我是verilog的新手,我正在尝试构建一个verilog代码,该代码模拟直接映射的缓存。在编译过程中,一切都很好,但testbench模块似乎没有执行"内存"模块(实例)。输出变量总是未知的,除了那些我在测试台中赋值的变量,甚至是我在主模块中填充了数据的RAM寄存器。你认为问题出在哪里?提前感谢这是实例模块代码:
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
这是一个模块,我写的数据,我想在一个文件中填充RAM:
module WritingToMemory;
reg[31:0]i;
integer file;
initial
begin
i=0;
file = $fopen("D:Verilog Project Data/MyMemory.txt");
$fmonitor(file,"%bn",i);
for(i=0; i<1024; i=i+1)
begin
#1
i=i;
end
end
endmodule
TestBench模块:
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
你确定你模拟了这个吗?它不会在当前状态下编译。下次你能不能把你发布的代码缩进?
回到你的问题,有三个问题:
1)你只初始化RAM, Tag和Valid数组都是x.你的硬件在真正的硅中是完全不可预测的。在使用缓存之前,必须初始化标签和有效位。现在你知道为什么了;)
2)您的测试平台实际上只生成一个事务。你写:
#10
RE = 1;
address = 0;
#10
RE=1;
address =0;
#10
RE=1;
address=0;
由于RE和地址在第一次赋值后都没有改变,因此再也不会触发always @ (RE or WE)
语句。你需要让RE回到0或者地址变更。或者,更有可能在实际缓存的行为中,引入时钟。
3) always @ (RE or WE)
也不正确,因为地址不在敏感列表中。这将导致存储器仅在频闪激活时才锁存地址,这在您的实现中可能是正确的,也可能是不正确的。这是引入时钟的另一个很好的理由