Fix P0/P1 RTL bugs found during pre-hardware audit
P0-1: nco_400m_enhanced.v — DSP48E1 OPMODE corrected from PCIN to P
feedback (was routing stale cascade data into accumulator)
P0-2: radar_receiver_final.v — removed same-clock CDC that corrupted
ADC data path between ad9484_interface and DDC
P1-5: fir_lowpass.v — fixed zero replication count in coefficient
symmetric extension ({0{1'b0}} is empty, now uses explicit 0)
Also updates .gitignore to exclude debug/scratch artifacts.
All 30+ testbenches pass (unit, co-sim, integration).
This commit is contained in:
+19
@@ -10,6 +10,25 @@ rbd_mode10_avg.csv
|
|||||||
rbd_mode10_ramp.csv
|
rbd_mode10_ramp.csv
|
||||||
rmc_autoscan.csv
|
rmc_autoscan.csv
|
||||||
|
|
||||||
|
# Debug / scratch RTL (not part of the design)
|
||||||
|
9_Firmware/9_2_FPGA/debug_*.v
|
||||||
|
9_Firmware/9_2_FPGA/tb/tb_fft_debug*.v
|
||||||
|
9_Firmware/9_2_FPGA/tb/tb_fft_mini*.v
|
||||||
|
9_Firmware/9_2_FPGA/tb/tb_bram_debug.v
|
||||||
|
|
||||||
|
# Stray CSV artifacts from unit testbenches
|
||||||
|
9_Firmware/9_2_FPGA/cic_*.csv
|
||||||
|
9_Firmware/9_2_FPGA/fir_*.csv
|
||||||
|
9_Firmware/9_2_FPGA/nco_*.csv
|
||||||
|
9_Firmware/9_2_FPGA/ddc_*.csv
|
||||||
|
9_Firmware/9_2_FPGA/mf_pipeline_output.csv
|
||||||
|
9_Firmware/9_2_FPGA/tb_usb_data_interface.csv
|
||||||
|
|
||||||
|
# Co-sim intermediate CSVs (regenerated by scripts)
|
||||||
|
9_Firmware/9_2_FPGA/tb/cosim/rtl_doppler_*.csv
|
||||||
|
9_Firmware/9_2_FPGA/tb/cosim/compare_doppler_*.csv
|
||||||
|
9_Firmware/9_2_FPGA/tb/cosim/rtl_multiseg_*.csv
|
||||||
|
|
||||||
# macOS
|
# macOS
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
|||||||
@@ -117,8 +117,11 @@ always @(posedge clk or negedge reset_n) begin
|
|||||||
end
|
end
|
||||||
end else if (valid_pipe[0]) begin
|
end else if (valid_pipe[0]) begin
|
||||||
for (i = 0; i < 16; i = i + 1) begin
|
for (i = 0; i < 16; i = i + 1) begin
|
||||||
add_l0[i] <= {{(ACCUM_WIDTH-DATA_WIDTH-COEFF_WIDTH){mult_result[2*i][DATA_WIDTH+COEFF_WIDTH-1]}}, mult_result[2*i]} +
|
// mult_result is (DATA_WIDTH + COEFF_WIDTH) = 36 bits = ACCUM_WIDTH,
|
||||||
{{(ACCUM_WIDTH-DATA_WIDTH-COEFF_WIDTH){mult_result[2*i+1][DATA_WIDTH+COEFF_WIDTH-1]}}, mult_result[2*i+1]};
|
// so no sign extension is needed. Direct assignment preserves the
|
||||||
|
// signed multiply result. (Fixes Vivado Synth 8-693 "zero replication
|
||||||
|
// count" warning from the original {0{sign_bit}} expression.)
|
||||||
|
add_l0[i] <= mult_result[2*i] + mult_result[2*i+1];
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ DSP48E1 #(
|
|||||||
.D(25'b0),
|
.D(25'b0),
|
||||||
.CARRYIN(1'b0),
|
.CARRYIN(1'b0),
|
||||||
// Control ports
|
// Control ports
|
||||||
.OPMODE(7'b0010011), // Z=P (010), Y=0 (00), X=C_reg (11) → P = P + C
|
.OPMODE(7'b0101100), // Z=P (010), Y=C (11), X=0 (00) → P = P + C
|
||||||
.ALUMODE(4'b0000), // Z + X + Y + CIN (standard add)
|
.ALUMODE(4'b0000), // Z + X + Y + CIN (standard add)
|
||||||
.INMODE(5'b00000),
|
.INMODE(5'b00000),
|
||||||
.CARRYINSEL(3'b000),
|
.CARRYINSEL(3'b000),
|
||||||
|
|||||||
@@ -103,9 +103,6 @@ wire clk_400m;
|
|||||||
wire [7:0] adc_data_cmos; // 8-bit ADC data (CMOS, from ad9484_interface_400m)
|
wire [7:0] adc_data_cmos; // 8-bit ADC data (CMOS, from ad9484_interface_400m)
|
||||||
wire adc_valid; // Data valid signal
|
wire adc_valid; // Data valid signal
|
||||||
|
|
||||||
wire [7:0] cdc_data_cmos; // 8-bit ADC data (CMOS)
|
|
||||||
wire cdc_valid; // Data valid signal
|
|
||||||
|
|
||||||
// ADC power-down control (directly tie low = ADC always on)
|
// ADC power-down control (directly tie low = ADC always on)
|
||||||
assign adc_pwdn = 1'b0;
|
assign adc_pwdn = 1'b0;
|
||||||
|
|
||||||
@@ -121,18 +118,12 @@ ad9484_interface_400m adc (
|
|||||||
.adc_dco_bufg(clk_400m)
|
.adc_dco_bufg(clk_400m)
|
||||||
);
|
);
|
||||||
|
|
||||||
cdc_adc_to_processing #(
|
// NOTE: The cdc_adc_to_processing instance that was here used src_clk=dst_clk=clk_400m
|
||||||
.WIDTH(8),
|
// (same clock domain — no crossing). Gray-code CDC on same-clock with fast-changing
|
||||||
.STAGES(3)
|
// ADC data corrupts samples because Gray coding only guarantees safe transfer of
|
||||||
)cdc(
|
// values that change by 1 LSB at a time. The real 400MHz→100MHz CDC crossing is
|
||||||
.src_clk(clk_400m),
|
// handled inside ddc_400m_enhanced via CIC decimation + CDC_FIR instances.
|
||||||
.dst_clk(clk_400m),
|
// Removed: cdc_adc_to_processing instance. ADC data now goes directly to DDC.
|
||||||
.reset_n(reset_n),
|
|
||||||
.src_data(adc_data_cmos),
|
|
||||||
.src_valid(adc_valid),
|
|
||||||
.dst_data(cdc_data_cmos),
|
|
||||||
.dst_valid(cdc_valid)
|
|
||||||
);
|
|
||||||
|
|
||||||
// 2. DDC Input Interface
|
// 2. DDC Input Interface
|
||||||
wire signed [17:0] ddc_out_i;
|
wire signed [17:0] ddc_out_i;
|
||||||
@@ -145,9 +136,9 @@ ddc_400m_enhanced ddc(
|
|||||||
.clk_400m(clk_400m), // 400MHz clock from ADC DCO
|
.clk_400m(clk_400m), // 400MHz clock from ADC DCO
|
||||||
.clk_100m(clk), // 100MHz system clock //used by the 2 FIR
|
.clk_100m(clk), // 100MHz system clock //used by the 2 FIR
|
||||||
.reset_n(reset_n),
|
.reset_n(reset_n),
|
||||||
.adc_data(cdc_data_cmos), // ADC data at 400MHz (unsigned 0-255)
|
.adc_data(adc_data_cmos), // ADC data at 400MHz (direct from ADC interface)
|
||||||
.adc_data_valid_i(cdc_valid), // Valid at 400MHz
|
.adc_data_valid_i(adc_valid), // Valid at 400MHz
|
||||||
.adc_data_valid_q(cdc_valid), // Valid at 400MHz
|
.adc_data_valid_q(adc_valid), // Valid at 400MHz
|
||||||
.baseband_i(ddc_out_i), // I output at 100MHz
|
.baseband_i(ddc_out_i), // I output at 100MHz
|
||||||
.baseband_q(ddc_out_q), // Q output at 100MHz
|
.baseband_q(ddc_out_q), // Q output at 100MHz
|
||||||
.baseband_valid_i(ddc_valid_i), // Valid at 100MHz
|
.baseband_valid_i(ddc_valid_i), // Valid at 100MHz
|
||||||
|
|||||||
Reference in New Issue
Block a user