input stall,
input jmp,
input [31:0] jmppc,
- output wire bubble,
- output wire [31:0] insn,
- output reg [31:0] pc);
-
- reg [31:0] prevpc;
- initial
- prevpc = 32'hFFFFFFFC; /* ugh... the first pc we request will be this +4 */
- always @(negedge Nrst)
- prevpc <= 32'hFFFFFFFC;
+ output reg bubble = 1,
+ output reg [31:0] insn = 0,
+ output reg [31:0] pc = 32'hFFFFFFFC);
+
+ reg qjmp = 0; /* A jump has been queued up while we were waiting. */
+ reg [31:0] qjmppc;
+ always @(posedge clk)
+ if ((rd_wait || stall) && jmp && !qjmp)
+ {qjmp,qjmppc} <= {jmp, jmppc};
+ else if (!rd_wait && !stall && qjmp) /* It has already been intoed. */
+ {qjmp,qjmppc} <= {1'b0, 32'hxxxxxxxx};
+ reg [31:0] reqpc;
always @(*)
- if (!Nrst)
- pc = 32'hFFFFFFFC;
- else if (stall) /* don't change any internal state */
- pc = prevpc;
+ if (stall)
+ reqpc = pc;
+ else if (qjmp)
+ reqpc = qjmppc;
else if (jmp)
- pc = jmppc;
+ reqpc = jmppc;
else
- pc = prevpc + 32'h4;
+ reqpc = pc + 4;
+
+ assign rd_addr = reqpc;
+ assign rd_req = 1;
+
+ always @(negedge Nrst)
+ begin
+ pc <= 32'hFFFFFFFC;
+ qjmp <= 0;
+ bubble <= 1;
+ end
- assign bubble = stall | rd_wait;
- assign rd_addr = pc;
- assign rd_req = !stall;
- assign insn = rd_data;
-
always @(posedge clk)
- if (!rd_wait || !Nrst)
- prevpc <= pc;
+ begin
+ if (!Nrst) begin
+ pc <= 32'hFFFFFFFC;
+ qjmp <= 0;
+ bubble <= 1;
+ end else if (!stall)
+ begin
+ bubble <= rd_wait;
+ insn <= rd_data;
+ if (!rd_wait)
+ pc <= reqpc;
+ end
+ end
endmodule