uncore: switch to new diplomacy Node API
Most adapters should work on multiple ports. This patch changes them all.
This commit is contained in:
parent
4d646939b0
commit
972953868c
@ -13,7 +13,7 @@ import uncore.util._
|
||||
|
||||
class ScratchpadSlavePort(implicit p: Parameters) extends LazyModule {
|
||||
val coreDataBytes = p(XLen)/8
|
||||
val node = TLManagerNode(TLManagerPortParameters(
|
||||
val node = TLManagerNode(Seq(TLManagerPortParameters(
|
||||
Seq(TLManagerParameters(
|
||||
address = List(AddressSet(0x80000000L, BigInt(p(DataScratchpadSize)-1))),
|
||||
regionType = RegionType.UNCACHED,
|
||||
@ -25,7 +25,7 @@ class ScratchpadSlavePort(implicit p: Parameters) extends LazyModule {
|
||||
supportsGet = TransferSizes(1, coreDataBytes),
|
||||
fifoId = Some(0))), // requests handled in FIFO order
|
||||
beatBytes = coreDataBytes,
|
||||
minLatency = 1))
|
||||
minLatency = 1)))
|
||||
|
||||
lazy val module = new LazyModuleImp(this) {
|
||||
val io = new Bundle {
|
||||
|
@ -31,16 +31,14 @@ object AHBImp extends NodeImp[AHBMasterPortParameters, AHBSlavePortParameters, A
|
||||
|
||||
// Nodes implemented inside modules
|
||||
case class AHBIdentityNode() extends IdentityNode(AHBImp)
|
||||
case class AHBMasterNode(portParams: AHBMasterPortParameters, numPorts: Range.Inclusive = 1 to 1)
|
||||
extends SourceNode(AHBImp)(portParams, numPorts)
|
||||
case class AHBSlaveNode(portParams: AHBSlavePortParameters, numPorts: Range.Inclusive = 1 to 1)
|
||||
extends SinkNode(AHBImp)(portParams, numPorts)
|
||||
case class AHBAdapterNode(
|
||||
case class AHBMasterNode(portParams: Seq[AHBMasterPortParameters]) extends SourceNode(AHBImp)(portParams)
|
||||
case class AHBSlaveNode(portParams: Seq[AHBSlavePortParameters]) extends SinkNode(AHBImp)(portParams)
|
||||
case class AHBNexusNode(
|
||||
masterFn: Seq[AHBMasterPortParameters] => AHBMasterPortParameters,
|
||||
slaveFn: Seq[AHBSlavePortParameters] => AHBSlavePortParameters,
|
||||
numMasterPorts: Range.Inclusive = 1 to 1,
|
||||
numSlavePorts: Range.Inclusive = 1 to 1)
|
||||
extends InteriorNode(AHBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts)
|
||||
numMasterPorts: Range.Inclusive = 1 to 999,
|
||||
numSlavePorts: Range.Inclusive = 1 to 999)
|
||||
extends NexusNode(AHBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts)
|
||||
|
||||
// Nodes passed from an inner module
|
||||
case class AHBOutputNode() extends OutputNode(AHBImp)
|
||||
|
@ -9,13 +9,13 @@ import regmapper._
|
||||
import scala.math.{min,max}
|
||||
|
||||
class AHBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false)
|
||||
extends AHBSlaveNode(AHBSlavePortParameters(
|
||||
extends AHBSlaveNode(Seq(AHBSlavePortParameters(
|
||||
Seq(AHBSlaveParameters(
|
||||
address = Seq(address),
|
||||
executable = executable,
|
||||
supportsWrite = TransferSizes(1, min(address.alignment.toInt, beatBytes * AHBParameters.maxTransfer)),
|
||||
supportsRead = TransferSizes(1, min(address.alignment.toInt, beatBytes * AHBParameters.maxTransfer)))),
|
||||
beatBytes = beatBytes))
|
||||
beatBytes = beatBytes)))
|
||||
{
|
||||
require (address.contiguous)
|
||||
|
||||
|
@ -8,14 +8,14 @@ import diplomacy._
|
||||
|
||||
class AHBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule
|
||||
{
|
||||
val node = AHBSlaveNode(AHBSlavePortParameters(
|
||||
val node = AHBSlaveNode(Seq(AHBSlavePortParameters(
|
||||
Seq(AHBSlaveParameters(
|
||||
address = List(address),
|
||||
regionType = RegionType.UNCACHED,
|
||||
executable = executable,
|
||||
supportsRead = TransferSizes(1, beatBytes * AHBParameters.maxTransfer),
|
||||
supportsWrite = TransferSizes(1, beatBytes * AHBParameters.maxTransfer))),
|
||||
beatBytes = beatBytes))
|
||||
beatBytes = beatBytes)))
|
||||
|
||||
// We require the address range to include an entire beat (for the write mask)
|
||||
require ((address.mask & (beatBytes-1)) == beatBytes-1)
|
||||
|
@ -9,7 +9,7 @@ import regmapper._
|
||||
import scala.math.{min,max}
|
||||
|
||||
class AHBFanout()(implicit p: Parameters) extends LazyModule {
|
||||
val node = AHBAdapterNode(
|
||||
val node = AHBNexusNode(
|
||||
numSlavePorts = 1 to 1,
|
||||
numMasterPorts = 1 to 32,
|
||||
masterFn = { case Seq(m) => m },
|
||||
|
@ -31,16 +31,14 @@ object APBImp extends NodeImp[APBMasterPortParameters, APBSlavePortParameters, A
|
||||
|
||||
// Nodes implemented inside modules
|
||||
case class APBIdentityNode() extends IdentityNode(APBImp)
|
||||
case class APBMasterNode(portParams: APBMasterPortParameters, numPorts: Range.Inclusive = 1 to 1)
|
||||
extends SourceNode(APBImp)(portParams, numPorts)
|
||||
case class APBSlaveNode(portParams: APBSlavePortParameters, numPorts: Range.Inclusive = 1 to 1)
|
||||
extends SinkNode(APBImp)(portParams, numPorts)
|
||||
case class APBAdapterNode(
|
||||
case class APBMasterNode(portParams: Seq[APBMasterPortParameters]) extends SourceNode(APBImp)(portParams)
|
||||
case class APBSlaveNode(portParams: Seq[APBSlavePortParameters]) extends SinkNode(APBImp)(portParams)
|
||||
case class APBNexusNode(
|
||||
masterFn: Seq[APBMasterPortParameters] => APBMasterPortParameters,
|
||||
slaveFn: Seq[APBSlavePortParameters] => APBSlavePortParameters,
|
||||
numMasterPorts: Range.Inclusive = 1 to 1,
|
||||
numSlavePorts: Range.Inclusive = 1 to 1)
|
||||
extends InteriorNode(APBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts)
|
||||
extends NexusNode(APBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts)
|
||||
|
||||
// Nodes passed from an inner module
|
||||
case class APBOutputNode() extends OutputNode(APBImp)
|
||||
|
@ -9,13 +9,13 @@ import regmapper._
|
||||
import scala.math.{min,max}
|
||||
|
||||
class APBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false)
|
||||
extends APBSlaveNode(APBSlavePortParameters(
|
||||
extends APBSlaveNode(Seq(APBSlavePortParameters(
|
||||
Seq(APBSlaveParameters(
|
||||
address = Seq(address),
|
||||
executable = executable,
|
||||
supportsWrite = true,
|
||||
supportsRead = true)),
|
||||
beatBytes = beatBytes))
|
||||
beatBytes = beatBytes)))
|
||||
{
|
||||
require (address.contiguous)
|
||||
|
||||
|
@ -8,14 +8,14 @@ import diplomacy._
|
||||
|
||||
class APBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule
|
||||
{
|
||||
val node = APBSlaveNode(APBSlavePortParameters(
|
||||
val node = APBSlaveNode(Seq(APBSlavePortParameters(
|
||||
Seq(APBSlaveParameters(
|
||||
address = List(address),
|
||||
regionType = RegionType.UNCACHED,
|
||||
executable = executable,
|
||||
supportsRead = true,
|
||||
supportsWrite = true)),
|
||||
beatBytes = beatBytes))
|
||||
beatBytes = beatBytes)))
|
||||
|
||||
// We require the address range to include an entire beat (for the write mask)
|
||||
require ((address.mask & (beatBytes-1)) == beatBytes-1)
|
||||
|
@ -9,7 +9,7 @@ import regmapper._
|
||||
import scala.math.{min,max}
|
||||
|
||||
class APBFanout()(implicit p: Parameters) extends LazyModule {
|
||||
val node = APBAdapterNode(
|
||||
val node = APBNexusNode(
|
||||
numSlavePorts = 1 to 1,
|
||||
numMasterPorts = 1 to 32,
|
||||
masterFn = { case Seq(m) => m },
|
||||
|
@ -18,8 +18,8 @@ class AXI4Buffer(aw: Int = 2, w: Int = 2, b: Int = 2, ar: Int = 2, r: Int = 2, p
|
||||
require (r >= 0)
|
||||
|
||||
val node = AXI4AdapterNode(
|
||||
masterFn = { case Seq(p) => p },
|
||||
slaveFn = { case Seq(p) => p.copy(minLatency = p.minLatency + min(1,min(aw,ar)) + min(1,min(r,b))) })
|
||||
masterFn = { p => p },
|
||||
slaveFn = { p => p.copy(minLatency = p.minLatency + min(1,min(aw,ar)) + min(1,min(r,b))) })
|
||||
|
||||
lazy val module = new LazyModuleImp(this) {
|
||||
val io = new Bundle {
|
||||
|
@ -23,8 +23,8 @@ class AXI4Fragmenter(lite: Boolean = false, maxInFlight: => Int = 32, combinatio
|
||||
def mapMaster(m: AXI4MasterParameters) = m.copy(aligned = true)
|
||||
|
||||
val node = AXI4AdapterNode(
|
||||
masterFn = { case Seq(mp) => mp.copy(masters = mp.masters.map(m => mapMaster(m))) },
|
||||
slaveFn = { case Seq(sp) => sp.copy(slaves = sp.slaves .map(s => mapSlave(s, sp.beatBytes))) })
|
||||
masterFn = { mp => mp.copy(masters = mp.masters.map(m => mapMaster(m))) },
|
||||
slaveFn = { sp => sp.copy(slaves = sp.slaves .map(s => mapSlave(s, sp.beatBytes))) })
|
||||
|
||||
lazy val module = new LazyModuleImp(this) {
|
||||
val io = new Bundle {
|
||||
@ -32,8 +32,7 @@ class AXI4Fragmenter(lite: Boolean = false, maxInFlight: => Int = 32, combinatio
|
||||
val out = node.bundleOut
|
||||
}
|
||||
|
||||
val edgeOut = node.edgesOut(0)
|
||||
val edgeIn = node.edgesIn(0)
|
||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
||||
val slave = edgeOut.slave
|
||||
val slaves = slave.slaves
|
||||
val beatBytes = slave.beatBytes
|
||||
@ -136,9 +135,6 @@ class AXI4Fragmenter(lite: Boolean = false, maxInFlight: => Int = 32, combinatio
|
||||
(out, last, beats)
|
||||
}
|
||||
|
||||
val in = io.in(0)
|
||||
val out = io.out(0)
|
||||
|
||||
// The size to which we will fragment the access
|
||||
val readSizes1 = slaves.map(s => s.supportsRead .max/beatBytes-1)
|
||||
val writeSizes1 = slaves.map(s => s.supportsWrite.max/beatBytes-1)
|
||||
@ -237,9 +233,9 @@ class AXI4Fragmenter(lite: Boolean = false, maxInFlight: => Int = 32, combinatio
|
||||
when (out_b.fire()) { r_resp := Mux(b_last, UInt(0), resp) }
|
||||
in_b.bits.resp := resp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* We want to put barriers between the fragments of a fragmented transfer and all other transfers.
|
||||
/* We want to put barriers between the fragments of a fragmented transfer and all other transfers.
|
||||
* This lets us use very little state to reassemble the fragments (else we need one FIFO per ID).
|
||||
* Furthermore, because all the fragments share the same AXI ID, they come back contiguously.
|
||||
* This guarantees that no other R responses might get mixed between fragments, ensuring that the
|
||||
@ -247,8 +243,8 @@ class AXI4Fragmenter(lite: Boolean = false, maxInFlight: => Int = 32, combinatio
|
||||
* Of course, if you need to fragment, this means there is a potentially hefty serialization cost.
|
||||
* However, this design allows full concurrency in the common no-fragmentation-needed scenario.
|
||||
*/
|
||||
class AXI4FragmenterSideband(maxInFlight: Int, flow: Boolean = false) extends Module
|
||||
{
|
||||
class AXI4FragmenterSideband(maxInFlight: Int, flow: Boolean = false) extends Module
|
||||
{
|
||||
val io = new QueueIO(Bool(), maxInFlight)
|
||||
io.count := UInt(0)
|
||||
|
||||
@ -283,6 +279,7 @@ class AXI4FragmenterSideband(maxInFlight: Int, flow: Boolean = false) extends Mo
|
||||
is(FIND) { when (io.enq.valid && io.enq.bits && !full) { state := Mux(empty, PASS, WAIT) } }
|
||||
is(WAIT) { when (last && io.deq.ready) { state := PASS } }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object AXI4Fragmenter
|
||||
|
@ -31,16 +31,13 @@ object AXI4Imp extends NodeImp[AXI4MasterPortParameters, AXI4SlavePortParameters
|
||||
|
||||
// Nodes implemented inside modules
|
||||
case class AXI4IdentityNode() extends IdentityNode(AXI4Imp)
|
||||
case class AXI4MasterNode(portParams: AXI4MasterPortParameters, numPorts: Range.Inclusive = 1 to 1)
|
||||
extends SourceNode(AXI4Imp)(portParams, numPorts)
|
||||
case class AXI4SlaveNode(portParams: AXI4SlavePortParameters, numPorts: Range.Inclusive = 1 to 1)
|
||||
extends SinkNode(AXI4Imp)(portParams, numPorts)
|
||||
case class AXI4MasterNode(portParams: Seq[AXI4MasterPortParameters]) extends SourceNode(AXI4Imp)(portParams)
|
||||
case class AXI4SlaveNode(portParams: Seq[AXI4SlavePortParameters]) extends SinkNode(AXI4Imp)(portParams)
|
||||
case class AXI4AdapterNode(
|
||||
masterFn: Seq[AXI4MasterPortParameters] => AXI4MasterPortParameters,
|
||||
slaveFn: Seq[AXI4SlavePortParameters] => AXI4SlavePortParameters,
|
||||
numMasterPorts: Range.Inclusive = 1 to 1,
|
||||
numSlavePorts: Range.Inclusive = 1 to 1)
|
||||
extends InteriorNode(AXI4Imp)(masterFn, slaveFn, numMasterPorts, numSlavePorts)
|
||||
masterFn: AXI4MasterPortParameters => AXI4MasterPortParameters,
|
||||
slaveFn: AXI4SlavePortParameters => AXI4SlavePortParameters,
|
||||
numPorts: Range.Inclusive = 0 to 999)
|
||||
extends AdapterNode(AXI4Imp)(masterFn, slaveFn, numPorts)
|
||||
|
||||
// Nodes passed from an inner module
|
||||
case class AXI4OutputNode() extends OutputNode(AXI4Imp)
|
||||
|
@ -9,7 +9,7 @@ import regmapper._
|
||||
import scala.math.{min,max}
|
||||
|
||||
class AXI4RegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false)
|
||||
extends AXI4SlaveNode(AXI4SlavePortParameters(
|
||||
extends AXI4SlaveNode(Seq(AXI4SlavePortParameters(
|
||||
Seq(AXI4SlaveParameters(
|
||||
address = Seq(address),
|
||||
executable = executable,
|
||||
@ -17,7 +17,7 @@ class AXI4RegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int
|
||||
supportsRead = TransferSizes(1, beatBytes),
|
||||
interleavedId = Some(0))),
|
||||
beatBytes = beatBytes,
|
||||
minLatency = min(concurrency, 1))) // the Queue adds at most one cycle
|
||||
minLatency = min(concurrency, 1)))) // the Queue adds at most one cycle
|
||||
{
|
||||
require (address.contiguous)
|
||||
|
||||
|
@ -8,7 +8,7 @@ import diplomacy._
|
||||
|
||||
class AXI4RAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule
|
||||
{
|
||||
val node = AXI4SlaveNode(AXI4SlavePortParameters(
|
||||
val node = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
|
||||
Seq(AXI4SlaveParameters(
|
||||
address = List(address),
|
||||
regionType = RegionType.UNCACHED,
|
||||
@ -17,7 +17,7 @@ class AXI4RAM(address: AddressSet, executable: Boolean = true, beatBytes: Int =
|
||||
supportsWrite = TransferSizes(1, beatBytes),
|
||||
interleavedId = Some(0))),
|
||||
beatBytes = beatBytes,
|
||||
minLatency = 0)) // B responds on same cycle
|
||||
minLatency = 0))) // B responds on same cycle
|
||||
|
||||
// We require the address range to include an entire beat (for the write mask)
|
||||
require ((address.mask & (beatBytes-1)) == beatBytes-1)
|
||||
|
@ -8,15 +8,15 @@ import config._
|
||||
import diplomacy._
|
||||
import uncore.tilelink2._
|
||||
|
||||
case class AXI4ToTLNode() extends MixedNode(AXI4Imp, TLImp)(
|
||||
dFn = { case (1, Seq(AXI4MasterPortParameters(masters))) =>
|
||||
Seq(TLClientPortParameters(clients = masters.map { m =>
|
||||
case class AXI4ToTLNode() extends MixedAdapterNode(AXI4Imp, TLImp)(
|
||||
dFn = { case AXI4MasterPortParameters(masters) =>
|
||||
TLClientPortParameters(clients = masters.map { m =>
|
||||
TLClientParameters(
|
||||
sourceId = IdRange(m.id.start << 1, m.id.end << 1), // R+W ids are distinct
|
||||
nodePath = m.nodePath)
|
||||
}))
|
||||
})
|
||||
},
|
||||
uFn = { case (1, Seq(mp)) => Seq(AXI4SlavePortParameters(
|
||||
uFn = { mp => AXI4SlavePortParameters(
|
||||
slaves = mp.managers.map { m =>
|
||||
AXI4SlaveParameters(
|
||||
address = m.address,
|
||||
@ -27,10 +27,8 @@ case class AXI4ToTLNode() extends MixedNode(AXI4Imp, TLImp)(
|
||||
supportsRead = m.supportsGet,
|
||||
interleavedId = Some(0))}, // TL2 never interleaves D beats
|
||||
beatBytes = mp.beatBytes,
|
||||
minLatency = mp.minLatency))
|
||||
},
|
||||
numPO = 1 to 1,
|
||||
numPI = 1 to 1)
|
||||
minLatency = mp.minLatency)
|
||||
})
|
||||
|
||||
class AXI4ToTL()(implicit p: Parameters) extends LazyModule
|
||||
{
|
||||
@ -42,10 +40,7 @@ class AXI4ToTL()(implicit p: Parameters) extends LazyModule
|
||||
val out = node.bundleOut
|
||||
}
|
||||
|
||||
val in = io.in(0)
|
||||
val out = io.out(0)
|
||||
val edgeIn = node.edgesIn(0)
|
||||
val edgeOut = node.edgesOut(0)
|
||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
||||
val numIds = edgeIn.master.endId
|
||||
val beatBytes = edgeOut.manager.beatBytes
|
||||
val countBits = AXI4Parameters.lenBits + (1 << AXI4Parameters.sizeBits) - 1
|
||||
@ -168,6 +163,7 @@ class AXI4ToTL()(implicit p: Parameters) extends LazyModule
|
||||
out.c.valid := Bool(false)
|
||||
out.e.valid := Bool(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AXI4BundleRError(params: AXI4BundleParameters) extends AXI4BundleBase(params)
|
||||
|
@ -62,7 +62,7 @@ class TLPLIC(supervisor: Boolean, maxPriorities: Int, address: BigInt = 0xC00000
|
||||
beatBytes = p(rocket.XLen)/8,
|
||||
undefZero = false)
|
||||
|
||||
val intnode = IntAdapterNode(
|
||||
val intnode = IntNexusNode(
|
||||
numSourcePorts = 0 to 1024,
|
||||
numSinkPorts = 0 to 1024,
|
||||
sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(contextsPerHart))) },
|
||||
|
@ -6,6 +6,7 @@ import Chisel._
|
||||
import chisel3.internal.sourceinfo.SourceInfo
|
||||
import config._
|
||||
import diplomacy._
|
||||
import util.GenericParameterizedBundle
|
||||
import scala.math.{min,max}
|
||||
|
||||
// Ensures that all downstream RW managers support Atomic operationss.
|
||||
@ -15,8 +16,8 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc
|
||||
require (concurrency >= 1)
|
||||
|
||||
val node = TLAdapterNode(
|
||||
clientFn = { case Seq(cp) => require (!cp.unsafeAtomics); cp.copy(unsafeAtomics = true) },
|
||||
managerFn = { case Seq(mp) => mp.copy(managers = mp.managers.map { m =>
|
||||
clientFn = { case cp => require (!cp.unsafeAtomics); cp.copy(unsafeAtomics = true) },
|
||||
managerFn = { case mp => mp.copy(managers = mp.managers.map { m =>
|
||||
val ourSupport = TransferSizes(1, mp.beatBytes)
|
||||
def widen(x: TransferSizes) = if (passthrough && x.min <= 2*mp.beatBytes) TransferSizes(1, max(mp.beatBytes, x.max)) else ourSupport
|
||||
val canDoit = m.supportsPutFull.contains(ourSupport) && m.supportsGet.contains(ourSupport)
|
||||
@ -33,10 +34,7 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc
|
||||
val out = node.bundleOut
|
||||
}
|
||||
|
||||
val in = io.in(0)
|
||||
val out = io.out(0)
|
||||
val edgeIn = node.edgesIn(0)
|
||||
val edgeOut = node.edgesOut(0)
|
||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
||||
val managers = edgeOut.manager.managers
|
||||
val beatBytes = edgeOut.manager.beatBytes
|
||||
|
||||
@ -72,25 +70,14 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc
|
||||
if (x.map(_ == x(0)).reduce(_ && _)) x(0).containsLg(lgSize) else
|
||||
Mux1H(select, x.map(_.containsLg(lgSize)))
|
||||
|
||||
val params = TLAtomicAutomata.CAMParams(out.a.bits.params, domainsNeedingHelp.size)
|
||||
// Do we need to do anything at all?
|
||||
if (camSize > 0) {
|
||||
class CAM_S extends Bundle {
|
||||
val state = UInt(width = 2)
|
||||
}
|
||||
class CAM_A extends Bundle {
|
||||
val bits = new TLBundleA(out.a.bits.params)
|
||||
val fifoId = UInt(width = log2Up(domainsNeedingHelp.size))
|
||||
val lut = UInt(width = 4)
|
||||
}
|
||||
class CAM_D extends Bundle {
|
||||
val data = UInt(width = out.a.bits.params.dataBits)
|
||||
}
|
||||
|
||||
val initval = Wire(new CAM_S)
|
||||
val initval = Wire(new TLAtomicAutomata.CAM_S(params))
|
||||
initval.state := FREE
|
||||
val cam_s = RegInit(Vec.fill(camSize)(initval))
|
||||
val cam_a = Reg(Vec(camSize, new CAM_A))
|
||||
val cam_d = Reg(Vec(camSize, new CAM_D))
|
||||
val cam_a = Reg(Vec(camSize, new TLAtomicAutomata.CAM_A(params)))
|
||||
val cam_d = Reg(Vec(camSize, new TLAtomicAutomata.CAM_D(params)))
|
||||
|
||||
val cam_free = cam_s.map(_.state === FREE)
|
||||
val cam_amo = cam_s.map(_.state === AMO)
|
||||
@ -274,6 +261,7 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc
|
||||
out.e.valid := Bool(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object TLAtomicAutomata
|
||||
@ -284,6 +272,20 @@ object TLAtomicAutomata
|
||||
atomics.node := x
|
||||
atomics.node
|
||||
}
|
||||
|
||||
case class CAMParams(a: TLBundleParameters, domainsNeedingHelp: Int)
|
||||
|
||||
class CAM_S(params: CAMParams) extends GenericParameterizedBundle(params) {
|
||||
val state = UInt(width = 2)
|
||||
}
|
||||
class CAM_A(params: CAMParams) extends GenericParameterizedBundle(params) {
|
||||
val bits = new TLBundleA(params.a)
|
||||
val fifoId = UInt(width = log2Up(params.domainsNeedingHelp))
|
||||
val lut = UInt(width = 4)
|
||||
}
|
||||
class CAM_D(params: CAMParams) extends GenericParameterizedBundle(params) {
|
||||
val data = UInt(width = params.a.dataBits)
|
||||
}
|
||||
}
|
||||
|
||||
/** Synthesizeable unit tests */
|
||||
|
@ -13,11 +13,11 @@ class TLBroadcast(lineBytes: Int, numTrackers: Int = 4, bufferless: Boolean = fa
|
||||
require (numTrackers > 0)
|
||||
|
||||
val node = TLAdapterNode(
|
||||
clientFn = { case Seq(cp) =>
|
||||
clientFn = { cp =>
|
||||
cp.copy(clients = Seq(TLClientParameters(
|
||||
sourceId = IdRange(0, 1 << log2Ceil(cp.endSourceId*4)))))
|
||||
},
|
||||
managerFn = { case Seq(mp) =>
|
||||
managerFn = { mp =>
|
||||
mp.copy(
|
||||
endSinkId = numTrackers,
|
||||
managers = mp.managers.map { m =>
|
||||
@ -56,10 +56,7 @@ class TLBroadcast(lineBytes: Int, numTrackers: Int = 4, bufferless: Boolean = fa
|
||||
val out = node.bundleOut
|
||||
}
|
||||
|
||||
val in = io.in(0)
|
||||
val out = io.out(0)
|
||||
val edgeIn = node.edgesIn(0)
|
||||
val edgeOut = node.edgesOut(0)
|
||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
||||
val clients = edgeIn.client.clients
|
||||
val managers = edgeOut.manager.managers
|
||||
val lineShift = log2Ceil(lineBytes)
|
||||
@ -205,6 +202,7 @@ class TLBroadcast(lineBytes: Int, numTrackers: Int = 4, bufferless: Boolean = fa
|
||||
out.c.valid := Bool(false)
|
||||
out.e.valid := Bool(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TLBroadcastTracker(id: Int, lineBytes: Int, probeCountBits: Int, bufferless: Boolean, edgeIn: TLEdgeIn, edgeOut: TLEdgeOut) extends Module
|
||||
|
@ -18,8 +18,8 @@ class TLBuffer(a: Int = 2, b: Int = 2, c: Int = 2, d: Int = 2, e: Int = 2, pipe:
|
||||
require (e >= 0)
|
||||
|
||||
val node = TLAdapterNode(
|
||||
clientFn = { case Seq(p) => p.copy(minLatency = p.minLatency + min(1,b) + min(1,c)) },
|
||||
managerFn = { case Seq(p) => p.copy(minLatency = p.minLatency + min(1,a) + min(1,d)) })
|
||||
clientFn = { p => p.copy(minLatency = p.minLatency + min(1,b) + min(1,c)) },
|
||||
managerFn = { p => p.copy(minLatency = p.minLatency + min(1,a) + min(1,d)) })
|
||||
|
||||
lazy val module = new LazyModuleImp(this) {
|
||||
val io = new Bundle {
|
||||
|
@ -12,10 +12,10 @@ import TLMessages._
|
||||
class TLCacheCork(unsafe: Boolean = false)(implicit p: Parameters) extends LazyModule
|
||||
{
|
||||
val node = TLAdapterNode(
|
||||
clientFn = { case Seq(cp) =>
|
||||
clientFn = { case cp =>
|
||||
cp.copy(clients = cp.clients.map { c => c.copy(
|
||||
sourceId = IdRange(c.sourceId.start*2, c.sourceId.end*2))})},
|
||||
managerFn = { case Seq(mp) =>
|
||||
managerFn = { case mp =>
|
||||
mp.copy(managers = mp.managers.map { m => m.copy(
|
||||
regionType = if (m.regionType == RegionType.UNCACHED) RegionType.TRACKED else m.regionType,
|
||||
supportsAcquireB = m.supportsGet,
|
||||
@ -27,18 +27,13 @@ class TLCacheCork(unsafe: Boolean = false)(implicit p: Parameters) extends LazyM
|
||||
val out = node.bundleOut
|
||||
}
|
||||
|
||||
val edgeIn = node.edgesIn(0)
|
||||
val edgeOut = node.edgesOut(0)
|
||||
|
||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
||||
require (edgeIn.client.clients.size == 1 || unsafe, "Only one client can safely use a TLCacheCork")
|
||||
require (edgeIn.client.clients.filter(_.supportsProbe).size == 1, "Only one caching client allowed")
|
||||
edgeOut.manager.managers.foreach { case m =>
|
||||
require (!m.supportsAcquireB, "Cannot support caches beyond the Cork")
|
||||
}
|
||||
|
||||
val out = io.out(0)
|
||||
val in = io.in(0)
|
||||
|
||||
// The Cork turns [Acquire=>Get] => [AccessAckData=>GrantData]
|
||||
// and [ReleaseData=>PutFullData] => [AccessAck=>ReleaseAck]
|
||||
// We need to encode information sufficient to reverse the transformation in output.
|
||||
@ -115,6 +110,7 @@ class TLCacheCork(unsafe: Boolean = false)(implicit p: Parameters) extends LazyM
|
||||
out.c.valid := Bool(false)
|
||||
out.e.valid := Bool(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object TLCacheCork
|
||||
|
@ -11,8 +11,8 @@ import scala.math.{min,max}
|
||||
class TLFilter(select: AddressSet)(implicit p: Parameters) extends LazyModule
|
||||
{
|
||||
val node = TLAdapterNode(
|
||||
clientFn = { case Seq(cp) => cp },
|
||||
managerFn = { case Seq(mp) =>
|
||||
clientFn = { cp => cp },
|
||||
managerFn = { mp =>
|
||||
mp.copy(managers = mp.managers.map { m =>
|
||||
val filtered = m.address.map(_.intersect(select)).flatten
|
||||
val alignment = select.alignment /* alignment 0 means 'select' selected everything */
|
||||
|
@ -41,8 +41,8 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean =
|
||||
sourceId = IdRange(c.sourceId.start << fragmentBits, c.sourceId.end << fragmentBits))
|
||||
|
||||
val node = TLAdapterNode(
|
||||
clientFn = { case Seq(c) => c.copy(clients = c.clients.map(mapClient)) },
|
||||
managerFn = { case Seq(m) => m.copy(managers = m.managers.map(mapManager)) })
|
||||
clientFn = { c => c.copy(clients = c.clients.map(mapClient)) },
|
||||
managerFn = { m => m.copy(managers = m.managers.map(mapManager)) })
|
||||
|
||||
lazy val module = new LazyModuleImp(this) {
|
||||
val io = new Bundle {
|
||||
@ -50,9 +50,8 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean =
|
||||
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)
|
||||
val edgeOut = node.edgesOut(0)
|
||||
val edgeIn = node.edgesIn(0)
|
||||
val manager = edgeOut.manager
|
||||
val managers = manager.managers
|
||||
val beatBytes = manager.beatBytes
|
||||
@ -129,9 +128,6 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean =
|
||||
* put1 put1 0 ack1 0 ack1 0 0
|
||||
*/
|
||||
|
||||
val in = io.in(0)
|
||||
val out = io.out(0)
|
||||
|
||||
val counterBits = log2Up(maxSize/beatBytes)
|
||||
val maxDownSize = if (alwaysMin) minSize else manager.maxTransfer
|
||||
|
||||
@ -249,6 +245,7 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean =
|
||||
out.c.valid := Bool(false)
|
||||
out.e.valid := Bool(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object TLFragmenter
|
||||
|
@ -12,8 +12,8 @@ import diplomacy._
|
||||
class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = false, passthrough: Boolean = true)(implicit p: Parameters) extends LazyModule
|
||||
{
|
||||
val node = TLAdapterNode(
|
||||
clientFn = { case Seq(c) => if (!supportClients) c else c.copy(minLatency = min(1, c.minLatency), clients = c.clients .map(_.copy(supportsHint = TransferSizes(1, c.maxTransfer)))) },
|
||||
managerFn = { case Seq(m) => if (!supportManagers) m else m.copy(minLatency = min(1, m.minLatency), managers = m.managers.map(_.copy(supportsHint = TransferSizes(1, m.maxTransfer)))) })
|
||||
clientFn = { c => if (!supportClients) c else c.copy(minLatency = min(1, c.minLatency), clients = c.clients .map(_.copy(supportsHint = TransferSizes(1, c.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) {
|
||||
val io = new Bundle {
|
||||
@ -21,11 +21,7 @@ class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = f
|
||||
val out = node.bundleOut
|
||||
}
|
||||
|
||||
val in = io.in(0)
|
||||
val out = io.out(0)
|
||||
val edgeIn = node.edgesIn(0)
|
||||
val edgeOut = node.edgesOut(0)
|
||||
|
||||
((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
|
||||
val bce = edgeOut.manager.anySupportAcquireB && edgeIn.client.anySupportProbe
|
||||
require (!supportClients || bce)
|
||||
@ -96,6 +92,7 @@ class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = f
|
||||
out.e.valid := Bool(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object TLHintHandler
|
||||
|
@ -81,16 +81,16 @@ object IntImp extends NodeImp[IntSourcePortParameters, IntSinkPortParameters, In
|
||||
|
||||
case class IntIdentityNode() extends IdentityNode(IntImp)
|
||||
case class IntSourceNode(num: Int) extends SourceNode(IntImp)(
|
||||
IntSourcePortParameters(Seq(IntSourceParameters(num))), (if (num == 0) 0 else 1) to 1)
|
||||
if (num == 0) Seq() else Seq(IntSourcePortParameters(Seq(IntSourceParameters(num)))))
|
||||
case class IntSinkNode() extends SinkNode(IntImp)(
|
||||
IntSinkPortParameters(Seq(IntSinkParameters())))
|
||||
Seq(IntSinkPortParameters(Seq(IntSinkParameters()))))
|
||||
|
||||
case class IntAdapterNode(
|
||||
case class IntNexusNode(
|
||||
sourceFn: Seq[IntSourcePortParameters] => IntSourcePortParameters,
|
||||
sinkFn: Seq[IntSinkPortParameters] => IntSinkPortParameters,
|
||||
numSourcePorts: Range.Inclusive = 1 to 1,
|
||||
numSinkPorts: Range.Inclusive = 1 to 1)
|
||||
extends InteriorNode(IntImp)(sourceFn, sinkFn, numSourcePorts, numSinkPorts)
|
||||
numSourcePorts: Range.Inclusive = 0 to 128,
|
||||
numSinkPorts: Range.Inclusive = 0 to 128)
|
||||
extends NexusNode(IntImp)(sourceFn, sinkFn, numSourcePorts, numSinkPorts)
|
||||
|
||||
case class IntOutputNode() extends OutputNode(IntImp)
|
||||
case class IntInputNode() extends InputNode(IntImp)
|
||||
@ -103,9 +103,7 @@ case class IntInternalInputNode(num: Int) extends InternalInputNode(IntImp)(Seq(
|
||||
|
||||
class IntXbar()(implicit p: Parameters) extends LazyModule
|
||||
{
|
||||
val intnode = IntAdapterNode(
|
||||
numSourcePorts = 0 to 128,
|
||||
numSinkPorts = 0 to 128,
|
||||
val intnode = IntNexusNode(
|
||||
sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) },
|
||||
sourceFn = { seq =>
|
||||
IntSourcePortParameters((seq zip seq.map(_.num).scanLeft(0)(_+_).init).map {
|
||||
|
@ -86,29 +86,33 @@ object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TL
|
||||
|
||||
// Nodes implemented inside modules
|
||||
case class TLIdentityNode() extends IdentityNode(TLImp)
|
||||
case class TLClientNode(portParams: TLClientPortParameters, numPorts: Range.Inclusive = 1 to 1)
|
||||
extends SourceNode(TLImp)(portParams, numPorts)
|
||||
case class TLManagerNode(portParams: TLManagerPortParameters, numPorts: Range.Inclusive = 1 to 1)
|
||||
extends SinkNode(TLImp)(portParams, numPorts)
|
||||
case class TLClientNode(portParams: Seq[TLClientPortParameters]) extends SourceNode(TLImp)(portParams)
|
||||
case class TLManagerNode(portParams: Seq[TLManagerPortParameters]) extends SinkNode(TLImp)(portParams)
|
||||
|
||||
object TLClientNode
|
||||
{
|
||||
def apply(params: TLClientParameters) =
|
||||
new TLClientNode(TLClientPortParameters(Seq(params)), 1 to 1)
|
||||
new TLClientNode(Seq(TLClientPortParameters(Seq(params))))
|
||||
}
|
||||
|
||||
object TLManagerNode
|
||||
{
|
||||
def apply(beatBytes: Int, params: TLManagerParameters) =
|
||||
new TLManagerNode(TLManagerPortParameters(Seq(params), beatBytes, minLatency = 0), 1 to 1)
|
||||
new TLManagerNode(Seq(TLManagerPortParameters(Seq(params), beatBytes, minLatency = 0)))
|
||||
}
|
||||
|
||||
case class TLAdapterNode(
|
||||
clientFn: TLClientPortParameters => TLClientPortParameters,
|
||||
managerFn: TLManagerPortParameters => TLManagerPortParameters,
|
||||
num: Range.Inclusive = 0 to 999)
|
||||
extends AdapterNode(TLImp)(clientFn, managerFn, num)
|
||||
|
||||
case class TLNexusNode(
|
||||
clientFn: Seq[TLClientPortParameters] => TLClientPortParameters,
|
||||
managerFn: Seq[TLManagerPortParameters] => TLManagerPortParameters,
|
||||
numClientPorts: Range.Inclusive = 1 to 1,
|
||||
numManagerPorts: Range.Inclusive = 1 to 1)
|
||||
extends InteriorNode(TLImp)(clientFn, managerFn, numClientPorts, numManagerPorts)
|
||||
numClientPorts: Range.Inclusive = 1 to 999,
|
||||
numManagerPorts: Range.Inclusive = 1 to 999)
|
||||
extends NexusNode(TLImp)(clientFn, managerFn, numClientPorts, numManagerPorts)
|
||||
|
||||
// Nodes passed from an inner module
|
||||
case class TLOutputNode() extends OutputNode(TLImp)
|
||||
@ -169,17 +173,15 @@ case class TLAsyncIdentityNode() extends IdentityNode(TLAsyncImp)
|
||||
case class TLAsyncOutputNode() extends OutputNode(TLAsyncImp)
|
||||
case class TLAsyncInputNode() extends InputNode(TLAsyncImp)
|
||||
|
||||
case class TLAsyncSourceNode(sync: Int) extends MixedNode(TLImp, TLAsyncImp)(
|
||||
dFn = { case (1, Seq(p)) => Seq(TLAsyncClientPortParameters(p)) },
|
||||
uFn = { case (1, Seq(p)) => Seq(p.base.copy(minLatency = sync+1)) }, // discard cycles in other clock domain
|
||||
numPO = 1 to 1,
|
||||
numPI = 1 to 1)
|
||||
case class TLAsyncSourceNode(sync: Int)
|
||||
extends MixedAdapterNode(TLImp, TLAsyncImp)(
|
||||
dFn = { p => TLAsyncClientPortParameters(p) },
|
||||
uFn = { p => p.base.copy(minLatency = sync+1) }) // discard cycles in other clock domain
|
||||
|
||||
case class TLAsyncSinkNode(depth: Int, sync: Int) extends MixedNode(TLAsyncImp, TLImp)(
|
||||
dFn = { case (1, Seq(p)) => Seq(p.base.copy(minLatency = sync+1)) },
|
||||
uFn = { case (1, Seq(p)) => Seq(TLAsyncManagerPortParameters(depth, p)) },
|
||||
numPO = 1 to 1,
|
||||
numPI = 1 to 1)
|
||||
case class TLAsyncSinkNode(depth: Int, sync: Int)
|
||||
extends MixedAdapterNode(TLAsyncImp, TLImp)(
|
||||
dFn = { p => p.base.copy(minLatency = sync+1) },
|
||||
uFn = { p => TLAsyncManagerPortParameters(depth, p) })
|
||||
|
||||
object TLRationalImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TLEdgeParameters, TLEdgeParameters, TLRationalBundle]
|
||||
{
|
||||
@ -205,14 +207,12 @@ case class TLRationalIdentityNode() extends IdentityNode(TLRationalImp)
|
||||
case class TLRationalOutputNode() extends OutputNode(TLRationalImp)
|
||||
case class TLRationalInputNode() extends InputNode(TLRationalImp)
|
||||
|
||||
case class TLRationalSourceNode() extends MixedNode(TLImp, TLRationalImp)(
|
||||
dFn = { case (_, s) => s },
|
||||
uFn = { case (_, s) => s.map(p => p.copy(minLatency = 1)) }, // discard cycles from other clock domain
|
||||
numPO = 0 to 999,
|
||||
numPI = 0 to 999)
|
||||
case class TLRationalSourceNode()
|
||||
extends MixedAdapterNode(TLImp, TLRationalImp)(
|
||||
dFn = { p => p },
|
||||
uFn = { p => p.copy(minLatency = 1) }) // discard cycles from other clock domain
|
||||
|
||||
case class TLRationalSinkNode() extends MixedNode(TLRationalImp, TLImp)(
|
||||
dFn = { case (_, s) => s.map(p => p.copy(minLatency = 1)) },
|
||||
uFn = { case (_, s) => s },
|
||||
numPO = 0 to 999,
|
||||
numPI = 0 to 999)
|
||||
case class TLRationalSinkNode()
|
||||
extends MixedAdapterNode(TLRationalImp, TLImp)(
|
||||
dFn = { p => p.copy(minLatency = 1) },
|
||||
uFn = { p => p })
|
||||
|
@ -5,6 +5,7 @@ package uncore.tilelink2
|
||||
import Chisel._
|
||||
import config._
|
||||
import diplomacy._
|
||||
import util.GenericParameterizedBundle
|
||||
|
||||
// We detect concurrent puts that put memory into an undefined state.
|
||||
// put0, put0Ack, put1, put1Ack => ok: defined
|
||||
@ -31,13 +32,8 @@ class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule
|
||||
val out = node.bundleOut
|
||||
}
|
||||
|
||||
// !!! support multiple clients via clock division
|
||||
require (io.out.size == 1)
|
||||
|
||||
val in = io.in(0)
|
||||
val out = io.out(0)
|
||||
|
||||
val edge = node.edgesIn(0)
|
||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
||||
val edge = edgeIn
|
||||
val endAddress = edge.manager.maxAddress + 1
|
||||
val endSourceId = edge.client.endSourceId
|
||||
val maxTransfer = edge.manager.maxTransfer
|
||||
@ -71,18 +67,10 @@ class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule
|
||||
in.c.ready := Bool(true)
|
||||
in.e.ready := Bool(true)
|
||||
|
||||
class ByteMonitor extends Bundle {
|
||||
val valid = Bool()
|
||||
val value = UInt(width = 8)
|
||||
}
|
||||
class FlightMonitor extends Bundle {
|
||||
val base = UInt(width = addressBits)
|
||||
val size = UInt(width = sizeBits)
|
||||
val opcode = UInt(width = 3)
|
||||
}
|
||||
val params = TLRAMModel.MonitorParameters(addressBits, sizeBits)
|
||||
|
||||
// Infer as simple dual port BRAM/M10k with write-first/new-data semantics (bypass needed)
|
||||
val shadow = Seq.fill(beatBytes) { Mem(endAddressHi, new ByteMonitor) }
|
||||
val shadow = Seq.fill(beatBytes) { Mem(endAddressHi, new TLRAMModel.ByteMonitor(params)) }
|
||||
val inc_bytes = Seq.fill(beatBytes) { Mem(endAddressHi, UInt(width = countBits)) }
|
||||
val dec_bytes = Seq.fill(beatBytes) { Mem(endAddressHi, UInt(width = countBits)) }
|
||||
val inc_trees = Seq.tabulate(decTrees) { i => Mem(endAddressHi >> (i+1), UInt(width = countBits)) }
|
||||
@ -95,11 +83,11 @@ class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule
|
||||
val dec_trees_wen = Wire(init = Fill(decTrees, wipe))
|
||||
|
||||
// This must be registers b/c we build a CAM from it
|
||||
val flight = Reg(Vec(endSourceId, new FlightMonitor))
|
||||
val flight = Reg(Vec(endSourceId, new TLRAMModel.FlightMonitor(params)))
|
||||
val valid = Reg(Vec(endSourceId, Bool()))
|
||||
|
||||
// We want to cross flight data from A to D in the same cycle (for combinational TL2 devices)
|
||||
val a_flight = Wire(new FlightMonitor)
|
||||
val a_flight = Wire(new TLRAMModel.FlightMonitor(params))
|
||||
a_flight.base := edge.address(in.a.bits)
|
||||
a_flight.size := edge.size(in.a.bits)
|
||||
a_flight.opcode := in.a.bits.opcode
|
||||
@ -169,7 +157,7 @@ class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule
|
||||
|
||||
val a_waddr = Mux(wipe, wipeIndex, a_addr_hi)
|
||||
for (i <- 0 until beatBytes) {
|
||||
val data = Wire(new ByteMonitor)
|
||||
val data = Wire(new TLRAMModel.ByteMonitor(params))
|
||||
val busy = a_inc(i) =/= a_dec(i) + (!a_first).asUInt
|
||||
val amo = a.opcode === TLMessages.ArithmeticData || a.opcode === TLMessages.LogicalData
|
||||
data.valid := Mux(wipe, Bool(false), (!busy || a_fifo) && !amo)
|
||||
@ -295,4 +283,20 @@ class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object TLRAMModel
|
||||
{
|
||||
case class MonitorParameters(addressBits: Int, sizeBits: Int)
|
||||
|
||||
class ByteMonitor(params: MonitorParameters) extends GenericParameterizedBundle(params) {
|
||||
val valid = Bool()
|
||||
val value = UInt(width = 8)
|
||||
}
|
||||
class FlightMonitor(params: MonitorParameters) extends GenericParameterizedBundle(params) {
|
||||
val base = UInt(width = params.addressBits)
|
||||
val size = UInt(width = params.sizeBits)
|
||||
val opcode = UInt(width = 3)
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import regmapper._
|
||||
import scala.math.{min,max}
|
||||
|
||||
class TLRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false)
|
||||
extends TLManagerNode(TLManagerPortParameters(
|
||||
extends TLManagerNode(Seq(TLManagerPortParameters(
|
||||
Seq(TLManagerParameters(
|
||||
address = Seq(address),
|
||||
executable = executable,
|
||||
@ -18,7 +18,7 @@ class TLRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int =
|
||||
supportsPutFull = TransferSizes(1, beatBytes),
|
||||
fifoId = Some(0))), // requests are handled in order
|
||||
beatBytes = beatBytes,
|
||||
minLatency = min(concurrency, 1))) // the Queue adds at most one cycle
|
||||
minLatency = min(concurrency, 1)))) // the Queue adds at most one cycle
|
||||
{
|
||||
require (address.contiguous)
|
||||
|
||||
|
@ -8,7 +8,7 @@ import diplomacy._
|
||||
|
||||
class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule
|
||||
{
|
||||
val node = TLManagerNode(TLManagerPortParameters(
|
||||
val node = TLManagerNode(Seq(TLManagerPortParameters(
|
||||
Seq(TLManagerParameters(
|
||||
address = List(address),
|
||||
regionType = RegionType.UNCACHED,
|
||||
@ -18,7 +18,7 @@ class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)
|
||||
supportsPutFull = TransferSizes(1, beatBytes),
|
||||
fifoId = Some(0))), // requests are handled in order
|
||||
beatBytes = beatBytes,
|
||||
minLatency = 1)) // no bypass needed for this device
|
||||
minLatency = 1))) // no bypass needed for this device
|
||||
|
||||
// We require the address range to include an entire beat (for the write mask)
|
||||
require ((address.mask & (beatBytes-1)) == beatBytes-1)
|
||||
|
@ -15,8 +15,8 @@ class TLSourceShrinker(maxInFlight: Int)(implicit p: Parameters) extends LazyMod
|
||||
private val client = TLClientParameters(sourceId = IdRange(0, maxInFlight))
|
||||
val node = TLAdapterNode(
|
||||
// We erase all client information since we crush the source Ids
|
||||
clientFn = { case _ => TLClientPortParameters(clients = Seq(client)) },
|
||||
managerFn = { case Seq(mp) => mp })
|
||||
clientFn = { _ => TLClientPortParameters(clients = Seq(client)) },
|
||||
managerFn = { mp => mp })
|
||||
|
||||
lazy val module = new LazyModuleImp(this) {
|
||||
val io = new Bundle {
|
||||
@ -24,11 +24,7 @@ class TLSourceShrinker(maxInFlight: Int)(implicit p: Parameters) extends LazyMod
|
||||
val out = node.bundleOut
|
||||
}
|
||||
|
||||
val edgeIn = node.edgesIn(0)
|
||||
val edgeOut = node.edgesOut(0)
|
||||
val in = io.in(0)
|
||||
val out = io.out(0)
|
||||
|
||||
((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
|
||||
require (!edgeIn.client.anySupportProbe ||
|
||||
!edgeOut.manager.anySupportAcquireB)
|
||||
@ -74,6 +70,7 @@ class TLSourceShrinker(maxInFlight: Int)(implicit p: Parameters) extends LazyMod
|
||||
allocated := (allocated | alloc_id) & ~free_id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object TLSourceShrinker
|
||||
|
@ -10,12 +10,12 @@ import uncore.ahb._
|
||||
import scala.math.{min, max}
|
||||
import AHBParameters._
|
||||
|
||||
case class TLToAHBNode() extends MixedNode(TLImp, AHBImp)(
|
||||
dFn = { case (1, Seq(TLClientPortParameters(clients, unsafeAtomics, minLatency))) =>
|
||||
case class TLToAHBNode() extends MixedAdapterNode(TLImp, AHBImp)(
|
||||
dFn = { case TLClientPortParameters(clients, unsafeAtomics, minLatency) =>
|
||||
val masters = clients.map { case c => AHBMasterParameters(nodePath = c.nodePath) }
|
||||
Seq(AHBMasterPortParameters(masters))
|
||||
AHBMasterPortParameters(masters)
|
||||
},
|
||||
uFn = { case (1, Seq(AHBSlavePortParameters(slaves, beatBytes))) =>
|
||||
uFn = { case AHBSlavePortParameters(slaves, beatBytes) =>
|
||||
val managers = slaves.map { case s =>
|
||||
TLManagerParameters(
|
||||
address = s.address,
|
||||
@ -26,10 +26,8 @@ case class TLToAHBNode() extends MixedNode(TLImp, AHBImp)(
|
||||
supportsPutFull = s.supportsWrite, // but not PutPartial
|
||||
fifoId = Some(0)) // a common FIFO domain
|
||||
}
|
||||
Seq(TLManagerPortParameters(managers, beatBytes, 1, 1))
|
||||
},
|
||||
numPO = 1 to 1,
|
||||
numPI = 1 to 1)
|
||||
TLManagerPortParameters(managers, beatBytes, 1, 1)
|
||||
})
|
||||
|
||||
class TLToAHB(combinational: Boolean = true)(implicit p: Parameters) extends LazyModule
|
||||
{
|
||||
@ -41,10 +39,7 @@ class TLToAHB(combinational: Boolean = true)(implicit p: Parameters) extends Laz
|
||||
val out = node.bundleOut
|
||||
}
|
||||
|
||||
val in = io.in(0)
|
||||
val out = io.out(0)
|
||||
val edgeIn = node.edgesIn(0)
|
||||
val edgeOut = node.edgesOut(0)
|
||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
||||
val beatBytes = edgeOut.slave.beatBytes
|
||||
val maxTransfer = edgeOut.slave.maxTransfer
|
||||
val lgMax = log2Ceil(maxTransfer)
|
||||
@ -127,6 +122,7 @@ class TLToAHB(combinational: Boolean = true)(implicit p: Parameters) extends Laz
|
||||
out.hprot := PROT_DEFAULT
|
||||
out.hwdata := RegEnable(a.bits.data, a.fire())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object TLToAHB
|
||||
|
@ -10,12 +10,12 @@ import uncore.apb._
|
||||
import scala.math.{min, max}
|
||||
import APBParameters._
|
||||
|
||||
case class TLToAPBNode() extends MixedNode(TLImp, APBImp)(
|
||||
dFn = { case (1, Seq(TLClientPortParameters(clients, unsafeAtomics, minLatency))) =>
|
||||
case class TLToAPBNode() extends MixedAdapterNode(TLImp, APBImp)(
|
||||
dFn = { case TLClientPortParameters(clients, unsafeAtomics, minLatency) =>
|
||||
val masters = clients.map { case c => APBMasterParameters(nodePath = c.nodePath) }
|
||||
Seq(APBMasterPortParameters(masters))
|
||||
APBMasterPortParameters(masters)
|
||||
},
|
||||
uFn = { case (1, Seq(APBSlavePortParameters(slaves, beatBytes))) =>
|
||||
uFn = { case APBSlavePortParameters(slaves, beatBytes) =>
|
||||
val managers = slaves.map { case s =>
|
||||
TLManagerParameters(
|
||||
address = s.address,
|
||||
@ -27,10 +27,8 @@ case class TLToAPBNode() extends MixedNode(TLImp, APBImp)(
|
||||
supportsPutFull = if (s.supportsWrite) TransferSizes(1, beatBytes) else TransferSizes.none,
|
||||
fifoId = Some(0)) // a common FIFO domain
|
||||
}
|
||||
Seq(TLManagerPortParameters(managers, beatBytes, 1, 0))
|
||||
},
|
||||
numPO = 1 to 1,
|
||||
numPI = 1 to 1)
|
||||
TLManagerPortParameters(managers, beatBytes, 1, 0)
|
||||
})
|
||||
|
||||
class TLToAPB(combinational: Boolean = true)(implicit p: Parameters) extends LazyModule
|
||||
{
|
||||
@ -42,10 +40,7 @@ class TLToAPB(combinational: Boolean = true)(implicit p: Parameters) extends Laz
|
||||
val out = node.bundleOut
|
||||
}
|
||||
|
||||
val in = io.in(0)
|
||||
val out = io.out(0)
|
||||
val edgeIn = node.edgesIn(0)
|
||||
val edgeOut = node.edgesOut(0)
|
||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
||||
val beatBytes = edgeOut.slave.beatBytes
|
||||
val lgBytes = log2Ceil(beatBytes)
|
||||
|
||||
@ -88,6 +83,7 @@ class TLToAPB(combinational: Boolean = true)(implicit p: Parameters) extends Laz
|
||||
d.bits := edgeIn.AccessAck(a.bits, UInt(0), out.prdata, out.pslverr)
|
||||
d.bits.opcode := Mux(a_write, TLMessages.AccessAck, TLMessages.AccessAckData)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object TLToAPB
|
||||
|
@ -10,16 +10,16 @@ import util.PositionalMultiQueue
|
||||
import uncore.axi4._
|
||||
import scala.math.{min, max}
|
||||
|
||||
case class TLToAXI4Node(idBits: Int) extends MixedNode(TLImp, AXI4Imp)(
|
||||
dFn = { case (1, _) =>
|
||||
case class TLToAXI4Node(idBits: Int) extends MixedAdapterNode(TLImp, AXI4Imp)(
|
||||
dFn = { _ =>
|
||||
// We must erase all client information, because we crush their source Ids
|
||||
val masters = Seq(
|
||||
AXI4MasterParameters(
|
||||
id = IdRange(0, 1 << idBits),
|
||||
aligned = true))
|
||||
Seq(AXI4MasterPortParameters(masters))
|
||||
AXI4MasterPortParameters(masters)
|
||||
},
|
||||
uFn = { case (1, Seq(p)) => Seq(TLManagerPortParameters(
|
||||
uFn = { p => TLManagerPortParameters(
|
||||
managers = p.slaves.map { case s =>
|
||||
TLManagerParameters(
|
||||
address = s.address,
|
||||
@ -31,10 +31,8 @@ case class TLToAXI4Node(idBits: Int) extends MixedNode(TLImp, AXI4Imp)(
|
||||
supportsPutPartial = s.supportsWrite)},
|
||||
// AXI4 is NEVER fifo in TL sense (R+W are independent)
|
||||
beatBytes = p.beatBytes,
|
||||
minLatency = p.minLatency))
|
||||
},
|
||||
numPO = 1 to 1,
|
||||
numPI = 1 to 1)
|
||||
minLatency = p.minLatency)
|
||||
})
|
||||
|
||||
class TLToAXI4(idBits: Int, combinational: Boolean = true)(implicit p: Parameters) extends LazyModule
|
||||
{
|
||||
@ -46,11 +44,7 @@ class TLToAXI4(idBits: Int, combinational: Boolean = true)(implicit p: Parameter
|
||||
val out = node.bundleOut
|
||||
}
|
||||
|
||||
val in = io.in(0)
|
||||
val out = io.out(0)
|
||||
|
||||
val edgeIn = node.edgesIn(0)
|
||||
val edgeOut = node.edgesOut(0)
|
||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
||||
val slaves = edgeOut.slave.slaves
|
||||
|
||||
// All pairs of slaves must promise that they will never interleave data
|
||||
@ -226,6 +220,7 @@ class TLToAXI4(idBits: Int, combinational: Boolean = true)(implicit p: Parameter
|
||||
in.c.ready := Bool(true)
|
||||
in.e.ready := Bool(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object TLToAXI4
|
||||
|
@ -12,8 +12,8 @@ import scala.math.{min,max}
|
||||
class TLWidthWidget(innerBeatBytes: Int)(implicit p: Parameters) extends LazyModule
|
||||
{
|
||||
val node = TLAdapterNode(
|
||||
clientFn = { case Seq(c) => c },
|
||||
managerFn = { case Seq(m) => m.copy(beatBytes = innerBeatBytes) })
|
||||
clientFn = { case c => c },
|
||||
managerFn = { case m => m.copy(beatBytes = innerBeatBytes) })
|
||||
|
||||
lazy val module = new LazyModuleImp(this) {
|
||||
val io = new Bundle {
|
||||
@ -139,11 +139,7 @@ class TLWidthWidget(innerBeatBytes: Int)(implicit p: Parameters) extends LazyMod
|
||||
}
|
||||
}
|
||||
|
||||
val edgeOut = node.edgesOut(0)
|
||||
val edgeIn = node.edgesIn(0)
|
||||
val in = io.in(0)
|
||||
val out = io.out(0)
|
||||
|
||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
||||
splice(edgeIn, in.a, edgeOut, out.a)
|
||||
splice(edgeOut, out.d, edgeIn, in.d)
|
||||
|
||||
@ -162,6 +158,7 @@ class TLWidthWidget(innerBeatBytes: Int)(implicit p: Parameters) extends LazyMod
|
||||
out.e.valid := Bool(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object TLWidthWidget
|
||||
|
@ -34,7 +34,7 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.lowestIndexFirst)(implicit p:
|
||||
}
|
||||
}
|
||||
|
||||
val node = TLAdapterNode(
|
||||
val node = TLNexusNode(
|
||||
numClientPorts = 1 to 32,
|
||||
numManagerPorts = 1 to 32,
|
||||
clientFn = { seq =>
|
||||
|
Loading…
Reference in New Issue
Block a user