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