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
This commit is contained in:
		
							
								
								
									
										2
									
								
								Makefrag
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefrag
									
									
									
									
									
								
							@@ -4,7 +4,7 @@ $(error Please set environment variable RISCV. Please take a look at README)
 | 
				
			|||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MODEL ?= TestHarness
 | 
					MODEL ?= TestHarness
 | 
				
			||||||
PROJECT ?= freechips.rocketchip.chip
 | 
					PROJECT ?= freechips.rocketchip.system
 | 
				
			||||||
CFG_PROJECT ?= $(PROJECT)
 | 
					CFG_PROJECT ?= $(PROJECT)
 | 
				
			||||||
CONFIG ?= DefaultConfig
 | 
					CONFIG ?= DefaultConfig
 | 
				
			||||||
# TODO: For now must match rocketchip.Generator
 | 
					# TODO: For now must match rocketchip.Generator
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										26
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								README.md
									
									
									
									
									
								
							@@ -156,9 +156,6 @@ Here is a brief description of what can be found in each package:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
* **amba**
 | 
					* **amba**
 | 
				
			||||||
This RTL package uses diplomacy to generate bus implementations of AMBA protocols, including AXI4, AHB-lite, and APB.
 | 
					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**
 | 
					* **config**
 | 
				
			||||||
This utility package provides Scala interfaces for configuring a generator via a dynamically-scoped
 | 
					This utility package provides Scala interfaces for configuring a generator via a dynamically-scoped
 | 
				
			||||||
parameterization library.
 | 
					parameterization library.
 | 
				
			||||||
@@ -188,6 +185,9 @@ This RTL package contains components that can be combined with cores to construc
 | 
				
			|||||||
* **tilelink**
 | 
					* **tilelink**
 | 
				
			||||||
This RTL package uses diplomacy to generate bus implementations of the TileLink protocol. It also contains a variety
 | 
					This RTL package uses diplomacy to generate bus implementations of the TileLink protocol. It also contains a variety
 | 
				
			||||||
of adapters and protocol converters.
 | 
					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**
 | 
					* **unittest**
 | 
				
			||||||
This utility package contains a framework for generateing synthesizeable hardware testers of individual modules.
 | 
					This utility package contains a framework for generateing synthesizeable hardware testers of individual modules.
 | 
				
			||||||
* **util**
 | 
					* **util**
 | 
				
			||||||
@@ -291,11 +291,11 @@ verilator.
 | 
				
			|||||||
    DefaultConfig.graphml
 | 
					    DefaultConfig.graphml
 | 
				
			||||||
    DefaultConfig.json
 | 
					    DefaultConfig.json
 | 
				
			||||||
    DefaultConfig.memmap.json
 | 
					    DefaultConfig.memmap.json
 | 
				
			||||||
    freechips.rocketchip.chip.DefaultConfig
 | 
					    freechips.rocketchip.system.DefaultConfig
 | 
				
			||||||
    freechips.rocketchip.chip.DefaultConfig.d
 | 
					    freechips.rocketchip.system.DefaultConfig.d
 | 
				
			||||||
    freechips.rocketchip.chip.DefaultConfig.fir
 | 
					    freechips.rocketchip.system.DefaultConfig.fir
 | 
				
			||||||
    freechips.rocketchip.chip.DefaultConfig.v
 | 
					    freechips.rocketchip.system.DefaultConfig.v
 | 
				
			||||||
    $ ls $ROCKETCHIP/emulator/generated-src/freechips.rocketchip.chip.DefaultConfig
 | 
					    $ ls $ROCKETCHIP/emulator/generated-src/freechips.rocketchip.system.DefaultConfig
 | 
				
			||||||
    VTestHarness__1.cpp
 | 
					    VTestHarness__1.cpp
 | 
				
			||||||
    VTestHarness__2.cpp
 | 
					    VTestHarness__2.cpp
 | 
				
			||||||
    VTestHarness__3.cpp
 | 
					    VTestHarness__3.cpp
 | 
				
			||||||
@@ -360,11 +360,11 @@ Top.DefaultConfig.conf file:
 | 
				
			|||||||
    DefaultConfig.graphml
 | 
					    DefaultConfig.graphml
 | 
				
			||||||
    DefaultConfig.json
 | 
					    DefaultConfig.json
 | 
				
			||||||
    DefaultConfig.memmap.json
 | 
					    DefaultConfig.memmap.json
 | 
				
			||||||
    freechips.rocketchip.chip.DefaultConfig.behav_srams.v
 | 
					    freechips.rocketchip.system.DefaultConfig.behav_srams.v
 | 
				
			||||||
    freechips.rocketchip.chip.DefaultConfig.conf
 | 
					    freechips.rocketchip.system.DefaultConfig.conf
 | 
				
			||||||
    freechips.rocketchip.chip.DefaultConfig.d
 | 
					    freechips.rocketchip.system.DefaultConfig.d
 | 
				
			||||||
    freechips.rocketchip.chip.DefaultConfig.fir
 | 
					    freechips.rocketchip.system.DefaultConfig.fir
 | 
				
			||||||
    freechips.rocketchip.chip.DefaultConfig.v
 | 
					    freechips.rocketchip.system.DefaultConfig.v
 | 
				
			||||||
    $ cat $ROCKETCHIP/vsim/generated-src/*.conf
 | 
					    $ cat $ROCKETCHIP/vsim/generated-src/*.conf
 | 
				
			||||||
    name data_arrays_0_ext depth 512 width 256 ports mrw mask_gran 8
 | 
					    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
 | 
					    name tag_array_ext depth 64 width 88 ports mrw mask_gran 22
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,17 +42,17 @@ $(error Set SUITE to the regression suite you want to run)
 | 
				
			|||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifeq ($(SUITE),RocketSuiteA)
 | 
					ifeq ($(SUITE),RocketSuiteA)
 | 
				
			||||||
PROJECT=freechips.rocketchip.chip
 | 
					PROJECT=freechips.rocketchip.system
 | 
				
			||||||
CONFIGS=DefaultConfig
 | 
					CONFIGS=DefaultConfig
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifeq ($(SUITE),RocketSuiteB)
 | 
					ifeq ($(SUITE),RocketSuiteB)
 | 
				
			||||||
PROJECT=freechips.rocketchip.chip
 | 
					PROJECT=freechips.rocketchip.system
 | 
				
			||||||
CONFIGS=DefaultBufferlessConfig
 | 
					CONFIGS=DefaultBufferlessConfig
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifeq ($(SUITE),RocketSuiteC)
 | 
					ifeq ($(SUITE),RocketSuiteC)
 | 
				
			||||||
PROJECT=freechips.rocketchip.chip
 | 
					PROJECT=freechips.rocketchip.system
 | 
				
			||||||
CONFIGS=TinyConfig
 | 
					CONFIGS=TinyConfig
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@ package freechips.rocketchip.amba.axi4
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import Chisel._
 | 
					import Chisel._
 | 
				
			||||||
import freechips.rocketchip.config.Parameters
 | 
					import freechips.rocketchip.config.Parameters
 | 
				
			||||||
import freechips.rocketchip.devices.tilelink.TLError
 | 
					import freechips.rocketchip.devices.tilelink._
 | 
				
			||||||
import freechips.rocketchip.diplomacy._
 | 
					import freechips.rocketchip.diplomacy._
 | 
				
			||||||
import freechips.rocketchip.tilelink._
 | 
					import freechips.rocketchip.tilelink._
 | 
				
			||||||
import freechips.rocketchip.unittest._
 | 
					import freechips.rocketchip.unittest._
 | 
				
			||||||
@@ -98,7 +98,7 @@ class AXI4FuzzSlave()(implicit p: Parameters) extends LazyModule with HasFuzzTar
 | 
				
			|||||||
  val node = AXI4InputNode()
 | 
					  val node = AXI4InputNode()
 | 
				
			||||||
  val xbar = LazyModule(new TLXbar)
 | 
					  val xbar = LazyModule(new TLXbar)
 | 
				
			||||||
  val ram  = LazyModule(new TLRAM(fuzzAddr))
 | 
					  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)
 | 
					  ram.node   := TLFragmenter(4, 16)(xbar.node)
 | 
				
			||||||
  error.node := TLFragmenter(4, 16)(xbar.node)
 | 
					  error.node := TLFragmenter(4, 16)(xbar.node)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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)
 | 
					 | 
				
			||||||
@@ -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
 | 
					 | 
				
			||||||
@@ -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
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -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)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -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
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -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)
 | 
					 | 
				
			||||||
@@ -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)
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -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
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -3,83 +3,133 @@
 | 
				
			|||||||
package freechips.rocketchip.coreplex
 | 
					package freechips.rocketchip.coreplex
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Chisel._
 | 
					import Chisel._
 | 
				
			||||||
 | 
					import freechips.rocketchip.config.Parameters
 | 
				
			||||||
import freechips.rocketchip.config._
 | 
					 | 
				
			||||||
import freechips.rocketchip.diplomacy._
 | 
					import freechips.rocketchip.diplomacy._
 | 
				
			||||||
import freechips.rocketchip.tile.{ XLen, TileInterrupts}
 | 
					import freechips.rocketchip.rocket.PAddrBits
 | 
				
			||||||
import freechips.rocketchip.tilelink._
 | 
					import freechips.rocketchip.tilelink._
 | 
				
			||||||
import freechips.rocketchip.util._
 | 
					import freechips.rocketchip.util._
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Widths of various points in the SoC */
 | 
					/** Enumerates the three types of clock crossing between tiles and system bus */
 | 
				
			||||||
