fix(fpga): PR-O.8.1 — drop stale BFP-era ports, fix xsim include path

Wrapper xfft_2048.v had m_axis_data_tuser and m_axis_status_{tdata,tvalid,
tready} hooked up to the IP, but the regenerated xfft_2048_ip in scaled
mode + Pipelined Streaming + 1 channel + no XK_INDEX/OVFLO doesn't expose
those ports. xelab errored "cannot find port" on all four. Removed.

run_xfft_xsim.sh missed -i "$PROJ_ROOT" so xvlog couldn't resolve
`include "radar_params.vh"` from inside tb/. Fixed.

gen_xfft_2048_ip.tcl header comment described the old Burst I/O 11-stage
schedule; updated to PG109 Pipelined Streaming pair-grouped layout that
matches the actual SCALE_SCH = 12'hAA9 we now drive.

Verified: tb_xfft_2048_xsim 5/5 PASS on real LogiCORE FFT v9.1 IP under
Vivado 2025.2 xsim — DC peak at bin 0, impulse flat spectrum, tone at
bin 128. Closes T-10 (FFT-block synth-mode validation).
This commit is contained in:
Jason
2026-05-02 10:20:10 +05:45
parent af64b0952e
commit 166464e877
3 changed files with 13 additions and 18 deletions

View File

@@ -6,7 +6,9 @@
# - Architecture: Pipelined Streaming I/O (Radix-2, 11 stages)
# - Data Format: Fixed Point
# - Scaling: Scaled (fixed schedule via cfg_tdata SCALE_SCH bits)
# Schedule [1,1,1,1,1,1,1,1,1,1,1] = /N (unitary FFT).
# Schedule = 12'hAA9 (PG109 Pipelined Streaming layout):
# stage 1 alone >>1, stages 2-3, 4-5, 6-7, 8-9, 10-11
# grouped each >>2 (per pair). Total = /N = unitary FFT.
# AUDIT-C10/C-8 resolution: BFP previously hid a per-frame
# block exponent the bridge dropped, making sim/silicon
# absolute magnitudes incomparable. Scaled mode locks a

View File

@@ -23,8 +23,9 @@ mkdir -p "$WORK_DIR"
cd "$WORK_DIR"
echo "===== Compiling Verilog sources ====="
# Wrapper + testbench with the IP-on define
xvlog -d FFT_USE_XILINX_IP "$WRAPPER" "$TB"
# Wrapper + testbench with the IP-on define. -i adds the FPGA root so
# `include "radar_params.vh"` resolves from inside tb/.
xvlog -d FFT_USE_XILINX_IP -i "$PROJ_ROOT" "$WRAPPER" "$TB"
# IP simulation netlist — references unisim primitives
xvlog "$IP_NETLIST"
# fft_engine etc. NOT needed because FFT_USE_XILINX_IP routes around it,

View File

@@ -56,8 +56,8 @@ module xfft_2048 (
output wire s_axis_data_tready,
// Data output channel (AXI-Stream master). 64-bit packed {Q[31:0], I[31:0]}.
// No tuser scaled mode does not emit BLK_EXP, and the design has no
// XK_INDEX / OVFLO consumers.
// No tuser scaled mode does not emit BLK_EXP, and the IP is configured
// with no XK_INDEX / OVFLO outputs (see gen_xfft_2048_ip.tcl).
output wire [63:0] m_axis_data_tdata,
output wire m_axis_data_tvalid,
output wire m_axis_data_tlast,
@@ -68,15 +68,11 @@ module xfft_2048 (
// ============================================================================
// XILINX LOGICORE FFT v9.1 production / XSim path
// ============================================================================
// Side-channels (status/event) are tied off here; if downstream needs them
// (e.g. for pipeline-stall debug), surface them through this wrapper.
wire [7:0] xfft_status_tdata;
wire xfft_status_tvalid;
// tuser still exists on the IP port surface (Vivado emits a 1-bit dummy in
// scaled mode with no XK_INDEX/OVFLO). Wired to a local sink so the placer
// elides it.
wire [7:0] xfft_dout_tuser_unused;
// Per the regenerated IP (Pipelined Streaming + scaled + 1 channel + no CP +
// no XK_INDEX / no OVFLO), the IP exposes only the AXI-Stream config / data
// channels and six event signals. There is no m_axis_data_tuser and no
// m_axis_status_* channel in this configuration. Event signals are left
// unconnected none are consumed downstream.
xfft_2048_ip u_xfft (
.aclk (aclk),
@@ -88,13 +84,9 @@ xfft_2048_ip u_xfft (
.s_axis_data_tready (s_axis_data_tready),
.s_axis_data_tlast (s_axis_data_tlast),
.m_axis_data_tdata (m_axis_data_tdata),
.m_axis_data_tuser (xfft_dout_tuser_unused),
.m_axis_data_tvalid (m_axis_data_tvalid),
.m_axis_data_tready (m_axis_data_tready),
.m_axis_data_tlast (m_axis_data_tlast),
.m_axis_status_tdata (xfft_status_tdata),
.m_axis_status_tvalid (xfft_status_tvalid),
.m_axis_status_tready (1'b1),
.event_frame_started (),
.event_tlast_unexpected (),
.event_tlast_missing (),