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

Subversion Repositories dp_repack_data

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /dp_repack_data/trunk
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

/dp_repack_data.vhd
0,0 → 1,748
--------------------------------------------------------------------------------
--
-- Copyright (C) 2015
-- 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:
-- The dp_repack_data works both as packer and as unpacker.
--
-- Block diagram:
--
-- A) Functional
-- The drawing shows g_in_nof_words=4 and g_out_nof_words=2 as example:
--
-- dp_repack_in dp_repack_out
-- ___ ___
-- | | pack_sosi | |--> src_out
-- | 3 |--------------------->| 1 |
-- | | | |
-- | 2 | ^ | | ^
-- | | |valid | | |shift
-- | 1 | |flush | 0 | |
-- | | | | | |
-- | 0 | | |
-- snk_in -->|___| pack_siso |___|
-- snk_out.ready <-- <--------------------- <-- src_in.ready
-- snk_out.xon <------------------------------------- src_in.xon
--
--
-- B) Flow control
--
-- RL=1 RL=1 RL=1
-- . . .
-- . /-----------------------------------------\
-- . | . _____ . |
-- . | /------\ nxt_r | | r |
-- . \-->| |---*-------*----->|p_reg|-----*---> src_out
-- . | | | | |_____|
-- snk_in -------->|p_comb|<--|-------|--------------*-------- src_in
-- | | | | |
-- | | | v |
-- | | | /-------\ |
-- | | | |p_flow | |
-- \------/ | \-------/ |
-- | | |
-- nxt_r.hold_out.valid | | |
-- v | |
-- /| |r_snk_out |
-- |0|------/ |
-- snk_out <------------------| | |
-- |1|---------------------/
-- \|
--
-- Description:
-- The dp_repack_data repacks g_in_nof_words of width g_in_dat_w into
-- g_out_nof_words of width g_out_dat_w.
--
-- . g_in_bypass, g_out_bypass
-- The dp_repack_in and dp_repack_out can be bypassed to save logic and to
-- avoid the pipeline stage. Default both are FALSE, but they can be set
-- TRUE if:
--
-- . g_in_bypass =TRUE if g_in_nof_words=g_out_nof_words or g_in_nof_words=1
-- . g_out_bypass=TRUE if g_in_nof_words=g_out_nof_words or g_out_nof_words=1
--
-- Both the dp_repack_in and dp_repack_out stage do work correctly independent
-- of the g_*_bypass setting. When g_*_bypass=FALSE then they merely
-- add a transparant pipeline delay. It is important that they also work for
-- g_*_bypass=FALSE because that gives confidence that their implementation
-- structure is ok.
--
-- . g_in_nof_words and input block size
-- The input block size in words is indicated by snk_in.sop and snk_in.eop.
-- Each subsection of g_in_nof_words is packed into g_out_nof_words. The
-- input block size does not have to be a multiple of g_in_nof_words. When
-- the snk_in.eop occurs the last repack is initiated without need for input
-- data padding. If the block length is an integer multiple of
-- g_in_nof_words then the dp_repack_data introduces no gaps between blocks.
-- If the block length is a fractional multiple of g_in_nof_words then there
-- will be a gap after the block due to that the dp_repack_in needs to
-- shift up the last subsection for the 'missing' input words.
--
-- . g_in_dat_w*g_in_nof_words <, =, > g_in_dat_w*g_in_nof_words
-- . = : no subsection zero padding
-- . < : the subsections will be zero padded
-- . > : then the input must have sufficient zero padded bits per
-- subsection that can be stripped without data loss.
--
-- . Resolution of the empty field
-- The g_in_symbol_w is used to define the resolution of snk_in.empty and
-- the g_out_symbol_w is used to define the resolution of src_out.empty. If
-- they are 1 then the resolution is in number of bits, because the symbol
-- size is then 1 bit. Their value has no effect on the packed data it self,
-- only on the meaning of the empty field. Hence if the empty field is not
-- used, then the setting of g_in_symbol_w and g_out_symbol_w is dont care.
--
-- Remarks:
-- . Originally reused from LOFAR rad_repack.vhd and rad_repack(rtl).vhd. This
-- dp_repack_data still uses the shift in input register in and the shift out
-- output register, but no longer the intermediate buffer register.
-- Using shift in and shift out may ease timing closure because the routing
-- is more local compared to using a demultiplexer to put the input data in
-- the input register and a multiplexer to get the data directly from the
-- output register. For the demultiplexer / multiplexer it would be possible
-- to only use one internal register.
-- Using shift up is sufficient, the shift down option is not needed. With
-- shift up the data is input a [0] and output the high index.
-- Instead of requiring an snk_in.valid duty cycle this dp_repack_data uses
-- snk_out.ready flow control and can handle src_in.ready flow control.
--
-- . To pack ETH/IP/UDP header slv of 14 + 20 + 8 = 42 octets into 32 bit words
-- use:
-- u_dp_repack_data : ENTITY .dp_repack_data
-- GENERIC MAP (
-- g_in_bypass => TRUE,
-- g_in_dat_w => 8 * 42,
-- g_in_nof_words => 1,
-- g_in_symbol_w => 8,
-- g_out_bypass => FALSE,
-- g_out_dat_w => 32,
-- g_out_nof_words => 11,
-- g_out_symbol_w => 8
-- )
-- The src_out.empty will be 2, because:
-- (g_out_dat_w*g_out_nof_words-g_in_dat_w*g_in_nof_words)/g_out_symbol_w
-- = (32*11 - 42*8*1)/ 8 = 2 octet symbols
--
-- Design steps:
-- * In total the development took 5 days. On day 3 I was in distress because
-- I could not get it to work so I needed to rethink. After changing to the
-- new flow control scheme that uses nxt_r the design was gradually improved
-- by getting the dp_repack_data instances in tb_tb_dp_repack_data to work one
-- by one. First only for e_active stimuli and later also for e_random and
-- e_pulse. Initially about 80 % of the functionality was implemented but
-- and subsequently each feature was verified starting with the basic
-- features and then themore detailed features. This step by step approach
-- makes that the bugs appear one by one instead of all together. Without a
-- step by step approach the bugs are too big to solve.
-- . First cases with g_in_nof_words=1 and g_out_nof_words were made to work
-- for different g_pkt_len <, =, > g_in_nof_words.
-- . Then the empty functionality for g_pkt_len MOD g_in_nof_words /= 0 was
-- added.
-- . Tried g_out_dat_w=1 which makes dp_repack_data a serializer/deserializer.
-- . Then apply external flow control using c_dp_flow_control_enum_arr in
-- the tb_tb_dp_repack_data was verified resulting in small corrections.
-- . Then verified g_in_dat_w * g_in_nof_words > or < g_out_dat_w *
-- g_out_nof_words which require padding in the subsection. The > case
-- occurs for packing and the < case then occurs for unpacking.
-- . Added g_bypass to force using wires instead of a void dp_repack_in or
-- dp_repack_out stage.
-- . Verified g_in_symbol_w and g_out_symbol_w /= 1.
-- * The development used the tb_dp_repack_data testbench that does a pack and
-- an unpack to be able to verify the data. The c_no_unpack and
-- c_enable_repack_in and c_enable_repack_out parameters in the tb are
-- useful to be able to isolate a component for debugging.
 
