output reg write_reg = 1'bx,
output reg [3:0] write_num = 4'bxxxx,
output reg [31:0] write_data = 32'hxxxxxxxx,
- output reg [31:0] outpc,
- output reg outflush
+ output reg [31:0] jmppc,
+ output reg jmp
);
reg mult_start;
reg [31:0] next_outcpsr, next_outspsr;
reg next_write_reg;
reg [3:0] next_write_num;
+
reg [31:0] next_write_data;
-
+
Multiplier multiplier(
.clk(clk), .Nrst(Nrst),
.start(mult_start), .acc0(mult_acc0), .in0(mult_in0),
always @(*)
begin
outstall = stall;
- next_outbubble = inbubble;
+ next_outbubble = inbubble | flush;
next_outcpsr = cpsr;
next_outspsr = spsr;
next_write_reg = 0;
next_write_num = 4'hx;
next_write_data = 32'hxxxxxxxx;
-
+
mult_start = 0;
mult_acc0 = 32'hxxxxxxxx;
mult_in0 = 32'hxxxxxxxx;
mult_in1 = 32'hxxxxxxxx;
-
+
alu_in0 = 32'hxxxxxxxx;
alu_in1 = 32'hxxxxxxxx;
alu_op = 4'hx; /* hax! */
alu_setflags = 1'bx;
-
+
+ jmp = 1'b0;
+ jmppc = 32'hxxxxxxxx;
+
casez (insn)
`DECODE_ALU_MULT: /* Multiply -- must come before ALU, because it pattern matches a specific case of ALU */
begin
begin end
`DECODE_BRANCH:
begin
- outpc = pc + op0;
+ jmppc = pc + op0 + 32'h8;
if(insn[24]) begin
next_write_reg = 1;
next_write_num = 4'hE; /* link register */
next_write_data = pc + 32'h4;
end
+ jmp = 1'b1;
end /* Branch */
`DECODE_LDCSTC, /* Coprocessor data transfer */
`DECODE_CDP, /* Coprocessor data op */
begin
if (waiting)
$display("ISSUE: Stalling instruction %08x because %d/%d", insn, waiting_cpsr, waiting_regs);
-
- if (!stall)
+
+ if(flush)
+ begin
+ cpsr_inflight[0] = 1'b0;
+ cpsr_inflight[1] = 1'b0;
+ regs_inflight[0] = 16'b0;
+ regs_inflight[1] = 16'b0;
+ end
+ else if (!stall)
begin
cpsr_inflight[0] <= cpsr_inflight[1]; /* I'm not sure how well selects work with arrays, and that seems like a dumb thing to get anusulated by. */
cpsr_inflight[1] <= (waiting || inbubble || !condition_met) ? 0 : def_cpsr;
regs_inflight[0] <= regs_inflight[1];
regs_inflight[1] <= (waiting || inbubble || !condition_met) ? 0 : def_regs;
- outbubble <= inbubble | waiting | !condition_met;
+ outbubble <= inbubble | waiting | !condition_met | flush;
outpc <= inpc;
outinsn <= insn;
end
assign bus_rd = bus_rd_icache;
assign bus_wr = bus_wr_icache;
assign bus_ready = bus_ready_blockram;
-
+
wire [31:0] icache_rd_addr;
wire icache_rd_req;
wire icache_rd_wait;
wire execute_out_write_reg;
wire [3:0] execute_out_write_num;
wire [31:0] execute_out_write_data;
+ wire [31:0] jmppc;
+ wire jmp;
wire bubble_out_fetch;
wire bubble_out_issue;
wire [31:0] insn_out_issue;
wire [31:0] pc_out_fetch;
wire [31:0] pc_out_issue;
-
+
BusArbiter busarbiter(.bus_req(bus_req), .bus_ack(bus_ack));
ICache icache(
.Nrst(1'b1 /* XXX */),
.rd_addr(icache_rd_addr), .rd_req(icache_rd_req),
.rd_wait(icache_rd_wait), .rd_data(icache_rd_data),
- .stall(stall_cause_issue), .jmp(1'b0 /* XXX */), .jmppc(32'b0 /* XXX */),
+ .stall(stall_cause_issue), .jmp(jmp), .jmppc(jmppc),
.bubble(bubble_out_fetch), .insn(insn_out_fetch),
.pc(pc_out_fetch));
.op2(decode_out_op2), .carry(decode_out_carry),
.outstall(stall_cause_execute), .outbubble(execute_out_bubble),
.write_reg(execute_out_write_reg), .write_num(execute_out_write_num),
- .write_data(execute_out_write_data));
-
+ .write_data(execute_out_write_data),
+ .jmppc(jmppc),
+ .jmp(jmp));
+
reg [31:0] clockno = 0;
always @(posedge clk)
begin