Block Preview

Introduction

Principle of Operation

In analogue mode the PETIROC-2A holds the peak charge of all 32 channels in its internal analogue memories and presents them, one at a time, on a single analogue output. A shift register inside the chip selects which channel is presented: a token is injected on SRIN and walked along by SCLK. On the DT5550W that analogue output is digitised by an external ADC whose 16-bit result arrives at the FPGA as PETIROC_<ASIC>_ADC_ENERGY.

This block owns the whole sequence:

  TRIG ─► inject token on SRIN
        ├─ for 36 shift steps:
        │     SCLK low  (CLKDIV+1 clocks)   ← sample the filtered ADC here
        │     SCLK high (CLKDIV+1 clocks)
        │     advance                       (1 clock)
        └─ latch 32 energies + 32 hits, pulse P_DV, replay the RAZ/VAL reset
  

The ADC conditioning chain

The raw ADC word is never published. Every clock the block computes

$$ f[n] = \mathrm{0x3FFF} - \mathrm{ADC_IN}[n] $$

(an inversion against a 14-bit full scale, because the ASIC’s analogue output swings downwards), pushes it into a shift register and maintains a running sum

$$ \mathrm{acc}[n] = \mathrm{acc}[n-1] + f[n-1] - f[n-32] \quad\Rightarrow\quad \mathrm{acc}[n] = \sum_{k=1}^{32} f[n-k] $$

The published value is acc(20 downto 5), i.e. the sum divided by 32 - a plain 32-tap boxcar average of the inverted ADC stream. This is what both S_ENERGY / P_E_<i> and the free-running monitor M_ENERGY carry. The filter runs continuously, it is not reset between events, so the value latched for a channel is the average of the last 32 ADC samples taken while that channel was selected - which is why the readout must be slow enough for the multiplexer to settle.

Pin Description

TS_IN Input 64 bit BIT VECTOR
Global timestamp in – any 64-bit counter; latched to TS_OUT at the trigger and held for the event. Purely a pipeline stage, the block does not interpret the value.
TS0_IN Input 32 bit BIT VECTOR
Local time code in – any 32-bit counter (typically a T0-referenced counter); latched to TS0_OUT at the trigger.
TRIG Input 1 bit BIT
Start a scan – rising edge, detected by a two-stage synchroniser. Ignored while a scan is in progress (the state machine is not in idle), so triggers arriving during the ~145 µs readout are lost without any flag. Usually driven from OR_CHARGE of the Petiroc Trigger block.
REJECT Input 1 bit BIT
Abort and rearm – while high, forces the state machine back to idle and restarts the RAZ_CHN / VAL_EVT reset sequence. Evaluated every clock, outside the state machine, so it wins over any state. No output is published for the aborted event.
Default: 0
TS_OUT Output 64 bit BIT VECTOR
Global timestamp out – TS_IN frozen at the trigger, stable for the whole readout and until the next trigger. Pair it with P_DV.
TS0_OUT Output 32 bit BIT VECTOR
Local time code out – TS0_IN frozen at the trigger.
S_CHID Output 5 bit BIT VECTOR
Serial channel index – 0…31, valid with S_DV. Counts the ASIC shift steps after the discarded first one.
S_ENERGY Output 16 bit BIT VECTOR
Serial energy – the 32-tap moving average of 0x3FFF - ADC for the channel named by S_CHID, valid with S_DV. Larger value = larger charge (the inversion is already applied).
S_HIT Output 1 bit BIT
Serial hit flag – the ASIC’s charge-hit line sampled at the same instant as S_ENERGY, valid with S_DV. Tells you whether that channel was over the charge threshold, independently of the digitised amplitude.
S_DV Output 1 bit BIT
Serial data valid – one-clock pulse per channel, 32 pulses per event, spaced by 2·CLKDIV+3 clocks. Emitted at the sampling instant, one clock before SCLK rises.
P_E_0 Output 16 bit BIT VECTOR
Channel 0 energy – latched at the end of the scan, valid with P_DV, held until the next event. Same value that channel 0 carried on S_ENERGY.
P_H_0 Output 1 bit BIT
Channel 0 hit flag – latched with P_E_0, valid with P_DV.
P_E_1 Output 16 bit BIT VECTOR
Channel 1 energy – see P_E_0.
P_H_1 Output 1 bit BIT
Channel 1 hit flag – see P_H_0.
P_E_2 Output 16 bit BIT VECTOR
Channel 2 energy – see P_E_0.
P_H_2 Output 1 bit BIT
Channel 2 hit flag – see P_H_0.
P_E_3 Output 16 bit BIT VECTOR
Channel 3 energy – see P_E_0.
P_H_3 Output 1 bit BIT
Channel 3 hit flag – see P_H_0.
P_E_4 Output 16 bit BIT VECTOR
Channel 4 energy – see P_E_0.
P_H_4 Output 1 bit BIT
Channel 4 hit flag – see P_H_0.
P_E_5 Output 16 bit BIT VECTOR
Channel 5 energy – see P_E_0.
P_H_5 Output 1 bit BIT
Channel 5 hit flag – see P_H_0.
P_E_6 Output 16 bit BIT VECTOR
Channel 6 energy – see P_E_0.
P_H_6 Output 1 bit BIT
Channel 6 hit flag – see P_H_0.
P_E_7 Output 16 bit BIT VECTOR
Channel 7 energy – see P_E_0.
P_H_7 Output 1 bit BIT
Channel 7 hit flag – see P_H_0.
P_E_8 Output 16 bit BIT VECTOR
Channel 8 energy – see P_E_0.
P_H_8 Output 1 bit BIT
Channel 8 hit flag – see P_H_0.
P_E_9 Output 16 bit BIT VECTOR
Channel 9 energy – see P_E_0.
P_H_9 Output 1 bit BIT
Channel 9 hit flag – see P_H_0.
P_E_10 Output 16 bit BIT VECTOR
Channel 10 energy – see P_E_0.
P_H_10 Output 1 bit BIT
Channel 10 hit flag – see P_H_0.
P_E_11 Output 16 bit BIT VECTOR
Channel 11 energy – see P_E_0.
P_H_11 Output 1 bit BIT
Channel 11 hit flag – see P_H_0.
P_E_12 Output 16 bit BIT VECTOR
Channel 12 energy – see P_E_0.
P_H_12 Output 1 bit BIT
Channel 12 hit flag – see P_H_0.
P_E_13 Output 16 bit BIT VECTOR
Channel 13 energy – see P_E_0.
P_H_13 Output 1 bit BIT
Channel 13 hit flag – see P_H_0.
P_E_14 Output 16 bit BIT VECTOR
Channel 14 energy – see P_E_0.
P_H_14 Output 1 bit BIT
Channel 14 hit flag – see P_H_0.
P_E_15 Output 16 bit BIT VECTOR
Channel 15 energy – see P_E_0.
P_H_15 Output 1 bit BIT
Channel 15 hit flag – see P_H_0.
P_E_16 Output 16 bit BIT VECTOR
Channel 16 energy – see P_E_0.
P_H_16 Output 1 bit BIT
Channel 16 hit flag – see P_H_0.
P_E_17 Output 16 bit BIT VECTOR
Channel 17 energy – see P_E_0.
P_H_17 Output 1 bit BIT
Channel 17 hit flag – see P_H_0.
P_E_18 Output 16 bit BIT VECTOR
Channel 18 energy – see P_E_0.
P_H_18 Output 1 bit BIT
Channel 18 hit flag – see P_H_0.
P_E_19 Output 16 bit BIT VECTOR
Channel 19 energy – see P_E_0.
P_H_19 Output 1 bit BIT
Channel 19 hit flag – see P_H_0.
P_E_20 Output 16 bit BIT VECTOR
Channel 20 energy – see P_E_0.
P_H_20 Output 1 bit BIT
Channel 20 hit flag – see P_H_0.
P_E_21 Output 16 bit BIT VECTOR
Channel 21 energy – see P_E_0.
P_H_21 Output 1 bit BIT
Channel 21 hit flag – see P_H_0.
P_E_22 Output 16 bit BIT VECTOR
Channel 22 energy – see P_E_0.
P_H_22 Output 1 bit BIT
Channel 22 hit flag – see P_H_0.
P_E_23 Output 16 bit BIT VECTOR
Channel 23 energy – see P_E_0.
P_H_23 Output 1 bit BIT
Channel 23 hit flag – see P_H_0.
P_E_24 Output 16 bit BIT VECTOR
Channel 24 energy – see P_E_0.
P_H_24 Output 1 bit BIT
Channel 24 hit flag – see P_H_0.
P_E_25 Output 16 bit BIT VECTOR
Channel 25 energy – see P_E_0.
P_H_25 Output 1 bit BIT
Channel 25 hit flag – see P_H_0.
P_E_26 Output 16 bit BIT VECTOR
Channel 26 energy – see P_E_0.
P_H_26 Output 1 bit BIT
Channel 26 hit flag – see P_H_0.
P_E_27 Output 16 bit BIT VECTOR
Channel 27 energy – see P_E_0.
P_H_27 Output 1 bit BIT
Channel 27 hit flag – see P_H_0.
P_E_28 Output 16 bit BIT VECTOR
Channel 28 energy – see P_E_0.
P_H_28 Output 1 bit BIT
Channel 28 hit flag – see P_H_0.
P_E_29 Output 16 bit BIT VECTOR
Channel 29 energy – see P_E_0.
P_H_29 Output 1 bit BIT
Channel 29 hit flag – see P_H_0.
P_E_30 Output 16 bit BIT VECTOR
Channel 30 energy – see P_E_0.
P_H_30 Output 1 bit BIT
Channel 30 hit flag – see P_H_0.
P_E_31 Output 16 bit BIT VECTOR
Channel 31 energy – see P_E_0.
P_H_31 Output 1 bit BIT
Channel 31 hit flag – see P_H_0.
P_DV Output 1 bit BIT
Parallel data valid – one-clock pulse at the end of the scan, when all 32 P_E_* / P_H_* pairs and the frozen timestamps are simultaneously valid. One pulse per accepted trigger.
BUSY Output 1 bit BIT
Dead time – high from the accepted trigger until the last shift step. Triggers arriving while it is high are discarded. Integrate it to measure the live-time fraction.
M_ENERGY Output 16 bit BIT VECTOR
Monitor: filtered ADC – the 32-tap moving average of 0x3FFF - ADC_IN, free-running, independent of the state machine. Wire it to an oscilloscope block to watch the multiplexed analogue signal and to check that the readout is slow enough for each channel to settle.
M_CLK Output 1 bit BIT
Monitor: shift clock – a copy of the SCLK line driven to the ASIC. Useful as a trigger/qualifier when looking at M_ENERGY on a scope block.
M_DIN Output 1 bit BIT
Monitor: token line – a copy of the SRIN line driven to the ASIC. High from the trigger until the last shift step.

