Skip to content

Commit 0fb0574

Browse files
authored
Merge pull request #3699 from chipsalliance/multi-rom
Support multiple ROMs
2 parents 1a8dae9 + 337f2ab commit 0fb0574

File tree

3 files changed

+42
-17
lines changed

3 files changed

+42
-17
lines changed

Diff for: src/main/scala/devices/tilelink/BootROM.scala

+32-14
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import freechips.rocketchip.diplomacy.{AddressSet, RegionType, TransferSizes}
1313
import freechips.rocketchip.resources.{Resource, SimpleDevice}
1414
import freechips.rocketchip.subsystem._
1515
import freechips.rocketchip.tilelink.{TLFragmenter, TLManagerNode, TLSlaveParameters, TLSlavePortParameters}
16+
import freechips.rocketchip.util.{FileName, SystemFileName, ResourceFileName}
1617

1718
import java.nio.ByteBuffer
1819
import java.nio.file.{Files, Paths}
@@ -22,7 +23,11 @@ case class BootROMParams(
2223
address: BigInt = 0x10000,
2324
size: Int = 0x10000,
2425
hang: BigInt = 0x10040, // The hang parameter is used as the power-on reset vector
25-
contentFileName: String)
26+
driveResetVector: Boolean = true,
27+
appendDTB: Boolean = true,
28+
name: String = "bootrom",
29+
contentFileName: FileName = SystemFileName("./bootrom/bootrom.img")
30+
)
2631

2732
class TLROM(val base: BigInt, val size: Int, contentsDelayed: => Seq[Byte], executable: Boolean = true, beatBytes: Int = 4,
2833
resources: Seq[Resource] = new SimpleDevice("rom", Seq("sifive,rom0")).reg("mem"))(implicit p: Parameters) extends LazyModule
@@ -63,7 +68,7 @@ class TLROM(val base: BigInt, val size: Int, contentsDelayed: => Seq[Byte], exec
6368
}
6469
}
6570

66-
case class BootROMLocated(loc: HierarchicalLocation) extends Field[Option[BootROMParams]](None)
71+
case class BootROMLocated(loc: HierarchicalLocation) extends Field[Seq[BootROMParams]](Nil)
6772

