Verilog で作業してきた 16 ビット シングル サイクルの非常にまばらな MIPS 実装があります。分岐が 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 ビット レジスタです。
なぜこの回路に問題があるのか わかりませんが、何らかの理由で、回路全体が分岐するまで 1 クロック サイクル遅延します (たとえば、0x16 に常にジャンプする BEQ 命令がある場合、それは実行されます)。 0x18 で次の命令を実行し、0x20 から相対オフセットにジャンプします)。
解決策が目の前にあるような気がしますが、セマンティックについて何が欠けているのかわかりません。+2
真の「バブル」またはハードウェアによるノーオペレーションがない限り、常に暗黙的な を削除すると、オフセットの問題は解決しますが、遅延は依然として存在します。
誰かが遅延の原因とその理由を説明できますか?