Verilog:FPGA和模拟行为差异的UART



编辑:删除了一些冗余,将所有作业移至非块,插入了一个重置映射为我的FPGA的输入按钮之一...但是当我实现代码时,它开始了传输相同的字符并陷入我的机器的单个状态。

综合和实施后模拟是相同的,$ TIME的

    module UART (reset_button, sysclk_p, sysclk_n,TxD, Tx_busy, Tx_state_scope_external);
    input reset_button, sysclk_p, sysclk_n;
    output wire TxD, Tx_busy;
    output wire [1:0]Tx_state_scope_external;
    //internal communications signals

    wire clk_internal;
    //buffer unit control signals
    wire [7:0]TxD_data_internal;
    wire Tx_start_internal;
    wire Tx_busy_internal;
    wire reset_flag;
    reset_buf RESET_BUFF (.reset_internal (reset_flag), .reset (reset_button));
    differential_CK CK_GENERATION (.sysclk_p (sysclk_p), .sysclk_n(sysclk_n), .clk(clk_internal));
    output_Dbuffer OB1 (.reset (reset_flag), .RTS_n (Tx_busy_internal), .clk(clk_internal), .TX_trigger (Tx_start_internal), .TX_data(TxD_data_internal));
    async_transmitter TX1 (.reset (reset_flag), .clk (clk_internal), .TxD_data(TxD_data_internal), .Tx_start (Tx_start_internal), .TxD(TxD), .Tx_busy_flag(Tx_busy_internal), .Tx_state_scope(Tx_state_scope_external));
    obuf_TX O_TX1( .Tx_busy(Tx_busy), .Tx_busy_flag(Tx_busy_internal));

   endmodule
    module reset_buf (
    output reset_internal,
    input reset
    );
