Select Git revision
dp_counter_func.vhd
-
Daniel van der Schuur authored
range(0,2,1) = [0,1]. -Reverified in sim using tb_tb_dp_counter and tb_dp_counter_func.
Daniel van der Schuur authoredrange(0,2,1) = [0,1]. -Reverified in sim using tb_tb_dp_counter and tb_dp_counter_func.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
dp_counter_func.vhd 5.67 KiB
--------------------------------------------------------------------------------
--
-- Copyright (C) 2017
-- 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/>.
--
--------------------------------------------------------------------------------
-- Author:
-- . Daniel van der Schuur
-- Purpose:
-- . Provide an array of counters with dimension carryover
-- Description:
-- . Provides g_nof_counters counters,[g_nof_counters-1]..[c0]
-- . Every counter is specified like Python's range(start,stop,step).
-- . c0 changes the fastest, c4 changes the slowest
-- . Faster changing dimensions carry over in slower changing dimensions
-- when dimension maximum is reached
-- . The outputs are in sync with / apply to src_out.
-- . range(0,1,1) = [0] is the smallest count range
-- Usage:
-- . The count values themselves (c0..c4) are very useful to tag streaming
-- data with corresponding ID indices.
-- . The extra outputs (e.g. c0_min, c0_max) can be used to trigger other
-- logic when minimum/maximum values per dimension are reached.
LIBRARY IEEE,common_lib;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
USE common_lib.common_pkg.ALL;
USE work.dp_stream_pkg.ALL;
ENTITY dp_counter_func IS
GENERIC (
g_nof_counters : NATURAL := 1;
g_range_start : t_nat_natural_arr; -- range must fit (g_nof_counters-1 DOWNTO 0)
g_range_stop : t_nat_natural_arr; -- range must fit (g_nof_counters-1 DOWNTO 0)
g_range_step : t_nat_natural_arr -- range must fit (g_nof_counters-1 DOWNTO 0)
);
PORT (
clk : IN STD_LOGIC;
rst : IN STD_LOGIC;
count_en : IN STD_LOGIC;
count_offset_in_arr : IN t_nat_natural_arr(g_nof_counters-1 DOWNTO 0) := (OTHERS=>0);
count_src_out_arr : OUT t_dp_sosi_arr(g_nof_counters-1 DOWNTO 0)
);
END dp_counter_func;
ARCHITECTURE str OF dp_counter_func IS
-- force downto range for unconstraint g_range generics
CONSTANT c_range_len : NATURAL := g_range_start'LENGTH; -- g_nof_counters must be <= c_range_len
CONSTANT c_range_start : t_nat_natural_arr(c_range_len-1 DOWNTO 0) := g_range_start;
CONSTANT c_range_stop : t_nat_natural_arr(c_range_len-1 DOWNTO 0) := g_range_stop;
CONSTANT c_range_step : t_nat_natural_arr(c_range_len-1 DOWNTO 0) := g_range_step;
CONSTANT c_max_count_w : NATURAL := 32;
SIGNAL count_en_arr : STD_LOGIC_VECTOR(g_nof_counters-1 DOWNTO 0);
SIGNAL check_max_arr : STD_LOGIC_VECTOR(g_nof_counters-1 DOWNTO 0);
SIGNAL count_init_arr : STD_LOGIC_VECTOR(g_nof_counters-1 DOWNTO 0);
SIGNAL count_min_arr : STD_LOGIC_VECTOR(g_nof_counters-1 DOWNTO 0);
SIGNAL count_max_arr : STD_LOGIC_VECTOR(g_nof_counters-1 DOWNTO 0);
TYPE t_count_arr IS ARRAY(g_nof_counters-1 DOWNTO 0) OF STD_LOGIC_VECTOR(c_max_count_w-1 DOWNTO 0);
SIGNAL count_arr : t_count_arr;
BEGIN
--------------------------------------------------------------------------------
-- Counter control inputs
-------------------------------------------------------------------------------
gen_dp_counter_func_single_input : FOR i IN 0 TO g_nof_counters-1 GENERATE
gen_c0 : IF i=0 GENERATE
count_en_arr(i) <= count_en;
check_max_arr(i) <= count_en;
END GENERATE;
gen_c1_upwards : IF i>0 GENERATE
count_en_arr(i) <= count_init_arr(i-1) OR count_min_arr(i-1);
check_max_arr(i) <= count_max_arr(i-1);
END GENERATE;
END GENERATE;
--------------------------------------------------------------------------------
-- Array of dp_counter_func_single instances
-------------------------------------------------------------------------------
gen_dp_counter_func_single : FOR i IN 0 TO g_nof_counters-1 GENERATE
u_dp_counter_func_single : ENTITY work.dp_counter_func_single
GENERIC MAP (
g_range_start => c_range_start(i),
g_range_stop => c_range_stop(i),
g_range_step => c_range_step(i)
)
PORT MAP (
rst => rst,
clk => clk,
count_en => count_en_arr(i),
check_max => check_max_arr(i),
count_offset => count_offset_in_arr(i),
count => count_arr(i),
count_init => count_init_arr(i),
count_min => count_min_arr(i),
count_max => count_max_arr(i)
);
END GENERATE;
--------------------------------------------------------------------------------
-- Counter outputs
-------------------------------------------------------------------------------
gen_dp_counter_func_single_output : FOR i IN 0 TO g_nof_counters-1 GENERATE
count_src_out_arr(i).sync <= '0'; -- not used, force to '0' to avoid toggling between '0' and 'X' in Wave window
-- when sync is passed on through other components
count_src_out_arr(i).sop <= count_min_arr(i);
count_src_out_arr(i).eop <= count_max_arr(i);
count_src_out_arr(i).valid <= count_en;
count_src_out_arr(i).data <= RESIZE_DP_DATA(count_arr(i));
END GENERATE;
END str;