1
0

Merge pull request #1094 from freechipsproject/in-situ-unit-tests

In situ unit tests
This commit is contained in:
Wesley W. Terpstra 2017-12-01 13:27:30 -08:00 committed by GitHub
commit 4bac8be483
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
68 changed files with 690 additions and 323 deletions

View File

@ -15,7 +15,7 @@ object ValNameImpl
def allOwners(s: c.Symbol): Seq[c.Symbol] = def allOwners(s: c.Symbol): Seq[c.Symbol] =
if (s == `NoSymbol`) Nil else s +: allOwners(s.owner) if (s == `NoSymbol`) Nil else s +: allOwners(s.owner)
val terms = allOwners(c.internal.enclosingOwner).filter(_.isTerm).map(_.asTerm) val terms = allOwners(c.internal.enclosingOwner).filter(_.isTerm).map(_.asTerm)
terms.filter(_.isVal).map(_.name.toString).find(_(0) != '$').map { s => terms.filter(t => t.isVal || t.isLazy).map(_.name.toString).find(_(0) != '$').map { s =>
val trim = s.replaceAll("\\s", "") val trim = s.replaceAll("\\s", "")
c.Expr[ValNameImpl] { q"_root_.freechips.rocketchip.macros.ValNameImpl(${trim})" } c.Expr[ValNameImpl] { q"_root_.freechips.rocketchip.macros.ValNameImpl(${trim})" }
}.getOrElse(c.abort(c.enclosingPosition, "Not a valid application.")) }.getOrElse(c.abort(c.enclosingPosition, "Not a valid application."))

View File

@ -24,10 +24,8 @@ case class AHBMasterNode(portParams: Seq[AHBMasterPortParameters])(implicit valN
case class AHBSlaveNode(portParams: Seq[AHBSlavePortParameters])(implicit valName: ValName) extends SinkNode(AHBImp)(portParams) case class AHBSlaveNode(portParams: Seq[AHBSlavePortParameters])(implicit valName: ValName) extends SinkNode(AHBImp)(portParams)
case class AHBNexusNode( case class AHBNexusNode(
masterFn: Seq[AHBMasterPortParameters] => AHBMasterPortParameters, masterFn: Seq[AHBMasterPortParameters] => AHBMasterPortParameters,
slaveFn: Seq[AHBSlavePortParameters] => AHBSlavePortParameters, slaveFn: Seq[AHBSlavePortParameters] => AHBSlavePortParameters)(
numMasterPorts: Range.Inclusive = 1 to 999,
numSlavePorts: Range.Inclusive = 1 to 999)(
implicit valName: ValName) implicit valName: ValName)
extends NexusNode(AHBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts) extends NexusNode(AHBImp)(masterFn, slaveFn)
case class AHBIdentityNode()(implicit valName: ValName) extends IdentityNode(AHBImp)() case class AHBIdentityNode()(implicit valName: ValName) extends IdentityNode(AHBImp)()

View File

@ -138,5 +138,9 @@ class AHBToTL()(implicit p: Parameters) extends LazyModule
object AHBToTL object AHBToTL
{ {
def apply()(implicit p: Parameters) = LazyModule(new AHBToTL).node def apply()(implicit p: Parameters) =
{
val ahb2tl = LazyModule(new AHBToTL)
ahb2tl.node
}
} }

View File

@ -10,12 +10,14 @@ import scala.math.{min,max}
class AHBFanout()(implicit p: Parameters) extends LazyModule { class AHBFanout()(implicit p: Parameters) extends LazyModule {
val node = AHBNexusNode( val node = AHBNexusNode(
numSlavePorts = 1 to 1,
numMasterPorts = 1 to 32,
masterFn = { case Seq(m) => m }, masterFn = { case Seq(m) => m },
slaveFn = { seq => seq(0).copy(slaves = seq.flatMap(_.slaves)) }) slaveFn = { seq => seq(0).copy(slaves = seq.flatMap(_.slaves)) })
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
if (node.edges.in.size >= 1) {
require (node.edges.in.size == 1, "AHBFanout does not support multiple masters")
require (node.edges.out.size > 0, "AHBFanout requires at least one slave")
// Require consistent bus widths // Require consistent bus widths
val (io_out, edgesOut) = node.out.unzip val (io_out, edgesOut) = node.out.unzip
val port0 = edgesOut(0).slave val port0 = edgesOut(0).slave
@ -43,4 +45,5 @@ class AHBFanout()(implicit p: Parameters) extends LazyModule {
in.hresp := Mux1H(d_sel, io_out.map(_.hresp)) in.hresp := Mux1H(d_sel, io_out.map(_.hresp))
in.hrdata := Mux1H(d_sel, io_out.map(_.hrdata)) in.hrdata := Mux1H(d_sel, io_out.map(_.hrdata))
} }
}
} }

View File

@ -7,7 +7,7 @@ import freechips.rocketchip.diplomacy._
package object ahb package object ahb
{ {
type AHBOutwardNode = OutwardNodeHandle[AHBMasterPortParameters, AHBSlavePortParameters, AHBBundle] type AHBOutwardNode = OutwardNodeHandle[AHBMasterPortParameters, AHBSlavePortParameters, AHBEdgeParameters, AHBBundle]
type AHBInwardNode = InwardNodeHandle[AHBMasterPortParameters, AHBSlavePortParameters, AHBBundle] type AHBInwardNode = InwardNodeHandle[AHBMasterPortParameters, AHBSlavePortParameters, AHBEdgeParameters, AHBBundle]
type AHBNode = SimpleNodeHandle[AHBMasterPortParameters, AHBSlavePortParameters, AHBBundle] type AHBNode = SimpleNodeHandle[AHBMasterPortParameters, AHBSlavePortParameters, AHBEdgeParameters, AHBBundle]
} }

View File

@ -23,10 +23,8 @@ case class APBMasterNode(portParams: Seq[APBMasterPortParameters])(implicit valN
case class APBSlaveNode(portParams: Seq[APBSlavePortParameters])(implicit valName: ValName) extends SinkNode(APBImp)(portParams) case class APBSlaveNode(portParams: Seq[APBSlavePortParameters])(implicit valName: ValName) extends SinkNode(APBImp)(portParams)
case class APBNexusNode( case class APBNexusNode(
masterFn: Seq[APBMasterPortParameters] => APBMasterPortParameters, masterFn: Seq[APBMasterPortParameters] => APBMasterPortParameters,
slaveFn: Seq[APBSlavePortParameters] => APBSlavePortParameters, slaveFn: Seq[APBSlavePortParameters] => APBSlavePortParameters)(
numMasterPorts: Range.Inclusive = 1 to 1,
numSlavePorts: Range.Inclusive = 1 to 1)(
implicit valName: ValName) implicit valName: ValName)
extends NexusNode(APBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts) extends NexusNode(APBImp)(masterFn, slaveFn)
case class APBIdentityNode()(implicit valName: ValName) extends IdentityNode(APBImp)() case class APBIdentityNode()(implicit valName: ValName) extends IdentityNode(APBImp)()

View File

@ -10,12 +10,14 @@ import scala.math.{min,max}
class APBFanout()(implicit p: Parameters) extends LazyModule { class APBFanout()(implicit p: Parameters) extends LazyModule {
val node = APBNexusNode( val node = APBNexusNode(
numSlavePorts = 1 to 1,
numMasterPorts = 1 to 32,
masterFn = { case Seq(m) => m }, masterFn = { case Seq(m) => m },
slaveFn = { seq => seq(0).copy(slaves = seq.flatMap(_.slaves)) }) slaveFn = { seq => seq(0).copy(slaves = seq.flatMap(_.slaves)) })
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
if (node.edges.in.size >= 1) {
require (node.edges.in.size == 1, "APBFanout does not support multiple masters")
require (node.edges.out.size > 0, "APBFanout requires at least one slave")
val (in, _) = node.in(0) val (in, _) = node.in(0)
// Require consistent bus widths // Require consistent bus widths
@ -42,4 +44,5 @@ class APBFanout()(implicit p: Parameters) extends LazyModule {
in.pslverr := Mux1H(sel, io_out.map(_.pslverr)) in.pslverr := Mux1H(sel, io_out.map(_.pslverr))
in.prdata := Mux1H(sel, io_out.map(_.prdata)) in.prdata := Mux1H(sel, io_out.map(_.prdata))
} }
}
} }

View File

@ -7,7 +7,7 @@ import freechips.rocketchip.diplomacy._
package object apb package object apb
{ {
type APBOutwardNode = OutwardNodeHandle[APBMasterPortParameters, APBSlavePortParameters, APBBundle] type APBOutwardNode = OutwardNodeHandle[APBMasterPortParameters, APBSlavePortParameters, APBEdgeParameters, APBBundle]
type APBInwardNode = InwardNodeHandle[APBMasterPortParameters, APBSlavePortParameters, APBBundle] type APBInwardNode = InwardNodeHandle[APBMasterPortParameters, APBSlavePortParameters, APBEdgeParameters, APBBundle]
type APBNode = SimpleNodeHandle[APBMasterPortParameters, APBSlavePortParameters, APBBundle] type APBNode = SimpleNodeHandle[APBMasterPortParameters, APBSlavePortParameters, APBEdgeParameters, APBBundle]
} }

View File

@ -43,12 +43,18 @@ class AXI4AsyncCrossingSink(depth: Int = 8, sync: Int = 3)(implicit p: Parameter
object AXI4AsyncCrossingSource object AXI4AsyncCrossingSource
{ {
def apply(sync: Int = 3)(implicit p: Parameters) = LazyModule(new AXI4AsyncCrossingSource(sync)).node def apply(sync: Int = 3)(implicit p: Parameters) = {
val axi4asource = LazyModule(new AXI4AsyncCrossingSource(sync))
axi4asource.node
}
} }
object AXI4AsyncCrossingSink object AXI4AsyncCrossingSink
{ {
def apply(depth: Int = 8, sync: Int = 3)(implicit p: Parameters) = LazyModule(new AXI4AsyncCrossingSink(depth, sync)).node def apply(depth: Int = 8, sync: Int = 3)(implicit p: Parameters) = {
val axi4asink = LazyModule(new AXI4AsyncCrossingSink(depth, sync))
axi4asink.node
}
} }
@deprecated("AXI4AsyncCrossing is fragile. Use AXI4AsyncCrossingSource and AXI4AsyncCrossingSink", "rocket-chip 1.2") @deprecated("AXI4AsyncCrossing is fragile. Use AXI4AsyncCrossingSource and AXI4AsyncCrossingSink", "rocket-chip 1.2")
@ -99,5 +105,6 @@ class AXI4RAMAsyncCrossing(txns: Int)(implicit p: Parameters) extends LazyModule
} }
class AXI4RAMAsyncCrossingTest(txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) { class AXI4RAMAsyncCrossingTest(txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) {
io.finished := Module(LazyModule(new AXI4RAMAsyncCrossing(txns)).module).io.finished val dut = Module(LazyModule(new AXI4RAMAsyncCrossing(txns)).module)
io.finished := dut.io.finished
} }

View File

@ -53,5 +53,9 @@ object AXI4Buffer
w: BufferParams, w: BufferParams,
b: BufferParams, b: BufferParams,
ar: BufferParams, ar: BufferParams,
r: BufferParams)(implicit p: Parameters): AXI4Node = LazyModule(new AXI4Buffer(aw, w, b, ar, r)).node r: BufferParams)(implicit p: Parameters): AXI4Node =
{
val axi4buf = LazyModule(new AXI4Buffer(aw, w, b, ar, r))
axi4buf.node
}
} }

View File

@ -99,5 +99,9 @@ class AXI4Deinterleaver(maxReadBytes: Int)(implicit p: Parameters) extends LazyM
object AXI4Deinterleaver object AXI4Deinterleaver
{ {
def apply(maxReadBytes: Int)(implicit p: Parameters): AXI4Node = LazyModule(new AXI4Deinterleaver(maxReadBytes)).node def apply(maxReadBytes: Int)(implicit p: Parameters): AXI4Node =
{
val axi4deint = LazyModule(new AXI4Deinterleaver(maxReadBytes))
axi4deint.node
}
} }

View File

@ -79,5 +79,9 @@ class AXI4Delayer(q: Double)(implicit p: Parameters) extends LazyModule
object AXI4Delayer object AXI4Delayer
{ {
def apply(q: Double)(implicit p: Parameters): AXI4Node = LazyModule(new AXI4Delayer(q)).node def apply(q: Double)(implicit p: Parameters): AXI4Node =
{
val axi4delay = LazyModule(new AXI4Delayer(q))
axi4delay.node
}
} }

View File

@ -58,5 +58,9 @@ object AXI4Filter
def apply( def apply(
Sfilter: AXI4SlaveParameters => Option[AXI4SlaveParameters] = AXI4Filter.Sidentity, Sfilter: AXI4SlaveParameters => Option[AXI4SlaveParameters] = AXI4Filter.Sidentity,
Mfilter: AXI4MasterParameters => Option[AXI4MasterParameters] = AXI4Filter.Midentity Mfilter: AXI4MasterParameters => Option[AXI4MasterParameters] = AXI4Filter.Midentity
)(implicit p: Parameters): AXI4Node = LazyModule(new AXI4Filter(Sfilter, Mfilter)).node )(implicit p: Parameters): AXI4Node =
{
val axi4filt = LazyModule(new AXI4Filter(Sfilter, Mfilter))
axi4filt.node
}
} }

View File

@ -199,5 +199,9 @@ class AXI4Fragmenter()(implicit p: Parameters) extends LazyModule
object AXI4Fragmenter object AXI4Fragmenter
{ {
def apply()(implicit p: Parameters): AXI4Node = LazyModule(new AXI4Fragmenter).node def apply()(implicit p: Parameters): AXI4Node =
{
val axi4frag = LazyModule(new AXI4Fragmenter)
axi4frag.node
}
} }