Properties

Property window

ASIC ASIC

Select the ASIC to be connected to the Endpoint

Selects the PETIROC-2A this readout engine is bound to. The letter is pasted into the board-support signal names emitted by CompileHDL: PETIROC_<ASIC>_ADC_ENERGY (16-bit ADC word), PETIROC_<ASIC>_CHARGE_HIT_s, PETIROC_<ASIC>_SRIN_s, PETIROC_<ASIC>_SCLK_s, <ASIC>_VAL_EVT_s, <ASIC>_RAZ_CHN_s.

Value Board ADC channel wired to ADC_IN
A ADC_A1
B ADC_A3
C ADC_A5
D ADC_A7

Hidden (isVisible = False): the board plug-in sets it when the block is placed.

Default: A

Default: A

Options: A B C D

Readout Frequency (KHz) ReadoutFrequency

Set the readout frequency for the chip. Value higher than 500KHz reduce the quality of the measure

Nominal rate of the analogue multiplexer shift clock, in kHz. It is turned into the CLKDIV generic as CLKDIV = 160000 / ReadoutFrequency, and the state machine then spends CLKDIV+1 clocks per half bit, so the true shift rate is f_clk / (2·CLKDIV + 3) - see the alert in the description about the factor-two difference and the hard-coded 160 MHz assumption.

Setting (kHz) CLKDIV Real shift rate at 160 MHz Scan duration
1 160000 ≈ 0.5 kHz ≈ 72 ms
10 16000 ≈ 5 kHz ≈ 7.2 ms
50 3200 ≈ 25 kHz ≈ 1.4 ms
100 1600 ≈ 50 kHz ≈ 720 µs
200 800 ≈ 100 kHz ≈ 360 µs
400 400 ≈ 199 kHz ≈ 181 µs
500 320 ≈ 249 kHz ≈ 145 µs
1000 160 ≈ 496 kHz ≈ 73 µs
2500 64 ≈ 1.22 MHz ≈ 29 µs
4000 40 ≈ 1.93 MHz ≈ 19 µs
5000 32 ≈ 2.39 MHz ≈ 15 µs

The block’s own description warns that “value higher than 500 KHz reduce the quality of the measure”: above that the 32-tap moving average has not yet flushed the previous channel when the sample is taken, so adjacent channels bleed into each other. Scan duration above is 36 × (2·CLKDIV+3) clocks and sets the dead time per event.

Hidden (isVisible = False) in the current version.

Default: 500

Default: 500

Options: 1 10 50 100 200 400 500 1000 2500 4000 5000

⚙️ Detailed Operation

