63 / 63 · अवधारणा
समग्र अभ्यास: UART प्रेषक और फ्रेम टाइमिंग
विभाजन काउंटर, शिफ्ट रजिस्टर और प्रवाह नियंत्रण जोड़कर 8N1 फ्रेम बनाएँ तथा बिट सीमाएँ सत्यापित करें।
पाठ पढ़ना मुफ़्त है। प्रगति सेव करने के लिए नामांकन करें।
पहले फ्रेम का विनिर्देश निश्चित करें
पूर्वज्ञान: काउंटर, शिफ्ट रजिस्टररजिस्टर कई बिटों की अवस्था संग्रहित करता है। इस पाठ्यक्रम के तुल्यकालिक रजिस्टर निर्धारित इनपुट को क्लॉक एज पर संग्रहित करते हैं। और जानें, valid/ready और तुल्यकालिक resetरीसेट अवस्था को विनिर्दिष्ट प्रारंभिक मान पर लौटाने वाला नियंत्रण। उसका तुल्यकालिक या अतुल्यकालिक होना और अन्य नियंत्रणों पर प्राथमिकता साथ तय करें। और जानें।
UARTUART अलग क्लॉक लाइन के बिना start बिट, डेटा और stop बिट से क्रमिक संचार करने वाला उपकरण। भेजने और पाने वाले को baud rate और फ्रेम प्रारूप पर सहमत होना चाहिए। का 8N1 प्रारूप एक start बिट, आठ डेटा बिट, कोई parity नहीं और एक stop बिट है। Idle और stop का मान 1, start का 0 है; डेटा LSBLSB सबसे कम स्थानिक भार वाला बिट। लिखने की दिशा और इंडेक्स के नियम साथ जाँचने चाहिए। और जानें से शुरू होता है। सभी बिट समान अवधि तक रखे जाते हैं। यह अभ्यास केवल भेजना समझाता है और डेटा देने वाले का क्लॉक समान मानता है।
48 MHz पर लक्ष्य 115200 baud हो तो पूर्णांक विभाजक D=417 चुन सकते हैं। वास्तविक गति लगभग 115108 baud और त्रुटि लगभग -0.080% है। पाने वाले सहित स्वीकार्य त्रुटि उपकरण के विनिर्देश से जाँचनी होगी।
0x53 को वास्तविक भेजने के क्रम में खोलें
0x53 का लिखा रूप 01010011 है, लेकिन लाइन पर निचले बिट से क्रम 1,1,0,0,1,0,1,0 जाता है। चित्र का एक खंड सिस्टम क्लॉक का एक चक्र नहीं, D क्लॉक की बिट अवधि है। तुलना के लिए पहले और बाद का idle एक-एक खंड दिखाया गया है।
तरंगरूप डेटा देखें
| संकेत | तरंगरूप | बस मान |
|---|---|---|
| tx | 101.0.10101. | |
| खंड | 234523452345 | निष्क्रिय → आरंभ → d0 → d1 → d2 → d3 → d4 → d5 → d6 → d7 → समापन → निष्क्रिय |
Start से stop तक ठीक 10D क्लॉक हैं। लगातार 1 या 0 भी प्रत्येक एक पूरी बिट अवधि लेते हैं। लाइन पर परिवर्तन न होने से बिट गायब नहीं होता।
एक डेटा बाइट केवल एक बार कैप्चर करें
नीचे का कार्यान्वयन CLKS_PER_BIT को कम से कम 1 का स्थिरांक मानता है। Busy में इनपुट स्वीकार नहीं होता और केवल फ्रेम शुरू होने पर कैप्चर किए गए data का उपयोग होता है। अलग bit-clock बनाने के बजाय मूल क्लॉक के भीतर काउंटर से आगे बढ़ने का समय नियंत्रित होता है।
module uart_tx #(
parameter int unsigned CLKS_PER_BIT = 417,
localparam int CW = (CLKS_PER_BIT <= 1) ? 1 : $clog2(CLKS_PER_BIT)
) (
input logic clk, rst,
input logic in_valid,
output logic in_ready,
input logic [7:0] in_data,
output logic tx, busy, done
);
logic [9:0] frame;
logic [3:0] bits_left;
logic [CW-1:0] ticks_left;
assign in_ready = !busy;
always_ff @(posedge clk) begin
if (rst) begin
tx <= 1'b1;
busy <= 1'b0;
done <= 1'b0;
bits_left <= 4'd0;
ticks_left <= '0;
end else begin
done <= 1'b0;
if (!busy) begin
if (in_valid) begin
frame <= {1'b1, in_data, 1'b0};
tx <= 1'b0;
busy <= 1'b1;
bits_left <= 4'd10;
ticks_left <= CW'(CLKS_PER_BIT-1);
end
end else if (ticks_left != 0) begin
ticks_left <= ticks_left - 1'b1;
end else if (bits_left == 4'd1) begin
tx <= 1'b1;
busy <= 1'b0;
done <= 1'b1;
end else begin
frame <= {1'b1, frame[9:1]};
tx <= frame[1];
bits_left <= bits_left - 1'b1;
ticks_left <= CW'(CLKS_PER_BIT-1);
end
end
end
endmoduleइनपुट स्वीकृति एज E0 हो तो tx, start=0 में बदलता है। इसके बाद हर ठीक D क्लॉक पर अगला बिट आता है। E0+9D पर stop शुरू होता है, E0+10D पर busy घटता है और done एक चक्र के लिए आता है। अंतिम stop अवधि भी पूरे D चक्र होनी चाहिए।
इस कार्यान्वयन में पूर्णता के एज से ठीक पहले तक in_ready=0 है, इसलिए अगला फ्रेम सबसे जल्दी उसके अगले एज पर स्वीकार होता है। लगातार फ्रेम स्वीकृतियों का अंतराल क्लॉक है। यह एक क्लॉक का idle अंतराल सामान्य व्यवहार का हिस्सा है।
बिट क्रम हाथ से निकालें
8'h53 के डेटा बिट LSB से 1,1,0,0,1,0,1,0 हैं। पूरा फ्रेम इस क्रम में है:
| क्रम | start | d0 | d1 | d2 | d3 | d4 | d5 | d6 | d7 | stop |
|---|---|---|---|---|---|---|---|---|---|---|
| tx | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 1 |
सत्यापन में केवल tx बदलने की संख्या न गिनें। लगातार समान बिटों में परिवर्तन नहीं होता। फ्रेम की शुरुआत के सापेक्ष हर बिट अवधि के मध्य में नमूना लेकर अपेक्षित बिट से मिलाएँ और start तथा stop की अवधि भी जाँचें। तेज इकाई सत्यापन के लिए D=1,2,3 जैसे छोटे मान भी लें।
FIFO से जोड़ने का विस्तारित डिजाइन
रजिस्टर्ड पढ़ने वाला FIFOFIFO कतार जिसमें पहले डाला गया डेटा पहले निकलता है। पूर्ण, रिक्त और एक साथ पढ़ने-लिखने की अनुमति के नियम इसके व्यवहार के अनुबंध का हिस्सा हैं। और जानें, pop स्वीकृति एज के ठीक बाद dout और dout_valid अपडेट करता है। उसी क्लॉक का अगला परिपथ अगले उर्ध्वगामी एजउदयी किनारा (rising edge) क्लॉक के 0 से 1 होने का क्षण। यह CLK=1 के पूरे स्तर-अंतराल से अलग है। और जानें पर उत्तर पढ़ता है। जिस एज पर pop स्वीकार हुआ, उसी का dout UART को देने पर पुराना मान जा सकता है। लौटे बाइट के लिए एक स्थान का बफर और pending अवस्था रखें; UART तैयार हो तो उसे ठीक एक बार भेजें।
अंतिम सत्यापन में 00,FF,01,80,55,53; busy के दौरान बदलता इनपुट; लगातार फ्रेम; और फ्रेम के बीच reset शामिल करें। Reset की नीति प्रसारण रोककर tx को idle=1 लौटाना है। फिर भी रिसीवर को यह एक वैध फ्रेम दिख सकता है, इसलिए केवल UART फ्रेमिंग से बाधित प्रसारण का पता लगाने की गारंटी नहीं मिलती। यदि प्रभावित डेटा को अनिवार्य रूप से हटाना है, तो ऐसा सिस्टम अनुबंध तय करें जो रिसीवर के reset को ट्रांसमीटर के साथ समन्वित करे या रिसीवर को प्रसारण बाधित होने का अलग संकेत दे।
आगे पढ़ें: Microchip — EUSART and 8N1 framing
खुद आज़माएँ
CLKS_PER_BIT=4 है और E0 पर डेटा स्वीकार हुआ। d0 की शुरुआत, stop की शुरुआत और done का एज निकालें। E40 पर नया in_valid=1 हो तो क्या अगला बाइट उसी एज पर स्वीकार होगा?
व्याख्या पढ़ें
d0, E4 के ठीक बाद; stop, E36 के ठीक बाद; done, E40 के ठीक बाद शुरू होते हैं। E40 के ठीक पहले busy=1 और in_ready=0 है, इसलिए नया बाइट अभी स्वीकार नहीं होता। भेजने वाले को valid और data बनाए रखने होंगे। अगला बाइट E41 पर स्वीकार हो सकता है। हर फ्रेम 40 क्लॉक है और स्वीकृतियों का न्यूनतम अंतराल 41 क्लॉक है।