From d067e87a7de89ad80c5e2bbe576b32ae864530b1 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Wed, 2 Nov 2016 17:53:32 -0700 Subject: [PATCH] tilelink2 Parameters: sinkId is per port, not per manager --- src/main/scala/uncore/axi4/ToTL.scala | 2 +- .../scala/uncore/tilelink2/HintHandler.scala | 2 +- src/main/scala/uncore/tilelink2/Monitor.scala | 5 ++-- src/main/scala/uncore/tilelink2/Nodes.scala | 2 +- .../scala/uncore/tilelink2/Parameters.scala | 20 ++-------------- .../scala/uncore/tilelink2/RAMModel.scala | 2 -- src/main/scala/uncore/tilelink2/ToAXI4.scala | 24 +++++++------------ src/main/scala/uncore/tilelink2/Xbar.scala | 5 ++-- 8 files changed, 19 insertions(+), 43 deletions(-) diff --git a/src/main/scala/uncore/axi4/ToTL.scala b/src/main/scala/uncore/axi4/ToTL.scala index eda60a78..1921c37a 100644 --- a/src/main/scala/uncore/axi4/ToTL.scala +++ b/src/main/scala/uncore/axi4/ToTL.scala @@ -15,7 +15,7 @@ case class AXI4ToTLNode() extends MixedNode(AXI4Imp, TLImp)( 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 => AXI4SlaveParameters( address = m.address, diff --git a/src/main/scala/uncore/tilelink2/HintHandler.scala b/src/main/scala/uncore/tilelink2/HintHandler.scala index 3ba187e0..213f7625 100644 --- a/src/main/scala/uncore/tilelink2/HintHandler.scala +++ b/src/main/scala/uncore/tilelink2/HintHandler.scala @@ -43,7 +43,7 @@ class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = f out.a.valid := in.a.valid && !hintBitsAtA 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 TLArbiter(TLArbiter.lowestIndexFirst)(in.d, (edgeOut.numBeats1(out.d.bits), out.d), (UInt(0), Queue(hint, 1))) diff --git a/src/main/scala/uncore/tilelink2/Monitor.scala b/src/main/scala/uncore/tilelink2/Monitor.scala index 26c60d97..a8af77e3 100644 --- a/src/main/scala/uncore/tilelink2/Monitor.scala +++ b/src/main/scala/uncore/tilelink2/Monitor.scala @@ -216,7 +216,7 @@ class TLMonitor(gen: () => TLBundleSnoop, edge: () => TLEdge, sourceInfo: Source val source_ok = edge.client.contains(bundle.source) 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) { 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) { - 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) = { diff --git a/src/main/scala/uncore/tilelink2/Nodes.scala b/src/main/scala/uncore/tilelink2/Nodes.scala index 962517ba..07cbd94c 100644 --- a/src/main/scala/uncore/tilelink2/Nodes.scala +++ b/src/main/scala/uncore/tilelink2/Nodes.scala @@ -108,7 +108,7 @@ object TLClientNode object TLManagerNode { 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( diff --git a/src/main/scala/uncore/tilelink2/Parameters.scala b/src/main/scala/uncore/tilelink2/Parameters.scala index 4499b852..8ffea166 100644 --- a/src/main/scala/uncore/tilelink2/Parameters.scala +++ b/src/main/scala/uncore/tilelink2/Parameters.scala @@ -8,7 +8,6 @@ import scala.math.max case class TLManagerParameters( address: Seq[AddressSet], - sinkId: IdRange = IdRange(0, 1), regionType: RegionType.T = RegionType.GET_EFFECTS, executable: Boolean = false, // processor can execute from this memory nodePath: Seq[BaseNode] = Seq(), @@ -59,22 +58,15 @@ case class TLManagerParameters( case class TLManagerPortParameters( managers: Seq[TLManagerParameters], beatBytes: Int, + endSinkId: Int = 1, minLatency: Int = 0) { require (!managers.isEmpty) require (isPow2(beatBytes)) + require (endSinkId > 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 - def endSinkId = managers.map(_.sinkId.end).max def maxAddress = managers.map(_.maxAddress).max def maxTransfer = managers.map(_.maxTransfer).max @@ -101,12 +93,6 @@ case class TLManagerPortParameters( // These return Option[TLManagerParameters] for your convenience 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 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? 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) = { val allSame = managers.map(member(_) == member(managers(0))).reduce(_ && _) diff --git a/src/main/scala/uncore/tilelink2/RAMModel.scala b/src/main/scala/uncore/tilelink2/RAMModel.scala index 7ba18da0..37dc2878 100644 --- a/src/main/scala/uncore/tilelink2/RAMModel.scala +++ b/src/main/scala/uncore/tilelink2/RAMModel.scala @@ -220,8 +220,6 @@ class TLRAMModel(log: String = "") extends LazyModule when (d_fire) { // Check the response is correct 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 when (d_flight.opcode === TLMessages.Hint) { diff --git a/src/main/scala/uncore/tilelink2/ToAXI4.scala b/src/main/scala/uncore/tilelink2/ToAXI4.scala index 509a663c..6b476815 100644 --- a/src/main/scala/uncore/tilelink2/ToAXI4.scala +++ b/src/main/scala/uncore/tilelink2/ToAXI4.scala @@ -19,10 +19,9 @@ case class TLToAXI4Node(idBits: Int) extends MixedNode(TLImp, AXI4Imp)( Seq(AXI4MasterPortParameters(masters)) }, uFn = { case (1, Seq(AXI4SlavePortParameters(slaves, beatBytes))) => - val managers = slaves.zipWithIndex.map { case (s, id) => + val managers = slaves.map { case s => TLManagerParameters( address = s.address, - sinkId = IdRange(id, id+1), regionType = s.regionType, executable = s.executable, nodePath = s.nodePath, @@ -31,7 +30,7 @@ case class TLToAXI4Node(idBits: Int) extends MixedNode(TLImp, AXI4Imp)( supportsPutPartial = s.supportsWrite) // 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, 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. 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.) // 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. @@ -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. val sourceBits = log2Ceil(edgeIn.client.endSourceId) - val sinkBits = log2Ceil(edgeIn.manager.endSinkId) val sizeBits = log2Ceil(edgeIn.maxLgSize+1) 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_addr_lo = edgeIn.addr_lo(a_address) 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_isPut = edgeIn.hasData(in.a.bits) val (_, a_last, _) = edgeIn.firstlast(in.a) // Make sure the fields are within the bounds we assumed assert (a_source < UInt(1 << sourceBits)) - assert (a_sink < UInt(1 << sinkBits)) assert (a_size < UInt(1 << sizeBits)) assert (a_addr_lo < UInt(1 << addrBits)) // Carefully pack/unpack fields into the state we send val baseEnd = 0 val (sourceEnd, sourceOff) = (sourceBits + baseEnd, baseEnd) - val (sinkEnd, sinkOff) = (sinkBits + sourceEnd, sourceEnd) - val (sizeEnd, sizeOff) = (sizeBits + sinkEnd, sinkEnd) + val (sizeEnd, sizeOff) = (sizeBits + sourceEnd, sourceEnd) val (addrEnd, addrOff) = (addrBits + sizeEnd, sizeEnd) require (addrEnd == stateBits) - val a_state = (a_source << sourceOff) | (a_sink << sinkOff) | - (a_size << sizeOff) | (a_addr_lo << addrOff) + val a_state = (a_source << sourceOff) | (a_size << sizeOff) | (a_addr_lo << addrOff) val a_id = if (idBits == 0) UInt(0) else a_state val r_state = Wire(UInt(width = stateBits)) 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_addr_lo = if (addrBits > 0) r_state(addrEnd -1, addrOff) else UInt(0) val b_state = Wire(UInt(width = stateBits)) 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_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 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 b_d = edgeIn.AccessAck(b_addr_lo, b_sink, b_source, b_size, b_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, UInt(0), b_source, b_size, b_error) in.d.bits := Mux(r_wins, r_d, b_d) in.d.bits.data := out.r.bits.data // avoid a costly Mux diff --git a/src/main/scala/uncore/tilelink2/Xbar.scala b/src/main/scala/uncore/tilelink2/Xbar.scala index 058353a6..f4c6a82b 100644 --- a/src/main/scala/uncore/tilelink2/Xbar.scala +++ b/src/main/scala/uncore/tilelink2/Xbar.scala @@ -50,13 +50,14 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.lowestIndexFirst) extends Lazy }, managerFn = { seq => val fifoIdFactory = relabeler() + val outputIdRanges = mapOutputIds(seq) seq(0).copy( 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) val fifoIdMapper = fifoIdFactory() port.managers map { manager => manager.copy( - sinkId = manager.sinkId.shift(range.start), fifoId = manager.fifoId.map(fifoIdMapper(_)) )} }