基于FPGA的通用8251串行异步收发器(6600+字)
1.簡介與仿真結論
? ? ? ?隨著集成電路技術的發(fā)展,電子設計自動化(EDA)逐漸成為重要的設計手段,已經(jīng)廣泛應用于模擬與數(shù)字電路系統(tǒng)等許多領域。電子設計自動化是一種實現(xiàn)電子系統(tǒng)或電子產品自動化設計的技術,它與電子技術,微電子技術的發(fā)展密切相關,它吸收了計算機科學領域的大多數(shù)最新研究成果,以高性能的計算機作為工作平臺,促進了工程發(fā)展。EDA的一個重要特征就是使用硬件描述語言(HDL)來完成的設計文件,VHDL語言是經(jīng)IEEE確認的標準硬件語言,在電子設計領域受到了廣泛的接受。本文介紹了串行通信的基本理論;綜述了EDA技術的發(fā)展概況,介紹了MAX+PLUSll軟件;熟悉Intel8251基本結構和工作原理.
發(fā)送段的說明:
當發(fā)送01000110,發(fā)出去的是01100010——010,后面的010是校驗位和停止位,注意每次發(fā)送的后三位是校驗位。
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ā)送模塊的設計
??? 首先來設計URAT的發(fā)送模塊,根據(jù)系統(tǒng)的要求我們首先定義如下的管腳:
mclkx16 : IN std_logic;?????? ?????????????--系統(tǒng)時鐘
????? write?? : IN std_logic;??????????????????? --寫時鐘
????? reset?? : IN std_logic;??????????????????? ?--復位,0工作,1復位
??? ? data??? : IN std_logic_vector(7 downto 0); ?--8位并行數(shù)據(jù)輸入
??? ? tx????? : OUT std_logic ;?????????????????? --串行輸出
????? txrdy?? : OUT std_logic???????????????????? --標志位
該模塊的仿真波形圖如下圖所示:
圖1
? ? ? 當信號發(fā)送的01000110的時候,將并行信號變?yōu)榇行盘?#xff0c;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ù)的校驗信號位。由此我們驗證了系統(tǒng)發(fā)送部分的正確性。
? ? ? 下面來具體介紹發(fā)送部分的工作流程:
圖2
? ? ? ?上圖中狀態(tài)的轉移是靠一個內部變量(Variable)來實現(xiàn)的,該變量在進行完當前狀態(tài)的處理后指向下一個將處理的狀態(tài),進程(Process)的每一次處理都根據(jù)變量的內容進行相應狀態(tài)的處理,由于其功能就像一個指針,因此我們稱之為接收或發(fā)送指針。
? ? ? ?其中的信號的轉換過程如下:
??????????? 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;
通過這個代碼可以將并型信號轉為串型信號,將串行信號發(fā)送出去。
其中信號的校驗公式如下:
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 接收模塊的設計
??? 首先來設計URAT的發(fā)送模塊,根據(jù)系統(tǒng)的要求我們首先定義如下的管腳:
mclkx16???? :? IN std_logic;??? -- 輸入時鐘
???? read??????? :? IN std_logic;??? -- 讀取信號
???? rx????????? :? IN std_logic;??? -- 接收到的信號
???? reset?????? :? IN std_logic;??? -- 復位
?? ? rxrdy?????? :? OUT? std_logic;? -- 接收的數(shù)據(jù)準備讀取
?? ? parityerr?? :? OUT? std_logic;? -- 接收校驗標志
?? ? framingerr? :? OUT? std_logic;?
?? ? overrun???? :? OUT? std_logic;?
?? ? data??????? :? OUT? std_logic_vector(7 downto 0)); -- 8 bit 數(shù)據(jù)輸出該模塊的仿真波形圖如下圖所示:
圖3
???? 當信號接收串型信號01101010的時候,將串行信號變?yōu)椴⑿行盘?#xff0c;data[0]=0, data[1]=1, data[2]=1, data[3]=0, data[4]=1, data[5]=0, data[6]=1, data[7]=0。由此我們驗證了系統(tǒng)發(fā)送部分的正確性。
???? 下面來具體介紹發(fā)送部分的工作流程:
圖4
接收處理首先完成起始位的檢測,并自己產生接收時序控制信號,在控制信號的控制下,逐位接收串行輸入數(shù)據(jù),并根據(jù)控制字判斷接收數(shù)據(jù)位數(shù),完成數(shù)據(jù)的接收后,進行奇偶校驗位的判斷,最后判斷停止位。在接收的過程中設置接收狀態(tài)輸出信號。
其中的信號的轉換過程如下:
?? 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;
通過這個程序,我們可以講接收端的串行信號變?yōu)樵嫉拇行盘枴?/p>
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)時鐘write : IN std_logic; --寫時鐘reset : IN std_logic; --復位,0工作,1復位data : IN std_logic_vector(7 downto 0); --8位并行數(shù)據(jù)輸入tx : OUT std_logic ; --串行輸出txrdy : OUT std_logic --標志位); 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 --校驗公式 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; --當寫信號為0的時候講數(shù)據(jù)打入寄存器THR中,THR是一個中間變量thr_write : PROCESS (write, data)BEGINIF (write = '0') THENthr <= data;END IF;END PROCESS; --生成一個分頻后的時鐘,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; --轉換過程。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; --輸出校驗位ELSEtx <= tsr(0);END IF;END IF;END IF;END PROCESS; --幾個控制信號的生成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; -- 輸入時鐘read : IN std_logic; -- 讀取信號rx : IN std_logic; -- 接收到的信號reset : IN std_logic; -- 復位rxrdy : OUT std_logic; -- 接收的數(shù)據(jù)準備讀取parityerr : OUT std_logic; -- 接收校驗標志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; --時鐘分頻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; --校驗位判斷過程和數(shù)據(jù)轉換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; --標志信號的生成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
總結
以上是生活随笔為你收集整理的基于FPGA的通用8251串行异步收发器(6600+字)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于FPGA的图像增强系统的verilo
- 下一篇: 基于Quartus II软件FPGA与P