1
0
Fork 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

@ -24,6 +24,7 @@ object Constants
val PC_MEM = UFix(7, 4);
val PC_MEM4 = UFix(8, 4);
val PC_EX = UFix(9, 4);
val PC_EVEC = UFix(10, 4);
val KF_Y = UFix(1, 1);
val KF_N = UFix(0, 1);
@ -165,6 +166,10 @@ object Constants
val DTLB_ENTRIES = 8;
val ITLB_ENTRIES = 8;
// physical memory size (# 4K pages - for proxy kernel at least)
// if you change this value, make sure to also change MEMORY_SIZE variable in memif.h
val MEMSIZE = Bits("h2000", 64); // 32 megs
val HAVE_FPU = Bool(false);
val HAVE_VEC = Bool(false);
}

View File

@ -51,14 +51,11 @@ class rocketProc extends Component
val arb = new rocketDmemArbiter();
ctrl.io.dpath <> dpath.io.ctrl;
ctrl.io.host.start ^^ io.host.start;
// ctrl.io.dmem ^^ io.dmem;
// ctrl.io.imem ^^ io.imem;
// dpath.io.dmem ^^ io.dmem;
// dpath.io.imem.req_addr ^^ io.imem.req_addr;
dpath.io.imem.resp_data ^^ io.imem.resp_data;
dpath.io.host ^^ io.host;
ctrl.io.host.start := io.host.start;
dpath.io.debug ^^ io.debug;
// dpath.io.imem.resp_data ^^ io.imem.resp_data;
// FIXME: make this less verbose
// connect ITLB to I$, ctrl, dpath
@ -71,7 +68,8 @@ class rocketProc extends Component
io.imem.req_addr := itlb.io.cpu.resp_addr;
ctrl.io.imem.req_rdy := itlb.io.cpu.req_rdy && io.imem.req_rdy;
ctrl.io.imem.resp_val := io.imem.resp_val;
ctrl.io.itlb_xcpt := itlb.io.cpu.exception;
dpath.io.imem.resp_data := io.imem.resp_data;
ctrl.io.xcpt_itlb := itlb.io.cpu.exception;
// connect DTLB to D$ arbiter, ctrl+dpath
dtlb.io.cpu.invalidate := Bool(false); // FIXME
@ -80,7 +78,9 @@ class rocketProc extends Component
dtlb.io.cpu.req_cmd := ctrl.io.dmem.req_cmd;
dtlb.io.cpu.req_asid := Bits(0,ASID_BITS); // FIXME: connect to PCR
dtlb.io.cpu.req_addr := dpath.io.dmem.req_addr;
ctrl.io.dtlb_xcpt := dtlb.io.cpu.exception;
ctrl.io.xcpt_dtlb_ld := dtlb.io.cpu.xcpt_ld;
ctrl.io.xcpt_dtlb_st := dtlb.io.cpu.xcpt_st;
ctrl.io.dtlb_miss := dtlb.io.cpu.resp_miss;
// connect page table walker to TLBs, page table base register (from PCR)
// and D$ arbiter (selects between requests from pipeline and PTW, PTW has priority)
@ -90,8 +90,7 @@ class rocketProc extends Component
arb.io.ptw <> ptw.io.dmem;
arb.io.mem ^^ io.dmem
// FIXME: make this less verbose
// connect arbiter to ctrl+dpath
// connect arbiter to ctrl+dpath+DTLB
arb.io.cpu.req_val := dtlb.io.cpu.resp_val;
arb.io.cpu.req_cmd := ctrl.io.dmem.req_cmd;
arb.io.cpu.req_type := ctrl.io.dmem.req_type;
@ -104,19 +103,6 @@ class rocketProc extends Component
dpath.io.dmem.resp_tag := arb.io.cpu.resp_tag;
dpath.io.dmem.resp_data := arb.io.cpu.resp_data;
// arb.io.cpu.req_val := ctrl.io.dmem.req_val;
// arb.io.cpu.req_cmd := ctrl.io.dmem.req_cmd;
// arb.io.cpu.req_type := ctrl.io.dmem.req_type;
// arb.io.cpu.req_addr := dpath.io.dmem.req_addr;
// arb.io.cpu.req_data := dpath.io.dmem.req_data;
// arb.io.cpu.req_tag := dpath.io.dmem.req_tag;
// ctrl.io.dmem.req_rdy := arb.io.cpu.req_rdy;
// ctrl.io.dmem.resp_miss := arb.io.cpu.resp_miss;
// ctrl.io.dmem.resp_val := arb.io.cpu.resp_val;
// dpath.io.dmem.resp_val := arb.io.cpu.resp_val;
// dpath.io.dmem.resp_tag := arb.io.cpu.resp_tag;
// dpath.io.dmem.resp_data := arb.io.cpu.resp_data;
// FIXME: console disconnected
// io.console.bits := dpath.io.dpath.rs1(7,0);
io.console.bits := Bits(0,8);

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

View File

@ -26,7 +26,6 @@ class ioDpathAll extends Bundle()
val host = new ioHost();
val ctrl = new ioCtrlDpath().flip();
val debug = new ioDebug();
// val dmem = new ioDmem(List("req_addr", "req_data", "req_tag", "resp_val", "resp_tag", "resp_data")).flip();
val dmem = new ioDpathDmem();
val imem = new ioDpathImem();
val ptbr = UFix(PADDR_BITS, 'output);
@ -91,8 +90,6 @@ class rocketDpath extends Component
val ex_reg_ctrl_ren_pcr = Reg(resetVal = Bool(false));
val ex_reg_ctrl_wen_pcr = Reg(resetVal = Bool(false));
val ex_reg_ctrl_eret = Reg(resetVal = Bool(false));
val ex_reg_ctrl_exception = Reg(resetVal = Bool(false));
val ex_reg_ctrl_cause = Reg(resetVal = UFix(0,5));
val ex_wdata = Wire() { Bits() };
// memory definitions
@ -103,9 +100,7 @@ class rocketDpath extends Component
val mem_reg_wdata = Reg(resetVal = Bits(0,64));
val mem_reg_raddr2 = Reg(resetVal = UFix(0,5));
val mem_reg_pcr = Reg(resetVal = Bits(0,64));
val mem_reg_ctrl_cause = Reg(resetVal = UFix(0,5));
val mem_reg_ctrl_eret = Reg(resetVal = Bool(false));
val mem_reg_ctrl_exception = Reg(resetVal = Bool(false));
val mem_reg_ctrl_ll_wb = Reg(resetVal = Bool(false));
val mem_reg_ctrl_wen = Reg(resetVal = Bool(false));
val mem_reg_ctrl_wen_pcr = Reg(resetVal = Bool(false));
@ -147,16 +142,17 @@ class rocketDpath extends Component
btb.io.correct_target := ex_branch_target;
val if_next_pc =
Mux(io.ctrl.sel_pc === PC_4, if_pc_plus4,
Mux(io.ctrl.sel_pc === PC_BTB, if_btb_target,
Mux(io.ctrl.sel_pc === PC_EX, ex_reg_pc,
Mux(io.ctrl.sel_pc === PC_EX4, ex_reg_pc_plus4,
Mux(io.ctrl.sel_pc === PC_BR, ex_branch_target,
Mux(io.ctrl.sel_pc === PC_J, ex_branch_target,
Mux(io.ctrl.sel_pc === PC_JR, ex_jr_target.toUFix,
Mux(io.ctrl.sel_pc === PC_PCR, mem_reg_pcr(VADDR_BITS-1,0).toUFix,
Mux(io.ctrl.sel_pc === PC_MEM, mem_reg_pc,
UFix(0, VADDR_BITS))))))))));
Mux(io.ctrl.sel_pc === PC_4, if_pc_plus4,
Mux(io.ctrl.sel_pc === PC_BTB, if_btb_target,
Mux(io.ctrl.sel_pc === PC_EX, ex_reg_pc,
Mux(io.ctrl.sel_pc === PC_EX4, ex_reg_pc_plus4,
Mux(io.ctrl.sel_pc === PC_BR, ex_branch_target,
Mux(io.ctrl.sel_pc === PC_J, ex_branch_target,
Mux(io.ctrl.sel_pc === PC_JR, ex_jr_target.toUFix,
Mux(io.ctrl.sel_pc === PC_PCR, mem_reg_pcr(VADDR_BITS-1,0).toUFix, // only used for ERET
Mux(io.ctrl.sel_pc === PC_EVEC, pcr.io.evec,
Mux(io.ctrl.sel_pc === PC_MEM, mem_reg_pc,
UFix(0, VADDR_BITS)))))))))));
when (!io.host.start){
if_reg_pc <== UFix(0, VADDR_BITS); //32'hFFFF_FFFC;
@ -256,16 +252,6 @@ class rocketDpath extends Component
Mux(id_raddr2 != UFix(0, 5) && r_dmem_resp_val && id_raddr2 === r_dmem_resp_waddr, dmem_resp_data_final,
Mux(id_raddr2 != UFix(0, 5) && wb_reg_ctrl_wen && id_raddr2 === wb_reg_waddr, wb_reg_wdata,
id_rdata2)))));
// write value to cause register based on exception type
val id_exception = io.ctrl.xcpt_illegal || io.ctrl.xcpt_privileged || io.ctrl.xcpt_fpu || io.ctrl.xcpt_syscall || io.ctrl.xcpt_itlb;
val id_cause =
Mux(io.ctrl.xcpt_itlb, UFix(1,5),
Mux(io.ctrl.xcpt_illegal, UFix(2,5),
Mux(io.ctrl.xcpt_privileged, UFix(3,5),
Mux(io.ctrl.xcpt_fpu, UFix(4,5),
Mux(io.ctrl.xcpt_syscall, UFix(6,5),
UFix(0,5))))));
io.ctrl.inst := id_reg_inst;
@ -287,7 +273,6 @@ class rocketDpath extends Component
ex_reg_ctrl_ll_wb <== io.ctrl.div_wb | io.ctrl.mul_wb; // TODO: verify
ex_reg_ctrl_sel_wb <== io.ctrl.sel_wb;
ex_reg_ctrl_ren_pcr <== io.ctrl.ren_pcr;
ex_reg_ctrl_cause <== id_cause;
when(io.ctrl.killd) {
ex_reg_valid <== Bool(false);
@ -296,7 +281,6 @@ class rocketDpath extends Component
ex_reg_ctrl_wen <== Bool(false);
ex_reg_ctrl_wen_pcr <== Bool(false);
ex_reg_ctrl_eret <== Bool(false);
ex_reg_ctrl_exception <== Bool(false);
}
otherwise {
ex_reg_valid <== id_reg_valid;
@ -305,7 +289,6 @@ class rocketDpath extends Component
ex_reg_ctrl_wen <== io.ctrl.wen;
ex_reg_ctrl_wen_pcr <== io.ctrl.wen_pcr;
ex_reg_ctrl_eret <== io.ctrl.eret;
ex_reg_ctrl_exception <== id_exception;
}
val ex_alu_in2 =
@ -358,12 +341,11 @@ class rocketDpath extends Component
io.dmem.req_tag := ex_reg_waddr;
// processor control regfile read
pcr.io.r.en := ex_reg_ctrl_ren_pcr | ex_reg_ctrl_exception | ex_reg_ctrl_eret;
pcr.io.r.en := ex_reg_ctrl_ren_pcr | ex_reg_ctrl_eret;
pcr.io.r.addr :=
Mux(ex_reg_ctrl_exception, PCR_EVEC,
Mux(ex_reg_ctrl_eret, PCR_EPC,
ex_reg_raddr2));
ex_reg_raddr2);
pcr.io.host.from_wen ^^ io.host.from_wen;
pcr.io.host.from ^^ io.host.from;
pcr.io.host.to ^^ io.host.to;
@ -396,25 +378,20 @@ class rocketDpath extends Component
mem_reg_wdata <== ex_wdata;
mem_reg_ctrl_ll_wb <== ex_reg_ctrl_ll_wb;
mem_reg_raddr2 <== ex_reg_raddr2;
mem_reg_ctrl_cause <== ex_reg_ctrl_cause;
when (io.ctrl.killx) {
mem_reg_valid <== Bool(false);
mem_reg_ctrl_eret <== Bool(false);
mem_reg_ctrl_wen <== Bool(false);
mem_reg_ctrl_wen_pcr <== Bool(false);
mem_reg_ctrl_exception <== Bool(false);
}
otherwise {
mem_reg_valid <== ex_reg_valid;
mem_reg_ctrl_eret <== ex_reg_ctrl_eret;
mem_reg_ctrl_wen <== ex_reg_ctrl_wen;
mem_reg_ctrl_wen_pcr <== ex_reg_ctrl_wen_pcr;
mem_reg_ctrl_exception <== ex_reg_ctrl_exception;
}
// exception signal to control (for NPC select)
io.ctrl.exception := mem_reg_ctrl_exception;
// for load/use hazard detection (load byte/halfword)
io.ctrl.mem_waddr := mem_reg_waddr;
@ -432,9 +409,9 @@ class rocketDpath extends Component
wb_reg_wdata <== mem_reg_wdata;
wb_reg_ctrl_ll_wb <== mem_reg_ctrl_ll_wb;
wb_reg_raddr2 <== mem_reg_raddr2;
wb_reg_ctrl_cause <== mem_reg_ctrl_cause;
wb_reg_ctrl_eret <== mem_reg_ctrl_eret;
wb_reg_ctrl_exception <== mem_reg_ctrl_exception;
wb_reg_ctrl_exception <== io.ctrl.exception;
wb_reg_ctrl_cause <== io.ctrl.cause;
when (io.ctrl.killm) {
wb_reg_valid <== Bool(false);

View File

@ -17,18 +17,15 @@ class ioDpathBTB extends Bundle()
class rocketDpathBTB extends Component
{
override val io = new ioDpathBTB();
override val io = new ioDpathBTB();
val rst_lwlr_pf = Mem(4, io.wen, io.correct_pc4(3, 2), UFix(1, 1), resetVal = UFix(0, 1));
val lwlr_pf = Mem(4, io.wen, io.correct_pc4(3, 2),
Cat(io.correct_pc4(VADDR_BITS-1,4), io.correct_target(VADDR_BITS-1,2)), resetVal = UFix(0, 1));
// Cat(io.correct_pc4(31,4), io.correct_target(31,2)), resetVal = UFix(0, 1));
val is_val = rst_lwlr_pf(io.current_pc4(3, 2));
val tag_target = lwlr_pf(io.current_pc4(3, 2));
io.hit := (is_val & (tag_target(2*VADDR_BITS-7,VADDR_BITS-2) === io.current_pc4(VADDR_BITS-1, 4))).toBool;
io.target := Cat(tag_target(VADDR_BITS-3, 0), Bits(0,2)).toUFix;
// io.hit := (is_val & (tag_target(57,30) === io.current_pc4(31, 4))).toBool;
// io.target := Cat(tag_target(29, 0), Bits(0,2)).toUFix;
}
class ioDpathPCR extends Bundle()
@ -40,6 +37,7 @@ class ioDpathPCR extends Bundle()
val status = Bits(17, 'output);
val ptbr = UFix(PADDR_BITS, 'output);
val evec = UFix(VADDR_BITS, 'output);
val exception = Bool('input);
val cause = UFix(5, 'input);
val pc = UFix(VADDR_BITS, 'input);
@ -51,9 +49,9 @@ class rocketDpathPCR extends Component
val io = new ioDpathPCR();
val w = 32;
val reg_epc = Reg(resetVal = Bits(0, w));
val reg_badvaddr = Reg(resetVal = Bits(0, w));
val reg_ebase = Reg(resetVal = Bits(0, w));
val reg_epc = Reg(resetVal = UFix(0, VADDR_BITS));
val reg_badvaddr = Reg(resetVal = UFix(0, VADDR_BITS));
val reg_ebase = Reg(resetVal = UFix(0, VADDR_BITS));
val reg_count = Reg(resetVal = Bits(0, w));
val reg_compare = Reg(resetVal = Bits(0, w));
val reg_cause = Reg(resetVal = Bits(0, 5));
@ -79,6 +77,7 @@ class rocketDpathPCR extends Component
val rdata = Wire() { Bits() };
io.status := Cat(reg_status_vm, reg_status_im, reg_status);
io.evec := reg_ebase;
io.ptbr := reg_ptbr;
io.host.to := Mux(io.host.from_wen, Bits(0, w), reg_tohost);
io.debug.error_mode := reg_error_mode;
@ -125,9 +124,9 @@ class rocketDpathPCR extends Component
reg_status_ef <== HAVE_FPU && io.w.data(1).toBool;
reg_status_et <== io.w.data(0).toBool;
}
when (io.w.addr === PCR_EPC) { reg_epc <== io.w.data(w-1,0); }
when (io.w.addr === PCR_BADVADDR) { reg_badvaddr <== io.w.data(w-1,0); }
when (io.w.addr === PCR_EVEC) { reg_ebase <== io.w.data(w-1,0); }
when (io.w.addr === PCR_EPC) { reg_epc <== io.w.data(VADDR_BITS-1,0).toUFix; }
when (io.w.addr === PCR_BADVADDR) { reg_badvaddr <== io.w.data(VADDR_BITS-1,0).toUFix; }
when (io.w.addr === PCR_EVEC) { reg_ebase <== io.w.data(VADDR_BITS-1,0).toUFix; }
when (io.w.addr === PCR_COUNT) { reg_count <== io.w.data(w-1,0); }
when (io.w.addr === PCR_COMPARE) { reg_compare <== io.w.data(w-1,0); }
when (io.w.addr === PCR_CAUSE) { reg_cause <== io.w.data(4,0); }
@ -141,13 +140,13 @@ class rocketDpathPCR extends Component
when (!io.r.en) { rdata <== Bits(0,2*w); }
switch (io.r.addr) {
is (PCR_STATUS) { rdata <== Cat(Bits(0,w+15), reg_status_vm, reg_status_im, reg_status); }
is (PCR_EPC) { rdata <== Cat(Fill(w, reg_epc(w-1)), reg_epc); }
is (PCR_BADVADDR) { rdata <== Cat(Fill(w, reg_badvaddr(w-1)), reg_badvaddr); }
is (PCR_EVEC) { rdata <== Cat(Fill(w, reg_ebase(w-1)), reg_ebase); }
is (PCR_EPC) { rdata <== Cat(Fill(2*w-VADDR_BITS, reg_epc(VADDR_BITS-1)), reg_epc); }
is (PCR_BADVADDR) { rdata <== Cat(Fill(2*w-VADDR_BITS, reg_badvaddr(VADDR_BITS-1)), reg_badvaddr); }
is (PCR_EVEC) { rdata <== Cat(Fill(2*w-VADDR_BITS, reg_ebase(VADDR_BITS-1)), reg_ebase); }
is (PCR_COUNT) { rdata <== Cat(Fill(w, reg_count(w-1)), reg_count); }
is (PCR_COMPARE) { rdata <== Cat(Fill(w, reg_compare(w-1)), reg_compare); }
is (PCR_CAUSE) { rdata <== Cat(Bits(0,w+27), reg_cause); }
is (PCR_MEMSIZE) { rdata <== Bits("h2000", 2*w); }
is (PCR_MEMSIZE) { rdata <== MEMSIZE; }
is (PCR_LOG) { rdata <== Cat(Bits(0,63), reg_log_control); }
is (PCR_FROMHOST) { rdata <== Cat(Fill(w, reg_fromhost(w-1)), reg_fromhost); }
is (PCR_TOHOST) { rdata <== Cat(Fill(w, reg_tohost(w-1)), reg_tohost); }

View File

@ -6,7 +6,7 @@ import Node._;
import Constants._;
import scala.math._;
// interface between DTLB and fetch stage of pipeline
// interface between DTLB and pipeline
class ioDTLB_CPU(view: List[String] = null) extends Bundle(view)
{
// status bits (from PCR), to check current permission and whether VM is enabled
@ -20,9 +20,11 @@ class ioDTLB_CPU(view: List[String] = null) extends Bundle(view)
val req_asid = Bits(ASID_BITS, 'input);
val req_addr = UFix(VADDR_BITS, 'input);
// lookup responses
val resp_miss = Bool('output);
val resp_val = Bool('output);
val resp_addr = UFix(PADDR_BITS, 'output);
val exception = Bool('output);
val xcpt_ld = Bool('output);
val xcpt_st = Bool('output);
}
class ioDTLB extends Bundle
@ -119,24 +121,22 @@ class rocketDTLB(entries: Int) extends Component
}
}
val dtlb_st_xcpt =
tag_hit && req_load &&
io.cpu.xcpt_ld :=
status_vm && tag_hit && req_load &&
((status_mode && !sw_array(tag_hit_addr).toBool) ||
(!status_mode && !uw_array(tag_hit_addr).toBool));
val dtlb_ld_xcpt =
tag_hit && req_store &&
io.cpu.xcpt_st :=
status_vm && tag_hit && req_store &&
((status_mode && !sr_array(tag_hit_addr).toBool) ||
(!status_mode && !ur_array(tag_hit_addr).toBool));
val dtlb_exception = dtlb_st_xcpt || dtlb_ld_xcpt;
io.cpu.req_rdy := (state === s_ready);
io.cpu.resp_miss := lookup_miss;
io.cpu.resp_val := Mux(status_vm, tag_hit, io.cpu.req_val);
io.cpu.resp_addr :=
Mux(status_vm, Cat(tag_ram(tag_hit_addr), req_idx),
io.cpu.req_addr(PADDR_BITS-1,0)).toUFix;
io.cpu.exception := status_vm && dtlb_exception;
io.ptw.req_val := (state === s_request);
io.ptw.req_vpn := r_refill_tag(VPN_BITS-1,0);

View File

@ -51,11 +51,9 @@ class rocketSRAMsp(entries: Int, width: Int) extends Component {
}
// basic direct mapped instruction cache
// 32 bit wide cpu port, 128 bit wide memory port, 64 byte cachelines
// parameters :
// lines = # cache lines
// addr_bits = address width (word addressable) bits
// 32 bit wide cpu port, 128 bit wide memory port, 64 byte cachelines
class rocketICacheDM(lines: Int) extends Component {
val io = new ioICacheDM();