ITCH hardware at a glance
NASDAQ ITCH 5.0 parsed in FPGA fabric — live UDP/MoldUDP64 Ethernet ingress on a Nexys A7-100T, an 8-bit streaming parser, a dual-sided 512-slot BRAM order book, and best bid / best offer (BBO) in fixed clock cycles. LEDs and the 7-segment display close the loop on silicon.
First clean Vivado run (2026-08-02, USE_ETH=1, Vivado 2025.2):
timing met at 100 MHz (WNS +1.552 ns, WHS +0.033 ns), ~2% LUT,
sim latency 3 cycles to record_valid and 6 cycles to bbo_valid
on the Add path.
About this manual
This is the detailed engineering reference for the project.
It is the companion to the concise, GitHub-facing README.md:
-
README.md— project identity, status, and quick start. -
docs/(this manual) — architecture, message formats, interfaces, verification, implementation, and measured behaviour. -
docs/*.md— normative companions (architecture.md,metrics.md,board_eth_setup.md), linked not duplicated. -
log/— dated lab journal (2026-08-02synthesis/bitstream, Ethernet cable bring-up), summarized in Lab Journal.
Conventions used throughout:
-
monospacemarks signals, file paths, commands, and literals. -
File paths are repository-relative, e.g.
rtl/book/order_book.sv. -
Unmeasured values are written as
TBD (unmeasured)— never silently estimated. -
Numbers in Performance and Implementation are post-route Vivado results and cocotb measurements from the 2026-08-02 build.
| Start with Introduction for scope and reading order, then Architecture for the system overview. |
1. Introduction
This chapter defines what the system is, what this manual covers, and how to navigate the rest of the document.
1.1. Purpose
NASDAQ’s ITCH feed is a binary stream of Add, Execute, and Cancel messages describing how the open book changes in real time. Exchanges do not wait for a software stack.
This project implements the hardware column: bytes arrive over Ethernet (UDP, Mold-wrapped ITCH) into a Nexys A7-100T, a streaming parser turns them into structured order events, a dual-sided on-chip order book updates and recomputes best bid / best offer (BBO), and LEDs plus the 7-segment display show the answer on silicon.
This manual is the engineering reference for that system. It records design intent, message formats, interfaces, verification strategy, Vivado implementation detail, and measured behaviour in one numbered document.
The fastest way to see what the system is: the bench photo and links
at the top of this manual, plus media/a7_fpga.jpeg in the tree.
1.2. Why this exists
In conversations with business friends — especially Wharton students — NASDAQ comes up a lot. The argument starts with the open book: visible bids and asks. The goal is to make the fastest, best decision to buy at the lowest price or sell at the highest.
From a computer engineering perspective, a conventional Von Neumann CPU is a poor fit for that rapid decision-making — fetch, decode, move data through memory, repeat (the Von Neumann bottleneck). To skip the OS and avoid unnecessary data movement, the decision belongs in a hardened logic block that tells the CPU what it did: accurate, deterministic, and fast.
FPGAs sit in the middle: reconfigurability while iterating, hardened logic on paths that must be fast and deterministic. Flash a new bitstream, test, repeat — no fab run. That is what this repo explores: feed an FPGA market data over Ethernet, watch real decision-making happen in hardware, and move toward seeing trades happen one step at a time.
1.3. Scope
The manual covers:
-
system architecture and build order (see Architecture)
-
ITCH message subset and book/BBO design (see Design)
-
board, network, and tool interfaces (see Interfaces)
-
bring-up and operation model (see Operation)
-
correctness strategy with cocotb golden model (see Verification)
-
Vivado synthesis/implementation/bitstream (see Implementation)
-
measured timing, utilization, and latency (see Performance)
-
honest limits (see Known Limitations)
-
dated lab journal (see Lab Journal)
It does not replace:
-
README.md— quick start and repository map -
docs/architecture.md— data path, order book, BBO timing -
docs/board_eth_setup.md— cable, LEDs, bench setup -
docs/metrics.md— timing, utilization, latency numbers -
log/— full design notes and lab journal text -
RTL comments — per-module implementation notes in
rtl/
1.4. How to read this manual
Read chapters in order the first time. Chapters 1–2 give context; chapters 3–5 give the working model; chapters 6–8 give the evidence the hardware behaves as claimed.
Each chapter is self-contained enough to be entered directly from the sidebar once the overview in Architecture is familiar.
1.5. Conventions
-
Internal references look like this: Verification.
-
External links look like this: author site.
-
Inline code uses monospace, e.g.
record_valid,order_book.sv,USE_ETH=1. -
File paths are repository-relative, e.g.
rtl/top/nexys_a7_100t_top.sv.
-
Unordered lists state properties or inventories.
-
Ordered lists state procedures where sequence matters:
-
Program the
USE_ETH=1bitstream. -
Confirm link on LED15.
-
Send Mold/ITCH UDP traffic and watch LED0/LED1.
-
Honest status is a project rule.
Roadmap items stay labelled roadmap; unverified claims stay out of
this manual. Where a number has not been measured it is written
TBD (unmeasured).
|
| The sidebar on the left is collapsible. Select a chapter title to navigate; select its arrow control to expand or collapse its subsections without leaving the page. On narrow screens the sidebar stacks above the content. |
2. Architecture
System overview: what the pieces are, how bytes flow from the cable to the display, and where each piece lives in the tree.
2.1. System overview
All boxes run on one FPGA — no host in the hot path.
Ethernet / UDP -> Parse ITCH -> BBO + LEDs
Mold-wrapped bytes Order book 7-segment
Best bid / offer
The three stages are deliberately asymmetric: ingress is line-driven and lossy-tolerant (lab UDP), parsing is cycle-exact, and the book is stateful with a bounded rescan fallback (see Design).
2.2. Hierarchy
Top: rtl/top/nexys_a7_100t_top.sv · USE_ETH=1 · UDP port 50000.
eth_ingress -> moldudp64_rx -> itch_hw_core -> seven_segment_ctrl
(RMII + UDP) (Mold) (parse + book) (best bid)
| Block | Module | Notes |
|---|---|---|
Ingress |
|
RMII @ 50 MHz → CDC ( |
PHY link |
|
MDIO poll → LED15; |
Unwrap |
|
Mold length-prefix → raw ITCH bytes |
Core |
|
|
Display |
|
Best bid price on 8-digit hex 7-seg, 1 kHz digit scan |
Types |
|
|
Cocotb tests stop at itch_hw_core — no PHY in sim
(see Verification).
2.3. Clocks and reset
-
100 MHz system (
CLK100MHZ,sys_clk_pin, 10 ns) — core, book, display. -
50 MHz
eth_refclk(20 ns) — RMII nibble capture. -
Async groups in
constraints/nexys_a7_100t.xdc:set_clock_groups -asynchronousbetweensys_clk_pinandeth_refclk. -
Reset: center button
rst→ 2-stagerst_pipe→rst_syncat 100 MHz. -
USE_ETH=0tiesbyte_in/byte_validto zero for core-only builds; default bitstream isUSE_ETH=1.
2.4. Further reading
-
docs/architecture.md— data path, order book, BBO timing -
docs/board_eth_setup.md— bench wiring and LEDs -
Design — byte formats behind each box in the figure
3. Design
Message formats, parser, order book, and BBO update. This is the conceptual companion to the Vivado detail in Implementation.
3.1. ITCH subset
NASDAQ ITCH 5.0, big-endian on the wire. Only three messages are implemented (single symbol, lab scope):
| Type | Length | Meaning |
|---|---|---|
|
36 B |
Add order: side, shares, stock, price |
|
31 B |
Execute: order_ref + executed shares + match number |
|
23 B |
Cancel: order_ref + canceled shares (0 = full) |
msg_len_bytes() and msg_from_char() map the leading type byte
to length and enum (MsgAdd/MsgExec/MsgCancel/MsgNone).
itch_record_t carries msg, 48-bit timestamp_ns, 64-bit
order_ref and stock, side (B=buy/S=sell), 32-bit price,
shares, and aux_shares (exec/cancel quantity).
MoldUDP64 framing (rtl/mold/moldudp64_rx.sv): each ITCH message is
preceded by a 16-bit big-endian length. StHdr collects the 2-byte
prefix, StMsg streams exactly that many bytes to the parser.
udp_payload_ready = itch_byte_ready && (state != StSkip).
3.2. Parser
rtl/itch/itch_byte_fsm.sv — streaming 8-bit FSM:
StIdle -> StCollect -> StDecode -> StIdle
type/len 36 B buffer assemble itch_record_t
-
StIdle:msg_len_bytes(byte_in); unknown type →parse_error. -
StCollect: pack bytes into 36-bytemsg_buf(avoids unpacked-array tool quirks);byte_ready = (state != StDecode). -
StDecode: big-endian field extraction (timestamp bytes 5–10, order_ref 11–18, side byte 19, shares/price windows per type);record_validpulses 1 cycle after assembly — ≤3 cycles after the last byte. -
Timestamps pass through; matching/exchange sequencing is out of scope.
rtl/itch/itch_pipeline.sv wires the FSM as the itch_hw_core front
end. (rtl/itch/itch_parser.sv, rtl/book/bbo_update.sv, and
rtl/book/lut3_price_cmp.sv are reserved/alternate helpers; the
synthesized book path is order_book.sv below.)
3.3. Order book and BBO
rtl/book/order_book.sv — dual 512-slot BRAM, keyed by
order_ref[8:0]:
-
Slot word:
{valid, price[31:0], shares[31:0]}(65 b),(* ram_style = "block" *) bid_mem/ask_mem. -
One registered-read + synchronous-write process per array (BRAM-friendly). Read address
raddrstages the target slot one cycle beforeapply_d. -
Add: write slot, incremental BBO compare (buy:
price > best_bid; sell:price < best_ask),bbo_validimmediately — 6 cycles fromrecord_validin sim. -
Execute/Cancel: decrement or invalidate; if the touched price equaled the current best, start a sequential rescan (≤512 cycles); otherwise
bbo_validimmediately. Unknown slot or message →book_error. -
Price compare intent is LUT-friendly (
lut3_price_cmp.sv, Tomato-style truth tables); the committed path uses direct compares.
Scan engine: scan_active/scan_warm/scan_idx/raddr, running best
run_bid/run_ask accumulators, final commit to best_bid/best_ask
plus bbo_valid. Reset clears all bests and scan state.
3.4. Display mapping
rtl/display/seven_segment_ctrl.sv: 8-digit multiplexed hex driver,
active-low segments/anodes, REFRESH_DIV=100_000 (1 kHz digit advance
at 100 MHz). Input is bbo_bid_price; digit_sel selects each nibble
with canonical segment patterns. Top level also fans
bbo_bid_price[10:0] to LED[14:4] for a binary readback.
Single symbol only; order_ref[8:0] aliases references that
differ in upper bits. That is a documented v1 limit, not a silent
assumption — see Known Limitations.
|
4. Interfaces
How operators and programs touch the system: board I/O, network port, bench tools, constraints, and build entry points.
4.1. Board I/O
| Output | Meaning |
|---|---|
LED15 |
PHY link up ( |
LED0 |
ITCH message parsed ( |
LED1 |
BBO updated ( |
LED2 |
Parse error ( |
LED3 |
Book error ( |
LED[14:4] |
|
7-seg (8-digit hex) |
Best bid price ( |
Order: LED15 first, then send traffic, then LED0/LED1 pulse.
Center button rst re-arms the pipeline; resend after reset.
Pin map lives in constraints/nexys_a7_100t.xdc
(xc7a100tcsg324-1): CLK100MHZ E3, rst N17, cathodes
ca–cg T10/R10/K16/K13/P15/T11/L18, anodes an[0–7]
J17/J18/T9/J14/P14/T14/K2/U13, LEDs H17–V11, RMII
eth_mdc/mdio/rstn/crs_dv/rxd/txd/refclk C9/A9/B3/D9/C11/D10/B9/A10/A8/D5.
constraints/nexys_a7_100t_eth.xdc is the Ethernet-focused variant.
4.2. Network port
-
Lab UDP broadcast
255.255.255.255:50000(defaultUDP_DST_PORT=50000). -
FPGA is RX-only: no ARP, no TX (
eth_txd=0,eth_txen=0). -
udp_rx_minimal.svfilters Eth → IPv4 (proto 17) → UDP dest-port match, then streams payload bytes. Non-matching frames return toStIdle. -
eth_ingress.svcaptures RMII nibbles oneth_refclk, toggles a frame flag oncrs_dvfall, crosses viabyte_cdc_fifo, and delimits frames withframe_endinto the UDP filter.
4.3. Bench tools
# Full bring-up helper (IP check + LED guide + traffic)
python tools/bench_check.py
python tools/bench_check.py --repeat 10 --skip-send
# Minimal sender (broadcast Mold/ITCH burst)
python tools/send_itch_udp.py --repeat 10
python tools/send_itch_udp.py --host 255.255.255.255 --port 50000 --repeat 3
Both tools build on sim/python/itch_ref.py encoders: two Adds
(order 1 buy 100 @ 50_0000, order 2 sell 50 @ 50_1000) plus an Execute
(order 1, 25 shares), wrapped with mold_wrap() (2-byte BE length
prefix per message).
| Command | Effect |
|---|---|
|
check |
|
send N Mold/ITCH UDP bursts; broadcast avoids ARP |
4.4. Build and sim entry points
# Simulate (core only, no PHY)
cd sim/cocotb && pip install -r ../requirements.txt && make
# Stress (10M messages, Verilator)
make stress SIM=verilator STRESS_MSGS=10000000
# Build and program (Ethernet bitstream)
vivado -mode batch -source vivado/add_sources.tcl
vivado -mode batch -source vivado/build.tcl
-
vivado/add_sources.tcl— source list for the.xpr. -
vivado/build.tcl— setsUSE_ETH=1, runssynth_1+impl_1towrite_bitstream(-jobs 8), prints timing/util report paths. -
vivado/build_eth.tcl,create_eth_ip.tcl,build_windows.ps1— variants/helpers for Ethernet builds on Windows. -
sim/cocotb/Makefile,run_tests.py,run_tests.cmd— cocotb runners.
Broadcasting to 255.255.255.255 is correct for the
point-to-point bench. Do not point production multicast at this
RX-only filter — it will be dropped by the port check.
|
5. Operation
How to bring the board up and what running looks like: the data-in → decision → data-out loop closed on hardware.
5.1. The loop
MARKET DATA IN DECISION OUT
───────────── ────────── ───
Ethernet / UDP → Parse ITCH → BBO + LEDs
Mold-wrapped bytes Order book 7-segment
Best bid / offer
-
Market data in. Live traffic hits the LAN8720 PHY. RMII RX, UDP filter, Mold unwrap — ITCH bytes reach the parser without a CPU
memcpy. -
Decision. The 8-bit streaming FSM decodes symbol, side, price, quantity, and timestamp. The dual 512-slot BRAM book applies the event and recomputes BBO — under 10 clock cycles on the Add path at 100 MHz.
-
Out. LED15 = link up. LED0/LED1 pulse on parse and BBO. The 7-segment shows the best bid.
LED[14:4]mirrors the low 11 bits of best bid.
5.2. Bring-up procedure
-
Program —
USE_ETH=1bitstream fromvivado/build.tclvia Hardware Manager (itch-hw.runs/impl_1/nexys_a7_100t_top.bit,xc7a100t_0JTAG). -
PC network — adapter on the Nexys cable: IP
192.168.1.1, mask255.255.255.0, gateway empty. Ignore “no internet”. -
Cable and link — RJ45 to board, power on, wait ~5 s. LED15 = link up.
-
Send traffic —
pip install -r sim/requirements.txt python tools/bench_check.pyor
python tools/send_itch_udp.py --repeat 10. -
Confirm — LED0 parse pulse, LED1 BBO pulse, 7-seg shows best bid (price
500000in the bench script).
When the 7-seg looks wrong, press center rst and resend before
assuming the book is wrong. Most bench surprises are link/broadcast
issues (see Interfaces troubleshooting), not RTL.
|
5.3. Reset and error behaviour
-
rst_syncclears parser buffer, book bests, scan state, and display scan. LEDs 2/3 clear until the next error. -
parse_error(LED2): unknown message type or undecodable buffer. -
book_error(LED3): execute/cancel on an empty slot or unknown message. -
Stretched pulses (LED0/LED1) are human-visible; sim
record_valid/bbo_validare single-cycle — do not compare bench LED timing to cocotb cycle counts directly.
| The bench path is lab replay only, not production MoldUDP64 multicast. Full architecture: Architecture. |
6. Verification
How the project proves the parser and book are correct — and how to re-run that proof locally. Simulation comes first: millions of synthetic ITCH events run against a Python golden model with zero BBO mismatches before any bitstream is trusted.
6.1. Reference oracle
sim/python/itch_ref.py is the intentionally simple model every RTL
path must agree with:
-
encode_add / encode_execute / encode_cancel— big-endian ITCH bytes. -
mold_wrap()— 16-bit BE length prefix per message. -
RefOrderBook— dict of orders,apply_bytes(),bbo()as(max bid, min ask).
Every optimized path (incremental BBO, rescan) must equal exhaustive
bbo() unless documented as approximate. Deleted/executed-away orders
never appear.
6.2. Correctness properties
| Property | Where it is checked |
|---|---|
last-byte → |
|
|
|
|
|
BBO |
|
corrupt/unknown bytes → |
|
Corruption handling is fail-loud: unknown type bytes raise parse_error
instead of guessing; empty-slot exec/cancel raises book_error.
6.3. Running the gates
cd sim/cocotb && pip install -r ../requirements.txt && make
Stress with Verilator (resume-scale 10M):
make stress SIM=verilator STRESS_MSGS=10000000
Windows equivalent: sim/cocotb/run_tests.cmd.
Latency artifact: sim/results/latency_summary.json
(parse_max_cycles, bbo_max_cycles, ns @ 100 MHz) — regenerated by
test_e2e_latency and consumed by Performance.
| No book optimization lands without oracle agreement. The rescan path must reproduce exhaustive BBO exactly. |
| When adding a message type, add the encoder + oracle comparison first. A failing BBO assert is the specification; a passing one is the proof. |
7. Implementation
Vivado synthesis, place-and-route, and bitstream detail.
docs/metrics.md is normative for the numbers; this chapter
summarizes them and states what was built.
7.1. Build snapshot
First clean end-to-end run with live Ethernet ingress (USE_ETH=1).
| Item | Value |
|---|---|
Date of build |
2026-08-02 |
Toolchain |
Vivado 2025.2 |
FPGA part |
|
Top module |
|
Clock |
100 MHz ( |
Generics |
|
Runs |
|
Bitstream |
|
7.2. Reports on disk
vivado/build.tcl (batch from repo root):
vivado -mode batch -source vivado/add_sources.tcl
vivado -mode batch -source vivado/build.tcl
build.tcl sets generic {USE_ETH=1} on sources_1, launches
synth_1 then impl_1 -to_step write_bitstream -jobs 8, and prints:
-
*.timing_summary_routed.rpt→ WNS, TNS, WHS, THS -
*.utilization_placed.rpt→ LUT, FF, BRAM counts -
*.power_routed.rpt→ total power
under itch-hw.runs/impl_1/. Update Performance and
docs/metrics.md badges from those reports.
7.3. What the diagrams show
-
synth_design_diagram.png— package view: RMII Ethernet pins (eth_mdc/mdio/rxd/crs_dv) and status LEDs on the Nexys ballout. -
impl_design_diagram.png— placed hierarchy:gen_eth.u_eth(eth_ingress) →gen_eth.u_mold(moldudp64_rx) →u_core(itch_hw_core) →u_display(seven_segment_ctrl). -
design_run_succ_synth.png— Design Runs withsynth_1/impl_1green;bitstream_dialog.png— Program Device ready onxc7a100t_0.
Never hand-edit generated itch-hw.runs/ reports to change
the numbers. Rebuild with vivado/build.tcl and copy the routed
values — the only writers that preserve the timing-closure claim.
|
8. Performance
Measured behaviour only. Unmeasured values are TBD (unmeasured).
Source build: 2026-08-02 USE_ETH=1, Vivado 2025.2, cocotb @ 100 MHz.
8.1. Timing (post-route impl_1, routed)
| Metric | Target | Measured | Status |
|---|---|---|---|
WNS |
≥ 0 ns |
+1.552 ns |
Met |
TNS |
0 ns |
0.000 ns |
Met |
WHS |
≥ 0 ns |
+0.033 ns |
Met |
THS |
0 ns |
0.000 ns |
Met |
Failed routes |
0 |
0 |
Met |
Timing closed at 100 MHz with headroom. Full table: docs/metrics.md.
8.2. Utilization and power
Light footprint — room left on the 100T for deeper book logic.
| Resource | Used (approx.) | Available | % |
|---|---|---|---|
Slice LUTs |
— |
63,400 |
2% |
Slice FFs |
— |
126,800 |
1% |
BRAM tiles |
— |
135 |
1% |
LUTRAM |
— |
— |
1% |
DSP |
— |
240 |
0% |
I/O |
— |
— |
20% |
BUFG |
— |
32 |
6% |
| Item | Value |
|---|---|
Estimated total power |
0.117 W (Vivado post-route) |
8.3. Functional latency (cocotb, itch_hw_core only)
Source: sim/results/latency_summary.json
(regenerated by sim/cocotb/run_tests.cmd).
| Path | Budget | Cycles | ns @ 100 MHz |
|---|---|---|---|
Last ITCH byte → |
≤ 5 |
3 |
30 |
|
≤ 6 |
6 |
60 |
|
— |
≤ 512 (rescan) |
≤ 5,120 |
On hardware the target remains under 10 cycles on the Add path for parse + BBO combined — sim and silicon to be reconciled after bench traffic.
8.4. How to refresh
vivado -mode batch -source vivado/build.tcl
Copy from itch-hw.runs/impl_1/ (*_timing_summary_routed.rpt,
*_utilization_placed.rpt, *_power_routed.rpt) into the tables above
and docs/metrics.md badges.
cd sim/cocotb
run_tests.cmd
Or on Linux / GNU make:
cd sim/cocotb && pip install -r ../requirements.txt && make
Bench LED pulse widths are human-visible stretches, not cycle
counts. Only cocotb + latency_summary.json may update the latency
table above.
|
9. Known Limitations
Honest boundaries: what the system is, and what it is not. This chapter overrides any optimistic reading of earlier chapters.
9.1. What is real today
-
RMII ingress with CDC + minimal IPv4/UDP filter (lab port 50000).
-
MoldUDP64 length-prefix unwrap to raw ITCH bytes.
-
Streaming 8-bit FSM for Add / Execute / Cancel →
itch_record_t. -
Dual 512-slot BRAM book with incremental Add BBO and ≤512-cycle rescan on Exec/Cancel at the best.
-
BBO outputs (
bid/ask price + shares,bbo_valid) with parse/book error flags. -
LED + 7-seg proof on Nexys A7-100T (
USE_ETH=1bitstream). -
cocotb gates vs Python golden model, including 10M-message Verilator stress entry point; post-route timing closed at 100 MHz.
9.2. What is explicitly not here
-
Production MoldUDP64 multicast: lab broadcast replay only.
-
ARP, IP TX, or UDP TX — the board never replies; use broadcast.
-
Multi-symbol books: single symbol in v1.
-
Message types beyond A / E / X (no crosses, halts, or admin).
-
Full 64-bit order identity: slots key on
order_ref[8:0], so upper-bit collisions alias — size test traffic accordingly. -
Exchange sequencing, matching, or order-entry back out.
9.3. Limits to design around
-
A byte is parsed if and only if the UDP dest port matches and the Mold length framing is intact; anything else is dropped to
StIdle. -
Corruption is a loud error (
parse_error/book_error), never a degraded read. -
Published numbers are measured in this tree (WNS +1.552 ns, ~2% LUT, 3 cy parse + 6 cy BBO on Add). Unmeasured values are
TBD (unmeasured). -
Bench LED timing ≠ sim cycle timing; reconcile Add-path <10-cycle claims after bench traffic capture.
10. Lab Journal
Dated bench notes. log/ holds the full text; this chapter
summarizes each entry and links the source so the manual never forks
the journal.
10.1. 2026-08-02 — Successful Synthesis, Implementation, Bitstream
First clean end-to-end Vivado run for the live UDP path (not just the cocotb core) after several RTL iterations on ingress, Mold unwrap, parser, and book.
-
synth_1+impl_1green;write_bitstreamproduceditch-hw.runs/impl_1/nexys_a7_100t_top.bit. -
Post-route: WNS +1.552 ns, WHS +0.033 ns, 0 failed routes, ~0.117 W, LUT 2% / FF 1% / BRAM 1%.
-
Hierarchy confirmed:
gen_eth.u_eth→gen_eth.u_mold→u_core→u_display; package pins match the Nexys ballout. -
Hardware Manager sees
xc7a100t_0, ready to program.
Full text with all four screenshots:
log/2026-08-02 - Successful Synthesis - Implementation - Bitstream.md.
Public companion on the engineering log:
Successful Synthesis - Implementation - Bitstream
— first clean Vivado build for the Nexys A7 ITCH pipeline with USE_ETH=1.
10.2. 2026-08-02 — Ethernet Cable
Market data must flow continuously so the FPGA can act — the full
data in → decision → data out path matters, without shortcuts that
skip real ingress.
-
Ordered Cat5e/Cat6 for PC ↔ Nexys (no switch; LAN8720 auto-MDIX); cable arrived and is ready for testing.
-
Goal: program
USE_ETH=1, confirm LED15, inject Mold/ITCH traffic withtools/send_itch_udp.pyperdocs/board_eth_setup.md.
Full text:
log/2026-08-02 - Ethernet Cable.md.
Public companion on the engineering log: ITCH Ethernet Lab Bring-Up — preparing Nexys A7 Ethernet ingress for end-to-end Mold/ITCH UDP testing.
Related bench reading from the sibling stack build:
Understanding the UDP Stack and Connecting to ITCH
— why market-data pipelines need UDP over TCP, from ITCH ingestion
on the FPGA to the custom 100 Mbps stack
(github.com/tmarhguy/udp-stack).
New entries go in log/YYYY-MM-DD - Topic.md and get a subsection
here. Link the file; do not paste bench speculation as fact.
|
11. About This Manual
Meta information about this manual — deliberately placed after the work itself.
This manual is the running engineering reference for the project —
message formats, pipeline decisions, and measured numbers as they land.
It is the companion to the concise, GitHub-facing README.md:
-
README.md— project identity, status, and quick start. -
docs/*.md— normative companions (architecture.md,metrics.md,board_eth_setup.md). -
log/— dated lab journal (design notes, bring-up narrative). -
docs/(this manual) — architecture, design, verification, and results in engineering-manual style.
11.1. Conventions
Conventions used throughout:
-
monospacemarks commands, file paths, identifiers, and literals. -
Unmeasured values are written as
TBD (unmeasured)— never silently estimated. -
Clocks are 100 MHz system + 50 MHz
eth_refclkunless noted. -
Characterization is post-route (
impl_1) unless a subsection states otherwise. -
Normative detail lives alongside this manual as Markdown (
docs/*.md,log/) and is linked, not duplicated. -
Figures in
docs/images/are staged copies; sources of truth stay inmedia/(seescripts/build-docs.sh).
| New here? Start with Introduction for scope and reading order, then Architecture for the system overview. |
12. Authors
The manual, RTL, verification, and lab journal are produced by the engineer behind the design.
12.1. Tyrone Marhguy
Computer Engineering '28, University of Pennsylvania. Independent FPGA work: ITCH parsing, order-book logic, and a public build log. Designer of the Tomato 32-bit computer; contributor to open-source EDA (LibreLane, Verilator, OpenROAD, OpenFPGA).
Questions or collabs — reach out. Build log and projects at tmarhguy.com.