0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

使用FPGA實(shí)現(xiàn)UART方案

電子工程師 ? 來(lái)源:FPGA技術(shù)江湖 ? 作者:The last one ? 2022-08-10 09:09 ? 次閱讀

導(dǎo)讀

串口的出現(xiàn)是在1980年前后,數(shù)據(jù)傳輸率是115kbps~230kbps。串口出現(xiàn)的初期是為了實(shí)現(xiàn)連接計(jì)算機(jī)外設(shè)的目的,初期串口一般用來(lái)連接鼠標(biāo)和外置Modem以及老式攝像頭和寫(xiě)字板等設(shè)備。串口也可以應(yīng)用于兩臺(tái)計(jì)算機(jī)(或設(shè)備)之間的互聯(lián)及數(shù)據(jù)傳輸。由于串口(COM)不支持熱插拔及傳輸速率較低,部分新主板和大部分便攜電腦已開(kāi)始取消該接口。串口多用于工控和測(cè)量設(shè)備以及部分通信設(shè)備中。

串口是串行接口的簡(jiǎn)稱,也稱串行通信接口或串行通訊接口(通常指COM接口),是采用串行通信方式的擴(kuò)展接口。串行接口(Serial Interface)是指數(shù)據(jù)一位一位地順序傳送。其特點(diǎn)是通信線路簡(jiǎn)單,只要一對(duì)傳輸線就可以實(shí)現(xiàn)雙向通信(可以直接利用電話線作為傳輸線),從而大大降低了成本,特別適用于遠(yuǎn)距離通信,但傳送速度較慢。

通信協(xié)議是指通信雙方的一種約定。約定包括對(duì)數(shù)據(jù)格式、同步方式、傳送速度、傳送步驟、檢糾錯(cuò)方式以及控制字符定義等問(wèn)題做出統(tǒng)一規(guī)定,通信雙方必須共同遵守。串口通信的兩種最基本的方式為:同步串行通信方式和異步串行通信方式。

同步串行通信是指SPI(Serial Peripheral interface)的縮寫(xiě),顧名思義就是串行外圍設(shè)備接口。SPI是一種高速的全雙工通信總線。封裝芯片上總共有四根線,PCB布局布線也簡(jiǎn)單,所以現(xiàn)在很多芯片集成了這個(gè)協(xié)議。主要用于CPU和各種外圍器件進(jìn)行通信,TRM450是SPI接口。

異步串行通信是指UART(Universal Asynchronous Receiver/Transmitter),通用異步接收/發(fā)送。UART是一個(gè)并行輸入成為串行輸出的芯片,通常集成在主板上。UART包含TTL電平的串口和RS232電平的串口。RS232也稱標(biāo)準(zhǔn)串口,也是最常用的一種串行通訊接口。RS-232-C 標(biāo)準(zhǔn)對(duì)兩個(gè)方面作了規(guī)定,即信號(hào)電平標(biāo)準(zhǔn)和控制信號(hào)線的定義。RS-232-C 采用負(fù)邏輯規(guī)定邏輯電平,信號(hào)電平與通常的TTL電平也不兼容,RS-232-C 將-5V~-15V 規(guī)定為“1”,+5V~+15V 規(guī)定為“0”。

一般情況下外設(shè)不能直接和主機(jī)直接相連,它們之間的信息交換主要存在以下問(wèn)題:

? 速度不匹配 通常情況下外設(shè)的工作速度會(huì)比主機(jī)慢許多,而且外設(shè)之間的速度差異也比較大。

? 數(shù)據(jù)格式不匹配 不同的外設(shè)在進(jìn)行信息存儲(chǔ)和處理時(shí)的數(shù)據(jù)單元可能不同,例如最基本的數(shù)據(jù)格式可以分為并行數(shù)據(jù)和串行數(shù)據(jù)。

? 信息類型不匹配 不同的外設(shè)可能采用不同類型的信號(hào),有些是模擬信號(hào),有些是數(shù)字信號(hào),因此所采用的處理方式也不同。

為了解決外設(shè)和主機(jī)之間信息交換的問(wèn)題,就需要設(shè)計(jì)一個(gè)信息交換的中間環(huán)節(jié)——接口。本篇將首先對(duì)接口技術(shù)進(jìn)行簡(jiǎn)要的介紹,然后以接口中最常用的 UART 控制器為例,詳細(xì)介紹用 FPGA 實(shí)現(xiàn) UART 控制器的方法。

第三篇內(nèi)容摘要:本篇會(huì)介紹使用 FPGA 實(shí)現(xiàn) UART,包括UART設(shè)計(jì)框架、UART 工作流程、信號(hào)監(jiān)測(cè)器模塊的實(shí)現(xiàn)、波特率發(fā)生器模塊的實(shí)現(xiàn)、移位寄存器模塊的實(shí)現(xiàn)、奇偶校驗(yàn)器模塊的實(shí)現(xiàn)、總線選擇器模塊的實(shí)現(xiàn)、計(jì)數(shù)器模塊的實(shí)現(xiàn)、UART 內(nèi)核模塊的實(shí)現(xiàn)、UART 頂層模塊的實(shí)現(xiàn) 、測(cè)試平臺(tái)的編寫(xiě)和仿真等相關(guān)內(nèi)容。

三、使用 FPGA 實(shí)現(xiàn) UART

3.1 UART 設(shè)計(jì)框架

UART 主要由 UART 內(nèi)核、信號(hào)監(jiān)測(cè)器、移位寄存器、波特率發(fā)生器、計(jì)數(shù)器、總線選擇器和奇偶校驗(yàn)器總共 7 個(gè)模塊組成,如圖 5 所示。

e8d546ae-17dc-11ed-ba43-dac502259ad0.png

圖 5 UART 實(shí)現(xiàn)框架圖

UART 各個(gè)模塊的功能如下。

1)UART 內(nèi)核模塊

UART 內(nèi)核模塊是整個(gè)設(shè)計(jì)的核心。在數(shù)據(jù)接收時(shí),UART 內(nèi)核模塊負(fù)責(zé)控制波特率發(fā)生器和移位寄存器,使得移位寄存器在波特率時(shí)鐘的驅(qū)動(dòng)下同步地接收并且保存 RS-232 接收端口上的串行數(shù)據(jù)。在數(shù)據(jù)發(fā)送時(shí),UART 內(nèi)核模塊首先根據(jù)待發(fā)送的數(shù)據(jù)和奇偶校驗(yàn)位的設(shè)置產(chǎn)生完整的發(fā)送序列(包括起始位、數(shù)據(jù)位、奇偶校驗(yàn)位和停止位),之后控制移位寄存器將序列加載到移位寄存器的內(nèi)部寄存器里,最后再控制波特率發(fā)生器驅(qū)動(dòng)移位寄存器將數(shù)據(jù)串行輸出。

2)信號(hào)監(jiān)測(cè)器模塊

信號(hào)監(jiān)測(cè)器用于對(duì) RS-232 的輸入信號(hào)進(jìn)行實(shí)時(shí)監(jiān)測(cè),一旦發(fā)現(xiàn)新的數(shù)據(jù)則立即通知 UART內(nèi)核。

注意:這里所說(shuō)的 RS-232 輸入、輸出信號(hào)都指的是經(jīng)過(guò)電平轉(zhuǎn)換后的邏輯信號(hào),而不是 RS-232 總線上的信號(hào)。絕對(duì)不能直接將 RS-232 總線的信號(hào)連接到 FPGA 管腳上,否則很容易造成 FPGA芯片的損壞。

3)移位寄存器模塊

移位寄存器的作用是存儲(chǔ)輸入或者輸出的數(shù)據(jù)。當(dāng) UART 接收 RS-232 輸入時(shí),移位寄存器在波特率模式下采集 RS-232 輸入信號(hào),并且保存結(jié)果;當(dāng) UART 進(jìn)行 RS-232 輸出時(shí),UART 內(nèi)核首先將數(shù)據(jù)加載到移位寄存器內(nèi),再使移位寄存器在波特率模式下將數(shù)據(jù)輸出到 RS-232 輸出端口上。

注意:波特率模式指的是模塊的輸入時(shí)鐘是符合 RS-232 傳輸波特率的時(shí)鐘,與波特率模式對(duì)應(yīng)的就是系統(tǒng)時(shí)鐘模式,即模塊是工作在系統(tǒng)時(shí)鐘下。

4)波特率發(fā)生器模塊

由于 RS-232 傳輸必定是工作在某種波特率下,比如 9600,為了便于和 RS-232 總線進(jìn)行同步,需要產(chǎn)生符合 RS-232 傳輸波特率的時(shí)鐘,這就是波特率發(fā)生器的功能。

5)奇偶校驗(yàn)器模塊

奇偶校驗(yàn)器的功能是根據(jù)奇偶校驗(yàn)的設(shè)置和輸入數(shù)據(jù)計(jì)算出相應(yīng)的奇偶校驗(yàn)位,它是通過(guò)純組合邏輯實(shí)現(xiàn)的。

6)總線選擇模塊

總線選擇模塊用于選擇奇偶校驗(yàn)器的輸入是數(shù)據(jù)發(fā)送總線還是數(shù)據(jù)接收總線。在接收數(shù)據(jù)時(shí),總線選擇模塊將數(shù)據(jù)接收總線連接到奇偶校驗(yàn)器的輸入端,來(lái)檢查已接收數(shù)據(jù)的奇偶校驗(yàn)位是否正確;而在發(fā)送數(shù)據(jù)時(shí),總線選擇模塊將數(shù)據(jù)發(fā)送總線連接到奇偶校驗(yàn)器的輸入端,UART內(nèi)核模塊就能夠獲取并且保存待發(fā)送序列所需的奇偶校驗(yàn)位了。

7)計(jì)數(shù)器模塊

計(jì)數(shù)器模塊的功能是記錄串行數(shù)據(jù)發(fā)送或者接收的數(shù)目,在計(jì)數(shù)到某數(shù)值時(shí)通知 UART 內(nèi)核模塊。

3.2 UART 工作流程

UART 的工作流程可以分為接收過(guò)程和發(fā)送過(guò)程兩部分。

接收過(guò)程指的是 UART 監(jiān)測(cè)到 RS-232 總線上的數(shù)據(jù),順序讀取串行數(shù)據(jù)并且將其輸出給CPU 的過(guò)程。當(dāng)信號(hào)監(jiān)測(cè)器監(jiān)測(cè)到新的數(shù)據(jù)(RS-232 輸入邏輯變?yōu)?0,即 RS-232 傳輸協(xié)議的起始位)就會(huì)觸發(fā)接收過(guò)程,其流程圖如圖 6 所示。

e8f017c2-17dc-11ed-ba43-dac502259ad0.png

圖6 UART 接收數(shù)據(jù)流程圖

首先 UART 內(nèi)核會(huì)重置波特率發(fā)生器和移位寄存器,并且設(shè)置移位寄存器的工作模式為波特率模式,以準(zhǔn)備接收數(shù)據(jù)。其次,移位寄存器在波特率時(shí)鐘的驅(qū)動(dòng)下工作,不斷讀取 RS-232 串行總線的輸入數(shù)據(jù),并且將數(shù)據(jù)保存在內(nèi)部的寄存器內(nèi)。接收完成后,UART 內(nèi)核會(huì)對(duì)已接收的數(shù)據(jù)進(jìn)行奇偶校驗(yàn)并且輸出校驗(yàn)結(jié)果。最后,UART 內(nèi)核會(huì)重置信號(hào)監(jiān)測(cè)器,以準(zhǔn)備進(jìn)行下一次數(shù)據(jù)接收。

發(fā)送過(guò)程是由加載和發(fā)送兩個(gè)步驟組成,如圖 7 所示。加載步驟是 UART 內(nèi)核按 RS-232串行發(fā)送的順序?qū)⑵鹗嘉?、?shù)據(jù)位、奇偶校驗(yàn)位和停止位加載到移位寄存器內(nèi),這個(gè)過(guò)程工作在系統(tǒng)時(shí)鐘下,相對(duì)于 RS-232 的傳輸速度來(lái)說(shuō)非常快。完成加載步驟后,UART 內(nèi)核會(huì)重置波特率發(fā)生器,并且設(shè)置移位寄存器工作在波特率模式下,于是移位寄存器便在波特率時(shí)鐘的驅(qū)動(dòng)下依次將加載的數(shù)據(jù)發(fā)送到 RS-232 的發(fā)送端 TxD,這樣便產(chǎn)生了 RS-232 的數(shù)據(jù)發(fā)送時(shí)序。

e9104bf0-17dc-11ed-ba43-dac502259ad0.png

圖 7 UART 發(fā)送數(shù)據(jù)流程圖

下面依次介紹一下 UART 各個(gè)模塊的實(shí)現(xiàn)方法。

3.3 信號(hào)監(jiān)測(cè)器模塊的實(shí)現(xiàn)

信號(hào)監(jiān)測(cè)器模塊的功能是監(jiān)測(cè) RS-232 輸入端的信號(hào),當(dāng)有新的數(shù)據(jù)傳輸時(shí)通知 UART 內(nèi)核開(kāi)始接收數(shù)據(jù),其端口定義如表 5 所示。

表 5 信號(hào)監(jiān)測(cè)器端口定義表

e923359e-17dc-11ed-ba43-dac502259ad0.png

在監(jiān)測(cè)到傳輸?shù)钠鹗嘉缓?,信?hào)監(jiān)測(cè)器需要將自己鎖定,即不對(duì)輸入信號(hào)進(jìn)行監(jiān)測(cè),直到UART 內(nèi)核將其復(fù)位。信號(hào)監(jiān)測(cè)器的實(shí)現(xiàn)代碼如下:

-- 庫(kù)聲明library IEEE;use IEEE.STD_LOGIC_1164.all;use WORK.UART_PACKAGE.ALL;-- 實(shí)體聲明entity detector is    port (    clk : in std_logic;    reset_n : in std_logic;    RxD : in std_logic;    new_data : out std_logic );end detector;
--}} End of automatically maintained section-- 結(jié)構(gòu)體architecture detector of detector is-- 信號(hào)監(jiān)測(cè)器狀態(tài)機(jī)signal state : dt_state;begin    -- enter your statements here --    -- 主過(guò)程    main : process(reset_n, clk)    begin        -- 復(fù)位信號(hào)        if reset_n = '0' then            state <= dt_unlock;            new_data <= '0';        elsif rising_edge(clk) then            -- 檢查輸入信號(hào)和狀態(tài),當(dāng)輸入為低并且不在鎖定狀態(tài)時(shí),輸出 new_data 信號(hào)            if state = dt_unlock and RxD = '0' then                new_data <= '1';                state <= dt_lock;            else                new_data <= '0';            end if;        end if;    end process;
end detector;

代碼中的狀態(tài)機(jī) dt_state 是在 UART_PACKAGE 包中定義的,如下:

-- 信號(hào)監(jiān)測(cè)器狀態(tài)typedt_stateis(                  dt_unlock, -- 未鎖定狀態(tài)                  dt_lock -- 鎖定狀態(tài)                );

為了驗(yàn)證信號(hào)監(jiān)測(cè)器模塊的實(shí)現(xiàn),需要編寫(xiě)一個(gè)測(cè)試平臺(tái)測(cè)試其功能。測(cè)試平臺(tái)的代碼請(qǐng)參考 UART 工程源代碼中的 detector_tb.vhd 文件,測(cè)試的結(jié)果如圖 8 所示。

e94036da-17dc-11ed-ba43-dac502259ad0.png

圖 8 信號(hào)監(jiān)測(cè)器仿真時(shí)序圖

其中,RxD 第一次變?yōu)榈蜁r(shí),new_data 信號(hào)產(chǎn)生輸出;之后,RxD 又變?yōu)榈停捎谛盘?hào)監(jiān)測(cè)器處于鎖定狀態(tài),所以 new_data 并沒(méi)有輸出;最后,由于 reset_n 信號(hào)將信號(hào)監(jiān)測(cè)器復(fù)位了,RxD 再次變?yōu)榈蜁r(shí),new_data 上又有輸出了??梢?jiàn),信號(hào)監(jiān)測(cè)器的實(shí)現(xiàn)完全正確,其功能完全符合設(shè)計(jì)的要求。

3.4 波特率發(fā)生器模塊的實(shí)現(xiàn)

波特率發(fā)生器的功能是產(chǎn)生和 RS-232 通信所采用的波特率同步的時(shí)鐘,這樣才能方便地按照 RS-232 串行通信的時(shí)序要求進(jìn)行數(shù)據(jù)接收或者發(fā)送。圖 9 表示了波特率時(shí)鐘和 RS-232接收端信號(hào) RxD 之間的時(shí)序關(guān)系,波特率時(shí)鐘的頻率就是波特率。比如,波特率為 9600,即每秒傳輸 9600 位數(shù)據(jù),則同步的波特率時(shí)鐘頻率為 9600,周期為 1/9600=0.10417 毫秒。

e9547faa-17dc-11ed-ba43-dac502259ad0.png

圖 9 波特率時(shí)鐘與 RxD 時(shí)序圖

實(shí)現(xiàn)上述的波特率時(shí)鐘的基本思路就是設(shè)計(jì)一個(gè)計(jì)數(shù)器,該計(jì)數(shù)器工作在速度很高的系統(tǒng)時(shí)鐘下,當(dāng)計(jì)數(shù)到某數(shù)值時(shí)將輸出置高,再計(jì)數(shù)一定數(shù)值后再將輸出置低,如此反復(fù)便能夠得到所需的波特率時(shí)鐘。假如 FPGA 的系統(tǒng)時(shí)鐘為 50MHz,RS-232 通信的波特率為 9600,則波特率時(shí)鐘的每個(gè)周期相當(dāng)于e965d0f2-17dc-11ed-ba43-dac502259ad0.png個(gè)系統(tǒng)時(shí)鐘的周期。假如要得到占空比為 50%的波特率時(shí)鐘,只要使得計(jì)數(shù)器在計(jì)數(shù)到e96f963c-17dc-11ed-ba43-dac502259ad0.png時(shí)將輸出置高,之后在計(jì)數(shù)到 5208 時(shí)將輸出置低并且重新計(jì)數(shù),就能夠?qū)崿F(xiàn)和 9600 波特率同步的時(shí)鐘,原理圖如圖 10 所示。

e990a192-17dc-11ed-ba43-dac502259ad0.png

圖 10 波特率時(shí)鐘實(shí)現(xiàn)原理

波特率發(fā)生器的端口定義如表 6 所示。

表 6 波特率發(fā)生器端口定義表

e9a2069e-17dc-11ed-ba43-dac502259ad0.png

波特率發(fā)生器在復(fù)位后,將內(nèi)部計(jì)數(shù)器置為“0”,如果使能信號(hào)有效,則在每個(gè)系統(tǒng)時(shí)鐘的上升沿工作,將計(jì)數(shù)器計(jì)數(shù)增加一。當(dāng)輸出一個(gè)完整的波特率時(shí)鐘脈沖后,波特率發(fā)生器會(huì)自動(dòng)將內(nèi)部計(jì)數(shù)器置為零,同時(shí)開(kāi)始進(jìn)行下一個(gè)脈沖的計(jì)數(shù)。還有一個(gè) indicator 信號(hào),每產(chǎn)生一個(gè)完整的波特率時(shí)鐘周期,indicator 信號(hào)會(huì)輸出一個(gè)寬度的高電平。indicator 信號(hào)用于表示產(chǎn)生了一個(gè)完整的波特率時(shí)鐘周期,UART 通過(guò)此信號(hào)來(lái)了解波特率發(fā)生器已輸出的脈沖個(gè)數(shù)。

波特率發(fā)生器的 實(shí)現(xiàn)代碼如下,其中在實(shí)體聲明中聲明了兩個(gè)類屬參數(shù),F(xiàn)ULL_PULSE_COUNT 表示一個(gè)波特率時(shí)鐘完整的周期所對(duì)應(yīng)的計(jì)數(shù)器計(jì)數(shù), RISE_PULSE_COUNT表示波特率時(shí)鐘信號(hào)上升時(shí)刻所對(duì)應(yīng)的計(jì)數(shù)器計(jì)數(shù),這樣波特率時(shí)鐘的占空比可以表示為:

e9b31e7a-17dc-11ed-ba43-dac502259ad0.png。

-- 庫(kù)聲明library IEEE;use IEEE.STD_LOGIC_1164.all;use WORK.UART_PACKAGE.ALL;-- 實(shí)體聲明entity baudrate_generator is    -- 類屬參數(shù)聲明    generic (    FULL_PULSE_COUNT : BD_COUNT := BD9600_FPC;    RISE_PULSE_COUNT : BD_COUNT := BD9600_HPC );    -- 端口聲明    port (    clk : in std_logic;    reset_n : in std_logic;    ce : in std_logic;    bd_out : out std_logic;    indicator : out std_logic );
    end baudrate_generator;
    --}} End of automatically maintained section
-- 結(jié)構(gòu)體architecture baudrate_generator of baudrate_generator isbegin
-- enter your statements here ---- 主過(guò)程    -- main process    main : process( clk, reset_n )    variable clk_count : BD_COUNT;    begin        -- 判斷復(fù)位信號(hào)        if reset_n = '0' then            bd_out <= '0';            indicator <= '0';            clk_count := 0;        -- 在時(shí)鐘信號(hào)的上升沿動(dòng)作        elsif rising_edge(clk) then            -- 判斷使能信號(hào)            if ce = '1' then                -- 經(jīng)過(guò)了 RISE_PULSE_COUNT 個(gè)計(jì)數(shù),數(shù)脈沖上升                if clk_count = RISE_PULSE_COUNT-1 then -- pulse rise                    bd_out <= '1';                    clk_count := clk_count+1;                -- 經(jīng)過(guò)了 FULL_PULSE_COUNT 個(gè)計(jì)數(shù),數(shù)脈沖下降    elsifclk_count=FULL_PULSE_COUNT-1then--indicatoroutputandpulse fall                    -- 輸出提示信號(hào),使其為高                    indicator <= '1';                    bd_out <= '0';                    -- 重置計(jì)數(shù)器計(jì)數(shù)為 0                    clk_count := 0;                -- 恢復(fù)提示信號(hào)為低                elsif clk_count = 0 then                    indicator <= '0';                    clk_count := clk_count+1;                else                    clk_count := clk_count+1;            end if;            end if;        end if;
   end process;
end baudrate_generator;

以上代碼中的 BD_COUNT 是在 UART_PACKAGE 庫(kù)中定義的,它代表范圍從 0~65535 的整數(shù)(即16 位整數(shù));BD9600_FPC 代表波特率時(shí)鐘完整周期對(duì)應(yīng)的計(jì)數(shù),而 BD9600_HFC 代表的是波特率時(shí)鐘半周期對(duì)應(yīng)的計(jì)數(shù),它們也是在 UART_PACKAGE 庫(kù)中定義的,如下所示:

-- 計(jì)數(shù)器計(jì)數(shù)范圍type BD_COUNT is range 65535 downto 0;-- 9600 波特率對(duì)應(yīng)參數(shù)
constant BD9600_FPC : BD_COUNT := 5208;constant BD9600_HPC : BD_COUNT := 2604;

下面介紹一下波特率發(fā)生器的仿真測(cè)試過(guò)程。由于 9600 波特率對(duì)應(yīng)的參數(shù)數(shù)值比較大,所 以 為 了 便 于 觀 察 仿 真 的 波 形 , 可 以 首 先 選 用 數(shù) 值 較 小 的 測(cè) 試 數(shù) 據(jù) 。比 如 , 可 以 在UART_PACKAGE 庫(kù)中定義完整波特率時(shí)鐘周期對(duì)應(yīng)計(jì)數(shù)為 10,半周期對(duì)應(yīng)計(jì)數(shù)為 5,代碼如下:

-- 波特率測(cè)試參數(shù)constant BDTEST_FPC : BD_COUNT := 10;constant BDTEST_HPC : BD_COUNT := 5;

在測(cè)試平臺(tái)文件中,聲明波特率發(fā)生器實(shí)例時(shí)應(yīng)該將其類屬參數(shù)設(shè)置為測(cè)試參數(shù),如下所示:

-- 波特率發(fā)生器實(shí)例UUT : baudrate_generator    generic map (    FULL_PULSE_COUNT => BDTEST_FPC,    RISE_PULSE_COUNT => BDTEST_HPC    )
    port map (        clk => clk,        reset_n => reset_n,        ce => ce,        bd_out => bd_out,        indicator => indicator     );

完整的波特率發(fā)生器測(cè)試平臺(tái)請(qǐng)參考 UART 工程源代碼中的 baudrate_generator_tb.vhd文件,使用測(cè)試參數(shù)仿真得到的波形如圖 11 所示。觀察波形可以看到波特率發(fā)生器每經(jīng)過(guò)10 個(gè)時(shí)鐘周期輸出一個(gè)完整的波特率時(shí)鐘周期,占空比為 1/2,并且在每次輸出完整脈沖后輸出一個(gè)系統(tǒng)時(shí)鐘脈寬的提示信號(hào),可見(jiàn)波特率發(fā)生器的工作完全滿足設(shè)計(jì)的要求。

e9c3b2d0-17dc-11ed-ba43-dac502259ad0.png

圖 11 波特率時(shí)鐘實(shí)現(xiàn)原理

使用測(cè)試參數(shù)仿真正常后,可以使用實(shí)際的參數(shù)進(jìn)行測(cè)試。

3.5 移位寄存器模塊的實(shí)現(xiàn)

移位寄存器在整個(gè)設(shè)計(jì)中非常關(guān)鍵,無(wú)論是數(shù)據(jù)接收還是數(shù)據(jù)發(fā)送都需要使用到移位寄存器。移位寄存器的基本工作原理是在觸發(fā)信號(hào)的驅(qū)動(dòng)下將內(nèi)部寄存器序列的最高位輸出,將次高位到最低位向高位移一位,并且讀取輸入端的數(shù)據(jù)保存到最低位。圖 12 所示為移位寄存器的工作原理。

e9da6b1a-17dc-11ed-ba43-dac502259ad0.png

圖 12 移位寄存器工作原理圖

由于 RS-232 通信在不同的傳輸設(shè)置下(比如奇偶校驗(yàn)位、停止位)總的數(shù)據(jù)位不同,所以為了能夠靈活的配置移位寄存器,可以在聲明移位寄存器實(shí)體的時(shí)候添加一個(gè)表示寄存器序列總長(zhǎng)度的類屬參數(shù),代碼如下:

entity shift_register is    -- generic    generic (    TOTAL_BIT : integer := 10 );    -- port    port (          clk : in std_logic;          reset_n : in std_logic;          din : in std_logic;          regs : out std_logic_vector(TOTAL_BIT-1 downto 0);          dout : out std_logic     );end shift_register;

以上代碼中的 TOTAL_BIT 表示的就是寄存器序列的長(zhǎng)度,默認(rèn)為 10,對(duì)應(yīng)的傳輸設(shè)置是 8位數(shù)據(jù)位、奇偶校驗(yàn)位、1 位停止位。移位寄存器的端口定義如表 7 所示。

表 7 移位寄存器端口定義表

e9ee7402-17dc-11ed-ba43-dac502259ad0.png

完整的移位寄存器實(shí)現(xiàn)代碼如下:

-- 庫(kù)聲明library IEEE;use IEEE.STD_LOGIC_1164.all;-- 實(shí)體聲明entity shift_register is    -- 類屬參數(shù)    generic (    TOTAL_BIT : integer := 10 );    -- 端口    port (    clk : in std_logic;    reset_n : in std_logic;    din : in std_logic;    regs : out std_logic_vector(TOTAL_BIT-1 downto 0);    dout : out std_logic );
end shift_register;
--}} End of automatically maintained section-- 結(jié)構(gòu)體architecture shift_register of shift_register is-- 內(nèi)部寄存器序列signal shift_regs : std_logic_vector(TOTAL_BIT-1 downto 0) := (others => '1');begin    -- 寄存器輸出    regs <= shift_regs;    -- 主過(guò)程    main : process(reset_n, clk)    begin        -- 檢查復(fù)位信號(hào)        if reset_n = '0' then            dout <= '1';        -- 在時(shí)鐘上升沿動(dòng)作        elsif rising_edge(clk) then            -- 將最高位輸出到 dout            dout <= shift_regs(TOTAL_BIT-1);            -- 次高位到最低位都向高位移一位            shift_regs(TOTAL_BIT-1 downto 1) <= shift_regs(TOTAL_BIT-2 downto 0);            -- 讀取輸入端口信號(hào)并且保存到寄存器序列的最低位            shift_regs(0) <= din;        end if;    end process;
end shift_register

編寫(xiě)一個(gè)測(cè)試平臺(tái)對(duì)上述的代碼進(jìn)行測(cè)試,得到的仿真波形如圖 13 所示。移位寄存器復(fù)位后在每個(gè)時(shí)鐘的上升沿工作,輸出寄存器最高位,將寄存器移位并且將輸入端保存到寄存器最低位。由于輸入信號(hào) din 以時(shí)鐘周期為 “0”和“1”之間交替變化,所以移位寄存器每次保存到最低位的數(shù)據(jù)也是“0”、“1”交替變化,最后其內(nèi)部寄存器也會(huì)呈現(xiàn)“0”、“1”交替的情況。所以上述的代碼符合設(shè)計(jì)的要求。

ea05bff4-17dc-11ed-ba43-dac502259ad0.png

圖 13 移位寄存器仿真時(shí)序圖

3.6 奇偶校驗(yàn)器模塊的實(shí)現(xiàn)

奇偶校驗(yàn)器根據(jù)奇偶校驗(yàn)的設(shè)置和輸入數(shù)據(jù)計(jì)算出奇偶校驗(yàn)位,所以在定義其實(shí)體時(shí)需要添加兩個(gè)類屬參數(shù) DATA_LENGTH 和 PARITY_RULE,分別表示校驗(yàn)數(shù)據(jù)的長(zhǎng)度和校驗(yàn)規(guī)則,代碼如下:

entity parity_verifier is    generic (    DATA_LENGTH : integer := 8;    PARITY_RULE : PARITY := NONE );    port (          source : in std_logic_vector(DATA_LENGTH-1 downto 0);          parity : out std_logic );end parity_verifier;

其中,PARITY 是在 UART_PACKAGE 庫(kù)中定義的,代碼如下:

-- 奇偶校驗(yàn)規(guī)則定義typePARITYis(              NONE, -- 無(wú)奇偶校驗(yàn)              ODD, -- 奇校驗(yàn)              EVEN -- 偶校驗(yàn)         );

奇偶校驗(yàn)器的端口定義如表 8 所示。

表 8 奇偶校驗(yàn)器端口定義表

ea168b40-17dc-11ed-ba43-dac502259ad0.png

奇偶校驗(yàn)器的實(shí)現(xiàn)代碼如下:

-- 庫(kù)聲明library IEEE;use IEEE.STD_LOGIC_1164.all;use WORK.UART_PACKAGE.ALL;-- 實(shí)體聲明entity parity_verifier is    -- 類屬參數(shù)    generic (    DATA_LENGTH : integer := 8;    PARITY_RULE : PARITY := NONE );    -- 端口    port (    source : in std_logic_vector(DATA_LENGTH-1 downto 0);    parity : out std_logic );end parity_verifier;
--}} End of automatically maintained section-- 結(jié)構(gòu)體architecture parity_verifier of parity_verifier isbegin
    -- enter your statements here --    -- 按照校驗(yàn)規(guī)則計(jì)算校驗(yàn)位    with PARITY_RULE select    parity <= MultiXOR(source) when ODD, -- 奇校驗(yàn)                      ( not MultiXOR(source) ) when EVEN, -- 偶校驗(yàn)                      '1' when others;
end parity_verifier;

上述奇偶校驗(yàn)器實(shí)現(xiàn)代碼中的 MultiXOR 函數(shù)也是在 UART_PACKAGE 庫(kù)中定義的,其功能是對(duì)輸入序列進(jìn)行異或計(jì)算。MultiXOR 的函數(shù)聲明如下:

function MultiXOR(                    din : in std_logic_vector )                    return std_logic;

MultiXOR 的函數(shù)實(shí)現(xiàn)如下:

function MultiXOR(            din : in std_logic_vector )            return std_logic is            variable check : std_logic;begin    check := din(din'LOW);    for i in 1 to (din'HIGH) loop        check := check xor din(i);    end loop;
    return check;end MultiXOR;

對(duì)上述奇偶校驗(yàn)器進(jìn)行仿真測(cè)試,在偶校驗(yàn)設(shè)置下,仿真得到的波形如圖 14 所示。

ea4492a6-17dc-11ed-ba43-dac502259ad0.png

圖 14 奇偶校驗(yàn)器仿真波形

注意:偶校驗(yàn)和奇校驗(yàn)的計(jì)算有一個(gè)技巧。如果使用偶校驗(yàn),在待校驗(yàn)序列中有偶數(shù)個(gè)“1”,則得到的結(jié)果為“1”,反之為“0”;如果使用奇校驗(yàn),在待校驗(yàn)序列中有奇數(shù)個(gè)“1”,則得到的結(jié)果為“1”,反之為“0”。

3.7 總線選擇器模塊的實(shí)現(xiàn)

總線選擇器模塊的功能是通過(guò)一個(gè)選擇信號(hào)控制兩個(gè)輸入信號(hào),將其輸出,也就是一個(gè)二選一的選擇器。圖 15 是總線選擇模塊的框圖,當(dāng)選擇信號(hào) sel 為低時(shí),將會(huì)把輸入總線一din1 輸出,否則在選擇信號(hào) sel 為高時(shí),將會(huì)把輸入總線二 din2 輸出。

ea5b7aca-17dc-11ed-ba43-dac502259ad0.png

圖 15 總線選擇器框圖

為了能夠使總線選擇器適應(yīng)不同寬度的總線,在聲明其實(shí)體的時(shí)候可以添加一個(gè)BUS_WIDTH 的類屬參數(shù),它表示總線的寬度,代碼如下:

entity switcher_bus is    -- 類屬參數(shù)    generic (    BUS_WIDTH : integer := 8 ); -- 總線寬度    port (    din1 : in std_logic_vector(BUS_WIDTH-1 downto 0); -- 輸入總線一    din2 : in std_logic_vector(BUS_WIDTH-1 downto 0); -- 輸入總線二    sel : in std_logic; -- 選擇信號(hào)    dout : out std_logic_vector(BUS_WIDTH-1 downto 0) ); -- 輸出總線end switcher_bus;

總線選擇器的端口定義如表 9 所示。

表 9 總線選擇器端口定義表

ea649a9c-17dc-11ed-ba43-dac502259ad0.png

總線選擇器的實(shí)現(xiàn)代碼如下:

-- 庫(kù)聲明library IEEE;use IEEE.STD_LOGIC_1164.all;-- 實(shí)體聲明entity switcher_bus is    -- 類屬參數(shù)    generic (    BUS_WIDTH : integer := 8 ); -- 總線寬度    port (    din1 : in std_logic_vector(BUS_WIDTH-1 downto 0); -- 輸入總線一    din2 : in std_logic_vector(BUS_WIDTH-1 downto 0); -- 輸入總線二    sel : in std_logic; -- 選擇信號(hào)    dout : out std_logic_vector(BUS_WIDTH-1 downto 0) ); -- 輸出總線end switcher_bus;
--}} End of automatically maintained section-- 結(jié)構(gòu)體architecture switcher_bus of switcher_bus isbegin    -- 使用 select 語(yǔ)句    with sel select    dout <= din1 when '0',        din2 when others;end switcher_bus;

編寫(xiě)一個(gè)測(cè)試平臺(tái)對(duì)上述代碼進(jìn)行測(cè)試,使得輸入總線一上的數(shù)據(jù)為“11110000”,輸入總線二上的數(shù)據(jù)為“00001111”,再分別使選擇信號(hào)為“0”和“1”。得到的仿真波形如圖 16所示,輸出總線在選擇信號(hào)為“0”時(shí)是“11110000”,即輸入總線一的數(shù)據(jù),而當(dāng)選擇信號(hào)變?yōu)椤?”后,輸出總線上的數(shù)據(jù)也變?yōu)檩斎肟偩€二的數(shù)據(jù)“00001111”,可見(jiàn)上述代碼完全實(shí)現(xiàn)了設(shè)計(jì)所需的功能。

ea832994-17dc-11ed-ba43-dac502259ad0.png

圖 16 總線選擇器仿真波形

3.8 計(jì)數(shù)器模塊的實(shí)現(xiàn)

計(jì)數(shù)器模塊的功能是可控地在輸入時(shí)鐘驅(qū)動(dòng)下進(jìn)行計(jì)數(shù),當(dāng)?shù)竭_(dá)計(jì)數(shù)上閾時(shí)給 UART 內(nèi)核一個(gè)提示信號(hào)。在不同的工作狀態(tài)下,計(jì)數(shù)器模塊的輸入時(shí)鐘是不同的。UART 在數(shù)據(jù)發(fā)送之前需要進(jìn)行數(shù)據(jù)加載(即將串行序列保存到移位寄存器內(nèi)),在此過(guò)程中計(jì)數(shù)器模塊的輸入時(shí)鐘就是系統(tǒng)時(shí)鐘,因?yàn)榇藭r(shí)移位寄存器也是工作在系統(tǒng)時(shí)鐘下的。除了數(shù)據(jù)加載,另外兩個(gè)需要計(jì)數(shù)器模塊的過(guò)程是數(shù)據(jù)接收和數(shù)據(jù)發(fā)送,由于這兩個(gè)過(guò)程中移位寄存器是工作在波特率時(shí)鐘下的,所以計(jì)數(shù)器模塊的時(shí)鐘就是和波特率時(shí)鐘同步的波特率發(fā)生器提示信號(hào) indicator,這樣每輸出一個(gè)完整的波特率時(shí)鐘周期計(jì)數(shù)器就能增加一。

計(jì)數(shù)器計(jì)數(shù)的上閾是在實(shí)體聲明中定義的,代碼如下。代碼中的 MAX_COUNT 類屬參數(shù)就是計(jì)數(shù)上閾。

entity counter is    generic (    MAX_COUNT : integer := 10 );    port (    clk : in std_logic;    reset_n : in std_logic;    ce : in std_logic;    overflow : out std_logic );end counter;

計(jì)數(shù)器模塊的端口定義如表 10 所示。

