Skip to content

Commit

Permalink
ice-v swirl, fixed issue when stalling on write fault in cache
Browse files Browse the repository at this point in the history
  • Loading branch information
sylefeb committed Oct 30, 2023
1 parent 5b033e5 commit d16833d
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 2 deletions.
2 changes: 1 addition & 1 deletion projects/common/qpsram2x.si
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ $$else
$$ if qpsram_fast then
16 : 6;
$$ else
16 : 7; // icebreaker, icestick <= 60 use 8, faster 7
16 : 7; // icebreaker, icestick <= 60 MHz
$$ end
$$end
after = 4;
Expand Down
33 changes: 32 additions & 1 deletion projects/ice-v/CPUs/ice-v-swirl.si
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,10 @@ $$end

always {

$$if DEBUG_swirl then
uint1 debug_on = 1;
$$end

// tracks whether a register was written cycle before
uint1 reg_was_written(0);
reg_was_written = xregsA.wenable1;
Expand All @@ -172,8 +176,10 @@ $$if ICEV_BRANCH_PRED then
uint$addrW+2$ bpred_n(0);
$$end
$$if DEBUG_swirl then
if (debug_on) {
__display("[1] cycle:%d stall_cpu:%b refetch:%b refetch_addr:%x pc:%x",cycle,stall_cpu,refetch,refetch_addr<<2,pc<<2);
__display("[1] cycle:%d imem.addr:%x imem.rdata:%x dmem.addr:%x dmem.rdata:%x",cycle,imem.addr<<2,imem.rdata,dmem.addr<<2,dmem.rdata);
}
$$end
// capture pc, instr in pipeline
pc = (exec.working | hold) ? pc : imem.addr;
Expand Down Expand Up @@ -205,13 +211,15 @@ $$else
$$end
: pc;
$$if DEBUG_swirl then
if (debug_on) {
if (~stall_cpu | on_stall) {
__display("[1] instr: %x @%x (bubble:%b reset:%b refetch:%b hold:%b stall_cpu:%b alu:%b rs1 %d rs2 %d)",
instr,pc<<2,bubble,reset,refetch,hold,stall_cpu,exec.working,xregsA.addr0,xregsB.addr0);
if (bpred) {
__display("[1] pc @%x following branch to @%x",pc<<2,imem.addr<<2);
}
}
}
$$end
// remember ALU was just busy
alu_was_working vv= exec.working;
Expand Down Expand Up @@ -262,34 +270,42 @@ $$end
// update bubble
bubble = (bubble | refetch | exec.working | hold);
$$if DEBUG_swirl then
if (debug_on) {
if (~stall_cpu | on_stall) {
__display("[2] instr: %x @%x (bubble:%b bpred:%b) rA:%x rB:%x",instr,pc<<2,bubble,bpred,xregsA.rdata0,xregsB.rdata0);
}
}
$$end
$$if DEBUG_swirl then
if (debug_on) {
if (~stall_cpu | on_stall) {
if (hold) {
__display("[2] *** data hazard (c) *** rs1[%d] rs2[%d](%b) rd(stage3)[%d]",Rtype(instr).rs1,Rtype(instr).rs2,has_rs2,exec.write_rd);
}
}
}
$$end
// [data hazards] case (a) detection
// instruction in stage 3 wrote on input registers read after stage 1
// the value is thus incorrect, use the previously written value instead
if (Rtype(instr).rs1 == xregsA.addr1 & reg_was_written) {
$$if DEBUG_swirl then
if (debug_on) {
if (~stall_cpu | on_stall) {
__display("[2] *** data hazard (a) on rs1 *** rs1[%d] rs2[%d] rd_was[%d]",Rtype(instr).rs1,Rtype(instr).rs2,xregsA.addr1);
}
}
$$end
xa_regR = 0; xa_regW = 0; xa_regW_prev = 1; xa_keep = 0;
// ^^^^^^^^^^^^^ selects value previously written
}
if (Rtype(instr).rs2 == xregsA.addr1 & reg_was_written & has_rs2) {
$$if DEBUG_swirl then
if (debug_on) {
if (~stall_cpu | on_stall) {
__display("[2] *** data hazard (a) on rs2 *** rs1[%d] rs2[%d] rd_was[%d]",Rtype(instr).rs1,Rtype(instr).rs2,xregsA.addr1);
}
}
$$end
xb_regR = 0; xb_regW = 0; xb_regW_prev = 1; xb_keep = 0; // same for rs2
}
Expand All @@ -299,17 +315,21 @@ $$end
// (checks with rd and write_rd from stage 4)
if (~no_rd & Rtype(instr).rs1 == rd) {
$$if DEBUG_swirl then
if (debug_on) {
if (~stall_cpu | on_stall) {
__display("[2] *** data hazard (b) on rs1 *** rs1[%d] rs2[%d] rd(stage4)[%d]",Rtype(instr).rs1,Rtype(instr).rs2,rd);
}
}
$$end
xa_regR = 0; xa_regW = 1; xa_regW_prev = 0; xa_keep = 0;
}
if (~no_rd & (Rtype(instr).rs2 == rd) & has_rs2) { // same for rs2
$$if DEBUG_swirl then
if (debug_on) {
if (~stall_cpu | on_stall) {
__display("[2] *** data hazard (b) on rs2 *** rs1[%d] rs2[%d] rd(stage4)[%d]",Rtype(instr).rs1,Rtype(instr).rs2,rd);
}
}
$$end
xb_regR = 0; xb_regW = 1; xb_regW_prev = 0; xb_keep = 0;
// ^^^^^^^^^^^ selects value being written
Expand All @@ -324,15 +344,18 @@ $$end
bubble = ((bubble & ~alu_was_working) | refetch | exec.working);
stage3_bubble ^= bubble;
$$if DEBUG_swirl then
if (debug_on) {
if (~stall_cpu | on_stall) {
__display("[3] instr: %x @%x (bubble:%b bpred:%b)",instr,pc<<2,bubble,bpred);
}
}
$$end
// memory address from which to load/store
$$if not ICEV_STALL then
dmem.addr = (exec.n >> 2);
$$else
dmem.addr = (exec.store|exec.load)&~bubble ? (exec.n >> 2) : dmem.addr;
dmem.addr = (exec.store|exec.load) & ~bubble & ~jumping
? (exec.n >> 2) : dmem.addr;
// ^^ if a cache is used, we preserve dmem.addr when not accessing dmem
$$end
if (exec.store & ~bubble & ~jumping) {
Expand Down Expand Up @@ -390,6 +413,7 @@ $$if ICEV_VERILATOR_TRACE then
}
$$end
$$if DEBUG_swirl then
if (debug_on) {
if (~stall_cpu | on_stall) {
__display("[4] instr: %x @%x (bubble:%b jump:%b bpred:%b load:%b) reinstr:%d",instr,pc<<2,bubble,jump,bpred,load,reinstr);
if (instr_done) {
Expand All @@ -400,6 +424,7 @@ $$if DEBUG_swirl then
if (xregsA.wenable1) {
__display("[4] wreg:[%d]=%x",Rtype(instr).rd,xregsA.wdata1);
}
}
$$end

// signal a jump if needed (flushes pipeline and jumps)
Expand All @@ -416,6 +441,7 @@ $$end
: pc; // stay on same

$$if DEBUG_swirl then
if (debug_on) {
if (~stall_cpu | on_stall) {
if (bpred & ~refetch) {
__display("[4] pc @%x branch predicted towards @%x (jump %b)",pc<<2,alu_n,jump);
Expand All @@ -424,6 +450,7 @@ $$if DEBUG_swirl then
__display("[4] REFETCH to @%x (stall_cpu %b jump %b bpred %b)",refetch_addr<<2,stall_cpu,jump,bpred);
}
}
}
$$end
}
} // end of pipeline
Expand All @@ -444,23 +471,27 @@ $$end
// ^^---------\
// capture xb from stage 2 so that stage 3 assign above sees the correct value
$$if DEBUG_swirl then
if (debug_on) {
if (dmem.wenable) {
__display("[3] store @%x = %x",dmem.addr<<2,dmem.wdata);
}
}
$$end
xb = exec.xb;
// register bank B follows A writes
xregsB.wenable1 = xregsA.wenable1;
xregsB.wdata1 = xregsA.wdata1;
xregsB.addr1 = xregsA.addr1;
$$if DEBUG_swirl then
if (debug_on) {
if (~stall_cpu) {
__display("exec.xa = %x exec.xb = %x mem.wdata = %x",exec.xa,exec.xb,dmem.wdata);
__display("exec.jump = %b exec.n = %x",exec.jump,exec.n);
__display("xa_keep %b xa_regR %b xa_regW %b xa_regW_prev %b",xa_keep,xa_regR,xa_regW,xa_regW_prev);
__display("xb_keep %b xb_regR %b xb_regW %b xb_regW_prev %b",xb_keep,xb_regR,xb_regW,xb_regW_prev);
__display("imem.addr @%x, dmem.addr @%x\n",imem.addr<<2,dmem.addr<<2);
}
}
$$end

$$if SIMULATION then
Expand Down

0 comments on commit d16833d

Please sign in to comment.