1
0

moved exception handling from ex stage in dpath to mem stage in ctrl

This commit is contained in:
Rimas Avizienis
2011-11-10 00:50:09 -08:00
parent fbfa356d2a
commit 36aa4bcc9d
7 changed files with 153 additions and 143 deletions

View File

@ -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;
}
}