Readout clock rate

CompileHDL passes one generic:

vb
  Component.AddGenericInteger("CLKDIV", 160000 / ReadoutFrequency)
  

with ReadoutFrequency in kHz, so CLKDIV = 160000 / f_readout[kHz] (500 kHz → 320). The state machine spends CLKDIV+1 clocks with SCLK low, CLKDIV+1 clocks with SCLK high and one more clock to advance, so the real shift-register period is

$$ T_{bit} = (2,\mathrm{CLKDIV} + 3)\ \text{clock cycles},\qquad f_{bit} = \frac{f_{clk}}{2,\mathrm{CLKDIV}+3} $$

A full event therefore takes about 36 × (2·CLKDIV+3) clocks (≈ 23 150 clocks ≈ 145 µs at the default settings), plus 31 clocks for the channel-reset sequence.

The 36-step scan

Step What happens
trigger SRIN raised (token injected), BUSY high, TS_IN/TS0_IN latched, bit counter = 35, skip flag set
steps 1…36 one SCLK cycle each; the filtered ADC value and CHARGE_HIT are sampled one clock before SCLK rises
step 1 discarded (the skip flag): the multiplexer output is not valid yet
steps 2…33 channels 0…31 → serial stream and internal buffer
steps 34…36 sampled into the buffer but never published
end 32 energy/hit pairs driven onto P_E_*/P_H_*, P_DV pulsed one clock, SRIN lowered, reset sequence restarted

SRIN is held high from the trigger until the last shift step, so the token is present on the ASIC shift register for the whole scan.

Two output styles, same data

  • Serial (S_CHID, S_ENERGY, S_HIT, S_DV): one S_DV pulse per channel, 32 pulses per event, spaced by T_bit. S_CHID carries the channel index 0…31. Cheap in logic - feed it straight into a histogrammer, a spectrum block or a list-mode packet builder.
  • Parallel (P_E_0…31, P_H_0…31, P_DV): all 32 energies and hit flags presented simultaneously, one P_DV pulse per event, at the end of the scan. Costs 544 wires but lets you do per-event logic (sum, maximum, centroid, multiplicity) in one clock.

Both are produced from the same buffer, so they always agree; use whichever fits the downstream block, or both.

The RAZ_CHN / VAL_EVT reset sequence

Identical to the one in Petiroc Digital. After reset, after every scan and on every REJECT, an 8-bit counter is loaded with 0x1F and counts down:

Counter value RAZ_CHN VAL_EVT
0x1F 1 0
0x15 0 0
0x07 1 0
0x00 (stops) 1 1

a 14-clock low pulse on RAZ_CHN that clears the analogue memories, then VAL_EVT high (the chip is armed) until the next event.

Timestamp pass-through

TS_IN/TS0_IN are copied to TS_OUT/TS0_OUT at the trigger and held for the whole readout. The block does not generate time codes of its own - it just freezes whatever counters you feed it so the energies and the time of the event stay together through the rest of the pipeline. Leave them open if you do not need them.

Monitor outputs

M_ENERGY, M_CLK and M_DIN are unconditional copies of the internal filtered ADC value, the shift clock and the token line. They are free-running (not gated by the state machine), which makes them useful for an oscilloscope block: put M_ENERGY on a scope to see the multiplexed analogue baseline in real time and to set the ReadoutFrequency slow enough that each channel’s plateau is flat before it is sampled.

Failure modes

There is no ValidateSettings and no compile-time check on this block; the only message it prints is the informational Generating HDL code For <designator>. Symptoms to recognise in hardware:

  • All channels identical / smeared – readout too fast: the 32-tap average still contains samples from the previous channel. Lower ReadoutFrequency.
  • Energies offset by one channel – the discarded first step is what aligns the token with channel 0; if the ASIC shift register is configured differently the whole map shifts.
  • BUSY stuck high – the state machine never left the scan; assert REJECT (or the global reset) to force it back to idle.

Resources & Timing

  • Latency: One scan = 36 × (2·CLKDIV + 3) clock cycles from the trigger to P_DV, plus 31 clocks of channel-reset sequence before the block is armed again.

  • Throughput: One event per scan; at the default 500 kHz setting on a 160 MHz clock that is ≈ 145 µs of dead time per event (≈ 6.9 kevents/s maximum).

  • S_DV pulses arrive one per 2·CLKDIV+3 clocks during the scan; P_DV pulses once at the end.
  • The ADC moving-average filter is 32 taps deep and never reset, so it also imposes a 32-clock settling time on M_ENERGY after any step on the analogue input.