Search code examples
verilogvivado

Register file not reading any data


I am trying to design a state machine that counts through and replaces values between 47 and 58. In my waveform though, I keep getting XXX for my R_data in the register file, and thus the rest of my top level design is thrown off. I can't seem to find a reason as to why R_data is outputting XXX for any address with R_en = 1. I'm on Vivado 2020.2; thank you for any help, and please let me know if I need to clarify anything.

Register:

`timescale 1ns / 1ps
module RegFile16x8(R_Addr, W_Addr, R_en, W_en, R_Data, W_Data, Clk, Rst);   
input [3:0] R_Addr, W_Addr;
input Clk, Rst, R_en, W_en;
output reg [7:0] R_Data;
input [7:0] W_Data;
reg [7:0] RegFile [0:15];

always @(posedge Clk) begin
  if (Rst == 1) begin
      RegFile[0] <= 8'd48;
      RegFile[1] <= 8'd53;
      RegFile[2] <= 8'd68;
      RegFile[3] <= 8'd57;
      RegFile[4] <= 8'd55;
      RegFile[5] <= 8'd59;
      RegFile[6] <= 8'd40;
      RegFile[7] <= 8'd49;
      RegFile[8] <= 8'd31;
      RegFile[9] <= 8'd38;
      RegFile[10] <= 8'd54;
      RegFile[11] <= 8'd50;
      RegFile[12] <= 8'd63;
      RegFile[13] <= 8'd58;
      RegFile[14] <= 8'd70;
      RegFile[15] <= 8'd51;
   end
   else if (W_en==1) begin
        RegFile[W_Addr] <= W_Data;
   end
 end

 always @(*) begin
  if (R_en==1)
     R_Data <= RegFile[R_Addr];
  else
     R_Data <= 8'bZZZZZZZZ;
end
endmodule

Top Level:

`timescale 1ns / 1ps


module PartA(Clk, Rst, go, done, count);
input Clk, Rst, go;
output reg [6:0] count;
output reg done;
reg [2:0] State, StateNext;
parameter s1 = 0, s2 = 1, s3 = 2, s4 = 3, s5 = 4, s6 = 5, s7 = 6, s8 = 7;

reg [4:0] i; 
reg [7:0] temp;
reg R_en, W_en;
reg [7 :0] a_i;
wire [7:0] a_o;
//RegFile16x8(R_Addr, W_Addr, R_en, W_en, R_Data, W_Data, Clk, Rst);   
RegFile16x8 r1(i[3:0], i[3:0], R_en, W_en, a_o, a_i, Clk, Rst);

always @(State, Rst, count) begin
    R_en = 0;
    W_en = 0;
    case(State)
        s1: begin
            if(go == 1)
                StateNext = s2;
            else
                StateNext = s1;
        end
        s2: begin
            done = 0;
            count = 0;
            i = 0; 
            StateNext = s3;
        end
        s3: begin
            if(i < 16)
                StateNext = s4;
            else    
                StateNext = s5;
        end
        s4: begin
            R_en = 1;
            temp = a_o;
            if ((temp > 47) && (temp < 58))
                StateNext = s7;
            else
                StateNext = s6;
        end
        s5: begin
            done = 1;
            StateNext = s1;
        end
        s6: begin
            StateNext = s8;
        end
        s7: begin
            W_en = 1;
            count = count + 1;
            a_i = temp - 48;
            StateNext = s8;
        end
        s8: begin
            i = i + 1;
            StateNext = s3;
        end
        default: begin
            StateNext = s1;
        end
    endcase
end
always @(posedge Clk) begin
    if (Rst == 1) 
        State = s1;
    else
        State = StateNext;
 end
endmodule

Test Bench:

`timescale 1ns / 1ps

module partA_tb();

reg Clk, Rst, go;
wire [6:0] count;
wire done;

PartA a1(Clk, Rst, go, done, count);

 always begin 
    Clk = 0;
    #200
    Clk = 1;
    #200;
 end
 initial begin
    Rst = 1;
    #200
    Rst = 0;
    go = 1;
 end

endmodule

Solution

  • You need to keep Rst in the testbench high for a longer amount of time. The 1st posedge of Clk happens at time 200ns, and that is when you release the reset. You need to keep the reset asserted until after the 1st posedge of the clock in order to properly reset your RegFile, since it is a synchronous reset.

    This testbench change allows RegFile to be reset to known values:

     initial begin
        Rst = 1;
        #400
        Rst = 0;
        go = 1;
     end
    

    The change above removes the XXX from R_data.

    I chose an arbitrary delay of 400, but it can be anything greater than 200. The key is that you need at least one posedge of Clk to sample Rst when it is high.