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:
parent
fee5d2b1ea
commit
3f8c60bbd6
@ -1 +1 @@
|
||||
Subproject commit dc0537b4a3c486d10cad6d0cf33547aef8bfbbbb
|
||||
Subproject commit ae2ca70b4c50ad34751c9aa732ac404e61508f5e
|
@ -79,6 +79,18 @@ class BaseCoreplexConfig extends Config (
|
||||
case NUncachedTileLinkPorts => 1
|
||||
//Tile Constants
|
||||
case BuildTiles => {
|
||||
val env = if(site(UseVM)) List("p","v") else List("p")
|
||||
site(FPUKey) foreach { case cfg =>
|
||||
TestGeneration.addSuite(rv32udBenchmarks)
|
||||
TestGeneration.addSuites(env.map(rv64ufNoDiv))
|
||||
TestGeneration.addSuites(env.map(rv64udNoDiv))
|
||||
if (cfg.divSqrt) {
|
||||
TestGeneration.addSuites(env.map(rv64uf))
|
||||
TestGeneration.addSuites(env.map(rv64ud))
|
||||
}
|
||||
}
|
||||
if (site(UseAtomics)) TestGeneration.addSuites(env.map(if (site(XLen) == 64) rv64ua else rv32ua))
|
||||
if (site(UseCompressed)) TestGeneration.addSuites(env.map(if (site(XLen) == 64) rv64uc else rv32uc))
|
||||
val (rvi, rvu) =
|
||||
if (site(XLen) == 64) ((if (site(UseVM)) rv64i else rv64pi), rv64u)
|
||||
else ((if (site(UseVM)) rv32i else rv32pi), rv32u)
|
||||
@ -105,36 +117,13 @@ class BaseCoreplexConfig extends Config (
|
||||
case NBreakpoints => 1
|
||||
case FastLoadWord => true
|
||||
case FastLoadByte => false
|
||||
case MulUnroll => 8
|
||||
case DivEarlyOut => true
|
||||
case XLen => 64
|
||||
case UseFPU => {
|
||||
val env = if(site(UseVM)) List("p","v") else List("p")
|
||||
TestGeneration.addSuite(rv32udBenchmarks)
|
||||
if(site(FDivSqrt)) {
|
||||
TestGeneration.addSuites(env.map(rv64uf))
|
||||
TestGeneration.addSuites(env.map(rv64ud))
|
||||
} else {
|
||||
TestGeneration.addSuites(env.map(rv64ufNoDiv))
|
||||
TestGeneration.addSuites(env.map(rv64udNoDiv))
|
||||
}
|
||||
true
|
||||
}
|
||||
case UseAtomics => {
|
||||
val env = if(site(UseVM)) List("p","v") else List("p")
|
||||
TestGeneration.addSuites(env.map(if (site(XLen) == 64) rv64ua else rv32ua))
|
||||
true
|
||||
}
|
||||
case UseCompressed => {
|
||||
val env = if(site(UseVM)) List("p","v") else List("p")
|
||||
TestGeneration.addSuites(env.map(if (site(XLen) == 64) rv64uc else rv32uc))
|
||||
true
|
||||
}
|
||||
case FPUKey => Some(FPUConfig())
|
||||
case MulDivKey => Some(MulDivConfig())
|
||||
case UseAtomics => true
|
||||
case UseCompressed => true
|
||||
case PLICKey => PLICConfig(site(NTiles), site(UseVM), site(NExtInterrupts), 0)
|
||||
case DMKey => new DefaultDebugModuleConfig(site(NTiles), site(XLen))
|
||||
case FDivSqrt => true
|
||||
case SFMALatency => 2
|
||||
case DFMALatency => 3
|
||||
case NCustomMRWCSRs => 0
|
||||
case ResetVector => BigInt(0x1000)
|
||||
case MtvecInit => BigInt(0x1010)
|
||||
@ -336,7 +325,7 @@ class WithRV32 extends Config(
|
||||
case UseVM => false
|
||||
case UseUser => false
|
||||
case UseAtomics => false
|
||||
case UseFPU => false
|
||||
case FPUKey => None
|
||||
case RegressionTestNames => LinkedHashSet(
|
||||
"rv32mi-p-ma_addr",
|
||||
"rv32mi-p-csr",
|
||||
@ -357,9 +346,7 @@ class WithBlockingL1 extends Config (
|
||||
|
||||
class WithSmallCores extends Config (
|
||||
topDefinitions = { (pname,site,here) => pname match {
|
||||
case UseFPU => false
|
||||
case MulUnroll => 1
|
||||
case DivEarlyOut => false
|
||||
case FPUKey => None
|
||||
case NTLBEntries => 4
|
||||
case BtbKey => BtbParameters(nEntries = 0)
|
||||
case StoreDataQueueDepth => 2
|
||||
|
@ -29,7 +29,7 @@ class WithComparator extends Config(
|
||||
operations = 1000,
|
||||
atomics = site(UseAtomics),
|
||||
prefetches = site("COMPARATOR_PREFETCHES"))
|
||||
case UseFPU => false
|
||||
case FPUConfig => None
|
||||
case UseAtomics => false
|
||||
case "COMPARATOR_PREFETCHES" => false
|
||||
case _ => throw new CDEMatchError
|
||||
@ -193,7 +193,7 @@ class WithDirectComparator extends Config(
|
||||
operations = 1000,
|
||||
atomics = site(UseAtomics),
|
||||
prefetches = site("COMPARATOR_PREFETCHES"))
|
||||
case UseFPU => false
|
||||
case FPUConfig => None
|
||||
case UseAtomics => false
|
||||
case "COMPARATOR_PREFETCHES" => false
|
||||
case _ => throw new CDEMatchError
|
||||
|
2
firrtl
2
firrtl
@ -1 +1 @@
|
||||
Subproject commit 5db4abebb7ceb5939a9efca158d78e3dc0e32c44
|
||||
Subproject commit 197760a962633d0e6140bcff16b96cc3d6b4e776
|
@ -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)
|
||||
|
@ -69,7 +69,7 @@ class BasePlatformConfig extends Config (
|
||||
res append "};\n"
|
||||
res append "core {\n"
|
||||
for (i <- 0 until site(NTiles)) {
|
||||
val isa = s"rv${site(XLen)}im${if (site(UseAtomics)) "a" else ""}${if (site(UseFPU)) "fd" else ""}"
|
||||
val isa = s"rv${site(XLen)}im${if (site(UseAtomics)) "a" else ""}${if (site(FPUKey).nonEmpty) "fd" else ""}"
|
||||
res append s" $i {\n"
|
||||
res append " 0 {\n"
|
||||
res append s" isa $isa;\n"
|
||||
|
@ -30,7 +30,7 @@ class WithUnitTest extends Config(
|
||||
case UnitTests => (testParams: Parameters) =>
|
||||
JunctionsUnitTests(testParams) ++ UncoreUnitTests(testParams)
|
||||
case NMemoryChannels => Dump("N_MEM_CHANNELS", 0)
|
||||
case UseFPU => false
|
||||
case FPUKey => None
|
||||
case UseAtomics => false
|
||||
case UseCompressed => false
|
||||
case RegressionTestNames => LinkedHashSet("rv64ui-p-simple")
|
||||
@ -78,7 +78,7 @@ class WithGroundTest extends Config(
|
||||
}
|
||||
}
|
||||
}
|
||||
case UseFPU => false
|
||||
case FPUKey => None
|
||||
case UseAtomics => false
|
||||
case UseCompressed => false
|
||||
case RegressionTestNames => LinkedHashSet("rv64ui-p-simple")
|
||||
@ -199,6 +199,7 @@ class WithBusMasterTest extends Config(
|
||||
}
|
||||
Seq(new BusMasterDevice)
|
||||
}
|
||||
case _ => throw new CDEMatchError
|
||||
})
|
||||
|
||||
class BusMasterTestConfig extends Config(new WithBusMasterTest ++ new GroundTestConfig)
|
||||
|
Loading…
Reference in New Issue
Block a user