Select Git revision
tech_transceiver_tx_align.vhd

Eric Kooistra authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
tech_transceiver_tx_align.vhd 4.15 KiB
--------------------------------------------------------------------------------
--
-- Copyright (C) 2012
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
--------------------------------------------------------------------------------
LIBRARY IEEE, common_lib;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
USE common_lib.common_pkg.ALL;
ENTITY tech_transceiver_tx_align IS
GENERIC(
g_sim : BOOLEAN;
g_data_w : NATURAL;
g_mbps : NATURAL
);
PORT(
tx_clk : IN STD_LOGIC;
tx_rst : IN STD_LOGIC;
tx_align_en_in : IN STD_LOGIC;
tx_align_en_out : OUT STD_LOGIC;
tx_state : OUT STD_LOGIC_VECTOR(1 DOWNTO 0)
);
END tech_transceiver_tx_align;
ARCHITECTURE rtl OF tech_transceiver_tx_align IS
CONSTANT c_tx_clk_freq : NATURAL := (g_mbps / g_data_w) / 10 * 8 *1000000;
CONSTANT c_timeout_1s : NATURAL := c_tx_clk_freq;
CONSTANT c_timeout_sim : NATURAL := 1000;
CONSTANT c_timeout : NATURAL := sel_a_b(g_sim, c_timeout_sim, 2*c_timeout_1s);
CONSTANT c_timeout_w : NATURAL := ceil_log2(c_timeout);
TYPE t_state_enum IS (s_init, s_init_send_pattern, s_send_user_data, s_force_pattern);
SIGNAL state : t_state_enum;
SIGNAL nxt_state : t_state_enum;
SIGNAL i_tx_align_en : STD_LOGIC;
SIGNAL nxt_tx_align_en : STD_LOGIC;
SIGNAL cycle_cnt : STD_LOGIC_VECTOR(c_timeout_w-1 DOWNTO 0);
SIGNAL nxt_cycle_cnt : STD_LOGIC_VECTOR(c_timeout_w-1 DOWNTO 0);
SIGNAL nxt_tx_state : STD_LOGIC_VECTOR(1 DOWNTO 0);
SIGNAL i_tx_state : STD_LOGIC_VECTOR(1 DOWNTO 0);
BEGIN
tx_state <= i_tx_state;
tx_align_en_out <= i_tx_align_en;
p_clk : PROCESS(tx_rst, tx_clk)
BEGIN
IF tx_rst='1' THEN
state <= s_init;
i_tx_align_en <= '1';
cycle_cnt <= (OTHERS=>'0');
i_tx_state <= (OTHERS=>'0');
ELSIF rising_edge(tx_clk) THEN
state <= nxt_state;
i_tx_align_en <= nxt_tx_align_en;
cycle_cnt <= nxt_cycle_cnt;
i_tx_state <= nxt_tx_state;
END IF;
END PROCESS;
p_state : PROCESS(state, i_tx_align_en, cycle_cnt, i_tx_state, tx_align_en_in)
BEGIN
nxt_state <= state;
nxt_tx_align_en <= i_tx_align_en;
nxt_cycle_cnt <= cycle_cnt;
nxt_tx_state <= i_tx_state;
CASE state IS
WHEN s_init =>
nxt_state <= s_init_send_pattern;
WHEN s_init_send_pattern =>
nxt_tx_align_en <= '1';
nxt_cycle_cnt <= INCR_UVEC(cycle_cnt, 1);
IF cycle_cnt = TO_UVEC(c_timeout, c_timeout_w) THEN
nxt_state <= s_send_user_data;
nxt_cycle_cnt <= (OTHERS=>'0');
END IF;
nxt_tx_state <= "01";
WHEN s_send_user_data =>
nxt_tx_align_en <= '0';
IF tx_align_en_in = '1' THEN
nxt_tx_align_en <= '1';
nxt_state <= s_force_pattern;
END IF;
nxt_tx_state <= "11";
WHEN s_force_pattern =>
nxt_tx_align_en <= '1';
IF tx_align_en_in = '0' THEN
nxt_tx_align_en <= '0';
nxt_state <= s_send_user_data;
END IF;
nxt_tx_state <= "10";
WHEN OTHERS =>
nxt_state <= s_init_send_pattern;
END CASE;
END PROCESS;
END rtl;