diff --git a/libraries/dsp/st/src/vhdl/st_histogram.vhd b/libraries/dsp/st/src/vhdl/st_histogram.vhd index 0076348213e60bd7b7c36df9bb11a49d8e7faf3b..66faa640ec7d779f38bc90bf731445231493ba1c 100644 --- a/libraries/dsp/st/src/vhdl/st_histogram.vhd +++ b/libraries/dsp/st/src/vhdl/st_histogram.vhd @@ -80,7 +80,7 @@ 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) g_nof_bins : NATURAL := 512; -- is a power of 2 and g_nof_bins <= c_data_span; max. 512 - g_nof_data : NATURAL; -- any use? + g_nof_data : NATURAL; -- g_str : STRING := "freq.density" -- to select output to MM bus ("frequency" or "freq.density") ); PORT ( @@ -103,6 +103,7 @@ ARCHITECTURE str OF st_histogram IS CONSTANT c_data_span : NATURAL := pow2(g_in_data_w); -- any use? CONSTANT c_bin_w : NATURAL := ceil_log2(g_nof_data); -- any use? + CONSTANT c_clear : NATURAL := g_nof_data - g_nof_bins; 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 @@ -127,6 +128,8 @@ ARCHITECTURE str OF st_histogram IS SIGNAL ram_pointer : STD_LOGIC := '0'; + SIGNAL cycle_cnt : NATURAL := 0 ; + SIGNAL nxt_cycle_cnt : NATURAL := 0 ; SIGNAL wr_en_a : STD_LOGIC := '0'; SIGNAL nxt_wr_en_a : STD_LOGIC; SIGNAL wr_dat_a : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0); @@ -137,11 +140,7 @@ ARCHITECTURE str OF st_histogram IS SIGNAL rd_dat_b : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0); SIGNAL rd_val_b : STD_LOGIC; - SIGNAL ram_0_rst_a : STD_LOGIC; - SIGNAL ram_0_rst_b : STD_LOGIC; - SIGNAL ram_0_clk_a : STD_LOGIC; - SIGNAL ram_0_clk_b : STD_LOGIC; - + SIGNAL ram_0_wr_en_a : STD_LOGIC; SIGNAL ram_0_wr_en_b : STD_LOGIC := '0'; -- pointer=1, temp'0' SIGNAL ram_0_wr_dat_a : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0); @@ -152,6 +151,30 @@ ARCHITECTURE str OF st_histogram IS SIGNAL ram_0_rd_dat_b : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0); SIGNAL ram_0_rd_val_b : STD_LOGIC; + SIGNAL ram_1_wr_en_a : STD_LOGIC; + SIGNAL ram_1_wr_dat_a : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0); + SIGNAL ram_1_adr_a : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low); + SIGNAL ram_1_adr_b : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low); + SIGNAL ram_1_rd_en_b : STD_LOGIC; + SIGNAL ram_1_rd_dat_b : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0); + SIGNAL ram_1_rd_val_b : 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 fifo_in_wr_en : STD_LOGIC := '0'; + SIGNAL fifo_in_wr_dat : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0) := (OTHERS => '0'); + SIGNAL fifo_in_wr_adr : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low) := (OTHERS => '0'); + SIGNAL fifo_in_rd_adr : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low) := (OTHERS => '0'); + SIGNAL fifo_in_rd_en : STD_LOGIC := '0'; + SIGNAL fifo_in_rd_dat : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0); + SIGNAL fifo_in_rd_val : STD_LOGIC; + BEGIN ----------------------------------------------------------------------------- @@ -184,10 +207,12 @@ BEGIN p_bin_cnt_switch : PROCESS(snk_in) IS BEGIN adr_b <= (OTHERS =>'0'); - IF g_nof_bins>1 THEN -- IF snk_in.valid='1' AND + IF g_nof_bins>1 THEN adr_b <= snk_in.data(g_in_data_w-1 DOWNTO c_adr_low);-- WHEN snk_in.valid='1' ELSE (OTHERS =>'0'); -- AND dp_rst='0'; END IF; END PROCESS; +-- Alternative method: +-- adr_b <= snk_in.data(g_in_data_w-1 DOWNTO c_adr_low) WHEN g_nof_bins >1 ELSE (OTHERS =>'0'); p_rd_en_b : PROCESS(dp_pipeline_src_out_p.sync, snk_in.valid, wr_en_a, adr_a, adr_b, prev_adr_b) IS BEGIN @@ -200,6 +225,10 @@ BEGIN rd_en_b <= '1'; END IF; END PROCESS; + +-- Alternative method: +-- rd_en_b <= '0' WHEN (dp_pipeline_src_out_p.sync = '1' AND wr_en_a = '1') +-- OR (adr_a = adr_b AND adr_a /= prev_adr_b) ELSE '1'; p_nxt_wr_dat : PROCESS(rd_dat_b, adr_b_cnt, rd_val_b, dp_pipeline_src_out_p.sync, dp_pipeline_src_out_pp.sync, wr_en_a) IS BEGIN @@ -217,6 +246,12 @@ BEGIN END IF; END PROCESS; +-- Alternative method: +-- nxt_wr_dat_a <= TO_UVEC(adr_b_cnt, c_word_w) WHEN dfgdfg OR +-- +-- +-- ELSE INCR_UVEC(rd_dat_b, adr_b_cnt) WHEN rd_val_b = '1' ELSE (others => 0) + p_nxt_wr_en : PROCESS(prev_adr_b, adr_b, snk_in.sync) IS BEGIN nxt_wr_en_a <= '0'; @@ -273,6 +308,7 @@ BEGIN wr_dat_a <= nxt_wr_dat_a; wr_en_a <= nxt_wr_en_a; same_r_w_adr <= nxt_same_r_w_adr; + cycle_cnt <= nxt_cycle_cnt; END IF; END PROCESS; @@ -280,8 +316,15 @@ BEGIN ----------------------------------------------------------------------------- -- RAM selector ----------------------------------------------------------------------------- + p_ram_pointer_at_sync : PROCESS(dp_pipeline_src_out_pp) IS + BEGIN + IF dp_pipeline_src_out_pp.sync = '1' THEN + ram_pointer <= NOT(ram_pointer); + END IF; + END PROCESS; - p_ram_pointer : PROCESS(ram_pointer, dp_rst, dp_clk, wr_en_a, wr_dat_a, adr_a, adr_b, rd_en_b, ram_0_rd_dat_b, ram_0_rd_val_b) IS + p_ram_pointer : PROCESS(ram_pointer, wr_en_a, wr_dat_a, adr_a, adr_b, rd_en_b, ram_0_rd_dat_b, ram_0_rd_val_b, + ram_out_wr_en, ram_out_wr_dat, ram_out_wr_adr, ram_out_rd_adr, ram_out_rd_en, ram_1_rd_dat_b, ram_1_rd_val_b) IS BEGIN -- Default / init values -- ram_miso <= c_mem_miso_rst; @@ -290,11 +333,6 @@ BEGIN IF ram_pointer='0' THEN -- ST side (RAM 0) --- ram_0_rst_a <= dp_rst; --- ram_0_rst_b <= dp_rst; --- ram_0_clk_a <= dp_clk; --- ram_0_clk_b <= dp_clk; - ram_0_wr_en_a <= wr_en_a; ram_0_wr_dat_a <= wr_dat_a; ram_0_adr_a <= adr_a; @@ -304,31 +342,35 @@ BEGIN rd_val_b <= ram_0_rd_val_b; --- -- MM side (RAM 1) --- ram_1_rst_a <= dp_rst; --- ram_1_clk_a <=common_pipeline dp_clk; --- ram_1_wr_en_a <= clear_en_a; --- ram_1_wr_dat_a <= clear_dat_a; --- ram_1_adr_a <= clear_adr_a; --- ---2 --- ram_1_rst_b <= mm_rst; --- ram_1_clk_b <= mm_clk; --- ram_1_wr_en_b <= ram_mosi.wr; -- only for diagnostic purposes, typically statistics are read only --- ram_1_wr_dat_b <= ram_mosi.wrdata(c_ram.dat_w-1 DOWNTO 0); --- ram_1_adr_b <= ram_mosi.address(c_ram.adr_w-1 DOWNTO 0); --- ram_1_rd_en_b <= ram_mosi.rd; --- ram_miso.rddata <= ram_1_rd_dat_b(c_ram.dat_w-1 DOWNTO 0); -- needs 'histogram/frequency' switch --- ram_miso.rdval <= ram_1_rd_val_b; + -- MM side (RAM 1) + ram_1_wr_en_a <= ram_out_wr_en; + ram_1_wr_dat_a <= ram_out_wr_dat; + ram_1_adr_a <= ram_out_wr_adr; + ram_1_adr_b <= ram_out_rd_adr; + ram_1_rd_en_b <= ram_out_rd_en; + ram_out_rd_dat <= ram_1_rd_dat_b; + ram_out_rd_val <= ram_1_rd_val_b; + ELSE -- ram_pointer='1' --- ram_1_wr_en_a <= wr_en_a; --- ram_1_wr_dat_a <= wr_dat_a; --- ram_1_adr_a <= adr_a; --- ram_1_adr_b <= adr_b; --- ram_1_rd_en_b <= rd_en_b; --- rd_dat_b <= ram_1_rd_dat_b; --- rd_val_b <= ram_1_rd_val_b; + + -- ST side (RAM 1) + ram_1_wr_en_a <= wr_en_a; + ram_1_wr_dat_a <= wr_dat_a; + ram_1_adr_a <= adr_a; + ram_1_adr_b <= adr_b; + ram_1_rd_en_b <= rd_en_b; + rd_dat_b <= ram_1_rd_dat_b; + rd_val_b <= ram_1_rd_val_b; + + -- MM side (RAM 0) + ram_0_wr_en_a <= ram_out_wr_en; + ram_0_wr_dat_a <= ram_out_wr_dat; + ram_0_adr_a <= ram_out_wr_adr; + ram_0_adr_b <= ram_out_rd_adr; + ram_0_rd_en_b <= ram_out_rd_en; + ram_out_rd_dat <= ram_0_rd_dat_b; + ram_out_rd_val <= ram_0_rd_val_b; -- -- -- ram_miso <= ram_0_miso; @@ -459,61 +501,24 @@ BEGIN rd_val => ram_0_rd_val_b ); --- ram_0: ENTITY common_lib.common_ram_crw_crw --- GENERIC MAP ( --- g_technology => c_tech_select_default, --- g_ram => c_ram, --- g_init_file => "UNUSED", --- g_true_dual_port => FALSE --- ) --- PORT MAP ( --- rst_a => ram_0_rst_a, --- rst_b => ram_0_rst_b, --- clk_a => ram_0_clk_a, --- clk_b => ram_0_clk_b, --- clken_a => '1', -- only necessary for Stratix iv --- clken_b => '1', --- wr_en_a => ram_0_wr_en_a, --- wr_en_b => ram_0_wr_en_b, -- pointer=1, temp'0' --- wr_dat_a => ram_0_wr_dat_a, --- wr_dat_b => ram_0_wr_dat_b, -- pointer=1, temp'0' --- adr_a => ram_0_adr_a, --- adr_b => ram_0_adr_b, --- rd_en_a => '0', --- rd_en_b => ram_0_rd_en_b, --- rd_dat_a => OPEN, --- rd_dat_b => ram_0_rd_dat_b, --- rd_val_a => OPEN, --- rd_val_b => ram_0_rd_val_b --- ); --- --- ram_1: ENTITY common_lib.common_ram_crw_crw --- GENERIC MAP ( --- g_technology => c_tech_select_default, --- g_ram => c_ram, --- g_init_file => "UNUSED", --- g_true_dual_port => TRUE --- ) --- PORT MAP ( --- rst_a => ram_1_rst_a, --- rst_b => ram_1_rst_b, --- clk_a => ram_1_clk_a, --- clk_b => ram_1_clk_b, --- clken_a => '1', --- clken_b => '1', --- wr_en_a => ram_1_wr_en_a, --- wr_en_b => ram_1_wr_en_b, --- wr_dat_a => ram_1_wr_dat_a, --- wr_dat_b => ram_1_wr_dat_b, --- adr_a => ram_1_adr_a, --- adr_b => ram_1_adr_b, --- rd_en_a => '0', --- rd_en_b => ram_1_rd_en_b, --- rd_dat_a => OPEN, --- rd_dat_b => ram_1_rd_dat_b, --- rd_val_a => OPEN, --- rd_val_b => ram_1_rd_val_b --- ); + ram_1: 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', -- only necessary for Stratix iv + wr_en => ram_1_wr_en_a, + wr_adr => ram_1_adr_a, + wr_dat => ram_1_wr_dat_a, + rd_en => ram_1_rd_en_b, + rd_adr => ram_1_adr_b, + rd_dat => ram_1_rd_dat_b, + rd_val => ram_1_rd_val_b + ); @@ -522,7 +527,31 @@ BEGIN -- Connect MM interface to DUAL swapped RAM read out histogram statistics ----------------------------------------------------------------------------- - + p_ram_to_fifo : PROCESS(dp_pipeline_src_out_pp.sync, cycle_cnt) IS + BEGIN + IF dp_pipeline_src_out_pp.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'; + ram_out_rd_en <= '0'; + nxt_cycle_cnt <= nxt_cycle_cnt +1; + ELSIF cycle_cnt > c_clear THEN + ram_out_wr_adr <= INCR_UVEC(ram_out_wr_adr, 1); + nxt_cycle_cnt <= nxt_cycle_cnt +1; + ELSE + ram_out_wr_en <= fifo_in_wr_en; + ram_out_wr_dat <= fifo_in_wr_dat; + ram_out_wr_adr <= fifo_in_wr_adr; + ram_out_rd_adr <= fifo_in_rd_adr; + ram_out_rd_en <= fifo_in_rd_en; + fifo_in_rd_dat <= ram_out_rd_dat; + fifo_in_rd_val <= ram_out_rd_val; + nxt_cycle_cnt <= nxt_cycle_cnt +1; + END IF; + END PROCESS; diff --git a/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd b/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd index 2e699fcd0f21d9d9ad78389e421580946163c349..1c94340e8f40d9bca2559644177aa4973e13c838 100644 --- a/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd +++ b/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd @@ -12,8 +12,8 @@ ENTITY tb_st_histogram IS g_nof_bins : NATURAL := 8; g_nof_data : NATURAL := 200; g_str : STRING := "freq.density"; - g_valid_gap : BOOLEAN := TRUE; - g_snk_in_data_sim_type : STRING := "toggle" -- "counter" or "toggle" + g_valid_gap : BOOLEAN := FALSE; + g_snk_in_data_sim_type : STRING := "counter" -- "counter" or "toggle" ); END tb_st_histogram;