diff --git a/libraries/dsp/st/src/vhdl/st_histogram.vhd b/libraries/dsp/st/src/vhdl/st_histogram.vhd index fef19cae53fb847cdfbd821ef52c3e7c30a92ec8..587298463e5e4ce69851ef6834609ac21b769f0b 100644 --- a/libraries/dsp/st/src/vhdl/st_histogram.vhd +++ b/libraries/dsp/st/src/vhdl/st_histogram.vhd @@ -42,13 +42,14 @@ ARCHITECTURE str OF st_histogram IS nof_dat => g_nof_bins, -- 512 adresses with 32 bit words, so 512 init_sl => '0'); -- MM side : sla_in, sla_out - SIGNAL dp_pipeline_src_out : 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 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? SIGNAL ram_pointer : STD_LOGIC := '0'; @@ -93,30 +94,32 @@ BEGIN p_bin_cnt_switch : PROCESS(snk_in) IS BEGIN adr_b <= (OTHERS =>'0'); - IF snk_in.valid='1' AND g_nof_bins>1 THEN + IF g_nof_bins>1 THEN -- IF snk_in.valid='1' AND 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; - p_rd_en_b : PROCESS(dp_pipeline_src_out.sync, wr_en_a) IS + p_rd_en_b : PROCESS(dp_pipeline_src_out_p.sync, snk_in.valid, wr_en_a) IS BEGIN - rd_en_b <= snk_in.valid; - IF dp_pipeline_src_out.sync = '1' AND wr_en_a = '1' THEN -- only at sync?? not at every wr_en_a? + 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 <= '0'; + ELSIF snk_in.valid = '0' AND wr_en_a = '1' THEN + rd_en_b <= '1'; END IF; END PROCESS; -- rd_en_b <= snk_in.valid; -- WHEN snk_in.valid='1'; -- AND dp_rst='0'; -- adr_a <= adr_b; -- wr_dat_a <= INCR_UVEC(rd_dat_b, adr_b_cnt_dly) WHEN rising_edge(dp_clk) AND rd_val_b='1' ELSE (OTHERS =>'1'); -- wr_en_a <= '1' WHEN rising_edge(dp_clk) AND rd_val_b='1' ELSE '0'; - p_nxt_wr_dat : PROCESS(rd_dat_b, adr_b_cnt, rd_val_b, dp_pipeline_src_out.sync, dp_sync_plus_two, wr_en_a) IS + 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 nxt_wr_dat_a <= (OTHERS => '0'); - IF dp_pipeline_src_out.sync = '1' THEN + IF dp_pipeline_src_out_p.sync = '1' THEN nxt_wr_dat_a <= TO_UVEC(adr_b_cnt, c_word_w); ELSIF rd_val_b = '1' THEN nxt_wr_dat_a <= INCR_UVEC(rd_dat_b, adr_b_cnt); - ELSIF dp_sync_plus_two = '1' THEN --AND wr_en_a = '0' -- wr_en_a = '1' changed to '0' + 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; @@ -124,11 +127,11 @@ BEGIN 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 + IF adr_b /= prev_adr_b THEN -- AND snk_in.valid = '1' !!!? 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' AND adr_b /= adr_a THEN + ELSIF snk_in.sync = '1' THEN --AND adr_b /= adr_a -- niet enkel sync ?? nxt_wr_en_a <= '1'; END IF; END PROCESS; @@ -136,13 +139,18 @@ 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) IS + p_prev_adr_cnt : PROCESS(adr_b, prev_adr_b, adr_b_cnt, snk_in.sync, snk_in.valid) IS BEGIN nxt_adr_b_cnt <= 1; - IF adr_b = prev_adr_b 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 --AND rd_val_b='1' really necessary?? probably not. nxt_adr_b_cnt <= adr_b_cnt + 1 ; --- ELSIF snk_in.sync = '1' THEN --- nxt_adr_b_cnt <= 1; + ELSIF adr_b = prev_adr_b AND snk_in.valid = '0' AND snk_in.sync = '1' THEN + 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 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; @@ -287,25 +295,36 @@ BEGIN -- 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, +-- 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, ) PORT MAP ( - clk => dp_clk, - in_dat => snk_in.sync, - out_dat => dp_sync_plus_two + rst => dp_rst, + clk => dp_clk, + snk_in => snk_in, + src_out => dp_pipeline_src_out_p ); - u_dp_pipeline_snk_in : ENTITY dp_lib.dp_pipeline + u_dp_pipeline_snk_in_2_cycle : ENTITY dp_lib.dp_pipeline GENERIC MAP ( - g_pipeline => 1 -- 0 for wires, > 0 for registers, + g_pipeline => 2 -- 0 for wires, > 0 for registers, ) PORT MAP ( rst => dp_rst, clk => dp_clk, snk_in => snk_in, - src_out => dp_pipeline_src_out + src_out => dp_pipeline_src_out_pp ); diff --git a/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd b/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd index c140045ea62fa98e1970b0495cb6a7a9dc246f1b..1a42426e8527538b229b397b946031bfcefa9949 100644 --- a/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd +++ b/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd @@ -6,12 +6,14 @@ USE dp_lib.dp_stream_pkg.ALL; ENTITY tb_st_histogram IS GENERIC( - g_sync_length : NATURAL := 200; - g_nof_sync : NATURAL := 3; - g_data_w : NATURAL := 4; - g_nof_bins : NATURAL := 4; - g_nof_data : NATURAL := 200; - g_str : STRING := "histogram" + g_sync_length : NATURAL := 200; + g_nof_sync : NATURAL := 3; + g_data_w : NATURAL := 4; + g_nof_bins : NATURAL := 8; + 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" ); END tb_st_histogram; @@ -64,31 +66,155 @@ BEGIN -- Source: counter stimuli ---------------------------------------------------------------------------- - st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= (OTHERS=>'0') WHEN dp_rst='1' ELSE INCR_UVEC(st_histogram_snk_in.data(g_data_w-1 DOWNTO 0), 1) WHEN rising_edge(dp_clk) AND st_histogram_snk_in.valid='1'; +-- st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= (OTHERS=>'0') WHEN dp_rst='1' ELSE INCR_UVEC(st_histogram_snk_in.data(g_data_w-1 DOWNTO 0), 1) WHEN rising_edge(dp_clk) AND st_histogram_snk_in.valid='1'; + + + p_data : PROCESS(dp_rst, dp_clk, st_histogram_snk_in) + BEGIN + IF g_snk_in_data_sim_type = "counter" THEN + IF dp_rst='1' THEN + st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= (OTHERS=>'0'); + ELSIF rising_edge(dp_clk) AND st_histogram_snk_in.valid='1' THEN + st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= INCR_UVEC(st_histogram_snk_in.data(g_data_w-1 DOWNTO 0), 1); + END IF; + ELSIF g_snk_in_data_sim_type = "toggle" THEN + IF dp_rst='1' THEN + st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= (OTHERS=>'0'); + ELSIF rising_edge(dp_clk) AND st_histogram_snk_in.valid='1' THEN + IF st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) = TO_UVEC(0, g_data_w) THEN + st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= TO_UVEC(1, g_data_w); + ELSE + st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= TO_UVEC(0, g_data_w); + END IF; + END IF; + END IF; + END PROCESS; p_stimuli : PROCESS BEGIN --- dp_rst <= '1'; - st_histogram_snk_in.sync <= '0'; - st_histogram_snk_in.valid <= '0'; - WAIT UNTIL rising_edge(dp_clk); --- FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP; --- dp_rst <= '0'; - FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP; - st_histogram_snk_in.valid <= '1'; - - - FOR I IN 0 TO g_nof_sync-1 LOOP - st_histogram_snk_in.sync <= '1'; + IF g_valid_gap = FALSE THEN +-- dp_rst <= '1'; + st_histogram_snk_in.sync <= '0'; + st_histogram_snk_in.valid <= '0'; WAIT UNTIL rising_edge(dp_clk); +-- FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP; +-- dp_rst <= '0'; + FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP; + st_histogram_snk_in.valid <= '1'; + + + FOR I IN 0 TO g_nof_sync-1 LOOP + st_histogram_snk_in.sync <= '1'; + WAIT UNTIL rising_edge(dp_clk); + st_histogram_snk_in.sync <= '0'; + FOR I IN 0 TO g_sync_length-1 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP; + + END LOOP; + FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP; + tb_end <= '1'; + WAIT; + + ELSIF g_valid_gap = TRUE THEN + + + --------------------------------------------- + -- temp copy procedure: proc_dp_gen_block_data + --------------------------------------------- +-- sync_nr <= 0; +-- block_nr <= 0; +-- +-- cnt_sync <= '0'; +-- cnt_val <= '0'; +-- cnt_dat <= (cnt_dat'RANGE=>'1'); -- -1, so first valid cnt_dat starts at 0 +-- +-- -- allow some clock cycles before start after rst release +-- WAIT UNTIL rst='0'; +-- FOR I IN 0 TO c_start_delay-1 LOOP WAIT UNTIL rising_edge(clk); END LOOP; +-- +-- -- output first sync +-- cnt_sync <= '1'; +-- WAIT UNTIL rising_edge(clk); +-- cnt_sync <= '0'; +-- FOR I IN 1 TO c_gap_size-1 LOOP WAIT UNTIL rising_edge(clk); END LOOP; +-- +-- WHILE TRUE LOOP +-- -- output block +-- IF c_throttle_num >= c_throttle_den THEN +-- -- no need to throttle, so cnt_val active during whole data block +-- FOR I IN 0 TO c_block_size-1 LOOP +-- cnt_val <= '1'; +-- cnt_dat <= INCR_UVEC(cnt_dat, 1); +-- WAIT UNTIL rising_edge(clk); +-- END LOOP; +-- ELSE +-- -- throttle cnt_val, so c_throttle_num active cnt_val cycles per c_throttle_den cycles +-- FOR I IN 0 TO c_block_size/c_throttle_num-1 LOOP +-- FOR J IN 0 TO c_throttle_num-1 LOOP +-- cnt_val <= '1'; +-- cnt_dat <= INCR_UVEC(cnt_dat, 1); +-- WAIT UNTIL rising_edge(clk); +-- END LOOP; +-- FOR J IN 0 TO c_throttle_den-c_throttle_num-1 LOOP +-- cnt_val <= '0'; +-- WAIT UNTIL rising_edge(clk); +-- END LOOP; +-- END LOOP; +-- END IF; +-- cnt_val <= '0'; +-- -- output sync for next block at first sample of gap +-- IF block_nr>0 AND ((block_nr + 1) MOD c_nof_block_per_sync)=0 THEN +-- cnt_sync <= '1'; +-- sync_nr <= sync_nr+1; +-- END IF; +-- WAIT UNTIL rising_edge(clk); +-- -- output rest of the gap +-- cnt_sync <= '0'; +-- FOR I IN 1 TO c_gap_size-1 LOOP WAIT UNTIL rising_edge(clk); END LOOP; +-- -- next block +-- block_nr <= block_nr+1; +-- END LOOP; + --------------------------------------------- + -- end temp copy procedure: proc_dp_gen_block_data + --------------------------------------------- + + + + + +-- dp_rst <= '1'; st_histogram_snk_in.sync <= '0'; - FOR I IN 0 TO g_sync_length-1 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP; + st_histogram_snk_in.valid <= '0'; + WAIT UNTIL rising_edge(dp_clk); +-- FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP; +-- dp_rst <= '0'; + FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP; + st_histogram_snk_in.valid <= '1'; + - END LOOP; - FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP; - tb_end <= '1'; - WAIT; + FOR I IN 0 TO g_nof_sync-2 LOOP + st_histogram_snk_in.sync <= '1'; + WAIT UNTIL rising_edge(dp_clk); + st_histogram_snk_in.sync <= '0'; + 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); + 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.sync <= '1'; + WAIT UNTIL rising_edge(dp_clk); + --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; + + END LOOP; + FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP; + tb_end <= '1'; + WAIT; + END IF; END PROCESS;