Skip to content

Trigger Link from HcalBackplane on ZCU

Tom Eichlersmith edited this page Jul 22, 2026 · 14 revisions

Set Up

Hardware

The DAQ link from the HcalBackplane is connected to SFP0 and the output from the TRG (trigger) link from the HcalBackplane is connected to the input of SFP1 (below SFP0).

Image of Hcal Backplane with optical fibers connected properly Image of ZCU Quad-SFP-Cage with the optical fibers connected properly

Firmware

A small patch was necessary to the "dualtarget" ZCU firmware necessary in order to confirm that the trigger optical link clock was correctly shared with the daq optical link clock and in order to capture words from the trigger path. Make sure you are on the latest ZCU firmware listed on the firmware page.

Check Word Rates

Connecting via Link 0 with pflpgbt, you can see the "word rate" for the DAQ and TRIG links are the same (as well as the clocks).

$ ./build/pflpgbt --do 0
> OPTO
> FULLSTATUS
Olink: DAQ
Polarity -- TX: 0  RX: 0
Optical status:
  BUFFBYPASS_DONE      : 0x0001
  BUFFBYPASS_ERROR     : 0x0000
  CDR_LOCK             : 0x0deb
  CDR_STABLE           : 0x0000
  LINK_ERRORS          : 0x0003
  NOT_IN_RESET         : 0x0001
  READY                : 0x0001
  RX_RESETDONE         : 0x0001
  TX_RESETDONE         : 0x0001
Optical rates:
  AXIS_clk             : 297.148 MHz (0x488bc)
  CLOCK_40             : 37.144 MHz (0x9118)
  DAQ_LINK_CLOCK       : 297.148 MHz (0x488bc)
  DAQ_LINK_ERROR       : 0.000 MHz (0x0000)
  DAQ_LINK_WORD        : 37.143 MHz (0x9117)
  EXT_REFCLK           : 0.000 MHz (0x0000)
  GTH_REFCLK           : 297.148 MHz (0x488bc)
  RX-LINK              : 297.148 MHz (0x488bc)
  S_AXI_ACLK           : 100.000 MHz (0x186a0)
  TRIG_LINK_CLOCK      : 297.148 MHz (0x488bc)
  TRIG_LINK_ERROR      : 0.000 MHz (0x0000)
  TRIG_LINK_WORD       : 37.144 MHz (0x9118)

This is after

  • using OPTO.RESET and OPTO.LINKTRICK in order to get the DAQ link READY 1
  • applying GENERAL.STANDARD_HCAL to configure the lpGBTs appropriately
    • using a recent version of pflib is necessary here since the TRG lpGBT configuration needed to be updated! PR 415
  • opto.linktrick after using opto.choose to switch to the TRG link

Initialize ECON-T

The configurations stored in pflib are examples that show necessary parts.

  • config/pftool/hcal-backplane-zcu.yaml: define the target (HcalBackplane on ZCU) and which ROCs are active
  • config/econ/econt_hcal_stc.yaml: configure algorithm, formatter buffer, and invert eTx data
    • will need to update which eRx are active according to which ROCs are active
$ ./build/pftool config/pftool/hcal-backplane-zcu.yaml
> ECON
> IECON 1 # switch to ECON-T that has a ROC connected
> LOAD config/econ/econt_hcal_stc.yaml
> RUNMODE
> IECON 2 # can also do the other ECON-T
> LOAD config/econ/econt_hcal_stc.yaml
> RUNMODE
> EXIT

Align ECON-T/ROC

The alignment block that handles tuning the connection between ECON-T and ROCs is the same as the ECON-D, so the task in software only needed to update the mapping.

$ ./build/pftool config/pftool/hcal-backplane-zcu.yaml
> TASKS
> SETUP
> ALIGN_PHASE_WORD
# choose IECON=1 or IECON=2 for which ECON-T has ROCs connected

Align ECON-T/lpGBT

$ ./build/pftool config/pftool/hcal-backplane-zcu.yaml
> TASKS
> SETUP
> ALIGN_ECON_LPGBT
# make sure to do the right IECON as before!
> EXIT

View TRG Data Stream

