-- Phobos event selector steered through -- the CAMAC dataway. Started 16.05.04. -- Version 1.2 (ACEX) Copyright I.Tsurin, -- FLNR JINR. -- Modifications to the version 1.0: -- 1. The ADC gate is extended from 6,35 us to 102 us; -- 2. The BDP start delay is extended from 1,5 us to 6,35 us; -- 3. The following signals were swapped: -- Stop_T1: (pin_204) <-> Target (pin_206); -- Stop_T2: (pin_202) <-> GTE_IN (pin_199). -- Modifications to the version 1.1: -- -- 1. Signals "Target", "Stop_T1", "Stop_T2" and -- "GTE_IN" are back to their original layout -- on the front-panel of the CAMAC #1 station; -- 2. Mapping change of the IO signals for -- the new NIM <-> TTL level adapter; -- 3. The pile-up registers for the SPAC_1 and -- PSAC_2 signals are set when more than one -- pulse is registered during the TOF blocking -- interval (KOI gate was the former pile-up -- expectation time) -- 4. The Pile-up bit is added for the target: the -- first target pulse starts the TOF blocking -- interval, during which this bit is set by any -- other pulses. The register is cleared at the -- end of the blocking interval interval, if no -- physical events were registered, otherwise -- its content is kept. -- 5. The neutron gate output is multiplexed: -- when NA(4)F(24) = 'N_Gate OFF', Gate = I_Gate; -- when NA(4)F(26) = 'N_Gate ON', Gate = N_Gate; -- 6. The neutron counter A(6)F(0)/F(2) is added -- to count pulses within a chosen gate. It -- increments continuously for zero gate width. -- 7. The minimum width of the internally generated -- ion gates (by the built-in delay line or by -- the clock counter) is equal to the trigger -- pulse width to let the first signal opening -- this gate by the leading edge, latch itself -- into KOI register by the trailing egde. The -- externally-formed gate has no limitations. -- 8. Fixing of gitter of the trailing edges of -- the timing signals for the TOF-spectrometry: -- the standard (original) pulse width results -- in a correct start-stop sequence for the -- KA-251M TDCs. -- Module functions: -------------------------------------------- -- NA(I)F(0) - read physics data; -- NA(J)F(1) - survey board steering; -- NA(I)F(2) - read and clear physics data; -- NA(X)F(8) - test LAM ('X' - any); -- NA(X)F(10) - test and clear LAM ('X' - any); -- NA(J)F(11) - set steering defaults; -- NA(I)F(16) - overwrite physics; -- NA(J)F(17) - change steerings; -- NA(K)F(24) - disable detector channels and LAM; -- NA(K)F(26) - enable detector channels and LAM; -- NA(K)F(27) - test detector channels; -------------------------------------------- -- Group #1 (I) registers (physics data): -------------------------------------------- -- KOI_REG (RW) A(0)F(0)/F(2)/F(16) - KOI register; -- PIL_REG (RW) A(1)F(0)/F(2)/F(16) - Pile-up register; -- EVT_CNT (R) A(2)F(0)/F(2) - event counter; -- SP1_CNT (R) A(3)F(0)/F(2) - rate counter (left arm); -- SP2_CNT (R) A(4)F(0)/F(2) - rate counter (right arm); -- TAR_CNT (R) A(5)F(0)/F(2) - rate counter (target); -- NEU_CNT (R) A(6)F(0)/F(2) - flux counter (He3 detector) -------------------------------------------- -- Group #2 (J) registers (board steerings): -------------------------------------------- -- IGD_REG (RW) A(0)F(1)/F(17) - collecting time for ions; -- NGD_REG (RW) A(1)F(1)/F(17) - collecting time for neutrons; -- ADC_REG (RW) A(2)F(1)/F(17) - dE integrating time; -- BLK_REG (RW) A(3)F(1)/F(17) - next TOF blocking time; -- BDP_REG (RW) A(4)F(1)/F(17) - BDP start delay; -- LAM_REG (RW) A(5)F(1)/F(17) - LAM assert time; -- ION_REG (RW) A(6)F(1)/F(17) - multiplicity scheme; -- SIN_REG (RW) A(7)F(1)/F(17) - scaling for single events; -------------------------------------------- -- Control (K) registers: -------------------------------------------- -- ENA_LAM (X) A(0)F(24)/F(26) - L1 trigger OFF/ON; -- ENA_CH1 (X) A(1)F(24)/F(26)/F(27) - left PSAC OFF/ON/Test; -- ENA_CH2 (X) A(2)F(24)/F(26)/F(27) - right PSAC OFF/ON/Test; -- ENA_TAR (X) A(3)F(24)/F(26)/F(27) - central PSAC OFF/ON/Test; -- ENA_NEU (X) A(4)F(24)/F(26)/F(27) - Neutron gate OFF/ON/Test; -------------------------------------------- -- Bit assignment of the KOI register: -------------------------------------------- -- Bit_0 Left PSAC; -- Bit_1 Right PSAC; -- Bit_2 Target; -- Bit_3 System bit (not cleared by SYS_RES); -------------------------------------------- -- Bit assignment of the pile-up register: -------------------------------------------- -- Bit_0 Left PSAC; -- Bit_1 Right PSAC; -- Bit_2 Target; -------------------------------------------- -- Bit assignment of the counters: -------------------------------------------- -- Bit_0 ... Bit14 - counter's value (0 to 32767); -- Bit_15 - overflow condition; -------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.numeric_std.all; -- OK. Here the entity starts... -------------------------------------------- entity Selector is port( -- CAMAC signals -------------------------------------------- N_COM: in std_logic; B_COM: in std_logic; Z_COM: in std_logic; C_COM: in std_logic; I_COM: in std_logic; Strobe1: in std_logic; Strobe2: in std_logic; X_RES: out std_logic; Q_RES: out std_logic; L_RES: out std_logic; WRI_DAT: in std_logic_vector(23 downto 0); RDA_DAT: out std_logic_vector(23 downto 0); F_BUS: in std_logic_vector(4 downto 0); A_BUS: in std_logic_vector(3 downto 0); -------------------------------------------- -- Detector signals -------------------------------------------- Target: in std_logic; Stop_T1: in std_logic; Stop_T2: in std_logic; Start_TDC1: out std_logic; Start_TDC2: out std_logic; Stop_TDC1: out std_logic; Stop_TDC2: out std_logic; Clear_TDC1: out std_logic; Clear_TDC2: out std_logic; Start_BDP1: out std_logic; Start_BDP2: out std_logic; Clear_BDP1: out std_logic; Clear_BDP2: out std_logic; Clear_TDC3: out std_logic; Start_DE: out std_logic; Clear_DE: out std_logic; N_Flux: in std_logic; -------------------------------------------- -- Steering signals -------------------------------------------- GTE_IN: in std_logic; GTE_OUT: out std_logic; GTE_CTL: out std_logic; DEL_OUT: out std_logic; DEL_TAP: in std_logic_vector(9 downto 0); -------------------------------------------- -- Indicators -------------------------------------------- LAM_OUT: out std_logic; EVT_LED: out std_logic; BLK_GT1: out std_logic; BLK_GT2: out std_logic; -------------------------------------------- -- Clock frequency -------------------------------------------- Clock: in std_logic ); attribute pinnum: string; attribute pinnum of N_COM: signal is "18"; attribute pinnum of B_COM: signal is "7"; attribute pinnum of Z_COM: signal is "27"; attribute pinnum of C_COM: signal is "16"; attribute pinnum of I_COM: signal is "14"; attribute pinnum of Strobe1: signal is "26"; attribute pinnum of Strobe2: signal is "28"; attribute pinnum of X_RES: signal is "12"; attribute pinnum of Q_RES: signal is "29"; attribute pinnum of L_RES: signal is "24"; attribute pinnum of WRI_DAT: signal is "30,31,36,37,38,39,40,41,44,45,46,47,53,54,55,56,57,58,60,61,62,63,64,65"; attribute pinnum of RDA_DAT: signal is "67,68,69,70,71,73,74,75,83,85,86,87,88,89,90,92,93,94,95,96,97,99,100,101"; attribute pinnum of F_BUS: signal is "8,9,10,11,13"; attribute pinnum of A_BUS: signal is "15,17,19,25"; attribute pinnum of Target: signal is "141"; attribute pinnum of Stop_T1: signal is "140"; attribute pinnum of Stop_T2: signal is "139"; attribute pinnum of Start_BDP1: signal is "204"; attribute pinnum of Start_BDP2: signal is "203"; attribute pinnum of Clear_BDP1: signal is "199"; attribute pinnum of Clear_BDP2: signal is "198"; attribute pinnum of LAM_OUT: signal is "206"; attribute pinnum of EVT_LED: signal is "207"; attribute pinnum of Start_TDC1: signal is "187"; attribute pinnum of Start_TDC2: signal is "149"; attribute pinnum of Stop_TDC1: signal is "148"; attribute pinnum of Stop_TDC2: signal is "147"; attribute pinnum of Start_DE: signal is "144"; attribute pinnum of Clear_TDC1: signal is "191"; attribute pinnum of Clear_TDC2: signal is "190"; attribute pinnum of Clear_DE: signal is "142"; attribute pinnum of Clear_TDC3: signal is "197"; attribute pinnum of GTE_CTL: signal is "196"; attribute pinnum of N_flux: signal is "195"; attribute pinnum of BLK_GT1: signal is "202"; attribute pinnum of BLK_GT2: signal is "200"; attribute pinnum of GTE_IN: signal is "136"; attribute pinnum of GTE_OUT: signal is "143"; attribute pinnum of DEL_OUT: signal is "104"; attribute pinnum of DEL_TAP: signal is "125,121,122,119,120,115,116,113,114,111"; attribute pinnum of Clock: signal is "208"; end; architecture behavior of Selector is -- Start-up variables -------------------------------------------- signal INI_CNT: natural range 0 to 524287; signal DUM_RES: std_logic; signal PWR_ON: std_logic; -------------------------------------------- -- CAMAC variables -------------------------------------------- signal COM_SET: std_logic; signal SEL_SET: std_logic; signal R29_KOI: std_logic; signal R29_PIL: std_logic; signal R29_EVT: std_logic; signal R29_SP1: std_logic; signal R29_SP2: std_logic; signal R29_TAR: std_logic; signal R29_NEU: std_logic; signal KOI_RG0: std_logic; signal KOI_RG1: std_logic; signal KOI_RG2: std_logic; signal KOI_RG3: std_logic; signal ARM: std_logic_vector(1 downto 0); signal PIL_RG0: std_logic; signal PIL_RG1: std_logic; signal PIL_RG2: std_logic; signal IGD_REG: natural range 0 to 127; -- used #7 bit -> 6.35 us; signal NGD_REG: natural range 0 to 2047; -- used #11 bit -> 102 us; signal ADC_REG: natural range 0 to 2047; -- used #11 bit -> 102 us; signal BLK_REG: natural range 0 to 127; -- used #7 bit -> 6.35 us; signal BDP_REG: natural range 0 to 127; -- used #7 bit -> 6.35 us; signal LAM_REG: natural range 0 to 2047; -- used #11 bit -> 102 us; signal ION_REG: natural range 0 to 3; -- #2 bit; signal SIN_REG: natural range 0 to 127; -- #7 bit; signal ENA_LAM: std_logic; signal ENA_CH1: std_logic; signal ENA_CH2: std_logic; signal ENA_TAR: std_logic; signal ENA_NEU: std_logic; -------------------------------------------- -- Physics variables -------------------------------------------- -- TAR_STP - pulse synchronous to the leading edge of the Target signal -- TAR_KOI - pulse synchronous to the trailing edge of the Target signal -- DM1_STP - pulse synchronous to the leading edge of the PSAC_1 signal -- DM1_KOI - pulse synchronous to the trailing edge of the PSAC_1 signal -- DM2_STP - pulse synchronous to the leading edge of the PSAC_2 signal -- DM2_KOI - pulse synchronous to the trailing edge of the PSAC_2 signal signal TAR_STP: std_logic; signal TAR_KOI: std_logic; signal DM1_STP: std_logic; signal DM1_KOI: std_logic; signal DM1_OUT: std_logic; signal DM2_STP: std_logic; signal DM2_KOI: std_logic; signal DM2_OUT: std_logic; signal M1F_CLR: std_logic; signal M2F_CLR: std_logic; signal TAR_CLR: std_logic; signal HIS_KEP: std_logic; signal HIS_RES: std_logic; signal TF_CNT: natural range 0 to 255; signal M1F_CNT: natural range 0 to 255; signal M2F_CNT: natural range 0 to 255; signal BLK_LIM: natural range 0 to 255; signal CHAN_OR: std_logic; signal BACK_OR: std_logic; signal INT_CNT: natural range 0 to 255; signal INT_GTE: std_logic; signal INT_STB: std_logic; signal INT_CLR: std_logic; signal EXT_CNT: natural range 0 to 3; signal EXT_STB: std_logic; signal EXT_CLR: std_logic; signal DEL_CNT: natural range 0 to 3; signal DEL_STB: std_logic; signal DEL_CLR: std_logic; signal SHUT_GT: std_logic; signal ION_GTE: std_logic; signal NEU_GTE: std_logic; signal RDO_CNT: natural range 0 to 4095; signal RDO_LIM: natural range 0 to 4095; signal RDO_CYC: std_logic; signal ION_MUL: natural range 0 to 3; signal CNT_SIN: natural range 0 to 127; signal SIN_DEL: natural range 0 to 127; signal SIN_EVT: std_logic; signal BIN_EVT: std_logic; signal Event_OK: std_logic; signal L1_TRIG: std_logic; signal FST_CLR: std_logic; signal LAM_CLR: std_logic; signal SYS_RES: std_logic; signal RES_FAN: std_logic; signal DET_BSY: std_logic; signal RES_CNT: natural range 0 to 31; signal WRI_KOI: std_logic; signal WRI_PIL: std_logic; signal BDP_CN1: natural range 0 to 255; signal BDP_CN2: natural range 0 to 255; signal BDP_TM1: std_logic; signal BDP_TM2: std_logic; signal BDP_ST1: std_logic; signal BDP_ST2: std_logic; signal ADC_CNT: natural range 0 to 2047; signal ADC_GTE: std_logic; signal LED_CNT: natural range 0 to 131071; signal LAM_IND: std_logic; -------------------------------------------- -- Spark counters -------------------------------------------- signal EVT_CNT: natural range 0 to 32767; signal SP1_CNT: natural range 0 to 32767; signal SP2_CNT: natural range 0 to 32767; signal TAR_CNT: natural range 0 to 32767; signal NEU_CNT: natural range 0 to 32767; signal EVT_OVF: std_logic; signal SP1_OVF: std_logic; signal SP2_OVF: std_logic; signal TAR_OVF: std_logic; signal NEU_OVF: std_logic; -------------------------------------------- -- function declarations -------------------------- -- Data type conversion: -- binary#11 -> natural -------------------------------------------- function BIT11_inv_to_NUM(BIT_ARR: std_logic_vector(10 downto 0)) return natural is variable TEMP: natural range 0 to 2047; begin TEMP:=0; for I in BIT_ARR'range loop TEMP:= TEMP * 2; if (BIT_ARR(I) = '0') then TEMP:= TEMP + 1; else null; end if; end loop; return TEMP; end BIT11_inv_to_NUM; -------------------------------------------- -- Data type conversion: -- binary#7 -> natural -------------------------------------------- function BIT7_inv_to_NUM(BIT_ARR: std_logic_vector(6 downto 0)) return natural is variable TEMP: natural range 0 to 127; begin TEMP:=0; for I in BIT_ARR'range loop TEMP:= TEMP * 2; if (BIT_ARR(I) = '0') then TEMP:= TEMP + 1; else null; end if; end loop; return TEMP; end BIT7_inv_to_NUM; -------------------------------------------- -- Data type conversion: -- binary#2 -> natural -------------------------------------------- function BIT2_inv_to_NUM(BIT_ARR: std_logic_vector(1 downto 0)) return natural is variable TEMP: natural range 0 to 3; begin TEMP:=0; for I in BIT_ARR'range loop TEMP:= TEMP * 2; if (BIT_ARR(I) = '0') then TEMP:= TEMP + 1; else null; end if; end loop; return TEMP; end BIT2_inv_to_NUM; -------------------------------------------- -- SUM_of_ONES_2 is used to count -- the number of PSACs triggered -------------------------------------------- function SUM_of_ONES_2(INP_DAT: std_logic_vector(1 downto 0)) return natural is variable TEMP: natural range 0 to 3; begin TEMP:= 0; for Index in INP_DAT'range loop if (INP_DAT(Index) = '1') then TEMP:= TEMP + 1; end if; end loop; return TEMP; end SUM_of_ONES_2; -------------------------------------------- begin -- Permanent statements -------------------------------------------- DUM_RES <= '0'; ------------------------- ARM(0) <= KOI_RG0; ARM(1) <= KOI_RG1; -------------------------------------------- -- Start-up reset -------------------------------------------- process(DUM_RES, Clock, PWR_ON) begin if (DUM_RES = '1') then INI_CNT <= 0; elsif (Clock'event and Clock = '1') then if (PWR_ON = '1') then INI_CNT <= INI_CNT + 1; else null; end if; end if; end process; ------------------------- process(DUM_RES, Clock, INI_CNT) begin if (DUM_RES = '1') then PWR_ON <= '1'; elsif (Clock'event and Clock = '0') then if (INI_CNT = 524287) then PWR_ON <= '0'; else PWR_ON <= '1'; end if; end if; end process; -------------------------------------------- -- Common CAMAC reset -- (clear registers group #1) -- (init registers group #2) -------------------------------------------- process(PWR_ON, Z_COM, Strobe2) begin if (PWR_ON = '1' or Z_COM = '1') then COM_SET <= '0'; elsif (Strobe2'event and Strobe2 = '0') then COM_SET <= '1'; end if; end process; -------------------------------------------- -- Selective CAMAC reset -- (clear registers group #1) -- (init registers group #2) -------------------------------------------- process(PWR_ON, C_COM, Strobe2) begin if (PWR_ON = '1' or C_COM = '1') then SEL_SET <= '0'; elsif (Strobe2'event and Strobe2 = '0') then SEL_SET <= '1'; end if; end process; -------------------------------------------- -- Reset group #1 by NA(0)F(2)S(2) or NA(0)F(9)S(2) -------------------------------------------- process(PWR_ON, Z_COM, N_COM, Strobe2, F_BUS, A_BUS) begin if (PWR_ON = '1' or Z_COM = '0' or N_COM = '1') then R29_KOI <= '0'; elsif (Strobe2'event and Strobe2 = '0') then if ((F_BUS = "11101" or F_BUS = "10110") and A_BUS = "1111") then R29_KOI <= '1'; else null; end if; end if; end process; -------------------------------------------- -- Reset group #1 by NA(1)F(2)S(2) or NA(1)F(9)S(2) -------------------------------------------- process(PWR_ON, Z_COM, N_COM, Strobe2, F_BUS, A_BUS) begin if (PWR_ON = '1' or Z_COM = '0' or N_COM = '1') then R29_PIL <= '0'; elsif (Strobe2'event and Strobe2 = '0') then if ((F_BUS = "11101" or F_BUS = "10110") and A_BUS = "1110") then R29_PIL <= '1'; else null; end if; end if; end process; -------------------------------------------- -- Reset group #1 by NA(2)F(2)S(2) -------------------------------------------- process(PWR_ON, Z_COM, N_COM, Strobe2, F_BUS, A_BUS) begin if (PWR_ON = '1' or Z_COM = '0' or N_COM = '1') then R29_EVT <= '0'; elsif (Strobe2'event and Strobe2 = '0') then if (F_BUS = "11101" and A_BUS = "1101") then R29_EVT <= '1'; else null; end if; end if; end process; -------------------------------------------- -- Reset group #1 by NA(3)F(2)S(2) -------------------------------------------- process(PWR_ON, Z_COM, N_COM, Strobe2, F_BUS, A_BUS) begin if (PWR_ON = '1' or Z_COM = '0' or N_COM = '1') then R29_SP1 <= '0'; elsif (Strobe2'event and Strobe2 = '0') then if (F_BUS = "11101" and A_BUS = "1100") then R29_SP1 <= '1'; else null; end if; end if; end process; -------------------------------------------- -- Reset group #1 by NA(4)F(2)S(2) -------------------------------------------- process(PWR_ON, Z_COM, N_COM, Strobe2, F_BUS, A_BUS) begin if (PWR_ON = '1' or Z_COM = '0' or N_COM = '1') then R29_SP2 <= '0'; elsif (Strobe2'event and Strobe2 = '0') then if (F_BUS = "11101" and A_BUS = "1011") then R29_SP2 <= '1'; else null; end if; end if; end process; -------------------------------------------- -- Reset group #1 by NA(5)F(2)S(2) -------------------------------------------- process(PWR_ON, Z_COM, N_COM, Strobe2, F_BUS, A_BUS) begin if (PWR_ON = '1' or Z_COM = '0' or N_COM = '1') then R29_TAR <= '0'; elsif (Strobe2'event and Strobe2 = '0') then if (F_BUS = "11101" and A_BUS = "1010") then R29_TAR <= '1'; else null; end if; end if; end process; -------------------------------------------- -- Reset group #1 by NA(6)F(2)S(2) -------------------------------------------- process(PWR_ON, Z_COM, N_COM, Strobe2, F_BUS, A_BUS) begin if (PWR_ON = '1' or Z_COM = '0' or N_COM = '1') then R29_NEU <= '0'; elsif (Strobe2'event and Strobe2 = '0') then if (F_BUS = "11101" and A_BUS = "1001") then R29_NEU <= '1'; else null; end if; end if; end process; -------------------------------------------- -- Reset LAM by NA(X)F(10)S(2) -------------------------------------------- process(PWR_ON, Z_COM, N_COM, Strobe2, F_BUS, A_BUS) begin if (PWR_ON = '1' or Z_COM = '0' or N_COM = '1') then LAM_CLR <= '0'; elsif (Strobe2'event and Strobe2 = '0') then if (F_BUS = "10101") then LAM_CLR <= '1'; else null; end if; end if; end process; -------------------------------------------- -- Write group #2 registers (board steering) -- Registers are set to default values: -- selected by a command NA(I)F(11)S(1); -- all by a command ZS(2); -- all by a command CS(2); -- all after the power ON; -- Registers are overwritten -- by a command NA(I)F(17)S(1); -------------------------------------------- process(PWR_ON, COM_SET, SEL_SET, Strobe1, N_COM, F_BUS, A_BUS, WRI_DAT) begin if (PWR_ON = '1' or COM_SET = '1' or SEL_SET = '1') then IGD_REG <= 11; NGD_REG <= 2000; ADC_REG <= 200; BLK_REG <= 100; BDP_REG <= 40; LAM_REG <= 400; ION_REG <= 3; SIN_REG <= 100; elsif (Strobe1'event and Strobe1 = '0') then if (N_COM = '0' and F_BUS = "10100") then if (A_BUS = "1111") then IGD_REG <= 11; elsif (A_BUS = "1110") then NGD_REG <= 2000; elsif (A_BUS = "1101") then ADC_REG <= 200; elsif (A_BUS = "1100") then BLK_REG <= 100; elsif (A_BUS = "1011") then BDP_REG <= 40; elsif (A_BUS = "1010") then LAM_REG <= 400; elsif (A_BUS = "1001") then ION_REG <= 3; elsif (A_BUS = "1000") then SIN_REG <= 100; else null; end if; elsif (N_COM = '0' and F_BUS = "01110") then if (A_BUS = "1111") then IGD_REG <= BIT7_inv_to_NUM(WRI_DAT(6 downto 0)); elsif (A_BUS = "1110") then NGD_REG <= BIT11_inv_to_NUM(WRI_DAT(10 downto 0)); elsif (A_BUS = "1101") then ADC_REG <= BIT11_inv_to_NUM(WRI_DAT(10 downto 0)); elsif (A_BUS = "1100") then BLK_REG <= BIT7_inv_to_NUM(WRI_DAT(6 downto 0)); elsif (A_BUS = "1011") then BDP_REG <= BIT7_inv_to_NUM(WRI_DAT(6 downto 0)); elsif (A_BUS = "1010") then LAM_REG <= BIT11_inv_to_NUM(WRI_DAT(10 downto 0)); elsif (A_BUS = "1001") then ION_REG <= BIT2_inv_to_NUM(WRI_DAT(1 downto 0)); elsif (A_BUS = "1000") then SIN_REG <= BIT7_inv_to_NUM(WRI_DAT(6 downto 0)); else null; end if; else null; end if; end if; end process; -------------------------------------------- -- Write group #3 registers (detector control) -- Registers are set to default values: -- all by a command ZS(2); -- all after the power ON; -- Registers are overwritten -- by commands NA(I)F(24)S(1) -- and NA(I)F(26)S(1); -------------------------------------------- process(PWR_ON, COM_SET, Strobe1, N_COM, F_BUS, A_BUS) begin if (PWR_ON = '1' or COM_SET = '1') then ENA_LAM <= '1'; ENA_CH1 <= '1'; ENA_CH2 <= '1'; ENA_TAR <= '1'; ENA_NEU <= '1'; elsif (Strobe1'event and Strobe1 = '0') then if (N_COM = '0' and F_BUS = "00111") then if (A_BUS = "1111") then ENA_LAM <= '0'; elsif (A_BUS = "1110") then ENA_CH1 <= '0'; elsif (A_BUS = "1101") then ENA_CH2 <= '0'; elsif (A_BUS = "1100") then ENA_TAR <= '0'; elsif (A_BUS = "1011") then ENA_NEU <= '0'; else null; end if; elsif (N_COM = '0' and F_BUS = "00101") then if (A_BUS = "1111") then ENA_LAM <= '1'; elsif (A_BUS = "1110") then ENA_CH1 <= '1'; elsif (A_BUS = "1101") then ENA_CH2 <= '1'; elsif (A_BUS = "1100") then ENA_TAR <= '1'; elsif (A_BUS = "1011") then ENA_NEU <= '1'; else null; end if; else null; end if; end if; end process; -------------------------------------------- -- Read registers -------------------------------------------- process(PWR_ON, Z_COM, N_COM, F_BUS, A_BUS, KOI_RG0, KOI_RG1, KOI_RG2, KOI_RG3, PIL_RG0, PIL_RG1, PIL_RG2, EVT_OVF, EVT_CNT, SP1_OVF, SP1_CNT, SP2_OVF, SP2_CNT, TAR_OVF, TAR_CNT, NEU_OVF, NEU_CNT, IGD_REG, NGD_REG, ADC_REG, BLK_REG, BDP_REG, LAM_REG, ION_REG, SIN_REG) begin if (PWR_ON = '1' or Z_COM = '0' or N_COM = '1') then RDA_DAT <= (others => 'Z'); -- group #1 registers -------------------------------------------- elsif (F_BUS = "11111" or F_BUS = "11101") then if (A_BUS = "1111") then RDA_DAT(23 downto 4) <= (others => 'Z'); RDA_DAT(3) <= not KOI_RG3; RDA_DAT(2) <= not KOI_RG2; RDA_DAT(1) <= not KOI_RG1; RDA_DAT(0) <= not KOI_RG0; elsif (A_BUS = "1110") then RDA_DAT(23 downto 3) <= (others => 'Z'); RDA_DAT(2) <= not PIL_RG2; RDA_DAT(1) <= not PIL_RG1; RDA_DAT(0) <= not PIL_RG0; elsif (A_BUS = "1101") then RDA_DAT(23 downto 16) <= (others => 'Z'); RDA_DAT(15) <= not EVT_OVF; RDA_DAT(14 downto 0) <= conv_std_logic_vector((32767 - EVT_CNT), 15); elsif (A_BUS = "1100") then RDA_DAT(23 downto 16) <= (others => 'Z'); RDA_DAT(15) <= not SP1_OVF; RDA_DAT(14 downto 0) <= conv_std_logic_vector((32767 - SP1_CNT), 15); elsif (A_BUS = "1011") then RDA_DAT(23 downto 16) <= (others => 'Z'); RDA_DAT(15) <= not SP2_OVF; RDA_DAT(14 downto 0) <= conv_std_logic_vector((32767 - SP2_CNT), 15); elsif (A_BUS = "1010") then RDA_DAT(23 downto 16) <= (others => 'Z'); RDA_DAT(15) <= not TAR_OVF; RDA_DAT(14 downto 0) <= conv_std_logic_vector((32767 - TAR_CNT), 15); elsif (A_BUS = "1001") then RDA_DAT(23 downto 16) <= (others => 'Z'); RDA_DAT(15) <= not NEU_OVF; RDA_DAT(14 downto 0) <= conv_std_logic_vector((32767 - NEU_CNT), 15); else RDA_DAT <= (others => 'Z'); end if; -- group #2 registers -------------------------------------------- elsif (F_BUS = "11110") then if (A_BUS = "1111") then RDA_DAT(23 downto 7) <= (others => 'Z'); RDA_DAT(6 downto 0) <= conv_std_logic_vector((127 - IGD_REG), 7); elsif (A_BUS = "1110") then RDA_DAT(23 downto 11) <= (others => 'Z'); RDA_DAT(10 downto 0) <= conv_std_logic_vector((2047 - NGD_REG), 11); elsif (A_BUS = "1101") then RDA_DAT(23 downto 11) <= (others => 'Z'); RDA_DAT(10 downto 0) <= conv_std_logic_vector((2047 - ADC_REG), 11); elsif (A_BUS = "1100") then RDA_DAT(23 downto 7) <= (others => 'Z'); RDA_DAT(6 downto 0) <= conv_std_logic_vector((127 - BLK_REG), 7); elsif (A_BUS = "1011") then RDA_DAT(23 downto 7) <= (others => 'Z'); RDA_DAT(6 downto 0) <= conv_std_logic_vector((127 - BDP_REG), 7); elsif (A_BUS = "1010") then RDA_DAT(23 downto 11) <= (others => 'Z'); RDA_DAT(10 downto 0) <= conv_std_logic_vector((2047 - LAM_REG), 11); elsif (A_BUS = "1001") then RDA_DAT(23 downto 2) <= (others => 'Z'); RDA_DAT(1 downto 0) <= conv_std_logic_vector((3 - ION_REG), 2); elsif (A_BUS = "1000") then RDA_DAT(23 downto 7) <= (others => 'Z'); RDA_DAT(6 downto 0) <= conv_std_logic_vector((127 - SIN_REG), 7); else RDA_DAT <= (others => 'Z'); end if; else RDA_DAT <= (others => 'Z'); end if; end process; -------------------------------------------- -- Genarating X - command response -- NA(I)F(0) - read physics data; -- NA(I)F(2) - read and clear physics data; -- NA(I)F(9) - clear physics data; -- NA(I)F(16) - overwrite physics; -- NA(J)F(1) - survey board steering; -- NA(J)F(11) - set steering defaults; -- NA(J)F(17) - change steerings; -- NA(K)F(24) - disable detector channels and LAM; -- NA(K)F(26) - enable detector channels and LAM; -- NA(K)F(27) - test detector channels; -- NA(X)F(8) - test LAM ('X' - any); -- NA(X)F(10) - test and clear LAM ('X' - any); -------------------------------------------- process(PWR_ON, Z_COM, N_COM, F_BUS, A_BUS) begin if (PWR_ON = '0' and Z_COM = '1' and N_COM = '0') then -- overwrite or read group #1 registers -------------------------------------------- if (F_BUS = "11111" or F_BUS = "11101") then if (A_BUS = "1111") then X_RES <= '0'; elsif (A_BUS = "1110") then X_RES <= '0'; elsif (A_BUS = "1101") then X_RES <= '0'; elsif (A_BUS = "1100") then X_RES <= '0'; elsif (A_BUS = "1011") then X_RES <= '0'; elsif (A_BUS = "1010") then X_RES <= '0'; elsif (A_BUS = "1001") then X_RES <= '0'; else X_RES <= 'Z'; end if; elsif (F_BUS = "10110" or F_BUS = "01111") then if (A_BUS = "1111") then X_RES <= '0'; elsif (A_BUS = "1110") then X_RES <= '0'; else X_RES <= 'Z'; end if; -- overwrite or read group #2 registers -------------------------------------------- elsif (F_BUS = "11110" or F_BUS = "10100" or F_BUS = "01110") then if (A_BUS = "1111") then X_RES <= '0'; elsif (A_BUS = "1110") then X_RES <= '0'; elsif (A_BUS = "1101") then X_RES <= '0'; elsif (A_BUS = "1100") then X_RES <= '0'; elsif (A_BUS = "1011") then X_RES <= '0'; elsif (A_BUS = "1010") then X_RES <= '0'; elsif (A_BUS = "1001") then X_RES <= '0'; elsif (A_BUS = "1000") then X_RES <= '0'; else X_RES <= 'Z'; end if; -- disable or enable group #3 registers -------------------------------------------- elsif (F_BUS = "00111" or F_BUS = "00101") then if (A_BUS = "1111") then X_RES <= '0'; elsif (A_BUS = "1110") then X_RES <= '0'; elsif (A_BUS = "1101") then X_RES <= '0'; elsif (A_BUS = "1100") then X_RES <= '0'; elsif (A_BUS = "1011") then X_RES <= '0'; else X_RES <= 'Z'; end if; -- test group #3 registers except LAM -------------------------------------------- elsif (F_BUS = "00100") then if (A_BUS = "1110") then X_RES <= '0'; elsif (A_BUS = "1101") then X_RES <= '0'; elsif (A_BUS = "1100") then X_RES <= '0'; elsif (A_BUS = "1011") then X_RES <= '0'; else X_RES <= 'Z'; end if; -- test or clear LAM -------------------------------------------- elsif (F_BUS = "10111" or F_BUS = "10101") then X_RES <= '0'; else X_RES <= 'Z'; end if; else X_RES <= 'Z'; end if; end process; -------------------------------------------- -- Genarating Q - status response -------------------------------------------- process(PWR_ON, Z_COM, N_COM, F_BUS, L1_TRIG, A_BUS, ENA_CH1, ENA_CH2, ENA_TAR, ENA_NEU) begin if (PWR_ON = '0' and Z_COM = '1' and N_COM = '0') then if (F_BUS = "10111" or F_BUS = "10101") then Q_RES <= not L1_TRIG; elsif (F_BUS = "00100") then if (A_BUS = "1110") then Q_RES <= not ENA_CH1; elsif (A_BUS = "1101") then Q_RES <= not ENA_CH2; elsif (A_BUS = "1100") then Q_RES <= not ENA_TAR; elsif (A_BUS = "1011") then Q_RES <= not ENA_NEU; else Q_RES <= 'Z'; end if; else Q_RES <= 'Z'; end if; else Q_RES <= 'Z'; end if; end process; -------------------------------------------- -------------------------------------------- -- minimum channel blocking time = 200 ns -- (blocking gate itself plus clear pulse) -------------------------------------------- process(BLK_REG) begin case BLK_REG is when 0 to 2 => BLK_LIM <= 3; when others => BLK_LIM <= BLK_REG; end case; end process; -------------------------------------------- -- Latching the leading edge of the target signal -------------------------------------------- process(PWR_ON, COM_SET, SYS_RES, ENA_TAR, TAR_CLR, Target, I_COM) begin if (PWR_ON = '1' or COM_SET = '1' or SYS_RES = '1' or ENA_TAR = '0' or TAR_CLR = '1') then TAR_STP <= '0'; elsif (Target'event and Target = '1') then if (I_COM = '1') then TAR_STP <= '1'; else null; end if; end if; end process; -------------------------------------------- -- Latching the trailing edge of the target signal -------------------------------------------- process(PWR_ON, COM_SET, SYS_RES, ENA_TAR, TAR_CLR, Target, I_COM) begin if (PWR_ON = '1' or COM_SET = '1' or SYS_RES = '1' or ENA_TAR = '0' or TAR_CLR = '1') then TAR_KOI <= '0'; elsif (Target'event and Target = '0') then if (I_COM = '1') then TAR_KOI <= '1'; else null; end if; end if; end process; -------------------------------------------- -- Extending the leading target pulse -------------------------------------------- process(PWR_ON, COM_SET, Clock, TAR_STP) begin if (PWR_ON = '1' or COM_SET = '1') then TF_CNT <= 0; elsif (Clock'event and Clock = '1') then if (TAR_STP = '1') then TF_CNT <= TF_CNT + 1; else TF_CNT <= 0; end if; end if; end process; -------------------------------------------- -- Synchronizing the leading target -- pulse to the clock frequency -------------------------------------------- process(PWR_ON, COM_SET, Clock, TF_CNT, BLK_LIM) begin if (PWR_ON = '1' or COM_SET = '1') then TAR_CLR <= '0'; elsif (Clock'event and Clock = '0') then if (TF_CNT = BLK_LIM) then TAR_CLR <= '1'; else TAR_CLR <= '0'; end if; end if; end process; -------------------------------------------- -- Latching the leading edge of the PSAC_1 signal -------------------------------------------- process(PWR_ON, COM_SET, SYS_RES, ENA_CH1, M1F_CLR, Stop_T1, I_COM, DET_BSY) begin if (PWR_ON = '1' or COM_SET = '1' or SYS_RES = '1' or ENA_CH1 = '0' or M1F_CLR = '1') then DM1_STP <= '0'; elsif (Stop_T1'event and Stop_T1 = '1') then if (I_COM = '1' and DET_BSY = '0') then DM1_STP <= '1'; else null; end if; end if; end process; -------------------------------------------- -- Latching the trailing edge of the PSAC_1 signal -------------------------------------------- process(PWR_ON, COM_SET, SYS_RES, ENA_CH1, M1F_CLR, Stop_T1, I_COM, DET_BSY) begin if (PWR_ON = '1' or COM_SET = '1' or SYS_RES = '1' or ENA_CH1 = '0' or M1F_CLR = '1') then DM1_KOI <= '0'; elsif (Stop_T1'event and Stop_T1 = '0') then if (I_COM = '1' and DET_BSY = '0') then DM1_KOI <= '1'; else null; end if; end if; end process; -------------------------------------------- -- Extending the leading PSAC_1 pulse -------------------------------------------- process(PWR_ON, COM_SET, Clock, DM1_STP) begin if (PWR_ON = '1' or COM_SET = '1') then M1F_CNT <= 0; elsif (Clock'event and Clock = '1') then if (DM1_STP = '1') then M1F_CNT <= M1F_CNT + 1; else M1F_CNT <= 0; end if; end if; end process; -------------------------------------------- -- Synchronizing the leading PSAC_1 -- pulse to the clock frequency -------------------------------------------- process(PWR_ON, COM_SET, Clock, M1F_CNT, BLK_LIM) begin if (PWR_ON = '1' or COM_SET = '1') then M1F_CLR <= '0'; elsif (Clock'event and Clock = '0') then if (M1F_CNT = BLK_LIM) then M1F_CLR <= '1'; else M1F_CLR <= '0'; end if; end if; end process; -------------------------------------------- -- Latching the leading edge of the PSAC_2 signal -------------------------------------------- process(PWR_ON, COM_SET, SYS_RES, ENA_CH2, M2F_CLR, Stop_T2, I_COM, DET_BSY) begin if (PWR_ON = '1' or COM_SET = '1' or SYS_RES = '1' or ENA_CH2 = '0' or M2F_CLR = '1') then DM2_STP <= '0'; elsif (Stop_T2'event and Stop_T2 = '1') then if (I_COM = '1' and DET_BSY = '0') then DM2_STP <= '1'; else null; end if; end if; end process; -------------------------------------------- -- Latching the trailing edge of the PSAC_2 signal -------------------------------------------- process(PWR_ON, COM_SET, SYS_RES, ENA_CH2, M2F_CLR, Stop_T2, I_COM, DET_BSY) begin if (PWR_ON = '1' or COM_SET = '1' or SYS_RES = '1' or ENA_CH2 = '0' or M2F_CLR = '1') then DM2_KOI <= '0'; elsif (Stop_T2'event and Stop_T2 = '0') then if (I_COM = '1' and DET_BSY = '0') then DM2_KOI <= '1'; else null; end if; end if; end process; -------------------------------------------- -- Extending the leading PSAC_2 pulse -------------------------------------------- process(PWR_ON, COM_SET, Clock, DM2_STP) begin if (PWR_ON = '1' or COM_SET = '1') then M2F_CNT <= 0; elsif (Clock'event and Clock = '1') then if (DM2_STP = '1') then M2F_CNT <= M2F_CNT + 1; else M2F_CNT <= 0; end if; end if; end process; -------------------------------------------- -- Synchronizing the leading PSAC_2 -- pulse to the clock frequency -------------------------------------------- process(PWR_ON, COM_SET, Clock, M2F_CNT, BLK_LIM) begin if (PWR_ON = '1' or COM_SET = '1') then M2F_CLR <= '0'; elsif (Clock'event and Clock = '0') then if (M2F_CNT = BLK_LIM) then M2F_CLR <= '1'; else M2F_CLR <= '0'; end if; end if; end process; -------------------------------------------- -- logical OR of all channels ------------------------------------------- CHAN_OR <= DM1_STP or DM2_STP; BACK_OR <= DM1_KOI or DM2_KOI; ------------------------------------------- -- Forming the ion collection gate -------------------------------------------- process(PWR_ON, COM_SET, SHUT_GT, CHAN_OR) begin if (PWR_ON = '1' or COM_SET = '1' or SHUT_GT = '1') then ION_GTE <= '0'; elsif (CHAN_OR'event and CHAN_OR = '1') then ION_GTE <= '1'; end if; end process; -------------------------------------------- -- Select a source to shut down the ion gate ------------------------------------------- process(IGD_REG, GTE_IN, DEL_TAP, INT_STB) begin case IGD_REG is when 0 => SHUT_GT <= GTE_IN; when 1 => SHUT_GT <= DEL_TAP(0); when 2 => SHUT_GT <= DEL_TAP(1); when 3 => SHUT_GT <= DEL_TAP(2); when 4 => SHUT_GT <= DEL_TAP(3); when 5 => SHUT_GT <= DEL_TAP(4); when 6 => SHUT_GT <= DEL_TAP(5); when 7 => SHUT_GT <= DEL_TAP(6); when 8 => SHUT_GT <= DEL_TAP(7); when 9 => SHUT_GT <= DEL_TAP(8); when 10 => SHUT_GT <= DEL_TAP(9); when others => SHUT_GT <= INT_STB; end case; end process; ------------------------------------------- -- Start an external strobe to close the -- ion gate -------------------------------------------- process(PWR_ON, COM_SET, EXT_CLR, CHAN_OR) begin if (PWR_ON = '1' or COM_SET = '1' or EXT_CLR = '1') then EXT_STB <= '0'; elsif (CHAN_OR'event and CHAN_OR = '1') then EXT_STB <= '1'; end if; end process; -------------------------------------------- -- External strobe counter -------------------------------------------- process(PWR_ON, COM_SET, Clock, EXT_STB) begin if (PWR_ON = '1' or COM_SET = '1') then EXT_CNT <= 0; elsif (Clock'event and Clock = '1') then if (EXT_STB = '1') then EXT_CNT <= EXT_CNT + 1; else EXT_CNT <= 0; end if; end if; end process; -------------------------------------------- -- Finishing the external strobe -------------------------------------------- process(PWR_ON, COM_SET, Clock, EXT_CNT) begin if (PWR_ON = '1' or COM_SET = '1') then EXT_CLR <= '0'; elsif (Clock'event and Clock = '0') then if (EXT_CNT = 1) then EXT_CLR <= '1'; else EXT_CLR <= '0'; end if; end if; end process; -------------------------------------------- -- Start a delay line strobe to close the -- ion gate -------------------------------------------- process(PWR_ON, COM_SET, DEL_CLR, BACK_OR) begin if (PWR_ON = '1' or COM_SET = '1' or DEL_CLR = '1') then DEL_STB <= '0'; elsif (BACK_OR'event and BACK_OR = '1') then DEL_STB <= '1'; end if; end process; -------------------------------------------- -- Delay line strobe counter -------------------------------------------- process(PWR_ON, COM_SET, Clock, DEL_STB) begin if (PWR_ON = '1' or COM_SET = '1') then DEL_CNT <= 0; elsif (Clock'event and Clock = '1') then if (DEL_STB = '1') then DEL_CNT <= DEL_CNT + 1; else DEL_CNT <= 0; end if; end if; end process; -------------------------------------------- -- Finishing the delay line strobe -------------------------------------------- process(PWR_ON, COM_SET, Clock, DEL_CNT) begin if (PWR_ON = '1' or COM_SET = '1') then DEL_CLR <= '0'; elsif (Clock'event and Clock = '0') then if (DEL_CNT = 3) then DEL_CLR <= '1'; else DEL_CLR <= '0'; end if; end if; end process; -------------------------------------------- -- Start an internal gate -------------------------------------------- process(PWR_ON, COM_SET, SYS_RES, INT_CLR, BACK_OR) begin if (PWR_ON = '1' or COM_SET = '1' or SYS_RES = '1' or INT_CLR = '1') then INT_GTE <= '0'; elsif (BACK_OR'event and BACK_OR = '1') then INT_GTE <= '1'; end if; end process; -------------------------------------------- -- Internal gate counter -------------------------------------------- process(PWR_ON, COM_SET, Clock, INT_GTE) begin if (PWR_ON = '1' or COM_SET = '1') then INT_CNT <= 0; elsif (Clock'event and Clock = '1') then if (INT_GTE = '1') then INT_CNT <= INT_CNT + 1; else INT_CNT <= 0; end if; end if; end process; -------------------------------------------- -- Stop the internal gate -------------------------------------------- process(PWR_ON, COM_SET, Clock, INT_CNT, IGD_REG) begin if (PWR_ON = '1' or COM_SET = '1') then INT_CLR <= '0'; elsif (Clock'event and Clock = '0') then if (INT_CNT = IGD_REG + 2) then INT_CLR <= '1'; else INT_CLR <= '0'; end if; end if; end process; -------------------------------------------- -- Internal strobe to close the ion gate -------------------------------------------- process(PWR_ON, COM_SET, Clock, INT_CNT, IGD_REG) begin if (PWR_ON = '1' or COM_SET = '1') then INT_STB <= '0'; elsif (Clock'event and Clock = '0') then if (INT_CNT = IGD_REG + 2) then INT_STB <= '0'; elsif (INT_CNT = IGD_REG) then INT_STB <= '1'; else null; end if; end if; end process; -------------------------------------------- -- Scaler for single events -------------------------------------------- ION_MUL <= SUM_of_ONES_2(ARM(1 downto 0)); -------------------------- process(PWR_ON, COM_SET, SHUT_GT, SIN_REG, SIN_DEL, ION_MUL) begin if (PWR_ON = '1' or COM_SET = '1') then CNT_SIN <= 0; elsif (SHUT_GT'event and SHUT_GT = '1') then if (ION_MUL = 1) then if (SIN_REG = 0 or SIN_REG = SIN_DEL) then CNT_SIN <= 0; else CNT_SIN <= CNT_SIN + 1; end if; else null; end if; end if; end process; -------------------------------------------- -- Begin the new scaler's cycle -------------------------------------------- process(PWR_ON, COM_SET, SHUT_GT, CNT_SIN) begin if (PWR_ON = '1' or COM_SET = '1') then SIN_DEL <= 0; elsif (SHUT_GT'event and SHUT_GT = '0') then SIN_DEL <= CNT_SIN; end if; end process; -------------------------------------------- -- Single event validation -------------------------------------------- process(ION_MUL, SIN_REG, CNT_SIN) begin if (ION_MUL = 1 and SIN_REG = CNT_SIN) then SIN_EVT <= '1'; else SIN_EVT <= '0'; end if; end process; -------------------------------------------- -- Binary event validation -------------------------------------------- process(ION_MUL) begin if (ION_MUL = 2) then BIN_EVT <= '1'; else BIN_EVT <= '0'; end if; end process; -------------------------------------------- -- Majority scheme -------------------------------------------- process(PWR_ON, COM_SET, SHUT_GT, ION_REG, SIN_EVT, BIN_EVT) begin if (PWR_ON = '1' or COM_SET = '1') then Event_OK <= '0'; elsif (SHUT_GT'event and SHUT_GT = '0') then case ION_REG is when 1 => Event_OK <= SIN_EVT; when 2 => Event_OK <= BIN_EVT; when 3 => Event_OK <= SIN_EVT or BIN_EVT; when others => Event_OK <= '0'; end case; end if; end process; -------------------------------------------- -- Readout counter limits -------------------------------------------- process(Event_OK, ENA_NEU, LAM_REG, NGD_REG) begin if (Event_OK = '1') then if (ENA_NEU = '1' and LAM_REG <= NGD_REG) then RDO_LIM <= NGD_REG + 2; else RDO_LIM <= LAM_REG + 1; end if; else RDO_LIM <= 3; end if; end process; -------------------------------------------- -- Readout cycle -------------------------------------------- process(PWR_ON, COM_SET, Clock, RDO_CNT) begin if (PWR_ON = '1' or COM_SET = '1') then RDO_CYC <= '0'; elsif (Clock'event and Clock = '0') then if (RDO_CNT = RDO_LIM + 1) then RDO_CYC <= '0'; else RDO_CYC <= '1'; end if; end if; end process; -------------------------------------------- -- Readout counter -------------------------------------------- process(PWR_ON, COM_SET, Clock, SHUT_GT, RDO_CYC) begin if (PWR_ON = '1' or COM_SET = '1') then RDO_CNT <= 0; elsif (Clock'event and Clock = '1') then if (SHUT_GT = '1') then RDO_CNT <= 0; elsif (RDO_CYC = '1') then RDO_CNT <= RDO_CNT + 1; else null; end if; end if; end process; -------------------------------------------- -- Event trigger (LAM) -------------------------------------------- process(PWR_ON, COM_SET, LAM_CLR, Clock, Event_OK, ENA_LAM, RDO_CNT, RDO_LIM) begin if (PWR_ON = '1' or COM_SET = '1' or LAM_CLR = '1') then L1_TRIG <= '0'; elsif (Clock'event and Clock = '0') then if (Event_OK = '1' and ENA_LAM = '1' and RDO_CNT = RDO_LIM) then L1_TRIG <= '1'; else null; end if; end if; end process; -------------------------------------------- -- Fast clear pulse -------------------------------------------- process(PWR_ON, COM_SET, Clock, Event_OK, RDO_CNT) begin if (PWR_ON = '1' or COM_SET = '1') then FST_CLR <= '0'; elsif (Clock'event and Clock = '0') then if (Event_OK = '0') then if (RDO_CNT = 2) then FST_CLR <= '1'; elsif (RDO_CNT = 3) then FST_CLR <= '0'; else null; end if; end if; end if; end process; -------------------------------------------- -- Reset DAQ and clear LAM -------------------------------------------- process(PWR_ON, COM_SET, Clock, FST_CLR, LAM_CLR, RES_CNT) begin if (PWR_ON = '1' or COM_SET = '1') then SYS_RES <= '0'; RES_FAN <= '0'; elsif (Clock'event and Clock = '1') then if (FST_CLR = '1' or LAM_CLR = '1') then SYS_RES <= '1'; RES_FAN <= '1'; elsif (RES_CNT = 31) then SYS_RES <= '0'; RES_FAN <= '0'; else null; end if; end if; end process; -------------------------------------------- -- Reset width counter -------------------------------------------- process(PWR_ON, COM_SET, Clock, SYS_RES) begin if (PWR_ON = '1' or COM_SET = '1') then RES_CNT <= 0; elsif (Clock'event and Clock = '0') then if (SYS_RES = '1') then RES_CNT <= RES_CNT + 1; else RES_CNT <= 0; end if; end if; end process; -------------------------------------------- -- Detector busy status: -------------------------------------------- process(PWR_ON, COM_SET, SYS_RES, SHUT_GT) begin if (PWR_ON = '1' or COM_SET = '1' or SYS_RES = '1') then DET_BSY <= '0'; elsif (SHUT_GT'event and SHUT_GT = '1') then DET_BSY <= '1'; end if; end process; -------------------------------------------- -- Group #1 registers write enable -------------------------------------------- process(PWR_ON, Z_COM, N_COM, F_BUS, Strobe1, A_BUS) begin if (PWR_ON = '1' or Z_COM = '0' or N_COM = '1') then WRI_KOI <= '0'; WRI_PIL <= '0'; elsif (F_BUS = "01111" and Strobe1 = '0') then if (A_BUS = "1111") then WRI_KOI <= '1'; WRI_PIL <= '0'; elsif (A_BUS = "1110") then WRI_KOI <= '0'; WRI_PIL <= '1'; else WRI_KOI <= '0'; WRI_PIL <= '0'; end if; else WRI_KOI <= '0'; WRI_PIL <= '0'; end if; end process; -------------------------------------------- -- KOI register -------------------------------------------- process(PWR_ON, COM_SET, SEL_SET, SYS_RES, R29_KOI, WRI_KOI, WRI_DAT(0), DM1_KOI, ION_GTE) begin if (PWR_ON = '1' or COM_SET = '1' or SEL_SET = '1' or SYS_RES = '1' or R29_KOI = '1') then KOI_RG0 <= '0'; elsif (WRI_KOI = '1') then KOI_RG0 <= not WRI_DAT(0); elsif (DM1_KOI'event and DM1_KOI = '1') then if (ION_GTE = '1') then KOI_RG0 <= '1'; else null; end if; end if; end process; -------------------------- process(PWR_ON, COM_SET, SEL_SET, SYS_RES, R29_KOI, WRI_KOI, WRI_DAT(1), DM2_KOI, ION_GTE) begin if (PWR_ON = '1' or COM_SET = '1' or SEL_SET = '1' or SYS_RES = '1' or R29_KOI = '1') then KOI_RG1 <= '0'; elsif (WRI_KOI = '1') then KOI_RG1 <= not WRI_DAT(1); elsif (DM2_KOI'event and DM2_KOI = '1') then if (ION_GTE = '1') then KOI_RG1 <= '1'; else null; end if; end if; end process; -------------------------- process(PWR_ON, COM_SET, SEL_SET, SYS_RES, R29_KOI, WRI_KOI, WRI_DAT(2), TAR_KOI, ION_GTE) begin if (PWR_ON = '1' or COM_SET = '1' or SEL_SET = '1' or SYS_RES = '1' or R29_KOI = '1') then KOI_RG2 <= '0'; elsif (WRI_KOI = '1') then KOI_RG2 <= not WRI_DAT(2); elsif (TAR_KOI'event and TAR_KOI = '1') then if (ION_GTE = '1') then KOI_RG2 <= '1'; else null; end if; end if; end process; -------------------------- process(PWR_ON, COM_SET, SEL_SET, R29_KOI, Strobe1, N_COM, F_BUS, A_BUS, WRI_DAT(3)) begin if (PWR_ON = '1' or COM_SET = '1' or SEL_SET = '1' or R29_KOI = '1') then KOI_RG3 <= '0'; elsif (Strobe1'event and Strobe1 = '0') then if (N_COM = '0' and F_BUS = "01111" and A_BUS = "1111") then KOI_RG3 <= not WRI_DAT(3); else null; end if; else null; end if; end process; -------------------------------------------- -- Pile-up register -------------------------------------------- process(PWR_ON, COM_SET, SEL_SET, SYS_RES, R29_PIL, WRI_PIL, WRI_DAT(0), Stop_T1, DM1_KOI) begin if (PWR_ON = '1' or COM_SET = '1' or SEL_SET = '1' or SYS_RES = '1' or R29_PIL = '1') then PIL_RG0 <= '0'; elsif (WRI_PIL = '1') then PIL_RG0 <= not WRI_DAT(0); elsif (Stop_T1'event and Stop_T1 = '1') then if (DM1_KOI = '1') then PIL_RG0 <= '1'; else null; end if; end if; end process; -------------------------- process(PWR_ON, COM_SET, SEL_SET, SYS_RES, R29_PIL, WRI_PIL, WRI_DAT(1), Stop_T2, DM2_KOI) begin if (PWR_ON = '1' or COM_SET = '1' or SEL_SET = '1' or SYS_RES = '1' or R29_PIL = '1') then PIL_RG1 <= '0'; elsif (WRI_PIL = '1') then PIL_RG1 <= not WRI_DAT(1); elsif (Stop_T2'event and Stop_T2 = '1') then if (DM2_KOI = '1') then PIL_RG1 <= '1'; else null; end if; end if; end process; -------------------------- process(PWR_ON, COM_SET, SEL_SET, SYS_RES, R29_PIL, HIS_RES, WRI_PIL, WRI_DAT(2), Target, TAR_KOI) begin if (PWR_ON = '1' or COM_SET = '1' or SEL_SET = '1' or SYS_RES = '1' or R29_PIL = '1' or HIS_RES = '1') then PIL_RG2 <= '0'; elsif (WRI_PIL = '1') then PIL_RG2 <= not WRI_DAT(2); elsif (Target'event and Target = '1') then if (TAR_KOI = '1') then PIL_RG2 <= '1'; else null; end if; end if; end process; -------------------------------------------- -- Reset the target pile-up when no event -- in the PSAC_1 nor PSAC_2 occured during -- the blocking time -------------------------------------------- process(PWR_ON, COM_SET, SEL_SET, SYS_RES, CHAN_OR) begin if (PWR_ON = '1' or COM_SET = '1' or SEL_SET = '1' or SYS_RES = '1') then HIS_KEP <= '1'; elsif (CHAN_OR'event and CHAN_OR = '1') then HIS_KEP <= '0'; end if; end process; -------------------------- HIS_RES <= TAR_CLR and HIS_KEP; -------------------------------------------- -- Counters for the discriminated pulses -------------------------------------------- process(PWR_ON, COM_SET, SEL_SET, R29_EVT, ENA_LAM, L1_TRIG) begin if (PWR_ON = '1' or COM_SET = '1' or SEL_SET = '1' or R29_EVT = '1' or ENA_LAM = '0') then EVT_CNT <= 0; elsif (L1_TRIG'event and L1_TRIG = '1') then EVT_CNT <= EVT_CNT + 1; end if; end process; -------------------------- process(PWR_ON, COM_SET, SEL_SET, R29_SP1, ENA_CH1, Stop_T1) begin if (PWR_ON = '1' or COM_SET = '1' or SEL_SET = '1' or R29_SP1 = '1' or ENA_CH1 = '0') then SP1_CNT <= 0; elsif (Stop_T1'event and Stop_T1 = '1') then SP1_CNT <= SP1_CNT + 1; end if; end process; -------------------------- process(PWR_ON, COM_SET, SEL_SET, R29_SP2, ENA_CH2, Stop_T2) begin if (PWR_ON = '1' or COM_SET = '1' or SEL_SET = '1' or R29_SP2 = '1' or ENA_CH2 = '0') then SP2_CNT <= 0; elsif (Stop_T2'event and Stop_T2 = '1') then SP2_CNT <= SP2_CNT + 1; end if; end process; -------------------------- process(PWR_ON, COM_SET, SEL_SET, R29_TAR, ENA_TAR, Target) begin if (PWR_ON = '1' or COM_SET = '1' or SEL_SET = '1' or R29_TAR = '1' or ENA_TAR = '0') then TAR_CNT <= 0; elsif (Target'event and Target = '1') then TAR_CNT <= TAR_CNT + 1; end if; end process; -------------------------- process(PWR_ON, COM_SET, SEL_SET, R29_NEU, ENA_NEU, N_Flux, NGD_REG, NEU_GTE) begin if (PWR_ON = '1' or COM_SET = '1' or SEL_SET = '1' or R29_NEU = '1' or ENA_NEU = '0') then NEU_CNT <= 0; elsif (N_Flux'event and N_Flux = '1') then if (NGD_REG = 0) then NEU_CNT <= NEU_CNT + 1; elsif (NEU_GTE = '1') then NEU_CNT <= NEU_CNT + 1; else null; end if; end if; end process; -------------------------------------------- -- counter overflows -------------------------------------------- process(PWR_ON, COM_SET, SEL_SET, R29_EVT, ENA_LAM, L1_TRIG, EVT_CNT) begin if (PWR_ON = '1' or COM_SET = '1' or SEL_SET = '1' or R29_EVT = '1' or ENA_LAM = '0') then EVT_OVF <= '0'; elsif (L1_TRIG'event and L1_TRIG = '0') then if (EVT_CNT = 32767) then EVT_OVF <= '1'; else null; end if; end if; end process; -------------------------- process(PWR_ON, COM_SET, SEL_SET, R29_SP1, ENA_CH1, Stop_T1, SP1_CNT) begin if (PWR_ON = '1' or COM_SET = '1' or SEL_SET = '1' or R29_SP1 = '1' or ENA_CH1 = '0') then SP1_OVF <= '0'; elsif (Stop_T1'event and Stop_T1 = '0') then if (SP1_CNT = 32767) then SP1_OVF <= '1'; else null; end if; end if; end process; -------------------------- process(PWR_ON, COM_SET, SEL_SET, R29_SP2, ENA_CH2, Stop_T2, SP2_CNT) begin if (PWR_ON = '1' or COM_SET = '1' or SEL_SET = '1' or R29_SP2 = '1' or ENA_CH2 = '0') then SP2_OVF <= '0'; elsif (Stop_T2'event and Stop_T2 = '0') then if (SP2_CNT = 32767) then SP2_OVF <= '1'; else null; end if; end if; end process; -------------------------- process(PWR_ON, COM_SET, SEL_SET, R29_TAR, ENA_TAR, Target, TAR_CNT) begin if (PWR_ON = '1' or COM_SET = '1' or SEL_SET = '1' or R29_TAR = '1' or ENA_TAR = '0') then TAR_OVF <= '0'; elsif (Target'event and Target = '0') then if (TAR_CNT = 32767) then TAR_OVF <= '1'; else null; end if; end if; end process; -------------------------- process(PWR_ON, COM_SET, SEL_SET, R29_NEU, ENA_NEU, N_Flux, NEU_CNT) begin if (PWR_ON = '1' or COM_SET = '1' or SEL_SET = '1' or R29_NEU = '1' or ENA_NEU = '0') then NEU_OVF <= '0'; elsif (N_Flux'event and N_Flux = '0') then if (NEU_CNT = 32767) then NEU_OVF <= '1'; else null; end if; end if; end process; -------------------------------------------- -- Shortening the TOF_1 pulse -------------------------------------------- process(PWR_ON, COM_SET, SYS_RES, DM1_KOI, DM1_STP) begin if (PWR_ON = '1' or COM_SET = '1' or SYS_RES = '1' or DM1_KOI = '1') then DM1_OUT <= '0'; elsif (DM1_STP'event and DM1_STP = '1') then DM1_OUT <= '1'; end if; end process; -------------------------------------------- -- Shortening the TOF_2 pulse -------------------------------------------- process(PWR_ON, COM_SET, SYS_RES, DM2_KOI, DM2_STP) begin if (PWR_ON = '1' or COM_SET = '1' or SYS_RES = '1' or DM2_KOI = '1') then DM2_OUT <= '0'; elsif (DM2_STP'event and DM2_STP = '1') then DM2_OUT <= '1'; end if; end process; -------------------------------------------- -- BDP_1 starting gate -------------------------------------------- process(PWR_ON, COM_SET, Clock, SYS_RES, BDP_CN1, BDP_REG, M1F_CNT) begin if (PWR_ON = '1' or COM_SET = '1') then BDP_TM1 <= '0'; elsif (Clock'event and Clock = '0') then if (SYS_RES = '1' or BDP_CN1 = BDP_REG + 15) then BDP_TM1 <= '0'; elsif (M1F_CNT = 1) then BDP_TM1 <= '1'; else null; end if; end if; end process; -------------------------------------------- -- BDP_2 starting gate -------------------------------------------- process(PWR_ON, COM_SET, Clock, SYS_RES, BDP_CN2, BDP_REG, M2F_CNT) begin if (PWR_ON = '1' or COM_SET = '1') then BDP_TM2 <= '0'; elsif (Clock'event and Clock = '0') then if (SYS_RES = '1' or BDP_CN2 = BDP_REG + 15) then BDP_TM2 <= '0'; elsif (M2F_CNT = 1) then BDP_TM2 <= '1'; else null; end if; end if; end process; -------------------------------------------- -- BDP_1 starting counter -------------------------------------------- process(PWR_ON, COM_SET, Clock, BDP_TM1) begin if (PWR_ON = '1' or COM_SET = '1') then BDP_CN1 <= 0; elsif (Clock'event and Clock = '1') then if (BDP_TM1 = '1') then BDP_CN1 <= BDP_CN1 + 1; else BDP_CN1 <= 0; end if; end if; end process; -------------------------------------------- -- BDP_2 starting counter -------------------------------------------- process(PWR_ON, COM_SET, Clock, BDP_TM2) begin if (PWR_ON = '1' or COM_SET = '1') then BDP_CN2 <= 0; elsif (Clock'event and Clock = '1') then if (BDP_TM2 = '1') then BDP_CN2 <= BDP_CN2 + 1; else BDP_CN2 <= 0; end if; end if; end process; -------------------------------------------- -- BDP_1 starting pulse -------------------------------------------- process(PWR_ON, COM_SET, Clock, SYS_RES, BDP_CN1, BDP_REG, M1F_CNT) begin if (PWR_ON = '1' or COM_SET = '1') then BDP_ST1 <= '0'; elsif (Clock'event and Clock = '0') then if (SYS_RES = '1' or BDP_CN1 = BDP_REG + 15) then BDP_ST1 <= '0'; elsif (BDP_REG = 0) then if (M1F_CNT = 1) then BDP_ST1 <= '1'; else null; end if; elsif (BDP_CN1 = BDP_REG) then BDP_ST1 <= '1'; else null; end if; end if; end process; -------------------------------------------- -- BDP_2 starting pulse -------------------------------------------- process(PWR_ON, COM_SET, Clock, SYS_RES, BDP_CN2, BDP_REG, M2F_CNT) begin if (PWR_ON = '1' or COM_SET = '1') then BDP_ST2 <= '0'; elsif (Clock'event and Clock = '0') then if (SYS_RES = '1' or BDP_CN2 = BDP_REG + 15) then BDP_ST2 <= '0'; elsif (BDP_REG = 0) then if (M2F_CNT = 1) then BDP_ST2 <= '1'; else null; end if; elsif (BDP_CN2 = BDP_REG) then BDP_ST2 <= '1'; else null; end if; end if; end process; -------------------------------------------- -- ADC gate for the energy loss measurements -------------------------------------------- process(PWR_ON, COM_SET, Clock, SYS_RES, ADC_CNT, ADC_REG) begin if (PWR_ON = '1' or COM_SET = '1') then ADC_GTE <= '0'; elsif (Clock'event and Clock = '0') then if (SYS_RES = '1' or ADC_CNT = ADC_REG) then ADC_GTE <= '0'; elsif (EXT_CNT = 1) then ADC_GTE <= '1'; else null; end if; end if; end process; -------------------------------------------- -- ADC gate counter -------------------------------------------- process(PWR_ON, COM_SET, Clock, ADC_GTE) begin if (PWR_ON = '1' or COM_SET = '1') then ADC_CNT <= 0; elsif (Clock'event and Clock = '1') then if (ADC_GTE = '1') then ADC_CNT <= ADC_CNT + 1; else ADC_CNT <= 0; end if; end if; end process; -------------------------------------------- -- Forming the gate for neutrons -- (starts after the event decision) -------------------------------------------- process(PWR_ON, COM_SET, Clock, RDO_CNT, NGD_REG, Event_OK, ENA_NEU) begin if (PWR_ON = '1' or COM_SET = '1') then NEU_GTE <= '0'; elsif (Clock'event and Clock = '0') then if (RDO_CNT = NGD_REG + 2) then NEU_GTE <= '0'; elsif (Event_OK = '1' and ENA_NEU = '1' and RDO_CNT = 2) then NEU_GTE <= '1'; else null; end if; end if; end process; -------------------------------------------- -- LAM indicator -------------------------------------------- process(PWR_ON, COM_SET, Clock, LED_CNT) begin if (PWR_ON = '1' or COM_SET = '1') then LAM_IND <= '0'; elsif (Clock'event and Clock = '0') then if (LED_CNT = 131071) then LAM_IND <= '0'; else LAM_IND <= '1'; end if; end if; end process; -------------------------------------------- -- LAM indicator counter -------------------------------------------- process(PWR_ON, COM_SET, Clock, L1_TRIG, LAM_IND) begin if (PWR_ON = '1' or COM_SET = '1') then LED_CNT <= 0; elsif (Clock'event and Clock = '1') then if (L1_TRIG = '1') then LED_CNT <= 0; elsif (LAM_IND = '1') then LED_CNT <= LED_CNT + 1; else null; end if; end if; end process; -------------------------------------------- -- Pulse for the external gate delay -------------------------------------------- GTE_OUT <= not EXT_STB; -- Socket 12 DEL_OUT <= DEL_STB; -------------------------------------------- -- starting TDCs -------------------------------------------- Start_TDC1 <= not DM1_OUT; -- Socket 7 Start_TDC2 <= not DM2_OUT; -- Socket 8 -------------------------------------------- -- stopping TDCs -------------------------------------------- Stop_TDC1 <= not (ENA_CH1 and ENA_TAR and Target); -- Socket 9 Stop_TDC2 <= not (ENA_CH2 and ENA_TAR and Target); -- Socket 10 -------------------------------------------- -- starting BDPs -------------------------------------------- Start_BDP1 <= not BDP_ST1; -- Socket 5 Start_BDP2 <= not BDP_ST2; -- Socket 6 -------------------------------------------- -- starting ADC -------------------------------------------- Start_DE <= not ADC_GTE; -- Socket 11 -------------------------------------------- -- System clear -------------------------------------------- Clear_DE <= not RES_FAN; -- Socket 13 Clear_TDC1 <= not ENA_CH1 and RES_FAN; Clear_TDC2 <= not ENA_CH2 and RES_FAN; Clear_TDC3 <= not RES_FAN; -- Socket 14 Clear_BDP1 <= not(ENA_CH1 and RES_FAN); Clear_BDP2 <= not(ENA_CH2 and RES_FAN); -------------------------------------------- -- Gates -------------------------------------------- process(ENA_NEU, ION_GTE, NEU_GTE) begin if (ENA_NEU = '1') then GTE_CTL <= NEU_GTE; -- Socket 15 else GTE_CTL <= ION_GTE; -- Socket 15 end if; end process; -------------------------------------------- -- L1 trigger request -------------------------------------------- L_RES <= not L1_TRIG; -------------------------------------------- -- Indicators -------------------------------------------- LAM_OUT <= L1_TRIG; EVT_LED <= LAM_IND; BLK_GT1 <= DM1_STP; BLK_GT2 <= DM2_STP; -------------------------------------------- end;