File: Local_DSP_Program.TXT Date: 17-MAY-1995 General Idea of the L1.5 Cal Trig Algorithm -------------------------------------------- The algorithm to be implemented in L1.5 Cal Trig DSP Code is as follows: I. In Local DSP's (0) Wait for ERPB Data and Beginning Status Word The Local DSP's are waiting for both ERPB Data and a Valid Wake Up word. The DSPs grab the ERPB data using DMA and Comm Port read synchronization so no CPU instructions are needed. The DSPs poll the Dual Port Memory looking for the Wake Up Word. This polling is essentially "free" because no other CPU activity is going on or even possible during this time. This of course assumes that the 68K can provide the Wake Up Word before all of the ERPB data arrives. Once the Wake Up Word has been received, the Local DSPs report back to the 68K that they have seen a valid Wake Up Word. Once the DMA is finished the DMA Controller will interrupt the DSP CPU. Once a DSP CPU sees all 4 DMA channels finished it will tell the 68K that all ERPB Data has been received. The DSP will examine the Wake Up Word to see whether this is a Mark and Force Pass Event. If so, it will set up the Local-to- Global DMA Lists for Mark and Force Pass transfers, and also set a flag which the Tool can examine to know whether this is a Mark and Force Pass event. (1) Search for Towers over Threshold Loop over the 128 Trigger Towers for which this DSP Node is responsible. Looping order is "4 ETAs at one PHI then go to the next PHI" (i.e. like CTFE's but recall that the DSP Node is shifted by 2 ETAs with respect to CTFE's). Compare each TT's EM Energy to its Reference Energy (we will only have one Reference Set). If the TT's EM Energy is Greater Than or the Reference Energy then call the 1x2 vs. 1x2 Tool. Note that COOR expects the Reference Energy comparison to actually be a Greater Than or Equal To comparison, also COOR specifies Reference Set Energy in Gev. The C40 performs this comparison on counts, not GeV. The TCC is responsible for the GeV to counts conversion, also it is responsible for the ">=" to ">" comparison. Note that the strictly Greater Than comparison is used to allow EXCLUSION of a Trigger Tower, in a similar fashion to the L1 Cal Trig. After looping over all 128 TT's then go to the Local-to-Global Transfer. (2) 1x2 vs. 3x3 Tool Find the most energetic of the 4 EM Trigger Towers adjacent to the seed found in step (1). Calculate the 1x2 EM Et of these 2 towers, and remember the offset to the chosen neighbor. Calculate the 1x2 Total Et of these 2 towers also. Calculate the 3x3 Total Et around this seed. For each of the 4 Terms which exist in this Local Tool: Reject the seed if any of the following is true: (a) the 1x2 EM Et < 1x2 EM Et Threshold (b) 1x2 EM Et / 3x3 Total Et < Isolation Ratio Threshold (c) 1x2 EM Et / 1x2 Total Et < Isolation Ratio Threshold If the seed is not rejected, or if this is a Mark and Force Pass Event, place the entry in the Local Object List and increment the Local Objects Found counter (and the pointer to the next open "slot" in the Local Object List). When writing to the Object List, check the Local Object Counter and don't write the entry if it would overflow the Local Object List. Note that all 4 Terms are always evaluated. Return to the Search for Towers over Threshold (step (1)). (3) Local-to-Global Transfer First generate the Local DSP Header which is a single longword. Then write it in some memory location. Now the operation is somewhat different depending on which DSP is being considered. The general specification of the transfer is as follows: (a) Collect all Local-to-Global data from the "previous" DSP in the chain. Note that the "previous" DSP may have also collected data from its "previous" DSP. (b) Transfer all Local-to-Global data (both from the "current" DSP and all "previous" DSPs) to the "next" DSP (which may or may not be the Global DSP). Part (a) of the transfer must completely finish before part (b) of the transfer may begin. Specifically, the transfer proceeds as follows: On all Hydra-II Cards: DSP #1: use DMA and Comm Port to send the Header and List of Identified Objects to DSP #2 DSP #4: use DMA and Comm Port to send the Header and List of Identified Objects to DSP #3 (the above 2 transfers happen "simultaneously") Assuming it takes 200 ns to shoot a longword out a Comm Port (see Table 14-20 on page 14-31 of the C40 User's Guide, which indicates that for a 40 MHz 'C40: Tword minimum = 1.5 * 50 + 46 = 121 ns Tword maximum = 2.5 * 50 + 202 = 327 ns), and also noting that the DMA Controller can keep up with two Comm Ports (remember that the DMA Controller requires 100 ns to complete a read/write pair), each transfer of 25 longwords should take 25 * 200ns = 5 us This 5 us number has been experimentally shown to be valid for a single isolated transfer (of the entire Object List from LDSP B1 to GDSP B2). DSP #3: use DMA and Comm Port to send the Header and List of Identified Objects of both DSP #3 and DSP #4 to DSP #2 (this transfer happens after the first two transfers, and takes approximately twice as long, or 10 us, for an elapsed time of 15 us so far) On Hydra-II Cards A and C only DSP #2: Once it has received DSP #1's list from DSP #1, and the lists from DSP #3 and #4 from DSP #3, it transfers ALL FOUR lists (its own plus the three it has just received) to the Global DSP. Recall the on Hydra-II Card B, DSP #2 is the Global DSP. (since the DMA engine on the Global DSP can keep up with two Comm Ports, this transfer requires four times as long as the transfer of one DSP's information, or 20 us. The total time required for the Local-to-Global transfer from 11 Local DSPs will thus be 35 us [a.k.a. 7 time slices]). NOTE: experimentally, in the full system, the Local to Global transfer time has been determined to be 56 us. NOTE also that as of 17-MAY-1995, the DMA list structure has been broken into 2 parts. First the Counts of Objects passed per Term is passed, then the Objects themselves as described above are passed. The idea is to give the Global DSP the information that it needs to trigger as quickly as possible, and then start moving the data for readout. The Count lists should move very quickly, they are about 1/12 the size of the Object Lists. The DMA list structure is described in detail in the file: [TRG_C40.FIRST_RELEASE.SOFTWARE_NOTES]DMA_LIST_STRUCTURE.TXT Note that this can be done with the following DMA Lists: (4) Wait and Prepare for the Next Event The Local DSP's wait for the 68K to tell them that it is time to prepare for the next event. When told, they prepare for the next event. After that, they return to Step (0). Additionally, there are additional functions required by the Local DSP Program. These are functions that do not execute "cyclically" like the loop described above but rather execute only when required (i.e. for initialization or error handling). Some of these functions execute exactly once (for example initialization), while others execute zero, one, or more times (for example error handling). (A) "General" Initialization In this module, the DSP "general" (or non-node-specific) initialization occurs. This includes setting up the IVTP, TVTP, Global MICR, SP, Status Register, etc. The "general" initialization is identical across all Local DSPs. (B) "Node-Specific" Initalization In this module, the DSP "node-specific" initialization occurs. This includes setting up the Local MICR (recall that it is different on DSP #1, hence it must be in the node-specific initialization), as well as defining the DSP Node ID, the actual eta range serviced by this Node, the constant part of the Local DSP Header Word, the sections of memory used by this Node for parameter passing and data storage, and assigning functions (and DMA Lists) to the 6 Comm Ports. This programming can be done by a combination of C40 code and assembler ".word" and ".set" directives (C) Parameter Receiving and Checking There needs to be one parameter receiver-and-checker per Local Tool. Since we only have one Local Tool in this version of the program, only one parameter receiver-and-checker is required. The parameters will be passed to the program via structures in Dual Port Memory (NOT built into the code or added to the Boot-Loader Readable Image of the code) once the Local DSP Program is running. Each DSP Card will have the parameters for ALL 11 Local DSP Nodes and the Global DSP Node deposited in a block in Dual Port Memory by the TCC. Then each DSP will be interrupted by the TCC to indicate that the Parameters are available. The DSP Nodes will read their appropriate parameter block, check the parameters, and report to the TCC via the Dual Port Memory. The appropriate way to signal the DSPs is via a VME interrupt. This only has to be done once at a specific point in the code (after the Node Initialization but before executing the "cyclic" code the first time, but it may be done multiple times in future versions. So we will use the interrupt rather than polling. If there is a problem with the Parameters, Parameter processing STOPS with the erroneous Parameter and an error code is returned to the TCC. No further Parameters will be considered. The program could either halt (waiting for a new download of the both the program and the parameters), or wait for a new download of just the parameters. (D) Error Handling Most error detection is NOT done in the Local DSPs, but rather is done in the Engine Control 68K. It is in fact not at all clear what types of errors could be detected by the Local DSPs. When the EC 68K detects an error, it must signal all of the Local DSPs (as well as the Global DSP). This should be done using an interrupt, because it may happen multiple times and will certainly happen at unpredictable points in the code. Therefore it is not reasonable for the Local DSPs to poll a memory location looking for an error flag. I think it makes sense to use the IIOF2 interrupt as a VME interrupt as described in the Hydra manual (i.e. briefly set this pin to its active state via the Hydra-II Board Control Register [which is accessed via VME]). When any error is detected, the Local DSP code should return to the "waiting for DSP Wakeup Word and ERPB Data" state. All event-specific memory relating to the event which resulted in an error should be cleared. There are I think some intrinsic difficulties in error handling. A big possible problem is verifying that the error has been completely stamped out. For example what if one ERPB Channel does not respond in time, so the Local DSPs are "reset," but then the slow ERPB Channel now responds. We are now guaranteed to have problems with the following event, because it has a mix of old and new data. I don't think there is much we can do in DSP-land to fix this type of problem, we are going to have to be very careful when we perform any error handling and clearing to be certain that we stamp the error out completely. There is only one "error handling" routine in the Local DSPs. That is, we don't do one thing if the ERPB readout has failed, and a different thing if the Local-to-Global Transfer has failed. We always do the same things. If for some reason this is not possible, then we could define a memory location in the Dual Port Memory to convey information about the type of error from the 68K (or TCC?) to the DSPs. PROGRAM FLOW ------------ L_Init (Local initialization) ------ (wait for "Load Parameters" interrupt, then in an ISR [all ISRs are in the L_ISR module) CALL the following modules) ----- L_DSP_%% (Node-Specific Initialization) -------- L_Params (Get Universal and Frame Parameters, as well -------- as the Local Tool Parameter Header and Tool ID) (from L_Params CALL the following module) L_Tl_Ini (Tool Initialization, including getting -------- Local Tool Parameters) (return to L_Params) (end the ISR, and force execution to resume at the beginning of the following module) L_Scan ("get ready for next event," wait for DSP Wakeup, ------ wait for Local Data, scan TT's, call Tools, i.e. this is the "cyclic" code) (from L_Scan BRANCH to the following modules as necessary L_Tl_Np2, L_Tl_Np3, L_Tl_Np4, L_Tl_Np5 -------- -------- -------- -------- (return to L_Scan) that is, L_Scan is the classical "Frame" code, while L_Tl_%%% is the classical "Tool" code Other modules outside the normal program flow: --------------------------------------------- L_ISR (Interrupt Service Routines) L_Data (real and "Place-holder" data) Constant.Inc (Include file for Program-specific constants, included in all source files, stored in the Common Code Subdirectory) Hydra.Inc (Include file for Hydra/C40 constants, included in L_Init and L_DSP_%%, stored in the Common Code Subdirectory) Macros.Inc (Include file for Macros, included in L_DSP_%% and L_Tl_Np%, stored in the Common Code Subdirectory) L_Tool.Inc (Include file for Tool-specific constants, included in L_Tl_%%%, stored in the Local Code Subdirectory) L_DMACmn.Inc (Include file for the "constant across all nodes" part of the DMA Lists, included in L_DSP_%%, stored in the Local Code Subdirectory) L_RefDef.Inc (Include file for the .ref and .def declarations which are constant across all Node-Specific Initialization Files, included in L_DSP_%%, stored in the Local Code Subdirectory) Detailed description of each module in the Local DSP Program ------------------------------------------------------------ 1. L_Init (Local DSP non-node-specific Initialization) This is the first code to execute in the Local DSP Program. This routine is loaded at the bottom of the Local SRAM on the Hydra-II card i.e. 4000 0000h. This routine performs general purpose initialization. Note that these initialization tasks are not speed-critical. Hence the initialization code is not written "tightly" to be optimized for execution speed, but instead is written to be clearly understandable. For example, the initialization routines do not use delayed branches, and make use of the CALL construct to allow the routines to be easily modular. When the initialization is finished, this module makes a BRANCH to the "cyclic" portion of the Local DSP Program (which begins at the Scan Routine Initialization entry point). That point marks the transition from non-speed-critical to speed-critical code. This routine has the following steps: 1. Initialize the C40 Data Page Pointer Register. 2. Initialize the C40 Interrupt Vector Table Pointer 3. Initialize the C40 Trap Vector Table Pointer 4. Initialize the C40 Stack Pointer Register. 5. Initialize the C40 Status Register. 6. Initialize a pointer to the On-Chip Peripherals 7. Initialize the C40 Global Memory Interface Control Register and Local Memory Interface Control Register (note that the value for the LMICR is found in the Node-Specific Initialization Module) 8. Initialize the Error Handler (IIOF2) Interrupt Service Routine 9. Enable IIOF2 as an edge-triggered interrupt. 10. Initialize the Initialize (NMI) Interrupt Service Routine 11. Initialize a pointer to the Dual Port Memory 12. Define some constant headers 13. Send a "DSP Code Loaded and Started, Waiting for Parameters" status code to the TCC 14. Wait in a "dead loop" for the TCC to issue an NMI. When the TCC issues the NMI, the C40 will execute the NMI ISR, which will perform the Node-Specific Initialization, receive and check the Parameters, perform Tool Initialization, and branch to the beginning of the Scan Routine 2. L_DSP_%% (Local DSP Node-Specific Initialization) This routine is the Local DSP Node-Specific Initialization. It is CALLed by either the Initialize_ISR routine or the Error_Handler_ISR routine. This routine does not need to be optimized for speed, because it is not time-critical code. It is instead optimized for ease of duplication across all 11 Local DSPs. This is the ONLY module which is allowed to contain Node-Specific information. It is important that this module be understandable and easy to edit. Changes to this module should not require extensive editing on 11 files. This module makes extensive use of both macros and include files to minimize the differences between the Local DSP Nodes. This routine has the following steps: 1. Program the Comm Ports and DMA Channels corresponding to ERPB Input Data for all Racks which are fed to this LDSP. This uses the SETUP_DMA and SETUP_CRC_PORT macros. 2. Program the Comm Port and DMA Channel used to transfer Local Object List data to the "next" DSP. Recall that the Local Object Lists are sent out in ascending eta order. This uses the SETUP_DMA and SETUP_LG_NEXT_PORT macros. 3. Program the Comm Port(s) and DMA Channel(s) used to receive Local Object List data from the "previous" DSP. A Local DSP has either 0 (in which case nothing need be done), 1, or 2 "previous" DSPs. This uses the SETUP_DMA and SETUP_LG_PREV_PORT macros. 4. RETURN to the calling module This module also contains a routine used to set up the Mark and Force Pass data readout. This routine is called from the L_Scan module whenever a Mark and Force Pass event flows through the L1.5 Cal Trig. This routine has the following steps: 1. Setup the Mark and Force Pass-flavor DMA to the "next" DSP. Recall that, during MFP events, each LDSP produces, in addition to its Local Object List, three entries (Trigger Tower Data, Reference Set Data, and Derived Constant data) for the DeBug Section of the Data Block. This DSP will first transfer all of the Local Object Lists for which it is responsible, and then it will transfer the DeBug Section entries for which it is responsible (again in ascending eta order). This uses the SETUP_MFP_TO_NEXT_DMA macro. 2. Setup the Mark and Force Pass-flavor DMA from the "prev" DSP. A Local DSP may have 0 (in which case nothing need be done), 1 (in which case the SETUP_MFP_FROM_SINGLE_PREV_DMA macro is used), or 2 (in which case the SETUP_MFP_FROM_DOUBLE_PREV_DMA macro is used) "previous" DSPs. 3. Return to the calling module. This module also contains routines which are called to wait for the arrival of the data from the "previous" LDSP(s). If this LDSP has no "previous" LDSPs, then this routine simply branches back to the L_Scan routine (from which it was branched to). If this LDSP has 1 or 2 "previous" LDSPs, the WAIT_FOR_PREV_DMA macro is used to wait for the data to arrive from the "previous" LDSP(s) before branching back to the L_Scan routine. This module also contains assembler .set and .word directives to define the contents of some node-specific variables. It also contains (as .include files) the "constant-across-all-nodes" part of the DMA lists, as well as all of the external variable references and definitions. 3. L_Params (Local DSP Paramater Receiver and Checker) This is the the module which is responsible for retrieving the Parameters from Dual Port Memory and checking them for validity. It is called by the Initialize_ISR routine after the Node-Specific Initialization has completed. When called, it reads the appropriate section of Parameter space in the Dual Port Memory (recall that all Parameters for all DSP Nodes are presented in the Dual Port Memory, and this Node must select its own Parameters. First the Universal Parameters are read. This defines the Dual Port Memory Map Version and Revision, the Crate ID, and the Number of Terms defined for this code. These Parameters are checked for correctness. The Reference Set Data (for each Reference Set) is then read from the Dual Port Memory. Recall that the Reference Set Data is arranged by Term in the Dual Port Memory (i.e. the Reference Set Data for Term #0 is first, then the Reference Set Data for Term #1, etc. For this first iteration, only one Reference Set (Reference Set #0) is allowed in the Dual Port Memory. Additional Reference Sets will be ignored. Reference Set Data are not checked for correctness. Next the Term Parameters are read. This is a multiple-step process. First the Frame Parameters are read. Currently no Frame Parameters are used by the Local DSPs so for now we don't actually read Frame Parameters. Then Local Parameters are read. Local Parameters are stored by Term Number. For each Term, the Local Parameters are examined to determine which Tool should be used, and the appropriate Tool Initialization Routine is called to actually absorb the Tool-Specific Local Parameters. If the specified Tool does not exist, this routine is responsible for setting an error flag to the TCC. If the specified Tool does exist, the Tool is responsible for checking its Parameters and returning an success/failure exit code to this module. Note that this Parameter Checker module only checks one Term (Term #0), one Local Tool, and one Global Tool. It expects 4 Terms to be defined, all pointing to a single Tool Once all Parameters have been received and checked, this routine sets a return status in the Dual Port Memory indicating the results of the Parameter reading and checking. It also pre-loads benign values into the Wake Up Word and Status to 68K Word in the Shared Dual Port Memory. Then contol is returned to the calling module 4. L_Tl_Ini (Local DSP Tool-Specific Initialization) This is the module that Initializes the Local Tool Code. Note that there must be one of these modules for each Local Tool. In this first version of the code there is only one Local Tool and hence only one Local Tool Initialization module. This version of the code requires 4 Terms, each mapped to this Tool. This module extracts Parameters for each of the 4 Terms. This module is called from the L_Params module after it has received and checked the Universal and Frame Parameters, and extracted some information about this Term's Tool-Specific Parameters (e.g. the Tool Number so it knows which Tool-Specific Initialization to call). It performs the following functions: (1) Receive and store the Term Number to which this Tool has been mapped (only for Term #0) (2) Receive and check the Reference Set Type used by this Tool (only for Term #0) (3) Receive, check, and store the Local Tool Parameters for Terms #0, #1, #2, and #3. (4) Generate any "derived constants" (i.e. Offsets) that will be used by the Local Tool and store them in known locations (5) Build the Header for the Derived Constants subsection of the Mark and Force Pass Section of the Data Block (6) Return a status code to the Parameter Checking module (7) Return to the calling module 5. L_Scan (Local DSP Frame Scan for Candidates) This is the program module for the "Trigger Tower Scan" for the Local DSP Program. This module looks for Trigger Towers with EM Et that is over threshold. This is the "cyclic" part of the L1.5 Cal Trig Code. It is branched to from either the Error_Handler_ISR or the Initialize_ISR, after those routines have completed all of their processing. This is now time-critical code which is written to be fast. This module performs the following functions: (1) Set/reset all pointers, etc. This either cleans up from the last time the loop was executed or initializes the loop for the first cycle (2) Set status to the 68K (EC) which indicates that this Local DSP has cleaned up and is waiting for all 12 DSPs to be synchronized. The 68K (EC) will indicate that synchronization has occured by making the Wake Up Word invalid. (3) Look for a valid Wake Up Word. When a valid Wake Up Word is found, set status to the 68K (EC) which indicates that this Local DSP has found a valid Wake Up Word (4) If the Wake Up Word indicates that this L1.5 Cal Trig Cycle is a Mark and Force Pass, then CALL the Setup Mark and Force Pass routine. This adds the Mark and Force Pass Data to the Local-to Global Transfer DMA List(s) (5) Wait for all ERPB data to arrive. When all ERPB data arrives, set status to the 68K (EC) which indicates that all ERPB data for this Local DSP has arrived (6) Scan through the trigger towers that this Local DSP Node is responsible for (i.e. etas n+2, n+3, n+4, n+5) and look for Trigger Towers with EM Et above the Reference Set (note that only one Reference Set, an EM Et Ref Set, is used in this version of the code). A Trigger Tower with EM Et above reference is called a Seed. Recall that "above reference" really means "equal to or greater than EM Ref Set Et". The order in which Trigger Towers are scanned is FOR phi = 1..32 FOR eta = n+2 to n+5 {Compare to Reference and branch to Tool if necessary} END FOR END FOR When we find a Seed, then we branch to the L15CT Tool code that is used to evaluate the L15CT Term that is under consideration. This tool code is executed BEFORE finishing the scan looking for all of the TT's above reference. The Tool is responsible for making Entries in the Local Object List as appropriate. The Tool is also responsible for building the per-Term Object Counts (in memory) and the Global Object Count (in R2). The Tool does NOT set the Object List Overflow Flag, so that needs to be done in this module if necessary. (7) Once the Object Scan is done, pack the 4 per-Term Object Counts into 2 longwords for transfer to the Global DSP. (8) Wait for the Object Counts from the Previous DSP (if there is a Previous DSP) to arrive. This is done in another module because it is node-specific. Note that this other module will clear the flag which says that a data transfer phase from the Previous DSP has completed, and start the DMA which receives the Object List from the Previous DSP (again, only if there is a Previous DSP). (9) Start the transfer of this LDSP's (and, if extant, the Previous DSP's) Counts to the Next DSP. Set the status to the 68K which indicates that this LDSP has started its part of the Local-to- Global Transfer. >> Note that at this point we have done everything we can to get >> the TRIGGERING information to the Global DSP. Everything else >> involves moving READOUT information. (10) Add the appropriate Header to the Local List of Identified Objects, including setting the Overflow Flag if appropriate. (11) Wait for the Object Count Transfer to the Next DSP to complete. We need to wait for this to complete (and halt) before we know it is safe to touch the DMA Control Registers. Once it has completed and halted clear the flag which says that a phase of the data transfer to the Next DSP has completed. Need to have this flag cleared before we can start the next phase of this data transfer. (12) Wait for the Object List Transfer from the Previous DSP (if there is a Previous DSP) to complete. Again this is done in another module because it is node-specific. We need to wait for this to complete before we know we have all of the information which needs to go to the Next DSP. (13) Start the transfer of this LDSP's (and, if extant, the Previous DSP's) Object List to the Next DSP. (14) Wait for the Object List Transfer to the Next DSP to finish. When finished, set status to the 68K (EC) which indicates that this Local DSP has finished its part(s) of the Local-to-Global Transfer (15) Return to step (1) 6. L_Tl_Np% (Local DSP Tool Ring for eta N plus %) These four modules (one per eta ring) are the Local DSP Tool routines. The appropriate Local Tool ring is branched to (not CALLed!) from the L_Scan routine. This routine performs the "Local Algorithm," decides whether to make an entry in the Local Object List, and then actually makes this entry if it is required. These modules are all identical except for the details of Trigger Tower addressing. All of the identical blocks are performed via macros, making updates to this module relatively simple. This module performs the following functions: 1. Push the Status Register and set the Tool_Accept_Flag. This is done using the START_TOOL macro. 2. Calculate the 1x2 EM Et Sum and 1x2 Total Et Sum. This requires finding the largest EM Et neighbor. 3. Calculate the 3x3 Total Et Sum. For each of the 4 Terms which exist in this version of the code: 4. Compare the 1x2 EM Et Sum to the 1x2 EM Et Threshold, and clear the Tool_Accept_Flag if the 1x2 Em Et Sum is strictly less than the 1x2 EM Et Threshold. Use a signed comparison for this test. This is done using the COMPARE_1X2 macro. 5. Compare the 1x2 Em Et Sum/3x3 Total Et Sum to the Isolation Ratio Threshold. Here, magnitudes must be compared, and a floating point comparison must be used. Clear the Tool_Accept_Flag if the actual ratio is strictly less than the threshold. This is done using the COMPARE_RATIO macro. 6. Compare the 1x2 Em Et Sum/1x2 Total Et Sum to the EM_Fraction Ratio Threshold. Here, magnitudes must be compared, and a floating point comparison must be used. Clear the Tool_Accept_Flag if the actual ratio is strictly less than the threshold. This is done using the COMPARE_RATIO macro. 7. Determine whether the Object under consideration should be written to the Local Object List. It should be written if either the Tool_Accept_Flag is set or if the MFP_Wakeup_Word_Flag is set (indicating that this is a Mark and Force Pass event, and all considered candidates should be saved. This is done using the TOOL_ACCEPT_REJECT macro. 8. If the object is to be written into the Local Object List, then write it (unless it would overflow the Local Object List, in which case a Local Object List Overflow flag is set, and the Object is not written). This is also done within the TOOL_ACCEPT_REJECT macro. 9. After all 4 Terms have been evaluated, then restore the Status Register and then branch back to the correct point in the L_Scan routine. This is done using the END_TOOL macro. Further notes about Local-to-Global Transfer -------------------------------------------- The Local-to-Global transfer requires a considerable amount of time to complete. In the future we might wish to reduce the amount of time required by this transfer. Here are some ways this transfer might be sped up: (1) Reduce the number of objects in the Local List of Identified Objects. - The transfer time will scale directly with the number of Objects in each List. If the list length is cut in half the transfer time will also be cut in half. (2) Give up on the "get all Previous data before sending data to Next" protocol. - If we do this only on DSP #3, we can save 1 time slice (5 us with 8 Objects, 2.5 us with 4 Objects). (3) If we could keep up with more than 2 Comm Ports, the minimum number of time slices required for the transfer would be 4. - Using the CPU rather than the DMA engine we can keep up with 5 Comm Ports - There is the problem of Peripheral Bus hangs if the CPU tries to read from an empty Input FIFO - CPU reads can be tied to interrupts but this slows things down again due to interrupt latency. (4) With some Global algorithms (algorithms that just count), we could use a 2-stage transfer - First transfer the Counts - If readout is required then transfer the rest of the data - This tries to separate triggering from readout but only works if the Global Tool doesn't need all of the data from the Local Tools. (5) We could build a custom hardware interface between the Local DSPs and the Global DSP, to eliminate the Global DSP input bottleneck. This would allow all Local DSPs to transfer their Object Lists (more or less) simultaneously, in a single time slice.