1
0

now able to add periphery devices through traits

Unfortunately, I had to touch a lot of code, which weren't quite possible to split up into multiple commits.
This commit gets rid of the "extra" infrastructure to add periphery devices into Top.
This commit is contained in:
Yunsup Lee
2016-09-10 23:39:29 -07:00
parent 2c000a99da
commit bb3f514e8d
15 changed files with 414 additions and 472 deletions

View File

@ -11,6 +11,7 @@ import uncore.devices._
import uncore.converters._
import rocket._
import rocket.Util._
import rocketchip.{GlobalAddrMap, NCoreplexExtClients}
import scala.math.max
import scala.collection.mutable.{LinkedHashSet, ListBuffer}
import DefaultTestSuites._
@ -127,7 +128,6 @@ class BaseCoreplexConfig extends Config (
case MulDivKey => Some(MulDivConfig(mulUnroll = 8, mulEarlyOut = true, divEarlyOut = true))
case UseAtomics => true
case UseCompressed => true
case PLICKey => PLICConfig(site(NTiles), site(UseVM), site(NExtInterrupts), 0)
case DMKey => new DefaultDebugModuleConfig(site(NTiles), site(XLen))
case NCustomMRWCSRs => 0
case ResetVector => BigInt(0x1000)
@ -145,7 +145,7 @@ class BaseCoreplexConfig extends Config (
else new MESICoherence(site(L2DirectoryRepresentation))),
nManagers = site(NBanksPerMemoryChannel)*site(NMemoryChannels) + 1 /* MMIO */,
nCachingClients = site(NCachedTileLinkPorts),
nCachelessClients = site(NExternalClients) + site(NUncachedTileLinkPorts),
nCachelessClients = site(NCoreplexExtClients).get + site(NUncachedTileLinkPorts),
maxClientXacts = max_int(
// L1 cache
site(DCacheKey).nMSHRs + 1 /* IOMSHR */,
@ -176,7 +176,7 @@ class BaseCoreplexConfig extends Config (
TileLinkParameters(
coherencePolicy = new MICoherence(
new NullRepresentation(site(NBanksPerMemoryChannel))),
nManagers = site(GlobalAddrMap).subMap("io").numSlaves,
nManagers = site(GlobalAddrMap).get.subMap("io").numSlaves,
nCachingClients = 0,
nCachelessClients = 1,
maxClientXacts = 4,
@ -194,7 +194,6 @@ class BaseCoreplexConfig extends Config (
case CacheBlockBytes => Dump("CACHE_BLOCK_BYTES", 64)
case CacheBlockOffsetBits => log2Up(here(CacheBlockBytes))
case EnableL2Logging => false
case ExtraCoreplexPorts => (p: Parameters) => new Bundle
case RegressionTestNames => LinkedHashSet(
"rv64ud-v-fcvt",
"rv64ud-p-fdiv",

View File

@ -14,6 +14,8 @@ import rocket.Util._
import java.nio.{ByteBuffer,ByteOrder}
import java.nio.file.{Files, Paths}
/** Function for building Coreplex */
case object BuildCoreplex extends Field[(Parameters, CoreplexConfig) => Coreplex]
/** Number of memory channels */
case object NMemoryChannels extends Field[Int]
/** Number of banks per memory channel */
@ -24,24 +26,11 @@ case object BankIdLSB extends Field[Int]
case object BuildL2CoherenceManager extends Field[(Int, Parameters) => CoherenceAgent]
/** Function for building some kind of tile connected to a reset signal */
case object BuildTiles extends Field[Seq[(Bool, Parameters) => Tile]]
/** A string describing on-chip devices, readable by target software */
case object ConfigString extends Field[Array[Byte]]
/** Number of external interrupt sources */
case object NExtInterrupts extends Field[Int]
/** Interrupt controller configuration */
case object PLICKey extends Field[PLICConfig]
/** The file to read the BootROM contents from */
case object BootROMFile extends Field[String]
/** Export an external MMIO slave port */
case object ExportMMIOPort extends Field[Boolean]
/** Expose additional TileLink client ports */
case object NExternalClients extends Field[Int]
/** Extra top-level ports exported from the coreplex */
case object ExtraCoreplexPorts extends Field[Parameters => Bundle]
trait HasCoreplexParameters {
implicit val p: Parameters
lazy val nTiles = p(NTiles)
lazy val nMemChannels = p(NMemoryChannels)
lazy val nBanksPerMemChannel = p(NBanksPerMemoryChannel)
lazy val nBanks = nMemChannels*nBanksPerMemChannel
@ -49,20 +38,31 @@ trait HasCoreplexParameters {
lazy val innerParams = p.alterPartial({ case TLId => "L1toL2" })
lazy val outermostParams = p.alterPartial({ case TLId => "Outermost" })
lazy val outermostMMIOParams = p.alterPartial({ case TLId => "MMIO_Outermost" })
lazy val nExtClients = p(NExternalClients)
lazy val exportMMIO = p(ExportMMIOPort)
lazy val configString = p(rocketchip.ConfigString).get
lazy val globalAddrMap = p(rocketchip.GlobalAddrMap).get
}
abstract class Coreplex(implicit val p: Parameters) extends Module
case class CoreplexConfig(
nTiles: Int,
nExtInterrupts: Int,
nSlaves: Int,
hasSupervisor: Boolean,
hasExtMMIOPort: Boolean)
{
val plicKey = PLICConfig(nTiles, hasSupervisor, nExtInterrupts, 0)
}
abstract class Coreplex(implicit val p: Parameters, implicit val c: CoreplexConfig) extends Module
with HasCoreplexParameters {
class CoreplexIO(implicit val p: Parameters) extends Bundle {
val mem = Vec(nMemChannels, new ClientUncachedTileLinkIO()(outermostParams))
val ext_clients = Vec(nExtClients, new ClientUncachedTileLinkIO()(innerParams)).flip
val mmio = p(ExportMMIOPort).option(new ClientUncachedTileLinkIO()(outermostMMIOParams))
val interrupts = Vec(p(NExtInterrupts), Bool()).asInput
class CoreplexIO(implicit val p: Parameters, implicit val c: CoreplexConfig) extends Bundle {
val master = new Bundle {
val mem = Vec(nMemChannels, new ClientUncachedTileLinkIO()(outermostParams))
val mmio = c.hasExtMMIOPort.option(new ClientUncachedTileLinkIO()(outermostMMIOParams))
}
val slave = Vec(c.nSlaves, new ClientUncachedTileLinkIO()(innerParams)).flip
val interrupts = Vec(c.nExtInterrupts, Bool()).asInput
val debug = new DebugBusIO()(p).flip
val rtcTick = Bool(INPUT)
val extra = p(ExtraCoreplexPorts)(p)
val success: Option[Bool] = hasSuccessFlag.option(Bool(OUTPUT))
}
@ -70,16 +70,16 @@ abstract class Coreplex(implicit val p: Parameters) extends Module
val io = new CoreplexIO
}
class DefaultCoreplex(topParams: Parameters) extends Coreplex()(topParams) {
class DefaultCoreplex(tp: Parameters, tc: CoreplexConfig) extends Coreplex()(tp, tc) {
// Build a set of Tiles
val tileResets = Wire(Vec(nTiles, Bool()))
val tileResets = Wire(Vec(tc.nTiles, Bool()))
val tileList = p(BuildTiles).zip(tileResets).map {
case (tile, rst) => tile(rst, p)
}
val nCachedPorts = tileList.map(tile => tile.io.cached.size).reduce(_ + _)
val nUncachedPorts = tileList.map(tile => tile.io.uncached.size).reduce(_ + _)
printConfigString
// Build an uncore backing the Tiles
buildUncore(p.alterPartial({
case HastiId => "TL"
case TLId => "L1toL2"
@ -87,25 +87,13 @@ class DefaultCoreplex(topParams: Parameters) extends Coreplex()(topParams) {
case NUncachedTileLinkPorts => nUncachedPorts
}))
def printConfigString(implicit p: Parameters) = {
println("Generated Address Map")
for (entry <- p(GlobalAddrMap).flatten) {
val name = entry.name
val start = entry.region.start
val end = entry.region.start + entry.region.size - 1
println(f"\t$name%s $start%x - $end%x")
}
println("Generated Configuration String")
println(new String(p(ConfigString)))
}
def buildUncore(implicit p: Parameters) = {
// Create a simple L1toL2 NoC between the tiles and the banks of outer memory
// Cached ports are first in client list, making sharerToClientId just an indentity function
// addrToBank is sed to hash physical addresses (of cache blocks) to banks (and thereby memory channels)
def sharerToClientId(sharerId: UInt) = sharerId
def addrToBank(addr: UInt): UInt = if (nBanks == 0) UInt(0) else {
val isMemory = p(GlobalAddrMap).isInRegion("mem", addr << log2Up(p(CacheBlockBytes)))
val isMemory = globalAddrMap.isInRegion("mem", addr << log2Up(p(CacheBlockBytes)))
Mux(isMemory, addr.extract(lsb + log2Ceil(nBanks) - 1, lsb), UInt(nBanks))
}
val preBuffering = TileLinkDepths(1,1,2,2,0)
@ -124,7 +112,7 @@ class DefaultCoreplex(topParams: Parameters) extends Coreplex()(topParams) {
// Wire the tiles to the TileLink client ports of the L1toL2 network,
// and coherence manager(s) to the other side
l1tol2net.io.clients_cached <> tileList.map(_.io.cached).flatten
l1tol2net.io.clients_uncached <> tileList.map(_.io.uncached).flatten ++ io.ext_clients
l1tol2net.io.clients_uncached <> tileList.map(_.io.uncached).flatten ++ io.slave
l1tol2net.io.managers <> managerEndpoints.map(_.innerTL) :+ mmioManager.io.inner
// Create a converter between TileLinkIO and MemIO for each channel
@ -138,7 +126,7 @@ class DefaultCoreplex(topParams: Parameters) extends Coreplex()(topParams) {
TileLinkWidthAdapter(icPort, unwrap.io.out)
}
io.mem <> mem_ic.io.out
io.master.mem <> mem_ic.io.out
buildMMIONetwork(ClientUncachedTileLinkEnqueuer(mmioManager.io.outer, 1))(
p.alterPartial({case TLId => "L2toMMIO"}))
@ -151,7 +139,10 @@ class DefaultCoreplex(topParams: Parameters) extends Coreplex()(topParams) {
rom.order(ByteOrder.LITTLE_ENDIAN)
// for now, have the reset vector jump straight to memory
val memBase = (if (p(GlobalAddrMap) contains "mem") p(GlobalAddrMap)("mem") else p(GlobalAddrMap)("io:int:dmem0")).start
val memBase = (
if (globalAddrMap contains "mem") globalAddrMap("mem")
else globalAddrMap("io:int:dmem0")
).start
val resetToMemDist = memBase - p(ResetVector)
require(resetToMemDist == (resetToMemDist.toInt >> 12 << 12))
val configStringAddr = p(ResetVector).toInt + rom.capacity
@ -159,17 +150,17 @@ class DefaultCoreplex(topParams: Parameters) extends Coreplex()(topParams) {
require(rom.getInt(12) == 0,
"Config string address position should not be occupied by code")
rom.putInt(12, configStringAddr)
rom.array() ++ p(ConfigString).toSeq
rom.array() ++ (configString.getBytes.toSeq)
}
def buildMMIONetwork(mmio: ClientUncachedTileLinkIO)(implicit p: Parameters) = {
val ioAddrMap = p(GlobalAddrMap).subMap("io")
val ioAddrMap = globalAddrMap.subMap("io")
val mmioNetwork = Module(new TileLinkRecursiveInterconnect(1, ioAddrMap))
mmioNetwork.io.in.head <> mmio
val plic = Module(new PLIC(p(PLICKey)))
val plic = Module(new PLIC(c.plicKey))
plic.io.tl <> mmioNetwork.port("int:plic")
for (i <- 0 until io.interrupts.size) {
val gateway = Module(new LevelGateway)
@ -191,25 +182,25 @@ class DefaultCoreplex(topParams: Parameters) extends Coreplex()(topParams) {
tile.io.prci <> prci
}
for (i <- 0 until nTiles) {
for (i <- 0 until tc.nTiles) {
prci.io.interrupts(i).meip := plic.io.harts(plic.cfg.context(i, 'M'))
if (p(UseVM))
prci.io.interrupts(i).seip := plic.io.harts(plic.cfg.context(i, 'S'))
prci.io.interrupts(i).debug := debugModule.io.debugInterrupts(i)
}
val tileSlavePorts = (0 until nTiles) map (i => s"int:dmem$i") filter (ioAddrMap contains _)
val tileSlavePorts = (0 until tc.nTiles) map (i => s"int:dmem$i") filter (ioAddrMap contains _)
for ((t, m) <- (tileList.map(_.io.slave).flatten) zip (tileSlavePorts map (mmioNetwork port _)))
t <> ClientUncachedTileLinkEnqueuer(m, 1)
val bootROM = Module(new ROMSlave(makeBootROM()))
bootROM.io <> mmioNetwork.port("int:bootrom")
io.mmio.foreach { _ <> mmioNetwork.port("ext") }
io.master.mmio.foreach { _ <> mmioNetwork.port("ext") }
}
}
class GroundTestCoreplex(topParams: Parameters) extends DefaultCoreplex(topParams) {
class GroundTestCoreplex(tp: Parameters, tc: CoreplexConfig) extends DefaultCoreplex(tp, tc) {
override def hasSuccessFlag = true
io.success.get := tileList.flatMap(_.io.elements get "success").map(_.asInstanceOf[Bool]).reduce(_&&_)
}

View File

@ -1,63 +0,0 @@
package coreplex
import Chisel._
import cde.{Parameters, Field}
import rocket.TileId
import groundtest._
import uncore.tilelink._
import uncore.agents._
case object ExportGroundTestStatus extends Field[Boolean]
class DirectGroundTestCoreplex(topParams: Parameters) extends Coreplex()(topParams) {
// Not using the debug
io.debug.req.ready := Bool(false)
io.debug.resp.valid := Bool(false)
require(!exportMMIO)
require(nExtClients == 0)
require(nMemChannels == 1)
require(nTiles == 1)
val test = p(BuildGroundTest)(outermostParams.alterPartial({
case TileId => 0
case CacheName => "L1D"
}))
require(test.io.cache.size == 0)
require(test.io.mem.size == nBanksPerMemChannel)
require(test.io.ptw.size == 0)
val mem_ic = Module(new TileLinkMemoryInterconnect(
nBanksPerMemChannel, nMemChannels)(outermostParams))
mem_ic.io.in <> test.io.mem
io.mem <> mem_ic.io.out
if (p(ExportGroundTestStatus)) {
val status = io.extra.asInstanceOf[GroundTestStatus]
val s_running :: s_finished :: s_errored :: s_timeout :: Nil = Enum(Bits(), 4)
val state = Reg(init = s_running)
val error_code = Reg(status.error.bits)
val timeout_code = Reg(status.timeout.bits)
when (state === s_running) {
when (test.io.status.finished) { state := s_finished }
when (test.io.status.error.valid) {
state := s_errored
error_code := test.io.status.error.bits
}
when (test.io.status.timeout.valid) {
state := s_timeout
timeout_code := test.io.status.timeout.bits
}
}
status.finished := (state === s_finished)
status.error.valid := (state === s_errored)
status.error.bits := error_code
status.timeout.valid := (state === s_timeout)
status.timeout.bits := timeout_code
}
override def hasSuccessFlag = true
io.success.get := test.io.status.finished
}

View File

@ -2,6 +2,7 @@ package coreplex
import Chisel._
import groundtest._
import rocketchip.{GlobalAddrMap}
import rocket._
import uncore.tilelink._
import uncore.coherence._
@ -24,7 +25,7 @@ class WithComparator extends Config(
(p: Parameters) => Module(new ComparatorCore()(p))
case ComparatorKey => ComparatorParameters(
targets = Seq("mem", "io:ext:testram").map(name =>
site(GlobalAddrMap)(name).start.longValue),
site(GlobalAddrMap).get(name).start.longValue),
width = 8,
operations = 1000,
atomics = site(UseAtomics),
@ -54,7 +55,7 @@ class WithMemtest extends Config(
}
case GeneratorKey => GeneratorParameters(
maxRequests = 128,
startAddress = site(GlobalAddrMap)("mem").start)
startAddress = site(GlobalAddrMap).get("mem").start)
case BuildGroundTest =>
(p: Parameters) => Module(new GeneratorTest()(p))
case _ => throw new CDEMatchError
@ -114,7 +115,7 @@ class WithNastiConverterTest extends Config(
}
case GeneratorKey => GeneratorParameters(
maxRequests = 128,
startAddress = site(GlobalAddrMap)("mem").start)
startAddress = site(GlobalAddrMap).get("mem").start)
case BuildGroundTest =>
(p: Parameters) => Module(new NastiConverterTest()(p))
case _ => throw new CDEMatchError
@ -134,7 +135,7 @@ class WithTraceGen extends Config(
val nSets = 32 // L2 NSets
val nWays = 1
val blockOffset = site(CacheBlockOffsetBits)
val baseAddr = site(GlobalAddrMap)("mem").start
val baseAddr = site(GlobalAddrMap).get("mem").start
val nBeats = site(MIFDataBeats)
List.tabulate(4 * nWays) { i =>
Seq.tabulate(nBeats) { j => (j * 8) + ((i * nSets) << blockOffset) }
@ -156,7 +157,7 @@ class WithPCIeMockupTest extends Config(
GroundTestTileSettings(1))
case GeneratorKey => GeneratorParameters(
maxRequests = 128,
startAddress = site(GlobalAddrMap)("mem").start)
startAddress = site(GlobalAddrMap).get("mem").start)
case BuildGroundTest =>
(p: Parameters) => p(TileId) match {
case 0 => Module(new GeneratorTest()(p))

View File

@ -6,9 +6,9 @@ import rocket.Tile
import uncore.tilelink.TLId
import cde.Parameters
class UnitTestCoreplex(topParams: Parameters) extends Coreplex()(topParams) {
require(!exportMMIO)
require(nExtClients == 0)
class UnitTestCoreplex(tp: Parameters, tc: CoreplexConfig) extends Coreplex()(tp, tc) {
require(!tc.hasExtMMIOPort)
require(tc.nSlaves == 0)
require(nMemChannels == 0)
io.debug.req.ready := Bool(false)