我有一個16位單週期非常稀疏的MIPS實現,我一直在Verilog中進行研究。除了分支延遲了整個時鐘週期的事實之外,一切都可以工作。在Verilog實現和同步問題中的1指令分支延遲
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
,則會解決偏移問題,除非存在真正的「泡」或硬件導致的空操作,但延遲仍然存在。
有人可以向我解釋是什麼原因導致延遲,爲什麼會發生?
邏輯規定,只要'pc'改變,'alu_zero'的'branch'的*和*爲* zero *,那麼'pc_next'必須加2。從片段中,我猜'alu_zero'或'branch'沒有正確更新。你能分享一些僞測試臺或波形嗎? – sharvil111
@ sharvil111其實我剛剛解決了這個問題!我會回答我自己的問題。 – VermillionAzure
是的,連續分配工作。 – sharvil111