function [pushFIFO, popFIFO, upperPop,  InitializeFlag, ...
enableDataCacheOut,unloadhStartOut, unloadhEndOut, ...
unloadvEndOut, unloadValidOut, unloadingDelayedOut, lineMaskOut, runOrUnload, validOut,delayedVStartOut,resetFIFO, loadingFlag,UnloadingOut, lineSpaceLoad, lineSpaceEn, loadCount]   = FIFOHandler(...
  allLineStart, hStartIn, vEndIn, validIn, lineSpaceAverageIn, allNextLineStart, vEndFlag, allFIFOEmpty, vStartIn, hEndIn,halfLoaded)
%#codegen


persistent LoadingPaddingRunCount;
persistent RunningPaddingRunCount;
persistent UnloadingPaddingRunCount;
persistent InterFrameCount;
persistent InitializeCount;
persistent Loading;
persistent Unloading;
persistent Running;
persistent Initialize;
persistent UnloadingDelayed;
persistent DelayedVStart;
persistent InBetween;
persistent LineSpace;
persistent LineMask;
persistent removeThis;

persistent unloadPop;
persistent InterFrameReset;
persistent unloadToggle;


loadTo = uint8(0);

if isempty(Loading)
LoadingPaddingRunCount = uint8(0);
RunningPaddingRunCount = uint8(0);
UnloadingPaddingRunCount = uint8(0);
InterFrameCount = uint8(0);
InitializeCount = uint8(0);
loadTo = uint8(0);
Loading = false;
Unloading = false;
Running = false;
Initialize = true;
InterFrameReset = false;
UnloadingDelayed = false;
DelayedVStart = false;
InBetween = false;
LineSpace = uint32(0);
LineMask = fi(0,0,LOADTO,0);
removeThis = int16(0);
localValid = false;
runOrUnload = false;
lineMaskOut = fi(0,0,LOADTO,0);
popFIFO = fi(0,0,LOADTO,0);
pushFIFO = fi(0,0,LOADTO,0);
upperPop = fi(0,0,HALFHEIGHT,0);
upperPopREG = fi(0,0,HALFHEIGHT,0); 
upperPopTemp = fi(0,0,HALFHEIGHT,0);
FIFOPopREG = fi(0,0,HALFHEIGHT,0);
popFIFO4REG = fi(0,0,HALFHEIGHT,0);
pushFIFO4REG = fi(0,0,HALFHEIGHT,0);
unloadToggle = logical(zeros(1,3));

end


popFIFO(:) =  0;
pushFIFO(:) = 0;     
upperPop(:) = 0;
popLast = false;
enableDataCacheOut = false;
unloadhStartOut = false;
unloadhEndOut = false;
unloadvEndOut = false;
unloadValidOut = false;
unloadingDelayedOut=false;
lineMaskOut(:) = 0;
validOut = false;
resetFIFO = false;
unloadPop = false;

    

if vStartIn
Loading = true;
Unloading = false;
Initialize = false;
InterFrameReset = false;
removeThis(:) =0; 
LoadingPaddingRunCount(:) = 1;
InterFrameCount(:) = 0;
InitializeCount(:) = 0;
elseif hEndIn
 LoadingPaddingRunCount(:) = LoadingPaddingRunCount -1;   
end


if (validIn) && (Loading)
         DelayedVStart = false;
 


    pushFIFO = bitset(pushFIFO,1);
    popFIFO  =  bitset(popFIFO,1);
    popFIFO  =  bitset(popFIFO,2);


  if  Loading  && hStartIn && (LoadingPaddingRunCount == 0)
              Loading = false;
             RunningPaddingRunCount(:) = 0;
              Running = true;
              Unloading = false;
              unloadToggle(:) = 0;
              Initialize = false;
              DelayedVStart = true; 
               popFIFO  =  bitset(popFIFO,2,0);
          end  


   
end

% if Loading
% 
%         if halfLoaded == 0 
%     popFIFO = bitset(popFIFO,2);
%        end
% 
% 
%     if allLineStart == 0 
%     popFIFO = bitset(popFIFO,1);
%     pushFIFO = bitset(pushFIFO,2);
%     end
% 
% end

if Running 
      if removeThis==1
      DelayedVStart = false ; 
      end
    removeThis(:) =1; 
      
    upperPopTemp(:) = 0;

       if (hStartIn && DelayedVStart)
          RunningPaddingRunCount(:) = 0;
      elseif (hStartIn && RunningPaddingRunCount ~= 1)
         RunningPaddingRunCount(:) =1;
      end

      enableDataCacheOut = true;
      
          loadTo(:) = LOADTO;



          popFIFO = bitset(popFIFO, 1);  
          pushFIFO = bitset(pushFIFO, 2);
     
          if  (RunningPaddingRunCount == 1)&&(~DelayedVStart)
         popFIFO = bitset(popFIFO,LOADTO);
          end
      

%         popLast = (RunningPaddingRunCount == 0);

       if validIn
      pushFIFO = bitset(pushFIFO,1);
       end




%% Unloading

end
runOrUnload = Running||Unloading;




