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

Remove accidental commit of dp_bsn_align_v2 in this L2SDP-495 branch.

parent beb04440
No related branches found
No related tags found
1 merge request!148L2SDP-495
......@@ -104,8 +104,6 @@ synth_files =
src/vhdl/dp_bsn_align.vhd
src/vhdl/dp_bsn_align_reg.vhd
src/vhdl/mms_dp_bsn_align.vhd
src/vhdl/dp_bsn_align_v2.vhd
src/vhdl/mmp_dp_bsn_align_v2.vhd
src/vhdl/dp_frame_rd.vhd
src/vhdl/dp_frame_fsn.vhd
src/vhdl/dp_frame_tx.vhd
......@@ -213,8 +211,6 @@ test_bench_files =
tb/vhdl/tb_dp_block_validate_channel.vhd
tb/vhdl/tb_dp_bsn_align.vhd
tb/vhdl/tb_mms_dp_bsn_align.vhd
tb/vhdl/tb_dp_bsn_align_v2.vhd
tb/vhdl/tb_mmp_dp_bsn_align_v2.vhd
tb/vhdl/tb_dp_bsn_monitor.vhd
tb/vhdl/tb_dp_bsn_monitor_v2.vhd
tb/vhdl/tb_dp_bsn_source.vhd
......@@ -299,7 +295,6 @@ test_bench_files =
tb/vhdl/tb_tb_dp_block_from_mm.vhd
tb/vhdl/tb_tb_dp_block_validate_channel.vhd
tb/vhdl/tb_tb_dp_bsn_align.vhd
tb/vhdl/tb_tb_dp_bsn_align_v2.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
......@@ -356,7 +351,6 @@ regression_test_vhdl =
tb/vhdl/tb_dp_latency_adapter.vhd
tb/vhdl/tb_dp_shiftreg.vhd
tb/vhdl/tb_dp_bsn_source.vhd
tb/vhdl/tb_mmp_dp_bsn_align_v2.vhd
tb/vhdl/tb_mms_dp_bsn_source.vhd
tb/vhdl/tb_mms_dp_bsn_source_v2.vhd
tb/vhdl/tb_mmp_dp_bsn_sync_scheduler.vhd
......@@ -370,7 +364,6 @@ regression_test_vhdl =
tb/vhdl/tb_tb_dp_block_gen_valid_arr.vhd
tb/vhdl/tb_tb_dp_block_from_mm.vhd
tb/vhdl/tb_tb_dp_block_validate_channel.vhd
tb/vhdl/tb_tb_dp_bsn_align_v2.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
......
-- --------------------------------------------------------------------------
-- 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: Eric Kooistra, 3 Sept 2021
-- Purpose :
-- Align frames from multiple input streams
-- Description:
-- The aligner uses a circular buffer to capture the blocks that arrive at
-- the input streams. The blocks have a block sequence number (BSN) that
-- is used to align the inputs. The input stream 0 is treated as local
-- input stream that is ahead of the other remote input streams. After a
-- certain number of blocks on input 0, the same block on all remote
-- inputs should also have arrived. If not then they are replaced by
-- filler data. The output streams are paced by the block rate of input 0.
-- The user has to read the block within the block period.
--
-- Features:
-- . uses filler flag and data to replace lost input blocks
-- . output block can be read in arbitrary order
--
-- For more detailed description see:
-- https://support.astron.nl/confluence/display/L2M/L6+FWLIB+Design+Document%3A+BSN+aligner+v2
--
-- Remarks:
-- . This dp_bsn_align_v2.vhd replaces the dp_bsn_align.vhd that was used in
-- APERTIF. Mian differences are that the old component uses FIFO buffers,
-- timeouts and states, and v2 does not, which makes v2 simpler and more
-- robust.
LIBRARY IEEE,common_lib;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE work.dp_stream_pkg.ALL;
ENTITY dp_bsn_align_v2 IS
GENERIC (
g_nof_streams : NATURAL; -- number of input and output streams
g_bsn_latency_max : NATURAL; -- Maximum travel latency of a remote block in number of block periods T_blk
g_bsn_latency_use_node_index : BOOLEAN := FALSE; -- FALSE for align at end node, TRUE for align at every intermediate node
g_node_index_max : NATURAL := 31; -- limit to functional 5 bit range, instead of full 31 bit NATURAL range
g_block_size : NATURAL := 32; -- > 1, g_block_size=1 is not supported
g_buffer_nof_blocks : NATURAL; -- circular buffer size per input, choose ceil_pow2(1 + g_bsn_latency_max)
g_bsn_w : NATURAL := c_dp_stream_bsn_w; -- number of bits in sosi BSN
g_data_w : NATURAL; -- number of bits in sosi data
g_filler_value : INTEGER := 0; -- output sosi data value for missing input blocks
g_use_mm_output : BOOLEAN := FALSE; -- output via MM or via streaming DP
g_pipeline_input : NATURAL := 0; -- >= 0, choose 0 for wires, choose 1 to ease timing closure
g_rd_latency : NATURAL := 1 -- 1 or 2, choose 2 to ease timing closure
);
PORT (
dp_rst : IN STD_LOGIC;
dp_clk : IN STD_LOGIC;
node_index : IN NATURAL RANGE 0 TO g_node_index_max := 0; -- only used when g_bsn_latency_use_node_index is TRUE
-- MM control
stream_en_arr : IN STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS=>'1');
-- Streaming input
in_sosi_arr : IN t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
-- Output via local MM interface in dp_clk domain
mm_sosi : OUT t_dp_sosi; -- streaming information that signals that an output block can be read
mm_copi : IN t_mem_copi; -- read access to output block, all output streams share same mm_copi
mm_cipo_arr : OUT t_mem_cipo_arr(g_nof_streams-1 DOWNTO 0);
-- Output via streaming DP interface
out_sosi_arr : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0)
);
END dp_bsn_align_v2;
ARCHITECTURE rtl OF dp_bsn_align_v2 IS
-- Circular buffer per stream
CONSTANT c_ram_size : NATURAL := g_buffer_nof_blocks * g_block_size;
CONSTANT c_ram_buf : t_c_mem := (latency => 1,
adr_w => ceil_log2(c_ram_size),
dat_w => g_data_w,
nof_dat => c_ram_size,
init_sl => '0');
CONSTANT c_block_size_w : NATURAL := ceil_log2(g_block_size);
CONSTANT c_block_size_slv : STD_LOGIC_VECTOR(c_block_size_w-1 DOWNTO 0) := TO_UVEC(g_block_size, c_block_size_w);
CONSTANT c_blk_pointer_w : NATURAL := ceil_log2(g_buffer_nof_blocks);
-- Use fixed slv width instead of using naturals for address calculation, to
-- avoid that synthesis may infer a too larger multiplier
CONSTANT c_product_w : NATURAL := c_blk_pointer_w + c_block_size_w;
TYPE t_bsn_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0);
TYPE t_adr_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(c_mem_ram.adr_w-1 DOWNTO 0);
TYPE t_filled_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(g_buffer_nof_blocks-1 DOWNTO 0);
TYPE t_reg IS RECORD
-- p_write_arr
wr_pointer : NATURAL;
wr_copi_arr : t_mem_copi_arr(g_nof_streams-1 DOWNTO 0);
-- all streams
filled_arr : t_filled_arr(g_nof_streams-1 DOWNTO 0);
use_filler_data : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
-- local reference
sync_arr : STD_LOGIC_VECTOR(g_buffer_nof_blocks-1 DOWNTO 0);
bsn_arr : t_bsn_arr(g_buffer_nof_blocks-1 DOWNTO 0);
mm_sosi : t_dp_sosi;
-- p_read
rd_pointer : INTEGER; -- use integer to detect need to wrap to natural
rd_offset : STD_LOGIC_VECTOR(c_mem_ram.adr_w-1 DOWNTO 0);
rd_copi : t_mem_copi;
fill_cipo_arr : t_mem_cipo_arr(g_nof_streams-1 DOWNTO 0); -- used combinatorial to contain rd_cipo_arr from buffer or filler data
out_bsn : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0); -- hold BSN for streaming output
END RECORD;
CONSTANT c_reg_rst : t_reg := (0,
(OTHERS=>c_mem_copi_rst),
(OTHERS=>(OTHERS=>'0')),
(OTHERS=>'0'),
(OTHERS=>'0'),
(OTHERS=>(OTHERS=>'0')),
c_dp_sosi_rst,
0,
(OTHERS=>'0'),
c_mem_copi_rst,
(OTHERS=>c_mem_cipo_rst),
(OTHERS=>'0'));
-- State registers
SIGNAL r : t_reg;
SIGNAL nxt_r : t_reg;
-- Wires
SIGNAL dp_done : STD_LOGIC;
SIGNAL dp_done_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
SIGNAL dp_copi : t_mem_copi;
SIGNAL dp_copi_arr : t_mem_copi_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL dp_sosi : t_dp_sosi;
SIGNAL rd_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL rd_cipo_arr : t_mem_cipo_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>c_mem_cipo_rst);
-- Pipeline registers
SIGNAL in_sosi_arr_p : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL rd_copi_p : t_mem_copi;
BEGIN
mm_sosi <= r.mm_sosi;
p_reg : PROCESS(dp_clk, dp_rst)
BEGIN
IF dp_rst='1' THEN
r <= c_reg_rst;
ELSIF rising_edge(dp_clk) THEN
r <= nxt_r;
END IF;
END PROCESS;
p_comb : PROCESS(r, in_sosi_arr_p, mm_copi, rd_cipo_arr, rd_sosi_arr)
-- State variable
VARIABLE v : t_reg;
-- Auxiliary variables / local wires / no memory
VARIABLE v_ref_sosi : t_dp_sosi;
VARIABLE v_pointer_slv : STD_LOGIC_VECTOR(c_blk_pointer_w-1 DOWNTO 0);
VARIABLE v_product_slv : STD_LOGIC_VECTOR(c_product_w-1 DOWNTO 0);
VARIABLE v_filler_flag : STD_LOGIC;
VARIABLE v_out_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
BEGIN
v := r;
v.mm_sosi := func_dp_stream_reset_control(r.mm_sosi);
v.wr_copi_arr := RESET_MEM_COPI_CTRL(r.wr_copi_arr);
----------------------------------------------------------------------------
-- p_write_arr
----------------------------------------------------------------------------
FOR I IN 0 TO g_nof_streams-1 LOOP
-- p_write
IF in_sosi_arr_p(I).valid = '1' THEN
-- . increment address during block
v.wr_copi_arr(I).address := RESIZE_MEM_ADDRESS(INCR_UVEC(r.wr_copi_arr(I).address(c_mem_ram.adr_w-1 DOWNTO 0), 1));
v.wr_copi_arr(I).wr := '1';
v.wr_copi_arr(I).wrdata := RESIZE_MEM_SDATA(in_sosi_arr_p(I).data);
END IF;
IF in_sosi_arr_p(I).sop = '1' THEN
-- . set address at start of block
v_pointer_slv := in_sosi_arr_p(I).bsn(c_blk_pointer_w-1 DOWNTO 0);
v_product_slv := MULT_UVEC(v_pointer_slv, c_block_size_slv);
v.wr_copi_arr(I).address := RESIZE_MEM_ADDRESS(v_product_slv);
-- . set filled flag at sop, so assume rest of block will follow in time
v.filled_arr(I)(TO_UINT(v_pointer_slv)) := '1';
END IF;
END LOOP;
----------------------------------------------------------------------------
-- p_control, all at sop of local reference input 0
----------------------------------------------------------------------------
v_ref_sosi := in_sosi_arr_p(0);
IF v_ref_sosi.sop = '1' THEN
-- . write sync & bsn buffer
v.wr_pointer := TO_UINT(v_ref_sosi.bsn(c_blk_pointer_w-1 DOWNTO 0));
v.sync_arr(v.wr_pointer) := v_ref_sosi.sync;
v.bsn_arr(v.wr_pointer) := v_ref_sosi.bsn(g_bsn_w-1 DOWNTO 0);
-- . update read block pointer at g_bsn_latency_max blocks behind the reference write pointer
IF g_bsn_latency_use_node_index = FALSE THEN
v.rd_pointer := v.wr_pointer - g_bsn_latency_max;
ELSE
v.rd_pointer := v.wr_pointer - g_bsn_latency_max * node_index;
END IF;
IF v.rd_pointer < 0 THEN
v.rd_pointer := v.rd_pointer + g_buffer_nof_blocks;
END IF;
-- . update read address of read block pointer
v_pointer_slv := TO_UVEC(v.rd_pointer, c_blk_pointer_w);
v_product_slv := MULT_UVEC(v_pointer_slv, c_block_size_slv);
v.rd_offset := RESIZE_UVEC(v_product_slv, c_mem_ram.adr_w);
-- . issue mm_sosi, if there is output ready to be read, indicated by filled reference block
IF r.filled_arr(0)(v.rd_pointer) = '1' THEN
v.mm_sosi.sop := '1';
v.mm_sosi.eop := '1';
v.mm_sosi.valid := '1';
-- . pass on timestamp information
v.mm_sosi.sync := v.sync_arr(v.rd_pointer);
v.mm_sosi.bsn := RESIZE_DP_BSN(v.bsn_arr(v.rd_pointer));
-- . pass on filled flags for enabled streams via channel field, and
-- determine whether the ouput has to insert filler data
v.mm_sosi.channel := (OTHERS=>'0');
FOR I IN 0 TO g_nof_streams-1 LOOP
v_filler_flag := NOT v.filled_arr(I)(v.rd_pointer);
IF stream_en_arr(I) = '1' THEN -- use MM bit at sop
v.use_filler_data(I) := v_filler_flag; -- enabled stream
v.mm_sosi.channel(I) := v_filler_flag;
ELSE
v.use_filler_data(I) := '1'; -- disabled stream
END IF;
END LOOP;
END IF;
-- . clear filled flags, after mm_sosi was issued, or could have been issued
FOR I IN 0 TO g_nof_streams-1 LOOP
v.filled_arr(I)(v.rd_pointer) := '0';
END LOOP;
END IF;
----------------------------------------------------------------------------
-- p_read
----------------------------------------------------------------------------
-- Read the data from the buffer, or replace a block by filler data
-- . default use input data from the circular buffer
v.fill_cipo_arr := rd_cipo_arr;
-- . if necessary, replace a stream by filler data
FOR I IN 0 TO g_nof_streams-1 LOOP
IF r.use_filler_data(I) = '1' THEN
v.fill_cipo_arr(I).rddata := TO_MEM_SDATA(g_filler_value);
END IF;
END LOOP;
IF g_use_mm_output THEN
--------------------------------------------------------------------------
-- Do the output via the MM interface
--------------------------------------------------------------------------
-- . adjust the rd address to the current buffer output block
v.rd_copi := mm_copi;
v.rd_copi.address := RESIZE_MEM_ADDRESS(ADD_UVEC(r.rd_offset, mm_copi.address)); -- sum yields c_mem_ram.adr_w bits, because left operand determines width
-- . output via MM interface
mm_cipo_arr <= v.fill_cipo_arr;
ELSE
--------------------------------------------------------------------------
-- Do the output via the DP streaming interface
--------------------------------------------------------------------------
-- . adjust the rd address
v.rd_copi := dp_copi;
v.rd_copi.address := RESIZE_MEM_ADDRESS(ADD_UVEC(r.rd_offset, dp_copi.address)); -- sum yields c_mem_ram.adr_w bits, because left operand determines width
-- . hold mm_sosi.sync, bsn
IF r.mm_sosi.sop = '1' THEN
dp_sosi <= r.mm_sosi;
END IF;
-- apply mm_sosi.sync and bsn at sop to all streams in out_sosi_arr
v_out_sosi_arr := rd_sosi_arr; -- the input data from the buffer or filler data (= v.fill_cipo_arr in streaming format)
IF rd_sosi_arr(0).sop = '1' THEN
v_out_sosi_arr := func_dp_stream_arr_set(v_out_sosi_arr, dp_sosi.sync, "SYNC");
v_out_sosi_arr := func_dp_stream_arr_set(v_out_sosi_arr, dp_sosi.bsn, "BSN");
v.out_bsn := dp_sosi.bsn(g_bsn_w-1 DOWNTO 0); -- hold BSN until next sop, to ease view in wave window
ELSE
-- hold BSN until next sop, to ease view in wave window
v_out_sosi_arr := func_dp_stream_arr_set(v_out_sosi_arr, r.out_bsn, "BSN");
END IF;
-- . output via DP streaming interface
out_sosi_arr <= v_out_sosi_arr;
END IF;
----------------------------------------------------------------------------
-- next state
----------------------------------------------------------------------------
nxt_r <= v;
END PROCESS;
------------------------------------------------------------------------------
-- Circular buffers
------------------------------------------------------------------------------
gen_data_buffer : FOR I IN 0 TO g_nof_streams-1 GENERATE
u_data_buffer : ENTITY common_lib.common_ram_r_w
GENERIC MAP (
g_ram => c_ram_buf
)
PORT MAP (
rst => dp_rst,
clk => dp_clk,
wr_en => r.wr_copi_arr(I).wr,
wr_adr => r.wr_copi_arr(I).address(c_ram_buf.adr_w-1 DOWNTO 0),
wr_dat => r.wr_copi_arr(I).wrdata(c_ram_buf.dat_w-1 DOWNTO 0),
rd_en => rd_copi_p.rd,
rd_adr => rd_copi_p.address(c_ram_buf.adr_w-1 DOWNTO 0),
rd_dat => rd_cipo_arr(I).rddata(c_ram_buf.dat_w-1 DOWNTO 0),
rd_val => rd_cipo_arr(I).rdval
);
END GENERATE;
------------------------------------------------------------------------------
-- MM to streaming DP
------------------------------------------------------------------------------
gen_streaming_output : IF NOT g_use_mm_output GENERATE
dp_copi <= dp_copi_arr(0);
dp_done <= dp_done_arr(0); -- for viewing only
gen_mm_to_dp : FOR I IN 0 TO g_nof_streams-1 GENERATE
u_mm_to_dp: ENTITY work.dp_block_from_mm
GENERIC MAP (
g_data_size => 1,
g_step_size => 1,
g_nof_data => g_block_size,
g_data_w => g_data_w,
g_mm_rd_latency => g_rd_latency,
g_reverse_word_order => FALSE
)
PORT MAP (
rst => dp_rst,
clk => dp_clk,
start_pulse => r.mm_sosi.sop,
start_address => 0,
mm_done => dp_done_arr(I),
mm_mosi => dp_copi_arr(I),
mm_miso => nxt_r.fill_cipo_arr(I),
out_sosi => rd_sosi_arr(I),
out_siso => c_dp_siso_rdy
);
END GENERATE;
END GENERATE;
------------------------------------------------------------------------------
-- Pipelining
------------------------------------------------------------------------------
-- . input
u_in_sosi_arr_p : ENTITY work.dp_pipeline_arr
GENERIC MAP (
g_nof_streams => g_nof_streams,
g_pipeline => g_pipeline_input -- 0 for wires, > 0 for registers,
)
PORT MAP (
rst => dp_rst,
clk => dp_clk,
-- ST sink
snk_in_arr => in_sosi_arr,
-- ST source
src_out_arr => in_sosi_arr_p
);
-- . read RAM
rd_copi_p <= nxt_r.rd_copi WHEN g_rd_latency = 1 ELSE r.rd_copi;
END rtl;
-- --------------------------------------------------------------------------
-- Copyright 2021
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
-- --------------------------------------------------------------------------
--
-- Author: Eric Kooistra, 6 Sept 2021
-- Purpose: MMP for dp_bsn_align_v2
-- Description:
-- Add MM interfaces to dp_bsn_align_v2:
--
-- * Instantiates input BSN monitors when g_nof_input_bsn_monitors > 0
-- * Instantiates output BSN monitor g_use_bsn_output_monitor = TRUE
-- * Define MM reg for input enable/disable control for input i:
--
-- wi Bits Access Type Name
-- i [0] RW boolean input_enable
--
-- where i = 0:g_nof_streams-1 and input_enable '1' is on, '0' is off
--
-- For more description see dp_bsn_align_v2 and
-- https://support.astron.nl/confluence/display/L2M/L6+FWLIB+Design+Document%3A+BSN+aligner+v2
LIBRARY IEEE, common_lib;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE work.dp_stream_pkg.ALL;
ENTITY mmp_dp_bsn_align_v2 IS
GENERIC (
g_nof_streams : NATURAL; -- number of input and output streams
g_bsn_latency_max : NATURAL; -- Maximum travel latency of a remote block in number of block periods T_blk
g_bsn_latency_use_node_index : BOOLEAN := FALSE; -- FALSE for align at end node, TRUE for align at every intermediate node
g_block_size : NATURAL := 32; -- > 1, g_block_size=1 is not supported
g_buffer_nof_blocks : NATURAL; -- circular buffer size per input, choose ceil_pow2(1 + g_bsn_latency_max)
g_bsn_w : NATURAL := c_dp_stream_bsn_w; -- number of bits in sosi BSN
g_data_w : NATURAL; -- number of bits in sosi data
g_filler_value : INTEGER := 0; -- output sosi data value for missing input blocks
g_nof_clk_per_sync : NATURAL := 200*10**6;
g_nof_input_bsn_monitors : NATURAL := 0;
g_use_bsn_output_monitor : BOOLEAN := FALSE
);
PORT (
-- Memory-mapped clock domain
mm_rst : IN STD_LOGIC;
mm_clk : IN STD_LOGIC;
reg_copi : IN t_mem_copi;
reg_cipo : OUT t_mem_cipo;
reg_input_monitor_copi : IN t_mem_copi;
reg_input_monitor_cipo : OUT t_mem_cipo;
reg_output_monitor_copi : IN t_mem_copi;
reg_output_monitor_cipo : OUT t_mem_cipo;
-- Streaming clock domain
dp_rst : IN STD_LOGIC;
dp_clk : IN STD_LOGIC;
node_index : IN NATURAL := 0; -- only used when g_bsn_latency_use_node_index is TRUE
-- Streaming input
in_sosi_arr : IN t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
-- Output via local MM in dp_clk domain
mm_copi : IN t_mem_copi; -- read access to output block, all output streams share same mm_copi
mm_cipo_arr : OUT t_mem_cipo_arr(g_nof_streams-1 DOWNTO 0);
mm_sosi : OUT t_dp_sosi -- streaming information that signals that an output block can be read
);
END mmp_dp_bsn_align_v2;
ARCHITECTURE str OF mmp_dp_bsn_align_v2 IS
-- Use one MM word (bit 0) per input_enable bit, similar as in dp_bsn_align_reg.vhd.
-- 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, ceil_log2(g_nof_streams), 1, g_nof_streams, '0');
SIGNAL reg_wr : STD_LOGIC_VECTOR(c_mm_reg.nof_dat*c_mm_reg.dat_w-1 DOWNTO 0);
SIGNAL stream_en_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
SIGNAL mm_sosi_arr : t_dp_sosi_arr(0 DOWNTO 0);
BEGIN
u_reg : 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_copi,
sla_out => reg_cipo,
-- MM registers in st_clk domain
reg_wr_arr => OPEN,
reg_rd_arr => OPEN,
out_reg => reg_wr, -- readback via ST clock domain
in_reg => reg_wr
);
stream_en_arr <= reg_wr;
-- Use input BSN monitors for the first g_nof_input_bsn_monitors input
-- streams, e.g. to support:
-- . only one input stream (g_nof_input_bsn_monitors = 1), or
-- . all input streams (g_nof_input_bsn_monitors = g_nof_streams).
gen_bsn_mon_input : IF g_nof_input_bsn_monitors > 0 GENERATE
u_bsn_mon_input : ENTITY work.mms_dp_bsn_monitor_v2
GENERIC MAP (
g_nof_streams => g_nof_input_bsn_monitors,
g_cross_clock_domain => TRUE,
g_sync_timeout => g_nof_clk_per_sync,
g_bsn_w => g_bsn_w,
g_error_bi => 0,
g_cnt_sop_w => c_word_w,
g_cnt_valid_w => c_word_w,
g_cnt_latency_w => c_word_w
)
PORT MAP (
-- Memory-mapped clock domain
mm_rst => mm_rst,
mm_clk => mm_clk,
reg_mosi => reg_input_monitor_copi,
reg_miso => reg_input_monitor_cipo,
-- Streaming clock domain
dp_rst => dp_rst,
dp_clk => dp_clk,
ref_sync => in_sosi_arr(0).sync, -- local reference sync input
in_siso_arr => (OTHERS=>c_dp_siso_rdy),
in_sosi_arr => in_sosi_arr(g_nof_input_bsn_monitors-1 DOWNTO 0)
);
END GENERATE;
gen_bsn_mon_output : IF g_use_bsn_output_monitor GENERATE
u_bsn_mon_output : ENTITY work.mms_dp_bsn_monitor_v2
GENERIC MAP (
g_nof_streams => 1, -- all outputs have same BSN monitor information
g_cross_clock_domain => TRUE,
g_sync_timeout => g_nof_clk_per_sync,
g_bsn_w => g_bsn_w,
g_error_bi => 0,
g_cnt_sop_w => c_word_w,
g_cnt_valid_w => c_word_w,
g_cnt_latency_w => c_word_w
)
PORT MAP (
-- Memory-mapped clock domain
mm_rst => mm_rst,
mm_clk => mm_clk,
reg_mosi => reg_output_monitor_copi,
reg_miso => reg_output_monitor_cipo,
-- Streaming clock domain
dp_rst => dp_rst,
dp_clk => dp_clk,
ref_sync => in_sosi_arr(0).sync, -- local reference sync input
in_siso_arr => (OTHERS=>c_dp_siso_rdy),
in_sosi_arr => mm_sosi_arr
);
END GENERATE;
u_bsn_align : ENTITY work.dp_bsn_align_v2
GENERIC MAP (
g_nof_streams => g_nof_streams,
g_bsn_latency_max => g_bsn_latency_max,
g_bsn_latency_use_node_index => g_bsn_latency_use_node_index,
g_block_size => g_block_size,
g_buffer_nof_blocks => g_buffer_nof_blocks,
g_bsn_w => g_bsn_w,
g_data_w => g_data_w,
g_filler_value => g_filler_value
)
PORT MAP (
dp_rst => dp_rst,
dp_clk => dp_clk,
node_index => node_index,
-- MM control
stream_en_arr => stream_en_arr,
-- Streaming input
in_sosi_arr => in_sosi_arr,
-- Output via local MM in dp_clk domain
mm_copi => mm_copi,
mm_cipo_arr => mm_cipo_arr,
mm_sosi => mm_sosi
);
mm_sosi <= mm_sosi_arr(0);
END str;
This diff is collapsed.
-- --------------------------------------------------------------------------
-- 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 sept 2021
-- Purpose: Verify MM part of mmp_dp_bsn_align_v2
-- Description:
-- The functional part is already verified by tb_tb_dp_bsn_align_v2.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_align_v2 IS
END tb_mmp_dp_bsn_align_v2;
ARCHITECTURE tb OF tb_mmp_dp_bsn_align_v2 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_report_note : BOOLEAN := FALSE; -- Use TRUE for tb debugging, else FALSE to keep Transcript window more empty
CONSTANT c_nof_input_sync : NATURAL := 10;
CONSTANT c_nof_block_per_sync : NATURAL := 32;
CONSTANT c_block_size : NATURAL := 10;
CONSTANT c_input_gap_size : NATURAL := 3;
CONSTANT c_sim_nof_blocks : NATURAL := c_nof_block_per_sync * c_nof_input_sync;
CONSTANT c_nof_streams : NATURAL := 2;
CONSTANT c_bsn_latency_max : NATURAL := 2;
CONSTANT c_bsn_latency_use_node_index : BOOLEAN := FALSE;
CONSTANT c_buffer_nof_blocks : NATURAL := ceil_pow2(1 + c_bsn_latency_max);
CONSTANT c_bsn_w : NATURAL := c_dp_stream_bsn_w;
CONSTANT c_data_w : NATURAL := 16;
CONSTANT c_filler_value : INTEGER := 0;
CONSTANT c_nof_clk_per_sync : NATURAL := 200*10**6;
CONSTANT c_nof_input_bsn_monitors : NATURAL := 0;
CONSTANT c_use_bsn_output_monitor : BOOLEAN := FALSE;
SIGNAL tb_end : STD_LOGIC := '0';
SIGNAL stimuli_end : STD_LOGIC := '0';
-- MM clock domain
SIGNAL mm_clk : STD_LOGIC := '1';
SIGNAL mm_rst : STD_LOGIC := '1';
SIGNAL reg_copi : t_mem_copi := c_mem_copi_rst;
SIGNAL reg_cipo : t_mem_cipo;
SIGNAL reg_input_monitor_copi : t_mem_copi := c_mem_copi_rst;
SIGNAL reg_input_monitor_cipo : t_mem_cipo;
SIGNAL reg_output_monitor_copi : t_mem_copi := c_mem_copi_rst;
SIGNAL reg_output_monitor_cipo : t_mem_cipo;
-- DP clock domain
SIGNAL dp_clk : STD_LOGIC := '1';
SIGNAL dp_rst : STD_LOGIC := '1';
SIGNAL node_index : NATURAL := 0; -- only used when g_bsn_latency_use_node_index is TRUE
SIGNAL stimuli_sosi : t_dp_sosi;
SIGNAL in_sosi_arr : t_dp_sosi_arr(c_nof_streams-1 DOWNTO 0);
SIGNAL mm_copi : t_mem_copi; -- read access to output block, all output streams share same mm_copi
SIGNAL mm_cipo_arr : t_mem_cipo_arr(c_nof_streams-1 DOWNTO 0);
SIGNAL mm_sosi : t_dp_sosi; -- streaming information that signals that an output block can be read
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);
---------------------------------------------------------------------------
-- End of test
---------------------------------------------------------------------------
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_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
);
in_sosi_arr <= (OTHERS => stimuli_sosi);
------------------------------------------------------------------------------
-- DUT
------------------------------------------------------------------------------
u_bsn_align : ENTITY work.mmp_dp_bsn_align_v2
GENERIC MAP (
g_nof_streams => c_nof_streams,
g_bsn_latency_max => c_bsn_latency_max,
g_bsn_latency_use_node_index => c_bsn_latency_use_node_index,
g_block_size => c_block_size,
g_buffer_nof_blocks => c_buffer_nof_blocks,
g_bsn_w => c_bsn_w,
g_data_w => c_data_w,
g_filler_value => c_filler_value,
g_nof_clk_per_sync => c_nof_clk_per_sync,
g_nof_input_bsn_monitors => c_nof_input_bsn_monitors,
g_use_bsn_output_monitor => c_use_bsn_output_monitor
)
PORT MAP (
mm_rst => mm_rst,
mm_clk => mm_clk,
reg_copi => reg_copi,
reg_cipo => reg_cipo,
reg_input_monitor_copi => reg_input_monitor_copi,
reg_input_monitor_cipo => reg_input_monitor_cipo,
reg_output_monitor_copi => reg_output_monitor_copi,
reg_output_monitor_cipo => reg_output_monitor_cipo,
dp_rst => dp_rst,
dp_clk => dp_clk,
node_index => node_index,
-- Streaming input
in_sosi_arr => in_sosi_arr,
-- Output via local MM in dp_clk domain
mm_copi => mm_copi,
mm_cipo_arr => mm_cipo_arr,
mm_sosi => mm_sosi
);
END tb;
-- --------------------------------------------------------------------------
-- Copyright 2021
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
-- --------------------------------------------------------------------------
--
-- Author: E. Kooistra, 15 sept 2021
-- Purpose: Regression multi tb for dp_bsn_align_v2
-- Description:
-- Usage:
-- > as 3
-- > run -all
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE work.tb_dp_pkg.ALL;
ENTITY tb_tb_dp_bsn_align_v2 IS
END tb_tb_dp_bsn_align_v2;
ARCHITECTURE tb OF tb_tb_dp_bsn_align_v2 IS
CONSTANT c_block_size : NATURAL := 11;
CONSTANT c_diff_delay : NATURAL := 20;
CONSTANT c_diff_bsn : NATURAL := 3; -- g_diff_bsn = g_bsn_latency can just be aligned
CONSTANT c_bsn_latency_max : NATURAL := 1;
CONSTANT c_nof_repeat : NATURAL := 100; -- for constant active stream control using 1 is sufficient, use > 1 to verify longer with random stimuli
SIGNAL tb_end : STD_LOGIC := '0'; -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end'
BEGIN
-- -- DUT
-- g_nof_streams : NATURAL := 2; -- number of input and output streams
-- g_bsn_latency_max : NATURAL := 1; -- Maximum travel latency of a remote block in number of block periods T_blk
-- g_bsn_latency_use_node_index : BOOLEAN := FALSE; -- FALSE for align at end node, TRUE for align at every intermediate node
-- g_block_size : NATURAL := 11; -- > 1, g_block_size=1 is not supported
-- g_bsn_w : NATURAL := c_dp_stream_bsn_w; -- number of bits in sosi BSN
-- g_data_w : NATURAL := 16; -- number of bits in sosi data
-- g_filler_value : INTEGER := 0; -- output sosi data value for missing input blocks
-- g_use_mm_output : BOOLEAN := FALSE; -- output via MM or via streaming DP
-- g_pipeline_input : NATURAL := 1; -- >= 0, choose 0 for wires, choose 1 to ease timing closure
-- g_rd_latency : NATURAL := 2; -- 1 or 2, choose 2 to ease timing closure
--
-- -- TB
-- g_diff_delay : NATURAL := 0;
-- g_diff_bsn : NATURAL := 0; -- g_diff_bsn = g_bsn_latency_max can just be aligned
-- g_nof_repeat : NATURAL := 100 -- for constant active stream control using 1 is sufficient, use > 1 to verify longer with random stimuli
u_mm_output : ENTITY work.tb_dp_bsn_align_v2 GENERIC MAP (2, c_bsn_latency_max, FALSE, 11, 32, 16, 0, TRUE, 0, 1, 0, 9, c_nof_repeat);
u_dp_output : ENTITY work.tb_dp_bsn_align_v2 GENERIC MAP (2, c_bsn_latency_max, FALSE, 11, 32, 16, 0, FALSE, 0, 1, 0, 9, c_nof_repeat);
END tb;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment