Skip to content
Snippets Groups Projects
Select Git revision
  • 6d479748c1b084242f19d2a1e625dd595e8ff565
  • master default protected
  • L2SDP-LIFT
  • L2SDP-1113
  • HPR-158
5 results

tech_transceiver_tx_align.vhd

Blame
  • 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;