`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    19:04:35 12/14/2025 
// Design Name: 
// Module Name:    radar_transmitter 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
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)
    
    // 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,
	 
	     // STM32 Control Interface
    input wire stm32_new_chirp,
    input wire stm32_new_elevation, 
    input wire stm32_new_azimuth,
    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,
	 
			 // Beam Position Tracking
	 output wire [5:0] current_elevation,
	 output wire [5:0] current_azimuth,
	 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;

// Edge Detection Signals
wire new_chirp_pulse;
wire new_elevation_pulse;
wire new_azimuth_pulse;

// CDC: Synchronized versions of async STM32 GPIO inputs to clk_100m
wire stm32_new_chirp_sync;
wire stm32_new_elevation_sync;
wire stm32_new_azimuth_sync;

// CDC: Synchronized versions of signals crossing clk_100m -> clk_120m_dac
wire mixers_enable_120m;   // stm32_mixers_enable sync'd to clk_120m_dac
wire new_chirp_pulse_120m; // new_chirp_pulse (toggle CDC) in clk_120m_dac domain

// Chirp Control Signals
wire [7:0] chirp_data;
wire chirp_valid;
wire chirp_sequence_done;

// Toggle CDC for new_chirp_pulse: clk_100m -> clk_120m_dac
// Edge detector produces a 1-cycle pulse on clk_100m. A level synchronizer
// would miss it (120/100 MHz ratio). Toggle CDC converts pulse to level toggle,
// syncs the toggle, then detects edges on the destination side.
reg chirp_toggle_100m;
always @(posedge clk_100m or negedge reset_100m_n) begin
    if (!reset_100m_n)
        chirp_toggle_100m <= 1'b0;
    else if (new_chirp_pulse)
        chirp_toggle_100m <= ~chirp_toggle_100m;
end

// Sync the toggle to clk_120m_dac domain
wire chirp_toggle_120m;
cdc_single_bit #(.STAGES(3)) cdc_chirp_toggle (
    .src_clk(clk_100m),
    .dst_clk(clk_120m_dac),
    .reset_n(reset_n),
    .src_signal(chirp_toggle_100m),
    .dst_signal(chirp_toggle_120m)
);

// Detect edges on synchronized toggle to recover pulse in clk_120m domain
reg chirp_toggle_120m_prev;
always @(posedge clk_120m_dac or negedge reset_n) begin
    if (!reset_n)
        chirp_toggle_120m_prev <= 1'b0;
    else
        chirp_toggle_120m_prev <= chirp_toggle_120m;
end
assign new_chirp_pulse_120m = chirp_toggle_120m ^ chirp_toggle_120m_prev;

// Sync stm32_mixers_enable (async GPIO level) to clk_120m_dac domain
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)
);

// CDC synchronizers: async STM32 GPIO inputs -> clk_100m domain
// These prevent metastability in the edge detectors. Without these,
// the edge detector's first FF can go metastable, and the XOR output
// can glitch, producing false chirp/elevation/azimuth pulses.
cdc_single_bit #(.STAGES(2)) cdc_stm32_chirp (
    .src_clk(clk_100m),         // Pseudo-source for async GPIO
    .dst_clk(clk_100m),
    .reset_n(reset_100m_n),
    .src_signal(stm32_new_chirp),
    .dst_signal(stm32_new_chirp_sync)
);

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)
);

// Enhanced STM32 Input Edge Detection with Debouncing
// Inputs are now CDC-synchronized (safe from metastability)
edge_detector_enhanced chirp_edge (
    .clk(clk_100m),
    .reset_n(reset_100m_n),
    .signal_in(stm32_new_chirp_sync),
    .rising_falling_edge(new_chirp_pulse)            
);

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)
);

// Enhanced PLFM Chirp Generation
plfm_chirp_controller_enhanced plfm_chirp_inst (
    .clk_120m(clk_120m_dac),
    .clk_100m(clk_100m),
    .reset_n(reset_n),
    .new_chirp(new_chirp_pulse_120m),      // CDC-synchronized pulse in clk_120m domain
    .new_elevation(new_elevation_pulse),
    .new_azimuth(new_azimuth_pulse),
    .new_chirp_frame(new_chirp_frame),
    .mixers_enable(mixers_enable_120m),    // CDC-synchronized level in clk_120m domain
    .chirp_data(chirp_data),
    .chirp_valid(chirp_valid),
    .chirp_done(chirp_sequence_done),
    .rf_switch_ctrl(fpga_rf_switch),
    .rx_mixer_en(rx_mixer_en),
    .tx_mixer_en(tx_mixer_en),
    .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),
    .elevation_counter(current_elevation),
    .azimuth_counter(current_azimuth),
    .chirp_counter(current_chirp)
);

// Enhanced DAC 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
