From a0cb711451bc9f34963dacecfab1db949e8c090a Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sat, 14 Sep 2013 15:31:50 -0700 Subject: [PATCH] Start adding RoCC --- rocket/src/main/scala/core.scala | 20 ++++++---- rocket/src/main/scala/ctrl.scala | 21 +++++++--- rocket/src/main/scala/dpath.scala | 34 ++++++++++------ rocket/src/main/scala/rocc.scala | 66 ++++++++++++++++++++++++++++++- 4 files changed, 114 insertions(+), 27 deletions(-) diff --git a/rocket/src/main/scala/core.scala b/rocket/src/main/scala/core.scala index 8067f3c9..0bf3e561 100644 --- a/rocket/src/main/scala/core.scala +++ b/rocket/src/main/scala/core.scala @@ -10,6 +10,7 @@ class RocketIO(implicit conf: RocketConfiguration) extends Bundle val imem = new CPUFrontendIO()(conf.icache) val dmem = new HellaCacheIO()(conf.dcache) val ptw = new DatapathPTWIO().flip + val rocc = new RoCCInterface().flip } class Core(implicit conf: RocketConfiguration) extends Module @@ -19,6 +20,15 @@ class Core(implicit conf: RocketConfiguration) extends Module val ctrl = Module(new Control) val dpath = Module(new Datapath) + val fpu: FPU = if (conf.fpu) { + val fpu = Module(new FPU(4,6)) + dpath.io.fpu <> fpu.io.dpath + ctrl.io.fpu <> fpu.io.ctrl + fpu.io.sfma.valid := Bool(false) // hook these up to coprocessor? + fpu.io.dfma.valid := Bool(false) + fpu + } else null + ctrl.io.dpath <> dpath.io.ctrl dpath.io.host <> io.host @@ -30,12 +40,6 @@ class Core(implicit conf: RocketConfiguration) extends Module dpath.io.ptw <> io.ptw - val fpu: FPU = if (conf.fpu) { - val fpu = Module(new FPU(4,6)) - dpath.io.fpu <> fpu.io.dpath - ctrl.io.fpu <> fpu.io.ctrl - fpu.io.sfma.valid := Bool(false) // hook these up to coprocessor? - fpu.io.dfma.valid := Bool(false) - fpu - } else null + ctrl.io.rocc <> io.rocc + dpath.io.rocc <> io.rocc } diff --git a/rocket/src/main/scala/ctrl.scala b/rocket/src/main/scala/ctrl.scala index e1adea1a..89769f71 100644 --- a/rocket/src/main/scala/ctrl.scala +++ b/rocket/src/main/scala/ctrl.scala @@ -37,7 +37,8 @@ class CtrlDpathIO extends Bundle() val wb_valid = Bool(OUTPUT) val ex_mem_type = Bits(OUTPUT, 3) val ex_rs2_val = Bool(OUTPUT) - val mem_rs2_val = Bool(OUTPUT) + val ex_rocc_val = Bool(OUTPUT) + val mem_rocc_val = Bool(OUTPUT) val mem_ll_bypass_rs1 = Bool(OUTPUT) val mem_ll_bypass_rs2 = Bool(OUTPUT) // exception handling @@ -317,6 +318,7 @@ class Control(implicit conf: RocketConfiguration) extends Module val xcpt_dtlb_ld = Bool(INPUT) val xcpt_dtlb_st = Bool(INPUT) val fpu = new CtrlFPUIO + val rocc = new RoCCInterface().flip } var decode_table = XDecode.table @@ -376,6 +378,7 @@ class Control(implicit conf: RocketConfiguration) extends Module val wb_reg_pcr = Reg(init=PCR.N) val wb_reg_wen = Reg(init=Bool(false)) val wb_reg_fp_wen = Reg(init=Bool(false)) + val wb_reg_rocc_val = Reg(init=Bool(false)) val wb_reg_flush_inst = Reg(init=Bool(false)) val wb_reg_mem_val = Reg(init=Bool(false)) val wb_reg_eret = Reg(init=Bool(false)) @@ -416,9 +419,11 @@ class Control(implicit conf: RocketConfiguration) extends Module val id_amo_aq = io.dpath.inst(16) val id_amo_rl = io.dpath.inst(15) val id_fence_next = id_fence || id_amo && id_amo_rl - val id_fence_ok = io.dmem.ordered && !ex_reg_mem_val + val id_rocc_busy = io.rocc.busy || ex_reg_rocc_val || mem_reg_rocc_val || wb_reg_rocc_val + val id_fence_ok = io.dmem.ordered && !ex_reg_mem_val && + (Bool(conf.rocc.isEmpty) || !id_rocc_busy) id_reg_fence := id_fence_next || id_reg_fence && !id_fence_ok - val id_do_fence = id_amo && id_amo_aq || id_reg_fence && id_mem_val || id_pcr_flush + val id_do_fence = id_amo && id_amo_aq || id_reg_fence && (id_mem_val || id_rocc_val) || id_pcr_flush val (id_xcpt, id_cause) = checkExceptions(List( (id_interrupt, id_interrupt_cause), @@ -549,6 +554,7 @@ class Control(implicit conf: RocketConfiguration) extends Module wb_reg_mem_val := Bool(false) wb_reg_div_mul_val := Bool(false); wb_reg_fp_val := Bool(false) + wb_reg_rocc_val := Bool(false) } .otherwise { wb_reg_valid := mem_reg_valid @@ -560,9 +566,11 @@ class Control(implicit conf: RocketConfiguration) extends Module wb_reg_mem_val := mem_reg_mem_val wb_reg_div_mul_val := mem_reg_div_mul_val wb_reg_fp_val := mem_reg_fp_val + wb_reg_rocc_val := mem_reg_rocc_val } - val replay_wb = io.dmem.resp.bits.nack || wb_reg_replay || io.dpath.pcr_replay + val replay_wb = io.dmem.resp.bits.nack || wb_reg_replay || + io.dpath.pcr_replay || Bool(!conf.rocc.isEmpty) && wb_reg_rocc_val && !io.rocc.cmd.ready class Scoreboard(n: Int) { @@ -708,7 +716,8 @@ class Control(implicit conf: RocketConfiguration) extends Module io.dpath.ex_mem_type := ex_reg_mem_type io.dpath.ex_br_type := ex_reg_br_type io.dpath.ex_rs2_val := ex_reg_mem_val && isWrite(ex_reg_mem_cmd) || ex_reg_rocc_val - io.dpath.mem_rs2_val := mem_reg_rocc_val + io.dpath.ex_rocc_val := ex_reg_rocc_val + io.dpath.mem_rocc_val := mem_reg_rocc_val io.fpu.valid := !ctrl_killd && id_fp_val io.fpu.killx := ctrl_killx @@ -719,4 +728,6 @@ class Control(implicit conf: RocketConfiguration) extends Module io.dmem.req.bits.cmd := ex_reg_mem_cmd io.dmem.req.bits.typ := ex_reg_mem_type io.dmem.req.bits.phys := Bool(false) + + io.rocc.cmd.valid := wb_reg_rocc_val } diff --git a/rocket/src/main/scala/dpath.scala b/rocket/src/main/scala/dpath.scala index 7f2e9701..00c3d5d2 100644 --- a/rocket/src/main/scala/dpath.scala +++ b/rocket/src/main/scala/dpath.scala @@ -14,6 +14,7 @@ class Datapath(implicit conf: RocketConfiguration) extends Module val ptw = (new DatapathPTWIO).flip val imem = new CPUFrontendIO()(conf.icache) val fpu = new DpathFPUIO + val rocc = new RoCCInterface().flip } // execute definitions @@ -39,8 +40,6 @@ class Datapath(implicit conf: RocketConfiguration) extends Module val mem_reg_wdata = Reg(Bits()) val mem_reg_kill = Reg(Bool()) val mem_reg_store_data = Reg(Bits()) - val mem_reg_rs1 = Reg(Bits()) - val mem_reg_rs2 = Reg(Bits()) // writeback definitions val wb_reg_pc = Reg(UInt()) @@ -49,8 +48,6 @@ class Datapath(implicit conf: RocketConfiguration) extends Module val wb_reg_wdata = Reg(Bits()) val wb_reg_ll_wb = Reg(init=Bool(false)) val wb_wdata = Bits() - val wb_reg_store_data = Reg(Bits()) - val wb_reg_rs1 = Reg(Bits()) val wb_reg_rs2 = Reg(Bits()) val wb_wen = io.ctrl.wb_wen && io.ctrl.wb_valid || wb_reg_ll_wb @@ -235,8 +232,6 @@ class Datapath(implicit conf: RocketConfiguration) extends Module mem_reg_pc := ex_reg_pc mem_reg_inst := ex_reg_inst mem_reg_wdata := ex_wdata - mem_reg_rs1 := ex_rs1 - mem_reg_rs2 := ex_rs2 when (io.ctrl.ex_rs2_val) { mem_reg_store_data := StoreGen(io.ctrl.ex_mem_type, Bits(0), ex_rs2).data } @@ -255,8 +250,19 @@ class Datapath(implicit conf: RocketConfiguration) extends Module mem_ll_wdata := div.io.resp.bits.data io.ctrl.mem_ll_waddr := div.io.resp.bits.tag io.ctrl.mem_ll_wb := div.io.resp.valid && !io.ctrl.mem_wen + if (!conf.rocc.isEmpty) { + io.rocc.resp.ready := !io.ctrl.mem_wen && !io.ctrl.mem_rocc_val + when (io.rocc.resp.fire()) { + div.io.resp.ready := Bool(false) + mem_ll_wdata := io.rocc.resp.bits.data + io.ctrl.mem_ll_waddr := io.rocc.resp.bits.rd + io.ctrl.mem_ll_wb := Bool(true) + } + } when (dmem_resp_replay) { div.io.resp.ready := Bool(false) + if (!conf.rocc.isEmpty) + io.rocc.resp.ready := Bool(false) mem_ll_wdata := io.dmem.resp.bits.data_subword io.ctrl.mem_ll_waddr := dmem_resp_waddr io.ctrl.mem_ll_wb := Bool(true) @@ -274,11 +280,9 @@ class Datapath(implicit conf: RocketConfiguration) extends Module wb_reg_waddr := io.ctrl.mem_waddr wb_reg_inst := mem_reg_inst wb_reg_wdata := Mux(io.ctrl.mem_fp_val && io.ctrl.mem_wen, io.fpu.toint_data, mem_reg_wdata) - wb_reg_rs1 := mem_reg_rs1 - wb_reg_rs2 := mem_reg_rs2 - when (io.ctrl.mem_rs2_val) { - wb_reg_store_data := mem_reg_store_data - } + } + when (io.ctrl.mem_rocc_val) { + wb_reg_rs2 := Bits(0)//mem_reg_rs2 } wb_reg_ll_wb := io.ctrl.mem_ll_wb when (io.ctrl.mem_ll_wb) { @@ -301,6 +305,10 @@ class Datapath(implicit conf: RocketConfiguration) extends Module pcr.io.rw.cmd := io.ctrl.pcr pcr.io.rw.wdata := wb_reg_wdata + io.rocc.cmd.bits.inst := new RoCCInstruction().fromBits(wb_reg_inst) + io.rocc.cmd.bits.rs1 := wb_reg_wdata + io.rocc.cmd.bits.rs2 := wb_reg_rs2 + // hook up I$ io.imem.req.bits.currentpc := ex_reg_pc io.imem.req.bits.pc := @@ -311,7 +319,7 @@ class Datapath(implicit conf: RocketConfiguration) extends Module printf("C: %d [%d] pc=[%x] W[r%d=%x] R[r%d=%x] R[r%d=%x] inst=[%x] %s\n", tsc_reg(32,0), io.ctrl.wb_valid, wb_reg_pc, Mux(wb_wen, wb_reg_waddr, UInt(0)), wb_wdata, - wb_reg_inst(26,22), wb_reg_rs1, - wb_reg_inst(21,17), wb_reg_rs2, + wb_reg_inst(26,22), Reg(next=Reg(next=ex_rs1)), + wb_reg_inst(21,17), Reg(next=Reg(next=ex_rs2)), wb_reg_inst, Disassemble(wb_reg_inst)) } diff --git a/rocket/src/main/scala/rocc.scala b/rocket/src/main/scala/rocc.scala index 6207582f..cbff596d 100644 --- a/rocket/src/main/scala/rocc.scala +++ b/rocket/src/main/scala/rocc.scala @@ -3,4 +3,68 @@ package rocket import Chisel._ import Node._ -abstract class RoCC extends Module +class RoCCInstruction extends Bundle +{ + val rd = Bits(width = 5) + val rs1 = Bits(width = 5) + val rs2 = Bits(width = 5) + val funct = Bits(width = 7) + val xd = Bool() + val xs1 = Bool() + val xs2 = Bool() + val opcode = Bits(width = 7) +} + +class RoCCCommand(implicit conf: RocketConfiguration) extends Bundle +{ + val inst = new RoCCInstruction + val rs1 = Bits(width = conf.xprlen) + val rs2 = Bits(width = conf.xprlen) + + override def clone = new RoCCCommand().asInstanceOf[this.type] +} + +class RoCCResponse(implicit conf: RocketConfiguration) extends Bundle +{ + val rd = Bits(width = 5) + val data = Bits(width = conf.xprlen) + + override def clone = new RoCCResponse().asInstanceOf[this.type] +} + +class RoCCInterface(implicit conf: RocketConfiguration) extends Bundle +{ + val cmd = Decoupled(new RoCCCommand).flip + val resp = Decoupled(new RoCCResponse) + val busy = Bool(OUTPUT) + val interrupt = Bool(OUTPUT) + + override def clone = new RoCCInterface().asInstanceOf[this.type] +} + +abstract class RoCC(implicit conf: RocketConfiguration) extends Module +{ + val io = new RoCCInterface +} + +class AccumulatorExample(implicit conf: RocketConfiguration) extends RoCC +{ + val regfile = Mem(UInt(width = conf.xprlen), 4) + + val funct = io.cmd.bits.inst.funct + val addr = io.cmd.bits.inst.rs2 + val addend = io.cmd.bits.rs1 + val accum = regfile(addr) + val wdata = Mux(funct === UInt(0), addend, accum + addend) + + when (io.cmd.fire() && (funct === UInt(1) || funct === UInt(3))) { + regfile(addr) := wdata + } + + io.cmd.ready := io.resp.ready + io.resp.valid := io.cmd.valid && io.cmd.bits.inst.xd + io.resp.bits.rd := io.cmd.bits.inst.rd + io.resp.bits.data := accum + io.busy := Bool(false) + io.interrupt := Bool(false) +}