Skip to content
Snippets Groups Projects
Commit 75aad013 authored by Daniel van der Schuur's avatar Daniel van der Schuur
Browse files

Merge branch 'STAT-314' into 'master'

Resolve STAT-314

Closes STAT-314

See merge request desp/hdl!20
parents 41e81aec 6aaba38d
No related branches found
No related tags found
2 merge requests!28Master,!20Resolve STAT-314
......@@ -10,11 +10,17 @@ synth_files =
src/vhdl/st_calc.vhd
src/vhdl/st_sst.vhd
# src/vhdl/st_top.vhd
src/vhdl/st_histogram.vhd
src/vhdl/st_histogram_reg.vhd
src/vhdl/mms_st_histogram.vhd
src/vhdl/st_histogram_8_april.vhd
test_bench_files =
tb/vhdl/tb_st_acc.vhd
tb/vhdl/tb_st_calc.vhd
tb/vhdl/tb_mmf_st_sst.vhd
tb/vhdl/tb_st_histogram.vhd
tb/vhdl/tb_mms_st_histogram.vhd
regression_test_vhdl =
tb/vhdl/tb_st_acc.vhd
......
-------------------------------------------------------------------------------
--
-- Copyright 2020
-- 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: J.W.E. Oudman
-- Purpose: Create a histogram from the input data and present it to the MM bus
-- Description:
-- mms_st_histogram couples the st_histogram component which works entirely
-- in the dp clock domain through st_histogram_reg that handles the cross
-- domain conversion to the MM bus.
--
--
-- --------------------------------------
-- | mms_st_histogram |
-- | |
-- | ---------------- | -------
-- snk_in -->|-->| st_histogram | | ^
-- | ---------------- | |
-- | | ^ |
-- | | | | dp clock domain
-- | ram_st_histogram_miso |
-- | | | |
-- | | ram_st_histogram_mosi | |
-- | v | | v
-- | -------------------- | -------
-- | | st_histogram_reg |-- ram_miso -->|--> mm clock domain
-- | | |<-- ram_mosi --|<--
-- | -------------------- | -------
-- | |
-- --------------------------------------
--
--
-------------------------------------------------------------------------------
LIBRARY IEEE, common_lib, mm_lib, technology_lib, dp_lib;
USE IEEE.std_logic_1164.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
USE technology_lib.technology_select_pkg.ALL;
ENTITY mms_st_histogram IS
GENERIC (
g_in_data_w : NATURAL := 14; -- >= 9 when g_nof_bins is 512; (max. c_dp_stream_data_w =768)
g_nof_bins : NATURAL := 512; -- is a power of 2 and g_nof_bins <= c_data_span; max. 512
g_nof_data : NATURAL; --
g_str : STRING := "freq.density" -- to select output to MM bus ("frequency" or "freq.density")
);
PORT (
dp_rst : IN STD_LOGIC;
dp_clk : IN STD_LOGIC;
mm_rst : IN STD_LOGIC;
mm_clk : IN STD_LOGIC;
-- Streaming
snk_in : IN t_dp_sosi;
-- Memory Mapped
ram_mosi : IN t_mem_mosi;
ram_miso : OUT t_mem_miso
);
END mms_st_histogram;
ARCHITECTURE str OF mms_st_histogram IS
SIGNAL ram_st_histogram_mosi : t_mem_mosi;
SIGNAL ram_st_histogram_miso : t_mem_miso;
BEGIN
u_st_histogram : ENTITY work.st_histogram
GENERIC MAP(
g_in_data_w => g_in_data_w,
g_nof_bins => g_nof_bins,
g_nof_data => g_nof_data,
g_str => g_str
)
PORT MAP (
dp_rst => dp_rst,
dp_clk => dp_clk,
snk_in => snk_in,
sla_in_ram_mosi => ram_st_histogram_mosi,
sla_out_ram_miso => ram_st_histogram_miso
);
u_st_histogram_reg : ENTITY work.st_histogram_reg
-- GENERIC MAP(
-- g_in_data_w =>
-- g_nof_bins =>
-- g_nof_data =>
-- g_str =>
-- )
PORT MAP (
dp_rst => dp_rst,
dp_clk => dp_clk,
mm_rst => mm_rst,
mm_clk => mm_clk,
mas_out_ram_mosi => ram_st_histogram_mosi,
mas_in_ram_miso => ram_st_histogram_miso,
ram_mosi => ram_mosi,
ram_miso => ram_miso
);
END str;
This diff is collapsed.
-- Daniel's suggested restructured st_hitogram.vhd.
LIBRARY IEEE, common_lib, mm_lib, technology_lib, dp_lib;
USE IEEE.std_logic_1164.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
USE technology_lib.technology_select_pkg.ALL;
ENTITY st_histogram_8_april IS
GENERIC (
g_in_data_w : NATURAL := 14; -- >= 9 when g_nof_bins is 512; (max. c_dp_stream_data_w =768) <-- maybe just g_data_w ??
g_nof_bins : NATURAL := 512; -- is a power of 2 and g_nof_bins <= c_data_span; max. 512
g_nof_data : NATURAL
);
PORT (
dp_rst : IN STD_LOGIC;
dp_clk : IN STD_LOGIC;
-- Streaming
snk_in : IN t_dp_sosi;
-- DP clocked memory bus
ram_mosi : IN t_mem_mosi;
ram_miso : OUT t_mem_miso
);
END st_histogram_8_april;
ARCHITECTURE rtl OF st_histogram_8_april IS
CONSTANT c_adr_w : NATURAL := ceil_log2(g_nof_bins);
CONSTANT c_ram : t_c_mem := (latency => 1,
adr_w => c_adr_w, -- 9 bits needed to adress/select 512 adresses
dat_w => c_word_w, -- 32bit, def. in common_pkg; >= c_bin_w
nof_dat => g_nof_bins, -- 512 adresses with 32 bit words, so 512
init_sl => '0'); -- MM side : sla_in, sla_out
-- CONSTANT c_mem_miso_setting : t_mem_miso := (rddata => mem_miso_init, -- c_mem_miso_rst; -- limit to 32 bit
-- rdval => '0',
-- waitrequest => '0' );
CONSTANT c_adr_low_calc : INTEGER := g_in_data_w-c_adr_w; -- Calculation might yield a negative number
CONSTANT c_adr_low : NATURAL := largest(0, c_adr_low_calc); -- Override any negative value of c_adr_low_calc
-- SIGNAL mem_miso_init : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0) := (OTHERS => '0');
SIGNAL bin_reader_mosi : t_mem_mosi := c_mem_mosi_rst;
SIGNAL nxt_bin_writer_mosi : t_mem_mosi;
SIGNAL bin_writer_mosi : t_mem_mosi;
SIGNAL nxt_bin_arbiter_wr_mosi : t_mem_mosi;
SIGNAL bin_arbiter_wr_mosi : t_mem_mosi;
SIGNAL nxt_bin_arbiter_rd_mosi : t_mem_mosi;
SIGNAL bin_arbiter_rd_mosi : t_mem_mosi;
SIGNAL common_ram_r_w_0_miso : t_mem_miso := c_mem_miso_rst;
SIGNAL init_phase : STD_LOGIC := '1';
SIGNAL rd_cnt_allowed : STD_LOGIC := '0';
SIGNAL rd_cnt_allowed_pp : STD_LOGIC := '0';
SIGNAL nxt_rd_adr_cnt : NATURAL := 0;
SIGNAL rd_adr_cnt : NATURAL;-- := 0;
SIGNAL toggle_detect : STD_LOGIC := '0';
SIGNAL toggle_detect_pp : STD_LOGIC;
SIGNAL toggle_detect_false : STD_LOGIC := '1';
-- SIGNAL nxt_toggle_adr_cnt : NATURAL := 0;
-- SIGNAL toggle_adr_cnt : NATURAL;-- := 0;
SIGNAL nxt_prev_wrdata : NATURAL;
SIGNAL prev_wrdata : NATURAL;
SIGNAL prev_prev_wrdata : NATURAL;
SIGNAL prev_prev_prev_wrdata: NATURAL;
SIGNAL sync_detect : STD_LOGIC := '0';
SIGNAL sync_detect_pp : STD_LOGIC;
-- SIGNAL adr_w : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low);
SIGNAL same_r_w_address : STD_LOGIC;
SIGNAL same_r_w_address_pp : STD_LOGIC;
--pipelined signals
SIGNAL dp_pipeline_src_out_p : t_dp_sosi;
SIGNAL dp_pipeline_src_out_pp : t_dp_sosi;
SIGNAL prev_bin_reader_mosi : t_mem_mosi := c_mem_mosi_rst ;
SIGNAL bin_reader_mosi_pp : t_mem_mosi := c_mem_mosi_rst;
SIGNAL bin_reader_mosi_ppp : t_mem_mosi := c_mem_mosi_rst;
--debug signals
-- SIGNAL nxt_dbg_sync_detect : STD_LOGIC;
-- SIGNAL dbg_sync_detect : STD_LOGIC;
SIGNAL dbg_state_string : STRING(1 TO 3) := " ";
SIGNAL dbg_snk_data : STD_LOGIC_VECTOR(g_in_data_w-1 DOWNTO 0);
BEGIN
-----------------------------------------------------------------------------
-- Bin reader: Convert snk_in data to bin_reader_mosi with read request
-- . in : snk_in (latency: 0)
-- . out : bin_reader_mosi (latency: 0)
-- . out : bin_reader_mosi_pp (latency: 2)
-- - out : rd_cnt_allowed_pp (latency: 2)
-----------------------------------------------------------------------------
bin_reader_mosi.rd <= snk_in.valid; -- when 1, count allowed
bin_reader_mosi.address(c_adr_w-1 DOWNTO 0) <= snk_in.data(g_in_data_w-1 DOWNTO c_adr_low);
--snk_in pipeline
u_dp_pipeline_snk_in_1_cycle : ENTITY dp_lib.dp_pipeline
GENERIC MAP (
g_pipeline => 1 -- 0 for wires, > 0 for registers,
)
PORT MAP (
rst => dp_rst,
clk => dp_clk,
snk_in => snk_in,
src_out => dp_pipeline_src_out_p
);
init_phase <= '0' WHEN dp_pipeline_src_out_p.sync = '1';
u_dp_pipeline_snk_in_2_cycle : ENTITY dp_lib.dp_pipeline
GENERIC MAP (
g_pipeline => 2 -- 0 for wires, > 0 for registers,
)
PORT MAP (
rst => dp_rst,
clk => dp_clk,
snk_in => snk_in,
src_out => dp_pipeline_src_out_pp
);
dbg_snk_data <= dp_pipeline_src_out_pp.data(g_in_data_w-1 DOWNTO 0);
toggle_detect_false <= '0' WHEN dp_pipeline_src_out_pp.sync = '1';
sync_detect <= snk_in.valid WHEN (snk_in.sync='1' OR dp_pipeline_src_out_p.sync='1' OR dp_pipeline_src_out_pp.sync='1') ELSE '0';
-- u_dp_sync_detect_3_cycle : ENTITY dp_lib.dp_pipeline
-- GENERIC MAP (
-- g_pipeline => 3 -- 0 for wires, > 0 for registers,
-- )
-- PORT MAP (
-- rst => dp_rst,
-- clk => dp_clk,
-- snk_in => sync_detect,
-- src_out => sync_detect_ppp
-- );
u_common_pipeline_sl_sync_detect_2_cycle : ENTITY common_lib.common_pipeline_sl
GENERIC MAP(
g_pipeline => 2 -- 0 for wires, > 0 for registers,
)
PORT MAP (
clk => dp_clk,
in_dat => sync_detect,
out_dat => sync_detect_pp
);
--prev_bin_reader_mosi pipeline
-- u_dp_pipeline_bin_reader_mosi_1_cycle : ENTITY dp_lib.dp_pipeline
-- GENERIC MAP (
-- g_pipeline => 1 -- 0 for wires, > 0 for registers,
-- )
-- PORT MAP (
-- rst => dp_rst,
-- clk => dp_clk,
-- snk_in => bin_reader_mosi,
-- src_out => prev_bin_reader_mosi
-- );
u_common_pipeline_bin_reader_mosi_1_cycle : ENTITY common_lib.common_pipeline
GENERIC MAP (
g_representation => "UNSIGNED", --orig. signed
g_pipeline => 1,
g_in_dat_w => c_adr_w, -- c_mem_address_w
g_out_dat_w => c_adr_w
)
PORT MAP (
clk => dp_clk,
clken => bin_reader_mosi.rd, -- '1',
in_dat => STD_LOGIC_VECTOR(bin_reader_mosi.address(c_adr_w-1 DOWNTO 0)),
out_dat => prev_bin_reader_mosi.address(c_adr_w-1 DOWNTO 0)
);
u_common_pipeline_bin_reader_mosi_2_cycle : ENTITY common_lib.common_pipeline -- better to pipeline prev_bin_reader_mosi??
GENERIC MAP (
g_representation => "UNSIGNED", --orig. signed
g_pipeline => 1,
g_in_dat_w => c_adr_w,
g_out_dat_w => c_adr_w
)
PORT MAP (
clk => dp_clk,
in_dat => STD_LOGIC_VECTOR(prev_bin_reader_mosi.address(c_adr_w-1 DOWNTO 0)),
out_dat => bin_reader_mosi_pp.address(c_adr_w-1 DOWNTO 0)
);
u_common_pipeline_bin_reader_mosi_3_cycle : ENTITY common_lib.common_pipeline -- better to pipeline prev_bin_reader_mosi??
GENERIC MAP (
g_representation => "UNSIGNED", --orig. signed
g_pipeline => 2,
g_in_dat_w => c_adr_w,
g_out_dat_w => c_adr_w
)
PORT MAP (
clk => dp_clk,
in_dat => STD_LOGIC_VECTOR(prev_bin_reader_mosi.address(c_adr_w-1 DOWNTO 0)),
out_dat => bin_reader_mosi_ppp.address(c_adr_w-1 DOWNTO 0)
);
--bin_reader_mosi_pp pipeline
-- u_dp_pipeline_bin_reader_mosi_2_cycle : ENTITY dp_lib.dp_pipeline
-- GENERIC MAP (
-- g_pipeline => 2 -- 0 for wires, > 0 for registers,
-- )
-- PORT MAP (
-- rst => dp_rst,
-- clk => dp_clk,
-- snk_in => bin_reader_mosi,
-- src_out => bin_reader_mosi_pp
-- );
-- rd_cnt_allowed <= snk_in.valid WHEN (bin_reader_mosi.address = prev_bin_reader_mosi.address AND init_phase = '0') ELSE '0'; -- AND snk_in.sync='0'
rd_cnt_allowed <= snk_in.valid WHEN ( bin_reader_mosi.address = prev_bin_reader_mosi.address AND ( (dp_pipeline_src_out_p.sync='1' AND dp_pipeline_src_out_p.valid='1') OR (dp_pipeline_src_out_pp.sync='1' AND dp_pipeline_src_out_p.valid='1') ) )
ELSE snk_in.valid WHEN (bin_reader_mosi.address = prev_bin_reader_mosi.address AND init_phase='0' AND snk_in.sync='0')
ELSE '0';
--rd_cnt_allowed_pp pipeline
u_common_pipeline_sl_rd_cnt_allowed : ENTITY common_lib.common_pipeline_sl
GENERIC MAP(
g_pipeline => 2 -- 0 for wires, > 0 for registers,
)
PORT MAP (
clk => dp_clk,
in_dat => rd_cnt_allowed,
out_dat => rd_cnt_allowed_pp
);
toggle_detect <= snk_in.valid WHEN (bin_reader_mosi_pp.address = bin_reader_mosi.address AND bin_reader_mosi_pp.address /= prev_bin_reader_mosi.address AND toggle_detect_false = '0') ELSE '0'; --AND (snk_in.sync='0' OR dp_pipeline_src_out_p.sync='0')
u_common_pipeline_sl_toggle_detect : ENTITY common_lib.common_pipeline_sl
GENERIC MAP(
g_pipeline => 2 -- 0 for wires, > 0 for registers,
)
PORT MAP (
clk => dp_clk,
in_dat => toggle_detect,
out_dat => toggle_detect_pp
);
same_r_w_address <= snk_in.valid WHEN (bin_reader_mosi.address = bin_reader_mosi_ppp.address AND init_phase = '0' AND sync_detect = '0') ELSE '0';
u_common_pipeline_sl_same_r_w_address : ENTITY common_lib.common_pipeline_sl
GENERIC MAP(
g_pipeline => 2 -- 0 for wires, > 0 for registers,
)
PORT MAP (
clk => dp_clk,
in_dat => same_r_w_address,
out_dat => same_r_w_address_pp
);
-----------------------------------------------------------------------------
-- Bin writer : increments current bin value and sets up write request
-- . in : dp_pipeline_src_out_pp (latency: 2)
-- . in : toggle_detect_pp (latency: 2)
-- . in : same_r_w_address_pp (latency: 2)
-- . in : bin_reader_mosi_pp (latency: 2)
-- . in : common_ram_r_w_0_miso (latency: 2)
-- . in : rd_cnt_allowed_pp (latency: 2)
-- . out : bin_writer_mosi (latency: 3)
-----------------------------------------------------------------------------
p_nxt_bin_writer_mosi : PROCESS(common_ram_r_w_0_miso, common_ram_r_w_0_miso.rdval, common_ram_r_w_0_miso.rddata,
bin_reader_mosi_pp.address, toggle_detect, rd_cnt_allowed_pp, rd_adr_cnt, init_phase, prev_wrdata, prev_prev_wrdata, sync_detect_pp, same_r_w_address_pp, dp_pipeline_src_out_pp.valid) IS
BEGIN
nxt_bin_writer_mosi <= c_mem_mosi_rst;
dbg_state_string <= "unv";
IF common_ram_r_w_0_miso.rdval='1' THEN -- OR rd_cnt_allowed_pp = '1' -- when not same as last 2 adresses
nxt_bin_writer_mosi.wr <= '1';
nxt_bin_writer_mosi.wrdata <= INCR_UVEC(common_ram_r_w_0_miso.rddata, 1); -- c_word_w); -- depends on count case -- rd_adr_cnt
nxt_bin_writer_mosi.address <= bin_reader_mosi_pp.address; --TODO: what other input do we need for this? -- becomes bin_reader_mosi.address
-- reset count? if toggle detected copy count to toggle counter
nxt_prev_wrdata <= TO_UINT(common_ram_r_w_0_miso.rddata) + 1;
-- nxt_rd_adr_cnt <= 0; -- really necessary ??
dbg_state_string <= "val";
-- IF bin_reader_mosi_pp.address = bin_reader_mosi.address THEN -- Double implemented ?? toggle?
-- nxt_toggle_adr_cnt <= INCR_UVEC(common_ram_r_w_0_miso.rddata, 1); -- Double implemented ??
ELSIF toggle_detect_pp = '1' THEN -- dp_pipeline_src_out_pp: 2
nxt_bin_writer_mosi.wr <= '1';
nxt_bin_writer_mosi.wrdata <= TO_UVEC( (prev_prev_wrdata+1), c_mem_data_w); -- prev_wrdata + rd_adr_cnt + toggle_adr_cnt??? + 1 òf prev_prev_wrdata + 1 ??
nxt_bin_writer_mosi.address <= bin_reader_mosi_pp.address;
-- nxt_toggle_adr_cnt <= 0;
nxt_prev_wrdata <= prev_prev_wrdata+1;
dbg_state_string <= "td ";
ELSIF rd_cnt_allowed_pp = '1' THEN
-- nxt_rd_adr_cnt <= rd_adr_cnt + 1; -- << !! is rd_adr_cnt really necessary? prev_wrdata might fulfill the need !!
nxt_bin_writer_mosi.wr <= '1';
-- IF sync_detect_ppp = '1' THEN
-- nxt_bin_writer_mosi.wrdata <= TO_UVEC( (rd_adr_cnt + 1), c_mem_data_w); -- snk_in.sync (impossible); dp_pipeline_src_out_p (thus 1st cnt): 2 (cnt+1?); dp_pipeline_src_out_pp (1st or maybe 2nd cnt): cnt+1
-- dbg_state_string <= "rs ";
-- ELSE
nxt_bin_writer_mosi.wrdata <= TO_UVEC( (prev_wrdata + rd_adr_cnt + 1), c_mem_data_w); -- c_word_w); -- maybe RAM + cnt + 1 ?? -- only prev_wrdata + 1 necessary
nxt_prev_wrdata <= prev_wrdata + 1;
dbg_state_string <= "r# ";
-- END IF;
nxt_bin_writer_mosi.address <= bin_reader_mosi_pp.address;
ELSIF sync_detect_pp = '1' THEN -- snk_in.sync at least -- good as it is!
nxt_bin_writer_mosi.wr <= '1';
nxt_bin_writer_mosi.wrdata <= TO_UVEC(1, c_mem_data_w); -- snk_in.sync: 1; dp_pipeline_src_out_p.sync (thus new adress): 1; dp_pipeline_src_out_pp.sync (thus new adress): 1
nxt_bin_writer_mosi.address <= bin_reader_mosi_pp.address;
-- nxt_rd_adr_cnt <= 0; -- really necessary ??
nxt_prev_wrdata <= 1;
dbg_state_string <= "sd ";
ELSIF same_r_w_address_pp = '1' THEN
nxt_bin_writer_mosi.wr <= '1';
nxt_bin_writer_mosi.wrdata <= TO_UVEC( (prev_prev_prev_wrdata+1), c_mem_data_w);
nxt_bin_writer_mosi.address <= bin_reader_mosi_pp.address;
nxt_prev_wrdata <= prev_prev_prev_wrdata + 1;
dbg_state_string <= "srw";
END IF;
END PROCESS;
p_bin_writer_mosi : PROCESS(dp_clk, dp_rst, nxt_bin_writer_mosi, nxt_rd_adr_cnt, nxt_prev_wrdata, prev_wrdata, prev_prev_wrdata) IS
BEGIN
IF dp_rst = '1' THEN
bin_writer_mosi <= c_mem_mosi_rst;
ELSIF RISING_EDGE(dp_clk) THEN
bin_writer_mosi <= nxt_bin_writer_mosi;
-- rd_adr_cnt <= nxt_rd_adr_cnt;
-- toggle_adr_cnt <= nxt_toggle_adr_cnt;
prev_wrdata <= nxt_prev_wrdata;
prev_prev_wrdata<= prev_wrdata;
prev_prev_prev_wrdata <= prev_prev_wrdata;
END IF;
END PROCESS;
-----------------------------------------------------------------------------
-- Bin Arbiter: Determine next RAM access
-- . in : bin_reader_mosi (latency: 0)
-- : init_phase (latency: 0)
-- : prev_bin_reader_mosi (latency: 1)
-- : bin_writer_mosi (latency: 3)
-- . out : bin_arbiter_rd_mosi (latency: 1)
-- . : bin_arbiter_wr_mosi (latency: 4)
-----------------------------------------------------------------------------
nxt_bin_arbiter_wr_mosi <= bin_writer_mosi; --TODO - The rd and wr mosi should not have the same address. v met 2 cycles rd mag, met 3 cycles niet, dus klopt dit wel?, moet hier niet bin_reader_mosi_pp staan? --AND !(A=B)
nxt_bin_arbiter_rd_mosi.rd <= bin_reader_mosi.rd WHEN (bin_reader_mosi.address /= prev_bin_reader_mosi.address AND bin_reader_mosi.address /= bin_reader_mosi_pp.address AND NOT(bin_reader_mosi.address = bin_reader_mosi_ppp.address) )
-- AND sync_detect='0')
OR (init_phase = '1') ELSE '0'; -- bin_writer_mosi(adress 3cycles ago?) .address when .rd='1' ????
nxt_bin_arbiter_rd_mosi.address <= bin_reader_mosi.address;
p_bin_arbiter_mosi : PROCESS(dp_clk, dp_rst, nxt_bin_arbiter_wr_mosi, nxt_bin_arbiter_rd_mosi) IS
BEGIN
IF dp_rst = '1' THEN
bin_arbiter_wr_mosi <= c_mem_mosi_rst;
bin_arbiter_rd_mosi <= c_mem_mosi_rst;
ELSIF RISING_EDGE(dp_clk) THEN
bin_arbiter_wr_mosi <= nxt_bin_arbiter_wr_mosi;
bin_arbiter_rd_mosi <= nxt_bin_arbiter_rd_mosi;
END IF;
END PROCESS;
-----------------------------------------------------------------------------
-- RAM that contains the bins
-- . in : bin_arbiter_wr_mosi (latency: 4)
-- . in : bin_arbiter_rd_mosi (latency: 1)
-- . out : common_ram_r_w_0_miso (latency: 2)
-----------------------------------------------------------------------------
common_ram_r_w_0: ENTITY common_lib.common_ram_r_w
GENERIC MAP (
g_technology => c_tech_select_default,
g_ram => c_ram,
g_init_file => "UNUSED"
)
PORT MAP (
rst => dp_rst,
clk => dp_clk,
clken => '1',
wr_en => bin_arbiter_wr_mosi.wr,
wr_adr => bin_arbiter_wr_mosi.address(c_adr_w-1 DOWNTO 0),
wr_dat => bin_arbiter_wr_mosi.wrdata(c_word_w-1 DOWNTO 0),
rd_en => bin_arbiter_rd_mosi.rd,
rd_adr => bin_arbiter_rd_mosi.address(c_adr_w-1 DOWNTO 0),
rd_dat => common_ram_r_w_0_miso.rddata(c_word_w-1 DOWNTO 0),
rd_val => common_ram_r_w_0_miso.rdval
);
END rtl;
-------------------------------------------------------------------------------
--
-- Copyright 2020
-- 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: J.W.E. Oudman
-- Purpose: Provide MM slave register for st_histogram
-- Description:
-- Because the st_histogram component uses 2 RAM blocks that are swapped
-- after every sync pulse, both blocks have to work in the dp clock domain
-- and the Memory Mapped bus coming out of the component consequently also
-- works in the dp clock domain.
--
-- To convert the signals to the mm clock domain the common_reg_cross_domain
-- component is used. Because the inner workings of that component is
-- dependent on some components that take time to reliably stabialize the
-- conversion takes 12 mm clock cycles before the next address may be
-- requested.
--
--
-- [Alternative: shared dual clocked RAM block]
--
--
-------------------------------------------------------------------------------
LIBRARY IEEE, common_lib, dp_lib;-- mm_lib, technology_lib,
USE IEEE.std_logic_1164.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
--USE technology_lib.technology_select_pkg.ALL;
ENTITY st_histogram_reg IS
-- GENERIC (
-- g_nof_bins : NATURAL := 512; -- is a power of 2 and g_nof_bins <= c_data_span; max. 512
-- g_str : STRING := "freq.density" -- to select output to MM bus ("frequency" or "freq.density")
-- );
PORT (
dp_rst : IN STD_LOGIC;
dp_clk : IN STD_LOGIC;
mm_rst : IN STD_LOGIC;
mm_clk : IN STD_LOGIC;
-- DP clocked memory bus
mas_out_ram_mosi : OUT t_mem_mosi ;--:= c_mem_mosi_rst; -- Beware, works in dp clock domain !
mas_in_ram_miso : IN t_mem_miso ;--:= c_mem_miso_rst; -- '' !
-- ram_st_histogram_mosi : OUT t_mem_mosi; -- Beware, works in dp clock domain !
-- ram_st_histogram_miso : IN t_mem_miso; -- '' !
-- Memory Mapped
ram_mosi : IN t_mem_mosi;
ram_miso : OUT t_mem_miso
);
END st_histogram_reg;
ARCHITECTURE str OF st_histogram_reg IS
-- CONSTANT c_mm_reg : t_c_mem := (latency => 1,
-- adr_w => 1,
-- dat_w => c_word_w,
-- nof_dat => 1,
-- init_sl => g_default_value);
BEGIN
u_common_reg_cross_domain_mosi_address : ENTITY common_lib.common_reg_cross_domain
PORT MAP (
in_rst => mm_rst,
in_clk => mm_clk,
in_new => ram_mosi.rd,
in_dat => ram_mosi.address,
out_rst => dp_rst,
out_clk => dp_clk,
out_dat => mas_out_ram_mosi.address,
out_new => mas_out_ram_mosi.rd
);
u_reg_cross_domain_miso_rddata : ENTITY common_lib.common_reg_cross_domain
PORT MAP (
in_rst => dp_rst,
in_clk => dp_clk,
in_new => mas_in_ram_miso.rdval,
in_dat => mas_in_ram_miso.rddata,
out_rst => mm_rst,
out_clk => mm_clk,
out_dat => ram_miso.rddata,
out_new => ram_miso.rdval
);
END str;
-------------------------------------------------------------------------------
--
-- Copyright 2020
-- 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: J.W.E. Oudman
-- Purpose: Create a histogram from the input data and present it to the MM bus
-- Description:
--
--
--
-------------------------------------------------------------------------------
LIBRARY IEEE, common_lib, mm_lib, dp_lib;
USE IEEE.std_logic_1164.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 dp_lib.dp_stream_pkg.ALL;
ENTITY tb_mms_st_histogram IS
GENERIC(
g_sync_length : NATURAL := 338;
g_nof_sync : NATURAL := 3;
g_data_w : NATURAL := 4;
g_nof_bins : NATURAL := 8;
g_nof_data : NATURAL := 338;
g_str : STRING := "freq.density";
g_valid_gap : BOOLEAN := FALSE;
g_snk_in_data_sim_type : STRING := "counter" -- "counter" or "toggle"
);
END tb_mms_st_histogram;
ARCHITECTURE tb OF tb_mms_st_histogram IS
CONSTANT c_adr_w : NATURAL := ceil_log2(g_nof_bins);
CONSTANT c_mm_init_time : NATURAL := 5;
CONSTANT c_dp_inti_time : NATURAL := 5;
SIGNAL tb_end : STD_LOGIC := '0';
SIGNAL first_sync : STD_LOGIC := '0';
----------------------------------------------------------------------------
-- Clocks and resets
----------------------------------------------------------------------------
CONSTANT c_mm_clk_period : TIME := 20 ns;
CONSTANT c_dp_clk_period : TIME := 5 ns;
SIGNAL mm_rst : STD_LOGIC := '1';
SIGNAL mm_clk : STD_LOGIC := '1';
SIGNAL dp_rst : STD_LOGIC;
SIGNAL dp_clk : STD_LOGIC := '1';
----------------------------------------------------------------------------
-- Streaming Input
----------------------------------------------------------------------------
SIGNAL st_histogram_snk_in : t_dp_sosi;
----------------------------------------------------------------------------
-- Memory Mapped Input
----------------------------------------------------------------------------
SIGNAL st_histogram_ram_mosi : t_mem_mosi;
SIGNAL st_histogram_ram_miso : t_mem_miso;
BEGIN
----------------------------------------------------------------------------
-- Clock and reset generation
----------------------------------------------------------------------------
mm_clk <= NOT mm_clk OR tb_end AFTER c_mm_clk_period/2;
mm_rst <= '1', '0' AFTER c_mm_clk_period*c_mm_init_time;
dp_clk <= NOT dp_clk OR tb_end AFTER c_dp_clk_period/2;
dp_rst <= '1', '0' AFTER c_dp_clk_period*c_dp_inti_time;
----------------------------------------------------------------------------
-- Source: counter stimuli
----------------------------------------------------------------------------
p_data : PROCESS(dp_rst, dp_clk, st_histogram_snk_in)
BEGIN
IF g_snk_in_data_sim_type = "counter" THEN
IF dp_rst='1' THEN
st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= (OTHERS=>'0');
ELSIF rising_edge(dp_clk) AND st_histogram_snk_in.valid='1' THEN
st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= INCR_UVEC(st_histogram_snk_in.data(g_data_w-1 DOWNTO 0), 1);
END IF;
ELSIF g_snk_in_data_sim_type = "toggle" THEN
IF dp_rst='1' THEN
st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= (OTHERS=>'0');
ELSIF rising_edge(dp_clk) AND st_histogram_snk_in.valid='1' THEN
IF st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) = TO_UVEC(0, g_data_w) THEN
st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= TO_UVEC(1, g_data_w);
ELSE
st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= TO_UVEC(0, g_data_w);
END IF;
END IF;
END IF;
END PROCESS;
p_stimuli : PROCESS
BEGIN
IF g_valid_gap = FALSE THEN
-- dp_rst <= '1';
st_histogram_snk_in.sync <= '0';
st_histogram_snk_in.valid <= '0';
WAIT UNTIL rising_edge(dp_clk);
-- FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
-- dp_rst <= '0';
FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
st_histogram_snk_in.valid <= '1';
FOR I IN 0 TO g_nof_sync-1 LOOP
st_histogram_snk_in.sync <= '1';
WAIT UNTIL rising_edge(dp_clk);
st_histogram_snk_in.sync <= '0';
FOR I IN 0 TO g_sync_length-1 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
END LOOP;
FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
tb_end <= '1';
WAIT;
ELSIF g_valid_gap = TRUE THEN
-- dp_rst <= '1';
st_histogram_snk_in.sync <= '0';
st_histogram_snk_in.valid <= '0';
WAIT UNTIL rising_edge(dp_clk);
-- FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
-- dp_rst <= '0';
FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
st_histogram_snk_in.valid <= '1';
FOR I IN 0 TO g_nof_sync-2 LOOP
st_histogram_snk_in.sync <= '1';
WAIT UNTIL rising_edge(dp_clk);
st_histogram_snk_in.sync <= '0';
FOR I IN 0 TO (g_sync_length/2)-1 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
st_histogram_snk_in.valid <= '0';
WAIT UNTIL rising_edge(dp_clk);
--WAIT UNTIL rising_edge(dp_clk);
--WAIT UNTIL rising_edge(dp_clk);
st_histogram_snk_in.valid <= '1';
FOR I IN 0 TO (g_sync_length/4)-1 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
st_histogram_snk_in.valid <= '0';
WAIT UNTIL rising_edge(dp_clk);
--st_histogram_snk_in.valid <= '0';
st_histogram_snk_in.sync <= '1';
WAIT UNTIL rising_edge(dp_clk);
st_histogram_snk_in.valid <= '1';
st_histogram_snk_in.sync <= '0';
FOR I IN 0 TO (g_sync_length/4)-1 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
END LOOP;
FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
tb_end <= '1';
WAIT;
END IF;
END PROCESS;
----------------------------------------------------------------------------
-- Source: read MM bus stimuli
----------------------------------------------------------------------------
-- p_mm_stimuli : PROCESS --(st_histogram_snk_in.sync)
-- BEGIN
-- IF mm_rst='1' THEN
-- st_histogram_ram_mosi <= c_mem_mosi_rst; --.address(c_adr_w-1 DOWNTO 0) <= (OTHERS=>'0');
---- ELSIF rising_edge(mm_clk) THEN --AND st_histogram_snk_in.valid='1'
-- ELSE
-- IF first_sync = '0' THEN
-- WAIT UNTIL st_histogram_snk_in.sync = '1';
-- first_sync <= '1';
-- -- wait till one RAM block is written
-- FOR I IN 0 TO (g_sync_length/4) LOOP WAIT UNTIL rising_edge(mm_clk); END LOOP;
-- -- wait for some more cycles
-- FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(mm_clk); END LOOP;
---- ELSIF rising_edge(mm_clk) THEN
-- ELSE
-- FOR I IN 0 TO g_nof_bins-1
-- --
-- st_histogram_ram_mosi.rd <= '1';
-- st_histogram_ram_mosi.address(c_adr_w-1 DOWNTO 0) <= INCR_UVEC(st_histogram_ram_mosi.address(c_adr_w-1 DOWNTO 0), 1);
-- END IF;
-- END IF;
-- END PROCESS;
p_mm_stimuli : PROCESS --(st_histogram_snk_in.sync)
BEGIN
--IF mm_rst='1' THEN
st_histogram_ram_mosi <= c_mem_mosi_rst; --.address(c_adr_w-1 DOWNTO 0) <= (OTHERS=>'0');
-- ELSIF rising_edge(mm_clk) THEN --AND st_histogram_snk_in.valid='1'
--ELSE
--IF first_sync = '0' THEN
WAIT UNTIL st_histogram_snk_in.sync = '1';
--first_sync <= '1';
-- wait till one RAM block is written
FOR I IN 0 TO (g_sync_length/4) LOOP WAIT UNTIL rising_edge(mm_clk); END LOOP;
-- wait for some more cycles
FOR I IN 0 TO 2 LOOP WAIT UNTIL rising_edge(mm_clk); END LOOP;
-- ELSIF rising_edge(mm_clk) THEN
--ELSE
FOR I IN 0 TO g_nof_bins-1 LOOP
proc_mem_mm_bus_rd(I, mm_clk, st_histogram_ram_mosi);
proc_common_wait_some_cycles(mm_clk, 11);
-- miso.rddata arrives
END LOOP;
--
--st_histogram_ram_mosi.rd <= '1';
--st_histogram_ram_mosi.address(c_adr_w-1 DOWNTO 0) <= INCR_UVEC(st_histogram_ram_mosi.address(c_adr_w-1 DOWNTO 0), 1);
--END IF;
--END IF;
END PROCESS;
-- -- Read data request to the MM bus
-- -- Use proc_mem_mm_bus_rd_latency() to wait for the MM MISO rd_data signal
-- -- to show the data after some read latency
-- PROCEDURE proc_mem_mm_bus_rd(CONSTANT rd_addr : IN NATURAL;
-- SIGNAL mm_clk : IN STD_LOGIC;
-- SIGNAL mm_miso : IN t_mem_miso;
-- SIGNAL mm_mosi : OUT t_mem_mosi) IS
-- BEGIN
-- mm_mosi.address <= TO_MEM_ADDRESS(rd_addr);
-- proc_mm_access(mm_clk, mm_miso.waitrequest, mm_mosi.rd);
-- END proc_mem_mm_bus_rd;
---- Issues a rd or a wr MM access and wait for it to have finished
-- PROCEDURE proc_mm_access(SIGNAL mm_clk : IN STD_LOGIC;
-- SIGNAL mm_waitreq : IN STD_LOGIC;
-- SIGNAL mm_access : OUT STD_LOGIC) IS
-- BEGIN
-- mm_access <= '1';
-- WAIT UNTIL rising_edge(mm_clk);
-- WHILE mm_waitreq='1' LOOP
-- WAIT UNTIL rising_edge(mm_clk);
-- END LOOP;
-- mm_access <= '0';
-- END proc_mm_access;
-- proc_mem_mm_bus_rd(0, mm_clk, mm_mosi); -- Read nof_early_syncs
-- proc_common_wait_some_cycles(mm_clk, 1);
-- mm_nof_early_syncs <= mm_miso.rddata(c_word_w-1 DOWNTO 0);
----------------------------------------------------------------------------
-- DUT: Device Under Test
----------------------------------------------------------------------------
u_mms_st_histogram : ENTITY work.mms_st_histogram
GENERIC MAP(
g_in_data_w => g_data_w,
g_nof_bins => g_nof_bins,
g_nof_data => g_nof_data,
g_str => g_str
)
PORT MAP (
dp_rst => dp_rst,
dp_clk => dp_clk,
mm_rst => mm_rst,
mm_clk => mm_clk,
-- Streaming
snk_in => st_histogram_snk_in,
-- Memory Mapped
ram_mosi => st_histogram_ram_mosi,
ram_miso => st_histogram_ram_miso --OPEN
);
END tb;
-------------------------------------------------------------------------------
--
-- Copyright 2020
-- 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: J.W.E. Oudman
-- Purpose: Testing the st_histogram component on it's pecularities
-- Description:
-- The st_histogram component is mainly about saving counter data and
-- making the saved data available for the MM master. The working of the
-- RAM blocks has a big influence on this. That is why the testbench is made
-- to generate data that can make related problems with that vissible.
--
-- To know if there can constantly new data be witten to the RAM blocks
-- a simple counter is sufficient.
--
-- Because there is a delay between requesting and writing back of data of
-- 2 cycles and it is illegal to read and write on the same adres at the
-- same time, a special situation can happen where the addresses can toggle
-- (e.g. 0; 1; 0; 1) which causes incorrect counting. To simulate this the
-- g_snk_in_data_sim_type can be set to 'toggle'
--
-- Only incoming data while snk_in.valid = '1' may be counted. To keep the
-- simulation simple there is the option to let there be some gap's in the
-- valid data (or not) where snk_in.valid = '0' by setting the g_valid_gap
-- to TRUE or FALSE.
--
-------------------------------------------------------------------------------
LIBRARY IEEE, common_lib, mm_lib, dp_lib;
USE IEEE.std_logic_1164.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE common_lib.tb_common_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
ENTITY tb_st_histogram IS
GENERIC(
g_sync_length : NATURAL := 200;
g_nof_sync : NATURAL := 3;
g_data_w : NATURAL := 4; --4 ; 1
g_nof_bins : NATURAL := 8; --8 ; 2
g_nof_data : NATURAL := 200;
--g_str : STRING := "freq.density";
g_valid_gap : BOOLEAN := TRUE;
g_snk_in_data_sim_type : STRING := "counter" -- "counter" or "toggle" or "same rw" or "mix"
);
END tb_st_histogram;
ARCHITECTURE tb OF tb_st_histogram IS
CONSTANT c_adr_w : NATURAL := ceil_log2(g_nof_bins);
CONSTANT c_adr_low_calc : INTEGER := g_data_w-c_adr_w; -- Calculation might yield a negative number
CONSTANT c_adr_low : NATURAL := largest(0, c_adr_low_calc); -- Override any negative value of c_adr_low_calc
--SIGNAL position : INTEGER range g_data_w'RANGE;
CONSTANT c_dp_inti_time : NATURAL := 5;
SIGNAL tb_end : STD_LOGIC := '0';
SIGNAL pre_valid : STD_LOGIC := '0';
SIGNAL prev_unvalid : STD_LOGIC := '0';
SIGNAL init_phase : STD_LOGIC := '1';
SIGNAL toggle_start : STD_LOGIC := '0';
----------------------------------------------------------------------------
-- Same read write test stimuli
----------------------------------------------------------------------------
TYPE t_srw_arr IS ARRAY (NATURAL RANGE <>) OF INTEGER;
CONSTANT c_srw_arr : t_srw_arr := (0,0,1,1,0,0,1,2,3, 1, 2, 3, 0, 3, 3, 0, 3);
-- 1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17
SIGNAL srw_index_cnt : NATURAL := 0;
----------------------------------------------------------------------------
-- Clocks and resets
----------------------------------------------------------------------------
CONSTANT c_dp_clk_period : TIME := 5 ns;
SIGNAL dp_rst : STD_LOGIC;
SIGNAL dp_clk : STD_LOGIC := '1';
----------------------------------------------------------------------------
-- Streaming Input
----------------------------------------------------------------------------
SIGNAL st_histogram_snk_in : t_dp_sosi;
BEGIN
----------------------------------------------------------------------------
-- Clock and reset generation
----------------------------------------------------------------------------
dp_clk <= NOT dp_clk OR tb_end AFTER c_dp_clk_period/2;
dp_rst <= '1', '0' AFTER c_dp_clk_period*c_dp_inti_time;
----------------------------------------------------------------------------
-- Source: stimuli
-- st_histogram_snk_in.data counter or toggle stimuli
-- .valid with or without gap's in valid stimuli
-- .sync sync stimuli
----------------------------------------------------------------------------
init_phase <= '0' WHEN st_histogram_snk_in.sync = '1';
p_data : PROCESS(dp_rst, dp_clk, st_histogram_snk_in)
BEGIN
IF g_snk_in_data_sim_type = "counter" THEN
IF dp_rst='1' THEN
st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= (OTHERS=>'0');
ELSIF rising_edge(dp_clk) AND pre_valid='1' THEN -- st_histogram_snk_in.valid='1' THEN -- maybe needs init_cnt_start = '1' instead?
IF prev_unvalid = '0' THEN
st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= INCR_UVEC(st_histogram_snk_in.data(g_data_w-1 DOWNTO 0), 1);
ELSIF prev_unvalid = '1' THEN
st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= INCR_UVEC(st_histogram_snk_in.data(g_data_w-1 DOWNTO 0), -1);
prev_unvalid <= '0';
END IF;
ELSIF rising_edge(dp_clk) AND pre_valid='0' AND init_phase='0' THEN -- st_histogram_snk_in.valid='0' AND init_phase = '0' THEN
IF prev_unvalid = '0' THEN
st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= INCR_UVEC(st_histogram_snk_in.data(g_data_w-1 DOWNTO 0), 2);
prev_unvalid <= '1';
END IF;
END IF;
ELSIF g_snk_in_data_sim_type = "toggle" THEN
IF dp_rst='1' THEN
st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= (OTHERS=>'0');
ELSIF rising_edge(dp_clk) AND st_histogram_snk_in.valid='1' THEN -- maybe needs init_cnt_start = '1' instead?
IF st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) = TO_UVEC(0, g_data_w) THEN -- c_adr_low
st_histogram_snk_in.data(c_adr_low) <= '1'; -- TO_UVEC(1, g_data_w); --g_data_w-1 DOWNTO 0
ELSE
st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= TO_UVEC(0, g_data_w);
END IF;
END IF;
ELSIF g_snk_in_data_sim_type = "same rw" THEN
IF dp_rst='1' THEN
st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= (OTHERS=>'0');
ELSIF rising_edge(dp_clk) AND pre_valid='1' THEN -- AND init_phase='0' didn't work
st_histogram_snk_in.data(g_data_w-1 DOWNTO c_adr_low) <= TO_UVEC(c_srw_arr(srw_index_cnt), c_adr_w); --placeholder !
IF srw_index_cnt = c_srw_arr'LENGTH -1 THEN
srw_index_cnt <= 0;
ELSE
srw_index_cnt <= srw_index_cnt+1;
END IF;
END IF;
ELSIF g_snk_in_data_sim_type = "mix" THEN
IF toggle_start = '1' THEN
-- toggle part
IF dp_rst='1' THEN
st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= (OTHERS=>'0');
ELSIF rising_edge(dp_clk) AND st_histogram_snk_in.valid='1' THEN -- maybe needs init_cnt_start = '1' instead?
IF st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) = TO_UVEC(0, g_data_w) THEN -- c_adr_low
st_histogram_snk_in.data(c_adr_low) <= '1'; -- TO_UVEC(1, g_data_w); --g_data_w-1 DOWNTO 0
ELSE
st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= TO_UVEC(0, g_data_w);
END IF;
END IF;
-- end toggle part
ELSE
-- counter part
IF dp_rst='1' THEN
st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= (OTHERS=>'0');
ELSIF rising_edge(dp_clk) AND pre_valid='1' THEN -- st_histogram_snk_in.valid='1' THEN -- maybe needs init_cnt_start = '1' instead?
IF prev_unvalid = '0' THEN
st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= INCR_UVEC(st_histogram_snk_in.data(g_data_w-1 DOWNTO 0), 1);
ELSIF prev_unvalid = '1' THEN
st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= INCR_UVEC(st_histogram_snk_in.data(g_data_w-1 DOWNTO 0), -1);
prev_unvalid <= '0';
END IF;
ELSIF rising_edge(dp_clk) AND pre_valid='0' AND init_phase='0' THEN -- st_histogram_snk_in.valid='0' AND init_phase = '0' THEN
IF prev_unvalid = '0' THEN
st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= INCR_UVEC(st_histogram_snk_in.data(g_data_w-1 DOWNTO 0), 2);
prev_unvalid <= '1';
END IF;
END IF;
-- end counter part
END IF;
END IF;
END PROCESS;
p_stimuli : PROCESS
BEGIN
IF g_valid_gap = FALSE THEN
-- initializing
st_histogram_snk_in.sync <= '0';
st_histogram_snk_in.valid <= '0';
WAIT UNTIL rising_edge(dp_clk);
FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
pre_valid <= '1';
st_histogram_snk_in.valid <= '1';
-- generating g_nof_sync sync pulses with g_sync_length cycles between
FOR I IN 0 TO g_nof_sync-1 LOOP
toggle_start <= '1';
st_histogram_snk_in.sync <= '1';
WAIT UNTIL rising_edge(dp_clk);
st_histogram_snk_in.sync <= '0';
proc_common_wait_some_cycles(dp_clk, 2);
toggle_start <= '0';
FOR I IN 0 TO g_sync_length-1 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP; -- -4 ipv -1 ?
END LOOP;
-- ending
FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
tb_end <= '1';
WAIT;
ELSIF g_valid_gap = TRUE THEN
-- initializing
st_histogram_snk_in.sync <= '0';
st_histogram_snk_in.valid <= '0';
WAIT UNTIL rising_edge(dp_clk);
FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
pre_valid <= '1';
st_histogram_snk_in.valid <= '1';
-- generating g_nof_sync-1 sync pulses with gaps in 'valid'
FOR I IN 0 TO g_nof_sync-2 LOOP
toggle_start <= '1';
st_histogram_snk_in.sync <= '1';
WAIT UNTIL rising_edge(dp_clk);
st_histogram_snk_in.sync <= '0';
proc_common_wait_some_cycles(dp_clk, 2);
toggle_start <= '0';
FOR I IN 0 TO (g_sync_length/2)-5 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP; -- -5 ipv -2 ?
pre_valid <= '0';
WAIT UNTIL rising_edge(dp_clk);
st_histogram_snk_in.valid <= '0';
pre_valid <= '1'; -- gap 1 clock cycles
WAIT UNTIL rising_edge(dp_clk);
--WAIT UNTIL rising_edge(dp_clk); -- gap 2 clock cycles
--WAIT UNTIL rising_edge(dp_clk); -- gap 3 clock cycles
st_histogram_snk_in.valid <= '1';
FOR I IN 0 TO (g_sync_length/4)-2 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
pre_valid <= '0';
WAIT UNTIL rising_edge(dp_clk);
st_histogram_snk_in.valid <= '0';
WAIT UNTIL rising_edge(dp_clk);
--st_histogram_snk_in.valid <= '0'; -- gap while sync
st_histogram_snk_in.sync <= '1';
pre_valid <= '1';
WAIT UNTIL rising_edge(dp_clk);
st_histogram_snk_in.valid <= '1';
st_histogram_snk_in.sync <= '0';
FOR I IN 0 TO (g_sync_length/4)-1 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
END LOOP;
-- ending
FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
tb_end <= '1';
WAIT;
END IF;
END PROCESS;
----------------------------------------------------------------------------
-- DUT: Device Under Test
----------------------------------------------------------------------------
u_st_histogram : ENTITY work.st_histogram_8_april
GENERIC MAP(
g_in_data_w => g_data_w,
g_nof_bins => g_nof_bins,
g_nof_data => g_nof_data
--g_str => g_str
)
PORT MAP (
dp_rst => dp_rst,
dp_clk => dp_clk,
-- Streaming
snk_in => st_histogram_snk_in,
-- Memory Mapped
ram_mosi => c_mem_mosi_rst,-- sla_in_
ram_miso => OPEN -- sla_out_
);
END tb;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment