我有一个 16 位单周期、非常稀疏的 MIPS 实现,我一直在 Verilog 中工作。除了分支延迟一个完整的时钟周期之外,一切正常。
always @(posedge clock) begin
// Necessary to add this in order to ensure PC => PC_next
iaddr <= pc_next
end
上面的代码用于更新程序计数器/指令地址,它来自一个模块,PCLogic:
module PCLogic(
pc_next, // next value of the pc
pc, // current pc value
signext, // from sign extend circuit
branch, // beq instruction
alu_zero, // zero from ALU, used in cond branch
reset // reset input
);
output [15:0] pc_next;
input [15:0] pc;
input [15:0] signext; // From sign extend circuit
input branch;
input alu_zero;
input reset;
reg [15:0] pc_next;
always @(pc or reset) begin
if (reset == 1)
pc_next = 0;
else if (branch == 1 && alu_zero == 1)
pc_next = pc+2+(signext << 1);
else
pc_next = pc+2;
end
endmodule
iaddr
是一个简单的 16 位寄存器,用于存储程序计数器。
我不明白为什么这个电路可能有问题,但由于某种原因,整个电路延迟了一个时钟周期,直到它分支(例如,如果我在 0x16 处有一条 BEQ 指令总是跳转,它将执行0x18 处的下一条指令,然后跳转到相对偏移量,但从 0x20 开始)。
我几乎可以感觉到解决方案就在我面前,但我不知道我在语义上缺少什么。如果我删除总是隐含的偏移量问题+2
,除非存在真正的“气泡”或硬件引起的无操作,但延迟仍然存在。
有人可以向我解释导致延迟的原因以及发生的原因吗?