View File

@ -75,5 +75,9 @@ class AXI4IdIndexer(idBits: Int)(implicit p: Parameters) extends LazyModule
object AXI4IdIndexer object AXI4IdIndexer
{ {
def apply(idBits: Int)(implicit p: Parameters): AXI4Node = LazyModule(new AXI4IdIndexer(idBits)).node def apply(idBits: Int)(implicit p: Parameters): AXI4Node =
{
val axi4index = LazyModule(new AXI4IdIndexer(idBits))
axi4index.node
}
} }

View File

@ -23,17 +23,14 @@ case class AXI4MasterNode(portParams: Seq[AXI4MasterPortParameters])(implicit va
case class AXI4SlaveNode(portParams: Seq[AXI4SlavePortParameters])(implicit valName: ValName) extends SinkNode(AXI4Imp)(portParams) case class AXI4SlaveNode(portParams: Seq[AXI4SlavePortParameters])(implicit valName: ValName) extends SinkNode(AXI4Imp)(portParams)
case class AXI4NexusNode( case class AXI4NexusNode(
masterFn: Seq[AXI4MasterPortParameters] => AXI4MasterPortParameters, masterFn: Seq[AXI4MasterPortParameters] => AXI4MasterPortParameters,
slaveFn: Seq[AXI4SlavePortParameters] => AXI4SlavePortParameters, slaveFn: Seq[AXI4SlavePortParameters] => AXI4SlavePortParameters)(
numMasterPorts: Range.Inclusive = 1 to 999,
numSlavePorts: Range.Inclusive = 1 to 999)(
implicit valName: ValName) implicit valName: ValName)
extends NexusNode(AXI4Imp)(masterFn, slaveFn, numMasterPorts, numSlavePorts) extends NexusNode(AXI4Imp)(masterFn, slaveFn)
case class AXI4AdapterNode( case class AXI4AdapterNode(
masterFn: AXI4MasterPortParameters => AXI4MasterPortParameters = { m => m }, masterFn: AXI4MasterPortParameters => AXI4MasterPortParameters = { m => m },
slaveFn: AXI4SlavePortParameters => AXI4SlavePortParameters = { s => s }, slaveFn: AXI4SlavePortParameters => AXI4SlavePortParameters = { s => s })(
numPorts: Range.Inclusive = 0 to 999)(
implicit valName: ValName) implicit valName: ValName)
extends AdapterNode(AXI4Imp)(masterFn, slaveFn, numPorts) extends AdapterNode(AXI4Imp)(masterFn, slaveFn)
case class AXI4IdentityNode()(implicit valName: ValName) extends IdentityNode(AXI4Imp)() case class AXI4IdentityNode()(implicit valName: ValName) extends IdentityNode(AXI4Imp)()
object AXI4AsyncImp extends SimpleNodeImp[AXI4AsyncMasterPortParameters, AXI4AsyncSlavePortParameters, AXI4AsyncEdgeParameters, AXI4AsyncBundle] object AXI4AsyncImp extends SimpleNodeImp[AXI4AsyncMasterPortParameters, AXI4AsyncSlavePortParameters, AXI4AsyncEdgeParameters, AXI4AsyncBundle]

View File

@ -99,5 +99,9 @@ object AXI4RAM
beatBytes: Int = 4, beatBytes: Int = 4,
devName: Option[String] = None, devName: Option[String] = None,
errors: Seq[AddressSet] = Nil) errors: Seq[AddressSet] = Nil)
(implicit p: Parameters) = LazyModule(new AXI4RAM(address, executable, beatBytes, devName, errors)).node (implicit p: Parameters) =
{
val axi4ram = LazyModule(new AXI4RAM(address, executable, beatBytes, devName, errors))
axi4ram.node
}
} }

View File

@ -160,5 +160,9 @@ class AXI4BundleRError(params: AXI4BundleParameters) extends AXI4BundleBase(para
object AXI4ToTL object AXI4ToTL
{ {
def apply()(implicit p: Parameters) = LazyModule(new AXI4ToTL).node def apply()(implicit p: Parameters) =
{
val axi42tl = LazyModule(new AXI4ToTL)
axi42tl.node
}
} }

View File

@ -91,5 +91,9 @@ class AXI4UserYanker(capMaxFlight: Option[Int] = None)(implicit p: Parameters) e
object AXI4UserYanker object AXI4UserYanker
{ {
def apply(capMaxFlight: Option[Int] = None)(implicit p: Parameters): AXI4Node = LazyModule(new AXI4UserYanker(capMaxFlight)).node def apply(capMaxFlight: Option[Int] = None)(implicit p: Parameters): AXI4Node =
{
val axi4yank = LazyModule(new AXI4UserYanker(capMaxFlight))
axi4yank.node
}
} }

View File

@ -18,8 +18,6 @@ class AXI4Xbar(
require (awQueueDepth >= 1) require (awQueueDepth >= 1)
val node = AXI4NexusNode( val node = AXI4NexusNode(
numMasterPorts = 1 to 999,
numSlavePorts = 1 to 999,
masterFn = { seq => masterFn = { seq =>
seq(0).copy( seq(0).copy(
userBits = seq.map(_.userBits).max, userBits = seq.map(_.userBits).max,
@ -56,14 +54,14 @@ class AXI4Xbar(
val awIn = Seq.fill(io_in .size) { Module(new Queue(UInt(width = io_out.size), awQueueDepth, flow = true)) } val awIn = Seq.fill(io_in .size) { Module(new Queue(UInt(width = io_out.size), awQueueDepth, flow = true)) }
val awOut = Seq.fill(io_out.size) { Module(new Queue(UInt(width = io_in .size), awQueueDepth, flow = true)) } val awOut = Seq.fill(io_out.size) { Module(new Queue(UInt(width = io_in .size), awQueueDepth, flow = true)) }
val requestARIO = Vec(io_in.map { i => Vec(outputPorts.map { o => o(i.ar.bits.addr) }) }) val requestARIO = io_in.map { i => Vec(outputPorts.map { o => o(i.ar.bits.addr) }) }
val requestAWIO = Vec(io_in.map { i => Vec(outputPorts.map { o => o(i.aw.bits.addr) }) }) val requestAWIO = io_in.map { i => Vec(outputPorts.map { o => o(i.aw.bits.addr) }) }
val requestROI = Vec(io_out.map { o => Vec(inputIdRanges.map { i => i.contains(o.r.bits.id) }) }) val requestROI = io_out.map { o => inputIdRanges.map { i => i.contains(o.r.bits.id) } }
val requestBOI = Vec(io_out.map { o => Vec(inputIdRanges.map { i => i.contains(o.b.bits.id) }) }) val requestBOI = io_out.map { o => inputIdRanges.map { i => i.contains(o.b.bits.id) } }
// W follows the path dictated by the AW Q // W follows the path dictated by the AW Q
for (i <- 0 until io_in.size) { awIn(i).io.enq.bits := requestAWIO(i).asUInt } for (i <- 0 until io_in.size) { awIn(i).io.enq.bits := requestAWIO(i).asUInt }
val requestWIO = Vec(awIn.map { q => if (io_out.size > 1) Vec(q.io.deq.bits.toBools) else Vec.fill(1){Bool(true)} }) val requestWIO = awIn.map { q => if (io_out.size > 1) q.io.deq.bits.toBools else Seq(Bool(true)) }
// We need an intermediate size of bundle with the widest possible identifiers // We need an intermediate size of bundle with the widest possible identifiers
val wide_bundle = AXI4BundleParameters.union(io_in.map(_.params) ++ io_out.map(_.params)) val wide_bundle = AXI4BundleParameters.union(io_in.map(_.params) ++ io_out.map(_.params))
@ -207,7 +205,11 @@ object AXI4Xbar
def apply( def apply(
arbitrationPolicy: TLArbiter.Policy = TLArbiter.roundRobin, arbitrationPolicy: TLArbiter.Policy = TLArbiter.roundRobin,
maxFlightPerId: Int = 7, maxFlightPerId: Int = 7,
awQueueDepth: Int = 2)(implicit p: Parameters) = LazyModule(new AXI4Xbar(arbitrationPolicy, maxFlightPerId, awQueueDepth)).node awQueueDepth: Int = 2)(implicit p: Parameters) =
{
val axi4xbar = LazyModule(new AXI4Xbar(arbitrationPolicy, maxFlightPerId, awQueueDepth))
axi4xbar.node
}
def mapInputIds(ports: Seq[AXI4MasterPortParameters]) = TLXbar.assignRanges(ports.map(_.endId)).map(_.get) def mapInputIds(ports: Seq[AXI4MasterPortParameters]) = TLXbar.assignRanges(ports.map(_.endId)).map(_.get)

View File

@ -7,7 +7,7 @@ import freechips.rocketchip.diplomacy._
package object axi4 package object axi4
{ {
type AXI4Node = SimpleNodeHandle[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4Bundle] type AXI4Node = SimpleNodeHandle[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4EdgeParameters, AXI4Bundle]
type AXI4OutwardNode = OutwardNodeHandle[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4Bundle] type AXI4OutwardNode = OutwardNodeHandle[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4EdgeParameters, AXI4Bundle]
type AXI4InwardNode = InwardNodeHandle[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4Bundle] type AXI4InwardNode = InwardNodeHandle[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4EdgeParameters, AXI4Bundle]
} }

View File

@ -51,20 +51,20 @@ trait HasCrossingMethods extends LazyModule with LazyScope
} }
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 = {
def sourceGen = LazyModule(new TLAsyncCrossingSource(sync)) lazy val asource = LazyModule(new TLAsyncCrossingSource(sync))
def sinkGen = LazyModule(new TLAsyncCrossingSink(depth, sync)) lazy val asink = LazyModule(new TLAsyncCrossingSink(depth, sync))
val source = if (out) this { sourceGen } else sourceGen val source = if (out) this { asource } else asource
val sink = if (out) sinkGen else this { sinkGen } val sink = if (out) asink else this { asink }
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 = {
def sourceGen = LazyModule(new TLRationalCrossingSource) lazy val rsource = LazyModule(new TLRationalCrossingSource)
def sinkGen = LazyModule(new TLRationalCrossingSink(if (out) direction else direction.flip)) lazy val rsink = LazyModule(new TLRationalCrossingSink(if (out) direction else direction.flip))
val source = if (out) this { sourceGen } else sourceGen val source = if (out) this { rsource } else rsource
val sink = if (out) sinkGen else this { sinkGen } val sink = if (out) rsink else this { rsink }
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)
@ -98,10 +98,10 @@ trait HasCrossingMethods extends LazyModule with LazyScope
} }
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 = {
def sourceGen = LazyModule(new AXI4AsyncCrossingSource(sync)) lazy val axi4asource = LazyModule(new AXI4AsyncCrossingSource(sync))
def sinkGen = LazyModule(new AXI4AsyncCrossingSink(depth, sync)) lazy val axi4asink = LazyModule(new AXI4AsyncCrossingSink(depth, sync))
val source = if (out) this { sourceGen } else sourceGen val source = if (out) this { axi4asource } else axi4asource
val sink = if (out) sinkGen else this { sinkGen } val sink = if (out) axi4asink else this { axi4asink }
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)
@ -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 = {
def sourceGen = LazyModule(new IntSyncCrossingSource(alreadyRegistered)) lazy val intssource = LazyModule(new IntSyncCrossingSource(alreadyRegistered))
def sinkGen = LazyModule(new IntSyncCrossingSink(0)) lazy val intssink = LazyModule(new IntSyncCrossingSink(0))
val source = if (out) this { sourceGen } else sourceGen val source = if (out) this { intssource } else intssource
val sink = if (out) sinkGen else this { sinkGen } val sink = if (out) intssink else this { intssink }
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 = {
def sourceGen = LazyModule(new IntSyncCrossingSource(alreadyRegistered)) lazy val intasource = LazyModule(new IntSyncCrossingSource(alreadyRegistered))
def sinkGen = LazyModule(new IntSyncCrossingSink(sync)) lazy val intasink = LazyModule(new IntSyncCrossingSink(sync))
val source = if (out) this { sourceGen } else sourceGen val source = if (out) this { intasource } else intasource
val sink = if (out) sinkGen else this { sinkGen } val sink = if (out) intasink else this { intasink }
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 = {
def sourceGen = LazyModule(new IntSyncCrossingSource(alreadyRegistered)) lazy val intrsource = LazyModule(new IntSyncCrossingSource(alreadyRegistered))
def sinkGen = LazyModule(new IntSyncCrossingSink(1)) lazy val intrsink = LazyModule(new IntSyncCrossingSink(1))
val source = if (out) this { sourceGen } else sourceGen val source = if (out) this { intrsource } else intrsource
val sink = if (out) sinkGen else this { sinkGen } val sink = if (out) intrsink else this { intrsink }
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)

View File

@ -38,7 +38,7 @@ class FrontBus(params: FrontBusParams)(implicit p: Parameters) extends TLBusWrap
def fromCoherentChip: TLInwardNode = inwardNode def fromCoherentChip: TLInwardNode = inwardNode
def toSystemBus : TLOutwardNode = outwardBufNode def toSystemBus : TLOutwardNode = TLBuffer(params.slaveBuffering) :=* xbar.node
} }
@ -51,5 +51,5 @@ trait HasFrontBus extends HasSystemBus {
val fbus = LazyModule(new FrontBus(frontbusParams)) val fbus = LazyModule(new FrontBus(frontbusParams))
FlipRendering { implicit p => sbus.fromFrontBus := fbus.toSystemBus } FlipRendering { implicit p => sbus.fromFrontBus :=* fbus.toSystemBus }
} }

View File

@ -33,7 +33,7 @@ class PeripheryBus(params: PeripheryBusParams)(implicit p: Parameters) extends T
val fromSystemBus: TLInwardNode = { val fromSystemBus: TLInwardNode = {
val atomics = LazyModule(new TLAtomicAutomata(arithmetic = params.arithmetic)) val atomics = LazyModule(new TLAtomicAutomata(arithmetic = params.arithmetic))
inwardBufNode := atomics.node xbar.node :*= TLBuffer(params.masterBuffering) :*= atomics.node
} }
def toTile(name: Option[String] = None)(gen: Parameters => TLInwardNode) { def toTile(name: Option[String] = None)(gen: Parameters => TLInwardNode) {
@ -59,5 +59,5 @@ trait HasPeripheryBus extends HasSystemBus {
val pbus = LazyModule(new PeripheryBus(pbusParams)) val pbus = LazyModule(new PeripheryBus(pbusParams))
// The peripheryBus hangs off of systemBus; here we convert TL-UH -> TL-UL // The peripheryBus hangs off of systemBus; here we convert TL-UH -> TL-UL
pbus.fromSystemBus := sbus.toPeripheryBus() pbus.fromSystemBus :*= sbus.toPeripheryBus()
} }

View File

@ -39,7 +39,7 @@ class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWr
def toSplitSlaves: TLOutwardNode = outwardSplitNode def toSplitSlaves: TLOutwardNode = outwardSplitNode
def toPeripheryBus(addBuffers: Int = 0): TLOutwardNode = { def toPeripheryBus(addBuffers: Int = 0): TLOutwardNode = {
TLBuffer.chain(addBuffers).foldRight(pbus_fixer.node:TLOutwardNode)(_ := _) TLBuffer.chain(addBuffers).foldRight(pbus_fixer.node:TLOutwardNode)(_ :*= _)
} }
val toMemoryBus: TLOutwardNode = outwardNode val toMemoryBus: TLOutwardNode = outwardNode

View File

@ -279,11 +279,9 @@ class TLDebugModuleOuter(device: Device)(implicit p: Parameters) extends LazyMod
import DMI_RegAddrs._ import DMI_RegAddrs._
val intnode = IntNexusNode( val intnode = IntNexusNode(
numSourcePorts = 1 to 1024,
numSinkPorts = 0 to 0,
sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(1, Seq(Resource(device, "int"))))) }, sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(1, Seq(Resource(device, "int"))))) },
sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) } sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) },
) outputRequiresInput = false)
val dmiNode = TLRegisterNode ( val dmiNode = TLRegisterNode (
address = AddressSet.misaligned(DMI_DMCONTROL << 2, 4), address = AddressSet.misaligned(DMI_DMCONTROL << 2, 4),
@ -293,6 +291,7 @@ class TLDebugModuleOuter(device: Device)(implicit p: Parameters) extends LazyMod
) )
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
require (intnode.edges.in.size == 0, "Debug Module does not accept interrupts")
val nComponents = intnode.out.size val nComponents = intnode.out.size