LIBRARY IEEE, common_pkg_lib, dp_pkg_lib;
USE IEEE.std_logic_1164.ALL;
USE common_pkg_lib.common_pkg.ALL;
USE dp_pkg_lib.dp_stream_pkg.ALL;
 
ENTITY dp_repack_in IS
GENERIC (
g_bypass : BOOLEAN := FALSE;
g_in_dat_w : NATURAL;
g_in_nof_words : NATURAL;
g_in_symbol_w : NATURAL := 1 -- default 1 for snk_in.empty in nof bits, else use power of 2
);
PORT (
rst : IN STD_LOGIC;
clk : IN STD_LOGIC;
 
snk_out : OUT t_dp_siso;
snk_in : IN t_dp_sosi;
 
src_in : IN t_dp_siso;
src_out : OUT t_dp_sosi
);
END dp_repack_in;
 
 
ARCHITECTURE rtl OF dp_repack_in IS
 
CONSTANT c_in_buf_dat_w : NATURAL := g_in_dat_w * g_in_nof_words;
CONSTANT c_bit_cnt_max : NATURAL := c_in_buf_dat_w;
CONSTANT c_in_empty_lo : NATURAL := true_log2(g_in_symbol_w);
 
TYPE t_dat_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);
 
TYPE t_reg IS RECORD
dat_arr : t_dat_arr(g_in_nof_words-1 DOWNTO 0); -- internally use dat_arr[] to represent v.src_out.data
src_out : t_dp_sosi; -- sosi output
hold_out : t_dp_sosi; -- hold snk_in.sync/sop/eop until end of section and then hold valid src_out until src_in.ready
flush : STD_LOGIC; -- shift when snk_in.valid or flush in case the last subsection has < g_in_nof_words
dat_bit_cnt : NATURAL RANGE 0 TO c_bit_cnt_max; -- actual nof bits in subsection
pack_bit_cnt : NATURAL RANGE 0 TO c_bit_cnt_max; -- count nof bits in subsection
END RECORD;
 
SIGNAL data_vec : STD_LOGIC_VECTOR(c_in_buf_dat_w-1 DOWNTO 0);
 
SIGNAL r_snk_out : t_dp_siso := c_dp_siso_rdy;
SIGNAL r : t_reg;
SIGNAL nxt_r : t_reg;
 
-- Debug signals
SIGNAL snk_in_data : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);
SIGNAL i_src_out : t_dp_sosi;
SIGNAL src_out_data : STD_LOGIC_VECTOR(c_in_buf_dat_w-1 DOWNTO 0);
 
SIGNAL dbg_g_in_dat_w : NATURAL := g_in_dat_w;
SIGNAL dbg_in_nof_words : NATURAL := g_in_nof_words;
SIGNAL dbg_in_symbol_w : NATURAL := g_in_symbol_w;
SIGNAL dbc_in_buf_dat_w : NATURAL := c_in_buf_dat_w;
 
BEGIN
 
snk_in_data <= snk_in.data(g_in_dat_w-1 DOWNTO 0);
src_out <= i_src_out;
src_out_data <= i_src_out.data(c_in_buf_dat_w-1 DOWNTO 0);
gen_bypass : IF g_bypass=TRUE GENERATE
snk_out <= src_in;
i_src_out <= snk_in;
END GENERATE;
no_bypass : IF g_bypass=FALSE GENERATE
 
p_comb : PROCESS(rst, r, snk_in, data_vec, src_in)
VARIABLE v : t_reg;
BEGIN
------------------------------------------------------------------------
-- Default
v := r;
v.src_out.sync := '0';
v.src_out.valid := '0';
v.src_out.sop := '0';
v.src_out.eop := '0';
--------------------------------------------------------------------------
-- Function
IF r.hold_out.valid='0' THEN
-- Clear hold_out for new output valid (= new subsection)
IF r.src_out.valid='1' THEN
v.hold_out := c_dp_sosi_rst;
END IF;
-- Capture the snk_in block info that is valid at sop and eop
IF snk_in.sop='1' THEN
v.hold_out.sop := '1';
v.hold_out.sync := snk_in.sync;
v.src_out.bsn := snk_in.bsn;
v.src_out.channel := snk_in.channel;
END IF;
IF snk_in.eop='1' THEN
v.hold_out.eop := '1';
v.hold_out.empty := SHIFT_UVEC(snk_in.empty, -c_in_empty_lo); -- use snk_in.empty as offset for src_out.empty in nof bits
v.src_out.err := snk_in.err;
END IF;
-- Capture the data per subsection in a block
IF snk_in.valid='1' OR r.flush='1' THEN
-- shift in during block
v.dat_arr(g_in_nof_words-1 DOWNTO 1) := r.dat_arr(g_in_nof_words-2 DOWNTO 0); -- shift up from low to high and shift in at index 0
IF r.flush='1' THEN
v.dat_arr(0) := (OTHERS=>'0'); -- shift in data=0 for flush
ELSE
v.dat_arr(0) := snk_in.data(g_in_dat_w-1 DOWNTO 0); -- shift in valid data
END IF;
-- pack subsection
IF r.pack_bit_cnt<c_in_buf_dat_w-g_in_dat_w THEN
v.pack_bit_cnt := r.pack_bit_cnt + g_in_dat_w;
-- early end of pack subsection
IF snk_in.eop='1' THEN
v.flush := '1'; -- enable flush in case eop occurs before end of pack subsection
v.dat_bit_cnt := v.pack_bit_cnt; -- capture the current subsection pack_bit_cnt
END IF;
ELSE -- r.pack_bit_cnt=c_in_buf_dat_w-g_in_dat_w
-- default end of pack subsection
v.pack_bit_cnt := 0;
v.flush := '0';
IF r.flush='0' THEN
v.dat_bit_cnt := c_in_buf_dat_w; -- set default subsection pack_bit_cnt
END IF;
v.hold_out.valid := '1'; -- the function has new data to output
END IF;
END IF;
-- pass on the v.dat_arr as data vector
v.src_out.data := RESIZE_DP_DATA(data_vec);
-- pass on dat_bit_cnt via DP empty field
v.src_out.empty := INCR_UVEC(v.hold_out.empty, c_in_buf_dat_w - v.dat_bit_cnt);
-- output input stage into output stage when ready, else hold_out.valid to signal pending output
IF v.hold_out.valid='1' THEN
IF src_in.ready='1' THEN
v.src_out.valid := '1';
v.src_out.sync := v.hold_out.sync;
v.src_out.sop := v.hold_out.sop;
v.src_out.eop := v.hold_out.eop;
v.hold_out.valid := '0';
END IF;
END IF;
ELSE
-- pending output
IF src_in.ready='1' THEN
v.src_out.valid := '1';
v.src_out.sync := r.hold_out.sync;
v.src_out.sop := r.hold_out.sop;
v.src_out.eop := r.hold_out.eop;
v.hold_out.valid := '0';
END IF;
END IF;
------------------------------------------------------------------------
-- Reset and nxt_r
IF rst = '1' THEN
v.src_out := c_dp_sosi_rst;
v.hold_out := c_dp_sosi_rst;
v.flush := '0';
v.dat_bit_cnt := 0;
v.pack_bit_cnt := 0;
END IF;
nxt_r <= v;
END PROCESS;
--------------------------------------------------------------------------
-- p_reg
r <= nxt_r WHEN rising_edge(clk);
--------------------------------------------------------------------------
-- Wires
p_data_vec : PROCESS(nxt_r)
BEGIN
FOR I IN 0 TO g_in_nof_words-1 LOOP
data_vec((I+1)*g_in_dat_w-1 DOWNTO I*g_in_dat_w) <= nxt_r.dat_arr(I);
END LOOP;
END PROCESS;
--------------------------------------------------------------------------
-- Wired output
i_src_out <= r.src_out;
--------------------------------------------------------------------------
-- Flow control
-- local function flow control
p_flow : PROCESS(nxt_r)
BEGIN
r_snk_out <= c_dp_siso_rdy;
IF nxt_r.flush='1' THEN
r_snk_out.ready <= '0'; -- input shift in stage function is always ready except when flushing
END IF;
END PROCESS;
-- combined local and remote src_in flow control
snk_out.ready <= r_snk_out.ready WHEN nxt_r.hold_out.valid='0' ELSE src_in.ready; -- if there is pending output then the src_in ready determines the flow control
snk_out.xon <= src_in.xon; -- just pass on the xon/off frame flow control
END GENERATE;
END rtl;
 
 
 
