Block Preview

Introduction

Principle of Operation

The CITIROC 1A holds the peak charge of its 32 channels in two analog memories, a high-gain (HG) and a low-gain (LG) one. Those memories are not addressable: the chip exposes them through an internal shift register that is advanced one position per clock on SR_IN / SCLK, and the currently selected channel is presented on a single analog output that the board digitises with an external ADC.

This block owns that whole sequence for one ASIC (A, B, C or D):

  1. detect the rising edge of TRIG;
  2. wait HOLD_TIME clock cycles so the shaper reaches its peak;
  3. assert HOLD_HG / HOLD_LG, freezing the analog memories;
  4. reset and then step the ASIC charge shift register, one slot at a time;
  5. sample the (filtered) ADC word at each slot;
  6. release the hold, run the channel-reset (RAZ_CHN) sequence and return to idle.

The ADC is never read raw. A 32-tap running boxcar is applied continuously to both ADC inputs, and the readout stores the filtered value:

$$ \widehat{E}[n] ;=; \left\lfloor \frac{1}{32}\sum_{k=0}^{31} \mathrm{ADC}[n-k] \right\rfloor $$

implemented as a 24-bit running accumulator whose bits [20:5] are taken as the 16-bit result (a plain truncation — there is no rounding term in this version).

The block is a board pin block: the ASIC control wires (SR_IN, SCLK, RESET_READ, VAL_EVT, RAZ_CHN, HOLD_HG, HOLD_LG) and the two 16-bit ADC buses are bound automatically to the Citiroc_<ASIC>_* board nets by the ASIC property. They are not drawn as pins on the canvas.

Pin Description

TS_IN Input 64 bit BIT VECTOR
Global timestamp in – free-running 64-bit time counter. Latched into TS_OUT at the accepted trigger edge.
TS0_IN Input 32 bit BIT VECTOR
Run/T0 timestamp in – 32-bit counter, latched into TS0_OUT at the accepted trigger edge. This is the value the frame decoder reports as Time_Code.
TRIG Input 1 bit BIT
Trigger – rising-edge sensitive. A 0 → 1 transition while the block is idle starts an event. While it is held high in idle the block asserts the ASIC channel reset RAZ_CHN, so a permanently high trigger keeps the ASIC in reset instead of free-running.
REJECT Input 1 bit BIT
Abort – sampled in every state. High aborts the event in progress: the FSM jumps to the ASIC-reset state and emits no P_DV / P_FRAME_DV. Tie low if unused.
P_FRAME_ACK Input 1 bit BIT
Frame acknowledge – when high, clears P_FRAME_DV. Drive it from the ACK_x output of the Citiroc Frame Transfer block. Left unconnected, P_FRAME_DV latches high after the first event and never releases.
HOLD_TIME Input 16 bit BIT VECTOR
Trigger-to-hold delay, in clock cycles, applied between the accepted trigger edge and the assertion of HOLD_HG / HOLD_LG. Set it to the peaking time of the CITIROC shaper expressed in global-clock periods. This is a runtime bus, so it can be driven from a register and tuned without recompiling.
TS_OUT Output 64 bit BIT VECTOR
Global timestamp of the event – TS_IN frozen at the trigger edge, held stable for the whole readout. Feed it to TS_x of the Citiroc Frame Transfer block.
TS0_OUT Output 32 bit BIT VECTOR
Run timestamp of the event – TS0_IN frozen at the trigger edge. Feed it to TS_T0_x of the Citiroc Frame Transfer block.
S_CHID Output 5 bit BIT VECTOR
Serial channel index – 0…31, valid while S_DV is high. Identifies which channel the current S_ENERGY_* / S_HIT word belongs to.
S_ENERGY_LG Output 16 bit BIT VECTOR
Serial low-gain charge – boxcar-filtered ADC value of the channel named by S_CHID, valid while S_DV is high.
S_ENERGY_HG Output 16 bit BIT VECTOR
Serial high-gain charge – boxcar-filtered ADC value of the channel named by S_CHID, valid while S_DV is high.
S_HIT Output 1 bit BIT
Serial hit flag – the ASIC CHARGE_HIT discriminator sampled at the same instant as the energy pair. Valid while S_DV is high.
S_DV Output 1 bit BIT
Serial data valid – one-cycle pulse per channel, 32 pulses per event, issued as the shift register is walked. The natural input for a per-channel spectrum or list-mode block.
P_E_LG_0 Output 16 bit BIT VECTOR
First of a 32-pin bus. Parallel low-gain charge, one pin per channel. Updated together with the high-gain set, qualified by P_DV.
P_E_HG_0 Output 16 bit BIT VECTOR
First of a 32-pin bus. Parallel high-gain charge, one pin per channel. All 32 are updated simultaneously at the end of the readout and stay stable until the next event. Qualify them with P_DV.
P_H_0 Output 1 bit BIT
First of a 32-pin bus. Parallel hit flag, one pin per channel – the CHARGE_HIT state captured while that channel was being shifted out.
P_E_LG_1 Output 16 bit BIT VECTOR
P_E_HG_1 Output 16 bit BIT VECTOR
P_H_1 Output 1 bit BIT
P_E_LG_2 Output 16 bit BIT VECTOR
P_E_HG_2 Output 16 bit BIT VECTOR
P_H_2 Output 1 bit BIT
P_E_LG_3 Output 16 bit BIT VECTOR
P_E_HG_3 Output 16 bit BIT VECTOR
P_H_3 Output 1 bit BIT
P_E_LG_4 Output 16 bit BIT VECTOR
P_E_HG_4 Output 16 bit BIT VECTOR
P_H_4 Output 1 bit BIT
P_E_LG_5 Output 16 bit BIT VECTOR
P_E_HG_5 Output 16 bit BIT VECTOR
P_H_5 Output 1 bit BIT
P_E_LG_6 Output 16 bit BIT VECTOR
P_E_HG_6 Output 16 bit BIT VECTOR
P_H_6 Output 1 bit BIT
P_E_LG_7 Output 16 bit BIT VECTOR
P_E_HG_7 Output 16 bit BIT VECTOR
P_H_7 Output 1 bit BIT
P_E_LG_8 Output 16 bit BIT VECTOR
P_E_HG_8 Output 16 bit BIT VECTOR
P_H_8 Output 1 bit BIT
P_E_LG_9 Output 16 bit BIT VECTOR
P_E_HG_9 Output 16 bit BIT VECTOR
P_H_9 Output 1 bit BIT
P_E_LG_10 Output 16 bit BIT VECTOR
P_E_HG_10 Output 16 bit BIT VECTOR
P_H_10 Output 1 bit BIT
P_E_LG_11 Output 16 bit BIT VECTOR
P_E_HG_11 Output 16 bit BIT VECTOR
P_H_11 Output 1 bit BIT
P_E_LG_12 Output 16 bit BIT VECTOR
P_E_HG_12 Output 16 bit BIT VECTOR
P_H_12 Output 1 bit BIT
P_E_LG_13 Output 16 bit BIT VECTOR
P_E_HG_13 Output 16 bit BIT VECTOR
P_H_13 Output 1 bit BIT
P_E_LG_14 Output 16 bit BIT VECTOR
P_E_HG_14 Output 16 bit BIT VECTOR
P_H_14 Output 1 bit BIT
P_E_LG_15 Output 16 bit BIT VECTOR
P_E_HG_15 Output 16 bit BIT VECTOR
P_H_15 Output 1 bit BIT
P_E_LG_16 Output 16 bit BIT VECTOR
P_E_HG_16 Output 16 bit BIT VECTOR
P_H_16 Output 1 bit BIT
P_E_LG_17 Output 16 bit BIT VECTOR
P_E_HG_17 Output 16 bit BIT VECTOR
P_H_17 Output 1 bit BIT
P_E_LG_18 Output 16 bit BIT VECTOR
P_E_HG_18 Output 16 bit BIT VECTOR
P_H_18 Output 1 bit BIT
P_E_LG_19 Output 16 bit BIT VECTOR
P_E_HG_19 Output 16 bit BIT VECTOR
P_H_19 Output 1 bit BIT
P_E_LG_20 Output 16 bit BIT VECTOR
P_E_HG_20 Output 16 bit BIT VECTOR
P_H_20 Output 1 bit BIT
P_E_LG_21 Output 16 bit BIT VECTOR
P_E_HG_21 Output 16 bit BIT VECTOR
P_H_21 Output 1 bit BIT
P_E_LG_22 Output 16 bit BIT VECTOR
P_E_HG_22 Output 16 bit BIT VECTOR
P_H_22 Output 1 bit BIT
P_E_LG_23 Output 16 bit BIT VECTOR
P_E_HG_23 Output 16 bit BIT VECTOR
P_H_23 Output 1 bit BIT
P_E_LG_24 Output 16 bit BIT VECTOR
P_E_HG_24 Output 16 bit BIT VECTOR
P_H_24 Output 1 bit BIT
P_E_LG_25 Output 16 bit BIT VECTOR
P_E_HG_25 Output 16 bit BIT VECTOR
P_H_25 Output 1 bit BIT
P_E_LG_26 Output 16 bit BIT VECTOR
P_E_HG_26 Output 16 bit BIT VECTOR
P_H_26 Output 1 bit BIT
P_E_LG_27 Output 16 bit BIT VECTOR
P_E_HG_27 Output 16 bit BIT VECTOR
P_H_27 Output 1 bit BIT
P_E_LG_28 Output 16 bit BIT VECTOR
P_E_HG_28 Output 16 bit BIT VECTOR
P_H_28 Output 1 bit BIT
P_E_LG_29 Output 16 bit BIT VECTOR
P_E_HG_29 Output 16 bit BIT VECTOR
P_H_29 Output 1 bit BIT
P_E_LG_30 Output 16 bit BIT VECTOR
P_E_HG_30 Output 16 bit BIT VECTOR
P_H_30 Output 1 bit BIT
P_E_LG_31 Output 16 bit BIT VECTOR
P_E_HG_31 Output 16 bit BIT VECTOR
P_H_31 Output 1 bit BIT
P_DV Output 1 bit BIT
Parallel data valid – single-cycle pulse marking the instant all 96 parallel pins have been refreshed with a new event.
P_FRAME_DATA Output 1024 bit BIT VECTOR
Packed event frame – 32 channel words of 32 bits, channel 0 in the most significant word (bits 1023:992), channel 31 in the least significant (bits 31:0). Word layout: [31:29]=000, [28]=HIT, [27:14]=LG, [13:0]=HG. Connect it straight to DATA_x of the Citiroc Frame Transfer block, which serialises it LSW-first — so channel 31 reaches the PC first.
P_FRAME_DV Output 1 bit BIT
Frame data valid – level signal, raised when P_FRAME_DATA is refreshed and cleared by P_FRAME_ACK. It is the request half of the frame handshake.
BUSY Output 1 bit BIT
Busy – high from the accepted trigger edge until the readout FSM returns to idle. Use it to veto the trigger generator and to measure live time.
M_ENERGY_LG Output 16 bit BIT VECTOR
Monitor, low gain – continuous filtered LG ADC value, free running.
M_ENERGY_HG Output 16 bit BIT VECTOR
Monitor, high gain – continuous output of the 32-tap boxcar filter on the HG ADC. Free running, not gated by the readout; for scoping the baseline and the pulse.
M_CLK Output 1 bit BIT
Monitor of SCLK – copy of the shift-register clock the block drives into the ASIC. Useful to confirm the real readout frequency on a logic analyser.
M_DIN Output 1 bit BIT
Monitor of SR_IN – copy of the token bit injected into the ASIC charge shift register at the start of a readout.