View File

@ -37,14 +37,21 @@ class TLBusBypass(beatBytes: Int)(implicit p: Parameters) extends TLBusBypassBas
} }
} }
class TLBypassNode(implicit valName: ValName) extends TLCustomNode
{
def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
require (iStars == 0 && oStars == 0, "TLBypass node does not support :=* or :*=")
require (iKnown == 1, "TLBypass node expects exactly one input")
require (oKnown == 2, "TLBypass node expects exactly one output")
(0, 0)
}
def mapParamsD(n: Int, p: Seq[TLClientPortParameters]): Seq[TLClientPortParameters] = { p ++ p }
def mapParamsU(n: Int, p: Seq[TLManagerPortParameters]): Seq[TLManagerPortParameters] = { p.tail }
}
class TLBusBypassBar(implicit p: Parameters) extends LazyModule class TLBusBypassBar(implicit p: Parameters) extends LazyModule
{ {
// The client only sees the second slave port val node = new TLBypassNode()
val node = TLNexusNode(
numClientPorts = 2 to 2 ,
numManagerPorts = 1 to 1,
clientFn = { seq => seq(0) },
managerFn = { seq => seq(1) })
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
val io = IO(new Bundle { val io = IO(new Bundle {

View File

@ -48,12 +48,13 @@ class CoreplexLocalInterrupter(params: ClintParams)(implicit p: Parameters) exte
beatBytes = p(XLen)/8) beatBytes = p(XLen)/8)
val intnode = IntNexusNode( val intnode = IntNexusNode(
numSourcePorts = 0 to 1024,
numSinkPorts = 0 to 0,
sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(ints, Seq(Resource(device, "int"))))) }, sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(ints, Seq(Resource(device, "int"))))) },
sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) }) sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) },
outputRequiresInput = false)
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
require (intnode.edges.in.size == 0, "CLINT only produces interrupts; it does not accept them")
val io = IO(new Bundle { val io = IO(new Bundle {
val rtcTick = Bool(INPUT) val rtcTick = Bool(INPUT)
}) })

View File

@ -86,10 +86,10 @@ class TLPLIC(params: PLICParams)(implicit p: Parameters) extends LazyModule
concurrency = 1) // limiting concurrency handles RAW hazards on claim registers concurrency = 1) // limiting concurrency handles RAW hazards on claim registers
val intnode = IntNexusNode( val intnode = IntNexusNode(
numSourcePorts = 0 to 1024,
numSinkPorts = 0 to 1024,
sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(1, Seq(Resource(device, "int"))))) }, sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(1, Seq(Resource(device, "int"))))) },
sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) }) sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) },
outputRequiresInput = false,
inputRequiresOutput = false)
/* Negotiated sizes */ /* Negotiated sizes */
def nDevices: Int = intnode.edges.in.map(_.source.num).sum def nDevices: Int = intnode.edges.in.map(_.source.num).sum

View File

@ -75,5 +75,6 @@ class TLRAMZeroDelay(ramBeatBytes: Int, txns: Int)(implicit p: Parameters) exten
} }
class TLRAMZeroDelayTest(ramBeatBytes: Int, txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) { class TLRAMZeroDelayTest(ramBeatBytes: Int, txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) {
io.finished := Module(LazyModule(new TLRAMZeroDelay(ramBeatBytes, txns)).module).io.finished val dut = Module(LazyModule(new TLRAMZeroDelay(ramBeatBytes, txns)).module)
io.finished := dut.io.finished
} }

View File

@ -0,0 +1,21 @@
// See LICENSE.SiFive for license details.
package freechips.rocketchip.diplomacy
import Chisel._
import chisel3.shim.CloneModule
final class CloneLazyModule private (val base: LazyModule)
{
// Pay special attention to the .iParams and .oParams of the node, which
// indicate the parameters a stand-in master must supply.
def clone[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](node: NodeHandle[DI, UI, EI, BI, DO, UO, EO, BO])(implicit valName: ValName) =
new MixedTestNode(node, this)
protected[diplomacy] lazy val io = CloneModule(base.module)
}
object CloneLazyModule
{
def apply(base: LazyModule) = new CloneLazyModule(base)
}

View File

@ -0,0 +1,58 @@
// See LICENSE.SiFive for license details.
// !!! HACK TO WORK-AROUND MISSING CHISEL FEATURE
// !!! We need to be inside the chisel3 package to access Builder
package chisel3.shim
import Chisel._
import chisel3.experimental.{RawModule, MultiIOModule, BaseModule}
import chisel3.internal.Builder
import chisel3.core.UserModule
import chisel3.internal.firrtl.{Command, DefInstance}
import scala.collection.immutable.ListMap
import scala.collection.mutable.ArrayBuffer
class ClonePorts protected[shim](elts: Data*) extends Record
{
val elements = ListMap(elts.map(d => d.instanceName -> d.chiselCloneType): _*)
def apply(field: String) = elements(field)
override def cloneType = (new ClonePorts(elts: _*)).asInstanceOf[this.type]
}
private class CloneModule private (model: RawModule) extends BlackBox
{
import CloneModule._
override def desiredName = model.name
val io = IO(new ClonePorts(model.getPorts.map(_.id): _*))
}
object CloneModule
{
def apply(model: BaseModule): ClonePorts = {
// Create the 'BlackBox' stand-in
val mod = Module(new CloneModule(model.asInstanceOf[RawModule]))
// Rewrite the instance definition to be the original module
// (this is needed because the original module gets clobbered by DCE + constant prop)
val method = classOf[UserModule].getDeclaredMethod("_commands")
method.setAccessible(true)
val commands = method.invoke(Builder.forcedUserModule).asInstanceOf[ArrayBuffer[Command]]
val victimIdx = commands.lastIndexWhere {
case DefInstance(_, kill, _) => mod eq kill
case _ => false
}
val victim = commands(victimIdx).asInstanceOf[DefInstance]
val standin = new DefInstance(victim.sourceInfo, model, victim.ports) {
override def name = victim.name
}
commands.update(victimIdx, standin)
// Wire it up
model match {
case _: MultiIOModule =>
mod.io("clock") := Module.clock
mod.io("reset") := Module.reset
case _: RawModule => // Do nothing
}
mod.io
}
}

View File

