UART发送模块的Verilog实现

UART协议的详细介绍,请点击此处UART的详解

UART发送模块大致有以下几个行为:
【1】数据未开始传输(复位状态reset=1)
【2】数据即将开始传输(电路处于空闲状态,但数据传输信号有效,即~tx_busy & new_tx_data)
【3】数据正在开始传输,时钟信号ce_16未计满16次,即未产生ce_1信号(每产生一次ce_1信号,移位科寄存器要移位一次)
【4】数据正在开始传输,时钟信号ce_16计满16次,产生ce_1信号,移位寄存器内的数据,循环右移一位,并将此bit送到串行输出端进行串行输出
【5】随着ce_1信号不断产生,数据不断移位传输,当bit计数计数器bit_count(用来计数已传输完成的数据bit)计满九次(已传输包括开始位,8个数据位)。
【6】当ce_16信号再次产生时,bit_count计数满10位,停止位传输完成,预示着一个字符的数据已经传输完成。电路重新恢复到空闲状态(!tx_busy)。

下面给出UART发送模块的verilog实现:

// uart transmit module  

module uart_tx  
						(
							clock, 
							reset,
							ce_16,
							 tx_data, 
							 new_tx_data, 
							ser_out, 
							tx_busy
						);

					input 			clock;		
					input 			reset;		
					input			ce_16;			//波特率时钟信号 
					input	[7:0]	tx_data;		// 待传输数据
					input			new_tx_data;	// 断言,表示有一个新的数据字节要传输
					output			ser_out;		// 串行数据输出
					output 			tx_busy;		// 数据正在传输

					// internal wires 
					wire ce_1;		// clock enable at bit rate(产生一个脉冲则数据传输完一位)

				// internal registers 
				reg ser_out;
				reg tx_busy;
				reg [3:0]	count16;             //产生ce_1脉冲信号的计数器
				reg [3:0]	bit_count;         //计数已传输数据bit的个数
				reg [8:0]	data_buf;          //移位寄存器,存储即将传输的数据


				//模块一.ce_1脉冲的产生,脉冲c计数器,16个ce_16得到1个ce_1 
				always @ (posedge clock or posedge reset)
				begin
					if (reset) 
						count16 <= 4'b0;
					else if (tx_busy & ce_16)         //只有发射机处于发送数据的状态时,ce_16脉冲计数,转换为ce_1脉冲
						count16 <= count16 + 4'b1;
					else if (~tx_busy)                //不发送数据,则此寄存器清零
						count16 <= 4'b0;
				end 
				// ce_1 pulse indicating output data bit should be updated 
				assign ce_1 = (count16 == 4'b1111) & ce_16;  //ce_1脉冲指示更新(计数器计满后,在来一个脉冲,则会产生一个ce_1时钟脉冲信号)



			// tx_busy flag (电路状态的一些行为)
			always @ (posedge clock or posedge reset)
			begin
				if (reset) 
					tx_busy <= 1'b0;//复位低电平
				else if (~tx_busy & new_tx_data)//未传输数据,但新数据信号有效时,变为高电平,意思是数据正在传输
					tx_busy <= 1'b1;
				else if (tx_busy & (bit_count == 4'h9) & ce_1)   //数据已经传输9位,在传输一位,传输停止,tx_busy表示空闲状态
					tx_busy <= 1'b0;
			end 





				// output bit counter (输出的数据位数计算)
				always @ (posedge clock or posedge reset)
				begin
					if (reset) 
						bit_count <= 4'h0;            //复位寄存器清零
					else if (tx_busy & ce_1)		//电路处于传输数据的状态,当ce_1脉冲产生,那么数据传输完成一位
						bit_count <= bit_count + 4'h1;
					else if (~tx_busy)              //如果电路处于未传输的状态,那么没有数据传输,寄存器为0
						bit_count <= 4'h0;    
				end 






				// data shift register (数据移位寄存器)
				always @ (posedge clock or posedge reset)
				begin
					if (reset) 
						data_buf <= 9'b0;
					else if (~tx_busy)                 //未传输数据时,寄存器存放的是起始位和待传输数据位
						data_buf <= {tx_data, 1'b0};
					else if (tx_busy & ce_1)           //当一位数据传输完成后,移位寄存器中的数据移位1bit
						data_buf <= {1'b1, data_buf[8:1]};//存储的数据右移
				end 







				// output data bit (数据的串行输出)
				always @ (posedge clock or posedge reset)
				begin
					if (reset) 
						ser_out <= 1'b1;      
					else if (tx_busy)
						ser_out <= data_buf[0];//使用右移移位寄存器将数据不断送到最低位,从而不断的送到串行输出端
					else 
						ser_out <= 1'b1;
				end 

endmodule

参考文献:

【1】opencores

发布了50 篇原创文章 · 获赞 5 · 访问量 2695

猜你喜欢

转载自blog.csdn.net/qq_43042339/article/details/103815459