刚开始学verilog 写了个uart程序,请教大侠啦;每次都丢最后一位
时间:10-02
整理:3721RD
点击:
我用led显示串口输入的数据,每次都丢最后一位,而且最后一位总是1
代码:
always @ (posedge clk or negedge rst_n)
if(!rst_n) begin
rx_temp_data <= 8'd0;
num <= 4'd0;
rx_data_r <= 8'd0;
end
else if(rx_int) begin //接收数据处理
if(clk_bps) begin //读取并保存数据,接收数据为一个起始位,8bit数据,1个结束位
num <= num+1'b1;
case (num)
4'd1: rx_temp_data[0] <= rs232_rx; //锁存第0bit
4'd2: rx_temp_data[1] <= rs232_rx; //锁存第1bit
4'd3: rx_temp_data[2] <= rs232_rx; //锁存第2bit
4'd4: rx_temp_data[3] <= rs232_rx; //锁存第3bit
4'd5: rx_temp_data[4] <= rs232_rx; //锁存第4bit
4'd6: rx_temp_data[5] <= rs232_rx; //锁存第5bit
4'd7: rx_temp_data[6] <= rs232_rx; //锁存第6bit
4'd8: rx_temp_data[7] <= rs232_rx; //锁存第7bit
default: ;
endcase
end
else if(num == 4'd10) begin //我们的标准接收模式下只有1+8+1=10bit的有效数据
num <= 4'd0; //接收到STOP位后结束,num清零
rx_data_r <= rx_temp_data; //把数据锁存到数据寄存器rx_data中
end
end
代码:
always @ (posedge clk or negedge rst_n)
if(!rst_n) begin
rx_temp_data <= 8'd0;
num <= 4'd0;
rx_data_r <= 8'd0;
end
else if(rx_int) begin //接收数据处理
if(clk_bps) begin //读取并保存数据,接收数据为一个起始位,8bit数据,1个结束位
num <= num+1'b1;
case (num)
4'd1: rx_temp_data[0] <= rs232_rx; //锁存第0bit
4'd2: rx_temp_data[1] <= rs232_rx; //锁存第1bit
4'd3: rx_temp_data[2] <= rs232_rx; //锁存第2bit
4'd4: rx_temp_data[3] <= rs232_rx; //锁存第3bit
4'd5: rx_temp_data[4] <= rs232_rx; //锁存第4bit
4'd6: rx_temp_data[5] <= rs232_rx; //锁存第5bit
4'd7: rx_temp_data[6] <= rs232_rx; //锁存第6bit
4'd8: rx_temp_data[7] <= rs232_rx; //锁存第7bit
default: ;
endcase
end
else if(num == 4'd10) begin //我们的标准接收模式下只有1+8+1=10bit的有效数据
num <= 4'd0; //接收到STOP位后结束,num清零
rx_data_r <= rx_temp_data; //把数据锁存到数据寄存器rx_data中
end
end
我看 好像是第8bit 为1 的话,fpga把那一位当成 结束位 了,不明白
rx_int ,clk_bps 这2个信号时怎么来的 呢?
uart有停止位吧,而且停止位为1吧,会在接收时去除吧,这个明显有问题,为何用两个时钟,感觉看不明白你的,看看标准的吧
别的不说,先把代码写规范了,clk在你敏感列表里,但代码里完全没用到,反而用到了clk_bps
uart是异步的,得用快点的时钟去采,8倍或16倍,中间采样几次做个判决,3取2或5取3
初学就弄UART呀,我惭愧呀
觉得case不应该写在时序块里,应该单独拿出来放在组合逻辑always块里吧。不然你的这个层次有点乱啊,条件都不是很完备。
同步时钟啊可以综合
