? ? ? ? 数据的输入是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;
`endif
localparam 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) begin
if(srst == 1'b0)
tx_data_reg <= 'd0;
else if(tx_trig == 1'b1 && tx_flag == 1'b0)
tx_data_reg <= tx_data;
end
always@(posedge sclk or negedge srst)begin
if(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;
end
always@(posedge sclk or negedge srst)begin
if(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;
end
always@(posedge sclk or negedge srst)begin
if(srst == 1'b0)
bit_flag <= 'b0;
else if(baud_cnt == baud_end)
bit_flag <= 1'b1;
else
bit_flag <= 1'b0;
end
always@(posedge sclk or negedge srst)begin
if(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;
end
always@(posedge sclk or negedge srst) begin
if(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;
endcase
else
rs232_tx <= 1'b1;
end
endmodule
错误1:`define `ifndef写成`ifdef? 导致仿真的时候baud_cnt计数太大
错误2:srst写成1有效
`timescale 1ns/1ns
module tb_uart_tx;
reg sclk;
reg srst;
reg tx_trig;
reg [7:0] tx_data;
wire rs232_tx;
initial begin
sclk = 1'b1;
srst = 1'b0;
#100
srst = 1'b1;
end
always
#5 sclk = ~sclk;
initial begin
tx_data <= 8'b0;
tx_trig <= 'b0;
#200
tx_trig <= 'b1;
tx_data <= 8'h55;
#10 //1 clk
tx_trig <= 'b0;
end
uart_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:当仿真验证通过但是加载到开发板出错以后? 考虑逻辑问题,考虑连线出错没有。