Basys3 FPGA通过UART发送数据时接收位错误的调试求助
问题:Basys3 UART发送数据与接收端不符
我想通过UART把Basys3开发板的数据发到笔记本电脑,Verilog代码仿真能正常发送,但接收端拿到的位不对。
发送ASCII字符U(对应二进制01010101)时,仿真显示每1/9600秒发送一位,10位发送完成耗时1041.66us,时序误差在2.5%的可接受范围内。传输起始时拉低TX,从LSB开始发数据,结束后拉高TX回到空闲状态。
但用Pyserial接收相同数据时结果不对,PuTTy终端显示字符A和未知符号。电脑端已经设置9600波特率、8位数据位、1位停止位、无奇偶校验。
设计源码
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 05/24/2023 04:33:54 PM // Design Name: // Module Name: TopUART // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module TopUART#(parameter cycle_BRG = 5208, idle = 2'b00, loading = 2'b01, sending = 2'b11, done = 2'b10)( input clk, input [7:0] data_send, input transmit, output Txd ); reg [13:0] BRG_counter = 0; reg [9:0] bit_counter = 0; reg BRG_SET; //set to 1 every (1/9600) seconds reg BRG_SET_tracker; //used so that I can set BRG_SET in two always blocks reg [1:0] state = 0; reg load = 0; reg shift = 0; reg clear = 0; reg Txd = 1; reg [9:0] shiftright_register = 0; //BRG for UART always @(posedge clk) begin if(BRG_counter == cycle_BRG) begin BRG_SET <= 1; BRG_counter <= 0; end else begin BRG_counter <= BRG_counter + 1; BRG_SET <= 0; end end //controller for UART always@(posedge clk) begin case(state) idle: //waiting for transmit button to be pressed begin if(transmit) begin state <= loading; load <= 1; shift <= 0; clear <= 0; Txd <= 1; end else begin state <= idle; load <= 0; shift <= 0; clear <= 0; Txd <= 1; end end loading: //button was pressed, keeping load signal high until BRG has been set so that data path can update the shift register begin if(BRG_SET) begin state <= sending; load <= 0; shift <= 1; clear <= 0; Txd <= 1; end else begin state <= loading; load <= 1; shift <= 0; clear <= 0; Txd <= 1; end end sending: //send data until 10 bits have been sent on TX line begin if(bit_counter == 10) begin state <= done; load <= 0; shift <= 0; clear <= 1; Txd <= 1; end else begin state <= sending; load <= 0; shift <= 1; clear <= 0; Txd <= shiftright_register[0]; end end done: //once 10 bits set, keep clear high and wait for BRG_SET to become 1 so that data path can reset the bit counter and BRG counter begin if(BRG_SET) begin state <= idle; load <= 0; shift <= 0; clear <= 0; Txd <= 1; end else begin state <= done; load <= 0; shift <= 0; clear <= 1; Txd <= 1; end end endcase end //data path for UART always @(posedge BRG_SET) begin if(load) begin shiftright_register <= {1'b1, data_send, 1'b0}; bit_counter <= 0; end else if(shift) begin shiftright_register <= shiftright_register >> 1; bit_counter <= bit_counter +1; end else if(clear) begin bit_counter <= 0; end end endmodule
约束文件
set_property IOSTANDARD LVCMOS33 [get_ports {data_send[7]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_send[6]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_send[5]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_send[4]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_send[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_send[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_send[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_send[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {transmit}] set_property IOSTANDARD LVCMOS33 [get_ports {Txd}] set_property PACKAGE_PIN W13 [get_ports {data_send[7]}] set_property PACKAGE_PIN W14 [get_ports {data_send[6]}] set_property PACKAGE_PIN V15 [get_ports {data_send[5]}] set_property PACKAGE_PIN W15 [get_ports {data_send[4]}] set_property PACKAGE_PIN W17 [get_ports {data_send[3]}] set_property PACKAGE_PIN W16 [get_ports {data_send[2]}] set_property PACKAGE_PIN V16 [get_ports {data_send[1]}] set_property PACKAGE_PIN V17 [get_ports {data_send[0]}] set_property PACKAGE_PIN T17 [get_ports {transmit}] set_property PACKAGE_PIN A18 [get_ports {Txd} ] set_property PACKAGE_PIN W5 [get_ports clk] set_property IOSTANDARD LVCMOS33 [get_ports clk] create_clock -period 10.000 -name sys_clk_pin -waveform {0.000 5.000} -add [get_ports clk]
补充内容:测试平台
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 05/25/2023 09:53:23 AM // Design Name: // Module Name: TopUARTTestbench // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module TopUARTTestbench( ); reg clk = 0; always #10 clk = ~clk; reg [7:0] data_send; reg transmit; wire Txd; TopUART x (clk, data_send, transmit, Txd); initial begin #20 transmit = 1; #30; transmit = 0; data_send = 8'b01010101; end endmodule
补充内容:波特率计数器调整
已将cycle_BRG设置为10416(每比特10416个时钟周期),使用10417时MSB始终被识别为1,推测是电脑采样时错过最后数据位,将停止位误读为最后数据位。
内容的提问来源于stack exchange,提问作者Hamza Beder
相关产品推荐
相关产品推荐

