diff --git a/libraries/dsp/st/src/vhdl/st_histogram.vhd b/libraries/dsp/st/src/vhdl/st_histogram.vhd index 587298463e5e4ce69851ef6834609ac21b769f0b..56fe01aa18d5d1a42d08a5d17271a9d79bde5c04 100644 --- a/libraries/dsp/st/src/vhdl/st_histogram.vhd +++ b/libraries/dsp/st/src/vhdl/st_histogram.vhd @@ -44,13 +44,16 @@ ARCHITECTURE str OF st_histogram IS SIGNAL dp_pipeline_src_out_p : t_dp_sosi; SIGNAL dp_pipeline_src_out_pp : t_dp_sosi; --- SIGNAL dp_sync_plus_two : STD_LOGIC; SIGNAL adr_b_cnt : NATURAL := 1; SIGNAL nxt_adr_b_cnt : NATURAL; - SIGNAL adr_b_cnt_dly : NATURAL := 1; SIGNAL prev_adr_b : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low); --- SIGNAL not_same_adr_dly : NATURAL := 0; -- any use? + + -- Toggle implementation signals + SIGNAL prev_same_r_w_adr : STD_LOGIC := '0'; + SIGNAL same_r_w_adr : STD_LOGIC := '0'; + SIGNAL nxt_same_r_w_adr : STD_LOGIC := '0'; + SIGNAL ram_pointer : STD_LOGIC := '0'; SIGNAL wr_en_a : STD_LOGIC := '0'; @@ -83,7 +86,7 @@ BEGIN ----------------------------------------------------------------------------- -- Check Generics ----------------------------------------------------------------------------- - ASSERT c_adr_low_calc>0 REPORT "ceil_log2(g_nof_bins) is larger than g_in_data_w" SEVERITY ERROR; + 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 dual page RAM: @@ -99,11 +102,13 @@ BEGIN END IF; END PROCESS; - p_rd_en_b : PROCESS(dp_pipeline_src_out_p.sync, snk_in.valid, wr_en_a) IS + 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 - rd_en_b <= '1'; --snk_in.valid - IF dp_pipeline_src_out_p.sync = '1' AND wr_en_a = '1' THEN -- only at sync?? not at every wr_en_a? + rd_en_b <= '1'; + IF dp_pipeline_src_out_p.sync = '1' AND wr_en_a = '1' THEN -- rd_en_b <= '0'; + ELSIF adr_a = adr_b AND adr_a /= prev_adr_b THEN -- toggle implementation + rd_en_b <= '0'; -- toggle implementation ELSIF snk_in.valid = '0' AND wr_en_a = '1' THEN rd_en_b <= '1'; END IF; @@ -117,21 +122,25 @@ BEGIN nxt_wr_dat_a <= (OTHERS => '0'); IF dp_pipeline_src_out_p.sync = '1' THEN nxt_wr_dat_a <= TO_UVEC(adr_b_cnt, c_word_w); + ELSIF dp_pipeline_src_out_pp.sync = '1' THEN + nxt_wr_dat_a <= TO_UVEC(adr_b_cnt, c_word_w); + ELSIF same_r_w_adr = '1' AND rd_val_b = '0' THEN -- toggle implementation: same adress forced rd_val to 0, counter instead of ram knows what to write + nxt_wr_dat_a <= TO_UVEC(adr_b_cnt, c_word_w); -- toggle implementation + ELSIF dp_pipeline_src_out_pp.valid = '0' AND prev_same_r_w_adr = '1' THEN -- toggle implementation: prevent 2* rd_dat_b + nxt_wr_dat_a <= TO_UVEC(adr_b_cnt, c_word_w); -- toggle implementation ELSIF rd_val_b = '1' THEN nxt_wr_dat_a <= INCR_UVEC(rd_dat_b, adr_b_cnt); - ELSIF dp_pipeline_src_out_pp.sync = '1' THEN --AND wr_en_a = '0' -- wr_en_a = '1' changed to '0' - nxt_wr_dat_a <= TO_UVEC(adr_b_cnt, c_word_w); END IF; END PROCESS; p_nxt_wr_en : PROCESS(prev_adr_b, adr_b, snk_in.sync) IS BEGIN nxt_wr_en_a <= '0'; - IF adr_b /= prev_adr_b THEN -- AND snk_in.valid = '1' !!!? + IF adr_b /= prev_adr_b THEN nxt_wr_en_a <= '1'; ELSIF snk_in.sync = '1' AND g_nof_bins = 1 THEN nxt_wr_en_a <= '1'; - ELSIF snk_in.sync = '1' THEN --AND adr_b /= adr_a -- niet enkel sync ?? + ELSIF snk_in.sync = '1' THEN nxt_wr_en_a <= '1'; END IF; END PROCESS; @@ -139,18 +148,37 @@ BEGIN -- nxt_wr_dat_a <= INCR_UVEC(rd_dat_b, adr_b_cnt) WHEN rd_val_b='1' ELSE (OTHERS =>'0'); -- adr_b_cnt_dly ?? -- nxt_wr_en_a <= rd_val_b WHEN adr_b /= prev_adr_b ELSE '0'; - p_prev_adr_cnt : PROCESS(adr_b, prev_adr_b, adr_b_cnt, snk_in.sync, snk_in.valid) IS + p_prev_adr_cnt : PROCESS(adr_a, adr_b, prev_adr_b, adr_b_cnt, snk_in.sync, snk_in.valid, dp_pipeline_src_out_p.valid, dp_pipeline_src_out_p.sync) IS BEGIN nxt_adr_b_cnt <= 1; - IF adr_b = prev_adr_b AND snk_in.valid = '1' AND snk_in.sync = '0' THEN --AND rd_val_b='1' really necessary?? probably not. + IF adr_b = prev_adr_b AND snk_in.valid = '1' AND snk_in.sync = '0' THEN nxt_adr_b_cnt <= adr_b_cnt + 1 ; - ELSIF adr_b = prev_adr_b AND snk_in.valid = '0' AND snk_in.sync = '1' THEN + ELSIF snk_in.valid = '0' AND snk_in.sync = '1' THEN --address doesn't matter at unvalid and sync, removed: adr_b = prev_adr_b AND nxt_adr_b_cnt <= 0; ELSIF adr_b = prev_adr_b AND snk_in.valid = '0' THEN nxt_adr_b_cnt <= adr_b_cnt; + ELSIF adr_b = prev_adr_b AND snk_in.valid = '1' AND dp_pipeline_src_out_p.valid = '0' AND snk_in.sync = '1' THEN -- toggle implementation; do the adresses even matter? + nxt_adr_b_cnt <= 1; -- toggle implementation + ELSIF adr_b = prev_adr_b AND snk_in.valid = '1' AND dp_pipeline_src_out_p.valid = '0' THEN -- toggle implementation + nxt_adr_b_cnt <= adr_b_cnt + 1; -- toggle implementation + ELSIF adr_a = adr_b AND snk_in.valid = '1' AND snk_in.sync = '1' THEN -- toggle implementation; do the adresses even matter? + nxt_adr_b_cnt <= 1; -- toggle implementation + ELSIF adr_a = adr_b AND adr_b /= prev_adr_b AND snk_in.valid = '0' THEN -- toggle implementation: disable count; -2 cycles count + 0 + nxt_adr_b_cnt <= TO_UINT(wr_dat_a); -- toggle implementation + ELSIF adr_a = adr_b AND snk_in.valid = '1' AND dp_pipeline_src_out_p.sync = '0' THEN -- toggle implentation + nxt_adr_b_cnt <= TO_UINT(wr_dat_a) + 1; -- toggle implentation + ELSIF adr_a = adr_b AND snk_in.valid = '0' THEN -- toggle implentation + nxt_adr_b_cnt <= adr_b_cnt; -- toggle implentation ELSIF snk_in.valid = '0' AND adr_b /= prev_adr_b AND adr_a /= adr_b THEN nxt_adr_b_cnt <= 0; - + END IF; + END PROCESS; + + p_nxt_same_r_w_adr : PROCESS(adr_a, adr_b) IS -- toggle implentation + BEGIN + nxt_same_r_w_adr <= '0'; + IF adr_a = adr_b AND g_nof_bins > 1 THEN + nxt_same_r_w_adr <= '1'; END IF; END PROCESS; @@ -163,6 +191,7 @@ BEGIN adr_b_cnt <= nxt_adr_b_cnt; wr_dat_a <= nxt_wr_dat_a; wr_en_a <= nxt_wr_en_a; + same_r_w_adr <= nxt_same_r_w_adr; END IF; END PROCESS; @@ -235,7 +264,7 @@ BEGIN -- Pipeline for adress ---------------------------------------------------------------------------- - u_common_pipeline_adr : ENTITY common_lib.common_pipeline -- pipeline output + u_common_pipeline_adr : ENTITY common_lib.common_pipeline GENERIC MAP ( g_representation => "UNSIGNED", --orig. signed g_pipeline => 2, @@ -249,6 +278,16 @@ BEGIN out_dat => adr_a ); + u_common_pipeline_sl_same_r_w_adr : ENTITY common_lib.common_pipeline_sl + GENERIC MAP( + g_pipeline => 1 -- 0 for wires, > 0 for registers, + ) + PORT MAP ( + clk => dp_clk, + in_dat => same_r_w_adr, + out_dat => prev_same_r_w_adr + ); + @@ -258,7 +297,7 @@ BEGIN -- Pipeline for adresscounter ---------------------------------------------------------------------------- - u_common_pipeline_adr_cnt : ENTITY common_lib.common_pipeline -- pipeline output + u_common_pipeline_adr_cnt : ENTITY common_lib.common_pipeline GENERIC MAP ( g_representation => "UNSIGNED", --orig. signed g_pipeline => 1, @@ -281,30 +320,6 @@ BEGIN -- Pipeline for cycle after sync ---------------------------------------------------------------------------- --- u_common_pipeline_dp_sync_plus_two : ENTITY common_lib.common_pipeline -- pipeline output --- GENERIC MAP ( --- g_representation => "UNSIGNED", --orig. signed --- g_pipeline => 2, --- g_in_dat_w => 1, --- g_out_dat_w => 1 --- ) --- PORT MAP ( --- clk => dp_clk, --- clken => '1', --- in_dat => STD_LOGIC_VECTOR(snk_in.sync), --- out_dat => dp_sync_plus_two --- ); - --- u_common_pipeline_sl_dp_sync_plus_two : ENTITY common_lib.common_pipeline_sl --- GENERIC MAP( --- g_pipeline => 2 -- 0 for wires, > 0 for registers, --- ) --- PORT MAP ( --- clk => dp_clk, --- in_dat => snk_in.sync, --- out_dat => dp_sync_plus_two --- ); - u_dp_pipeline_snk_in_1_cycle : ENTITY dp_lib.dp_pipeline GENERIC MAP ( g_pipeline => 1 -- 0 for wires, > 0 for registers, @@ -332,28 +347,6 @@ BEGIN - ----------------------------------------------------------------------------- - -- Pipeline for adresscounter delay - ---------------------------------------------------------------------------- - --- u_common_pipeline_adr_cnt_dly : ENTITY common_lib.common_pipeline_natural -- pipeline output --- GENERIC MAP ( --- g_pipeline => 1, --- g_reset_value => 0, --- g_dat_w => 3 --has to enough bits to count to 200.000.000 ; so minimal 28 --- ) --- PORT MAP ( --- clk => dp_clk, --- clken => '1', --- in_dat => NATURAL(nxt_adr_b_cnt), --- out_dat => adr_b_cnt_dly --- ); - - - - - - ----------------------------------------------------------------------------- -- Dual page RAM instace ---------------------------------------------------------------------------- diff --git a/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd b/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd index 1a42426e8527538b229b397b946031bfcefa9949..fa6f771dbc8a93c06dc470545b0db841f937aba7 100644 --- a/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd +++ b/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd @@ -13,7 +13,7 @@ ENTITY tb_st_histogram IS g_nof_data : NATURAL := 200; g_str : STRING := "histogram"; g_valid_gap : BOOLEAN := TRUE; - g_snk_in_data_sim_type : STRING := "counter" -- "counter" of "toggle" + g_snk_in_data_sim_type : STRING := "toggle" -- "counter" of "toggle" ); END tb_st_histogram; @@ -199,14 +199,16 @@ BEGIN 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 <= '1'; + --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.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;