tilelink2 Parameters: sinkId is per port, not per manager
This commit is contained in:
parent
1b016051e8
commit
d067e87a7d
@ -15,7 +15,7 @@ case class AXI4ToTLNode() extends MixedNode(AXI4Imp, TLImp)(
|
|||||||
nodePath = m.nodePath)
|
nodePath = m.nodePath)
|
||||||
}))
|
}))
|
||||||
},
|
},
|
||||||
uFn = { case (1, Seq(TLManagerPortParameters(managers, beatBytes, _))) =>
|
uFn = { case (1, Seq(TLManagerPortParameters(managers, beatBytes, _, _))) =>
|
||||||
Seq(AXI4SlavePortParameters(beatBytes = beatBytes, slaves = managers.map { m =>
|
Seq(AXI4SlavePortParameters(beatBytes = beatBytes, slaves = managers.map { m =>
|
||||||
AXI4SlaveParameters(
|
AXI4SlaveParameters(
|
||||||
address = m.address,
|
address = m.address,
|
||||||
|
@ -43,7 +43,7 @@ class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = f
|
|||||||
out.a.valid := in.a.valid && !hintBitsAtA
|
out.a.valid := in.a.valid && !hintBitsAtA
|
||||||
in.a.ready := Mux(hintBitsAtA, hint.ready, out.a.ready)
|
in.a.ready := Mux(hintBitsAtA, hint.ready, out.a.ready)
|
||||||
|
|
||||||
hint.bits := edgeIn.HintAck(in.a.bits, edgeOut.manager.findIdStartFast(address))
|
hint.bits := edgeIn.HintAck(in.a.bits, UInt(0))
|
||||||
out.a.bits := in.a.bits
|
out.a.bits := in.a.bits
|
||||||
|
|
||||||
TLArbiter(TLArbiter.lowestIndexFirst)(in.d, (edgeOut.numBeats1(out.d.bits), out.d), (UInt(0), Queue(hint, 1)))
|
TLArbiter(TLArbiter.lowestIndexFirst)(in.d, (edgeOut.numBeats1(out.d.bits), out.d), (UInt(0), Queue(hint, 1)))
|
||||||
|
@ -216,7 +216,7 @@ class TLMonitor(gen: () => TLBundleSnoop, edge: () => TLEdge, sourceInfo: Source
|
|||||||
|
|
||||||
val source_ok = edge.client.contains(bundle.source)
|
val source_ok = edge.client.contains(bundle.source)
|
||||||
val is_aligned = edge.isAligned(bundle.addr_lo, bundle.size)
|
val is_aligned = edge.isAligned(bundle.addr_lo, bundle.size)
|
||||||
val sink_ok = edge.manager.containsById(bundle.sink)
|
val sink_ok = bundle.sink < UInt(edge.manager.endSinkId)
|
||||||
|
|
||||||
when (bundle.opcode === TLMessages.ReleaseAck) {
|
when (bundle.opcode === TLMessages.ReleaseAck) {
|
||||||
assert (source_ok, "'D' channel ReleaseAck carries invalid source ID" + extra)
|
assert (source_ok, "'D' channel ReleaseAck carries invalid source ID" + extra)
|
||||||
@ -270,7 +270,8 @@ class TLMonitor(gen: () => TLBundleSnoop, edge: () => TLEdge, sourceInfo: Source
|
|||||||
}
|
}
|
||||||
|
|
||||||
def legalizeFormatE(bundle: TLBundleE, edge: TLEdge)(implicit sourceInfo: SourceInfo) {
|
def legalizeFormatE(bundle: TLBundleE, edge: TLEdge)(implicit sourceInfo: SourceInfo) {
|
||||||
assert (edge.manager.containsById(bundle.sink), "'E' channels carries invalid sink ID" + extra)
|
val sink_ok = bundle.sink < UInt(edge.manager.endSinkId)
|
||||||
|
assert (sink_ok, "'E' channels carries invalid sink ID" + extra)
|
||||||
}
|
}
|
||||||
|
|
||||||
def legalizeFormat(bundle: TLBundleSnoop, edge: TLEdge)(implicit sourceInfo: SourceInfo) = {
|
def legalizeFormat(bundle: TLBundleSnoop, edge: TLEdge)(implicit sourceInfo: SourceInfo) = {
|
||||||
|
@ -108,7 +108,7 @@ object TLClientNode
|
|||||||
object TLManagerNode
|
object TLManagerNode
|
||||||
{
|
{
|
||||||
def apply(beatBytes: Int, params: TLManagerParameters) =
|
def apply(beatBytes: Int, params: TLManagerParameters) =
|
||||||
new TLManagerNode(TLManagerPortParameters(Seq(params), beatBytes, 0), 1 to 1)
|
new TLManagerNode(TLManagerPortParameters(Seq(params), beatBytes, minLatency = 0), 1 to 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
case class TLAdapterNode(
|
case class TLAdapterNode(
|
||||||
|
@ -8,7 +8,6 @@ import scala.math.max
|
|||||||
|
|
||||||
case class TLManagerParameters(
|
case class TLManagerParameters(
|
||||||
address: Seq[AddressSet],
|
address: Seq[AddressSet],
|
||||||
sinkId: IdRange = IdRange(0, 1),
|
|
||||||
regionType: RegionType.T = RegionType.GET_EFFECTS,
|
regionType: RegionType.T = RegionType.GET_EFFECTS,
|
||||||
executable: Boolean = false, // processor can execute from this memory
|
executable: Boolean = false, // processor can execute from this memory
|
||||||
nodePath: Seq[BaseNode] = Seq(),
|
nodePath: Seq[BaseNode] = Seq(),
|
||||||
@ -59,22 +58,15 @@ case class TLManagerParameters(
|
|||||||
case class TLManagerPortParameters(
|
case class TLManagerPortParameters(
|
||||||
managers: Seq[TLManagerParameters],
|
managers: Seq[TLManagerParameters],
|
||||||
beatBytes: Int,
|
beatBytes: Int,
|
||||||
|
endSinkId: Int = 1,
|
||||||
minLatency: Int = 0)
|
minLatency: Int = 0)
|
||||||
{
|
{
|
||||||
require (!managers.isEmpty)
|
require (!managers.isEmpty)
|
||||||
require (isPow2(beatBytes))
|
require (isPow2(beatBytes))
|
||||||
|
require (endSinkId > 0)
|
||||||
require (minLatency >= 0)
|
require (minLatency >= 0)
|
||||||
|
|
||||||
// Require disjoint ranges for Ids and addresses
|
|
||||||
managers.combinations(2).foreach({ case Seq(x,y) =>
|
|
||||||
require (!x.sinkId.overlaps(y.sinkId))
|
|
||||||
x.address.foreach({ a => y.address.foreach({ b =>
|
|
||||||
require (!a.overlaps(b))
|
|
||||||
})})
|
|
||||||
})
|
|
||||||
|
|
||||||
// Bounds on required sizes
|
// Bounds on required sizes
|
||||||
def endSinkId = managers.map(_.sinkId.end).max
|
|
||||||
def maxAddress = managers.map(_.maxAddress).max
|
def maxAddress = managers.map(_.maxAddress).max
|
||||||
def maxTransfer = managers.map(_.maxTransfer).max
|
def maxTransfer = managers.map(_.maxTransfer).max
|
||||||
|
|
||||||
@ -101,12 +93,6 @@ case class TLManagerPortParameters(
|
|||||||
|
|
||||||
// These return Option[TLManagerParameters] for your convenience
|
// These return Option[TLManagerParameters] for your convenience
|
||||||
def find(address: BigInt) = managers.find(_.address.exists(_.contains(address)))
|
def find(address: BigInt) = managers.find(_.address.exists(_.contains(address)))
|
||||||
def findById(id: Int) = managers.find(_.sinkId.contains(id))
|
|
||||||
|
|
||||||
// Synthesizable lookup methods
|
|
||||||
def findById(id: UInt) = Vec(managers.map(_.sinkId.contains(id)))
|
|
||||||
def findIdStartFast(address: UInt) = Mux1H(findFast(address), managers.map(m => UInt(m.sinkId.start)))
|
|
||||||
def findIdEndFast(address: UInt) = Mux1H(findFast(address), managers.map(m => UInt(m.sinkId.end)))
|
|
||||||
|
|
||||||
// The safe version will check the entire address
|
// The safe version will check the entire address
|
||||||
def findSafe(address: UInt) = Vec(managers.map(_.address.map(_.contains(address)).reduce(_ || _)))
|
def findSafe(address: UInt) = Vec(managers.map(_.address.map(_.contains(address)).reduce(_ || _)))
|
||||||
@ -119,8 +105,6 @@ case class TLManagerPortParameters(
|
|||||||
|
|
||||||
// Does this Port manage this ID/address?
|
// Does this Port manage this ID/address?
|
||||||
def containsSafe(address: UInt) = findSafe(address).reduce(_ || _)
|
def containsSafe(address: UInt) = findSafe(address).reduce(_ || _)
|
||||||
// containsFast would be useless; it could always be true
|
|
||||||
def containsById(id: UInt) = findById(id).reduce(_ || _)
|
|
||||||
|
|
||||||
private def safe_helper(member: TLManagerParameters => TransferSizes)(address: UInt, lgSize: UInt) = {
|
private def safe_helper(member: TLManagerParameters => TransferSizes)(address: UInt, lgSize: UInt) = {
|
||||||
val allSame = managers.map(member(_) == member(managers(0))).reduce(_ && _)
|
val allSame = managers.map(member(_) == member(managers(0))).reduce(_ && _)
|
||||||
|
@ -220,8 +220,6 @@ class TLRAMModel(log: String = "") extends LazyModule
|
|||||||
when (d_fire) {
|
when (d_fire) {
|
||||||
// Check the response is correct
|
// Check the response is correct
|
||||||
assert (d_size === d_flight.size)
|
assert (d_size === d_flight.size)
|
||||||
assert (edge.manager.findIdStartFast(d_flight.base) <= d.sink)
|
|
||||||
assert (edge.manager.findIdEndFast (d_flight.base) > d.sink)
|
|
||||||
// addr_lo is allowed to differ
|
// addr_lo is allowed to differ
|
||||||
|
|
||||||
when (d_flight.opcode === TLMessages.Hint) {
|
when (d_flight.opcode === TLMessages.Hint) {
|
||||||
|
@ -19,10 +19,9 @@ case class TLToAXI4Node(idBits: Int) extends MixedNode(TLImp, AXI4Imp)(
|
|||||||
Seq(AXI4MasterPortParameters(masters))
|
Seq(AXI4MasterPortParameters(masters))
|
||||||
},
|
},
|
||||||
uFn = { case (1, Seq(AXI4SlavePortParameters(slaves, beatBytes))) =>
|
uFn = { case (1, Seq(AXI4SlavePortParameters(slaves, beatBytes))) =>
|
||||||
val managers = slaves.zipWithIndex.map { case (s, id) =>
|
val managers = slaves.map { case s =>
|
||||||
TLManagerParameters(
|
TLManagerParameters(
|
||||||
address = s.address,
|
address = s.address,
|
||||||
sinkId = IdRange(id, id+1),
|
|
||||||
regionType = s.regionType,
|
regionType = s.regionType,
|
||||||
executable = s.executable,
|
executable = s.executable,
|
||||||
nodePath = s.nodePath,
|
nodePath = s.nodePath,
|
||||||
@ -31,7 +30,7 @@ case class TLToAXI4Node(idBits: Int) extends MixedNode(TLImp, AXI4Imp)(
|
|||||||
supportsPutPartial = s.supportsWrite)
|
supportsPutPartial = s.supportsWrite)
|
||||||
// AXI4 is NEVER fifo in TL sense (R+W are independent)
|
// AXI4 is NEVER fifo in TL sense (R+W are independent)
|
||||||
}
|
}
|
||||||
Seq(TLManagerPortParameters(managers, beatBytes, 0))
|
Seq(TLManagerPortParameters(managers, beatBytes, 1, 0))
|
||||||
},
|
},
|
||||||
numPO = 1 to 1,
|
numPO = 1 to 1,
|
||||||
numPI = 1 to 1)
|
numPI = 1 to 1)
|
||||||
@ -64,7 +63,7 @@ class TLToAXI4(idBits: Int, combinational: Boolean = true) extends LazyModule
|
|||||||
// AR before working on AW might have an AW slipped between two AR fragments.
|
// AR before working on AW might have an AW slipped between two AR fragments.
|
||||||
val out_b = Queue.irrevocable(out.b, entries=edgeIn.client.endSourceId, flow=combinational)
|
val out_b = Queue.irrevocable(out.b, entries=edgeIn.client.endSourceId, flow=combinational)
|
||||||
|
|
||||||
// We need to keep the following state from A => D: (addr_lo, size, sink, source)
|
// We need to keep the following state from A => D: (addr_lo, size, source)
|
||||||
// All of those fields could potentially require 0 bits (argh. Chisel.)
|
// All of those fields could potentially require 0 bits (argh. Chisel.)
|
||||||
// We will pack as many of the lowest bits of state as fit into the AXI ID.
|
// We will pack as many of the lowest bits of state as fit into the AXI ID.
|
||||||
// Any bits left-over must be put into a bank of Queues.
|
// Any bits left-over must be put into a bank of Queues.
|
||||||
@ -72,46 +71,39 @@ class TLToAXI4(idBits: Int, combinational: Boolean = true) extends LazyModule
|
|||||||
// The Queues are deep enough that every source has guaranteed space in its Queue.
|
// The Queues are deep enough that every source has guaranteed space in its Queue.
|
||||||
|
|
||||||
val sourceBits = log2Ceil(edgeIn.client.endSourceId)
|
val sourceBits = log2Ceil(edgeIn.client.endSourceId)
|
||||||
val sinkBits = log2Ceil(edgeIn.manager.endSinkId)
|
|
||||||
val sizeBits = log2Ceil(edgeIn.maxLgSize+1)
|
val sizeBits = log2Ceil(edgeIn.maxLgSize+1)
|
||||||
val addrBits = log2Ceil(edgeIn.manager.beatBytes)
|
val addrBits = log2Ceil(edgeIn.manager.beatBytes)
|
||||||
val stateBits = addrBits + sizeBits + sinkBits + sourceBits // could be 0
|
val stateBits = addrBits + sizeBits + sourceBits // could be 0
|
||||||
|
|
||||||
val a_address = edgeIn.address(in.a.bits)
|
val a_address = edgeIn.address(in.a.bits)
|
||||||
val a_addr_lo = edgeIn.addr_lo(a_address)
|
val a_addr_lo = edgeIn.addr_lo(a_address)
|
||||||
val a_source = in.a.bits.source
|
val a_source = in.a.bits.source
|
||||||
val a_sink = edgeIn.manager.findIdStartFast(a_address)
|
|
||||||
val a_size = edgeIn.size(in.a.bits)
|
val a_size = edgeIn.size(in.a.bits)
|
||||||
val a_isPut = edgeIn.hasData(in.a.bits)
|
val a_isPut = edgeIn.hasData(in.a.bits)
|
||||||
val (_, a_last, _) = edgeIn.firstlast(in.a)
|
val (_, a_last, _) = edgeIn.firstlast(in.a)
|
||||||
|
|
||||||
// Make sure the fields are within the bounds we assumed
|
// Make sure the fields are within the bounds we assumed
|
||||||
assert (a_source < UInt(1 << sourceBits))
|
assert (a_source < UInt(1 << sourceBits))
|
||||||
assert (a_sink < UInt(1 << sinkBits))
|
|
||||||
assert (a_size < UInt(1 << sizeBits))
|
assert (a_size < UInt(1 << sizeBits))
|
||||||
assert (a_addr_lo < UInt(1 << addrBits))
|
assert (a_addr_lo < UInt(1 << addrBits))
|
||||||
|
|
||||||
// Carefully pack/unpack fields into the state we send
|
// Carefully pack/unpack fields into the state we send
|
||||||
val baseEnd = 0
|
val baseEnd = 0
|
||||||
val (sourceEnd, sourceOff) = (sourceBits + baseEnd, baseEnd)
|
val (sourceEnd, sourceOff) = (sourceBits + baseEnd, baseEnd)
|
||||||
val (sinkEnd, sinkOff) = (sinkBits + sourceEnd, sourceEnd)
|
val (sizeEnd, sizeOff) = (sizeBits + sourceEnd, sourceEnd)
|
||||||
val (sizeEnd, sizeOff) = (sizeBits + sinkEnd, sinkEnd)
|
|
||||||
val (addrEnd, addrOff) = (addrBits + sizeEnd, sizeEnd)
|
val (addrEnd, addrOff) = (addrBits + sizeEnd, sizeEnd)
|
||||||
require (addrEnd == stateBits)
|
require (addrEnd == stateBits)
|
||||||
|
|
||||||
val a_state = (a_source << sourceOff) | (a_sink << sinkOff) |
|
val a_state = (a_source << sourceOff) | (a_size << sizeOff) | (a_addr_lo << addrOff)
|
||||||
(a_size << sizeOff) | (a_addr_lo << addrOff)
|
|
||||||
val a_id = if (idBits == 0) UInt(0) else a_state
|
val a_id = if (idBits == 0) UInt(0) else a_state
|
||||||
|
|
||||||
val r_state = Wire(UInt(width = stateBits))
|
val r_state = Wire(UInt(width = stateBits))
|
||||||
val r_source = if (sourceBits > 0) r_state(sourceEnd-1, sourceOff) else UInt(0)
|
val r_source = if (sourceBits > 0) r_state(sourceEnd-1, sourceOff) else UInt(0)
|
||||||
val r_sink = if (sinkBits > 0) r_state(sinkEnd -1, sinkOff) else UInt(0)
|
|
||||||
val r_size = if (sizeBits > 0) r_state(sizeEnd -1, sizeOff) else UInt(0)
|
val r_size = if (sizeBits > 0) r_state(sizeEnd -1, sizeOff) else UInt(0)
|
||||||
val r_addr_lo = if (addrBits > 0) r_state(addrEnd -1, addrOff) else UInt(0)
|
val r_addr_lo = if (addrBits > 0) r_state(addrEnd -1, addrOff) else UInt(0)
|
||||||
|
|
||||||
val b_state = Wire(UInt(width = stateBits))
|
val b_state = Wire(UInt(width = stateBits))
|
||||||
val b_source = if (sourceBits > 0) b_state(sourceEnd-1, sourceOff) else UInt(0)
|
val b_source = if (sourceBits > 0) b_state(sourceEnd-1, sourceOff) else UInt(0)
|
||||||
val b_sink = if (sinkBits > 0) b_state(sinkEnd -1, sinkOff) else UInt(0)
|
|
||||||
val b_size = if (sizeBits > 0) b_state(sizeEnd -1, sizeOff) else UInt(0)
|
val b_size = if (sizeBits > 0) b_state(sizeEnd -1, sizeOff) else UInt(0)
|
||||||
val b_addr_lo = if (addrBits > 0) b_state(addrEnd -1, addrOff) else UInt(0)
|
val b_addr_lo = if (addrBits > 0) b_state(addrEnd -1, addrOff) else UInt(0)
|
||||||
|
|
||||||
@ -221,8 +213,8 @@ class TLToAXI4(idBits: Int, combinational: Boolean = true) extends LazyModule
|
|||||||
val r_error = out.r.bits.resp =/= AXI4Parameters.RESP_OKAY
|
val r_error = out.r.bits.resp =/= AXI4Parameters.RESP_OKAY
|
||||||
val b_error = out_b.bits.resp =/= AXI4Parameters.RESP_OKAY
|
val b_error = out_b.bits.resp =/= AXI4Parameters.RESP_OKAY
|
||||||
|
|
||||||
val r_d = edgeIn.AccessAck(r_addr_lo, r_sink, r_source, r_size, UInt(0), r_error)
|
val r_d = edgeIn.AccessAck(r_addr_lo, UInt(0), r_source, r_size, UInt(0), r_error)
|
||||||
val b_d = edgeIn.AccessAck(b_addr_lo, b_sink, b_source, b_size, b_error)
|
val b_d = edgeIn.AccessAck(b_addr_lo, UInt(0), b_source, b_size, b_error)
|
||||||
|
|
||||||
in.d.bits := Mux(r_wins, r_d, b_d)
|
in.d.bits := Mux(r_wins, r_d, b_d)
|
||||||
in.d.bits.data := out.r.bits.data // avoid a costly Mux
|
in.d.bits.data := out.r.bits.data // avoid a costly Mux
|
||||||
|
@ -50,13 +50,14 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.lowestIndexFirst) extends Lazy
|
|||||||
},
|
},
|
||||||
managerFn = { seq =>
|
managerFn = { seq =>
|
||||||
val fifoIdFactory = relabeler()
|
val fifoIdFactory = relabeler()
|
||||||
|
val outputIdRanges = mapOutputIds(seq)
|
||||||
seq(0).copy(
|
seq(0).copy(
|
||||||
minLatency = seq.map(_.minLatency).min,
|
minLatency = seq.map(_.minLatency).min,
|
||||||
managers = (mapOutputIds(seq) zip seq) flatMap { case (range, port) =>
|
endSinkId = outputIdRanges.map(_.end).max,
|
||||||
|
managers = (outputIdRanges zip seq) flatMap { case (range, port) =>
|
||||||
require (port.beatBytes == seq(0).beatBytes)
|
require (port.beatBytes == seq(0).beatBytes)
|
||||||
val fifoIdMapper = fifoIdFactory()
|
val fifoIdMapper = fifoIdFactory()
|
||||||
port.managers map { manager => manager.copy(
|
port.managers map { manager => manager.copy(
|
||||||
sinkId = manager.sinkId.shift(range.start),
|
|
||||||
fifoId = manager.fifoId.map(fifoIdMapper(_))
|
fifoId = manager.fifoId.map(fifoIdMapper(_))
|
||||||
)}
|
)}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user