docs(fpga): PR-X.2 F-7.3 — refresh tb_ad9484_xsim header + retire Group 4

Header (line 6, 11): "(IBUFDS, BUFG, IDDR)" → "(IBUFDS, BUFIO, BUFG,
  MMCME2_ADV)"; "IDDR Q2 (falling-edge) data capture in
  SAME_EDGE_PIPELINED mode" → "Falling-DCO-edge IOB-packed IFF capture
  (post-AUDIT-C4 SDR shape; no IDDR, no rise/fall demux)".

  $display banner: "(IBUFDS, BUFG, IDDR)" → "(IBUFDS, BUFIO, BUFG, MMCME2)".

  Group 8 inline comment: "captures Q2 of the IDDR (falling-edge…)"
  → "captures the IOB-packed IFF on the falling DCO edge".

  Test Group 4 retired. The block drove 0xAA on rising DCO and 0x55 on
  falling DCO. Post-AUDIT-C4 the IFF only samples the falling edge —
  every captured value was 0x55 — so the assertion
  `saw_aa > 0 || saw_55 > 0` was trivially true and `cap_count > 0`
  duplicates Group 5 / Group 8's stronger checks. Block replaced with
  a tombstone comment; group numbering preserved for git-blame
  continuity.

Two "IDDR" references intentionally retained inside negations
(line 12, line 186) — they explicitly contrast the current SDR
topology against the broken pre-C-4 shape so a reader who finds the
old vocabulary in git history understands what changed.

Verification: remote Vivado 2025.2 xsim → 15 / 15 PASS
(was 17 / 17; the lost 2 are Group 4's trivial-pass and existence
checks, both now subsumed by Groups 5 / 8).
This commit is contained in:
Jason
2026-05-05 13:48:30 +05:45
parent d6462c6d5b
commit ce869e9e20
+18 -62
View File
@@ -3,17 +3,18 @@
// ============================================================================
// tb_ad9484_xsim.v XSim testbench for ad9484_interface_400m.v
//
// Tests the REAL module with Xilinx UNISIM primitives (IBUFDS, BUFG, IDDR).
// Must be compiled with xvlog/xelab/xsim (not iverilog).
// Tests the REAL module with Xilinx UNISIM primitives (IBUFDS, BUFIO,
// BUFG, MMCME2_ADV). Must be compiled with xvlog/xelab/xsim (not iverilog).
//
// Key things tested:
// 1. Differential LVDS data capture (IBUFDS)
// 2. IDDR Q2 (falling-edge) data capture in SAME_EDGE_PIPELINED mode
// 2. Falling-DCO-edge IOB-packed IFF capture (post-AUDIT-C4 SDR shape;
// no IDDR, no rise/fall demux)
// 3. Reset synchronizer (P1-7 fix: async assert, sync de-assert)
// 4. Data integrity through full pipeline
// 5. AUDIT-C4: SDR-correctness every rising-DCO sample appears exactly
// once in the output stream (no duplications, no drops). Catches any
// future regression that reintroduces a DDR-style Q1/Q2 demux on this
// 5. AUDIT-C4: SDR-correctness every DCO period produces exactly one
// output sample (no duplications, no drops). Catches any future
// regression that reintroduces a DDR-style Q1/Q2 demux on this
// SDR-only chip.
// ============================================================================
@@ -112,7 +113,7 @@ module tb_ad9484_xsim;
// Stimulus
initial begin
$display("\n=== AD9484 Interface XSim Testbench ===");
$display(" Testing REAL Xilinx primitives (IBUFDS, BUFG, IDDR)");
$display(" Testing REAL Xilinx primitives (IBUFDS, BUFIO, BUFG, MMCME2)");
$display(" Testing reset synchronizer (P1-7 fix)\n");
// Init
@@ -180,60 +181,15 @@ module tb_ad9484_xsim;
end
//
// TEST GROUP 4: Data capture via IDDR
// TEST GROUP 4 RETIRED (F-7.3, PR-X.2)
//
$display("\n--- Test Group 4: IDDR Data Capture ---");
// Reset and restart
reset_n = 0;
adc_d_p = 8'h00;
#100;
reset_n = 1;
// F-7.4: every reset cycle re-arms the MMCM lock countdown, so
// wait for lock + sync drain before driving the test pattern.
wait_for_adc_ready();
// Feed a known pattern on rising edges
// IDDR in SAME_EDGE_PIPELINED mode captures:
// Q1 = data at rising edge (1 cycle pipelined)
// Q2 = data at falling edge (pipelined to align with Q1)
// The module alternates output between Q1 and Q2 via dco_phase
// Drive known data: alternate 0xAA on rise, 0x55 on fall
begin : iddr_test
reg [7:0] captured [0:31];
integer cap_count;
integer saw_aa, saw_55;
cap_count = 0;
saw_aa = 0;
saw_55 = 0;
for (i = 0; i < 20; i = i + 1) begin
// Set data before rising edge
adc_d_p = 8'hAA;
@(posedge adc_dco_p);
// Set data before falling edge
#0.1;
adc_d_p = 8'h55;
@(negedge adc_dco_p);
#0.1;
// Capture output
if (adc_data_valid_400m && cap_count < 32) begin
captured[cap_count] = adc_data_400m;
if (adc_data_400m == 8'hAA) saw_aa = saw_aa + 1;
if (adc_data_400m == 8'h55) saw_55 = saw_55+ 1;
cap_count = cap_count + 1;
end
end
$display(" Captured %0d samples, saw 0xAA: %0d times, 0x55: %0d times",
cap_count, saw_aa, saw_55);
check(cap_count > 0, "IDDR produces output samples");
// With DDR capture, we should see both rise and fall data
check(saw_aa > 0 || saw_55 > 0, "IDDR captures at least one known value");
end
// Was a "data capture via IDDR" test that drove 0xAA on rising
// DCO and 0x55 on falling DCO. After AUDIT-C4 the IFF only
// captures the falling edge (SDR), so all outputs were 0x55
// and the assertion `saw_aa > 0 || saw_55 > 0` was trivially
// true. Group 5 (sequential integrity) and Group 8 (SDR ramp,
// AUDIT-C4) are strictly stronger and remain the load-bearing
// checks. Group numbering preserved for git-blame continuity.
//
// TEST GROUP 5: Sequential data integrity
@@ -314,8 +270,8 @@ module tb_ad9484_xsim;
// held stable across the full DCO period. We model that by
// launching a new counter value just after each rising DCO
// edge (~tPD = 0.85 ns) and holding it stable. The interface
// captures Q2 of the IDDR (falling-edge, in the stable window)
// and re-registers into BUFG output.
// captures the IOB-packed IFF on the falling DCO edge (mid
// stable window) and re-registers into BUFG output.
//
// Correctness invariant: once the pipeline fills, the output
// stream must increment by exactly 1 per BUFG cycle no