表 10 計(jì)數(shù)器端口定義表

eaa20cf6-17dc-11ed-ba43-dac502259ad0.png

計(jì)數(shù)器模塊的實(shí)現(xiàn)代碼如下:

-- 庫(kù)聲明library IEEE;use IEEE.STD_LOGIC_1164.all;-- 實(shí)體聲明entity counter is    generic (    MAX_COUNT : integer := 10 );    port (    clk : in std_logic;    reset_n : in std_logic;    ce : in std_logic;    overflow : out std_logic );end counter;
--}} End of automatically maintained section-- 結(jié)構(gòu)體architecture counter of counter issignal count : integer;begin
    -- enter your statements here --    -- 主過(guò)程    main: process( clk, reset_n )    begin        -- 判斷復(fù)位信號(hào)        if reset_n = '0' then            count <= 0;            overflow <= '0';        -- 時(shí)鐘信號(hào)的上升沿動(dòng)作        elsif rising_edge(clk) and ce = '1' then            -- 在計(jì)數(shù)上閾時(shí)候輸出提示信號(hào) overflow            if count = MAX_COUNT-1 then                count <= 0;                overflow <= '1';            -- 恢復(fù)提示信號(hào) overflow 為低            elsif count = 0 then                count <= count+1;                overflow <= '0';            else                count <= count+1;            end if;      end if;  end process;end counter

對(duì)上述代碼進(jìn)行仿真測(cè)試,得到的仿真波形如圖 17 所示。計(jì)數(shù)器在復(fù)位后并且 ce 有效時(shí)開(kāi)始計(jì)數(shù),并且在第 10 個(gè)時(shí)鐘周期輸出提示信號(hào) overflow。

eab60c56-17dc-11ed-ba43-dac502259ad0.png

圖 17 計(jì)數(shù)器仿真波形

3.9 UART 內(nèi)核模塊的實(shí)現(xiàn)

UART 內(nèi)核模塊是整個(gè)設(shè)計(jì)的核心,所以它也是整個(gè)設(shè)計(jì)中最為復(fù)雜的模塊。由于 UART 內(nèi)核模塊的整體結(jié)構(gòu)比較復(fù)雜,下面的內(nèi)容將從模塊接口、狀態(tài)機(jī)設(shè)計(jì)和實(shí)現(xiàn)代碼 3 方面介紹UART 內(nèi)核的實(shí)現(xiàn)方法。

1)UART 內(nèi)核模塊的接口

(1)CPUUART 內(nèi)核模塊提供的 CPU 接口就是 UART 模塊的 CPU 接口,如圖 18 虛線框中所示。

eacf1c8c-17dc-11ed-ba43-dac502259ad0.png

圖 18 UART 內(nèi)核模塊的 CPU 接口

這些端口又可以分為兩組:第一組是與發(fā)送相關(guān)的,包括 send、send_bus 和 send_over,其中 send 信號(hào)是發(fā)送控制的信號(hào),send_bus 是待發(fā)送數(shù)據(jù)的總線,send_over 是發(fā)送完成的提示信號(hào);第二組是與接收相關(guān)的,包括 recv、recv_bus 和 error,其中 recv 信號(hào)表示有新的數(shù)據(jù)被接收,recv_bus 是接收數(shù)據(jù)的總線,error 信號(hào)表示數(shù)據(jù)接收產(chǎn)生錯(cuò)誤。CPU 接口的端口定義如表 11 所示。

表 11 CPU 接口端口定義表

eae1a866-17dc-11ed-ba43-dac502259ad0.png

其中,DATA_BIT 是 UART 內(nèi)核模塊實(shí)體聲明中定義的類屬參數(shù),表示數(shù)據(jù)位的長(zhǎng)度。

(2)奇偶校驗(yàn)器UART

內(nèi)核模塊通過(guò)總線選擇模塊和奇偶校驗(yàn)器模塊實(shí)現(xiàn)奇偶校驗(yàn),它們之間的連接方式如圖 19 所示。

eb1085a0-17dc-11ed-ba43-dac502259ad0.png

圖 19 奇偶校驗(yàn)相關(guān)模塊連接示意圖

總線選擇器的兩個(gè)輸入端分別連接到數(shù)據(jù)發(fā)送總線 send_bus 和數(shù)據(jù)接收總線 recv_bus上,它的輸出連接到奇偶校驗(yàn)器的輸入端,最后奇偶校驗(yàn)器的校驗(yàn)結(jié)果輸出連接到 UART 的一個(gè)端口 parity 上。這樣的連接方式有一個(gè)好處,就是在發(fā)送和接收的不同過(guò)程中,只要通過(guò)一個(gè)總線選擇信號(hào) sel_pv 就能夠選擇不同的奇偶校驗(yàn)內(nèi)容,sel_pv 信號(hào)是由 UART 內(nèi)核的一個(gè)端口連接到總線選擇器的選擇信號(hào)端口上。

由上述內(nèi)容可知, UART 使用的端口除了上面已經(jīng)介紹的數(shù)據(jù)發(fā)送總線和數(shù)據(jù)接收總線外,就是總線選擇信號(hào) sel_pv 和奇偶校驗(yàn)信號(hào) parity 了。它們的定義如表 12 所示。

表 12 奇偶校驗(yàn)端口定義表

eb1ecec6-17dc-11ed-ba43-dac502259ad0.png

(3)計(jì)數(shù)器模塊

計(jì)數(shù)器模塊的功能是在輸入時(shí)鐘的驅(qū)動(dòng)下進(jìn)行計(jì)數(shù),當(dāng)?shù)竭_(dá)計(jì)數(shù)上閾時(shí)給 UART 內(nèi)核一個(gè)提示信號(hào),它們兩者之間的連接方法如圖 20 所示。

eb2d0c7a-17dc-11ed-ba43-dac502259ad0.png

圖 20 UART 內(nèi)核模塊和計(jì)數(shù)器模塊連接示意圖

在數(shù)據(jù)接收、數(shù)據(jù)加載和數(shù)據(jù)發(fā)送過(guò)程中,都需要使用到計(jì)數(shù)器,并且不同的過(guò)程中提供給計(jì)數(shù)器的時(shí)鐘信號(hào)是不一樣的。要選擇計(jì)數(shù)器時(shí)鐘信號(hào),可以通過(guò)一個(gè)二選一選擇器實(shí)現(xiàn)。二選一選擇器的兩個(gè)輸入端分別連接到波特率發(fā)生器的 indicator 提示信號(hào)和系統(tǒng)時(shí)鐘信號(hào),同時(shí)其信號(hào)選擇端口連接 UART 內(nèi)核的一個(gè) sel_clk 端口,這樣便可以通過(guò)控制 sel_clk 端口實(shí)現(xiàn)對(duì)計(jì)數(shù)器模塊時(shí)鐘信號(hào)的控制。另一方面,要正確使用計(jì)數(shù)器需要對(duì)其進(jìn)行復(fù)位和使能,所以 UART 內(nèi)核還提供了兩個(gè)端口 reset_parts 和 ce_parts,作為子模塊復(fù)位信號(hào)和使能信號(hào)的端口。以上介紹的 4 個(gè)端口定義如表 5-13 所示。

表 13 奇偶校驗(yàn)端口定義表

eb400e38-17dc-11ed-ba43-dac502259ad0.png

(4)移位寄存器UART

內(nèi)核和移位寄存器之間的接口主要可以分為 3 個(gè)作用:第一,UART 內(nèi)核需要控制數(shù)據(jù)加載過(guò)程,所以具有向移位寄存器發(fā)送串行數(shù)據(jù)的接口;第二,已接收的數(shù)據(jù)是保存在移位寄存器內(nèi)部的,所以移位寄存器具有提供內(nèi)部寄存器數(shù)據(jù)的接口;第三,在不同的工作流程中,移位寄存器的工作時(shí)鐘也不同,可能是波特率時(shí)鐘,也可能是系統(tǒng)時(shí)鐘,所以 UART 內(nèi)核還需要有控制移位寄存器輸入時(shí)鐘的信號(hào)接口。圖 21 是 UART 內(nèi)核和移位寄存器之間的連接示意圖。

eb5e9c4a-17dc-11ed-ba43-dac502259ad0.png

圖 21 UART 內(nèi)核與移位寄存器連接示意圖

UART 內(nèi)核對(duì)數(shù)據(jù)加載過(guò)程的控制是通過(guò) send_si 信號(hào)、sel_si 信號(hào)和一個(gè)二選一選擇器實(shí)現(xiàn)的。圖 21 中左側(cè)的二選一選擇器的作用即是串行數(shù)據(jù)選擇,它的輸入端分別接到 UART內(nèi)核的串行數(shù)據(jù)發(fā)送端口 send_si 和 RS-232 的數(shù)據(jù)接收端口 RxD,信號(hào)選擇端口則和 UART 內(nèi)核的 sel_si 端口相連,輸出端口連接到移位寄存器的數(shù)據(jù)輸入端口。這樣,在進(jìn)行數(shù)據(jù)加時(shí),UART 內(nèi)核可以通過(guò) sel_si 信號(hào)控制 UART 內(nèi)核的串行數(shù)據(jù)輸入端口作為移位寄存器的輸入;當(dāng)進(jìn)行數(shù)據(jù)接收時(shí),UART 內(nèi)核又可以將 RS-232 的接收端口 RxD 選擇為移位寄存器的輸入。

UART 內(nèi)核對(duì)移位寄存器輸入時(shí)鐘的控制方法和對(duì)計(jì)數(shù)器的控制方法一樣,也是利用了一個(gè)二選一選擇器,再通過(guò)選擇信號(hào)控制。圖 5-21 中右側(cè)的二選一選擇器的作用便是實(shí)現(xiàn)對(duì)移位寄存器輸入時(shí)鐘的選擇,它的兩個(gè)輸入信號(hào)分別是波特率時(shí)鐘 bd_clk 和系統(tǒng)時(shí)鐘,選擇信號(hào)連接到 UART 內(nèi)核的一個(gè)端口 sel_clk 上,輸出和移位寄存器的輸入時(shí)鐘端口相連。

移位寄存器內(nèi)部寄存器的數(shù)據(jù)是通過(guò)一個(gè) regs 端口發(fā)送給 UART 內(nèi)核的,regs 端口是多位信號(hào),其寬度就是 RS-232 串行通信的總位數(shù)(起始位、數(shù)據(jù)位、奇偶校驗(yàn)位和停止位)。表5-14 所示為 UART 內(nèi)核和移位寄存器之間的端口。

表 14 UART 內(nèi)核與移位寄存器間端口定義表

eb72fa64-17dc-11ed-ba43-dac502259ad0.png

除了表 14 所列的端口,UART 內(nèi)核的 reset_parts 端口還和移位寄存器的復(fù)位端口相連,作為它的復(fù)位信號(hào)。

(5)波特率發(fā)生器

UART 內(nèi)核和波特率發(fā)生器之間的接口比較簡(jiǎn)單,只有復(fù)位和使能兩個(gè)信號(hào),即圖 22 所示中的 reset_parts 和 ce_parts 信號(hào)。

eb800876-17dc-11ed-ba43-dac502259ad0.png

圖 22 UART 內(nèi)核與波特率發(fā)生器連接示意圖

波特率發(fā)生器的復(fù)位、使能信號(hào)與計(jì)數(shù)器的相同,其端口定義參考表 13 所示。

(6)信號(hào)監(jiān)測(cè)器

UART 內(nèi)核不但需要接收信號(hào)監(jiān)測(cè)器的指示信號(hào),同時(shí)還需要在完成數(shù)據(jù)接收后控制信號(hào)監(jiān)測(cè)器復(fù)位。所以,UART 內(nèi)核和信號(hào)監(jiān)測(cè)器之間有兩個(gè)接口,第一個(gè)是監(jiān)測(cè)到數(shù)據(jù)傳輸?shù)奶崾拘盘?hào)接口 new_data,另一個(gè)是用于復(fù)位信號(hào)監(jiān)測(cè)器的 reset_dt 信號(hào)。圖 23 所示是 UART內(nèi)核與信號(hào)監(jiān)測(cè)器連接示意圖。

eb909a38-17dc-11ed-ba43-dac502259ad0.png

圖 23 UART 內(nèi)核與信號(hào)監(jiān)測(cè)器連接示意圖

UART 內(nèi)核和信號(hào)監(jiān)測(cè)器的端口定義如表 15 所示。

表 15 UART 內(nèi)核與信號(hào)監(jiān)測(cè)器間端口定義表

ebab42f2-17dc-11ed-ba43-dac502259ad0.png

(7)RS-232 串行發(fā)送端口

移位寄存器在進(jìn)行移位的時(shí)候,會(huì)將最高位輸出,但是只有在發(fā)送數(shù)據(jù)的時(shí)候才需要將移位寄存器的數(shù)據(jù)串行輸出,所以移位寄存器的輸出端不能直接連到 RS-232 串行發(fā)送端口上,它們之間需要添加一個(gè)二選一選擇器,如圖 24 所示。

