Start adding RoCC
This commit is contained in:
		| @@ -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 | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
| } | ||||
|   | ||||
| @@ -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)) | ||||
| } | ||||
|   | ||||
| @@ -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) | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user