moved exception handling from ex stage in dpath to mem stage in ctrl
This commit is contained in:
parent
fbfa356d2a
commit
36aa4bcc9d
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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); }
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user