【发布时间】: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