LIBRARY IEEE, common_pkg_lib, dp_pkg_lib;
USE IEEE.std_logic_1164.ALL;
USE common_pkg_lib.common_pkg.ALL;
USE dp_pkg_lib.dp_stream_pkg.ALL;
 
ENTITY dp_repack_out IS
GENERIC (
g_bypass : BOOLEAN := FALSE;
g_in_buf_dat_w : NATURAL;
g_out_dat_w : NATURAL;
g_out_nof_words : NATURAL;
g_out_symbol_w : NATURAL := 1 -- default 1 for snk_in.empty in nof bits, else use power of 2
);
PORT (
rst : IN STD_LOGIC;
clk : IN STD_LOGIC;
 
snk_out : OUT t_dp_siso;
snk_in : IN t_dp_sosi;
 
src_in : IN t_dp_siso;
src_out : OUT t_dp_sosi
);
END dp_repack_out;
 
ARCHITECTURE rtl OF dp_repack_out IS
 
CONSTANT c_out_buf_dat_w : NATURAL := g_out_dat_w * g_out_nof_words;
CONSTANT c_out_buf_dat_lo : NATURAL := sel_a_b(c_out_buf_dat_w > g_in_buf_dat_w, c_out_buf_dat_w - g_in_buf_dat_w, 0); -- pack into subsection with 0 or more padding bits
CONSTANT c_snk_in_dat_lo : NATURAL := sel_a_b(c_out_buf_dat_w < g_in_buf_dat_w, g_in_buf_dat_w - c_out_buf_dat_w, 0); -- unpack from subsection that has 0 or more padding bits
CONSTANT c_bit_cnt_max : NATURAL := c_out_buf_dat_w;
CONSTANT c_out_empty_lo : NATURAL := true_log2(g_out_symbol_w);
 
TYPE t_dat_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0);
 
TYPE t_reg IS RECORD
dat_arr : t_dat_arr(g_out_nof_words-1 DOWNTO 0);
src_out : t_dp_sosi;
hold_out : t_dp_sosi; -- hold src_out valid and sync/sop/eop until src_in.ready
shift : STD_LOGIC; -- shift out the dat_arr
dat_bit_cnt : NATURAL RANGE 0 TO c_bit_cnt_max; -- actual nof bits in subsection
pack_bit_cnt : NATURAL RANGE 0 TO c_bit_cnt_max; -- count nof bits in subsection
empty_bit_cnt : NATURAL RANGE 0 TO c_bit_cnt_max; -- empty nof bits in subsection
eos : STD_LOGIC; -- end of subsection
END RECORD;
 
SIGNAL data_vec : STD_LOGIC_VECTOR(c_out_buf_dat_w-1 DOWNTO 0) := (OTHERS=>'0');
 
SIGNAL r_snk_out : t_dp_siso := c_dp_siso_rdy;
SIGNAL r : t_reg;
SIGNAL nxt_r : t_reg;
 
-- Debug signals
SIGNAL snk_in_data : STD_LOGIC_VECTOR(g_in_buf_dat_w-1 DOWNTO 0);
SIGNAL i_src_out : t_dp_sosi;
SIGNAL src_out_data : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0);
 
SIGNAL dbg_g_in_buf_dat_w : NATURAL := g_in_buf_dat_w;
SIGNAL dbg_g_out_dat_w : NATURAL := g_out_dat_w;
SIGNAL dbg_out_nof_words : NATURAL := g_out_nof_words;
SIGNAL dbg_out_symbol_w : NATURAL := g_out_symbol_w;
SIGNAL dbc_out_buf_dat_w : NATURAL := c_out_buf_dat_w;
SIGNAL dbc_out_buf_dat_lo : NATURAL := c_out_buf_dat_lo;
SIGNAL dbc_snk_in_dat_lo : NATURAL := c_snk_in_dat_lo;
 
BEGIN
 
snk_in_data <= snk_in.data(g_in_buf_dat_w-1 DOWNTO 0);
src_out <= i_src_out;
src_out_data <= i_src_out.data(g_out_dat_w-1 DOWNTO 0);
gen_bypass : IF g_bypass=TRUE GENERATE
snk_out <= src_in;
p_src_out : PROCESS(snk_in)
BEGIN
i_src_out <= snk_in;
IF c_snk_in_dat_lo>0 THEN
i_src_out.data <= SHIFT_UVEC(snk_in.data, c_snk_in_dat_lo);
i_src_out.empty <= INCR_UVEC( snk_in.empty, -c_snk_in_dat_lo);
END IF;
IF c_out_buf_dat_lo>0 THEN
i_src_out.data <= SHIFT_UVEC(snk_in.data, -c_out_buf_dat_lo);
i_src_out.empty <= INCR_UVEC( snk_in.empty, c_out_buf_dat_lo);
END IF;
END PROCESS;
END GENERATE;
no_bypass : IF g_bypass=FALSE GENERATE
 
