signal state_bits : std_logic_vector(2 downto 0);
type link_state_t is (STARTUP, WAITING, WORKING, RESYNC_WAIT);
signal link_state : link_state_t;
+ signal pattern_detected_q : std_logic;
signal pattern_counter : unsigned(11 downto 0);
signal pattern_detected : std_logic;
signal last_DATA_CTRL_IN : std_logic;
signal present_sig : std_logic;
+
+ signal rx_idle_pattern : std_logic;
+ signal rx_idle_pattern_q : std_logic;
+ signal rx_resync_pattern : std_logic;
+ signal rx_resync_pattern_q : std_logic;
+ signal pattern_valid : std_logic;
+ signal pattern_valid_q : std_logic;
+
begin
-------------------------------------------
-- Link Control
-------------------------------------------
- PROC_SIGNAL_DETECT_PREPARE : process(CLK)
+ PROC_SIGNAL_DETECT_PREPARE : process(DATA_CLK_IN)
begin
- if rising_edge(CLK) then
+ if rising_edge(DATA_CLK_IN) then
if RESET = '1' then
last_DATA_CTRL_IN <= '0';
pattern_detected <= '0';
+ pattern_valid <= '0';
elsif reg_DATA_VALID_IN = '0' then
last_DATA_CTRL_IN <= reg_DATA_CTRL_IN;
pattern_detected <= last_DATA_CTRL_IN xor reg_DATA_CTRL_IN;
+ pattern_valid <= pattern_detected and not reg_DATA_VALID_IN;
end if;
end if;
end process;
-
PROC_FSM : process(CLK)
begin
if rising_edge(CLK) then
resync_received <= '0';
not_connected <= '1';
make_reset <= '0';
+ rx_allow <= '0';
+ tx_allow <= '0';
else
case link_state is
when STARTUP =>
- med_error <= ERROR_NC;
- link_running <= '0';
- not_connected <= '1';
+ med_error <= ERROR_NC;
+ link_running <= '0';
+ not_connected <= '1';
resync_received <= '0';
- if pattern_detected = '1' then
+ rx_allow <= '0';
+ tx_allow <= '0';
+ if pattern_detected_q = '1' then
not_connected <= '0';
link_state <= WAITING;
pattern_counter <= x"040";
when WAITING =>
med_error <= ERROR_WAIT;
- if pattern_detected = '1' and reg_DATA_VALID_IN = '0' then
+ if pattern_valid_q = '1' then
pattern_counter <= pattern_counter + "1";
- elsif pattern_detected = '0' then
+ elsif pattern_detected_q = '0' then
pattern_counter <= pattern_counter - x"40";
end if;
if pattern_counter < x"040" then
link_state <= STARTUP;
+ elsif pattern_counter = x"DFF" then
+ rx_allow <= '1';
elsif pattern_counter = x"FFF" then
link_state <= WORKING;
+ tx_allow <= '1';
end if;
when WORKING =>
med_error <= ERROR_OK;
link_running <= '1';
- if reg_DATA_VALID_IN = '0' and reg_DATA_IN = x"FEFE" then
+ if rx_resync_pattern_q = '1' then
resync_received <= '1';
else
resync_received <= '0';
make_reset <= resync_received;
end if;
- if pattern_detected = '0' then
+ if pattern_detected_q = '0' then
link_running <= '0';
link_state <= STARTUP;
end if;
when RESYNC_WAIT =>
med_error <= ERROR_WAIT;
- if reg_DATA_VALID_IN = '0' and reg_DATA_IN = x"AAAA" then
+ if rx_idle_pattern_q = '1' then
link_state <= WAITING;
pattern_counter <= x"040";
- elsif pattern_detected = '0' then
+ elsif pattern_detected_q = '0' then
link_state <= STARTUP;
end if;
"011" when link_state = RESYNC_WAIT else
"100" when link_state = WORKING else "111";
+-------------------------------------------
+-- Transfer RX status to sys clock domain
+-------------------------------------------
+
+ rx_idle_pattern <= '1' when reg_DATA_IN = x"AAAA" and reg_DATA_VALID_IN = '0' else '0';
+ rx_resync_pattern <= '1' when reg_DATA_IN = x"FEFE" and reg_DATA_VALID_IN = '0' else '0';
+
+
+ THE_SYNC_TO_SYS : signal_sync
+ generic map(
+ DEPTH => 3,
+ WIDTH => 4
+ )
+ port map(
+ RESET => RESET,
+ D_IN(0) => pattern_detected,
+ D_IN(1) => rx_idle_pattern,
+ D_IN(2) => rx_resync_pattern,
+ D_IN(3) => pattern_valid,
+ CLK0 => DATA_CLK_IN,
+ CLK1 => CLK,
+ D_OUT(0) => pattern_detected_q,
+ D_OUT(1) => rx_idle_pattern_q,
+ D_OUT(2) => rx_resync_pattern_q,
+ D_OUT(3) => pattern_valid_q
+ );
+
+ THE_SYNC_TO_RX : signal_sync
+ generic map(
+ DEPTH => 3,
+ WIDTH => 1
+ )
+ port map(
+ RESET => RESET,
+ D_IN(0) => rx_allow,
+ CLK0 => CLK,
+ CLK1 => DATA_CLK_IN,
+ D_OUT(0) => rx_allow_qrx
+ );
+
+
+
-------------------------------------------
STAT_DEBUG(5) <= make_reset;
STAT_DEBUG(6) <= not_connected;
STAT_DEBUG(7) <= present_sig;
- STAT_DEBUG(15 downto 8) <= reg_DATA_IN(7 downto 0);
+ STAT_DEBUG(8) <= last_DATA_CTRL_IN;
+ STAT_DEBUG(9) <= buf_DATA_VALID_OUT;
+ STAT_DEBUG(10) <= DATA_CLK_IN;
+ STAT_DEBUG(11) <= resync_received;
+ STAT_DEBUG(15 downto 12) <= reg_DATA_IN(3 downto 0);
STAT_DEBUG(63 downto 16) <= (others => '0');