diff --git a/libraries/dsp/st/hdllib.cfg b/libraries/dsp/st/hdllib.cfg index 32ff32a2e3c1ab532b0a9f4bca1a8c4ad9aedf79..2313597703f4d281c5e10784465184423562cfdb 100644 --- a/libraries/dsp/st/hdllib.cfg +++ b/libraries/dsp/st/hdllib.cfg @@ -11,12 +11,15 @@ synth_files = src/vhdl/st_sst.vhd # src/vhdl/st_top.vhd src/vhdl/st_histogram.vhd + src/vhdl/st_histogram_reg.vhd + src/vhdl/mms_st_histogram.vhd test_bench_files = tb/vhdl/tb_st_acc.vhd tb/vhdl/tb_st_calc.vhd tb/vhdl/tb_mmf_st_sst.vhd tb/vhdl/tb_st_histogram.vhd + tb/vhdl/tb_mms_st_histogram.vhd regression_test_vhdl = tb/vhdl/tb_st_acc.vhd diff --git a/libraries/dsp/st/src/vhdl/st_histogram.vhd b/libraries/dsp/st/src/vhdl/st_histogram.vhd index 66faa640ec7d779f38bc90bf731445231493ba1c..7b2a197abdbec1197285bbd522bce228fd30e772 100644 --- a/libraries/dsp/st/src/vhdl/st_histogram.vhd +++ b/libraries/dsp/st/src/vhdl/st_histogram.vhd @@ -21,13 +21,14 @@ ------------------------------------------------------------------------------- -- -- Author: J.W.E. Oudman --- Purpose: Create a histogram from the input data and present it to the MM bus +-- 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 2 -- cycles. While one RAM block is used to count the input samples, the other --- is read by the MM bus through a fifo. +-- is read by the MM bus through st_histogram_reg. -- -- -- ram_pointer ram_pointer @@ -35,16 +36,16 @@ -- | /o--- RAM_0 ---o | -- |/ | -- / | --- snk_in ----o/ | /o----- FIFO to MM ---- MM --- |/ +-- 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. --- Because the MM bus needs to access one RAM block but can't use it's mm_clk --- on it a FIFO is used. +-- 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. -- -- Remarks: -- . Because the values of the generics g_nof_bins depends on g_in_data_w @@ -84,17 +85,17 @@ ENTITY st_histogram IS g_str : STRING := "freq.density" -- to select output to MM bus ("frequency" or "freq.density") ); PORT ( - mm_rst : IN STD_LOGIC; - mm_clk : IN STD_LOGIC; dp_rst : IN STD_LOGIC; dp_clk : IN STD_LOGIC; -- Streaming snk_in : IN t_dp_sosi; - -- Memory Mapped - ram_mosi : IN t_mem_mosi; - ram_miso : OUT t_mem_miso + -- 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 -- '' ! ); END st_histogram; @@ -127,18 +128,22 @@ ARCHITECTURE str OF st_histogram IS SIGNAL nxt_same_r_w_adr : STD_LOGIC := '0'; - 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); - SIGNAL nxt_wr_dat_a : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0); - SIGNAL adr_a : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low); - SIGNAL adr_b : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low); - SIGNAL rd_en_b : STD_LOGIC := '0'; - SIGNAL rd_dat_b : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0); - SIGNAL rd_val_b : STD_LOGIC; + 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); + SIGNAL nxt_wr_dat_a : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0); + SIGNAL adr_a : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low); + SIGNAL adr_b : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low); + SIGNAL rd_en_b : STD_LOGIC := '0'; + SIGNAL rd_dat_b : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0); + SIGNAL rd_val_b : 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_a : STD_LOGIC; @@ -167,13 +172,16 @@ ARCHITECTURE str OF st_histogram IS 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; + 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; + +-- 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 @@ -309,6 +317,7 @@ BEGIN wr_en_a <= nxt_wr_en_a; same_r_w_adr <= nxt_same_r_w_adr; cycle_cnt <= nxt_cycle_cnt; + prev_ram_out_wr_adr <= ram_out_wr_adr; END IF; END PROCESS; @@ -326,10 +335,6 @@ BEGIN 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; --- ram_0_mosi <= c_common_pipelinemem_mosi_rst; - IF ram_pointer='0' THEN -- ST side (RAM 0) @@ -342,7 +347,7 @@ BEGIN rd_val_b <= ram_0_rd_val_b; - -- MM side (RAM 1) + -- dp_clk'd 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; @@ -363,7 +368,7 @@ BEGIN rd_dat_b <= ram_1_rd_dat_b; rd_val_b <= ram_1_rd_val_b; - -- MM side (RAM 0) + --dp_clk'd 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; @@ -371,10 +376,7 @@ BEGIN 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; --- ram_0_mosi <= ram_mosi;2 + END IF; END PROCESS; @@ -478,6 +480,25 @@ BEGIN + ----------------------------------------------------------------------------- + -- 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 + ); + + + + + + ----------------------------------------------------------------------------- -- Dual swapped RAM instance ----------------------------------------------------------------------------- @@ -524,10 +545,28 @@ BEGIN ----------------------------------------------------------------------------- - -- Connect MM interface to DUAL swapped RAM read out histogram statistics + -- Connect interface to DUAL swapped RAM, read out histogram statistics: + -- . Limit the data read by the MM master to the RAM block where it started + -- to read (the values read after a new sync will be OTHERS => '0') + -- . In the last g_nof_bins cycles all addresses will sequentially be cleared ----------------------------------------------------------------------------- - p_ram_to_fifo : PROCESS(dp_pipeline_src_out_pp.sync, cycle_cnt) IS + 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(dp_pipeline_src_out_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, ram_out_same_w_r_adr) IS BEGIN IF dp_pipeline_src_out_pp.sync = '1' THEN ram_out_wr_en <= '0'; @@ -536,25 +575,57 @@ BEGIN 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; + IF ram_out_same_w_r_adr = '1' THEN + --ram_out_rd_adr <= sla_in_ram_mosi.address(c_ram.adr_w-1 DOWNTO 0); -- fifo_in_rd_adr; + ram_out_rd_en <= '0'; --sla_in_ram_mosi.rd; -- fifo_in_rd_en; + sla_out_ram_miso.rddata(c_ram.dat_w-1 DOWNTO 0) <= (OTHERS => '0'); -- ram_out_rd_dat; + sla_out_ram_miso.rdval <= ram_out_rd_val; -- ram_out_rd_val; + ELSE + ram_out_rd_adr <= sla_in_ram_mosi.address(c_ram.adr_w-1 DOWNTO 0); -- fifo_in_rd_adr; + ram_out_rd_en <= sla_in_ram_mosi.rd; -- fifo_in_rd_en; + 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; -- ram_out_rd_val; + END IF; + --ram_out_rd_en <= '0'; + nxt_cycle_cnt <= 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; + ram_out_wr_adr <= INCR_UVEC(prev_ram_out_wr_adr, 1); + --prev_ram_out_wr_adr <= ram_out_wr_adr; + nxt_cycle_cnt <= cycle_cnt +1; + IF ram_out_same_w_r_adr = '1' OR snk_in.sync = '1' THEN + --ram_out_rd_adr <= sla_in_ram_mosi.address(c_ram.adr_w-1 DOWNTO 0); -- fifo_in_rd_adr; + --ram_out_rd_en <= sla_in_ram_mosi.rd; -- fifo_in_rd_en; + sla_out_ram_miso.rddata(c_ram.dat_w-1 DOWNTO 0) <= (OTHERS => '0'); -- ram_out_rd_dat; + sla_out_ram_miso.rdval <= ram_out_rd_val; -- ram_out_rd_val; + ELSE + ram_out_rd_adr <= sla_in_ram_mosi.address(c_ram.adr_w-1 DOWNTO 0); -- fifo_in_rd_adr; + ram_out_rd_en <= sla_in_ram_mosi.rd; -- fifo_in_rd_en; + 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; -- ram_out_rd_val; + END IF; +-- ELSIF snk_in.sync = '1' AND mm_adr_cnt /= 0 THEN +-- mm_adr_illegal <= '1'; +-- ELSIF mm_adr_cnt = g_nof_bins THEN +-- mm_adr_illegal <= '0'; + ELSIF mm_adr_illegal_pp = '1' THEN + ram_out_rd_adr <= sla_in_ram_mosi.address(c_ram.adr_w-1 DOWNTO 0); -- fifo_in_rd_adr; + ram_out_rd_en <= sla_in_ram_mosi.rd; -- fifo_in_rd_en; + sla_out_ram_miso.rddata(c_ram.dat_w-1 DOWNTO 0) <= (OTHERS => '0'); -- ram_out_rd_dat; + sla_out_ram_miso.rdval <= ram_out_rd_val; -- ram_out_rd_val; + nxt_cycle_cnt <= 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; +-- ram_out_wr_en <= ram_mosi.wr --fifo_in_wr_en; +-- ram_out_wr_dat <= ram_mosi.wrdata(c_ram.dat_w-1 DOWNTO 0) -- fifo_in_wr_dat; +-- ram_out_wr_adr <= fifo_in_wr_adr; + ram_out_rd_adr <= sla_in_ram_mosi.address(c_ram.adr_w-1 DOWNTO 0); -- fifo_in_rd_adr; + ram_out_rd_en <= sla_in_ram_mosi.rd; -- fifo_in_rd_en; + sla_out_ram_miso.rddata(c_ram.dat_w-1 DOWNTO 0) <= ram_out_rd_dat; -- ram_out_rd_dat; + sla_out_ram_miso.rdval <= ram_out_rd_val; -- ram_out_rd_val; + nxt_cycle_cnt <= cycle_cnt +1; END IF; END PROCESS; - END str; diff --git a/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd b/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd index 1c94340e8f40d9bca2559644177aa4973e13c838..3e0afad90bd5c7ec6f56f5dac4195085559dfc1c 100644 --- a/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd +++ b/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd @@ -20,7 +20,7 @@ END tb_st_histogram; ARCHITECTURE tb OF tb_st_histogram IS - CONSTANT c_mm_init_time : NATURAL := 5; +-- CONSTANT c_mm_init_time : NATURAL := 5; -- <-- CONSTANT c_dp_inti_time : NATURAL := 5; SIGNAL tb_end : STD_LOGIC := '0'; @@ -28,12 +28,12 @@ ARCHITECTURE tb OF tb_st_histogram IS ---------------------------------------------------------------------------- -- Clocks and resets ---------------------------------------------------------------------------- - CONSTANT c_mm_clk_period : TIME := 20 ns; +-- CONSTANT c_mm_clk_period : TIME := 20 ns; -- <-- CONSTANT c_dp_clk_period : TIME := 5 ns; - SIGNAL mm_rst : STD_LOGIC := '1'; - SIGNAL mm_clk : STD_LOGIC := '1'; +-- SIGNAL mm_rst : STD_LOGIC := '1'; -- <-- +-- SIGNAL mm_clk : STD_LOGIC := '1'; SIGNAL dp_rst : STD_LOGIC; SIGNAL dp_clk : STD_LOGIC := '1'; @@ -53,8 +53,8 @@ BEGIN ---------------------------------------------------------------------------- -- Clock and reset generation ---------------------------------------------------------------------------- - mm_clk <= NOT mm_clk OR tb_end AFTER c_mm_clk_period/2; - mm_rst <= '1', '0' AFTER c_mm_clk_period*c_mm_init_time; +-- mm_clk <= NOT mm_clk OR tb_end AFTER c_mm_clk_period/2; -- <-- +-- mm_rst <= '1', '0' AFTER c_mm_clk_period*c_mm_init_time; dp_clk <= NOT dp_clk OR tb_end AFTER c_dp_clk_period/2; dp_rst <= '1', '0' AFTER c_dp_clk_period*c_dp_inti_time; @@ -233,8 +233,6 @@ BEGIN g_str => g_str ) PORT MAP ( - mm_rst => mm_rst, - mm_clk => mm_clk, dp_rst => dp_rst, dp_clk => dp_clk, @@ -242,8 +240,8 @@ BEGIN snk_in => st_histogram_snk_in, -- Memory Mapped - ram_mosi => c_mem_mosi_rst, - ram_miso => OPEN + sla_in_ram_mosi => c_mem_mosi_rst, + sla_out_ram_miso => OPEN ); END tb;