目录
实现功能:
1.接收uart串行数据,输出并行数据(1byte)。
2.输入并行数据(1byte),输出uart串行数据。
3.完成uart传输的1次环回。
uart协议的1帧数据传输
模块封装-port设置
Verilog代码实现
1.uart接收模块:接收串行数据,输出并行数据和其有效标志。
仿真结果:
2.uart发送模块:接收并行数据,发送串行数据。
仿真结果:
3.uart环回测试。
仿真验证:
仿真结果:
FPGA系统集成-RTL框图
实现功能:
1.接收uart串行数据,输出并行数据(1byte)。
2.输入并行数据(1byte),输出uart串行数据。
3.完成uart传输的1次环回。
uart协议的1帧数据传输

模块封装-port设置

Verilog代码实现
1.uart接收模块:接收串行数据,输出并行数据和其有效标志。
module uart_rx#(parameter	UART_BPS='d9600			,	//波特率:1s传输9600个bitparameter	CLK_FREQ='d50_000_000		//时钟频率:50MHz
)(input 	wire			clk			,input 	wire			rst_n		,input 	wire			rx			,	//接收的串行数据output 	reg		[7:0]	po_data		,	//输出并行数据output 	reg				po_flag			//输出有效并行数据的标志信号
);首先对rx进行时钟同步,消除亚稳态,以及打拍处理提取下降沿;
always@(posedge clk or negedge rst_n)if(!rst_n) beginrx_d1<=1'b1;rx_d2<=1'b1;rx_d3<=1'b1;endelse beginrx_d1<=rx;		//时钟同步,消除亚稳态rx_d2<=rx_d1;	//时钟同步,消除亚稳态rx_d3<=rx_d2;	//打拍处理endassign rx_fall = ~rx_d2 & rx_d3 ;	//提取rx下降沿然后需要数据帧的有效信号,以便知道什么时候计数;
always@(posedge clk or negedge rst_n)if(!rst_n) frame_val<=1'b0;else if((bit_cnt==BIT_CNT_MAX-1'b1) && bit_flag)	//接收完1帧数据frame_val<=1'b0;else if(rx_fall)frame_val<=1'b1;elseframe_val<=frame_val;1码元符号(1bit)所需的计数器;
always@(posedge clk or negedge rst_n)if(!rst_n) baud_cnt<=16'd0;else if(frame_val==1'b0)	//数据帧无效baud_cnt<=16'd0;else if(baud_cnt==BAUD_CNT_MAX-1'b1)baud_cnt<=16'd0;elsebaud_cnt<=baud_cnt+1'b1;
1bit稳定数据的采样标志信号;
always@(posedge clk or negedge rst_n)if(!rst_n) bit_flag<=1'b0;else if(baud_cnt==BAUD_CNT_MAX_HALF-1'b1)	//采样需要在中间数据才稳定bit_flag<=1'b1;elsebit_flag<=1'b0;对采样到的bit数据进行计数;
always@(posedge clk or negedge rst_n)if(!rst_n) bit_cnt<=4'd0;else if((bit_cnt==BIT_CNT_MAX-1'b1) && bit_flag)	//10bit数据采样完毕bit_cnt<=4'd0;else if(bit_flag)	//采样到1bit数据bit_cnt<=bit_cnt+1'b1;elsebit_cnt<=bit_cnt;将接收到的串行数据rx转化为并行数据po_data_t;
always@(posedge clk or negedge rst_n)if(!rst_n) po_data_t<=8'b0;else if((bit_cnt>=4'd1) && (bit_cnt<BIT_CNT_MAX-1'b1) && bit_flag)	//8bit数据po_data_t<={rx_d3,po_data_t[7:1]};	//起始位后接的是低位elsepo_data_t<=po_data_t;并行数据全部拼接完成的标志信号;
always@(posedge clk or negedge rst_n)if(!rst_n) po_flag_t<=1'b0;else if((bit_cnt==BIT_CNT_MAX-1'b1) && bit_flag)po_flag_t<=1'b1;elsepo_flag_t<=1'b0;输出并行数据和输出有效并行数据的标志信号。
always@(posedge clk or negedge rst_n)if(!rst_n) po_data<=8'b0;else if(po_flag_t)po_data<=po_data_t;elsepo_data<=po_data;//po_flag_t延迟1拍与po_data同步
always@(posedge clk or negedge rst_n)if(!rst_n) po_flag<=1'b0;elsepo_flag<=po_flag_t;仿真结果:

