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

-Replaced st_histogram.vhd contents with cleaned version

parent ba439202
No related branches found
No related tags found
3 merge requests!101Merged sub-branch L2SDP-151 into L2SDP-143 (st_histogram rework),!99Cleaned/rewrote st_histogram.,!98Major rework on st_histogram.
...@@ -97,9 +97,9 @@ BEGIN ...@@ -97,9 +97,9 @@ BEGIN
dp_rst => dp_rst, dp_rst => dp_rst,
dp_clk => dp_clk, dp_clk => dp_clk,
snk_in => snk_in, snk_in => snk_in
sla_in_ram_mosi => ram_st_histogram_mosi, -- sla_in_ram_mosi => ram_st_histogram_mosi,
sla_out_ram_miso => ram_st_histogram_miso -- sla_out_ram_miso => ram_st_histogram_miso
); );
u_st_histogram_reg : ENTITY work.st_histogram_reg u_st_histogram_reg : ENTITY work.st_histogram_reg
......
...@@ -18,68 +18,10 @@ ...@@ -18,68 +18,10 @@
-- --
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- -- Author: Daniel van der Schuur
-- Author: J.W.E. Oudman -- Purpose:
-- Purpose: Create a histogram from the input data and present it to
-- st_histogram_reg
-- Description:
-- The histogram component separates it's input samples in counter bins based
-- on the value of the MSbits of the input. These bins are adresses on a RAM
-- block that is swapped with another RAM block at every sync pulse plus 3
-- cycles. While one RAM block is used to count the input samples, the other
-- is read by the MM bus through st_histogram_reg.
--
--
-- ram_pointer ram_pointer
-- | |
-- | /o--- RAM_0 ---o |
-- |/ |
-- / |
-- snk_in ----o/ | /o----- ram_miso (st_histogram_reg)
-- |/ _mosi
-- /
-- o--- RAM_1 ---o/
--
--
-- The input data is a dp stream which obviously uses a dp_clk. Because the
-- RAM is swapped after every sync both RAM blocks need to use the dp_clk.
-- If the MM bus needs to acces the data in a RAM block it has to acces it
-- through st_histogram_reg as the mm_clk can't be used.
--
-- The design is basically devided in the following blocks of code:
-- . Assign inputs of RAM
-- . Bin reader
-- . Bin Writer
-- . Bin Arbiter
-- . RAM selector & Dual swapped RAM instances
-- . Connect interface to DUAL swapped RAM, read out histogram statistics
--
-- Remarks:
-- . Because the values of the generics g_nof_bins depends on g_in_data_w
-- (you should not have more bins than data values) an assert is made to
-- warn in the simulation when the maximum value of g_nof_bins is reached.
-- If exceeded the simulator will throw fatal error ("...Port length (#) does
-- not match actual length (#)...")
--
-- . when an adress is determined it takes 2 cycles to receive it's value and
-- another cycle before the calculated value can be written into that RAM
-- adress (1st cycle: address; 3rd cycle: data available; 5th cycle: write
-- data). There is also the limitation of not being able to read and write
-- on the same adress at the same time. These limitations cause the following
-- complications in the implementation:
-- . repeating samples of the same adress have to be counted first till
-- another adress appears before written (as you would miss the second and
-- further consecutive samples and have the read/write limitation)
-- . If adresses are toggling at every cycle (e.g. adress 0; 1; 0; 1) you
-- have to remember the data to be written and increment it as you have the
-- read/write limitation (missing samples) and writing takes priority
-- in this case
-- . When a sync signal appears the RAM has to be swapped 4 cycles later so
-- the first 3 cycles may/can not ask a read from the old RAM block (the
-- read_enable takes one cycle hence the difference of 3 against 4 cycles)
--
-------------------------------------------------------------------------------
LIBRARY IEEE, common_lib, mm_lib, technology_lib, dp_lib; LIBRARY IEEE, common_lib, mm_lib, technology_lib, dp_lib;
USE IEEE.std_logic_1164.ALL; USE IEEE.std_logic_1164.ALL;
...@@ -89,580 +31,180 @@ USE dp_lib.dp_stream_pkg.ALL; ...@@ -89,580 +31,180 @@ USE dp_lib.dp_stream_pkg.ALL;
USE technology_lib.technology_select_pkg.ALL; USE technology_lib.technology_select_pkg.ALL;
ENTITY st_histogram IS ENTITY st_histogram 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; --
g_str : STRING := "freq.density"; -- to select output to MM bus ("frequency" or "freq.density")
g_ram_miso_sim_mode : BOOLEAN := FALSE -- when TRUE the ram_miso bus will get a copy of the data written into the RAM.
);
PORT ( PORT (
dp_rst : IN STD_LOGIC; dp_rst : IN STD_LOGIC;
dp_clk : IN STD_LOGIC; dp_clk : IN STD_LOGIC;
-- Streaming snk_in : IN t_dp_sosi
snk_in : IN t_dp_sosi;
-- DP clocked memory bus
sla_in_ram_mosi : IN t_mem_mosi; -- Beware, works in dp clock domain !
sla_out_ram_miso : OUT t_mem_miso; -- '' !
-- ram_mosi : IN t_mem_mosi; -- Beware, works in dp clock domain !
-- ram_miso : OUT t_mem_miso -- '' !
-- Debug bus
dbg_ram_miso : OUT t_mem_miso
); );
END st_histogram; END st_histogram;
ARCHITECTURE rtl OF st_histogram IS ARCHITECTURE rtl OF st_histogram IS
-- CONSTANT c_data_span : NATURAL := pow2(g_in_data_w); -- any use? CONSTANT c_nof_bins : NATURAL := 256;
-- CONSTANT c_bin_w : NATURAL := ceil_log2(g_nof_data); -- any use? CONSTANT c_in_data_w : NATURAL := 8;
CONSTANT c_clear : NATURAL := g_nof_data - g_nof_bins; CONSTANT c_adr_low : NATURAL := c_in_data_w-8; -- 0
CONSTANT c_adr_w : NATURAL := ceil_log2(g_nof_bins);
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
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' );
-- SIGNAL mem_miso_init : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0) := (OTHERS => '0'); -------------------------------------------------------------------------------
-- bin_reader
-------------------------------------------------------------------------------
SIGNAL bin_reader_mosi : t_mem_mosi;
SIGNAL bin_reader_miso : t_mem_miso;
SIGNAL snk_in_p : t_dp_sosi; SIGNAL prv_rd_address : STD_LOGIC_VECTOR(32-1 DOWNTO 0);
SIGNAL snk_in_pp : t_dp_sosi;
SIGNAL snk_in_pppp : t_dp_sosi;
SIGNAL bin_reader_mosi : t_mem_mosi := c_mem_mosi_rst; -------------------------------------------------------------------------------
SIGNAL prev_bin_reader_mosi : t_mem_mosi := c_mem_mosi_rst; -- bin_writer
SIGNAL bin_reader_mosi_pp : t_mem_mosi := c_mem_mosi_rst; -------------------------------------------------------------------------------
SIGNAL bin_reader_mosi_ppp : t_mem_mosi := c_mem_mosi_rst; SIGNAL bin_reader_to_writer_mosi : t_mem_mosi;
SIGNAL nxt_bin_writer_mosi : t_mem_mosi; SIGNAL nxt_bin_writer_mosi : t_mem_mosi;
SIGNAL bin_writer_mosi : t_mem_mosi; SIGNAL bin_writer_mosi : t_mem_mosi;
-------------------------------------------------------------------------------
-- bin_arbiter
-------------------------------------------------------------------------------
SIGNAL write_allowed : BOOLEAN;
SIGNAL nxt_bin_arbiter_wr_mosi : t_mem_mosi; SIGNAL nxt_bin_arbiter_wr_mosi : t_mem_mosi;
SIGNAL 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 bin_arbiter_rd_mosi : t_mem_mosi;
SIGNAL bin_arbiter_rd_miso : t_mem_miso;
SIGNAL bin_arbiter_rd_miso : t_mem_miso := c_mem_miso_rst; -------------------------------------------------------------------------------
SIGNAL bin_reader_rd_miso : t_mem_miso := c_mem_miso_rst; -- 2x RAM (common_ram_r_w) instances
SIGNAL common_ram_r_w_miso : t_mem_miso := c_mem_miso_rst; -------------------------------------------------------------------------------
CONSTANT c_nof_common_ram_r_w : NATURAL := 2;
SIGNAL init_phase : STD_LOGIC := '1';
SIGNAL nxt_init_phase : STD_LOGIC;
SIGNAL rd_cnt_allowed : STD_LOGIC := '0';
SIGNAL rd_cnt_allowed_pp : STD_LOGIC := '0';
SIGNAL toggle_detect : STD_LOGIC := '0';
SIGNAL toggle_detect_pp : STD_LOGIC;
SIGNAL toggle_detect_false : STD_LOGIC := '1';
SIGNAL nxt_toggle_detect_false : STD_LOGIC;
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 same_r_w_address : STD_LOGIC;
SIGNAL same_r_w_address_pp : STD_LOGIC;
--debug signals
SIGNAL dbg_state_string : STRING(1 TO 3) := " ";
SIGNAL dbg_snk_data : STD_LOGIC_VECTOR(g_in_data_w-1 DOWNTO 0);
SIGNAL ram_pointer : STD_LOGIC := '0';
SIGNAL cycle_cnt : NATURAL := 0 ;
SIGNAL nxt_cycle_cnt : NATURAL := 0 ;
-- SIGNAL wr_en : STD_LOGIC := '0';
-- SIGNAL nxt_wr_en : STD_LOGIC;
-- SIGNAL wr_dat : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0);
-- SIGNAL nxt_wr_dat : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0);
-- SIGNAL wr_adr : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low);
-- SIGNAL rd_adr : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low);
-- SIGNAL rd_en : STD_LOGIC := '0';
-- SIGNAL rd_dat : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0);
-- SIGNAL rd_val : STD_LOGIC;
SIGNAL mm_adr_cnt : NATURAL := 0 ;
SIGNAL mm_adr_illegal : STD_LOGIC := '0';
SIGNAL mm_adr_illegal_pp : STD_LOGIC := '0';
SIGNAL ram_0_wr_en : STD_LOGIC;
SIGNAL ram_0_wr_dat : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0);
SIGNAL ram_0_wr_adr : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low);
SIGNAL ram_0_rd_adr : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low);
SIGNAL ram_0_rd_en : STD_LOGIC;
SIGNAL ram_0_rd_dat : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0);
SIGNAL ram_0_rd_val : STD_LOGIC;
SIGNAL ram_1_wr_en : STD_LOGIC;
SIGNAL ram_1_wr_dat : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0);
SIGNAL ram_1_wr_adr : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low);
SIGNAL ram_1_rd_adr : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low);
SIGNAL ram_1_rd_en : STD_LOGIC;
SIGNAL ram_1_rd_dat : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0);
SIGNAL ram_1_rd_val : STD_LOGIC;
SIGNAL ram_out_wr_en : STD_LOGIC;
SIGNAL ram_out_wr_dat : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0);
SIGNAL ram_out_wr_adr : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low);
SIGNAL ram_out_rd_adr : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low);
SIGNAL ram_out_rd_en : STD_LOGIC;
SIGNAL ram_out_rd_dat : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0);
SIGNAL ram_out_rd_val : STD_LOGIC;
SIGNAL prev_ram_out_wr_adr : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low);
SIGNAL ram_out_same_w_r_adr : STD_LOGIC;
BEGIN CONSTANT c_adr_w : NATURAL := ceil_log2(c_nof_bins);
CONSTANT c_ram : t_c_mem := (latency => 1,
adr_w => c_adr_w, -- 8 bits needed to adress/select 256 adresses
dat_w => c_word_w, -- 32b, def. in common_pkg; >= c_bin_w
nof_dat => c_nof_bins, -- 256 adresses with 32b words
init_sl => '0');
----------------------------------------------------------------------------- SIGNAL ram_pointer : STD_LOGIC;
-- Check Generics
-----------------------------------------------------------------------------
ASSERT c_adr_low_calc>0 REPORT "ceil_log2(g_nof_bins) is as large as g_in_data_w, don't increase g_nof_bins" SEVERITY WARNING;
-----------------------------------------------------------------------------
-- Assign inputs of RAM: <-- use parts of description for bin_writer
-- . Determine address based on input data
-- . Compare adress with the two previous adresses and if:
-- . it is the same as the last adress increase a counter
-- . it is the same as 2 cycles back but not the last copy the data to be
-- written directly into a local counter instead of trying to read (ask)
-- it back from RAM at the same clock cycle (which is impossible)
-- . it is not the same enable the nxt_wr_dat data to be written .
-- at the next cycle by making nxt_wr_en high .
-- . Write the wr_dat data to the RAM
-- . At the snk_in.sync pulse:
-- . let first 3 cycles start counting from 0 again
-- . (plus 3 cycles) let counting depend on values in RAM (which should
-- be 0)
-- . Restart or pause counting when a snk_in.valid = '0' appears:
-- . pause when adress is the same as the previous adress
-- . restart from 0 when adress is not the same as previous adress
-- . restart from 0 when also a sync appears
--
--
-- . in : snk_in (latency: 0)
-- : common_ram_r_w_miso (latency: 2)
-- . out : snk_in_pppp.sync (latency: 4)
-- : bin_arbiter_wr_mosi (latency: 4)
-- : bin_arbiter_rd_mosi (latency: 1)
--
----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Bin reader: Convert snk_in data to bin_reader_mosi with read request
-- and generate signals for detection of problems in the
-- consecutive data.
-- . in : snk_in (latency: 0)
-- : bin_arbiter_rd_miso (latency: 2)
-- . out : init_phase (latency: 0 ?
-- : bin_reader_mosi (latency: 0)
-- : prev_bin_reader_mosi (latency: 1)
-- : bin_reader_mosi_pp (latency: 2)
-- : bin_reader_mosi_ppp (latency: 3)
-- : bin_reader_rd_miso (latency: 2)
-- : rd_cnt_allowed_pp (latency: 2)
-- : same_r_w_address_pp (latency: 2)
-- : toggle_detect_pp (latency: 2)
-- : sync_detect (latency: 0)
-- : sync_detect_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);
bin_reader_rd_miso <= bin_arbiter_rd_miso;
--snk_in pipeline; Enable sync and valid comparisons
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 => snk_in_p
);
-- init_phase <= '0' WHEN snk_in_p.sync = '1'; -- ELSE will be impossible since the init_phase may only be triggered once on the first sync SIGNAL common_ram_r_w_wr_mosi_arr : t_mem_mosi_arr(1 DOWNTO 0);
nxt_init_phase <= '0' WHEN snk_in.sync='1' ELSE init_phase; SIGNAL common_ram_r_w_rd_mosi_arr : t_mem_mosi_arr(1 DOWNTO 0);
SIGNAL common_ram_r_w_rd_miso_arr : t_mem_miso_arr(1 DOWNTO 0);
p_init_phase : PROCESS(dp_clk, dp_rst) SIGNAL histogram_wr_mosi : t_mem_mosi;
SIGNAL histogram_rd_mosi : t_mem_mosi;
SIGNAL histogram_rd_miso : t_mem_miso;
BEGIN
-------------------------------------------------------------------------------
-- bin_reader : reads bin from RAM, sends bin + count to bin_writer.
-- . Input : snk_in (input data stream)
-- bin_reader_miso (reply to RAM read request: rddata = bin count)
-- . Output : bin_reader_mosi (RAM read request, address = bin)
-- bin_reader_to_writer_mosi (address = bin, wrdata = bin count)
-------------------------------------------------------------------------------
-- Fetch the bin from RAM
bin_reader_mosi.wrdata <= (OTHERS=>'0');
bin_reader_mosi.wr <= '0';
bin_reader_mosi.rd <= snk_in.valid;
bin_reader_mosi.address <= RESIZE_UVEC(snk_in.data(c_in_data_w-1 DOWNTO c_adr_low), 32);
-- Store the rd address as bin_writer needs to know where to write the bin count
p_prv_rd_address : PROCESS(dp_clk, dp_rst) IS
BEGIN BEGIN
IF dp_rst = '1' THEN IF dp_rst = '1' THEN
init_phase <= '1'; prv_rd_address <= (OTHERS=>'0');
toggle_detect_false <= '1';
ELSIF RISING_EDGE(dp_clk) THEN ELSIF RISING_EDGE(dp_clk) THEN
init_phase <= nxt_init_phase; prv_rd_address <= bin_reader_mosi.address;
toggle_detect_false <= nxt_toggle_detect_false;
END IF; END IF;
END PROCESS; END PROCESS;
-- Enable sync comparisons -- Forward the read bin + count to bin writer
u_dp_pipeline_snk_in_2_cycle : ENTITY dp_lib.dp_pipeline bin_reader_to_writer_mosi.wr <= bin_reader_miso.rdval;
GENERIC MAP ( bin_reader_to_writer_mosi.wrdata <= RESIZE_UVEC(bin_reader_miso.rddata(8-1 DOWNTO 0), 72);
g_pipeline => 2 -- 0 for wires, > 0 for registers, bin_reader_to_writer_mosi.address <= prv_rd_address;
)
PORT MAP (
rst => dp_rst,
clk => dp_clk,
snk_in => snk_in,
src_out => snk_in_pp
);
-- Enable switching the ram_pointer
u_dp_pipeline_snk_in_4_cycle : ENTITY dp_lib.dp_pipeline
GENERIC MAP (
g_pipeline => 4 -- 0 for wires, > 0 for registers,
)
PORT MAP (
rst => dp_rst,
clk => dp_clk,
snk_in => snk_in,
src_out => snk_in_pppp
);
dbg_snk_data <= snk_in_pp.data(g_in_data_w-1 DOWNTO 0);
-- toggle_detect_false <= '0' WHEN snk_in_pp.sync = '1'; -- ELSE will be impossible since the toggle_detect_false may only be triggered once on the first sync
nxt_toggle_detect_false <= '0' WHEN snk_in_p.sync='1' ELSE toggle_detect_false;
sync_detect <= snk_in.valid WHEN (snk_in.sync='1' OR snk_in_p.sync='1' OR snk_in_pp.sync='1') ELSE '0'; -- @sync, first 3 cycles would try to read from the wrong (old) RAM block, detect this problem
-- Line up to p_nxt_bin_writer_mosi process
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
);
-- Enable adress comparisons 1 cycle back
-- Skip unvalid data with trigger bin_reader_mosi.rd to make comparisons between unvalid-data-seperated data possible.
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)
);
-- Enable adress comparisons 2 cycles back
u_common_pipeline_bin_reader_mosi_2_cycle : ENTITY common_lib.common_pipeline
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)
);
-- Enable adress comparisons 3 cycles back
u_common_pipeline_bin_reader_mosi_3_cycle : ENTITY common_lib.common_pipeline
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)
);
-- Only count sequential valid data on the same address when: address is the same as last and 1 or 2 cycles after the sync when in sync_detect; address is the same as last and past the initialisation and outside sync_detect
rd_cnt_allowed <= snk_in.valid WHEN ( bin_reader_mosi.address = prev_bin_reader_mosi.address AND ( snk_in_p.sync='1' OR (snk_in_pp.sync='1' AND snk_in_p.valid='1') ) )
OR (bin_reader_mosi.address = prev_bin_reader_mosi.address AND init_phase='0' AND sync_detect='0')
ELSE '0';
-- Line rd_cnt_allowed up to p_nxt_bin_writer_mosi process
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
);
-- Detect a (valid) repeating address seperated by one other address past the initialisation and outside the first two cycles of a (new) sync --also @sync, one wil be true; use NOT(1 or 1) instead of (0 or 0)
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' AND NOT(snk_in.sync='1' OR snk_in_p.sync='1') )
ELSE '0';
-- Line up to p_nxt_bin_writer_mosi process
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
);
-- Detect an (valid) address that has to be read as well as written at the same time
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';
-- Line up top p_nxt_bin_writer_mosi process
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 -- bin_writer : Increment the bin, forward write request to bin_arbiter
-- . in : toggle_detect_pp (latency: 2) -- . Input : bin_reader_to_writer_mosi (from bin_reader = bin + bin count)
-- . in : same_r_w_address_pp (latency: 2) -- . Output : bin_writer_mosi (to bin_arbiter = bin + incremented bin count)
-- . in : bin_reader_mosi_pp (latency: 2) -------------------------------------------------------------------------------
-- . in : bin_reader_rd_miso (latency: 2) aka bin_arbiter_rd_miso or common_ram_r_w_miso nxt_bin_writer_mosi.rd <= '0';
-- . in : rd_cnt_allowed_pp (latency: 2) nxt_bin_writer_mosi.wr <= bin_reader_to_writer_mosi.wr;
-- . in : sync_detect_pp nxt_bin_writer_mosi.address <= bin_reader_to_writer_mosi.address;
-- . out : bin_writer_mosi (latency: 3) nxt_bin_writer_mosi.wrdata <= INCR_UVEC(bin_reader_to_writer_mosi.wrdata, 1);
-----------------------------------------------------------------------------
p_nxt_bin_writer_mosi : PROCESS(bin_reader_rd_miso,
bin_reader_mosi_pp.address, toggle_detect_pp, rd_cnt_allowed_pp, prev_wrdata, prev_prev_wrdata, prev_prev_prev_wrdata, sync_detect_pp, same_r_w_address_pp) IS
BEGIN
nxt_bin_writer_mosi <= c_mem_mosi_rst;
dbg_state_string <= "unv";
IF bin_reader_rd_miso.rdval='1' THEN
nxt_bin_writer_mosi.wr <= '1';
nxt_bin_writer_mosi.wrdata <= INCR_UVEC(bin_reader_rd_miso.rddata, 1);
nxt_bin_writer_mosi.address <= bin_reader_mosi_pp.address;
nxt_prev_wrdata <= TO_UINT(bin_reader_rd_miso.rddata) + 1;
dbg_state_string <= "val";
ELSIF toggle_detect_pp = '1' THEN
nxt_bin_writer_mosi.wr <= '1';
nxt_bin_writer_mosi.wrdata <= TO_UVEC( (prev_prev_wrdata+1), c_mem_data_w);
nxt_bin_writer_mosi.address <= bin_reader_mosi_pp.address;
nxt_prev_wrdata <= prev_prev_wrdata+1;
dbg_state_string <= "td ";
ELSIF rd_cnt_allowed_pp = '1' THEN
nxt_bin_writer_mosi.wr <= '1';
nxt_bin_writer_mosi.wrdata <= TO_UVEC( (prev_wrdata + 1), c_mem_data_w);
nxt_prev_wrdata <= prev_wrdata + 1;
dbg_state_string <= "r# ";
nxt_bin_writer_mosi.address <= bin_reader_mosi_pp.address;
ELSIF sync_detect_pp = '1' THEN
nxt_bin_writer_mosi.wr <= '1';
nxt_bin_writer_mosi.wrdata <= TO_UVEC(1, c_mem_data_w); -- snk_in.sync: 1; snk_in_p.sync (thus new adress): 1; snk_in_pp.sync (thus new adress): 1
nxt_bin_writer_mosi.address <= bin_reader_mosi_pp.address;
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_prev_wrdata : PROCESS(dp_clk, dp_rst, nxt_bin_writer_mosi.wr) IS --seperated from p_bin_writer_mosi since the implementation was unwanted
BEGIN
IF dp_rst = '1' THEN
prev_wrdata <= 0;
prev_prev_wrdata <= 0;
prev_prev_prev_wrdata <= 0;
ELSIF nxt_bin_writer_mosi.wr='1' AND RISING_EDGE(dp_clk) THEN
prev_wrdata <= nxt_prev_wrdata;
prev_prev_wrdata <= prev_wrdata;
prev_prev_prev_wrdata <= prev_prev_wrdata;
END IF;
END PROCESS;
p_bin_writer_mosi : PROCESS(dp_clk, dp_rst) IS --, nxt_bin_writer_mosi, nxt_prev_wrdata, prev_wrdata, prev_prev_wrdata -- Register the outputs to bin_arbiter (above we have a combinational adder = propagation delay)
p_bin_writer_mosi : PROCESS(dp_clk, dp_rst) IS
BEGIN BEGIN
IF dp_rst = '1' THEN IF dp_rst = '1' THEN
bin_writer_mosi <= c_mem_mosi_rst; bin_writer_mosi <= c_mem_mosi_rst;
-- prev_wrdata <= 0;
-- prev_prev_wrdata <= 0;
-- prev_prev_prev_wrdata <= 0;
ELSIF RISING_EDGE(dp_clk) THEN ELSIF RISING_EDGE(dp_clk) THEN
bin_writer_mosi <= nxt_bin_writer_mosi; bin_writer_mosi <= nxt_bin_writer_mosi;
-- IF nxt_bin_writer_mosi.wr = '1' THEN
-- prev_wrdata <= nxt_prev_wrdata;
-- prev_prev_wrdata<= prev_wrdata;
-- prev_prev_prev_wrdata <= prev_prev_wrdata;
-- END IF;
END IF; END IF;
END PROCESS; END PROCESS;
----------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- Bin Arbiter: Determine next RAM access -- bin_arbiter : Take care of simultaneous rd/wr to the same RAM address
-- . in : bin_reader_mosi (latency: 0) -- . Input: bin_reader_mosi (wants to read bins)
-- : init_phase (latency: 0) -- bin_writer_mosi (wants to write to bins)
-- : prev_bin_reader_mosi (latency: 1) -- bin_arbiter_rd_miso (carries the bins requested by bin_reader)
-- : bin_reader_mosi_pp (latency: 2) -- . Output: bin_arbiter_wr_mosi (wr requests to RAM)
-- : bin_reader_mosi_ppp (latency: 3) -- bin_arbiter_rd_mosi (rd requests to RAM)
-- : bin_writer_mosi (latency: 3) -- bin_reader_miso (carries the bins requested by bin_reader)
-- : sync_detect (latency: 0? or 3? -------------------------------------------------------------------------------
-- : common_ram_r_w_miso (latency: 2) -- Really simple arbitration: always allow reads, only allow writes when possible (rd_addr != wr_addr).
-- . out : bin_arbiter_rd_mosi (latency: 1) write_allowed <= TRUE WHEN bin_writer_mosi.address/=bin_reader_mosi.address ELSE FALSE;
-- . : bin_arbiter_rd_miso (latency: 2)
-- . : bin_arbiter_wr_mosi (latency: 4)
-----------------------------------------------------------------------------
nxt_bin_arbiter_wr_mosi <= bin_writer_mosi;
-- Read RAM when subsequent addresses are not the same, when there is no toggle detected and only when the same address is not going to be written to. When a sync is detected don't read in the old RAM block.
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';
nxt_bin_arbiter_rd_mosi.address <= bin_reader_mosi.address;
p_bin_arbiter_mosi : PROCESS(dp_clk, dp_rst) IS --, nxt_bin_arbiter_wr_mosi, nxt_bin_arbiter_rd_mosi
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;
-- -- Temporary debug data bin_arbiter_rd_mosi.wr <= '0';
-- sla_out_ram_miso.rddata <= bin_arbiter_wr_mosi.wrdata; bin_arbiter_rd_mosi.rd <= bin_reader_mosi.rd; -- Reading is always allowed
bin_arbiter_rd_mosi.address <= bin_reader_mosi.address;
-- Make RAM data available for the bin_reader (or bin_writer) nxt_bin_arbiter_wr_mosi.rd <= '0';
bin_arbiter_rd_miso <= common_ram_r_w_miso; nxt_bin_arbiter_wr_mosi.wr <= bin_writer_mosi.wr WHEN write_allowed ELSE '0';
nxt_bin_arbiter_wr_mosi.wrdata <= bin_writer_mosi.wrdata WHEN write_allowed ELSE (OTHERS=>'0');
nxt_bin_arbiter_wr_mosi.address <= bin_writer_mosi.address WHEN write_allowed ELSE bin_reader_mosi.address;
-- Forward the rd_miso to the bin_reader
bin_reader_miso <= bin_arbiter_rd_miso;
----------------------------------------------------------------------------- -- Register the outputs to RAM
-- RAM selector & Dual swapped RAM instances: p_bin_arbiter_mosi : PROCESS(dp_clk, dp_rst) IS
-- 4 cycles after a sync the RAM block is swapped for an empty one to allow
-- the block to be read out till the next sync+3 cycles
-- The input is the st side, the output is the dp clocked mm side.
--
-- Depending on ram_pointer:
-- ram_pointer = '0': input RAM_0, output RAM_1
-- ram_pointer = '1': input RAM_1, output RAM_0
--
-- input in: snk_in_pppp.sync (latency: 4)
-- bin_arbiter_wr_mosi (latency: 4)
-- bin_arbiter_rd_mosi (latency: 1)
-- out: common_ram_r_w_miso (latency: 2)
--
-- output in: ram_out_wr_en; ram_out_wr_dat; ram_out_wr_adr; ram_out_rd_adr;
-- ram_out_rd_en
-- out: ram_out_rd_dat; ram_out_rd_val
-----------------------------------------------------------------------------
p_ram_pointer_at_sync : PROCESS(snk_in_pppp) IS -- needs nxt_ram_pointer ??
BEGIN BEGIN
IF snk_in_pppp.sync = '1' THEN --needs snk_in_pppp <-- IF dp_rst = '1' THEN
ram_pointer <= NOT(ram_pointer); bin_arbiter_wr_mosi <= c_mem_mosi_rst;
ELSIF RISING_EDGE(dp_clk) THEN
bin_arbiter_wr_mosi <= nxt_bin_arbiter_wr_mosi;
END IF; END IF;
END PROCESS; END PROCESS;
p_ram_pointer : PROCESS(ram_pointer, bin_arbiter_wr_mosi, bin_arbiter_rd_mosi, ram_0_rd_dat, ram_0_rd_val,
ram_out_wr_en, ram_out_wr_dat, ram_out_wr_adr, ram_out_rd_adr, ram_out_rd_en, ram_1_rd_dat, ram_1_rd_val) IS
BEGIN
IF ram_pointer='0' THEN
-- ST side (RAM 0)
ram_0_wr_en <= bin_arbiter_wr_mosi.wr; -- bin_arbiter_wr_mosi.wr wr_en
ram_0_wr_dat <= bin_arbiter_wr_mosi.wrdata(c_word_w-1 DOWNTO 0); -- bin_arbiter_wr_mosi.wrdata wr_dat
ram_0_wr_adr <= bin_arbiter_wr_mosi.address(c_adr_w-1 DOWNTO 0); -- bin_arbiter_wr_mosi.address wr_adr
ram_0_rd_adr <= bin_arbiter_rd_mosi.address(c_adr_w-1 DOWNTO 0); -- bin_arbiter_rd_mosi.address rd_adr
ram_0_rd_en <= bin_arbiter_rd_mosi.rd; -- bin_arbiter_rd_mosi.rd rd_en
common_ram_r_w_miso.rddata(c_word_w-1 DOWNTO 0) <= ram_0_rd_dat; -- common_ram_r_w_miso.rddata rd_dat
common_ram_r_w_miso.rdval <= ram_0_rd_val; -- common_ram_r_w_miso.rdval rd_val
-- dp_clk'd MM side (RAM 1)
ram_1_wr_en <= ram_out_wr_en;
ram_1_wr_dat <= ram_out_wr_dat;
ram_1_wr_adr <= ram_out_wr_adr;
ram_1_rd_adr <= ram_out_rd_adr;
ram_1_rd_en <= ram_out_rd_en;
ram_out_rd_dat <= ram_1_rd_dat;
ram_out_rd_val <= ram_1_rd_val;
ELSE -- ram_pointer='1'
-- ST side (RAM 1)
ram_1_wr_en <= bin_arbiter_wr_mosi.wr;
ram_1_wr_dat <= bin_arbiter_wr_mosi.wrdata(c_word_w-1 DOWNTO 0);
ram_1_wr_adr <= bin_arbiter_wr_mosi.address(c_adr_w-1 DOWNTO 0);
ram_1_rd_adr <= bin_arbiter_rd_mosi.address(c_adr_w-1 DOWNTO 0);
ram_1_rd_en <= bin_arbiter_rd_mosi.rd;
common_ram_r_w_miso.rddata(c_word_w-1 DOWNTO 0) <= ram_1_rd_dat;
common_ram_r_w_miso.rdval <= ram_1_rd_val;
--dp_clk'd MM side (RAM 0)
ram_0_wr_en <= ram_out_wr_en;
ram_0_wr_dat <= ram_out_wr_dat;
ram_0_wr_adr <= ram_out_wr_adr;
ram_0_rd_adr <= ram_out_rd_adr;
ram_0_rd_en <= ram_out_rd_en;
ram_out_rd_dat <= ram_0_rd_dat;
ram_out_rd_val <= ram_0_rd_val;
END IF; -------------------------------------------------------------------------------
END PROCESS; -- Two RAM (common_ram_r_w) instances. The user can read the histogram from the
-- instance that is not being written to by the bin_arbiter.
-- . Input: bin_arbiter_wr_mosi (writes bins)
-- bin_arbiter_rd_mosi (requests to read bins to increment bin count)
-- histogram_rd_mosi (requests to read the bins on the user side)
-- histogram_wr_mosi (on user side, auto clears RAM every sync)
-- . Output: histogram_rd_miso (carries the bins the user wants to read)
-- bin_arbiter_miso (carries then bins the bin_reader wants to read)
-------------------------------------------------------------------------------
ram_pointer <= '0'; --FIXME This needs to be somehow tied to snk_in.sync.
-- Let bin_arbiter write RAM 0 while user reads RAM 1 and vice versa
common_ram_r_w_wr_mosi_arr(0) <= bin_arbiter_wr_mosi WHEN ram_pointer='0' ELSE histogram_wr_mosi;
common_ram_r_w_rd_mosi_arr(0) <= bin_arbiter_rd_mosi WHEN ram_pointer='0' ELSE histogram_rd_mosi;
common_ram_r_w_wr_mosi_arr(1) <= bin_arbiter_wr_mosi WHEN ram_pointer='1' ELSE histogram_wr_mosi;
common_ram_r_w_rd_mosi_arr(1) <= bin_arbiter_rd_mosi WHEN ram_pointer='1' ELSE histogram_rd_mosi;
-- Dual swapped RAM instances -- Let bin_arbiter read RAM 0 while user reads RAM 1 and vice versa
ram_0: ENTITY common_lib.common_ram_r_w bin_arbiter_rd_miso <= common_ram_r_w_rd_miso_arr(0) WHEN ram_pointer='0' ELSE common_ram_r_w_rd_miso_arr(1);
GENERIC MAP ( histogram_rd_miso <= common_ram_r_w_rd_miso_arr(1) WHEN ram_pointer='0' ELSE common_ram_r_w_rd_miso_arr(0);
g_technology => c_tech_select_default,
g_ram => c_ram,
g_init_file => "UNUSED"
)
PORT MAP (
rst => dp_rst,
clk => dp_clk,
clken => '1', -- only necessary for Stratix iv
wr_en => ram_0_wr_en,
wr_adr => ram_0_wr_adr,
wr_dat => ram_0_wr_dat,
rd_en => ram_0_rd_en,
rd_adr => ram_0_rd_adr,
rd_dat => ram_0_rd_dat,
rd_val => ram_0_rd_val
);
ram_1: ENTITY common_lib.common_ram_r_w gen_common_ram_r_w : FOR i IN 0 TO c_nof_common_ram_r_w-1 GENERATE
u_common_ram_r_w : ENTITY common_lib.common_ram_r_w
GENERIC MAP ( GENERIC MAP (
g_technology => c_tech_select_default, g_technology => c_tech_select_default,
g_ram => c_ram, g_ram => c_ram,
...@@ -671,123 +213,27 @@ BEGIN ...@@ -671,123 +213,27 @@ BEGIN
PORT MAP ( PORT MAP (
rst => dp_rst, rst => dp_rst,
clk => dp_clk, clk => dp_clk,
clken => '1', -- only necessary for Stratix iv clken => '1',
wr_en => ram_1_wr_en, wr_en => common_ram_r_w_wr_mosi_arr(i).wr,
wr_adr => ram_1_wr_adr, wr_adr => common_ram_r_w_wr_mosi_arr(i).address(8-1 DOWNTO 0),
wr_dat => ram_1_wr_dat, wr_dat => common_ram_r_w_wr_mosi_arr(i).wrdata(32-1 DOWNTO 0),
rd_en => ram_1_rd_en, rd_en => common_ram_r_w_rd_mosi_arr(i).rd,
rd_adr => ram_1_rd_adr, rd_adr => common_ram_r_w_rd_mosi_arr(i).address(8-1 DOWNTO 0),
rd_dat => ram_1_rd_dat, rd_dat => common_ram_r_w_rd_miso_arr(i).rddata(32-1 DOWNTO 0),
rd_val => ram_1_rd_val rd_val => common_ram_r_w_rd_miso_arr(i).rdval
); );
END GENERATE;
histogram_wr_mosi <= c_mem_mosi_rst; --FIXME add code to clear all RAM addresses here ?
----------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- Connect interface to DUAL swapped RAM, read out histogram statistics: -- Cross clock domains
-- . Limit the data read by the MM master to the RAM block where it started -- . Input: histogram_rd_miso (from RAM block)
-- to read (the values read after a new sync will be OTHERS => '0') -- mm_histogram_rd_mosi (from user)
-- . In the last g_nof_bins cycles all addresses will sequentially be cleared -- . Output: mm_histogram_rd_miso (towards user)
-- -- histogram_rd_mosi (towards RAM block)
-- RAM selector: -------------------------------------------------------------------------------
-- input: ram_out_rd_dat; ram_out_rd_val -- FIXME We should do this in the MMS wrapper.
-- output: ram_out_wr_en; ram_out_wr_dat; ram_out_wr_adr; ram_out_rd_adr;
-- ram_out_wr_en
-- (PORT):
-- input: snk_in; sla_in_ram_mosi
-- output: sla_out_ram_miso
-----------------------------------------------------------------------------
-- Pipeline for identified illegal read requests after new sync
u_common_pipeline_sl_mm_adr_illegal : ENTITY common_lib.common_pipeline_sl
GENERIC MAP(
g_pipeline => 2 -- 0 for wires, > 0 for registers,
)
PORT MAP (
clk => dp_clk,
in_dat => mm_adr_illegal,
out_dat => mm_adr_illegal_pp
);
p_mm_adr_illegal : PROCESS(snk_in.sync, mm_adr_cnt) IS
BEGIN
IF snk_in.sync = '1' AND mm_adr_cnt /= 0 THEN
mm_adr_illegal <= '1';
ELSIF mm_adr_cnt = g_nof_bins-1 THEN
mm_adr_illegal <= '0';
ELSE
END IF;
END PROCESS;
mm_adr_cnt <= TO_UINT(sla_in_ram_mosi.address(c_ram.adr_w-1 DOWNTO 0)) WHEN sla_in_ram_mosi.rd = '1';
ram_out_same_w_r_adr <= '1' WHEN ram_out_wr_adr = sla_in_ram_mosi.address(c_ram.adr_w-1 DOWNTO 0) ELSE '0';
p_ram_to_fifo : PROCESS(snk_in_pp.sync, cycle_cnt, sla_in_ram_mosi.address, sla_in_ram_mosi.rd, ram_out_rd_dat, ram_out_rd_val, prev_ram_out_wr_adr, mm_adr_illegal_pp, ram_out_same_w_r_adr, bin_arbiter_wr_mosi.wrdata) IS
BEGIN
IF g_ram_miso_sim_mode = FALSE THEN
IF snk_in_pppp.sync = '1' THEN
ram_out_wr_en <= '0';
nxt_cycle_cnt <= 0;
ELSIF cycle_cnt = c_clear THEN
ram_out_wr_adr <= (OTHERS => '0');
ram_out_wr_dat <= (OTHERS => '0');
ram_out_wr_en <= '1';
IF ram_out_same_w_r_adr = '1' THEN
ram_out_rd_en <= '0';
sla_out_ram_miso.rddata(c_ram.dat_w-1 DOWNTO 0) <= (OTHERS => '0');
sla_out_ram_miso.rdval <= ram_out_rd_val;
ELSE
ram_out_rd_adr <= sla_in_ram_mosi.address(c_ram.adr_w-1 DOWNTO 0);
ram_out_rd_en <= sla_in_ram_mosi.rd;
sla_out_ram_miso.rddata(c_ram.dat_w-1 DOWNTO 0) <= ram_out_rd_dat;
sla_out_ram_miso.rdval <= ram_out_rd_val;
END IF;
nxt_cycle_cnt <= cycle_cnt +1;
ELSIF cycle_cnt > c_clear THEN
ram_out_wr_adr <= INCR_UVEC(prev_ram_out_wr_adr, 1);
ram_out_wr_dat <= (OTHERS => '0');
nxt_cycle_cnt <= cycle_cnt +1;
IF ram_out_same_w_r_adr = '1' OR snk_in.sync = '1' THEN
sla_out_ram_miso.rddata(c_ram.dat_w-1 DOWNTO 0) <= (OTHERS => '0');
sla_out_ram_miso.rdval <= ram_out_rd_val;
ELSE
ram_out_rd_adr <= sla_in_ram_mosi.address(c_ram.adr_w-1 DOWNTO 0);
ram_out_rd_en <= sla_in_ram_mosi.rd;
sla_out_ram_miso.rddata(c_ram.dat_w-1 DOWNTO 0) <= ram_out_rd_dat;
sla_out_ram_miso.rdval <= ram_out_rd_val;
END IF;
ram_out_wr_en <= '1';
ELSIF mm_adr_illegal_pp = '1' THEN
ram_out_rd_adr <= sla_in_ram_mosi.address(c_ram.adr_w-1 DOWNTO 0);
ram_out_rd_en <= sla_in_ram_mosi.rd;
sla_out_ram_miso.rddata(c_ram.dat_w-1 DOWNTO 0) <= (OTHERS => '0');
sla_out_ram_miso.rdval <= ram_out_rd_val;
nxt_cycle_cnt <= cycle_cnt +1;
ram_out_wr_en <= '0';
ELSE
ram_out_rd_adr <= sla_in_ram_mosi.address(c_ram.adr_w-1 DOWNTO 0);
ram_out_rd_en <= sla_in_ram_mosi.rd;
sla_out_ram_miso.rddata(c_ram.dat_w-1 DOWNTO 0) <= ram_out_rd_dat;
sla_out_ram_miso.rdval <= ram_out_rd_val;
nxt_cycle_cnt <= cycle_cnt +1;
ram_out_wr_en <= '0';
END IF;
dbg_ram_miso.rddata <= bin_arbiter_wr_mosi.wrdata;
ELSE
sla_out_ram_miso.rddata <= bin_arbiter_wr_mosi.wrdata;
END IF;
END PROCESS;
p_clk : PROCESS(dp_clk, dp_rst)
BEGIN
IF dp_rst='1' THEN
cycle_cnt <= 0;
ELSIF rising_edge(dp_clk) THEN
cycle_cnt <= nxt_cycle_cnt;
prev_ram_out_wr_adr <= ram_out_wr_adr;
END IF;
END PROCESS;
END rtl; END rtl;
...@@ -63,8 +63,8 @@ ENTITY tb_st_histogram IS ...@@ -63,8 +63,8 @@ ENTITY tb_st_histogram IS
GENERIC( GENERIC(
g_sync_length : NATURAL := 200; g_sync_length : NATURAL := 200;
g_nof_sync : NATURAL := 3; g_nof_sync : NATURAL := 3;
g_data_w : NATURAL := 4; --4 ; 1 g_data_w : NATURAL := 8; --4 ; 1
g_nof_bins : NATURAL := 8; --8 ; 2 g_nof_bins : NATURAL := 256; --8 ; 2
g_nof_data : NATURAL := 200; g_nof_data : NATURAL := 200;
--g_str : STRING := "freq.density"; --g_str : STRING := "freq.density";
g_valid_gap : STRING := "custom"; -- "false" or "true" or "custom" --BOOLEAN := TRUE g_valid_gap : STRING := "custom"; -- "false" or "true" or "custom" --BOOLEAN := TRUE
...@@ -397,12 +397,12 @@ BEGIN ...@@ -397,12 +397,12 @@ BEGIN
dp_clk => dp_clk, dp_clk => dp_clk,
-- Streaming -- Streaming
snk_in => st_histogram_snk_in, snk_in => st_histogram_snk_in
-- Memory Mapped -- Memory Mapped
sla_in_ram_mosi => c_mem_mosi_rst,-- sla_in_ -- sla_in_ram_mosi => c_mem_mosi_rst,-- sla_in_
sla_out_ram_miso => st_histogram_ram_miso, --OPEN -- sla_out_ -- sla_out_ram_miso => st_histogram_ram_miso, --OPEN -- sla_out_
dbg_ram_miso => st_histogram_dbg_ram_miso -- dbg_ram_miso => st_histogram_dbg_ram_miso
); );
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment