数据的输入:
数据的输入是uart接收模块的输出:串—并—串(接收到的外部的串行数据进入内部寄存器转化为并行数据,再由内部寄存器读出,输出表现为串行数据),接收到的输入信号为tx_flag(po_trig)和tx_data[7:0]。
内部的中间变量:
tx_data_reg:为寄存器存储输入并行数据
tx_flag:当开始发送数据的时候为高,停止发送数据时候为低
baud_cnt:波特计数器,发送一个波特所需要的时钟周期,当计数器记满之后采样,拉高bit_flag电平,输出一个数据
bit_flag:波特计数器记满之后拉高一个时钟周期,比特计数器加1
bit_cnt:记满8比特后拉低tx_flag;此时不再发送数据(当第一个bit_flag来的时候发送起始位)计数0-8
数据的输出:
rs_tx:当bit_flag拉高的时候发送一个数据
时序图:
代码:
`define sim
module uart_tx( input sclk,input srst,output reg rs232_tx,input tx_trig,input [7:0] tx_data
);//******************************************************
// degine parameter and internal signal
//******************************************************
`ifndef sim
localparam baud_end = 5207;
`else
localparam baud_end = 56;
`endiflocalparam bit_end = 8;reg [7:0] tx_data_reg;
reg tx_flag;
reg [12:0] baud_cnt;
reg bit_flag;
reg [3:0] bit_cnt;//========================================================
// main code
//========================================================always@(posedge sclk or negedge srst) beginif(srst == 1'b0)tx_data_reg <= 'd0;else if(tx_trig == 1'b1 && tx_flag == 1'b0)tx_data_reg <= tx_data;
endalways@(posedge sclk or negedge srst)beginif(srst == 1'b0)tx_flag <= 1'b0;else if(tx_trig == 1'b1)tx_flag <= 1'b1;else if(bit_cnt == bit_end && bit_flag == 1'b1)tx_flag <= 1'b0;
endalways@(posedge sclk or negedge srst)beginif(srst == 1'b0)baud_cnt <= 'd0;else if(baud_cnt == baud_end)baud_cnt <= 'd0;else if(tx_flag == 1'b1)baud_cnt <= baud_cnt + 1'b1;else baud_cnt <= 'd0;
endalways@(posedge sclk or negedge srst)beginif(srst == 1'b0)bit_flag <= 'b0;else if(baud_cnt == baud_end)bit_flag <= 1'b1;else bit_flag <= 1'b0;
endalways@(posedge sclk or negedge srst)beginif(srst == 1'b0)bit_cnt <= 'd0;else if(bit_cnt == bit_end && bit_flag == 1'b1)bit_cnt <= 'd0;else if(bit_flag == 1'b1)bit_cnt <= bit_cnt + 1'b1;//else // bit_cnt <= 'd0;
endalways@(posedge sclk or negedge srst) beginif(srst == 1'b0)rs232_tx <= 1'b1;else if(tx_flag == 1'b1)case(bit_cnt)0: rs232_tx <= 1'b0;1: rs232_tx <= tx_data_reg[0];2: rs232_tx <= tx_data_reg[1];3: rs232_tx <= tx_data_reg[2];4: rs232_tx <= tx_data_reg[3];5: rs232_tx <= tx_data_reg[4];6: rs232_tx <= tx_data_reg[5];7: rs232_tx <= tx_data_reg[6];8: rs232_tx <= tx_data_reg[7];default:rs232_tx <= 1'b1;endcaseelse rs232_tx <= 1'b1;
endendmodule
错误1:`define `ifndef写成`ifdef 导致仿真的时候baud_cnt计数太大
错误2:srst写成1有效
测试代码:
`timescale 1ns/1nsmodule tb_uart_tx;reg sclk;reg srst;reg tx_trig;reg [7:0] tx_data;wire rs232_tx;initial beginsclk = 1'b1;srst = 1'b0;#100srst = 1'b1;endalways#5 sclk = ~sclk;initial begintx_data <= 8'b0;tx_trig <= 'b0;#200tx_trig <= 'b1;tx_data <= 8'h55;#10 //1 clktx_trig <= 'b0;enduart_tx uart_tx_inst( .sclk (sclk) , .srst (srst) ,.rs232_tx (rs232_tx) ,.tx_trig (tx_trig) ,.tx_data (tx_data)
);endmodule
注意1:if else语句 else if的适用范围
注意2:当仿真验证通过但是加载到开发板出错以后 考虑逻辑问题,考虑连线出错没有。