diff --git a/applications/aartfaac/libraries/rsp_terminal/hdllib.cfg b/applications/aartfaac/libraries/rsp_terminal/hdllib.cfg index b2d361aa418f35519d94b8c0b8ab318f5364cc81..2a2c836b2b4660f91bcb03fe3764d9cb34d8e69e 100644 --- a/applications/aartfaac/libraries/rsp_terminal/hdllib.cfg +++ b/applications/aartfaac/libraries/rsp_terminal/hdllib.cfg @@ -11,10 +11,12 @@ synth_files = src/vhdl/rsp_terminal_frame_gen.vhd $SVN/Aartfaac/trunk/Firmware/modules/rsp_terminal/src/vhdl/rsp_terminal_frame_dec.vhd $SVN/Aartfaac/trunk/Firmware/modules/rsp_terminal/src/vhdl/rsp_terminal_rx.vhd - $SVN/Aartfaac/trunk/Firmware/modules/rsp_terminal/src/vhdl/rsp_terminal_tx.vhd + src/vhdl/rsp_terminal_tx.vhd src/vhdl/io_rsp_terminal.vhd test_bench_files = $SVN/Aartfaac/trunk/Firmware/modules/rsp_terminal/tb/vhdl/tb_rsp_terminal.vhd $SVN/Aartfaac/trunk/Firmware/modules/rsp_terminal/tb/vhdl/tb_tb_rsp_terminal.vhd +modelsim_copy_files = + $SVN/Aartfaac/trunk/Firmware/modules/rsp_terminal/src/hex/ hex diff --git a/applications/aartfaac/libraries/rsp_terminal/src/vhdl/rsp_terminal_tx.vhd b/applications/aartfaac/libraries/rsp_terminal/src/vhdl/rsp_terminal_tx.vhd new file mode 100644 index 0000000000000000000000000000000000000000..086b4b4a3205912a2639bed331c558b45b79d817 --- /dev/null +++ b/applications/aartfaac/libraries/rsp_terminal/src/vhdl/rsp_terminal_tx.vhd @@ -0,0 +1,242 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2013 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.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/>. +-- +------------------------------------------------------------------------------- + + +-- Purpose: Transmit RSP data frames for one or more lanes via serdes PHY +-- Description: +-- . Data: Generate beamlet, crosslet and subband frames +-- . Flow: +-- +-- rsp_terminal_frame_gen dp_frame_scheduler +-- +-- SOSI +-- beamlet_src --0-\ +-- crosslet_src --1--> scheduler_in --> scheduler_tx --> src_out_arr +-- subband_src --2-/ +-- +-- Remark: +-- . The rsp_terminal_tx serves two purposes: +-- 1) it models the behaviour of the RSP tx +-- 2) it can also by synthesized and run on an UniBoard BN to serve as source +-- to validate BN-BN link on hardware. If the BN-BN link does not work +-- then the RSP - BN link is unlikely to work either, so trying the BN-BN +-- link forms a useful intermediate development step. + + +LIBRARY IEEE, common_lib, dp_lib, diag_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE common_lib.common_pkg.ALL; +USE dp_lib.dp_stream_pkg.ALL; +USE diag_lib.diag_pkg.ALL; +USE work.rsp_terminal_pkg.ALL; + +ENTITY rsp_terminal_tx IS + GENERIC ( + g_sim : BOOLEAN; + g_nof_lanes : NATURAL := c_rsp_terminal_nof_lanes; + g_bg_use_subband_dat_hex : BOOLEAN := FALSE -- when true use alternative (instead of counter data) subband HEX files + ); + PORT ( + mm_rst : IN STD_LOGIC; + mm_clk : IN STD_LOGIC; + dp_rst : IN STD_LOGIC; + dp_clk : IN STD_LOGIC; + gp_out : OUT STD_LOGIC_VECTOR(c_rsp_terminal_nof_frame_types*g_nof_lanes+g_nof_lanes*c_rsp_terminal_nof_frame_types-1 DOWNTO 0); -- General purpose outputs for FIFO full monitoring + + -- Output at frame interface level + src_out_arr : OUT t_dp_sosi_arr(g_nof_lanes-1 DOWNTO 0); + src_in_arr : IN t_dp_siso_arr(g_nof_lanes-1 DOWNTO 0) + ); +END rsp_terminal_tx; + + +ARCHITECTURE str OF rsp_terminal_tx IS + + CONSTANT c_scheduler_fifo_rl : NATURAL := 1; + + TYPE t_scheduler_in_data_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(c_rsp_terminal_nof_frame_types*c_rsp_terminal_lane_dat_w-1 DOWNTO 0); + TYPE t_scheduler_in_ctrl_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(c_rsp_terminal_nof_frame_types -1 DOWNTO 0); + + -- Generate three types of tx frames for all lanes + -- . beamlets + SIGNAL rsp_terminal_frame_gen_beamlet_src_o_arr : t_dp_sosi_arr(g_nof_lanes-1 DOWNTO 0); + SIGNAL rsp_terminal_frame_gen_beamlet_src_i_arr : t_dp_siso_arr(g_nof_lanes-1 DOWNTO 0); + + -- . crosslets + SIGNAL rsp_terminal_frame_gen_crosslet_src_o_arr : t_dp_sosi_arr(g_nof_lanes-1 DOWNTO 0); + SIGNAL rsp_terminal_frame_gen_crosslet_src_i_arr : t_dp_siso_arr(g_nof_lanes-1 DOWNTO 0); + + -- . subbands + SIGNAL rsp_terminal_frame_gen_subband_src_o_arr : t_dp_sosi_arr(g_nof_lanes-1 DOWNTO 0); + SIGNAL rsp_terminal_frame_gen_subband_src_i_arr : t_dp_siso_arr(g_nof_lanes-1 DOWNTO 0); + + -- Schedule (= multiplex) the three types of tx frames over a single lane + -- . scheduler inputs, three per lane + SIGNAL scheduler_in_data_arr : t_scheduler_in_data_arr(g_nof_lanes-1 DOWNTO 0) := (OTHERS=>(OTHERS=>'0')); + SIGNAL scheduler_in_val_arr : t_scheduler_in_ctrl_arr(g_nof_lanes-1 DOWNTO 0) := (OTHERS=>(OTHERS=>'0')); + SIGNAL scheduler_in_sop_arr : t_scheduler_in_ctrl_arr(g_nof_lanes-1 DOWNTO 0) := (OTHERS=>(OTHERS=>'0')); + SIGNAL scheduler_in_eop_arr : t_scheduler_in_ctrl_arr(g_nof_lanes-1 DOWNTO 0) := (OTHERS=>(OTHERS=>'0')); + + -- . scheduler output per lane + SIGNAL scheduler_tx_data : STD_LOGIC_VECTOR(g_nof_lanes*c_rsp_terminal_lane_dat_w-1 DOWNTO 0); + SIGNAL scheduler_tx_val : STD_LOGIC_VECTOR(g_nof_lanes -1 DOWNTO 0); + SIGNAL scheduler_tx_sop : STD_LOGIC_VECTOR(g_nof_lanes -1 DOWNTO 0); + SIGNAL scheduler_tx_eop : STD_LOGIC_VECTOR(g_nof_lanes -1 DOWNTO 0); + + -- FIFO monitoring + SIGNAL gp_out_beamlet_frames : STD_LOGIC_VECTOR(g_nof_lanes-1 DOWNTO 0); + SIGNAL gp_out_crosslet_frames : STD_LOGIC_VECTOR(g_nof_lanes-1 DOWNTO 0); + SIGNAL gp_out_subband_frames : STD_LOGIC_VECTOR(g_nof_lanes-1 DOWNTO 0); + SIGNAL gp_out_frame_scheduler : STD_LOGIC_VECTOR(g_nof_lanes*c_rsp_terminal_nof_frame_types-1 DOWNTO 0); + +BEGIN + + -- FIFO full monitoring + gp_out <= gp_out_beamlet_frames & gp_out_crosslet_frames & gp_out_subband_frames & gp_out_frame_scheduler; + + --------------------------------------------------------------------------------------- + -- Beamlet Frames + --------------------------------------------------------------------------------------- + u_rsp_terminal_frame_gen_beamlet : ENTITY work.rsp_terminal_frame_gen + GENERIC MAP( + g_nof_lanes => g_nof_lanes, + g_usr_dat_w => c_rsp_terminal_beamlet_dat_w, + g_usr_nof_words => c_rsp_terminal_beamlet_usr_nof_words, + g_lane_dat_w => c_rsp_terminal_lane_dat_w, + g_lane_nof_words => c_rsp_terminal_beamlet_lane_nof_words, + g_usr_block_size => c_rsp_terminal_beamlet_block_size, + g_sfd => c_rsp_terminal_beamlet_sfd, + g_bg_ctrl => sel_a_b(g_sim, c_rsp_terminal_beamlet_bg_ctrl_sim, c_rsp_terminal_beamlet_bg_ctrl), + g_bg_file_name_prefix=> sel_a_b(g_bg_use_subband_dat_hex, "../", "") & "../../../../../modules/rsp_terminal/src/hex/cnt_dat" + ) + PORT MAP ( + mm_rst => mm_rst, + mm_clk => mm_clk, + dp_rst => dp_rst, + dp_clk => dp_clk, + gp_out => gp_out_beamlet_frames, + + src_out_arr => rsp_terminal_frame_gen_beamlet_src_o_arr, + src_in_arr => rsp_terminal_frame_gen_beamlet_src_i_arr + ); + + --------------------------------------------------------------------------------------- + -- Crosslet Frames + --------------------------------------------------------------------------------------- + u_rsp_terminal_frame_gen_crosslet : ENTITY work.rsp_terminal_frame_gen + GENERIC MAP( + g_nof_lanes => g_nof_lanes, + g_usr_dat_w => c_rsp_terminal_crosslet_dat_w, + g_usr_nof_words => c_rsp_terminal_crosslet_usr_nof_words, + g_lane_dat_w => c_rsp_terminal_lane_dat_w, + g_lane_nof_words => c_rsp_terminal_crosslet_lane_nof_words, + g_usr_block_size => c_rsp_terminal_crosslet_block_size, + g_sfd => c_rsp_terminal_crosslet_sfd, + g_bg_ctrl => sel_a_b(g_sim, c_rsp_terminal_crosslet_bg_ctrl_sim, c_rsp_terminal_crosslet_bg_ctrl), + g_bg_file_name_prefix=> sel_a_b(g_bg_use_subband_dat_hex, "../", "") & "../../../../../modules/rsp_terminal/src/hex/cnt_dat" + ) + PORT MAP ( + mm_rst => mm_rst, + mm_clk => mm_clk, + dp_rst => dp_rst, + dp_clk => dp_clk, + gp_out => gp_out_crosslet_frames, + + src_out_arr => rsp_terminal_frame_gen_crosslet_src_o_arr, + src_in_arr => rsp_terminal_frame_gen_crosslet_src_i_arr + ); + + --------------------------------------------------------------------------------------- + -- Subband Frames + --------------------------------------------------------------------------------------- + u_rsp_terminal_frame_gen_subband : ENTITY work.rsp_terminal_frame_gen + GENERIC MAP( + g_nof_lanes => g_nof_lanes, + g_usr_dat_w => c_rsp_terminal_subband_dat_w, + g_usr_nof_words => c_rsp_terminal_subband_usr_nof_words, + g_lane_dat_w => c_rsp_terminal_lane_dat_w, + g_lane_nof_words => c_rsp_terminal_subband_lane_nof_words, + g_sfd => c_rsp_terminal_subband_sfd, + g_usr_block_size => c_rsp_terminal_subband_block_size, + g_bg_ctrl => sel_a_b(g_sim, c_rsp_terminal_subband_bg_ctrl_sim, c_rsp_terminal_subband_bg_ctrl), + g_bg_file_name_prefix=> sel_a_b(g_bg_use_subband_dat_hex, "../../../../../../designs/aartfaac_bn_sdo/src/hex/subband_dat", "../../../../../modules/rsp_terminal/src/hex/interleaved_cnt_dat"), + g_use_dp_packet_enc => TRUE + ) + PORT MAP ( + mm_rst => mm_rst, + mm_clk => mm_clk, + dp_rst => dp_rst, + dp_clk => dp_clk, + gp_out => gp_out_subband_frames, + + src_out_arr => rsp_terminal_frame_gen_subband_src_o_arr, + src_in_arr => rsp_terminal_frame_gen_subband_src_i_arr + ); + + + --------------------------------------------------------------------------------------- + -- Frame scheduler + --------------------------------------------------------------------------------------- + gen_nof_lanes : FOR I IN 0 TO g_nof_lanes-1 GENERATE + -- dp_frame_scheduler does not have/forward flow control, so bypass it + rsp_terminal_frame_gen_beamlet_src_i_arr(i).ready <= '1'; + rsp_terminal_frame_gen_beamlet_src_i_arr(i).xon <= src_in_arr(i).xon; + rsp_terminal_frame_gen_crosslet_src_i_arr(i).ready <= '1'; + rsp_terminal_frame_gen_crosslet_src_i_arr(i).xon <= src_in_arr(i).xon; + rsp_terminal_frame_gen_subband_src_i_arr(i).ready <= '1'; + rsp_terminal_frame_gen_subband_src_i_arr(i).xon <= src_in_arr(i).xon; + + -- Wire the scheduler input for c_rsp_terminal_nof_frame_types = 3, with beamlets at priority input 0 of range g_nof_input-1:0 + scheduler_in_data_arr(I) <= rsp_terminal_frame_gen_subband_src_o_arr(I).data(c_rsp_terminal_lane_dat_w-1 DOWNTO 0) & + rsp_terminal_frame_gen_crosslet_src_o_arr(I).data(c_rsp_terminal_lane_dat_w-1 DOWNTO 0) & + rsp_terminal_frame_gen_beamlet_src_o_arr(I).data(c_rsp_terminal_lane_dat_w-1 DOWNTO 0); + scheduler_in_val_arr(I) <= rsp_terminal_frame_gen_subband_src_o_arr(I).valid & rsp_terminal_frame_gen_crosslet_src_o_arr(I).valid & rsp_terminal_frame_gen_beamlet_src_o_arr(I).valid; + scheduler_in_sop_arr(I) <= rsp_terminal_frame_gen_subband_src_o_arr(I).sop & rsp_terminal_frame_gen_crosslet_src_o_arr(I).sop & rsp_terminal_frame_gen_beamlet_src_o_arr(I).sop; + scheduler_in_eop_arr(I) <= rsp_terminal_frame_gen_subband_src_o_arr(I).eop & rsp_terminal_frame_gen_crosslet_src_o_arr(I).eop & rsp_terminal_frame_gen_beamlet_src_o_arr(I).eop; + + u_dp_frame_scheduler : ENTITY dp_lib.dp_frame_scheduler + GENERIC MAP ( + g_dat_w => c_rsp_terminal_lane_dat_w, + g_nof_input => c_rsp_terminal_nof_frame_types, + g_fifo_rl => c_scheduler_fifo_rl, -- for all input use 0 for look ahead FIFO, 1 for normal FIFO + g_fifo_size => (c_rsp_terminal_subband_scheduler_size, c_rsp_terminal_crosslet_scheduler_size, c_rsp_terminal_beamlet_scheduler_size), -- must match g_nof_input-1:0 + g_fifo_fill => (c_rsp_terminal_subband_scheduler_fill, c_rsp_terminal_crosslet_scheduler_fill, c_rsp_terminal_beamlet_scheduler_fill) -- must match g_nof_input-1:0 + ) + PORT MAP ( + rst => dp_rst, + clk => dp_clk, + gp_out => gp_out_frame_scheduler((I+1)*c_rsp_terminal_nof_frame_types-1 DOWNTO I*c_rsp_terminal_nof_frame_types), + in_dat => scheduler_in_data_arr(I), + in_val => scheduler_in_val_arr(I), + in_sof => scheduler_in_sop_arr(I), + in_eof => scheduler_in_eop_arr(I), + out_dat => scheduler_tx_data((I+1)*c_rsp_terminal_lane_dat_w-1 DOWNTO I*c_rsp_terminal_lane_dat_w), + out_val => scheduler_tx_val(I), + out_sof => scheduler_tx_sop(I), + out_eof => scheduler_tx_eop(I) + ); + + src_out_arr(I).data(c_rsp_terminal_lane_dat_w-1 DOWNTO 0) <= scheduler_tx_data((I+1)*c_rsp_terminal_lane_dat_w-1 DOWNTO I*c_rsp_terminal_lane_dat_w); + src_out_arr(I).valid <= scheduler_tx_val(I); + END GENERATE; + +END str; +