// IBUF: Single-ended Input Buffer
// 7 Series
// Xilinx HDL Libraries Guide, version 14.7
IBUF #(
.IBUF_LOW_PWR("TRUE"), // Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards
.IOSTANDARD("DEFAULT") // Specify the input I/O standard
) IBUF_inst (
.O(reset_internal), // Buffer output
.I(reset) // Buffer input (connect directly to top-level port)
);
// End of IBUF_inst instantiation
    endmodule
    module differential_CK(
    input sysclk_p,
    input sysclk_n,
    output clk    
    );
    // IBUFGDS: Differential Global Clock Input Buffer
    // 7 Series
    // Xilinx HDL Libraries Guide, version 14.7
    IBUFGDS #(
    .DIFF_TERM("FALSE"), // Differential Termination
    .IBUF_LOW_PWR("TRUE"), // Low power="TRUE", Highest performance="FALSE"
    .IOSTANDARD("DEFAULT") // Specify the input I/O standard
    ) IBUFGDS_inst (
    .O(clk), // Clock buffer output
    .I(sysclk_p), // Diff_p clock buffer input (connect directly to top-level port)
    .IB(sysclk_n) // Diff_n clock buffer input (connect directly to top-level port)
    );
    // End of IBUFGDS_inst instantiation

    endmodule
    module output_Dbuffer (
    input reset,
    input RTS_n, //TX_BUSY flag of the transmitter is my ready to send flag
    input clk, //ck needed for the FSM
    output wire TX_trigger, //TX_START flag of the transmitter now comes from THIS unit instead of Receiver
    output wire [7:0]TX_data //byte for transmission
    );
    //internal variables
    reg [7:0] mem [0:9]; //memory init, 10 * 8 bit locations
    integer m, n, i, j, k ; //M = row [a.k.a. bytes], N = column [a.k.a. single bits]
    reg TX_trigger_int;
    reg [7:0] TX_data_int, TX_complete;
    //reg sum256_ok;        
    reg [7:0]checksum_buff ;
    //buffer FSM required variables 
    localparam  //state enumeration declaration
        BUF_IDLE = 3'b000, 
        BUF_START = 3'b001,
        BUF_BYTES = 3'b010,  
        BUF_BUSY = 3'b011,
        BUF_TX_CHECKSUM = 3'b100;
    reg [2:0] buf_state; //2 bits for 4 states

    //static assignments of OUTPUTS : Transmission Flag and Transmission Data (content)
    assign TX_trigger = TX_trigger_int;
    assign TX_data = TX_data_int;
    //Block for transmitting [here I manage the TX_Data and TX_Trigger functionality]
    always @(posedge clk)
        begin
            if (reset) 
                begin
                    buf_state <= BUF_IDLE;
                    TX_trigger_int <= 0;
                    TX_data_int <= 8'b00000000;
                end
            else case (buf_state)
            BUF_IDLE:
                begin
                       TX_trigger_int <= 0;
                       TX_data_int <= 8'b00000000;
                       m <=0;
                       n <=0;
                       i <=0;
                       j <=0;                                     
                       mem[9] <= 8'b01010001; //81
                       mem[8] <= 8'b01000000; //64
                       mem[7] <= 8'b00110001; //49
                       mem[6] <= 8'b00100100; //36
                       mem[5] <= 8'b00011001; //25
                       mem[4] <= 8'b00010000; //16
                       mem[3] <= 8'b00001001; //9
                       mem[2] <= 8'b00000100; //4
                       mem[1] <= 8'b00000001; //1
                       mem[0] <= 8'b00000010;//2
                       checksum_buff <= 8'd31;
                            //check if the TX is not busy
                       if (RTS_n == 0) buf_state <= BUF_START;                                                                     
                end
            BUF_START:
                begin
                    TX_trigger_int <= 0;
                    if ((i == 0) || ( (j - i) > 1 )) buf_state <= BUF_BYTES;
                            else begin
                                $display ("BUFFER BUSY @time:", $time);
                                buf_state <= BUF_BUSY;   
                            end 
                end   

            BUF_BYTES:
                begin
                    //check if the TX is busy
                    if (RTS_n==0) 
                        begin
                         //   TX_trigger_int = 1; 21.09 MOVED THE TRIGGER INSIDE THE ELSE N LINE 498
                            if (j > 9) 
                                begin
                                        TX_trigger_int <= 0;
                                        buf_state <= BUF_TX_CHECKSUM;
                                    end
                            else begin
                                    TX_data_int <= mem[j];
                                    TX_trigger_int <= 1;
                                    j <= j+1;
                                    //TX_trigger_int =0;
                                    buf_state <= BUF_START;
                                end
                        end
                    else buf_state <= BUF_BYTES;
                end
            BUF_BUSY:
                begin
                    if (RTS_n == 0)
                        begin 
                            $display ("BUFFER AVAILABLE AGAIN @time:", $time);
                            buf_state <= BUF_START;
                        end
                end
            BUF_TX_CHECKSUM:
                begin
                    if (RTS_n==0) begin
                        TX_data_int <= checksum_buff;
                    //    sum256_ok = 0;
                        TX_trigger_int <= 1;
                        buf_state <= BUF_IDLE;
                        end
                end
            //default: buf_state <= BUF_IDLE;
            endcase
    end

    endmodule
    module async_transmitter(
    input clk,
    input reset,
    //differential clock pair
    input [7:0] TxD_data,
    input  Tx_start, // it is ==TX_TRIGGER
    output wire TxD, //bit being sent to the USB
    output reg Tx_busy_flag,
    output wire [1:0]Tx_state_scope
    );
      localparam  //state enumeration declaration
      TX_IDLE = 2'b00, 
      TX_START_BIT = 2'b01,
      TX_BITS = 2'b10,
      TX_STOP_BIT = 2'b11;
      parameter ClkFrequencyTx = 200000000; // 200MHz
      parameter BaudTx = 9600;
      reg [1:0] Tx_state; //2 bits for 4 states
      integer bit_counter;   //bit counter variable
      reg [7:0]TxD_data_int, TxD_int;
      integer i; //vector index for output data
      wire TXSTART_Trigger;
      StartDetectionUnitTX SDU_TX (.clk(clk), .state (Tx_state), .signal_in (Tx_start), . trigger (TXSTART_Trigger));
      wire BitTick;
      BaudTickGen #(ClkFrequencyTx, BaudTx) as (.clk(clk), .trigger (TXSTART_Trigger), .tick(BitTick));
      //BitTick is 16times the frequency generated during the RX portion
      assign TxD = TxD_int;
      always @(posedge clk) begin
            if (reset) 
                begin
                    Tx_state <= TX_IDLE;
                    TxD_int <= 1;
                    Tx_busy_flag <=0;
                end
            else case (Tx_state)
                TX_IDLE:
                    begin //reinitialization and check on the trigger condition
                        bit_counter <= 0;
                        TxD_data_int <= 8'b00000000;
                        i <= 0;
                        TxD_int <= 1; //idle state
                        Tx_busy_flag <= 0; 
                                if (TXSTART_Trigger) begin
                                         Tx_state <= TX_START_BIT;
                                         TxD_data_int <= TxD_data;
                                         Tx_busy_flag <= 1; 
                                         bit_counter <= 8;
                                     end                              
                    end
                TX_START_BIT:
                    begin
                        if (BitTick)
                            begin
                            TxD_int <= 0 ; //start bit is a ZERO logical value
                            Tx_state <= TX_BITS; 
                            end 
            end
                TX_BITS:
                    begin
                        if (BitTick) 
                            begin
                                bit_counter <= bit_counter -1;
                                TxD_int <= TxD_data_int[i];
                       //         $display ("ho trasmesso dalla UART un bit di valore %b al tempo: ", TxD, $time);
                                i <= i+1;
                                if (bit_counter < 1) Tx_state <= TX_STOP_BIT; 
                            end
                    end

                 TX_STOP_BIT:   
                               begin
                                   if (BitTick) begin
                                       TxD_int <= 1; //STOP BIT is a logical '1'
                                       Tx_busy_flag <= 0;
                                       Tx_state <= TX_IDLE;          
                                       end                                 
                               end

               // default: Tx_state <= TX_IDLE;
                endcase
             end 

            assign Tx_state_scope = Tx_state;
