Files
NawfalMotii79-PLFM_RADAR/9_Firmware/9_2_FPGA/radar_transmitter.v
T
Jason 1b2a21d55b 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.
2026-05-11 10:24:20 +05:45

222 lines
7.8 KiB
Verilog

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// radar_transmitter — DAC-side wrapper around plfm_chirp_controller_v2.
//
// chirp-v2 PR-E reorganization:
// chirp_scheduler (clk_100m, in receiver_final) is now the master timekeeper.
// It emits {wave_sel[1:0], chirp_pulse, frame_pulse} on clk_100m. We bridge
// them to clk_120m_dac here:
// - wave_sel + chirp_pulse → cdc_async_fifo (Cummings style #2). Each
// chirp_pulse pushes wave_sel into the FIFO; the dst-side dst_valid
// pulse drives plfm_chirp_controller_v2.dst_chirp_valid.
// - frame_pulse → toggle CDC → 1-cycle pulse on clk_120m_dac for
// chirp_counter clear and the new_chirp_frame status output.
//
// 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 CDC)
// DAC Interface
output wire [7:0] dac_data,
output wire dac_clk,
output wire dac_sleep,
output wire rx_mixer_en,
output wire tx_mixer_en,
// Scheduler outputs from receiver_final (clk_100m domain) — PR-E
input wire [1:0] sched_wave_sel,
input wire sched_chirp_pulse,
input wire sched_frame_pulse,
// STM32 master enable (mixers_enable, CDC-synced to clk_120m_dac here)
input wire stm32_mixers_enable,
output wire fpga_rf_switch,
// ADAR1000 Control Interface
output wire adar_tx_load_1,
output wire adar_rx_load_1,
output wire adar_tx_load_2,
output wire adar_rx_load_2,
output wire adar_tx_load_3,
output wire adar_rx_load_3,
output wire adar_tx_load_4,
output wire adar_rx_load_4,
output wire adar_tr_1,
output wire adar_tr_2,
output wire adar_tr_3,
output wire adar_tr_4,
// Level Shifter SPI Interface (STM32F7 to ADAR1000)
input wire stm32_sclk_3v3,
input wire stm32_mosi_3v3,
output wire stm32_miso_3v3,
input wire stm32_cs_adar1_3v3,
input wire stm32_cs_adar2_3v3,
input wire stm32_cs_adar3_3v3,
input wire stm32_cs_adar4_3v3,
output wire stm32_sclk_1v8,
output wire stm32_mosi_1v8,
input wire stm32_miso_1v8,
output wire stm32_cs_adar1_1v8,
output wire stm32_cs_adar2_1v8,
output wire stm32_cs_adar3_1v8,
output wire stm32_cs_adar4_1v8,
// Live chirp-index telemetry (clk_120m_dac, sync'd back at top level)
output wire [5:0] current_chirp,
output wire new_chirp_frame
);
// ========== SPI LEVEL SHIFTER PASSTHROUGH ==========
// FPGA bridges 3.3V STM32 SPI bus (Bank 15) to 1.8V ADAR1000 SPI bus (Bank 34).
// The FPGA I/O banks handle the actual voltage translation; these assigns
// route the signals through the fabric.
assign stm32_sclk_1v8 = stm32_sclk_3v3;
assign stm32_mosi_1v8 = stm32_mosi_3v3;
assign stm32_miso_3v3 = stm32_miso_1v8;
assign stm32_cs_adar1_1v8 = stm32_cs_adar1_3v3;
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;
// CDC: stm32_mixers_enable into clk_120m_dac domain
wire mixers_enable_120m;
// PR-E: scheduler bridge outputs in clk_120m_dac domain
wire dst_chirp_valid;
wire [1:0] dst_wave_sel;
wire sched_overrun_unused;
wire frame_pulse_120m;
// Chirp Control Signals
wire [7:0] chirp_data;
wire chirp_valid;
wire chirp_sequence_done;
// ============================================================================
// PR-E: chirp_pulse + wave_sel CDC (clk_100m → clk_120m_dac)
//
// Each scheduler chirp_pulse on clk_100m pushes wave_sel into a Gray-coded
// async FIFO. The dst side auto-drains so dst_chirp_valid is a 1-cycle pulse
// on clk_120m_dac, and dst_wave_sel carries the matching waveform identity.
// ============================================================================
cdc_async_fifo #(
.WIDTH(2),
.DEPTH(4)
) cdc_chirp_fifo (
.src_clk (clk_100m),
.dst_clk (clk_120m_dac),
.src_reset_n (reset_100m_n),
.dst_reset_n (reset_n),
.src_data (sched_wave_sel),
.src_valid (sched_chirp_pulse),
.dst_data (dst_wave_sel),
.dst_valid (dst_chirp_valid),
.overrun (sched_overrun_unused)
);
// ============================================================================
// frame_pulse toggle CDC (clk_100m → clk_120m_dac)
// ============================================================================
reg frame_toggle_100m;
always @(posedge clk_100m or negedge reset_100m_n) begin
if (!reset_100m_n)
frame_toggle_100m <= 1'b0;
else if (sched_frame_pulse)
frame_toggle_100m <= ~frame_toggle_100m;
end
wire frame_toggle_120m;
cdc_single_bit #(.STAGES(3)) cdc_frame_toggle (
.src_clk(clk_100m),
.dst_clk(clk_120m_dac),
.reset_n(reset_n),
.src_signal(frame_toggle_100m),
.dst_signal(frame_toggle_120m)
);
reg frame_toggle_120m_prev;
always @(posedge clk_120m_dac or negedge reset_n) begin
if (!reset_n)
frame_toggle_120m_prev <= 1'b0;
else
frame_toggle_120m_prev <= frame_toggle_120m;
end
assign frame_pulse_120m = frame_toggle_120m ^ frame_toggle_120m_prev;
// ============================================================================
// stm32_mixers_enable level CDC into clk_120m_dac
// ============================================================================
cdc_single_bit #(.STAGES(3)) cdc_mixers_en_120m (
.src_clk(clk_100m), // Treat as pseudo-source (GPIO is async)
.dst_clk(clk_120m_dac),
.reset_n(reset_n),
.src_signal(stm32_mixers_enable),
.dst_signal(mixers_enable_120m)
);
// ============================================================================
// PLFM Chirp Generator (chirp-v2)
// ============================================================================
plfm_chirp_controller_v2 plfm_chirp_inst (
.clk_120m (clk_120m_dac),
.reset_n (reset_n),
.mixers_enable (mixers_enable_120m),
// Scheduler bridge (clk_120m_dac, post-CDC)
.dst_chirp_valid (dst_chirp_valid),
.dst_wave_sel (dst_wave_sel),
.frame_pulse_120m(frame_pulse_120m),
// DAC outputs
.chirp_data (chirp_data),
.chirp_valid (chirp_valid),
.new_chirp_frame(new_chirp_frame),
.chirp_done (chirp_sequence_done),
.rf_switch_ctrl (fpga_rf_switch),
.rx_mixer_en (rx_mixer_en),
.tx_mixer_en (tx_mixer_en),
// ADAR
.adar_tx_load_1 (adar_tx_load_1),
.adar_rx_load_1 (adar_rx_load_1),
.adar_tx_load_2 (adar_tx_load_2),
.adar_rx_load_2 (adar_rx_load_2),
.adar_tx_load_3 (adar_tx_load_3),
.adar_rx_load_3 (adar_rx_load_3),
.adar_tx_load_4 (adar_tx_load_4),
.adar_rx_load_4 (adar_rx_load_4),
.adar_tr_1 (adar_tr_1),
.adar_tr_2 (adar_tr_2),
.adar_tr_3 (adar_tr_3),
.adar_tr_4 (adar_tr_4),
// Live chirp-index telemetry
.chirp_counter (current_chirp)
);
// ============================================================================
// DAC Output Interface
// ============================================================================
dac_interface_enhanced dac_interface_inst (
.clk_120m (clk_120m_dac),
.reset_n (reset_n),
.chirp_data (chirp_data),
.chirp_valid(chirp_valid),
.dac_data (dac_data),
.dac_clk (dac_clk),
.dac_sleep (dac_sleep)
);
endmodule