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-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 MMIO controls */
|
|
|
|
case object NExtMMIOAXIChannels extends Field[Int]
|
|
|
|
case object NExtMMIOAHBChannels extends Field[Int]
|
|
|
|
case object NExtMMIOTLChannels extends Field[Int]
|
|
|
|
/** 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]
|
|
|
|
case object AsyncMMIOChannels extends Field[Boolean]
|
|
|
|
/** External address map settings */
|
|
|
|
case object ExtMMIOPorts extends Field[Seq[AddrMapEntry]]
|
|
|
|
/** 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 00:57:24 +02:00
|
|
|
lazy val outerMMIOParams = p.alterPartial({ case TLId => "L2toMMIO" })
|
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" })
|
|
|
|
lazy val edgeMMIOParams = p.alterPartial({ case TLId => "MMIOtoEdge" })
|
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
|
|
|
}
|
|
|
|
|
|
|
|
/////
|
|
|
|
|
|
|
|
trait PeripheryDebug extends LazyModule {
|
|
|
|
implicit val p: Parameters
|
|
|
|
}
|
|
|
|
|
|
|
|
trait PeripheryDebugBundle {
|
|
|
|
implicit val p: Parameters
|
|
|
|
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 {
|
|
|
|
implicit val p: Parameters
|
|
|
|
val outer: PeripheryDebug
|
|
|
|
val io: PeripheryDebugBundle
|
2016-09-22 01:54:35 +02:00
|
|
|
val coreplexIO: BaseCoreplexBundle
|
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-09-22 01:54:35 +02:00
|
|
|
coreplexIO.debug <> dtm.io.debug
|
2016-09-08 11:08:57 +02:00
|
|
|
} else {
|
2016-09-22 01:54:35 +02:00
|
|
|
coreplexIO.debug <>
|
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-09-11 08:39:29 +02:00
|
|
|
trait PeripheryExtInterrupts extends LazyModule {
|
2016-09-08 11:08:57 +02:00
|
|
|
implicit val p: Parameters
|
2016-09-11 08:39:29 +02:00
|
|
|
val pInterrupts: RangeManager
|
|
|
|
|
|
|
|
pInterrupts.add("ext", p(NExtTopInterrupts))
|
2016-09-08 11:08:57 +02:00
|
|
|
}
|
|
|
|
|
2016-09-11 08:39:29 +02:00
|
|
|
trait PeripheryExtInterruptsBundle {
|
2016-09-08 11:08:57 +02:00
|
|
|
implicit val p: Parameters
|
|
|
|
val interrupts = Vec(p(NExtTopInterrupts), Bool()).asInput
|
|
|
|
}
|
|
|
|
|
2016-09-11 08:39:29 +02:00
|
|
|
trait PeripheryExtInterruptsModule {
|
2016-09-08 11:08:57 +02:00
|
|
|
implicit val p: Parameters
|
2016-09-11 08:39:29 +02:00
|
|
|
val outer: PeripheryExtInterrupts
|
|
|
|
val io: PeripheryExtInterruptsBundle
|
2016-09-22 01:54:35 +02:00
|
|
|
val coreplexIO: BaseCoreplexBundle
|
2016-09-08 11:08:57 +02:00
|
|
|
|
2016-09-11 08:39:29 +02:00
|
|
|
{
|
|
|
|
val r = outer.pInterrupts.range("ext")
|
|
|
|
((r._1 until r._2) zipWithIndex) foreach { case (c, i) =>
|
2016-09-22 01:54:35 +02:00
|
|
|
coreplexIO.interrupts(c) := io.interrupts(i)
|
2016-09-11 08:39:29 +02:00
|
|
|
}
|
|
|
|
}
|
2016-09-08 11:08:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/////
|
|
|
|
|
|
|
|
trait PeripheryMasterMem extends LazyModule {
|
|
|
|
implicit val p: Parameters
|
|
|
|
}
|
|
|
|
|
|
|
|
trait PeripheryMasterMemBundle extends HasPeripheryParameters {
|
|
|
|
implicit val p: Parameters
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
trait PeripheryMasterMemModule extends HasPeripheryParameters {
|
|
|
|
implicit val p: Parameters
|
|
|
|
val outer: PeripheryMasterMem
|
|
|
|
val io: PeripheryMasterMemBundle
|
2016-09-22 01:54:35 +02:00
|
|
|
val coreplexIO: BaseCoreplexBundle
|
2016-09-08 11:08:57 +02:00
|
|
|
|
2016-09-27 20:44:11 +02:00
|
|
|
val edgeMem = coreplexIO.master.mem.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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/////
|
|
|
|
|
|
|
|
trait PeripheryMasterMMIO extends LazyModule {
|
|
|
|
implicit val p: Parameters
|
|
|
|
}
|
|
|
|
|
|
|
|
trait PeripheryMasterMMIOBundle extends HasPeripheryParameters {
|
|
|
|
implicit val p: Parameters
|
|
|
|
val mmio_clk = p(AsyncMMIOChannels).option(Vec(p(NExtMMIOAXIChannels), Clock(INPUT)))
|
|
|
|
val mmio_rst = p(AsyncMMIOChannels).option(Vec(p(NExtMMIOAXIChannels), Bool (INPUT)))
|
|
|
|
val mmio_axi = Vec(p(NExtMMIOAXIChannels), new NastiIO)
|
|
|
|
val mmio_ahb = Vec(p(NExtMMIOAHBChannels), new HastiMasterIO)
|
2016-09-27 20:44:11 +02:00
|
|
|
val mmio_tl = Vec(p(NExtMMIOTLChannels), new ClientUncachedTileLinkIO()(edgeMMIOParams))
|
2016-09-08 11:08:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
trait PeripheryMasterMMIOModule extends HasPeripheryParameters {
|
|
|
|
implicit val p: Parameters
|
|
|
|
val outer: PeripheryMasterMMIO
|
|
|
|
val io: PeripheryMasterMMIOBundle
|
2016-09-22 03:16:04 +02:00
|
|
|
val pBus: TileLinkRecursiveInterconnect
|
2016-09-08 11:08:57 +02:00
|
|
|
|
|
|
|
val mmio_ports = p(ExtMMIOPorts) map { port =>
|
2016-09-27 20:44:11 +02:00
|
|
|
TileLinkWidthAdapter(pBus.port(port.name), edgeMMIOParams)
|
2016-09-08 11:08:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
val mmio_axi_start = 0
|
|
|
|
val mmio_axi_end = mmio_axi_start + p(NExtMMIOAXIChannels)
|
|
|
|
val mmio_ahb_start = mmio_axi_end
|
|
|
|
val mmio_ahb_end = mmio_ahb_start + p(NExtMMIOAHBChannels)
|
|
|
|
val mmio_tl_start = mmio_ahb_end
|
|
|
|
val mmio_tl_end = mmio_tl_start + p(NExtMMIOTLChannels)
|
|
|
|
require (mmio_tl_end == mmio_ports.size)
|
|
|
|
|
|
|
|
for (i <- 0 until mmio_ports.size) {
|
|
|
|
if (mmio_axi_start <= i && i < mmio_axi_end) {
|
|
|
|
val idx = i-mmio_axi_start
|
2016-09-23 19:06:09 +02:00
|
|
|
val axi_sync = PeripheryUtils.convertTLtoAXI(mmio_ports(i))
|
2016-09-08 11:08:57 +02:00
|
|
|
io.mmio_axi(idx) <> (
|
|
|
|
if (!p(AsyncMMIOChannels)) axi_sync
|
|
|
|
else AsyncNastiTo(io.mmio_clk.get(idx), io.mmio_rst.get(idx), axi_sync)
|
|
|
|
)
|
|
|
|
} else if (mmio_ahb_start <= i && i < mmio_ahb_end) {
|
|
|
|
val idx = i-mmio_ahb_start
|
2016-09-23 19:06:09 +02:00
|
|
|
io.mmio_ahb(idx) <> PeripheryUtils.convertTLtoAHB(mmio_ports(i), atomics = true)
|
2016-09-08 11:08:57 +02:00
|
|
|
} else if (mmio_tl_start <= i && i < mmio_tl_end) {
|
|
|
|
val idx = i-mmio_tl_start
|
2016-09-23 19:06:09 +02:00
|
|
|
io.mmio_tl(idx) <> TileLinkEnqueuer(mmio_ports(i), 2)
|
2016-09-08 11:08:57 +02:00
|
|
|
} else {
|
|
|
|
require(false, "Unconnected external MMIO port")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/////
|
|
|
|
|
|
|
|
trait PeripherySlave extends LazyModule {
|
|
|
|
implicit val p: Parameters
|
2016-09-11 08:39:29 +02:00
|
|
|
val pBusMasters: RangeManager
|
|
|
|
|
|
|
|
if (p(NExtBusAXIChannels) > 0) pBusMasters.add("ext", 1) // NExtBusAXIChannels are arbitrated into one TL port
|
2016-09-08 11:08:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
trait PeripherySlaveBundle extends HasPeripheryParameters {
|
|
|
|
implicit val p: Parameters
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
trait PeripherySlaveModule extends HasPeripheryParameters {
|
|
|
|
implicit val p: Parameters
|
|
|
|
val outer: PeripherySlave
|
|
|
|
val io: PeripherySlaveBundle
|
2016-09-22 01:54:35 +02:00
|
|
|
val coreplexIO: BaseCoreplexBundle
|
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")
|
|
|
|
TileLinkWidthAdapter(coreplexIO.slave(r_start), conv.io.tl)
|
2016-09-11 08:39:29 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/////
|
|
|
|
|
2016-09-16 23:26:34 +02:00
|
|
|
trait PeripheryCoreplexLocalInterrupter extends LazyModule with HasPeripheryParameters {
|
2016-09-14 19:57:01 +02:00
|
|
|
implicit val p: Parameters
|
2016-09-15 03:09:27 +02:00
|
|
|
val peripheryBus: TLXbar
|
|
|
|
|
2016-09-16 23:26:34 +02:00
|
|
|
// CoreplexLocalInterrupter must be at least 64b if XLen >= 64
|
2016-09-27 00:57:24 +02:00
|
|
|
val beatBytes = max((outerMMIOParams(XLen) min 64) / 8, peripheryBusConfig.beatBytes)
|
2016-09-16 23:26:34 +02:00
|
|
|
val clintConfig = CoreplexLocalInterrupterConfig(beatBytes)
|
2016-09-27 00:57:24 +02:00
|
|
|
val clint = LazyModule(new CoreplexLocalInterrupter(clintConfig)(outerMMIOParams))
|
2016-09-16 23:26:34 +02:00
|
|
|
// The periphery bus is 32-bit, so we may need to adapt its width to XLen
|
2016-09-24 00:25:58 +02:00
|
|
|
clint.node := TLFragmenter(beatBytes, cacheBlockBytes)(TLWidthWidget(peripheryBusConfig.beatBytes)(peripheryBus.node))
|
2016-09-14 19:57:01 +02:00
|
|
|
}
|
|
|
|
|
2016-09-16 23:26:34 +02:00
|
|
|
trait PeripheryCoreplexLocalInterrupterBundle {
|
2016-09-14 19:57:01 +02:00
|
|
|
implicit val p: Parameters
|
|
|
|
}
|
|
|
|
|
2016-09-16 23:26:34 +02:00
|
|
|
trait PeripheryCoreplexLocalInterrupterModule extends HasPeripheryParameters {
|
2016-09-14 19:57:01 +02:00
|
|
|
implicit val p: Parameters
|
2016-09-16 23:26:34 +02:00
|
|
|
val outer: PeripheryCoreplexLocalInterrupter
|
|
|
|
val io: PeripheryCoreplexLocalInterrupterBundle
|
2016-09-22 01:54:35 +02:00
|
|
|
val coreplexIO: BaseCoreplexBundle
|
2016-09-14 19:57:01 +02:00
|
|
|
|
2016-09-16 23:26:34 +02:00
|
|
|
outer.clint.module.io.rtcTick := Counter(p(RTCPeriod)).inc()
|
2016-09-22 01:54:35 +02:00
|
|
|
coreplexIO.clint <> outer.clint.module.io.tiles
|
2016-09-14 19:57:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/////
|
|
|
|
|
2016-09-24 00:25:58 +02:00
|
|
|
trait PeripheryBootROM extends LazyModule with HasPeripheryParameters {
|
2016-09-15 01:09:59 +02:00
|
|
|
implicit val p: Parameters
|
2016-09-15 03:09:27 +02:00
|
|
|
val peripheryBus: TLXbar
|
|
|
|
|
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
|
|
|
val address = 0x1000
|
|
|
|
val size = 0x1000
|
2016-09-24 00:25:58 +02:00
|
|
|
val rom = LazyModule(new TLROM(address, size, GenerateBootROM(p, address), true, peripheryBusConfig.beatBytes)
|
|
|
|
{ override def name = "bootrom" })
|
|
|
|
rom.node := TLFragmenter(peripheryBusConfig.beatBytes, cacheBlockBytes)(peripheryBus.node)
|
2016-09-15 01:09:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
trait PeripheryBootROMBundle {
|
|
|
|
implicit val p: Parameters
|
|
|
|
}
|
|
|
|
|
|
|
|
trait PeripheryBootROMModule extends HasPeripheryParameters {
|
|
|
|
implicit val p: Parameters
|
|
|
|
val outer: PeripheryBootROM
|
|
|
|
val io: PeripheryBootROMBundle
|
|
|
|
}
|
|
|
|
|
|
|
|
/////
|
|
|
|
|
2016-09-24 00:25:58 +02:00
|
|
|
trait PeripheryTestRAM extends LazyModule with HasPeripheryParameters {
|
2016-09-11 08:39:29 +02:00
|
|
|
implicit val p: Parameters
|
2016-09-15 03:09:27 +02:00
|
|
|
val peripheryBus: TLXbar
|
2016-09-11 08:39:29 +02:00
|
|
|
|
2016-09-15 03:09:27 +02:00
|
|
|
val ramBase = 0x52000000
|
2016-09-11 08:39:29 +02:00
|
|
|
val ramSize = 0x1000
|
2016-09-15 03:09:27 +02:00
|
|
|
|
2016-09-24 00:25:58 +02:00
|
|
|
val sram = LazyModule(new TLRAM(AddressSet(ramBase, ramSize-1), true, peripheryBusConfig.beatBytes)
|
|
|
|
{ override def name = "testram" })
|
|
|
|
sram.node := TLFragmenter(peripheryBusConfig.beatBytes, cacheBlockBytes)(peripheryBus.node)
|
2016-09-11 08:39:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
trait PeripheryTestRAMBundle {
|
|
|
|
implicit val p: Parameters
|
|
|
|
}
|
|
|
|
|
|
|
|
trait PeripheryTestRAMModule extends HasPeripheryParameters {
|
|
|
|
implicit val p: Parameters
|
|
|
|
val outer: PeripheryTestRAM
|
|
|
|
}
|
|
|
|
|
|
|
|
/////
|
|
|
|
|
|
|
|
trait PeripheryTestBusMaster extends LazyModule {
|
|
|
|
implicit val p: Parameters
|
2016-09-15 03:09:27 +02:00
|
|
|
val peripheryBus: TLXbar
|
2016-09-11 08:39:29 +02:00
|
|
|
|
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 {
|
|
|
|
implicit val p: Parameters
|
|
|
|
}
|
|
|
|
|
|
|
|
trait PeripheryTestBusMasterModule {
|
|
|
|
implicit val p: Parameters
|
|
|
|
val outer: PeripheryTestBusMaster
|
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-09-22 01:54:35 +02:00
|
|
|
val coreplexIO: BaseCoreplexBundle
|
|
|
|
coreplexIO.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
|
|
|
}
|