【问题标题】:Mips simulation using verilog , lw instruction not working right使用 verilog 进行 Mips 模拟,lw 指令无法正常工作
【发布时间】:2019-11-13 00:03:51
【问题描述】:

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

readReg1= 0 , readReg2=14 , writeSig=1 , MemRead=1 , MemWrite=0 , readData2= x , result= 2 , readData= x , writeData= x, 时钟=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

这是波浪视图: Wave View

【问题讨论】:

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

标签: verilog mips simulation system-verilog mips32


【解决方案1】:

我通过用 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-07
    • 1970-01-01
    • 1970-01-01
    • 2021-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多