2.uart发送模块:接收并行数据,发送串行数据。
module uart_tx#(parameter	UART_BPS='d9600			,	//波特率:1s传输9600个bitparameter	CLK_FREQ='d50_000_000		//时钟频率:50MHz
)(input 	wire			clk			,input 	wire			rst_n		,input	wire			pi_flag		,	//输入并行数据input	wire	[7:0]	pi_data		,	//输入有效并行数据的标志信号output 	reg 			tx				//输出串行数据
);首先同样是uart 1帧数据的有效信号;
always@(posedge clk or negedge rst_n)if(!rst_n) frame_val<=1'b0;else if((bit_cnt==BIT_CNT_MAX-1'b1) && bit_flag)	//发送完1帧数据frame_val<=1'b0;else if(pi_flag)	//接收到有效的并行数据frame_val<=1'b1;elseframe_val<=frame_val;1码元符号(1bit)所需的计数器;
always@(posedge clk or negedge rst_n)if(!rst_n) baud_cnt<=16'd0;else if(frame_val==1'b0)	//数据帧无效baud_cnt<=16'd0;else if(baud_cnt==BAUD_CNT_MAX-1'b1)baud_cnt<=16'd0;elsebaud_cnt<=baud_cnt+1'b1;1bit数据的发送标志信号;
always@(posedge clk or negedge rst_n)if(!rst_n) bit_flag<=1'b0;else if(frame_val && !baud_cnt)bit_flag<=1'b1;elsebit_flag<=1'b0;对bit数据的发送进行计数;
always@(posedge clk or negedge rst_n)if(!rst_n) bit_cnt<=4'd0;else if((bit_cnt==BIT_CNT_MAX-1'b1) && bit_flag)	//10bit数据计数完毕bit_cnt<=4'd0;else if(bit_flag)	//发送完1bit数据bit_cnt<=bit_cnt+1'b1;elsebit_cnt<=bit_cnt;
输出串行数据。
always@(posedge clk or negedge rst_n)if(rst_n==1'b0) tx<=1'b1;	//空闲else if(bit_flag)case(bit_cnt)4'd0:	tx<=1'b0;		//起始位4'd1:	tx<=pi_data[0];	//最低位数据4'd2:	tx<=pi_data[1];4'd3:	tx<=pi_data[2];4'd4:	tx<=pi_data[3];4'd5:	tx<=pi_data[4];4'd6:	tx<=pi_data[5];4'd7:	tx<=pi_data[6];4'd8:	tx<=pi_data[7];	//最高位数据4'd9:	tx<=1'b1;		//结束位default:tx<=1'b1;endcase仿真结果:

3.uart环回测试。
module uart_test#(parameter	UART_BPS='d9600			,	//波特率:1s传输9600个bitparameter	CLK_FREQ='d50_000_000		//时钟频率:50MHz
)(input 	wire clk	,input 	wire rst_n	,input 	wire rx		,	//接收的串行数据output 	wire tx			//发送的串行数据
);wire [7:0] 	data		;
wire 		data_flag	;uart_rx#(.UART_BPS(UART_BPS),.CLK_FREQ(CLK_FREQ)
)u_uart_rx(.clk	(clk	),.rst_n	(rst_n	),.rx		(rx		),.po_data(data),.po_flag(data_flag)
);uart_tx#(.UART_BPS(UART_BPS),.CLK_FREQ(CLK_FREQ)
)u_uart_tx(.clk	(clk	),.rst_n	(rst_n	),.pi_data(data),.pi_flag(data_flag),.tx(tx)
);endmodule仿真验证:
`timescale 1ns/1ns
module tb_uart_test();parameter	UART_BPS='d9600			;	//波特率:1s传输9600个bit
parameter	CLK_FREQ='d50_000_000	;	//时钟频率:50MHzreg clk;
reg rst_n;
reg rx;wire tx;initial
beginclk=1'b0;rst_n<=1'b0;rx<=1'b1;#20rst_n<=1'b1;
endalways #10 clk=~clk;initial
begin#200	//空闲状态rx_test();#(5208*10*20*3)#200$stop;
end//输出uart数据帧(10-13)
task rx_test();	//任务函数,类似C语言integer j;for(j=10;j<13;j=j+1)rx_8bit(j);
endtask//输入8bit并行数据,输出uart数据帧
task rx_8bit(input [7:0] data
);
integer i;for(i=0;i<10;i=i+1)
begincase(i)0:rx<=1'b0;		//1帧数据1:rx<=data[0];2:rx<=data[1];3:rx<=data[2];4:rx<=data[3];5:rx<=data[4];6:rx<=data[5];7:rx<=data[6];8:rx<=data[7];9:rx<=1'b1;endcase#(5208*20);		//9600波特率
end
endtaskuart_test#(.UART_BPS(UART_BPS),.CLK_FREQ(CLK_FREQ)
)u_uart_test(.clk	(clk	),.rst_n	(rst_n	),.rx		(rx		),.tx(tx)
);endmodule仿真结果:

FPGA系统集成-RTL框图