ebbcf2c2-17dc-11ed-ba43-dac502259ad0.png

圖 24 RS-232 串行發(fā)送端口連接示意圖

圖 24 中的二選一選擇器的輸入信號(hào)分別是高電平 VCC(即邏輯“1”)和移位寄存器輸出 dout,選擇信號(hào)連接到 UART 內(nèi)核的一個(gè)端口 set_out,輸出連接到 RS-232 串行發(fā)送端口TxD 上。這樣,UART 內(nèi)核就可以通過(guò) sel_out 信號(hào)選擇向 TxD 發(fā)送的數(shù)據(jù),在發(fā)送過(guò)程中將移位寄存器輸出 dout 送到 TxD 上,在其他的過(guò)程中則將高電平送到 TxD 上。

2)UART 內(nèi)核模塊的狀態(tài)機(jī)設(shè)計(jì)

UART 內(nèi)核模塊的功能是控制數(shù)據(jù)接收、數(shù)據(jù)加載和數(shù)據(jù)發(fā)送的過(guò)程,這可以用狀態(tài)機(jī)來(lái)實(shí)現(xiàn)。下面就按接收和發(fā)送的過(guò)程來(lái)介紹 UART 內(nèi)核模塊狀態(tài)機(jī)的實(shí)現(xiàn)。

(1)數(shù)據(jù)接收過(guò)程

數(shù)據(jù)接收過(guò)程的流程圖如圖 6 所示,可以定義 3 個(gè)狀態(tài)——空閑、接收和接收完成,其狀態(tài)變換圖如圖 25 所示。

UART 內(nèi)核模塊在復(fù)位后進(jìn)入空閑狀態(tài)。如果信號(hào)監(jiān)測(cè)器監(jiān)測(cè)到數(shù)據(jù)傳輸,會(huì)給 UART 內(nèi)核發(fā)送一個(gè)提示信號(hào),UART 內(nèi)核監(jiān)測(cè)到此信號(hào)就會(huì)進(jìn)入接收狀態(tài)。在 UART 內(nèi)核由空閑狀態(tài)轉(zhuǎn)為接收狀態(tài)過(guò)程中,需要進(jìn)行一系列的接收預(yù)備操作,包括將子模塊復(fù)位、選擇移位寄存器串行輸入數(shù)據(jù)、選擇移位寄存器時(shí)鐘等。

進(jìn)入接收狀態(tài)后,波特率發(fā)生器開(kāi)始工作,其輸出波特率時(shí)鐘驅(qū)動(dòng)移位寄存器同步地存儲(chǔ) RS-232 接收端口上的數(shù)據(jù),并且其提示信號(hào)驅(qū)動(dòng)計(jì)數(shù)器進(jìn)行計(jì)數(shù)。當(dāng)所有數(shù)據(jù)接收完成,計(jì)數(shù)器也達(dá)到了其計(jì)數(shù)的上閾,它會(huì)給 UART 內(nèi)核發(fā)送一個(gè)信號(hào),使得 UART 內(nèi)核進(jìn)入接收完成的狀態(tài)。UART 內(nèi)核進(jìn)入接收完成狀態(tài)的同時(shí),會(huì)檢查奇偶校驗(yàn)的結(jié)果,同時(shí)使得子模塊使能信號(hào)無(wú)效以停止各個(gè)子模塊。UART 內(nèi)核的接收完成狀態(tài)僅僅保持一個(gè)時(shí)鐘周期,設(shè)置這個(gè)狀態(tài)的作用是借用一個(gè)時(shí)鐘周期復(fù)位信號(hào)監(jiān)測(cè)器,準(zhǔn)備接收下次數(shù)據(jù)傳輸。

ebcb6370-17dc-11ed-ba43-dac502259ad0.png

圖 25 UART 內(nèi)核數(shù)據(jù)接收狀態(tài)轉(zhuǎn)換圖

(2)數(shù)據(jù)加載和發(fā)送過(guò)程

數(shù)據(jù)加載和發(fā)送的過(guò)程都是為了發(fā)送數(shù)據(jù)而設(shè)定的,所以將它們放在一起進(jìn)行介紹??梢杂?4 個(gè)狀態(tài)來(lái)實(shí)現(xiàn)上述的過(guò)程,即空閑、加載、發(fā)送和發(fā)送完成,其中的空閑狀態(tài)就是 UART內(nèi)核復(fù)位后的空閑狀態(tài),和上面介紹的數(shù)據(jù)接收過(guò)程的空閑狀態(tài)一致。數(shù)據(jù)加載和發(fā)送過(guò)程的狀態(tài)轉(zhuǎn)換圖如圖 26 所示。

ebd687b4-17dc-11ed-ba43-dac502259ad0.png

圖 26 UART 內(nèi)核數(shù)據(jù)加載和發(fā)送狀態(tài)轉(zhuǎn)換圖

數(shù)據(jù)加載過(guò)程在數(shù)據(jù)發(fā)送過(guò)程之前進(jìn)行。UART 內(nèi)核復(fù)位后進(jìn)入空閑狀態(tài),當(dāng)探測(cè)到發(fā)送控制信號(hào)有效時(shí),便會(huì)進(jìn)入加載狀態(tài)開(kāi)始數(shù)據(jù)加載。在進(jìn)入加載狀態(tài)的同時(shí),UART 內(nèi)核會(huì)將移位寄存器、計(jì)數(shù)器復(fù)位,并且通過(guò)選擇信號(hào)使得移位寄存器的輸入為 UART 內(nèi)核產(chǎn)生的串行數(shù)據(jù)序列,使得移位存器和計(jì)數(shù)器的工作時(shí)鐘為系統(tǒng)時(shí)鐘。進(jìn)入加載狀態(tài)后,UART 內(nèi)核會(huì)將完整的待發(fā)送序列加載到移位寄存器的數(shù)據(jù)輸入端,發(fā)送的序列是和系統(tǒng)時(shí)鐘同步的,移位寄存器則在系統(tǒng)時(shí)鐘的驅(qū)動(dòng)下不斷讀入輸入端數(shù)據(jù)并且保存在內(nèi)部寄存器內(nèi)。在移位寄存器加載數(shù)據(jù)的同時(shí),計(jì)數(shù)器也在時(shí)鐘的驅(qū)動(dòng)下進(jìn)行計(jì)數(shù),由于都是工作在系統(tǒng)時(shí)鐘下,所以當(dāng)所有數(shù)據(jù)被加載時(shí),計(jì)數(shù)器也達(dá)到了計(jì)數(shù)的上閾(即串行數(shù)據(jù)的總量),它會(huì)產(chǎn)生一個(gè)提示信號(hào)使得UART 內(nèi)核進(jìn)入發(fā)送狀態(tài)。

UART 內(nèi)核進(jìn)入發(fā)送狀態(tài)的同時(shí)會(huì)改變幾個(gè)選擇信號(hào),比如將移位寄存器時(shí)鐘設(shè)為波特率時(shí)鐘,將計(jì)數(shù)器時(shí)鐘設(shè)為波特率的提示信號(hào),最重要的是將輸出信號(hào)送到 RS-232 的發(fā)送端口TxD 上。發(fā)送的過(guò)程和接收類似,移位寄存器在波特率時(shí)鐘的驅(qū)動(dòng)下內(nèi)部寄存器的數(shù)據(jù)串行的發(fā)送出去,同時(shí)計(jì)數(shù)器在波特率發(fā)生器的提示信號(hào)驅(qū)動(dòng)下進(jìn)行計(jì)數(shù)。UART 內(nèi)核在計(jì)數(shù)器到達(dá)計(jì)數(shù)上閾后便進(jìn)入發(fā)送完成模式,并且輸出發(fā)送完成信號(hào)。

3)UART 內(nèi)核模塊的實(shí)現(xiàn)代碼

由于 UART 內(nèi)核控制著所有的處理過(guò)程,并且還要跟大部分模塊進(jìn)行通信,所以它的實(shí)現(xiàn)代碼比較復(fù)雜。為了能夠便于讀者理解,下面將分 5 部分對(duì)其進(jìn)行介紹。

(1)實(shí)體聲明

上面的內(nèi)容已經(jīng)介紹了 UART 內(nèi)核和其他模塊之間的接口,在實(shí)體聲明中,需要將所有的接口都包括進(jìn)去。表 16 所示總結(jié)了所有的 UART 內(nèi)核接口。

表 16 UART 內(nèi)核端口定義表

ebf079c6-17dc-11ed-ba43-dac502259ad0.png

除了上述的端口,UART 內(nèi)核模塊的聲明中還需要聲明 3 個(gè)類屬參數(shù),分別是 DATA_BIT、TOTAL_BIT 和 PARITY_RULE,分別表示數(shù)據(jù)位個(gè)數(shù)、總數(shù)據(jù)個(gè)數(shù)、奇偶校驗(yàn)規(guī)則。

UART 內(nèi)核的實(shí)體聲明代碼如下:

entity uart_core is    generic (    -- 數(shù)據(jù)位個(gè)數(shù)    DATA_BIT : integer := 8;    -- 總數(shù)據(jù)個(gè)數(shù)    TOTAL_BIT : integer := 10;    -- 奇偶校驗(yàn)規(guī)則    PARITY_RULE : PARITY := NONE );    port (    -- 時(shí)鐘和復(fù)位信號(hào)    clk : in std_logic;    reset_n : in std_logic;    -- 和信號(hào)監(jiān)測(cè)器的接口信號(hào)    new_data : in std_logic;    reset_dt : out std_logic;    -- 復(fù)位、使能子模塊的信號(hào)    reset_parts : out std_logic;    ce_parts : out std_logic;    -- 和移位寄存器的接口信號(hào)    send_si : out std_logic;    sel_si : out std_logic;    regs : in std_logic_vector(TOTAL_BIT-1 downto 0);    -- 計(jì)數(shù)器時(shí)鐘選擇信號(hào)和計(jì)數(shù)器計(jì)數(shù)到達(dá)上閾的指示信號(hào)    sel_clk : out std_logic;    overflow : in std_logic;    -- 和奇偶校驗(yàn)器的接口信號(hào)    sel_pv : out std_logic;    parity : in std_logic;    -- 輸出選擇信號(hào)    sel_out : out std_logic;    -- 提供給 CPU 的接口信號(hào)    send : in std_logic;    send_bus : in std_logic_vector(DATA_BIT-1 downto 0);    send_over : out std_logic;    recv : out std_logic;    recv_bus : out std_logic_vector(DATA_BIT-1 downto 0);    error : out std_logic );
end uart_core;

(2)內(nèi)部信號(hào)定義

在 UART 內(nèi)核模塊內(nèi)部需要定義 3 個(gè)信號(hào),如下:

signal state : UART_STATE := UART_IDLE;signal send_buf : std_logic_vector(TOTAL_BIT-1 downto 0);signal si_count : integer range 0 to 15 := 0;

其中 state 信號(hào)是狀態(tài)機(jī)狀態(tài)信號(hào);send_buf 表示待發(fā)送串行序列的緩沖寄存器;si_count 是發(fā)送序列的索引信號(hào),在生成加載的串行發(fā)送序列時(shí)候需要使用到。

(3)串行加載序列的生成方法

串行加載序列的生成有兩個(gè)步驟,第一個(gè)步驟是將起始位、數(shù)據(jù)位、奇偶校驗(yàn)的結(jié)果等存儲(chǔ)到待發(fā)送串行序列的緩存寄存器內(nèi)。這是通過(guò)一個(gè)過(guò)程來(lái)實(shí)現(xiàn)的,過(guò)程的觸發(fā)信號(hào)是數(shù)據(jù)發(fā)送總線和奇偶校驗(yàn)輸入信號(hào),代碼如下。此過(guò)程的功能除了存儲(chǔ)奇偶校驗(yàn)結(jié)果外,還包括存儲(chǔ)起始位的功能。

-- 生成串行加載序列send_buffer: process(send_bus, parity)begin    -- 存儲(chǔ)起始位    send_buf(0) <= '0';    -- 存儲(chǔ)數(shù)據(jù)位    send_buf(DATA_BIT downto 1) <= send_bus(DATA_BIT-1 downto 0);    -- 存儲(chǔ)奇偶校驗(yàn)位和停止位    if PARITY_RULE = ODD or PARITY_RULE = EVEN then        send_buf(DATA_BIT+1) <= parity;        send_buf(TOTAL_BIT-1 downto DATA_BIT+2) <= (others => '1');    else        send_buf(TOTAL_BIT-1 downto DATA_BIT+1) <= (others => '1');    end if;end process;

第二個(gè)步驟是將 send_buf 寄存器序列中的數(shù)據(jù)發(fā)送到 send_si 端口上,發(fā)送的時(shí)序應(yīng)該和系統(tǒng)時(shí)鐘同步。此步驟也是利用一個(gè)過(guò)程實(shí)現(xiàn)的,代碼如下。其中 si_count 是加載串行序列的索引,UART 內(nèi)核在加載過(guò)程中,每經(jīng)過(guò)一個(gè)時(shí)鐘就會(huì)將 si_count 增加 1。

