TITLE "Merger"; FUNCTION fifologic(clock,ee,ef[4..0],disable[4..0],reset,testmode) RETURNS (ren[4..0],fifoclock[4..0],ffend[4..0]); FUNCTION lpm_ff (data[LPM_WIDTH-1..0], clock, enable, sclr, sset, sload, aclr, aset, aload) WITH (LPM_WIDTH, LPM_AVALUE, LPM_SVALUE, LPM_FFTYPE) RETURNS (q[LPM_WIDTH-1..0]); 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]); FUNCTION mergevmedecode (vmeaddress[10..0],load,vmewrite,vme_as) RETURNS (vmefiforead[9..0],vmedisableread,vmedisablewrite, vmefifoefread); SUBDESIGN merge ( clock : INPUT; afifohit[17..0] : INPUT; bfifohit[17..0] : INPUT; afifoef[4..0] : INPUT; bfifoef[4..0] : INPUT; hold : INPUT; afiforen[4..0] : OUTPUT; bfiforen[4..0] : OUTPUT; afifoclock[4..0] : OUTPUT; bfifoclock[4..0] : OUTPUT; hit[17..0] : OUTPUT; stream[5..0] : OUTPUT; outclock : OUTPUT; % VME interface % vmedata[17..0] : BIDIR; vmeclock : INPUT; vmeaddress[10..0] : INPUT; vmewrite : INPUT; hf_load : INPUT; hf_init : INPUT; hf_test : INPUT; vme_as : INPUT; vmespare : INPUT; HF_Spare : INPUT; Merger_Spare : OUTPUT; ) VARIABLE holdff : DFFE; ahit[17..0] : DFFE; astream[4..0] : DFFE; afifologic : fifologic; bhit[17..0] : DFFE; bstream[4..0] : DFFE; bfifologic : fifologic; chit : lpm_ff WITH (LPM_WIDTH=18); cstream : lpm_ff WITH (LPM_WIDTH=6); halfclock : DFFE; disable[9..0] : DFFE; mergevmedecoder : mergevmedecode; fifomux : lpm_mux WITH (LPM_WIDTH=18, LPM_SIZE=2, LPM_WIDTHS=1); streammux : lpm_mux WITH (LPM_WIDTH=6, LPM_SIZE=2, LPM_WIDTHS=1); affend,bffend, go,remember : NODE; % VME stuff % afifovmetri[17..0]:TRI; bfifovmetri[17..0]:TRI; disablevmetri[17..0]:TRI; fifoefvmetri[17..0]:TRI; % tri state nodes for BIDIR pins % vmedatatri[17..0]:TRI_STATE_NODE; % multiplexes vme with merger for HITLIST requests% avmemergemux :lpm_mux WITH (LPM_WIDTH=10, LPM_SIZE=2, LPM_WIDTHS=1); bvmemergemux :lpm_mux WITH (LPM_WIDTH=10, LPM_SIZE=2, LPM_WIDTHS=1); vmedisablemux :lpm_mux WITH (LPM_WIDTH=10, LPM_SIZE=2, LPM_WIDTHS=1); % vme input/output enables % vmefiforead[9..0], vmedisableread,vmedisablewrite, vmefifoefread :NODE; BEGIN % Spare % Merger_Spare = HF_Spare & vmespare; % VME stuff % vmedata[] = vmedatatri[]; % decode VME address % mergevmedecoder.vmeaddress[] = vmeaddress[]; mergevmedecoder.vmewrite = vmewrite; mergevmedecoder.vme_as = vme_as; mergevmedecoder.load = hf_load; vmefiforead[] = mergevmedecoder.vmefiforead[]; vmedisableread = mergevmedecoder.vmedisableread; vmedisablewrite = mergevmedecoder.vmedisablewrite; vmefifoefread = mergevmedecoder.vmefifoefread; % read HITLISTs over VME % % enable output from first 5 HITLISTs % afifovmetri[17..0].in = afifohit[]; afifovmetri[].oe = vmefiforead[0] # vmefiforead[1] # vmefiforead[2] # vmefiforead[3] # vmefiforead[4]; vmedatatri[] = afifovmetri[].out; % enable output from second 5 HITLISTs % bfifovmetri[17..0].in = bfifohit[]; bfifovmetri[].oe = vmefiforead[5] # vmefiforead[6] # vmefiforead[7] # vmefiforead[8] # vmefiforead[9]; vmedatatri[] = bfifovmetri[].out; % multiplex fiforen and fifoclk from merger with% % vmefiforead and vmeclock % avmemergemux.data[0][4..0] = afifologic.ren[4..0]; avmemergemux.data[1][4..0] = vmefiforead[4..0]; avmemergemux.data[0][9..5] = afifologic.fifoclock[4..0]; avmemergemux.data[1][9..5] = (vmefiforead[4..0] # vmefifoefread) & vmeclock; avmemergemux.sel[] = hf_load; afifoclock[] = avmemergemux.result[9..5]; afiforen[] = !avmemergemux.result[4..0]; bvmemergemux.data[0][4..0] = bfifologic.ren[4..0]; bvmemergemux.data[1][4..0] = vmefiforead[9..5]; bvmemergemux.data[0][9..5] = bfifologic.fifoclock[4..0]; bvmemergemux.data[1][9..5] = (vmefiforead[9..5] # vmefifoefread) & vmeclock; bvmemergemux.sel[] = hf_load; bfifoclock[] = bvmemergemux.result[9..5]; bfiforen[] = !bvmemergemux.result[4..0]; % write to disable mask over VME % vmedisablemux.data[0][] = disable[].q; vmedisablemux.data[1][] = vmedata[9..0]; vmedisablemux.sel[] = vmedisablewrite; disable[].clk = vmeclock; disable[].d = vmedisablemux.result[]; % read disable mask over VME % disablevmetri[9..0].in = disable[].q; disablevmetri[17..10].in = GND; disablevmetri[].oe = vmedisableread; vmedatatri[] = disablevmetri[].out; % read fifo empty flags over vme % fifoefvmetri[4..0].in = afifoef[]; fifoefvmetri[9..5].in = bfifoef[]; fifoefvmetri[17..10].in = GND; fifoefvmetri[].oe = vmefifoefread; vmedatatri[] = fifoefvmetri[].out; % end VME stuff % holdff.d = hold; holdff.clk = clock; holdff.clrn = !(hf_init # hf_load); holdff.ena = VCC; go = VCC; % was !hold % remember = !hf_init; % read out 2 sets of 5 fifos each at half the speed of the system clock% halfclock.clk = clock; halfclock.d = !halfclock.q; halfclock.prn = VCC; halfclock.clrn = remember; halfclock.ena = go; % register input from fifos % ahit[].clk = halfclock.q; ahit[].d = afifohit[]; ahit[].prn = VCC; ahit[].clrn = remember; ahit[].ena = go; % register stream number of the fifo being read% astream[].clk = halfclock.q; astream[].d = !afiforen[]; % added invert wja 1998-08-20 % astream[].prn = VCC; astream[].clrn = remember; astream[].ena = go; % fifologic determines which fifos are enabled and clocked% afifologic.clock = halfclock.q; afifologic.ee = afifohit[15]; afifologic.ef[] = afifoef[] & !holdff.q; afifologic.disable[] = disable[4..0].q; afifologic.reset = (affend & bffend) # hf_init; afifologic.testmode = hf_test; % repeat for second set of 5 fifos % bhit[].clk = !halfclock.q; bhit[].d = bfifohit[]; bhit[].prn = VCC; bhit[].clrn = remember; bhit[].ena = go; bstream[].clk = !halfclock.q; bstream[].d = !bfiforen[]; bstream[].prn = VCC; bstream[].clrn = remember; bstream[].ena = go; bfifologic.clock = !halfclock.q; bfifologic.ee = bfifohit[15]; bfifologic.ef[] = bfifoef[] & !(hf_test & !affend) & !holdff.q; bfifologic.disable[] = disable[9..5].q; bfifologic.reset = (affend & bffend) # hf_init; bfifologic.testmode = hf_test; affend = afifologic.ffend4 & afifologic.ffend3 & afifologic.ffend2 & afifologic.ffend1 & afifologic.ffend0; bffend = bfifologic.ffend4 & bfifologic.ffend3 & bfifologic.ffend2 & bfifologic.ffend1 & bfifologic.ffend0; % demultiplex the 2 fifo input buses into one output bus % chit.clock = clock; fifomux.data[0][] = bhit[].q; fifomux.data[1][] = ahit[].q; fifomux.sel[] = halfclock.q; chit.data[] = fifomux.result[]; chit.aclr = hf_init; chit.sclr = (streammux.result[4..0]==0); chit.enable = go; cstream.clock = clock; streammux.data[0][4..0] = bstream[].q; streammux.data[0][5] = VCC; streammux.data[1][4..0] = astream[].q; streammux.data[1][5] = GND; streammux.sel[] = halfclock.q; cstream.data[] = streammux.result[]; cstream.aclr = hf_init; cstream.sclr = (streammux.result[4..0]==0); cstream.enable = go; hit[] = chit.q[]; stream[] = cstream.q[]; outclock = !clock; END;