Hierarchicalize FPU and MulDiv parameters
This gets some leaf-level parameters out of the global parameterization, better separating concerns. This commit also allows disabling the M extension.
This commit is contained in:
committed by
Howard Mao
parent
fee5d2b1ea
commit
3f8c60bbd6
@ -10,8 +10,11 @@ import uncore.constants.MemoryOpConstants._
|
||||
import uncore.util._
|
||||
import cde.{Parameters, Field}
|
||||
|
||||
case object SFMALatency extends Field[Int]
|
||||
case object DFMALatency extends Field[Int]
|
||||
case class FPUConfig(
|
||||
divSqrt: Boolean = true,
|
||||
sfmaLatency: Int = 2,
|
||||
dfmaLatency: Int = 3
|
||||
)
|
||||
|
||||
object FPConstants
|
||||
{
|
||||
@ -414,7 +417,7 @@ class FPUFMAPipe(val latency: Int, expWidth: Int, sigWidth: Int) extends Module
|
||||
io.out := Pipe(valid, res, latency-1)
|
||||
}
|
||||
|
||||
class FPU(implicit p: Parameters) extends CoreModule()(p) {
|
||||
class FPU(cfg: FPUConfig)(implicit p: Parameters) extends CoreModule()(p) {
|
||||
require(xLen == 64, "RV32 Rocket FP support missing")
|
||||
val io = new FPUIO
|
||||
|
||||
@ -489,11 +492,11 @@ class FPU(implicit p: Parameters) extends CoreModule()(p) {
|
||||
req.in3 := Mux(ex_reg_valid, ex_rs3, cp_rs3)
|
||||
req.typ := Mux(ex_reg_valid, ex_reg_inst(21,20), io.cp_req.bits.typ)
|
||||
|
||||
val sfma = Module(new FPUFMAPipe(p(SFMALatency), 8, 24))
|
||||
val sfma = Module(new FPUFMAPipe(cfg.sfmaLatency, 8, 24))
|
||||
sfma.io.in.valid := req_valid && ex_ctrl.fma && ex_ctrl.single
|
||||
sfma.io.in.bits := req
|
||||
|
||||
val dfma = Module(new FPUFMAPipe(p(DFMALatency), 11, 53))
|
||||
val dfma = Module(new FPUFMAPipe(cfg.dfmaLatency, 11, 53))
|
||||
dfma.io.in.valid := req_valid && ex_ctrl.fma && !ex_ctrl.single
|
||||
dfma.io.in.bits := req
|
||||
|
||||
@ -610,7 +613,7 @@ class FPU(implicit p: Parameters) extends CoreModule()(p) {
|
||||
|
||||
divSqrt_wdata := 0
|
||||
divSqrt_flags := 0
|
||||
if (p(FDivSqrt)) {
|
||||
if (cfg.divSqrt) {
|
||||
val divSqrt_single = Reg(Bool())
|
||||
val divSqrt_rm = Reg(Bits())
|
||||
val divSqrt_flags_double = Reg(Bits())
|
||||
@ -645,5 +648,7 @@ class FPU(implicit p: Parameters) extends CoreModule()(p) {
|
||||
divSqrt_toSingle.io.roundingMode := divSqrt_rm
|
||||
divSqrt_wdata := Mux(divSqrt_single, divSqrt_toSingle.io.out, divSqrt_wdata_double)
|
||||
divSqrt_flags := divSqrt_flags_double | Mux(divSqrt_single, divSqrt_toSingle.io.exceptionFlags, Bits(0))
|
||||
} else {
|
||||
when (ex_ctrl.div || ex_ctrl.sqrt) { io.illegal_rm := true }
|
||||
}
|
||||
}
|
||||
|
@ -277,12 +277,7 @@ class F64Decode(implicit val p: Parameters) extends DecodeConstants
|
||||
FCVT_S_L-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N),
|
||||
FCVT_D_L-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N),
|
||||
FCVT_S_LU-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N),
|
||||
FCVT_D_LU-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N))
|
||||
}
|
||||
|
||||
class FDivSqrtDecode(implicit val p: Parameters) extends DecodeConstants
|
||||
{
|
||||
val table: Array[(BitPat, List[BitPat])] = Array(
|
||||
FCVT_D_LU-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N),
|
||||
FDIV_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N),
|
||||
FDIV_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N),
|
||||
FSQRT_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N),
|
||||
|
@ -27,14 +27,16 @@ class MultiplierIO(dataBits: Int, tagBits: Int) extends Bundle {
|
||||
val resp = Decoupled(new MultiplierResp(dataBits, tagBits))
|
||||
}
|
||||
|
||||
class MulDiv(
|
||||
width: Int,
|
||||
nXpr: Int = 32,
|
||||
unroll: Int = 1,
|
||||
earlyOut: Boolean = false) extends Module {
|
||||
case class MulDivConfig(
|
||||
mulUnroll: Int = 1,
|
||||
mulEarlyOut: Boolean = false,
|
||||
divEarlyOut: Boolean = false
|
||||
)
|
||||
|
||||
class MulDiv(cfg: MulDivConfig, width: Int, nXpr: Int = 32) extends Module {
|
||||
val io = new MultiplierIO(width, log2Up(nXpr))
|
||||
val w = io.req.bits.in1.getWidth
|
||||
val mulw = (w+unroll-1)/unroll*unroll
|
||||
val mulw = (w + cfg.mulUnroll - 1) / cfg.mulUnroll * cfg.mulUnroll
|
||||
|
||||
val s_ready :: s_neg_inputs :: s_busy :: s_move_rem :: s_neg_output :: s_done :: Nil = Enum(UInt(), 6)
|
||||
val state = Reg(init=s_ready)
|
||||
@ -96,18 +98,18 @@ class MulDiv(
|
||||
val mplier = mulReg(mulw-1,0)
|
||||
val accum = mulReg(2*mulw,mulw).asSInt
|
||||
val mpcand = divisor.asSInt
|
||||
val prod = mplier(unroll-1,0) * mpcand + accum
|
||||
val nextMulReg = Cat(prod, mplier(mulw-1,unroll))
|
||||
val prod = mplier(cfg.mulUnroll-1, 0) * mpcand + accum
|
||||
val nextMulReg = Cat(prod, mplier(mulw-1, cfg.mulUnroll))
|
||||
|
||||
val eOutMask = (SInt(BigInt(-1) << mulw) >> (count * unroll)(log2Up(mulw)-1,0))(mulw-1,0)
|
||||
val eOut = Bool(earlyOut) && count =/= mulw/unroll-1 && count =/= 0 &&
|
||||
val eOutMask = (SInt(BigInt(-1) << mulw) >> (count * cfg.mulUnroll)(log2Up(mulw)-1,0))(mulw-1,0)
|
||||
val eOut = Bool(cfg.mulEarlyOut) && count =/= mulw/cfg.mulUnroll-1 && count =/= 0 &&
|
||||
!isHi && (mplier & ~eOutMask) === UInt(0)
|
||||
val eOutRes = (mulReg >> (mulw - count * unroll)(log2Up(mulw)-1,0))
|
||||
val eOutRes = (mulReg >> (mulw - count * cfg.mulUnroll)(log2Up(mulw)-1,0))
|
||||
val nextMulReg1 = Cat(nextMulReg(2*mulw,mulw), Mux(eOut, eOutRes, nextMulReg)(mulw-1,0))
|
||||
remainder := Cat(nextMulReg1 >> w, Bool(false), nextMulReg1(w-1,0))
|
||||
|
||||
count := count + 1
|
||||
when (eOut || count === mulw/unroll-1) {
|
||||
when (eOut || count === mulw/cfg.mulUnroll-1) {
|
||||
state := Mux(isHi, s_move_rem, s_done)
|
||||
}
|
||||
}
|
||||
@ -124,7 +126,7 @@ class MulDiv(
|
||||
val eOutPos = UInt(w-1) + divisorMSB - dividendMSB
|
||||
val eOutZero = divisorMSB > dividendMSB
|
||||
val eOut = count === 0 && less /* not divby0 */ && (eOutPos > 0 || eOutZero)
|
||||
when (Bool(earlyOut) && eOut) {
|
||||
when (Bool(cfg.divEarlyOut) && eOut) {
|
||||
val shift = Mux(eOutZero, UInt(w-1), eOutPos(log2Up(w)-1,0))
|
||||
remainder := remainder(w-1,0) << shift
|
||||
count := shift
|
||||
|
@ -10,11 +10,11 @@ import uncore.constants._
|
||||
import Util._
|
||||
import cde.{Parameters, Field}
|
||||
|
||||
case object UseFPU extends Field[Boolean]
|
||||
case object FDivSqrt extends Field[Boolean]
|
||||
case object XLen extends Field[Int]
|
||||
case object FetchWidth extends Field[Int]
|
||||
case object RetireWidth extends Field[Int]
|
||||
case object FPUKey extends Field[Option[FPUConfig]]
|
||||
case object MulDivKey extends Field[Option[MulDivConfig]]
|
||||
case object UseVM extends Field[Boolean]
|
||||
case object UseUser extends Field[Boolean]
|
||||
case object UseDebug extends Field[Boolean]
|
||||
@ -22,8 +22,6 @@ case object UseAtomics extends Field[Boolean]
|
||||
case object UseCompressed extends Field[Boolean]
|
||||
case object FastLoadWord extends Field[Boolean]
|
||||
case object FastLoadByte extends Field[Boolean]
|
||||
case object MulUnroll extends Field[Int]
|
||||
case object DivEarlyOut extends Field[Boolean]
|
||||
case object CoreInstBits extends Field[Int]
|
||||
case object NCustomMRWCSRs extends Field[Int]
|
||||
case object MtvecWritable extends Field[Boolean]
|
||||
@ -38,13 +36,11 @@ trait HasCoreParameters extends HasAddrMapParameters {
|
||||
val usingVM = p(UseVM)
|
||||
val usingUser = p(UseUser) || usingVM
|
||||
val usingDebug = p(UseDebug)
|
||||
val usingFPU = p(UseFPU)
|
||||
val usingMulDiv = p(MulDivKey).nonEmpty
|
||||
val usingFPU = p(FPUKey).nonEmpty
|
||||
val usingAtomics = p(UseAtomics)
|
||||
val usingCompressed = p(UseCompressed)
|
||||
val usingFDivSqrt = p(FDivSqrt)
|
||||
val usingRoCC = !p(BuildRoCC).isEmpty
|
||||
val mulUnroll = p(MulUnroll)
|
||||
val divEarlyOut = p(DivEarlyOut)
|
||||
val fastLoadWord = p(FastLoadWord)
|
||||
val fastLoadByte = p(FastLoadByte)
|
||||
|
||||
@ -144,10 +140,9 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) {
|
||||
}
|
||||
|
||||
val decode_table = {
|
||||
(if (true) new MDecode +: (if (xLen > 32) Seq(new M64Decode) else Nil) else Nil) ++:
|
||||
(if (usingMulDiv) new MDecode +: (if (xLen > 32) Seq(new M64Decode) else Nil) else Nil) ++:
|
||||
(if (usingAtomics) new ADecode +: (if (xLen > 32) Seq(new A64Decode) else Nil) else Nil) ++:
|
||||
(if (usingFPU) new FDecode +: (if (xLen > 32) Seq(new F64Decode) else Nil) else Nil) ++:
|
||||
(if (usingFPU && usingFDivSqrt) Some(new FDivSqrtDecode) else None) ++:
|
||||
(if (usingRoCC) Some(new RoCCDecode) else None) ++:
|
||||
(if (xLen > 32) Some(new I64Decode) else None) ++:
|
||||
(if (usingVM) Some(new SDecode) else None) ++:
|
||||
@ -302,10 +297,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) {
|
||||
alu.io.in1 := ex_op1.asUInt
|
||||
|
||||
// multiplier and divider
|
||||
val div = Module(new MulDiv(width = xLen,
|
||||
unroll = mulUnroll,
|
||||
earlyOut = divEarlyOut))
|
||||
|
||||
val div = Module(new MulDiv(p(MulDivKey).getOrElse(MulDivConfig()), width = xLen))
|
||||
div.io.req.valid := ex_reg_valid && ex_ctrl.div
|
||||
div.io.req.bits.dw := ex_ctrl.alu_dw
|
||||
div.io.req.bits.fn := ex_ctrl.alu_fn
|
||||
|
@ -56,7 +56,7 @@ class RocketTile(clockSignal: Clock = null, resetSignal: Bool = null)
|
||||
core.io.prci <> io.prci
|
||||
icache.io.cpu <> core.io.imem
|
||||
|
||||
val fpuOpt = if (p(UseFPU)) Some(Module(new FPU)) else None
|
||||
val fpuOpt = p(FPUKey).map(cfg => Module(new FPU(cfg)))
|
||||
fpuOpt.foreach(fpu => core.io.fpu <> fpu.io)
|
||||
|
||||
if (usingRocc) {
|
||||
@ -127,7 +127,7 @@ class RocketTile(clockSignal: Clock = null, resetSignal: Bool = null)
|
||||
dcArb.io.requestor <> dcPorts
|
||||
dcache.cpu <> dcArb.io.mem
|
||||
|
||||
if (!usingRocc || nFPUPorts == 0) {
|
||||
if (nFPUPorts == 0) {
|
||||
fpuOpt.foreach { fpu =>
|
||||
fpu.io.cp_req.valid := Bool(false)
|
||||
fpu.io.cp_resp.ready := Bool(false)
|
||||
|
Reference in New Issue
Block a user