/ 9_Firmware / 9_2_FPGA / ddc_400m.v
ddc_400m.v
  1  `timescale 1ns / 1ps
  2  
  3  module ddc_400m_enhanced (
  4      input wire clk_400m,           // 400MHz clock from ADC DCO
  5      input wire clk_100m,           // 100MHz system clock
  6      input wire reset_n,
  7      input wire mixers_enable,
  8      input wire [7:0] adc_data,     // ADC data at 400MHz
  9      input wire adc_data_valid_i,     // Valid at 400MHz
 10  	 input wire adc_data_valid_q,
 11      output wire signed [17:0] baseband_i,
 12      output wire signed [17:0] baseband_q,  
 13      output wire baseband_valid_i,
 14  	 output wire baseband_valid_q,
 15  
 16      output wire [1:0] ddc_status,
 17      // Enhanced interfaces
 18      output wire [7:0] ddc_diagnostics,
 19      output wire mixer_saturation,
 20      output wire filter_overflow,
 21  	 
 22  	 input wire [1:0] test_mode,
 23      input wire [15:0] test_phase_inc,
 24      input wire force_saturation,
 25      input wire reset_monitors,
 26      output wire [31:0] debug_sample_count,
 27      output wire [17:0] debug_internal_i,
 28      output wire [17:0] debug_internal_q
 29  );
 30  
 31  // Parameters for numerical precision
 32  parameter ADC_WIDTH = 8;
 33  parameter NCO_WIDTH = 16;
 34  parameter MIXER_WIDTH = 18;
 35  parameter OUTPUT_WIDTH = 18;
 36  
 37  // IF frequency parameters
 38  parameter IF_FREQ = 120000000;
 39  parameter FS = 400000000;
 40  parameter PHASE_WIDTH = 32;
 41  
 42  // Internal signals
 43  wire signed [15:0] sin_out, cos_out;
 44  wire nco_ready;
 45  wire cic_valid;
 46  wire fir_valid;
 47  wire [17:0] cic_i_out, cic_q_out;
 48  wire signed [17:0] fir_i_out, fir_q_out;
 49  
 50  
 51  // Diagnostic registers
 52  reg [2:0] saturation_count;
 53  reg overflow_detected;
 54  reg [7:0] error_counter;
 55  
 56  // ============================================================================
 57  // 400 MHz Reset Synchronizer
 58  //
 59  // reset_n arrives from the 100 MHz domain (sys_reset_n from radar_system_top).
 60  // Using it directly as an async reset in the 400 MHz domain causes the reset
 61  // deassertion edge to violate timing: the 100 MHz flip-flop driving reset_n
 62  // has its output fanning out to 1156 registers across the FPGA in the 400 MHz
 63  // domain, requiring 18.243ns of routing (WNS = -18.081ns).
 64  //
 65  // Solution: 2-stage async-assert, sync-deassert reset synchronizer in the
 66  // 400 MHz domain. Reset assertion is immediate (asynchronous — combinatorial
 67  // path from reset_n to all 400 MHz registers). Reset deassertion is
 68  // synchronized to clk_400m rising edge, preventing metastability.
 69  //
 70  // All 400 MHz submodules (NCO, CIC, mixers, LFSR) use reset_n_400m.
 71  // All 100 MHz submodules (FIR, output stage) continue using reset_n directly
 72  // (already synchronized to 100 MHz at radar_system_top level).
 73  // ============================================================================
 74  (* ASYNC_REG = "TRUE" *) reg [1:0] reset_sync_400m;
 75  (* max_fanout = 50 *) wire reset_n_400m = reset_sync_400m[1];
 76  
 77  // Active-high reset for DSP48E1 RST ports (avoids LUT1 inverter fan-out)
 78  (* max_fanout = 50 *) reg reset_400m;
 79  
 80  always @(posedge clk_400m or negedge reset_n) begin
 81      if (!reset_n) begin
 82          reset_sync_400m <= 2'b00;
 83          reset_400m      <= 1'b1;
 84      end else begin
 85          reset_sync_400m <= {reset_sync_400m[0], 1'b1};
 86          reset_400m      <= ~reset_sync_400m[1];
 87      end
 88  end
 89  
 90  // CDC synchronization for control signals (2-stage synchronizers)
 91  (* ASYNC_REG = "TRUE" *) reg [1:0] mixers_enable_sync_chain;
 92  (* ASYNC_REG = "TRUE" *) reg [1:0] force_saturation_sync_chain;
 93  wire mixers_enable_sync;
 94  wire force_saturation_sync;
 95  
 96  // Debug monitoring signals
 97  reg [31:0] sample_counter;
 98  wire signed [17:0] debug_mixed_i_trunc;
 99  wire signed [17:0] debug_mixed_q_trunc;
100  
101  // Real-time status monitoring
102  reg [7:0] signal_power_i, signal_power_q;
103  
104  // Internal mixing signals
105  // DSP48E1 with AREG=1, BREG=1, MREG=1, PREG=1 handles all internal pipelining
106  // Latency: 4 cycles (1 for AREG/BREG, 1 for MREG, 1 for PREG, 1 for post-DSP retiming)
107  wire signed [MIXER_WIDTH-1:0] adc_signed_w;
108  reg signed [MIXER_WIDTH + NCO_WIDTH -1:0] mixed_i, mixed_q;
109  reg mixed_valid;
110  reg mixer_overflow_i, mixer_overflow_q;
111  // Pipeline valid tracking: 4-stage shift register (3 for DSP48E1 + 1 for post-DSP retiming)
112  reg [3:0] dsp_valid_pipe;
113  // Post-DSP retiming registers — breaks DSP48E1 CLK→P to fabric timing path
114  // This extra pipeline stage absorbs the 1.866ns DSP output prop delay + routing,
115  // ensuring WNS > 0 at 400 MHz regardless of placement seed
116  (* DONT_TOUCH = "TRUE" *) reg signed [MIXER_WIDTH+NCO_WIDTH-1:0] mult_i_retimed, mult_q_retimed;
117  
118  // Output stage registers
119  reg signed [17:0] baseband_i_reg, baseband_q_reg;
120  reg baseband_valid_reg;
121  
122  // ============================================================================
123  // Phase Dithering Signals
124  // ============================================================================
125  wire [7:0] phase_dither_bits;
126  reg [31:0] phase_inc_dithered;
127  
128  
129  
130  // ============================================================================
131  // Debug Signal Assignments
132  // ============================================================================
133  assign debug_internal_i = mixed_i[25:8];
134  assign debug_internal_q = mixed_q[25:8];
135  assign debug_sample_count = sample_counter;
136  assign debug_mixed_i_trunc = mixed_i[25:8];
137  assign debug_mixed_q_trunc = mixed_q[25:8];
138  
139  // ============================================================================
140  // Clock Domain Crossing for Control Signals (2-stage synchronizers)
141  // ============================================================================
142  assign mixers_enable_sync = mixers_enable_sync_chain[1];
143  assign force_saturation_sync = force_saturation_sync_chain[1];
144  
145  always @(posedge clk_400m or negedge reset_n_400m) begin
146      if (!reset_n_400m) begin
147          mixers_enable_sync_chain <= 2'b00;
148          force_saturation_sync_chain <= 2'b00;
149      end else begin
150          mixers_enable_sync_chain <= {mixers_enable_sync_chain[0], mixers_enable};
151          force_saturation_sync_chain <= {force_saturation_sync_chain[0], force_saturation};
152      end
153  end
154  
155  // ============================================================================
156  // Sample Counter and Debug Monitoring
157  // ============================================================================
158  always @(posedge clk_400m or negedge reset_n_400m) begin
159      if (!reset_n_400m || reset_monitors) begin
160          sample_counter <= 0;
161          error_counter <= 0;
162      end else if (adc_data_valid_i && adc_data_valid_q ) begin
163          sample_counter <= sample_counter + 1;
164      end
165  end
166  
167  
168  // ============================================================================
169  // Enhanced Phase Dithering Instance
170  // ============================================================================
171  lfsr_dither_enhanced #(
172      .DITHER_WIDTH(8)
173  ) phase_dither_gen (
174      .clk(clk_400m),
175      .reset_n(reset_n_400m),
176      .enable(nco_ready),
177      .dither_out(phase_dither_bits)
178  );
179  
180  // ============================================================================
181  // Phase Increment Calculation with Dithering
182  // ============================================================================
183  // Calculate phase increment for 120MHz IF at 400MHz sampling
184  localparam PHASE_INC_120MHZ = 32'h4CCCCCCD;
185  
186  // Apply dithering to reduce spurious tones (registered for 400 MHz timing)
187  always @(posedge clk_400m or negedge reset_n_400m) begin
188      if (!reset_n_400m)
189          phase_inc_dithered <= PHASE_INC_120MHZ;
190      else
191          phase_inc_dithered <= PHASE_INC_120MHZ + {24'b0, phase_dither_bits};
192  end
193  
194  // ============================================================================
195  // Enhanced NCO with Diagnostics
196  // ============================================================================
197  nco_400m_enhanced nco_core (
198      .clk_400m(clk_400m),
199      .reset_n(reset_n_400m),
200      .frequency_tuning_word(phase_inc_dithered),
201      .phase_valid(mixers_enable),
202      .phase_offset(16'h0000),
203      .sin_out(sin_out),
204      .cos_out(cos_out),
205      .dds_ready(nco_ready)
206  );
207  
208  // ============================================================================
209  // Enhanced Mixing Stage — DSP48E1 direct instantiation for 400 MHz timing
210  //
211  // Architecture:
212  //   ADC data → sign-extend to 18b → DSP48E1 A-port (AREG=1 pipelines it)
213  //   NCO cos/sin → sign-extend to 18b → DSP48E1 B-port (BREG=1 pipelines it)
214  //   Multiply result captured by MREG=1, then output registered by PREG=1
215  //   force_saturation override applied AFTER DSP48E1 output (not on input path)
216  //
217  // Latency: 3 clock cycles (AREG/BREG + MREG + PREG)
218  // PREG=1 absorbs DSP48E1 CLK→P delay internally, preventing fabric timing violations
219  // In simulation (Icarus), uses behavioral equivalent since DSP48E1 is Xilinx-only
220  // ============================================================================
221  
222  // Combinational ADC sign conversion (no register — DSP48E1 AREG handles it)
223  assign adc_signed_w = {1'b0, adc_data, {(MIXER_WIDTH-ADC_WIDTH-1){1'b0}}} - 
224                        {1'b0, {ADC_WIDTH{1'b1}}, {(MIXER_WIDTH-ADC_WIDTH-1){1'b0}}} / 2;
225  
226  // Valid pipeline: 4-stage shift register (3 for DSP48E1 AREG+MREG+PREG + 1 for retiming)
227  always @(posedge clk_400m or negedge reset_n_400m) begin
228      if (!reset_n_400m) begin
229          dsp_valid_pipe <= 4'b0000;
230      end else begin
231          dsp_valid_pipe <= {dsp_valid_pipe[2:0], (nco_ready && adc_data_valid_i && adc_data_valid_q)};
232      end
233  end
234  
235  `ifdef SIMULATION
236  // ---- Behavioral model for Icarus Verilog simulation ----
237  // Mimics DSP48E1 with AREG=1, BREG=1, MREG=1, PREG=1 (3-cycle latency)
238  reg signed [MIXER_WIDTH-1:0] adc_signed_reg;     // Models AREG
239  reg signed [15:0] cos_pipe_reg, sin_pipe_reg;     // Models BREG
240  reg signed [MIXER_WIDTH+NCO_WIDTH-1:0] mult_i_internal, mult_q_internal;  // Models MREG
241  reg signed [MIXER_WIDTH+NCO_WIDTH-1:0] mult_i_reg, mult_q_reg;            // Models PREG
242  
243  // Stage 1: AREG/BREG equivalent
244  always @(posedge clk_400m or negedge reset_n_400m) begin
245      if (!reset_n_400m) begin
246          adc_signed_reg <= 0;
247          cos_pipe_reg <= 0;
248          sin_pipe_reg <= 0;
249      end else begin
250          adc_signed_reg <= adc_signed_w;
251          cos_pipe_reg <= cos_out;
252          sin_pipe_reg <= sin_out;
253      end
254  end
255  
256  // Stage 2: MREG equivalent
257  always @(posedge clk_400m or negedge reset_n_400m) begin
258      if (!reset_n_400m) begin
259          mult_i_internal <= 0;
260          mult_q_internal <= 0;
261      end else begin
262          mult_i_internal <= $signed(adc_signed_reg) * $signed(cos_pipe_reg);
263          mult_q_internal <= $signed(adc_signed_reg) * $signed(sin_pipe_reg);
264      end
265  end
266  
267  // Stage 3: PREG equivalent
268  always @(posedge clk_400m or negedge reset_n_400m) begin
269      if (!reset_n_400m) begin
270          mult_i_reg <= 0;
271          mult_q_reg <= 0;
272      end else begin
273          mult_i_reg <= mult_i_internal;
274          mult_q_reg <= mult_q_internal;
275      end
276  end
277  
278  // Stage 4: Post-DSP retiming register (matches synthesis path)
279  always @(posedge clk_400m or negedge reset_n_400m) begin
280      if (!reset_n_400m) begin
281          mult_i_retimed <= 0;
282          mult_q_retimed <= 0;
283      end else begin
284          mult_i_retimed <= mult_i_reg;
285          mult_q_retimed <= mult_q_reg;
286      end
287  end
288  
289  `else
290  // ---- Direct DSP48E1 instantiation for Vivado synthesis ----
291  // This guarantees AREG/BREG/MREG are used, achieving timing closure at 400 MHz
292  wire [47:0] dsp_p_i, dsp_p_q;
293  
294  // DSP48E1 for I-channel mixer (adc_signed * cos_out)
295  DSP48E1 #(
296      // Feature control attributes
297      .A_INPUT("DIRECT"),
298      .B_INPUT("DIRECT"),
299      .USE_DPORT("FALSE"),
300      .USE_MULT("MULTIPLY"),
301      .USE_SIMD("ONE48"),
302      // Pipeline register attributes — all enabled for max timing
303      .AREG(1),
304      .BREG(1),
305      .MREG(1),
306      .PREG(1),           // P register enabled — absorbs CLK→P delay for timing closure
307      .ADREG(0),
308      .ACASCREG(1),
309      .BCASCREG(1),
310      .ALUMODEREG(0),
311      .CARRYINREG(0),
312      .CARRYINSELREG(0),
313      .CREG(0),
314      .DREG(0),
315      .INMODEREG(0),
316      .OPMODEREG(0),
317      // Pattern detector (unused)
318      .AUTORESET_PATDET("NO_RESET"),
319      .MASK(48'h3fffffffffff),
320      .PATTERN(48'h000000000000),
321      .SEL_MASK("MASK"),
322      .SEL_PATTERN("PATTERN"),
323      .USE_PATTERN_DETECT("NO_PATDET")
324  ) dsp_mixer_i (
325      // Clock and reset
326      .CLK(clk_400m),
327      .RSTA(reset_400m),
328      .RSTB(reset_400m),
329      .RSTM(reset_400m),
330      .RSTP(reset_400m),
331      .RSTALLCARRYIN(1'b0),
332      .RSTALUMODE(1'b0),
333      .RSTCTRL(1'b0),
334      .RSTC(1'b0),
335      .RSTD(1'b0),
336      .RSTINMODE(1'b0),
337      // Clock enables
338      .CEA1(1'b0),       // AREG=1 uses CEA2
339      .CEA2(1'b1),
340      .CEB1(1'b0),       // BREG=1 uses CEB2
341      .CEB2(1'b1),
342      .CEM(1'b1),
343      .CEP(1'b1),         // P register clock enable (PREG=1)
344      .CEAD(1'b0),
345      .CEALUMODE(1'b0),
346      .CECARRYIN(1'b0),
347      .CECTRL(1'b0),
348      .CEC(1'b0),
349      .CED(1'b0),
350      .CEINMODE(1'b0),
351      // Data ports
352      .A({{12{adc_signed_w[MIXER_WIDTH-1]}}, adc_signed_w}),   // Sign-extend 18b to 30b
353      .B({{2{cos_out[15]}}, cos_out}),                          // Sign-extend 16b to 18b
354      .C(48'b0),
355      .D(25'b0),
356      .CARRYIN(1'b0),
357      // Control ports
358      .OPMODE(7'b0000101),       // P = M (multiply only, no accumulate)
359      .ALUMODE(4'b0000),         // Z + X + Y + CIN
360      .INMODE(5'b00000),         // A2 * B2 (direct)
361      .CARRYINSEL(3'b000),
362      // Output ports
363      .P(dsp_p_i),
364      .PATTERNDETECT(),
365      .PATTERNBDETECT(),
366      .OVERFLOW(),
367      .UNDERFLOW(),
368      .CARRYOUT(),
369      // Cascade ports (unused)
370      .ACIN(30'b0),
371      .BCIN(18'b0),
372      .CARRYCASCIN(1'b0),
373      .MULTSIGNIN(1'b0),
374      .PCIN(48'b0),
375      .ACOUT(),
376      .BCOUT(),
377      .CARRYCASCOUT(),
378      .MULTSIGNOUT(),
379      .PCOUT()
380  );
381  
382  // DSP48E1 for Q-channel mixer (adc_signed * sin_out)
383  DSP48E1 #(
384      .A_INPUT("DIRECT"),
385      .B_INPUT("DIRECT"),
386      .USE_DPORT("FALSE"),
387      .USE_MULT("MULTIPLY"),
388      .USE_SIMD("ONE48"),
389      .AREG(1),
390      .BREG(1),
391      .MREG(1),
392      .PREG(1),
393      .ADREG(0),
394      .ACASCREG(1),
395      .BCASCREG(1),
396      .ALUMODEREG(0),
397      .CARRYINREG(0),
398      .CARRYINSELREG(0),
399      .CREG(0),
400      .DREG(0),
401      .INMODEREG(0),
402      .OPMODEREG(0),
403      .AUTORESET_PATDET("NO_RESET"),
404      .MASK(48'h3fffffffffff),
405      .PATTERN(48'h000000000000),
406      .SEL_MASK("MASK"),
407      .SEL_PATTERN("PATTERN"),
408      .USE_PATTERN_DETECT("NO_PATDET")
409  ) dsp_mixer_q (
410      .CLK(clk_400m),
411      .RSTA(reset_400m),
412      .RSTB(reset_400m),
413      .RSTM(reset_400m),
414      .RSTP(reset_400m),
415      .RSTALLCARRYIN(1'b0),
416      .RSTALUMODE(1'b0),
417      .RSTCTRL(1'b0),
418      .RSTC(1'b0),
419      .RSTD(1'b0),
420      .RSTINMODE(1'b0),
421      .CEA1(1'b0),
422      .CEA2(1'b1),
423      .CEB1(1'b0),
424      .CEB2(1'b1),
425      .CEM(1'b1),
426      .CEP(1'b1),         // P register clock enable (PREG=1)
427      .CEAD(1'b0),
428      .CEALUMODE(1'b0),
429      .CECARRYIN(1'b0),
430      .CECTRL(1'b0),
431      .CEC(1'b0),
432      .CED(1'b0),
433      .CEINMODE(1'b0),
434      .A({{12{adc_signed_w[MIXER_WIDTH-1]}}, adc_signed_w}),
435      .B({{2{sin_out[15]}}, sin_out}),
436      .C(48'b0),
437      .D(25'b0),
438      .CARRYIN(1'b0),
439      .OPMODE(7'b0000101),
440      .ALUMODE(4'b0000),
441      .INMODE(5'b00000),
442      .CARRYINSEL(3'b000),
443      .P(dsp_p_q),
444      .PATTERNDETECT(),
445      .PATTERNBDETECT(),
446      .OVERFLOW(),
447      .UNDERFLOW(),
448      .CARRYOUT(),
449      .ACIN(30'b0),
450      .BCIN(18'b0),
451      .CARRYCASCIN(1'b0),
452      .MULTSIGNIN(1'b0),
453      .PCIN(48'b0),
454      .ACOUT(),
455      .BCOUT(),
456      .CARRYCASCOUT(),
457      .MULTSIGNOUT(),
458      .PCOUT()
459  );
460  
461  // Extract the multiply result from DSP48E1 P output
462  // adc_signed is 18 bits, NCO is 16 bits → product is 34 bits (bits [33:0] of P)
463  wire signed [MIXER_WIDTH+NCO_WIDTH-1:0] mult_i_reg = dsp_p_i[MIXER_WIDTH+NCO_WIDTH-1:0];
464  wire signed [MIXER_WIDTH+NCO_WIDTH-1:0] mult_q_reg = dsp_p_q[MIXER_WIDTH+NCO_WIDTH-1:0];
465  
466  // Stage 4: Post-DSP retiming register — breaks DSP48E1 CLK→P to fabric path
467  // Without this, the DSP output prop delay (1.866ns) + routing (0.515ns) exceeds
468  // the 2.500ns clock period at slow process corner
469  always @(posedge clk_400m or negedge reset_n_400m) begin
470      if (!reset_n_400m) begin
471          mult_i_retimed <= 0;
472          mult_q_retimed <= 0;
473      end else begin
474          mult_i_retimed <= mult_i_reg;
475          mult_q_retimed <= mult_q_reg;
476      end
477  end
478  
479  `endif
480  
481  // ============================================================================
482  // Post-DSP48E1 output stage: force_saturation override + overflow detection
483  // force_saturation mux is intentionally AFTER the DSP48E1 output to avoid
484  // polluting the critical input path with extra logic
485  // ============================================================================
486  always @(posedge clk_400m or negedge reset_n_400m) begin
487      if (!reset_n_400m) begin
488          mixed_i <= 0;
489          mixed_q <= 0;
490          mixed_valid <= 0;
491          mixer_overflow_i <= 0;
492          mixer_overflow_q <= 0;
493          saturation_count <= 0;
494          overflow_detected <= 0;
495      end else if (dsp_valid_pipe[3]) begin
496          // Force saturation for testing (applied after DSP output, not on input path)
497          if (force_saturation_sync) begin
498              mixed_i <= 34'h1FFFFFFFF;
499              mixed_q <= 34'h200000000;
500              mixer_overflow_i <= 1'b1;
501              mixer_overflow_q <= 1'b1;
502          end else begin
503              // Normal path: take retimed DSP48E1 multiply result
504              mixed_i <= mult_i_retimed;
505              mixed_q <= mult_q_retimed;
506              
507              // Overflow detection on retimed multiply result
508              mixer_overflow_i <= (mult_i_retimed > (2**(MIXER_WIDTH+NCO_WIDTH-2)-1)) || 
509                                 (mult_i_retimed < -(2**(MIXER_WIDTH+NCO_WIDTH-2)));
510              mixer_overflow_q <= (mult_q_retimed > (2**(MIXER_WIDTH+NCO_WIDTH-2)-1)) || 
511                                 (mult_q_retimed < -(2**(MIXER_WIDTH+NCO_WIDTH-2)));
512          end
513          
514          mixed_valid <= 1;
515          
516          if (mixer_overflow_i || mixer_overflow_q) begin
517              saturation_count <= saturation_count + 1;
518              overflow_detected <= 1'b1;
519          end else begin
520              overflow_detected <= 1'b0;
521          end
522          
523      end else begin
524          mixed_valid <= 0;
525          mixer_overflow_i <= 0;
526          mixer_overflow_q <= 0;
527          overflow_detected <= 1'b0;
528      end
529  end
530  
531  // ============================================================================
532  // Enhanced CIC Decimators
533  // ============================================================================
534  wire cic_valid_i, cic_valid_q;
535  
536  cic_decimator_4x_enhanced cic_i_inst (
537      .clk(clk_400m),
538      .reset_n(reset_n_400m),
539      .data_in(mixed_i[33:16]),
540      .data_valid(mixed_valid),
541      .data_out(cic_i_out),
542      .data_out_valid(cic_valid_i)
543  );
544  
545  cic_decimator_4x_enhanced cic_q_inst (
546      .clk(clk_400m),
547      .reset_n(reset_n_400m),
548      .data_in(mixed_q[33:16]),
549      .data_valid(mixed_valid),
550      .data_out(cic_q_out),
551      .data_out_valid(cic_valid_q)
552  );
553  
554  assign cic_valid = cic_valid_i & cic_valid_q;
555  
556  // ============================================================================
557  // Enhanced FIR Filters with FIXED valid signal handling
558  // NOTE: Wire declarations moved BEFORE CDC instances to fix forward-reference
559  //       error in Icarus Verilog (was originally after CDC instantiation)
560  // ============================================================================
561  wire fir_in_valid_i, fir_in_valid_q;
562  wire fir_valid_i, fir_valid_q;
563  wire fir_i_ready, fir_q_ready;
564  wire [17:0] fir_d_in_i, fir_d_in_q; 
565  
566  cdc_adc_to_processing #(
567      .WIDTH(18),
568      .STAGES(3)
569  )CDC_FIR_i(
570      .src_clk(clk_400m),
571      .dst_clk(clk_100m),
572      .src_reset_n(reset_n_400m),
573      .dst_reset_n(reset_n),
574      .src_data(cic_i_out),
575      .src_valid(cic_valid_i),
576      .dst_data(fir_d_in_i),
577      .dst_valid(fir_in_valid_i)
578  );
579  
580  cdc_adc_to_processing #(
581      .WIDTH(18),
582      .STAGES(3)
583  )CDC_FIR_q(
584      .src_clk(clk_400m),
585      .dst_clk(clk_100m),
586      .src_reset_n(reset_n_400m),
587      .dst_reset_n(reset_n),
588      .src_data(cic_q_out),
589      .src_valid(cic_valid_q),
590      .dst_data(fir_d_in_q),
591      .dst_valid(fir_in_valid_q)
592  );
593  
594  // ============================================================================
595  // FIR Filter Instances
596  // ============================================================================
597  
598  // FIR I channel
599  fir_lowpass_parallel_enhanced fir_i_inst (
600      .clk(clk_100m),
601      .reset_n(reset_n),
602      .data_in(fir_d_in_i),  // Use synchronized data
603      .data_valid(fir_in_valid_i),  // Use synchronized valid
604      .data_out(fir_i_out),
605      .data_out_valid(fir_valid_i),
606      .fir_ready(fir_i_ready),
607      .filter_overflow()
608  );
609  
610  // FIR Q channel  
611  fir_lowpass_parallel_enhanced fir_q_inst (
612      .clk(clk_100m),
613      .reset_n(reset_n),
614      .data_in(fir_d_in_q),  // Use synchronized data
615      .data_valid(fir_in_valid_q),  // Use synchronized valid
616      .data_out(fir_q_out),
617      .data_out_valid(fir_valid_q),
618      .fir_ready(fir_q_ready),
619      .filter_overflow()
620  );
621  
622  assign fir_valid = fir_valid_i & fir_valid_q;
623  
624  // ============================================================================
625  // Enhanced Output Stage
626  // ============================================================================
627  always @(posedge clk_100m or negedge reset_n) begin
628      if (!reset_n) begin
629          baseband_i_reg <= 0;
630          baseband_q_reg <= 0;
631          baseband_valid_reg <= 0;
632      end else if (fir_valid) begin
633          baseband_i_reg <= fir_i_out;
634          baseband_q_reg <= fir_q_out;
635          baseband_valid_reg <= 1;
636      end else begin
637          baseband_valid_reg <= 0;
638      end
639  end
640  
641  
642  // ============================================================================
643  // Output Assignments
644  // ============================================================================
645  assign baseband_i = baseband_i_reg;
646  assign baseband_q = baseband_q_reg;
647  assign baseband_valid_i = baseband_valid_reg;
648  assign baseband_valid_q = baseband_valid_reg;
649  assign ddc_status = {mixer_overflow_i | mixer_overflow_q, nco_ready};
650  assign mixer_saturation = overflow_detected;
651  assign ddc_diagnostics = {saturation_count, error_counter[4:0]};
652  
653  // ============================================================================
654  // Enhanced Debug and Monitoring
655  // ============================================================================
656  reg [31:0] debug_cic_count, debug_fir_count, debug_bb_count;
657  
658  `ifdef SIMULATION
659  always @(posedge clk_100m) begin
660      
661      if (fir_valid_i && debug_fir_count < 20) begin
662          debug_fir_count <= debug_fir_count + 1;
663          $display("FIR_OUTPUT: fir_i=%6d, fir_q=%6d", fir_i_out, fir_q_out);
664      end
665      
666      if (adc_data_valid_i && adc_data_valid_q && debug_bb_count < 20) begin
667          debug_bb_count <= debug_bb_count + 1;
668          $display("BASEBAND_OUT: i=%6d, q=%6d, count=%0d", 
669                   baseband_i, baseband_q, debug_bb_count);
670      end
671  end
672  `endif
673  
674  // In ddc_400m.v, add these debug signals:
675  
676  // Debug monitoring (simulation only)
677  `ifdef SIMULATION
678  reg [31:0] debug_adc_count = 0;
679  reg [31:0] debug_baseband_count = 0;
680  
681  always @(posedge clk_400m) begin
682      if (adc_data_valid_i && adc_data_valid_q && debug_adc_count < 10) begin
683          debug_adc_count <= debug_adc_count + 1;
684          $display("DDC_ADC: data=%0d, count=%0d, time=%t", 
685                   adc_data, debug_adc_count, $time);
686      end
687  end
688  
689  always @(posedge clk_100m) begin
690      if (baseband_valid_i && baseband_valid_q && debug_baseband_count < 10) begin
691          debug_baseband_count <= debug_baseband_count + 1;
692          $display("DDC_BASEBAND: i=%0d, q=%0d, count=%0d, time=%t", 
693                   baseband_i, baseband_q, debug_baseband_count, $time);
694      end
695  end
696  `endif
697  
698  
699  endmodule
700  
701  // ============================================================================
702  // Enhanced Phase Dithering Module
703  // ============================================================================
704  `timescale 1ns / 1ps
705  
706  module lfsr_dither_enhanced #(
707      parameter DITHER_WIDTH = 8  // Increased for better dithering
708  )(
709      input wire clk,
710      input wire reset_n,
711      input wire enable,
712      output wire [DITHER_WIDTH-1:0] dither_out
713  );
714  
715  reg [DITHER_WIDTH-1:0] lfsr_reg;
716  reg [15:0] cycle_counter;
717  reg lock_detected;
718  
719  // Polynomial for better randomness: x^8 + x^6 + x^5 + x^4 + 1
720  wire feedback;
721  
722  generate
723      if (DITHER_WIDTH == 4) begin
724          assign feedback = lfsr_reg[3] ^ lfsr_reg[2];
725      end else if (DITHER_WIDTH == 8) begin
726          assign feedback = lfsr_reg[7] ^ lfsr_reg[5] ^ lfsr_reg[4] ^ lfsr_reg[3];
727      end else begin
728          assign feedback = lfsr_reg[DITHER_WIDTH-1] ^ lfsr_reg[DITHER_WIDTH-2];
729      end
730  endgenerate
731  
732  always @(posedge clk or negedge reset_n) begin
733      if (!reset_n) begin
734          lfsr_reg <= {DITHER_WIDTH{1'b1}};  // Non-zero initial state
735          cycle_counter <= 0;
736          lock_detected <= 0;
737      end else if (enable) begin
738          lfsr_reg <= {lfsr_reg[DITHER_WIDTH-2:0], feedback};
739          cycle_counter <= cycle_counter + 1;
740          
741          // Detect LFSR lock after sufficient cycles
742          if (cycle_counter > (2**DITHER_WIDTH * 8)) begin
743              lock_detected <= 1'b1;
744          end
745      end
746  end
747  
748  assign dither_out = lfsr_reg;
749  
750  endmodule