1
0

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:
Andrew Waterman 2016-08-17 00:57:35 -07:00 committed by Howard Mao
parent fee5d2b1ea
commit 3f8c60bbd6
11 changed files with 61 additions and 79 deletions

@ -1 +1 @@
Subproject commit dc0537b4a3c486d10cad6d0cf33547aef8bfbbbb
Subproject commit ae2ca70b4c50ad34751c9aa732ac404e61508f5e

View File

@ -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

View File

@ -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

@ -1 +1 @@
Subproject commit 5db4abebb7ceb5939a9efca158d78e3dc0e32c44
Subproject commit 197760a962633d0e6140bcff16b96cc3d6b4e776

View File

@ -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 }
}
}

View File

@ -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),

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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"

View File

@ -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)