%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;