Commit Graph

18 Commits

Author SHA1 Message Date
Jason 30279e8c4d fix(fpga): F-0.9 option A — BUFIO+BUFR for 50T ft_clkout (SRCC pin)
C4 is an SRCC pin (IS_CLK_CAPABLE=1, IS_MASTER=0 in the Vivado device
model), not an MRCC as earlier comments claimed. SRCC cannot drive BUFG
through dedicated routing, so the previous CLOCK_DEDICATED_ROUTE=FALSE
override forced fabric routing and burned ~5 ns on the ft_clkout path
(WNS -5.362 ns in the d36a4c9 build).

Swap to BUFIO + BUFR for USB_MODE=1 (50T/FT2232H): SRCC → BUFIO → BUFR
is the standard 7-series path for regional clock distribution. All
ft_clkout-domain logic (FT2232H FSM, toggle CDCs, USB FIFO flops) is
contained in bank 35 / one clock region, so regional distribution is
sufficient. USB_MODE=0 (200T/FT601) keeps the BUFG because D17 is a
proper MRCC pin.

Removed CLOCK_DEDICATED_ROUTE=FALSE from both the XDC and the build
script — no longer needed with dedicated BUFIO/BUFR routing.
2026-04-20 20:53:49 +05:45
Jason bf89984f04 Revert "fix(fpga): IOB=TRUE on FT2232H pads to meet 5 ns FPGA launch budget"
This reverts commit 94bf6944a3.
2026-04-20 20:20:02 +05:45
Jason 94bf6944a3 fix(fpga): IOB=TRUE on FT2232H pads to meet 5 ns FPGA launch budget
Post-route WNS = -5.355 ns on path group ft_clkout, net
  u_core/gen_ft2232h.usb_inst/ft_data_TRI[0]_repN_1

FT2232H 245-sync FIFO input setup (t_su = 11.667 ns on a 16.667 ns
CLKOUT) leaves the FPGA only ~5 ns from clock edge to pad. Without
IOB=TRUE, the output / tristate FFs live in fabric and FF→OBUFT
routing eats 2–3 ns, forcing Vivado to replicate the tristate
driver (ft_data_TRI[*]_repN) and still miss timing.

The FSM in usb_data_interface_ft2232h.v already registers
ft_data_out / ft_data_oe / ft_{rd,wr,oe}_n at the output boundary
in the ft_clk domain, so packing them into the IOB is safe with
no RTL change.
2026-04-20 16:43:12 +05:45
Jason 0067969ee7 fix(fpga): wire F-0.1 adc_or_p/n through 50T wrapper + remove xdc control-flow
Build-blocking fixes surfaced by gpu-server synth:

1. radar_system_top_50t.v wrapper was missing adc_or_p/n ports and the
   u_core instantiation left them unconnected. Every XDC line in the 50T
   anchor block (PACKAGE_PIN M6/N6, IOSTANDARD, DIFF_TERM, set_input_delay)
   therefore matched no ports and emitted CRITICAL WARNINGs, leaving the
   overrange pin effectively tied off. Added the two inputs and wired them
   through to the core.

2. adc_clk_mmcm.xdc used foreach / unset — Vivado's XDC parser only
   accepts a restricted Tcl subset and rejected them as
   [Designutils 20-1307]. Moved the clk_mmcm_out0 ↔ USB-clock false paths
   into each board XDC (ft_clkout for 50T, ft601_clk_in for 200T) where
   the clock name is already known.
2026-04-20 16:08:13 +05:45
Jason 70067c6121 fix(fpga): F-0.1 wire AD9484 OR overrange pin into diagnostics
The AD9484 OR (overrange) LVDS pair is routed on the 50T main board to
xc7a50t-ftg256 bank-14 pins M6/N6 but was previously left unconnected at
the top level. Plumb it through the full stack so saturation at the raw
ADC boundary shows up in the existing overflow aggregation:

- ad9484_interface_400m: add adc_or_p/n inputs, IBUFDS + IDDR capture of
  both phases in the BUFIO domain, re-register into the clk_400m BUFG
  domain, OR rise|fall into adc_overrange_400m output.
- radar_receiver_final: stickify adc_overrange_400m in clk_400m, CDC to
  clk_100m via a 2FF ASYNC_REG chain (same reasoning as F-1.2's
  cdc_cic_fir_overrun — single-bit, latched low→high, GPIO-class
  diagnostic), OR into the existing ddc_overflow_any aggregation.
- radar_system_top: expose adc_or_p/n top-level ports and pass through.
- xc7a50t_ftg256.xdc: anchor M6/N6 as LVDS_25 DIFF_TERM, with the same
  DCO-relative input-delay constraints as adc_d_p[*].
