verilogsystem-verilog

RAM array displays 'XXXXX'


Purpose: Input 128 data, store them in RAM, and output them to dout after collecting 128 data.

di is an input variable. RAM is used to store 128 data. When RAM collects 128 numbers, dout will write these 128 numbers. ram_cnt is the index of the RAM, but currently ram_cnt shows 0, dout and RAM show XXXXX. I don't know what is wrong.

Waveform

Here's my code

module Data_buffer (
  input clk,
  input rst,
  input we,
  input en,
  input [7:0] di,
  output reg [1023:0] dout,
  output reg [6:0] ram_cnt
);

  reg [7:0] RAM [0:127];
  integer i;

  always @(posedge clk) begin
    if (rst) begin
      ram_cnt <= 7'd0;
    end

    else if (en && we ) begin
      if ( ram_cnt <= 7'd127 ) begin
         for (i = 0; i < 128; i = i + 1) begin
            dout[(127 - i)*8 +: 8] = RAM[i];
         end
         
         ram_cnt <= 0;
      end
      else begin
        RAM[ram_cnt] <= di;
        ram_cnt <= ram_cnt + 1;
      end
    end
  end

endmodule

Solution

  • but currently ram_cnt shows 0

    At the start of simulation, I assume you set rst to 1 to synchronously reset the logic. This sets ram_cnt to 0. It remains 0 for the rest of the simulation because you have a bug in your Verilog code. The following else code is unreachable:

      else begin
        RAM[ram_cnt] <= di;
        ram_cnt <= ram_cnt + 1;
      end
    

    Here is a simplified version of the code that just involves ram_cnt:

    always @(posedge clk) begin
        if (rst) begin
            ram_cnt <= 7'd0;
        end else if (en && we ) begin
            if (ram_cnt <= 7'd127) begin
                ram_cnt <= 0;
            end else begin
                ram_cnt <= ram_cnt + 1;
            end
        end
    end
    

    After reset is released and you enable for writing, the following condition is always true:

        if (ram_cnt <= 7'd127) begin
    

    This keeps ram_cnt at 0, and the else clause is never executed. You never increment the count. You need to change your logic.

    For a similar reason RAM remains unknown (x). The only place in the code that you assign to RAM is in the unreachable else clause.

    This code shows ram_cnt incrementing, for example:

    always @(posedge clk) begin
        if (rst) begin
            ram_cnt <= 7'd0;
        end else if (en && we ) begin
            if (ram_cnt <= 7'd127) begin
                ram_cnt <= ram_cnt + 1;
            end else begin
                ram_cnt <= 0;
            end
        end
    end
    

    It might not be exactly what you need, but it demonstrates the principal.

    Note that since you declared ram_cnt as 7 bits wide, it can only take on values 0 to 127. Therefore, (ram_cnt <= 7'd127) will always be true.