@ -36,7 +36,8 @@ abstract class LazyModule()(implicit val p: Parameters)
getClass.getMethods.filter { m => getClass.getMethods.filter { m =>
m.getParameterTypes.isEmpty && m.getParameterTypes.isEmpty &&
!java.lang.reflect.Modifier.isStatic(m.getModifiers) && !java.lang.reflect.Modifier.isStatic(m.getModifiers) &&
m.getName != "children" m.getName != "children" &&
m.getName != "getChildren"
}.flatMap { m => }.flatMap { m =>
if (classOf[LazyModule].isAssignableFrom(m.getReturnType)) { if (classOf[LazyModule].isAssignableFrom(m.getReturnType)) {
val obj = m.invoke(this) val obj = m.invoke(this)
@ -126,6 +127,8 @@ abstract class LazyModule()(implicit val p: Parameters)
iterfunc(this) iterfunc(this)
children.foreach( _.nodeIterator(iterfunc) ) children.foreach( _.nodeIterator(iterfunc) )
} }
def getChildren = children
} }
object LazyModule object LazyModule
@ -162,7 +165,9 @@ sealed trait LazyModuleImpLike extends BaseModule
protected[diplomacy] def instantiate() = { protected[diplomacy] def instantiate() = {
val childDangles = wrapper.children.reverse.flatMap { c => val childDangles = wrapper.children.reverse.flatMap { c =>
implicit val sourceInfo = c.info implicit val sourceInfo = c.info
Module(c.module).dangles val mod = Module(c.module)
mod.finishInstantiate()
mod.dangles
} }
wrapper.instantiate() wrapper.instantiate()
val nodeDangles = wrapper.nodes.reverse.flatMap(_.instantiate()) val nodeDangles = wrapper.nodes.reverse.flatMap(_.instantiate())
@ -181,6 +186,10 @@ sealed trait LazyModuleImpLike extends BaseModule
} }
(auto, dangles) (auto, dangles)
} }
protected[diplomacy] def finishInstantiate() {
wrapper.nodes.reverse.foreach { _.finishInstantiate() }
}
} }
class LazyModuleImp(val wrapper: LazyModule) extends MultiIOModule with LazyModuleImpLike { class LazyModuleImp(val wrapper: LazyModule) extends MultiIOModule with LazyModuleImpLike {

View File

@ -93,6 +93,7 @@ abstract class BaseNode(implicit val valName: ValName)
val serial = BaseNode.serial val serial = BaseNode.serial
BaseNode.serial = BaseNode.serial + 1 BaseNode.serial = BaseNode.serial + 1
protected[diplomacy] def instantiate(): Seq[Dangle] protected[diplomacy] def instantiate(): Seq[Dangle]
protected[diplomacy] def finishInstantiate(): Unit
def name = lazyModule.name + "." + valName.name def name = lazyModule.name + "." + valName.name
def omitGraphML = outputs.isEmpty && inputs.isEmpty def omitGraphML = outputs.isEmpty && inputs.isEmpty
@ -122,50 +123,53 @@ object BaseNode
trait NoHandle trait NoHandle
case object NoHandleObject extends NoHandle case object NoHandleObject extends NoHandle
trait NodeHandle[DI, UI, BI <: Data, DO, UO, BO <: Data] trait NodeHandle[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]
extends InwardNodeHandle[DI, UI, BI] with OutwardNodeHandle[DO, UO, BO] extends InwardNodeHandle[DI, UI, EI, BI] with OutwardNodeHandle[DO, UO, EO, BO]
{ {
// connecting two full nodes => full node // connecting two full nodes => full node
override def := [DX, UX, BX <: Data](h: NodeHandle[DX, UX, BX, DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NodeHandle[DX, UX, BX, DO, UO, BO] = { bind(h, BIND_ONCE); NodeHandle(h, this) } override def := [DX, UX, EX, BX <: Data, EY](h: NodeHandle[DX, UX, EX, BX, DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NodeHandle[DX, UX, EX, BX, DO, UO, EO, BO] = { bind(h, BIND_ONCE); NodeHandle(h, this) }
override def :*= [DX, UX, BX <: Data](h: NodeHandle[DX, UX, BX, DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NodeHandle[DX, UX, BX, DO, UO, BO] = { bind(h, BIND_STAR); NodeHandle(h, this) } override def :*= [DX, UX, EX, BX <: Data, EY](h: NodeHandle[DX, UX, EX, BX, DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NodeHandle[DX, UX, EX, BX, DO, UO, EO, BO] = { bind(h, BIND_STAR); NodeHandle(h, this) }
override def :=* [DX, UX, BX <: Data](h: NodeHandle[DX, UX, BX, DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NodeHandle[DX, UX, BX, DO, UO, BO] = { bind(h, BIND_QUERY); NodeHandle(h, this) } override def :=* [DX, UX, EX, BX <: Data, EY](h: NodeHandle[DX, UX, EX, BX, DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NodeHandle[DX, UX, EX, BX, DO, UO, EO, BO] = { bind(h, BIND_QUERY); NodeHandle(h, this) }
override def :=? [DX, UX, BX <: Data](h: NodeHandle[DX, UX, BX, DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NodeHandle[DX, UX, BX, DO, UO, BO] = { bind(h, p(CardinalityInferenceDirectionKey)); NodeHandle(h, this) } override def :=? [DX, UX, EX, BX <: Data, EY](h: NodeHandle[DX, UX, EX, BX, DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NodeHandle[DX, UX, EX, BX, DO, UO, EO, BO] = { bind(h, p(CardinalityInferenceDirectionKey)); NodeHandle(h, this) }
// connecting a full node with an output => an output // connecting a full node with an output => an output
override def := (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): OutwardNodeHandle[DO, UO, BO] = { bind(h, BIND_ONCE); this } override def := [EY](h: OutwardNodeHandle[DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): OutwardNodeHandle[DO, UO, EO, BO] = { bind(h, BIND_ONCE); this }
override def :*= (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): OutwardNodeHandle[DO, UO, BO] = { bind(h, BIND_STAR); this } override def :*= [EY](h: OutwardNodeHandle[DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): OutwardNodeHandle[DO, UO, EO, BO] = { bind(h, BIND_STAR); this }
override def :=* (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): OutwardNodeHandle[DO, UO, BO] = { bind(h, BIND_QUERY); this } override def :=* [EY](h: OutwardNodeHandle[DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): OutwardNodeHandle[DO, UO, EO, BO] = { bind(h, BIND_QUERY); this }
override def :=? (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): OutwardNodeHandle[DO, UO, BO] = { bind(h, p(CardinalityInferenceDirectionKey)); this } override def :=? [EY](h: OutwardNodeHandle[DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): OutwardNodeHandle[DO, UO, EO, BO] = { bind(h, p(CardinalityInferenceDirectionKey)); this }
} }
object NodeHandle object NodeHandle
{ {
def apply[DI, UI, BI <: Data, DO, UO, BO <: Data](i: InwardNodeHandle[DI, UI, BI], o: OutwardNodeHandle[DO, UO, BO]) = NodeHandlePair(i, o) def apply[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](i: InwardNodeHandle[DI, UI, EI, BI], o: OutwardNodeHandle[DO, UO, EO, BO]) = new NodeHandlePair(i, o)
} }
case class NodeHandlePair[DI, UI, BI <: Data, DO, UO, BO <: Data] class NodeHandlePair[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]
(inwardHandle: InwardNodeHandle[DI, UI, BI], outwardHandle: OutwardNodeHandle[DO, UO, BO]) (inwardHandle: InwardNodeHandle[DI, UI, EI, BI], outwardHandle: OutwardNodeHandle[DO, UO, EO, BO])
extends NodeHandle[DI, UI, BI, DO, UO, BO] extends NodeHandle[DI, UI, EI, BI, DO, UO, EO, BO]
{ {
val inward = inwardHandle.inward val inward = inwardHandle.inward
val outward = outwardHandle.outward val outward = outwardHandle.outward
def inner = inwardHandle.inner
def outer = outwardHandle.outer
} }
trait InwardNodeHandle[DI, UI, BI <: Data] extends NoHandle trait InwardNodeHandle[DI, UI, EI, BI <: Data] extends NoHandle
{ {
def inward: InwardNode[DI, UI, BI] def inward: InwardNode[DI, UI, BI]
def parentsIn: Seq[LazyModule] = inward.parents def inner: InwardNodeImp[DI, UI, EI, BI]
def bind(h: OutwardNodeHandle[DI, UI, BI], binding: NodeBinding)(implicit p: Parameters, sourceInfo: SourceInfo): Unit = inward.bind(h.outward, binding)
protected def bind[EY](h: OutwardNodeHandle[DI, UI, EY, BI], binding: NodeBinding)(implicit p: Parameters, sourceInfo: SourceInfo): Unit = inward.bind(h.outward, binding)
// connecting an input node with a full nodes => an input node // connecting an input node with a full nodes => an input node
def := [DX, UX, BX <: Data](h: NodeHandle[DX, UX, BX, DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): InwardNodeHandle[DX, UX, BX] = { bind(h, BIND_ONCE); h } def := [DX, UX, EX, BX <: Data, EY](h: NodeHandle[DX, UX, EX, BX, DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): InwardNodeHandle[DX, UX, EX, BX] = { bind(h, BIND_ONCE); h }
def :*= [DX, UX, BX <: Data](h: NodeHandle[DX, UX, BX, DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): InwardNodeHandle[DX, UX, BX] = { bind(h, BIND_STAR); h } def :*= [DX, UX, EX, BX <: Data, EY](h: NodeHandle[DX, UX, EX, BX, DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): InwardNodeHandle[DX, UX, EX, BX] = { bind(h, BIND_STAR); h }
def :=* [DX, UX, BX <: Data](h: NodeHandle[DX, UX, BX, DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): InwardNodeHandle[DX, UX, BX] = { bind(h, BIND_QUERY); h } def :=* [DX, UX, EX, BX <: Data, EY](h: NodeHandle[DX, UX, EX, BX, DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): InwardNodeHandle[DX, UX, EX, BX] = { bind(h, BIND_QUERY); h }
def :=? [DX, UX, BX <: Data](h: NodeHandle[DX, UX, BX, DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): InwardNodeHandle[DX, UX, BX] = { bind(h, p(CardinalityInferenceDirectionKey)); h } def :=? [DX, UX, EX, BX <: Data, EY](h: NodeHandle[DX, UX, EX, BX, DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): InwardNodeHandle[DX, UX, EX, BX] = { bind(h, p(CardinalityInferenceDirectionKey)); h }
// connecting input node with output node => no node // connecting input node with output node => no node
def := (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NoHandle = { bind(h, BIND_ONCE); NoHandleObject } def := [EY](h: OutwardNodeHandle[DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NoHandle = { bind(h, BIND_ONCE); NoHandleObject }
def :*= (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NoHandle = { bind(h, BIND_STAR); NoHandleObject } def :*= [EY](h: OutwardNodeHandle[DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NoHandle = { bind(h, BIND_STAR); NoHandleObject }
def :=* (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NoHandle = { bind(h, BIND_QUERY); NoHandleObject } def :=* [EY](h: OutwardNodeHandle[DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NoHandle = { bind(h, BIND_QUERY); NoHandleObject }
def :=? (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NoHandle = { bind(h, p(CardinalityInferenceDirectionKey)); NoHandleObject } def :=? [EY](h: OutwardNodeHandle[DI, UI, EY, BI])(implicit p: Parameters, sourceInfo: SourceInfo): NoHandle = { bind(h, p(CardinalityInferenceDirectionKey)); NoHandleObject }
} }
sealed trait NodeBinding sealed trait NodeBinding
@ -182,22 +186,14 @@ object NodeBinding
} }
} }
trait InwardNode[DI, UI, BI <: Data] extends BaseNode with InwardNodeHandle[DI, UI, BI] trait InwardNode[DI, UI, BI <: Data] extends BaseNode
{ {
val inward = this
protected[diplomacy] val numPI: Range.Inclusive
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}")
private val accPI = ListBuffer[(Int, OutwardNode[DI, UI, BI], NodeBinding, Parameters, SourceInfo)]() private val accPI = ListBuffer[(Int, OutwardNode[DI, UI, BI], NodeBinding, Parameters, SourceInfo)]()
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 p: Parameters, 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)
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 its .module was used" + info) require (!iRealized, s"${name}${lazyModule.line} was incorrectly connected as a sink after its .module was used" + info)
accPI += ((index, node, binding, p, sourceInfo)) accPI += ((index, node, binding, p, sourceInfo))
} }
@ -206,33 +202,26 @@ 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 diParams: Seq[DI] // from connected nodes
protected[diplomacy] val uiParams: Seq[UI] // from this node
protected[diplomacy] def bind(h: OutwardNode[DI, UI, BI], binding: NodeBinding)(implicit p: Parameters, sourceInfo: SourceInfo): Unit protected[diplomacy] def bind(h: OutwardNode[DI, UI, BI], binding: NodeBinding)(implicit p: Parameters, sourceInfo: SourceInfo): Unit
} }
trait OutwardNodeHandle[DO, UO, BO <: Data] extends NoHandle trait OutwardNodeHandle[DO, UO, EO, BO <: Data] extends NoHandle
{ {
def outward: OutwardNode[DO, UO, BO] def outward: OutwardNode[DO, UO, BO]
def parentsOut: Seq[LazyModule] = outward.parents def outer: OutwardNodeImp[DO, UO, EO, BO]
} }
trait OutwardNode[DO, UO, BO <: Data] extends BaseNode with OutwardNodeHandle[DO, UO, BO] trait OutwardNode[DO, UO, BO <: Data] extends BaseNode
{ {
val outward = this
protected[diplomacy] val numPO: Range.Inclusive
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}")
private val accPO = ListBuffer[(Int, InwardNode [DO, UO, BO], NodeBinding, Parameters, SourceInfo)]() private val accPO = ListBuffer[(Int, InwardNode [DO, UO, BO], NodeBinding, Parameters, SourceInfo)]()
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 p: Parameters, 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)
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 its .module was used" + info) require (!oRealized, s"${name}${lazyModule.line} was incorrectly connected as a source after its .module was used" + info)
accPO += ((index, node, binding, p, sourceInfo)) accPO += ((index, node, binding, p, sourceInfo))
} }
@ -241,7 +230,8 @@ 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 uoParams: Seq[UO] // from connected nodes
protected[diplomacy] val doParams: Seq[DO] // from this node
} }
abstract class CycleException(kind: String, loop: Seq[String]) extends Exception(s"Diplomatic ${kind} cycle detected involving ${loop}") abstract class CycleException(kind: String, loop: Seq[String]) extends Exception(s"Diplomatic ${kind} cycle detected involving ${loop}")
@ -251,13 +241,14 @@ case class UpwardCycleException(loop: Seq[String] = Nil) extends CycleException(
case class Edges[EI, EO](in: EI, out: EO) case class Edges[EI, EO](in: EI, out: EO)
sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
inner: InwardNodeImp [DI, UI, EI, BI], val inner: InwardNodeImp [DI, UI, EI, BI],
outer: OutwardNodeImp[DO, UO, EO, BO])( val outer: OutwardNodeImp[DO, UO, EO, BO])(
protected[diplomacy] val numPO: Range.Inclusive,
protected[diplomacy] val numPI: Range.Inclusive)(
implicit valName: ValName) implicit valName: ValName)
extends BaseNode with NodeHandle[DI, UI, BI, DO, UO, BO] with InwardNode[DI, UI, BI] with OutwardNode[DO, UO, BO] extends BaseNode with NodeHandle[DI, UI, EI, BI, DO, UO, EO, BO] with InwardNode[DI, UI, BI] with OutwardNode[DO, UO, BO]
{ {
val inward = this
val outward = this
protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStar: Int, oStar: Int): (Int, Int) protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStar: Int, oStar: Int): (Int, Int)
protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO] protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO]
protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI] protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI]
@ -287,8 +278,6 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
case BIND_STAR => iStar }}.scanLeft(0)(_+_) case BIND_STAR => iStar }}.scanLeft(0)(_+_)
val oTotal = oSum.lastOption.getOrElse(0) val oTotal = oSum.lastOption.getOrElse(0)
val iTotal = iSum.lastOption.getOrElse(0) val iTotal = iSum.lastOption.getOrElse(0)
require(numPO.contains(oTotal), s"${name} has ${oTotal} outputs, expected ${numPO}${lazyModule.line}")
require(numPI.contains(iTotal), s"${name} has ${iTotal} inputs, expected ${numPI}${lazyModule.line}")
(oSum.init zip oSum.tail, iSum.init zip iSum.tail, oStar, iStar) (oSum.init zip oSum.tail, iSum.init zip iSum.tail, oStar, iStar)
} catch { } catch {
case c: StarCycleException => throw c.copy(loop = s"${name}${lazyModule.line}" +: c.loop) case c: StarCycleException => throw c.copy(loop = s"${name}${lazyModule.line}" +: c.loop)
@ -305,11 +294,12 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
} }
private var oParamsCycleGuard = false private var oParamsCycleGuard = false
protected[diplomacy] lazy val oParams: Seq[DO] = { protected[diplomacy] lazy val diParams: Seq[DI] = iPorts.map { case (i, n, _, _) => n.doParams(i) }
protected[diplomacy] lazy val doParams: Seq[DO] = {
try { try {
if (oParamsCycleGuard) throw DownwardCycleException() if (oParamsCycleGuard) throw DownwardCycleException()
oParamsCycleGuard = true oParamsCycleGuard = true
val o = mapParamsD(oPorts.size, iPorts.map { case (i, n, _, _) => n.oParams(i) }) val o = mapParamsD(oPorts.size, diParams)
require (o.size == oPorts.size, s"Bug in diplomacy; ${name} has ${o.size} != ${oPorts.size} down/up outer parameters${lazyModule.line}") require (o.size == oPorts.size, s"Bug in diplomacy; ${name} has ${o.size} != ${oPorts.size} down/up outer parameters${lazyModule.line}")
o.map(outer.mixO(_, this)) o.map(outer.mixO(_, this))
} catch { } catch {
@ -318,11 +308,12 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
} }
private var iParamsCycleGuard = false private var iParamsCycleGuard = false
protected[diplomacy] lazy val iParams: Seq[UI] = { protected[diplomacy] lazy val uoParams: Seq[UO] = oPorts.map { case (o, n, _, _) => n.uiParams(o) }
protected[diplomacy] lazy val uiParams: Seq[UI] = {
try { try {
if (iParamsCycleGuard) throw UpwardCycleException() if (iParamsCycleGuard) throw UpwardCycleException()
iParamsCycleGuard = true iParamsCycleGuard = true
val i = mapParamsU(iPorts.size, oPorts.map { case (o, n, _, _) => n.iParams(o) }) val i = mapParamsU(iPorts.size, uoParams)
require (i.size == iPorts.size, s"Bug in diplomacy; ${name} has ${i.size} != ${iPorts.size} up/down inner parameters${lazyModule.line}") require (i.size == iPorts.size, s"Bug in diplomacy; ${name} has ${i.size} != ${iPorts.size} up/down inner parameters${lazyModule.line}")
i.map(inner.mixI(_, this)) i.map(inner.mixI(_, this))
} catch { } catch {
@ -330,11 +321,11 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
} }
} }
protected[diplomacy] def gco = if (iParams.size != 1) None else inner.getO(iParams(0)) protected[diplomacy] def gco = if (uiParams.size != 1) None else inner.getO(uiParams(0))
protected[diplomacy] def gci = if (oParams.size != 1) None else outer.getI(oParams(0)) protected[diplomacy] def gci = if (doParams.size != 1) None else outer.getI(doParams(0))
protected[diplomacy] lazy val edgesOut = (oPorts zip oParams).map { case ((i, n, p, s), o) => outer.edgeO(o, n.iParams(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 iParams).map { case ((o, n, p, s), i) => inner.edgeI(n.oParams(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) }
// If you need access to the edges of a foreign Node, use this method (in/out create bundles) // If you need access to the edges of a foreign Node, use this method (in/out create bundles)
lazy val edges = Edges(edgesIn, edgesOut) lazy val edges = Edges(edgesIn, edgesOut)
@ -381,6 +372,10 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
danglesOut ++ danglesIn danglesOut ++ danglesIn
} }
protected[diplomacy] def finishInstantiate() = {
bundlesSafeNow = false
}
// 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
protected[diplomacy] def bind(h: OutwardNode[DI, UI, BI], binding: NodeBinding)(implicit p: Parameters, sourceInfo: SourceInfo) { protected[diplomacy] def bind(h: OutwardNode[DI, UI, BI], binding: NodeBinding)(implicit p: Parameters, sourceInfo: SourceInfo) {
val x = this // x := y val x = this // x := y
@ -406,10 +401,8 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
abstract class MixedCustomNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( abstract class MixedCustomNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
inner: InwardNodeImp [DI, UI, EI, BI], inner: InwardNodeImp [DI, UI, EI, BI],
outer: OutwardNodeImp[DO, UO, EO, BO])( outer: OutwardNodeImp[DO, UO, EO, BO])(
numPO: Range.Inclusive,
numPI: Range.Inclusive)(
implicit valName: ValName) implicit valName: ValName)
extends MixedNode(inner, outer)(numPO, numPI) extends MixedNode(inner, outer)
{ {
def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int)
def mapParamsD(n: Int, p: Seq[DI]): Seq[DO] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO]
@ -417,28 +410,28 @@ abstract class MixedCustomNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
} }
abstract class CustomNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])( abstract class CustomNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(
numPO: Range.Inclusive,
numPI: Range.Inclusive)(
implicit valName: ValName) implicit valName: ValName)
extends MixedCustomNode(imp, imp)(numPO, numPI) extends MixedCustomNode(imp, imp)
class MixedAdapterNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( class MixedAdapterNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
inner: InwardNodeImp [DI, UI, EI, BI], inner: InwardNodeImp [DI, UI, EI, BI],
outer: OutwardNodeImp[DO, UO, EO, BO])( outer: OutwardNodeImp[DO, UO, EO, BO])(
dFn: DI => DO, dFn: DI => DO,
uFn: UO => UI, uFn: UO => UI)(
num: Range.Inclusive = 0 to 999)(
implicit valName: ValName) implicit valName: ValName)
extends MixedNode(inner, outer)(num, num) extends MixedNode(inner, outer)
{ {
protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = { protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
require (oStars + iStars <= 1, s"${name} (an adapter) appears left of a :*= ${iStars} times and right of a :=* ${oStars} times; at most once is allowed${lazyModule.line}") require (oStars + iStars <= 1, s"${name} (an adapter) appears left of a :*= ${iStars} times and right of a :=* ${oStars} times; at most once is allowed${lazyModule.line}")
if (oStars > 0) { if (oStars > 0) {
require (iKnown >= oKnown, s"${name} (an adapter) has ${oKnown} outputs and ${iKnown} inputs; cannot assign ${iKnown-oKnown} edges to resolve :=*${lazyModule.line}") require (iKnown >= oKnown, s"${name} (an adapter) has ${oKnown} outputs and ${iKnown} inputs; cannot assign ${iKnown-oKnown} edges to resolve :=*${lazyModule.line}")
(0, iKnown - oKnown) (0, iKnown - oKnown)
} else { } else if (iStars > 0) {
require (oKnown >= iKnown, s"${name} (an adapter) has ${oKnown} outputs and ${iKnown} inputs; cannot assign ${oKnown-iKnown} edges to resolve :*=${lazyModule.line}") require (oKnown >= iKnown, s"${name} (an adapter) has ${oKnown} outputs and ${iKnown} inputs; cannot assign ${oKnown-iKnown} edges to resolve :*=${lazyModule.line}")
(oKnown - iKnown, 0) (oKnown - iKnown, 0)
} else {
require (oKnown == iKnown, s"${name} (an adapter) has ${oKnown} outputs and ${iKnown} inputs; these do not match")
(0, 0)
} }
} }
protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO] = { protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO] = {
@ -453,10 +446,9 @@ class MixedAdapterNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
class AdapterNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])( class AdapterNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(
dFn: D => D, dFn: D => D,
uFn: U => U, uFn: U => U)(
num: Range.Inclusive = 0 to 999)(
implicit valName: ValName) implicit valName: ValName)
extends MixedAdapterNode[D, U, EI, B, D, U, EO, B](imp, imp)(dFn, uFn, num) extends MixedAdapterNode[D, U, EI, B, D, U, EO, B](imp, imp)(dFn, uFn)
// IdentityNodes automatically connect their inputs to outputs // IdentityNodes automatically connect their inputs to outputs
class IdentityNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])()(implicit valName: ValName) class IdentityNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])()(implicit valName: ValName)
@ -475,39 +467,39 @@ class MixedNexusNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
outer: OutwardNodeImp[DO, UO, EO, BO])( outer: OutwardNodeImp[DO, UO, EO, BO])(
dFn: Seq[DI] => DO, dFn: Seq[DI] => DO,
uFn: Seq[UO] => UI, uFn: Seq[UO] => UI,
numPO: Range.Inclusive = 1 to 999, // no inputs and no outputs is always allowed
numPI: Range.Inclusive = 1 to 999)( inputRequiresOutput: Boolean = true,
outputRequiresInput: Boolean = true)(
implicit valName: ValName) implicit valName: ValName)
extends MixedNode(inner, outer)(numPO, numPI) extends MixedNode(inner, outer)
{ {
// require (numPO.end >= 1, s"${name} does not accept outputs${lazyModule.line}")
// require (numPI.end >= 1, s"${name} does not accept inputs${lazyModule.line}")
protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = { protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
require (iStars == 0, s"${name} (a nexus) appears left of :*= (perhaps you should flip the '*' to :=*?)${lazyModule.line}") // a nexus treats :=* as a weak pointer
require (oStars == 0, s"${name} (a nexus) appears right of a :=* (perhaps you should flip the '*' to :*=?)${lazyModule.line}") require (!outputRequiresInput || oKnown == 0 || iStars + iKnown != 0, s"${name} (a nexus) has ${oKnown} required outputs and no possible inputs")
(0, 0) require (!inputRequiresOutput || iKnown == 0 || oStars + oKnown != 0, s"${name} (a nexus) has ${iKnown} required inputs and no possible outputs")
if (iKnown == 0 && oKnown == 0) (0, 0) else (1, 1)
} }
protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO] = { val a = dFn(p); Seq.fill(n)(a) } protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO] = { if (n > 0) { val a = dFn(p); Seq.fill(n)(a) } else Nil }
protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI] = { val a = uFn(p); Seq.fill(n)(a) } protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI] = { if (n > 0) { val a = uFn(p); Seq.fill(n)(a) } else Nil }
} }
class NexusNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])( class NexusNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(
dFn: Seq[D] => D, dFn: Seq[D] => D,
uFn: Seq[U] => U, uFn: Seq[U] => U,
numPO: Range.Inclusive = 1 to 999, inputRequiresOutput: Boolean = true,
numPI: Range.Inclusive = 1 to 999)( outputRequiresInput: Boolean = true)(
implicit valName: ValName) implicit valName: ValName)
extends MixedNexusNode[D, U, EI, B, D, U, EO, B](imp, imp)(dFn, uFn, numPO, numPI) extends MixedNexusNode[D, U, EI, B, D, U, EO, B](imp, imp)(dFn, uFn, inputRequiresOutput, outputRequiresInput)
// There are no Mixed SourceNodes // There are no Mixed SourceNodes
class SourceNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq[D])(implicit valName: ValName) class SourceNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq[D])(implicit valName: ValName)
extends MixedNode(imp, imp)(po.size to po.size, 0 to 0) extends MixedNode(imp, imp)
{ {
protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = { protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
require (oStars <= 1, s"${name} (a source) appears right of a :=* ${oStars} times; at most once is allowed${lazyModule.line}") require (oStars <= 1, s"${name} (a source) appears right of a :=* ${oStars} times; at most once is allowed${lazyModule.line}")
require (iStars == 0, s"${name} (a source) cannot appear left of a :*=${lazyModule.line}") require (iStars == 0, s"${name} (a source) cannot appear left of a :*=${lazyModule.line}")
require (iKnown == 0, s"${name} (a source) cannot appear left of a :=${lazyModule.line}") require (iKnown == 0, s"${name} (a source) cannot appear left of a :=${lazyModule.line}")
require (po.size == oKnown || oStars == 1, s"${name} (a source) has only ${oKnown} outputs connected out of ${po.size}")
require (po.size >= oKnown, s"${name} (a source) has ${oKnown} outputs out of ${po.size}; cannot assign ${po.size - oKnown} edges to resolve :=*${lazyModule.line}") require (po.size >= oKnown, s"${name} (a source) has ${oKnown} outputs out of ${po.size}; cannot assign ${po.size - oKnown} edges to resolve :=*${lazyModule.line}")
(0, po.size - oKnown) (0, po.size - oKnown)
} }
@ -517,15 +509,58 @@ class SourceNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq
// There are no Mixed SinkNodes // There are no Mixed SinkNodes
class SinkNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U])(implicit valName: ValName) class SinkNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U])(implicit valName: ValName)
extends MixedNode(imp, imp)(0 to 0, pi.size to pi.size) extends MixedNode(imp, imp)
{ {
protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = { protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
require (iStars <= 1, s"${name} (a sink) appears left of a :*= ${iStars} times; at most once is allowed${lazyModule.line}") require (iStars <= 1, s"${name} (a sink) appears left of a :*= ${iStars} times; at most once is allowed${lazyModule.line}")
require (oStars == 0, s"${name} (a sink) cannot appear right of a :=*${lazyModule.line}") require (oStars == 0, s"${name} (a sink) cannot appear right of a :=*${lazyModule.line}")
require (oKnown == 0, s"${name} (a sink) cannot appear right of a :=${lazyModule.line}") require (oKnown == 0, s"${name} (a sink) cannot appear right of a :=${lazyModule.line}")
require (pi.size == iKnown || iStars == 1, s"${name} (a sink) has only ${iKnown} inputs connected out of ${pi.size}")
require (pi.size >= iKnown, s"${name} (a sink) has ${iKnown} inputs out of ${pi.size}; cannot assign ${pi.size - iKnown} edges to resolve :*=${lazyModule.line}") require (pi.size >= iKnown, s"${name} (a sink) has ${iKnown} inputs out of ${pi.size}; cannot assign ${pi.size - iKnown} edges to resolve :*=${lazyModule.line}")
(pi.size - iKnown, 0) (pi.size - iKnown, 0)
} }
protected[diplomacy] def mapParamsD(n: Int, p: Seq[D]): Seq[D] = Seq() protected[diplomacy] def mapParamsD(n: Int, p: Seq[D]): Seq[D] = Seq()
protected[diplomacy] def mapParamsU(n: Int, p: Seq[U]): Seq[U] = pi protected[diplomacy] def mapParamsU(n: Int, p: Seq[U]): Seq[U] = pi
} }
class MixedTestNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data] protected[diplomacy](
node: NodeHandle [DI, UI, EI, BI, DO, UO, EO, BO], clone: CloneLazyModule)(
implicit valName: ValName)
extends MixedNode(node.inner, node.outer)
{
// The devices connected to this test node must recreate these parameters:
def iParams: Seq[DI] = node.inward .diParams
def oParams: Seq[UO] = node.outward.uoParams
protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
require (oStars <= 1, s"${name} (a test node) appears right of a :=* ${oStars} times; at most once is allowed${lazyModule.line}")
require (iStars <= 1, s"${name} (a test node) appears left of a :*= ${iStars} times; at most once is allowed${lazyModule.line}")
require (node.inward .uiParams.size == iKnown || iStars == 1, s"${name} (a test node) has only ${iKnown} inputs connected out of ${node.inward.uiParams.size}")
require (node.outward.doParams.size == oKnown || oStars == 1, s"${name} (a test node) has only ${oKnown} outputs connected out of ${node.outward.doParams.size}")
(node.inward.uiParams.size - iKnown, node.outward.doParams.size - oKnown)
}
protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI] = node.inward .uiParams
protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO] = node.outward.doParams
override protected[diplomacy] def instantiate() = {
val dangles = super.instantiate()
val orig_module = clone.base.module
val clone_auto = clone.io("auto").asInstanceOf[AutoBundle]
danglesOut.zipWithIndex.foreach { case (d, i) =>
val orig = orig_module.dangles.find(_.source == HalfEdge(node.outward.serial, i))
require (orig.isDefined, s"Cloned node ${node.outward.name} must be connected externally out ${orig_module.name}")
val io_name = orig_module.auto.elements.find(_._2 eq orig.get.data).get._1
d.data <> clone_auto.elements(io_name)
}
danglesIn.zipWithIndex.foreach { case (d, i) =>
val orig = orig_module.dangles.find(_.sink == HalfEdge(node.inward.serial, i))
require (orig.isDefined, s"Cloned node ${node.inward.name} must be connected externally in ${orig_module.name}")
val io_name = orig_module.auto.elements.find(_._2 eq orig.get.data).get._1
clone_auto.elements(io_name) <> d.data
}
dangles
}
}

