diff --git a/libraries/dsp/st/src/vhdl/mmp_st_histogram.vhd b/libraries/dsp/st/src/vhdl/mmp_st_histogram.vhd index 2a53b9aec74926c824f48e4a590534cca6fad139..68f9df5f48febfe34b87ffd864ebcbef7b8e85b6 100644 --- a/libraries/dsp/st/src/vhdl/mmp_st_histogram.vhd +++ b/libraries/dsp/st/src/vhdl/mmp_st_histogram.vhd @@ -24,8 +24,7 @@ -- . MMS-wrapper that adds MM clock domain RAM readout and and multi-instance -- support to st_histogram. -- Description: --- . This MMS wrapper contains logic to fill a local RAM with the contents of --- a selected st_histogram instance. + LIBRARY IEEE, common_lib, mm_lib, technology_lib, dp_lib; USE IEEE.std_logic_1164.ALL; @@ -57,6 +56,15 @@ END mmp_st_histogram; ARCHITECTURE str OF mmp_st_histogram IS + ------------------------------------------------------------------------------- + -- st_histogram instances + ------------------------------------------------------------------------------- + SIGNAL st_histogram_ram_copi_arr : t_mem_copi_arr(g_nof_instances-1 DOWNTO 0); + SIGNAL st_histogram_ram_cipo_arr : t_mem_cipo_arr(g_nof_instances-1 DOWNTO 0); + + ------------------------------------------------------------------------------- + -- Dual clock RAM + ------------------------------------------------------------------------------- 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)+1; @@ -70,27 +78,28 @@ ARCHITECTURE str OF mmp_st_histogram IS CONSTANT c_addr_high : NATURAL := g_nof_bins-1; SIGNAL common_ram_cr_cw_wr_copi_arr : t_mem_copi_arr(g_nof_instances-1 DOWNTO 0); - SIGNAL common_ram_cr_cw_rd_copi_arr : t_mem_copi_arr(g_nof_instances-1 DOWNTO 0); SIGNAL common_ram_cr_cw_rd_cipo_arr : t_mem_cipo_arr(g_nof_instances-1 DOWNTO 0); - SIGNAL st_histogram_ram_copi_arr : t_mem_copi_arr(g_nof_instances-1 DOWNTO 0); - SIGNAL st_histogram_ram_cipo_arr : t_mem_cipo_arr(g_nof_instances-1 DOWNTO 0); - - SIGNAL ram_copi_arr : t_mem_copi_arr(g_nof_instances-1 DOWNTO 0); - SIGNAL ram_cipo_arr : t_mem_cipo_arr(g_nof_instances-1 DOWNTO 0); - - SIGNAL ram_fill_arr : STD_LOGIC_VECTOR(g_nof_instances-1 DOWNTO 0); - + ------------------------------------------------------------------------------- + -- Logic to move st_histogram RAM contents into the dual clock RAM + ------------------------------------------------------------------------------- + SIGNAL ram_fill_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_inst_int : NATURAL; - 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); - + + ------------------------------------------------------------------------------- + -- MM multiplexing + ------------------------------------------------------------------------------- + SIGNAL ram_copi_arr : t_mem_copi_arr(g_nof_instances-1 DOWNTO 0); + SIGNAL ram_cipo_arr : t_mem_cipo_arr(g_nof_instances-1 DOWNTO 0); + + BEGIN ------------------------------------------------------------------------------- @@ -151,7 +160,6 @@ BEGIN ------------------------------------------------------------------------------- -- Logic to move st_histogram RAM contents into the dual clock RAM above ------------------------------------------------------------------------------- - -- Use only the status signal of st_histogram instance 0 ram_fill <= snk_in_arr(0).sync; diff --git a/libraries/dsp/st/src/vhdl/st_histogram.vhd b/libraries/dsp/st/src/vhdl/st_histogram.vhd index 298ea89da75d9823ff33725e6394387b5cc2ca75..297aa95ccaa5345645b2af153518e42cc34e85e8 100644 --- a/libraries/dsp/st/src/vhdl/st_histogram.vhd +++ b/libraries/dsp/st/src/vhdl/st_histogram.vhd @@ -24,35 +24,50 @@ -- . Count incoming data values and keep the counts in RAM as a histogram -- Description: -- . See st_histogram.txt for the original design description. --- . The contents of the inactive RAM is cleared automatically just before the --- next sync interval. This way, no data is lost and all valid input data --- contributes to the histogram. The ram_clearing status output is high --- during this automated clearing. --- . All valid data of a DC input contributes to the histogram, no data is --- lost. +-- . The histogram of all input data per sync (g_nof_data_per_sync) is +-- kept as count values in g_nof_bins RAM addresses. g_nof_data_per_sync +-- determines the required width of the data in RAM. +-- . All valid data of the input contributes to the histogram, no data is +-- lost. This applies to any input type including DC. +-- . Internally 2 RAM pages are used and are swapped on a sync. One +-- (inactive) page contains the histogram of the last sync interval +-- while the new data is written to the other (active) page. The contents +-- of the inactive RAM are cleared automatically just before the next sync +-- interval. This way no data is lost and all valid g_nof_data_per_sync +-- samples contribute to the histogram. +-- . tb_st_histogram generates and visualizes an input sine wave and the +-- resulting histogram in the wave window. -- . The block schematic below shows the data flow from snk_in to ram_mosi: --- . snk_in.data is interpreted as address (bin) to read from RAM by bin_reader. +-- . snk_in.data is reduced by combining up to 3 consecutive identical +-- samples into 1 and carrying the count (1..3) in the channel field. +-- . This is to prevent simultaneous read/writes to the RAM from/on +-- the same address. The read,increment,write sequence takes 3 cycles, +-- hence combining up to 3 consecutive samples (=addresses) into 1 +-- rules out this issue. +-- . snk_in_reg.data is interpreted as address (bin) to read from RAM by +-- bin_reader. -- . a RAM pointer 0 or 1 is kept as MS part of the address. --- . snk_in.sync determines the RAM pointer 0 or 1. --- . The data read from that adress, the bin count, is incremented and written --- back by bin_writer. --- . Upon request (ram_miso), the bin counts (the histogram) are output on --- ram_mosi. --- bin_reader_miso --- __________ __________ | ___________ --- | | | | | | | --- ---snk_in--->| reduce |----->|bin_reader|<--+---| | --- |__________| |__________| | | --- | | | --- | | | --- bin_reader_to_writer_mosi | RAM(1..0) |----ram_mosi---> --- | | | --- ____v_____ | | --- | | | | --- |bin_writer|---+-->| | --- |__________| | |___________| --- | --- bin_writer_mosi +-- . snk_in_reg.sync determines the RAM pointer 0 or 1. +-- . The data read from that adress, the bin count, is incremented with +-- the count carried in the channel field (1..3) and written back to +-- the RAM by bin_writer. +-- . Upon request (ram_miso), the bin counts (=the histogram) are output +-- on ram_mosi. +-- bin_reader_miso +-- ______ __________ | _________ +-- | | | | | | | +-- --snk_in-->|reduce|--snk_in_reg-->|bin_reader|<--+--| | +-- |______| |__________| | | +-- | | | +-- | | | +-- bin_reader_to_writer_mosi |RAM(1..0)|--ram_mosi--> +-- | | | +-- ____v_____ | | +-- | | | | +-- |bin_writer|--+-->| | +-- |__________| | |_________| +-- | +-- bin_writer_mosi -- Usage: -- . The ram_mosi input applies to the RAM page that is inactive (not -- being written to from data path) *at that time*. The user should take care to @@ -73,7 +88,10 @@ -- . 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. This --- has been done in mms_st_histogram.vhd. +-- has been done in mmp_st_histogram.vhd. +-- . Possibly common_paged_ram_r_w could be used instead of 2 common_ram_r_w +-- instances. However that modification would not add an MM clk domain for +-- readout. LIBRARY IEEE, common_lib, mm_lib, technology_lib, dp_lib; USE IEEE.std_logic_1164.ALL; @@ -85,8 +103,8 @@ USE technology_lib.technology_select_pkg.ALL; ENTITY st_histogram IS GENERIC ( g_data_w : NATURAL := 8; - g_nof_bins : NATURAL := 256; - g_nof_data_per_sync : NATURAL := 1024; -- must be larger than g_nof_bins + g_nof_bins : NATURAL := 256; -- <= 2^g_data_w + g_nof_data_per_sync : NATURAL := 1024; -- >= g_nof_bins g_data_type : STRING := "unsigned" -- unsigned or signed ); PORT ( @@ -288,6 +306,7 @@ BEGIN END LOOP; END PROCESS; + ------------------------------------------------------------------------------- -- ram_pointer: Keep track of what RAM to target -- . Target either RAM 0 or 1 per sync period diff --git a/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd b/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd index dea080d96f62841b555f72aa7e4597f0d7ad14ba..e5701611d8027c34ad59bf59d424a200227b3415 100644 --- a/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd +++ b/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd @@ -1,6 +1,6 @@ ------------------------------------------------------------------------------- -- --- Copyright 2020 +-- Copyright 2021 -- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> -- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands -- @@ -33,7 +33,9 @@ -- . set Radix to 'decimal' for signed input data. -- Description: -- . Verification be eye (wave window): --- . For the sine input, observe input 'stimuli_data' and output 'histogram' signals. +-- . For the sine input (default), observe input 'stimuli_data' and output +-- 'histogram' signals. Set Radix->Decimal and Format->Analog (automatic) +-- in QuestaSim. -- . For counter data, observe that: -- . There are 4 sync periods in which 3 packets of 1024 words are generated; -- . histogram_snk_in.data = 0..1023, 3 times per sync @@ -43,9 +45,10 @@ -- . bin_writer_mosi writes bin counts 1..12 per sync interval; -- . Both RAMs are used twice: RAM 0, RAM 1, RAM 0, RAM 1; -- . RAM clearing completes just before the end of each sync interval. --- . Automatic verification: --- . In each sync period the RAM contents are read out via ram_mosi/miso and --- compared to the expected bin counts. +-- . Automatic verification - in each sync period: +-- . the RAM contents are read out via ram_mosi/miso and compared to the +-- expected bin counts. +-- . the sum of all bins is checked against the expected g_nof_data_per_sync. ------------------------------------------------------------------------------- LIBRARY IEEE, common_lib, mm_lib, dp_lib; @@ -65,8 +68,8 @@ ENTITY tb_st_histogram IS GENERIC( g_nof_sync : NATURAL := 4; -- We're simulating at least 4 g_nof_sync so both RAMs are written and cleared twice. g_data_w : NATURAL := 3; -- Determines maximum number of bins (2^g_data_w) - g_nof_bins : NATURAL := 8; -- Lower than or equal to 2^g_data_w. Higher is allowed but makes no sense. - g_nof_data_per_sync : NATURAL := 20; -- Determines max required RAM data width. e.g. 11b to store max bin count '1024'. + g_nof_bins : NATURAL := 8; -- Lower than or equal to 2^g_data_w. Higher is allowed but makes no sense. + g_nof_data_per_sync : NATURAL := 20; -- Determines max required RAM data width. e.g. 11b to store max bin count '1024'. g_stimuli_mode : STRING := "sine"; -- "counter", "dc", "sine" or "random" g_data_type : STRING := "signed"; -- use "signed" if g_stimuli_mode="sine" g_lock_sine : BOOLEAN := TRUE -- TRUE to lock the sine wave to Sync - produces sparse histogram with low number of non-zero samples (occuring 2*c_sine_nof_periods) @@ -153,7 +156,6 @@ BEGIN BEGIN nxt_stimuli_src_out <= c_dp_sosi_rst; stimuli_done <= '0'; --- stimuli_src_out <= c_dp_sosi_rst; proc_common_wait_until_low(dp_clk, dp_rst); proc_common_wait_some_cycles(dp_clk, 5); diff --git a/libraries/dsp/st/tb/vhdl/tb_tb_st_histogram.vhd b/libraries/dsp/st/tb/vhdl/tb_tb_st_histogram.vhd index 3e3e103c21aa40006c08ff6095810b8496dfc7a4..b278c2c124e1efb150531eee2e6301bf1ff2e232 100644 --- a/libraries/dsp/st/tb/vhdl/tb_tb_st_histogram.vhd +++ b/libraries/dsp/st/tb/vhdl/tb_tb_st_histogram.vhd @@ -44,7 +44,8 @@ BEGIN -- g_nof_bins : NATURAL := 256; -- g_nof_data : NATURAL := 1024; -- g_stimuli_mode : STRING := "dc"; --- g_data_type : STRING := "unsigned" +-- g_data_type : STRING := "unsigned"; +-- g_lock_sine : BOOLEAN := TRUE -- Counter data u_tb_st_histogram_0 : ENTITY work.tb_st_histogram GENERIC MAP ( 7, 8, 256, 1024, "counter", "unsigned"); -- Incoming data repeats 1024/ 256= 4 times: Bin count = 4 @@ -60,18 +61,25 @@ u_tb_st_histogram_7 : ENTITY work.tb_st_histogram GENERIC MAP ( 5, 12, 512, 400 u_tb_st_histogram_8 : ENTITY work.tb_st_histogram GENERIC MAP ( 4, 13, 1024, 8000, "dc", "unsigned"); u_tb_st_histogram_9 : ENTITY work.tb_st_histogram GENERIC MAP (11, 6, 64, 100, "dc", "unsigned"); --- Sine wave +-- Locked Sine wave u_tb_st_histogram_10: ENTITY work.tb_st_histogram GENERIC MAP ( 4, 3, 8, 20, "sine", "signed"); u_tb_st_histogram_11: ENTITY work.tb_st_histogram GENERIC MAP ( 8, 6, 64, 200, "sine", "signed"); u_tb_st_histogram_12: ENTITY work.tb_st_histogram GENERIC MAP (12, 8, 256, 2000, "sine", "signed"); u_tb_st_histogram_13: ENTITY work.tb_st_histogram GENERIC MAP (17, 10, 256, 3455, "sine", "signed"); u_tb_st_histogram_14: ENTITY work.tb_st_histogram GENERIC MAP (21, 14, 1024, 8111, "sine", "signed"); +-- Drifting Sine wave +u_tb_st_histogram_15: ENTITY work.tb_st_histogram GENERIC MAP ( 4, 3, 8, 20, "sine", "signed", FALSE); +u_tb_st_histogram_16: ENTITY work.tb_st_histogram GENERIC MAP ( 8, 6, 64, 200, "sine", "signed", FALSE); +u_tb_st_histogram_17: ENTITY work.tb_st_histogram GENERIC MAP (12, 8, 256, 2000, "sine", "signed", FALSE); +u_tb_st_histogram_18: ENTITY work.tb_st_histogram GENERIC MAP (17, 10, 256, 3455, "sine", "signed", FALSE); +u_tb_st_histogram_19: ENTITY work.tb_st_histogram GENERIC MAP (21, 14, 1024, 8111, "sine", "signed", FALSE); + -- Random -u_tb_st_histogram_15: ENTITY work.tb_st_histogram GENERIC MAP ( 4, 3, 8, 20, "random", "signed"); -u_tb_st_histogram_16: ENTITY work.tb_st_histogram GENERIC MAP ( 6, 6, 64, 200, "random", "signed"); -u_tb_st_histogram_17: ENTITY work.tb_st_histogram GENERIC MAP ( 9, 8, 256, 2000, "random", "signed"); -u_tb_st_histogram_18: ENTITY work.tb_st_histogram GENERIC MAP (17, 10, 256, 3455, "random", "signed"); -u_tb_st_histogram_19: ENTITY work.tb_st_histogram GENERIC MAP (13, 14, 1024, 8111, "random", "signed"); +u_tb_st_histogram_20: ENTITY work.tb_st_histogram GENERIC MAP ( 4, 3, 8, 20, "random", "signed"); +u_tb_st_histogram_21: ENTITY work.tb_st_histogram GENERIC MAP ( 6, 6, 64, 200, "random", "signed"); +u_tb_st_histogram_22: ENTITY work.tb_st_histogram GENERIC MAP ( 9, 8, 256, 2000, "random", "signed"); +u_tb_st_histogram_23: ENTITY work.tb_st_histogram GENERIC MAP (17, 10, 256, 3455, "random", "signed"); +u_tb_st_histogram_24: ENTITY work.tb_st_histogram GENERIC MAP (13, 14, 1024, 8111, "random", "signed"); END tb;