1
0

rocket: make RocketTileParams trivial to serialize

By storing ECC setting as Option[String] and converting it
to a scala Code class later.
This commit is contained in:
Henry Cook 2018-03-19 12:28:48 -07:00
parent 12997a644d
commit 70895b6ffa
6 changed files with 38 additions and 24 deletions

View File

@ -15,16 +15,15 @@ import TLMessages._
class DCacheErrors(implicit p: Parameters) extends L1HellaCacheBundle()(p)
with CanHaveErrors {
val correctable = (cacheParams.tagECC.canCorrect || cacheParams.dataECC.canCorrect).option(Valid(UInt(width = paddrBits)))
val uncorrectable = (cacheParams.tagECC.canDetect || cacheParams.dataECC.canDetect).option(Valid(UInt(width = paddrBits)))
val correctable = (cacheParams.tagCode.canCorrect || cacheParams.dataCode.canCorrect).option(Valid(UInt(width = paddrBits)))
val uncorrectable = (cacheParams.tagCode.canDetect || cacheParams.dataCode.canDetect).option(Valid(UInt(width = paddrBits)))
val bus = Valid(UInt(width = paddrBits))
}
class DCacheDataReq(implicit p: Parameters) extends L1HellaCacheBundle()(p) {
val eccBytes = cacheParams.dataECCBytes
val addr = Bits(width = untagBits)
val write = Bool()
val wdata = UInt(width = cacheParams.dataECC.width(eccBytes*8) * rowBytes/eccBytes)
val wdata = UInt(width = encBits * rowBytes / eccBytes)
val wordMask = UInt(width = rowBytes / wordBytes)
val eccMask = UInt(width = wordBytes / eccBytes)
val way_en = Bits(width = nWays)
@ -37,9 +36,6 @@ class DCacheDataArray(implicit p: Parameters) extends L1HellaCacheModule()(p) {
}
require(rowBytes % wordBytes == 0)
val eccBits = cacheParams.dataECCBytes * 8
val encBits = cacheParams.dataECC.width(eccBits)
val encWordBits = encBits * (wordBits / eccBits)
val eccMask = if (eccBits == wordBits) Seq(true.B) else io.req.bits.eccMask.toBools
val wMask = if (nWays == 1) eccMask else (0 until nWays).flatMap(i => eccMask.map(_ && io.req.bits.way_en(i)))
val wWords = io.req.bits.wdata.grouped(encBits * (wordBits / eccBits))
@ -69,11 +65,8 @@ class DCache(hartid: Int, val scratch: () => Option[AddressSet] = () => None, va
}
class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
// no tag ECC support
val tECC = cacheParams.tagECC
val dECC = cacheParams.dataECC
val eccBytes = cacheParams.dataECCBytes
val eccBits = eccBytes * 8
val tECC = cacheParams.tagCode
val dECC = cacheParams.dataCode
require(isPow2(eccBytes) && eccBytes <= wordBytes)
require(eccBytes == 1 || !dECC.isInstanceOf[IdentityCode])
val usingRMW = eccBytes > 1 || usingAtomicsInCache

View File

@ -19,8 +19,8 @@ case class DCacheParams(
nWays: Int = 4,
rowBits: Int = 64,
nTLBEntries: Int = 32,
tagECC: Code = new IdentityCode,
dataECC: Code = new IdentityCode,
tagECC: Option[String] = None,
dataECC: Option[String] = None,
dataECCBytes: Int = 1,
nMSHRs: Int = 1,
nSDQ: Int = 17,
@ -31,6 +31,9 @@ case class DCacheParams(
pipelineWayMux: Boolean = false,
scratch: Option[BigInt] = None) extends L1CacheParams {
def tagCode: Code = Code.fromString(tagECC)
def dataCode: Code = Code.fromString(dataECC)
def dataScratchpadBytes: Int = scratch.map(_ => nSets*blockBytes).getOrElse(0)
def replacement = new RandomReplacement(nWays)
@ -58,7 +61,11 @@ trait HasL1HellaCacheParameters extends HasL1CacheParameters with HasCoreParamet
def offsetlsb = wordOffBits
def rowWords = rowBits/wordBits
def doNarrowRead = coreDataBits * nWays % rowBits == 0
def encDataBits = cacheParams.dataECC.width(coreDataBits)
def eccBytes = cacheParams.dataECCBytes
val eccBits = cacheParams.dataECCBytes * 8
val encBits = cacheParams.dataCode.width(eccBits)
val encWordBits = encBits * (wordBits / eccBits)
def encDataBits = cacheParams.dataCode.width(coreDataBits) // NBDCache only
def encRowBits = encDataBits*rowWords
def lrscCycles = 32 // ISA requires 16-insn LRSC sequences to succeed
def lrscBackoff = 3 // disallow LRSC reacquisition briefly

View File

@ -20,13 +20,15 @@ case class ICacheParams(
rowBits: Int = 128,
nTLBEntries: Int = 32,
cacheIdBits: Int = 0,
tagECC: Code = new IdentityCode,
dataECC: Code = new IdentityCode,
tagECC: Option[String] = None,
dataECC: Option[String] = None,
itimAddr: Option[BigInt] = None,
prefetch: Boolean = false,
blockBytes: Int = 64,
latency: Int = 2,
fetchBytes: Int = 4) extends L1CacheParams {
def tagCode: Code = Code.fromString(tagECC)
def dataCode: Code = Code.fromString(dataECC)
def replacement = new RandomReplacement(nWays)
}
@ -41,8 +43,8 @@ class ICacheReq(implicit p: Parameters) extends CoreBundle()(p) with HasL1ICache
class ICacheErrors(implicit p: Parameters) extends CoreBundle()(p)
with HasL1ICacheParameters
with CanHaveErrors {
val correctable = (cacheParams.tagECC.canDetect || cacheParams.dataECC.canDetect).option(Valid(UInt(width = paddrBits)))
val uncorrectable = (cacheParams.itimAddr.nonEmpty && cacheParams.dataECC.canDetect).option(Valid(UInt(width = paddrBits)))
val correctable = (cacheParams.tagCode.canDetect || cacheParams.dataCode.canDetect).option(Valid(UInt(width = paddrBits)))
val uncorrectable = (cacheParams.itimAddr.nonEmpty && cacheParams.dataCode.canDetect).option(Valid(UInt(width = paddrBits)))
}
class ICache(val icacheParams: ICacheParams, val hartId: Int)(implicit p: Parameters) extends LazyModule {
@ -113,8 +115,8 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer)
// Option.unzip does not exist :-(
val (tl_in, edge_in) = outer.slaveNode.in.headOption.unzip
val tECC = cacheParams.tagECC
val dECC = cacheParams.dataECC
val tECC = cacheParams.tagCode
val dECC = cacheParams.dataCode
require(isPow2(nSets) && isPow2(nWays))
require(!usingVM || pgIdxBits >= untagBits)

View File

@ -668,8 +668,8 @@ class NonBlockingDCacheModule(outer: NonBlockingDCache) extends HellaCacheModule
require(dataScratchpadSize == 0)
// ECC is only supported on the data array
require(cacheParams.tagECC.isInstanceOf[IdentityCode])
val dECC = cacheParams.dataECC
require(cacheParams.tagCode.isInstanceOf[IdentityCode])
val dECC = cacheParams.dataCode
val wb = Module(new WritebackUnit)
val prober = Module(new ProbeUnit)

View File

@ -572,7 +572,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p)
sboard.clear(ll_wen, ll_waddr)
def id_sboard_clear_bypass(r: UInt) = {
// ll_waddr arrives late when D$ has ECC, so reshuffle the hazard check
if (tileParams.dcache.get.dataECC.isInstanceOf[IdentityCode]) ll_wen && ll_waddr === r
if (!tileParams.dcache.get.dataECC.isDefined) ll_wen && ll_waddr === r
else div.io.resp.fire() && div.io.resp.bits.tag === r || dmem_resp_replay && dmem_resp_xpu && dmem_resp_waddr === r
}
val id_sboard_hazard = checkHazards(hazard_targets, rd => sboard.read(rd) && !id_sboard_clear_bypass(rd))

View File

@ -178,3 +178,15 @@ trait CanHaveErrors extends Bundle {
val correctable: Option[ValidIO[UInt]]
val uncorrectable: Option[ValidIO[UInt]]
}
object Code {
def fromString(s: Option[String]): Code = fromString(s.getOrElse("none"))
def fromString(s: String): Code = s.toLowerCase match {
case "none" => new IdentityCode
case "identity" => new IdentityCode
case "parity" => new ParityCode
case "sec" => new SECCode
case "secded" => new SECDEDCode
case _ => throw new IllegalArgumentException("Unknown ECC type")
}
}