FPGA串口收發(三):接收數據,再轉發出去

FPGA串口收發(三):接收數據,再轉發出去

功能:測試串口接收數據,再將數據從串口發出

// 模擬串口信號線,串行接收數據 1101_1000 ,轉換爲並行數據, 並顯示 D8

// 把並行數據 D8 傳給串口輸出模塊,串行輸出數據 1101 1000

時鐘40MHz,波特率115200

1、源文件

uart_rx.v

uart_tx.v

2、仿真文件 testbench

tb_uart_rx_tx.v

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: Myminieye
// Engineer: Nill
//
// Create Date:
// Design Name:
// Module Name:
// Project Name:
// Target Devices:
// Tool Versions:
// Description: 測試串口接收數據,再將數據從串口發出
// 模擬串口信號線,串行接收數據 1101_1000 ,轉換爲並行數據, 並顯示 D8
// 把並行數據 D8 傳給串口輸出模塊,串行輸出數據 1101 1000
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
`define UD #1

module tb_uart_rx_tx();

//==========================================================================
//wire and reg 定義:信號與參數
//==========================================================================
	reg       sim_clk;		//模擬時鐘信號
	//reg     tx_pulse;     // active posedge
	reg 	  sim_rst_n;
	
	// input to rx module
	reg       uart_rx;		//串口發送信號線
	//output from rx module
	wire [7:0] rx_data;		//送入串口發送模塊,準備發送的數據
	wire       rx_finish;   //串口接收數據有效,接收完成拉高1個BPS
	
	// input to tx module
	reg       tx_pulse;     // active posedge
	reg [7:0] tx_data;		//送入串口發送模塊,準備發送的數據
	//output from tx module
	wire      uart_tx;		//串口發送信號線
	wire      tx_busy;		//串口發送模塊狀態
	
	//時鐘參數
	parameter SYS_CLK_FRE = 40_000_000;     //系統頻率40MHz  40_000_000
	parameter SYS_CLK_PERIOD = 1_000_000_000/SYS_CLK_FRE;  //週期25ns
	parameter RST_CYCLE = 5;                //復位持續時間,clk時鐘週期數
	parameter RST_TIME = RST_CYCLE * SYS_CLK_PERIOD;    //復位時間:5個時鐘週期

	//波特率參數
  	parameter BAUD_RATE = 115200; 	//串口波特率
	parameter BAUD_RATE_PERIOD	= 1_000_000_000/BAUD_RATE;
	//波特率週期,0.104ms = 104us,1/9600 s = 1^9 /9600 ns = 4167 sim_clk
	//波特率週期, 1/115200 = 8680 ns  =  8.7us = 347 sim_clk

	//波特率+時鐘參數
    parameter [15:0]  BPS_NUM = SYS_CLK_FRE / BAUD_RATE; //時鐘/波特率,用時鐘週期構造波特率週期
	//  BPS_NUM = 40_000_000/115200 = 347.22 = 16'd347
    //  1 bit位寬所需時鐘週期的個數。最長的波特率計數,10417,二進制有14位,取16位
	//  parameter BPS_4800: 40MHz set 8333 ; 50MHz set 10417
	//  parameter BPS_9600: 40MHz set 4167 ; 50MHz set 5208
	//  parameter BPS_115200: 40MHz set 347; 50MHz set 434

//==========================================================================
//模擬:信號的輸入,顯示輸出結果
//==========================================================================
	//模擬系統時鐘:40MHz,25ns
	always #((SYS_CLK_PERIOD+1)/2-1) sim_clk = ~sim_clk; //延時,電平翻轉
	
	initial	begin
		//模擬復位信號:拉低一次
		#0;
			sim_clk = 1'b0;
			sim_rst_n = 1'b0;      //復位拉低,有效,
			
			uart_rx  = 1'b1;		//串口線,默認高,起始拉低
			//rx_data <= `UD 8'h00;		//rx_data 初始化,在 uart_rx中完成
			tx_pulse = 1'b0;		//觸發發送,高有效,先拉低
			tx_data  = 8'h00;		//數據默認爲0		
			
		//#RST_TIME;			   //延時:保持足夠長時間(至少5個clk)
		#BAUD_RATE_PERIOD;		   //5個clk時間軸太短,仿真改爲1個BPS,更明顯
			sim_rst_n = 1'b1;      //解除復位
		
		//==========================================================================
		//模擬串口接收:串行信號輸入,轉化成並行數據,並顯示
		//==========================================================================
			uart_rx = 1'b1;	   //串口發送線,默認拉高
		repeat( BPS_NUM*1 ) @(posedge sim_clk);	    //循環347個時鐘週期,即一個波特率週期
		//#BAUD_RATE_PERIOD; 						//直接延時,一個波特率週期
		
		$display("Initialization complete. BAUD_RATE is %d",BAUD_RATE); //命令行顯示初始化完成,輸出BAUD_RATE
		
		//串口:起始位
			uart_rx = 1'b0;	
		#BAUD_RATE_PERIOD;					

		//串行數據,一位一位送入接收信號線:***從位0到位7***,依次發送
		//測試數據爲8'hD8=8'b1101_1000
			uart_rx = 1'b0;		
		#BAUD_RATE_PERIOD; 
			uart_rx = 1'b0;		
		#BAUD_RATE_PERIOD; 
			uart_rx = 1'b0;		
		#BAUD_RATE_PERIOD; 		
			uart_rx = 1'b1;		
		#BAUD_RATE_PERIOD; 
			uart_rx = 1'b1;		
		#BAUD_RATE_PERIOD; 
			uart_rx = 1'b0;		
		#BAUD_RATE_PERIOD; 
			uart_rx = 1'b1;		
		#BAUD_RATE_PERIOD; 
			uart_rx = 1'b1;		
		#BAUD_RATE_PERIOD; 		
		$display("The uart_rx 8'hD8 = 8'b1101_1000 has been sent.");  //命令行顯示:串口信號線數據已發送

		//串口:結束位
			uart_rx = 1'b1;	
		#BAUD_RATE_PERIOD;
			$display("The uart_rx has received. rx_data = 8'h%h",rx_data);  
		//命令行顯示:串口信號線接收已結束,顯示接收到的數據
		
		//==========================================================================
		//模擬串口發送:並行數據,串行輸出
		//==========================================================================		
		//***串口接收模塊收到的數據,傳遞給串口輸出模塊***
		
		repeat( BPS_NUM*1 ) @(posedge sim_clk);	  //循環347個時鐘週期,即一個波特率週期
		//#BAUD_RATE_PERIOD; 		//直接延時,一個波特率週期		
		
		//傳遞 第一組數據:8位並行數據,一次性送入串口發送模塊
		 tx_data = rx_data;	//串口接收數據,傳給串口發送
		#BAUD_RATE_PERIOD;
		
		//開啓觸發信號:串口發送
		//tx_pulse = 1;				//用 rx_en 代替 模擬tx_pulse,直接觸發
		#BAUD_RATE_PERIOD;			//rx_en 串口接收數據有效,接收完成拉高1個BPS
		
		//結束觸發:串口發送
		//tx_pulse = 0;
		#BAUD_RATE_PERIOD;
		
		repeat( BPS_NUM*9 ) @(posedge sim_clk);	//發送數據,等待8個波特率週期
			$display("The first tx_data 8'h%h has been sent.",tx_data);  //命令行顯示:第1組數據發送完
		
		#BAUD_RATE_PERIOD;	
			$stop;		//結束仿真
		
	end

