fix(pre-bringup): second-batch P1/P2/P3 audit findings
Addresses the remaining actionable items from
docs/DEVELOP_AUDIT_2026-04-19.md after commit 3f47d1e.
XDC (dead waivers — F-0.4, F-0.5, F-0.6, F-0.7):
- ft_clkout_IBUF CLOCK_DEDICATED_ROUTE now uses hierarchical filter;
flat net name did not exist post-synth.
- reset_sync_reg[*] false-path rewritten to walk hierarchy and filter
on CLR/PRE pins.
- adc_clk_mmcm.xdc ft601_clk_in references replaced with foreach-loop
over real USB clock names, gated on -quiet existence.
- MMCM LOCKED waiver uses REF_PIN_NAME filter instead of the
previously-missing u_core/ literal path.
CDC (F-1.1, F-1.2, F-1.3):
- Documented the quasi-static-bus stability invariant above the
FT601 cmd_valid toggle block.
- cdc_adc_to_processing gains an `overrun` output; the two CIC->FIR
instances feed a sticky cdc_cic_fir_overrun flag surfaced on
gpio_dig5 so silent sample drops become visible to the MCU.
- Removed the dead mixers_enable synchronizer in ddc_400m.v; the _sync
output was unused and every caller ties the port to 1'b1.
Diagnostics (F-6.4):
- range_bin_decimator watchdog_timeout plumbed through receiver
and top-level, OR'd into gpio_dig5.
ADAR (F-4.7):
- delayUs() replaced with DWT cycle counter; self-initialising
TRCENA/CYCCNTENA, overflow-safe unsigned subtraction.
Regression: tb_cdc_modules.v 57/57 passes under iverilog after
the cdc_modules.v change. Remote Vivado verification in progress.
This commit is contained in:
@@ -17,7 +17,12 @@ module cdc_adc_to_processing #(
|
||||
input wire [WIDTH-1:0] src_data,
|
||||
input wire src_valid,
|
||||
output wire [WIDTH-1:0] dst_data,
|
||||
output wire dst_valid
|
||||
output wire dst_valid,
|
||||
// Audit F-1.2: overrun pulse in src_clk domain. Asserts for 1 src cycle
|
||||
// whenever src_valid fires while the previous sample has not yet been
|
||||
// acknowledged by the destination edge-detector (i.e., the transaction
|
||||
// the CDC is silently dropping). Hold/count externally.
|
||||
output wire overrun
|
||||
`ifdef FORMAL
|
||||
,output wire [WIDTH-1:0] fv_src_data_reg,
|
||||
output wire [1:0] fv_src_toggle
|
||||
@@ -130,6 +135,36 @@ module cdc_adc_to_processing #(
|
||||
assign dst_data = dst_data_reg;
|
||||
assign dst_valid = dst_valid_reg;
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Audit F-1.2: overrun detection
|
||||
//
|
||||
// The src-side `src_toggle` counter flips on each latched src_valid.
|
||||
// We feed back a 1-bit "ack" toggle from the dst domain (flipped each
|
||||
// time dst_valid fires) through a STAGES-deep synchronizer into the
|
||||
// src domain. If a new src_valid arrives while src_toggle[0] already
|
||||
// differs from the acked value, the previous sample is still in flight
|
||||
// and this new latch drops it. Emit a 1-cycle overrun pulse.
|
||||
// ------------------------------------------------------------------
|
||||
reg dst_ack_toggle;
|
||||
always @(posedge dst_clk) begin
|
||||
if (!dst_reset_n) dst_ack_toggle <= 1'b0;
|
||||
else if (dst_valid_reg) dst_ack_toggle <= ~dst_ack_toggle;
|
||||
end
|
||||
|
||||
(* ASYNC_REG = "TRUE" *) reg [STAGES-1:0] ack_sync_chain;
|
||||
always @(posedge src_clk) begin
|
||||
if (!src_reset_n) ack_sync_chain <= {STAGES{1'b0}};
|
||||
else ack_sync_chain <= {ack_sync_chain[STAGES-2:0], dst_ack_toggle};
|
||||
end
|
||||
wire ack_in_src = ack_sync_chain[STAGES-1];
|
||||
|
||||
reg overrun_r;
|
||||
always @(posedge src_clk) begin
|
||||
if (!src_reset_n) overrun_r <= 1'b0;
|
||||
else overrun_r <= src_valid && (src_toggle[0] != ack_in_src);
|
||||
end
|
||||
assign overrun = overrun_r;
|
||||
|
||||
`ifdef FORMAL
|
||||
assign fv_src_data_reg = src_data_reg;
|
||||
assign fv_src_toggle = src_toggle;
|
||||
|
||||
Reference in New Issue
Block a user