From 4d38451f2a11d07ccad66d82bf9517318602f31a Mon Sep 17 00:00:00 2001 From: Javier Valenzuela Date: Tue, 19 Sep 2023 13:05:19 -0500 Subject: [PATCH] fpga: x400: pps_sync cleanup Original-commit: 4527a8f70d35d88f8cd75dd358fff07f29496f4f --- top/x400/x4xx_pps_sync.v | 71 +++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/top/x400/x4xx_pps_sync.v b/top/x400/x4xx_pps_sync.v index 8787777..53f7f0d 100644 --- a/top/x400/x4xx_pps_sync.v +++ b/top/x400/x4xx_pps_sync.v @@ -44,7 +44,7 @@ module x4xx_pps_sync #( output wire pll_sync_done, input wire [7:0] pps_brc_delay, input wire [25:0] pps_prc_delay, - input wire [3:0] prc_rc_divider, + input wire [9:0] prc_rc_divider, input wire pps_rc_enabled, //signal for debugging @@ -325,7 +325,7 @@ module x4xx_pps_sync #( // On the aligned edge of BRC and PRC this synchronizer is just a two stage // delay into the PRC domain as the edges occur at the same time the tools // should make sure we close timing on this edge - + wire pps_prc; synchronizer #( .FALSE_PATH_TO_IN (0) @@ -363,6 +363,11 @@ module x4xx_pps_sync #( always @(posedge pll_ref_clk) begin // Disable delayed rising edge by default pps_delayed_prc <= 1'b0; + // pps_delayed_prc should assert one PRC clock cycle before the aligned edge, + // so that it can be transferred to the radio clock domain when PRC and radio_clock + // run at the same rate. pps_delayed_prc_out holds the PPS on PRC domain delayed to + // the aligned edge. + pps_delayed_prc_out <= pps_delayed_prc; pps_prc_delayed <= pps_prc; // Reset counter on rising edge @@ -386,21 +391,28 @@ module x4xx_pps_sync #( // rc. The divider has to account for the output register and the shift // register. - wire [3:0] prc_rc_divider_rc; - wire [1:0] pps_rc_enabled_rc; - wire [1:0] pps_delayed_prc_rc; - reg [7:0] pps_shift_reg_rc = 8'b0; genvar rc_sync_i; generate for (rc_sync_i = 0; rc_sync_i < 2; rc_sync_i = rc_sync_i+1) begin : gen_rc_sync - synchronizer #( - .FALSE_PATH_TO_IN (1), - .WIDTH (2) + + wire [ 4:0] prc_rc_divider_rc; + reg [ 4:0] prc_rc_divider_reg_rc = 5'b0; + wire prc_rc_divider_valid; + wire pps_rc_enabled_rc; + // Make signal one bit longer than maximum divider value to enable t-1 comparison. + reg [31:0] pps_shift_reg_rc = 32'b0; + + handshake #( + .WIDTH (5) ) synchronizer_prc_rc_divider ( - .clk (radio_clk[rc_sync_i]), - .rst (1'b0), - .in (prc_rc_divider[2*rc_sync_i+:2]), - .out (prc_rc_divider_rc[2*rc_sync_i+:2]) + .clk_a (ctrl_clk), + .rst_a (1'b0), + .valid_a (1'b1), + .data_a (prc_rc_divider[5*rc_sync_i+:5]), + .busy_a (), + .clk_b (radio_clk[rc_sync_i]), + .valid_b (prc_rc_divider_valid), + .data_b (prc_rc_divider_rc) ); synchronizer #( .FALSE_PATH_TO_IN (1) @@ -408,31 +420,22 @@ module x4xx_pps_sync #( .clk (radio_clk[rc_sync_i]), .rst (1'b0), .in (pps_rc_enabled), - .out (pps_rc_enabled_rc[rc_sync_i]) - ); - synchronizer #( - .FALSE_PATH_TO_IN (1) - ) synchronizer_pps_rc ( - .clk (radio_clk[rc_sync_i]), - .rst (1'b0), - .in (pps_delayed_prc), - .out (pps_delayed_prc_rc[rc_sync_i]) + .out (pps_rc_enabled_rc) ); + + always @(posedge radio_clk[rc_sync_i]) begin + if (prc_rc_divider_valid) begin + prc_rc_divider_reg_rc <= prc_rc_divider_rc; + end + pps_shift_reg_rc <= {pps_shift_reg_rc[30:0], pps_delayed_prc}; + // Restoring a one clock cycle pulse by feeding back to output value. + pps_out_rc[rc_sync_i] <= pps_shift_reg_rc[prc_rc_divider_reg_rc] & + ~pps_shift_reg_rc[prc_rc_divider_reg_rc+1] & pps_rc_enabled_rc; + end + end endgenerate - always @(posedge radio_clk[0]) begin - pps_shift_reg_rc[3:0] <= {pps_shift_reg_rc[2:0], pps_delayed_prc}; - // Restoring a one clock cycle pulse by feeding back to output value. - pps_out_rc[0] <= pps_shift_reg_rc[prc_rc_divider_rc[1:0]] & ~pps_out_rc[0] & pps_rc_enabled_rc[0]; - end - - always @(posedge radio_clk[1]) begin - pps_shift_reg_rc[7:4] <= {pps_shift_reg_rc[6:4], pps_delayed_prc}; - // Restoring a one clock cycle pulse by feeding back to output value. - pps_out_rc[1] <= pps_shift_reg_rc[prc_rc_divider_rc[3:2]] & ~pps_out_rc[1] & pps_rc_enabled_rc[1]; - end - //--------------------------------------------------------------------------- // Debug assignment //---------------------------------------------------------------------------