diff --git a/rocket/src/main/scala/cpu.scala b/rocket/src/main/scala/cpu.scala index 8cde5d50..0d46f702 100644 --- a/rocket/src/main/scala/cpu.scala +++ b/rocket/src/main/scala/cpu.scala @@ -10,7 +10,6 @@ class ioDebug(view: List[String] = null) extends Bundle(view) val id_valid = Bool('output); val ex_valid = Bool('output); val mem_valid = Bool('output); - val wb_valid = Bool('output); } class ioHost(view: List[String] = null) extends Bundle(view) @@ -73,7 +72,6 @@ class rocketProc extends Component // ctrl.io.itlb_miss := itlb.io.cpu.resp_miss; io.imem.itlb_miss := itlb.io.cpu.resp_miss; - // connect DTLB to D$ arbiter, ctrl+dpath dtlb.io.cpu.invalidate := dpath.io.ptbr_wen; dtlb.io.cpu.status := dpath.io.ctrl.status; diff --git a/rocket/src/main/scala/ctrl.scala b/rocket/src/main/scala/ctrl.scala index b9d8e535..be527aa5 100644 --- a/rocket/src/main/scala/ctrl.scala +++ b/rocket/src/main/scala/ctrl.scala @@ -33,7 +33,8 @@ class ioCtrlDpath extends Bundle() val sel_wb = UFix(3, 'output); val ren_pcr = Bool('output); val wen_pcr = Bool('output); - val eret = Bool('output); + val id_eret = Bool('output); + val mem_eret = Bool('output); val mem_load = Bool('output); val wen = Bool('output); // enable/disable interrupts @@ -247,7 +248,7 @@ class rocketCtrl extends Component SYSCALL-> List(Y, BR_N, REN_N,REN_N,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,Y,N), EI-> List(Y, BR_N, REN_N,REN_N,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_N,I_EI,SYNC_N,N,N,Y), DI-> List(Y, BR_N, REN_N,REN_N,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_N,I_DI,SYNC_N,N,N,Y), - ERET-> List(Y, BR_N, REN_N,REN_N,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_N,I_X ,SYNC_N,Y,N,Y), + ERET-> List(Y, BR_N, REN_N,REN_N,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_PCR,REN_N,WEN_N,I_X ,SYNC_N,Y,N,Y), FENCE-> List(Y, BR_N, REN_N,REN_N,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_N,I_X ,SYNC_D,N,N,N), FENCE_I-> List(Y, BR_N, REN_N,REN_N,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_N,I_X ,SYNC_I,N,N,N), CFLUSH-> List(Y, BR_N, REN_Y,REN_N,A2_X, A1_X, DW_X, FN_X, M_Y,M_FLA, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,N,Y), @@ -354,10 +355,6 @@ class rocketCtrl extends Component val mem_reg_xcpt_privileged = Reg(resetVal = Bool(false)); val mem_reg_xcpt_fpu = Reg(resetVal = Bool(false)); val mem_reg_xcpt_syscall = Reg(resetVal = Bool(false)); - - val wb_reg_inst_di = Reg(resetVal = Bool(false)); - val wb_reg_inst_ei = Reg(resetVal = Bool(false)); - val wb_reg_flush_inst = Reg(resetVal = Bool(false)); when (!io.dpath.stalld) { when (io.dpath.killf) { @@ -479,19 +476,8 @@ class rocketCtrl extends Component mem_reg_xcpt_fpu <== ex_reg_xcpt_fpu; mem_reg_xcpt_syscall <== ex_reg_xcpt_syscall; } - - when (reset.toBool || io.dpath.killm) { - wb_reg_div_mul_val <== Bool(false); - wb_reg_inst_di <== Bool(false); - wb_reg_inst_ei <== Bool(false); - wb_reg_flush_inst <== Bool(false); - } - otherwise { - wb_reg_div_mul_val <== mem_reg_div_mul_val; - wb_reg_inst_di <== mem_reg_inst_di; - wb_reg_inst_ei <== mem_reg_inst_ei; - wb_reg_flush_inst <== mem_reg_flush_inst; - } + + wb_reg_div_mul_val <== mem_reg_div_mul_val; // exception handling // FIXME: verify PC in MEM stage points to valid, restartable instruction @@ -644,9 +630,8 @@ class rocketCtrl extends Component // for divider, multiplier writeback val mul_wb = io.dpath.mul_result_val; val div_wb = io.dpath.div_result_val & !mul_wb; - - - io.flush_inst := wb_reg_flush_inst; + + io.flush_inst := mem_reg_flush_inst; io.dpath.stalld := ctrl_stalld.toBool; io.dpath.killf := take_pc | ~io.imem.resp_val; @@ -672,9 +657,10 @@ class rocketCtrl extends Component io.dpath.sel_wb := id_sel_wb; io.dpath.ren_pcr := id_ren_pcr.toBool; io.dpath.wen_pcr := id_wen_pcr.toBool; - io.dpath.eret := id_eret.toBool; - io.dpath.irq_disable := wb_reg_inst_di; - io.dpath.irq_enable := wb_reg_inst_ei; + io.dpath.id_eret := id_eret.toBool; + io.dpath.mem_eret := mem_reg_eret; + io.dpath.irq_disable := mem_reg_inst_di && !kill_mem; + io.dpath.irq_enable := mem_reg_inst_ei && !kill_mem; } } diff --git a/rocket/src/main/scala/dcache.scala b/rocket/src/main/scala/dcache.scala index ab0f6f02..1fcda1a5 100644 --- a/rocket/src/main/scala/dcache.scala +++ b/rocket/src/main/scala/dcache.scala @@ -7,7 +7,6 @@ import scala.math._; // interface between D$ and processor/DTLB class ioDmem(view: List[String] = null) extends Bundle(view) { -// val dtlb_busy = Bool('input); val dtlb_miss = Bool('input); val req_val = Bool('input); val req_rdy = Bool('output); @@ -48,7 +47,7 @@ class rocketDCacheStoreGen extends Component { val req_type = Bits(3, 'input); val req_addr_lsb = Bits(3, 'input); val req_data = Bits(64, 'input); - val store_wmask = Bits(8, 'output); + val store_wmask = Bits(64, 'output); val store_data = Bits(64, 'output); } @@ -86,7 +85,16 @@ class rocketDCacheStoreGen extends Component { Mux(io.req_type === MT_D, wmask_d, UFix(0, 8))))); - io.store_wmask := store_wmask_byte; + val store_wmask_d = Cat(Fill(8, store_wmask_byte(7)), + Fill(8, store_wmask_byte(6)), + Fill(8, store_wmask_byte(5)), + Fill(8, store_wmask_byte(4)), + Fill(8, store_wmask_byte(3)), + Fill(8, store_wmask_byte(2)), + Fill(8, store_wmask_byte(1)), + Fill(8, store_wmask_byte(0))); + + io.store_wmask := store_wmask_d; io.store_data := Mux(io.req_type === MT_B, Fill(8, io.req_data( 7,0)), @@ -260,7 +268,7 @@ class rocketDCacheDM(lines: Int) extends Component { when (tag_we && r_req_flush) { vb_array <== vb_array.bitSet(r_cpu_req_idx(PGIDX_BITS-1,offsetbits).toUFix, UFix(0,1)); } - val vb_rdata = Reg(vb_array(tag_addr).toBool); + val vb_rdata = vb_array(r_cpu_req_idx(PGIDX_BITS-1,offsetbits).toUFix).toBool; val tag_valid = r_cpu_req_val && vb_rdata; val tag_match = (tag_rdata === io.cpu.req_ppn); val tag_hit = tag_valid && tag_match; @@ -282,28 +290,28 @@ class rocketDCacheDM(lines: Int) extends Component { // after the cache line refill has completed val resolve_store = (state === s_resolve_miss) && r_req_store; - // dirty bit array - val db_array = Reg(resetVal = Bits(0, lines)); - val tag_dirty = Reg(db_array(tag_addr)).toBool; - + // pending store data when (io.cpu.req_val && io.cpu.req_rdy && req_store) { p_store_idx <== io.cpu.req_idx; p_store_data <== io.cpu.req_data; p_store_type <== io.cpu.req_type; } - - when (io.cpu.req_val && io.cpu.req_rdy && req_amo) { - r_amo_data <== io.cpu.req_data; - } - when (store_hit && !drain_store) { p_store_valid <== Bool(true); } when (drain_store) { p_store_valid <== Bool(false); - db_array <== db_array.bitSet(p_store_idx(PGIDX_BITS-1,offsetbits).toUFix, UFix(1,1)); } - when (resolve_store) { + + // AMO operand + when (io.cpu.req_val && io.cpu.req_rdy && req_amo) { + r_amo_data <== io.cpu.req_data; + } + + // dirty bit array + val db_array = Reg(resetVal = Bits(0, lines)); + val tag_dirty = db_array(r_cpu_req_idx(PGIDX_BITS-1,offsetbits).toUFix).toBool; + when ((r_cpu_req_val && !io.cpu.dtlb_miss && tag_hit && r_req_store) || resolve_store) { db_array <== db_array.bitSet(p_store_idx(PGIDX_BITS-1,offsetbits).toUFix, UFix(1,1)); } when (state === s_write_amo) { @@ -319,17 +327,8 @@ class rocketDCacheDM(lines: Int) extends Component { storegen.io.req_data := p_store_data; storegen.io.req_type := p_store_type; val store_data = Fill(2, storegen.io.store_data); - val store_wmask_b = storegen.io.store_wmask; - val store_wmask_d = Cat(Fill(8, store_wmask_b(7)), - Fill(8, store_wmask_b(6)), - Fill(8, store_wmask_b(5)), - Fill(8, store_wmask_b(4)), - Fill(8, store_wmask_b(3)), - Fill(8, store_wmask_b(2)), - Fill(8, store_wmask_b(1)), - Fill(8, store_wmask_b(0))); - val store_idx_sel = p_store_idx(offsetlsb).toBool; - val store_wmask = Mux(store_idx_sel, Cat(store_wmask_d, Bits(0,64)), Cat(Bits(0,64), store_wmask_d)); + val store_wmask_d = storegen.io.store_wmask; + val store_wmask = Mux(p_store_idx(offsetlsb).toBool, Cat(store_wmask_d, Bits(0,64)), Cat(Bits(0,64), store_wmask_d)); // data array val data_array = new rocketSRAMsp(lines*4, 128); @@ -351,9 +350,8 @@ class rocketDCacheDM(lines: Int) extends Component { Fill(8, amo_wmask(2)), Fill(8, amo_wmask(1)), Fill(8, amo_wmask(0))); - - val amo_store_idx_sel = r_cpu_req_idx(offsetlsb).toBool; - val amo_store_wmask = Mux(amo_store_idx_sel, Cat(amo_store_wmask_d, Bits(0,64)), Cat(Bits(0,64), amo_store_wmask_d)); + + val amo_store_wmask = Mux(r_cpu_req_idx(offsetlsb).toBool, Cat(amo_store_wmask_d, Bits(0,64)), Cat(Bits(0,64), amo_store_wmask_d)); val amo_alu = new rocketDCacheAmoALU(); amo_alu.io.cmd := r_cpu_req_cmd; @@ -373,6 +371,7 @@ class rocketDCacheDM(lines: Int) extends Component { Mux((state === s_refill), io.mem.resp_data, Mux((state === s_write_amo), amo_alu_out, store_data)); + data_array.io.we := ((state === s_refill) && io.mem.resp_val) || (state === s_write_amo) || diff --git a/rocket/src/main/scala/dpath.scala b/rocket/src/main/scala/dpath.scala index 32bc74cd..4192cbd3 100644 --- a/rocket/src/main/scala/dpath.scala +++ b/rocket/src/main/scala/dpath.scala @@ -60,7 +60,7 @@ class rocketDpath extends Component val rfile = new rocketDpathRegfile(); // instruction fetch definitions - val if_reg_pc = Reg(resetVal = UFix(0,VADDR_BITS)); + val if_reg_pc = Reg(resetVal = UFix(0,VADDR_BITS)); // instruction decode definitions val id_reg_valid = Reg(resetVal = Bool(false)); @@ -80,6 +80,7 @@ class rocketDpath extends Component val ex_reg_waddr = Reg(resetVal = UFix(0,5)); val ex_reg_ctrl_sel_alu2 = Reg(resetVal = A2_X); val ex_reg_ctrl_sel_alu1 = Reg(resetVal = A1_X); + val ex_reg_ctrl_eret = Reg(resetVal = Bool(false)); val ex_reg_ctrl_fn_dw = Reg(resetVal = DW_X); val ex_reg_ctrl_fn_alu = Reg(resetVal = FN_X); val ex_reg_ctrl_ll_wb = Reg(resetVal = Bool(false)); @@ -91,36 +92,23 @@ class rocketDpath extends Component val ex_reg_ctrl_wen = Reg(resetVal = Bool(false)); 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_wdata = Wire() { Bits() }; // memory definitions val mem_reg_valid = Reg(resetVal = Bool(false)); val mem_reg_pc = Reg(resetVal = UFix(0,VADDR_BITS)); - val mem_reg_pc_plus4 = Reg(resetVal = UFix(0,VADDR_BITS)); val mem_reg_waddr = Reg(resetVal = UFix(0,5)); 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_eret = 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)); // writeback definitions - val wb_reg_valid = Reg(resetVal = Bool(false)); - val wb_reg_pc = Reg(resetVal = UFix(0,VADDR_BITS)); - val wb_reg_mem_req_addr = Reg(resetVal = UFix(0,VADDR_BITS)); val wb_reg_waddr = Reg(resetVal = UFix(0,5)); val wb_reg_wdata = Reg(resetVal = Bits(0,64)); val wb_reg_ctrl_ll_wb = Reg(resetVal = Bool(false)); - val wb_reg_raddr2 = Reg(resetVal = UFix(0,5)); - val wb_reg_ctrl_cause = Reg(resetVal = UFix(0,5)); - val wb_reg_ctrl_eret = Reg(resetVal = Bool(false)); - val wb_reg_ctrl_exception = Reg(resetVal = Bool(false)); val wb_reg_ctrl_wen = Reg(resetVal = Bool(false)); - val wb_reg_ctrl_wen_pcr = Reg(resetVal = Bool(false)); - val wb_reg_badvaddr_wen = Reg(resetVal = Bool(false)); val r_dmem_resp_val = Reg(resetVal = Bool(false)); val r_dmem_resp_waddr = Reg(resetVal = UFix(0,5)); @@ -153,7 +141,7 @@ class rocketDpath extends Component 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_PCR, mem_reg_wdata, // 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))))))))))); @@ -162,14 +150,15 @@ class rocketDpath extends Component if_reg_pc <== UFix(START_ADDR, VADDR_BITS); } when (!io.ctrl.stallf) { - if_reg_pc <== if_next_pc; + if_reg_pc <== if_next_pc.toUFix; } - + + // FIXME: make sure PCs are properly sign extended io.ctrl.xcpt_ma_inst := if_next_pc(1,0) != Bits(0,2) io.imem.req_addr := Mux(io.ctrl.stallf, if_reg_pc, - if_next_pc); + if_next_pc.toUFix); btb.io.current_pc4 := if_pc_plus4; btb.io.hit ^^ io.ctrl.btb_hit; @@ -294,7 +283,7 @@ class rocketDpath extends Component ex_reg_ctrl_mul_val <== io.ctrl.mul_val; 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_eret <== io.ctrl.id_eret; } val ex_alu_in2 = @@ -338,7 +327,7 @@ class rocketDpath extends Component io.ctrl.mul_result_val := mul.io.result_val; - io.ctrl.ex_waddr := ex_reg_waddr; // for load/use hazard detection + io.ctrl.ex_waddr := ex_reg_waddr; // for load/use hazard detection & bypass control // D$ request interface (registered inside D$ module) // other signals (req_val, req_rdy) connect to control module @@ -385,22 +374,18 @@ class rocketDpath extends Component // memory stage mem_reg_pc <== ex_reg_pc; - mem_reg_pc_plus4 <== ex_reg_pc_plus4; - mem_reg_pcr <== ex_pcr; mem_reg_waddr <== ex_reg_waddr; mem_reg_wdata <== ex_wdata; mem_reg_ctrl_ll_wb <== ex_reg_ctrl_ll_wb; mem_reg_raddr2 <== ex_reg_raddr2; - + 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); } 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; } @@ -418,26 +403,15 @@ class rocketDpath extends Component r_dmem_resp_type <== dmem_resp_type; r_dmem_resp_data <== mem_dmem_resp_data; - wb_reg_pc <== mem_reg_pc; wb_reg_waddr <== mem_reg_waddr; 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_eret <== mem_reg_ctrl_eret; - wb_reg_ctrl_exception <== io.ctrl.exception; - wb_reg_ctrl_cause <== io.ctrl.cause; - wb_reg_mem_req_addr <== io.dmem.req_addr; - wb_reg_badvaddr_wen <== io.ctrl.badvaddr_wen; when (io.ctrl.killm) { - wb_reg_valid <== Bool(false); wb_reg_ctrl_wen <== Bool(false); - wb_reg_ctrl_wen_pcr <== Bool(false); } otherwise { - wb_reg_valid <== mem_reg_valid; wb_reg_ctrl_wen <== mem_reg_ctrl_wen; - wb_reg_ctrl_wen_pcr <== mem_reg_ctrl_wen_pcr; } // crossbar/sign extension for 8/16 bit loads (moved to earlier in file) @@ -460,24 +434,22 @@ class rocketDpath extends Component io.ctrl.sboard_clr1a := r_dmem_resp_waddr; // processor control regfile write - pcr.io.w.addr := wb_reg_raddr2; - pcr.io.w.en := wb_reg_ctrl_wen_pcr; - pcr.io.w.data := wb_reg_wdata; + pcr.io.w.addr := mem_reg_raddr2; + pcr.io.w.en := mem_reg_ctrl_wen_pcr && !io.ctrl.killm; + pcr.io.w.data := mem_reg_wdata; pcr.io.di := io.ctrl.irq_disable; pcr.io.ei := io.ctrl.irq_enable; - pcr.io.eret := wb_reg_ctrl_eret; - pcr.io.exception := wb_reg_ctrl_exception; - pcr.io.cause := wb_reg_ctrl_cause; - pcr.io.pc := wb_reg_pc; - pcr.io.badvaddr := wb_reg_mem_req_addr; - pcr.io.badvaddr_wen := wb_reg_badvaddr_wen; + pcr.io.eret := io.ctrl.mem_eret; + pcr.io.exception := io.ctrl.exception; + pcr.io.cause := io.ctrl.cause; + pcr.io.pc := mem_reg_pc; + pcr.io.badvaddr_wen := io.ctrl.badvaddr_wen; // temporary debug outputs so things don't get optimized away io.debug.id_valid := id_reg_valid; io.debug.ex_valid := ex_reg_valid; io.debug.mem_valid := mem_reg_valid; - io.debug.wb_valid := wb_reg_valid; } diff --git a/rocket/src/main/scala/dpath_util.scala b/rocket/src/main/scala/dpath_util.scala index 2d4f6604..751bf796 100644 --- a/rocket/src/main/scala/dpath_util.scala +++ b/rocket/src/main/scala/dpath_util.scala @@ -51,7 +51,6 @@ class ioDpathPCR extends Bundle() val cause = UFix(5, 'input); val badvaddr_wen = Bool('input); val pc = UFix(VADDR_BITS, 'input); - val badvaddr = UFix(VADDR_BITS, 'input); val eret = Bool('input); val ei = Bool('input); val di = Bool('input); @@ -114,7 +113,7 @@ class rocketDpathPCR extends Component } when (io.badvaddr_wen) { - reg_badvaddr <== io.badvaddr; + reg_badvaddr <== io.w.data.toUFix; } when (io.exception && !reg_status_et) {