diff --git a/libraries/dsp/st/hdllib.cfg b/libraries/dsp/st/hdllib.cfg index 4631ff20209e6f9758a4d43659f61f3e6e2c3616..467f6c731cb83d9c39b4ef38f2d4992f22f19fd4 100644 --- a/libraries/dsp/st/hdllib.cfg +++ b/libraries/dsp/st/hdllib.cfg @@ -19,12 +19,14 @@ 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_mms_st_histogram.vhd tb/vhdl/tb_st_histogram.vhd tb/vhdl/tb_tb_st_histogram.vhd regression_test_vhdl = tb/vhdl/tb_st_acc.vhd #tb/vhdl/tb_st_calc.vhd -- tb is not self checking yet + tb/vhdl/tb_tb_st_histogram.vhd [modelsim_project_file] diff --git a/libraries/dsp/st/src/vhdl/mms_st_histogram.vhd b/libraries/dsp/st/src/vhdl/mms_st_histogram.vhd index 538f815e7a4972931599bb4a84e2dbcae8169cef..d0c367ad245f1abdf7c2a35b044a0166e6ba7484 100644 --- a/libraries/dsp/st/src/vhdl/mms_st_histogram.vhd +++ b/libraries/dsp/st/src/vhdl/mms_st_histogram.vhd @@ -21,7 +21,23 @@ -- Author: -- . Daniel van der Schuur -- Purpose: --- . MM-wrapper that adds registers and multi-instance support to st_histogram. +-- . MMS-wrapper that adds registers and multi-instance support to st_histogram. +-- Description: +-- . st_histogram_reg implements the registers to control all g_nof_instances +-- . This MMS wrapper contains logic to fill a local RAM with the contents of +-- a selected st_histogram instance. +-- Usage (see st_histogram_reg.vhd for the register map): +-- . Reading RAM contents: +-- 1) User writes instance to read (0..g_nof_instances-1) to ram_fill_inst +-- register via reg_mosi +-- 2) Users writes to bit 0 of fill_ram register via reg_mosi +-- . ram_filling status will go high +-- 3) User reads ram_filling status until it reads zero via reg_mosi +-- 4) User reads freshly filled RAM contents via ram_mosi +-- . Clearing the RAMs: +-- 1) User writes to bit 0 of ram_clear register to clear RAMs of all +-- g_nof_instances +-- . ram_clearing status will go high LIBRARY IEEE, common_lib, mm_lib, technology_lib, dp_lib; USE IEEE.std_logic_1164.ALL; @@ -58,18 +74,37 @@ ARCHITECTURE str OF mms_st_histogram IS CONSTANT c_reg_adr_w : NATURAL := 1; CONSTANT c_ram_adr_w : NATURAL := ceil_log2(g_nof_bins); + CONSTANT c_ram_dat_w : NATURAL := ceil_log2(g_nof_data_per_sync); - SIGNAL reg_mosi_arr : t_mem_mosi_arr(g_nof_instances-1 DOWNTO 0); - SIGNAL reg_miso_arr : t_mem_miso_arr(g_nof_instances-1 DOWNTO 0); + CONSTANT c_ram : t_c_mem := (latency => 1, + adr_w => c_ram_adr_w, + dat_w => c_ram_dat_w, + nof_dat => g_nof_bins, + init_sl => '0'); - SIGNAL dp_ram_mosi : t_mem_mosi; - SIGNAL dp_ram_miso : t_mem_miso; + CONSTANT c_addr_high : NATURAL := g_nof_bins-1; - SIGNAL ram_mosi_arr : t_mem_mosi_arr(g_nof_instances-1 DOWNTO 0); - SIGNAL ram_miso_arr : t_mem_miso_arr(g_nof_instances-1 DOWNTO 0); + SIGNAL common_ram_cr_cw_wr_mosi : t_mem_mosi; + SIGNAL nxt_common_ram_cr_cw_wr_mosi : t_mem_mosi; - SIGNAL ram_clear_arr : STD_LOGIC_VECTOR(g_nof_instances-1 DOWNTO 0); + SIGNAL common_ram_cr_cw_rd_mosi : t_mem_mosi; + SIGNAL common_ram_cr_cw_rd_miso : t_mem_miso; + + SIGNAL reg_mosi_arr : t_mem_mosi_arr(g_nof_instances-1 DOWNTO 0); + SIGNAL reg_miso_arr : t_mem_miso_arr(g_nof_instances-1 DOWNTO 0); + + SIGNAL ram_mosi_arr : t_mem_mosi_arr(g_nof_instances-1 DOWNTO 0); + SIGNAL ram_miso_arr : t_mem_miso_arr(g_nof_instances-1 DOWNTO 0); + + SIGNAL ram_clear : STD_LOGIC; SIGNAL ram_clearing_arr : STD_LOGIC_VECTOR(g_nof_instances-1 DOWNTO 0); + + SIGNAL ram_fill_inst : STD_LOGIC_VECTOR(ceil_log2(g_nof_instances)-1 DOWNTO 0); + SIGNAL ram_fill : STD_LOGIC; + SIGNAL ram_filling : STD_LOGIC; + SIGNAL nxt_ram_filling : STD_LOGIC; + SIGNAL address : STD_LOGIC_VECTOR(c_ram_adr_w-1 DOWNTO 0); + SIGNAL nxt_address : STD_LOGIC_VECTOR(c_ram_adr_w-1 DOWNTO 0); BEGIN @@ -89,33 +124,39 @@ BEGIN snk_in => snk_in_arr(i), - ram_clear => ram_clear_arr(i), + ram_clear => ram_clear, ram_clearing => ram_clearing_arr(i), ram_mosi => ram_mosi_arr(i), ram_miso => ram_miso_arr(i) ); - - u_st_histogram_reg : ENTITY work.st_histogram_reg - PORT MAP ( - dp_clk => dp_clk, - dp_rst => dp_rst, - - ram_clearing => ram_clearing_arr(i), - - mm_clk => mm_clk, - mm_rst => mm_rst, - - ram_clear => ram_clear_arr(i), - - reg_mosi => reg_mosi, - reg_miso => reg_miso - ); END GENERATE; + u_st_histogram_reg : ENTITY work.st_histogram_reg + GENERIC MAP ( + g_nof_instances => g_nof_instances + ) + PORT MAP ( + dp_clk => dp_clk, + dp_rst => dp_rst, + + ram_clearing => ram_clearing_arr(0), + ram_filling => ram_filling, + + mm_clk => mm_clk, + mm_rst => mm_rst, + + ram_clear => ram_clear, + ram_fill_inst => ram_fill_inst, + ram_fill => ram_fill, + + reg_mosi => reg_mosi, + reg_miso => reg_miso + ); + ------------------------------------------------------------------------------- - -- reg_mosi/miso multiplexer from g_nof_instances to 1 + -- MM multiplexer from g_nof_instances to 1 ------------------------------------------------------------------------------- u_common_mem_mux_reg : ENTITY common_lib.common_mem_mux GENERIC MAP ( @@ -131,22 +172,64 @@ BEGIN ------------------------------------------------------------------------------- - -- ram_mosi/miso multiplexer from g_nof_instances to 1 + -- Dual clock RAM: DP write side, MM read side ------------------------------------------------------------------------------- - u_common_mem_mux_ram : ENTITY common_lib.common_mem_mux - GENERIC MAP ( - g_nof_mosi => g_nof_instances, - g_mult_addr_w => c_ram_adr_w + u_common_ram_cr_cw : ENTITY common_lib.common_ram_cr_cw + GENERIC MAP ( + g_technology => c_tech_select_default, + g_ram => c_ram, + g_init_file => "UNUSED" ) PORT MAP ( - mosi => dp_ram_mosi, - miso => dp_ram_miso, - mosi_arr => ram_mosi_arr, - miso_arr => ram_miso_arr + wr_clk => dp_clk, + wr_rst => dp_rst, + wr_clken => '1', + wr_en => common_ram_cr_cw_wr_mosi.wr, + wr_adr => common_ram_cr_cw_wr_mosi.address(c_ram_adr_w-1 DOWNTO 0), + wr_dat => common_ram_cr_cw_wr_mosi.wrdata(c_ram_dat_w-1 DOWNTO 0), + rd_clk => mm_clk, + rd_rst => mm_rst, + rd_clken => '1', + rd_en => common_ram_cr_cw_rd_mosi.rd, + rd_adr => common_ram_cr_cw_rd_mosi.address(c_ram_adr_w-1 DOWNTO 0), + rd_dat => common_ram_cr_cw_rd_miso.rddata(c_ram_dat_w-1 DOWNTO 0), + rd_val => common_ram_cr_cw_rd_miso.rdval ); - - -- Cross clock domain from DP clock to MM clock NOTE - work in progress - ram_miso <= dp_ram_miso; - dp_ram_mosi <= ram_mosi; + -- User side MM bus for histogram readout + common_ram_cr_cw_rd_mosi <= ram_mosi; + ram_miso <= common_ram_cr_cw_rd_miso; + + + ------------------------------------------------------------------------------- + -- Logic to move st_histogram RAM contents into the dual clock RAM above + ------------------------------------------------------------------------------- + + -- Keep track of ram_filling status and address + nxt_ram_filling <= '0' WHEN TO_UINT(address)=c_addr_high ELSE '1' WHEN ram_fill='1' ELSE ram_filling; + nxt_address <= (OTHERS=>'0') WHEN ram_filling='0' ELSE INCR_UVEC(address, 1) WHEN ram_filling='1' ELSE address; + + -- Do read request on ram_mosi when ram_filling + ram_mosi_arr(TO_UINT(ram_fill_inst)).rd <= ram_filling; + ram_mosi_arr(TO_UINT(ram_fill_inst)).address(c_ram_adr_w-1 DOWNTO 0) <= address; + + -- Forward the read histogram data from ram_miso into write mosi of dual clock RAM + nxt_common_ram_cr_cw_wr_mosi.wr <= ram_miso_arr(TO_UINT(ram_fill_inst)).rdval; + nxt_common_ram_cr_cw_wr_mosi.wrdata(c_ram_dat_w-1 DOWNTO 0) <= ram_miso_arr(TO_UINT(ram_fill_inst)).rddata(c_ram_dat_w-1 DOWNTO 0); + nxt_common_ram_cr_cw_wr_mosi.address(c_ram_adr_w-1 DOWNTO 0) <= address; + + -- Registers + p_clk : PROCESS(dp_clk, dp_rst) IS + BEGIN + IF dp_rst = '0' THEN + common_ram_cr_cw_wr_mosi <= c_mem_mosi_rst; + address <= (OTHERS=>'0'); + ram_filling <= '0'; + ELSIF RISING_EDGE(dp_clk) THEN + common_ram_cr_cw_wr_mosi <= nxt_common_ram_cr_cw_wr_mosi; + address <= nxt_address; + ram_filling <= nxt_ram_filling; + END IF; + END PROCESS; + END str; diff --git a/libraries/dsp/st/src/vhdl/st_histogram.vhd b/libraries/dsp/st/src/vhdl/st_histogram.vhd index efad41951435988044c07868c7123072aeeae1f4..ec236d67b9fd5ab79542d78396d8ed8cce31c30f 100644 --- a/libraries/dsp/st/src/vhdl/st_histogram.vhd +++ b/libraries/dsp/st/src/vhdl/st_histogram.vhd @@ -49,6 +49,22 @@ -- |__________| | |___________| | |___________| -- | | -- bin_writer_mosi bin_arbiter_wr_mosi +-- Usage: +-- . The ram_mosi and ram_clear inputs apply to the RAM page that is inactive (not +-- being written to from data path) *at that time*. The user should take care to +-- time these controls such that the active RAM page does not swap before these +-- operations (ram_mosi readout, ram_clear) have finished. +-- Remarks: +-- . common_ram_r_w +-- . Why common_ram_r_w was selected: it uses a single clock +-- . We need to read and write back bins in the dp_clk clock domain, so our RAM +-- block needs to have 2 separate address inputs - but in the same clock domain. +-- . The other, dual clock, RAM blocks (e.g. common_ram_cr_cw) are based on +-- common_ram_crw_crw and use 2 address inputs (adr_a,adr_b), each in +-- its own (clk_a,clk_b) clock domain, which is not what we need here. +-- . Downside of common_ram_r_w: it uses a single clock +-- . This st_histogram.vhd operates in dp_clk domain only, so we need to +-- provide MM access to the user, in the mm_clk domain, elsewhere. LIBRARY IEEE, common_lib, mm_lib, technology_lib, dp_lib; USE IEEE.std_logic_1164.ALL; @@ -67,12 +83,12 @@ ENTITY st_histogram IS dp_clk : IN STD_LOGIC; dp_rst : IN STD_LOGIC; - snk_in : IN t_dp_sosi; + snk_in : IN t_dp_sosi; -- Active RAM page swaps on snk_in.sync - ram_clear : IN STD_LOGIC; - ram_clearing : OUT STD_LOGIC; + ram_clear : IN STD_LOGIC; -- Control input: Pulse high to clear the inactive RAM page + ram_clearing : OUT STD_LOGIC; -- Status output: high while RAM is being cleared - ram_mosi : IN t_mem_mosi; + ram_mosi : IN t_mem_mosi; -- MM access to the inactive RAM page ram_miso : OUT t_mem_miso ); END st_histogram; @@ -311,7 +327,7 @@ BEGIN common_ram_r_w_rd_mosi_arr(0) <= bin_arbiter_rd_mosi WHEN bin_arbiter_rd_ram_pointer='0' ELSE histogram_rd_mosi; common_ram_r_w_wr_mosi_arr(1) <= bin_arbiter_wr_mosi WHEN bin_arbiter_wr_ram_pointer='1' ELSE histogram_wr_mosi; common_ram_r_w_rd_mosi_arr(1) <= bin_arbiter_rd_mosi WHEN bin_arbiter_rd_ram_pointer='1' ELSE histogram_rd_mosi; - + -- Let bin_arbiter read RAM 0 while user reads RAM 1 and vice versa -- . We always want the MISO bus to switch 1 cycle later than the MOSI (such that the MM operation can finish); hence using prv_bin_arbiter_rd_ram_pointer. bin_arbiter_rd_miso <= common_ram_r_w_rd_miso_arr(0) WHEN prv_bin_arbiter_rd_ram_pointer='0' ELSE common_ram_r_w_rd_miso_arr(1); @@ -338,6 +354,7 @@ BEGIN ); END GENERATE; + ------------------------------------------------------------------------------- -- ram_clear control input - let user clear the RAM -- 1) User waits for PPS diff --git a/libraries/dsp/st/src/vhdl/st_histogram_reg.vhd b/libraries/dsp/st/src/vhdl/st_histogram_reg.vhd index bc01f52c88d8bb9240ecfa48238b64cf899d1b1d..f26b335e88e8243e0c913c22ddd89c7a6e2fca0b 100644 --- a/libraries/dsp/st/src/vhdl/st_histogram_reg.vhd +++ b/libraries/dsp/st/src/vhdl/st_histogram_reg.vhd @@ -26,6 +26,13 @@ -- . Address 0, bit 0 = RAM clear -- . Read : 'ram_clearing' status. '1' right after write of ram_clear. '0' when not clearing RAM (anymore). -- . Write: 'ram_clear ' control. '1' to clear RAM on write event. +-- . Address 1 = select RAM instance to fill (read out) +-- . Read : read back selected instance +-- . Write: select RAM instance to fill +-- . Address 2, bit 0 = RAM fill +-- . Read : 'ram_filling' status. '1' right after write of ram_fill. '0' when not filling RAM (anymore). +-- . Write: 'ram_fill ' control. '1' to fill RAM on write event. + LIBRARY IEEE, common_lib; USE IEEE.std_logic_1164.ALL; @@ -33,19 +40,25 @@ USE common_lib.common_pkg.ALL; USE common_lib.common_mem_pkg.ALL; ENTITY st_histogram_reg IS - + GENERIC ( + g_nof_instances : NATURAL + ); PORT ( - dp_clk : IN STD_LOGIC; - dp_rst : IN STD_LOGIC; - - ram_clear : OUT STD_LOGIC; - ram_clearing : IN STD_LOGIC; - - mm_clk : IN STD_LOGIC; - mm_rst : IN STD_LOGIC; - - reg_mosi : IN t_mem_mosi; - reg_miso : OUT t_mem_miso + dp_clk : IN STD_LOGIC; + dp_rst : IN STD_LOGIC; + + ram_clear : OUT STD_LOGIC; + ram_clearing : IN STD_LOGIC; + + ram_fill_inst : OUT STD_LOGIC_VECTOR(ceil_log2(g_nof_instances)-1 DOWNTO 0); + ram_fill : OUT STD_LOGIC; + ram_filling : IN STD_LOGIC; + + mm_clk : IN STD_LOGIC; + mm_rst : IN STD_LOGIC; + + reg_mosi : IN t_mem_mosi; + reg_miso : OUT t_mem_miso ); END st_histogram_reg; @@ -61,6 +74,10 @@ ARCHITECTURE rtl OF st_histogram_reg IS SIGNAL mm_ram_clear : STD_LOGIC; SIGNAL mm_ram_clearing : STD_LOGIC; + + SIGNAL mm_ram_fill_inst : STD_LOGIC_VECTOR(ceil_log2(g_nof_instances)-1 DOWNTO 0); + SIGNAL mm_ram_fill : STD_LOGIC; + SIGNAL mm_ram_filling : STD_LOGIC; BEGIN @@ -79,6 +96,7 @@ BEGIN -- Access event, register values mm_ram_clear <= '0'; + mm_ram_fill <= '0'; ELSIF rising_edge(mm_clk) THEN -- Read access defaults @@ -86,12 +104,17 @@ BEGIN -- Access event defaults mm_ram_clear <= '0'; + mm_ram_fill <= '0'; -- Write access: set register value IF reg_mosi.wr = '1' THEN CASE TO_UINT(reg_mosi.address(c_mm_reg.adr_w-1 DOWNTO 0)) IS WHEN 0 => mm_ram_clear <= '1'; + WHEN 1 => + mm_ram_fill_inst <= reg_mosi.wrdata(ceil_log2(g_nof_instances)-1 DOWNTO 0); + WHEN 2 => + mm_ram_fill <= '1'; WHEN OTHERS => NULL; -- unused MM addresses END CASE; @@ -103,6 +126,12 @@ BEGIN WHEN 0 => -- Read RAM clearing status reg_miso.rddata(0) <= mm_ram_clearing; + WHEN 1 => + -- Read selected RAM instance to fill + reg_miso.rddata(ceil_log2(g_nof_instances)-1 DOWNTO 0) <= mm_ram_fill_inst; + WHEN 2 => + -- Read RAM filling status + reg_miso.rddata(0) <= mm_ram_filling; WHEN OTHERS => NULL; -- unused MM addresses END CASE; END IF; @@ -127,7 +156,7 @@ BEGIN ------------------------------------------------------------------------------ -- ST --> MM - u_common_async : ENTITY common_lib.common_async + u_common_async_clear : ENTITY common_lib.common_async GENERIC MAP ( g_rst_level => '0' ) @@ -139,8 +168,20 @@ BEGIN dout => mm_ram_clearing ); + u_common_async_fill : ENTITY common_lib.common_async + GENERIC MAP ( + g_rst_level => '0' + ) + PORT MAP ( + clk => mm_clk, + rst => mm_rst, + + din => ram_filling, + dout => mm_ram_filling + ); + -- MM --> ST - u_common_spulse : ENTITY common_lib.common_spulse + u_common_spulse_clear : ENTITY common_lib.common_spulse PORT MAP ( in_clk => mm_clk, in_rst => mm_rst, @@ -153,5 +194,31 @@ BEGIN out_pulse => ram_clear ); - + + u_common_spulse_fill : ENTITY common_lib.common_spulse + PORT MAP ( + in_clk => mm_clk, + in_rst => mm_rst, + + in_pulse => mm_ram_fill, + in_busy => OPEN, + + out_clk => dp_clk, + out_rst => dp_rst, + + out_pulse => ram_fill + ); + + u_common_reg_cross_domain : ENTITY common_lib.common_reg_cross_domain + PORT MAP ( + in_clk => mm_clk, + in_rst => mm_rst, + in_dat => mm_ram_fill_inst, + in_done => OPEN, + out_clk => dp_clk, + out_rst => dp_rst, + out_dat => ram_fill_inst, + out_new => OPEN + ); + END rtl; diff --git a/libraries/dsp/st/tb/vhdl/tb_mms_st_histogram.vhd b/libraries/dsp/st/tb/vhdl/tb_mms_st_histogram.vhd new file mode 100644 index 0000000000000000000000000000000000000000..e930713ff475ea27c93da6d014af31fdfe2c844a --- /dev/null +++ b/libraries/dsp/st/tb/vhdl/tb_mms_st_histogram.vhd @@ -0,0 +1,138 @@ +------------------------------------------------------------------------------- +-- +-- 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: +-- . Daniel van der Schuur +-- Purpose: +-- . TB to verify correct MM access across clock domain by eye. +-- ModelSim usage: +-- . (open project, compile) +-- . (load simulation config) +-- . as 8 +-- . run -a +-- Description: +-- . reg_mosi/miso uses traditional _reg instance to cross clock domain and +-- therefor does not need additional checks. +-- . ram_mosi/miso uses several common_reg_cross_domain instances to let the +-- MM buses cross MM<->DP clock domain in both directions. Should work, but +-- is not a proven method - hence this TB. +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib, mm_lib, dp_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 common_lib.tb_common_mem_pkg.ALL; +USE common_lib.tb_common_pkg.ALL; +USE dp_lib.dp_stream_pkg.ALL; +USE dp_lib.tb_dp_pkg.ALL; + +ENTITY tb_mms_st_histogram IS +END tb_mms_st_histogram; + + +ARCHITECTURE tb OF tb_mms_st_histogram IS + + --------------------------------------------------------------------------- + -- Clocks and resets + --------------------------------------------------------------------------- + CONSTANT c_dp_clk_period : TIME := 5 ns; + CONSTANT c_mm_clk_period : TIME := 20 ns; + + SIGNAL dp_clk : STD_LOGIC := '1'; + SIGNAL dp_rst : STD_LOGIC; + + SIGNAL mm_clk : STD_LOGIC := '1'; + SIGNAL mm_rst : STD_LOGIC; + + SIGNAL tb_end : STD_LOGIC := '0'; + + ---------------------------------------------------------------------------- + -- st_histogram + ---------------------------------------------------------------------------- + SIGNAL st_histogram_snk_in : t_dp_sosi; + + SIGNAL st_histogram_reg_mosi : t_mem_mosi; + SIGNAL st_histogram_reg_miso : t_mem_miso; + + SIGNAL st_histogram_ram_mosi : t_mem_mosi; + SIGNAL st_histogram_ram_miso : t_mem_miso; + + +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*10; + + mm_clk <= NOT mm_clk OR tb_end AFTER c_mm_clk_period/2; + mm_rst <= '1', '0' AFTER c_mm_clk_period*10; + + + ---------------------------------------------------------------------------- + -- mms_st_histogram + ---------------------------------------------------------------------------- + u_mms_st_histogram : ENTITY work.mms_st_histogram + GENERIC MAP( + g_nof_instances => 1, + g_data_w => 8, + g_nof_bins => 256, + g_nof_data_per_sync => 1024 + ) + PORT MAP ( + dp_clk => dp_clk, + dp_rst => dp_rst, + + mm_clk => mm_clk, + mm_rst => mm_rst, + + snk_in_arr(0)=> st_histogram_snk_in, + + reg_mosi => st_histogram_reg_mosi, + reg_miso => st_histogram_reg_miso, + + ram_mosi => st_histogram_ram_mosi, + ram_miso => st_histogram_ram_miso + ); + + ---------------------------------------------------------------------------- + -- Readout of RAM + ---------------------------------------------------------------------------- + -- Perform MM read + p_verify_mm_read : PROCESS + BEGIN + st_histogram_ram_mosi <= c_mem_mosi_rst; + proc_common_wait_until_low(mm_clk, mm_rst); + proc_common_wait_some_cycles(mm_clk, 10); + + -- Read address 7 of the RAM + proc_mem_mm_bus_rd(7, mm_clk, st_histogram_ram_mosi); + + proc_common_wait_some_cycles(mm_clk, 10); + tb_end <= '1'; + WAIT; + END PROCESS; + +END tb;