p_comb : PROCESS(rst, snk_in, r, data_vec, src_in)
VARIABLE v : t_reg;
BEGIN
------------------------------------------------------------------------
-- Default
v := r;
v.src_out.sync := '0';
v.src_out.valid := '0';
v.src_out.sop := '0';
v.src_out.eop := '0';
------------------------------------------------------------------------
-- Function
IF r.hold_out.valid='0' THEN
-- Clear hold_out for new output valid
IF r.src_out.sop='1' THEN
v.hold_out.sync := '0';
v.hold_out.sop := '0';
END IF;
IF r.src_out.eop='1' THEN
v.hold_out.eop := '0';
END IF;
-- Capture the snk_in block info that is valid at sop and eop
IF snk_in.sop='1' THEN
v.hold_out.sop := '1';
v.hold_out.sync := snk_in.sync;
v.src_out.bsn := snk_in.bsn;
v.src_out.channel := snk_in.channel;
END IF;
IF snk_in.eop='1' THEN
v.hold_out.eop := '1'; -- local function will calculate src_out.empty based on snk_in.empty
v.src_out.err := snk_in.err;
END IF;
IF r.shift='1' THEN
-- shift out rest of subsection
v.hold_out.valid := '1';
v.dat_arr(g_out_nof_words-1 DOWNTO 1) := r.dat_arr(g_out_nof_words-2 DOWNTO 0); -- shift up from low to high and shift out at high index
v.dat_arr(0) := (OTHERS=>'0'); -- shift in data=0
v.pack_bit_cnt := r.pack_bit_cnt - g_out_dat_w;
-- end of pack subsection
IF v.pack_bit_cnt<=r.empty_bit_cnt THEN
v.eos := '1'; -- end of subsection, so ready for new snk_in
v.shift := '0'; -- stop shifting
END IF;
ELSIF snk_in.valid='1' THEN
-- start of pack subsection
v.hold_out.valid := '1';
FOR I IN 0 TO g_out_nof_words-1 LOOP
v.dat_arr(I) := data_vec((I+1)*g_out_dat_w-1 DOWNTO I*g_out_dat_w);
END LOOP;
v.dat_bit_cnt := g_in_buf_dat_w - c_snk_in_dat_lo; -- default dat_bit_cnt per subsection
IF snk_in.eop='1' THEN
v.dat_bit_cnt := g_in_buf_dat_w - TO_UINT(snk_in.empty); -- pass on last subsection dat_bit_cnt info via DP empty field
END IF;
v.pack_bit_cnt := c_out_buf_dat_w - g_out_dat_w;
v.empty_bit_cnt := c_out_buf_dat_w - v.dat_bit_cnt;
v.eos := '0';
v.shift := '1';
-- end of pack subsection
IF v.pack_bit_cnt<=v.empty_bit_cnt THEN
v.eos := '1'; -- end of subsection, so ready for new snk_in
v.shift := '0';
END IF;
END IF;
-- fill in local empty if this is the last subsection of a block
IF v.eos='1' THEN
IF v.hold_out.eop='1' THEN
v.src_out.empty := TO_DP_EMPTY(v.empty_bit_cnt - v.pack_bit_cnt); -- in nof bits
v.src_out.empty := SHIFT_UVEC(v.src_out.empty, c_out_empty_lo); -- in nof symbols
END IF;
END IF;
-- pass on the v.dat_arr as data vector
v.src_out.data := RESIZE_DP_DATA(v.dat_arr(g_out_nof_words-1));
-- output valid data when ready, else hold_out.valid to signal pending output
IF v.hold_out.valid='1' THEN
IF src_in.ready='1' THEN
v.src_out.valid := '1';
v.src_out.sync := v.hold_out.sync;
v.src_out.sop := v.hold_out.sop;
v.src_out.eop := v.hold_out.eop AND v.eos; -- output eop at end of subsection
v.hold_out.valid := '0';
END IF;
END IF;
ELSE
-- pending output
IF src_in.ready='1' THEN
v.src_out.valid := '1';
v.src_out.sync := r.hold_out.sync;
v.src_out.sop := r.hold_out.sop;
v.src_out.eop := r.hold_out.eop AND r.eos; -- output eop at end of subsection
v.hold_out.valid := '0';
END IF;
END IF;
------------------------------------------------------------------------
-- Reset and nxt_r
IF rst = '1' THEN
v.src_out := c_dp_sosi_rst;
v.hold_out := c_dp_sosi_rst;
v.shift := '0';
v.dat_bit_cnt := 0;
v.pack_bit_cnt := 0;
v.empty_bit_cnt := 0;
v.eos := '0';
END IF;
nxt_r <= v;
END PROCESS;
--------------------------------------------------------------------------
-- p_reg
r <= nxt_r WHEN rising_edge(clk);
--------------------------------------------------------------------------
-- Wires
data_vec(c_out_buf_dat_w-1 DOWNTO c_out_buf_dat_lo) <= snk_in.data(g_in_buf_dat_w-1 DOWNTO c_snk_in_dat_lo);
--------------------------------------------------------------------------
-- Wired output
i_src_out <= r.src_out;
--------------------------------------------------------------------------
-- Flow control
-- local function flow control
p_flow : PROCESS(nxt_r)
BEGIN
r_snk_out <= c_dp_siso_rdy;
IF nxt_r.shift='1' AND nxt_r.eos='0' THEN
r_snk_out.ready <= '0'; -- output shift out stage function is only ready when it is not shifting or at the end of the subsection
END IF;
END PROCESS;
-- combined local and remote src_in flow control
snk_out.ready <= r_snk_out.ready WHEN nxt_r.hold_out.valid='0' ELSE src_in.ready; -- if there is pending output then the src_in ready determines the flow control
snk_out.xon <= src_in.xon; -- just pass on the xon/off frame flow control
END GENERATE;
END rtl;
 
 
 
LIBRARY IEEE, common_pkg_lib, dp_pkg_lib;
USE IEEE.std_logic_1164.ALL;
USE common_pkg_lib.common_pkg.ALL;
USE dp_pkg_lib.dp_stream_pkg.ALL;
 
ENTITY dp_repack_data IS
GENERIC (
g_enable_repack_in : BOOLEAN := TRUE;
g_enable_repack_out : BOOLEAN := TRUE;
g_in_bypass : BOOLEAN := FALSE;
g_in_dat_w : NATURAL;
g_in_nof_words : NATURAL;
g_in_symbol_w : NATURAL := 1; -- default 1 for snk_in.empty in nof bits, else use power of 2
g_out_bypass : BOOLEAN := FALSE;
g_out_dat_w : NATURAL;
g_out_nof_words : NATURAL;
g_out_symbol_w : NATURAL := 1 -- default 1 for src_out.empty in nof bits, else use power of 2
);
PORT (
rst : IN STD_LOGIC;
clk : IN STD_LOGIC;
 
snk_out : OUT t_dp_siso;
snk_in : IN t_dp_sosi;
 
src_in : IN t_dp_siso;
src_out : OUT t_dp_sosi
);
END dp_repack_data;
 
 
ARCHITECTURE str OF dp_repack_data IS
 
CONSTANT c_in_buf_dat_w : NATURAL := g_in_dat_w * g_in_nof_words;
 
SIGNAL snk_in_data : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);
SIGNAL i_snk_out : t_dp_siso;
 
SIGNAL pack_siso : t_dp_siso;
SIGNAL pack_sosi : t_dp_sosi;
SIGNAL pack_sosi_data : STD_LOGIC_VECTOR(c_in_buf_dat_w-1 DOWNTO 0);
 
SIGNAL i_src_out : t_dp_sosi;
SIGNAL src_out_data : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0);
 
SIGNAL snk_out_ready_reg : STD_LOGIC_VECTOR(0 TO c_dp_stream_rl);
SIGNAL pack_ready_reg : STD_LOGIC_VECTOR(0 TO c_dp_stream_rl);
 
BEGIN
 
snk_out <= i_snk_out;
src_out <= i_src_out;
 
snk_in_data <= snk_in.data(g_in_dat_w-1 DOWNTO 0);
pack_sosi_data <= pack_sosi.data(c_in_buf_dat_w-1 DOWNTO 0);
src_out_data <= i_src_out.data(g_out_dat_w-1 DOWNTO 0);
 
no_dp_repack_in : IF g_enable_repack_in=FALSE GENERATE
i_snk_out <= pack_siso;
pack_sosi <= snk_in;
END GENERATE;
 
