diff --git a/rocket/src/main/scala/consts.scala b/rocket/src/main/scala/consts.scala index 794e54d2..d0d318d3 100644 --- a/rocket/src/main/scala/consts.scala +++ b/rocket/src/main/scala/consts.scala @@ -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); } diff --git a/rocket/src/main/scala/cpu.scala b/rocket/src/main/scala/cpu.scala index f2c993ca..0c2d2e0f 100644 --- a/rocket/src/main/scala/cpu.scala +++ b/rocket/src/main/scala/cpu.scala @@ -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); diff --git a/rocket/src/main/scala/ctrl.scala b/rocket/src/main/scala/ctrl.scala index 807a80d8..346cb095 100644 --- a/rocket/src/main/scala/ctrl.scala +++ b/rocket/src/main/scala/ctrl.scala @@ -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; } } diff --git a/rocket/src/main/scala/dpath.scala b/rocket/src/main/scala/dpath.scala index 825c3897..d5a98549 100644 --- a/rocket/src/main/scala/dpath.scala +++ b/rocket/src/main/scala/dpath.scala @@ -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); diff --git a/rocket/src/main/scala/dpath_util.scala b/rocket/src/main/scala/dpath_util.scala index b9de3dab..7b132e3e 100644 --- a/rocket/src/main/scala/dpath_util.scala +++ b/rocket/src/main/scala/dpath_util.scala @@ -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); } diff --git a/rocket/src/main/scala/dtlb.scala b/rocket/src/main/scala/dtlb.scala index e0cdfe6f..557a7e24 100644 --- a/rocket/src/main/scala/dtlb.scala +++ b/rocket/src/main/scala/dtlb.scala @@ -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); diff --git a/rocket/src/main/scala/icache.scala b/rocket/src/main/scala/icache.scala index c72c7ca8..36ff768b 100644 --- a/rocket/src/main/scala/icache.scala +++ b/rocket/src/main/scala/icache.scala @@ -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();