Skip to content
Snippets Groups Projects
Commit 2ef73a21 authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Added in_maintain_phs support to maintain stable phase once it is found.

parent f4ae45f6
No related branches found
No related tags found
No related merge requests found
...@@ -28,11 +28,21 @@ USE common_lib.common_pkg.ALL; ...@@ -28,11 +28,21 @@ USE common_lib.common_pkg.ALL;
-- Description: -- Description:
-- The 800 MHz in_dat samples have already been captured at the pin by -- The 800 MHz in_dat samples have already been captured at the pin by
-- a common_ddio_in component. -- 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 ENTITY lvdsh_dd_phs4_align IS
GENERIC ( GENERIC (
g_wb_factor : NATURAL := 4; -- fixed wideband factor 4 = c_rx_factor*c_dd_factor 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_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_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 g_in_dat_w : NATURAL := 8 -- nof PHY data bits
); );
...@@ -46,6 +56,7 @@ ENTITY lvdsh_dd_phs4_align IS ...@@ -46,6 +56,7 @@ ENTITY lvdsh_dd_phs4_align IS
in_clk : IN STD_LOGIC := '1'; 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_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_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 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 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; ...@@ -58,10 +69,13 @@ END lvdsh_dd_phs4_align;
ARCHITECTURE str OF lvdsh_dd_phs4_align IS 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_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_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_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_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_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 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 ...@@ -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 ref_f_vec : STD_LOGIC_VECTOR(g_nof_dp_phs_clk-1 DOWNTO 0);
SIGNAL sel_r : STD_LOGIC; SIGNAL sel_r : STD_LOGIC;
SIGNAL sel_f : 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_r : STD_LOGIC;
SIGNAL ref_f : STD_LOGIC; SIGNAL ref_f : STD_LOGIC;
SIGNAL sync_r : STD_LOGIC; SIGNAL sync_r : STD_LOGIC;
...@@ -138,7 +155,7 @@ BEGIN ...@@ -138,7 +155,7 @@ BEGIN
g_rising_edge => TRUE, g_rising_edge => TRUE,
g_phase_rst_level => '1', g_phase_rst_level => '1',
g_meta_delay_len => c_delay_len, 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 g_clk_factor => c_rx_factor
) )
PORT MAP ( PORT MAP (
...@@ -154,7 +171,7 @@ BEGIN ...@@ -154,7 +171,7 @@ BEGIN
g_rising_edge => FALSE, g_rising_edge => FALSE,
g_phase_rst_level => '1', g_phase_rst_level => '1',
g_meta_delay_len => c_delay_len, 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 g_clk_factor => c_rx_factor
) )
PORT MAP ( PORT MAP (
...@@ -179,7 +196,7 @@ BEGIN ...@@ -179,7 +196,7 @@ BEGIN
rst => in_rst, rst => in_rst,
clk => in_clk, clk => in_clk,
in_dat => sel_r, in_dat => sel_r,
out_dat => ref_r out_dat => ref_align_r
); );
u_pipeline_ref_f : ENTITY common_lib.common_pipeline_sl u_pipeline_ref_f : ENTITY common_lib.common_pipeline_sl
...@@ -191,7 +208,42 @@ BEGIN ...@@ -191,7 +208,42 @@ BEGIN
rst => in_rst, rst => in_rst,
clk => in_clk, clk => in_clk,
in_dat => sel_f, 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 ...@@ -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. -- . 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'; 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 u_common_stable_delayed : ENTITY common_lib.common_stable_delayed
GENERIC MAP ( GENERIC MAP (
g_active_level => '1', 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 ( PORT MAP (
rst => in_rst, rst => in_rst,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment