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 imem = new CPUFrontendIO()(conf.icache)
|
||||||
val dmem = new HellaCacheIO()(conf.dcache)
|
val dmem = new HellaCacheIO()(conf.dcache)
|
||||||
val ptw = new DatapathPTWIO().flip
|
val ptw = new DatapathPTWIO().flip
|
||||||
|
val rocc = new RoCCInterface().flip
|
||||||
}
|
}
|
||||||
|
|
||||||
class Core(implicit conf: RocketConfiguration) extends Module
|
class Core(implicit conf: RocketConfiguration) extends Module
|
||||||
@ -19,6 +20,15 @@ class Core(implicit conf: RocketConfiguration) extends Module
|
|||||||
val ctrl = Module(new Control)
|
val ctrl = Module(new Control)
|
||||||
val dpath = Module(new Datapath)
|
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
|
ctrl.io.dpath <> dpath.io.ctrl
|
||||||
dpath.io.host <> io.host
|
dpath.io.host <> io.host
|
||||||
|
|
||||||
@ -30,12 +40,6 @@ class Core(implicit conf: RocketConfiguration) extends Module
|
|||||||
|
|
||||||
dpath.io.ptw <> io.ptw
|
dpath.io.ptw <> io.ptw
|
||||||
|
|
||||||
val fpu: FPU = if (conf.fpu) {
|
ctrl.io.rocc <> io.rocc
|
||||||
val fpu = Module(new FPU(4,6))
|
dpath.io.rocc <> io.rocc
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,8 @@ class CtrlDpathIO extends Bundle()
|
|||||||
val wb_valid = Bool(OUTPUT)
|
val wb_valid = Bool(OUTPUT)
|
||||||
val ex_mem_type = Bits(OUTPUT, 3)
|
val ex_mem_type = Bits(OUTPUT, 3)
|
||||||
val ex_rs2_val = Bool(OUTPUT)
|
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_rs1 = Bool(OUTPUT)
|
||||||
val mem_ll_bypass_rs2 = Bool(OUTPUT)
|
val mem_ll_bypass_rs2 = Bool(OUTPUT)
|
||||||
// exception handling
|
// exception handling
|
||||||
@ -317,6 +318,7 @@ class Control(implicit conf: RocketConfiguration) extends Module
|
|||||||
val xcpt_dtlb_ld = Bool(INPUT)
|
val xcpt_dtlb_ld = Bool(INPUT)
|
||||||
val xcpt_dtlb_st = Bool(INPUT)
|
val xcpt_dtlb_st = Bool(INPUT)
|
||||||
val fpu = new CtrlFPUIO
|
val fpu = new CtrlFPUIO
|
||||||
|
val rocc = new RoCCInterface().flip
|
||||||
}
|
}
|
||||||
|
|
||||||
var decode_table = XDecode.table
|
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_pcr = Reg(init=PCR.N)
|
||||||
val wb_reg_wen = Reg(init=Bool(false))
|
val wb_reg_wen = Reg(init=Bool(false))
|
||||||
val wb_reg_fp_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_flush_inst = Reg(init=Bool(false))
|
||||||
val wb_reg_mem_val = Reg(init=Bool(false))
|
val wb_reg_mem_val = Reg(init=Bool(false))
|
||||||
val wb_reg_eret = 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_aq = io.dpath.inst(16)
|
||||||
val id_amo_rl = io.dpath.inst(15)
|
val id_amo_rl = io.dpath.inst(15)
|
||||||
val id_fence_next = id_fence || id_amo && id_amo_rl
|
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
|
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(
|
val (id_xcpt, id_cause) = checkExceptions(List(
|
||||||
(id_interrupt, id_interrupt_cause),
|
(id_interrupt, id_interrupt_cause),
|
||||||
@ -549,6 +554,7 @@ class Control(implicit conf: RocketConfiguration) extends Module
|
|||||||
wb_reg_mem_val := Bool(false)
|
wb_reg_mem_val := Bool(false)
|
||||||
wb_reg_div_mul_val := Bool(false);
|
wb_reg_div_mul_val := Bool(false);
|
||||||
wb_reg_fp_val := Bool(false)
|
wb_reg_fp_val := Bool(false)
|
||||||
|
wb_reg_rocc_val := Bool(false)
|
||||||
}
|
}
|
||||||
.otherwise {
|
.otherwise {
|
||||||
wb_reg_valid := mem_reg_valid
|
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_mem_val := mem_reg_mem_val
|
||||||
wb_reg_div_mul_val := mem_reg_div_mul_val
|
wb_reg_div_mul_val := mem_reg_div_mul_val
|
||||||
wb_reg_fp_val := mem_reg_fp_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)
|
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_mem_type := ex_reg_mem_type
|
||||||
io.dpath.ex_br_type := ex_reg_br_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.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.valid := !ctrl_killd && id_fp_val
|
||||||
io.fpu.killx := ctrl_killx
|
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.cmd := ex_reg_mem_cmd
|
||||||
io.dmem.req.bits.typ := ex_reg_mem_type
|
io.dmem.req.bits.typ := ex_reg_mem_type
|
||||||
io.dmem.req.bits.phys := Bool(false)
|
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 ptw = (new DatapathPTWIO).flip
|
||||||
val imem = new CPUFrontendIO()(conf.icache)
|
val imem = new CPUFrontendIO()(conf.icache)
|
||||||
val fpu = new DpathFPUIO
|
val fpu = new DpathFPUIO
|
||||||
|
val rocc = new RoCCInterface().flip
|
||||||
}
|
}
|
||||||
|
|
||||||
// execute definitions
|
// execute definitions
|
||||||
@ -39,8 +40,6 @@ class Datapath(implicit conf: RocketConfiguration) extends Module
|
|||||||
val mem_reg_wdata = Reg(Bits())
|
val mem_reg_wdata = Reg(Bits())
|
||||||
val mem_reg_kill = Reg(Bool())
|
val mem_reg_kill = Reg(Bool())
|
||||||
val mem_reg_store_data = Reg(Bits())
|
val mem_reg_store_data = Reg(Bits())
|
||||||
val mem_reg_rs1 = Reg(Bits())
|
|
||||||
val mem_reg_rs2 = Reg(Bits())
|
|
||||||
|
|
||||||
// writeback definitions
|
// writeback definitions
|
||||||
val wb_reg_pc = Reg(UInt())
|
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_wdata = Reg(Bits())
|
||||||
val wb_reg_ll_wb = Reg(init=Bool(false))
|
val wb_reg_ll_wb = Reg(init=Bool(false))
|
||||||
val wb_wdata = Bits()
|
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_reg_rs2 = Reg(Bits())
|
||||||
val wb_wen = io.ctrl.wb_wen && io.ctrl.wb_valid || wb_reg_ll_wb
|
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_pc := ex_reg_pc
|
||||||
mem_reg_inst := ex_reg_inst
|
mem_reg_inst := ex_reg_inst
|
||||||
mem_reg_wdata := ex_wdata
|
mem_reg_wdata := ex_wdata
|
||||||
mem_reg_rs1 := ex_rs1
|
|
||||||
mem_reg_rs2 := ex_rs2
|
|
||||||
when (io.ctrl.ex_rs2_val) {
|
when (io.ctrl.ex_rs2_val) {
|
||||||
mem_reg_store_data := StoreGen(io.ctrl.ex_mem_type, Bits(0), ex_rs2).data
|
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
|
mem_ll_wdata := div.io.resp.bits.data
|
||||||
io.ctrl.mem_ll_waddr := div.io.resp.bits.tag
|
io.ctrl.mem_ll_waddr := div.io.resp.bits.tag
|
||||||
io.ctrl.mem_ll_wb := div.io.resp.valid && !io.ctrl.mem_wen
|
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) {
|
when (dmem_resp_replay) {
|
||||||
div.io.resp.ready := Bool(false)
|
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
|
mem_ll_wdata := io.dmem.resp.bits.data_subword
|
||||||
io.ctrl.mem_ll_waddr := dmem_resp_waddr
|
io.ctrl.mem_ll_waddr := dmem_resp_waddr
|
||||||
io.ctrl.mem_ll_wb := Bool(true)
|
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_waddr := io.ctrl.mem_waddr
|
||||||
wb_reg_inst := mem_reg_inst
|
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_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
|
wb_reg_ll_wb := io.ctrl.mem_ll_wb
|
||||||
when (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.cmd := io.ctrl.pcr
|
||||||
pcr.io.rw.wdata := wb_reg_wdata
|
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$
|
// hook up I$
|
||||||
io.imem.req.bits.currentpc := ex_reg_pc
|
io.imem.req.bits.currentpc := ex_reg_pc
|
||||||
io.imem.req.bits.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",
|
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,
|
tsc_reg(32,0), io.ctrl.wb_valid, wb_reg_pc,
|
||||||
Mux(wb_wen, wb_reg_waddr, UInt(0)), wb_wdata,
|
Mux(wb_wen, wb_reg_waddr, UInt(0)), wb_wdata,
|
||||||
wb_reg_inst(26,22), wb_reg_rs1,
|
wb_reg_inst(26,22), Reg(next=Reg(next=ex_rs1)),
|
||||||
wb_reg_inst(21,17), wb_reg_rs2,
|
wb_reg_inst(21,17), Reg(next=Reg(next=ex_rs2)),
|
||||||
wb_reg_inst, Disassemble(wb_reg_inst))
|
wb_reg_inst, Disassemble(wb_reg_inst))
|
||||||
}
|
}
|
||||||
|
@ -3,4 +3,68 @@ package rocket
|
|||||||
import Chisel._
|
import Chisel._
|
||||||
import Node._
|
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