G.Moh
G.Moh

Reputation: 1

TestBench doesn't execute instance module

I'm new to verilog and I'm trying to build a verilog code that models a direct mapped cache. Every thing is working fine within the compilation process but the testbench module doesn't seem to execute the "Memory" module (instance). The output variables are always unknowns except for those that I assign values in the testbench itself, even the RAM register which I had filled up with data in the main module. What do you think seems to be the problem? Thanks in advance This is the instance module code:

module Memory (outdata,address,indata,RE,WE);
input [31:0]address;
input [31:0]indata;
output reg [31:0]outdata;
input RE,WE;
//Declared the inputs and outputs
reg[31:0]RAM[0:1023];
reg[19:0]tag[0:1023];
reg valid [0:1023];
reg [31:0]Data[0:1023];
//Defined the registers that were supposed to be modules
//Divided the cache into tag,data and valid
//Starting thr Reading Process
always @ (RE or WE)
begin
  if (RE==1)
  begin
    if (address[31:12] == tag [address[11:2]])
    begin
      if (valid[address[11:2]] ==1)
      begin
        outdata = Data[address[11:2]];
      end
      else if (valid[address[11:2]] ==0) //Read from RAM
      begin
        Data[address[11:2]] = RAM [address];
        valid[address[11:2]] =1;
        outdata = Data[address[11:2]];
      end
    end
    if (address[31:12] != tag [address[11:2]])
    begin
      Data[address[11:2]] <= RAM [address];
      tag[address[11:2]] <= address [31:12];
      valid[address[11:2]] =1;
      outdata <= Data[address[11:2]];
    end
  end
  //Starting the Writing Process
  else if (WE==1)
  begin
    if(address[31:12]==tag[address[11:2]]) //Hit
    begin
      Data[address[11:2]]<=indata;
      valid[address[11:2]] =1;
      RAM[address]<=indata;
    end
    if (address[31:12] != tag [address[11:2]])//Miss
    begin
      RAM[address]<=indata;
    end
  end
end
initial
begin 
  $readmemb("D:\Verilog Project Data/MyMemory.txt",RAM);
end
endmodule
// Filling up the RAM

This is a module where I write the data I want to fill the RAM with in a file:

module WritingToMemory;
reg[31:0]i;
integer file;
initial
begin
  i=0;
  file = $fopen("D:\Verilog Project Data/MyMemory.txt");
  $fmonitor(file,"%b\n",i);
  for(i=0; i<1024; i=i+1)
  begin
    #1
    i=i;
  end
end
endmodule

TestBench module:

module TestBench;
reg[31:0]address;
reg[31:0]indata;
reg RE;
reg WE;
wire[31:0]outdata;
initial
begin
  $monitor("address= %b, Inputputdata= %b, Outputdata= %b, Data=%b,  RAMdata=%b",
            address,indata,outdata, Data[address[11:2]],RAM[address]);
  #10
  RE = 1;
  address = 0;
  #10
  RE=1;
  address =0;
  #10
  RE=1;
  address=0;
end
Memory M1(outdata,address,indata,RE,WE);
endmodule

Upvotes: 0

Views: 707

Answers (1)

Marco
Marco

Reputation: 21

Are you sure you simulated this? It does not compile in the current state. Next time could you please indent the code you post?

Getting to your question, there are three issues:

1) You initialize only RAM, the Tag and Valid arrays are all x. Your HW would be completely unpredictable in real silicon. Before a cache can be used, the tags and valid bits must be initialized. Now you know why ;)

2) Your testbench is really generating only one transaction. You wrote:

#10
RE = 1;
address = 0;
#10
RE=1;
address =0;
#10
RE=1;
address=0;

Since neither RE nor address ever change after the first assignment, the always @ (RE or WE) statement never gets triggered again. you need to have RE go back to 0 or address change. Or, which is much more likely in the behaviour of an actual cache, introduce a clock.

3) always @ (RE or WE) is also incorrect, because address is not part of the sensitivity list. This would cause the memory to latch the address only when the strobe is activated, which might or not be correct in your implementation. That's another very good reason to introduce a clock

Upvotes: 2

Related Questions