diff --git a/src/main/scala/protocol/Tilelink.scala b/src/main/scala/protocol/Tilelink.scala index 13ebf32..79e5ffa 100644 --- a/src/main/scala/protocol/Tilelink.scala +++ b/src/main/scala/protocol/Tilelink.scala @@ -30,197 +30,8 @@ trait TLFieldHelper { case b: TLBundleE => Seq( b.sink ) } def minTLPayloadWidth(b: TLChannel): Int = Seq(getBodyFields(b), getConstFields(b)).map(_.map(_.getWidth).sum).max - def minTLPayloadWidth(b: TLBundle): Int = Seq(b.a, b.b, b.c, b.d, b.e).map(t => minTLPayloadWidth(t.bits)).max -} - -abstract class TLChannelToNoC[T <: TLChannel](gen: => T, edge: TLEdge, idToEgress: Int => Int)(implicit val p: Parameters) extends Module with TLFieldHelper { - val flitWidth = minTLPayloadWidth(gen) - val io = IO(new Bundle { - val protocol = Flipped(Decoupled(gen)) - val flit = Decoupled(new IngressFlit(flitWidth)) - }) - def unique(x: Vector[Boolean]): Bool = (x.filter(x=>x).size <= 1).B - - // convert decoupled to irrevocable - val q = Module(new Queue(gen, 1, pipe=true, flow=true)) - val protocol = q.io.deq - - val has_body = Wire(Bool()) - val body_fields = getBodyFields(protocol.bits) - val const_fields = getConstFields(protocol.bits) - val head = edge.first(protocol.bits, protocol.fire()) - val tail = edge.last(protocol.bits, protocol.fire()) - def requestOH: Seq[Bool] - - val body = Cat( body_fields.filter(_.getWidth > 0).map(_.asUInt)) - val const = Cat(const_fields.filter(_.getWidth > 0).map(_.asUInt)) - - val is_body = RegInit(false.B) - io.flit.valid := protocol.valid - protocol.ready := io.flit.ready && (is_body || !has_body) - - io.flit.bits.head := head && !is_body - io.flit.bits.tail := tail && (is_body || !has_body) - io.flit.bits.egress_id := Mux1H(requestOH.zipWithIndex.map { case (r, i) => - r -> idToEgress(i).U - }) - io.flit.bits.payload := Mux(is_body, body, const) - - when (io.flit.fire() && io.flit.bits.head) { is_body := true.B } - when (io.flit.fire() && io.flit.bits.tail) { is_body := false.B } -} - -abstract class TLChannelFromNoC[T <: TLChannel](gen: => T)(implicit val p: Parameters) extends Module with TLFieldHelper { - val flitWidth = minTLPayloadWidth(gen) - val io = IO(new Bundle { - val protocol = Decoupled(gen) - val flit = Flipped(Decoupled(new EgressFlit(flitWidth))) - }) - - // Handle size = 1 gracefully (Chisel3 empty range is broken) - def trim(id: UInt, size: Int): UInt = if (size <= 1) 0.U else id(log2Ceil(size)-1, 0) - - val protocol = Wire(Decoupled(gen)) - val body_fields = getBodyFields(protocol.bits) - val const_fields = getConstFields(protocol.bits) - - val is_const = RegInit(true.B) - val const_reg = Reg(UInt(const_fields.map(_.getWidth).sum.W)) - val const = Mux(io.flit.bits.head, io.flit.bits.payload, const_reg) - io.flit.ready := (is_const && !io.flit.bits.tail) || protocol.ready - protocol.valid := (!is_const || io.flit.bits.tail) && io.flit.valid - - def assign(i: UInt, sigs: Seq[Data]) = { - var t = i - for (s <- sigs.reverse) { - s := t.asTypeOf(s.cloneType) - t = t >> s.getWidth - } - } - assign(const, const_fields) - assign(io.flit.bits.payload, body_fields) - - when (io.flit.fire() && io.flit.bits.head) { is_const := false.B; const_reg := io.flit.bits.payload } - when (io.flit.fire() && io.flit.bits.tail) { is_const := true.B } -} - -trait HasAddressDecoder { - // Filter a list to only those elements selected - def filter[T](data: Seq[T], mask: Seq[Boolean]) = (data zip mask).filter(_._2).map(_._1) - - val edgeIn: TLEdge - val edgesOut: Seq[TLEdge] - lazy val reacheableIO = edgesOut.map { mp => - edgeIn.client.clients.exists { c => mp.manager.managers.exists { m => - c.visibility.exists { ca => m.address.exists { ma => - ca.overlaps(ma) - }} - }} - }.toVector - lazy val releaseIO = (edgesOut zip reacheableIO).map { case (mp, reachable) => - reachable && edgeIn.client.anySupportProbe && mp.manager.anySupportAcquireB - }.toVector - def outputPortFn(connectIO: Seq[Boolean]) = { - val port_addrs = edgesOut.map(_.manager.managers.flatMap(_.address)) - val routingMask = AddressDecoder(filter(port_addrs, connectIO)) - val route_addrs = port_addrs.map(seq => AddressSet.unify(seq.map(_.widen(~routingMask)).distinct)) - route_addrs.map(seq => (addr: UInt) => seq.map(_.contains(addr)).reduce(_||_)) - } -} - -class TLAToNoC( - val edgeIn: TLEdge, - val edgesOut: Seq[TLEdge], - bundle: TLBundleParameters, - slaveToAEgress: Int => Int, - sourceStart: Int -)(implicit p: Parameters) extends TLChannelToNoC(new TLBundleA(bundle), edgeIn, slaveToAEgress)(p) with HasAddressDecoder { - has_body := edgeIn.hasData(protocol.bits) || (~protocol.bits.mask =/= 0.U) - lazy val connectAIO = reacheableIO - lazy val requestOH = outputPortFn(connectAIO).zipWithIndex.map { case (o, j) => - connectAIO(j).B && (unique(connectAIO) || o(protocol.bits.address)) - } - q.io.enq <> io.protocol - q.io.enq.bits.source := io.protocol.bits.source | sourceStart.U -} - -class TLAFromNoC(edgeOut: TLEdge, bundle: TLBundleParameters)(implicit p: Parameters) extends TLChannelFromNoC(new TLBundleA(bundle))(p) { - io.protocol <> protocol - when (io.flit.bits.head) { io.protocol.bits.mask := ~(0.U(io.protocol.bits.mask.getWidth.W)) } -} - -class TLBToNoC( - edgeOut: TLEdge, - edgesIn: Seq[TLEdge], - bundle: TLBundleParameters, - masterToBIngress: Int => Int -)(implicit p: Parameters) extends TLChannelToNoC(new TLBundleB(bundle), edgeOut, masterToBIngress)(p) { - has_body := edgeOut.hasData(protocol.bits) || (~protocol.bits.mask =/= 0.U) - lazy val inputIdRanges = TLXbar.mapInputIds(edgesIn.map(_.client)) - lazy val requestOH = inputIdRanges.map { i => i.contains(protocol.bits.source) } - q.io.enq <> io.protocol -} - -class TLBFromNoC(edgeIn: TLEdge, bundle: TLBundleParameters, sourceSize: Int)(implicit p: Parameters) extends TLChannelFromNoC(new TLBundleB(bundle))(p) { - io.protocol <> protocol - io.protocol.bits.source := trim(protocol.bits.source, sourceSize) - when (io.flit.bits.head) { io.protocol.bits.mask := ~(0.U(io.protocol.bits.mask.getWidth.W)) } -} - -class TLCToNoC( - val edgeIn: TLEdge, - val edgesOut: Seq[TLEdge], - bundle: TLBundleParameters, - slaveToCEgress: Int => Int, - sourceStart: Int -)(implicit p: Parameters) extends TLChannelToNoC(new TLBundleC(bundle), edgeIn, slaveToCEgress)(p) with HasAddressDecoder { - has_body := edgeIn.hasData(protocol.bits) - lazy val connectCIO = releaseIO - lazy val requestOH = outputPortFn(connectCIO).zipWithIndex.map { - case (o, j) => connectCIO(j).B && (unique(connectCIO) || o(protocol.bits.address)) - } - q.io.enq <> io.protocol - q.io.enq.bits.source := io.protocol.bits.source | sourceStart.U -} - -class TLCFromNoC(edgeOut: TLEdge, bundle: TLBundleParameters)(implicit p: Parameters) extends TLChannelFromNoC(new TLBundleC(bundle))(p) { - io.protocol <> protocol -} - -class TLDToNoC( - edgeOut: TLEdge, - edgesIn: Seq[TLEdge], - bundle: TLBundleParameters, - masterToDIngress: Int => Int, - sourceStart: Int -)(implicit p: Parameters) extends TLChannelToNoC(new TLBundleD(bundle), edgeOut, masterToDIngress)(p) { - has_body := edgeOut.hasData(protocol.bits) - lazy val inputIdRanges = TLXbar.mapInputIds(edgesIn.map(_.client)) - lazy val requestOH = inputIdRanges.map { i => i.contains(protocol.bits.source) } - q.io.enq <> io.protocol - q.io.enq.bits.sink := io.protocol.bits.sink | sourceStart.U -} - -class TLDFromNoC(edgeIn: TLEdge, bundle: TLBundleParameters, sourceSize: Int)(implicit p: Parameters) extends TLChannelFromNoC(new TLBundleD(bundle))(p) -{ - io.protocol <> protocol - io.protocol.bits.source := trim(protocol.bits.source, sourceSize) -} - -class TLEToNoC( - val edgeIn: TLEdge, - val edgesOut: Seq[TLEdge], - bundle: TLBundleParameters, - slaveToEEgress: Int => Int -)(implicit p: Parameters) extends TLChannelToNoC(new TLBundleE(bundle), edgeIn, slaveToEEgress)(p) { - has_body := edgeIn.hasData(protocol.bits) - lazy val outputIdRanges = TLXbar.mapOutputIds(edgesOut.map(_.manager)) - lazy val requestOH = outputIdRanges.map { o => o.contains(protocol.bits.sink) } - q.io.enq <> io.protocol -} -class TLEFromNoC(edgeOut: TLEdge, bundle: TLBundleParameters, sourceSize: Int)(implicit p: Parameters) extends TLChannelFromNoC(new TLBundleE(bundle))(p) { - io.protocol <> protocol - io.protocol.bits.sink := trim(protocol.bits.sink, sourceSize) + def minTLPayloadWidth(bs: Seq[TLChannel]): Int = bs.map(b => minTLPayloadWidth(b)).max + def minTLPayloadWidth(b: TLBundle): Int = minTLPayloadWidth(Seq(b.a, b.b, b.c, b.d, b.e).map(_.bits)) } class TLMasterToNoC( @@ -258,6 +69,59 @@ class TLMasterToNoC( io.flits.e <> e.io.flit } +class TLMasterACDToNoC( + edgeIn: TLEdge, edgesOut: Seq[TLEdge], + sourceStart: Int, sourceSize: Int, + wideBundle: TLBundleParameters, + slaveToEgressOffset: Int => Int, + flitWidth: Int +)(implicit p: Parameters) extends Module { + val io = IO(new Bundle { + val tilelink = Flipped(new TLBundle(wideBundle)) + val flits = new Bundle { + val a = Decoupled(new IngressFlit(flitWidth)) + val c = Decoupled(new IngressFlit(flitWidth)) + val d = Flipped(Decoupled(new EgressFlit(flitWidth))) + } + }) + io.tilelink := DontCare + val a = Module(new TLAToNoC(edgeIn, edgesOut, wideBundle, (i) => slaveToEgressOffset(i) + 0, sourceStart)) + val c = Module(new TLCToNoC(edgeIn, edgesOut, wideBundle, (i) => slaveToEgressOffset(i) + 1, sourceStart)) + val d = Module(new TLDFromNoC(edgeIn, wideBundle, sourceSize)) + a.io.protocol <> io.tilelink.a + c.io.protocol <> io.tilelink.c + io.tilelink.d <> d.io.protocol + + io.flits.a <> a.io.flit + io.flits.c <> c.io.flit + d.io.flit <> io.flits.d +} + +class TLMasterBEToNoC( + edgeIn: TLEdge, edgesOut: Seq[TLEdge], + sourceStart: Int, sourceSize: Int, + wideBundle: TLBundleParameters, + slaveToEgressOffset: Int => Int, + flitWidth: Int +)(implicit p: Parameters) extends Module { + val io = IO(new Bundle { + val tilelink = Flipped(new TLBundle(wideBundle)) + val flits = new Bundle { + val b = Flipped(Decoupled(new EgressFlit(flitWidth))) + val e = Decoupled(new IngressFlit(flitWidth)) + } + }) + io.tilelink := DontCare + val b = Module(new TLBFromNoC(edgeIn, wideBundle, sourceSize)) + val e = Module(new TLEToNoC(edgeIn, edgesOut, wideBundle, (i) => slaveToEgressOffset(i) + 0)) + io.tilelink.b <> b.io.protocol + e.io.protocol <> io.tilelink.e + + b.io.flit <> io.flits.b + io.flits.e <> e.io.flit +} + + class TLSlaveToNoC( edgeOut: TLEdge, edgesIn: Seq[TLEdge], sourceStart: Int, sourceSize: Int, @@ -294,29 +158,92 @@ class TLSlaveToNoC( e.io.flit <> io.flits.e } +class TLSlaveACDToNoC( + edgeOut: TLEdge, edgesIn: Seq[TLEdge], + sourceStart: Int, sourceSize: Int, + wideBundle: TLBundleParameters, + masterToEgressOffset: Int => Int, + flitWidth: Int +)(implicit p: Parameters) extends Module { + val io = IO(new Bundle { + val tilelink = new TLBundle(wideBundle) + val flits = new Bundle { + val a = Flipped(Decoupled(new EgressFlit(flitWidth))) + val c = Flipped(Decoupled(new EgressFlit(flitWidth))) + val d = Decoupled(new IngressFlit(flitWidth)) + } + }) + io.tilelink := DontCare + val a = Module(new TLAFromNoC(edgeOut, wideBundle)) + val c = Module(new TLCFromNoC(edgeOut, wideBundle)) + val d = Module(new TLDToNoC(edgeOut, edgesIn, wideBundle, (i) => masterToEgressOffset(i) + 0, sourceStart)) + io.tilelink.a <> a.io.protocol + io.tilelink.c <> c.io.protocol + d.io.protocol <> io.tilelink.d + + a.io.flit <> io.flits.a + c.io.flit <> io.flits.c + io.flits.d <> d.io.flit +} + +class TLSlaveBEToNoC( + edgeOut: TLEdge, edgesIn: Seq[TLEdge], + sourceStart: Int, sourceSize: Int, + wideBundle: TLBundleParameters, + masterToEgressOffset: Int => Int, + flitWidth: Int +)(implicit p: Parameters) extends Module { + val io = IO(new Bundle { + val tilelink = new TLBundle(wideBundle) + val flits = new Bundle { + val b = Decoupled(new IngressFlit(flitWidth)) + val e = Flipped(Decoupled(new EgressFlit(flitWidth))) + } + }) + io.tilelink := DontCare + val b = Module(new TLBToNoC(edgeOut, edgesIn, wideBundle, (i) => masterToEgressOffset(i) + 0)) + val e = Module(new TLEFromNoC(edgeOut, wideBundle, sourceSize)) + b.io.protocol <> io.tilelink.b + io.tilelink.e <> e.io.protocol + + io.flits.b <> b.io.flit + e.io.flit <> io.flits.e +} + class TileLinkInterconnectInterface(edgesIn: Seq[TLEdge], edgesOut: Seq[TLEdge])(implicit val p: Parameters) extends Bundle { val in = MixedVec(edgesIn.map { e => Flipped(new TLBundle(e.bundle)) }) val out = MixedVec(edgesOut.map { e => new TLBundle(e.bundle) }) } +trait TileLinkProtocolParams extends ProtocolParams with TLFieldHelper { + def edgesIn: Seq[TLEdge] + def edgesOut: Seq[TLEdge] + def edgeInNodes: Seq[Int] + def edgeOutNodes: Seq[Int] + require(edgesIn.size == edgeInNodes.size && edgesOut.size == edgeOutNodes.size) + def wideBundle = TLBundleParameters.union(edgesIn.map(_.bundle) ++ edgesOut.map(_.bundle)) + def genBundle = new TLBundle(wideBundle) + def inputIdRanges = TLXbar.mapInputIds(edgesIn.map(_.client)) + def outputIdRanges = TLXbar.mapOutputIds(edgesOut.map(_.manager)) + + val vNetBlocking = (blocker: Int, blockee: Int) => blocker < blockee + + def genIO()(implicit p: Parameters): Data = new TileLinkInterconnectInterface(edgesIn, edgesOut) +} + // BEGIN: TileLinkProtocolParams -case class TileLinkProtocolParams( +case class TileLinkABCDEProtocolParams( edgesIn: Seq[TLEdge], edgesOut: Seq[TLEdge], edgeInNodes: Seq[Int], edgeOutNodes: Seq[Int] -) extends ProtocolParams with TLFieldHelper { +) extends TileLinkProtocolParams { // END: TileLinkProtocolParams - require(edgesIn.size == edgeInNodes.size && edgesOut.size == edgeOutNodes.size) - val wideBundle = TLBundleParameters.union(edgesIn.map(_.bundle) ++ edgesOut.map(_.bundle)) - val inputIdRanges = TLXbar.mapInputIds(edgesIn.map(_.client)) - val outputIdRanges = TLXbar.mapOutputIds(edgesOut.map(_.manager)) - val minPayloadWidth = minTLPayloadWidth(new TLBundle(wideBundle)) val ingressNodes = (edgeInNodes.map(u => Seq.fill(3) (u)) ++ edgeOutNodes.map(u => Seq.fill (2) {u})).flatten val egressNodes = (edgeInNodes.map(u => Seq.fill(2) (u)) ++ edgeOutNodes.map(u => Seq.fill (3) {u})).flatten val nVirtualNetworks = 5 - val vNetBlocking = (blocker: Int, blockee: Int) => blocker < blockee + val flows = edgesIn.zipWithIndex.map { case (edgeIn, ii) => edgesOut.zipWithIndex.map { case (edgeOut, oi) => val reachable = edgeIn.client.clients.exists { c => edgeOut.manager.managers.exists { m => c.visibility.exists { ca => m.address.exists { ma => @@ -331,69 +258,211 @@ case class TileLinkProtocolParams( (if (reachable) Some(FlowParams(oi * 2 + 1 + edgesIn.size * 3, ii * 2 + 1 , 1)) else None) ++ // D (if (release ) Some(FlowParams(ii * 3 + 2 , oi * 3 + 2 + edgesIn.size * 2, 0)) else None)) // E }}.flatten.flatten - def genIO()(implicit p: Parameters): Data = new TileLinkInterconnectInterface(edgesIn, edgesOut) def interface(terminals: NoCTerminalIO, ingressOffset: Int, egressOffset: Int, protocol: Data)(implicit p: Parameters) = { val ingresses = terminals.ingress val egresses = terminals.egress - protocol match { - case protocol: TileLinkInterconnectInterface => { - edgesIn.zipWithIndex.map { case (e,i) => - val nif_master = Module(new TLMasterToNoC( - e, edgesOut, inputIdRanges(i).start, inputIdRanges(i).size, - wideBundle, - (s) => s * 3 + edgesIn.size * 2 + egressOffset, - minPayloadWidth - )) - nif_master.io.tilelink := DontCare - nif_master.io.tilelink.a.valid := false.B - nif_master.io.tilelink.c.valid := false.B - nif_master.io.tilelink.e.valid := false.B - - nif_master.io.tilelink.a <> protocol.in(i).a - protocol.in(i).d <> nif_master.io.tilelink.d - - if (protocol.in(i).params.hasBCE) { - protocol.in(i).b <> nif_master.io.tilelink.b - nif_master.io.tilelink.c <> protocol.in(i).c - protocol.in(i).e <> nif_master.io.tilelink.e - } - - ingresses(i * 3 + 0).flit <> nif_master.io.flits.a - ingresses(i * 3 + 1).flit <> nif_master.io.flits.c - ingresses(i * 3 + 2).flit <> nif_master.io.flits.e - nif_master.io.flits.b <> egresses(i * 2 + 0).flit - nif_master.io.flits.d <> egresses(i * 2 + 1).flit + protocol match { case protocol: TileLinkInterconnectInterface => { + edgesIn.zipWithIndex.map { case (e,i) => + val nif_master = Module(new TLMasterToNoC( + e, edgesOut, inputIdRanges(i).start, inputIdRanges(i).size, + wideBundle, + (s) => s * 3 + edgesIn.size * 2 + egressOffset, + minPayloadWidth + )) + nif_master.io.tilelink := DontCare + nif_master.io.tilelink.a.valid := false.B + nif_master.io.tilelink.c.valid := false.B + nif_master.io.tilelink.e.valid := false.B + + nif_master.io.tilelink.a <> protocol.in(i).a + protocol.in(i).d <> nif_master.io.tilelink.d + + if (protocol.in(i).params.hasBCE) { + protocol.in(i).b <> nif_master.io.tilelink.b + nif_master.io.tilelink.c <> protocol.in(i).c + protocol.in(i).e <> nif_master.io.tilelink.e } - edgesOut.zipWithIndex.map { case (e,i) => - val nif_slave = Module(new TLSlaveToNoC( - e, edgesIn, outputIdRanges(i).start, outputIdRanges(i).size, - wideBundle, - (s) => s * 2 + egressOffset, - minPayloadWidth - )) - nif_slave.io.tilelink := DontCare - nif_slave.io.tilelink.b.valid := false.B - nif_slave.io.tilelink.d.valid := false.B - - protocol.out(i).a <> nif_slave.io.tilelink.a - nif_slave.io.tilelink.d <> protocol.out(i).d - - if (protocol.out(i).params.hasBCE) { - nif_slave.io.tilelink.b <> protocol.out(i).b - protocol.out(i).c <> nif_slave.io.tilelink.c - nif_slave.io.tilelink.e <> protocol.out(i).e - } - - ingresses(i * 2 + 0 + edgesIn.size * 3).flit <> nif_slave.io.flits.b - ingresses(i * 2 + 1 + edgesIn.size * 3).flit <> nif_slave.io.flits.d - nif_slave.io.flits.a <> egresses(i * 3 + 0 + edgesIn.size * 2).flit - nif_slave.io.flits.c <> egresses(i * 3 + 1 + edgesIn.size * 2).flit - nif_slave.io.flits.e <> egresses(i * 3 + 2 + edgesIn.size * 2).flit + + ingresses(i * 3 + 0).flit <> nif_master.io.flits.a + ingresses(i * 3 + 1).flit <> nif_master.io.flits.c + ingresses(i * 3 + 2).flit <> nif_master.io.flits.e + nif_master.io.flits.b <> egresses(i * 2 + 0).flit + nif_master.io.flits.d <> egresses(i * 2 + 1).flit + } + edgesOut.zipWithIndex.map { case (e,i) => + val nif_slave = Module(new TLSlaveToNoC( + e, edgesIn, outputIdRanges(i).start, outputIdRanges(i).size, + wideBundle, + (s) => s * 2 + egressOffset, + minPayloadWidth + )) + nif_slave.io.tilelink := DontCare + nif_slave.io.tilelink.b.valid := false.B + nif_slave.io.tilelink.d.valid := false.B + + protocol.out(i).a <> nif_slave.io.tilelink.a + nif_slave.io.tilelink.d <> protocol.out(i).d + + if (protocol.out(i).params.hasBCE) { + nif_slave.io.tilelink.b <> protocol.out(i).b + protocol.out(i).c <> nif_slave.io.tilelink.c + nif_slave.io.tilelink.e <> protocol.out(i).e } + + ingresses(i * 2 + 0 + edgesIn.size * 3).flit <> nif_slave.io.flits.b + ingresses(i * 2 + 1 + edgesIn.size * 3).flit <> nif_slave.io.flits.d + nif_slave.io.flits.a <> egresses(i * 3 + 0 + edgesIn.size * 2).flit + nif_slave.io.flits.c <> egresses(i * 3 + 1 + edgesIn.size * 2).flit + nif_slave.io.flits.e <> egresses(i * 3 + 2 + edgesIn.size * 2).flit } - } + } } + } +} + +case class TileLinkACDProtocolParams( + edgesIn: Seq[TLEdge], + edgesOut: Seq[TLEdge], + edgeInNodes: Seq[Int], + edgeOutNodes: Seq[Int]) extends TileLinkProtocolParams { + val minPayloadWidth = minTLPayloadWidth(Seq(genBundle.a, genBundle.c, genBundle.d).map(_.bits)) + val ingressNodes = (edgeInNodes.map(u => Seq.fill(2) (u)) ++ edgeOutNodes.map(u => Seq.fill (1) {u})).flatten + val egressNodes = (edgeInNodes.map(u => Seq.fill(1) (u)) ++ edgeOutNodes.map(u => Seq.fill (2) {u})).flatten + + val nVirtualNetworks = 3 + val flows = edgesIn.zipWithIndex.map { case (edgeIn, ii) => edgesOut.zipWithIndex.map { case (edgeOut, oi) => + val reachable = edgeIn.client.clients.exists { c => edgeOut.manager.managers.exists { m => + c.visibility.exists { ca => m.address.exists { ma => + ca.overlaps(ma) + }} + }} + val release = edgeIn.client.anySupportProbe && edgeOut.manager.anySupportAcquireB + ( (if (reachable) Some(FlowParams(ii * 2 + 0 , oi * 2 + 0 + edgesIn.size * 1, 2)) else None) ++ // A + (if (release ) Some(FlowParams(ii * 2 + 1 , oi * 2 + 1 + edgesIn.size * 1, 1)) else None) ++ // C + (if (reachable) Some(FlowParams(oi * 1 + 0 + edgesIn.size * 2, ii * 1 + 0 , 0)) else None)) // D + + }}.flatten.flatten + + + def interface(terminals: NoCTerminalIO, + ingressOffset: Int, egressOffset: Int, protocol: Data)(implicit p: Parameters) = { + val ingresses = terminals.ingress + val egresses = terminals.egress + protocol match { case protocol: TileLinkInterconnectInterface => { + protocol := DontCare + edgesIn.zipWithIndex.map { case (e,i) => + val nif_master_acd = Module(new TLMasterACDToNoC( + e, edgesOut, inputIdRanges(i).start, inputIdRanges(i).size, + wideBundle, + (s) => s * 2 + edgesIn.size * 1 + egressOffset, + minPayloadWidth + )) + nif_master_acd.io.tilelink := DontCare + nif_master_acd.io.tilelink.a.valid := false.B + nif_master_acd.io.tilelink.c.valid := false.B + nif_master_acd.io.tilelink.e.valid := false.B + + nif_master_acd.io.tilelink.a <> protocol.in(i).a + protocol.in(i).d <> nif_master_acd.io.tilelink.d + + if (protocol.in(i).params.hasBCE) { + nif_master_acd.io.tilelink.c <> protocol.in(i).c + } + + ingresses(i * 2 + 0).flit <> nif_master_acd.io.flits.a + ingresses(i * 2 + 1).flit <> nif_master_acd.io.flits.c + nif_master_acd.io.flits.d <> egresses(i * 1 + 0).flit + } + edgesOut.zipWithIndex.map { case (e,i) => + val nif_slave_acd = Module(new TLSlaveACDToNoC( + e, edgesIn, outputIdRanges(i).start, outputIdRanges(i).size, + wideBundle, + (s) => s * 1 + egressOffset, + minPayloadWidth + )) + nif_slave_acd.io.tilelink := DontCare + nif_slave_acd.io.tilelink.b.valid := false.B + nif_slave_acd.io.tilelink.d.valid := false.B + + protocol.out(i).a <> nif_slave_acd.io.tilelink.a + nif_slave_acd.io.tilelink.d <> protocol.out(i).d + + if (protocol.out(i).params.hasBCE) { + protocol.out(i).c <> nif_slave_acd.io.tilelink.c + } + + ingresses(i * 1 + 0 + edgesIn.size * 2).flit <> nif_slave_acd.io.flits.d + nif_slave_acd.io.flits.a <> egresses(i * 2 + 0 + edgesIn.size * 1).flit + nif_slave_acd.io.flits.c <> egresses(i * 2 + 1 + edgesIn.size * 1).flit + } + }} + } +} + +case class TileLinkBEProtocolParams( + edgesIn: Seq[TLEdge], + edgesOut: Seq[TLEdge], + edgeInNodes: Seq[Int], + edgeOutNodes: Seq[Int]) extends TileLinkProtocolParams { + val minPayloadWidth = minTLPayloadWidth(Seq(genBundle.b, genBundle.e).map(_.bits)) + val ingressNodes = (edgeInNodes.map(u => Seq.fill(1) (u)) ++ edgeOutNodes.map(u => Seq.fill (1) {u})).flatten + val egressNodes = (edgeInNodes.map(u => Seq.fill(1) (u)) ++ edgeOutNodes.map(u => Seq.fill (1) {u})).flatten + + val nVirtualNetworks = 2 + val flows = edgesIn.zipWithIndex.map { case (edgeIn, ii) => edgesOut.zipWithIndex.map { case (edgeOut, oi) => + val probe = edgeIn.client.anySupportProbe && edgeOut.manager.managers.exists(_.regionType >= RegionType.TRACKED) + val release = edgeIn.client.anySupportProbe && edgeOut.manager.anySupportAcquireB + ( (if (probe ) Some(FlowParams(oi * 1 + 0 + edgesIn.size * 1, ii * 1 + 0 , 1)) else None) ++ // B + (if (release ) Some(FlowParams(ii * 1 + 0 , oi * 1 + 0 + edgesIn.size * 1, 0)) else None)) // E + }}.flatten.flatten + + def interface(terminals: NoCTerminalIO, + ingressOffset: Int, egressOffset: Int, protocol: Data)(implicit p: Parameters) = { + val ingresses = terminals.ingress + val egresses = terminals.egress + protocol match { case protocol: TileLinkInterconnectInterface => { + protocol := DontCare + edgesIn.zipWithIndex.map { case (e,i) => + val nif_master_be = Module(new TLMasterBEToNoC( + e, edgesOut, inputIdRanges(i).start, inputIdRanges(i).size, + wideBundle, + (s) => s * 1 + edgesIn.size * 1 + egressOffset, + minPayloadWidth + )) + nif_master_be.io.tilelink := DontCare + nif_master_be.io.tilelink.a.valid := false.B + nif_master_be.io.tilelink.c.valid := false.B + nif_master_be.io.tilelink.e.valid := false.B + + if (protocol.in(i).params.hasBCE) { + protocol.in(i).b <> nif_master_be.io.tilelink.b + nif_master_be.io.tilelink.e <> protocol.in(i).e + } + + ingresses(i * 1 + 0).flit <> nif_master_be.io.flits.e + nif_master_be.io.flits.b <> egresses(i * 1 + 0).flit + } + edgesOut.zipWithIndex.map { case (e,i) => + val nif_slave_be = Module(new TLSlaveBEToNoC( + e, edgesIn, outputIdRanges(i).start, outputIdRanges(i).size, + wideBundle, + (s) => s * 1 + egressOffset, + minPayloadWidth + )) + nif_slave_be.io.tilelink := DontCare + nif_slave_be.io.tilelink.b.valid := false.B + nif_slave_be.io.tilelink.d.valid := false.B + + if (protocol.out(i).params.hasBCE) { + protocol.out(i).e <> nif_slave_be.io.tilelink.e + nif_slave_be.io.tilelink.b <> protocol.out(i).b + } + + ingresses(i * 1 + 0 + edgesIn.size * 1).flit <> nif_slave_be.io.flits.b + nif_slave_be.io.flits.e <> egresses(i * 1 + 0 + edgesIn.size * 1).flit + } + }} } } @@ -439,12 +508,6 @@ abstract class TLNoCModuleImp(outer: LazyModule) extends LazyModuleImp(outer) { lazy val outNames = nodeMapping.genUniqueName(edgesOut.map(_.slave.slaves.map(_.name))) lazy val edgeInNodes = nodeMapping.getNodesIn(inNames) lazy val edgeOutNodes = nodeMapping.getNodesOut(outNames) - lazy val protocolParams = TileLinkProtocolParams( - edgesIn = edgesIn, - edgesOut = edgesOut, - edgeInNodes = edgeInNodes.flatten, - edgeOutNodes = edgeOutNodes.flatten - ) def printNodeMappings() { println(s"Constellation: TLNoC $nocName inwards mapping:") for ((n, i) <- inNames zip edgeInNodes) { @@ -460,13 +523,15 @@ abstract class TLNoCModuleImp(outer: LazyModule) extends LazyModuleImp(outer) { } } +trait TLNoCParams + // Instantiates a private TLNoC. Replaces the TLXbar // BEGIN: TLNoCParams -case class TLNoCParams( +case class SimpleTLNoCParams( nodeMappings: DiplomaticNetworkNodeMapping, - nocParams: NoCParams = NoCParams() -) -class TLNoC(params: TLNoCParams, name: String = "test")(implicit p: Parameters) extends TLNoCLike { + nocParams: NoCParams = NoCParams(), +) extends TLNoCParams +class TLNoC(params: SimpleTLNoCParams, name: String = "test")(implicit p: Parameters) extends TLNoCLike { // END: TLNoCParams lazy val module = new TLNoCModuleImp(this) { val (io_in, edgesIn) = node.in.unzip @@ -474,6 +539,14 @@ class TLNoC(params: TLNoCParams, name: String = "test")(implicit p: Parameters) val nodeMapping = params.nodeMappings val nocName = name + val protocolParams = TileLinkABCDEProtocolParams( + edgesIn = edgesIn, + edgesOut = edgesOut, + edgeInNodes = edgeInNodes.flatten, + edgeOutNodes = edgeOutNodes.flatten + ) + + printNodeMappings() val noc = Module(new ProtocolNoC(ProtocolNoCParams( params.nocParams.copy(hasCtrl = false, nocName=name), @@ -489,15 +562,90 @@ class TLNoC(params: TLNoCParams, name: String = "test")(implicit p: Parameters) } } +case class SplitACDxBETLNoCParams( + nodeMappings: DiplomaticNetworkNodeMapping, + acdNoCParams: NoCParams = NoCParams(), + beNoCParams: NoCParams = NoCParams() +) extends TLNoCParams +class TLSplitACDxBENoC(params: SplitACDxBETLNoCParams, name: String = "test")(implicit p: Parameters) extends TLNoCLike { + lazy val module = new TLNoCModuleImp(this) { + val (io_in, edgesIn) = node.in.unzip + val (io_out, edgesOut) = node.out.unzip + val nodeMapping = params.nodeMappings + val nocName = name + + printNodeMappings() + val acdProtocolParams = TileLinkACDProtocolParams( + edgesIn = edgesIn, + edgesOut = edgesOut, + edgeInNodes = edgeInNodes.flatten, + edgeOutNodes = edgeOutNodes.flatten + ) + val beProtocolParams = TileLinkBEProtocolParams( + edgesIn = edgesIn, + edgesOut = edgesOut, + edgeInNodes = edgeInNodes.flatten, + edgeOutNodes = edgeOutNodes.flatten + ) + + val acd_noc = Module(new ProtocolNoC(ProtocolNoCParams( + params.acdNoCParams.copy(hasCtrl = false, nocName=s"${name}_acd"), + Seq(acdProtocolParams) + ))) + val be_noc = Module(new ProtocolNoC(ProtocolNoCParams( + params.beNoCParams.copy(hasCtrl = false, nocName=s"${name}_be"), + Seq(beProtocolParams) + ))) + + acd_noc.io.protocol(0) match { case protocol: TileLinkInterconnectInterface => { + (protocol.in zip io_in).foreach { case (l,r) => + l := DontCare + l.a <> r.a + l.c <> r.c + l.d <> r.d + } + (io_out zip protocol.out).foreach { case (l,r) => + r := DontCare + l.a <> r.a + l.c <> r.c + l.d <> r.d + } + }} + + be_noc.io.protocol(0) match { case protocol: TileLinkInterconnectInterface => { + (protocol.in zip io_in).foreach { case (l,r) => + l := DontCare + l.b <> r.b + l.e <> r.e + } + (io_out zip protocol.out).foreach { case (l,r) => + r := DontCare + l.b <> r.b + l.e <> r.e + } + }} + } +} + +case class GlobalTLNoCParams( + nodeMappings: DiplomaticNetworkNodeMapping +) extends TLNoCParams // Maps this interconnect onto a global NoC -class TLGlobalNoC(params: TLNoCParams, name: String = "test")(implicit p: Parameters) extends TLNoCLike { +class TLGlobalNoC(params: GlobalTLNoCParams, name: String = "test")(implicit p: Parameters) extends TLNoCLike { lazy val module = new TLNoCModuleImp(this) with CanAttachToGlobalNoC { val (io_in, edgesIn) = node.in.unzip val (io_out, edgesOut) = node.out.unzip val nodeMapping = params.nodeMappings val nocName = name + val protocolParams = TileLinkABCDEProtocolParams( + edgesIn = edgesIn, + edgesOut = edgesOut, + edgeInNodes = edgeInNodes.flatten, + edgeOutNodes = edgeOutNodes.flatten + ) + printNodeMappings() val io_global = IO(Flipped(protocolParams.genIO())) io_global match { diff --git a/src/main/scala/soc/Buses.scala b/src/main/scala/soc/Buses.scala index f6a0dbf..ff8c429 100644 --- a/src/main/scala/soc/Buses.scala +++ b/src/main/scala/soc/Buses.scala @@ -17,13 +17,12 @@ import scala.collection.immutable.{ListMap} case class ConstellationSystemBusParams( sbusParams: SystemBusParams, - tlNoCParams: TLNoCParams, - useGlobalNoC: Boolean = false + tlNoCParams: TLNoCParams ) extends TLBusWrapperInstantiationLike { def instantiate(context: HasTileLinkLocations, loc: Location[TLBusWrapper] )(implicit p: Parameters): ConstellationSystemBus = { val constellation = LazyModule(new ConstellationSystemBus( - sbusParams, tlNoCParams, loc.name, useGlobalNoC, context)) + sbusParams, tlNoCParams, loc.name, context)) constellation.suggestName(loc.name) context.tlBusWrapperLocationMap += (loc -> constellation) @@ -32,8 +31,7 @@ case class ConstellationSystemBusParams( } class ConstellationSystemBus( - sbus_params: SystemBusParams, noc_params: TLNoCParams, name: String, - useGlobalNoC: Boolean, context: HasTileLinkLocations + sbus_params: SystemBusParams, noc_params: TLNoCParams, name: String, context: HasTileLinkLocations )(implicit p: Parameters) extends TLBusWrapper(sbus_params, name) { private val replicator = sbus_params.replication.map(r => LazyModule(new RegionReplicator(r))) val prefixNode = replicator.map { r => @@ -41,13 +39,14 @@ class ConstellationSystemBus( addressPrefixNexusNode } - private val system_bus_noc = if (useGlobalNoC) { - context.asInstanceOf[CanHaveGlobalNoC].globalNoCDomain { - LazyModule(new TLGlobalNoC(noc_params, name)) + private val system_bus_noc = LazyModule(noc_params match { + case params: GlobalTLNoCParams => context.asInstanceOf[CanHaveGlobalNoC].globalNoCDomain { + new TLGlobalNoC(params, name) } - } else { - LazyModule(new TLNoC(noc_params, name)) - } + case params: SimpleTLNoCParams => new TLNoC(params, name) + case params: SplitACDxBETLNoCParams => new TLSplitACDxBENoC(params, name) + }) + val inwardNode: TLInwardNode = (system_bus_noc.node :=* TLFIFOFixer(TLFIFOFixer.allVolatile) :=* replicator.map(_.node).getOrElse(TLTempNode())) val outwardNode: TLOutwardNode = system_bus_noc.node @@ -58,13 +57,12 @@ class ConstellationSystemBus( case class ConstellationMemoryBusParams( mbusParams: MemoryBusParams, - tlNoCParams: TLNoCParams, - useGlobalNoC: Boolean = false + tlNoCParams: TLNoCParams ) extends TLBusWrapperInstantiationLike { def instantiate(context: HasTileLinkLocations, loc: Location[TLBusWrapper] )(implicit p: Parameters): ConstellationMemoryBus = { val constellation = LazyModule(new ConstellationMemoryBus( - mbusParams, tlNoCParams, loc.name, useGlobalNoC, context)) + mbusParams, tlNoCParams, loc.name, context)) constellation.suggestName(loc.name) context.tlBusWrapperLocationMap += (loc -> constellation) @@ -72,7 +70,7 @@ case class ConstellationMemoryBusParams( } } -class ConstellationMemoryBus(mbus_params: MemoryBusParams, noc_params: TLNoCParams, name: String, useGlobalNoC: Boolean, context: HasTileLinkLocations) +class ConstellationMemoryBus(mbus_params: MemoryBusParams, noc_params: TLNoCParams, name: String, context: HasTileLinkLocations) (implicit p: Parameters) extends TLBusWrapper(mbus_params, name) { private val replicator = mbus_params.replication.map(r => LazyModule(new RegionReplicator(r))) val prefixNode = replicator.map { r => @@ -80,13 +78,14 @@ class ConstellationMemoryBus(mbus_params: MemoryBusParams, noc_params: TLNoCPara addressPrefixNexusNode } - private val memory_bus_noc = if (useGlobalNoC) { - context.asInstanceOf[CanHaveGlobalNoC].globalNoCDomain { - LazyModule(new TLGlobalNoC(noc_params, name)) + private val memory_bus_noc = LazyModule(noc_params match { + case params: GlobalTLNoCParams => context.asInstanceOf[CanHaveGlobalNoC].globalNoCDomain { + new TLGlobalNoC(params, name) } - } else { - LazyModule(new TLNoC(noc_params, name)) - } + case params: SimpleTLNoCParams => new TLNoC(params, name) + case params: SplitACDxBETLNoCParams => new TLSplitACDxBENoC(params, name) + }) + val inwardNode: TLInwardNode = replicator.map(memory_bus_noc.node :*=* TLFIFOFixer(TLFIFOFixer.all) :*=* _.node) .getOrElse(memory_bus_noc.node :*=* TLFIFOFixer(TLFIFOFixer.all)) @@ -99,12 +98,11 @@ class ConstellationMemoryBus(mbus_params: MemoryBusParams, noc_params: TLNoCPara case class ConstellationPeripheryBusParams( pbusParams: PeripheryBusParams, - tlNoCParams: TLNoCParams, - useGlobalNoC: Boolean = false + tlNoCParams: TLNoCParams ) extends TLBusWrapperInstantiationLike { def instantiate(context: HasTileLinkLocations, loc: Location[TLBusWrapper] )(implicit p: Parameters): ConstellationPeripheryBus = { - val constellation = LazyModule(new ConstellationPeripheryBus(pbusParams, tlNoCParams, loc.name, useGlobalNoC, context)) + val constellation = LazyModule(new ConstellationPeripheryBus(pbusParams, tlNoCParams, loc.name, context)) constellation.suggestName(loc.name) context.tlBusWrapperLocationMap += (loc -> constellation) @@ -112,7 +110,7 @@ case class ConstellationPeripheryBusParams( } } -class ConstellationPeripheryBus(pbus_params: PeripheryBusParams, noc_params: TLNoCParams, name: String, useGlobalNoC: Boolean, context: HasTileLinkLocations) +class ConstellationPeripheryBus(pbus_params: PeripheryBusParams, noc_params: TLNoCParams, name: String, context: HasTileLinkLocations) (implicit p: Parameters) extends TLBusWrapper(pbus_params, name) { private val replicator = pbus_params.replication.map(r => LazyModule(new RegionReplicator(r))) @@ -121,15 +119,13 @@ class ConstellationPeripheryBus(pbus_params: PeripheryBusParams, noc_params: TLN addressPrefixNexusNode } - def genNoC(): TLNoCLike = if (useGlobalNoC) { - context.asInstanceOf[CanHaveGlobalNoC].globalNoCDomain { - val noc = LazyModule(new TLGlobalNoC(noc_params, name)) - noc + def genNoC()(implicit valName: ValName): TLNoCLike = LazyModule(noc_params match { + case params: GlobalTLNoCParams => context.asInstanceOf[CanHaveGlobalNoC].globalNoCDomain { + new TLGlobalNoC(params, name) } - } else { - val noc = LazyModule(new TLNoC(noc_params, name)) - noc - } + case params: SimpleTLNoCParams => new TLNoC(params, name) + case params: SplitACDxBETLNoCParams => new TLSplitACDxBENoC(params, name) + }) private val fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.all)) private val node: TLNode = pbus_params.atomics.map { pa => @@ -153,6 +149,5 @@ class ConstellationPeripheryBus(pbus_params: PeripheryBusParams, noc_params: TLN def busView: TLEdge = fixer.node.edges.in.head val builtInDevices: BuiltInDevices = BuiltInDevices.attach(pbus_params, outwardNode) - } diff --git a/src/main/scala/soc/Configs.scala b/src/main/scala/soc/Configs.scala index 037ee28..cbfd248 100644 --- a/src/main/scala/soc/Configs.scala +++ b/src/main/scala/soc/Configs.scala @@ -14,14 +14,14 @@ import constellation.protocol.TLNoCParams import scala.collection.immutable.{ListMap} /** System bus */ -class WithSbusNoC(tlnocParams: TLNoCParams, globalNoC: Boolean = false) extends Config((site, here, up) => { +class WithSbusNoC(tlnocParams: TLNoCParams) extends Config((site, here, up) => { case TLNetworkTopologyLocated(InSubsystem) => { up(TLNetworkTopologyLocated(InSubsystem), site).map(topo => { topo match { case j: TLBusWrapperTopology => { new TLBusWrapperTopology(j.instantiations.map(inst => inst match { case (SBUS, sbus_params: SystemBusParams) => - (SBUS, ConstellationSystemBusParams(sbus_params, tlnocParams, globalNoC)) + (SBUS, ConstellationSystemBusParams(sbus_params, tlnocParams)) case a => a }), j.connections) } @@ -32,14 +32,14 @@ class WithSbusNoC(tlnocParams: TLNoCParams, globalNoC: Boolean = false) extends }) /** Memory bus */ -class WithMbusNoC(tlnocParams: TLNoCParams, globalNoC: Boolean = false) extends Config((site, here, up) => { +class WithMbusNoC(tlnocParams: TLNoCParams) extends Config((site, here, up) => { case TLNetworkTopologyLocated(InSubsystem) => { up(TLNetworkTopologyLocated(InSubsystem), site).map(topo => { topo match { case j: TLBusWrapperTopology => { new TLBusWrapperTopology(j.instantiations.map(inst => inst match { case (MBUS, mbus_params: MemoryBusParams) => - (MBUS, ConstellationMemoryBusParams(mbus_params, tlnocParams, globalNoC)) + (MBUS, ConstellationMemoryBusParams(mbus_params, tlnocParams)) case a => a }), j.connections) } @@ -68,14 +68,14 @@ class WithCbusNoC(tlnocParams: TLNoCParams) extends Config((site, here, up) => { }) /** Peripheral bus */ -class WithPbusNoC(tlnocParams: TLNoCParams, globalNoC: Boolean = false) extends Config((site, here, up) => { +class WithPbusNoC(tlnocParams: TLNoCParams) extends Config((site, here, up) => { case TLNetworkTopologyLocated(InSubsystem) => { up(TLNetworkTopologyLocated(InSubsystem), site).map(topo => { topo match { case j: TLBusWrapperTopology => { new TLBusWrapperTopology(j.instantiations.map(inst => inst match { case (PBUS, pbus_params: PeripheryBusParams) => - (PBUS, ConstellationPeripheryBusParams(pbus_params, tlnocParams, globalNoC)) + (PBUS, ConstellationPeripheryBusParams(pbus_params, tlnocParams)) case a => a }), j.connections) } diff --git a/src/main/scala/test/TLTestHarness.scala b/src/main/scala/test/TLTestHarness.scala index 08fdfae..da73cff 100644 --- a/src/main/scala/test/TLTestHarness.scala +++ b/src/main/scala/test/TLTestHarness.scala @@ -11,7 +11,7 @@ import freechips.rocketchip.util._ import constellation.noc.{NoCParams, HasNoCParams, NoC} import constellation.channel._ -import constellation.protocol.{TLNoC, TLNoCParams, DiplomaticNetworkNodeMapping} +import constellation.protocol.{TLNoC, SimpleTLNoCParams, DiplomaticNetworkNodeMapping} import constellation.router.{HasRouterCtrlConsts} import scala.collection.immutable.ListMap @@ -36,7 +36,7 @@ class TLNoCTester(implicit p: Parameters) extends LazyModule { outNodeMapping) val nManagers = outNodeMapping.size val nClients = inNodeMapping.size - val noc = LazyModule(new TLNoC(TLNoCParams(nodeMapping, p(TLNoCTesterKey).nocParams.copy(nocName="test")))) + val noc = LazyModule(new TLNoC(SimpleTLNoCParams(nodeMapping, p(TLNoCTesterKey).nocParams.copy(nocName="test")))) val fuzzers = (0 until nClients) map { n => val fuzz = LazyModule(new TLFuzzer(txns))