Skip to content
Snippets Groups Projects

Resolve L2SDP-962

Merged Eric Kooistra requested to merge L2SDP-962 into master
4 files
+ 517
24
Compare changes
  • Side-by-side
  • Inline
Files
4
@@ -19,13 +19,31 @@
--
--------------------------------------------------------------------------------
-- Purpose: Unmerge each input packet into g_nof_pkt output packets. Below is the
-- waveform when g_nof_pkt = 3. The numbers in snk_in.sop and snk_in.eop
-- match pkt_cnt.
-- Purpose: Unmerge each input packet into output packets of length g_pkt_len.
-- Description:
-- . The merged packet length of the snk_in input packets must be an integer
-- multiple of g_pkt_len. The number of output packets g_nof_pkt_max is only
-- used to determine the maximum supported pkt_cnt range. The actual number
-- of output packets has to be <= g_nof_pkt_max, and is determined by input
-- packet length / g_pkt_len. Hence the dp_packet_unmerge can dynamically
-- handle different sizes of input packets, provided that their length is an
-- integer multiple of g_pkt_len.
-- . The pkt_cnt is passed on as src_out.channel index.
-- . The g_bsn_increment sets the BSN increment for the unmerged output
-- packets relative to the BSN of the snk_in input packet. When
-- g_bsn_increment = 0, then all unmerged output packets get the same BSN as
-- the input packet.
-- . The input snk_in.err and snk_in.empty are valid at the snk_in.eop, but
-- that is too late to apply them to the unmerged packets. Therefor assume
-- that the snk_in.err and snk_in_eop are already valid at the snk_in.sop
-- and remain valid until the snk_in.eop. Hence these signals are then valid
-- when snk_in.valid = '1'. Use same snk_in.err and snk_in.empty value for
-- all unmerged packets.
--
-- _ _ _
-- snk_in.sop _____|0|___________________________|1|___________________________|2|_
-- snk_in.sop _____| |___________________________| |___________________________| |_
-- _ _
-- snk_in.sop _________________________________|0|___________________________|1|___
-- snk_in.eop _________________________________| |___________________________| |___
-- _ _ _ _ _ _ _
-- src_out.sop _____|0|_______|1|_______|2|_______|0|_______|1|_______|2|_______|0|_
-- _ _ _ _ _ _
@@ -39,8 +57,9 @@ use work.dp_stream_pkg.all;
entity dp_packet_unmerge is
generic (
g_nof_pkt : natural := 1; -- Nof packets to unmerge each incoming packet to
g_pkt_len : natural := 1 -- Length of the unmerged packets
g_nof_pkt_max : natural := 1; -- Maximum nof packets to unmerge each incoming packet to
g_pkt_len : natural := 1; -- Length of the unmerged packets
g_bsn_increment : natural := 0
);
port (
rst : in std_logic;
@@ -55,8 +74,106 @@ entity dp_packet_unmerge is
end dp_packet_unmerge;
architecture rtl of dp_packet_unmerge is
type t_reg is record
pkt_cnt : natural range 0 to g_nof_pkt_max + 1;
val_cnt : natural range 0 to g_pkt_len + 1;
src_out : t_dp_sosi;
end record;
constant c_reg_rst : t_reg := (0, 0, c_dp_sosi_rst);
signal r : t_reg;
signal d : t_reg;
begin
-- Temporary void component that assigns output = input
-- Map t_reg outputs to entity outputs
snk_out <= src_in;
src_out <= snk_in;
src_out <= r.src_out;
-- p_reg
r <= d when rising_edge(clk);
p_comb : process(rst, r, snk_in)
variable v : t_reg;
begin
-- Default
v := r;
-- Function
-- _ _ _
-- snk_in.sop __| |_______________| |_______________| |_______________|
-- _ _ _
-- snk_in.eop _________________| |_______________| |_______________| |_
-- _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
-- snk_in.valid __|
-- v.val_cnt 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
-- v.pkt_cnt 0 1 2 0 1 2 0 1 2
-- ______________ _______________ _______________ _
-- v.busy __| |_| |_| |_|
-- _ _ _ _ _ _ _ _ _
-- v.src_out.sop __|0|___|1|___|2|___|0|___|1|___|2|___|0|___|1|___|2|___|
-- _ _ _ _ _ _ _ _ _
-- v.src_out.eop _____|0|___|1|___|2|___|0|___|1|___|2|___|0|___|1|___|2|_
-- input valid counter
if snk_in.sop = '1' then
v.val_cnt := 0;
elsif snk_in.valid = '1' then
if r.val_cnt < g_pkt_len - 1 then
v.val_cnt := r.val_cnt + 1;
else
v.val_cnt := 0;
end if;
end if;
-- output packet counter
if snk_in.sop = '1' then
v.pkt_cnt := 0;
elsif snk_in.valid = '1' and v.val_cnt = 0 then
v.pkt_cnt := r.pkt_cnt + 1;
end if;
-- output packet bsn, sync, sop and eop
v.src_out := snk_in; -- passes on snk_in.sync, data, re, im
v.src_out.bsn := r.src_out.bsn;
v.src_out.channel := r.src_out.channel;
v.src_out.empty := r.src_out.empty;
v.src_out.err := r.src_out.err;
v.src_out.sop := '0';
v.src_out.eop := '0';
-- . output sop, eop
if snk_in.valid = '1' then
if v.val_cnt = 0 then
v.src_out.sop := '1';
end if;
if v.val_cnt = g_pkt_len - 1 then
v.src_out.eop := '1';
end if;
end if;
-- . output bsn
if snk_in.sop = '1' then
v.src_out.bsn := snk_in.bsn;
elsif v.src_out.sop = '1' then
v.src_out.bsn := incr_uvec(r.src_out.bsn, g_bsn_increment);
end if;
-- . output channel
v.src_out.channel := TO_DP_CHANNEL(v.pkt_cnt);
-- . output err, empty. assume they are valid during entire input packet,
-- so not only at the snk_in.eop
if snk_in.valid = '1' then
v.src_out.empty := snk_in.empty;
v.src_out.err := snk_in.err;
end if;
-- Synchronous reset
if rst = '1' then
v := c_reg_rst;
end if;
d <= v;
end process;
end rtl;
Loading