diff --git a/libraries/io/aduh/src/vhdl/lvdsh_dd_phs4_align.vhd b/libraries/io/aduh/src/vhdl/lvdsh_dd_phs4_align.vhd index da1c701c704003b20f3966a89c4e6f19c5685753..9c529d93cd969dc04feaaa8a23704f8708e40570 100644 --- a/libraries/io/aduh/src/vhdl/lvdsh_dd_phs4_align.vhd +++ b/libraries/io/aduh/src/vhdl/lvdsh_dd_phs4_align.vhd @@ -28,11 +28,21 @@ USE common_lib.common_pkg.ALL; -- Description: -- The 800 MHz in_dat samples have already been captured at the pin by -- a common_ddio_in component. +-- Default in_maintain_phs='0' to achieve and restore word alignment. Once +-- word alignment has been achieved in_maintain_phs can be set to '1' to +-- maintain this alignment and ignore any subsequent timing jitter +-- between in_clk and dp_clk. This avoids that a too severe timing jitter +-- would cause a restore action on the word alignment, which then +-- could lead to an unwanted sample shift in the out_dat. The assumption +-- is that the initial word alignment that is found is good enough. Any +-- remaining sample phase uncertainty that could occur after a power cycle +-- needs to be calibrated for at a higher level. ENTITY lvdsh_dd_phs4_align IS GENERIC ( g_wb_factor : NATURAL := 4; -- fixed wideband factor 4 = c_rx_factor*c_dd_factor g_nof_dp_phs_clk : NATURAL := 2; -- nof dp_phs_clk that can be used to detect lock + g_dp_phs_clk_period : NATURAL := 32; -- number of dp_clk periods per dp_phs_clk period, must match g_clk*_divide_by in unb_clk200_pll g_dd_phs_locked_w : NATURAL := 8; -- used to ensure that dd_phs_locked is only declared if dd_phs_detected is stable for at least 2**(g_dd_phs_locked_w-1) cycles g_in_dat_w : NATURAL := 8 -- nof PHY data bits ); @@ -46,6 +56,7 @@ ENTITY lvdsh_dd_phs4_align IS in_clk : IN STD_LOGIC := '1'; in_dat_hi : IN STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0); -- input samples [t1], [t3], [t5], [t7], ... --> time in_dat_lo : IN STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0); -- input samples [t0], [t2], [t4], [t6], ... --> time + in_maintain_phs : IN STD_LOGIC := '0'; raw_phs : OUT STD_LOGIC_VECTOR( g_wb_factor-1 DOWNTO 0); -- the measured sample phase before realignment out_phs_locked : OUT STD_LOGIC; -- '1' when realigned sample phase is stable and correct for at least 2**(g_dd_phs_locked_w-1) cycles @@ -58,10 +69,13 @@ END lvdsh_dd_phs4_align; ARCHITECTURE str OF lvdsh_dd_phs4_align IS - CONSTANT c_delay_len : NATURAL := c_meta_delay_len; CONSTANT c_ref_pipeline : NATURAL := 1; -- need pipeline to achieve 400 MHz when g_nof_dp_phs_clk=8 + CONSTANT c_align_pipeline : NATURAL := 1; -- use pipeline to achieve 400 MHz + CONSTANT c_offset_delay_len : INTEGER := c_ref_pipeline+c_align_pipeline; -- = 1+1 + CONSTANT c_delay_len : NATURAL := c_meta_delay_len+c_offset_delay_len; -- = 3 + 1+1 CONSTANT c_dd_factor : NATURAL := 2; -- fixed double data rate factor CONSTANT c_rx_factor : NATURAL := 2; -- fixed for g_wb_factor = c_rx_factor*c_dd_factor = 4 + CONSTANT c_in_phs_clk_period : NATURAL := c_dd_factor*g_dp_phs_clk_period; CONSTANT c_dd_phs_w : NATURAL := g_wb_factor; -- = 4 * 1b = 4b CONSTANT c_dd_dat_w : NATURAL := g_wb_factor*g_in_dat_w; -- = 4 * 8b = 32b CONSTANT c_exp_raw_phs_arr : t_natural_arr(g_wb_factor-1 DOWNTO 0) := (3, 6, 12, 9); -- the expected word phase before realignment is fixed, the other values in the range indicate incorrect phase detection @@ -71,6 +85,9 @@ ARCHITECTURE str OF lvdsh_dd_phs4_align IS SIGNAL ref_f_vec : STD_LOGIC_VECTOR(g_nof_dp_phs_clk-1 DOWNTO 0); SIGNAL sel_r : STD_LOGIC; SIGNAL sel_f : STD_LOGIC; + SIGNAL ref_align_en : STD_LOGIC; + SIGNAL ref_align_r : STD_LOGIC; + SIGNAL ref_align_f : STD_LOGIC; SIGNAL ref_r : STD_LOGIC; SIGNAL ref_f : STD_LOGIC; SIGNAL sync_r : STD_LOGIC; @@ -138,7 +155,7 @@ BEGIN g_rising_edge => TRUE, g_phase_rst_level => '1', g_meta_delay_len => c_delay_len, - g_offset_delay_len => -c_ref_pipeline, + g_offset_delay_len => -c_offset_delay_len, g_clk_factor => c_rx_factor ) PORT MAP ( @@ -154,7 +171,7 @@ BEGIN g_rising_edge => FALSE, g_phase_rst_level => '1', g_meta_delay_len => c_delay_len, - g_offset_delay_len => -c_ref_pipeline, + g_offset_delay_len => -c_offset_delay_len, g_clk_factor => c_rx_factor ) PORT MAP ( @@ -179,7 +196,7 @@ BEGIN rst => in_rst, clk => in_clk, in_dat => sel_r, - out_dat => ref_r + out_dat => ref_align_r ); u_pipeline_ref_f : ENTITY common_lib.common_pipeline_sl @@ -191,7 +208,42 @@ BEGIN rst => in_rst, clk => in_clk, in_dat => sel_f, - out_dat => ref_f + out_dat => ref_align_f + ); + + ------------------------------------------------------------------------------ + -- Enable word phase alignment to sel_r and sel_f or maintain current alignment + ------------------------------------------------------------------------------ + -- The current alignment is fixed by no longer allowing sel_r and sel_f to adjust the ref_r and ref_f toggling + + ref_align_en <= NOT in_maintain_phs; + + u_common_toggle_align_ref_r : ENTITY common_lib.common_toggle_align + GENERIC MAP ( + g_pipeline => c_align_pipeline, + g_reset_value => 0, + g_nof_clk_per_period => c_in_phs_clk_period + ) + PORT MAP ( + rst => in_rst, + clk => in_clk, + in_align => ref_align_en, + in_toggle => ref_align_r, + out_toggle => ref_r + ); + + u_common_toggle_align_ref_f : ENTITY common_lib.common_toggle_align + GENERIC MAP ( + g_pipeline => c_align_pipeline, + g_reset_value => 0, + g_nof_clk_per_period => c_in_phs_clk_period + ) + PORT MAP ( + rst => in_rst, + clk => in_clk, + in_align => ref_align_en, + in_toggle => ref_align_f, + out_toggle => ref_f ); ------------------------------------------------------------------------------ @@ -286,10 +338,15 @@ BEGIN -- . Note: a single sample phase shift due to missing a sample (when g_clk_drift=-2 ps in tb) is not noticed in realigned dd_phs. Therefore also check phs_evt and raw_phs. nxt_r.dd_phs_detected <= '1' WHEN r.phs_evt='0' AND r.dd_raw_phs_evt='0' AND r.dd_phs_err='0' AND r.dd_raw_phs_err='0' ELSE '0'; + -- Use g_delayed_lo<g_dd_phs_locked_w-1 to waist less within the dp_phs_timeout interval in lvdsh_dd_phs4_align.vhd, such that + -- within dp_phs_timeout it is just possible to achieve dd_phs_detected_ok. + -- However in simulation with tb_lvdsh_dd_phs4_align.vhd when g_dclk_drift = +2ps then best use g_delayed_lo=g_dd_phs_locked_w-1. + -- For g_dclk_drift = 0 or -2ps it is also in simulation fine to use the similar g_delayed_lo value as in HW. u_common_stable_delayed : ENTITY common_lib.common_stable_delayed GENERIC MAP ( g_active_level => '1', - g_delayed_w => g_dd_phs_locked_w + g_delayed_w => g_dd_phs_locked_w, + g_delayed_lo => g_dd_phs_locked_w-3 -- must be <= g_dd_phs_locked_w-1 ) PORT MAP ( rst => in_rst,