rain: rewrite matrix mode text pixel pipeline - #947
Open
0xa000 wants to merge 1 commit into
Open
Conversation
The rotate+stretch shifter that expands font bytes into the 16-tick character cells has three defects, visible as rendering artifacts in matrix mode: 1. the 2x pixel-stretch phase free-runs across raster lines; with an odd toggle count per line it flips every scanline, displacing alternate scanlines of each glyph row by one pixel (jagged, zig-zag glyph edges); 2. 8 font pixels x 2 ticks never fit the 16-tick cell without a seam: depending on phase, either the last font pixel lingers for a third tick (glyphs grow an extra pixel on the right) or the first font column ghosts at the end of the cell; 3. display order is b0-first: every glyph is shifted one pixel right, with the rightmost font column wrapped around to the cell's left edge (visible on glyphs like 'm' and 'p' whose rows use bit 0). Replace the shifter with a strobe-aligned character reload (exact 16-tick cells) and an indexed, msb-first font-bit select. Verified in a differential RTL simulation harness (synthetic PAL raster, banner text injected through the monitor char handshake, rendered frames dumped as images): all 320 header character cells now match the font ROM pixel-exactly, with no mismatched scanline pairs and no odd-width strokes. Also verified on hardware (matrix mode on an openXC7 build of the core for an xc7a100t board).
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.
Authorship notice: investigation and patch developed with substantial AI assistance (Claude), reviewed and hardware-verified by me.
Symptom. In matrix mode, glyph rendering has visible defects: jagged (zig-zag) vertical edges on all glyphs, some glyphs one pixel wider than they should be (easy to see on
eandp), and every glyph shifted one pixel to the right with the rightmost font column wrapped around to the left edge of its character cell (visible onmandp, whose rows use font bit 0). We found this while porting the core to the open-source openXC7 toolchain, but the defects are pure RTL behaviour inrain.vhdl— deterministic given the raster geometry and independent of the toolchain used to build the core.Root cause. The rotate+stretch shifter that expands 8-bit font rows into the 16-tick character cells has three independent defects.
char_bit_stretch) free-runs across raster lines; because the character-reload branch preempts its toggle branch, the per-line toggle count is odd and the phase flips every scanline, displacing alternate scanlines of each glyph row by one pixel — the zig-zag.Fix. Replace the shifter entirely: reload the character on the strobe-aligned tick (exact 16-tick cells, reload takes the place of the decrement-to-zero branch) and select the font bit by indexing with the upper bits of the tick counter, msb-first.
Evidence. Verified in a differential RTL simulation harness built for this hunt: the
matrix_rain_compositor+termmem+lfsr16leaf driven with a synthetic PAL raster (pixel strobe every 3rd 81 MHz cycle, 864-strobe lines), banner text injected through the monitor char handshake, and the green channel dumped as PGM frames. The unmodified RTL reproduces all three defects (matching board photos); with the fix, an automated per-cell comparison of the rendered frame against the font ROM shows all 320 header character cells pixel-exact, zero mismatched scanline pairs, zero odd-width strokes. Also verified on hardware: matrix mode renders crisp, correctly-placed glyphs on an openXC7 build of the core for an xc7a100t board (QMTech Wukong port).Deliberately not included. The same investigation produced a CDC hardening for the monitor char handshake (2-FF synchroniser on
monitor_char_valid, registered ack). It is omitted here because on stock buildsuartclock(= cpuclock) andpixelclockcome from the same MMCM and sit in the sameset_clock_groupsgroup, so Vivado times the crossing and the raw handshake is safe by construction; the hardening only matters under toolchains that do not time inter-clock paths. It belongs with a future series enabling the core on such toolchains.