The thesis proposed the algorithm for hardware but never built it. This page is the missing half: SweepLSD running live on 2009-era silicon.
Live demo: 1080p30 HDMI video passes through the board while segments are detected and overlaid on-chip. (direct video link if the embed does not play.)
The C++ library was re-expressed twice, and both forms are held to the same acceptance gate as the software:
| form | what it is | status |
|---|---|---|
hls/ | the full detector as synthesizable HLS C++ (Vitis HLS), plus a tool-free g++ shim so the model runs as ordinary C++ | Artix-7 reports: front-end II=1 at 100 MHz; C-sim and C/RTL co-sim clean |
rtl/ | hand-written, portable Verilog RTL: streaming front-end → sparse event FIFO → labelling back-end → integer judge | runs on the Atlys; verified as below |
The contract is SW == HLS == RTL, bit-exact: golden-vector parity testbenches
(Icarus Verilog) hold the RTL to the HLS C model and the C++ detect() reference,
including 1920×1080 photographs — all 150 photographs of the project's Full-HD test corpus
match segment-for-segment in the hardware configuration. The refinements that fit the
streaming/integer model — strict NMS, half-pixel lattice, bounding-box endpoints, streaming
hysteresis, curve rejection — are all in the hardware (sub-pixel NMS stays software-only: it
does not fit the judge's 128-bit envelope).
What it costs. Both realizations, side by side. The HLS core proves the streaming schedule (front-end II=1, one pixel per clock) but, left to instantiate a moment multiplier per product, spends 79 DSP blocks and 95% of the small Artix-7's LUTs on the detector alone. The hand-written RTL folds every product onto one shared sequential multiplier, collapsing 79 DSP blocks to 14 — so the complete live system (detector + HDMI receive/transmit + overlay drawer) fits the 2009-era Spartan-6 well within budget, with every timing constraint met (74.8 MHz achieved against the 74.25 MHz pixel clock).
| HLS core (Artix-7 xc7a35t) | RTL system (Spartan-6 xc6slx45) | |
|---|---|---|
| clock | 100 MHz, II=1 | 74.25 MHz pixel |
| slice LUTs | 19,789 (95%) | 12,664 (46%) |
| slice registers | 14,684 (35%) | 8,813 (16%) |
| occupied slices | — | 4,109 (60%) |
| block RAM | 79 (79%) | 74 RAMB16 + 26 RAMB8 |
| DSP blocks | 79 (87%) | 14 (24%) |
| timing | met (slack 0.02 ns) | all met (74.8 MHz) |
The RTL column is the complete design that runs on the board; block RAM is counted as allocated primitives (the logical footprint is ≈140 KiB of 261 KiB, see footer). The single shared multiplier is what collapses the DSP count from 79 to 14.
The back-end labels events (edge pixels), so a maximally dense row can outrun it.
The event FIFO absorbs bursts and, when saturated, sheds data events rather than stalling
live video. After a sequence of measured drain optimizations (each bit-exact, each verified
by a ground-truth burst simulation at real 1080p30 timing), corpus-wide loss went from
~52 % of segments on the first live build to ≈0.2 %, concentrated in a
single pathologically dense frame; at a deeper FIFO the whole corpus is provably lossless in
simulation. The remaining step on this 2009 part is a BRAM-based FIFO to afford that depth.
Details and the measurement methodology: rtl/DESIGN.md, "Overflow reality
check".
The hardest bug of the bring-up never appeared in simulation: the live board lost all
detections below a per-image "cut row" on dense scenes, deterministically, with timing
closed at Score 0 and RTL simulation clean. Per-pass UART telemetry showed the board's
judge handshakes dying where simulation's did not — and a gate-level simulation of the
synthesized netlist reproduced the board exactly: XST's FSM re-encoding had
mis-synthesized the back-end's large FSM. One synthesis option (-fsm_extract NO)
restores RTL-identical netlist behaviour; every build script now sets it, with a warning.
rtl/DESIGN.md.The RTL parity suite runs with the open-source Icarus Verilog on the tracked synthetic
vectors: sh rtl/tb/run_tb.sh tb_sweep_core core/*.v (per-stage and full-chain
testbenches; Full-HD golden vectors are regenerated locally with
sweeplsd_dump_vectors since the photographs are not redistributed). The board
bitstream needs Xilinx ISE 14.7 and the XAPP495 HDMI PHY, fetched separately — build steps,
licensing notes, and the diagnostic LED/UART map are in
rtl/boards/atlys/README.md;
architecture and the verification story in
rtl/DESIGN.md.