diff --git a/libraries/io/tr_nonbonded/hdllib.cfg b/libraries/io/tr_nonbonded/hdllib.cfg new file mode 100644 index 0000000000000000000000000000000000000000..ba0d2b460a9f83b6cee65ddb618023ae8bb1356b --- /dev/null +++ b/libraries/io/tr_nonbonded/hdllib.cfg @@ -0,0 +1,18 @@ +hdl_lib_name = tr_nonbonded +hdl_library_clause_name = tr_nonbonded_lib +hdl_lib_uses = common dp diag diagnostics tech_transceiver + +build_sim_dir = $HDL_BUILD_DIR +build_synth_dir = + +synth_files = + src/vhdl/tr_nonbonded.vhd + $UNB/Firmware/modules/tr_nonbonded/src/vhdl/src/vhdl/tr_nonbonded_reg.vhd + $UNB/Firmware/modules/tr_nonbonded/src/vhdl/src/vhdl/mms_tr_nonbonded.vhd + +test_bench_files = + $UNB/Firmware/modules/tr_nonbonded/src/vhdl/tb/vhdl/serializer.vhd + $UNB/Firmware/modules/tr_nonbonded/src/vhdl/tb/vhdl/deserializer.vhd + $UNB/Firmware/modules/tr_nonbonded/src/vhdl/tb/vhdl/tb_serdes.vhd + $UNB/Firmware/modules/tr_nonbonded/src/vhdl/tb/vhdl/sim_gx.vhd + $UNB/Firmware/modules/tr_nonbonded/src/vhdl/tb/vhdl/tb_tr_nonbonded.vhd diff --git a/libraries/io/tr_nonbonded/src/vhdl/tr_nonbonded.vhd b/libraries/io/tr_nonbonded/src/vhdl/tr_nonbonded.vhd new file mode 100644 index 0000000000000000000000000000000000000000..2be3b5fd677f2fae49ad9f567bef22d075bd3f14 --- /dev/null +++ b/libraries/io/tr_nonbonded/src/vhdl/tr_nonbonded.vhd @@ -0,0 +1,286 @@ +-------------------------------------------------------------------------------- +-- +-- 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, dp_lib, technology_lib, tech_transceiver_lib;; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.STD_LOGIC_UNSIGNED.ALL; +USE IEEE.NUMERIC_STD.ALL; +USE common_lib.common_pkg.ALL; +USE dp_lib.dp_stream_pkg.ALL; +USE technology_lib.technology_select_pkg.ALL; + +ENTITY tr_nonbonded IS + GENERIC( + g_technology : NATURAL := c_tech_select_default; + g_data_w : NATURAL := 32; + g_nof_gx : NATURAL := 12; + g_mbps : NATURAL := 6250; -- Supported: 6250, 5000, 3125, 2500 + ------------------------------------------------------------------------------------------------ + -- | g_sim | g_sim_level | Description + -- |-------------------------------------------------------------------------------------------- + -- | FALSE | X | Use ALTGX IP; Use long initialization delay for alignment on HW + -- |-------------------------------------------------------------------------------------------- + -- | TRUE | 0 | Use ALTGX IP; Use short initialization delay for alignment in sim + -- | TRUE | 1 | Use fast sim-only behavioural serdes model + -- |-------------------------------------------------------------------------------------------- + -- | X | >1 | Not supported + ------------------------------------------------------------------------------------------------ + g_sim : BOOLEAN := FALSE; + g_sim_level : NATURAL := 0; + g_tx : BOOLEAN := TRUE; + g_rx : BOOLEAN := TRUE; + g_fifos : BOOLEAN := FALSE; -- When TRUE use dp_clk and clock domain crossing FIFO for dp->tx and for rx->dp, when FALSE use rx_clk stream and tx_clk stream + g_tx_fifo_depth : NATURAL := c_bram_m9k_fifo_depth; -- = 256 * 32b = 1 M9K, because g_data_w=32b, functionally a depth of c_meta_fifo_depth=16 is sufficient to cross the clock domain + g_rx_fifo_depth : NATURAL := c_bram_m9k_fifo_depth -- = 256 * 32b = 1 M9K, because g_data_w=32b, functionally a depth of c_meta_fifo_depth=16 is sufficient to cross the clock domain + ); + PORT ( + tb_end : IN STD_LOGIC := '0'; -- in simulation stop internal clocks when tb_end='1' to support 'run -all' + + -- DP clock domain (only used when g_fifos=TRUE) + st_rst : IN STD_LOGIC; + st_clk : IN STD_LOGIC; + + -- PHY clocks + tr_clk : IN STD_LOGIC; + cal_rec_clk : IN STD_LOGIC; + + -- FIFO monitoring + gp_out : OUT STD_LOGIC_VECTOR(2*g_nof_gx-1 DOWNTO 0); + + -- Serial data I/O + tx_dataout : OUT STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0); + rx_datain : IN STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0); + + -- Parallel data I/O with fabric + -- . Use g_fifos=FALSE for data receive directly in rx_clk domain + rx_rst : OUT STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0); + rx_clk : OUT STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0); + rx_sosi_arr : OUT t_dp_sosi_arr(g_nof_gx-1 DOWNTO 0); + rx_siso_arr : IN t_dp_siso_arr(g_nof_gx-1 DOWNTO 0); + + -- . Use g_fifos=FALSE for data transmit directly in tx_clk domain + tx_rst : OUT STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0); + tx_clk : OUT STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0); + tx_sosi_arr : IN t_dp_sosi_arr(g_nof_gx-1 DOWNTO 0); + tx_siso_arr : OUT t_dp_siso_arr(g_nof_gx-1 DOWNTO 0); + + -- . Use g_fifos=TRUE for data transmit and receive in dp_clk domain + dp_rx_sosi_arr : OUT t_dp_sosi_arr(g_nof_gx-1 DOWNTO 0); + dp_rx_siso_arr : IN t_dp_siso_arr(g_nof_gx-1 DOWNTO 0); + dp_tx_sosi_arr : IN t_dp_sosi_arr(g_nof_gx-1 DOWNTO 0); + dp_tx_siso_arr : OUT t_dp_siso_arr(g_nof_gx-1 DOWNTO 0); + + -- Control and monitoring + tx_state : OUT STD_LOGIC_VECTOR(2*g_nof_gx-1 DOWNTO 0); + tx_align_en : IN STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0); + + rx_state : OUT STD_LOGIC_VECTOR(2*g_nof_gx-1 DOWNTO 0); + rx_align_en : IN STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0); + + rx_dataout : OUT t_slv_32_arr(g_nof_gx-1 DOWNTO 0) := (OTHERS=>(OTHERS=>'0')) + ); +END tr_nonbonded; + + +ARCHITECTURE str OF tr_nonbonded IS + + SIGNAL i_rx_clk : STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0); + SIGNAL i_rx_rst : STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0); + + SIGNAL i_tx_clk : STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0); + SIGNAL i_tx_rst : STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0); + + SIGNAL rx_fifo_sosi_arr : t_dp_sosi_arr(g_nof_gx-1 DOWNTO 0); + SIGNAL rx_fifo_siso_arr : t_dp_siso_arr(g_nof_gx-1 DOWNTO 0); + + SIGNAL tx_fifo_sosi_arr : t_dp_sosi_arr(g_nof_gx-1 DOWNTO 0); + SIGNAL tx_fifo_siso_arr : t_dp_siso_arr(g_nof_gx-1 DOWNTO 0); + + SIGNAL gp_out_tx : STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0) := (OTHERS=>'0'); + SIGNAL gp_out_rx : STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0) := (OTHERS=>'0'); + +BEGIN + + -- FIFO monitoring + gp_out <= gp_out_tx & gp_out_rx; + + gen_phy: IF g_sim = FALSE OR g_sim_level = 0 GENERATE + -- Altera's IP + u_phy_gx: ENTITY tech_transceiver_lib.tech_transceiver_gx + GENERIC MAP ( + g_technology => g_technology, + g_data_w => g_data_w, + g_nof_gx => g_nof_gx, + g_mbps => g_mbps, + g_tx => g_tx, + g_rx => g_rx, + g_sim => g_sim + ) + PORT MAP ( + tr_clk => tr_clk, + + cal_rec_clk => cal_rec_clk, + + rx_clk => i_rx_clk, + rx_rst => i_rx_rst, + + rx_sosi_arr => rx_fifo_sosi_arr, + rx_siso_arr => rx_fifo_siso_arr, + + tx_clk => i_tx_clk, + tx_rst => i_tx_rst, + + tx_sosi_arr => tx_fifo_sosi_arr, + tx_siso_arr => tx_fifo_siso_arr, + + tx_dataout => tx_dataout, + rx_datain => rx_datain, + + tx_state => tx_state, + tx_align_en => tx_align_en, + + rx_state => rx_state, + rx_align_en => rx_align_en + ); + END GENERATE; + + gen_sim: IF g_sim = TRUE AND g_sim_level = 1 GENERATE + -- Behavioural serdes model (fast) + u_sim_gx: ENTITY WORK.sim_gx + GENERIC MAP ( + g_data_w => g_data_w, + g_nof_gx => g_nof_gx, + g_mbps => g_mbps, + g_tx => g_tx, + g_rx => g_rx + ) + PORT MAP ( + tb_end => tb_end, + + tr_clk => tr_clk, + + rx_clk => i_rx_clk, + rx_rst => i_rx_rst, + + rx_sosi_arr => rx_fifo_sosi_arr, + rx_siso_arr => rx_fifo_siso_arr, + + tx_clk => i_tx_clk, + tx_rst => i_tx_rst, + + tx_sosi_arr => tx_fifo_sosi_arr, + tx_siso_arr => tx_fifo_siso_arr, + + tx_dataout => tx_dataout, + rx_datain => rx_datain + ); + END GENERATE; + + -- === TX === TX === TX === TX === TX === TX === TX === TX === TX === TX === TX === TX === TX === TX === TX === TX + gen_tx : IF g_tx = TRUE GENERATE + + tx_rst <= i_tx_rst; + tx_clk <= i_tx_clk; + + gen_i : FOR i in 0 to g_nof_gx-1 GENERATE + + no_tx_fifo : IF g_fifos = FALSE GENERATE + tx_fifo_sosi_arr(i) <= tx_sosi_arr(i); -- for tx_fifo_sosi_arr it is needed to select between tx_sosi_arr and dp_tx_sosi_arr + tx_siso_arr(i) <= tx_fifo_siso_arr(i); -- could default connect tx_siso_arr, but for clarity only connect tx_siso_arr when g_fifos = FALSE, else leave it 'X' + END GENERATE; + + gen_tx_fifo : IF g_fifos = TRUE GENERATE + u_tx_fifo : ENTITY dp_lib.dp_fifo_dc + GENERIC MAP ( + g_data_w => g_data_w, + g_use_ctrl => FALSE, + g_fifo_size => g_tx_fifo_depth, + g_fifo_rl => 1 + ) + PORT MAP ( + wr_rst => st_rst, + wr_clk => st_clk, + rd_rst => i_tx_rst(i), + rd_clk => i_tx_clk(i), + -- ST sink + snk_out => dp_tx_siso_arr(i), + snk_in => dp_tx_sosi_arr(i), + -- Monitor FIFO filling + wr_ful => gp_out_tx(i), + wr_usedw => OPEN, + rd_usedw => OPEN, + rd_emp => OPEN, + -- ST source + src_in => tx_fifo_siso_arr(i), + src_out => tx_fifo_sosi_arr(i) + ); + END GENERATE; -- gen_tx_fifo + END GENERATE; -- gen_i + END GENERATE; -- gen_tx + + + -- === RX === RX === RX === RX === RX === RX === RX === RX === RX === RX === RX === RX === RX === RX === RX === RX + gen_rx : IF g_rx = TRUE GENERATE + + rx_rst <= i_rx_rst; + rx_clk <= i_rx_clk; + + gen_i : FOR i in 0 to g_nof_gx-1 GENERATE + + rx_dataout(i)(g_data_w-1 DOWNTO 0) <= rx_fifo_sosi_arr(i).data(g_data_w-1 DOWNTO 0); + + no_rx_fifo : IF g_fifos = FALSE GENERATE + rx_sosi_arr(i) <= rx_fifo_sosi_arr(i); -- could default connect rx_sosi_arr, but for clarity only connect rx_sosi_arr when g_fifos = FALSE, else leave it 'X' + rx_fifo_siso_arr(i) <= rx_siso_arr(i); -- for rx_fifo_siso_arr it is needed to select between rx_siso_arr and dp_rx_siso_arr + END GENERATE; + + gen_rx_fifo : IF g_fifos = TRUE GENERATE + u_rx_fifo : ENTITY dp_lib.dp_fifo_dc + GENERIC MAP ( + g_data_w => g_data_w, + g_use_ctrl => FALSE, + g_fifo_size => g_rx_fifo_depth, + g_fifo_rl => 1 + ) + PORT MAP ( + wr_rst => i_rx_rst(i), + wr_clk => i_rx_clk(i), + rd_rst => st_rst, + rd_clk => st_clk, + -- ST sink + snk_out => rx_fifo_siso_arr(i), + snk_in => rx_fifo_sosi_arr(i), + -- Monitor FIFO filling + wr_ful => gp_out_rx(i), + wr_usedw => OPEN, + rd_usedw => OPEN, + rd_emp => OPEN, + -- ST source + src_in => dp_rx_siso_arr(i), + src_out => dp_rx_sosi_arr(i) + ); + END GENERATE; -- gen_rx_fifo + END GENERATE; -- gen_i + END GENERATE; -- gen_rx + +END str; +