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

Added g_maintain_phs=TRUE to maintain stable phase once it is found. Added...

Added g_maintain_phs=TRUE to maintain stable phase once it is found. Added out_status(5) = wb_roundtrip_stable.
parent 2ef73a21
No related branches found
No related tags found
No related merge requests found
......@@ -24,9 +24,11 @@ USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
USE common_lib.common_pkg.ALL;
-- Author: Eric Kooistra
-- Purpose: Detect the wide band factor phase 0, 1, 2 or 3 of the 200 MHz
-- dp_clk using the rising and falling edge of the double data rate
-- 400 MHz in_clk clock.
-- 400 MHz in_clk clock. The aim is to detect same sample phase
-- after each restart of the ADC, without the need for calibration.
-- Description:
-- The edges of the in_clk occur at the 800 MHz sample rate of the ADC. The
-- in_clk is a double data rate (DDR) 400 MHz clock as indicated by
......@@ -46,12 +48,13 @@ USE common_lib.common_pkg.ALL;
-- g_wb_factor-1 samples.
-- The sample phase alignment within a g_wb_factor=4 sample word is done by
-- lvdsh_dd_phs4_align. After that the word phase is also aligned by
-- adjusting the latency between wb_sync and dp_sync which.
-- adjusting the roundtrip latency between wb_sync and dp_sync which are both
-- derived from the selected dp_phs_clk.
-- Both the sample phase alignment and the word phase alignment use the
-- dp_phs_clk as reference. For the sample phase alignment within a word the
-- dp_phs_clk could run at the same 200 MHz rate as the dp_clk. However to
-- support a word latency of about 16 dp_clk cycles the dp_phs_clk are
-- divided by 32 at the PLL and only their rising edge is used to do the
-- support a roundtrip word latency of about 16 dp_clk cycles the dp_phs_clk
-- are divided by 32 at the PLL and only their rising edge is used to do the
-- alignments.
-- The g_nof_dp_phs_clk>= 1 and maximum 6. When g_nof_dp_phs_clk=6 then
-- typically each dp_phs_clk is shifted by 11.25 or 22.5 degrees where 90
......@@ -59,7 +62,7 @@ USE common_lib.common_pkg.ALL;
-- period. By selecting one suitable out of a range of phase shifted
-- dp_phs_clk it is possible to find a proper dp_phs_clk reference for all
-- signal paths in the different nodes.
-- The whole sample phase realingment scheme relies on fixed clock
-- The whole sample phase realignment scheme relies on fixed clock
-- distribution delays on the boards and in the FPGA. Therefore a clock tree
-- network is used for the dp_phs_clk as well, even though the dp_phs_clk
-- does not clock any logic. The dp_phs_clk gets sampled by the dp_clk to
......@@ -91,6 +94,22 @@ USE common_lib.common_pkg.ALL;
-- an entire sample period and via MM control one phase is selected per
-- BN- ADU pair. The MM control is then needed to select always the same
-- phase in case not always the same phase is found automatically.
-- . With multiple Apertif subracks it appears that the word alignment found
-- for all ADC paths is not always the same for all ADC paths. This cannot
-- be avoided with this lvdsh_dd_phs4, therefore any residual sample phase
-- uncertainty needs to be accounted for by calibration. However for most
-- ADC dp_dat paths this lvdsh_dd_phs4 will ensure a proper word alignment
-- that makes it feasible to perform coherent beamforming.
-- . On Apertif subracks it appears that sometimes over hours an initial word
-- alignment will get adjusted and this then causes a brief disturbance in
-- the dp_dat values or it may even cause a sample shift that remains. Such
-- a sample shift would harm the remainder of the observation. By setting
-- in_maintain_phs='1' after word alignment it can be ensured that this word
-- alignment maintained as long as the ADC in_clk remains active (so in
-- practise for as long as the observation will last or the Apertif frontend
-- and subracks remain on). The maintain lock feature is enabled when
-- g_maintain_phs = TRUE.
--
ENTITY lvdsh_dd_phs4 IS
GENERIC (
......@@ -98,6 +117,7 @@ ENTITY lvdsh_dd_phs4 IS
g_wb_factor : NATURAL := 4; -- fixed wideband factor 4 = c_rx_factor*c_dd_factor
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_nof_dp_phs_clk : NATURAL := 2; -- nof dp_phs_clk that can be used to detect lock
g_maintain_phs : BOOLEAN := TRUE; -- when TRUE maintain the stable lock once it is found, else keep on checking whether the stable lock is still stable
g_wb_use_rising_edge : BOOLEAN := FALSE; -- when TRUE using rising edge of dp_clk domain to capture wb_sync as reference for dp_sync from in_clk domain, else use falling edge
g_in_dat_w : NATURAL := 8 -- nof PHY data bits
);
......@@ -148,34 +168,40 @@ ARCHITECTURE str OF lvdsh_dd_phs4 IS
CONSTANT c_word_req_lat : NATURAL := 4;
CONSTANT c_dp_phs_align_restart_w : NATURAL := 5;
CONSTANT c_in_dd_phs_locked_w : NATURAL := sel_a_b(g_sim, 12, 25); -- used to ensure that dd_phs_locked is only declared if dd_phs is detected ok for at least 2**(g_dd_phs_locked_w-1) in_clk cycles
CONSTANT c_dp_dd_phs_timeout_w : NATURAL := c_in_dd_phs_locked_w + 0; -- dd_phs locked timeout in dp_clk domain, use c_dd_factor longer or more than c_in_dd_phs_locked_w
CONSTANT c_wb_sync_offset : INTEGER := g_dp_phs_clk_period/2;
CONSTANT c_wb_sync_delta : INTEGER := 0; -- use c_wb_sync_offset for default FIFO fill level and c_wb_sync_delta < 0 or > 0 to decrease or increase it somewhat
CONSTANT c_wb_sync_latency : NATURAL := c_wb_sync_offset + c_wb_sync_delta; -- nof dp_clk cycles from getting wb_sync back via dp_sync
CONSTANT c_wb_sync_period : NATURAL := g_dp_phs_clk_period; -- nof dp_clk cycles for wb_sync period, must be > c_wb_sync_latency
CONSTANT c_in_dd_phs_locked_w : NATURAL := sel_a_b(g_sim, 12, 30); -- used to ensure that dd_phs_locked is only declared if dd_phs is detected ok for at least 2**(g_dd_phs_locked_w-1) in_clk cycles
CONSTANT c_dp_dd_phs_timeout_w : NATURAL := c_in_dd_phs_locked_w; -- dd_phs locked timeout in dp_clk domain, so c_dd_factor=2 longer than c_in_dd_phs_locked_w, because c_in_dd_phs_locked_w runs
-- in the in_clk domain. This is enough to find stable lock if it is possible to have stable lock at the selected dp_phs_clk.
CONSTANT c_wb_sync_period : NATURAL := g_dp_phs_clk_period; -- nof dp_clk cycles for wb_sync period, must be > c_wb_sync_roundtrip
CONSTANT c_wb_cnt_w : NATURAL := ceil_log2(c_wb_sync_period);
CONSTANT c_wb_fifo_latency : NATURAL := c_wb_sync_latency-9; -- estimated FIFO fill level based on simulation and measurement on hardware (6, 7 and 8 occur)
CONSTANT c_wb_fifo_fill_offset : INTEGER := 2; -- some offset to adjust the mean fifo fill level
CONSTANT c_wb_sync_in_latency : NATURAL := 12; -- estimated nof dp_clk cycles latency of wb_sync transfer in the in_clk domain based on simulation and measurement on hardware
CONSTANT c_wb_sync_roundtrip : NATURAL := c_wb_fifo_fill_offset+g_dp_phs_clk_period/2; -- achieve this nof dp_clk cycles from getting wb_sync back via dp_sync
CONSTANT c_wb_fifo_fill_level : NATURAL := c_wb_fifo_fill_offset+c_wb_sync_roundtrip-c_wb_sync_in_latency; -- expected FIFO fill level on read side (mean level +- 1 can occur),
CONSTANT c_wb_fifo_fill_margin : NATURAL := 2; -- some symmetrical FIFO filled margin >= 0, use 0 in theory, use 1 to allow some timing uncertainty in rdusedw of dual clock FIFO
CONSTANT c_wb_fifo_fill_margin_p : NATURAL := c_wb_fifo_fill_margin; -- some FIFO more filled margin >= 0, use 0 or 1 to allow 8 and 9
CONSTANT c_wb_fifo_fill_margin_n : NATURAL := c_wb_fifo_fill_margin; -- some FIFO less filled margin >= 0, use 1 or 2 to allow 7 and 6
CONSTANT c_wb_fifo_fill_max : NATURAL := c_wb_fifo_latency+c_wb_fifo_fill_margin_p; -- maximum FIFO fill level at any time
CONSTANT c_wb_fifo_fill_min : NATURAL := c_wb_fifo_latency-c_wb_fifo_fill_margin_n; -- minimum FIFO fill level during lock
CONSTANT c_wb_fifo_fill_margin_p : NATURAL := c_wb_fifo_fill_margin; -- some FIFO more filled margin >= 0, use 0 or 1 to allow 8 and 9
CONSTANT c_wb_fifo_fill_margin_n : NATURAL := c_wb_fifo_fill_margin; -- some FIFO less filled margin >= 0, use 1 or 2 to allow 7 and 6
CONSTANT c_wb_fifo_fill_max : NATURAL := c_wb_fifo_fill_level+c_wb_fifo_fill_margin_p; -- maximum FIFO fill level at any time
CONSTANT c_wb_fifo_fill_min : NATURAL := c_wb_fifo_fill_level-c_wb_fifo_fill_margin_n; -- minimum FIFO fill level during lock
-- view debug signals in Wave Window
SIGNAL dbg_c_dp_phs_align_en : BOOLEAN := c_dp_phs_align_en;
SIGNAL dbg_c_wb_sync_latency : NATURAL := c_wb_sync_latency;
SIGNAL dbg_c_wb_sync_period : NATURAL := c_wb_sync_period;
SIGNAL dbg_c_wb_fifo_fill_offset : INTEGER := c_wb_fifo_fill_offset;
SIGNAL dbg_c_wb_sync_in_latency : NATURAL := c_wb_sync_in_latency;
SIGNAL dbg_c_wb_sync_roundtrip : NATURAL := c_wb_sync_roundtrip;
SIGNAL dbg_c_wb_fifo_fill_max : NATURAL := c_wb_fifo_fill_max;
SIGNAL dbg_c_wb_fifo_latency : NATURAL := c_wb_fifo_latency;
SIGNAL dbg_c_wb_fifo_fill_level : NATURAL := c_wb_fifo_fill_level; -- must be > c_word_req_lat to ensure that fifo_rdusedw > 0
SIGNAL dbg_c_wb_fifo_fill_min : NATURAL := c_wb_fifo_fill_min;
SIGNAL dbg_status_0_out_word_locked : STD_LOGIC;
SIGNAL dbg_status_1_out_word_stable : STD_LOGIC;
SIGNAL dbg_status_4_dp_phs_locked : STD_LOGIC;
SIGNAL dbg_status_5_wb_roundtrip_stable : STD_LOGIC;
SIGNAL dbg_status_6_dp_in_clk_detected : STD_LOGIC;
SIGNAL dbg_status_7_dp_in_clk_stable : STD_LOGIC;
SIGNAL dbg_status_15_8_fifo_rdusedw : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL dbg_status_23_16_wb_cnt_latency : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL dbg_status_23_16_wb_cnt_roundtrip : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL dbg_status_27_24_dp_phs_clk_select : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL dbg_status_31_28_dp_raw_phs : STD_LOGIC_VECTOR(3 DOWNTO 0);
......@@ -202,6 +228,7 @@ ARCHITECTURE str OF lvdsh_dd_phs4 IS
SIGNAL in_fifo_wr_dat : STD_LOGIC_VECTOR(c_fifo_dat_w-1 DOWNTO 0);
SIGNAL in_fifo_wr_req : STD_LOGIC;
SIGNAL in_phs_align_en : STD_LOGIC;
SIGNAL in_maintain_phs : STD_LOGIC := '0';
SIGNAL r_in : t_in_reg;
SIGNAL nxt_r_in : t_in_reg;
......@@ -239,12 +266,13 @@ ARCHITECTURE str OF lvdsh_dd_phs4 IS
prev_dp_sync_cap : STD_LOGIC;
dp_sync : STD_LOGIC;
wb_cnt_clr : STD_LOGIC;
wb_cnt_latency : STD_LOGIC_VECTOR(c_wb_cnt_w-1 DOWNTO 0);
wb_cnt_latency_hold : STD_LOGIC_VECTOR(c_wb_cnt_w-1 DOWNTO 0);
wb_cnt_roundtrip : STD_LOGIC_VECTOR(c_wb_cnt_w-1 DOWNTO 0);
wb_cnt_roundtrip_hold: STD_LOGIC_VECTOR(c_wb_cnt_w-1 DOWNTO 0);
dp_word_req : STD_LOGIC;
dp_word_req_dly : STD_LOGIC_VECTOR(c_word_req_lat-1 DOWNTO 0);
dp_word_locked : STD_LOGIC;
dp_word_lock_failed : STD_LOGIC;
dp_maintain_phs : STD_LOGIC;
END RECORD;
SIGNAL r_dp : t_dp_reg;
......@@ -274,14 +302,22 @@ ARCHITECTURE str OF lvdsh_dd_phs4 IS
SIGNAL wb_phs_clk : STD_LOGIC;
SIGNAL wb_sync_cap : STD_LOGIC;
SIGNAL wb_cnt : STD_LOGIC_VECTOR(c_wb_cnt_w-1 DOWNTO 0);
SIGNAL wb_roundtrip_lock : STD_LOGIC;
SIGNAL wb_roundtrip_stable : STD_LOGIC;
BEGIN
------------------------------------------------------------------------------
-- Reset input section when lock is lost
------------------------------------------------------------------------------
-- Multiple triggers for dp_phs_align_restart
--
-- . The dp_phs_align_restart is an input to the dp_in_rst_req that drives in_rst for lvdsh_dd_phs4_align
-- . When out_word_stable='1' then dp_maintain_phs='1' if g_maintain_phs=TRUE. The dp_phs_timeout and dp_phs_lock_lost can then
-- no longer occur, because the lvdsh_dd_phs4_align then continues on the current phs using common_toggle_align.
-- The dp_word_lock_failed can still occur, but only if the course check on wb_cnt_roundtrip latency and fifo_rdusedw FIFO fill
-- level fails by more than a +-1 margin.
dp_phs_align_restart <= dp_phs_timeout OR dp_phs_lock_lost OR r_dp.dp_word_lock_failed;
-- Extend dp_phs_align_restart to filter out any subsequent restart triggers
......@@ -319,6 +355,9 @@ BEGIN
-- . the in_clk has stopped, or
-- . the dp_phs_clk_en_vec was changed via MM, or
-- . an internal dp_phs_align_restart request occured
-- When out_word_stable='1' then dp_maintain_phs='1' if g_maintain_phs=TRUE. The dp_in_clk_stopped and dp_phs_clk_en_vec_evt
-- can the then still cause a reset. When dp_maintain_phs='1' the dp_phs_align_restart will effectively not occur anymore,
-- because both dp_clk and in_clk are active and in lock and any jitter is ignored.
nxt_r_dp.dp_in_rst_req <= dp_in_clk_stopped OR dp_phs_clk_en_vec_evt OR dp_phs_align_restart_extend;
u_common_async_in_rst : ENTITY common_lib.common_async
......@@ -404,10 +443,11 @@ BEGIN
u_lvdsh_dd_phs4_align : ENTITY work.lvdsh_dd_phs4_align
GENERIC MAP (
g_wb_factor => g_wb_factor,
g_nof_dp_phs_clk => g_nof_dp_phs_clk,
g_dd_phs_locked_w => c_in_dd_phs_locked_w,
g_in_dat_w => g_in_dat_w
g_wb_factor => g_wb_factor,
g_nof_dp_phs_clk => g_nof_dp_phs_clk,
g_dp_phs_clk_period => g_dp_phs_clk_period,
g_dd_phs_locked_w => c_in_dd_phs_locked_w,
g_in_dat_w => g_in_dat_w
)
PORT MAP (
-- DP clock reference for word alignment
......@@ -419,6 +459,7 @@ BEGIN
in_clk => in_clk,
in_dat_hi => in_dat_hi,
in_dat_lo => in_dat_lo,
in_maintain_phs => in_maintain_phs,
raw_phs => raw_phs,
out_phs_locked => dd_phs_locked,
......@@ -437,7 +478,7 @@ BEGIN
-- Support raw data without realignment
------------------------------------------------------------------------------
u_common_async_1 : ENTITY common_lib.common_async
u_common_async_in_phs_align_en : ENTITY common_lib.common_async
GENERIC MAP (
g_delay_len => c_delay_len
)
......@@ -580,10 +621,10 @@ BEGIN
dp_phs_timeout <= dp_phs_timeout_cnt(dp_phs_timeout_cnt'HIGH); -- dp_phs_timeout pulse also restarts the timer
------------------------------------------------------------------------------
-- Determine DP word lock based on the wb_sync - dp_sync latency
-- Determine DP word lock based on the wb_sync - dp_sync roundtrip latency via in_clk domain
------------------------------------------------------------------------------
-- Measure and align the wb_sync to dp_sync latency
-- Measure and align the wb_sync to dp_sync roundtrip latency
u_common_counter_wb_cnt : ENTITY common_lib.common_counter
GENERIC MAP (
g_width => c_wb_cnt_w
......@@ -600,11 +641,14 @@ BEGIN
nxt_r_dp.dp_word_req_dly(c_word_req_lat-1 DOWNTO 0) <= r_dp.dp_word_req_dly(c_word_req_lat-2 DOWNTO 0) & r_dp.dp_word_req;
p_dp_word_lock : PROCESS (r_dp, wb_cnt, fifo_rd_emp, fifo_rdusedw)
-- Monitor wb_cnt of roundtrip latency
wb_roundtrip_lock <= '1' WHEN UNSIGNED(r_dp.wb_cnt_roundtrip)=c_wb_sync_roundtrip ELSE '0';
p_dp_word_lock : PROCESS (r_dp, wb_cnt, wb_roundtrip_lock, fifo_rd_emp, fifo_rdusedw)
BEGIN
nxt_r_dp.wb_cnt_clr <= '1';
nxt_r_dp.wb_cnt_latency <= (OTHERS=>'0');
nxt_r_dp.wb_cnt_latency_hold <= (OTHERS=>'0');
nxt_r_dp.wb_cnt_clr <= '1';
nxt_r_dp.wb_cnt_roundtrip <= (OTHERS=>'0');
nxt_r_dp.wb_cnt_roundtrip_hold <= (OTHERS=>'0');
nxt_r_dp.dp_word_req <= '1';
nxt_r_dp.dp_word_locked <= '0';
......@@ -615,16 +659,16 @@ BEGIN
-- Realignment enabled
--------------------------------------------------------------------------
IF r_dp.dp_phs_locked='1' THEN
-- Measure wb_sync - dp_sync latency
nxt_r_dp.wb_cnt_clr <= r_dp.wb_cnt_clr;
nxt_r_dp.wb_cnt_latency <= r_dp.wb_cnt_latency;
nxt_r_dp.wb_cnt_latency_hold <= r_dp.wb_cnt_latency_hold;
-- Measure wb_sync - dp_sync roundtrip latency
nxt_r_dp.wb_cnt_clr <= r_dp.wb_cnt_clr;
nxt_r_dp.wb_cnt_roundtrip <= r_dp.wb_cnt_roundtrip;
nxt_r_dp.wb_cnt_roundtrip_hold <= r_dp.wb_cnt_roundtrip_hold;
IF r_dp.wb_sync='1' THEN
nxt_r_dp.wb_cnt_clr <= '0';
ELSIF r_dp.dp_sync='1' THEN
nxt_r_dp.wb_cnt_clr <= '1';
nxt_r_dp.wb_cnt_latency <= wb_cnt;
nxt_r_dp.wb_cnt_latency_hold <= r_dp.wb_cnt_latency;
nxt_r_dp.wb_cnt_roundtrip <= wb_cnt;
nxt_r_dp.wb_cnt_roundtrip_hold <= r_dp.wb_cnt_roundtrip;
END IF;
-- Word lock control
......@@ -633,35 +677,36 @@ BEGIN
IF r_dp.dp_word_locked='0' THEN
-- Word lock acquisition
IF r_dp.dp_sync='1' THEN -- dp_sync implies also that the FIFO is not empty, so no need to check fifo_rd_emp to avoid false dp_phs_val via dp_word_req_dly
-- Adjust wb_sync - dp_sync latency to become c_wb_sync_latency
IF UNSIGNED(wb_cnt) < c_wb_sync_latency THEN
-- Adjust wb_sync - dp_sync roundtrip latency to become c_wb_sync_roundtrip
IF UNSIGNED(wb_cnt) < c_wb_sync_roundtrip THEN
nxt_r_dp.dp_word_req <= '0'; -- too early dp_sync so slip 1 word
ELSIF UNSIGNED(wb_cnt) = c_wb_sync_latency THEN
ELSIF UNSIGNED(wb_cnt) = c_wb_sync_roundtrip THEN
nxt_r_dp.dp_word_locked <= '1'; -- declare word locked
-- Fine check FIFO fill level when lock is declared
IF UNSIGNED(fifo_rdusedw) < c_wb_fifo_fill_min THEN
nxt_r_dp.dp_word_lock_failed <= '1'; -- unexpected FIFO latency, so recover via in_rst
nxt_r_dp.dp_word_lock_failed <= '1'; -- unexpected change in FIFO fill level, so recover via in_rst
END IF;
END IF;
-- Fine check that latency is incrementing properly during word lock acquisition
IF UNSIGNED(r_dp.wb_cnt_latency_hold)>0 THEN
IF UNSIGNED(r_dp.wb_cnt_latency_hold)/=UNSIGNED(r_dp.wb_cnt_latency)-1 THEN
nxt_r_dp.dp_word_lock_failed <= '1'; -- wrong latency increment, so recover via in_rst
IF UNSIGNED(r_dp.wb_cnt_roundtrip_hold)>0 THEN
IF UNSIGNED(r_dp.wb_cnt_roundtrip_hold)/=UNSIGNED(r_dp.wb_cnt_roundtrip)-1 THEN
nxt_r_dp.dp_word_lock_failed <= '1'; -- wrong roundtrip latency increment, so recover via in_rst
END IF;
END IF;
END IF;
ELSE
-- *** Word locked, this is the correct end state for the ALIGNED data processing ***
-- Fine check latency during stable word lock
IF UNSIGNED(r_dp.wb_cnt_latency) /= c_wb_sync_latency THEN
-- Fine check roundtrip latency during stable word lock
IF wb_roundtrip_lock='0' AND r_dp.dp_maintain_phs = '0' THEN
-- After achieving dp_word_locked, but while dp_maintain_phs is still '0' the wb_cnt_roundtrip must exactly match c_wb_sync_roundtrip.
nxt_r_dp.dp_word_lock_failed <= '1'; -- word lock lost, so recover via in_rst
END IF;
-- Fine check FIFO fill level during stable word lock
IF UNSIGNED(fifo_rdusedw) < c_wb_fifo_fill_min THEN
nxt_r_dp.dp_word_lock_failed <= '1'; -- unexpected FIFO latency, so recover via in_rst
nxt_r_dp.dp_word_lock_failed <= '1'; -- unexpected change in FIFO fill level, so recover via in_rst
END IF;
END IF;
END IF;
......@@ -676,7 +721,7 @@ BEGIN
IF r_dp.dp_word_locked='0' THEN
-- Word lock acquisition
IF fifo_rd_emp='0' THEN -- no dp_sync in raw mode, so need to use fifo_rd_emp to check that FIFO is not empty to avoid false dp_phs_val due to dp_word_req_dly
IF UNSIGNED(fifo_rdusedw) <= c_wb_fifo_latency-c_word_req_lat THEN
IF UNSIGNED(fifo_rdusedw) <= c_wb_fifo_fill_level-c_word_req_lat THEN
nxt_r_dp.dp_word_req <= '0'; -- too few words in FIFO so slip 1 word
ELSIF UNSIGNED(fifo_rdusedw) >= c_wb_fifo_fill_min THEN
nxt_r_dp.dp_word_locked <= '1'; -- declare word locked
......@@ -687,19 +732,19 @@ BEGIN
-- Fine check FIFO fill level during stable word lock
IF UNSIGNED(fifo_rdusedw) < c_wb_fifo_fill_min THEN
nxt_r_dp.dp_word_lock_failed <= '1'; -- unexpected FIFO latency, so recover via in_rst
nxt_r_dp.dp_word_lock_failed <= '1'; -- unexpected change in FIFO fill level, so recover via in_rst
END IF;
END IF;
END IF;
END IF;
-- Course check latency and FIFO fill level at any time
IF UNSIGNED(wb_cnt) > c_wb_sync_latency+1 THEN
-- Course check roundtrip latency and FIFO fill level at any time
IF UNSIGNED(wb_cnt) > c_wb_sync_roundtrip+1 THEN
nxt_r_dp.dp_word_lock_failed <= '1'; -- timeout dp_sync, so recover via in_rst
END IF;
IF UNSIGNED(fifo_rdusedw) > c_wb_fifo_fill_max THEN
nxt_r_dp.dp_word_lock_failed <= '1'; -- unexpected FIFO latency, so recover via in_rst
nxt_r_dp.dp_word_lock_failed <= '1'; -- unexpected change in FIFO fill level, so recover via in_rst
END IF;
END PROCESS;
......@@ -712,9 +757,10 @@ BEGIN
-- Debug monitor status
i_out_status <= (OTHERS=>'0');
i_out_status( 4) <= r_dp.dp_phs_locked; -- 1 bit
i_out_status( 5) <= wb_roundtrip_stable; -- 1 bit
i_out_status( 7 DOWNTO 6) <= dp_in_clk_stable & dp_in_clk_detected; -- 2 bit
i_out_status(15 DOWNTO 8) <= fifo_rdusedw; -- c_fifo_size_w = 8
i_out_status(23 DOWNTO 16) <= RESIZE_UVEC(r_dp.wb_cnt_latency, 8); -- c_wb_cnt_w <= 8
i_out_status(23 DOWNTO 16) <= RESIZE_UVEC(r_dp.wb_cnt_roundtrip, 8); -- c_wb_cnt_w <= 8
i_out_status(27 DOWNTO 24) <= TO_UVEC(r_dp.dp_phs_clk_select, 4); -- g_nof_dp_phs_clk <= 6, fits in 4 bit
i_out_status(31 DOWNTO 28) <= r_dp.dp_raw_phs; -- g_wb_factor = 4
END PROCESS;
......@@ -725,15 +771,16 @@ BEGIN
dbg_status_0_out_word_locked <= r_dp.dp_word_locked;
dbg_status_1_out_word_stable <= i_out_word_stable;
dbg_status_4_dp_phs_locked <= i_out_status(4);
dbg_status_5_wb_roundtrip_stable <= i_out_status(5);
dbg_status_6_dp_in_clk_detected <= i_out_status(6);
dbg_status_7_dp_in_clk_stable <= i_out_status(7);
dbg_status_15_8_fifo_rdusedw <= i_out_status(15 DOWNTO 8);
dbg_status_23_16_wb_cnt_latency <= i_out_status(23 DOWNTO 16);
dbg_status_23_16_wb_cnt_roundtrip <= i_out_status(23 DOWNTO 16);
dbg_status_27_24_dp_phs_clk_select <= i_out_status(27 DOWNTO 24);
dbg_status_31_28_dp_raw_phs <= i_out_status(31 DOWNTO 28) WHEN r_dp.dp_val='1' AND r_dp.le_val='1'; -- latch to view only yhe raw_phs when in lock
END GENERATE;
u_common_stable_monitor : ENTITY common_lib.common_stable_monitor
u_common_stable_monitor_word_lock : ENTITY common_lib.common_stable_monitor
PORT MAP (
rst => dp_rst,
clk => dp_clk,
......@@ -742,10 +789,38 @@ BEGIN
r_stable => i_out_word_stable,
r_stable_ack => out_word_stable_ack
);
u_common_stable_monitor_wb_cnt_roundtrip : ENTITY common_lib.common_stable_monitor
PORT MAP (
rst => dp_rst,
clk => dp_clk,
-- MM
r_in => wb_roundtrip_lock,
r_stable => wb_roundtrip_stable,
r_stable_ack => out_word_stable_ack
);
out_word_locked <= r_dp.dp_word_locked;
out_word_stable <= i_out_word_stable;
------------------------------------------------------------------------------
-- Enable alignment or maintain current alignment once out_word_stable is achieved
------------------------------------------------------------------------------
nxt_r_dp.dp_maintain_phs <= i_out_word_stable WHEN g_maintain_phs=TRUE ELSE '0';
u_common_async_in_maintain_phs : ENTITY common_lib.common_async
GENERIC MAP (
g_rst_level => '1',
g_delay_len => c_delay_len
)
PORT MAP (
rst => '0',
clk => in_clk,
din => r_dp.dp_maintain_phs,
dout => in_maintain_phs
);
------------------------------------------------------------------------------
-- Registers
------------------------------------------------------------------------------
......@@ -766,6 +841,7 @@ BEGIN
BEGIN
IF dp_rst='1' THEN
r_dp.wb_sync_cap <= '0';
r_dp.wb_sync <= '0';
r_dp.dp_in_rst_req <= '1';
r_dp.fifo_rd_req <= '0';
r_dp.le_sync <= '0';
......@@ -782,11 +858,12 @@ BEGIN
r_dp.prev_dp_sync_cap <= '0';
r_dp.dp_sync <= '0';
r_dp.wb_cnt_clr <= '1';
r_dp.wb_cnt_latency <= (OTHERS=>'1');
r_dp.wb_cnt_roundtrip <= (OTHERS=>'1');
r_dp.dp_word_req <= '1';
r_dp.dp_word_req_dly <= (OTHERS=>'1');
r_dp.dp_word_locked <= '0';
r_dp.dp_word_lock_failed <= '0';
r_dp.dp_maintain_phs <= '0';
ELSIF rising_edge(dp_clk) THEN
r_dp <= nxt_r_dp;
END IF;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment