使用verilog进行仿真,lw指令无法正常工作

问题描述 投票:0回答:1

我在单个时钟周期内使用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,MemWrite = x,readData2 = x,result = x,readData = x,writeData = x,时钟= 0

readReg1 = x,readReg2 = x,writeSig = x,MemRead = x,MemWrite = x,readData2 = x,result = x,readData = x,writeData = x,时钟= 1

readReg1 = x,readReg2 = x,writeSig = x,MemRead = x,MemWrite = x,readData2 = x,result = x,readData = x,writeData = x,时钟= 0

readReg1 = 0,readReg2 = 14,writeSig = 1,MemRead = 1,MemWrite = 0,readData2 = x,结果= 2,readData = x,writeData = x,时钟= 1

readReg1 = 0,readReg2 = 14,writeSig = 1,MemRead = 1,MemWrite = 0,readData2 = x,结果= 2,readData = x,writeData = x,时钟= 0

readReg1 = x,readReg2 = x,writeSig = 1,MemRead = 1,MemWrite = 0,readData2 = x,结果= x,readData = 10,writeData = 10,时钟= 1

readReg1 = x,readReg2 = x,writeSig = 1,MemRead = 1,MemWrite = 0,readData2 = x,结果= x,readData = 10,writeData = 10,时钟= 0

这是wave视图:Wave View

verilog mips simulation system-verilog mips32
1个回答
0
投票

我通过在always块之外用assign语句替换MemRead的if语句来解决它,例如:assign readData =(MemRead == 1)? DM [地址]:0;而且我也将readData形式的reg更改为wire

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
© www.soinside.com 2019 - 2024. All rights reserved.