基于FPGA的通用8251串行异步收发器(6600+字)
1.簡(jiǎn)介與仿真結(jié)論
? ? ? ?隨著集成電路技術(shù)的發(fā)展,電子設(shè)計(jì)自動(dòng)化(EDA)逐漸成為重要的設(shè)計(jì)手段,已經(jīng)廣泛應(yīng)用于模擬與數(shù)字電路系統(tǒng)等許多領(lǐng)域。電子設(shè)計(jì)自動(dòng)化是一種實(shí)現(xiàn)電子系統(tǒng)或電子產(chǎn)品自動(dòng)化設(shè)計(jì)的技術(shù),它與電子技術(shù),微電子技術(shù)的發(fā)展密切相關(guān),它吸收了計(jì)算機(jī)科學(xué)領(lǐng)域的大多數(shù)最新研究成果,以高性能的計(jì)算機(jī)作為工作平臺(tái),促進(jìn)了工程發(fā)展。EDA的一個(gè)重要特征就是使用硬件描述語言(HDL)來完成的設(shè)計(jì)文件,VHDL語言是經(jīng)IEEE確認(rèn)的標(biāo)準(zhǔn)硬件語言,在電子設(shè)計(jì)領(lǐng)域受到了廣泛的接受。本文介紹了串行通信的基本理論;綜述了EDA技術(shù)的發(fā)展概況,介紹了MAX+PLUSll軟件;熟悉Intel8251基本結(jié)構(gòu)和工作原理.
發(fā)送段的說明:
當(dāng)發(fā)送01000110,發(fā)出去的是01100010——010,后面的010是校驗(yàn)位和停止位,注意每次發(fā)送的后三位是校驗(yàn)位。
paritycycle <= tsr(1) AND NOT (tag2 OR tag1 OR tsr(7) OR tsr(6) OR tsr(5) OR tsr(4) OR tsr(3) OR tsr(2));
txdone <= NOT (tag2 OR tag1 OR tsr(7) OR tsr(6) OR tsr(5) OR tsr(4) OR tsr(3) OR tsr(2) OR tsr(1) OR tsr(0));
txrdy <= NOT txdatardy;
接收段的說明:
發(fā)送01101010,接收也為01101010
2.理論分析
發(fā)送模塊的設(shè)計(jì)
??? 首先來設(shè)計(jì)URAT的發(fā)送模塊,根據(jù)系統(tǒng)的要求我們首先定義如下的管腳:
mclkx16 : IN std_logic;?????? ?????????????--系統(tǒng)時(shí)鐘
????? write?? : IN std_logic;??????????????????? --寫時(shí)鐘
????? reset?? : IN std_logic;??????????????????? ?--復(fù)位,0工作,1復(fù)位
??? ? data??? : IN std_logic_vector(7 downto 0); ?--8位并行數(shù)據(jù)輸入
??? ? tx????? : OUT std_logic ;?????????????????? --串行輸出
????? txrdy?? : OUT std_logic???????????????????? --標(biāo)志位
該模塊的仿真波形圖如下圖所示:
圖1
? ? ? 當(dāng)信號(hào)發(fā)送的01000110的時(shí)候,將并行信號(hào)變?yōu)榇行盘?hào),data[0]=0, data[1]=1, data[2]=1, data[3]=0, data[4]=0, data[5]=0, data[6]=1, data[7]=0,后3位的010為該數(shù)據(jù)的校驗(yàn)信號(hào)位。由此我們驗(yàn)證了系統(tǒng)發(fā)送部分的正確性。
? ? ? 下面來具體介紹發(fā)送部分的工作流程:
圖2
? ? ? ?上圖中狀態(tài)的轉(zhuǎn)移是靠一個(gè)內(nèi)部變量(Variable)來實(shí)現(xiàn)的,該變量在進(jìn)行完當(dāng)前狀態(tài)的處理后指向下一個(gè)將處理的狀態(tài),進(jìn)程(Process)的每一次處理都根據(jù)變量的內(nèi)容進(jìn)行相應(yīng)狀態(tài)的處理,由于其功能就像一個(gè)指針,因此我們稱之為接收或發(fā)送指針。
? ? ? ?其中的信號(hào)的轉(zhuǎn)換過程如下:
??????????? tsr <= '0'&tsr(7 downto 1);
??????????? tsr(7) <= tag1;
??????????? tag1 <= tag2;
???????????????????? ?tag2 <= '0';
??????????? txparity <= txparity XOR tsr(0);
??????????? IF (txdone = '1') THEN
?????????????? tx <= '1';
?????????????? ELSIF (paritycycle = '1') THEN
????????????????? tx <= txparity;???????????? ?
?????????????? ELSE
????????????????? tx <= tsr(0);
??????????? END IF;
通過這個(gè)代碼可以將并型信號(hào)轉(zhuǎn)為串型信號(hào),將串行信號(hào)發(fā)送出去。
其中信號(hào)的校驗(yàn)公式如下:
paritycycle <= tsr(1) AND NOT (tag2 OR tag1 OR tsr(7) OR tsr(6) OR tsr(5) OR tsr(4) OR tsr(3) OR tsr(2));
2 接收模塊的設(shè)計(jì)
??? 首先來設(shè)計(jì)URAT的發(fā)送模塊,根據(jù)系統(tǒng)的要求我們首先定義如下的管腳:
mclkx16???? :? IN std_logic;??? -- 輸入時(shí)鐘
???? read??????? :? IN std_logic;??? -- 讀取信號(hào)
???? rx????????? :? IN std_logic;??? -- 接收到的信號(hào)
???? reset?????? :? IN std_logic;??? -- 復(fù)位
?? ? rxrdy?????? :? OUT? std_logic;? -- 接收的數(shù)據(jù)準(zhǔn)備讀取
?? ? parityerr?? :? OUT? std_logic;? -- 接收校驗(yàn)標(biāo)志
?? ? framingerr? :? OUT? std_logic;?
?? ? overrun???? :? OUT? std_logic;?
?? ? data??????? :? OUT? std_logic_vector(7 downto 0)); -- 8 bit 數(shù)據(jù)輸出該模塊的仿真波形圖如下圖所示:
圖3
???? 當(dāng)信號(hào)接收串型信號(hào)01101010的時(shí)候,將串行信號(hào)變?yōu)椴⑿行盘?hào),data[0]=0, data[1]=1, data[2]=1, data[3]=0, data[4]=1, data[5]=0, data[6]=1, data[7]=0。由此我們驗(yàn)證了系統(tǒng)發(fā)送部分的正確性。
???? 下面來具體介紹發(fā)送部分的工作流程:
圖4
接收處理首先完成起始位的檢測(cè),并自己產(chǎn)生接收時(shí)序控制信號(hào),在控制信號(hào)的控制下,逐位接收串行輸入數(shù)據(jù),并根據(jù)控制字判斷接收數(shù)據(jù)位數(shù),完成數(shù)據(jù)的接收后,進(jìn)行奇偶校驗(yàn)位的判斷,最后判斷停止位。在接收的過程中設(shè)置接收狀態(tài)輸出信號(hào)。
其中的信號(hào)的轉(zhuǎn)換過程如下:
?? sample_data : PROCESS (rxclk, reset)
?? BEGIN
????? IF (reset = '1') THEN
????? -- idle_reset??
???????? rsr??????? <= "11111111";?????????????
?? ???rxparity?? <= '1';??????? ????? ?????????
?? ???paritygen? <= paritymode;?????
?? ???rxstop???? <= '0';????
????? ELSIF (rxclk='1') AND (rxclk'EVENT) THEN
???????? IF (idle='1') THEN
??????????? -- idle_reset??
??????????? rsr??????? <= "11111111";???????
?? ??????rxparity?? <= '1';??????? ?????? ?????????
?? ??????paritygen? <= paritymode;?????????????
?? ??????rxstop???? <= '0';
???????? ELSE
? ?? ?????????-- shift_data
? ?? ?????????rsr???????? <= '0'&rsr(7 downto 1);???
??????????? rsr(7)????? <= rxparity;???????????
??????????? rxparity??? <= rxstop;????????????
??????????? rxstop????? <= rx;????????????????
??????????? paritygen?? <= paritygen XOR rxstop;?
???????? END IF;
????? END IF;
?? END PROCESS;
通過這個(gè)程序,我們可以講接收端的串行信號(hào)變?yōu)樵嫉拇行盘?hào)。
3.部分核心代碼
·發(fā)送模塊:
LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.std_logic_unsigned.ALL; ENTITY txmit IS PORT (mclkx16 : IN std_logic; --系統(tǒng)時(shí)鐘write : IN std_logic; --寫時(shí)鐘reset : IN std_logic; --復(fù)位,0工作,1復(fù)位data : IN std_logic_vector(7 downto 0); --8位并行數(shù)據(jù)輸入tx : OUT std_logic ; --串行輸出txrdy : OUT std_logic --標(biāo)志位); END txmit; --以下定義一些中間變量,具體使用在以下模塊中介紹 ARCHITECTURE behave OF txmit ISSIGNAL write1, write2 : std_logic;SIGNAL txdone1, txdone : std_logic;SIGNAL thr, tsr : std_logic_vector(7 downto 0);SIGNAL tag1, tag2 : std_logic;CONSTANT paritymode : std_logic :='1';SIGNAL txparity : std_logic;SIGNAL txclk : std_logic;SIGNAL paritycycle : std_logic;SIGNAL txdatardy : std_logic;SIGNAL cnt : std_logic_vector(2 downto 0); BEGIN --校驗(yàn)公式 paritycycle <= tsr(1) AND NOT (tag2 OR tag1 OR tsr(7) OR tsr(6) OR tsr(5) OR tsr(4) OR tsr(3) OR tsr(2)); txdone <= NOT (tag2 OR tag1 OR tsr(7) OR tsr(6) OR tsr(5) OR tsr(4) OR tsr(3) OR tsr(2) OR tsr(1) OR tsr(0)); txrdy <= NOT txdatardy; --當(dāng)寫信號(hào)為0的時(shí)候講數(shù)據(jù)打入寄存器THR中,THR是一個(gè)中間變量thr_write : PROCESS (write, data)BEGINIF (write = '0') THENthr <= data;END IF;END PROCESS; --生成一個(gè)分頻后的時(shí)鐘,16分頻baud_clock_gen : PROCESS (mclkx16, reset)BEGINIF (reset ='1') THENtxclk <= '0';cnt <= "000";ELSIF (mclkx16='1') AND mclkx16'EVENT THENIF (cnt = "000") THENtxclk <= NOT txclk;END IF;cnt <= cnt + 1;END IF;END PROCESS; --轉(zhuǎn)換過程。shift_out : PROCESS (txclk, reset)BEGINIF (reset = '1') THENtsr <= (OTHERS => '0');tag2 <= '0';tag1 <= '0';txparity <= paritymode;tx <= '1';--idle_reset;ELSIF txclk = '1' AND txclk'EVENT THENIF (txdone='1' AND txdatardy = '1') THEN -- load_data;tsr <= thr;tag2 <= '1';tag1 <= '1';txparity <= paritymode;tx <= '0';ELSE -- shift_data; --一下幾行就是并-》串的過程。tsr <= '0'&tsr(7 downto 1);tsr(7) <= tag1;tag1 <= tag2;tag2 <= '0';txparity <= txparity XOR tsr(0);IF (txdone = '1') THENtx <= '1';ELSIF (paritycycle = '1') THENtx <= txparity; --輸出校驗(yàn)位ELSEtx <= tsr(0);END IF;END IF;END IF;END PROCESS; --幾個(gè)控制信號(hào)的生成PROCESS (mclkx16, reset)BEGINIF (reset='1') THENtxdatardy <= '0';write2 <= '1';write1 <= '1';txdone1 <= '1';ELSIF mclkx16 = '1' AND mclkx16'EVENT THENIF (write1 = '1' AND write2 = '0') THENtxdatardy <= '1';ELSIF (txdone = '0' AND txdone1 = '1') THENtxdatardy <= '0';END IF;write2 <= write1;write1 <= write;txdone1 <= txdone;END IF;END PROCESS; END behave;·接收模塊:
LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.std_logic_unsigned.ALL; ENTITY rxcver IS PORT (mclkx16 : IN std_logic; -- 輸入時(shí)鐘read : IN std_logic; -- 讀取信號(hào)rx : IN std_logic; -- 接收到的信號(hào)reset : IN std_logic; -- 復(fù)位rxrdy : OUT std_logic; -- 接收的數(shù)據(jù)準(zhǔn)備讀取parityerr : OUT std_logic; -- 接收校驗(yàn)標(biāo)志framingerr : OUT std_logic; overrun : OUT std_logic; data : OUT std_logic_vector(7 downto 0)); -- 8 bit 數(shù)據(jù)輸出 END rxcver; --定義的中間變量 ARCHITECTURE behave OF rxcver IS SIGNAL rxcnt : std_logic_vector(3 downto 0); SIGNAL rx1, read1, read2, idle1 : std_logic; SIGNAL hunt : std_logic; SIGNAL rhr : std_logic_vector(7 downto 0); SIGNAL rsr : std_logic_vector(7 downto 0); SIGNAL rxparity : std_logic; SIGNAL paritygen : std_logic; SIGNAL rxstop : std_logic; CONSTANT paritymode : std_logic := '1'; SIGNAL rxclk : std_logic; SIGNAL idle : std_logic; SIGNAL rxdatardy : std_logic; BEGINidle_preset : PROCESS (rxclk, reset)BEGINIF reset = '1' THENidle <= '1';ELSIF rxclk'EVENT AND rxclk='1' THENidle <= (NOT idle) AND (NOT rsr(0));END IF;END PROCESS; --時(shí)鐘分頻rxclk_sync : PROCESS (mclkx16, reset)BEGINIF reset='1' THENhunt <= '0';rxcnt <= "0001";rx1 <= '1';rxclk <= '0';ELSIF (mclkx16='1') AND mclkx16'EVENT THENIF (idle='1' AND rx='0' AND rx1='1') THENhunt <= '1';ELSEIF (idle='0' OR rx='1') THENhunt <= '0';END IF;IF (idle ='0' OR hunt='1') THENrxcnt <= rxcnt + 1;ELSErxcnt <= "0001";END IF;END IF;rx1 <= rx;rxclk <= rxcnt(3); END IF;END PROCESS; --校驗(yàn)位判斷過程和數(shù)據(jù)轉(zhuǎn)換sample_data : PROCESS (rxclk, reset)BEGINIF (reset = '1') THEN-- idle_reset rsr <= "11111111"; rxparity <= '1'; paritygen <= paritymode; rxstop <= '0'; ELSIF (rxclk='1') AND (rxclk'EVENT) THENIF (idle='1') THEN-- idle_reset rsr <= "11111111"; rxparity <= '1'; paritygen <= paritymode; rxstop <= '0';ELSE-- shift_datarsr <= '0'&rsr(7 downto 1); rsr(7) <= rxparity; rxparity <= rxstop; rxstop <= rx; paritygen <= paritygen XOR rxstop; END IF;END IF;END PROCESS; --標(biāo)志信號(hào)的生成generate_flag : PROCESS (mclkx16, reset)BEGINIF (reset='1') THENrhr <= "00000000";rxdatardy <= '0';overrun <= '0';parityerr <= '0';framingerr <= '0';idle1 <= '1'; read2 <= '1'; read1 <= '1'; ELSIF (mclkx16='1') AND (mclkx16'EVENT) THENIF (idle='1' AND idle1='0') THENIF (rxdatardy='1') THENoverrun <= '1';ELSEoverrun <= '0'; rhr <= rsr; parityerr <= paritygen; framingerr <= NOT rxstop; rxdatardy <= '1'; END IF;END IF;IF (read2 = '0' AND read1='1') THENrxdatardy <= '0';parityerr <= '0';framingerr <= '0';overrun <= '0';END IF;idle1 <= idle; read2 <= read1; read1 <= read; END IF;END PROCESS;rxrdy <= rxdatardy;latch_data : PROCESS (read, rhr)BEGINIF (read = '1') THENdata <= rhr;END IF;END PROCESS; END behave;A38-01
總結(jié)
以上是生活随笔為你收集整理的基于FPGA的通用8251串行异步收发器(6600+字)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于FPGA的图像增强系统的verilo
- 下一篇: 基于FPGA的AFDX接口实现