moved exception handling from ex stage in dpath to mem stage in ctrl
This commit is contained in:
@ -33,17 +33,11 @@ class ioCtrlDpath extends Bundle()
|
||||
val sel_wb = UFix(3, 'output);
|
||||
val ren_pcr = Bool('output);
|
||||
val wen_pcr = Bool('output);
|
||||
// FIXME: move exception handling stuff (generating cause value, etc)
|
||||
// from EX stage of dpath to MEM stage of control
|
||||
val xcpt_illegal = Bool('output);
|
||||
val xcpt_privileged = Bool('output);
|
||||
val xcpt_fpu = Bool('output);
|
||||
val xcpt_syscall = Bool('output);
|
||||
// val xcpt_dtlb = Bool('output);
|
||||
val xcpt_itlb = Bool('output);
|
||||
val exception = Bool('output);
|
||||
val cause = UFix(5,'output);
|
||||
val eret = Bool('output);
|
||||
val mem_load = Bool('output);
|
||||
val wen = Bool('output);
|
||||
val wen = Bool('output);
|
||||
// inputs from datapath
|
||||
val btb_hit = Bool('input);
|
||||
val inst = Bits(32, 'input);
|
||||
@ -53,10 +47,9 @@ class ioCtrlDpath extends Bundle()
|
||||
val div_rdy = Bool('input);
|
||||
val div_result_val = Bool('input);
|
||||
val mul_result_val = Bool('input);
|
||||
val ex_waddr = UFix(5,'input); // write addr from execute stage
|
||||
val ex_waddr = UFix(5,'input); // write addr from execute stage
|
||||
val mem_waddr = UFix(5,'input); // write addr from memory stage
|
||||
val wb_waddr = UFix(5,'input); // write addr from writeback stage
|
||||
val exception = Bool('input);
|
||||
val wb_waddr = UFix(5,'input); // write addr from writeback stage
|
||||
val status = Bits(17, 'input);
|
||||
val sboard_clr0 = Bool('input);
|
||||
val sboard_clr0a = UFix(5, 'input);
|
||||
@ -71,8 +64,10 @@ class ioCtrlAll extends Bundle()
|
||||
val imem = new ioImem(List("req_val", "req_rdy", "resp_val")).flip();
|
||||
val dmem = new ioDmem(List("req_val", "req_rdy", "req_cmd", "req_type", "resp_miss")).flip();
|
||||
val host = new ioHost(List("start"));
|
||||
val dtlb_xcpt = Bool('input);
|
||||
val itlb_xcpt = Bool('input);
|
||||
val dtlb_miss = Bool('input);
|
||||
val xcpt_dtlb_ld = Bool('input);
|
||||
val xcpt_dtlb_st = Bool('input);
|
||||
val xcpt_itlb = Bool('input);
|
||||
}
|
||||
|
||||
class rocketCtrl extends Component
|
||||
@ -97,6 +92,7 @@ class rocketCtrl extends Component
|
||||
JALR_C-> List(Y, BR_JR, REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_ADD, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_Y,WA_RD,WB_PC, REN_N,WEN_N,N,N,N,N),
|
||||
JALR_J-> List(Y, BR_JR, REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_ADD, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_Y,WA_RD,WB_PC, REN_N,WEN_N,N,N,N,N),
|
||||
JALR_R-> List(Y, BR_JR, REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_ADD, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_Y,WA_RD,WB_PC, REN_N,WEN_N,N,N,N,N),
|
||||
RDNPC-> List(Y, BR_N, REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_ADD, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_Y,WA_RD,WB_PC, REN_N,WEN_N,N,N,N,N),
|
||||
|
||||
LB-> List(Y, BR_N, REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_ADD, M_Y,M_XRD, MT_B, N,MUL_X, N,DIV_X, WEN_N,WA_RD,WB_X, REN_N,WEN_N,N,N,N,N),
|
||||
LH-> List(Y, BR_N, REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_ADD, M_Y,M_XRD, MT_H, N,MUL_X, N,DIV_X, WEN_N,WA_RD,WB_X, REN_N,WEN_N,N,N,N,N),
|
||||
@ -189,9 +185,6 @@ class rocketCtrl extends Component
|
||||
AMOMAX_D-> List(xpr64, BR_N, REN_Y,REN_Y,A2_0, A1_RS1,DW_XPR,FN_ADD, M_Y,M_XA_MAX, MT_D, N,MUL_X, N,DIV_X, WEN_N,WA_RD,WB_X, REN_N,WEN_N,N,N,N,N),
|
||||
AMOMINU_D->List(xpr64, BR_N, REN_Y,REN_Y,A2_0, A1_RS1,DW_XPR,FN_ADD, M_Y,M_XA_MINU,MT_D, N,MUL_X, N,DIV_X, WEN_N,WA_RD,WB_X, REN_N,WEN_N,N,N,N,N),
|
||||
AMOMAXU_D->List(xpr64, BR_N, REN_Y,REN_Y,A2_0, A1_RS1,DW_XPR,FN_ADD, M_Y,M_XA_MAXU,MT_D, N,MUL_X, N,DIV_X, WEN_N,WA_RD,WB_X, REN_N,WEN_N,N,N,N,N),
|
||||
|
||||
// miscellaneous
|
||||
RDNPC-> List(Y, BR_N, REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_ADD, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_Y,WA_RD,WB_PC, REN_N,WEN_N,N,N,N,N),
|
||||
*/
|
||||
));
|
||||
|
||||
@ -210,7 +203,7 @@ class rocketCtrl extends Component
|
||||
io.console.valid := console_out_fire.toBool;
|
||||
|
||||
val wb_reg_div_mul_val = Reg(){Bool()};
|
||||
val dcache_miss = Reg(){Bool()};
|
||||
val dcache_miss = Reg(io.dmem.resp_miss);
|
||||
|
||||
val sboard = new rocketCtrlSboard();
|
||||
sboard.io.raddra := id_raddr2.toUFix;
|
||||
@ -232,7 +225,8 @@ class rocketCtrl extends Component
|
||||
val id_stall_ra = sboard.io.stallra;
|
||||
|
||||
val id_reg_btb_hit = Reg(resetVal = Bool(false));
|
||||
val id_reg_itlb_xcpt = Reg(resetVal = Bool(false));
|
||||
val id_reg_xcpt_itlb = Reg(resetVal = Bool(false));
|
||||
|
||||
val ex_reg_br_type = Reg(){UFix(width = 4)};
|
||||
val ex_reg_btb_hit = Reg(){Bool()};
|
||||
val ex_reg_div_mul_val = Reg(){Bool()};
|
||||
@ -241,15 +235,27 @@ class rocketCtrl extends Component
|
||||
val ex_reg_mem_type = Reg(){UFix(width = 3)};
|
||||
val ex_reg_eret = Reg(resetVal = Bool(false));
|
||||
val ex_reg_privileged = Reg(resetVal = Bool(false));
|
||||
// val ex_reg_itlb_xcpt = Reg(resetVal = Bool(false));
|
||||
|
||||
val ex_reg_xcpt_itlb = Reg(resetVal = Bool(false));
|
||||
val ex_reg_xcpt_illegal = Reg(resetVal = Bool(false));
|
||||
val ex_reg_xcpt_privileged = Reg(resetVal = Bool(false));
|
||||
// val ex_reg_xcpt_fpu = Reg(resetVal = Bool(false));
|
||||
val ex_reg_xcpt_syscall = Reg(resetVal = Bool(false));
|
||||
|
||||
val mem_reg_xcpt_itlb = Reg(resetVal = Bool(false));
|
||||
val mem_reg_xcpt_illegal = Reg(resetVal = Bool(false));
|
||||
val mem_reg_xcpt_privileged = Reg(resetVal = Bool(false));
|
||||
// val mem_reg_xcpt_fpu = Reg(resetVal = Bool(false));
|
||||
val mem_reg_xcpt_fpu = Bool(false); // FIXME: trap on unimplemented FPU instructions
|
||||
val mem_reg_xcpt_syscall = Reg(resetVal = Bool(false));
|
||||
|
||||
when (!io.dpath.stalld) {
|
||||
when (io.dpath.killf) {
|
||||
id_reg_itlb_xcpt <== Bool(false);
|
||||
id_reg_xcpt_itlb <== Bool(false);
|
||||
id_reg_btb_hit <== Bool(false);
|
||||
}
|
||||
otherwise{
|
||||
id_reg_itlb_xcpt <== io.itlb_xcpt;
|
||||
id_reg_xcpt_itlb <== io.xcpt_itlb;
|
||||
id_reg_btb_hit <== io.dpath.btb_hit;
|
||||
}
|
||||
}
|
||||
@ -263,7 +269,12 @@ class rocketCtrl extends Component
|
||||
ex_reg_mem_type <== UFix(0, 3);
|
||||
ex_reg_eret <== Bool(false);
|
||||
ex_reg_privileged <== Bool(false);
|
||||
// ex_reg_itlb_xcpt <== Bool(false);
|
||||
|
||||
ex_reg_xcpt_itlb <== Bool(false);
|
||||
ex_reg_xcpt_illegal <== Bool(false);
|
||||
ex_reg_xcpt_privileged <== Bool(false);
|
||||
// ex_reg_xcpt_fpu <== Bool(false);
|
||||
ex_reg_xcpt_syscall <== Bool(false);
|
||||
}
|
||||
otherwise {
|
||||
ex_reg_br_type <== id_br_type;
|
||||
@ -274,7 +285,12 @@ class rocketCtrl extends Component
|
||||
ex_reg_mem_type <== id_mem_type;
|
||||
ex_reg_eret <== id_eret.toBool;
|
||||
ex_reg_privileged <== id_privileged.toBool;
|
||||
// ex_reg_itlb_xcpt <== id_reg_itlb_xcpt;
|
||||
|
||||
ex_reg_xcpt_itlb <== id_reg_xcpt_itlb;
|
||||
ex_reg_xcpt_illegal <== ~id_int_val.toBool;
|
||||
ex_reg_xcpt_privileged <== (id_privileged & ~io.dpath.status(5)).toBool;
|
||||
// ex_reg_xcpt_fpu <== Bool(false);
|
||||
ex_reg_xcpt_syscall <== id_syscall.toBool;
|
||||
}
|
||||
|
||||
val beq = io.dpath.br_eq;
|
||||
@ -316,6 +332,12 @@ class rocketCtrl extends Component
|
||||
mem_reg_mem_cmd <== UFix(0, 4);
|
||||
mem_reg_mem_type <== UFix(0, 3);
|
||||
mem_reg_privileged <== Bool(false);
|
||||
|
||||
mem_reg_xcpt_itlb <== Bool(false);
|
||||
mem_reg_xcpt_illegal <== Bool(false);
|
||||
mem_reg_xcpt_privileged <== Bool(false);
|
||||
// mem_reg_xcpt_fpu <== Bool(false);
|
||||
mem_reg_xcpt_syscall <== Bool(false);
|
||||
}
|
||||
otherwise {
|
||||
mem_reg_div_mul_val <== ex_reg_div_mul_val;
|
||||
@ -324,6 +346,12 @@ class rocketCtrl extends Component
|
||||
mem_reg_mem_cmd <== ex_reg_mem_cmd;
|
||||
mem_reg_mem_type <== ex_reg_mem_type;
|
||||
mem_reg_privileged <== ex_reg_privileged;
|
||||
|
||||
mem_reg_xcpt_itlb <== ex_reg_xcpt_itlb;
|
||||
mem_reg_xcpt_illegal <== mem_reg_xcpt_illegal;
|
||||
mem_reg_xcpt_privileged <== ex_reg_xcpt_privileged;
|
||||
// mem_reg_xcpt_fpu <== Bool(false);
|
||||
mem_reg_xcpt_syscall <== ex_reg_xcpt_syscall;
|
||||
}
|
||||
|
||||
when (reset.toBool || io.dpath.killm) {
|
||||
@ -333,31 +361,54 @@ class rocketCtrl extends Component
|
||||
wb_reg_div_mul_val <== mem_reg_div_mul_val;
|
||||
}
|
||||
|
||||
// replay execute stage PC when the D$ is blocked
|
||||
val replay_ex = ex_reg_mem_val && !io.dmem.req_rdy;
|
||||
|
||||
// replay execute stage PC on a D$ load miss
|
||||
val mem_cmd_load = mem_reg_mem_val && (mem_reg_mem_cmd === M_XRD);
|
||||
val replay_mem = io.dmem.resp_miss;
|
||||
|
||||
val kill_ex = replay_ex | replay_mem | mem_reg_privileged;
|
||||
val kill_mem = io.dpath.exception; // TODO: add load/store related exceptions
|
||||
// exception handling
|
||||
val mem_exception =
|
||||
io.xcpt_dtlb_ld ||
|
||||
io.xcpt_dtlb_st ||
|
||||
mem_reg_xcpt_illegal ||
|
||||
mem_reg_xcpt_privileged ||
|
||||
mem_reg_xcpt_fpu ||
|
||||
mem_reg_xcpt_syscall ||
|
||||
mem_reg_xcpt_itlb;
|
||||
|
||||
val mem_cause =
|
||||
// instruction address misaligned
|
||||
Mux(mem_reg_xcpt_itlb, UFix(1,5), // instruction access fault
|
||||
Mux(mem_reg_xcpt_illegal, UFix(2,5), // illegal instruction
|
||||
Mux(mem_reg_xcpt_privileged, UFix(3,5), // privileged instruction
|
||||
Mux(mem_reg_xcpt_fpu, UFix(4,5), // FPU disabled
|
||||
// interrupt
|
||||
Mux(mem_reg_xcpt_syscall, UFix(6,5), // system call
|
||||
// breakpoint
|
||||
// misaligned load
|
||||
// misaligned store
|
||||
Mux(io.xcpt_dtlb_ld, UFix(8,5), // load fault
|
||||
Mux(io.xcpt_dtlb_st, UFix(9,5), // store fault
|
||||
UFix(0,5))))))));
|
||||
|
||||
// write cause to PCR on an exception
|
||||
io.dpath.exception := mem_exception;
|
||||
io.dpath.cause := mem_cause;
|
||||
|
||||
dcache_miss <== io.dmem.resp_miss;
|
||||
// replay execute stage PC when the D$ is blocked, when the D$ misses, and for privileged instructions
|
||||
val replay_ex = (ex_reg_mem_val && !io.dmem.req_rdy) || io.dmem.resp_miss || mem_reg_privileged;
|
||||
|
||||
io.dpath.mem_load := mem_cmd_load;
|
||||
|
||||
// FIXME: dtlb exception handling broken, need to move cause value generation
|
||||
// to mem stage. also should probably move it from dpath to ctrl
|
||||
// replay mem stage PC on a DTLB miss
|
||||
val replay_mem = io.dtlb_miss;
|
||||
val kill_ex = replay_ex || replay_mem;
|
||||
val kill_mem = mem_exception || io.dtlb_miss;
|
||||
|
||||
io.dpath.sel_pc :=
|
||||
Mux(io.dpath.exception || io.dtlb_xcpt || mem_reg_eret, PC_PCR,
|
||||
Mux(replay_ex || replay_mem || mem_reg_privileged, PC_EX,
|
||||
Mux(!ex_reg_btb_hit && br_taken, PC_BR,
|
||||
Mux(ex_reg_btb_hit && !br_taken, PC_EX4,
|
||||
Mux(jr_taken, PC_JR,
|
||||
Mux(j_taken, PC_J,
|
||||
Mux(io.dpath.btb_hit, PC_BTB,
|
||||
PC_4)))))));
|
||||
Mux(mem_exception, PC_EVEC, // exception
|
||||
Mux(replay_mem, PC_MEM, // dtlb miss
|
||||
Mux(mem_reg_eret, PC_PCR, // eret instruction
|
||||
Mux(replay_ex, PC_EX, // D$ blocked, D$ miss, privileged inst
|
||||
Mux(!ex_reg_btb_hit && br_taken, PC_BR, // mispredicted taken branch
|
||||
Mux(ex_reg_btb_hit && !br_taken, PC_EX4, // mispredicted not taken branch
|
||||
Mux(jr_taken, PC_JR, // jump register
|
||||
Mux(j_taken, PC_J, // jump
|
||||
Mux(io.dpath.btb_hit, PC_BTB, // predicted PC from BTB
|
||||
PC_4))))))))); // PC+4
|
||||
|
||||
io.dpath.wen_btb := ~ex_reg_btb_hit & br_taken & ~kill_ex & ~kill_mem;
|
||||
|
||||
@ -366,8 +417,7 @@ class rocketCtrl extends Component
|
||||
ex_reg_btb_hit & ~br_taken |
|
||||
jr_taken |
|
||||
j_taken |
|
||||
io.dpath.exception |
|
||||
mem_reg_privileged |
|
||||
mem_exception |
|
||||
mem_reg_eret |
|
||||
replay_ex |
|
||||
replay_mem;
|
||||
@ -451,6 +501,7 @@ class rocketCtrl extends Component
|
||||
io.dpath.killx := kill_ex.toBool || kill_mem.toBool;
|
||||
io.dpath.killm := kill_mem.toBool;
|
||||
|
||||
io.dpath.mem_load := mem_reg_mem_val && (mem_reg_mem_cmd === M_XRD);
|
||||
io.dpath.ren2 := id_ren2.toBool;
|
||||
io.dpath.ren1 := id_ren1.toBool;
|
||||
io.dpath.sel_alu2 := id_sel_alu2;
|
||||
@ -469,12 +520,6 @@ class rocketCtrl extends Component
|
||||
io.dpath.ren_pcr := id_ren_pcr.toBool;
|
||||
io.dpath.wen_pcr := id_wen_pcr.toBool;
|
||||
io.dpath.eret := id_eret.toBool;
|
||||
|
||||
io.dpath.xcpt_illegal := ~id_int_val.toBool;
|
||||
io.dpath.xcpt_privileged := (id_privileged & ~io.dpath.status(5)).toBool;
|
||||
io.dpath.xcpt_fpu := Bool(false);
|
||||
io.dpath.xcpt_syscall := id_syscall.toBool;
|
||||
io.dpath.xcpt_itlb := id_reg_itlb_xcpt;
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user