gen_dp_repack_in : IF g_enable_repack_in=TRUE GENERATE
u_dp_repack_in : ENTITY work.dp_repack_in
GENERIC MAP (
g_bypass => g_in_bypass,
g_in_dat_w => g_in_dat_w,
g_in_nof_words => g_in_nof_words,
g_in_symbol_w => g_in_symbol_w
)
PORT MAP (
rst => rst,
clk => clk,
 
snk_out => i_snk_out,
snk_in => snk_in,
 
src_in => pack_siso,
src_out => pack_sosi
);
END GENERATE;
 
no_dp_repack_out : IF g_enable_repack_out=FALSE GENERATE
pack_siso <= src_in;
i_src_out <= pack_sosi;
END GENERATE;
 
gen_dp_repack_out : IF g_enable_repack_out=TRUE GENERATE
u_dp_repack_out : ENTITY work.dp_repack_out
GENERIC MAP (
g_bypass => g_out_bypass,
g_in_buf_dat_w => c_in_buf_dat_w,
g_out_dat_w => g_out_dat_w,
g_out_nof_words => g_out_nof_words,
g_out_symbol_w => g_out_symbol_w
)
PORT MAP (
rst => rst,
clk => clk,
 
snk_out => pack_siso,
snk_in => pack_sosi,
 
src_in => src_in,
src_out => i_src_out
);
END GENERATE;
 
-- Simulation only: internal stream RL verification
proc_dp_siso_alert(clk, snk_in, i_snk_out, snk_out_ready_reg);
proc_dp_siso_alert(clk, pack_sosi, pack_siso, pack_ready_reg);
 
END str;
/hdllib.cfg
0,0 → 1,20
hdl_lib_name = dp_repack_data
hdl_library_clause_name = dp_repack_data_lib
hdl_lib_uses_synth = dp_pkg
hdl_lib_uses_sim =
hdl_lib_technology =
 
synth_files =
dp_repack_data.vhd
test_bench_files =
tb_dp_repack_data.vhd
tb_tb_dp_repack_data.vhd
 
regression_test_vhdl =
tb_tb_dp_repack_data.vhd
[modelsim_project_file]
 
 
[quartus_project_file]
/tb_dp_repack_data.vhd
0,0 → 1,317
-------------------------------------------------------------------------------
--
-- Copyright (C) 2015
-- 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:
-- . Test bench for dp_repack_data
-- Description:
-- c_no_unpack
-- .
-- g_in_dat_w g_pack_dat_w . g_in_dat_w
-- g_in_nof_words g_pack_nof_words . g_in_nof_words
-- . . . .
-- . u_pack . u_unpack . .
-- . ______________ . ______________ .
-- . |dp_repack_data| . |dp_repack_data| .
-- stimuli_src ---->| |----------->| |----> verify_snk
-- | in out | pack_src | in out |
-- |______________| |______________|
--
-- Usage:
-- > as 10
-- > run -all
--
 
LIBRARY IEEE, common_pkg_lib, dp_pkg_lib;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
USE common_pkg_lib.common_pkg.ALL;
USE common_pkg_lib.common_lfsr_sequences_pkg.ALL;
USE common_pkg_lib.tb_common_pkg.ALL;
USE dp_pkg_lib.dp_stream_pkg.ALL;
USE dp_pkg_lib.tb_dp_pkg.ALL;
 
 
ENTITY tb_dp_repack_data IS
GENERIC (
-- general
g_flow_control_stimuli : t_dp_flow_control_enum := e_active; -- always e_active, e_random or e_pulse flow control
g_flow_control_verify : t_dp_flow_control_enum := e_active; -- always e_active, e_random or e_pulse flow control
-- specific
g_in_dat_w : NATURAL := 8 * 42;
g_in_nof_words : NATURAL := 1;
g_pack_dat_w : NATURAL := 32;
g_pack_nof_words : NATURAL := 11;
g_in_bypass : BOOLEAN := TRUE; -- can use TRUE when g_in_nof_words=1 or g_in_nof_words=g_out_nof_words
g_pack_bypass : BOOLEAN := FALSE; -- can use TRUE when g_out_nof_words=1 or g_in_nof_words=g_out_nof_words
g_in_symbol_w : NATURAL := 8; -- default 1 for snk_in.empty in nof bits, else use power of 2
g_pack_symbol_w : NATURAL := 8; -- default 1 for src_out.empty in nof bits, else use power of 2
g_nof_repeat : NATURAL := 10;
g_pkt_len : NATURAL := 1; -- if not a multiple of g_in_nof_words then the input stage flush creates gap between blocks
g_pkt_gap : NATURAL := 0
);
END tb_dp_repack_data;
 
 
ARCHITECTURE tb OF tb_dp_repack_data IS
 
CONSTANT c_no_unpack : BOOLEAN := FALSE;
CONSTANT c_enable_repack_in : BOOLEAN := TRUE;
CONSTANT c_enable_repack_out : BOOLEAN := TRUE;
 
-- dp_stream_stimuli
CONSTANT c_stimuli_pulse_active : NATURAL := 3; --g_in_nof_words;
CONSTANT c_stimuli_pulse_period : NATURAL := 7;
 
CONSTANT c_data_init : NATURAL := 0;
CONSTANT c_bsn_init : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0) := X"0000000000000000"; -- X"0877665544332211"
CONSTANT c_err_init : NATURAL := 247;
CONSTANT c_channel_init : NATURAL := 5; -- fixed
 
-- dp_stream_verify
CONSTANT c_verify_pulse_active : NATURAL := 1;
CONSTANT c_verify_pulse_period : NATURAL := 5;
 
CONSTANT c_data_max : UNSIGNED(g_in_dat_w-1 DOWNTO 0) := (OTHERS=>'1');
CONSTANT c_dsp_max : UNSIGNED(g_in_dat_w-1 DOWNTO 0) := (OTHERS=>'1');
 
--CONSTANT c_verify_snk_in_cnt_max : t_dp_sosi_unsigned := c_dp_sosi_unsigned_rst; -- default 0 is no wrap
CONSTANT c_verify_snk_in_cnt_max : t_dp_sosi_unsigned := TO_DP_SOSI_UNSIGNED('0', '0', '0', '0', c_data_max, c_dsp_max, c_dsp_max, c_unsigned_0, c_unsigned_0, c_unsigned_0, c_unsigned_0);
CONSTANT c_verify_snk_in_cnt_gap : t_dp_sosi_unsigned := c_dp_sosi_unsigned_ones; -- default only accept increment +1
 
CONSTANT c_expected_pkt_len : NATURAL := sel_a_b(c_no_unpack, g_pkt_len * g_pack_nof_words / g_in_nof_words, g_pkt_len);
-- both
CONSTANT c_sync_period : NATURAL := 10;
CONSTANT c_sync_offset : NATURAL := 7;
 
SIGNAL clk : STD_LOGIC := '1';
SIGNAL rst : STD_LOGIC := '1';
SIGNAL tb_end : STD_LOGIC := '0';
 
SIGNAL stimuli_src_in : t_dp_siso := c_dp_siso_rdy;
SIGNAL stimuli_src_out : t_dp_sosi;
SIGNAL stimuli_src_out_data : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);
 
SIGNAL verify_snk_in_enable : t_dp_sosi_sl := c_dp_sosi_sl_rst;
SIGNAL last_snk_in : t_dp_sosi;
SIGNAL last_snk_in_evt : STD_LOGIC;
SIGNAL verify_last_snk_in_evt : t_dp_sosi_sl := c_dp_sosi_sl_rst;
 
