0

Having a bit of trouble with looping through a 1D reg array.

ultimately I am trying to accomplish the following.

  1. in "Listen" state, the rx_values fill a read buffer (4 8-bit characters) to store the characters being typed in a console and echo back the character by setting tx_data to the last character (this works)

  2. when the enter key is hit, the state switches to "Read" which sets the tx_data to the readbuffer with each iteration until the 4th character is reached at which time the state is reset to idle. (this doesnt work)

I get to the read state;however,the counter does not work as expected.

any help would be greatly appreciated.

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
Equinox86
  • 11
  • 3

2 Answers2

1

Sorry to use "answer" feature instead of comment but I don't have enough points yet. This is intended as a "comment". Since you wanted any help I hope this fits.

1) Your code needs some improvement both in functionality and readability (empty combo blocks, mixing BA with NBA -> mixing combo with sequential logic, reset input but no reset logic, commented logic lines, latches on FSM).

Consider rewriting it according to some good coding practices, e.g. http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf

You also have inconsistencies like buffdex = buffdex + 1' and buffdex = buffdex + 1. (And thus doesn't compile on incisive).

2) Can you provide a testbench for this module? Have you tried strobing signals to check their values? Does buffdex increment in read state? Is the if statement reachable?

3) Since this isn't a 1st problem with Mojo (seems like under developement) you may consider free https://www.edaplayground.com/ for both testing and compiling/syntax checking.

RaZ
  • 364
  • 1
  • 5
  • 17
  • Thanks for the feedback! yes I am very green at coding in Verilog. I can clean up the code for sure, do you think any of these will impact functionality? buffdex + 1' is a typo . both should be buffdex+1, which produces the same result unfortunately.I haven't done a test bench on this (or ever) , so I will give that a shot and see what I can determine from the signals. I will take a look at EDA playground as well. In the meantime, aside from the buffdex+1' typo and sloppy code, shouldnt this provide the result of storing the characters in the readbuffer and displaying them in read state? – Equinox86 Oct 11 '17 at 13:32
  • @Equinox86 , read the sunburst-design paper. Your functional issue is related to the misuse of BA and NBA. – Greg Oct 11 '17 at 15:01
0

So I read the paper (along with other various IEEE instructions) and finally got a working version. below is the code. as before I am open the suggestions as to how the code can be made more efficient or functional. I think the read buffer is one big latch, but not sure how to fix it.

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
Equinox86
  • 11
  • 3