Properties

Property window

ASIC ASIC

Select the ASIC to be connected to the Endpoint

Selects which of the four CITIROC 1A chips on the board this instance drives. It does not change any pin; it renames the internal board nets the block binds to (Citiroc_<ASIC>_ADC_ENERGY_HG/LG, Citiroc_<ASIC>_CHARGE_HIT_s, Citiroc_<ASIC>_SRIN_s, Citiroc_<ASIC>_SCLK_s, Citiroc_<ASIC>_RESET_READ_s, <ASIC>_VAL_EVT_s, <ASIC>_RAZ_CHN_s, <ASIC>_HOLD_HG_s, <ASIC>_HOLD_LG_s).

Value ASIC
A chip A
B chip B
C chip C
D chip D

Two instances must never carry the same value — they would both drive the same SCLK / HOLD nets.

This property is flagged isVisible = False in the component definition, so it is not shown in the standard property dialog.

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 ASIC readout frequency in kHz. It sets the only generic of the instantiated entity: CLKDIV = 160000 / ReadoutFrequency, and one shift-register step costs 2·(CLKDIV+1) global-clock cycles.

Value (kHz) CLKDIV
1 160000
10 16000
50 3200
100 1600
200 800
400 400
500 320
1000 160
2500 64
4000 40
5000 32