SIGNAL verify_snk_out : t_dp_siso := c_dp_siso_rdy;
SIGNAL verify_snk_in : t_dp_sosi;
SIGNAL verify_snk_in_data : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);
 
-- specific
SIGNAL pack_src_in : t_dp_siso;
SIGNAL pack_src_out : t_dp_sosi;
SIGNAL pack_src_out_data : STD_LOGIC_VECTOR(g_pack_dat_w-1 DOWNTO 0);
 
SIGNAL unpack_src_in : t_dp_siso;
SIGNAL unpack_src_out : t_dp_sosi;
SIGNAL unpack_src_out_data : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);
 
BEGIN
 
clk <= (NOT clk) OR tb_end AFTER clk_period/2;
rst <= '1', '0' AFTER clk_period*7;
 
------------------------------------------------------------------------------
-- DATA GENERATION
------------------------------------------------------------------------------
 
u_dp_stream_stimuli : ENTITY dp_pkg_lib.dp_stream_stimuli
GENERIC MAP (
g_instance_nr => 0, -- only one stream so choose index 0
-- flow control
g_random_w => 15, -- use different random width for stimuli and for verify to have different random sequences
g_pulse_active => c_stimuli_pulse_active,
g_pulse_period => c_stimuli_pulse_period,
g_flow_control => g_flow_control_stimuli, -- always active, random or pulse flow control
-- initializations
g_sync_period => c_sync_period,
g_sync_offset => c_sync_offset,
g_data_init => c_data_init,
g_bsn_init => c_bsn_init,
g_err_init => c_err_init,
g_channel_init => c_channel_init,
-- specific
g_in_dat_w => g_in_dat_w,
g_nof_repeat => g_nof_repeat,
g_pkt_len => g_pkt_len,
g_pkt_gap => g_pkt_gap
)
PORT MAP (
rst => rst,
clk => clk,
 
-- Generate stimuli
src_in => stimuli_src_in,
src_out => stimuli_src_out,
 
-- End of stimuli
last_snk_in => last_snk_in, -- expected verify_snk_in after end of stimuli
last_snk_in_evt => last_snk_in_evt, -- trigger verify to verify the last_snk_in
tb_end => tb_end -- signal end of tb as far as this dp_stream_stimuli is concerned
);
 
 
------------------------------------------------------------------------------
-- DATA VERIFICATION
------------------------------------------------------------------------------
 
-- Select fields that need to be verified
-- . during the test
verify_snk_in_enable.sync <= '1';
verify_snk_in_enable.bsn <= '1';
verify_snk_in_enable.data <= '1' WHEN c_no_unpack=FALSE ELSE '0';
verify_snk_in_enable.re <= '0';
verify_snk_in_enable.im <= '0';
verify_snk_in_enable.valid <= '1';
verify_snk_in_enable.sop <= '1';
verify_snk_in_enable.eop <= '1';
verify_snk_in_enable.empty <= '0';
verify_snk_in_enable.channel <= '1';
verify_snk_in_enable.err <= '1';
 
-- . after the test
verify_last_snk_in_evt.sync <= last_snk_in_evt;
verify_last_snk_in_evt.bsn <= last_snk_in_evt;
verify_last_snk_in_evt.data <= last_snk_in_evt WHEN c_no_unpack=FALSE ELSE '0';
verify_last_snk_in_evt.re <= '0';
verify_last_snk_in_evt.im <= '0';
verify_last_snk_in_evt.valid <= last_snk_in_evt;
verify_last_snk_in_evt.sop <= last_snk_in_evt;
verify_last_snk_in_evt.eop <= last_snk_in_evt;
verify_last_snk_in_evt.empty <= '0';
verify_last_snk_in_evt.channel <= last_snk_in_evt;
verify_last_snk_in_evt.err <= last_snk_in_evt;
 
u_dp_stream_verify : ENTITY dp_pkg_lib.dp_stream_verify
GENERIC MAP (
g_instance_nr => 0, -- only one stream so choose index 0
-- flow control
g_random_w => 14, -- use different random width for stimuli and for verify to have different random sequences
g_pulse_active => c_verify_pulse_active,
g_pulse_period => c_verify_pulse_period,
g_flow_control => g_flow_control_verify, -- always active, random or pulse flow control
-- initializations
g_sync_period => c_sync_period,
g_sync_offset => c_sync_offset,
g_snk_in_cnt_max => c_verify_snk_in_cnt_max,
g_snk_in_cnt_gap => c_verify_snk_in_cnt_gap,
-- specific
g_in_dat_w => g_in_dat_w,
g_pkt_len => c_expected_pkt_len
)
PORT MAP (
rst => rst,
clk => clk,
 
-- Verify data
snk_out => verify_snk_out,
snk_in => verify_snk_in,
 
-- During stimuli
verify_snk_in_enable => verify_snk_in_enable, -- enable verify to verify that the verify_snk_in fields are incrementing
 
-- End of stimuli
expected_snk_in => last_snk_in, -- expected verify_snk_in after end of stimuli
verify_expected_snk_in_evt => verify_last_snk_in_evt -- trigger verify to verify the last_snk_in
);
 
------------------------------------------------------------------------------
-- DUT Pack
------------------------------------------------------------------------------
 
u_pack : ENTITY work.dp_repack_data
GENERIC MAP (
g_enable_repack_in => c_enable_repack_in,
g_enable_repack_out => c_enable_repack_out,
g_in_bypass => g_in_bypass,
g_in_dat_w => g_in_dat_w,
g_in_nof_words => g_in_nof_words,
g_in_symbol_w => g_in_symbol_w,
g_out_bypass => g_pack_bypass,
g_out_dat_w => g_pack_dat_w,
g_out_nof_words => g_pack_nof_words,
g_out_symbol_w => g_pack_symbol_w
)
PORT MAP (
rst => rst,
clk => clk,
 
snk_out => stimuli_src_in,
snk_in => stimuli_src_out,
 
src_in => pack_src_in,
src_out => pack_src_out
);
 
pack_src_out_data <= pack_src_out.data(g_pack_dat_w-1 DOWNTO 0);
 
------------------------------------------------------------------------------
-- DUT Unpack
------------------------------------------------------------------------------
 
no_unpack : IF c_no_unpack=TRUE GENERATE
pack_src_in <= unpack_src_in;
unpack_src_out <= pack_src_out;
END GENERATE;
 
gen_unpack : IF c_no_unpack=FALSE GENERATE
u_unpack : ENTITY work.dp_repack_data
GENERIC MAP (
g_enable_repack_in => c_enable_repack_out,
g_enable_repack_out => c_enable_repack_in,
g_in_bypass => g_pack_bypass,
g_in_dat_w => g_pack_dat_w,
g_in_nof_words => g_pack_nof_words,
g_in_symbol_w => g_pack_symbol_w,
g_out_bypass => g_in_bypass,
g_out_dat_w => g_in_dat_w,
g_out_nof_words => g_in_nof_words,
g_out_symbol_w => g_in_symbol_w
)
PORT MAP (
rst => rst,
clk => clk,
 
snk_out => pack_src_in,
snk_in => pack_src_out,
 
src_in => unpack_src_in,
src_out => unpack_src_out
);
END GENERATE;
 
unpack_src_out_data <= unpack_src_out.data(g_in_dat_w-1 DOWNTO 0);
 
