Merge pull request #985 from freechipsproject/flop-interrupts
Add Parameters to diplomatic edges
This commit is contained in:
commit
e7de7f3e82
@ -139,7 +139,7 @@ object AHBToTL
|
|||||||
{
|
{
|
||||||
def apply()(x: AHBOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
def apply()(x: AHBOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
||||||
val tl = LazyModule(new AHBToTL)
|
val tl = LazyModule(new AHBToTL)
|
||||||
tl.node := x
|
tl.node :=? x
|
||||||
tl.node
|
tl.node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ object AXI4Buffer
|
|||||||
ar: BufferParams,
|
ar: BufferParams,
|
||||||
r: BufferParams)(x: AXI4OutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): AXI4OutwardNode = {
|
r: BufferParams)(x: AXI4OutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): AXI4OutwardNode = {
|
||||||
val buffer = LazyModule(new AXI4Buffer(aw, w, b, ar, r))
|
val buffer = LazyModule(new AXI4Buffer(aw, w, b, ar, r))
|
||||||
buffer.node := x
|
buffer.node :=? x
|
||||||
buffer.node
|
buffer.node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,7 +108,7 @@ object AXI4Deinterleaver
|
|||||||
// applied to the AXI4 source node; y.node := AXI4Deinterleaver()(x.node)
|
// applied to the AXI4 source node; y.node := AXI4Deinterleaver()(x.node)
|
||||||
def apply(maxReadBytes: Int)(x: AXI4OutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): AXI4OutwardNode = {
|
def apply(maxReadBytes: Int)(x: AXI4OutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): AXI4OutwardNode = {
|
||||||
val deinterleaver = LazyModule(new AXI4Deinterleaver(maxReadBytes))
|
val deinterleaver = LazyModule(new AXI4Deinterleaver(maxReadBytes))
|
||||||
deinterleaver.node := x
|
deinterleaver.node :=? x
|
||||||
deinterleaver.node
|
deinterleaver.node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,7 +208,7 @@ object AXI4Fragmenter
|
|||||||
// applied to the AXI4 source node; y.node := AXI4Fragmenter()(x.node)
|
// applied to the AXI4 source node; y.node := AXI4Fragmenter()(x.node)
|
||||||
def apply()(x: AXI4OutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): AXI4OutwardNode = {
|
def apply()(x: AXI4OutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): AXI4OutwardNode = {
|
||||||
val fragmenter = LazyModule(new AXI4Fragmenter)
|
val fragmenter = LazyModule(new AXI4Fragmenter)
|
||||||
fragmenter.node := x
|
fragmenter.node :=? x
|
||||||
fragmenter.node
|
fragmenter.node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ object AXI4IdIndexer
|
|||||||
// applied to the AXI4 source node; y.node := AXI4IdIndexer(idBits)(x.node)
|
// applied to the AXI4 source node; y.node := AXI4IdIndexer(idBits)(x.node)
|
||||||
def apply(idBits: Int)(x: AXI4OutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): AXI4OutwardNode = {
|
def apply(idBits: Int)(x: AXI4OutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): AXI4OutwardNode = {
|
||||||
val indexer = LazyModule(new AXI4IdIndexer(idBits))
|
val indexer = LazyModule(new AXI4IdIndexer(idBits))
|
||||||
indexer.node := x
|
indexer.node :=? x
|
||||||
indexer.node
|
indexer.node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,7 +168,7 @@ object AXI4ToTL
|
|||||||
{
|
{
|
||||||
def apply()(x: AXI4OutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
def apply()(x: AXI4OutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
||||||
val tl = LazyModule(new AXI4ToTL)
|
val tl = LazyModule(new AXI4ToTL)
|
||||||
tl.node := x
|
tl.node :=? x
|
||||||
tl.node
|
tl.node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ object AXI4UserYanker
|
|||||||
// applied to the AXI4 source node; y.node := AXI4UserYanker(idBits, maxFlight)(x.node)
|
// applied to the AXI4 source node; y.node := AXI4UserYanker(idBits, maxFlight)(x.node)
|
||||||
def apply(capMaxFlight: Option[Int] = None)(x: AXI4OutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): AXI4OutwardNode = {
|
def apply(capMaxFlight: Option[Int] = None)(x: AXI4OutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): AXI4OutwardNode = {
|
||||||
val yanker = LazyModule(new AXI4UserYanker(capMaxFlight))
|
val yanker = LazyModule(new AXI4UserYanker(capMaxFlight))
|
||||||
yanker.node := x
|
yanker.node :=? x
|
||||||
yanker.node
|
yanker.node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,22 @@
|
|||||||
|
|
||||||
package freechips.rocketchip.config
|
package freechips.rocketchip.config
|
||||||
|
|
||||||
class Field[T]
|
abstract class Field[T] private (val default: Option[T])
|
||||||
|
{
|
||||||
|
def this() = this(None)
|
||||||
|
def this(x: T) = this(Some(x))
|
||||||
|
}
|
||||||
|
|
||||||
abstract class View {
|
abstract class View {
|
||||||
final def apply[T](pname: Field[T]): T = apply(pname, this)
|
final def apply[T](pname: Field[T]): T = apply(pname, this)
|
||||||
final def apply[T](pname: Field[T], site: View): T = find(pname, site).asInstanceOf[T]
|
final def apply[T](pname: Field[T], site: View): T = find(pname, site) match {
|
||||||
|
case Some(x) => x.asInstanceOf[T]
|
||||||
|
}
|
||||||
|
|
||||||
protected[config] def find(pname: Any, site: View): Any
|
final def lift[T](pname: Field[T]): Option[T] = lift(pname, this)
|
||||||
|
final def lift[T](pname: Field[T], site: View): Option[T] = find(pname, site).map(_.asInstanceOf[T])
|
||||||
|
|
||||||
|
protected[config] def find[T](pname: Field[T], site: View): Option[T]
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class Parameters extends View {
|
abstract class Parameters extends View {
|
||||||
@ -16,8 +25,8 @@ abstract class Parameters extends View {
|
|||||||
final def alter(f: (View, View, View) => PartialFunction[Any,Any]): Parameters = Parameters(f) ++ this
|
final def alter(f: (View, View, View) => PartialFunction[Any,Any]): Parameters = Parameters(f) ++ this
|
||||||
final def alterPartial(f: PartialFunction[Any,Any]): Parameters = Parameters((_,_,_) => f) ++ this
|
final def alterPartial(f: PartialFunction[Any,Any]): Parameters = Parameters((_,_,_) => f) ++ this
|
||||||
|
|
||||||
protected[config] def chain(site: View, tail: View, pname: Any): Any
|
protected[config] def chain[T](site: View, tail: View, pname: Field[T]): Option[T]
|
||||||
protected[config] def find(pname: Any, site: View) = chain(site, new TerminalView, pname)
|
protected[config] def find[T](pname: Field[T], site: View) = chain(site, new TerminalView, pname)
|
||||||
}
|
}
|
||||||
|
|
||||||
object Parameters {
|
object Parameters {
|
||||||
@ -29,7 +38,7 @@ object Parameters {
|
|||||||
class Config(p: Parameters) extends Parameters {
|
class Config(p: Parameters) extends Parameters {
|
||||||
def this(f: (View, View, View) => PartialFunction[Any,Any]) = this(Parameters(f))
|
def this(f: (View, View, View) => PartialFunction[Any,Any]) = this(Parameters(f))
|
||||||
|
|
||||||
protected[config] def chain(site: View, tail: View, pname: Any) = p.chain(site, tail, pname)
|
protected[config] def chain[T](site: View, tail: View, pname: Field[T]) = p.chain(site, tail, pname)
|
||||||
override def toString = this.getClass.getSimpleName
|
override def toString = this.getClass.getSimpleName
|
||||||
def toInstance = this
|
def toInstance = this
|
||||||
}
|
}
|
||||||
@ -37,25 +46,24 @@ class Config(p: Parameters) extends Parameters {
|
|||||||
// Internal implementation:
|
// Internal implementation:
|
||||||
|
|
||||||
private class TerminalView extends View {
|
private class TerminalView extends View {
|
||||||
private class Unusable
|
def find[T](pname: Field[T], site: View): Option[T] = pname.default
|
||||||
def find(pname: Any, site: View): Any = pname match { case x: Unusable => () }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ChainView(head: Parameters, tail: View) extends View {
|
private class ChainView(head: Parameters, tail: View) extends View {
|
||||||
def find(pname: Any, site: View) = head.chain(site, tail, pname)
|
def find[T](pname: Field[T], site: View) = head.chain(site, tail, pname)
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ChainParameters(x: Parameters, y: Parameters) extends Parameters {
|
private class ChainParameters(x: Parameters, y: Parameters) extends Parameters {
|
||||||
def chain(site: View, tail: View, pname: Any) = x.chain(site, new ChainView(y, tail), pname)
|
def chain[T](site: View, tail: View, pname: Field[T]) = x.chain(site, new ChainView(y, tail), pname)
|
||||||
}
|
}
|
||||||
|
|
||||||
private class EmptyParameters extends Parameters {
|
private class EmptyParameters extends Parameters {
|
||||||
def chain(site: View, tail: View, pname: Any) = tail.find(pname, site)
|
def chain[T](site: View, tail: View, pname: Field[T]) = tail.find(pname, site)
|
||||||
}
|
}
|
||||||
|
|
||||||
private class PartialParameters(f: (View, View, View) => PartialFunction[Any,Any]) extends Parameters {
|
private class PartialParameters(f: (View, View, View) => PartialFunction[Any,Any]) extends Parameters {
|
||||||
protected[config] def chain(site: View, tail: View, pname: Any) = {
|
protected[config] def chain[T](site: View, tail: View, pname: Field[T]) = {
|
||||||
val g = f(site, this, tail)
|
val g = f(site, this, tail)
|
||||||
if (g.isDefinedAt(pname)) g.apply(pname) else tail.find(pname, site)
|
if (g.isDefinedAt(pname)) Some(g.apply(pname).asInstanceOf[T]) else tail.find(pname, site)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,9 +36,6 @@ class BaseCoreplexConfig extends Config ((site, here, up) => {
|
|||||||
case PLICParams => PLICParams()
|
case PLICParams => PLICParams()
|
||||||
case ClintParams => ClintParams()
|
case ClintParams => ClintParams()
|
||||||
case DTSTimebase => BigInt(1000000) // 1 MHz
|
case DTSTimebase => BigInt(1000000) // 1 MHz
|
||||||
// TileLink connection global parameters
|
|
||||||
case TLMonitorBuilder => (args: TLMonitorArgs) => Some(LazyModule(new TLMonitor(args)))
|
|
||||||
case TLCombinationalCheck => false
|
|
||||||
case TLBusDelayProbability => 0.0
|
case TLBusDelayProbability => 0.0
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ trait HasMemoryBus extends HasSystemBus with HasPeripheryBus with HasInterruptBu
|
|||||||
val mbus = new MemoryBus(mbusParams)
|
val mbus = new MemoryBus(mbusParams)
|
||||||
for (bank <- 0 until nBanksPerChannel) {
|
for (bank <- 0 until nBanksPerChannel) {
|
||||||
val offset = (bank * nMemoryChannels) + channel
|
val offset = (bank * nMemoryChannels) + channel
|
||||||
in := sbus.toMemoryBus
|
ForceFanout(a = true) { implicit p => in := sbus.toMemoryBus }
|
||||||
mbus.fromCoherenceManager := TLFilter(TLFilter.Mmask(AddressSet(offset * blockBytes, mask)))(out)
|
mbus.fromCoherenceManager := TLFilter(TLFilter.Mmask(AddressSet(offset * blockBytes, mask)))(out)
|
||||||
}
|
}
|
||||||
mbus
|
mbus
|
||||||
|
@ -45,20 +45,20 @@ trait HasRocketTiles extends HasSystemBus
|
|||||||
val wrapper = crossing match {
|
val wrapper = crossing match {
|
||||||
case SynchronousCrossing(params) => {
|
case SynchronousCrossing(params) => {
|
||||||
val wrapper = LazyModule(new SyncRocketTile(tp, i)(pWithExtra))
|
val wrapper = LazyModule(new SyncRocketTile(tp, i)(pWithExtra))
|
||||||
sbus.fromSyncTiles(params, tp.externalBuffers, tp.name) :=* wrapper.masterNode
|
sbus.fromSyncTiles(params, tp.externalMasterBuffers, tp.name) :=* wrapper.masterNode
|
||||||
wrapper.slaveNode :*= pbus.bufferToSlaves
|
wrapper.slaveNode :*= pbus.toSyncSlaves(tp.name, tp.externalSlaveBuffers)
|
||||||
wrapper
|
wrapper
|
||||||
}
|
}
|
||||||
case AsynchronousCrossing(depth, sync) => {
|
case AsynchronousCrossing(depth, sync) => {
|
||||||
val wrapper = LazyModule(new AsyncRocketTile(tp, i)(pWithExtra))
|
val wrapper = LazyModule(new AsyncRocketTile(tp, i)(pWithExtra))
|
||||||
sbus.fromAsyncTiles(depth, sync, tp.externalBuffers, tp.name) :=* wrapper.masterNode
|
sbus.fromAsyncTiles(depth, sync, tp.externalMasterBuffers, tp.name) :=* wrapper.masterNode
|
||||||
wrapper.slaveNode :*= pbus.toAsyncSlaves(sync, tp.name)
|
wrapper.slaveNode :*= pbus.toAsyncSlaves(sync, tp.name, tp.externalSlaveBuffers)
|
||||||
wrapper
|
wrapper
|
||||||
}
|
}
|
||||||
case RationalCrossing(direction) => {
|
case RationalCrossing(direction) => {
|
||||||
val wrapper = LazyModule(new RationalRocketTile(tp, i)(pWithExtra))
|
val wrapper = LazyModule(new RationalRocketTile(tp, i)(pWithExtra))
|
||||||
sbus.fromRationalTiles(direction, tp.externalBuffers, tp.name) :=* wrapper.masterNode
|
sbus.fromRationalTiles(direction, tp.externalMasterBuffers, tp.name) :=* wrapper.masterNode
|
||||||
wrapper.slaveNode :*= pbus.toRationalSlaves(tp.name)
|
wrapper.slaveNode :*= pbus.toRationalSlaves(tp.name, tp.externalSlaveBuffers)
|
||||||
wrapper
|
wrapper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ object ClintConsts
|
|||||||
def ints = 2
|
def ints = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
case class ClintParams(baseAddress: BigInt = 0x02000000)
|
case class ClintParams(baseAddress: BigInt = 0x02000000, intStages: Int = 0)
|
||||||
{
|
{
|
||||||
def address = AddressSet(baseAddress, ClintConsts.size-1)
|
def address = AddressSet(baseAddress, ClintConsts.size-1)
|
||||||
}
|
}
|
||||||
@ -71,8 +71,8 @@ class CoreplexLocalInterrupter(params: ClintParams)(implicit p: Parameters) exte
|
|||||||
val ipi = Seq.fill(nTiles) { RegInit(UInt(0, width = 1)) }
|
val ipi = Seq.fill(nTiles) { RegInit(UInt(0, width = 1)) }
|
||||||
|
|
||||||
io.int.zipWithIndex.foreach { case (int, i) =>
|
io.int.zipWithIndex.foreach { case (int, i) =>
|
||||||
int(0) := ipi(i)(0) // msip
|
int(0) := ShiftRegister(ipi(i)(0), params.intStages) // msip
|
||||||
int(1) := time.asUInt >= timecmp(i).asUInt // mtip
|
int(1) := ShiftRegister(time.asUInt >= timecmp(i).asUInt, params.intStages) // mtip
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 0000 msip hart 0
|
/* 0000 msip hart 0
|
||||||
|
@ -52,7 +52,7 @@ object PLICConsts
|
|||||||
require(hartBase >= enableBase(maxHarts))
|
require(hartBase >= enableBase(maxHarts))
|
||||||
}
|
}
|
||||||
|
|
||||||
case class PLICParams(baseAddress: BigInt = 0xC000000, maxPriorities: Int = 7)
|
case class PLICParams(baseAddress: BigInt = 0xC000000, maxPriorities: Int = 7, intStages: Int = 0)
|
||||||
{
|
{
|
||||||
require (maxPriorities >= 0)
|
require (maxPriorities >= 0)
|
||||||
def address = AddressSet(baseAddress, PLICConsts.size-1)
|
def address = AddressSet(baseAddress, PLICConsts.size-1)
|
||||||
@ -166,7 +166,7 @@ class TLPLIC(params: PLICParams)(implicit p: Parameters) extends LazyModule
|
|||||||
val (maxPri, maxDev) = findMax(effectivePriority)
|
val (maxPri, maxDev) = findMax(effectivePriority)
|
||||||
|
|
||||||
maxDevs(hart) := maxDev
|
maxDevs(hart) := maxDev
|
||||||
harts(hart) := Reg(next = maxPri) > Cat(UInt(1), threshold(hart))
|
harts(hart) := ShiftRegister(Reg(next = maxPri) > Cat(UInt(1), threshold(hart)), params.intStages)
|
||||||
}
|
}
|
||||||
|
|
||||||
def priorityRegField(x: UInt) = if (nPriorities > 0) RegField(32, x) else RegField.r(32, x)
|
def priorityRegField(x: UInt) = if (nPriorities > 0) RegField(32, x) else RegField.r(32, x)
|
||||||
|
@ -4,10 +4,30 @@ package freechips.rocketchip.diplomacy
|
|||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import chisel3.internal.sourceinfo.SourceInfo
|
import chisel3.internal.sourceinfo.SourceInfo
|
||||||
import freechips.rocketchip.config.Parameters
|
import freechips.rocketchip.config.{Parameters,Field}
|
||||||
import freechips.rocketchip.util.HeterogeneousBag
|
import freechips.rocketchip.util.HeterogeneousBag
|
||||||
import scala.collection.mutable.ListBuffer
|
import scala.collection.mutable.ListBuffer
|
||||||
|
|
||||||
|
object CardinalityInferenceDirection {
|
||||||
|
val cases = Seq(SOURCE_TO_SINK, SINK_TO_SOURCE, NO_INFERENCE)
|
||||||
|
sealed trait T {
|
||||||
|
def flip = this match {
|
||||||
|
case SOURCE_TO_SINK => SINK_TO_SOURCE
|
||||||
|
case SINK_TO_SOURCE => SOURCE_TO_SINK
|
||||||
|
case NO_INFERENCE => NO_INFERENCE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case object SOURCE_TO_SINK extends T
|
||||||
|
case object SINK_TO_SOURCE extends T
|
||||||
|
case object NO_INFERENCE extends T
|
||||||
|
}
|
||||||
|
|
||||||
|
private case object CardinalityInferenceDirectionKey extends
|
||||||
|
Field[CardinalityInferenceDirection.T](CardinalityInferenceDirection.NO_INFERENCE)
|
||||||
|
|
||||||
|
private case object MonitorsEnabled extends Field[Boolean](true)
|
||||||
|
|
||||||
// DI = Downwards flowing Parameters received on the inner side of the node
|
// DI = Downwards flowing Parameters received on the inner side of the node
|
||||||
// UI = Upwards flowing Parameters generated by the inner side of the node
|
// UI = Upwards flowing Parameters generated by the inner side of the node
|
||||||
// EI = Edge Parameters describing a connection on the inner side of the node
|
// EI = Edge Parameters describing a connection on the inner side of the node
|
||||||
@ -77,13 +97,15 @@ case class NodeHandle[DI, UI, BI <: Data, DO, UO, BO <: Data]
|
|||||||
|
|
||||||
trait InwardNodeHandle[DI, UI, BI <: Data]
|
trait InwardNodeHandle[DI, UI, BI <: Data]
|
||||||
{
|
{
|
||||||
val inward: InwardNode[DI, UI, BI]
|
protected[diplomacy] val inward: InwardNode[DI, UI, BI]
|
||||||
def := (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] =
|
def := (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] =
|
||||||
inward.:=(h)(p, sourceInfo)
|
inward.:=(h)(p, sourceInfo)
|
||||||
def :*= (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] =
|
def :*= (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] =
|
||||||
inward.:*=(h)(p, sourceInfo)
|
inward.:*=(h)(p, sourceInfo)
|
||||||
def :=* (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] =
|
def :=* (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] =
|
||||||
inward.:=*(h)(p, sourceInfo)
|
inward.:=*(h)(p, sourceInfo)
|
||||||
|
def :=? (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] =
|
||||||
|
inward.:=?(h)(p, sourceInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed trait NodeBinding
|
sealed trait NodeBinding
|
||||||
@ -93,22 +115,22 @@ case object BIND_STAR extends NodeBinding
|
|||||||
|
|
||||||
trait InwardNode[DI, UI, BI <: Data] extends BaseNode with InwardNodeHandle[DI, UI, BI]
|
trait InwardNode[DI, UI, BI <: Data] extends BaseNode with InwardNodeHandle[DI, UI, BI]
|
||||||
{
|
{
|
||||||
val inward = this
|
protected[diplomacy] val inward = this
|
||||||
|
|
||||||
protected[diplomacy] val numPI: Range.Inclusive
|
protected[diplomacy] val numPI: Range.Inclusive
|
||||||
require (!numPI.isEmpty, s"No number of inputs would be acceptable to ${name}${lazyModule.line}")
|
require (!numPI.isEmpty, s"No number of inputs would be acceptable to ${name}${lazyModule.line}")
|
||||||
require (numPI.start >= 0, s"${name} accepts a negative number of inputs${lazyModule.line}")
|
require (numPI.start >= 0, s"${name} accepts a negative number of inputs${lazyModule.line}")
|
||||||
|
|
||||||
private val accPI = ListBuffer[(Int, OutwardNode[DI, UI, BI], NodeBinding)]()
|
private val accPI = ListBuffer[(Int, OutwardNode[DI, UI, BI], NodeBinding, Parameters)]()
|
||||||
private var iRealized = false
|
private var iRealized = false
|
||||||
|
|
||||||
protected[diplomacy] def iPushed = accPI.size
|
protected[diplomacy] def iPushed = accPI.size
|
||||||
protected[diplomacy] def iPush(index: Int, node: OutwardNode[DI, UI, BI], binding: NodeBinding)(implicit sourceInfo: SourceInfo) {
|
protected[diplomacy] def iPush(index: Int, node: OutwardNode[DI, UI, BI], binding: NodeBinding)(implicit p: Parameters, sourceInfo: SourceInfo) {
|
||||||
val info = sourceLine(sourceInfo, " at ", "")
|
val info = sourceLine(sourceInfo, " at ", "")
|
||||||
val noIs = numPI.size == 1 && numPI.contains(0)
|
val noIs = numPI.size == 1 && numPI.contains(0)
|
||||||
require (!noIs, s"${name}${lazyModule.line} was incorrectly connected as a sink" + info)
|
require (!noIs, s"${name}${lazyModule.line} was incorrectly connected as a sink" + info)
|
||||||
require (!iRealized, s"${name}${lazyModule.line} was incorrectly connected as a sink after it's .module was used" + info)
|
require (!iRealized, s"${name}${lazyModule.line} was incorrectly connected as a sink after it's .module was used" + info)
|
||||||
accPI += ((index, node, binding))
|
accPI += ((index, node, binding, p))
|
||||||
}
|
}
|
||||||
|
|
||||||
protected[diplomacy] lazy val iBindings = { iRealized = true; accPI.result() }
|
protected[diplomacy] lazy val iBindings = { iRealized = true; accPI.result() }
|
||||||
@ -116,32 +138,32 @@ trait InwardNode[DI, UI, BI <: Data] extends BaseNode with InwardNodeHandle[DI,
|
|||||||
protected[diplomacy] val iStar: Int
|
protected[diplomacy] val iStar: Int
|
||||||
protected[diplomacy] val iPortMapping: Seq[(Int, Int)]
|
protected[diplomacy] val iPortMapping: Seq[(Int, Int)]
|
||||||
protected[diplomacy] val iParams: Seq[UI]
|
protected[diplomacy] val iParams: Seq[UI]
|
||||||
val bundleIn: HeterogeneousBag[BI]
|
protected[diplomacy] val bundleIn: HeterogeneousBag[BI]
|
||||||
}
|
}
|
||||||
|
|
||||||
trait OutwardNodeHandle[DO, UO, BO <: Data]
|
trait OutwardNodeHandle[DO, UO, BO <: Data]
|
||||||
{
|
{
|
||||||
val outward: OutwardNode[DO, UO, BO]
|
protected[diplomacy] val outward: OutwardNode[DO, UO, BO]
|
||||||
}
|
}
|
||||||
|
|
||||||
trait OutwardNode[DO, UO, BO <: Data] extends BaseNode with OutwardNodeHandle[DO, UO, BO]
|
trait OutwardNode[DO, UO, BO <: Data] extends BaseNode with OutwardNodeHandle[DO, UO, BO]
|
||||||
{
|
{
|
||||||
val outward = this
|
protected[diplomacy] val outward = this
|
||||||
|
|
||||||
protected[diplomacy] val numPO: Range.Inclusive
|
protected[diplomacy] val numPO: Range.Inclusive
|
||||||
require (!numPO.isEmpty, s"No number of outputs would be acceptable to ${name}${lazyModule.line}")
|
require (!numPO.isEmpty, s"No number of outputs would be acceptable to ${name}${lazyModule.line}")
|
||||||
require (numPO.start >= 0, s"${name} accepts a negative number of outputs${lazyModule.line}")
|
require (numPO.start >= 0, s"${name} accepts a negative number of outputs${lazyModule.line}")
|
||||||
|
|
||||||
private val accPO = ListBuffer[(Int, InwardNode [DO, UO, BO], NodeBinding)]()
|
private val accPO = ListBuffer[(Int, InwardNode [DO, UO, BO], NodeBinding, Parameters)]()
|
||||||
private var oRealized = false
|
private var oRealized = false
|
||||||
|
|
||||||
protected[diplomacy] def oPushed = accPO.size
|
protected[diplomacy] def oPushed = accPO.size
|
||||||
protected[diplomacy] def oPush(index: Int, node: InwardNode [DO, UO, BO], binding: NodeBinding)(implicit sourceInfo: SourceInfo) {
|
protected[diplomacy] def oPush(index: Int, node: InwardNode [DO, UO, BO], binding: NodeBinding)(implicit p: Parameters, sourceInfo: SourceInfo) {
|
||||||
val info = sourceLine(sourceInfo, " at ", "")
|
val info = sourceLine(sourceInfo, " at ", "")
|
||||||
val noOs = numPO.size == 1 && numPO.contains(0)
|
val noOs = numPO.size == 1 && numPO.contains(0)
|
||||||
require (!noOs, s"${name}${lazyModule.line} was incorrectly connected as a source" + info)
|
require (!noOs, s"${name}${lazyModule.line} was incorrectly connected as a source" + info)
|
||||||
require (!oRealized, s"${name}${lazyModule.line} was incorrectly connected as a source after it's .module was used" + info)
|
require (!oRealized, s"${name}${lazyModule.line} was incorrectly connected as a source after it's .module was used" + info)
|
||||||
accPO += ((index, node, binding))
|
accPO += ((index, node, binding, p))
|
||||||
}
|
}
|
||||||
|
|
||||||
protected[diplomacy] lazy val oBindings = { oRealized = true; accPO.result() }
|
protected[diplomacy] lazy val oBindings = { oRealized = true; accPO.result() }
|
||||||
@ -149,7 +171,7 @@ trait OutwardNode[DO, UO, BO <: Data] extends BaseNode with OutwardNodeHandle[DO
|
|||||||
protected[diplomacy] val oStar: Int
|
protected[diplomacy] val oStar: Int
|
||||||
protected[diplomacy] val oPortMapping: Seq[(Int, Int)]
|
protected[diplomacy] val oPortMapping: Seq[(Int, Int)]
|
||||||
protected[diplomacy] val oParams: Seq[DO]
|
protected[diplomacy] val oParams: Seq[DO]
|
||||||
val bundleOut: HeterogeneousBag[BO]
|
protected[diplomacy] val bundleOut: HeterogeneousBag[BO]
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
||||||
@ -164,22 +186,22 @@ abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
|||||||
protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI]
|
protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI]
|
||||||
|
|
||||||
protected[diplomacy] lazy val (oPortMapping, iPortMapping, oStar, iStar) = {
|
protected[diplomacy] lazy val (oPortMapping, iPortMapping, oStar, iStar) = {
|
||||||
val oStars = oBindings.filter { case (_,_,b) => b == BIND_STAR }.size
|
val oStars = oBindings.filter { case (_,_,b,_) => b == BIND_STAR }.size
|
||||||
val iStars = iBindings.filter { case (_,_,b) => b == BIND_STAR }.size
|
val iStars = iBindings.filter { case (_,_,b,_) => b == BIND_STAR }.size
|
||||||
val oKnown = oBindings.map { case (_, n, b) => b match {
|
val oKnown = oBindings.map { case (_, n, b, _) => b match {
|
||||||
case BIND_ONCE => 1
|
case BIND_ONCE => 1
|
||||||
case BIND_QUERY => n.iStar
|
case BIND_QUERY => n.iStar
|
||||||
case BIND_STAR => 0 }}.foldLeft(0)(_+_)
|
case BIND_STAR => 0 }}.foldLeft(0)(_+_)
|
||||||
val iKnown = iBindings.map { case (_, n, b) => b match {
|
val iKnown = iBindings.map { case (_, n, b, _) => b match {
|
||||||
case BIND_ONCE => 1
|
case BIND_ONCE => 1
|
||||||
case BIND_QUERY => n.oStar
|
case BIND_QUERY => n.oStar
|
||||||
case BIND_STAR => 0 }}.foldLeft(0)(_+_)
|
case BIND_STAR => 0 }}.foldLeft(0)(_+_)
|
||||||
val (iStar, oStar) = resolveStar(iKnown, oKnown, iStars, oStars)
|
val (iStar, oStar) = resolveStar(iKnown, oKnown, iStars, oStars)
|
||||||
val oSum = oBindings.map { case (_, n, b) => b match {
|
val oSum = oBindings.map { case (_, n, b, _) => b match {
|
||||||
case BIND_ONCE => 1
|
case BIND_ONCE => 1
|
||||||
case BIND_QUERY => n.iStar
|
case BIND_QUERY => n.iStar
|
||||||
case BIND_STAR => oStar }}.scanLeft(0)(_+_)
|
case BIND_STAR => oStar }}.scanLeft(0)(_+_)
|
||||||
val iSum = iBindings.map { case (_, n, b) => b match {
|
val iSum = iBindings.map { case (_, n, b, _) => b match {
|
||||||
case BIND_ONCE => 1
|
case BIND_ONCE => 1
|
||||||
case BIND_QUERY => n.oStar
|
case BIND_QUERY => n.oStar
|
||||||
case BIND_STAR => iStar }}.scanLeft(0)(_+_)
|
case BIND_STAR => iStar }}.scanLeft(0)(_+_)
|
||||||
@ -190,11 +212,11 @@ abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
|||||||
(oSum.init zip oSum.tail, iSum.init zip iSum.tail, oStar, iStar)
|
(oSum.init zip oSum.tail, iSum.init zip iSum.tail, oStar, iStar)
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy val oPorts = oBindings.flatMap { case (i, n, _) =>
|
lazy val oPorts = oBindings.flatMap { case (i, n, _, _) =>
|
||||||
val (start, end) = n.iPortMapping(i)
|
val (start, end) = n.iPortMapping(i)
|
||||||
(start until end) map { j => (j, n) }
|
(start until end) map { j => (j, n) }
|
||||||
}
|
}
|
||||||
lazy val iPorts = iBindings.flatMap { case (i, n, _) =>
|
lazy val iPorts = iBindings.flatMap { case (i, n, _, _) =>
|
||||||
val (start, end) = n.oPortMapping(i)
|
val (start, end) = n.oPortMapping(i)
|
||||||
(start until end) map { j => (j, n) }
|
(start until end) map { j => (j, n) }
|
||||||
}
|
}
|
||||||
@ -218,6 +240,9 @@ abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
|||||||
lazy val externalEdgesOut = if (externalOut) {edgesOut} else { Seq() }
|
lazy val externalEdgesOut = if (externalOut) {edgesOut} else { Seq() }
|
||||||
lazy val externalEdgesIn = if (externalIn) {edgesIn} else { Seq() }
|
lazy val externalEdgesIn = if (externalIn) {edgesIn} else { Seq() }
|
||||||
|
|
||||||
|
lazy val paramsOut: Seq[Parameters] = (oPortMapping zip oBindings).flatMap { case ((s, e), b) => Seq.fill(e-s) { b._4 } }
|
||||||
|
lazy val paramsIn: Seq[Parameters] = (iPortMapping zip iBindings).flatMap { case ((s, e), b) => Seq.fill(e-s) { b._4 } }
|
||||||
|
|
||||||
val flip = false // needed for blind nodes
|
val flip = false // needed for blind nodes
|
||||||
private def flipO(b: HeterogeneousBag[BO]) = if (flip) b.flip else b
|
private def flipO(b: HeterogeneousBag[BO]) = if (flip) b.flip else b
|
||||||
private def flipI(b: HeterogeneousBag[BI]) = if (flip) b else b.flip
|
private def flipI(b: HeterogeneousBag[BI]) = if (flip) b else b.flip
|
||||||
@ -229,7 +254,7 @@ abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
|||||||
lazy val bundleIn = wireI(flipI(HeterogeneousBag(edgesIn .map(inner.bundleI(_)))))
|
lazy val bundleIn = wireI(flipI(HeterogeneousBag(edgesIn .map(inner.bundleI(_)))))
|
||||||
|
|
||||||
// connects the outward part of a node with the inward part of this node
|
// connects the outward part of a node with the inward part of this node
|
||||||
private def bind(h: OutwardNodeHandle[DI, UI, BI], binding: NodeBinding, enableMonitoring: Boolean)
|
private def bind(h: OutwardNodeHandle[DI, UI, BI], binding: NodeBinding)
|
||||||
(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = {
|
(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = {
|
||||||
val x = this // x := y
|
val x = this // x := y
|
||||||
val y = h.outward
|
val y = h.outward
|
||||||
@ -256,18 +281,21 @@ abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
|||||||
(x.bundleIn(iStart+j), y.bundleOut(oStart+j))
|
(x.bundleIn(iStart+j), y.bundleOut(oStart+j))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val (out, newbinding) = inner.connect(edges _, bundles _, enableMonitoring)
|
val (out, newbinding) = inner.connect(edges _, bundles _, p(MonitorsEnabled))
|
||||||
LazyModule.stack.head.bindings = newbinding :: LazyModule.stack.head.bindings
|
LazyModule.stack.head.bindings = newbinding :: LazyModule.stack.head.bindings
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
override def := (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_ONCE, true)
|
override def := (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_ONCE)
|
||||||
override def :*= (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_STAR, true)
|
override def :*= (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_STAR)
|
||||||
override def :=* (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_QUERY, true)
|
override def :=* (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_QUERY)
|
||||||
|
override def :=? (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = {
|
||||||
def connectButDontMonitor(h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_ONCE, false)
|
p(CardinalityInferenceDirectionKey) match {
|
||||||
def connectButDontMonitorSlaves(h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_STAR, false)
|
case CardinalityInferenceDirection.SOURCE_TO_SINK => this :=* h
|
||||||
def connectButDontMonitorMasters(h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_QUERY, false)
|
case CardinalityInferenceDirection.SINK_TO_SOURCE => this :*= h
|
||||||
|
case CardinalityInferenceDirection.NO_INFERENCE => this := h
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// meta-data for printing the node graph
|
// meta-data for printing the node graph
|
||||||
protected[diplomacy] def colour = inner.colour
|
protected[diplomacy] def colour = inner.colour
|
||||||
|
@ -293,3 +293,14 @@ object BufferParams
|
|||||||
val flow = BufferParams(1, true, false)
|
val flow = BufferParams(1, true, false)
|
||||||
val pipe = BufferParams(1, false, true)
|
val pipe = BufferParams(1, false, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case class TriStateValue(value: Boolean, set: Boolean)
|
||||||
|
{
|
||||||
|
def update(orig: Boolean) = if (set) value else orig
|
||||||
|
}
|
||||||
|
|
||||||
|
object TriStateValue
|
||||||
|
{
|
||||||
|
implicit def apply(value: Boolean): TriStateValue = TriStateValue(value, true)
|
||||||
|
def unset = TriStateValue(false, false)
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
package freechips.rocketchip
|
package freechips.rocketchip
|
||||||
|
|
||||||
import chisel3.internal.sourceinfo.{SourceInfo, SourceLine, UnlocatableSourceInfo}
|
import chisel3.internal.sourceinfo.{SourceInfo, SourceLine, UnlocatableSourceInfo}
|
||||||
|
import freechips.rocketchip.config.Parameters
|
||||||
|
|
||||||
package object diplomacy
|
package object diplomacy
|
||||||
{
|
{
|
||||||
@ -20,4 +21,23 @@ package object diplomacy
|
|||||||
bitIndexes(x.clearBit(lowest), lowest +: tail)
|
bitIndexes(x.clearBit(lowest), lowest +: tail)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def SinkCardinality[T](body: Parameters => T)(implicit p: Parameters) = body(p.alterPartial {
|
||||||
|
case CardinalityInferenceDirectionKey => CardinalityInferenceDirection.SINK_TO_SOURCE
|
||||||
|
})
|
||||||
|
def SourceCardinality[T](body: Parameters => T)(implicit p: Parameters) = body(p.alterPartial {
|
||||||
|
case CardinalityInferenceDirectionKey => CardinalityInferenceDirection.SOURCE_TO_SINK
|
||||||
|
})
|
||||||
|
def UnaryCardinality[T](body: Parameters => T)(implicit p: Parameters) = body(p.alterPartial {
|
||||||
|
case CardinalityInferenceDirectionKey => CardinalityInferenceDirection.NO_INFERENCE
|
||||||
|
})
|
||||||
|
def FlipCardinality[T](body: Parameters => T)(implicit p: Parameters) = body(p.alterPartial {
|
||||||
|
case CardinalityInferenceDirectionKey => p(CardinalityInferenceDirectionKey).flip
|
||||||
|
})
|
||||||
|
def EnableMonitors[T](body: Parameters => T)(implicit p: Parameters) = body(p.alterPartial {
|
||||||
|
case MonitorsEnabled => true
|
||||||
|
})
|
||||||
|
def DisableMonitors[T](body: Parameters => T)(implicit p: Parameters) = body(p.alterPartial {
|
||||||
|
case MonitorsEnabled => false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ 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.coreplex._
|
||||||
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp}
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
import freechips.rocketchip.tile._
|
import freechips.rocketchip.tile._
|
||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
@ -61,7 +61,7 @@ class Frontend(val icacheParams: ICacheParams, hartid: Int)(implicit p: Paramete
|
|||||||
|
|
||||||
masterNode := icache.masterNode
|
masterNode := icache.masterNode
|
||||||
// Avoid breaking tile dedup due to address constants in the monitor
|
// Avoid breaking tile dedup due to address constants in the monitor
|
||||||
icache.slaveNode.map { _ connectButDontMonitor slaveNode }
|
DisableMonitors { implicit p => icache.slaveNode.map { _ := slaveNode } }
|
||||||
}
|
}
|
||||||
|
|
||||||
class FrontendBundle(outer: Frontend) extends CoreBundle()(outer.p) {
|
class FrontendBundle(outer: Frontend) extends CoreBundle()(outer.p) {
|
||||||
|
@ -103,16 +103,18 @@ trait CanHaveScratchpad extends HasHellaCache with HasICacheFrontend with HasCor
|
|||||||
val slaveNode = TLInputNode() // Up to two uses for this input node:
|
val slaveNode = TLInputNode() // Up to two uses for this input node:
|
||||||
|
|
||||||
// 1) Frontend always exists, but may or may not have a scratchpad node
|
// 1) Frontend always exists, but may or may not have a scratchpad node
|
||||||
|
// 2) ScratchpadSlavePort always has a node, but only exists when the HellaCache has a scratchpad
|
||||||
val fg = LazyModule(new TLFragmenter(fetchWidth*coreInstBytes, p(CacheBlockBytes), earlyAck=true))
|
val fg = LazyModule(new TLFragmenter(fetchWidth*coreInstBytes, p(CacheBlockBytes), earlyAck=true))
|
||||||
val ww = LazyModule(new TLWidthWidget(xLen/8))
|
val ww = LazyModule(new TLWidthWidget(xLen/8))
|
||||||
frontend.slaveNode connectButDontMonitorSlaves fg.node
|
|
||||||
fg.node connectButDontMonitorSlaves ww.node
|
|
||||||
ww.node connectButDontMonitorSlaves slaveNode
|
|
||||||
|
|
||||||
// 2) ScratchpadSlavePort always has a node, but only exists when the HellaCache has a scratchpad
|
|
||||||
val scratch = tileParams.dcache.flatMap(d => d.scratch.map(s =>
|
val scratch = tileParams.dcache.flatMap(d => d.scratch.map(s =>
|
||||||
LazyModule(new ScratchpadSlavePort(AddressSet(s, d.dataScratchpadBytes-1)))))
|
LazyModule(new ScratchpadSlavePort(AddressSet(s, d.dataScratchpadBytes-1)))))
|
||||||
scratch foreach { lm => lm.node connectButDontMonitor TLFragmenter(xLen/8, p(CacheBlockBytes), earlyAck=true)(slaveNode) }
|
|
||||||
|
DisableMonitors { implicit p =>
|
||||||
|
frontend.slaveNode :*= fg.node
|
||||||
|
fg.node :*= ww.node
|
||||||
|
ww.node :*= slaveNode
|
||||||
|
scratch foreach { lm => lm.node := TLFragmenter(xLen/8, p(CacheBlockBytes), earlyAck=true)(slaveNode) }
|
||||||
|
}
|
||||||
|
|
||||||
def findScratchpadFromICache: Option[AddressSet] = scratch.map { s =>
|
def findScratchpadFromICache: Option[AddressSet] = scratch.map { s =>
|
||||||
val finalNode = frontend.masterNode.edgesOut.head.manager.managers.find(_.nodePath.last == s.node)
|
val finalNode = frontend.masterNode.edgesOut.head.manager.managers.find(_.nodePath.last == s.node)
|
||||||
|
@ -20,7 +20,8 @@ case class RocketTileParams(
|
|||||||
dataScratchpadBytes: Int = 0,
|
dataScratchpadBytes: Int = 0,
|
||||||
boundaryBuffers: Boolean = false,
|
boundaryBuffers: Boolean = false,
|
||||||
name: Option[String] = Some("tile"),
|
name: Option[String] = Some("tile"),
|
||||||
externalBuffers: Int = 0) extends TileParams {
|
externalMasterBuffers: Int = 0,
|
||||||
|
externalSlaveBuffers: Int = 0) extends TileParams {
|
||||||
require(icache.isDefined)
|
require(icache.isDefined)
|
||||||
require(dcache.isDefined)
|
require(dcache.isDefined)
|
||||||
}
|
}
|
||||||
@ -190,7 +191,7 @@ abstract class RocketTileWrapper(rtp: RocketTileParams, hartid: Int)(implicit p:
|
|||||||
def optionalSlaveBuffer(in: TLOutwardNode): TLOutwardNode = {
|
def optionalSlaveBuffer(in: TLOutwardNode): TLOutwardNode = {
|
||||||
if (rtp.boundaryBuffers) {
|
if (rtp.boundaryBuffers) {
|
||||||
val sbuf = LazyModule(new TLBuffer(BufferParams.flow, BufferParams.none, BufferParams.none, BufferParams.none, BufferParams.none))
|
val sbuf = LazyModule(new TLBuffer(BufferParams.flow, BufferParams.none, BufferParams.none, BufferParams.none, BufferParams.none))
|
||||||
sbuf.node connectButDontMonitorSlaves in
|
DisableMonitors { implicit p => sbuf.node :*= in }
|
||||||
sbuf.node
|
sbuf.node
|
||||||
} else {
|
} else {
|
||||||
in
|
in
|
||||||
@ -216,7 +217,7 @@ class SyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters)
|
|||||||
masterNode :=* optionalMasterBuffer(rocket.masterNode)
|
masterNode :=* optionalMasterBuffer(rocket.masterNode)
|
||||||
|
|
||||||
val slaveNode = new TLInputNode() { override def reverse = true }
|
val slaveNode = new TLInputNode() { override def reverse = true }
|
||||||
rocket.slaveNode connectButDontMonitorSlaves optionalSlaveBuffer(slaveNode)
|
DisableMonitors { implicit p => rocket.slaveNode :*= optionalSlaveBuffer(slaveNode) }
|
||||||
|
|
||||||
// Fully async interrupts need synchronizers.
|
// Fully async interrupts need synchronizers.
|
||||||
// Others need no synchronization.
|
// Others need no synchronization.
|
||||||
@ -236,8 +237,11 @@ class AsyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters
|
|||||||
|
|
||||||
val slaveNode = new TLAsyncInputNode() { override def reverse = true }
|
val slaveNode = new TLAsyncInputNode() { override def reverse = true }
|
||||||
val sink = LazyModule(new TLAsyncCrossingSink)
|
val sink = LazyModule(new TLAsyncCrossingSink)
|
||||||
rocket.slaveNode connectButDontMonitorSlaves sink.node
|
|
||||||
sink.node connectButDontMonitorSlaves slaveNode
|
DisableMonitors { implicit p =>
|
||||||
|
rocket.slaveNode :*= sink.node
|
||||||
|
sink.node :*= slaveNode
|
||||||
|
}
|
||||||
|
|
||||||
// Fully async interrupts need synchronizers,
|
// Fully async interrupts need synchronizers,
|
||||||
// as do those coming from the periphery clock.
|
// as do those coming from the periphery clock.
|
||||||
@ -260,8 +264,11 @@ class RationalRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Paramet
|
|||||||
|
|
||||||
val slaveNode = new TLRationalInputNode() { override def reverse = true }
|
val slaveNode = new TLRationalInputNode() { override def reverse = true }
|
||||||
val sink = LazyModule(new TLRationalCrossingSink(SlowToFast))
|
val sink = LazyModule(new TLRationalCrossingSink(SlowToFast))
|
||||||
sink.node connectButDontMonitorSlaves slaveNode
|
|
||||||
rocket.slaveNode connectButDontMonitorSlaves optionalSlaveBuffer(sink.node)
|
DisableMonitors { implicit p =>
|
||||||
|
sink.node :*= slaveNode
|
||||||
|
rocket.slaveNode :*= optionalSlaveBuffer(sink.node)
|
||||||
|
}
|
||||||
|
|
||||||
// Fully async interrupts need synchronizers.
|
// Fully async interrupts need synchronizers.
|
||||||
// Those coming from periphery clock need a
|
// Those coming from periphery clock need a
|
||||||
|
@ -80,7 +80,7 @@ object TLAsyncCrossingSource
|
|||||||
// applied to the TL source node; y.node := TLAsyncCrossingSource()(x.node)
|
// applied to the TL source node; y.node := TLAsyncCrossingSource()(x.node)
|
||||||
def apply(sync: Int = 3)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLAsyncOutwardNode = {
|
def apply(sync: Int = 3)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLAsyncOutwardNode = {
|
||||||
val source = LazyModule(new TLAsyncCrossingSource(sync))
|
val source = LazyModule(new TLAsyncCrossingSource(sync))
|
||||||
source.node := x
|
source.node :=? x
|
||||||
source.node
|
source.node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ object TLAsyncCrossingSink
|
|||||||
// applied to the TL source node; y.node := TLAsyncCrossingSink()(x.node)
|
// applied to the TL source node; y.node := TLAsyncCrossingSink()(x.node)
|
||||||
def apply(depth: Int = 8, sync: Int = 3)(x: TLAsyncOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
def apply(depth: Int = 8, sync: Int = 3)(x: TLAsyncOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
||||||
val sink = LazyModule(new TLAsyncCrossingSink(depth, sync))
|
val sink = LazyModule(new TLAsyncCrossingSink(depth, sync))
|
||||||
sink.node := x
|
sink.node :=? x
|
||||||
sink.node
|
sink.node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -265,7 +265,7 @@ object TLAtomicAutomata
|
|||||||
// applied to the TL source node; y.node := TLAtomicAutomata(x.node)
|
// applied to the TL source node; y.node := TLAtomicAutomata(x.node)
|
||||||
def apply(logical: Boolean = true, arithmetic: Boolean = true, concurrency: Int = 1, passthrough: Boolean = true)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
def apply(logical: Boolean = true, arithmetic: Boolean = true, concurrency: Int = 1, passthrough: Boolean = true)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
||||||
val atomics = LazyModule(new TLAtomicAutomata(logical, arithmetic, concurrency, passthrough))
|
val atomics = LazyModule(new TLAtomicAutomata(logical, arithmetic, concurrency, passthrough))
|
||||||
atomics.node := x
|
atomics.node :=? x
|
||||||
atomics.node
|
atomics.node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ object TLBuffer
|
|||||||
d: BufferParams,
|
d: BufferParams,
|
||||||
e: BufferParams)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
e: BufferParams)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
||||||
val buffer = LazyModule(new TLBuffer(a, b, c, d, e))
|
val buffer = LazyModule(new TLBuffer(a, b, c, d, e))
|
||||||
buffer.node := x
|
buffer.node :=? x
|
||||||
buffer.node
|
buffer.node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,18 +82,19 @@ class TLBufferChain(depth: Int)(implicit p: Parameters) extends LazyModule {
|
|||||||
|
|
||||||
val nodeIn = TLInputNode()
|
val nodeIn = TLInputNode()
|
||||||
val nodeOut = TLOutputNode()
|
val nodeOut = TLOutputNode()
|
||||||
|
val node = NodeHandle(nodeIn, nodeOut)
|
||||||
|
|
||||||
val buf_chain = if (depth > 0) {
|
val buf_chain = if (depth > 0) {
|
||||||
val chain = List.fill(depth)(LazyModule(new TLBuffer(BufferParams.default)))
|
val chain = List.fill(depth)(LazyModule(new TLBuffer(BufferParams.default)))
|
||||||
|
|
||||||
(chain.init zip chain.tail) foreach { case(prev, next) => next.node :=* prev.node }
|
(chain.init zip chain.tail) foreach { case(prev, next) => next.node :=? prev.node }
|
||||||
chain
|
chain
|
||||||
} else {
|
} else {
|
||||||
List(LazyModule(new TLBuffer(BufferParams.none)))
|
List(LazyModule(new TLBuffer(BufferParams.none)))
|
||||||
}
|
}
|
||||||
|
|
||||||
buf_chain.head.node :=* nodeIn
|
buf_chain.head.node :=? nodeIn
|
||||||
nodeOut :=* buf_chain.last.node
|
nodeOut :=? buf_chain.last.node
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
@ -102,3 +103,12 @@ class TLBufferChain(depth: Int)(implicit p: Parameters) extends LazyModule {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object TLBufferChain
|
||||||
|
{
|
||||||
|
def apply(depth: Int)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
||||||
|
val buffer = LazyModule(new TLBufferChain(depth))
|
||||||
|
buffer.node :=? x
|
||||||
|
buffer.node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -68,26 +68,32 @@ abstract class TLBusWrapper(params: TLBusParams, val busName: String)(implicit p
|
|||||||
protected def inwardBufNode: TLInwardNode = master_buffer.node
|
protected def inwardBufNode: TLInwardNode = master_buffer.node
|
||||||
|
|
||||||
protected def bufferChain(depth: Int, name: Option[String] = None): (TLInwardNode, TLOutwardNode) = {
|
protected def bufferChain(depth: Int, name: Option[String] = None): (TLInwardNode, TLOutwardNode) = {
|
||||||
val chain = LazyModule(new TLBufferChain(depth))
|
SourceCardinality { implicit p =>
|
||||||
name.foreach { n => chain.suggestName(s"${busName}_${n}_TLBufferChain")}
|
val chain = LazyModule(new TLBufferChain(depth))
|
||||||
(chain.nodeIn, chain.nodeOut)
|
name.foreach { n => chain.suggestName(s"${busName}_${n}_TLBufferChain")}
|
||||||
|
(chain.nodeIn, chain.nodeOut)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def bufferFromMasters: TLInwardNode = inwardBufNode
|
def bufferFromMasters: TLInwardNode = inwardBufNode
|
||||||
|
|
||||||
def bufferToSlaves: TLOutwardNode = outwardBufNode
|
def bufferToSlaves: TLOutwardNode = outwardBufNode
|
||||||
|
|
||||||
def toAsyncSlaves(sync: Int = 3, name: Option[String] = None): TLAsyncOutwardNode = {
|
def toSyncSlaves(name: Option[String] = None, addBuffers: Int = 0): TLOutwardNode = SinkCardinality { implicit p =>
|
||||||
|
TLBufferChain(addBuffers)(outwardBufNode)
|
||||||
|
}
|
||||||
|
|
||||||
|
def toAsyncSlaves(sync: Int = 3, name: Option[String] = None, addBuffers: Int = 0): TLAsyncOutwardNode = SinkCardinality { implicit p =>
|
||||||
val source = LazyModule(new TLAsyncCrossingSource(sync))
|
val source = LazyModule(new TLAsyncCrossingSource(sync))
|
||||||
name.foreach{ n => source.suggestName(s"${busName}_${n}_TLAsyncCrossingSource")}
|
name.foreach{ n => source.suggestName(s"${busName}_${n}_TLAsyncCrossingSource")}
|
||||||
source.node :*= outwardNode
|
source.node :=? TLBufferChain(addBuffers)(outwardNode)
|
||||||
source.node
|
source.node
|
||||||
}
|
}
|
||||||
|
|
||||||
def toRationalSlaves(name: Option[String] = None): TLRationalOutwardNode = {
|
def toRationalSlaves(name: Option[String] = None, addBuffers: Int = 0): TLRationalOutwardNode = SinkCardinality { implicit p =>
|
||||||
val source = LazyModule(new TLRationalCrossingSource())
|
val source = LazyModule(new TLRationalCrossingSource())
|
||||||
name.foreach{ n => source.suggestName(s"${busName}_${n}_TLRationalCrossingSource")}
|
name.foreach{ n => source.suggestName(s"${busName}_${n}_TLRationalCrossingSource")}
|
||||||
source.node :*= outwardNode
|
source.node :=? TLBufferChain(addBuffers)(outwardNode)
|
||||||
source.node
|
source.node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ object TLCacheCork
|
|||||||
// applied to the TL source node; y.node := TLCacheCork()(x.node)
|
// applied to the TL source node; y.node := TLCacheCork()(x.node)
|
||||||
def apply(unsafe: Boolean = false)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
def apply(unsafe: Boolean = false)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
||||||
val cork = LazyModule(new TLCacheCork(unsafe))
|
val cork = LazyModule(new TLCacheCork(unsafe))
|
||||||
cork.node := x
|
cork.node :=? x
|
||||||
cork.node
|
cork.node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ object TLDelayer
|
|||||||
// applied to the TL source node; y.node := TLDelayer(0.01)(x.node)
|
// applied to the TL source node; y.node := TLDelayer(0.01)(x.node)
|
||||||
def apply(q: Double)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
def apply(q: Double)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
||||||
val delayer = LazyModule(new TLDelayer(q))
|
val delayer = LazyModule(new TLDelayer(q))
|
||||||
delayer.node := x
|
delayer.node :=? x
|
||||||
delayer.node
|
delayer.node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ object TLFIFOFixer
|
|||||||
// applied to the TL source node; y.node := TLFIFOFixer()(x.node)
|
// applied to the TL source node; y.node := TLFIFOFixer()(x.node)
|
||||||
def apply(policy: Policy = all)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
def apply(policy: Policy = all)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
||||||
val fixer = LazyModule(new TLFIFOFixer(policy))
|
val fixer = LazyModule(new TLFIFOFixer(policy))
|
||||||
fixer.node := x
|
fixer.node :=? x
|
||||||
fixer.node
|
fixer.node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -292,7 +292,7 @@ object TLFragmenter
|
|||||||
// applied to the TL source node; y.node := TLFragmenter(x.node, 256, 4)
|
// applied to the TL source node; y.node := TLFragmenter(x.node, 256, 4)
|
||||||
def apply(minSize: Int, maxSize: Int, alwaysMin: Boolean = false, earlyAck: Boolean = false)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
def apply(minSize: Int, maxSize: Int, alwaysMin: Boolean = false, earlyAck: Boolean = false)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
||||||
val fragmenter = LazyModule(new TLFragmenter(minSize, maxSize, alwaysMin, earlyAck))
|
val fragmenter = LazyModule(new TLFragmenter(minSize, maxSize, alwaysMin, earlyAck))
|
||||||
fragmenter.node := x
|
fragmenter.node :=? x
|
||||||
fragmenter.node
|
fragmenter.node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ object TLHintHandler
|
|||||||
// applied to the TL source node; y.node := TLHintHandler(x.node)
|
// applied to the TL source node; y.node := TLHintHandler(x.node)
|
||||||
def apply(supportManagers: Boolean = true, supportClients: Boolean = false, passthrough: Boolean = true)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
def apply(supportManagers: Boolean = true, supportClients: Boolean = false, passthrough: Boolean = true)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
||||||
val hints = LazyModule(new TLHintHandler(supportManagers, supportClients, passthrough))
|
val hints = LazyModule(new TLHintHandler(supportManagers, supportClients, passthrough))
|
||||||
hints.node := x
|
hints.node :=? x
|
||||||
hints.node
|
hints.node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ object TLIsolation
|
|||||||
// **** WARNING: the isolation functions must bring the values to 0 ****
|
// **** WARNING: the isolation functions must bring the values to 0 ****
|
||||||
def apply(fOut: (Bool, UInt) => UInt, fIn: (Bool, UInt) => UInt)(x: TLAsyncOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): (TLAsyncOutwardNode, () => (Bool, Bool)) = {
|
def apply(fOut: (Bool, UInt) => UInt, fIn: (Bool, UInt) => UInt)(x: TLAsyncOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): (TLAsyncOutwardNode, () => (Bool, Bool)) = {
|
||||||
val iso = LazyModule(new TLIsolation(fOut, fIn))
|
val iso = LazyModule(new TLIsolation(fOut, fIn))
|
||||||
iso.node := x
|
iso.node :=? x
|
||||||
(iso.node, () => (iso.module.io.iso_out, iso.module.io.iso_in))
|
(iso.node, () => (iso.module.io.iso_out, iso.module.io.iso_in))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ object TLMap
|
|||||||
// applied to the TL source node; y.node := TLMap(fn)(x.node)
|
// applied to the TL source node; y.node := TLMap(fn)(x.node)
|
||||||
def apply(fn: AddressSet => BigInt)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
def apply(fn: AddressSet => BigInt)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
||||||
val map = LazyModule(new TLMap(fn))
|
val map = LazyModule(new TLMap(fn))
|
||||||
map.node := x
|
map.node :=? x
|
||||||
map.node
|
map.node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ object TLNodeNumberer
|
|||||||
// applied to the TL source node; y.node := TLBuffer(x.node)
|
// applied to the TL source node; y.node := TLBuffer(x.node)
|
||||||
def apply(nodeAddressOffset: Option[Int] = None)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
def apply(nodeAddressOffset: Option[Int] = None)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
||||||
val numberer = LazyModule(new TLNodeNumberer(nodeAddressOffset))
|
val numberer = LazyModule(new TLNodeNumberer(nodeAddressOffset))
|
||||||
numberer.node := x
|
numberer.node :=? x
|
||||||
numberer.node
|
numberer.node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,8 @@ import freechips.rocketchip.diplomacy._
|
|||||||
import freechips.rocketchip.util.RationalDirection
|
import freechips.rocketchip.util.RationalDirection
|
||||||
import scala.collection.mutable.ListBuffer
|
import scala.collection.mutable.ListBuffer
|
||||||
|
|
||||||
case object TLMonitorBuilder extends Field[TLMonitorArgs => Option[TLMonitorBase]]
|
case object TLMonitorBuilder extends Field[TLMonitorArgs => TLMonitorBase](args => LazyModule(new TLMonitor(args)))
|
||||||
case object TLCombinationalCheck extends Field[Boolean]
|
case object TLCombinationalCheck extends Field[Boolean](false)
|
||||||
|
|
||||||
object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TLEdgeOut, TLEdgeIn, TLBundle]
|
object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TLEdgeOut, TLEdgeIn, TLBundle]
|
||||||
{
|
{
|
||||||
@ -26,7 +26,7 @@ object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TL
|
|||||||
|
|
||||||
override def connect(edges: () => Seq[TLEdgeIn], bundles: () => Seq[(TLBundle, TLBundle)], enableMonitoring: Boolean)
|
override def connect(edges: () => Seq[TLEdgeIn], bundles: () => Seq[(TLBundle, TLBundle)], enableMonitoring: Boolean)
|
||||||
(implicit p: Parameters, sourceInfo: SourceInfo): (Option[TLMonitorBase], () => Unit) = {
|
(implicit p: Parameters, sourceInfo: SourceInfo): (Option[TLMonitorBase], () => Unit) = {
|
||||||
val monitor = if (enableMonitoring) p(TLMonitorBuilder)(TLMonitorArgs(edges, sourceInfo, p)) else None
|
val monitor = if (enableMonitoring) Some(p(TLMonitorBuilder)(TLMonitorArgs(edges, sourceInfo, p))) else None
|
||||||
(monitor, () => {
|
(monitor, () => {
|
||||||
val eval = bundles ()
|
val eval = bundles ()
|
||||||
monitor.foreach { m => (eval zip m.module.io.in) foreach { case ((i,o), m) => m := TLBundleSnoop(o,i) } }
|
monitor.foreach { m => (eval zip m.module.io.in) foreach { case ((i,o), m) => m := TLBundleSnoop(o,i) } }
|
||||||
|
@ -92,7 +92,7 @@ object TLRationalCrossingSource
|
|||||||
// applied to the TL source node; y.node := TLRationalCrossingSource()(x.node)
|
// applied to the TL source node; y.node := TLRationalCrossingSource()(x.node)
|
||||||
def apply()(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLRationalOutwardNode = {
|
def apply()(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLRationalOutwardNode = {
|
||||||
val source = LazyModule(new TLRationalCrossingSource)
|
val source = LazyModule(new TLRationalCrossingSource)
|
||||||
source.node := x
|
source.node :=? x
|
||||||
source.node
|
source.node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,7 +102,7 @@ object TLRationalCrossingSink
|
|||||||
// applied to the TL source node; y.node := TLRationalCrossingSink()(x.node)
|
// applied to the TL source node; y.node := TLRationalCrossingSink()(x.node)
|
||||||
def apply(direction: RationalDirection = Symmetric)(x: TLRationalOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
def apply(direction: RationalDirection = Symmetric)(x: TLRationalOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
||||||
val sink = LazyModule(new TLRationalCrossingSink(direction))
|
val sink = LazyModule(new TLRationalCrossingSink(direction))
|
||||||
sink.node := x
|
sink.node :=? x
|
||||||
sink.node
|
sink.node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ object TLSourceShrinker
|
|||||||
// applied to the TL source node; y.node := TLSourceShrinker(n)(x.node)
|
// applied to the TL source node; y.node := TLSourceShrinker(n)(x.node)
|
||||||
def apply(maxInFlight: Int)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
def apply(maxInFlight: Int)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
||||||
val shrinker = LazyModule(new TLSourceShrinker(maxInFlight))
|
val shrinker = LazyModule(new TLSourceShrinker(maxInFlight))
|
||||||
shrinker.node := x
|
shrinker.node :=? x
|
||||||
shrinker.node
|
shrinker.node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,7 +195,7 @@ object TLToAHB
|
|||||||
// applied to the TL source node; y.node := TLToAHB()(x.node)
|
// applied to the TL source node; y.node := TLToAHB()(x.node)
|
||||||
def apply(aFlow: Boolean = true)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): AHBOutwardNode = {
|
def apply(aFlow: Boolean = true)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): AHBOutwardNode = {
|
||||||
val ahb = LazyModule(new TLToAHB(aFlow))
|
val ahb = LazyModule(new TLToAHB(aFlow))
|
||||||
ahb.node := x
|
ahb.node :=? x
|
||||||
ahb.node
|
ahb.node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ object TLToAPB
|
|||||||
// applied to the TL source node; y.node := TLToAPB()(x.node)
|
// applied to the TL source node; y.node := TLToAPB()(x.node)
|
||||||
def apply(aFlow: Boolean = true)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): APBOutwardNode = {
|
def apply(aFlow: Boolean = true)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): APBOutwardNode = {
|
||||||
val apb = LazyModule(new TLToAPB(aFlow))
|
val apb = LazyModule(new TLToAPB(aFlow))
|
||||||
apb.node := x
|
apb.node :=? x
|
||||||
apb.node
|
apb.node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -223,7 +223,7 @@ object TLToAXI4
|
|||||||
// applied to the TL source node; y.node := TLToAXI4(beatBytes)(x.node)
|
// applied to the TL source node; y.node := TLToAXI4(beatBytes)(x.node)
|
||||||
def apply(beatBytes: Int, combinational: Boolean = true, adapterName: Option[String] = None, stripBits: Int = 0)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): AXI4OutwardNode = {
|
def apply(beatBytes: Int, combinational: Boolean = true, adapterName: Option[String] = None, stripBits: Int = 0)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): AXI4OutwardNode = {
|
||||||
val axi4 = LazyModule(new TLToAXI4(beatBytes, combinational, adapterName, stripBits))
|
val axi4 = LazyModule(new TLToAXI4(beatBytes, combinational, adapterName, stripBits))
|
||||||
axi4.node := x
|
axi4.node :=? x
|
||||||
axi4.node
|
axi4.node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,7 +200,7 @@ object TLWidthWidget
|
|||||||
// applied to the TL source node; y.node := WidthWidget(x.node, 16)
|
// applied to the TL source node; y.node := WidthWidget(x.node, 16)
|
||||||
def apply(innerBeatBytes: Int)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
def apply(innerBeatBytes: Int)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
||||||
val widget = LazyModule(new TLWidthWidget(innerBeatBytes))
|
val widget = LazyModule(new TLWidthWidget(innerBeatBytes))
|
||||||
widget.node := x
|
widget.node :=? x
|
||||||
widget.node
|
widget.node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,31 @@
|
|||||||
package freechips.rocketchip.tilelink
|
package freechips.rocketchip.tilelink
|
||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import freechips.rocketchip.config.Parameters
|
import freechips.rocketchip.config._
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
|
|
||||||
|
// Trades off slave port proximity against routing resource cost
|
||||||
|
object ForceFanout
|
||||||
|
{
|
||||||
|
def apply[T](
|
||||||
|
a: TriStateValue = TriStateValue.unset,
|
||||||
|
b: TriStateValue = TriStateValue.unset,
|
||||||
|
c: TriStateValue = TriStateValue.unset,
|
||||||
|
d: TriStateValue = TriStateValue.unset,
|
||||||
|
e: TriStateValue = TriStateValue.unset)(body: Parameters => T)(implicit p: Parameters) =
|
||||||
|
{
|
||||||
|
body(p.alterPartial {
|
||||||
|
case ForceFanoutKey => p(ForceFanoutKey) match {
|
||||||
|
case ForceFanoutParams(pa, pb, pc, pd, pe) =>
|
||||||
|
ForceFanoutParams(a.update(pa), b.update(pb), c.update(pc), d.update(pd), e.update(pe))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private case class ForceFanoutParams(a: Boolean, b: Boolean, c: Boolean, d: Boolean, e: Boolean)
|
||||||
|
private case object ForceFanoutKey extends Field(ForceFanoutParams(false, false, false, false, false))
|
||||||
|
|
||||||
class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parameters) extends LazyModule
|
class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parameters) extends LazyModule
|
||||||
{
|
{
|
||||||
val node = TLNexusNode(
|
val node = TLNexusNode(
|
||||||
@ -157,11 +179,11 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parame
|
|||||||
def filter[T](data: Seq[T], mask: Seq[Boolean]) = (data zip mask).filter(_._2).map(_._1)
|
def filter[T](data: Seq[T], mask: Seq[Boolean]) = (data zip mask).filter(_._2).map(_._1)
|
||||||
|
|
||||||
// Fanout the input sources to the output sinks
|
// Fanout the input sources to the output sinks
|
||||||
val portsAOI = transpose((in zip requestAIO) map { case (i, r) => TLXbar.fanout(i.a, r) })
|
val portsAOI = transpose((in zip requestAIO) map { case (i, r) => TLXbar.fanout(i.a, r, node.paramsOut.map(_(ForceFanoutKey).a)) })
|
||||||
val portsBIO = transpose((out zip requestBOI) map { case (o, r) => TLXbar.fanout(o.b, r) })
|
val portsBIO = transpose((out zip requestBOI) map { case (o, r) => TLXbar.fanout(o.b, r, node.paramsIn .map(_(ForceFanoutKey).b)) })
|
||||||
val portsCOI = transpose((in zip requestCIO) map { case (i, r) => TLXbar.fanout(i.c, r) })
|
val portsCOI = transpose((in zip requestCIO) map { case (i, r) => TLXbar.fanout(i.c, r, node.paramsOut.map(_(ForceFanoutKey).c)) })
|
||||||
val portsDIO = transpose((out zip requestDOI) map { case (o, r) => TLXbar.fanout(o.d, r) })
|
val portsDIO = transpose((out zip requestDOI) map { case (o, r) => TLXbar.fanout(o.d, r, node.paramsIn .map(_(ForceFanoutKey).d)) })
|
||||||
val portsEOI = transpose((in zip requestEIO) map { case (i, r) => TLXbar.fanout(i.e, r) })
|
val portsEOI = transpose((in zip requestEIO) map { case (i, r) => TLXbar.fanout(i.e, r, node.paramsOut.map(_(ForceFanoutKey).e)) })
|
||||||
|
|
||||||
// Arbitrate amongst the sources
|
// Arbitrate amongst the sources
|
||||||
for (o <- 0 until out.size) {
|
for (o <- 0 until out.size) {
|
||||||
@ -216,10 +238,10 @@ object TLXbar
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Replicate an input port to each output port
|
// Replicate an input port to each output port
|
||||||
def fanout[T <: TLChannel](input: DecoupledIO[T], select: Seq[Bool]) = {
|
def fanout[T <: TLChannel](input: DecoupledIO[T], select: Seq[Bool], force: Seq[Boolean] = Nil) = {
|
||||||
val filtered = Wire(Vec(select.size, input))
|
val filtered = Wire(Vec(select.size, input))
|
||||||
for (i <- 0 until select.size) {
|
for (i <- 0 until select.size) {
|
||||||
filtered(i).bits := input.bits
|
filtered(i).bits := (if (force.lift(i).getOrElse(false)) IdentityModule(input.bits) else input.bits)
|
||||||
filtered(i).valid := input.valid && select(i)
|
filtered(i).valid := input.valid && select(i)
|
||||||
}
|
}
|
||||||
input.ready := Mux1H(select, filtered.map(_.ready))
|
input.ready := Mux1H(select, filtered.map(_.ready))
|
||||||
|
24
src/main/scala/util/IdentityModule.scala
Normal file
24
src/main/scala/util/IdentityModule.scala
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// See LICENSE.SiFive for license details.
|
||||||
|
|
||||||
|
package freechips.rocketchip.tilelink
|
||||||
|
|
||||||
|
import Chisel._
|
||||||
|
|
||||||
|
class IdentityModule[T <: Data](gen: T) extends Module
|
||||||
|
{
|
||||||
|
val io = new Bundle {
|
||||||
|
val in = gen.cloneType.flip
|
||||||
|
val out = gen.cloneType
|
||||||
|
}
|
||||||
|
|
||||||
|
io.out := io.in
|
||||||
|
}
|
||||||
|
|
||||||
|
object IdentityModule
|
||||||
|
{
|
||||||
|
def apply[T <: Data](x: T): T = {
|
||||||
|
val identity = Module(new IdentityModule(x))
|
||||||
|
identity.io.in := x
|
||||||
|
identity.io.out
|
||||||
|
}
|
||||||
|
}
|
@ -73,10 +73,10 @@ class RationalCrossingSource[T <: Data](gen: T, direction: RationalDirection = S
|
|||||||
|
|
||||||
val deq = io.deq
|
val deq = io.deq
|
||||||
val enq = direction match {
|
val enq = direction match {
|
||||||
case Symmetric => Queue(io.enq, 1, flow=true)
|
case Symmetric => ShiftQueue(io.enq, 1, flow=true)
|
||||||
case Flexible => Queue(io.enq, 2)
|
case Flexible => ShiftQueue(io.enq, 2)
|
||||||
case FastToSlow => io.enq
|
case FastToSlow => io.enq
|
||||||
case SlowToFast => Queue(io.enq, 2)
|
case SlowToFast => ShiftQueue(io.enq, 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
val count = RegInit(UInt(0, width = 2))
|
val count = RegInit(UInt(0, width = 2))
|
||||||
@ -109,9 +109,9 @@ class RationalCrossingSink[T <: Data](gen: T, direction: RationalDirection = Sym
|
|||||||
val enq = io.enq
|
val enq = io.enq
|
||||||
val deq = Wire(io.deq)
|
val deq = Wire(io.deq)
|
||||||
direction match {
|
direction match {
|
||||||
case Symmetric => io.deq <> Queue(deq, 1, pipe=true)
|
case Symmetric => io.deq <> ShiftQueue(deq, 1, pipe=true)
|
||||||
case Flexible => io.deq <> Queue(deq, 2)
|
case Flexible => io.deq <> ShiftQueue(deq, 2)
|
||||||
case FastToSlow => io.deq <> Queue(deq, 2)
|
case FastToSlow => io.deq <> ShiftQueue(deq, 2)
|
||||||
case SlowToFast => io.deq <> deq
|
case SlowToFast => io.deq <> deq
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ class ShiftQueue[T <: Data](gen: T,
|
|||||||
val wdata = if (i == entries-1) io.enq.bits else Mux(valid(i+1), elts(i+1), io.enq.bits)
|
val wdata = if (i == entries-1) io.enq.bits else Mux(valid(i+1), elts(i+1), io.enq.bits)
|
||||||
val wen =
|
val wen =
|
||||||
Mux(io.deq.ready,
|
Mux(io.deq.ready,
|
||||||
paddedValid(i+1) || io.enq.fire() && valid(i),
|
paddedValid(i+1) || io.enq.fire() && (Bool(i == 0 && !flow) || valid(i)),
|
||||||
io.enq.fire() && paddedValid(i-1) && !valid(i))
|
io.enq.fire() && paddedValid(i-1) && !valid(i))
|
||||||
when (wen) { elts(i) := wdata }
|
when (wen) { elts(i) := wdata }
|
||||||
|
|
||||||
@ -52,3 +52,12 @@ class ShiftQueue[T <: Data](gen: T,
|
|||||||
io.mask := valid.asUInt
|
io.mask := valid.asUInt
|
||||||
io.count := PopCount(io.mask)
|
io.count := PopCount(io.mask)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object ShiftQueue
|
||||||
|
{
|
||||||
|
def apply[T <: Data](enq: DecoupledIO[T], entries: Int = 2, pipe: Boolean = false, flow: Boolean = false): DecoupledIO[T] = {
|
||||||
|
val q = Module(new ShiftQueue(enq.bits.cloneType, entries, pipe, flow))
|
||||||
|
q.io.enq <> enq
|
||||||
|
q.io.deq
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user