Skip to content

Commit e602d91

Browse files
Merge pull request #2368 from ucb-bar/cospike_iobinders
cosim: pass the elaborated device map, custom CSRs, register widths a…
2 parents bfe3027 + bf81ed0 commit e602d91

1 file changed

Lines changed: 44 additions & 5 deletions

File tree

generators/chipyard/src/main/scala/iobinders/IOBinders.scala

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -489,17 +489,38 @@ class WithTraceIOPunchthrough extends OverrideLazyIOBinder({
489489
val chipyardSystem = system.asInstanceOf[ChipyardSystem]
490490
val tiles = chipyardSystem.totalTiles.values
491491
val viewpointBus = system.asInstanceOf[HasConfigurableTLNetworkTopology].viewpointBus
492+
val ignoreAddresses = Seq(
493+
BigInt(0x10000) // bootrom is handled specially
494+
)
495+
// The debug module goes in neither list: access is denied outside debug mode,
496+
// so spike having no device there is what makes both models fault.
497+
val debugAddresses = p(DebugModuleKey).toSeq.map(_.address.base)
498+
val skipAddresses = ignoreAddresses ++ debugAddresses
499+
val memRegionTypes = Seq(RegionType.CACHED, RegionType.TRACKED,
500+
RegionType.UNCACHED, RegionType.IDEMPOTENT)
492501
val mems = viewpointBus.unifyManagers.filter { m =>
493-
val regionTypes = Seq(RegionType.CACHED, RegionType.TRACKED, RegionType.UNCACHED, RegionType.IDEMPOTENT)
494-
val ignoreAddresses = Seq(
495-
0x10000 // bootrom is handled specially
496-
)
497-
regionTypes.contains(m.regionType) && !ignoreAddresses.contains(m.address.map(_.base).min)
502+
memRegionTypes.contains(m.regionType) && !skipAddresses.contains(m.address.map(_.base).min)
503+
}.map { m =>
504+
val base = m.address.map(_.base).min
505+
val size = m.address.map(_.max).max - base + 1
506+
(base, size)
507+
}
508+
// A device is anything in the map that is not memory. The complement, not a
509+
// list of region types: enumerating types silently omits any rocket adds or
510+
// renames, which is how RegionType.VOLATILE (rocket's TLError) was missed.
511+
val devices = viewpointBus.unifyManagers.filter { m =>
512+
!memRegionTypes.contains(m.regionType) && !skipAddresses.contains(m.address.map(_.base).min)
498513
}.map { m =>
499514
val base = m.address.map(_.base).min
500515
val size = m.address.map(_.max).max - base + 1
501516
(base, size)
502517
}
518+
// Asserted, not assumed: a later change to the address map, the region types
519+
// or the filter above fails elaboration instead of hiding a bug class.
520+
require(!devices.exists { case (base, size) =>
521+
debugAddresses.exists(d => d >= base && d < base + size) },
522+
s"cospike: the debug module must not be registered as a device " +
523+
s"(devices=$devices, debug=$debugAddresses)")
503524
val useSimDTM = p(ExportDebug).protocols.contains(DMI) // assume that exposing clockeddmi means we will connect SimDTM
504525
val cfg = SpikeCosimConfig(
505526
isa = tiles.headOption.map(_.isaDTS).getOrElse(""),
@@ -510,6 +531,24 @@ class WithTraceIOPunchthrough extends OverrideLazyIOBinder({
510531
bootrom = chipyardSystem.bootROM.headOption.map(_.module.contents.toArray.mkString(" ")).getOrElse(""),
511532
has_dtm = useSimDTM,
512533
mems = mems,
534+
devices = devices,
535+
customCSRs = tiles.headOption.toSeq.flatMap { t =>
536+
// t.p, not p: CustomCSRs builds a CoreBundle, which needs p(TileKey).
537+
t.tileParams.core.customCSRs(t.p).decls.map(c =>
538+
(c.id, c.mask, c.init.getOrElse(BigInt(0))))
539+
},
540+
paddrBits = viewpointBus.busView.bundle.addressBits,
541+
// Mirrors HasTileParameters.{vaddrBits,vpnBitsExtended}, which tiles do
542+
// not mix in (BaseTile only gets HasNonDiplomaticTileParameters).
543+
vaddrBitsExtended = tiles.headOption.map { t =>
544+
val pa = viewpointBus.busView.bundle.addressBits
545+
val va = if (t.usingVM) t.maxHVAddrBits else ((pa + 1) min t.xLen)
546+
va + (if (va < t.xLen) 1 + (if (t.usingHypervisor) 1 else 0) else 0)
547+
}.getOrElse(0),
548+
// The CSR count, not nPMPs: rocket fixes it at CSR.maxPMPs if any PMP exists.
549+
npmpcsrs = tiles.headOption.map(t =>
550+
if (t.tileParams.core.nPMPs > 0) freechips.rocketchip.rocket.CSR.maxPMPs
551+
else 0).getOrElse(0),
513552
// Connect using the legacy API for firesim only
514553
mem0_base = p(ExtMem).map(_.master.base).getOrElse(BigInt(0)),
515554
mem0_size = p(ExtMem).map(_.master.size).getOrElse(BigInt(0)),

0 commit comments

Comments
 (0)