diff --git a/libraries/base/dp/hdllib.cfg b/libraries/base/dp/hdllib.cfg index 0e9754f649d3f7b116ad9af03bb8287ad68f6267..9cc984efdde5e083ce57a73815e6cb4d062c570b 100644 --- a/libraries/base/dp/hdllib.cfg +++ b/libraries/base/dp/hdllib.cfg @@ -86,12 +86,13 @@ synth_files = src/vhdl/dp_bsn_source_v2.vhd src/vhdl/dp_bsn_source_reg.vhd src/vhdl/dp_bsn_source_reg_v2.vhd - src/vhdl/dp_bsn_sync_scheduler.vhd src/vhdl/mms_dp_bsn_source.vhd src/vhdl/mms_dp_bsn_source_v2.vhd src/vhdl/dp_bsn_scheduler.vhd src/vhdl/dp_bsn_scheduler_reg.vhd src/vhdl/mms_dp_bsn_scheduler.vhd + src/vhdl/dp_bsn_sync_scheduler.vhd + src/vhdl/mmp_dp_bsn_sync_scheduler.vhd src/vhdl/dp_bsn_delay.vhd src/vhdl/dp_bsn_align.vhd src/vhdl/dp_bsn_align_reg.vhd @@ -216,6 +217,7 @@ test_bench_files = tb/vhdl/tb_mms_dp_bsn_source.vhd tb/vhdl/tb_mms_dp_bsn_source_v2.vhd tb/vhdl/tb_dp_bsn_sync_scheduler.vhd + tb/vhdl/tb_mmp_dp_bsn_sync_scheduler.vhd tb/vhdl/tb_dp_demux.vhd tb/vhdl/tb2_dp_demux.vhd tb/vhdl/tb3_dp_demux.vhd @@ -350,7 +352,7 @@ regression_test_vhdl = tb/vhdl/tb_dp_bsn_source.vhd tb/vhdl/tb_mms_dp_bsn_source.vhd tb/vhdl/tb_mms_dp_bsn_source_v2.vhd - tb/vhdl/tb_tb_dp_bsn_sync_scheduler.vhd + tb/vhdl/tb_mmp_dp_bsn_sync_scheduler.vhd tb/vhdl/tb_tb_dp_block_select.vhd tb/vhdl/tb_tb_dp_block_validate_length.vhd tb/vhdl/tb_tb_dp_block_validate_err.vhd @@ -363,6 +365,7 @@ regression_test_vhdl = tb/vhdl/tb_tb_dp_block_validate_channel.vhd tb/vhdl/tb_tb_dp_bsn_align.vhd tb/vhdl/tb_tb_dp_bsn_source_v2.vhd + tb/vhdl/tb_tb_dp_bsn_sync_scheduler.vhd tb/vhdl/tb_tb_dp_concat.vhd tb/vhdl/tb_tb_dp_demux.vhd tb/vhdl/tb_tb2_dp_demux.vhd diff --git a/libraries/base/dp/src/vhdl/mmp_dp_bsn_sync_scheduler.vhd b/libraries/base/dp/src/vhdl/mmp_dp_bsn_sync_scheduler.vhd new file mode 100644 index 0000000000000000000000000000000000000000..6a6a367230f3b0d1a1f31d40336ee8212e75a42f --- /dev/null +++ b/libraries/base/dp/src/vhdl/mmp_dp_bsn_sync_scheduler.vhd @@ -0,0 +1,214 @@ +-- -------------------------------------------------------------------------- +-- 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 : E. Kooistra, 6 aug 2021 +-- Purpose : MM peripheral interface for dp_bsn_sync_scheduler.vhd +-- Description: MM port register logic +-- +-- wi Bits Access Type Name +-- 0 [0] RW boolean ctrl_enable, '1' is on, '0' is FALSE is off +-- 1 [31:0] RW uint32 ctrl_interval_size +-- 2 [31:0] RW uint64 ctrl_start_bsn[31:0] +-- 3 [31:0] RW ctrl_start_bsn[63:32] +-- 4 [31:0] RO uint64 mon_current_input_bsn[31:0] +-- 5 [31:0] RO mon_current_input_bsn[63:32] +-- 6 [31:0] RO uint64 mon_input_bsn_at_sync[31:0] +-- 7 [31:0] RO mon_input_bsn_at_sync[63:32] +-- 8 [0] RO boolean mon_output_enable, '1' is on, '0' is FALSE is off +-- 9 [31:0] RO uint64 mon_output_sync_bsn[31:0] +-- 10 [31:0] RO mon_output_sync_bsn[63:32] +-- +-- * Do not use reg_wr_arr[0] in dp_clk domain to detect ctrl_enable_evt, +-- because reg_wr_arr pulses occur before the reg_wr data arrives in the +-- dp_clk domain. Therefore instead use change in wr_ctrl_enable value +-- to detect ctrl_enable_evt. Hence a re-enable via MM now requires a +-- disable via MM first. +-- +-- Remarks: +-- * The actual bsn width is constrained by g_bsn_w. +-- * The MM interface accesses 64 bit words in two 32 bit MM word accesses. +-- This can result in a BSN value that is wrong if it happens to have +-- an increment carry from the low word to the high word. The BSN carry +-- occurs after every 2**32 blocks, so e.g. with a block period of 5.12 us +-- this is once every 6.1 hours. It is very unlikely that this will cause +-- a problem and if it does then a next attempt will succeed. Therefore +-- it is not necessary to ensure that the 64 values are accesses more +-- robustly (e.g. by only accepting them when the high word is accessed), +-- and therefore it is fine to use common_reg_r_w_dc for 64 bit BSN words. +-- + +LIBRARY IEEE, common_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; +USE work.dp_stream_pkg.ALL; + + +ENTITY mmp_dp_bsn_sync_scheduler IS + GENERIC ( + g_bsn_w : NATURAL := c_dp_stream_bsn_w; + g_block_size : NATURAL := 256 -- = number of data valid per BSN block, must be >= 2 + ); + 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 control + reg_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_miso : OUT t_mem_miso; + + -- Streaming + in_sosi : IN t_dp_sosi; + out_sosi : OUT t_dp_sosi; + out_start : OUT STD_LOGIC; + out_enable : OUT STD_LOGIC + ); +END mmp_dp_bsn_sync_scheduler; + +ARCHITECTURE str OF mmp_dp_bsn_sync_scheduler IS + + -- TYPE t_c_mem IS RECORD + -- latency : NATURAL; -- read latency + -- adr_w : NATURAL; + -- dat_w : NATURAL; + -- nof_dat : NATURAL; -- optional, nof dat words <= 2**adr_w + -- init_sl : STD_LOGIC; -- optional, init all dat words to std_logic '0', '1' or 'X' + CONSTANT c_mm_reg : t_c_mem := (1, 4, c_word_w, 11, '0'); + + SIGNAL reg_wr_arr : STD_LOGIC_VECTOR(c_mm_reg.nof_dat -1 DOWNTO 0); + SIGNAL reg_wr : STD_LOGIC_VECTOR(c_mm_reg.nof_dat*c_mm_reg.dat_w-1 DOWNTO 0); + SIGNAL reg_rd : STD_LOGIC_VECTOR(c_mm_reg.nof_dat*c_mm_reg.dat_w-1 DOWNTO 0) := (OTHERS=>'0'); + + SIGNAL wr_ctrl_enable : STD_LOGIC; + SIGNAL wr_ctrl_enable_evt : STD_LOGIC; + SIGNAL ctrl_enable : STD_LOGIC := '0'; + SIGNAL ctrl_enable_evt : STD_LOGIC := '0'; + SIGNAL ctrl_interval_size : NATURAL; + SIGNAL ctrl_start_bsn : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0) := (OTHERS=>'0'); + SIGNAL mon_current_input_bsn : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0); + SIGNAL mon_input_bsn_at_sync : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0); + SIGNAL mon_output_enable : STD_LOGIC; + SIGNAL mon_output_sync_bsn : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0); + + -- Resize BSN values to 64 bit + SIGNAL wr_start_bsn_64 : STD_LOGIC_VECTOR(2*c_word_w-1 DOWNTO 0); + SIGNAL rd_current_input_bsn_64 : STD_LOGIC_VECTOR(2*c_word_w-1 DOWNTO 0); + SIGNAL rd_input_bsn_at_sync_64 : STD_LOGIC_VECTOR(2*c_word_w-1 DOWNTO 0); + SIGNAL rd_output_sync_bsn_64 : STD_LOGIC_VECTOR(2*c_word_w-1 DOWNTO 0); + +BEGIN + + ctrl_start_bsn <= wr_start_bsn_64(g_bsn_w-1 DOWNTO 0); + + rd_current_input_bsn_64 <= RESIZE_UVEC(mon_current_input_bsn, 2*c_word_w); + rd_input_bsn_at_sync_64 <= RESIZE_UVEC(mon_input_bsn_at_sync, 2*c_word_w); + rd_output_sync_bsn_64 <= RESIZE_UVEC(mon_output_sync_bsn, 2*c_word_w); + + -- Register mapping + -- . Write + wr_ctrl_enable <= reg_wr( 0); + ctrl_interval_size <= TO_UINT(reg_wr( 2*c_word_w-1 DOWNTO 1*c_word_w)); + wr_start_bsn_64( c_word_w-1 DOWNTO 0) <= reg_wr( 3*c_word_w-1 DOWNTO 2*c_word_w); -- low word + wr_start_bsn_64(2*c_word_w-1 DOWNTO 1*c_word_w) <= reg_wr( 4*c_word_w-1 DOWNTO 3*c_word_w); -- high word + + -- Derive ctrl_enable_evt from change in wr_ctrl_enable, instead of using + -- reg_wr_arr(0), see description + u_common_evt : ENTITY common_lib.common_evt + GENERIC MAP ( + g_evt_type => "BOTH", + g_out_reg => TRUE + ) + PORT MAP ( + rst => dp_rst, + clk => dp_clk, + in_sig => wr_ctrl_enable, + out_evt => wr_ctrl_enable_evt + ); + + ctrl_enable <= wr_ctrl_enable WHEN rising_edge(dp_clk) AND wr_ctrl_enable_evt = '1'; + ctrl_enable_evt <= wr_ctrl_enable_evt WHEN rising_edge(dp_clk); + + -- . Read + reg_rd( 0) <= ctrl_enable; -- read back internal ctrl_enable + reg_rd( 2*c_word_w-1 DOWNTO 1*c_word_w) <= TO_UVEC(ctrl_interval_size, c_word_w); + reg_rd( 3*c_word_w-1 DOWNTO 2*c_word_w) <= wr_start_bsn_64( c_word_w-1 DOWNTO 0); -- low word + reg_rd( 4*c_word_w-1 DOWNTO 3*c_word_w) <= wr_start_bsn_64( 2*c_word_w-1 DOWNTO c_word_w); -- high word + reg_rd( 5*c_word_w-1 DOWNTO 4*c_word_w) <= rd_current_input_bsn_64( c_word_w-1 DOWNTO 0); -- low word + reg_rd( 6*c_word_w-1 DOWNTO 5*c_word_w) <= rd_current_input_bsn_64(2*c_word_w-1 DOWNTO c_word_w); -- high word + reg_rd( 7*c_word_w-1 DOWNTO 6*c_word_w) <= rd_input_bsn_at_sync_64( c_word_w-1 DOWNTO 0); -- low word + reg_rd( 8*c_word_w-1 DOWNTO 7*c_word_w) <= rd_input_bsn_at_sync_64(2*c_word_w-1 DOWNTO c_word_w); -- high word + reg_rd( 8*c_word_w) <= mon_output_enable; + reg_rd(10*c_word_w-1 DOWNTO 9*c_word_w) <= rd_output_sync_bsn_64( c_word_w-1 DOWNTO 0); -- low word + reg_rd(11*c_word_w-1 DOWNTO 10*c_word_w) <= rd_output_sync_bsn_64( 2*c_word_w-1 DOWNTO c_word_w); -- high word + + 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_mm_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 => reg_wr_arr, + reg_rd_arr => OPEN, + out_reg => reg_wr, -- readback via ST clock domain + in_reg => reg_rd + ); + + u_dp_bsn_sync_scheduler : ENTITY work.dp_bsn_sync_scheduler + GENERIC MAP ( + g_bsn_w => g_bsn_w, + g_block_size => g_block_size, + g_pipeline => 1 + ) + PORT MAP ( + rst => dp_rst, + clk => dp_clk, + + -- M&C + ctrl_enable => ctrl_enable, + ctrl_enable_evt => ctrl_enable_evt, + ctrl_interval_size => ctrl_interval_size, + ctrl_start_bsn => ctrl_start_bsn, + mon_current_input_bsn => mon_current_input_bsn, + mon_input_bsn_at_sync => mon_input_bsn_at_sync, + mon_output_enable => mon_output_enable, + mon_output_sync_bsn => mon_output_sync_bsn, + + -- Streaming + in_sosi => in_sosi, + out_sosi => out_sosi, + out_start => out_start, + out_enable => out_enable + ); + +END str; + diff --git a/libraries/base/dp/tb/vhdl/tb_dp_bsn_sync_scheduler.vhd b/libraries/base/dp/tb/vhdl/tb_dp_bsn_sync_scheduler.vhd index 6ce8ab3ad0c35044bf61dab3bb03a52eb2bcde9e..a94570c92e294b528d12f0d07819f6dad441fb7e 100644 --- a/libraries/base/dp/tb/vhdl/tb_dp_bsn_sync_scheduler.vhd +++ b/libraries/base/dp/tb/vhdl/tb_dp_bsn_sync_scheduler.vhd @@ -1,24 +1,22 @@ ------------------------------------------------------------------------------- --- --- Copyright (C) 2011 +-- -------------------------------------------------------------------------- +-- Copyright 2021 -- 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. +-- 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 -- --- 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. +-- http://www.apache.org/licenses/LICENSE-2.0 -- --- You should have received a copy of the GNU General Public License --- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- 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: Eric Kooistra -- Purpose: Test bench for dp_bsn_sync_scheduler.vhd -- Description: @@ -57,8 +55,8 @@ -- fractional sync intervals -- g Add verification of mon_output_sync_bsn (p_verify_mon_output_sync_bsn) -- 3a Add tb generics and tb_tb_dp_bsn_sync_scheduler.vhd --- 4a Add mmc_dp_bsn_sync_scheduler.vhd with MM register and --- tb_mmc_dp_bsn_sync_scheduler.vhd that verifies only the MM part, +-- 4a Add mmp_dp_bsn_sync_scheduler.vhd with MM register and +-- tb_mmp_dp_bsn_sync_scheduler.vhd that verifies only the MM part, -- because the sync part is already verified by -- tb_tb_dp_bsn_sync_scheduler.vhd. -- 5a For all ASSERTs, verify that the ERROR or FAILURE can occur by e.g. diff --git a/libraries/base/dp/tb/vhdl/tb_mmp_dp_bsn_sync_scheduler.vhd b/libraries/base/dp/tb/vhdl/tb_mmp_dp_bsn_sync_scheduler.vhd new file mode 100644 index 0000000000000000000000000000000000000000..acee0b57c9f314a4600a91edad10d8a266b9d117 --- /dev/null +++ b/libraries/base/dp/tb/vhdl/tb_mmp_dp_bsn_sync_scheduler.vhd @@ -0,0 +1,330 @@ +-- -------------------------------------------------------------------------- +-- 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: E. Kooistra, 6 aug 2021 +-- Purpose: Verify MM part of mmp_dp_bsn_sync_scheduler +-- Description: +-- The functional part is already verified by tb_tb_dp_bsn_sync_scheduler.vhd. +-- Usage: +-- > as 5 +-- > run -all + + +LIBRARY IEEE, common_lib, technology_lib; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.tb_common_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; +USE common_lib.tb_common_mem_pkg.ALL; +USE common_lib.common_str_pkg.ALL; +USE work.dp_stream_pkg.ALL; +USE work.tb_dp_pkg.ALL; + +ENTITY tb_mmp_dp_bsn_sync_scheduler IS +END tb_mmp_dp_bsn_sync_scheduler; + + +ARCHITECTURE tb OF tb_mmp_dp_bsn_sync_scheduler IS + + CONSTANT c_mm_clk_period : TIME := 40 ns; + CONSTANT c_dp_clk_period : TIME := 10 ns; + CONSTANT c_cross_clock_domain_latency : NATURAL := 20; + + CONSTANT c_nof_input_sync : NATURAL := 5; + CONSTANT c_nof_block_per_input_sync : NATURAL := 17; + CONSTANT c_nof_block_per_output_sync : NATURAL := 5; + CONSTANT c_block_size : NATURAL := 10; + CONSTANT c_input_gap_size : NATURAL := 3; + CONSTANT c_sim_nof_blocks : NATURAL := c_nof_block_per_input_sync * c_nof_input_sync; + + -- DUT settings + CONSTANT c_bsn_w : NATURAL := 40; + CONSTANT c_ctrl_interval_size : NATURAL := c_nof_block_per_output_sync * c_block_size; + CONSTANT c_ctrl_start_bsn_lo : NATURAL := 19; + CONSTANT c_ctrl_start_bsn_hi : NATURAL := 17; + + SIGNAL tb_end : STD_LOGIC := '0'; + SIGNAL stimuli_end : STD_LOGIC := '0'; + SIGNAL mm_clk : STD_LOGIC := '1'; + SIGNAL mm_rst : STD_LOGIC := '1'; + SIGNAL dp_clk : STD_LOGIC := '1'; + SIGNAL dp_rst : STD_LOGIC := '1'; + + SIGNAL reg_mosi : t_mem_mosi := c_mem_mosi_rst; + SIGNAL reg_miso : t_mem_miso; + + SIGNAL ctrl_start_bsn_64 : STD_LOGIC_VECTOR(2*c_word_w-1 DOWNTO 0); + + SIGNAL mon_output_enable : STD_LOGIC; + SIGNAL mon_current_input_bsn_64 : STD_LOGIC_VECTOR(2*c_word_w-1 DOWNTO 0); + SIGNAL mon_input_bsn_at_sync_64 : STD_LOGIC_VECTOR(2*c_word_w-1 DOWNTO 0); + SIGNAL mon_output_sync_bsn_64 : STD_LOGIC_VECTOR(2*c_word_w-1 DOWNTO 0); + + SIGNAL stimuli_sosi : t_dp_sosi; + SIGNAL out_sosi : t_dp_sosi; + SIGNAL out_start : STD_LOGIC; + SIGNAL out_enable : STD_LOGIC; + +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; + dp_rst <= '1', '0' AFTER c_dp_clk_period*7; + mm_rst <= '1', '0' AFTER c_mm_clk_period*7; + + ------------------------------------------------------------------------------ + -- MM stimuli and verification + ------------------------------------------------------------------------------ + + p_stimuli_and_verify_mm : PROCESS + VARIABLE v_bsn : NATURAL; + BEGIN + proc_common_wait_until_low(dp_clk, mm_rst); + proc_common_wait_until_low(dp_clk, dp_rst); + proc_common_wait_some_cycles(mm_clk, 5); + + --------------------------------------------------------------------------- + -- Initial check + --------------------------------------------------------------------------- + -- . Read mon_output_enable + proc_mem_mm_bus_rd(8, mm_clk, reg_miso, reg_mosi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + mon_output_enable <= reg_miso.rddata(0); + + -- . Verify output is off + proc_common_wait_some_cycles(mm_clk, 1); + ASSERT mon_output_enable = '0' REPORT "DUT output is enabled." SEVERITY ERROR; + + --------------------------------------------------------------------------- + -- Verify c_ctrl_start_bsn_hi + --------------------------------------------------------------------------- + + -- . Write ctrl_start_bsn + proc_mem_mm_bus_wr(2, c_ctrl_start_bsn_lo, mm_clk, reg_miso, reg_mosi); + proc_mem_mm_bus_wr(3, c_ctrl_start_bsn_hi, mm_clk, reg_miso, reg_mosi); + proc_common_wait_some_cycles(mm_clk, c_cross_clock_domain_latency); + proc_common_wait_some_cycles(dp_clk, c_cross_clock_domain_latency); + + -- . Read back ctrl_start_bsn + proc_mem_mm_bus_rd(2, mm_clk, reg_miso, reg_mosi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + ctrl_start_bsn_64(c_word_w-1 DOWNTO 0) <= reg_miso.rddata(c_word_w-1 DOWNTO 0); + proc_mem_mm_bus_rd(3, mm_clk, reg_miso, reg_mosi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + ctrl_start_bsn_64(2*c_word_w-1 DOWNTO c_word_w) <= reg_miso.rddata(c_word_w-1 DOWNTO 0); + + proc_common_wait_some_cycles(mm_clk, 1); + ASSERT c_ctrl_start_bsn_lo = TO_UINT(ctrl_start_bsn_64( c_word_w-1 DOWNTO 0)) REPORT "Wrong ctrl_start_bsn low word." SEVERITY ERROR; + ASSERT c_ctrl_start_bsn_hi = TO_UINT(ctrl_start_bsn_64(2*c_word_w-1 DOWNTO c_word_w)) REPORT "Wrong ctrl_start_bsn high word." SEVERITY ERROR; + + --------------------------------------------------------------------------- + -- Setup, enable and verify DUT output + --------------------------------------------------------------------------- + -- . Read mon_current_input_bsn_64 + proc_mem_mm_bus_rd(4, mm_clk, reg_miso, reg_mosi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + mon_current_input_bsn_64(c_word_w-1 DOWNTO 0) <= reg_miso.rddata(c_word_w-1 DOWNTO 0); + proc_mem_mm_bus_rd(5, mm_clk, reg_miso, reg_mosi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + mon_current_input_bsn_64(2*c_word_w-1 DOWNTO c_word_w) <= reg_miso.rddata(c_word_w-1 DOWNTO 0); + proc_common_wait_some_cycles(mm_clk, 1); + + -- . Select start BSN in the future + v_bsn := TO_UINT(mon_current_input_bsn_64) + 20; + + -- . Setup output sync interval + proc_mem_mm_bus_wr(1, c_ctrl_interval_size, mm_clk, reg_miso, reg_mosi); + proc_mem_mm_bus_wr(2, v_bsn, mm_clk, reg_miso, reg_mosi); + proc_mem_mm_bus_wr(3, 0, mm_clk, reg_miso, reg_mosi); + proc_common_wait_some_cycles(dp_clk, c_block_size*10); + + -- . Enable output + proc_mem_mm_bus_wr(0, 1, mm_clk, reg_miso, reg_mosi); + proc_common_wait_some_cycles(mm_clk, c_cross_clock_domain_latency); + proc_common_wait_some_cycles(dp_clk, c_cross_clock_domain_latency); + + proc_common_wait_some_cycles(dp_clk, c_block_size*10); + + -- . Read back ctrl_start_bsn + proc_mem_mm_bus_rd(2, mm_clk, reg_miso, reg_mosi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + ctrl_start_bsn_64(c_word_w-1 DOWNTO 0) <= reg_miso.rddata(c_word_w-1 DOWNTO 0); + proc_mem_mm_bus_rd(3, mm_clk, reg_miso, reg_mosi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + ctrl_start_bsn_64(2*c_word_w-1 DOWNTO c_word_w) <= reg_miso.rddata(c_word_w-1 DOWNTO 0); + + -- . Read mon_current_input_bsn_64 + proc_mem_mm_bus_rd(4, mm_clk, reg_miso, reg_mosi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + mon_current_input_bsn_64(c_word_w-1 DOWNTO 0) <= reg_miso.rddata(c_word_w-1 DOWNTO 0); + proc_mem_mm_bus_rd(5, mm_clk, reg_miso, reg_mosi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + mon_current_input_bsn_64(2*c_word_w-1 DOWNTO c_word_w) <= reg_miso.rddata(c_word_w-1 DOWNTO 0); + + -- . Read mon_input_bsn_at_sync_64 + proc_mem_mm_bus_rd(6, mm_clk, reg_miso, reg_mosi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + mon_input_bsn_at_sync_64(c_word_w-1 DOWNTO 0) <= reg_miso.rddata(c_word_w-1 DOWNTO 0); + proc_mem_mm_bus_rd(7, mm_clk, reg_miso, reg_mosi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + mon_input_bsn_at_sync_64(2*c_word_w-1 DOWNTO c_word_w) <= reg_miso.rddata(c_word_w-1 DOWNTO 0); + + -- . Read mon_output_sync_bsn_64 + proc_mem_mm_bus_rd(9, mm_clk, reg_miso, reg_mosi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + mon_output_sync_bsn_64(c_word_w-1 DOWNTO 0) <= reg_miso.rddata(c_word_w-1 DOWNTO 0); + proc_mem_mm_bus_rd(10, mm_clk, reg_miso, reg_mosi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + mon_output_sync_bsn_64(2*c_word_w-1 DOWNTO c_word_w) <= reg_miso.rddata(c_word_w-1 DOWNTO 0); + + -- . Read mon_output_enable + proc_mem_mm_bus_rd(8, mm_clk, reg_miso, reg_mosi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + mon_output_enable <= reg_miso.rddata(0); + + -- Verify output is on and running + proc_common_wait_some_cycles(mm_clk, 1); + ASSERT mon_output_enable = '1' REPORT "mon_output_enable is not enabled." SEVERITY ERROR; + ASSERT out_enable = '1' REPORT "output_enable is not enabled." SEVERITY ERROR; + + --------------------------------------------------------------------------- + -- Check that monitor BSN are incrementing + --------------------------------------------------------------------------- + proc_common_wait_some_cycles(mm_clk, c_ctrl_interval_size * 3); + + -- . Check mon_current_input_bsn_64 + v_bsn := TO_UINT(mon_current_input_bsn_64); + proc_mem_mm_bus_rd(4, mm_clk, reg_miso, reg_mosi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + mon_current_input_bsn_64(c_word_w-1 DOWNTO 0) <= reg_miso.rddata(c_word_w-1 DOWNTO 0); + proc_mem_mm_bus_rd(5, mm_clk, reg_miso, reg_mosi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + mon_current_input_bsn_64(2*c_word_w-1 DOWNTO c_word_w) <= reg_miso.rddata(c_word_w-1 DOWNTO 0); + proc_common_wait_some_cycles(mm_clk, 1); + REPORT "mon_current_input_bsn : " & int_to_str(v_bsn) & ", " & int_to_str(TO_UINT(mon_current_input_bsn_64)) SEVERITY NOTE; + ASSERT v_bsn < TO_UINT(mon_current_input_bsn_64) REPORT "DUT mon_current_input_bsn is not incrementing." SEVERITY ERROR; + + -- . Check mon_input_bsn_at_sync_64 + v_bsn := TO_UINT(mon_input_bsn_at_sync_64); + proc_mem_mm_bus_rd(6, mm_clk, reg_miso, reg_mosi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + mon_input_bsn_at_sync_64(c_word_w-1 DOWNTO 0) <= reg_miso.rddata(c_word_w-1 DOWNTO 0); + proc_mem_mm_bus_rd(7, mm_clk, reg_miso, reg_mosi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + mon_input_bsn_at_sync_64(2*c_word_w-1 DOWNTO c_word_w) <= reg_miso.rddata(c_word_w-1 DOWNTO 0); + proc_common_wait_some_cycles(mm_clk, 1); + REPORT "mon_input_bsn_at_sync : " & int_to_str(v_bsn) & ", " & int_to_str(TO_UINT(mon_input_bsn_at_sync_64)) SEVERITY NOTE; + ASSERT v_bsn < TO_UINT(mon_input_bsn_at_sync_64) REPORT "DUT mon_input_bsn_at_sync is not incrementing." SEVERITY ERROR; + ASSERT (TO_UINT(mon_input_bsn_at_sync_64) - v_bsn) MOD c_nof_block_per_input_sync = 0 REPORT "TB input_sync interval is not correct." SEVERITY ERROR; + + -- . Check mon_output_sync_bsn_64 + v_bsn := TO_UINT(mon_output_sync_bsn_64); + proc_mem_mm_bus_rd(9, mm_clk, reg_miso, reg_mosi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + mon_output_sync_bsn_64(c_word_w-1 DOWNTO 0) <= reg_miso.rddata(c_word_w-1 DOWNTO 0); + proc_mem_mm_bus_rd(10, mm_clk, reg_miso, reg_mosi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + mon_output_sync_bsn_64(2*c_word_w-1 DOWNTO c_word_w) <= reg_miso.rddata(c_word_w-1 DOWNTO 0); + proc_common_wait_some_cycles(mm_clk, 1); + REPORT "mon_output_sync_bsn : " & int_to_str(v_bsn) & ", " & int_to_str(TO_UINT(mon_output_sync_bsn_64)) SEVERITY NOTE; + ASSERT v_bsn < TO_UINT(mon_output_sync_bsn_64) REPORT "DUT mon_output_sync_bsn is not incrementing." SEVERITY ERROR; + ASSERT (TO_UINT(mon_output_sync_bsn_64) - v_bsn) MOD c_nof_block_per_output_sync = 0 REPORT "DUT output_sync interval is not correct." SEVERITY ERROR; + + --------------------------------------------------------------------------- + -- Disable and verify DUT output + --------------------------------------------------------------------------- + + -- . Disable output + proc_mem_mm_bus_wr(0, 0, mm_clk, reg_miso, reg_mosi); + proc_common_wait_some_cycles(mm_clk, c_cross_clock_domain_latency); + proc_common_wait_some_cycles(dp_clk, c_cross_clock_domain_latency); + + proc_common_wait_some_cycles(dp_clk, c_block_size*10); + + -- . Read mon_output_enable + proc_mem_mm_bus_rd(8, mm_clk, reg_miso, reg_mosi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + mon_output_enable <= reg_miso.rddata(0); + + -- Verify output is on and running + proc_common_wait_some_cycles(mm_clk, 1); + ASSERT mon_output_enable = '0' REPORT "DUT mon_output_enable is not diabled." SEVERITY ERROR; + ASSERT out_enable = '0' REPORT "DUT output_enable is not enabled." SEVERITY ERROR; + + proc_common_wait_until_high(dp_clk, stimuli_end); + tb_end <= '1'; + WAIT; + END PROCESS; + + + ------------------------------------------------------------------------------ + -- Streaming stimuli + ------------------------------------------------------------------------------ + + -- Generate data blocks with input sync + u_stimuli : ENTITY work.dp_stream_stimuli + GENERIC MAP ( + g_sync_period => c_nof_block_per_input_sync, + g_err_init => 0, + g_err_incr => 0, -- do not increment, to not distract from viewing of BSN in Wave window + g_channel_init => 0, + g_channel_incr => 0, -- do not increment, to not distract from viewing of BSN in Wave window + g_nof_repeat => c_sim_nof_blocks, + g_pkt_len => c_block_size, + g_pkt_gap => c_input_gap_size + ) + PORT MAP ( + rst => dp_rst, + clk => dp_clk, + + -- Generate stimuli + src_out => stimuli_sosi, + + -- End of stimuli + tb_end => stimuli_end + ); + + ------------------------------------------------------------------------------ + -- DUT + ------------------------------------------------------------------------------ + + u_mmp_dp_bsn_sync_scheduler : ENTITY work.mmp_dp_bsn_sync_scheduler + GENERIC MAP ( + g_bsn_w => c_bsn_w, + g_block_size => c_block_size + ) + PORT MAP ( + -- Clocks and reset + mm_rst => mm_rst, + mm_clk => mm_clk, + dp_rst => dp_rst, + dp_clk => dp_clk, + + -- MM control + reg_mosi => reg_mosi, + reg_miso => reg_miso, + + -- Streaming + in_sosi => stimuli_sosi, + out_sosi => out_sosi, + out_start => out_start, + out_enable => out_enable + ); + +END tb;