- xc7a200t_fbg484.xdc: IOSTANDARD/DIFF_TERM set; PACKAGE_PIN left as a
  documented TODO — the 200T dev-board schematic has not been checked
  and the 200T build will need the anchor filled in before place/route.
2026-04-20 15:48:34 +05:45
Jason 675b1c0015 fix(pre-bringup): second-batch P1/P2/P3 audit findings
Addresses the remaining actionable items from
docs/DEVELOP_AUDIT_2026-04-19.md after commit 3f47d1e.

XDC (dead waivers — F-0.4, F-0.5, F-0.6, F-0.7):
- ft_clkout_IBUF CLOCK_DEDICATED_ROUTE now uses hierarchical filter;
  flat net name did not exist post-synth.
- reset_sync_reg[*] false-path rewritten to walk hierarchy and filter
  on CLR/PRE pins.
- adc_clk_mmcm.xdc ft601_clk_in references replaced with foreach-loop
  over real USB clock names, gated on -quiet existence.
- MMCM LOCKED waiver uses REF_PIN_NAME filter instead of the
  previously-missing u_core/ literal path.

CDC (F-1.1, F-1.2, F-1.3):
- Documented the quasi-static-bus stability invariant above the
  FT601 cmd_valid toggle block.
- cdc_adc_to_processing gains an `overrun` output; the two CIC->FIR
  instances feed a sticky cdc_cic_fir_overrun flag surfaced on
  gpio_dig5 so silent sample drops become visible to the MCU.
- Removed the dead mixers_enable synchronizer in ddc_400m.v; the _sync
  output was unused and every caller ties the port to 1'b1.

Diagnostics (F-6.4):
- range_bin_decimator watchdog_timeout plumbed through receiver
  and top-level, OR'd into gpio_dig5.

ADAR (F-4.7):
- delayUs() replaced with DWT cycle counter; self-initialising
  TRCENA/CYCCNTENA, overflow-safe unsigned subtraction.

Regression: tb_cdc_modules.v 57/57 passes under iverilog after
the cdc_modules.v change. Remote Vivado verification in progress.
2026-04-20 14:28:22 +05:45
NawfalMotii79 d3476139e3 Merge pull request #89 from NawfalMotii79/feat/ft2232h-default-ft601-option
feat: make FT2232H default USB interface, add FT601 premium option, deprecate GUI V6
2026-04-17 22:21:58 +01:00
Jason 658752abb7 fix: propagate FPGA AGC enable to MCU outer loop via DIG_6 GPIO
Resolve cross-layer AGC control mismatch where opcode 0x28 only
controlled the FPGA inner-loop AGC but the STM32 outer-loop AGC
(ADAR1000_AGC) ran independently with its own enable state.

FPGA: Drive gpio_dig6 from host_agc_enable instead of tied low,
making the FPGA register the single source of truth for AGC state.

MCU: Change ADAR1000_AGC constructor default from enabled(true) to
enabled(false) so boot state matches FPGA reset default (AGC off).
Read DIG_6 GPIO every frame with 2-frame confirmation debounce to
sync outerAgc.enabled — prevents single-sample glitch from causing
spurious AGC state transitions.

Tests: Update MCU unit tests for new default, add 6 cross-layer
contract tests verifying the FPGA-MCU-GUI AGC invariant chain.
2026-04-17 00:04:37 +05:45
Jason f393e96d69 feat(fpga): make FT2232H default USB interface, rewrite FT601 write FSM, add clock-loss watchdog
- Set USB_MODE default to 1 (FT2232H) in radar_system_top.v; 200T build
  overrides to USB_MODE=0 via build_200t.tcl generic property
- Rewrite FT601 write FSM: 4-state architecture with 3-word packed data,
  pending-flag gating, and frame sync counter
- Add FT2232H read FSM rd_cmd_complete flag, stream field zeroing, and
  range_data_ready 1-cycle pipeline delay in both USB modules
- Implement clock-loss watchdog: ft_heartbeat toggle + 16-bit timeout
  counter drives ft_clk_lost, feeding ft_effective_reset_n via 2-stage
  ASYNC_REG synchronizer chain
- Fix sample_counter reset literal width (11'd0 -> 12'd0)
- Add FT2232H I/O timing constraints to 50T XDC; fix dac_clk comments
- Document vestigial ft601_txe_n/rxf_n ports (needed for 200T XDC)
- Tie off AGC ports on TE0713 dev wrapper
- Rewrite tb_usb_data_interface.v for new 4-state FSM (89 checks)
- Add USB_MODE=1 regression runs; remove dead CHECK 5/6 loop
- Update diag_log.h USB interface comment
2026-04-16 16:18:52 +05:45
Jason ffba27a10a feat: hybrid AGC (FPGA phases 1-3 + GUI phase 6) with timing fix
FPGA:
- rx_gain_control.v rewritten: per-frame peak/saturation tracking,
  auto-shift AGC with attack/decay/holdoff, signed gain -7 to +7
- New registers 0x28-0x2C (agc_enable/target/attack/decay/holdoff)
- status_words[4] carries AGC metrics (gain, peak, sat_count, enable)
- DIG_5 GPIO outputs saturation flag for STM32 outer loop
- Both USB interfaces (FT601 + FT2232H) updated with AGC status ports

Timing fix (WNS +0.001ns -> +0.045ns, 45x improvement):
- CIC max_fanout 4->16 on valid pipeline registers
- +200ps setup uncertainty on 400MHz domain
- ExtraNetDelay_high placement + AggressiveExplore routing

GUI:
- AGC opcodes + status parsing in radar_protocol.py
- AGC control groups in both tkinter and V7 PyQt dashboards
- 11 new AGC tests (103/103 GUI tests pass)

Cross-layer:
- AGC opcodes/defaults/status assertions added (29/29 pass)
- contract_parser.py: fixed comment stripping in concat parser

All tests green: 25 FPGA + 103 GUI + 29 cross-layer = 157 pass
2026-04-13 19:24:11 +05:45
Jason 408f4d126f feat(usb): add FT2232H USB 2.0 interface for 50T production board
Replace FT601 (USB 3.0, 32-bit) with FT2232H (USB 2.0, 8-bit) on the
50T production board per updated Eagle schematic (commit 0db0e7b).
USB 3.0 via FT601 remains available on the 200T premium board.

RTL changes:
- Add usb_data_interface_ft2232h.v: 245 Sync FIFO interface with toggle
  CDC (3-stage) for reliable 100MHz->60MHz clock domain crossing,
  mux-based byte serialization for 11-byte data packets, 26-byte status
  packets, and 4-byte sequential command read FSM
- Add USB_MODE parameter to radar_system_top.v with generate block:
  USB_MODE=0 selects FT601 (200T), USB_MODE=1 selects FT2232H (50T)
- Wire FT2232H ports in radar_system_top_50t.v with USB_MODE=1 override,
  connect ft_clkout to shared clock input port
- Add post-DSP retiming register in ddc_400m.v to fix marginal 400MHz
  timing path (WNS improved from +0.070ns to +0.088ns)

Constraints:
- Add FT2232H pin assignments for all 15 signals on Bank 35 (LVCMOS33)
- Add 60MHz ft_clkout clock constraint (16.667ns) on MRCC N-type pin C4
- Add CLOCK_DEDICATED_ROUTE FALSE for N-type MRCC workaround
- Add CDC false paths between ft_clkout and clk_100m/clk_120m_dac

Build scripts:
- Add PLIO-9 DRC demotion and CLOCK_DEDICATED_ROUTE property in build_50t.tcl
- Add usb_data_interface_ft2232h.v to build_200t.tcl explicit file list

Python host:
- Add FT2232HConnection class using pyftdi SyncFIFO (VID 0x0403:0x6010)
- Add compact 11-byte packet parser for FT2232H data packets
- Update RadarAcquisition to support both FT601 and FT2232H connections

Test results:
- iverilog regression: 23/23 PASS
- Vivado Build 15 (XC7A50T): WNS=+0.088ns, WHS=+0.059ns, 0 violations
- DSP48E1: 112/120 (93.3%), LUTs: 10,060/32,600 (30.9%)
2026-04-07 19:22:16 +03:00
Jason 849b32240b fix(xdc): add hold false_path for ADC IDDR + reorganize build scripts by target
- Add set_false_path -hold for source-synchronous ADC IDDR paths in
  adc_clk_mmcm.xdc (eliminates 8 hold violations from build 12)
- Add DDR falling-edge input delay constraints to xc7a50t_ftg256.xdc
  (parity with 200T XDC)
- Reorganize scripts/ into target subdirectories: 50t/, 200t/, te0712/,
  te0713/, utils/ so users can run the correct build for their hardware
- Delete obsolete build scripts (build17-20) superseded by build_50t/200t
- Update project_root paths in all moved scripts (.. -> ../..)
2026-04-07 15:13:13 +03:00
Jason 44460e7443 fix(constraints): change adc_pwdn from LVCMOS33 to LVCMOS25 for Bank 14 compatibility
The placer enforces a single VCCO per bank. LVDS_25 forces Bank 14
to VCCO=2.5V, which conflicts with LVCMOS33 (needs 3.3V). Changing
adc_pwdn to LVCMOS25 resolves [Place 30-372] bank incompatibility.
The AD9484 PWDN pin has CMOS-level thresholds (~0.8V), so 2.5V
output drives it correctly.
2026-04-07 06:07:47 +03:00
Jason 7d90e5e7d6 fix(constraints,scripts): resolve 50T build failures — LVDS_25 + DRC waivers + unconstrained ports
Three issues prevented the 50T (FTG256) build from completing:

