使用verilog进行Mips模拟,lw指令工作不正常

使用verilog进行Mips模拟,lw指令工作不正常,verilog,mips,simulation,system-verilog,mips32,Verilog,Mips,Simulation,System Verilog,Mips32,我在一个时钟周期内使用verilog模拟32位mips,所有指令都在一个周期内正常工作,但lw指令不会在同一个周期内读取内存内容,而是在下一个周期读取!! 以下是数据存储模块代码: module dataMemory (address, writeData, MemWrite, MemRead, clock, readData); input address, writeData, MemWrite, MemRead, clock; output readData; wire [31:0] a

我在一个时钟周期内使用verilog模拟32位mips,所有指令都在一个周期内正常工作,但lw指令不会在同一个周期内读取内存内容,而是在下一个周期读取!! 以下是数据存储模块代码:

module dataMemory (address, writeData, MemWrite, MemRead, clock, readData);

input address, writeData, MemWrite, MemRead, clock;
output readData;
wire [31:0] address, writeData;
wire MemWrite, MemRead, clock;
reg  [31:0] DM [0:32767], readData;

initial
begin
DM[2]=10;
end

always @ (posedge clock)
begin

if(MemWrite)
begin
DM[address]=writeData;
end

if(MemRead)
begin
readData=DM[address];
end

end


endmodule
module instMemory(address, clock, inst);

input address, clock;
output inst;
wire [31:0] address;
wire clock;
reg [31:0] IM [0:32767], inst;

initial
begin
//IM[0]=32'b00000001000010010110000000100000;
//IM[1]=32'b10001100000011010000000000000010;
//IM[2]=32'b00000001100011010111000000100000;
//IM[3]=32'b10101100000011100000000000000010;
IM[0]=32'b10001100000011100000000000000010; //lw t6 0x0002(zero) *** DM[2]=10***
end

always @ (posedge clock)
begin
inst<=IM[address];
end

endmodule
以下是指令内存模块代码:

module dataMemory (address, writeData, MemWrite, MemRead, clock, readData);

input address, writeData, MemWrite, MemRead, clock;
output readData;
wire [31:0] address, writeData;
wire MemWrite, MemRead, clock;
reg  [31:0] DM [0:32767], readData;

initial
begin
DM[2]=10;
end

always @ (posedge clock)
begin

if(MemWrite)
begin
DM[address]=writeData;
end

if(MemRead)
begin
readData=DM[address];
end

end


endmodule
module instMemory(address, clock, inst);

input address, clock;
output inst;
wire [31:0] address;
wire clock;
reg [31:0] IM [0:32767], inst;

initial
begin
//IM[0]=32'b00000001000010010110000000100000;
//IM[1]=32'b10001100000011010000000000000010;
//IM[2]=32'b00000001100011010111000000100000;
//IM[3]=32'b10101100000011100000000000000010;
IM[0]=32'b10001100000011100000000000000010; //lw t6 0x0002(zero) *** DM[2]=10***
end

always @ (posedge clock)
begin
inst<=IM[address];
end

endmodule
$monitor的输出为:

readReg1=x,readReg2=x,writeSig=x,MemRead=x,MemWrite=x,readData2=x,result=x,readData=x,writeData=x,clock=0 readReg1=x,readReg2=x,writeSig=x,MemRead=x,MemWrite=x,readData2=x,result=x,readData=x,writeData=x,clock=1 readReg1=x,readReg2=x,writeSig=x,MemRead=x,MemWrite=x,readData2=x,result=x,readData=x,writeData=x,clock=0 readReg1=0,readReg2=14,writeSig=1,MemRead=1,MemWrite=0,readData2=x,result=2,readData=x,writeData=x,clock=1 readReg1=0,readReg2=14,writeSig=1,MemRead=1,MemWrite=0,readData2=x,result=2,readData=x,writeData=x,clock=0 readReg1=x,readReg2=x,writeSig=1,MemRead=1,MemWrite=0,readData2=x,result=x,readData=10,writeData=10,clock=1 readReg1=x,readReg2=x,writeSig=1,MemRead=1,MemWrite=0,readData2=x,result=x,readData=10,writeData=10,clock=0 以下是波浪图:

我解决了这个问题,将MemRead的if语句替换为always块外的assign语句,比如:assign readData=(MemRead==1)?DM[地址]:0;我还将readData form reg更改为wire

数据存储模块变为:

module dataMemory (address, writeData, MemWrite, MemRead, clock, readData);

input address, writeData, MemWrite, MemRead, clock;
output readData;
wire [31:0] address, writeData,readData;
wire MemWrite, MemRead, clock;
reg  [31:0] DM [0:32767];


initial
begin
DM[2]=10;
end

always @ (posedge clock)
begin

if(MemWrite)
begin
DM[address]<=writeData;
end



end
assign readData = (MemRead==1) ? DM[address]:0;


endmodule
模块数据存储器(地址、写入数据、MemWrite、MemRead、时钟、readData);
输入地址、写入数据、MemWrite、MemRead、时钟;
输出读取数据;
导线[31:0]地址、写入数据、读取数据;
线MemWrite、MemRead、时钟;
reg[31:0]DM[0:32767];
最初的
开始
DM[2]=10;
结束
始终@(posedge时钟)
开始
if(MemWrite)
开始

DM[address]我厌倦了,但是,同样的问题非阻塞分配不会有什么不同。一个可能的解决方案是添加一个
wait
状态,在该状态下,所有内容都停止,等待模块完成其工作,然后在下一个时钟中,让所有内容恢复工作。内存操作通常需要超过1个周期才能执行。那么我的代码中有什么问题???Sw inst和其他模块运行良好。可能Sw
不关心其他模块。当您运行
sw
时,可能需要超过1个周期才能运行,但由于您只是在保存,其他模块并不关心它。当您加载时,情况就不同了,因为您需要等待内存结束其工作并将结果提供给寄存器。这在
sw
中是不应该出现的,这就是为什么它不是一个问题,当内存正在循环保存时,其他模块仍然在工作。