Per the property description in the component, values above 500 kHz degrade the quality of the measurement. Note that the constant 160000 is hard-coded in CompileHDL: the project global clock frequency is read into a local variable but is not used, so changing the design clock does not change CLKDIV.

This property is flagged isVisible = False in the component definition, so it is not shown in the standard property dialog.

Default: 500

Default: 500

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

⚙️ Detailed Operation

Emitted HDL

CompileHDL writes the embedded resource CitirocAnalogReadout.vhd (entity CITIROCAnalogReadout) to pcores/CitirocAnalogReadout.vhd and instantiates it with a single generic:

Generic Value written by the compiler
CLKDIV 160000 / ReadoutFrequency (integer division, ReadoutFrequency in kHz)

The entity also declares a TRIGGER_HOLD_DELAY generic and a CHIP_TEMP output port; neither is driven or mapped by the compiler. TRIGGER_HOLD_DELAY keeps its VHDL default and is dead code — the hold delay comes from the HOLD_TIME pin, not from the generic.

Readout state machine

   TRIG ↑
   │
   ▼
 [0] idle ──► [1] wait HOLD_TIME ──► [2] SR reset low ──► [3] 5 clk ──► [4][5] ──►
 [6] first SCLK edge ──► ┌─► [7] SCLK low  (CLKDIV+1 clk) ─┐
                         │                                  │  35 slots
                         └── [8] SCLK high (CLKDIV+1 clk) ◄─┘  (sample here)
                                       │ slot 34
                                       ▼
 [9] publish outputs ──► [A] RAZ_CHN pulse ──► [B] dead time ──► [0]
  
  • TRIG is edge sensitive: the machine leaves idle on a 0 → 1 transition only. While TRIG stays high in idle, RAZ_CHN is held asserted (continuous channel reset).
  • Each shift-register step takes 2·(CLKDIV+1) clock cycles (states 7 and 8), so the shift clock produced on SCLK is $f_{\mathrm{SCLK}} = f_{\mathrm{clk}} / \left(2,(\mathrm{CLKDIV}+1)\right)$.
  • At each step the current filtered HG/LG pair and CHARGE_HIT are latched into an internal 35-entry buffer.

The 35 shift-register slots

The ASIC shift register is longer than the 32 channels. The FSM walks 35 slots and treats them differently:

Slot I Meaning Where it goes
0 … 31 channel 0 … 31 serial stream (S_*), parallel pins, frame word
32 chip temperature internal CHIP_TEMP port only
33 dummy cycle discarded
34 last step, exits the loop discarded

Serial output (S_*)

During slots 0…31 the block emits one word per channel:

 

S_DV is a single-cycle pulse; S_CHID (5 bit) says which channel the word belongs to. S_HIT is the ASIC CHARGE_HIT discriminator state sampled at the same instant.

Parallel output (P_*) and the packed frame

When the last slot has been read, state 9 publishes everything at once:

  • the 32 P_E_HG_n / P_E_LG_n / P_H_n triplets, with a one-cycle P_DV pulse;
  • the 1024-bit P_FRAME_DATA bus, with P_FRAME_DV raised and held.

