Skip to content
Snippets Groups Projects
Commit ba11989d authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Verify dynamic reorder control. Verify g_inter_valid_gap.

parent d01b85f3
No related branches found
No related tags found
1 merge request!339Resolve L2SDP-959
Pipeline #55818 passed
......@@ -21,13 +21,25 @@
-------------------------------------------------------------------------------
-- Author : E. Kooistra
-- Purpose:
-- Verify reorder_col_select using two instances and selects all inputdata.
-- Verify reorder_col_select using two instances and select all input data,
-- so that second instance can restore the original input data order.
-- Description:
-- The second reorder_col_select instances undo's the reordering of the
-- first reorder_col_select instance. All data in the input block is used,
-- so that the output of the second reorder_col_select instance is equal
-- to the tb input data, except for a delay, so that the output data can
-- easily be verified.
-- to the tb input data, except for a delay and data valid gaps.
-- The data and info fields are incrementing, so that the out_sosi can be
-- verified with dp_stream_verify.
--
-- p_comb_transpose p_comb_undo_transpose
-- | |
-- ____v_____ ____v_____
-- |reorder | |reorder |
-- p_st_stimuli -->|col_select|------->|col_select|--> p_verify
-- |__________| |__________|
-- in_sosi transposed_sosi out_sosi
-- nof_ch_input nof_ch_transposed nof_ch_output
--
-- Remark:
-- * Development order from basic functionality to all verifying features:
-- . verify reorder 1 packet
......@@ -38,12 +50,16 @@
-- designs.
-- . verify reorder multiple packets with and without interpacket gaps
-- . verify g_use_complex
-- . verify all sosi fields using proc_dp_verify_sosi_equal()
-- . verify all sosi fields using dp_stream_verify. Cannot use delayed
-- in_sosi and proc_dp_verify_sosi_equal(), because the out_sosi does
-- not have data valid gaps within a packet.
-- . add tb_tb_reorder_col_select_all
-- . verify dynamic change of nof_blocks_per_packet, nof_data_per_block
-- . verify dynamic change of nof_blocks_per_packet, nof_data_per_block.
-- . only support changing the nof_ch_in and nof_ch_sel when the no
-- reordering is busy.
--
-- Usage:
-- > as 10
-- > as 8
-- > run -all
-- * The tb is self stopping and self checking, tb_end will stop the simulation
-- by stopping the clk and thus all toggling.
......@@ -61,12 +77,14 @@ use work.reorder_pkg.all;
entity tb_reorder_col_select_all is
generic(
g_dsp_data_w : natural := 16; -- complex data width, = c_data_w / 2
g_nof_sync : natural := 1;
g_nof_sync : natural := 5;
g_nof_packets_per_sync : natural := 3;
g_nof_blocks_per_packet : natural := 5;
g_nof_data_per_block : natural := 3;
g_inter_packet_gap : natural := 0;
g_use_complex : boolean := false
g_inter_valid_gap : natural := 0; -- nof clk gap in in_sosi.valid
g_inter_packet_gap : natural := 3; -- nof clk gap betweek in_sosi.eop and next in_sosi.sop
g_use_complex : boolean := false;
g_use_dynamic_selection : boolean := false
);
end tb_reorder_col_select_all;
......@@ -76,33 +94,53 @@ architecture tb of tb_reorder_col_select_all is
constant c_clk_period : time := 10 ns;
constant c_rl : natural := 1;
constant c_use_data : boolean := not g_use_complex;
constant c_data_w : natural := c_nof_complex * g_dsp_data_w;
constant c_nof_ch : natural := g_nof_blocks_per_packet * g_nof_data_per_block;
constant c_use_data : boolean := not g_use_complex;
constant c_data_w : natural := c_nof_complex * g_dsp_data_w;
constant c_nof_blocks_max : natural:= largest(g_nof_blocks_per_packet, g_nof_data_per_block) + 1;
constant c_addr_max : natural := c_nof_ch + c_nof_blocks_max;
constant c_cnt_max : natural := c_nof_blocks_max;
-- Match c_nof_sync with p_nof_ch_stimuli
constant c_nof_sync : natural := sel_a_b(g_use_dynamic_selection, 2, g_nof_sync);
constant c_factor_blk : natural := sel_a_b(g_use_dynamic_selection, 2, 1); -- factor for more blocks per packet
constant c_factor_dat : natural := sel_a_b(g_use_dynamic_selection, 1, 1); -- factor for more data per block
constant c_factor_ch : natural := c_factor_blk * c_factor_dat; -- factor for more data per packet
constant c_nof_ch : natural := g_nof_blocks_per_packet * g_nof_data_per_block;
constant c_nof_ch_long : natural := c_nof_ch * c_factor_ch;
constant c_sel_gap : natural := c_nof_ch_long * 2;
-- Total output latency for transpose and undo transpose
constant c_retrieve_lat : natural := 2; -- rd latency of reorder_col_select
constant c_output_lat : natural := (c_nof_ch + c_retrieve_lat) * 2;
constant c_retrieve_lat : natural := 2; -- rd latency of reorder_col_select
constant c_output_lat : natural := (c_nof_ch + c_retrieve_lat) * 2;
constant c_output_lat_long : natural := (c_nof_ch_long + c_retrieve_lat) * 2;
signal rst : std_logic;
signal clk : std_logic := '1';
signal tb_end : std_logic := '0';
signal verify_en_sosi : t_dp_sosi_sl;
signal verify_en_out_sosi : t_dp_sosi_sl;
signal verify_en_out_sosi_long : t_dp_sosi_sl;
-- Data
signal in_en : std_logic := '1';
signal in_sosi : t_dp_sosi := c_dp_sosi_rst;
signal in_siso : t_dp_siso := c_dp_siso_rdy; -- used for proc_dp_gen_block_data
signal transposed_sosi : t_dp_sosi;
signal out_sosi : t_dp_sosi;
signal in_sosi_dly : t_dp_sosi := c_dp_sosi_rst;
signal expected_sosi : t_dp_sosi := c_dp_sosi_rst;
-- Reorder and undo reorder control
signal nof_ch : natural range 0 to c_nof_ch := c_nof_ch;
-- Reorder control for transpose and undo transpose
signal sel_long : boolean := false;
signal reorder_busy_transposed : std_logic;
signal reorder_busy_output : std_logic;
signal reorder_busy : std_logic;
signal nof_ch_input : natural := c_nof_ch;
signal nof_ch_transposed : natural;
signal nof_ch_output : natural;
signal nof_blocks_per_packet_input : natural := g_nof_blocks_per_packet;
signal nof_blocks_per_packet_transposed : natural;
signal nof_blocks_per_packet_output : natural;
signal nof_data_per_block_input : natural := g_nof_data_per_block;
signal nof_data_per_block_transposed : natural;
signal nof_data_per_block_output : natural;
signal select_cipo : t_mem_cipo;
signal undo_select_cipo : t_mem_cipo;
signal r_transpose : t_reorder_transpose;
......@@ -115,11 +153,20 @@ begin
clk <= (not clk) or tb_end after c_clk_period / 2;
rst <= '1', '0' after c_clk_period * 7;
-- Pulse in_en to control in_sosi.valid
proc_common_gen_pulse(1, 1 + g_inter_valid_gap, '1', rst, clk, in_en);
-- Dynamic reorder control
nof_ch_input <= sel_a_b(sel_long, c_nof_ch_long, c_nof_ch);
-- Input data packets stimuli
p_st_stimuli : process
variable v_bsn : std_logic_vector(31 downto 0) := (others => '0');
variable v_data : natural := 0;
variable v_nof_ch : natural := c_nof_ch;
variable v_bsn : std_logic_vector(31 downto 0) := (others => '0');
variable v_info : natural := 0;
variable v_data : natural := 0;
begin
sel_long <= false;
proc_common_wait_until_low(clk, rst);
proc_common_wait_some_cycles(clk, 5);
......@@ -141,8 +188,9 @@ begin
-- signal in_en : in std_logic; -- when '0' then no valid output even when src_in is ready
-- signal src_in : in t_dp_siso;
-- signal src_out : out t_dp_sosi);
for I in 0 to g_nof_sync - 1 loop
for I in 0 to c_nof_sync - 1 loop
-- First packet in sync interval
v_nof_ch := nof_ch_input;
proc_dp_gen_block_data(c_rl,
c_use_data,
g_dsp_data_w,
......@@ -150,9 +198,9 @@ begin
v_data, -- data
v_data, -- re
v_data + 1, -- im
c_nof_ch,
v_data + 2, -- channel
v_data + 3, -- error
v_nof_ch,
v_info + 2, -- channel
v_info + 3, -- error
'1', -- with sync
v_bsn, -- bsn
clk,
......@@ -162,8 +210,10 @@ begin
proc_common_wait_some_cycles(clk, g_inter_packet_gap);
for J in 0 to g_nof_packets_per_sync - 2 loop
-- Next packets in sync interval
v_nof_ch := nof_ch_input;
v_bsn := INCR_UVEC(v_bsn, 1);
v_data := v_data + c_nof_ch;
v_info := v_info + 1;
v_data := v_data + v_nof_ch;
proc_dp_gen_block_data(c_rl,
c_use_data,
g_dsp_data_w,
......@@ -171,9 +221,9 @@ begin
v_data, -- data
v_data, -- re
v_data + 1, -- im
c_nof_ch,
v_data + 2, -- channel
v_data + 3, -- error
v_nof_ch,
v_info + 2, -- channel
v_info + 3, -- error
'0', -- no sync
v_bsn, -- bsn
clk,
......@@ -182,9 +232,19 @@ begin
in_sosi);
proc_common_wait_some_cycles(clk, g_inter_packet_gap);
end loop;
v_bsn := INCR_UVEC(v_bsn, 1);
v_info := v_info + 1;
v_data := v_data + v_nof_ch;
if g_use_dynamic_selection then
-- Toggle dynamic reorder control
proc_common_wait_until_low(clk, reorder_busy);
sel_long <= not sel_long;
proc_common_wait_some_cycles(clk, 1);
end if;
end loop;
in_sosi <= c_dp_sosi_rst;
proc_common_wait_some_cycles(clk, c_nof_ch * 2);
proc_common_wait_some_cycles(clk, c_nof_ch_long * 2);
proc_common_wait_some_cycles(clk, 10);
tb_end <= '1';
wait;
......@@ -194,31 +254,104 @@ begin
-- Verification
------------------------------------------------------------------------------
in_sosi_dly <= transport in_sosi after c_output_lat * c_clk_period;
expected_sosi <= in_sosi_dly when rising_edge(clk);
p_verify : process(rst, clk)
p_verify_en_sosi : process
begin
if rst = '1' then
elsif rising_edge(clk) then
proc_dp_verify_sosi_equal(g_use_complex, out_sosi, expected_sosi);
verify_en_sosi <= c_dp_sosi_sl_rst;
proc_common_wait_until_low(clk, rst);
-- Verify all sosi fields, except for some
verify_en_sosi <= c_dp_sosi_sl_ones;
if g_use_complex then
verify_en_sosi.data <= '0';
else
verify_en_sosi.re <= '0';
verify_en_sosi.im <= '0';
end if;
verify_en_sosi.empty <= '0';
wait;
end process;
verify_en_out_sosi <= verify_en_sosi when sel_long = false else c_dp_sosi_sl_rst;
verify_en_out_sosi_long <= verify_en_sosi when sel_long = true else c_dp_sosi_sl_rst;
u_verify_out_sosi : entity dp_lib.dp_stream_verify
generic map (
-- initializations
g_sync_period => g_nof_packets_per_sync, -- BSN increment per sync interval
g_sync_offset => 0, -- first BSN
-- specific
g_in_dat_w => c_data_w,
g_pkt_len => c_nof_ch
)
port map (
rst => rst,
clk => clk,
-- Verify data
snk_in => out_sosi,
-- During stimuli
verify_snk_in_enable => verify_en_out_sosi,
-- End of stimuli
expected_snk_in => c_dp_sosi_rst,
verify_expected_snk_in_evt => c_dp_sosi_sl_rst
);
-- When g_use_dynamic_selection = true then c_nof_sync = 2 and second sync interval
-- will contain the long packets. All sync intervals have g_nof_packets_per_sync.
-- The first sync interval will start with BSN = g_sync_offset = 0, so the second
-- sync interval with the long packets, will start with BSN = g_sync_offset =
-- g_nof_packets_per_sync.
u_verify_out_sosi_long : entity dp_lib.dp_stream_verify
generic map (
-- initializations
g_sync_period => g_nof_packets_per_sync,
g_sync_offset => g_nof_packets_per_sync,
-- specific
g_in_dat_w => c_data_w,
g_pkt_len => c_nof_ch_long
)
port map (
rst => rst,
clk => clk,
-- Verify data
snk_in => out_sosi,
-- During stimuli
verify_snk_in_enable => verify_en_out_sosi_long,
-- End of stimuli
expected_snk_in => c_dp_sosi_rst,
verify_expected_snk_in_evt => c_dp_sosi_sl_rst
);
------------------------------------------------------------------------------
-- DUT
------------------------------------------------------------------------------
r_transpose <= d_transpose when rising_edge(clk);
r_undo_transpose <= d_undo_transpose when rising_edge(clk);
p_clk : process(rst, clk)
begin
if rst = '1' then
r_transpose <= c_reorder_transpose_rst;
r_undo_transpose <= c_reorder_transpose_rst;
elsif rising_edge(clk) then
r_transpose <= d_transpose;
r_undo_transpose <= d_undo_transpose;
end if;
end process;
-- The p_comb_transpose and p_comb_undo_transpose can both use
-- func_reorder_transpose(), by swapping the transpose dimensions.
nof_blocks_per_packet_input <= g_nof_blocks_per_packet when nof_ch_input = c_nof_ch else
g_nof_blocks_per_packet * c_factor_blk;
nof_data_per_block_input <= g_nof_data_per_block when nof_ch_input = c_nof_ch else
g_nof_data_per_block * c_factor_dat;
p_comb_transpose : process(rst, r_transpose, select_cipo)
variable v : t_reorder_transpose;
begin
if select_cipo.waitrequest = '0' then
-- Read from reorder_col_select page
v := func_reorder_transpose(g_nof_data_per_block, g_nof_blocks_per_packet, r_transpose);
v := func_reorder_transpose(nof_data_per_block_input, nof_blocks_per_packet_input, r_transpose);
else
-- No read, new reorder_col_select page not available yet
v := c_reorder_transpose_rst;
......@@ -230,12 +363,17 @@ begin
d_transpose <= v;
end process;
nof_blocks_per_packet_transposed <= g_nof_blocks_per_packet when nof_ch_transposed = c_nof_ch else
g_nof_blocks_per_packet * c_factor_blk;
nof_data_per_block_transposed <= g_nof_data_per_block when nof_ch_transposed = c_nof_ch else
g_nof_data_per_block * c_factor_dat;
p_comb_undo_transpose : process(rst, r_undo_transpose, undo_select_cipo)
variable v : t_reorder_transpose;
begin
if undo_select_cipo.waitrequest = '0' then
-- Read from reorder_col_select page
v := func_reorder_transpose(g_nof_blocks_per_packet, g_nof_data_per_block, r_undo_transpose);
v := func_reorder_transpose(nof_blocks_per_packet_transposed, nof_data_per_block_transposed, r_undo_transpose);
else
-- No read, new reorder_col_select page not available yet
v := c_reorder_transpose_rst;
......@@ -247,20 +385,31 @@ begin
d_undo_transpose <= v;
end process;
nof_blocks_per_packet_output <= g_nof_blocks_per_packet when nof_ch_output = c_nof_ch else
g_nof_blocks_per_packet * c_factor_blk;
nof_data_per_block_output <= g_nof_data_per_block when nof_ch_output = c_nof_ch else
g_nof_data_per_block * c_factor_dat;
u_transpose : entity work.reorder_col_select
generic map (
g_dsp_data_w => g_dsp_data_w,
g_nof_ch_in => c_nof_ch,
g_nof_ch_sel => c_nof_ch,
g_nof_ch_in => c_nof_ch_long,
g_nof_ch_sel => c_nof_ch_long,
g_use_complex => g_use_complex
)
port map (
dp_rst => rst,
dp_clk => clk,
reorder_busy => reorder_busy_transposed,
-- Dynamic reorder block size control
nof_ch_in => nof_ch,
nof_ch_sel => nof_ch,
nof_ch_in => nof_ch_input,
nof_ch_sel => nof_ch_input,
-- Captured reorder block size control used for output_sosi
output_nof_ch_in => nof_ch_transposed,
output_nof_ch_sel => open,
-- Memory Mapped
col_select_mosi => r_transpose.select_copi,
......@@ -274,17 +423,23 @@ begin
u_undo_transpose : entity work.reorder_col_select
generic map (
g_dsp_data_w => g_dsp_data_w,
g_nof_ch_in => c_nof_ch,
g_nof_ch_sel => c_nof_ch,
g_nof_ch_in => c_nof_ch_long,
g_nof_ch_sel => c_nof_ch_long,
g_use_complex => g_use_complex
)
port map (
dp_rst => rst,
dp_clk => clk,
reorder_busy => reorder_busy_output,
-- Dynamic reorder block size control
nof_ch_in => nof_ch,
nof_ch_sel => nof_ch,
nof_ch_in => nof_ch_transposed,
nof_ch_sel => nof_ch_transposed,
-- Captured reorder block size control used for output_sosi
output_nof_ch_in => nof_ch_output,
output_nof_ch_sel => open,
-- Memory Mapped
col_select_mosi => r_undo_transpose.select_copi,
......@@ -295,4 +450,5 @@ begin
output_sosi => out_sosi
);
reorder_busy <= reorder_busy_transposed or reorder_busy_output;
end tb;
......@@ -38,17 +38,23 @@ architecture tb of tb_tb_reorder_col_select_all is
begin
-- g_dsp_data_w : natural := 16; -- complex data width, = c_data_w / 2
-- g_nof_sync : natural := 1;
-- g_nof_sync : natural := 2;
-- g_nof_packets_per_sync : natural := 3;
-- g_nof_blocks_per_packet : natural := 5;
-- g_nof_data_per_block : natural := 3;
-- g_inter_packet_gap : natural := 0;
-- g_use_complex : boolean := false
u_complex_5_3_no_gaps : entity work.tb_reorder_col_select_all generic map(16, 3, 2, 5, 3, 0, true);
u_data_5_3_no_gaps : entity work.tb_reorder_col_select_all generic map(16, 3, 3, 5, 3, 0, false);
u_data_5_1_no_gaps : entity work.tb_reorder_col_select_all generic map(16, 3, 4, 5, 1, 0, false);
u_data_1_3_no_gaps : entity work.tb_reorder_col_select_all generic map(16, 3, 5, 1, 3, 0, false);
u_data_3_5_gap_1 : entity work.tb_reorder_col_select_all generic map(16, 3, 6, 3, 5, 1, false);
-- g_inter_valid_gap : natural := 5; -- nof clk gap in in_sosi.valid
-- g_inter_packet_gap : natural := 0; -- nof clk gap between in_sosi.eop and next in_sosi.sop
-- g_use_complex : boolean := false;
-- g_use_dynamic_selection : boolean := true
u_complex_5_3_no_gaps : entity work.tb_reorder_col_select_all generic map(16, 3, 2, 5, 3, 0, 0, true, false);
u_data_5_3_no_gaps : entity work.tb_reorder_col_select_all generic map(16, 3, 3, 5, 3, 0, 0, false, false);
u_data_5_1_no_gaps : entity work.tb_reorder_col_select_all generic map(16, 3, 4, 5, 1, 0, 0, false, false);
u_data_1_3_no_gaps : entity work.tb_reorder_col_select_all generic map(16, 3, 5, 1, 3, 0, 0, false, false);
u_data_3_5_pkt_gap_1 : entity work.tb_reorder_col_select_all generic map(16, 3, 6, 3, 5, 0, 1, false, false);
u_data_3_5_valid_gap_1 : entity work.tb_reorder_col_select_all generic map(16, 3, 6, 3, 5, 1, 0, false, false);
u_dynamic_data_5_3_no_gaps : entity work.tb_reorder_col_select_all generic map(16, 3, 3, 5, 3, 0, 0, false, true);
u_dynamic_data_5_3_gaps : entity work.tb_reorder_col_select_all generic map(16, 3, 3, 5, 3,10,100, false, true);
end tb;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment