mirror of
https://github.com/NawfalMotii79/PLFM_RADAR.git
synced 2026-06-08 14:44:56 +00:00
PR-AB.b expanded commit 1: RTL strip (dead modes + counters + range_mode)
Flatten chirp_scheduler.v to single-FSM auto-scan. Mode 00 (STM32 pass-through), mode 10 (single-chirp debug) and mode 11 (track dwell) FSM branches were all half-implemented and unreachable in production: MCU dispatcher was deleted in F-2.1; mode 11 inputs were tied to constants in radar_receiver_final; mode 10 debug_wave_sel was hardcoded to SHORT. The case-switch wrapper, watchdog, effective_mode mux, and all host_track_* / host_debug_wave_sel / host_trigger plumbing are removed. Strip host_radar_mode (opcode 0x01), host_trigger_pulse (opcode 0x02), and host_range_mode (opcode 0x20). The mode register had no consumer after the single-mode flatten; the range_mode register was already write-only telemetry (declared as input in radar_receiver_final but never read). The runtime 3km vs 20km presentation on a 200T build is driven by host_subframe_enable (0x19) + per-waveform chirp/listen cycles (0x10-0x18) — no separate mode field needed. Strip stm32_new_elevation / stm32_new_azimuth GPIOs and the elevation_counter / azimuth_counter regs in plfm_chirp_controller_v2. The FPGA-side counters had no consumer (status pack never carried them; on 50T they went to _nc; on 200T to unconstrained outputs). MCU software counters n/y reach the GUI via USB-CDC on a separate channel. USB status word 0 bits [23:22] (was radar_mode) and word 4 bits [1:0] (was range_mode) are now reserved zeros — host parser keeps the same byte offsets. Files modified: chirp_scheduler.v - flatten to single FSM (~155 LOC delta) plfm_chirp_controller_v2.v - strip counter blocks + ports radar_transmitter.v - strip elev/azim CDC + edge detectors + ports radar_receiver_final.v - strip host_mode/range_mode/trigger + STM32 toggle ports radar_system_top.v - strip regs, opcodes 0x01/0x02/0x20, status_*_mode wiring, top-level ports radar_system_top_50t.v - strip _nc wires + stm32_new_elev/azim + tie-offs radar_system_top_te0713_umft601x_dev.v - strip status_radar_mode/range_mode ties usb_data_interface.v - drop status_*_mode ports, reserve word 0 [23:22] + word 4 [1:0] usb_data_interface_ft2232h.v - same as above radar_params.vh - strip RP_MODE_* / RP_RANGE_MODE_* / RP_OP_RADAR_MODE / RP_OP_TRIGGER_PULSE / RP_OP_RANGE_MODE / RP_DEF_TRACK_* Regression will fail at this commit due to TB references to deleted signals (host_radar_mode, status_range_mode, etc.) — TB cleanup follows in commit 2.
This commit is contained in:
@@ -3,32 +3,26 @@
|
||||
`include "radar_params.vh"
|
||||
|
||||
/**
|
||||
* chirp_scheduler.v (chirp-v2 PR-D, replaces radar_mode_controller.v)
|
||||
* chirp_scheduler.v
|
||||
*
|
||||
* Single source of truth for waveform identity and inter-chirp timing on the
|
||||
* RX side. Drives `wave_sel[1:0]` and `chirp_pulse` natively; downstream
|
||||
* modules (chirp_reference_rom, matched_filter_multi_segment, mti_canceller)
|
||||
* consume those without 1-bit shims.
|
||||
*
|
||||
* Operating modes (host_radar_mode, opcode 0x01):
|
||||
* 2'b00 STM32 pass-through STM32 owns chirp timing; we follow stm32_*
|
||||
* toggles and announce the wave_sel that matches
|
||||
* the current sub-frame index.
|
||||
* 2'b01 Auto-scan Internal FSM cycles SHORT, MEDIUM, LONG sub-
|
||||
* frames in order (host_subframe_enable masks
|
||||
* individual waveforms out without recompiling).
|
||||
* Each sub-frame fires `host_chirps_per_subframe`
|
||||
* chirps at the per-waveform timing.
|
||||
* 2'b10 Single-chirp debug One chirp per host_trigger pulse, waveform
|
||||
* from host_debug_wave_sel.
|
||||
* 2'b11 Track Host-cued dwell on one beam + one waveform
|
||||
* for host_track_chirp_count chirps. A watchdog
|
||||
* falls back to mode 01 after
|
||||
* RP_DEF_TRACK_WATCHDOG_FRAMES idle frames so a
|
||||
* USB-yank does not silently drop coverage.
|
||||
* Operation: FPGA-paced auto-scan over the enabled sub-frames (SHORT, MEDIUM,
|
||||
* LONG). `host_subframe_enable[2:0]` masks individual waveforms out without
|
||||
* recompiling. Each sub-frame fires `host_chirps_per_subframe` chirps at the
|
||||
* per-waveform chirp/listen-cycle setpoints.
|
||||
*
|
||||
* The legacy multi-mode field (STM32 pass-through / single-chirp debug /
|
||||
* track dwell) was retired in PR-AB.b expanded (2026-05-11). All three
|
||||
* dead branches plus their host_* inputs (host_mode, host_trigger,
|
||||
* host_debug_wave_sel, host_track_*) and the track watchdog were stripped
|
||||
* — see project_aeris10_mode_strip_2026-05-11.md for rationale.
|
||||
*
|
||||
* Pulse outputs (chirp_pulse, subframe_pulse, frame_pulse) are 1-cycle
|
||||
* positive pulses, not toggles. The legacy mc_new_*-style toggles are gone.
|
||||
* positive pulses, not toggles.
|
||||
*
|
||||
* Clock domain: clk (100 MHz), async-low reset.
|
||||
*/
|
||||
@@ -37,8 +31,7 @@ module chirp_scheduler (
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
|
||||
// Top-level mode and 3-bit sub-frame enable mask (LONG|MEDIUM|SHORT)
|
||||
input wire [1:0] host_mode,
|
||||
// 3-bit sub-frame enable mask (LONG|MEDIUM|SHORT)
|
||||
input wire [2:0] host_subframe_enable,
|
||||
|
||||
// 3-ladder timing (100 MHz cycles). host_*_listen sums with host_guard
|
||||
@@ -55,22 +48,6 @@ module chirp_scheduler (
|
||||
// Frame structure (chirps per Doppler sub-frame, default 16)
|
||||
input wire [5:0] host_chirps_per_subframe,
|
||||
|
||||
// Single-chirp debug (mode 10)
|
||||
input wire host_trigger,
|
||||
input wire [1:0] host_debug_wave_sel,
|
||||
|
||||
// Track mode (mode 11)
|
||||
input wire host_track_request,
|
||||
input wire [1:0] host_track_wave_sel,
|
||||
input wire [8:0] host_track_chirp_count,
|
||||
input wire [5:0] host_track_beam_az,
|
||||
input wire [5:0] host_track_beam_el,
|
||||
|
||||
// STM32 pass-through (mode 00) toggle inputs (CDC-synced upstream)
|
||||
input wire stm32_new_chirp,
|
||||
input wire stm32_new_subframe,
|
||||
input wire stm32_new_frame,
|
||||
|
||||
// Master enable (PR-E). When low, the scheduler holds in S_IDLE and
|
||||
// emits no chirp_pulse — the FSM resumes on the next clock edge after
|
||||
// mixers_enable returns high. Keeps the radar quiet between operator
|
||||
@@ -89,45 +66,9 @@ module chirp_scheduler (
|
||||
// Currently selected timing for the in-flight chirp (PR-E TX async FIFO)
|
||||
output wire [15:0] cfg_chirp_cycles,
|
||||
output wire [15:0] cfg_listen_cycles,
|
||||
output wire [15:0] cfg_guard_cycles,
|
||||
|
||||
// Track-mode beam pointer (latched on host_track_request rising edge)
|
||||
output reg track_mode_active,
|
||||
output reg [5:0] track_beam_az,
|
||||
output reg [5:0] track_beam_el
|
||||
output wire [15:0] cfg_guard_cycles
|
||||
);
|
||||
|
||||
// ============================================================================
|
||||
// Edge / pulse detection on async inputs
|
||||
// ============================================================================
|
||||
reg trigger_prev;
|
||||
reg track_request_prev;
|
||||
reg stm32_new_chirp_prev;
|
||||
reg stm32_new_subframe_prev;
|
||||
reg stm32_new_frame_prev;
|
||||
|
||||
wire trigger_pulse = host_trigger & ~trigger_prev;
|
||||
wire track_request_pulse = host_track_request & ~track_request_prev;
|
||||
wire stm32_chirp_edge = stm32_new_chirp ^ stm32_new_chirp_prev;
|
||||
wire stm32_subframe_edge = stm32_new_subframe ^ stm32_new_subframe_prev;
|
||||
wire stm32_frame_edge = stm32_new_frame ^ stm32_new_frame_prev;
|
||||
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
trigger_prev <= 1'b0;
|
||||
track_request_prev <= 1'b0;
|
||||
stm32_new_chirp_prev <= 1'b0;
|
||||
stm32_new_subframe_prev <= 1'b0;
|
||||
stm32_new_frame_prev <= 1'b0;
|
||||
end else begin
|
||||
trigger_prev <= host_trigger;
|
||||
track_request_prev <= host_track_request;
|
||||
stm32_new_chirp_prev <= stm32_new_chirp;
|
||||
stm32_new_subframe_prev <= stm32_new_subframe;
|
||||
stm32_new_frame_prev <= stm32_new_frame;
|
||||
end
|
||||
end
|
||||
|
||||
// ============================================================================
|
||||
// Sub-frame helpers — pure functions of (subframe, mask)
|
||||
// ============================================================================
|
||||
@@ -169,39 +110,6 @@ function [1:0] subframe_to_wave;
|
||||
end
|
||||
endfunction
|
||||
|
||||
// ============================================================================
|
||||
// Track watchdog — count frames since last host_track_request rising edge.
|
||||
// effective_mode collapses to scan once the watchdog expires so a USB stall
|
||||
// does not silently freeze coverage on one beam.
|
||||
// ============================================================================
|
||||
reg [7:0] track_idle_frames;
|
||||
wire watchdog_expired = (track_idle_frames >= `RP_DEF_TRACK_WATCHDOG_FRAMES);
|
||||
|
||||
wire [1:0] effective_mode = (host_mode == `RP_MODE_TRACK && watchdog_expired)
|
||||
? `RP_MODE_AUTO_3KM
|
||||
: host_mode;
|
||||
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
track_idle_frames <= 8'd0;
|
||||
end else if (track_request_pulse) begin
|
||||
track_idle_frames <= 8'd0;
|
||||
end else if (frame_pulse && track_idle_frames != 8'hFF) begin
|
||||
track_idle_frames <= track_idle_frames + 8'd1;
|
||||
end
|
||||
end
|
||||
|
||||
// Latch beam pointer at the start of every track dwell.
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
track_beam_az <= 6'd0;
|
||||
track_beam_el <= 6'd0;
|
||||
end else if (track_request_pulse) begin
|
||||
track_beam_az <= host_track_beam_az;
|
||||
track_beam_el <= host_track_beam_el;
|
||||
end
|
||||
end
|
||||
|
||||
// ============================================================================
|
||||
// Output mux for selected timing — wave_sel drives chirp/listen window length.
|
||||
// guard is shared across waveforms.
|
||||
@@ -233,7 +141,7 @@ assign cfg_listen_cycles = sel_listen_cycles;
|
||||
assign cfg_guard_cycles = host_guard_cycles;
|
||||
|
||||
// ============================================================================
|
||||
// Main FSM
|
||||
// Main FSM — auto-scan over enabled sub-frames.
|
||||
// ============================================================================
|
||||
localparam S_IDLE = 3'd0;
|
||||
localparam S_CHIRP = 3'd1;
|
||||
@@ -243,7 +151,6 @@ localparam S_ADVANCE = 3'd4;
|
||||
|
||||
reg [2:0] state;
|
||||
reg [16:0] timer; // 17 bits cover LONG+listen+guard worst case
|
||||
reg [5:0] track_remaining; // saturated copy of host_track_chirp_count
|
||||
|
||||
// Pre-computed wires used inside the FSM advance logic so non-blocking
|
||||
// updates to subframe_id / wave_sel see the correct next value in the same
|
||||
@@ -253,20 +160,17 @@ wire [1:0] next_sf = next_enabled_subframe(subframe_id, host_subframe_enable);
|
||||
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
state <= S_IDLE;
|
||||
timer <= 17'd0;
|
||||
wave_sel <= `RP_WAVE_SHORT;
|
||||
chirp_pulse <= 1'b0;
|
||||
subframe_pulse <= 1'b0;
|
||||
frame_pulse <= 1'b0;
|
||||
chirp_counter <= 6'd0;
|
||||
subframe_id <= 2'd0;
|
||||
track_mode_active <= 1'b0;
|
||||
track_remaining <= 6'd0;
|
||||
state <= S_IDLE;
|
||||
timer <= 17'd0;
|
||||
wave_sel <= `RP_WAVE_SHORT;
|
||||
chirp_pulse <= 1'b0;
|
||||
subframe_pulse <= 1'b0;
|
||||
frame_pulse <= 1'b0;
|
||||
chirp_counter <= 6'd0;
|
||||
subframe_id <= 2'd0;
|
||||
end else if (!mixers_enable) begin
|
||||
// Master disable — quiesce the FSM so chirp_pulse never asserts and
|
||||
// the TX side stays at idle. Doesn't disturb track_mode_active so
|
||||
// the host can still observe whether track was last requested.
|
||||
// the TX side stays at idle.
|
||||
state <= S_IDLE;
|
||||
timer <= 17'd0;
|
||||
chirp_pulse <= 1'b0;
|
||||
@@ -278,22 +182,38 @@ always @(posedge clk or negedge reset_n) begin
|
||||
subframe_pulse <= 1'b0;
|
||||
frame_pulse <= 1'b0;
|
||||
|
||||
case (effective_mode)
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// MODE 00 — STM32 pass-through. STM32 owns chirp timing; we walk
|
||||
// sub-frames in step with stm32_chirp_edge so wave_sel always matches
|
||||
// the chirp the firmware just fired.
|
||||
// --------------------------------------------------------------------
|
||||
`RP_MODE_STM32_PASSTHROUGH: begin
|
||||
state <= S_IDLE;
|
||||
timer <= 17'd0;
|
||||
track_mode_active <= 1'b0;
|
||||
|
||||
if (stm32_chirp_edge) begin
|
||||
chirp_pulse <= 1'b1;
|
||||
case (state)
|
||||
S_IDLE: begin
|
||||
timer <= 17'd0;
|
||||
chirp_counter <= 6'd0;
|
||||
subframe_id <= first_sf;
|
||||
wave_sel <= subframe_to_wave(first_sf);
|
||||
chirp_pulse <= 1'b1;
|
||||
state <= S_CHIRP;
|
||||
end
|
||||
S_CHIRP: begin
|
||||
if (timer + 17'd1 >= {1'b0, sel_chirp_cycles}) begin
|
||||
timer <= 17'd0;
|
||||
state <= S_LISTEN;
|
||||
end else timer <= timer + 17'd1;
|
||||
end
|
||||
S_LISTEN: begin
|
||||
if (timer + 17'd1 >= {1'b0, sel_listen_cycles}) begin
|
||||
timer <= 17'd0;
|
||||
state <= S_GUARD;
|
||||
end else timer <= timer + 17'd1;
|
||||
end
|
||||
S_GUARD: begin
|
||||
if (timer + 17'd1 >= {1'b0, host_guard_cycles}) begin
|
||||
timer <= 17'd0;
|
||||
state <= S_ADVANCE;
|
||||
end else timer <= timer + 17'd1;
|
||||
end
|
||||
S_ADVANCE: begin
|
||||
if (chirp_counter < host_chirps_per_subframe - 6'd1) begin
|
||||
chirp_counter <= chirp_counter + 6'd1;
|
||||
chirp_pulse <= 1'b1;
|
||||
state <= S_CHIRP;
|
||||
end else begin
|
||||
chirp_counter <= 6'd0;
|
||||
subframe_pulse <= 1'b1;
|
||||
@@ -301,154 +221,11 @@ always @(posedge clk or negedge reset_n) begin
|
||||
wave_sel <= subframe_to_wave(next_sf);
|
||||
if (next_sf == first_sf)
|
||||
frame_pulse <= 1'b1;
|
||||
chirp_pulse <= 1'b1;
|
||||
state <= S_CHIRP;
|
||||
end
|
||||
end
|
||||
|
||||
// STM32 firmware can pulse subframe/frame toggles directly when it
|
||||
// wants to force-advance (e.g. abort current sub-frame). These
|
||||
// override the chirp-driven walk above.
|
||||
if (stm32_subframe_edge) subframe_pulse <= 1'b1;
|
||||
if (stm32_frame_edge) frame_pulse <= 1'b1;
|
||||
end
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// MODE 01 — Auto-scan over enabled sub-frames.
|
||||
// --------------------------------------------------------------------
|
||||
`RP_MODE_AUTO_3KM: begin
|
||||
track_mode_active <= 1'b0;
|
||||
case (state)
|
||||
S_IDLE: begin
|
||||
timer <= 17'd0;
|
||||
chirp_counter <= 6'd0;
|
||||
subframe_id <= first_sf;
|
||||
wave_sel <= subframe_to_wave(first_sf);
|
||||
chirp_pulse <= 1'b1;
|
||||
state <= S_CHIRP;
|
||||
end
|
||||
S_CHIRP: begin
|
||||
if (timer + 17'd1 >= {1'b0, sel_chirp_cycles}) begin
|
||||
timer <= 17'd0;
|
||||
state <= S_LISTEN;
|
||||
end else timer <= timer + 17'd1;
|
||||
end
|
||||
S_LISTEN: begin
|
||||
if (timer + 17'd1 >= {1'b0, sel_listen_cycles}) begin
|
||||
timer <= 17'd0;
|
||||
state <= S_GUARD;
|
||||
end else timer <= timer + 17'd1;
|
||||
end
|
||||
S_GUARD: begin
|
||||
if (timer + 17'd1 >= {1'b0, host_guard_cycles}) begin
|
||||
timer <= 17'd0;
|
||||
state <= S_ADVANCE;
|
||||
end else timer <= timer + 17'd1;
|
||||
end
|
||||
S_ADVANCE: begin
|
||||
if (chirp_counter < host_chirps_per_subframe - 6'd1) begin
|
||||
chirp_counter <= chirp_counter + 6'd1;
|
||||
chirp_pulse <= 1'b1;
|
||||
state <= S_CHIRP;
|
||||
end else begin
|
||||
chirp_counter <= 6'd0;
|
||||
subframe_pulse <= 1'b1;
|
||||
subframe_id <= next_sf;
|
||||
wave_sel <= subframe_to_wave(next_sf);
|
||||
if (next_sf == first_sf)
|
||||
frame_pulse <= 1'b1;
|
||||
chirp_pulse <= 1'b1;
|
||||
state <= S_CHIRP;
|
||||
end
|
||||
end
|
||||
default: state <= S_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// MODE 10 — Single-chirp debug. One chirp per host_trigger.
|
||||
// --------------------------------------------------------------------
|
||||
`RP_MODE_SINGLE_DEBUG: begin
|
||||
track_mode_active <= 1'b0;
|
||||
case (state)
|
||||
S_IDLE: begin
|
||||
timer <= 17'd0;
|
||||
if (trigger_pulse) begin
|
||||
wave_sel <= host_debug_wave_sel;
|
||||
chirp_pulse <= 1'b1;
|
||||
state <= S_CHIRP;
|
||||
end
|
||||
end
|
||||
S_CHIRP: begin
|
||||
if (timer + 17'd1 >= {1'b0, sel_chirp_cycles}) begin
|
||||
timer <= 17'd0;
|
||||
state <= S_LISTEN;
|
||||
end else timer <= timer + 17'd1;
|
||||
end
|
||||
S_LISTEN: begin
|
||||
if (timer + 17'd1 >= {1'b0, sel_listen_cycles}) begin
|
||||
timer <= 17'd0;
|
||||
state <= S_IDLE;
|
||||
end else timer <= timer + 17'd1;
|
||||
end
|
||||
default: state <= S_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// MODE 11 — Track dwell. Watchdog fallback handled by effective_mode.
|
||||
// --------------------------------------------------------------------
|
||||
`RP_MODE_TRACK: begin
|
||||
track_mode_active <= 1'b1;
|
||||
case (state)
|
||||
S_IDLE: begin
|
||||
timer <= 17'd0;
|
||||
if (track_request_pulse) begin
|
||||
wave_sel <= host_track_wave_sel;
|
||||
// chirp_counter is 6 bits; clip the dwell length to
|
||||
// avoid wrapping inside a single dwell.
|
||||
track_remaining <= (host_track_chirp_count > 9'd63)
|
||||
? 6'd63
|
||||
: host_track_chirp_count[5:0];
|
||||
chirp_counter <= 6'd0;
|
||||
chirp_pulse <= 1'b1;
|
||||
state <= S_CHIRP;
|
||||
end
|
||||
end
|
||||
S_CHIRP: begin
|
||||
if (timer + 17'd1 >= {1'b0, sel_chirp_cycles}) begin
|
||||
timer <= 17'd0;
|
||||
state <= S_LISTEN;
|
||||
end else timer <= timer + 17'd1;
|
||||
end
|
||||
S_LISTEN: begin
|
||||
if (timer + 17'd1 >= {1'b0, sel_listen_cycles}) begin
|
||||
timer <= 17'd0;
|
||||
state <= S_GUARD;
|
||||
end else timer <= timer + 17'd1;
|
||||
end
|
||||
S_GUARD: begin
|
||||
if (timer + 17'd1 >= {1'b0, host_guard_cycles}) begin
|
||||
timer <= 17'd0;
|
||||
state <= S_ADVANCE;
|
||||
end else timer <= timer + 17'd1;
|
||||
end
|
||||
S_ADVANCE: begin
|
||||
if (chirp_counter < track_remaining) begin
|
||||
chirp_counter <= chirp_counter + 6'd1;
|
||||
chirp_pulse <= 1'b1;
|
||||
state <= S_CHIRP;
|
||||
end else begin
|
||||
// Dwell complete = one track frame. Watchdog ticks
|
||||
// here on every dwell; host re-pulsing track_request
|
||||
// resets it.
|
||||
frame_pulse <= 1'b1;
|
||||
chirp_counter <= 6'd0;
|
||||
state <= S_IDLE;
|
||||
end
|
||||
end
|
||||
default: state <= S_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
default: state <= S_IDLE;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
@@ -47,11 +47,6 @@
|
||||
// useful and the change is benign — revisit in PR-H if a finer gate is
|
||||
// needed.
|
||||
//
|
||||
// Beam steering:
|
||||
// elevation_counter / azimuth_counter remain on clk_100m and are bumped
|
||||
// by the STM32 toggle inputs (independent of the chirp FSM), unchanged
|
||||
// from v1.
|
||||
//
|
||||
// chirp_counter:
|
||||
// Increments by 1 each time we leave ST_CHIRP (i.e. one chirp finished).
|
||||
// Cleared on frame_pulse_120m so it tracks chirp index within the current
|
||||
@@ -62,9 +57,7 @@
|
||||
// ============================================================================
|
||||
module plfm_chirp_controller_v2 (
|
||||
input wire clk_120m,
|
||||
input wire clk_100m,
|
||||
input wire reset_n, // 120m-domain reset
|
||||
input wire reset_100m_n, // 100m-domain reset (elev/az counters)
|
||||
|
||||
input wire mixers_enable, // CDC-synced to clk_120m
|
||||
|
||||
@@ -73,10 +66,6 @@ module plfm_chirp_controller_v2 (
|
||||
input wire [1:0] dst_wave_sel,
|
||||
input wire frame_pulse_120m,
|
||||
|
||||
// STM32 beam-step toggle inputs (clk_100m, edge-detected upstream)
|
||||
input wire new_elevation,
|
||||
input wire new_azimuth,
|
||||
|
||||
// DAC outputs
|
||||
output reg [7:0] chirp_data,
|
||||
output reg chirp_valid,
|
||||
@@ -100,10 +89,8 @@ module plfm_chirp_controller_v2 (
|
||||
output reg adar_tr_3,
|
||||
output reg adar_tr_4,
|
||||
|
||||
// Status counters
|
||||
output reg [5:0] chirp_counter,
|
||||
output reg [5:0] elevation_counter,
|
||||
output reg [5:0] azimuth_counter
|
||||
// Status counter
|
||||
output reg [5:0] chirp_counter
|
||||
);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -113,10 +100,6 @@ localparam SHORT_SAMPLES = 12'd120;
|
||||
localparam MEDIUM_SAMPLES = 12'd600;
|
||||
localparam LONG_SAMPLES = 12'd3600;
|
||||
|
||||
// Beam ranges
|
||||
parameter ELEVATION_MAX = 31;
|
||||
parameter AZIMUTH_MAX = 50;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// FSM
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -266,29 +249,4 @@ always @(posedge clk_120m or negedge reset_n) begin
|
||||
end
|
||||
end
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Beam steering counters (clk_100m, independent of chirp FSM) — unchanged from v1.
|
||||
// ----------------------------------------------------------------------------
|
||||
always @(posedge clk_100m or negedge reset_100m_n) begin
|
||||
if (!reset_100m_n) begin
|
||||
elevation_counter <= 6'd1;
|
||||
end else if (new_elevation) begin
|
||||
if (elevation_counter == ELEVATION_MAX)
|
||||
elevation_counter <= 6'd1;
|
||||
else
|
||||
elevation_counter <= elevation_counter + 6'd1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk_100m or negedge reset_100m_n) begin
|
||||
if (!reset_100m_n) begin
|
||||
azimuth_counter <= 6'd1;
|
||||
end else if (new_azimuth) begin
|
||||
if (azimuth_counter == AZIMUTH_MAX)
|
||||
azimuth_counter <= 6'd1;
|
||||
else
|
||||
azimuth_counter <= azimuth_counter + 6'd1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -10,20 +10,15 @@
|
||||
// optionally alias macros to localparams for readability.
|
||||
//
|
||||
// BOARD VARIANTS:
|
||||
// SUPPORT_LONG_RANGE = 0 (50T, USB_MODE=1) — 3 km mode only
|
||||
// SUPPORT_LONG_RANGE = 1 (200T, USB_MODE=0) — 3 km + 20 km modes
|
||||
// SUPPORT_LONG_RANGE = 0 (50T, USB_MODE=1) — 3 km build
|
||||
// SUPPORT_LONG_RANGE = 1 (200T, USB_MODE=0) — 3 km + 20 km build
|
||||
//
|
||||
// RADAR MODES (runtime, via host_radar_mode register, opcode 0x01):
|
||||
// 2'b00 = STM32 pass-through (production — STM32 controls chirp timing)
|
||||
// 2'b01 = Auto-scan 3 km (FPGA-timed, short chirps only)
|
||||
// 2'b10 = Single-chirp debug (one long chirp per trigger)
|
||||
// 2'b11 = Reserved / idle
|
||||
//
|
||||
// RANGE MODES (runtime, via host_range_mode register, opcode 0x20):
|
||||
// 2'b00 = 3 km (default — pass-through treats all chirps as short)
|
||||
// 2'b01 = Long-range (pass-through: first half long, second half short)
|
||||
// 2'b10 = Reserved
|
||||
// 2'b11 = Reserved
|
||||
// The runtime "3 km vs 20 km" presentation on a 200T build is controlled by
|
||||
// host_subframe_enable (opcode 0x19, default 3'b111 = all subframes) combined
|
||||
// with the per-waveform chirp/listen-cycle opcodes (0x10-0x18). The legacy
|
||||
// host_radar_mode opcode 0x01 + host_range_mode opcode 0x20 were stripped in
|
||||
// PR-AB.b expanded scope (2026-05-11) along with three dead FSM branches
|
||||
// (STM32 pass-through, single-chirp debug, track dwell).
|
||||
//
|
||||
// USAGE:
|
||||
// `include "radar_params.vh"
|
||||
@@ -241,8 +236,6 @@
|
||||
// LONG defaults reuse RP_DEF_LONG_CHIRP_CYCLES / RP_DEF_LONG_LISTEN_CYCLES
|
||||
`define RP_DEF_CHIRPS_PER_SUBFRAME 16 // 16 per sub-frame, 3 sub-frames = 48 frame
|
||||
`define RP_DEF_SUBFRAME_ENABLE 3'b111 // SHORT|MEDIUM|LONG all on by default
|
||||
`define RP_DEF_TRACK_WATCHDOG_FRAMES 8'd5 // frames without track cmd before scan-fallback
|
||||
`define RP_DEF_TRACK_CHIRP_COUNT 9'd64 // default track-mode dwell N
|
||||
`define RP_DEF_CFAR_ALPHA_SOFT 8'h18 // 1.5 in Q4.4 — soft threshold for candidates
|
||||
// (Pfa_soft ≈ 10⁻⁵; confirm Pfa ≈ 10⁻⁶ at α=3.0)
|
||||
|
||||
@@ -293,30 +286,6 @@
|
||||
// ============================================================================
|
||||
`define RP_DEF_DETECT_THRESHOLD 10000
|
||||
|
||||
// ============================================================================
|
||||
// RADAR MODE ENCODING (host_radar_mode, opcode 0x01)
|
||||
// ============================================================================
|
||||
`define RP_MODE_STM32_PASSTHROUGH 2'b00
|
||||
`define RP_MODE_AUTO_3KM 2'b01
|
||||
`define RP_MODE_SINGLE_DEBUG 2'b10
|
||||
`define RP_MODE_RESERVED 2'b11
|
||||
|
||||
// ============================================================================
|
||||
// RANGE MODE ENCODING (host_range_mode, opcode 0x20)
|
||||
// ============================================================================
|
||||
`define RP_RANGE_MODE_3KM 2'b00
|
||||
`define RP_RANGE_MODE_LONG 2'b01
|
||||
`define RP_RANGE_MODE_RSVD2 2'b10
|
||||
`define RP_RANGE_MODE_RSVD3 2'b11
|
||||
|
||||
// ============================================================================
|
||||
// RADAR MODE ENCODING — TRACK extension (host_radar_mode, opcode 0x01)
|
||||
// ============================================================================
|
||||
// Mode 11 ("RESERVED" until PR-D) becomes TRACK mode: scheduler dwells one
|
||||
// beam, one waveform, host_track_chirp_count chirps. Doppler runs xfft_64.
|
||||
// RP_MODE_RESERVED below is renamed in-place for clarity.
|
||||
`define RP_MODE_TRACK 2'b11
|
||||
|
||||
// ============================================================================
|
||||
// STREAM CONTROL (host_stream_control, opcode 0x04, 6-bit)
|
||||
// ============================================================================
|
||||
@@ -355,8 +324,9 @@
|
||||
// ============================================================================
|
||||
// USB OPCODE MAP (PR-G v2 — single source of truth for RTL & GUI parity)
|
||||
// ============================================================================
|
||||
`define RP_OP_RADAR_MODE 8'h01
|
||||
`define RP_OP_TRIGGER_PULSE 8'h02
|
||||
// 0x01 (RADAR_MODE) and 0x02 (TRIGGER_PULSE) retired in PR-AB.b expanded
|
||||
// (2026-05-11) — single-mode FSM has no mode field to write, no host-driven
|
||||
// debug trigger. Reserved; host MUST NOT issue these opcodes.
|
||||
`define RP_OP_DETECT_THRESHOLD 8'h03
|
||||
`define RP_OP_STREAM_CONTROL 8'h04
|
||||
`define RP_OP_LONG_CHIRP_CYCLES 8'h10
|
||||
@@ -370,7 +340,9 @@
|
||||
`define RP_OP_MEDIUM_CHIRP_CYCLES 8'h17
|
||||
`define RP_OP_MEDIUM_LISTEN_CYCLES 8'h18
|
||||
// 0x19–0x1F reserved (per-waveform guard if needed in future)
|
||||
`define RP_OP_RANGE_MODE 8'h20
|
||||
// 0x20 (RANGE_MODE) retired in PR-AB.b expanded (2026-05-11) — runtime
|
||||
// 3km/20km presentation is driven by host_subframe_enable + per-waveform
|
||||
// chirp/listen-cycles on a 200T build.
|
||||
`define RP_OP_CFAR_GUARD 8'h21
|
||||
`define RP_OP_CFAR_TRAIN 8'h22
|
||||
`define RP_OP_CFAR_ALPHA 8'h23 // confirm-tier (Q4.4)
|
||||
|
||||
@@ -35,13 +35,8 @@ module radar_receiver_final (
|
||||
output wire [15:0] decimated_range_mag_out,
|
||||
output wire decimated_range_valid_out,
|
||||
|
||||
// Host command inputs (Gap 4: USB Read Path, CDC-synchronized)
|
||||
// CDC-synchronized in radar_system_top.v before reaching here
|
||||
input wire [1:0] host_mode, // Radar mode: 00=STM32, 01=auto-scan, 10=single-chirp
|
||||
input wire host_trigger, // Single-chirp trigger pulse (1 clk cycle)
|
||||
input wire [1:0] host_range_mode, // Range mode: 00=3km (short only), 01=long-range (dual chirp)
|
||||
|
||||
// Gap 2: Host-configurable chirp timing (CDC-synchronized in radar_system_top.v)
|
||||
// Host command inputs (CDC-synchronized in radar_system_top.v)
|
||||
// Gap 2: Host-configurable chirp timing
|
||||
input wire [15:0] host_long_chirp_cycles,
|
||||
input wire [15:0] host_long_listen_cycles,
|
||||
input wire [15:0] host_guard_cycles,
|
||||
@@ -68,14 +63,6 @@ module radar_receiver_final (
|
||||
input wire [3:0] host_agc_decay, // 0x2B: gain-up step when weak
|
||||
input wire [3:0] host_agc_holdoff, // 0x2C: frames before gain-up
|
||||
|
||||
// STM32 toggle signals for mode 00 (STM32-driven) pass-through.
|
||||
// These are CDC-synchronized in radar_system_top.v / radar_transmitter.v
|
||||
// before reaching this module. In mode 00, the RX mode controller uses
|
||||
// these to synchronize receiver processing with STM32-timed chirps.
|
||||
input wire stm32_new_chirp_rx,
|
||||
input wire stm32_new_elevation_rx,
|
||||
input wire stm32_new_azimuth_rx,
|
||||
|
||||
// PR-E: master mixers_enable in clk_100m domain — gates the scheduler
|
||||
// so it stays in S_IDLE until the operator turns the radar on.
|
||||
input wire mixers_enable_100m,
|
||||
@@ -151,8 +138,6 @@ wire frame_pulse; // unused on RX in PR-D; PR-F doppler driver
|
||||
wire [5:0] sched_chirp_counter;
|
||||
wire [1:0] sched_subframe_id;
|
||||
wire [15:0] sched_cfg_chirp_cycles, sched_cfg_listen_cycles, sched_cfg_guard_cycles;
|
||||
wire sched_track_mode_active;
|
||||
wire [5:0] sched_track_beam_az, sched_track_beam_el;
|
||||
|
||||
wire [1:0] segment_request;
|
||||
wire mem_request;
|
||||
@@ -239,7 +224,6 @@ chirp_scheduler sched (
|
||||
.mixers_enable(mixers_enable_100m),
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
.host_mode(host_mode),
|
||||
// PR-U / M-8: routed from radar_system_top opcode 0x19 (was the
|
||||
// RP_DEF_SUBFRAME_ENABLE constant — host had no way to mask sub-frames).
|
||||
.host_subframe_enable(host_subframe_enable),
|
||||
@@ -252,16 +236,6 @@ chirp_scheduler sched (
|
||||
.host_long_listen_cycles(host_long_listen_cycles),
|
||||
.host_guard_cycles(host_guard_cycles),
|
||||
.host_chirps_per_subframe(6'd`RP_DEF_CHIRPS_PER_SUBFRAME),
|
||||
.host_trigger(host_trigger),
|
||||
.host_debug_wave_sel(`RP_WAVE_SHORT),
|
||||
.host_track_request(1'b0),
|
||||
.host_track_wave_sel(`RP_WAVE_SHORT),
|
||||
.host_track_chirp_count(`RP_DEF_TRACK_CHIRP_COUNT),
|
||||
.host_track_beam_az(6'd0),
|
||||
.host_track_beam_el(6'd0),
|
||||
.stm32_new_chirp (stm32_new_chirp_rx),
|
||||
.stm32_new_subframe(stm32_new_elevation_rx),
|
||||
.stm32_new_frame (stm32_new_azimuth_rx),
|
||||
.wave_sel(wave_sel),
|
||||
.chirp_pulse(chirp_pulse),
|
||||
.subframe_pulse(subframe_pulse),
|
||||
@@ -270,10 +244,7 @@ chirp_scheduler sched (
|
||||
.subframe_id(sched_subframe_id),
|
||||
.cfg_chirp_cycles (sched_cfg_chirp_cycles),
|
||||
.cfg_listen_cycles(sched_cfg_listen_cycles),
|
||||
.cfg_guard_cycles (sched_cfg_guard_cycles),
|
||||
.track_mode_active(sched_track_mode_active),
|
||||
.track_beam_az(sched_track_beam_az),
|
||||
.track_beam_el(sched_track_beam_el)
|
||||
.cfg_guard_cycles (sched_cfg_guard_cycles)
|
||||
);
|
||||
|
||||
// PR-E: forward scheduler pulses + wave_sel to the TX-side CDC bridge in
|
||||
@@ -324,31 +295,15 @@ ad9484_interface_400m adc (
|
||||
// via 2FF. Single-bit, low→high-only once latched, so a 2FF sync is
|
||||
// sufficient for a GPIO-class diagnostic.
|
||||
//
|
||||
// F-7.7 fix: clear path now follows the same `clear_monitors_pulse` wire
|
||||
// as the DDC's `reset_monitors` port (see ddc instance below). Today
|
||||
// clear_monitors_pulse is tied 1'b0, matching the prior reset_n-only
|
||||
// behaviour; once a host opcode for "clear diagnostic stickies" lands,
|
||||
// both this OR sticky and the DDC's overrun/saturation flags clear from
|
||||
// the same edge — no per-flag re-plumbing needed.
|
||||
//
|
||||
// Compare with ddc_400m.v `cdc_cic_fir_overrun_sticky` which already
|
||||
// uses reset_monitors as a clear, and the new symmetric path here keeps
|
||||
// the AD9484 overrange diagnostic consistent.
|
||||
//
|
||||
// Audit M-11: `force_saturation_pulse` is the symmetric hook for the DDC's
|
||||
// debug `force_saturation` input (forces the saturation flag high for
|
||||
// validation campaigns). Today it is tied 1'b0 — the DDC saturation path
|
||||
// is exercised only by real overflow conditions. When a future host opcode
|
||||
// surface for "diagnostic force/clear" lands, both this pulse and
|
||||
// clear_monitors_pulse below get driven from the same dispatcher.
|
||||
wire force_saturation_pulse = 1'b0; // future host-driven force hook
|
||||
wire clear_monitors_pulse = 1'b0; // future host-driven clear hook
|
||||
// Cleared only by reset_n: the FPGA exposes no host-driven clear opcode
|
||||
// today, so any path that wants the sticky to drop has to go through a
|
||||
// full chip reset. A real host clear is a future bundled PR (opcode +
|
||||
// ft_clk→clk_400m CDC + matching plumbing for the DDC stickies). See
|
||||
// project_aeris10_clear_monitors_opcode_future.md.
|
||||
reg adc_overrange_sticky_400m;
|
||||
always @(posedge clk_400m or negedge reset_n) begin
|
||||
if (!reset_n)
|
||||
adc_overrange_sticky_400m <= 1'b0;
|
||||
else if (clear_monitors_pulse)
|
||||
adc_overrange_sticky_400m <= 1'b0;
|
||||
else if (adc_overrange_400m)
|
||||
adc_overrange_sticky_400m <= 1'b1;
|
||||
end
|
||||
@@ -411,13 +366,11 @@ ddc_400m_enhanced ddc(
|
||||
// Test/debug inputs — explicit tie-low (were floating)
|
||||
.test_mode(2'b00),
|
||||
.test_phase_inc(16'h0000),
|
||||
// M-11: routed through `force_saturation_pulse` so a future host
|
||||
// opcode can exercise the DDC saturation path alongside the clear hook.
|
||||
.force_saturation(force_saturation_pulse),
|
||||
// F-7.7: routed through the shared clear_monitors_pulse wire so the
|
||||
// DDC's internal stickies and the AD9484 OR sticky above clear from
|
||||
// the same future host opcode.
|
||||
.reset_monitors(clear_monitors_pulse),
|
||||
// No host-driven clear/force opcode exists today; both ports tied 1'b0.
|
||||
// See project_aeris10_clear_monitors_opcode_future.md for the bundled-PR
|
||||
// shape required to activate them (opcode + CDC + matching top-level hook).
|
||||
.force_saturation(1'b0),
|
||||
.reset_monitors(1'b0),
|
||||
.debug_sample_count(),
|
||||
.debug_internal_i(),
|
||||
.debug_internal_q(),
|
||||
|
||||
@@ -76,10 +76,11 @@ module radar_system_top (
|
||||
|
||||
// ========== STM32 CONTROL INTERFACES ==========
|
||||
|
||||
// Chirp/Beam Control (toggle signals from STM32)
|
||||
// STM32 → FPGA control (PD8/PD11). PD9/PD10 (was stm32_new_elevation /
|
||||
// stm32_new_azimuth) retired in PR-AB.b expanded — see commit 3 for the
|
||||
// XDC + MCU GPIO scrub. stm32_new_chirp will be renamed to
|
||||
// stm32_beam_ready in commit 5 (beam-ready handshake).
|
||||
input wire stm32_new_chirp,
|
||||
input wire stm32_new_elevation,
|
||||
input wire stm32_new_azimuth,
|
||||
input wire stm32_mixers_enable,
|
||||
|
||||
// ========== FT601 USB 3.0 INTERFACE ==========
|
||||
@@ -116,10 +117,8 @@ module radar_system_top (
|
||||
output wire ft_siwu, // Send Immediate / WakeUp
|
||||
|
||||
// ========== STATUS OUTPUTS ==========
|
||||
|
||||
// Beam position tracking
|
||||
output wire [5:0] current_elevation,
|
||||
output wire [5:0] current_azimuth,
|
||||
|
||||
// Live chirp-index telemetry (TX-side counter sync'd back to clk_100m)
|
||||
output wire [5:0] current_chirp,
|
||||
output wire new_chirp_frame,
|
||||
|
||||
@@ -171,8 +170,6 @@ wire tx_chirp_valid;
|
||||
wire tx_chirp_done;
|
||||
wire tx_new_chirp_frame; // In clk_120m_dac domain
|
||||
wire tx_new_chirp_frame_sync; // Synchronized to clk_100m domain
|
||||
wire [5:0] tx_current_elevation;
|
||||
wire [5:0] tx_current_azimuth;
|
||||
wire [5:0] tx_current_chirp; // In clk_120m_dac domain
|
||||
wire [5:0] tx_current_chirp_sync; // Synchronized to clk_100m domain
|
||||
wire tx_current_chirp_sync_valid;
|
||||
@@ -275,8 +272,6 @@ wire [15:0] usb_cmd_value;
|
||||
|
||||
// USB command decode registers (clk_100m domain, driven by CDC block below)
|
||||
// Declared here (before rx_inst) so Icarus Verilog can resolve forward refs.
|
||||
reg [1:0] host_radar_mode;
|
||||
reg host_trigger_pulse;
|
||||
reg [15:0] host_detect_threshold; // (was host_cfar_threshold)
|
||||
reg [5:0] host_stream_control;
|
||||
|
||||
@@ -314,14 +309,6 @@ reg host_status_request; // Opcode 0xFF (self-clearing pulse)
|
||||
localparam DOPPLER_FRAME_CHIRPS = `RP_CHIRPS_PER_FRAME; // 48 (PR-F); was 32
|
||||
reg chirps_mismatch_error; // Set if host tried to set chirps != FFT size
|
||||
|
||||
// Range-mode register (opcode 0x20)
|
||||
// Controls chirp type selection in the mode controller:
|
||||
// 2'b00 = 3 km mode (all short chirps — long blind zone > max range)
|
||||
// 2'b01 = Long-range (dual chirp: first half long, second half short)
|
||||
// 2'b10 = Reserved
|
||||
// 2'b11 = Reserved
|
||||
reg [1:0] host_range_mode;
|
||||
|
||||
// CFAR configuration registers (host-configurable via USB)
|
||||
reg [3:0] host_cfar_guard; // Opcode 0x21: guard cells per side (0..8)
|
||||
reg [4:0] host_cfar_train; // Opcode 0x22: training cells per side (1..16)
|
||||
@@ -540,9 +527,7 @@ radar_transmitter tx_inst (
|
||||
.sched_chirp_pulse(sched_chirp_pulse),
|
||||
.sched_frame_pulse(sched_frame_pulse),
|
||||
|
||||
// STM32 Control Interface (chirp moved to scheduler — only beam-step here)
|
||||
.stm32_new_elevation(stm32_new_elevation),
|
||||
.stm32_new_azimuth(stm32_new_azimuth),
|
||||
// STM32 master enable (mixers_enable)
|
||||
.stm32_mixers_enable(stm32_mixers_enable),
|
||||
|
||||
// RF Switch Control
|
||||
@@ -579,9 +564,7 @@ radar_transmitter tx_inst (
|
||||
.stm32_cs_adar3_1v8(stm32_cs_adar3_1v8),
|
||||
.stm32_cs_adar4_1v8(stm32_cs_adar4_1v8),
|
||||
|
||||
// Beam Position Tracking
|
||||
.current_elevation(tx_current_elevation),
|
||||
.current_azimuth(tx_current_azimuth),
|
||||
// Live chirp-index telemetry
|
||||
.current_chirp(tx_current_chirp),
|
||||
.new_chirp_frame(tx_new_chirp_frame)
|
||||
);
|
||||
@@ -621,9 +604,6 @@ radar_receiver_final rx_inst (
|
||||
.decimated_range_mag_out(rx_range_profile_decimated),
|
||||
.decimated_range_valid_out(rx_range_profile_decimated_valid),
|
||||
|
||||
.host_mode(host_radar_mode),
|
||||
.host_trigger(host_trigger_pulse),
|
||||
.host_range_mode(host_range_mode),
|
||||
// Gap 2: Host-configurable chirp timing
|
||||
.host_long_chirp_cycles(host_long_chirp_cycles),
|
||||
.host_long_listen_cycles(host_long_listen_cycles),
|
||||
@@ -645,11 +625,6 @@ radar_receiver_final rx_inst (
|
||||
.host_agc_attack(host_agc_attack),
|
||||
.host_agc_decay(host_agc_decay),
|
||||
.host_agc_holdoff(host_agc_holdoff),
|
||||
// STM32 toggle signals for the RX scheduler (mode 00 pass-through).
|
||||
// Raw GPIO inputs — chirp_scheduler's edge detectors handle debouncing.
|
||||
.stm32_new_chirp_rx(stm32_new_chirp),
|
||||
.stm32_new_elevation_rx(stm32_new_elevation),
|
||||
.stm32_new_azimuth_rx(stm32_new_azimuth),
|
||||
// PR-E: master enable for the scheduler (CDC-sync'd to clk_100m above)
|
||||
.mixers_enable_100m(stm32_mixers_enable_100m),
|
||||
// CFAR: Doppler frame-complete pulse
|
||||
@@ -903,14 +878,12 @@ if (USB_MODE == 0) begin : gen_ft601
|
||||
.status_request(host_status_request),
|
||||
.status_cfar_threshold(host_detect_threshold),
|
||||
.status_stream_ctrl(host_stream_control),
|
||||
.status_radar_mode(host_radar_mode),
|
||||
.status_long_chirp(host_long_chirp_cycles),
|
||||
.status_long_listen(host_long_listen_cycles),
|
||||
.status_guard(host_guard_cycles),
|
||||
.status_short_chirp(host_short_chirp_cycles),
|
||||
.status_short_listen(host_short_listen_cycles),
|
||||
.status_chirps_per_elev(host_chirps_per_elev),
|
||||
.status_range_mode(host_range_mode),
|
||||
.status_chirps_mismatch(chirps_mismatch_error),
|
||||
|
||||
// Self-test status readback
|
||||
@@ -996,7 +969,6 @@ end else begin : gen_ft2232h
|
||||
.status_request(host_status_request),
|
||||
.status_cfar_threshold(host_detect_threshold),
|
||||
.status_stream_ctrl(host_stream_control),
|
||||
.status_radar_mode(host_radar_mode),
|
||||
.status_long_chirp(host_long_chirp_cycles),
|
||||
.status_long_listen(host_long_listen_cycles),
|
||||
.status_guard(host_guard_cycles),
|
||||
@@ -1006,7 +978,6 @@ end else begin : gen_ft2232h
|
||||
.status_medium_chirp(host_medium_chirp_cycles),
|
||||
.status_medium_listen(host_medium_listen_cycles),
|
||||
.status_chirps_per_elev(host_chirps_per_elev),
|
||||
.status_range_mode(host_range_mode),
|
||||
.status_chirps_mismatch(chirps_mismatch_error),
|
||||
|
||||
// Self-test status readback
|
||||
@@ -1101,14 +1072,12 @@ wire cmd_valid_100m = cmd_valid_toggle_100m ^ cmd_valid_toggle_100m_prev;
|
||||
// Step 4: Command decode registers in clk_100m domain
|
||||
// Sample cmd_data fields when CDC'd valid pulse arrives. Data is stable
|
||||
// because the read FSM holds cmd_opcode/addr/value until the next command.
|
||||
// NOTE: reg declarations for host_radar_mode, host_trigger_pulse,
|
||||
// host_detect_threshold, host_stream_control are in INTERNAL SIGNALS section
|
||||
// above (before rx_inst) to avoid Icarus Verilog forward-reference errors.
|
||||
// NOTE: reg declarations for host_detect_threshold, host_stream_control are
|
||||
// in INTERNAL SIGNALS section above (before rx_inst) to avoid Icarus Verilog
|
||||
// forward-reference errors.
|
||||
|
||||
always @(posedge clk_100m_buf or negedge sys_reset_n) begin
|
||||
if (!sys_reset_n) begin
|
||||
host_radar_mode <= 2'b01; // Default: auto-scan
|
||||
host_trigger_pulse <= 1'b0;
|
||||
host_detect_threshold <= 16'd10000; // Default threshold
|
||||
host_stream_control <= `RP_STREAM_CTRL_DEFAULT; // Default: all streams, mag-only mode
|
||||
host_gain_shift <= 4'd0; // Default: pass-through (no gain change)
|
||||
@@ -1129,7 +1098,6 @@ always @(posedge clk_100m_buf or negedge sys_reset_n) begin
|
||||
host_subframe_enable <= `RP_DEF_SUBFRAME_ENABLE;
|
||||
host_status_request <= 1'b0;
|
||||
chirps_mismatch_error <= 1'b0;
|
||||
host_range_mode <= 2'b00; // Default: 3 km mode (all short chirps)
|
||||
// CFAR defaults (disabled by default — backward-compatible)
|
||||
host_cfar_guard <= 4'd2; // 2 guard cells each side
|
||||
host_cfar_train <= 5'd8; // 8 training cells each side
|
||||
@@ -1155,13 +1123,12 @@ always @(posedge clk_100m_buf or negedge sys_reset_n) begin
|
||||
// this fix, so existing bringup behavior is preserved).
|
||||
host_adc_pwdn <= 1'b0;
|
||||
end else begin
|
||||
host_trigger_pulse <= 1'b0; // Self-clearing pulse
|
||||
host_status_request <= 1'b0; // Self-clearing pulse
|
||||
host_self_test_trigger <= 1'b0; // Self-clearing pulse
|
||||
if (cmd_valid_100m) begin
|
||||
case (usb_cmd_opcode)
|
||||
8'h01: host_radar_mode <= usb_cmd_value[1:0];
|
||||
8'h02: host_trigger_pulse <= 1'b1;
|
||||
// 0x01 (RADAR_MODE) and 0x02 (TRIGGER_PULSE) retired in
|
||||
// PR-AB.b expanded — single-mode FSM has no mode field.
|
||||
8'h03: host_detect_threshold <= usb_cmd_value;
|
||||
// PR-G: protocol v2 has a single canonical encoding
|
||||
// (Manhattan-mag doppler + 2-bit dense detect). Bits [5:3] of
|
||||
@@ -1199,7 +1166,9 @@ always @(posedge clk_100m_buf or negedge sys_reset_n) begin
|
||||
end
|
||||
end
|
||||
8'h16: host_gain_shift <= usb_cmd_value[3:0]; // Fix 3: digital gain
|
||||
8'h20: host_range_mode <= usb_cmd_value[1:0]; // Range mode
|
||||
// 0x20 (RANGE_MODE) retired in PR-AB.b expanded — runtime
|
||||
// 3km/20km presentation is driven by host_subframe_enable +
|
||||
// per-waveform chirp/listen-cycles on a 200T build.
|
||||
// CFAR configuration opcodes
|
||||
8'h21: host_cfar_guard <= usb_cmd_value[3:0];
|
||||
8'h22: host_cfar_train <= usb_cmd_value[4:0];
|
||||
@@ -1238,8 +1207,6 @@ end
|
||||
// OUTPUT ASSIGNMENTS
|
||||
// ============================================================================
|
||||
|
||||
assign current_elevation = tx_current_elevation;
|
||||
assign current_azimuth = tx_current_azimuth;
|
||||
assign current_chirp = tx_current_chirp_sync; // Use CDC-synchronized version
|
||||
assign new_chirp_frame = tx_new_chirp_frame_sync; // Use CDC-synchronized version
|
||||
|
||||
|
||||
@@ -67,9 +67,9 @@ module radar_system_top_50t (
|
||||
output wire adc_pwdn,
|
||||
|
||||
// ===== STM32 Control (Bank 15: 3.3V) =====
|
||||
// PR-AB.b expanded: stm32_new_elevation/azimuth retired (no consumer).
|
||||
// stm32_new_chirp becomes stm32_beam_ready in commit 5.
|
||||
input wire stm32_new_chirp,
|
||||
input wire stm32_new_elevation,
|
||||
input wire stm32_new_azimuth,
|
||||
input wire stm32_mixers_enable,
|
||||
|
||||
// ===== FT2232H USB 2.0 Interface (Bank 35: 3.3V) =====
|
||||
@@ -108,8 +108,6 @@ module radar_system_top_50t (
|
||||
wire ft601_oe_n_nc;
|
||||
wire ft601_siwu_n_nc;
|
||||
wire ft601_clk_out_nc;
|
||||
wire [5:0] current_elevation_nc;
|
||||
wire [5:0] current_azimuth_nc;
|
||||
wire [5:0] current_chirp_nc;
|
||||
wire new_chirp_frame_nc;
|
||||
wire [31:0] dbg_doppler_data_nc;
|
||||
@@ -181,8 +179,6 @@ module radar_system_top_50t (
|
||||
|
||||
// ----- STM32 Control -----
|
||||
.stm32_new_chirp (stm32_new_chirp),
|
||||
.stm32_new_elevation (stm32_new_elevation),
|
||||
.stm32_new_azimuth (stm32_new_azimuth),
|
||||
.stm32_mixers_enable (stm32_mixers_enable),
|
||||
|
||||
// ----- FT2232H USB 2.0 (active on 50T, USB_MODE=1) -----
|
||||
@@ -210,8 +206,6 @@ module radar_system_top_50t (
|
||||
.ft601_clk_out (ft601_clk_out_nc),
|
||||
|
||||
// ----- Status/Debug (no pins on 50T) -----
|
||||
.current_elevation (current_elevation_nc),
|
||||
.current_azimuth (current_azimuth_nc),
|
||||
.current_chirp (current_chirp_nc),
|
||||
.new_chirp_frame (new_chirp_frame_nc),
|
||||
.dbg_doppler_data (dbg_doppler_data_nc),
|
||||
|
||||
@@ -128,14 +128,12 @@ usb_data_interface usb_inst (
|
||||
.status_request(status_request_reg),
|
||||
.status_cfar_threshold(16'h1234),
|
||||
.status_stream_ctrl(stream_control_reg),
|
||||
.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'b01),
|
||||
.status_self_test_flags(5'b11111),
|
||||
.status_self_test_detail(8'hA5),
|
||||
.status_self_test_busy(1'b0),
|
||||
|
||||
@@ -12,22 +12,17 @@
|
||||
// - frame_pulse → toggle CDC → 1-cycle pulse on clk_120m_dac for
|
||||
// chirp_counter clear and the new_chirp_frame status output.
|
||||
//
|
||||
// Beam steering:
|
||||
// stm32_new_elevation / stm32_new_azimuth still run through edge detectors
|
||||
// on clk_100m and feed the controller's internal beam counters. These are
|
||||
// independent of the chirp FSM and unchanged from chirp-v1.
|
||||
//
|
||||
// stm32_new_chirp:
|
||||
// Removed from this module — the scheduler in receiver_final now owns chirp
|
||||
// timing. The top-level GPIO is still wired to receiver_final via
|
||||
// stm32_new_chirp_rx; the transmitter has no separate path.
|
||||
// Beam-step GPIOs (stm32_new_elevation / stm32_new_azimuth) were retired
|
||||
// in PR-AB.b expanded (2026-05-11). The FPGA-side elev/az counters they
|
||||
// drove had no host consumer (status pack didn't carry them, GUI reads
|
||||
// MCU software counters via USB-CDC instead). PD9 / PD10 are now free.
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
module radar_transmitter(
|
||||
// System Clocks
|
||||
input wire clk_100m, // System clock
|
||||
input wire clk_120m_dac, // 120MHz DAC clock
|
||||
input wire reset_n, // Reset synchronized to clk_120m_dac
|
||||
input wire reset_100m_n, // Reset synchronized to clk_100m (for edge detectors/CDC)
|
||||
input wire reset_100m_n, // Reset synchronized to clk_100m (for CDC)
|
||||
|
||||
// DAC Interface
|
||||
output wire [7:0] dac_data,
|
||||
@@ -41,9 +36,7 @@ module radar_transmitter(
|
||||
input wire sched_chirp_pulse,
|
||||
input wire sched_frame_pulse,
|
||||
|
||||
// STM32 Control Interface (chirp moved to scheduler; beam-step still here)
|
||||
input wire stm32_new_elevation,
|
||||
input wire stm32_new_azimuth,
|
||||
// STM32 master enable (mixers_enable, CDC-synced to clk_120m_dac here)
|
||||
input wire stm32_mixers_enable,
|
||||
|
||||
output wire fpga_rf_switch,
|
||||
@@ -79,9 +72,7 @@ module radar_transmitter(
|
||||
output wire stm32_cs_adar3_1v8,
|
||||
output wire stm32_cs_adar4_1v8,
|
||||
|
||||
// Beam Position Tracking
|
||||
output wire [5:0] current_elevation,
|
||||
output wire [5:0] current_azimuth,
|
||||
// Live chirp-index telemetry (clk_120m_dac, sync'd back at top level)
|
||||
output wire [5:0] current_chirp,
|
||||
output wire new_chirp_frame
|
||||
);
|
||||
@@ -98,14 +89,6 @@ assign stm32_cs_adar2_1v8 = stm32_cs_adar2_3v3;
|
||||
assign stm32_cs_adar3_1v8 = stm32_cs_adar3_3v3;
|
||||
assign stm32_cs_adar4_1v8 = stm32_cs_adar4_3v3;
|
||||
|
||||
// Beam-step edge detection (STM32 GPIO -> clk_100m pulses)
|
||||
wire new_elevation_pulse;
|
||||
wire new_azimuth_pulse;
|
||||
|
||||
// CDC: Synchronized versions of async STM32 GPIO inputs to clk_100m
|
||||
wire stm32_new_elevation_sync;
|
||||
wire stm32_new_azimuth_sync;
|
||||
|
||||
// CDC: stm32_mixers_enable into clk_120m_dac domain
|
||||
wire mixers_enable_120m;
|
||||
|
||||
@@ -182,47 +165,12 @@ cdc_single_bit #(.STAGES(3)) cdc_mixers_en_120m (
|
||||
.dst_signal(mixers_enable_120m)
|
||||
);
|
||||
|
||||
// ============================================================================
|
||||
// Beam-step CDC + edge detection (clk_100m, unchanged from v1)
|
||||
// ============================================================================
|
||||
cdc_single_bit #(.STAGES(2)) cdc_stm32_elevation (
|
||||
.src_clk(clk_100m),
|
||||
.dst_clk(clk_100m),
|
||||
.reset_n(reset_100m_n),
|
||||
.src_signal(stm32_new_elevation),
|
||||
.dst_signal(stm32_new_elevation_sync)
|
||||
);
|
||||
|
||||
cdc_single_bit #(.STAGES(2)) cdc_stm32_azimuth (
|
||||
.src_clk(clk_100m),
|
||||
.dst_clk(clk_100m),
|
||||
.reset_n(reset_100m_n),
|
||||
.src_signal(stm32_new_azimuth),
|
||||
.dst_signal(stm32_new_azimuth_sync)
|
||||
);
|
||||
|
||||
edge_detector_enhanced elevation_edge (
|
||||
.clk(clk_100m),
|
||||
.reset_n(reset_100m_n),
|
||||
.signal_in(stm32_new_elevation_sync),
|
||||
.rising_falling_edge(new_elevation_pulse)
|
||||
);
|
||||
|
||||
edge_detector_enhanced azimuth_edge (
|
||||
.clk(clk_100m),
|
||||
.reset_n(reset_100m_n),
|
||||
.signal_in(stm32_new_azimuth_sync),
|
||||
.rising_falling_edge(new_azimuth_pulse)
|
||||
);
|
||||
|
||||
// ============================================================================
|
||||
// PLFM Chirp Generator (chirp-v2)
|
||||
// ============================================================================
|
||||
plfm_chirp_controller_v2 plfm_chirp_inst (
|
||||
.clk_120m (clk_120m_dac),
|
||||
.clk_100m (clk_100m),
|
||||
.reset_n (reset_n),
|
||||
.reset_100m_n (reset_100m_n),
|
||||
.mixers_enable (mixers_enable_120m),
|
||||
|
||||
// Scheduler bridge (clk_120m_dac, post-CDC)
|
||||
@@ -230,10 +178,6 @@ plfm_chirp_controller_v2 plfm_chirp_inst (
|
||||
.dst_wave_sel (dst_wave_sel),
|
||||
.frame_pulse_120m(frame_pulse_120m),
|
||||
|
||||
// Beam-step pulses (clk_100m)
|
||||
.new_elevation (new_elevation_pulse),
|
||||
.new_azimuth (new_azimuth_pulse),
|
||||
|
||||
// DAC outputs
|
||||
.chirp_data (chirp_data),
|
||||
.chirp_valid (chirp_valid),
|
||||
@@ -257,10 +201,8 @@ plfm_chirp_controller_v2 plfm_chirp_inst (
|
||||
.adar_tr_3 (adar_tr_3),
|
||||
.adar_tr_4 (adar_tr_4),
|
||||
|
||||
// Status counters
|
||||
.chirp_counter (current_chirp),
|
||||
.elevation_counter(current_elevation),
|
||||
.azimuth_counter (current_azimuth)
|
||||
// Live chirp-index telemetry
|
||||
.chirp_counter (current_chirp)
|
||||
);
|
||||
|
||||
// ============================================================================
|
||||
|
||||
@@ -86,14 +86,14 @@ module usb_data_interface (
|
||||
input wire status_request, // 1-cycle pulse in clk_100m when 0xFF received
|
||||
input wire [15:0] status_cfar_threshold, // Current CFAR threshold
|
||||
input wire [5:0] status_stream_ctrl, // Current stream control (6-bit: [2:0]=stream en, [5:3]=format)
|
||||
input wire [1:0] status_radar_mode, // Current radar mode
|
||||
// status_radar_mode + status_range_mode retired in PR-AB.b expanded.
|
||||
// Bits in status_words[0][23:22] and status_words[4][1:0] are reserved 0.
|
||||
input wire [15:0] status_long_chirp, // Current long chirp cycles
|
||||
input wire [15:0] status_long_listen, // Current long listen cycles
|
||||
input wire [15:0] status_guard, // Current guard cycles
|
||||
input wire [15:0] status_short_chirp, // Current short chirp cycles
|
||||
input wire [15:0] status_short_listen, // Current short listen cycles
|
||||
input wire [5:0] status_chirps_per_elev, // Current chirps per elevation
|
||||
input wire [1:0] status_range_mode, // Fix 7: Current range mode (0x20)
|
||||
input wire status_chirps_mismatch, // TX-G: host requested chirps != Doppler FFT size
|
||||
|
||||
// Self-test status readback (opcode 0x31 / included in 0xFF status packet)
|
||||
@@ -399,8 +399,9 @@ always @(posedge ft601_clk_in or negedge ft601_effective_reset_n) begin
|
||||
// Gap 2: Capture status snapshot when request arrives in ft601 domain
|
||||
if (status_req_ft601) begin
|
||||
// Pack register values into 5x 32-bit status words
|
||||
// Word 0: {0xFF[31:24], mode[23:22], stream[21:16], threshold[15:0]}
|
||||
status_words[0] <= {8'hFF, status_radar_mode, status_stream_ctrl,
|
||||
// Word 0: {0xFF[31:24], reserved[23:22]=0, stream[21:16], threshold[15:0]}
|
||||
// (mode bits retired in PR-AB.b expanded — single-mode FSM)
|
||||
status_words[0] <= {8'hFF, 2'd0, status_stream_ctrl,
|
||||
status_cfar_threshold};
|
||||
// Word 1: {long_chirp_cycles[15:0], long_listen_cycles[15:0]}
|
||||
status_words[1] <= {status_long_chirp, status_long_listen};
|
||||
@@ -408,14 +409,14 @@ always @(posedge ft601_clk_in or negedge ft601_effective_reset_n) begin
|
||||
status_words[2] <= {status_guard, status_short_chirp};
|
||||
// Word 3: {short_listen_cycles[15:0], chirps_per_elev[5:0], 10'b0}
|
||||
status_words[3] <= {status_short_listen, 10'd0, status_chirps_per_elev};
|
||||
// Word 4: AGC metrics + range_mode
|
||||
// Word 4: AGC metrics (range_mode retired in PR-AB.b expanded)
|
||||
status_words[4] <= {status_agc_current_gain, // [31:28]
|
||||
status_agc_peak_magnitude, // [27:20]
|
||||
status_agc_saturation_count, // [19:12] 8-bit saturation count
|
||||
status_agc_enable, // [11]
|
||||
status_chirps_mismatch, // [10] TX-G mismatch flag
|
||||
8'd0, // [9:2] reserved
|
||||
status_range_mode}; // [1:0]
|
||||
2'd0}; // [1:0] reserved (was range_mode)
|
||||
// Word 5: {reserved[6:0], self_test_busy[24], reserved[23:16],
|
||||
// self_test_detail[15:8], reserved[7], cic_fir_overrun[6],
|
||||
// range_decim_watchdog[5], self_test_flags[4:0]}
|
||||
|
||||
@@ -143,7 +143,8 @@ module usb_data_interface_ft2232h (
|
||||
input wire status_request,
|
||||
input wire [15:0] status_cfar_threshold,
|
||||
input wire [5:0] status_stream_ctrl,
|
||||
input wire [1:0] status_radar_mode,
|
||||
// status_radar_mode + status_range_mode retired in PR-AB.b expanded.
|
||||
// Bits in status_words[0][23:22] and status_words[4][1:0] are reserved 0.
|
||||
input wire [15:0] status_long_chirp,
|
||||
input wire [15:0] status_long_listen,
|
||||
input wire [15:0] status_guard,
|
||||
@@ -152,7 +153,6 @@ module usb_data_interface_ft2232h (
|
||||
input wire [15:0] status_medium_chirp, // M-5: status_words[7][31:16] readback
|
||||
input wire [15:0] status_medium_listen, // M-5: status_words[7][15:0] readback
|
||||
input wire [5:0] status_chirps_per_elev,
|
||||
input wire [1:0] status_range_mode,
|
||||
input wire status_chirps_mismatch, // TX-G: host requested chirps != Doppler FFT size
|
||||
|
||||
// Self-test status readback
|
||||
@@ -872,10 +872,10 @@ always @(posedge ft_clk or negedge ft_effective_reset_n) begin
|
||||
|
||||
// Status snapshot on request
|
||||
if (status_req_ft) begin
|
||||
// Word 0: {0xFF, mode[1:0], stream[5:0], threshold[15:0]}
|
||||
// NOTE: stream_ctrl now 6-bit. Pack as: {0xFF, mode, stream[5:3], stream[2:0], threshold}
|
||||
// Keep backward-compatible layout: {0xFF[31:24], mode[23:22], stream[21:16], threshold[15:0]}
|
||||
status_words[0] <= {8'hFF, status_radar_mode, status_stream_ctrl, status_cfar_threshold};
|
||||
// Word 0: {0xFF[31:24], reserved[23:22]=0, stream[21:16], threshold[15:0]}
|
||||
// mode bits retired in PR-AB.b expanded — single-mode FSM has no mode field.
|
||||
// Layout preserved for parser compatibility; bits [23:22] always 0.
|
||||
status_words[0] <= {8'hFF, 2'd0, status_stream_ctrl, status_cfar_threshold};
|
||||
status_words[1] <= {status_long_chirp, status_long_listen};
|
||||
status_words[2] <= {status_guard, status_short_chirp};
|
||||
status_words[3] <= {status_short_listen, 10'd0, status_chirps_per_elev};
|
||||
@@ -885,7 +885,7 @@ always @(posedge ft_clk or negedge ft_effective_reset_n) begin
|
||||
status_agc_enable, // [11]
|
||||
status_chirps_mismatch, // [10] TX-G mismatch flag
|
||||
alpha_soft_sync_1, // [9:2] PR-G: host_cfar_alpha_soft echo (Q4.4)
|
||||
status_range_mode}; // [1:0]
|
||||
2'd0}; // [1:0] reserved (was range_mode, retired PR-AB.b expanded)
|
||||
// Word 5: {frame_drop_count[31:25], self_test_busy[24],
|
||||
// reserved[23:16], self_test_detail[15:8], reserved[7],
|
||||
// cic_fir_overrun[6], range_decim_watchdog[5],
|
||||
|
||||
Reference in New Issue
Block a user