diplomacy: change API to auto-create node bundles => cross-module refs
This commit is contained in:
parent
53f6999ea8
commit
9217baf9d4
@ -4,12 +4,13 @@ package freechips.rocketchip.amba.ahb
|
|||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import chisel3.internal.sourceinfo.SourceInfo
|
import chisel3.internal.sourceinfo.SourceInfo
|
||||||
|
import freechips.rocketchip.config.Parameters
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
|
|
||||||
object AHBImp extends NodeImp[AHBMasterPortParameters, AHBSlavePortParameters, AHBEdgeParameters, AHBEdgeParameters, AHBBundle]
|
object AHBImp extends NodeImp[AHBMasterPortParameters, AHBSlavePortParameters, AHBEdgeParameters, AHBEdgeParameters, AHBBundle]
|
||||||
{
|
{
|
||||||
def edgeO(pd: AHBMasterPortParameters, pu: AHBSlavePortParameters): AHBEdgeParameters = AHBEdgeParameters(pd, pu)
|
def edgeO(pd: AHBMasterPortParameters, pu: AHBSlavePortParameters, p: Parameters): AHBEdgeParameters = AHBEdgeParameters(pd, pu, p)
|
||||||
def edgeI(pd: AHBMasterPortParameters, pu: AHBSlavePortParameters): AHBEdgeParameters = AHBEdgeParameters(pd, pu)
|
def edgeI(pd: AHBMasterPortParameters, pu: AHBSlavePortParameters, p: Parameters): AHBEdgeParameters = AHBEdgeParameters(pd, pu, p)
|
||||||
|
|
||||||
def bundleO(eo: AHBEdgeParameters): AHBBundle = AHBBundle(eo.bundle)
|
def bundleO(eo: AHBEdgeParameters): AHBBundle = AHBBundle(eo.bundle)
|
||||||
def bundleI(ei: AHBEdgeParameters): AHBBundle = AHBBundle(ei.bundle)
|
def bundleI(ei: AHBEdgeParameters): AHBBundle = AHBBundle(ei.bundle)
|
||||||
@ -25,7 +26,6 @@ object AHBImp extends NodeImp[AHBMasterPortParameters, AHBSlavePortParameters, A
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Nodes implemented inside modules
|
// Nodes implemented inside modules
|
||||||
case class AHBIdentityNode()(implicit valName: ValName) extends IdentityNode(AHBImp)
|
|
||||||
case class AHBMasterNode(portParams: Seq[AHBMasterPortParameters])(implicit valName: ValName) extends SourceNode(AHBImp)(portParams)
|
case class AHBMasterNode(portParams: Seq[AHBMasterPortParameters])(implicit valName: ValName) extends SourceNode(AHBImp)(portParams)
|
||||||
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(
|
||||||
@ -36,13 +36,4 @@ case class AHBNexusNode(
|
|||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends NexusNode(AHBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts)
|
extends NexusNode(AHBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts)
|
||||||
|
|
||||||
// Nodes passed from an inner module
|
case class AHBIdentityNode()(implicit valName: ValName) extends IdentityNode(AHBImp)()
|
||||||
case class AHBOutputNode()(implicit valName: ValName) extends OutputNode(AHBImp)
|
|
||||||
case class AHBInputNode()(implicit valName: ValName) extends InputNode(AHBImp)
|
|
||||||
|
|
||||||
// Nodes used for external ports
|
|
||||||
case class AHBBlindOutputNode(portParams: Seq[AHBSlavePortParameters])(implicit valName: ValName) extends BlindOutputNode(AHBImp)(portParams)
|
|
||||||
case class AHBBlindInputNode(portParams: Seq[AHBMasterPortParameters])(implicit valName: ValName) extends BlindInputNode(AHBImp)(portParams)
|
|
||||||
|
|
||||||
case class AHBInternalOutputNode(portParams: Seq[AHBSlavePortParameters])(implicit valName: ValName) extends InternalOutputNode(AHBImp)(portParams)
|
|
||||||
case class AHBInternalInputNode(portParams: Seq[AHBMasterPortParameters])(implicit valName: ValName) extends InternalInputNode(AHBImp)(portParams)
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
package freechips.rocketchip.amba.ahb
|
package freechips.rocketchip.amba.ahb
|
||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
|
import freechips.rocketchip.config.Parameters
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import scala.math.max
|
import scala.math.max
|
||||||
|
|
||||||
@ -90,7 +91,8 @@ object AHBBundleParameters
|
|||||||
|
|
||||||
case class AHBEdgeParameters(
|
case class AHBEdgeParameters(
|
||||||
master: AHBMasterPortParameters,
|
master: AHBMasterPortParameters,
|
||||||
slave: AHBSlavePortParameters)
|
slave: AHBSlavePortParameters,
|
||||||
|
params: Parameters)
|
||||||
{
|
{
|
||||||
val bundle = AHBBundleParameters(master, slave)
|
val bundle = AHBBundleParameters(master, slave)
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ case class AHBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes:
|
|||||||
// Calling this method causes the matching AHB bundle to be
|
// Calling this method causes the matching AHB bundle to be
|
||||||
// configured to route all requests to the listed RegFields.
|
// configured to route all requests to the listed RegFields.
|
||||||
def regmap(mapping: RegField.Map*) = {
|
def regmap(mapping: RegField.Map*) = {
|
||||||
val ahb = bundleIn(0)
|
val (ahb, _) = this.in(0)
|
||||||
|
|
||||||
val indexBits = log2Up((address.mask+1)/beatBytes)
|
val indexBits = log2Up((address.mask+1)/beatBytes)
|
||||||
val params = RegMapperParams(indexBits, beatBytes, 1)
|
val params = RegMapperParams(indexBits, beatBytes, 1)
|
||||||
@ -76,13 +76,11 @@ abstract class AHBRegisterRouterBase(address: AddressSet, interrupts: Int, concu
|
|||||||
val intnode = IntSourceNode(IntSourcePortSimple(num = interrupts))
|
val intnode = IntSourceNode(IntSourcePortSimple(num = interrupts))
|
||||||
}
|
}
|
||||||
|
|
||||||
case class AHBRegBundleArg(interrupts: HeterogeneousBag[Vec[Bool]], in: HeterogeneousBag[AHBBundle])(implicit val p: Parameters)
|
case class AHBRegBundleArg()(implicit val p: Parameters)
|
||||||
|
|
||||||
class AHBRegBundleBase(arg: AHBRegBundleArg) extends Bundle
|
class AHBRegBundleBase(arg: AHBRegBundleArg) extends Bundle
|
||||||
{
|
{
|
||||||
implicit val p = arg.p
|
implicit val p = arg.p
|
||||||
val interrupts = arg.interrupts
|
|
||||||
val in = arg.in
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class AHBRegBundle[P](val params: P, arg: AHBRegBundleArg) extends AHBRegBundleBase(arg)
|
class AHBRegBundle[P](val params: P, arg: AHBRegBundleArg) extends AHBRegBundleBase(arg)
|
||||||
@ -90,8 +88,8 @@ class AHBRegBundle[P](val params: P, arg: AHBRegBundleArg) extends AHBRegBundleB
|
|||||||
class AHBRegModule[P, B <: AHBRegBundleBase](val params: P, bundleBuilder: => B, router: AHBRegisterRouterBase)
|
class AHBRegModule[P, B <: AHBRegBundleBase](val params: P, bundleBuilder: => B, router: AHBRegisterRouterBase)
|
||||||
extends LazyModuleImp(router) with HasRegMap
|
extends LazyModuleImp(router) with HasRegMap
|
||||||
{
|
{
|
||||||
val io = bundleBuilder
|
val io = IO(bundleBuilder)
|
||||||
val interrupts = if (io.interrupts.isEmpty) Vec(0, Bool()) else io.interrupts(0)
|
val interrupts = if (router.intnode.in.isEmpty) Vec(0, Bool()) else router.intnode.in(0)._1
|
||||||
def regmap(mapping: RegField.Map*) = router.node.regmap(mapping:_*)
|
def regmap(mapping: RegField.Map*) = router.node.regmap(mapping:_*)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,5 +102,5 @@ class AHBRegisterRouter[B <: AHBRegBundleBase, M <: LazyModuleImp]
|
|||||||
require (isPow2(size))
|
require (isPow2(size))
|
||||||
// require (size >= 4096) ... not absolutely required, but highly recommended
|
// require (size >= 4096) ... not absolutely required, but highly recommended
|
||||||
|
|
||||||
lazy val module = moduleBuilder(bundleBuilder(AHBRegBundleArg(intnode.bundleOut, node.bundleIn)), this)
|
lazy val module = moduleBuilder(bundleBuilder(AHBRegBundleArg()), this)
|
||||||
}
|
}
|
||||||
|
@ -22,15 +22,11 @@ class AHBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4
|
|||||||
require ((address.mask & (beatBytes-1)) == beatBytes-1)
|
require ((address.mask & (beatBytes-1)) == beatBytes-1)
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
|
||||||
val in = node.bundleIn
|
|
||||||
}
|
|
||||||
|
|
||||||
def bigBits(x: BigInt, tail: List[Boolean] = List.empty[Boolean]): List[Boolean] =
|
def bigBits(x: BigInt, tail: List[Boolean] = List.empty[Boolean]): List[Boolean] =
|
||||||
if (x == 0) tail.reverse else bigBits(x >> 1, ((x & 1) == 1) :: tail)
|
if (x == 0) tail.reverse else bigBits(x >> 1, ((x & 1) == 1) :: tail)
|
||||||
val mask = bigBits(address.mask >> log2Ceil(beatBytes))
|
val mask = bigBits(address.mask >> log2Ceil(beatBytes))
|
||||||
|
|
||||||
val in = io.in(0)
|
val (in, _) = node.in(0)
|
||||||
|
|
||||||
// The mask and address during the address phase
|
// The mask and address during the address phase
|
||||||
val a_access = in.htrans === AHBParameters.TRANS_NONSEQ || in.htrans === AHBParameters.TRANS_SEQ
|
val a_access = in.htrans === AHBParameters.TRANS_NONSEQ || in.htrans === AHBParameters.TRANS_SEQ
|
||||||
|
@ -30,7 +30,7 @@ class AHBFuzzNative(aFlow: Boolean, txns: Int)(implicit p: Parameters) extends L
|
|||||||
ram.node := xbar.node
|
ram.node := xbar.node
|
||||||
gpio.node := xbar.node
|
gpio.node := xbar.node
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) with HasUnitTestIO {
|
lazy val module = new LazyModuleImp(this) with UnitTestModule {
|
||||||
io.finished := fuzz.module.io.finished
|
io.finished := fuzz.module.io.finished
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -42,7 +42,7 @@ class AHBNativeTest(aFlow: Boolean, txns: Int = 5000, timeout: Int = 500000)(imp
|
|||||||
|
|
||||||
class AHBFuzzMaster(aFlow: Boolean, txns: Int)(implicit p: Parameters) extends LazyModule
|
class AHBFuzzMaster(aFlow: Boolean, txns: Int)(implicit p: Parameters) extends LazyModule
|
||||||
{
|
{
|
||||||
val node = AHBOutputNode()
|
val node = AHBIdentityNode()
|
||||||
val fuzz = LazyModule(new TLFuzzer(txns))
|
val fuzz = LazyModule(new TLFuzzer(txns))
|
||||||
val model = LazyModule(new TLRAMModel("AHBFuzzMaster"))
|
val model = LazyModule(new TLRAMModel("AHBFuzzMaster"))
|
||||||
|
|
||||||
@ -55,10 +55,9 @@ class AHBFuzzMaster(aFlow: Boolean, txns: Int)(implicit p: Parameters) extends L
|
|||||||
model.node))))
|
model.node))))
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
val io = IO(new Bundle {
|
||||||
val out = node.bundleOut
|
|
||||||
val finished = Bool(OUTPUT)
|
val finished = Bool(OUTPUT)
|
||||||
}
|
})
|
||||||
|
|
||||||
io.finished := fuzz.module.io.finished
|
io.finished := fuzz.module.io.finished
|
||||||
}
|
}
|
||||||
@ -66,7 +65,7 @@ class AHBFuzzMaster(aFlow: Boolean, txns: Int)(implicit p: Parameters) extends L
|
|||||||
|
|
||||||
class AHBFuzzSlave()(implicit p: Parameters) extends LazyModule
|
class AHBFuzzSlave()(implicit p: Parameters) extends LazyModule
|
||||||
{
|
{
|
||||||
val node = AHBInputNode()
|
val node = AHBIdentityNode()
|
||||||
val ram = LazyModule(new TLTestRAM(AddressSet(0x0, 0xfff)))
|
val ram = LazyModule(new TLTestRAM(AddressSet(0x0, 0xfff)))
|
||||||
|
|
||||||
ram.node :=
|
ram.node :=
|
||||||
@ -77,11 +76,7 @@ class AHBFuzzSlave()(implicit p: Parameters) extends LazyModule
|
|||||||
AHBToTL()(
|
AHBToTL()(
|
||||||
node)))))
|
node)))))
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) { }
|
||||||
val io = new Bundle {
|
|
||||||
val in = node.bundleIn
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class AHBFuzzBridge(aFlow: Boolean, txns: Int)(implicit p: Parameters) extends LazyModule
|
class AHBFuzzBridge(aFlow: Boolean, txns: Int)(implicit p: Parameters) extends LazyModule
|
||||||
@ -91,7 +86,7 @@ class AHBFuzzBridge(aFlow: Boolean, txns: Int)(implicit p: Parameters) extends L
|
|||||||
|
|
||||||
slave.node := master.node
|
slave.node := master.node
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) with HasUnitTestIO {
|
lazy val module = new LazyModuleImp(this) with UnitTestModule {
|
||||||
io.finished := master.module.io.finished
|
io.finished := master.module.io.finished
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,12 +41,7 @@ class AHBToTL()(implicit p: Parameters) extends LazyModule
|
|||||||
val node = AHBToTLNode()
|
val node = AHBToTLNode()
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
|
||||||
val beatBytes = edgeOut.manager.beatBytes
|
val beatBytes = edgeOut.manager.beatBytes
|
||||||
|
|
||||||
val d_send = RegInit(Bool(false))
|
val d_send = RegInit(Bool(false))
|
||||||
|
@ -16,35 +16,31 @@ class AHBFanout()(implicit p: Parameters) extends LazyModule {
|
|||||||
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) {
|
||||||
val io = new Bundle {
|
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
// Require consistent bus widths
|
// Require consistent bus widths
|
||||||
val port0 = node.edgesOut(0).slave
|
val (io_out, edgesOut) = node.out.unzip
|
||||||
node.edgesOut.foreach { edge =>
|
val port0 = edgesOut(0).slave
|
||||||
|
edgesOut.foreach { edge =>
|
||||||
val port = edge.slave
|
val port = edge.slave
|
||||||
require (port.beatBytes == port0.beatBytes,
|
require (port.beatBytes == port0.beatBytes,
|
||||||
s"${port.slaves.map(_.name)} ${port.beatBytes} vs ${port0.slaves.map(_.name)} ${port0.beatBytes}")
|
s"${port.slaves.map(_.name)} ${port.beatBytes} vs ${port0.slaves.map(_.name)} ${port0.beatBytes}")
|
||||||
}
|
}
|
||||||
|
|
||||||
val port_addrs = node.edgesOut.map(_.slave.slaves.map(_.address).flatten)
|
val port_addrs = edgesOut.map(_.slave.slaves.map(_.address).flatten)
|
||||||
val routingMask = AddressDecoder(port_addrs)
|
val routingMask = AddressDecoder(port_addrs)
|
||||||
val route_addrs = port_addrs.map(_.map(_.widen(~routingMask)).distinct)
|
val route_addrs = port_addrs.map(_.map(_.widen(~routingMask)).distinct)
|
||||||
|
|
||||||
val in = io.in(0)
|
val (in, _) = node.in(0)
|
||||||
val a_sel = Vec(route_addrs.map(seq => seq.map(_.contains(in.haddr)).reduce(_ || _)))
|
val a_sel = Vec(route_addrs.map(seq => seq.map(_.contains(in.haddr)).reduce(_ || _)))
|
||||||
val d_sel = Reg(a_sel)
|
val d_sel = Reg(a_sel)
|
||||||
|
|
||||||
when (in.hready) { d_sel := a_sel }
|
when (in.hready) { d_sel := a_sel }
|
||||||
(a_sel zip io.out) foreach { case (sel, out) =>
|
(a_sel zip io_out) foreach { case (sel, out) =>
|
||||||
out := in
|
out := in
|
||||||
out.hsel := in.hsel && sel
|
out.hsel := in.hsel && sel
|
||||||
}
|
}
|
||||||
|
|
||||||
in.hreadyout := !Mux1H(d_sel, io.out.map(!_.hreadyout))
|
in.hreadyout := !Mux1H(d_sel, io_out.map(!_.hreadyout))
|
||||||
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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,8 @@ import freechips.rocketchip.diplomacy._
|
|||||||
|
|
||||||
object APBImp extends NodeImp[APBMasterPortParameters, APBSlavePortParameters, APBEdgeParameters, APBEdgeParameters, APBBundle]
|
object APBImp extends NodeImp[APBMasterPortParameters, APBSlavePortParameters, APBEdgeParameters, APBEdgeParameters, APBBundle]
|
||||||
{
|
{
|
||||||
def edgeO(pd: APBMasterPortParameters, pu: APBSlavePortParameters): APBEdgeParameters = APBEdgeParameters(pd, pu)
|
def edgeO(pd: APBMasterPortParameters, pu: APBSlavePortParameters, p: Parameters): APBEdgeParameters = APBEdgeParameters(pd, pu, p)
|
||||||
def edgeI(pd: APBMasterPortParameters, pu: APBSlavePortParameters): APBEdgeParameters = APBEdgeParameters(pd, pu)
|
def edgeI(pd: APBMasterPortParameters, pu: APBSlavePortParameters, p: Parameters): APBEdgeParameters = APBEdgeParameters(pd, pu, p)
|
||||||
|
|
||||||
def bundleO(eo: APBEdgeParameters): APBBundle = APBBundle(eo.bundle)
|
def bundleO(eo: APBEdgeParameters): APBBundle = APBBundle(eo.bundle)
|
||||||
def bundleI(ei: APBEdgeParameters): APBBundle = APBBundle(ei.bundle)
|
def bundleI(ei: APBEdgeParameters): APBBundle = APBBundle(ei.bundle)
|
||||||
@ -25,8 +25,6 @@ object APBImp extends NodeImp[APBMasterPortParameters, APBSlavePortParameters, A
|
|||||||
pu.copy(slaves = pu.slaves.map { m => m.copy (nodePath = node +: m.nodePath) })
|
pu.copy(slaves = pu.slaves.map { m => m.copy (nodePath = node +: m.nodePath) })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nodes implemented inside modules
|
|
||||||
case class APBIdentityNode()(implicit valName: ValName) extends IdentityNode(APBImp)
|
|
||||||
case class APBMasterNode(portParams: Seq[APBMasterPortParameters])(implicit valName: ValName) extends SourceNode(APBImp)(portParams)
|
case class APBMasterNode(portParams: Seq[APBMasterPortParameters])(implicit valName: ValName) extends SourceNode(APBImp)(portParams)
|
||||||
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(
|
||||||
@ -37,13 +35,4 @@ case class APBNexusNode(
|
|||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends NexusNode(APBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts)
|
extends NexusNode(APBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts)
|
||||||
|
|
||||||
// Nodes passed from an inner module
|
case class APBIdentityNode()(implicit valName: ValName) extends IdentityNode(APBImp)()
|
||||||
case class APBOutputNode()(implicit valName: ValName) extends OutputNode(APBImp)
|
|
||||||
case class APBInputNode()(implicit valName: ValName) extends InputNode(APBImp)
|
|
||||||
|
|
||||||
// Nodes used for external ports
|
|
||||||
case class APBBlindOutputNode(portParams: Seq[APBSlavePortParameters])(implicit valName: ValName) extends BlindOutputNode(APBImp)(portParams)
|
|
||||||
case class APBBlindInputNode(portParams: Seq[APBMasterPortParameters])(implicit valName: ValName) extends BlindInputNode(APBImp)(portParams)
|
|
||||||
|
|
||||||
case class APBInternalOutputNode(portParams: Seq[APBSlavePortParameters])(implicit valName: ValName) extends InternalOutputNode(APBImp)(portParams)
|
|
||||||
case class APBInternalInputNode(portParams: Seq[APBMasterPortParameters])(implicit valName: ValName) extends InternalInputNode(APBImp)(portParams)
|
|
||||||
|
@ -78,7 +78,8 @@ object APBBundleParameters
|
|||||||
|
|
||||||
case class APBEdgeParameters(
|
case class APBEdgeParameters(
|
||||||
master: APBMasterPortParameters,
|
master: APBMasterPortParameters,
|
||||||
slave: APBSlavePortParameters)
|
slave: APBSlavePortParameters,
|
||||||
|
params: Parameters)
|
||||||
{
|
{
|
||||||
val bundle = APBBundleParameters(master, slave)
|
val bundle = APBBundleParameters(master, slave)
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ case class APBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes:
|
|||||||
// Calling this method causes the matching APB bundle to be
|
// Calling this method causes the matching APB bundle to be
|
||||||
// configured to route all requests to the listed RegFields.
|
// configured to route all requests to the listed RegFields.
|
||||||
def regmap(mapping: RegField.Map*) = {
|
def regmap(mapping: RegField.Map*) = {
|
||||||
val apb = bundleIn(0)
|
val (apb, _) = this.in(0)
|
||||||
|
|
||||||
val indexBits = log2Up((address.mask+1)/beatBytes)
|
val indexBits = log2Up((address.mask+1)/beatBytes)
|
||||||
val params = RegMapperParams(indexBits, beatBytes, 1)
|
val params = RegMapperParams(indexBits, beatBytes, 1)
|
||||||
@ -60,13 +60,11 @@ abstract class APBRegisterRouterBase(address: AddressSet, interrupts: Int, concu
|
|||||||
val intnode = IntSourceNode(IntSourcePortSimple(num = interrupts))
|
val intnode = IntSourceNode(IntSourcePortSimple(num = interrupts))
|
||||||
}
|
}
|
||||||
|
|
||||||
case class APBRegBundleArg(interrupts: HeterogeneousBag[Vec[Bool]], in: HeterogeneousBag[APBBundle])(implicit val p: Parameters)
|
case class APBRegBundleArg()(implicit val p: Parameters)
|
||||||
|
|
||||||
class APBRegBundleBase(arg: APBRegBundleArg) extends Bundle
|
class APBRegBundleBase(arg: APBRegBundleArg) extends Bundle
|
||||||
{
|
{
|
||||||
implicit val p = arg.p
|
implicit val p = arg.p
|
||||||
val interrupts = arg.interrupts
|
|
||||||
val in = arg.in
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class APBRegBundle[P](val params: P, arg: APBRegBundleArg) extends APBRegBundleBase(arg)
|
class APBRegBundle[P](val params: P, arg: APBRegBundleArg) extends APBRegBundleBase(arg)
|
||||||
@ -74,8 +72,8 @@ class APBRegBundle[P](val params: P, arg: APBRegBundleArg) extends APBRegBundleB
|
|||||||
class APBRegModule[P, B <: APBRegBundleBase](val params: P, bundleBuilder: => B, router: APBRegisterRouterBase)
|
class APBRegModule[P, B <: APBRegBundleBase](val params: P, bundleBuilder: => B, router: APBRegisterRouterBase)
|
||||||
extends LazyModuleImp(router) with HasRegMap
|
extends LazyModuleImp(router) with HasRegMap
|
||||||
{
|
{
|
||||||
val io = bundleBuilder
|
val io = IO(bundleBuilder)
|
||||||
val interrupts = if (io.interrupts.isEmpty) Vec(0, Bool()) else io.interrupts(0)
|
val interrupts = if (router.intnode.in.isEmpty) Vec(0, Bool()) else router.intnode.in(0)._1
|
||||||
def regmap(mapping: RegField.Map*) = router.node.regmap(mapping:_*)
|
def regmap(mapping: RegField.Map*) = router.node.regmap(mapping:_*)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,5 +86,5 @@ class APBRegisterRouter[B <: APBRegBundleBase, M <: LazyModuleImp]
|
|||||||
require (isPow2(size))
|
require (isPow2(size))
|
||||||
// require (size >= 4096) ... not absolutely required, but highly recommended
|
// require (size >= 4096) ... not absolutely required, but highly recommended
|
||||||
|
|
||||||
lazy val module = moduleBuilder(bundleBuilder(APBRegBundleArg(intnode.bundleOut, node.bundleIn)), this)
|
lazy val module = moduleBuilder(bundleBuilder(APBRegBundleArg()), this)
|
||||||
}
|
}
|
||||||
|
@ -22,11 +22,7 @@ class APBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4
|
|||||||
require ((address.mask & (beatBytes-1)) == beatBytes-1)
|
require ((address.mask & (beatBytes-1)) == beatBytes-1)
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
val (in, _) = node.in(0)
|
||||||
val in = node.bundleIn
|
|
||||||
}
|
|
||||||
|
|
||||||
val in = io.in(0)
|
|
||||||
|
|
||||||
def bigBits(x: BigInt, tail: List[Boolean] = List.empty[Boolean]): List[Boolean] =
|
def bigBits(x: BigInt, tail: List[Boolean] = List.empty[Boolean]): List[Boolean] =
|
||||||
if (x == 0) tail.reverse else bigBits(x >> 1, ((x & 1) == 1) :: tail)
|
if (x == 0) tail.reverse else bigBits(x >> 1, ((x & 1) == 1) :: tail)
|
||||||
|
@ -34,7 +34,7 @@ class APBFuzzBridge(aFlow: Boolean, txns: Int)(implicit p: Parameters) extends L
|
|||||||
TLDelayer(0.2)(
|
TLDelayer(0.2)(
|
||||||
model.node))))
|
model.node))))
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) with HasUnitTestIO {
|
lazy val module = new LazyModuleImp(this) with UnitTestModule {
|
||||||
io.finished := fuzz.module.io.finished
|
io.finished := fuzz.module.io.finished
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,34 +16,30 @@ class APBFanout()(implicit p: Parameters) extends LazyModule {
|
|||||||
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) {
|
||||||
val io = new Bundle {
|
val (in, _) = node.in(0)
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
val in = io.in(0)
|
|
||||||
|
|
||||||
// Require consistent bus widths
|
// Require consistent bus widths
|
||||||
val port0 = node.edgesOut(0).slave
|
val (io_out, edgesOut) = node.out.unzip
|
||||||
node.edgesOut.foreach { edge =>
|
val port0 = edgesOut(0).slave
|
||||||
|
edgesOut.foreach { edge =>
|
||||||
val port = edge.slave
|
val port = edge.slave
|
||||||
require (port.beatBytes == port0.beatBytes,
|
require (port.beatBytes == port0.beatBytes,
|
||||||
s"${port.slaves.map(_.name)} ${port.beatBytes} vs ${port0.slaves.map(_.name)} ${port0.beatBytes}")
|
s"${port.slaves.map(_.name)} ${port.beatBytes} vs ${port0.slaves.map(_.name)} ${port0.beatBytes}")
|
||||||
}
|
}
|
||||||
|
|
||||||
val port_addrs = node.edgesOut.map(_.slave.slaves.map(_.address).flatten)
|
val port_addrs = edgesOut.map(_.slave.slaves.map(_.address).flatten)
|
||||||
val routingMask = AddressDecoder(port_addrs)
|
val routingMask = AddressDecoder(port_addrs)
|
||||||
val route_addrs = port_addrs.map(_.map(_.widen(~routingMask)).distinct)
|
val route_addrs = port_addrs.map(_.map(_.widen(~routingMask)).distinct)
|
||||||
|
|
||||||
val sel = Vec(route_addrs.map(seq => seq.map(_.contains(in.paddr)).reduce(_ || _)))
|
val sel = Vec(route_addrs.map(seq => seq.map(_.contains(in.paddr)).reduce(_ || _)))
|
||||||
(sel zip io.out) foreach { case (sel, out) =>
|
(sel zip io_out) foreach { case (sel, out) =>
|
||||||
out := in
|
out := in
|
||||||
out.psel := sel && in.psel
|
out.psel := sel && in.psel
|
||||||
out.penable := sel && in.penable
|
out.penable := sel && in.penable
|
||||||
}
|
}
|
||||||
|
|
||||||
in.pready := !Mux1H(sel, io.out.map(!_.pready))
|
in.pready := !Mux1H(sel, io_out.map(!_.pready))
|
||||||
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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,11 +26,6 @@ class AXI4Buffer(
|
|||||||
slaveFn = { p => p.copy(minLatency = p.minLatency + min(aw.latency,ar.latency) + min(r.latency,b.latency)) })
|
slaveFn = { p => p.copy(minLatency = p.minLatency + min(aw.latency,ar.latency) + min(r.latency,b.latency)) })
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
def buffer[T <: Data](config: BufferParams, data: IrrevocableIO[T]): IrrevocableIO[T] = {
|
def buffer[T <: Data](config: BufferParams, data: IrrevocableIO[T]): IrrevocableIO[T] = {
|
||||||
if (config.isDefined) {
|
if (config.isDefined) {
|
||||||
Queue.irrevocable(data, config.depth, pipe=config.pipe, flow=config.flow)
|
Queue.irrevocable(data, config.depth, pipe=config.pipe, flow=config.flow)
|
||||||
@ -39,7 +34,7 @@ class AXI4Buffer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
||||||
out.aw <> buffer(aw, in .aw)
|
out.aw <> buffer(aw, in .aw)
|
||||||
out.w <> buffer(w, in .w)
|
out.w <> buffer(w, in .w)
|
||||||
in .b <> buffer(b, out.b)
|
in .b <> buffer(b, out.b)
|
||||||
|
@ -22,12 +22,7 @@ class AXI4Deinterleaver(maxReadBytes: Int)(implicit p: Parameters) extends LazyM
|
|||||||
})
|
})
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
|
||||||
val endId = edgeOut.master.endId
|
val endId = edgeOut.master.endId
|
||||||
val beatBytes = edgeOut.slave.beatBytes
|
val beatBytes = edgeOut.slave.beatBytes
|
||||||
val beats = (maxReadBytes+beatBytes-1) / beatBytes
|
val beats = (maxReadBytes+beatBytes-1) / beatBytes
|
||||||
|
@ -26,12 +26,7 @@ class AXI4Fragmenter()(implicit p: Parameters) extends LazyModule
|
|||||||
slaveFn = { sp => sp.copy(slaves = sp.slaves .map(s => mapSlave(s, sp.beatBytes))) })
|
slaveFn = { sp => sp.copy(slaves = sp.slaves .map(s => mapSlave(s, sp.beatBytes))) })
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
|
||||||
val slave = edgeOut.slave
|
val slave = edgeOut.slave
|
||||||
val slaves = slave.slaves
|
val slaves = slave.slaves
|
||||||
val beatBytes = slave.beatBytes
|
val beatBytes = slave.beatBytes
|
||||||
|
@ -42,12 +42,7 @@ class AXI4IdIndexer(idBits: Int)(implicit p: Parameters) extends LazyModule
|
|||||||
})
|
})
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
|
||||||
|
|
||||||
// Leave everything mostly untouched
|
// Leave everything mostly untouched
|
||||||
out.ar <> in.ar
|
out.ar <> in.ar
|
||||||
|
@ -9,8 +9,8 @@ import freechips.rocketchip.diplomacy._
|
|||||||
|
|
||||||
object AXI4Imp extends NodeImp[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4EdgeParameters, AXI4EdgeParameters, AXI4Bundle]
|
object AXI4Imp extends NodeImp[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4EdgeParameters, AXI4EdgeParameters, AXI4Bundle]
|
||||||
{
|
{
|
||||||
def edgeO(pd: AXI4MasterPortParameters, pu: AXI4SlavePortParameters): AXI4EdgeParameters = AXI4EdgeParameters(pd, pu)
|
def edgeO(pd: AXI4MasterPortParameters, pu: AXI4SlavePortParameters, p: Parameters): AXI4EdgeParameters = AXI4EdgeParameters(pd, pu, p)
|
||||||
def edgeI(pd: AXI4MasterPortParameters, pu: AXI4SlavePortParameters): AXI4EdgeParameters = AXI4EdgeParameters(pd, pu)
|
def edgeI(pd: AXI4MasterPortParameters, pu: AXI4SlavePortParameters, p: Parameters): AXI4EdgeParameters = AXI4EdgeParameters(pd, pu, p)
|
||||||
|
|
||||||
def bundleO(eo: AXI4EdgeParameters): AXI4Bundle = AXI4Bundle(eo.bundle)
|
def bundleO(eo: AXI4EdgeParameters): AXI4Bundle = AXI4Bundle(eo.bundle)
|
||||||
def bundleI(ei: AXI4EdgeParameters): AXI4Bundle = AXI4Bundle(ei.bundle)
|
def bundleI(ei: AXI4EdgeParameters): AXI4Bundle = AXI4Bundle(ei.bundle)
|
||||||
@ -25,8 +25,6 @@ object AXI4Imp extends NodeImp[AXI4MasterPortParameters, AXI4SlavePortParameters
|
|||||||
pu.copy(slaves = pu.slaves.map { m => m.copy (nodePath = node +: m.nodePath) })
|
pu.copy(slaves = pu.slaves.map { m => m.copy (nodePath = node +: m.nodePath) })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nodes implemented inside modules
|
|
||||||
case class AXI4IdentityNode()(implicit valName: ValName) extends IdentityNode(AXI4Imp)
|
|
||||||
case class AXI4MasterNode(portParams: Seq[AXI4MasterPortParameters])(implicit valName: ValName) extends SourceNode(AXI4Imp)(portParams)
|
case class AXI4MasterNode(portParams: Seq[AXI4MasterPortParameters])(implicit valName: ValName) extends SourceNode(AXI4Imp)(portParams)
|
||||||
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 AXI4AdapterNode(
|
case class AXI4AdapterNode(
|
||||||
@ -35,14 +33,4 @@ case class AXI4AdapterNode(
|
|||||||
numPorts: Range.Inclusive = 0 to 999)(
|
numPorts: Range.Inclusive = 0 to 999)(
|
||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends AdapterNode(AXI4Imp)(masterFn, slaveFn, numPorts)
|
extends AdapterNode(AXI4Imp)(masterFn, slaveFn, numPorts)
|
||||||
|
case class AXI4IdentityNode()(implicit valName: ValName) extends IdentityNode(AXI4Imp)()
|
||||||
// Nodes passed from an inner module
|
|
||||||
case class AXI4OutputNode()(implicit valName: ValName) extends OutputNode(AXI4Imp)
|
|
||||||
case class AXI4InputNode()(implicit valName: ValName) extends InputNode(AXI4Imp)
|
|
||||||
|
|
||||||
// Nodes used for external ports
|
|
||||||
case class AXI4BlindOutputNode(portParams: Seq[AXI4SlavePortParameters])(implicit valName: ValName) extends BlindOutputNode(AXI4Imp)(portParams)
|
|
||||||
case class AXI4BlindInputNode(portParams: Seq[AXI4MasterPortParameters])(implicit valName: ValName) extends BlindInputNode(AXI4Imp)(portParams)
|
|
||||||
|
|
||||||
case class AXI4InternalOutputNode(portParams: Seq[AXI4SlavePortParameters])(implicit valName: ValName) extends InternalOutputNode(AXI4Imp)(portParams)
|
|
||||||
case class AXI4InternalInputNode(portParams: Seq[AXI4MasterPortParameters])(implicit valName: ValName) extends InternalInputNode(AXI4Imp)(portParams)
|
|
||||||
|
@ -124,7 +124,8 @@ object AXI4BundleParameters
|
|||||||
|
|
||||||
case class AXI4EdgeParameters(
|
case class AXI4EdgeParameters(
|
||||||
master: AXI4MasterPortParameters,
|
master: AXI4MasterPortParameters,
|
||||||
slave: AXI4SlavePortParameters)
|
slave: AXI4SlavePortParameters,
|
||||||
|
params: Parameters)
|
||||||
{
|
{
|
||||||
val bundle = AXI4BundleParameters(master, slave)
|
val bundle = AXI4BundleParameters(master, slave)
|
||||||
}
|
}
|
||||||
|
@ -26,11 +26,12 @@ case class AXI4RegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes
|
|||||||
// Calling this method causes the matching AXI4 bundle to be
|
// Calling this method causes the matching AXI4 bundle to be
|
||||||
// configured to route all requests to the listed RegFields.
|
// configured to route all requests to the listed RegFields.
|
||||||
def regmap(mapping: RegField.Map*) = {
|
def regmap(mapping: RegField.Map*) = {
|
||||||
val ar = bundleIn(0).ar
|
val (io, _) = this.in(0)
|
||||||
val aw = bundleIn(0).aw
|
val ar = io.ar
|
||||||
val w = bundleIn(0).w
|
val aw = io.aw
|
||||||
val r = bundleIn(0).r
|
val w = io.w
|
||||||
val b = bundleIn(0).b
|
val r = io.r
|
||||||
|
val b = io.b
|
||||||
|
|
||||||
val params = RegMapperParams(log2Up((address.mask+1)/beatBytes), beatBytes, ar.bits.params.idBits + ar.bits.params.userBits)
|
val params = RegMapperParams(log2Up((address.mask+1)/beatBytes), beatBytes, ar.bits.params.idBits + ar.bits.params.userBits)
|
||||||
val in = Wire(Decoupled(new RegMapperInput(params)))
|
val in = Wire(Decoupled(new RegMapperInput(params)))
|
||||||
@ -86,13 +87,11 @@ abstract class AXI4RegisterRouterBase(address: AddressSet, interrupts: Int, conc
|
|||||||
val intnode = IntSourceNode(IntSourcePortSimple(num = interrupts))
|
val intnode = IntSourceNode(IntSourcePortSimple(num = interrupts))
|
||||||
}
|
}
|
||||||
|
|
||||||
case class AXI4RegBundleArg(interrupts: HeterogeneousBag[Vec[Bool]], in: HeterogeneousBag[AXI4Bundle])(implicit val p: Parameters)
|
case class AXI4RegBundleArg()(implicit val p: Parameters)
|
||||||
|
|
||||||
class AXI4RegBundleBase(arg: AXI4RegBundleArg) extends Bundle
|
class AXI4RegBundleBase(arg: AXI4RegBundleArg) extends Bundle
|
||||||
{
|
{
|
||||||
implicit val p = arg.p
|
implicit val p = arg.p
|
||||||
val interrupts = arg.interrupts
|
|
||||||
val in = arg.in
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class AXI4RegBundle[P](val params: P, arg: AXI4RegBundleArg) extends AXI4RegBundleBase(arg)
|
class AXI4RegBundle[P](val params: P, arg: AXI4RegBundleArg) extends AXI4RegBundleBase(arg)
|
||||||
@ -100,8 +99,8 @@ class AXI4RegBundle[P](val params: P, arg: AXI4RegBundleArg) extends AXI4RegBund
|
|||||||
class AXI4RegModule[P, B <: AXI4RegBundleBase](val params: P, bundleBuilder: => B, router: AXI4RegisterRouterBase)
|
class AXI4RegModule[P, B <: AXI4RegBundleBase](val params: P, bundleBuilder: => B, router: AXI4RegisterRouterBase)
|
||||||
extends LazyModuleImp(router) with HasRegMap
|
extends LazyModuleImp(router) with HasRegMap
|
||||||
{
|
{
|
||||||
val io = bundleBuilder
|
val io = IO(bundleBuilder)
|
||||||
val interrupts = if (io.interrupts.isEmpty) Vec(0, Bool()) else io.interrupts(0)
|
val interrupts = if (router.intnode.in.isEmpty) Vec(0, Bool()) else router.intnode.in(0)._1
|
||||||
def regmap(mapping: RegField.Map*) = router.node.regmap(mapping:_*)
|
def regmap(mapping: RegField.Map*) = router.node.regmap(mapping:_*)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,5 +113,5 @@ class AXI4RegisterRouter[B <: AXI4RegBundleBase, M <: LazyModuleImp]
|
|||||||
require (isPow2(size))
|
require (isPow2(size))
|
||||||
// require (size >= 4096) ... not absolutely required, but highly recommended
|
// require (size >= 4096) ... not absolutely required, but highly recommended
|
||||||
|
|
||||||
lazy val module = moduleBuilder(bundleBuilder(AXI4RegBundleArg(intnode.bundleOut, node.bundleIn)), this)
|
lazy val module = moduleBuilder(bundleBuilder(AXI4RegBundleArg()), this)
|
||||||
}
|
}
|
||||||
|
@ -24,15 +24,11 @@ class AXI4RAM(address: AddressSet, executable: Boolean = true, beatBytes: Int =
|
|||||||
require ((address.mask & (beatBytes-1)) == beatBytes-1)
|
require ((address.mask & (beatBytes-1)) == beatBytes-1)
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
|
||||||
val in = node.bundleIn
|
|
||||||
}
|
|
||||||
|
|
||||||
def bigBits(x: BigInt, tail: List[Boolean] = List.empty[Boolean]): List[Boolean] =
|
def bigBits(x: BigInt, tail: List[Boolean] = List.empty[Boolean]): List[Boolean] =
|
||||||
if (x == 0) tail.reverse else bigBits(x >> 1, ((x & 1) == 1) :: tail)
|
if (x == 0) tail.reverse else bigBits(x >> 1, ((x & 1) == 1) :: tail)
|
||||||
val mask = bigBits(address.mask >> log2Ceil(beatBytes))
|
val mask = bigBits(address.mask >> log2Ceil(beatBytes))
|
||||||
|
|
||||||
val in = io.in(0)
|
val (in, _) = node.in(0)
|
||||||
val mem = SeqMem(1 << mask.filter(b=>b).size, Vec(beatBytes, Bits(width = 8)))
|
val mem = SeqMem(1 << mask.filter(b=>b).size, Vec(beatBytes, Bits(width = 8)))
|
||||||
|
|
||||||
val r_addr = Cat((mask zip (in.ar.bits.addr >> log2Ceil(beatBytes)).toBools).filter(_._1).map(_._2).reverse)
|
val r_addr = Cat((mask zip (in.ar.bits.addr >> log2Ceil(beatBytes)).toBools).filter(_._1).map(_._2).reverse)
|
||||||
|
@ -30,7 +30,7 @@ class AXI4LiteFuzzRAM(txns: Int)(implicit p: Parameters) extends LazyModule
|
|||||||
ram.node := AXI4UserYanker()(AXI4IdIndexer(0)(TLToAXI4(4, true )(TLFragmenter(4, 16)(xbar.node))))
|
ram.node := AXI4UserYanker()(AXI4IdIndexer(0)(TLToAXI4(4, true )(TLFragmenter(4, 16)(xbar.node))))
|
||||||
gpio.node := AXI4UserYanker()(AXI4IdIndexer(0)(TLToAXI4(4, false)(TLFragmenter(4, 16)(xbar.node))))
|
gpio.node := AXI4UserYanker()(AXI4IdIndexer(0)(TLToAXI4(4, false)(TLFragmenter(4, 16)(xbar.node))))
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) with HasUnitTestIO {
|
lazy val module = new LazyModuleImp(this) with UnitTestModule {
|
||||||
io.finished := fuzz.module.io.finished
|
io.finished := fuzz.module.io.finished
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -53,7 +53,7 @@ class AXI4FullFuzzRAM(txns: Int)(implicit p: Parameters) extends LazyModule
|
|||||||
ram.node := AXI4Fragmenter()(AXI4Deinterleaver(16)(TLToAXI4(4,false)(xbar.node)))
|
ram.node := AXI4Fragmenter()(AXI4Deinterleaver(16)(TLToAXI4(4,false)(xbar.node)))
|
||||||
gpio.node := AXI4Fragmenter()(AXI4Deinterleaver(16)(TLToAXI4(4,true )(xbar.node)))
|
gpio.node := AXI4Fragmenter()(AXI4Deinterleaver(16)(TLToAXI4(4,true )(xbar.node)))
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) with HasUnitTestIO {
|
lazy val module = new LazyModuleImp(this) with UnitTestModule {
|
||||||
io.finished := fuzz.module.io.finished
|
io.finished := fuzz.module.io.finished
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -69,7 +69,7 @@ trait HasFuzzTarget {
|
|||||||
|
|
||||||
class AXI4FuzzMaster(txns: Int)(implicit p: Parameters) extends LazyModule with HasFuzzTarget
|
class AXI4FuzzMaster(txns: Int)(implicit p: Parameters) extends LazyModule with HasFuzzTarget
|
||||||
{
|
{
|
||||||
val node = AXI4OutputNode()
|
val node = AXI4IdentityNode()
|
||||||
val fuzz = LazyModule(new TLFuzzer(txns, overrideAddress = Some(fuzzAddr)))
|
val fuzz = LazyModule(new TLFuzzer(txns, overrideAddress = Some(fuzzAddr)))
|
||||||
val model = LazyModule(new TLRAMModel("AXI4FuzzMaster"))
|
val model = LazyModule(new TLRAMModel("AXI4FuzzMaster"))
|
||||||
|
|
||||||
@ -84,10 +84,9 @@ class AXI4FuzzMaster(txns: Int)(implicit p: Parameters) extends LazyModule with
|
|||||||
model.node))))))
|
model.node))))))
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
val io = IO(new Bundle {
|
||||||
val out = node.bundleOut
|
|
||||||
val finished = Bool(OUTPUT)
|
val finished = Bool(OUTPUT)
|
||||||
}
|
})
|
||||||
|
|
||||||
io.finished := fuzz.module.io.finished
|
io.finished := fuzz.module.io.finished
|
||||||
}
|
}
|
||||||
@ -95,7 +94,7 @@ class AXI4FuzzMaster(txns: Int)(implicit p: Parameters) extends LazyModule with
|
|||||||
|
|
||||||
class AXI4FuzzSlave()(implicit p: Parameters) extends LazyModule with HasFuzzTarget
|
class AXI4FuzzSlave()(implicit p: Parameters) extends LazyModule with HasFuzzTarget
|
||||||
{
|
{
|
||||||
val node = AXI4InputNode()
|
val node = AXI4IdentityNode()
|
||||||
val xbar = LazyModule(new TLXbar)
|
val xbar = LazyModule(new TLXbar)
|
||||||
val ram = LazyModule(new TLRAM(fuzzAddr))
|
val ram = LazyModule(new TLRAM(fuzzAddr))
|
||||||
val error= LazyModule(new TLError(ErrorParams(Seq(AddressSet(0x1800, 0xff)), maxTransfer = 256)))
|
val error= LazyModule(new TLError(ErrorParams(Seq(AddressSet(0x1800, 0xff)), maxTransfer = 256)))
|
||||||
@ -114,11 +113,7 @@ class AXI4FuzzSlave()(implicit p: Parameters) extends LazyModule with HasFuzzTar
|
|||||||
AXI4IdIndexer(2)(
|
AXI4IdIndexer(2)(
|
||||||
node))))))))
|
node))))))))
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) { }
|
||||||
val io = new Bundle {
|
|
||||||
val in = node.bundleIn
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class AXI4FuzzBridge(txns: Int)(implicit p: Parameters) extends LazyModule
|
class AXI4FuzzBridge(txns: Int)(implicit p: Parameters) extends LazyModule
|
||||||
@ -128,7 +123,7 @@ class AXI4FuzzBridge(txns: Int)(implicit p: Parameters) extends LazyModule
|
|||||||
|
|
||||||
slave.node := master.node
|
slave.node := master.node
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) with HasUnitTestIO {
|
lazy val module = new LazyModuleImp(this) with UnitTestModule {
|
||||||
io.finished := master.module.io.finished
|
io.finished := master.module.io.finished
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,12 +44,7 @@ class AXI4ToTL()(implicit p: Parameters) extends LazyModule
|
|||||||
val node = AXI4ToTLNode()
|
val node = AXI4ToTLNode()
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
|
||||||
val numIds = edgeIn.master.endId
|
val numIds = edgeIn.master.endId
|
||||||
val beatBytes = edgeOut.manager.beatBytes
|
val beatBytes = edgeOut.manager.beatBytes
|
||||||
val beatCountBits = AXI4Parameters.lenBits + (1 << AXI4Parameters.sizeBits) - 1
|
val beatCountBits = AXI4Parameters.lenBits + (1 << AXI4Parameters.sizeBits) - 1
|
||||||
|
@ -22,12 +22,7 @@ class AXI4UserYanker(capMaxFlight: Option[Int] = None)(implicit p: Parameters) e
|
|||||||
slaveFn = { sp => sp })
|
slaveFn = { sp => sp })
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
|
||||||
val bits = edgeIn.bundle.userBits
|
val bits = edgeIn.bundle.userBits
|
||||||
val need_bypass = edgeOut.slave.minLatency < 1
|
val need_bypass = edgeOut.slave.minLatency < 1
|
||||||
require (bits > 0) // useless UserYanker!
|
require (bits > 0) // useless UserYanker!
|
||||||
|
@ -21,7 +21,7 @@ abstract class BareCoreplex(implicit p: Parameters) extends LazyModule with Bind
|
|||||||
lazy val json = JSON(bindingTree)
|
lazy val json = JSON(bindingTree)
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class BareCoreplexModule[+L <: BareCoreplex](_outer: L) extends LazyMultiIOModuleImp(_outer) {
|
abstract class BareCoreplexModule[+L <: BareCoreplex](_outer: L) extends LazyModuleImp(_outer) {
|
||||||
val outer = _outer
|
val outer = _outer
|
||||||
ElaborationArtefacts.add("graphml", outer.graphML)
|
ElaborationArtefacts.add("graphml", outer.graphML)
|
||||||
ElaborationArtefacts.add("dts", outer.dts)
|
ElaborationArtefacts.add("dts", outer.dts)
|
||||||
|
@ -44,7 +44,7 @@ abstract trait HasExtInterrupts extends HasInterruptBus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val nExtInterrupts = p(NExtTopInterrupts)
|
val nExtInterrupts = p(NExtTopInterrupts)
|
||||||
val extInterrupts = IntInternalInputNode(IntSourcePortSimple(num = nExtInterrupts, resources = device.int))
|
val extInterrupts = IntSourceNode(IntSourcePortSimple(num = nExtInterrupts, resources = device.int))
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This trait should be used if the External Interrupts have NOT
|
/** This trait should be used if the External Interrupts have NOT
|
||||||
@ -77,9 +77,9 @@ trait HasExtInterruptsBundle {
|
|||||||
/** This trait performs the translation from a UInt IO into Diplomatic Interrupts.
|
/** This trait performs the translation from a UInt IO into Diplomatic Interrupts.
|
||||||
* The wiring must be done in the concrete LazyModuleImp.
|
* The wiring must be done in the concrete LazyModuleImp.
|
||||||
*/
|
*/
|
||||||
trait HasExtInterruptsModuleImp extends LazyMultiIOModuleImp with HasExtInterruptsBundle {
|
trait HasExtInterruptsModuleImp extends LazyModuleImp with HasExtInterruptsBundle {
|
||||||
val outer: HasExtInterrupts
|
val outer: HasExtInterrupts
|
||||||
val interrupts = IO(UInt(INPUT, width = outer.nExtInterrupts))
|
val interrupts = IO(UInt(INPUT, width = outer.nExtInterrupts))
|
||||||
|
|
||||||
outer.extInterrupts.bundleIn.flatten.zipWithIndex.foreach { case(o, i) => o := interrupts(i) }
|
outer.extInterrupts.in.map(_._1).flatten.zipWithIndex.foreach { case(o, i) => o := interrupts(i) }
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ trait HasMasterAXI4MemPort extends HasMemoryBus {
|
|||||||
private val params = p(ExtMem)
|
private val params = p(ExtMem)
|
||||||
private val device = new MemoryDevice
|
private val device = new MemoryDevice
|
||||||
|
|
||||||
val mem_axi4 = AXI4BlindOutputNode(Seq.tabulate(nMemoryChannels) { channel =>
|
val mem_axi4 = AXI4SlaveNode(Seq.tabulate(nMemoryChannels) { channel =>
|
||||||
val base = AddressSet(params.base, params.size-1)
|
val base = AddressSet(params.base, params.size-1)
|
||||||
val filter = AddressSet(channel * cacheBlockBytes, ~((nMemoryChannels-1) * cacheBlockBytes))
|
val filter = AddressSet(channel * cacheBlockBytes, ~((nMemoryChannels-1) * cacheBlockBytes))
|
||||||
|
|
||||||
@ -77,9 +77,10 @@ trait HasMasterAXI4MemPortBundle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Actually generates the corresponding IO in the concrete Module */
|
/** Actually generates the corresponding IO in the concrete Module */
|
||||||
trait HasMasterAXI4MemPortModuleImp extends LazyMultiIOModuleImp with HasMasterAXI4MemPortBundle {
|
trait HasMasterAXI4MemPortModuleImp extends LazyModuleImp with HasMasterAXI4MemPortBundle {
|
||||||
val outer: HasMasterAXI4MemPort
|
val outer: HasMasterAXI4MemPort
|
||||||
val mem_axi4 = IO(outer.mem_axi4.bundleOut)
|
val mem_axi4 = IO(HeterogeneousBag(outer.mem_axi4.in.map(_._1.cloneType)))
|
||||||
|
(mem_axi4 zip outer.mem_axi4.in) foreach { case (i, (o, _)) => i <> o }
|
||||||
val nMemoryChannels = outer.nMemoryChannels
|
val nMemoryChannels = outer.nMemoryChannels
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +88,7 @@ trait HasMasterAXI4MemPortModuleImp extends LazyMultiIOModuleImp with HasMasterA
|
|||||||
trait HasMasterAXI4MMIOPort extends HasSystemBus {
|
trait HasMasterAXI4MMIOPort extends HasSystemBus {
|
||||||
private val params = p(ExtBus)
|
private val params = p(ExtBus)
|
||||||
private val device = new SimpleBus("mmio", Nil)
|
private val device = new SimpleBus("mmio", Nil)
|
||||||
val mmio_axi4 = AXI4BlindOutputNode(Seq(AXI4SlavePortParameters(
|
val mmio_axi4 = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
|
||||||
slaves = Seq(AXI4SlaveParameters(
|
slaves = Seq(AXI4SlaveParameters(
|
||||||
address = List(AddressSet(params.base, params.size-1)),
|
address = List(AddressSet(params.base, params.size-1)),
|
||||||
resources = device.ranges,
|
resources = device.ranges,
|
||||||
@ -116,15 +117,16 @@ trait HasMasterAXI4MMIOPortBundle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Actually generates the corresponding IO in the concrete Module */
|
/** Actually generates the corresponding IO in the concrete Module */
|
||||||
trait HasMasterAXI4MMIOPortModuleImp extends LazyMultiIOModuleImp with HasMasterAXI4MMIOPortBundle {
|
trait HasMasterAXI4MMIOPortModuleImp extends LazyModuleImp with HasMasterAXI4MMIOPortBundle {
|
||||||
val outer: HasMasterAXI4MMIOPort
|
val outer: HasMasterAXI4MMIOPort
|
||||||
val mmio_axi4 = IO(outer.mmio_axi4.bundleOut)
|
val mmio_axi4 = IO(HeterogeneousBag(outer.mmio_axi4.in.map(_._1.cloneType)))
|
||||||
|
(mmio_axi4 zip outer.mmio_axi4.in) foreach { case (i, (o, _)) => i <> o }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds an AXI4 port to the system intended to be a slave on an MMIO device bus */
|
/** Adds an AXI4 port to the system intended to be a slave on an MMIO device bus */
|
||||||
trait HasSlaveAXI4Port extends HasSystemBus {
|
trait HasSlaveAXI4Port extends HasSystemBus {
|
||||||
private val params = p(ExtIn)
|
private val params = p(ExtIn)
|
||||||
val l2FrontendAXI4Node = AXI4BlindInputNode(Seq(AXI4MasterPortParameters(
|
val l2FrontendAXI4Node = AXI4MasterNode(Seq(AXI4MasterPortParameters(
|
||||||
masters = Seq(AXI4MasterParameters(
|
masters = Seq(AXI4MasterParameters(
|
||||||
name = "AXI4 periphery",
|
name = "AXI4 periphery",
|
||||||
id = IdRange(0, 1 << params.idBits))))))
|
id = IdRange(0, 1 << params.idBits))))))
|
||||||
@ -155,16 +157,17 @@ trait HasSlaveAXI4PortBundle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Actually generates the corresponding IO in the concrete Module */
|
/** Actually generates the corresponding IO in the concrete Module */
|
||||||
trait HasSlaveAXI4PortModuleImp extends LazyMultiIOModuleImp with HasSlaveAXI4PortBundle {
|
trait HasSlaveAXI4PortModuleImp extends LazyModuleImp with HasSlaveAXI4PortBundle {
|
||||||
val outer: HasSlaveAXI4Port
|
val outer: HasSlaveAXI4Port
|
||||||
val l2_frontend_bus_axi4 = IO(outer.l2FrontendAXI4Node.bundleIn)
|
val l2_frontend_bus_axi4 = IO(HeterogeneousBag(outer.l2FrontendAXI4Node.out.map(_._1.cloneType)).flip)
|
||||||
|
(outer.l2FrontendAXI4Node.out zip l2_frontend_bus_axi4) foreach { case ((i, _), o) => i <> o }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds a TileLink port to the system intended to master an MMIO device bus */
|
/** Adds a TileLink port to the system intended to master an MMIO device bus */
|
||||||
trait HasMasterTLMMIOPort extends HasSystemBus {
|
trait HasMasterTLMMIOPort extends HasSystemBus {
|
||||||
private val params = p(ExtBus)
|
private val params = p(ExtBus)
|
||||||
private val device = new SimpleBus("mmio", Nil)
|
private val device = new SimpleBus("mmio", Nil)
|
||||||
val mmio_tl = TLBlindOutputNode(Seq(TLManagerPortParameters(
|
val mmio_tl = TLManagerNode(Seq(TLManagerPortParameters(
|
||||||
managers = Seq(TLManagerParameters(
|
managers = Seq(TLManagerParameters(
|
||||||
address = List(AddressSet(params.base, params.size-1)),
|
address = List(AddressSet(params.base, params.size-1)),
|
||||||
resources = device.ranges,
|
resources = device.ranges,
|
||||||
@ -196,9 +199,10 @@ trait HasMasterTLMMIOPortBundle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Actually generates the corresponding IO in the concrete Module */
|
/** Actually generates the corresponding IO in the concrete Module */
|
||||||
trait HasMasterTLMMIOPortModuleImp extends LazyMultiIOModuleImp with HasMasterTLMMIOPortBundle {
|
trait HasMasterTLMMIOPortModuleImp extends LazyModuleImp with HasMasterTLMMIOPortBundle {
|
||||||
val outer: HasMasterTLMMIOPort
|
val outer: HasMasterTLMMIOPort
|
||||||
val mmio_tl = IO(outer.mmio_tl.bundleOut)
|
val mmio_tl = IO(HeterogeneousBag(outer.mmio_tl.in.map(_._1.cloneType)))
|
||||||
|
(mmio_tl zip outer.mmio_tl.out) foreach { case (i, (o, _)) => i <> o }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds an TL port to the system intended to be a slave on an MMIO device bus.
|
/** Adds an TL port to the system intended to be a slave on an MMIO device bus.
|
||||||
@ -206,7 +210,7 @@ trait HasMasterTLMMIOPortModuleImp extends LazyMultiIOModuleImp with HasMasterTL
|
|||||||
*/
|
*/
|
||||||
trait HasSlaveTLPort extends HasSystemBus {
|
trait HasSlaveTLPort extends HasSystemBus {
|
||||||
private val params = p(ExtIn)
|
private val params = p(ExtIn)
|
||||||
val l2FrontendTLNode = TLBlindInputNode(Seq(TLClientPortParameters(
|
val l2FrontendTLNode = TLClientNode(Seq(TLClientPortParameters(
|
||||||
clients = Seq(TLClientParameters(
|
clients = Seq(TLClientParameters(
|
||||||
name = "Front Port (TL)",
|
name = "Front Port (TL)",
|
||||||
sourceId = IdRange(0, 1 << params.idBits))))))
|
sourceId = IdRange(0, 1 << params.idBits))))))
|
||||||
@ -233,9 +237,10 @@ trait HasSlaveTLPortBundle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Actually generates the corresponding IO in the concrete Module */
|
/** Actually generates the corresponding IO in the concrete Module */
|
||||||
trait HasSlaveTLPortModuleImp extends LazyMultiIOModuleImp with HasSlaveTLPortBundle {
|
trait HasSlaveTLPortModuleImp extends LazyModuleImp with HasSlaveTLPortBundle {
|
||||||
val outer: HasSlaveTLPort
|
val outer: HasSlaveTLPort
|
||||||
val l2_frontend_bus_tl = IO(outer.l2FrontendTLNode.bundleIn)
|
val l2_frontend_bus_tl = IO(HeterogeneousBag(outer.l2FrontendTLNode.out.map(_._1.cloneType)).flip)
|
||||||
|
(outer.l2FrontendTLNode.in zip l2_frontend_bus_tl) foreach { case ((i, _), o) => i <> o }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Memory with AXI port for use in elaboratable test harnesses. */
|
/** Memory with AXI port for use in elaboratable test harnesses. */
|
||||||
@ -245,7 +250,7 @@ class SimAXIMem(channels: Int, forceSize: BigInt = 0)(implicit p: Parameters) ex
|
|||||||
val size = totalSize / channels
|
val size = totalSize / channels
|
||||||
require(totalSize % channels == 0)
|
require(totalSize % channels == 0)
|
||||||
|
|
||||||
val node = AXI4BlindInputNode(Seq.fill(channels) {
|
val node = AXI4MasterNode(Seq.fill(channels) {
|
||||||
AXI4MasterPortParameters(Seq(AXI4MasterParameters(
|
AXI4MasterPortParameters(Seq(AXI4MasterParameters(
|
||||||
name = "dut",
|
name = "dut",
|
||||||
id = IdRange(0, 1 << config.idBits)
|
id = IdRange(0, 1 << config.idBits)
|
||||||
@ -258,8 +263,9 @@ class SimAXIMem(channels: Int, forceSize: BigInt = 0)(implicit p: Parameters) ex
|
|||||||
}
|
}
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
val io = IO(new Bundle {
|
||||||
val axi4 = node.bundleIn
|
val axi4 = HeterogeneousBag(node.out.map(_._1.cloneType)).flip
|
||||||
}
|
})
|
||||||
|
(node.out zip io.axi4) foreach { case ((i, _), o) => i <> o }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,10 @@
|
|||||||
package freechips.rocketchip.coreplex
|
package freechips.rocketchip.coreplex
|
||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import freechips.rocketchip.diplomacy.{LazyMultiIOModuleImp, DTSTimebase}
|
import freechips.rocketchip.diplomacy.{LazyModuleImp, DTSTimebase}
|
||||||
import freechips.rocketchip.devices.tilelink.HasPeripheryClint
|
import freechips.rocketchip.devices.tilelink.HasPeripheryClint
|
||||||
|
|
||||||
trait HasRTCModuleImp extends LazyMultiIOModuleImp {
|
trait HasRTCModuleImp extends LazyModuleImp {
|
||||||
val outer: HasPeripheryClint
|
val outer: HasPeripheryClint
|
||||||
private val pbusFreq = outer.p(PeripheryBusKey).frequency
|
private val pbusFreq = outer.p(PeripheryBusKey).frequency
|
||||||
private val rtcFreq = outer.p(DTSTimebase)
|
private val rtcFreq = outer.p(DTSTimebase)
|
||||||
|
@ -98,7 +98,7 @@ trait HasRocketTilesBundle {
|
|||||||
val rocket_tile_inputs: Vec[ClockedRocketTileInputs]
|
val rocket_tile_inputs: Vec[ClockedRocketTileInputs]
|
||||||
}
|
}
|
||||||
|
|
||||||
trait HasRocketTilesModuleImp extends LazyMultiIOModuleImp
|
trait HasRocketTilesModuleImp extends LazyModuleImp
|
||||||
with HasRocketTilesBundle
|
with HasRocketTilesBundle
|
||||||
with HasResetVectorWire
|
with HasResetVectorWire
|
||||||
with HasPeripheryDebugModuleImp {
|
with HasPeripheryDebugModuleImp {
|
||||||
|
@ -22,7 +22,7 @@ class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWr
|
|||||||
private val master_splitter = LazyModule(new TLSplitter) // Allows cycle-free connection to external networks
|
private val master_splitter = LazyModule(new TLSplitter) // Allows cycle-free connection to external networks
|
||||||
master_splitter.suggestName(s"${busName}_master_TLSplitter")
|
master_splitter.suggestName(s"${busName}_master_TLSplitter")
|
||||||
inwardNode :=* master_splitter.node
|
inwardNode :=* master_splitter.node
|
||||||
def busView = master_splitter.node.edgesIn.head
|
def busView = master_splitter.node.in.head._2
|
||||||
|
|
||||||
protected def inwardSplitNode: TLInwardNode = master_splitter.node
|
protected def inwardSplitNode: TLInwardNode = master_splitter.node
|
||||||
protected def outwardSplitNode: TLOutwardNode = master_splitter.node
|
protected def outwardSplitNode: TLOutwardNode = master_splitter.node
|
||||||
|
@ -288,14 +288,12 @@ class TLDebugModuleOuter(device: Device)(implicit p: Parameters) extends LazyMod
|
|||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
|
|
||||||
val nComponents = intnode.bundleOut.size
|
val nComponents = intnode.out.size
|
||||||
|
|
||||||
val io = new Bundle {
|
val io = IO(new Bundle {
|
||||||
val ctrl = (new DebugCtrlBundle(nComponents))
|
val ctrl = (new DebugCtrlBundle(nComponents))
|
||||||
val tlIn = dmiNode.bundleIn
|
|
||||||
val debugInterrupts = intnode.bundleOut
|
|
||||||
val innerCtrl = new DecoupledIO(new DebugInternalBundle())
|
val innerCtrl = new DecoupledIO(new DebugInternalBundle())
|
||||||
}
|
})
|
||||||
|
|
||||||
//----DMCONTROL (The whole point of 'Outer' is to maintain this register on dmiClock (e.g. TCK) domain, so that it
|
//----DMCONTROL (The whole point of 'Outer' is to maintain this register on dmiClock (e.g. TCK) domain, so that it
|
||||||
// can be written even if 'Inner' is not being clocked or is in reset. This allows halting
|
// can be written even if 'Inner' is not being clocked or is in reset. This allows halting
|
||||||
@ -356,7 +354,7 @@ class TLDebugModuleOuter(device: Device)(implicit p: Parameters) extends LazyMod
|
|||||||
debugIntNxt := debugIntRegs
|
debugIntNxt := debugIntRegs
|
||||||
|
|
||||||
for (component <- 0 until nComponents) {
|
for (component <- 0 until nComponents) {
|
||||||
io.debugInterrupts(component)(0) := debugIntRegs(component)
|
intnode.out(component)._1(0) := debugIntRegs(component)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Halt request registers are set & cleared by writes to DMCONTROL.haltreq
|
// Halt request registers are set & cleared by writes to DMCONTROL.haltreq
|
||||||
@ -393,9 +391,9 @@ class TLDebugModuleOuterAsync(device: Device)(implicit p: Parameters) extends La
|
|||||||
val dmiXbar = LazyModule (new TLXbar())
|
val dmiXbar = LazyModule (new TLXbar())
|
||||||
|
|
||||||
val dmOuter = LazyModule( new TLDebugModuleOuter(device))
|
val dmOuter = LazyModule( new TLDebugModuleOuter(device))
|
||||||
val intnode = IntOutputNode()
|
val intnode = IntIdentityNode()
|
||||||
|
|
||||||
val dmiInnerNode = TLAsyncOutputNode()
|
val dmiInnerNode = TLAsyncIdentityNode()
|
||||||
|
|
||||||
intnode :*= dmOuter.intnode
|
intnode :*= dmOuter.intnode
|
||||||
|
|
||||||
@ -405,15 +403,13 @@ class TLDebugModuleOuterAsync(device: Device)(implicit p: Parameters) extends La
|
|||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
|
|
||||||
val nComponents = intnode.bundleOut.size
|
val nComponents = intnode.out.size
|
||||||
|
|
||||||
val io = new Bundle {
|
val io = IO(new Bundle {
|
||||||
val dmi = new DMIIO()(p).flip()
|
val dmi = new DMIIO()(p).flip()
|
||||||
val dmiInner = dmiInnerNode.bundleOut
|
|
||||||
val ctrl = new DebugCtrlBundle(nComponents)
|
val ctrl = new DebugCtrlBundle(nComponents)
|
||||||
val debugInterrupts = intnode.bundleOut
|
|
||||||
val innerCtrl = new AsyncBundle(depth=1, new DebugInternalBundle())
|
val innerCtrl = new AsyncBundle(depth=1, new DebugInternalBundle())
|
||||||
}
|
})
|
||||||
|
|
||||||
dmi2tl.module.io.dmi <> io.dmi
|
dmi2tl.module.io.dmi <> io.dmi
|
||||||
|
|
||||||
@ -447,13 +443,11 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
|
|||||||
|
|
||||||
val nComponents = getNComponents()
|
val nComponents = getNComponents()
|
||||||
|
|
||||||
val io = new Bundle {
|
val io = IO(new Bundle {
|
||||||
val hart_in = tlNode.bundleIn
|
|
||||||
val dmi_in = dmiNode.bundleIn
|
|
||||||
val dmactive = Bool(INPUT)
|
val dmactive = Bool(INPUT)
|
||||||
val innerCtrl = (new DecoupledIO(new DebugInternalBundle())).flip
|
val innerCtrl = (new DecoupledIO(new DebugInternalBundle())).flip
|
||||||
val debugUnavail = Vec(nComponents, Bool()).asInput
|
val debugUnavail = Vec(nComponents, Bool()).asInput
|
||||||
}
|
})
|
||||||
|
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
// Import constants for shorter variable names
|
// Import constants for shorter variable names
|
||||||
@ -1012,25 +1006,23 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
|
|||||||
class TLDebugModuleInnerAsync(device: Device, getNComponents: () => Int)(implicit p: Parameters) extends LazyModule{
|
class TLDebugModuleInnerAsync(device: Device, getNComponents: () => Int)(implicit p: Parameters) extends LazyModule{
|
||||||
|
|
||||||
val dmInner = LazyModule(new TLDebugModuleInner(device, getNComponents)(p))
|
val dmInner = LazyModule(new TLDebugModuleInner(device, getNComponents)(p))
|
||||||
val dmiNode = TLAsyncInputNode()
|
val dmiNode = TLAsyncIdentityNode()
|
||||||
val tlNode = TLInputNode()
|
val tlNode = TLIdentityNode()
|
||||||
|
|
||||||
dmInner.dmiNode := TLAsyncCrossingSink(depth=1)(dmiNode)
|
dmInner.dmiNode := TLAsyncCrossingSink(depth=1)(dmiNode)
|
||||||
dmInner.tlNode := tlNode
|
dmInner.tlNode := tlNode
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
|
|
||||||
val io = new Bundle {
|
val io = IO(new Bundle {
|
||||||
// this comes from tlClk domain.
|
// this comes from tlClk domain.
|
||||||
val tl_in = tlNode.bundleIn
|
|
||||||
// These are all asynchronous and come from Outer
|
// These are all asynchronous and come from Outer
|
||||||
val dmi_in = dmiNode.bundleIn
|
|
||||||
val dmactive = Bool(INPUT)
|
val dmactive = Bool(INPUT)
|
||||||
val innerCtrl = new AsyncBundle(1, new DebugInternalBundle()).flip
|
val innerCtrl = new AsyncBundle(1, new DebugInternalBundle()).flip
|
||||||
// This comes from tlClk domain.
|
// This comes from tlClk domain.
|
||||||
val debugUnavail = Vec(getNComponents(), Bool()).asInput
|
val debugUnavail = Vec(getNComponents(), Bool()).asInput
|
||||||
val psd = new PSDTestMode().asInput
|
val psd = new PSDTestMode().asInput
|
||||||
}
|
})
|
||||||
|
|
||||||
dmInner.module.io.innerCtrl := FromAsyncBundle(io.innerCtrl)
|
dmInner.module.io.innerCtrl := FromAsyncBundle(io.innerCtrl)
|
||||||
dmInner.module.io.dmactive := ~ResetCatchAndSync(clock, ~io.dmactive, "dmactiveSync", io.psd)
|
dmInner.module.io.dmactive := ~ResetCatchAndSync(clock, ~io.dmactive, "dmactiveSync", io.psd)
|
||||||
@ -1049,26 +1041,24 @@ class TLDebugModule(implicit p: Parameters) extends LazyModule {
|
|||||||
override val alwaysExtended = true
|
override val alwaysExtended = true
|
||||||
}
|
}
|
||||||
|
|
||||||
val node = TLInputNode()
|
val node = TLIdentityNode()
|
||||||
val intnode = IntOutputNode()
|
val intnode = IntIdentityNode()
|
||||||
|
|
||||||
val dmOuter = LazyModule(new TLDebugModuleOuterAsync(device)(p))
|
val dmOuter = LazyModule(new TLDebugModuleOuterAsync(device)(p))
|
||||||
val dmInner = LazyModule(new TLDebugModuleInnerAsync(device, () => {intnode.bundleOut.size})(p))
|
val dmInner = LazyModule(new TLDebugModuleInnerAsync(device, () => {intnode.edges._2.size})(p))
|
||||||
|
|
||||||
dmInner.dmiNode := dmOuter.dmiInnerNode
|
dmInner.dmiNode := dmOuter.dmiInnerNode
|
||||||
dmInner.tlNode := node
|
dmInner.tlNode := node
|
||||||
intnode :*= dmOuter.intnode
|
intnode :*= dmOuter.intnode
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val nComponents = intnode.bundleOut.size
|
val nComponents = intnode.out.size
|
||||||
|
|
||||||
val io = new Bundle {
|
val io = IO(new Bundle {
|
||||||
val ctrl = new DebugCtrlBundle(nComponents)
|
val ctrl = new DebugCtrlBundle(nComponents)
|
||||||
val dmi = new ClockedDMIIO().flip
|
val dmi = new ClockedDMIIO().flip
|
||||||
val in = node.bundleIn
|
|
||||||
val debugInterrupts = intnode.bundleOut
|
|
||||||
val psd = new PSDTestMode().asInput
|
val psd = new PSDTestMode().asInput
|
||||||
}
|
})
|
||||||
|
|
||||||
dmOuter.module.io.dmi <> io.dmi.dmi
|
dmOuter.module.io.dmi <> io.dmi.dmi
|
||||||
dmOuter.module.reset := io.dmi.dmiReset
|
dmOuter.module.reset := io.dmi.dmiReset
|
||||||
@ -1102,16 +1092,14 @@ class ClockedDMIIO(implicit val p: Parameters) extends ParameterizedBundle()(p){
|
|||||||
|
|
||||||
class DMIToTL(implicit p: Parameters) extends LazyModule {
|
class DMIToTL(implicit p: Parameters) extends LazyModule {
|
||||||
|
|
||||||
val node = TLClientNode(TLClientParameters("debug"))
|
val node = TLClientNode(Seq(TLClientPortParameters(Seq(TLClientParameters("debug")))))
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
val io = IO(new Bundle {
|
||||||
val dmi = new DMIIO()(p).flip()
|
val dmi = new DMIIO()(p).flip()
|
||||||
val out = node.bundleOut
|
})
|
||||||
}
|
|
||||||
|
|
||||||
val tl = io.out(0)
|
val (tl, edge) = node.out(0)
|
||||||
val edge = node.edgesOut(0)
|
|
||||||
|
|
||||||
val src = Wire(init = 0.U)
|
val src = Wire(init = 0.U)
|
||||||
val addr = Wire(init = (io.dmi.req.bits.addr << 2))
|
val addr = Wire(init = (io.dmi.req.bits.addr << 2))
|
||||||
|
@ -54,9 +54,9 @@ trait HasPeripheryDebugBundle {
|
|||||||
}
|
}
|
||||||
debug.psd.foreach { _ <> psd }
|
debug.psd.foreach { _ <> psd }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
trait HasPeripheryDebugModuleImp extends LazyMultiIOModuleImp with HasPeripheryDebugBundle {
|
|
||||||
|
trait HasPeripheryDebugModuleImp extends LazyModuleImp with HasPeripheryDebugBundle {
|
||||||
val outer: HasPeripheryDebug
|
val outer: HasPeripheryDebug
|
||||||
|
|
||||||
val debug = IO(new DebugIO)
|
val debug = IO(new DebugIO)
|
||||||
|
@ -23,25 +23,22 @@ case object BootROMParams extends Field[BootROMParams]
|
|||||||
class TLROM(val base: BigInt, val size: Int, contentsDelayed: => Seq[Byte], executable: Boolean = true, beatBytes: Int = 4,
|
class TLROM(val base: BigInt, val size: Int, contentsDelayed: => Seq[Byte], executable: Boolean = true, beatBytes: Int = 4,
|
||||||
resources: Seq[Resource] = new SimpleDevice("rom", Seq("sifive,rom0")).reg("mem"))(implicit p: Parameters) extends LazyModule
|
resources: Seq[Resource] = new SimpleDevice("rom", Seq("sifive,rom0")).reg("mem"))(implicit p: Parameters) extends LazyModule
|
||||||
{
|
{
|
||||||
val node = TLManagerNode(beatBytes, TLManagerParameters (
|
val node = TLManagerNode(Seq(TLManagerPortParameters(
|
||||||
address = List(AddressSet(base, size-1)),
|
Seq(TLManagerParameters(
|
||||||
resources = resources,
|
address = List(AddressSet(base, size-1)),
|
||||||
regionType = RegionType.UNCACHED,
|
resources = resources,
|
||||||
executable = executable,
|
regionType = RegionType.UNCACHED,
|
||||||
supportsGet = TransferSizes(1, beatBytes),
|
executable = executable,
|
||||||
fifoId = Some(0)))
|
supportsGet = TransferSizes(1, beatBytes),
|
||||||
|
fifoId = Some(0))),
|
||||||
|
beatBytes = beatBytes)))
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
|
||||||
val in = node.bundleIn
|
|
||||||
}
|
|
||||||
|
|
||||||
val contents = contentsDelayed
|
val contents = contentsDelayed
|
||||||
val wrapSize = 1 << log2Ceil(contents.size)
|
val wrapSize = 1 << log2Ceil(contents.size)
|
||||||
require (wrapSize <= size)
|
require (wrapSize <= size)
|
||||||
|
|
||||||
val in = io.in(0)
|
val (in, edge) = node.in(0)
|
||||||
val edge = node.edgesIn(0)
|
|
||||||
|
|
||||||
val words = (contents ++ Seq.fill(wrapSize-contents.size)(0.toByte)).grouped(beatBytes).toSeq
|
val words = (contents ++ Seq.fill(wrapSize-contents.size)(0.toByte)).grouped(beatBytes).toSeq
|
||||||
val bigs = words.map(_.foldRight(BigInt(0)){ case (x,y) => (x.toInt & 0xff) | y << 8})
|
val bigs = words.map(_.foldRight(BigInt(0)){ case (x,y) => (x.toInt & 0xff) | y << 8})
|
||||||
@ -78,7 +75,7 @@ trait HasPeripheryBootROM extends HasPeripheryBus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Coreplex will power-on running at 0x10040 (BootROM) */
|
/** Coreplex will power-on running at 0x10040 (BootROM) */
|
||||||
trait HasPeripheryBootROMModuleImp extends LazyMultiIOModuleImp
|
trait HasPeripheryBootROMModuleImp extends LazyModuleImp
|
||||||
with HasResetVectorWire {
|
with HasResetVectorWire {
|
||||||
val outer: HasPeripheryBootROM
|
val outer: HasPeripheryBootROM
|
||||||
global_reset_vector := outer.resetVector.U
|
global_reset_vector := outer.resetVector.U
|
||||||
|
@ -81,20 +81,13 @@ class BusBlocker(params: BusBlockerParams)(implicit p: Parameters) extends TLBus
|
|||||||
beatBytes = params.controlBeatBytes)
|
beatBytes = params.controlBeatBytes)
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
|
||||||
val ctl = controlNode.bundleIn
|
|
||||||
val in = nodeIn.bundleIn
|
|
||||||
val out = nodeOut.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
// We need to be able to represent +1 larger than the largest populated address
|
// We need to be able to represent +1 larger than the largest populated address
|
||||||
val addressBits = log2Ceil(nodeOut.edgesOut(0).manager.maxAddress+1+1)
|
val addressBits = log2Ceil(nodeOut.out(0)._2.manager.maxAddress+1+1)
|
||||||
val pmps = RegInit(Vec.fill(params.pmpRegisters) { DevicePMP(addressBits, params.pageBits) })
|
val pmps = RegInit(Vec.fill(params.pmpRegisters) { DevicePMP(addressBits, params.pageBits) })
|
||||||
val blocks = pmps.tail.map(_.blockPriorAddress) :+ Bool(false)
|
val blocks = pmps.tail.map(_.blockPriorAddress) :+ Bool(false)
|
||||||
controlNode.regmap(0 -> (pmps zip blocks).map { case (p, b) => p.fields(b) }.toList.flatten)
|
controlNode.regmap(0 -> (pmps zip blocks).map { case (p, b) => p.fields(b) }.toList.flatten)
|
||||||
|
|
||||||
val in = io.in(0)
|
val (in, edge) = nodeIn.in(0)
|
||||||
val edge = nodeIn.edgesIn(0)
|
|
||||||
|
|
||||||
// Determine if a request is allowed
|
// Determine if a request is allowed
|
||||||
val needW = in.a.bits.opcode =/= TLMessages.Get
|
val needW = in.a.bits.opcode =/= TLMessages.Get
|
||||||
|
@ -12,8 +12,8 @@ import scala.math.min
|
|||||||
|
|
||||||
abstract class TLBusBypassBase(beatBytes: Int)(implicit p: Parameters) extends LazyModule
|
abstract class TLBusBypassBase(beatBytes: Int)(implicit p: Parameters) extends LazyModule
|
||||||
{
|
{
|
||||||
protected val nodeIn = TLInputNode()
|
protected val nodeIn = TLIdentityNode()
|
||||||
protected val nodeOut = TLOutputNode()
|
protected val nodeOut = TLIdentityNode()
|
||||||
val node = NodeHandle(nodeIn, nodeOut)
|
val node = NodeHandle(nodeIn, nodeOut)
|
||||||
|
|
||||||
protected val bar = LazyModule(new TLBusBypassBar)
|
protected val bar = LazyModule(new TLBusBypassBar)
|
||||||
@ -28,11 +28,9 @@ abstract class TLBusBypassBase(beatBytes: Int)(implicit p: Parameters) extends L
|
|||||||
class TLBusBypass(beatBytes: Int)(implicit p: Parameters) extends TLBusBypassBase(beatBytes)
|
class TLBusBypass(beatBytes: Int)(implicit p: Parameters) extends TLBusBypassBase(beatBytes)
|
||||||
{
|
{
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
val io = IO(new Bundle {
|
||||||
val in = nodeIn.bundleIn
|
|
||||||
val out = nodeOut.bundleOut
|
|
||||||
val bypass = Bool(INPUT)
|
val bypass = Bool(INPUT)
|
||||||
}
|
})
|
||||||
bar.module.io.bypass := io.bypass
|
bar.module.io.bypass := io.bypass
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -47,17 +45,13 @@ class TLBusBypassBar(implicit p: Parameters) extends LazyModule
|
|||||||
managerFn = { seq => seq(1) })
|
managerFn = { seq => seq(1) })
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
val io = IO(new Bundle {
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
val bypass = Bool(INPUT)
|
val bypass = Bool(INPUT)
|
||||||
}
|
})
|
||||||
|
|
||||||
val in = io.in(0)
|
val (in, edge) = node.in(0)
|
||||||
val out0 = io.out(0)
|
val Seq((out0,_), (out1,_)) = node.out
|
||||||
val out1 = io.out(1)
|
|
||||||
|
|
||||||
val edge = node.edgesIn(0)
|
|
||||||
val bce = edge.manager.anySupportAcquireB && edge.client.anySupportProbe
|
val bce = edge.manager.anySupportAcquireB && edge.client.anySupportProbe
|
||||||
|
|
||||||
// We need to be locked to the given bypass direction until all transactions stop
|
// We need to be locked to the given bypass direction until all transactions stop
|
||||||
|
@ -53,11 +53,9 @@ class CoreplexLocalInterrupter(params: ClintParams)(implicit p: Parameters) exte
|
|||||||
sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) })
|
sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) })
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
val io = IO(new Bundle {
|
||||||
val rtcTick = Bool(INPUT)
|
val rtcTick = Bool(INPUT)
|
||||||
val int = intnode.bundleOut
|
})
|
||||||
val in = node.bundleIn
|
|
||||||
}
|
|
||||||
|
|
||||||
val time = Seq.fill(timeWidth/regWidth)(Reg(init=UInt(0, width = regWidth)))
|
val time = Seq.fill(timeWidth/regWidth)(Reg(init=UInt(0, width = regWidth)))
|
||||||
when (io.rtcTick) {
|
when (io.rtcTick) {
|
||||||
@ -66,11 +64,11 @@ class CoreplexLocalInterrupter(params: ClintParams)(implicit p: Parameters) exte
|
|||||||
reg := newTime >> i
|
reg := newTime >> i
|
||||||
}
|
}
|
||||||
|
|
||||||
val nTiles = intnode.edgesOut.size
|
val nTiles = intnode.out.size
|
||||||
val timecmp = Seq.fill(nTiles) { Seq.fill(timeWidth/regWidth)(Reg(UInt(width = regWidth))) }
|
val timecmp = Seq.fill(nTiles) { Seq.fill(timeWidth/regWidth)(Reg(UInt(width = regWidth))) }
|
||||||
val ipi = Seq.fill(nTiles) { RegInit(UInt(0, width = 1)) }
|
val ipi = Seq.fill(nTiles) { RegInit(UInt(0, width = 1)) }
|
||||||
|
|
||||||
io.int.zipWithIndex.foreach { case (int, i) =>
|
intnode.in.map(_._1).zipWithIndex.foreach { case (int, i) =>
|
||||||
int(0) := ShiftRegister(ipi(i)(0), params.intStages) // msip
|
int(0) := ShiftRegister(ipi(i)(0), params.intStages) // msip
|
||||||
int(1) := ShiftRegister(time.asUInt >= timecmp(i).asUInt, params.intStages) // mtip
|
int(1) := ShiftRegister(time.asUInt >= timecmp(i).asUInt, params.intStages) // mtip
|
||||||
}
|
}
|
||||||
|
@ -40,15 +40,10 @@ class TLError(params: ErrorParams, beatBytes: Int = 4)(implicit p: Parameters) e
|
|||||||
minLatency = 1))) // no bypass needed for this device
|
minLatency = 1))) // no bypass needed for this device
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
|
||||||
val in = node.bundleIn
|
|
||||||
}
|
|
||||||
|
|
||||||
import TLMessages._
|
import TLMessages._
|
||||||
import TLPermissions._
|
import TLPermissions._
|
||||||
|
|
||||||
val edge = node.edgesIn(0)
|
val (in, edge) = node.in(0)
|
||||||
val in = io.in(0)
|
|
||||||
val a = Queue(in.a, 1)
|
val a = Queue(in.a, 1)
|
||||||
val c = Queue(in.c, 1)
|
val c = Queue(in.c, 1)
|
||||||
val da = Wire(in.d)
|
val da = Wire(in.d)
|
||||||
|
@ -24,21 +24,18 @@ trait HasPeripheryMaskROMSlave extends HasPeripheryBus {
|
|||||||
|
|
||||||
class TLMaskROM(c: MaskROMParams)(implicit p: Parameters) extends LazyModule {
|
class TLMaskROM(c: MaskROMParams)(implicit p: Parameters) extends LazyModule {
|
||||||
val beatBytes = c.width/8
|
val beatBytes = c.width/8
|
||||||
val node = TLManagerNode(beatBytes, TLManagerParameters(
|
val node = TLManagerNode(Seq(TLManagerPortParameters(
|
||||||
address = AddressSet.misaligned(c.address, c.depth*beatBytes),
|
Seq(TLManagerParameters(
|
||||||
resources = new SimpleDevice("rom", Seq("sifive,maskrom0")).reg("mem"),
|
address = AddressSet.misaligned(c.address, c.depth*beatBytes),
|
||||||
regionType = RegionType.UNCACHED,
|
resources = new SimpleDevice("rom", Seq("sifive,maskrom0")).reg("mem"),
|
||||||
executable = true,
|
regionType = RegionType.UNCACHED,
|
||||||
supportsGet = TransferSizes(1, beatBytes),
|
executable = true,
|
||||||
fifoId = Some(0))) // requests are handled in order
|
supportsGet = TransferSizes(1, beatBytes),
|
||||||
|
fifoId = Some(0))), // requests are handled in order
|
||||||
|
beatBytes = beatBytes)))
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
val (in, edge)= node.in(0)
|
||||||
val in = node.bundleIn
|
|
||||||
}
|
|
||||||
|
|
||||||
val in = io.in(0)
|
|
||||||
val edge = node.edgesIn(0)
|
|
||||||
|
|
||||||
val rom = ROMGenerator(ROMConfig(c.name, c.depth, c.width))
|
val rom = ROMGenerator(ROMConfig(c.name, c.depth, c.width))
|
||||||
rom.io.clock := clock
|
rom.io.clock := clock
|
||||||
|
@ -91,12 +91,12 @@ class TLPLIC(params: PLICParams)(implicit p: Parameters) extends LazyModule
|
|||||||
sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) })
|
sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) })
|
||||||
|
|
||||||
/* Negotiated sizes */
|
/* Negotiated sizes */
|
||||||
def nDevices: Int = intnode.edgesIn.map(_.source.num).sum
|
def nDevices: Int = intnode.in.map(_._2.source.num).sum
|
||||||
def nPriorities = min(params.maxPriorities, nDevices)
|
def nPriorities = min(params.maxPriorities, nDevices)
|
||||||
def nHarts = intnode.edgesOut.map(_.source.num).sum
|
def nHarts = intnode.out.map(_._2.source.num).sum
|
||||||
|
|
||||||
// Assign all the devices unique ranges
|
// Assign all the devices unique ranges
|
||||||
lazy val sources = intnode.edgesIn.map(_.source)
|
lazy val sources = intnode.in.map(_._2.source)
|
||||||
lazy val flatSources = (sources zip sources.map(_.num).scanLeft(0)(_+_).init).map {
|
lazy val flatSources = (sources zip sources.map(_.num).scanLeft(0)(_+_).init).map {
|
||||||
case (s, o) => s.sources.map(z => z.copy(range = z.range.offset(o)))
|
case (s, o) => s.sources.map(z => z.copy(range = z.range.offset(o)))
|
||||||
}.flatten
|
}.flatten
|
||||||
@ -109,16 +109,13 @@ class TLPLIC(params: PLICParams)(implicit p: Parameters) extends LazyModule
|
|||||||
}
|
}
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
val (io_devices, edgesIn) = intnode.in.unzip
|
||||||
val tl_in = node.bundleIn
|
val (io_harts, _) = intnode.out.unzip
|
||||||
val devices = intnode.bundleIn
|
|
||||||
val harts = intnode.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compact the interrupt vector the same way
|
// Compact the interrupt vector the same way
|
||||||
val interrupts = (intnode.edgesIn zip io.devices).map { case (e, i) => i.take(e.source.num) }.flatten
|
val interrupts = intnode.in.map { case (i, e) => i.take(e.source.num) }.flatten
|
||||||
// This flattens the harts into an MSMSMSMSMS... or MMMMM.... sequence
|
// This flattens the harts into an MSMSMSMSMS... or MMMMM.... sequence
|
||||||
val harts = io.harts.flatten
|
val harts = io_harts.flatten
|
||||||
|
|
||||||
println(s"Interrupt map (${nHarts} harts ${nDevices} interrupts):")
|
println(s"Interrupt map (${nHarts} harts ${nDevices} interrupts):")
|
||||||
flatSources.foreach { s =>
|
flatSources.foreach { s =>
|
||||||
|
@ -29,16 +29,11 @@ class TLTestRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int
|
|||||||
require ((address.mask & (beatBytes-1)) == beatBytes-1)
|
require ((address.mask & (beatBytes-1)) == beatBytes-1)
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
|
||||||
val in = node.bundleIn
|
|
||||||
}
|
|
||||||
|
|
||||||
def bigBits(x: BigInt, tail: List[Boolean] = List.empty[Boolean]): List[Boolean] =
|
def bigBits(x: BigInt, tail: List[Boolean] = List.empty[Boolean]): List[Boolean] =
|
||||||
if (x == 0) tail.reverse else bigBits(x >> 1, ((x & 1) == 1) :: tail)
|
if (x == 0) tail.reverse else bigBits(x >> 1, ((x & 1) == 1) :: tail)
|
||||||
val mask = bigBits(address.mask >> log2Ceil(beatBytes))
|
val mask = bigBits(address.mask >> log2Ceil(beatBytes))
|
||||||
|
|
||||||
val in = io.in(0)
|
val (in, edge) = node.in(0)
|
||||||
val edge = node.edgesIn(0)
|
|
||||||
|
|
||||||
val addrBits = (mask zip edge.addr_hi(in.a.bits).toBools).filter(_._1).map(_._2)
|
val addrBits = (mask zip edge.addr_hi(in.a.bits).toBools).filter(_._1).map(_._2)
|
||||||
val memAddress = Cat(addrBits.reverse)
|
val memAddress = Cat(addrBits.reverse)
|
||||||
@ -75,7 +70,7 @@ class TLRAMZeroDelay(ramBeatBytes: Int, txns: Int)(implicit p: Parameters) exten
|
|||||||
model.node := fuzz.node
|
model.node := fuzz.node
|
||||||
ram.node := TLDelayer(0.25)(model.node)
|
ram.node := TLDelayer(0.25)(model.node)
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) with HasUnitTestIO {
|
lazy val module = new LazyModuleImp(this) with UnitTestModule {
|
||||||
io.finished := fuzz.module.io.finished
|
io.finished := fuzz.module.io.finished
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,12 +24,7 @@ class TLZero(address: AddressSet, resources: Seq[Resource], executable: Boolean
|
|||||||
minLatency = 1))) // no bypass needed for this device
|
minLatency = 1))) // no bypass needed for this device
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
val (in, edge) = node.in(0)
|
||||||
val in = node.bundleIn
|
|
||||||
}
|
|
||||||
|
|
||||||
val in = io.in(0)
|
|
||||||
val edge = node.edgesIn(0)
|
|
||||||
|
|
||||||
val a = Queue(in.a, 2)
|
val a = Queue(in.a, 2)
|
||||||
val hasData = edge.hasData(a.bits)
|
val hasData = edge.hasData(a.bits)
|
||||||
|
@ -6,6 +6,7 @@ import Chisel._
|
|||||||
import chisel3.experimental.{BaseModule, RawModule, MultiIOModule, withClockAndReset}
|
import chisel3.experimental.{BaseModule, RawModule, MultiIOModule, withClockAndReset}
|
||||||
import chisel3.internal.sourceinfo.{SourceInfo, SourceLine, UnlocatableSourceInfo}
|
import chisel3.internal.sourceinfo.{SourceInfo, SourceLine, UnlocatableSourceInfo}
|
||||||
import freechips.rocketchip.config.Parameters
|
import freechips.rocketchip.config.Parameters
|
||||||
|
import scala.collection.immutable.ListMap
|
||||||
|
|
||||||
abstract class LazyModule()(implicit val p: Parameters)
|
abstract class LazyModule()(implicit val p: Parameters)
|
||||||
{
|
{
|
||||||
@ -54,15 +55,6 @@ abstract class LazyModule()(implicit val p: Parameters)
|
|||||||
|
|
||||||
def module: LazyModuleImpLike
|
def module: LazyModuleImpLike
|
||||||
|
|
||||||
protected[diplomacy] def instantiate() = {
|
|
||||||
children.reverse.foreach { c =>
|
|
||||||
// !!! fix chisel3 so we can pass the desired sourceInfo
|
|
||||||
// implicit val sourceInfo = c.module.outer.info
|
|
||||||
Module(c.module)
|
|
||||||
}
|
|
||||||
bindings.reverse.foreach { f => f () }
|
|
||||||
}
|
|
||||||
|
|
||||||
def omitGraphML: Boolean = !nodes.exists(!_.omitGraphML) && !children.exists(!_.omitGraphML)
|
def omitGraphML: Boolean = !nodes.exists(!_.omitGraphML) && !children.exists(!_.omitGraphML)
|
||||||
lazy val graphML: String = parent.map(_.graphML).getOrElse {
|
lazy val graphML: String = parent.map(_.graphML).getOrElse {
|
||||||
val buf = new StringBuilder
|
val buf = new StringBuilder
|
||||||
@ -144,6 +136,8 @@ object LazyModule
|
|||||||
sealed trait LazyModuleImpLike extends BaseModule
|
sealed trait LazyModuleImpLike extends BaseModule
|
||||||
{
|
{
|
||||||
val wrapper: LazyModule
|
val wrapper: LazyModule
|
||||||
|
val auto: AutoBundle
|
||||||
|
protected[diplomacy] val dangles: Seq[Dangle]
|
||||||
|
|
||||||
// .module had better not be accessed while LazyModules are still being built!
|
// .module had better not be accessed while LazyModules are still being built!
|
||||||
require (LazyModule.stack.isEmpty, s"${wrapper.name}.module was constructed before LazyModule() was run on ${LazyModule.stack.head.name}")
|
require (LazyModule.stack.isEmpty, s"${wrapper.name}.module was constructed before LazyModule() was run on ${LazyModule.stack.head.name}")
|
||||||
@ -152,18 +146,47 @@ sealed trait LazyModuleImpLike extends BaseModule
|
|||||||
suggestName(wrapper.instanceName)
|
suggestName(wrapper.instanceName)
|
||||||
|
|
||||||
implicit val p = wrapper.p
|
implicit val p = wrapper.p
|
||||||
|
|
||||||
|
protected[diplomacy] def instantiate() = {
|
||||||
|
val childDangles = wrapper.children.reverse.flatMap { c =>
|
||||||
|
implicit val sourceInfo = c.info
|
||||||
|
Module(c.module).dangles
|
||||||
|
}
|
||||||
|
val nodeDangles = wrapper.nodes.reverse.flatMap(_.instantiate())
|
||||||
|
val (toConnect, toForward) = (nodeDangles ++ childDangles).groupBy(_.source).partition(_._2.size == 2)
|
||||||
|
val forward = toForward.map(_._2(0)).toList
|
||||||
|
toConnect.foreach { case (_, Seq(a, b)) =>
|
||||||
|
require (a.flipped != b.flipped)
|
||||||
|
if (a.flipped) { a.data <> b.data } else { b.data <> a.data }
|
||||||
|
}
|
||||||
|
val auto = IO(new AutoBundle(forward.map { d => (d.name, d.data, d.flipped) }:_*))
|
||||||
|
val dangles = (forward zip auto.elements) map { case (d, (_, io)) =>
|
||||||
|
if (d.flipped) { d.data <> io } else { io <> d.data }
|
||||||
|
d.copy(data = io, name = wrapper.valName.getOrElse("anon") + "_" + d.name)
|
||||||
|
}
|
||||||
|
wrapper.bindings.reverse.foreach { f => f () }
|
||||||
|
(auto, dangles)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class LazyModuleImp(val wrapper: LazyModule) extends Module with LazyModuleImpLike {
|
abstract class LazyModuleImp(val wrapper: LazyModule) extends MultiIOModule with LazyModuleImpLike {
|
||||||
wrapper.instantiate()
|
val (auto, dangles) = instantiate()
|
||||||
}
|
|
||||||
|
|
||||||
abstract class LazyMultiIOModuleImp(val wrapper: LazyModule) extends MultiIOModule with LazyModuleImpLike {
|
|
||||||
wrapper.instantiate()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class LazyRawModuleImp(val wrapper: LazyModule) extends RawModule with LazyModuleImpLike {
|
abstract class LazyRawModuleImp(val wrapper: LazyModule) extends RawModule with LazyModuleImpLike {
|
||||||
withClockAndReset(Bool(false).asClock, Bool(true)) {
|
val (auto, dangles) = withClockAndReset(Bool(false).asClock, Bool(true)) {
|
||||||
wrapper.instantiate()
|
instantiate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case class HalfEdge(serial: Int, index: Int)
|
||||||
|
case class Dangle(source: HalfEdge, sink: HalfEdge, flipped: Boolean, name: String, data: Data)
|
||||||
|
|
||||||
|
final class AutoBundle(elts: (String, Data, Boolean)*) extends Record {
|
||||||
|
// !!! need to fix-up name collision better than appending _#
|
||||||
|
val elements = ListMap(elts.zipWithIndex map { case ((field, elt, flip), i) =>
|
||||||
|
(field + "_" + i) -> (if (flip) elt.cloneType.flip else elt.cloneType)
|
||||||
|
}:_*)
|
||||||
|
|
||||||
|
override def cloneType = (new AutoBundle(elts:_*)).asInstanceOf[this.type]
|
||||||
|
}
|
||||||
|
@ -34,7 +34,7 @@ private case object MonitorsEnabled extends Field[Boolean](true)
|
|||||||
// BI = Bundle type used when connecting to the inner side of the node
|
// BI = Bundle type used when connecting to the inner side of the node
|
||||||
trait InwardNodeImp[DI, UI, EI, BI <: Data]
|
trait InwardNodeImp[DI, UI, EI, BI <: Data]
|
||||||
{
|
{
|
||||||
def edgeI(pd: DI, pu: UI): EI
|
def edgeI(pd: DI, pu: UI, p: Parameters): EI
|
||||||
def bundleI(ei: EI): BI
|
def bundleI(ei: EI): BI
|
||||||
def colour: String
|
def colour: String
|
||||||
def reverse: Boolean = false
|
def reverse: Boolean = false
|
||||||
@ -55,7 +55,7 @@ trait InwardNodeImp[DI, UI, EI, BI <: Data]
|
|||||||
// BO = Bundle type used when connecting to the outer side of the node
|
// BO = Bundle type used when connecting to the outer side of the node
|
||||||
trait OutwardNodeImp[DO, UO, EO, BO <: Data]
|
trait OutwardNodeImp[DO, UO, EO, BO <: Data]
|
||||||
{
|
{
|
||||||
def edgeO(pd: DO, pu: UO): EO
|
def edgeO(pd: DO, pu: UO, p: Parameters): EO
|
||||||
def bundleO(eo: EO): BO
|
def bundleO(eo: EO): BO
|
||||||
|
|
||||||
// optional methods to track node graph
|
// optional methods to track node graph
|
||||||
@ -75,11 +75,11 @@ abstract class BaseNode(implicit val valName: ValName)
|
|||||||
val index = lazyModule.nodes.size
|
val index = lazyModule.nodes.size
|
||||||
lazyModule.nodes = this :: lazyModule.nodes
|
lazyModule.nodes = this :: lazyModule.nodes
|
||||||
|
|
||||||
val externalIn: Boolean
|
val serial = BaseNode.serial
|
||||||
val externalOut: Boolean
|
BaseNode.serial = BaseNode.serial + 1
|
||||||
|
protected[diplomacy] def instantiate(): Seq[Dangle]
|
||||||
|
|
||||||
def nodename = getClass.getName.split('.').last
|
def name = lazyModule.name + "." + valName.name
|
||||||
def name = lazyModule.name + "." + nodename
|
|
||||||
def omitGraphML = outputs.isEmpty && inputs.isEmpty
|
def omitGraphML = outputs.isEmpty && inputs.isEmpty
|
||||||
lazy val nodedebugstring: String = ""
|
lazy val nodedebugstring: String = ""
|
||||||
|
|
||||||
@ -91,6 +91,11 @@ abstract class BaseNode(implicit val valName: ValName)
|
|||||||
protected[diplomacy] def reverse: Boolean
|
protected[diplomacy] def reverse: Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object BaseNode
|
||||||
|
{
|
||||||
|
protected[diplomacy] var serial = 0
|
||||||
|
}
|
||||||
|
|
||||||
case class NodeHandle[DI, UI, BI <: Data, DO, UO, BO <: Data]
|
case class NodeHandle[DI, UI, BI <: Data, DO, UO, BO <: Data]
|
||||||
(inward: InwardNode[DI, UI, BI], outward: OutwardNode[DO, UO, BO])
|
(inward: InwardNode[DI, UI, BI], outward: OutwardNode[DO, UO, BO])
|
||||||
extends Object with InwardNodeHandle[DI, UI, BI] with OutwardNodeHandle[DO, UO, BO]
|
extends Object with InwardNodeHandle[DI, UI, BI] with OutwardNodeHandle[DO, UO, BO]
|
||||||
@ -138,7 +143,6 @@ trait InwardNode[DI, UI, BI <: Data] extends BaseNode with InwardNodeHandle[DI,
|
|||||||
protected[diplomacy] val iStar: Int
|
protected[diplomacy] val iStar: Int
|
||||||
protected[diplomacy] val iPortMapping: Seq[(Int, Int)]
|
protected[diplomacy] val iPortMapping: Seq[(Int, Int)]
|
||||||
protected[diplomacy] val iParams: Seq[UI]
|
protected[diplomacy] val iParams: Seq[UI]
|
||||||
protected[diplomacy] val bundleIn: HeterogeneousBag[BI]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trait OutwardNodeHandle[DO, UO, BO <: Data]
|
trait OutwardNodeHandle[DO, UO, BO <: Data]
|
||||||
@ -171,10 +175,9 @@ trait OutwardNode[DO, UO, BO <: Data] extends BaseNode with OutwardNodeHandle[DO
|
|||||||
protected[diplomacy] val oStar: Int
|
protected[diplomacy] val oStar: Int
|
||||||
protected[diplomacy] val oPortMapping: Seq[(Int, Int)]
|
protected[diplomacy] val oPortMapping: Seq[(Int, Int)]
|
||||||
protected[diplomacy] val oParams: Seq[DO]
|
protected[diplomacy] val oParams: Seq[DO]
|
||||||
protected[diplomacy] val bundleOut: HeterogeneousBag[BO]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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],
|
inner: InwardNodeImp [DI, UI, EI, BI],
|
||||||
outer: OutwardNodeImp[DO, UO, EO, BO])(
|
outer: OutwardNodeImp[DO, UO, EO, BO])(
|
||||||
protected[diplomacy] val numPO: Range.Inclusive,
|
protected[diplomacy] val numPO: Range.Inclusive,
|
||||||
@ -213,22 +216,22 @@ abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
|||||||
(oSum.init zip oSum.tail, iSum.init zip iSum.tail, oStar, iStar)
|
(oSum.init zip oSum.tail, iSum.init zip iSum.tail, oStar, iStar)
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy val oPorts = oBindings.flatMap { case (i, n, _, _) =>
|
lazy val oPorts = oBindings.flatMap { case (i, n, _, p) =>
|
||||||
val (start, end) = n.iPortMapping(i)
|
val (start, end) = n.iPortMapping(i)
|
||||||
(start until end) map { j => (j, n) }
|
(start until end) map { j => (j, n, p) }
|
||||||
}
|
}
|
||||||
lazy val iPorts = iBindings.flatMap { case (i, n, _, _) =>
|
lazy val iPorts = iBindings.flatMap { case (i, n, _, p) =>
|
||||||
val (start, end) = n.oPortMapping(i)
|
val (start, end) = n.oPortMapping(i)
|
||||||
(start until end) map { j => (j, n) }
|
(start until end) map { j => (j, n, p) }
|
||||||
}
|
}
|
||||||
|
|
||||||
protected[diplomacy] lazy val oParams: Seq[DO] = {
|
protected[diplomacy] lazy val oParams: Seq[DO] = {
|
||||||
val o = mapParamsD(oPorts.size, iPorts.map { case (i, n) => n.oParams(i) })
|
val o = mapParamsD(oPorts.size, iPorts.map { case (i, n, _) => n.oParams(i) })
|
||||||
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))
|
||||||
}
|
}
|
||||||
protected[diplomacy] lazy val iParams: Seq[UI] = {
|
protected[diplomacy] lazy val iParams: Seq[UI] = {
|
||||||
val i = mapParamsU(iPorts.size, oPorts.map { case (o, n) => n.iParams(o) })
|
val i = mapParamsU(iPorts.size, oPorts.map { case (o, n, _) => n.iParams(o) })
|
||||||
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))
|
||||||
}
|
}
|
||||||
@ -236,23 +239,48 @@ 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 (iParams.size != 1) None else inner.getO(iParams(0))
|
||||||
protected[diplomacy] def gci = if (oParams.size != 1) None else outer.getI(oParams(0))
|
protected[diplomacy] def gci = if (oParams.size != 1) None else outer.getI(oParams(0))
|
||||||
|
|
||||||
lazy val edgesOut = (oPorts zip oParams).map { case ((i, n), o) => outer.edgeO(o, n.iParams(i)) }
|
protected[diplomacy] lazy val edgesOut = (oPorts zip oParams).map { case ((i, n, p), o) => outer.edgeO(o, n.iParams(i), p) }
|
||||||
lazy val edgesIn = (iPorts zip iParams).map { case ((o, n), i) => inner.edgeI(n.oParams(o), i) }
|
protected[diplomacy] lazy val edgesIn = (iPorts zip iParams).map { case ((o, n, p), i) => inner.edgeI(n.oParams(o), i, p) }
|
||||||
lazy val externalEdgesOut = if (externalOut) {edgesOut} else { Seq() }
|
|
||||||
lazy val externalEdgesIn = if (externalIn) {edgesIn} else { Seq() }
|
|
||||||
|
|
||||||
lazy val paramsOut: Seq[Parameters] = (oPortMapping zip oBindings).flatMap { case ((s, e), b) => Seq.fill(e-s) { b._4 } }
|
// If you need access to the edges of a foreign Node, use this method (in/out create bundles)
|
||||||
lazy val paramsIn: Seq[Parameters] = (iPortMapping zip iBindings).flatMap { case ((s, e), b) => Seq.fill(e-s) { b._4 } }
|
lazy val edges = (edgesIn, edgesOut)
|
||||||
|
|
||||||
val flip = false // needed for blind nodes
|
protected[diplomacy] lazy val bundleOut: Seq[BO] = edgesOut.map(e => Wire(outer.bundleO(e)))
|
||||||
private def flipO(b: HeterogeneousBag[BO]) = if (flip) b.flip else b
|
protected[diplomacy] lazy val bundleIn: Seq[BI] = edgesIn .map(e => Wire(inner.bundleI(e)))
|
||||||
private def flipI(b: HeterogeneousBag[BI]) = if (flip) b else b.flip
|
|
||||||
val wire = false // needed if you want to grab access to from inside a module
|
|
||||||
private def wireO(b: HeterogeneousBag[BO]) = if (wire) Wire(b) else b
|
|
||||||
private def wireI(b: HeterogeneousBag[BI]) = if (wire) Wire(b) else b
|
|
||||||
|
|
||||||
lazy val bundleOut = wireO(flipO(HeterogeneousBag(edgesOut.map(outer.bundleO(_)))))
|
protected[diplomacy] def danglesOut: Seq[Dangle] = oPorts.zipWithIndex.map { case ((j, n, _), i) =>
|
||||||
lazy val bundleIn = wireI(flipI(HeterogeneousBag(edgesIn .map(inner.bundleI(_)))))
|
Dangle(
|
||||||
|
source = HalfEdge(serial, i),
|
||||||
|
sink = HalfEdge(n.serial, j),
|
||||||
|
flipped= false,
|
||||||
|
name = valName.name + "_out",
|
||||||
|
data = bundleOut(i))
|
||||||
|
}
|
||||||
|
protected[diplomacy] def danglesIn: Seq[Dangle] = iPorts.zipWithIndex.map { case ((j, n, _), i) =>
|
||||||
|
Dangle(
|
||||||
|
source = HalfEdge(n.serial, j),
|
||||||
|
sink = HalfEdge(serial, i),
|
||||||
|
flipped= true,
|
||||||
|
name = valName.name + "_in",
|
||||||
|
data = bundleIn(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used by LazyModules.module.instantiate
|
||||||
|
private var bundlesSafeNow = false
|
||||||
|
protected[diplomacy] def instantiate() = {
|
||||||
|
bundlesSafeNow = true
|
||||||
|
danglesOut ++ danglesIn
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accessors to the result of negotiation to be used in LazyModuleImp:
|
||||||
|
def out: Seq[(BO, EO)] = {
|
||||||
|
require(bundlesSafeNow, s"${name}.out should only be called from the context of it's module implementation")
|
||||||
|
bundleOut zip edgesOut
|
||||||
|
}
|
||||||
|
def in: Seq[(BI, EI)] = {
|
||||||
|
require(bundlesSafeNow, s"${name}.in should only be called from the context of it's module implementation")
|
||||||
|
bundleIn zip edgesIn
|
||||||
|
}
|
||||||
|
|
||||||
// connects the outward part of a node with the inward part of this node
|
// connects the outward part of a node with the inward part of this node
|
||||||
private def bind(h: OutwardNodeHandle[DI, UI, BI], binding: NodeBinding)
|
private def bind(h: OutwardNodeHandle[DI, UI, BI], binding: NodeBinding)
|
||||||
@ -268,23 +296,7 @@ abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
|||||||
case BIND_STAR => BIND_QUERY
|
case BIND_STAR => BIND_QUERY
|
||||||
case BIND_QUERY => BIND_STAR })
|
case BIND_QUERY => BIND_STAR })
|
||||||
x.iPush(o, y, binding)
|
x.iPush(o, y, binding)
|
||||||
def edges() = {
|
None // !!! create monitors
|
||||||
val (iStart, iEnd) = x.iPortMapping(i)
|
|
||||||
val (oStart, oEnd) = y.oPortMapping(o)
|
|
||||||
require (iEnd - iStart == oEnd - oStart, s"Bug in diplomacy; ${iEnd-iStart} != ${oEnd-oStart} means port resolution failed")
|
|
||||||
Seq.tabulate(iEnd - iStart) { j => x.edgesIn(iStart+j) }
|
|
||||||
}
|
|
||||||
def bundles() = {
|
|
||||||
val (iStart, iEnd) = x.iPortMapping(i)
|
|
||||||
val (oStart, oEnd) = y.oPortMapping(o)
|
|
||||||
require (iEnd - iStart == oEnd - oStart, s"Bug in diplomacy; ${iEnd-iStart} != ${oEnd-oStart} means port resolution failed")
|
|
||||||
Seq.tabulate(iEnd - iStart) { j =>
|
|
||||||
(x.bundleIn(iStart+j), y.bundleOut(oStart+j))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val (out, newbinding) = inner.connect(edges _, bundles _, p(MonitorsEnabled))
|
|
||||||
LazyModule.stack.head.bindings = newbinding :: LazyModule.stack.head.bindings
|
|
||||||
out
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override def := (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_ONCE)
|
override def := (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_ONCE)
|
||||||
@ -333,9 +345,6 @@ class MixedAdapterNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
|||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends MixedNode(inner, outer)(num, num)
|
extends MixedNode(inner, outer)(num, num)
|
||||||
{
|
{
|
||||||
val externalIn: Boolean = true
|
|
||||||
val externalOut: Boolean = true
|
|
||||||
|
|
||||||
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) {
|
||||||
@ -356,6 +365,24 @@ 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])(
|
||||||
|
dFn: D => D,
|
||||||
|
uFn: U => U,
|
||||||
|
num: Range.Inclusive = 0 to 999)(
|
||||||
|
implicit valName: ValName)
|
||||||
|
extends MixedAdapterNode[D, U, EI, B, D, U, EO, B](imp, imp)(dFn, uFn, num)
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
extends AdapterNode(imp)({ s => s }, { s => s })
|
||||||
|
{
|
||||||
|
override protected[diplomacy] def instantiate() = {
|
||||||
|
val dangles = super.instantiate()
|
||||||
|
(out zip in) map { case ((o, _), (i, _)) => o <> i }
|
||||||
|
dangles
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class MixedNexusNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
class MixedNexusNode[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])(
|
||||||
@ -369,9 +396,6 @@ class MixedNexusNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
|||||||
// require (numPO.end >= 1, s"${name} does not accept outputs${lazyModule.line}")
|
// require (numPO.end >= 1, s"${name} does not accept outputs${lazyModule.line}")
|
||||||
// require (numPI.end >= 1, s"${name} does not accept inputs${lazyModule.line}")
|
// require (numPI.end >= 1, s"${name} does not accept inputs${lazyModule.line}")
|
||||||
|
|
||||||
val externalIn: Boolean = true
|
|
||||||
val externalOut: Boolean = true
|
|
||||||
|
|
||||||
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}")
|
require (iStars == 0, s"${name} (a nexus) appears left of :*= (perhaps you should flip the '*' to :=*?)${lazyModule.line}")
|
||||||
require (oStars == 0, s"${name} (a nexus) appears right of a :=* (perhaps you should flip the '*' to :*=?)${lazyModule.line}")
|
require (oStars == 0, s"${name} (a nexus) appears right of a :=* (perhaps you should flip the '*' to :*=?)${lazyModule.line}")
|
||||||
@ -381,13 +405,6 @@ class MixedNexusNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
|||||||
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] = { val a = uFn(p); Seq.fill(n)(a) }
|
||||||
}
|
}
|
||||||
|
|
||||||
class AdapterNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(
|
|
||||||
dFn: D => D,
|
|
||||||
uFn: U => U,
|
|
||||||
num: Range.Inclusive = 0 to 999)(
|
|
||||||
implicit valName: ValName)
|
|
||||||
extends MixedAdapterNode[D, U, EI, B, D, U, EO, B](imp, imp)(dFn, uFn, num)
|
|
||||||
|
|
||||||
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,
|
||||||
@ -396,30 +413,10 @@ class NexusNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(
|
|||||||
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, numPO, numPI)
|
||||||
|
|
||||||
class IdentityNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(implicit valName: ValName)
|
// There are no Mixed SourceNodes
|
||||||
extends AdapterNode(imp)({s => s}, {s => s})
|
|
||||||
|
|
||||||
class OutputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(implicit valName: ValName) extends IdentityNode(imp)
|
|
||||||
{
|
|
||||||
override val externalIn: Boolean = false
|
|
||||||
override val externalOut: Boolean = true
|
|
||||||
override lazy val bundleIn = bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
class InputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(implicit valName: ValName) extends IdentityNode(imp)
|
|
||||||
{
|
|
||||||
override val externalIn: Boolean = true
|
|
||||||
override val externalOut: Boolean = false
|
|
||||||
|
|
||||||
override lazy val bundleOut = bundleIn
|
|
||||||
}
|
|
||||||
|
|
||||||
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)(po.size to po.size, 0 to 0)
|
||||||
{
|
{
|
||||||
override val externalIn: Boolean = false
|
|
||||||
override val externalOut: Boolean = true
|
|
||||||
|
|
||||||
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}")
|
||||||
@ -429,16 +426,12 @@ class SourceNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq
|
|||||||
}
|
}
|
||||||
protected[diplomacy] def mapParamsD(n: Int, p: Seq[D]): Seq[D] = po
|
protected[diplomacy] def mapParamsD(n: Int, p: Seq[D]): Seq[D] = po
|
||||||
protected[diplomacy] def mapParamsU(n: Int, p: Seq[U]): Seq[U] = Seq()
|
protected[diplomacy] def mapParamsU(n: Int, p: Seq[U]): Seq[U] = Seq()
|
||||||
|
|
||||||
override lazy val bundleIn = { require(false, s"${name} has no bundleIn; try bundleOut?"); bundleOut }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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)(0 to 0, pi.size to pi.size)
|
||||||
{
|
{
|
||||||
override val externalIn: Boolean = true
|
|
||||||
override val externalOut: Boolean = false
|
|
||||||
|
|
||||||
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}")
|
||||||
@ -448,40 +441,4 @@ class SinkNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U
|
|||||||
}
|
}
|
||||||
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
|
||||||
|
|
||||||
override lazy val bundleOut = { require(false, s"${name} has no bundleOut; try bundleIn?"); bundleIn }
|
|
||||||
}
|
|
||||||
|
|
||||||
class BlindOutputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U])(implicit valName: ValName)
|
|
||||||
extends SinkNode(imp)(pi)
|
|
||||||
{
|
|
||||||
override val externalIn: Boolean = false
|
|
||||||
override val flip = true
|
|
||||||
override lazy val bundleOut = bundleIn
|
|
||||||
}
|
|
||||||
|
|
||||||
class BlindInputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq[D])(implicit valName: ValName)
|
|
||||||
extends SourceNode(imp)(po)
|
|
||||||
{
|
|
||||||
override val externalOut: Boolean = false
|
|
||||||
override val flip = true
|
|
||||||
override lazy val bundleIn = bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
class InternalOutputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U])(implicit valName: ValName)
|
|
||||||
extends SinkNode(imp)(pi)
|
|
||||||
{
|
|
||||||
override val externalIn: Boolean = false
|
|
||||||
override val externalOut: Boolean = false
|
|
||||||
override val wire = true
|
|
||||||
override lazy val bundleOut = bundleIn
|
|
||||||
}
|
|
||||||
|
|
||||||
class InternalInputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq[D])(implicit valName: ValName)
|
|
||||||
extends SourceNode(imp)(po)
|
|
||||||
{
|
|
||||||
override val externalIn: Boolean = false
|
|
||||||
override val externalOut: Boolean = false
|
|
||||||
override val wire = true
|
|
||||||
override lazy val bundleIn = bundleOut
|
|
||||||
}
|
}
|
||||||
|
@ -37,11 +37,9 @@ class BusErrorUnit[T <: BusErrors](t: => T, params: BusErrorUnitParams)(implicit
|
|||||||
beatBytes = p(XLen)/8)
|
beatBytes = p(XLen)/8)
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
val io = IO(new Bundle {
|
||||||
val tl = node.bundleIn
|
|
||||||
val interrupt = intNode.bundleOut
|
|
||||||
val errors = t.flip
|
val errors = t.flip
|
||||||
}
|
})
|
||||||
|
|
||||||
val sources = io.errors.toErrorList
|
val sources = io.errors.toErrorList
|
||||||
val mask = sources.map(_.nonEmpty.B).asUInt
|
val mask = sources.map(_.nonEmpty.B).asUInt
|
||||||
@ -61,7 +59,8 @@ class BusErrorUnit[T <: BusErrors](t: => T, params: BusErrorUnitParams)(implicit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
io.interrupt.head(0) := (accrued & interrupt).orR
|
val (int_out, _) = intNode.out(0)
|
||||||
|
int_out(0) := (accrued & interrupt).orR
|
||||||
|
|
||||||
def reg(r: UInt) = RegField(regWidth, r)
|
def reg(r: UInt) = RegField(regWidth, r)
|
||||||
def maskedReg(r: UInt, m: UInt) = RegField(regWidth, r, RegWriteFn((v, d) => { when (v) { r := d & m }; true }))
|
def maskedReg(r: UInt, m: UInt) = RegField(regWidth, r, RegWriteFn((v, d) => { when (v) { r := d & m }; true }))
|
||||||
|
@ -56,8 +56,8 @@ class FrontendIO(implicit p: Parameters) extends CoreBundle()(p) {
|
|||||||
class Frontend(val icacheParams: ICacheParams, hartid: Int)(implicit p: Parameters) extends LazyModule {
|
class Frontend(val icacheParams: ICacheParams, hartid: Int)(implicit p: Parameters) extends LazyModule {
|
||||||
lazy val module = new FrontendModule(this)
|
lazy val module = new FrontendModule(this)
|
||||||
val icache = LazyModule(new ICache(icacheParams, hartid))
|
val icache = LazyModule(new ICache(icacheParams, hartid))
|
||||||
val masterNode = TLOutputNode()
|
val masterNode = TLIdentityNode()
|
||||||
val slaveNode = TLInputNode()
|
val slaveNode = TLIdentityNode()
|
||||||
|
|
||||||
masterNode := icache.masterNode
|
masterNode := icache.masterNode
|
||||||
// Avoid breaking tile dedup due to address constants in the monitor
|
// Avoid breaking tile dedup due to address constants in the monitor
|
||||||
@ -68,16 +68,14 @@ class FrontendBundle(outer: Frontend) extends CoreBundle()(outer.p)
|
|||||||
with HasExternallyDrivenTileConstants {
|
with HasExternallyDrivenTileConstants {
|
||||||
val cpu = new FrontendIO().flip
|
val cpu = new FrontendIO().flip
|
||||||
val ptw = new TLBPTWIO()
|
val ptw = new TLBPTWIO()
|
||||||
val tl_out = outer.masterNode.bundleOut
|
|
||||||
val tl_in = outer.slaveNode.bundleIn
|
|
||||||
val errors = new ICacheErrors
|
val errors = new ICacheErrors
|
||||||
}
|
}
|
||||||
|
|
||||||
class FrontendModule(outer: Frontend) extends LazyModuleImp(outer)
|
class FrontendModule(outer: Frontend) extends LazyModuleImp(outer)
|
||||||
with HasCoreParameters
|
with HasCoreParameters
|
||||||
with HasL1ICacheParameters {
|
with HasL1ICacheParameters {
|
||||||
val io = new FrontendBundle(outer)
|
val io = IO(new FrontendBundle(outer))
|
||||||
implicit val edge = outer.masterNode.edgesOut.head
|
implicit val edge = outer.masterNode.out(0)._2
|
||||||
val icache = outer.icache.module
|
val icache = outer.icache.module
|
||||||
require(fetchWidth*coreInstBytes == outer.icacheParams.fetchBytes)
|
require(fetchWidth*coreInstBytes == outer.icacheParams.fetchBytes)
|
||||||
|
|
||||||
|
@ -176,15 +176,14 @@ class HellaCacheBundle(outer: HellaCache)(implicit p: Parameters) extends CoreBu
|
|||||||
val hartid = UInt(INPUT, hartIdLen)
|
val hartid = UInt(INPUT, hartIdLen)
|
||||||
val cpu = (new HellaCacheIO).flip
|
val cpu = (new HellaCacheIO).flip
|
||||||
val ptw = new TLBPTWIO()
|
val ptw = new TLBPTWIO()
|
||||||
val mem = outer.node.bundleOut
|
|
||||||
val errors = new DCacheErrors
|
val errors = new DCacheErrors
|
||||||
}
|
}
|
||||||
|
|
||||||
class HellaCacheModule(outer: HellaCache) extends LazyModuleImp(outer)
|
class HellaCacheModule(outer: HellaCache) extends LazyModuleImp(outer)
|
||||||
with HasL1HellaCacheParameters {
|
with HasL1HellaCacheParameters {
|
||||||
implicit val edge = outer.node.edgesOut(0)
|
implicit val edge = outer.node.out(0)._2
|
||||||
val io = new HellaCacheBundle(outer)
|
val tl_out = outer.node.out(0)._1
|
||||||
val tl_out = io.mem(0)
|
val io = IO(new HellaCacheBundle(outer))
|
||||||
|
|
||||||
private val fifoManagers = edge.manager.managers.filter(TLFIFOFixer.allUncacheable)
|
private val fifoManagers = edge.manager.managers.filter(TLFIFOFixer.allUncacheable)
|
||||||
fifoManagers.foreach { m =>
|
fifoManagers.foreach { m =>
|
||||||
|
@ -45,9 +45,9 @@ class ICacheErrors(implicit p: Parameters) extends CoreBundle()(p)
|
|||||||
|
|
||||||
class ICache(val icacheParams: ICacheParams, val hartid: Int)(implicit p: Parameters) extends LazyModule {
|
class ICache(val icacheParams: ICacheParams, val hartid: Int)(implicit p: Parameters) extends LazyModule {
|
||||||
lazy val module = new ICacheModule(this)
|
lazy val module = new ICacheModule(this)
|
||||||
val masterNode = TLClientNode(TLClientParameters(
|
val masterNode = TLClientNode(Seq(TLClientPortParameters(Seq(TLClientParameters(
|
||||||
sourceId = IdRange(0, 1 + icacheParams.prefetch.toInt), // 0=refill, 1=hint
|
sourceId = IdRange(0, 1 + icacheParams.prefetch.toInt), // 0=refill, 1=hint
|
||||||
name = s"Core ${hartid} ICache"))
|
name = s"Core ${hartid} ICache")))))
|
||||||
|
|
||||||
val size = icacheParams.nSets * icacheParams.nWays * icacheParams.blockBytes
|
val size = icacheParams.nSets * icacheParams.nWays * icacheParams.blockBytes
|
||||||
val device = new SimpleDevice("itim", Seq("sifive,itim0"))
|
val device = new SimpleDevice("itim", Seq("sifive,itim0"))
|
||||||
@ -91,8 +91,6 @@ class ICacheBundle(outer: ICache) extends CoreBundle()(outer.p) {
|
|||||||
|
|
||||||
val resp = Valid(new ICacheResp(outer))
|
val resp = Valid(new ICacheResp(outer))
|
||||||
val invalidate = Bool(INPUT)
|
val invalidate = Bool(INPUT)
|
||||||
val tl_out = outer.masterNode.bundleOut
|
|
||||||
val tl_in = outer.slaveNode.map(_.bundleIn)
|
|
||||||
|
|
||||||
val errors = new ICacheErrors
|
val errors = new ICacheErrors
|
||||||
val perf = new ICachePerfEvents().asOutput
|
val perf = new ICachePerfEvents().asOutput
|
||||||
@ -109,11 +107,10 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer)
|
|||||||
with HasL1ICacheParameters {
|
with HasL1ICacheParameters {
|
||||||
override val cacheParams = outer.icacheParams // Use the local parameters
|
override val cacheParams = outer.icacheParams // Use the local parameters
|
||||||
|
|
||||||
val io = new ICacheBundle(outer)
|
val io = IO(new ICacheBundle(outer))
|
||||||
val edge_out = outer.masterNode.edgesOut.head
|
val (tl_out, edge_out) = outer.masterNode.out(0)
|
||||||
val tl_out = io.tl_out.head
|
val tl_in = outer.slaveNode.map(_.in(0)._1)
|
||||||
val edge_in = outer.slaveNode.map(_.edgesIn.head)
|
val edge_in = outer.slaveNode.map(_.in(0)._2)
|
||||||
val tl_in = io.tl_in.map(_.head)
|
|
||||||
|
|
||||||
val tECC = cacheParams.tagECC
|
val tECC = cacheParams.tagECC
|
||||||
val dECC = cacheParams.dataECC
|
val dECC = cacheParams.dataECC
|
||||||
|
@ -283,7 +283,7 @@ trait CanHavePTW extends HasHellaCache {
|
|||||||
trait CanHavePTWModule extends HasHellaCacheModule {
|
trait CanHavePTWModule extends HasHellaCacheModule {
|
||||||
val outer: CanHavePTW
|
val outer: CanHavePTW
|
||||||
val ptwPorts = ListBuffer(outer.dcache.module.io.ptw)
|
val ptwPorts = ListBuffer(outer.dcache.module.io.ptw)
|
||||||
val ptw = Module(new PTW(outer.nPTWPorts)(outer.dcache.node.edgesOut(0), outer.p))
|
val ptw = Module(new PTW(outer.nPTWPorts)(outer.dcache.node.out(0)._2, outer.p))
|
||||||
if (outer.usingPTW)
|
if (outer.usingPTW)
|
||||||
dcachePorts += ptw.io.mem
|
dcachePorts += ptw.io.mem
|
||||||
}
|
}
|
||||||
|
@ -30,13 +30,11 @@ class ScratchpadSlavePort(address: AddressSet, coreDataBytes: Int, usingAtomics:
|
|||||||
minLatency = 1)))
|
minLatency = 1)))
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
val io = IO(new Bundle {
|
||||||
val tl_in = node.bundleIn
|
|
||||||
val dmem = new HellaCacheIO
|
val dmem = new HellaCacheIO
|
||||||
}
|
})
|
||||||
|
|
||||||
val tl_in = io.tl_in(0)
|
val (tl_in, edge) = node.in(0)
|
||||||
val edge = node.edgesIn(0)
|
|
||||||
|
|
||||||
val s_ready :: s_wait :: s_replay :: s_grant :: Nil = Enum(UInt(), 4)
|
val s_ready :: s_wait :: s_replay :: s_grant :: Nil = Enum(UInt(), 4)
|
||||||
val state = Reg(init = s_ready)
|
val state = Reg(init = s_ready)
|
||||||
@ -104,7 +102,7 @@ trait CanHaveScratchpad extends HasHellaCache with HasICacheFrontend {
|
|||||||
LazyModule(new ScratchpadSlavePort(AddressSet(s, d.dataScratchpadBytes-1), xBytes, tileParams.core.useAtomics)))
|
LazyModule(new ScratchpadSlavePort(AddressSet(s, d.dataScratchpadBytes-1), xBytes, tileParams.core.useAtomics)))
|
||||||
}
|
}
|
||||||
|
|
||||||
val intOutputNode = tileParams.core.tileControlAddr.map(dummy => IntOutputNode())
|
val intOutputNode = tileParams.core.tileControlAddr.map(dummy => IntIdentityNode())
|
||||||
val busErrorUnit = tileParams.core.tileControlAddr map { a =>
|
val busErrorUnit = tileParams.core.tileControlAddr map { a =>
|
||||||
val beu = LazyModule(new BusErrorUnit(new L1BusErrors, BusErrorUnitParams(a)))
|
val beu = LazyModule(new BusErrorUnit(new L1BusErrors, BusErrorUnitParams(a)))
|
||||||
intOutputNode.get := beu.intNode
|
intOutputNode.get := beu.intNode
|
||||||
@ -112,7 +110,7 @@ trait CanHaveScratchpad extends HasHellaCache with HasICacheFrontend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// connect any combination of ITIM, DTIM, and BusErrorUnit
|
// connect any combination of ITIM, DTIM, and BusErrorUnit
|
||||||
val slaveNode = TLInputNode()
|
val slaveNode = TLIdentityNode()
|
||||||
DisableMonitors { implicit p =>
|
DisableMonitors { implicit p =>
|
||||||
val xbarPorts =
|
val xbarPorts =
|
||||||
scratch.map(lm => (lm.node, xBytes)) ++
|
scratch.map(lm => (lm.node, xBytes)) ++
|
||||||
@ -129,7 +127,7 @@ trait CanHaveScratchpad extends HasHellaCache with HasICacheFrontend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def findScratchpadFromICache: Option[AddressSet] = scratch.map { s =>
|
def findScratchpadFromICache: Option[AddressSet] = scratch.map { s =>
|
||||||
val finalNode = frontend.masterNode.edgesOut.head.manager.managers.find(_.nodePath.last == s.node)
|
val finalNode = frontend.masterNode.out.head._2.manager.managers.find(_.nodePath.last == s.node)
|
||||||
require (finalNode.isDefined, "Could not find the scratch pad; not reachable via icache?")
|
require (finalNode.isDefined, "Could not find the scratch pad; not reachable via icache?")
|
||||||
require (finalNode.get.address.size == 1, "Scratchpad address space was fragmented!")
|
require (finalNode.get.address.size == 1, "Scratchpad address space was fragmented!")
|
||||||
finalNode.get.address(0)
|
finalNode.get.address(0)
|
||||||
@ -140,8 +138,6 @@ trait CanHaveScratchpad extends HasHellaCache with HasICacheFrontend {
|
|||||||
|
|
||||||
trait CanHaveScratchpadBundle extends HasHellaCacheBundle with HasICacheFrontendBundle {
|
trait CanHaveScratchpadBundle extends HasHellaCacheBundle with HasICacheFrontendBundle {
|
||||||
val outer: CanHaveScratchpad
|
val outer: CanHaveScratchpad
|
||||||
val slave = outer.slaveNode.bundleIn
|
|
||||||
val intOutput = outer.intOutputNode.map(_.bundleOut)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trait CanHaveScratchpadModule extends HasHellaCacheModule with HasICacheFrontendModule {
|
trait CanHaveScratchpadModule extends HasHellaCacheModule with HasICacheFrontendModule {
|
||||||
|
@ -66,21 +66,20 @@ abstract class BareTileBundle[+L <: BareTile](_outer: L) extends GenericParamete
|
|||||||
|
|
||||||
abstract class BareTileModule[+L <: BareTile, +B <: BareTileBundle[L]](_outer: L, _io: () => B) extends LazyModuleImp(_outer) {
|
abstract class BareTileModule[+L <: BareTile, +B <: BareTileBundle[L]](_outer: L, _io: () => B) extends LazyModuleImp(_outer) {
|
||||||
val outer = _outer
|
val outer = _outer
|
||||||
val io = _io ()
|
val io = IO(_io ())
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Uses TileLink master port to connect caches and accelerators to the coreplex */
|
/** Uses TileLink master port to connect caches and accelerators to the coreplex */
|
||||||
trait HasTileLinkMasterPort {
|
trait HasTileLinkMasterPort {
|
||||||
implicit val p: Parameters
|
implicit val p: Parameters
|
||||||
val module: HasTileLinkMasterPortModule
|
val module: HasTileLinkMasterPortModule
|
||||||
val masterNode = TLOutputNode()
|
val masterNode = TLIdentityNode()
|
||||||
val tileBus = LazyModule(new TLXbar) // TileBus xbar for cache backends to connect to
|
val tileBus = LazyModule(new TLXbar) // TileBus xbar for cache backends to connect to
|
||||||
masterNode := tileBus.node
|
masterNode := tileBus.node
|
||||||
}
|
}
|
||||||
|
|
||||||
trait HasTileLinkMasterPortBundle {
|
trait HasTileLinkMasterPortBundle {
|
||||||
val outer: HasTileLinkMasterPort
|
val outer: HasTileLinkMasterPort
|
||||||
val master = outer.masterNode.bundleOut
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trait HasTileLinkMasterPortModule {
|
trait HasTileLinkMasterPortModule {
|
||||||
|
@ -38,7 +38,6 @@ trait HasExternalInterrupts extends HasTileParameters {
|
|||||||
|
|
||||||
trait HasExternalInterruptsBundle {
|
trait HasExternalInterruptsBundle {
|
||||||
val outer: HasExternalInterrupts
|
val outer: HasExternalInterrupts
|
||||||
val interrupts = outer.intNode.bundleIn
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trait HasExternalInterruptsModule {
|
trait HasExternalInterruptsModule {
|
||||||
@ -57,6 +56,6 @@ trait HasExternalInterruptsModule {
|
|||||||
|
|
||||||
val core_ips = core.lip
|
val core_ips = core.lip
|
||||||
|
|
||||||
(async_ips ++ periph_ips ++ seip ++ core_ips).zip(io.interrupts(0)).foreach { case(c, i) => c := i }
|
(async_ips ++ periph_ips ++ seip ++ core_ips).zip(outer.intNode.in(0)._1).foreach { case(c, i) => c := i }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,13 +60,11 @@ class RoCCCoreIO(implicit p: Parameters) extends CoreBundle()(p) {
|
|||||||
abstract class LazyRoCC(implicit p: Parameters) extends LazyModule {
|
abstract class LazyRoCC(implicit p: Parameters) extends LazyModule {
|
||||||
val module: LazyRoCCModule
|
val module: LazyRoCCModule
|
||||||
|
|
||||||
val atlNode: TLMixedNode = TLOutputNode()
|
val atlNode: TLMixedNode = TLIdentityNode()
|
||||||
val tlNode: TLMixedNode = TLOutputNode()
|
val tlNode: TLMixedNode = TLIdentityNode()
|
||||||
}
|
}
|
||||||
|
|
||||||
class RoCCIO(outer: LazyRoCC)(implicit p: Parameters) extends RoCCCoreIO()(p) {
|
class RoCCIO(outer: LazyRoCC)(implicit p: Parameters) extends RoCCCoreIO()(p) {
|
||||||
val atl = outer.atlNode.bundleOut
|
|
||||||
val tl = outer.tlNode.bundleOut
|
|
||||||
// Should be handled differently, eventually
|
// Should be handled differently, eventually
|
||||||
val ptw = Vec(p(RoccNPTWPorts), new TLBPTWIO)
|
val ptw = Vec(p(RoccNPTWPorts), new TLBPTWIO)
|
||||||
val fpu_req = Decoupled(new FPInput)
|
val fpu_req = Decoupled(new FPInput)
|
||||||
@ -74,7 +72,7 @@ class RoCCIO(outer: LazyRoCC)(implicit p: Parameters) extends RoCCCoreIO()(p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class LazyRoCCModule(outer: LazyRoCC) extends LazyModuleImp(outer) {
|
class LazyRoCCModule(outer: LazyRoCC) extends LazyModuleImp(outer) {
|
||||||
val io = new RoCCIO(outer)
|
val io = IO(new RoCCIO(outer))
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Mixins for including RoCC **/
|
/** Mixins for including RoCC **/
|
||||||
@ -263,7 +261,7 @@ class TranslatorExampleModule(outer: TranslatorExample)(implicit p: Parameters)
|
|||||||
|
|
||||||
class CharacterCountExample(implicit p: Parameters) extends LazyRoCC {
|
class CharacterCountExample(implicit p: Parameters) extends LazyRoCC {
|
||||||
override lazy val module = new CharacterCountExampleModule(this)
|
override lazy val module = new CharacterCountExampleModule(this)
|
||||||
override val atlNode = TLClientNode(TLClientParameters("CharacterCountRoCC"))
|
override val atlNode = TLClientNode(Seq(TLClientPortParameters(Seq(TLClientParameters("CharacterCountRoCC")))))
|
||||||
}
|
}
|
||||||
|
|
||||||
class CharacterCountExampleModule(outer: CharacterCountExample)(implicit p: Parameters) extends LazyRoCCModule(outer)
|
class CharacterCountExampleModule(outer: CharacterCountExample)(implicit p: Parameters) extends LazyRoCCModule(outer)
|
||||||
@ -286,7 +284,7 @@ class CharacterCountExampleModule(outer: CharacterCountExample)(implicit p: Para
|
|||||||
val s_idle :: s_acq :: s_gnt :: s_check :: s_resp :: Nil = Enum(Bits(), 5)
|
val s_idle :: s_acq :: s_gnt :: s_check :: s_resp :: Nil = Enum(Bits(), 5)
|
||||||
val state = Reg(init = s_idle)
|
val state = Reg(init = s_idle)
|
||||||
|
|
||||||
val tl_out = io.atl.head
|
val (tl_out, edgesOut) = outer.atlNode.out(0)
|
||||||
val gnt = tl_out.d.bits
|
val gnt = tl_out.d.bits
|
||||||
val recv_data = Reg(UInt(width = cacheDataBits))
|
val recv_data = Reg(UInt(width = cacheDataBits))
|
||||||
val recv_beat = Reg(UInt(width = log2Up(cacheDataBeats+1)), init = UInt(0))
|
val recv_beat = Reg(UInt(width = log2Up(cacheDataBeats+1)), init = UInt(0))
|
||||||
@ -309,7 +307,7 @@ class CharacterCountExampleModule(outer: CharacterCountExample)(implicit p: Para
|
|||||||
io.resp.bits.rd := resp_rd
|
io.resp.bits.rd := resp_rd
|
||||||
io.resp.bits.data := count
|
io.resp.bits.data := count
|
||||||
tl_out.a.valid := (state === s_acq)
|
tl_out.a.valid := (state === s_acq)
|
||||||
tl_out.a.bits := outer.atlNode.edgesOut(0).Get(
|
tl_out.a.bits := edgesOut.Get(
|
||||||
fromSource = UInt(0),
|
fromSource = UInt(0),
|
||||||
toAddress = addr_block << blockOffset,
|
toAddress = addr_block << blockOffset,
|
||||||
lgSize = UInt(lgCacheBlockBytes))._2
|
lgSize = UInt(lgCacheBlockBytes))._2
|
||||||
|
@ -82,7 +82,7 @@ class RocketTile(val rocketParams: RocketTileParams, val hartid: Int)(implicit p
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
// Find all the caches
|
// Find all the caches
|
||||||
val outer = masterNode.edgesOut
|
val outer = masterNode.out.map(_._2)
|
||||||
.flatMap(_.manager.managers)
|
.flatMap(_.manager.managers)
|
||||||
.filter(_.supportsAcquireB)
|
.filter(_.supportsAcquireB)
|
||||||
.flatMap(_.resources.headOption)
|
.flatMap(_.resources.headOption)
|
||||||
@ -115,7 +115,7 @@ class RocketTile(val rocketParams: RocketTileParams, val hartid: Int)(implicit p
|
|||||||
Resource(cpuDevice, "reg").bind(ResourceInt(BigInt(hartid)))
|
Resource(cpuDevice, "reg").bind(ResourceInt(BigInt(hartid)))
|
||||||
Resource(intcDevice, "reg").bind(ResourceInt(BigInt(hartid)))
|
Resource(intcDevice, "reg").bind(ResourceInt(BigInt(hartid)))
|
||||||
|
|
||||||
intNode.edgesIn.flatMap(_.source.sources).map { case s =>
|
intNode.in.flatMap(_._2.source.sources).map { case s =>
|
||||||
for (i <- s.range.start until s.range.end) {
|
for (i <- s.range.start until s.range.end) {
|
||||||
csrIntMap.lift(i).foreach { j =>
|
csrIntMap.lift(i).foreach { j =>
|
||||||
s.resources.foreach { r =>
|
s.resources.foreach { r =>
|
||||||
@ -181,12 +181,12 @@ class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => ne
|
|||||||
|
|
||||||
abstract class RocketTileWrapper(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends LazyModule {
|
abstract class RocketTileWrapper(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends LazyModule {
|
||||||
val rocket = LazyModule(new RocketTile(rtp, hartid))
|
val rocket = LazyModule(new RocketTile(rtp, hartid))
|
||||||
val masterNode: OutputNode[_,_,_,_,_]
|
val masterNode: IdentityNode[_,_,_,_,_]
|
||||||
val slaveNode: InputNode[_,_,_,_,_]
|
val slaveNode: IdentityNode[_,_,_,_,_]
|
||||||
val intOutputNode = rocket.intOutputNode.map(dummy => IntOutputNode())
|
val asyncIntNode = IntIdentityNode()
|
||||||
val asyncIntNode = IntInputNode()
|
val periphIntNode = IntIdentityNode()
|
||||||
val periphIntNode = IntInputNode()
|
val coreIntNode = IntIdentityNode()
|
||||||
val coreIntNode = IntInputNode()
|
val intOutputNode = rocket.intOutputNode.map(dummy => IntIdentityNode())
|
||||||
val intXbar = LazyModule(new IntXbar)
|
val intXbar = LazyModule(new IntXbar)
|
||||||
|
|
||||||
rocket.intNode := intXbar.intnode
|
rocket.intNode := intXbar.intnode
|
||||||
@ -220,18 +220,12 @@ abstract class RocketTileWrapper(rtp: RocketTileParams, hartid: Int)(implicit p:
|
|||||||
}
|
}
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new CoreBundle
|
val io = IO(new CoreBundle
|
||||||
with HasExternallyDrivenTileConstants
|
with HasExternallyDrivenTileConstants
|
||||||
with CanHaveInstructionTracePort
|
with CanHaveInstructionTracePort
|
||||||
with CanHaltAndCatchFire {
|
with CanHaltAndCatchFire {
|
||||||
val master = masterNode.bundleOut
|
|
||||||
val slave = slaveNode.bundleIn
|
|
||||||
val outputInterrupts = intOutputNode.map(_.bundleOut)
|
|
||||||
val asyncInterrupts = asyncIntNode.bundleIn
|
|
||||||
val periphInterrupts = periphIntNode.bundleIn
|
|
||||||
val coreInterrupts = coreIntNode.bundleIn
|
|
||||||
val halt_and_catch_fire = rocket.module.io.halt_and_catch_fire.map(_.cloneType)
|
val halt_and_catch_fire = rocket.module.io.halt_and_catch_fire.map(_.cloneType)
|
||||||
}
|
})
|
||||||
// signals that do not change based on crossing type:
|
// signals that do not change based on crossing type:
|
||||||
rocket.module.io.hartid := io.hartid
|
rocket.module.io.hartid := io.hartid
|
||||||
rocket.module.io.reset_vector := io.reset_vector
|
rocket.module.io.reset_vector := io.reset_vector
|
||||||
@ -241,10 +235,10 @@ abstract class RocketTileWrapper(rtp: RocketTileParams, hartid: Int)(implicit p:
|
|||||||
}
|
}
|
||||||
|
|
||||||
class SyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) {
|
class SyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) {
|
||||||
val masterNode = TLOutputNode()
|
val masterNode = TLIdentityNode()
|
||||||
masterNode :=* optionalMasterBuffer(rocket.masterNode)
|
masterNode :=* optionalMasterBuffer(rocket.masterNode)
|
||||||
|
|
||||||
val slaveNode = new TLInputNode()(ValName("slave")) { override def reverse = true }
|
val slaveNode = new TLIdentityNode() { override def reverse = true }
|
||||||
DisableMonitors { implicit p => rocket.slaveNode :*= optionalSlaveBuffer(slaveNode) }
|
DisableMonitors { implicit p => rocket.slaveNode :*= optionalSlaveBuffer(slaveNode) }
|
||||||
|
|
||||||
// Fully async interrupts need synchronizers.
|
// Fully async interrupts need synchronizers.
|
||||||
@ -260,12 +254,12 @@ class SyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters)
|
|||||||
}
|
}
|
||||||
|
|
||||||
class AsyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) {
|
class AsyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) {
|
||||||
val masterNode = TLAsyncOutputNode()
|
val masterNode = TLAsyncIdentityNode()
|
||||||
val source = LazyModule(new TLAsyncCrossingSource)
|
val source = LazyModule(new TLAsyncCrossingSource)
|
||||||
source.node :=* rocket.masterNode
|
source.node :=* rocket.masterNode
|
||||||
masterNode :=* source.node
|
masterNode :=* source.node
|
||||||
|
|
||||||
val slaveNode = new TLAsyncInputNode()(ValName("slave")) { override def reverse = true }
|
val slaveNode = new TLAsyncIdentityNode() { override def reverse = true }
|
||||||
val sink = LazyModule(new TLAsyncCrossingSink)
|
val sink = LazyModule(new TLAsyncCrossingSink)
|
||||||
|
|
||||||
DisableMonitors { implicit p =>
|
DisableMonitors { implicit p =>
|
||||||
@ -289,12 +283,12 @@ class AsyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters
|
|||||||
}
|
}
|
||||||
|
|
||||||
class RationalRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) {
|
class RationalRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) {
|
||||||
val masterNode = TLRationalOutputNode()
|
val masterNode = TLRationalIdentityNode()
|
||||||
val source = LazyModule(new TLRationalCrossingSource)
|
val source = LazyModule(new TLRationalCrossingSource)
|
||||||
source.node :=* optionalMasterBuffer(rocket.masterNode)
|
source.node :=* optionalMasterBuffer(rocket.masterNode)
|
||||||
masterNode :=* source.node
|
masterNode :=* source.node
|
||||||
|
|
||||||
val slaveNode = new TLRationalInputNode()(ValName("slave")) { override def reverse = true }
|
val slaveNode = new TLRationalIdentityNode() { override def reverse = true }
|
||||||
val sink = LazyModule(new TLRationalCrossingSink(SlowToFast))
|
val sink = LazyModule(new TLRationalCrossingSink(SlowToFast))
|
||||||
|
|
||||||
DisableMonitors { implicit p =>
|
DisableMonitors { implicit p =>
|
||||||
|
@ -13,12 +13,7 @@ class TLAsyncCrossingSource(sync: Int = 3)(implicit p: Parameters) extends LazyM
|
|||||||
val node = TLAsyncSourceNode(sync)
|
val node = TLAsyncSourceNode(sync)
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
|
||||||
val sink_reset_n = out.a.sink_reset_n
|
val sink_reset_n = out.a.sink_reset_n
|
||||||
val bce = edgeIn.manager.anySupportAcquireB && edgeIn.client.anySupportProbe
|
val bce = edgeIn.manager.anySupportAcquireB && edgeIn.client.anySupportProbe
|
||||||
val depth = edgeOut.manager.depth
|
val depth = edgeOut.manager.depth
|
||||||
@ -47,12 +42,7 @@ class TLAsyncCrossingSink(depth: Int = 8, sync: Int = 3)(implicit p: Parameters)
|
|||||||
val node = TLAsyncSinkNode(depth, sync)
|
val node = TLAsyncSinkNode(depth, sync)
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
|
||||||
val source_reset_n = in.a.source_reset_n
|
val source_reset_n = in.a.source_reset_n
|
||||||
val bce = edgeOut.manager.anySupportAcquireB && edgeOut.client.anySupportProbe
|
val bce = edgeOut.manager.anySupportAcquireB && edgeOut.client.anySupportProbe
|
||||||
|
|
||||||
@ -97,8 +87,8 @@ object TLAsyncCrossingSink
|
|||||||
|
|
||||||
class TLAsyncCrossing(depth: Int = 8, sync: Int = 3)(implicit p: Parameters) extends LazyModule
|
class TLAsyncCrossing(depth: Int = 8, sync: Int = 3)(implicit p: Parameters) extends LazyModule
|
||||||
{
|
{
|
||||||
val nodeIn = TLInputNode()
|
val nodeIn = TLIdentityNode()
|
||||||
val nodeOut = TLOutputNode()
|
val nodeOut = TLIdentityNode()
|
||||||
val node = NodeHandle(nodeIn, nodeOut)
|
val node = NodeHandle(nodeIn, nodeOut)
|
||||||
|
|
||||||
val source = LazyModule(new TLAsyncCrossingSource(sync))
|
val source = LazyModule(new TLAsyncCrossingSource(sync))
|
||||||
@ -109,14 +99,12 @@ class TLAsyncCrossing(depth: Int = 8, sync: Int = 3)(implicit p: Parameters) ext
|
|||||||
val out = (nodeOut := sink.node)
|
val out = (nodeOut := sink.node)
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
val io = IO(new Bundle {
|
||||||
val in = nodeIn.bundleIn
|
|
||||||
val in_clock = Clock(INPUT)
|
val in_clock = Clock(INPUT)
|
||||||
val in_reset = Bool(INPUT)
|
val in_reset = Bool(INPUT)
|
||||||
val out = nodeOut.bundleOut
|
|
||||||
val out_clock = Clock(INPUT)
|
val out_clock = Clock(INPUT)
|
||||||
val out_reset = Bool(INPUT)
|
val out_reset = Bool(INPUT)
|
||||||
}
|
})
|
||||||
|
|
||||||
source.module.clock := io.in_clock
|
source.module.clock := io.in_clock
|
||||||
source.module.reset := io.in_reset
|
source.module.reset := io.in_reset
|
||||||
@ -147,7 +135,7 @@ class TLRAMAsyncCrossing(txns: Int)(implicit p: Parameters) extends LazyModule {
|
|||||||
cross.node := TLFragmenter(4, 256)(TLDelayer(0.1)(model.node))
|
cross.node := TLFragmenter(4, 256)(TLDelayer(0.1)(model.node))
|
||||||
val monitor = (ram.node := cross.node)
|
val monitor = (ram.node := cross.node)
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) with HasUnitTestIO {
|
lazy val module = new LazyModuleImp(this) with UnitTestModule {
|
||||||
io.finished := fuzz.module.io.finished
|
io.finished := fuzz.module.io.finished
|
||||||
|
|
||||||
// Shove the RAM into another clock domain
|
// Shove the RAM into another clock domain
|
||||||
|
@ -29,12 +29,7 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc
|
|||||||
})})
|
})})
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
|
||||||
val managers = edgeOut.manager.managers
|
val managers = edgeOut.manager.managers
|
||||||
val beatBytes = edgeOut.manager.beatBytes
|
val beatBytes = edgeOut.manager.beatBytes
|
||||||
|
|
||||||
@ -297,7 +292,7 @@ class TLRAMAtomicAutomata(txns: Int)(implicit p: Parameters) extends LazyModule
|
|||||||
model.node := fuzz.node
|
model.node := fuzz.node
|
||||||
ram.node := TLFragmenter(4, 256)(TLDelayer(0.1)(TLAtomicAutomata()(TLDelayer(0.1)(model.node))))
|
ram.node := TLFragmenter(4, 256)(TLDelayer(0.1)(TLAtomicAutomata()(TLDelayer(0.1)(model.node))))
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) with HasUnitTestIO {
|
lazy val module = new LazyModuleImp(this) with UnitTestModule {
|
||||||
io.finished := fuzz.module.io.finished
|
io.finished := fuzz.module.io.finished
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,12 +53,7 @@ class TLBroadcast(lineBytes: Int, numTrackers: Int = 4, bufferless: Boolean = fa
|
|||||||
)
|
)
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
|
||||||
val clients = edgeIn.client.clients
|
val clients = edgeIn.client.clients
|
||||||
val managers = edgeOut.manager.managers
|
val managers = edgeOut.manager.managers
|
||||||
val lineShift = log2Ceil(lineBytes)
|
val lineShift = log2Ceil(lineBytes)
|
||||||
|
@ -35,12 +35,7 @@ class TLBuffer(
|
|||||||
val node = new TLBufferNode(a, b, c, d, e)
|
val node = new TLBufferNode(a, b, c, d, e)
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
|
||||||
out.a <> a(in .a)
|
out.a <> a(in .a)
|
||||||
in .d <> d(out.d)
|
in .d <> d(out.d)
|
||||||
|
|
||||||
@ -80,8 +75,8 @@ object TLBuffer
|
|||||||
|
|
||||||
class TLBufferChain(depth: Int)(implicit p: Parameters) extends LazyModule {
|
class TLBufferChain(depth: Int)(implicit p: Parameters) extends LazyModule {
|
||||||
|
|
||||||
val nodeIn = TLInputNode()
|
val nodeIn = TLIdentityNode()
|
||||||
val nodeOut = TLOutputNode()
|
val nodeOut = TLIdentityNode()
|
||||||
val node = NodeHandle(nodeIn, nodeOut)
|
val node = NodeHandle(nodeIn, nodeOut)
|
||||||
|
|
||||||
val buf_chain = if (depth > 0) {
|
val buf_chain = if (depth > 0) {
|
||||||
@ -96,12 +91,7 @@ class TLBufferChain(depth: Int)(implicit p: Parameters) extends LazyModule {
|
|||||||
buf_chain.head.node :=? nodeIn
|
buf_chain.head.node :=? nodeIn
|
||||||
nodeOut :=? buf_chain.last.node
|
nodeOut :=? buf_chain.last.node
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) { }
|
||||||
val io = new Bundle {
|
|
||||||
val in = nodeIn.bundleIn
|
|
||||||
val out = nodeOut.bundleOut
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object TLBufferChain
|
object TLBufferChain
|
||||||
|
@ -24,12 +24,7 @@ class TLCacheCork(unsafe: Boolean = false)(implicit p: Parameters) extends LazyM
|
|||||||
supportsAcquireT = if (m.regionType == RegionType.UNCACHED) m.supportsPutFull else m.supportsAcquireT)})})
|
supportsAcquireT = if (m.regionType == RegionType.UNCACHED) m.supportsPutFull else m.supportsAcquireT)})})
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
|
||||||
val clients = edgeIn.client.clients
|
val clients = edgeIn.client.clients
|
||||||
val caches = clients.filter(_.supportsProbe)
|
val caches = clients.filter(_.supportsProbe)
|
||||||
require (clients.size == 1 || caches.size == 0 || unsafe, "Only one client can safely use a TLCacheCork")
|
require (clients.size == 1 || caches.size == 0 || unsafe, "Only one client can safely use a TLCacheCork")
|
||||||
|
@ -10,15 +10,10 @@ import freechips.rocketchip.diplomacy._
|
|||||||
// q is the probability to delay a request
|
// q is the probability to delay a request
|
||||||
class TLDelayer(q: Double)(implicit p: Parameters) extends LazyModule
|
class TLDelayer(q: Double)(implicit p: Parameters) extends LazyModule
|
||||||
{
|
{
|
||||||
val node = TLIdentityNode()
|
val node = TLAdapterNode()
|
||||||
require (0.0 <= q && q < 1)
|
require (0.0 <= q && q < 1)
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
def feed[T <: Data](sink: DecoupledIO[T], source: DecoupledIO[T], noise: T) {
|
def feed[T <: Data](sink: DecoupledIO[T], source: DecoupledIO[T], noise: T) {
|
||||||
val allow = UInt((q * 65535.0).toInt) <= LFSR16(source.valid)
|
val allow = UInt((q * 65535.0).toInt) <= LFSR16(source.valid)
|
||||||
sink.valid := source.valid && allow
|
sink.valid := source.valid && allow
|
||||||
@ -27,7 +22,7 @@ class TLDelayer(q: Double)(implicit p: Parameters) extends LazyModule
|
|||||||
when (!sink.valid) { sink.bits := noise }
|
when (!sink.valid) { sink.bits := noise }
|
||||||
}
|
}
|
||||||
|
|
||||||
(io.in zip io.out) foreach { case (in, out) =>
|
(node.in zip node.out) foreach { case ((in, _), (out, _)) =>
|
||||||
val anoise = Wire(in.a.bits)
|
val anoise = Wire(in.a.bits)
|
||||||
anoise.opcode := LFSRNoiseMaker(3)
|
anoise.opcode := LFSRNoiseMaker(3)
|
||||||
anoise.param := LFSRNoiseMaker(3)
|
anoise.param := LFSRNoiseMaker(3)
|
||||||
|
@ -4,13 +4,15 @@ package freechips.rocketchip.tilelink
|
|||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import chisel3.internal.sourceinfo.SourceInfo
|
import chisel3.internal.sourceinfo.SourceInfo
|
||||||
|
import freechips.rocketchip.config.Parameters
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
|
|
||||||
class TLEdge(
|
class TLEdge(
|
||||||
client: TLClientPortParameters,
|
client: TLClientPortParameters,
|
||||||
manager: TLManagerPortParameters)
|
manager: TLManagerPortParameters,
|
||||||
extends TLEdgeParameters(client, manager)
|
params: Parameters)
|
||||||
|
extends TLEdgeParameters(client, manager, params)
|
||||||
{
|
{
|
||||||
def isAligned(address: UInt, lgSize: UInt): Bool = {
|
def isAligned(address: UInt, lgSize: UInt): Bool = {
|
||||||
if (maxLgSize == 0) Bool(true) else {
|
if (maxLgSize == 0) Bool(true) else {
|
||||||
@ -262,8 +264,9 @@ class TLEdge(
|
|||||||
|
|
||||||
class TLEdgeOut(
|
class TLEdgeOut(
|
||||||
client: TLClientPortParameters,
|
client: TLClientPortParameters,
|
||||||
manager: TLManagerPortParameters)
|
manager: TLManagerPortParameters,
|
||||||
extends TLEdge(client, manager)
|
params: Parameters)
|
||||||
|
extends TLEdge(client, manager, params)
|
||||||
{
|
{
|
||||||
// Transfers
|
// Transfers
|
||||||
def Acquire(fromSource: UInt, toAddress: UInt, lgSize: UInt, growPermissions: UInt) = {
|
def Acquire(fromSource: UInt, toAddress: UInt, lgSize: UInt, growPermissions: UInt) = {
|
||||||
@ -476,8 +479,9 @@ class TLEdgeOut(
|
|||||||
|
|
||||||
class TLEdgeIn(
|
class TLEdgeIn(
|
||||||
client: TLClientPortParameters,
|
client: TLClientPortParameters,
|
||||||
manager: TLManagerPortParameters)
|
manager: TLManagerPortParameters,
|
||||||
extends TLEdge(client, manager)
|
params: Parameters)
|
||||||
|
extends TLEdge(client, manager, params)
|
||||||
{
|
{
|
||||||
// Transfers
|
// Transfers
|
||||||
def Probe(fromAddress: UInt, toSource: UInt, lgSize: UInt, capPermissions: UInt) = {
|
def Probe(fromAddress: UInt, toSource: UInt, lgSize: UInt, capPermissions: UInt) = {
|
||||||
|
@ -41,12 +41,7 @@ class TLFIFOFixer(policy: TLFIFOFixer.Policy = TLFIFOFixer.all)(implicit p: Para
|
|||||||
})
|
})
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
|
||||||
val (fixMap, splatMap) = fifoMap(edgeOut.manager.managers)
|
val (fixMap, splatMap) = fifoMap(edgeOut.manager.managers)
|
||||||
|
|
||||||
// Do we need to serialize the request to this manager?
|
// Do we need to serialize the request to this manager?
|
||||||
|
@ -49,11 +49,9 @@ class TLFilter(
|
|||||||
})})
|
})})
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
||||||
val in = node.bundleIn
|
out <> in
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
}
|
||||||
io.out <> io.in
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,12 +52,7 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean =
|
|||||||
managerFn = { m => m.copy(managers = m.managers.map(mapManager)) })
|
managerFn = { m => m.copy(managers = m.managers.map(mapManager)) })
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
|
||||||
// All managers must share a common FIFO domain (responses might end up interleaved)
|
// All managers must share a common FIFO domain (responses might end up interleaved)
|
||||||
val manager = edgeOut.manager
|
val manager = edgeOut.manager
|
||||||
val managers = manager.managers
|
val managers = manager.managers
|
||||||
@ -249,7 +244,7 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean =
|
|||||||
val aFrag = Mux(aOrig > limit, limit, aOrig)
|
val aFrag = Mux(aOrig > limit, limit, aOrig)
|
||||||
val aOrigOH1 = UIntToOH1(aOrig, log2Ceil(maxSize))
|
val aOrigOH1 = UIntToOH1(aOrig, log2Ceil(maxSize))
|
||||||
val aFragOH1 = UIntToOH1(aFrag, log2Up(maxDownSize))
|
val aFragOH1 = UIntToOH1(aFrag, log2Up(maxDownSize))
|
||||||
val aHasData = node.edgesIn(0).hasData(in_a.bits)
|
val aHasData = edgeIn.hasData(in_a.bits)
|
||||||
val aMask = Mux(aHasData, UInt(0), aFragOH1)
|
val aMask = Mux(aHasData, UInt(0), aFragOH1)
|
||||||
|
|
||||||
val gennum = RegInit(UInt(0, width = counterBits))
|
val gennum = RegInit(UInt(0, width = counterBits))
|
||||||
@ -317,7 +312,7 @@ class TLRAMFragmenter(ramBeatBytes: Int, maxSize: Int, txns: Int)(implicit p: Pa
|
|||||||
TLBuffer(BufferParams.flow)(
|
TLBuffer(BufferParams.flow)(
|
||||||
model.node)))))))))
|
model.node)))))))))
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) with HasUnitTestIO {
|
lazy val module = new LazyModuleImp(this) with UnitTestModule {
|
||||||
io.finished := fuzz.module.io.finished
|
io.finished := fuzz.module.io.finished
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,13 +107,11 @@ class TLFuzzer(
|
|||||||
val node = TLClientNode(Seq(TLClientPortParameters(clientParams)))
|
val node = TLClientNode(Seq(TLClientPortParameters(clientParams)))
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
val io = IO(new Bundle {
|
||||||
val out = node.bundleOut
|
|
||||||
val finished = Bool(OUTPUT)
|
val finished = Bool(OUTPUT)
|
||||||
}
|
})
|
||||||
|
|
||||||
val out = io.out(0)
|
val (out, edge) = node.out(0)
|
||||||
val edge = node.edgesOut(0)
|
|
||||||
|
|
||||||
// Extract useful parameters from the TL edge
|
// Extract useful parameters from the TL edge
|
||||||
val maxTransfer = edge.manager.maxTransfer
|
val maxTransfer = edge.manager.maxTransfer
|
||||||
@ -245,7 +243,7 @@ class TLFuzzRAM(txns: Int)(implicit p: Parameters) extends LazyModule
|
|||||||
val monitor = (ram.node := cross.node)
|
val monitor = (ram.node := cross.node)
|
||||||
gpio.node := TLFragmenter(4, 32)(TLBuffer()(xbar.node))
|
gpio.node := TLFragmenter(4, 32)(TLBuffer()(xbar.node))
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) with HasUnitTestIO {
|
lazy val module = new LazyModuleImp(this) with UnitTestModule {
|
||||||
io.finished := fuzz.module.io.finished
|
io.finished := fuzz.module.io.finished
|
||||||
|
|
||||||
// Shove the RAM into another clock domain
|
// Shove the RAM into another clock domain
|
||||||
|
@ -16,12 +16,7 @@ class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = f
|
|||||||
managerFn = { m => if (!supportManagers) m else m.copy(minLatency = min(1, m.minLatency), managers = m.managers.map(_.copy(supportsHint = TransferSizes(1, m.maxTransfer)))) })
|
managerFn = { m => if (!supportManagers) m else m.copy(minLatency = min(1, m.minLatency), managers = m.managers.map(_.copy(supportsHint = TransferSizes(1, m.maxTransfer)))) })
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
|
||||||
// Don't add support for clients if there is no BCE channel
|
// Don't add support for clients if there is no BCE channel
|
||||||
val bce = edgeOut.manager.anySupportAcquireB && edgeIn.client.anySupportProbe
|
val bce = edgeOut.manager.anySupportAcquireB && edgeIn.client.anySupportProbe
|
||||||
require (!supportClients || bce)
|
require (!supportClients || bce)
|
||||||
@ -118,7 +113,7 @@ class TLRAMHintHandler(txns: Int)(implicit p: Parameters) extends LazyModule {
|
|||||||
model.node := fuzz.node
|
model.node := fuzz.node
|
||||||
ram.node := TLFragmenter(4, 256)(TLDelayer(0.1)(TLHintHandler()(TLDelayer(0.1)(model.node))))
|
ram.node := TLFragmenter(4, 256)(TLDelayer(0.1)(TLHintHandler()(TLDelayer(0.1)(model.node))))
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) with HasUnitTestIO {
|
lazy val module = new LazyModuleImp(this) with UnitTestModule {
|
||||||
io.finished := fuzz.module.io.finished
|
io.finished := fuzz.module.io.finished
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,12 +61,12 @@ object IntSinkPortSimple
|
|||||||
Seq.fill(ports)(IntSinkPortParameters(Seq.fill(sinks)(IntSinkParameters())))
|
Seq.fill(ports)(IntSinkPortParameters(Seq.fill(sinks)(IntSinkParameters())))
|
||||||
}
|
}
|
||||||
|
|
||||||
case class IntEdge(source: IntSourcePortParameters, sink: IntSinkPortParameters)
|
case class IntEdge(source: IntSourcePortParameters, sink: IntSinkPortParameters, params: Parameters)
|
||||||
|
|
||||||
object IntImp extends NodeImp[IntSourcePortParameters, IntSinkPortParameters, IntEdge, IntEdge, Vec[Bool]]
|
object IntImp extends NodeImp[IntSourcePortParameters, IntSinkPortParameters, IntEdge, IntEdge, Vec[Bool]]
|
||||||
{
|
{
|
||||||
def edgeO(pd: IntSourcePortParameters, pu: IntSinkPortParameters): IntEdge = IntEdge(pd, pu)
|
def edgeO(pd: IntSourcePortParameters, pu: IntSinkPortParameters, p: Parameters): IntEdge = IntEdge(pd, pu, p)
|
||||||
def edgeI(pd: IntSourcePortParameters, pu: IntSinkPortParameters): IntEdge = IntEdge(pd, pu)
|
def edgeI(pd: IntSourcePortParameters, pu: IntSinkPortParameters, p: Parameters): IntEdge = IntEdge(pd, pu, p)
|
||||||
def bundleO(eo: IntEdge): Vec[Bool] = Vec(eo.source.num, Bool())
|
def bundleO(eo: IntEdge): Vec[Bool] = Vec(eo.source.num, Bool())
|
||||||
def bundleI(ei: IntEdge): Vec[Bool] = Vec(ei.source.num, Bool())
|
def bundleI(ei: IntEdge): Vec[Bool] = Vec(ei.source.num, Bool())
|
||||||
|
|
||||||
@ -75,22 +75,21 @@ object IntImp extends NodeImp[IntSourcePortParameters, IntSinkPortParameters, In
|
|||||||
override def labelI(ei: IntEdge) = ei.source.sources.map(_.range.size).sum.toString
|
override def labelI(ei: IntEdge) = ei.source.sources.map(_.range.size).sum.toString
|
||||||
override def labelO(eo: IntEdge) = eo.source.sources.map(_.range.size).sum.toString
|
override def labelO(eo: IntEdge) = eo.source.sources.map(_.range.size).sum.toString
|
||||||
|
|
||||||
def connect(bo: => Vec[Bool], bi: => Vec[Bool], ei: => IntEdge)(implicit p: Parameters, sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) = {
|
|
||||||
(None, () => {
|
|
||||||
// Cannot use bulk connect, because the widths could differ
|
|
||||||
(bo zip bi) foreach { case (o, i) => i := o }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
override def mixO(pd: IntSourcePortParameters, node: OutwardNode[IntSourcePortParameters, IntSinkPortParameters, Vec[Bool]]): IntSourcePortParameters =
|
override def mixO(pd: IntSourcePortParameters, node: OutwardNode[IntSourcePortParameters, IntSinkPortParameters, Vec[Bool]]): IntSourcePortParameters =
|
||||||
pd.copy(sources = pd.sources.map { s => s.copy (nodePath = node +: s.nodePath) })
|
pd.copy(sources = pd.sources.map { s => s.copy (nodePath = node +: s.nodePath) })
|
||||||
override def mixI(pu: IntSinkPortParameters, node: InwardNode[IntSourcePortParameters, IntSinkPortParameters, Vec[Bool]]): IntSinkPortParameters =
|
override def mixI(pu: IntSinkPortParameters, node: InwardNode[IntSourcePortParameters, IntSinkPortParameters, Vec[Bool]]): IntSinkPortParameters =
|
||||||
pu.copy(sinks = pu.sinks.map { s => s.copy (nodePath = node +: s.nodePath) })
|
pu.copy(sinks = pu.sinks.map { s => s.copy (nodePath = node +: s.nodePath) })
|
||||||
}
|
}
|
||||||
|
|
||||||
case class IntIdentityNode()(implicit valName: ValName) extends IdentityNode(IntImp)
|
|
||||||
case class IntSourceNode(portParams: Seq[IntSourcePortParameters])(implicit valName: ValName) extends SourceNode(IntImp)(portParams)
|
case class IntSourceNode(portParams: Seq[IntSourcePortParameters])(implicit valName: ValName) extends SourceNode(IntImp)(portParams)
|
||||||
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(
|
||||||
|
sourceFn: IntSourcePortParameters => IntSourcePortParameters = { s => s },
|
||||||
|
sinkFn: IntSinkPortParameters => IntSinkPortParameters = { s => s },
|
||||||
|
num: Range.Inclusive = 0 to 999)(
|
||||||
|
implicit valName: ValName)
|
||||||
|
extends AdapterNode(IntImp)(sourceFn, sinkFn, num)
|
||||||
|
case class IntIdentityNode()(implicit valName: ValName) extends IdentityNode(IntImp)()
|
||||||
|
|
||||||
case class IntNexusNode(
|
case class IntNexusNode(
|
||||||
sourceFn: Seq[IntSourcePortParameters] => IntSourcePortParameters,
|
sourceFn: Seq[IntSourcePortParameters] => IntSourcePortParameters,
|
||||||
@ -100,15 +99,6 @@ case class IntNexusNode(
|
|||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends NexusNode(IntImp)(sourceFn, sinkFn, numSourcePorts, numSinkPorts)
|
extends NexusNode(IntImp)(sourceFn, sinkFn, numSourcePorts, numSinkPorts)
|
||||||
|
|
||||||
case class IntOutputNode()(implicit valName: ValName) extends OutputNode(IntImp)
|
|
||||||
case class IntInputNode()(implicit valName: ValName) extends InputNode(IntImp)
|
|
||||||
|
|
||||||
case class IntBlindOutputNode(portParams: Seq[IntSinkPortParameters])(implicit valName: ValName) extends BlindOutputNode(IntImp)(portParams)
|
|
||||||
case class IntBlindInputNode(portParams: Seq[IntSourcePortParameters])(implicit valName: ValName) extends BlindInputNode(IntImp)(portParams)
|
|
||||||
|
|
||||||
case class IntInternalOutputNode(portParams: Seq[IntSinkPortParameters])(implicit valName: ValName) extends InternalOutputNode(IntImp)(portParams)
|
|
||||||
case class IntInternalInputNode(portParams: Seq[IntSourcePortParameters])(implicit valName: ValName) extends InternalInputNode(IntImp)(portParams)
|
|
||||||
|
|
||||||
class IntXbar()(implicit p: Parameters) extends LazyModule
|
class IntXbar()(implicit p: Parameters) extends LazyModule
|
||||||
{
|
{
|
||||||
val intnode = IntNexusNode(
|
val intnode = IntNexusNode(
|
||||||
@ -120,27 +110,17 @@ class IntXbar()(implicit p: Parameters) extends LazyModule
|
|||||||
})
|
})
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
val cat = intnode.in.map { case (i, e) => i.take(e.source.num) }.flatten
|
||||||
val in = intnode.bundleIn
|
intnode.out.foreach { case (o, _) => o := cat }
|
||||||
val out = intnode.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
val cat = (intnode.edgesIn zip io.in).map{ case (e, i) => i.take(e.source.num) }.flatten
|
|
||||||
io.out.foreach { _ := cat }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class IntXing(sync: Int = 3)(implicit p: Parameters) extends LazyModule
|
class IntXing(sync: Int = 3)(implicit p: Parameters) extends LazyModule
|
||||||
{
|
{
|
||||||
val intnode = IntIdentityNode()
|
val intnode = IntAdapterNode()
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
(intnode.in zip intnode.out) foreach { case ((in, _), (out, _)) =>
|
||||||
val in = intnode.bundleIn
|
|
||||||
val out = intnode.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
(io.in zip io.out) foreach { case (in, out) =>
|
|
||||||
out := SynchronizerShiftReg(in, sync)
|
out := SynchronizerShiftReg(in, sync)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,15 +11,13 @@ import freechips.rocketchip.util.AsyncBundle
|
|||||||
// READ the comments in the TLIsolation object before you instantiate this module
|
// READ the comments in the TLIsolation object before you instantiate this module
|
||||||
class TLIsolation(fOut: (Bool, UInt) => UInt, fIn: (Bool, UInt) => UInt)(implicit p: Parameters) extends LazyModule
|
class TLIsolation(fOut: (Bool, UInt) => UInt, fIn: (Bool, UInt) => UInt)(implicit p: Parameters) extends LazyModule
|
||||||
{
|
{
|
||||||
val node = TLAsyncIdentityNode()
|
val node = TLAsyncAdapterNode()
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
val io = IO(new Bundle {
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
val iso_out = Bool(INPUT) // Isolate from client to manager
|
val iso_out = Bool(INPUT) // Isolate from client to manager
|
||||||
val iso_in = Bool(INPUT) // Isolate from manager to client
|
val iso_in = Bool(INPUT) // Isolate from manager to client
|
||||||
}
|
})
|
||||||
|
|
||||||
def ISOo[T <: Data](x: T): T = x.fromBits(fOut(io.iso_out, x.asUInt))
|
def ISOo[T <: Data](x: T): T = x.fromBits(fOut(io.iso_out, x.asUInt))
|
||||||
def ISOi[T <: Data](x: T): T = x.fromBits(fIn (io.iso_in, x.asUInt))
|
def ISOi[T <: Data](x: T): T = x.fromBits(fIn (io.iso_in, x.asUInt))
|
||||||
@ -53,7 +51,7 @@ class TLIsolation(fOut: (Bool, UInt) => UInt, fIn: (Bool, UInt) => UInt)(implici
|
|||||||
y.sink_reset_n := Bool(false)
|
y.sink_reset_n := Bool(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
||||||
ABo(out.a, in .a)
|
ABo(out.a, in .a)
|
||||||
ABi(in .d, out.d)
|
ABi(in .d, out.d)
|
||||||
|
|
||||||
|
@ -20,14 +20,8 @@ class TLMap(fn: AddressSet => BigInt)(implicit p: Parameters) extends LazyModule
|
|||||||
AddressSet(fn(a), a.mask)))))})
|
AddressSet(fn(a), a.mask)))))})
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
||||||
val in = node.bundleIn
|
out <> in
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
io.out <> io.in
|
|
||||||
|
|
||||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
|
||||||
val convert = edgeIn.manager.managers.flatMap(_.address) zip edgeOut.manager.managers.flatMap(_.address)
|
val convert = edgeIn.manager.managers.flatMap(_.address) zip edgeOut.manager.managers.flatMap(_.address)
|
||||||
def forward(x: UInt) =
|
def forward(x: UInt) =
|
||||||
convert.map { case (i, o) => Mux(i.contains(x), UInt(o.base) | (x & UInt(o.mask)), UInt(0)) }.reduce(_ | _)
|
convert.map { case (i, o) => Mux(i.contains(x), UInt(o.base) | (x & UInt(o.mask)), UInt(0)) }.reduce(_ | _)
|
||||||
|
@ -16,9 +16,9 @@ abstract class TLMonitorBase(args: TLMonitorArgs) extends MonitorBase()(args.sou
|
|||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val edges = args.edge()
|
val edges = args.edge()
|
||||||
val io = new Bundle {
|
val io = IO(new Bundle {
|
||||||
val in = HeterogeneousBag(edges.map(p => new TLBundleSnoop(p.bundle))).flip
|
val in = HeterogeneousBag(edges.map(p => new TLBundleSnoop(p.bundle))).flip
|
||||||
}
|
})
|
||||||
|
|
||||||
(edges zip io.in).foreach { case (e, in) => legalize(in, e, reset) }
|
(edges zip io.in).foreach { case (e, in) => legalize(in, e, reset) }
|
||||||
}
|
}
|
||||||
|
@ -9,9 +9,6 @@ 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(0 to 999, 0 to 999)
|
||||||
{
|
{
|
||||||
val externalIn = true
|
|
||||||
val externalOut = true
|
|
||||||
|
|
||||||
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}")
|
||||||
if (oStars > 0) {
|
if (oStars > 0) {
|
||||||
@ -46,15 +43,10 @@ class TLNodeNumberer(nodeAddressOffset: Option[Int] = None)(implicit p: Paramete
|
|||||||
val node = TLNodeNumbererNode(nodeAddressOffset)
|
val node = TLNodeNumbererNode(nodeAddressOffset)
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
val minNodeOffset = log2Ceil(node.out.map(_._2.manager.maxAddress).max)
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
val minNodeOffset = log2Ceil(node.edgesOut.map(_.manager.maxAddress).max)
|
|
||||||
val nodeOffset = nodeAddressOffset.getOrElse(minNodeOffset)
|
val nodeOffset = nodeAddressOffset.getOrElse(minNodeOffset)
|
||||||
|
|
||||||
(io.in zip io.out).zipWithIndex foreach { case ((in, out), i) =>
|
(node.in zip node.out).zipWithIndex foreach { case (((in, _), (out, _)), i) =>
|
||||||
out <> in
|
out <> in
|
||||||
// a&c address already get truncated
|
// a&c address already get truncated
|
||||||
in.b.bits.address := (UInt(i+1) << nodeOffset) | out.b.bits.address
|
in.b.bits.address := (UInt(i+1) << nodeOffset) | out.b.bits.address
|
||||||
|
@ -14,8 +14,8 @@ case object TLCombinationalCheck extends Field[Boolean](false)
|
|||||||
|
|
||||||
object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TLEdgeOut, TLEdgeIn, TLBundle]
|
object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TLEdgeOut, TLEdgeIn, TLBundle]
|
||||||
{
|
{
|
||||||
def edgeO(pd: TLClientPortParameters, pu: TLManagerPortParameters): TLEdgeOut = new TLEdgeOut(pd, pu)
|
def edgeO(pd: TLClientPortParameters, pu: TLManagerPortParameters, p: Parameters): TLEdgeOut = new TLEdgeOut(pd, pu, p)
|
||||||
def edgeI(pd: TLClientPortParameters, pu: TLManagerPortParameters): TLEdgeIn = new TLEdgeIn(pd, pu)
|
def edgeI(pd: TLClientPortParameters, pu: TLManagerPortParameters, p: Parameters): TLEdgeIn = new TLEdgeIn(pd, pu, p)
|
||||||
|
|
||||||
def bundleO(eo: TLEdgeOut): TLBundle = TLBundle(eo.bundle)
|
def bundleO(eo: TLEdgeOut): TLBundle = TLBundle(eo.bundle)
|
||||||
def bundleI(ei: TLEdgeIn): TLBundle = TLBundle(ei.bundle)
|
def bundleI(ei: TLEdgeIn): TLBundle = TLBundle(ei.bundle)
|
||||||
@ -63,30 +63,18 @@ object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TL
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nodes implemented inside modules
|
|
||||||
case class TLIdentityNode()(implicit valName: ValName) extends IdentityNode(TLImp)
|
|
||||||
case class TLClientNode(portParams: Seq[TLClientPortParameters])(implicit valName: ValName) extends SourceNode(TLImp)(portParams)
|
case class TLClientNode(portParams: Seq[TLClientPortParameters])(implicit valName: ValName) extends SourceNode(TLImp)(portParams)
|
||||||
case class TLManagerNode(portParams: Seq[TLManagerPortParameters])(implicit valName: ValName) extends SinkNode(TLImp)(portParams)
|
case class TLManagerNode(portParams: Seq[TLManagerPortParameters])(implicit valName: ValName) extends SinkNode(TLImp)(portParams)
|
||||||
|
|
||||||
object TLClientNode
|
|
||||||
{
|
|
||||||
def apply(params: TLClientParameters)(implicit valName: ValName) =
|
|
||||||
new TLClientNode(Seq(TLClientPortParameters(Seq(params))))
|
|
||||||
}
|
|
||||||
|
|
||||||
object TLManagerNode
|
|
||||||
{
|
|
||||||
def apply(beatBytes: Int, params: TLManagerParameters)(implicit valName: ValName) =
|
|
||||||
new TLManagerNode(Seq(TLManagerPortParameters(Seq(params), beatBytes, minLatency = 0)))
|
|
||||||
}
|
|
||||||
|
|
||||||
case class TLAdapterNode(
|
case class TLAdapterNode(
|
||||||
clientFn: TLClientPortParameters => TLClientPortParameters,
|
clientFn: TLClientPortParameters => TLClientPortParameters = { s => s },
|
||||||
managerFn: TLManagerPortParameters => TLManagerPortParameters,
|
managerFn: TLManagerPortParameters => TLManagerPortParameters = { s => s },
|
||||||
num: Range.Inclusive = 0 to 999)(
|
num: Range.Inclusive = 0 to 999)(
|
||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends AdapterNode(TLImp)(clientFn, managerFn, num)
|
extends AdapterNode(TLImp)(clientFn, managerFn, num)
|
||||||
|
|
||||||
|
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,
|
||||||
@ -101,43 +89,12 @@ abstract class TLCustomNode(
|
|||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends CustomNode(TLImp)(numClientPorts, numManagerPorts)
|
extends CustomNode(TLImp)(numClientPorts, numManagerPorts)
|
||||||
|
|
||||||
// Nodes passed from an inner module
|
// Asynchronous crossings
|
||||||
case class TLOutputNode()(implicit valName: ValName) extends OutputNode(TLImp)
|
|
||||||
case class TLInputNode()(implicit valName: ValName) extends InputNode(TLImp)
|
|
||||||
|
|
||||||
// Nodes used for external ports
|
|
||||||
case class TLBlindOutputNode(portParams: Seq[TLManagerPortParameters])(implicit valName: ValName) extends BlindOutputNode(TLImp)(portParams)
|
|
||||||
case class TLBlindInputNode(portParams: Seq[TLClientPortParameters])(implicit valName: ValName) extends BlindInputNode(TLImp)(portParams)
|
|
||||||
|
|
||||||
case class TLInternalOutputNode(portParams: Seq[TLManagerPortParameters])(implicit valName: ValName) extends InternalOutputNode(TLImp)(portParams)
|
|
||||||
case class TLInternalInputNode(portParams: Seq[TLClientPortParameters])(implicit valName: ValName) extends InternalInputNode(TLImp)(portParams)
|
|
||||||
|
|
||||||
/** Synthesizeable unit tests */
|
|
||||||
import freechips.rocketchip.unittest._
|
|
||||||
|
|
||||||
class TLInputNodeTest(txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) {
|
|
||||||
class Acceptor extends LazyModule {
|
|
||||||
val node = TLInputNode()
|
|
||||||
val tlram = LazyModule(new TLRAM(AddressSet(0x54321000, 0xfff)))
|
|
||||||
tlram.node := node
|
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
|
||||||
val io = new Bundle {
|
|
||||||
val in = node.bundleIn
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val fuzzer = LazyModule(new TLFuzzer(txns))
|
|
||||||
LazyModule(new Acceptor).node := TLFragmenter(4, 64)(fuzzer.node)
|
|
||||||
|
|
||||||
io.finished := Module(fuzzer.module).io.finished
|
|
||||||
}
|
|
||||||
|
|
||||||
object TLAsyncImp extends NodeImp[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncEdgeParameters, TLAsyncEdgeParameters, TLAsyncBundle]
|
object TLAsyncImp extends NodeImp[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncEdgeParameters, TLAsyncEdgeParameters, TLAsyncBundle]
|
||||||
{
|
{
|
||||||
def edgeO(pd: TLAsyncClientPortParameters, pu: TLAsyncManagerPortParameters): TLAsyncEdgeParameters = TLAsyncEdgeParameters(pd, pu)
|
def edgeO(pd: TLAsyncClientPortParameters, pu: TLAsyncManagerPortParameters, p: Parameters): TLAsyncEdgeParameters = TLAsyncEdgeParameters(pd, pu, p)
|
||||||
def edgeI(pd: TLAsyncClientPortParameters, pu: TLAsyncManagerPortParameters): TLAsyncEdgeParameters = TLAsyncEdgeParameters(pd, pu)
|
def edgeI(pd: TLAsyncClientPortParameters, pu: TLAsyncManagerPortParameters, p: Parameters): TLAsyncEdgeParameters = TLAsyncEdgeParameters(pd, pu, p)
|
||||||
|
|
||||||
def bundleO(eo: TLAsyncEdgeParameters): TLAsyncBundle = new TLAsyncBundle(eo.bundle)
|
def bundleO(eo: TLAsyncEdgeParameters): TLAsyncBundle = new TLAsyncBundle(eo.bundle)
|
||||||
def bundleI(ei: TLAsyncEdgeParameters): TLAsyncBundle = new TLAsyncBundle(ei.bundle)
|
def bundleI(ei: TLAsyncEdgeParameters): TLAsyncBundle = new TLAsyncBundle(ei.bundle)
|
||||||
@ -152,9 +109,14 @@ object TLAsyncImp extends NodeImp[TLAsyncClientPortParameters, TLAsyncManagerPor
|
|||||||
pu.copy(base = pu.base.copy(managers = pu.base.managers.map { m => m.copy (nodePath = node +: m.nodePath) }))
|
pu.copy(base = pu.base.copy(managers = pu.base.managers.map { m => m.copy (nodePath = node +: m.nodePath) }))
|
||||||
}
|
}
|
||||||
|
|
||||||
case class TLAsyncIdentityNode()(implicit valName: ValName) extends IdentityNode(TLAsyncImp)
|
case class TLAsyncAdapterNode(
|
||||||
case class TLAsyncOutputNode()(implicit valName: ValName) extends OutputNode(TLAsyncImp)
|
clientFn: TLAsyncClientPortParameters => TLAsyncClientPortParameters = { s => s },
|
||||||
case class TLAsyncInputNode()(implicit valName: ValName) extends InputNode(TLAsyncImp)
|
managerFn: TLAsyncManagerPortParameters => TLAsyncManagerPortParameters = { s => s },
|
||||||
|
num: Range.Inclusive = 0 to 999)(
|
||||||
|
implicit valName: ValName)
|
||||||
|
extends AdapterNode(TLAsyncImp)(clientFn, managerFn, num)
|
||||||
|
|
||||||
|
case class TLAsyncIdentityNode()(implicit valName: ValName) extends IdentityNode(TLAsyncImp)()
|
||||||
|
|
||||||
case class TLAsyncSourceNode(sync: Int)(implicit valName: ValName)
|
case class TLAsyncSourceNode(sync: Int)(implicit valName: ValName)
|
||||||
extends MixedAdapterNode(TLImp, TLAsyncImp)(
|
extends MixedAdapterNode(TLImp, TLAsyncImp)(
|
||||||
@ -166,10 +128,12 @@ case class TLAsyncSinkNode(depth: Int, sync: Int)(implicit valName: ValName)
|
|||||||
dFn = { p => p.base.copy(minLatency = sync+1) },
|
dFn = { p => p.base.copy(minLatency = sync+1) },
|
||||||
uFn = { p => TLAsyncManagerPortParameters(depth, p) })
|
uFn = { p => TLAsyncManagerPortParameters(depth, p) })
|
||||||
|
|
||||||
|
// Rationally related crossings
|
||||||
|
|
||||||
object TLRationalImp extends NodeImp[TLRationalClientPortParameters, TLRationalManagerPortParameters, TLRationalEdgeParameters, TLRationalEdgeParameters, TLRationalBundle]
|
object TLRationalImp extends NodeImp[TLRationalClientPortParameters, TLRationalManagerPortParameters, TLRationalEdgeParameters, TLRationalEdgeParameters, TLRationalBundle]
|
||||||
{
|
{
|
||||||
def edgeO(pd: TLRationalClientPortParameters, pu: TLRationalManagerPortParameters): TLRationalEdgeParameters = TLRationalEdgeParameters(pd, pu)
|
def edgeO(pd: TLRationalClientPortParameters, pu: TLRationalManagerPortParameters, p: Parameters): TLRationalEdgeParameters = TLRationalEdgeParameters(pd, pu, p)
|
||||||
def edgeI(pd: TLRationalClientPortParameters, pu: TLRationalManagerPortParameters): TLRationalEdgeParameters = TLRationalEdgeParameters(pd, pu)
|
def edgeI(pd: TLRationalClientPortParameters, pu: TLRationalManagerPortParameters, p: Parameters): TLRationalEdgeParameters = TLRationalEdgeParameters(pd, pu, p)
|
||||||
|
|
||||||
def bundleO(eo: TLRationalEdgeParameters): TLRationalBundle = new TLRationalBundle(eo.bundle)
|
def bundleO(eo: TLRationalEdgeParameters): TLRationalBundle = new TLRationalBundle(eo.bundle)
|
||||||
def bundleI(ei: TLRationalEdgeParameters): TLRationalBundle = new TLRationalBundle(ei.bundle)
|
def bundleI(ei: TLRationalEdgeParameters): TLRationalBundle = new TLRationalBundle(ei.bundle)
|
||||||
@ -182,9 +146,14 @@ object TLRationalImp extends NodeImp[TLRationalClientPortParameters, TLRationalM
|
|||||||
pu.copy(base = pu.base.copy(managers = pu.base.managers.map { m => m.copy (nodePath = node +: m.nodePath) }))
|
pu.copy(base = pu.base.copy(managers = pu.base.managers.map { m => m.copy (nodePath = node +: m.nodePath) }))
|
||||||
}
|
}
|
||||||
|
|
||||||
case class TLRationalIdentityNode()(implicit valName: ValName) extends IdentityNode(TLRationalImp)
|
case class TLRationalAdapterNode(
|
||||||
case class TLRationalOutputNode()(implicit valName: ValName) extends OutputNode(TLRationalImp)
|
clientFn: TLRationalClientPortParameters => TLRationalClientPortParameters = { s => s },
|
||||||
case class TLRationalInputNode()(implicit valName: ValName) extends InputNode(TLRationalImp)
|
managerFn: TLRationalManagerPortParameters => TLRationalManagerPortParameters = { s => s },
|
||||||
|
num: Range.Inclusive = 0 to 999)(
|
||||||
|
implicit valName: ValName)
|
||||||
|
extends AdapterNode(TLRationalImp)(clientFn, managerFn, num)
|
||||||
|
|
||||||
|
case class TLRationalIdentityNode()(implicit valName: ValName) extends IdentityNode(TLRationalImp)()
|
||||||
|
|
||||||
case class TLRationalSourceNode()(implicit valName: ValName)
|
case class TLRationalSourceNode()(implicit valName: ValName)
|
||||||
extends MixedAdapterNode(TLImp, TLRationalImp)(
|
extends MixedAdapterNode(TLImp, TLRationalImp)(
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
package freechips.rocketchip.tilelink
|
package freechips.rocketchip.tilelink
|
||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
|
import freechips.rocketchip.config.Parameters
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.util.RationalDirection
|
import freechips.rocketchip.util.RationalDirection
|
||||||
import scala.math.max
|
import scala.math.max
|
||||||
@ -312,7 +313,8 @@ object TLBundleParameters
|
|||||||
|
|
||||||
case class TLEdgeParameters(
|
case class TLEdgeParameters(
|
||||||
client: TLClientPortParameters,
|
client: TLClientPortParameters,
|
||||||
manager: TLManagerPortParameters)
|
manager: TLManagerPortParameters,
|
||||||
|
params: Parameters)
|
||||||
{
|
{
|
||||||
val maxTransfer = max(client.maxTransfer, manager.maxTransfer)
|
val maxTransfer = max(client.maxTransfer, manager.maxTransfer)
|
||||||
val maxLgSize = log2Ceil(maxTransfer)
|
val maxLgSize = log2Ceil(maxTransfer)
|
||||||
@ -340,7 +342,7 @@ object TLAsyncBundleParameters
|
|||||||
def union(x: Seq[TLAsyncBundleParameters]) = x.foldLeft(emptyBundleParams)((x,y) => x.union(y))
|
def union(x: Seq[TLAsyncBundleParameters]) = x.foldLeft(emptyBundleParams)((x,y) => x.union(y))
|
||||||
}
|
}
|
||||||
|
|
||||||
case class TLAsyncEdgeParameters(client: TLAsyncClientPortParameters, manager: TLAsyncManagerPortParameters)
|
case class TLAsyncEdgeParameters(client: TLAsyncClientPortParameters, manager: TLAsyncManagerPortParameters, params: Parameters)
|
||||||
{
|
{
|
||||||
val bundle = TLAsyncBundleParameters(manager.depth, TLBundleParameters(client.base, manager.base))
|
val bundle = TLAsyncBundleParameters(manager.depth, TLBundleParameters(client.base, manager.base))
|
||||||
}
|
}
|
||||||
@ -348,7 +350,7 @@ case class TLAsyncEdgeParameters(client: TLAsyncClientPortParameters, manager: T
|
|||||||
case class TLRationalManagerPortParameters(direction: RationalDirection, base: TLManagerPortParameters)
|
case class TLRationalManagerPortParameters(direction: RationalDirection, base: TLManagerPortParameters)
|
||||||
case class TLRationalClientPortParameters(base: TLClientPortParameters)
|
case class TLRationalClientPortParameters(base: TLClientPortParameters)
|
||||||
|
|
||||||
case class TLRationalEdgeParameters(client: TLRationalClientPortParameters, manager: TLRationalManagerPortParameters)
|
case class TLRationalEdgeParameters(client: TLRationalClientPortParameters, manager: TLRationalManagerPortParameters, params: Parameters)
|
||||||
{
|
{
|
||||||
val bundle = TLBundleParameters(client.base, manager.base)
|
val bundle = TLBundleParameters(client.base, manager.base)
|
||||||
}
|
}
|
||||||
|
@ -38,13 +38,12 @@ class TLPatternPusher(name: String, pattern: Seq[Pattern])(implicit p: Parameter
|
|||||||
val node = TLClientNode(Seq(TLClientPortParameters(Seq(TLClientParameters(name = name)))))
|
val node = TLClientNode(Seq(TLClientPortParameters(Seq(TLClientParameters(name = name)))))
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
val io = IO(new Bundle {
|
||||||
val tl_out = node.bundleOut
|
|
||||||
val run = Bool(INPUT)
|
val run = Bool(INPUT)
|
||||||
val done = Bool(OUTPUT)
|
val done = Bool(OUTPUT)
|
||||||
}
|
})
|
||||||
|
|
||||||
val edgeOut = node.edgesOut(0)
|
val (tl_out, edgeOut) = node.out(0)
|
||||||
pattern.foreach { p =>
|
pattern.foreach { p =>
|
||||||
require (p.size <= log2Ceil(edgeOut.manager.beatBytes), "Patterns must fit in a single beat")
|
require (p.size <= log2Ceil(edgeOut.manager.beatBytes), "Patterns must fit in a single beat")
|
||||||
}
|
}
|
||||||
@ -56,8 +55,8 @@ class TLPatternPusher(name: String, pattern: Seq[Pattern])(implicit p: Parameter
|
|||||||
val end = step === UInt(pattern.size)
|
val end = step === UInt(pattern.size)
|
||||||
io.done := end && !flight
|
io.done := end && !flight
|
||||||
|
|
||||||
val a = io.tl_out(0).a
|
val a = tl_out.a
|
||||||
val d = io.tl_out(0).d
|
val d = tl_out.d
|
||||||
|
|
||||||
// Expected response?
|
// Expected response?
|
||||||
val check = Vec(pattern.map(p => Bool(p.dataIn.isDefined)))(step) holdUnless a.fire()
|
val check = Vec(pattern.map(p => Bool(p.dataIn.isDefined)))(step) holdUnless a.fire()
|
||||||
@ -80,8 +79,8 @@ class TLPatternPusher(name: String, pattern: Seq[Pattern])(implicit p: Parameter
|
|||||||
d.ready := Bool(true)
|
d.ready := Bool(true)
|
||||||
|
|
||||||
// Tie off unused channels
|
// Tie off unused channels
|
||||||
io.tl_out(0).b.ready := Bool(true)
|
tl_out.b.ready := Bool(true)
|
||||||
io.tl_out(0).c.valid := Bool(false)
|
tl_out.c.valid := Bool(false)
|
||||||
io.tl_out(0).e.valid := Bool(false)
|
tl_out.e.valid := Bool(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,15 +24,10 @@ import freechips.rocketchip.util._
|
|||||||
|
|
||||||
class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule
|
class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule
|
||||||
{
|
{
|
||||||
val node = TLIdentityNode()
|
val node = TLAdapterNode()
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
|
||||||
val edge = edgeIn
|
val edge = edgeIn
|
||||||
val endAddress = edge.manager.maxAddress + 1
|
val endAddress = edge.manager.maxAddress + 1
|
||||||
val endSourceId = edge.client.endSourceId
|
val endSourceId = edge.client.endSourceId
|
||||||
|
@ -20,12 +20,7 @@ class TLRationalCrossingSource(implicit p: Parameters) extends LazyModule
|
|||||||
val node = TLRationalSourceNode()
|
val node = TLRationalSourceNode()
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
|
||||||
val bce = edgeIn.manager.anySupportAcquireB && edgeIn.client.anySupportProbe
|
val bce = edgeIn.manager.anySupportAcquireB && edgeIn.client.anySupportProbe
|
||||||
val direction = edgeOut.manager.direction
|
val direction = edgeOut.manager.direction
|
||||||
|
|
||||||
@ -56,12 +51,7 @@ class TLRationalCrossingSink(direction: RationalDirection = Symmetric)(implicit
|
|||||||
val node = TLRationalSinkNode(direction)
|
val node = TLRationalSinkNode(direction)
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
|
||||||
val bce = edgeOut.manager.anySupportAcquireB && edgeOut.client.anySupportProbe
|
val bce = edgeOut.manager.anySupportAcquireB && edgeOut.client.anySupportProbe
|
||||||
val direction = edgeIn.manager.direction
|
val direction = edgeIn.manager.direction
|
||||||
|
|
||||||
@ -109,8 +99,8 @@ object TLRationalCrossingSink
|
|||||||
|
|
||||||
class TLRationalCrossing(direction: RationalDirection = Symmetric)(implicit p: Parameters) extends LazyModule
|
class TLRationalCrossing(direction: RationalDirection = Symmetric)(implicit p: Parameters) extends LazyModule
|
||||||
{
|
{
|
||||||
val nodeIn = TLInputNode()
|
val nodeIn = TLIdentityNode()
|
||||||
val nodeOut = TLOutputNode()
|
val nodeOut = TLIdentityNode()
|
||||||
val node = NodeHandle(nodeIn, nodeOut)
|
val node = NodeHandle(nodeIn, nodeOut)
|
||||||
|
|
||||||
val source = LazyModule(new TLRationalCrossingSource)
|
val source = LazyModule(new TLRationalCrossingSource)
|
||||||
@ -121,14 +111,12 @@ class TLRationalCrossing(direction: RationalDirection = Symmetric)(implicit p: P
|
|||||||
val out = (nodeOut := sink.node)
|
val out = (nodeOut := sink.node)
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
val io = IO(new Bundle {
|
||||||
val in = nodeIn.bundleIn
|
|
||||||
val in_clock = Clock(INPUT)
|
val in_clock = Clock(INPUT)
|
||||||
val in_reset = Bool(INPUT)
|
val in_reset = Bool(INPUT)
|
||||||
val out = nodeOut.bundleOut
|
|
||||||
val out_clock = Clock(INPUT)
|
val out_clock = Clock(INPUT)
|
||||||
val out_reset = Bool(INPUT)
|
val out_reset = Bool(INPUT)
|
||||||
}
|
})
|
||||||
|
|
||||||
source.module.clock := io.in_clock
|
source.module.clock := io.in_clock
|
||||||
source.module.reset := io.in_reset
|
source.module.reset := io.in_reset
|
||||||
@ -150,7 +138,7 @@ class TLRationalCrossing(direction: RationalDirection = Symmetric)(implicit p: P
|
|||||||
import freechips.rocketchip.unittest._
|
import freechips.rocketchip.unittest._
|
||||||
|
|
||||||
class TLRAMRationalCrossingSource(name: String, txns: Int)(implicit p: Parameters) extends LazyModule {
|
class TLRAMRationalCrossingSource(name: String, txns: Int)(implicit p: Parameters) extends LazyModule {
|
||||||
val node = TLRationalOutputNode()
|
val node = TLRationalIdentityNode()
|
||||||
val fuzz = LazyModule(new TLFuzzer(txns))
|
val fuzz = LazyModule(new TLFuzzer(txns))
|
||||||
val model = LazyModule(new TLRAMModel(name))
|
val model = LazyModule(new TLRAMModel(name))
|
||||||
|
|
||||||
@ -158,25 +146,20 @@ class TLRAMRationalCrossingSource(name: String, txns: Int)(implicit p: Parameter
|
|||||||
node := TLRationalCrossingSource()(TLDelayer(0.25)(model.node))
|
node := TLRationalCrossingSource()(TLDelayer(0.25)(model.node))
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
val io = IO(new Bundle {
|
||||||
val finished = Bool(OUTPUT)
|
val finished = Bool(OUTPUT)
|
||||||
val out = node.bundleOut
|
})
|
||||||
}
|
|
||||||
io.finished := fuzz.module.io.finished
|
io.finished := fuzz.module.io.finished
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TLRAMRationalCrossingSink(direction: RationalDirection)(implicit p: Parameters) extends LazyModule {
|
class TLRAMRationalCrossingSink(direction: RationalDirection)(implicit p: Parameters) extends LazyModule {
|
||||||
val node = TLRationalInputNode()
|
val node = TLRationalIdentityNode()
|
||||||
val ram = LazyModule(new TLRAM(AddressSet(0x0, 0x3ff)))
|
val ram = LazyModule(new TLRAM(AddressSet(0x0, 0x3ff)))
|
||||||
|
|
||||||
ram.node := TLFragmenter(4, 256)(TLDelayer(0.25)(TLRationalCrossingSink(direction)(node)))
|
ram.node := TLFragmenter(4, 256)(TLDelayer(0.25)(TLRationalCrossingSink(direction)(node)))
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) { }
|
||||||
val io = new Bundle {
|
|
||||||
val in = node.bundleIn
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class TLRAMRationalCrossing(txns: Int)(implicit p: Parameters) extends LazyModule {
|
class TLRAMRationalCrossing(txns: Int)(implicit p: Parameters) extends LazyModule {
|
||||||
@ -196,7 +179,7 @@ class TLRAMRationalCrossing(txns: Int)(implicit p: Parameters) extends LazyModul
|
|||||||
val fix_fast_sink = LazyModule(new TLRAMRationalCrossingSink(SlowToFast))
|
val fix_fast_sink = LazyModule(new TLRAMRationalCrossingSink(SlowToFast))
|
||||||
fix_fast_sink.node := fix_slow_source.node
|
fix_fast_sink.node := fix_slow_source.node
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) with HasUnitTestIO {
|
lazy val module = new LazyModuleImp(this) with UnitTestModule {
|
||||||
io.finished :=
|
io.finished :=
|
||||||
sym_fast_source.module.io.finished &&
|
sym_fast_source.module.io.finished &&
|
||||||
sym_slow_source.module.io.finished &&
|
sym_slow_source.module.io.finished &&
|
||||||
|
@ -40,9 +40,9 @@ case class TLRegisterNode(
|
|||||||
// Calling this method causes the matching TL2 bundle to be
|
// Calling this method causes the matching TL2 bundle to be
|
||||||
// configured to route all requests to the listed RegFields.
|
// configured to route all requests to the listed RegFields.
|
||||||
def regmap(mapping: RegField.Map*) = {
|
def regmap(mapping: RegField.Map*) = {
|
||||||
val a = bundleIn(0).a
|
val (bundleIn, edge) = this.in(0)
|
||||||
val d = bundleIn(0).d
|
val a = bundleIn.a
|
||||||
val edge = edgesIn(0)
|
val d = bundleIn.d
|
||||||
|
|
||||||
// Please forgive me ...
|
// Please forgive me ...
|
||||||
val baseEnd = 0
|
val baseEnd = 0
|
||||||
@ -76,9 +76,9 @@ case class TLRegisterNode(
|
|||||||
d.bits.opcode := Mux(out.bits.read, TLMessages.AccessAckData, TLMessages.AccessAck)
|
d.bits.opcode := Mux(out.bits.read, TLMessages.AccessAckData, TLMessages.AccessAck)
|
||||||
|
|
||||||
// Tie off unused channels
|
// Tie off unused channels
|
||||||
bundleIn(0).b.valid := Bool(false)
|
bundleIn.b.valid := Bool(false)
|
||||||
bundleIn(0).c.ready := Bool(true)
|
bundleIn.c.ready := Bool(true)
|
||||||
bundleIn(0).e.ready := Bool(true)
|
bundleIn.e.ready := Bool(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,13 +92,11 @@ abstract class TLRegisterRouterBase(devname: String, devcompat: Seq[String], val
|
|||||||
val intnode = IntSourceNode(IntSourcePortSimple(num = interrupts, resources = Seq(Resource(device, "int"))))
|
val intnode = IntSourceNode(IntSourcePortSimple(num = interrupts, resources = Seq(Resource(device, "int"))))
|
||||||
}
|
}
|
||||||
|
|
||||||
case class TLRegBundleArg(interrupts: HeterogeneousBag[Vec[Bool]], in: HeterogeneousBag[TLBundle])(implicit val p: Parameters)
|
case class TLRegBundleArg()(implicit val p: Parameters)
|
||||||
|
|
||||||
class TLRegBundleBase(arg: TLRegBundleArg) extends Bundle
|
class TLRegBundleBase(arg: TLRegBundleArg) extends Bundle
|
||||||
{
|
{
|
||||||
implicit val p = arg.p
|
implicit val p = arg.p
|
||||||
val interrupts = arg.interrupts
|
|
||||||
val in = arg.in
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class TLRegBundle[P](val params: P, arg: TLRegBundleArg)(implicit p: Parameters) extends TLRegBundleBase(arg)
|
class TLRegBundle[P](val params: P, arg: TLRegBundleArg)(implicit p: Parameters) extends TLRegBundleBase(arg)
|
||||||
@ -106,8 +104,8 @@ class TLRegBundle[P](val params: P, arg: TLRegBundleArg)(implicit p: Parameters)
|
|||||||
class TLRegModule[P, B <: TLRegBundleBase](val params: P, bundleBuilder: => B, router: TLRegisterRouterBase)
|
class TLRegModule[P, B <: TLRegBundleBase](val params: P, bundleBuilder: => B, router: TLRegisterRouterBase)
|
||||||
extends LazyModuleImp(router) with HasRegMap
|
extends LazyModuleImp(router) with HasRegMap
|
||||||
{
|
{
|
||||||
val io = bundleBuilder
|
val io = IO(bundleBuilder)
|
||||||
val interrupts = if (io.interrupts.isEmpty) Vec(0, Bool()) else io.interrupts(0)
|
val interrupts = if (router.intnode.in.isEmpty) Vec(0, Bool()) else router.intnode.in(0)._1
|
||||||
val address = router.address
|
val address = router.address
|
||||||
def regmap(mapping: RegField.Map*) = router.node.regmap(mapping:_*)
|
def regmap(mapping: RegField.Map*) = router.node.regmap(mapping:_*)
|
||||||
}
|
}
|
||||||
@ -129,5 +127,5 @@ class TLRegisterRouter[B <: TLRegBundleBase, M <: LazyModuleImp](
|
|||||||
require (isPow2(size))
|
require (isPow2(size))
|
||||||
// require (size >= 4096) ... not absolutely required, but highly recommended
|
// require (size >= 4096) ... not absolutely required, but highly recommended
|
||||||
|
|
||||||
lazy val module = moduleBuilder(bundleBuilder(TLRegBundleArg(intnode.bundleOut, node.bundleIn)), this)
|
lazy val module = moduleBuilder(bundleBuilder(TLRegBundleArg()), this)
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
package freechips.rocketchip.tilelink
|
package freechips.rocketchip.tilelink
|
||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
|
import chisel3.experimental.MultiIOModule
|
||||||
import freechips.rocketchip.config.Parameters
|
import freechips.rocketchip.config.Parameters
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.regmapper._
|
import freechips.rocketchip.regmapper._
|
||||||
@ -222,7 +223,7 @@ trait RRTest1Bundle
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
trait RRTest1Module extends Module with HasRegMap
|
trait RRTest1Module extends MultiIOModule with HasRegMap
|
||||||
{
|
{
|
||||||
val clocks = Module(new Pow2ClockDivider(2))
|
val clocks = Module(new Pow2ClockDivider(2))
|
||||||
|
|
||||||
@ -261,7 +262,7 @@ class FuzzRRTest0(txns: Int)(implicit p: Parameters) extends LazyModule {
|
|||||||
|
|
||||||
rrtr.node := TLFragmenter(4, 32)(TLDelayer(0.1)(fuzz.node))
|
rrtr.node := TLFragmenter(4, 32)(TLDelayer(0.1)(fuzz.node))
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) with HasUnitTestIO {
|
lazy val module = new LazyModuleImp(this) with UnitTestModule {
|
||||||
io.finished := fuzz.module.io.finished
|
io.finished := fuzz.module.io.finished
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -276,7 +277,7 @@ class FuzzRRTest1(txns: Int)(implicit p: Parameters) extends LazyModule {
|
|||||||
|
|
||||||
rrtr.node := TLFragmenter(4, 32)(TLDelayer(0.1)(fuzz.node))
|
rrtr.node := TLFragmenter(4, 32)(TLDelayer(0.1)(fuzz.node))
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) with HasUnitTestIO {
|
lazy val module = new LazyModuleImp(this) with UnitTestModule {
|
||||||
io.finished := fuzz.module.io.finished
|
io.finished := fuzz.module.io.finished
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,18 +29,12 @@ class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4,
|
|||||||
// We require the address range to include an entire beat (for the write mask)
|
// We require the address range to include an entire beat (for the write mask)
|
||||||
require ((address.mask & (beatBytes-1)) == beatBytes-1)
|
require ((address.mask & (beatBytes-1)) == beatBytes-1)
|
||||||
|
|
||||||
lazy val module = new Implementation
|
lazy val module = new LazyModuleImp(this) {
|
||||||
@chiselName class Implementation extends LazyModuleImp(this) {
|
|
||||||
val io = new Bundle {
|
|
||||||
val in = node.bundleIn
|
|
||||||
}
|
|
||||||
|
|
||||||
def bigBits(x: BigInt, tail: List[Boolean] = List.empty[Boolean]): List[Boolean] =
|
def bigBits(x: BigInt, tail: List[Boolean] = List.empty[Boolean]): List[Boolean] =
|
||||||
if (x == 0) tail.reverse else bigBits(x >> 1, ((x & 1) == 1) :: tail)
|
if (x == 0) tail.reverse else bigBits(x >> 1, ((x & 1) == 1) :: tail)
|
||||||
val mask = bigBits(address.mask >> log2Ceil(beatBytes))
|
val mask = bigBits(address.mask >> log2Ceil(beatBytes))
|
||||||
|
|
||||||
val in = io.in(0)
|
val (in, edge) = node.in(0)
|
||||||
val edge = node.edgesIn(0)
|
|
||||||
|
|
||||||
val addrBits = (mask zip edge.addr_hi(in.a.bits).toBools).filter(_._1).map(_._2)
|
val addrBits = (mask zip edge.addr_hi(in.a.bits).toBools).filter(_._1).map(_._2)
|
||||||
val a_legal = address.contains(in.a.bits.address)
|
val a_legal = address.contains(in.a.bits.address)
|
||||||
@ -101,7 +95,7 @@ class TLRAMSimple(ramBeatBytes: Int, txns: Int)(implicit p: Parameters) extends
|
|||||||
model.node := fuzz.node
|
model.node := fuzz.node
|
||||||
ram.node := TLDelayer(0.25)(model.node)
|
ram.node := TLDelayer(0.25)(model.node)
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) with HasUnitTestIO {
|
lazy val module = new LazyModuleImp(this) with UnitTestModule {
|
||||||
io.finished := fuzz.module.io.finished
|
io.finished := fuzz.module.io.finished
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,12 +23,7 @@ class TLSourceShrinker(maxInFlight: Int)(implicit p: Parameters) extends LazyMod
|
|||||||
managerFn = { mp => mp.copy(managers = mp.managers.map(_.copy(fifoId = None))) })
|
managerFn = { mp => mp.copy(managers = mp.managers.map(_.copy(fifoId = None))) })
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
|
||||||
// Acquires cannot pass this adapter; it makes Probes impossible
|
// Acquires cannot pass this adapter; it makes Probes impossible
|
||||||
require (!edgeIn.client.anySupportProbe ||
|
require (!edgeIn.client.anySupportProbe ||
|
||||||
!edgeOut.manager.anySupportAcquireB)
|
!edgeOut.manager.anySupportAcquireB)
|
||||||
|
@ -15,9 +15,6 @@ case class TLSplitterNode(
|
|||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends TLCustomNode(numClientPorts, numManagerPorts)
|
extends TLCustomNode(numClientPorts, numManagerPorts)
|
||||||
{
|
{
|
||||||
val externalIn = true
|
|
||||||
val externalOut = true
|
|
||||||
|
|
||||||
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}")
|
||||||
require (iStars == 0, s"${name} (a splitter) cannot appear left of a :*=; did you mean :=*?${lazyModule.line}")
|
require (iStars == 0, s"${name} (a splitter) cannot appear left of a :*=; did you mean :=*?${lazyModule.line}")
|
||||||
@ -65,18 +62,14 @@ class TLSplitter(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Pa
|
|||||||
})
|
})
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
def group[T](x: Seq[T]) =
|
def group[T](x: Seq[T]) =
|
||||||
if (x.isEmpty) Nil else x.grouped(node.edgesIn.size).toList.transpose
|
if (x.isEmpty) Nil else x.grouped(node.in.size).toList.transpose
|
||||||
|
|
||||||
if (node.edgesOut.size == node.edgesIn.size) {
|
if (node.out.size == node.in.size) {
|
||||||
io.out <> io.in
|
(node.in zip node.out) foreach { case ((i, _), (o, _)) => o <> i }
|
||||||
} else ((node.edgesIn zip io.in) zip (group(node.edgesOut) zip group(io.out))) foreach {
|
} else (node.in zip group(node.out)) foreach {
|
||||||
case ((edgeIn, io_in), (edgesOut, io_out)) =>
|
case ((io_in, edgeIn), seq) =>
|
||||||
|
val (io_out, edgesOut) = seq.unzip
|
||||||
|
|
||||||
// Grab the port ID mapping
|
// Grab the port ID mapping
|
||||||
val outputIdRanges = TLXbar.mapOutputIds(edgesOut.map(_.manager))
|
val outputIdRanges = TLXbar.mapOutputIds(edgesOut.map(_.manager))
|
||||||
|
@ -53,12 +53,7 @@ class TLToAHB(val aFlow: Boolean = false)(implicit p: Parameters) extends LazyMo
|
|||||||
val node = TLToAHBNode()
|
val node = TLToAHBNode()
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
|
||||||
val beatBytes = edgeOut.slave.beatBytes
|
val beatBytes = edgeOut.slave.beatBytes
|
||||||
val maxTransfer = edgeOut.slave.maxTransfer
|
val maxTransfer = edgeOut.slave.maxTransfer
|
||||||
val lgMax = log2Ceil(maxTransfer)
|
val lgMax = log2Ceil(maxTransfer)
|
||||||
|
@ -38,12 +38,7 @@ class TLToAPB(val aFlow: Boolean = true)(implicit p: Parameters) extends LazyMod
|
|||||||
val node = TLToAPBNode()
|
val node = TLToAPBNode()
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
|
||||||
val beatBytes = edgeOut.slave.beatBytes
|
val beatBytes = edgeOut.slave.beatBytes
|
||||||
val lgBytes = log2Ceil(beatBytes)
|
val lgBytes = log2Ceil(beatBytes)
|
||||||
|
|
||||||
|
@ -53,12 +53,7 @@ class TLToAXI4(val beatBytes: Int, val combinational: Boolean = true, val adapte
|
|||||||
val node = TLToAXI4Node(beatBytes, stripBits)
|
val node = TLToAXI4Node(beatBytes, stripBits)
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
|
||||||
val slaves = edgeOut.slave.slaves
|
val slaves = edgeOut.slave.slaves
|
||||||
|
|
||||||
// All pairs of slaves must promise that they will never interleave data
|
// All pairs of slaves must promise that they will never interleave data
|
||||||
|
@ -17,11 +17,6 @@ class TLWidthWidget(innerBeatBytes: Int)(implicit p: Parameters) extends LazyMod
|
|||||||
managerFn = { case m => m.copy(beatBytes = innerBeatBytes) })
|
managerFn = { case m => m.copy(beatBytes = innerBeatBytes) })
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
|
||||||
val in = node.bundleIn
|
|
||||||
val out = node.bundleOut
|
|
||||||
}
|
|
||||||
|
|
||||||
def merge[T <: TLDataChannel](edgeIn: TLEdge, in: DecoupledIO[T], edgeOut: TLEdge, out: DecoupledIO[T]) = {
|
def merge[T <: TLDataChannel](edgeIn: TLEdge, in: DecoupledIO[T], edgeOut: TLEdge, out: DecoupledIO[T]) = {
|
||||||
val inBytes = edgeIn.manager.beatBytes
|
val inBytes = edgeIn.manager.beatBytes
|
||||||
val outBytes = edgeOut.manager.beatBytes
|
val outBytes = edgeOut.manager.beatBytes
|
||||||
@ -154,7 +149,7 @@ class TLWidthWidget(innerBeatBytes: Int)(implicit p: Parameters) extends LazyMod
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
||||||
|
|
||||||
// If the master is narrower than the slave, the D channel must be narrowed.
|
// If the master is narrower than the slave, the D channel must be narrowed.
|
||||||
// This is tricky, because the D channel has no address data.
|
// This is tricky, because the D channel has no address data.
|
||||||
@ -220,7 +215,7 @@ class TLRAMWidthWidget(first: Int, second: Int, txns: Int)(implicit p: Parameter
|
|||||||
TLWidthWidget(second)(
|
TLWidthWidget(second)(
|
||||||
TLWidthWidget(first)(TLDelayer(0.1)(model.node)))}))
|
TLWidthWidget(first)(TLDelayer(0.1)(model.node)))}))
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) with HasUnitTestIO {
|
lazy val module = new LazyModuleImp(this) with UnitTestModule {
|
||||||
io.finished := fuzz.module.io.finished
|
io.finished := fuzz.module.io.finished
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,22 +63,21 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parame
|
|||||||
})
|
})
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new Bundle {
|
if ((node.in.size * node.out.size) > (8*32)) {
|
||||||
val in = node.bundleIn
|
println (s"!!! WARNING !!!")
|
||||||
val out = node.bundleOut
|
println (s" Your TLXbar ($name) is very large, with ${node.in.size} Masters and ${node.out.size} Slaves.")
|
||||||
|
println (s"!!! WARNING !!!")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((io.in.size * io.out.size) > (8*32)) {
|
val (io_in, edgesIn) = node.in.unzip
|
||||||
println (s"!!! WARNING !!!")
|
val (io_out, edgesOut) = node.out.unzip
|
||||||
println (s" Your TLXbar ($name) is very large, with ${io.in.size} Masters and ${io.out.size} Slaves.")
|
|
||||||
println (s"!!! WARNING !!!")
|
|
||||||
}
|
|
||||||
// Grab the port ID mapping
|
// Grab the port ID mapping
|
||||||
val inputIdRanges = TLXbar.mapInputIds(node.edgesIn.map(_.client))
|
val inputIdRanges = TLXbar.mapInputIds(edgesIn.map(_.client))
|
||||||
val outputIdRanges = TLXbar.mapOutputIds(node.edgesOut.map(_.manager))
|
val outputIdRanges = TLXbar.mapOutputIds(edgesOut.map(_.manager))
|
||||||
|
|
||||||
// Find a good mask for address decoding
|
// Find a good mask for address decoding
|
||||||
val port_addrs = node.edgesOut.map(_.manager.managers.map(_.address).flatten)
|
val port_addrs = edgesOut.map(_.manager.managers.map(_.address).flatten)
|
||||||
val routingMask = AddressDecoder(port_addrs)
|
val routingMask = AddressDecoder(port_addrs)
|
||||||
val route_addrs = port_addrs.map(seq => AddressSet.unify(seq.map(_.widen(~routingMask)).distinct))
|
val route_addrs = port_addrs.map(seq => AddressSet.unify(seq.map(_.widen(~routingMask)).distinct))
|
||||||
val outputPorts = route_addrs.map(seq => (addr: UInt) => seq.map(_.contains(addr)).reduce(_ || _))
|
val outputPorts = route_addrs.map(seq => (addr: UInt) => seq.map(_.contains(addr)).reduce(_ || _))
|
||||||
@ -97,70 +96,70 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parame
|
|||||||
// Print the ID mapping
|
// Print the ID mapping
|
||||||
if (false) {
|
if (false) {
|
||||||
println(s"XBar ${name} mapping:")
|
println(s"XBar ${name} mapping:")
|
||||||
(node.edgesIn zip inputIdRanges).zipWithIndex.foreach { case ((edge, id), i) =>
|
(edgesIn zip inputIdRanges).zipWithIndex.foreach { case ((edge, id), i) =>
|
||||||
println(s"\t$i assigned ${id} for ${edge.client.clients.map(_.name).mkString(", ")}")
|
println(s"\t$i assigned ${id} for ${edge.client.clients.map(_.name).mkString(", ")}")
|
||||||
}
|
}
|
||||||
println("")
|
println("")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 = TLBundleParameters.union(io.in.map(_.params) ++ io.out.map(_.params))
|
val wide_bundle = TLBundleParameters.union(io_in.map(_.params) ++ io_out.map(_.params))
|
||||||
|
|
||||||
// Handle size = 1 gracefully (Chisel3 empty range is broken)
|
// Handle size = 1 gracefully (Chisel3 empty range is broken)
|
||||||
def trim(id: UInt, size: Int) = if (size <= 1) UInt(0) else id(log2Ceil(size)-1, 0)
|
def trim(id: UInt, size: Int) = if (size <= 1) UInt(0) else id(log2Ceil(size)-1, 0)
|
||||||
|
|
||||||
// Transform input bundle sources (sinks use global namespace on both sides)
|
// Transform input bundle sources (sinks use global namespace on both sides)
|
||||||
val in = Wire(Vec(io.in.size, TLBundle(wide_bundle)))
|
val in = Wire(Vec(io_in.size, TLBundle(wide_bundle)))
|
||||||
for (i <- 0 until in.size) {
|
for (i <- 0 until in.size) {
|
||||||
val r = inputIdRanges(i)
|
val r = inputIdRanges(i)
|
||||||
|
|
||||||
in(i).a <> io.in(i).a
|
in(i).a <> io_in(i).a
|
||||||
io.in(i).d <> in(i).d
|
io_in(i).d <> in(i).d
|
||||||
in(i).a.bits.source := io.in(i).a.bits.source | UInt(r.start)
|
in(i).a.bits.source := io_in(i).a.bits.source | UInt(r.start)
|
||||||
io.in(i).d.bits.source := trim(in(i).d.bits.source, r.size)
|
io_in(i).d.bits.source := trim(in(i).d.bits.source, r.size)
|
||||||
|
|
||||||
if (node.edgesIn(i).client.anySupportProbe && node.edgesOut.exists(_.manager.anySupportAcquireB)) {
|
if (edgesIn(i).client.anySupportProbe && edgesOut.exists(_.manager.anySupportAcquireB)) {
|
||||||
in(i).c <> io.in(i).c
|
in(i).c <> io_in(i).c
|
||||||
in(i).e <> io.in(i).e
|
in(i).e <> io_in(i).e
|
||||||
io.in(i).b <> in(i).b
|
io_in(i).b <> in(i).b
|
||||||
in(i).c.bits.source := io.in(i).c.bits.source | UInt(r.start)
|
in(i).c.bits.source := io_in(i).c.bits.source | UInt(r.start)
|
||||||
io.in(i).b.bits.source := trim(in(i).b.bits.source, r.size)
|
io_in(i).b.bits.source := trim(in(i).b.bits.source, r.size)
|
||||||
} else {
|
} else {
|
||||||
in(i).c.valid := Bool(false)
|
in(i).c.valid := Bool(false)
|
||||||
in(i).e.valid := Bool(false)
|
in(i).e.valid := Bool(false)
|
||||||
in(i).b.ready := Bool(false)
|
in(i).b.ready := Bool(false)
|
||||||
io.in(i).c.ready := Bool(true)
|
io_in(i).c.ready := Bool(true)
|
||||||
io.in(i).e.ready := Bool(true)
|
io_in(i).e.ready := Bool(true)
|
||||||
io.in(i).b.valid := Bool(false)
|
io_in(i).b.valid := Bool(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transform output bundle sinks (sources use global namespace on both sides)
|
// Transform output bundle sinks (sources use global namespace on both sides)
|
||||||
val out = Wire(Vec(io.out.size, TLBundle(wide_bundle)))
|
val out = Wire(Vec(io_out.size, TLBundle(wide_bundle)))
|
||||||
for (i <- 0 until out.size) {
|
for (i <- 0 until out.size) {
|
||||||
val r = outputIdRanges(i)
|
val r = outputIdRanges(i)
|
||||||
|
|
||||||
io.out(i).a <> out(i).a
|
io_out(i).a <> out(i).a
|
||||||
out(i).d <> io.out(i).d
|
out(i).d <> io_out(i).d
|
||||||
out(i).d.bits.sink := io.out(i).d.bits.sink | UInt(r.map(_.start).getOrElse(0))
|
out(i).d.bits.sink := io_out(i).d.bits.sink | UInt(r.map(_.start).getOrElse(0))
|
||||||
|
|
||||||
if (node.edgesOut(i).manager.anySupportAcquireB && node.edgesIn.exists(_.client.anySupportProbe)) {
|
if (edgesOut(i).manager.anySupportAcquireB && edgesIn.exists(_.client.anySupportProbe)) {
|
||||||
io.out(i).c <> out(i).c
|
io_out(i).c <> out(i).c
|
||||||
io.out(i).e <> out(i).e
|
io_out(i).e <> out(i).e
|
||||||
out(i).b <> io.out(i).b
|
out(i).b <> io_out(i).b
|
||||||
io.out(i).e.bits.sink := trim(out(i).e.bits.sink, r.map(_.size).getOrElse(0))
|
io_out(i).e.bits.sink := trim(out(i).e.bits.sink, r.map(_.size).getOrElse(0))
|
||||||
} else {
|
} else {
|
||||||
out(i).c.ready := Bool(false)
|
out(i).c.ready := Bool(false)
|
||||||
out(i).e.ready := Bool(false)
|
out(i).e.ready := Bool(false)
|
||||||
out(i).b.valid := Bool(false)
|
out(i).b.valid := Bool(false)
|
||||||
io.out(i).c.valid := Bool(false)
|
io_out(i).c.valid := Bool(false)
|
||||||
io.out(i).e.valid := Bool(false)
|
io_out(i).e.valid := Bool(false)
|
||||||
io.out(i).b.ready := Bool(true)
|
io_out(i).b.ready := Bool(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val addressA = (in zip node.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 node.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 = Vec(addressA.map { i => Vec(outputPorts.map { o => o(i) }) })
|
||||||
val requestCIO = Vec(addressC.map { i => Vec(outputPorts.map { o => o(i) }) })
|
val requestCIO = Vec(addressC.map { i => Vec(outputPorts.map { o => o(i) }) })
|
||||||
@ -168,28 +167,28 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parame
|
|||||||
val requestDOI = Vec(out.map { o => Vec(inputIdRanges.map { i => i.contains(o.d.bits.source) }) })
|
val requestDOI = Vec(out.map { o => Vec(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 = Vec(in.map { i => Vec(outputIdRanges.map { o => o.map(_.contains(i.e.bits.sink)).getOrElse(Bool(false)) }) })
|
||||||
|
|
||||||
val beatsAI = Vec((in zip node.edgesIn) map { case (i, e) => e.numBeats1(i.a.bits) })
|
val beatsAI = Vec((in zip edgesIn) map { case (i, e) => e.numBeats1(i.a.bits) })
|
||||||
val beatsBO = Vec((out zip node.edgesOut) map { case (o, e) => e.numBeats1(o.b.bits) })
|
val beatsBO = Vec((out zip edgesOut) map { case (o, e) => e.numBeats1(o.b.bits) })
|
||||||
val beatsCI = Vec((in zip node.edgesIn) map { case (i, e) => e.numBeats1(i.c.bits) })
|
val beatsCI = Vec((in zip edgesIn) map { case (i, e) => e.numBeats1(i.c.bits) })
|
||||||
val beatsDO = Vec((out zip node.edgesOut) map { case (o, e) => e.numBeats1(o.d.bits) })
|
val beatsDO = Vec((out zip edgesOut) map { case (o, e) => e.numBeats1(o.d.bits) })
|
||||||
val beatsEI = Vec((in zip node.edgesIn) map { case (i, e) => e.numBeats1(i.e.bits) })
|
val beatsEI = Vec((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]]) = 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
|
||||||
val portsAOI = transpose((in zip requestAIO) map { case (i, r) => TLXbar.fanout(i.a, r, node.paramsOut.map(_(ForceFanoutKey).a)) })
|
val portsAOI = transpose((in zip requestAIO) map { case (i, r) => TLXbar.fanout(i.a, r, edgesOut.map(_.params(ForceFanoutKey).a)) })
|
||||||
val portsBIO = transpose((out zip requestBOI) map { case (o, r) => TLXbar.fanout(o.b, r, node.paramsIn .map(_(ForceFanoutKey).b)) })
|
val portsBIO = transpose((out zip requestBOI) map { case (o, r) => TLXbar.fanout(o.b, r, edgesIn .map(_.params(ForceFanoutKey).b)) })
|
||||||
val portsCOI = transpose((in zip requestCIO) map { case (i, r) => TLXbar.fanout(i.c, r, node.paramsOut.map(_(ForceFanoutKey).c)) })
|
val portsCOI = transpose((in zip requestCIO) map { case (i, r) => TLXbar.fanout(i.c, r, edgesOut.map(_.params(ForceFanoutKey).c)) })
|
||||||
val portsDIO = transpose((out zip requestDOI) map { case (o, r) => TLXbar.fanout(o.d, r, node.paramsIn .map(_(ForceFanoutKey).d)) })
|
val portsDIO = transpose((out zip requestDOI) map { case (o, r) => TLXbar.fanout(o.d, r, edgesIn .map(_.params(ForceFanoutKey).d)) })
|
||||||
val portsEOI = transpose((in zip requestEIO) map { case (i, r) => TLXbar.fanout(i.e, r, node.paramsOut.map(_(ForceFanoutKey).e)) })
|
val portsEOI = transpose((in zip requestEIO) map { case (i, r) => TLXbar.fanout(i.e, r, edgesOut.map(_.params(ForceFanoutKey).e)) })
|
||||||
|
|
||||||
// Arbitrate amongst the sources
|
// Arbitrate amongst the sources
|
||||||
for (o <- 0 until out.size) {
|
for (o <- 0 until out.size) {
|
||||||
val allowI = Seq.tabulate(in.size) { i =>
|
val allowI = Seq.tabulate(in.size) { i =>
|
||||||
node.edgesIn(i).client.anySupportProbe &&
|
edgesIn(i).client.anySupportProbe &&
|
||||||
node.edgesOut(o).manager.anySupportAcquireB
|
edgesOut(o).manager.anySupportAcquireB
|
||||||
}
|
}
|
||||||
TLArbiter(policy)(out(o).a, (beatsAI zip portsAOI(o) ):_*)
|
TLArbiter(policy)(out(o).a, (beatsAI zip portsAOI(o) ):_*)
|
||||||
TLArbiter(policy)(out(o).c, filter(beatsCI zip portsCOI(o), allowI):_*)
|
TLArbiter(policy)(out(o).c, filter(beatsCI zip portsCOI(o), allowI):_*)
|
||||||
@ -198,8 +197,8 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parame
|
|||||||
|
|
||||||
for (i <- 0 until in.size) {
|
for (i <- 0 until in.size) {
|
||||||
val allowO = Seq.tabulate(out.size) { o =>
|
val allowO = Seq.tabulate(out.size) { o =>
|
||||||
node.edgesIn(i).client.anySupportProbe &&
|
edgesIn(i).client.anySupportProbe &&
|
||||||
node.edgesOut(o).manager.anySupportAcquireB
|
edgesOut(o).manager.anySupportAcquireB
|
||||||
}
|
}
|
||||||
TLArbiter(policy)(in(i).b, filter(beatsBO zip portsBIO(i), allowO):_*)
|
TLArbiter(policy)(in(i).b, filter(beatsBO zip portsBIO(i), allowO):_*)
|
||||||
TLArbiter(policy)(in(i).d, (beatsDO zip portsDIO(i) ):_*)
|
TLArbiter(policy)(in(i).d, (beatsDO zip portsDIO(i) ):_*)
|
||||||
@ -264,7 +263,7 @@ class TLRAMXbar(nManagers: Int, txns: Int)(implicit p: Parameters) extends LazyM
|
|||||||
ram.node := TLFragmenter(4, 256)(TLDelayer(0.1)(xbar.node))
|
ram.node := TLFragmenter(4, 256)(TLDelayer(0.1)(xbar.node))
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) with HasUnitTestIO {
|
lazy val module = new LazyModuleImp(this) with UnitTestModule {
|
||||||
io.finished := fuzz.module.io.finished
|
io.finished := fuzz.module.io.finished
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -287,7 +286,7 @@ class TLMulticlientXbar(nManagers: Int, nClients: Int, txns: Int)(implicit p: Pa
|
|||||||
ram.node := TLFragmenter(4, 256)(TLDelayer(0.1)(xbar.node))
|
ram.node := TLFragmenter(4, 256)(TLDelayer(0.1)(xbar.node))
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) with HasUnitTestIO {
|
lazy val module = new LazyModuleImp(this) with UnitTestModule {
|
||||||
io.finished := fuzzers.last.module.io.finished
|
io.finished := fuzzers.last.module.io.finished
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,17 +3,28 @@
|
|||||||
package freechips.rocketchip.unittest
|
package freechips.rocketchip.unittest
|
||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
|
import chisel3.experimental.MultiIOModule
|
||||||
import freechips.rocketchip.config._
|
import freechips.rocketchip.config._
|
||||||
import freechips.rocketchip.util.SimpleTimer
|
import freechips.rocketchip.util.SimpleTimer
|
||||||
|
|
||||||
trait HasUnitTestIO {
|
trait UnitTestIO {
|
||||||
val io = new Bundle {
|
val finished = Bool(OUTPUT)
|
||||||
val finished = Bool(OUTPUT)
|
val start = Bool(INPUT)
|
||||||
val start = Bool(INPUT)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class UnitTest(val timeout: Int = 4096) extends Module with HasUnitTestIO {
|
trait HasUnitTestIO {
|
||||||
|
val io: UnitTestIO
|
||||||
|
}
|
||||||
|
|
||||||
|
trait UnitTestLegacyModule extends HasUnitTestIO {
|
||||||
|
val io = new Bundle with UnitTestIO
|
||||||
|
}
|
||||||
|
|
||||||
|
trait UnitTestModule extends MultiIOModule with HasUnitTestIO {
|
||||||
|
val io = IO(new Bundle with UnitTestIO)
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class UnitTest(val timeout: Int = 4096) extends Module with UnitTestLegacyModule {
|
||||||
val testName = this.getClass.getSimpleName
|
val testName = this.getClass.getSimpleName
|
||||||
|
|
||||||
when (io.start) { printf(s"Started UnitTest $testName\n") }
|
when (io.start) { printf(s"Started UnitTest $testName\n") }
|
||||||
|
Loading…
Reference in New Issue
Block a user