1. LVDS standard: LVDS_33 and LVDS do not exist on 7-series HR banks.
   Changed to LVDS_25 (the only valid differential input standard).
   IBUFDS inputs are VCCO-independent, so LVDS_25 works correctly even
   with Bank 14 VCCO=3.3V.

2. BIVC-1 DRC: Bank 14 has LVDS_25 (needs 2.5V) and LVCMOS33 adc_pwdn
   (needs 3.3V). Since all LVDS ports are inputs (IBUFDS only), the
   voltage conflict does not affect functionality. Demoted to warning.

3. Pin overflow: 113 ports vs 69 available FTG256 pins. The 118
   unconstrained port bits (FT601 unwired, status/debug unrouted,
   dac_clk unconnected) cause NSTD-1/UCIO-1 DRC errors. Demoted to
   warnings since these ports have no physical connections on this board.

Also added: CFGBVS/CONFIG_VOLTAGE settings, build_50t_test.tcl to repo.
2026-04-07 05:48:35 +03:00
Jason 30f56f3089 fix(constraints): use LVDS (not LVDS_33) for 50T Bank 14 ADC inputs
LVDS_33 is not a valid I/O standard on 7-series FPGAs. The correct
standard for LVDS inputs in HR banks with VCCO != 2.5V is LVDS, which
works with any VCCO for input-only buffers (IBUFDS). LVDS_25 requires
VCCO=2.5V exactly.

Note: the 50T FTG256 build still fails at placement due to pin overflow
(113 ports vs 69 available pins) — this is a pre-existing package
limitation unrelated to this fix.
2026-04-07 05:31:48 +03:00
Jason d50e51ada6 fix(rtl,constraints): change IBUFDS to IOSTANDARD DEFAULT for multi-target bank voltage compatibility
The IBUFDS primitives in ad9484_interface_400m.v hardcoded LVDS_25 and
DIFF_TERM TRUE, which overrode XDC constraints. On the XC7A50T (Bank 14
VCCO=3.3V), this caused a BIVC-1 DRC error: LVDS_25 requires VCCO=2.5V,
conflicting with adc_pwdn (LVCMOS33, VCCO=3.3V) in the same bank.

Changes:
- ad9484_interface_400m.v: IBUFDS parameters changed from LVDS_25/DIFF_TERM
  TRUE to DEFAULT/DIFF_TERM FALSE, delegating control to XDC per target
- xc7a50t_ftg256.xdc: Re-enable DIFF_TERM TRUE (safe now that RTL does not
  hardcode LVDS_25), update DRC Fix History with correct root cause
2026-04-07 05:17:11 +03:00
Jason 1f315a62c8 fix(scripts,constraints): handle empty STATS properties in build summaries, fix 50T XDC DRC errors
Build scripts (17-21): STATS.WNS/TNS/WHS/THS/TPWS from get_property can
return empty strings in Vivado 2025.2 after write_bitstream auto-launch.
Wrap in catch with N/A fallback. Guard all expr delta calculations and
signoff comparisons with [string is double -strict] checks.

XDC (xc7a50t_ftg256): Fix PLIO-9 by moving clk_120m_dac from C13 (N-type)
to D13 (P-type MRCC) — clock inputs require P-type MRCC pin. Fix BIVC-1 by
disabling DIFF_TERM on Bank 14 LVDS pairs to resolve VCCO conflict with
single-ended adc_pwdn (LVCMOS33) on T5 — requires external termination.
2026-04-07 05:07:14 +03:00
Jason 1acedf494c Migrate hardware platform from XC7A50T to XC7A200T-2FBG484I
Production FPGA: Artix-7 XC7A200T-2FBG484I (33,650 slices, 740 DSP48E1,
365 BRAM, -2 speed grade). Pin-mapped across 6 banks with proper VCCO
assignment (3.3V/2.5V/1.8V).

RTL timing primitives added for clean timing closure:
- ad9484_interface_400m.v: BUFIO for IDDR capture at 400MHz DDR,
  BUFG for fabric logic, reset synchronizer (P1-7)
- dac_interface_single.v: ODDR for dac_clk forwarding + dac_data[7:0]
  output registration, eliminates clock-forwarding insertion delay
- usb_data_interface.v: ODDR for ft601_clk_out forwarding, FSM runs
  on ft601_clk_in domain with CDC synchronizers

Constraints:
- New production XDC (xc7a200t_fbg484.xdc): 182 pins, generated clocks
  for ODDR outputs, BUFIO/DDR input delays, fixed false_path strategy
  (from reset source, not to CLR pins), IOB packing on cells not ports
- Preserved upstream XDC as xc7a50t_ftg256.xdc for reference
- Updated cntrt.xdc with DRC fixes (I/O standards, missing constraints)
2026-03-16 22:24:22 +02:00