Repository navigation
Description
Part of the 5G-NR RAN EPIC #254. Phase A, first demoable capability.
Goal: one gNB-DU serves N UEs on a shared, TSF-locked fixed-grid slot grid — per-UE registry, a QoS scheduler that emits a grant map (DCI-style), collision-free scheduled DL (within the M0-measured guard), and scheduled UL with per-UE timing advance.
Restricted numerology (from the architecture review)
M1 deliberately uses a fixed grid — variable-length slots and mini-slots follow once M0 has measured real airtime/scheduling distributions:
- fixed superframe; fixed beacon/TBTT period in integer TU;
- one periodic uplink opportunity per UE;
- an explicit DL→UL turnaround guard;
- no channel or bandwidth switching inside M1.
5G mapping
- gNB-DU = the AP node; SSB = the hardware beacon; DCI/PDCCH = the grant map
{ue, dl_slot, ul_slot, rate, pwr, ta}(delivery mechanism decided in M0 — likely a slow static beacon grant + scheduled unicast deltas, since there is no atomic beacon-update API); timing advance = the per-UE UL phase loop (corrects clock/actuation phase, not propagation — indoor propagation is ns).
Deliverables (the reusable DU MAC library src/cell/)
-
UeRegistry— per-MACID state: assoc, timing advance, and a per-UE RX-quality window built from M0's per-frame attribution (NOT device-wideGetRxQuality). cell M1: per-UE state in the DU library (UeRegistry UeContext: TA loop, uplink-quality window) #570:UeContextper scheduled UE insrc/cell/UeRegistry.h(the TA loop, nowsrc/cell/TimingAdvance.h, and an uplink window of RSSI/SNR/EVM fromUeRxAttribution), with the binding's lifetime. -
GrantMap— DCI-style IE build/decode (headless round-trip selftest); delivery per the M0 decision. cell: M1 core — SlotGrid (slot-budget accounting, fixed grid) + GrantMap IE #516:src/cell/GrantMap.h, epoch + effective superframe, ctestcell_core. -
SlotGrid— fixed-grid slot phase math on the disciplined TSF (generalizeexamples/tdma/tdma.hSchedule/at()+ the TD tag). Full slot-budget accounting (PSDU + preamble + SIFS/ACK + retry + turnaround + guard), not payload size alone. cell: M1 core — SlotGrid (slot-budget accounting, fixed grid) + GrantMap IE #516:src/cell/SlotGrid.h. - scheduled DL loop — per-UE slot, per-packet rate/power via
RadiotapBuilder.h, respecting the M0-measured DL departure guard. examples/cell: M1 reference DU / UE / witness node + 2-UE on-air test #518 (+ per-UE rate in examples/cell: M2 — DL HARQ from UE feedback + per-UE link adaptation (rig: attenuated UE recovered) #521); hardware-ACKed DL, as Kestrel has no no-ACK path. - scheduled UL + per-UE TA — generalize the single-UE loop in
examples/timesync/main.cpp(master_ta_cb) to per-MACID; UE uplink = HW-beacon steered byPinBeaconTbtt. examples/cell: M1 reference DU / UE / witness node + 2-UE on-air test #518: on Kestrel the UE steers its TBTT through its TSF (the kestrel: multi-cell beacon sync on one PTP timebase — free-running-counter TSF discipline + on-air observer (#258) #513 actuator;PinBeaconTbttcannot hold an offset on TSF-locked parts); DU TA loop on the window median. -
CellScheduler— 5QI-style QoS classes producing the grant map. cell M1: QoS classes (CellScheduler) — 5QI sets each UE's HARQ budget, discard timer and link adaptation #569:src/cell/CellScheduler.h; on the fixed grid a class sets each UE's HARQ budget (at the configured HARQ round trip), a DL discard timer and link adaptation; admission ranking headless. Rig: testrigm1_qos.sh. -
examples/cell/— reference gNB-DU + UE node (generalizesexamples/timesync/+examples/tdma/). examples/cell: M1 reference DU / UE / witness node + 2-UE on-air test #518, docs/cell-m1.md; rig test as testrigscripts/m1_cell_2ue.sh(2 UEs 100 % in slot, ~1.5–2 µs UL error, 0 overlaps).
Reuses
PinBeaconTbtt, StartBeacon, ReadTsf, examples/tdma/tdma.h, examples/timesync/, RadiotapBuilder.h.
Risks (from EPIC)
send_packetUL has no sub-slot air-departure control → UL must ride the HW-beacon-steered path, not naivesend_packet.- Half-duplex UE turnaround bounds adjacent DL-RX / UL-TX mini-slot sizing.
- ~ms
FastRetune⇒ slots ≫ retune time if a slot ever changes channel.
Dependencies
M0 (#261) — the four feasibility contracts (DL guard, grant delivery, unicast-ACK matrix, per-UE attribution) gate this milestone's design.
Test — tests/cell_2ue.sh
2 USB stations under the Radxa 8821CE DU; each gets its DL+UL slot; each station's arrival-TSF-mod-period lands in-slot, zero collisions. Reuse timesync_ta_analyze.py for arrival-phase RMS. Plus a headless selftest: GrantMap round-trip + SlotGrid phase math, in the CMake selftests aggregate.
Activity
M0: measured feasibility contracts — DL guard, dynamic beacon grants,…
cell: M1 core — SlotGrid (slot-budget accounting, fixed grid) + Grant…
cell: M1 core — SlotGrid (slot-budget accounting, fixed grid) + Grant…
examples/cell: M1 reference DU / UE / witness node + 2-UE on-air test (…
cell M1: QoS classes (CellScheduler) — 5QI sets each UE's HARQ budget…
cell M1: per-UE state in the DU library (UeRegistry UeContext: TA loo…
josephnef commentedon Nov 13, 2026
Closing: every M1 deliverable is in.
UeRegistryper-UE state. AUeContextholds the TA loop and the uplink-quality window, attributed per transmitter.CellScheduler5QI classes. On the fixed grid a class sets the HARQ budget (at the configured round trip), a DL discard timer and link adaptation. Rig: testrigm1_qos.sh.GrantMap,SlotGrid, scheduled DL/UL with per-UE TA, andexamples/cell(cell: M1 core — SlotGrid (slot-budget accounting, fixed grid) + GrantMap IE #516/examples/cell: M1 reference DU / UE / witness node + 2-UE on-air test #518/examples/cell: M2 — DL HARQ from UE feedback + per-UE link adaptation (rig: attenuated UE recovered) #521).The tests live in testrig (
m1_cell_2ue.sh,m1_qos.sh), nottests/cell_2ue.sh. Not yet in the DU: priority preemption at admission (preempt_for, headless).