2016-09-08 11:08:57 +02:00
|
|
|
// See LICENSE for license details.
|
|
|
|
|
|
|
|
package rocketchip
|
|
|
|
|
|
|
|
import Chisel._
|
2016-09-11 08:39:29 +02:00
|
|
|
import cde.{Parameters, Field}
|
2016-09-08 11:08:57 +02:00
|
|
|
import junctions._
|
|
|
|
import uncore.tilelink._
|
2016-09-15 03:09:27 +02:00
|
|
|
import uncore.tilelink2._
|
2016-09-11 08:39:29 +02:00
|
|
|
import uncore.devices._
|
2016-09-14 05:22:20 +02:00
|
|
|
import util.ParameterizedBundle
|
2016-09-11 08:39:29 +02:00
|
|
|
import rocket._
|
2016-09-08 11:08:57 +02:00
|
|
|
import rocket.Util._
|
|
|
|
import coreplex._
|
|
|
|
|
2016-09-11 08:39:29 +02:00
|
|
|
// the following parameters will be refactored properly with TL2
|
2016-09-15 09:38:46 +02:00
|
|
|
case object GlobalAddrMap extends Field[AddrMap]
|
|
|
|
case object ConfigString extends Field[String]
|
|
|
|
case object NCoreplexExtClients extends Field[Int]
|
2016-09-12 21:40:10 +02:00
|
|
|
/** Function for building Coreplex */
|
|
|
|
case object BuildCoreplex extends Field[(Parameters, CoreplexConfig) => Coreplex]
|
2016-09-08 11:08:57 +02:00
|
|
|
|
|
|
|
/** Base Top with no Periphery */
|
2016-09-15 09:38:46 +02:00
|
|
|
abstract class BaseTop(q: Parameters) extends LazyModule {
|
2016-09-11 08:39:29 +02:00
|
|
|
// the following variables will be refactored properly with TL2
|
|
|
|
val pInterrupts = new RangeManager
|
|
|
|
val pBusMasters = new RangeManager
|
|
|
|
val pDevices = new ResourceManager[AddrMapEntry]
|
2016-09-15 09:38:46 +02:00
|
|
|
|
2016-09-17 02:27:49 +02:00
|
|
|
// Add a peripheral bus
|
|
|
|
val peripheryBus = LazyModule(new TLXbar)
|
|
|
|
lazy val peripheryManagers = peripheryBus.node.edgesIn(0).manager.managers
|
|
|
|
|
2016-09-15 09:38:46 +02:00
|
|
|
lazy val c = CoreplexConfig(
|
|
|
|
nTiles = q(NTiles),
|
|
|
|
nExtInterrupts = pInterrupts.sum,
|
|
|
|
nSlaves = pBusMasters.sum,
|
|
|
|
nMemChannels = q(NMemoryChannels),
|
|
|
|
hasSupervisor = q(UseVM),
|
|
|
|
hasExtMMIOPort = true
|
|
|
|
)
|
|
|
|
|
2016-09-17 02:27:49 +02:00
|
|
|
lazy val genGlobalAddrMap = GenerateGlobalAddrMap(q, pDevices.get, peripheryManagers)
|
2016-09-15 09:38:46 +02:00
|
|
|
private val qWithMap = q.alterPartial({case GlobalAddrMap => genGlobalAddrMap})
|
|
|
|
|
2016-09-17 02:27:49 +02:00
|
|
|
lazy val genConfigString = GenerateConfigString(qWithMap, c, pDevices.get, peripheryManagers)
|
2016-09-15 09:38:46 +02:00
|
|
|
implicit val p = qWithMap.alterPartial({
|
|
|
|
case ConfigString => genConfigString
|
|
|
|
case NCoreplexExtClients => pBusMasters.sum})
|
|
|
|
|
2016-09-15 03:09:27 +02:00
|
|
|
val legacy = LazyModule(new TLLegacy()(p.alterPartial({ case TLId => "L2toMMIO" })))
|
|
|
|
|
|
|
|
peripheryBus.node := TLBuffer(TLWidthWidget(TLHintHandler(legacy.node), legacy.tlDataBytes))
|
2016-09-11 08:39:29 +02:00
|
|
|
}
|
2016-09-08 11:08:57 +02:00
|
|
|
|
|
|
|
class BaseTopBundle(val p: Parameters, val c: Coreplex) extends ParameterizedBundle()(p) {
|
|
|
|
val success = c.hasSuccessFlag.option(Bool(OUTPUT))
|
|
|
|
}
|
|
|
|
|
2016-09-11 08:39:29 +02:00
|
|
|
class BaseTopModule[+L <: BaseTop, +B <: BaseTopBundle](val p: Parameters, l: L, b: Coreplex => B) extends LazyModuleImp(l) {
|
2016-09-08 11:08:57 +02:00
|
|
|
val outer: L = l
|
2016-09-11 08:39:29 +02:00
|
|
|
|
2016-09-15 09:38:46 +02:00
|
|
|
val coreplex = p(BuildCoreplex)(p, outer.c)
|
|
|
|
val io: B = b(coreplex)
|
2016-09-11 08:39:29 +02:00
|
|
|
|
2016-09-15 09:38:46 +02:00
|
|
|
io.success zip coreplex.io.success map { case (x, y) => x := y }
|
2016-09-11 08:39:44 +02:00
|
|
|
|
2016-09-15 09:38:46 +02:00
|
|
|
val mmioNetwork =
|
|
|
|
Module(new TileLinkRecursiveInterconnect(1, p(GlobalAddrMap).subMap("io:ext"))(
|
|
|
|
p.alterPartial({ case TLId => "L2toMMIO" })))
|
|
|
|
mmioNetwork.io.in.head <> coreplex.io.master.mmio.get
|
|
|
|
outer.legacy.module.io.legacy <> mmioNetwork.port("TL2")
|
2016-09-11 08:39:29 +02:00
|
|
|
|
|
|
|
println("Generated Address Map")
|
2016-09-15 09:38:46 +02:00
|
|
|
for (entry <- p(GlobalAddrMap).flatten) {
|
2016-09-11 08:39:29 +02:00
|
|
|
val name = entry.name
|
|
|
|
val start = entry.region.start
|
|
|
|
val end = entry.region.start + entry.region.size - 1
|
2016-09-17 09:16:00 +02:00
|
|
|
val prot = entry.region.attr.prot
|
|
|
|
val protStr = (if ((prot & AddrMapProt.R) > 0) "R" else "") +
|
|
|
|
(if ((prot & AddrMapProt.W) > 0) "W" else "") +
|
|
|
|
(if ((prot & AddrMapProt.X) > 0) "X" else "")
|
|
|
|
val cacheable = if (entry.region.attr.cacheable) " [C]" else ""
|
|
|
|
println(f"\t$name%s $start%x - $end%x, $protStr$cacheable")
|
2016-09-11 08:39:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
println("Generated Configuration String")
|
2016-09-15 09:38:46 +02:00
|
|
|
println(p(ConfigString))
|
|
|
|
ConfigStringOutput.contents = Some(p(ConfigString))
|
2016-09-08 11:08:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/** Example Top with Periphery */
|
2016-09-15 09:38:46 +02:00
|
|
|
class ExampleTop(q: Parameters) extends BaseTop(q)
|
2016-09-16 23:26:34 +02:00
|
|
|
with PeripheryBootROM with PeripheryDebug with PeripheryExtInterrupts with PeripheryCoreplexLocalInterrupter
|
2016-09-08 11:08:57 +02:00
|
|
|
with PeripheryMasterMem with PeripheryMasterMMIO with PeripherySlave {
|
2016-09-11 08:39:29 +02:00
|
|
|
override lazy val module = Module(new ExampleTopModule(p, this, new ExampleTopBundle(p, _)))
|
2016-09-08 11:08:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
class ExampleTopBundle(p: Parameters, c: Coreplex) extends BaseTopBundle(p, c)
|
2016-09-16 23:26:34 +02:00
|
|
|
with PeripheryBootROMBundle with PeripheryDebugBundle with PeripheryExtInterruptsBundle with PeripheryCoreplexLocalInterrupterBundle
|
2016-09-08 11:08:57 +02:00
|
|
|
with PeripheryMasterMemBundle with PeripheryMasterMMIOBundle with PeripherySlaveBundle
|
|
|
|
|
2016-09-11 08:39:29 +02:00
|
|
|
class ExampleTopModule[+L <: ExampleTop, +B <: ExampleTopBundle](p: Parameters, l: L, b: Coreplex => B) extends BaseTopModule(p, l, b)
|
2016-09-16 23:26:34 +02:00
|
|
|
with PeripheryBootROMModule with PeripheryDebugModule with PeripheryExtInterruptsModule with PeripheryCoreplexLocalInterrupterModule
|
2016-09-08 11:08:57 +02:00
|
|
|
with PeripheryMasterMemModule with PeripheryMasterMMIOModule with PeripherySlaveModule
|
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
|
|
|
with HardwiredResetVector
|
2016-09-11 08:39:29 +02:00
|
|
|
|
|
|
|
/** Example Top with TestRAM */
|
2016-09-15 09:38:46 +02:00
|
|
|
class ExampleTopWithTestRAM(q: Parameters) extends ExampleTop(q)
|
2016-09-11 08:39:29 +02:00
|
|
|
with PeripheryTestRAM {
|
|
|
|
override lazy val module = Module(new ExampleTopWithTestRAMModule(p, this, new ExampleTopWithTestRAMBundle(p, _)))
|
|
|
|
}
|
|
|
|
|
|
|
|
class ExampleTopWithTestRAMBundle(p: Parameters, c: Coreplex) extends ExampleTopBundle(p, c)
|
|
|
|
with PeripheryTestRAMBundle
|
|
|
|
|
|
|
|
class ExampleTopWithTestRAMModule[+L <: ExampleTopWithTestRAM, +B <: ExampleTopWithTestRAMBundle](p: Parameters, l: L, b: Coreplex => B) extends ExampleTopModule(p, l, b)
|
|
|
|
with PeripheryTestRAMModule
|