概述
如图所示.本串口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中的仿真结果:
最后
以上就是淡淡大白为你收集整理的UART串口TX模块的Verilog实现和testbench代码的全部内容,希望文章能够帮你解决UART串口TX模块的Verilog实现和testbench代码所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复