Skip to content

Commit

Permalink
Support FIFO flows
Browse files Browse the repository at this point in the history
  • Loading branch information
jerryz123 committed Jun 13, 2023
1 parent a70acdf commit cde8503
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 12 deletions.
3 changes: 2 additions & 1 deletion src/main/scala/channel/Parameters.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import constellation.noc.{HasNoCParams}
case class FlowParams(
ingressId: Int,
egressId: Int,
vNetId: Int
vNetId: Int,
fifo: Boolean = false
)
// END: FlowParams

Expand Down
5 changes: 4 additions & 1 deletion src/main/scala/noc/Parameters.scala
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ object InternalNoCParams {
ingressNode=ingressNode,
egressNode=egressNode,
ingressNodeId=nocParams.ingresses.take(f.ingressId).count(_.destId == ingressNode),
egressNodeId=nocParams.egresses.take(f.egressId).count(_.srcId == egressNode)
egressNodeId=nocParams.egresses.take(f.egressId).count(_.srcId == egressNode),
fifo = f.fifo
)
}
val ingressParams = nocParams.ingresses.zipWithIndex.map { case (u,i) => {
Expand Down Expand Up @@ -174,6 +175,8 @@ object InternalNoCParams {
s"Failed to route $flow at $head \n $stack \n ${nextChannelParamMap(head.dst)}")
require((nexts.toSet & stack.toSet).size == 0,
s"$flow, $nexts, $stack")
require(!(flow.fifo && nexts.map(_.dst).distinct.size != 1),
s"FIFO flow $flow at $head routes to multiple possible next-nodes \n $nexts")
stack = Seq(nexts.head) ++ stack
unexplored = nexts.tail.filter(n => !unexplored.contains(n)) ++ unexplored
} else {
Expand Down
20 changes: 19 additions & 1 deletion src/main/scala/router/InputUnit.scala
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ class InputUnit(cParam: ChannelParams, outParams: Seq[ChannelParams],
val g = UInt(3.W)
val vc_sel = MixedVec(allOutParams.map { u => Vec(u.nVirtualChannels, Bool()) })
val flow = new FlowRoutingBundle
val fifo_deps = UInt(nVirtualChannels.W)
}

val input_buffer = Module(new InputBuffer(cParam))
Expand All @@ -190,6 +191,16 @@ class InputUnit(cParam: ChannelParams, outParams: Seq[ChannelParams],

val states = Reg(Vec(nVirtualChannels, new InputState))

val anyFifo = cParam.possibleFlows.map(_.fifo).reduce(_||_)
val allFifo = cParam.possibleFlows.map(_.fifo).reduce(_&&_)

if (anyFifo) {
val idle_mask = VecInit(states.map(_.g === g_i)).asUInt
for (s <- states)
for (i <- 0 until nVirtualChannels)
s.fifo_deps := s.fifo_deps & ~idle_mask
}

for (i <- 0 until cParam.srcSpeedup) {
when (io.in.flit(i).fire() && io.in.flit(i).bits.head) {
val id = io.in.flit(i).bits.virt_channel_id
Expand All @@ -204,6 +215,12 @@ class InputUnit(cParam: ChannelParams, outParams: Seq[ChannelParams],
}
}
states(id).flow := io.in.flit(i).bits.flow
if (anyFifo) {
val fifo = cParam.possibleFlows.filter(_.fifo).map(_.isFlow(io.in.flit(i).bits.flow)).toSeq.orR
states(id).fifo_deps := VecInit(states.zipWithIndex.map { case (s, j) =>
s.g =/= g_i && s.flow.asUInt === io.in.flit(i).bits.flow.asUInt && j.U =/= id
}).asUInt
}
}
}

Expand Down Expand Up @@ -246,7 +263,7 @@ class InputUnit(cParam: ChannelParams, outParams: Seq[ChannelParams],

states.zipWithIndex.map { case (s,idx) =>
if (virtualChannelParams(idx).traversable) {
vcalloc_vals(idx) := s.g === g_v
vcalloc_vals(idx) := s.g === g_v && s.fifo_deps === 0.U
vcalloc_reqs(idx).in_vc := idx.U
vcalloc_reqs(idx).vc_sel := s.vc_sel
vcalloc_reqs(idx).flow := s.flow
Expand Down Expand Up @@ -298,6 +315,7 @@ class InputUnit(cParam: ChannelParams, outParams: Seq[ChannelParams],
r.bits := DontCare
}
}

io.debug.sa_stall := PopCount(salloc_arb.io.in.map(r => r.valid && !r.ready))
io.salloc_req <> salloc_arb.io.out
when (io.block) {
Expand Down
3 changes: 2 additions & 1 deletion src/main/scala/routing/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ case class FlowRoutingInfo(
ingressNode: Int,
ingressNodeId: Int,
egressNode: Int,
egressNodeId: Int
egressNodeId: Int,
fifo: Boolean
) {
// END: FlowRoutingInfo
def isFlow(f: FlowRoutingBundle): Bool = {
Expand Down
10 changes: 5 additions & 5 deletions src/main/scala/test/Configs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class TestConfig02 extends NoCTesterConfig(NoCTesterParams(NoCParams(
),
ingresses = Seq(0, 0).map { i => UserIngressParams(i) },
egresses = Seq(1, 1).map { i => UserEgressParams(1) },
flows = Seq.tabulate(2, 2) { (s, d) => FlowParams(s, d, 0) }.flatten,
flows = Seq.tabulate(2, 2) { (s, d) => FlowParams(s, d, 0, fifo=true) }.flatten,
routingRelation = UnidirectionalLineRouting()
)))
class TestConfig03 extends NoCTesterConfig(NoCTesterParams(NoCParams(
Expand Down Expand Up @@ -155,7 +155,7 @@ class TestConfig14 extends NoCTesterConfig(NoCTesterParams(NoCParams(
channelParamGen = (a, b) => UserChannelParams(Seq.fill(4) { UserVirtualChannelParams(5) }),
ingresses = Seq(0, 2).map { i => UserIngressParams(i) },
egresses = Seq(1, 3).map { i => UserEgressParams(i) },
flows = Seq.tabulate(2, 2) { (s, d) => FlowParams(s, d, 0) }.flatten,
flows = Seq.tabulate(2, 2) { (s, d) => FlowParams(s, d, 0, fifo=true) }.flatten,
routingRelation = UnidirectionalTorus1DDatelineRouting()
)))
class TestConfig15 extends NoCTesterConfig(NoCTesterParams(
Expand Down Expand Up @@ -216,7 +216,7 @@ class TestConfig20 extends NoCTesterConfig(NoCTesterParams(
flows = Seq.tabulate(10, 10) { (s, d) => FlowParams(s, d, 0) }.flatten,
routingRelation = BidirectionalTorus1DRandomRouting()
),
inputFlitStallProbability = 0.9
inputPacketStallProbability = 0.90
))
class TestConfig21 extends NoCTesterConfig(NoCTesterParams(
NoCParams(
Expand Down Expand Up @@ -330,7 +330,7 @@ class TestConfig31 extends NoCTesterConfig(NoCTesterParams(NoCParams(
channelParamGen = (a, b) => UserChannelParams(Seq.fill(4) { UserVirtualChannelParams(5) }),
ingresses = (0 until 18).map { i => UserIngressParams(i) },
egresses = (0 until 18).map { i => UserEgressParams(i) },
flows = Seq.tabulate(18, 18) { (s, d) => FlowParams(s, d, 0) }.flatten,
flows = Seq.tabulate(18, 18) { (s, d) => FlowParams(s, d, 0, fifo=true) }.flatten,
routingRelation = Mesh2DDimensionOrderedRouting()
)))
class TestConfig32 extends NoCTesterConfig(NoCTesterParams(NoCParams(
Expand Down Expand Up @@ -619,7 +619,7 @@ class TestConfig61 extends NoCTesterConfig(NoCTesterParams(NoCParams(
channelParamGen = (a, b) => UserChannelParams(Seq.fill(4) { UserVirtualChannelParams(5) }),
ingresses = (0 until 25).map { i => UserIngressParams(i) },
egresses = (0 until 25).map { i => UserEgressParams(i) },
flows = Seq.tabulate(25, 25) { (s, d) => FlowParams(s, d, 0) }.flatten,
flows = Seq.tabulate(25, 25) { (s, d) => FlowParams(s, d, 0, fifo=true) }.flatten,
routingRelation = TerminalRouterRouting(Mesh2DDimensionOrderedRouting())
)))
class TestConfig62 extends NoCTesterConfig(NoCTesterParams(NoCParams(
Expand Down
27 changes: 24 additions & 3 deletions src/main/scala/test/TestHarness.scala
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ case object NoCTesterKey extends Field[NoCTesterParams](NoCTesterParams())

class Payload extends Bundle {
val tsc = UInt(32.W)
val rob_idx = UInt(16.W)
val rob_idx = UInt(8.W)
val flow_idx = UInt(8.W)
val flits_fired = UInt(16.W)
}

Expand All @@ -71,21 +72,25 @@ class InputGen(idx: Int, cParams: IngressChannelParams)
val flits_left = RegInit(0.U(flitIdBits.W))
val flits_fired = RegInit(0.U(flitIdBits.W))
val egress = Reg(UInt(log2Ceil(nEgresses).W))
val flow = Reg(UInt(log2Ceil(cParams.possibleFlows.size).W))
val payload = Reg(new Payload)

val can_fire = (flits_left === 0.U) && io.rob_ready

val packet_remaining = if (p(NoCTesterKey).constPacketSize) maxFlits.U else (LFSR(20) % maxFlits.U)
val random_flit_delay = (LFSR(20) < (inputFlitStallProbability * (1 << 20)).toInt.U)
val random_packet_delay = (LFSR(20) < (inputPacketStallProbability * (1 << 20)).toInt.U)
val flow_idx = LFSR(20) % cParams.possibleFlows.size.U
val flow_ctrs = RegInit(VecInit.fill(cParams.possibleFlows.size) { 0.U(8.W) })
io.out.valid := !random_packet_delay && flits_left === 0.U && io.rob_ready
io.out.bits.head := true.B
io.out.bits.tail := packet_remaining === 0.U
io.out.bits.egress_id := VecInit(cParams.possibleFlows.toSeq.map(_.egressId.U))(LFSR(20) % cParams.possibleFlows.size.U)
io.out.bits.egress_id := VecInit(cParams.possibleFlows.toSeq.map(_.egressId.U))(flow_idx)
val out_payload = Wire(new Payload)
io.out.bits.payload := out_payload.asUInt
out_payload.tsc := io.tsc
out_payload.rob_idx := io.rob_idx
out_payload.flow_idx := flow_ctrs(flow_idx)
out_payload.flits_fired := 0.U

io.n_flits := packet_remaining + 1.U
Expand All @@ -95,6 +100,7 @@ class InputGen(idx: Int, cParams: IngressChannelParams)
flits_left := packet_remaining
payload := out_payload
egress := io.out.bits.egress_id
flow := flow_idx
flits_fired := 1.U
}
when (flits_left =/= 0.U) {
Expand All @@ -110,7 +116,10 @@ class InputGen(idx: Int, cParams: IngressChannelParams)
flits_left := flits_left - 1.U
}
}

when (io.out.fire && io.out.bits.tail) {
val idx = Mux(io.out.bits.head, flow_idx, flow)
flow_ctrs(idx) := flow_ctrs(idx) + 1.U
}
}

class NoCTester(inputParams: Seq[IngressChannelParams], outputParams: Seq[EgressChannelParams])(implicit val p: Parameters) extends Module with HasNoCParams {
Expand Down Expand Up @@ -196,14 +205,26 @@ class NoCTester(inputParams: Seq[IngressChannelParams], outputParams: Seq[Egress
val packet_valid = RegInit(false.B)
val packet_rob_idx = Reg(UInt(log2Ceil(robSz).W))

val flow_ctrs = RegInit(VecInit.fill(outputParams(i).possibleFlows.size) { 0.U(8.W) })
when (o.flit.fire()) {
val flows = outputParams(i).possibleFlows.toSeq
val fifo = flows.filter(_.fifo).map(_.ingressId.U === o.flit.bits.ingress_id).orR
val flow_id = flows.zipWithIndex.map { case (f, fid) =>
Mux(f.ingressId.U === o.flit.bits.ingress_id, fid.U, 0.U)
}.reduce(_|_)

assert(rob_valids(rob_idx), cf"out[${i.toString}] unexpected response")
assert(rob_payload(rob_idx).asUInt === o.flit.bits.payload.asUInt, cf"out[${i.toString}] incorrect payload");
assert(o.flit.bits.ingress_id === rob_ingress_id(rob_idx), cf"out[${i.toString}] incorrect source")
assert(i.U === rob_egress_id(rob_idx), cf"out[${i.toString}] incorrect destination")
assert(rob_flits_returned(rob_idx) < rob_n_flits(rob_idx), cf"out[${i.toString}] too many flits returned")
assert((!packet_valid && o.flit.bits.head) || rob_idx === packet_rob_idx)
when (fifo && o.flit.bits.tail) {
assert(flow_ctrs(flow_id) === o.flit.bits.payload.asTypeOf(new Payload).flow_idx,
cf"out[${i.toString}] not fifo")
flow_ctrs(flow_id) := flow_ctrs(flow_id) + 1.U
}


when (o.flit.bits.head && enable_print_latency) {
val fmtStr = s"%d, $i, %d\n"
Expand Down

0 comments on commit cde8503

Please sign in to comment.