2016-09-08 11:08:57 +02:00
|
|
|
// See LICENSE for license details.
|
|
|
|
|
|
|
|
package rocketchip
|
|
|
|
|
|
|
|
import Chisel._
|
|
|
|
import cde.{Parameters, Field}
|
|
|
|
import junctions._
|
2016-09-13 19:47:36 +02:00
|
|
|
import junctions.NastiConstants._
|
2016-10-04 00:17:36 +02:00
|
|
|
import diplomacy._
|
2016-09-08 11:08:57 +02:00
|
|
|
import uncore.tilelink._
|
2016-09-15 03:09:27 +02:00
|
|
|
import uncore.tilelink2._
|
2016-10-26 01:27:42 +02:00
|
|
|
import uncore.axi4._
|
2016-09-08 11:08:57 +02:00
|
|
|
import uncore.converters._
|
|
|
|
import uncore.devices._
|
2016-09-24 00:25:58 +02:00
|
|
|
import uncore.agents._
|
2016-09-08 11:08:57 +02:00
|
|
|
import uncore.util._
|
2016-09-28 06:27:07 +02:00
|
|
|
import util._
|
2016-09-16 07:06:39 +02:00
|
|
|
import rocket.XLen
|
|
|
|
import scala.math.max
|
2016-09-08 11:08:57 +02:00
|
|
|
import coreplex._
|
|
|
|
|
|
|
|
/** Options for memory bus interface */
|
|
|
|
object BusType {
|
|
|
|
sealed trait EnumVal
|
|
|
|
case object AXI extends EnumVal
|
|
|
|
case object AHB extends EnumVal
|
|
|
|
case object TL extends EnumVal
|
|
|
|
val busTypes = Seq(AXI, AHB, TL)
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Memory channel controls */
|
|
|
|
case object TMemoryChannels extends Field[BusType.EnumVal]
|
|
|
|
/** External Bus controls */
|
|
|
|
case object NExtBusAXIChannels extends Field[Int]
|
|
|
|
/** Async configurations */
|
|
|
|
case object AsyncBusChannels extends Field[Boolean]
|
|
|
|
case object AsyncDebugBus extends Field[Boolean]
|
|
|
|
case object AsyncMemChannels extends Field[Boolean]
|
|
|
|
/** Specifies the size of external memory */
|
|
|
|
case object ExtMemSize extends Field[Long]
|
2016-09-11 08:39:29 +02:00
|
|
|
/** Specifies the number of external interrupts */
|
2016-09-08 11:08:57 +02:00
|
|
|
case object NExtTopInterrupts extends Field[Int]
|
|
|
|
/** Source of RTC. First bundle is TopIO.extra, Second bundle is periphery.io.extra **/
|
|
|
|
case object RTCPeriod extends Field[Int]
|
2016-09-24 00:25:58 +02:00
|
|
|
/* Specifies the periphery bus configuration */
|
|
|
|
case class PeripheryBusConfig(arithAMO: Boolean, beatBytes: Int = 4)
|
|
|
|
case object PeripheryBusKey extends Field[PeripheryBusConfig]
|
2016-10-25 08:56:09 +02:00
|
|
|
/* Specifies the SOC-bus configuration */
|
|
|
|
case class SOCBusConfig(beatBytes: Int = 4)
|
|
|
|
case object SOCBusKey extends Field[SOCBusConfig]
|
2016-09-08 11:08:57 +02:00
|
|
|
|
2016-09-28 00:11:31 +02:00
|
|
|
/* Specifies the data and id width at the chip boundary */
|
|
|
|
case object EdgeDataBits extends Field[Int]
|
|
|
|
case object EdgeIDBits extends Field[Int]
|
|
|
|
|
2016-09-08 11:08:57 +02:00
|
|
|
object PeripheryUtils {
|
2016-09-23 19:06:09 +02:00
|
|
|
def addQueueAXI(source: NastiIO) = {
|
|
|
|
val sink = Wire(source)
|
2016-09-08 11:08:57 +02:00
|
|
|
sink.ar <> Queue(source.ar, 1)
|
|
|
|
sink.aw <> Queue(source.aw, 1)
|
|
|
|
sink.w <> Queue(source.w)
|
|
|
|
source.r <> Queue(sink.r)
|
|
|
|
source.b <> Queue(sink.b, 1)
|
|
|
|
sink
|
|
|
|
}
|
2016-09-23 19:06:09 +02:00
|
|
|
def convertTLtoAXI(tl: ClientUncachedTileLinkIO) = {
|
|
|
|
val bridge = Module(new NastiIOTileLinkIOConverter()(tl.p))
|
2016-09-08 11:08:57 +02:00
|
|
|
bridge.io.tl <> tl
|
|
|
|
addQueueAXI(bridge.io.nasti)
|
|
|
|
}
|
2016-09-23 19:06:09 +02:00
|
|
|
def convertTLtoAHB(tl: ClientUncachedTileLinkIO, atomics: Boolean) = {
|
|
|
|
val bridge = Module(new AHBBridge(atomics)(tl.p))
|
2016-09-08 11:08:57 +02:00
|
|
|
bridge.io.tl <> tl
|
|
|
|
bridge.io.ahb
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Utility trait for quick access to some relevant parameters */
|
|
|
|
trait HasPeripheryParameters {
|
|
|
|
implicit val p: Parameters
|
|
|
|
lazy val tMemChannels = p(TMemoryChannels)
|
|
|
|
lazy val nMemChannels = p(NMemoryChannels)
|
|
|
|
lazy val nMemAXIChannels = if (tMemChannels == BusType.AXI) nMemChannels else 0
|
|
|
|
lazy val nMemAHBChannels = if (tMemChannels == BusType.AHB) nMemChannels else 0
|
|
|
|
lazy val nMemTLChannels = if (tMemChannels == BusType.TL) nMemChannels else 0
|
2016-09-27 21:07:02 +02:00
|
|
|
lazy val edgeSlaveParams = p.alterPartial({ case TLId => "EdgetoSlave" })
|
2016-09-27 20:44:11 +02:00
|
|
|
lazy val edgeMemParams = p.alterPartial({ case TLId => "MCtoEdge" })
|
2016-09-24 00:25:58 +02:00
|
|
|
lazy val peripheryBusConfig = p(PeripheryBusKey)
|
2016-10-25 08:56:09 +02:00
|
|
|
lazy val socBusConfig = p(SOCBusKey)
|
2016-09-24 00:25:58 +02:00
|
|
|
lazy val cacheBlockBytes = p(CacheBlockBytes)
|
2016-09-08 11:08:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/////
|
|
|
|
|
2016-10-29 07:30:13 +02:00
|
|
|
trait PeripheryDebug {
|
|
|
|
this: TopNetwork =>
|
2016-09-08 11:08:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
trait PeripheryDebugBundle {
|
2016-10-29 07:30:13 +02:00
|
|
|
this: TopNetworkBundle {
|
|
|
|
val outer: PeripheryDebug
|
|
|
|
} =>
|
2016-09-08 11:08:57 +02:00
|
|
|
val debug_clk = (p(AsyncDebugBus) && !p(IncludeJtagDTM)).option(Clock(INPUT))
|
|
|
|
val debug_rst = (p(AsyncDebugBus) && !p(IncludeJtagDTM)).option(Bool(INPUT))
|
|
|
|
val debug = (!p(IncludeJtagDTM)).option(new DebugBusIO()(p).flip)
|
|
|
|
val jtag = p(IncludeJtagDTM).option(new JTAGIO(true).flip)
|
|
|
|
}
|
|
|
|
|
|
|
|
trait PeripheryDebugModule {
|
2016-10-29 07:30:13 +02:00
|
|
|
this: TopNetworkModule {
|
|
|
|
val outer: PeripheryDebug
|
|
|
|
val io: PeripheryDebugBundle
|
|
|
|
} =>
|
2016-09-08 11:08:57 +02:00
|
|
|
|
|
|
|
if (p(IncludeJtagDTM)) {
|
|
|
|
// JtagDTMWithSync is a wrapper which
|
|
|
|
// handles the synchronization as well.
|
|
|
|
val dtm = Module (new JtagDTMWithSync()(p))
|
|
|
|
dtm.io.jtag <> io.jtag.get
|
2016-10-28 00:34:37 +02:00
|
|
|
coreplexDebug <> dtm.io.debug
|
2016-09-08 11:08:57 +02:00
|
|
|
} else {
|
2016-10-28 00:34:37 +02:00
|
|
|
coreplexDebug <>
|
2016-09-08 11:08:57 +02:00
|
|
|
(if (p(AsyncDebugBus)) AsyncDebugBusFrom(io.debug_clk.get, io.debug_rst.get, io.debug.get)
|
|
|
|
else io.debug.get)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/////
|
|
|
|
|
2016-10-29 07:30:13 +02:00
|
|
|
trait PeripheryExtInterrupts {
|
|
|
|
this: TopNetwork =>
|
2016-09-11 08:39:29 +02:00
|
|
|
|
2016-10-29 06:20:49 +02:00
|
|
|
val extInterrupts = IntBlindInputNode(p(NExtTopInterrupts))
|
|
|
|
val extInterruptXing = LazyModule(new IntXing)
|
|
|
|
|
|
|
|
intBus.intnode := extInterruptXing.intnode
|
|
|
|
extInterruptXing.intnode := extInterrupts
|
2016-09-08 11:08:57 +02:00
|
|
|
}
|
|
|
|
|
2016-09-11 08:39:29 +02:00
|
|
|
trait PeripheryExtInterruptsBundle {
|
2016-10-29 07:30:13 +02:00
|
|
|
this: TopNetworkBundle {
|
|
|
|
val outer: PeripheryExtInterrupts
|
|
|
|
} =>
|
2016-10-29 06:20:49 +02:00
|
|
|
val interrupts = outer.extInterrupts.bundleIn
|
2016-09-08 11:08:57 +02:00
|
|
|
}
|
|
|
|
|
2016-09-11 08:39:29 +02:00
|
|
|
trait PeripheryExtInterruptsModule {
|
2016-10-29 07:30:13 +02:00
|
|
|
this: TopNetworkModule {
|
|
|
|
val outer: PeripheryExtInterrupts
|
|
|
|
val io: PeripheryExtInterruptsBundle
|
|
|
|
} =>
|
2016-09-08 11:08:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/////
|
|
|
|
|
2016-10-29 07:30:13 +02:00
|
|
|
trait PeripheryMasterMem {
|
|
|
|
this: TopNetwork =>
|
2016-09-08 11:08:57 +02:00
|
|
|
}
|
|
|
|
|
2016-10-29 07:30:13 +02:00
|
|
|
trait PeripheryMasterMemBundle {
|
|
|
|
this: TopNetworkBundle {
|
|
|
|
val outer: PeripheryMasterMem
|
|
|
|
} =>
|
2016-09-08 11:08:57 +02:00
|
|
|
val mem_clk = p(AsyncMemChannels).option(Vec(nMemChannels, Clock(INPUT)))
|
|
|
|
val mem_rst = p(AsyncMemChannels).option(Vec(nMemChannels, Bool (INPUT)))
|
|
|
|
val mem_axi = Vec(nMemAXIChannels, new NastiIO)
|
|
|
|
val mem_ahb = Vec(nMemAHBChannels, new HastiMasterIO)
|
2016-09-27 20:44:11 +02:00
|
|
|
val mem_tl = Vec(nMemTLChannels, new ClientUncachedTileLinkIO()(edgeMemParams))
|
2016-09-08 11:08:57 +02:00
|
|
|
}
|
|
|
|
|
2016-10-29 07:30:13 +02:00
|
|
|
trait PeripheryMasterMemModule {
|
|
|
|
this: TopNetworkModule {
|
|
|
|
val outer: PeripheryMasterMem
|
|
|
|
val io: PeripheryMasterMemBundle
|
|
|
|
} =>
|
2016-09-08 11:08:57 +02:00
|
|
|
|
2016-10-28 00:34:37 +02:00
|
|
|
val edgeMem = coreplexMem.map(TileLinkWidthAdapter(_, edgeMemParams))
|
2016-09-27 20:33:20 +02:00
|
|
|
|
2016-09-08 11:08:57 +02:00
|
|
|
// Abuse the fact that zip takes the shorter of the two lists
|
2016-09-27 20:33:20 +02:00
|
|
|
((io.mem_axi zip edgeMem) zipWithIndex) foreach { case ((axi, mem), idx) =>
|
2016-09-23 19:06:09 +02:00
|
|
|
val axi_sync = PeripheryUtils.convertTLtoAXI(mem)
|
2016-09-13 19:47:36 +02:00
|
|
|
axi_sync.ar.bits.cache := CACHE_NORMAL_NOCACHE_BUF
|
|
|
|
axi_sync.aw.bits.cache := CACHE_NORMAL_NOCACHE_BUF
|
2016-09-08 11:08:57 +02:00
|
|
|
axi <> (
|
|
|
|
if (!p(AsyncMemChannels)) axi_sync
|
|
|
|
else AsyncNastiTo(io.mem_clk.get(idx), io.mem_rst.get(idx), axi_sync)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2016-09-27 20:33:20 +02:00
|
|
|
(io.mem_ahb zip edgeMem) foreach { case (ahb, mem) =>
|
2016-09-23 19:06:09 +02:00
|
|
|
ahb <> PeripheryUtils.convertTLtoAHB(mem, atomics = false)
|
2016-09-08 11:08:57 +02:00
|
|
|
}
|
|
|
|
|
2016-09-27 20:33:20 +02:00
|
|
|
(io.mem_tl zip edgeMem) foreach { case (tl, mem) =>
|
2016-09-23 19:06:09 +02:00
|
|
|
tl <> TileLinkEnqueuer(mem, 2)
|
2016-09-08 11:08:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/////
|
|
|
|
|
2016-10-26 01:27:42 +02:00
|
|
|
// PeripheryMasterAXI4MMIO is an example, make your own cake pattern like this one.
|
2016-10-29 07:30:13 +02:00
|
|
|
trait PeripheryMasterAXI4MMIO {
|
|
|
|
this: TopNetwork =>
|
2016-10-26 01:27:42 +02:00
|
|
|
|
|
|
|
val mmio_axi4 = AXI4BlindOutputNode(AXI4SlavePortParameters(
|
|
|
|
slaves = Seq(AXI4SlaveParameters(
|
|
|
|
address = List(AddressSet(0x60000000L, 0x1fffffffL)),
|
|
|
|
executable = true, // Can we run programs on this memory?
|
|
|
|
supportsWrite = TransferSizes(1, 256), // The slave supports 1-256 byte transfers
|
|
|
|
supportsRead = TransferSizes(1, 256),
|
|
|
|
interleavedId = Some(0))), // slave does not interleave read responses
|
|
|
|
beatBytes = 8)) // 64-bit AXI interface
|
|
|
|
|
|
|
|
mmio_axi4 :=
|
|
|
|
// AXI4Fragmenter(lite=false, maxInFlight = 20)( // beef device up to support awlen = 0xff
|
|
|
|
TLToAXI4(idBits = 4)( // use idBits = 0 for AXI4-Lite
|
|
|
|
TLWidthWidget(socBusConfig.beatBytes)( // convert width before attaching to socBus
|
|
|
|
socBus.node))
|
2016-09-08 11:08:57 +02:00
|
|
|
}
|
|
|
|
|
2016-10-29 07:30:13 +02:00
|
|
|
trait PeripheryMasterAXI4MMIOBundle {
|
|
|
|
this: TopNetworkBundle {
|
|
|
|
val outer: PeripheryMasterAXI4MMIO
|
|
|
|
} =>
|
2016-10-26 01:27:42 +02:00
|
|
|
val mmio_axi = outer.mmio_axi4.bundleOut
|
2016-09-08 11:08:57 +02:00
|
|
|
}
|
|
|
|
|
2016-10-29 07:30:13 +02:00
|
|
|
trait PeripheryMasterAXI4MMIOModule {
|
|
|
|
this: TopNetworkModule {
|
|
|
|
val outer: PeripheryMasterAXI4MMIO
|
|
|
|
val io: PeripheryMasterAXI4MMIOBundle
|
|
|
|
} =>
|
2016-10-26 01:27:42 +02:00
|
|
|
// nothing to do
|
2016-09-08 11:08:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/////
|
|
|
|
|
2016-10-29 07:30:13 +02:00
|
|
|
trait PeripherySlave {
|
|
|
|
this: TopNetwork {
|
|
|
|
val pBusMasters: RangeManager
|
|
|
|
} =>
|
2016-09-11 08:39:29 +02:00
|
|
|
|
|
|
|
if (p(NExtBusAXIChannels) > 0) pBusMasters.add("ext", 1) // NExtBusAXIChannels are arbitrated into one TL port
|
2016-09-08 11:08:57 +02:00
|
|
|
}
|
|
|
|
|
2016-10-29 07:30:13 +02:00
|
|
|
trait PeripherySlaveBundle {
|
|
|
|
this: TopNetworkBundle {
|
|
|
|
val outer: PeripherySlave
|
|
|
|
} =>
|
2016-09-08 11:08:57 +02:00
|
|
|
val bus_clk = p(AsyncBusChannels).option(Vec(p(NExtBusAXIChannels), Clock(INPUT)))
|
|
|
|
val bus_rst = p(AsyncBusChannels).option(Vec(p(NExtBusAXIChannels), Bool (INPUT)))
|
|
|
|
val bus_axi = Vec(p(NExtBusAXIChannels), new NastiIO).flip
|
|
|
|
}
|
|
|
|
|
2016-10-29 07:30:13 +02:00
|
|
|
trait PeripherySlaveModule {
|
|
|
|
this: TopNetworkModule {
|
|
|
|
val outer: PeripherySlave { val pBusMasters: RangeManager }
|
|
|
|
val io: PeripherySlaveBundle
|
|
|
|
} =>
|
2016-09-08 11:08:57 +02:00
|
|
|
|
|
|
|
if (p(NExtBusAXIChannels) > 0) {
|
|
|
|
val arb = Module(new NastiArbiter(p(NExtBusAXIChannels)))
|
|
|
|
((io.bus_axi zip arb.io.master) zipWithIndex) foreach { case ((bus, port), idx) =>
|
|
|
|
port <> (
|
|
|
|
if (!p(AsyncBusChannels)) bus
|
|
|
|
else AsyncNastiFrom(io.bus_clk.get(idx), io.bus_rst.get(idx), bus)
|
|
|
|
)
|
|
|
|
}
|
2016-09-27 21:07:02 +02:00
|
|
|
val conv = Module(new TileLinkIONastiIOConverter()(edgeSlaveParams))
|
2016-09-08 11:08:57 +02:00
|
|
|
conv.io.nasti <> arb.io.slave
|
2016-09-11 08:39:29 +02:00
|
|
|
|
2016-09-27 21:07:02 +02:00
|
|
|
val (r_start, r_end) = outer.pBusMasters.range("ext")
|
|
|
|
require(r_end - r_start == 1, "RangeManager should return 1 slot")
|
2016-10-28 00:34:37 +02:00
|
|
|
TileLinkWidthAdapter(coreplexSlave(r_start), conv.io.tl)
|
2016-09-11 08:39:29 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/////
|
|
|
|
|
2016-10-29 07:30:13 +02:00
|
|
|
trait PeripheryBootROM {
|
|
|
|
this: TopNetwork =>
|
2016-09-15 03:09:27 +02:00
|
|
|
|
2016-10-29 07:30:13 +02:00
|
|
|
val bootrom_address = 0x1000
|
|
|
|
val bootrom_size = 0x1000
|
|
|
|
val bootrom = LazyModule(new TLROM(bootrom_address, bootrom_size, GenerateBootROM(p, bootrom_address), true, peripheryBusConfig.beatBytes))
|
2016-10-15 00:11:13 +02:00
|
|
|
bootrom.node := TLFragmenter(peripheryBusConfig.beatBytes, cacheBlockBytes)(peripheryBus.node)
|
2016-09-15 01:09:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
trait PeripheryBootROMBundle {
|
2016-10-29 07:30:13 +02:00
|
|
|
this: TopNetworkBundle {
|
|
|
|
val outer: PeripheryBootROM
|
|
|
|
} =>
|
2016-09-15 01:09:59 +02:00
|
|
|
}
|
|
|
|
|
2016-10-29 07:30:13 +02:00
|
|
|
trait PeripheryBootROMModule {
|
|
|
|
this: TopNetworkModule {
|
|
|
|
val outer: PeripheryBootROM
|
|
|
|
val io: PeripheryBootROMBundle
|
|
|
|
} =>
|
2016-09-15 01:09:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/////
|
|
|
|
|
2016-10-29 07:30:13 +02:00
|
|
|
trait PeripheryTestRAM {
|
|
|
|
this: TopNetwork =>
|
2016-09-15 03:09:27 +02:00
|
|
|
|
2016-10-29 07:30:13 +02:00
|
|
|
val testram = LazyModule(new TLRAM(AddressSet(0x52000000, 0xfff), true, peripheryBusConfig.beatBytes))
|
|
|
|
testram.node := TLFragmenter(peripheryBusConfig.beatBytes, cacheBlockBytes)(peripheryBus.node)
|
2016-09-11 08:39:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
trait PeripheryTestRAMBundle {
|
2016-10-29 07:30:13 +02:00
|
|
|
this: TopNetworkBundle {
|
|
|
|
val outer: PeripheryTestRAM
|
|
|
|
} =>
|
2016-09-11 08:39:29 +02:00
|
|
|
}
|
|
|
|
|
2016-10-29 07:30:13 +02:00
|
|
|
trait PeripheryTestRAMModule {
|
|
|
|
this: TopNetworkModule {
|
|
|
|
val outer: PeripheryTestRAM
|
|
|
|
val io: PeripheryTestRAMBundle
|
|
|
|
} =>
|
2016-09-11 08:39:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/////
|
|
|
|
|
2016-10-29 07:30:13 +02:00
|
|
|
trait PeripheryTestBusMaster {
|
|
|
|
this: TopNetwork =>
|
2016-09-15 03:09:27 +02:00
|
|
|
val fuzzer = LazyModule(new TLFuzzer(5000))
|
|
|
|
peripheryBus.node := fuzzer.node
|
2016-09-11 08:39:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
trait PeripheryTestBusMasterBundle {
|
2016-10-29 07:30:13 +02:00
|
|
|
this: TopNetworkBundle {
|
|
|
|
val outer: PeripheryTestBusMaster
|
|
|
|
} =>
|
2016-09-11 08:39:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
trait PeripheryTestBusMasterModule {
|
2016-10-29 07:30:13 +02:00
|
|
|
this: TopNetworkModule {
|
|
|
|
val outer: PeripheryTestBusMaster
|
|
|
|
val io: PeripheryTestBusMasterBundle
|
|
|
|
} =>
|
2016-09-08 11:08:57 +02:00
|
|
|
}
|
Allow reset vector to be set dynamically
A chip's power-up sequence, or awake-from-sleep sequence, may wish to
set the reset PC based upon dynamic properties, e.g., the settings of
external pins. Support this by passing the reset vector to the Coreplex.
ExampleTop simply hard-wires the reset vector, as was the case before.
Additionally, allow MTVEC to *not* be reset. In most cases, including
riscv-tests, pk, and bbl, overriding MTVEC is one of the first things
that the boot sequence does. So the reset value is superfluous.
2016-09-20 01:45:57 +02:00
|
|
|
|
|
|
|
/////
|
|
|
|
|
|
|
|
trait HardwiredResetVector {
|
2016-10-29 07:30:13 +02:00
|
|
|
this: TopNetworkModule {
|
|
|
|
val outer: BaseTop[BaseCoreplex]
|
|
|
|
} =>
|
2016-10-28 00:34:37 +02:00
|
|
|
outer.coreplex.module.io.resetVector := UInt(0x1000) // boot ROM
|
Allow reset vector to be set dynamically
A chip's power-up sequence, or awake-from-sleep sequence, may wish to
set the reset PC based upon dynamic properties, e.g., the settings of
external pins. Support this by passing the reset vector to the Coreplex.
ExampleTop simply hard-wires the reset vector, as was the case before.
Additionally, allow MTVEC to *not* be reset. In most cases, including
riscv-tests, pk, and bbl, overriding MTVEC is one of the first things
that the boot sequence does. So the reset value is superfluous.
2016-09-20 01:45:57 +02:00
|
|
|
}
|