endmodule
module obuf_TX (
    output Tx_busy,
    input Tx_busy_flag
    );
// OBUF: Single-ended Output Buffer
// 7 Series
// Xilinx HDL Libraries Guide, version 14.7
OBUF #(
.DRIVE(12), // Specify the output drive strength
.IOSTANDARD("DEFAULT"), // Specify the output I/O standard
.SLEW("SLOW") // Specify the output slew rate
) OBUF_inst (
.O(Tx_busy), // Buffer output (connect directly to top-level port)
.I(Tx_busy_flag) // Buffer input
);
// End of OBUF_inst instantiation
endmodule
module StartDetectionUnitTX ( //detects a rising edge of the start bit == TRANSMISSION START, during the IDLE state = 0000
    input clk, [1:0]state, 
    input signal_in,
    output trigger
    );
    reg signal_d;
    always @(posedge clk)
            begin
            signal_d <= signal_in;
        end   
    assign trigger = signal_in & (!signal_d) & (!state);
endmodule  
module BaudTickGen (
        input clk, trigger, 
        output tick //generates a tick at a specified baud rate *oversampling
        );
        parameter ClkFrequency = 200000000; //sysclk at 200Mhz
        parameter Baud = 9600;
        parameter Oversampling = 1;
        //20832 almost= ClkFrequency / Baud, to make it an integer number
        integer counter = (20833/Oversampling)-1; //-1 so counter can get to 0
        reg out;
        always @(posedge clk)
                   begin
                    if (trigger) 
                        begin
                            counter <= (20833/Oversampling)-1; //-1 so counter can get to 0
                            out <= 1; 
                        end
                           if (counter == 0) 
                               begin
                                   counter <= (20833/Oversampling)-1; //-1 so counter can get to 0
                                   out <= 1; 
                               end
                               else begin
                                   counter <= counter-1;
                                   out <= 0;
                               end   
                    end     
            assign tick = out;
            endmodule

我的FPGA是Virtex-7 VC707,我正在使用Vivado进行设计流程。

在这里,我正在附上循环错误的图像。

错误图像

您做了什么?您只是模拟了代码吗?您是说它在董事会上失败了,但是插入后模拟可以吗?

  1. 实施前和实施后SIM之间的差异可能指向种族条件。摆脱所有您的阻止分配,用NBA替换(为什么使用阻止分配?)
  2. 不要去Chipscope-这只是一个危险信号,您不知道自己在做什么
  3. 代码是一团糟 - 简化它。Xilinx特定的内容是无关紧要的 - 如果您希望任何人查看它,请删除它,修复评论( 2 bit state?!),修复有关卡在'10'的说法,等
  4. 您是否通过Vivado运行?严重地?您有多个信号的驱动程序。摆脱初始块,使用重置。以工具理解的方式初始化RAM。即使Vivado能够使用单独的初始块初始化内容,也不要这样做
  5. 摆脱tx_idle分支中的'else tx_state = tx_idle'之类的语句 - 它们是冗余的,只需添加冗长
  6. 写一些失败的东西,然后再次发布。

相关内容

  • 没有找到相关文章

最新更新