-- serial input switchsi_switch: process(reset_n, si_count)begin    -- 復(fù)位    if reset_n = '0' then        send_si <= '1';    else        -- 將 send_buf 里面的數(shù)據(jù)送到 send_si 端口上        send_si <= send_buf(si_count);    end if;
end process;

(4)復(fù)位處理

UART 內(nèi)核模塊是由 reset_n 信號(hào)控制復(fù)位的,此信號(hào)為低即表示復(fù)位有效。復(fù)位的處理是在一個(gè) UART 內(nèi)核的主過(guò)程中實(shí)現(xiàn)的,代碼如下:

-- 主過(guò)程main: process(clk, reset_n)begin    if reset_n = '0' then        -- 信號(hào)監(jiān)測(cè)器復(fù)位信號(hào)        reset_dt <= '1';        -- 其他模塊的復(fù)位和使能信號(hào)        reset_parts <= '0';        ce_parts <= '0';        -- 移位寄存器輸入        sel_si <= '0';        -- 波特率發(fā)生器和計(jì)數(shù)器的時(shí)鐘選擇信號(hào)        sel_clk <= '0';        -- 奇偶校驗(yàn)器的輸入        sel_pv <= '0';        -- 選擇 TxD 輸出        sel_out <= '0';        -- 與 CPU 之間的接口信號(hào)        send_over <= '0';        recv <= '0';        error <= '0';
        -- 狀態(tài)機(jī)        state <= UART_IDLE;
        -- 串行加載的計(jì)數(shù)        si_count <= 0;    elsif rising_edge(clk) then        -- 狀態(tài)機(jī)實(shí)現(xiàn)    end ifend process;

(5)UART 內(nèi)核模塊的狀態(tài)機(jī)實(shí)現(xiàn)

UART 內(nèi)核的主過(guò)程除了處理復(fù)位信號(hào)外,還控制了數(shù)據(jù)發(fā)送和數(shù)據(jù)接收的狀態(tài)轉(zhuǎn)換,即實(shí)現(xiàn)了狀態(tài)機(jī),代碼如下:

-- 主過(guò)程main: process(clk, reset_n)begin    if reset_n = '0' then        -- 復(fù)位處理    elsif rising_edge(clk) then        case state is            -- 空閑狀態(tài)            when UART_IDLE =>            -- 當(dāng)信號(hào)監(jiān)測(cè)器監(jiān)測(cè)到數(shù)據(jù)時(shí),new_data 變?yōu)椤?’            if new_data = '1' then                -- 復(fù)位子模塊                reset_parts <= '0';                -- 子模塊使能無(wú)效                ce_parts <= '0';                -- 選擇移位寄存器串行輸入為 RxD                sel_si <= '1';                -- 選擇移位寄存器的時(shí)鐘為波特率始終                -- 選擇計(jì)數(shù)器的時(shí)鐘為波特率發(fā)生器的指示信號(hào)                sel_clk <= '0';                -- 使得輸出保持為’1’                sel_out <= '0';                -- 設(shè)置奇偶校驗(yàn)的數(shù)據(jù)源為數(shù)據(jù)發(fā)送總線                sel_pv <= '1';                -- 改變狀態(tài)為接收                state <= UART_RECV;            -- 當(dāng) send 信號(hào)變?yōu)椤?’,表示 CPU 要求發(fā)送數(shù)據(jù)            elsif send = '1' then                -- 復(fù)位子模塊                reset_parts <= '0';                -- 子模塊使能無(wú)效                ce_parts <= '0';                -- 選擇移位寄存器串行輸入為串行加載序列                sel_si <= '0';                -- 選擇移位寄存器的時(shí)鐘為波特率始終                -- 選擇計(jì)數(shù)器的時(shí)鐘為波特率發(fā)生器的指示信號(hào)                sel_clk <= '0';                -- 使得輸出保持為‘1’                sel_out <= '0';                -- 設(shè)置奇偶校驗(yàn)的數(shù)據(jù)源為數(shù)據(jù)發(fā)送總線                sel_pv <= '0';                -- 初始化串行加載序列的索引變量                si_count <= TOTAL_BIT-1;                -- 改變狀態(tài)為加載                state <= UART_LOAD;            else                -- 停止對(duì)信號(hào)監(jiān)測(cè)器的復(fù)位                reset_dt <= '1';            end if;
            -------- 數(shù)據(jù)加載和發(fā)送狀態(tài)--------                -- 加載狀態(tài)            when UART_LOAD =>            -- 如果 overflow 信號(hào)為‘1’,表示數(shù)據(jù)加載完成            if overflow = '1' then                -- 復(fù)位子模塊                reset_parts <= '0';                -- 子模塊使能信號(hào)無(wú)效                ce_parts <= '0';                -- 選擇移位寄存器串行輸入為串行加載序列                sel_si <= '0';                -- 選擇移位寄存器的時(shí)鐘為波特率始終                -- 選擇計(jì)數(shù)器的時(shí)鐘為波特率發(fā)生器的指示信號(hào)                sel_clk <= '0';                -- 使得輸出保持為‘1’                sel_out <= '0';                -- 設(shè)置奇偶校驗(yàn)的數(shù)據(jù)源為數(shù)據(jù)發(fā)送總線                sel_pv <= '0';                -- 改變狀態(tài)為發(fā)送                state <= UART_SEND;            else                -- 選擇移位寄存器的時(shí)鐘為系統(tǒng)時(shí)鐘                -- 選擇計(jì)數(shù)器的時(shí)鐘為系統(tǒng)時(shí)鐘                sel_clk <= '1';                -- 通過(guò)增加 si_count,生成串行加載序列                if not(si_count = TOTAL_BIT-1) then                    si_count <= si_count+1;                else                    si_count <= 0;                end if;                -- 子模塊復(fù)位信號(hào)無(wú)效                reset_parts <= '1';                -- 子模塊使能信號(hào)有效                ce_parts <= '1';            end if;
            -- 發(fā)送狀態(tài)            when UART_SEND =>            -- 如果 overflow 為‘1’,表示發(fā)送完成            if overflow = '1' then                -- 輸出發(fā)送完成的指示信號(hào)                send_over <= '1';
                -- 改變狀態(tài)為發(fā)送完成                state <= UART_END_SEND;            else                -- 子模塊復(fù)位信號(hào)無(wú)效                reset_parts <= '1';                -- 子模塊使能信號(hào)有效                ce_parts <= '1';            end if;
            -- 發(fā)送完成狀態(tài)            when UART_END_SEND =>            -- 子模塊使能信號(hào)無(wú)效            ce_parts <= '0';            -- 復(fù)位信號(hào)監(jiān)測(cè)器            reset_dt <= '0';            -- 恢復(fù)發(fā)送完成指示信號(hào)            send_over <= '0';
            -- 改變狀態(tài)為空閑            state <= UART_IDLE;
            -------- 數(shù)據(jù)接收狀態(tài)--------            -- 接收狀態(tài)            when UART_RECV =>            -- 如果 overflow 變?yōu)椤?”,表示接收完成            if overflow = '1' then                -- 輸出接收指示信號(hào)                recv <= '1';                -- 改變狀態(tài)為接收完成                state <= UART_END_RECV;            else                -- 子模塊復(fù)位信號(hào)無(wú)效                reset_parts <= '1';                -- 子模塊使能信號(hào)有效                ce_parts <= '1';            end if;
            -- 接收完成狀態(tài)            when UART_END_RECV =>            -- 進(jìn)行奇偶校驗(yàn)            if not(regs(0) = parity) then                error <= '1';            end if;            -- 子模塊使能信號(hào)無(wú)效            ce_parts <= '0';            -- 復(fù)位信號(hào)監(jiān)測(cè)器            reset_dt <= '0';            -- 恢復(fù)接收完成指示信號(hào)            recv <= '0';
            -- 改變狀態(tài)為空閑            state <= UART_IDLE;
            -- 如果產(chǎn)生未知狀態(tài),輸出錯(cuò)誤信息            when others =>            error <= '1';
            -- 恢復(fù)到空閑狀態(tài)            state <= UART_IDLE;        end case;    end if;end process;

3.10 UART 頂層模塊的實(shí)現(xiàn)

上面介紹了 UART 各個(gè)模塊的基本原理和實(shí)現(xiàn)方法,要實(shí)現(xiàn) UART 還需要將所有的模塊連接起來(lái),即需要編寫(xiě)一個(gè)頂層模塊。頂層模塊實(shí)現(xiàn)了所有 UART 和外部器件之間的通信接口,端口定義如表 17 所示。

表 17 UART 頂層模塊端口定義表

ec04a0e0-17dc-11ed-ba43-dac502259ad0.png

由于 UART 頂層模塊包括了所有的子模塊,所以其實(shí)現(xiàn)代碼也比較復(fù)雜,為了便于讀者理解,下面分 3 個(gè)部分進(jìn)行介紹。

1)實(shí)體聲明

UART頂層模塊的實(shí)體聲明中除了端口的聲明外,還需要聲明所有子模塊需要使用的類屬參數(shù),包括 DATA_BIT(數(shù)據(jù)位個(gè)數(shù))、TOTAL_BIT(總數(shù)據(jù)個(gè)數(shù))、PARITY_RULE(奇偶校驗(yàn)規(guī)則)、FULL_PULSE_COUNT(完整波特率時(shí)鐘對(duì)應(yīng)的計(jì)數(shù))和 RISE_PULSE_COUNT(波特率時(shí)鐘上升沿對(duì)應(yīng)的計(jì)數(shù))。

實(shí)體聲明部分的代碼如下:

library IEEE;use IEEE.std_logic_1164.all;use WORK.UART_PACKAGE.all;
entity UART is    generic(        -- 數(shù)據(jù)位個(gè)數(shù)        DATA_BIT : integer := 8;        -- 總數(shù)據(jù)個(gè)數(shù)        TOTAL_BIT : integer := 10;        -- 奇偶校驗(yàn)規(guī)則        PARITY_RULE : PARITY := NONE;        --完整波特率時(shí)鐘對(duì)應(yīng)的計(jì)數(shù)        FULL_PULSE_COUNT : BD_COUNT := BD9600_FPC;        --波特率時(shí)鐘上升沿對(duì)應(yīng)的計(jì)數(shù)        RISE_PULSE_COUNT : BD_COUNT := BD9600_HPC    );
    port(        -- 時(shí)鐘信號(hào)        clk : in STD_LOGIC;        -- 復(fù)位信號(hào)        reset_n : in STD_LOGIC;        -- 發(fā)送控制信號(hào)        send : in STD_LOGIC;        -- 數(shù)據(jù)發(fā)送總線        send_bus : in STD_LOGIC_VECTOR(7 downto 0);        -- 發(fā)送完成信號(hào)        send_over : out STD_LOGIC;        -- 錯(cuò)誤提示信號(hào)        error : out STD_LOGIC;        -- 接收提示信號(hào)        recv : out STD_LOGIC;        -- 數(shù)據(jù)接收總線        recv_buf : out STD_LOGIC_VECTOR(7 downto 0);        -- RS-232 數(shù)據(jù)接收端口        RxD : in STD_LOGIC;        -- RS-232 數(shù)據(jù)發(fā)送端口        TxD : out STD_LOGIC;   );
end UART;

2)子模塊和內(nèi)部信號(hào)聲明

子模塊聲明就是將各個(gè)子模塊實(shí)體端口、類屬參數(shù)的定義方式按照組件的格式聲明一遍。聲明組件的格式和聲明實(shí)體完全一致,惟一的差別在于實(shí)體聲明使用 entity 和 end entity,而組件聲明使用 component 和 end component,所以實(shí)際編寫(xiě)過(guò)程中沒(méi)必要完整地書(shū)寫(xiě)一遍聲明內(nèi)容,只需要將實(shí)體聲明的代碼拷貝過(guò)來(lái)并將 entity 修改為 component 即可。

UART 頂層模塊中實(shí)體聲明的代碼如下:

-- 波特率發(fā)生器組件聲明component baudrate_generator    generic(        FULL_PULSE_COUNT : BD_COUNT := BD9600_FPC;        RISE_PULSE_COUNT : BD_COUNT := BD9600_HPC    );
    port (        ce : in STD_LOGIC;        clk : in STD_LOGIC;        reset_n : in STD_LOGIC;        bg_out : out STD_LOGIC;        indicator : out STD_LOGIC    );
endcomponent;
-- 計(jì)數(shù)器組件聲明component counter    generic(        MAX_COUNT : INTEGER := 10    );
    port (        ce : in STD_LOGIC;        clk : in STD_LOGIC;        reset_n : in STD_LOGIC;        overflow : out STD_LOGIC    );end component;
