diff --git a/libraries/base/dp/hdllib.cfg b/libraries/base/dp/hdllib.cfg index 3cbdaf9fdf532bb80963d54c341e3fa372dbb062..3a75fed46cf35b5f228ddec98938bbc515bc9d3a 100644 --- a/libraries/base/dp/hdllib.cfg +++ b/libraries/base/dp/hdllib.cfg @@ -76,6 +76,7 @@ synth_files = src/vhdl/dp_bsn_source.vhd src/vhdl/dp_bsn_source_v2.vhd src/vhdl/dp_bsn_source_reg.vhd + src/vhdl/dp_bsn_source_reg_v2.vhd src/vhdl/mms_dp_bsn_source.vhd src/vhdl/mms_dp_bsn_source_v2.vhd src/vhdl/dp_bsn_scheduler.vhd diff --git a/libraries/base/dp/src/vhdl/dp_bsn_source_reg_v2.vhd b/libraries/base/dp/src/vhdl/dp_bsn_source_reg_v2.vhd new file mode 100644 index 0000000000000000000000000000000000000000..fed0ff23ae38c86639905c25d83da8144c8bf35c --- /dev/null +++ b/libraries/base/dp/src/vhdl/dp_bsn_source_reg_v2.vhd @@ -0,0 +1,285 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2012 +-- 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/>. +-- +------------------------------------------------------------------------------- + +-- RO read only (no VHDL present to access HW in write mode) +-- WO write only (no VHDL present to access HW in read mode) +-- WE write event (=WO) +-- WR write control, read control +-- RW read status, write control +-- RC read, clear on read +-- FR FIFO read +-- FW FIFO write +-- +-- wi Bits R/W Name Default Description +-- ==================================================================================== +-- 0 [0] RW dp_on 0x0 WR '1' enables DP (on PPS when dp_on_pps=1) +-- RD '0' = DP off; RD '1' = DP on. +-- [1] WR dp_on_pps 0x0 +-- 1 [31..0] WR nof_clk_per_sync 0x0 +-- 2 [31..0] RW bsn[31..0] 0x0 write init_bsn, read current bsn +-- 3 [31..0] RW bsn[63..32] 0x0 write init_bsn, read current bsn +-- ==================================================================================== + +LIBRARY IEEE, common_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; + +ENTITY dp_bsn_source_reg_v2 IS + GENERIC ( + g_cross_clock_domain : BOOLEAN := TRUE; -- use FALSE when mm_clk and st_clk are the same, else use TRUE to cross the clock domain + g_nof_clk_per_sync : NATURAL := 200 * 10**6 + ); + PORT ( + -- Clocks and reset + mm_rst : IN STD_LOGIC; -- reset synchronous with mm_clk + mm_clk : IN STD_LOGIC; -- memory-mapped bus clock + st_rst : IN STD_LOGIC; -- reset synchronous with st_clk + st_clk : IN STD_LOGIC; -- other clock domain clock + + -- Memory Mapped Slave in mm_clk domain + sla_in : IN t_mem_mosi; -- actual ranges defined by c_mm_reg + sla_out : OUT t_mem_miso; -- actual ranges defined by c_mm_reg + + -- MM registers in st_clk domain + st_on : OUT STD_LOGIC := '1'; -- level + st_on_pps : OUT STD_LOGIC := '0'; -- level + st_on_status : IN STD_LOGIC; + st_nof_clk_per_sync : OUT STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- nof block per sync + st_init_bsn : OUT STD_LOGIC_VECTOR; -- wr init BSN + st_current_bsn : IN STD_LOGIC_VECTOR -- rd current BSN + ); +END dp_bsn_source_reg_v2; + + +ARCHITECTURE rtl OF dp_bsn_source_reg_v2 IS + + CONSTANT c_bsn_w : NATURAL := st_init_bsn'LENGTH; + + -- Define the actual size of the MM slave register + CONSTANT c_mm_reg : t_c_mem := (latency => 1, + adr_w => 2, + dat_w => c_word_w, -- Use MM bus data width = c_word_w = 32 for all MM registers + nof_dat => 2**2, + init_sl => '0'); + + -- Registers in mm_clk domain + SIGNAL mm_on : STD_LOGIC; + SIGNAL mm_on_pps : STD_LOGIC; + SIGNAL mm_on_ctrl : STD_LOGIC_VECTOR(1 DOWNTO 0); -- = mm_on_pps & mm_on + SIGNAL st_on_ctrl : STD_LOGIC_VECTOR(1 DOWNTO 0); -- = st_on_pps & st_on + SIGNAL mm_on_status : STD_LOGIC; + + SIGNAL mm_nof_clk_per_sync : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); + + SIGNAL mm_init_bsn : STD_LOGIC_VECTOR(c_longword_w-1 DOWNTO 0); + SIGNAL mm_init_bsn_wr : STD_LOGIC; + SIGNAL mm_current_bsn : STD_LOGIC_VECTOR(c_longword_w-1 DOWNTO 0) := (OTHERS=>'0'); + SIGNAL mm_current_bsn_hi : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0) := (OTHERS=>'0'); + + -- Registers in st_clk domain + +BEGIN + + ------------------------------------------------------------------------------ + -- MM register access in the mm_clk domain + -- . Hardcode the shared MM slave register directly in RTL instead of using + -- the common_reg_r_w instance. Directly using RTL is easier when the large + -- MM register has multiple different fields and with different read and + -- write options per field in one MM register. + ------------------------------------------------------------------------------ + + p_mm_reg : PROCESS (mm_rst, mm_clk) + BEGIN + IF mm_rst = '1' THEN + -- Read access + sla_out <= c_mem_miso_rst; + -- Access event, register values + mm_on <= '0'; + mm_on_pps <= '0'; + mm_nof_clk_per_sync <= TO_UVEC(g_nof_clk_per_sync, c_word_w); + mm_init_bsn <= (OTHERS=>'0'); + mm_init_bsn_wr <= '0'; + mm_current_bsn_hi <= (OTHERS=>'0'); + ELSIF rising_edge(mm_clk) THEN + -- Read access defaults + sla_out.rdval <= '0'; + + -- Access event defaults + mm_init_bsn_wr <= '0'; + + -- Write access: set register value + IF sla_in.wr = '1' THEN + CASE TO_UINT(sla_in.address(c_mm_reg.adr_w-1 DOWNTO 0)) IS + -- Write Block Sync + WHEN 0 => + mm_on <= sla_in.wrdata(0); + mm_on_pps <= sla_in.wrdata(1); + WHEN 1 => + mm_nof_clk_per_sync <= sla_in.wrdata(31 DOWNTO 0); + + -- Write init BSN + WHEN 2 => + mm_init_bsn(31 DOWNTO 0) <= sla_in.wrdata(31 DOWNTO 0); + WHEN 3 => + mm_init_bsn(63 DOWNTO 32) <= sla_in.wrdata(31 DOWNTO 0); + mm_init_bsn_wr <= '1'; + + WHEN OTHERS => NULL; -- not used MM addresses + END CASE; + + -- Read access: get register value + ELSIF sla_in.rd = '1' THEN + sla_out <= c_mem_miso_rst; -- set unused rddata bits to '0' when read + sla_out.rdval <= '1'; -- c_mm_reg.latency = 1 + CASE TO_UINT(sla_in.address(c_mm_reg.adr_w-1 DOWNTO 0)) IS + -- Read Block Sync + WHEN 0 => + sla_out.rddata(0) <= mm_on_status; + sla_out.rddata(1) <= mm_on_pps; + WHEN 1 => + sla_out.rddata(31 DOWNTO 0) <= mm_nof_clk_per_sync; + + -- Read current BSN + WHEN 2 => + sla_out.rddata(31 DOWNTO 0) <= mm_current_bsn(31 DOWNTO 0); + mm_current_bsn_hi <= mm_current_bsn(63 DOWNTO 32); -- first read low part and preserve high part + WHEN 3 => + sla_out.rddata(31 DOWNTO 0) <= mm_current_bsn_hi; + + WHEN OTHERS => NULL; -- not used MM addresses + END CASE; + END IF; + END IF; + END PROCESS; + + ------------------------------------------------------------------------------ + -- Transfer register value between mm_clk and st_clk domain. + -- If the function of the register ensures that the value will not be used + -- immediately when it was set, then the transfer between the clock domains + -- can be done by wires only. Otherwise if the change in register value can + -- have an immediate effect then the bit or word value needs to be transfered + -- using: + -- + -- . common_async --> for single-bit level signal + -- . common_spulse --> for single-bit pulse signal + -- . common_reg_cross_domain --> for a multi-bit (a word) signal + -- + -- Typically always use a crossing component for the single bit signals (to + -- be on the save side) and only use a crossing component for the word + -- signals if it is necessary (to avoid using more logic than necessary). + ------------------------------------------------------------------------------ + + no_cross : IF g_cross_clock_domain = FALSE GENERATE -- so mm_clk = st_clk + st_on <= mm_on; + st_on_pps <= mm_on_pps; + st_nof_clk_per_sync <= mm_nof_clk_per_sync; + st_init_bsn <= mm_init_bsn(c_bsn_w-1 DOWNTO 0); + + p_st_clk : PROCESS(st_rst, st_clk) + BEGIN + IF st_rst='1' THEN + st_init_bsn <= TO_UVEC(0, c_bsn_w); + ELSIF rising_edge(st_clk) THEN + IF mm_init_bsn_wr='1' THEN + st_init_bsn <= mm_init_bsn(c_bsn_w-1 DOWNTO 0); -- use wr of mm_init_bsn high part for in_new to ensure proper transfer of double word + END IF; + END IF; + END PROCESS; + + mm_current_bsn(c_bsn_w-1 DOWNTO 0) <= st_current_bsn; -- MM user may read current_bsn twice to avoid small chance that the high part of the double word changed (i.e. incremented) + END GENERATE; -- no_cross + + gen_cross : IF g_cross_clock_domain = TRUE GENERATE + -- Block sync registers + u_dp_on_ctrl : ENTITY common_lib.common_reg_cross_domain + PORT MAP ( + in_rst => mm_rst, + in_clk => mm_clk, + in_dat => mm_on_ctrl, + in_done => OPEN, -- pulses when no more pending in_new + out_rst => st_rst, + out_clk => st_clk, + out_dat => st_on_ctrl, + out_new => OPEN + ); + + mm_on_ctrl(0) <= mm_on; + mm_on_ctrl(1) <= mm_on_pps; + + st_on <= st_on_ctrl(0); + st_on_pps <= st_on_ctrl(1); + + u_mm_on_status : ENTITY common_lib.common_async + GENERIC MAP ( + g_rst_level => '0' + ) + PORT MAP ( + rst => mm_rst, + clk => mm_clk, + din => st_on_status, + dout => mm_on_status + ); + + -- write occurs with sufficient margin before it is used, still use common_reg_cross_domain nonetheless + u_nof_block_per_sync : ENTITY common_lib.common_reg_cross_domain + PORT MAP ( + in_rst => mm_rst, + in_clk => mm_clk, + in_dat => mm_nof_clk_per_sync, + in_done => OPEN, -- pulses when no more pending in_new + out_rst => st_rst, + out_clk => st_clk, + out_dat => st_nof_clk_per_sync, + out_new => OPEN + ); + + -- write occurs with sufficient margin before it is used, still use common_reg_cross_domain nonetheless + u_init_bsn : ENTITY common_lib.common_reg_cross_domain + PORT MAP ( + in_rst => mm_rst, + in_clk => mm_clk, + in_new => mm_init_bsn_wr, -- use wr of mm_init_bsn high part for in_new to ensure proper transfer of double word + in_dat => mm_init_bsn(c_bsn_w-1 DOWNTO 0), + in_done => OPEN, -- pulses when no more pending in_new + out_rst => st_rst, + out_clk => st_clk, + out_dat => st_init_bsn, + out_new => OPEN + ); + + -- thanks to mm_current_bsn_hi the double word can be read reliably + u_current_bsn : ENTITY common_lib.common_reg_cross_domain + PORT MAP ( + in_rst => st_rst, + in_clk => st_clk, + in_new => '1', -- could use t_dp_sosi sop here to indicate in_new, but using default '1' is fine too + in_dat => st_current_bsn, + in_done => OPEN, -- pulses when no more pending in_new + out_rst => mm_rst, + out_clk => mm_clk, + out_dat => mm_current_bsn(c_bsn_w-1 DOWNTO 0), + out_new => OPEN + ); + + END GENERATE; -- gen_cross + +END rtl; diff --git a/libraries/base/dp/src/vhdl/dp_bsn_source_v2.vhd b/libraries/base/dp/src/vhdl/dp_bsn_source_v2.vhd index ebf97ff3beb2003d734d0971ab263091c5b39c5b..5108162f14d92ff6ff48eef7da576b77443e31ab 100644 --- a/libraries/base/dp/src/vhdl/dp_bsn_source_v2.vhd +++ b/libraries/base/dp/src/vhdl/dp_bsn_source_v2.vhd @@ -41,7 +41,7 @@ USE work.dp_stream_pkg.ALL; ENTITY dp_bsn_source_v2 IS GENERIC ( g_block_size : NATURAL := 256; - g_nof_block_per_sync : NATURAL := 8; + g_nof_clk_per_sync : NATURAL := 200 * 10**6; g_bsn_w : NATURAL := 48; g_offset_w : NATURAL := 4 ); @@ -56,7 +56,7 @@ ENTITY dp_bsn_source_v2 IS dp_on_status : OUT STD_LOGIC; init_bsn : IN STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0) := (OTHERS=>'0'); - nof_block_per_sync : IN STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0) := TO_UVEC(g_nof_block_per_sync, c_word_w); + nof_clk_per_sync : IN STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0) := TO_UVEC(g_nof_clk_per_sync, c_word_w); offset_bsn : IN STD_LOGIC_VECTOR(g_offset_w-1 DOWNTO 0) := (OTHERS=>'0'); --offset_bsn : IN STD_LOGIC_VECTOR(g_offset_w-1 DOWNTO 0) := TO_UVEC(4, g_offset_w); @@ -79,8 +79,8 @@ ARCHITECTURE rtl OF dp_bsn_source_v2 IS SIGNAL block_size_cnt : STD_LOGIC_VECTOR(c_block_size_cnt_w-1 DOWNTO 0); SIGNAL nxt_block_size_cnt : STD_LOGIC_VECTOR(c_block_size_cnt_w-1 DOWNTO 0); - SIGNAL block_cnt : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0); - SIGNAL nxt_block_cnt : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0); + --SIGNAL block_cnt : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0); + --SIGNAL nxt_block_cnt : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0); SIGNAL i_src_out : t_dp_sosi := c_dp_sosi_init; SIGNAL nxt_src_out : t_dp_sosi; @@ -89,14 +89,19 @@ ARCHITECTURE rtl OF dp_bsn_source_v2 IS SIGNAL i_dp_on_status : STD_LOGIC; SIGNAL nxt_offset_bsn_cnt : STD_LOGIC_VECTOR(g_offset_w-1 DOWNTO 0); - SIGNAL offset_bsn_cnt : STD_LOGIC_VECTOR(g_offset_w-1 DOWNTO 0); + SIGNAL offset_bsn_cnt : STD_LOGIC_VECTOR(g_offset_w-1 DOWNTO 0); + + SIGNAL nxt_clk_cnt : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); + SIGNAL clk_cnt : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); + SIGNAL nxt_sync : STD_LOGIC; + SIGNAL sync : STD_LOGIC; BEGIN src_out <= i_src_out; dp_on_status <= i_dp_on_status; - p_state : PROCESS(state, prev_state, dp_on, dp_on_pps, pps, block_size_cnt, block_cnt, nof_block_per_sync, init_bsn, i_src_out, i_dp_on_status, offset_bsn_cnt) + p_state : PROCESS(state, prev_state, dp_on, dp_on_pps, pps, block_size_cnt, clk_cnt, init_bsn, i_src_out, i_dp_on_status, offset_bsn_cnt) BEGIN nxt_state <= state; nxt_src_out <= i_src_out; @@ -105,8 +110,15 @@ BEGIN nxt_src_out.sop <= '0'; nxt_src_out.eop <= '0'; nxt_block_size_cnt <= block_size_cnt; - nxt_block_cnt <= block_cnt; + nxt_clk_cnt <= INCR_UVEC(clk_cnt, 1); + nxt_sync <= sync; nxt_dp_on_status <= i_dp_on_status; + nxt_offset_bsn_cnt <= offset_bsn_cnt; + + IF UNSIGNED(clk_cnt) = UNSIGNED(nof_clk_per_sync) - 1 THEN + nxt_clk_cnt <= (OTHERS=>'0'); + nxt_sync <= '1'; -- set sync signal on next sop + END IF; CASE state IS @@ -115,11 +127,6 @@ BEGIN nxt_src_out.valid <= '1'; nxt_state <= s_dp_on_sop; nxt_block_size_cnt <= INCR_UVEC(block_size_cnt, 1); - IF UNSIGNED(block_cnt) = UNSIGNED(nof_block_per_sync) -1 THEN - nxt_block_cnt <= (OTHERS=>'0'); - ELSE - nxt_block_cnt <= INCR_UVEC(block_cnt, 1); - END IF; IF dp_on = '0' THEN nxt_state <= s_dp_off; END IF; @@ -140,14 +147,16 @@ BEGIN IF prev_state = s_dp_on_eop THEN nxt_src_out.bsn(g_bsn_w-1 DOWNTO 0) <= INCR_UVEC(i_src_out.bsn(g_bsn_w-1 DOWNTO 0), 1); END IF; - IF UNSIGNED(block_cnt) = UNSIGNED(c_block_cnt_zero) THEN + IF sync = '1' THEN nxt_src_out.sync <= '1'; + nxt_sync <= '0'; -- clear sync if set END IF; WHEN s_dp_off => nxt_dp_on_status <= '0'; - nxt_block_cnt <= (OTHERS=>'0'); nxt_src_out.bsn <= RESIZE_DP_BSN(init_bsn); + nxt_sync <= '0'; -- clear sync if set + nxt_clk_cnt <= (OTHERS=>'0'); IF dp_on = '1' THEN IF dp_on_pps = '1' THEN IF pps = '1' THEN @@ -183,7 +192,9 @@ BEGIN prev_state <= s_init; state <= s_init; i_src_out <= c_dp_sosi_rst; - block_cnt <= (OTHERS=>'0'); + --block_cnt <= (OTHERS=>'0'); + clk_cnt <= (OTHERS=>'0'); + sync <= '0'; block_size_cnt <= (OTHERS=>'0'); i_dp_on_status <= '0'; offset_bsn_cnt <= (OTHERS=>'0'); @@ -191,7 +202,9 @@ BEGIN prev_state <= state; state <= nxt_state; i_src_out <= nxt_src_out; - block_cnt <= nxt_block_cnt; + --block_cnt <= nxt_block_cnt; + clk_cnt <= nxt_clk_cnt; + sync <= nxt_sync; block_size_cnt <= nxt_block_size_cnt; i_dp_on_status <= nxt_dp_on_status; offset_bsn_cnt <= nxt_offset_bsn_cnt; diff --git a/libraries/base/dp/src/vhdl/mms_dp_bsn_source_v2.vhd b/libraries/base/dp/src/vhdl/mms_dp_bsn_source_v2.vhd index f6429063ae10a6651b8f1c619d5f711b67df8341..501e8860993b9ab7b23be43e6e53c51e25988f5b 100644 --- a/libraries/base/dp/src/vhdl/mms_dp_bsn_source_v2.vhd +++ b/libraries/base/dp/src/vhdl/mms_dp_bsn_source_v2.vhd @@ -33,7 +33,7 @@ ENTITY mms_dp_bsn_source_v2 IS GENERIC ( g_cross_clock_domain : BOOLEAN := TRUE; -- use FALSE when mm_clk and st_clk are the same, else use TRUE to cross the clock domain g_block_size : NATURAL := 256; -- 1024 samples @ 800M / 4 = 256 4 sample words @ 200 M - g_nof_block_per_sync : NATURAL := 8; -- 800M/1024 = 781250; + g_nof_clk_per_sync : NATURAL := 200 * 10**6; -- ; g_bsn_w : NATURAL := 48 ); PORT ( @@ -58,7 +58,7 @@ ARCHITECTURE str OF mms_dp_bsn_source_v2 IS SIGNAL dp_on : STD_LOGIC; SIGNAL dp_on_pps : STD_LOGIC; - SIGNAL nof_block_per_sync : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); + SIGNAL nof_clk_per_sync : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); SIGNAL init_bsn : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0); SIGNAL i_bs_sosi : t_dp_sosi; @@ -71,10 +71,10 @@ BEGIN bs_sosi <= i_bs_sosi; - u_mm_reg : ENTITY work.dp_bsn_source_reg + u_mm_reg : ENTITY work.dp_bsn_source_reg_v2 GENERIC MAP ( g_cross_clock_domain => g_cross_clock_domain, - g_nof_block_per_sync => g_nof_block_per_sync + g_nof_clk_per_sync => g_nof_clk_per_sync ) PORT MAP ( -- Clocks and reset @@ -91,7 +91,7 @@ BEGIN st_on => dp_on, st_on_pps => dp_on_pps, st_on_status => dp_on_status, - st_nof_block_per_sync => nof_block_per_sync, + st_nof_clk_per_sync => nof_clk_per_sync, st_init_bsn => init_bsn, st_current_bsn => capture_bsn ); @@ -99,7 +99,7 @@ BEGIN u_bsn_source : ENTITY work.dp_bsn_source_v2 GENERIC MAP ( g_block_size => g_block_size, - g_nof_block_per_sync => g_nof_block_per_sync, + g_nof_clk_per_sync => g_nof_clk_per_sync, g_bsn_w => g_bsn_w ) PORT MAP ( @@ -111,7 +111,7 @@ BEGIN dp_on_pps => dp_on_pps, dp_on_status => dp_on_status, init_bsn => init_bsn, - nof_block_per_sync => nof_block_per_sync, + nof_clk_per_sync => nof_clk_per_sync, -- Streaming src_out => i_bs_sosi ); diff --git a/libraries/base/dp/tb/vhdl/tb_dp_bsn_source_v2.vhd b/libraries/base/dp/tb/vhdl/tb_dp_bsn_source_v2.vhd index bcfaab3c2317d308a54c569f6fe1467cf129062c..8c5e636000998a0241ab920d5b436f829f47b265 100644 --- a/libraries/base/dp/tb/vhdl/tb_dp_bsn_source_v2.vhd +++ b/libraries/base/dp/tb/vhdl/tb_dp_bsn_source_v2.vhd @@ -25,7 +25,7 @@ -- . sop, eop are verified automatically -- . sync and bsn are verified automatically -- and then manually verify on/off in Wave window - + LIBRARY IEEE, common_lib, dp_lib; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; @@ -40,13 +40,13 @@ END tb_dp_bsn_source_v2; ARCHITECTURE tb OF tb_dp_bsn_source_v2 IS CONSTANT c_clk_period : TIME := 10 ns; - - CONSTANT c_block_size : NATURAL := 31; - --CONSTANT c_block_size : NATURAL := 32; - CONSTANT c_bsn_w : NATURAL := 16; - CONSTANT c_sync_period : NATURAL := 7; - CONSTANT c_sync_offset : NATURAL := 3; -- must be < c_sync_period for proc_dp_verify_sync - + + CONSTANT c_block_size : NATURAL := 32; -- 31; + CONSTANT c_bsn_w : NATURAL := 31; -- 16; + CONSTANT c_clk_per_sync : NATURAL := 240; -- 200 * 10**6; + CONSTANT c_sync_period : NATURAL := 8; + CONSTANT c_sync_offset : NATURAL := 0; -- 3; -- must be < c_sync_period for proc_dp_verify_sync + -- The state name tells what kind of test is being done TYPE t_state_enum IS ( s_disable, @@ -55,23 +55,25 @@ ARCHITECTURE tb OF tb_dp_bsn_source_v2 IS ); SIGNAL tb_state : t_state_enum; - + SIGNAL tb_end : STD_LOGIC := '0'; SIGNAL rst : STD_LOGIC := '1'; SIGNAL clk : STD_LOGIC := '1'; SIGNAL pps : STD_LOGIC; - + -- DUT SIGNAL dp_on : STD_LOGIC := '0'; SIGNAL dp_on_pps : STD_LOGIC := '0'; SIGNAL init_bsn : STD_LOGIC_VECTOR(c_bsn_w-1 DOWNTO 0) := (OTHERS=>'0'); - + SIGNAL bs_sosi : t_dp_sosi; - + -- Verify SIGNAL verify_sync : STD_LOGIC := '1'; - SIGNAL hold_bs_sop : STD_LOGIC; - + SIGNAL hold_bs_sop : STD_LOGIC; + + SIGNAL tb_bsn_cnt : INTEGER := 0; + BEGIN ----------------------------------------------------------------------------- @@ -79,32 +81,32 @@ BEGIN ----------------------------------------------------------------------------- rst <= '1', '0' AFTER c_clk_period*7; clk <= (NOT clk) OR tb_end AFTER c_clk_period/2; - + -- MM control p_mm : PROCESS BEGIN tb_end <= '0'; tb_state <= s_disable; pps <= '0'; - + dp_on <= '0'; dp_on_pps <= '0'; init_bsn <= TO_UVEC(c_sync_offset, c_bsn_w); - + -- Get synchronous to clk proc_common_wait_until_low(clk, rst); proc_common_wait_some_cycles(clk, 500); - + -- Start by making dp_on high tb_state <= s_start; dp_on <= '1'; proc_common_wait_some_cycles(clk, 2000); - + -- Stop by making dp_on low tb_state <= s_disable; dp_on <= '0'; proc_common_wait_some_cycles(clk, 1000); - + -- Now start on PPS tb_state <= s_pps_start; dp_on_pps <= '1'; @@ -114,24 +116,24 @@ BEGIN proc_common_wait_some_cycles(clk, 1); pps <= '0'; proc_common_wait_some_cycles(clk, 1000); - + -- Stop by making dp_on low tb_state <= s_disable; dp_on <= '0'; dp_on_pps <= '0'; --No PPS trigger next time proc_common_wait_some_cycles(clk, 1000); - + -- Start by making dp_on high tb_state <= s_start; dp_on <= '1'; proc_common_wait_some_cycles(clk, 2500); - + -- Stop by making dp_on low tb_state <= s_disable; dp_on <= '0'; dp_on_pps <= '0'; proc_common_wait_some_cycles(clk, 1000); - + -- Now start on next PPS and continue forever init_bsn <= TO_UVEC(c_sync_offset, c_bsn_w); tb_state <= s_pps_start; @@ -141,28 +143,28 @@ BEGIN pps <= '1'; proc_common_wait_some_cycles(clk, 1); pps <= '0'; - - + + proc_common_wait_some_cycles(clk, 10000); tb_end <= '1'; WAIT; - END PROCESS; - - + END PROCESS; + + ----------------------------------------------------------------------------- -- Verification ----------------------------------------------------------------------------- proc_dp_verify_sop_and_eop(clk, bs_sosi.valid, bs_sosi.sop, bs_sosi.eop, hold_bs_sop); -- Verify that sop and eop come in pairs - proc_dp_verify_sync(c_sync_period, c_sync_offset, clk, verify_sync, bs_sosi.sync, bs_sosi.sop, bs_sosi.bsn); -- Verify sync at sop and at expected BSN + proc_dp_verify_sync_v2(c_sync_period, c_sync_offset, clk, verify_sync, bs_sosi.sync, bs_sosi.sop, bs_sosi.bsn, tb_bsn_cnt); -- Verify sync at sop and at expected BSN ----------------------------------------------------------------------------- -- DUT: dp_bsn_source_v2 ----------------------------------------------------------------------------- - + dut : ENTITY work.dp_bsn_source_v2 GENERIC MAP ( g_block_size => c_block_size, - g_nof_block_per_sync => c_sync_period, + g_nof_clk_per_sync => c_clk_per_sync, g_bsn_w => c_bsn_w ) PORT MAP ( @@ -176,5 +178,5 @@ BEGIN -- Streaming src_out => bs_sosi ); - + END tb; diff --git a/libraries/base/dp/tb/vhdl/tb_dp_pkg.vhd b/libraries/base/dp/tb/vhdl/tb_dp_pkg.vhd index f3955889bab0b15aed221174b8c59d26642ab617..e0afa14eb18a8ca0e364f20437d3446621e0dbdc 100644 --- a/libraries/base/dp/tb/vhdl/tb_dp_pkg.vhd +++ b/libraries/base/dp/tb/vhdl/tb_dp_pkg.vhd @@ -25,6 +25,7 @@ USE IEEE.std_logic_1164.ALL; USE IEEE.numeric_std.ALL; USE common_lib.common_pkg.ALL; USE common_lib.common_lfsr_sequences_pkg.ALL; +USE common_lib.common_str_pkg.ALL; USE common_lib.tb_common_pkg.ALL; USE work.dp_stream_pkg.ALL; @@ -74,7 +75,7 @@ PACKAGE tb_dp_pkg IS CONSTANT c_dp_error_w : NATURAL := c_dp_stream_error_w; TYPE t_dp_data_arr IS ARRAY (NATURAL RANGE <>) OF STD_LOGIC_VECTOR(c_dp_data_w-1 DOWNTO 0); - + -- The state name tells what kind of test is done in the sync interval TYPE t_dp_state_enum IS ( s_idle, @@ -94,22 +95,22 @@ PACKAGE tb_dp_pkg IS e_equal, e_at_least ); - + -- always active, random or pulse flow control TYPE t_dp_flow_control_enum IS ( e_active, e_random, - e_pulse + e_pulse ); - + TYPE t_dp_flow_control_enum_arr IS ARRAY (NATURAL RANGE <>) OF t_dp_flow_control_enum; - + CONSTANT c_dp_flow_control_enum_arr : t_dp_flow_control_enum_arr := (e_active, e_random, e_pulse); -- array all possible values that can be iterated over - + ------------------------------------------------------------------------------ -- Stream source functions ------------------------------------------------------------------------------ - + -- Block data generator with feedforward throttle control -- !!! old style: sync before sop -- !!! used by tb_dp_packetizing, do not use for new DP components @@ -125,7 +126,7 @@ PACKAGE tb_dp_pkg IS SIGNAL cnt_sync : OUT STD_LOGIC; SIGNAL cnt_val : OUT STD_LOGIC; SIGNAL cnt_dat : INOUT STD_LOGIC_VECTOR); - + -- Block data generator with ready flow control and symbols counter PROCEDURE proc_dp_gen_block_data(CONSTANT c_ready_latency : IN NATURAL; -- 0, 1 are supported by proc_dp_stream_ready_latency() CONSTANT c_use_data : IN BOOLEAN; -- when TRUE use data field, else use re, im fields, and keep unused fields at 'X' @@ -143,7 +144,7 @@ PACKAGE tb_dp_pkg IS 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); - + -- Increment only sosi.data, keep complex re,im = 0 PROCEDURE proc_dp_gen_block_data(CONSTANT c_data_w : IN NATURAL; -- data width for the data field CONSTANT c_symbol_init : IN NATURAL; -- init counter for the data in the data field @@ -156,7 +157,7 @@ PACKAGE tb_dp_pkg IS 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); - + -- Increment only sosi.re, im, keep data = 0 PROCEDURE proc_dp_gen_block_complex(CONSTANT c_data_w : IN NATURAL; -- data width for the re, im field CONSTANT c_symbol_re_init : IN NATURAL; -- init counter for symbols in re field @@ -170,7 +171,7 @@ PACKAGE tb_dp_pkg IS 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); - + -- Handle stream ready signal, only support RL=0 or 1. PROCEDURE proc_dp_stream_ready_latency(CONSTANT c_latency : IN NATURAL; SIGNAL clk : IN STD_LOGIC; @@ -184,13 +185,13 @@ PACKAGE tb_dp_pkg IS SIGNAL out_valid : OUT STD_LOGIC; SIGNAL out_sop : OUT STD_LOGIC; SIGNAL out_eop : OUT STD_LOGIC); - + -- Initialize the data per symbol FUNCTION func_dp_data_init(c_data_w, c_symbol_w, init : NATURAL) RETURN STD_LOGIC_VECTOR; - + -- Increment the data per symbol FUNCTION func_dp_data_incr(c_data_w, c_symbol_w : NATURAL; data : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR; - + -- Generate a counter data with valid PROCEDURE proc_dp_gen_data(CONSTANT c_ready_latency : IN NATURAL; -- 0, 1 are supported by proc_dp_stream_ready_latency() CONSTANT c_data_w : IN NATURAL; @@ -202,16 +203,16 @@ PACKAGE tb_dp_pkg IS SIGNAL src_out : OUT t_dp_sosi); -- As above but with counter max - PROCEDURE proc_dp_gen_data(CONSTANT c_ready_latency : IN NATURAL; + PROCEDURE proc_dp_gen_data(CONSTANT c_ready_latency : IN NATURAL; CONSTANT c_data_w : IN NATURAL; CONSTANT c_data_init : IN NATURAL; - CONSTANT c_data_max : IN NATURAL; + CONSTANT c_data_max : IN NATURAL; SIGNAL rst : IN STD_LOGIC; SIGNAL clk : IN STD_LOGIC; SIGNAL in_en : IN STD_LOGIC; SIGNAL src_in : IN t_dp_siso; SIGNAL src_out : OUT t_dp_sosi); - + -- Generate a frame with symbols counter PROCEDURE proc_dp_gen_frame(CONSTANT c_ready_latency : IN NATURAL; -- 0, 1 are supported by proc_dp_stream_ready_latency() CONSTANT c_data_w : IN NATURAL; @@ -236,7 +237,7 @@ PACKAGE tb_dp_pkg IS SIGNAL in_en : IN STD_LOGIC; SIGNAL cnt_val : INOUT STD_LOGIC; SIGNAL cnt_dat : INOUT STD_LOGIC_VECTOR); - + -- Transmit data PROCEDURE proc_dp_tx_data(CONSTANT c_ready_latency : IN NATURAL; SIGNAL rst : IN STD_LOGIC; @@ -247,14 +248,14 @@ PACKAGE tb_dp_pkg IS SIGNAL tx_val : INOUT STD_LOGIC_VECTOR; SIGNAL out_data : OUT STD_LOGIC_VECTOR; SIGNAL out_val : OUT STD_LOGIC); - + -- Transmit data control (use for sop, eop) PROCEDURE proc_dp_tx_ctrl(CONSTANT c_offset : IN NATURAL; CONSTANT c_period : IN NATURAL; SIGNAL data : IN STD_LOGIC_VECTOR; SIGNAL valid : IN STD_LOGIC; SIGNAL ctrl : OUT STD_LOGIC); - + -- Define sync interval PROCEDURE proc_dp_sync_interval(SIGNAL clk : IN STD_LOGIC; SIGNAL sync : OUT STD_LOGIC); @@ -272,55 +273,55 @@ PACKAGE tb_dp_pkg IS ------------------------------------------------------------------------------ -- Stream sink functions ------------------------------------------------------------------------------ - + -- Stimuli for out_ready PROCEDURE proc_dp_out_ready(SIGNAL rst : IN STD_LOGIC; SIGNAL clk : IN STD_LOGIC; SIGNAL sync : IN STD_LOGIC; SIGNAL lfsr : INOUT STD_LOGIC_VECTOR; SIGNAL out_ready : OUT STD_LOGIC); - + -- DUT output verify enable PROCEDURE proc_dp_verify_en(CONSTANT c_delay : IN NATURAL; SIGNAL rst : IN STD_LOGIC; SIGNAL clk : IN STD_LOGIC; SIGNAL sync : IN STD_LOGIC; SIGNAL verify_en : OUT STD_LOGIC); - + PROCEDURE proc_dp_verify_en(CONSTANT c_continuous : IN BOOLEAN; SIGNAL clk : IN STD_LOGIC; SIGNAL valid : IN STD_LOGIC; SIGNAL sop : IN STD_LOGIC; SIGNAL eop : IN STD_LOGIC; SIGNAL verify_en : OUT STD_LOGIC); - + -- Run and verify for some cycles PROCEDURE proc_dp_verify_run_some_cycles(CONSTANT nof_pre_clk : IN NATURAL; CONSTANT nof_verify_clk : IN NATURAL; CONSTANT nof_post_clk : IN NATURAL; SIGNAL clk : IN STD_LOGIC; SIGNAL verify_en : OUT STD_LOGIC); - + -- Verify the expected value PROCEDURE proc_dp_verify_value(CONSTANT c_str : IN STRING; CONSTANT mode : IN t_dp_value_enum; SIGNAL clk : IN STD_LOGIC; SIGNAL en : IN STD_LOGIC; - SIGNAL exp : IN STD_LOGIC_VECTOR; + SIGNAL exp : IN STD_LOGIC_VECTOR; SIGNAL res : IN STD_LOGIC_VECTOR); - + PROCEDURE proc_dp_verify_value(CONSTANT mode : IN t_dp_value_enum; SIGNAL clk : IN STD_LOGIC; SIGNAL en : IN STD_LOGIC; - SIGNAL exp : IN STD_LOGIC_VECTOR; + SIGNAL exp : IN STD_LOGIC_VECTOR; SIGNAL res : IN STD_LOGIC_VECTOR); - + PROCEDURE proc_dp_verify_value(CONSTANT c_str : IN STRING; SIGNAL clk : IN STD_LOGIC; SIGNAL en : IN STD_LOGIC; - SIGNAL exp : IN STD_LOGIC; + SIGNAL exp : IN STD_LOGIC; SIGNAL res : IN STD_LOGIC); - + -- Verify output global and local BSN -- . incrementing or replicated global BSN -- . incrementing local BSN that starts at 1 @@ -336,7 +337,7 @@ PACKAGE tb_dp_pkg IS SIGNAL cnt_replicated_global_bsn : INOUT NATURAL; SIGNAL prev_out_bsn_global : INOUT STD_LOGIC_VECTOR; SIGNAL prev_out_bsn_local : INOUT STD_LOGIC_VECTOR); - + -- Verify incrementing data -- . wrap at c_out_data_max when >0, else no wrap when c_out_data_max=0 -- . default increment by +1, but also allow an increment by +c_out_data_gap @@ -350,7 +351,7 @@ PACKAGE tb_dp_pkg IS SIGNAL out_val : IN STD_LOGIC; SIGNAL out_data : IN STD_LOGIC_VECTOR; SIGNAL prev_out_data : INOUT STD_LOGIC_VECTOR); - + -- Verify the DUT incrementing output data that wraps in range 0 ... c_out_data_max PROCEDURE proc_dp_verify_data(CONSTANT c_str : IN STRING; CONSTANT c_ready_latency : IN NATURAL; @@ -361,7 +362,7 @@ PACKAGE tb_dp_pkg IS SIGNAL out_val : IN STD_LOGIC; SIGNAL out_data : IN STD_LOGIC_VECTOR; SIGNAL prev_out_data : INOUT STD_LOGIC_VECTOR); - + -- Verify the DUT incrementing output data, fixed increment +1 PROCEDURE proc_dp_verify_data(CONSTANT c_str : IN STRING; CONSTANT c_ready_latency : IN NATURAL; @@ -371,7 +372,7 @@ PACKAGE tb_dp_pkg IS SIGNAL out_val : IN STD_LOGIC; -- by using sop or eop proc_dp_verify_data() can also be used to verify other SOSI fields like bsn, error, channel, empty SIGNAL out_data : IN STD_LOGIC_VECTOR; SIGNAL prev_out_data : INOUT STD_LOGIC_VECTOR); - + -- Verify incrementing data with RL > 0 or no flow control, support wrap at maximum and increment gap PROCEDURE proc_dp_verify_data(CONSTANT c_str : IN STRING; CONSTANT c_out_data_max : IN UNSIGNED; @@ -381,7 +382,7 @@ PACKAGE tb_dp_pkg IS SIGNAL out_val : IN STD_LOGIC; SIGNAL out_data : IN STD_LOGIC_VECTOR; SIGNAL prev_out_data : INOUT STD_LOGIC_VECTOR); - + PROCEDURE proc_dp_verify_data(CONSTANT c_str : IN STRING; CONSTANT c_out_data_max : IN NATURAL; CONSTANT c_out_data_gap : IN NATURAL; @@ -390,7 +391,7 @@ PACKAGE tb_dp_pkg IS SIGNAL out_val : IN STD_LOGIC; SIGNAL out_data : IN STD_LOGIC_VECTOR; SIGNAL prev_out_data : INOUT STD_LOGIC_VECTOR); - + PROCEDURE proc_dp_verify_data(CONSTANT c_str : IN STRING; CONSTANT c_out_data_max : IN NATURAL; SIGNAL clk : IN STD_LOGIC; @@ -398,7 +399,7 @@ PACKAGE tb_dp_pkg IS SIGNAL out_val : IN STD_LOGIC; SIGNAL out_data : IN STD_LOGIC_VECTOR; SIGNAL prev_out_data : INOUT STD_LOGIC_VECTOR); - + -- Verify incrementing data with RL > 0 or no flow control, fixed increment +1 PROCEDURE proc_dp_verify_data(CONSTANT c_str : IN STRING; SIGNAL clk : IN STD_LOGIC; @@ -406,7 +407,7 @@ PACKAGE tb_dp_pkg IS SIGNAL out_val : IN STD_LOGIC; SIGNAL out_data : IN STD_LOGIC_VECTOR; SIGNAL prev_out_data : INOUT STD_LOGIC_VECTOR); - + -- Verify the DUT output symbols PROCEDURE proc_dp_verify_symbols(CONSTANT c_ready_latency : IN NATURAL; CONSTANT c_data_w : IN NATURAL; @@ -419,7 +420,7 @@ PACKAGE tb_dp_pkg IS SIGNAL out_data : IN STD_LOGIC_VECTOR; SIGNAL out_empty : IN STD_LOGIC_VECTOR; SIGNAL prev_out_data : INOUT STD_LOGIC_VECTOR); - + -- Verify the DUT output data with empty PROCEDURE proc_dp_verify_data_empty(CONSTANT c_ready_latency : IN NATURAL; CONSTANT c_last_word : IN NATURAL; @@ -436,26 +437,26 @@ PACKAGE tb_dp_pkg IS SIGNAL out_data_3 : INOUT STD_LOGIC_VECTOR; SIGNAL out_empty : IN STD_LOGIC_VECTOR; SIGNAL out_empty_1 : INOUT STD_LOGIC_VECTOR); - + PROCEDURE proc_dp_verify_other_sosi(CONSTANT c_str : IN STRING; CONSTANT c_exp_data : IN STD_LOGIC_VECTOR; SIGNAL clk : IN STD_LOGIC; SIGNAL verify_en : IN STD_LOGIC; SIGNAL res_data : IN STD_LOGIC_VECTOR); - + PROCEDURE proc_dp_verify_valid(CONSTANT c_ready_latency : IN NATURAL; SIGNAL clk : IN STD_LOGIC; SIGNAL verify_en : IN STD_LOGIC; SIGNAL out_ready : IN STD_LOGIC; SIGNAL prev_out_ready : INOUT STD_LOGIC_VECTOR; SIGNAL out_val : IN STD_LOGIC); - + PROCEDURE proc_dp_verify_valid(SIGNAL clk : IN STD_LOGIC; SIGNAL verify_en : IN STD_LOGIC; SIGNAL out_ready : IN STD_LOGIC; SIGNAL prev_out_ready : INOUT STD_LOGIC; SIGNAL out_val : IN STD_LOGIC); - + -- Verify the DUT output sync PROCEDURE proc_dp_verify_sync(CONSTANT c_sync_period : IN NATURAL; CONSTANT c_sync_offset : IN NATURAL; @@ -464,7 +465,17 @@ PACKAGE tb_dp_pkg IS SIGNAL sync : IN STD_LOGIC; SIGNAL sop : IN STD_LOGIC; SIGNAL bsn : IN STD_LOGIC_VECTOR); - + + -- Verify the DUT output sync + PROCEDURE proc_dp_verify_sync_v2(CONSTANT c_sync_period : IN NATURAL; + CONSTANT c_sync_offset : IN NATURAL; + SIGNAL clk : IN STD_LOGIC; + SIGNAL verify_en : IN STD_LOGIC; + SIGNAL sync : IN STD_LOGIC; + SIGNAL sop : IN STD_LOGIC; + SIGNAL bsn : IN STD_LOGIC_VECTOR; + SIGNAL tb_bsn_cnt : INOUT INTEGER); + -- Verify the DUT output sop and eop PROCEDURE proc_dp_verify_sop_and_eop(CONSTANT c_ready_latency : IN NATURAL; CONSTANT c_verify_valid : IN BOOLEAN; @@ -474,7 +485,7 @@ PACKAGE tb_dp_pkg IS SIGNAL out_sop : IN STD_LOGIC; SIGNAL out_eop : IN STD_LOGIC; SIGNAL hold_sop : INOUT STD_LOGIC); - + PROCEDURE proc_dp_verify_sop_and_eop(CONSTANT c_ready_latency : IN NATURAL; SIGNAL clk : IN STD_LOGIC; SIGNAL out_ready : IN STD_LOGIC; @@ -482,13 +493,13 @@ PACKAGE tb_dp_pkg IS SIGNAL out_sop : IN STD_LOGIC; SIGNAL out_eop : IN STD_LOGIC; SIGNAL hold_sop : INOUT STD_LOGIC); - + PROCEDURE proc_dp_verify_sop_and_eop(SIGNAL clk : IN STD_LOGIC; SIGNAL out_val : IN STD_LOGIC; SIGNAL out_sop : IN STD_LOGIC; SIGNAL out_eop : IN STD_LOGIC; SIGNAL hold_sop : INOUT STD_LOGIC); - + PROCEDURE proc_dp_verify_block_size(CONSTANT c_ready_latency : IN NATURAL; SIGNAL alt_size : IN NATURAL; -- alternative size (eg. use exp_size'last_value) SIGNAL exp_size : IN NATURAL; -- expected size @@ -498,7 +509,7 @@ PACKAGE tb_dp_pkg IS SIGNAL out_sop : IN STD_LOGIC; SIGNAL out_eop : IN STD_LOGIC; SIGNAL cnt_size : INOUT NATURAL); - + PROCEDURE proc_dp_verify_block_size(CONSTANT c_ready_latency : IN NATURAL; SIGNAL exp_size : IN NATURAL; -- expected size SIGNAL clk : IN STD_LOGIC; @@ -507,7 +518,7 @@ PACKAGE tb_dp_pkg IS SIGNAL out_sop : IN STD_LOGIC; SIGNAL out_eop : IN STD_LOGIC; SIGNAL cnt_size : INOUT NATURAL); - + PROCEDURE proc_dp_verify_block_size(SIGNAL alt_size : IN NATURAL; -- alternative size (eg. use exp_size'last_value) SIGNAL exp_size : IN NATURAL; -- expected size SIGNAL clk : IN STD_LOGIC; @@ -515,21 +526,21 @@ PACKAGE tb_dp_pkg IS SIGNAL out_sop : IN STD_LOGIC; SIGNAL out_eop : IN STD_LOGIC; SIGNAL cnt_size : INOUT NATURAL); - + PROCEDURE proc_dp_verify_block_size(SIGNAL exp_size : IN NATURAL; -- expected size SIGNAL clk : IN STD_LOGIC; SIGNAL out_val : IN STD_LOGIC; SIGNAL out_sop : IN STD_LOGIC; SIGNAL out_eop : IN STD_LOGIC; SIGNAL cnt_size : INOUT NATURAL); - + -- Verify the DUT output invalid between frames PROCEDURE proc_dp_verify_gap_invalid(SIGNAL clk : IN STD_LOGIC; SIGNAL in_val : IN STD_LOGIC; SIGNAL in_sop : IN STD_LOGIC; SIGNAL in_eop : IN STD_LOGIC; SIGNAL out_gap : INOUT STD_LOGIC); -- declare initial gap signal = '1' - + -- Verify the DUT output control (use for sop, eop) PROCEDURE proc_dp_verify_ctrl(CONSTANT c_offset : IN NATURAL; CONSTANT c_period : IN NATURAL; @@ -539,21 +550,21 @@ PACKAGE tb_dp_pkg IS SIGNAL data : IN STD_LOGIC_VECTOR; SIGNAL valid : IN STD_LOGIC; SIGNAL ctrl : IN STD_LOGIC); - + -- Wait for stream valid PROCEDURE proc_dp_stream_valid(SIGNAL clk : IN STD_LOGIC; SIGNAL in_valid : IN STD_LOGIC); - + -- Wait for stream valid AND sop PROCEDURE proc_dp_stream_valid_sop(SIGNAL clk : IN STD_LOGIC; SIGNAL in_valid : IN STD_LOGIC; SIGNAL in_sop : IN STD_LOGIC); - + -- Wait for stream valid AND eop PROCEDURE proc_dp_stream_valid_eop(SIGNAL clk : IN STD_LOGIC; SIGNAL in_valid : IN STD_LOGIC; SIGNAL in_eop : IN STD_LOGIC); - + END tb_dp_pkg; @@ -579,11 +590,11 @@ PACKAGE BODY tb_dp_pkg IS BEGIN sync_nr <= 0; block_nr <= 0; - - cnt_sync <= '0'; + + cnt_sync <= '0'; cnt_val <= '0'; cnt_dat <= (cnt_dat'RANGE=>'1'); -- -1, so first valid cnt_dat starts at 0 - + -- allow some clock cycles before start after rst release WAIT UNTIL rst='0'; FOR I IN 0 TO c_start_delay-1 LOOP WAIT UNTIL rising_edge(clk); END LOOP; @@ -593,7 +604,7 @@ PACKAGE BODY tb_dp_pkg IS WAIT UNTIL rising_edge(clk); cnt_sync <= '0'; FOR I IN 1 TO c_gap_size-1 LOOP WAIT UNTIL rising_edge(clk); END LOOP; - + WHILE TRUE LOOP -- output block IF c_throttle_num >= c_throttle_den THEN @@ -629,14 +640,14 @@ PACKAGE BODY tb_dp_pkg IS FOR I IN 1 TO c_gap_size-1 LOOP WAIT UNTIL rising_edge(clk); END LOOP; -- next block block_nr <= block_nr+1; - END LOOP; + END LOOP; END proc_dp_gen_block_data; - - + + ------------------------------------------------------------------------------ -- PROCEDURE: Block data generator with ready flow control and symbols counter -- . dependent on in_en and src_in.ready - -- . optional sync pulse at end of frame + -- . optional sync pulse at end of frame ------------------------------------------------------------------------------ PROCEDURE proc_dp_gen_block_data(CONSTANT c_ready_latency : IN NATURAL; -- 0, 1 are supported by proc_dp_stream_ready_latency() CONSTANT c_use_data : IN BOOLEAN; -- when TRUE use data field, else use re, im fields, and keep unused fields at 'X' @@ -686,7 +697,7 @@ PACKAGE BODY tb_dp_pkg IS IF c_use_data=FALSE THEN src_out.im <= RESIZE_DP_DSP_DATA(v_im); END IF; proc_dp_stream_ready_latency(c_ready_latency, clk, src_in.ready, in_en, '0', '1', '0', '0', src_out.sync, src_out.valid, src_out.sop, src_out.eop); END LOOP; - + -- . eop v_data := func_dp_data_incr(c_data_w, c_symbol_w, v_data); v_re := func_dp_data_incr(c_data_w, c_symbol_w, v_re); @@ -704,7 +715,7 @@ PACKAGE BODY tb_dp_pkg IS proc_common_wait_some_cycles(clk, c_nof_data); END IF; END proc_dp_gen_block_data; - + -- Increment only sosi.data, keep complex re,im = 0 PROCEDURE proc_dp_gen_block_data(CONSTANT c_data_w : IN NATURAL; -- data width for the data field CONSTANT c_symbol_init : IN NATURAL; -- init counter for the data in the data field @@ -720,7 +731,7 @@ PACKAGE BODY tb_dp_pkg IS BEGIN proc_dp_gen_block_data(1, TRUE, c_data_w, c_data_w, c_symbol_init, 0, 0, c_nof_symbols, c_channel, c_error, c_sync, c_bsn, clk, in_en, src_in, src_out); END proc_dp_gen_block_data; - + -- Increment only sosi.re, im, keep data = 0 PROCEDURE proc_dp_gen_block_complex(CONSTANT c_data_w : IN NATURAL; -- data width for the re, im field CONSTANT c_symbol_re_init : IN NATURAL; -- init counter for symbols in re field @@ -737,7 +748,7 @@ PACKAGE BODY tb_dp_pkg IS BEGIN proc_dp_gen_block_data(1, FALSE, c_data_w, c_data_w, 0, c_symbol_re_init, c_symbol_im_init, c_nof_symbols, c_channel, c_error, c_sync, c_bsn, clk, in_en, src_in, src_out); END proc_dp_gen_block_complex; - + ------------------------------------------------------------------------------ -- PROCEDURE: Handle stream ready signal -- . output active when src_in is ready and in_en='1' @@ -761,12 +772,12 @@ PACKAGE BODY tb_dp_pkg IS out_valid <= '0'; out_sop <= '0'; out_eop <= '0'; - + -- Skip cycles until in_en='1' WHILE in_en='0' LOOP WAIT UNTIL rising_edge(clk); END LOOP; - + -- Active output when ready -- . RL = 0 IF c_latency=0 THEN @@ -781,7 +792,7 @@ PACKAGE BODY tb_dp_pkg IS END LOOP; -- ready has acknowledged the valid output END IF; - + -- . RL = 1 IF c_latency=1 THEN -- no valid output until request @@ -795,7 +806,7 @@ PACKAGE BODY tb_dp_pkg IS out_eop <= c_eop; WAIT UNTIL rising_edge(clk); END IF; - + -- Return with no active output out_sync <= '0'; out_valid <= '0'; @@ -803,7 +814,7 @@ PACKAGE BODY tb_dp_pkg IS out_eop <= '0'; END proc_dp_stream_ready_latency; - + ------------------------------------------------------------------------------ -- FUNCTION: Initialize the data per symbol -- . use big endian @@ -822,8 +833,8 @@ PACKAGE BODY tb_dp_pkg IS END LOOP; RETURN v_data; END func_dp_data_init; - - + + ------------------------------------------------------------------------------ -- FUNCTION: Increment the data per symbol -- . use big endian @@ -844,8 +855,8 @@ PACKAGE BODY tb_dp_pkg IS END LOOP; RETURN v_data; END func_dp_data_incr; - - + + ------------------------------------------------------------------------------ -- PROCEDURE: Generate counter data with valid -- . Output counter data dependent on in_en and src_in.ready @@ -878,10 +889,10 @@ PACKAGE BODY tb_dp_pkg IS -- . Output counter data dependent on in_en and src_in.ready -- . with maximum count value ------------------------------------------------------------------------------ - PROCEDURE proc_dp_gen_data(CONSTANT c_ready_latency : IN NATURAL; + PROCEDURE proc_dp_gen_data(CONSTANT c_ready_latency : IN NATURAL; CONSTANT c_data_w : IN NATURAL; CONSTANT c_data_init : IN NATURAL; - CONSTANT c_data_max : IN NATURAL; + CONSTANT c_data_max : IN NATURAL; SIGNAL rst : IN STD_LOGIC; SIGNAL clk : IN STD_LOGIC; SIGNAL in_en : IN STD_LOGIC; -- when '0' then no valid output even when src_in is ready @@ -904,8 +915,8 @@ PACKAGE BODY tb_dp_pkg IS END LOOP; END IF; END proc_dp_gen_data; - - + + ------------------------------------------------------------------------------ -- PROCEDURE: Generate a frame with symbols counter -- . dependent on in_en and src_in.ready @@ -954,8 +965,8 @@ PACKAGE BODY tb_dp_pkg IS src_out.sop <= '0'; src_out.eop <= '0'; END proc_dp_gen_frame; - - + + ------------------------------------------------------------------------------ -- PROCEDURE: Input data counter ------------------------------------------------------------------------------ @@ -972,7 +983,7 @@ PACKAGE BODY tb_dp_pkg IS END IF; END IF; END proc_dp_cnt_dat; - + PROCEDURE proc_dp_cnt_dat(SIGNAL rst : IN STD_LOGIC; SIGNAL clk : IN STD_LOGIC; SIGNAL in_en : IN STD_LOGIC; @@ -990,7 +1001,7 @@ PACKAGE BODY tb_dp_pkg IS END IF; END IF; END proc_dp_cnt_dat; - + ------------------------------------------------------------------------------ -- PROCEDURE: Transmit data ------------------------------------------------------------------------------ @@ -1008,7 +1019,7 @@ PACKAGE BODY tb_dp_pkg IS -- TX data array for output ready latency [c_ready_latency], index [0] for zero latency combinatorial tx_data(0) <= cnt_dat; tx_val( 0) <= cnt_val; - + IF rst='1' THEN tx_data(1 TO c_ready_latency+c_void) <= (1 TO c_ready_latency+c_void=>(OTHERS=>'0')); tx_val( 1 TO c_ready_latency+c_void) <= (1 TO c_ready_latency+c_void=>'0'); @@ -1016,12 +1027,12 @@ PACKAGE BODY tb_dp_pkg IS tx_data(1 TO c_ready_latency+c_void) <= tx_data(0 TO c_ready_latency+c_void-1); tx_val( 1 TO c_ready_latency+c_void) <= tx_val( 0 TO c_ready_latency+c_void-1); END IF; - + out_data <= tx_data(c_ready_latency); out_val <= tx_val(c_ready_latency); END proc_dp_tx_data; - - + + ------------------------------------------------------------------------------ -- PROCEDURE: Transmit data control (use for sop, eop) ------------------------------------------------------------------------------ @@ -1038,8 +1049,8 @@ PACKAGE BODY tb_dp_pkg IS ctrl <= '1'; END IF; END proc_dp_tx_ctrl; - - + + ------------------------------------------------------------------------------ -- PROCEDURE: Define test sync interval ------------------------------------------------------------------------------ @@ -1052,7 +1063,7 @@ PACKAGE BODY tb_dp_pkg IS WAIT UNTIL rising_edge(clk); END proc_dp_sync_interval; - + ------------------------------------------------------------------------------ -- PROCEDURE: Stimuli for cnt_en ------------------------------------------------------------------------------ @@ -1200,7 +1211,7 @@ PACKAGE BODY tb_dp_pkg IS END LOOP; cnt_en <= '1'; FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP; - + -- . 2-1 toggle cnt_en <= '0'; FOR I IN 1 TO c_dp_nof_toggle LOOP @@ -1238,7 +1249,7 @@ PACKAGE BODY tb_dp_pkg IS END LOOP; cnt_en <= '1'; FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP; - + -- . 3-1 toggle cnt_en <= '0'; FOR I IN 1 TO c_dp_nof_toggle LOOP @@ -1251,7 +1262,7 @@ PACKAGE BODY tb_dp_pkg IS END LOOP; cnt_en <= '1'; FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP; - + -- . 2-3 toggle cnt_en <= '0'; FOR I IN 1 TO c_dp_nof_toggle LOOP @@ -1265,7 +1276,7 @@ PACKAGE BODY tb_dp_pkg IS END LOOP; cnt_en <= '1'; FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP; - + -- . 3-2 toggle cnt_en <= '0'; FOR I IN 1 TO c_dp_nof_toggle LOOP @@ -1279,7 +1290,7 @@ PACKAGE BODY tb_dp_pkg IS END LOOP; cnt_en <= '1'; FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP; - + ---------------------------------------------------------------------------- -- Interval 6 ---------------------------------------------------------------------------- @@ -1287,7 +1298,7 @@ PACKAGE BODY tb_dp_pkg IS state <= s_toggle_both; cnt_en <= '1'; FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP; - + FOR I IN 1 TO c_dp_nof_both LOOP cnt_en <= '0'; FOR J IN 1 TO I LOOP WAIT UNTIL rising_edge(clk); END LOOP; @@ -1302,7 +1313,7 @@ PACKAGE BODY tb_dp_pkg IS WAIT UNTIL sync='1'; state <= s_pulse_cnt_en; FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP; - + FOR I IN 1 TO 15 LOOP FOR J IN 1 TO 15 LOOP cnt_en <= '0'; @@ -1314,7 +1325,7 @@ PACKAGE BODY tb_dp_pkg IS END LOOP; cnt_en <= '1'; FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP; - + ---------------------------------------------------------------------------- -- Interval 8 ---------------------------------------------------------------------------- @@ -1322,20 +1333,20 @@ PACKAGE BODY tb_dp_pkg IS state <= s_chirp_out_ready; cnt_en <= '1'; FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP; - + ---------------------------------------------------------------------------- -- Interval 9 ---------------------------------------------------------------------------- WAIT UNTIL sync='1'; state <= s_random; cnt_en <= '1'; - + FOR I IN 0 TO c_dp_sync_interval - c_dp_test_interval LOOP lfsr <= func_common_random(lfsr); cnt_en <= lfsr(lfsr'HIGH); WAIT UNTIL rising_edge(clk); END LOOP; - + ---------------------------------------------------------------------------- -- Done ---------------------------------------------------------------------------- @@ -1343,13 +1354,13 @@ PACKAGE BODY tb_dp_pkg IS state <= s_done; WAIT UNTIL rising_edge(clk); cnt_en <= '0'; - + -- pulse done FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP; done <= '1'; WAIT UNTIL rising_edge(clk); done <= '0'; - + ---------------------------------------------------------------------------- -- Testbench end ---------------------------------------------------------------------------- @@ -1438,7 +1449,7 @@ PACKAGE BODY tb_dp_pkg IS WAIT UNTIL rising_edge(clk); out_ready <= '1'; FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP; - + -- . 7 cycle out_ready <= '0'; WAIT UNTIL rising_edge(clk); @@ -1450,7 +1461,7 @@ PACKAGE BODY tb_dp_pkg IS WAIT UNTIL rising_edge(clk); out_ready <= '1'; FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP; - + ---------------------------------------------------------------------------- -- Interval 3 ---------------------------------------------------------------------------- @@ -1525,7 +1536,7 @@ PACKAGE BODY tb_dp_pkg IS END LOOP; out_ready <= '1'; FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP; - + -- . 3-1 toggle out_ready <= '0'; FOR I IN 1 TO c_dp_nof_toggle LOOP @@ -1580,7 +1591,7 @@ PACKAGE BODY tb_dp_pkg IS WAIT UNTIL sync='1'; out_ready <= '1'; FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP; - + FOR I IN 1 TO c_dp_nof_both LOOP out_ready <= '0'; FOR J IN I TO c_dp_nof_both LOOP WAIT UNTIL rising_edge(clk); END LOOP; @@ -1613,30 +1624,30 @@ PACKAGE BODY tb_dp_pkg IS END LOOP; out_ready <= '1'; FOR I IN 0 TO c_dp_test_interval LOOP WAIT UNTIL rising_edge(clk); END LOOP; - + ---------------------------------------------------------------------------- -- Interval 9 : Random ---------------------------------------------------------------------------- WAIT UNTIL sync='1'; out_ready <= '1'; - + FOR I IN 0 TO c_dp_sync_interval - c_dp_test_interval LOOP lfsr <= func_common_random(lfsr); out_ready <= lfsr(lfsr'HIGH); WAIT UNTIL rising_edge(clk); END LOOP; - + ---------------------------------------------------------------------------- -- Done ---------------------------------------------------------------------------- WAIT; END proc_dp_out_ready; - + ------------------------------------------------------------------------------ -- PROCEDURE: DUT output verify enable ------------------------------------------------------------------------------ - + -- Fixed delay until verify_en active PROCEDURE proc_dp_verify_en(CONSTANT c_delay : IN NATURAL; SIGNAL rst : IN STD_LOGIC; @@ -1647,16 +1658,16 @@ PACKAGE BODY tb_dp_pkg IS verify_en <= '0'; WAIT UNTIL rst='0'; WAIT UNTIL rising_edge(clk); - + WAIT UNTIL sync='1'; -- Use c_delay delay before enabling the p_verify. FOR I IN 0 TO c_delay LOOP WAIT UNTIL rising_edge(clk); END LOOP; - + verify_en <= '1'; WAIT; END proc_dp_verify_en; - - + + -- Dynamicly depend on first valid data to make verify_en active PROCEDURE proc_dp_verify_en(CONSTANT c_continuous : IN BOOLEAN; SIGNAL clk : IN STD_LOGIC; @@ -1681,7 +1692,7 @@ PACKAGE BODY tb_dp_pkg IS END IF; END IF; END proc_dp_verify_en; - + -- Run and verify for some cycles PROCEDURE proc_dp_verify_run_some_cycles(CONSTANT nof_pre_clk : IN NATURAL; CONSTANT nof_verify_clk : IN NATURAL; @@ -1695,7 +1706,7 @@ PACKAGE BODY tb_dp_pkg IS verify_en <= '0'; proc_common_wait_some_cycles(clk, nof_post_clk); END proc_dp_verify_run_some_cycles; - + ------------------------------------------------------------------------------ -- PROCEDURE: Verify the expected value @@ -1705,7 +1716,7 @@ PACKAGE BODY tb_dp_pkg IS CONSTANT mode : IN t_dp_value_enum; SIGNAL clk : IN STD_LOGIC; SIGNAL en : IN STD_LOGIC; - SIGNAL exp : IN STD_LOGIC_VECTOR; + SIGNAL exp : IN STD_LOGIC_VECTOR; SIGNAL res : IN STD_LOGIC_VECTOR) IS BEGIN IF rising_edge(clk) THEN @@ -1723,16 +1734,16 @@ PACKAGE BODY tb_dp_pkg IS PROCEDURE proc_dp_verify_value(CONSTANT mode : IN t_dp_value_enum; SIGNAL clk : IN STD_LOGIC; SIGNAL en : IN STD_LOGIC; - SIGNAL exp : IN STD_LOGIC_VECTOR; + SIGNAL exp : IN STD_LOGIC_VECTOR; SIGNAL res : IN STD_LOGIC_VECTOR) IS BEGIN proc_dp_verify_value("", mode, clk, en, exp, res); END proc_dp_verify_value; - + PROCEDURE proc_dp_verify_value(CONSTANT c_str : IN STRING; SIGNAL clk : IN STD_LOGIC; SIGNAL en : IN STD_LOGIC; - SIGNAL exp : IN STD_LOGIC; + SIGNAL exp : IN STD_LOGIC; SIGNAL res : IN STD_LOGIC) IS BEGIN IF rising_edge(clk) THEN @@ -1743,7 +1754,7 @@ PACKAGE BODY tb_dp_pkg IS END IF; END IF; END proc_dp_verify_value; - + ------------------------------------------------------------------------------ -- PROCEDURE: Verify output global and local BSN ------------------------------------------------------------------------------ @@ -1751,7 +1762,7 @@ PACKAGE BODY tb_dp_pkg IS -- . incrementing or replicated global BSN -- . incrementing local BSN that starts at 1 -- - -- _ _ _ _ + -- _ _ _ _ -- sync __| |____________| |____________| |____________| |____________ -- _ _ _ _ _ _ _ _ _ _ _ _ -- sop __| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__ c_block_per_sync = 3 @@ -1767,7 +1778,7 @@ PACKAGE BODY tb_dp_pkg IS -- global bsn 3 6 9 12 c_global_bsn_increment = 3, c_nof_replicated_global_bsn = 1 -- global bsn 3 3 9 9 c_global_bsn_increment = 6, c_nof_replicated_global_bsn = 2 -- local bsn - 1 2 - 1 2 - 1 2 - 1 2 range 1:c_block_per_sync-1 - -- + -- -- The verify_en should initially be set to '0' and gets enabled when -- sufficient BSN history is available to do the verification. -- @@ -1833,11 +1844,11 @@ PACKAGE BODY tb_dp_pkg IS END IF; END IF; END proc_dp_verify_bsn; - + ------------------------------------------------------------------------------ -- PROCEDURE: Verify the DUT output data ------------------------------------------------------------------------------ - + -- Verify incrementing data -- . wrap at c_out_data_max when >0, else no wrap when c_out_data_max=0 -- . default increment by 1, but also allow an increment by c_out_data_gap @@ -1876,7 +1887,7 @@ PACKAGE BODY tb_dp_pkg IS END IF; END IF; END proc_dp_verify_data; - + -- Verify incrementing data that wraps in range 0 ... c_out_data_max PROCEDURE proc_dp_verify_data(CONSTANT c_str : IN STRING; CONSTANT c_ready_latency : IN NATURAL; @@ -1890,7 +1901,7 @@ PACKAGE BODY tb_dp_pkg IS BEGIN proc_dp_verify_data(c_str, c_ready_latency, c_out_data_max, TO_UNSIGNED(1,1), clk, verify_en, out_ready, out_val, out_data, prev_out_data); END proc_dp_verify_data; - + -- Verify incrementing data PROCEDURE proc_dp_verify_data(CONSTANT c_str : IN STRING; CONSTANT c_ready_latency : IN NATURAL; @@ -1903,7 +1914,7 @@ PACKAGE BODY tb_dp_pkg IS BEGIN proc_dp_verify_data(c_str, c_ready_latency, TO_UNSIGNED(0,1), TO_UNSIGNED(1,1), clk, verify_en, out_ready, out_val, out_data, prev_out_data); END proc_dp_verify_data; - + -- Verify incrementing data with RL > 0 or no flow control PROCEDURE proc_dp_verify_data(CONSTANT c_str : IN STRING; CONSTANT c_out_data_max : IN UNSIGNED; @@ -1917,7 +1928,7 @@ PACKAGE BODY tb_dp_pkg IS -- Use out_val as void signal to pass on to unused out_ready, because a signal input can not connect a constant or variable proc_dp_verify_data(c_str, 1, c_out_data_max, c_out_data_gap, clk, verify_en, out_val, out_val, out_data, prev_out_data); END proc_dp_verify_data; - + PROCEDURE proc_dp_verify_data(CONSTANT c_str : IN STRING; CONSTANT c_out_data_max : IN NATURAL; CONSTANT c_out_data_gap : IN NATURAL; @@ -1930,7 +1941,7 @@ PACKAGE BODY tb_dp_pkg IS BEGIN proc_dp_verify_data(c_str, TO_UNSIGNED(c_out_data_max, c_data_w), TO_UNSIGNED(c_out_data_gap, c_data_w), clk, verify_en, out_val, out_data, prev_out_data); END proc_dp_verify_data; - + PROCEDURE proc_dp_verify_data(CONSTANT c_str : IN STRING; CONSTANT c_out_data_max : IN NATURAL; SIGNAL clk : IN STD_LOGIC; @@ -1942,7 +1953,7 @@ PACKAGE BODY tb_dp_pkg IS BEGIN proc_dp_verify_data(c_str, TO_UNSIGNED(c_out_data_max, c_data_w), TO_UNSIGNED(1, 1), clk, verify_en, out_val, out_data, prev_out_data); END proc_dp_verify_data; - + PROCEDURE proc_dp_verify_data(CONSTANT c_str : IN STRING; SIGNAL clk : IN STD_LOGIC; SIGNAL verify_en : IN STD_LOGIC; @@ -1953,7 +1964,7 @@ PACKAGE BODY tb_dp_pkg IS -- Use out_val as void signal to pass on to unused out_ready, because a signal input can not connect a constant or variable proc_dp_verify_data(c_str, 1, TO_UNSIGNED(0,1), TO_UNSIGNED(1,1), clk, verify_en, out_val, out_val, out_data, prev_out_data); END proc_dp_verify_data; - + ------------------------------------------------------------------------------ -- PROCEDURE: Verify incrementing symbols in data -- . for c_data_w = c_symbol_w proc_dp_verify_symbols() = proc_dp_verify_data() @@ -2011,8 +2022,8 @@ PACKAGE BODY tb_dp_pkg IS END IF; END IF; END proc_dp_verify_symbols; - - + + ------------------------------------------------------------------------------ -- PROCEDURE: Verify the DUT output data with empty -- . account for stream empty @@ -2098,9 +2109,9 @@ PACKAGE BODY tb_dp_pkg IS END IF; END IF; END IF; - END proc_dp_verify_data_empty; - - + END proc_dp_verify_data_empty; + + ------------------------------------------------------------------------------ -- PROCEDURE: Verify the DUT output other SOSI data -- . Suited to verify the empty, error, channel fields assuming that these @@ -2136,8 +2147,8 @@ PACKAGE BODY tb_dp_pkg IS END IF; END IF; END proc_dp_verify_other_sosi; - - + + ------------------------------------------------------------------------------ -- PROCEDURE: Verify the DUT output valid ------------------------------------------------------------------------------ @@ -2166,7 +2177,7 @@ PACKAGE BODY tb_dp_pkg IS END IF; END IF; END proc_dp_verify_valid; - + PROCEDURE proc_dp_verify_valid(SIGNAL clk : IN STD_LOGIC; SIGNAL verify_en : IN STD_LOGIC; SIGNAL out_ready : IN STD_LOGIC; @@ -2186,7 +2197,7 @@ PACKAGE BODY tb_dp_pkg IS END IF; END IF; END proc_dp_verify_valid; - + ------------------------------------------------------------------------------ -- PROCEDURE: Verify the DUT output sync -- . sync is defined such that it can only be active at sop @@ -2220,7 +2231,80 @@ PACKAGE BODY tb_dp_pkg IS END IF; END IF; END proc_dp_verify_sync; - + + + ------------------------------------------------------------------------------ + -- PROCEDURE: Verify the DUT output sync + -- . sync is defined such that it can only be active at sop + -- . assume that the sync occures priodically at bsn MOD c_sync_period = c_sync_offset + ------------------------------------------------------------------------------ + PROCEDURE proc_dp_verify_sync_v2(CONSTANT c_sync_period : IN NATURAL; -- BSN sync period + CONSTANT c_sync_offset : IN NATURAL; -- BSN sync offset + SIGNAL clk : IN STD_LOGIC; + SIGNAL verify_en : IN STD_LOGIC; + SIGNAL sync : IN STD_LOGIC; + SIGNAL sop : IN STD_LOGIC; + SIGNAL bsn : IN STD_LOGIC_VECTOR; + SIGNAL tb_bsn_cnt : INOUT INTEGER) IS + CONSTANT c_bsn_w : NATURAL := sel_a_b(bsn'LENGTH>31, 31, bsn'LENGTH); -- use maximally 31 bit of BSN slv to allow calculations with integers + + VARIABLE v_valid_sync_period : BOOLEAN; + VARIABLE v_tb_bsn_cnt : INTEGER; + BEGIN + IF rising_edge(clk) THEN + IF verify_en='1' THEN + + v_valid_sync_period := FALSE; + v_tb_bsn_cnt := tb_bsn_cnt; -- assign signal to variable + + -- on sync check if tb_bsn_cnt is a valid value + -- valid is c_sync_period or c_sync_period-1 + IF sync='1' THEN + IF v_tb_bsn_cnt=c_sync_period OR v_tb_bsn_cnt=c_sync_period-1 THEN + v_valid_sync_period := TRUE; + REPORT "bsn count valid " & int_to_str(v_tb_bsn_cnt); + ELSE + v_valid_sync_period := FALSE; + REPORT "bsn count not valid " & int_to_str(v_tb_bsn_cnt) SEVERITY ERROR; + END IF; + + v_tb_bsn_cnt := 0; -- reset tb_bsn_cnt + END IF; + + -- on sop increment tb_bsn_cnt by 1 + IF sop='1' THEN + v_tb_bsn_cnt := v_tb_bsn_cnt + 1; + END IF; + + -- if bsn = 0 (when in dp_off state) set tb_bsn_cnt also to 0 + IF TO_UINT(bsn(c_bsn_w-1 DOWNTO 0)) = 0 THEN + v_tb_bsn_cnt := 0; + END IF; + + tb_bsn_cnt <= v_tb_bsn_cnt; -- assign variable to signal + + -- Check for unexpected sync + IF sync='1' THEN + ASSERT v_valid_sync_period = TRUE + REPORT "Error: Unexpected sync at BSN" SEVERITY ERROR; + ASSERT sop = '1' + REPORT "Error: Unexpected sync at inactive sop" SEVERITY ERROR; + END IF; + -- Check for missing sync + IF sop='1' AND v_valid_sync_period=TRUE THEN + ASSERT sync = '1' + REPORT "Error: Missing sync" SEVERITY ERROR; + END IF; + -- Check for missing sync + IF sop='1' THEN + ASSERT v_tb_bsn_cnt <= c_sync_period + REPORT "Error: bsn count " & int_to_str(v_tb_bsn_cnt) & " > " & int_to_str(c_sync_period) SEVERITY ERROR; + END IF; + + END IF; + END IF; + END proc_dp_verify_sync_v2; + ------------------------------------------------------------------------------ -- PROCEDURE: Verify the DUT output sop and eop @@ -2263,7 +2347,7 @@ PACKAGE BODY tb_dp_pkg IS END IF; END IF; END proc_dp_verify_sop_and_eop; - + PROCEDURE proc_dp_verify_sop_and_eop(CONSTANT c_ready_latency : IN NATURAL; SIGNAL clk : IN STD_LOGIC; SIGNAL out_ready : IN STD_LOGIC; @@ -2274,7 +2358,7 @@ PACKAGE BODY tb_dp_pkg IS BEGIN proc_dp_verify_sop_and_eop(c_ready_latency, TRUE, clk, out_ready, out_val, out_sop, out_eop, hold_sop); END proc_dp_verify_sop_and_eop; - + PROCEDURE proc_dp_verify_sop_and_eop(SIGNAL clk : IN STD_LOGIC; SIGNAL out_val : IN STD_LOGIC; SIGNAL out_sop : IN STD_LOGIC; @@ -2284,10 +2368,10 @@ PACKAGE BODY tb_dp_pkg IS -- Use out_val as void signal to pass on to unused out_ready, because a signal input can not connect a constant or variable proc_dp_verify_sop_and_eop(1, TRUE, clk, out_val, out_val, out_sop, out_eop, hold_sop); END proc_dp_verify_sop_and_eop; - + PROCEDURE proc_dp_verify_block_size(CONSTANT c_ready_latency : IN NATURAL; SIGNAL alt_size : IN NATURAL; -- alternative size - SIGNAL exp_size : IN NATURAL; -- expected size + SIGNAL exp_size : IN NATURAL; -- expected size SIGNAL clk : IN STD_LOGIC; SIGNAL out_ready : IN STD_LOGIC; SIGNAL out_val : IN STD_LOGIC; @@ -2314,7 +2398,7 @@ PACKAGE BODY tb_dp_pkg IS END IF; END IF; END proc_dp_verify_block_size; - + PROCEDURE proc_dp_verify_block_size(CONSTANT c_ready_latency : IN NATURAL; SIGNAL exp_size : IN NATURAL; SIGNAL clk : IN STD_LOGIC; @@ -2326,9 +2410,9 @@ PACKAGE BODY tb_dp_pkg IS BEGIN proc_dp_verify_block_size(c_ready_latency, exp_size, exp_size, clk, out_ready, out_val, out_sop, out_eop, cnt_size); END proc_dp_verify_block_size; - + PROCEDURE proc_dp_verify_block_size(SIGNAL alt_size : IN NATURAL; -- alternative size - SIGNAL exp_size : IN NATURAL; -- expected size + SIGNAL exp_size : IN NATURAL; -- expected size SIGNAL clk : IN STD_LOGIC; SIGNAL out_val : IN STD_LOGIC; SIGNAL out_sop : IN STD_LOGIC; @@ -2338,7 +2422,7 @@ PACKAGE BODY tb_dp_pkg IS -- Use out_val as void signal to pass on to unused out_ready, because a signal input can not connect a constant or variable proc_dp_verify_block_size(1, alt_size, exp_size, clk, out_val, out_val, out_sop, out_eop, cnt_size); END proc_dp_verify_block_size; - + PROCEDURE proc_dp_verify_block_size(SIGNAL exp_size : IN NATURAL; SIGNAL clk : IN STD_LOGIC; SIGNAL out_val : IN STD_LOGIC; @@ -2349,7 +2433,7 @@ PACKAGE BODY tb_dp_pkg IS -- Use out_val as void signal to pass on to unused out_ready, because a signal input can not connect a constant or variable proc_dp_verify_block_size(1, exp_size, exp_size, clk, out_val, out_val, out_sop, out_eop, cnt_size); END proc_dp_verify_block_size; - + ------------------------------------------------------------------------------ -- PROCEDURE: Verify the DUT output invalid between frames ------------------------------------------------------------------------------ @@ -2369,8 +2453,8 @@ PACKAGE BODY tb_dp_pkg IS END IF; END IF; END proc_dp_verify_gap_invalid; - - + + ------------------------------------------------------------------------------ -- PROCEDURE: Verify the DUT output control (use for sop, eop) ------------------------------------------------------------------------------ @@ -2399,8 +2483,8 @@ PACKAGE BODY tb_dp_pkg IS END IF; END IF; END proc_dp_verify_ctrl; - - + + ------------------------------------------------------------------------------ -- PROCEDURE: Wait for stream valid ------------------------------------------------------------------------------ @@ -2412,8 +2496,8 @@ PACKAGE BODY tb_dp_pkg IS WAIT UNTIL rising_edge(clk); END LOOP; END proc_dp_stream_valid; - - + + ------------------------------------------------------------------------------ -- PROCEDURE: Wait for stream valid AND sop ------------------------------------------------------------------------------ @@ -2427,7 +2511,7 @@ PACKAGE BODY tb_dp_pkg IS END LOOP; END proc_dp_stream_valid_sop; - + ------------------------------------------------------------------------------ -- PROCEDURE: Wait for stream valid AND eop ------------------------------------------------------------------------------ @@ -2440,5 +2524,5 @@ PACKAGE BODY tb_dp_pkg IS WAIT UNTIL rising_edge(clk); END LOOP; END proc_dp_stream_valid_eop; - + END tb_dp_pkg; diff --git a/libraries/base/dp/tb/vhdl/tb_mms_dp_bsn_source_v2.vhd b/libraries/base/dp/tb/vhdl/tb_mms_dp_bsn_source_v2.vhd index 56046797b6a8281aee5b1bfce3690886c28a9613..5984c4d6af1551d1a1cc1177eb6b084105fdc858 100644 --- a/libraries/base/dp/tb/vhdl/tb_mms_dp_bsn_source_v2.vhd +++ b/libraries/base/dp/tb/vhdl/tb_mms_dp_bsn_source_v2.vhd @@ -161,7 +161,7 @@ BEGIN GENERIC MAP ( g_cross_clock_domain => TRUE, -- use FALSE when mm_clk and st_clk are the same, else use TRUE to cross the clock domain g_block_size => c_block_size, - g_nof_block_per_sync => 1, -- overrule via MM write + g_nof_clk_per_sync => 200 * 10**6, -- overrule via MM write g_bsn_w => c_dp_stream_bsn_w ) PORT MAP (