if Unloading
 unloadhStartOut = false;
    if (~InBetween) && allNextLineStart && unloadToggle(3) 
  unloadhEndOut   = true;
  unloadvEndOut = unloadhEndOut && (UnloadingPaddingRunCount==0);
       unloadToggle(1) = false;
    end
 
unloadToggle(2:3) = unloadToggle(1:2);


    if InBetween
            lineSpaceEn  =true;
        if lineSpaceAverageIn == 1
         unloadingDelayedOut = true;
            InBetween = false;
            lineSpaceLoad= true;
            lineSpaceEn  =false;
            if UnloadingPaddingRunCount == 0
                 Unloading = false;
                 InterFrameReset = true;
               lineSpaceLoad = false;
               lineSpaceEn  =true;
               unloadToggle(:) = 0;
            else
                 lineSpaceLoad = false;
                 lineSpaceEn  =true;
                UnloadingPaddingRunCount = UnloadingPaddingRunCount -1;
                unloadhStartOut = true;
                 LineMask(:) =  bitsll(LineMask,1);
                unloadToggle(1) = true;

            end 
        else
             lineSpaceLoad = false;
             lineSpaceEn  =true;  
        end   
    else
              lineSpaceEn = false;
        unloadingDelayedOut = false;  
    end


    lineMaskOut = LineMask;

     enableDataCacheOut = true;

    
     loadTo(:) = LOADTO;



%         end
     
if ~InBetween
popFIFO = bitset(popFIFO,2);
pushFIFO = bitset(pushFIFO,2,1);
      pushFIFO = bitset(pushFIFO,1,1);
      popFIFO  = bitset(popFIFO,1,1);
unloadPop = true;
else
unloadPop = false;
popFIFO = bitset(popFIFO,2,0);
pushFIFO = bitset(pushFIFO,2,0);
      pushFIFO = bitset(pushFIFO,1,0);
      popFIFO  = bitset(popFIFO,1,0);
end
   
    if unloadhEndOut &&~unloadhStartOut
    InBetween = true;
lineSpaceLoad = false;
% lineSpaceEn = true;
    elseif lineSpaceAverageIn == 2
     lineSpaceLoad = true; 
    else
       lineSpaceLoad = false; 
    
    end

 unloadValidOut = ~InBetween;

%         validOut = ~InBetween;
else
    lineSpaceLoad = false;
    lineSpaceEn = false;
    
    
    
end


if validIn && vEndIn
    InBetween = true;
    lineSpaceLoad = true;
    UnloadingPaddingRunCount(:) = 1;

    LineMask(:) = bitset(LineMask,1,1);
    for ii = 2:1:LOADTO
    LineMask(:) = bitset(LineMask,ii,0);
    end
    unloadhStartOut = false;

popFIFO = bitset(popFIFO,2);
pushFIFO = bitset(pushFIFO,2,1);
unloadPop = true;

     Loading = false;
     Running = false;
     Unloading = true;
     InterFrameReset = false;
   enableDataCacheOut = true;
end



UnloadingOut = Unloading;

% if vEndFlag
% Initialize = true;
% Unloading = true;
% removeThis(:) = 0;
% end

% if Initialize
% popFIFO(:) = (2^(LOADTO)+1)-1;
% pushFIFO(:) = 0; 
% end

if InterFrameReset == true
% Initialize = false;
if InterFrameCount <6
popFIFO = bitset(popFIFO,2,0);
pushFIFO = bitset(pushFIFO,2,0);
pushFIFO = bitset(pushFIFO,1,1);
popFIFO  = bitset(popFIFO,1,0);
enableDataCacheOut = true;
InterFrameCount(:) = InterFrameCount +1;
resetFIFO = true;
else
popFIFO = bitset(popFIFO,2,0);
pushFIFO = bitset(pushFIFO,2,0);
pushFIFO = bitset(pushFIFO,1,0);
popFIFO  = bitset(popFIFO,1,0);
enableDataCacheOut = true;
resetFIFO = true;
end
end

if Initialize == true
% Initialize = false;
if InitializeCount <6
popFIFO = bitset(popFIFO,2,0);
pushFIFO = bitset(pushFIFO,2,1);
pushFIFO = bitset(pushFIFO,1,1);
popFIFO  = bitset(popFIFO,1,0);
InitializeCount(:) = InitializeCount +1;
enableDataCacheOut = true;
resetFIFO = false;
else
popFIFO = bitset(popFIFO,2,0);
pushFIFO = bitset(pushFIFO,2,0);
pushFIFO = bitset(pushFIFO,1,0);
popFIFO  = bitset(popFIFO,1,0);
enableDataCacheOut = true;
resetFIFO = true;
end
end



% upperPopREG(:) = upperPopTemp;
% upperPop(:) = upperPopREG;

% if validIn
% FIFOPopREG = upperPopTemp;
% end

% for ii = 1:1:HALFHEIGHT
% if bitget(FIFOPopREG,ii)
% popFIFO = bitset(popFIFO,ii+HALFHEIGHT);
% pushFIFO = bitset(pushFIFO, ii + HALFHEIGHT+1);
% end
% end
InitializeFlag = Initialize || InterFrameReset;
delayedVStartOut = DelayedVStart;
validOut = validIn;
loadingFlag = Loading;
upperPop = unloadPop;
loadCount = LoadingPaddingRunCount;
