首页 > 解决方案 > verilog中的以下代码有什么问题?

问题描述

我在 rs232 上工作了一个多星期。我的程序需要一个 13 位数据帧 [来自 testbench] 并串行传输它。现在,我正在测试 TX 端。我认为这[如下评论-here1,here2] 是问题所在。

module rs232_tx(dtr_tx,rts_tx,clk_tx,dsr_tx,cts_tx,data_tx,dataframe_tx,r_tx);
input clk_tx;
input dsr_tx;                // data set ready
input cts_tx;                // clear to send
//input rx;                  // not using for now
input r_tx;                  // asynchronous active low reset signal, given by testbench
input [8:0]data_tx;          // send this data serially out, given by testbench
output reg dtr_tx;           // data terminal ready
output reg rts_tx;           // ready to send
output reg dataframe_tx;     // serially out data

reg [1:0]state_tx;
reg [1:0]next_tx;
reg [12:0]temp_tx;
reg done_tx;

reg [3:0]count_tx = 4'b1100; // counting the shift

parameter S_IDLE=2'b00, S_START=2'b01, S_SENDING=2'b10, S_DONE=2'b11, frame_size=4'b1100;

always@(posedge clk_tx, negedge r_tx)
begin
  if(~r_tx)
    state_tx <= S_IDLE;
  else
    state_tx <= next_tx;
end

always@(*)
begin
  case(state_tx)
    S_IDLE:
    begin
      done_tx = 1'b0;
      dtr_tx = 1'b1;
      temp_tx = 12'b0;
      next_tx = (dsr_tx) ? S_START : S_IDLE; // dsr gives receiver information
    end
    S_START:
    begin                           // form data-frame
      rts_tx = 1'b1;
      .    
      .
      .
      //assigning data to temp_tx bit by bit. And few more bits.
      .
      .
      next_tx = (cts_tx) ? S_SENDING : S_START;
    end
    S_SENDING:
    begin
      //dataframe_tx = temp_tx[frame_size - count_tx];
      dataframe_tx = temp_tx[frame_size];
      temp_tx = temp_tx<<1;
      count_tx = count_tx - 1;
      if(|count_tx)
        next_tx = S_SENDING;
      else
      begin
        next_tx = S_DONE;
        done_tx = 1'b1;
      end
    end
    S_DONE:
    begin
      done_tx = 1'b0;
    end
    default:
      next_tx = S_IDLE;
  endcase
end

endmodule

在测试台中:

module rs232_tb;
.
.
rs232_tx dut(.clk(c_Clock),.rst(c_r),.dataframe_tx(t_data),done_tx,temp_tx);
.
.
.
initial
  begin
    $dumpfile("rs232.vcd");
    $dumpvars(0,rs232_tb);
    #7 c_r = 1'b1;
    // checking Tx
    #7 t_dsr = 1'b1;          // Data Set Ready signal for rs232
    #7 t_data = 9'b101010101; // data to be transmitted on receiving CTS from RX.
    #7 t_cts = 1'b1;         // Clear To Send signal from RX
    #50 $finish;
  end
.
.
.

问题是,我总是在 dataframe_tx 上获得 temp_tx[12] 值,然后 temp_tx 在逻辑上向左旋转一。下一次,这种转变不会发生。我观察到reg [3:0]state它保持在 S_SENDING 状态,但在下一个时钟沿没有执行逻辑移位。另外,作为旁注,我观察到 count_tx 只递减一次,然后就保持不变为 11。

我正处于学习阶段。我在互联网上找不到任何解决方案或任何共享此类问题的人。请帮我...

标签: verilogprotocolshdlfsmiverilog

解决方案


您正在对作为主要输入的 temp_tx 执行逻辑操作,这是不正确的。将此输入存储到寄存器并对其执行操作。

always@(posedge clk or negedge rst_n)
begin
 if(!rst_n)
  temp_tx_reg <= 'd0;
 else if (state == S_START) // Register input when initializing
  temp_tx_reg <= temp_tx;
end

也请使用适当的 always 块作为计数器。

always@(posedge clk or negedge rst_n)
begin
 if(!rst_n)
  count_tx <= 4'b0000;
 else if(state == S_START)
  count_tx <= 4'b1100;
 else if(state == S_SENDING && |count_tx)
  count_tx <= count_tx - 1'd1;
end

我建议您通过 FSM 执行步骤。

  1. State1——初始化寄存器和计数器。
  2. State2 -- 执行序列化。
  3. State3 -- 设置输出标志。

推荐阅读