-- 信號(hào)監(jiān)測(cè)器component detector    port (        RxD : in STD_LOGIC;        clk : in STD_LOGIC;        reset_n : in STD_LOGIC;        new_data : out STD_LOGIC    );end component;
-- 奇偶校驗(yàn)器component parity_verifier    generic(        DATA_LENGTH : INTEGER := 8;        PARITY_RULE : PARITY := NONE    );    port (        source : in STD_LOGIC_VECTOR(DATA_LENGTH-1 downto 0);        parity : out STD_LOGIC    );end component;
-- 移位寄存器component shift_register    generic(        TOTAL_BIT : INTEGER := 10    );    port (        clk : in STD_LOGIC; din:inSTD_LOGIC; reset_n : in STD_LOGIC; dout:outSTD_LOGIC;        regs : out STD_LOGIC_VECTOR(TOTAL_BIT-1 downto 0)    );end component;
-- 二選一選擇器component switch    port (        din1 : in STD_LOGIC;        din2 : in STD_LOGIC;        sel : in STD_LOGIC;        dout : out STD_LOGIC    );end component;
-- 總線選擇器component switch_bus    generic(        BUS_WIDTH : INTEGER := 8    );    port (        din1 : in STD_LOGIC_VECTOR(BUS_WIDTH-1 downto 0);        din2 : in STD_LOGIC_VECTOR(BUS_WIDTH-1 downto 0);        sel : in STD_LOGIC;        dout : out STD_LOGIC_VECTOR(BUS_WIDTH-1 downto 0)    );end component;
-- UART 內(nèi)核component uart_core    generic(        DATA_BIT : INTEGER := 8;        PARITY_RULE : PARITY := NONE;        TOTAL_BIT : INTEGER := 10    );    port (        clk : in STD_LOGIC;        new_data : in STD_LOGIC;        overflow : in STD_LOGIC;        parity : in STD_LOGIC;        regs : in STD_LOGIC_VECTOR(TOTAL_BIT-1 downto 0);        reset_n : in STD_LOGIC;        send : in STD_LOGIC;        send_bus : in STD_LOGIC_VECTOR(DATA_BIT-1 downto 0);        ce_parts : out STD_LOGIC;        error : out STD_LOGIC;        recv : out STD_LOGIC;        recv_bus : out STD_LOGIC_VECTOR(DATA_BIT-1 downto 0);        reset_dt : out STD_LOGIC;        reset_parts : out STD_LOGIC;        sel_clk : out STD_LOGIC;        sel_out : out STD_LOGIC;        sel_pv : out STD_LOGIC;        sel_si : out STD_LOGIC;        send_over : out STD_LOGIC;        send_si : out STD_LOGIC    );end component;

完成組件聲明后,需要對(duì)內(nèi)部信號(hào)進(jìn)行聲明。內(nèi)部信號(hào)的主要作用有兩種,第一種是作為各個(gè)模塊(組件)之間的連接信號(hào),第二種是作為寄存器使用。在 UART 頂層模塊中的內(nèi)部信號(hào)主要用于連接各個(gè)組件(模塊),即作為連接信號(hào)使用。

內(nèi)部信號(hào)聲明的代碼如下:

---- 常數(shù) -----constant VCC_CONSTANT : STD_LOGIC := '1';---- 內(nèi)部信號(hào)聲明 ----signal bg_clk : STD_LOGIC;signal bg_out : STD_LOGIC;signal ce_parts : STD_LOGIC;signal clk_inv : STD_LOGIC;signal counter_clk : STD_LOGIC;signal indicator : STD_LOGIC;signal new_data : STD_LOGIC;signal overflow : STD_LOGIC;signal parity : STD_LOGIC;signal reset_dt : STD_LOGIC;signal reset_parts : STD_LOGIC;signal sel_clk : STD_LOGIC;signal sel_out : STD_LOGIC;signal sel_pv : STD_LOGIC;signal sel_si : STD_LOGIC;signal send_si : STD_LOGIC;signal sr_in : STD_LOGIC;signal sr_out : STD_LOGIC;signal VCC : STD_LOGIC;signal pv_source : STD_LOGIC_VECTOR (DATA_BIT-1 downto 0);signal recv_parity_source : STD_LOGIC_VECTOR (DATA_BIT-1 downto 0);signal regs : STD_LOGIC_VECTOR (TOTAL_BIT-1 downto 0);signal send_parity_source : STD_LOGIC_VECTOR (DATA_BIT-1 downto 0);

3)子模塊實(shí)例化

子模塊實(shí)例化表示的就是根據(jù)子模塊(組件)的聲明定義一個(gè)子模塊實(shí)例,同時(shí)定義此實(shí)例的信號(hào)連接方式以及類屬參數(shù)等。

UART 頂層模塊的子模塊實(shí)例化代碼如下:

-- 波特率發(fā)生器實(shí)例U_BG : baudrate_generator    port map(        bg_out => bg_out,        ce => ce_parts,        clk => clk,        indicator => indicator,        reset_n => reset_parts    );-- 總線選擇器實(shí)例U_BusSwitch : switch_bus    port map(        din1 => send_parity_source( DATA_BIT-1 downto 0 ),        din2 => recv_parity_source( DATA_BIT-1 downto 0 ),        dout => pv_source( DATA_BIT-1 downto 0 ),        sel => sel_pv    );-- UART 內(nèi)核實(shí)例U_Core : uart_core    port map(        ce_parts => ce_parts,        clk => clk,        error => error,        new_data => new_data,        overflow => overflow,        parity => parity,        recv => recv,        recv_bus => recv_parity_source( DATA_BIT-1 downto 0 ),        regs => regs( TOTAL_BIT-1 downto 0 ),        reset_dt => reset_dt,        reset_n => reset_n,        reset_parts => reset_parts,        sel_clk => sel_clk,        sel_out => sel_out,        sel_pv => sel_pv,        sel_si => sel_si,        send => send,        send_bus => send_parity_source( DATA_BIT-1 downto 0 ),        send_over => send_over,        send_si => send_si    );-- 計(jì)數(shù)器實(shí)例U_Counter : counter    port map(        ce => ce_parts,        clk => counter_clk,        overflow => overflow,        reset_n => reset_parts    );-- 計(jì)數(shù)器時(shí)鐘源選擇器U_CounterClkSwitch : switch    port map(        din1 => indicator,        din2 => clk_inv,        dout => counter_clk,        sel => sel_clk    );-- 信號(hào)監(jiān)測(cè)器U_Detector : detector    port map(        RxD => RxD,        clk => clk,        new_data => new_data,        reset_n => reset_dt    );-- 奇偶校驗(yàn)器U_ParityVerifier : parity_verifier    port map(        parity => parity,        source => pv_source( DATA_BIT-1 downto 0 )    );-- 移位寄存器輸入源選擇器實(shí)例U_SISwitch : switch    port map(        din1 => send_si,        din2 => RxD,        dout => sr_in,        sel => sel_si    );-- 移位寄存器實(shí)例U_SR : shift_register    port map(        clk => bg_clk,        din => sr_in,        dout => sr_out,        regs => regs( TOTAL_BIT-1 downto 0 ),        reset_n => reset_parts    );-- 移位寄存器時(shí)鐘源選擇器實(shí)例U_SRClkSwitch : switch    port map(        din1 => bg_out,        din2 => clk_inv,        dout => bg_clk,        sel => sel_clk    );-- 輸出選擇器實(shí)例U_TXDSwitch : switch    port map(        din1 => VCC,        din2 => sr_out,        dout => TxD,        sel => sel_out    );

以上便是 UART 頂層模塊的實(shí)現(xiàn)方法, UART 頂層模塊就是將 UART 內(nèi)核和其他模塊連接起來(lái)組成一個(gè)完成的模塊。

3.11 測(cè)試平臺(tái)的編寫(xiě)和仿真

為了驗(yàn)證 UART 實(shí)現(xiàn)的正確性,需要設(shè)計(jì)一個(gè)仿真平臺(tái)對(duì) UART 頂層模塊進(jìn)行仿真,下面就介紹一下 UART 仿真平臺(tái)的編寫(xiě)方法和仿真結(jié)果的分析。仿真平臺(tái)是一個(gè) VHDL 文件,其本身也是一個(gè)實(shí)體(entity)。仿真平臺(tái)除了包含了實(shí)體聲明(entity)和結(jié)構(gòu)體(architecture)以外,還需要有一個(gè)配置(configuration)。例如,針對(duì) UART 頂層模塊 uart_top.vhd 編寫(xiě)的測(cè)試平臺(tái)就有如下的結(jié)構(gòu):

-- 庫(kù)聲明library ieee;use work.uart_package.all;use ieee.std_logic_1164.all;
-- 實(shí)體聲明entity uart_top_tb is-- 實(shí)體聲明內(nèi)容(略)end uart_top_tb;-- 結(jié)構(gòu)體architecture TB_ARCHITECTURE of uart_top_tb is    -- 結(jié)構(gòu)體內(nèi)容(略)end TB_ARCHITECTURE;-- 配置configuration TESTBENCH_FOR_uart_top of uart_top_tb is    for TB_ARCHITECTURE        for UUT : uart_top            use entity work.uart_top(uart_top);        end for;    end for;end TESTBENCH_FOR_uart_top;

從上面的代碼可以看出,配置的作用就是為測(cè)試對(duì)象指定一個(gè)結(jié)構(gòu)體,下面從 3 個(gè)方面介紹測(cè)試平臺(tái)的實(shí)現(xiàn)代碼。

1)實(shí)體聲明

一般來(lái)說(shuō),測(cè)試平臺(tái)的實(shí)體聲明中不會(huì)有輸入/輸出信號(hào),僅包括其測(cè)試對(duì)象所需要的類屬參數(shù)。UART 測(cè)試平臺(tái)的實(shí)體聲明如下:

entity uart_top_tb is    -- 定義類屬參數(shù)        generic(            DATA_BIT : INTEGER := 8;            TOTAL_BIT : INTEGER := 10;            PARITY_RULE : PARITY := none;            FULL_PULSE_COUNT : BD_COUNT := 5208;            RISE_PULSE_COUNT : BD_COUNT := 2604 );end uart_top_tb;

2)組件和信號(hào)聲明

組件聲明就是對(duì)測(cè)試對(duì)象的聲明。在測(cè)試平臺(tái)中,測(cè)試對(duì)象是作為一個(gè)組件來(lái)呈現(xiàn)的。比如 UART 測(cè)試平臺(tái)中對(duì) UART 頂層模塊的組件聲明如下:

-- UART 頂層模塊組件聲明component uart_top    generic(        DATA_BIT : INTEGER := 8;        TOTAL_BIT : INTEGER := 10;        PARITY_RULE : PARITY := none;        FULL_PULSE_COUNT : BD_COUNT := 5208;        RISE_PULSE_COUNT : BD_COUNT := 2604 );    port(        RxD : in std_logic;        clk : in std_logic;        reset_n : in std_logic;        send : in std_logic;        send_bus : in std_logic_vector(7 downto 0);        TxD : out std_logic;        error : out std_logic;        recv : out std_logic;        send_over : out std_logic;        recv_buf : out std_logic_vector(7 downto 0) );end component;

測(cè)試對(duì)象肯定有一些輸入/輸出信號(hào),它們?cè)跍y(cè)試平臺(tái)中是定義為內(nèi)部信號(hào)的,可以直接對(duì)這些內(nèi)部信號(hào)進(jìn)行賦值來(lái)控制測(cè)試對(duì)象的輸入信號(hào)。實(shí)際上,一般來(lái)說(shuō)測(cè)試平臺(tái)的內(nèi)部信號(hào)都是和測(cè)試對(duì)象的輸入/輸出信號(hào)一一對(duì)應(yīng)的,代碼如下:

-- 內(nèi)部信號(hào)signal RxD : std_logic := '1';signal clk : std_logic := '0';signal reset_n : std_logic := '0';signal send : std_logic := '0';signal send_bus : std_logic_vector(7 downto 0) := (others => '0');signal TxD : std_logic := '1';signal error : std_logic := '0';signal recv : std_logic := '0';signal send_over : std_logic := '0';signal recv_buf : std_logic_vector(7 downto 0) := (others => '0');

3)測(cè)試流程的控制

編寫(xiě)測(cè)試流程的第一個(gè)步驟是對(duì)測(cè)試對(duì)象的實(shí)例化,即將 UART 頂層模塊實(shí)例化,實(shí)現(xiàn)代碼如下:

-- 測(cè)試對(duì)象實(shí)例化UUT : uart_top    generic map (        DATA_BIT => DATA_BIT,        TOTAL_BIT => TOTAL_BIT,        PARITY_RULE => PARITY_RULE,        FULL_PULSE_COUNT => FULL_PULSE_COUNT,        RISE_PULSE_COUNT => RISE_PULSE_COUNT    );    port map (        RxD => RxD,        clk => clk,        reset_n => reset_n,        send => send,        send_bus => send_bus,        TxD => TxD,        error => error,        recv => recv,        send_over => send_over,        recv_buf => recv_buf    )

