// ===================================================================== // don't modify the lines below! // // ===================================================================== error ( (ConfigEvent != 1) && (ConfigEvent != 0) ) "ConfigEvent can be only 0 (do not dump the config) or 1 (dump the config as first raw data readout)!" restrict TRACKLETS_MODE == TRACKLETS_3Q_MODE asm DYN_MASK = (1 << DYN_SIZE) - 1; asm DYN_CHECK0 = DYN_SHIFT0 + DYN_SIZE; asm DYN_CHECK1 = DYN_SHIFT1 + DYN_SIZE; asm DYN_CHECK2 = DYN_SHIFT2 + DYN_SIZE; restrict NSAMPLES > 30 // this is now possible! //error (ZS_FULL_MOD != ZS_FULL_NO) "When the number of samples > 30, sending black events is not possible!" asm NBEG_MAX=NSAMPLES+1-3*NWORDS; // the max possible beginning sample, so that the whole window lyies in the limits error ( (NWORDS > 10) && (NSAMPLES > 30) ) "When NSAMPLES > 30, the max NWORDS is 10" error ( (RAW_RDOUT_MODE != RAW_RDOUT_ZS) && (NSAMPLES > 30) ) "When NSAMPLES > 30, only ZS is possible!" restrict 1 error ( (RAW_RDOUT_MODE == RAW_RDOUT_FULL) && (RAW_SCSN == RAW_SCSN_ZS) ) "Wrong combination of RAW_RDOUT_MODE=FULL and RAW_SCSN=ZS" error ( (RAW_RDOUT_MODE == RAW_RDOUT_TP ) && (RAW_SCSN == RAW_SCSN_ZS) ) "Wrong combination of RAW_RDOUT_MODE=TP and RAW_SCSN=ZS" bits2_0=0; bit3=0; bit4=0; bit5=0; bit6=0; min_ver=0; // default value, modified eventually in case of ZS restrict TRACKLETS_MODE==TRACKLETS_DIS_MODE bit4=1; restrict TRACKLETS_MODE==TRACKLETS_COS_MODE bit3=1; restrict RAW_RDOUT_MODE==RAW_RDOUT_TP bit6=1; bits2_0=RAW_TP_TYPE & 7; asm RAW_RDOUT_TP_TYPE=bits2_0; //error ( (RAW_RDOUT_TP_TYPE==4) || (RAW_RDOUT_TP_TYPE==5) || (RAW_RDOUT_TP_TYPE==7) ) "Invalid test pattern 4, 5 or 7 in test pattern mode!"; restrict RAW_RDOUT_MODE==RAW_RDOUT_ZS warning ( (ZS_FULL_MOD == ZS_FULL_1) && (ZS_FULL_EVENT >= ZS_FULL_N1) ) "The full event # in ZS 1 of 128 is > 127!" warning ( (ZS_FULL_MOD == ZS_FULL_2) && (ZS_FULL_EVENT >= ZS_FULL_N2) ) "The full event # in ZS 1 of 256 is > 255!" warning ( (ZS_FULL_MOD == ZS_FULL_3) && (ZS_FULL_EVENT >= ZS_FULL_N3) ) "The full event # in ZS 1 of 1024 is > 1023!" warning ( (ConfigEvent == ZS_FULL_EVENT) && (ConfigEvent == 1) ) "The first event will be a configuration dump and not full ADC readout!" restrict RAW_RDOUT_MODE==RAW_RDOUT_ZS bit5=1; bit6=0; bits2_0=(ZS_FULL_MOD << 1) | (DONT_SEND_EMPTY_HDR_ZS & 1); // combine bits 0..1 and 2 min_ver= ZS_TRACKL | (ZS_ADCMSK_AND << 2); restrict RAW_RDOUT_MODE==RAW_RDOUT_FULL; bits2_0=WITH_STAT; restrict RAW_RDOUT_MODE!=RAW_RDOUT_FULL; WITH_STAT = 0; WITH_FIT2DM = 0; restrict 1; restrict RAW_SCSN == RAW_SCSN_DIS; warning ( (WITH_FIT2DM == 1) && (RAW_SCSN == RAW_SCSN_DIS) ) "FIT2DM was set, but the SCSN readout was disabled, so FIT2DM will be disabled too!"; WITH_FIT2DM = 0; restrict 1; asm FULL_WITH_STAT = WITH_STAT; // export the statistics flag to the asm prog asm FULL_WITH_FIT2DM = WITH_FIT2DM; // store the fit registers to DMEM for debugging asm FUNC_CODE=(bit6 << 6) | (bit5 << 5) | (bit4 << 4) | (bit3 << 3) | bits2_0; asm HC_0_RAW_VER_MIN_NR = min_ver; asm HC_0_ADD_HD_WORDS = 2; // the position independent part of the HC_0 can be used directly in the asm program: asm HC_0_CNF = (1 << 17) | (FUNC_CODE << 10) | (HC_0_RAW_VER_MIN_NR << 3) | HC_0_ADD_HD_WORDS ; // reverse ingeneering: < not needed at all> //asm RAW_VER_MAJ_VER = (HC_0_CNF >> 10) & 0x7F; // 7-bits //asm RAW_VER_MIN_VER = (HC_0_CNF >> 3) & 0x7F; // 7-bits //asm RAW_ADD_HDR_WRD = HC_0_CNF & 0x07; // 3-bits // in order to overwrite the upper part of the HC_0 with HC_0_CNF defined here, define the constant OVERWR_UPPER_HC0. // For the old behaviour delete or comment the next line! //asm OVERWR_UPPER_HC0 = 123; // the value doesn't matter, important only if defined or not defined! restrict TRACKLETS_MODE == TRACKLETS_TPT_MODE // rescale to 1023, as we will use 10-bits asm TEST_PAT_THRESH1 = TEST_PAT_MASK*(TEST_PAT_1_TR + TEST_PAT_2_TR + TEST_PAT_3_TR)/1000; asm TEST_PAT_THRESH2 = TEST_PAT_MASK*( TEST_PAT_2_TR + TEST_PAT_3_TR)/1000; asm TEST_PAT_THRESH3 = TEST_PAT_MASK*( TEST_PAT_3_TR)/1000; error (TEST_PAT_THRESH1 > 1023) "Tracklet testpattern parameters wrong, sum of probabilities > 100%" // can use either the defined constants above or the DMEM dword here: const SCALE_D = (SCRM_WORD_H << 16) | SCRM_WORD_L; // scramble word const SCALE_Y = TEST_PAT_THRESH1 | (TEST_PAT_THRESH2 << 10) | (TEST_PAT_THRESH3 << 20); const OFFS_Y = 0; // not used now restrict NSAMPLES>30 const EBmask_32_63_VAL = EBmask_32_63 & ( (1 << (NSAMPLES-32) ) -1 ); const EBmask_0_31_VAL = EBmask_0_31; // no correction here restrict NSAMPLES<31 const EBmask_32_63_VAL = 0; const EBmask_0_31_VAL = EBmask_0_31 & ( (1 << NSAMPLES ) -1 ); restrict 1 // ----------------------------------------- // Preprocessor parameters // ----------------------------------------- asm PRECLK_VAL = 0x07; asm TPPT0_VAL = 1; asm TPPGR_VAL = NSAMPLES+1; // Response Time to GSM asm TPPAE_VAL = NSAMPLES+3; // Event Buffer Data Acquisition End // ----------------------------------------- // Event buffer // ----------------------------------------- // set to 0x00 for ADC readout or to 0x1E for test data readout asm EBAQA_VAL = 0; asm EBSF_VAL = ADCraw; asm EBD_VAL = ADCdatapipe; asm EBSIM_VAL = 1; // 0 means simulation asm EBSIA_VAL = 0x20; // start address for ADC data in sim mode asm EBPP_VAL = 1; // 0 - enable parity, 1 - disable, anyway parity error not counted? asm EBIS_VAL = EBSingleIndicatorThreshold; asm EBIT_VAL = EBSumIndicatorThreshold; asm EBIL_VAL = EBIndicatorLookupTable; asm EBIN_VAL = EBmarkIgnoreNeighbour; // ----------------------------------------- // Filter // ----------------------------------------- asm FILCLK_VAL= 0x07; restrict SIMULATION==0 EnableFilters=1; restrict SIMULATION==1 EnableFilters=0; // typically don't use filter in HDL simulation restrict 1 // ------- Tail filter ------ asm FTBY_VAL = EnableTailCancellation*EnableFilters; asm FTAL_VAL = LongDecayWeight; asm FTLL_VAL = LongDecayParameter; asm FTLS_VAL = ShortDecayParameter; //echo "FTBY_VAL: %d" FTBY_VAL // ----- Pedestal filter ----- asm FPBY_VAL = EnablePedestal*EnableFilters asm FPTC_VAL = PedestalTimeConstant //asm FPNP_VAL = FPNPvalue // The baseline at the output of the pedestal filter is still not the final! // Set the baseline variation parameters in FPNPvalue and GainPedestalIni: //echo "EffectPedestal=%d" EffectPedestal //echo "EnableTailCancellation=%d" EnableTailCancellation //echo "XtalkF0=%d" XtalkF0 //echo "EnableGainCorrection=%d" EnableGainCorrection // Tom: the original calculation (see below) seems buggy as it does not consider // the integer arithmetics. The influence of the tail cancellation filter seems // to be overestimated, so I disable it for now. tc_corr = 14 ; // + (45-31)*EnableTailCancellation; // units: 1/14 xt_corr = XtalkF0*(9-EnableGainCorrection) ; // units: 1/9 asm FPNP_VAL = ( (EffectPedestal +2) * tc_corr * xt_corr ) / (14*9) ; // const FPNPvalue=4*(EffectPedestal+1/2)*(1+EnableTailCancellation*(-1+45/14))*XtalkF0*(9-EnableGainCorrection)/9; // FPNP is restricted to 0 ... 127.75 (7+2 bits) //echo "factor=%d" (1+EnableTailCancellation*(-1+45/14))*XtalkF0*(9-EnableGainCorrection)/9 //echo "FPNP_VAL=%d" FPNP_VAL // ----- Gain correction ----- asm FGBY_VAL = EnableGainCorrection*EnableFilters; // Counter Threshold A, eventually could be modified asm FGTA_VAL = 0x014; // Counter Threshold B, eventually could be modified asm FGTB_VAL = 0x80C; // ------ Cross-talk ------ asm FCBY_VAL = 1; // disabled, but used as 2-pipe stage, eventually could be modified // ----- Linearity ------ asm FLBY_VAL = 0; // eventually could be modified // ----------------------------------------- // Global state machine // ----------------------------------------- ignore_L1R = ignore_L1R & (1-DYN_L1A); // 0 for DYN_L1A=1 and unchanged when 0 asm SML0_VAL = (LTIME0 - (smmode_delta >> 1) ) | (ignore_L0R << 14); // the time for L0 accept asm SML2_VAL = (LTIME2 - (smmode_delta >> 1) ) | (ignore_L1R << 14); // the actual L1 time asm SML2_VALnoA = (LTIME2 - (smmode_delta >> 1) ) | (0 << 14); // the actual L1 time asm SML1_VAL = (LTIME1 - (smmode_delta >> 1) ) | (1 << 14); // the time to start the raw data readout, a little bit later asm SMMODE_VAL_NM = (smmode_simflag << 11) | (smmode_eod2cpu << 4) | smmode_delta; asm SMMODE_VAL_CM = (1011b << 12) | SMMODE_VAL_NM; asm SMMODE_VAL_BM = (1111b << 12) | SMMODE_VAL_NM; asm SMMODE_VAL_HM4 = (1111b << 12) | SMMODE_VAL_NM; asm SMMODE_VAL_HM3 = (1111b << 12) | SMMODE_VAL_NM; // 0 - external, 1 - after read, 2, 3 - continuous at 120 MHz sel_inp = 0; // 0 - slow clock 10 MHz, decoded pretrigger command: 1 - clear (2 LHC clocks), 2 - pretriger (1 LHC clock), 3 - reserved (3 LHC clocks) ext_sel = 2 + DYN_L1A; // DYN_L1A is 1 or 0, // when 0, program the global counter as pretrigger counter, // when 1 - as RESERVED command counter asm CTGCTRL_VAL = 0xE1F | (sel_inp << 5) | (ext_sel << 7); // ----------------------------------------- // Internal bus & memory timing parameters & hamming settings // ----------------------------------------- asm ARBTIM_VAL = 1101b; // fastest timing 11 for writing and slower 01 for reading asm DMDELA_VAL = 2; // Nominal:2 used in DMDELA asm DMDELS_VAL = 15; // Nominal:15 used in DMDELS //asm MEMRW_RST_VAL = 0x79; // may be not necessary to refresh? // select the hamming correction on/off const HAMMIM=1; const HAMMDB=1; const HAMMDM=1; // enable/disable hamming correction used in MEMCOR hamming_imem = HAMMIM | (HAMMIM << 1) | (HAMMIM << 2) | (HAMMIM << 3); hamming_dmem = HAMMDM | (HAMMDM << 1) | (HAMMDM << 2) | (HAMMDM << 3); asm MEMCOR_VAL = hamming_imem | (hamming_dmem << 4) | (HAMMDB << 8); asm IRQHW_VAL = (1 << IRQ_ACQ) | (1 << IRQ_CLR) | (1 << IRQ_RAW) | (1 << IRQ_TST); asm IRQHL_VAL = (1 << IRQ_ACQ) | (1 << IRQ_CLR) | (1 << IRQ_RAW) | (1 << IRQ_TST); asm CPUxCLK_VAL = 0x1F; // used 4x times // ----------------------------------------- // NI parameters // ----------------------------------------- asm NSIG_TR_VAL = 0x1000; // end signature for tracklets \ stored in NES register, but used separately asm NSIG_RR_VAL = 0x0000; // ... and for raw data readout / in the assembler program asm NBND_VAL = 0x6020; // this is the reset value // *************************** // TRAP => TRAP delay and exclude parameters // *************************** const t_data_delay = 2; // if strobe delay is 0, here should work with 1..3 and minor errors at 0 at 4 // individual delays, normally we don't need to use different values here const t_data_delay0 = t_data_delay; const t_data_delay1 = t_data_delay; const t_data_delay2 = t_data_delay; const t_data_delay3 = t_data_delay; const t_data_delay4 = t_data_delay; const t_data_delay5 = t_data_delay; const t_data_delay6 = t_data_delay; const t_data_delay7 = t_data_delay; const t_data_delay8 = t_data_delay; const t_data_delay9 = t_data_delay; const t_strb_delay = 0; // 0, better not to change, actually the difference data_delay-strb_delay is important const t_ctrl_delay = 0; // 0..7 not used between the TRAPs // this is only the default configuration and will be changed individually if necessary in the patch maker! const t_false_bit = 9; // 0..9 const t_parit_bit = 8; // 0..9 // ----------------------------------------- // Last merger => ORI delay and exclude parameters // ----------------------------------------- const m_data_delay = 2; // individual delays, normally we don't need to use different values here const m_data_delay0 = m_data_delay; const m_data_delay1 = m_data_delay; const m_data_delay2 = m_data_delay; const m_data_delay3 = m_data_delay; const m_data_delay4 = m_data_delay; const m_data_delay5 = m_data_delay; const m_data_delay6 = m_data_delay; const m_data_delay7 = m_data_delay; const m_data_delay8 = m_data_delay; const m_data_delay9 = m_data_delay; const m_strb_delay = 0; // 0 const m_ctrl_delay = 0; // 0..7 not used at all, only in the case of OASE chip but not in ORI // this is only the default configuration and will be changed if necessary! const m_false_bit = 9; // 0..9 const m_parit_bit = 8; // 0..9 asm NITM0_VAL = NSAMPLES*12+50; // normally = nsamples*12+50 and up to 12 bit asm NITM1_VAL = 0x3FFF; // reset value asm NITM2_VAL = 0x3FFF; // reset value // NDLY has a hamming protected value in DB asm NDLY_VAL = (t_data_delay0) | (t_data_delay1 << 3) | (t_data_delay2 << 6) | (t_data_delay3 << 9) | (t_data_delay4 << 12) | (t_data_delay5 << 15) | (t_data_delay6 << 18) | (t_data_delay7 << 21) | (t_data_delay8 << 24) | (t_data_delay9 << 27); asm NDLY_HCM_VAL = (m_data_delay0) | (m_data_delay1 << 3) | (m_data_delay2 << 6) | (m_data_delay3 << 9) | (m_data_delay4 << 12) | (m_data_delay5 << 15) | (m_data_delay6 << 18) | (m_data_delay7 << 21) | (m_data_delay8 << 24) | (m_data_delay9 << 27); // NED has a hamming procted value in DB // root(bit14) and oase(bit15) flags are cleared asm NED_VAL = (0 << 15) | (0 << 14) | (t_parit_bit << 10) | (t_false_bit << 6) | (t_ctrl_delay << 3) | t_strb_delay; // root(bit14) set asm NED_HCM_VAL = (0 << 15) | (1 << 14) | (m_parit_bit << 10) | (m_false_bit << 6) | (m_ctrl_delay << 3) | m_strb_delay; asm NIP4D_VAL = 0x03; // delays asm NICLK_VAL = 0x1F; // some reset values, which still need to be refreshed asm NMOD_RST_VAL = 8; asm NCUT_SINGLE_P_VAL = 0xFF; // for normal MCMs and BM, no HCM asm NIODE_VAL = 0x1B; asm NIOCE_VAL = 0x01; // was 1F, 01 to permanently turn on the LVDS output cells of the NI control signals asm NIIDE_VAL = 0x02; asm NIICE_VAL = 0x01; // was 0x1F, but later in asm program was overwritten with 1? // HCM only asm NIODE_HCM_VAL = 0x02; asm NIOCE_HCM_VAL = 0x01; asm NIIDE_HCM_VAL = 0x07; asm NIICE_HCM_VAL = 0x01; // was 7, 01 to permanently turn on the LVDS input cells of the NI control signals // ----------------------------------------- // ADC // ----------------------------------------- // ADCPAR fields: IRQ, sampling phase, en inp buffer, autozero, power asm ADCPAR_VAL = adc_power_backgr | (adc_az_backgr << 3) | (adc_enibf_backgr << 4) | (adc_power_pretr << 5) | ((adc_az_pretr|adc_az_pretr_sim) << 8) | (adc_enibf_pretr << 9) | (adc_smp_phase << 10) | (adc_irq_phase << 14); asm ADCINB_VAL = 10b; // invert bits asm ADCEN_VAL = 0x01; // ADCMSK can be modified by the patch maker const ADCMSK_VAL = 0x1FFFFF; //const ADCMSK_A_BND = 0x07FFFF; // channels 19, 20 masked, but only 20 comes from the neighbour ROB or is floating! //const ADCMSK_B_BND = 0x1FFFF8; // channels 0, 1, 2 masked, but only 0, 1 come from the neighbour ROB or are floating! const ADCMSK_A_BND = 0x0FFFFF; // channel 20 masked, only 20 comes from the neighbour ROB or is floating! const ADCMSK_B_BND = 0x1FFFFC; // channels 0, 1 masked, only 0, 1 come from the neighbour ROB or are floating! const MASK_BOUNDARY_ADCS=1; // ----------------------------------------- // Software parameters // ----------------------------------------- // build the 4-bits with the data format restrict TRACKLETS_MODE == TRACKLETS_3Q_MODE; const DATA_FORMAT_VAL = (TRACKLETS_MODE << 2) | (DONT_SEND_EMPTY_HDR_TR << 1) | DYN_FP_Q; restrict TRACKLETS_MODE == TRACKLETS_DIS_MODE; const DATA_FORMAT_VAL = (TRACKLETS_MODE << 2) | (DONT_SEND_EMPTY_HDR_TR << 1) ; // bit 0 is unused restrict TRACKLETS_MODE == TRACKLETS_TPT_MODE; const DATA_FORMAT_VAL = (TRACKLETS_MODE << 2) | (DONT_SEND_EMPTY_HDR_TR << 1) ; // bit 0 is unused but could be used for different test patterns restrict TRACKLETS_MODE == TRACKLETS_COS_MODE; // be aware, the format word should be different from 0000 and 0001, as this could lead to get an end marker in the upper 16 bits! const DATA_FORMAT_VAL = (TRACKLETS_MODE << 2) | 3; // bits 0,1 are unused => set in order to get something different from 0 restrict 1; // Addresses in DMEM, here for access over SCSN // the CPUs don't need these values, therefore defined with 'const' // please don't change the order const WDOG_DM_SCSN = 0xC060; // address in DMEM accessed through SCSN const SCALE_Y_DM_SCSN = 0xC061; // address in DMEM accessed through SCSN const OFFS_Y_DM_SCSN = 0xC062; // address in DMEM accessed through SCSN const SCALE_D_DM_SCSN = 0xC063; // address in DMEM accessed through SCSN const SCALE_Q_DM_SCSN = 0xC064; // address in DMEM accessed through SCSN const DEFL_CR_DM_SCSN = 0xC065; // address in DMEM accessed through SCSN const ZS_SMSK_DM_SCSN = 0xC068; // address in DMEM accessed through SCSN const ZS_ADC_ORM_DM_SCSN = 0xC06A; // address in DMEM accessed through SCSN // 20x{sum ADC (dword), sum ADC**2, (2 dwords/channel)} const AddrDMstat_DM_SCSN = 0xC080; // address in DMEM accessed through SCSN // signed left and right margin for the deflection in the corresponding channel (0..17) const DEFL_RNG_TBL_DM_SCSN = 0xC020; // .. 0xC043 // Tables: // position LUT stored in DMEM, in 32-bit words: each word has 6 x 5 bit LUT data // LUT32[ 0]=LUT5[0] | LUT5[1] << 5 | LUT5[2] << 10 | LUT5[3] << 15 | LUT5[4] << 20 | LUT5[5] << 25 // ... // LUT32[21]=LUT5[126] | LUT5[127] << 5 | flags << 12 | counter << 16 // where flags is a 2-bit counter, 0 - init state, 1, 2, 3 - first, second, third/3 refreshed // once read, 6 times write to GIO 21 times and the last time write only twice to GIO! 128 = 6*21 + 2 const POS_LUT_TBL_DM_SCSN = 0xC048; // .. 5D // the gain factors stored in DMEM (3 x 9 bit in one 32-bit word) x 7 for 21 channels const GAIN_TABLE_MULT_DM_SCSN = 0xC11C; // 9-bit/channel, 3 channels in 32-bit, 21 channels -> 7 32-bit words // the gain additives stored in DMEM (5 x 6 bit in one 32-bit word) x 4 + 1 const GAIN_TABLE_ADDT_DM_SCSN = 0xC124; // 6-bit/channel, 5 channels in 32-bit, 21 channels -> 5 32-bit words //const ZS_SMSK_DM_SCSN = 0xC068; // same addresses but this time when accessed by the CPUs, therefore defined with 'asm' // SCSN uses DWord Addresses, CPUs use Byte Addresses and start from 0 // SCSN 0xC000 .. 0xC3FF => CPU_DMEM 0x000 .. 0xFFC (only 4*n) asm WDOG_DM = (WDOG_DM_SCSN & 0xFFF) << 2; // address in DMEM for CPU access is byte address and relative to 0 asm SCALE_Y_DM = (SCALE_Y_DM_SCSN & 0xFFF) << 2; asm OFFS_Y_DM = (OFFS_Y_DM_SCSN & 0xFFF) << 2; asm SCALE_D_DM = (SCALE_D_DM_SCSN & 0xFFF) << 2; asm SCALE_Q_DM = (SCALE_Q_DM_SCSN & 0xFFF) << 2; asm DEFL_CR_DM = (DEFL_CR_DM_SCSN & 0xFFF) << 2; asm DEFL_RNG_TBL_DM = (DEFL_RNG_TBL_DM_SCSN & 0xFFF) << 2; asm ZS_SMSK_DM = (ZS_SMSK_DM_SCSN & 0xFFF) << 2; asm ZS_ADC_ORM_DM = (ZS_ADC_ORM_DM_SCSN & 0xFFF) << 2; asm AddrDMstat_DM = (AddrDMstat_DM_SCSN & 0xFFF) << 2; // initial addresses for the 4 CPUs asm AddrDMstat_0 = AddrDMstat_DM; asm AddrDMstat_1 = AddrDMstat_DM+ 5*3*4; // 5 channels/CPU, 3 32-bit words/ADC channel, byte address (x4) asm AddrDMstat_2 = AddrDMstat_DM+10*3*4; // 5 channels/CPU, 3 32-bit words/ADC channel, byte address (x4) asm AddrDMstat_3 = AddrDMstat_DM+15*3*4; // 5 channels/CPU, 3 32-bit words/ADC channel, byte address (x4) asm POS_LUT_TBL_DM = (POS_LUT_TBL_DM_SCSN & 0xFFF) << 2; // the last address of the position LUT, used for the last 2 entries + flags + refresh counter asm POS_LUT_TBL_DM_E= POS_LUT_TBL_DM+0x054; asm TPLm2 = TPL+128-2; // the address of the before last entry in the POS LUT, used in the refresh program asm GAIN_TABLE_MULT_DM = (GAIN_TABLE_MULT_DM_SCSN & 0xFFF) << 2; asm GAIN_TABLE_ADDT_DM = (GAIN_TABLE_ADDT_DM_SCSN & 0xFFF) << 2; // LUT for 1/N division base address in DMEM (mapped in GIO) asm Base_LUT_1divN_DM_SCSN = 0xC000; // probably not used any more // Addresses in DBANK with parameter values asm EvtCtr_DB = 0xF0F4; // used as a event counter asm ADCMSK_DB = 0xF0F5; // used for refresh // non-global parameters, depending on the position of the MCM, ROB, Chamber etc. asm ChipPOS_DB = 0xF0F6; // c14 was used for MCM id, readout flags asm h_0_DB = 0xF0F7; // c15 was used for h_0 before // // parameters, which could be modified by the patch maker // clock & pre distribution, NI -ports enable // don't change the order here! asm SMMODE_DB = 0xF0F8; // the content of the SMMODE register // NI parameters asm NTRO_DB = SMMODE_DB+1; // the content of the NTRO register: readout order tracklet mode asm NRRO_DB = SMMODE_DB+2; // the content of the NRRO register: readout order raw data readout mode asm NED_DB = SMMODE_DB+3; // the content of the NED register: output excludes and control delays asm NDLY_DB = SMMODE_DB+4; // the content of the NDLY register: out data delays asm NP0_3_DB = SMMODE_DB+5; // bits 10..3 of NP0..3 registers (false & parity position), the lower bits 2..0 are 100 always // NP0_3_DB = NP0[10..3] | NP1[10..3] << 8 | NP2[10..3] << 16 | NP3[10..3] << 24 asm H_PAD_ROW_COL_DB = SMMODE_DB+6; // MCM tracklet header prepared // defined above: // const ADCMSK_DM_SCSN = 0xC060; // address in DMEM accessed through SCSN // the gain factors stored in DMEM (3 x 9 bit in one 32-bit word) x 7 for 21 channels // const GAIN_TABLE_MULT_DM_SCSN = 0xC11C; // 9-bit/channel, 3 channels in 32-bit, 21 channels -> 7 32-bit words // the gain additives stored in DMEM (5 x 6 bit in one 32-bit word) x 4 + 1 // const GAIN_TABLE_ADDT_DM_SCSN = 0xC124; // 6-bit/channel, 5 channels in 32-bit, 21 channels -> 5 32-bit words // **************************************** // READOUT TREE parameters // **************************************** // Readout tree on all boards except for half-chamber merger // 00 01 -0> 02 <3- 03 // `--------1/ \----------, // | // 04 05 -0> 06 <3- 07 2 // `--------1/ \--------0,| // || // 16 --> // 08 09 -0> 10 <3- 11 || // `--------1/ \--------1�| // | // 12 13 -0> 14 <3- 15 3 // `--------1/ \----------� // Here one can see the connectivity of the readout tree. // For example MCM00 sends its data to NI input port 1 of the column merger MCM02, // its output goes to NI input port 2 of the board merger MCM16. // Readout tree on the boards with half-chamber mergers // 00 01 -0> 02 <3- 03 // `--------1/ \----------, // | // 04 05 -0> 06 <3- 07 2 // `--------1/ \--------0,| // || // 16 -- 3->17->ORI // 08 09 -0> 10 <3- 11 || // `--------1/ \--------1�| // | // 12 13 -0> 14 <3- 15 3 // `--------1/ \----------� // // Readout order for the CM-mergers: p1 -> p0 -> p4 -> p3, here p4 means the own data // Readout order for the BM-mergers: p2 -> p0 -> p1 -> p3 // readout order configuration constants const NIRO_NM = 0x0003fffc; // for normal chips, send only own data // 1 -> 0 -> own -> 3 const NIRO_CM = 0x0001fe21; // for column merger chips restrict FULLROB==1 // 3 -> 1 -> 0 -> 2 (0x39e13), now: own -> 2 -> 0 -> 1 -> 3 // own in order to have not so different programs in HCM and BM const NIRO_BM = 0x000170cc; // for board merger chips restrict FULLROB==0 const NIRO_BM = 0x00017ffc; // own -> 2, used in simulation normally restrict 1 // C0 chamber // // --------- --------- --------- // | 2:0 | | 1:0 | | 0:0 | // | BM | | | | | // | p3 |<-p1---| |-------|--BM | Side A // | HCM |<-p0---|--BM | | | // | T3A | | T1A | | T1A | // --------- --------- --------- // 4 2 0 // // // --------- --------- --------- // | 2:1 | | 1:1 | | 0:1 | // | BM | | | | | // | p3 |<-p1---| |-------|--BM | Side B // | HCM |<-p0---|--BM | | | // | T3B | | T2B | | T1B | // --------- --------- --------- // 5 3 1 // // Readout order for the HC-mergers: p1 -> p0 -> p3 restrict SINGLEROB==0 // own -> 1 -> 0 -> 3 const NIRO_HM3 = 0x0000fe1c; // for half-chamber merger chips sending header as own data restrict SINGLEROB==1 // own -> 3, used only in single ROB configuration const NIRO_HM3 = 0x0001fffc; // for half-chamber merger chips sending header as own data restrict 1 // C1 chamber // // --------- --------- --------- --------- // | 3:0 | | 2:0 | | 1:0 | | 0:0 | // | | | BM | | | | | // | | | p3 |<-p1---| |-------|--BM | Side A // | BM--|--p2-> | HCM |<-p0---|--BM | | | // | T4A | | T3A | | T1A | | T1A | // --------- --------- --------- --------- // 6 4 2 0 // // // --------- --------- --------- --------- // | 3:1 | | 2:1 | | 1:1 | | 0:1 | // | | | BM | | | | | // | | | p3 |<-p1---| |-------|--BM | Side B // | BM--|--p2-> | HCM |<-p0---|--BM | | | // | T4B | | T3B | | T2B | | T1B | // --------- --------- --------- --------- // 7 5 3 1 // restrict SINGLEROB==0 // Readout order for the HC-mergers: p1 -> p0 -> p3 -> p2 // own -> 1 -> 0 -> 3 -> 2 const NIRO_HM4 = 0x0000ae1c; // for half-chamber merger chips sending header as own data restrict SINGLEROB==1 // own -> 3, used only in single ROB configuration const NIRO_HM4 = 0x0001fffc; // for half-chamber merger chips sending header as own data restrict 1