%fifo_port reads DSP fifo data to vme and generates FIFO_EVTEND to dspfifo% %also builds and sends fifo output status word to vme 3/22/00 % SUBDESIGN FIFO_PORT1 %modified to remove S3 state 7/28/00 % ( CLK, %40 MHZ LOCAL CLOCK% /RST, %SOFT RESET FROM VME_PORT.TDF% DI[31..0], %FIFO DATA% FIFO_EVTRDY, %FLAG FROM OUTFPGA THAT FIFO HAS A EVENT TO BE READ% vmeadd[13..6], %vme address as command% ST6,ST7,ST8,ST15 %READ CONTROL PULSES FROM VME_PORT1% : input; FIFO_EVTEND, %PULSE TO DSPFIFO.TDF THAT THE EVENT READ IS COMPLETED% /REN, %FIFO READ ENABLE% /OE, %FIFO OUTPUT ENABLE% BSY, %FIFO_PORT IS BUSY, TO VME_PORT1.TDF% DO[31..0] %FIFO OUTPUT DATA/STATUS TO VME_PORT% : OUTPUT; ) VARIABLE WCNT[15..0] :DFF; %COUNTS WORD # IN AN EVENT% WREG[15..0] :DFFE; %CATCH WORD # FROM HEARDER WORD% SEL :NODE; %FIFO PORT IS SELECTED% EODATA :LCELL; %INDICATES THE CATCHING OF THE TRAILER WORD% EOWCNT :LCELL; %SET WHEN WCNT REACH THE TOTAL WORD #% WDLY[1..0] :DFF; % 2 CYCLE DELEY FROM EOWCNT% STATUS[31..0] :DFFE; %FIFO OUTPUT STATUS REG. TO VME% ERR :LCELL; %TRAILER AND LAST WORD# DO NOT ARRIVE AT SAME CYCLE% S: machine of bits (sb[1..0]) with states ( S0 = B"00", S1 = B"01", S2 = B"10", S3 = B"11"); BEGIN %FIFO PORT IS SELECTED% SEL = (VMEADD[13..11] == 2); /OE = !(SEL & (VMEADD[10..6] == 7)); %fifo /oe is low true% %CONTROL SEQUENCE% S.CLK = CLK; S.RESET = !SEL; CASE S IS WHEN S0 => IF (VMEADD[10..6] == 7) %& FIFO_EVTRDY %& ST6 THEN S = S1; % ELSIF (VMEADD[10..6] == 7) & !FIFO_EVTRDY & ST6 THEN% % S = S3; % %new, 7/28/00% ELSIF (VMEADD[10..6] == 6) & ST6 THEN S = S2; ELSE S = S0; END IF; WHEN S1 => IF ST15 THEN S = S0; ELSE S = S1; END IF; WHEN S2 => IF ST15 THEN S =S0; ELSE S = S2; END IF; % WHEN S3 => IF ST15 THEN S = S0; ELSE S = S3; END IF; % END CASE; %FIFO DATA/STATUS READ BACK TO VME_PORT% /REN = !(ST7 & S1); DO[31..0] = S1 & DI[31..0] # S2 & STATUS[31..0] %# S3 & GND%; %new, 7/28/00% BSY = SEL & (ST7 # ST8); %FIFO_EVTEND % WCNT[].CLK = CLK; WCNT[].CLRN = FIFO_EVTRDY; IF !/REN THEN WCNT[].D = WCNT[].Q +1; ELSE WCNT[].D = WCNT[].Q; END IF; EODATA = (DO[31..0] == H"00000E0E") & S1; %SET WHEN REACH THE TRAILER WORD% %FETCH AND STORE THE HEADER WORD FOR WORD # COMPARISON% WREG[15..0].CLK = CLK; WREG[].ENA = ST8 & (WCNT[]==1); WREG[].D = DI[15..0]; %CATCH HEADER WORD% EOWCNT = (WCNT[] == WREG[]) & (WCNT[] !=0); %WCNT[] COUNTS TO TOTAL # OF WORD EXCLUDING HEADER AND TRAILER% WDLY[].CLK = ST7 & S1; WDLY[0].D = EOWCNT; WDLY[1].D = WDLY[0].Q; FIFO_EVTEND = EODATA & WDLY[1].Q; %FIFP_EVTEND IS SET WHEN TRAILER WORD AND (TOTAL WORD#) ARRIVED AT SAME CYCLE% ERR = (EODATA $ WDLY[1].Q); %ERROR FLAG IS SET WHEN TRAILER WORD AND (TOTAL WORD#) ARRIVED AT DIFFERENT CYCLE% %FIFO STATUS REG.% STATUS[31..0].CLK = CLK; STATUS[].CLRN = /RST; STATUS[15..0].ENA = VCC; STATUS[15..0].D = WCNT[15..0].Q; STATUS[16].ENA = VCC ; STATUS[16].D = FIFO_EVTRDY; %FROM DSPOUTFPGA.TDF% STATUS[17].ENA = ST15 & S1; STATUS[17].D = (ERR # STATUS[17].Q) & (wcnt[]!=1); %fifo_evtend error% STATUS[18].ENA = S3 & ST15; STATUS[18].D = S3; %!EVT_RDY, READ BACK NULL% STATUS[31..19].ENA = VCC; STATUS[31..19].D = GND; END;