rocketchip: top-level systems are now multi-IO modules
Cake pattern only 2 layers instead of 3. Standardized naming convention. Comments for periphery mix-ins. Testharnesses use new periphery helper methods.
This commit is contained in:
		| @@ -9,13 +9,8 @@ import rocketchip._ | ||||
| import util._ | ||||
|  | ||||
| class TestHarness(implicit p: Parameters) extends Module { | ||||
|   val io = new Bundle { | ||||
|     val success = Bool(OUTPUT) | ||||
|   } | ||||
|  | ||||
|   val io = new Bundle { val success = Bool(OUTPUT) } | ||||
|   val dut = Module(LazyModule(new GroundTestTop).module) | ||||
|   io.success := dut.io.success | ||||
|  | ||||
|   val channels = p(coreplex.BankedL2Config).nMemoryChannels | ||||
|   if (channels > 0) Module(LazyModule(new SimAXIMem(channels)).module).io.axi4 <> dut.io.mem_axi4 | ||||
|   io.success := dut.io_success | ||||
|   dut.connectSimAXIMem() | ||||
| } | ||||
|   | ||||
| @@ -3,15 +3,14 @@ | ||||
| package groundtest | ||||
|  | ||||
| import Chisel._ | ||||
| import config._ | ||||
| import diplomacy._ | ||||
| import coreplex._ | ||||
| import config.Parameters | ||||
| import diplomacy.LazyModule | ||||
| import rocketchip._ | ||||
|  | ||||
| class GroundTestTop(implicit p: Parameters) extends BaseTop | ||||
|     with PeripheryMasterAXI4Mem | ||||
|     with PeripheryTestRAM { | ||||
|   override lazy val module = new GroundTestTopModule(this, () => new GroundTestTopBundle(this)) | ||||
| class GroundTestTop(implicit p: Parameters) extends BaseSystem | ||||
|     with HasPeripheryMasterAXI4MemPort | ||||
|     with HasPeripheryTestRAMSlave { | ||||
|   override lazy val module = new GroundTestTopModule(this) | ||||
|  | ||||
|   val coreplex = LazyModule(new GroundTestCoreplex) | ||||
|  | ||||
| @@ -20,14 +19,8 @@ class GroundTestTop(implicit p: Parameters) extends BaseTop | ||||
|   (mem zip coreplex.mem) foreach { case (xbar, channel) => xbar.node :=* channel } | ||||
| } | ||||
|  | ||||
| class GroundTestTopBundle[+L <: GroundTestTop](_outer: L) extends BaseTopBundle(_outer) | ||||
|     with PeripheryMasterAXI4MemBundle | ||||
|     with PeripheryTestRAMBundle { | ||||
|   val success = Bool(OUTPUT) | ||||
| } | ||||
|  | ||||
| class GroundTestTopModule[+L <: GroundTestTop, +B <: GroundTestTopBundle[L]](_outer: L, _io: () => B) extends BaseTopModule(_outer, _io) | ||||
|     with PeripheryMasterAXI4MemModule | ||||
|     with PeripheryTestRAMModule { | ||||
|   io.success := outer.coreplex.module.io.success | ||||
| class GroundTestTopModule[+L <: GroundTestTop](_outer: L) extends BaseSystemModule(_outer) | ||||
|     with HasPeripheryMasterAXI4MemPortModuleImp { | ||||
|   val io_success = IO(Bool(OUTPUT)) | ||||
|   io_success := outer.coreplex.module.io.success | ||||
| } | ||||
|   | ||||
| @@ -1,71 +0,0 @@ | ||||
| // See LICENSE.SiFive for license details. | ||||
|  | ||||
| package rocketchip | ||||
|  | ||||
| import Chisel._ | ||||
| import config._ | ||||
| import junctions._ | ||||
| import diplomacy._ | ||||
| import uncore.tilelink._ | ||||
| import uncore.tilelink2._ | ||||
| import uncore.devices._ | ||||
| import util._ | ||||
| import rocket._ | ||||
|  | ||||
| /** BareTop is the root class for creating a top-level RTL module */ | ||||
| abstract class BareTop(implicit p: Parameters) extends LazyModule { | ||||
|   ElaborationArtefacts.add("graphml", graphML) | ||||
| } | ||||
|  | ||||
| abstract class BareTopBundle[+L <: BareTop](_outer: L) extends GenericParameterizedBundle(_outer) { | ||||
|   val outer = _outer | ||||
|   implicit val p = outer.p | ||||
| } | ||||
|  | ||||
| abstract class BareTopModule[+L <: BareTop, +B <: BareTopBundle[L]](_outer: L, _io: () => B) extends LazyMultiIOModuleImp(_outer) { | ||||
|   val outer = _outer | ||||
|   val io = IO(_io()) | ||||
| } | ||||
|  | ||||
| /** HasTopLevelNetworks provides buses that will serve as attachment points, | ||||
|   * for use in sub-traits that connect individual agents or external ports. | ||||
|   */ | ||||
| trait HasTopLevelNetworks extends HasPeripheryParameters { | ||||
|   val module: HasTopLevelNetworksModule | ||||
|  | ||||
|   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))) | ||||
| } | ||||
|  | ||||
| trait HasTopLevelNetworksBundle extends HasPeripheryParameters { | ||||
|   val outer: HasTopLevelNetworks | ||||
| } | ||||
|  | ||||
| trait HasTopLevelNetworksModule extends HasPeripheryParameters { | ||||
|   val outer: HasTopLevelNetworks | ||||
|   val io: HasTopLevelNetworksBundle | ||||
| } | ||||
|  | ||||
| /** Base Top class with no peripheral devices or ports added */ | ||||
| abstract class BaseTop(implicit p: Parameters) extends BareTop | ||||
|     with HasTopLevelNetworks { | ||||
|   override val module: BaseTopModule[BaseTop, BaseTopBundle[BaseTop]] | ||||
| } | ||||
|  | ||||
| abstract class BaseTopBundle[+L <: BaseTop](_outer: L) extends BareTopBundle(_outer) | ||||
|     with HasTopLevelNetworksBundle | ||||
|  | ||||
| abstract class BaseTopModule[+L <: BaseTop, +B <: BaseTopBundle[L]](_outer: L, _io: () => B) extends BareTopModule(_outer, _io) | ||||
|     with HasTopLevelNetworksModule | ||||
| @@ -7,52 +7,34 @@ import config._ | ||||
| import junctions._ | ||||
| import rocketchip._ | ||||
|  | ||||
| /** Example Top with Periphery (w/o coreplex) */ | ||||
| abstract class ExampleTop(implicit p: Parameters) extends BaseTop | ||||
|     with PeripheryAsyncExtInterrupts | ||||
|     with PeripheryErrorSlave | ||||
|     with PeripheryMasterAXI4Mem | ||||
|     with PeripheryMasterAXI4MMIO | ||||
|     with PeripherySlaveAXI4 { | ||||
|   override lazy val module = new ExampleTopModule(this, () => new ExampleTopBundle(this)) | ||||
| /** 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 ExampleTopBundle[+L <: ExampleTop](_outer: L) extends BaseTopBundle(_outer) | ||||
|     with PeripheryExtInterruptsBundle | ||||
|     with PeripheryErrorSlaveBundle | ||||
|     with PeripheryMasterAXI4MemBundle | ||||
|     with PeripheryMasterAXI4MMIOBundle | ||||
|     with PeripherySlaveAXI4Bundle | ||||
| class ExampleSystemModule[+L <: ExampleSystem](_outer: L) extends BaseSystemModule(_outer) | ||||
|     with HasPeripheryExtInterruptsModuleImp | ||||
|     with HasPeripheryMasterAXI4MemPortModuleImp | ||||
|     with HasPeripheryMasterAXI4MMIOPortModuleImp | ||||
|     with HasPeripherySlaveAXI4PortModuleImp | ||||
|  | ||||
| class ExampleTopModule[+L <: ExampleTop, +B <: ExampleTopBundle[L]](_outer: L, _io: () => B) extends BaseTopModule(_outer, _io) | ||||
|     with PeripheryExtInterruptsModule | ||||
|     with PeripheryErrorSlaveModule | ||||
|     with PeripheryMasterAXI4MemModule | ||||
|     with PeripheryMasterAXI4MMIOModule | ||||
|     with PeripherySlaveAXI4Module | ||||
|  | ||||
| class ExampleRocketTop(implicit p: Parameters) extends ExampleTop | ||||
|     with PeripheryBootROM | ||||
|     with PeripheryZero | ||||
|     with PeripheryDebug | ||||
|     with PeripheryCounter | ||||
|     with HardwiredResetVector | ||||
|     with RocketPlexMaster { | ||||
|   override lazy val module = new ExampleRocketTopModule(this, () => new ExampleRocketTopBundle(this)) | ||||
| /** 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 ExampleRocketTopBundle[+L <: ExampleRocketTop](_outer: L) extends ExampleTopBundle(_outer) | ||||
|     with PeripheryBootROMBundle | ||||
|     with PeripheryZeroBundle | ||||
|     with PeripheryDebugBundle | ||||
|     with PeripheryCounterBundle | ||||
|     with HardwiredResetVectorBundle | ||||
|     with RocketPlexMasterBundle | ||||
|  | ||||
| class ExampleRocketTopModule[+L <: ExampleRocketTop, +B <: ExampleRocketTopBundle[L]](_outer: L, _io: () => B) extends ExampleTopModule(_outer, _io) | ||||
|     with PeripheryBootROMModule | ||||
|     with PeripheryZeroModule | ||||
|     with PeripheryDebugModule | ||||
|     with PeripheryCounterModule | ||||
|     with HardwiredResetVectorModule | ||||
|     with RocketPlexMasterModule | ||||
| class ExampleRocketTopModule[+L <: ExampleRocketTop](_outer: L) extends ExampleSystemModule(_outer) | ||||
|     with HasPeripheryBootROMModuleImp | ||||
|     with HasPeripheryDebugModuleImp | ||||
|     with HasPeripheryRTCCounterModuleImp | ||||
|     with HasRocketPlexMasterModuleImp | ||||
|   | ||||
| @@ -6,12 +6,8 @@ import Chisel._ | ||||
| import config._ | ||||
| import coreplex._ | ||||
| import diplomacy._ | ||||
| import tile.XLen | ||||
| import uncore.tilelink2._ | ||||
| import uncore.axi4._ | ||||
| import uncore.converters._ | ||||
| import uncore.devices._ | ||||
| import uncore.util._ | ||||
| import util._ | ||||
| import scala.math.{min,max} | ||||
|  | ||||
| @@ -47,80 +43,96 @@ trait HasPeripheryParameters { | ||||
|   def cacheBlockBytes = p(CacheBlockBytes) | ||||
|   def peripheryBusArithmetic = p(PeripheryBusArithmetic) | ||||
|   def nMemoryChannels = p(coreplex.BankedL2Config).nMemoryChannels | ||||
|   def nExtInterrupts = p(NExtTopInterrupts) | ||||
| } | ||||
|  | ||||
| ///// | ||||
| abstract trait PeripheryExtInterrupts { | ||||
|   this: HasTopLevelNetworks => | ||||
| /** 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/offchip-interrupts", describeInterrupts(resources)) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   val nExtInterrupts = p(NExtTopInterrupts) | ||||
|   val extInterrupts = IntInternalInputNode(IntSourcePortSimple(num = nExtInterrupts, resources = device.int)) | ||||
|  | ||||
| } | ||||
|  | ||||
| trait PeripheryExtInterruptsBundle { | ||||
|   this: HasTopLevelNetworksBundle { | ||||
|     val outer: PeripheryExtInterrupts | ||||
|   } => | ||||
|   val interrupts = UInt(INPUT, width = outer.nExtInterrupts) | ||||
| } | ||||
|  | ||||
| trait PeripheryExtInterruptsModule { | ||||
|   this: HasTopLevelNetworksModule { | ||||
|     val outer: PeripheryExtInterrupts | ||||
|     val io: PeripheryExtInterruptsBundle | ||||
|   } => | ||||
|   outer.extInterrupts.bundleIn.flatten.zipWithIndex.foreach { case(o, i) => o := io.interrupts(i) } | ||||
| } | ||||
|  | ||||
| // This trait should be used if the External Interrupts have NOT | ||||
| // already been synchronized | ||||
| // to the Periphery (PLIC) Clock. | ||||
|  | ||||
| trait PeripheryAsyncExtInterrupts extends PeripheryExtInterrupts { | ||||
|   this: HasTopLevelNetworks => | ||||
|  | ||||
| /** 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 PeripherySyncExtInterrupts extends PeripheryExtInterrupts { | ||||
|   this: HasTopLevelNetworks => | ||||
|  | ||||
| /** 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)) | ||||
|  | ||||
| trait PeripheryMasterAXI4Mem { | ||||
|   this: HasTopLevelNetworks => | ||||
|   val module: PeripheryMasterAXI4MemModule | ||||
|   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 lineBytes = p(CacheBlockBytes) | ||||
|   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 * lineBytes, ~((channels-1) * lineBytes)) | ||||
|     val filter = AddressSet(channel * blockBytes, ~((channels-1) * blockBytes)) | ||||
|  | ||||
|     AXI4SlavePortParameters( | ||||
|       slaves = Seq(AXI4SlaveParameters( | ||||
| @@ -148,56 +160,22 @@ trait PeripheryMasterAXI4Mem { | ||||
|   } | ||||
| } | ||||
|  | ||||
| trait PeripheryMasterAXI4MemBundle { | ||||
|   this: HasTopLevelNetworksBundle { | ||||
|     val outer: PeripheryMasterAXI4Mem | ||||
|   } => | ||||
|   val mem_axi4 = outer.mem_axi4.bundleOut | ||||
| } | ||||
|  | ||||
| trait PeripheryMasterAXI4MemModule { | ||||
|   this: HasTopLevelNetworksModule { | ||||
|     val outer: PeripheryMasterAXI4Mem | ||||
|     val io: PeripheryMasterAXI4MemBundle | ||||
|   } => | ||||
| } | ||||
|  | ||||
| ///// | ||||
|  | ||||
| trait PeripheryZero { | ||||
|   this: HasTopLevelNetworks => | ||||
|   val module: PeripheryZeroModule | ||||
|  | ||||
|   private val config = p(ZeroConfig) | ||||
|   private val address = AddressSet(config.base, config.size-1) | ||||
|   private val lineBytes = p(CacheBlockBytes) | ||||
|  | ||||
|   val zeros = mem map { case xbar => | ||||
|     val zero = LazyModule(new TLZero(address, beatBytes = config.beatBytes)) | ||||
|     zero.node := TLFragmenter(config.beatBytes, lineBytes)(xbar.node) | ||||
|     zero | ||||
| /** 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 | ||||
|   } | ||||
| } | ||||
|  | ||||
| trait PeripheryZeroBundle { | ||||
|   this: HasTopLevelNetworksBundle { | ||||
|     val outer: PeripheryZero | ||||
|   } => | ||||
| /** 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) | ||||
| } | ||||
|  | ||||
| trait PeripheryZeroModule { | ||||
|   this: HasTopLevelNetworksModule { | ||||
|     val outer: PeripheryZero | ||||
|     val io: PeripheryZeroBundle | ||||
|   } => | ||||
| } | ||||
|  | ||||
| ///// | ||||
|  | ||||
| // PeripheryMasterAXI4MMIO is an example, make your own cake pattern like this one. | ||||
| trait PeripheryMasterAXI4MMIO { | ||||
|   this: HasTopLevelNetworks => | ||||
|  | ||||
| /** 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 SimpleDevice("mmio", Nil) | ||||
|   val mmio_axi4 = AXI4BlindOutputNode(Seq(AXI4SlavePortParameters( | ||||
| @@ -219,25 +197,22 @@ trait PeripheryMasterAXI4MMIO { | ||||
|     socBus.node)))))) | ||||
| } | ||||
|  | ||||
| trait PeripheryMasterAXI4MMIOBundle { | ||||
|   this: HasTopLevelNetworksBundle { | ||||
|     val outer: PeripheryMasterAXI4MMIO | ||||
|   } => | ||||
|   val mmio_axi4 = outer.mmio_axi4.bundleOut | ||||
| /** 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 | ||||
|   } | ||||
| } | ||||
|  | ||||
| trait PeripheryMasterAXI4MMIOModule { | ||||
|   this: HasTopLevelNetworksModule { | ||||
|     val outer: PeripheryMasterAXI4MMIO | ||||
|     val io: PeripheryMasterAXI4MMIOBundle | ||||
|   } => | ||||
|   // nothing to do | ||||
| /** 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) | ||||
| } | ||||
|  | ||||
| ///// | ||||
|  | ||||
| // PeripherySlaveAXI4 is an example, make your own cake pattern like this one. | ||||
| trait PeripherySlaveAXI4 extends HasTopLevelNetworks { | ||||
| /** 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( | ||||
| @@ -254,23 +229,28 @@ trait PeripherySlaveAXI4 extends HasTopLevelNetworks { | ||||
|     l2FrontendAXI4Node))))) | ||||
| } | ||||
|  | ||||
| trait PeripherySlaveAXI4Bundle extends HasTopLevelNetworksBundle { | ||||
|   val outer: PeripherySlaveAXI4 | ||||
|   val l2_frontend_bus_axi4 = outer.l2FrontendAXI4Node.bundleIn | ||||
| /** 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) | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| trait PeripherySlaveAXI4Module extends HasTopLevelNetworksModule { | ||||
|   val outer: PeripherySlaveAXI4 | ||||
|   val io: PeripherySlaveAXI4Bundle | ||||
|   // nothing to do | ||||
| /** 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) | ||||
| } | ||||
|  | ||||
| ///// | ||||
|  | ||||
| // Add an external TL-UL slave | ||||
| trait PeripheryMasterTLMMIO { | ||||
|   this: HasTopLevelNetworks => | ||||
|  | ||||
| /** 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 SimpleDevice("mmio", Nil) | ||||
|   val mmio_tl = TLBlindOutputNode(Seq(TLManagerPortParameters( | ||||
| @@ -290,25 +270,30 @@ trait PeripheryMasterTLMMIO { | ||||
|     socBus.node))) | ||||
| } | ||||
|  | ||||
| trait PeripheryMasterTLMMIOBundle { | ||||
|   this: HasTopLevelNetworksBundle { | ||||
|     val outer: PeripheryMasterTLMMIO | ||||
|   } => | ||||
|   val mmio_tl = outer.mmio_tl.bundleOut | ||||
| /** 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) | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| trait PeripheryMasterTLMMIOModule { | ||||
|   this: HasTopLevelNetworksModule { | ||||
|     val outer: PeripheryMasterTLMMIO | ||||
|     val io: PeripheryMasterTLMMIOBundle | ||||
|   } => | ||||
|   // nothing to do | ||||
| /** 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) | ||||
| } | ||||
|  | ||||
| ///// | ||||
|  | ||||
| // NOTE: this port is NOT allowed to issue Acquires | ||||
| trait PeripherySlaveTL extends HasTopLevelNetworks { | ||||
| /** 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( | ||||
| @@ -321,105 +306,58 @@ trait PeripherySlaveTL extends HasTopLevelNetworks { | ||||
|     l2FrontendTLNode)) | ||||
| } | ||||
|  | ||||
| trait PeripherySlaveTLBundle extends HasTopLevelNetworksBundle { | ||||
|   val outer: PeripherySlaveTL | ||||
|   val l2_frontend_bus_tl = outer.l2FrontendTLNode.bundleIn | ||||
| /** 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) | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| trait PeripherySlaveTLModule extends HasTopLevelNetworksModule { | ||||
|   val outer: PeripherySlaveTL | ||||
|   val io: PeripherySlaveTLBundle | ||||
|   // nothing to do | ||||
| /** 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. | ||||
|  | ||||
| trait PeripheryBootROM { | ||||
|   this: HasTopLevelNetworks => | ||||
|   val coreplex: CoreplexRISCVPlatform | ||||
| /** Adds a /dev/null slave that generates */ | ||||
| trait HasPeripheryZeroSlave extends HasSystemNetworks { | ||||
|   private val config = p(ZeroConfig) | ||||
|   private val address = AddressSet(config.base, config.size-1) | ||||
|   private val blockBytes = p(CacheBlockBytes) | ||||
|  | ||||
|   private val bootrom_address = 0x10000 | ||||
|   private val bootrom_size = 0x10000 | ||||
|   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) | ||||
|   val zeros = mem map { case xbar => | ||||
|     val zero = LazyModule(new TLZero(address, beatBytes = config.beatBytes)) | ||||
|     zero.node := TLFragmenter(config.beatBytes, blockBytes)(xbar.node) | ||||
|     zero | ||||
|   } | ||||
| } | ||||
|  | ||||
| trait PeripheryBootROMBundle { | ||||
|   this: HasTopLevelNetworksBundle { | ||||
|     val outer: PeripheryBootROM | ||||
|   } => | ||||
| } | ||||
|  | ||||
| trait PeripheryBootROMModule { | ||||
|   this: HasTopLevelNetworksModule { | ||||
|     val outer: PeripheryBootROM | ||||
|     val io: PeripheryBootROMBundle | ||||
|   } => | ||||
| } | ||||
|  | ||||
| ///// | ||||
|  | ||||
| trait PeripheryTestRAM { | ||||
|   this: HasTopLevelNetworks => | ||||
|  | ||||
|   val testram = LazyModule(new TLRAM(AddressSet(0x52000000, 0xfff), true, peripheryBusConfig.beatBytes)) | ||||
|   testram.node := TLFragmenter(peripheryBusConfig.beatBytes, cacheBlockBytes)(peripheryBus.node) | ||||
| } | ||||
|  | ||||
| trait PeripheryTestRAMBundle { | ||||
|   this: HasTopLevelNetworksBundle { | ||||
|     val outer: PeripheryTestRAM | ||||
|   } => | ||||
| } | ||||
|  | ||||
| trait PeripheryTestRAMModule { | ||||
|   this: HasTopLevelNetworksModule { | ||||
|     val outer: PeripheryTestRAM | ||||
|     val io: PeripheryTestRAMBundle | ||||
|   } => | ||||
| } | ||||
|  | ||||
| ///// | ||||
|  | ||||
| trait PeripheryTestBusMaster { | ||||
|   this: HasTopLevelNetworks => | ||||
|   val fuzzer = LazyModule(new TLFuzzer(5000)) | ||||
|   peripheryBus.node := fuzzer.node | ||||
| } | ||||
|  | ||||
| trait PeripheryTestBusMasterBundle { | ||||
|   this: HasTopLevelNetworksBundle { | ||||
|     val outer: PeripheryTestBusMaster | ||||
|   } => | ||||
| } | ||||
|  | ||||
| trait PeripheryTestBusMasterModule { | ||||
|   this: HasTopLevelNetworksModule { | ||||
|     val outer: PeripheryTestBusMaster | ||||
|     val io: PeripheryTestBusMasterBundle | ||||
|   } => | ||||
| } | ||||
|  | ||||
| ///// | ||||
|  | ||||
| trait PeripheryErrorSlave { | ||||
|   this: HasTopLevelNetworks => | ||||
| /** 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)) | ||||
|   error.node := TLFragmenter(peripheryBusConfig.beatBytes, maxXfer)(peripheryBus.node) | ||||
| } | ||||
|  | ||||
| trait PeripheryErrorSlaveBundle { | ||||
|   this: HasTopLevelNetworksBundle { | ||||
|     val outer: PeripheryErrorSlave | ||||
|   } => | ||||
|  | ||||
| /** 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) | ||||
| } | ||||
|  | ||||
| trait PeripheryErrorSlaveModule { | ||||
|   this: HasTopLevelNetworksModule { | ||||
|     val outer: PeripheryErrorSlave | ||||
|     val io: PeripheryErrorSlaveBundle | ||||
|   } => | ||||
| /** Adds a fuzzing master to the system for testing purposes. */ | ||||
| trait HasPeripheryTestFuzzMaster extends HasSystemNetworks { | ||||
|   val fuzzer = LazyModule(new TLFuzzer(5000)) | ||||
|   peripheryBus.node := fuzzer.node | ||||
| } | ||||
|   | ||||
| @@ -4,153 +4,112 @@ package rocketchip | ||||
|  | ||||
| import Chisel._ | ||||
| import config._ | ||||
| import coreplex._ | ||||
| import diplomacy._ | ||||
| import jtag.JTAGIO | ||||
| import uncore.tilelink2._ | ||||
| import uncore.devices._ | ||||
| import util._ | ||||
| import jtag.JTAGIO | ||||
| import coreplex._ | ||||
|  | ||||
| // System with JTAG DTM Instantiated inside. JTAG interface is | ||||
| // exported outside. | ||||
|  | ||||
| trait PeripheryJTAGDTM extends HasTopLevelNetworks { | ||||
|   val module: PeripheryJTAGDTMModule | ||||
| /** 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 | ||||
| } | ||||
|  | ||||
| trait PeripheryJTAGDTMBundle extends HasTopLevelNetworksBundle { | ||||
|   val outer: PeripheryJTAGDTM | ||||
|  | ||||
| /** A wrapper around JTAG providing a reset signal and manufacturer id. */ | ||||
| class SystemJTAGIO extends Bundle { | ||||
|   val jtag = new JTAGIO(hasTRSTn = false).flip | ||||
|   val jtag_reset = Bool(INPUT) | ||||
|   val jtag_mfr_id = UInt(INPUT, 11) | ||||
|  | ||||
|   val reset = Bool(INPUT) | ||||
|   val mfr_id = UInt(INPUT, 11) | ||||
| } | ||||
|  | ||||
| trait PeripheryJTAGDTMModule extends HasTopLevelNetworksModule { | ||||
|   val outer: PeripheryJTAGDTM | ||||
|   val io: PeripheryJTAGDTMBundle | ||||
|  | ||||
|   val dtm = Module (new DebugTransportModuleJTAG(p(DMKey).nDMIAddrSize, p(JtagDTMKey))) | ||||
|   dtm.io.jtag <> io.jtag | ||||
|    | ||||
|   dtm.clock             := io.jtag.TCK | ||||
|   dtm.io.jtag_reset     := io.jtag_reset | ||||
|   dtm.io.jtag_mfr_id    := io.jtag_mfr_id | ||||
|   dtm.reset             := dtm.io.fsmReset | ||||
|  | ||||
|   outer.coreplex.module.io.debug.dmi <> dtm.io.dmi | ||||
|   outer.coreplex.module.io.debug.dmiClock := io.jtag.TCK | ||||
|   outer.coreplex.module.io.debug.dmiReset := ResetCatchAndSync(io.jtag.TCK, io.jtag_reset, "dmiResetCatch") | ||||
|  | ||||
| /** 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) | ||||
| } | ||||
|  | ||||
| // System with Debug Module Interface Only. Any sort of DTM | ||||
| // can be connected outside. DMI Clock and Reset must be provided. | ||||
|  | ||||
| trait PeripheryDMI extends HasTopLevelNetworks { | ||||
|   val module: PeripheryDMIModule | ||||
|   val coreplex: CoreplexRISCVPlatform | ||||
| /** 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 PeripheryDMIBundle extends HasTopLevelNetworksBundle { | ||||
|   val outer: PeripheryDMI | ||||
|  | ||||
|   val debug = new ClockedDMIIO().flip | ||||
| 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 PeripheryDMIModule extends HasTopLevelNetworksModule { | ||||
|   val outer: PeripheryDMI | ||||
|   val io: PeripheryDMIBundle | ||||
| trait HasPeripheryDebugModuleImp extends LazyMultiIOModuleImp with HasPeripheryDebugBundle { | ||||
|   val outer: HasPeripheryDebug | ||||
|  | ||||
|   outer.coreplex.module.io.debug <> io.debug | ||||
| } | ||||
|   val debug = IO(new DebugIO) | ||||
|  | ||||
| // System with DMI or JTAG interface based on a parameter | ||||
|   debug.clockeddmi.foreach { dbg => outer.coreplex.module.io.debug <> dbg } | ||||
|  | ||||
| trait PeripheryDebug extends HasTopLevelNetworks { | ||||
|   val module: PeripheryDebugModule | ||||
|   val coreplex: CoreplexRISCVPlatform | ||||
| } | ||||
|   val dtm = debug.systemjtag.map { sj =>  | ||||
|     val dtm = Module(new DebugTransportModuleJTAG(p(DMKey).nDMIAddrSize, p(JtagDTMKey))) | ||||
|     dtm.io.jtag <> sj.jtag | ||||
|  | ||||
| trait PeripheryDebugBundle extends HasTopLevelNetworksBundle { | ||||
|   val outer: PeripheryDebug | ||||
|  | ||||
|   val debug = (!p(IncludeJtagDTM)).option(new ClockedDMIIO().flip) | ||||
|  | ||||
|   val jtag        = (p(IncludeJtagDTM)).option(new JTAGIO(hasTRSTn = false).flip) | ||||
|   val jtag_reset  = (p(IncludeJtagDTM)).option(Bool(INPUT)) | ||||
|   val jtag_mfr_id = (p(IncludeJtagDTM)).option(UInt(INPUT, 11)) | ||||
|  | ||||
|   val ndreset = Bool(OUTPUT) | ||||
|   val dmactive = Bool(OUTPUT) | ||||
| } | ||||
|  | ||||
| trait PeripheryDebugModule extends HasTopLevelNetworksModule { | ||||
|   val outer: PeripheryDebug | ||||
|   val io: PeripheryDebugBundle | ||||
|  | ||||
|   io.debug.foreach { dbg => outer.coreplex.module.io.debug <> dbg } | ||||
|  | ||||
|   val dtm = if (io.jtag.isDefined) Some[DebugTransportModuleJTAG](Module (new DebugTransportModuleJTAG(p(DMKey).nDMIAddrSize, p(JtagDTMKey)))) else None | ||||
|   dtm.foreach { dtm => | ||||
|     dtm.io.jtag <> io.jtag.get | ||||
|  | ||||
|     dtm.clock          := io.jtag.get.TCK | ||||
|     dtm.io.jtag_reset  := io.jtag_reset.get | ||||
|     dtm.io.jtag_mfr_id := io.jtag_mfr_id.get | ||||
|     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 := io.jtag.get.TCK | ||||
|     outer.coreplex.module.io.debug.dmiReset := ResetCatchAndSync(io.jtag.get.TCK, io.jtag_reset.get, "dmiResetCatch") | ||||
|     outer.coreplex.module.io.debug.dmiClock := sj.jtag.TCK | ||||
|     outer.coreplex.module.io.debug.dmiReset := ResetCatchAndSync(sj.jtag.TCK, sj.reset, "dmiResetCatch") | ||||
|     dtm | ||||
|   } | ||||
|  | ||||
|   io.ndreset  := outer.coreplex.module.io.ndreset | ||||
|   io.dmactive := outer.coreplex.module.io.dmactive | ||||
|  | ||||
|   debug.ndreset  := outer.coreplex.module.io.ndreset | ||||
|   debug.dmactive := outer.coreplex.module.io.dmactive | ||||
| } | ||||
|  | ||||
| /// Real-time clock is based on RTCPeriod relative to Top clock | ||||
|  | ||||
| trait PeripheryCounter extends HasTopLevelNetworks { | ||||
|   val module: PeripheryCounterModule | ||||
|   val coreplex: CoreplexRISCVPlatform | ||||
| /** 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 PeripheryCounterBundle extends HasTopLevelNetworksBundle { | ||||
|   val outer: PeripheryCounter | ||||
| trait HasPeripheryRTCCounterModuleImp extends LazyMultiIOModuleImp { | ||||
|   val outer: HasPeripheryRTCCounter | ||||
|   val period = p(rocketchip.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) | ||||
| } | ||||
|  | ||||
| trait PeripheryCounterModule extends HasTopLevelNetworksModule { | ||||
|   val outer: PeripheryCounter | ||||
|   val io: PeripheryCounterBundle | ||||
| /** Adds a boot ROM that contains the DTB describing the system's coreplex. */ | ||||
| trait HasPeripheryBootROM extends HasSystemNetworks with HasCoreplexRISCVPlatform { | ||||
|   val bootrom_address = 0x10000 | ||||
|   val bootrom_size    = 0x10000 | ||||
|   val bootrom_hang    = 0x10040 | ||||
|   private lazy val bootrom_contents = GenerateBootROM(coreplex.dtb) | ||||
|   val bootrom = LazyModule(new TLROM(bootrom_address, bootrom_size, bootrom_contents, true, peripheryBusConfig.beatBytes)) | ||||
|  | ||||
|   { | ||||
|     val period = p(rocketchip.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) | ||||
|   } | ||||
|   bootrom.node := TLFragmenter(peripheryBusConfig.beatBytes, cacheBlockBytes)(peripheryBus.node) | ||||
| } | ||||
|  | ||||
| /// Coreplex will power-on running at 0x1000 (BootROM) | ||||
|  | ||||
| trait HardwiredResetVector extends HasTopLevelNetworks { | ||||
|   val module: HardwiredResetVectorModule | ||||
|   val coreplex: CoreplexRISCVPlatform | ||||
| } | ||||
|  | ||||
| trait HardwiredResetVectorBundle extends HasTopLevelNetworksBundle { | ||||
|   val outer: HardwiredResetVector | ||||
| } | ||||
|  | ||||
| trait HardwiredResetVectorModule extends HasTopLevelNetworksModule { | ||||
|   val outer: HardwiredResetVector | ||||
|   val io: HardwiredResetVectorBundle | ||||
|  | ||||
|   outer.coreplex.module.io.resetVector := UInt(0x10040) // boot ROM: hang | ||||
| /** Coreplex will power-on running at 0x10040 (BootROM) */ | ||||
| trait HasPeripheryBootROMModuleImp extends LazyMultiIOModuleImp { | ||||
|   val outer: HasPeripheryBootROM | ||||
|   outer.coreplex.module.io.resetVector := UInt(outer.bootrom_hang) | ||||
| } | ||||
|   | ||||
| @@ -4,10 +4,11 @@ package rocketchip | ||||
|  | ||||
| import Chisel._ | ||||
| import coreplex.RocketPlex | ||||
| import diplomacy.LazyModule | ||||
| import diplomacy.{LazyModule, LazyMultiIOModuleImp} | ||||
|  | ||||
| trait RocketPlexMaster extends HasTopLevelNetworks { | ||||
|   val module: RocketPlexMasterModule | ||||
| /** Add a RocketPlex to the system */ | ||||
| trait HasRocketPlexMaster extends HasSystemNetworks with HasCoreplexRISCVPlatform { | ||||
|   val module: HasRocketPlexMasterModuleImp | ||||
|  | ||||
|   val coreplex = LazyModule(new RocketPlex) | ||||
|  | ||||
| @@ -20,15 +21,9 @@ trait RocketPlexMaster extends HasTopLevelNetworks { | ||||
|   (mem zip coreplex.mem) foreach { case (xbar, channel) => xbar.node :=* channel } | ||||
| } | ||||
|  | ||||
| trait RocketPlexMasterBundle extends HasTopLevelNetworksBundle { | ||||
|   val outer: RocketPlexMaster | ||||
| } | ||||
|  | ||||
| trait RocketPlexMasterModule extends HasTopLevelNetworksModule { | ||||
|   val outer: RocketPlexMaster | ||||
|   val io: RocketPlexMasterBundle | ||||
|   val clock: Clock | ||||
|   val reset: Bool | ||||
| trait HasRocketPlexMasterModuleImp extends LazyMultiIOModuleImp { | ||||
|   val outer: HasRocketPlexMaster | ||||
|  | ||||
|   outer.coreplex.module.io.tcrs.foreach { case tcr => | ||||
|     tcr.clock := clock | ||||
|   | ||||
							
								
								
									
										24
									
								
								src/main/scala/rocketchip/System.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/main/scala/rocketchip/System.scala
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| // See LICENSE.SiFive for license details. | ||||
|  | ||||
| package rocketchip | ||||
|  | ||||
| import Chisel._ | ||||
| import config.Parameters | ||||
| import diplomacy._ | ||||
| import util._ | ||||
|  | ||||
| /** 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) | ||||
| @@ -16,30 +16,13 @@ class TestHarness()(implicit p: Parameters) extends Module { | ||||
|   } | ||||
|  | ||||
|   val dut = Module(LazyModule(new ExampleRocketTop).module) | ||||
|   dut.reset := reset | dut.io.ndreset | ||||
|   dut.reset := reset | dut.debug.ndreset | ||||
|  | ||||
|  | ||||
|   dut.io.interrupts := UInt(0) | ||||
|  | ||||
|   val channels = p(coreplex.BankedL2Config).nMemoryChannels | ||||
|   if (channels > 0) Module(LazyModule(new SimAXIMem(channels)).module).io.axi4 <> dut.io.mem_axi4 | ||||
|  | ||||
|   if (!p(IncludeJtagDTM)) { | ||||
|     val dtm = Module(new SimDTM).connect(clock, reset, dut.io.debug.get, io.success) | ||||
|   } else { | ||||
|     val jtag = Module(new JTAGVPI).connect(dut.io.jtag.get, dut.io.jtag_reset.get, reset, io.success) | ||||
|     dut.io.jtag_mfr_id.get := p(JtagDTMKey).idcodeManufId.U(11.W) | ||||
|   } | ||||
|  | ||||
|   val mmio_sim = Module(LazyModule(new SimAXIMem(1, 4096)).module) | ||||
|   mmio_sim.io.axi4 <> dut.io.mmio_axi4 | ||||
|  | ||||
|   val l2_axi4 = dut.io.l2_frontend_bus_axi4(0) | ||||
|   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) | ||||
|   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 { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user