View File

@ -7,7 +7,7 @@ import freechips.rocketchip.config.Parameters
package object diplomacy package object diplomacy
{ {
type SimpleNodeHandle[D, U, B <: Chisel.Data] = NodeHandle[D, U, B, D, U, B] type SimpleNodeHandle[D, U, E, B <: Chisel.Data] = NodeHandle[D, U, E, B, D, U, E, B]
def sourceLine(sourceInfo: SourceInfo, prefix: String = " (", suffix: String = ")") = sourceInfo match { def sourceLine(sourceInfo: SourceInfo, prefix: String = " (", suffix: String = ")") = sourceInfo match {
case SourceLine(filename, line, col) => s"$prefix$filename:$line:$col$suffix" case SourceLine(filename, line, col) => s"$prefix$filename:$line:$col$suffix"

View File

@ -21,7 +21,11 @@ class IntXing(sync: Int = 3)(implicit p: Parameters) extends LazyModule
object IntSyncCrossingSource object IntSyncCrossingSource
{ {
def apply(alreadyRegistered: Boolean = false)(implicit p: Parameters) = LazyModule(new IntSyncCrossingSource(alreadyRegistered)).node def apply(alreadyRegistered: Boolean = false)(implicit p: Parameters) =
{
val intsource = LazyModule(new IntSyncCrossingSource(alreadyRegistered))
intsource.node
}
} }
@ -54,5 +58,9 @@ class IntSyncCrossingSink(sync: Int = 3)(implicit p: Parameters) extends LazyMod
object IntSyncCrossingSink object IntSyncCrossingSink
{ {
def apply(sync: Int = 3)(implicit p: Parameters) = LazyModule(new IntSyncCrossingSink(sync)).node def apply(sync: Int = 3)(implicit p: Parameters) =
{
val intsink = LazyModule(new IntSyncCrossingSink(sync))
intsink.node
}
} }

View File

@ -23,19 +23,18 @@ case class IntSourceNode(portParams: Seq[IntSourcePortParameters])(implicit valN
case class IntSinkNode(portParams: Seq[IntSinkPortParameters])(implicit valName: ValName) extends SinkNode(IntImp)(portParams) case class IntSinkNode(portParams: Seq[IntSinkPortParameters])(implicit valName: ValName) extends SinkNode(IntImp)(portParams)
case class IntAdapterNode( case class IntAdapterNode(
sourceFn: IntSourcePortParameters => IntSourcePortParameters = { s => s }, sourceFn: IntSourcePortParameters => IntSourcePortParameters = { s => s },
sinkFn: IntSinkPortParameters => IntSinkPortParameters = { s => s }, sinkFn: IntSinkPortParameters => IntSinkPortParameters = { s => s })(
num: Range.Inclusive = 0 to 999)(
implicit valName: ValName) implicit valName: ValName)
extends AdapterNode(IntImp)(sourceFn, sinkFn, num) extends AdapterNode(IntImp)(sourceFn, sinkFn)
case class IntIdentityNode()(implicit valName: ValName) extends IdentityNode(IntImp)() case class IntIdentityNode()(implicit valName: ValName) extends IdentityNode(IntImp)()
case class IntNexusNode( case class IntNexusNode(
sourceFn: Seq[IntSourcePortParameters] => IntSourcePortParameters, sourceFn: Seq[IntSourcePortParameters] => IntSourcePortParameters,
sinkFn: Seq[IntSinkPortParameters] => IntSinkPortParameters, sinkFn: Seq[IntSinkPortParameters] => IntSinkPortParameters,
numSourcePorts: Range.Inclusive = 0 to 128, inputRequiresOutput: Boolean = true,
numSinkPorts: Range.Inclusive = 0 to 128)( outputRequiresInput: Boolean = true)(
implicit valName: ValName) implicit valName: ValName)
extends NexusNode(IntImp)(sourceFn, sinkFn, numSourcePorts, numSinkPorts) extends NexusNode(IntImp)(sourceFn, sinkFn, inputRequiresOutput, outputRequiresInput)
object IntSyncImp extends SimpleNodeImp[IntSourcePortParameters, IntSinkPortParameters, IntEdge, SyncInterrupts] object IntSyncImp extends SimpleNodeImp[IntSourcePortParameters, IntSinkPortParameters, IntEdge, SyncInterrupts]
{ {

View File

@ -7,7 +7,7 @@ import freechips.rocketchip.diplomacy._
package object interrupts package object interrupts
{ {
type IntInwardNode = InwardNodeHandle[IntSourcePortParameters, IntSinkPortParameters, Vec[Bool]] type IntInwardNode = InwardNodeHandle[IntSourcePortParameters, IntSinkPortParameters, IntEdge, Vec[Bool]]
type IntOutwardNode = OutwardNodeHandle[IntSourcePortParameters, IntSinkPortParameters, Vec[Bool]] type IntOutwardNode = OutwardNodeHandle[IntSourcePortParameters, IntSinkPortParameters, IntEdge, Vec[Bool]]
type IntNode = SimpleNodeHandle[IntSourcePortParameters, IntSinkPortParameters, Vec[Bool]] type IntNode = SimpleNodeHandle[IntSourcePortParameters, IntSinkPortParameters, IntEdge, Vec[Bool]]
} }

View File

@ -78,12 +78,20 @@ class TLAsyncCrossingSink(depth: Int = 8, sync: Int = 3)(implicit p: Parameters)
object TLAsyncCrossingSource object TLAsyncCrossingSource
{ {
def apply(sync: Int = 3)(implicit p: Parameters) = LazyModule(new TLAsyncCrossingSource(sync)).node def apply(sync: Int = 3)(implicit p: Parameters) =
{
val asource = LazyModule(new TLAsyncCrossingSource(sync))
asource.node
}
} }
object TLAsyncCrossingSink object TLAsyncCrossingSink
{ {
def apply(depth: Int = 8, sync: Int = 3)(implicit p: Parameters) = LazyModule(new TLAsyncCrossingSink(depth, sync)).node def apply(depth: Int = 8, sync: Int = 3)(implicit p: Parameters) =
{
val asink = LazyModule(new TLAsyncCrossingSink(depth, sync))
asink.node
}
} }
@deprecated("TLAsyncCrossing is fragile. Use TLAsyncCrossingSource and TLAsyncCrossingSink", "rocket-chip 1.2") @deprecated("TLAsyncCrossing is fragile. Use TLAsyncCrossingSource and TLAsyncCrossingSink", "rocket-chip 1.2")
@ -131,5 +139,6 @@ class TLRAMAsyncCrossing(txns: Int)(implicit p: Parameters) extends LazyModule {
} }
class TLRAMAsyncCrossingTest(txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) { class TLRAMAsyncCrossingTest(txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) {
io.finished := Module(LazyModule(new TLRAMAsyncCrossing(txns)).module).io.finished val dut = Module(LazyModule(new TLRAMAsyncCrossing(txns)).module)
io.finished := dut.io.finished
} }

View File

@ -266,7 +266,10 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc
object TLAtomicAutomata object TLAtomicAutomata
{ {
def apply(logical: Boolean = true, arithmetic: Boolean = true, concurrency: Int = 1, passthrough: Boolean = true)(implicit p: Parameters): TLNode = def apply(logical: Boolean = true, arithmetic: Boolean = true, concurrency: Int = 1, passthrough: Boolean = true)(implicit p: Parameters): TLNode =
LazyModule(new TLAtomicAutomata(logical, arithmetic, concurrency, passthrough)).node {
val atomics = LazyModule(new TLAtomicAutomata(logical, arithmetic, concurrency, passthrough))
atomics.node
}
case class CAMParams(a: TLBundleParameters, domainsNeedingHelp: Int) case class CAMParams(a: TLBundleParameters, domainsNeedingHelp: Int)
@ -318,5 +321,6 @@ class TLRAMAtomicAutomata(txns: Int)(implicit p: Parameters) extends LazyModule
} }
class TLRAMAtomicAutomataTest(txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) { class TLRAMAtomicAutomataTest(txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) {
io.finished := Module(LazyModule(new TLRAMAtomicAutomata(txns)).module).io.finished val dut = Module(LazyModule(new TLRAMAtomicAutomata(txns)).module)
io.finished := dut.io.finished
} }

View File

@ -205,6 +205,15 @@ class TLBroadcast(lineBytes: Int, numTrackers: Int = 4, bufferless: Boolean = fa
} }
} }
object TLBroadcast
{
def apply(lineBytes: Int, numTrackers: Int = 4, bufferless: Boolean = false)(implicit p: Parameters): TLNode =
{
val broadcast = LazyModule(new TLBroadcast(lineBytes, numTrackers, bufferless))
broadcast.node
}
}
class TLBroadcastTracker(id: Int, lineBytes: Int, probeCountBits: Int, bufferless: Boolean, edgeIn: TLEdgeIn, edgeOut: TLEdgeOut) extends Module class TLBroadcastTracker(id: Int, lineBytes: Int, probeCountBits: Int, bufferless: Boolean, edgeIn: TLEdgeIn, edgeOut: TLEdgeOut) extends Module
{ {
val io = new Bundle { val io = new Bundle {

View File

@ -64,7 +64,11 @@ object TLBuffer
b: BufferParams, b: BufferParams,
c: BufferParams, c: BufferParams,
d: BufferParams, d: BufferParams,
e: BufferParams)(implicit p: Parameters): TLNode = LazyModule(new TLBuffer(a, b, c, d, e)).node e: BufferParams)(implicit p: Parameters): TLNode =
{
val buffer = LazyModule(new TLBuffer(a, b, c, d, e))
buffer.node
}
def chain(depth: Int, name: Option[String] = None)(implicit p: Parameters): Seq[TLNode] = { def chain(depth: Int, name: Option[String] = None)(implicit p: Parameters): Seq[TLNode] = {
val buffers = Seq.fill(depth) { LazyModule(new TLBuffer()) } val buffers = Seq.fill(depth) { LazyModule(new TLBuffer()) }

View File

@ -121,5 +121,9 @@ class TLCacheCork(unsafe: Boolean = false)(implicit p: Parameters) extends LazyM
object TLCacheCork object TLCacheCork
{ {
def apply(unsafe: Boolean = false)(implicit p: Parameters): TLNode = LazyModule(new TLCacheCork(unsafe)).node def apply(unsafe: Boolean = false)(implicit p: Parameters): TLNode =
{
val cork = LazyModule(new TLCacheCork(unsafe))
cork.node
}
} }

View File

@ -72,5 +72,9 @@ class TLDelayer(q: Double)(implicit p: Parameters) extends LazyModule
object TLDelayer object TLDelayer
{ {
def apply(q: Double)(implicit p: Parameters): TLNode = LazyModule(new TLDelayer(q)).node def apply(q: Double)(implicit p: Parameters): TLNode =
{
val delayer = LazyModule(new TLDelayer(q))
delayer.node
}
} }

View File

@ -62,5 +62,8 @@ class TLErrorEvaluator(test: RequestPattern, testOn: Boolean, testOff: Boolean)(
object TLErrorEvaluator object TLErrorEvaluator
{ {
def apply(test: RequestPattern, testOn: Boolean = false, testOff: Boolean = false)(implicit p: Parameters): TLNode = def apply(test: RequestPattern, testOn: Boolean = false, testOff: Boolean = false)(implicit p: Parameters): TLNode =
LazyModule(new TLErrorEvaluator(test, testOn, testOff)).node {
val errors = LazyModule(new TLErrorEvaluator(test, testOn, testOff))
errors.node
}
} }

View File

@ -113,5 +113,9 @@ object TLFIFOFixer
val allFIFO: Policy = m => m.fifoId.isDefined val allFIFO: Policy = m => m.fifoId.isDefined
val allUncacheable: Policy = m => m.regionType <= UNCACHEABLE val allUncacheable: Policy = m => m.regionType <= UNCACHEABLE
def apply(policy: Policy = all)(implicit p: Parameters): TLNode = LazyModule(new TLFIFOFixer(policy)).node def apply(policy: Policy = all)(implicit p: Parameters): TLNode =
{
val fixer = LazyModule(new TLFIFOFixer(policy))
fixer.node
}
} }

View File

@ -91,5 +91,9 @@ object TLFilter
def apply( def apply(
Mfilter: TLManagerParameters => Option[TLManagerParameters] = TLFilter.Midentity, Mfilter: TLManagerParameters => Option[TLManagerParameters] = TLFilter.Midentity,
Cfilter: TLClientParameters => Option[TLClientParameters] = TLFilter.Cidentity Cfilter: TLClientParameters => Option[TLClientParameters] = TLFilter.Cidentity
)(implicit p: Parameters): TLNode = LazyModule(new TLFilter(Mfilter, Cfilter)).node )(implicit p: Parameters): TLNode =
{
val filter = LazyModule(new TLFilter(Mfilter, Cfilter))
filter.node
}
} }

View File

@ -294,7 +294,10 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean =
object TLFragmenter object TLFragmenter
{ {
def apply(minSize: Int, maxSize: Int, alwaysMin: Boolean = false, earlyAck: EarlyAck.T = EarlyAck.None)(implicit p: Parameters): TLNode = def apply(minSize: Int, maxSize: Int, alwaysMin: Boolean = false, earlyAck: EarlyAck.T = EarlyAck.None)(implicit p: Parameters): TLNode =
LazyModule(new TLFragmenter(minSize, maxSize, alwaysMin, earlyAck)).node {
val fragmenter = LazyModule(new TLFragmenter(minSize, maxSize, alwaysMin, earlyAck))
fragmenter.node
}
} }
/** Synthesizeable unit tests */ /** Synthesizeable unit tests */
@ -324,5 +327,6 @@ class TLRAMFragmenter(ramBeatBytes: Int, maxSize: Int, txns: Int)(implicit p: Pa
} }
class TLRAMFragmenterTest(ramBeatBytes: Int, maxSize: Int, txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) { class TLRAMFragmenterTest(ramBeatBytes: Int, maxSize: Int, txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) {
io.finished := Module(LazyModule(new TLRAMFragmenter(ramBeatBytes,maxSize,txns)).module).io.finished val dut = Module(LazyModule(new TLRAMFragmenter(ramBeatBytes,maxSize,txns)).module)
io.finished := dut.io.finished
} }

View File

@ -221,6 +221,24 @@ class TLFuzzer(
} }
} }
object TLFuzzer
{
def apply(
nOperations: Int,
inFlight: Int = 32,
noiseMaker: (Int, Bool, Int) => UInt = {
(wide: Int, increment: Bool, abs_values: Int) =>
LFSRNoiseMaker(wide=wide, increment=increment)
},
noModify: Boolean = false,
overrideAddress: Option[AddressSet] = None,
nOrdered: Option[Int] = None)(implicit p: Parameters): TLOutwardNode =
{
val fuzzer = LazyModule(new TLFuzzer(nOperations, inFlight, noiseMaker, noModify, overrideAddress, nOrdered))
fuzzer.node
}
}
/** Synthesizeable integration test */ /** Synthesizeable integration test */
import freechips.rocketchip.unittest._ import freechips.rocketchip.unittest._