case class TLBusConfig(beatBytes: Int)
 | 
					sealed trait CoreplexClockCrossing
 | 
				
			||||||
case object CBusConfig extends Field[TLBusConfig]
 | 
					case class SynchronousCrossing(params: BufferParams = BufferParams.default) extends CoreplexClockCrossing
 | 
				
			||||||
case object L1toL2Config extends Field[TLBusConfig]
 | 
					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
 | 
					/** BareCoreplex is the root class for creating a coreplex sub-system */
 | 
				
			||||||
case object CacheBlockBytes extends Field[Int]
 | 
					abstract class BareCoreplex(implicit p: Parameters) extends LazyModule with BindingScope {
 | 
				
			||||||
 | 
					  lazy val dts = DTS(bindingTree)
 | 
				
			||||||
/** L2 Broadcast Hub configuration */
 | 
					  lazy val dtb = DTB(dts)
 | 
				
			||||||
case class BroadcastConfig(
 | 
					  lazy val json = JSON(bindingTree)
 | 
				
			||||||
  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
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
case class CoreplexParameters(implicit val p: Parameters) extends HasCoreplexParameters
 | 
					abstract class BareCoreplexModule[+L <: BareCoreplex](_outer: L) extends LazyMultiIOModuleImp(_outer) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
abstract class BareCoreplex(implicit p: Parameters) extends LazyModule with BindingScope
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
abstract class BareCoreplexBundle[+L <: BareCoreplex](_outer: L) extends GenericParameterizedBundle(_outer) {
 | 
					 | 
				
			||||||
  val outer = _outer
 | 
					  val outer = _outer
 | 
				
			||||||
  implicit val p = outer.p
 | 
					  ElaborationArtefacts.add("graphml", outer.graphML)
 | 
				
			||||||
}
 | 
					  ElaborationArtefacts.add("dts", outer.dts)
 | 
				
			||||||
 | 
					  ElaborationArtefacts.add("json", outer.json)
 | 
				
			||||||
abstract class BareCoreplexModule[+L <: BareCoreplex, +B <: BareCoreplexBundle[L]](_outer: L, _io: () => B) extends LazyModuleImp(_outer) {
 | 
					  println(outer.dts)
 | 
				
			||||||
  val outer = _outer
 | 
					 | 
				
			||||||
  val io = _io ()
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Base Coreplex class with no peripheral devices or ports added */
 | 
				
			||||||
abstract class BaseCoreplex(implicit p: Parameters) extends BareCoreplex
 | 
					abstract class BaseCoreplex(implicit p: Parameters) extends BareCoreplex
 | 
				
			||||||
    with CoreplexNetwork
 | 
					    with HasInterruptBus
 | 
				
			||||||
    with BankedL2CoherenceManagers {
 | 
					    with HasSystemBus
 | 
				
			||||||
  override lazy val module = new BaseCoreplexModule(this, () => new BaseCoreplexBundle(this))
 | 
					    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)
 | 
					abstract class BaseCoreplexModule[+L <: BaseCoreplex](_outer: L) extends BareCoreplexModule(_outer) {
 | 
				
			||||||
    with CoreplexNetworkBundle
 | 
					  println("Generated Address Map")
 | 
				
			||||||
    with BankedL2CoherenceManagersBundle
 | 
					  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)
 | 
					  private def collect(path: List[String], value: ResourceValue): List[(String, ResourceAddress)] = {
 | 
				
			||||||
    with CoreplexNetworkModule
 | 
					    value match {
 | 
				
			||||||
    with BankedL2CoherenceManagersModule
 | 
					      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("")
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,6 @@
 | 
				
			|||||||
package freechips.rocketchip.coreplex
 | 
					package freechips.rocketchip.coreplex
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Chisel._
 | 
					import Chisel._
 | 
				
			||||||
 | 
					 | 
				
			||||||
import freechips.rocketchip.config._
 | 
					import freechips.rocketchip.config._
 | 
				
			||||||
import freechips.rocketchip.devices.debug._
 | 
					import freechips.rocketchip.devices.debug._
 | 
				
			||||||
import freechips.rocketchip.devices.tilelink._
 | 
					import freechips.rocketchip.devices.tilelink._
 | 
				
			||||||
@@ -15,6 +14,7 @@ import freechips.rocketchip.tilelink._
 | 
				
			|||||||
import freechips.rocketchip.util._
 | 
					import freechips.rocketchip.util._
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class BaseCoreplexConfig extends Config ((site, here, up) => {
 | 
					class BaseCoreplexConfig extends Config ((site, here, up) => {
 | 
				
			||||||
 | 
					  // Tile parameters
 | 
				
			||||||
  case PAddrBits => 32
 | 
					  case PAddrBits => 32
 | 
				
			||||||
  case PgLevels => if (site(XLen) == 64) 3 /* Sv39 */ else 2 /* Sv32 */
 | 
					  case PgLevels => if (site(XLen) == 64) 3 /* Sv39 */ else 2 /* Sv32 */
 | 
				
			||||||
  case ASIdBits => 0
 | 
					  case ASIdBits => 0
 | 
				
			||||||
@@ -22,19 +22,26 @@ class BaseCoreplexConfig extends Config ((site, here, up) => {
 | 
				
			|||||||
  case ResetVectorBits => site(PAddrBits)
 | 
					  case ResetVectorBits => site(PAddrBits)
 | 
				
			||||||
  case MaxHartIdBits => log2Up(site(RocketTilesKey).size)
 | 
					  case MaxHartIdBits => log2Up(site(RocketTilesKey).size)
 | 
				
			||||||
  case BuildCore => (p: Parameters) => new Rocket()(p)
 | 
					  case BuildCore => (p: Parameters) => new Rocket()(p)
 | 
				
			||||||
 | 
					  case RocketTilesKey =>  Nil // Will be added by partial configs found below
 | 
				
			||||||
 | 
					  // Interconnect parameters
 | 
				
			||||||
  case RocketCrossing => SynchronousCrossing()
 | 
					  case RocketCrossing => SynchronousCrossing()
 | 
				
			||||||
  case RocketTilesKey =>  Nil
 | 
					  case BroadcastParams => BroadcastParams()
 | 
				
			||||||
  case DMKey => DefaultDebugModuleConfig(site(XLen))
 | 
					  case BankedL2Params => BankedL2Params()
 | 
				
			||||||
  case PLICKey => PLICParams()
 | 
					  case SystemBusParams => SystemBusParams(beatBytes = site(XLen)/8, blockBytes = site(CacheBlockBytes))
 | 
				
			||||||
  case ClintKey => ClintParams()
 | 
					  case PeripheryBusParams => PeripheryBusParams(beatBytes = site(XLen)/8, blockBytes = site(CacheBlockBytes))
 | 
				
			||||||
  case CBusConfig => TLBusConfig(beatBytes = site(XLen)/8)
 | 
					  case MemoryBusParams => MemoryBusParams(beatBytes = 8, blockBytes = site(CacheBlockBytes))
 | 
				
			||||||
  case L1toL2Config => TLBusConfig(beatBytes = site(XLen)/8) // increase for more PCIe bandwidth
 | 
					 | 
				
			||||||
  case BootROMFile => "./bootrom/bootrom.img"
 | 
					 | 
				
			||||||
  case BroadcastConfig => BroadcastConfig()
 | 
					 | 
				
			||||||
  case BankedL2Config => BankedL2Config()
 | 
					 | 
				
			||||||
  case CacheBlockBytes => 64
 | 
					  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) => {
 | 
					class WithNBigCores(n: Int) extends Config((site, here, up) => {
 | 
				
			||||||
  case RocketTilesKey => {
 | 
					  case RocketTilesKey => {
 | 
				
			||||||
    val big = RocketTileParams(
 | 
					    val big = RocketTileParams(
 | 
				
			||||||
@@ -43,11 +50,11 @@ class WithNBigCores(n: Int) extends Config((site, here, up) => {
 | 
				
			|||||||
        mulEarlyOut = true,
 | 
					        mulEarlyOut = true,
 | 
				
			||||||
        divEarlyOut = true))),
 | 
					        divEarlyOut = true))),
 | 
				
			||||||
      dcache = Some(DCacheParams(
 | 
					      dcache = Some(DCacheParams(
 | 
				
			||||||
        rowBits = site(L1toL2Config).beatBytes*8,
 | 
					        rowBits = site(SystemBusParams).beatBits,
 | 
				
			||||||
        nMSHRs  = 0,
 | 
					        nMSHRs = 0,
 | 
				
			||||||
        blockBytes = site(CacheBlockBytes))),
 | 
					        blockBytes = site(CacheBlockBytes))),
 | 
				
			||||||
      icache = Some(ICacheParams(
 | 
					      icache = Some(ICacheParams(
 | 
				
			||||||
        rowBits = site(L1toL2Config).beatBytes*8,
 | 
					        rowBits = site(SystemBusParams).beatBits,
 | 
				
			||||||
        blockBytes = site(CacheBlockBytes))))
 | 
					        blockBytes = site(CacheBlockBytes))))
 | 
				
			||||||
    List.fill(n)(big) ++ up(RocketTilesKey, site)
 | 
					    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),
 | 
					      core = RocketCoreParams(useVM = false, fpu = None),
 | 
				
			||||||
      btb = None,
 | 
					      btb = None,
 | 
				
			||||||
      dcache = Some(DCacheParams(
 | 
					      dcache = Some(DCacheParams(
 | 
				
			||||||
        rowBits = site(L1toL2Config).beatBytes*8,
 | 
					        rowBits = site(SystemBusParams).beatBits,
 | 
				
			||||||
        nSets = 64,
 | 
					        nSets = 64,
 | 
				
			||||||
        nWays = 1,
 | 
					        nWays = 1,
 | 
				
			||||||
        nTLBEntries = 4,
 | 
					        nTLBEntries = 4,
 | 
				
			||||||
        nMSHRs = 0,
 | 
					        nMSHRs = 0,
 | 
				
			||||||
        blockBytes = site(CacheBlockBytes))),
 | 
					        blockBytes = site(CacheBlockBytes))),
 | 
				
			||||||
      icache = Some(ICacheParams(
 | 
					      icache = Some(ICacheParams(
 | 
				
			||||||
        rowBits = site(L1toL2Config).beatBytes*8,
 | 
					        rowBits = site(SystemBusParams).beatBits,
 | 
				
			||||||
        nSets = 64,
 | 
					        nSets = 64,
 | 
				
			||||||
        nWays = 1,
 | 
					        nWays = 1,
 | 
				
			||||||
        nTLBEntries = 4,
 | 
					        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) => {
 | 
					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) => {
 | 
					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
 | 
					// 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) => {
 | 
					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.
 | 
					 * DO NOT use this configuration.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
class WithStatelessBridge extends Config((site, here, up) => {
 | 
					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
 | 
					    implicit val p = q
 | 
				
			||||||
    val cork = LazyModule(new TLCacheCork(unsafe = true))
 | 
					    val cork = LazyModule(new TLCacheCork(unsafe = true))
 | 
				
			||||||
    val ww = LazyModule(new TLWidthWidget(p(L1toL2Config).beatBytes))
 | 
					    (cork.node, cork.node)
 | 
				
			||||||
    ww.node :*= cork.node
 | 
					 | 
				
			||||||
    (cork.node, ww.node)
 | 
					 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -208,7 +240,7 @@ class WithFPUWithoutDivSqrt extends Config((site, here, up) => {
 | 
				
			|||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class WithBootROMFile(bootROMFile: String) 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) => {
 | 
					class WithSynchronousRocketTiles extends Config((site, here, up) => {
 | 
				
			||||||
@@ -223,3 +255,49 @@ class WithRationalRocketTiles extends Config((site, here, up) => {
 | 
				
			|||||||
  case RocketCrossing => RationalCrossing()
 | 
					  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
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -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
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										85
									
								
								src/main/scala/coreplex/InterruptBus.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								src/main/scala/coreplex/InterruptBus.scala
									
									
									
									
									
										Normal file
									
								
							@@ -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) }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										75
									
								
								src/main/scala/coreplex/MemoryBus.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								src/main/scala/coreplex/MemoryBus.scala
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										48
									
								
								src/main/scala/coreplex/PeripheryBus.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/main/scala/coreplex/PeripheryBus.scala
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										261
									
								
								src/main/scala/coreplex/Ports.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										261
									
								
								src/main/scala/coreplex/Ports.scala
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -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)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										24
									
								
								src/main/scala/coreplex/RTC.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/main/scala/coreplex/RTC.scala
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										14
									
								
								src/main/scala/coreplex/ResetVector.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/main/scala/coreplex/ResetVector.scala
									
									
									
									
									
										Normal file
									
								
							@@ -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))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										130
									
								
								src/main/scala/coreplex/RocketCoreplex.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								src/main/scala/coreplex/RocketCoreplex.scala
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
				
			||||||
@@ -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
 | 
					 | 
				
			||||||
@@ -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) }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										97
									
								
								src/main/scala/coreplex/SystemBus.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								src/main/scala/coreplex/SystemBus.scala
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -61,11 +61,11 @@ object DsbRegAddrs{
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  // We want DATA to immediately follow PROGBUF so that we can
 | 
					  // We want DATA to immediately follow PROGBUF so that we can
 | 
				
			||||||
  // use them interchangeably.
 | 
					  // 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
 | 
					  // We want abstract to be immediately before PROGBUF
 | 
				
			||||||
  // because we auto-generate 2 instructions.
 | 
					  // because we auto-generate 2 instructions.
 | 
				
			||||||
  def ABSTRACT(cfg:DebugModuleConfig) = PROGBUF(cfg) - 8
 | 
					  def ABSTRACT(cfg:DebugModuleParams) = PROGBUF(cfg) - 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def FLAGS        = 0x400
 | 
					  def FLAGS        = 0x400
 | 
				
			||||||
  def ROMBASE      = 0x800
 | 
					  def ROMBASE      = 0x800
 | 
				
			||||||
@@ -112,7 +112,7 @@ import DebugAbstractCommandType._
 | 
				
			|||||||
  *  supportHartArray : Whether or not to implement the hart array register.
 | 
					  *  supportHartArray : Whether or not to implement the hart array register.
 | 
				
			||||||
  **/
 | 
					  **/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
case class DebugModuleConfig (
 | 
					case class DebugModuleParams (
 | 
				
			||||||
  nDMIAddrSize  : Int = 7,
 | 
					  nDMIAddrSize  : Int = 7,
 | 
				
			||||||
  nProgramBufferWords: Int = 16,
 | 
					  nProgramBufferWords: Int = 16,
 | 
				
			||||||
  nAbstractDataWords : Int = 4,
 | 
					  nAbstractDataWords : Int = 4,
 | 
				
			||||||
@@ -152,17 +152,17 @@ case class DebugModuleConfig (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
object DefaultDebugModuleConfig {
 | 
					object DefaultDebugModuleParams {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def apply(xlen:Int /*TODO , val configStringAddr: Int*/): DebugModuleConfig = {
 | 
					  def apply(xlen:Int /*TODO , val configStringAddr: Int*/): DebugModuleParams = {
 | 
				
			||||||
    new DebugModuleConfig().copy(
 | 
					    new DebugModuleParams().copy(
 | 
				
			||||||
      nAbstractDataWords  = (if (xlen == 32) 1 else if (xlen == 64) 2 else 4)
 | 
					      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
 | 
					// Module Interfaces
 | 
				
			||||||
@@ -192,7 +192,7 @@ class DMIResp( ) extends Bundle {
 | 
				
			|||||||
  *  Therefore it has the 'flipped' version of this.
 | 
					  *  Therefore it has the 'flipped' version of this.
 | 
				
			||||||
  */
 | 
					  */
 | 
				
			||||||
class DMIIO(implicit val p: Parameters) extends ParameterizedBundle()(p) {
 | 
					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()
 | 
					  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){
 | 
					  lazy val module = new LazyModuleImp(this){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    val cfg = p(DMKey)
 | 
					    val cfg = p(DebugModuleParams)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    val nComponents = getNComponents()
 | 
					    val nComponents = getNComponents()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,16 +1,13 @@
 | 
				
			|||||||
// See LICENSE.SiFive for license details.
 | 
					// See LICENSE.SiFive for license details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package freechips.rocketchip.chip
 | 
					package freechips.rocketchip.devices.debug
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Chisel._
 | 
					import Chisel._
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import freechips.rocketchip.config._
 | 
					import freechips.rocketchip.config._
 | 
				
			||||||
import freechips.rocketchip.devices.debug.{DMIConsts, DMIIO, DMIReq, DMIResp}
 | 
					 | 
				
			||||||
import freechips.rocketchip.jtag._
 | 
					import freechips.rocketchip.jtag._
 | 
				
			||||||
import freechips.rocketchip.util._
 | 
					import freechips.rocketchip.util._
 | 
				
			||||||
 | 
					
 | 
				
			||||||
case object IncludeJtagDTM extends Field[Boolean]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
case class JtagDTMConfig (
 | 
					case class JtagDTMConfig (
 | 
				
			||||||
  idcodeVersion    : Int,      // chosen by manuf.
 | 
					  idcodeVersion    : Int,      // chosen by manuf.
 | 
				
			||||||
  idcodePartNum    : Int,      // Chosen by manuf.
 | 
					  idcodePartNum    : Int,      // Chosen by manuf.
 | 
				
			||||||
@@ -63,12 +60,19 @@ class DTMInfo extends Bundle {
 | 
				
			|||||||
  val debugVersion = UInt(4.W)
 | 
					  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)
 | 
					class DebugTransportModuleJTAG(debugAddrBits: Int, c: JtagDTMConfig)
 | 
				
			||||||
  (implicit val p: Parameters) extends Module  {
 | 
					  (implicit val p: Parameters) extends Module  {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  val io = new Bundle {
 | 
					  val io = new Bundle {
 | 
				
			||||||
    val dmi = new DMIIO()(p)
 | 
					    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_reset = Bool(INPUT)
 | 
				
			||||||
    val jtag_mfr_id = UInt(INPUT, 11)
 | 
					    val jtag_mfr_id = UInt(INPUT, 11)
 | 
				
			||||||
    val fsmReset = Bool(OUTPUT)
 | 
					    val fsmReset = Bool(OUTPUT)
 | 
				
			||||||
							
								
								
									
										123
									
								
								src/main/scala/devices/debug/Periphery.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								src/main/scala/devices/debug/Periphery.scala
									
									
									
									
									
										Normal file
									
								
							@@ -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)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										41
									
								
								src/main/scala/devices/tilelink/BootROM.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/main/scala/devices/tilelink/BootROM.scala
									
									
									
									
									
										Normal file
									
								
							@@ -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)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -3,7 +3,8 @@
 | 
				
			|||||||
package freechips.rocketchip.devices.tilelink
 | 
					package freechips.rocketchip.devices.tilelink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Chisel._
 | 
					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.diplomacy._
 | 
				
			||||||
import freechips.rocketchip.regmapper._
 | 
					import freechips.rocketchip.regmapper._
 | 
				
			||||||
import freechips.rocketchip.tile.XLen
 | 
					import freechips.rocketchip.tile.XLen
 | 
				
			||||||
@@ -29,6 +30,8 @@ case class ClintParams(baseAddress: BigInt = 0x02000000)
 | 
				
			|||||||
  def address = AddressSet(baseAddress, ClintConsts.size-1)
 | 
					  def address = AddressSet(baseAddress, ClintConsts.size-1)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					case object ClintParams extends Field[ClintParams]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CoreplexLocalInterrupter(params: ClintParams)(implicit p: Parameters) extends LazyModule
 | 
					class CoreplexLocalInterrupter(params: ClintParams)(implicit p: Parameters) extends LazyModule
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  import ClintConsts._
 | 
					  import ClintConsts._
 | 
				
			||||||
@@ -90,3 +93,9 @@ class CoreplexLocalInterrupter(params: ClintParams)(implicit p: Parameters) exte
 | 
				
			|||||||
      timeOffset       -> makeRegFields(time))
 | 
					      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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,13 +3,21 @@
 | 
				
			|||||||
package freechips.rocketchip.devices.tilelink
 | 
					package freechips.rocketchip.devices.tilelink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Chisel._
 | 
					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.diplomacy._
 | 
				
			||||||
import freechips.rocketchip.tilelink._
 | 
					import freechips.rocketchip.tilelink._
 | 
				
			||||||
import freechips.rocketchip.util._
 | 
					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 device = new SimpleDevice("error-device", Seq("sifive,error0"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  val node = TLManagerNode(Seq(TLManagerPortParameters(
 | 
					  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)
 | 
					    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)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,8 @@ package freechips.rocketchip.devices.tilelink
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import Chisel._
 | 
					import Chisel._
 | 
				
			||||||
import Chisel.ImplicitConversions._
 | 
					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.diplomacy._
 | 
				
			||||||
import freechips.rocketchip.regmapper._
 | 
					import freechips.rocketchip.regmapper._
 | 
				
			||||||
import freechips.rocketchip.tile.XLen
 | 
					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)
 | 
					  def address = AddressSet(baseAddress, PLICConsts.size-1)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					case object PLICParams extends Field[PLICParams]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Platform-Level Interrupt Controller */
 | 
					/** Platform-Level Interrupt Controller */
 | 
				
			||||||
class TLPLIC(params: PLICParams)(implicit p: Parameters) extends LazyModule
 | 
					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
 | 
					      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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,8 @@
 | 
				
			|||||||
package freechips.rocketchip.devices.tilelink
 | 
					package freechips.rocketchip.devices.tilelink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Chisel._
 | 
					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.diplomacy._
 | 
				
			||||||
import freechips.rocketchip.tilelink._
 | 
					import freechips.rocketchip.tilelink._
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -44,3 +45,23 @@ class TLZero(address: AddressSet, resources: Seq[Resource], executable: Boolean
 | 
				
			|||||||
    in.e.ready := Bool(true)
 | 
					    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
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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)
 | 
					  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 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
 | 
					  // meta-data for printing the node graph
 | 
				
			||||||
  protected[diplomacy] def colour  = inner.colour
 | 
					  protected[diplomacy] def colour  = inner.colour
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,15 +4,14 @@
 | 
				
			|||||||
package freechips.rocketchip.groundtest
 | 
					package freechips.rocketchip.groundtest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Chisel._
 | 
					import Chisel._
 | 
				
			||||||
import freechips.rocketchip.chip.{BaseConfig, ExtMem}
 | 
					 | 
				
			||||||
import freechips.rocketchip.config.Config
 | 
					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.rocket.{DCacheParams, PAddrBits}
 | 
				
			||||||
import freechips.rocketchip.tile.{MaxHartIdBits, XLen}
 | 
					import freechips.rocketchip.tile.{MaxHartIdBits, XLen}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Actual testing target Configs */
 | 
					/** 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)
 | 
					class TraceGenBufferlessConfig extends Config(new WithBufferlessBroadcastHub ++ new TraceGenConfig)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -26,8 +25,8 @@ class WithTraceGen(params: Seq[DCacheParams], nReqs: Int = 8192) extends Config(
 | 
				
			|||||||
    addrBag = {
 | 
					    addrBag = {
 | 
				
			||||||
      val nSets = 2
 | 
					      val nSets = 2
 | 
				
			||||||
      val nWays = 1
 | 
					      val nWays = 1
 | 
				
			||||||
      val blockOffset = log2Up(site(CacheBlockBytes))
 | 
					      val blockOffset = site(SystemBusParams).blockOffset
 | 
				
			||||||
      val nBeats = site(CacheBlockBytes)/site(L1toL2Config).beatBytes
 | 
					      val nBeats = site(SystemBusParams).blockBeats
 | 
				
			||||||
      List.tabulate(4 * nWays) { i =>
 | 
					      List.tabulate(4 * nWays) { i =>
 | 
				
			||||||
        Seq.tabulate(nBeats) { j => BigInt((j * 8) + ((i * nSets) << blockOffset)) }
 | 
					        Seq.tabulate(nBeats) { j => BigInt((j * 8) + ((i * nSets) << blockOffset)) }
 | 
				
			||||||
      }.flatten
 | 
					      }.flatten
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,33 +14,43 @@ import scala.math.max
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
case object TileId extends Field[Int]
 | 
					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 tileParams = p(GroundTestTilesKey)
 | 
				
			||||||
  val tiles = tileParams.zipWithIndex.map { case(c, i) => LazyModule(
 | 
					  val tiles = tileParams.zipWithIndex.map { case(c, i) => LazyModule(
 | 
				
			||||||
    c.build(i, p.alterPartial {
 | 
					    c.build(i, p.alterPartial {
 | 
				
			||||||
      case TileKey => c
 | 
					      case TileKey => c
 | 
				
			||||||
      case SharedMemoryTLEdge => tile_splitter.node.edgesIn(0)
 | 
					      case SharedMemoryTLEdge => sbus.edgesIn.head
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
  )}
 | 
					  )}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  val fixer = LazyModule(new TLFIFOFixer)
 | 
					  tiles.foreach { sbus.fromSyncTiles(BufferParams.default) :=* _.masterNode }
 | 
				
			||||||
  tile_splitter.node :=* fixer.node
 | 
					 | 
				
			||||||
  tiles.foreach { fixer.node :=* _.masterNode }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  val pbusRAM = LazyModule(new TLRAM(AddressSet(testRamAddr, 0xffff), false, pbusBeatBytes))
 | 
					  val pbusRAM = LazyModule(new TLRAM(AddressSet(testRamAddr, 0xffff), false, pbus.beatBytes))
 | 
				
			||||||
  pbusRAM.node := TLFragmenter(pbusBeatBytes, pbusBlockBytes)(pbus.node)
 | 
					  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) {
 | 
					class GroundTestCoreplexModule[+L <: GroundTestCoreplex](_outer: L) extends BaseCoreplexModule(_outer)
 | 
				
			||||||
  val success = Bool(OUTPUT)
 | 
					    with HasMasterAXI4MemPortModuleImp {
 | 
				
			||||||
}
 | 
					  val success = IO(Bool(OUTPUT))
 | 
				
			||||||
 | 
					 | 
				
			||||||
class GroundTestCoreplexModule[+L <: GroundTestCoreplex, +B <: GroundTestCoreplexBundle[L]](_outer: L, _io: () => B) extends BaseCoreplexModule(_outer, _io) {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  outer.tiles.zipWithIndex.map { case(t, i) => t.module.io.hartid := UInt(i) }
 | 
					  outer.tiles.zipWithIndex.map { case(t, i) => t.module.io.hartid := UInt(i) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  val status = DebugCombiner(outer.tiles.map(_.module.io.status))
 | 
					  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
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,7 @@ import freechips.rocketchip.diplomacy.LazyModule
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class TestHarness(implicit p: Parameters) extends Module {
 | 
					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)
 | 
					  val dut = Module(LazyModule(new GroundTestCoreplex).module)
 | 
				
			||||||
  io.success := dut.io_success
 | 
					  io.success := dut.success
 | 
				
			||||||
  dut.connectSimAXIMem()
 | 
					  dut.connectSimAXIMem()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,11 +6,8 @@ package freechips.rocketchip.groundtest
 | 
				
			|||||||
import Chisel._
 | 
					import Chisel._
 | 
				
			||||||
import freechips.rocketchip.config._
 | 
					import freechips.rocketchip.config._
 | 
				
			||||||
import freechips.rocketchip.coreplex._
 | 
					import freechips.rocketchip.coreplex._
 | 
				
			||||||
import freechips.rocketchip.diplomacy._
 | 
					import freechips.rocketchip.rocket.{HellaCache, RocketCoreParams}
 | 
				
			||||||
import freechips.rocketchip.rocket._
 | 
					 | 
				
			||||||
import freechips.rocketchip.chip._
 | 
					 | 
				
			||||||
import freechips.rocketchip.tile._
 | 
					import freechips.rocketchip.tile._
 | 
				
			||||||
import freechips.rocketchip.tilelink._
 | 
					 | 
				
			||||||
import scala.collection.mutable.ListBuffer
 | 
					import scala.collection.mutable.ListBuffer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
trait GroundTestTileParams extends TileParams {
 | 
					trait GroundTestTileParams extends TileParams {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -183,9 +183,10 @@ class HellaCacheModule(outer: HellaCache) extends LazyModuleImp(outer)
 | 
				
			|||||||
  val io = new HellaCacheBundle(outer)
 | 
					  val io = new HellaCacheBundle(outer)
 | 
				
			||||||
  val tl_out = io.mem(0)
 | 
					  val tl_out = io.mem(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // IOMSHRs must be FIFO for all regions with effects
 | 
					  private val fifoManagers = edge.manager.managers.filter(TLFIFOFixer.allUncacheable)
 | 
				
			||||||
  edge.manager.managers.foreach { m =>
 | 
					  fifoManagers.foreach { m =>
 | 
				
			||||||
    require (m.fifoId == Some(0) || !TLFIFOFixer.allUncacheable(m))
 | 
					    require (m.fifoId == fifoManagers.head.fifoId,
 | 
				
			||||||
 | 
					      s"IOMSHRs must be FIFO for all regions with effects, but HellaCache sees ${m.nodePath.map(_.name)}")
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
					  // 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 fg = LazyModule(new TLFragmenter(fetchWidth*coreInstBytes, p(CacheBlockBytes), earlyAck=true))
 | 
				
			||||||
  val ww = LazyModule(new TLWidthWidget(xLen/8))
 | 
					  val ww = LazyModule(new TLWidthWidget(xLen/8))
 | 
				
			||||||
  frontend.slaveNode :*= fg.node
 | 
					  frontend.slaveNode connectButDontMonitorSlaves fg.node
 | 
				
			||||||
  fg.node :*= ww.node
 | 
					  fg.node connectButDontMonitorSlaves ww.node
 | 
				
			||||||
  ww.node :*= slaveNode
 | 
					  ww.node connectButDontMonitorSlaves slaveNode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // 2) ScratchpadSlavePort always has a node, but only exists when the HellaCache has a scratchpad
 | 
					  // 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 =>
 | 
					  val scratch = tileParams.dcache.flatMap(d => d.scratch.map(s =>
 | 
				
			||||||
    LazyModule(new ScratchpadSlavePort(AddressSet(s, d.dataScratchpadBytes-1)))))
 | 
					    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 =>
 | 
					  def findScratchpadFromICache: Option[AddressSet] = scratch.map { s =>
 | 
				
			||||||
    val finalNode = frontend.masterNode.edgesOut.head.manager.managers.find(_.nodePath.last == s.node)
 | 
					    val finalNode = frontend.masterNode.edgesOut.head.manager.managers.find(_.nodePath.last == s.node)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										84
									
								
								src/main/scala/system/Configs.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								src/main/scala/system/Configs.scala
									
									
									
									
									
										Normal file
									
								
							@@ -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)
 | 
				
			||||||
							
								
								
									
										26
									
								
								src/main/scala/system/ExampleRocketSystem.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/main/scala/system/ExampleRocketSystem.scala
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
				
			||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
// See LICENSE.SiFive for license details.
 | 
					// See LICENSE.SiFive for license details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package freechips.rocketchip.chip
 | 
					package freechips.rocketchip.system
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import freechips.rocketchip.coreplex.RocketTilesKey
 | 
					import freechips.rocketchip.coreplex.RocketTilesKey
 | 
				
			||||||
import freechips.rocketchip.tile.XLen
 | 
					import freechips.rocketchip.tile.XLen
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
// See LICENSE.Berkeley for license details.
 | 
					// See LICENSE.Berkeley for license details.
 | 
				
			||||||
// See LICENSE.SiFive for license details.
 | 
					// See LICENSE.SiFive for license details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package freechips.rocketchip.chip
 | 
					package freechips.rocketchip.system
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import scala.collection.mutable.LinkedHashSet
 | 
					import scala.collection.mutable.LinkedHashSet
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										22
									
								
								src/main/scala/system/TestHarness.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/main/scala/system/TestHarness.scala
									
									
									
									
									
										Normal file
									
								
							@@ -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)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -21,6 +21,7 @@ trait L1CacheParams {
 | 
				
			|||||||
trait HasL1CacheParameters {
 | 
					trait HasL1CacheParameters {
 | 
				
			||||||
  implicit val p: Parameters
 | 
					  implicit val p: Parameters
 | 
				
			||||||
  val cacheParams: L1CacheParams
 | 
					  val cacheParams: L1CacheParams
 | 
				
			||||||
 | 
					  private val bundleParams = p(SharedMemoryTLEdge).bundle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def cacheBlockBytes = cacheParams.blockBytes
 | 
					  def cacheBlockBytes = cacheParams.blockBytes
 | 
				
			||||||
  def lgCacheBlockBytes = log2Up(cacheBlockBytes)
 | 
					  def lgCacheBlockBytes = log2Up(cacheBlockBytes)
 | 
				
			||||||
@@ -28,7 +29,7 @@ trait HasL1CacheParameters {
 | 
				
			|||||||
  def blockOffBits = lgCacheBlockBytes
 | 
					  def blockOffBits = lgCacheBlockBytes
 | 
				
			||||||
  def idxBits = log2Up(cacheParams.nSets)
 | 
					  def idxBits = log2Up(cacheParams.nSets)
 | 
				
			||||||
  def untagBits = blockOffBits + idxBits
 | 
					  def untagBits = blockOffBits + idxBits
 | 
				
			||||||
  def tagBits = p(PAddrBits) - untagBits
 | 
					  def tagBits = bundleParams.addressBits - untagBits
 | 
				
			||||||
  def nWays = cacheParams.nWays
 | 
					  def nWays = cacheParams.nWays
 | 
				
			||||||
  def wayBits = log2Up(nWays)
 | 
					  def wayBits = log2Up(nWays)
 | 
				
			||||||
  def isDM = nWays == 1
 | 
					  def isDM = nWays == 1
 | 
				
			||||||
@@ -37,7 +38,7 @@ trait HasL1CacheParameters {
 | 
				
			|||||||
  def rowOffBits = log2Up(rowBytes)
 | 
					  def rowOffBits = log2Up(rowBytes)
 | 
				
			||||||
  def nTLBEntries = cacheParams.nTLBEntries
 | 
					  def nTLBEntries = cacheParams.nTLBEntries
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def cacheDataBits = p(SharedMemoryTLEdge).bundle.dataBits
 | 
					  def cacheDataBits = bundleParams.dataBits
 | 
				
			||||||
  def cacheDataBeats = (cacheBlockBytes * 8) / cacheDataBits
 | 
					  def cacheDataBeats = (cacheBlockBytes * 8) / cacheDataBits
 | 
				
			||||||
  def refillCycles = cacheDataBeats
 | 
					  def refillCycles = cacheDataBeats
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,14 +1,13 @@
 | 
				
			|||||||
// See LICENSE.SiFive for license details.
 | 
					// See LICENSE.SiFive for license details.
 | 
				
			||||||
// See LICENSE.Berkeley for license details.
 | 
					// See LICENSE.Berkeley for license details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package freechips.rocketchip.rocket
 | 
					package freechips.rocketchip.tile
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Chisel._
 | 
					import Chisel._
 | 
				
			||||||
 | 
					 | 
				
			||||||
import freechips.rocketchip.config._
 | 
					import freechips.rocketchip.config._
 | 
				
			||||||
import freechips.rocketchip.coreplex._
 | 
					import freechips.rocketchip.coreplex._
 | 
				
			||||||
import freechips.rocketchip.diplomacy._
 | 
					import freechips.rocketchip.diplomacy._
 | 
				
			||||||
import freechips.rocketchip.tile._
 | 
					import freechips.rocketchip.rocket._
 | 
				
			||||||
import freechips.rocketchip.tilelink._
 | 
					import freechips.rocketchip.tilelink._
 | 
				
			||||||
import freechips.rocketchip.util._
 | 
					import freechips.rocketchip.util._
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -164,29 +163,14 @@ class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => ne
 | 
				
			|||||||
  ptw.io.requestor <> ptwPorts
 | 
					  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 rocket = LazyModule(new RocketTile(rtp, hartid))
 | 
				
			||||||
 | 
					  val masterNode: OutputNode[_,_,_,_,_]
 | 
				
			||||||
  val masterNode = TLOutputNode()
 | 
					  val slaveNode: InputNode[_,_,_,_,_]
 | 
				
			||||||
  masterNode :=* rocket.masterNode
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  val slaveNode = new TLInputNode() { override def reverse = true }
 | 
					 | 
				
			||||||
  rocket.slaveNode :*= slaveNode
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Fully async interrupts need synchronizers.
 | 
					 | 
				
			||||||
  // Others need no synchronization.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  val asyncIntNode   = IntInputNode()
 | 
					  val asyncIntNode   = IntInputNode()
 | 
				
			||||||
  val periphIntNode  = IntInputNode()
 | 
					  val periphIntNode  = IntInputNode()
 | 
				
			||||||
  val coreIntNode    = IntInputNode()
 | 
					  val coreIntNode    = IntInputNode()
 | 
				
			||||||
 | 
					 | 
				
			||||||
  val xing = LazyModule(new IntXing(3))
 | 
					 | 
				
			||||||
  xing.intnode := asyncIntNode
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  val intXbar = LazyModule(new IntXbar)
 | 
					  val intXbar = LazyModule(new IntXbar)
 | 
				
			||||||
  intXbar.intnode  := xing.intnode
 | 
					 | 
				
			||||||
  intXbar.intnode  := periphIntNode
 | 
					 | 
				
			||||||
  intXbar.intnode  := coreIntNode
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  rocket.intNode := intXbar.intnode
 | 
					  rocket.intNode := intXbar.intnode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -198,15 +182,30 @@ class SyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters)
 | 
				
			|||||||
      val periphInterrupts = periphIntNode.bundleIn
 | 
					      val periphInterrupts = periphIntNode.bundleIn
 | 
				
			||||||
      val coreInterrupts   = coreIntNode.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.hartid := io.hartid
 | 
				
			||||||
    rocket.module.io.resetVector := io.resetVector
 | 
					    rocket.module.io.resetVector := io.resetVector
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AsyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends LazyModule {
 | 
					class SyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) {
 | 
				
			||||||
  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 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 masterNode = TLAsyncOutputNode()
 | 
				
			||||||
  val source = LazyModule(new TLAsyncCrossingSource)
 | 
					  val source = LazyModule(new TLAsyncCrossingSource)
 | 
				
			||||||
  source.node :=* rocket.masterNode
 | 
					  source.node :=* rocket.masterNode
 | 
				
			||||||
@@ -220,40 +219,17 @@ class AsyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters
 | 
				
			|||||||
  // Fully async interrupts need synchronizers,
 | 
					  // Fully async interrupts need synchronizers,
 | 
				
			||||||
  // as do those coming from the periphery clock.
 | 
					  // as do those coming from the periphery clock.
 | 
				
			||||||
  // Others need no synchronization.
 | 
					  // Others need no synchronization.
 | 
				
			||||||
 | 
					 | 
				
			||||||
  val asyncIntNode   = IntInputNode()
 | 
					 | 
				
			||||||
  val periphIntNode  = IntInputNode()
 | 
					 | 
				
			||||||
  val coreIntNode    = IntInputNode()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  val asyncXing = LazyModule(new IntXing(3))
 | 
					  val asyncXing = LazyModule(new IntXing(3))
 | 
				
			||||||
  val periphXing = LazyModule(new IntXing(3))
 | 
					  val periphXing = LazyModule(new IntXing(3))
 | 
				
			||||||
  asyncXing.intnode := asyncIntNode
 | 
					  asyncXing.intnode := asyncIntNode
 | 
				
			||||||
  periphXing.intnode := periphIntNode
 | 
					  periphXing.intnode := periphIntNode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  val intXbar = LazyModule(new IntXbar)
 | 
					 | 
				
			||||||
  intXbar.intnode  := asyncXing.intnode
 | 
					  intXbar.intnode  := asyncXing.intnode
 | 
				
			||||||
  intXbar.intnode  := periphXing.intnode
 | 
					  intXbar.intnode  := periphXing.intnode
 | 
				
			||||||
  intXbar.intnode  := coreIntNode
 | 
					  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 {
 | 
					class RationalRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) {
 | 
				
			||||||
  val rocket = LazyModule(new RocketTile(rtp, hartid))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  val masterNode = TLRationalOutputNode()
 | 
					  val masterNode = TLRationalOutputNode()
 | 
				
			||||||
  val source = LazyModule(new TLRationalCrossingSource)
 | 
					  val source = LazyModule(new TLRationalCrossingSource)
 | 
				
			||||||
  source.node :=* rocket.masterNode
 | 
					  source.node :=* rocket.masterNode
 | 
				
			||||||
@@ -268,33 +244,12 @@ class RationalRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Paramet
 | 
				
			|||||||
  // Those coming from periphery clock need a
 | 
					  // Those coming from periphery clock need a
 | 
				
			||||||
  // rational synchronizer.
 | 
					  // rational synchronizer.
 | 
				
			||||||
  // Others need no synchronization.
 | 
					  // Others need no synchronization.
 | 
				
			||||||
 | 
					 | 
				
			||||||
  val asyncIntNode   = IntInputNode()
 | 
					 | 
				
			||||||
  val periphIntNode  = IntInputNode()
 | 
					 | 
				
			||||||
  val coreIntNode    = IntInputNode()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  val asyncXing    = LazyModule(new IntXing(3))
 | 
					  val asyncXing    = LazyModule(new IntXing(3))
 | 
				
			||||||
  val periphXing = LazyModule(new IntXing(1))
 | 
					  val periphXing = LazyModule(new IntXing(1))
 | 
				
			||||||
  asyncXing.intnode := asyncIntNode
 | 
					  asyncXing.intnode := asyncIntNode
 | 
				
			||||||
  periphXing.intnode := periphIntNode
 | 
					  periphXing.intnode := periphIntNode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  val intXbar = LazyModule(new IntXbar)
 | 
					 | 
				
			||||||
  intXbar.intnode  := asyncXing.intnode
 | 
					  intXbar.intnode  := asyncXing.intnode
 | 
				
			||||||
  intXbar.intnode  := periphXing.intnode
 | 
					  intXbar.intnode  := periphXing.intnode
 | 
				
			||||||
  intXbar.intnode  := coreIntNode
 | 
					  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
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -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
 | 
					      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)
 | 
					      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
 | 
					      // 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(
 | 
					      m.copy(
 | 
				
			||||||
        supportsArithmetic = if (!arithmetic || !canDoit) m.supportsArithmetic else widen(m.supportsArithmetic),
 | 
					        supportsArithmetic = if (!arithmetic || !canDoit) m.supportsArithmetic else widen(m.supportsArithmetic),
 | 
				
			||||||
        supportsLogical    = if (!logical    || !canDoit) m.supportsLogical    else widen(m.supportsLogical))
 | 
					        supportsLogical    = if (!logical    || !canDoit) m.supportsLogical    else widen(m.supportsLogical))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,8 +29,8 @@ class TLBroadcast(lineBytes: Int, numTrackers: Int = 4, bufferless: Boolean = fa
 | 
				
			|||||||
          if (m.regionType == RegionType.UNCACHED) {
 | 
					          if (m.regionType == RegionType.UNCACHED) {
 | 
				
			||||||
            // The device had better support line transfers
 | 
					            // The device had better support line transfers
 | 
				
			||||||
            val lowerBound = max(m.supportsPutFull.min, m.supportsGet.min)
 | 
					            val lowerBound = max(m.supportsPutFull.min, m.supportsGet.min)
 | 
				
			||||||
            require (!m.supportsPutFull || m.supportsPutFull.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))
 | 
					            require (!m.supportsGet     || m.supportsGet    .contains(lineBytes), s"${m.name} only supports Get(${m.supportsGet}), which does not include $lineBytes")
 | 
				
			||||||
            m.copy(
 | 
					            m.copy(
 | 
				
			||||||
              regionType         = RegionType.TRACKED,
 | 
					              regionType         = RegionType.TRACKED,
 | 
				
			||||||
              supportsAcquireB   = TransferSizes(lowerBound, lineBytes),
 | 
					              supportsAcquireB   = TransferSizes(lowerBound, lineBytes),
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										96
									
								
								src/main/scala/tilelink/Bus.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								src/main/scala/tilelink/Bus.scala
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -76,7 +76,9 @@ case class TLManagerPortParameters(
 | 
				
			|||||||
  require (endSinkId >= 0)
 | 
					  require (endSinkId >= 0)
 | 
				
			||||||
  require (minLatency >= 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
 | 
					  // Bounds on required sizes
 | 
				
			||||||
  def maxAddress  = managers.map(_.maxAddress).max
 | 
					  def maxAddress  = managers.map(_.maxAddress).max
 | 
				
			||||||
@@ -315,7 +317,7 @@ case class TLEdgeParameters(
 | 
				
			|||||||
  val maxLgSize = log2Ceil(maxTransfer)
 | 
					  val maxLgSize = log2Ceil(maxTransfer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Sanity check the link...
 | 
					  // 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)
 | 
					  val bundle = TLBundleParameters(client, manager)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,9 +9,13 @@ package object tilelink
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  type TLInwardNode = InwardNodeHandle[TLClientPortParameters, TLManagerPortParameters, TLBundle]
 | 
					  type TLInwardNode = InwardNodeHandle[TLClientPortParameters, TLManagerPortParameters, TLBundle]
 | 
				
			||||||
  type TLOutwardNode = OutwardNodeHandle[TLClientPortParameters, TLManagerPortParameters, TLBundle]
 | 
					  type TLOutwardNode = OutwardNodeHandle[TLClientPortParameters, TLManagerPortParameters, TLBundle]
 | 
				
			||||||
 | 
					  type TLAsyncInwardNode = InwardNodeHandle[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncBundle]
 | 
				
			||||||
  type TLAsyncOutwardNode = OutwardNodeHandle[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncBundle]
 | 
					  type TLAsyncOutwardNode = OutwardNodeHandle[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncBundle]
 | 
				
			||||||
 | 
					  type TLRationalInwardNode = InwardNodeHandle[TLRationalClientPortParameters, TLRationalManagerPortParameters, TLRationalBundle]
 | 
				
			||||||
  type TLRationalOutwardNode = OutwardNodeHandle[TLRationalClientPortParameters, TLRationalManagerPortParameters, TLRationalBundle]
 | 
					  type TLRationalOutwardNode = OutwardNodeHandle[TLRationalClientPortParameters, TLRationalManagerPortParameters, TLRationalBundle]
 | 
				
			||||||
  type IntOutwardNode = OutwardNodeHandle[IntSourcePortParameters, IntSinkPortParameters, Vec[Bool]]
 | 
					 | 
				
			||||||
  type TLMixedNode = MixedNode[TLClientPortParameters, TLManagerPortParameters, TLEdgeIn, TLBundle,
 | 
					  type TLMixedNode = MixedNode[TLClientPortParameters, TLManagerPortParameters, TLEdgeIn, TLBundle,
 | 
				
			||||||
                               TLClientPortParameters, TLManagerPortParameters, TLEdgeOut, TLBundle]
 | 
					                               TLClientPortParameters, TLManagerPortParameters, TLEdgeOut, TLBundle]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  type IntInwardNode = InwardNodeHandle[IntSourcePortParameters, IntSinkPortParameters, Vec[Bool]]
 | 
				
			||||||
 | 
					  type IntOutwardNode = OutwardNodeHandle[IntSourcePortParameters, IntSinkPortParameters, Vec[Bool]]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,8 +6,8 @@ import Chisel._
 | 
				
			|||||||
import freechips.rocketchip.amba.ahb._
 | 
					import freechips.rocketchip.amba.ahb._
 | 
				
			||||||
import freechips.rocketchip.amba.apb._
 | 
					import freechips.rocketchip.amba.apb._
 | 
				
			||||||
import freechips.rocketchip.amba.axi4._
 | 
					import freechips.rocketchip.amba.axi4._
 | 
				
			||||||
import freechips.rocketchip.chip.{BaseConfig, BasePlatformConfig}
 | 
					 | 
				
			||||||
import freechips.rocketchip.config._
 | 
					import freechips.rocketchip.config._
 | 
				
			||||||
 | 
					import freechips.rocketchip.coreplex.{BaseCoreplexConfig}
 | 
				
			||||||
import freechips.rocketchip.devices.tilelink._
 | 
					import freechips.rocketchip.devices.tilelink._
 | 
				
			||||||
import freechips.rocketchip.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)) ) }
 | 
					      Module(new TLMulticlientXbarTest(4,4, txns=2*txns, timeout=timeout)) ) }
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AMBAUnitTestConfig extends Config(new WithAMBAUnitTests ++ 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 BasePlatformConfig)
 | 
					class TLSimpleUnitTestConfig extends Config(new WithTLSimpleUnitTests ++ new WithTestDuration(10) ++ new BaseCoreplexConfig)
 | 
				
			||||||
class TLWidthUnitTestConfig extends Config(new WithTLWidthUnitTests ++ new WithTestDuration(10) ++ new BasePlatformConfig)
 | 
					class TLWidthUnitTestConfig extends Config(new WithTLWidthUnitTests ++ new WithTestDuration(10) ++ new BaseCoreplexConfig)
 | 
				
			||||||
class TLXbarUnitTestConfig extends Config(new WithTLXbarUnitTests ++ new WithTestDuration(10) ++ new BasePlatformConfig)
 | 
					class TLXbarUnitTestConfig extends Config(new WithTLXbarUnitTests ++ new WithTestDuration(10) ++ new BaseCoreplexConfig)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,7 @@ import Chisel._
 | 
				
			|||||||
import chisel3.internal.firrtl.Circuit
 | 
					import chisel3.internal.firrtl.Circuit
 | 
				
			||||||
import chisel3.experimental.{RawModule}
 | 
					import chisel3.experimental.{RawModule}
 | 
				
			||||||
// TODO: better job of Makefrag generation for non-RocketChip testing platforms
 | 
					// 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.config._
 | 
				
			||||||
import freechips.rocketchip.diplomacy.LazyModule
 | 
					import freechips.rocketchip.diplomacy.LazyModule
 | 
				
			||||||
import java.io.{File, FileWriter}
 | 
					import java.io.{File, FileWriter}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,6 +21,11 @@ class ParameterizedBundle(implicit p: Parameters) extends Bundle {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					trait Clocked extends Bundle {
 | 
				
			||||||
 | 
					  val clock = Clock()
 | 
				
			||||||
 | 
					  val reset = Bool()  
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
object DecoupledHelper {
 | 
					object DecoupledHelper {
 | 
				
			||||||
  def apply(rvs: Bool*) = new DecoupledHelper(rvs)
 | 
					  def apply(rvs: Bool*) = new DecoupledHelper(rvs)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user