Skip to content
Snippets Groups Projects
Commit 190dcc54 authored by Reinier van der Walle's avatar Reinier van der Walle
Browse files

Added dp_offload_tx_v3

parent ab96e44a
No related branches found
No related tags found
2 merge requests!10Update branch to latest revision,!9Resolve L2SDP-23
......@@ -128,6 +128,7 @@ synth_files =
src/vhdl/dp_field_blk.vhd
src/vhdl/dp_concat_field_blk.vhd
src/vhdl/dp_offload_tx.vhd
src/vhdl/dp_offload_tx_v3.vhd
src/vhdl/dp_offload_rx_filter.vhd
src/vhdl/dp_offload_rx_filter_mm.vhd
src/vhdl/dp_offload_rx.vhd
......@@ -289,6 +290,7 @@ test_bench_files =
tb/vhdl/tb_tb_dp_xonoff.vhd
tb/vhdl/tb_tb_tb_dp_backpressure.vhd
tb/vhdl/tb_dp_offload_tx_v3.vhd
tb/vhdl/tb_dp_offload_rx_filter.vhd
regression_test_vhdl =
......
-------------------------------------------------------------------------------
--
-- Copyright (C) 2017
-- 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:
-- . Concatenate a user-defined header to a DP frame e.g. to create an Ethernet frame
-- Description:
-- . The header contents can be controlled dynamically by data path or MM control (selected by g_hdr_field_sel)
-- . The header and data can be concatened at symbol level. The g_symbol_w defines the
-- resolution of the empty field. The g_data_w must be an integer multiple of the
-- g_symbol_w. If the empty field is not used or if the empty field is always 0 then
-- set g_symbol_w = g_data_w.
-- . For example to concat header and data for an Ethernet frame use:
-- - g_data_w = 32 (1GbE) or 64 (10GbE)
-- - g_symbol_w = c_byte_w = 8 if either the header or the data can have an
-- non-zero empty field, so when they are not a multiple of 4 bytes
-- (= 32b) or 8 bytes (= 64b).
-- g_symbol_w = g_data_w if the empty field is always 0, so the number of bits in
-- the header and data are an integer number of g_data_w.
LIBRARY IEEE, common_lib, technology_lib, mm_lib;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE work.dp_stream_pkg.ALL;
USE common_lib.common_field_pkg.ALL;
USE technology_lib.technology_select_pkg.ALL;
ENTITY dp_offload_tx_v3 IS
GENERIC (
g_nof_streams : NATURAL;
g_data_w : NATURAL;
g_symbol_w : NATURAL;
g_hdr_field_arr : t_common_field_arr; -- User defined header fields
g_hdr_field_sel : STD_LOGIC_VECTOR; -- For each header field, select the source: 0=data path, 1=MM controlled
g_pipeline_ready : BOOLEAN := FALSE
);
PORT (
mm_rst : IN STD_LOGIC;
mm_clk : IN STD_LOGIC;
dp_rst : IN STD_LOGIC;
dp_clk : IN STD_LOGIC;
reg_hdr_dat_mosi : IN t_mem_mosi := c_mem_mosi_rst;
reg_hdr_dat_miso : OUT t_mem_miso;
snk_in_arr : IN t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
snk_out_arr : OUT t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);
src_out_arr : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
src_in_arr : IN t_dp_siso_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>c_dp_siso_rdy);
hdr_fields_in_arr : IN t_slv_1024_arr(g_nof_streams-1 DOWNTO 0); -- hdr_fields_in_arr(i) is considered valid @ snk_in_arr(i).sop
hdr_fields_out_arr : OUT t_slv_1024_arr(g_nof_streams-1 DOWNTO 0)
);
END dp_offload_tx_v3;
ARCHITECTURE str OF dp_offload_tx_v3 IS
CONSTANT c_dp_field_blk_snk_data_w : NATURAL := field_slv_out_len(field_arr_set_mode(g_hdr_field_arr , "RW"));
CONSTANT c_dp_field_blk_src_data_w : NATURAL := g_data_w;
SIGNAL dbg_c_dp_field_blk_snk_data_w : NATURAL := c_dp_field_blk_snk_data_w;
SIGNAL dbg_c_dp_field_blk_src_data_w : NATURAL := c_dp_field_blk_src_data_w;
SIGNAL dp_field_blk_snk_in_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL dp_field_blk_snk_out_arr : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL dp_field_blk_src_out_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL dp_field_blk_src_in_arr : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL dp_concat_snk_in_2arr : t_dp_sosi_2arr_2(g_nof_streams-1 DOWNTO 0);
SIGNAL dp_concat_snk_out_2arr : t_dp_siso_2arr_2(g_nof_streams-1 DOWNTO 0);
SIGNAL reg_hdr_dat_mosi_arr : t_mem_mosi_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL reg_hdr_dat_miso_arr : t_mem_miso_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL mm_fields_slv_out_arr : t_slv_1024_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL field_override_arr : STD_LOGIC_VECTOR(g_hdr_field_arr'RANGE) := g_hdr_field_sel; --1 override bit per field
BEGIN
ASSERT c_dp_field_blk_snk_data_w <= c_dp_stream_data_w REPORT "Number of header bits must fit in t_dp_sosi data field." SEVERITY FAILURE;
---------------------------------------------------------------------------------------
-- Create header block & concatenate header to offload stream.
---------------------------------------------------------------------------------------
p_wire_valid : PROCESS(snk_in_arr, hdr_fields_in_arr)
BEGIN
FOR i IN 0 TO g_nof_streams-1 LOOP
-- default pass on the other snk_in_arr fields as well, especially the sync, bsn and channel can
-- be useful to preserve for the packetized output, even though only the sosi.data of the
-- packetized output will get transmitted.
dp_field_blk_snk_in_arr(i) <= snk_in_arr(i);
-- Prepare packet header as a data block with only one data word, so valid = sop = eop. If
-- c_dp_field_blk_snk_data_w > c_dp_field_blk_src_data_w then dp_repack_data in dp_field_blk will
-- repack this data word into a multi word header block, else dp_field_blk will pass on the
-- dp_field_blk_snk_in_arr as a single word header block.
dp_field_blk_snk_in_arr(i).data <= RESIZE_DP_DATA(hdr_fields_in_arr(i)(field_slv_len(g_hdr_field_arr)-1 DOWNTO 0));
dp_field_blk_snk_in_arr(i).valid <= snk_in_arr(i).sop;
dp_field_blk_snk_in_arr(i).sop <= snk_in_arr(i).sop; -- necessary for single word header block
dp_field_blk_snk_in_arr(i).eop <= snk_in_arr(i).sop; -- necessary for single word header block
END LOOP;
END PROCESS;
gen_dp_field_blk : FOR i IN 0 TO g_nof_streams-1 GENERATE
-- Both dp_concat inputs must be ready. One of the inputs toggles ready via dp_field_blk.
snk_out_arr(i).ready <= dp_field_blk_snk_out_arr(i).ready AND dp_concat_snk_out_2arr(i)(0).ready;
snk_out_arr(i).xon <= src_in_arr(i).xon;
-- Wire hdr_fields_out_arr
-- MM override bits determine source for each field
gen_field_wires: FOR j IN g_hdr_field_arr'RANGE GENERATE
hdr_fields_out_arr(i)(field_hi(g_hdr_field_arr, j) DOWNTO field_lo(g_hdr_field_arr, j)) <= mm_fields_slv_out_arr(i)(field_hi(g_hdr_field_arr, j) DOWNTO field_lo(g_hdr_field_arr, j))
WHEN field_override_arr(j) = '1' ELSE
hdr_fields_in_arr(i)(field_hi(g_hdr_field_arr, j) DOWNTO field_lo(g_hdr_field_arr, j));
END GENERATE;
---------------------------------------------------------------------------------------
-- mm_fields for MM access to each field
---------------------------------------------------------------------------------------
u_mm_fields_slv: ENTITY mm_lib.mm_fields
GENERIC MAP(
g_field_arr => field_arr_set_mode(g_hdr_field_arr , "RW")
)
PORT MAP (
mm_clk => mm_clk,
mm_rst => mm_rst,
mm_mosi => reg_hdr_dat_mosi_arr(i),
mm_miso => OPEN, -- Not used
slv_clk => dp_clk,
slv_rst => dp_rst,
slv_out => mm_fields_slv_out_arr(i)(field_slv_len(g_hdr_field_arr)-1 DOWNTO 0)
);
-- Create multi-cycle header block from single-cycle wide header SLV
u_dp_field_blk : ENTITY work.dp_field_blk
GENERIC MAP (
g_field_arr => field_arr_set_mode(g_hdr_field_arr , "RW"),
g_field_sel => g_hdr_field_sel,
g_snk_data_w => c_dp_field_blk_snk_data_w,
g_src_data_w => c_dp_field_blk_src_data_w,
g_in_symbol_w => g_symbol_w,
g_out_symbol_w => g_symbol_w,
g_pipeline_ready => g_pipeline_ready
)
PORT MAP (
dp_clk => dp_clk,
dp_rst => dp_rst,
mm_clk => mm_clk,
mm_rst => mm_rst,
snk_in => dp_field_blk_snk_in_arr(i),
snk_out => dp_field_blk_snk_out_arr(i),
src_out => dp_field_blk_src_out_arr(i),
src_in => dp_field_blk_src_in_arr(i),
reg_slv_mosi => reg_hdr_dat_mosi_arr(i),
reg_slv_miso => reg_hdr_dat_miso_arr(i)
);
dp_field_blk_src_in_arr(i) <= dp_concat_snk_out_2arr(i)(1);
END GENERATE;
-- Prepend the header block to the input block
gen_dp_concat : FOR i IN 0 TO g_nof_streams-1 GENERATE
dp_concat_snk_in_2arr(i)(0) <= snk_in_arr(i);
dp_concat_snk_in_2arr(i)(1) <= dp_field_blk_src_out_arr(i);
u_dp_concat : ENTITY work.dp_concat
GENERIC MAP (
g_data_w => g_data_w,
g_symbol_w => g_symbol_w
)
PORT MAP (
rst => dp_rst,
clk => dp_clk,
snk_out_arr => dp_concat_snk_out_2arr(i),
snk_in_arr => dp_concat_snk_in_2arr(i),
src_in => src_in_arr(i),
src_out => src_out_arr(i)
);
END GENERATE;
---------------------------------------------------------------------------------------
-- MM control & monitoring
---------------------------------------------------------------------------------------
u_common_mem_mux_hdr_dat : ENTITY common_lib.common_mem_mux
GENERIC MAP (
g_nof_mosi => g_nof_streams,
g_mult_addr_w => ceil_log2(field_nof_words(g_hdr_field_arr, c_word_w))
)
PORT MAP (
mosi => reg_hdr_dat_mosi,
miso => reg_hdr_dat_miso,
mosi_arr => reg_hdr_dat_mosi_arr,
miso_arr => reg_hdr_dat_miso_arr
);
END str;
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment