Initial Galileo receiver and SignalSim integration

This commit is contained in:
2026-07-30 23:26:03 +03:00
commit 2a6ccfc23d
153 changed files with 8080 additions and 0 deletions
+104
View File
@@ -0,0 +1,104 @@
# RTL mapping and architecture tradeoffs
All streaming datapaths use `data`, `valid`, `ready`, optional `first/last`,
`channel_id`, and sideband metadata. State advances only on `valid && ready`.
Backpressure must propagate or terminate in a sized sample FIFO. Reset clears
valid/state/overflow counters and sets NCO phases to software-programmed start
values; it must not occur between arbitrary host blocks.
## Acquisition formulas
Let \(N_s=\operatorname{round}(f_sT_c)\), FFT size \(N\ge N_s\), PRNs \(P\),
Doppler bins \(D\), noncoherent intervals \(M\), Doppler lanes \(L\), FFT
latency/interval \(C_{FFT}\), and clock \(f_{clk}\).
- observation buffer: \(MN_s\) complex samples;
- transforms per PRN: \(2DM\) when code FFTs are precomputed;
- code FFT store: \(PN\) complex words (or \(N\) for on-demand PRN loading);
- pointwise complex multiplications: \(PDMN\);
- approximate single-engine search cycles:
\(P\lceil D/L\rceil M(2C_{FFT}+N)\);
- acquisition time is those cycles divided by \(f_{clk}\), plus fill and control
overhead.
### A — buffered FFT PCPS
One coherent block is buffered. A mixer iterates Doppler bins, a forward FFT is
multiplied by conjugated code FFT memory, the same or a second engine performs
IFFT, magnitude squared accumulates in Doppler/code RAM, and peak search scans
the result. It minimizes mixers/FFT engines/DSPs and maximizes search latency.
Ping-pong buffers hide capture behind search. One FFT engine needs arbitration
and doubles transform serialization; two remove that conflict at extra DSP/BRAM.
### B — parallel Doppler lanes
`NUM_DOPPLER_LANES=L` replicates carrier mixers and either feeds batched FFTs or
replicates FFT engines. With one reused FFT, lanes improve mixing but not the FFT
bottleneck. With L FFT/IFFT paths, ideal Doppler latency approaches 1/L while
DSP, twiddle ROM, transpose memory, and noncoherent RAM ports grow roughly with
L. Intermediate choices use L mixers, a smaller number of FFT engines, and
FIFOs. Resource budgets and required reacquisition time select L; neither
architecture is universally preferred.
## Tracking
Fully parallel mode instantiates carrier/code NCOs and VE/E/P/L/VL complex
MACs per channel. It provides one-sample-per-clock latency independence and
uses the most DSPs and accumulators.
Time-multiplexed mode stores phase words, FCWs, five complex accumulators, loop
states, counters, and secondary phase per channel in `channel_state_ram`.
`NUM_CORRELATOR_LANES` engines visit all active channels for every input sample.
The no-loss condition is
\[
\left\lceil\frac{NUM\_TRACKING\_CHANNELS}{NUM\_CORRELATOR\_LANES}\right\rceil
C_{channel}\le f_{clk}/f_s.
\]
If it fails, more lanes, a faster clock, a lower post-decimation sample rate, or
fewer active channels are required. A sample FIFO cannot repair a sustained
rate violation.
Parameters are `NUM_TRACKING_CHANNELS`, `NUM_CORRELATOR_LANES`, `SAMPLE_WIDTH`,
`NCO_PHASE_WIDTH`, `CODE_PHASE_WIDTH`, `ACCUMULATOR_WIDTH`, and
`MAX_INTEGRATION_SAMPLES`. The Python `TrackingScheduler` evaluates this exact
condition.
The detailed per-module signal, width, latency, storage, reset, saturation, and
verification contract is in `src/galileo_rx/rtl_model/architecture.md`.
## SignalSim gate before Acquisition IP / Tracking IP implementation
The validated external stimulus is complex IQ8 at 8.184 MHz with +2.046 MHz
IF. `validate-signalsim` exports the 20 ms acquisition observation as separate
two's-complement I/Q hex files, a per-sample timestamp CSV, and symbolic
register values under `reports/signalsim_validation/rtl_vectors/`.
The fixed acquisition boundary model agrees with the float64/complex128
reference on Doppler bin, code-phase sample, and acquisition decision with zero
overflow. Its normalized correlation-map RMS error is 0.00219 and peak error is
0.01996 for the proposed comparison formats. This is an input/FFT/product/power
boundary result; it does not yet include a selected vendor FFT butterfly shift
schedule.
Measured requirements feeding the RTL plan are:
- complex IQ input and `IQ` ordering must be a first-class sample-input mode;
- code ROM import must discard one padding bit per 1024-bit SignalSim E1 table
sector—no unexplained chip offset is permitted;
- acquisition-to-tracking handoff carries IF center separately from Doppler so
code aiding never uses the IF frequency;
- E1B pull-in supports 2 ms dumps and data-insensitive FLL, followed by paired
4 ms raw-symbol outputs;
- E1C channel state includes secondary phase (measured phase 10 for this
vector) and supports wipeoff before PLL/discriminator processing;
- tracking measurement/APB visibility includes prompt I/Q, carrier/code NCOs,
state, lock metrics, secondary phase, and symbol-valid/data;
- APB addresses are still unassigned. The exported metadata uses symbolic
names and therefore blocks a bus-level RTL run until the register map exists.
Native real-IF SignalSim stimulus is unavailable, so the real-input DDC path
remains covered only by internal Python vectors. Full CBOC, IQ2, full I/NAV
decoding, nominal/weak C/N0, signed-Doppler, and multi-PRN external regressions
remain gates before claiming broad Galileo/RTL compatibility.