diff --git a/libraries/dsp/st/src/vhdl/mms_st_histogram.vhd b/libraries/dsp/st/src/vhdl/mms_st_histogram.vhd index 0ab6ae546e7fcf95b630ccc011c4777d58758ec5..7070e6151ba541e0cc8f7319e2d468e2d5f2a78a 100644 --- a/libraries/dsp/st/src/vhdl/mms_st_histogram.vhd +++ b/libraries/dsp/st/src/vhdl/mms_st_histogram.vhd @@ -59,67 +59,67 @@ USE technology_lib.technology_select_pkg.ALL; ENTITY mms_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; -- - g_str : STRING := "freq.density" -- to select output to MM bus ("frequency" or "freq.density") + g_data_w : NATURAL; + g_nof_bins : NATURAL; + g_nof_data_per_sync : NATURAL ); PORT ( - dp_rst : IN STD_LOGIC; - dp_clk : IN STD_LOGIC; - mm_rst : IN STD_LOGIC; - mm_clk : IN STD_LOGIC; - - -- Streaming - snk_in : IN t_dp_sosi; + dp_clk : IN STD_LOGIC; + dp_rst : IN STD_LOGIC; + + snk_in : IN t_dp_sosi; + + mm_clk : IN STD_LOGIC; + mm_rst : IN STD_LOGIC; + + reg_mosi : IN t_mem_mosi; + reg_miso : OUT t_mem_miso; - -- Memory Mapped ram_mosi : IN t_mem_mosi; ram_miso : OUT t_mem_miso ); END mms_st_histogram; ARCHITECTURE str OF mms_st_histogram IS - - SIGNAL ram_st_histogram_mosi : t_mem_mosi; - SIGNAL ram_st_histogram_miso : t_mem_miso; - + + SIGNAL ram_clear : STD_LOGIC; + SIGNAL ram_clearing : STD_LOGIC; + BEGIN u_st_histogram : ENTITY work.st_histogram GENERIC MAP( - g_in_data_w => g_in_data_w, - g_nof_bins => g_nof_bins, - g_nof_data => g_nof_data, - g_str => g_str + g_data_w => g_data_w, + g_nof_bins => g_nof_bins, + g_nof_data_per_sync => g_nof_data_per_sync ) PORT MAP ( - dp_rst => dp_rst, - dp_clk => dp_clk, + dp_clk => dp_clk, + dp_rst => dp_rst, - snk_in => snk_in --- sla_in_ram_mosi => ram_st_histogram_mosi, --- sla_out_ram_miso => ram_st_histogram_miso + snk_in => snk_in, + + ram_clear => ram_clear, + ram_clearing => ram_clearing, + + ram_mosi => ram_mosi, + ram_miso => ram_miso ); u_st_histogram_reg : ENTITY work.st_histogram_reg --- GENERIC MAP( --- g_in_data_w => --- g_nof_bins => --- g_nof_data => --- g_str => --- ) PORT MAP ( - dp_rst => dp_rst, - dp_clk => dp_clk, - mm_rst => mm_rst, - mm_clk => mm_clk, - - mas_out_ram_mosi => ram_st_histogram_mosi, - mas_in_ram_miso => ram_st_histogram_miso, + dp_clk => dp_clk, + dp_rst => dp_rst, + + ram_clearing => ram_clearing, + + mm_clk => mm_clk, + mm_rst => mm_rst, + + ram_clear => ram_clear, - ram_mosi => ram_mosi, - ram_miso => ram_miso + reg_mosi => reg_mosi, + reg_miso => reg_miso ); END str; diff --git a/libraries/dsp/st/src/vhdl/st_histogram.vhd b/libraries/dsp/st/src/vhdl/st_histogram.vhd index 1155d86fdfe30c092165dcf58d767851a9e7da5a..efad41951435988044c07868c7123072aeeae1f4 100644 --- a/libraries/dsp/st/src/vhdl/st_histogram.vhd +++ b/libraries/dsp/st/src/vhdl/st_histogram.vhd @@ -64,15 +64,16 @@ ENTITY st_histogram IS g_nof_data_per_sync : NATURAL := 1024 ); PORT ( - dp_clk : IN STD_LOGIC; - dp_rst : IN STD_LOGIC; + dp_clk : IN STD_LOGIC; + dp_rst : IN STD_LOGIC; - snk_in : IN t_dp_sosi; + snk_in : IN t_dp_sosi; - ram_clear : IN STD_LOGIC; + ram_clear : IN STD_LOGIC; + ram_clearing : OUT STD_LOGIC; - ram_mosi : IN t_mem_mosi; - ram_miso : OUT t_mem_miso + ram_mosi : IN t_mem_mosi; + ram_miso : OUT t_mem_miso ); END st_histogram; @@ -150,7 +151,7 @@ ARCHITECTURE rtl OF st_histogram IS SIGNAL ram_clear_address : STD_LOGIC_VECTOR(c_ram_adr_w-1 DOWNTO 0); SIGNAL nxt_ram_clear_address : STD_LOGIC_VECTOR(c_ram_adr_w-1 DOWNTO 0); - SIGNAL ram_clearing : STD_LOGIC; + SIGNAL i_ram_clearing : STD_LOGIC; SIGNAL nxt_ram_clearing : STD_LOGIC; BEGIN @@ -348,12 +349,12 @@ BEGIN -- ram_clear is set) ------------------------------------------------------------------------------- -- Signal to indicate when RAM is being cleared - nxt_ram_clearing <= '1' WHEN ram_clear='1' ELSE '0' WHEN TO_UINT(ram_clear_address)=g_nof_bins-1 ELSE ram_clearing; + nxt_ram_clearing <= '1' WHEN ram_clear='1' ELSE '0' WHEN TO_UINT(ram_clear_address)=g_nof_bins-1 ELSE i_ram_clearing; -- Address counter: 0 to g_nof_bins-1. - nxt_ram_clear_address <= INCR_UVEC(ram_clear_address, 1) WHEN ram_clearing='1' ELSE (OTHERS=>'0'); + nxt_ram_clear_address <= INCR_UVEC(ram_clear_address, 1) WHEN i_ram_clearing='1' ELSE (OTHERS=>'0'); - histogram_wr_mosi.wr <= ram_clearing; + histogram_wr_mosi.wr <= i_ram_clearing; histogram_wr_mosi.address(c_ram_adr_w-1 DOWNTO 0) <= ram_clear_address; histogram_wr_mosi.wrdata <= (OTHERS=>'0'); histogram_wr_mosi.rd <= '0'; @@ -363,13 +364,15 @@ BEGIN BEGIN IF dp_rst = '1' THEN ram_clear_address <= (OTHERS=>'0'); - ram_clearing <= '0'; + i_ram_clearing <= '0'; ELSIF RISING_EDGE(dp_clk) THEN ram_clear_address <= nxt_ram_clear_address; - ram_clearing <= nxt_ram_clearing; + i_ram_clearing <= nxt_ram_clearing; END IF; END PROCESS; + ram_clearing <= i_ram_clearing; + ------------------------------------------------------------------------------- -- Expose the MM buses to the user ------------------------------------------------------------------------------- diff --git a/libraries/dsp/st/src/vhdl/st_histogram_reg.vhd b/libraries/dsp/st/src/vhdl/st_histogram_reg.vhd index 94b5895787d93f9e24bba470440a8a18b13e70a6..bc01f52c88d8bb9240ecfa48238b64cf899d1b1d 100644 --- a/libraries/dsp/st/src/vhdl/st_histogram_reg.vhd +++ b/libraries/dsp/st/src/vhdl/st_histogram_reg.vhd @@ -18,98 +18,140 @@ -- ------------------------------------------------------------------------------- -------------------------------------------------------------------------------- --- --- Author: J.W.E. Oudman --- Purpose: Provide MM slave register for st_histogram --- Description: --- Because the st_histogram component uses 2 RAM blocks that are swapped --- after every sync pulse, both blocks have to work in the dp clock domain --- and the Memory Mapped bus coming out of the component consequently also --- works in the dp clock domain. --- --- To convert the signals to the mm clock domain the common_reg_cross_domain --- component is used. Because the inner workings of that component is --- dependent on some components that take time to reliably stabialize the --- conversion takes 12 mm clock cycles before the next address may be --- requested. --- --- --- [Alternative: shared dual clocked RAM block] --- --- -------------------------------------------------------------------------------- +-- Author: +-- . Daniel van der Schuur +-- Purpose: +-- . Provide MM registers for st_histogram +-- Description: +-- . Address 0, bit 0 = RAM clear +-- . Read : 'ram_clearing' status. '1' right after write of ram_clear. '0' when not clearing RAM (anymore). +-- . Write: 'ram_clear ' control. '1' to clear RAM on write event. -LIBRARY IEEE, common_lib, dp_lib;-- mm_lib, technology_lib, +LIBRARY IEEE, common_lib; USE IEEE.std_logic_1164.ALL; USE common_lib.common_pkg.ALL; USE common_lib.common_mem_pkg.ALL; -USE dp_lib.dp_stream_pkg.ALL; ---USE technology_lib.technology_select_pkg.ALL; ENTITY st_histogram_reg IS --- GENERIC ( --- g_nof_bins : NATURAL := 512; -- is a power of 2 and g_nof_bins <= c_data_span; max. 512 --- g_str : STRING := "freq.density" -- to select output to MM bus ("frequency" or "freq.density") --- ); + PORT ( - dp_rst : IN STD_LOGIC; - dp_clk : IN STD_LOGIC; - mm_rst : IN STD_LOGIC; - mm_clk : IN STD_LOGIC; - - -- DP clocked memory bus - mas_out_ram_mosi : OUT t_mem_mosi ;--:= c_mem_mosi_rst; -- Beware, works in dp clock domain ! - mas_in_ram_miso : IN t_mem_miso ;--:= c_mem_miso_rst; -- '' ! --- ram_st_histogram_mosi : OUT t_mem_mosi; -- Beware, works in dp clock domain ! --- ram_st_histogram_miso : IN t_mem_miso; -- '' ! - - -- Memory Mapped - ram_mosi : IN t_mem_mosi; - ram_miso : OUT t_mem_miso + dp_clk : IN STD_LOGIC; + dp_rst : IN STD_LOGIC; + + ram_clear : OUT STD_LOGIC; + ram_clearing : IN STD_LOGIC; + + mm_clk : IN STD_LOGIC; + mm_rst : IN STD_LOGIC; + + reg_mosi : IN t_mem_mosi; + reg_miso : OUT t_mem_miso ); END st_histogram_reg; -ARCHITECTURE str OF st_histogram_reg IS - --- CONSTANT c_mm_reg : t_c_mem := (latency => 1, --- adr_w => 1, --- dat_w => c_word_w, --- nof_dat => 1, --- init_sl => g_default_value); +ARCHITECTURE rtl OF st_histogram_reg IS + + CONSTANT nof_addresses : NATURAL := 2; + CONSTANT c_mm_reg : t_c_mem := (latency => 1, + adr_w => ceil_log2(nof_addresses), + dat_w => c_word_w, -- Use MM bus data width = c_word_w = 32 for all MM registers + nof_dat => nof_addresses, + init_sl => '0'); + + SIGNAL mm_ram_clear : STD_LOGIC; + SIGNAL mm_ram_clearing : STD_LOGIC; BEGIN + ------------------------------------------------------------------------------ + -- MM register access in the mm_clk domain + -- . Hardcode the shared MM slave register directly in RTL instead of using + -- the common_reg_r_w instance. Directly using RTL is easier when the large + -- MM register has multiple different fields and with different read and + -- write options per field in one MM register. + ------------------------------------------------------------------------------ + p_mm_reg : PROCESS (mm_clk, mm_rst) + BEGIN + IF mm_rst = '1' THEN + -- Read access + reg_miso <= c_mem_miso_rst; + + -- Access event, register values + mm_ram_clear <= '0'; + + ELSIF rising_edge(mm_clk) THEN + -- Read access defaults + reg_miso.rdval <= '0'; + + -- Access event defaults + mm_ram_clear <= '0'; + + -- Write access: set register value + IF reg_mosi.wr = '1' THEN + CASE TO_UINT(reg_mosi.address(c_mm_reg.adr_w-1 DOWNTO 0)) IS + WHEN 0 => + mm_ram_clear <= '1'; + WHEN OTHERS => NULL; -- unused MM addresses + END CASE; + + -- Read access: get register value + ELSIF reg_mosi.rd = '1' THEN + reg_miso <= c_mem_miso_rst; -- set unused rddata bits to '0' when read + reg_miso.rdval <= '1'; -- c_mm_reg.latency = 1 + CASE TO_UINT(reg_mosi.address(c_mm_reg.adr_w-1 DOWNTO 0)) IS + WHEN 0 => + -- Read RAM clearing status + reg_miso.rddata(0) <= mm_ram_clearing; + WHEN OTHERS => NULL; -- unused MM addresses + END CASE; + END IF; + END IF; + END PROCESS; - u_common_reg_cross_domain_mosi_address : ENTITY common_lib.common_reg_cross_domain + ------------------------------------------------------------------------------ + -- Transfer register value between mm_clk and st_clk domain. + -- If the function of the register ensures that the value will not be used + -- immediately when it was set, then the transfer between the clock domains + -- can be done by wires only. Otherwise if the change in register value can + -- have an immediate effect then the bit or word value needs to be transfered + -- using: + -- + -- . common_async --> for single-bit level signal + -- . common_spulse --> for single-bit pulse signal + -- . common_reg_cross_domain --> for a multi-bit (a word) signal + -- + -- Typically always use a crossing component for the single bit signals (to + -- be on the save side) and only use a crossing component for the word + -- signals if it is necessary (to avoid using more logic than necessary). + ------------------------------------------------------------------------------ + + -- ST --> MM + u_common_async : ENTITY common_lib.common_async + GENERIC MAP ( + g_rst_level => '0' + ) PORT MAP ( - in_rst => mm_rst, - in_clk => mm_clk, - - in_new => ram_mosi.rd, - in_dat => ram_mosi.address, + clk => mm_clk, + rst => mm_rst, - out_rst => dp_rst, - out_clk => dp_clk, - - out_dat => mas_out_ram_mosi.address, - out_new => mas_out_ram_mosi.rd + din => ram_clearing, + dout => mm_ram_clearing ); - - u_reg_cross_domain_miso_rddata : ENTITY common_lib.common_reg_cross_domain + + -- MM --> ST + u_common_spulse : ENTITY common_lib.common_spulse PORT MAP ( - in_rst => dp_rst, - in_clk => dp_clk, - - in_new => mas_in_ram_miso.rdval, - in_dat => mas_in_ram_miso.rddata, + in_clk => mm_clk, + in_rst => mm_rst, + + in_pulse => mm_ram_clear, + in_busy => OPEN, - out_rst => mm_rst, - out_clk => mm_clk, + out_clk => dp_clk, + out_rst => dp_rst, - out_dat => ram_miso.rddata, - out_new => ram_miso.rdval + out_pulse => ram_clear ); -END str; +END rtl;