-- -- Multiplicity unit contains Multiplicity trigger (9 classes thresholds for T(8)..T(0) ------------------------------------------------------------------------------- -- Multiplicity counters and Trigger outputs. -- 9 Counter, 9 classes with upper and lower bound -- Counter class defined by 10 Bits (0...1023): -- Low Bound: Bit 0..9 High Bound: Bit 10..19 -- -- -- Base Address currently 0x1c00 -- address 00 0000 .. 00 1000 : 9 ratecounter (0..8) -- address 01 0000 .. 01 1000 : 9 counter classes (0..8) -- -- address 10 0000 : counter control -- (0: stop, 1:run, 2:clr, 4 enable by soreor, 8: start gated count) -- -- -- address 10 0001 .. 10 1111 : 9 counter values (0..8) -- -- address 11 0000 : 32 Bit value for gated count library IEEE; use IEEE.std_logic_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.STD_LOGIC_UNSIGNED.all; entity multi_top is port ( clk : in std_logic; -- for threshold (multiplicity trigger) cpuclk : in std_logic; -- SCSN CLK cntclk : in std_logic; -- Counter clock (40MHz) reset_n : in std_logic; S : in std_logic_vector(575 downto 0); T : out std_logic_vector(8 downto 0); soreor : in std_logic; we : in std_logic; address : in std_logic_vector(5 downto 0); -- max 8 for counter, max 8 for threshold multi_IBO : in std_logic_vector(31 downto 0); multi_OBI : out std_logic_vector(31 downto 0)); end multi_top; architecture behv of multi_top is component multi generic ( oreg : boolean); port ( clk : in std_logic; reset_n : in std_logic; invec : in std_logic_vector(575 downto 0); outvec : out std_logic_vector(9 downto 0)); end component; component rate_counter generic ( gate_time : integer; fcnt : integer); port ( cntclk : in std_logic; cpuclk : in std_logic; reset_n : in std_logic; address : in std_logic_vector(1 downto 0); ratecnt_OBI : out std_logic_vector(31 downto 0); T : in std_logic); end component; -- combinatoric signal (sync to cntclk), 1 when fit to class signal mult_in_class: std_logic_vector(8 downto 0); signal multiplicity : std_logic_vector(9 downto 0); signal multiplicity_cntclk : std_logic_vector(9 downto 0); -- signals for counter block subtype mp_threshold_st is std_logic_vector(9 downto 0); type counter_class_t is array(0 to 8) of mp_threshold_st; -- counter_class_puclk signal class_L_cpuclk : counter_class_t; signal class_L_cntclk : counter_class_t; signal class_U_cpuclk : counter_class_t; signal class_U_cntclk : counter_class_t; signal cnt_en, cnt_clr : std_logic; subtype datOBI_st is std_logic_vector(31 downto 0); type datOBI_t is array(0 to 8) of datOBI_st; signal ratecnt_OBI : datOBI_t; signal gatecount_regcpu : std_logic_vector(31 downto 0); -- scsn written value signal gatecount_cnt : std_logic_vector(31 downto 0); -- counter signal gate_start_comb : std_logic; signal gate_start_cpuclk : std_logic; signal gate_start : std_logic; signal gate_en : std_logic; signal soreor_en : std_logic; signal en : std_logic; subtype counter_st is std_logic_vector(31 downto 0); type counter_t is array(0 to 8) of counter_st; signal counter : counter_t; begin -- behv multi_1 : multi generic map ( oreg => true) -- register inside port map ( clk => clk, reset_n => reset_n, invec => S, outvec => multiplicity ); -- Register here: multiplicity_regp : process (cntclk, reset_n) begin -- process multiplicity_regp if reset_n = '0' then -- asynchronous reset (active low) multiplicity_cntclk <= (others => '0'); elsif cntclk'event and cntclk = '1' then -- rising clock edge multiplicity_cntclk <= multiplicity; end if; end process multiplicity_regp; rate_cnt_p: for i in 0 to 8 generate rate_counter_1: rate_counter generic map ( gate_time => 1, fcnt => 40000000) port map ( cntclk => cntclk, cpuclk => cpuclk, reset_n => reset_n, address => "00", ratecnt_OBI => ratecnt_OBI(i), T => mult_in_class(i)); end generate rate_cnt_p; with address select multi_OBI <= ratecnt_OBI(0) when "000000", ratecnt_OBI(1) when "000001", ratecnt_OBI(2) when "000010", ratecnt_OBI(3) when "000011", ratecnt_OBI(4) when "000100", ratecnt_OBI(5) when "000101", ratecnt_OBI(6) when "000110", ratecnt_OBI(7) when "000111", ratecnt_OBI(8) when "001000", ((31 downto 20 => '0') & class_U_cpuclk(0) & class_L_cpuclk(0)) when "010000", ((31 downto 20 => '0') & class_U_cpuclk(1) & class_L_cpuclk(1)) when "010001", ((31 downto 20 => '0') & class_U_cpuclk(2) & class_L_cpuclk(2)) when "010010", ((31 downto 20 => '0') & class_U_cpuclk(3) & class_L_cpuclk(3)) when "010011", ((31 downto 20 => '0') & class_U_cpuclk(4) & class_L_cpuclk(4)) when "010100", ((31 downto 20 => '0') & class_U_cpuclk(5) & class_L_cpuclk(5)) when "010101", ((31 downto 20 => '0') & class_U_cpuclk(6) & class_L_cpuclk(6)) when "010110", ((31 downto 20 => '0') & class_U_cpuclk(7) & class_L_cpuclk(7)) when "010111", ((31 downto 20 => '0') & class_U_cpuclk(8) & class_L_cpuclk(8)) when "011000", ((31 downto 3 => '0') & soreor_en & cnt_clr & cnt_en) when "100000", counter(0) when "100001", counter(1) when "100010", counter(2) when "100011", counter(3) when "100100", counter(4) when "100101", counter(5) when "100110", counter(6) when "100111", counter(7) when "101000", counter(8) when "101001", gatecount_regcpu when "110000", (others => '0') when others; -- 1Counter cntrl cntctrl_p : process (cpuclk, reset_n) begin -- process cntctrl_p if reset_n = '0' then -- asynchronous reset (active low) cnt_en <= '0'; cnt_clr <= '0'; soreor_en <= '0'; elsif cpuclk'event and cpuclk = '1' then -- rising clock edge if address = "100000" and we = '1' then cnt_en <= multi_IBO(0); cnt_clr <= multi_IBO(1); soreor_en <= multi_IBO(2); end if; end if; end process cntctrl_p; -- 9 Counter classes mulcounter_g : for i in 0 to 8 generate mp_cnt_regi : process (cpuclk, reset_n) begin -- process mp_th_regi if reset_n = '0' then -- asynchronous reset (active low) class_L_cpuclk(i) <= (others => '0'); class_U_cpuclk(i) <= (others => '0'); elsif cpuclk'event and cpuclk = '1' then -- rising clock edge if conv_integer(address) = i+16 and we = '1' then class_L_cpuclk(i) <= multi_IBO( 9 downto 0); class_U_cpuclk(i) <= multi_IBO(19 downto 10); end if; end if; end process mp_cnt_regi; mp_cntclk_regi : process (cntclk, reset_n) begin -- process mp_th_regi if cntclk'event and cntclk = '1' then -- rising clock edge class_L_cntclk(i) <= class_L_cpuclk(i); class_U_cntclk(i) <= class_U_cpuclk(i); end if; end process mp_cntclk_regi; end generate mulcounter_g; class_comb_p : for i in 0 to 8 generate mult_in_class(i) <= '1' when multiplicity_cntclk > class_L_cntclk(i) and multiplicity_cntclk <= class_U_cntclk(i) else '0'; end generate class_comb_p; -- 9 Counter in beetween the classes counter_g : for i in 0 to 8 generate counter_p : process (cntclk, reset_n) begin -- process counter_p if reset_n = '0' then -- asynchronous reset (active low) counter(i) <= (others => '0'); elsif cntclk'event and cntclk = '1' then -- rising clock edge if cnt_clr = '1' then counter(i) <= (others => '0'); elsif en = '1' and mult_in_class(i) = '1' then counter(i) <= counter(i) + 1; end if; end if; end process counter_p; end generate counter_g; en <= cnt_en or gate_en or (soreor_en and soreor); -- generate trigger signals 0 to 8 = match class 1 to 9 T <= mult_in_class(8 downto 0); -- ******************************************************************* -- Address 11 0000: Gated count -- register holding gate timer value in 25ns steps gatecount_regcpu_p : process (cpuclk, reset_n) begin -- process gatecount_regcpu_p if reset_n = '0' then -- asynchronous reset (active low) gatecount_regcpu <= (others => '0'); elsif cpuclk'event and cpuclk = '1' then -- rising clock edge if address = "110000" and we = '1' then gatecount_regcpu <= multi_IBO; end if; end if; end process gatecount_regcpu_p; -- bit 3 of "110000" is gate start gate_start_comb <= '1' when address = "100000" and we = '1' and multi_IBO(3) = '1' else '0'; gs_cpuclk_p : process (cpuclk, reset_n) begin -- process gs_cpuclk_p if reset_n = '0' then -- asynchronous reset (active low) gate_start_cpuclk <= '0'; elsif cpuclk'event and cpuclk = '1' then -- rising clock edge gate_start_cpuclk <= (gate_start_cpuclk or gate_start_comb) and not gate_start; end if; end process gs_cpuclk_p; -- sync to 40 MHz clock and generate feed abck for process above gs_p : process (cntclk, reset_n) begin -- process gs_p if reset_n = '0' then -- asynchronous reset (active low) gate_start <= '0'; elsif cntclk'event and cntclk = '1' then -- rising clock edge gate_start <= gate_start_cpuclk; end if; end process gs_p; -- *** Counter sync to 40 MHz clk gatecounter_p : process (cntclk, reset_n) begin -- process gatecounter_p if reset_n = '0' then -- asynchronous reset (active low) gatecount_cnt <= (others => '0'); gate_en <= '0'; elsif cntclk'event and cntclk = '1' then -- rising clock edge if gate_start = '1' then gate_en <= '1'; elsif gatecount_cnt = gatecount_regcpu then gate_en <= '0'; end if; if gate_en = '1' then gatecount_cnt <= gatecount_cnt + 1; else gatecount_cnt <= (others => '0'); end if; end if; end process gatecounter_p; end behv; ------------------------------------------------------------------------------- -- Device utilization summary: -- --------------------------- -- -- Selected Device : 4vlx40ff1148-11 -- -- Number of Slices: 1121 out of 18432 6% -- Number of Slice Flip Flops: 584 out of 36864 1% -- Number of 4 input LUTs: 2004 out of 36864 5% -- Number of IOs: 656 -- Number of bonded IOBs: 633 out of 640 98% -- Number of GCLKs: 3 out of 32 9% -- -- Timing summary: -- --------------- -- -- Timing errors: 0 Score: 0 -- -- Constraints cover 22256 paths, 0 nets, and 1497 connections -- -- Design statistics: -- Minimum period: 6.277ns (Maximum frequency: 159.312MHz) --