[米聯客-安路飛龍DR1-FPSOC] FPGA基礎篇連載-12 串列埠程式收發環路設計

米联客(milianke)發表於2024-07-29

軟體版本:Anlogic -TD5.9.1-DR1_ES1.1

作業系統:WIN10 64bit

硬體平臺:適用安路(Anlogic)FPGA

實驗平臺:米聯客-MLK-L1-CZ06-DR1M90G開發板

板卡獲取平臺:https://milianke.tmall.com/

登入"米聯客"FPGA社群 http://www.uisrc.com 影片課程、答疑解惑!

1概述

前面兩課,我們完成了我們傳送程式的測試,成功給PC主機傳送了"HELLO FPGA"的資訊,主機顯示接收成功。但是我們串列埠接收的程式僅僅是透過我們模擬模擬,雖然模擬結果達到了期望,但是不能直接上板測試難免差強人意。所以我們不妨將我們串列埠UART接收程式以及傳送程式連線起來,做到能將PC端透過USB傳送過來的資料接收,然後將接收到的資料再透過傳送程式返回給我們的PC機。

在完成本實驗前,請確保已經完成前面的實驗,包括已經掌握以下能力:

1:完成了TD軟體安裝

2:完成了modelsim安裝以及TD庫的編譯

3:掌握了TD模擬環境的設定

4:掌握了modesim透過do檔案啟動模擬

實驗目的:

1:實現UART串列埠傳送控制器的設計

2:實現主程式中呼叫串列埠傳送控制器傳送字元"HELLO FPGA"

3:實用modelsim完成模擬驗證

4:編譯並且固化程式到FPGA驗證

1.1 UART收發環路簡介

電腦USB口和FPGA串列埠通訊示意圖:

一般RS232只使用到TXDRXD兩個訊號,兩個裝置之間的TXDRXD必須交叉連線,例如對於PCTX 要和FPGARX連線,同樣PCRX要和FPGATX連線才可以正常通訊。

1.2硬體電路分析

參照 "UART串列埠傳送驅動設計"硬體電路分析部分

2 UART收發環路程式設計

在完成以下實驗前,請確保已經完成了"UART串列埠傳送實驗""UART串列埠接收實驗"

2.1系統框圖

