Merge pull request #1299 from freechipsproject/serializable-metadata
Store metadata in serializable case classes
This commit is contained in:
commit
7593baf2aa
75
src/main/scala/diplomacy/AddressRange.scala
Normal file
75
src/main/scala/diplomacy/AddressRange.scala
Normal file
@ -0,0 +1,75 @@
|
||||
// See LICENSE.SiFive for license details.
|
||||
|
||||
package freechips.rocketchip.diplomacy
|
||||
|
||||
import Chisel._
|
||||
|
||||
// Use AddressSet instead -- this is just for pretty printing
|
||||
case class AddressRange(base: BigInt, size: BigInt) extends Ordered[AddressRange]
|
||||
{
|
||||
val end = base + size
|
||||
|
||||
require (base >= 0, s"AddressRange base must be positive, got: $base")
|
||||
require (size > 0, s"AddressRange size must be > 0, got: $size")
|
||||
|
||||
def compare(x: AddressRange) = {
|
||||
val primary = (this.base - x.base).signum
|
||||
val secondary = (x.size - this.size).signum
|
||||
if (primary != 0) primary else secondary
|
||||
}
|
||||
|
||||
def contains(x: AddressRange) = base <= x.base && x.end <= end
|
||||
def union(x: AddressRange): Option[AddressRange] = {
|
||||
if (base > x.end || x.base > end) {
|
||||
None
|
||||
} else {
|
||||
val obase = if (base < x.base) base else x.base
|
||||
val oend = if (end > x.end) end else x.end
|
||||
Some(AddressRange(obase, oend-obase))
|
||||
}
|
||||
}
|
||||
|
||||
private def helper(base: BigInt, end: BigInt) =
|
||||
if (base < end) Seq(AddressRange(base, end-base)) else Nil
|
||||
def subtract(x: AddressRange) =
|
||||
helper(base, end min x.base) ++ helper(base max x.end, end)
|
||||
|
||||
// We always want to see things in hex
|
||||
override def toString() = "AddressRange(0x%x, 0x%x)".format(base, size)
|
||||
}
|
||||
|
||||
object AddressRange
|
||||
{
|
||||
def fromSets(seq: Seq[AddressSet]): Seq[AddressRange] = unify(seq.flatMap(_.toRanges))
|
||||
def unify(seq: Seq[AddressRange]): Seq[AddressRange] = {
|
||||
if (seq.isEmpty) return Nil
|
||||
val ranges = seq.sorted
|
||||
ranges.tail.foldLeft(Seq(ranges.head)) { case (head :: tail, x) =>
|
||||
head.union(x) match {
|
||||
case Some(z) => z :: tail
|
||||
case None => x :: head :: tail
|
||||
}
|
||||
}.reverse
|
||||
}
|
||||
// Set subtraction... O(n*n) b/c I am lazy
|
||||
def subtract(from: Seq[AddressRange], take: Seq[AddressRange]): Seq[AddressRange] =
|
||||
take.foldLeft(from) { case (left, r) => left.flatMap { _.subtract(r) } }
|
||||
}
|
||||
|
||||
case class AddressMapEntry(range: AddressRange, permissions: ResourcePermissions, names: Seq[String]) {
|
||||
val ResourcePermissions(r, w, x, c, a) = permissions
|
||||
|
||||
def toString(aw: Int) = s"\t%${aw}x - %${aw}x %c%c%c%c%c %s".format(
|
||||
range.base,
|
||||
range.base+range.size,
|
||||
if (a) 'A' else ' ',
|
||||
if (r) 'R' else ' ',
|
||||
if (w) 'W' else ' ',
|
||||
if (x) 'X' else ' ',
|
||||
if (c) 'C' else ' ',
|
||||
names.mkString(", "))
|
||||
|
||||
def serialize = s"""{"base":[${range.base}],"size":[${range.size}],""" +
|
||||
s""""r":[$r],"w":[$w],"x":[$x],"c":[$c],"a":[$a],""" +
|
||||
s""""names":[${names.map('"'+_+'"').mkString(",")}]}"""
|
||||
}
|
@ -104,40 +104,6 @@ object TransferSizes {
|
||||
implicit def asBool(x: TransferSizes) = !x.none
|
||||
}
|
||||
|
||||
// Use AddressSet instead -- this is just for pretty printing
|
||||
case class AddressRange(base: BigInt, size: BigInt) extends Ordered[AddressRange]
|
||||
{
|
||||
val end = base + size
|
||||
|
||||
require (base >= 0, s"AddressRange base must be positive, got: $base")
|
||||
require (size > 0, s"AddressRange size must be > 0, got: $size")
|
||||
|
||||
def compare(x: AddressRange) = {
|
||||
val primary = (this.base - x.base).signum
|
||||
val secondary = (x.size - this.size).signum
|
||||
if (primary != 0) primary else secondary
|
||||
}
|
||||
|
||||
def contains(x: AddressRange) = base <= x.base && x.end <= end
|
||||
def union(x: AddressRange): Option[AddressRange] = {
|
||||
if (base > x.end || x.base > end) {
|
||||
None
|
||||
} else {
|
||||
val obase = if (base < x.base) base else x.base
|
||||
val oend = if (end > x.end) end else x.end
|
||||
Some(AddressRange(obase, oend-obase))
|
||||
}
|
||||
}
|
||||
|
||||
private def helper(base: BigInt, end: BigInt) =
|
||||
if (base < end) Seq(AddressRange(base, end-base)) else Nil
|
||||
def subtract(x: AddressRange) =
|
||||
helper(base, end min x.base) ++ helper(base max x.end, end)
|
||||
|
||||
// We always want to see things in hex
|
||||
override def toString() = "AddressRange(0x%x, 0x%x)".format(base, size)
|
||||
}
|
||||
|
||||
// AddressSets specify the address space managed by the manager
|
||||
// Base is the base address, and mask are the bits consumed by the manager
|
||||
// e.g: base=0x200, mask=0xff describes a device managing 0x200-0x2ff
|
||||
@ -210,24 +176,6 @@ case class AddressSet(base: BigInt, mask: BigInt) extends Ordered[AddressSet]
|
||||
}
|
||||
}
|
||||
|
||||
object AddressRange
|
||||
{
|
||||
def fromSets(seq: Seq[AddressSet]): Seq[AddressRange] = unify(seq.flatMap(_.toRanges))
|
||||
def unify(seq: Seq[AddressRange]): Seq[AddressRange] = {
|
||||
if (seq.isEmpty) return Nil
|
||||
val ranges = seq.sorted
|
||||
ranges.tail.foldLeft(Seq(ranges.head)) { case (head :: tail, x) =>
|
||||
head.union(x) match {
|
||||
case Some(z) => z :: tail
|
||||
case None => x :: head :: tail
|
||||
}
|
||||
}.reverse
|
||||
}
|
||||
// Set subtraction... O(n*n) b/c I am lazy
|
||||
def subtract(from: Seq[AddressRange], take: Seq[AddressRange]): Seq[AddressRange] =
|
||||
take.foldLeft(from) { case (left, r) => left.flatMap { _.subtract(r) } }
|
||||
}
|
||||
|
||||
object AddressSet
|
||||
{
|
||||
val everything = AddressSet(0, -1)
|
||||
|
@ -251,6 +251,15 @@ trait BindingScope
|
||||
}
|
||||
}
|
||||
|
||||
private def collect(path: List[String], value: ResourceValue): List[(String, ResourceAddress)] = {
|
||||
value match {
|
||||
case r: ResourceAddress => List((path(1), r))
|
||||
case b: ResourceMapping => List((path(1), ResourceAddress(b.address, b.permissions)))
|
||||
case ResourceMap(value, _) => value.toList.flatMap { case (key, seq) => seq.flatMap(r => collect(key :: path, r)) }
|
||||
case _ => Nil
|
||||
}
|
||||
}
|
||||
|
||||
/** Generate the device tree. */
|
||||
def bindingTree: ResourceMap = {
|
||||
eval
|
||||
@ -263,6 +272,9 @@ trait BindingScope
|
||||
expand(tokens, Seq(ResourceMap(mapping, Seq(d.label)))) })
|
||||
ResourceMap(SortedMap("/" -> tree))
|
||||
}
|
||||
|
||||
/** Collect resource addresses from tree. */
|
||||
def collectResourceAddresses = collect(Nil, bindingTree)
|
||||
}
|
||||
|
||||
object BindingScope
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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))
|
||||
|
@ -97,39 +97,22 @@ abstract class BaseSubsystem(implicit p: Parameters) extends BareSubsystem {
|
||||
}
|
||||
}
|
||||
|
||||
abstract class BaseSubsystemModuleImp[+L <: BaseSubsystem](_outer: L) extends BareSubsystemModuleImp(_outer) {
|
||||
println("Generated Address Map")
|
||||
private val aw = (outer.sbus.busView.bundle.addressBits-1)/4 + 1
|
||||
private val fmt = s"\t%${aw}x - %${aw}x %c%c%c%c%c %s"
|
||||
|
||||
private def collect(path: List[String], value: ResourceValue): List[(String, ResourceAddress)] = {
|
||||
value match {
|
||||
case r: ResourceAddress => List((path(1), r))
|
||||
case b: ResourceMapping => List((path(1), ResourceAddress(b.address, b.permissions)))
|
||||
case ResourceMap(value, _) => value.toList.flatMap { case (key, seq) => seq.flatMap(r => collect(key :: path, r)) }
|
||||
case _ => Nil
|
||||
}
|
||||
}
|
||||
private val ranges = collect(Nil, outer.bindingTree).groupBy(_._2).toList.flatMap { case (key, seq) =>
|
||||
AddressRange.fromSets(key.address).map { r => (r, key.permissions, seq.map(_._1)) }
|
||||
}.sortBy(_._1)
|
||||
private val json = ranges.map { case (range, ResourcePermissions(r, w, x, c, a), names) =>
|
||||
println(fmt.format(
|
||||
range.base,
|
||||
range.base+range.size,
|
||||
if (a) 'A' else ' ',
|
||||
if (r) 'R' else ' ',
|
||||
if (w) 'W' else ' ',
|
||||
if (x) 'X' else ' ',
|
||||
if (c) 'C' else ' ',
|
||||
names.mkString(", ")))
|
||||
s"""{"base":[${range.base}],"size":[${range.size}],"r":[$r],"w":[$w],"x":[$x],"c":[$c],"a":[$a],"names":[${names.map('"'+_+'"').mkString(",")}]}"""
|
||||
abstract class BaseSubsystemModuleImp[+L <: BaseSubsystem](_outer: L) extends BareSubsystemModuleImp(_outer) {
|
||||
private val mapping: Seq[AddressMapEntry] = {
|
||||
outer.collectResourceAddresses.groupBy(_._2).toList.flatMap { case (key, seq) =>
|
||||
AddressRange.fromSets(key.address).map { r => AddressMapEntry(r, key.permissions, seq.map(_._1)) }
|
||||
}.sortBy(_.range)
|
||||
}
|
||||
|
||||
println("Generated Address Map")
|
||||
mapping.map(entry => println(entry.toString((outer.sbus.busView.bundle.addressBits-1)/4 + 1)))
|
||||
println("")
|
||||
ElaborationArtefacts.add("memmap.json", s"""{"mapping":[${json.mkString(",")}]}""")
|
||||
|
||||
ElaborationArtefacts.add("memmap.json", s"""{"mapping":[${mapping.map(_.serialize).mkString(",")}]}""")
|
||||
|
||||
// Confirm that all of memory was described by DTS
|
||||
private val dtsRanges = AddressRange.unify(ranges.map(_._1))
|
||||
private val dtsRanges = AddressRange.unify(mapping.map(_.range))
|
||||
private val allRanges = AddressRange.unify(outer.topManagers.get.flatMap { m => AddressRange.fromSets(m.address) })
|
||||
|
||||
if (dtsRanges != allRanges) {
|
||||
|
@ -9,6 +9,30 @@ import freechips.rocketchip.util._
|
||||
import freechips.rocketchip.amba.axi4._
|
||||
import scala.math.{min, max}
|
||||
|
||||
class TLtoAXI4IdMap(tl: TLClientPortParameters, axi4: AXI4MasterPortParameters) {
|
||||
private val axiDigits = String.valueOf(axi4.endId-1).length()
|
||||
private val tlDigits = String.valueOf(tl.endSourceId-1).length()
|
||||
private val fmt = s"\t[%${axiDigits}d, %${axiDigits}d) <= [%${tlDigits}d, %${tlDigits}d) %s%s%s"
|
||||
private val sorted = tl.clients.sortWith(TLToAXI4.sortByType)
|
||||
|
||||
val mapping: Seq[TLToAXI4IdMapEntry] = (sorted zip axi4.masters) map { case (c, m) =>
|
||||
TLToAXI4IdMapEntry(m.id, c.sourceId, c.name, c.supportsProbe, c.requestFifo)
|
||||
}
|
||||
|
||||
def pretty: String = mapping.map(_.pretty(fmt)).mkString(",\n")
|
||||
}
|
||||
|
||||
case class TLToAXI4IdMapEntry(axi4Id: IdRange, tlId: IdRange, name: String, isCache: Boolean, requestFifo: Boolean) {
|
||||
def pretty(fmt: String) = fmt.format(
|
||||
axi4Id.start,
|
||||
axi4Id.end,
|
||||
tlId.start,
|
||||
tlId.end,
|
||||
s""""$name"""",
|
||||
if (isCache) " [CACHE]" else "",
|
||||
if (requestFifo) " [FIFO]" else "")
|
||||
}
|
||||
|
||||
case class TLToAXI4Node(stripBits: Int = 0)(implicit valName: ValName) extends MixedAdapterNode(TLImp, AXI4Imp)(
|
||||
dFn = { p =>
|
||||
p.clients.foreach { c =>
|
||||
@ -59,32 +83,25 @@ class TLToAXI4(val combinational: Boolean = true, val adapterName: Option[String
|
||||
require (slaves(0).interleavedId.isDefined)
|
||||
slaves.foreach { s => require (s.interleavedId == slaves(0).interleavedId) }
|
||||
|
||||
val axiDigits = String.valueOf(edgeOut.master.endId-1).length()
|
||||
val tlDigits = String.valueOf(edgeIn.client.endSourceId-1).length()
|
||||
|
||||
// Construct the source=>ID mapping table
|
||||
adapterName.foreach { n => println(s"$n AXI4-ID <= TL-Source mapping:") }
|
||||
val map = new TLtoAXI4IdMap(edgeIn.client, edgeOut.master)
|
||||
val sourceStall = Wire(Vec(edgeIn.client.endSourceId, Bool()))
|
||||
val sourceTable = Wire(Vec(edgeIn.client.endSourceId, out.aw.bits.id))
|
||||
val idStall = Wire(init = Vec.fill(edgeOut.master.endId) { Bool(false) })
|
||||
var idCount = Array.fill(edgeOut.master.endId) { None:Option[Int] }
|
||||
val maps = (edgeIn.client.clients.sortWith(TLToAXI4.sortByType) zip edgeOut.master.masters) flatMap { case (c, m) =>
|
||||
for (i <- 0 until c.sourceId.size) {
|
||||
val id = m.id.start + (if (c.requestFifo) 0 else (i >> stripBits))
|
||||
sourceStall(c.sourceId.start + i) := idStall(id)
|
||||
sourceTable(c.sourceId.start + i) := UInt(id)
|
||||
}
|
||||
if (c.requestFifo) { idCount(m.id.start) = Some(c.sourceId.size) }
|
||||
adapterName.map { n =>
|
||||
val fmt = s"\t[%${axiDigits}d, %${axiDigits}d) <= [%${tlDigits}d, %${tlDigits}d) %s%s"
|
||||
println(fmt.format(m.id.start, m.id.end, c.sourceId.start, c.sourceId.end, c.name, if (c.supportsProbe) " CACHE" else ""))
|
||||
s"""{"axi4-id":[${m.id.start},${m.id.end}],"tilelink-id":[${c.sourceId.start},${c.sourceId.end}],"master":["${c.name}"],"cache":[${!(!c.supportsProbe)}]}"""
|
||||
|
||||
map.mapping.foreach { case TLToAXI4IdMapEntry(axi4Id, tlId, _, _, fifo) =>
|
||||
for (i <- 0 until tlId.size) {
|
||||
val id = axi4Id.start + (if (fifo) 0 else (i >> stripBits))
|
||||
sourceStall(tlId.start + i) := idStall(id)
|
||||
sourceTable(tlId.start + i) := UInt(id)
|
||||
}
|
||||
if (fifo) { idCount(axi4Id.start) = Some(tlId.size) }
|
||||
}
|
||||
|
||||
adapterName.foreach { n =>
|
||||
println("")
|
||||
ElaborationArtefacts.add(s"${n}.axi4.json", s"""{"mapping":[${maps.mkString(",")}]}""")
|
||||
println(s"$n AXI4-ID <= TL-Source mapping:\n${map.pretty}\n")
|
||||
ElaborationArtefacts.add(s"$n.axi4.json", s"""{"mapping":[${map.mapping.mkString(",")}]}""")
|
||||
}
|
||||
|
||||
// We need to keep the following state from A => D: (size, source)
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user