From 01ca3efc2be16a09156ea06018c10886dbfd7058 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Sun, 23 Jul 2017 08:31:04 -0700 Subject: [PATCH] Combine Coreplex and System Module Hierarchies (#875) * coreplex collapse: peripherals now in coreplex * coreplex: better factoring of TLBusWrapper attachement points * diplomacy: allow monitorless :*= and :=* * rocket: don't connect monitors to tile tim slave ports * rename chip package to system * coreplex: only sbus has a splitter * TLFragmenter: Continuing my spot battles on requires without explanatory strings * pbus: toFixedWidthSingleBeatSlave * tilelink: more verbose requires * use the new system package for regression * sbus: add more explicit FIFO attachment points * delete leftover top-level utils * cleanup ResetVector and RTC --- Makefrag | 2 +- README.md | 26 +- regression/Makefile | 6 +- src/main/scala/amba/axi4/Test.scala | 4 +- src/main/scala/chip/Configs.scala | 166 -------- src/main/scala/chip/ExampleTop.scala | 39 -- src/main/scala/chip/Periphery.scala | 374 ------------------ src/main/scala/chip/RISCVPlatform.scala | 122 ------ src/main/scala/chip/RocketPlexMaster.scala | 33 -- src/main/scala/chip/System.scala | 25 -- src/main/scala/chip/TestHarness.scala | 95 ----- src/main/scala/chip/Utils.scala | 56 --- src/main/scala/coreplex/BaseCoreplex.scala | 182 +++++---- src/main/scala/coreplex/Configs.scala | 124 ++++-- src/main/scala/coreplex/CoreplexNetwork.scala | 190 --------- src/main/scala/coreplex/ISPPort.scala | 40 -- src/main/scala/coreplex/InterruptBus.scala | 85 ++++ src/main/scala/coreplex/MemoryBus.scala | 75 ++++ src/main/scala/coreplex/PeripheryBus.scala | 48 +++ src/main/scala/coreplex/Ports.scala | 261 ++++++++++++ src/main/scala/coreplex/RISCVPlatform.scala | 65 --- src/main/scala/coreplex/RTC.scala | 24 ++ src/main/scala/coreplex/ResetVector.scala | 14 + src/main/scala/coreplex/RocketCoreplex.scala | 130 ++++++ src/main/scala/coreplex/RocketPlex.scala | 21 - src/main/scala/coreplex/RocketTiles.scala | 135 ------- src/main/scala/coreplex/SystemBus.scala | 97 +++++ src/main/scala/devices/debug/Debug.scala | 18 +- .../debug}/DebugTransport.scala | 14 +- src/main/scala/devices/debug/Periphery.scala | 123 ++++++ src/main/scala/devices/tilelink/BootROM.scala | 41 ++ src/main/scala/devices/tilelink/Clint.scala | 11 +- src/main/scala/devices/tilelink/Error.scala | 22 +- src/main/scala/devices/tilelink/Plic.scala | 12 +- .../devices/tilelink/{Rom.scala => ROM.scala} | 0 src/main/scala/devices/tilelink/Zero.scala | 23 +- src/main/scala/diplomacy/Nodes.scala | 2 + src/main/scala/groundtest/Configs.scala | 9 +- src/main/scala/groundtest/Coreplex.scala | 38 +- src/main/scala/groundtest/TestHarness.scala | 4 +- src/main/scala/groundtest/Tile.scala | 5 +- src/main/scala/groundtest/Top.scala | 27 -- src/main/scala/rocket/HellaCache.scala | 7 +- .../scala/rocket/ScratchpadSlavePort.scala | 8 +- src/main/scala/system/Configs.scala | 84 ++++ .../scala/system/ExampleRocketSystem.scala | 26 ++ .../scala/{chip => system}/Generator.scala | 2 +- .../{chip => system}/RocketTestSuite.scala | 2 +- src/main/scala/system/TestHarness.scala | 22 ++ src/main/scala/tile/L1Cache.scala | 5 +- .../scala/{rocket => tile}/RocketTile.scala | 93 ++--- src/main/scala/tilelink/AtomicAutomata.scala | 2 +- src/main/scala/tilelink/Broadcast.scala | 4 +- src/main/scala/tilelink/Bus.scala | 96 +++++ src/main/scala/tilelink/Parameters.scala | 6 +- src/main/scala/tilelink/package.scala | 6 +- src/main/scala/unittest/Configs.scala | 10 +- src/main/scala/util/GeneratorUtils.scala | 2 +- src/main/scala/util/Misc.scala | 5 + 59 files changed, 1536 insertions(+), 1632 deletions(-) delete mode 100644 src/main/scala/chip/Configs.scala delete mode 100644 src/main/scala/chip/ExampleTop.scala delete mode 100644 src/main/scala/chip/Periphery.scala delete mode 100644 src/main/scala/chip/RISCVPlatform.scala delete mode 100644 src/main/scala/chip/RocketPlexMaster.scala delete mode 100644 src/main/scala/chip/System.scala delete mode 100644 src/main/scala/chip/TestHarness.scala delete mode 100644 src/main/scala/chip/Utils.scala delete mode 100644 src/main/scala/coreplex/CoreplexNetwork.scala delete mode 100644 src/main/scala/coreplex/ISPPort.scala create mode 100644 src/main/scala/coreplex/InterruptBus.scala create mode 100644 src/main/scala/coreplex/MemoryBus.scala create mode 100644 src/main/scala/coreplex/PeripheryBus.scala create mode 100644 src/main/scala/coreplex/Ports.scala delete mode 100644 src/main/scala/coreplex/RISCVPlatform.scala create mode 100644 src/main/scala/coreplex/RTC.scala create mode 100644 src/main/scala/coreplex/ResetVector.scala create mode 100644 src/main/scala/coreplex/RocketCoreplex.scala delete mode 100644 src/main/scala/coreplex/RocketPlex.scala delete mode 100644 src/main/scala/coreplex/RocketTiles.scala create mode 100644 src/main/scala/coreplex/SystemBus.scala rename src/main/scala/{chip => devices/debug}/DebugTransport.scala (96%) create mode 100644 src/main/scala/devices/debug/Periphery.scala create mode 100644 src/main/scala/devices/tilelink/BootROM.scala rename src/main/scala/devices/tilelink/{Rom.scala => ROM.scala} (100%) delete mode 100644 src/main/scala/groundtest/Top.scala create mode 100644 src/main/scala/system/Configs.scala create mode 100644 src/main/scala/system/ExampleRocketSystem.scala rename src/main/scala/{chip => system}/Generator.scala (98%) rename src/main/scala/{chip => system}/RocketTestSuite.scala (99%) create mode 100644 src/main/scala/system/TestHarness.scala rename src/main/scala/{rocket => tile}/RocketTile.scala (84%) create mode 100644 src/main/scala/tilelink/Bus.scala diff --git a/Makefrag b/Makefrag index 5b013e35..09f11ebc 100644 --- a/Makefrag +++ b/Makefrag @@ -4,7 +4,7 @@ $(error Please set environment variable RISCV. Please take a look at README) endif MODEL ?= TestHarness -PROJECT ?= freechips.rocketchip.chip +PROJECT ?= freechips.rocketchip.system CFG_PROJECT ?= $(PROJECT) CONFIG ?= DefaultConfig # TODO: For now must match rocketchip.Generator diff --git a/README.md b/README.md index 81e4fda4..07b234b6 100644 --- a/README.md +++ b/README.md @@ -156,9 +156,6 @@ Here is a brief description of what can be found in each package: * **amba** This RTL package uses diplomacy to generate bus implementations of AMBA protocols, including AXI4, AHB-lite, and APB. -* **chip** -This top-level utility package invokes Chisel to elaborate a particular configuration of a coreplex, -along with the appropriate testing collateral. * **config** This utility package provides Scala interfaces for configuring a generator via a dynamically-scoped parameterization library. @@ -188,6 +185,9 @@ This RTL package contains components that can be combined with cores to construc * **tilelink** This RTL package uses diplomacy to generate bus implementations of the TileLink protocol. It also contains a variety of adapters and protocol converters. +* **system** +This top-level utility package invokes Chisel to elaborate a particular configuration of a coreplex, +along with the appropriate testing collateral. * **unittest** This utility package contains a framework for generateing synthesizeable hardware testers of individual modules. * **util** @@ -291,11 +291,11 @@ verilator. DefaultConfig.graphml DefaultConfig.json DefaultConfig.memmap.json - freechips.rocketchip.chip.DefaultConfig - freechips.rocketchip.chip.DefaultConfig.d - freechips.rocketchip.chip.DefaultConfig.fir - freechips.rocketchip.chip.DefaultConfig.v - $ ls $ROCKETCHIP/emulator/generated-src/freechips.rocketchip.chip.DefaultConfig + freechips.rocketchip.system.DefaultConfig + freechips.rocketchip.system.DefaultConfig.d + freechips.rocketchip.system.DefaultConfig.fir + freechips.rocketchip.system.DefaultConfig.v + $ ls $ROCKETCHIP/emulator/generated-src/freechips.rocketchip.system.DefaultConfig VTestHarness__1.cpp VTestHarness__2.cpp VTestHarness__3.cpp @@ -360,11 +360,11 @@ Top.DefaultConfig.conf file: DefaultConfig.graphml DefaultConfig.json DefaultConfig.memmap.json - freechips.rocketchip.chip.DefaultConfig.behav_srams.v - freechips.rocketchip.chip.DefaultConfig.conf - freechips.rocketchip.chip.DefaultConfig.d - freechips.rocketchip.chip.DefaultConfig.fir - freechips.rocketchip.chip.DefaultConfig.v + freechips.rocketchip.system.DefaultConfig.behav_srams.v + freechips.rocketchip.system.DefaultConfig.conf + freechips.rocketchip.system.DefaultConfig.d + freechips.rocketchip.system.DefaultConfig.fir + freechips.rocketchip.system.DefaultConfig.v $ cat $ROCKETCHIP/vsim/generated-src/*.conf name data_arrays_0_ext depth 512 width 256 ports mrw mask_gran 8 name tag_array_ext depth 64 width 88 ports mrw mask_gran 22 diff --git a/regression/Makefile b/regression/Makefile index 82be8dd0..6c011f92 100644 --- a/regression/Makefile +++ b/regression/Makefile @@ -42,17 +42,17 @@ $(error Set SUITE to the regression suite you want to run) endif ifeq ($(SUITE),RocketSuiteA) -PROJECT=freechips.rocketchip.chip +PROJECT=freechips.rocketchip.system CONFIGS=DefaultConfig endif ifeq ($(SUITE),RocketSuiteB) -PROJECT=freechips.rocketchip.chip +PROJECT=freechips.rocketchip.system CONFIGS=DefaultBufferlessConfig endif ifeq ($(SUITE),RocketSuiteC) -PROJECT=freechips.rocketchip.chip +PROJECT=freechips.rocketchip.system CONFIGS=TinyConfig endif diff --git a/src/main/scala/amba/axi4/Test.scala b/src/main/scala/amba/axi4/Test.scala index 5c926c39..062607fa 100644 --- a/src/main/scala/amba/axi4/Test.scala +++ b/src/main/scala/amba/axi4/Test.scala @@ -4,7 +4,7 @@ package freechips.rocketchip.amba.axi4 import Chisel._ import freechips.rocketchip.config.Parameters -import freechips.rocketchip.devices.tilelink.TLError +import freechips.rocketchip.devices.tilelink._ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.unittest._ @@ -98,7 +98,7 @@ class AXI4FuzzSlave()(implicit p: Parameters) extends LazyModule with HasFuzzTar val node = AXI4InputNode() val xbar = LazyModule(new TLXbar) val ram = LazyModule(new TLRAM(fuzzAddr)) - val error= LazyModule(new TLError(Seq(AddressSet(0x1800, 0xff)))) + val error= LazyModule(new TLError(ErrorParams(Seq(AddressSet(0x1800, 0xff))))) ram.node := TLFragmenter(4, 16)(xbar.node) error.node := TLFragmenter(4, 16)(xbar.node) diff --git a/src/main/scala/chip/Configs.scala b/src/main/scala/chip/Configs.scala deleted file mode 100644 index 315e9c65..00000000 --- a/src/main/scala/chip/Configs.scala +++ /dev/null @@ -1,166 +0,0 @@ -// See LICENSE.SiFive for license details. -// See LICENSE.Berkeley for license details. - -package freechips.rocketchip.chip - -import Chisel._ - -import freechips.rocketchip.config._ -import freechips.rocketchip.coreplex._ -import freechips.rocketchip.devices._ -import freechips.rocketchip.diplomacy._ -import freechips.rocketchip.rocket._ -import freechips.rocketchip.tile.XLen -import freechips.rocketchip.tilelink._ -import freechips.rocketchip.util._ - -import scala.math.max -import scala.collection.mutable.{LinkedHashSet, ListBuffer} -import scala.collection.immutable.HashMap - -import DefaultTestSuites._ - -class BasePlatformConfig extends Config((site, here, up) => { - // DTS descriptive parameters - case DTSModel => "ucbbar,rocketchip-unknown" - case DTSCompat => Nil - case DTSTimebase => BigInt(1000000) // 1 MHz - case RTCPeriod => 1000 // Implies coreplex clock is DTSTimebase * RTCPeriod = 1 GHz - // TileLink connection parameters - case TLMonitorBuilder => (args: TLMonitorArgs) => Some(LazyModule(new TLMonitor(args))) - case TLCombinationalCheck => false - //Memory Parameters - case NExtTopInterrupts => 2 - case SOCBusConfig => site(L1toL2Config) - case PeripheryBusConfig => TLBusConfig(beatBytes = 4) - case PeripheryBusArithmetic => true - // Default BootROMParams - case PeripheryBootROMKey => BootROMParams() - // Note that PLIC asserts that this is > 0. - case IncludeJtagDTM => false - case JtagDTMKey => new JtagDTMKeyDefault() - case ZeroConfig => ZeroConfig(base=0xa000000L, size=0x2000000L, beatBytes=8) - case ErrorConfig => ErrorConfig(Seq(AddressSet(0x3000, 0xfff))) - case ExtMem => MasterConfig(base=0x80000000L, size=0x10000000L, beatBytes=8, idBits=4) - case ExtBus => MasterConfig(base=0x60000000L, size=0x20000000L, beatBytes=8, idBits=4) - case ExtIn => SlaveConfig(beatBytes=8, idBits=8, sourceBits=4) -}) - -/** Actual elaboratable target Configs */ - -class BaseConfig extends Config(new BaseCoreplexConfig ++ new BasePlatformConfig) -class DefaultConfig extends Config(new WithNBigCores(1) ++ new BaseConfig) - -class DefaultBufferlessConfig extends Config( - new WithBufferlessBroadcastHub ++ new WithNBigCores(1) ++ new BaseConfig) - -class FPGAConfig extends Config(Parameters.empty) -class DefaultFPGAConfig extends Config(new FPGAConfig ++ new BaseConfig) - -class DefaultSmallConfig extends Config(new WithNSmallCores(1) ++ new BaseConfig) -class DefaultRV32Config extends Config(new WithRV32 ++ new DefaultConfig) - -class DualBankConfig extends Config( - new WithNBanksPerMemChannel(2) ++ new BaseConfig) - -class DualChannelConfig extends Config(new WithNMemoryChannels(2) ++ new BaseConfig) - -class DualChannelDualBankConfig extends Config( - new WithNMemoryChannels(2) ++ - new WithNBanksPerMemChannel(2) ++ new BaseConfig) - -class RoccExampleConfig extends Config(new WithRoccExample ++ new DefaultConfig) - -class Edge128BitConfig extends Config( - new WithEdgeDataBits(128) ++ new BaseConfig) -class Edge32BitConfig extends Config( - new WithEdgeDataBits(32) ++ new BaseConfig) - -class SingleChannelBenchmarkConfig extends Config(new DefaultConfig) -class DualChannelBenchmarkConfig extends Config(new WithNMemoryChannels(2) ++ new SingleChannelBenchmarkConfig) -class QuadChannelBenchmarkConfig extends Config(new WithNMemoryChannels(4) ++ new SingleChannelBenchmarkConfig) -class OctoChannelBenchmarkConfig extends Config(new WithNMemoryChannels(8) ++ new SingleChannelBenchmarkConfig) - -class EightChannelConfig extends Config(new WithNMemoryChannels(8) ++ new BaseConfig) - -class DualCoreConfig extends Config( - new WithNBigCores(2) ++ new BaseConfig) -class HeterogeneousDualCoreConfig extends Config( - new WithNSmallCores(1) ++ new WithNBigCores(1) ++ new BaseConfig) - -class TinyConfig extends Config( - new WithNMemoryChannels(0) ++ - new WithStatelessBridge ++ - new BaseConfig().alter((site, here, up) => { - case XLen => 32 - case RocketTilesKey => Seq( - RocketTileParams( - core = RocketCoreParams( - useVM = false, - fpu = None, - mulDiv = Some(MulDivParams(mulUnroll = 8))), - btb = None, - dcache = Some(DCacheParams( - rowBits = site(L1toL2Config).beatBytes*8, - nSets = 256, // 16Kb scratchpad - nWays = 1, - nTLBEntries = 4, - nMSHRs = 0, - blockBytes = site(CacheBlockBytes), - scratch = Some(0x80000000L))), - icache = Some(ICacheParams( - rowBits = site(L1toL2Config).beatBytes*8, - nSets = 64, - nWays = 1, - nTLBEntries = 4, - blockBytes = site(CacheBlockBytes)))))})) - -/* Composable partial function Configs to set individual parameters */ - -class WithEdgeDataBits(dataBits: Int) extends Config((site, here, up) => { - case ExtMem => up(ExtMem, site).copy(beatBytes = dataBits/8) - case ZeroConfig => up(ZeroConfig, site).copy(beatBytes = dataBits/8) -}) - -class WithJtagDTM extends Config ((site, here, up) => { - case IncludeJtagDTM => true -}) - -class WithNoPeripheryArithAMO extends Config ((site, here, up) => { - case PeripheryBusArithmetic => false -}) - -class With64BitPeriphery extends Config ((site, here, up) => { - case PeripheryBusConfig => TLBusConfig(beatBytes = 8) -}) - -class WithoutTLMonitors extends Config ((site, here, up) => { - case TLMonitorBuilder => (args: TLMonitorArgs) => None -}) - -class WithNExtTopInterrupts(nExtInts: Int) extends Config((site, here, up) => { - case NExtTopInterrupts => nExtInts -}) - -class WithRTCPeriod(nCycles: Int) extends Config((site, here, up) => { - case RTCPeriod => nCycles -}) - -class WithNMemoryChannels(n: Int) extends Config((site, here, up) => { - case BankedL2Config => up(BankedL2Config, site).copy(nMemoryChannels = n) -}) - -class WithExtMemSize(n: Long) extends Config((site, here, up) => { - case ExtMem => up(ExtMem, site).copy(size = n) -}) - -class WithDTS(model: String, compat: Seq[String]) extends Config((site, here, up) => { - case DTSModel => model - case DTSCompat => compat -}) - -class WithTimebase(hertz: BigInt) extends Config((site, here, up) => { - case DTSTimebase => hertz -}) - -class DefaultFPGASmallConfig extends Config(new WithNSmallCores(1) ++ new DefaultFPGAConfig) diff --git a/src/main/scala/chip/ExampleTop.scala b/src/main/scala/chip/ExampleTop.scala deleted file mode 100644 index 19e1cd4f..00000000 --- a/src/main/scala/chip/ExampleTop.scala +++ /dev/null @@ -1,39 +0,0 @@ -// See LICENSE.SiFive for license details. - -package freechips.rocketchip.chip - -import Chisel._ - -import freechips.rocketchip.config.Parameters - -/** Example system with periphery devices (w/o coreplex) */ -abstract class ExampleSystem(implicit p: Parameters) extends BaseSystem - with HasPeripheryAsyncExtInterrupts - with HasPeripheryMasterAXI4MemPort - with HasPeripheryMasterAXI4MMIOPort - with HasPeripherySlaveAXI4Port - with HasPeripheryErrorSlave - with HasPeripheryZeroSlave { - override lazy val module = new ExampleSystemModule(this) -} - -class ExampleSystemModule[+L <: ExampleSystem](_outer: L) extends BaseSystemModule(_outer) - with HasPeripheryExtInterruptsModuleImp - with HasPeripheryMasterAXI4MemPortModuleImp - with HasPeripheryMasterAXI4MMIOPortModuleImp - with HasPeripherySlaveAXI4PortModuleImp - -/** Example Top with periphery and a Rocket coreplex */ -class ExampleRocketTop(implicit p: Parameters) extends ExampleSystem - with HasPeripheryBootROM - with HasPeripheryDebug - with HasPeripheryRTCCounter - with HasRocketPlexMaster { - override lazy val module = new ExampleRocketTopModule(this) -} - -class ExampleRocketTopModule[+L <: ExampleRocketTop](_outer: L) extends ExampleSystemModule(_outer) - with HasPeripheryBootROMModuleImp - with HasPeripheryDebugModuleImp - with HasPeripheryRTCCounterModuleImp - with HasRocketPlexMasterModuleImp diff --git a/src/main/scala/chip/Periphery.scala b/src/main/scala/chip/Periphery.scala deleted file mode 100644 index 26d30d9c..00000000 --- a/src/main/scala/chip/Periphery.scala +++ /dev/null @@ -1,374 +0,0 @@ -// See LICENSE.SiFive for license details. - -package freechips.rocketchip.chip - -import Chisel._ - -import freechips.rocketchip.config._ -import freechips.rocketchip.coreplex._ -import freechips.rocketchip.devices.tilelink._ -import freechips.rocketchip.diplomacy._ -import freechips.rocketchip.tilelink._ -import freechips.rocketchip.amba.axi4._ -import freechips.rocketchip.util._ - -import scala.math.{min,max} - -/** Specifies the size of external memory */ -case class MasterConfig(base: Long, size: Long, beatBytes: Int, idBits: Int) -case object ExtMem extends Field[MasterConfig] -case object ExtBus extends Field[MasterConfig] -case class SlaveConfig(beatBytes: Int, idBits: Int, sourceBits: Int) -case object ExtIn extends Field[SlaveConfig] -/** Specifies the number of external interrupts */ -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] -/* Specifies the periphery bus configuration */ -case object PeripheryBusConfig extends Field[TLBusConfig] -case object PeripheryBusArithmetic extends Field[Boolean] -/* Specifies the SOC-bus configuration */ -case object SOCBusConfig extends Field[TLBusConfig] -/* Specifies the location of the Zero device */ -case class ZeroConfig(base: Long, size: Long, beatBytes: Int) -case object ZeroConfig extends Field[ZeroConfig] -/* Specifies the location of the Error device */ -case class ErrorConfig(address: Seq[AddressSet]) -case object ErrorConfig extends Field[ErrorConfig] - -/** Utility trait for quick access to some relevant parameters */ -trait HasPeripheryParameters { - implicit val p: Parameters - def peripheryBusConfig = p(PeripheryBusConfig) - def peripheryBusBytes = peripheryBusConfig.beatBytes - def socBusConfig = p(SOCBusConfig) - def socBusBytes = socBusConfig.beatBytes - def cacheBlockBytes = p(CacheBlockBytes) - def peripheryBusArithmetic = p(PeripheryBusArithmetic) - def nMemoryChannels = p(BankedL2Config).nMemoryChannels - def nExtInterrupts = p(NExtTopInterrupts) -} - -/** HasSystemNetworks provides buses that will serve as attachment points, - * for use in the following child traits that connect individual agents or external ports. - */ -trait HasSystemNetworks extends HasPeripheryParameters { - val socBus = LazyModule(new TLXbar) // Wide or unordered-access slave devices (TL-UH) - val peripheryBus = LazyModule(new TLXbar) // Narrow and ordered-access slave devices (TL-UL) - val intBus = LazyModule(new IntXbar) // Device and global external interrupts - val fsb = LazyModule(new TLBuffer(BufferParams.none)) // Master devices talking to the frontside of the L2 - val bsb = LazyModule(new TLBuffer(BufferParams.none)) // Slave devices talking to the backside of the L2 - val mem = Seq.fill(nMemoryChannels) { LazyModule(new TLXbar) } // Ports out to DRAM - - // The peripheryBus hangs off of socBus; - // here we convert TL-UH -> TL-UL - peripheryBus.node := - TLBuffer()( - TLWidthWidget(socBusConfig.beatBytes)( - TLAtomicAutomata(arithmetic = peripheryBusArithmetic)( - socBus.node))) -} - -/** This trait adds externally driven interrupts to the system. - * However, it should not be used directly; instead one of the below - * synchronization wiring child traits should be used. - */ -abstract trait HasPeripheryExtInterrupts extends HasSystemNetworks { - private val device = new Device with DeviceInterrupts { - def describe(resources: ResourceBindings): Description = { - Description("soc/external-interrupts", describeInterrupts(resources)) - } - } - - val extInterrupts = IntInternalInputNode(IntSourcePortSimple(num = nExtInterrupts, resources = device.int)) -} - -/** This trait should be used if the External Interrupts have NOT - * already been synchronized to the Periphery (PLIC) Clock. - */ -trait HasPeripheryAsyncExtInterrupts extends HasPeripheryExtInterrupts { - if (nExtInterrupts > 0) { - val extInterruptXing = LazyModule(new IntXing) - intBus.intnode := extInterruptXing.intnode - extInterruptXing.intnode := extInterrupts - } -} - -/** This trait can be used if the External Interrupts have already been synchronized - * to the Periphery (PLIC) Clock. - */ -trait HasPeripherySyncExtInterrupts extends HasPeripheryExtInterrupts { - if (nExtInterrupts > 0) { - intBus.intnode := extInterrupts - } -} - -/** Common io name and methods for propagating or tying off the port bundle */ -trait HasPeripheryExtInterruptsBundle extends HasPeripheryParameters { - val interrupts: UInt - def tieOffInterrupts(dummy: Int = 1) { - interrupts := UInt(0) - } -} - -/** This trait performs the translation from a UInt IO into Diplomatic Interrupts. - * The wiring must be done in the concrete LazyModuleImp. - */ -trait HasPeripheryExtInterruptsModuleImp extends LazyMultiIOModuleImp with HasPeripheryExtInterruptsBundle { - val outer: HasPeripheryExtInterrupts - val interrupts = IO(UInt(INPUT, width = outer.nExtInterrupts)) - - outer.extInterrupts.bundleIn.flatten.zipWithIndex.foreach { case(o, i) => o := interrupts(i) } -} - -///// The following traits add ports to the sytem, in some cases converting to different interconnect standards - -/** Adds a port to the system intended to master an AXI4 DRAM controller. */ -trait HasPeripheryMasterAXI4MemPort extends HasSystemNetworks { - val module: HasPeripheryMasterAXI4MemPortModuleImp - - private val config = p(ExtMem) - private val channels = p(BankedL2Config).nMemoryChannels - private val blockBytes = p(CacheBlockBytes) - - private val device = new MemoryDevice - - val mem_axi4 = AXI4BlindOutputNode(Seq.tabulate(channels) { channel => - val base = AddressSet(config.base, config.size-1) - val filter = AddressSet(channel * blockBytes, ~((channels-1) * blockBytes)) - - AXI4SlavePortParameters( - slaves = Seq(AXI4SlaveParameters( - address = base.intersect(filter).toList, - resources = device.reg, - regionType = RegionType.UNCACHED, // cacheable - executable = true, - supportsWrite = TransferSizes(1, blockBytes), - supportsRead = TransferSizes(1, blockBytes), - interleavedId = Some(0))), // slave does not interleave read responses - beatBytes = config.beatBytes) - }) - - private val converter = LazyModule(new TLToAXI4(config.beatBytes)) - private val trim = LazyModule(new AXI4IdIndexer(config.idBits)) - private val yank = LazyModule(new AXI4UserYanker) - private val buffer = LazyModule(new AXI4Buffer) - - mem foreach { case xbar => - converter.node := xbar.node - trim.node := converter.node - yank.node := trim.node - buffer.node := yank.node - mem_axi4 := buffer.node - } -} - -/** Common io name and methods for propagating or tying off the port bundle */ -trait HasPeripheryMasterAXI4MemPortBundle extends HasPeripheryParameters { - val mem_axi4: HeterogeneousBag[AXI4Bundle] - def connectSimAXIMem(dummy: Int = 1) = { - if (nMemoryChannels > 0) Module(LazyModule(new SimAXIMem(nMemoryChannels)).module).io.axi4 <> mem_axi4 - } -} - -/** Actually generates the corresponding IO in the concrete Module */ -trait HasPeripheryMasterAXI4MemPortModuleImp extends LazyMultiIOModuleImp with HasPeripheryMasterAXI4MemPortBundle { - val outer: HasPeripheryMasterAXI4MemPort - val mem_axi4 = IO(outer.mem_axi4.bundleOut) -} - -/** Adds a AXI4 port to the system intended to master an MMIO device bus */ -trait HasPeripheryMasterAXI4MMIOPort extends HasSystemNetworks { - private val config = p(ExtBus) - private val device = new SimpleBus("mmio", Nil) - val mmio_axi4 = AXI4BlindOutputNode(Seq(AXI4SlavePortParameters( - slaves = Seq(AXI4SlaveParameters( - address = List(AddressSet(BigInt(config.base), config.size-1)), - resources = device.ranges, - executable = true, // Can we run programs on this memory? - supportsWrite = TransferSizes(1, 256), // The slave supports 1-256 byte transfers - supportsRead = TransferSizes(1, 256))), - beatBytes = config.beatBytes))) - - mmio_axi4 := - AXI4Buffer()( - AXI4UserYanker()( - AXI4Deinterleaver(cacheBlockBytes)( - AXI4IdIndexer(config.idBits)( - TLToAXI4(config.beatBytes)( - TLWidthWidget(socBusConfig.beatBytes)( // convert width before attaching to socBus - socBus.node)))))) -} - -/** Common io name and methods for propagating or tying off the port bundle */ -trait HasPeripheryMasterAXI4MMIOPortBundle extends HasPeripheryParameters { - val mmio_axi4: HeterogeneousBag[AXI4Bundle] - def connectSimAXIMMIO(dummy: Int = 1) { - Module(LazyModule(new SimAXIMem(1, 4096)).module).io.axi4 <> mmio_axi4 - } -} - -/** Actually generates the corresponding IO in the concrete Module */ -trait HasPeripheryMasterAXI4MMIOPortModuleImp extends LazyMultiIOModuleImp with HasPeripheryMasterAXI4MMIOPortBundle { - val outer: HasPeripheryMasterAXI4MMIOPort - val mmio_axi4 = IO(outer.mmio_axi4.bundleOut) -} - -/** Adds an AXI4 port to the system intended to be a slave on an MMIO device bus */ -trait HasPeripherySlaveAXI4Port extends HasSystemNetworks { - private val config = p(ExtIn) - val l2FrontendAXI4Node = AXI4BlindInputNode(Seq(AXI4MasterPortParameters( - masters = Seq(AXI4MasterParameters( - name = "AXI4 periphery", - id = IdRange(0, 1 << config.idBits)))))) - - private val fifoBits = 1 - fsb.node := - TLWidthWidget(config.beatBytes)( - AXI4ToTL()( - AXI4UserYanker(Some(1 << (config.sourceBits - fifoBits - 1)))( - AXI4Fragmenter()( - AXI4IdIndexer(fifoBits)( - l2FrontendAXI4Node))))) -} - -/** Common io name and methods for propagating or tying off the port bundle */ -trait HasPeripherySlaveAXI4PortBundle extends HasPeripheryParameters { - val l2_frontend_bus_axi4: HeterogeneousBag[AXI4Bundle] - def tieOffAXI4SlavePort(dummy: Int = 1) { - l2_frontend_bus_axi4.foreach { l2_axi4 => - l2_axi4.ar.valid := Bool(false) - l2_axi4.aw.valid := Bool(false) - l2_axi4.w .valid := Bool(false) - l2_axi4.r .ready := Bool(true) - l2_axi4.b .ready := Bool(true) - } - } -} - -/** Actually generates the corresponding IO in the concrete Module */ -trait HasPeripherySlaveAXI4PortModuleImp extends LazyMultiIOModuleImp with HasPeripherySlaveAXI4PortBundle { - val outer: HasPeripherySlaveAXI4Port - val l2_frontend_bus_axi4 = IO(outer.l2FrontendAXI4Node.bundleIn) -} - -/** Adds a TileLink port to the system intended to master an MMIO device bus */ -trait HasPeripheryMasterTLMMIOPort extends HasSystemNetworks { - private val config = p(ExtBus) - private val device = new SimpleBus("mmio", Nil) - val mmio_tl = TLBlindOutputNode(Seq(TLManagerPortParameters( - managers = Seq(TLManagerParameters( - address = List(AddressSet(BigInt(config.base), config.size-1)), - resources = device.ranges, - executable = true, - supportsGet = TransferSizes(1, cacheBlockBytes), - supportsPutFull = TransferSizes(1, cacheBlockBytes), - supportsPutPartial = TransferSizes(1, cacheBlockBytes))), - beatBytes = config.beatBytes))) - - mmio_tl := - TLBuffer()( - TLSourceShrinker(1 << config.idBits)( - TLWidthWidget(socBusConfig.beatBytes)( - socBus.node))) -} - -/** Common io name and methods for propagating or tying off the port bundle */ -trait HasPeripheryMasterTLMMIOPortBundle extends HasPeripheryParameters { - val mmio_tl: HeterogeneousBag[TLBundle] - def tieOffTLMMIO(dummy: Int = 1) { - mmio_tl.foreach { tl => - tl.a.ready := Bool(true) - tl.b.valid := Bool(false) - tl.c.ready := Bool(true) - tl.d.valid := Bool(false) - tl.e.ready := Bool(true) - } - } -} - -/** Actually generates the corresponding IO in the concrete Module */ -trait HasPeripheryMasterTLMMIOPortModuleImp extends LazyMultiIOModuleImp with HasPeripheryMasterTLMMIOPortBundle { - val outer: HasPeripheryMasterTLMMIOPort - val mmio_tl = IO(outer.mmio_tl.bundleOut) -} - -/** Adds an AXI4 port to the system intended to be a slave on an MMIO device bus. - * NOTE: this port is NOT allowed to issue Acquires. - */ -trait HasPeripherySlaveTLPort extends HasSystemNetworks { - private val config = p(ExtIn) - val l2FrontendTLNode = TLBlindInputNode(Seq(TLClientPortParameters( - clients = Seq(TLClientParameters( - name = "TL periph", - sourceId = IdRange(0, 1 << config.idBits)))))) - - fsb.node := - TLSourceShrinker(1 << config.sourceBits)( - TLWidthWidget(config.beatBytes)( - l2FrontendTLNode)) -} - -/** Common io name and methods for propagating or tying off the port bundle */ -trait HasPeripherySlaveTLPortBundle extends HasPeripheryParameters { - val l2_frontend_bus_tl: HeterogeneousBag[TLBundle] - def tieOffSlaveTLPort(dummy: Int = 1) { - l2_frontend_bus_tl.foreach { tl => - tl.a.valid := Bool(false) - tl.b.ready := Bool(true) - tl.c.valid := Bool(false) - tl.d.ready := Bool(true) - tl.e.valid := Bool(false) - } - } -} - -/** Actually generates the corresponding IO in the concrete Module */ -trait HasPeripherySlaveTLPortModuleImp extends LazyMultiIOModuleImp with HasPeripherySlaveTLPortBundle { - val outer: HasPeripherySlaveTLPort - val l2_frontend_bus_tl = IO(outer.l2FrontendTLNode.bundleIn) -} - -///// The following traits add specific devices to the periphery of the system. - -/** Adds a /dev/null slave that generates */ -trait HasPeripheryZeroSlave extends HasSystemNetworks { - private val config = p(ZeroConfig) - private val channels = p(BankedL2Config).nMemoryChannels - private val blockBytes = p(CacheBlockBytes) - - private val device = new SimpleDevice("rom", Seq("ucbbar,cacheable-zero0")) - - val zeros = mem.zipWithIndex.map { case (xbar, channel) => - val base = AddressSet(config.base, config.size-1) - val filter = AddressSet(channel * blockBytes, ~((channels-1) * blockBytes)) - val address = base.intersect(filter).get - val zero = LazyModule(new TLZero(address, beatBytes = config.beatBytes, resources = device.reg("mem"))) - zero.node := TLFragmenter(config.beatBytes, blockBytes)(xbar.node) - zero - } -} - -/** Adds a /dev/null slave that generates TL2 error response messages. */ -trait HasPeripheryErrorSlave extends HasSystemNetworks { - private val config = p(ErrorConfig) - private val maxXfer = min(config.address.map(_.alignment).max.toInt, 4096) - val error = LazyModule(new TLError(config.address, peripheryBusConfig.beatBytes)) - - // Most slaves do not support a 4kB burst so this slave ends up with many more source bits than others; - // we exclude the onerously large TLMonitor that results. - error.node connectButDontMonitor TLFragmenter(peripheryBusConfig.beatBytes, maxXfer)(peripheryBus.node) -} - - -/** Adds a SRAM to the system for testing purposes. */ -trait HasPeripheryTestRAMSlave extends HasSystemNetworks { - val testram = LazyModule(new TLRAM(AddressSet(0x52000000, 0xfff), true, peripheryBusConfig.beatBytes)) - testram.node := TLFragmenter(peripheryBusConfig.beatBytes, cacheBlockBytes)(peripheryBus.node) -} - -/** Adds a fuzzing master to the system for testing purposes. */ -trait HasPeripheryTestFuzzMaster extends HasSystemNetworks { - val fuzzer = LazyModule(new TLFuzzer(5000)) - peripheryBus.node := fuzzer.node -} diff --git a/src/main/scala/chip/RISCVPlatform.scala b/src/main/scala/chip/RISCVPlatform.scala deleted file mode 100644 index bef01db8..00000000 --- a/src/main/scala/chip/RISCVPlatform.scala +++ /dev/null @@ -1,122 +0,0 @@ -// See LICENSE.SiFive for license details. - -package freechips.rocketchip.chip - -import Chisel._ - -import freechips.rocketchip.config._ -import freechips.rocketchip.devices.debug._ -import freechips.rocketchip.devices.tilelink._ -import freechips.rocketchip.coreplex._ -import freechips.rocketchip.diplomacy._ -import freechips.rocketchip.jtag.JTAGIO -import freechips.rocketchip.tilelink._ -import freechips.rocketchip.util._ - -/** All the traits defined in this file assume that they are being mixed in - * to a system that has a standard RISCV-based coreplex platform. - */ -trait HasCoreplexRISCVPlatform { - implicit val p: Parameters - val coreplex: CoreplexRISCVPlatform -} - -/** A wrapper around JTAG providing a reset signal and manufacturer id. */ -class SystemJTAGIO extends Bundle { - val jtag = new JTAGIO(hasTRSTn = false).flip - val reset = Bool(INPUT) - val mfr_id = UInt(INPUT, 11) -} - -/** A wrapper bundle containing one of the two possible debug interfaces */ -class DebugIO(implicit p: Parameters) extends ParameterizedBundle()(p) { - val clockeddmi = (!p(IncludeJtagDTM)).option(new ClockedDMIIO().flip) - val systemjtag = (p(IncludeJtagDTM)).option(new SystemJTAGIO) - val ndreset = Bool(OUTPUT) - val dmactive = Bool(OUTPUT) -} - -/** Either adds a JTAG DTM to system, and exports a JTAG interface, - * or exports the Debug Module Interface (DMI), based on a global parameter. - */ -trait HasPeripheryDebug extends HasSystemNetworks with HasCoreplexRISCVPlatform { - val module: HasPeripheryDebugModuleImp -} - -trait HasPeripheryDebugBundle extends HasPeripheryParameters { - val debug: DebugIO - def connectDebug(c: Clock, r: Bool, out: Bool) { - debug.clockeddmi.foreach { d => - val dtm = Module(new SimDTM).connect(c, r, d, out) - } - debug.systemjtag.foreach { sj => - val jtag = Module(new JTAGVPI).connect(sj.jtag, sj.reset, r, out) - sj.mfr_id := p(JtagDTMKey).idcodeManufId.U(11.W) - } - } -} - -trait HasPeripheryDebugModuleImp extends LazyMultiIOModuleImp with HasPeripheryDebugBundle { - val outer: HasPeripheryDebug - - val debug = IO(new DebugIO) - - debug.clockeddmi.foreach { dbg => outer.coreplex.module.io.debug <> dbg } - - val dtm = debug.systemjtag.map { sj => - val dtm = Module(new DebugTransportModuleJTAG(p(DMKey).nDMIAddrSize, p(JtagDTMKey))) - dtm.io.jtag <> sj.jtag - - dtm.clock := sj.jtag.TCK - dtm.io.jtag_reset := sj.reset - dtm.io.jtag_mfr_id := sj.mfr_id - dtm.reset := dtm.io.fsmReset - - outer.coreplex.module.io.debug.dmi <> dtm.io.dmi - outer.coreplex.module.io.debug.dmiClock := sj.jtag.TCK - outer.coreplex.module.io.debug.dmiReset := ResetCatchAndSync(sj.jtag.TCK, sj.reset, "dmiResetCatch") - dtm - } - - debug.ndreset := outer.coreplex.module.io.ndreset - debug.dmactive := outer.coreplex.module.io.dmactive -} - -/** Real-time clock is based on RTCPeriod relative to system clock. - * Note: nothing about this is diplomatic, all the work is done in the ModuleImp - */ -trait HasPeripheryRTCCounter extends HasSystemNetworks with HasCoreplexRISCVPlatform { - val module: HasPeripheryRTCCounterModuleImp -} - -trait HasPeripheryRTCCounterModuleImp extends LazyMultiIOModuleImp { - val outer: HasPeripheryRTCCounter - val period = p(RTCPeriod) - val rtcCounter = RegInit(UInt(0, width = log2Up(period))) - val rtcWrap = rtcCounter === UInt(period-1) - - rtcCounter := Mux(rtcWrap, UInt(0), rtcCounter + UInt(1)) - outer.coreplex.module.io.rtcToggle := rtcCounter(log2Up(period)-1) -} - -/** Adds a boot ROM that contains the DTB describing the system's coreplex. */ -case class BootROMParams(address: BigInt = 0x10000, size: Int = 0x10000, hang: BigInt = 0x10040) - -case object PeripheryBootROMKey extends Field[BootROMParams] - -trait HasPeripheryBootROM extends HasSystemNetworks with HasCoreplexRISCVPlatform { - val bootROMParams = p(PeripheryBootROMKey) - val bootrom_address = bootROMParams.address - val bootrom_size = bootROMParams.size - val bootrom_hang = bootROMParams.hang - private lazy val bootrom_contents = GenerateBootROM(coreplex.dtb) - val bootrom = LazyModule(new TLROM(bootrom_address, bootrom_size, bootrom_contents, true, peripheryBusConfig.beatBytes)) - - bootrom.node := TLFragmenter(peripheryBusConfig.beatBytes, cacheBlockBytes)(peripheryBus.node) -} - -/** Coreplex will power-on running at 0x10040 (BootROM) */ -trait HasPeripheryBootROMModuleImp extends LazyMultiIOModuleImp { - val outer: HasPeripheryBootROM - outer.coreplex.module.io.resetVector := UInt(outer.bootrom_hang) -} diff --git a/src/main/scala/chip/RocketPlexMaster.scala b/src/main/scala/chip/RocketPlexMaster.scala deleted file mode 100644 index 8e5c4e2e..00000000 --- a/src/main/scala/chip/RocketPlexMaster.scala +++ /dev/null @@ -1,33 +0,0 @@ -// See LICENSE.SiFive for license details. - -package freechips.rocketchip.chip - -import Chisel._ - -import freechips.rocketchip.coreplex.RocketPlex -import freechips.rocketchip.diplomacy.{LazyModule, LazyMultiIOModuleImp} - -/** Add a RocketPlex to the system */ -trait HasRocketPlexMaster extends HasSystemNetworks with HasCoreplexRISCVPlatform { - val module: HasRocketPlexMasterModuleImp - - val coreplex = LazyModule(new RocketPlex) - - coreplex.l2in :=* fsb.node - bsb.node :*= coreplex.l2out - socBus.node := coreplex.mmio - coreplex.mmioInt := intBus.intnode - - require (mem.size == coreplex.mem.size) - (mem zip coreplex.mem) foreach { case (xbar, channel) => xbar.node :=* channel } -} - - -trait HasRocketPlexMasterModuleImp extends LazyMultiIOModuleImp { - val outer: HasRocketPlexMaster - - outer.coreplex.module.io.tcrs.foreach { case tcr => - tcr.clock := clock - tcr.reset := reset - } -} diff --git a/src/main/scala/chip/System.scala b/src/main/scala/chip/System.scala deleted file mode 100644 index ddef55e4..00000000 --- a/src/main/scala/chip/System.scala +++ /dev/null @@ -1,25 +0,0 @@ -// See LICENSE.SiFive for license details. - -package freechips.rocketchip.chip - -import Chisel._ - -import freechips.rocketchip.config.Parameters -import freechips.rocketchip.diplomacy.{LazyModule, LazyMultiIOModuleImp} -import freechips.rocketchip.util.ElaborationArtefacts - -/** BareSystem is the root class for creating a top-level RTL module */ -abstract class BareSystem(implicit p: Parameters) extends LazyModule { - ElaborationArtefacts.add("graphml", graphML) -} - -abstract class BareSystemModule[+L <: BareSystem](_outer: L) extends LazyMultiIOModuleImp(_outer) { - val outer = _outer -} - -/** Base System class with no peripheral devices or ports added */ -abstract class BaseSystem(implicit p: Parameters) extends BareSystem with HasSystemNetworks { - override val module: BaseSystemModule[BaseSystem] -} - -abstract class BaseSystemModule[+L <: BaseSystem](_outer: L) extends BareSystemModule(_outer) diff --git a/src/main/scala/chip/TestHarness.scala b/src/main/scala/chip/TestHarness.scala deleted file mode 100644 index fe57443c..00000000 --- a/src/main/scala/chip/TestHarness.scala +++ /dev/null @@ -1,95 +0,0 @@ -// See LICENSE.SiFive for license details. - -package freechips.rocketchip.chip - -import Chisel._ - -import freechips.rocketchip.amba.axi4._ -import freechips.rocketchip.config.Parameters -import freechips.rocketchip.coreplex._ -import freechips.rocketchip.devices.debug._ -import freechips.rocketchip.diplomacy._ -import freechips.rocketchip.jtag.JTAGIO - -class TestHarness()(implicit p: Parameters) extends Module { - val io = new Bundle { - val success = Bool(OUTPUT) - } - - val dut = Module(LazyModule(new ExampleRocketTop).module) - dut.reset := reset | dut.debug.ndreset - - dut.tieOffInterrupts() - dut.connectSimAXIMem() - dut.connectSimAXIMMIO() - dut.tieOffAXI4SlavePort() - dut.connectDebug(clock, reset, io.success) -} - -class SimAXIMem(channels: Int, forceSize: BigInt = 0)(implicit p: Parameters) extends LazyModule { - val config = p(ExtMem) - val totalSize = if (forceSize > 0) forceSize else BigInt(config.size) - val size = totalSize / channels - require(totalSize % channels == 0) - - val node = AXI4BlindInputNode(Seq.fill(channels) { - AXI4MasterPortParameters(Seq(AXI4MasterParameters( - name = "dut", - id = IdRange(0, 1 << config.idBits))))}) - - for (i <- 0 until channels) { - val sram = LazyModule(new AXI4RAM(AddressSet(0, size-1), beatBytes = config.beatBytes)) - sram.node := AXI4Buffer()(AXI4Fragmenter()(node)) - } - - lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val axi4 = node.bundleIn - } - } -} - -class SimDTM(implicit p: Parameters) extends BlackBox { - val io = new Bundle { - val clk = Clock(INPUT) - val reset = Bool(INPUT) - val debug = new DMIIO - val exit = UInt(OUTPUT, 32) - } - - def connect(tbclk: Clock, tbreset: Bool, dutio: ClockedDMIIO, tbsuccess: Bool) = { - io.clk := tbclk - io.reset := tbreset - dutio.dmi <> io.debug - dutio.dmiClock := tbclk - dutio.dmiReset := tbreset - - tbsuccess := io.exit === UInt(1) - when (io.exit >= UInt(2)) { - printf("*** FAILED *** (exit code = %d)\n", io.exit >> UInt(1)) - stop(1) - } - } -} - -class JTAGVPI(implicit val p: Parameters) extends BlackBox { - val io = new Bundle { - val jtag = new JTAGIO(hasTRSTn = false) - val enable = Bool(INPUT) - val init_done = Bool(INPUT) - } - - def connect(dutio: JTAGIO, jtag_reset: Bool, tbreset: Bool, tbsuccess: Bool) = { - dutio <> io.jtag - - dutio.TRSTn.foreach{ _:= false.B} - jtag_reset := tbreset - - io.enable := ~tbreset - io.init_done := ~tbreset - - // Success is determined by the gdbserver - // which is controlling this simulation. - tbsuccess := Bool(false) - } -} diff --git a/src/main/scala/chip/Utils.scala b/src/main/scala/chip/Utils.scala deleted file mode 100644 index bab78811..00000000 --- a/src/main/scala/chip/Utils.scala +++ /dev/null @@ -1,56 +0,0 @@ -// See LICENSE.SiFive for license details. - -package freechips.rocketchip.chip - -import freechips.rocketchip.config.Parameters -import freechips.rocketchip.diplomacy.DTB -import freechips.rocketchip.coreplex.BootROMFile -import java.nio.file.{Files, Paths} -import java.nio.{ByteBuffer, ByteOrder} -import scala.collection.mutable.ArrayBuffer - -class RangeManager { - private var finalized = false - private val l = collection.mutable.ListBuffer[(String, Int)]() - def add(name: String, element: Int) = { require(!finalized); l += (name -> element) } - def rangeMap = { - finalized = true - (l map { - var sum = 0 - x => { sum += x._2; (x._1 -> (sum-x._2, sum)) } - }).toMap - } - def range(name: String) = rangeMap(name) - def print = { - rangeMap.toSeq.sortBy(_._2).foreach { case (name, (start, end)) => - println(s"${name} on int ${start}-${end-1}") - } - } - def sum = { - finalized = true - l.map(_._2).sum - } -} - -class ResourceManager[T] { - private var finalized = false - private val l = ArrayBuffer[T]() - def add(element: T) = { require(!finalized); l += element } - def add(list: Seq[T]) = { require(!finalized); l ++= list } - def get: Seq[T] = { finalized = true; l } -} - -class GlobalVariable[T] { - private var assigned = false - private var variable: T = _ - def assign(value: T) = { require(!assigned); assigned = true; variable = value } - def get: T = { require(assigned); variable } -} - -object GenerateBootROM { - def apply(dtb: DTB)(implicit p: Parameters) = { - val romdata = Files.readAllBytes(Paths.get(p(BootROMFile))) - val rom = ByteBuffer.wrap(romdata) - rom.array() ++ dtb.contents - } -} diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index eefaf011..7c7be713 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -3,83 +3,133 @@ package freechips.rocketchip.coreplex import Chisel._ - -import freechips.rocketchip.config._ +import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ -import freechips.rocketchip.tile.{ XLen, TileInterrupts} +import freechips.rocketchip.rocket.PAddrBits import freechips.rocketchip.tilelink._ import freechips.rocketchip.util._ -/** Widths of various points in the SoC */ -case class TLBusConfig(beatBytes: Int) -case object CBusConfig extends Field[TLBusConfig] -case object L1toL2Config extends Field[TLBusConfig] +/** Enumerates the three types of clock crossing between tiles and system bus */ +sealed trait CoreplexClockCrossing +case class SynchronousCrossing(params: BufferParams = BufferParams.default) extends CoreplexClockCrossing +case class RationalCrossing(direction: RationalDirection = FastToSlow) extends CoreplexClockCrossing +case class AsynchronousCrossing(depth: Int, sync: Int = 2) extends CoreplexClockCrossing -// These parameters apply to all caches, for now -case object CacheBlockBytes extends Field[Int] - -/** L2 Broadcast Hub configuration */ -case class BroadcastConfig( - nTrackers: Int = 4, - bufferless: Boolean = false) -case object BroadcastConfig extends Field[BroadcastConfig] - -/** L2 memory subsystem configuration */ -case class BankedL2Config( - nMemoryChannels: Int = 1, - nBanksPerChannel: Int = 1, - coherenceManager: (Parameters, CoreplexNetwork) => (TLInwardNode, TLOutwardNode) = { case (q, _) => - implicit val p = q - val BroadcastConfig(nTrackers, bufferless) = p(BroadcastConfig) - val bh = LazyModule(new TLBroadcast(p(CacheBlockBytes), nTrackers, bufferless)) - val ww = LazyModule(new TLWidthWidget(p(L1toL2Config).beatBytes)) - ww.node :*= bh.node - (bh.node, ww.node) - }) { - val nBanks = nMemoryChannels*nBanksPerChannel -} -case object BankedL2Config extends Field[BankedL2Config] - -/** The file to read the BootROM contents from */ -case object BootROMFile extends Field[String] - -trait HasCoreplexParameters { - implicit val p: Parameters - lazy val tilesParams = p(RocketTilesKey) - lazy val sbusConfig = p(L1toL2Config) - lazy val pbusConfig = p(CBusConfig) - lazy val nTiles = tilesParams.size - lazy val l2Config = p(BankedL2Config) - def sbusBeatBytes = sbusConfig.beatBytes - def sbusBlockBytes = p(CacheBlockBytes) - def pbusBeatBytes = pbusConfig.beatBytes - def pbusBlockBytes = sbusBlockBytes +/** BareCoreplex is the root class for creating a coreplex sub-system */ +abstract class BareCoreplex(implicit p: Parameters) extends LazyModule with BindingScope { + lazy val dts = DTS(bindingTree) + lazy val dtb = DTB(dts) + lazy val json = JSON(bindingTree) } -case class CoreplexParameters(implicit val p: Parameters) extends HasCoreplexParameters - -abstract class BareCoreplex(implicit p: Parameters) extends LazyModule with BindingScope - -abstract class BareCoreplexBundle[+L <: BareCoreplex](_outer: L) extends GenericParameterizedBundle(_outer) { +abstract class BareCoreplexModule[+L <: BareCoreplex](_outer: L) extends LazyMultiIOModuleImp(_outer) { val outer = _outer - implicit val p = outer.p -} - -abstract class BareCoreplexModule[+L <: BareCoreplex, +B <: BareCoreplexBundle[L]](_outer: L, _io: () => B) extends LazyModuleImp(_outer) { - val outer = _outer - val io = _io () + ElaborationArtefacts.add("graphml", outer.graphML) + ElaborationArtefacts.add("dts", outer.dts) + ElaborationArtefacts.add("json", outer.json) + println(outer.dts) } +/** Base Coreplex class with no peripheral devices or ports added */ abstract class BaseCoreplex(implicit p: Parameters) extends BareCoreplex - with CoreplexNetwork - with BankedL2CoherenceManagers { - override lazy val module = new BaseCoreplexModule(this, () => new BaseCoreplexBundle(this)) + with HasInterruptBus + with HasSystemBus + with HasPeripheryBus + with HasMemoryBus { + override val module: BaseCoreplexModule[BaseCoreplex] + + val root = new Device { + def describe(resources: ResourceBindings): Description = { + val width = resources("width").map(_.value) + Description("/", Map( + "#address-cells" -> width, + "#size-cells" -> width, + "model" -> Seq(ResourceString(p(DTSModel))), + "compatible" -> (p(DTSModel) +: p(DTSCompat)).map(s => ResourceString(s + "-dev")))) + } + } + + val soc = new Device { + def describe(resources: ResourceBindings): Description = { + val width = resources("width").map(_.value) + Description("soc", Map( + "#address-cells" -> width, + "#size-cells" -> width, + "compatible" -> ((p(DTSModel) +: p(DTSCompat)).map(s => ResourceString(s + "-soc")) :+ ResourceString("simple-bus")), + "ranges" -> Nil)) + } + } + + val cpus = new Device { + def describe(resources: ResourceBindings): Description = { + Description("cpus", Map( + "#address-cells" -> Seq(ResourceInt(1)), + "#size-cells" -> Seq(ResourceInt(0)), + "timebase-frequency" -> Seq(ResourceInt(p(DTSTimebase))))) + } + } + + // Make topManagers an Option[] so as to avoid LM name reflection evaluating it... + lazy val topManagers = Some(ManagerUnification(sharedMemoryTLEdge.manager.managers)) + ResourceBinding { + val managers = topManagers.get + val max = managers.flatMap(_.address).map(_.max).max + val width = ResourceInt((log2Ceil(max)+31) / 32) + Resource(root, "width").bind(width) + Resource(soc, "width").bind(width) + Resource(cpus, "null").bind(ResourceString("")) + + managers.foreach { case manager => + val value = manager.toResource + manager.resources.foreach { case resource => + resource.bind(value) + } + } + } } -class BaseCoreplexBundle[+L <: BaseCoreplex](_outer: L) extends BareCoreplexBundle(_outer) - with CoreplexNetworkBundle - with BankedL2CoherenceManagersBundle +abstract class BaseCoreplexModule[+L <: BaseCoreplex](_outer: L) extends BareCoreplexModule(_outer) { + println("Generated Address Map") + private val aw = (outer.sharedMemoryTLEdge.bundle.addressBits-1)/4 + 1 + private val fmt = s"\t%${aw}x - %${aw}x %c%c%c%c %s" -class BaseCoreplexModule[+L <: BaseCoreplex, +B <: BaseCoreplexBundle[L]](_outer: L, _io: () => B) extends BareCoreplexModule(_outer, _io) - with CoreplexNetworkModule - with BankedL2CoherenceManagersModule + private def collect(path: List[String], value: ResourceValue): List[(String, ResourceAddress)] = { + value match { + case r: ResourceAddress => List((path(1), r)) + case b: ResourceMapping => List((path(1), ResourceAddress(b.address, b.permissions))) + case ResourceMap(value, _) => value.toList.flatMap { case (key, seq) => seq.flatMap(r => collect(key :: path, r)) } + case _ => Nil + } + } + private val ranges = collect(Nil, outer.bindingTree).groupBy(_._2).toList.flatMap { case (key, seq) => + AddressRange.fromSets(key.address).map { r => (r, key.permissions, seq.map(_._1)) } + }.sortBy(_._1) + private val json = ranges.map { case (range, ResourcePermissions(r, w, x, c), names) => + println(fmt.format( + range.base, + range.base+range.size, + if (r) 'R' else ' ', + if (w) 'W' else ' ', + if (x) 'X' else ' ', + if (c) 'C' else ' ', + names.mkString(", "))) + s"""{"base":[${range.base}],"size":[${range.size}],"r":[$r],"w":[$w],"x":[$x],"c":[$c],"names":[${names.map('"'+_+'"').mkString(",")}]}""" + } + println("") + ElaborationArtefacts.add("memmap.json", s"""{"mapping":[${json.mkString(",")}]}""") + + // Confirm that all of memory was described by DTS + private val dtsRanges = AddressRange.unify(ranges.map(_._1)) + private val allRanges = AddressRange.unify(outer.topManagers.get.flatMap { m => AddressRange.fromSets(m.address) }) + + if (dtsRanges != allRanges) { + println("Address map described by DTS differs from physical implementation:") + AddressRange.subtract(allRanges, dtsRanges).foreach { case r => + println(s"\texists, but undescribed by DTS: ${r}") + } + AddressRange.subtract(dtsRanges, allRanges).foreach { case r => + println(s"\tdoes not exist, but described by DTS: ${r}") + } + println("") + } +} diff --git a/src/main/scala/coreplex/Configs.scala b/src/main/scala/coreplex/Configs.scala index 65bd8cd8..374150c8 100644 --- a/src/main/scala/coreplex/Configs.scala +++ b/src/main/scala/coreplex/Configs.scala @@ -4,7 +4,6 @@ package freechips.rocketchip.coreplex import Chisel._ - import freechips.rocketchip.config._ import freechips.rocketchip.devices.debug._ import freechips.rocketchip.devices.tilelink._ @@ -15,6 +14,7 @@ import freechips.rocketchip.tilelink._ import freechips.rocketchip.util._ class BaseCoreplexConfig extends Config ((site, here, up) => { + // Tile parameters case PAddrBits => 32 case PgLevels => if (site(XLen) == 64) 3 /* Sv39 */ else 2 /* Sv32 */ case ASIdBits => 0 @@ -22,19 +22,26 @@ class BaseCoreplexConfig extends Config ((site, here, up) => { case ResetVectorBits => site(PAddrBits) case MaxHartIdBits => log2Up(site(RocketTilesKey).size) case BuildCore => (p: Parameters) => new Rocket()(p) + case RocketTilesKey => Nil // Will be added by partial configs found below + // Interconnect parameters case RocketCrossing => SynchronousCrossing() - case RocketTilesKey => Nil - case DMKey => DefaultDebugModuleConfig(site(XLen)) - case PLICKey => PLICParams() - case ClintKey => ClintParams() - case CBusConfig => TLBusConfig(beatBytes = site(XLen)/8) - case L1toL2Config => TLBusConfig(beatBytes = site(XLen)/8) // increase for more PCIe bandwidth - case BootROMFile => "./bootrom/bootrom.img" - case BroadcastConfig => BroadcastConfig() - case BankedL2Config => BankedL2Config() + case BroadcastParams => BroadcastParams() + case BankedL2Params => BankedL2Params() + case SystemBusParams => SystemBusParams(beatBytes = site(XLen)/8, blockBytes = site(CacheBlockBytes)) + case PeripheryBusParams => PeripheryBusParams(beatBytes = site(XLen)/8, blockBytes = site(CacheBlockBytes)) + case MemoryBusParams => MemoryBusParams(beatBytes = 8, blockBytes = site(CacheBlockBytes)) case CacheBlockBytes => 64 + // Device parameters + case DebugModuleParams => DefaultDebugModuleParams(site(XLen)) + case PLICParams => PLICParams() + case ClintParams => ClintParams() + // TileLink connection global parameters + case TLMonitorBuilder => (args: TLMonitorArgs) => Some(LazyModule(new TLMonitor(args))) + case TLCombinationalCheck => false }) +/* Composable partial function Configs to set individual parameters */ + class WithNBigCores(n: Int) extends Config((site, here, up) => { case RocketTilesKey => { val big = RocketTileParams( @@ -43,11 +50,11 @@ class WithNBigCores(n: Int) extends Config((site, here, up) => { mulEarlyOut = true, divEarlyOut = true))), dcache = Some(DCacheParams( - rowBits = site(L1toL2Config).beatBytes*8, - nMSHRs = 0, + rowBits = site(SystemBusParams).beatBits, + nMSHRs = 0, blockBytes = site(CacheBlockBytes))), icache = Some(ICacheParams( - rowBits = site(L1toL2Config).beatBytes*8, + rowBits = site(SystemBusParams).beatBits, blockBytes = site(CacheBlockBytes)))) List.fill(n)(big) ++ up(RocketTilesKey, site) } @@ -59,14 +66,14 @@ class WithNSmallCores(n: Int) extends Config((site, here, up) => { core = RocketCoreParams(useVM = false, fpu = None), btb = None, dcache = Some(DCacheParams( - rowBits = site(L1toL2Config).beatBytes*8, + rowBits = site(SystemBusParams).beatBits, nSets = 64, nWays = 1, nTLBEntries = 4, nMSHRs = 0, blockBytes = site(CacheBlockBytes))), icache = Some(ICacheParams( - rowBits = site(L1toL2Config).beatBytes*8, + rowBits = site(SystemBusParams).beatBits, nSets = 64, nWays = 1, nTLBEntries = 4, @@ -75,12 +82,39 @@ class WithNSmallCores(n: Int) extends Config((site, here, up) => { } }) +class WithNTinyCores(n: Int) extends Config((site, here, up) => { + case XLen => 32 + case RocketTilesKey => { + val tiny = RocketTileParams( + core = RocketCoreParams( + useVM = false, + fpu = None, + mulDiv = Some(MulDivParams(mulUnroll = 8))), + btb = None, + dcache = Some(DCacheParams( + rowBits = site(SystemBusParams).beatBits, + nSets = 256, // 16Kb scratchpad + nWays = 1, + nTLBEntries = 4, + nMSHRs = 0, + blockBytes = site(CacheBlockBytes), + scratch = Some(0x80000000L))), + icache = Some(ICacheParams( + rowBits = site(SystemBusParams).beatBits, + nSets = 64, + nWays = 1, + nTLBEntries = 4, + blockBytes = site(CacheBlockBytes)))) + List.fill(n)(tiny) ++ up(RocketTilesKey, site) + } +}) + class WithNBanksPerMemChannel(n: Int) extends Config((site, here, up) => { - case BankedL2Config => up(BankedL2Config, site).copy(nBanksPerChannel = n) + case BankedL2Params => up(BankedL2Params, site).copy(nBanksPerChannel = n) }) class WithNTrackersPerBank(n: Int) extends Config((site, here, up) => { - case BroadcastConfig => up(BroadcastConfig, site).copy(nTrackers = n) + case BroadcastParams => up(BroadcastParams, site).copy(nTrackers = n) }) // This is the number of icache sets for all Rocket tiles @@ -112,7 +146,7 @@ class WithCacheBlockBytes(linesize: Int) extends Config((site, here, up) => { }) class WithBufferlessBroadcastHub extends Config((site, here, up) => { - case BroadcastConfig => up(BroadcastConfig, site).copy(bufferless = true) + case BroadcastParams => up(BroadcastParams, site).copy(bufferless = true) }) /** @@ -128,12 +162,10 @@ class WithBufferlessBroadcastHub extends Config((site, here, up) => { * DO NOT use this configuration. */ class WithStatelessBridge extends Config((site, here, up) => { - case BankedL2Config => up(BankedL2Config, site).copy(coherenceManager = { case (q, _) => + case BankedL2Params => up(BankedL2Params, site).copy(coherenceManager = { case (q, _) => implicit val p = q val cork = LazyModule(new TLCacheCork(unsafe = true)) - val ww = LazyModule(new TLWidthWidget(p(L1toL2Config).beatBytes)) - ww.node :*= cork.node - (cork.node, ww.node) + (cork.node, cork.node) }) }) @@ -208,7 +240,7 @@ class WithFPUWithoutDivSqrt extends Config((site, here, up) => { }) class WithBootROMFile(bootROMFile: String) extends Config((site, here, up) => { - case BootROMFile => bootROMFile + case BootROMParams => up(BootROMParams, site).copy(contentFileName = bootROMFile) }) class WithSynchronousRocketTiles extends Config((site, here, up) => { @@ -223,3 +255,49 @@ class WithRationalRocketTiles extends Config((site, here, up) => { case RocketCrossing => RationalCrossing() }) +class WithEdgeDataBits(dataBits: Int) extends Config((site, here, up) => { + case MemoryBusParams => up(MemoryBusParams, site).copy(beatBytes = dataBits/8) + case ExtIn => up(ExtIn, site).copy(beatBytes = dataBits/8) + +}) + +class WithJtagDTM extends Config ((site, here, up) => { + case IncludeJtagDTM => true +}) + +class WithNoPeripheryArithAMO extends Config ((site, here, up) => { + case PeripheryBusParams => up(PeripheryBusParams, site).copy(arithmetic = false) +}) + +class WithNBitPeripheryBus(nBits: Int) extends Config ((site, here, up) => { + case PeripheryBusParams => up(PeripheryBusParams, site).copy(beatBytes = nBits/8) +}) + +class WithoutTLMonitors extends Config ((site, here, up) => { + case TLMonitorBuilder => (args: TLMonitorArgs) => None +}) + +class WithNExtTopInterrupts(nExtInts: Int) extends Config((site, here, up) => { + case NExtTopInterrupts => nExtInts +}) + +class WithRTCPeriod(nCycles: Int) extends Config((site, here, up) => { + case RTCPeriod => nCycles +}) + +class WithNMemoryChannels(n: Int) extends Config((site, here, up) => { + case BankedL2Params => up(BankedL2Params, site).copy(nMemoryChannels = n) +}) + +class WithExtMemSize(n: Long) extends Config((site, here, up) => { + case ExtMem => up(ExtMem, site).copy(size = n) +}) + +class WithDTS(model: String, compat: Seq[String]) extends Config((site, here, up) => { + case DTSModel => model + case DTSCompat => compat +}) + +class WithTimebase(hertz: BigInt) extends Config((site, here, up) => { + case DTSTimebase => hertz +}) diff --git a/src/main/scala/coreplex/CoreplexNetwork.scala b/src/main/scala/coreplex/CoreplexNetwork.scala deleted file mode 100644 index 7476b841..00000000 --- a/src/main/scala/coreplex/CoreplexNetwork.scala +++ /dev/null @@ -1,190 +0,0 @@ -// See LICENSE.SiFive for license details. - -package freechips.rocketchip.coreplex - -import Chisel._ - -import freechips.rocketchip.config._ -import freechips.rocketchip.diplomacy._ -import freechips.rocketchip.rocket.PAddrBits -import freechips.rocketchip.tilelink._ -import freechips.rocketchip.util._ - -trait CoreplexNetwork extends HasCoreplexParameters { - val module: CoreplexNetworkModule - def bindingTree: ResourceMap - - // TODO: do we need one of these? val cbus = LazyModule(new TLXbar) // Locally-visible peripheral devices - val sbus = LazyModule(new TLXbar) // Globally-visible high-bandwidth devices - val pbus = LazyModule(new TLXbar) // Globally-visible low-bandwidth devices - val tile_splitter = LazyModule(new TLSplitter) // Allows cycle-free connection to external networks - val int_xbar = LazyModule(new IntXbar) // Interrupt crossbar - - val mmio = TLOutputNode() // Exernal memory-mapped IO slaves - val mmioInt = IntInputNode() // Exernal devices' interrupts - val l2in = TLInputNode() // External masters talking to the frontside of the shared cache - val l2out = TLOutputNode() // External slaves hanging off the backside of the shared cache - - int_xbar.intnode := mmioInt - - // Allows a variable number of inputs from outside to the Xbar - private val l2in_buffer = LazyModule(new TLBuffer) - private val l2in_fifo = LazyModule(new TLFIFOFixer) - sbus.node :=* l2in_fifo.node - sbus.node :=* tile_splitter.node - l2in_fifo.node :=* l2in_buffer.node - l2in_buffer.node :=* l2in - - private val l2out_buffer = LazyModule(new TLBuffer(BufferParams.flow, BufferParams.none)) - l2out :*= l2out_buffer.node - l2out_buffer.node :*= sbus.node - - pbus.node := - TLBuffer()( - TLAtomicAutomata(arithmetic = true)( // disable once TLB uses TL2 metadata - TLWidthWidget(sbusBeatBytes)( - sbus.node))) - - mmio := - TLWidthWidget(sbusBeatBytes)( - sbus.node) - - val root = new Device { - def describe(resources: ResourceBindings): Description = { - val width = resources("width").map(_.value) - Description("/", Map( - "#address-cells" -> width, - "#size-cells" -> width, - "model" -> Seq(ResourceString(p(DTSModel))), - "compatible" -> (p(DTSModel) +: p(DTSCompat)).map(s => ResourceString(s + "-dev")))) - } - } - - val soc = new Device { - def describe(resources: ResourceBindings): Description = { - val width = resources("width").map(_.value) - Description("soc", Map( - "#address-cells" -> width, - "#size-cells" -> width, - "compatible" -> ((p(DTSModel) +: p(DTSCompat)).map(s => ResourceString(s + "-soc")) :+ ResourceString("simple-bus")), - "ranges" -> Nil)) - } - } - - val cpus = new Device { - def describe(resources: ResourceBindings): Description = { - Description("cpus", Map( - "#address-cells" -> Seq(ResourceInt(1)), - "#size-cells" -> Seq(ResourceInt(0)), - "timebase-frequency" -> Seq(ResourceInt(p(DTSTimebase))))) - } - } - - // Make topManagers an Option[] so as to avoid LM name reflection evaluating it... - lazy val topManagers = Some(ManagerUnification(tile_splitter.node.edgesIn.headOption.map(_.manager.managers).getOrElse(Nil))) - ResourceBinding { - val managers = topManagers.get - val max = managers.flatMap(_.address).map(_.max).max - val width = ResourceInt((log2Ceil(max)+31) / 32) - Resource(root, "width").bind(width) - Resource(soc, "width").bind(width) - Resource(cpus, "null").bind(ResourceString("")) - - managers.foreach { case manager => - val value = manager.toResource - manager.resources.foreach { case resource => - resource.bind(value) - } - } - } -} - -trait CoreplexNetworkBundle extends HasCoreplexParameters { - val outer: CoreplexNetwork - - val mmio = outer.mmio.bundleOut - val interrupts = outer.mmioInt.bundleIn - val l2in = outer.l2in.bundleIn - val l2out = outer.l2out.bundleOut -} - -trait CoreplexNetworkModule extends HasCoreplexParameters { - val outer: CoreplexNetwork - val io: CoreplexNetworkBundle - - println("Generated Address Map") - private val aw = (outer.p(PAddrBits)-1)/4 + 1 - private val fmt = s"\t%${aw}x - %${aw}x %c%c%c%c %s" - - private def collect(path: List[String], value: ResourceValue): List[(String, ResourceAddress)] = { - value match { - case r: ResourceAddress => List((path(1), r)) - case b: ResourceMapping => List((path(1), ResourceAddress(b.address, b.permissions))) - case ResourceMap(value, _) => value.toList.flatMap { case (key, seq) => seq.flatMap(r => collect(key :: path, r)) } - case _ => Nil - } - } - private val ranges = collect(Nil, outer.bindingTree).groupBy(_._2).toList.flatMap { case (key, seq) => - AddressRange.fromSets(key.address).map { r => (r, key.permissions, seq.map(_._1)) } - }.sortBy(_._1) - private val json = ranges.map { case (range, ResourcePermissions(r, w, x, c), names) => - println(fmt.format( - range.base, - range.base+range.size, - if (r) 'R' else ' ', - if (w) 'W' else ' ', - if (x) 'X' else ' ', - if (c) 'C' else ' ', - names.mkString(", "))) - s"""{"base":[${range.base}],"size":[${range.size}],"r":[$r],"w":[$w],"x":[$x],"c":[$c],"names":[${names.map('"'+_+'"').mkString(",")}]}""" - } - println("") - ElaborationArtefacts.add("memmap.json", s"""{"mapping":[${json.mkString(",")}]}""") - - // Confirm that all of memory was described by DTS - private val dtsRanges = AddressRange.unify(ranges.map(_._1)) - private val allRanges = AddressRange.unify(outer.topManagers.get.flatMap { m => AddressRange.fromSets(m.address) }) - - if (dtsRanges != allRanges) { - println("Address map described by DTS differs from physical implementation:") - AddressRange.subtract(allRanges, dtsRanges).foreach { case r => - println(s"\texists, but undescribed by DTS: ${r}") - } - AddressRange.subtract(dtsRanges, allRanges).foreach { case r => - println(s"\tdoes not exist, but described by DTS: ${r}") - } - println("") - } -} - -///// - -trait BankedL2CoherenceManagers extends CoreplexNetwork { - val module: BankedL2CoherenceManagersModule - - require (isPow2(l2Config.nMemoryChannels) || l2Config.nMemoryChannels == 0) - require (isPow2(l2Config.nBanksPerChannel)) - require (isPow2(sbusBlockBytes)) - - private val (in, out) = l2Config.coherenceManager(p, this) - private val mask = ~BigInt((l2Config.nBanks-1) * sbusBlockBytes) - val mem = Seq.tabulate(l2Config.nMemoryChannels) { channel => - val node = TLOutputNode() - for (bank <- 0 until l2Config.nBanksPerChannel) { - val offset = (bank * l2Config.nMemoryChannels) + channel - in := sbus.node - node := TLFilter(AddressSet(offset * sbusBlockBytes, mask))(out) - } - node - } -} - -trait BankedL2CoherenceManagersBundle extends CoreplexNetworkBundle { - val outer: BankedL2CoherenceManagers - val mem = HeterogeneousBag(outer.mem.map(_.bundleOut)) -} - -trait BankedL2CoherenceManagersModule extends CoreplexNetworkModule { - val outer: BankedL2CoherenceManagers - val io: BankedL2CoherenceManagersBundle -} diff --git a/src/main/scala/coreplex/ISPPort.scala b/src/main/scala/coreplex/ISPPort.scala deleted file mode 100644 index 70017536..00000000 --- a/src/main/scala/coreplex/ISPPort.scala +++ /dev/null @@ -1,40 +0,0 @@ -// See LICENSE.SiFive for license details. - -package freechips.rocketchip.coreplex - -import Chisel._ -import freechips.rocketchip.diplomacy.LazyModule -import freechips.rocketchip.tilelink._ - -trait HasISPPort extends CoreplexNetwork { - val module: HasISPPortModule - - // TODO: use ChipLink instead of AsyncTileLink - val isp_in = TLAsyncInputNode() - val isp_out = TLAsyncOutputNode() - - private val out_xbar = LazyModule(new TLXbar) - private val out_nums = LazyModule(new TLNodeNumberer) - private val out_async = LazyModule(new TLAsyncCrossingSource) - out_xbar.node :=* tile_splitter.node - out_nums.node :*= out_xbar.node - out_async.node :*= out_nums.node - isp_out :*= out_async.node - - private val in_async = LazyModule(new TLAsyncCrossingSink) - in_async.node :=* isp_in - sbus.node :=* in_async.node -} - -trait HasISPPortBundle extends CoreplexNetworkBundle { - val outer: HasISPPort - - // TODO: move to IO(...) in Module? - val isp_in = outer.isp_in.bundleIn - val isp_out = outer.isp_out.bundleOut -} - -trait HasISPPortModule extends CoreplexNetworkModule { - val outer: HasISPPort - val io: HasISPPortBundle -} diff --git a/src/main/scala/coreplex/InterruptBus.scala b/src/main/scala/coreplex/InterruptBus.scala new file mode 100644 index 00000000..d99b1734 --- /dev/null +++ b/src/main/scala/coreplex/InterruptBus.scala @@ -0,0 +1,85 @@ +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.coreplex + +import Chisel._ +import freechips.rocketchip.config.{Field, Parameters} +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.tilelink._ + +/** Collects interrupts from internal and external devices and feeds them into the PLIC */ +class InterruptBusWrapper(implicit p: Parameters) { + + val int_bus = LazyModule(new IntXbar) // Interrupt crossbar + + private def synchronize(sync: Int): IntInwardNode = { + val asyncXing = LazyModule(new IntXing(sync)) + int_bus.intnode := asyncXing.intnode + asyncXing.intnode + } + + def fromAsync: IntInwardNode = synchronize(3) + def fromRational: IntInwardNode = synchronize(1) + def fromSync: IntInwardNode = int_bus.intnode + def toPLIC: IntOutwardNode = int_bus.intnode +} + +trait HasInterruptBus { + implicit val p: Parameters + val ibus = new InterruptBusWrapper +} + +/** Specifies the number of external interrupts */ +case object NExtTopInterrupts extends Field[Int] + +/** This trait adds externally driven interrupts to the system. + * However, it should not be used directly; instead one of the below + * synchronization wiring child traits should be used. + */ +abstract trait HasExtInterrupts extends HasInterruptBus { + private val device = new Device with DeviceInterrupts { + def describe(resources: ResourceBindings): Description = { + Description("soc/external-interrupts", describeInterrupts(resources)) + } + } + + val nExtInterrupts = p(NExtTopInterrupts) + val extInterrupts = IntInternalInputNode(IntSourcePortSimple(num = nExtInterrupts, resources = device.int)) +} + +/** This trait should be used if the External Interrupts have NOT + * already been synchronized to the Periphery (PLIC) Clock. + */ +trait HasAsyncExtInterrupts extends HasExtInterrupts { + if (nExtInterrupts > 0) { + ibus.fromAsync := extInterrupts + } +} + +/** This trait can be used if the External Interrupts have already been synchronized + * to the Periphery (PLIC) Clock. + */ +trait HasSyncExtInterrupts extends HasExtInterrupts { + if (nExtInterrupts > 0) { + ibus.fromSync := extInterrupts + } +} + +/** Common io name and methods for propagating or tying off the port bundle */ +trait HasExtInterruptsBundle { + val interrupts: UInt + + def tieOffInterrupts(dummy: Int = 1) { + interrupts := UInt(0) + } +} + +/** This trait performs the translation from a UInt IO into Diplomatic Interrupts. + * The wiring must be done in the concrete LazyModuleImp. + */ +trait HasExtInterruptsModuleImp extends LazyMultiIOModuleImp with HasExtInterruptsBundle { + val outer: HasExtInterrupts + val interrupts = IO(UInt(INPUT, width = outer.nExtInterrupts)) + + outer.extInterrupts.bundleIn.flatten.zipWithIndex.foreach { case(o, i) => o := interrupts(i) } +} diff --git a/src/main/scala/coreplex/MemoryBus.scala b/src/main/scala/coreplex/MemoryBus.scala new file mode 100644 index 00000000..db022982 --- /dev/null +++ b/src/main/scala/coreplex/MemoryBus.scala @@ -0,0 +1,75 @@ +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.coreplex + +import Chisel._ +import freechips.rocketchip.config._ +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.tilelink._ +import freechips.rocketchip.util._ + +// TODO: applies to all caches, for now +case object CacheBlockBytes extends Field[Int] + +/** L2 Broadcast Hub configuration */ +case class BroadcastParams( + nTrackers: Int = 4, + bufferless: Boolean = false) +case object BroadcastParams extends Field[BroadcastParams] + +/** L2 memory subsystem configuration */ +case class BankedL2Params( + nMemoryChannels: Int = 1, + nBanksPerChannel: Int = 1, + coherenceManager: (Parameters, HasMemoryBus) => (TLInwardNode, TLOutwardNode) = { case (q, _) => + implicit val p = q + val MemoryBusParams(_, blockBytes, _, _) = p(MemoryBusParams) + val BroadcastParams(nTrackers, bufferless) = p(BroadcastParams) + val bh = LazyModule(new TLBroadcast(blockBytes, nTrackers, bufferless)) + (bh.node, bh.node) + }) { + val nBanks = nMemoryChannels*nBanksPerChannel +} +case object BankedL2Params extends Field[BankedL2Params] + +/** Parameterization of the memory-side bus created for each memory channel */ +case class MemoryBusParams( + beatBytes: Int, + blockBytes: Int, + masterBuffering: BufferParams = BufferParams.none, + slaveBuffering: BufferParams = BufferParams.none +) extends TLBusParams + +case object MemoryBusParams extends Field[MemoryBusParams] + +/** Wrapper for creating TL nodes from a bus connected to the back of each mem channel */ +class MemoryBus(params: MemoryBusParams)(implicit p: Parameters) extends TLBusWrapper(params)(p) { + def fromCoherenceManager: TLInwardNode = inwardBufNode + def toDRAMController: TLOutwardNode = outwardBufNode + def toVariableWidthSlave: TLOutwardNode = outwardFragNode +} + +trait HasMemoryBus extends HasSystemBus with HasPeripheryBus with HasInterruptBus { + private val mbusParams = p(MemoryBusParams) + private val MemoryBusParams(beatBytes, blockBytes, _, _) = mbusParams + private val l2Params = p(BankedL2Params) + val BankedL2Params(nMemoryChannels, nBanksPerChannel, coherenceManager) = l2Params + val nBanks = l2Params.nBanks + val cacheBlockBytes = blockBytes + + require (isPow2(nMemoryChannels) || nMemoryChannels == 0) + require (isPow2(nBanksPerChannel)) + require (isPow2(blockBytes)) + + private val (in, out) = coherenceManager(p, this) + private val mask = ~BigInt((nBanks-1) * blockBytes) + val memBuses = Seq.tabulate(nMemoryChannels) { channel => + val mbus = new MemoryBus(mbusParams) + for (bank <- 0 until nBanksPerChannel) { + val offset = (bank * nMemoryChannels) + channel + in := sbus.toMemoryBus + mbus.fromCoherenceManager := TLFilter(AddressSet(offset * blockBytes, mask))(out) + } + mbus + } +} diff --git a/src/main/scala/coreplex/PeripheryBus.scala b/src/main/scala/coreplex/PeripheryBus.scala new file mode 100644 index 00000000..20680a7c --- /dev/null +++ b/src/main/scala/coreplex/PeripheryBus.scala @@ -0,0 +1,48 @@ +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.coreplex + +import Chisel._ +import freechips.rocketchip.config.{Field, Parameters} +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.tilelink._ + +case class PeripheryBusParams( + beatBytes: Int, + blockBytes: Int, + masterBuffering: BufferParams = BufferParams.default, + slaveBuffering: BufferParams = BufferParams.none, + arithmetic: Boolean = true +) extends TLBusParams { +} + +case object PeripheryBusParams extends Field[PeripheryBusParams] + +class PeripheryBus(params: PeripheryBusParams)(implicit p: Parameters) extends TLBusWrapper(params) { + def toFixedWidthSingleBeatSlave(widthBytes: Int) = { + TLFragmenter(widthBytes, params.blockBytes)(outwardWWNode) + } + + def toLargeBurstSlave(maxXferBytes: Int) = { + TLFragmenter(params.beatBytes, maxXferBytes)(outwardBufNode) + } + + val fromSystemBus: TLInwardNode = { + val atomics = LazyModule(new TLAtomicAutomata(arithmetic = params.arithmetic)) + inwardBufNode := atomics.node + atomics.node + } +} + +/** Provides buses that serve as attachment points, + * for use in traits that connect individual devices or external ports. + */ +trait HasPeripheryBus extends HasSystemBus { + private val pbusParams = p(PeripheryBusParams) + val pbusBeatBytes = pbusParams.beatBytes + + val pbus = new PeripheryBus(pbusParams) + + // The peripheryBus hangs off of systemBus; here we convert TL-UH -> TL-UL + pbus.fromSystemBus := sbus.toPeripheryBus +} diff --git a/src/main/scala/coreplex/Ports.scala b/src/main/scala/coreplex/Ports.scala new file mode 100644 index 00000000..9c0e1388 --- /dev/null +++ b/src/main/scala/coreplex/Ports.scala @@ -0,0 +1,261 @@ +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.coreplex + +import Chisel._ +import freechips.rocketchip.config.{Field, Parameters} +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.tilelink._ +import freechips.rocketchip.amba.axi4._ +import freechips.rocketchip.util._ + +/** Specifies the size and width of external memory ports */ +case class MasterPortParams( + base: Long, + size: Long, + beatBytes: Int, + idBits: Int, + maxXferBytes: Int = 256, + executable: Boolean = true) +case object ExtMem extends Field[MasterPortParams] +case object ExtBus extends Field[MasterPortParams] + +/** Specifies the width of external slave ports */ +case class SlavePortParams(beatBytes: Int, idBits: Int, sourceBits: Int) +case object ExtIn extends Field[SlavePortParams] + +///// The following traits add ports to the sytem, in some cases converting to different interconnect standards + +/** Adds a port to the system intended to master an AXI4 DRAM controller. */ +trait HasMasterAXI4MemPort extends HasMemoryBus { + val module: HasMasterAXI4MemPortModuleImp + + private val params = p(ExtMem) + private val device = new MemoryDevice + + val mem_axi4 = AXI4BlindOutputNode(Seq.tabulate(nMemoryChannels) { channel => + val base = AddressSet(params.base, params.size-1) + val filter = AddressSet(channel * cacheBlockBytes, ~((nMemoryChannels-1) * cacheBlockBytes)) + + AXI4SlavePortParameters( + slaves = Seq(AXI4SlaveParameters( + address = base.intersect(filter).toList, + resources = device.reg, + regionType = RegionType.UNCACHED, // cacheable + executable = true, + supportsWrite = TransferSizes(1, cacheBlockBytes), + supportsRead = TransferSizes(1, cacheBlockBytes), + interleavedId = Some(0))), // slave does not interleave read responses + beatBytes = params.beatBytes) + }) + + val converter = LazyModule(new TLToAXI4(params.beatBytes)) + val trim = LazyModule(new AXI4IdIndexer(params.idBits)) + val yank = LazyModule(new AXI4UserYanker) + val buffer = LazyModule(new AXI4Buffer) + + memBuses.map(_.toDRAMController).foreach { case node => + converter.node := node + trim.node := converter.node + yank.node := trim.node + buffer.node := yank.node + mem_axi4 := buffer.node + } +} + +/** Common io name and methods for propagating or tying off the port bundle */ +trait HasMasterAXI4MemPortBundle { + implicit val p: Parameters + val mem_axi4: HeterogeneousBag[AXI4Bundle] + val nMemoryChannels: Int + def connectSimAXIMem(dummy: Int = 1) = { + if (nMemoryChannels > 0) Module(LazyModule(new SimAXIMem(nMemoryChannels)).module).io.axi4 <> mem_axi4 + } +} + +/** Actually generates the corresponding IO in the concrete Module */ +trait HasMasterAXI4MemPortModuleImp extends LazyMultiIOModuleImp with HasMasterAXI4MemPortBundle { + val outer: HasMasterAXI4MemPort + val mem_axi4 = IO(outer.mem_axi4.bundleOut) + val nMemoryChannels = outer.nMemoryChannels +} + +/** Adds a AXI4 port to the system intended to master an MMIO device bus */ +trait HasMasterAXI4MMIOPort extends HasSystemBus { + private val params = p(ExtBus) + private val device = new SimpleBus("mmio", Nil) + val mmio_axi4 = AXI4BlindOutputNode(Seq(AXI4SlavePortParameters( + slaves = Seq(AXI4SlaveParameters( + address = List(AddressSet(BigInt(params.base), params.size-1)), + resources = device.ranges, + executable = params.executable, + supportsWrite = TransferSizes(1, params.maxXferBytes), + supportsRead = TransferSizes(1, params.maxXferBytes))), + beatBytes = params.beatBytes))) + + mmio_axi4 := + AXI4Buffer()( + AXI4UserYanker()( + AXI4Deinterleaver(sbus.blockBytes)( + AXI4IdIndexer(params.idBits)( + TLToAXI4(params.beatBytes)( + sbus.toFixedWidthPorts))))) +} + +/** Common io name and methods for propagating or tying off the port bundle */ +trait HasMasterAXI4MMIOPortBundle { + implicit val p: Parameters + val mmio_axi4: HeterogeneousBag[AXI4Bundle] + def connectSimAXIMMIO(dummy: Int = 1) { + Module(LazyModule(new SimAXIMem(1, 4096)).module).io.axi4 <> mmio_axi4 + } +} + +/** Actually generates the corresponding IO in the concrete Module */ +trait HasMasterAXI4MMIOPortModuleImp extends LazyMultiIOModuleImp with HasMasterAXI4MMIOPortBundle { + val outer: HasMasterAXI4MMIOPort + val mmio_axi4 = IO(outer.mmio_axi4.bundleOut) +} + +/** Adds an AXI4 port to the system intended to be a slave on an MMIO device bus */ +trait HasSlaveAXI4Port extends HasSystemBus { + private val params = p(ExtIn) + val l2FrontendAXI4Node = AXI4BlindInputNode(Seq(AXI4MasterPortParameters( + masters = Seq(AXI4MasterParameters( + name = "AXI4 periphery", + id = IdRange(0, 1 << params.idBits)))))) + + private val fifoBits = 1 + sbus.fromSyncPorts() := + TLWidthWidget(params.beatBytes)( + AXI4ToTL()( + AXI4UserYanker(Some(1 << (params.sourceBits - fifoBits - 1)))( + AXI4Fragmenter()( + AXI4IdIndexer(fifoBits)( + l2FrontendAXI4Node))))) +} + +/** Common io name and methods for propagating or tying off the port bundle */ +trait HasSlaveAXI4PortBundle { + implicit val p: Parameters + val l2_frontend_bus_axi4: HeterogeneousBag[AXI4Bundle] + def tieOffAXI4SlavePort(dummy: Int = 1) { + l2_frontend_bus_axi4.foreach { l2_axi4 => + l2_axi4.ar.valid := Bool(false) + l2_axi4.aw.valid := Bool(false) + l2_axi4.w .valid := Bool(false) + l2_axi4.r .ready := Bool(true) + l2_axi4.b .ready := Bool(true) + } + } +} + +/** Actually generates the corresponding IO in the concrete Module */ +trait HasSlaveAXI4PortModuleImp extends LazyMultiIOModuleImp with HasSlaveAXI4PortBundle { + val outer: HasSlaveAXI4Port + val l2_frontend_bus_axi4 = IO(outer.l2FrontendAXI4Node.bundleIn) +} + +/** Adds a TileLink port to the system intended to master an MMIO device bus */ +trait HasMasterTLMMIOPort extends HasSystemBus { + private val params = p(ExtBus) + private val device = new SimpleBus("mmio", Nil) + val mmio_tl = TLBlindOutputNode(Seq(TLManagerPortParameters( + managers = Seq(TLManagerParameters( + address = List(AddressSet(BigInt(params.base), params.size-1)), + resources = device.ranges, + executable = params.executable, + supportsGet = TransferSizes(1, sbus.blockBytes), + supportsPutFull = TransferSizes(1, sbus.blockBytes), + supportsPutPartial = TransferSizes(1, sbus.blockBytes))), + beatBytes = params.beatBytes))) + + mmio_tl := + TLBuffer()( + TLSourceShrinker(1 << params.idBits)( + sbus.toFixedWidthPorts)) +} + +/** Common io name and methods for propagating or tying off the port bundle */ +trait HasMasterTLMMIOPortBundle { + implicit val p: Parameters + val mmio_tl: HeterogeneousBag[TLBundle] + def tieOffTLMMIO(dummy: Int = 1) { + mmio_tl.foreach { tl => + tl.a.ready := Bool(true) + tl.b.valid := Bool(false) + tl.c.ready := Bool(true) + tl.d.valid := Bool(false) + tl.e.ready := Bool(true) + } + } +} + +/** Actually generates the corresponding IO in the concrete Module */ +trait HasMasterTLMMIOPortModuleImp extends LazyMultiIOModuleImp with HasMasterTLMMIOPortBundle { + val outer: HasMasterTLMMIOPort + val mmio_tl = IO(outer.mmio_tl.bundleOut) +} + +/** Adds an TL port to the system intended to be a slave on an MMIO device bus. + * NOTE: this port is NOT allowed to issue Acquires. + */ +trait HasSlaveTLPort extends HasSystemBus { + private val params = p(ExtIn) + val l2FrontendTLNode = TLBlindInputNode(Seq(TLClientPortParameters( + clients = Seq(TLClientParameters( + name = "Front Port (TL)", + sourceId = IdRange(0, 1 << params.idBits)))))) + + sbus.fromSyncPorts() := + TLSourceShrinker(1 << params.sourceBits)( + TLWidthWidget(params.beatBytes)( + l2FrontendTLNode)) +} + +/** Common io name and methods for propagating or tying off the port bundle */ +trait HasSlaveTLPortBundle { + implicit val p: Parameters + val l2_frontend_bus_tl: HeterogeneousBag[TLBundle] + def tieOffSlaveTLPort(dummy: Int = 1) { + l2_frontend_bus_tl.foreach { tl => + tl.a.valid := Bool(false) + tl.b.ready := Bool(true) + tl.c.valid := Bool(false) + tl.d.ready := Bool(true) + tl.e.valid := Bool(false) + } + } +} + +/** Actually generates the corresponding IO in the concrete Module */ +trait HasSlaveTLPortModuleImp extends LazyMultiIOModuleImp with HasSlaveTLPortBundle { + val outer: HasSlaveTLPort + val l2_frontend_bus_tl = IO(outer.l2FrontendTLNode.bundleIn) +} + +/** Memory with AXI port for use in elaboratable test harnesses. */ +class SimAXIMem(channels: Int, forceSize: BigInt = 0)(implicit p: Parameters) extends LazyModule { + val config = p(ExtMem) + val totalSize = if (forceSize > 0) forceSize else BigInt(config.size) + val size = totalSize / channels + require(totalSize % channels == 0) + + val node = AXI4BlindInputNode(Seq.fill(channels) { + AXI4MasterPortParameters(Seq(AXI4MasterParameters( + name = "dut", + id = IdRange(0, 1 << config.idBits) + ))) + }) + + for (i <- 0 until channels) { + val sram = LazyModule(new AXI4RAM(AddressSet(0, size-1), beatBytes = config.beatBytes)) + sram.node := AXI4Buffer()(AXI4Fragmenter()(node)) + } + + lazy val module = new LazyModuleImp(this) { + val io = new Bundle { + val axi4 = node.bundleIn + } + } +} diff --git a/src/main/scala/coreplex/RISCVPlatform.scala b/src/main/scala/coreplex/RISCVPlatform.scala deleted file mode 100644 index 7eba3ef7..00000000 --- a/src/main/scala/coreplex/RISCVPlatform.scala +++ /dev/null @@ -1,65 +0,0 @@ -// See LICENSE.SiFive for license details. - -package freechips.rocketchip.coreplex - -import Chisel._ - -import freechips.rocketchip.config.Field -import freechips.rocketchip.devices.debug._ -import freechips.rocketchip.devices.tilelink._ -import freechips.rocketchip.diplomacy._ -import freechips.rocketchip.tile._ -import freechips.rocketchip.tilelink._ -import freechips.rocketchip.util._ - -case object PLICKey extends Field[PLICParams] -case object ClintKey extends Field[ClintParams] - -trait CoreplexRISCVPlatform extends CoreplexNetwork { - val module: CoreplexRISCVPlatformModule - - val debug = LazyModule(new TLDebugModule()) - debug.node := TLFragmenter(pbusBeatBytes, pbusBlockBytes)(pbus.node) - - val plic = LazyModule(new TLPLIC(p(PLICKey))) - plic.node := TLFragmenter(pbusBeatBytes, pbusBlockBytes)(pbus.node) - plic.intnode := int_xbar.intnode - - val clint = LazyModule(new CoreplexLocalInterrupter(p(ClintKey))) - clint.node := TLFragmenter(pbusBeatBytes, pbusBlockBytes)(pbus.node) - - lazy val dts = DTS(bindingTree) - lazy val dtb = DTB(dts) - lazy val json = JSON(bindingTree) -} - -trait CoreplexRISCVPlatformBundle extends CoreplexNetworkBundle { - val outer: CoreplexRISCVPlatform - - val debug = new ClockedDMIIO().flip - val rtcToggle = Bool(INPUT) - val resetVector = UInt(INPUT, p(ResetVectorBits)) - val ndreset = Bool(OUTPUT) - val dmactive = Bool(OUTPUT) -} - -trait CoreplexRISCVPlatformModule extends CoreplexNetworkModule { - val outer: CoreplexRISCVPlatform - val io: CoreplexRISCVPlatformBundle - - outer.debug.module.io.dmi <> io.debug - // TODO in inheriting traits: Set this to something meaningful, e.g. "component is in reset or powered down" - val nDebugComponents = outer.debug.intnode.bundleOut.size - outer.debug.module.io.ctrl.debugUnavail := Vec.fill(nDebugComponents){Bool(false)} - io.dmactive := outer.debug.module.io.ctrl.dmactive - io.ndreset := outer.debug.module.io.ctrl.ndreset - - // Synchronize the rtc into the coreplex - val rtcSync = ShiftRegister(io.rtcToggle, 3) - val rtcLast = Reg(init = Bool(false), next=rtcSync) - outer.clint.module.io.rtcTick := Reg(init = Bool(false), next=(rtcSync & (~rtcLast))) - - println(outer.dts) - ElaborationArtefacts.add("dts", outer.dts) - ElaborationArtefacts.add("json", outer.json) -} diff --git a/src/main/scala/coreplex/RTC.scala b/src/main/scala/coreplex/RTC.scala new file mode 100644 index 00000000..d1687cf9 --- /dev/null +++ b/src/main/scala/coreplex/RTC.scala @@ -0,0 +1,24 @@ +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.coreplex + +import Chisel._ +import freechips.rocketchip.config.Field +import freechips.rocketchip.diplomacy.LazyMultiIOModuleImp +import freechips.rocketchip.devices.tilelink.HasPeripheryClint + +/** Real-time clock is based on RTCPeriod relative to system clock. + */ +case object RTCPeriod extends Field[Option[Int]] + +trait HasRTCModuleImp extends LazyMultiIOModuleImp { + val outer: HasPeripheryClint + private val internalPeriod: Option[Int] = outer.p(RTCPeriod) + require(internalPeriod.isDefined, "RTCPeriod is not defined") + + // Use the static period to toggle the RTC + val (rtc_counter, _) = Counter(true.B, internalPeriod.get) + val tick = rtc_counter(log2Up(internalPeriod.get)-1) + + outer.clint.module.io.rtcTick := tick +} diff --git a/src/main/scala/coreplex/ResetVector.scala b/src/main/scala/coreplex/ResetVector.scala new file mode 100644 index 00000000..1c986d60 --- /dev/null +++ b/src/main/scala/coreplex/ResetVector.scala @@ -0,0 +1,14 @@ +// See LICENSE for license details. + +package freechips.rocketchip.coreplex + +import Chisel._ +import freechips.rocketchip.config.Parameters +import freechips.rocketchip.tile.ResetVectorBits + +/** A single place for all tiles to find out the reset vector */ +trait HasResetVectorWire { + implicit val p: Parameters + val resetVectorBits = p(ResetVectorBits) + val global_reset_vector = Wire(UInt(width = resetVectorBits)) +} diff --git a/src/main/scala/coreplex/RocketCoreplex.scala b/src/main/scala/coreplex/RocketCoreplex.scala new file mode 100644 index 00000000..80af5a39 --- /dev/null +++ b/src/main/scala/coreplex/RocketCoreplex.scala @@ -0,0 +1,130 @@ +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.coreplex + +import Chisel._ +import freechips.rocketchip.config.{Field, Parameters} +import freechips.rocketchip.devices.tilelink._ +import freechips.rocketchip.devices.debug.{HasPeripheryDebug, HasPeripheryDebugModuleImp} +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.tile._ +import freechips.rocketchip.tilelink._ +import freechips.rocketchip.util._ + +case object RocketTilesKey extends Field[Seq[RocketTileParams]] +case object RocketCrossing extends Field[CoreplexClockCrossing] + +trait HasRocketTiles extends HasSystemBus + with HasPeripheryBus + with HasPeripheryPLIC + with HasPeripheryClint + with HasPeripheryDebug { + val module: HasRocketTilesModuleImp + + private val crossing = p(RocketCrossing) + private val tileParams = p(RocketTilesKey) + val nRocketTiles = tileParams.size + + // Handle interrupts to be routed directly into each tile + // TODO: figure out how to merge the localIntNodes and coreIntXbar below + val localIntCounts = tileParams.map(_.core.nLocalInterrupts) + val localIntNodes = tileParams map { t => + (t.core.nLocalInterrupts > 0).option(LazyModule(new IntXbar).intnode) + } + + // Make a wrapper for each tile that will wire it to coreplex devices and crossbars, + // according to the specified type of clock crossing. + val wiringTuple = localIntNodes.zip(tileParams).zipWithIndex + val wrappers: Seq[RocketTileWrapper] = wiringTuple.map { case ((lip, c), i) => + val pWithExtra = p.alterPartial { + case TileKey => c + case BuildRoCC => c.rocc + case SharedMemoryTLEdge => sharedMemoryTLEdge + } + + val wrapper = crossing match { + case SynchronousCrossing(params) => { + val wrapper = LazyModule(new SyncRocketTile(c, i)(pWithExtra)) + sbus.fromSyncTiles(params) :=* wrapper.masterNode + wrapper.slaveNode :*= pbus.bufferToSlaves + wrapper + } + case AsynchronousCrossing(depth, sync) => { + val wrapper = LazyModule(new AsyncRocketTile(c, i)(pWithExtra)) + sbus.fromAsyncTiles(depth, sync) :=* wrapper.masterNode + wrapper.slaveNode :*= pbus.toAsyncSlaves(sync) + wrapper + } + case RationalCrossing(direction) => { + val wrapper = LazyModule(new RationalRocketTile(c, i)(pWithExtra)) + val sink = LazyModule(new TLRationalCrossingSink(direction)) + val source = LazyModule(new TLRationalCrossingSource) + sbus.fromRationalTiles(direction) :=* wrapper.masterNode + wrapper.slaveNode :*= pbus.toRationalSlaves + wrapper + } + } + + // Local Interrupts must be synchronized to the core clock + // before being passed into this module. + // This allows faster latency for interrupts which are already synchronized. + // The CLINT and PLIC outputs interrupts that are synchronous to the periphery clock, + // so may or may not need to be synchronized depending on the Tile's crossing type. + // Debug interrupt is definitely asynchronous in all cases. + val asyncIntXbar = LazyModule(new IntXbar) + asyncIntXbar.intnode := debug.intnode // debug + wrapper.asyncIntNode := asyncIntXbar.intnode + + val periphIntXbar = LazyModule(new IntXbar) + periphIntXbar.intnode := clint.intnode // msip+mtip + periphIntXbar.intnode := plic.intnode // meip + if (c.core.useVM) periphIntXbar.intnode := plic.intnode // seip + wrapper.periphIntNode := periphIntXbar.intnode + + val coreIntXbar = LazyModule(new IntXbar) + lip.foreach { coreIntXbar.intnode := _ } // lip + wrapper.coreIntNode := coreIntXbar.intnode + + wrapper + } +} + +class ClockedRocketTileInputs(implicit val p: Parameters) extends ParameterizedBundle + with HasExternallyDrivenTileConstants + with Clocked + +trait HasRocketTilesBundle { + val rocket_tile_inputs: Vec[ClockedRocketTileInputs] +} + +trait HasRocketTilesModuleImp extends LazyMultiIOModuleImp + with HasRocketTilesBundle + with HasResetVectorWire + with HasPeripheryDebugModuleImp { + val outer: HasRocketTiles + val rocket_tile_inputs = Wire(Vec(outer.nRocketTiles, new ClockedRocketTileInputs)) + + // Unconditionally wire up the non-diplomatic tile inputs + outer.wrappers.map(_.module).zip(rocket_tile_inputs).foreach { case(tile, wire) => + tile.clock := wire.clock + tile.reset := wire.reset + tile.io.hartid := wire.hartid + tile.io.resetVector := wire.resetVector + } + + // Default values for tile inputs; may be overriden in other traits + rocket_tile_inputs.zipWithIndex.foreach { case(wire, i) => + wire.clock := clock + wire.reset := reset + wire.hartid := UInt(i) + wire.resetVector := global_reset_vector + } +} + +class RocketCoreplex(implicit p: Parameters) extends BaseCoreplex + with HasRocketTiles { + override lazy val module = new RocketCoreplexModule(this) +} + +class RocketCoreplexModule[+L <: RocketCoreplex](_outer: L) extends BaseCoreplexModule(_outer) + with HasRocketTilesModuleImp diff --git a/src/main/scala/coreplex/RocketPlex.scala b/src/main/scala/coreplex/RocketPlex.scala deleted file mode 100644 index 8d6a1829..00000000 --- a/src/main/scala/coreplex/RocketPlex.scala +++ /dev/null @@ -1,21 +0,0 @@ -// See LICENSE.SiFive for license details. - -package freechips.rocketchip.coreplex - -import Chisel._ - -import freechips.rocketchip.config.Parameters - -class RocketPlex(implicit p: Parameters) extends BaseCoreplex - with CoreplexRISCVPlatform - with HasRocketTiles { - override lazy val module = new RocketPlexModule(this, () => new RocketPlexBundle(this)) -} - -class RocketPlexBundle[+L <: RocketPlex](_outer: L) extends BaseCoreplexBundle(_outer) - with CoreplexRISCVPlatformBundle - with HasRocketTilesBundle - -class RocketPlexModule[+L <: RocketPlex, +B <: RocketPlexBundle[L]](_outer: L, _io: () => B) extends BaseCoreplexModule(_outer, _io) - with CoreplexRISCVPlatformModule - with HasRocketTilesModule diff --git a/src/main/scala/coreplex/RocketTiles.scala b/src/main/scala/coreplex/RocketTiles.scala deleted file mode 100644 index ffe79ef2..00000000 --- a/src/main/scala/coreplex/RocketTiles.scala +++ /dev/null @@ -1,135 +0,0 @@ -// See LICENSE.SiFive for license details. - -package freechips.rocketchip.coreplex - -import Chisel._ -import freechips.rocketchip.config.Field -import freechips.rocketchip.diplomacy._ -import freechips.rocketchip.rocket._ -import freechips.rocketchip.tile._ -import freechips.rocketchip.tilelink._ -import freechips.rocketchip.util._ - -sealed trait CoreplexClockCrossing -case class SynchronousCrossing(params: BufferParams = BufferParams.default) extends CoreplexClockCrossing -case class RationalCrossing(direction: RationalDirection = FastToSlow) extends CoreplexClockCrossing -case class AsynchronousCrossing(depth: Int, sync: Int = 2) extends CoreplexClockCrossing - -case object RocketTilesKey extends Field[Seq[RocketTileParams]] -case object RocketCrossing extends Field[CoreplexClockCrossing] - -trait HasRocketTiles extends CoreplexRISCVPlatform { - val module: HasRocketTilesModule - - private val crossing = p(RocketCrossing) - val tileParams = p(RocketTilesKey) - - // Handle interrupts to be routed directly into each tile - val localIntNodes = tileParams map { t => - (t.core.nLocalInterrupts > 0).option(IntInputNode()) - } - - // Make a function for each tile that will wire it to coreplex devices and crossbars, - // according to the specified type of clock crossing. - val wiringTuple = localIntNodes.zip(tileParams).zipWithIndex - val rocketWires: Seq[HasRocketTilesBundle => Unit] = wiringTuple.map { case ((lip, c), i) => - val pWithExtra = p.alterPartial { - case TileKey => c - case BuildRoCC => c.rocc - case SharedMemoryTLEdge => tile_splitter.node.edgesIn(0) - } - - val asyncIntXbar = LazyModule(new IntXbar) - val periphIntXbar = LazyModule(new IntXbar) - val coreIntXbar = LazyModule(new IntXbar) - - // Local Interrupts must be synchronized to the core clock - // before being passed into this module. - // This allows faster latency for interrupts which are already synchronized. - // The CLINT and PLIC outputs interrupts that are synchronous to the periphery clock, - // so may or may not need to be synchronized depending on the Tile's - // synchronization type. - // Debug interrupt is definitely asynchronous in all cases. - - asyncIntXbar.intnode := debug.intnode // debug - periphIntXbar.intnode := clint.intnode // msip+mtip - periphIntXbar.intnode := plic.intnode // meip - if (c.core.useVM) periphIntXbar.intnode := plic.intnode // seip - lip.foreach { coreIntXbar.intnode := _ } // lip - - crossing match { - case SynchronousCrossing(params) => { - val wrapper = LazyModule(new SyncRocketTile(c, i)(pWithExtra)) - val buffer = LazyModule(new TLBuffer(params)) - val fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.allUncacheable)) - buffer.node :=* wrapper.masterNode - fixer.node :=* buffer.node - tile_splitter.node :=* fixer.node - wrapper.slaveNode :*= pbus.node - wrapper.asyncIntNode := asyncIntXbar.intnode - wrapper.periphIntNode := periphIntXbar.intnode - wrapper.coreIntNode := coreIntXbar.intnode - (io: HasRocketTilesBundle) => { - // leave clock as default (simpler for hierarchical PnR) - wrapper.module.io.hartid := UInt(i) - wrapper.module.io.resetVector := io.resetVector - } - } - case AsynchronousCrossing(depth, sync) => { - val wrapper = LazyModule(new AsyncRocketTile(c, i)(pWithExtra)) - val sink = LazyModule(new TLAsyncCrossingSink(depth, sync)) - val source = LazyModule(new TLAsyncCrossingSource(sync)) - val fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.allUncacheable)) - sink.node :=* wrapper.masterNode - fixer.node :=* sink.node - tile_splitter.node :=* fixer.node - wrapper.slaveNode :*= source.node - wrapper.asyncIntNode := asyncIntXbar.intnode - wrapper.periphIntNode := periphIntXbar.intnode - wrapper.coreIntNode := coreIntXbar.intnode - source.node :*= pbus.node - (io: HasRocketTilesBundle) => { - wrapper.module.clock := io.tcrs(i).clock - wrapper.module.reset := io.tcrs(i).reset - wrapper.module.io.hartid := UInt(i) - wrapper.module.io.resetVector := io.resetVector - } - } - case RationalCrossing(direction) => { - val wrapper = LazyModule(new RationalRocketTile(c, i)(pWithExtra)) - val sink = LazyModule(new TLRationalCrossingSink(direction)) - val source = LazyModule(new TLRationalCrossingSource) - val fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.allUncacheable)) - sink.node :=* wrapper.masterNode - fixer.node :=* sink.node - tile_splitter.node :=* fixer.node - wrapper.slaveNode :*= source.node - wrapper.asyncIntNode := asyncIntXbar.intnode - wrapper.periphIntNode := periphIntXbar.intnode - wrapper.coreIntNode := coreIntXbar.intnode - source.node :*= pbus.node - (io: HasRocketTilesBundle) => { - wrapper.module.clock := io.tcrs(i).clock - wrapper.module.reset := io.tcrs(i).reset - wrapper.module.io.hartid := UInt(i) - wrapper.module.io.resetVector := io.resetVector - } - } - } - } -} - -trait HasRocketTilesBundle extends CoreplexRISCVPlatformBundle { - val outer: HasRocketTiles - val local_interrupts = HeterogeneousBag(outer.localIntNodes.flatten.map(_.bundleIn)) - val tcrs = Vec(p(RocketTilesKey).size, new Bundle { - val clock = Clock(INPUT) - val reset = Bool(INPUT) - }) -} - -trait HasRocketTilesModule extends CoreplexRISCVPlatformModule { - val outer: HasRocketTiles - val io: HasRocketTilesBundle - outer.rocketWires.foreach { _(io) } -} diff --git a/src/main/scala/coreplex/SystemBus.scala b/src/main/scala/coreplex/SystemBus.scala new file mode 100644 index 00000000..954d6200 --- /dev/null +++ b/src/main/scala/coreplex/SystemBus.scala @@ -0,0 +1,97 @@ +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.coreplex + +import Chisel._ +import freechips.rocketchip.config.{Field, Parameters} +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.tilelink._ +import freechips.rocketchip.util._ + +case class SystemBusParams( + beatBytes: Int, + blockBytes: Int, + masterBuffering: BufferParams = BufferParams.default, + slaveBuffering: BufferParams = BufferParams.flow // TODO should be BufferParams.none on BCE +) extends TLBusParams + +case object SystemBusParams extends Field[SystemBusParams] + +class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWrapper(params) { + private val master_splitter = LazyModule(new TLSplitter) // Allows cycle-free connection to external networks + inwardBufNode :=* master_splitter.node + + protected def inwardSplitNode: TLInwardNode = master_splitter.node + protected def outwardSplitNode: TLOutwardNode = master_splitter.node + + private val tile_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.allUncacheable)) + private val port_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.all)) + master_splitter.node :=* tile_fixer.node + master_splitter.node :=* port_fixer.node + + def toSplitSlaves: TLOutwardNode = outwardSplitNode + + val toPeripheryBus: TLOutwardNode = outwardWWNode + + val toMemoryBus: TLOutwardNode = outwardNode + + def fromAsyncMasters(depth: Int = 8, sync: Int = 3): TLAsyncInwardNode = { + val sink = LazyModule(new TLAsyncCrossingSink(depth, sync)) + inwardNode :=* sink.node + sink.node + } + + def fromSyncTiles(params: BufferParams): TLInwardNode = { + val buf = LazyModule(new TLBuffer(params)) + tile_fixer.node :=* buf.node + buf.node + } + + def fromRationalTiles(dir: RationalDirection): TLRationalInwardNode = { + val sink = LazyModule(new TLRationalCrossingSink(direction = dir)) + tile_fixer.node :=* sink.node + sink.node + } + + def fromAsyncTiles(depth: Int, sync: Int): TLAsyncInwardNode = { + val sink = LazyModule(new TLAsyncCrossingSink(depth, sync)) + tile_fixer.node :=* sink.node + sink.node + } + + def fromSyncPorts(params: BufferParams = BufferParams.default): TLInwardNode = { + val buffer = LazyModule(new TLBuffer(params)) + port_fixer.node :=* buffer.node + buffer.node + } + + def fromSyncFIFOMaster(params: BufferParams = BufferParams.default): TLInwardNode = fromSyncPorts(params) + + def fromAsyncPorts(depth: Int = 8, sync: Int = 3): TLAsyncInwardNode = { + val sink = LazyModule(new TLAsyncCrossingSink(depth, sync)) + port_fixer.node :=* sink.node + sink.node + } + + def fromAsyncFIFOMaster(depth: Int = 8, sync: Int = 3): TLAsyncInwardNode = fromAsyncPorts(depth, sync) + + def fromRationalPorts(dir: RationalDirection): TLRationalInwardNode = { + val sink = LazyModule(new TLRationalCrossingSink(dir)) + port_fixer.node :=* sink.node + sink.node + } + + def fromRationalFIFOMaster(dir: RationalDirection): TLRationalInwardNode = fromRationalPorts(dir) +} + +/** Provides buses that serve as attachment points, + * for use in traits that connect individual devices or external ports. + */ +trait HasSystemBus extends HasInterruptBus { + private val sbusParams = p(SystemBusParams) + val sbusBeatBytes = sbusParams.beatBytes + + val sbus = new SystemBus(sbusParams) + + def sharedMemoryTLEdge: TLEdge = sbus.edgesIn.head +} diff --git a/src/main/scala/devices/debug/Debug.scala b/src/main/scala/devices/debug/Debug.scala index 30271488..618f155d 100644 --- a/src/main/scala/devices/debug/Debug.scala +++ b/src/main/scala/devices/debug/Debug.scala @@ -61,11 +61,11 @@ object DsbRegAddrs{ // We want DATA to immediately follow PROGBUF so that we can // use them interchangeably. - def PROGBUF(cfg:DebugModuleConfig) = {DATA - (cfg.nProgramBufferWords * 4)} + def PROGBUF(cfg:DebugModuleParams) = {DATA - (cfg.nProgramBufferWords * 4)} // We want abstract to be immediately before PROGBUF // because we auto-generate 2 instructions. - def ABSTRACT(cfg:DebugModuleConfig) = PROGBUF(cfg) - 8 + def ABSTRACT(cfg:DebugModuleParams) = PROGBUF(cfg) - 8 def FLAGS = 0x400 def ROMBASE = 0x800 @@ -112,7 +112,7 @@ import DebugAbstractCommandType._ * supportHartArray : Whether or not to implement the hart array register. **/ -case class DebugModuleConfig ( +case class DebugModuleParams ( nDMIAddrSize : Int = 7, nProgramBufferWords: Int = 16, nAbstractDataWords : Int = 4, @@ -152,17 +152,17 @@ case class DebugModuleConfig ( } -object DefaultDebugModuleConfig { +object DefaultDebugModuleParams { - def apply(xlen:Int /*TODO , val configStringAddr: Int*/): DebugModuleConfig = { - new DebugModuleConfig().copy( + def apply(xlen:Int /*TODO , val configStringAddr: Int*/): DebugModuleParams = { + new DebugModuleParams().copy( nAbstractDataWords = (if (xlen == 32) 1 else if (xlen == 64) 2 else 4) ) } } -case object DMKey extends Field[DebugModuleConfig] +case object DebugModuleParams extends Field[DebugModuleParams] // ***************************************** // Module Interfaces @@ -192,7 +192,7 @@ class DMIResp( ) extends Bundle { * Therefore it has the 'flipped' version of this. */ class DMIIO(implicit val p: Parameters) extends ParameterizedBundle()(p) { - val req = new DecoupledIO(new DMIReq(p(DMKey).nDMIAddrSize)) + val req = new DecoupledIO(new DMIReq(p(DebugModuleParams).nDMIAddrSize)) val resp = new DecoupledIO(new DMIResp).flip() } @@ -443,7 +443,7 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p: lazy val module = new LazyModuleImp(this){ - val cfg = p(DMKey) + val cfg = p(DebugModuleParams) val nComponents = getNComponents() diff --git a/src/main/scala/chip/DebugTransport.scala b/src/main/scala/devices/debug/DebugTransport.scala similarity index 96% rename from src/main/scala/chip/DebugTransport.scala rename to src/main/scala/devices/debug/DebugTransport.scala index 30c11c94..44b535e9 100644 --- a/src/main/scala/chip/DebugTransport.scala +++ b/src/main/scala/devices/debug/DebugTransport.scala @@ -1,16 +1,13 @@ // See LICENSE.SiFive for license details. -package freechips.rocketchip.chip +package freechips.rocketchip.devices.debug import Chisel._ import freechips.rocketchip.config._ -import freechips.rocketchip.devices.debug.{DMIConsts, DMIIO, DMIReq, DMIResp} import freechips.rocketchip.jtag._ import freechips.rocketchip.util._ -case object IncludeJtagDTM extends Field[Boolean] - case class JtagDTMConfig ( idcodeVersion : Int, // chosen by manuf. idcodePartNum : Int, // Chosen by manuf. @@ -63,12 +60,19 @@ class DTMInfo extends Bundle { val debugVersion = UInt(4.W) } +/** A wrapper around JTAG providing a reset signal and manufacturer id. */ +class SystemJTAGIO extends Bundle { + val jtag = new JTAGIO(hasTRSTn = false).flip + val reset = Bool(INPUT) + val mfr_id = UInt(INPUT, 11) +} + class DebugTransportModuleJTAG(debugAddrBits: Int, c: JtagDTMConfig) (implicit val p: Parameters) extends Module { val io = new Bundle { val dmi = new DMIIO()(p) - val jtag = Flipped(new JTAGIO(hasTRSTn = false)) + val jtag = Flipped(new JTAGIO(hasTRSTn = false)) // TODO: re-use SystemJTAGIO here? val jtag_reset = Bool(INPUT) val jtag_mfr_id = UInt(INPUT, 11) val fsmReset = Bool(OUTPUT) diff --git a/src/main/scala/devices/debug/Periphery.scala b/src/main/scala/devices/debug/Periphery.scala new file mode 100644 index 00000000..8aaaac74 --- /dev/null +++ b/src/main/scala/devices/debug/Periphery.scala @@ -0,0 +1,123 @@ +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.devices.debug + +import Chisel._ +import freechips.rocketchip.config.{Field, Parameters} +import freechips.rocketchip.coreplex.HasPeripheryBus +import freechips.rocketchip.devices.tilelink._ +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.jtag._ +import freechips.rocketchip.util._ + +/** A knob selecting one of the two possible debug interfaces */ +case object IncludeJtagDTM extends Field[Boolean] + +/** A wrapper bundle containing one of the two possible debug interfaces */ +class DebugIO(implicit p: Parameters) extends ParameterizedBundle()(p) { + val clockeddmi = (!p(IncludeJtagDTM)).option(new ClockedDMIIO().flip) + val systemjtag = (p(IncludeJtagDTM)).option(new SystemJTAGIO) + val ndreset = Bool(OUTPUT) + val dmactive = Bool(OUTPUT) +} + +/** Either adds a JTAG DTM to system, and exports a JTAG interface, + * or exports the Debug Module Interface (DMI), based on a global parameter. + */ +trait HasPeripheryDebug extends HasPeripheryBus { + val module: HasPeripheryDebugModuleImp + + val debug = LazyModule(new TLDebugModule()) + + debug.node := pbus.toVariableWidthSlaves +} + +trait HasPeripheryDebugBundle { + implicit val p: Parameters + + val debug: DebugIO + + def connectDebug(c: Clock, r: Bool, out: Bool) { + debug.clockeddmi.foreach { d => + val dtm = Module(new SimDTM).connect(c, r, d, out) + } + debug.systemjtag.foreach { sj => + val jtag = Module(new JTAGVPI).connect(sj.jtag, sj.reset, r, out) + sj.mfr_id := p(JtagDTMKey).idcodeManufId.U(11.W) + } + } +} + +trait HasPeripheryDebugModuleImp extends LazyMultiIOModuleImp with HasPeripheryDebugBundle { + val outer: HasPeripheryDebug + + val debug = IO(new DebugIO) + + debug.clockeddmi.foreach { dbg => outer.debug.module.io.dmi <> dbg } + + val dtm = debug.systemjtag.map { sj => + val dtm = Module(new DebugTransportModuleJTAG(p(DebugModuleParams).nDMIAddrSize, p(JtagDTMKey))) + dtm.io.jtag <> sj.jtag + + dtm.clock := sj.jtag.TCK + dtm.io.jtag_reset := sj.reset + dtm.io.jtag_mfr_id := sj.mfr_id + dtm.reset := dtm.io.fsmReset + + outer.debug.module.io.dmi.dmi <> dtm.io.dmi + outer.debug.module.io.dmi.dmiClock := sj.jtag.TCK + outer.debug.module.io.dmi.dmiReset := ResetCatchAndSync(sj.jtag.TCK, sj.reset, "dmiResetCatch") + dtm + } + + debug.ndreset := outer.debug.module.io.ctrl.ndreset + debug.dmactive := outer.debug.module.io.ctrl.dmactive + + // TODO in inheriting traits: Set this to something meaningful, e.g. "component is in reset or powered down" + outer.debug.module.io.ctrl.debugUnavail.foreach { _ := Bool(false) } +} + +class SimDTM(implicit p: Parameters) extends BlackBox { + val io = new Bundle { + val clk = Clock(INPUT) + val reset = Bool(INPUT) + val debug = new DMIIO + val exit = UInt(OUTPUT, 32) + } + + def connect(tbclk: Clock, tbreset: Bool, dutio: ClockedDMIIO, tbsuccess: Bool) = { + io.clk := tbclk + io.reset := tbreset + dutio.dmi <> io.debug + dutio.dmiClock := tbclk + dutio.dmiReset := tbreset + + tbsuccess := io.exit === UInt(1) + when (io.exit >= UInt(2)) { + printf("*** FAILED *** (exit code = %d)\n", io.exit >> UInt(1)) + stop(1) + } + } +} + +class JTAGVPI(implicit val p: Parameters) extends BlackBox { + val io = new Bundle { + val jtag = new JTAGIO(hasTRSTn = false) + val enable = Bool(INPUT) + val init_done = Bool(INPUT) + } + + def connect(dutio: JTAGIO, jtag_reset: Bool, tbreset: Bool, tbsuccess: Bool) = { + dutio <> io.jtag + + dutio.TRSTn.foreach{ _:= false.B} + jtag_reset := tbreset + + io.enable := ~tbreset + io.init_done := ~tbreset + + // Success is determined by the gdbserver + // which is controlling this simulation. + tbsuccess := Bool(false) + } +} diff --git a/src/main/scala/devices/tilelink/BootROM.scala b/src/main/scala/devices/tilelink/BootROM.scala new file mode 100644 index 00000000..706401b9 --- /dev/null +++ b/src/main/scala/devices/tilelink/BootROM.scala @@ -0,0 +1,41 @@ +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.devices.tilelink + +import Chisel._ +import freechips.rocketchip.config.{Field, Parameters} +import freechips.rocketchip.coreplex._ +import freechips.rocketchip.diplomacy._ +import java.nio.{ByteBuffer, ByteOrder} +import java.nio.file.{Files, Paths} + +/** Size, location and contents of the boot rom. */ +case class BootROMParams( + address: BigInt = 0x10000, + size: Int = 0x10000, + hang: BigInt = 0x10040, + contentFileName: String) +case object BootROMParams extends Field[BootROMParams] + +/** Adds a boot ROM that contains the DTB describing the system's coreplex. */ +trait HasPeripheryBootROM extends HasPeripheryBus { + val dtb: DTB + private val params = p(BootROMParams) + private lazy val contents = { + val romdata = Files.readAllBytes(Paths.get(params.contentFileName)) + val rom = ByteBuffer.wrap(romdata) + rom.array() ++ dtb.contents + } + def resetVector: BigInt = params.hang + + val bootrom = LazyModule(new TLROM(params.address, params.size, contents, true, pbus.beatBytes)) + + bootrom.node := pbus.toVariableWidthSlaves +} + +/** Coreplex will power-on running at 0x10040 (BootROM) */ +trait HasPeripheryBootROMModuleImp extends LazyMultiIOModuleImp + with HasResetVectorWire { + val outer: HasPeripheryBootROM + global_reset_vector := UInt(outer.resetVector, width = resetVectorBits) +} diff --git a/src/main/scala/devices/tilelink/Clint.scala b/src/main/scala/devices/tilelink/Clint.scala index ff3e1067..c1235176 100644 --- a/src/main/scala/devices/tilelink/Clint.scala +++ b/src/main/scala/devices/tilelink/Clint.scala @@ -3,7 +3,8 @@ package freechips.rocketchip.devices.tilelink import Chisel._ -import freechips.rocketchip.config.Parameters +import freechips.rocketchip.config.{Field, Parameters} +import freechips.rocketchip.coreplex.HasPeripheryBus import freechips.rocketchip.diplomacy._ import freechips.rocketchip.regmapper._ import freechips.rocketchip.tile.XLen @@ -29,6 +30,8 @@ case class ClintParams(baseAddress: BigInt = 0x02000000) def address = AddressSet(baseAddress, ClintConsts.size-1) } +case object ClintParams extends Field[ClintParams] + class CoreplexLocalInterrupter(params: ClintParams)(implicit p: Parameters) extends LazyModule { import ClintConsts._ @@ -90,3 +93,9 @@ class CoreplexLocalInterrupter(params: ClintParams)(implicit p: Parameters) exte timeOffset -> makeRegFields(time)) } } + +/** Trait that will connect a Clint to a coreplex */ +trait HasPeripheryClint extends HasPeripheryBus { + val clint = LazyModule(new CoreplexLocalInterrupter(p(ClintParams))) + clint.node := pbus.toVariableWidthSlaves +} diff --git a/src/main/scala/devices/tilelink/Error.scala b/src/main/scala/devices/tilelink/Error.scala index c3f2cac1..9f10051f 100644 --- a/src/main/scala/devices/tilelink/Error.scala +++ b/src/main/scala/devices/tilelink/Error.scala @@ -3,13 +3,21 @@ package freechips.rocketchip.devices.tilelink import Chisel._ -import freechips.rocketchip.config.Parameters +import freechips.rocketchip.config.{Field, Parameters} +import freechips.rocketchip.coreplex.HasPeripheryBus import freechips.rocketchip.diplomacy._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.util._ +import scala.math.min -class TLError(address: Seq[AddressSet], beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule +case class ErrorParams(address: Seq[AddressSet]) +case object ErrorParams extends Field[ErrorParams] + +/** Adds a /dev/null slave that generates TL error response messages */ +class TLError(params: ErrorParams, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule { + val address = params.address + val device = new SimpleDevice("error-device", Seq("sifive,error0")) val node = TLManagerNode(Seq(TLManagerPortParameters( @@ -55,3 +63,13 @@ class TLError(address: Seq[AddressSet], beatBytes: Int = 4)(implicit p: Paramete in.e.ready := Bool(true) } } + +trait HasPeripheryErrorSlave extends HasPeripheryBus { + private val params = p(ErrorParams) + private val maxXfer = min(params.address.map(_.alignment).max.toInt, 4096) + val error = LazyModule(new TLError(params, pbus.beatBytes)) + + // Most slaves do not support a 4kB burst so this slave ends up with many more source bits than others; + // we exclude the onerously large TLMonitor that results. + error.node connectButDontMonitor pbus.toLargeBurstSlave(maxXfer) +} diff --git a/src/main/scala/devices/tilelink/Plic.scala b/src/main/scala/devices/tilelink/Plic.scala index 4b124de5..5581352e 100644 --- a/src/main/scala/devices/tilelink/Plic.scala +++ b/src/main/scala/devices/tilelink/Plic.scala @@ -4,7 +4,8 @@ package freechips.rocketchip.devices.tilelink import Chisel._ import Chisel.ImplicitConversions._ -import freechips.rocketchip.config.Parameters +import freechips.rocketchip.config.{Field, Parameters} +import freechips.rocketchip.coreplex.{HasInterruptBus, HasPeripheryBus} import freechips.rocketchip.diplomacy._ import freechips.rocketchip.regmapper._ import freechips.rocketchip.tile.XLen @@ -57,6 +58,8 @@ case class PLICParams(baseAddress: BigInt = 0xC000000, maxPriorities: Int = 7) def address = AddressSet(baseAddress, PLICConsts.size-1) } +case object PLICParams extends Field[PLICParams] + /** Platform-Level Interrupt Controller */ class TLPLIC(params: PLICParams)(implicit p: Parameters) extends LazyModule { @@ -232,3 +235,10 @@ class TLPLIC(params: PLICParams)(implicit p: Parameters) extends LazyModule e(0) := false } } + +/** Trait that will connect a PLIC to a coreplex */ +trait HasPeripheryPLIC extends HasInterruptBus with HasPeripheryBus { + val plic = LazyModule(new TLPLIC(p(PLICParams))) + plic.node := pbus.toVariableWidthSlaves + plic.intnode := ibus.toPLIC +} diff --git a/src/main/scala/devices/tilelink/Rom.scala b/src/main/scala/devices/tilelink/ROM.scala similarity index 100% rename from src/main/scala/devices/tilelink/Rom.scala rename to src/main/scala/devices/tilelink/ROM.scala diff --git a/src/main/scala/devices/tilelink/Zero.scala b/src/main/scala/devices/tilelink/Zero.scala index 51bb0782..19d18f47 100644 --- a/src/main/scala/devices/tilelink/Zero.scala +++ b/src/main/scala/devices/tilelink/Zero.scala @@ -3,7 +3,8 @@ package freechips.rocketchip.devices.tilelink import Chisel._ -import freechips.rocketchip.config.Parameters +import freechips.rocketchip.config.{Field, Parameters} +import freechips.rocketchip.coreplex.HasMemoryBus import freechips.rocketchip.diplomacy._ import freechips.rocketchip.tilelink._ @@ -44,3 +45,23 @@ class TLZero(address: AddressSet, resources: Seq[Resource], executable: Boolean in.e.ready := Bool(true) } } + +/* Specifies the location of the Zero device */ +case class ZeroParams(base: Long, size: Long, beatBytes: Int) +case object ZeroParams extends Field[ZeroParams] + +/** Adds a /dev/null slave that generates zero-filled responses to reads */ +trait HasMemoryZeroSlave extends HasMemoryBus { + private val params = p(ZeroParams) + private val device = new SimpleDevice("rom", Seq("ucbbar,cacheable-zero0")) + + val zeros = memBuses.map(_.toVariableWidthSlave).zipWithIndex.map { case (node, channel) => + val channels = memBuses.size + val base = AddressSet(params.base, params.size-1) + val filter = AddressSet(channel * cacheBlockBytes, ~((channels-1) * cacheBlockBytes)) + val address = base.intersect(filter).get + val zero = LazyModule(new TLZero(address, beatBytes = params.beatBytes, resources = device.reg("mem"))) + zero.node := node + zero + } +} diff --git a/src/main/scala/diplomacy/Nodes.scala b/src/main/scala/diplomacy/Nodes.scala index bf895685..619da2bb 100644 --- a/src/main/scala/diplomacy/Nodes.scala +++ b/src/main/scala/diplomacy/Nodes.scala @@ -267,6 +267,8 @@ abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( override def :=* (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_QUERY, true) def connectButDontMonitor(h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_ONCE, false) + def connectButDontMonitorSlaves(h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_STAR, false) + def connectButDontMonitorMasters(h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_QUERY, false) // meta-data for printing the node graph protected[diplomacy] def colour = inner.colour diff --git a/src/main/scala/groundtest/Configs.scala b/src/main/scala/groundtest/Configs.scala index 90d08e24..1fdf64d5 100644 --- a/src/main/scala/groundtest/Configs.scala +++ b/src/main/scala/groundtest/Configs.scala @@ -4,15 +4,14 @@ package freechips.rocketchip.groundtest import Chisel._ -import freechips.rocketchip.chip.{BaseConfig, ExtMem} import freechips.rocketchip.config.Config -import freechips.rocketchip.coreplex.{CacheBlockBytes, L1toL2Config, WithBufferlessBroadcastHub} +import freechips.rocketchip.coreplex._ import freechips.rocketchip.rocket.{DCacheParams, PAddrBits} import freechips.rocketchip.tile.{MaxHartIdBits, XLen} /** Actual testing target Configs */ -class TraceGenConfig extends Config(new WithTraceGen(List.fill(2){ DCacheParams(nSets = 16, nWays = 1) }) ++ new BaseConfig) +class TraceGenConfig extends Config(new WithTraceGen(List.fill(2){ DCacheParams(nSets = 16, nWays = 1) }) ++ new BaseCoreplexConfig) class TraceGenBufferlessConfig extends Config(new WithBufferlessBroadcastHub ++ new TraceGenConfig) @@ -26,8 +25,8 @@ class WithTraceGen(params: Seq[DCacheParams], nReqs: Int = 8192) extends Config( addrBag = { val nSets = 2 val nWays = 1 - val blockOffset = log2Up(site(CacheBlockBytes)) - val nBeats = site(CacheBlockBytes)/site(L1toL2Config).beatBytes + val blockOffset = site(SystemBusParams).blockOffset + val nBeats = site(SystemBusParams).blockBeats List.tabulate(4 * nWays) { i => Seq.tabulate(nBeats) { j => BigInt((j * 8) + ((i * nSets) << blockOffset)) } }.flatten diff --git a/src/main/scala/groundtest/Coreplex.scala b/src/main/scala/groundtest/Coreplex.scala index 6ab78ca0..fc58912a 100644 --- a/src/main/scala/groundtest/Coreplex.scala +++ b/src/main/scala/groundtest/Coreplex.scala @@ -14,33 +14,43 @@ import scala.math.max case object TileId extends Field[Int] -class GroundTestCoreplex(implicit p: Parameters) extends BaseCoreplex { +class GroundTestCoreplex(implicit p: Parameters) extends BaseCoreplex + with HasMasterAXI4MemPort + with HasPeripheryTestRAMSlave { val tileParams = p(GroundTestTilesKey) val tiles = tileParams.zipWithIndex.map { case(c, i) => LazyModule( c.build(i, p.alterPartial { case TileKey => c - case SharedMemoryTLEdge => tile_splitter.node.edgesIn(0) + case SharedMemoryTLEdge => sbus.edgesIn.head }) )} - val fixer = LazyModule(new TLFIFOFixer) - tile_splitter.node :=* fixer.node - tiles.foreach { fixer.node :=* _.masterNode } + tiles.foreach { sbus.fromSyncTiles(BufferParams.default) :=* _.masterNode } - val pbusRAM = LazyModule(new TLRAM(AddressSet(testRamAddr, 0xffff), false, pbusBeatBytes)) - pbusRAM.node := TLFragmenter(pbusBeatBytes, pbusBlockBytes)(pbus.node) + val pbusRAM = LazyModule(new TLRAM(AddressSet(testRamAddr, 0xffff), false, pbus.beatBytes)) + pbusRAM.node := pbus.toVariableWidthSlaves - override lazy val module = new GroundTestCoreplexModule(this, () => new GroundTestCoreplexBundle(this)) + override lazy val module = new GroundTestCoreplexModule(this) } -class GroundTestCoreplexBundle[+L <: GroundTestCoreplex](_outer: L) extends BaseCoreplexBundle(_outer) { - val success = Bool(OUTPUT) -} - -class GroundTestCoreplexModule[+L <: GroundTestCoreplex, +B <: GroundTestCoreplexBundle[L]](_outer: L, _io: () => B) extends BaseCoreplexModule(_outer, _io) { +class GroundTestCoreplexModule[+L <: GroundTestCoreplex](_outer: L) extends BaseCoreplexModule(_outer) + with HasMasterAXI4MemPortModuleImp { + val success = IO(Bool(OUTPUT)) outer.tiles.zipWithIndex.map { case(t, i) => t.module.io.hartid := UInt(i) } val status = DebugCombiner(outer.tiles.map(_.module.io.status)) - io.success := status.finished + success := status.finished +} + +/** Adds a SRAM to the system for testing purposes. */ +trait HasPeripheryTestRAMSlave extends HasPeripheryBus { + val testram = LazyModule(new TLRAM(AddressSet(0x52000000, 0xfff), true, pbus.beatBytes)) + testram.node := pbus.toVariableWidthSlaves +} + +/** Adds a fuzzing master to the system for testing purposes. */ +trait HasPeripheryTestFuzzMaster extends HasPeripheryBus { + val fuzzer = LazyModule(new TLFuzzer(5000)) + pbus.bufferFromMasters := fuzzer.node } diff --git a/src/main/scala/groundtest/TestHarness.scala b/src/main/scala/groundtest/TestHarness.scala index a7dd1ef3..6f2f447e 100644 --- a/src/main/scala/groundtest/TestHarness.scala +++ b/src/main/scala/groundtest/TestHarness.scala @@ -9,7 +9,7 @@ import freechips.rocketchip.diplomacy.LazyModule class TestHarness(implicit p: Parameters) extends Module { val io = new Bundle { val success = Bool(OUTPUT) } - val dut = Module(LazyModule(new GroundTestTop).module) - io.success := dut.io_success + val dut = Module(LazyModule(new GroundTestCoreplex).module) + io.success := dut.success dut.connectSimAXIMem() } diff --git a/src/main/scala/groundtest/Tile.scala b/src/main/scala/groundtest/Tile.scala index a41e8a5a..f5ae3c3a 100644 --- a/src/main/scala/groundtest/Tile.scala +++ b/src/main/scala/groundtest/Tile.scala @@ -6,11 +6,8 @@ package freechips.rocketchip.groundtest import Chisel._ import freechips.rocketchip.config._ import freechips.rocketchip.coreplex._ -import freechips.rocketchip.diplomacy._ -import freechips.rocketchip.rocket._ -import freechips.rocketchip.chip._ +import freechips.rocketchip.rocket.{HellaCache, RocketCoreParams} import freechips.rocketchip.tile._ -import freechips.rocketchip.tilelink._ import scala.collection.mutable.ListBuffer trait GroundTestTileParams extends TileParams { diff --git a/src/main/scala/groundtest/Top.scala b/src/main/scala/groundtest/Top.scala deleted file mode 100644 index 9de7b6e3..00000000 --- a/src/main/scala/groundtest/Top.scala +++ /dev/null @@ -1,27 +0,0 @@ -// See LICENSE.SiFive for license details. - -package freechips.rocketchip.groundtest - -import Chisel._ - -import freechips.rocketchip.config.Parameters -import freechips.rocketchip.diplomacy.LazyModule -import freechips.rocketchip.chip._ - -class GroundTestTop(implicit p: Parameters) extends BaseSystem - with HasPeripheryMasterAXI4MemPort - with HasPeripheryTestRAMSlave { - override lazy val module = new GroundTestTopModule(this) - - val coreplex = LazyModule(new GroundTestCoreplex) - - socBus.node := coreplex.mmio - coreplex.mmioInt := intBus.intnode - (mem zip coreplex.mem) foreach { case (xbar, channel) => xbar.node :=* channel } -} - -class GroundTestTopModule[+L <: GroundTestTop](_outer: L) extends BaseSystemModule(_outer) - with HasPeripheryMasterAXI4MemPortModuleImp { - val io_success = IO(Bool(OUTPUT)) - io_success := outer.coreplex.module.io.success -} diff --git a/src/main/scala/rocket/HellaCache.scala b/src/main/scala/rocket/HellaCache.scala index e7d506a8..27a44ff3 100644 --- a/src/main/scala/rocket/HellaCache.scala +++ b/src/main/scala/rocket/HellaCache.scala @@ -183,9 +183,10 @@ class HellaCacheModule(outer: HellaCache) extends LazyModuleImp(outer) val io = new HellaCacheBundle(outer) val tl_out = io.mem(0) - // IOMSHRs must be FIFO for all regions with effects - edge.manager.managers.foreach { m => - require (m.fifoId == Some(0) || !TLFIFOFixer.allUncacheable(m)) + private val fifoManagers = edge.manager.managers.filter(TLFIFOFixer.allUncacheable) + fifoManagers.foreach { m => + require (m.fifoId == fifoManagers.head.fifoId, + s"IOMSHRs must be FIFO for all regions with effects, but HellaCache sees ${m.nodePath.map(_.name)}") } } diff --git a/src/main/scala/rocket/ScratchpadSlavePort.scala b/src/main/scala/rocket/ScratchpadSlavePort.scala index 8fe3cad2..0b575a8f 100644 --- a/src/main/scala/rocket/ScratchpadSlavePort.scala +++ b/src/main/scala/rocket/ScratchpadSlavePort.scala @@ -105,14 +105,14 @@ trait CanHaveScratchpad extends HasHellaCache with HasICacheFrontend with HasCor // 1) Frontend always exists, but may or may not have a scratchpad node val fg = LazyModule(new TLFragmenter(fetchWidth*coreInstBytes, p(CacheBlockBytes), earlyAck=true)) val ww = LazyModule(new TLWidthWidget(xLen/8)) - frontend.slaveNode :*= fg.node - fg.node :*= ww.node - ww.node :*= slaveNode + frontend.slaveNode connectButDontMonitorSlaves fg.node + fg.node connectButDontMonitorSlaves ww.node + ww.node connectButDontMonitorSlaves slaveNode // 2) ScratchpadSlavePort always has a node, but only exists when the HellaCache has a scratchpad val scratch = tileParams.dcache.flatMap(d => d.scratch.map(s => LazyModule(new ScratchpadSlavePort(AddressSet(s, d.dataScratchpadBytes-1))))) - scratch foreach { lm => lm.node := TLFragmenter(xLen/8, p(CacheBlockBytes), earlyAck=true)(slaveNode) } + scratch foreach { lm => lm.node connectButDontMonitor TLFragmenter(xLen/8, p(CacheBlockBytes), earlyAck=true)(slaveNode) } def findScratchpadFromICache: Option[AddressSet] = scratch.map { s => val finalNode = frontend.masterNode.edgesOut.head.manager.managers.find(_.nodePath.last == s.node) diff --git a/src/main/scala/system/Configs.scala b/src/main/scala/system/Configs.scala new file mode 100644 index 00000000..8460e20e --- /dev/null +++ b/src/main/scala/system/Configs.scala @@ -0,0 +1,84 @@ +// See LICENSE.SiFive for license details. +// See LICENSE.Berkeley for license details. + +package freechips.rocketchip.system + +import Chisel._ +import freechips.rocketchip.config.Config +import freechips.rocketchip.coreplex._ +import freechips.rocketchip.devices.debug._ +import freechips.rocketchip.devices.tilelink._ +import freechips.rocketchip.diplomacy._ + +class BaseConfig extends Config(new BaseCoreplexConfig().alter((site,here,up) => { + // DTS descriptive parameters + case DTSModel => "freechips,rocketchip-unknown" + case DTSCompat => Nil + case DTSTimebase => BigInt(1000000) // 1 MHz + case RTCPeriod => Some(1000) // Implies coreplex clock is DTSTimebase * RTCPeriod = 1 GHz + // External port parameters + case IncludeJtagDTM => false + case JtagDTMKey => new JtagDTMKeyDefault() + case NExtTopInterrupts => 2 + case ExtMem => MasterPortParams( + base = 0x80000000L, + size = 0x10000000L, + beatBytes = site(MemoryBusParams).beatBytes, + idBits = 4) + case ExtBus => MasterPortParams( + base = 0x60000000L, + size = 0x20000000L, + beatBytes = site(MemoryBusParams).beatBytes, + idBits = 4) + case ExtIn => SlavePortParams(beatBytes = 8, idBits = 8, sourceBits = 4) + // Additional device Parameters + case ErrorParams => ErrorParams(Seq(AddressSet(0x3000, 0xfff))) + case BootROMParams => BootROMParams(contentFileName = "./bootrom/bootrom.img") +})) + +class DefaultConfig extends Config(new WithNBigCores(1) ++ new BaseConfig) + +class DefaultBufferlessConfig extends Config( + new WithBufferlessBroadcastHub ++ new WithNBigCores(1) ++ new BaseConfig) + +class DefaultSmallConfig extends Config(new WithNSmallCores(1) ++ new BaseConfig) +class DefaultRV32Config extends Config(new WithRV32 ++ new DefaultConfig) + +class DualBankConfig extends Config( + new WithNBanksPerMemChannel(2) ++ new BaseConfig) + +class DualChannelConfig extends Config(new WithNMemoryChannels(2) ++ new BaseConfig) + +class DualChannelDualBankConfig extends Config( + new WithNMemoryChannels(2) ++ + new WithNBanksPerMemChannel(2) ++ new BaseConfig) + +class RoccExampleConfig extends Config(new WithRoccExample ++ new DefaultConfig) + +class Edge128BitConfig extends Config( + new WithEdgeDataBits(128) ++ new BaseConfig) +class Edge32BitConfig extends Config( + new WithEdgeDataBits(32) ++ new BaseConfig) + +class SingleChannelBenchmarkConfig extends Config(new DefaultConfig) +class DualChannelBenchmarkConfig extends Config(new WithNMemoryChannels(2) ++ new SingleChannelBenchmarkConfig) +class QuadChannelBenchmarkConfig extends Config(new WithNMemoryChannels(4) ++ new SingleChannelBenchmarkConfig) +class OctoChannelBenchmarkConfig extends Config(new WithNMemoryChannels(8) ++ new SingleChannelBenchmarkConfig) + +class EightChannelConfig extends Config(new WithNMemoryChannels(8) ++ new BaseConfig) + +class DualCoreConfig extends Config( + new WithNBigCores(2) ++ new BaseConfig) + +class HeterogeneousDualCoreConfig extends Config( + new WithNSmallCores(1) ++ new WithNBigCores(1) ++ new BaseConfig) + +class TinyConfig extends Config( + new WithNMemoryChannels(0) ++ + new WithStatelessBridge ++ + new WithNTinyCores(1) ++ + new BaseConfig) + +class DefaultFPGAConfig extends Config(new BaseConfig) + +class DefaultFPGASmallConfig extends Config(new WithNSmallCores(1) ++ new DefaultFPGAConfig) diff --git a/src/main/scala/system/ExampleRocketSystem.scala b/src/main/scala/system/ExampleRocketSystem.scala new file mode 100644 index 00000000..acb14ce6 --- /dev/null +++ b/src/main/scala/system/ExampleRocketSystem.scala @@ -0,0 +1,26 @@ +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.system + +import Chisel._ +import freechips.rocketchip.config.Parameters +import freechips.rocketchip.coreplex._ +import freechips.rocketchip.devices.tilelink._ + +/** Example Top with periphery devices and ports, and a Rocket coreplex */ +class ExampleRocketSystem(implicit p: Parameters) extends RocketCoreplex + with HasAsyncExtInterrupts + with HasMasterAXI4MemPort + with HasMasterAXI4MMIOPort + with HasSlaveAXI4Port + with HasPeripheryBootROM + with HasPeripheryErrorSlave { + override lazy val module = new ExampleRocketSystemModule(this) +} + +class ExampleRocketSystemModule[+L <: ExampleRocketSystem](_outer: L) extends RocketCoreplexModule(_outer) + with HasRTCModuleImp + with HasExtInterruptsModuleImp + with HasMasterAXI4MemPortModuleImp + with HasMasterAXI4MMIOPortModuleImp + with HasSlaveAXI4PortModuleImp diff --git a/src/main/scala/chip/Generator.scala b/src/main/scala/system/Generator.scala similarity index 98% rename from src/main/scala/chip/Generator.scala rename to src/main/scala/system/Generator.scala index 6a998276..717ebeda 100644 --- a/src/main/scala/chip/Generator.scala +++ b/src/main/scala/system/Generator.scala @@ -1,6 +1,6 @@ // See LICENSE.SiFive for license details. -package freechips.rocketchip.chip +package freechips.rocketchip.system import freechips.rocketchip.coreplex.RocketTilesKey import freechips.rocketchip.tile.XLen diff --git a/src/main/scala/chip/RocketTestSuite.scala b/src/main/scala/system/RocketTestSuite.scala similarity index 99% rename from src/main/scala/chip/RocketTestSuite.scala rename to src/main/scala/system/RocketTestSuite.scala index ccd4d740..4a29356c 100644 --- a/src/main/scala/chip/RocketTestSuite.scala +++ b/src/main/scala/system/RocketTestSuite.scala @@ -1,7 +1,7 @@ // See LICENSE.Berkeley for license details. // See LICENSE.SiFive for license details. -package freechips.rocketchip.chip +package freechips.rocketchip.system import scala.collection.mutable.LinkedHashSet diff --git a/src/main/scala/system/TestHarness.scala b/src/main/scala/system/TestHarness.scala new file mode 100644 index 00000000..e8accb7f --- /dev/null +++ b/src/main/scala/system/TestHarness.scala @@ -0,0 +1,22 @@ +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.system + +import Chisel._ +import freechips.rocketchip.config.Parameters +import freechips.rocketchip.diplomacy.LazyModule + +class TestHarness()(implicit p: Parameters) extends Module { + val io = new Bundle { + val success = Bool(OUTPUT) + } + + val dut = Module(LazyModule(new ExampleRocketSystem).module) + dut.reset := reset | dut.debug.ndreset + + dut.tieOffInterrupts() + dut.connectSimAXIMem() + dut.connectSimAXIMMIO() + dut.tieOffAXI4SlavePort() + dut.connectDebug(clock, reset, io.success) +} diff --git a/src/main/scala/tile/L1Cache.scala b/src/main/scala/tile/L1Cache.scala index bffd1b7e..b98eebab 100644 --- a/src/main/scala/tile/L1Cache.scala +++ b/src/main/scala/tile/L1Cache.scala @@ -21,6 +21,7 @@ trait L1CacheParams { trait HasL1CacheParameters { implicit val p: Parameters val cacheParams: L1CacheParams + private val bundleParams = p(SharedMemoryTLEdge).bundle def cacheBlockBytes = cacheParams.blockBytes def lgCacheBlockBytes = log2Up(cacheBlockBytes) @@ -28,7 +29,7 @@ trait HasL1CacheParameters { def blockOffBits = lgCacheBlockBytes def idxBits = log2Up(cacheParams.nSets) def untagBits = blockOffBits + idxBits - def tagBits = p(PAddrBits) - untagBits + def tagBits = bundleParams.addressBits - untagBits def nWays = cacheParams.nWays def wayBits = log2Up(nWays) def isDM = nWays == 1 @@ -37,7 +38,7 @@ trait HasL1CacheParameters { def rowOffBits = log2Up(rowBytes) def nTLBEntries = cacheParams.nTLBEntries - def cacheDataBits = p(SharedMemoryTLEdge).bundle.dataBits + def cacheDataBits = bundleParams.dataBits def cacheDataBeats = (cacheBlockBytes * 8) / cacheDataBits def refillCycles = cacheDataBeats } diff --git a/src/main/scala/rocket/RocketTile.scala b/src/main/scala/tile/RocketTile.scala similarity index 84% rename from src/main/scala/rocket/RocketTile.scala rename to src/main/scala/tile/RocketTile.scala index b7bb35b5..d663d02e 100644 --- a/src/main/scala/rocket/RocketTile.scala +++ b/src/main/scala/tile/RocketTile.scala @@ -1,14 +1,13 @@ // See LICENSE.SiFive for license details. // See LICENSE.Berkeley for license details. -package freechips.rocketchip.rocket +package freechips.rocketchip.tile import Chisel._ - import freechips.rocketchip.config._ import freechips.rocketchip.coreplex._ import freechips.rocketchip.diplomacy._ -import freechips.rocketchip.tile._ +import freechips.rocketchip.rocket._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.util._ @@ -164,29 +163,14 @@ class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => ne ptw.io.requestor <> ptwPorts } -class SyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends LazyModule { +abstract class RocketTileWrapper(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends LazyModule { val rocket = LazyModule(new RocketTile(rtp, hartid)) - - val masterNode = TLOutputNode() - masterNode :=* rocket.masterNode - - val slaveNode = new TLInputNode() { override def reverse = true } - rocket.slaveNode :*= slaveNode - - // Fully async interrupts need synchronizers. - // Others need no synchronization. - + val masterNode: OutputNode[_,_,_,_,_] + val slaveNode: InputNode[_,_,_,_,_] val asyncIntNode = IntInputNode() val periphIntNode = IntInputNode() val coreIntNode = IntInputNode() - - val xing = LazyModule(new IntXing(3)) - xing.intnode := asyncIntNode - val intXbar = LazyModule(new IntXbar) - intXbar.intnode := xing.intnode - intXbar.intnode := periphIntNode - intXbar.intnode := coreIntNode rocket.intNode := intXbar.intnode @@ -198,15 +182,30 @@ class SyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) val periphInterrupts = periphIntNode.bundleIn val coreInterrupts = coreIntNode.bundleIn } - // signals that do not change: + // signals that do not change based on crossing type: rocket.module.io.hartid := io.hartid rocket.module.io.resetVector := io.resetVector } } -class AsyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends LazyModule { - val rocket = LazyModule(new RocketTile(rtp, hartid)) +class SyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) { + val masterNode = TLOutputNode() + masterNode :=* rocket.masterNode + val slaveNode = new TLInputNode() { override def reverse = true } + rocket.slaveNode :*= slaveNode + + // Fully async interrupts need synchronizers. + // Others need no synchronization. + val xing = LazyModule(new IntXing(3)) + xing.intnode := asyncIntNode + + intXbar.intnode := xing.intnode + intXbar.intnode := periphIntNode + intXbar.intnode := coreIntNode +} + +class AsyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) { val masterNode = TLAsyncOutputNode() val source = LazyModule(new TLAsyncCrossingSource) source.node :=* rocket.masterNode @@ -220,40 +219,17 @@ class AsyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters // Fully async interrupts need synchronizers, // as do those coming from the periphery clock. // Others need no synchronization. - - val asyncIntNode = IntInputNode() - val periphIntNode = IntInputNode() - val coreIntNode = IntInputNode() - val asyncXing = LazyModule(new IntXing(3)) val periphXing = LazyModule(new IntXing(3)) asyncXing.intnode := asyncIntNode periphXing.intnode := periphIntNode - val intXbar = LazyModule(new IntXbar) intXbar.intnode := asyncXing.intnode intXbar.intnode := periphXing.intnode intXbar.intnode := coreIntNode - - rocket.intNode := intXbar.intnode - - lazy val module = new LazyModuleImp(this) { - val io = new CoreBundle with HasExternallyDrivenTileConstants { - val master = masterNode.bundleOut - val slave = slaveNode.bundleIn - val asyncInterrupts = asyncIntNode.bundleIn - val periphInterrupts = periphIntNode.bundleIn - val coreInterrupts = coreIntNode.bundleIn - } - // signals that do not change: - rocket.module.io.hartid := io.hartid - rocket.module.io.resetVector := io.resetVector - } } -class RationalRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends LazyModule { - val rocket = LazyModule(new RocketTile(rtp, hartid)) - +class RationalRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) { val masterNode = TLRationalOutputNode() val source = LazyModule(new TLRationalCrossingSource) source.node :=* rocket.masterNode @@ -268,33 +244,12 @@ class RationalRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Paramet // Those coming from periphery clock need a // rational synchronizer. // Others need no synchronization. - - val asyncIntNode = IntInputNode() - val periphIntNode = IntInputNode() - val coreIntNode = IntInputNode() - val asyncXing = LazyModule(new IntXing(3)) val periphXing = LazyModule(new IntXing(1)) asyncXing.intnode := asyncIntNode periphXing.intnode := periphIntNode - val intXbar = LazyModule(new IntXbar) intXbar.intnode := asyncXing.intnode intXbar.intnode := periphXing.intnode intXbar.intnode := coreIntNode - - rocket.intNode := intXbar.intnode - - lazy val module = new LazyModuleImp(this) { - val io = new CoreBundle with HasExternallyDrivenTileConstants { - val master = masterNode.bundleOut - val slave = slaveNode.bundleIn - val asyncInterrupts = asyncIntNode.bundleIn - val periphInterrupts = periphIntNode.bundleIn - val coreInterrupts = coreIntNode.bundleIn - } - // signals that do not change: - rocket.module.io.hartid := io.hartid - rocket.module.io.resetVector := io.resetVector - } } diff --git a/src/main/scala/tilelink/AtomicAutomata.scala b/src/main/scala/tilelink/AtomicAutomata.scala index e9bbd200..de2604a9 100644 --- a/src/main/scala/tilelink/AtomicAutomata.scala +++ b/src/main/scala/tilelink/AtomicAutomata.scala @@ -22,7 +22,7 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc def widen(x: TransferSizes) = if (passthrough && x.min <= 2*mp.beatBytes) TransferSizes(1, max(mp.beatBytes, x.max)) else ourSupport val canDoit = m.supportsPutFull.contains(ourSupport) && m.supportsGet.contains(ourSupport) // Blow up if there are devices to which we cannot add Atomics, because their R|W are too inflexible - require (!m.supportsPutFull || !m.supportsGet || canDoit) + require (!m.supportsPutFull || !m.supportsGet || canDoit, s"${m.name} has $ourSupport, needed PutFull(${m.supportsPutFull}) or Get(${m.supportsGet})") m.copy( supportsArithmetic = if (!arithmetic || !canDoit) m.supportsArithmetic else widen(m.supportsArithmetic), supportsLogical = if (!logical || !canDoit) m.supportsLogical else widen(m.supportsLogical)) diff --git a/src/main/scala/tilelink/Broadcast.scala b/src/main/scala/tilelink/Broadcast.scala index 204ec8ad..86b3f26d 100644 --- a/src/main/scala/tilelink/Broadcast.scala +++ b/src/main/scala/tilelink/Broadcast.scala @@ -29,8 +29,8 @@ class TLBroadcast(lineBytes: Int, numTrackers: Int = 4, bufferless: Boolean = fa if (m.regionType == RegionType.UNCACHED) { // The device had better support line transfers val lowerBound = max(m.supportsPutFull.min, m.supportsGet.min) - require (!m.supportsPutFull || m.supportsPutFull.contains(lineBytes)) - require (!m.supportsGet || m.supportsGet .contains(lineBytes)) + require (!m.supportsPutFull || m.supportsPutFull.contains(lineBytes), s"${m.name} only supports PutFull(${m.supportsPutFull}), which does not include $lineBytes") + require (!m.supportsGet || m.supportsGet .contains(lineBytes), s"${m.name} only supports Get(${m.supportsGet}), which does not include $lineBytes") m.copy( regionType = RegionType.TRACKED, supportsAcquireB = TransferSizes(lowerBound, lineBytes), diff --git a/src/main/scala/tilelink/Bus.scala b/src/main/scala/tilelink/Bus.scala new file mode 100644 index 00000000..3795be10 --- /dev/null +++ b/src/main/scala/tilelink/Bus.scala @@ -0,0 +1,96 @@ +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.tilelink + +import Chisel._ +import freechips.rocketchip.config.Parameters +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.tilelink._ + +/** Specifies widths of various attachement points in the SoC */ +trait TLBusParams { + val beatBytes: Int + val blockBytes: Int + val masterBuffering: BufferParams + val slaveBuffering: BufferParams + + def beatBits: Int = beatBytes * 8 + def blockBits: Int = blockBytes * 8 + def blockBeats: Int = blockBytes / beatBytes + def blockOffset: Int = log2Up(blockBytes) +} + +abstract class TLBusWrapper(params: TLBusParams)(implicit p: Parameters) extends TLBusParams { + val beatBytes = params.beatBytes + val blockBytes = params.blockBytes + val masterBuffering = params.masterBuffering + val slaveBuffering = params.slaveBuffering + require(blockBytes % beatBytes == 0) + + private val xbar = LazyModule(new TLXbar) + private val master_buffer = LazyModule(new TLBuffer(masterBuffering)) + private val slave_buffer = LazyModule(new TLBuffer(slaveBuffering)) + private val slave_frag = LazyModule(new TLFragmenter(beatBytes, blockBytes)) + private val slave_ww = LazyModule(new TLWidthWidget(beatBytes)) + + xbar.node :=* master_buffer.node + slave_buffer.node :*= xbar.node + slave_frag.node :*= slave_buffer.node + slave_ww.node :*= slave_buffer.node + + protected def outwardNode: TLOutwardNode = xbar.node + protected def outwardBufNode: TLOutwardNode = slave_buffer.node + protected def outwardFragNode: TLOutwardNode = slave_frag.node + protected def outwardWWNode: TLOutwardNode = slave_ww.node + protected def inwardNode: TLInwardNode = xbar.node + protected def inwardBufNode: TLInwardNode = master_buffer.node + + def edgesIn = xbar.node.edgesIn + + def bufferFromMasters: TLInwardNode = inwardBufNode + + def bufferToSlaves: TLOutwardNode = outwardBufNode + + def toAsyncSlaves(sync: Int = 3): TLAsyncOutwardNode = { + val source = LazyModule(new TLAsyncCrossingSource(sync)) + source.node :*= outwardNode + source.node + } + + def toRationalSlaves: TLRationalOutwardNode = { + val source = LazyModule(new TLRationalCrossingSource()) + source.node :*= outwardNode + source.node + } + + def toVariableWidthSlaves: TLOutwardNode = outwardFragNode + + def toAsyncVariableWidthSlaves(sync: Int = 3): TLAsyncOutwardNode = { + val source = LazyModule(new TLAsyncCrossingSource(sync)) + source.node :*= outwardFragNode + source.node + } + + def toRationalVariableWidthSlaves: TLRationalOutwardNode = { + val source = LazyModule(new TLRationalCrossingSource()) + source.node :*= outwardFragNode + source.node + } + + def toFixedWidthSlaves: TLOutwardNode = outwardWWNode + + def toAsyncFixedWidthSlaves(sync: Int = 3): TLAsyncOutwardNode = { + val source = LazyModule(new TLAsyncCrossingSource(sync)) + source.node := outwardWWNode + source.node + } + + def toRationalFixedWidthSlaves: TLRationalOutwardNode = { + val source = LazyModule(new TLRationalCrossingSource()) + source.node :*= outwardWWNode + source.node + } + + def toFixedWidthPorts: TLOutwardNode = outwardWWNode // TODO, do/don't buffer here; knowing we will after the necessary port conversions + +} diff --git a/src/main/scala/tilelink/Parameters.scala b/src/main/scala/tilelink/Parameters.scala index a33f4501..716b5284 100644 --- a/src/main/scala/tilelink/Parameters.scala +++ b/src/main/scala/tilelink/Parameters.scala @@ -76,7 +76,9 @@ case class TLManagerPortParameters( require (endSinkId >= 0) require (minLatency >= 0) - def requireFifo() = managers.foreach { m =>require (m.fifoId == Some(0)) } + def requireFifo() = managers.foreach { m => + require(m.fifoId == Some(0), s"${m.name} had fifoId ${m.fifoId}, which was not 0 (${managers.map(s => (s.name, s.fifoId))}) ") + } // Bounds on required sizes def maxAddress = managers.map(_.maxAddress).max @@ -315,7 +317,7 @@ case class TLEdgeParameters( val maxLgSize = log2Ceil(maxTransfer) // Sanity check the link... - require (maxTransfer >= manager.beatBytes) + require (maxTransfer >= manager.beatBytes, s"Link's max transfer (${maxTransfer}) < ${manager.managers.map(_.name)}'s beatBytes (${manager.beatBytes})") val bundle = TLBundleParameters(client, manager) } diff --git a/src/main/scala/tilelink/package.scala b/src/main/scala/tilelink/package.scala index 8a319b7e..e0a165b7 100644 --- a/src/main/scala/tilelink/package.scala +++ b/src/main/scala/tilelink/package.scala @@ -9,9 +9,13 @@ package object tilelink { type TLInwardNode = InwardNodeHandle[TLClientPortParameters, TLManagerPortParameters, TLBundle] type TLOutwardNode = OutwardNodeHandle[TLClientPortParameters, TLManagerPortParameters, TLBundle] + type TLAsyncInwardNode = InwardNodeHandle[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncBundle] type TLAsyncOutwardNode = OutwardNodeHandle[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncBundle] + type TLRationalInwardNode = InwardNodeHandle[TLRationalClientPortParameters, TLRationalManagerPortParameters, TLRationalBundle] type TLRationalOutwardNode = OutwardNodeHandle[TLRationalClientPortParameters, TLRationalManagerPortParameters, TLRationalBundle] - type IntOutwardNode = OutwardNodeHandle[IntSourcePortParameters, IntSinkPortParameters, Vec[Bool]] type TLMixedNode = MixedNode[TLClientPortParameters, TLManagerPortParameters, TLEdgeIn, TLBundle, TLClientPortParameters, TLManagerPortParameters, TLEdgeOut, TLBundle] + + type IntInwardNode = InwardNodeHandle[IntSourcePortParameters, IntSinkPortParameters, Vec[Bool]] + type IntOutwardNode = OutwardNodeHandle[IntSourcePortParameters, IntSinkPortParameters, Vec[Bool]] } diff --git a/src/main/scala/unittest/Configs.scala b/src/main/scala/unittest/Configs.scala index 190977ac..1af3bb80 100644 --- a/src/main/scala/unittest/Configs.scala +++ b/src/main/scala/unittest/Configs.scala @@ -6,8 +6,8 @@ import Chisel._ import freechips.rocketchip.amba.ahb._ import freechips.rocketchip.amba.apb._ import freechips.rocketchip.amba.axi4._ -import freechips.rocketchip.chip.{BaseConfig, BasePlatformConfig} import freechips.rocketchip.config._ +import freechips.rocketchip.coreplex.{BaseCoreplexConfig} import freechips.rocketchip.devices.tilelink._ import freechips.rocketchip.tilelink._ @@ -77,7 +77,7 @@ class WithTLXbarUnitTests extends Config((site, here, up) => { Module(new TLMulticlientXbarTest(4,4, txns=2*txns, timeout=timeout)) ) } }) -class AMBAUnitTestConfig extends Config(new WithAMBAUnitTests ++ new WithTestDuration(10) ++ new BasePlatformConfig) -class TLSimpleUnitTestConfig extends Config(new WithTLSimpleUnitTests ++ new WithTestDuration(10) ++ new BasePlatformConfig) -class TLWidthUnitTestConfig extends Config(new WithTLWidthUnitTests ++ new WithTestDuration(10) ++ new BasePlatformConfig) -class TLXbarUnitTestConfig extends Config(new WithTLXbarUnitTests ++ new WithTestDuration(10) ++ new BasePlatformConfig) +class AMBAUnitTestConfig extends Config(new WithAMBAUnitTests ++ new WithTestDuration(10) ++ new BaseCoreplexConfig) +class TLSimpleUnitTestConfig extends Config(new WithTLSimpleUnitTests ++ new WithTestDuration(10) ++ new BaseCoreplexConfig) +class TLWidthUnitTestConfig extends Config(new WithTLWidthUnitTests ++ new WithTestDuration(10) ++ new BaseCoreplexConfig) +class TLXbarUnitTestConfig extends Config(new WithTLXbarUnitTests ++ new WithTestDuration(10) ++ new BaseCoreplexConfig) diff --git a/src/main/scala/util/GeneratorUtils.scala b/src/main/scala/util/GeneratorUtils.scala index 98b3a359..572ed632 100644 --- a/src/main/scala/util/GeneratorUtils.scala +++ b/src/main/scala/util/GeneratorUtils.scala @@ -6,7 +6,7 @@ import Chisel._ import chisel3.internal.firrtl.Circuit import chisel3.experimental.{RawModule} // TODO: better job of Makefrag generation for non-RocketChip testing platforms -import freechips.rocketchip.chip.{TestGeneration, DefaultTestSuites} +import freechips.rocketchip.system.{TestGeneration, DefaultTestSuites} import freechips.rocketchip.config._ import freechips.rocketchip.diplomacy.LazyModule import java.io.{File, FileWriter} diff --git a/src/main/scala/util/Misc.scala b/src/main/scala/util/Misc.scala index 7227802f..16fb4f98 100644 --- a/src/main/scala/util/Misc.scala +++ b/src/main/scala/util/Misc.scala @@ -21,6 +21,11 @@ class ParameterizedBundle(implicit p: Parameters) extends Bundle { } } +trait Clocked extends Bundle { + val clock = Clock() + val reset = Bool() +} + object DecoupledHelper { def apply(rvs: Bool*) = new DecoupledHelper(rvs) }