上位機透過串列埠傳送資料到FPGA開發板的UART資料接收模組,將串列埠接收埠(I_uart_rx)的序列資料解析回並行資料輸出,再將並行資料作為輸入給資料傳送模組,UART資料傳送模組將並行資料轉成序列資料傳送回上位機。透過串列埠傳送埠(O_uart_tx)把資料發回到串列埠晶片,之後資料在串列埠除錯助手上列印,實現環路測試。需要注意的是,資料並不是一直有效的,所以將UART資料接收模組的資料有效訊號(O_uart_rvalid)接入到UART資料傳送模組的傳送資料請求訊號(I_uart_wreq,當接收的訊號有效時,觸發UART資料傳送模組,就可以傳送接收的有效資料。對於傳送驅動模組中的O_uart_wbusy訊號,不需要使用,因為這裡uart傳送模組是被動傳送。

2.2驅動原始碼

頂層模組只需要呼叫uart的首發模組驅動介面。並且設定uart_rdatauart_wdata互聯,uart_wrequart_rvalid互聯。

 1 `timescale 1ns / 1ns //模擬時鐘刻度和精度
 2 
 3 module uart_top
 4 (
 5 input  I_sysclk,//系統時鐘輸入
 6 input  I_uart_rx,//uart rx接收訊號
 7 output O_uart_tx //uart tx傳送訊號
 8 );
 9 
10 localparam SYSCLKHZ = 25_000_000;  //系統輸入時鐘
11 
12 reg [11:0] rstn_cnt = 0;//上電後延遲復位
13 wire uart_rstn_i;//內部復位訊號
14 wire uart_wreq,uart_rvalid;
15 wire [7:0]uart_wdata,uart_rdata;
16 
17 assign uart_wreq  = uart_rvalid;//用uart rx接收資料有效的uart_rvalid訊號,控制uart傳送模組的傳送請求
18 assign uart_wdata = uart_rdata; //接收的資料給傳送模組傳送
19 assign uart_rstn_i = rstn_cnt[11];//延遲復位設計,用計數器的高bit控制復位
20 
21 //同步計數器實現復位
22 always @(posedge I_sysclk)begin
23     if(rstn_cnt[11] == 1'b0)
24         rstn_cnt <= rstn_cnt + 1'b1;
25     else 
26         rstn_cnt <= rstn_cnt;
27 end
28 
29 //例化uart 傳送模組
30 uiuart_tx#
31 (
32 .BAUD_DIV(SYSCLKHZ/115200-1)    
33 )
34 uart_tx_u 
35 (
36 .I_clk(I_sysclk),//系統時鐘輸入
37 .I_uart_rstn(uart_rstn_i), //系統復位
38 .I_uart_wreq(uart_wreq), //uart傳送驅動的寫請求訊號,高電平有效
39 .I_uart_wdata(uart_wdata), //uart傳送驅動的寫資料
40 .O_uart_wbusy(),//uart 傳送驅動的忙標誌
41 .O_uart_tx(O_uart_tx)//uart 序列資料傳送
42 );
43 
44 //例化uart 接收
45 uiuart_rx#
46 (
47 .BAUD_DIV(SYSCLKHZ/115200-1)   
48 )
49 uiuart_rx_u 
50 (
51 .I_clk(I_sysclk), //系統時鐘輸入
52 .I_uart_rstn(uart_rstn_i),//系統復位
53 .I_uart_rx(I_uart_rx), //uart 序列資料接收
54 .O_uart_rdata(uart_rdata), //uart 接收資料
55 .O_uart_rvalid(uart_rvalid)//uart 接收資料有效,當O_uart_rvalid =1'b1 O_uart_rdata輸出的資料有效
56 );
57     
58 endmodule

3 FPGA工程

fpga工程的建立過程不再重複,如有不清楚的請看前面實驗,具體的FPGA型號以對應的開發板上晶片為準

米聯客的程式碼管理規範,在對應的FPGA工程路徑下建立uisrc路徑,並且建立以下資料夾

01_rtl:放使用者編寫的rtl程式碼

02_sim:模擬檔案或者工程

03_ip:放使用到的ip檔案

04_pin:fpgapin腳約束檔案或者時序約束檔案

05_boot:放編譯好的bit或者bin檔案(一般為空)

06_doc:放本一些相關文件(一般為空)

4 Modelsim模擬

4.1準備工作

Modelsim模擬的建立過程不再重複,如有不清楚的請看前面實驗

模擬測試檔案原始碼如下:

 1 `timescale 1ns/1ns  //定義模擬時間刻度/精度
 2 
 3 module sim_top_tb();
 4  
 5 localparam     BPS       = 'd115200          ;                //波特率
 6 localparam     CLK_FRE    = 'd25_000_000     ;                //系統頻率
 7 localparam     CLK_TIME   =  'd250_000_000 /CLK_FRE;          //計算系統時鐘週期,以ns為單位
 8 localparam     BIT_TIME   = 'd250_000_000  / BPS ;            //計算出傳輸每個bit所需要的時間以ns為單位
 9 localparam     NUM_BYTES  = 3;                                //需要傳送的BYTES
10 
11 reg              I_sysclk;                                    //系統時鐘
12 reg              bsp_clk ;                                    //波特率時鐘
13 reg              uart_tx;                                     //uart 資料傳送,該訊號接入到,FPGA的uart 接收
14 wire             uart_rx;                                     //uart 資料接收,該訊號接入到,FPGA的uart 傳送
15 reg [8*NUM_BYTES-1:0] uart_send_data;                         //需要傳送的資料
16 reg [7:0]            uart_send_data_r;                        //寄存每次需要傳送的BYTE
17 
18 integer i,j;
19 
20 //例化頂層模組
21 uart_top uart_top_inst
22 (
23 .I_sysclk(I_sysclk),
24 .I_uart_rx(uart_tx),
25 .O_uart_tx(uart_rx)
26 );
27 
28 //模擬初始化
29 initial begin  
30 
31 //初始化REG暫存器
32 I_sysclk =0;
33 bsp_clk  = 0;  
34 uart_tx  = 1;
35 i=0;
36 j=0;
37 
38 uart_send_data   =0;
39 uart_send_data_r =0;
40 
41 #20000;//延遲20000ns,等待uart測試程式碼中的復位延遲
42 
43 uart_send_data[(0*8) +: 8] = 8'b1001_0101;//初始化需要傳送的第1個BYTE
44 uart_send_data[(1*8) +: 8] = 8'b0000_0101;//初始化需要傳送的第2個BYTE
45 uart_send_data[(2*8) +: 8] = 8'b1000_0100;//初始化需要傳送的第3個BYTE
46 
47 //uart tx 傳送資料
48   for(i=0; i<NUM_BYTES;i=i+1)
49   begin
50 
51       uart_send_data_r = uart_send_data[(i*8) +: 8];//寄存需要傳送的資料到暫存器
52       $display("uart_send_data : 0x%h",uart_send_data_r);//列印準備傳送的資料
53 
54       @(posedge bsp_clk);  //傳送起始位1bit
55       uart_tx = 1'b0;
56 
57       for(j=0;j<8;j=j+1)begin//傳送資料8bits
58       @(posedge bsp_clk);  //傳送
59       uart_tx = uart_send_data_r[j];
60       end
61 
62        @(posedge bsp_clk);//傳送停止位1bit
63        uart_tx = 1'b1;  
64 
65   end
66        @(posedge bsp_clk); 
67        #200 $finish;               
68 end
69  
70 always #(CLK_TIME/2) I_sysclk = ~I_sysclk;     //產生主時鐘
71 always #(BIT_TIME/2) bsp_clk  = ~bsp_clk;         //產生波特率時鐘
72  
73 
74 endmodule

4.2啟動modelsim模擬

啟動後,右擊需要觀察的訊號,新增到波形視窗

設定restart

設定執行2.2ms(如果時間太長需要找下資料位置,時間太短需要繼續跑直到波形出來)

5下載演示

下載程式前,先確保FPGA工程已經編譯。

5.1硬體連線

(該教程為通用型教程,教程中僅展示一款示例開發板的連線方式,具體連線方式以所購買的開發板型號以及結合配套程式碼管腳約束為準。)

請確保下載器和開發板已經正確連線,並且開發板已經上電(注意JTAG端子不支援熱插拔,而USB介面支援,所以在不通電的情況下接通好JTAG後,再插入USB到電腦,之後再上電,以免造成JTAG IO損壞)

5.2執行結果

相關文章