How operators and scripts touch the system: lab addresses, host tools, LEDs, 7-segment, and pin constraints.
From core/rtl/top.sv and core/rtl/stack/udp_stack_core.sv:
| Field | Value |
|---|---|
FPGA IP |
|
Host IP |
|
UDP port |
|
Host MAC |
set |
Edit before building for a new host:
localparam logic [47:0] HOST_MAC = 48'h00_08_DC_12_34_56;
localparam logic [31:0] HOST_IP = {8'd192, 8'd168, 8'd1, 8'd100};tools/send_udp.py — send a datagram and wait for the echo:
# Direct cable without ARP — broadcast works
python tools/send_udp.py --host 255.255.255.255 --port 50000
# Targeted echo with custom payload
python tools/send_udp.py --host 192.168.1.10 --port 50000 --payload "echo-test"
# Repeat N times
python tools/send_udp.py --host 192.168.1.10 --port 50000 --payload "bench" --repeat 10tools/bench_check.py — wire-level sanity wrapper around the above
(--host 255.255.255.255 --payload bench):
python tools/bench_check.pyBoth use plain UDP sockets with SO_BROADCAST and a 2 s reply timeout.
No reply (timeout) means link, address, or bitstream needs checking —
see Bring-Up.
From core/rtl/top.sv:
| LED | Meaning |
|---|---|
|
Mirror |
|
Heartbeat (~1 Hz, |
|
RX activity pulse (5 M-cycle stretch) |
|
TX activity pulse (5 M-cycle stretch) |
|
Stack error ( |
|
Latency-valid pulse ( |
|
PHY link up ( |
Right to left on the board (from seg_value in top.sv):
-
Right 2 digits:
SW[7:0]in hex. -
Next 2 digits: heartbeat counter (slowly increments each blink).
-
Left 4 digits:
0000.
core/constrs/nexys_a7_100t.xdc maps top ports to Nexys A7 pins:
| Constraint | Purpose |
|---|---|
|
100 MHz board clock, 10 ns |
|
50 MHz RMII ref, 20 ns |
|
unrelated clocks for CDC FIFO |
|
center-button reset path ( |
|
switches and status above |
|
7-segment cathodes and anodes |
|
RMII + MDIO to LAN8720 |
|
Caution
|
The XDC must stay paired with top. Port names match exactly
(CLK100MHZ, eth_refclk, LED[15:0]). constraints/udp_consts.xdc
is a legacy copy — core/constrs/nexys_a7_100t.xdc is the build truth.
|