Main Page | Packages | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | Related Pages

TrgGemRegisters.py

00001 #!/usr/local/bin/python
00002 #
00003 #                               Copyright 2004
00004 #                                     by
00005 #                        The Board of Trustees of the
00006 #                     Leland Stanford Junior University.
00007 #                            All rights reserved.
00008 #
00009 
00010 __facility__ = "Online"
00011 __abstract__ = "GLAST LAT Coincidence based Trigger System Interface classes"
00012 __author__   = "Jim Panetta <panetta@slac.stanford.edu> SLAC - GLAST I&T"
00013 __date__     = "2/14/04"
00014 __version__  = "$Revision: 2.10 $"
00015 __release__  = "$Name: R04-12-00 $"
00016 __credits__  = "SLAC"
00017 
00018 import LATTE.copyright_SLAC
00019 
00020 
00021 from TrgObject              import TrgObject
00022 from TrgGemAbstract         import TrgGemAbstract
00023 from TrgGemRegisterGeometry import AcdTileNumbering
00024 from TrgGemRegisterGeometry import RoiRegisterMap
00025 
00026 """TrgGemRegisters: Register shape defintions for a GASU trigger system"""
00027 
00028 
00029 class TrgGemRegisters(TrgGemAbstract):
00030   """\brief TrgGemRegisters class definition
00031   
00032   Implements the register shape definitions for a GASU trigger system
00033   """
00034   ROI_REGISTER_MIN   =  0
00035   ROI_REGISTER_MAX   = 53
00036   TILE_REGISTER_MIN  =  0
00037   TILE_REGISTER_MAX  = 11
00038   TILE_REGISTER_SIZE =  9
00039   NULLENGINE         = 0xe
00040   
00041   def __init__(self):
00042     """\brief TrgGem constructor
00043     """
00044     TrgGemAbstract.__init__(self)
00045     
00046   # protected:
00047   def configurationRegister(self):
00048     """\brief configurationRegister() method
00049     
00050     Method to construct the value of the GEM configuration register
00051     \return An integer
00052     """
00053     # Configuration register format defined in LAT-01545-03: Sec 2.3.1
00054     conf = 0x0
00055     conf |= ( self.useAcdAsTrigger()          )  << 0 
00056     conf |= ( self.responseHeaderParityEven() )  << 1 
00057     conf |= ( self.responseDataParityEven()   )  << 2 
00058     conf |= ( self.eventHeaderParityEven()    )  << 3 
00059     conf |= ( self.eventDataParityEven()      )  << 4 
00060     conf |= ( self.triggerParityEven()        )  << 5 
00061     conf |= ( self.inhibitContribution()      )  << 6 
00062     conf |= ( self.version() & 0xffffL        )  << 16  # meaningless.  Field is RO
00063     
00064     return conf
00065 
00066   def widthRegister(self):
00067     """\brief widthRegister method
00068 
00069     \return integer
00070     
00071     Returns a 32 bit integer corresponding to the WINDOW_WIDTH register
00072     of the GEM. Ref: LAT-TD-01545, S 2.9.1
00073     """
00074     return (self.width() & 0x1f)
00075 
00076   def periodicRateRegister(self):
00077     """\brief periodicRateRegister method
00078 
00079     \return integer
00080     
00081     Returns a 32 bit integer corresponding to the PERIODIC_RATE register
00082     of the GEM. Ref: LAT-TD-01545, S 2.3.3.1
00083     """
00084     # prescale is 24 bits.
00085     rate = 0
00086     rate |= ( self.periodicCondition().definition().prescale() & 0xffffff  )
00087     rate |= ( self.periodicCondition().definition().source()   & 0x1       ) << 31 
00088     return rate
00089 
00090   def periodicModeRegister(self):
00091     """\brief periodicModeRegister method
00092 
00093     \return integer
00094     
00095     Returns a 32 bit integer corresponding to the PERIODIC_MODE register
00096     of the GEM. Ref: LAT-TD-01545, S 2.3.3.2
00097     """
00098     mode = 1
00099     if self.periodicCondition().definition().limit() != 0:
00100       mode = 0
00101     return mode
00102 
00103   def periodicLimitRegister(self):
00104     """\brief periodicLimitRegister method
00105 
00106     \return integer
00107     
00108     Returns a 32 bit integer corresponding to the PERIODIC_LIMITS register
00109     of the GEM. Ref: LAT-TD-01545, S 2.3.3.3
00110     """
00111     limit = 0
00112     limit |= ( self.periodicCondition().definition().limit() & 0xffffL )
00113     return limit
00114 
00115   def sequenceRegister(self):
00116     """\brief sequenceRegister method
00117 
00118     \return integer
00119     
00120     Returns a 32 bit integer corresponding to the SEQUENCE register
00121     of the GEM. Ref: LAT-TD-01545, S 2.3.4
00122     """
00123     # yes, this is 17 bits...
00124     seq = 0
00125     seq |= ( self.sequence().definition().eventTag()    & 0x3    )     
00126     seq |= ( self.sequence().definition().eventNumber() & 0x7fffL ) << 2
00127     return seq
00128 
00129   def templateRegister(self, registerNumber):
00130     """\brief templateRegister method
00131 
00132     \param registerNumber  An registerNumber value
00133     \return integer
00134     
00135     Returns a 32 bit integer corresponding to the message engine
00136     template register of the TAM.  Ref: LAT-TD-01545, S 2.5
00137     Context portion is defined in 1.8.6.1
00138     """
00139     # note:  There is an exact correspondence between the engineNumber
00140     #        and the registerNumber
00141     
00142     if registerNumber < TrgObject.ENGINE_NUMBER_MIN or \
00143        registerNumber > TrgObject.ENGINE_NUMBER_MAX:
00144       raise IndexError, "Register index out of bounds"
00145     eng = self.engines().engine(registerNumber)
00146     return self.__parseEngine(eng)
00147     
00148   def __parseEngine(self, eng):
00149     presc = eng.prescale()
00150     if presc < 0: 
00151       inhibit = 1
00152       presc = 0
00153     else:
00154       inhibit = 0
00155     
00156     reg      = 0
00157     reg     |= ( presc                     & 0xff )
00158     reg     |= ( inhibit                   & 0x1  ) << 15
00159     
00160     engReq   = eng.request()
00161     calstr   = ( engReq.sequence()     & 0x2  ) >> 1
00162     tack     = ( engReq.sequence()     & 0x1  )
00163     context  = 0
00164     context |= ( calstr                & 0x1  )
00165     # 2 bits for tag
00166     context |= ( tack                  & 0x1  ) << 3
00167     context |= ( engReq.fourRange()    & 0x1  ) << 4
00168     context |= ( engReq.zeroSuppress() & 0x1  ) << 5
00169     context |= ( engReq.marker()       & 0x7  ) << 6
00170     context |= ( engReq.destination()  & 0x3f ) << 9
00171     
00172     reg |= ( context                & 0xffffL ) << 16
00173     
00174     return reg
00175 
00176   def lookupTableRegister(self, registerNumber):
00177     """\brief lookupTableRegister method
00178 
00179     \param registerNumber  A reference into the Scheduler register set
00180     \return integer
00181     
00182     Returns a 32 bit integer referencing the TAM generator used for a
00183     particular trigger summary
00184     Ref: LAT-TD-01545, S 2.7
00185     """
00186     nReg = ( TrgObject.CONDITIONS_NUMBER_MAX + 1 ) / 8
00187     if registerNumber < 0 or registerNumber > nReg:
00188       raise IndexError, "Register index out of bounds"
00189       
00190     reg = 0
00191     for contrib in range(8):
00192       reg |= ( self.__lutEntry(contrib + (registerNumber << 3)) << (contrib << 2L) )
00193     return reg
00194 
00195   def __lutEntry(self, conditionValue):
00196     engineSet = self.engines()
00197     for engineNumber in range(TrgObject.ENGINE_NUMBER_MAX+1):
00198       if engineSet.engine(engineNumber).participate(conditionValue):
00199         return engineNumber
00200     
00201     return TrgGemRegisters.NULLENGINE  # Condition value has no engine.  Disable it.
00202     
00203   def roiRegister(self, registerNumber):
00204     """\brief roiRegister method
00205 
00206     \param registerNumber  A reference into the ROI generator registers
00207     \return integer
00208     
00209     Returns a 32 bit integer referencing the 54 ROI registers defined in
00210     Ref: LAT-TD-01545, S 2.8
00211     """
00212     # two ways to define this register.  1)  ACD is trigger  (coincidence mode) 
00213     #                                    2)  ACD is veto     (shadow mode)
00214     # The code is the same regardless of intent.  :-)
00215     if registerNumber < TrgGemRegisters.ROI_REGISTER_MIN or \
00216        registerNumber > TrgGemRegisters.ROI_REGISTER_MAX:
00217       raise IndexError, "Register index out of bounds"
00218     
00219     reg = 0
00220     roiSet = self.roi()
00221     # RoiRegisterMap[n] returns ("name0","name1")
00222     # AcdTileNumbering["name"] returns tile number
00223     tile0 = AcdTileNumbering[ RoiRegisterMap[registerNumber][0] ]
00224     tile1 = AcdTileNumbering[ RoiRegisterMap[registerNumber][1] ]
00225     reg |= ( self.__roiValue(roiSet, tile0) & 0xffffL )      
00226     reg |= ( self.__roiValue(roiSet, tile1) & 0xffffL ) << 16
00227     return reg
00228       
00229   def __roiValue(self, roiSet, tileNumber):
00230     """ constructs either:
00231         a) the set of 8 region pairs that define the 16 bits of coincidence info
00232         b) the tower mask information
00233         The code is the same regardless of intent.  :-)
00234         
00235         \param roiSet is passed to save function overhead.
00236         \param tileNumber As elsewhere
00237         c.f. figure 75, 76, 77, LAT-TD-01545
00238     """
00239     pairSet = 0
00240     for region in range(TrgObject.ROI_NUMBER_MAX + 1):
00241       bit = roiSet.roi(region).tile(tileNumber)  # tile returns 1 or 0
00242       pairSet |= (bit << region)
00243     return pairSet
00244   
00245   def towerEnableRegister(self, registerNumber):
00246     """\brief towerEnableRegister method
00247 
00248     \param registerNumber A reference into the tower enable registers
00249     \return integer
00250     
00251     Returns a 32 bit object corresponding to figures 78/79 of the GEM
00252     documentation.  This is used to construct the registers
00253     TOWERS_0_3, etc.
00254     Ref: LAT-TD-01545, 2.9.1
00255     """
00256     # 4 towers/register
00257     nReg = ( TrgObject.TOWER_NUMBER_MAX + 1 ) / 4
00258     if registerNumber < 0 or registerNumber > nReg:
00259       raise IndexError, "Register index out of bounds"
00260     
00261     reg = 0
00262     for twr in range(4):
00263       reg |= ( self.__tower3bit(twr + (registerNumber << 2)) << twr*3 )
00264     return reg
00265 
00266   def __tower3bit(self, towerIndex):
00267     if towerIndex < TrgObject.TOWER_NUMBER_MIN or \
00268        towerIndex > TrgObject.TOWER_NUMBER_MAX:
00269       raise IndexError, "towerIndex out of bounds"
00270     
00271     tower = self.inputEnables().towers().tower(towerIndex)
00272     twr = 0
00273     if tower is not None:
00274       twr |= ( tower.calorimeter().useLowEnergy()  & 0x1 )     
00275       twr |= ( tower.calorimeter().useHighEnergy() & 0x1 ) << 1
00276       twr |= ( tower.tracker().use()               & 0x1 ) << 2
00277     
00278     return twr
00279 
00280   def towerBusyEnableRegister(self):
00281     """\brief towerBusyEnableRegister method
00282     
00283     \return integer
00284     
00285     Returns a 32 bit integer corresponding to the Tower Busy enable register
00286     """
00287     twrBusy = 0
00288     towerBusy = self.inputEnables().towerBusy()
00289     for tower in range(TrgObject.TOWER_NUMBER_MAX +1):
00290       # # Tower is ON if one or more of the inputs is enabled
00291       # if self.__tower3bit(tower) != 0:
00292         # twrBusy |= ( 1 << tower )
00293       if towerBusy.tower(tower):
00294         twrBusy |= ( 1 << tower )
00295     
00296     return twrBusy
00297 
00298   def externalEnableRegister(self):
00299     """\brief externalEnableRegister method
00300     
00301     \return integer
00302     
00303     Returns a 32 bit integer corresponding to the external enable register
00304     """
00305     ext = 0
00306     if self.inputEnables().external().external():
00307       ext = 0x1
00308     return ext
00309     
00310   def cnoEnableRegister(self):
00311     """\brief cnoEnableRegister method
00312 
00313     \return integer
00314     
00315     Returns a 32 bit integer corresponding to the ACD CNO enable register
00316     Ref: LAT-TD-01545, 2.9.2
00317     """
00318     
00319     enab = self.inputEnables().cno()
00320     cno = 0
00321     cno |= ( enab.LA1() & 0x1 )       
00322     cno |= ( enab.RB1() & 0x1 ) << 1 
00323     cno |= ( enab.LA2() & 0x1 ) << 2 
00324     cno |= ( enab.LB2() & 0x1 ) << 3 
00325     cno |= ( enab.RA2() & 0x1 ) << 4 
00326     cno |= ( enab.RB2() & 0x1 ) << 5 
00327     cno |= ( enab.LA3() & 0x1 ) << 6 
00328     cno |= ( enab.RB3() & 0x1 ) << 7 
00329     cno |= ( enab.LA4() & 0x1 ) << 8 
00330     cno |= ( enab.LB4() & 0x1 ) << 9 
00331     cno |= ( enab.RA4() & 0x1 ) << 10
00332     cno |= ( enab.RB4() & 0x1 ) << 11
00333     
00334     return cno
00335 
00336   def tileEnableRegister(self, registerNumber):
00337     """\brief tileEnableRegister method
00338 
00339     \param registerNumber
00340     \return integer
00341     
00342     Returns a 32 bit integer corresponding to the ACD tile enable register.
00343     Ref: LAT-TD-01545, 2.9.3
00344     """
00345     # 108 'real' tiles, 9 tiles/register --> 12 registers
00346     if registerNumber < TrgGemRegisters.TILE_REGISTER_MIN or \
00347        registerNumber > TrgGemRegisters.TILE_REGISTER_MAX:
00348       raise IndexError, "registerNumber out of bounds"
00349     
00350     reg = 0
00351     
00352     tto = self.inputEnables().tiles()
00353     for t in range(TrgGemRegisters.TILE_REGISTER_SIZE):
00354       tile = t + (TrgGemRegisters.TILE_REGISTER_SIZE) * registerNumber
00355       reg |= ( tto.tile(tile) & 0x1 ) << t    
00356       reg |= ( tto.tile(tile) & 0x2 ) << (t+8)  # using 1 bit offset here
00357     return reg
00358 
00359 
00360   # Pure virtual function implementation
00361   # Defaults from ACD Roadmap document
00362   def width(self): 
00363     return 0x5
00364     
00365   def responseHeaderParityEven(self):
00366     return False
00367     
00368   def responseDataParityEven(self):
00369     return False
00370 
00371   def eventHeaderParityEven(self):
00372     return False
00373 
00374   def eventDataParityEven(self):
00375     return False
00376 
00377   def triggerParityEven(self):
00378     return False
00379 
00380   def inhibitContribution(self):
00381     return False
00382 

Generated on Fri Jul 21 13:26:33 2006 for LATTE R04-12-00 by doxygen 1.4.3