mirror of
https://github.com/NawfalMotii79/PLFM_RADAR.git
synced 2026-06-10 23:41:18 +00:00
AUDIT-S19/S20/S21: replace fpga_self_test tautologies with real arithmetic
Pre-fix Tests 1/2/4 in fpga_self_test.v gave false PASS even on broken
silicon:
S-19 Test 1 (CIC): `result_flags[1] <= 1'b1` unconditional, comment
admitted "always true for simple check".
S-20 Test 2 (FFT): `(16'sd100+16'sd100 == 16'sd200) && (...)` —
both predicates compile-time-fold to 1; synth reduces to a
constant write.
S-21 Test 4 (ADC): PASS once N samples land, regardless of value.
A stuck-at-0 / stuck-at-MAX / dead LVDS link still PASSed
provided adc_valid_in toggled.
Fixes:
Test 1: drive impulse {5,0,0,0,0,0,0} through registered integrator
y[n]=y[n-1]+x[n]; require accumulator==5 after step
response. Real adder + register path; sign-extension
exercised. Detail = 0xC1 on fail.
Test 2: real radix-2 butterfly with twiddle multiply across 4 FSM
states. A=8, B=4 (real), W=2+3j -> WB=(8,12), A'=(16,12),
B'=(0,-12). Forces synth to instantiate signed multiplier
(DSP slice) + 17-bit signed add/sub. Detail = 0xF2 on fail.
Test 4: track min/max across 256-sample capture, require
(max - min) > ADC_RANGE_THRESHOLD (10 LSB). Catches stuck-at
faults. Does NOT distinguish AD9484 format mismatches
(audit's per-mode mean check requires SPI, impossible per
AUDIT-C13). Detail = 0xAD on fail.
Tests:
- tb_fpga_self_test.v existing Group 1-4 (16 PASS) still pass: varied
ADC counter input gives range >> 10.
- New Group 5: drive constant 0 -> expect Test 4 FAIL + detail=0xAD.
- New Group 6: drive constant 0x7FFF -> expect Test 4 FAIL + detail=0xAD.
- Regression: 41/41 PASS; fpga_self_test 22/22 (was 16/16).
This commit is contained in:
@@ -77,8 +77,12 @@ task check;
|
||||
end
|
||||
endtask
|
||||
|
||||
// ADC data generator: provides synthetic samples when capture is active
|
||||
// ADC data generator: provides synthetic samples when capture is active.
|
||||
// `adc_stuck_mode` (driven from main test) forces every sample to a constant
|
||||
// value, exercising the AUDIT-S21 stuck-at detection path.
|
||||
reg [15:0] adc_sample_cnt;
|
||||
reg adc_stuck_mode; // 1 = drive constant adc_stuck_value
|
||||
reg [15:0] adc_stuck_value;
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
adc_data_in <= 16'd0;
|
||||
@@ -89,7 +93,8 @@ always @(posedge clk or negedge reset_n) begin
|
||||
// Provide a new ADC sample every 4 cycles (simulating 25 MHz sample rate)
|
||||
adc_sample_cnt <= adc_sample_cnt + 1;
|
||||
if (adc_sample_cnt[1:0] == 2'b11) begin
|
||||
adc_data_in <= adc_sample_cnt[15:0];
|
||||
adc_data_in <= adc_stuck_mode ? adc_stuck_value
|
||||
: adc_sample_cnt[15:0];
|
||||
adc_valid_in <= 1'b1;
|
||||
end else begin
|
||||
adc_valid_in <= 1'b0;
|
||||
@@ -123,7 +128,9 @@ initial begin
|
||||
pass_count = 0;
|
||||
fail_count = 0;
|
||||
|
||||
trigger = 0;
|
||||
trigger = 0;
|
||||
adc_stuck_mode = 1'b0;
|
||||
adc_stuck_value = 16'd0;
|
||||
|
||||
$display("");
|
||||
$display("============================================================");
|
||||
@@ -221,6 +228,68 @@ initial begin
|
||||
check("Re-trigger completes", result_valid);
|
||||
check("All pass on re-run", result_flags == 5'b11111);
|
||||
|
||||
// =====================================================================
|
||||
// Group 5: AUDIT-S21 — stuck-at ADC must FAIL Test 4
|
||||
// =====================================================================
|
||||
// Pre-fix Test 4 set result_flags[4] <= 1'b1 once N samples landed,
|
||||
// regardless of value. Drive a constant ADC sample (stuck-at-0) and
|
||||
// verify Test 4 now FAILs with result_detail == 0xAD.
|
||||
$display("");
|
||||
$display("--- Group 5: ADC Stuck-At Detection (AUDIT-S21) ---");
|
||||
|
||||
adc_stuck_mode = 1'b1;
|
||||
adc_stuck_value = 16'd0;
|
||||
repeat (10) @(posedge clk);
|
||||
@(posedge clk);
|
||||
trigger = 1;
|
||||
@(posedge clk);
|
||||
trigger = 0;
|
||||
|
||||
begin : wait_for_done3
|
||||
integer i;
|
||||
for (i = 0; i < 5000; i = i + 1) begin
|
||||
@(posedge clk);
|
||||
if (result_valid) begin
|
||||
i = 5000;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
check("Stuck ADC: result_valid", result_valid);
|
||||
check("Stuck ADC: Tests 0-3 pass", result_flags[3:0] == 4'b1111);
|
||||
check("Stuck ADC: Test 4 FAILS", !result_flags[4]);
|
||||
check("Stuck ADC: detail=0xAD", result_detail == 8'hAD);
|
||||
|
||||
// =====================================================================
|
||||
// Group 6: AUDIT-S21 — stuck-at-MAX (different stuck value) must also FAIL
|
||||
// =====================================================================
|
||||
$display("");
|
||||
$display("--- Group 6: ADC Stuck-At-MAX Detection (AUDIT-S21) ---");
|
||||
|
||||
adc_stuck_mode = 1'b1;
|
||||
adc_stuck_value = 16'h7FFF; // stuck high
|
||||
repeat (10) @(posedge clk);
|
||||
@(posedge clk);
|
||||
trigger = 1;
|
||||
@(posedge clk);
|
||||
trigger = 0;
|
||||
|
||||
begin : wait_for_done4
|
||||
integer i;
|
||||
for (i = 0; i < 5000; i = i + 1) begin
|
||||
@(posedge clk);
|
||||
if (result_valid) begin
|
||||
i = 5000;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
check("Stuck-MAX: Test 4 FAILS", !result_flags[4]);
|
||||
check("Stuck-MAX: detail=0xAD", result_detail == 8'hAD);
|
||||
|
||||
// Restore varied-sample mode
|
||||
adc_stuck_mode = 1'b0;
|
||||
|
||||
// =====================================================================
|
||||
// Summary
|
||||
// =====================================================================
|
||||
|
||||
Reference in New Issue
Block a user