一、描述
之前做了一个串口发送,后来进行了几处优化。
本来触发发送的send_en需要在整个数据发送过程中都要拉高,改成只需要在出发时拉高一个时钟周期。然后再利用send_en一个时钟周期的高脉冲和其他逻辑实现baud_cnt在数据发送期间一直能计数。


还有就是在send_en拉高时,将data_byte用data_byte_reg寄存一级,确保取数据时数据是稳定的


然后在top中实现按一次按键,数据发送一个字节。
module uart_tx_top
(
input wire clk ,
input wire rst_n ,
input wire key_in ,
output wire rs232_tx ,
output wire uart_state
);
wire send_en;
wire [7:0] data_byte;
wire tx_done;
wire key_flag;
wire key_state;
uart_tx uart_tx_inst
(
.clk (clk),
.rst_n (rst_n),
.send_en (send_en),
.baud_set (20'd9600),
.data_byte (8'h35),
.rs232_tx (rs232_tx),
.tx_done (tx_done),
.uart_state (uart_state)
);
key_filter key_filter
(
.clk (clk),
.rst_n (rst_n),
.key_in (key_in),
.key_flag (key_flag),
.key_state (key_state)
);
assign send_en = key_flag & (!key_state);
endmodule

发现在按一次复位时,会收到长度不等的几个字节的数据!是00,或者是其他。
分析:
错误发送不止一个字节可以理解,因为复位键是没有经过消抖的,表面上按下一次,可能在20ns的时钟速度下几ms内已经检测到了多次rst_n == 0,从而触发多次复位。
原因应该在rst_n == 0 时,触发了一些赋值,从而会错误发送。
解决:在tb中只对复位信号给数据


发现在复位信号有效期间,uart_state信号有效了!导致整个rst_n ==0 期间会发送数据。找到代码中,确定是一个逻辑BUG。

改为在复位时,uart_state赋值为0,再硬件验证,发现bug被完美修复。