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