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

Merge branch 'L2SDP-281' into 'master'

initial commit of dp_sync_insert_v2

Closes L2SDP-281

See merge request desp/hdl!84
parents 6e0b3a09 89e5b9c9
No related branches found
No related tags found
2 merge requests!100Removed text for XSub that is now written in Confluence Subband correlator...,!84initial commit of dp_sync_insert_v2
......@@ -133,6 +133,7 @@ synth_files =
src/vhdl/dp_offload_tx_legacy.vhd
src/vhdl/dp_offload_tx_len_calc.vhd
src/vhdl/dp_sync_insert.vhd
src/vhdl/dp_sync_insert_v2.vhd
src/vhdl/dp_field_blk.vhd
src/vhdl/dp_concat_field_blk.vhd
......@@ -253,6 +254,7 @@ test_bench_files =
tb/vhdl/tb_mms_dp_xonoff.vhd
tb/vhdl/tb_dp_xonoff_reg_timeout.vhd
tb/vhdl/tb_dp_sync_insert.vhd
tb/vhdl/tb_dp_sync_insert_v2.vhd
tb/vhdl/tb_dp_folder.vhd
tb/vhdl/tb_dp_switch.vhd
tb/vhdl/tb_dp_counter_func.vhd
......@@ -304,6 +306,7 @@ test_bench_files =
tb/vhdl/tb_tb_dp_split.vhd
tb/vhdl/tb_tb_dp_sync_checker.vhd
tb/vhdl/tb_tb_dp_sync_insert.vhd
tb/vhdl/tb_tb_dp_sync_insert_v2.vhd
tb/vhdl/tb_tb_mms_dp_force_data_parallel_arr.vhd
tb/vhdl/tb_tb_mms_dp_force_data_serial_arr.vhd
tb/vhdl/tb_tb_mms_dp_gain_arr.vhd
......@@ -365,6 +368,7 @@ regression_test_vhdl =
tb/vhdl/tb_tb_dp_sync_checker.vhd
tb/vhdl/tb_mms_dp_sync_checker.vhd
tb/vhdl/tb_tb_dp_sync_insert.vhd
tb/vhdl/tb_tb_dp_sync_insert_v2.vhd
tb/vhdl/tb_dp_counter_func.vhd
tb/vhdl/tb_tb_dp_counter.vhd
tb/vhdl/tb_tb_mms_dp_force_data_parallel_arr.vhd
......
-------------------------------------------------------------------------------
--
-- Copyright 2021
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Author : R vd Walle
-- Purpose : * Insert extra sync pulses.
-- Description:
-- Every nof_blk_per_sync block a sync pulse is created at the output. The block
-- counter resets if a sync arrives at the input or when nof_blk_per_sync is reached.
-- nof_blk_per_sync is controllable using M&C.
--
-- Remarks:
-- . There is no support for back pressure.
-- . It does not compensate for missing data or extra data. There is NO reset function. It assumes that the
-- incoming data is perfectly aligned. Use a dp_sync_checker to assure the incoming data is perfect.
-------------------------------------------------------------------------------
LIBRARY IEEE, common_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;
ENTITY dp_sync_insert_v2 IS
GENERIC (
g_nof_streams : NATURAL := 1;
g_nof_blk_per_sync : NATURAL := 200000;
g_nof_blk_per_sync_min : NATURAL := 19530
);
PORT (
-- Clocks and reset
mm_rst : IN STD_LOGIC;
mm_clk : IN STD_LOGIC;
dp_rst : IN STD_LOGIC;
dp_clk : IN STD_LOGIC;
-- MM bus access in memory-mapped clock domain
reg_mosi : IN t_mem_mosi := c_mem_mosi_rst;
reg_miso : OUT t_mem_miso := c_mem_miso_rst;
-- Streaming sink
in_sosi_arr : IN t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
-- Streaming source
out_sosi_arr: OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0)
);
END dp_sync_insert_v2;
ARCHITECTURE rtl OF dp_sync_insert_v2 IS
TYPE t_reg IS RECORD -- local registers
blk_cnt : NATURAL RANGE 0 TO g_nof_blk_per_sync;
nof_blk_per_sync : NATURAL RANGE 0 TO g_nof_blk_per_sync;
out_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
END RECORD;
CONSTANT c_reg_rst : t_reg := ( 0, 0, (OTHERS => c_dp_sosi_rst));
CONSTANT c_mm_reg_w : NATURAL := ceil_log2(g_nof_blk_per_sync+1);
CONSTANT c_nof_blk_per_sync_mm_reg : t_c_mem := (1, 1, c_mm_reg_w, 1, 'X');
CONSTANT c_init_reg : STD_LOGIC_VECTOR(c_mem_reg_init_w-1 DOWNTO 0) := TO_UVEC(g_nof_blk_per_sync, c_mem_reg_init_w);
-- Define the local registers in t_reg record
SIGNAL r : t_reg;
SIGNAL nxt_r : t_reg;
SIGNAL reg_nof_blk_per_sync : STD_LOGIC_VECTOR(c_mm_reg_w -1 DOWNTO 0);
BEGIN
out_sosi_arr <= r.out_sosi_arr;
p_clk : PROCESS(dp_rst, dp_clk)
BEGIN
IF dp_rst='1' THEN
r <= c_reg_rst;
ELSIF rising_edge(dp_clk) THEN
r <= nxt_r;
END IF;
END PROCESS;
p_comb : PROCESS(r, in_sosi_arr, reg_nof_blk_per_sync)
VARIABLE v : t_reg;
BEGIN
v := r;
v.out_sosi_arr := in_sosi_arr;
v.nof_blk_per_sync := TO_UINT(reg_nof_blk_per_sync);
IF TO_UINT(reg_nof_blk_per_sync) < g_nof_blk_per_sync_min THEN
v.nof_blk_per_sync := g_nof_blk_per_sync_min;
END IF;
IF in_sosi_arr(0).sop = '1' THEN
v.blk_cnt := r.blk_cnt + 1;
IF r.blk_cnt = r.nof_blk_per_sync-1 OR in_sosi_arr(0).sync = '1' THEN
v.blk_cnt := 0;
FOR I IN 0 TO g_nof_streams-1 LOOP
v.out_sosi_arr(I).sync := '1';
END LOOP;
END IF;
END IF;
nxt_r <= v;
END PROCESS;
u_common_reg_r_w_dc : ENTITY common_lib.common_reg_r_w_dc
GENERIC MAP (
g_cross_clock_domain => TRUE,
g_readback => FALSE,
g_reg => c_nof_blk_per_sync_mm_reg,
g_init_reg => c_init_reg
)
PORT MAP (
-- Clocks and reset
mm_rst => mm_rst,
mm_clk => mm_clk,
st_rst => dp_rst,
st_clk => dp_clk,
-- Memory Mapped Slave in mm_clk domain
sla_in => reg_mosi,
sla_out => reg_miso,
-- MM registers in st_clk domain
reg_wr_arr => OPEN,
reg_rd_arr => OPEN,
in_reg => reg_nof_blk_per_sync,
out_reg => reg_nof_blk_per_sync
);
END rtl;
-------------------------------------------------------------------------------
--
-- Copyright 2021
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Author : R vd Walle
-- Purpose: Verify dp_sync_insert_v2
-- Description: The tb verifies:
-- . data valid gaps between blocks
-- . data valid gaps within blocks
-- . output sop, eop, valid, bsn equal to input
-- . expected output sync consisting of input syncs and inserted syncs
-- Usage:
-- > as 8
-- > run -all
--
-- * The tb is self stopping because tb_end will stop the simulation by
-- stopping the clk and thus all toggling.
-------------------------------------------------------------------------------
LIBRARY IEEE, common_lib, dp_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 common_lib.common_lfsr_sequences_pkg.ALL;
USE common_lib.tb_common_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
USE dp_lib.tb_dp_pkg.ALL;
ENTITY tb_dp_sync_insert_v2 IS
GENERIC (
g_nof_streams : NATURAL := 2;
g_block_size_input : NATURAL := 16;
g_nof_blk_per_sync_input : NATURAL := 32;
g_gap_size_during_block : NATURAL := 0;
g_gap_size_between_block : NATURAL := 0;
g_nof_blk_per_sync : NATURAL := 8;
g_nof_blk_per_sync_min : NATURAL := 2;
g_nof_repeat : NATURAL := 14
);
END tb_dp_sync_insert_v2;
ARCHITECTURE tb OF tb_dp_sync_insert_v2 IS
CONSTANT c_dut_latency : NATURAL := 1;
CONSTANT c_nof_replicated_sync : NATURAL := g_nof_blk_per_sync_input/g_nof_blk_per_sync;
CONSTANT c_dp_clk_period : TIME := 5 ns;
CONSTANT c_mm_clk_period : TIME := 8 ns;
SIGNAL tb_end : STD_LOGIC := '0';
SIGNAL mm_clk : STD_LOGIC := '1';
SIGNAL dp_clk : STD_LOGIC := '1';
SIGNAL rst : STD_LOGIC := '1';
-- DUT
SIGNAL ref_sosi : t_dp_sosi := c_dp_sosi_rst;
SIGNAL ref_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
SIGNAL out_sosi : t_dp_sosi;
SIGNAL out_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL reg_mosi : t_mem_mosi := c_mem_mosi_rst;
SIGNAL reg_miso : t_mem_miso := c_mem_miso_rst;
-- Verification
SIGNAL dly_valid_arr : STD_LOGIC_VECTOR(0 TO c_dut_latency) := (OTHERS=>'0');
SIGNAL dly_ref_sosi_arr : t_dp_sosi_arr(0 TO c_dut_latency) := (OTHERS => c_dp_sosi_rst);
SIGNAL exp_sync : STD_LOGIC := '0';
SIGNAL out_hold_sop : STD_LOGIC := '0';
SIGNAL exp_size : NATURAL := g_block_size_input;
SIGNAL cnt_size_arr : t_natural_arr(0 TO g_nof_streams-1);
BEGIN
dp_clk <= (NOT dp_clk) OR tb_end AFTER c_dp_clk_period/2;
mm_clk <= (NOT mm_clk) OR tb_end AFTER c_mm_clk_period/2;
rst <= '1', '0' AFTER c_dp_clk_period*7;
------------------------------------------------------------------------------
-- STIMULI
------------------------------------------------------------------------------
p_stimuli : PROCESS
BEGIN
proc_common_wait_until_low(dp_clk, rst);
proc_common_wait_some_cycles(dp_clk, 5);
FOR I IN 0 TO g_nof_repeat-1 LOOP
-- Generate first block with sync
ref_sosi.sync <= '1';
ref_sosi.sop <= '1';
ref_sosi.valid <= '1';
ref_sosi.bsn <= TO_DP_BSN(23+I);
proc_common_wait_some_cycles(dp_clk, 1);
ref_sosi.sync <= '0';
ref_sosi.sop <= '0';
-- Optionally apply valid='0' during block of data
ref_sosi.valid <= '0';
proc_common_wait_some_cycles(dp_clk, g_gap_size_during_block);
ref_sosi.valid <= '1';
proc_common_wait_some_cycles(dp_clk, g_block_size_input-2);
ref_sosi.eop <= '1';
proc_common_wait_some_cycles(dp_clk, 1);
ref_sosi.eop <= '0';
ref_sosi.valid <= '0';
-- Optionally apply valid='0' between block of data
proc_common_wait_some_cycles(dp_clk, g_gap_size_between_block);
-- Generate next blocks after sync
FOR I IN 0 TO g_nof_blk_per_sync_input-2 LOOP
ref_sosi.sop <= '1';
ref_sosi.valid <= '1';
proc_common_wait_some_cycles(dp_clk, 1);
ref_sosi.sync <= '0';
ref_sosi.sop <= '0';
-- Optionally apply valid='0' during block of data
ref_sosi.valid <= '0';
proc_common_wait_some_cycles(dp_clk, g_gap_size_during_block);
ref_sosi.valid <= '1';
proc_common_wait_some_cycles(dp_clk, g_block_size_input-2);
ref_sosi.eop <= '1';
proc_common_wait_some_cycles(dp_clk, 1);
ref_sosi.eop <= '0';
ref_sosi.valid <= '0';
-- Optionally apply valid='0' between block of data
proc_common_wait_some_cycles(dp_clk, g_gap_size_between_block);
END LOOP;
END LOOP;
-- End of stimuli
proc_common_wait_some_cycles(dp_clk, 100);
tb_end <= '1';
WAIT;
END PROCESS;
ref_sosi.data <= INCR_UVEC(ref_sosi.data, 1) WHEN rising_edge(dp_clk);
ref_sosi.re <= INCR_UVEC(ref_sosi.re, 2) WHEN rising_edge(dp_clk);
ref_sosi.im <= INCR_UVEC(ref_sosi.im, 3) WHEN rising_edge(dp_clk);
gen_streams : FOR I IN 0 TO g_nof_streams-1 GENERATE
ref_sosi_arr(I) <= ref_sosi;
END GENERATE;
------------------------------------------------------------------------------
-- DUT
------------------------------------------------------------------------------
u_dut: ENTITY work.dp_sync_insert_v2
GENERIC MAP (
g_nof_streams => g_nof_streams,
g_nof_blk_per_sync => g_nof_blk_per_sync,
g_nof_blk_per_sync_min => g_nof_blk_per_sync_min
)
PORT MAP (
mm_rst => rst,
mm_clk => mm_clk,
dp_rst => rst,
dp_clk => dp_clk,
reg_mosi => reg_mosi,
reg_miso => reg_miso,
-- Streaming sink
in_sosi_arr => ref_sosi_arr,
-- Streaming source
out_sosi_arr => out_sosi_arr
);
------------------------------------------------------------------------------
-- Verification
-- . use some DUT specific verification
-- . use some general Verification means from tb_dp_pkg.vhd, dp_stream_verify.vhd
------------------------------------------------------------------------------
dly_ref_sosi_arr(0) <= ref_sosi;
dly_ref_sosi_arr(1 TO c_dut_latency) <= dly_ref_sosi_arr(0 TO c_dut_latency-1) WHEN rising_edge(dp_clk);
p_exp_sync : PROCESS(dp_clk)
VARIABLE blk_cnt : NATURAL := 0;
BEGIN
IF rising_edge(dp_clk) THEN
exp_sync <= '0';
IF dly_ref_sosi_arr(c_dut_latency-1).sop = '1' THEN
IF dly_ref_sosi_arr(c_dut_latency-1).sync = '1' OR blk_cnt >= g_nof_blk_per_sync-1 THEN
blk_cnt := 0;
exp_sync <= '1';
ELSE
blk_cnt := blk_cnt+1;
END IF;
END IF;
END IF;
END PROCESS;
p_verify_out_sosi : PROCESS(dp_clk)
BEGIN
IF rising_edge(dp_clk) THEN
FOR I IN 0 TO g_nof_streams-1 LOOP
ASSERT out_sosi_arr(I).valid = dly_ref_sosi_arr(c_dut_latency).valid REPORT "Wrong out_sosi.valid" SEVERITY ERROR;
ASSERT out_sosi_arr(I).sop = dly_ref_sosi_arr(c_dut_latency).sop REPORT "Wrong out_sosi.sop" SEVERITY ERROR;
ASSERT out_sosi_arr(I).eop = dly_ref_sosi_arr(c_dut_latency).eop REPORT "Wrong out_sosi.eop" SEVERITY ERROR;
ASSERT out_sosi_arr(I).bsn = dly_ref_sosi_arr(c_dut_latency).bsn REPORT "Wrong out_sosi.bsn" SEVERITY ERROR;
ASSERT out_sosi_arr(I).sync = exp_sync REPORT "Wrong out_sosi.sync" SEVERITY ERROR;
END LOOP;
END IF;
END PROCESS;
-- Verify output packet ctrl
gen_verify_ctrl : FOR I IN 0 TO g_nof_streams-1 GENERATE
proc_dp_verify_sop_and_eop(dp_clk, out_sosi_arr(I).valid, out_sosi_arr(I).sop, out_sosi_arr(I).eop, out_hold_sop);
-- Verify output packet block size
proc_dp_verify_block_size(exp_size, dp_clk, out_sosi_arr(I).valid, out_sosi_arr(I).sop, out_sosi_arr(I).eop, cnt_size_arr(I));
END GENERATE;
END tb;
-------------------------------------------------------------------------------
--
-- Copyright 2021
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Author : R vd Walle
-- Purpose: Verify multiple variations of tb_dp_sync_insert_v2
-- Description:
-- Usage:
-- > as 3
-- > run -all
-------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
ENTITY tb_tb_dp_sync_insert_v2 IS
END tb_tb_dp_sync_insert_v2;
ARCHITECTURE tb OF tb_tb_dp_sync_insert_v2 IS
SIGNAL tb_end : STD_LOGIC := '0'; -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end'
BEGIN
-- g_nof_streams : NATURAL := 2;
-- g_block_size_input : NATURAL := 16;
-- g_nof_blk_per_sync_input : NATURAL := 32;
-- g_gap_size_during_block : NATURAL := 0;
-- g_gap_size_between_block : NATURAL := 0;
-- g_nof_blk_per_sync : NATURAL := 8;
-- g_nof_blk_per_sync_min : NATURAL := 2;
-- g_nof_repeat : NATURAL := 14
u_no_gaps : ENTITY work.tb_dp_sync_insert_v2 GENERIC MAP(2, 16, 32, 0, 0, 8, 2, 14);
u_gap : ENTITY work.tb_dp_sync_insert_v2 GENERIC MAP(2, 16, 32, 1, 3, 8, 2, 14);
u_large_blk_per_sync : ENTITY work.tb_dp_sync_insert_v2 GENERIC MAP(2, 16, 32, 0, 0, 999, 2, 14);
u_fract_blk_per_sync : ENTITY work.tb_dp_sync_insert_v2 GENERIC MAP(2, 16, 32, 0, 0, 7, 2, 14);
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