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)

%

% Copyright 2014-2020 The MathWorks, Inc.

%#codegen

persistent LoadingPaddingRunCount;
persistent RunningPaddingRunCount;
persistent UnloadingPaddingRunCount;
persistent InitialCount;
persistent Loading;
persistent Unloading;
persistent Running;
persistent Initialize;
persistent InterFrameReset;
persistent DelayedVStart;
persistent InBetween;
persistent LineSpace;
persistent LineMask;
persistent removeThis;
persistent loadCounter;
persistent upperHalfPopCount;
persistent upperPopREG;
persistent FIFOPopREG;
persistent resetFIFOREG;
persistent unloadToggle;



if isempty(Loading)
LoadingPaddingRunCount =uint8(0);
RunningPaddingRunCount =fi(0,0,CEILHALFWIDTHHEIGHT,0,'OverflowAction','Saturate');
UnloadingPaddingRunCount = uint8(0);
InitialCount = uint8(0);
upperHalfPopCount =fi(0,0,COUNTERT,0);
% loadTo = uint8(0);
loadTo = uint16(0);
Loading = false;
Unloading = false;
Running = false;
Initialize = true;
InterFrameReset = false;
DelayedVStart = false;
InBetween = false;
LineSpace = fi(0,0,LINESPACET,0);
loadCounter =fi(0,0,COUNTERT,0);
LineMask = fi(0,0,LOADTO,0);
 removeThis = false;
% 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);
% resetFIFOREG = false;
unloadToggle = false(1,8);
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;





if vStartIn
Loading = true;
Initialize = false;
InterFrameReset = false;
removeThis =false; 
LoadingPaddingRunCount(:) = HALFHEIGHT;
end



if (validIn) && (Loading)
         DelayedVStart = false;
 
if hStartIn && (vStartIn==0)
LoadingPaddingRunCount(:) = LoadingPaddingRunCount -1;
end

    for ii = 1:1:HALFHEIGHT
    popFIFO  =  bitset(popFIFO,ii);
    pushFIFO = bitset(pushFIFO,ii); 
%     pushFIFO = bitset(pushFIFO,ii);  
    end

%     if LoadingPaddingRunCount == HALFHEIGHT
%      pushFIFO = bitset(pushFIFO,HALFHEIGHT,1);
%     if ((bitget(halfLoaded,HALFHEIGHT)) == 0)
%     popFIFO = bitset(popFIFO, HALFHEIGHT,1);
%     pushFIFO = bitset(pushFIFO,HALFHEIGHT+1,1);
%     end
%     else
%      pushFIFO = bitset(pushFIFO,HALFHEIGHT,0);
%      popFIFO = bitset(popFIFO, HALFHEIGHT,0);
%      end 
% 
% for ii = 1:1:HALFHEIGHT-1
% 
%     if LoadingPaddingRunCount <= ii
%    if ((bitget(halfLoaded,ii)) == 0)
%     popFIFO = bitset(popFIFO,ii,1);
%     pushFIFO = bitset(pushFIFO,ii+1,1);
%    else
%     popFIFO = bitset(popFIFO,ii,0);
%     pushFIFO = bitset(pushFIFO,ii+1,0);
%    end
%    end
% %     if PaddingRunCount == 1
% %     if ((bitget(halfLoaded,1)) == 0)
% %     popFIFO = bitset(popFIFO,1,1);
% %     pushFIFO = bitset(pushFIFO,2,1);
% %     else
% %     popFIFO = bitset(popFIFO,1,0);
% %     pushFIFO = bitset(pushFIFO,2,0);
% %     end
% %     end
% 
% end
%     if allLineStart == 0 
%     pushFIFO = bitset(pushFIFO,HALFHEIGHT);
%     end

          if  Loading  && hStartIn && LoadingPaddingRunCount ==0
              Loading = false;
              Running = true;
              DelayedVStart = true; 
         else
        DelayedVStart = false;
          end


