--- /dev/null
+library ieee;
+ use ieee.std_logic_1164.all;
+ use ieee.numeric_std.all;
+
+library work;
+ use work.trb_net_std.all;
+
+
+
+entity shutdown_comp is
+generic(
+ INPUTS : integer := 24;
+ OUTPUTS : integer := 8
+ );
+ port(
+ clk_in : in std_logic;
+ signal_in : in std_logic_vector(INPUTS-1 downto 0);
+ max_number_reg : in std_logic_vector(31 downto 0);
+ disable_reg : in std_logic_vector(31 downto 0);
+
+ processed_signal : out std_logic_vector(OUTPUTS-1 downto 0)
+ );
+end shutdown_comp;
+
+
+architecture behave of shutdown_comp is
+
+signal max_signals : integer range 0 to 255;
+signal sum_signals : integer range 0 to 255;
+signal temp_out : std_logic_vector(OUTPUTS-1 downto 0);
+
+
+
+
+begin
+-- max_signals <= to_integer(unsigned(max_number_reg))+1;
+max_signals <= to_integer(unsigned(max_number_reg));
+sum_signals <= count_ones(signal_in and not disable_reg(INPUTS-1 downto 0));
+
+
+
+
+PROC_SAFETYOFF: process (temp_out) -- stops the entity from sending signals before there are values recieved from the bussystem
+begin
+if max_signals = 0 then
+ processed_signal <= (others => '0');
+ else
+ processed_signal <= temp_out;
+end if;
+end process;
+
+
+
+
+
+PROC_COMPARE: process begin
+wait until rising_edge(clk_in);
+ if sum_signals >= max_signals then
+ temp_out <= (others => '0');
+ temp_out(0)<='1';
+
+ else
+ temp_out <= (others => '0');
+ --processed_signal(0)<='0';
+ end if;
+
+end process;
+
+end behave;
+
+
+
+
+
+
+
+
+
+
+
+--
+-- function count_ones( input:std_logic_vector ) return integer is
+-- variable temp:std_logic_vector(input'range);
+-- begin
+-- temp := (others => '0');
+-- for i in input'range loop
+-- -- if input(i) = '1' then
+-- temp := temp + input(i);
+-- -- end if;
+-- end loop;
+-- return conv_integer(temp);
+-- end function count_ones;
--- /dev/null
+library ieee;
+ use ieee.std_logic_1164.all;
+ use ieee.numeric_std.all;
+
+library work;
+ use work.trb_net_std.all;
+
+
+entity shutdown_indv is
+
+ port(
+ clk_in : in std_logic;
+ signal_in : in std_logic;
+ int_time : in std_logic_vector (31 downto 0);
+ max_count : in std_logic_vector (31 downto 0);
+ current_hits_vctr : out std_logic_vector (31 downto 0);
+ processed_signal : out std_logic
+ );
+end shutdown_indv;
+
+
+
+
+architecture behave of shutdown_indv is
+
+-- declare all signals like pulser
+signal ms_timer : unsigned(15 downto 0):= x"0000";
+signal ms_pulse : std_logic;
+signal integration_time_int: unsigned(31 downto 0):= x"00000000";
+-- signal current_hits_vctr: std_logic_vector (31 downto 0);
+signal max_hitcount: unsigned(31 downto 0):= x"00000000";
+signal hitcounter : unsigned(31 downto 0):= x"00000000";
+signal hitsaver : unsigned(31 downto 0):= x"00000000";
+signal hitteller : unsigned(31 downto 0):= x"00000000";
+-- signal hitcounter2 : unsigned(31 downto 0):= x"00000000";
+signal timecounter : unsigned(31 downto 0):= x"00000000";
+signal temp_save1 : std_logic;
+signal temp_save2 : std_logic;
+signal ext : std_logic;
+signal finalout : std_logic;
+-- signal temp_save2 : std_logic;
+signal temp_out : std_logic;
+signal reset_pulse : std_logic;
+signal reset_hitcounter : std_logic;
+signal reset_timecounter : std_logic;
+
+
+begin
+
+ integration_time_int <= unsigned(int_time(31 downto 0));
+-- max_hitcount <= unsigned(max_count(31 downto 0))+1; --Sehr ungalante methode den anfangsfehler zu umgehen, evtl wieder loeschen
+ max_hitcount <= unsigned(max_count(31 downto 0));
+ current_hits_vctr <= std_logic_vector(hitteller);
+-- hitsaver <= hitcounter;
+
+
+PROC_SAFETYOFF: process begin -- stops the entity from sending signals before there are values recieved from the bussystem
+wait until rising_edge(clk_in);
+
+if max_hitcount = x"00000000" or integration_time_int = x"00000000" then
+ processed_signal <= '0';
+ else
+ processed_signal <= finalout;
+end if;
+end process;
+
+EDGEDETECT: process is
+begin
+wait until rising_edge(clk_in);
+ hitsaver <= hitcounter;
+ temp_save1 <= signal_in;
+ temp_save2 <= temp_save1;
+
+if temp_out='1' or ext='1' then
+ finalout <= '1';
+else
+ finalout <='0';
+end if;
+
+end process;
+
+HITCOUNT: process is
+begin
+wait until rising_edge(clk_in);
+if reset_pulse='1' then
+ hitcounter <= x"00000000";
+elsif temp_save1='1' and temp_save2='0' then
+ hitcounter<= hitcounter+1;
+else
+ hitcounter<=hitcounter+0;
+end if;
+
+end process;
+
+
+MAXHITS_ALERT: process begin
+wait until rising_edge(clk_in);
+
+if hitcounter >= max_hitcount then
+ temp_out <= '1';
+else
+ temp_out <= '0';
+end if;
+end process;
+
+POC_OUTPUT: process begin
+wait until rising_edge(clk_in);
+
+if reset_pulse='1' then
+ hitteller <= hitsaver;
+ if temp_out = '1' then
+-- temp_out<='0';
+ ext<='1';
+ elsif ext='1' then
+ ext<='0';
+-- temp_out<='0';
+ else
+-- temp_out<='0';
+ ext<='0';
+ end if;
+end if;
+end process;
+
+
+--
+-- PROC_OUTPUT: process (reset_pulse)
+-- begin
+-- hitteller <= hitcounter;
+-- -- hitcounter <= x"00000000";
+-- if temp_out = '1' then
+-- temp_out<='0';
+-- ext<='1';
+-- elsif ext='1' then
+-- ext<='0';
+-- temp_out<='0';
+-- else
+-- temp_out<='0';
+-- ext<='0';
+-- end if;
+--
+-- end process;
+--
+PROC_MSPUSER: process begin -- generate a pulse every 10.000 pulses so its every 0.1ms
+wait until rising_edge (clk_in);
+ if ms_timer=x"2710" then -- eqals 10.000 and 14 dual digits ORIGINAL CODE
+-- if ms_timer=x"0196" then -- eqals 150 ticks
+ ms_pulse<='1';
+ ms_timer<=x"0000" ;
+ else
+ ms_timer <= ms_timer+1;
+ ms_pulse<='0';
+ end if;
+end process;
+
+
+TIMERESETPULSE: process begin -- generates a pulse every time the integration window is closed
+wait until rising_edge(clk_in);
+
+ if timecounter >= integration_time_int then -- changed from = so it doesnt softlock in between < and >
+ reset_pulse <= '1';
+ timecounter <= x"00000000";
+ elsif timecounter < integration_time_int and ms_pulse='1' then
+ timecounter <= timecounter +1;
+ reset_pulse <= '0';
+ else
+ reset_pulse <= '0';
+
+ end if;
+end process;
+
+
+
+
+
+
+end behave;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+ library ieee;
+ use ieee.std_logic_1164.all;
+ use ieee.numeric_std.all;
+
+library work;
+ use work.trb_net_std.all;
+
+entity shutdown_logic is
+ generic(
+ INPUTS : integer := 24;
+ OUTPUTS : integer := 8
+ );
+ port(
+ CLK : in std_logic;
+ RESET : in std_logic;
+
+ --Slowcontrol
+ BUS_RX : in CTRLBUS_RX;
+ BUS_TX : out CTRLBUS_TX;
+
+ --Inputs and Outputs
+ INPUT : in std_logic_vector(INPUTS-1 downto 0);
+ OUTPUT : out std_logic_vector(OUTPUTS-1 downto 0)
+ );
+end entity;
+
+
+
+
+architecture arch of shutdown_logic is
+
+-- Registers with values
+type Array32bit is array(INPUTS-1 downto 0) of std_logic_vector (31 downto 0); -- Register-Type for individuals is 24 times 32 bit deep
+
+
+signal stretch_time : Array32bit:=(others => (others => '0')); -- Register Entries INPUT
+signal max_count : Array32bit:=(others => (others => '0')); -- or individual entity INPUT
+
+
+-- signal reg_individual: std_logic_vector(31 downto 0):=(others => '0');
+signal reg_compare_1: std_logic_vector(31 downto 0):=(others => '0'); -- Register to set max value of simultanious peaks
+signal disableReg_compare: std_logic_vector(31 downto 0):=(others => '0'); -- Disable Register for single channels
+
+
+-- registers for READOUT
+signal current_count: Array32bit:=(others => (others => '0')); -- OUTPUT from indiv to bussystem to log the live values of every channel
+signal individual_alerts: std_logic_vector(31 downto 0):=(others => '0');
+
+-- ON / OFF Switch register 32
+signal register_onoff :std_logic_vector(31 downto 0):=(others => '0');
+
+
+
+-- hand over the signals between entities
+signal in_2_indiv :std_logic_vector(INPUTS-1 downto 0);
+signal indiv_2_comp :std_logic_vector(INPUTS-1 downto 0);
+signal comp_2_out :std_logic_vector(OUTPUTS-1 downto 0);
+
+signal address_i : integer range 0 to 255;
+
+
+
+begin
+
+ address_i <= to_integer(unsigned(BUS_RX.addr(7 downto 0)));
+-- OUTPUT <= comp_2_out;
+ individual_alerts(INPUTS-1 downto 0) <= indiv_2_comp;
+ in_2_indiv <= INPUT;
+-- comp_2_out(1) <= not comp_2_out(0);
+
+
+
+-- PROC_OFFSWITCH : process begin -- Version 1, in sync
+-- wait until rising_edge(CLK);
+-- if register_onoff(0) = '1' then
+-- OUTPUT <= comp_2_out;
+-- else
+-- OUTPUT <= (others => '0');
+-- end if;
+-- end process;
+
+
+PROC_OFFSWITCH : process (comp_2_out) --Version 2 out of sync
+ begin
+ if register_onoff(0) = '1' then
+ OUTPUT <= comp_2_out;
+ else
+ OUTPUT <= (others => '0');
+ end if;
+end process;
+
+
+PROC_REGS : process begin
+ wait until rising_edge(CLK);
+ BUS_TX.ack <= '0';
+ BUS_TX.nack <= '0';
+ BUS_TX.unknown <= '0';
+
+ if BUS_RX.read = '1' then -- READ
+ BUS_TX.ack <= '1';
+ if BUS_RX.addr(11 downto 8) = x"0" then -- Register for individual
+ if address_i < INPUTS then
+ BUS_TX.data <= stretch_time(address_i);
+ else
+ BUS_TX.ack <= '0'; BUS_TX.unknown <= '1';
+ end if;
+ elsif BUS_RX.addr(11 downto 8) = x"1" then
+ if address_i < INPUTS then
+ BUS_TX.data <= max_count(address_i);
+ else
+ BUS_TX.ack <= '0'; BUS_TX.unknown <= '1';
+ end if;
+ elsif BUS_RX.addr(11 downto 8) = x"2" then
+ BUS_TX.data <= reg_compare_1;
+ elsif BUS_RX.addr(11 downto 8) = x"3" then
+ BUS_TX.data <= disableReg_compare;
+ elsif BUS_RX.addr(11 downto 8) = x"4" then
+ if address_i < INPUTS then
+ BUS_TX.data <= current_count(address_i);
+ else
+ BUS_TX.ack <= '0'; BUS_TX.unknown <= '1' ;
+ end if;
+ elsif BUS_RX.addr(11 downto 8) = x"5" then
+ BUS_TX.data <= individual_alerts;
+ elsif BUS_RX.addr(11 downto 8) = x"6" then
+ BUS_TX.data <= register_onoff;
+ else BUS_TX.ack <= '0'; BUS_TX.unknown <= '1';
+ end if;
+
+
+ elsif BUS_RX.write = '1' then --WRITE
+ BUS_TX.ack <= '1';
+ if BUS_RX.addr(11 downto 8) = x"0" then
+ if address_i < INPUTS then
+ stretch_time(address_i) <= BUS_RX.data;
+ else
+ BUS_TX.ack <= '0'; BUS_TX.unknown <= '1';
+ end if;
+ elsif BUS_RX.addr(11 downto 8) =x"1" then
+ if address_i < INPUTS then
+ max_count(address_i) <= BUS_RX.data; -- Write max count values
+ else
+ BUS_TX.ack <= '0'; BUS_TX.unknown <= '1';
+ end if;
+ elsif BUS_RX.addr(11 downto 8) = x"2" then
+ reg_compare_1 <= BUS_RX.data;
+ elsif BUS_RX.addr(11 downto 8) = x"3" then
+ disableReg_compare <= BUS_RX.data;
+ elsif BUS_RX.addr(11 downto 8) = x"6" then -- write the preset Value of ON/OFF in the boards register
+ register_onoff <= BUS_RX.data;
+ else BUS_TX.ack <= '0'; BUS_TX.unknown <= '1';
+ end if;
+ end if;
+
+end process;
+
+
+
+GEN_INDIV : for i in 0 to INPUTS-1 generate
+THE_INDIV: entity work.shutdown_indv
+
+ port map(
+ clk_in => CLK,
+ signal_in => in_2_indiv(i),
+ int_time => stretch_time(i),
+ max_count => max_count(i),
+ processed_signal => indiv_2_comp(i),
+ current_hits_vctr => current_count(i)
+ );
+end generate;
+
+
+
+
+THE_COMPARE: entity work.shutdown_comp
+generic map(
+ INPUTS => INPUTS,
+ OUTPUTS => OUTPUTS
+)
+ port map(
+ clk_in => CLK,
+ signal_in => indiv_2_comp,
+ max_number_reg => reg_compare_1,
+ disable_reg => disableReg_compare,
+ processed_signal => comp_2_out
+ );
+
+
+end architecture;
+
+
+
+
+
+
+
+
+
+
+
add_file -vhdl -lib work "../../trbnet/media_interfaces/ecp3_sfp/serdes_sync_3.vhd"
add_file -vhdl -lib work "../../trbnet/media_interfaces/med_ecp3_sfp_sync.vhd"
+#ShutdownLogic Files
+add_file -vhdl -lib work "../../shutdownlogic/shutdown_logic.vhd"
+add_file -vhdl -lib work "../../shutdownlogic/shutdown_compare.vhd"
+add_file -vhdl -lib work "../../shutdownlogic/shutdown_individual.vhd"
+
#TrbNet Endpoint
add_file -vhdl -lib work "../../trbnet/trb_net16_term_buf.vhd"
add_file -vhdl -lib work "../../trbnet/trb_net_CRC.vhd"
add_file -vhdl -lib work "../../trbnet/trb_net16_api_ipu_streaming.vhd"
+
+
+
+
add_file -vhdl -lib work "./trb3sc_basic.vhd"
#add_file -fpga_constraint "./synplify.fdc"