首页 文章

Verilog Reg数组

提问于
浏览
0

循环访问1D reg数组会遇到一些麻烦 .

最终我试图完成以下任务 .

  • 在“监听”状态下,rx_values填充一个读缓冲区(4个8位字符),用于存储在控制台中输入的字符,并通过将tx_data设置为最后一个字符来回显字符(这有效)

  • 当按下回车键时,状态切换到“读取”,每次迭代将tx_data设置为读缓冲,直到达到第4个字符,此时状态被重置为空闲 . (这不起作用)

我进入读状态;但是,计数器不能按预期工作 .

任何帮助将不胜感激 .

module receiver (
input clk,
input rst,
output reg [7:0] tx_data,
output reg new_tx_data,
input tx_busy,
input [7:0] rx_data,
input new_rx_data
);
localparam idle = 4'h0 ,listen = 4'h1 ,read = 4'h2, write = 4'h3; 
reg [3:0] state = idle;
reg [7:0] readbuff[3:0];
integer buffdex;

always @* begin
end


always @(posedge clk) begin
new_tx_data = 1'b0;

case (state) 
  idle: begin 
    if(new_rx_data) begin
      state<=listen;
    end
  end
  listen: begin
    new_tx_data = 1'b1;
    readbuff[buffdex] = rx_data;
    tx_data = readbuff[buffdex];
    //tx_data = buffdex;
    buffdex = buffdex + 1';
    if(rx_data == 8'h0D) begin
      tx_data = "\n";
      buffdex = 0;
      state <= read;
    end else begin
      state<=idle;
    end
  end
  read: begin
    new_tx_data = 1'b1;
    tx_data = readbuff[buffdex];
    buffdex = buffdex + 1;
    if (buffdex == 3) begin
      state <= idle;
    end
    //tx_data = state;
  end

endcase
end

endmodule

2 回答

  • 1

    很抱歉使用"answer"功能而不是评论,但我还没有足够的分数 . 这是"comment" . 既然你想 any help 我希望这适合 .

    1)你的代码在功能和可读性方面都需要一些改进(空组合块,BA与NBA混合 - >混合组合与顺序逻辑,复位输入但没有复位逻辑,注释逻辑线,FSM上的锁存器) .

    考虑根据一些好的编码实践重写它,例如http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf

    你也有像 buffdex = buffdex + 1'buffdex = buffdex + 1 这样的不一致 . (因此不会精辟的编译) .

    2)您能为该模块提供测试平台吗?您是否尝试过频闪信号来检查它们的值? readread 状态下是否增加? if 语句是否可以访问?

    3)由于这不是Mojo的第一个问题(似乎正在开发中),您可以考虑免费https://www.edaplayground.com/进行测试和编译/语法检查 .

  • 0

    所以我读了这篇论文(以及其他各种IEEE指令),最后得到了一个工作版本 . 下面是代码 . 和以前一样,我打开了关于如何使代码更高效或更有效的建议 . 我认为读取缓冲区是一个很大的锁存器,但不知道如何解决它 .

    module receiver (
        //inputs
        input clk,
        input rst,
        input tx_busy,
        input [7:0] rx_data,
        input new_rx_data,
        //outputs
        output reg [7:0] tx_data,
        output reg new_tx_data,
        output reg [0:4] LED
        );
    
    
        //local parameters
        localparam IDLE = 2'b00 , LISTEN = 2'b01 ,NEWLINE = 2'b10, READ = 2'b11;
    
    
        //fsm state reg and readbuff reg
        reg [1:0] stated, stateq;
        reg [3:0] cntrd,cntrq;
        reg [7:0] readbuff [15:0];
        reg nl;
    
        //on clock edge set flip-flop  - non-blocking assignments
        always @(posedge clk ) begin
          if(rst) begin
            stateq <= IDLE; 
            cntrq<=4'b0000;
          end else begin
           //update the state and readbuff index values to be current.
           stateq <= stated;
           cntrq <=cntrd;
          end
        end
    
        //sequential and combinational blocking assignments
        always @(*) begin
          //set default states to avoid latches.
          stated = stateq;
          cntrd = cntrq; 
          LED = cntrq;
          //set output defaults
          tx_data = 8'hxx;
          new_tx_data = 1'b0;
    
          case (stateq) 
            IDLE: begin
              //move to listen state
              cntrd=4'b0;
              stated = stateq + 1'b1;
            end
            LISTEN: begin
              if(new_rx_data) begin
                //set readbuffer[indx] to the rx data
                readbuff[cntrq] = rx_data;
                new_tx_data = 1'b1;
                tx_data = readbuff[cntrq];
                cntrd = cntrq + 1'b1;
                //if enter is pressed change states, otherwise, echo and increase the read buffer.
                if(rx_data == "\r" || rx_data == "\n") begin
                  stated = stateq + 1'b1;
                  cntrd=4'b0000;
                end
              end
            end
            NEWLINE: begin  
            if(!tx_busy) begin
                   new_tx_data = 1'b1;
                   tx_data = 8'h0A;
                   nl = 1'b1;
                   stated = stateq + 1'b1;
                 end
            end
            READ: begin
              //check the value of cntrq for the enter statement 
              if(readbuff[cntrq] == "\r" || readbuff[cntrq] == "\n" ) begin
                 stated = IDLE;
              //otherwise write out the value of the readbuff - tx busy should sync to avr clock
              end else begin    
                if (!tx_busy) begin
                  new_tx_data = 1'b1;
                  tx_data = readbuff[cntrq];
                  cntrd = cntrq + 1'b1;
                end  
              end
            end    
          endcase
        end
        endmodule
    

相关问题