architecture input_to_trigger_logic_arch of input_to_trigger_logic_record is
constant register_bits : integer := (INPUTS-1)/32*32+32-1;
type reg_t is array(0 to OUTPUTS-1) of std_logic_vector(register_bits downto 0);
-signal enable : reg_t;
-signal invert : std_logic_vector(register_bits downto 0);
-signal coincidence1 : std_logic_vector(register_bits downto 0);
-signal coincidence2 : std_logic_vector(register_bits downto 0);
+signal enable : reg_t := (others => (others => '0'));
+signal invert : std_logic_vector(register_bits downto 0) := (others => '0');
+signal coincidence1 : std_logic_vector(register_bits downto 0) := (others => '0');
+signal coincidence2 : std_logic_vector(register_bits downto 0) := (others => '0');
signal coin_in_1 : std_logic;
signal coin_in_2 : std_logic;
-signal stretch_inp : std_logic_vector(register_bits downto 0);
+signal stretch_inp : std_logic_vector(register_bits downto 0) := (others => '0');
type inp_t is array(0 to 4) of std_logic_vector(INPUTS-1 downto 0);
-signal inp_shift : inp_t;
+signal inp_shift : inp_t := (others => (others => '0'));
-signal inp_inv : std_logic_vector(INPUTS-1 downto 0);
-signal inp_long : std_logic_vector(INPUTS-1 downto 0);
-signal inp_verylong : std_logic_vector(INPUTS-1 downto 0);
+signal inp_inv : std_logic_vector(INPUTS-1 downto 0) := (others => '0');
+signal inp_long : std_logic_vector(INPUTS-1 downto 0) := (others => '0');
+signal inp_verylong : std_logic_vector(INPUTS-1 downto 0) := (others => '0');
-signal output_i : std_logic_vector(OUTPUTS-1 downto 0);
-signal out_reg : std_logic_vector(OUTPUTS-1 downto 0);
+signal output_i : std_logic_vector(OUTPUTS-1 downto 0) := (others => '0');
+signal out_reg : std_logic_vector(OUTPUTS-1 downto 0) := (others => '0');
signal got_coincidence : std_logic;
-signal coin_enable : std_logic;
+signal coin_enable : std_logic := '0';
+signal current_multiplicity, set_multiplicity : unsigned(7 downto 0);
+signal multiplicity_trigger : std_logic := '0';
begin
THE_CONTROL : process
when "01" => invert(31 downto 0) <= BUS_RX.data;
when "10" => coincidence1(31 downto 0)<= BUS_RX.data;
when "11" => coincidence2(31 downto 0)<= BUS_RX.data;
+ when others => null;
end case;
elsif slice=1 and INPUTS > 32 then
case BUS_RX.addr(3 downto 2) is
when "01" => invert(63 downto 32) <= BUS_RX.data;
when "10" => coincidence1(63 downto 32)<= BUS_RX.data;
when "11" => coincidence2(63 downto 32)<= BUS_RX.data;
+ when others => null;
end case;
elsif slice=2 and INPUTS > 64 then
case BUS_RX.addr(3 downto 2) is
when "01" => invert(95 downto 64) <= BUS_RX.data;
when "10" => coincidence1(95 downto 64)<= BUS_RX.data;
when "11" => coincidence2(95 downto 64)<= BUS_RX.data;
+ when others => null;
end case;
end if;
+ elsif BUS_RX.addr(5 downto 0) = "110010" then
+ set_multiplicity <= unsigned(BUS_RX.data(23 downto 16));
else
BUS_TX.nack <= '1';
BUS_TX.ack <= '0';
when "01" => BUS_TX.data <= invert(31 downto 0) ;
when "10" => BUS_TX.data <= coincidence1(31 downto 0);
when "11" => BUS_TX.data <= coincidence2(31 downto 0);
+ when others => null;
end case;
elsif slice=1 and INPUTS > 32 then
case BUS_RX.addr(3 downto 2) is
when "01" => BUS_TX.data <= invert(63 downto 32) ;
when "10" => BUS_TX.data <= coincidence1(63 downto 32);
when "11" => BUS_TX.data <= coincidence2(63 downto 32);
+ when others => null;
end case;
elsif slice=2 and INPUTS > 64 then
case BUS_RX.addr(3 downto 2) is
when "01" => BUS_TX.data <= invert(95 downto 64) ;
when "10" => BUS_TX.data <= coincidence1(95 downto 64);
when "11" => BUS_TX.data <= coincidence2(95 downto 64);
+ when others => null;
end case;
else BUS_TX.data <= (others => '0');
end if;
BUS_TX.data <= (others => '0');
BUS_TX.data( 6 downto 0) <= std_logic_vector(to_unsigned(INPUTS,7));
BUS_TX.data(11 downto 8) <= std_logic_vector(to_unsigned(OUTPUTS,4));
+ elsif BUS_RX.addr(5 downto 0) = "110010" then
+ BUS_TX.data <= x"00" & std_logic_vector(set_multiplicity) & x"00" & std_logic_vector(current_multiplicity);
else
BUS_TX.nack <= '1';
BUS_TX.ack <= '0';
got_coincidence <= coin_in_1 and coin_in_2 and coin_enable when rising_edge(CLK);
gen_outs : for i in 0 to OUTPUTS-1 generate
- output_i(i) <= or_all(((inp_long and stretch_inp(INPUTS-1 downto 0)) or (inp_inv(INPUTS-1 downto 0) and not stretch_inp(INPUTS-1 downto 0))) and enable(i)(INPUTS-1 downto 0)) or got_coincidence;
+ gen_first : if i = 0 generate
+ output_i(i) <= or_all(((inp_long and stretch_inp(INPUTS-1 downto 0)) or (inp_inv(INPUTS-1 downto 0) and not stretch_inp(INPUTS-1 downto 0))) and enable(i)(INPUTS-1 downto 0)) or got_coincidence;
+ end generate;
+ gen_second : if i = 1 generate
+ output_i(i) <= or_all(((inp_long and stretch_inp(INPUTS-1 downto 0)) or (inp_inv(INPUTS-1 downto 0) and not stretch_inp(INPUTS-1 downto 0))) and enable(i)(INPUTS-1 downto 0)) or multiplicity_trigger;
+ end generate;
+ gen_rest : if i > 1 generate
+ output_i(i) <= or_all(((inp_long and stretch_inp(INPUTS-1 downto 0)) or (inp_inv(INPUTS-1 downto 0) and not stretch_inp(INPUTS-1 downto 0))) and enable(i)(INPUTS-1 downto 0));
+ end generate;
+end generate;
+
+gen_mult : if OUTPUTS >= 2 generate
+ PROC_MULT : process
+ variable m : integer range 0 to INPUTS-1;
+ begin
+ wait until rising_edge(CLK);
+ m := 0;
+ for i in 0 to INPUTS-1 loop
+ if inp_verylong(i) = '1' and enable(0)(i) = '1' then
+ m := m + 1;
+ end if;
+ end loop;
+ current_multiplicity <= to_unsigned(m,8);
+
+ if current_multiplicity >= set_multiplicity and set_multiplicity > 0 then
+ multiplicity_trigger <= '1';
+ else
+ multiplicity_trigger <= '0';
+ end if;
+ end process;
+end generate;
+gen_no_mult : if OUTPUTS < 2 generate
+ multiplicity_trigger <= '0';
end generate;