UART串口TX模块的Verilog实现和testbench代码

如图所示.本串口TX模块包含     input clk_div,       // 时钟信号输入
    input [7:0]TX_data,  //待发送的数据
    input  TX_EN,         // 发送使能信号,上升沿有效
    output reg idle,         // TX信号线的状态,idle 高电平表示忙碌,低电平表示空闲
    output reg TX            // TX信号线输出

模块原理图如图所示:

 

TX模块的Verilog实现代码:

`timescale 1ns / 100ps
//

//


module UART_TX(
	input clk_div,       // 时钟信号输入
	input [7:0]TX_data,  //待发送的数据
	input  TX_EN,         // 发送使能信号,上升沿有效
	output reg idle,         // TX信号线的状态,idle 高电平表示忙碌,低电平表示空闲
	output reg TX            // TX信号线输出
    );
	


	
//  1. TX_EN的检测电路,得到允许发送数据的信号
reg TX_EN_D;
reg TX_EN_Flag;
always@(posedge clk_div)     // 上升沿检测
	begin
		TX_EN_D <= TX_EN;  
		TX_EN_Flag <= (~TX_EN_D)&TX_EN;  
	end
	

// 2.TX_data 数据发送电路
// 描述一个计数器,跟着时钟计数用来按时序发送数据.9600波特时用16个时钟发送1bit,那总时钟个数为16*11
reg [7:0]cnt;
parameter paritymode = 1'b0;  // 常数,奇偶校验的极性
reg presult;   // 保存奇偶校验的结果




always@(posedge clk_div)   //  关于idle信号
	begin
		if(cnt == 8'd176)     // 发送完了,进入空闲状态
			idle <= 1'b0;
		else if(TX_EN_Flag)   // 使能信号有效 ,进入忙状态
			idle <= 1'b1;
	end



always@(posedge clk_div)
	begin
		if(TX_EN_Flag)  // 发送使能信号无效
			begin
				cnt <= 8'b0;
//				idle <= 1'b0;
			end
		else
			begin
				case(cnt)
					8'd0:begin    // 起始位
							TX <= 1'b0;
//							idle <= 1'b1;       //   线路状态变成忙碌
							cnt <= cnt + 8'b1;	
						  end
					8'd16:begin            // 发送bit 0
							TX <= TX_data[0];
							presult <= TX_data[0] ^ paritymode;// 奇偶校验的操作,异或
							cnt <= cnt + 8'b1;	
						  end						  
					8'd32:begin            // 发送bit 1
							TX <= TX_data[1];
							presult <= TX_data[1] ^ presult;// 奇偶校验的操作,异或
							cnt <= cnt + 8'b1;	
						  end	
					8'd48:begin            // 发送bit 2
							TX <= TX_data[2];
							presult <= TX_data[2] ^ presult;// 奇偶校验的操作,异或
							cnt <= cnt + 8'b1;	
						  end						  
					8'd64:begin            // 发送bit 3
							TX <= TX_data[3];
							presult <= TX_data[3] ^ presult;// 奇偶校验的操作,异或
							cnt <= cnt + 8'b1;	
						  end	
					8'd80:begin            // 发送bit 4
							TX <= TX_data[4];
							presult <= TX_data[4] ^ presult;// 奇偶校验的操作,异或
							cnt <= cnt + 8'b1;	
						  end						  
					8'd96:begin            // 发送bit 5
							TX <= TX_data[5];
							presult <= TX_data[5] ^ presult;// 奇偶校验的操作,异或
							cnt <= cnt + 8'b1;	
						  end	
					8'd112:begin            // 发送bit 6
							TX <= TX_data[6];
							presult <= TX_data[6] ^ presult;// 奇偶校验的操作,异或
							cnt <= cnt + 8'b1;	
						  end						  
					8'd128:begin            // 发送bit 7
							TX <= TX_data[7];
							presult <= TX_data[7] ^ presult;// 奇偶校验的操作,异或
							cnt <= cnt + 8'b1;	
						  end							 
					8'd144:begin            // 发送校验位
							TX <= presult;							
							cnt <= cnt + 8'b1;	
						  end	
					8'd160:begin            // 发送停止位
							TX <= 1'b1;							
							cnt <= cnt + 8'b1;	
						  end	
					8'd176:begin            // 结束
//						   idle <= 1'b0;
							cnt <= 8'b0;	
						  end	
						  
					default:
						   cnt <= cnt + 8'b1;
				endcase
				
				
			end
		
			
	end

	
	
endmodule

 

模块对应的testbench代码:

`include "UART_TX.v"

module TX_tb;   //  闭合系统,不需要输入输出列表

reg clk_div,TX_EN;
reg [7:0]TX_data;

wire idle,TX;



// 例化

UART_TX tx_uut(
	.clk_div(clk_div),       // 时钟信号输入
	.TX_data(TX_data),  		//待发送的数据
	.TX_EN(TX_EN),         // 发送使能信号,上升沿有效
	.idle(idle),         	// TX信号线的状态,idle 高电平表示忙碌,低电平表示空闲
	.TX(TX)            	// TX信号线输出
    ); 

initial
	begin
		clk_div 		= 1'b1;
		TX_data[7:0] 	= 8'b10101010;
		TX_EN 			= 1'b0;
		
		forever
			begin
				#10 	TX_EN = 1'b1;
				#200 	TX_EN = 1'b0;
				TX_data = TX_data + 8'b1;
				#10		TX_EN = 1'b1;
				#200 	TX_EN = 1'b0;	
				
			end 
	end 

always #0.5 clk_div = ~clk_div;


endmodule

 

模块代码在modelsim中的仿真结果:

 

  • 5
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值