hl2: decode the TX FIFO status word as the gateware sends it - #5398
Open
on8st wants to merge 2 commits into
Open
hl2: decode the TX FIFO status word as the gateware sends it#5398on8st wants to merge 2 commits into
on8st wants to merge 2 commits into
Conversation
…oday
MetisProtocol.cpp's own comment above txFifoCount asks for this check:
"The gateware RTL is the authority and this has NOT been checked against
it. Do not build FIFO-servoed TX pacing on this field until it has been."
Checked, against Hermes-Lite2 gateware 883a338. The decode is wrong.
control.v:472 puts the whole FIFO field in DATA[15:8] — dsiq_status,
eight bits — with DATA[23:16] a constant zero. fifos.v:100-110 composes
it as {recovery_flag, rd_count[6:0]} where rd_count is the TOP 7 bits of
the read-side fill level, and the recovery flag covers BOTH "ran empty"
and "writes blocked because it filled" (fifos.v:55-61). There is no
15-bit count in this word and no under/overflow distinction anywhere in
the gateware.
Four checks fail:
- dsiq_status 0x80 reports a depth of 128 for an empty FIFO, because
bit 7 is read as part of a count.
- dsiq_status 0xC0 reports 192 for a fill level of 0x40.
- the same recovery flag is diagnosed as "underflow" at 0x80 and
"overflow" at 0xC0 — two opposite verdicts on one event, chosen by a
fill-level bit.
The 0x40 and 0x7F cases pass, which is why this survived: DATA[23:16] is
zero, so the old expression happens to return dsiq_status itself. It read
the right number under a name claiming it was something else.
Not asserted, because not established: what one unit of the fill field is
worth in samples or milliseconds. aethersdr#17's servo needs that; this decode
does not.
Fix follows in the next commit.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017SvGM4eqSng7aX62aVCFyh
Makes the previous commit's test pass. The word is dsiq_status,
DATA[15:8] of RADDR 0, and it carries two things, neither of which the
old decode named correctly:
txFifoFillMsbs <- [6:0] top 7 bits of the read-side fill level, 0-127
txFifoRecovery <- [7] one flag for BOTH underrun and blocked writes
replacing txFifoCount (a 15-bit sample count that does not exist on the
wire), txFifoUnderflow and txFifoOverflow (a distinction the gateware
does not make).
Evidence, at 883a338: control.v:472 places dsiq_status at DATA[15:8]
with DATA[23:16] a constant zero; fifos.v:100-110 composes it as
{recovery_flag_d1, rd_count[6:0]} where rd_count is
rd_tlength[(rdbits-1):(rdbits-7)] and recovery_flag is set by
rd_tvalidn OR ~allow_push (fifos.v:55-61, 105-106).
Why it survived: DATA[23:16] being zero made (data >> 8) & 0x7FFF equal
dsiq_status, so the displayed number was the right byte under a wrong
name. Nothing ever looked absurd enough to prompt the read that
MetisProtocol.cpp's own comment had been asking for.
What the operator saw: a recovery event added 128 to a figure labelled
"TX FIFO depth", and the same event was reported as "underflow" or
"overflow" according to fill-level bit 6 — opposite diagnoses of one
fault. The diagnostics rows are now one level (0-127, labelled coarse)
and one "TX pacing fault (under OR overrun)".
Still not established, so still not servo-safe: what one unit of the
fill field is worth in samples. rdbits is 12 for this board's
DSIQ_FIFO_DEPTH of 16384 (hermeslite_core.v:136), making the unit 32
read-side words, but words-to-samples is an inference. aethersdr#17 must measure
it before pacing on this field.
Verified: hl2_metis_protocol_test passes (10 new checks, 4 of which
failed before this commit); Hl2Backend.cpp and hl2_live_band_filter_probe
.cpp syntax-check clean against Qt 6.8.3. No full build run.
Row B-18.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017SvGM4eqSng7aX62aVCFyh
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.
Hl2Telemetry::apply()decodes RADDR 0'sDATA[22:8]as a 15-bit TX FIFOsample count, and
DATA[15:14]as an under/overflow code. Neither field existson the wire. The comment above that code says so itself, and asks for the check
this PR carries out:
Checked, against Hermes-Lite 2 gateware at
883a338— theSHA in the discovery string
20231230_74p2_883a338, gateware 74.2, the currentstable. Board variant
hl2b5up_main. The oracle is wrong about both fields, andso is the code.
What the gateware actually sends
gateware/rtl/control.v:472builds the RADDR 0 response:Eight bits of C0 then 32 of data, so:
DATA[31:26]6'b000111DATA[25]~ext_txinhibitDATA[24](&clip_cnt)— the ADC-overload bitDATA[23:16]8'h00DATA[15:8]dsiq_status— the entire FIFO field, eight bitsDATA[7:0]VERSION_MAJORdsiq_statusis composed ingateware/rtl/fifos.v:100-110:Two consequences:
[6:0]is the top 7 bits of the read-side fill level — a coarseoccupancy, 0–127. There is no sample count anywhere in this word.
[7]is one flag for two faults.rd_tvalidnis the FIFO having runempty;
~allow_pushis writes being dropped after it filled(
fifos.v:55-61). The gateware never distinguishes them, so an under/overflowcode cannot be decoded from this word by anyone.
Why the existing decode looked fine
DATA[23:16]is a constant zero, so(data >> 8) & 0x7FFFreturnsdsiq_statusitself. The displayed number was the right byte carrying a wrongname — it never took an absurd value, so nothing ever prompted the read.
What an operator actually saw:
"TX FIFO depth" jumped by 128 on an empty FIFO.
clear and "overflow" when it was set — two opposite diagnoses of one event,
selected by how full the buffer happened to be.
The change
The diagnostics pane goes from three rows to two:
TX FIFO fill (0-127, coarse)and
TX pacing fault (under OR overrun). The label carries the ambiguity thewire has, rather than resolving it in the reader's favour — a consumer that
wants to know which fault occurred cannot get it from this word and should not
be encouraged to guess.
What this PR deliberately does not do
It does not convert the fill level into samples or milliseconds.
rdbitsis 12for this board's
DSIQ_FIFO_DEPTHof 16384 (hermeslite_core.v:136, notoverridden by
variants/hl2b5up_main/hermeslite.v), which makes one unit 32read-side FIFO words — but the words-to-samples mapping is an inference from the
FIFO's port widths, not something read out of the RTL. The original comment's
warning stands until that is measured: do not servo TX pacing on this field
yet. This PR makes the field honest; it does not make it sufficient.
Tests
tests/hl2_metis_protocol_test.cppgains ten checks over hand-builtdsiq_statuswords. Four of them fail onmainbefore the fix:The
0x40and0x7Fcases pass both before and after — kept deliberately,because they are the reason this survived: they are exactly the values where the
old expression's accident holds. An all-ones
DATAcase pins the field width soa future widening cannot silently pick up the ADC-overload and TX-inhibit bits
sitting just above the constant zero byte.
Scope
Gateware read at
883a338and the AetherSDR source. Nothing here ismeasured — no radio was keyed to produce a recovery event, and this PR makes
no claim about how often one occurs or what causes it. It is a decode
correction, and the test is a decode test.
Notes for the orchestrator, not for the PR body
Sizes as XS. Touches
MetisProtocol.h,MetisProtocol.cpp, four lines ofHl2Backend.cpp(a diagnosticsput()block and oneqCDebug), one line ofhl2_live_band_filter_probe.cpp, and the test.Hl2Backend.cppoverlap check: both edits are inpublishTelemetryandthe diagnostics table, not in the drive path
tx-dynamicsholds onfix/hl2-initial-drive. Worth a rebase check before either goes up.Verified on the PR branch itself, not only on the feature branch it came
from — red at
ebf6c66, green at505f575, same four failures:The standalone build is the right citation here: the target is two
translation units with no Qt and no
aethercore, which is why it is fastenough to run at both commits.
Also verified in a full build, on
feat/hl2-telemetrywhere these twocommits are the base:
cmake --buildexit 0 over 2952 objects, andctest -R hl222/23 withhl2_metis_protocol_testpassing in the realtree. The single failure is
hl2_state_restore_test's three pre-existingCW-passband-guard assertions (hl2_state_restore_test: three CW-passband assertions fail on main (10a847b) #5394), which fail identically on unmodified
upstream
main. That build usedENABLE_ASR=OFF, the standard on thismachine, and
CMAKE_IGNORE_PREFIX_PATH=/opt/homebrew;/opt/local.The full build has not been re-run on
fix/tx-fifo-status-decodeitself;it carries the same two commits against the same base, and the standalone
test was run there directly. Say so rather than implying otherwise if asked.
gh api user --jq .loginmust readon8stbefore any push, ever.🤖 Generated with Claude Code
https://claude.ai/code/session_01FtHEsQsghFwhUQEZdwVKUz