//==========================================================================
//調用top模塊
//==========================================================================
    //串口發送
    uart_rx #(
         //.CLK_SYS   (  SYS_CLK_FRE), //系統時鐘
         .BPS_NUM (  BPS_NUM  )  // 時鐘/波特率,1 bit位寬所需時鐘週期的個數
     )
     u_uart_rx(
        .clk      (  sim_clk  ),// input       clk,
		//.rst_n	  (  sim_rst_n ),// input 
		.uart_rx  (  uart_rx  ),// input reg  串口接收信號線
		
        .rx_data  (  rx_data  ),// output  接收到的數據
        .rx_finish(  rx_finish)// output  串口接收數據有效,接收完成拉高1個BPS
        //.rx_end   (  rx_end   ) // output  //接收到停止位,拉高1個clk,沒啥用
    );
	
	//串口發送
    uart_tx #(
         //.CLK_SYS   (  SYS_CLK_FRE), //系統時鐘
         .BPS_NUM (  BPS_NUM  )  // 時鐘/波特率,用時鐘週期構造波特率週期
     )
     u_uart_tx(
        .clk      (  sim_clk  ),// input       clk,
        .tx_data  (  tx_data  ),// input [7:0] tx_data,
        .tx_pulse (  rx_finish),// input       外部輸入,開始產生數據->開啓串口發送狀態

        .uart_tx  (  uart_tx  ),// output reg  uart_tx,
        .tx_busy  (  tx_busy  ),  // output      輸出,串口接收忙狀態
		.tx_finish(  tx_finish) // output      //串口發送數據結束標誌,8位數據發完,拉高一個BPS
    );

endmodule

3、仿真結果

ModelSim波形
[外鏈圖片轉存中...(img-RJwbdc2Q-1592206711752)]

命令行顯示
[外鏈圖片轉存中...(img-Phr8ckGc-1592206711759)]

增加 tx_finish 和 rx_finish
[外鏈圖片轉存中...(img-9MiYxW4g-1592206711764)]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章