You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 12:29:55