Merge remote-tracking branch 'origin/master' into sim_jtag_reset
This commit is contained in:
commit
bd3a72e585
2
chisel3
2
chisel3
@ -1 +1 @@
|
|||||||
Subproject commit e27657118ff5915b96f8e3a467d464245fe09769
|
Subproject commit 97871178cb511063965f971b768f91c289c4776f
|
2
firrtl
2
firrtl
@ -1 +1 @@
|
|||||||
Subproject commit 57025111d3bc872da726e31e3e9a1e4895593266
|
Subproject commit b90fc784a1819c1d7905910130a7da022214bc22
|
@ -1 +1 @@
|
|||||||
sbt.version=1.0.4
|
sbt.version=1.1.1
|
||||||
|
BIN
sbt-launch.jar
BIN
sbt-launch.jar
Binary file not shown.
@ -7,7 +7,7 @@ import freechips.rocketchip.config.Parameters
|
|||||||
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 freechips.rocketchip.coreplex.{CrossingWrapper, AsynchronousCrossing}
|
import freechips.rocketchip.subsystem.{CrossingWrapper, AsynchronousCrossing}
|
||||||
|
|
||||||
class AXI4AsyncCrossingSource(sync: Int = 3)(implicit p: Parameters) extends LazyModule
|
class AXI4AsyncCrossingSource(sync: Int = 3)(implicit p: Parameters) extends LazyModule
|
||||||
{
|
{
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
// 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 FrontBusParams(
|
|
||||||
beatBytes: Int,
|
|
||||||
blockBytes: Int,
|
|
||||||
masterBuffering: BufferParams = BufferParams.default,
|
|
||||||
slaveBuffering: BufferParams = BufferParams.default
|
|
||||||
) extends TLBusParams
|
|
||||||
|
|
||||||
case object FrontBusKey extends Field[FrontBusParams]
|
|
||||||
|
|
||||||
class FrontBus(params: FrontBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "FrontBus") {
|
|
||||||
|
|
||||||
private val master_buffer = LazyModule(new TLBuffer(params.masterBuffering))
|
|
||||||
private val master_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.all))
|
|
||||||
|
|
||||||
master_buffer.suggestName(s"${busName}_master_TLBuffer")
|
|
||||||
master_fixer.suggestName(s"${busName}_master_TLFIFOFixer")
|
|
||||||
|
|
||||||
master_fixer.node :=* master_buffer.node
|
|
||||||
inwardNode :=* master_fixer.node
|
|
||||||
|
|
||||||
def fromSyncPorts(addBuffers: Int = 0, name: Option[String] = None): TLInwardNode = {
|
|
||||||
TLBuffer.chain(addBuffers).foldLeft(master_buffer.node:TLInwardNode)(_ :=* _)
|
|
||||||
}
|
|
||||||
|
|
||||||
def fromSyncMasters(addBuffers: Int = 0, name: Option[String] = None): TLInwardNode = {
|
|
||||||
TLBuffer.chain(addBuffers).foldLeft(master_buffer.node:TLInwardNode)(_ :=* _)
|
|
||||||
}
|
|
||||||
|
|
||||||
def fromCoherentChip: TLInwardNode = inwardNode
|
|
||||||
|
|
||||||
def toSystemBus : TLOutwardNode = TLBuffer(params.slaveBuffering) :=* xbar.node
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Provides buses that serve as attachment points,
|
|
||||||
* for use in traits that connect individual devices or external ports.
|
|
||||||
*/
|
|
||||||
trait HasFrontBus extends HasSystemBus {
|
|
||||||
private val frontbusParams = p(FrontBusKey)
|
|
||||||
val frontbusBeatBytes = frontbusParams.beatBytes
|
|
||||||
|
|
||||||
val fbus = LazyModule(new FrontBus(frontbusParams))
|
|
||||||
|
|
||||||
FlipRendering { implicit p => sbus.fromFrontBus :=* fbus.toSystemBus }
|
|
||||||
}
|
|
@ -1,79 +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.tilelink._
|
|
||||||
import freechips.rocketchip.util._
|
|
||||||
|
|
||||||
// TODO: applies to all caches, for now
|
|
||||||
case object CacheBlockBytes extends Field[Int](64)
|
|
||||||
|
|
||||||
/** L2 Broadcast Hub configuration */
|
|
||||||
case class BroadcastParams(
|
|
||||||
nTrackers: Int = 4,
|
|
||||||
bufferless: Boolean = false)
|
|
||||||
|
|
||||||
case object BroadcastKey extends Field(BroadcastParams())
|
|
||||||
|
|
||||||
/** L2 memory subsystem configuration */
|
|
||||||
case class BankedL2Params(
|
|
||||||
nMemoryChannels: Int = 1,
|
|
||||||
nBanksPerChannel: Int = 1,
|
|
||||||
coherenceManager: HasMemoryBus => (TLInwardNode, TLOutwardNode, () => Option[Bool]) = { coreplex =>
|
|
||||||
implicit val p = coreplex.p
|
|
||||||
val BroadcastParams(nTrackers, bufferless) = p(BroadcastKey)
|
|
||||||
val bh = LazyModule(new TLBroadcast(coreplex.memBusBlockBytes, nTrackers, bufferless))
|
|
||||||
val ww = LazyModule(new TLWidthWidget(coreplex.sbusBeatBytes))
|
|
||||||
ww.node :*= bh.node
|
|
||||||
(bh.node, ww.node, () => None)
|
|
||||||
}) {
|
|
||||||
val nBanks = nMemoryChannels*nBanksPerChannel
|
|
||||||
}
|
|
||||||
|
|
||||||
case object BankedL2Key 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 MemoryBusKey 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, "MemoryBus")(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(MemoryBusKey)
|
|
||||||
private val l2Params = p(BankedL2Key)
|
|
||||||
val MemoryBusParams(memBusBeatBytes, memBusBlockBytes, _, _) = mbusParams
|
|
||||||
val BankedL2Params(nMemoryChannels, nBanksPerChannel, coherenceManager) = l2Params
|
|
||||||
val nBanks = l2Params.nBanks
|
|
||||||
val cacheBlockBytes = memBusBlockBytes
|
|
||||||
private val (in, out, halt) = coherenceManager(this)
|
|
||||||
def memBusCanCauseHalt: () => Option[Bool] = halt
|
|
||||||
|
|
||||||
require (isPow2(nMemoryChannels) || nMemoryChannels == 0)
|
|
||||||
require (isPow2(nBanksPerChannel))
|
|
||||||
require (isPow2(memBusBlockBytes))
|
|
||||||
|
|
||||||
private val mask = ~BigInt((nBanks-1) * memBusBlockBytes)
|
|
||||||
val memBuses = Seq.tabulate(nMemoryChannels) { channel =>
|
|
||||||
val mbus = LazyModule(new MemoryBus(mbusParams))
|
|
||||||
for (bank <- 0 until nBanksPerChannel) {
|
|
||||||
val offset = (bank * nMemoryChannels) + channel
|
|
||||||
ForceFanout(a = true) { implicit p => in := sbus.toMemoryBus }
|
|
||||||
mbus.fromCoherenceManager := TLFilter(TLFilter.Mmask(AddressSet(offset * memBusBlockBytes, mask))) := out
|
|
||||||
}
|
|
||||||
mbus
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,61 +0,0 @@
|
|||||||
// 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.config.Field
|
|
||||||
|
|
||||||
case class PeripheryBusParams(
|
|
||||||
beatBytes: Int,
|
|
||||||
blockBytes: Int,
|
|
||||||
masterBuffering: BufferParams = BufferParams.default,
|
|
||||||
slaveBuffering: BufferParams = BufferParams.none,
|
|
||||||
arithmetic: Boolean = true,
|
|
||||||
frequency: BigInt = BigInt(100000000) // 100 MHz as default bus frequency
|
|
||||||
) extends TLBusParams {
|
|
||||||
}
|
|
||||||
|
|
||||||
case object PeripheryBusKey extends Field[PeripheryBusParams]
|
|
||||||
|
|
||||||
class PeripheryBus(params: PeripheryBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "PeripheryBus") {
|
|
||||||
|
|
||||||
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))
|
|
||||||
xbar.node :*= TLBuffer(params.masterBuffering) :*= atomics.node
|
|
||||||
}
|
|
||||||
|
|
||||||
def toTile(name: Option[String] = None)(gen: Parameters => TLInwardNode) {
|
|
||||||
this {
|
|
||||||
LazyScope(s"${busName}ToTile${name.getOrElse("")}") {
|
|
||||||
FlipRendering { implicit p =>
|
|
||||||
gen(p) :*= outwardNode
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 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(PeripheryBusKey)
|
|
||||||
val pbusBeatBytes = pbusParams.beatBytes
|
|
||||||
|
|
||||||
val pbus = LazyModule(new PeripheryBus(pbusParams))
|
|
||||||
|
|
||||||
// The peripheryBus hangs off of systemBus; here we convert TL-UH -> TL-UL
|
|
||||||
pbus.fromSystemBus :*= sbus.toPeripheryBus()
|
|
||||||
}
|
|
@ -1,83 +0,0 @@
|
|||||||
// 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.default
|
|
||||||
) extends TLBusParams
|
|
||||||
|
|
||||||
case object SystemBusKey extends Field[SystemBusParams]
|
|
||||||
|
|
||||||
class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "SystemBus") {
|
|
||||||
|
|
||||||
private val master_splitter = LazyModule(new TLSplitter) // Allows cycle-free connection to external networks
|
|
||||||
master_splitter.suggestName(s"${busName}_master_TLSplitter")
|
|
||||||
inwardNode :=* master_splitter.node
|
|
||||||
def busView = master_splitter.node.edges.in.head
|
|
||||||
|
|
||||||
protected def inwardSplitNode: TLInwardNode = master_splitter.node
|
|
||||||
protected def outwardSplitNode: TLOutwardNode = master_splitter.node
|
|
||||||
|
|
||||||
|
|
||||||
private val port_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.all))
|
|
||||||
port_fixer.suggestName(s"${busName}_port_TLFIFOFixer")
|
|
||||||
master_splitter.node :=* port_fixer.node
|
|
||||||
|
|
||||||
private val pbus_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.all))
|
|
||||||
pbus_fixer.suggestName(s"${busName}_pbus_TLFIFOFixer")
|
|
||||||
pbus_fixer.node :*= outwardWWNode
|
|
||||||
|
|
||||||
def toSplitSlaves: TLOutwardNode = outwardSplitNode
|
|
||||||
|
|
||||||
def toPeripheryBus(addBuffers: Int = 0): TLOutwardNode = {
|
|
||||||
TLBuffer.chain(addBuffers).foldRight(pbus_fixer.node:TLOutwardNode)(_ :*= _)
|
|
||||||
}
|
|
||||||
|
|
||||||
val toMemoryBus: TLOutwardNode = outwardNode
|
|
||||||
|
|
||||||
val toSlave: TLOutwardNode = outwardBufNode
|
|
||||||
|
|
||||||
def fromCoherentChip: TLInwardNode = inwardNode
|
|
||||||
|
|
||||||
def fromFrontBus: TLInwardNode = master_splitter.node
|
|
||||||
|
|
||||||
def fromTile(name: Option[String])(gen: Parameters => TLOutwardNode) {
|
|
||||||
this {
|
|
||||||
LazyScope(s"${busName}FromTile${name.getOrElse("")}") {
|
|
||||||
master_splitter.node :=* gen(p)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def fromSyncPorts(params: BufferParams = BufferParams.default, name: Option[String] = None): TLInwardNode = {
|
|
||||||
val buffer = LazyModule(new TLBuffer(params))
|
|
||||||
name.foreach { n => buffer.suggestName(s"${busName}_${n}_TLBuffer") }
|
|
||||||
port_fixer.node :=* buffer.node
|
|
||||||
buffer.node
|
|
||||||
}
|
|
||||||
|
|
||||||
def fromSyncFIFOMaster(params: BufferParams = BufferParams.default, name: Option[String] = None): TLInwardNode = {
|
|
||||||
fromSyncPorts(params, name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 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(SystemBusKey)
|
|
||||||
val sbusBeatBytes = sbusParams.beatBytes
|
|
||||||
|
|
||||||
val sbus = LazyModule(new SystemBus(sbusParams))
|
|
||||||
|
|
||||||
def sharedMemoryTLEdge: TLEdge = sbus.busView
|
|
||||||
}
|
|
@ -5,7 +5,7 @@ package freechips.rocketchip.devices.debug
|
|||||||
import Chisel._
|
import Chisel._
|
||||||
import chisel3.core.{IntParam, Input, Output}
|
import chisel3.core.{IntParam, Input, Output}
|
||||||
import freechips.rocketchip.config.{Field, Parameters}
|
import freechips.rocketchip.config.{Field, Parameters}
|
||||||
import freechips.rocketchip.coreplex.HasPeripheryBus
|
import freechips.rocketchip.subsystem._
|
||||||
import freechips.rocketchip.devices.tilelink._
|
import freechips.rocketchip.devices.tilelink._
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.jtag._
|
import freechips.rocketchip.jtag._
|
||||||
@ -26,12 +26,9 @@ class DebugIO(implicit val p: Parameters) extends ParameterizedBundle()(p) with
|
|||||||
/** Either adds a JTAG DTM to system, and exports a JTAG interface,
|
/** Either adds a JTAG DTM to system, and exports a JTAG interface,
|
||||||
* or exports the Debug Module Interface (DMI), based on a global parameter.
|
* or exports the Debug Module Interface (DMI), based on a global parameter.
|
||||||
*/
|
*/
|
||||||
trait HasPeripheryDebug extends HasPeripheryBus {
|
trait HasPeripheryDebug { this: BaseSubsystem =>
|
||||||
val module: HasPeripheryDebugModuleImp
|
|
||||||
|
|
||||||
val debug = LazyModule(new TLDebugModule(pbus.beatBytes))
|
val debug = LazyModule(new TLDebugModule(pbus.beatBytes))
|
||||||
|
pbus.toVariableWidthSlave(Some("debug")){ debug.node }
|
||||||
debug.node := pbus.toVariableWidthSlaves
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trait HasPeripheryDebugBundle {
|
trait HasPeripheryDebugBundle {
|
||||||
|
@ -4,7 +4,7 @@ package freechips.rocketchip.devices.tilelink
|
|||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import freechips.rocketchip.config.{Field, Parameters}
|
import freechips.rocketchip.config.{Field, Parameters}
|
||||||
import freechips.rocketchip.coreplex._
|
import freechips.rocketchip.subsystem.{BaseSubsystem, HasResetVectorWire}
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
@ -58,8 +58,8 @@ class TLROM(val base: BigInt, val size: Int, contentsDelayed: => Seq[Byte], exec
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds a boot ROM that contains the DTB describing the system's coreplex. */
|
/** Adds a boot ROM that contains the DTB describing the system's subsystem. */
|
||||||
trait HasPeripheryBootROM extends HasPeripheryBus {
|
trait HasPeripheryBootROM { this: BaseSubsystem =>
|
||||||
val dtb: DTB
|
val dtb: DTB
|
||||||
private val params = p(BootROMParams)
|
private val params = p(BootROMParams)
|
||||||
private lazy val contents = {
|
private lazy val contents = {
|
||||||
@ -71,10 +71,10 @@ trait HasPeripheryBootROM extends HasPeripheryBus {
|
|||||||
|
|
||||||
val bootrom = LazyModule(new TLROM(params.address, params.size, contents, true, pbus.beatBytes))
|
val bootrom = LazyModule(new TLROM(params.address, params.size, contents, true, pbus.beatBytes))
|
||||||
|
|
||||||
bootrom.node := pbus.toVariableWidthSlaves
|
pbus.toVariableWidthSlave(Some("bootrom")){ bootrom.node }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Coreplex will power-on running at 0x10040 (BootROM) */
|
/** Subsystem will power-on running at 0x10040 (BootROM) */
|
||||||
trait HasPeripheryBootROMModuleImp extends LazyModuleImp
|
trait HasPeripheryBootROMModuleImp extends LazyModuleImp
|
||||||
with HasResetVectorWire {
|
with HasResetVectorWire {
|
||||||
val outer: HasPeripheryBootROM
|
val outer: HasPeripheryBootROM
|
||||||
|
@ -4,7 +4,6 @@ package freechips.rocketchip.devices.tilelink
|
|||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import freechips.rocketchip.config.{Field, 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._
|
||||||
|
@ -4,7 +4,7 @@ package freechips.rocketchip.devices.tilelink
|
|||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import freechips.rocketchip.config.{Field, Parameters}
|
import freechips.rocketchip.config.{Field, Parameters}
|
||||||
import freechips.rocketchip.coreplex.HasPeripheryBus
|
import freechips.rocketchip.subsystem.BaseSubsystem
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.regmapper._
|
import freechips.rocketchip.regmapper._
|
||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
@ -12,7 +12,7 @@ import freechips.rocketchip.interrupts._
|
|||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
import scala.math.{min,max}
|
import scala.math.{min,max}
|
||||||
|
|
||||||
object ClintConsts
|
object CLINTConsts
|
||||||
{
|
{
|
||||||
def msipOffset(hart: Int) = hart * msipBytes
|
def msipOffset(hart: Int) = hart * msipBytes
|
||||||
def timecmpOffset(hart: Int) = 0x4000 + hart * timecmpBytes
|
def timecmpOffset(hart: Int) = 0x4000 + hart * timecmpBytes
|
||||||
@ -25,16 +25,16 @@ object ClintConsts
|
|||||||
def ints = 2
|
def ints = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
case class ClintParams(baseAddress: BigInt = 0x02000000, intStages: Int = 0)
|
case class CLINTParams(baseAddress: BigInt = 0x02000000, intStages: Int = 0)
|
||||||
{
|
{
|
||||||
def address = AddressSet(baseAddress, ClintConsts.size-1)
|
def address = AddressSet(baseAddress, CLINTConsts.size-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
case object ClintKey extends Field(ClintParams())
|
case object CLINTKey extends Field(CLINTParams())
|
||||||
|
|
||||||
class CoreplexLocalInterrupter(params: ClintParams, beatBytes: Int)(implicit p: Parameters) extends LazyModule
|
class CLINT(params: CLINTParams, beatBytes: Int)(implicit p: Parameters) extends LazyModule
|
||||||
{
|
{
|
||||||
import ClintConsts._
|
import CLINTConsts._
|
||||||
|
|
||||||
// clint0 => at most 4095 devices
|
// clint0 => at most 4095 devices
|
||||||
val device = new SimpleDevice("clint", Seq("riscv,clint0")) {
|
val device = new SimpleDevice("clint", Seq("riscv,clint0")) {
|
||||||
@ -90,8 +90,8 @@ class CoreplexLocalInterrupter(params: ClintParams, beatBytes: Int)(implicit p:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Trait that will connect a Clint to a coreplex */
|
/** Trait that will connect a CLINT to a subsystem */
|
||||||
trait HasPeripheryClint extends HasPeripheryBus {
|
trait HasPeripheryCLINT { this: BaseSubsystem =>
|
||||||
val clint = LazyModule(new CoreplexLocalInterrupter(p(ClintKey), pbus.beatBytes))
|
val clint = LazyModule(new CLINT(p(CLINTKey), pbus.beatBytes))
|
||||||
clint.node := pbus.toVariableWidthSlaves
|
pbus.toVariableWidthSlave(Some("clint")) { clint.node }
|
||||||
}
|
}
|
@ -4,7 +4,7 @@ package freechips.rocketchip.devices.tilelink
|
|||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import freechips.rocketchip.config.{Field, Parameters}
|
import freechips.rocketchip.config.{Field, Parameters}
|
||||||
import freechips.rocketchip.coreplex.HasSystemBus
|
import freechips.rocketchip.subsystem.BaseSubsystem
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
@ -118,9 +118,8 @@ class DeadlockDevice(params: ErrorParams, beatBytes: Int = 4)(implicit p: Parame
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait HasSystemErrorSlave extends HasSystemBus {
|
trait HasSystemErrorSlave { this: BaseSubsystem =>
|
||||||
private val params = p(ErrorParams)
|
private val params = p(ErrorParams)
|
||||||
val error = LazyModule(new TLError(params, sbus.beatBytes))
|
val error = LazyModule(new TLError(params, sbus.beatBytes))
|
||||||
|
sbus.toSlave(Some("Error")){ error.node }
|
||||||
error.node := sbus.toSlave
|
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
package freechips.rocketchip.devices.tilelink
|
package freechips.rocketchip.devices.tilelink
|
||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import freechips.rocketchip.coreplex.{HasPeripheryBus}
|
|
||||||
import freechips.rocketchip.config.{Field, Parameters}
|
import freechips.rocketchip.config.{Field, Parameters}
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
|
import freechips.rocketchip.subsystem.BaseSubsystem
|
||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
|
|
||||||
@ -13,11 +13,11 @@ case class MaskROMParams(address: BigInt, name: String, depth: Int = 2048, width
|
|||||||
|
|
||||||
case object PeripheryMaskROMKey extends Field[Seq[MaskROMParams]]
|
case object PeripheryMaskROMKey extends Field[Seq[MaskROMParams]]
|
||||||
|
|
||||||
trait HasPeripheryMaskROMSlave extends HasPeripheryBus {
|
trait HasPeripheryMaskROMSlave { this: BaseSubsystem =>
|
||||||
val maskROMParams = p(PeripheryMaskROMKey)
|
val maskROMParams = p(PeripheryMaskROMKey)
|
||||||
val maskROMs = maskROMParams map { params =>
|
val maskROMs = maskROMParams map { params =>
|
||||||
val maskROM = LazyModule(new TLMaskROM(params))
|
val maskROM = LazyModule(new TLMaskROM(params))
|
||||||
maskROM.node := pbus.toFixedWidthSingleBeatSlave(maskROM.beatBytes)
|
pbus.toFixedWidthSingleBeatSlave(maskROM.beatBytes, Some("MaskROM")) { maskROM.node }
|
||||||
maskROM
|
maskROM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ package freechips.rocketchip.devices.tilelink
|
|||||||
import Chisel._
|
import Chisel._
|
||||||
import Chisel.ImplicitConversions._
|
import Chisel.ImplicitConversions._
|
||||||
import freechips.rocketchip.config.{Field, Parameters}
|
import freechips.rocketchip.config.{Field, Parameters}
|
||||||
import freechips.rocketchip.coreplex.{HasInterruptBus, HasPeripheryBus}
|
import freechips.rocketchip.subsystem.BaseSubsystem
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.regmapper._
|
import freechips.rocketchip.regmapper._
|
||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
@ -268,9 +268,9 @@ class TLPLIC(params: PLICParams, beatBytes: Int)(implicit p: Parameters) extends
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Trait that will connect a PLIC to a coreplex */
|
/** Trait that will connect a PLIC to a subsystem */
|
||||||
trait HasPeripheryPLIC extends HasInterruptBus with HasPeripheryBus {
|
trait HasPeripheryPLIC { this: BaseSubsystem =>
|
||||||
val plic = LazyModule(new TLPLIC(p(PLICKey), pbus.beatBytes))
|
val plic = LazyModule(new TLPLIC(p(PLICKey), pbus.beatBytes))
|
||||||
plic.node := pbus.toVariableWidthSlaves
|
pbus.toVariableWidthSlave(Some("plic")) { plic.node }
|
||||||
plic.intnode := ibus.toPLIC
|
plic.intnode := ibus.toPLIC
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ package freechips.rocketchip.devices.tilelink
|
|||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import freechips.rocketchip.config.{Field, Parameters}
|
import freechips.rocketchip.config.{Field, Parameters}
|
||||||
import freechips.rocketchip.coreplex.HasMemoryBus
|
import freechips.rocketchip.subsystem.BaseSubsystem
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
|
|
||||||
@ -46,17 +46,17 @@ case class ZeroParams(base: Long, size: Long, beatBytes: Int)
|
|||||||
case object ZeroParams extends Field[ZeroParams]
|
case object ZeroParams extends Field[ZeroParams]
|
||||||
|
|
||||||
/** Adds a /dev/null slave that generates zero-filled responses to reads */
|
/** Adds a /dev/null slave that generates zero-filled responses to reads */
|
||||||
trait HasMemoryZeroSlave extends HasMemoryBus {
|
trait HasMemoryZeroSlave { this: BaseSubsystem =>
|
||||||
private val params = p(ZeroParams)
|
private val params = p(ZeroParams)
|
||||||
private val device = new SimpleDevice("rom", Seq("ucbbar,cacheable-zero0"))
|
private val device = new SimpleDevice("rom", Seq("ucbbar,cacheable-zero0"))
|
||||||
|
|
||||||
val zeros = memBuses.map(_.toVariableWidthSlave).zipWithIndex.map { case (node, channel) =>
|
val zeros = memBuses.zipWithIndex.map { case (bus, channel) =>
|
||||||
val channels = memBuses.size
|
val channels = memBuses.size
|
||||||
val base = AddressSet(params.base, params.size-1)
|
val base = AddressSet(params.base, params.size-1)
|
||||||
val filter = AddressSet(channel * cacheBlockBytes, ~((channels-1) * cacheBlockBytes))
|
val filter = AddressSet(channel * bus.blockBytes, ~((channels-1) * bus.blockBytes))
|
||||||
val address = base.intersect(filter).get
|
val address = base.intersect(filter).get
|
||||||
val zero = LazyModule(new TLZero(address, beatBytes = params.beatBytes, resources = device.reg("mem")))
|
val zero = LazyModule(new TLZero(address, beatBytes = params.beatBytes, resources = device.reg("mem")))
|
||||||
zero.node := node
|
bus.toVariableWidthSlave(Some("Zero")) { zero.node }
|
||||||
zero
|
zero
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,50 +25,30 @@ abstract class LazyModule()(implicit val p: Parameters)
|
|||||||
parent.foreach(p => p.children = this :: p.children)
|
parent.foreach(p => p.children = this :: p.children)
|
||||||
|
|
||||||
// suggestedName accumulates Some(names), taking the final one. Nones are ignored.
|
// suggestedName accumulates Some(names), taking the final one. Nones are ignored.
|
||||||
private var suggestedName: Option[String] = None
|
private var suggestedNameVar: Option[String] = None
|
||||||
def suggestName(x: String): this.type = suggestName(Some(x))
|
def suggestName(x: String): this.type = suggestName(Some(x))
|
||||||
def suggestName(x: Option[String]): this.type = {
|
def suggestName(x: Option[String]): this.type = {
|
||||||
x.foreach { n => suggestedName = Some(n) }
|
x.foreach { n => suggestedNameVar = Some(n) }
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
private lazy val childNames =
|
|
||||||
getClass.getMethods.filter { m =>
|
|
||||||
m.getParameterTypes.isEmpty &&
|
|
||||||
!java.lang.reflect.Modifier.isStatic(m.getModifiers) &&
|
|
||||||
m.getName != "children" &&
|
|
||||||
m.getName != "getChildren"
|
|
||||||
}.flatMap { m =>
|
|
||||||
if (classOf[LazyModule].isAssignableFrom(m.getReturnType)) {
|
|
||||||
val obj = m.invoke(this)
|
|
||||||
if (obj eq null) Seq() else Seq((m.getName, obj))
|
|
||||||
} else if (classOf[Seq[LazyModule]].isAssignableFrom(m.getReturnType)) {
|
|
||||||
val obj = m.invoke(this)
|
|
||||||
if (obj eq null) Seq() else {
|
|
||||||
val seq = try { obj.asInstanceOf[Seq[Object]] } catch { case _: Throwable => null }
|
|
||||||
if (seq eq null) Seq() else {
|
|
||||||
seq.zipWithIndex.map { case (l, i) => (m.getName + "_" + i, l) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else Seq()
|
|
||||||
}
|
|
||||||
private def findValName =
|
|
||||||
parent.flatMap(_.childNames.find(_._2 eq this)).map(_._1)
|
|
||||||
|
|
||||||
private def findClassName(c: Class[_]): String = {
|
private def findClassName(c: Class[_]): String = {
|
||||||
val n = c.getName.split('.').last
|
val n = c.getName.split('.').last
|
||||||
if (n.contains('$')) findClassName(c.getSuperclass) else n
|
if (n.contains('$')) findClassName(c.getSuperclass) else n
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy val className = findClassName(getClass)
|
lazy val className = findClassName(getClass)
|
||||||
lazy val valName = suggestedName.orElse(findValName)
|
lazy val suggestedName = suggestedNameVar.getOrElse(className)
|
||||||
lazy val outerName = if (nodes.size != 1) None else nodes(0).gco.flatMap(_.lazyModule.valName)
|
lazy val desiredName = className // + hashcode?
|
||||||
|
|
||||||
def moduleName = className + valName.orElse(outerName).map("_" + _).getOrElse("")
|
def name = suggestedName // className + suggestedName ++ hashcode ?
|
||||||
def instanceName = valName.getOrElse(outerName.map(_ + "_").getOrElse("") + className)
|
|
||||||
def name = valName.getOrElse(className)
|
|
||||||
def line = sourceLine(info)
|
def line = sourceLine(info)
|
||||||
|
|
||||||
|
// Accessing these names can only be done after circuit elaboration!
|
||||||
|
lazy val moduleName = module.name // The final Verilog Module name
|
||||||
|
lazy val pathName = module.pathName
|
||||||
|
lazy val instanceName = pathName.split('.').last // The final Verilog instance name
|
||||||
|
|
||||||
def instantiate() { } // a hook for running things in module scope (after children exist, but before dangles+auto exists)
|
def instantiate() { } // a hook for running things in module scope (after children exist, but before dangles+auto exists)
|
||||||
def module: LazyModuleImpLike
|
def module: LazyModuleImpLike
|
||||||
|
|
||||||
@ -79,7 +59,7 @@ abstract class LazyModule()(implicit val p: Parameters)
|
|||||||
buf ++= "<graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\" xmlns:y=\"http://www.yworks.com/xml/graphml\">\n"
|
buf ++= "<graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\" xmlns:y=\"http://www.yworks.com/xml/graphml\">\n"
|
||||||
buf ++= " <key for=\"node\" id=\"n\" yfiles.type=\"nodegraphics\"/>\n"
|
buf ++= " <key for=\"node\" id=\"n\" yfiles.type=\"nodegraphics\"/>\n"
|
||||||
buf ++= " <key for=\"edge\" id=\"e\" yfiles.type=\"edgegraphics\"/>\n"
|
buf ++= " <key for=\"edge\" id=\"e\" yfiles.type=\"edgegraphics\"/>\n"
|
||||||
buf ++= " <key for=\"node\" id=\"d\" attr.name=\"NodeDebugString\" attr.type=\"string\"/>\n"
|
buf ++= " <key for=\"node\" id=\"d\" attr.name=\"Description\" attr.type=\"string\"/>\n"
|
||||||
buf ++= " <graph id=\"G\" edgedefault=\"directed\">\n"
|
buf ++= " <graph id=\"G\" edgedefault=\"directed\">\n"
|
||||||
nodesGraphML(buf, " ")
|
nodesGraphML(buf, " ")
|
||||||
edgesGraphML(buf, " ")
|
edgesGraphML(buf, " ")
|
||||||
@ -92,11 +72,13 @@ abstract class LazyModule()(implicit val p: Parameters)
|
|||||||
|
|
||||||
private def nodesGraphML(buf: StringBuilder, pad: String) {
|
private def nodesGraphML(buf: StringBuilder, pad: String) {
|
||||||
buf ++= s"""${pad}<node id=\"${index}\">\n"""
|
buf ++= s"""${pad}<node id=\"${index}\">\n"""
|
||||||
buf ++= s"""${pad} <data key=\"n\"><y:ShapeNode><y:NodeLabel modelName=\"sides\" modelPosition=\"w\" rotationAngle=\"270.0\">${module.instanceName}</y:NodeLabel></y:ShapeNode></data>\n"""
|
buf ++= s"""${pad} <data key=\"n\"><y:ShapeNode><y:NodeLabel modelName=\"sides\" modelPosition=\"w\" rotationAngle=\"270.0\">${instanceName}</y:NodeLabel></y:ShapeNode></data>\n"""
|
||||||
|
buf ++= s"""${pad} <data key=\"d\">${moduleName} (${pathName})</data>\n"""
|
||||||
buf ++= s"""${pad} <graph id=\"${index}::\" edgedefault=\"directed\">\n"""
|
buf ++= s"""${pad} <graph id=\"${index}::\" edgedefault=\"directed\">\n"""
|
||||||
nodes.filter(!_.omitGraphML).foreach { n =>
|
nodes.filter(!_.omitGraphML).foreach { n =>
|
||||||
buf ++= s"""${pad} <node id=\"${index}::${n.index}\">\n"""
|
buf ++= s"""${pad} <node id=\"${index}::${n.index}\">\n"""
|
||||||
buf ++= s"""${pad} <data key=\"d\"><y:ShapeNode><y:Shape type="ellipse"/></y:ShapeNode>${n.nodedebugstring}</data>\n"""
|
buf ++= s"""${pad} <data key=\"e\"><y:ShapeNode><y:Shape type="Ellipse"/></y:ShapeNode></data>\n"""
|
||||||
|
buf ++= s"""${pad} <data key=\"d\">${n.nodedebugstring}</data>\n"""
|
||||||
buf ++= s"""${pad} </node>\n"""
|
buf ++= s"""${pad} </node>\n"""
|
||||||
}
|
}
|
||||||
children.filter(!_.omitGraphML).foreach { _.nodesGraphML(buf, pad + " ") }
|
children.filter(!_.omitGraphML).foreach { _.nodesGraphML(buf, pad + " ") }
|
||||||
@ -149,6 +131,7 @@ object LazyModule
|
|||||||
require (scope.get eq bc, s"LazyModule() applied to ${bc.name} before ${scope.get.name} ${sourceLine(sourceInfo)}")
|
require (scope.get eq bc, s"LazyModule() applied to ${bc.name} before ${scope.get.name} ${sourceLine(sourceInfo)}")
|
||||||
scope = bc.parent
|
scope = bc.parent
|
||||||
bc.info = sourceInfo
|
bc.info = sourceInfo
|
||||||
|
if (!bc.suggestedNameVar.isDefined) bc.suggestName(valName.name)
|
||||||
bc
|
bc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -162,8 +145,8 @@ sealed trait LazyModuleImpLike extends BaseModule
|
|||||||
// .module had better not be accessed while LazyModules are still being built!
|
// .module had better not be accessed while LazyModules are still being built!
|
||||||
require (!LazyModule.scope.isDefined, s"${wrapper.name}.module was constructed before LazyModule() was run on ${LazyModule.scope.get.name}")
|
require (!LazyModule.scope.isDefined, s"${wrapper.name}.module was constructed before LazyModule() was run on ${LazyModule.scope.get.name}")
|
||||||
|
|
||||||
override def desiredName = wrapper.moduleName
|
override def desiredName = wrapper.desiredName
|
||||||
suggestName(wrapper.instanceName)
|
suggestName(wrapper.suggestedName)
|
||||||
|
|
||||||
implicit val p = wrapper.p
|
implicit val p = wrapper.p
|
||||||
|
|
||||||
@ -186,7 +169,7 @@ sealed trait LazyModuleImpLike extends BaseModule
|
|||||||
val auto = IO(new AutoBundle(forward.map { d => (d.name, d.data, d.flipped) }:_*))
|
val auto = IO(new AutoBundle(forward.map { d => (d.name, d.data, d.flipped) }:_*))
|
||||||
val dangles = (forward zip auto.elements) map { case (d, (_, io)) =>
|
val dangles = (forward zip auto.elements) map { case (d, (_, io)) =>
|
||||||
if (d.flipped) { d.data <> io } else { io <> d.data }
|
if (d.flipped) { d.data <> io } else { io <> d.data }
|
||||||
d.copy(data = io, name = wrapper.valName.getOrElse("anon") + "_" + d.name)
|
d.copy(data = io, name = wrapper.suggestedName + "_" + d.name)
|
||||||
}
|
}
|
||||||
wrapper.instantiate()
|
wrapper.instantiate()
|
||||||
(auto, dangles)
|
(auto, dangles)
|
||||||
|
@ -32,7 +32,6 @@ trait InwardNodeImp[DI, UI, EI, BI <: Data]
|
|||||||
|
|
||||||
// optional methods to track node graph
|
// optional methods to track node graph
|
||||||
def mixI(pu: UI, node: InwardNode[DI, UI, BI]): UI = pu // insert node into parameters
|
def mixI(pu: UI, node: InwardNode[DI, UI, BI]): UI = pu // insert node into parameters
|
||||||
def getO(pu: UI): Option[BaseNode] = None // most-outward common node
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DO = Downwards flowing Parameters generated by the outer side of the node
|
// DO = Downwards flowing Parameters generated by the outer side of the node
|
||||||
@ -91,8 +90,6 @@ abstract class BaseNode(implicit val valName: ValName)
|
|||||||
if (name.isEmpty) "" else name + "_"
|
if (name.isEmpty) "" else name + "_"
|
||||||
}
|
}
|
||||||
|
|
||||||
protected[diplomacy] def gci: Option[BaseNode] // greatest common inner
|
|
||||||
protected[diplomacy] def gco: Option[BaseNode] // greatest common outer
|
|
||||||
def inputs: Seq[(BaseNode, RenderedEdge)]
|
def inputs: Seq[(BaseNode, RenderedEdge)]
|
||||||
def outputs: Seq[(BaseNode, RenderedEdge)]
|
def outputs: Seq[(BaseNode, RenderedEdge)]
|
||||||
|
|
||||||
@ -322,9 +319,6 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected[diplomacy] def gco = if (uiParams.size != 1) None else inner.getO(uiParams(0))
|
|
||||||
protected[diplomacy] def gci = if (doParams.size != 1) None else outer.getI(doParams(0))
|
|
||||||
|
|
||||||
protected[diplomacy] lazy val edgesOut = (oPorts zip doParams).map { case ((i, n, p, s), o) => outer.edgeO(o, n.uiParams(i), p, s) }
|
protected[diplomacy] lazy val edgesOut = (oPorts zip doParams).map { case ((i, n, p, s), o) => outer.edgeO(o, n.uiParams(i), p, s) }
|
||||||
protected[diplomacy] lazy val edgesIn = (iPorts zip uiParams).map { case ((o, n, p, s), i) => inner.edgeI(n.doParams(o), i, p, s) }
|
protected[diplomacy] lazy val edgesIn = (iPorts zip uiParams).map { case ((o, n, p, s), i) => inner.edgeI(n.doParams(o), i, p, s) }
|
||||||
|
|
||||||
|
@ -211,7 +211,7 @@ case class Resource(owner: Device, key: String)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The resource binding scope for a LazyModule that generates a device tree (currently Coreplex only). */
|
/** The resource binding scope for a LazyModule that generates a device tree (currently Subsystem only). */
|
||||||
trait BindingScope
|
trait BindingScope
|
||||||
{
|
{
|
||||||
this: LazyModule =>
|
this: LazyModule =>
|
||||||
|
@ -5,13 +5,13 @@ package freechips.rocketchip.groundtest
|
|||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import freechips.rocketchip.config.Config
|
import freechips.rocketchip.config.Config
|
||||||
import freechips.rocketchip.coreplex._
|
import freechips.rocketchip.subsystem._
|
||||||
import freechips.rocketchip.rocket.{DCacheParams}
|
import freechips.rocketchip.rocket.{DCacheParams}
|
||||||
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 BaseCoreplexConfig)
|
class TraceGenConfig extends Config(new WithTraceGen(List.fill(2){ DCacheParams(nSets = 16, nWays = 1) }) ++ new BaseSubsystemConfig)
|
||||||
|
|
||||||
class TraceGenBufferlessConfig extends Config(new WithBufferlessBroadcastHub ++ new TraceGenConfig)
|
class TraceGenBufferlessConfig extends Config(new WithBufferlessBroadcastHub ++ new TraceGenConfig)
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import Chisel._
|
|||||||
import freechips.rocketchip.config.{Field, Parameters}
|
import freechips.rocketchip.config.{Field, Parameters}
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.interrupts._
|
import freechips.rocketchip.interrupts._
|
||||||
import freechips.rocketchip.coreplex._
|
import freechips.rocketchip.subsystem._
|
||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
import freechips.rocketchip.tile._
|
import freechips.rocketchip.tile._
|
||||||
|
|
||||||
@ -15,10 +15,9 @@ import scala.math.max
|
|||||||
|
|
||||||
case object TileId extends Field[Int]
|
case object TileId extends Field[Int]
|
||||||
|
|
||||||
class GroundTestCoreplex(implicit p: Parameters) extends BaseCoreplex
|
class GroundTestSubsystem(implicit p: Parameters) extends BaseSubsystem
|
||||||
with HasMasterAXI4MemPort
|
with HasMasterAXI4MemPort
|
||||||
with HasPeripheryTestRAMSlave
|
with HasPeripheryTestRAMSlave {
|
||||||
with HasInterruptBus {
|
|
||||||
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 {
|
||||||
@ -28,19 +27,16 @@ class GroundTestCoreplex(implicit p: Parameters) extends BaseCoreplex
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
tiles.flatMap(_.dcacheOpt).foreach { dc =>
|
tiles.flatMap(_.dcacheOpt).foreach { dc =>
|
||||||
sbus.fromTile(None) { implicit p => TileMasterPortParams(addBuffers = 1).adapt(this)(dc.node) }
|
sbus.fromTile(None, buffers = 1){ dc.node }
|
||||||
}
|
}
|
||||||
|
|
||||||
// No PLIC in ground test; so just sink the interrupts to nowhere
|
// No PLIC in ground test; so just sink the interrupts to nowhere
|
||||||
IntSinkNode(IntSinkPortSimple()) := ibus.toPLIC
|
IntSinkNode(IntSinkPortSimple()) := ibus.toPLIC
|
||||||
|
|
||||||
val pbusRAM = LazyModule(new TLRAM(AddressSet(testRamAddr, 0xffff), true, false, pbus.beatBytes))
|
override lazy val module = new GroundTestSubsystemModuleImp(this)
|
||||||
pbusRAM.node := pbus.toVariableWidthSlaves
|
|
||||||
|
|
||||||
override lazy val module = new GroundTestCoreplexModule(this)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class GroundTestCoreplexModule[+L <: GroundTestCoreplex](_outer: L) extends BaseCoreplexModule(_outer)
|
class GroundTestSubsystemModuleImp[+L <: GroundTestSubsystem](_outer: L) extends BaseSubsystemModuleImp(_outer)
|
||||||
with HasMasterAXI4MemPortModuleImp {
|
with HasMasterAXI4MemPortModuleImp {
|
||||||
val success = IO(Bool(OUTPUT))
|
val success = IO(Bool(OUTPUT))
|
||||||
|
|
||||||
@ -51,13 +47,13 @@ class GroundTestCoreplexModule[+L <: GroundTestCoreplex](_outer: L) extends Base
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Adds a SRAM to the system for testing purposes. */
|
/** Adds a SRAM to the system for testing purposes. */
|
||||||
trait HasPeripheryTestRAMSlave extends HasPeripheryBus {
|
trait HasPeripheryTestRAMSlave { this: BaseSubsystem =>
|
||||||
val testram = LazyModule(new TLRAM(AddressSet(0x52000000, 0xfff), true, true, pbus.beatBytes))
|
val testram = LazyModule(new TLRAM(AddressSet(0x52000000, 0xfff), true, true, pbus.beatBytes))
|
||||||
testram.node := pbus.toVariableWidthSlaves
|
pbus.toVariableWidthSlave(Some("TestRAM")) { testram.node }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds a fuzzing master to the system for testing purposes. */
|
/** Adds a fuzzing master to the system for testing purposes. */
|
||||||
trait HasPeripheryTestFuzzMaster extends HasPeripheryBus {
|
trait HasPeripheryTestFuzzMaster { this: BaseSubsystem =>
|
||||||
val fuzzer = LazyModule(new TLFuzzer(5000))
|
val fuzzer = LazyModule(new TLFuzzer(5000))
|
||||||
pbus.bufferFromMasters := fuzzer.node
|
pbus.fromOtherMaster(Some("Fuzzer")) { 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 GroundTestCoreplex).module)
|
val dut = Module(LazyModule(new GroundTestSubsystem).module)
|
||||||
io.success := dut.success
|
io.success := dut.success
|
||||||
dut.connectSimAXIMem()
|
dut.connectSimAXIMem()
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ package freechips.rocketchip.groundtest
|
|||||||
import Chisel._
|
import Chisel._
|
||||||
import freechips.rocketchip.config._
|
import freechips.rocketchip.config._
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.coreplex._
|
import freechips.rocketchip.subsystem._
|
||||||
import freechips.rocketchip.interrupts._
|
import freechips.rocketchip.interrupts._
|
||||||
import freechips.rocketchip.rocket.{DCache, RocketCoreParams}
|
import freechips.rocketchip.rocket.{DCache, RocketCoreParams}
|
||||||
import freechips.rocketchip.tile._
|
import freechips.rocketchip.tile._
|
||||||
|
@ -26,7 +26,7 @@ case class RegFieldDesc (
|
|||||||
groupDesc: Option[String] = None,
|
groupDesc: Option[String] = None,
|
||||||
access: RegFieldAccessType = RegFieldAccessType.RW,
|
access: RegFieldAccessType = RegFieldAccessType.RW,
|
||||||
reset: Option[BigInt] = None,
|
reset: Option[BigInt] = None,
|
||||||
enumerations: Map[String, BigInt] = Map()
|
enumerations: Map[BigInt, (String, String)] = Map()
|
||||||
){
|
){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ package freechips.rocketchip.rocket
|
|||||||
import Chisel._
|
import Chisel._
|
||||||
import Chisel.ImplicitConversions._
|
import Chisel.ImplicitConversions._
|
||||||
import freechips.rocketchip.config.Parameters
|
import freechips.rocketchip.config.Parameters
|
||||||
import freechips.rocketchip.coreplex.CacheBlockBytes
|
import freechips.rocketchip.subsystem.CacheBlockBytes
|
||||||
import freechips.rocketchip.tile.HasCoreParameters
|
import freechips.rocketchip.tile.HasCoreParameters
|
||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ package freechips.rocketchip.rocket
|
|||||||
import Chisel._
|
import Chisel._
|
||||||
import Chisel.ImplicitConversions._
|
import Chisel.ImplicitConversions._
|
||||||
import freechips.rocketchip.config.Parameters
|
import freechips.rocketchip.config.Parameters
|
||||||
import freechips.rocketchip.coreplex.{RocketTilesKey}
|
import freechips.rocketchip.subsystem.{RocketTilesKey}
|
||||||
import freechips.rocketchip.diplomacy.{AddressSet, RegionType}
|
import freechips.rocketchip.diplomacy.{AddressSet, RegionType}
|
||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
|
@ -7,7 +7,7 @@ import Chisel._
|
|||||||
import Chisel.ImplicitConversions._
|
import Chisel.ImplicitConversions._
|
||||||
import chisel3.core.withReset
|
import chisel3.core.withReset
|
||||||
import freechips.rocketchip.config._
|
import freechips.rocketchip.config._
|
||||||
import freechips.rocketchip.coreplex._
|
import freechips.rocketchip.subsystem._
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
import freechips.rocketchip.tile._
|
import freechips.rocketchip.tile._
|
||||||
@ -62,7 +62,7 @@ class Frontend(val icacheParams: ICacheParams, hartid: Int)(implicit p: Paramete
|
|||||||
val slaveNode = icache.slaveNode
|
val slaveNode = icache.slaveNode
|
||||||
}
|
}
|
||||||
|
|
||||||
class FrontendBundle(outer: Frontend) extends CoreBundle()(outer.p)
|
class FrontendBundle(val outer: Frontend) extends CoreBundle()(outer.p)
|
||||||
with HasExternallyDrivenTileConstants {
|
with HasExternallyDrivenTileConstants {
|
||||||
val cpu = new FrontendIO().flip
|
val cpu = new FrontendIO().flip
|
||||||
val ptw = new TLBPTWIO()
|
val ptw = new TLBPTWIO()
|
||||||
|
@ -6,7 +6,7 @@ package freechips.rocketchip.rocket
|
|||||||
import Chisel._
|
import Chisel._
|
||||||
import chisel3.experimental.dontTouch
|
import chisel3.experimental.dontTouch
|
||||||
import freechips.rocketchip.config.{Parameters, Field}
|
import freechips.rocketchip.config.{Parameters, Field}
|
||||||
import freechips.rocketchip.coreplex._
|
import freechips.rocketchip.subsystem._
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.tile._
|
import freechips.rocketchip.tile._
|
||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
@ -173,7 +173,7 @@ abstract class HellaCache(hartid: Int)(implicit p: Parameters) extends LazyModul
|
|||||||
val module: HellaCacheModule
|
val module: HellaCacheModule
|
||||||
}
|
}
|
||||||
|
|
||||||
class HellaCacheBundle(outer: HellaCache)(implicit p: Parameters) extends CoreBundle()(p) {
|
class HellaCacheBundle(val outer: HellaCache)(implicit p: Parameters) extends CoreBundle()(p) {
|
||||||
val hartid = UInt(INPUT, hartIdLen)
|
val hartid = UInt(INPUT, hartIdLen)
|
||||||
val cpu = (new HellaCacheIO).flip
|
val cpu = (new HellaCacheIO).flip
|
||||||
val ptw = new TLBPTWIO()
|
val ptw = new TLBPTWIO()
|
||||||
|
@ -6,7 +6,7 @@ package freechips.rocketchip.rocket
|
|||||||
import Chisel._
|
import Chisel._
|
||||||
import Chisel.ImplicitConversions._
|
import Chisel.ImplicitConversions._
|
||||||
import freechips.rocketchip.config.Parameters
|
import freechips.rocketchip.config.Parameters
|
||||||
import freechips.rocketchip.coreplex.RocketTilesKey
|
import freechips.rocketchip.subsystem.RocketTilesKey
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.tile._
|
import freechips.rocketchip.tile._
|
||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
@ -81,7 +81,7 @@ class ICachePerfEvents extends Bundle {
|
|||||||
val acquire = Bool()
|
val acquire = Bool()
|
||||||
}
|
}
|
||||||
|
|
||||||
class ICacheBundle(outer: ICache) extends CoreBundle()(outer.p) {
|
class ICacheBundle(val outer: ICache) extends CoreBundle()(outer.p) {
|
||||||
val hartid = UInt(INPUT, hartIdLen)
|
val hartid = UInt(INPUT, hartIdLen)
|
||||||
val req = Decoupled(new ICacheReq).flip
|
val req = Decoupled(new ICacheReq).flip
|
||||||
val s1_paddr = UInt(INPUT, paddrBits) // delayed one cycle w.r.t. req
|
val s1_paddr = UInt(INPUT, paddrBits) // delayed one cycle w.r.t. req
|
||||||
|
@ -6,7 +6,7 @@ package freechips.rocketchip.rocket
|
|||||||
import Chisel._
|
import Chisel._
|
||||||
import Chisel.ImplicitConversions._
|
import Chisel.ImplicitConversions._
|
||||||
import freechips.rocketchip.config.Parameters
|
import freechips.rocketchip.config.Parameters
|
||||||
import freechips.rocketchip.coreplex.CacheBlockBytes
|
import freechips.rocketchip.subsystem.CacheBlockBytes
|
||||||
import freechips.rocketchip.tile._
|
import freechips.rocketchip.tile._
|
||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
|
@ -210,17 +210,17 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p)
|
|||||||
id_ctrl.rocc && csr.io.decode(0).rocc_illegal ||
|
id_ctrl.rocc && csr.io.decode(0).rocc_illegal ||
|
||||||
id_csr_en && (csr.io.decode(0).read_illegal || !id_csr_ren && csr.io.decode(0).write_illegal) ||
|
id_csr_en && (csr.io.decode(0).read_illegal || !id_csr_ren && csr.io.decode(0).write_illegal) ||
|
||||||
!ibuf.io.inst(0).bits.rvc && ((id_sfence || id_system_insn) && csr.io.decode(0).system_illegal)
|
!ibuf.io.inst(0).bits.rvc && ((id_sfence || id_system_insn) && csr.io.decode(0).system_illegal)
|
||||||
// stall decode for fences (now, for AMO.aq; later, for AMO.rl and FENCE)
|
// stall decode for fences (now, for AMO.rl; later, for AMO.aq and FENCE)
|
||||||
val id_amo_aq = id_inst(0)(26)
|
val id_amo_aq = id_inst(0)(26)
|
||||||
val id_amo_rl = id_inst(0)(25)
|
val id_amo_rl = id_inst(0)(25)
|
||||||
val id_fence_next = id_ctrl.fence || id_ctrl.amo && id_amo_rl
|
val id_fence_next = id_ctrl.fence || id_ctrl.amo && id_amo_aq
|
||||||
val id_mem_busy = !io.dmem.ordered || io.dmem.req.valid
|
val id_mem_busy = !io.dmem.ordered || io.dmem.req.valid
|
||||||
when (!id_mem_busy) { id_reg_fence := false }
|
when (!id_mem_busy) { id_reg_fence := false }
|
||||||
val id_rocc_busy = Bool(usingRoCC) &&
|
val id_rocc_busy = Bool(usingRoCC) &&
|
||||||
(io.rocc.busy || ex_reg_valid && ex_ctrl.rocc ||
|
(io.rocc.busy || ex_reg_valid && ex_ctrl.rocc ||
|
||||||
mem_reg_valid && mem_ctrl.rocc || wb_reg_valid && wb_ctrl.rocc)
|
mem_reg_valid && mem_ctrl.rocc || wb_reg_valid && wb_ctrl.rocc)
|
||||||
val id_do_fence = Wire(init = id_rocc_busy && id_ctrl.fence ||
|
val id_do_fence = Wire(init = id_rocc_busy && id_ctrl.fence ||
|
||||||
id_mem_busy && (id_ctrl.amo && id_amo_aq || id_ctrl.fence_i || id_reg_fence && (id_ctrl.mem || id_ctrl.rocc)))
|
id_mem_busy && (id_ctrl.amo && id_amo_rl || id_ctrl.fence_i || id_reg_fence && (id_ctrl.mem || id_ctrl.rocc)))
|
||||||
|
|
||||||
val bpu = Module(new BreakpointUnit(nBreakpoints))
|
val bpu = Module(new BreakpointUnit(nBreakpoints))
|
||||||
bpu.io.status := csr.io.status
|
bpu.io.status := csr.io.status
|
||||||
|
@ -7,7 +7,7 @@ import Chisel._
|
|||||||
import Chisel.ImplicitConversions._
|
import Chisel.ImplicitConversions._
|
||||||
|
|
||||||
import freechips.rocketchip.config.{Field, Parameters}
|
import freechips.rocketchip.config.{Field, Parameters}
|
||||||
import freechips.rocketchip.coreplex.CacheBlockBytes
|
import freechips.rocketchip.subsystem.CacheBlockBytes
|
||||||
import freechips.rocketchip.diplomacy.RegionType
|
import freechips.rocketchip.diplomacy.RegionType
|
||||||
import freechips.rocketchip.tile.{XLen, CoreModule, CoreBundle}
|
import freechips.rocketchip.tile.{XLen, CoreModule, CoreBundle}
|
||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// See LICENSE.SiFive for license details.
|
// See LICENSE.SiFive for license details.
|
||||||
|
|
||||||
package freechips.rocketchip.coreplex
|
package freechips.rocketchip.subsystem
|
||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import freechips.rocketchip.config.Parameters
|
import freechips.rocketchip.config.Parameters
|
||||||
@ -9,14 +9,14 @@ import freechips.rocketchip.tilelink._
|
|||||||
import freechips.rocketchip.devices.tilelink._
|
import freechips.rocketchip.devices.tilelink._
|
||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
|
|
||||||
/** BareCoreplex is the root class for creating a coreplex sub-system */
|
/** BareSubsystem is the root class for creating a subsystem */
|
||||||
abstract class BareCoreplex(implicit p: Parameters) extends LazyModule with BindingScope {
|
abstract class BareSubsystem(implicit p: Parameters) extends LazyModule with BindingScope {
|
||||||
lazy val dts = DTS(bindingTree)
|
lazy val dts = DTS(bindingTree)
|
||||||
lazy val dtb = DTB(dts)
|
lazy val dtb = DTB(dts)
|
||||||
lazy val json = JSON(bindingTree)
|
lazy val json = JSON(bindingTree)
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class BareCoreplexModule[+L <: BareCoreplex](_outer: L) extends LazyModuleImp(_outer) {
|
abstract class BareSubsystemModuleImp[+L <: BareSubsystem](_outer: L) extends LazyModuleImp(_outer) {
|
||||||
val outer = _outer
|
val outer = _outer
|
||||||
ElaborationArtefacts.add("graphml", outer.graphML)
|
ElaborationArtefacts.add("graphml", outer.graphML)
|
||||||
ElaborationArtefacts.add("dts", outer.dts)
|
ElaborationArtefacts.add("dts", outer.dts)
|
||||||
@ -25,16 +25,54 @@ abstract class BareCoreplexModule[+L <: BareCoreplex](_outer: L) extends LazyMod
|
|||||||
println(outer.dts)
|
println(outer.dts)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Base Coreplex class with no peripheral devices or ports added */
|
/** Base Subsystem class with no peripheral devices or ports added */
|
||||||
abstract class BaseCoreplex(implicit p: Parameters) extends BareCoreplex
|
abstract class BaseSubsystem(implicit p: Parameters) extends BareSubsystem {
|
||||||
with HasInterruptBus
|
override val module: BaseSubsystemModuleImp[BaseSubsystem]
|
||||||
with HasSystemBus
|
|
||||||
with HasPeripheryBus
|
// These are wrappers around the standard buses available in all subsytems, where
|
||||||
with HasMemoryBus {
|
// peripherals, tiles, ports, and other masters and slaves can attach themselves.
|
||||||
override val module: BaseCoreplexModule[BaseCoreplex]
|
val ibus = new InterruptBusWrapper()
|
||||||
|
val sbus = LazyModule(new SystemBus(p(SystemBusKey)))
|
||||||
|
val pbus = LazyModule(new PeripheryBus(p(PeripheryBusKey)))
|
||||||
|
val fbus = LazyModule(new FrontBus(p(FrontBusKey)))
|
||||||
|
|
||||||
|
// The sbus masters the pbus; here we convert TL-UH -> TL-UL
|
||||||
|
pbus.fromSystemBus { sbus.toPeripheryBus { pbus.crossTLIn } }
|
||||||
|
|
||||||
|
// The fbus masters the sbus; both are TL-UH or TL-C
|
||||||
|
FlipRendering { implicit p =>
|
||||||
|
fbus.toSystemBus { sbus.fromFrontBus { fbus.crossTLOut } }
|
||||||
|
}
|
||||||
|
|
||||||
|
// The sbus masters the mbus; here we convert TL-C -> TL-UH
|
||||||
|
private val mbusParams = p(MemoryBusKey)
|
||||||
|
private val l2Params = p(BankedL2Key)
|
||||||
|
val MemoryBusParams(memBusBeatBytes, memBusBlockBytes) = mbusParams
|
||||||
|
val BankedL2Params(nMemoryChannels, nBanksPerChannel, coherenceManager) = l2Params
|
||||||
|
val nBanks = l2Params.nBanks
|
||||||
|
val cacheBlockBytes = memBusBlockBytes
|
||||||
|
// TODO: the below call to coherenceManager should be wrapped in a LazyScope here,
|
||||||
|
// but plumbing halt is too annoying for now.
|
||||||
|
private val (in, out, halt) = coherenceManager(this)
|
||||||
|
def memBusCanCauseHalt: () => Option[Bool] = halt
|
||||||
|
|
||||||
|
require (isPow2(nMemoryChannels) || nMemoryChannels == 0)
|
||||||
|
require (isPow2(nBanksPerChannel))
|
||||||
|
require (isPow2(memBusBlockBytes))
|
||||||
|
|
||||||
|
private val mask = ~BigInt((nBanks-1) * memBusBlockBytes)
|
||||||
|
val memBuses = Seq.tabulate(nMemoryChannels) { channel =>
|
||||||
|
val mbus = LazyModule(new MemoryBus(mbusParams)(p))
|
||||||
|
for (bank <- 0 until nBanksPerChannel) {
|
||||||
|
val offset = (bank * nMemoryChannels) + channel
|
||||||
|
ForceFanout(a = true) { implicit p => sbus.toMemoryBus { in } }
|
||||||
|
mbus.fromCoherenceManager(None) { TLFilter(TLFilter.Mmask(AddressSet(offset * memBusBlockBytes, mask))) } := out
|
||||||
|
}
|
||||||
|
mbus
|
||||||
|
}
|
||||||
|
|
||||||
// Make topManagers an Option[] so as to avoid LM name reflection evaluating it...
|
// Make topManagers an Option[] so as to avoid LM name reflection evaluating it...
|
||||||
lazy val topManagers = Some(ManagerUnification(sharedMemoryTLEdge.manager.managers))
|
lazy val topManagers = Some(ManagerUnification(sbus.busView.manager.managers))
|
||||||
ResourceBinding {
|
ResourceBinding {
|
||||||
val managers = topManagers.get
|
val managers = topManagers.get
|
||||||
val max = managers.flatMap(_.address).map(_.max).max
|
val max = managers.flatMap(_.address).map(_.max).max
|
||||||
@ -59,9 +97,9 @@ abstract class BaseCoreplex(implicit p: Parameters) extends BareCoreplex
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class BaseCoreplexModule[+L <: BaseCoreplex](_outer: L) extends BareCoreplexModule(_outer) {
|
abstract class BaseSubsystemModuleImp[+L <: BaseSubsystem](_outer: L) extends BareSubsystemModuleImp(_outer) {
|
||||||
println("Generated Address Map")
|
println("Generated Address Map")
|
||||||
private val aw = (outer.sharedMemoryTLEdge.bundle.addressBits-1)/4 + 1
|
private val aw = (outer.sbus.busView.bundle.addressBits-1)/4 + 1
|
||||||
private val fmt = s"\t%${aw}x - %${aw}x %c%c%c%c%c %s"
|
private val fmt = s"\t%${aw}x - %${aw}x %c%c%c%c%c %s"
|
||||||
|
|
||||||
private def collect(path: List[String], value: ResourceValue): List[(String, ResourceAddress)] = {
|
private def collect(path: List[String], value: ResourceValue): List[(String, ResourceAddress)] = {
|
@ -1,7 +1,7 @@
|
|||||||
// 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.coreplex
|
package freechips.rocketchip.subsystem
|
||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import freechips.rocketchip.config._
|
import freechips.rocketchip.config._
|
||||||
@ -13,7 +13,7 @@ import freechips.rocketchip.tile._
|
|||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
|
|
||||||
class BaseCoreplexConfig extends Config ((site, here, up) => {
|
class BaseSubsystemConfig extends Config ((site, here, up) => {
|
||||||
// Tile parameters
|
// Tile parameters
|
||||||
case PgLevels => if (site(XLen) == 64) 3 /* Sv39 */ else 2 /* Sv32 */
|
case PgLevels => if (site(XLen) == 64) 3 /* Sv39 */ else 2 /* Sv32 */
|
||||||
case XLen => 64 // Applies to all cores
|
case XLen => 64 // Applies to all cores
|
||||||
@ -23,6 +23,7 @@ class BaseCoreplexConfig extends Config ((site, here, up) => {
|
|||||||
case SystemBusKey => SystemBusParams(beatBytes = site(XLen)/8, blockBytes = site(CacheBlockBytes))
|
case SystemBusKey => SystemBusParams(beatBytes = site(XLen)/8, blockBytes = site(CacheBlockBytes))
|
||||||
case PeripheryBusKey => PeripheryBusParams(beatBytes = site(XLen)/8, blockBytes = site(CacheBlockBytes))
|
case PeripheryBusKey => PeripheryBusParams(beatBytes = site(XLen)/8, blockBytes = site(CacheBlockBytes))
|
||||||
case MemoryBusKey => MemoryBusParams(beatBytes = site(XLen)/8, blockBytes = site(CacheBlockBytes))
|
case MemoryBusKey => MemoryBusParams(beatBytes = site(XLen)/8, blockBytes = site(CacheBlockBytes))
|
||||||
|
case FrontBusKey => FrontBusParams(beatBytes = site(XLen)/8, blockBytes = site(CacheBlockBytes))
|
||||||
// Additional device Parameters
|
// Additional device Parameters
|
||||||
case ErrorParams => ErrorParams(Seq(AddressSet(0x3000, 0xfff)), maxAtomic=site(XLen)/8, maxTransfer=4096)
|
case ErrorParams => ErrorParams(Seq(AddressSet(0x3000, 0xfff)), maxAtomic=site(XLen)/8, maxTransfer=4096)
|
||||||
case BootROMParams => BootROMParams(contentFileName = "./bootrom/bootrom.img")
|
case BootROMParams => BootROMParams(contentFileName = "./bootrom/bootrom.img")
|
||||||
@ -155,8 +156,8 @@ class WithIncoherentTiles extends Config((site, here, up) => {
|
|||||||
case RocketCrossingKey => up(RocketCrossingKey, site) map { r =>
|
case RocketCrossingKey => up(RocketCrossingKey, site) map { r =>
|
||||||
r.copy(master = r.master.copy(cork = Some(true)))
|
r.copy(master = r.master.copy(cork = Some(true)))
|
||||||
}
|
}
|
||||||
case BankedL2Key => up(BankedL2Key, site).copy(coherenceManager = { coreplex =>
|
case BankedL2Key => up(BankedL2Key, site).copy(coherenceManager = { subsystem =>
|
||||||
val ww = LazyModule(new TLWidthWidget(coreplex.sbusBeatBytes)(coreplex.p))
|
val ww = LazyModule(new TLWidthWidget(subsystem.sbus.beatBytes)(subsystem.p))
|
||||||
(ww.node, ww.node, () => None)
|
(ww.node, ww.node, () => None)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -270,10 +271,6 @@ class WithJtagDTM extends Config ((site, here, up) => {
|
|||||||
case IncludeJtagDTM => true
|
case IncludeJtagDTM => true
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithNoPeripheryArithAMO extends Config ((site, here, up) => {
|
|
||||||
case PeripheryBusKey => up(PeripheryBusKey, site).copy(arithmetic = false)
|
|
||||||
})
|
|
||||||
|
|
||||||
class WithNBitPeripheryBus(nBits: Int) extends Config ((site, here, up) => {
|
class WithNBitPeripheryBus(nBits: Int) extends Config ((site, here, up) => {
|
||||||
case PeripheryBusKey => up(PeripheryBusKey, site).copy(beatBytes = nBits/8)
|
case PeripheryBusKey => up(PeripheryBusKey, site).copy(beatBytes = nBits/8)
|
||||||
})
|
})
|
@ -1,6 +1,6 @@
|
|||||||
// See LICENSE.SiFive for license details.
|
// See LICENSE.SiFive for license details.
|
||||||
|
|
||||||
package freechips.rocketchip.coreplex
|
package freechips.rocketchip.subsystem
|
||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import freechips.rocketchip.config._
|
import freechips.rocketchip.config._
|
||||||
@ -11,16 +11,16 @@ import freechips.rocketchip.interrupts._
|
|||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
|
|
||||||
/** Enumerates the three types of clock crossing between tiles and system bus */
|
/** Enumerates the three types of clock crossing between tiles and system bus */
|
||||||
sealed trait CoreplexClockCrossing
|
sealed trait SubsystemClockCrossing
|
||||||
{
|
{
|
||||||
def sameClock = this match {
|
def sameClock = this match {
|
||||||
case _: SynchronousCrossing => true
|
case _: SynchronousCrossing => true
|
||||||
case _ => false
|
case _ => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case class SynchronousCrossing(params: BufferParams = BufferParams.default) extends CoreplexClockCrossing
|
case class SynchronousCrossing(params: BufferParams = BufferParams.default) extends SubsystemClockCrossing
|
||||||
case class RationalCrossing(direction: RationalDirection = FastToSlow) extends CoreplexClockCrossing
|
case class RationalCrossing(direction: RationalDirection = FastToSlow) extends SubsystemClockCrossing
|
||||||
case class AsynchronousCrossing(depth: Int, sync: Int = 3) extends CoreplexClockCrossing
|
case class AsynchronousCrossing(depth: Int, sync: Int = 3) extends SubsystemClockCrossing
|
||||||
|
|
||||||
private case class CrossingCheck(out: Boolean, source: BaseNode, sink: BaseNode)
|
private case class CrossingCheck(out: Boolean, source: BaseNode, sink: BaseNode)
|
||||||
|
|
||||||
@ -45,26 +45,26 @@ trait HasCrossingMethods extends LazyModule with LazyScope
|
|||||||
// TileLink
|
// TileLink
|
||||||
|
|
||||||
def crossTLSyncInOut(out: Boolean)(params: BufferParams = BufferParams.default)(implicit p: Parameters): TLNode = {
|
def crossTLSyncInOut(out: Boolean)(params: BufferParams = BufferParams.default)(implicit p: Parameters): TLNode = {
|
||||||
val node = this { LazyModule(new TLBuffer(params)).node }
|
val sync_xing = this { LazyModule(new TLBuffer(params)).node }
|
||||||
checks = CrossingCheck(out, node, node) :: checks
|
checks = CrossingCheck(out, sync_xing, sync_xing) :: checks
|
||||||
node
|
sync_xing
|
||||||
}
|
}
|
||||||
|
|
||||||
def crossTLAsyncInOut(out: Boolean)(depth: Int = 8, sync: Int = 3)(implicit p: Parameters): TLNode = {
|
def crossTLAsyncInOut(out: Boolean)(depth: Int = 8, sync: Int = 3)(implicit p: Parameters): TLNode = {
|
||||||
lazy val asource = LazyModule(new TLAsyncCrossingSource(sync))
|
lazy val async_xing_source = LazyModule(new TLAsyncCrossingSource(sync))
|
||||||
lazy val asink = LazyModule(new TLAsyncCrossingSink(depth, sync))
|
lazy val async_xing_sink = LazyModule(new TLAsyncCrossingSink(depth, sync))
|
||||||
val source = if (out) this { asource } else asource
|
val source = if (out) this { async_xing_source } else async_xing_source
|
||||||
val sink = if (out) asink else this { asink }
|
val sink = if (out) async_xing_sink else this { async_xing_sink }
|
||||||
sink.node :*=* source.node
|
sink.node :*=* source.node
|
||||||
checks = CrossingCheck(out, source.node, sink.node) :: checks
|
checks = CrossingCheck(out, source.node, sink.node) :: checks
|
||||||
NodeHandle(source.node, sink.node)
|
NodeHandle(source.node, sink.node)
|
||||||
}
|
}
|
||||||
|
|
||||||
def crossTLRationalInOut(out: Boolean)(direction: RationalDirection)(implicit p: Parameters): TLNode = {
|
def crossTLRationalInOut(out: Boolean)(direction: RationalDirection)(implicit p: Parameters): TLNode = {
|
||||||
lazy val rsource = LazyModule(new TLRationalCrossingSource)
|
lazy val rational_xing_source = LazyModule(new TLRationalCrossingSource)
|
||||||
lazy val rsink = LazyModule(new TLRationalCrossingSink(if (out) direction else direction.flip))
|
lazy val rational_xing_sink = LazyModule(new TLRationalCrossingSink(if (out) direction else direction.flip))
|
||||||
val source = if (out) this { rsource } else rsource
|
val source = if (out) this { rational_xing_source } else rational_xing_source
|
||||||
val sink = if (out) rsink else this { rsink }
|
val sink = if (out) rational_xing_sink else this { rational_xing_sink }
|
||||||
sink.node :*=* source.node
|
sink.node :*=* source.node
|
||||||
checks = CrossingCheck(out, source.node, sink.node) :: checks
|
checks = CrossingCheck(out, source.node, sink.node) :: checks
|
||||||
NodeHandle(source.node, sink.node)
|
NodeHandle(source.node, sink.node)
|
||||||
@ -77,13 +77,13 @@ trait HasCrossingMethods extends LazyModule with LazyScope
|
|||||||
def crossTLRationalIn (direction: RationalDirection)(implicit p: Parameters): TLNode = crossTLRationalInOut(false)(direction)
|
def crossTLRationalIn (direction: RationalDirection)(implicit p: Parameters): TLNode = crossTLRationalInOut(false)(direction)
|
||||||
def crossTLRationalOut(direction: RationalDirection)(implicit p: Parameters): TLNode = crossTLRationalInOut(true )(direction)
|
def crossTLRationalOut(direction: RationalDirection)(implicit p: Parameters): TLNode = crossTLRationalInOut(true )(direction)
|
||||||
|
|
||||||
def crossTLIn(arg: CoreplexClockCrossing)(implicit p: Parameters): TLNode = arg match {
|
def crossTLIn(arg: SubsystemClockCrossing)(implicit p: Parameters): TLNode = arg match {
|
||||||
case x: SynchronousCrossing => crossTLSyncIn(x.params)
|
case x: SynchronousCrossing => crossTLSyncIn(x.params)
|
||||||
case x: AsynchronousCrossing => crossTLAsyncIn(x.depth, x.sync)
|
case x: AsynchronousCrossing => crossTLAsyncIn(x.depth, x.sync)
|
||||||
case x: RationalCrossing => crossTLRationalIn(x.direction)
|
case x: RationalCrossing => crossTLRationalIn(x.direction)
|
||||||
}
|
}
|
||||||
|
|
||||||
def crossTLOut(arg: CoreplexClockCrossing)(implicit p: Parameters): TLNode = arg match {
|
def crossTLOut(arg: SubsystemClockCrossing)(implicit p: Parameters): TLNode = arg match {
|
||||||
case x: SynchronousCrossing => crossTLSyncOut(x.params)
|
case x: SynchronousCrossing => crossTLSyncOut(x.params)
|
||||||
case x: AsynchronousCrossing => crossTLAsyncOut(x.depth, x.sync)
|
case x: AsynchronousCrossing => crossTLAsyncOut(x.depth, x.sync)
|
||||||
case x: RationalCrossing => crossTLRationalOut(x.direction)
|
case x: RationalCrossing => crossTLRationalOut(x.direction)
|
||||||
@ -92,16 +92,16 @@ trait HasCrossingMethods extends LazyModule with LazyScope
|
|||||||
// AXI4
|
// AXI4
|
||||||
|
|
||||||
def crossAXI4SyncInOut(out: Boolean)(params: BufferParams = BufferParams.default)(implicit p: Parameters): AXI4Node = {
|
def crossAXI4SyncInOut(out: Boolean)(params: BufferParams = BufferParams.default)(implicit p: Parameters): AXI4Node = {
|
||||||
val node = this { LazyModule(new AXI4Buffer(params)).node }
|
val axi4_sync_xing = this { LazyModule(new AXI4Buffer(params)).node }
|
||||||
checks = CrossingCheck(out, node, node) :: checks
|
checks = CrossingCheck(out, axi4_sync_xing, axi4_sync_xing) :: checks
|
||||||
node
|
axi4_sync_xing
|
||||||
}
|
}
|
||||||
|
|
||||||
def crossAXI4AsyncInOut(out: Boolean)(depth: Int = 8, sync: Int = 3)(implicit p: Parameters): AXI4Node = {
|
def crossAXI4AsyncInOut(out: Boolean)(depth: Int = 8, sync: Int = 3)(implicit p: Parameters): AXI4Node = {
|
||||||
lazy val axi4asource = LazyModule(new AXI4AsyncCrossingSource(sync))
|
lazy val axi4_async_xing_source = LazyModule(new AXI4AsyncCrossingSource(sync))
|
||||||
lazy val axi4asink = LazyModule(new AXI4AsyncCrossingSink(depth, sync))
|
lazy val axi4_async_xing_sink = LazyModule(new AXI4AsyncCrossingSink(depth, sync))
|
||||||
val source = if (out) this { axi4asource } else axi4asource
|
val source = if (out) this { axi4_async_xing_source } else axi4_async_xing_source
|
||||||
val sink = if (out) axi4asink else this { axi4asink }
|
val sink = if (out) axi4_async_xing_sink else this { axi4_async_xing_sink }
|
||||||
sink.node :*=* source.node
|
sink.node :*=* source.node
|
||||||
checks = CrossingCheck(out, source.node, sink.node) :: checks
|
checks = CrossingCheck(out, source.node, sink.node) :: checks
|
||||||
NodeHandle(source.node, sink.node)
|
NodeHandle(source.node, sink.node)
|
||||||
@ -112,13 +112,13 @@ trait HasCrossingMethods extends LazyModule with LazyScope
|
|||||||
def crossAXI4AsyncIn (depth: Int = 8, sync: Int = 3)(implicit p: Parameters): AXI4Node = crossAXI4AsyncInOut(false)(depth, sync)
|
def crossAXI4AsyncIn (depth: Int = 8, sync: Int = 3)(implicit p: Parameters): AXI4Node = crossAXI4AsyncInOut(false)(depth, sync)
|
||||||
def crossAXI4AsyncOut(depth: Int = 8, sync: Int = 3)(implicit p: Parameters): AXI4Node = crossAXI4AsyncInOut(true )(depth, sync)
|
def crossAXI4AsyncOut(depth: Int = 8, sync: Int = 3)(implicit p: Parameters): AXI4Node = crossAXI4AsyncInOut(true )(depth, sync)
|
||||||
|
|
||||||
def crossAXI4In(arg: CoreplexClockCrossing)(implicit p: Parameters): AXI4Node = arg match {
|
def crossAXI4In(arg: SubsystemClockCrossing)(implicit p: Parameters): AXI4Node = arg match {
|
||||||
case x: SynchronousCrossing => crossAXI4SyncIn(x.params)
|
case x: SynchronousCrossing => crossAXI4SyncIn(x.params)
|
||||||
case x: AsynchronousCrossing => crossAXI4AsyncIn(x.depth, x.sync)
|
case x: AsynchronousCrossing => crossAXI4AsyncIn(x.depth, x.sync)
|
||||||
case x: RationalCrossing => throw new IllegalArgumentException("AXI4 Rational crossing unimplemented")
|
case x: RationalCrossing => throw new IllegalArgumentException("AXI4 Rational crossing unimplemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
def crossAXI4Out(arg: CoreplexClockCrossing)(implicit p: Parameters): AXI4Node = arg match {
|
def crossAXI4Out(arg: SubsystemClockCrossing)(implicit p: Parameters): AXI4Node = arg match {
|
||||||
case x: SynchronousCrossing => crossAXI4SyncOut(x.params)
|
case x: SynchronousCrossing => crossAXI4SyncOut(x.params)
|
||||||
case x: AsynchronousCrossing => crossAXI4AsyncOut(x.depth, x.sync)
|
case x: AsynchronousCrossing => crossAXI4AsyncOut(x.depth, x.sync)
|
||||||
case x: RationalCrossing => throw new IllegalArgumentException("AXI4 Rational crossing unimplemented")
|
case x: RationalCrossing => throw new IllegalArgumentException("AXI4 Rational crossing unimplemented")
|
||||||
@ -127,30 +127,30 @@ trait HasCrossingMethods extends LazyModule with LazyScope
|
|||||||
// Interrupts
|
// Interrupts
|
||||||
|
|
||||||
def crossIntSyncInOut(out: Boolean)(alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = {
|
def crossIntSyncInOut(out: Boolean)(alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = {
|
||||||
lazy val intssource = LazyModule(new IntSyncCrossingSource(alreadyRegistered))
|
lazy val int_sync_xing_source = LazyModule(new IntSyncCrossingSource(alreadyRegistered))
|
||||||
lazy val intssink = LazyModule(new IntSyncCrossingSink(0))
|
lazy val int_sync_xing_sink = LazyModule(new IntSyncCrossingSink(0))
|
||||||
val source = if (out) this { intssource } else intssource
|
val source = if (out) this { int_sync_xing_source } else int_sync_xing_source
|
||||||
val sink = if (out) intssink else this { intssink }
|
val sink = if (out) int_sync_xing_sink else this { int_sync_xing_sink }
|
||||||
sink.node :*=* source.node
|
sink.node :*=* source.node
|
||||||
checks = CrossingCheck(out, source.node, sink.node) :: checks
|
checks = CrossingCheck(out, source.node, sink.node) :: checks
|
||||||
NodeHandle(source.node, sink.node)
|
NodeHandle(source.node, sink.node)
|
||||||
}
|
}
|
||||||
|
|
||||||
def crossIntAsyncInOut(out: Boolean)(sync: Int = 3, alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = {
|
def crossIntAsyncInOut(out: Boolean)(sync: Int = 3, alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = {
|
||||||
lazy val intasource = LazyModule(new IntSyncCrossingSource(alreadyRegistered))
|
lazy val int_async_xing_source = LazyModule(new IntSyncCrossingSource(alreadyRegistered))
|
||||||
lazy val intasink = LazyModule(new IntSyncCrossingSink(sync))
|
lazy val int_async_xing_sink = LazyModule(new IntSyncCrossingSink(sync))
|
||||||
val source = if (out) this { intasource } else intasource
|
val source = if (out) this { int_async_xing_source } else int_async_xing_source
|
||||||
val sink = if (out) intasink else this { intasink }
|
val sink = if (out) int_async_xing_sink else this { int_async_xing_sink }
|
||||||
sink.node :*=* source.node
|
sink.node :*=* source.node
|
||||||
checks = CrossingCheck(out, source.node, sink.node) :: checks
|
checks = CrossingCheck(out, source.node, sink.node) :: checks
|
||||||
NodeHandle(source.node, sink.node)
|
NodeHandle(source.node, sink.node)
|
||||||
}
|
}
|
||||||
|
|
||||||
def crossIntRationalInOut(out: Boolean)(alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = {
|
def crossIntRationalInOut(out: Boolean)(alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = {
|
||||||
lazy val intrsource = LazyModule(new IntSyncCrossingSource(alreadyRegistered))
|
lazy val int_rational_xing_source = LazyModule(new IntSyncCrossingSource(alreadyRegistered))
|
||||||
lazy val intrsink = LazyModule(new IntSyncCrossingSink(1))
|
lazy val int_rational_xing_sink = LazyModule(new IntSyncCrossingSink(1))
|
||||||
val source = if (out) this { intrsource } else intrsource
|
val source = if (out) this { int_rational_xing_source } else int_rational_xing_source
|
||||||
val sink = if (out) intrsink else this { intrsink }
|
val sink = if (out) int_rational_xing_sink else this { int_rational_xing_sink }
|
||||||
sink.node :*=* source.node
|
sink.node :*=* source.node
|
||||||
checks = CrossingCheck(out, source.node, sink.node) :: checks
|
checks = CrossingCheck(out, source.node, sink.node) :: checks
|
||||||
NodeHandle(source.node, sink.node)
|
NodeHandle(source.node, sink.node)
|
||||||
@ -163,26 +163,26 @@ trait HasCrossingMethods extends LazyModule with LazyScope
|
|||||||
def crossIntRationalIn (alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = crossIntRationalInOut(false)(alreadyRegistered)
|
def crossIntRationalIn (alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = crossIntRationalInOut(false)(alreadyRegistered)
|
||||||
def crossIntRationalOut(alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = crossIntRationalInOut(true )(alreadyRegistered)
|
def crossIntRationalOut(alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = crossIntRationalInOut(true )(alreadyRegistered)
|
||||||
|
|
||||||
def crossIntIn(arg: CoreplexClockCrossing, alreadyRegistered: Boolean)(implicit p: Parameters): IntNode = arg match {
|
def crossIntIn(arg: SubsystemClockCrossing, alreadyRegistered: Boolean)(implicit p: Parameters): IntNode = arg match {
|
||||||
case x: SynchronousCrossing => crossIntSyncIn(alreadyRegistered)
|
case x: SynchronousCrossing => crossIntSyncIn(alreadyRegistered)
|
||||||
case x: AsynchronousCrossing => crossIntAsyncIn(x.sync, alreadyRegistered)
|
case x: AsynchronousCrossing => crossIntAsyncIn(x.sync, alreadyRegistered)
|
||||||
case x: RationalCrossing => crossIntRationalIn(alreadyRegistered)
|
case x: RationalCrossing => crossIntRationalIn(alreadyRegistered)
|
||||||
}
|
}
|
||||||
|
|
||||||
def crossIntOut(arg: CoreplexClockCrossing, alreadyRegistered: Boolean)(implicit p: Parameters): IntNode = arg match {
|
def crossIntOut(arg: SubsystemClockCrossing, alreadyRegistered: Boolean)(implicit p: Parameters): IntNode = arg match {
|
||||||
case x: SynchronousCrossing => crossIntSyncOut(alreadyRegistered)
|
case x: SynchronousCrossing => crossIntSyncOut(alreadyRegistered)
|
||||||
case x: AsynchronousCrossing => crossIntAsyncOut(x.sync, alreadyRegistered)
|
case x: AsynchronousCrossing => crossIntAsyncOut(x.sync, alreadyRegistered)
|
||||||
case x: RationalCrossing => crossIntRationalOut(alreadyRegistered)
|
case x: RationalCrossing => crossIntRationalOut(alreadyRegistered)
|
||||||
}
|
}
|
||||||
|
|
||||||
def crossIntIn (arg: CoreplexClockCrossing)(implicit p: Parameters): IntNode = crossIntIn (arg, false)
|
def crossIntIn (arg: SubsystemClockCrossing)(implicit p: Parameters): IntNode = crossIntIn (arg, false)
|
||||||
def crossIntOut(arg: CoreplexClockCrossing)(implicit p: Parameters): IntNode = crossIntOut(arg, false)
|
def crossIntOut(arg: SubsystemClockCrossing)(implicit p: Parameters): IntNode = crossIntOut(arg, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
trait HasCrossing extends HasCrossingMethods
|
trait HasCrossing extends HasCrossingMethods
|
||||||
{
|
{
|
||||||
this: LazyModule =>
|
this: LazyModule =>
|
||||||
val crossing: CoreplexClockCrossing
|
val crossing: SubsystemClockCrossing
|
||||||
|
|
||||||
def crossTLIn (implicit p: Parameters): TLNode = crossTLIn (crossing)
|
def crossTLIn (implicit p: Parameters): TLNode = crossTLIn (crossing)
|
||||||
def crossTLOut (implicit p: Parameters): TLNode = crossTLOut (crossing)
|
def crossTLOut (implicit p: Parameters): TLNode = crossTLOut (crossing)
|
||||||
@ -195,4 +195,4 @@ trait HasCrossing extends HasCrossingMethods
|
|||||||
def crossIntOut(alreadyRegistered: Boolean)(implicit p: Parameters): IntNode = crossIntOut(crossing, alreadyRegistered)
|
def crossIntOut(alreadyRegistered: Boolean)(implicit p: Parameters): IntNode = crossIntOut(crossing, alreadyRegistered)
|
||||||
}
|
}
|
||||||
|
|
||||||
class CrossingWrapper(val crossing: CoreplexClockCrossing)(implicit p: Parameters) extends SimpleLazyModule with HasCrossing
|
class CrossingWrapper(val crossing: SubsystemClockCrossing)(implicit p: Parameters) extends SimpleLazyModule with HasCrossing
|
50
src/main/scala/subsystem/FrontBus.scala
Normal file
50
src/main/scala/subsystem/FrontBus.scala
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// See LICENSE.SiFive for license details.
|
||||||
|
|
||||||
|
package freechips.rocketchip.subsystem
|
||||||
|
|
||||||
|
import Chisel._
|
||||||
|
import freechips.rocketchip.config.{Field, Parameters}
|
||||||
|
import freechips.rocketchip.diplomacy._
|
||||||
|
import freechips.rocketchip.tilelink._
|
||||||
|
import freechips.rocketchip.util._
|
||||||
|
|
||||||
|
case class FrontBusParams(
|
||||||
|
beatBytes: Int,
|
||||||
|
blockBytes: Int,
|
||||||
|
sbusCrossing: SubsystemClockCrossing = SynchronousCrossing(),
|
||||||
|
sbusBuffer: BufferParams = BufferParams.default) extends HasTLBusParams
|
||||||
|
|
||||||
|
case object FrontBusKey extends Field[FrontBusParams]
|
||||||
|
|
||||||
|
class FrontBus(params: FrontBusParams)
|
||||||
|
(implicit p: Parameters) extends TLBusWrapper(params, "front_bus")
|
||||||
|
with HasTLXbarPhy
|
||||||
|
with HasCrossing {
|
||||||
|
val crossing = params.sbusCrossing
|
||||||
|
|
||||||
|
def fromPort[D,U,E,B <: Data]
|
||||||
|
(name: Option[String] = None, buffers: Int = 1)
|
||||||
|
(gen: => NodeHandle[D,U,E,B,TLClientPortParameters,TLManagerPortParameters,TLEdgeOut,TLBundle] =
|
||||||
|
TLIdentity.gen): InwardNodeHandle[D,U,E,B] = {
|
||||||
|
from("port" named name) { fixFrom(TLFIFOFixer.all, buffers) :=* gen }
|
||||||
|
}
|
||||||
|
|
||||||
|
def fromMasterNode(name: Option[String] = None, buffers: Int = 1)(gen: TLOutwardNode) {
|
||||||
|
from("master" named name) { fixFrom(TLFIFOFixer.all, buffers) :=* gen }
|
||||||
|
}
|
||||||
|
|
||||||
|
def fromMaster[D,U,E,B <: Data]
|
||||||
|
(name: Option[String] = None, buffers: Int = 1)
|
||||||
|
(gen: => NodeHandle[D,U,E,B,TLClientPortParameters,TLManagerPortParameters,TLEdgeOut,TLBundle] =
|
||||||
|
TLIdentity.gen): InwardNodeHandle[D,U,E,B] = {
|
||||||
|
from("master" named name) { fixFrom(TLFIFOFixer.all, buffers) :=* gen }
|
||||||
|
}
|
||||||
|
|
||||||
|
def fromCoherentChip(gen: => TLNode): TLInwardNode = {
|
||||||
|
from("coherent_subsystem") { inwardNode :=* gen }
|
||||||
|
}
|
||||||
|
|
||||||
|
def toSystemBus(gen: => TLInwardNode) {
|
||||||
|
to("sbus") { gen :=* TLBuffer(params.sbusBuffer) :=* outwardNode }
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
// See LICENSE.SiFive for license details.
|
// See LICENSE.SiFive for license details.
|
||||||
|
|
||||||
package freechips.rocketchip.coreplex
|
package freechips.rocketchip.subsystem
|
||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import chisel3.experimental.dontTouch
|
import chisel3.experimental.dontTouch
|
||||||
@ -14,12 +14,14 @@ class ClockedTileInputs(implicit val p: Parameters) extends ParameterizedBundle
|
|||||||
with HasExternallyDrivenTileConstants
|
with HasExternallyDrivenTileConstants
|
||||||
with Clocked
|
with Clocked
|
||||||
|
|
||||||
trait HasTiles extends HasSystemBus {
|
trait HasTiles { this: BaseSubsystem =>
|
||||||
|
implicit val p: Parameters
|
||||||
val tiles: Seq[BaseTile]
|
val tiles: Seq[BaseTile]
|
||||||
protected def tileParams: Seq[TileParams] = tiles.map(_.tileParams)
|
protected def tileParams: Seq[TileParams] = tiles.map(_.tileParams)
|
||||||
def nTiles: Int = tileParams.size
|
def nTiles: Int = tileParams.size
|
||||||
def hartIdList: Seq[Int] = tileParams.map(_.hartId)
|
def hartIdList: Seq[Int] = tileParams.map(_.hartId)
|
||||||
def localIntCounts: Seq[Int] = tileParams.map(_.core.nLocalInterrupts)
|
def localIntCounts: Seq[Int] = tileParams.map(_.core.nLocalInterrupts)
|
||||||
|
def sharedMemoryTLEdge = sbus.busView
|
||||||
}
|
}
|
||||||
|
|
||||||
trait HasTilesBundle {
|
trait HasTilesBundle {
|
@ -1,6 +1,6 @@
|
|||||||
// See LICENSE.SiFive for license details.
|
// See LICENSE.SiFive for license details.
|
||||||
|
|
||||||
package freechips.rocketchip.coreplex
|
package freechips.rocketchip.subsystem
|
||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import freechips.rocketchip.config.{Field, Parameters}
|
import freechips.rocketchip.config.{Field, Parameters}
|
||||||
@ -24,11 +24,6 @@ class InterruptBusWrapper(implicit p: Parameters) {
|
|||||||
def toPLIC: IntOutwardNode = 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 */
|
/** Specifies the number of external interrupts */
|
||||||
case object NExtTopInterrupts extends Field[Int](0)
|
case object NExtTopInterrupts extends Field[Int](0)
|
||||||
|
|
||||||
@ -36,7 +31,7 @@ case object NExtTopInterrupts extends Field[Int](0)
|
|||||||
* However, it should not be used directly; instead one of the below
|
* However, it should not be used directly; instead one of the below
|
||||||
* synchronization wiring child traits should be used.
|
* synchronization wiring child traits should be used.
|
||||||
*/
|
*/
|
||||||
abstract trait HasExtInterrupts extends HasInterruptBus {
|
abstract trait HasExtInterrupts { this: BaseSubsystem =>
|
||||||
private val device = new Device with DeviceInterrupts {
|
private val device = new Device with DeviceInterrupts {
|
||||||
def describe(resources: ResourceBindings): Description = {
|
def describe(resources: ResourceBindings): Description = {
|
||||||
Description("soc/external-interrupts", describeInterrupts(resources))
|
Description("soc/external-interrupts", describeInterrupts(resources))
|
||||||
@ -50,7 +45,7 @@ abstract trait HasExtInterrupts extends HasInterruptBus {
|
|||||||
/** This trait should be used if the External Interrupts have NOT
|
/** This trait should be used if the External Interrupts have NOT
|
||||||
* already been synchronized to the Periphery (PLIC) Clock.
|
* already been synchronized to the Periphery (PLIC) Clock.
|
||||||
*/
|
*/
|
||||||
trait HasAsyncExtInterrupts extends HasExtInterrupts {
|
trait HasAsyncExtInterrupts extends HasExtInterrupts { this: BaseSubsystem =>
|
||||||
if (nExtInterrupts > 0) {
|
if (nExtInterrupts > 0) {
|
||||||
ibus.fromAsync := extInterrupts
|
ibus.fromAsync := extInterrupts
|
||||||
}
|
}
|
||||||
@ -59,7 +54,7 @@ trait HasAsyncExtInterrupts extends HasExtInterrupts {
|
|||||||
/** This trait can be used if the External Interrupts have already been synchronized
|
/** This trait can be used if the External Interrupts have already been synchronized
|
||||||
* to the Periphery (PLIC) Clock.
|
* to the Periphery (PLIC) Clock.
|
||||||
*/
|
*/
|
||||||
trait HasSyncExtInterrupts extends HasExtInterrupts {
|
trait HasSyncExtInterrupts extends HasExtInterrupts { this: BaseSubsystem =>
|
||||||
if (nExtInterrupts > 0) {
|
if (nExtInterrupts > 0) {
|
||||||
ibus.fromSync := extInterrupts
|
ibus.fromSync := extInterrupts
|
||||||
}
|
}
|
77
src/main/scala/subsystem/MemoryBus.scala
Normal file
77
src/main/scala/subsystem/MemoryBus.scala
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
// See LICENSE.SiFive for license details.
|
||||||
|
|
||||||
|
package freechips.rocketchip.subsystem
|
||||||
|
|
||||||
|
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](64)
|
||||||
|
|
||||||
|
/** L2 Broadcast Hub configuration */
|
||||||
|
case class BroadcastParams(
|
||||||
|
nTrackers: Int = 4,
|
||||||
|
bufferless: Boolean = false)
|
||||||
|
|
||||||
|
case object BroadcastKey extends Field(BroadcastParams())
|
||||||
|
|
||||||
|
/** L2 memory subsystem configuration */
|
||||||
|
case class BankedL2Params(
|
||||||
|
nMemoryChannels: Int = 1,
|
||||||
|
nBanksPerChannel: Int = 1,
|
||||||
|
coherenceManager: BaseSubsystem => (TLInwardNode, TLOutwardNode, () => Option[Bool]) = { subsystem =>
|
||||||
|
implicit val p = subsystem.p
|
||||||
|
val BroadcastParams(nTrackers, bufferless) = p(BroadcastKey)
|
||||||
|
val bh = LazyModule(new TLBroadcast(subsystem.memBusBlockBytes, nTrackers, bufferless))
|
||||||
|
val ww = LazyModule(new TLWidthWidget(subsystem.sbus.beatBytes))
|
||||||
|
ww.node :*= bh.node
|
||||||
|
(bh.node, ww.node, () => None)
|
||||||
|
}) {
|
||||||
|
val nBanks = nMemoryChannels*nBanksPerChannel
|
||||||
|
}
|
||||||
|
|
||||||
|
case object BankedL2Key extends Field(BankedL2Params())
|
||||||
|
|
||||||
|
/** Parameterization of the memory-side bus created for each memory channel */
|
||||||
|
case class MemoryBusParams(beatBytes: Int, blockBytes: Int) extends HasTLBusParams
|
||||||
|
|
||||||
|
case object MemoryBusKey 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, "memory_bus")(p)
|
||||||
|
with HasTLXbarPhy {
|
||||||
|
|
||||||
|
def fromCoherenceManager(
|
||||||
|
name: Option[String] = None,
|
||||||
|
buffer: BufferParams = BufferParams.none)
|
||||||
|
(gen: => TLNode): TLInwardNode = {
|
||||||
|
from("coherence_manager" named name) {
|
||||||
|
inwardNode := TLBuffer(buffer) := gen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def toDRAMController[D,U,E,B <: Data]
|
||||||
|
(name: Option[String] = None, buffer: BufferParams = BufferParams.none)
|
||||||
|
(gen: => NodeHandle[ TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle, D,U,E,B] =
|
||||||
|
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
|
||||||
|
to("memory_controller" named name) { gen := bufferTo(buffer) }
|
||||||
|
}
|
||||||
|
|
||||||
|
def toVariableWidthSlave[D,U,E,B <: Data]
|
||||||
|
(name: Option[String] = None, buffer: BufferParams = BufferParams.none)
|
||||||
|
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] =
|
||||||
|
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
|
||||||
|
to("slave" named name) { gen :*= fragmentTo(buffer) }
|
||||||
|
}
|
||||||
|
|
||||||
|
def toFixedWidthSlave[D,U,E,B <: Data]
|
||||||
|
(name: Option[String] = None, buffer: BufferParams = BufferParams.none)
|
||||||
|
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] =
|
||||||
|
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
|
||||||
|
to("slave" named name) { gen :*= fixedWidthTo(buffer) }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
117
src/main/scala/subsystem/PeripheryBus.scala
Normal file
117
src/main/scala/subsystem/PeripheryBus.scala
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
// See LICENSE.SiFive for license details.
|
||||||
|
|
||||||
|
package freechips.rocketchip.subsystem
|
||||||
|
|
||||||
|
import Chisel._
|
||||||
|
import freechips.rocketchip.config.{Field, Parameters}
|
||||||
|
import freechips.rocketchip.diplomacy._
|
||||||
|
import freechips.rocketchip.tilelink._
|
||||||
|
import freechips.rocketchip.util._
|
||||||
|
|
||||||
|
case class PeripheryBusParams(
|
||||||
|
beatBytes: Int,
|
||||||
|
blockBytes: Int,
|
||||||
|
arithmeticAtomics: Boolean = true,
|
||||||
|
bufferAtomics: BufferParams = BufferParams.default,
|
||||||
|
sbusCrossingType: SubsystemClockCrossing = SynchronousCrossing(), // relative to sbus
|
||||||
|
frequency: BigInt = BigInt(100000000) // 100 MHz as default bus frequency
|
||||||
|
) extends HasTLBusParams
|
||||||
|
|
||||||
|
case object PeripheryBusKey extends Field[PeripheryBusParams]
|
||||||
|
|
||||||
|
class PeripheryBus(params: PeripheryBusParams)
|
||||||
|
(implicit p: Parameters) extends TLBusWrapper(params, "periphery_bus")
|
||||||
|
with HasTLXbarPhy
|
||||||
|
with HasCrossing {
|
||||||
|
val crossing = params.sbusCrossingType
|
||||||
|
|
||||||
|
def toSlave[D,U,E,B <: Data]
|
||||||
|
(name: Option[String] = None, buffer: BufferParams = BufferParams.none)
|
||||||
|
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] =
|
||||||
|
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
|
||||||
|
to("slave" named name) { gen :*= bufferTo(buffer) }
|
||||||
|
}
|
||||||
|
|
||||||
|
def toVariableWidthSlaveNode(name: Option[String] = None, buffer: BufferParams = BufferParams.none)(node: TLInwardNode) { toVariableWidthSlaveNodeOption(name, buffer)(Some(node)) }
|
||||||
|
|
||||||
|
def toVariableWidthSlaveNodeOption(name: Option[String] = None, buffer: BufferParams = BufferParams.none)(node: Option[TLInwardNode]) {
|
||||||
|
node foreach { n => to("slave" named name) { n :*= fragmentTo(buffer) } }
|
||||||
|
}
|
||||||
|
|
||||||
|
def toVariableWidthSlave[D,U,E,B <: Data]
|
||||||
|
(name: Option[String] = None, buffer: BufferParams = BufferParams.none)
|
||||||
|
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] =
|
||||||
|
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
|
||||||
|
to("slave" named name) { gen :*= fragmentTo(buffer) }
|
||||||
|
}
|
||||||
|
|
||||||
|
def toFixedWidthSlaveNode(name: Option[String] = None, buffer: BufferParams = BufferParams.none)(gen: TLInwardNode) {
|
||||||
|
to("slave" named name) { gen :*= fixedWidthTo(buffer) }
|
||||||
|
}
|
||||||
|
|
||||||
|
def toFixedWidthSlave[D,U,E,B <: Data]
|
||||||
|
(name: Option[String] = None, buffer: BufferParams = BufferParams.none)
|
||||||
|
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] =
|
||||||
|
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
|
||||||
|
to("slave" named name) { gen :*= fixedWidthTo(buffer) }
|
||||||
|
}
|
||||||
|
|
||||||
|
def toFixedWidthSingleBeatSlaveNode
|
||||||
|
(widthBytes: Int, name: Option[String] = None, buffer: BufferParams = BufferParams.none)
|
||||||
|
(gen: TLInwardNode) {
|
||||||
|
to("slave" named name) {
|
||||||
|
gen :*= TLFragmenter(widthBytes, params.blockBytes) :*= fixedWidthTo(buffer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def toFixedWidthSingleBeatSlave[D,U,E,B <: Data]
|
||||||
|
(widthBytes: Int, name: Option[String] = None, buffer: BufferParams = BufferParams.none)
|
||||||
|
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] =
|
||||||
|
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
|
||||||
|
to("slave" named name) {
|
||||||
|
gen :*= TLFragmenter(widthBytes, params.blockBytes) :*= fixedWidthTo(buffer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def toLargeBurstSlave[D,U,E,B <: Data]
|
||||||
|
(maxXferBytes: Int, name: Option[String] = None, buffer: BufferParams = BufferParams.none)
|
||||||
|
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] =
|
||||||
|
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
|
||||||
|
to("slave" named name) {
|
||||||
|
gen :*= fragmentTo(params.beatBytes, maxXferBytes, buffer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def toFixedWidthPort[D,U,E,B <: Data]
|
||||||
|
(name: Option[String] = None, buffer: BufferParams = BufferParams.none)
|
||||||
|
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] =
|
||||||
|
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
|
||||||
|
to("port" named name) { gen := fixedWidthTo(buffer) }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def fromSystemBus(gen: => TLOutwardNode) {
|
||||||
|
from("sbus") {
|
||||||
|
(inwardNode
|
||||||
|
:*= TLBuffer(params.bufferAtomics)
|
||||||
|
:*= TLAtomicAutomata(arithmetic = params.arithmeticAtomics)
|
||||||
|
:*= gen)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def fromOtherMaster[D,U,E,B <: Data]
|
||||||
|
(name: Option[String] = None, buffer: BufferParams = BufferParams.none)
|
||||||
|
(gen: => NodeHandle[D,U,E,B,TLClientPortParameters,TLManagerPortParameters,TLEdgeOut,TLBundle] =
|
||||||
|
TLIdentity.gen): InwardNodeHandle[D,U,E,B] = {
|
||||||
|
from("master" named name) { bufferFrom(buffer) :=* gen }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def toTile
|
||||||
|
(name: Option[String] = None, buffers: Int = 0)
|
||||||
|
(gen: => TLNode): TLOutwardNode = {
|
||||||
|
to("tile" named name) { FlipRendering { implicit p =>
|
||||||
|
gen :*= bufferTo(buffers)
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
// See LICENSE.SiFive for license details.
|
// See LICENSE.SiFive for license details.
|
||||||
|
|
||||||
package freechips.rocketchip.coreplex
|
package freechips.rocketchip.subsystem
|
||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import freechips.rocketchip.config.{Field, Parameters}
|
import freechips.rocketchip.config.{Field, Parameters}
|
||||||
@ -27,11 +27,13 @@ case object ExtIn extends Field[SlavePortParams]
|
|||||||
///// The following traits add ports to the sytem, in some cases converting to different interconnect standards
|
///// 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. */
|
/** Adds a port to the system intended to master an AXI4 DRAM controller. */
|
||||||
trait HasMasterAXI4MemPort extends HasMemoryBus {
|
trait HasMasterAXI4MemPort { this: BaseSubsystem =>
|
||||||
val module: HasMasterAXI4MemPortModuleImp
|
val module: HasMasterAXI4MemPortModuleImp
|
||||||
|
|
||||||
private val params = p(ExtMem)
|
private val params = p(ExtMem)
|
||||||
|
private val portName = "axi4"
|
||||||
private val device = new MemoryDevice
|
private val device = new MemoryDevice
|
||||||
|
val nMemoryChannels: Int
|
||||||
|
|
||||||
val mem_axi4 = AXI4SlaveNode(Seq.tabulate(nMemoryChannels) { channel =>
|
val mem_axi4 = AXI4SlaveNode(Seq.tabulate(nMemoryChannels) { channel =>
|
||||||
val base = AddressSet(params.base, params.size-1)
|
val base = AddressSet(params.base, params.size-1)
|
||||||
@ -49,13 +51,10 @@ trait HasMasterAXI4MemPort extends HasMemoryBus {
|
|||||||
beatBytes = params.beatBytes)
|
beatBytes = params.beatBytes)
|
||||||
})
|
})
|
||||||
|
|
||||||
val converter = LazyModule(new TLToAXI4())
|
memBuses.map { m =>
|
||||||
val trim = LazyModule(new AXI4IdIndexer(params.idBits))
|
mem_axi4 := m.toDRAMController(Some(portName)) {
|
||||||
val yank = LazyModule(new AXI4UserYanker)
|
(AXI4UserYanker() := AXI4IdIndexer(params.idBits) := TLToAXI4())
|
||||||
val buffer = LazyModule(new AXI4Buffer)
|
}
|
||||||
|
|
||||||
memBuses.map(_.toDRAMController).foreach { case node =>
|
|
||||||
mem_axi4 := buffer.node := yank.node := trim.node := converter.node := node
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,15 +74,17 @@ trait HasMasterAXI4MemPortBundle {
|
|||||||
/** Actually generates the corresponding IO in the concrete Module */
|
/** Actually generates the corresponding IO in the concrete Module */
|
||||||
trait HasMasterAXI4MemPortModuleImp extends LazyModuleImp with HasMasterAXI4MemPortBundle {
|
trait HasMasterAXI4MemPortModuleImp extends LazyModuleImp with HasMasterAXI4MemPortBundle {
|
||||||
val outer: HasMasterAXI4MemPort
|
val outer: HasMasterAXI4MemPort
|
||||||
|
|
||||||
val mem_axi4 = IO(HeterogeneousBag.fromNode(outer.mem_axi4.in))
|
val mem_axi4 = IO(HeterogeneousBag.fromNode(outer.mem_axi4.in))
|
||||||
(mem_axi4 zip outer.mem_axi4.in) foreach { case (i, (o, _)) => i <> o }
|
(mem_axi4 zip outer.mem_axi4.in) foreach { case (i, (o, _)) => i <> o }
|
||||||
val nMemoryChannels = outer.nMemoryChannels
|
val nMemoryChannels = outer.nMemoryChannels
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds a AXI4 port to the system intended to master an MMIO device bus */
|
/** Adds a AXI4 port to the system intended to master an MMIO device bus */
|
||||||
trait HasMasterAXI4MMIOPort extends HasSystemBus {
|
trait HasMasterAXI4MMIOPort { this: BaseSubsystem =>
|
||||||
private val params = p(ExtBus)
|
private val params = p(ExtBus)
|
||||||
private val device = new SimpleBus("mmio", Nil)
|
private val portName = "mmio_port_axi4"
|
||||||
|
private val device = new SimpleBus(portName.kebab, Nil)
|
||||||
val mmio_axi4 = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
|
val mmio_axi4 = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
|
||||||
slaves = Seq(AXI4SlaveParameters(
|
slaves = Seq(AXI4SlaveParameters(
|
||||||
address = AddressSet.misaligned(params.base, params.size),
|
address = AddressSet.misaligned(params.base, params.size),
|
||||||
@ -93,13 +94,13 @@ trait HasMasterAXI4MMIOPort extends HasSystemBus {
|
|||||||
supportsRead = TransferSizes(1, params.maxXferBytes))),
|
supportsRead = TransferSizes(1, params.maxXferBytes))),
|
||||||
beatBytes = params.beatBytes)))
|
beatBytes = params.beatBytes)))
|
||||||
|
|
||||||
(mmio_axi4
|
mmio_axi4 := sbus.toFixedWidthPort(Some(portName)) {
|
||||||
:= AXI4Buffer()
|
(AXI4Buffer()
|
||||||
:= AXI4UserYanker()
|
:= AXI4UserYanker()
|
||||||
:= AXI4Deinterleaver(sbus.blockBytes)
|
:= AXI4Deinterleaver(sbus.blockBytes)
|
||||||
:= AXI4IdIndexer(params.idBits)
|
:= AXI4IdIndexer(params.idBits)
|
||||||
:= TLToAXI4()
|
:= TLToAXI4())
|
||||||
:= sbus.toFixedWidthPorts)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Common io name and methods for propagating or tying off the port bundle */
|
/** Common io name and methods for propagating or tying off the port bundle */
|
||||||
@ -120,21 +121,22 @@ trait HasMasterAXI4MMIOPortModuleImp extends LazyModuleImp with HasMasterAXI4MMI
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Adds an AXI4 port to the system intended to be a slave on an MMIO device bus */
|
/** Adds an AXI4 port to the system intended to be a slave on an MMIO device bus */
|
||||||
trait HasSlaveAXI4Port extends HasSystemBus {
|
trait HasSlaveAXI4Port { this: BaseSubsystem =>
|
||||||
private val params = p(ExtIn)
|
private val params = p(ExtIn)
|
||||||
|
private val portName = "slave_port_axi4"
|
||||||
val l2FrontendAXI4Node = AXI4MasterNode(Seq(AXI4MasterPortParameters(
|
val l2FrontendAXI4Node = AXI4MasterNode(Seq(AXI4MasterPortParameters(
|
||||||
masters = Seq(AXI4MasterParameters(
|
masters = Seq(AXI4MasterParameters(
|
||||||
name = "AXI4 periphery",
|
name = portName.kebab,
|
||||||
id = IdRange(0, 1 << params.idBits))))))
|
id = IdRange(0, 1 << params.idBits))))))
|
||||||
|
|
||||||
private val fifoBits = 1
|
private val fifoBits = 1
|
||||||
(sbus.fromSyncPorts()
|
sbus.fromPort(Some(portName)) {
|
||||||
:= TLWidthWidget(params.beatBytes)
|
(TLWidthWidget(params.beatBytes)
|
||||||
:= AXI4ToTL()
|
:= AXI4ToTL()
|
||||||
:= AXI4UserYanker(Some(1 << (params.sourceBits - fifoBits - 1)))
|
:= AXI4UserYanker(Some(1 << (params.sourceBits - fifoBits - 1)))
|
||||||
:= AXI4Fragmenter()
|
:= AXI4Fragmenter()
|
||||||
:= AXI4IdIndexer(fifoBits)
|
:= AXI4IdIndexer(fifoBits))
|
||||||
:= l2FrontendAXI4Node)
|
} := l2FrontendAXI4Node
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Common io name and methods for propagating or tying off the port bundle */
|
/** Common io name and methods for propagating or tying off the port bundle */
|
||||||
@ -160,9 +162,10 @@ trait HasSlaveAXI4PortModuleImp extends LazyModuleImp with HasSlaveAXI4PortBundl
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Adds a TileLink port to the system intended to master an MMIO device bus */
|
/** Adds a TileLink port to the system intended to master an MMIO device bus */
|
||||||
trait HasMasterTLMMIOPort extends HasSystemBus {
|
trait HasMasterTLMMIOPort { this: BaseSubsystem =>
|
||||||
private val params = p(ExtBus)
|
private val params = p(ExtBus)
|
||||||
private val device = new SimpleBus("mmio", Nil)
|
private val portName = "mmio_port_tl"
|
||||||
|
private val device = new SimpleBus(portName.kebab, Nil)
|
||||||
val mmio_tl = TLManagerNode(Seq(TLManagerPortParameters(
|
val mmio_tl = TLManagerNode(Seq(TLManagerPortParameters(
|
||||||
managers = Seq(TLManagerParameters(
|
managers = Seq(TLManagerParameters(
|
||||||
address = AddressSet.misaligned(params.base, params.size),
|
address = AddressSet.misaligned(params.base, params.size),
|
||||||
@ -173,7 +176,9 @@ trait HasMasterTLMMIOPort extends HasSystemBus {
|
|||||||
supportsPutPartial = TransferSizes(1, sbus.blockBytes))),
|
supportsPutPartial = TransferSizes(1, sbus.blockBytes))),
|
||||||
beatBytes = params.beatBytes)))
|
beatBytes = params.beatBytes)))
|
||||||
|
|
||||||
mmio_tl := TLBuffer() := TLSourceShrinker(1 << params.idBits) := sbus.toFixedWidthPorts
|
mmio_tl := sbus.toFixedWidthPort(Some(portName)) {
|
||||||
|
TLBuffer() := TLSourceShrinker(1 << params.idBits)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Common io name and methods for propagating or tying off the port bundle */
|
/** Common io name and methods for propagating or tying off the port bundle */
|
||||||
@ -201,14 +206,17 @@ trait HasMasterTLMMIOPortModuleImp extends LazyModuleImp with HasMasterTLMMIOPor
|
|||||||
/** Adds an TL port to the system intended to be a slave on an MMIO device bus.
|
/** 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.
|
* NOTE: this port is NOT allowed to issue Acquires.
|
||||||
*/
|
*/
|
||||||
trait HasSlaveTLPort extends HasSystemBus {
|
trait HasSlaveTLPort { this: BaseSubsystem =>
|
||||||
private val params = p(ExtIn)
|
private val params = p(ExtIn)
|
||||||
|
private val portName = "slave_port_tl"
|
||||||
val l2FrontendTLNode = TLClientNode(Seq(TLClientPortParameters(
|
val l2FrontendTLNode = TLClientNode(Seq(TLClientPortParameters(
|
||||||
clients = Seq(TLClientParameters(
|
clients = Seq(TLClientParameters(
|
||||||
name = "Front Port (TL)",
|
name = portName.kebab,
|
||||||
sourceId = IdRange(0, 1 << params.idBits))))))
|
sourceId = IdRange(0, 1 << params.idBits))))))
|
||||||
|
|
||||||
sbus.fromSyncPorts() := TLSourceShrinker(1 << params.sourceBits) := TLWidthWidget(params.beatBytes) := l2FrontendTLNode
|
sbus.fromPort(Some(portName)) {
|
||||||
|
TLSourceShrinker(1 << params.sourceBits) := TLWidthWidget(params.beatBytes)
|
||||||
|
} := l2FrontendTLNode
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Common io name and methods for propagating or tying off the port bundle */
|
/** Common io name and methods for propagating or tying off the port bundle */
|
@ -1,13 +1,13 @@
|
|||||||
// See LICENSE.SiFive for license details.
|
// See LICENSE.SiFive for license details.
|
||||||
|
|
||||||
package freechips.rocketchip.coreplex
|
package freechips.rocketchip.subsystem
|
||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import freechips.rocketchip.diplomacy.{LazyModuleImp, DTSTimebase}
|
import freechips.rocketchip.diplomacy.{LazyModuleImp, DTSTimebase}
|
||||||
import freechips.rocketchip.devices.tilelink.HasPeripheryClint
|
import freechips.rocketchip.devices.tilelink.HasPeripheryCLINT
|
||||||
|
|
||||||
trait HasRTCModuleImp extends LazyModuleImp {
|
trait HasRTCModuleImp extends LazyModuleImp {
|
||||||
val outer: HasPeripheryClint
|
val outer: BaseSubsystem with HasPeripheryCLINT
|
||||||
private val pbusFreq = outer.p(PeripheryBusKey).frequency
|
private val pbusFreq = outer.p(PeripheryBusKey).frequency
|
||||||
private val rtcFreq = outer.p(DTSTimebase)
|
private val rtcFreq = outer.p(DTSTimebase)
|
||||||
private val internalPeriod: BigInt = pbusFreq / rtcFreq
|
private val internalPeriod: BigInt = pbusFreq / rtcFreq
|
@ -1,6 +1,6 @@
|
|||||||
// See LICENSE.SiFive for license details.
|
// See LICENSE.SiFive for license details.
|
||||||
|
|
||||||
package freechips.rocketchip.coreplex
|
package freechips.rocketchip.subsystem
|
||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
// See LICENSE.SiFive for license details.
|
// See LICENSE.SiFive for license details.
|
||||||
|
|
||||||
package freechips.rocketchip.coreplex
|
package freechips.rocketchip.subsystem
|
||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import chisel3.internal.sourceinfo.SourceInfo
|
import chisel3.internal.sourceinfo.SourceInfo
|
||||||
@ -14,41 +14,11 @@ import freechips.rocketchip.interrupts._
|
|||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
|
|
||||||
// TODO: how specific are these to RocketTiles?
|
// TODO: how specific are these to RocketTiles?
|
||||||
case class TileMasterPortParams(
|
case class TileMasterPortParams(buffers: Int = 0, cork: Option[Boolean] = None)
|
||||||
addBuffers: Int = 0,
|
case class TileSlavePortParams(buffers: Int = 0, blockerCtrlAddr: Option[BigInt] = None)
|
||||||
cork: Option[Boolean] = None) {
|
|
||||||
|
|
||||||
def adapt(coreplex: HasPeripheryBus)
|
|
||||||
(masterNode: TLOutwardNode)
|
|
||||||
(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
|
||||||
val tile_master_cork = cork.map(u => (LazyModule(new TLCacheCork(unsafe = u))))
|
|
||||||
val tile_master_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.allUncacheable))
|
|
||||||
|
|
||||||
(Seq(tile_master_fixer.node) ++ TLBuffer.chain(addBuffers) ++ tile_master_cork.map(_.node))
|
|
||||||
.foldRight(masterNode)(_ :=* _)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case class TileSlavePortParams(
|
|
||||||
addBuffers: Int = 0,
|
|
||||||
blockerCtrlAddr: Option[BigInt] = None) {
|
|
||||||
|
|
||||||
def adapt(coreplex: HasPeripheryBus)
|
|
||||||
(slaveNode: TLInwardNode)
|
|
||||||
(implicit p: Parameters, sourceInfo: SourceInfo): TLInwardNode = {
|
|
||||||
val tile_slave_blocker =
|
|
||||||
blockerCtrlAddr
|
|
||||||
.map(BasicBusBlockerParams(_, coreplex.pbus.beatBytes, coreplex.sbus.beatBytes))
|
|
||||||
.map(bp => LazyModule(new BasicBusBlocker(bp)))
|
|
||||||
|
|
||||||
tile_slave_blocker.foreach { _.controlNode := coreplex.pbus.toVariableWidthSlaves }
|
|
||||||
(Seq() ++ tile_slave_blocker.map(_.node) ++ TLBuffer.chain(addBuffers))
|
|
||||||
.foldLeft(slaveNode)(_ :*= _)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case class RocketCrossingParams(
|
case class RocketCrossingParams(
|
||||||
crossingType: CoreplexClockCrossing = SynchronousCrossing(),
|
crossingType: SubsystemClockCrossing = SynchronousCrossing(),
|
||||||
master: TileMasterPortParams = TileMasterPortParams(),
|
master: TileMasterPortParams = TileMasterPortParams(),
|
||||||
slave: TileSlavePortParams = TileSlavePortParams()) {
|
slave: TileSlavePortParams = TileSlavePortParams()) {
|
||||||
def knownRatio: Option[Int] = crossingType match {
|
def knownRatio: Option[Int] = crossingType match {
|
||||||
@ -61,10 +31,9 @@ case object RocketTilesKey extends Field[Seq[RocketTileParams]](Nil)
|
|||||||
case object RocketCrossingKey extends Field[Seq[RocketCrossingParams]](List(RocketCrossingParams()))
|
case object RocketCrossingKey extends Field[Seq[RocketCrossingParams]](List(RocketCrossingParams()))
|
||||||
|
|
||||||
trait HasRocketTiles extends HasTiles
|
trait HasRocketTiles extends HasTiles
|
||||||
with HasPeripheryBus
|
|
||||||
with HasPeripheryPLIC
|
with HasPeripheryPLIC
|
||||||
with HasPeripheryClint
|
with HasPeripheryCLINT
|
||||||
with HasPeripheryDebug {
|
with HasPeripheryDebug { this: BaseSubsystem =>
|
||||||
val module: HasRocketTilesModuleImp
|
val module: HasRocketTilesModuleImp
|
||||||
|
|
||||||
protected val rocketTileParams = p(RocketTilesKey)
|
protected val rocketTileParams = p(RocketTilesKey)
|
||||||
@ -95,7 +64,7 @@ trait HasRocketTiles extends HasTiles
|
|||||||
|
|
||||||
def tileMasterBuffering: TLOutwardNode = rocket {
|
def tileMasterBuffering: TLOutwardNode = rocket {
|
||||||
// The buffers needed to cut feed-through paths are microarchitecture specific, so belong here
|
// The buffers needed to cut feed-through paths are microarchitecture specific, so belong here
|
||||||
val masterBuffer = LazyModule(new TLBuffer(BufferParams.none, BufferParams.flow, BufferParams.none, BufferParams.flow, BufferParams(1)))
|
val masterBufferNode = TLBuffer(BufferParams.none, BufferParams.flow, BufferParams.none, BufferParams.flow, BufferParams(1))
|
||||||
crossing.crossingType match {
|
crossing.crossingType match {
|
||||||
case _: AsynchronousCrossing => rocket.masterNode
|
case _: AsynchronousCrossing => rocket.masterNode
|
||||||
case SynchronousCrossing(b) =>
|
case SynchronousCrossing(b) =>
|
||||||
@ -104,28 +73,41 @@ trait HasRocketTiles extends HasTiles
|
|||||||
case RationalCrossing(dir) =>
|
case RationalCrossing(dir) =>
|
||||||
require (dir != SlowToFast, "Misconfiguration? Core slower than fabric")
|
require (dir != SlowToFast, "Misconfiguration? Core slower than fabric")
|
||||||
if (tp.boundaryBuffers) {
|
if (tp.boundaryBuffers) {
|
||||||
masterBuffer.node :=* rocket.masterNode
|
masterBufferNode :=* rocket.masterNode
|
||||||
} else {
|
} else {
|
||||||
rocket.masterNode
|
rocket.masterNode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sbus.fromTile(tp.name) { implicit p => crossing.master.adapt(this)(rocket.crossTLOut :=* tileMasterBuffering) }
|
sbus.fromTile(tp.name, crossing.master.buffers) {
|
||||||
|
crossing.master.cork
|
||||||
|
.map { u => TLCacheCork(unsafe = u) }
|
||||||
|
.map { _ :=* rocket.crossTLOut }
|
||||||
|
.getOrElse { rocket.crossTLOut }
|
||||||
|
} :=* tileMasterBuffering
|
||||||
|
|
||||||
// Connect the slave ports of the tile to the periphery bus
|
// Connect the slave ports of the tile to the periphery bus
|
||||||
|
|
||||||
def tileSlaveBuffering: TLInwardNode = rocket {
|
def tileSlaveBuffering: TLInwardNode = rocket {
|
||||||
val slaveBuffer = LazyModule(new TLBuffer(BufferParams.flow, BufferParams.none, BufferParams.none, BufferParams.none, BufferParams.none))
|
val slaveBufferNode = TLBuffer(BufferParams.flow, BufferParams.none, BufferParams.none, BufferParams.none, BufferParams.none)
|
||||||
crossing.crossingType match {
|
crossing.crossingType match {
|
||||||
case RationalCrossing(_) if (tp.boundaryBuffers) => rocket.slaveNode :*= slaveBuffer.node
|
case RationalCrossing(_) if (tp.boundaryBuffers) => rocket.slaveNode :*= slaveBufferNode
|
||||||
case _ => rocket.slaveNode
|
case _ => rocket.slaveNode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pbus.toTile(tp.name) { implicit p => crossing.slave.adapt(this)( DisableMonitors { implicit p =>
|
DisableMonitors { implicit p =>
|
||||||
tileSlaveBuffering :*= rocket.crossTLIn
|
tileSlaveBuffering :*= pbus.toTile(tp.name) {
|
||||||
})}
|
crossing.slave.blockerCtrlAddr
|
||||||
|
.map { BasicBusBlockerParams(_, pbus.beatBytes, sbus.beatBytes) }
|
||||||
|
.map { bbbp => LazyModule(new BasicBusBlocker(bbbp)) }
|
||||||
|
.map { bbb =>
|
||||||
|
pbus.toVariableWidthSlave(Some("bus_blocker")) { bbb.controlNode }
|
||||||
|
rocket.crossTLIn :*= bbb.node
|
||||||
|
} .getOrElse { rocket.crossTLIn }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Handle all the different types of interrupts crossing to or from the tile:
|
// Handle all the different types of interrupts crossing to or from the tile:
|
||||||
// 1. Debug interrupt is definitely asynchronous in all cases.
|
// 1. Debug interrupt is definitely asynchronous in all cases.
|
||||||
@ -163,13 +145,13 @@ trait HasRocketTilesModuleImp extends HasTilesModuleImp
|
|||||||
val outer: HasRocketTiles
|
val outer: HasRocketTiles
|
||||||
}
|
}
|
||||||
|
|
||||||
class RocketCoreplex(implicit p: Parameters) extends BaseCoreplex
|
class RocketSubsystem(implicit p: Parameters) extends BaseSubsystem
|
||||||
with HasRocketTiles {
|
with HasRocketTiles {
|
||||||
val tiles = rocketTiles
|
val tiles = rocketTiles
|
||||||
override lazy val module = new RocketCoreplexModule(this)
|
override lazy val module = new RocketSubsystemModuleImp(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
class RocketCoreplexModule[+L <: RocketCoreplex](_outer: L) extends BaseCoreplexModule(_outer)
|
class RocketSubsystemModuleImp[+L <: RocketSubsystem](_outer: L) extends BaseSubsystemModuleImp(_outer)
|
||||||
with HasRocketTilesModuleImp {
|
with HasRocketTilesModuleImp {
|
||||||
tile_inputs.zip(outer.hartIdList).foreach { case(wire, i) =>
|
tile_inputs.zip(outer.hartIdList).foreach { case(wire, i) =>
|
||||||
wire.clock := clock
|
wire.clock := clock
|
109
src/main/scala/subsystem/SystemBus.scala
Normal file
109
src/main/scala/subsystem/SystemBus.scala
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
// See LICENSE.SiFive for license details.
|
||||||
|
|
||||||
|
package freechips.rocketchip.subsystem
|
||||||
|
|
||||||
|
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,
|
||||||
|
pbusBuffer: BufferParams = BufferParams.none) extends HasTLBusParams
|
||||||
|
|
||||||
|
case object SystemBusKey extends Field[SystemBusParams]
|
||||||
|
|
||||||
|
class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWrapper(params, "system_bus")
|
||||||
|
with HasTLXbarPhy {
|
||||||
|
|
||||||
|
private val master_splitter = LazyModule(new TLSplitter)
|
||||||
|
inwardNode :=* master_splitter.node
|
||||||
|
|
||||||
|
protected def fixFromThenSplit(policy: TLFIFOFixer.Policy, buffers: Int): TLInwardNode =
|
||||||
|
master_splitter.node :=* TLBuffer.chain(buffers).foldLeft(TLFIFOFixer(policy))(_ :=* _)
|
||||||
|
|
||||||
|
def busView = master_splitter.node.edges.in.head
|
||||||
|
|
||||||
|
def toPeripheryBus(gen: => TLNode): TLOutwardNode = {
|
||||||
|
to("pbus") {
|
||||||
|
(gen
|
||||||
|
:= TLFIFOFixer(TLFIFOFixer.all)
|
||||||
|
:= TLWidthWidget(params.beatBytes)
|
||||||
|
:= bufferTo(params.pbusBuffer))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def toMemoryBus(gen: => TLInwardNode) {
|
||||||
|
to("mbus") { gen := delayNode := outwardNode }
|
||||||
|
}
|
||||||
|
|
||||||
|
def toSlave[D,U,E,B <: Data]
|
||||||
|
(name: Option[String] = None, buffer: BufferParams = BufferParams.default)
|
||||||
|
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] =
|
||||||
|
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
|
||||||
|
to("slave" named name) { gen :*= bufferTo(buffer) }
|
||||||
|
}
|
||||||
|
|
||||||
|
def toSplitSlave[D,U,E,B <: Data]
|
||||||
|
(name: Option[String] = None)
|
||||||
|
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] =
|
||||||
|
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
|
||||||
|
to("slave" named name) { gen :=* master_splitter.node }
|
||||||
|
}
|
||||||
|
|
||||||
|
def toFixedWidthSlave[D,U,E,B <: Data]
|
||||||
|
(name: Option[String] = None, buffer: BufferParams = BufferParams.default)
|
||||||
|
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] =
|
||||||
|
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
|
||||||
|
to("slave" named name) { gen :*= fixedWidthTo(buffer) }
|
||||||
|
}
|
||||||
|
|
||||||
|
def toVariableWidthSlave[D,U,E,B <: Data]
|
||||||
|
(name: Option[String] = None, buffer: BufferParams = BufferParams.default)
|
||||||
|
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] =
|
||||||
|
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
|
||||||
|
to("slave" named name) { gen :*= fragmentTo(buffer) }
|
||||||
|
}
|
||||||
|
|
||||||
|
def fromFrontBus(gen: => TLNode): TLInwardNode = {
|
||||||
|
from("front_bus") { master_splitter.node :=* gen }
|
||||||
|
}
|
||||||
|
|
||||||
|
def fromTile
|
||||||
|
(name: Option[String], buffers: Int = 0, cork: Option[Boolean] = None)
|
||||||
|
(gen: => TLNode): TLInwardNode = {
|
||||||
|
from("tile" named name) {
|
||||||
|
fixFromThenSplit(TLFIFOFixer.allUncacheable, buffers) :=* gen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def toFixedWidthPort[D,U,E,B <: Data]
|
||||||
|
(name: Option[String] = None, buffer: BufferParams = BufferParams.default)
|
||||||
|
(gen: => NodeHandle[TLClientPortParameters,TLManagerPortParameters,TLEdgeIn,TLBundle,D,U,E,B] =
|
||||||
|
TLIdentity.gen): OutwardNodeHandle[D,U,E,B] = {
|
||||||
|
to("port" named name) { gen := fixedWidthTo(buffer) }
|
||||||
|
}
|
||||||
|
|
||||||
|
def fromPort[D,U,E,B <: Data]
|
||||||
|
(name: Option[String] = None, buffers: Int = 0)
|
||||||
|
(gen: => NodeHandle[D,U,E,B,TLClientPortParameters,TLManagerPortParameters,TLEdgeOut,TLBundle] =
|
||||||
|
TLIdentity.gen): InwardNodeHandle[D,U,E,B] = {
|
||||||
|
from("port" named name) { fixFromThenSplit(TLFIFOFixer.all, buffers) :=* gen }
|
||||||
|
}
|
||||||
|
|
||||||
|
def fromCoherentMaster[D,U,E,B <: Data]
|
||||||
|
(name: Option[String] = None, buffers: Int = 0)
|
||||||
|
(gen: => NodeHandle[D,U,E,B,TLClientPortParameters,TLManagerPortParameters,TLEdgeOut,TLBundle] =
|
||||||
|
TLIdentity.gen): InwardNodeHandle[D,U,E,B] = {
|
||||||
|
from("coherent_master" named name) { fixFrom(TLFIFOFixer.all, buffers) :=* gen }
|
||||||
|
}
|
||||||
|
|
||||||
|
def fromMaster[D,U,E,B <: Data]
|
||||||
|
(name: Option[String] = None, buffers: Int = 0)
|
||||||
|
(gen: => NodeHandle[D,U,E,B,TLClientPortParameters,TLManagerPortParameters,TLEdgeOut,TLBundle] =
|
||||||
|
TLIdentity.gen): InwardNodeHandle[D,U,E,B] = {
|
||||||
|
from("master" named name) { fixFromThenSplit(TLFIFOFixer.all, buffers) :=* gen }
|
||||||
|
}
|
||||||
|
}
|
@ -5,13 +5,13 @@ package freechips.rocketchip.system
|
|||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import freechips.rocketchip.config.Config
|
import freechips.rocketchip.config.Config
|
||||||
import freechips.rocketchip.coreplex._
|
import freechips.rocketchip.subsystem._
|
||||||
import freechips.rocketchip.devices.debug.{IncludeJtagDTM, JtagDTMKey}
|
import freechips.rocketchip.devices.debug.{IncludeJtagDTM, JtagDTMKey}
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
|
|
||||||
class WithJtagDTMSystem extends freechips.rocketchip.coreplex.WithJtagDTM
|
class WithJtagDTMSystem extends freechips.rocketchip.subsystem.WithJtagDTM
|
||||||
|
|
||||||
class BaseConfig extends Config(new BaseCoreplexConfig().alter((site,here,up) => {
|
class BaseConfig extends Config(new BaseSubsystemConfig().alter((site,here,up) => {
|
||||||
// DTS descriptive parameters
|
// DTS descriptive parameters
|
||||||
case DTSModel => "freechips,rocketchip-unknown"
|
case DTSModel => "freechips,rocketchip-unknown"
|
||||||
case DTSCompat => Nil
|
case DTSCompat => Nil
|
||||||
|
@ -4,22 +4,22 @@ package freechips.rocketchip.system
|
|||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import freechips.rocketchip.config.Parameters
|
import freechips.rocketchip.config.Parameters
|
||||||
import freechips.rocketchip.coreplex._
|
import freechips.rocketchip.subsystem._
|
||||||
import freechips.rocketchip.devices.tilelink._
|
import freechips.rocketchip.devices.tilelink._
|
||||||
import freechips.rocketchip.util.DontTouch
|
import freechips.rocketchip.util.DontTouch
|
||||||
|
|
||||||
/** Example Top with periphery devices and ports, and a Rocket coreplex */
|
/** Example Top with periphery devices and ports, and a Rocket subsystem */
|
||||||
class ExampleRocketSystem(implicit p: Parameters) extends RocketCoreplex
|
class ExampleRocketSystem(implicit p: Parameters) extends RocketSubsystem
|
||||||
with HasAsyncExtInterrupts
|
with HasAsyncExtInterrupts
|
||||||
with HasMasterAXI4MemPort
|
with HasMasterAXI4MemPort
|
||||||
with HasMasterAXI4MMIOPort
|
with HasMasterAXI4MMIOPort
|
||||||
with HasSlaveAXI4Port
|
with HasSlaveAXI4Port
|
||||||
with HasPeripheryBootROM
|
with HasPeripheryBootROM
|
||||||
with HasSystemErrorSlave {
|
with HasSystemErrorSlave {
|
||||||
override lazy val module = new ExampleRocketSystemModule(this)
|
override lazy val module = new ExampleRocketSystemModuleImp(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExampleRocketSystemModule[+L <: ExampleRocketSystem](_outer: L) extends RocketCoreplexModule(_outer)
|
class ExampleRocketSystemModuleImp[+L <: ExampleRocketSystem](_outer: L) extends RocketSubsystemModuleImp(_outer)
|
||||||
with HasRTCModuleImp
|
with HasRTCModuleImp
|
||||||
with HasExtInterruptsModuleImp
|
with HasExtInterruptsModuleImp
|
||||||
with HasMasterAXI4MemPortModuleImp
|
with HasMasterAXI4MemPortModuleImp
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
package freechips.rocketchip.system
|
package freechips.rocketchip.system
|
||||||
|
|
||||||
import freechips.rocketchip.coreplex.RocketTilesKey
|
import freechips.rocketchip.subsystem.RocketTilesKey
|
||||||
import freechips.rocketchip.tile.XLen
|
import freechips.rocketchip.tile.XLen
|
||||||
import freechips.rocketchip.util.GeneratorApp
|
import freechips.rocketchip.util.GeneratorApp
|
||||||
|
|
||||||
import scala.collection.mutable.LinkedHashSet
|
import scala.collection.mutable.LinkedHashSet
|
||||||
|
|
||||||
/** A Generator for platforms containing Rocket Coreplexes */
|
/** A Generator for platforms containing Rocket Subsystemes */
|
||||||
object Generator extends GeneratorApp {
|
object Generator extends GeneratorApp {
|
||||||
|
|
||||||
val rv64RegrTestNames = LinkedHashSet(
|
val rv64RegrTestNames = LinkedHashSet(
|
||||||
@ -50,7 +50,7 @@ object Generator extends GeneratorApp {
|
|||||||
override def addTestSuites {
|
override def addTestSuites {
|
||||||
import DefaultTestSuites._
|
import DefaultTestSuites._
|
||||||
val xlen = params(XLen)
|
val xlen = params(XLen)
|
||||||
// TODO: for now only generate tests for the first core in the first coreplex
|
// TODO: for now only generate tests for the first core in the first subsystem
|
||||||
val tileParams = params(RocketTilesKey).head
|
val tileParams = params(RocketTilesKey).head
|
||||||
val coreParams = tileParams.core
|
val coreParams = tileParams.core
|
||||||
val vm = coreParams.useVM
|
val vm = coreParams.useVM
|
||||||
|
@ -5,7 +5,7 @@ package freechips.rocketchip.tile
|
|||||||
import Chisel._
|
import Chisel._
|
||||||
|
|
||||||
import freechips.rocketchip.config._
|
import freechips.rocketchip.config._
|
||||||
import freechips.rocketchip.coreplex._
|
import freechips.rocketchip.subsystem._
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.interrupts._
|
import freechips.rocketchip.interrupts._
|
||||||
import freechips.rocketchip.rocket._
|
import freechips.rocketchip.rocket._
|
||||||
@ -122,7 +122,7 @@ trait HasTileParameters {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Base class for all Tiles that use TileLink */
|
/** Base class for all Tiles that use TileLink */
|
||||||
abstract class BaseTile(tileParams: TileParams, val crossing: CoreplexClockCrossing)
|
abstract class BaseTile(tileParams: TileParams, val crossing: SubsystemClockCrossing)
|
||||||
(implicit p: Parameters) extends LazyModule with HasTileParameters with HasCrossing
|
(implicit p: Parameters) extends LazyModule with HasTileParameters with HasCrossing
|
||||||
{
|
{
|
||||||
def module: BaseTileModuleImp[BaseTile]
|
def module: BaseTileModuleImp[BaseTile]
|
||||||
|
@ -18,7 +18,7 @@ class TileInterrupts(implicit p: Parameters) extends CoreBundle()(p) {
|
|||||||
val lip = Vec(coreParams.nLocalInterrupts, Bool())
|
val lip = Vec(coreParams.nLocalInterrupts, Bool())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use diplomatic interrupts to external interrupts from the coreplex into the tile
|
// Use diplomatic interrupts to external interrupts from the subsystem into the tile
|
||||||
trait HasExternalInterrupts { this: BaseTile =>
|
trait HasExternalInterrupts { this: BaseTile =>
|
||||||
|
|
||||||
val intInwardNode = intXbar.intnode
|
val intInwardNode = intXbar.intnode
|
||||||
@ -50,7 +50,7 @@ trait HasExternalInterrupts { this: BaseTile =>
|
|||||||
|
|
||||||
// TODO: the order of the following two functions must match, and
|
// TODO: the order of the following two functions must match, and
|
||||||
// also match the order which things are connected to the
|
// also match the order which things are connected to the
|
||||||
// per-tile crossbar in coreplex.HasRocketTiles
|
// per-tile crossbar in subsystem.HasRocketTiles
|
||||||
|
|
||||||
// debug, msip, mtip, meip, seip, lip offsets in CSRs
|
// debug, msip, mtip, meip, seip, lip offsets in CSRs
|
||||||
def csrIntMap: List[Int] = {
|
def csrIntMap: List[Int] = {
|
||||||
|
@ -5,7 +5,7 @@ package freechips.rocketchip.tile
|
|||||||
import Chisel._
|
import Chisel._
|
||||||
|
|
||||||
import freechips.rocketchip.config.{Parameters, Field}
|
import freechips.rocketchip.config.{Parameters, Field}
|
||||||
import freechips.rocketchip.coreplex.CacheBlockBytes
|
import freechips.rocketchip.subsystem.CacheBlockBytes
|
||||||
import freechips.rocketchip.tilelink.ClientMetadata
|
import freechips.rocketchip.tilelink.ClientMetadata
|
||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ package freechips.rocketchip.tile
|
|||||||
import Chisel._
|
import Chisel._
|
||||||
|
|
||||||
import freechips.rocketchip.config._
|
import freechips.rocketchip.config._
|
||||||
import freechips.rocketchip.coreplex._
|
import freechips.rocketchip.subsystem._
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.rocket._
|
import freechips.rocketchip.rocket._
|
||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
|
@ -5,7 +5,7 @@ package freechips.rocketchip.tile
|
|||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import freechips.rocketchip.config._
|
import freechips.rocketchip.config._
|
||||||
import freechips.rocketchip.coreplex.CoreplexClockCrossing
|
import freechips.rocketchip.subsystem.SubsystemClockCrossing
|
||||||
import freechips.rocketchip.devices.tilelink._
|
import freechips.rocketchip.devices.tilelink._
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.interrupts._
|
import freechips.rocketchip.interrupts._
|
||||||
@ -33,7 +33,7 @@ case class RocketTileParams(
|
|||||||
|
|
||||||
class RocketTile(
|
class RocketTile(
|
||||||
val rocketParams: RocketTileParams,
|
val rocketParams: RocketTileParams,
|
||||||
crossing: CoreplexClockCrossing)
|
crossing: SubsystemClockCrossing)
|
||||||
(implicit p: Parameters) extends BaseTile(rocketParams, crossing)(p)
|
(implicit p: Parameters) extends BaseTile(rocketParams, crossing)(p)
|
||||||
with HasExternalInterrupts
|
with HasExternalInterrupts
|
||||||
with HasLazyRoCC // implies CanHaveSharedFPU with CanHavePTW with HasHellaCache
|
with HasLazyRoCC // implies CanHaveSharedFPU with CanHavePTW with HasHellaCache
|
||||||
|
@ -7,7 +7,7 @@ import freechips.rocketchip.config.Parameters
|
|||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
import freechips.rocketchip.util.property._
|
import freechips.rocketchip.util.property._
|
||||||
import freechips.rocketchip.coreplex.{CrossingWrapper, AsynchronousCrossing}
|
import freechips.rocketchip.subsystem.{CrossingWrapper, AsynchronousCrossing}
|
||||||
|
|
||||||
class TLAsyncCrossingSource(sync: Int = 3)(implicit p: Parameters) extends LazyModule
|
class TLAsyncCrossingSource(sync: Int = 3)(implicit p: Parameters) extends LazyModule
|
||||||
{
|
{
|
||||||
|
@ -1,85 +0,0 @@
|
|||||||
// See LICENSE.SiFive for license details.
|
|
||||||
|
|
||||||
package freechips.rocketchip.tilelink
|
|
||||||
|
|
||||||
import Chisel._
|
|
||||||
import freechips.rocketchip.config.{Field, Parameters}
|
|
||||||
import freechips.rocketchip.diplomacy._
|
|
||||||
|
|
||||||
case object TLBusDelayProbability extends Field[Double](0.0)
|
|
||||||
|
|
||||||
/** 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, val busName: String)(implicit p: Parameters)
|
|
||||||
extends SimpleLazyModule with LazyScope with TLBusParams {
|
|
||||||
|
|
||||||
val beatBytes = params.beatBytes
|
|
||||||
val blockBytes = params.blockBytes
|
|
||||||
val masterBuffering = params.masterBuffering
|
|
||||||
val slaveBuffering = params.slaveBuffering
|
|
||||||
require(blockBytes % beatBytes == 0)
|
|
||||||
private val delayProb = p(TLBusDelayProbability)
|
|
||||||
|
|
||||||
protected val xbar = LazyModule(new TLXbar)
|
|
||||||
xbar.suggestName(busName)
|
|
||||||
|
|
||||||
private val master_buffer = LazyModule(new TLBuffer(masterBuffering))
|
|
||||||
master_buffer.suggestName(s"${busName}_master_TLBuffer")
|
|
||||||
private val slave_buffer = LazyModule(new TLBuffer(slaveBuffering))
|
|
||||||
slave_buffer.suggestName(s"${busName}_slave_TLBuffer")
|
|
||||||
private val slave_frag = LazyModule(new TLFragmenter(beatBytes, blockBytes))
|
|
||||||
slave_frag.suggestName(s"${busName}_slave_TLFragmenter")
|
|
||||||
|
|
||||||
private val slave_ww = LazyModule(new TLWidthWidget(beatBytes))
|
|
||||||
slave_ww.suggestName(s"${busName}_slave_TLWidthWidget")
|
|
||||||
|
|
||||||
private val delayedNode = if (delayProb > 0.0) {
|
|
||||||
val firstDelay = LazyModule(new TLDelayer(delayProb))
|
|
||||||
val flowDelay = LazyModule(new TLBuffer(BufferParams.flow))
|
|
||||||
val secondDelay = LazyModule(new TLDelayer(delayProb))
|
|
||||||
firstDelay.node :*= xbar.node
|
|
||||||
flowDelay.node :*= firstDelay.node
|
|
||||||
secondDelay.node :*= flowDelay.node
|
|
||||||
secondDelay.node
|
|
||||||
} else {
|
|
||||||
xbar.node
|
|
||||||
}
|
|
||||||
|
|
||||||
xbar.node :=* master_buffer.node
|
|
||||||
slave_buffer.node :*= delayedNode
|
|
||||||
slave_frag.node :*= slave_buffer.node
|
|
||||||
slave_ww.node :*= slave_buffer.node
|
|
||||||
|
|
||||||
protected def outwardNode: TLOutwardNode = delayedNode
|
|
||||||
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 bufferFromMasters: TLInwardNode = inwardBufNode
|
|
||||||
|
|
||||||
def bufferToSlaves: TLOutwardNode = outwardBufNode
|
|
||||||
|
|
||||||
def toSyncSlaves(name: Option[String] = None, addBuffers: Int = 0): TLOutwardNode = {
|
|
||||||
TLBuffer.chain(addBuffers).foldRight(outwardBufNode)(_ :*= _)
|
|
||||||
}
|
|
||||||
|
|
||||||
def toVariableWidthSlaves: TLOutwardNode = outwardFragNode
|
|
||||||
|
|
||||||
def toFixedWidthSlaves: TLOutwardNode = outwardWWNode
|
|
||||||
|
|
||||||
def toFixedWidthPorts: TLOutwardNode = outwardWWNode // TODO, do/don't buffer here; knowing we will after the necessary port conversions
|
|
||||||
|
|
||||||
}
|
|
87
src/main/scala/tilelink/BusWrapper.scala
Normal file
87
src/main/scala/tilelink/BusWrapper.scala
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
// See LICENSE.SiFive for license details.
|
||||||
|
|
||||||
|
package freechips.rocketchip.tilelink
|
||||||
|
|
||||||
|
import Chisel._
|
||||||
|
import freechips.rocketchip.config.{Field, Parameters}
|
||||||
|
import freechips.rocketchip.diplomacy._
|
||||||
|
|
||||||
|
case object TLBusDelayProbability extends Field[Double](0.0)
|
||||||
|
|
||||||
|
/** Specifies widths of various attachement points in the SoC */
|
||||||
|
trait HasTLBusParams {
|
||||||
|
val beatBytes: Int
|
||||||
|
val blockBytes: Int
|
||||||
|
|
||||||
|
def beatBits: Int = beatBytes * 8
|
||||||
|
def blockBits: Int = blockBytes * 8
|
||||||
|
def blockBeats: Int = blockBytes / beatBytes
|
||||||
|
def blockOffset: Int = log2Up(blockBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class TLBusWrapper(params: HasTLBusParams, val busName: String)(implicit p: Parameters)
|
||||||
|
extends SimpleLazyModule with LazyScope with HasTLBusParams {
|
||||||
|
|
||||||
|
val beatBytes = params.beatBytes
|
||||||
|
val blockBytes = params.blockBytes
|
||||||
|
require(blockBytes % beatBytes == 0)
|
||||||
|
|
||||||
|
protected def inwardNode: TLInwardNode
|
||||||
|
protected def outwardNode: TLOutwardNode
|
||||||
|
|
||||||
|
protected def bufferFrom(buffer: BufferParams): TLInwardNode =
|
||||||
|
inwardNode :=* TLBuffer(buffer)
|
||||||
|
|
||||||
|
protected def bufferFrom(buffers: Int): TLInwardNode =
|
||||||
|
TLBuffer.chain(buffers).foldLeft(inwardNode)(_ :=* _)
|
||||||
|
|
||||||
|
protected def fixFrom(policy: TLFIFOFixer.Policy, buffers: Int): TLInwardNode =
|
||||||
|
inwardNode :=* TLBuffer.chain(buffers).foldLeft(TLFIFOFixer(policy))(_ :=* _)
|
||||||
|
|
||||||
|
protected def bufferTo(buffer: BufferParams): TLOutwardNode =
|
||||||
|
TLBuffer(buffer) :*= delayNode :*= outwardNode
|
||||||
|
|
||||||
|
protected def bufferTo(buffers: Int): TLOutwardNode =
|
||||||
|
TLBuffer.chain(buffers).foldRight(delayNode)(_ :*= _) :*= outwardNode
|
||||||
|
|
||||||
|
protected def fixedWidthTo(buffer: BufferParams): TLOutwardNode =
|
||||||
|
TLWidthWidget(beatBytes) :*= bufferTo(buffer)
|
||||||
|
|
||||||
|
protected def fragmentTo(buffer: BufferParams): TLOutwardNode =
|
||||||
|
TLFragmenter(beatBytes, blockBytes) :*= bufferTo(buffer)
|
||||||
|
|
||||||
|
protected def fragmentTo(minSize: Int, maxSize: Int, buffer: BufferParams): TLOutwardNode =
|
||||||
|
TLFragmenter(minSize, maxSize) :*= bufferTo(buffer)
|
||||||
|
|
||||||
|
protected def delayNode(implicit p: Parameters): TLNode = {
|
||||||
|
val delayProb = p(TLBusDelayProbability)
|
||||||
|
if (delayProb > 0.0) {
|
||||||
|
TLDelayer(delayProb) :*=* TLBuffer(BufferParams.flow) :*=* TLDelayer(delayProb)
|
||||||
|
} else {
|
||||||
|
val nodelay = TLIdentityNode()
|
||||||
|
nodelay
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected def to[T](name: String)(body: => T): T = {
|
||||||
|
this { LazyScope(s"coupler_to_${name}") { body } }
|
||||||
|
}
|
||||||
|
|
||||||
|
protected def from[T](name: String)(body: => T): T = {
|
||||||
|
this { LazyScope(s"coupler_from_${name}") { body } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait HasTLXbarPhy { this: TLBusWrapper =>
|
||||||
|
private val xbar = LazyModule(new TLXbar).suggestName(busName + "_xbar")
|
||||||
|
|
||||||
|
protected def inwardNode: TLInwardNode = xbar.node
|
||||||
|
protected def outwardNode: TLOutwardNode = xbar.node
|
||||||
|
}
|
||||||
|
|
||||||
|
object TLIdentity {
|
||||||
|
def gen: TLNode = {
|
||||||
|
val passthru = TLIdentityNode()
|
||||||
|
passthru
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,8 @@ package freechips.rocketchip.tilelink
|
|||||||
import Chisel._
|
import Chisel._
|
||||||
import freechips.rocketchip.config.Parameters
|
import freechips.rocketchip.config.Parameters
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
|
import freechips.rocketchip.util._
|
||||||
|
import freechips.rocketchip.util.property._
|
||||||
import scala.math.max
|
import scala.math.max
|
||||||
|
|
||||||
class TLFIFOFixer(policy: TLFIFOFixer.Policy = TLFIFOFixer.all)(implicit p: Parameters) extends LazyModule
|
class TLFIFOFixer(policy: TLFIFOFixer.Policy = TLFIFOFixer.all)(implicit p: Parameters) extends LazyModule
|
||||||
@ -98,6 +100,31 @@ class TLFIFOFixer(policy: TLFIFOFixer.Policy = TLFIFOFixer.all)(implicit p: Para
|
|||||||
out.c.valid := Bool(false)
|
out.c.valid := Bool(false)
|
||||||
out.e.valid := Bool(false)
|
out.e.valid := Bool(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Functional cover properties
|
||||||
|
|
||||||
|
cover(in.a.valid && stall, "COVER FIFOFIXER STALL", "Cover: Stall occured for a valid transaction")
|
||||||
|
|
||||||
|
val SourceIdFIFOed = RegInit(UInt(0, width = edgeIn.client.endSourceId))
|
||||||
|
val SourceIdSet = Wire(init = UInt(0, width = edgeIn.client.endSourceId))
|
||||||
|
val SourceIdClear = Wire(init = UInt(0, width = edgeIn.client.endSourceId))
|
||||||
|
|
||||||
|
when (a_first && in.a.fire() && !a_notFIFO) {
|
||||||
|
SourceIdSet := UIntToOH(in.a.bits.source)
|
||||||
|
}
|
||||||
|
when (d_first && in.d.fire()) {
|
||||||
|
SourceIdClear := UIntToOH(in.d.bits.source)
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceIdFIFOed := SourceIdFIFOed | SourceIdSet
|
||||||
|
val allIDs_FIFOed = SourceIdFIFOed===Fill(SourceIdFIFOed.getWidth, 1.U)
|
||||||
|
|
||||||
|
cover(allIDs_FIFOed, "COVER all sources", "Cover: FIFOFIXER covers all Source IDs")
|
||||||
|
//cover(flight.reduce(_ && _), "COVER full", "Cover: FIFO is full with all Source IDs")
|
||||||
|
cover(!(flight.reduce(_ || _)), "COVER empty", "Cover: FIFO is empty")
|
||||||
|
cover(SourceIdSet > 0.U, "COVER at least one push", "Cover: At least one Source ID is pushed")
|
||||||
|
cover(SourceIdClear > 0.U, "COVER at least one pop", "Cover: At least one Source ID is popped")
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,18 +30,6 @@ object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TL
|
|||||||
pd.copy(clients = pd.clients.map { c => c.copy (nodePath = node +: c.nodePath) })
|
pd.copy(clients = pd.clients.map { c => c.copy (nodePath = node +: c.nodePath) })
|
||||||
override def mixI(pu: TLManagerPortParameters, node: InwardNode[TLClientPortParameters, TLManagerPortParameters, TLBundle]): TLManagerPortParameters =
|
override def mixI(pu: TLManagerPortParameters, node: InwardNode[TLClientPortParameters, TLManagerPortParameters, TLBundle]): TLManagerPortParameters =
|
||||||
pu.copy(managers = pu.managers.map { m => m.copy (nodePath = node +: m.nodePath) })
|
pu.copy(managers = pu.managers.map { m => m.copy (nodePath = node +: m.nodePath) })
|
||||||
override def getO(pu: TLManagerPortParameters): Option[BaseNode] = {
|
|
||||||
val head = pu.managers.map(_.nodePath.headOption)
|
|
||||||
if (head.exists(!_.isDefined) || head.map(_.get).distinct.size != 1) {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
val subproblem = pu.copy(managers = pu.managers.map(m => m.copy(nodePath = m.nodePath.tail)))
|
|
||||||
getO(subproblem) match {
|
|
||||||
case Some(x) => Some(x)
|
|
||||||
case None => Some(head(0).get)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case class TLClientNode(portParams: Seq[TLClientPortParameters])(implicit valName: ValName) extends SourceNode(TLImp)(portParams)
|
case class TLClientNode(portParams: Seq[TLClientPortParameters])(implicit valName: ValName) extends SourceNode(TLImp)(portParams)
|
||||||
|
@ -97,7 +97,13 @@ case class TLRegisterNode(
|
|||||||
("resetValue" -> f.desc.map{_.reset}) ~
|
("resetValue" -> f.desc.map{_.reset}) ~
|
||||||
("group" -> f.desc.map{_.group}) ~
|
("group" -> f.desc.map{_.group}) ~
|
||||||
("groupDesc" -> f.desc.map{_.groupDesc}) ~
|
("groupDesc" -> f.desc.map{_.groupDesc}) ~
|
||||||
("accessType" -> f.desc.map {d => d.access.toString})
|
("accessType" -> f.desc.map {d => d.access.toString}) ~
|
||||||
|
("enumerations" -> f.desc.map {d =>
|
||||||
|
Option(d.enumerations.map { case (key, (name, desc)) =>
|
||||||
|
(("value" -> key) ~
|
||||||
|
("name" -> name) ~
|
||||||
|
("description" -> desc))
|
||||||
|
}).filter(_.nonEmpty)})
|
||||||
))
|
))
|
||||||
currentBitOffset = currentBitOffset + f.width
|
currentBitOffset = currentBitOffset + f.width
|
||||||
tmp
|
tmp
|
||||||
@ -137,7 +143,7 @@ class TLRegBundleBase(arg: TLRegBundleArg) extends Bundle
|
|||||||
implicit val p = arg.p
|
implicit val p = arg.p
|
||||||
}
|
}
|
||||||
|
|
||||||
class TLRegBundle[P](val params: P, arg: TLRegBundleArg)(implicit p: Parameters) extends TLRegBundleBase(arg)
|
class TLRegBundle[P](val params: P, val arg: TLRegBundleArg) extends TLRegBundleBase(arg)
|
||||||
|
|
||||||
class TLRegModule[P, B <: TLRegBundleBase](val params: P, bundleBuilder: => B, router: TLRegisterRouterBase)
|
class TLRegModule[P, B <: TLRegBundleBase](val params: P, bundleBuilder: => B, router: TLRegisterRouterBase)
|
||||||
extends LazyModuleImp(router) with HasRegMap
|
extends LazyModuleImp(router) with HasRegMap
|
||||||
|
@ -7,7 +7,7 @@ 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.config._
|
import freechips.rocketchip.config._
|
||||||
import freechips.rocketchip.coreplex.{BaseCoreplexConfig}
|
import freechips.rocketchip.subsystem.{BaseSubsystemConfig}
|
||||||
import freechips.rocketchip.devices.tilelink._
|
import freechips.rocketchip.devices.tilelink._
|
||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
|
|
||||||
@ -79,7 +79,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 BaseCoreplexConfig)
|
class AMBAUnitTestConfig extends Config(new WithAMBAUnitTests ++ new WithTestDuration(10) ++ new BaseSubsystemConfig)
|
||||||
class TLSimpleUnitTestConfig extends Config(new WithTLSimpleUnitTests ++ new WithTestDuration(10) ++ new BaseCoreplexConfig)
|
class TLSimpleUnitTestConfig extends Config(new WithTLSimpleUnitTests ++ new WithTestDuration(10) ++ new BaseSubsystemConfig)
|
||||||
class TLWidthUnitTestConfig extends Config(new WithTLWidthUnitTests ++ new WithTestDuration(10) ++ new BaseCoreplexConfig)
|
class TLWidthUnitTestConfig extends Config(new WithTLWidthUnitTests ++ new WithTestDuration(10) ++ new BaseSubsystemConfig)
|
||||||
class TLXbarUnitTestConfig extends Config(new WithTLXbarUnitTests ++ new WithTestDuration(10) ++ new BaseCoreplexConfig)
|
class TLXbarUnitTestConfig extends Config(new WithTLXbarUnitTests ++ new WithTestDuration(10) ++ new BaseSubsystemConfig)
|
||||||
|
@ -108,7 +108,7 @@ trait GeneratorApp extends App with HasGeneratorUtilities {
|
|||||||
/** Output software test Makefrags, which provide targets for integration testing. */
|
/** Output software test Makefrags, which provide targets for integration testing. */
|
||||||
def generateTestSuiteMakefrags {
|
def generateTestSuiteMakefrags {
|
||||||
addTestSuites
|
addTestSuites
|
||||||
writeOutputFile(td, s"$longName.d", TestGeneration.generateMakefrag) // Coreplex-specific test suites
|
writeOutputFile(td, s"$longName.d", TestGeneration.generateMakefrag) // Subsystem-specific test suites
|
||||||
}
|
}
|
||||||
|
|
||||||
def addTestSuites {
|
def addTestSuites {
|
||||||
|
@ -11,7 +11,7 @@ final case class HeterogeneousBag[T <: Data](elts: Seq[T]) extends Record with c
|
|||||||
def length = elts.length
|
def length = elts.length
|
||||||
|
|
||||||
val elements = ListMap(elts.zipWithIndex.map { case (n,i) => (i.toString, n) }:_*)
|
val elements = ListMap(elts.zipWithIndex.map { case (n,i) => (i.toString, n) }:_*)
|
||||||
override def cloneType: this.type = (new HeterogeneousBag(elts.map(_.cloneType))).asInstanceOf[this.type]
|
override def cloneType: this.type = (new HeterogeneousBag(elts.map(_.chiselCloneType))).asInstanceOf[this.type]
|
||||||
|
|
||||||
// IndexedSeq has its own hashCode/equals that we must not use
|
// IndexedSeq has its own hashCode/equals that we must not use
|
||||||
override def hashCode: Int = super[Record].hashCode
|
override def hashCode: Int = super[Record].hashCode
|
||||||
|
@ -8,19 +8,7 @@ import chisel3.experimental.{ChiselAnnotation, RawModule}
|
|||||||
import freechips.rocketchip.config.Parameters
|
import freechips.rocketchip.config.Parameters
|
||||||
import scala.math._
|
import scala.math._
|
||||||
|
|
||||||
class ParameterizedBundle(implicit p: Parameters) extends Bundle {
|
class ParameterizedBundle(implicit p: Parameters) extends Bundle
|
||||||
override def cloneType = {
|
|
||||||
try {
|
|
||||||
this.getClass.getConstructors.head.newInstance(p).asInstanceOf[this.type]
|
|
||||||
} catch {
|
|
||||||
case e: java.lang.IllegalArgumentException =>
|
|
||||||
throwException("Unable to use ParamaterizedBundle.cloneType on " +
|
|
||||||
this.getClass + ", probably because " + this.getClass +
|
|
||||||
"() takes more than one argument. Consider overriding " +
|
|
||||||
"cloneType() on " + this.getClass, e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: replace this with an implicit class when @chisel unprotects dontTouchPorts
|
// TODO: replace this with an implicit class when @chisel unprotects dontTouchPorts
|
||||||
trait DontTouch {
|
trait DontTouch {
|
||||||
@ -101,7 +89,7 @@ object ValidMux {
|
|||||||
apply(v1 +: v2.toSeq)
|
apply(v1 +: v2.toSeq)
|
||||||
}
|
}
|
||||||
def apply[T <: Data](valids: Seq[ValidIO[T]]): ValidIO[T] = {
|
def apply[T <: Data](valids: Seq[ValidIO[T]]): ValidIO[T] = {
|
||||||
val out = Wire(Valid(valids.head.bits))
|
val out = Wire(Valid(valids.head.bits.cloneType))
|
||||||
out.valid := valids.map(_.valid).reduce(_ || _)
|
out.valid := valids.map(_.valid).reduce(_ || _)
|
||||||
out.bits := MuxCase(valids.head.bits,
|
out.bits := MuxCase(valids.head.bits,
|
||||||
valids.map(v => (v.valid -> v.bits)))
|
valids.map(v => (v.valid -> v.bits)))
|
||||||
|
@ -43,6 +43,28 @@ package object util {
|
|||||||
def readAndHold(addr: UInt, enable: Bool): T = x.read(addr, enable) holdUnless RegNext(enable)
|
def readAndHold(addr: UInt, enable: Bool): T = x.read(addr, enable) holdUnless RegNext(enable)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
implicit class StringToAugmentedString(val x: String) extends AnyVal {
|
||||||
|
/** converts from camel case to to underscores, also removing all spaces */
|
||||||
|
def underscore: String = x.tail.foldLeft(x.headOption.map(_.toLower + "") getOrElse "") {
|
||||||
|
case (acc, c) if c.isUpper => acc + "_" + c.toLower
|
||||||
|
case (acc, c) if c == ' ' => acc
|
||||||
|
case (acc, c) => acc + c
|
||||||
|
}
|
||||||
|
|
||||||
|
/** converts spaces or underscores to hyphens, also lowering case */
|
||||||
|
def kebab: String = x.toLowerCase map {
|
||||||
|
case ' ' => '-'
|
||||||
|
case '_' => '-'
|
||||||
|
case c => c
|
||||||
|
}
|
||||||
|
|
||||||
|
def named(name: Option[String]): String = {
|
||||||
|
x + name.map("_named_" + _ ).getOrElse("_with_no_name")
|
||||||
|
}
|
||||||
|
|
||||||
|
def named(name: String): String = named(Some(name))
|
||||||
|
}
|
||||||
|
|
||||||
implicit def uintToBitPat(x: UInt): BitPat = BitPat(x)
|
implicit def uintToBitPat(x: UInt): BitPat = BitPat(x)
|
||||||
implicit def wcToUInt(c: WideCounter): UInt = c.value
|
implicit def wcToUInt(c: WideCounter): UInt = c.value
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
# Verilog sources
|
# Verilog sources
|
||||||
|
|
||||||
bb_vsrcs = \
|
bb_vsrcs = \
|
||||||
$(base_dir)/vsrc/jtag_vpi.v \
|
|
||||||
$(base_dir)/vsrc/plusarg_reader.v \
|
$(base_dir)/vsrc/plusarg_reader.v \
|
||||||
$(base_dir)/vsrc/ClockDivider2.v \
|
$(base_dir)/vsrc/ClockDivider2.v \
|
||||||
$(base_dir)/vsrc/ClockDivider3.v \
|
$(base_dir)/vsrc/ClockDivider3.v \
|
||||||
@ -24,7 +23,7 @@ sim_vsrcs = \
|
|||||||
sim_csrcs = \
|
sim_csrcs = \
|
||||||
$(base_dir)/csrc/SimDTM.cc \
|
$(base_dir)/csrc/SimDTM.cc \
|
||||||
$(base_dir)/csrc/SimJTAG.cc \
|
$(base_dir)/csrc/SimJTAG.cc \
|
||||||
$(base_dir)/csrc/remote_bitbang.cc \
|
$(base_dir)/csrc/remote_bitbang.cc
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
# Build Verilog
|
# Build Verilog
|
||||||
@ -59,7 +58,6 @@ VCS_OPTS = -notice -line +lint=all,noVCDE,noONGS,noUI -error=PCWM-L -timescale=1
|
|||||||
+libext+.v \
|
+libext+.v \
|
||||||
|
|
||||||
VCS_OPTS += +vpi
|
VCS_OPTS += +vpi
|
||||||
VCS_OPTS += -P $(base_dir)/vsrc/jtag_vpi.tab
|
|
||||||
VCS_OPTS += -CC "-DVCS_VPI"
|
VCS_OPTS += -CC "-DVCS_VPI"
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user