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 got_simplecoin : std_logic;
signal coin_enable : std_logic := '0';
signal current_multiplicity, set_multiplicity : unsigned(7 downto 0);
signal multiplicity_trigger : std_logic := '0';
+signal multiplicity_enable : std_logic_vector(31 downto 0);
+
+signal set_output_coin, set_output_mult, set_output_simplecoin : std_logic_vector(7 downto 0);
+
+type coincidence_arr is array(0 to 16) of integer range 0 to 31;
+signal coincidence_config_1, coincidence_config_2 : coincidence_arr;
+signal coincidence_enable : std_logic_vector(15 downto 0);
begin
THE_CONTROL : process
if BUS_RX.write = '1' then
BUS_TX.ack <= '1';
- if BUS_RX.addr(5) = '0' and outchan < OUTPUTS then
+ if BUS_RX.addr(6 downto 5) = "00" and outchan < OUTPUTS then
if slice=0 then enable(outchan)(31 downto 0) <= BUS_RX.data;
elsif slice=1 and INPUTS > 32 then enable(outchan)(63 downto 32) <= BUS_RX.data;
elsif slice=2 and INPUTS > 64 then enable(outchan)(95 downto 64) <= BUS_RX.data;
end if;
- elsif BUS_RX.addr(5 downto 4) = "10" then
+ elsif BUS_RX.addr(6 downto 4) = "010" then
if slice=0 then
case BUS_RX.addr(3 downto 2) is
when "00" => stretch_inp(31 downto 0) <= BUS_RX.data;
when others => null;
end case;
end if;
- elsif BUS_RX.addr(5 downto 0) = "110010" then
+ elsif BUS_RX.addr(6 downto 4) = "100" then
+ coincidence_config_1(to_integer(unsigned(BUS_RX.addr(3 downto 0)))) <= to_integer(unsigned(BUS_RX.data(12 downto 8)));
+ coincidence_config_2(to_integer(unsigned(BUS_RX.addr(3 downto 0)))) <= to_integer(unsigned(BUS_RX.data(4 downto 0)));
+ coincidence_enable(to_integer(unsigned(BUS_RX.addr(3 downto 0)))) <= BUS_RX.data(31);
+ elsif BUS_RX.addr(6 downto 0) = "0110010" then
set_multiplicity <= unsigned(BUS_RX.data(23 downto 16));
+ elsif BUS_RX.addr(6 downto 0) = "0110011" then
+ multiplicity_enable <= BUS_RX.data;
+ elsif BUS_RX.addr(6 downto 0) = "0110100" then
+ set_output_simplecoin <= BUS_RX.data(7 downto 0);
+ set_output_mult <= BUS_RX.data(15 downto 8);
+ set_output_coin <= BUS_RX.data(23 downto 16);
else
BUS_TX.nack <= '1';
BUS_TX.ack <= '0';
end if;
if BUS_RX.read = '1' then
BUS_TX.ack <= '1';
- if BUS_RX.addr(5) = '0' and outchan < OUTPUTS then
+ if BUS_RX.addr(6 downto 5) = "00" and outchan < OUTPUTS then
if slice=0 then BUS_TX.data <= enable(outchan)(31 downto 0);
elsif slice=1 and INPUTS > 32 then BUS_TX.data <= enable(outchan)(63 downto 32);
elsif slice=2 and INPUTS > 64 then BUS_TX.data <= enable(outchan)(95 downto 64);
- else BUS_TX.data <= (others => '0');
+ else
+ BUS_TX.data <= (others => '0');
+ BUS_TX.ack <= '0';
+ BUS_TX.unknown <= '1';
end if;
- elsif BUS_RX.addr(5 downto 4) = "10" then
+ elsif BUS_RX.addr(6 downto 4) = "010" then
if slice=0 then
case BUS_RX.addr(3 downto 2) is
when "00" => BUS_TX.data <= stretch_inp(31 downto 0) ;
when "11" => BUS_TX.data <= coincidence2(95 downto 64);
when others => null;
end case;
- else BUS_TX.data <= (others => '0');
+ else
+ BUS_TX.data <= (others => '0');
+ BUS_TX.ack <= '0';
+ BUS_TX.unknown <= '1';
end if;
- elsif BUS_RX.addr(5 downto 0) = "110000" then
+ elsif BUS_RX.addr(6 downto 4) = "100" then
+ BUS_TX.data(12 downto 8) <= std_logic_vector(to_unsigned(coincidence_config_1(to_integer(unsigned(BUS_RX.addr(3 downto 0)))),5));
+ BUS_TX.data( 4 downto 0) <= std_logic_vector(to_unsigned(coincidence_config_2(to_integer(unsigned(BUS_RX.addr(3 downto 0)))),5));
+ BUS_TX.data(31) <= coincidence_enable(to_integer(unsigned(BUS_RX.addr(3 downto 0))));
+ elsif BUS_RX.addr(6 downto 0) = "0110000" then
BUS_TX.data(OUTPUTS-1 downto 0) <= out_reg;
BUS_TX.data(31 downto OUTPUTS) <= (others => '0');
- elsif BUS_RX.addr(5 downto 0) = "110001" then
+ elsif BUS_RX.addr(6 downto 0) = "0110001" then
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
+ elsif BUS_RX.addr(6 downto 0) = "0110010" then
BUS_TX.data <= x"00" & std_logic_vector(set_multiplicity) & x"00" & std_logic_vector(current_multiplicity);
+ elsif BUS_RX.addr(6 downto 0) = "0110011" then
+ BUS_TX.data <= multiplicity_enable;
+ elsif BUS_RX.addr(6 downto 0) = "0110100" then
+ BUS_TX.data <= x"00" & set_output_coin & set_output_mult & set_output_coin;
else
BUS_TX.nack <= '1';
BUS_TX.ack <= '0';
end process;
-
+----------------------------
+-- Shift register for stretching
+----------------------------
inp_shift(0) <= (inp_inv or inp_shift(0)) and not (inp_shift(1) and not inp_inv);
gen_shift: for i in 1 to 4 generate
inp_shift(i) <= inp_shift(i-1) when rising_edge(CLK);
end generate;
-coin_enable <= or_all(coincidence1) when rising_edge(CLK);
-
+----------------------------
+-- Input Signals
+----------------------------
inp_inv <= INPUT xor invert(INPUTS-1 downto 0);
inp_long <= inp_shift(0) or inp_shift(1);
inp_verylong <= inp_shift(1) or inp_shift(2) or inp_shift(3) or inp_shift(4) when rising_edge(CLK);
-coin_in_1 <= or_all(coincidence1(INPUTS-1 downto 0) and inp_verylong) when rising_edge(CLK);
-coin_in_2 <= or_all(coincidence2(INPUTS-1 downto 0) and inp_verylong) when rising_edge(CLK);
-got_coincidence <= coin_in_1 and coin_in_2 and coin_enable when rising_edge(CLK);
-
+----------------------------
+-- Outputs
+----------------------------
gen_outs : for i in 0 to OUTPUTS-1 generate
- 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;
+ 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_simplecoin and set_output_simplecoin(i))
+ or (multiplicity_trigger and set_output_mult(i))
+ or (got_coincidence and set_output_coin(i))
+ ;
end generate;
+out_reg <= output_i when rising_edge(CLK);
+OUTPUT <= output_i;
+
+----------------------------
+-- Simple Coincidence
+----------------------------
+coin_enable <= or_all(coincidence1) when rising_edge(CLK);
+
+coin_in_1 <= or_all(coincidence1(INPUTS-1 downto 0) and inp_verylong) when rising_edge(CLK);
+coin_in_2 <= or_all(coincidence2(INPUTS-1 downto 0) and inp_verylong) when rising_edge(CLK);
+got_simplecoin <= coin_in_1 and coin_in_2 and coin_enable when rising_edge(CLK);
+
+
+
+----------------------------
+-- Multiplicity Trigger
+----------------------------
+
gen_mult : if OUTPUTS >= 2 generate
PROC_MULT : process
variable m : integer range 0 to INPUTS-1;
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
+ if inp_verylong(i) = '1' and multiplicity_enable(i) = '1' then
m := m + 1;
end if;
end loop;
end generate;
-out_reg <= output_i when rising_edge(CLK);
+----------------------------
+-- Advanced Coincidence
+----------------------------
+process(coincidence_config_1, coincidence_config_2, inp_verylong)
+ variable t : std_logic;
+begin
+ t := '0';
+ for i in 0 to 15 loop
+ t := t or (coincidence_enable(i) and inp_verylong(coincidence_config_1(i)) and inp_verylong(coincidence_config_2(i)));
+ end loop;
+ got_coincidence <= t;
+end process;
-OUTPUT <= output_i;
-end architecture;
\ No newline at end of file
+end architecture;