unpack_src_in <= verify_snk_out;
verify_snk_in <= unpack_src_out;
------------------------------------------------------------------------------
-- Auxiliary
------------------------------------------------------------------------------
 
-- Map to slv to ease monitoring in wave window
stimuli_src_out_data <= stimuli_src_out.data(g_in_dat_w-1 DOWNTO 0);
verify_snk_in_data <= verify_snk_in.data(g_in_dat_w-1 DOWNTO 0);
 
END tb;
/tb_tb_dp_repack_data.vhd
0,0 → 1,166
-------------------------------------------------------------------------------
--
-- Copyright (C) 2015
-- 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_pkg_lib, dp_pkg_lib;
USE IEEE.std_logic_1164.ALL;
USE common_pkg_lib.common_pkg.ALL;
USE dp_pkg_lib.tb_dp_pkg.ALL;
 
-- Purpose: Verify multiple variations of tb_dp_repack_data
-- Description:
-- Usage:
-- > as 6
-- > run -all
 
ENTITY tb_tb_dp_repack_data IS
END tb_tb_dp_repack_data;
 
 
ARCHITECTURE tb OF tb_tb_dp_repack_data IS
 
CONSTANT c_nof_repeat : NATURAL := 5;
CONSTANT c_flow : t_dp_flow_control_enum_arr := c_dp_flow_control_enum_arr;
CONSTANT c_bool : t_nat_boolean_arr := c_nat_boolean_arr;
SIGNAL tb_end : STD_LOGIC := '0'; -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end'
BEGIN
 
-- -- general
-- g_flow_control_stimuli : t_dp_flow_control_enum := e_active; -- always e_active, e_random or e_pulse flow control
-- g_flow_control_verify : t_dp_flow_control_enum := e_active; -- always e_active, e_random or e_pulse flow control
-- -- specific
-- g_in_dat_w : NATURAL := 5;
-- g_in_nof_words : NATURAL := 2;
-- g_pack_dat_w : NATURAL := 16;
-- g_pack_nof_words : NATURAL := 1;
-- g_in_bypass : BOOLEAN := FALSE; -- can use TRUE when g_in_nof_words=1 or g_in_nof_words=g_out_nof_words
-- g_pack_bypass : BOOLEAN := FALSE; -- can use TRUE when g_out_nof_words=1 or g_in_nof_words=g_out_nof_words
-- g_in_symbol_w : NATURAL := 1; -- default 1 for snk_in.empty in nof bits, else use power of 2
-- g_pack_symbol_w : NATURAL := 1; -- default 1 for src_out.empty in nof bits, else use power of 2
-- g_nof_repeat : NATURAL := 10;
-- g_pkt_len : NATURAL := 11; -- if not a multiple of g_in_nof_words then the input stage flush creates gap between blocks
-- g_pkt_gap : NATURAL := 0
g_flow_control_stimuli : FOR I IN 0 TO 2 GENERATE -- 0 = e_active, 1 = e_random, 2 = e_pulse
g_flow_control_verify : FOR J IN 0 TO 2 GENERATE -- 0 = e_active, 1 = e_random, 2 = e_pulse
 
