PR-AB.b expanded commit 2: TB cleanup (modes/range/counters strip)

Restore regression to green after commit 1's RTL strip. Drop dead-signal
references from 10 TBs to match the post-strip RTL surface:

- chirp TBs: drop clk_100m / reset_100m_n / new_elevation / new_azimuth
  port wiring on plfm_chirp_controller_v2; drop elevation/azimuth counter
  wires + check() assertions; retire Group 9 (Beam steering counters) in
  tb_chirp_controller and C3 (stm32 toggle non-drive) in tb_chirp_contract.
- system TBs: drop stm32_new_chirp / stm32_new_elevation / stm32_new_azimuth
  regs + DUT port wiring; drop current_elevation / current_azimuth wires;
  delete stm32_chirp_toggle helper task; retire G6.1 (radar_mode opcode
  0x01), G6.6 (trigger_pulse opcode 0x02), G7.1 (STM32->FPGA chirp CDC
  stress), and G14.1/.2/.3 (range_mode opcode 0x20) test groups; replace
  stm32_chirp_toggle calls in G2 with passive waits (scheduler auto-scans).
- receiver TB: drop .host_mode / .host_range_mode / .host_trigger ties.
- usb TBs: drop status_radar_mode / status_range_mode regs + DUT port
  wiring + apply_reset init + per-test setup; update word[4][1:0] expected
  value from 2'b10 (range_mode=2) to 2'b00 (now reserved) in
  tb_usb_data_interface; refresh T3.7 comment in tb_usb_protocol_v2
  (assertion value 0x60 unchanged because range_mode was already 2'd0).
- adc pwdn TB: strip host_radar_mode dummy reg + opcode 0x01 dispatch from
  the local dispatch_block mirror; rewrite T5 with unknown opcode 0x05 to
  preserve the dispatch-isolation case after 0x01 retirement.

Regression: 42/0/0 (was 37/0/6 in the pre-strip baseline where scipy was
unavailable; with radar_venv on PATH all 42 phases run and pass).
This commit is contained in:
Jason
2026-05-11 11:02:26 +05:45
parent 1b2a21d55b
commit 0da5ac6eaa
10 changed files with 43 additions and 182 deletions
+13 -10
View File
@@ -27,9 +27,11 @@
// (so a future expansion to a multi-bit ADC control field can repurpose
// upper bits without breaking back-compat).
//
// T5: Unrelated opcodes (0x33 = host_adc_format, 0x01 = radar_mode) do
// NOT disturb host_adc_pwdn — opcode dispatch is properly mutually
// exclusive.
// T5: Unrelated opcodes (0x33 = host_adc_format, and an unknown opcode)
// do NOT disturb host_adc_pwdn — opcode dispatch is properly mutually
// exclusive. (Opcode 0x01 = radar_mode was retired in PR-AB.b
// expanded; an unknown opcode now stands in for the second isolation
// case.)
//
// T6: Without cmd_valid_100m, opcode bus changes alone do NOT update
// host_adc_pwdn — the dispatcher only acts on validated commands.
@@ -147,9 +149,11 @@ module tb_adc_pwdn_opcode;
issue_opcode(8'h33, 32'h0000_0001);
check(host_adc_pwdn === 1'b1, "T5: opcode 0x33 doesn't disturb host_adc_pwdn");
check(host_adc_format === 2'b01, "T5: opcode 0x33 updates host_adc_format independently");
// Issue opcode 0x01 (radar_mode) must NOT touch host_adc_pwdn.
issue_opcode(8'h01, 32'h0000_0002);
check(host_adc_pwdn === 1'b1, "T5: opcode 0x01 doesn't disturb host_adc_pwdn");
// Issue an unknown opcode (0x05) must NOT touch host_adc_pwdn.
// PR-AB.b expanded retired opcode 0x01 (radar_mode); use an unknown
// opcode instead to still cover the dispatch-isolation case.
issue_opcode(8'h05, 32'h0000_0002);
check(host_adc_pwdn === 1'b1, "T5: unknown opcode 0x05 doesn't disturb host_adc_pwdn");
// ---------- T6: opcode bus changes without cmd_valid_100m don't latch ----------
// Snap state, drive opcode/value but withhold cmd_valid_100m.
@@ -207,18 +211,17 @@ module dispatch_block (
output reg [1:0] host_adc_format
);
// Dummy reg for opcode 0x01 (radar_mode) exercised only by T5.
reg [1:0] host_radar_mode;
// Unknown-opcode placeholder for T5 (dispatch isolation): opcode 0x05 is
// not a recognized opcode in production, so issuing it must not touch
// host_adc_pwdn or host_adc_format.
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
host_adc_pwdn <= 1'b0;
host_adc_format <= 2'b00;
host_radar_mode <= 2'b00;
end else begin
if (cmd_valid_100m) begin
case (usb_cmd_opcode)
8'h01: host_radar_mode <= usb_cmd_value[1:0];
8'h32: host_adc_pwdn <= usb_cmd_value[0];
8'h33: host_adc_format <= usb_cmd_value[1:0];
default: ;
+4 -20
View File
@@ -38,7 +38,6 @@ reg mixers_enable;
reg dst_chirp_valid;
reg [1:0] dst_wave_sel;
reg frame_pulse_120m;
reg new_elevation, new_azimuth;
// DUT outputs (subset — only those used in the contract checks)
wire [7:0] chirp_data;
@@ -53,7 +52,6 @@ wire adar_tx_load_4, adar_rx_load_4;
wire adar_tr_1, adar_tr_2, adar_tr_3, adar_tr_4;
wire new_chirp_frame;
wire [5:0] chirp_counter;
wire [5:0] elevation_counter, azimuth_counter;
// 120 MHz: period = 8.333 ns
initial clk_120m = 0;
@@ -66,15 +64,11 @@ always #5 clk_100m = ~clk_100m;
// ---- DUT ----
plfm_chirp_controller_v2 dut (
.clk_120m(clk_120m),
.clk_100m(clk_100m),
.reset_n(reset_n),
.reset_100m_n(reset_100m_n),
.mixers_enable(mixers_enable),
.dst_chirp_valid(dst_chirp_valid),
.dst_wave_sel(dst_wave_sel),
.frame_pulse_120m(frame_pulse_120m),
.new_elevation(new_elevation),
.new_azimuth(new_azimuth),
.chirp_data(chirp_data),
.chirp_valid(chirp_valid),
.new_chirp_frame(new_chirp_frame),
@@ -94,9 +88,7 @@ plfm_chirp_controller_v2 dut (
.adar_tr_2(adar_tr_2),
.adar_tr_3(adar_tr_3),
.adar_tr_4(adar_tr_4),
.chirp_counter(chirp_counter),
.elevation_counter(elevation_counter),
.azimuth_counter(azimuth_counter)
.chirp_counter(chirp_counter)
);
// ---- Test infrastructure ----
@@ -194,8 +186,6 @@ initial begin
dst_chirp_valid = 0;
dst_wave_sel = `RP_WAVE_SHORT;
frame_pulse_120m = 0;
new_elevation = 0;
new_azimuth = 0;
$display("");
$display("============================================================");
@@ -225,15 +215,9 @@ initial begin
wait_for_idle(SHORT_SAMPLES + 20);
check("C5/C6: chirp_counter == 2 after second SHORT chirp", chirp_counter == 6'd2);
// ---------- C3: stm32 toggles do NOT drive chirp_counter ----------
repeat (8) begin
new_elevation = ~new_elevation;
new_azimuth = ~new_azimuth;
@(posedge clk_100m);
end
new_elevation = 0;
new_azimuth = 0;
check("C3: stm32 toggles do not change chirp_counter", chirp_counter == 6'd2);
// C3 (chirp_counter increments only on clk_120m edges) is now structurally
// upheld by the RTL: post PR-AB.b expanded strip there is no stm32_new_*
// input on the clk_100m side that could spuriously drive the counter.
// ---------- C7: frame_pulse wraps to 0 ----------
pulse_frame();
+1 -32
View File
@@ -12,7 +12,6 @@
// active during CHIRP, deassert after
// - chirp_counter increments per chirp and clears on frame_pulse_120m
// - mixer enables: tx_mixer_en active during CHIRP, rx_mixer_en otherwise
// - elevation_counter / azimuth_counter still bump on STM32 toggles
//
// Sample counts (must mirror plfm_chirp_controller_v2.v localparams):
// SHORT = 120, MEDIUM = 600, LONG = 3600
@@ -47,8 +46,6 @@ reg mixers_enable;
reg dst_chirp_valid;
reg [1:0] dst_wave_sel;
reg frame_pulse_120m;
reg new_elevation;
reg new_azimuth;
wire [7:0] chirp_data;
wire chirp_valid;
@@ -62,23 +59,17 @@ wire adar_tx_load_3, adar_rx_load_3;
wire adar_tx_load_4, adar_rx_load_4;
wire adar_tr_1, adar_tr_2, adar_tr_3, adar_tr_4;
wire [5:0] chirp_counter;
wire [5:0] elevation_counter;
wire [5:0] azimuth_counter;
// =========================================================================
// DUT
// =========================================================================
plfm_chirp_controller_v2 dut (
.clk_120m(clk_120m),
.clk_100m(clk_100m),
.reset_n(reset_n),
.reset_100m_n(reset_100m_n),
.mixers_enable(mixers_enable),
.dst_chirp_valid(dst_chirp_valid),
.dst_wave_sel(dst_wave_sel),
.frame_pulse_120m(frame_pulse_120m),
.new_elevation(new_elevation),
.new_azimuth(new_azimuth),
.chirp_data(chirp_data),
.chirp_valid(chirp_valid),
.new_chirp_frame(new_chirp_frame),
@@ -98,9 +89,7 @@ plfm_chirp_controller_v2 dut (
.adar_tr_2(adar_tr_2),
.adar_tr_3(adar_tr_3),
.adar_tr_4(adar_tr_4),
.chirp_counter(chirp_counter),
.elevation_counter(elevation_counter),
.azimuth_counter(azimuth_counter)
.chirp_counter(chirp_counter)
);
// =========================================================================
@@ -179,8 +168,6 @@ initial begin
dst_chirp_valid = 0;
dst_wave_sel = `RP_WAVE_SHORT;
frame_pulse_120m = 0;
new_elevation = 0;
new_azimuth = 0;
$display("");
$display("============================================================");
@@ -199,8 +186,6 @@ initial begin
check("Reset: rf_switch_ctrl low", rf_switch_ctrl == 1'b0);
check("Reset: chirp_done low", chirp_done == 1'b0);
check("Reset: chirp_counter == 0", chirp_counter == 6'd0);
check("Reset: elevation_counter==1", elevation_counter == 6'd1);
check("Reset: azimuth_counter==1", azimuth_counter == 6'd1);
@(posedge clk_120m);
reset_n <= 1;
@@ -287,22 +272,6 @@ initial begin
check("Mixer disable: rx_mixer_en 0", rx_mixer_en == 1'b0);
check("Mixer disable: state forced IDLE", dut.state == 1'b0);
// ---------- Beam-step counters ----------
$display("--- Group 9: Beam steering counters ---");
new_elevation = 1;
@(posedge clk_100m);
@(posedge clk_100m);
check("Elevation: increments on toggle",
elevation_counter == 6'd2 || elevation_counter == 6'd3);
new_elevation = 0;
new_azimuth = 1;
@(posedge clk_100m);
@(posedge clk_100m);
check("Azimuth: increments on toggle",
azimuth_counter == 6'd2 || azimuth_counter == 6'd3);
new_azimuth = 0;
// ---------- ADAR load pins tied low ----------
$display("--- Group 10: ADAR load pins ---");
check("adar_tx_load_1 tied low", adar_tx_load_1 == 1'b0);
@@ -341,7 +341,6 @@ module tb_e2e_dsp_to_host;
.status_request (1'b0),
.status_cfar_threshold (16'd0),
.status_stream_ctrl (TEST_STREAM_CONTROL),
.status_radar_mode (2'd0),
.status_long_chirp (16'd0),
.status_long_listen (16'd0),
.status_guard (16'd0),
@@ -352,7 +351,6 @@ module tb_e2e_dsp_to_host;
.status_medium_chirp (16'd0),
.status_medium_listen (16'd0),
.status_chirps_per_elev (6'd0),
.status_range_mode (2'd0),
.status_chirps_mismatch (1'b0),
.status_self_test_flags (5'd0),
.status_self_test_detail (8'd0),
@@ -75,14 +75,12 @@ module tb_ft2232h_frame_drop;
reg status_request = 1'b0;
reg [15:0] status_cfar_threshold = 16'd0;
reg [5:0] status_stream_ctrl = 6'b000_000;
reg [1:0] status_radar_mode = 2'd0;
reg [15:0] status_long_chirp = 16'd0;
reg [15:0] status_long_listen = 16'd0;
reg [15:0] status_guard = 16'd0;
reg [15:0] status_short_chirp = 16'd0;
reg [15:0] status_short_listen = 16'd0;
reg [5:0] status_chirps_per_elev = 6'd0;
reg [1:0] status_range_mode = 2'd0;
reg status_chirps_mismatch = 1'b0;
reg [4:0] status_self_test_flags = 5'd0;
reg [7:0] status_self_test_detail = 8'd0;
@@ -131,7 +129,6 @@ module tb_ft2232h_frame_drop;
.status_request(status_request),
.status_cfar_threshold(status_cfar_threshold),
.status_stream_ctrl(status_stream_ctrl),
.status_radar_mode(status_radar_mode),
.status_long_chirp(status_long_chirp),
.status_long_listen(status_long_listen),
.status_guard(status_guard),
@@ -142,7 +139,6 @@ module tb_ft2232h_frame_drop;
.status_medium_chirp(16'd0),
.status_medium_listen(16'd0),
.status_chirps_per_elev(status_chirps_per_elev),
.status_range_mode(status_range_mode),
.status_chirps_mismatch(status_chirps_mismatch),
.status_self_test_flags(status_self_test_flags),
.status_self_test_detail(status_self_test_detail),
@@ -166,11 +166,6 @@ radar_receiver_final dut (
.range_profile_q_out(),
.range_profile_valid_out(),
// Host command inputs (Gap 4) — default auto-scan, no trigger
.host_mode(2'b01),
.host_range_mode(2'b01), // long-range mode (dual chirp); was missing -> z
.host_trigger(1'b0),
// chirp-v2 PR-D: chirp_scheduler is host-input driven. SHORT chirp bumped
// to 100 cycles (1 µs V2). Host_chirps_per_elev is still wired to keep
// the parent port list intact, but the scheduler inside the receiver
+12 -41
View File
@@ -14,12 +14,13 @@
// tb_e2e_dsp_to_host (PR-Z A6) end-to-end.
// G3 Safety architecture (TX/RX mixer mutual exclusion, ADC pwdn, ADAR TR,
// mixer-disable propagation)
// G7.1 Rapid chirp toggle CDC stress (100MHz STM32 -> 120MHz TX)
// G7.3 TX chirp counter CDC (120MHz -> 100MHz)
// — G7.1 (STM32→FPGA chirp toggle CDC stress) retired in PR-AB.b
// expanded; stm32_new_chirp port is gone.
//
// DUT is radar_system_top with USB_MODE=1 (production FT2232H path); the
// FT2232H ports are wired so a minimal opcode can be sent if needed (none
// are needed here — radar_mode defaults to 2'b00 STM32-driven).
// FT2232H ports are wired so a stream_control opcode (0x04) can be sent at
// start to give the USB write FSM a clean exit from IDLE.
// ============================================================================
module tb_system_mechanics;
@@ -51,9 +52,6 @@ reg reset_n = 1'b0;
reg [7:0] adc_d_p = 8'h80;
reg [7:0] adc_d_n = 8'h7F;
reg stm32_new_chirp = 1'b0;
reg stm32_new_elevation = 1'b0;
reg stm32_new_azimuth = 1'b0;
reg stm32_mixers_enable = 1'b0;
reg stm32_sclk_3v3 = 1'b0;
reg stm32_mosi_3v3 = 1'b0;
@@ -108,7 +106,7 @@ reg ft_data_drive_en = 1'b0;
assign ft_data = ft_data_drive_en ? ft_data_drive : 8'hzz;
pulldown pd[7:0] (ft_data);
wire [5:0] current_elevation, current_azimuth, current_chirp;
wire [5:0] current_chirp;
wire new_chirp_frame;
wire [31:0] dbg_doppler_data;
wire dbg_doppler_valid;
@@ -157,9 +155,6 @@ radar_system_top #(.USB_MODE(1)) dut (
.adc_or_p(1'b0), .adc_or_n(1'b1),
.adc_pwdn(adc_pwdn),
.stm32_new_chirp(stm32_new_chirp),
.stm32_new_elevation(stm32_new_elevation),
.stm32_new_azimuth(stm32_new_azimuth),
.stm32_mixers_enable(stm32_mixers_enable),
.ft601_data(ft601_data),
@@ -184,8 +179,6 @@ radar_system_top #(.USB_MODE(1)) dut (
.ft_oe_n(ft_oe_n),
.ft_siwu(ft_siwu),
.current_elevation(current_elevation),
.current_azimuth(current_azimuth),
.current_chirp(current_chirp),
.new_chirp_frame(new_chirp_frame),
.dbg_doppler_data(dbg_doppler_data),
@@ -198,16 +191,6 @@ radar_system_top #(.USB_MODE(1)) dut (
.gpio_dig7(gpio_dig7)
);
// ----------------------------------------------------------------------------
// Helper: STM32 chirp toggle (drives stm32_new_chirp edge)
// ----------------------------------------------------------------------------
task stm32_chirp_toggle;
begin
stm32_new_chirp = ~stm32_new_chirp;
#40; // hold 4 clk_100m cycles for edge detector
end
endtask
// ADC stimulus: ramp around mid-scale (matches tb_system_e2e pattern)
integer adc_phase;
initial begin
@@ -368,12 +351,11 @@ initial begin
stm32_mixers_enable = 1'b1;
#100;
// Fire one LONG chirp + 3 follow-ups so DAC, RF switch, and both mixers
// are exercised across TX (chirp) and RX (listen) phases.
stm32_chirp_toggle;
#40000; // 40 us — covers LONG_CHIRP -> LONG_LISTEN
// PR-AB.b expanded: scheduler auto-scans once mixers_enable=1 — no STM32
// chirp trigger needed. Wait long enough to observe DAC, RF switch, and
// both mixers exercised across TX (chirp) and RX (listen) phases.
#40000; // 40 us — covers initial LONG_CHIRP -> LONG_LISTEN
for (i = 0; i < 3; i = i + 1) begin
stm32_chirp_toggle;
#3000;
end
#5000;
@@ -412,21 +394,10 @@ initial begin
#100;
// ====================================================================
// GROUP 7.1 / 7.3: CDC CROSSING STRESS (G7.2/7.4 in tb_system_opcodes)
// GROUP 7.3: TX chirp counter CDC (G7.2/7.4 in tb_system_opcodes;
// G7.1 retired in PR-AB.b expanded — STM32→FPGA chirp CDC path removed)
// ====================================================================
$display("\n--- Group 7: CDC crossing stress ---");
// G7.1: rapid chirp toggles — verify DAC stays active (CDC delivered).
// host_radar_mode defaults to 2'b00 (STM32-driven) at reset, so toggles
// drive the TX directly without an opcode.
obs_dac_nonzero_count = 0;
for (i = 0; i < 10; i = i + 1) begin
stm32_chirp_toggle;
#500;
end
#20000;
check(obs_dac_nonzero_count > 0,
"G7.1: CDC delivered chirp toggles (DAC active after rapid toggles)");
$display("\n--- Group 7: TX chirp counter CDC (120 MHz -> 100 MHz) ---");
// G7.3: TX chirp counter CDC (120 MHz -> 100 MHz). Either the counter
// advanced or DAC was active long enough to prove the path is alive.
+6 -48
View File
@@ -46,9 +46,6 @@ reg [7:0] adc_d_p = 8'h80;
reg [7:0] adc_d_n = 8'h7F;
// STM32 control — tied off
reg stm32_new_chirp = 1'b0;
reg stm32_new_elevation = 1'b0;
reg stm32_new_azimuth = 1'b0;
reg stm32_mixers_enable = 1'b0;
reg stm32_sclk_3v3 = 1'b0;
reg stm32_mosi_3v3 = 1'b0;
@@ -110,7 +107,7 @@ assign ft_data = ft_data_drive_en ? ft_data_drive : 8'hzz;
pulldown pd[7:0] (ft_data);
// Status / debug outputs (mostly ignored)
wire [5:0] current_elevation, current_azimuth, current_chirp;
wire [5:0] current_chirp;
wire new_chirp_frame;
wire [31:0] dbg_doppler_data;
wire dbg_doppler_valid;
@@ -161,9 +158,6 @@ radar_system_top #(
.adc_or_p(1'b0), .adc_or_n(1'b1),
.adc_pwdn(adc_pwdn),
.stm32_new_chirp(stm32_new_chirp),
.stm32_new_elevation(stm32_new_elevation),
.stm32_new_azimuth(stm32_new_azimuth),
.stm32_mixers_enable(stm32_mixers_enable),
// FT601 ports — tied off / unused in USB_MODE=1
@@ -190,8 +184,6 @@ radar_system_top #(
.ft_oe_n(ft_oe_n),
.ft_siwu(ft_siwu),
.current_elevation(current_elevation),
.current_azimuth(current_azimuth),
.current_chirp(current_chirp),
.new_chirp_frame(new_chirp_frame),
.dbg_doppler_data(dbg_doppler_data),
@@ -254,13 +246,6 @@ integer pass_count = 0;
integer fail_count = 0;
integer test_num = 0;
// Sticky flag for G6.6 (host_trigger_pulse is a 1-cycle self-clearing pulse).
reg trigger_pulse_seen = 1'b0;
always @(posedge clk_100m) begin
if (!reset_n) trigger_pulse_seen <= 1'b0;
else if (dut.host_trigger_pulse) trigger_pulse_seen <= 1'b1;
end
task check;
input cond;
input [80*8-1:0] msg;
@@ -291,15 +276,11 @@ initial begin
wait_clk(50);
// ====================================================================
// GROUP 6: USB COMMAND DECODE (was tb_system_e2e G6)
// GROUP 6: USB COMMAND DECODE (was tb_system_e2e G6;
// G6.1 radar_mode / G6.6 trigger_pulse retired in PR-AB.b expanded)
// ====================================================================
$display("\n--- Group 6: USB Command Decode ---");
// G6.1: Set radar mode (opcode 0x01) -> host_radar_mode[1:0]
send_cmd(8'h01, 8'h00, 16'h0002);
check(dut.host_radar_mode == 2'b10,
"G6.1: 0x01 -> host_radar_mode = 2'b10 (single chirp)");
// G6.2: Set detection threshold (0x03) -> host_detect_threshold
send_cmd(8'h03, 8'h00, 16'h1234);
check(dut.host_detect_threshold == 16'h1234,
@@ -324,15 +305,6 @@ initial begin
check(dut.chirps_mismatch_error == 1'b0,
"G6.5b: chirps_mismatch_error clear when chirps==48");
// G6.6: Trigger pulse (0x02) — self-clearing, latches host_trigger_pulse
// for one clk_100m cycle. Capture via a flag set on rising edge.
@(posedge clk_100m);
send_cmd(8'h02, 8'h00, 16'h0000);
// host_trigger_pulse self-clears the cycle after; we observed it via
// a sticky flag (see below).
check(trigger_pulse_seen == 1'b1,
"G6.6: 0x02 trigger pulse observed");
// ====================================================================
// GROUP 7: USB COMMAND CDC INTEGRITY (was G7.2 / G7.4)
// ====================================================================
@@ -386,24 +358,10 @@ initial begin
"G13.8: Mismatch clears when restored to 48");
// ====================================================================
// GROUP 14: CFAR + RANGE-MODE OPCODES
// GROUP 14: CFAR OPCODES (G14.1/.2/.3 range_mode retired in PR-AB.b
// expanded — opcode 0x20 / host_range_mode are gone)
// ====================================================================
$display("\n--- Group 14: CFAR / Range-Mode Opcodes ---");
// G14.1: range_mode=0x01 (long-range)
send_cmd(8'h20, 8'h00, 16'h0001);
check(dut.host_range_mode == 2'b01,
"G14.1: 0x20 -> host_range_mode = 2'b01 (long-range)");
// G14.2: range_mode=0x02 (reserved, stored as-is)
send_cmd(8'h20, 8'h00, 16'h0002);
check(dut.host_range_mode == 2'b10,
"G14.2: 0x20 -> host_range_mode = 2'b10 (reserved)");
// G14.3: range_mode=0x00 (3 km)
send_cmd(8'h20, 8'h00, 16'h0000);
check(dut.host_range_mode == 2'b00,
"G14.3: 0x20 -> host_range_mode = 2'b00 (3 km)");
$display("\n--- Group 14: CFAR Opcodes ---");
// G14.4-5: CFAR guard cells (0x21)
send_cmd(8'h21, 8'h00, 16'h0004);
+3 -10
View File
@@ -62,14 +62,12 @@ module tb_usb_data_interface;
reg status_request;
reg [15:0] status_cfar_threshold;
reg [2:0] status_stream_ctrl;
reg [1:0] status_radar_mode;
reg [15:0] status_long_chirp;
reg [15:0] status_long_listen;
reg [15:0] status_guard;
reg [15:0] status_short_chirp;
reg [15:0] status_short_listen;
reg [5:0] status_chirps_per_elev;
reg [1:0] status_range_mode;
reg status_chirps_mismatch;
// Self-test status readback inputs
@@ -126,14 +124,12 @@ module tb_usb_data_interface;
.status_request (status_request),
.status_cfar_threshold (status_cfar_threshold),
.status_stream_ctrl (status_stream_ctrl),
.status_radar_mode (status_radar_mode),
.status_long_chirp (status_long_chirp),
.status_long_listen (status_long_listen),
.status_guard (status_guard),
.status_short_chirp (status_short_chirp),
.status_short_listen (status_short_listen),
.status_chirps_per_elev(status_chirps_per_elev),
.status_range_mode (status_range_mode),
.status_chirps_mismatch(status_chirps_mismatch),
// Self-test status readback
@@ -197,14 +193,12 @@ module tb_usb_data_interface;
status_request = 0;
status_cfar_threshold = 16'd10000;
status_stream_ctrl = 3'b111;
status_radar_mode = 2'b00;
status_long_chirp = 16'd3000;
status_long_listen = 16'd13700;
status_guard = 16'd17540;
status_short_chirp = 16'd50;
status_short_listen = 16'd17450;
status_chirps_per_elev = 6'd32;
status_range_mode = 2'b00;
status_chirps_mismatch = 1'b0;
status_self_test_flags = 5'b00000;
status_self_test_detail = 8'd0;
@@ -926,14 +920,12 @@ module tb_usb_data_interface;
// Set known status input values
status_cfar_threshold = 16'hABCD;
status_stream_ctrl = 3'b101;
status_radar_mode = 2'b01;
status_long_chirp = 16'd3000;
status_long_listen = 16'd13700;
status_guard = 16'd17540;
status_short_chirp = 16'd50;
status_short_listen = 16'd17450;
status_chirps_per_elev = 6'd32;
status_range_mode = 2'b10; // Long-range for status test
status_chirps_mismatch = 1'b1; // TX-G: exercise the new bit too
// Self-test status: all 5 tests passed, detail=0xA5, not busy
status_self_test_flags = 5'b11111;
@@ -978,8 +970,9 @@ module tb_usb_data_interface;
"Status readback: word 2 = {guard, short_chirp}");
check(uut.status_words[3] === {16'd17450, 10'd0, 6'd32},
"Status readback: word 3 = {short_listen, 0, chirps_per_elev}");
check(uut.status_words[4] === {4'd5, 8'd180, 8'd12, 1'b1, 1'b1, 8'd0, 2'b10},
"Status readback: word 4 = {agc_gain=5, peak=180, sat=12, en=1, mismatch=1, range_mode=2}");
// PR-AB.b expanded: status_words[4][1:0] formerly range_mode, now reserved 2'd0.
check(uut.status_words[4] === {4'd5, 8'd180, 8'd12, 1'b1, 1'b1, 8'd0, 2'b00},
"Status readback: word 4 = {agc_gain=5, peak=180, sat=12, en=1, mismatch=1, reserved=0}");
// status_words[5] = {7'd0, busy, 8'd0, detail[7:0], 3'd0, flags[4:0]}
// = {7'd0, 1'b0, 8'd0, 8'hA5, 3'd0, 5'b11111}
check(uut.status_words[5] === {7'd0, 1'b0, 8'd0, 8'hA5, 3'd0, 5'b11111},
+4 -10
View File
@@ -73,7 +73,6 @@ module tb_usb_protocol_v2;
// Status inputs (mostly tied off; PR-G additions below)
reg status_request = 1'b0;
reg [15:0] status_cfar_threshold = 16'h1234;
reg [1:0] status_radar_mode = 2'd0;
reg [15:0] status_long_chirp = 16'd0;
reg [15:0] status_long_listen = 16'd0;
reg [15:0] status_guard = 16'd0;
@@ -84,7 +83,6 @@ module tb_usb_protocol_v2;
reg [15:0] status_medium_chirp = 16'd`RP_DEF_MEDIUM_CHIRP_CYCLES;
reg [15:0] status_medium_listen = 16'd`RP_DEF_MEDIUM_LISTEN_CYCLES;
reg [5:0] status_chirps_per_elev = 6'd0;
reg [1:0] status_range_mode = 2'd0;
reg status_chirps_mismatch = 1'b0;
reg [4:0] status_self_test_flags = 5'd0;
reg [7:0] status_self_test_detail = 8'd0;
@@ -140,7 +138,6 @@ module tb_usb_protocol_v2;
.status_request(status_request),
.status_cfar_threshold(status_cfar_threshold),
.status_stream_ctrl(status_stream_ctrl),
.status_radar_mode(status_radar_mode),
.status_long_chirp(status_long_chirp),
.status_long_listen(status_long_listen),
.status_guard(status_guard),
@@ -150,7 +147,6 @@ module tb_usb_protocol_v2;
.status_medium_chirp(status_medium_chirp),
.status_medium_listen(status_medium_listen),
.status_chirps_per_elev(status_chirps_per_elev),
.status_range_mode(status_range_mode),
.status_chirps_mismatch(status_chirps_mismatch),
.status_self_test_flags(status_self_test_flags),
.status_self_test_detail(status_self_test_detail),
@@ -297,12 +293,10 @@ module tb_usb_protocol_v2;
check_b("T3.4: status_words[6] count_cand[7:0]=42", egress_bytes[26] == 8'd42);
check_b("T3.5: status_words[6] thr_soft[15:8]=0x0A", egress_bytes[27] == 8'h0A);
check_b("T3.6: status_words[6] thr_soft[7:0]=0xBC", egress_bytes[28] == 8'hBC);
// alpha_soft (0x18) packed into word[4][9:2] → byte at index 19,20
// word[4] = {gain[3:0], peak[7:0], sat[7:0], en, mismatch, alpha_soft[7:0], range_mode[1:0]}
// bits[9:2] = alpha_soft. byte[19] = word[4][15:8], byte[20] = word[4][7:0]
// alpha_soft sits in byte[20][7:2] | byte[19][1:0] — let's just check mid bytes are non-zero
// when alpha_soft=0x18 (b0001_1000): bits[9:2] of word[4] = 8'h18, so:
// word[4][7:0] = {alpha_soft[7:0], range_mode[1:0]} = {8'h18, 2'b00} = 8'h60
// alpha_soft (0x18) packed into word[4][9:2] → byte at index 19,20.
// PR-AB.b expanded: word[4][1:0] formerly range_mode, now reserved 2'd0.
// word[4] = {gain[3:0], peak[7:0], sat[7:0], en, mismatch, alpha_soft[7:0], 2'd0}
// When alpha_soft=0x18: word[4][7:0] = {8'h18, 2'b00} = 8'h60.
check_b("T3.7: status_words[4][7:0] = alpha_soft<<2 = 0x60 (alpha=0x18)",
egress_bytes[20] == 8'h60);
// M-5: status_words[7] = {medium_chirp, medium_listen}.