The ECON-T outputs a known pattern of data when we send a link_reset_econt command to it. The 32b words should contain two copies of the 16b idle word. The 16b idle word is a 5b BX number followed by the 11b idle pattern we configure to be 0x526. The ALIGN_READ command can decode for this pattern to make it easier for you to observe by splitting the 32b words into the BX numbers (shown in decimal) and the idle pattern (shown in hex).

If everything is aligned properly you should see an output that looks like

00 : | 10 526 10 526 | 11 526 11 526 | 12 526 12 526 | 13 526 13 526 | 14 526 14 526 | 15 526 15 526 | 00 526 00 526 | 01 526 01 526
01 : | 10 526 10 526 | 11 526 11 526 | 12 526 12 526 | 13 526 13 526 | 14 526 14 526 | 15 526 15 526 | 00 526 00 526 | 01 526 01 526
02 : | 10 526 10 526 | 11 526 11 526 | 12 526 12 526 | 13 526 13 526 | 14 526 14 526 | 15 526 15 526 | 00 526 00 526 | 01 526 01 526

Key Features:

  • Two copies of the same BX number in each 32b word (separated by |)
  • BX numbers increment by one between 32b words and are modulo 16 (the special BX number of 31 is used to distinguish orbit boundaries)
  • BX numbers are the same across links (rows)
  • idle patterns are all uniformly equal to the expected pattern
> TRIG
> ALIGN_READ
# view eTx streams output by ECON-T

Capture TRG Path Data

Warning

From here forward, software developments are being prepared on the 442-time-in-trg-path branch and will require a to-be-posted firmware update as well.

The default configuration of the firmware has many of these firmware parameters set to zero. You must update them before you can appropriately capture TRG path data.

  • trig.pipeline: how many BX ago we should start the capture
  • trig.samples_per_l1a: number of samples to capture on each L1A
  • trig.presamples: index within the set of samples where the primary sample of interest is (i.e. where we expect "in time" to be)
  • trig.econid: ID number to go with this ECON-T, stored in output header (see below)

The example below is with one ROC connected to one ECON-T that outputs three links. There was no pedestal subtraction being applied on the ROC so the STC sums that are connected to a ROC are relatively large.

 > EVENT_SPY 
10a4040e
13004143
40005020
10080444
a2d148b0
5000d020
10080444
a2d148b0
6000d020
10080444
a2d148b0
70005020
10080444
a2d148b0
econ_id = 41 n_samples = 4
BX STC1 STC2 STC3 STC4 STC5 STC6 STC7 STC8
 4    8    8    8    8  274  278  276  278
 5    8    8    8    8  274  278  276  278
 6    8    8    8    8  274  278  276  278
 7    8    8    8    8  274  278  276  278

Time-In TRG Path Capture

The trig.timein command can deduce the pipeline setting and "time-in" the TRG path data collection by setting the pedestals and thresholds on the ROC to their maxima to make a pulse stand out more in the sums and then injecting a pulse into a known channel.

  • pipeline: 5
  • samples_per_l1a: 8
  • presamples: 1
  • charge_to_l1a: 60
  • roc.l1offset: 48

Self-Trigger on Calibration Pulse

The firmware is unable to temporarily raise the ROC's pedestals and thresholds like the software is, so you must update the ROC configuration to set its pedestals and acceptance thresholds. The pedestals (CH_##.ADC_PEDESTAL or use HALFWISE_#.ADC_PEDESTAL shortcut) are subtracted from the observed value within the ROC on the TRG path while the thresholds (DIGITALHALF_#.ADC_TH) are used to suppress normal fluctuations of the pedestal.

The trigger algorithm settings need to be updated as well. At UMN, we have ROC0 connected and it is directed into STC6 and STC7, so all of the thresholds should be kept at 0 except for thresholds 6 and 7 which should be set to something above 0x8. Even with these settings, the external L1A should not be left on for too long. While I have observed the occupancy stay at 0 without a calib pulse for ~dozen seconds, I have also observed the event buffer of 127 fill up when leaving it one for several minutes.

The trigger decision now needs to be routed through the FC block, so the roc.l1offset and the pipeline need to be increased to account for this extra time. At UMN, we found adding 12 to both aligned allowed you to observe the self-trigger calibration pulse. The self_trigger command in the trig menu allows you to test these settings until you find one that works.

  • pipeline: 17
  • roc.l1offset: 60

Self-Trigger on Cosmics

TBD

Clone this wiki locally