-------------------------------------------------------------------------
-- Tests that can use bypass
-- . g_in_nof_words = 1
-- . g_out_nof_words = 1
-- . g_in_nof_words = g_in_nof_words >= 1
-------------------------------------------------------------------------
gen_bool_bypass : FOR K IN 0 TO 1 GENERATE
gen_bool_bypass : FOR L IN 0 TO 1 GENERATE
-- no repack, g_in_nof_words = g_out_nof_words = 1
u_16_1_16_1_len_10_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 16, 1, 16, 1, c_bool(K), c_bool(L), 1, 1, c_nof_repeat, 10, 0); -- g_pkt_len > g_in_nof_words
u_16_1_16_1_len_3_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 16, 1, 16, 1, c_bool(K), c_bool(L), 1, 1, c_nof_repeat, 3, 0); -- g_pkt_len > g_in_nof_words, odd
u_16_1_16_1_len_2_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 16, 1, 16, 1, c_bool(K), c_bool(L), 1, 1, c_nof_repeat, 2, 0); -- g_pkt_len > g_in_nof_words, even
u_16_1_16_1_len_1_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 16, 1, 16, 1, c_bool(K), c_bool(L), 1, 1, c_nof_repeat, 1, 0); -- g_pkt_len = g_in_nof_words
u_16_1_16_1_len_1_gap_1 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 16, 1, 16, 1, c_bool(K), c_bool(L), 1, 1, c_nof_repeat, 1, 1); -- g_pkt_gap > 0
END GENERATE;
-- no repack, g_in_nof_words = g_out_nof_words > 1
u_16_3_16_3_len_10_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 16, 3, 16, 3, c_bool(K), c_bool(K), 1, 1, c_nof_repeat, 10, 0);
-- g_in_nof_words > g_pack_nof_words can use always active stimuli except when g_pkt_len MOD g_in_nof_words /= 0, because then the input stage needs to flush
u_8_4_32_1_len_1_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 8, 4, 32, 1, FALSE, c_bool(K), 1, 1, c_nof_repeat, 1, 0); -- g_pkt_len < g_in_nof_words
u_8_4_32_1_len_2_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 8, 4, 32, 1, FALSE, c_bool(K), 1, 1, c_nof_repeat, 2, 0); -- g_pkt_len = g_in_nof_words
u_8_4_32_1_len_3_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 8, 4, 32, 1, FALSE, c_bool(K), 1, 1, c_nof_repeat, 3, 0); -- g_pkt_len > g_in_nof_words, MOD /= 0
u_8_4_32_1_len_10_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 8, 4, 32, 1, FALSE, c_bool(K), 1, 1, c_nof_repeat, 10, 0); -- g_pkt_len > g_in_nof_words, MOD /= 0
u_8_4_32_1_len_11_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 8, 4, 32, 1, FALSE, c_bool(K), 1, 1, c_nof_repeat, 11, 0); -- g_pkt_len > g_in_nof_words, MOD /= 0
u_8_4_32_1_len_12_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 8, 4, 32, 1, FALSE, c_bool(K), 1, 1, c_nof_repeat, 12, 0); -- g_pkt_len > g_in_nof_words, MOD = 0
u_8_4_32_1_len_12_gap_2 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 8, 4, 32, 1, FALSE, c_bool(K), 1, 1, c_nof_repeat, 12, 2); -- g_pkt_gap > 0
-- g_in_nof_words < g_pack_nof_words will apply backpressure, because the output stage needs to output more
u_32_1_8_4_len_1_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 32, 1, 8, 4, c_bool(K), FALSE, 1, 1, c_nof_repeat, 1, 0); -- g_pkt_len = g_in_nof_words
u_32_1_8_4_len_2_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 32, 1, 8, 4, c_bool(K), FALSE, 1, 1, c_nof_repeat, 2, 0); -- g_pkt_len > g_in_nof_words
u_32_1_8_4_len_3_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 32, 1, 8, 4, c_bool(K), FALSE, 1, 1, c_nof_repeat, 3, 0); -- g_pkt_len > g_in_nof_words
u_32_1_8_4_len_10_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 32, 1, 8, 4, c_bool(K), FALSE, 1, 1, c_nof_repeat, 10, 0); -- g_pkt_len > g_in_nof_words
u_32_1_8_4_len_11_gap_1 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 32, 1, 8, 4, c_bool(K), FALSE, 1, 1, c_nof_repeat, 11, 1); -- g_pkt_gap > 0
-- g_in_dat_w MOD 8 /= 0, g_in_nof_words=1
u_14_1_8_2_len_10_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 14, 1, 8, 2, c_bool(K), FALSE, 1, 1, c_nof_repeat, 10, 0); -- repack with subsection padding, even multiple of g_in_nof_words
u_14_1_8_2_len_11_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 14, 1, 8, 2, c_bool(K), FALSE, 1, 1, c_nof_repeat, 11, 0); -- repack with subsection padding, odd multiple of g_in_nof_words
-- g_in_dat_w MOD 8 /= 0, g_out_nof_words=1
u_5_2_16_1_len_10_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 5, 2, 16, 1, FALSE, c_bool(K), 1, 1, c_nof_repeat, 10, 0); -- repack with subsection padding, integer multiple of g_in_nof_words
u_5_2_16_1_len_11_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 5, 2, 16, 1, FALSE, c_bool(K), 1, 1, c_nof_repeat, 11, 0); -- repack with subsection padding, fractional multiple of g_in_nof_words
-- g_in_nof_words=1, g_pack_nof_words>1
u_8_1_4_2_len_10_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 8, 1, 4, 2, c_bool(K), FALSE, 1, 1, c_nof_repeat, 10, 0);
u_512_1_32_16_len_1_gap_20 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 512, 1, 32, 16, c_bool(K), FALSE, 1, 1, c_nof_repeat, 1, 20); -- pack a larger header slv into g_pack_dat_w words
-- serialize to and deserialize from g_pack_dat_w=1 bit
u_8_1_1_8_len_10_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 8, 1, 1, 8, c_bool(K), FALSE, 1, 1, c_nof_repeat, 10, 0); -- g_pack_dat_w=1
u_32_1_1_32_len_10_gap_7 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 32, 1, 1, 32, c_bool(K), FALSE, 1, 1, c_nof_repeat, 10, 7); -- g_pack_dat_w=1
-- g_in_symbol_w /= 1, g_out_symbol_w /= 1
u_20_1_8_3_symbol_1_4_len_10_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 20, 1, 8, 3, c_bool(K), FALSE, 1, 4, c_nof_repeat, 10, 0); -- no repack
u_20_1_8_3_symbol_4_1_len_10_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 20, 1, 8, 3, c_bool(K), FALSE, 4, 1, c_nof_repeat, 10, 0); -- no repack
u_20_1_8_3_symbol_4_4_len_10_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 20, 1, 8, 3, c_bool(K), FALSE, 4, 4, c_nof_repeat, 10, 0); -- no repack
-- pack ETH/IP/UDP header, g_in_symbol_w = 8, g_out_symbol_w = 8
u_336_1_32_11_symbol_8_8_len_1_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 336, 1, 32, 11, c_bool(K), FALSE, 8, 8, c_nof_repeat, 1, 0); --pack to 32 bit --> empty = 2
u_336_1_64_6_symbol_8_8_len_1_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 336, 1, 64, 6, c_bool(K), FALSE, 8, 8, c_nof_repeat, 1, 0); --pack to 64 bit --> empty = 6
END GENERATE;
-------------------------------------------------------------------------
-- Tests that cannot use bypass
-------------------------------------------------------------------------
-- g_in_nof_words > 1 and g_pack_nof_words > 1
u_24_2_16_3_len_1_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 24, 2, 16, 3, FALSE, FALSE, 1, 1, c_nof_repeat, 1, 0); -- g_pkt_len < g_in_nof_words
u_24_2_16_3_len_2_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 24, 2, 16, 3, FALSE, FALSE, 1, 1, c_nof_repeat, 2, 0); -- g_pkt_len = g_in_nof_words
u_24_2_16_3_len_3_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 24, 2, 16, 3, FALSE, FALSE, 1, 1, c_nof_repeat, 3, 0); -- g_pkt_len = fractional multiple of g_in_nof_words
u_24_2_16_3_len_10_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 24, 2, 16, 3, FALSE, FALSE, 1, 1, c_nof_repeat, 10, 0); -- g_pkt_len = integer multiple of g_in_nof_words
u_24_2_16_3_len_11_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 24, 2, 16, 3, FALSE, FALSE, 1, 1, c_nof_repeat, 11, 0); -- g_pkt_len = fractional multiple of g_in_nof_words
u_24_2_16_3_len_11_gap_3 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 24, 2, 16, 3, FALSE, FALSE, 1, 1, c_nof_repeat, 11, 3); -- g_pkt_gap > 0
 
-- g_in_dat_w MOD 8 /= 0
u_6_5_10_3_len_1_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 6, 5, 10, 3, FALSE, FALSE, 1, 1, c_nof_repeat, 1, 0); -- g_pkt_len < g_in_nof_words
u_6_5_10_3_len_2_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 6, 5, 10, 3, FALSE, FALSE, 1, 1, c_nof_repeat, 2, 0); -- g_pkt_len < g_in_nof_words
u_6_5_10_3_len_3_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 6, 5, 10, 3, FALSE, FALSE, 1, 1, c_nof_repeat, 3, 0); -- g_pkt_len < g_in_nof_words
u_6_5_10_3_len_4_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 6, 5, 10, 3, FALSE, FALSE, 1, 1, c_nof_repeat, 4, 0); -- g_pkt_len < g_in_nof_words
u_6_5_10_3_len_5_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 6, 5, 10, 3, FALSE, FALSE, 1, 1, c_nof_repeat, 5, 0); -- g_pkt_len = g_in_nof_words
u_6_5_10_3_len_10_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 6, 5, 10, 3, FALSE, FALSE, 1, 1, c_nof_repeat, 10, 0); -- g_pkt_len = integer multiple of g_in_nof_words
u_6_5_10_3_len_11_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 6, 5, 10, 3, FALSE, FALSE, 1, 1, c_nof_repeat, 11, 0); -- g_pkt_len = fractional multiple of g_in_nof_words
u_6_5_10_3_len_21_gap_3 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 6, 5, 10, 3, FALSE, FALSE, 1, 1, c_nof_repeat, 21, 3); -- g_pkt_gap > 0
-- subsection padding, g_in_dat_w * g_in_nof_words < g_pack_dat_w * g_pack_nof_words
u_18_2_8_5_len_1_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 18, 2, 8, 5, FALSE, FALSE, 1, 1, c_nof_repeat, 1, 0); -- g_pkt_len < g_in_nof_words
u_18_2_8_5_len_2_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 18, 2, 8, 5, FALSE, FALSE, 1, 1, c_nof_repeat, 2, 0); -- g_pkt_len = g_in_nof_words
u_18_2_8_5_len_3_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 18, 2, 8, 5, FALSE, FALSE, 1, 1, c_nof_repeat, 3, 0); -- g_pkt_len = fractional multiple of g_in_nof_words
u_18_2_8_5_len_10_gap_0 : ENTITY work.tb_dp_repack_data GENERIC MAP (c_flow(I), c_flow(J), 18, 2, 8, 5, FALSE, FALSE, 1, 1, c_nof_repeat, 10, 0); -- g_pkt_len = integer multiple of g_in_nof_words
END GENERATE;
END GENERATE;
END tb;

powered by: WebSVN 2.1.0

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