diff --git a/rocket/src/main/scala/consts.scala b/rocket/src/main/scala/consts.scala index e5660ca6..8b8c8740 100644 --- a/rocket/src/main/scala/consts.scala +++ b/rocket/src/main/scala/consts.scala @@ -21,6 +21,7 @@ object Constants val PC_J = UFix(4, 3); val PC_JR = UFix(5, 3); val PC_PCR = UFix(6, 3); + val PC_MEM = UFix(7, 3); val KF_Y = UFix(1, 1); val KF_N = UFix(0, 1); diff --git a/rocket/src/main/scala/cpu.scala b/rocket/src/main/scala/cpu.scala index a891582e..2e3374f7 100644 --- a/rocket/src/main/scala/cpu.scala +++ b/rocket/src/main/scala/cpu.scala @@ -39,57 +39,64 @@ class rocketProc extends Component val io = new ioRocket(); val ctrl = new rocketCtrl(); - val dpath = new rocketDpath(); - val mem = new rocketMemory(); - val wb = new rocketWriteback(); + val dpath = new rocketDpath(); +// val mem = new rocketMemory(); +// val wb = new rocketWriteback(); - dpath.io.host ^^ io.host; - dpath.io.debug ^^ io.debug; - // dpath.io.wb <> wb.io; - dpath.io.wb.wen <> wb.io.wb_wen; - dpath.io.wb.waddr <> wb.io.wb_waddr; - dpath.io.wb.wdata <> wb.io.wb_wdata; - dpath.io.imem.req_addr ^^ io.imem.req_addr; - dpath.io.imem.resp_data ^^ io.imem.resp_data; - - ctrl.io.ctrl <> dpath.io.ctrl; - ctrl.io.dpath <> dpath.io.dpath; - // ctrl.io.mem <> mem.io; - ctrl.io.mem.mrq_val <> mem.io.mem_mrq_val; - ctrl.io.mem.mrq_cmd <> mem.io.mem_mrq_cmd; - ctrl.io.mem.mrq_type <> mem.io.mem_mrq_type; - ctrl.io.mem.mrq_deq <> mem.io.mem_mrq_deq; - ctrl.io.mem.xsdq_rdy <> mem.io.mem_xsdq_rdy; - ctrl.io.mem.xsdq_val <> mem.io.mem_xsdq_val; - ctrl.io.mem.dc_busy := !io.dmem.req_rdy; + ctrl.io.dpath <> dpath.io.ctrl; ctrl.io.host.start ^^ io.host.start; ctrl.io.imem ^^ io.imem; + dpath.io.imem.req_addr ^^ io.imem.req_addr; + dpath.io.imem.resp_data ^^ io.imem.resp_data; + dpath.io.host ^^ io.host; + dpath.io.debug ^^ io.debug; + + ctrl.io.dmem ^^ io.dmem; + dpath.io.dmem ^^ io.dmem; + + // FIXME +// io.console.bits := dpath.io.dpath.rs1(7,0); + io.console.bits := Bits(0,8); + io.console.valid := ctrl.io.console.valid; + ctrl.io.console.rdy := io.console.rdy; + + // dpath.io.wb <> wb.io; +// dpath.io.wb.wen <> wb.io.wb_wen; +// dpath.io.wb.waddr <> wb.io.wb_waddr; +// dpath.io.wb.wdata <> wb.io.wb_wdata; + + +// ctrl.io.mem.mrq_val <> mem.io.mem_mrq_val; +// ctrl.io.mem.mrq_cmd <> mem.io.mem_mrq_cmd; +// ctrl.io.mem.mrq_type <> mem.io.mem_mrq_type; +// ctrl.io.mem.mrq_deq <> mem.io.mem_mrq_deq; +// ctrl.io.mem.xsdq_rdy <> mem.io.mem_xsdq_rdy; +// ctrl.io.mem.xsdq_val <> mem.io.mem_xsdq_val; +// ctrl.io.mem.dc_busy := !io.dmem.req_rdy; + // ctrl.io.console ^^ io.console; - ctrl.io.wb.waddr <> wb.io.wb_waddr; - ctrl.io.wb.wen <> wb.io.wb_wen; +// ctrl.io.wb.waddr <> wb.io.wb_waddr; +// ctrl.io.wb.wen <> wb.io.wb_wen; // TODO: SHOULD BE THE FOLLOWING BUT NEED BETTER INTERFACE CHUNKS // mem.io.dmem >< io.dmem; - mem.io.dmem_req_val ^^ io.dmem.req_val; - mem.io.dmem_req_rdy ^^ io.dmem.req_rdy; - mem.io.dmem_req_op ^^ io.dmem.req_op; - mem.io.dmem_req_addr ^^ io.dmem.req_addr; - mem.io.dmem_req_data ^^ io.dmem.req_data; - mem.io.dmem_req_wmask ^^ io.dmem.req_wmask; - mem.io.dmem_req_tag ^^ io.dmem.req_tag; +// mem.io.dmem_req_val ^^ io.dmem.req_val; +// mem.io.dmem_req_rdy ^^ io.dmem.req_rdy; +// mem.io.dmem_req_op ^^ io.dmem.req_op; +// mem.io.dmem_req_addr ^^ io.dmem.req_addr; +// mem.io.dmem_req_data ^^ io.dmem.req_data; +// mem.io.dmem_req_wmask ^^ io.dmem.req_wmask; +// mem.io.dmem_req_tag ^^ io.dmem.req_tag; - mem.io.dpath_rs2 <> dpath.io.dpath.rs2; - mem.io.dpath_waddr <> dpath.io.dpath.waddr; - mem.io.dpath_alu_out <> dpath.io.dpath.alu_out; +// +// mem.io.dpath_rs2 <> dpath.io.dpath.rs2; +// mem.io.dpath_waddr <> dpath.io.dpath.waddr; +// mem.io.dpath_alu_out <> dpath.io.dpath.alu_out; - wb.io.dmem_resp_val ^^ io.dmem.resp_val; - wb.io.dmem_resp_data ^^ io.dmem.resp_data; - wb.io.dmem_resp_tag ^^ io.dmem.resp_tag; - - io.console.bits := dpath.io.dpath.rs1(7,0); - io.console.valid := ctrl.io.console.valid; - ctrl.io.console.rdy := io.console.rdy; +// wb.io.dmem_resp_val ^^ io.dmem.resp_val; +// wb.io.dmem_resp_data ^^ io.dmem.resp_data; +// wb.io.dmem_resp_tag ^^ io.dmem.resp_tag; } } diff --git a/rocket/src/main/scala/ctrl.scala b/rocket/src/main/scala/ctrl.scala index 90899de1..8d6a7d22 100644 --- a/rocket/src/main/scala/ctrl.scala +++ b/rocket/src/main/scala/ctrl.scala @@ -6,14 +6,17 @@ import Node._; import Constants._ import Instructions._ -class ioCtrl extends Bundle() +class ioCtrlDpath extends Bundle() { + // outputs to datapath val sel_pc = UFix(3, 'output); val wen_btb = Bool('output); val stallf = Bool('output); val stalld = Bool('output); val killf = Bool('output); val killd = Bool('output); + val killx = Bool('output); + val killm = Bool('output); val ren2 = Bool('output); val ren1 = Bool('output); val sel_alu2 = UFix(2, 'output); @@ -26,7 +29,6 @@ class ioCtrl extends Bundle() val div_val = Bool('output); val div_fn = UFix(4, 'output); val div_wb = Bool('output); - val wen = Bool('output); val sel_wa = Bool('output); val sel_wb = UFix(3, 'output); val ren_pcr = Bool('output); @@ -36,56 +38,34 @@ class ioCtrl extends Bundle() val xcpt_fpu = Bool('output); val xcpt_syscall = Bool('output); val eret = Bool('output); -} - -class ioCtrlDpath extends Bundle() -{ + val dcache_miss = Bool('output); + val wen = Bool('output); + // inputs from datapath val btb_hit = Bool('input); - val inst = UFix(32, 'input); + val inst = Bits(32, 'input); val br_eq = Bool('input); val br_lt = Bool('input); val br_ltu = Bool('input); val div_rdy = Bool('input); val div_result_val = Bool('input); val mul_result_val = Bool('input); - val wen = Bool('input); - val waddr = UFix(5, 'input); + val ex_waddr = UFix(5,'input); // write addr from execute stage val exception = Bool('input); val status = Bits(8, 'input); -} - -class ioCtrlMem extends Bundle() -{ - val mrq_val = Bool('output); - val mrq_cmd = UFix(4, 'output); - val mrq_type = UFix(3, 'output); - val mrq_deq = Bool('input); - val xsdq_rdy = Bool('input); - val xsdq_val = Bool('output); - val dc_busy = Bool('input); -} - -class ioCtrlImem extends Bundle() -{ - val req_val = Bool('output); - val req_rdy = Bool('input); - val resp_val = Bool('input); -} - -class ioCtrlWB extends Bundle() -{ - val waddr = UFix(5, 'input); - val wen = Bool('input); + val sboard_set = Bool('input); + val sboard_seta = UFix(5, 'input); + val sboard_clr0 = Bool('input); + val sboard_clr0a = UFix(5, 'input); + val sboard_clr1 = Bool('input); + val sboard_clr1a = UFix(5, 'input); } class ioCtrlAll extends Bundle() { - val ctrl = new ioCtrl(); - val console = new ioConsole(List("rdy", "valid")); val dpath = new ioCtrlDpath(); - val imem = new ioCtrlImem(); - val mem = new ioCtrlMem(); - val wb = new ioCtrlWB(); + val console = new ioConsole(List("rdy", "valid")); + 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_val")).flip(); val host = new ioHost(List("start")); } @@ -219,47 +199,27 @@ class rocketCtrl extends Component val id_ren2 = id_renx2; val id_ren1 = id_renx1; - val id_console_out_val = id_wen_pcr & (id_raddr2 === PCR_CONSOLE); + val id_console_out_val = id_wen_pcr & (id_raddr2 === PCR_CONSOLE); + val console_out_fire = id_console_out_val & ~io.dpath.killd; + io.console.valid := console_out_fire.toBool; - val id_mem_val_masked = id_mem_val; - - val mem_xload_val = id_mem_val_masked & (id_mem_cmd === M_XRD); - val mem_xstore_val = id_mem_val_masked & (id_mem_cmd === M_XWR); - - val mem_fire = id_mem_val_masked & ~io.ctrl.killd; - val mem_xload_fire = mem_xload_val & ~io.ctrl.killd; - val mem_xstore_fire = mem_xstore_val & ~io.ctrl.killd; - - val console_out_fire = id_console_out_val & ~io.ctrl.killd; - - val div_fire = id_div_val & ~io.ctrl.killd; - val mul_fire = id_mul_val & ~io.ctrl.killd; - - val sboard_wen = mem_xload_fire | div_fire | mul_fire; - val sboard_waddr = id_waddr; - val sboard = new rocketCtrlSboard(); - sboard.io.raddra := id_raddr2; - sboard.io.raddrb := id_raddr1; - sboard.io.raddrc := id_waddr; - sboard.io.set := sboard_wen.toBool; - sboard.io.seta := sboard_waddr; - sboard.io.clr0 := io.wb.wen.toBool; - sboard.io.clr0a ^^ io.wb.waddr; - sboard.io.clr1 := io.dpath.wen.toBool; - sboard.io.clr1a := io.dpath.waddr; + sboard.io.raddra := id_raddr2.toUFix; + sboard.io.raddrb := id_raddr1.toUFix; + sboard.io.raddrc := id_waddr.toUFix; + + sboard.io.set := io.dpath.sboard_set; + sboard.io.seta := io.dpath.sboard_seta; + sboard.io.clr0 := io.dpath.sboard_clr0; + sboard.io.clr0a := io.dpath.sboard_clr0a; + sboard.io.clr1 := io.dpath.sboard_clr1; + sboard.io.clr1a := io.dpath.sboard_clr1a; val id_stall_raddr2 = sboard.io.stalla; val id_stall_raddr1 = sboard.io.stallb; val id_stall_waddr = sboard.io.stallc; val id_stall_ra = sboard.io.stallra; - val mrq = new rocketCtrlCnt(3, 4); - mrq.io.enq := mem_fire.toBool; - mrq.io.deq ^^ io.mem.mrq_deq; - val id_empty_mrq = mrq.io.empty; - val id_full_mrq = mrq.io.full; - val id_reg_btb_hit = Reg(width = 1, resetVal = Bool(false)); val ex_reg_br_type = Reg(){UFix(width = 4)}; val ex_reg_btb_hit = Reg(){Bool()}; @@ -269,15 +229,16 @@ class rocketCtrl extends Component val ex_reg_eret = Reg(resetVal = Bool(false)); val ex_reg_privileged = Reg(resetVal = Bool(false)); - when (!io.ctrl.stalld) { - when (io.ctrl.killf) { + when (!io.dpath.stalld) { + when (io.dpath.killf) { id_reg_btb_hit <== Bool(false); } otherwise{ id_reg_btb_hit <== io.dpath.btb_hit; } } - when (reset.toBool || io.ctrl.killd) { + + when (reset.toBool || io.dpath.killd) { ex_reg_br_type <== BR_N; ex_reg_btb_hit <== Bool(false); ex_reg_mem_val <== Bool(false); @@ -289,7 +250,7 @@ class rocketCtrl extends Component otherwise { ex_reg_br_type <== id_br_type; ex_reg_btb_hit <== id_reg_btb_hit; - ex_reg_mem_val <== id_mem_val_masked.toBool; + ex_reg_mem_val <== id_mem_val.toBool; ex_reg_mem_cmd <== id_mem_cmd; ex_reg_mem_type <== id_mem_type; ex_reg_eret <== id_eret.toBool; @@ -317,22 +278,42 @@ class rocketCtrl extends Component io.imem.req_val := io.host.start; // io.imem.req_val := Bool(true); - io.mem.mrq_val := ex_reg_mem_val; - io.mem.mrq_cmd := ex_reg_mem_cmd; - io.mem.mrq_type := ex_reg_mem_type; - io.mem.xsdq_val := mem_xstore_fire.toBool; - io.console.valid := console_out_fire.toBool; + io.dmem.req_val := ex_reg_mem_val && ~io.dpath.killx; + io.dmem.req_cmd := ex_reg_mem_cmd; + io.dmem.req_type := ex_reg_mem_type; - io.ctrl.sel_pc := + val mem_reg_mem_val = Reg(){Bool()}; + val mem_reg_mem_cmd = Reg(){UFix(width = 4)}; + val mem_reg_mem_type = Reg(){UFix(width = 3)}; + + when (reset.toBool || io.dpath.killx) { + mem_reg_mem_val <== Bool(false); + mem_reg_mem_cmd <== UFix(0, 4); + mem_reg_mem_type <== UFix(0, 3); + } + otherwise { + mem_reg_mem_val <== ex_reg_mem_val; + mem_reg_mem_cmd <== ex_reg_mem_cmd; + mem_reg_mem_type <== ex_reg_mem_type; + } + + // replay on a D$ load miss : FIXME - add a miss signal to D$ + val replay_mem = mem_reg_mem_val && (mem_reg_mem_cmd === M_XRD) && !io.dmem.resp_val; + val dcache_miss = Reg(replay_mem); + + io.dpath.dcache_miss := dcache_miss; + + io.dpath.sel_pc := + Mux(replay_mem, PC_MEM, Mux(io.dpath.exception || ex_reg_eret, PC_PCR, Mux(!ex_reg_btb_hit && br_taken, PC_BR, Mux(ex_reg_btb_hit && !br_taken || ex_reg_privileged, PC_EX4, Mux(jr_taken, PC_JR, Mux(j_taken, PC_J, Mux(io.dpath.btb_hit, PC_BTB, - PC_4)))))); + PC_4))))))); - io.ctrl.wen_btb := ~ex_reg_btb_hit & br_taken; + io.dpath.wen_btb := ~ex_reg_btb_hit & br_taken; val take_pc = ~ex_reg_btb_hit & br_taken | @@ -341,65 +322,86 @@ class rocketCtrl extends Component j_taken | io.dpath.exception | ex_reg_privileged | - ex_reg_eret; + ex_reg_eret | + replay_mem; - io.ctrl.stallf := + io.dpath.stallf := ~take_pc & ( ~io.imem.req_rdy | ~io.imem.resp_val | - io.ctrl.stalld + io.dpath.stalld ); - val ctrl_stalld_wo_fpu_rdy = + // check for loads in execute stage to detect load/use hazards + val lu_stall_raddr1 = + ex_reg_mem_val && + (ex_reg_mem_cmd === M_XRD) && + id_ren1.toBool && + (id_raddr1 === io.dpath.ex_waddr); + + val lu_stall_raddr2 = + ex_reg_mem_val && + (ex_reg_mem_cmd === M_XRD) && + id_ren2.toBool && + (id_raddr2 === io.dpath.ex_waddr); + + val ctrl_stalld = ~take_pc & ( - id_ren2 & id_stall_raddr2 | - id_ren1 & id_stall_raddr1 | - (id_sel_wa === WA_RD) & id_stall_waddr | + lu_stall_raddr1 | + lu_stall_raddr2 | + id_ren2 & id_stall_raddr2 | + id_ren1 & id_stall_raddr1 | + (id_sel_wa === WA_RD) && id_stall_waddr | (id_sel_wa === WA_RA) & id_stall_ra | - id_mem_val_masked & id_full_mrq | - id_sync & (~id_empty_mrq | io.mem.dc_busy) | - mem_xstore_val & ~io.mem.xsdq_rdy | + id_mem_val & ~io.dmem.req_rdy | + id_sync & ~io.dmem.req_rdy | +// id_mem_val_masked & id_full_mrq | +// id_sync & (~id_empty_mrq | io.mem.dc_busy) | +// mem_xstore_val & ~io.mem.xsdq_rdy | id_console_out_val & ~io.console.rdy | id_div_val & ~io.dpath.div_rdy | io.dpath.div_result_val | io.dpath.mul_result_val ); + val ctrl_killd = take_pc | ctrl_stalld; + // for divider, multiplier writeback val mul_wb = io.dpath.mul_result_val; val div_wb = io.dpath.div_result_val & !mul_wb; - io.ctrl.stalld := ctrl_stalld_wo_fpu_rdy.toBool; + io.dpath.stalld := ctrl_stalld.toBool; - io.ctrl.killf := take_pc | ~io.imem.resp_val; - val ctrl_killd_wo_fpu_rdy = take_pc | ctrl_stalld_wo_fpu_rdy; - io.ctrl.killd := ctrl_killd_wo_fpu_rdy.toBool; + io.dpath.killf := take_pc | ~io.imem.resp_val; + io.dpath.killd := ctrl_killd.toBool; + io.dpath.killx := replay_mem.toBool; + io.dpath.killm := replay_mem.toBool; - io.ctrl.ren2 := id_ren2.toBool; - io.ctrl.ren1 := id_ren1.toBool; - io.ctrl.sel_alu2 := id_sel_alu2; - io.ctrl.sel_alu1 := id_sel_alu1.toBool; - io.ctrl.fn_dw := id_fn_dw.toBool; - io.ctrl.fn_alu := id_fn_alu; - io.ctrl.div_fn := id_div_fn; - io.ctrl.div_val := id_div_val.toBool; - io.ctrl.div_wb := div_wb; - io.ctrl.mul_fn := id_mul_fn; - io.ctrl.mul_val := id_mul_val.toBool; - io.ctrl.mul_wb := mul_wb; - io.ctrl.wen := id_wen.toBool; - io.ctrl.sel_wa := id_sel_wa.toBool; - io.ctrl.sel_wb := id_sel_wb; - io.ctrl.ren_pcr := id_ren_pcr.toBool; - io.ctrl.wen_pcr := id_wen_pcr.toBool; - io.ctrl.eret := id_eret.toBool; + io.dpath.ren2 := id_ren2.toBool; + io.dpath.ren1 := id_ren1.toBool; + io.dpath.sel_alu2 := id_sel_alu2; + io.dpath.sel_alu1 := id_sel_alu1.toBool; + io.dpath.fn_dw := id_fn_dw.toBool; + io.dpath.fn_alu := id_fn_alu; + io.dpath.div_fn := id_div_fn; + io.dpath.div_val := id_div_val.toBool; + io.dpath.div_wb := div_wb; + io.dpath.mul_fn := id_mul_fn; + io.dpath.mul_val := id_mul_val.toBool; + io.dpath.mul_wb := mul_wb; + io.dpath.wen := id_wen.toBool; + io.dpath.sel_wa := id_sel_wa.toBool; + 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.ctrl.xcpt_illegal := ~id_int_val.toBool; - io.ctrl.xcpt_privileged := (id_privileged & ~io.dpath.status(5)).toBool; - io.ctrl.xcpt_fpu := Bool(false); - io.ctrl.xcpt_syscall := id_syscall.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; } } diff --git a/rocket/src/main/scala/dcache.scala b/rocket/src/main/scala/dcache.scala index eb24aacc..0bddf7d4 100644 --- a/rocket/src/main/scala/dcache.scala +++ b/rocket/src/main/scala/dcache.scala @@ -9,10 +9,10 @@ import scala.math._; class ioDmem(view: List[String] = null) extends Bundle(view) { val req_val = Bool('input); val req_rdy = Bool('output); - val req_op = Bits(4, 'input); + val req_cmd = Bits(4, 'input); + val req_type = Bits(3, 'input); val req_addr = UFix(32, 'input); val req_data = Bits(64, 'input); - val req_wmask = Bits(8, 'input); val req_tag = Bits(12, 'input); val resp_val = Bool('output); val resp_data = Bits(64, 'output); @@ -58,7 +58,7 @@ class rocketDCacheDM_flush(lines: Int, addrbits: Int) extends Component { val flush_waiting = Reg(resetVal = Bool(false)); val r_cpu_req_tag = Reg(resetVal = Bits(0, 12)); - when (io.cpu.req_val && io.cpu.req_rdy && (io.cpu.req_op === M_FLA)) + when (io.cpu.req_val && io.cpu.req_rdy && (io.cpu.req_cmd === M_FLA)) { r_cpu_req_tag <== io.cpu.req_tag; flushing <== Bool(true); @@ -75,12 +75,12 @@ class rocketDCacheDM_flush(lines: Int, addrbits: Int) extends Component { when (flush_waiting && dcache.io.cpu.resp_val && (dcache.io.cpu.resp_tag === r_cpu_req_tag)) { flush_resp_count <== flush_resp_count + UFix(1,1); } - dcache.io.cpu.req_val := (io.cpu.req_val && (io.cpu.req_op != M_FLA) && !flush_waiting) || flushing; - dcache.io.cpu.req_op := Mux(flushing, M_FLA, io.cpu.req_op); + dcache.io.cpu.req_val := (io.cpu.req_val && (io.cpu.req_cmd != M_FLA) && !flush_waiting) || flushing; + dcache.io.cpu.req_cmd := Mux(flushing, M_FLA, io.cpu.req_cmd); dcache.io.cpu.req_addr := Mux(flushing, Cat(Bits(0,tagmsb-taglsb+1), flush_count, Bits(0,offsetbits)).toUFix, io.cpu.req_addr); dcache.io.cpu.req_tag := Mux(flushing, r_cpu_req_tag, io.cpu.req_tag); + dcache.io.cpu.req_type := io.cpu.req_type; dcache.io.cpu.req_data ^^ io.cpu.req_data; - dcache.io.cpu.req_wmask ^^ io.cpu.req_wmask; dcache.io.mem ^^ io.mem; io.cpu.req_rdy := dcache.io.cpu.req_rdy && !flush_waiting; @@ -96,7 +96,7 @@ class rocketDCacheDM_flush(lines: Int, addrbits: Int) extends Component { // lines = # of cache lines // addr_bits = address width (word addressable) bits // 64 bit wide cpu port, 128 bit wide memory port, 64 byte cachelines - +/* class rocketDCacheDM(lines: Int, addrbits: Int) extends Component { val io = new ioDCacheDM(); @@ -116,7 +116,7 @@ class rocketDCacheDM(lines: Int, addrbits: Int) extends Component { val r_r_cpu_req_addr = Reg(r_cpu_req_addr); val r_cpu_req_val = Reg(Bool(false)); val r_cpu_req_data = Reg(Bits(0,64)); - val r_cpu_req_op = Reg(Bits(0,4)); + val r_cpu_req_cmd = Reg(Bits(0,4)); val r_cpu_req_wmask = Reg(Bits(0,8)); val r_cpu_req_tag = Reg(Bits(0,12)); val r_cpu_resp_tag = Reg(r_cpu_req_tag); @@ -125,13 +125,13 @@ class rocketDCacheDM(lines: Int, addrbits: Int) extends Component { when (io.cpu.req_val && io.cpu.req_rdy) { r_cpu_req_addr <== io.cpu.req_addr; r_cpu_req_data <== io.cpu.req_data; - r_cpu_req_op <== io.cpu.req_op; + r_cpu_req_cmd <== io.cpu.req_cmd; r_cpu_req_wmask <== io.cpu.req_wmask; r_cpu_req_tag <== io.cpu.req_tag; } - val req_load = (r_cpu_req_op === M_XRD); - val req_store = (r_cpu_req_op === M_XWR); - val req_flush = (r_cpu_req_op === M_FLA); + val req_load = (r_cpu_req_cmd === M_XRD); + val req_store = (r_cpu_req_cmd === M_XWR); + val req_flush = (r_cpu_req_cmd === M_FLA); when (io.cpu.req_rdy) { r_cpu_req_val <== io.cpu.req_val; } otherwise { r_cpu_req_val <== Bool(false); } @@ -248,6 +248,7 @@ class rocketDCacheDM(lines: Int, addrbits: Int) extends Component { } } } +*/ class rocketDCacheDM_1C(lines: Int, addrbits: Int) extends Component { val io = new ioDCacheDM(); @@ -267,24 +268,26 @@ class rocketDCacheDM_1C(lines: Int, addrbits: Int) extends Component { val r_cpu_req_addr = Reg(resetVal = Bits(0, addrbits)); val r_cpu_req_val = Reg(resetVal = Bool(false)); val r_cpu_req_data = Reg(resetVal = Bits(0,64)); - val r_cpu_req_op = Reg(resetVal = Bits(0,4)); - val r_cpu_req_wmask = Reg(resetVal = Bits(0,8)); - val r_cpu_req_tag = Reg(resetVal = Bits(0,12)); + val r_cpu_req_cmd = Reg(resetVal = Bits(0,4)); + val r_cpu_req_type = Reg(resetVal = Bits(0,3)); +// val r_cpu_req_wmask = Reg(resetVal = Bits(0,8)); + val r_cpu_req_tag = Reg(resetVal = Bits(0,5)); val p_store_data = Reg(resetVal = Bits(0,64)); val p_store_addr = Reg(resetVal = Bits(0,64)); val p_store_wmask = Reg(resetVal = Bits(0,64)); val p_store_valid = Reg(resetVal = Bool(false)); - val req_load = (r_cpu_req_op === M_XRD); - val req_store = (r_cpu_req_op === M_XWR); - val req_flush = (r_cpu_req_op === M_FLA); + val req_load = (r_cpu_req_cmd === M_XRD); + val req_store = (r_cpu_req_cmd === M_XWR); + val req_flush = (r_cpu_req_cmd === M_FLA); when (io.cpu.req_val && io.cpu.req_rdy) { r_cpu_req_addr <== io.cpu.req_addr; r_cpu_req_data <== io.cpu.req_data; - r_cpu_req_op <== io.cpu.req_op; - r_cpu_req_wmask <== io.cpu.req_wmask; + r_cpu_req_cmd <== io.cpu.req_cmd; + r_cpu_req_type <== io.cpu.req_type; +// r_cpu_req_wmask <== io.cpu.req_wmask; r_cpu_req_tag <== io.cpu.req_tag; } @@ -325,10 +328,51 @@ class rocketDCacheDM_1C(lines: Int, addrbits: Int) extends Component { val tag_valid = vb_rdata.toBool; val tag_match = tag_valid && (tag_rdata === r_cpu_req_addr(tagmsb, taglsb)); + // generate write mask and store data signals based on store type and address LSBs + val wmask_b = + Mux(r_cpu_req_addr(2,0) === UFix(0, 3), Bits("b0000_0001", 8), + Mux(r_cpu_req_addr(2,0) === UFix(1, 3), Bits("b0000_0010", 8), + Mux(r_cpu_req_addr(2,0) === UFix(2, 3), Bits("b0000_0100", 8), + Mux(r_cpu_req_addr(2,0) === UFix(3, 3), Bits("b0000_1000", 8), + Mux(r_cpu_req_addr(2,0) === UFix(4, 3), Bits("b0001_0000", 8), + Mux(r_cpu_req_addr(2,0) === UFix(5, 3), Bits("b0010_0000", 8), + Mux(r_cpu_req_addr(2,0) === UFix(6, 3), Bits("b0100_0000", 8), + Mux(r_cpu_req_addr(2,0) === UFix(7, 3), Bits("b1000_0000", 8), + UFix(0, 8))))))))); + + val wmask_h = + Mux(r_cpu_req_addr(2,1) === UFix(0, 2), Bits("b0000_0011", 8), + Mux(r_cpu_req_addr(2,1) === UFix(1, 2), Bits("b0000_1100", 8), + Mux(r_cpu_req_addr(2,1) === UFix(2, 2), Bits("b0011_0000", 8), + Mux(r_cpu_req_addr(2,1) === UFix(3, 2), Bits("b1100_0000", 8), + UFix(0, 8))))); + + val wmask_w = + Mux(r_cpu_req_addr(2) === UFix(0, 1), Bits("b0000_1111", 8), + Mux(r_cpu_req_addr(2) === UFix(1, 1), Bits("b1111_0000", 8), + UFix(0, 8))); + + val wmask_d = + Bits("b1111_1111", 8); + + val store_wmask = + Mux(r_cpu_req_type === MT_B, wmask_b, + Mux(r_cpu_req_type === MT_H, wmask_h, + Mux(r_cpu_req_type === MT_W, wmask_w, + Mux(r_cpu_req_type === MT_D, wmask_d, + UFix(0, 8))))); + + val store_data = + Mux(r_cpu_req_type === MT_B, Fill(8, r_cpu_req_data( 7,0)), + Mux(r_cpu_req_type === MT_H, Fill(4, r_cpu_req_data(15,0)), + Mux(r_cpu_req_type === MT_W, Fill(2, r_cpu_req_data(31,0)), + Mux(r_cpu_req_type === MT_D, r_cpu_req_data, + UFix(0, 64))))); + when ((state === s_ready) && r_cpu_req_val && req_store) { - p_store_data <== r_cpu_req_data; + p_store_data <== store_data; p_store_addr <== r_cpu_req_addr; - p_store_wmask <== r_cpu_req_wmask; + p_store_wmask <== store_wmask; p_store_valid <== Bool(true); } @@ -370,14 +414,14 @@ class rocketDCacheDM_1C(lines: Int, addrbits: Int) extends Component { Fill(8, p_store_wmask(1)), Fill(8, p_store_wmask(0))); - val store_wmask = + val da_store_wmask = Mux(p_store_addr(offsetlsb).toBool, Cat(p_wmask_expand, Bits(0,64)), Cat(Bits(0,64), p_wmask_expand)); val data_array_wmask = Mux((state === s_refill), ~Bits(0,128), - store_wmask); + da_store_wmask); val data_array = Mem(lines*4, data_array_we, data_array_waddr, data_array_wdata, wrMask = data_array_wmask, resetVal = null); val data_array_raddr = Mux((state === s_writeback) && io.mem.req_rdy, Cat(r_cpu_req_addr(indexmsb, indexlsb), rr_count_next).toUFix, @@ -394,7 +438,7 @@ class rocketDCacheDM_1C(lines: Int, addrbits: Int) extends Component { io.cpu.resp_val := ((state === s_ready) && r_cpu_req_val && tag_match && req_load && !(p_store_valid && addr_match)) || ((state === s_resolve_miss) && req_flush); - io.cpu.resp_tag := r_cpu_req_tag; + io.cpu.resp_tag := Cat(Bits(0,1), r_cpu_req_type, r_cpu_req_addr(2,0), r_cpu_req_tag); io.cpu.resp_data := Mux(r_cpu_req_addr(offsetlsb).toBool, data_array_rdata(127, 64), diff --git a/rocket/src/main/scala/dpath.scala b/rocket/src/main/scala/dpath.scala index 6c7e5287..f9039a0a 100644 --- a/rocket/src/main/scala/dpath.scala +++ b/rocket/src/main/scala/dpath.scala @@ -5,46 +5,13 @@ import Node._; import Constants._ import Instructions._ -class ioDpath extends Bundle() -{ - val btb_hit = Bool('output); - val inst = Bits(32, 'output); - val rs2 = Bits(64, 'output); - val rs1 = Bits(64, 'output); - val br_eq = Bool('output); - val br_lt = Bool('output); - val br_ltu = Bool('output); - val div_result_val = Bool('output); - val div_rdy = Bool('output); - val mul_result_val = Bool('output); - val wen = Bool('output); - val waddr = UFix(5, 'output); - val alu_out = UFix(64, 'output); - val exception = Bool('output); - val status = Bits(8, 'output); -} - -class ioDpathImem extends Bundle() -{ - val req_addr = UFix(32, 'output); - val resp_data = Bits(32, 'input); -} - -class ioDpathWB extends Bundle() -{ - val waddr = UFix(5, 'input); - val wen = Bool('input); - val wdata = Bits(64, 'input); -} - class ioDpathAll extends Bundle() { - val dpath = new ioDpath(); val host = new ioHost(); - val ctrl = new ioCtrl().flip(); + val ctrl = new ioCtrlDpath().flip(); val debug = new ioDebug(); - val wb = new ioDpathWB(); - val imem = new ioDpathImem(); + val dmem = new ioDmem(List("req_addr", "req_data", "req_tag", "resp_val", "resp_tag", "resp_data")).flip(); + val imem = new ioImem(List("req_addr", "resp_data")).flip(); } class rocketDpath extends Component @@ -77,37 +44,60 @@ class rocketDpath extends Component val if_reg_pc = Reg(width = 32, resetVal = UFix(0, 32)); // instruction decode definitions - val id_reg_pc = Reg(){UFix(width = 32)}; - val id_reg_pc_plus4 = Reg(){UFix(width = 32)}; - val id_reg_inst = Reg(width = 32, resetVal = NOP); + val id_reg_pc = Reg(resetVal = UFix(0,32)); + val id_reg_pc_plus4 = Reg(resetVal = UFix(0,32)); + val id_reg_inst = Reg(resetVal = NOP); // execute definitions - val ex_reg_pc = Reg(width = 32, resetVal = UFix(0, 32)); - val ex_reg_pc_plus4 = Reg(width = 32, resetVal = UFix(0, 32)); - val ex_reg_inst = Reg(width = 32, resetVal = Bits(0, 32)); - val ex_reg_raddr2 = Reg(width = 5, resetVal = UFix(0, 5)); - val ex_reg_raddr1 = Reg(width = 5, resetVal = UFix(0, 5)); - val ex_reg_rs2 = Reg(width = 64, resetVal = Bits(0, 64)); - val ex_reg_rs1 = Reg(width = 64, resetVal = Bits(0, 64)); - val ex_reg_waddr = Reg(width = 5, resetVal = UFix(0, 5)); - val ex_reg_ctrl_sel_alu2 = Reg(width = 2, resetVal = A2_X); - val ex_reg_ctrl_sel_alu1 = Reg(width = 1, resetVal = A1_X); - val ex_reg_ctrl_fn_dw = Reg(width = 1, resetVal = DW_X); - val ex_reg_ctrl_fn_alu = Reg(width = 4, resetVal = FN_X); - val ex_reg_ctrl_ll_wb = Reg(width = 1, resetVal = Bool(false)); - val ex_reg_ctrl_mul_val = Reg(width = 1, resetVal = Bool(false)); - val ex_reg_ctrl_mul_fn = Reg(width = 3, resetVal = MUL_X); - val ex_reg_ctrl_div_val = Reg(width = 1, resetVal = Bool(false)); - val ex_reg_ctrl_div_fn = Reg(width = 4, resetVal = DIV_X); - val ex_reg_ctrl_sel_wb = Reg(width = 3, resetVal = WB_X); - val ex_reg_ctrl_wen = Reg(width = 1, resetVal = Bool(false)); - val ex_reg_ctrl_ren_pcr = Reg(width = 1, resetVal = Bool(false)); - val ex_reg_ctrl_wen_pcr = Reg(width = 1, resetVal = Bool(false)); - val ex_reg_ctrl_eret = Reg(width = 1, resetVal = Bool(false)); - val ex_reg_ctrl_exception = Reg(width = 1, resetVal = Bool(false)); - val ex_reg_ctrl_cause = Reg(width = 5, resetVal = UFix(0,5)); - val ex_wdata = Wire() { Bits() }; - + val ex_reg_pc = Reg(resetVal = UFix(0,32)); + val ex_reg_pc_plus4 = Reg(resetVal = UFix(0,32)); + val ex_reg_inst = Reg(resetVal = Bits(0,32)); + val ex_reg_raddr2 = Reg(resetVal = UFix(0,5)); + val ex_reg_raddr1 = Reg(resetVal = UFix(0,5)); + val ex_reg_rs2 = Reg(resetVal = Bits(0,64)); + val ex_reg_rs1 = Reg(resetVal = Bits(0,64)); + 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_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)); + val ex_reg_ctrl_mul_val = Reg(resetVal = Bool(false)); + val ex_reg_ctrl_mul_fn = Reg(resetVal = MUL_X); + val ex_reg_ctrl_div_val = Reg(resetVal = Bool(false)); + val ex_reg_ctrl_div_fn = Reg(resetVal = DIV_X); + val ex_reg_ctrl_sel_wb = Reg(resetVal = WB_X); + 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_reg_ctrl_exception = Reg(resetVal = Bool(false)); + val ex_reg_ctrl_cause = Reg(resetVal = UFix(0,5)); + val ex_wdata = Wire() { Bits() }; + + val mem_reg_pc = Reg(resetVal = UFix(0,32)); + val mem_reg_pc_plus4 = Reg(resetVal = UFix(0,32)); + 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_ctrl_ll_wb = Reg(resetVal = Bool(false)); + val mem_reg_ctrl_div_val = Reg(resetVal = Bool(false)); + val mem_reg_ctrl_mul_val = Reg(resetVal = Bool(false)); + val mem_reg_ctrl_wen = Reg(resetVal = Bool(false)); + val mem_reg_ctrl_wen_pcr = Reg(resetVal = Bool(false)); + val mem_reg_ctrl_exception = Reg(resetVal = Bool(false)); + + val wb_reg_pc = Reg(resetVal = UFix(0,32)); + val wb_reg_pc_plus4 = Reg(resetVal = UFix(0,32)); + 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_div_val = Reg(resetVal = Bool(false)); + val wb_reg_ctrl_mul_val = Reg(resetVal = Bool(false)); + val wb_reg_ctrl_wen = Reg(resetVal = Bool(false)); + val wb_reg_ctrl_wen_pcr = Reg(resetVal = Bool(false)); + // instruction fetch stage val if_pc_plus4 = if_reg_pc + UFix(4, 32); @@ -132,7 +122,8 @@ class rocketDpath extends Component 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, ex_pcr(31,0).toUFix, - UFix(0, 32)))))))); + Mux(io.ctrl.sel_pc === PC_MEM, mem_reg_pc, + UFix(0, 32))))))))); when (!io.host.start){ if_reg_pc <== UFix(0, 32); //32'hFFFF_FFFC; @@ -146,7 +137,7 @@ class rocketDpath extends Component if_next_pc); btb.io.current_pc4 := if_pc_plus4; - btb.io.hit ^^ io.dpath.btb_hit; + btb.io.hit ^^ io.ctrl.btb_hit; btb.io.wen ^^ io.ctrl.wen_btb; btb.io.correct_pc4 := ex_reg_pc_plus4; @@ -174,6 +165,7 @@ class rocketDpath extends Component rfile.io.r1.addr := id_raddr1; val id_rdata1 = rfile.io.r1.data; + // destination register selection val id_waddr = Mux(io.ctrl.div_wb, div_result_tag, Mux(io.ctrl.mul_wb, mul_result_tag, @@ -181,16 +173,22 @@ class rocketDpath extends Component Mux(io.ctrl.sel_wa === WA_RA, RA, UFix(0, 5))))); + // bypass muxes val id_rs1 = Mux(io.ctrl.div_wb, div_result, Mux(io.ctrl.mul_wb, mul_result, - Mux(id_raddr1 != UFix(0, 5) && ex_reg_ctrl_wen && id_raddr1 === ex_reg_waddr, ex_wdata, - id_rdata1))); + Mux(id_raddr1 != UFix(0, 5) && ex_reg_ctrl_wen && id_raddr1 === ex_reg_waddr, ex_wdata, + Mux(id_raddr1 != UFix(0, 5) && mem_reg_ctrl_wen && id_raddr1 === mem_reg_waddr, mem_reg_wdata, + Mux(id_raddr1 != UFix(0, 5) && wb_reg_ctrl_wen && id_raddr1 === wb_reg_waddr, wb_reg_wdata, + id_rdata1))))); val id_rs2 = - Mux(id_raddr2 != UFix(0, 5) && ex_reg_ctrl_wen && id_raddr2 === ex_reg_waddr, ex_wdata, - id_rdata2); + Mux(id_raddr2 != UFix(0, 5) && ex_reg_ctrl_wen && id_raddr2 === ex_reg_waddr, ex_wdata, + Mux(id_raddr2 != UFix(0, 5) && mem_reg_ctrl_wen && id_raddr2 === mem_reg_waddr, mem_reg_wdata, + 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; val id_cause = Mux(io.ctrl.xcpt_illegal, UFix(2,5), @@ -199,9 +197,9 @@ class rocketDpath extends Component Mux(io.ctrl.xcpt_syscall, UFix(6,5), UFix(0,5))))); - io.dpath.inst := id_reg_inst; - io.dpath.rs1 := id_rs1; - io.dpath.rs2 := id_rs2; + io.ctrl.inst := id_reg_inst; +// io.ctrl.rs1 := id_rs1; +// io.ctrl.rs2 := id_rs2; // execute stage ex_reg_pc <== id_reg_pc; @@ -269,8 +267,8 @@ class rocketDpath extends Component div.io.dpath_rs2 := ex_reg_rs2; div.io.div_result_rdy := io.ctrl.div_wb; - io.dpath.div_rdy := div.io.div_rdy; - io.dpath.div_result_val := div.io.div_result_val; + io.ctrl.div_rdy := div.io.div_rdy; + io.ctrl.div_result_val := div.io.div_result_val; // multiplier mul.io.mul_val := ex_reg_ctrl_mul_val; @@ -279,66 +277,145 @@ class rocketDpath extends Component mul.io.in0 := ex_reg_rs1; mul.io.in1 := ex_reg_rs2; - io.dpath.mul_result_val := mul.io.result_val; + io.ctrl.mul_result_val := mul.io.result_val; + + io.ctrl.ex_waddr := ex_reg_waddr; // for load/use hazard detection - // processor control register i/o - pcr.io.host.from_wen ^^ io.host.from_wen; - pcr.io.host.from ^^ io.host.from; - pcr.io.host.to ^^ io.host.to; + // D$ request interface (registered inside D$ module) + // other signals (req_val, req_rdy) connect to control module + io.dmem.req_addr := ex_alu_out; + io.dmem.req_data := ex_reg_rs2; + 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.addr := Mux(ex_reg_ctrl_exception, PCR_EVEC, Mux(ex_reg_ctrl_eret, PCR_EPC, ex_reg_raddr2)); - - pcr.io.w.addr := ex_reg_raddr2; - pcr.io.w.en := ex_reg_ctrl_wen_pcr; - pcr.io.w.data := ex_reg_rs1; - + + pcr.io.host.from_wen ^^ io.host.from_wen; + pcr.io.host.from ^^ io.host.from; + pcr.io.host.to ^^ io.host.to; + pcr.io.eret := ex_reg_ctrl_eret; pcr.io.exception := ex_reg_ctrl_exception; pcr.io.cause := ex_reg_ctrl_cause; pcr.io.pc := ex_reg_pc; - io.dpath.status := pcr.io.status; -// io.debug ^^ pcr.io.debug; - + io.ctrl.status := pcr.io.status; io.debug.error_mode := pcr.io.debug.error_mode; io.debug.log_control := pcr.io.debug.log_control; - + // branch resolution logic - io.dpath.br_eq := (ex_reg_rs1 === ex_reg_rs2); - io.dpath.br_ltu := (ex_reg_rs1.toUFix < ex_reg_rs2.toUFix); - io.dpath.br_lt := - (~(ex_reg_rs1(63) ^ ex_reg_rs2(63)) & io.dpath.br_ltu | + io.ctrl.br_eq := (ex_reg_rs1 === ex_reg_rs2); + io.ctrl.br_ltu := (ex_reg_rs1.toUFix < ex_reg_rs2.toUFix); + io.ctrl.br_lt := + (~(ex_reg_rs1(63) ^ ex_reg_rs2(63)) & io.ctrl.br_ltu | ex_reg_rs1(63) & ~ex_reg_rs2(63)).toBool; - io.dpath.alu_out := ex_alu_out; - // writeback select mux ex_wdata := - Mux(ex_reg_ctrl_ll_wb, ex_reg_rs1, + Mux(ex_reg_ctrl_ll_wb || ex_reg_ctrl_wen_pcr, ex_reg_rs1, Mux(ex_reg_ctrl_sel_wb === WB_PC, ex_reg_pc_plus4, Mux(ex_reg_ctrl_sel_wb === WB_ALU, ex_alu_out, Mux(ex_reg_ctrl_sel_wb === WB_PCR, ex_pcr, Bits(0, 64))))).toBits; - // regfile write - rfile.io.w0.addr := ex_reg_waddr; - rfile.io.w0.en := ex_reg_ctrl_wen | ex_reg_ctrl_ll_wb; - rfile.io.w0.data := ex_wdata; - - rfile.io.w1.addr ^^ io.wb.waddr; - rfile.io.w1.en ^^ io.wb.wen; - rfile.io.w1.data ^^ io.wb.wdata; - - // clear scoreboard for "long latency" writebacks - io.dpath.wen := ex_reg_ctrl_ll_wb; - io.dpath.waddr := ex_reg_waddr; + // memory stage + mem_reg_pc <== ex_reg_pc; + mem_reg_pc_plus4 <== ex_reg_pc_plus4; + 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_ctrl_div_val <== Bool(false); + mem_reg_ctrl_mul_val <== Bool(false); + mem_reg_ctrl_wen <== Bool(false); + mem_reg_ctrl_wen_pcr <== Bool(false); + mem_reg_ctrl_exception <== Bool(false); + } + otherwise { + mem_reg_ctrl_div_val <== ex_reg_ctrl_div_val; + mem_reg_ctrl_mul_val <== ex_reg_ctrl_mul_val; + 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.dpath.exception := ex_reg_ctrl_exception; + io.ctrl.exception := mem_reg_ctrl_exception; + + // writeback stage + val r_dmem_resp_val = Reg(io.dmem.resp_val); + val r_dmem_resp_waddr = Reg(io.dmem.resp_tag(4,0).toUFix); + val r_dmem_resp_pos = Reg(io.dmem.resp_tag(7,5)); + val r_dmem_resp_type = Reg(io.dmem.resp_tag(9,8)); + val r_dmem_resp_data = Reg(io.dmem.resp_data); + + wb_reg_pc <== mem_reg_pc; + wb_reg_pc_plus4 <== mem_reg_pc_plus4; + 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; + + when (io.ctrl.killm) { + wb_reg_ctrl_div_val <== Bool(false); + wb_reg_ctrl_mul_val <== Bool(false); + wb_reg_ctrl_wen <== Bool(false); + wb_reg_ctrl_wen_pcr <== Bool(false); + } + otherwise { + wb_reg_ctrl_div_val <== mem_reg_ctrl_div_val; + wb_reg_ctrl_mul_val <== mem_reg_ctrl_mul_val; + wb_reg_ctrl_wen <== mem_reg_ctrl_wen; + wb_reg_ctrl_wen_pcr <== mem_reg_ctrl_wen_pcr; + } + + // crossbar/sign extension for 8/16/32 bit loads + val dmem_resp_data_w = + Mux(r_dmem_resp_pos(2).toBool, r_dmem_resp_data(63, 32), r_dmem_resp_data(31, 0)); + val dmem_resp_data_h = + Mux(r_dmem_resp_pos(1).toBool, dmem_resp_data_w(31, 16), dmem_resp_data_w(15, 0)); + val dmem_resp_data_b = + Mux(r_dmem_resp_pos(0).toBool, dmem_resp_data_h(15, 8), dmem_resp_data_h(7, 0)); + + val dmem_resp_data_final = + Mux(r_dmem_resp_type === MT_B, Cat(Fill(56, dmem_resp_data_b(7)), dmem_resp_data_b), + Mux(r_dmem_resp_type === MT_BU, Cat(UFix(0, 56), dmem_resp_data_b), + Mux(r_dmem_resp_type === MT_H, Cat(Fill(48, dmem_resp_data_h(15)), dmem_resp_data_h), + Mux(r_dmem_resp_type === MT_HU, Cat(UFix(0, 48), dmem_resp_data_h), + Mux(r_dmem_resp_type === MT_W, Cat(Fill(32, dmem_resp_data_w(31)), dmem_resp_data_w), + Mux(r_dmem_resp_type === MT_WU, Cat(UFix(0, 32), dmem_resp_data_w), + Mux(r_dmem_resp_type === MT_D, r_dmem_resp_data, + UFix(0, 64)))))))); + + // regfile write + rfile.io.w0.addr := wb_reg_waddr; + rfile.io.w0.en := wb_reg_ctrl_wen | wb_reg_ctrl_ll_wb; + rfile.io.w0.data := wb_reg_wdata; + + rfile.io.w1.addr := r_dmem_resp_waddr; + rfile.io.w1.en := r_dmem_resp_val; + rfile.io.w1.data := dmem_resp_data_final; + + // scoreboard set (for D$ misses, div, mul) + io.ctrl.sboard_set := wb_reg_ctrl_div_val | wb_reg_ctrl_mul_val | io.ctrl.dcache_miss; + io.ctrl.sboard_seta := wb_reg_waddr; + + // scoreboard clear (for div/mul and D$ load miss writebacks) + io.ctrl.sboard_clr0 := wb_reg_ctrl_ll_wb; + io.ctrl.sboard_clr0a := wb_reg_waddr; + io.ctrl.sboard_clr1 := r_dmem_resp_val; + 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; } diff --git a/rocket/src/main/scala/memory.scala b/rocket/src/main/scala/memory.scala deleted file mode 100644 index 3d0b5869..00000000 --- a/rocket/src/main/scala/memory.scala +++ /dev/null @@ -1,124 +0,0 @@ -package Top -{ - -import Chisel._ -import Node._; - -import queues._; -import Constants._; - -class ioMemory extends Bundle() -{ - val mem_mrq_val = Bool('input); - val mem_mrq_cmd = Bits(4, 'input); - val mem_mrq_type = Bits(3, 'input); - val mem_xsdq_rdy = Bool('output); - val mem_xsdq_val = Bool('input); - val mem_mrq_deq = Bool('output); - val dpath_rs2 = Bits(64, 'input); - val dpath_waddr = UFix(5, 'input); - val dpath_alu_out = UFix(64, 'input); - val dmem_req_val = Bool('output); - val dmem_req_rdy = Bool('input); - val dmem_req_op = Bits(4, 'output); - val dmem_req_addr = UFix(32, 'output); - val dmem_req_data = Bits(64, 'output); - val dmem_req_wmask = Bits(8, 'output); - val dmem_req_tag = Bits(12, 'output); -} - -class rocketMemory extends Component -{ - override val io = new ioMemory(); - val mrq_enq_xf - = (io.mem_mrq_cmd === M_FRD || io.mem_mrq_cmd === M_FWR); - - val mrq_enq_op - = Mux(io.mem_mrq_cmd === M_FRD, M_XRD, - Mux(io.mem_mrq_cmd === M_FWR, M_XWR, - io.mem_mrq_cmd)); - - val mrq_enq_type = io.mem_mrq_type; - - val mrq = new queueSimplePF(45, 4, 2); - val xsdq = new queueSimplePF(64, 4, 2); - - mrq.io.q_reset := Bool(false); - mrq.io.enq_bits := Cat(mrq_enq_xf,mrq_enq_op,mrq_enq_type,io.dpath_waddr,io.dpath_alu_out(31,0)); - mrq.io.enq_val ^^ io.mem_mrq_val; - // mrq.io.enq_rdy <> (); issue logic takes care of this - - val mrq_deq_xf = Wire(){Bits(width = 1)}; - val mrq_deq_op = Wire(){Bits(width = 4)}; - val mrq_deq_type = Wire(){Bits(width = 3)}; - val mrq_deq_waddr = Wire(){Bits(width = 5)}; - val mrq_deq_addr = Wire(){Bits(width = 32)}; - val mrq_deq_bits = mrq.io.deq_bits; - mrq_deq_bits.Match(Array(mrq_deq_xf, mrq_deq_op, mrq_deq_type, mrq_deq_waddr, mrq_deq_addr)); - val mrq_deq_val = mrq.io.deq_val; - - xsdq.io.q_reset := Bool(false); - xsdq.io.enq_bits ^^ io.dpath_rs2; - xsdq.io.enq_val ^^ io.mem_xsdq_val; - xsdq.io.enq_rdy ^^ io.mem_xsdq_rdy; - - val mrq_deq_flush = mrq_deq_op === M_FLA; - val mrq_deq_load = mrq_deq_op === M_XRD; - val mrq_deq_xstore = mrq_deq_op === M_XWR & ~mrq_deq_xf & xsdq.io.deq_val; - - val mrq_deq_rdy = io.dmem_req_rdy & (mrq_deq_load | mrq_deq_xstore | mrq_deq_flush); - io.mem_mrq_deq := (mrq_deq_val & mrq_deq_rdy).toBool; - mrq.io.deq_rdy := mrq_deq_rdy.toBool; - val xsdq_deq_rdy = io.dmem_req_rdy & mrq_deq_val & mrq_deq_op === M_XWR & ~mrq_deq_xf; - xsdq.io.deq_rdy := xsdq_deq_rdy.toBool; - - val wdata = xsdq.io.deq_bits; - - val wmask_b = - Mux(mrq_deq_addr(2,0) === UFix(0, 3), Bits("b0000_0001", 8), - Mux(mrq_deq_addr(2,0) === UFix(1, 3), Bits("b0000_0010", 8), - Mux(mrq_deq_addr(2,0) === UFix(2, 3), Bits("b0000_0100", 8), - Mux(mrq_deq_addr(2,0) === UFix(3, 3), Bits("b0000_1000", 8), - Mux(mrq_deq_addr(2,0) === UFix(4, 3), Bits("b0001_0000", 8), - Mux(mrq_deq_addr(2,0) === UFix(5, 3), Bits("b0010_0000", 8), - Mux(mrq_deq_addr(2,0) === UFix(6, 3), Bits("b0100_0000", 8), - Mux(mrq_deq_addr(2,0) === UFix(7, 3), Bits("b1000_0000", 8), - UFix(0, 8))))))))); - - val wmask_h = - Mux(mrq_deq_addr(2,1) === UFix(0, 2), Bits("b0000_0011", 8), - Mux(mrq_deq_addr(2,1) === UFix(1, 2), Bits("b0000_1100", 8), - Mux(mrq_deq_addr(2,1) === UFix(2, 2), Bits("b0011_0000", 8), - Mux(mrq_deq_addr(2,1) === UFix(3, 2), Bits("b1100_0000", 8), - UFix(0, 8))))); - - val wmask_w = - Mux(mrq_deq_addr(2) === UFix(0, 1), Bits("b0000_1111", 8), - Mux(mrq_deq_addr(2) === UFix(1, 1), Bits("b1111_0000", 8), - UFix(0, 8))); - - val wmask_d = - Bits("b1111_1111", 8); - - io.dmem_req_val := (mrq_deq_val & (mrq_deq_load | mrq_deq_xstore | mrq_deq_flush)).toBool; - io.dmem_req_op := mrq_deq_op; - io.dmem_req_addr := Cat(mrq_deq_addr(31,3), UFix(0, 3)).toUFix; - - io.dmem_req_data := - Mux(mrq_deq_type === MT_B, Fill(8, wdata( 7,0)), - Mux(mrq_deq_type === MT_H, Fill(4, wdata(15,0)), - Mux(mrq_deq_type === MT_W, Fill(2, wdata(31,0)), - Mux(mrq_deq_type === MT_D, wdata, - UFix(0, 64))))); - - io.dmem_req_wmask := - Mux(mrq_deq_type === MT_B, wmask_b, - Mux(mrq_deq_type === MT_H, wmask_h, - Mux(mrq_deq_type === MT_W, wmask_w, - Mux(mrq_deq_type === MT_D, wmask_d, - UFix(0, 8))))); - - io.dmem_req_tag := Cat(mrq_deq_xf,mrq_deq_type,mrq_deq_addr(2,0),mrq_deq_waddr); -} - -} diff --git a/rocket/src/main/scala/writeback.scala b/rocket/src/main/scala/writeback.scala deleted file mode 100644 index 327358c6..00000000 --- a/rocket/src/main/scala/writeback.scala +++ /dev/null @@ -1,56 +0,0 @@ -package Top -{ - -import Chisel._ -import Node._; -import Constants._; - -class ioWriteback extends Bundle() -{ - val dmem_resp_val = Bool('input); - val dmem_resp_data = UFix(64, 'input); - val dmem_resp_tag = UFix(12, 'input); - val wb_waddr = UFix(5, 'output); - val wb_wen = Bool('output); - val wb_wdata = Bits(64, 'output); -} - -class rocketWriteback extends Component -{ - override val io = new ioWriteback(); - - val r_dmem_resp_val = Reg(io.dmem_resp_val); - val r_dmem_resp_data = Reg(io.dmem_resp_data); - val r_dmem_resp_tag = Reg(io.dmem_resp_tag); - - val dmem_resp_xf = r_dmem_resp_tag(11); - val dmem_resp_type = r_dmem_resp_tag(10, 8); - val dmem_resp_pos = r_dmem_resp_tag(7, 5); - val dmem_resp_waddr = r_dmem_resp_tag(4, 0); - val dmem_resp_xval = r_dmem_resp_val & ~dmem_resp_xf; - val dmem_resp_fval = r_dmem_resp_val & dmem_resp_xf; - - val dmem_resp_data_w = - Mux(dmem_resp_pos(2).toBool, r_dmem_resp_data(63, 32), r_dmem_resp_data(31, 0)); - val dmem_resp_data_h = - Mux(dmem_resp_pos(1).toBool, dmem_resp_data_w(31, 16), dmem_resp_data_w(15, 0)); - val dmem_resp_data_b = - Mux(dmem_resp_pos(0).toBool, dmem_resp_data_h(15, 8), dmem_resp_data_h(7, 0)); - - val dmem_resp_data_final = - Mux(dmem_resp_type === MT_B, Cat(Fill(56, dmem_resp_data_b(7)), dmem_resp_data_b), - Mux(dmem_resp_type === MT_BU, Cat(UFix(0, 56), dmem_resp_data_b), - Mux(dmem_resp_type === MT_H, Cat(Fill(48, dmem_resp_data_h(15)), dmem_resp_data_h), - Mux(dmem_resp_type === MT_HU, Cat(UFix(0, 48), dmem_resp_data_h), - Mux(dmem_resp_type === MT_W, Cat(Fill(32, dmem_resp_data_w(31)), dmem_resp_data_w), - Mux(dmem_resp_type === MT_WU, Cat(UFix(0, 32), dmem_resp_data_w), - Mux(dmem_resp_type === MT_D, r_dmem_resp_data, - UFix(0, 64)))))))); - - io.wb_wen := dmem_resp_xval.toBool; - io.wb_waddr := dmem_resp_waddr; - io.wb_wdata := dmem_resp_data_final; - -} - -}