OpenCores
URL https://opencores.org/ocsvn/ccsds_rxtxsoc/ccsds_rxtxsoc/trunk

Subversion Repositories ccsds_rxtxsoc

[/] [ccsds_rxtxsoc/] [trunk/] [ccsds_tx_manager.vhd] - Rev 2

Compare with Previous | Blame | View Log

-------------------------------
---- Project: EurySPACE CCSDS RX/TX with wishbone interface
---- Design Name: ccsds_tx_manager
---- Version: 1.0.0
---- Description:
---- In charge of internal clocks generation + forwarding to reduce power draw + select TX input data
-------------------------------
---- Author(s):
---- Guillaume REMBERT
-------------------------------
---- Licence:
---- MIT
-------------------------------
---- Changes list:
---- 2016/10/16: initial release
---- 2016/10/31: add serdes sub-component
---- 2016/11/05: add clock generator sub-component
-------------------------------
 
-- libraries used
library ieee;
use ieee.std_logic_1164.all;
 
--=============================================================================
-- Entity declaration for ccsds_tx / unitary tx manager inputs and outputs
--=============================================================================
entity ccsds_tx_manager is
    generic(
      constant CCSDS_TX_MANAGER_BITS_PER_SYMBOL: integer;
      constant CCSDS_TX_MANAGER_MODULATION_TYPE: integer;
      constant CCSDS_TX_MANAGER_DATALINK_OVERHEAD_RATIO: integer := 2;
      constant CCSDS_TX_MANAGER_PARALLELISM_MAX_RATIO: integer := 16;
      constant CCSDS_TX_MANAGER_OVERSAMPLING_RATIO: integer;
      constant CCSDS_TX_MANAGER_DATA_BUS_SIZE : integer
    );
    port(
      -- inputs
      clk_i: in std_logic;
      dat_par_i: in std_logic_vector(CCSDS_TX_MANAGER_DATA_BUS_SIZE-1 downto 0);
      dat_ser_i: in std_logic;
      dat_val_i: in std_logic;
      ena_i: in std_logic;
      in_sel_i: in std_logic; -- 0 = parallel data / 1 = external serial data
      rst_i: in std_logic;
      -- outputs
      clk_bit_o: out std_logic;
      clk_dat_o: out std_logic;
      clk_sam_o: out std_logic;
      clk_sym_o: out std_logic;
      dat_o: out std_logic_vector(CCSDS_TX_MANAGER_DATA_BUS_SIZE-1 downto 0);
      dat_val_o: out std_logic;
      ena_o: out std_logic
    );
end ccsds_tx_manager;
 
--=============================================================================
-- architecture declaration / internal connections
--=============================================================================
architecture structure of ccsds_tx_manager is
  component ccsds_rxtx_serdes is
    generic (
      constant CCSDS_RXTX_SERDES_DEPTH : integer
    );
    port(
      clk_i: in std_logic;
      dat_par_i: in std_logic_vector(CCSDS_RXTX_SERDES_DEPTH-1 downto 0);
      dat_par_val_i: in std_logic;
      dat_ser_i: in std_logic;
      dat_ser_val_i: in std_logic;
      rst_i: in std_logic;
      bus_o: out std_logic;
      dat_par_o: out std_logic_vector(CCSDS_RXTX_SERDES_DEPTH-1 downto 0);
      dat_par_val_o: out std_logic;
      dat_ser_o: out std_logic;
      dat_ser_val_o: out std_logic
    );
  end component;
  component ccsds_rxtx_clock_divider is
    generic(
      CCSDS_RXTX_CLOCK_DIVIDER: integer
    );
    port(
      clk_i: in std_logic;
      rst_i: in std_logic;
      clk_o: out std_logic
    );
  end component;
 
-- internal constants
  -- for simulation only / cannot be used when synthesizing
  constant CCSDS_TX_MANAGER_DEBUG: std_logic := '0';
--------------------------------
-- Clocks ratios computations --
--------------------------------
-- clk_dat
---- clk_bit = clk_dat / parallelism * data_link_overhead_ratio
------ clk_sym = clk_bit * data_bus_size / (2 * bits_per_symbol)
-------- clk_sam = clk_sym * oversampling_ratio
  constant CCSDS_TX_MANAGER_SAMPLES_TO_SYMBOLS_RATIO: integer := CCSDS_TX_MANAGER_OVERSAMPLING_RATIO;
  constant CCSDS_TX_MANAGER_SAMPLES_TO_BITS_RATIO: integer := CCSDS_TX_MANAGER_MODULATION_TYPE*CCSDS_TX_MANAGER_SAMPLES_TO_SYMBOLS_RATIO*CCSDS_TX_MANAGER_DATA_BUS_SIZE/(CCSDS_TX_MANAGER_BITS_PER_SYMBOL*2);
  constant CCSDS_TX_MANAGER_SAMPLES_TO_DATA_RATIO: integer := CCSDS_TX_MANAGER_SAMPLES_TO_BITS_RATIO*CCSDS_TX_MANAGER_DATALINK_OVERHEAD_RATIO/CCSDS_TX_MANAGER_PARALLELISM_MAX_RATIO;
 
