diff --git a/python/epix_hr_core/_TriggerRegisters.py b/python/epix_hr_core/_TriggerRegisters.py index 69d6936..b996e18 100644 --- a/python/epix_hr_core/_TriggerRegisters.py +++ b/python/epix_hr_core/_TriggerRegisters.py @@ -8,7 +8,6 @@ # contained in the LICENSE.txt file. #----------------------------------------------------------------------------- import pyrogue as pr -import time class TriggerRegisters(pr.Device): def __init__(self, triggerFreq = 1e8, **kwargs): super().__init__(description='Trigger Registers', **kwargs) @@ -37,6 +36,8 @@ def __init__(self, triggerFreq = 1e8, **kwargs): self.add(pr.RemoteVariable(name='AutoTrigPeriod', description='AutoTrigPeriod', offset=0x00000018, bitSize=32, bitOffset=0, base=pr.UInt, disp = '{}', mode='RW')) self.add(pr.RemoteVariable(name='PgpTrigEn', description='PgpTrigEn', offset=0x0000001C, bitSize=1, bitOffset=0, base=pr.Bool, mode='RW')) self.add(pr.RemoteVariable(name='AcqCount', description='AcqCount', offset=0x00000024, bitSize=32, bitOffset=0, base=pr.UInt, disp = '{}', mode='RO')) + self.add(pr.RemoteVariable(name='DaqCount', description='DaqCount', offset=0x00000028, bitSize=32, bitOffset=0, base=pr.UInt, disp = '{}', mode='RO')) + self.add(pr.RemoteVariable(name='numberTrigger', description='numberTrigger', offset=0x0000002C, bitSize=32, bitOffset=0, base=pr.UInt, disp = '{}', mode='RW')) ##################################### @@ -64,11 +65,14 @@ def SetAutoTrigger (arg): @self.command(description = 'Start and enable auto triggers') def StartAutoTrigger (): print('Start Auto Trigger command executed') - self.AutoRunEn.set(True) - self.RunTriggerEnable.set(True) - time.sleep(1) + # DaqCount AND AcqCount must be identical, otherwise triggers are + # being sent to the ASICs without reseting the fifos OR warning the + # logic! Fifos get full and overflow is detected, but not because the + # logic is not catching up self.AutoDaqEn.set(True) self.DaqTriggerEnable.set(True) + self.AutoRunEn.set(True) + self.RunTriggerEnable.set(True) @self.command(description = 'Stop all trigger sources') def StopTriggers (): diff --git a/shared/rtl/AutoTrigger.vhd b/shared/rtl/AutoTrigger.vhd index cd53394..b2e0574 100644 --- a/shared/rtl/AutoTrigger.vhd +++ b/shared/rtl/AutoTrigger.vhd @@ -38,6 +38,9 @@ entity AutoTrigger is -- Number of clock cycles between triggers trigPeriod : in slv(31 downto 0); + -- Number of triggers + numTriggers : in slv(31 downto 0) := (others => '0'); + --Enable run and daq triggers runEn : in sl; daqEn : in sl; @@ -55,6 +58,7 @@ architecture AutoTrigger of AutoTrigger is signal timeoutTarget : unsigned(31 downto 0); signal trigTarget : unsigned(31 downto 0); signal timeoutCnt : unsigned(31 downto 0) := (others => '0'); + signal triggerCnt : unsigned(31 downto 0) := (others => '0'); signal iRunTrigOut : sl := '0'; signal iDaqTrigOut : sl := '0'; -- MUX select types @@ -77,6 +81,7 @@ begin if (sysClkRst = '1') then iRunTrigOut <= '0' after tpd; timeoutCnt <= (others => '0') after tpd; + triggerCnt <= (others => '0') after tpd; else -- Default output iRunTrigOut <= '0' after tpd; @@ -103,11 +108,16 @@ begin when INTERNAL_T => if (timeoutCnt >= trigTarget) then timeoutCnt <= (others => '0') after tpd; - iRunTrigOut <= '1' after tpd; + if ((unsigned(numTriggers) = 0) or (triggerCnt < unsigned(numTriggers))) then + iRunTrigOut <= '1' after tpd; + triggerCnt <= triggerCnt + 1 after tpd; + end if; end if; end case; end if; else + --Reset trigger count + triggerCnt <= (others => '0') after tpd; --If autotriggers are off, select external triggers trigSel <= EXTERNAL_T; end if; diff --git a/shared/rtl/TrigControlAxi.vhd b/shared/rtl/TrigControlAxi.vhd index 755eded..ba7b6fe 100644 --- a/shared/rtl/TrigControlAxi.vhd +++ b/shared/rtl/TrigControlAxi.vhd @@ -4,6 +4,9 @@ ------------------------------------------------------------------------------- -- Description: ------------------------------------------------------------------------------- +-- History : 2023/7/27 Added the generation of a designated +-- number of triggers by Dawood +------------------------------------------------------------------------------- -- This file is part of 'EPIX HR Firmware'. -- It is subject to the license terms in the LICENSE.txt file found in the -- top-level directory of this distribution and at: @@ -80,6 +83,7 @@ architecture rtl of TrigControlAxi is timingRunEn : sl; timingDaqEn : sl; acqCountReset : sl; + numTriggers : slv(31 downto 0); runTriggerDelay : slv(31 downto 0); daqTriggerDelay : slv(31 downto 0); autoTrigPeriod : slv(31 downto 0); @@ -94,6 +98,7 @@ architecture rtl of TrigControlAxi is timingRunEn => '0', timingDaqEn => '0', acqCountReset => '0', + numTriggers => (others=>'0'), runTriggerDelay => (others=>'0'), daqTriggerDelay => (others=>'0'), autoTrigPeriod => (others=>'0') @@ -126,8 +131,11 @@ architecture rtl of TrigControlAxi is signal runTriggerOut : std_logic; signal daqTriggerOut : std_logic; signal countEnable : std_logic; + signal daqCountEnable : std_logic; signal acqCount : std_logic_vector(31 downto 0); + signal daqCount : std_logic_vector(31 downto 0); signal acqCountSync : std_logic_vector(31 downto 0); + signal daqCountSync : std_logic_vector(31 downto 0); signal swRun : std_logic; signal swRunSync : std_logic; signal swRead : std_logic; @@ -357,6 +365,8 @@ begin daqTrigIn => hwDaqTrig, -- Number of clock cycles between triggers trigPeriod => trigSync.autoTrigPeriod, + -- Number of triggers + numTriggers => trigSync.numTriggers, --Enable run and daq triggers runEn => autoRunEn, daqEn => autoDaqEn, @@ -389,11 +399,25 @@ begin end if; end process; + process ( appClk, appRst ) begin + if ( appRst = '1' ) then + daqCount <= (others=>'0') after TPD_G; + daqCountEnable <= '0' after TPD_G; + elsif rising_edge(appClk) then + daqCountEnable <= iDaqTrigOut or swRead after TPD_G; + + if trigSync.acqCountReset = '1' then + daqCount <= (others=>'0') after TPD_G; + elsif daqCountEnable = '1' then + daqCount <= daqCount + 1 after TPD_G; + end if; + end if; + end process; -------------------------------------------------- -- AXI Lite register logic -------------------------------------------------- - comb : process (axilRst, sAxilReadMaster, sAxilWriteMaster, r, acqCountSync) is + comb : process (axilRst, sAxilReadMaster, sAxilWriteMaster, r, acqCountSync, daqCountSync) is variable v : RegType; variable regCon : AxiLiteEndPointType; begin @@ -415,6 +439,8 @@ begin axiSlaveRegister (regCon, x"1C", 0, v.trig.pgpTrigEn); axiSlaveRegister (regCon, x"20", 0, v.trig.acqCountReset); axiSlaveRegisterR(regCon, x"24", 0, acqCountSync); + axiSlaveRegisterR(regCon, x"28", 0, daqCountSync); + axiSlaveRegister (regCon, x"2C", 0, v.trig.numTriggers); axiSlaveDefault(regCon, v.sAxilWriteSlave, v.sAxilReadSlave, AXIL_ERR_RESP_G); @@ -434,6 +460,7 @@ begin if (rising_edge(axilClk)) then r <= rin after TPD_G; acqCountSync <= acqCount after TPD_G; + daqCountSync <= daqCount after TPD_G; end if; end process seq;