Add fpu port to the rocc interface
This commit is contained in:
parent
d912ea265e
commit
a369d8f17f
@ -74,6 +74,12 @@ class Core extends Module with CoreParameters
|
|||||||
.foreach { fpu =>
|
.foreach { fpu =>
|
||||||
dpath.io.fpu <> fpu.io.dpath
|
dpath.io.fpu <> fpu.io.dpath
|
||||||
ctrl.io.fpu <> fpu.io.ctrl
|
ctrl.io.fpu <> fpu.io.ctrl
|
||||||
|
if(!params(BuildRoCC).isEmpty) {
|
||||||
|
io.rocc.fpu_req <> fpu.io.cp_req
|
||||||
|
io.rocc.fpu_resp <> fpu.io.cp_resp
|
||||||
|
} else {
|
||||||
|
fpu.io.cp_req.valid := Bool(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctrl.io.dpath <> dpath.io.ctrl
|
ctrl.io.dpath <> dpath.io.ctrl
|
||||||
|
@ -348,21 +348,32 @@ class FPU extends Module
|
|||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val ctrl = (new CtrlFPUIO).flip
|
val ctrl = (new CtrlFPUIO).flip
|
||||||
val dpath = (new DpathFPUIO).flip
|
val dpath = (new DpathFPUIO).flip
|
||||||
|
val cp_req = Decoupled(new FPInput()).flip //cp doesn't pay attn to kill sigs
|
||||||
|
val cp_resp = Decoupled(new FPResult())
|
||||||
}
|
}
|
||||||
|
|
||||||
val ex_reg_valid = Reg(next=io.ctrl.valid, init=Bool(false))
|
val ex_reg_valid = Reg(next=io.ctrl.valid, init=Bool(false))
|
||||||
|
val req_valid = ex_reg_valid || io.cp_req.valid
|
||||||
val ex_reg_inst = RegEnable(io.dpath.inst, io.ctrl.valid)
|
val ex_reg_inst = RegEnable(io.dpath.inst, io.ctrl.valid)
|
||||||
val mem_reg_valid = Reg(next=ex_reg_valid && !io.ctrl.killx, init=Bool(false))
|
val ex_cp_valid = io.cp_req.valid && !ex_reg_valid
|
||||||
|
val mem_reg_valid = Reg(next=ex_reg_valid && !io.ctrl.killx || ex_cp_valid, init=Bool(false))
|
||||||
val mem_reg_inst = RegEnable(ex_reg_inst, ex_reg_valid)
|
val mem_reg_inst = RegEnable(ex_reg_inst, ex_reg_valid)
|
||||||
val killm = io.ctrl.killm || io.ctrl.nack_mem
|
val mem_cp_valid = Reg(next=ex_cp_valid, init=Bool(false))
|
||||||
val wb_reg_valid = Reg(next=mem_reg_valid && !killm, init=Bool(false))
|
val killm = (io.ctrl.killm || io.ctrl.nack_mem) && !mem_cp_valid
|
||||||
|
val wb_reg_valid = Reg(next=mem_reg_valid && (!killm || mem_cp_valid), init=Bool(false))
|
||||||
|
val wb_cp_valid = Reg(next=mem_cp_valid, init=Bool(false))
|
||||||
|
|
||||||
val fp_decoder = Module(new FPUDecoder)
|
val fp_decoder = Module(new FPUDecoder)
|
||||||
fp_decoder.io.inst := io.dpath.inst
|
fp_decoder.io.inst := io.dpath.inst
|
||||||
|
|
||||||
|
val cp_ctrl = new FPUCtrlSigs
|
||||||
|
cp_ctrl <> io.cp_req.bits
|
||||||
|
io.cp_resp.valid := Bool(false)
|
||||||
|
io.cp_resp.bits.data := UInt(0)
|
||||||
|
|
||||||
val id_ctrl = fp_decoder.io.sigs
|
val id_ctrl = fp_decoder.io.sigs
|
||||||
val ex_ctrl = RegEnable(id_ctrl, io.ctrl.valid)
|
val ex_ctrl = Mux(ex_reg_valid, RegEnable(id_ctrl, io.ctrl.valid), cp_ctrl)
|
||||||
val mem_ctrl = RegEnable(ex_ctrl, ex_reg_valid)
|
val mem_ctrl = RegEnable(ex_ctrl, req_valid)
|
||||||
val wb_ctrl = RegEnable(mem_ctrl, mem_reg_valid)
|
val wb_ctrl = RegEnable(mem_ctrl, mem_reg_valid)
|
||||||
|
|
||||||
// load response
|
// load response
|
||||||
@ -391,35 +402,43 @@ class FPU extends Module
|
|||||||
val ex_rs1::ex_rs2::ex_rs3::Nil = Seq(ex_ra1, ex_ra2, ex_ra3).map(regfile(_))
|
val ex_rs1::ex_rs2::ex_rs3::Nil = Seq(ex_ra1, ex_ra2, ex_ra3).map(regfile(_))
|
||||||
val ex_rm = Mux(ex_reg_inst(14,12) === Bits(7), io.dpath.fcsr_rm, ex_reg_inst(14,12))
|
val ex_rm = Mux(ex_reg_inst(14,12) === Bits(7), io.dpath.fcsr_rm, ex_reg_inst(14,12))
|
||||||
|
|
||||||
|
val cp_rs1 = io.cp_req.bits.in1
|
||||||
|
val cp_rs2 = Mux(io.cp_req.bits.swap23, io.cp_req.bits.in3, io.cp_req.bits.in2)
|
||||||
|
val cp_rs3 = Mux(io.cp_req.bits.swap23, io.cp_req.bits.in2, io.cp_req.bits.in3)
|
||||||
|
|
||||||
val req = new FPInput
|
val req = new FPInput
|
||||||
req := ex_ctrl
|
req := ex_ctrl
|
||||||
req.rm := ex_rm
|
req.rm := Mux(ex_reg_valid, ex_rm, io.cp_req.bits.rm)
|
||||||
req.in1 := ex_rs1
|
req.in1 := Mux(ex_reg_valid, ex_rs1, cp_rs1)
|
||||||
req.in2 := ex_rs2
|
req.in2 := Mux(ex_reg_valid, ex_rs2, cp_rs2)
|
||||||
req.in3 := ex_rs3
|
req.in3 := Mux(ex_reg_valid, ex_rs3, cp_rs3)
|
||||||
req.typ := ex_reg_inst(21,20)
|
req.typ := Mux(ex_reg_valid, ex_reg_inst(21,20), io.cp_req.bits.typ)
|
||||||
|
|
||||||
val sfma = Module(new FPUFMAPipe(params(SFMALatency), 23, 9))
|
val sfma = Module(new FPUFMAPipe(params(SFMALatency), 23, 9))
|
||||||
sfma.io.in.valid := ex_reg_valid && ex_ctrl.fma && ex_ctrl.single
|
sfma.io.in.valid := req_valid && ex_ctrl.fma && ex_ctrl.single
|
||||||
sfma.io.in.bits := req
|
sfma.io.in.bits := req
|
||||||
|
|
||||||
val dfma = Module(new FPUFMAPipe(params(DFMALatency), 52, 12))
|
val dfma = Module(new FPUFMAPipe(params(DFMALatency), 52, 12))
|
||||||
dfma.io.in.valid := ex_reg_valid && ex_ctrl.fma && !ex_ctrl.single
|
dfma.io.in.valid := req_valid && ex_ctrl.fma && !ex_ctrl.single
|
||||||
dfma.io.in.bits := req
|
dfma.io.in.bits := req
|
||||||
|
|
||||||
val fpiu = Module(new FPToInt)
|
val fpiu = Module(new FPToInt)
|
||||||
fpiu.io.in.valid := ex_reg_valid && (ex_ctrl.toint || ex_ctrl.cmd === FCMD_MINMAX)
|
fpiu.io.in.valid := req_valid && (ex_ctrl.toint || ex_ctrl.cmd === FCMD_MINMAX)
|
||||||
fpiu.io.in.bits := req
|
fpiu.io.in.bits := req
|
||||||
io.dpath.store_data := fpiu.io.out.bits.store
|
io.dpath.store_data := fpiu.io.out.bits.store
|
||||||
io.dpath.toint_data := fpiu.io.out.bits.toint
|
io.dpath.toint_data := fpiu.io.out.bits.toint
|
||||||
|
when(fpiu.io.out.valid){//COLIN FIXME: are there conflicts since we now share a port?
|
||||||
|
io.cp_resp.bits.data := fpiu.io.out.bits.toint
|
||||||
|
io.cp_resp.valid := Bool(true)
|
||||||
|
}
|
||||||
|
|
||||||
val ifpu = Module(new IntToFP(3))
|
val ifpu = Module(new IntToFP(3))
|
||||||
ifpu.io.in.valid := ex_reg_valid && ex_ctrl.fromint
|
ifpu.io.in.valid := req_valid && ex_ctrl.fromint
|
||||||
ifpu.io.in.bits := req
|
ifpu.io.in.bits := req
|
||||||
ifpu.io.in.bits.in1 := io.dpath.fromint_data
|
ifpu.io.in.bits.in1 := Mux(ex_reg_valid, io.dpath.fromint_data, cp_rs1)
|
||||||
|
|
||||||
val fpmu = Module(new FPToFP(2))
|
val fpmu = Module(new FPToFP(2))
|
||||||
fpmu.io.in.valid := ex_reg_valid && ex_ctrl.fastpipe
|
fpmu.io.in.valid := req_valid && ex_ctrl.fastpipe
|
||||||
fpmu.io.in.bits := req
|
fpmu.io.in.bits := req
|
||||||
fpmu.io.lt := fpiu.io.out.bits.lt
|
fpmu.io.lt := fpiu.io.out.bits.lt
|
||||||
|
|
||||||
@ -441,8 +460,8 @@ class FPU extends Module
|
|||||||
val wen = Reg(init=Bits(0, maxLatency-1))
|
val wen = Reg(init=Bits(0, maxLatency-1))
|
||||||
val winfo = Vec.fill(maxLatency-1){Reg(Bits())}
|
val winfo = Vec.fill(maxLatency-1){Reg(Bits())}
|
||||||
val mem_wen = mem_reg_valid && (mem_ctrl.fma || mem_ctrl.fastpipe || mem_ctrl.fromint)
|
val mem_wen = mem_reg_valid && (mem_ctrl.fma || mem_ctrl.fastpipe || mem_ctrl.fromint)
|
||||||
val write_port_busy = RegEnable(mem_wen && (memLatencyMask & latencyMask(ex_ctrl, 1)).orR || (wen & latencyMask(ex_ctrl, 0)).orR, ex_reg_valid)
|
val write_port_busy = RegEnable(mem_wen && (memLatencyMask & latencyMask(ex_ctrl, 1)).orR || (wen & latencyMask(ex_ctrl, 0)).orR, req_valid)
|
||||||
val mem_winfo = Cat(pipeid(mem_ctrl), mem_reg_inst(11,7))
|
val mem_winfo = Cat(mem_cp_valid, pipeid(mem_ctrl), mem_reg_inst(11,7))
|
||||||
|
|
||||||
for (i <- 0 until maxLatency-2) {
|
for (i <- 0 until maxLatency-2) {
|
||||||
when (wen(i+1)) { winfo(i) := winfo(i+1) }
|
when (wen(i+1)) { winfo(i) := winfo(i+1) }
|
||||||
@ -461,9 +480,15 @@ class FPU extends Module
|
|||||||
|
|
||||||
val waddr = winfo(0)(4,0).toUInt
|
val waddr = winfo(0)(4,0).toUInt
|
||||||
val wsrc = winfo(0) >> waddr.getWidth
|
val wsrc = winfo(0) >> waddr.getWidth
|
||||||
|
val wcp = winfo(0)(waddr.getWidth+log2Up(pipes.size))
|
||||||
val wdata = Vec(pipes.map(_.wdata))(wsrc)
|
val wdata = Vec(pipes.map(_.wdata))(wsrc)
|
||||||
val wexc = Vec(pipes.map(_.wexc))(wsrc)
|
val wexc = Vec(pipes.map(_.wexc))(wsrc)
|
||||||
when (wen(0)) { regfile(waddr(4,0)) := wdata }
|
when (wen(0) && !wcp) { regfile(waddr(4,0)) := wdata }
|
||||||
|
when (wen(0) && wcp) {
|
||||||
|
io.cp_resp.bits.data := wdata
|
||||||
|
io.cp_resp.valid := Bool(true)
|
||||||
|
}
|
||||||
|
io.cp_req.ready := !ex_reg_valid
|
||||||
|
|
||||||
val wb_toint_valid = wb_reg_valid && wb_ctrl.toint
|
val wb_toint_valid = wb_reg_valid && wb_ctrl.toint
|
||||||
val wb_toint_exc = RegEnable(fpiu.io.out.bits.exc, mem_ctrl.toint)
|
val wb_toint_exc = RegEnable(fpiu.io.out.bits.exc, mem_ctrl.toint)
|
||||||
@ -478,8 +503,8 @@ class FPU extends Module
|
|||||||
io.ctrl.nack_mem := units_busy || write_port_busy
|
io.ctrl.nack_mem := units_busy || write_port_busy
|
||||||
io.ctrl.dec <> fp_decoder.io.sigs
|
io.ctrl.dec <> fp_decoder.io.sigs
|
||||||
def useScoreboard(f: ((Pipe, Int)) => Bool) = pipes.zipWithIndex.filter(_._1.lat > 3).map(x => f(x)).fold(Bool(false))(_||_)
|
def useScoreboard(f: ((Pipe, Int)) => Bool) = pipes.zipWithIndex.filter(_._1.lat > 3).map(x => f(x)).fold(Bool(false))(_||_)
|
||||||
io.ctrl.sboard_set := wb_reg_valid && Reg(next=useScoreboard(_._1.cond(mem_ctrl)))
|
io.ctrl.sboard_set := wb_reg_valid && !wb_cp_valid && Reg(next=useScoreboard(_._1.cond(mem_ctrl)))
|
||||||
io.ctrl.sboard_clr := wen(0) && useScoreboard(x => wsrc === UInt(x._2))
|
io.ctrl.sboard_clr := wen(0) && !wb_cp_valid && useScoreboard(x => wsrc === UInt(x._2))
|
||||||
io.ctrl.sboard_clra := waddr
|
io.ctrl.sboard_clra := waddr
|
||||||
// we don't currently support round-max-magnitude (rm=4)
|
// we don't currently support round-max-magnitude (rm=4)
|
||||||
io.ctrl.illegal_rm := ex_rm(2) && ex_ctrl.round
|
io.ctrl.illegal_rm := ex_rm(2) && ex_ctrl.round
|
||||||
|
@ -49,6 +49,8 @@ class RoCCInterface extends Bundle
|
|||||||
val iptw = new TLBPTWIO
|
val iptw = new TLBPTWIO
|
||||||
val dptw = new TLBPTWIO
|
val dptw = new TLBPTWIO
|
||||||
val pptw = new TLBPTWIO
|
val pptw = new TLBPTWIO
|
||||||
|
val fpu_req = Decoupled(new FPInput)
|
||||||
|
val fpu_resp = Decoupled(new FPResult).flip
|
||||||
val exception = Bool(INPUT)
|
val exception = Bool(INPUT)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user