-- interconnection signals
  signal wire_serdes_dat_par_o: std_logic_vector(CCSDS_TX_MANAGER_DATA_BUS_SIZE-1 downto 0);
  signal wire_serdes_dat_par_val_o: std_logic;
  signal wire_serdes_dat_ser_val_i: std_logic;
  signal wire_clk_dat: std_logic;
  signal wire_rst_clk: std_logic;
 
  begin
-- presynthesis checks
	  CHKMANAGERP0: if (CCSDS_TX_MANAGER_DEBUG = '1') generate
		  process
		  begin
			  report "INFO: TX CLOCK FREQUENCY HAS TO BE " & integer'image(CCSDS_TX_MANAGER_SAMPLES_TO_DATA_RATIO) & " x WB DATA CLOCK" severity note;
			  wait;
		  end process;
	  end generate CHKMANAGERP0;
-- components instanciation and mapping
    clock_divider_bits_001: ccsds_rxtx_clock_divider
      generic map(
        CCSDS_RXTX_CLOCK_DIVIDER => CCSDS_TX_MANAGER_SAMPLES_TO_BITS_RATIO
      )
      port map(
        clk_i => clk_i,
        rst_i => wire_rst_clk,
        clk_o => clk_bit_o
      );
    clock_divider_dat_001: ccsds_rxtx_clock_divider
      generic map(
        CCSDS_RXTX_CLOCK_DIVIDER => CCSDS_TX_MANAGER_SAMPLES_TO_DATA_RATIO
      )
      port map(
        clk_i => clk_i,
        rst_i => wire_rst_clk,
        clk_o => wire_clk_dat
      );
    clock_divider_sam_001: ccsds_rxtx_clock_divider
      generic map(
        CCSDS_RXTX_CLOCK_DIVIDER => 1
      )
      port map(
        clk_i => clk_i,
        rst_i => wire_rst_clk,
        clk_o => clk_sam_o
      );
    clock_divider_sym_001: ccsds_rxtx_clock_divider
      generic map(
        CCSDS_RXTX_CLOCK_DIVIDER => CCSDS_TX_MANAGER_SAMPLES_TO_SYMBOLS_RATIO
      )
      port map(
        clk_i => clk_i,
        rst_i => wire_rst_clk,
        clk_o => clk_sym_o
      );
    serdes_001: ccsds_rxtx_serdes
      generic map(
        CCSDS_RXTX_SERDES_DEPTH => CCSDS_TX_MANAGER_DATA_BUS_SIZE
      )
      port map(
        clk_i => wire_clk_dat,
        dat_par_i => (others => '0'),
        dat_par_val_i => '0',
        dat_ser_i => dat_ser_i,
        dat_ser_val_i => wire_serdes_dat_ser_val_i,
        rst_i => rst_i,
        dat_par_o => wire_serdes_dat_par_o,
        dat_par_val_o => wire_serdes_dat_par_val_o
      );
 
    ena_o <= ena_i;
    wire_rst_clk <= not(ena_i);
    clk_dat_o <= wire_clk_dat;
    --=============================================================================
    -- Begin of selectp
    -- Input selection
    --=============================================================================
    -- read: rst_i, ena_i, in_sel_i, dat_val_i
    -- write: dat_o, dat_val_o, wire_serdes_dat_ser_val_i
    -- r/w: 
    SELECTP : process (wire_clk_dat, ena_i)
    -- variables instantiation
    begin
      -- on each clock rising edge
      if rising_edge(wire_clk_dat) and (ena_i = '1') then
        if (rst_i = '1') then
          dat_o <= (others => '0');
          dat_val_o <= '0';
          wire_serdes_dat_ser_val_i <= '0';
        else
          if (in_sel_i = '1') then
            wire_serdes_dat_ser_val_i <= '1';
            dat_o <= wire_serdes_dat_par_o;
            dat_val_o <= wire_serdes_dat_par_val_o;
          else
            wire_serdes_dat_ser_val_i <= '0';
            dat_val_o <= dat_val_i;
            dat_o <= dat_par_i;
          end if;
        end if;
      end if;
    end process;
end structure;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.