Repository navigation
hw: Add priority-aware WRRA - #364
Draft
gbellocchi wants to merge 29 commits into
Draft
gbellocchi wants to merge 29 commits into
gbellocchi wants to merge 29 commits into
Conversation
Add a generic N-input weighted round-robin arbiter that distributes output bandwidth proportionally to a per-input weight (w_i / sum_j w_j) by granting each winner a quantum of up to w_i consecutive beats before the round-robin pointer advances. Built on cc_rr_arb_tree (FairArb + LockIn) for winner selection, with a contender snapshot and a quantum counter on top. Testbenches: - cc_wrr_arbiter_tb: flat N-input throughput check vs the w_i/sum(w_j) ideal. - cc_wrr_arbiter_cascade_tb: mixed-radix cascade reproducing and curing NoC topological unfairness (Dally & Towles) - unit weights give the unfair 1/12, 1/4, 1/2 split; source-count weights restore 1/5 fairness. Add test/simulate-wrra.sh and wire the new files into Bender.yml.
- doc/cc_wrr_arbiter.md: design write-up covering the topological-unfairness motivation, the burst weighted-round-robin mechanism, design decisions and trade-offs, and the evaluation results (flat throughput + before/after cascade). - test/waves/cc_wrr_arbiter_tb.wave.do and cc_wrr_arbiter_cascade_tb.wave.do: QuestaSim wave setups exposing the TB signals and the quantum-counter internals.
- src/cc_qos_wrr_arbiter.sv: QoS-priority + aging + weighted round-robin. QoS selects the served tier (with per-grant aging to prevent starvation); within the tier, bandwidth is split by weight via cc_wrr_arbiter. - test/cc_qos_wrr_arbiter_tb.sv: checks QoS priority, in-tier weighted split, and anti-starvation. - test/cc_arbiter_compare_tb.sv: head-to-head RRA vs WRRA vs QoS+WRRA on identical traffic, reporting throughput share and urgent-flow request->grant latency; swept over the number of competing flows in simulate-wrra.sh. - cc_wrr_arbiter: a weight of 0 now excludes an input from arbitration entirely (never granted) instead of being clamped to 1; renamed the accepted-transfer signal to flit_transfered. Added a weight-0 case to cc_wrr_arbiter_tb.
cc_wrr_arbiter: abandon the current burst if the locked winner stops requesting (winner_gone) instead of stalling on it forever. When wrapped by a dynamic eligibility mask (cc_qos_wrr_arbiter), a higher-QoS arrival demotes the current winner out of the eligible set mid-burst; previously the inner arbiter stayed locked on that now-ineligible winner and deadlocked, starving the high-QoS flow. A plain downstream stall (winner still requesting) still only pauses, so under saturated traffic winner_gone never fires and behaviour is unchanged. Also add test/cc_qos_wrr_cascade_tb.sv: a 3-hop cascade with per-flit QoS that measures the farthest flow's end-to-end latency with vs without priority, and guard the comparison TB's latency print against divide-by-zero.
Assert gnt_o[winner] only when req_o is high (the winning flit actually leaves), not merely on gnt_i. When an upstream mask (cc_qos_wrr_arbiter) demotes the winner mid-burst, req_o drops; without this gate the winner got a spurious grant for a flit that never left - dropping data and skewing throughput accounting. Under saturated traffic req_o is always high, so behaviour is unchanged. Also comment out the already-verified baseline WRRA runs in simulate-wrra.sh to keep the QoS evaluation log short.
- doc/cc_wrr_arbiter.md: add the QoS+WRR arbiter design, the full evaluation (two-tier weighting, RRA/WRRA/QoS+WRRA latency sweep, cascade end-to-end latency), the intra-tier-fairness-under-periodic-preemption limitation, and an engineering-issues-found-and-fixed section. - test/waves/cc_arbiter_compare_tb.wave.do: GUI wave setup to inspect the QoS arbiter internals (served index, ages, eligible set, preemptions).
Testbenches now emit machine-readable "CSV,..." lines and gained sweep knobs: - cc_wrr_arbiter_tb: WeightMode (weight-pattern select) for the proportionality cloud. - cc_arbiter_compare_tb: CSV summary; finer NumInp sweep in simulate-wrra.sh. - cc_qos_wrr_arbiter_tb: SweepMode (relax fixed asserts) + CSV for the aging curve. simulate-wrra.sh runs the three sweeps and accumulates results.csv. doc/plots/plot_arbiters.py (matplotlib) turns results.csv + embedded single-config numbers into the report figures: latency-vs-congestion, topological before/after, weight proportionality (bars + swept cloud), QoS two-tier shares, aging-tuning curve. Core PNGs (fig1-4) committed; fig5/fig6 generated once results.csv is produced.
- cc_wrr_arbiter_tb weight sweep overflowed WtWidth (weight i+1 > 15 at NumInp=16 wrapped to 0); the failing assert aborted the whole sweep. Run that sweep with WtWidth=8 so weights fit. - simulate-wrra.sh: a non-zero-errors run now warns instead of aborting (set -e + grep), so one bad config no longer drops the rest of the sweep. - cc_arbiter_compare_tb: add GapJitter knob (randomize the urgent think-time). It breaks the periodic-stimulus resonance -> smooth latency-vs-congestion curves AND even bulk-throughput shares (the strobe artifact). The compare sweep enables it.
Regenerate all six figures from the full sweep results: - fig1: latency vs congestion (jittered -> smooth RRA/WRRA curves, QoS flat) - fig5: weight-proportionality cloud (3 patterns x 3 input counts, all on y=x) - fig6: aging-tuning curve (low-tier share down / max-wait up vs AgingInterval) Plot script dedups repeated AgingInterval points.
Add a weight-config box to the topological figure showing that fairness comes from the through-port weights (A1=3, A2=4 = #sources aggregated), not per-source weights (every source injects with local weight 1).
cc_qos_wrr_3tier_tb: 4 inputs at QoS 4/2/2/0, weights 1/3/1/1 (mid tier split 3:1), emits "CSV,qos3,..." per input. Wired into Bender + simulate-wrra.sh. plot_arbiters.py gains fig7 (three-tier shares), generated once the qos3 CSV rows are produced.
Real 3-tier run (QoS 4/2/2/0, weights 1/3/1/1): bandwidth is ordered by QoS tier, but in1(w3) == in2(w1) - the within-tier weights are NOT applied, because an input promoted into a higher tier by aging is served ~1 flit then demoted (its grant resets its age), cutting the weighted burst to one. Weights only apply in an input's native top tier. Figure annotated with this finding.
cc_qos_wrr_3tier_tb gains a Scenario param:
0 (default): QoS {4,2,2,0} w {1,3,1,1} - weighted pair in mid tier (weights nullified).
1: QoS {4,4,2,0} w {3,1,1,1} - weighted pair is native top tier (3:1 applies).
CSV lines tagged with scen=; simulate-wrra.sh runs both; plot_arbiters.py emits fig7
(scenario 0) and fig7b (scenario 1, weighted top tier).
Scenario-1 run (QoS 4/4/2/0, weights 3/1/1/1): the QoS4 pair in0(w3)/in1(w1) is the native top tier and splits 3:1 (0.680 / 0.227), with in2/in3 aging-rescued below. Pairs with fig7 (weighted pair in mid tier -> weights nullified by aging) to pin down exactly when within-tier weighting holds: native top tier yes, aged-up no.
- Inline all eight figures (fig1-7b) in their matching evaluation sections. - §6.2: reconcile the latency table with the jittered swept figure. - §6.4: note the GapJitter knob fixes both the jagged curves and the bulk strobe. - §6.5 (new): aging-knob tradeoff curve (fig6) with the halve/double rule. - §6.6 (new): three-QoS-tier finding - within-tier weights apply only in an input's native top tier, not when aged up (fig7 vs fig7b). - §8: list the new TBs, the plot script, and the figures.
Add cc_qos_wrr_cascade_share_tb: drives all 5 cascade sources saturated with a 3-high/2-low QoS layout (weighted pair r0:r1=3:1) and measures each source's end-to-end bandwidth share at the destination, so the QoS evaluation runs on the same 5-source structure as the topological-fairness study (fig2) and is directly comparable. Shows QoS priority surviving all 3 hops, the weighted split at the A0 merge, and aging keeping the low tier alive (fig8). Also anchor the N-sweeps at N=5 (same source count as the cascade): compare and wrrprop sweeps start at 5, fig1 marks N=5, and the fig1 animation uses N=5.
fig8: high tier r0-r2 = 93% of destination bandwidth despite being farthest; within-tier r0:r1:r2 = 3:1:1 (weight applied at the A0 merge); low tier r3,r4 kept alive by aging (~3-4%). §6.3.1 updated with the measured shares. Also refresh fig1/fig5/fig6 from the new sweep (compare and wrrprop anchored at N=5), and fix a warmup artifact in cc_qos_wrr_cascade_share_tb's maxwait (skip the first per-source grant gap; shares were always correct).
QoS-aware WRRA for fair service in NoC
gbellocchi
marked this pull request as draft
September 30, 2026 08:15
This was originally included to support the student during his initial familiarization with the round-robin arbiter.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This PR introduces two new
common_cellsIPs implementing Weighted Round-Robin Arbitration (WRRA) tailored for real-time, mixed-criticality platforms. These modules can be readily used into best-effort interconnects, such as FlooNoC and the AXI4 crossbar.Features
AgingInterval).Tasks