使用verilog的Mips模拟,lw指令无法正常工作



我在一个时钟周期内使用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 final_tb();
reg [31:0] PC;
wire clock, writeSig,RegDst,Jump,Branch,MemRead,MemToReg,MemWrite,ALUSrc;
wire [1:0] ALUOp;
wire [3:0] aluCtl_out;
wire [4:0] writeReg;
wire [31:0] inst,readData1,readData2,in_2, result, writeData,out,readData,address ;
always @ (clock)
begin
$monitor("readReg1=%d , readReg2=%d , writeSig=%b , MemRead=%b , MemWrite=%b , readData2=%d , result=%d , readData=%d ,  writeData=%d,  clock=%b",inst[25:21]
,inst[20:16],writeSig,MemRead,MemWrite,readData2,result,readData,writeData,clock);
end
clock clk(.clk(clock));
PC pc(.in(0),.clock(clock),.out(address));
instMemory im(.address(address), .clock(clock), .inst(inst));
regFile rf(.readReg1(inst[25:21]), .readReg2(inst[20:16]), .writeReg(writeReg), .writeData(writeData), .writeSig(writeSig), .clock(clock), 
.readData1(readData1), .readData2(readData2));
ctrlUnit CU(.OPCode(inst[31:26]), .RegDst(RegDst), .Jump(Jump), .Branch(Branch), .MemRead(MemRead), .MemToReg(MemToReg), .ALUOp(ALUOp), 
.MemWrite(MemWrite), .ALUSrc(ALUSrc), .RegWrite(writeSig));
aluCtl AC(.in_func(inst[5:0]), .in_ALUOp(ALUOp), .aluCtl_out(aluCtl_out));
ALU alu(.in_1(readData1), .in_2(in_2), .aluCtl(aluCtl_out), .zeroSig(zeroSig), .sltSig(sltSig), .result(result));
dataMemory dm(.address(result), .writeData(readData2), .MemWrite(MemWrite), .MemRead(MemRead), .clock(clock), .readData(readData));
signExtend SE(.in(inst[15:0]), .out(out));
mux1 mux1(.A(inst[20:16]), .B(inst[15:11]), .sel(RegDst), .out(writeReg));
mux2 mux2(.A(readData2), .B(out), .sel(ALUSrc), .out(in_2));
mux3 mux3(.A(result), .B(readData), .sel(MemToReg), .out(writeData));
endmodule

$monitor的输出为:

readReg1=x,readReg2=x,writeSig=x,MemRead=x,MemoWrite=x,readData2=x,result=x,读取数据=x,写入数据=x、时钟=0

readReg1=x,readReg2=x,writeSig=x,MemRead=x,MemoWrite=x,readData2=x,result=x,读取数据=x,写入数据=x、时钟=1

readReg1=x,readReg2=x,writeSig=x,MemRead=x,MemoWrite=x,readData2=x,result=x,读取数据=x,写入数据=x、时钟=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语句替换为始终块外的assign语句来解决这个问题,比如:assign readData=(MemRead==1(?DM[地址]:0;我还将readData表单reg更改为有线

dataMemory模块变为:

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

最新更新