From: Florian Marx Date: Tue, 30 Mar 2021 19:00:16 +0000 (+0200) Subject: Added the VHDL code of the ShutdownLogic. X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=9ea741c93838f8ca4702c7f02dac64af8048a263;p=trb3sc.git Added the VHDL code of the ShutdownLogic. --- diff --git a/shutdownlogic/code/shutdown_compare.vhd b/shutdownlogic/code/shutdown_compare.vhd new file mode 100644 index 0000000..47794b8 --- /dev/null +++ b/shutdownlogic/code/shutdown_compare.vhd @@ -0,0 +1,92 @@ +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; diff --git a/shutdownlogic/code/shutdown_individual.vhd b/shutdownlogic/code/shutdown_individual.vhd new file mode 100644 index 0000000..6b1028b --- /dev/null +++ b/shutdownlogic/code/shutdown_individual.vhd @@ -0,0 +1,203 @@ +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; + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/shutdownlogic/code/shutdown_logic.vhd b/shutdownlogic/code/shutdown_logic.vhd new file mode 100644 index 0000000..8e0af47 --- /dev/null +++ b/shutdownlogic/code/shutdown_logic.vhd @@ -0,0 +1,200 @@ + 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; + + + + + + + + + + + diff --git a/template/trb3sc_basic.prj b/template/trb3sc_basic.prj index 630d317..5a8cea8 100644 --- a/template/trb3sc_basic.prj +++ b/template/trb3sc_basic.prj @@ -140,6 +140,11 @@ add_file -vhdl -lib work "../../trbnet/media_interfaces/ecp3_sfp/serdes_sync_0.v 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" @@ -238,6 +243,10 @@ add_file -vhdl -lib work "../../trbnet/gbe_trb/ipcores/ecp3/fifo_4kx18x9_wcnt.vh 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"