View File

@ -92,7 +92,10 @@ class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = f
object TLHintHandler object TLHintHandler
{ {
def apply(supportManagers: Boolean = true, supportClients: Boolean = false, passthrough: Boolean = true)(implicit p: Parameters): TLNode = def apply(supportManagers: Boolean = true, supportClients: Boolean = false, passthrough: Boolean = true)(implicit p: Parameters): TLNode =
LazyModule(new TLHintHandler(supportManagers, supportClients, passthrough)).node {
val hints = LazyModule(new TLHintHandler(supportManagers, supportClients, passthrough))
hints.node
}
} }
/** Synthesizeable unit tests */ /** Synthesizeable unit tests */
@ -119,5 +122,6 @@ class TLRAMHintHandler(txns: Int)(implicit p: Parameters) extends LazyModule {
} }
class TLRAMHintHandlerTest(txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) { class TLRAMHintHandlerTest(txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) {
io.finished := Module(LazyModule(new TLRAMHintHandler(txns)).module).io.finished val dut = Module(LazyModule(new TLRAMHintHandler(txns)).module)
io.finished := dut.io.finished
} }

View File

@ -38,5 +38,9 @@ class TLMap(fn: AddressSet => BigInt)(implicit p: Parameters) extends LazyModule
object TLMap object TLMap
{ {
def apply(fn: AddressSet => BigInt)(implicit p: Parameters): TLNode = LazyModule(new TLMap(fn)).node def apply(fn: AddressSet => BigInt)(implicit p: Parameters): TLNode =
{
val map = LazyModule(new TLMap(fn))
map.node
}
} }

