; $Id$: ;############################################################## ;# ;# Cosmic mode, send 1 "tracklet" from CPU3 ;# ;# accumulate the total charge and the number of hits ;# ;# from the fitregister ;# ;# The tracklet is composed so: ;# ;# (Qtot << 24) | (Qthr << 16) | (Nhits << 8) | (COSMIC_MIN_HITS << 3) | Q_SHR(dyn) ;# where Qtot is Qmeasured >> Q_SHR(dyn) ;# Qthr is COSMIC_Q_THR >> Q_SHR(dyn) ;# Q_SHR(dyn) is from 0 to 7 auto selected (smallest, so that Qtot < 0x100) ;# ;# OLD: ;# ;# (Qtot << 24) | (Qthr << 16) | (Nhits << 8) | (COSMIC_MIN_HITS << 3) | COSMIC_Q_SHR ;# where Qtot is Qmeasured >> COSMIC_Q_SHR ;# Qthr is COSMIC_Q_THR >> COSMIC_Q_SHR ;# COSMIC_Q_SHR is fixed ;# ;############################################################## acq: SEM b1111_0000 #ifdef cpu0 ; switch on the NIICE lvds cells mov 1, r0 sgio r0, NIICE nop #endif ; bypass the automatic selection of the fit-registers #ifdef cpu1 mov 0, r0 IEXT TPCBY SGIO r0, TPCBY #endif #ifdef cpu2 nop nop nop #endif #ifdef cpu3 mov TPFP_VAL, r5 ; Filtered Pedestal, with 2 additional bits (x4) mul32 r5, 3, r5 ; 3 channels in the hit-charge, this value/4 must be subtracted for each hit nop #endif iext TPCI mov TPCI, r1 ; addres in the GIO with the lower channel number when the auto-select is disabled mov COS_BEG_CH, r2 ; start channel, different for the 4 CPUs #ifdef cpu3 mov AddrDM_Cos, r15 ; start address in DMEM for debug information #else nop #endif jmpr cc_busy, 0 sgio r2, r1 mov 0, r6 ; clear hit accu mov 0, r7 ; clear charge accu ; r1 is TPCIx (address), r2 is the selected channel (and loop index) acq_cosmic_next_ch: jmpr cc_busy, 0 swp f8, r4 ; ? may be just needed some CPU clocks to wait? or f9, r4, r4 ; ?, the result is not used? add r6, f9, r6 ; accumulate Nhits add r2, 1, r2 ; inc the loop counter = channel number sgio r2, r1 ; set the next channel to be read from the FRF shl -16, f10, r4 ; take the upper 16 bits, Q1 add r7, r4, r7 ; accumulate Q cmp r2, COS_END_CH jmp cc_leu, acq_cosmic_next_ch ; here we have: ; the number of Hits in r6 ; the accumulated charge (+ pedestal) in r7 mov r6, adc_ch_msk ; g4..7 mov r7, charge_i ; g0..3 SYN ; wait until all CPUs write their number of hits in g4..7 #ifdef cpu3 add r6, adc_ch_msk_0, r6 ; add the number of hits of CPU0 add r6, adc_ch_msk_1, r6 ; ... CPU1 add r6, adc_ch_msk_2, r6 ; ... CPU2 #else #ifdef cpu0 add r7, charge_1, r7 ; add the charge of CPU1 add r7, charge_2, r7 ; ... and CPU2 add r7, charge_3, charge_3 ; ... and CPU3 #else nop nop nop #endif #endif #ifdef cpu3 sra+ r6 ; store the number of hits for debugging mov charge_3, r7 sra+ r7 ; store the complete charge for debugging #else #ifdef cpu1 mov 1, r0 ; switch back to automatic select, necessary IEXT TPCBY ; for the zero suppression SGIO r0, TPCBY #else nop nop nop #endif #endif ; parameters defined in the .tcs files: ; COSMIC_MIN_HITS = 4; // min number of hits, 5 bit ; COSMIC_Q_THR = 350; // threshold for the total cluster charge/MCM, 16 bit ; COSMIC_Q_SHR = 4; // shift right the total cluster charge/MCM, 3 bit ; C10CPU3 is (COSMIC_Q_SHR & 0x0007) | ((COSMIC_MIN_HITS & 0x001F) << 3) | ((COSMIC_Q_THR & 0xFFFF) << 8) #ifdef cpu3 mul32 r5, r6, r5 ; the pedestal in the charge sra+ r5 ; store for debugging the pedestal of 3 channels (x4) shl -2, r5, r5 ; the TPFP is with 2 more bits, therefore /4 sub r7, r5, r7 ; the charge without pedestal sra+ r7 ; store for debugging #else #ifdef cpu0 sem b1000 ; wait on writing to g3 syn slr 0, charge_3 ; no other way to check if some GRF is 0 jmp cc_nzero, acq_cos_qcompr jmp cc_uncond, acqco_no_tr #else nop nop nop nop jmp cc_uncond, acqco_no_tr #endif #endif ; here only CPU3 continues ; check the thresholds: ; - number of hits cmp r6, COSMIC_MIN_HITS ; min number of hits jmp cc_leu, acqco_no_tr ; - min charge mova COSMIC_Q_THR, r1 cmp r7, r1 ; r7 could be negative after subtracting the pedestal! jmp cc_les, acqco_no_tr ; therefore compare as signed! mov r7, charge_3 ; store here for CPU0 to make the charge compression sem b1100 ; wait on writing to g2, g3 syn neg charge_2, r2 ; the shift distance ; shift the threshold shl r2, r1, r1 ; shift right the threshold ; prepare the tracklet word shl 8, charge_3, r7 ; shift the charge left 8 bits or r7, r1, r7 ; add the threshold shl 8, r7, r7 ; shift left 8 bits or r7, r6, r6 ; add the Nhits shl 8, r6, r6 ; shift left 8 bits ; here we have in r6: Qsc << 24 | Q_THRsc << 16 | Nhits << 8 ; where ; Qsc = Q >> Q_SHR ; Q_THRsc = Q_THR >> Q_SHR ; the lower 8 bits are still free! mov COSMIC_MIN_HITS, r1 sll 3, r1, r1 or r6, r1, r6 or r6, charge_2, r6 ; the lower 8 bits are now: COSMIC_Q_SHR(dyn) | COSMIC_MIN_HITS << 3 ; the tracklet is ready! acqco_wr_track: #ifdef TimerCPU lpio CTPDOUT, r5 ; the number of CPU clocks #endif #ifdef TrcklDMEMa sra r6, TrcklDMEMa ; store in DMEM for debugging #endif spio r6, NODP #ifdef TimerCPU sra r5, TimerCPU ; store in DMEM for debugging #else nop #endif jmp cc_uncond, clr_endloop nop acqco_no_tr: #ifdef cpu3 mov 0, charge_3 ; to say to cpu0, there is no tracklet #endif ; cpu0..2 come here directly, cpu3 only when not "tracklet" ; short delay mov 6, r6 sub r6, c1, r6 jmpr cc_nzero, -1 ; load the end marker acq_cos_wem: iext NSIG_TR_VAL mov NSIG_TR_VAL, r6 jmp cc_uncond, acqco_wr_track ; used only by CPU0 acq_cos_qcompr: ; input data: charge in charge_3 ; output data: shift distance 0..7, stored in charge_2 slr 8, charge_3, r7 ; we want to store in 8 bits, if the result is 0, then then the shift distance is 0 jmp cc_zero, acq_cos_qcompr0 slr 1, r7, r7 ; now shift only by 1 jmp cc_zero, acq_cos_qcompr1 ; and jump out if 0 slr 1, r7, r7 ; now shift only by 1 jmp cc_zero, acq_cos_qcompr2 ; and jump out if 0 slr 1, r7, r7 ; now shift only by 1 jmp cc_zero, acq_cos_qcompr3 ; and jump out if 0 slr 1, r7, r7 ; now shift only by 1 jmp cc_zero, acq_cos_qcompr4 ; and jump out if 0 slr 1, r7, r7 ; now shift only by 1 jmp cc_zero, acq_cos_qcompr5 ; and jump out if 0 slr 1, r7, r7 ; now shift only by 1 jmp cc_zero, acq_cos_qcompr6 ; and jump out if 0 mov 7, charge_2 slr 1, r7, r7 ; now shift only by 1 jmp cc_zero, acq_cos_qcompr7 ; and jump out if 0 mov 0xFF, charge_3 ; the max jmp cc_uncond, acq_cos_wem acq_cos_qcompr7: slr 7, charge_3, charge_3 ; the result jmp cc_uncond, acq_cos_wem acq_cos_qcompr6: slr 6, charge_3, charge_3 ; the result mov 6, charge_2 jmp cc_uncond, acq_cos_wem acq_cos_qcompr5: slr 5, charge_3, charge_3 ; the result mov 5, charge_2 jmp cc_uncond, acq_cos_wem acq_cos_qcompr4: slr 4, charge_3, charge_3 ; the result mov 4, charge_2 jmp cc_uncond, acq_cos_wem acq_cos_qcompr3: slr 3, charge_3, charge_3 ; the result mov 3, charge_2 jmp cc_uncond, acq_cos_wem acq_cos_qcompr2: slr 2, charge_3, charge_3 ; the result mov 2, charge_2 jmp cc_uncond, acq_cos_wem acq_cos_qcompr1: slr 1, charge_3, charge_3 ; the result mov 1, charge_2 jmp cc_uncond, acq_cos_wem acq_cos_qcompr0: mov 0, charge_2 jmp cc_uncond, acq_cos_wem