function [horMUX,verMUX, hStartOut,...
    hEndOut, vStartOut, vEndOut, validOut, processDataOut] = dataWriteFSM(...
    hStartIn, hEndIn, vStartIn, vEndIn, validTempIn, preProcessFlag, postProcessFlag, hStartFlag,   ...
    vStartFlag, hEndFlag, unloadingD, runOrUnload,resetFIFO)
%#codegen

persistent PaddingCount;
persistent PaddingLine;
persistent validREG;
persistent horizontalMUXSEL;
persistent verticalMUXSEL;
persistent Unloading;


if isempty(PaddingCount)
    PaddingCount = int16(0);
    PaddingLine = int16(0);
horizontalMUXSEL = fi(0,0,HSELW,0);
verticalMUXSEL = fi(0,0,VSELW,0);
validREG = false;
Unloading = false;
processDataOut = false;
    hStartOut = false;
    hEndOut = false;
    vStartOut = false;
    vEndOut = false;
    validOut  = false;
preProcessData = false;
postProcessData = false;
runOrUnloadS = false;
end
runOrUnloadS = logical(runOrUnload);
%verticalMUXSEL = fi(0,0,3,0);



if unloadingD && PaddingLine == 0
    PaddingLine(:) = VERPADNUM;
end

if validTempIn 
    PaddingCount = int16(0); % no more padding for now
    horizontalMUXSEL(:) = PASSTHRU;
    if hStartIn
        validREG = true;
    end
    hStartOut(:) = hStartIn;
    hEndOut(:)   = hEndIn;
    vStartOut(:) = vStartIn;
    vEndOut(:)   = vEndIn;
    validOut(:) = validREG;
    processDataOut(:) = true;        % always advance during data phase
    if hEndIn
        validREG(:) = false;
    end
    postProcessData(:) = false; %#ok<NASGU>
else
    preProcessData(:)  = preProcessFlag && runOrUnloadS;
    postProcessData(:) = postProcessFlag && runOrUnloadS;
    

    if preProcessData        
    if PaddingCount == 0
    horizontalMUXSEL(:) = 0;
    PaddingCount(:) = 1;
    else
    horizontalMUXSEL(:) = plus(horizontalMUXSEL,1);
    end
    processDataOut(:) = preProcessData || postProcessData;
    elseif postProcessData
    if Unloading
    processDataOut(:) = (preProcessData || postProcessData)&& (horizontalMUXSEL<MAXPASS);
    else
    if horizontalMUXSEL>=DOWNW
    processDataOut(:) = false;
    else
    processDataOut(:) = preProcessData || postProcessData;
    end  
    end  
    
      horizontalMUXSEL(:) = plus(horizontalMUXSEL,1);  

else
processDataOut(:) = preProcessData || postProcessData;
        horizontalMUXSEL(:) = 0;    
        PaddingCount = int16(0);
    end
      
    
    
    
    
    hStartOut(:) = false;
    hEndOut(:) = false;
    vStartOut(:) = false;
    vEndOut(:) = false;
    validOut(:)  = false;


    %%% Vertical data multiplexing
    end
    if PaddingLine ~= 0        
        if unloadingD
        if hStartFlag
    verticalMUXSEL(:) = verticalMUXSEL + 1;
    PaddingLine(:) = PaddingLine -1;
        end

        else
        if hStartFlag
    verticalMUXSEL(:) = verticalMUXSEL + 1;
    PaddingLine(:) = PaddingLine -1;
        end
        end

    elseif ~Unloading
        %%% Do not reorder
         verticalMUXSEL(:) = VERPADNUM;
    end

    if vStartFlag
        PaddingLine(:) = VERPADNUM;
        verticalMUXSEL(:) =0;
    else
        if PaddingLine == -1
            PaddingLine(:) = 0;
        end
    end

    if resetFIFO
    verticalMUXSEL(:) = 0;
    PaddingLine(:) = VERPADNUM;
    PaddingCount(:) = 0;
    validREG(:) =0;
    horizontalMUXSEL(:) = 0;
    Unloading = false;
    end


% 
%     if vEndIn
%      verticalMUXSEL(:) = 0;
%      end

% if hStartFlag
%     PaddingCount(:) = 1;
% %     if vStartFlag
% %         PaddingLine(:) = 1;
% %     else
% %         PaddingLine(:) =0;
% %         if PaddingLine == -1
% %             PaddingLine(:) = 0;
% %         end
% %     end
% elseif hEndFlag
%     PaddingCount(:) = 1;
% end

if unloadingD
   Unloading = true; 
end



horMUX = horizontalMUXSEL;
verMUX = verticalMUXSEL;