6873
object BootROM {
6974
/** BootROM.attach not only instantiates a TLROM and attaches it to the tilelink interconnect
@@ -73,27 +78,40 @@ object BootROM {
7378
def attach(params: BootROMParams, subsystem: BaseSubsystem with HasHierarchicalElements with HasTileInputConstants, where: TLBusWrapperLocation)
7479
(implicit p: Parameters): TLROM = {
7580
val tlbus = subsystem.locateTLBusWrapper(where)
76-
val bootROMDomainWrapper = tlbus.generateSynchronousDomain("BootROM").suggestName("bootrom_domain")
81+
val bootROMDomainWrapper = tlbus.generateSynchronousDomain(params.name).suggestName(s"${params.name}_domain")
7782

7883
val bootROMResetVectorSourceNode = BundleBridgeSource[UInt]()
79-
lazy val contents = {
80-
val romdata = Files.readAllBytes(Paths.get(params.contentFileName))
81-
val rom = ByteBuffer.wrap(romdata)
82-
rom.array() ++ subsystem.dtb.contents
84+
val rom = params.contentFileName match {
85+
case SystemFileName(fileName) => {
86+
val romdata = Files.readAllBytes(Paths.get(fileName))
87+
ByteBuffer.wrap(romdata).array()
88+
}
89+
case ResourceFileName(fileName) => {
90+
val file = os.resource / os.RelPath(fileName.dropWhile(_ == '/'))
91+
os.read.bytes(file)
92+
}
93+
}
94+
95+
lazy val contents = if (params.appendDTB) {
96+
rom ++ subsystem.dtb.contents
97+
} else {
98+
rom
8399
}
84100

85101
val bootrom = bootROMDomainWrapper {
86102
LazyModule(new TLROM(params.address, params.size, contents, true, tlbus.beatBytes))
87103
}
88104

89-
bootrom.node := tlbus.coupleTo("bootrom"){ TLFragmenter(tlbus, Some("BootROM")) := _ }
105+
bootrom.node := tlbus.coupleTo(params.name){ TLFragmenter(tlbus, Some(params.name)) := _ }
90106
// Drive the `subsystem` reset vector to the `hang` address of this Boot ROM.
91-
subsystem.tileResetVectorNexusNode := bootROMResetVectorSourceNode
92-
InModuleBody {
93-
val reset_vector_source = bootROMResetVectorSourceNode.bundle
94-
require(reset_vector_source.getWidth >= params.hang.bitLength,
95-
s"BootROM defined with a reset vector (${params.hang})too large for physical address space (${reset_vector_source.getWidth})")
96-
bootROMResetVectorSourceNode.bundle := params.hang.U
107+
if (params.driveResetVector) {
108+
subsystem.tileResetVectorNexusNode := bootROMResetVectorSourceNode
109+
InModuleBody {
110+
val reset_vector_source = bootROMResetVectorSourceNode.bundle
111+
require(reset_vector_source.getWidth >= params.hang.bitLength,
112+
s"BootROM defined with a reset vector (${params.hang})too large for physical address space (${reset_vector_source.getWidth})")
113+
bootROMResetVectorSourceNode.bundle := params.hang.U
114+
}
97115
}
98116
bootrom
99117
}

Diff for: src/main/scala/subsystem/Configs.scala

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
// See LICENSE.SiFive for license details.
23
// See LICENSE.Berkeley for license details.
34

@@ -22,7 +23,7 @@ import freechips.rocketchip.resources.{
2223
import freechips.rocketchip.tile.{
2324
MaxHartIdBits, RocketTileParams, BuildRoCC, AccumulatorExample, OpcodeSet, TranslatorExample, CharacterCountExample, BlackBoxExample
2425
}
25-
import freechips.rocketchip.util.ClockGateModelFile
26+
import freechips.rocketchip.util.{ClockGateModelFile, SystemFileName}
2627
import scala.reflect.ClassTag
2728

2829
case object MaxXLen extends Field[Int]
@@ -54,7 +55,7 @@ class BaseSubsystemConfig extends Config ((site, here, up) => {
5455
beatBytes = 8,
5556
blockBytes = site(CacheBlockBytes))
5657
// Additional device Parameters
57-
case BootROMLocated(InSubsystem) => Some(BootROMParams(contentFileName = "./bootrom/bootrom.img"))
58+
case BootROMLocated(InSubsystem) => Seq(BootROMParams(contentFileName = SystemFileName("./bootrom/bootrom.img")))
5859
case HasTilesExternalResetVectorKey => false
5960
case DebugModuleKey => Some(DefaultDebugModuleParams(64))
6061
case CLINTKey => Some(CLINTParams())
@@ -207,7 +208,7 @@ class WithIncoherentTiles extends Config((site, here, up) => {
207208
})
208209

209210
class WithBootROMFile(bootROMFile: String) extends Config((site, here, up) => {
210-
case BootROMLocated(x) => up(BootROMLocated(x), site).map(_.copy(contentFileName = bootROMFile))
211+
case BootROMLocated(x) => up(BootROMLocated(x), site).map(_.copy(contentFileName=SystemFileName(bootROMFile)))
211212
})
212213

213214
class WithClockGateModel(file: String = "/vsrc/EICG_wrapper.v") extends Config((site, here, up) => {

Diff for: src/main/scala/util/package.scala

+6
Original file line numberDiff line numberDiff line change
@@ -300,4 +300,10 @@ package object util {
300300
def HeterogeneousBag[T <: Data](elts: Seq[T]) = _root_.org.chipsalliance.diplomacy.nodes.HeterogeneousBag[T](elts)
301301
@deprecated("HeterogeneousBag has been absorbed into standalone diplomacy library", "rocketchip 2.0.0")
302302
val HeterogeneousBag = _root_.org.chipsalliance.diplomacy.nodes.HeterogeneousBag
303+
304+
trait FileName {
305+
val fileName: String
306+
}
307+
case class SystemFileName(fileName: String) extends FileName
308+
case class ResourceFileName(fileName: String) extends FileName
303309
}

0 commit comments

Comments
 (0)