軟體版本: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只使用到TXD和RXD兩個訊號,兩個裝置之間的TXD和RXD必須交叉連線,例如對於PC的TX 要和FPGA的RX連線,同樣PC的RX要和FPGA的TX連線才可以正常通訊。
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_rdata和uart_wdata互聯,uart_wreq和uart_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:放fpga的pin腳約束檔案或者時序約束檔案
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損壞)