View File

@ -6,7 +6,7 @@ import Chisel._
import freechips.rocketchip.config.Parameters import freechips.rocketchip.config.Parameters
import freechips.rocketchip.diplomacy._ import freechips.rocketchip.diplomacy._
case class TLNodeNumbererNode(nodeAddressOffset: Option[Int] = None)(implicit valName: ValName) extends TLCustomNode(0 to 999, 0 to 999) case class TLNodeNumbererNode(nodeAddressOffset: Option[Int] = None)(implicit valName: ValName) extends TLCustomNode
{ {
def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = { def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
require (oStars + iStars <= 1, s"${name} (a custom adapter) appears left of a :*= ${iStars} times and right of a :=* ${oStars} times; at most once is allowed${lazyModule.line}") require (oStars + iStars <= 1, s"${name} (a custom adapter) appears left of a :*= ${iStars} times and right of a :=* ${oStars} times; at most once is allowed${lazyModule.line}")
@ -55,5 +55,9 @@ class TLNodeNumberer(nodeAddressOffset: Option[Int] = None)(implicit p: Paramete
object TLNodeNumberer object TLNodeNumberer
{ {
def apply(nodeAddressOffset: Option[Int] = None)(implicit p: Parameters): TLNode = LazyModule(new TLNodeNumberer(nodeAddressOffset)).node def apply(nodeAddressOffset: Option[Int] = None)(implicit p: Parameters): TLNode =
{
val numberer = LazyModule(new TLNodeNumberer(nodeAddressOffset))
numberer.node
}
} }

View File

@ -49,26 +49,20 @@ case class TLManagerNode(portParams: Seq[TLManagerPortParameters])(implicit valN
case class TLAdapterNode( case class TLAdapterNode(
clientFn: TLClientPortParameters => TLClientPortParameters = { s => s }, clientFn: TLClientPortParameters => TLClientPortParameters = { s => s },
managerFn: TLManagerPortParameters => TLManagerPortParameters = { s => s }, managerFn: TLManagerPortParameters => TLManagerPortParameters = { s => s })(
num: Range.Inclusive = 0 to 999)(
implicit valName: ValName) implicit valName: ValName)
extends AdapterNode(TLImp)(clientFn, managerFn, num) extends AdapterNode(TLImp)(clientFn, managerFn)
case class TLIdentityNode()(implicit valName: ValName) extends IdentityNode(TLImp)() case class TLIdentityNode()(implicit valName: ValName) extends IdentityNode(TLImp)()
case class TLNexusNode( case class TLNexusNode(
clientFn: Seq[TLClientPortParameters] => TLClientPortParameters, clientFn: Seq[TLClientPortParameters] => TLClientPortParameters,
managerFn: Seq[TLManagerPortParameters] => TLManagerPortParameters, managerFn: Seq[TLManagerPortParameters] => TLManagerPortParameters)(
numClientPorts: Range.Inclusive = 1 to 999,
numManagerPorts: Range.Inclusive = 1 to 999)(
implicit valName: ValName) implicit valName: ValName)
extends NexusNode(TLImp)(clientFn, managerFn, numClientPorts, numManagerPorts) extends NexusNode(TLImp)(clientFn, managerFn)
abstract class TLCustomNode( abstract class TLCustomNode(implicit valName: ValName)
numClientPorts: Range.Inclusive, extends CustomNode(TLImp)
numManagerPorts: Range.Inclusive)(
implicit valName: ValName)
extends CustomNode(TLImp)(numClientPorts, numManagerPorts)
// Asynchronous crossings // Asynchronous crossings
@ -86,10 +80,9 @@ object TLAsyncImp extends SimpleNodeImp[TLAsyncClientPortParameters, TLAsyncMana
case class TLAsyncAdapterNode( case class TLAsyncAdapterNode(
clientFn: TLAsyncClientPortParameters => TLAsyncClientPortParameters = { s => s }, clientFn: TLAsyncClientPortParameters => TLAsyncClientPortParameters = { s => s },
managerFn: TLAsyncManagerPortParameters => TLAsyncManagerPortParameters = { s => s }, managerFn: TLAsyncManagerPortParameters => TLAsyncManagerPortParameters = { s => s })(
num: Range.Inclusive = 0 to 999)(
implicit valName: ValName) implicit valName: ValName)
extends AdapterNode(TLAsyncImp)(clientFn, managerFn, num) extends AdapterNode(TLAsyncImp)(clientFn, managerFn)
case class TLAsyncIdentityNode()(implicit valName: ValName) extends IdentityNode(TLAsyncImp)() case class TLAsyncIdentityNode()(implicit valName: ValName) extends IdentityNode(TLAsyncImp)()
@ -119,10 +112,9 @@ object TLRationalImp extends SimpleNodeImp[TLRationalClientPortParameters, TLRat
case class TLRationalAdapterNode( case class TLRationalAdapterNode(
clientFn: TLRationalClientPortParameters => TLRationalClientPortParameters = { s => s }, clientFn: TLRationalClientPortParameters => TLRationalClientPortParameters = { s => s },
managerFn: TLRationalManagerPortParameters => TLRationalManagerPortParameters = { s => s }, managerFn: TLRationalManagerPortParameters => TLRationalManagerPortParameters = { s => s })(
num: Range.Inclusive = 0 to 999)(
implicit valName: ValName) implicit valName: ValName)
extends AdapterNode(TLRationalImp)(clientFn, managerFn, num) extends AdapterNode(TLRationalImp)(clientFn, managerFn)
case class TLRationalIdentityNode()(implicit valName: ValName) extends IdentityNode(TLRationalImp)() case class TLRationalIdentityNode()(implicit valName: ValName) extends IdentityNode(TLRationalImp)()

View File

@ -84,3 +84,12 @@ class TLPatternPusher(name: String, pattern: Seq[Pattern])(implicit p: Parameter
tl_out.e.valid := Bool(false) tl_out.e.valid := Bool(false)
} }
} }
object TLPatternPusher
{
def apply(name: String, pattern: Seq[Pattern])(implicit p: Parameters): TLOutwardNode =
{
val pusher = LazyModule(new TLPatternPusher(name, pattern))
pusher.node
}
}

View File

@ -333,8 +333,11 @@ class TLRAMModel(log: String = "", ignoreErrorData: Boolean = false)(implicit p:
object TLRAMModel object TLRAMModel
{ {
def apply(log: String = "", ignoreErrorData: Boolean = false)(implicit p: Parameters) = def apply(log: String = "", ignoreErrorData: Boolean = false)(implicit p: Parameters): TLNode =
LazyModule(new TLRAMModel(log, ignoreErrorData)).node {
val model = LazyModule(new TLRAMModel(log, ignoreErrorData))
model.node
}
case class MonitorParameters(addressBits: Int, sizeBits: Int) case class MonitorParameters(addressBits: Int, sizeBits: Int)

View File

@ -78,12 +78,20 @@ class TLRationalCrossingSink(direction: RationalDirection = Symmetric)(implicit
object TLRationalCrossingSource object TLRationalCrossingSource
{ {
def apply()(implicit p: Parameters) = LazyModule(new TLRationalCrossingSource).node def apply()(implicit p: Parameters) =
{
val rsource = LazyModule(new TLRationalCrossingSource)
rsource.node
}
} }
object TLRationalCrossingSink object TLRationalCrossingSink
{ {
def apply(direction: RationalDirection = Symmetric)(implicit p: Parameters) = LazyModule(new TLRationalCrossingSink(direction)).node def apply(direction: RationalDirection = Symmetric)(implicit p: Parameters) =
{
val rsink = LazyModule(new TLRationalCrossingSink(direction))
rsink.node
}
} }
@deprecated("TLRationalCrossing is fragile. Use TLRationalCrossingSource and TLRationalCrossingSink", "rocket-chip 1.2") @deprecated("TLRationalCrossing is fragile. Use TLRationalCrossingSource and TLRationalCrossingSink", "rocket-chip 1.2")
@ -189,5 +197,6 @@ class TLRAMRationalCrossing(txns: Int)(implicit p: Parameters) extends LazyModul
} }
class TLRAMRationalCrossingTest(txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) { class TLRAMRationalCrossingTest(txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) {
io.finished := Module(LazyModule(new TLRAMRationalCrossing(txns)).module).io.finished val dut = Module(LazyModule(new TLRAMRationalCrossing(txns)).module)
io.finished := dut.io.finished
} }

View File

@ -268,7 +268,8 @@ class FuzzRRTest0(txns: Int)(implicit p: Parameters) extends LazyModule {
} }
class TLRR0Test(txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) { class TLRR0Test(txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) {
io.finished := Module(LazyModule(new FuzzRRTest0(txns)).module).io.finished val dut = Module(LazyModule(new FuzzRRTest0(txns)).module)
io.finished := dut.io.finished
} }
class FuzzRRTest1(txns: Int)(implicit p: Parameters) extends LazyModule { class FuzzRRTest1(txns: Int)(implicit p: Parameters) extends LazyModule {
@ -283,6 +284,7 @@ class FuzzRRTest1(txns: Int)(implicit p: Parameters) extends LazyModule {
} }
class TLRR1Test(txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) { class TLRR1Test(txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) {
io.finished := Module(LazyModule(new FuzzRRTest1(txns)).module).io.finished val dut = Module(LazyModule(new FuzzRRTest1(txns)).module)
io.finished := dut.io.finished
} }

View File

@ -81,6 +81,21 @@ class TLRAM(
} }
} }
object TLRAM
{
def apply(
address: AddressSet,
cacheable: Boolean = true,
executable: Boolean = true,
beatBytes: Int = 4,
devName: Option[String] = None,
errors: Seq[AddressSet] = Nil)(implicit p: Parameters): TLInwardNode =
{
val ram = LazyModule(new TLRAM(address, cacheable, executable, beatBytes, devName, errors))
ram.node
}
}
/** Synthesizeable unit testing */ /** Synthesizeable unit testing */
import freechips.rocketchip.unittest._ import freechips.rocketchip.unittest._
@ -97,5 +112,6 @@ class TLRAMSimple(ramBeatBytes: Int, txns: Int)(implicit p: Parameters) extends
} }
class TLRAMSimpleTest(ramBeatBytes: Int, txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) { class TLRAMSimpleTest(ramBeatBytes: Int, txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) {
io.finished := Module(LazyModule(new TLRAMSimple(ramBeatBytes, txns)).module).io.finished val dut = Module(LazyModule(new TLRAMSimple(ramBeatBytes, txns)).module)
io.finished := dut.io.finished
} }

View File

@ -74,5 +74,9 @@ class TLSourceShrinker(maxInFlight: Int)(implicit p: Parameters) extends LazyMod
object TLSourceShrinker object TLSourceShrinker
{ {
def apply(maxInFlight: Int)(implicit p: Parameters): TLNode = LazyModule(new TLSourceShrinker(maxInFlight)).node def apply(maxInFlight: Int)(implicit p: Parameters): TLNode =
{
val shrinker = LazyModule(new TLSourceShrinker(maxInFlight))
shrinker.node
}
} }

View File

@ -9,11 +9,9 @@ import freechips.rocketchip.diplomacy._
case class SplitterArg[T](newSize: Int, ports: Seq[T]) case class SplitterArg[T](newSize: Int, ports: Seq[T])
case class TLSplitterNode( case class TLSplitterNode(
clientFn: SplitterArg[TLClientPortParameters] => Seq[TLClientPortParameters], clientFn: SplitterArg[TLClientPortParameters] => Seq[TLClientPortParameters],
managerFn: SplitterArg[TLManagerPortParameters] => Seq[TLManagerPortParameters], managerFn: SplitterArg[TLManagerPortParameters] => Seq[TLManagerPortParameters])(
numClientPorts: Range.Inclusive = 0 to 999,
numManagerPorts: Range.Inclusive = 0 to 999)(
implicit valName: ValName) implicit valName: ValName)
extends TLCustomNode(numClientPorts, numManagerPorts) extends TLCustomNode
{ {
def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = { def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
require (oKnown == 0, s"${name} (a splitter) appears right of a := or :*=; use a :=* instead${lazyModule.line}") require (oKnown == 0, s"${name} (a splitter) appears right of a := or :*=; use a :=* instead${lazyModule.line}")

View File

@ -186,5 +186,9 @@ class TLToAHB(val aFlow: Boolean = false)(implicit p: Parameters) extends LazyMo
object TLToAHB object TLToAHB
{ {
def apply(aFlow: Boolean = true)(implicit p: Parameters) = LazyModule(new TLToAHB(aFlow)).node def apply(aFlow: Boolean = true)(implicit p: Parameters) =
{
val tl2ahb = LazyModule(new TLToAHB(aFlow))
tl2ahb.node
}
} }

View File

@ -85,5 +85,9 @@ class TLToAPB(val aFlow: Boolean = true)(implicit p: Parameters) extends LazyMod
object TLToAPB object TLToAPB
{ {
def apply(aFlow: Boolean = true)(implicit p: Parameters) = LazyModule(new TLToAPB(aFlow)).node def apply(aFlow: Boolean = true)(implicit p: Parameters) =
{
val tl2apb = LazyModule(new TLToAPB(aFlow))
tl2apb.node
}
} }

View File

@ -227,7 +227,10 @@ class TLToAXI4(val combinational: Boolean = true, val adapterName: Option[String
object TLToAXI4 object TLToAXI4
{ {
def apply(combinational: Boolean = true, adapterName: Option[String] = None, stripBits: Int = 0)(implicit p: Parameters) = def apply(combinational: Boolean = true, adapterName: Option[String] = None, stripBits: Int = 0)(implicit p: Parameters) =
LazyModule(new TLToAXI4(combinational, adapterName, stripBits)).node {
val tl2axi4 = LazyModule(new TLToAXI4(combinational, adapterName, stripBits))
tl2axi4.node
}
def sortByType(a: TLClientParameters, b: TLClientParameters): Boolean = { def sortByType(a: TLClientParameters, b: TLClientParameters): Boolean = {
if ( a.supportsProbe && !b.supportsProbe) return false if ( a.supportsProbe && !b.supportsProbe) return false

View File

@ -184,7 +184,11 @@ class TLWidthWidget(innerBeatBytes: Int)(implicit p: Parameters) extends LazyMod
object TLWidthWidget object TLWidthWidget
{ {
def apply(innerBeatBytes: Int)(implicit p: Parameters): TLNode = LazyModule(new TLWidthWidget(innerBeatBytes)).node def apply(innerBeatBytes: Int)(implicit p: Parameters): TLNode =
{
val widget = LazyModule(new TLWidthWidget(innerBeatBytes))
widget.node
}
} }
/** Synthesizeable unit tests */ /** Synthesizeable unit tests */
@ -210,5 +214,6 @@ class TLRAMWidthWidget(first: Int, second: Int, txns: Int)(implicit p: Parameter
} }
class TLRAMWidthWidgetTest(little: Int, big: Int, txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) { class TLRAMWidthWidgetTest(little: Int, big: Int, txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) {
io.finished := Module(LazyModule(new TLRAMWidthWidget(little,big,txns)).module).io.finished val dut = Module(LazyModule(new TLRAMWidthWidget(little,big,txns)).module)
io.finished := dut.io.finished
} }

View File

@ -31,8 +31,6 @@ private case object ForceFanoutKey extends Field(ForceFanoutParams(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(
numClientPorts = 1 to 999,
numManagerPorts = 1 to 999,
clientFn = { seq => clientFn = { seq =>
seq(0).copy( seq(0).copy(
minLatency = seq.map(_.minLatency).min, minLatency = seq.map(_.minLatency).min,
@ -159,20 +157,20 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parame
val addressA = (in zip edgesIn) map { case (i, e) => e.address(i.a.bits) } val addressA = (in zip edgesIn) map { case (i, e) => e.address(i.a.bits) }
val addressC = (in zip edgesIn) map { case (i, e) => e.address(i.c.bits) } val addressC = (in zip edgesIn) map { case (i, e) => e.address(i.c.bits) }
val requestAIO = Vec(addressA.map { i => Vec(outputPorts.map { o => o(i) }) }) val requestAIO = addressA.map { i => outputPorts.map { o => o(i) } }
val requestCIO = Vec(addressC.map { i => Vec(outputPorts.map { o => o(i) }) }) val requestCIO = addressC.map { i => outputPorts.map { o => o(i) } }
val requestBOI = Vec(out.map { o => Vec(inputIdRanges.map { i => i.contains(o.b.bits.source) }) }) val requestBOI = out.map { o => inputIdRanges.map { i => i.contains(o.b.bits.source) } }
val requestDOI = Vec(out.map { o => Vec(inputIdRanges.map { i => i.contains(o.d.bits.source) }) }) val requestDOI = out.map { o => inputIdRanges.map { i => i.contains(o.d.bits.source) } }
val requestEIO = Vec(in.map { i => Vec(outputIdRanges.map { o => o.map(_.contains(i.e.bits.sink)).getOrElse(Bool(false)) }) }) val requestEIO = in.map { i => outputIdRanges.map { o => o.map(_.contains(i.e.bits.sink)).getOrElse(Bool(false)) } }
val beatsAI = Vec((in zip edgesIn) map { case (i, e) => e.numBeats1(i.a.bits) }) val beatsAI = (in zip edgesIn) map { case (i, e) => e.numBeats1(i.a.bits) }
val beatsBO = Vec((out zip edgesOut) map { case (o, e) => e.numBeats1(o.b.bits) }) val beatsBO = (out zip edgesOut) map { case (o, e) => e.numBeats1(o.b.bits) }
val beatsCI = Vec((in zip edgesIn) map { case (i, e) => e.numBeats1(i.c.bits) }) val beatsCI = (in zip edgesIn) map { case (i, e) => e.numBeats1(i.c.bits) }
val beatsDO = Vec((out zip edgesOut) map { case (o, e) => e.numBeats1(o.d.bits) }) val beatsDO = (out zip edgesOut) map { case (o, e) => e.numBeats1(o.d.bits) }
val beatsEI = Vec((in zip edgesIn) map { case (i, e) => e.numBeats1(i.e.bits) }) val beatsEI = (in zip edgesIn) map { case (i, e) => e.numBeats1(i.e.bits) }
// Which pairs support support transfers // Which pairs support support transfers
def transpose[T](x: Seq[Seq[T]]) = Seq.tabulate(x(0).size) { i => Seq.tabulate(x.size) { j => x(j)(i) } } def transpose[T](x: Seq[Seq[T]]) = if (x.isEmpty) Nil else Seq.tabulate(x(0).size) { i => Seq.tabulate(x.size) { j => x(j)(i) } }
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
@ -206,6 +204,12 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parame
object TLXbar object TLXbar
{ {
def apply(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parameters): TLNode =
{
val xbar = LazyModule(new TLXbar(policy))
xbar.node
}
def mapInputIds (ports: Seq[TLClientPortParameters ]) = assignRanges(ports.map(_.endSourceId)).map(_.get) def mapInputIds (ports: Seq[TLClientPortParameters ]) = assignRanges(ports.map(_.endSourceId)).map(_.get)
def mapOutputIds(ports: Seq[TLManagerPortParameters]) = assignRanges(ports.map(_.endSinkId)) def mapOutputIds(ports: Seq[TLManagerPortParameters]) = assignRanges(ports.map(_.endSinkId))
@ -266,7 +270,8 @@ class TLRAMXbar(nManagers: Int, txns: Int)(implicit p: Parameters) extends LazyM
} }
class TLRAMXbarTest(nManagers: Int, txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) { class TLRAMXbarTest(nManagers: Int, txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) {
io.finished := Module(LazyModule(new TLRAMXbar(nManagers,txns)).module).io.finished val dut = Module(LazyModule(new TLRAMXbar(nManagers,txns)).module)
io.finished := dut.io.finished
} }
class TLMulticlientXbar(nManagers: Int, nClients: Int, txns: Int)(implicit p: Parameters) extends LazyModule { class TLMulticlientXbar(nManagers: Int, nClients: Int, txns: Int)(implicit p: Parameters) extends LazyModule {
@ -289,5 +294,6 @@ class TLMulticlientXbar(nManagers: Int, nClients: Int, txns: Int)(implicit p: Pa
} }
class TLMulticlientXbarTest(nManagers: Int, nClients: Int, txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) { class TLMulticlientXbarTest(nManagers: Int, nClients: Int, txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) {
io.finished := Module(LazyModule(new TLMulticlientXbar(nManagers, nClients, txns)).module).io.finished val dut = Module(LazyModule(new TLMulticlientXbar(nManagers, nClients, txns)).module)
io.finished := dut.io.finished
} }

View File

@ -7,7 +7,7 @@ import freechips.rocketchip.diplomacy._
package object tilelink package object tilelink
{ {
type TLInwardNode = InwardNodeHandle[TLClientPortParameters, TLManagerPortParameters, TLBundle] type TLInwardNode = InwardNodeHandle[TLClientPortParameters, TLManagerPortParameters, TLEdgeIn, TLBundle]
type TLOutwardNode = OutwardNodeHandle[TLClientPortParameters, TLManagerPortParameters, TLBundle] type TLOutwardNode = OutwardNodeHandle[TLClientPortParameters, TLManagerPortParameters, TLEdgeOut, TLBundle]
type TLNode = SimpleNodeHandle[TLClientPortParameters, TLManagerPortParameters, TLBundle] type TLNode = NodeHandle[TLClientPortParameters, TLManagerPortParameters, TLEdgeIn, TLBundle, TLClientPortParameters, TLManagerPortParameters, TLEdgeOut, TLBundle]
} }

View File

@ -0,0 +1,35 @@
// See LICENSE.SiFive for license details.
package freechips.rocketchip.unittest
import Chisel._
import freechips.rocketchip.config._
import freechips.rocketchip.diplomacy._
abstract class LazyUnitTest(implicit p: Parameters) extends LazyModule
{ self =>
protected def finished: Bool
lazy val module = new LazyModuleImp(this) {
val finished = IO(Bool(OUTPUT))
finished := self.finished
}
}
// FYI, you can call .finished on a Seq[LazyUnitTest]
class TestGenerator(gen: LazyModule => Seq[LazyUnitTest])
{
def apply(lm: LazyModule) = gen(lm)
def ++ (other: TestGenerator) = new TestGenerator(gen = lm => gen(lm) ++ other(lm))
}
object TestGenerator
{
def apply(matcher: PartialFunction[LazyModule, Seq[LazyUnitTest]]): TestGenerator =
new TestGenerator(gen = matcher.lift(_).getOrElse(Nil))
def recurse(other: TestGenerator): TestGenerator = {
def helper(lm: LazyModule, tail: Seq[LazyUnitTest]): Seq[LazyUnitTest] =
lm.getChildren.foldLeft(other(lm) ++ tail) { case (tail, child) => helper(child, tail) }
new TestGenerator(gen = helper(_, Nil))
}
}

View File

@ -0,0 +1,12 @@
// See LICENSE.SiFive for license details.
package freechips.rocketchip
import Chisel._
package object unittest
{
implicit class LazyUnitTestSeq(val seq: Seq[LazyUnitTest]) {
def finished = seq.map(_.module.finished).foldLeft(Bool(true))(_ && _)
}
}