TITLE "MULTI PFRED"; % carla grosso-pilcher % % outputs 20 trigger bits from various input types to the back plane for FRED % % see CDF5403 % % !!!! Pin names and assignment fixed from the sumet chip. !!!!% % !!!! They have to be conserved on all pfred chip, even if not optimal. !!!!% FUNCTION lpm_shiftreg (data[LPM_WIDTH-1..0], clock, enable, shiftin, load, sclr, sset, aclr, aset) WITH (LPM_WIDTH, LPM_DIRECTION, LPM_AVALUE, LPM_SVALUE) RETURNS (Q[LPM_WIDTH-1..0], shiftout); FUNCTION lpm_mux (data[LPM_SIZE-1..0][LPM_WIDTH-1..0], sel[LPM_WIDTHS-1..0], clock, aclr) WITH (LPM_WIDTH, LPM_SIZE, LPM_WIDTHS, LPM_PIPELINE) RETURNS (result[LPM_WIDTH-1..0]); SUBDESIGN multi ( clk_66ns : INPUT; clk_132ns[2..0] : INPUT; % 132 ns clocks, separated by 22 ns; 1st one % % is in sync with CRATESUMs' incoming data % b0_delayed : INPUT; % B0 signal delayed by b0_offset % run : INPUT; vme_write : INPUT; % read (0) or write (1) request from VME % vme_dat[31..0] : BIDIR; % port used to download input mask % vme_address[13..2]: INPUT; % VME address bus % vme_proc_clk : INPUT; % clock to load masks from VME % vme_fifo_wen : INPUT; vme_version_ren : INPUT; % enables vme reading of the code version number % fred_delay[5..0] : INPUT; % alignment delay (constant) in units of 22 ns % thres_sel[1..0] : INPUT; % threshold selector for sumet pfred, % % here only used to define mask for bad channels % src_etin : INPUT; % What feeds this chip: % % 0=backplane (normal run), 1=VME_address bus % etin[11..0][9..0] : INPUT; % input trigger bits - 12 set of signals from aux card% % 20 differential LVDS channels to etin10[9..0] and etin11[9..0] % % 4 single ended NIM signals to etin[3..0]_0 % % 2 TTL signals to etin[5..4]_0 % % 2 ECL signals to etin[7..6]_0 % % 2 LVDS signals to etin[9..8]_0 % dataout_ren[1..0] : INPUT; % enables vme reading of dataout, i.e. trigword & % % to_fred % dataout[55..0] : OUTPUT; sram_enable : OUTPUT; %**** the following signals are not used in this module, defined as input to keep pin assignment *****% lut_address[5..0][11..0] : INPUT; % output in sumet % lut_data[5..0][11..0] : INPUT; % bidir in sumet % vme_lut_en[2..0] : INPUT; ) VARIABLE _clk_132ns[2..0] : GLOBAL; load : NODE; vme_wen : NODE; % vme_write & load % vme_read : NODE; run_ : NODE; % run # src_etin % vme_data[31..0] : TRI_STATE_NODE; % fake_etin[11..0][9..0] : TRI; fake_trigbits[19..0] : TRI; fake_b0delayed : TRI; % datain[11..0][9..0] : TRI_STATE_NODE; etin_[11..0][9..0] : DFFE; % trigger bit from muon system % mask_et[11..0][9..0] : DFFE; % mask for etin data. % tri_mask_et[11..0] : TRI; tri_b0delayed : TRI; tri_dataout[55..15] : TRI; tri_etin[11..0][9..0] : TRI; tri_trigbits[39..0] : TRI; % 19..0 are b0_delayed, 39..20 are the original ones % tri_version[7..0] : TRI; tri_dummy[2..0] : TRI; datout[55..15] : TRI_STATE_NODE; outpipe[20..0] : lpm_shiftreg WITH (LPM_WIDTH=8); % FRED alignment pipeline % align_mux : lpm_mux WITH (LPM_WIDTH=21, LPM_SIZE=8, LPM_WIDTHS=3); % picks the output with desired align delay % select_clk : lpm_mux WITH (LPM_WIDTH=1, LPM_SIZE=6, LPM_WIDTHS=3); tofred[20..0] : DFFE; %20 trigger bits and b0delayed % trgbts[19..0] : DFFE; % trigger bits before Fred delay% version[7..0] : NODE; trg_out[19..0] : NODE; BEGIN _clk_132ns[] = !clk_132ns[]; etin_[][].clk = _clk_132ns2; trgbts[].clk = _clk_132ns2; tri_dummy[].in = GND; tri_dummy[].oe = dataout_ren1; vme_data[23..21] = tri_dummy[2..0].out; % dummy assignment, 23..21 actually unused % run_ = run # src_etin; etin_[][].ena = run_; % I. LOAD mode % load = !run; vme_read = !vme_write; vme_wen = vme_write & load; version[] = 5; tri_version[].in = version[]; tri_version[].oe = vme_version_ren; vme_data[31..24] = tri_version[].out; mask_et[][].clk = vme_proc_clk; mask_et[][].ena = vme_wen & thres_sel0 & thres_sel1; mask_et[]_0.d = vme_dat[11..0]; mask_et[]_1.d = vme_dat[11..0]; mask_et[]_2.d = vme_dat[11..0]; mask_et[]_3.d = vme_dat[11..0]; mask_et[]_4.d = vme_dat[11..0]; mask_et[]_5.d = vme_dat[11..0]; mask_et[]_6.d = vme_dat[11..0]; mask_et[]_7.d = vme_dat[11..0]; mask_et[]_8.d = vme_dat[11..0]; mask_et[]_9.d = vme_dat[11..0]; tri_mask_et[].in = mask_et[]_0.q; tri_mask_et[].oe = vme_read & thres_sel0 & thres_sel1; vme_data[11..0] = tri_mask_et[].out; tri_trigbits[19..0].in = tofred[19..0].q; tri_trigbits[39..20].in = trgbts[19..0].q; tri_trigbits[19..0].oe = dataout_ren0; tri_trigbits[39..20].oe = dataout_ren1; vme_data[19..0] = tri_trigbits[19..0].out; vme_data[19..0] = tri_trigbits[39..20].out; tri_b0delayed.in = tofred20.q; tri_b0delayed.oe = dataout_ren0; vme_data20 = tri_b0delayed.out; vme_dat[] = vme_data[]; % this seems like an overkill, but kept for symmetry with sumet % % fake_trigbits[19..0].in = vme_dat[19..0]; fake_trigbits[19..0].oe = vme_fifo_wen; datout[50..35] = fake_trigbits[19..4].out; datout[54..51] = fake_trigbits[3..0].out; datout[34..15] = fake_trigbits[19..0].out; fake_b0delayed.in = vme_dat20; fake_b0delayed.oe = vme_fifo_wen; datout55 = fake_b0delayed.out; fake_etin0_[].in = vme_address[11..2]; fake_etin1_[].in = (vme_address11,vme_address2,vme_address[10..3]); fake_etin2_[].in = (vme_address11,vme_address[3..2],vme_address[10..4]); fake_etin3_[].in = (vme_address11,vme_address[4..2],vme_address[10..5]); fake_etin4_[].in = (vme_address11,vme_address[5..2],vme_address[10..6]); fake_etin5_[].in = (vme_address11,vme_address[6..2],vme_address[10..7]); fake_etin6_[].in = (vme_address11,vme_address[7..2],vme_address[10..8]); fake_etin7_[].in = (vme_address11,vme_address[8..2],vme_address[10..9]); fake_etin8_[].in = (vme_address11,vme_address[9..2],vme_address10); fake_etin9_[].in = vme_address[11..2]; fake_etin10_[].in = (vme_address11,vme_address2,vme_address[10..3]); fake_etin11_[].in = (vme_address11,vme_address[3..2],vme_address[10..4]); fake_etin[][].oe = src_etin; datain[][] = fake_etin[][].out; % % II. RUN mode: % tri_etin[][].in = etin[][]; tri_etin[][].oe = run; datain[][] = tri_etin[][].out; etin_[][].d = datain[][] & !mask_et[][]; % OR bits from single input signals and differential LVDS from first 20 pin connector % trg_out0 = etin_10_0.q#etin_0_0; trg_out1 = etin_10_1.q#etin_1_0; trg_out2 = etin_10_2.q#etin_2_0; trg_out3 = etin_10_3.q#etin_3_0; trg_out4 = etin_10_4.q#etin_4_0; trg_out5 = etin_10_5.q#etin_5_0; trg_out6 = etin_10_6.q#etin_6_0; trg_out7 = etin_10_7.q#etin_7_0; trg_out8 = etin_10_8.q#etin_8_0; trg_out9 = etin_10_9.q#etin_9_0; trg_out[19..10] = etin_11_[].q;  trgbts[19..0].d = trg_out[19..0]; outpipe[19..0].shiftin = trg_out[]; outpipe20.shiftin = b0_delayed; outpipe[].clock = _clk_132ns1; align_mux.data0_[] = outpipe[].q0; align_mux.data1_[] = outpipe[].q1; align_mux.data2_[] = outpipe[].q2; align_mux.data3_[] = outpipe[].q3; align_mux.data4_[] = outpipe[].q4; align_mux.data5_[] = outpipe[].q5; align_mux.data6_[] = outpipe[].q6; align_mux.data7_[] = outpipe[].q7; align_mux.sel[] = fred_delay[5..3]; select_clk.data0_0 = _clk_132ns1; select_clk.data1_0 = _clk_132ns2; select_clk.data2_0 = clk_132ns0; select_clk.data3_0 = clk_132ns1; select_clk.data4_0 = clk_132ns2; select_clk.data5_0 = _clk_132ns0; select_clk.sel[] = fred_delay[2..0]; % fine delay : selects which clock the trigger bits will be sent out to FRED on % tofred[].clk = select_clk.result0; tofred[].d = align_mux.result[]; tri_dataout[34..15].in = trgbts[].q; % these bits go to the L2 buffers and front panel % tri_dataout[54..51].in = tofred[3..0].q; % to allign bits properly on the back plane, need to follow pfred-sumet assignements% tri_dataout[50..35].in = tofred[19..4].q; tri_dataout[55].in = tofred[20].q; tri_dataout[].oe = run; datout[] = tri_dataout[].out; dataout[19..0] = datout[34..15]; % lowest 10 trigger bits will correspond to first 10 bits of sumet% % highest 10 trigger bits will correspond to bit 10 of sumet and bits 9-0 of sumex% dataout[55..35] = datout[55..35]; dataout[34..20] = GND; sram_enable = VCC; END;