P_FRAME_DATA is 32 concatenated 32-bit channel words. Channel 0 occupies the most significant word (bits 1023:992) and channel 31 the least significant (bits 31:0). Each 32-bit word is:

Bits Field Width
31:29 "000" (reserved, always zero) 3
28 HIT — the channel discriminator 1
27:14 LG charge 14
13:0 HG charge 14

Frame handshake

P_FRAME_DV is level, not a pulse. It goes high in state 9 and is cleared only when P_FRAME_ACK is seen high:

 

This is what lets the round-robin arbiter inside Citiroc Frame Transfer poll the four ASICs one after the other without losing an event. If P_FRAME_ACK is left unconnected, P_FRAME_DV stays high forever after the first event.

Timestamps

TS_IN (64 bit) and TS0_IN (32 bit) are simply latched and forwarded to TS_OUT / TS0_OUT at the instant the trigger edge is accepted. The block does not generate or increment them — it only freezes the free-running counters that feed it, so that the timestamp travelling with the event is the trigger time, not the end-of-readout time.

Abort: REJECT

REJECT is tested every clock cycle, in every state. When it is high the FSM jumps straight to the ASIC-reset state and restarts the RAZ_CHN sequence. No P_DV, no P_FRAME_DV and no further S_DV are produced for that event — the event is discarded in flight. Use it with a pile-up or veto detector to kill a bad event before paying the full readout dead time.

Dead time

The dominant term is the shift-register walk:

$$ T_{\mathrm{dead}} ;\approx; \mathrm{HOLD_TIME} ;+; 35 \cdot 2,(\mathrm{CLKDIV}+1) ;+; \mathcal{O}(50) ;; \text{clock cycles} $$

With the default ReadoutFrequency = 500 (so CLKDIV = 320) on the 160 MHz global clock of the DT5550W-Citiroc1A this is about 22 500 clocks ≈ 140 µs per event, and the shift clock actually produced is $160,\mathrm{MHz}/642 \approx 249$ kHz.

Monitor outputs

M_ENERGY_HG / M_ENERGY_LG are the continuous output of the boxcar filter — they are not gated by the readout and are live at all times. M_CLK and M_DIN mirror the SCLK and SR_IN wires the block drives into the ASIC. All four are intended for a logic analyser or an oscilloscope block, to debug the readout sequence without probing the hardware.

Typical wiring

   Citiroc Trigger ──TRIG──►┌──────────────────┐──P_FRAME_DATA──►┌────────────────┐
 Timestamp ct. ──TS_IN───►│  Citiroc Analog  │──P_FRAME_DV────►│ Citiroc Frame  │──► PC
               ──TS0_IN──►│     (ASIC A)     │◄─P_FRAME_ACK────│   Transfer     │
 pile-up det.  ──REJECT──►│                  │──TS_OUT/TS0_OUT►│                │
 constant      ─HOLD_TIME►└──────────────────┘                 └────────────────┘
  

One instance per ASIC; set the ASIC property of each instance to A, B, C, D so that each one binds to its own set of Citiroc_<ASIC>_* board nets.

Resources & Timing

  • Latency: Trigger edge to P_DV ≈ HOLD_TIME + 35·2·(CLKDIV+1) clock cycles (≈140 µs at the default 500 kHz setting on a 160 MHz clock)

  • Throughput: One event per readout cycle; BUSY is high for the whole cycle and no new trigger is accepted while it is high

  • Emits pcores/CitirocAnalogReadout.vhd (entity CITIROCAnalogReadout), the plain CitirocAnalogReadout.vhd resource — not the _NEW variant, which belongs to the V2 block.
  • No memory-mapped registers and no SDK code: CompileMMC and CompileSDK are empty. Everything software-visible comes from the downstream Citiroc Frame Transfer block.
  • 32-tap boxcar on both ADC inputs, truncated (no rounding); 24-bit accumulator, result taken from bits [20:5].
  • The chip temperature is digitised at shift-register slot 32 but is not reachable from any pin.
  • Supported board: DT5550W-Citiroc1A (97567308-DA16-4E48-BB5E-ACE3E84DF06D). Not available inside subpages or state machines.