end


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

      if (hStartIn && DelayedVStart)
          RunningPaddingRunCount(:) = 1;
          upperPopTemp = bitset(upperPop,RunningPaddingRunCount);
      elseif ((hStartIn && RunningPaddingRunCount ~= 0) && ((RunningPaddingRunCount< 253)))
         RunningPaddingRunCount(:) = RunningPaddingRunCount + 1;
  upperPopTemp = bitset(upperPop,RunningPaddingRunCount);
      end

      enableDataCacheOut = true;
      
      if (RunningPaddingRunCount == HALFHEIGHT)
          loadTo(:) = LOADTO;
      else
          loadTo(:) = HALFHEIGHT + RunningPaddingRunCount;

      end
%             for ii = 1:1:HALFHEIGHT
%                 if ii == (upperHalfPopCount)
%                 upperPopTemp = bitset(upperPop,ii);
%                 else
%                 upperPopTemp = bitset(upperPop,ii,0);
%                 end
%             end

      popFIFO(:) = 0;
      pushFIFO(:) = 0;

      for ii = 2:1:KERNELHEIGHT
          if ii<= loadTo
          popFIFO = bitset(popFIFO, ii-1);  
          pushFIFO = bitset(pushFIFO, ii);
        end
      end
      
      if validIn
      pushFIFO = bitset(pushFIFO,1);
      end



else
upperPopTemp(:) = 0;


end
      if validIn && vEndIn
          Loading = false;
          Running = false;
          Unloading = true;
          InterFrameReset = false;
          UnloadingDelayed = false;
      UnloadingPaddingRunCount(:) = PADRUN;
    
       end




%% Unloading



runOrUnload = Running||Unloading;

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

    end


%         if InBetween
%             lineSpaceEn = true;
%         else
%             lineSpaceEn = false;
%         end

unloadToggle(2:end) = unloadToggle(1:end-1);

    if InBetween
    lineSpaceEn  =true;

        if lineSpaceAverageIn == 1
         unloadingDelayedOut = true;
            InBetween = false;
        lineSpaceLoad= true;
            lineSpaceEn  =false;

            if UnloadingPaddingRunCount == 0
                 Unloading = false;
                 UnloadingDelayed = false;
              InterFrameReset = true;
                lineSpaceLoad = false;
               lineSpaceEn  =true;
               unloadToggle(:) = 0;

            else
                lineSpaceLoad = false;
                 lineSpaceEn  =true;

                UnloadingPaddingRunCount(:) = UnloadingPaddingRunCount -1;
                unloadhStartOut = true;
                unloadToggle(1) = false;
                LineMask(:) =  bitsll(LineMask,1);
              InterFrameReset = false;
                           lineSpaceLoad = false;
                 lineSpaceEn  =true;

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

     enableDataCacheOut = true;

    
     loadTo(:) = LOADTO;
    popFIFO(:)  = 0;
    pushFIFO(:) = 0;
       if ~InBetween
        pushFIFO = bitset(pushFIFO,1,1);
         
        for ii = 2:1:KERNELHEIGHT
            %         if ii<= loadTo
            popFIFO  = bitset(popFIFO,ii-1,1);
            pushFIFO = bitset(pushFIFO,ii,1);
            %         end
        end
        if UnloadingPaddingRunCount == 0 && (~InBetween)
            popFIFO = bitset(popFIFO,LOADTO);
        end
    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;
    LineMask(:) = bitset(LineMask,1,0);
    for ii = 2:1:LOADTO
    LineMask(:) = bitset(LineMask,ii,1);
    end
    unloadhStartOut = false;
end



UnloadingOut = Unloading;




% if InterFrameReset && ~Initialize
% resetFIFOREG = true;
% else
% resetFIFOREG = false;
% end


if Initialize == true
if InitialCount<INITCOUNT
resetFIFOREG = false;
pushFIFO(:) = MAXVAL;
popFIFO(:) = 0;
InitialCount(:) = InitialCount +1;
else
resetFIFOREG = true;
pushFIFO(:) = 0;
popFIFO(:) = 0;
end
elseif  InterFrameReset
resetFIFOREG = true;
Unloading = false;
enableDataCacheOut = true;

else
resetFIFOREG = false;
end

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

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


if validIn
FIFOPopREG = bitor(upperPopTemp,upperPopREG);
end

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




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