第二個(gè)步驟是產(chǎn)生時(shí)鐘信號(hào),由于時(shí)鐘信號(hào)比較有規(guī)律,所以可以用一個(gè)過(guò)程(process)來(lái)實(shí)現(xiàn),代碼如下:

-- 產(chǎn)生時(shí)鐘信號(hào)clk_gen : processbegin    clk <= not clk;    wait for 10 ns;end process;

最后一個(gè)步驟就是實(shí)現(xiàn)測(cè)試的主流程,一般是在一個(gè)過(guò)程(Process)中實(shí)現(xiàn)。對(duì)于 UART的測(cè)試,主要的內(nèi)容就是數(shù)據(jù)發(fā)送的測(cè)試和數(shù)據(jù)接收的測(cè)試,測(cè)試主流程的流程圖如圖 27所示。

ec156b5a-17dc-11ed-ba43-dac502259ad0.png

圖 27 UART 測(cè)試流程圖

測(cè)試主流程的實(shí)現(xiàn)代碼如下:

-- 測(cè)試主流程main: processbegin    -- 復(fù)位    reset_n <= '0';    wait for 100 ns;
    -- 結(jié)束復(fù)位    reset_n <= '1';    wait for 100 ns;
        -- 測(cè)試數(shù)據(jù)發(fā)送    wait for 10 ns;    -- 發(fā)送數(shù)據(jù)為 01010101    send_bus <= "01010101";    -- send 為高激活數(shù)據(jù)發(fā)送    send <= '1';    wait for 20 ns;    send <= '0';
        -- 測(cè)試數(shù)據(jù)接收    -- 使用測(cè)試用波特率    if FULL_PULSE_COUNT = BDTEST_FPC then        wait for 2500 ns;        -- 仿真 RS-232 輸入信號(hào) RxD        for i in 0 to 9 loop            RxD <= test_si_none(i);            -- 測(cè)試波特率為 10,所以輸入間隔 10 個(gè)時(shí)鐘,總共 200ns            wait for 200 ns;        end loop;    -- 使用實(shí)際波特率 9600    elsif FULL_PULSE_COUNT = BD9600_FPC then        wait for 1.2 ms;        -- 仿真 RS-232 輸入信號(hào) RxD        for i in 0 to 9 loop            RxD <= test_si_none(i);            -- 測(cè)試波特率為 9600,所以輸入間隔 9600 個(gè)時(shí)鐘,總共 104.17μs            wait for 104.17 us;        end loop;    end if;
    wait ;end process;

上面代碼中的 test_si_none 是在 UART_PACKAGE 庫(kù)中定義的輸入測(cè)試數(shù)據(jù)串行序列(無(wú)奇偶教研),此外還定義了奇校驗(yàn)和偶校驗(yàn)對(duì)應(yīng)的序列,代碼如下:

-- 類型聲明type test_vectors is array (0 to 10) of std_logic;-- 無(wú)奇偶校驗(yàn)測(cè)試序列constant test_si_none : test_vectors :=('0', '1', '0', '1', '0', '1', '0', '1', '0', others => '1');-- 奇校驗(yàn)測(cè)試序列constant test_si_odd : test_vectors :=('0', '1', '0', '1', '0', '1', '1', '1', '0', '1', others => '1');-- 偶校驗(yàn)測(cè)試序列constant test_si_even : test_vectors :=('0', '1', '0', '1', '0', '1', '0', '1', '0', '0', others => '1');

在波特率為 9600 情況下利用上述測(cè)試平臺(tái)對(duì) UART 進(jìn)行仿真,得到數(shù)據(jù)發(fā)送的仿真結(jié)果分別如圖 28 所示。

ec2be196-17dc-11ed-ba43-dac502259ad0.png

圖 5-28 UART 數(shù)據(jù)發(fā)送仿真結(jié)果

從圖 28 可以看出,待發(fā)送的數(shù)據(jù)是 0x55(十六進(jìn)制,即 send_bus 總線上的數(shù)據(jù)),由send 信號(hào)觸發(fā)后,RS-232 的 TxD 端輸出為序列 001010101(二進(jìn)制),其中第一位是起始位,中間的八位正是待發(fā)送的數(shù)據(jù) 0xFF,最后再發(fā)送完成后輸出提示信號(hào) send_over。可見(jiàn),發(fā)送的結(jié)果符合 RS-232 的時(shí)序要求,UART 的發(fā)送功能完全正確。

同樣測(cè)試條件下數(shù)據(jù)接收的仿真結(jié)果如圖 29 所示。首先,RxD 上的數(shù)據(jù)序列為0101010010(二進(jìn)制),表示起始位 0,之后數(shù)據(jù)位是 10101010(二進(jìn)制),所以待接收的數(shù)據(jù)是 0xAA(十六進(jìn)制)。recv_buf 是數(shù)據(jù)接收總線,可以看到其最終得到的數(shù)據(jù)正是 0xAA(十六進(jìn)制),并且,在接收完成后 recv 信號(hào)會(huì)輸出一個(gè)脈寬的高電平作為提示。由上述可知,數(shù)據(jù)接收的過(guò)程也完全正確。

ec51492c-17dc-11ed-ba43-dac502259ad0.png

圖 29 UART 數(shù)據(jù)接收仿真結(jié)果

審核編輯:湯梓紅


聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • FPGA
    +關(guān)注

    關(guān)注

    1620

    文章

    21510

    瀏覽量

    598930
  • 控制器
    +關(guān)注

    關(guān)注

    112

    文章

    15885

    瀏覽量

    175372
  • 串口
    +關(guān)注

    關(guān)注

    14

    文章

    1533

    瀏覽量

    75463
  • uart
    +關(guān)注

    關(guān)注

    22

    文章

    1199

    瀏覽量

    100829

原文標(biāo)題:系統(tǒng)設(shè)計(jì)精選 | 基于 FPGA 的 UART 控制器設(shè)計(jì)(附代碼)

文章出處:【微信號(hào):FPGA之旅,微信公眾號(hào):FPGA之旅】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    如何利用FPGA實(shí)現(xiàn)UART的設(shè)計(jì)?

    如何利用FPGA實(shí)現(xiàn)UART的設(shè)計(jì)?UART的結(jié)構(gòu)和幀格式
    發(fā)表于 04-08 06:32

    基于FPGAUART控制器的設(shè)計(jì)和實(shí)現(xiàn)

    文章介紹了一種在現(xiàn)場(chǎng)可編程門陣列(FPGA)上實(shí)現(xiàn)UART 的方法。UART 的波特率可設(shè)置調(diào)整,工作狀態(tài)可讀取。系統(tǒng)結(jié)構(gòu)進(jìn)行了模塊化分解,使之適應(yīng)自頂向下(Top-Down)的設(shè)計(jì)
    發(fā)表于 08-21 11:35 ?52次下載

    FPGA/CPLD設(shè)計(jì)UART

    UART 是廣泛使用的串行數(shù)據(jù)通訊電路。本設(shè)計(jì)包含UART 發(fā)送器、接收器和波特率發(fā)生器。設(shè)計(jì)應(yīng)用EDA 技術(shù),基于FPGA/CPLD 器件設(shè)計(jì)與實(shí)現(xiàn)
    發(fā)表于 09-29 08:01 ?24次下載

    利用FPGA實(shí)現(xiàn)UART的設(shè)計(jì)

    利用 FPGA 實(shí)現(xiàn)UART 的設(shè)計(jì)引 言隨著計(jì)算機(jī)技術(shù)的發(fā)展和廣泛應(yīng)用,尤其是在工業(yè)控制領(lǐng)域的應(yīng)用越來(lái)越廣泛,計(jì)算機(jī)通信顯的尤為重要。串行通信雖然使設(shè)備之間的連線大為減
    發(fā)表于 03-24 09:23 ?49次下載

    異步收發(fā)通信端口(UART)的FPGA實(shí)現(xiàn)

    文章介紹了一種在現(xiàn)場(chǎng)可編程門陣列(FPGA)上實(shí)現(xiàn)UART 的方法。首先闡述了UART 異步串行通信原理,然后介紹了實(shí)現(xiàn)
    發(fā)表于 08-06 16:24 ?55次下載

    FPGA/CPLD設(shè)計(jì)UART

    摘 要 :UART是廣泛使用的串行數(shù)據(jù)通訊電路。本設(shè)計(jì)包含UART發(fā)送器、接收器和波特率發(fā)生器。設(shè)計(jì)應(yīng)用EDA技術(shù),基于FPGA/CPLD器件設(shè)計(jì)與實(shí)現(xiàn)
    發(fā)表于 06-20 13:14 ?1047次閱讀
    用<b class='flag-5'>FPGA</b>/CPLD設(shè)計(jì)<b class='flag-5'>UART</b>

    FPGA與CPLD實(shí)現(xiàn)UART

    UART 是廣泛使用的串行數(shù)據(jù)通訊電路。本設(shè)計(jì)包含UART 發(fā)送器、接收器和波特率發(fā)生器。設(shè)計(jì)應(yīng)用EDA 技術(shù),基于FPGA/CPLD 器件設(shè)計(jì)與實(shí)現(xiàn)
    發(fā)表于 12-17 00:15 ?57次下載
    <b class='flag-5'>FPGA</b>與CPLD<b class='flag-5'>實(shí)現(xiàn)</b><b class='flag-5'>UART</b>

    華清遠(yuǎn)見(jiàn)FPGA代碼-RS-232C(UART)接口的設(shè)計(jì)與實(shí)現(xiàn)

    華清遠(yuǎn)見(jiàn)FPGA代碼-RS-232C(UART)接口的設(shè)計(jì)與實(shí)現(xiàn)
    發(fā)表于 10-27 18:07 ?10次下載

    基于FPGA/CPLD的UART功能設(shè)計(jì)

    基于FPGA/CPLD的UART功能設(shè)計(jì)
    發(fā)表于 01-23 20:45 ?30次下載

    UART功能集成到FPGA內(nèi)部實(shí)現(xiàn)多模塊的設(shè)計(jì)

    FPGA芯片卻沒(méi)有這個(gè)特點(diǎn),所以使用FPGA作為處理器可以有兩個(gè)選擇,第一個(gè)選擇是使用UART芯片進(jìn)行串并轉(zhuǎn)換,第二個(gè)選擇是在FPGA內(nèi)部實(shí)現(xiàn)
    的頭像 發(fā)表于 10-18 07:54 ?2491次閱讀
    將<b class='flag-5'>UART</b>功能集成到<b class='flag-5'>FPGA</b>內(nèi)部<b class='flag-5'>實(shí)現(xiàn)</b>多模塊的設(shè)計(jì)

    FPGA為基礎(chǔ)的UART模塊的詳細(xì)設(shè)計(jì)方案

    UART實(shí)現(xiàn)方法,具體描述了發(fā)送、接收等模塊的設(shè)計(jì),恰當(dāng)使用了有限狀態(tài)機(jī),實(shí)現(xiàn)FPGA上的UART的設(shè)計(jì),給出仿真結(jié)果。
    發(fā)表于 07-07 15:51 ?12次下載
    以<b class='flag-5'>FPGA</b>為基礎(chǔ)的<b class='flag-5'>UART</b>模塊的詳細(xì)設(shè)計(jì)<b class='flag-5'>方案</b>

    使用FPGA和模塊化設(shè)計(jì)方法實(shí)現(xiàn)UART的設(shè)計(jì)論文

    實(shí)現(xiàn)方法,具體描述了發(fā)送、接收等模塊的設(shè)計(jì),恰當(dāng)使用了有限狀態(tài)機(jī),實(shí)現(xiàn)FPGA上的UART的設(shè)計(jì),給出仿真結(jié)果。
    發(fā)表于 07-07 17:28 ?10次下載
    使用<b class='flag-5'>FPGA</b>和模塊化設(shè)計(jì)方法<b class='flag-5'>實(shí)現(xiàn)</b><b class='flag-5'>UART</b>的設(shè)計(jì)論文

    一種基于FPGAUART電路的實(shí)現(xiàn)

    的。本設(shè)計(jì)使用Xilinx的FPGA器件,只將UART的核心功能嵌入到FPGA內(nèi)部,不但實(shí)現(xiàn)了電路的異步通訊的主要功能,而且使電路更加緊湊、穩(wěn)定、可靠。
    發(fā)表于 04-27 14:07 ?8次下載

    基于FPGAUART模塊設(shè)計(jì)與實(shí)現(xiàn)簡(jiǎn)介

    基于FPGAUART模塊設(shè)計(jì)與實(shí)現(xiàn)介紹說(shuō)明。
    發(fā)表于 06-01 09:43 ?20次下載

    GPIO模擬UART的算法實(shí)現(xiàn)與設(shè)計(jì)方案

    GPIO模擬UART的算法實(shí)現(xiàn)與設(shè)計(jì)方案
    發(fā)表于 07-07 09:49 ?9次下載