%% ============================================================================
%% File : commonbodlib.tlc
%%
%% Abstract:
%%      This system TLC library file contains functions that are common
%%      between the different code generators for producing the model's
%%      source file.
%%
%%      The functions provide for caching code for all systems and also dumping
%%      the cached buffers.
%%
%% Note: The only CodeFormat dependencies allowed in this file are for:
%%       1) Creating function prototypes for subsystems
%%       2) Caching body code
%%
%% $Revision: 1.1.8.27 $g
%% Copyright 1994-2004 The MathWorks, Inc.
%%
%% ============================================================================
%selectfile NULL_FILE

%if EXISTS("_COMMONBODLIB_") == 0
%assign _COMMONBODLIB_ = 1

%include "subsystemlib.tlc"

%% Function: SLibGenerate ======================================================
%% Abstract:
%%    Generateds the %<fcnType> code for block if it hasn't been generated by
%%    IR already
%%
%function SLibGenerate(block, fcnType, system) void
  %if block.SkipBlockFcn
    %return ""
  %elseif block.Type != "Opaque" || block.OpaqueBlockMethode.Has%<fcnType>
    %assign buff = ""
    %openfile buff
    %<GENERATE(block, fcnType, system)> \
    %closefile buff
    %return buff
  %endif
%endfunction

%% Function: SLibGenerateForTID ================================================
%% Abstract:
%%    Generateds the %<fcnType> code for block if it hasn't been generated by
%%    IR already
%%
%function SLibGenerateForTID(block, fcnType, system, tid) void
  %if block.SkipBlockFcn
    %return ""
  %else
    %assign buff = ""
    %openfile buff
    %<GENERATE(block, fcnType, system, tid)> \
    %closefile buff
    %return buff
  %endif
%endfunction


%% Function: FcnDeclareTIDIfNeeded =============================================
%% Abstract:
%%      returns 1 if TID was used via LibGetTaskTimeFromTID, then resets
%%      the flag
%%
%function FcnDeclareTIDIfNeeded(sys) void
  %if sys.Type == "root" && RootBodyTIDneeded
    %return 1
  %else
    %if NeedTID
      %assign ::CompiledModel.NeedTID = 0
      %return 1
    %else
      %return 0
    %endif
  %endif
%endfunction


%% Function: FcnDeclareCPIIfNeeded =============================================
%% Abstract:
%%      returns 1 if CPI (Control Port Index) was used in a function-call
%%      subsystem.
%%
%function FcnDeclareCPIIfNeeded(system) void
  %return LibGetSystemField(system, "NeedCPIInOutputUpdate")
%endfunction


%% Function: SLibSystemNonEmpty ================================================
%%
%% Abstract:
%%    Returns true if a system generates some code
%%
%function SLibSystemNonEmpty(system)
  %assign nonEmpty = ( ...
    !LibSystemFcnIsEmpty(system, "Start")        || ...
    !LibSystemFcnIsEmpty(system, "Initialize")   || ...
    !LibSystemFcnIsEmpty(system, "Output")       || ...
    !LibSystemFcnIsEmpty(system, "Update")       || ...
    !LibSystemFcnIsEmpty(system, "Derivative")   || ...
    !LibSystemFcnIsEmpty(system, "Projection")   || ...
    !LibSystemFcnIsEmpty(system, "OutputUpdate") || ...
    !LibSystemFcnIsEmpty(system, "Enable")       || ...
    !LibSystemFcnIsEmpty(system, "Disable"))
  %return (nonEmpty)
%endfunction %% SLibSystemNonEmpty


%% Function: SLibSystemTerminateNonEmpty =======================================
%%
%% Abstract:
%%    Returns true if a system terminate generates some code
%%
%function SLibSystemTerminateNonEmpty(system)
  %assign nonEmpty = !LibSystemFcnIsEmpty(system, "Terminate")
  %return (nonEmpty)
%endfunction %% SLibSystemTerminateNonEmpty


%% Function: FcnGenBodySysCache ================================================
%% Description:
%%   Cache all code for a system (including root).
%%
%function FcnGenBodySysCache(system) void
  %% RTWAssert (!system.SystemCached)

  %assign isRoot = (system.Type == "root")

  %if (ISFIELD(system,"NoCode"))
    %if (system.NoCode == "yes")
      %<SLibExtModeHostOnlyStub(system)>
      %return ""
    %endif
  %endif

  %% EnableFcn, InitializeFcn, and StartFcn fields should always exist in
  %% System record
  %% However, there may not be any blocks in the system that generate initialize
  %% or enable code.  Thus, we must cache those two functions first -- Start
  %% will call them if they are non-empty.

  %% Cache Initialize before Enable so Initialize args get added to Enable
  %if ISFIELD(system,"InitializeFcn")
    %assign ::BlockFcn = "Initialize"
    %<LibSetGlobalSysFcnsForArgAccess([])>
    %if ISFIELD(system, "InitializeOOCC")
      %<LibSetGlobalSysFcnsForArgAccess(system.InitializeOOCC)>
    %endif
    %<FcnGenBodyInitializeFcnCache(system)>

    %assign ::BlockFcn = "Unknown"
    %<LibSetGlobalSysFcnsForArgAccess([])>
  %endif
  %if ISFIELD(system,"EnableFcn")
    %assign ::BlockFcn = "Enable"
    %<LibSetGlobalSysFcnsForArgAccess([])>
    %if ISFIELD(system, "EnableOOCC")
      %<LibSetGlobalSysFcnsForArgAccess(system.EnableOOCC)>
    %endif
    %<FcnGenBodyEnableFcnCache(system)>

    %assign ::BlockFcn = "Unknown"
    %<LibSetGlobalSysFcnsForArgAccess([])>
  %endif
  %% Don't cache start function since it will never be called, Accelerator
  %% runs start function via Simulink.
  %if Accelerator
    %<LibSetSystemField(system, "CachedStartFcn", "")>
  %else
    %assign ::BlockFcn = "Start"
    %<LibSetGlobalSysFcnsForArgAccess([])>
    %if ISFIELD(system, "StartOOCC")
      %<LibSetGlobalSysFcnsForArgAccess(system.StartOOCC)>
    %endif
    %<FcnGenBodyStartFcnCache(system)>

    %assign ::BlockFcn = "Unknown"
    %<LibSetGlobalSysFcnsForArgAccess([])>
  %endif
  %%
  %if ISFIELD(system,"DerivativeFcn") && (!isRoot || (NumContStates > 0))
    %assign ::BlockFcn = "Derivative"
    %<LibSetGlobalSysFcnsForArgAccess([])>
    %if ISFIELD(system, "DerivativeOOCC")
      %<LibSetGlobalSysFcnsForArgAccess(system.DerivativeOOCC)>
    %endif
    %<FcnGenBodyDerivativeFcnCache(system)>

    %assign ::BlockFcn = "Unknown"
    %<LibSetGlobalSysFcnsForArgAccess([])>
  %endif
  %if ISFIELD(system,"ProjectionFcn") && (!isRoot || (NumContStates > 0))
    %assign ::BlockFcn = "Projection"
    %<LibSetGlobalSysFcnsForArgAccess([])>
    %if ISFIELD(system, "ProjectionOOCC")
      %<LibSetGlobalSysFcnsForArgAccess(system.ProjectionOOCC)>
    %endif
    %<FcnGenBodyProjectionFcnCache(system)>

    %assign ::BlockFcn = "Unknown"
    %<LibSetGlobalSysFcnsForArgAccess([])>
  %endif
  %if ISFIELD(system,"ZeroCrossingFcn") && (!isRoot || (NumNonsampledZCs > 0))
    %assign ::BlockFcn = "ZeroCrossing"
    %<LibSetGlobalSysFcnsForArgAccess([])>
    %if ISFIELD(system, "ZeroCrossingOOCC")
      %<LibSetGlobalSysFcnsForArgAccess(system.ZeroCrossingOOCC)>
    %endif
    %<FcnGenBodyZeroCrossingFcnCache(system)>

    %assign ::BlockFcn = "Unknown"
    %<LibSetGlobalSysFcnsForArgAccess([])>
  %endif
  %% DisableFcn always exists
  %if ISFIELD(system,"DisableFcn")
    %assign ::BlockFcn = "Disable"
    %<LibSetGlobalSysFcnsForArgAccess([])>
    %if ISFIELD(system, "DisableOOCC")
      %<LibSetGlobalSysFcnsForArgAccess(system.DisableOOCC)>
    %endif
    %<FcnGenBodyDisableFcnCache(system)>

    %assign ::BlockFcn = "Unknown"
    %<LibSetGlobalSysFcnsForArgAccess([])>
  %endif
  %assign updateNonEmpty = TLC_FALSE
  %if ISFIELD(system,"UpdateFcn")
    %if isRoot
      %assign ::BlockFcn = "RootUpdate"
    %else
      %assign ::BlockFcn = "Update"
      %<LibSetGlobalSysFcnsForArgAccess([])>
      %if ISFIELD(system, "UpdateOOCC")
        %<LibSetGlobalSysFcnsForArgAccess(system.UpdateOOCC)>
      %endif
    %endif
    %assign updateNonEmpty = %<FcnGenBodyUpdateFcnCache(system)>

    %assign ::BlockFcn = "Unknown"
    %<LibSetGlobalSysFcnsForArgAccess([])>
  %endif
  %% Cache Outputs function after update fcn because the
  %% the Output method checks if output or update is empty
  %% before generating special code for conditionally
  %% executed systems (such as setting the mode in an enabled
  %% subsystem).  It is possible with CGIR for the Output buffer
  %% of an enabled subsystem to be empty, but the Update buffer
  %% to be nonempty.
  %if ISFIELD(system,"OutputFcn") && !system.DeletedInIR
    %assign ::BlockFcn = "Output"
    %<LibSetGlobalSysFcnsForArgAccess([])>
    %if ISFIELD(system, "OutputOOCC")
      %<LibSetGlobalSysFcnsForArgAccess(system.OutputOOCC)>
    %endif
    %<FcnGenBodyOutputFcnCache(system, updateNonEmpty)>

    %assign ::BlockFcn = "Unknown"
    %<LibSetGlobalSysFcnsForArgAccess([])>
  %endif
  %if ISFIELD(system,"OutputUpdateFcn") && !system.DeletedInIR
    %assign ::BlockFcn = "OutputUpdate"
    %<LibSetGlobalSysFcnsForArgAccess([])>
    %if ISFIELD(system, "OutputOOCC")
      %if ISFIELD(system, "UpdateOOCC")
        %assign outputUpdateOOCC = system.OutputOOCC
        %foreach idx = SIZE(system.UpdateOOCC,1)
          %assign outputUpdateOOCC = outputUpdateOOCC + system.UpdateOOCC[idx]
        %endforeach
        %<LibSetGlobalSysFcnsForArgAccess(outputUpdateOOCC)>
      %else
      %<LibSetGlobalSysFcnsForArgAccess(system.OutputOOCC)>
    %endif
    %elseif ISFIELD(system, "UpdateOOCC")
      %<LibSetGlobalSysFcnsForArgAccess(system.UpdateOOCC)>
    %endif
    %<FcnGenBodyOutputUpdateFcnCache(system)>

    %assign ::BlockFcn = "Unknown"
    %<LibSetGlobalSysFcnsForArgAccess([])>
  %endif
  %%
  %% For ert model reference the registration function will be in the top level
  %% subsystem file. If all blocks have constant sample time, only registration
  %% function will be generated. The registration function will be dumped in
  %% in ertreg.tlc.
  %assign isMdlRefSys  = IsModelReferenceBaseSys(system)
  %assign nonEmpty = isRoot || isMdlRefSys || SLibSystemNonEmpty(system)
  %<LibSetSystemField(system, "SystemNonEmpty", nonEmpty)>
  %<LibSetSystemField(system, "SystemCached",   TLC_TRUE)>

  %% For the model reference base system, we generate the interface
  %% and prototype in FcnGenBodySysCache.  This is because information
  %% from Output may be needed in Update to determine if an 
  %% rtModel argument is needed (one reason is the firstInitCond).
  %% 
  %% NOTE(mdt): We do not need to this here for OutputUpdate because
  %% we call ModelrefMarkRTMIfNeeded at the end of 
  %% FcnGenBodyOutputUpdateFcnCache after both Output and Update 
  %% have already been generated.  This avoids the problem that
  %% happens when Output and Update are called separately.
  %if isMdlRefSys
    %if ISFIELD(system,"UpdateFcn")
      %assign ::BlockFcn = "Update"
      %<LibSetGlobalSysFcnsForArgAccess([])>
      %if ISFIELD(system, "UpdateOOCC")
        %<LibSetGlobalSysFcnsForArgAccess(system.UpdateOOCC)>
      %endif
      %if !ModelReferenceTargetWithGlobalTiming
        %<ModelrefMarkRTMIfNeeded(system, "Update")>
      %endif
      %<LibDefineSystemFcn(system, "Update")>
      %assign ::BlockFcn = "Unknown"
    %endif
    
    %if ISFIELD(system,"OutputFcn") && !system.DeletedInIR
      %assign ::BlockFcn = "Output"
      %<LibSetGlobalSysFcnsForArgAccess([])>
      %if ISFIELD(system, "OutputOOCC")
        %<LibSetGlobalSysFcnsForArgAccess(system.OutputOOCC)>
      %endif
      %if !ModelReferenceTargetWithGlobalTiming
        %<ModelrefMarkRTMIfNeeded(system, "Output")>
      %endif
      %<LibDefineSystemFcn(system, "Output")>
      %assign ::BlockFcn = "Unknown"
    %endif
  %endif
%endfunction %% FcnGenBodySysCache


%% Function: FcnGenSystemTerminate =============================================
%% Description:
%%   Cache all terminate code for a subsystem.  Ultimately, this function
%%   should also be able to cache code for the root system.
%%
%function FcnGenSystemTerminate(system) void
  %% RTWAssert (!system.SystemTerminateCached)

  %if (ISFIELD(system,"NoCode"))
    %if (system.NoCode == "yes")
      %<SLibExtModeHostOnlyStub(system)>
      %return ""
    %endif
  %endif

  %<FcnGenBodyTerminateFcnCache(system)>

  %assign terminateNonEmpty = SLibSystemTerminateNonEmpty(system)
  %<LibSetSystemField(system, "SystemTerminateNonEmpty", terminateNonEmpty)>
  %<LibSetSystemField(system, "SystemTerminateCached", TLC_TRUE)>

%endfunction %% FcnGenSystemTerminate


%% Function: FcnGenerateEnable(system) =========================================
%% Description:
%%      Generate enable code for a system
%%
%function FcnGenerateEnable(system) void
  %openfile tmpBuffer
  %with system
    %%  For action systems we need to write out the Enable code
    %%  for a system at the top of the EnableFcn for this system.
    %%  This is similar to how enabled subsytems work in subsystemlib.tlc
    %if system.Type == "action" && SolverType == "VariableStep"
      %assign graphicalSys = CompiledModel.System[CallSites[0][2]]
      %assign ssBlock = graphicalSys.Block[CallSites[0][3]] 
      %<SLibSetStatesDisabled(ssBlock,system,"FALSE")>
    %endif
    %foreach blkIdx = NumBlocks
      %% Enabled systems automatically do not generate.  See subsystm.tlc.

      %<SLibGenerate(Block[blkIdx], "Enable", system)>

    %endforeach
  %endwith
  %closefile tmpBuffer
  %if !WHITE_SPACE(tmpBuffer)
    %return tmpBuffer
  %else
    %return ""
  %endif
%endfunction


%% Function: FcnGenBodyEnableFcnCache(system) ==================================
%% Description:
%%      Functions that generates the enable code for the specified
%%      subsystem and caches it into the system's record.
%%
%function FcnGenBodyEnableFcnCache(system) void
  %assign enableFcn    = FcnGenerateEnable(system)
  %assign enableSSVars = LibDeclareAllAccessedSimStructVars()
  %<LibSetSystemField(system, "CachedEnableFcn",    enableFcn)>
  %<LibSetSystemField(system, "CachedEnableSSVars", enableSSVars)>

  %<LibDefineSystemFcn(system, "Enable")>
%endfunction


%% Function: FcnGenerateInitialize =============================================
%% Description:
%%      Generate init. code for all blocks with InitializeConditions functions
%%
%function FcnGenerateInitialize(system) void
  %openfile tmpBuffer
  %with system
    %if system.Type == "root"
      %% Initialized flags that are used when asynchronous task 
      %% read absolute time from base rate
       %foreach idx = NumAsynchronousSampleTimes
	 %assign tid = idx + NumSynchronousSampleTimes
	 %if RTMAbsTimeNeedNoPriorityTrans(tid) 
	   %<SLibGetDbBufReadBuf(tid)>   = 0xFF;
	   %<SLibGetDbBufWriteBuf(tid)>  = 0xFF;
	   %<SLibGetDbBufLastBufWr(tid)> = 0;
	 %endif
       %endforeach
    %else
      %assign graphicalSys = CompiledModel.System[CallSites[0][2]]
      %assign ssBlock = graphicalSys.Block[CallSites[0][3]]

      %% If system need elapse time and can be reset,
      %% elapse time must be reset when the system reset
      %% states.
      %% MJE xxx 
      %if SLibXBInitRequired(system,ssBlock,[],"","",0)
	%with ssBlock
	  %if system.Type == "trigger" || ...
	    system.Type == "enable_with_trigger" || ...
	    system.Type == "enable" || ...
	    system.Type == "function-call" || ...
	    system.Type == "iterator"
	    %<FcnResetSystemElapseTime(system)>
	    %if (system.Type == "function-call" || ...
	      system.Type == "trigger") && ...
	      SysNeedsElapseTime(system)
	      {
	      %<FcnCalculatePrevTime(system, ssBlock)>
	      }
	    %endif
	  %endif
	%endwith
      %endif
    %endif

    %foreach blkIdx = NumBlocks
      %% Enabled systems automatically do not generate.  See subsystm.tlc.

      %<SLibGenerate(Block[blkIdx], "InitializeConditions", system)>

    %endforeach
  %endwith
  %% Stateflow global machine initialize
  %if IsBaseSystem(system)
    %<SLibWriteMachineInitialize()>\
  %endif
  %closefile tmpBuffer
  %if !WHITE_SPACE(tmpBuffer)
    %return tmpBuffer
  %else
    %return ""
  %endif
%endfunction %% FcnGenerateInitialize


%% Function: FcnGenBodyInitializeFcnCache(system) ==============================
%% Description:
%%      Functions that generates the InitializeConditions code for the specified
%%      subsystem and caches it into the system's record.
%%
%function FcnGenBodyInitializeFcnCache(system) void
  %assign initFcn          = FcnGenerateInitialize(system)
  %<LibSetSystemField(system, "CachedInitializeFcn",    initFcn)>
  %%
  %% generate code for open and close systems code for
  %% trigger_enabled, triggered and iterator systems
  %% xxx mje do I really need this and aren't we caching initfcn
  %% both above and below?
  %<SLibGenerateSubSystemCode(system, "Initialize")>

  %assign initializeSSVars = LibDeclareAllAccessedSimStructVars()
  %<LibSetSystemField(system, "CachedInitializeFcn",    initFcn)>
  %<LibSetSystemField(system, "CachedInitializeSSVars", initializeSSVars)>

  %<LibDefineSystemFcn(system, "Initialize")>
%endfunction %% FcnGenBodyInitializeFcnCache


%% Function: FcnGenerateConstantTID ============================================
%% Description:
%%      Constant TID blocks (subsystem block is *NOT* recursive)
%%
%function FcnGenerateConstantTID(system) void
  %assign ::CompiledModel.GeneratingOutputsCode = 1
  %openfile buffer
  %assign hashIfIsOpen = 0
  %with system
    %foreach blkIdx = NumBlocks
      %assign block = Block[blkIdx]
      %with block
	%%
        %if block.SkipBlockFcn || !ISEQUAL(block.TID, "constant") || ...
          LibBlockAllOutputSignalsAreExpr()
          %continue
        %endif
	%%
        %<FcnWriteReducedBlocksComment(block)>\
	%if NumDataOutputPorts == 0 || EXISTS("NeedOutputsFcnInMdlStart") || ...
          block.Type == "Opaque"
          %%
          %% opaque blocks don't have an output function if its TID is constant
          %% unless it is needed in the start function
          %%
	  %if hashIfIsOpen
	    #endif

	    %assign hashIfIsOpen = 0
	  %endif
	%elseif ShowEliminatedStatements
	  %if !hashIfIsOpen
	    #if 0 /* Turn ShowEliminatedStatements off to remove this code */
	    %assign hashIfIsOpen = 1
	  %endif
	%else
	  %continue
	%endif
	%assign ::CompiledModel.GeneratingDeadCode = hashIfIsOpen

	%if hashIfIsOpen
	  %assign tmpBlkFcn = ::BlockFcn
	  %assign ::BlockFcn = "DeadCode"
	  %copyrecord TempBlockFcnAccessed ::BlockFcnAccessed
	  %<SLibGenerateNonExprOutput(block,system)>\
	  %undef ::BlockFcnAccessed
	  %copyrecord ::BlockFcnAccessed TempBlockFcnAccessed
	  %assign ::BlockFcn = tmpBlkFcn
	%else
	  %<SLibGenerateNonExprOutput(block,system)>\
	%endif

      %endwith %% block
    %endforeach %% blkIdx
  %endwith  %% system
  %if hashIfIsOpen
    #endif

  %endif
  %closefile buffer
  %assign ::CompiledModel.GeneratingOutputsCode = 0
  %assign ::CompiledModel.GeneratingDeadCode = 0
  %%
  %if !WHITE_SPACE(buffer)
    %return "\n\n/* blocks with infinite sample periods */ \n\n" + buffer
  %else
    %return ""
  %endif
%endfunction %% FcnGenerateConstantTID


%% Function: FcnGenerateVirtualOutports() ======================================
%% Description:
%% Generate virtual outport code for all blocks with Virtual
%% InitializeConditions functions
%%
%function FcnGenerateVirtualOutports(system) void
  %openfile tmpBuffer
  %with system
    %if (system.Type != "root")
      %foreach blkIdx = NumVirtualOutportBlocks
	  %assign vblkIdx = VirtualOutportBlocksIdx + blkIdx

	  %<GENERATE(Block[vblkIdx], "VirtualInitializeConditions", system)>

      %endforeach
    %else
      %if (CodeFormat == "S-Function" && CompiledModel.HaveVirtualOutports)
        %% Run root outports so any ICs that are connected to root outports
        %% propagate to the output.  This is to ensure the IC is put at the
        %% output of the RTW s-function, since mdlOutputs doesn't run at
        %% time 0 if the s-function is in a disabled enable_subsystm.
        %foreach blkIdx = NumBlocks
          %if Block[blkIdx].Type == "Outport"

	    %<GENERATE(Block[blkIdx], "OutputsForRTWSFunction", system)>

          %endif
        %endforeach
      %endif
    %endif
  %endwith
  %closefile tmpBuffer
  %if !WHITE_SPACE(tmpBuffer)
    %openfile retBuffer
    /* virtual outports code */

    %<tmpBuffer>\
    %closefile retBuffer
    %if (system.Type != "root")
      %assign ::CompiledModel.HaveVirtualOutports = 1
    %endif
    %return retBuffer
  %else
    %return ""
  %endif
%endfunction %%FcnGenerateVirtualOutports

%% Function: FncGenInitStatesInRootStart ======================================
%% Abstract:
%%   This function generate code initialize states
%% if needed
%%
%function FncGenInitStatesInRootStart()
  %assign ss = System[NumSystems - 1] %% root system
  %openfile retBuf
  %% Load intial states if needed.
  %if CompiledModel.LoadInitialState == "yes"

    /* initial state override */
    %assign origBlockFcn = ::BlockFcn
    %assign ::BlockFcn = "Start"
    %<FcnLoadInitialState()>\
    %assign ::BlockFcn = origBlockFcn
  %endif
  %closefile retBuf

  %return retBuf
%endfunction %% FncGenInitStatesInRootStart


%% Function: FcnGenerateStart(system) ==========================================
%% Description:
%%      Generate start code for a system
%%
%function FcnGenerateStart(system) void
  %openfile tmpBuffer
  %with system
    %foreach blkIdx = NumBlocks
      %if (Block[blkIdx].Type == "SubSystem")
        %openfile tmpStartBuffer

	%<SLibGenerate(Block[blkIdx], "Start", system)>

        %closefile tmpStartBuffer
        %selectfile tmpBuffer
        %if !WHITE_SPACE(tmpStartBuffer)
          %<tmpStartBuffer>
        %endif
      %else

	%<SLibGenerate(Block[blkIdx], "Start", system)>

      %endif

    %endforeach
    %<FcnGenerateConstantTID(system)>\
    %%
    %% Enabled systems are responsible for calling their own enable and
    %% initialize functions in their start function.
    %% Initialize code for other systems is called during the parent system's
    %% initialize function.  Note that we can't do this for enabled subsystems,
    %% since in general (that is, for all other times except for start-up), we
    %% do not want to call an enabled systems initialize code when the parent
    %% system runs its enable code.
    %% An enabled systems initialize code should ONLY be called either at
    %% start-up or when the system itself enables.
    %%
    %% Action systems and iterator systems also can reset their states
    %% like an enabled system, so treat them like enabled systems.
    %if ((system.Type == "enable") || ...
         (system.Type == "enable_with_trigger") || ...
         (system.Type == "action") || ...
         (system.Type == "iterator"))
      %if (!LibSystemFcnIsEmpty(system, "Initialize"))
        %<LibGenSystemFcnCall(system, "Initialize", 0)>
      %endif
    %endif
    %<FcnGenerateVirtualOutports(system)>\
    %<FcnGenSysRanInitCode(system)>
  %endwith
  %closefile tmpBuffer
  %if !WHITE_SPACE(tmpBuffer)
    %return tmpBuffer
  %else
    %return ""
  %endif
%endfunction %% FcnGenerateStart


%% Function: FcnGenBodyStartFcnCache(system) ===================================
%% Description:
%%      Cache start code for a system
%%
%function FcnGenBodyStartFcnCache(system) void
  %assign startFcn    = FcnGenerateStart(system)
  %<LibSetSystemField(system, "CachedStartFcn",    startFcn)>
  %%
  %% generate code for open and close systems code for
  %% trigger_enabled, triggered and iterator systems
  %%
  %<SLibGenerateSubSystemCode(system, "Start")>

  %assign startSSVars = LibDeclareAllAccessedSimStructVars()
  %<LibSetSystemField(system, "CachedStartSSVars", startSSVars)>

  %<LibDefineSystemFcn(system, "Start")>
%endfunction


%% Function: FcnGenBodyOutputFcnCache(system, updateNonEmpty) ==================
%% Description:
%%      Functions that generates the output code for the specified
%%      system and caches it into the system's record.
%%
%%      Note: root system also calls this function
%%
%function FcnGenBodyOutputFcnCache(system, updateNonEmpty) void
  %assign outputFcn     = FcnGenerateOutput(system)
  %<LibSetSystemFieldForTID(system, "Output","Fcn",  outputFcn)>
  %%
  %% generate code for open and close systems code for
  %% enabled systems.  We need to check if either the output or
  %% update code is nonempty, because it is possible for the
  %% output code to be optimized away, but an update function
  %% is still generated.  In this case we need to generate the
  %% code to switch modes for an enabled subsystem.  For example,
  %%
  %%      _____
  %%     |     |
  %%     |     |-----------
  %%     |_____|           |
  %%                       |
  %%                       |
  %%                       |
  %%               ________v_______________
  %%               |         _             |
  %%               |       _| |_           |
  %%               |        _____          |      ____
  %%               |  _    |  1  |     _   |     | _  |
  %%               | |_|-->|  -  |--->|_|  |---->|--| |
  %%               |       |_z-1_|         |     |_- _|
  %%               |_______________________|   Terminator block
  %%
  %%
  %%
  %%
  %%
  %if !LibSystemFcnIsEmpty(system,"Output") || updateNonEmpty
    %<SLibGenerateSubSystemCode(system, "Output")>
  %endif

  %assign outputLocalBO = FcnDeclareAccessedLocalBlockOutputs(system)
  %assign outputSSVars  = LibDeclareAllAccessedSimStructVars()
  %<LibSetSystemFieldForTID(system, "Output","LocalBO", outputLocalBO)>
  %<LibSetSystemField(system, "CachedOutputSSVars",  outputSSVars)>
  %%
  %% generate profiling code
  %%
  %assign declsProf = SLibGenProfSysDeclare(system, "Output")
  %<LibSetSystemField(system, "CachedOutputProfileDeclsCode", declsProf)>
  %assign startProf = SLibGenProfSysStart(system, "Output")
  %<LibSetSystemField(system, "CachedOutputProfileStartCode", startProf)>
  %assign endProf   = SLibGenProfSysEnd(system, "Output")
  %<LibSetSystemField(system, "CachedOutputProfileEndCode",   endProf)>

  %<LibSetSystemField(system, "NeedTIDInOutput", FcnDeclareTIDIfNeeded(system))>
  
  %% For the model reference base system, we generate the interface
  %% and prototype in FcnGenBodySysCache.  This is because information
  %% from Output may be needed in Update to determine if an 
  %% rtModel argument is needed (one reason is the firstInitCond).
  %if !IsModelReferenceBaseSys(system)
    %<LibDefineSystemFcn(system, "Output")>
  %endif
%endfunction %% FcnGenBodyOutputFcnCache

%% Function: FcnGenBodyUpdateFcnCache(system) ==================================
%% Description:
%%      Functions that generates the update code for the specified
%%      system and caches it into the system's record.  This function will
%%      return true if the update cache is nonempty, and false otherwise.
%%      This is used by the Output function to decide if we should call
%%      SLibGenerateSubSystemCode.  It will be called if there is any output
%%      or update code.
%%
%%      Note: root system also calls this function
%%
%function FcnGenBodyUpdateFcnCache(system) void
  %assign buffNonEmpty = TLC_FALSE

  %assign updateFcn = FcnGenerateUpdate(system)

  %<LibSetSystemFieldForTID(system, "Update","Fcn",  updateFcn)>

  %%
  %% generate code for open and close systems code for
  %% enabled systems
  %%
  %if !LibSystemFcnIsEmpty(system,"Update")
    %assign buffNonEmpty = TLC_TRUE
    %<SLibGenerateSubSystemCode(system, "Update")>
  %endif

  %assign updateSSVars = LibDeclareAllAccessedSimStructVars()
  %<LibSetSystemField(system, "CachedUpdateSSVars", updateSSVars)>
  %%
  %% generate profiling code
  %%
  %assign declsProf = SLibGenProfSysDeclare(system, "Update")
  %<LibSetSystemField(system, "CachedUpdateProfileDeclsCode", declsProf)>
  %assign startProf = SLibGenProfSysStart(system, "Update")
  %<LibSetSystemField(system, "CachedUpdateProfileStartCode", startProf)>
  %assign endProf   = SLibGenProfSysEnd(system, "Update")
  %<LibSetSystemField(system, "CachedUpdateProfileEndCode",   endProf)>

  %<LibSetSystemField(system, "NeedTIDInUpdate", FcnDeclareTIDIfNeeded(system))>

  %% For the model reference base system, we generate the interface
  %% and prototype in FcnGenBodySysCache.  This is because information
  %% from Output may be needed in Update to determine if an 
  %% rtModel argument is needed (one reason is the firstInitCond).
  %if !IsModelReferenceBaseSys(system)
    %<LibDefineSystemFcn(system, "Update")>
  %endif
  
  %return buffNonEmpty
%endfunction %% FcnGenBodyUpdateFcnCache


%% Function: FcnGenBodyOutputUpdateFcnCache(system) ============================
%% Description:
%%      Functions that generates the outputupdate code for the specified
%%      subsystem and caches it into the system's record.
%%
%function FcnGenBodyOutputUpdateFcnCache(system) void
  %% output
  %assign outputFcn = FcnGenerateOutput(system)
  %<LibSetSystemFieldForTID(system, "Output","Fcn",  outputFcn)>

  %% update
  %assign updateFcn = FcnGenerateUpdate(system)

  %<LibSetSystemFieldForTID(system, "Update","Fcn", updateFcn)>

  %if system.Type == "iterator"
    %% accessed block outputs
    %assign localBO = FcnDeclareAccessedLocalBlockOutputs(system)
    %<LibSetSystemFieldForTID(system, "OutputUpdate","LocalBO", localBO)>
  %endif

  %%
  %% generate code for open and close systems code for
  %% trigger_enabled, triggered and iterator systems
  %%
  %% For trigger subsystem, if trigger block output port
  %% presents, must generate system code.
  %if !LibSystemFcnIsEmpty(system,"Output") || ...
    !LibSystemFcnIsEmpty(system,"Update") || ...
    system.Type == "iterator" || ...
    (system.Type == "trigger" && system.TriggerBlkIdx != -1)
    %<SLibGenerateSubSystemCode(system, "OutputUpdate")>
  %endif

  %if system.Type != "iterator"
    %% accessed block outputs
    %assign localBO = FcnDeclareAccessedLocalBlockOutputs(system)
    %<LibSetSystemFieldForTID(system, "OutputUpdate","LocalBO", localBO)>
  %endif

  %% accessed simstruct variables and global variables
  %assign outputUpdateSSVars = LibDeclareAllAccessedSimStructVars()
  %<LibSetSystemField(system, "CachedOutputUpdateSSVars", outputUpdateSSVars)>

  %%
  %% generate profiling code
  %%
  %assign declsProf = SLibGenProfSysDeclare(system, "OutputUpdate")
  %<LibSetSystemField(system, "CachedOutputUpdateProfileDeclsCode", declsProf)>
  %assign startProf = SLibGenProfSysStart(system, "OutputUpdate")
  %<LibSetSystemField(system, "CachedOutputUpdateProfileStartCode", startProf)>
  %assign endProf   = SLibGenProfSysEnd(system, "OutputUpdate")
  %<LibSetSystemField(system, "CachedOutputUpdateProfileEndCode",   endProf)>

  %% Set Need TID flag
  %% Set Need CPI flag
  %%
  %% Force flag is set for function-call subsystems because:
  %%   1) at least 1 caller is a non-inlined S-Function (determined in
  %%      Simulink)
  %%   2) the function-call subsystem has inside it an S-Function that makes
  %%      function-calls and it is part of a feedback loop (determined in
  %%      Simulink)
  %%   3) vxtask.tlc and vxinterrupt.tlc require the function-call subsystem to
  %%      be a function
  %%   4) A multi-instanced, non-inlined StateFlow block is the caller
  %%      (set in LibDetermineSFMultiInstantiation() in commonpass.tlc)
  %%
  %% NOTE: This assumes inlined S-Functions will use OutputUpdateFcnInfo.FcnCall
  %%       or LibSystemFcnNeedsTid to correctly perform the call.
  %%
  %assign needTIDInOutputUpdate = ...
    FcnDeclareTIDIfNeeded(system) || LibSystemIsForceNonInline(system)
  %<LibSetSystemField(system, "NeedTIDInOutputUpdate", needTIDInOutputUpdate)>

  %assign needCPIInOutputUpdate = ...
    FcnDeclareCPIIfNeeded(system) || LibSystemIsForceNonInline(system)
  %<LibSetSystemField(system, "NeedCPIInOutputUpdate", needCPIInOutputUpdate)>

  %% For the model reference base system, we generate the interface
  %% and prototype after output and update have been generated. 
  %% This is because information from Output may be needed in 
  %% Update to determine if an rtModel argument is needed 
  %% (one reason is the firstInitCond).
  %% Global timing engine does not need any of these.
  %if IsModelReferenceBaseSys(system) && !ModelReferenceTargetWithGlobalTiming
    %<ModelrefMarkRTMIfNeeded(system, "OutputUpdate")>
  %endif
  
  %<LibDefineSystemFcn(system, "OutputUpdate")>
%endfunction %% FcnGenBodyOutputUpdateFcnCache


%% Function: FcnGenBodyDisableFcnCache(system) =================================
%% Description:
%%      Functions that generates the disable code for the specified
%%      subsystem and caches it into the system's record.
%%
%function FcnGenBodyDisableFcnCache(system) void
  %openfile tempbuf
  %with system
%%    %if system.Type != "root"
%%      %assign graphicalSys = CompiledModel.System[CallSites[0][2]]
%%      %assign ssBlock = graphicalSys.Block[CallSites[0][3]]
%%
%%      %% If system need elapse time and can be reset,
%%      %% elapse time must be reset when the system reset
%%      %% states.
%% MJE xxx
%%      %if SLibXBInitRequired(system,ssBlock,[],"","",0)
%%	%with ssBlock
%%	  %if system.Type == "trigger" || ...
%%	    system.Type == "enable_with_trigger" || ...
%%	    system.Type == "enable" || ...
%%	    system.Type == "function-call"
%%	    %<FcnResetSystemElapseTime(system)>
%%	  %endif
%%	%endwith
%%      %endif
%%    %endif
%%
%%
%%  For action systems we need to write out the Disable code
%%  for a system at the top of the DisableFcn for this system.
%%  This is similar to how enabled subsytems work in subsystemlib.tlc
    %if system.Type == "action" && SolverType == "VariableStep"
      %assign graphicalSys = CompiledModel.System[CallSites[0][2]]
      %assign ssBlock = graphicalSys.Block[CallSites[0][3]] 
      %<RTMSetSolverNeedsReset()>;
      %<SLibSetStatesDisabled(ssBlock,system,"TRUE")>
    %endif
    %foreach blkIdx = NumBlocks

      %<SLibGenerate(Block[blkIdx], "Disable", system)>
      
    %endforeach
    %foreach blkIdx = NumVirtualOutportBlocks
      %assign vblkIdx = VirtualOutportBlocksIdx + blkIdx

      %<GENERATE(Block[vblkIdx], "VirtualDisable", system)>

    %endforeach
  %endwith %% system
  %closefile tempbuf
  %<LibSetSystemField(system, "CachedDisableFcn",    tempbuf)>

  %<SLibGenerateSubSystemCode(system, "Disable")>

  %assign disableSSVars = LibDeclareAllAccessedSimStructVars()
  %<LibSetSystemField(system, "CachedDisableSSVars", disableSSVars)>

  %<LibDefineSystemFcn(system, "Disable")>
%endfunction


%% Function: FcnGenBodyDerivativeFcnCache(system) ==============================
%% Description:
%%      Functions that generates the derivative code for the specified
%%      subsystem and caches it into the system's record.
%%
%%      Note: root system also calls this function
%%
%function FcnGenBodyDerivativeFcnCache(system) void
  %openfile tempbuf
  %with system
    %foreach blkIdx = NumBlocks

      %<SLibGenerate(Block[blkIdx], "Derivatives", system)>

    %endforeach
  %endwith %% system
  %closefile tempbuf
  %<LibSetSystemField(system, "CachedDerivativeFcn",    tempbuf)>

  %<SLibGenerateSubSystemCode(system, "Derivative")>

  %assign derivativeSSVars = LibDeclareAllAccessedSimStructVars()
  %<LibSetSystemField(system, "CachedDerivativeSSVars", derivativeSSVars)>

  %assign ::BlockFcn = "Derivative"
  %<LibDefineSystemFcn(system, "Derivative")>
%endfunction


%% Function: FcnGenBodyProjectionFcnCache(system) ==============================
%% Description:
%%      Functions that generates the projection code for the specified
%%      subsystem and caches it into the system's record.
%%
%%      Note: root system also calls this function
%%
%function FcnGenBodyProjectionFcnCache(system) void
  %openfile tempbuf
  %%
  %% If Model registered Projection function, the ODE solvers must call
  %% MdlOutputs before calling MdlProjection. MdlProjection is generated/called
  %% always, but MdlOutputs should only be called if needed.
  %%
  %if ((system.Type == "root") && (ModelHasProjections == "yes"))
    %if isRSim && !isRSimWithSolverModule %% RSim with the RTW ODE solver
      /* Update Outputs before calling Projections */
      MdlOutputs(0);
    %elseif CodeFormat == "RealTimeMalloc"            %% GRT with malloc
      /* Update Outputs before calling Projections */
      MdlOutputs(%<tSimStruct>,0);
    %endif
  %endif
  %%
  %with system
    %foreach blkIdx = NumBlocks

      %<SLibGenerate(Block[blkIdx], "Projection", system)>

    %endforeach
  %endwith %% system
  %closefile tempbuf
  %<LibSetSystemField(system, "CachedProjectionFcn",    tempbuf)>

  %<SLibGenerateSubSystemCode(system, "Projection")>

  %assign projectionSSVars = LibDeclareAllAccessedSimStructVars()
  %<LibSetSystemField(system, "CachedProjectionSSVars", projectionSSVars)>

  %<LibDefineSystemFcn(system, "Projection")>
%endfunction


%% Function: FcnGenBodyZeroCrossingFcnCache(system) ============================
%% Description:
%%      Generates the zero-crossing code for the specified system and caches it
%%      into the system's record.
%%
%%      Note: Root system also calls this function
%%
%function FcnGenBodyZeroCrossingFcnCache(system) void
  %openfile tempbuf
  %with system
    %foreach blkIdx = NumBlocks
      %if (Block[blkIdx].NumNonsampledZCs > 0) || ...
        Block[blkIdx].Type == "Opaque" || ...
	Block[blkIdx].Type == "SubSystem" || ...
        Block[blkIdx].Type == "If" || ...
        Block[blkIdx].Type == "SwitchCase"

	%<SLibGenerate(Block[blkIdx], "ZeroCrossings", system)>

      %endif
    %endforeach
  %endwith %% system
  %closefile tempbuf
  %<LibSetSystemField(system, "CachedZeroCrossingFcn",    tempbuf)>

  %<SLibGenerateSubSystemCode(system, "ZeroCrossing")>

  %assign zeroCrossingSSVars = LibDeclareAllAccessedSimStructVars()
  %<LibSetSystemField(system, "CachedZeroCrossingSSVars", zeroCrossingSSVars)>

  %<LibDefineSystemFcn(system, "ZeroCrossing")>
%endfunction



%% Function: FcnGenerateTerminate ==============================================
%% Description:
%%      Generate terminate code for the system
%%
%function FcnGenerateTerminate(system)
  %openfile tmpBuffer
  %with system
    %foreach blkIdx = system.NumBlocks

      %<SLibGenerate(system.Block[blkIdx], "Terminate", system)>

    %endforeach
  %endwith
  %% Stateflow global machine terminate
  %if IsBaseSystem(system)
    %<SLibWriteMachineTerminate()>\
  %endif

  %closefile tmpBuffer
  %if !WHITE_SPACE(tmpBuffer)
    %return tmpBuffer
  %else
    %return ""
  %endif
%endfunction  %% FcnGenerateTerminate


%% Function: FcnGenBodyTerminateFcnCache(system) ===============================
%% Description:
%%      Caches system Terminate function
%%
%function FcnGenBodyTerminateFcnCache(system) void
  %assign terminateFcn    = FcnGenerateTerminate(system)
  %assign terminateSSVars = LibDeclareAllAccessedSimStructVars()
  %if system.Type == "root"
    %assign terminateProf = SLibGenProfSysTerminate(system)
    %<LibSetSystemField(system, "CachedTerminateProfileEndCode", terminateProf)>
  %endif
  %<LibSetSystemField(system, "CachedTerminateFcn",    terminateFcn)>
  %<LibSetSystemField(system, "CachedTerminateSSVars", terminateSSVars)>

  %<LibDefineSystemFcn(system, "Terminate")>
%endfunction %% FcnGenBodyTerminateFcnCache


%% Function: FcnGenerateExtModeOutput(system) ===================================
%% Description:
%%      Generates the External Mode Outputs code for an enabled, triggered, or
%%      enabled & triggered subsystem to update the extmode active dwork.
%%
%function FcnGenerateExtModeOutput() void
  %openfile ext
  %if Type == "trigger" || Type == "enable_with_trigger" || Type == "enable" || ...
    Type == "function-call" || Type == "action"
    %assign callSites      = CallSites
    %assign graphParentSys = CompiledModel.System[callSites[0][2]]
    %assign ssBlock        = graphParentSys.Block[callSites[0][3]]
    %with ssBlock
      %foreach i = NumDWork
	%assign dwRec  = DWork[i]
	%assign dwName = LibBlockDWorkName(dwRec)
	%assign dwIdx  = dwRec.FirstRootIdx
	%if dwName == SLibGetNameOfExtModeActiveDWork()
	  %assign mode = SLibGetSubsystemActiveVector(dwIdx)
	  %<mode> = EXTMODE_SUBSYS_ENABLED;
	%endif
      %endforeach
    %endwith
  %endif
  %closefile ext
  %return ext
%endfunction %% FcnGenerateExtModeOutput


%% Function: FcnUpdateSubsysRanBC(system) ======================================
%% Description:
%%   Find the SUBSYS_RAN_BC dwork entry for this system and update it
%%
%function FcnUpdateSubsysRanBC(system) void
  %assign buf = ""
  %if (IsModelReferenceSimTarget() || Accelerator || (ExtMode == 1)) &&...
                                                (system.Type != "root")
    %openfile buf
    %assign callSites      = system.CallSites
    %assign graphParentSys = CompiledModel.System[callSites[0][2]]
    %assign ssBlock        = graphParentSys.Block[callSites[0][3]]
    %assign dworks         = CompiledModel.DWorks
    %if SLibIsCondExec(system, ssBlock)
      %with ssBlock
	%% We only need the MajorTimeStep guard for enable subsystems-all other
	%% subsystems should already be guarded (implicit or explicitly)
	%assign needMajorTimeStepGuard = TLC_FALSE
	%if (system.Type == "enable") || (system.Type == "action")
	  %assign needMajorTimeStepGuard=(ParamSettings.MinorStepGuard== "yes")
	%endif
	%foreach i = NumDWork
	  %% Loop over all the DWorks for this block and look for SUBSYS_RAN_BC
	  %assign blkDwRec  = DWork[i]
	  %assign dwName    = LibBlockDWorkName(blkDwRec)
	  %assign dwIdx     = blkDwRec.FirstRootIdx
	  %if dwName == SLibGetNameOfSubsysRanBCDWork()
	    %% Found it! Figure out the full path and write into the buffer
	    %assign dwRec   = dworks.DWork[dwIdx]
	    %assign idxVec  = SLibGetSystemAndCallSideIndex(dwRec)
	    %assign sysIdx  = idxVec[0]
	    %assign csIdx   = idxVec[1]
	    %assign hStructIdx = system.HStructDeclSystemIdx
	    %assign dwPath  = FcnGetLocalDWorkPath(sysIdx, csIdx, hStructIdx)
	    %switch system.Type
	      %case "trigger"
	      %case "enable_with_trigger"
	      %case "function-call"
		%<dwPath>%<dwRec.Identifier> = SUBSYS_RAN_BC_ONE_SHOT;
		%break
	      %default
		
		%if needMajorTimeStepGuard
		  if (%<RTMIs("MajorTimeStep")>) {
		  %endif
		    srUpdateBC(%<dwPath>%<dwRec.Identifier>);
		  %if needMajorTimeStepGuard
		  }
		%endif
	    %endswitch
	    %break
	  %endif
	%endforeach
      %endwith
    %endif
    %closefile buf
  %endif
  
  %return buf
%endfunction %% FcnUpdateSubsysRanBC

%% Function: GetSystemAsyncTIDCode =======================
%%
%%
%function GetSystemAsyncTIDCode(block, system, fcnType, tid)
  %assign ts  = SampleTime[tid] 
  %assert fcnType == "Output" || fcnType == "Update"
  %assert ts.Asynchronous == "yes" 
  
  %with block
    %assign ss = CompiledModel.System[CallSiteInfo.SystemIdx]
    
    %if LibSystemIsReusedFcn(ss)
      %%  When single rate system is reused from different tids and these tids
      %%  include asychronous tid, it is possible that the reused code 
      %%  is put in the buf associated with one of the async tids that reuse
      %%  the code. When subsytem generates code for its own tid (SubsystemTID), 
      %%  subsystem need get code from the tid that has the 
      %%  code. 
      %if ISEQUAL(tid, block.SubsystemTID)
	%assign tmpTid = FcnGetReusedSubsystemCodeTID(ss)
	%assign system.CurrentTID = tmpTid
	%assign tmpBuf = (fcnType == "Output") ? ...
	  SLibGenerateNonExprOutputForTID(block,system,"",tmpTid) : ...
	  SLibGenerateForTID(block, "UpdateForTID", system, tmpTid)
	%assign system.CurrentTID = -1
      %else
	 %assign tmpBuf = ""
      %endif    
    %elseif FcnSubsystemIsAsycnTopSS(ss) 
      %% allways dump async code if subsystem is a async
      %% top system 
      %assign tmpBuf = LibGetSystemField(ss, "Cached%<fcnType>%<tid>Fcn")
    %else 
      %if ss.Type == "function-call" 
	%% If system is function call system, 
	%% -- code associated with system tid is generated with 
	%%    fcncall generator block, don't need dump here. 
	%% -- code that not associated with system tid won't be
	%%    generated with fcncall generator block, should 
	%%    dump here. 
	%if ISEQUAL(tid, FcnGetSubsystemTID(system))
	  %assign tmpBuf = ""
	%else
	  %assign tmpBuf = LibGetSystemField(ss, "Cached%<fcnType>%<tid>Fcn")
	%endif
      %else
	%% always dump async code if system is not fcn-call system
	%assert system.CurrentTID == -1
	%assign system.CurrentTID = tid
	%assign tmpBuf = (fcnType == "Output") ? ...
	  SLibGenerateNonExprOutputForTID(block,system,"",tid) : ...
	  SLibGenerateForTID(block, "UpdateForTID", system, tid)
	%assign system.CurrentTID = -1
      %endif
    %endif
  %endwith
  
  %return tmpBuf
%endfunction

%% Function: FcnGenerateRateGroupedOutput =============================
%% Abstract:
%%   Generate rate grouped output code,
%%   Function return an array Multirate_outputBuffers[NumSampleTimes]
%%
%function FcnGenerateRateGroupedOutput(system)
  %assign tid01Eq = ISEQUAL(SolverType, "FixedStep") && FixedStepOpts.TID01EQ
  %foreach tid = NumSampleTimes
    %assign outputBufferForTID%<tid> = ""
  %endforeach
  %foreach blkIdx = NumBlocks
    %assign block = Block[blkIdx]
    %with block
      %if SkipBlockFcn
        %continue
      %endif
      %assign current_tid = TID
      %% Check if this is a model reference block, then load the Tid01eq
      %% from the interface.  If tid01eq is true and
      %if block.Type == "ModelReference"
        %assign current_tid = FcnMapTIDForRateGrouping(block, current_tid)
      %endif
      %if LibBlockAllOutputSignalsAreExpr()
	%% skip output if all outputs are expressions
      %elseif ISEQUAL(current_tid, "constant")
	%% No action taken
	%<FcnWriteReducedBlocksComment(block)>\
      %elseif TYPE(current_tid) == "Number"
	%assign system.CurrentTID = current_tid
	%openfile tmpBuffer
	%<SLibGenerateNonExprOutput(block,system)>\
	%closefile tmpBuffer
	%assign system.CurrentTID = -1
	%if !WHITE_SPACE(tmpBuffer)
          %assign tid = current_tid
          %% For tid01Eq=1, add tid=1 code to tid=0 buffer
          %if tid01Eq && (tid == 1)
            %assign tid = 0
            %openfile tmpBufferTid01Eq
              if (%<RTMIs("MajorTimeStep")>) {
                %<tmpBuffer>\
              }
            %closefile tmpBufferTid01Eq
            %assign tmpBuffer = tmpBufferTid01Eq
          %endif
	  %% Code of "Asynchronous Rate Transition: Reader"
	  %% is grouped with AsyncPromptedTID in order to
	  %% synchronize data transfer with this async task's
	  %% caller. See abstract of FcnGetAsyncPromotedTID
	  %% for more information
	  %if LibAsynchronousTriggeredTID(current_tid) && ...
	    Type == "S-Function" && ISFIELD(block, "MaskType") && ...
	    MaskType == "Asynchronous Rate Transition: Reader"
	    %assign tid = FcnGetAsyncPromotedTID(current_tid)
	  %endif
	  %assign outputBufferForTID%<tid> = ...
	    outputBufferForTID%<tid> + tmpBuffer
	%endif
	%undef tmpBuffer
      %elseif TYPE(current_tid) == "Vector"
	%assign sfuncName    = ...
	  (block.Type == "S-Function")? ParamSettings.FunctionName : ""
	%assign TIDVectorLen = SIZE(current_tid,1)
	%if SLibBlockFcnRateGrouping(block, "Outputs")
	  %%
	  %% If the block TLC file rate-grouping compliant.
	  %% outputBufferForTID# code is written to corresponind
	  %% buffer for TID
	  %%
	  %assign fcnName      = "OutputsForTID"
 	  %assign system.CurrentTID = -1
	  %foreach TIDidx = TIDVectorLen
	    %assign tid   = current_tid[TIDidx]
	    %assign orgTid = tid

	    %% Output code of port based blocks is grouped with
	    %% AsyncPromotedTID if its orignal tid is
	    %% asynchronous tid. See abstract of
	    %% FcnGetAsyncPromotedTID
	    %% for more information
	    %if LibAsynchronousTriggeredTID(tid)
	      %assign tid = FcnGetAsyncPromotedTID(orgTid)
	    %endif
	    %assign tid = (tid < 0)? 0 : tid
	    %openfile tmpBuffer
	    %assign system.CurrentTID = tid
	    %<SLibGenerateNonExprOutputForTID(block,system,sfuncName,orgTid)>\
	    %assign system.CurrentTID = -1
	    %closefile tmpBuffer
	    %if !WHITE_SPACE(tmpBuffer)
	      %% For tid01Eq=1, add tid=1 code to tid=0 buffer
              %if tid01Eq && (tid == 1)
                %assign tid = 0
                %openfile tmpBufferTid01Eq
                  if (%<RTMIs("MajorTimeStep")>) {
                    %<tmpBuffer>\
                  }
                %closefile tmpBufferTid01Eq
                %assign tmpBuffer = tmpBufferTid01Eq
              %endif
	      %assign outputBufferForTID%<tid> = ...
		outputBufferForTID%<tid> + tmpBuffer
	    %endif
	  %endforeach
	%else
	  %assign system.CurrentTID = current_tid
	  %openfile tmpBuffer
	  %<SLibGenerateNonExprOutput(block,system)>\
	  %closefile tmpBuffer
	  %assign warnTxt = ""
	  %assign system.CurrentTID = -1
	  %assign isInlinedSfcn = Type == "S-Function" && SFunctionType == "TLC"
	  %if !WHITE_SPACE(tmpBuffer) 
	    %if SLibBlkHasMultirateCode(block) && isInlinedSfcn
	      %assign warnTxt = ...
		"Code of output function for multirate "...
		"block '%<Name>' is guarded by sample hit checks "...
		"rather than being rate grouped. This will generate "...
		"the same code for all rates used by the block, "...
		"possibly generating dead code. To avoid dead "...
		"code, you must update the TLC file for the block."
	      %<LibReportWarning(warnTxt)>
	      %assign warnTxt = ...
		"/* Because the output function of multirate block \n"...
		"   %<Name> is not rate grouped, \n"...
		"   the following code might contain unreachable blocks of code. \n"...
		"   To avoid this, you must update your block TLC file. */"
	    %endif
	    %assign tmpBufferHasDumpedForTID0 = TLC_FALSE
	    %foreach TIDidx =  TIDVectorLen
	      %assign tid = current_tid[TIDidx]
	      %if TYPE(tid) == "Number" && tid > 0
                %% For tid01Eq=1, no code for tid1
                %if tid01Eq && (tid == 1)
		  %continue
		%endif
		%assign outputBufferForTID%<tid> = ...
		  outputBufferForTID%<tid> + warnTxt + tmpBuffer
	      %elseif !tmpBufferHasDumpedForTID0
                %% put tid=0 and tid=non-numeric code into tid=0 buffer
		%assign outputBufferForTID0 = ...
		  outputBufferForTID0 + tmpBuffer
		%assign tmpBufferHasDumpedForTID0 = TLC_TRUE
	      %endif
	    %endforeach
	  %endif
	%endif
      %elseif ISEQUAL(current_tid, "Subsystem")
	%assign ss         = CompiledModel.System[CallSiteInfo.SystemIdx]
	%% generate code for Synchronous tid
	%%
	%if SLibIsMultiRateAndRateGrouping(ss)
	  %% subsystem is multirate
	  %assign tid0CodeHasGenerated = TLC_FALSE
	  %foreach tidIdx = SIZE(SubsystemTID,1)
	    %assign tid = SubsystemTID[tidIdx]
	    %assign system.CurrentTID = tid
	    %if !LibAsynchronousTriggeredTID(tid)
	      %if tid01Eq && (tid == 1)
		%% For tid01Eq=1, add tid=1 code to tid=0 buffer
		%if tid0CodeHasGenerated 
		  %% avoid generate tid0 code twice
		  %continue
		%else
		  %assign needMajorTimeStepGuard = TLC_TRUE
		  %assign tid = 0
		%endif
	      %else
		%assign needMajorTimeStepGuard = TLC_FALSE
	      %endif
	      %if tid == 0
		%assign tid0CodeHasGenerated = TLC_TRUE
	      %endif
	      %openfile tmpBuffer
	      %<SLibGenerateNonExprOutputForTID(block,system,"",tid)>\
	      %closefile tmpBuffer
	      %assign system.CurrentTID = -1
	      %if !WHITE_SPACE(tmpBuffer)
		%if needMajorTimeStepGuard
		  %openfile tmpBufferTid01Eq
		  if (%<RTMIs("MajorTimeStep")>) {
		    %<tmpBuffer>\
                  }
		  %closefile tmpBufferTid01Eq
		  %assign tmpBuffer = tmpBufferTid01Eq
		%endif
		%assign outputBufferForTID%<tid> = ...
		  outputBufferForTID%<tid> + tmpBuffer
	      %endif
	    %endif
	  %endforeach
	%else
	  %% subsystem is single rate,
	  %assign tid = SubsystemTID
	  %if !LibAsynchronousTriggeredTID(tid)
	    %openfile tmpBuffer
	    %<SLibGenerateNonExprOutput(block,system)>\
	    %closefile tmpBuffer
	    %if !WHITE_SPACE(tmpBuffer)
	      %if TYPE(tid) == "Number"
		%assert tid >= 0
		%% For tid01Eq=1, add tid=1 code to tid=0 buffer
		%if tid01Eq && (tid == 1)
		  %assign tid = 0
		  %openfile tmpBufferTid01Eq
		  if (%<RTMIs("MajorTimeStep")>) {
		    %<tmpBuffer>\
		  }
		  %closefile tmpBufferTid01Eq
		  %assign tmpBuffer = tmpBufferTid01Eq
		%endif
		%assign outputBufferForTID%<tid> = ...
		  outputBufferForTID%<tid> + tmpBuffer
	      %else
		%assert ISEQUAL(tid, "constant") || ...
		  ISEQUAL(tid, [0,1]) && tid01Eq
		%assign outputBufferForTID0 = ...
		  outputBufferForTID0 + tmpBuffer%<tmpBuffer>
	      %endif
	    %endif
	  %endif
	%endif
	%% Generate code for Asynchronous tid
	%foreach tidIdx = NumAsynchronousSampleTimes
	  %assign tid = tidIdx + NumSynchronousSampleTimes
	  %assign outputBufferForTID%<tid> = ...
	    outputBufferForTID%<tid> + ...
	    GetSystemAsyncTIDCode(block,system,"Output",tid)
	%endforeach
      %endif
    %endwith
  %endforeach
  %assign Multirate_outputBuffers  =[] 
  %% Update the system ran breadcrumb (ModelRefSimTarget and ExtMode)
  %assign sysRanCode = ""
  %if (system.Type != "enable")
    %assign sysRanCode = FcnUpdateSubsysRanBC(system)
  %endif

  %% Prepend the system ran clearing code, if needed
  %foreach Tid = NumSampleTimes
    %assign sysRanReset = ""
    %if IsBaseSystem(system) && (ExtMode == 1)
      %assign sysRanReset = SLibGetSubsystemRanBCReset(system, Tid)
    %endif
    %assign tmpOutputBufferForTID = outputBufferForTID%<Tid>
    %assign Multirate_outputBuffers = ...
      Multirate_outputBuffers +"%<sysRanReset>%<tmpOutputBufferForTID>%<sysRanCode>"
    
 %endforeach
  %return  Multirate_outputBuffers
%endfunction %%   FcnGenerateRateGroupedOutput

%% Function: FcnGenerateTidGuardOpenCode(tid) ===========================
%%  Return TID guard open potion.
%%  If rate grouping is on, return "" because
%%  rate grouped code does not need tid guard
%%
%function FcnGenerateTidGuardOpenCode(tid)
  %assign tidGuard = LibIsSampleHit(tid)

  %if SLibIsRateGrouping() || tidGuard == "1"
    %return "{ %<LibTaskComment(tid)>"
  %else
    %return  "if (%<tidGuard>) { %<LibTaskComment(tid)>"
  %endif
%endfunction %%  FcnGenerateTidGuardOpenCode

%% Function: FcnGenerateTidGuardCloseCode(tid) ===========================
%%  Return TID guard close potion.
%%  If rate grouping is on, return "" because
%%  rate grouped code does not need tid guard
%%
%function FcnGenerateTidGuardCloseCode(tid)
  %return  "}"
%endfunction %%  FcnGenerateTidGuardCloseCode


%% Function: FcnGenerateNonRateGroupedOutput ===========================
%% Abstract:
%%  Generate non-rate-grouped output code
%%
%function FcnGenerateNonRateGroupedOutput(system)
  %foreach tid = NumAsynchronousSampleTimes
    %assign outputBufferForAsyncTID%<tid+NumSynchronousSampleTimes> = ""
  %endforeach
  %assign Multirate_outputBuffers = []
  %foreach idx = NumSampleTimes
    %assign Multirate_outputBuffers = ...
      Multirate_outputBuffers + ""
  %endforeach
  %openfile outputTmpBuf
  %assign prevTID = ""
  %% If system is a single rate, don't need tid guard inside
  %% this system.
  %assign needTIDGuard = !LibIsSingleRateSystem(system)
  %assign scopeOpen = 0
  %foreach blkIdx = NumBlocks
    %assign block = Block[blkIdx]
    %assign multiTasking = !SLibSingleTasking()
    %with block
      %if SkipBlockFcn
        %continue
      %endif    
      %%
      %% Previous TID is NULL ("").
      %%

      %% skip output if all outputs are expressions
      %if LibBlockAllOutputSignalsAreExpr()
	%continue
      %endif

      %% otherwise

      %if ISEQUAL(TID, "constant")
	%% No action taken
	%<FcnWriteReducedBlocksComment(block)>\
      %elseif TYPE(TID) == "Number"
	%assign system.CurrentTID = TID
	%openfile tmpBuffer
	%<SLibGenerateNonExprOutput(block,system)>\
	%closefile tmpBuffer
	%assign system.CurrentTID = -1
	%if !WHITE_SPACE(tmpBuffer)
	  %if LibAsynchronousTriggeredTID(TID)
	    %% Code of "Asynchronous Rate Transition: Reader"
	    %% is grouped with AsyncPromptedTID in order to
	    %% synchronize data transfer with this async task's
	    %% caller. See abstract of FcnGetAsyncPromotedTID
	    %% for more information
	    %if Type == "S-Function" && ISFIELD(block, "MaskType") && ...
	      MaskType == "Asynchronous Rate Transition: Reader"
	      %assign tid = FcnGetAsyncPromotedTID(TID)
	    %else
	      %assign tid = TID
	    %endif
	    
	    %if LibAsynchronousTriggeredTID(tid)
	      %% async tid
	      %assign outputBufferForAsyncTID%<tid> = ...
		outputBufferForAsyncTID%<tid> + tmpBuffer
	    %else
	      %<tmpBuffer>
	    %endif
	  %else
	    %% sync tid
	    %if ISEQUAL(TID, prevTID)
	      %<tmpBuffer>\
	    %else
	      %if scopeOpen && needTIDGuard
		%<FcnGenerateTidGuardCloseCode(prevTID)>
		%assign scopeOpen = 0
	      %endif
	      %if needTIDGuard && (TID != 0 || multiTasking)
		%<FcnGenerateTidGuardOpenCode(TID)>
		%assign scopeOpen = 1
	      %endif
	      %<tmpBuffer>\
	      %assign prevTID = TID
	    %endif
	  %endif
	%endif
	%undef tmpBuffer
      %elseif TYPE(TID) == "Vector"
	%assign system.CurrentTID = TID
	%openfile tmpBuf

	%<SLibGenerateNonExprOutput(block,system)>\

	%closefile tmpBuf
	%assign system.CurrentTID = -1
	%if !WHITE_SPACE(tmpBuf)
	  %if scopeOpen && needTIDGuard
	    %<FcnGenerateTidGuardCloseCode(prevTID)>
	    %assign scopeOpen = 0
	  %endif
	  %<tmpBuf>\
	  %assign prevTID = TID
	%endif
	%%
	%% generate and rate group async tid code
	%%
	%assign sfuncName    = ...
	  (block.Type == "S-Function")? ParamSettings.FunctionName : ""
	%assign fcnName      = "OutputsForTID"
	%assign TIDVectorLen = SIZE(TID,1)
	%foreach TIDidx = TIDVectorLen

	  %assign tid   = TID[TIDidx]
	  %if LibAsynchronousTriggeredTID(tid)
	    %% Output code of port based blocks is grouped with
	    %% AsyncPromotedTID if its orignal tid is
	    %% asynchronous tid. See abstract of
	    %% FcnGetAsyncPromotedTID
	    %% for more information
	    %assign orgTid = tid
	    %assign tid = FcnGetAsyncPromotedTID(orgTid)
	    %assign system.CurrentTID = tid
	    %assign tmpBuf = SLibGenerateNonExprOutputForTID(block,system,sfuncName,orgTid)
	    %if LibAsynchronousTriggeredTID(tid)
	      %assign outputBufferForAsyncTID%<tid> = ...
		outputBufferForAsyncTID%<tid> + tmpBuf
	      %assign system.CurrentTID = -1
	    %else
	      %<tmpBuf>
	    %endif
	  %endif
	%endforeach
      %elseif ISEQUAL(TID, "Subsystem")
	%assign ss  = CompiledModel.System[CallSiteInfo.SystemIdx]
	%openfile tmpBuf
	%<SLibGenerateNonExprOutput(block,system)>\

	%closefile tmpBuf
	%if !WHITE_SPACE(tmpBuf)
	  %if scopeOpen && needTIDGuard
	    %<FcnGenerateTidGuardCloseCode(prevTID)>
	    %assign scopeOpen = 0
	  %endif
	  %%
	  %<tmpBuf>
	  %assign prevTID = TID
	%endif
	%% Generate code for Asynchronous tid
	%% since code for async is always rate grouped
	%% need generate tid specific code
	%foreach tidIdx = NumAsynchronousSampleTimes
	  %assign tid = tidIdx + NumSynchronousSampleTimes
	  %assign outputBufferForAsyncTID%<tid> = ...
	    outputBufferForAsyncTID%<tid> + ...
	    GetSystemAsyncTIDCode(block,system,"Output",tid)
	%endforeach
      %elseif ISEQUAL(TID, "triggered")
	%assign system.CurrentTID = TriggerTID
	%if LibAsynchronousTriggeredTID(TriggerTID)
	  %% async TID
	  %assign outputBufferForAsyncTID%<TriggerTID> = ...
	    outputBufferForAsyncTID%<TriggerTID> + ...
	    SLibGenerateNonExprOutput(block,system)
	%else
	  %if scopeOpen && needTIDGuard
	    %<FcnGenerateTidGuardCloseCode(prevTID)>
	    %assign scopeOpen = 0
	  %endif
	  %%
	  %<SLibGenerateNonExprOutput(block,system)>\
	%endif
	%assign system.CurrentTID = -1
	%assign prevTID = TID
      %endif
    %endwith
  %endforeach
  %if scopeOpen == 1 && needTIDGuard
    %<FcnGenerateTidGuardCloseCode(prevTID)>
  %endif
  %closefile outputTmpBuf
  
  %% Update the system ran breadcrumb (ModelRefSimTarget only)
  %assign sysRanBCOutput = "" 
  %if (system.Type != "enable")
    %assign sysRanBCOutput = FcnUpdateSubsysRanBC(system)
  %endif

  %% Prepend the system ran clearing code, if needed
  %assign sysRanReset = ""
  %if IsBaseSystem(system) && (ExtMode == 1)
    %assign sysRanReset = SLibGetSubsystemRanBCReset(system, 0)
  %endif
  
  %assign Multirate_outputBuffers[0] = "%<sysRanReset>%<outputTmpBuf>%<sysRanBCOutput>"
  
  %foreach idx = NumAsynchronousSampleTimes 
    %assign tid = idx + NumSynchronousSampleTimes
    %assign Multirate_outputBuffers[tid] = outputBufferForAsyncTID%<tid>
  %endforeach
  %return  Multirate_outputBuffers
  
%endfunction %% FcnGenerateNonRateGroupedOutput


%% Function: FcnGenerateOutput(system) =========================================
%% Description:
%%      Generates the Outputs code for a system with the proper scoping(s) of
%%      blocks in their TIDs.
%%
%function FcnGenerateOutput(system) void
  %assign ::CompiledModel.GeneratingOutputsCode = 1
  %with system
    %assign extOutput = ""
    %if ExtMode == 1
      %assign extOutput = FcnGenerateExtModeOutput()
    %endif
    %if SLibIsMultiRateAndRateGrouping(system)
      %% rate grouping
      %%
      %assign Multirate_outputBuffers = ...
	FcnGenerateRateGroupedOutput(system)
    %else
      %% not rate grouping
      %%
      %assign Multirate_outputBuffers = ...
	FcnGenerateNonRateGroupedOutput(system)
    %endif
  %%  %endif   %% employTIDTransitionTable
  %endwith %% system
  %% Reset solver if needed
  %openfile resetSolverBuffer
  %if system.Type == "root" && ...
    CodeFormat == "S-Function" && !Accelerator && ...
    SolverType == "VariableStep"
    %assign nDU = SolverResetInfo.NumNonContDerivSignals
    %if nDU > 0
      %assign dU  = "nonContDerivSigCache"

      {
	%assign varName = "pNonContDerivSig"
	%<dU> *%<varName> = (%<dU> *)%<RTMGet("LocalNonContDerivSig")>;
	%foreach idx = nDU
	  %%
	  %assign sigSrc = SolverResetInfo.NonContDerivSignal[idx].SigSrc
	  %assign startEl = SolverResetInfo.NonContDerivSignal[idx].StartEl
	  %assign regLen = SolverResetInfo.NonContDerivSignal[idx].RegionLen
	  %%
	  %assign idNum = IDNUM(sigSrc)
	  %assert (idNum[0] == "B")
	  %if idNum[1] < BlockOutputs.NumGlobalBlockOutputs
	    %assign bo = BlockOutputs.GlobalBlockOutput[idNum[1]]
	    %assert (bo.Width >= regLen + startEl)
	    %assert (bo.Invariant == "no")
	    %assert (bo.ComplexSignal == "no")
	    %%
	    %assign boPath = FcnGetLocalBlockIOPath(bo.SigSrc[0], ...
	      bo.SigSrc[1], ...
	      NumSystems-1)
	    %assign name = "%<boPath>%<bo.Identifier>"
	  %else
	    %assign nExternalOp = BlockOutputs.NumExternalBlockOutputs
	    %foreach iExOp = nExternalOp
	      %if BlockOutputs.ExternalBlockOutput[iExOp].LogicalSrc == sigSrc
		%assign bo = BlockOutputs.ExternalBlockOutput[iExOp]
		%break
	      %endif
	    %endforeach
	    %assign name = "%<bo.SigLabel>"
	  %endif
	  %assign opW  = (bo.Width == 1) ? "" : "[%<startEl>]"
	  %assign addr = "&%<name>%<opW>"
	  %assign dType = LibGetDataTypeNameFromId(bo.DataTypeIdx)
	  %assign sizeInBytes = "%<regLen>*sizeof(%<dType>)"

	  if (memcmp(%<varName>->cache_%<idx>, (char *)%<addr>, %<sizeInBytes>) != 0) {
	    (void)memcpy(%<varName>->cache_%<idx>, (char *)%<addr>, %<sizeInBytes>);
	    ssSetSolverNeedsReset(%<tSimStruct>);
	  }
	%endforeach
      }
    %endif
  %endif
  %closefile resetSolverBuffer
  %assign ::CompiledModel.GeneratingOutputsCode = 0
  %assign Multirate_outputBuffers[0] = ...
      extOutput + Multirate_outputBuffers[0] + resetSolverBuffer
  %if ISEQUAL(SolverType, "FixedStep") && FixedStepOpts.TID01EQ
    %assert (WHITE_SPACE(Multirate_outputBuffers[1]))
  %endif
  %return Multirate_outputBuffers
%endfunction

%% Function: FcnGenerateRateGroupedUpdate ============================
%% Abstract:
%%   Generate rate grouped update code for system,
%%   function return a array Multirate_updateBuffers[NumSyncronousSampleTimes]
%%
%function FcnGenerateRateGroupedUpdate(system)
  %assign tid01Eq = ISEQUAL(SolverType, "FixedStep") && FixedStepOpts.TID01EQ
  %foreach tid = NumSampleTimes
    %assign updateBufferForTID%<tid> = ""
  %endforeach
  %foreach blkIdx = NumBlocks
    %assign block = Block[blkIdx]
    %with block
      %if SkipBlockFcn
        %continue
      %endif    
      %%
      %% Get "curent_tid"  is equal to the block's tid, unless
      %% it is a special sample hit, in which case we need to use
      %% the sample time index.
      %%
      %assign current_tid = TID
      %if EXISTS("SampleTimeIdx")
	%assign current_tid = SampleTimeIdx
      %endif
      %% Check if this is a model reference block, then load the Tid01eq
      %% from the interface.  If tid01eq is true and
      %if block.Type == "ModelReference"
        %assign current_tid = FcnMapTIDForRateGrouping(block, current_tid)
      %endif
      %%
      %%  updateBuffer for TID
      %%
      %if ISEQUAL(current_tid, "constant")
	%% No action taken
      %elseif TYPE(current_tid) == "Number"
	%assign system.CurrentTID = current_tid
	%openfile tmpBuffer

	%<SLibGenerate(block, "Update", system)>

	%closefile tmpBuffer
	%assign system.CurrentTID = -1
	%if !WHITE_SPACE(tmpBuffer)
          %% For tid01Eq=1, add tid=1 code to tid=0 buffer
          %assign tidOut = tid01Eq && (current_tid == 1) ? 0 : current_tid
	  %assign updateBufferForTID%<tidOut> = ...
	    updateBufferForTID%<tidOut> + tmpBuffer
	%endif
	%undef tmpBuffer
      %elseif TYPE(current_tid) == "Vector"
	%assign sfuncName = ...
	  (block.Type == "S-Function") ? ...
	  ParamSettings.FunctionName : ""
	%assign TIDVectorLen = SIZE(current_tid,1)
	%if SLibBlockFcnRateGrouping(block, "Update")
	  %%
	  %% If the block TLC file rate-grouping compliant.
	  %% UpdateForTID# code is written to corresponind
	  %% buffer for TID
	  %%
	  %assign fcnName      = "UpdateForTID"
	  %foreach TIDidx             = TIDVectorLen
	    %assign tid               = current_tid[TIDidx]
	    %assign system.CurrentTID = tid < 0 ? 0 : tid
	    %openfile tmpBuffer

	    %if block.Type == "S-Function"
	      %<GENERATE_TYPE(block, fcnName, sfuncName, system, tid)>
	    %else
	      %<SLibGenerateForTID(block, fcnName, system, tid)>
	    %endif

	    %closefile tmpBuffer
	    %assign system.CurrentTID = -1
	    %if !WHITE_SPACE(tmpBuffer)
	      %assign tid   = (tid < 0)? 0 : tid
              %% For tid01Eq=1, add tid=1 code to tid=0 buffer
              %assign tidOut = tid01Eq && (tid == 1) ? 0 : tid
	      %assign updateBufferForTID%<tidOut> = ...
		updateBufferForTID%<tidOut> + tmpBuffer
	    %endif
	  %endforeach
	%else
	  %%
	  %% If the block TLC file not rate-grouping compliant.
	  %% updateBufferForTID# code is written into updatebuffer
	  %% if not-rate-grouping, written into all involved
	  %% updateBufferForTID## if is rate grouping.
	  %%
	  %assign system.CurrentTID = current_tid
	  %openfile tmpBuffer

	  %<SLibGenerate(block, "Update", system)>

	  %closefile tmpBuffer
	  %assign warnTxt = ""
	  %assign system.CurrentTID = -1
	  %assign isInlinedSfcn = Type == "S-Function" && SFunctionType == "TLC"
	  %if !WHITE_SPACE(tmpBuffer) 
	    %if SLibBlkHasMultirateCode(block) && isInlinedSfcn
	      %assign warnTxt = ...
		"Code of update function for multirate "...
		"block '%<Name>' is guarded by sample hit checks "...
		"rather than being rate grouped. This will generate "...
		"the same code for all rates used by the block, "...
		"possibly generating dead code. To avoid dead "...
		"code, you must update the TLC file for the block."
	      %<LibReportWarning(warnTxt)>
	      %assign warnTxt = ...
		"/* Because the update function of multirate block \n"...
		"   %<Name> is not rate grouped, \n"...
		"   the following code might contain unreachable blocks of code. \n"...
		"   To avoid this, you must update your block TLC file. */"
	    %endif
	    %assign tmpBufferHasDumpedForTID0 = TLC_FALSE
	    %foreach TIDidx =  TIDVectorLen
	      %assign tid = TID[TIDidx]
	      %if TYPE(tid) == "Number" && tid > 0
		%% If tid01Eq=1, no code for tid1
                %if tid01Eq && (tid == 1)
		  %continue
		%endif
		%assign updateBufferForTID%<tid> = ...
		  updateBufferForTID%<tid> + warnTxt + tmpBuffer
	      %elseif !tmpBufferHasDumpedForTID0
                %% put tid=0 and tid=non-numeric code into tid=0 buffer
		%assign updateBufferForTID0 = ...
		  updateBufferForTID0 + tmpBuffer
		%assign tmpBufferHasDumpedForTID0 = TLC_TRUE
	      %endif
	    %endforeach
	  %endif
	%endif
      %elseif ISEQUAL(current_tid, "Subsystem")
	%assign ss= CompiledModel.System[CallSiteInfo.SystemIdx]
	%% generate code for Synchronous tid
	%%
	%if SLibIsMultiRateAndRateGrouping(ss)
	  %% subsystem is multirate
	  %assign fcnName = "UpdateForTID"
	  %assign tid0CodeHasGenerated = TLC_FALSE		  
	  %foreach tidIdx = SIZE(SubsystemTID,1)
	    %assign tid = SubsystemTID[tidIdx]
	    %if !LibAsynchronousTriggeredTID(tid)
	      %if tid01Eq && (tid == 1)
		%% For tid01Eq=1, add tid=1 code to tid=0 buffer
		%if tid0CodeHasGenerated 
		  %% avoid generate tid0 code twice
		  %continue
		%else
		  %assign tid = 0
		%endif
	      %endif
	      %if tid == 0
		%assign tid0CodeHasGenerated = TLC_TRUE
	      %endif
	      %assign system.CurrentTID = tid
	      %openfile tmpBuffer

	      %<SLibGenerateForTID(block, fcnName, system, tid)>

	      %closefile tmpBuffer
	      %assign system.CurrentTID = -1
	      %if !WHITE_SPACE(tmpBuffer)
		%assign updateBufferForTID%<tid> = ...
		  updateBufferForTID%<tid> + tmpBuffer
	      %endif
	    %endif
	  %endforeach
	%else
	  %% subsystem is single rate
	  %if !LibAsynchronousTriggeredTID(SubsystemTID)
	    %assign fcnName = "Update"
	    %assign tid   = SubsystemTID
	    %openfile tmpBuffer
	    
	    %<SLibGenerate(block, fcnName, system)>
	    
	    %closefile tmpBuffer
	    %if !WHITE_SPACE(tmpBuffer)
	      %if TYPE(tid) == "Number"
		%% For tid01Eq=1, add tid=1 code to tid=0 buffer
		%assign tidOut = tid01Eq && (tid == 1) ? 0 : tid
		%assign updateBufferForTID%<tidOut> = ...
		  updateBufferForTID%<tidOut> + tmpBuffer
	      %else
		%assert ISEQUAL(tid, "constant") || ...
		  ISEQUAL(tid, [0,1]) && tid01Eq
		%assign updateBufferForTID0 = ...
		  updateBufferForTID0 + tmpBuffer
	      %endif
	    %endif
	  %endif
	%endif
	%% Generate code for Asynchronous tid
	%foreach tidIdx = NumAsynchronousSampleTimes
	  %assign tid = tidIdx + NumSynchronousSampleTimes
	  %assign updateBufferForTID%<tid> = ...
	    updateBufferForTID%<tid> + ...
	   GetSystemAsyncTIDCode(block,system,"Update",tid)
	%endforeach
      %endif
    %endwith
  %endforeach  %% Block
  %assign Multirate_updateBuffers = []
  %foreach Tid = NumSampleTimes
    %assign Multirate_updateBuffers = ...
      Multirate_updateBuffers + updateBufferForTID%<Tid>
  %endforeach
  %return Multirate_updateBuffers
%endfunction

%% Function: FcnGenerateNonRateGroupedUpdate =================================
%% Abstract:
%%   Generate non rate grouped update code
%%
%function FcnGenerateNonRateGroupedUpdate(system)
  %assign scopeOpen = 0
  %assign multiTasking = !SLibSingleTasking()
  %foreach tid = NumAsynchronousSampleTimes
    %assign updateBufferForAsyncTID%<tid+NumSynchronousSampleTimes> = ""
  %endforeach
  %assign Multirate_updateBuffers = []
  %foreach idx = NumSampleTimes
    %assign Multirate_updateBuffers = Multirate_updateBuffers + ""
  %endforeach
  %assign prevTID = ""
  %% If system is a single rate, don't need tid guard inside
  %% this system.
  %assign needTIDGuard = !LibIsSingleRateSystem(system)
  %openfile tmpUpdateBuf
  %foreach blkIdx = NumBlocks
    %assign block = Block[blkIdx]
    %with block
      %if SkipBlockFcn
        %continue
      %endif    
      %%
      %% Get "current" tid which is equal to the block's tid, unless
      %% it is a special sample hit, in which case we need to use
      %% the sample time index.
      %%
      %assign currentTID = TID
      %if EXISTS("SampleTimeIdx")
	%assign currentTID = SampleTimeIdx
      %endif
      %%
      %% Previous tid was nothing (ie, "").  This is a special
      %% case from the cases listed in the RTW Functional
      %% Specification since previous tid hasn't been set.  A current
      %% tid of type constant is ignored.
      %%
      %if ISEQUAL(currentTID, "constant")
	%% No action taken
      %elseif TYPE(currentTID) == "Number"
	%assign system.CurrentTID = currentTID
	%openfile tmpBuffer

	%<SLibGenerate(Block[blkIdx], "Update", system)>

	%closefile tmpBuffer
	%assign system.CurrentTID = -1
	%if !WHITE_SPACE(tmpBuffer)
	  %if LibAsynchronousTriggeredTID(currentTID)
	    %% async tid
	    %assign updateBufferForAsyncTID%<currentTID> = ...
	      updateBufferForAsyncTID%<currentTID> + tmpBuffer
	  %else
	    %% sync tid
	    %if ISEQUAL(currentTID, prevTID)
	      %<tmpBuffer>\
	    %else
	      %if scopeOpen && needTIDGuard
		%<FcnGenerateTidGuardCloseCode(prevTID)>
		%assign scopeOpen = 0
	      %endif
	      %if needTIDGuard && (currentTID != 0 || multiTasking)
		%<FcnGenerateTidGuardOpenCode(currentTID)>
		%assign scopeOpen = 1
	      %endif
	      %<tmpBuffer>\
	      %assign prevTID = currentTID
	    %endif
	  %endif
	%endif
	%undef tmpBuffer
      %elseif TYPE(currentTID) == "Vector"
	%assign system.CurrentTID = currentTID
	%openfile tmpBuffer

	%<SLibGenerate(Block[blkIdx], "Update", system)>

	%closefile tmpBuffer
	%assign system.CurrentTID = -1
	%if !WHITE_SPACE(tmpBuffer)
	  %if scopeOpen && needTIDGuard
	    %<FcnGenerateTidGuardCloseCode(prevTID)>
	    %assign scopeOpen = 0
	  %endif
	  %<tmpBuffer>\
	  %assign prevTID = currentTID
	%endif
	%%
	%% generate and rate group async code
	%%
	%assign sfuncName    = ...
	  (block.Type == "S-Function")? ParamSettings.FunctionName : ""
	%assign fcnName      = "UpdateForTID"
	%assign TIDVectorLen = SIZE(TID,1)
	%foreach TIDidx = TIDVectorLen
	  %assign tid   = TID[TIDidx]
	  %if LibAsynchronousTriggeredTID(tid)
	    %assign system.CurrentTID = tid
	    %openfile tmpBuffer

	    %assert LibBlockFunctionExists(block, fcnName)
	    %if block.Type == "S-Function"
	      %<GENERATE_TYPE(block, fcnName, sfuncName, system, tid)>
	    %else
	      %<SLibGenerateForTID(block, fcnName, system, tid)>
	    %endif

	    %closefile tmpBuffer
	    %assign system.CurrentTID = -1
	    %assign updateBufferForAsyncTID%<tid> = ...
	      updateBufferForAsyncTID%<tid> + tmpBuffer
	  %endif
	%endforeach
      %elseif ISEQUAL(currentTID, "Subsystem")
	%assign ss  = CompiledModel.System[CallSiteInfo.SystemIdx]
	%openfile tmpBuf
	%<SLibGenerate(block, "Update", system)>
	%closefile tmpBuf
	%if !WHITE_SPACE(tmpBuf)
	  %if scopeOpen && needTIDGuard
	    %<FcnGenerateTidGuardCloseCode(prevTID)>
	    %assign scopeOpen = 0
	  %endif
	  %%
	  %<tmpBuf>
	  %assign prevTID = currentTID
	%endif
	%%
	%% generate code code for async tid
	%% since code for async is always rate grouped
	%% need generate tid specific code
	%% Generate code for Asynchronous tid
	%foreach tidIdx = NumAsynchronousSampleTimes
	  %assign tid = tidIdx + NumSynchronousSampleTimes
	  %assign updateBufferForAsyncTID%<tid> = ...
	    updateBufferForAsyncTID%<tid> + ...
	    GetSystemAsyncTIDCode(block,system,"Update",tid)
	%endforeach
      %elseif ISEQUAL(currentTID, "triggered")
	%assign system.CurrentTID = TriggerTID
	%if LibAsynchronousTriggeredTID(TriggerTID)
	  %% async TID
	  %assign updateBufferForAsyncTID%<TriggerTID> = ...
	    updateBufferForAsyncTID%<TriggerTID> + ...
	    SLibGenerate(Block[blkIdx], "Update", system)
	%else
	  %if scopeOpen && needTIDGuard
	    %<FcnGenerateTidGuardCloseCode(prevTID)>
	    %assign scopeOpen = 0
	  %endif

	  %<SLibGenerate(Block[blkIdx], "Update", system)>

	%endif
	%assign system.CurrentTID = -1
	%assign prevTID = currentTID
      %endif
    %endwith
  %endforeach  %% Block
  %if scopeOpen == 1 && needTIDGuard
    %<FcnGenerateTidGuardCloseCode(prevTID)>
  %endif
  %%
  %closefile tmpUpdateBuf
  %assign Multirate_updateBuffers[0] = tmpUpdateBuf

  %foreach idx = NumAsynchronousSampleTimes
    %assign tid = idx + NumSynchronousSampleTimes
    %assign Multirate_updateBuffers[tid] = updateBufferForAsyncTID%<tid>
  %endforeach
  %return  Multirate_updateBuffers

%endfunction %% FcnGenerateNonRateGroupedUpdate


%% Function: FcnGenerateUpdate(system) =========================================
%% Description:
%%      Generates the Update code for a system with the proper scoping(s) of
%%      blocks in their TIDs.
%%
%function FcnGenerateUpdate(system) void
  %with system
    %if SLibIsMultiRateAndRateGrouping(system)
      %% Multi-rate system, rate grouping
      %%
      %assign Multirate_updateBuffers = ...
	FcnGenerateRateGroupedUpdate(system)
    %else
      %%
      %% Multi-rate system, not rate grouping
      %%
      %assign Multirate_updateBuffers = ...
	FcnGenerateNonRateGroupedUpdate(system)
      %% end of Multi-rate system, no-rate- grouping
      %%
    %endif
  %endwith %% system

  %if ISEQUAL(SolverType, "FixedStep")
    %if FixedStepOpts.TID01EQ
      %assign Multirate_updateBuffers[0] = ...
	Multirate_updateBuffers[0] + Multirate_updateBuffers[1]
      %assign Multirate_updateBuffers[1] = ""
    %endif
  %endif
  %return Multirate_updateBuffers

%endfunction

%% Function: SLibGetRateGroupedFcnBody ===========
%%   Returned rate grouped Fcn body
%%  Only "Update" "Output" "OutputUdate" fcn body can
%%  be rate grouped.
%%  If system tid is asynchronous tid,
%%      always return rate grouped fcn body.
%%  If system tid is synchronous tid,
%%      - return rate grouped body if system is rate grouped
%%      - otherwise, return non-rate-grouped body.
%function SLibGetRateGroupedFcnBody(system, fcnType, dontChkEmpty)
  %openfile retBuf
  %assign ssTid = LibSystemIsReusedFcn(system) ? ...
    FcnGetReusedSubsystemCodeTID(system) :  FcnGetSubsystemTID(system)
  %%
  %assert fcnType == "Update" || ...
    fcnType == "Output" || fcnType == "OutputUpdate"
  %%
  %if LibAsynchronousTriggeredTID(ssTid)
    %% async tid always rate grouping
    %assign system.CurrentTID = ssTid
    %if !LibSystemFcnIsEmptyForTID(system, fcnType)
      %assign  fcnBody =  SLibGetBody%<fcnType>FcnCache(system)
      %<fcnBody>
    %endif
    %assign system.CurrentTID = -1
  %else
    %% sync tid
    %if !SLibIsMultiRateAndRateGrouping(system)
      %% non-rate grouping sync tid
      %assign system.CurrentTID = ""
      %if dontChkEmpty || ...
	!LibSystemFcnIsEmpty(system,fcnType) || ...
	(fcnType == "OutputUpdate" && LibSystemIsForceNonInline(system))
	%assign  fcnBody =  SLibGetBody%<fcnType>FcnCache(system)
	%<fcnBody>
      %endif
      %assign system.CurrentTID = -1
    %else
      %% rate grouping sync tid
      %foreach Tid = NumSynchronousSampleTimes
	%assign system.CurrentTID = Tid
	%if dontChkEmpty || ...
	  !LibSystemFcnIsEmptyForTID(system,fcnType) || ...
	  LibSystemIsForceNonInline(system)
	  %assign  fcnBody =  SLibGetBody%<fcnType>FcnCache(system)
	  %<fcnBody>
	%endif
	%assign system.CurrentTID = -1
      %endforeach
    %endif
  %endif
  %closefile retBuf

  %return retBuf
%endfunction %% SLibGetRateGroupedFcnBody


%% Function: SLibGetSystemFcnBodyCacheHelper ==================================
%% Abstract:
%%     Helper function for SLibGetSystemFcnBodyCache
%%
%function SLibGetSystemFcnBodyCacheHelper(system, needToDumpSysFcn)
  %assign isRoot       = (system.Type == "root")
  %assign dontChkEmpty = isRoot

  %openfile codeBuffer

  %<SLibGetSystemStateflowFcnCache(system)>

  %if needToDumpSysFcn
    %if ISFIELD(system,"InitializeFcn")
      %if !LibSystemFcnIsEmpty(system, "Initialize")
	%<SLibGetBodyInitializeFcnCache(system)>
      %endif
    %endif
    %% EnableFcn always exists
    %if ISFIELD(system,"EnableFcn")
      %if !LibSystemFcnIsEmpty(system,"Enable")
	%<SLibGetBodyEnableFcnCache(system)>
      %endif
    %endif
    %% DisableFcn always exists
    %if ISFIELD(system,"DisableFcn")
      %if !LibSystemFcnIsEmpty(system,"Disable")
	%<SLibGetBodyDisableFcnCache(system)>
      %endif
    %endif
    %% StartFcn always exists
    %if ISFIELD(system,"StartFcn")
      %if dontChkEmpty || !LibSystemFcnIsEmpty(system,"Start")
	%<SLibGetBodyStartFcnCache(system)>
      %endif
    %endif
    %if ISFIELD(system,"OutputFcn")
      %<SLibGetRateGroupedFcnBody(system, "Output", dontChkEmpty)>
    %endif
    %if ISFIELD(system,"UpdateFcn")
      %<SLibGetRateGroupedFcnBody(system, "Update", dontChkEmpty)>
    %endif
    %if ISFIELD(system,"DerivativeFcn") && (!isRoot || (NumContStates > 0))
      %if dontChkEmpty || !LibSystemFcnIsEmpty(system,"Derivative")
	%<SLibGetBodyDerivativeFcnCache(system)>
      %endif
    %endif
    %if ISFIELD(system,"ProjectionFcn") && (!isRoot || (NumContStates > 0))
      %if dontChkEmpty || !LibSystemFcnIsEmpty(system,"Projection")
	%<SLibGetBodyProjectionFcnCache(system)>
      %endif
    %endif
    %if ISFIELD(system,"ZeroCrossingFcn") && (!isRoot || (NumNonsampledZCs > 0))
      %if dontChkEmpty || !LibSystemFcnIsEmpty(system,"ZeroCrossing")
	%<SLibGetBodyZeroCrossingFcnCache(system)>
      %endif
    %endif
    %if ISFIELD(system,"OutputUpdateFcn")
      %<SLibGetRateGroupedFcnBody(system, "OutputUpdate", dontChkEmpty)>
    %endif
    %% TerminateFcn should always exist
    %if (!isRoot || !Accelerator) && ...
      (dontChkEmpty || !LibSystemFcnIsEmpty(system,"Terminate"))
      %<SLibGetBodyTerminateFcnCache(system)>
    %endif
    %%
    %% CheckParamsFcn for S-function target root
    %%
    %if (system.Type == "root") && (CodeFormat == "S-Function") && ...
      !Accelerator
      %assign rootSystem = System[NumSystems-1]
      %<SLibGetBodyCheckParamsFcnCache(rootSystem)>
    %endif
  %endif
  %closefile codeBuffer
  %return codeBuffer
%endfunction

%% Function: NotRootFileName ==================================================
%% Abstract:
%%    Return true if the code for this system does not go to model.c
%%
%function NotRootFileName(system)
  %assign isRoot = (system.Type == "root")
  %assign notRootFileName = 0
  %if !isRoot
    %assign rootFileName = GetRootSystemFileName()
    %assign notRootFileName = (system.SystemFileName != rootFileName)
  %endif
  %return notRootFileName
%endfunction

%% Function: SLibDumpGlobalVarDeclaration =====================================
%% Abstract:
%%     Dump global variable declration in the specified file.
%%
%function SLibDumpGlobalVarDeclaration(system, file) void
  %assign buf = LibDeclareGlobalVars(system,"")
  %if !WHITE_SPACE(buf)
    %openfile globalBuf

    /* Declare global variables for system: %<system.Name> */
    %<buf>\
    %closefile globalBuf
    %<SLibSetModelFileAttribute(file, "Declarations",globalBuf)>
  %endif
%endfunction


%% Function: SLibGetSystemBodyCache ============================================
%% Abstract:
%%   Get or dump the cached body for the specified system (including root).
%%
%function SLibGetSystemBodyCache(system)

  %if LibIsSystemDumped(system)
    %return ""
  %endif

  %assign needToDumpSysFcn =  ((LibIsSystemNonEmpty(system) || ...
    LibIsSystemTerminateNonEmpty(system) || ...
    LibSystemIsForceNonInline(system)) && ...
    !LibSystemIsInlined(system))

  %% We are in the process of updateing stateflow to marked the stateflow
  %% subsystem as "Function", if it is generating a function for the
  %% function call sybsystem. When all changes are in A, we can enable
  %% the following Assertion.
  %%
  %% %assert(SLibSystemStateflowFcnCacheIsEmpty(system) || needToDump)
  %%
  %% For now, stateflow may be inlined, therefore, we need to check
  %% the following:

  %assign  needToDump = !SLibSystemStateflowFcnCacheIsEmpty(system)|| ...
  needToDumpSysFcn

  %if !needToDump
    %<LibSetSystemField(system, "SystemDumped", TLC_TRUE)>
    %return ""
  %endif

  %assign codeBuffer = SLibGetSystemFcnBodyCacheHelper(system, needToDumpSysFcn)

  %%
  %% Comparing with CompiledModel.Name will not hold good for RTWSFCN/ACCEL
  %% But, its OK since we will not generate separate files for them
  %% Systems generating into model.c are handled by srtbody.tlc and dumped
  %% there directly
  %assign notRootFileName = NotRootFileName(system)

  %assign retBuf = ""

  %if notRootFileName
    %assign duplicate = LibAddToModelSources(system.SystemFileName)
    %assign fileName  = SLibGetSystemOutputFileName(system)
    %assign fileBaseName = SLibGetSystemOutputFileBaseName(system)
    %assign modelName = CompiledModel.Name
    %assign opFile    = SLibAddModelFile("SystemBody","Simulink",fileBaseName)
    %assign includeBuf = ""
    %assign bannerBuf  = ""

    %assign ::CompiledModel.HaveSeparateSourceFiles = 1

    %if !duplicate
      %assign fileOwnerSys = CompiledModel.System[system.FileNameOwnerIdx]

      %% If we are allowing nonreusable functions to live inside
      %% reusable functions, then handle all necessary extern
      %% global declarations in subsystem files.
      %if CompiledModel.AllowNoArgFcnInReusedFcn
        %<SLibGlobalFileHandling(fileOwnerSys, opFile)>
      %endif
      
      %openfile bannerBuf
      %% Dump comments, only if its the first time
      /*
      %<SLibSystemBanner(fileOwnerSys)>\
      *
      * Note that the functions contained in this file are part of a Simulink
      * model, and are not self-contained algorithms.
      */
      %closefile bannerBuf
      %openfile includeBuf

      #include "%<system.SystemFileName>.h"

      %if IsModelReferenceTarget()
        %if !IsModelReferenceBaseSys(system)
          /* Include model header file for global data */
          %assign fileName = SLibGetSystemOutputFileBaseName(System[NumSystems-2])
          #include "%<fileName>.h"
        %endif
      %else
	/* Include model header file for global data */
	#include "%<CompiledModel.Name>.h"
      %endif

      #include "%<CompiledModel.Name>_private.h"

      %closefile includeBuf
    %endif %% if !duplicate ... - comments dumped

    %<SLibSetModelFileAttribute(opFile, "Banner", bannerBuf)>
    %<SLibSetModelFileAttribute(opFile, "Includes", includeBuf)>
    %<SLibSetModelFileAttribute(opFile, "Functions", codeBuffer)>
    %<SLibDumpGlobalVarDeclaration(system, opFile)>
    %<LibSetSystemField(system, "SystemDumped", TLC_TRUE)>
    %% retBuf is ""
  %else %% dumping into root (model.c) or (model_acc.c)
    %assert !IsModelReferenceTarget()
    %assign rootFile = GetBaseFile("SystemBody")
    %<SLibDumpGlobalVarDeclaration(system, rootFile)>

    %openfile retBuf

    %<codeBuffer>\
    %closefile retBuf
  %endif %% if notRootFileName

  %return retBuf

%endfunction %% SLibGetSystemBodyCache


%% Function: SLibGetBodyInitializeFcnCache(ss) =================================
%% Description:
%%      Generates the initialize function for these system types.
%%        o enable (states reset)
%%        o enable with trigger (states reset)
%%
%function SLibGetBodyInitializeFcnCache(ss) void
  %openfile tmpBuffer
  %<LibDumpFcnOpen(ss,"Initialize")>\
  %<LibDumpSystemSSVars(ss,"Initialize")>\
  %<LibDumpSystemUserCode(ss,"Initialize","Header")>\
  %<LibDumpGlobalVars(ss, "Initialize")>\
  %<LibDumpFcnBegin(ss,"Initialize")>\
  %% XXX mje open code do we really need this?
  %<SLibDumpSubSystemOpenCode(ss, "Initialize")>\
  %<LibDumpSystemUserCode(ss,"Initialize","Body")>\
  %<LibDumpSystemFcn(ss,"Initialize")>\
  %<LibDumpSystemUserCode(ss,"Initialize","Trailer")>\
  %<LibDumpFcnClose(ss,"Initialize")>
  %closefile tmpBuffer
  %assign retBuffer = ""
  %if !WHITE_SPACE(tmpBuffer)
    %openfile retBuffer
    %<SLibGetFcnComment(ss,"Initial conditions")>\
    %<tmpBuffer>\
    %closefile retBuffer
  %endif
  %return retBuffer
%endfunction


%% Function: FcnLoadInitialState ===============================================
%% Abstract:
%%   Load Initial values for continuous and discrete states that are non-zero.
%%
%function FcnLoadInitialState() Output
  %%
  %% Continuous States
  %%
  %foreach csIdx = ContStates.NumContStates
    %assign cs = ContStates.ContState[csIdx]
    %assign ic = cs.InitialValue
    %if SIZE(ic,1) == 1 && ic[0] == 0.0
      %continue
    %endif
    %assign sgnl = SLibContinuousState(cs,"","",0,NumSystems-1)
    %assign addr = "&" + sgnl
    %if cs.Width == 1
      %<sgnl> = %<ic[0]>;
    %else
      {
	%assign comma = ""
	%assign varName = "rtcs%<csIdx>_%<cs.Identifier>"
	static const real_T %<varName>[%<cs.Width>] = {
	  %foreach idx = cs.Width
	    %<comma>%<ic[idx]>
	    %assign comma = ","
	  %endforeach
	};
	(void)memcpy(%<addr>, %<varName>, %<cs.Width>*sizeof(real_T));
      }
    %endif

  %endforeach
  %%
  %% Discrete States
  %%
  %foreach dwIdx = DWorks.NumDWorks
    %assign ds = DWorks.DWork[dwIdx]
    %assign ic = ds.InitialValue
    %if ISEMPTY(ic)
      %continue
    %endif
    %with System[NumSystems-1]
      %with System[ds.SigSrc[0]].Block[ds.SigSrc[2]]
	%assign sgnl = LibBlockDWork(ds,"","",0)
	%assign addr = LibBlockDWorkAddr(ds,"","",0)
      %endwith
    %endwith
    %if ds.Width == 1
      %<sgnl> = %<ic[0]>;
    %else
      {
	%assign comma = ""
	%assign varName = "rtds%<dwIdx>_%<ds.Identifier>"
	%assign dtype = SLibGetRecordDataTypeName(ds,"")
	static const %<dtype> %<varName>[%<ds.Width>] = {
	  %if ds.ComplexSignal == "yes"
	    %foreach idx = ds.Width
	      %<comma>{%<REAL(ic[idx])>, %<IMAG(ic[idx])>}
	      %assign comma = ","
	    %endforeach
	  %else
	    %foreach idx = ds.Width
	      %<comma>%<ic[idx]>
	      %assign comma = ","
	    %endforeach
	  %endif
	};
	(void)memcpy(%<addr>, %<varName>, %<ds.Width>*sizeof(%<dtype>));
      }
    %endif

  %endforeach
%endfunction %% FcnLoadInitialState


%% Function: SLibGetBodyStartFcnCache(ss) ======================================
%% Description:
%%      Generates the start function for systems
%%
%function SLibGetBodyStartFcnCache(ss) void
  %assign isRootInSfcn = (ss.Type == "root") && ...
    (CodeFormat == "S-Function") && !Accelerator

  %openfile tmpBuffer
  %<LibDumpFcnOpen(ss,"Start")>\
  %if isRootInSfcn
    %<LibDumpSfunTargetChecks()> \
    {
  %endif
  %<LibDumpSystemSSVars(ss,"Start")>\
  %<LibDumpSystemUserCode(ss,"Start","Header")>\
  %<LibDumpGlobalVars(ss, "Start")>\
  %<LibDumpFcnBegin(ss,"Start")>\
  %% open code
  %<SLibDumpSubSystemOpenCode(ss, "Start")>\
  %<LibDumpSystemUserCode(ss,"Start","Body")>\
  %<LibDumpSystemFcn(ss,"Start")>\
  %<LibDumpSystemUserCode(ss,"Start","Trailer")>\
  %%
  %% For some targets, we allow root to call Initialize and Enable
  %% within the context of start
  %%
  %if (ss.Type == "root")
    %if RootBodyStartCallsInitEnab
      %if (!LibSystemFcnIsEmpty(ss, "Initialize"))
	%assign fcnInfo = LibGetSystemField(ss, "Initialize" + "FcnInfo")
	%assign comArgs = fcnInfo.CommonArgs
	%<fcnInfo.Name>(%<comArgs>);
      %endif
      %if (!LibSystemFcnIsEmpty(ss, "Enable"))
	%assign fcnInfo = LibGetSystemField(ss, "Enable" + "FcnInfo")
	%assign comArgs = fcnInfo.CommonArgs
	%<fcnInfo.Name>(%<comArgs>);
      %endif
    %endif
    %% Load intial states if needed.
    %<FncGenInitStatesInRootStart()>
  %endif
  %if isRootInSfcn
    }
  %endif
  %% close code
  %<SLibDumpSubSystemCloseCode(ss, "Start")>\
  %<LibDumpFcnClose(ss,"Start")>
  %closefile tmpBuffer
  %assign retBuffer = ""
  %if !WHITE_SPACE(tmpBuffer)
    %openfile retBuffer
    %<SLibGetFcnComment(ss,"Start")>\
    %<tmpBuffer>\
    %closefile retBuffer
  %endif
  %return retBuffer
%endfunction

%% Function: SLibGetRateGroupSysFieldForAsyncTopSS =====
%% Abstract:
%%   Rate grouped fields of each async tid are cached
%%  to rootSS fields during code generation.
%%   This function get asycn field of rootSS, and set it to the
%%  async filed of current ss. This function only can be
%%  called by the topSS of the async tid.
%%   When dump code for this async subsystem later, code
%%  contains all code belong to this async tid.
%%
%function SLibGetRateGroupSysFieldForAsyncTopSS(ss, tid,fcnType) void

  %assign rootSS = System[NumSystems-1]
  %assign tmpCurrentTID = rootSS.CurrentTID 
  %assign rootSS.CurrentTID = tid

  %if fcnType == "Output" || fcnType == "OutputUpdate"
    %assign tmpFieldName = "Cached%<fcnType>%<tid>LocalBO"
    %assign tmpBuf1       = LibGetSystemField(rootSS, tmpFieldName)
    %assign tmpBuf2       = LibGetSystemField(ss, tmpFieldName)
    %<LibSetSystemField(ss, tmpFieldName, tmpBuf1+tmpBuf2)>
  %endif
  
  %assign tmpFieldName = "Cached%<fcnType>%<tid>GlobalVars"
  %assign tmpBuf1       = LibGetSystemField(rootSS, tmpFieldName)
  %assign tmpBuf2       = LibGetSystemField(ss, tmpFieldName)
  %<LibAddToSystemField(ss, tmpFieldName, tmpBuf1+tmpBuf2)>
  %<LibSetSystemField(rootSS, tmpFieldName, "")>

  %if fcnType == "Output" || fcnType == "OutputUpdate"
    %assign tmpBuf      = LibGetSystemField(rootSS, "CachedOutput%<tid>Fcn")
    %<LibSetSystemField(ss,  "CachedOutput%<tid>Fcn", tmpBuf)>
  %endif

  %if fcnType == "Update" || fcnType == "OutputUpdate"
    %assign tmpBuf        = LibGetSystemField(rootSS, "CachedUpdate%<tid>Fcn")
    %<LibSetSystemField(ss, "CachedUpdate%<tid>Fcn", tmpBuf)>
  %endif

  %assign rootSS.CurrentTID = tmpCurrentTID
  %% System field %<fcnType>FncInfo
  %% might need be combined
  %% too, especially fcnInfo.Open
  %% xxx byu
  %%
  %return
%endfunction

%% Function: SLibGetBodyOutputFcnCache(ss) =====================================
%% Description:
%%      Generates the output function for an enable subsystem.
%%
%function SLibGetBodyOutputFcnCache(ss) void
  %if SLibIsMultiRateAndRateGrouping(ss) || ...
    LibAsynchronousTriggeredTID(ss.CurrentTID)
    %assign tid = ss.CurrentTID
  %else
    %assign tid = ""
  %endif

  %if !SLibIsRateGrouping()
    %% If not grouping rating, system output
    %% fcn always exists
    %assign systemFcnIsEmpty = TLC_FALSE
  %else
    %assign systemFcnIsEmpty = LibSystemFcnIsEmptyForTID(ss, "Output")
  %endif

  %% System is an asycn TopSS
  %if FcnSubsystemIsAsycnTopSS(ss)
    %<SLibGetRateGroupSysFieldForAsyncTopSS(ss, tid, "Output")>
  %endif


  %assign mdlRefTimingOutput = ""
  %if IsModelReferenceBaseSys(ss)
    %% Create and initialize it here. It may be updated at the end
    %% of the function
    %addtorecord ss ModelRefOutputFcnIsEmpty%<tid> "yes"

    %assign mdlRefTimingOutput = ErtOrModelrefGetTimingForTopOfOutputFcn(ss, tid)
        
    %if !WHITE_SPACE(mdlRefTimingOutput)
      %assign systemFcnIsEmpty = TLC_FALSE
    %endif
  %endif

  %if systemFcnIsEmpty
    %return
  %endif

  %openfile tmpBuffer
  %<LibDumpFcnOpen(ss,"Output")>\
  %% Profiler declaration code
  %<LibDumpSystemProfileCode(ss,"Output", "Decls")>\
  %<LibDumpSystemSSVars(ss,"Output")>\
  %<LibDumpSystemLocalBO(ss,"Output%<tid>")>\
  %<LibDumpSystemUserCode(ss,"Output","Header")>\
  %<LibDumpGlobalVars(ss, "Output%<tid>")>\
  %if (ss.Type == "root") && RootBodyTIDneeded && LibIsSingleRateSystem(ss)
    /* %<tTID> is required for a uniform function interface. This system
     * is single rate, and in this case, %<tTID> is not accessed. */
     UNUSED_PARAMETER(%<tTID>);

  %endif
  %<LibDumpFcnBegin(ss,"Output")>\
  
  %% Profiler start code
  %<LibDumpSystemProfileCode(ss,"Output", "Start")>\

  %% open code
  %<SLibDumpSubSystemOpenCode(ss, "Output%<tid>")>\

  %% When we are generating for model reference, write out
  %% part of the ERT timing Engine.
  %% output code
  %<mdlRefTimingOutput>
  %<LibDumpSystemUserCode(ss,"Output","Body")>\
  %if Accelerator && LibIsSystemField(ss, "FcnCallSubsystemPtrs")
    %<LibGetSystemField(ss, "FcnCallSubsystemPtrs")>\
  %endif

  %<LibDumpSystemFcn(ss,"Output%<tid>")>\
  %<LibDumpSystemUserCode(ss,"Output","Trailer")>\

  %% close code
  %<SLibDumpSubSystemCloseCode(ss, "Output%<tid>")>\

  %% Profiler finish code
  %<LibDumpSystemProfileCode(ss,"Output", "End")>\

  %<LibDumpFcnClose(ss,"Output")>
  %closefile tmpBuffer
  %assign retBuffer = ""
  %if !WHITE_SPACE(tmpBuffer)
    %openfile retBuffer
    %<SLibGetFcnComment(ss,"Outputs")>\
    %<tmpBuffer>\
    %closefile retBuffer

    %if IsModelReferenceBaseSys(ss)
      %assign ss.ModelRefOutputFcnIsEmpty%<tid> = "no"
    %endif

  %endif

  %return retBuffer
%endfunction %% SLibGetBodyOutputFcnCache

%% Function: SLibGetBodyUpdateFcnCache(ss) =====================================
%% Description:
%%      Generates the update function for an enable subsystem.
%%
%function SLibGetBodyUpdateFcnCache(ss) void
  %if SLibIsMultiRateAndRateGrouping(ss) || ...
    LibAsynchronousTriggeredTID(ss.CurrentTID)
    %assign tid = ss.CurrentTID
  %else
    %assign tid = ""
  %endif

  %if FcnSubsystemIsAsycnTopSS(ss)
    %<SLibGetRateGroupSysFieldForAsyncTopSS(ss, tid, "Update")>
  %endif

  %assign mdlRefTimingUpdate = ""
  %assign solverResetBuffer  = ""
  %if IsModelReferenceBaseSys(ss)
    %addtorecord ss ModelRefUpdateFcnIsEmpty%<tid> "yes"

    %if !::ModelReferenceTargetWithGlobalTiming
      %assign mdlRefTimingUpdate = ErtOrModelrefGetTimingForBottomOfUpdateFcn(ss,tid, TLC_TRUE)
    %endif
    %% Create and initialize it to "no"
  %endif


  %openfile tmpBuffer
  %<LibDumpFcnOpen(ss,"Update")>\
  %% Profiler declaration code
  %<LibDumpSystemProfileCode(ss,"Update", "Decls")>\

  %<LibDumpSystemSSVars(ss,"Update")>\
  %<LibDumpSystemUserCode(ss,"Update","Header")>\
  %<LibDumpGlobalVars(ss, "Update%<tid>")>\
  %if (ss.Type == "root") && RootBodyTIDneeded && LibIsSingleRateSystem(ss)
    /* %<tTID> is required for a uniform function interface. This system
     * is single rate, and in this case, %<tTID> is not accessed. */
     UNUSED_PARAMETER(%<tTID>);

  %endif
  %<LibDumpFcnBegin(ss,"Update")>\

  %% Profiler start code
  %<LibDumpSystemProfileCode(ss,"Update", "Start")>\

  %% open code
  %<SLibDumpSubSystemOpenCode(ss, "Update%<tid>")>\
 
  %<LibDumpSystemUserCode(ss,"Update","Body")>\
  %<LibDumpSystemFcn(ss,"Update%<tid>")>\
  %<LibDumpSystemUserCode(ss,"Update","Trailer")>\
  %<mdlRefTimingUpdate>
  %<solverResetBuffer>

  %% close code
  %<SLibDumpSubSystemCloseCode(ss, "Update%<tid>")>\

  %% Profiler finish code
  %<LibDumpSystemProfileCode(ss,"Update", "End")>\

  %<LibDumpFcnClose(ss,"Update")>
  %closefile tmpBuffer
  %assign retBuffer = ""
  %if !WHITE_SPACE(tmpBuffer)
    %openfile retBuffer
    %<SLibGetFcnComment(ss,"Update")>\
    %<tmpBuffer>\
    %closefile retBuffer
    %if IsModelReferenceBaseSys(ss)
      %assign ss.ModelRefUpdateFcnIsEmpty%<tid> = "no"
    %endif
  %endif
  %return retBuffer
%endfunction  %%SLibGetBodyUpdateFcnCache

%% Function: SLibGetBodyDerivativeFcnCache(ss) =================================
%% Description:
%%      Generates the derivatives function for an enable system containing
%%      continuous states.  Note that DerivativeFcn only exists if the
%%      system has continuous states.
%%
%function SLibGetBodyDerivativeFcnCache(ss) void
  %openfile tmpBuffer
  %if (CodeFormat == "Embedded-C") && LibSystemIsRoot(ss)
    %assign fcnRec = LibGetSystemField(ss, "DerivativeFcnInfo")
    void %<fcnRec.Name>(%<SLibModelFcnArgs("Derivative",0,"")>)
    {
  %else
    %<LibDumpFcnOpen(ss,"Derivative")>\
  %endif
  %<LibDumpSystemSSVars(ss,"Derivative")>\
  %<LibDumpSystemUserCode(ss,"Derivative","Header")>\
  %<LibDumpGlobalVars(ss, "Derivative")>\
  %<LibDumpFcnBegin(ss,"Derivative")>\
  %% open code
  %<SLibDumpSubSystemOpenCode(ss, "Derivative")>\
  %<LibDumpSystemUserCode(ss,"Derivative","Body")>\
  %<LibDumpSystemFcn(ss,"Derivative")>\
  %<LibDumpSystemUserCode(ss,"Derivative","Trailer")>\
  %% close code
  %<SLibDumpSubSystemCloseCode(ss, "Derivative")>\
  %<LibDumpFcnClose(ss,"Derivative")>
  %closefile tmpBuffer
  %assign retBuffer = ""
  %if !WHITE_SPACE(tmpBuffer)
    %openfile retBuffer
    %<SLibGetFcnComment(ss,"Derivatives")>\
    %<tmpBuffer>\
    %closefile retBuffer
  %endif
  %return retBuffer
%endfunction


%% Function: SLibGetBodyProjectionFcnCache(ss) =================================
%% Description:
%%      Generates the projection function for an enable system containing
%%      continuous states.  Note that ProjectionFcn only exists if the
%%      system has continuous states.
%%
%function SLibGetBodyProjectionFcnCache(ss) void
  %assign tmpBuffer = ""
  %if CodeFormat == "S-Function" && ModelHasProjections == "yes" || ...
      CodeFormat != "S-Function"
    %openfile tmpBuffer
    %<LibDumpFcnOpen(ss,"Projection")>\
    %<LibDumpSystemSSVars(ss,"Projection")>\
    %<LibDumpSystemUserCode(ss,"Projection","Header")>\
    %<LibDumpGlobalVars(ss, "Projection")>\
    %<LibDumpFcnBegin(ss,"Projection")>\
    %% open code
    %<SLibDumpSubSystemOpenCode(ss, "Projection")>\
    %<LibDumpSystemUserCode(ss,"Projection","Body")>\
    %<LibDumpSystemFcn(ss,"Projection")>\
    %<LibDumpSystemUserCode(ss,"Projection","Trailer")>\
    %% close code
    %<SLibDumpSubSystemCloseCode(ss, "Projection")>\
    %<LibDumpFcnClose(ss,"Projection")>
    %closefile tmpBuffer
  %endif
  %assign retBuffer = ""
  %if !WHITE_SPACE(tmpBuffer)
    %openfile retBuffer

    %<SLibGetFcnComment(ss,"Projection")>\
    %<tmpBuffer>\
    %closefile retBuffer
  %endif
  %return retBuffer
%endfunction


%% Function: SLibGetBodyZeroCrossingFcnCache(ss) ===============================
%% Description:
%%      Generates the ZeroCrossings function for an enable/atomic system
%%      containing continuous states.
%%
%function SLibGetBodyZeroCrossingFcnCache(ss) void
  %openfile tmpBuffer
  %<LibDumpFcnOpen(ss,"ZeroCrossing")>\
  %<LibDumpSystemSSVars(ss,"ZeroCrossing")>\
  %<LibDumpSystemUserCode(ss,"ZeroCrossing","Header")>\
  %<LibDumpGlobalVars(ss, "ZeroCrossing")>\
  %<LibDumpFcnBegin(ss,"ZeroCrossing")>\
  %% open code
  %<SLibDumpSubSystemOpenCode(ss, "ZeroCrossing")>\
  %<LibDumpSystemUserCode(ss,"ZeroCrossing","Body")>\
  %<LibDumpSystemFcn(ss,"ZeroCrossing")>\
  %<LibDumpSystemUserCode(ss,"ZeroCrossing","Trailer")>\
  %% close code
  %<SLibDumpSubSystemCloseCode(ss, "ZeroCrossing")>\
  %<LibDumpFcnClose(ss,"ZeroCrossing")>
  %closefile tmpBuffer
  %assign retBuffer = ""
  %if !WHITE_SPACE(tmpBuffer)
    %openfile retBuffer
    %<SLibGetFcnComment(ss,"ZeroCrossings")>\
    %<tmpBuffer>\
    %closefile retBuffer
  %endif
  %return retBuffer
%endfunction


%% Function: SLibGetBodyEnableFcnCache(ss) =====================================
%% Description:
%%      Generates the enable function for these system types.
%%        o enable
%%        o enable with trigger
%%
%function SLibGetBodyEnableFcnCache(ss) void
  %openfile tmpBuffer
  %<LibDumpFcnOpen(ss,"Enable")>\
  %<LibDumpSystemSSVars(ss,"Enable")>\
  %<LibDumpSystemUserCode(ss,"Enable","Header")>\
  %<LibDumpGlobalVars(ss, "Enable")>\
  %<LibDumpFcnBegin(ss,"Enable")>\
  %<LibDumpSystemUserCode(ss,"Enable","Body")>\
  %<LibDumpSystemFcn(ss,"Enable")>\
  %<LibDumpSystemUserCode(ss,"Enable","Trailer")>\
  %<LibDumpFcnClose(ss,"Enable")>
  %closefile tmpBuffer
  %assign retBuffer = ""
  %if !WHITE_SPACE(tmpBuffer)
    %openfile retBuffer
    %<SLibGetFcnComment(ss,"Enable")>\
    %<tmpBuffer>\
    %closefile retBuffer
  %endif
  %return retBuffer
%endfunction


%% Function: SLibGetBodyDisableFcnCache(ss) ====================================
%% Description:
%%      Generates the disable function for these system types.
%%        o enable
%%        o enable with trigger
%%
%function SLibGetBodyDisableFcnCache(ss) void
  %openfile tmpBuffer
  %<LibDumpFcnOpen(ss,"Disable")>\
  %<LibDumpSystemSSVars(ss,"Disable")>\
  %<LibDumpSystemUserCode(ss,"Disable","Header")>\
  %<LibDumpGlobalVars(ss, "Disable")>\
  %<LibDumpFcnBegin(ss,"Disable")>\
  %% open code
  %<SLibDumpSubSystemOpenCode(ss, "Disable")>\
  %% disable code
  %<LibDumpSystemUserCode(ss,"Disable","Body")>\
  %<LibDumpSystemFcn(ss,"Disable")>\
  %<LibDumpSystemUserCode(ss,"Disable","Trailer")>\
  %% close code
  %<SLibDumpSubSystemCloseCode(ss, "Disable")>\
  %<LibDumpFcnClose(ss,"Disable")>
  %closefile tmpBuffer
  %assign retBuffer = ""
  %if !WHITE_SPACE(tmpBuffer)
    %openfile retBuffer
    %<SLibGetFcnComment(ss,"Disable")>\
    %<tmpBuffer>\
    %closefile retBuffer
  %endif
  %return retBuffer
%endfunction


%% Function: SLibGetFcnComment(ss, fcn) =======================================
%% Description:
%%    Return comment for each function type. If the system is reused the comment
%%    includes the first 10(11) instances of the reused system.
%%
%function SLibGetFcnComment(ss, fcn) void
  %assign needBlkDsc = (InsertBlockDesc && (ss.Type != "root") && ...
    !ss.DescInCallSite && ( fcn == "Output and update" || fcn == "Outputs"))

  %openfile retBuffer
  %if ss.Type == "atomic" && ss.CalledByBlock == "yes"
%% do not return any thing
  %elseif (ss.Type == "root")

    /* %<fcn> for %<ss.Type> system: '%<ss.Name>' */
  %elseif IsModelReferenceBaseSys(ss)

    /* %<fcn> for referenced model: '%<CompiledModel.Name>'*/
  %else
    %assign cs    = ss.CallSites
    %assign numCs = SIZE(cs, 0)
    %assert (numCs > 0)
    %assign retOneBlk = (numCs == 1 || LibSystemIsInlined(ss))
    %if retOneBlk
      %assign blkName = SLibGrBlockName(ss.GraphCallSites[0])
      %assign thisCs  = cs[0]
      %assign thisBlk = System[thisCs[2]].Block[thisCs[3]]
      %if LibSystemIsInlined(ss) && ISFIELD(thisBlk, "MaskType") && ...
        thisBlk.MaskType == "Stateflow"
	%if needBlkDsc && SIZE(thisBlk.Description,1) > 0

	  /* Chart description for: '%<blkName>'
	  %<FcnGetBlockDescription(thisBlk)>
	  */
	%endif
      %elseif needBlkDsc && SIZE(thisBlk.Description,1) > 0

	/* %<fcn> for %<ss.Type> system: '%<blkName>'
	%<FcnGetBlockDescription(thisBlk)>
	*/
      %else

/* %<fcn> for %<ss.Type> system: '%<blkName>' */
      %endif
    %else

      /* %<fcn> for %<ss.Type> system:
      %assign max = 10
      %assign num = (numCs > max+1) ? max : numCs
      %foreach cIdx = num
	%assign blkName = SLibGrBlockName(ss.GraphCallSites[cIdx])
	*   '%<blkName>'
      %endforeach
      %if numCs > num
	%assign etc = "..."
	*   %<etc>
      %endif
      %if needBlkDsc
	%% we assume all callsites use the same description if they ever
	%% come to this point; so we will just pick the first one
	%assign thisCs = cs[0]
	%assign thisBlk = System[thisCs[2]].Block[thisCs[3]]
	%if SIZE(thisBlk.Description,1) > 0
	  %assert(!ISFIELD(thisBlk,"DescriptionWritten"))
	  *
	  * Common description for the above blocks:
	  %<thisBlk.Description>
	%endif
      %endif
      */
    %endif
  %endif
  %closefile retBuffer
  %return retBuffer
%endfunction


%% Function: SLibGetBodyOutputUpdateFcnCache(ss) ===============================
%% Description:
%%      Generates the output/update function for systems that have output
%%      and update combined into one function.
%%      Note: a function-call is generated even if it is empty.
%%
%function SLibGetBodyOutputUpdateFcnCache(ss) void
  %if SLibIsMultiRateAndRateGrouping(ss) || ...
    LibAsynchronousTriggeredTID(ss.CurrentTID)
    %assign tid = ss.CurrentTID
  %else
    %assign tid = ""
  %endif

  %assign systemFcnIsEmpty = LibSystemFcnIsEmptyForTID(ss, "OutputUpdate")

  %if FcnSubsystemIsAsycnTopSS(ss)
    %<SLibGetRateGroupSysFieldForAsyncTopSS(ss, tid, "OutputUpdate")>
  %endif

  %assign mdlRefTimingOutput = ""
  %assign mdlRefTimingUpdate = ""
  %if IsModelReferenceBaseSys(ss)
    %% Create this field and initialize it to "no"
    %% This will be updated at the end of function
    %addtorecord ss ModelRefOutputUpdateFcnIsEmpty%<tid> "yes"

    %assign mdlRefTimingOutput = ErtOrModelrefGetTimingForTopOfOutputFcn(ss, tid)
    %if !::ModelReferenceTargetWithGlobalTiming
      %assign mdlRefTimingUpdate = ErtOrModelrefGetTimingForBottomOfUpdateFcn(ss,tid, TLC_FALSE)
    %endif
    
    %if !WHITE_SPACE(mdlRefTimingOutput) || !WHITE_SPACE(mdlRefTimingUpdate)
      %assign systemFcnIsEmpty = TLC_FALSE
    %endif
  %endif

  %if systemFcnIsEmpty && SLibIsRateGrouping()
    %% if not rate grouping, outputupdate
    %% fcn always exists.
    %return
  %endif
  %openfile tmpBuffer
  %% open
  %<LibDumpFcnOpen(ss,"OutputUpdate")>\
  %% Profiler declaration code
  %<LibDumpSystemProfileCode(ss,"OutputUpdate", "Decls")>\
  %% output declarations
  %<LibDumpSystemSSVars(ss,"OutputUpdate")>\
  %<LibDumpSystemLocalBO(ss,"OutputUpdate%<tid>")>\
  %<LibDumpSystemUserCode(ss,"Output","Header")>\
  %<LibDumpGlobalVars(ss, "OutputUpdate%<tid>")>\
  %<LibDumpFcnBegin(ss,"OutputUpdate")>\
  %% Profiler start code
  %<LibDumpSystemProfileCode(ss,"OutputUpdate", "Start")>\
  %% open code
  %<SLibDumpSubSystemOpenCode(ss, "OutputUpdate%<tid>")>\
  %% When we are generating for model reference, write out
  %% part of the ERT timing Engine.
  %assign mdlrefSys = IsModelReferenceBaseSys(ss)
  %<mdlRefTimingOutput>
  %% output code
  %<LibDumpSystemUserCode(ss,"Output","Body")>\
  %<LibDumpSystemFcn(ss,"Output%<tid>")>\
  %<LibDumpSystemUserCode(ss,"Output","Trailer")>\
  %% update declarations
  %assign needBrace = !LibSystemUserCodeIsEmpty(ss,"Update","Header")
  %if needBrace
    {
    %<LibDumpSystemUserCode(ss,"Update","Header")>\
    \
  %endif
  %% update code
  %<LibDumpSystemUserCode(ss,"Update","Body")>\
  %<LibDumpSystemFcn(ss,"Update%<tid>")>\
  %<LibDumpSystemUserCode(ss,"Update","Trailer")>\
  %if needBrace
    }
  %endif
  %<mdlRefTimingUpdate>

  %% close code
  %<SLibDumpSubSystemCloseCode(ss, "OutputUpdate%<tid>")>\
  
  %% Profiler finish code
  %<LibDumpSystemProfileCode(ss,"OutputUpdate", "End")>\

  %<LibDumpFcnClose(ss,"OutputUpdate")>
  %closefile tmpBuffer
  %assign retBuffer = ""
  %openfile retBuffer
  %if !WHITE_SPACE(tmpBuffer)

    %<SLibGetFcnComment(ss,"Output and update")>\
    %<tmpBuffer>\
  %endif

  %<SLibGenerateFNIStubs(ss)>\
  %<SLibGenerateISRStubs(ss)>\
  %closefile retBuffer
  %if IsModelReferenceBaseSys(ss)
    %assign ss.ModelRefOutputUpdateFcnIsEmpty%<tid> = "no"
  %endif
  %return retBuffer
%endfunction


%% Function: SLibGetBodyTerminateFcnCache(ss) ==================================
%% Description:
%%      Generates the terminate function for systems
%%
%function SLibGetBodyTerminateFcnCache(ss) void
  %% We need to change the BlockFcn to terminate because the
  %% rtModel is accessed here.  This currently does not cause
  %% any problems, but it would make the Interface record incorrect.
  %assign oldBlockFcn = ::BlockFcn
  %assign ::BlockFcn = "Terminate"
  %assign isRoot = (ss.Type == "root")
  %%
  %openfile tmpBuffer
  %<LibDumpFcnOpen(ss,"Terminate")>\
  %if isRoot
    %<LibDumpSystemProfileCode(ss, "Terminate", "End")>
  %endif
  %<LibDumpSystemSSVars(ss,"Terminate")>\
  %<LibDumpSystemUserCode(ss,"Terminate","Header")>\
  %<LibDumpGlobalVars(ss, "Terminate")>\
  %<LibDumpFcnBegin(ss,"Terminate")>\
  %<LibDumpSystemUserCode(ss,"Terminate","Body")>\
  %<LibDumpSystemFcn(ss,"Terminate")>\
  %if isRoot && UsingMalloc
    %<SLibGenRootTermMemFreeCode()>\
  %endif
  %<LibDumpSystemUserCode(ss,"Terminate","Trailer")>\
  %<LibDumpFcnClose(ss,"Terminate")>
  %closefile tmpBuffer
  %assign retBuffer = ""
  %if !WHITE_SPACE(tmpBuffer)
    %openfile retBuffer

    %<SLibGetFcnComment(ss,"Terminate")>\
    %<tmpBuffer>\
    %closefile retBuffer
  %endif
  %assign ::BlockFcn = oldBlockFcn
  %return retBuffer
%endfunction %% SLibGetBodyTerminateFcnCache


%% Function: LibDumpSystemFcn(system,fcn) ======================================
%% Description:
%%      Outputs the cached contents of the specified function for a system.
%%
%function LibDumpSystemFcn(system,fcn) Output
  %assign tempFcnName = "Cached" + fcn + "Fcn"
  %assign code = LibGetSystemField(system, tempFcnName)
  %if code != "/* rate grouped */"
    %% don't dump this comment line
    %% is comment line is only used
    %% to indicate the code is not
    %% empty, is rate grouped
    %<LibTrapCacheAssert(code)>\
    %<code>\
  %endif
%endfunction %% LibDumpSystemFcn


%% Function: LibDumpSystemSSVars(system,fcn) ===================================
%% Description:
%%      Outputs the cached simstruct variables that are needed by the function.
%%
%function LibDumpSystemSSVars(system,fcn) Output
  %assign tempSSVarsName  = "Cached" + fcn + "SSVars"
  %assign code = LibGetSystemField(system, tempSSVarsName)
  %<code>\
%endfunction %% LibDumpSystemSSVars

%% Function: LibDumpSystemProfileCode(system,fcn, part) =========================
%% Description:
%%      Outputs the cached profile code
%%      fcn:  terminate, output, update, outputupdate
%%      part: ProfileDecls, ProfileStart, ProfileEnd
%%
%function LibDumpSystemProfileCode(system,fcn, part) Output
  %assign tempProfile  = "Cached" + fcn + "Profile"+ part + "Code"
  %assign code = LibGetSystemField(system, tempProfile)
  %<code>\
%endfunction %% LibDumpSystemProfileCode



%% Function: LibDumpSystemLocalBO(system,fcn) ==================================
%% Description:
%%      Outputs the cached local block output variables that are needed by the
%%      function.
%%
%function LibDumpSystemLocalBO(system,fcn) Output
  %assign tempLocalBOName = "Cached" + fcn + "LocalBO"
  %if LibIsSystemField(system, tempLocalBOName)
    %assign code = LibGetSystemField(system, tempLocalBOName)
    %if code != "/* rate grouped */"
      %% don't dump this comment line
      %% is comment line is only used
      %% to indicate the code is not
      %% empty, is rate grouped
      %<code>\
    %endif
  %endif
%endfunction %% LibDumpSystemLocalBO


%% Function: LibSystemFcnNeedsTID(system,fcn) ==================================
%% Description:
%%      returns TLC_TRUE if the system function needs TID passed in,
%%      else returns TLC_FALSE
%%
%function LibSystemFcnNeedsTID(system,fcn) void
  %if fcn == "Output"       || fcn == "Update" || fcn == "RootUpdate" || ...
      fcn == "OutputUpdate" || fcn == "UpdateContStates"
    %if fcn == "Update" || fcn == "RootUpdate"
      %return LibGetSystemField(system, "NeedTIDInUpdate")
    %elseif fcn == "Output"
      %return LibGetSystemField(system, "NeedTIDInOutput") || ...
        LibGetSystemField(system, "NeedTIDInOutputUpdate")
    %else
      %return LibGetSystemField(system, "NeedTIDInOutput") || ...
        LibGetSystemField(system, "NeedTIDInOutputUpdate") ||...
        LibGetSystemField(system, "NeedTIDInUpdate")
    %endif
  %else
    %return TLC_FALSE
  %endif
%endfunction %% LibSystemFcnNeedsTID


%% Function: LibSystemFcnNeedsCPI(system,fcn) ==================================
%% Description:
%%      returns TLC_TRUE if the system function needs CPI (Control Port Index)
%%      passed in, else returns TLC_FALSE
%%
%function LibSystemFcnNeedsCPI(system,fcn) void
  %if fcn == "OutputUpdate"
    %assign tempName = "NeedCPIIn" + fcn
    %return LibGetSystemField(system, tempName)
  %else
    %return TLC_FALSE
  %endif
%endfunction %% LibSystemFcnNeedsCPI


%function LibSystemFcnIsEmptyHelper(system, fcn, tid)
  %% Output may have been combined with update
  %if fcn == "Output" && !ISFIELD(system,"OutputFcn") &&  ...
      !(ISFIELD(system,"OutputCalledInUpdate") &&  ...
      system.OutputCalledInUpdate == "yes")
    %assign fcn = "OutputUpdate"
  %endif

  %if fcn != "Output" && fcn != "Update" && fcn != "OutputUpdate"
    %% fcn other than "output", "Update" and 
    %% "OutputUpdate" is not rate grouped.
    %assign tid = ""
  %endif   

  %if !ISFIELD(system,"%<fcn>Fcn") && system.Type != "root"
    %return TLC_TRUE
  %endif
  %if fcn == "OutputUpdate"    
    %if system.DeletedInIR
      %return TLC_TRUE
    %endif
    %assign userCodeIsEmpty = ...
      WHITE_SPACE(LibGetSystemField(system, "OutputHeader" )) && ...
      WHITE_SPACE(LibGetSystemField(system, "OutputBody"   )) && ...
      WHITE_SPACE(LibGetSystemField(system, "OutputTrailer")) && ...
      WHITE_SPACE(LibGetSystemField(system, "UpdateHeader" )) && ...
      WHITE_SPACE(LibGetSystemField(system, "UpdateBody"   )) && ...
      WHITE_SPACE(LibGetSystemField(system, "UpdateTrailer"))
    %assign rtwCode = LibGetSystemField(system, "CachedOutput%<tid>Fcn") + ...
      LibGetSystemField(system, "CachedUpdate%<tid>Fcn")
  %elseif fcn == "Output" && system.DeletedInIR
    %return TLC_TRUE
  %else
    %assign userCodeIsEmpty = ...
      WHITE_SPACE(LibGetSystemField(system, "%<fcn>Header" )) && ...
      WHITE_SPACE(LibGetSystemField(system, "%<fcn>Body"   )) && ...
      WHITE_SPACE(LibGetSystemField(system, "%<fcn>Trailer"))
    %assign rtwCode = LibGetSystemField(system, "Cached%<fcn>%<tid>Fcn")
  %endif
  
  %assign ssCodeIsEmpty = ...
    WHITE_SPACE(LibGetSystemField(system, "Cached%<fcn>%<tid>OpenCode")) && ...
    WHITE_SPACE(LibGetSystemField(system, "Cached%<fcn>%<tid>CloseCode"))

  %if ISEQUAL(tid, "")
    %assign ssCodeIsEmpty = ssCodeIsEmpty && ...
      WHITE_SPACE(LibGetSystemField(system, "Cached%<fcn>ProfileDeclsCode")) &&...
      WHITE_SPACE(LibGetSystemField(system, "Cached%<fcn>ProfileStartCode")) &&...
      WHITE_SPACE(LibGetSystemField(system, "Cached%<fcn>ProfileEndCode"))
 %endif
 
 %assign rtwCodeIsEmpty = WHITE_SPACE(rtwCode)
 %if TYPE(tid) == "Number" 
   %assert tid >= 0
   %% userCode is not rate grouped, when check if code for specific tid 
   %% is empty, should not include user code unless the tid equal to
   %% the tid of subsystem tid
   %assign ssTid = LibSystemIsReusedFcn(system) ? ...
     FcnGetReusedSubsystemCodeTID(system) :  FcnGetSubsystemTID(system)
   %if !ISEQUAL(tid, ssTid)
     %assign userCodeIsEmpty = TLC_TRUE
   %endif
 %endif
 
 %<LibTrapCacheAssert(rtwCode)>

  %if (fcn == "Update" && !ISEQUAL(tid, ""))
    %assign isEmpty = (rtwCodeIsEmpty && userCodeIsEmpty)
  %else
    %assign isEmpty= (rtwCodeIsEmpty && userCodeIsEmpty && ssCodeIsEmpty)
  %endif

  %if isEmpty == TLC_TRUE &&  ...
    IsModelReferenceBaseSys(system) && ...
    (fcn == "Output" || fcn == "Update" || fcn == "OutputUpdate")

    %if ISFIELD(system, "ModelRef%<fcn>FcnIsNotEmpty%<tid>")
      %% The code has already been dumped
      %assign isEmpty = ISEQUAL(system.ModelRef%<fcn>FcnIsEmpty%<tid>, "yes")
    %else
      %% Assume it is not empty
      %assign isEmpty = TLC_FALSE
    %endif

  %endif

  %return isEmpty
%endfunction %%LibSystemFcnIsEmptyHelper

%% Function: LibSystemFcnIsEmpty(system,fcn) ===================================
%% Description:
%%      Function that returns TLC_FALSE if the system contains cached code for
%%      the specified function name.
%%
%function LibSystemFcnIsEmpty(system,fcn) void
  %assign isEmpty = LibSystemFcnIsEmptyHelper(system, fcn, "")
  %if fcn == "Output" || fcn == "Update" || fcn == "OutputUpdate"
    %foreach tid = NumSampleTimes
      %assign isEmpty = isEmpty && LibSystemFcnIsEmptyHelper(system, fcn, tid)
    %endforeach
  %endif 

  %return isEmpty
%endfunction %% LibSystemFcnIsEmpty(system,fcn)

%% Function: LibSystemFcnIsEmptyForTID(system,fcn) ===================================
%% Description:
%%      Function that returns TLC_FALSE if the system contains cached code for
%%      the specified function name of specific Tid.
%%
%function LibSystemFcnIsEmptyForTID(system,fcn) void
   %assign tid = SLibIsMultiRateAndRateGrouping(system) ||...
    LibAsynchronousTriggeredTID(system.CurrentTID) ? system.CurrentTID : ""
  
  %assign isEmpty = LibSystemFcnIsEmptyHelper(system, fcn, tid)

  %return isEmpty
%endfunction


%% Function: LibSystemIsForceNonInline =========================================
%%
%% Abstract:
%%    Accessor function for system's ForceNonInline flag
%%
%function LibSystemIsForceNonInline(system)
  %return system.ForceNonInline
%endfunction %% LibSystemIsForceNonInline

%% Function: LibSystemCalledByNonInlineSfcn =========================================
%%
%% Abstract:
%%    Accessor function for system's CalledByNonInlineSfcn flag
%%
%function LibSystemCalledByNonInlineSfcn(system)
  %return system.CalledByNonInlineSfcn
%endfunction %% LibSystemCalledByNonInlineSfcn

%% Function: LibSystemIsInlined(system) void ===================================
%% Description:
%%      Returns TLC_TRUE if the system is inlined
%%
%function LibSystemIsInlined(system) void
  %return system.RTWSystemCode == 0
%endfunction %% LibSystemIsInlined


%% Function: LibSystemIsNonReusedFcn(system) void ==============================
%% Description:
%%      Returns TLC_TRUE if the subsystem is non-reused
%%
%function LibSystemIsNonReusedFcn(system) void
  %return system.RTWSystemCode == 1
%endfunction %% LibSystemIsNonReusedFcn


%% Function: LibSystemIsReusedFcn(system) void =================================
%% Description:
%%      Returns TLC_TRUE if the subsystem is reused
%%
%function LibSystemIsReusedFcn(system) void
  %return system.RTWSystemCode == 2
%endfunction %% LibSystemIsReusedFcn


%% Function: LibSystemIsRoot(system) void ======================================
%% Description:
%%      Returns TLC_TRUE if the system is root
%%
%function LibSystemIsRoot(system) void
  %return system.Type == "root"
%endfunction %% LibSystemIsRoot


%% Function: SLibSystemHasOwnDataScope(system) void ============================
%% Description:
%%      Returns TLC_TRUE if the system stores its data in a new scope.
%%
%function SLibSystemHasOwnDataScope(system) void
  %return (system.HStructDeclSystemIdx == system.SystemIdx)
%endfunction %% SLibSystemHasOwnDataScope




%%
%% Local Functions used only in this file.
%%


%% Function: FcnDeclareAccessedLocalBlockOutputs ===============================
%% Description:
%%      A routine to declare all accessed local block output signals. Once they
%%      are declared, the "DeclareInFcnScope" field for these block outputs is
%%      reset to zero.
%%
%% Syntax:
%%      FcnDeclareAccessedLocalBlockOutputs(system)
%%
%function FcnDeclareAccessedLocalBlockOutputs(system) void
  %assign LocalBO_Buf = ""
  %assign tid01Eq =  ISEQUAL(SolverType, "FixedStep") && FixedStepOpts.TID01EQ
  %foreach tid = NumSampleTimes
    %assign LocalBO_Buf%<tid> = ""
  %endforeach
  %if system.Variables.LocalBlockIODef.NumFlatFields > 0
    %assign numLocs = 0
    %with system.Variables.LocalBlockIODef
      %foreach idx = NumFlatFields
	%assign localBO = BlockOutputs.LocalBlockOutput[FirstLocation + idx]
	%%
	%if localBO.DeclareInFcnScope == 0
	  %continue
	%endif
	%%
	%assign numLocs = numLocs+1
	%with localBO
	  %openfile tmpBuf
	  %assign optWidth = LibOptionalVectorWidth(Width)
	  %assign dataType = SLibGetRecordDataTypeName(localBO, "")
	  %<dataType> %<tLocalBlockIO>_%<Identifier>%<optWidth>;
          %closefile tmpBuf
	  %assign TIDlen = SIZE(TID,1)
	  %assign tidIncludesTID0 = TLC_FALSE
	  %assign bufferIncludedForTID0 = TLC_FALSE
	  %foreach tidIdx = TIDlen
	    %assign tid = (TYPE(TID) == "Vector") ? TID[tidIdx]:TID
	    %if TYPE(tid) == "Number" && tid > tid01Eq
	      %assign LocalBO_Buf%<tid> = LocalBO_Buf%<tid> + tmpBuf
	    %elseif !bufferIncludedForTID0
	      %assign LocalBO_Buf0 = LocalBO_Buf0 + tmpBuf
	      %assign bufferIncludedForTID0 = TLC_TRUE
	    %endif
	  %endforeach
	%endwith
	%% Reset the DeclareInFcnScope flag to zero
	%assign localBO.DeclareInFcnScope = 0
      %endforeach
    %endwith %% system.Variables.LocalBlockIODef
    %%
    %assign Multirate_LocalBOBuf = []
    %foreach Tid = NumSampleTimes
      %assign Multirate_LocalBOBuf = Multirate_LocalBOBuf + ""
    %endforeach
    %% LocalBO of sync tid
    %if SLibIsMultiRateAndRateGrouping(system)
       %foreach Tid = NumSynchronousSampleTimes
	%if !WHITE_SPACE(LocalBO_Buf%<Tid>)
	  %assign tmpBuffer = "/* local block i/o variables */\n" ...
	    +  LocalBO_Buf%<Tid> + "\n"
	%else
	  %assign tmpBuffer = ""
	%endif
	%assign Multirate_LocalBOBuf[Tid] = tmpBuffer
      %endforeach
      %assign Multirate_LocalBOBuf[0] = ...
	LocalBO_Buf + Multirate_LocalBOBuf[0]
    %elseif !LibAsynchronousTriggeredTID(FcnGetSubsystemTID(system))
      %openfile tmpBuffer

      %%
      %% The following section is for testing purpose only. We write out
      %% number of local variables into code comments if
      %% BufferReuseCrossBoundaryTesting feature is ON
      %%
      %if FEVAL("feature", "BufferReuseCrossBoundaryTesting") == 1
	/* Total number of local variables in mdlOutput is %<numLocs> */
      %endif

      /* local block i/o variables */
      %<LocalBO_Buf>
      %foreach Tid = NumSynchronousSampleTimes
	%assign tmpBuf = LocalBO_Buf%<Tid>
	%<tmpBuf>
      %endforeach
      %closefile tmpBuffer
      %assign Multirate_LocalBOBuf[0] = tmpBuffer
    %endif
    %% LocalBO of async tid
    %foreach tidIdx = NumAsynchronousSampleTimes
      %assign tid = NumSynchronousSampleTimes + tidIdx
      %if !WHITE_SPACE(LocalBO_Buf%<tid>)
	%assign tmpBuffer = "/* local block i/o variables */\n" ...
	  +  LocalBO_Buf%<tid> + "\n"
      %else
	%assign tmpBuffer = ""
      %endif
      %assign Multirate_LocalBOBuf[tid] = tmpBuffer
    %endforeach
    %return Multirate_LocalBOBuf
  %endif

  %return ""
%endfunction %% FcnDeclareAccessedLocalBlockOutputs


%% Function: SLibGenTerminateBody ==============================================
%% Abstract:
%%      Caches all terminate code
%%
%function SLibGenTerminateBody() void
  %% Cache subsystems
  %assign ::BlockFcn = "Terminate"
  %foreach sysIdx = NumSystems-1
    %if (!LibIsSystemTerminateCached(System[sysIdx]))
      %<FcnGenSystemTerminate(System[sysIdx])>
    %endif
  %endforeach

  %assign rootSystem = System[NumSystems-1]

  %% Cache terminate function
  %% DSP Blockset uses terminate to manage it's database
  %<FcnGenBodyTerminateFcnCache(rootSystem)>
  %assign ::BlockFcn = "Unknown"
%endfunction


%% Function: SLibGetNumericTID==============================================
%% Abstract:
%%      get numeric TID. if TID is triggered, return TriggerTID of the block.
%%   If it is constant, return 0, if it subsystem. return subsystemTID.
%%
%function SLibGetNumericTID(block)
  %with block
    %if TYPE(TID) == "Number"
      %assign tid = TID
    %elseif ISEQUAL(TID,"triggered")
      %assign tid = TriggerTID
    %elseif ISEQUAL(TID,"constant")
      %assign tid = 0
    %elseif ISEQUAL(TID,"Subsystem")
      %assign tid = ISEQUAL(SubsystemTID,"triggered") ? ...
	            TriggerTID : SubsystemTID
      %assign tid = ISEQUAL(tid,"constant") ? ...
	            0 : tid
    %endif
  %endwith
  %return tid
%endfunction

%% Function FcnGenAsyncTopSSCode ===================================
%% Abstract:
%%     This function generates code for Async tid Top Subsystem.
%%
%%     SFcn block that call inlined Async Top Subsystem
%%  must generate code after root system.  Async code
%%  won't be available until that time.
%%
%%  This function is called after code generation of root system.
%%
%function FcnGenAsyncTopSSCode() void
  %assign orgBlockFcn = ::BlockFcn
  %assign ::BlockFcn = "OutputUpdate"
  %foreach sysIdx = NumSystems
    %assign system = System[sysIdx]
    %with system
      %foreach blkIdx = NumBlocks
	%assign block = Block[blkIdx]
	%if ISFIELD(block, "IsAsyncTopCaller")
	  %openfile tmpBuffer
	  %with block
	    %<SLibGenerateNonExprOutput(block,system)>\
	  %endwith
	  %closefile tmpBuffer
	%else
	  %continue
	%endif
      %endforeach
    %endwith
  %endforeach
  %assign ::BlockFcn = orgBlockFcn
%endfunction


%% Function: SLibGenBodyCache ==================================================
%% Abstract:
%%      Caches all body code (minus the terminate code since mallocs occur
%%      in the registration and block instance code).
%%
%function SLibGenBodyCache() void
  %<LibResetBlockFcnAccessed()>

  %selectfile STDOUT
  %if RTWVerbose
### Caching model source code
  %endif
  %flushfile STDOUT
  %selectfile NULL_FILE
  %if Accelerator
    %<LibAddToSystem(System[NumSystems-1], "FcnCallSubsystemPtrs", ...
      SLibSetupFCSubsystemPtrs())>
  %endif

  %% Cache subsystems
  %foreach sysIdx = NumSystems
    %assign system = System[sysIdx]
    %% When generating model reference target, we do not need to generate
    %% code for root. (After cleanup, we should be abled to skip
    %% code generation for root)
    %addtorecord system CurrentTID -1
    %<FcnGenBodySysCache(system)>
  %endforeach
  %<FcnGenAsyncTopSSCode()>
  %<SLibGetNonContDerivSig()> \

%endfunction %% SLibGenBodyCache


%% Function:  SLibGenHeaderCache ===============================================
%% Abstract:
%%      Caches all system header files.
%%
%function SLibGenHeaderCache() void
  %% Cache system headers
  %foreach sysIdx = NumSystems
    %assign system = System[sysIdx]
    %assign skip = IsModelReferenceTarget() && sysIdx == NumSystems -1
    %if !skip
      %<LibCacheSystemIncludes(sysIdx)>
      %<LibCacheSystemBlkIOStructDef(sysIdx)>
      %if ((CodeFormat != "S-Function") || Accelerator)
	%<LibCacheSystemDWorkStructDef(sysIdx)>
      %endif
      %<LibCacheSystemCStatesStructDef(sysIdx)>
      %<LibCacheSystemStateDerivStructDef(sysIdx)>
      %<LibCacheSystemStateDisabledStructDef(sysIdx)>
      %<LibCacheSystemNonSampledZCStructDef(sysIdx)>
      %<LibCacheSystemZCEStructDef(sysIdx)>
    %endif
  %endforeach
%endfunction

%function SLibGenConstBlkIOCache() void
  %%
  %% Those structures get accessed in the commonreglib and
  %% this might alter the contents.
  %%
  %assign numSys = GetNumSystemsForCodeGen()
  %foreach sysIdx = numSys
    %<LibCacheSystemConstBlkIOStructDef(sysIdx)>
  %endforeach
%endfunction



%% Function: SLibDumpSFLibraryBlockInitialization ==============================
%% Abstract:
%%


%% Function: SLibExtModeHostOnlyStub ===========================================
%% Abstract:
%%  Stubs out system that only runs on host (for external mode).
%%
%function SLibExtModeHostOnlyStub(system) void
  %if ISFIELD(system,"StartFcn")
    %<LibSetSystemField(system, "CachedStartFcn", "")>
  %endif
  %if ISFIELD(system,"EnableFcn")
    %<LibSetSystemField(system, "CachedEnableFcn", "")>
  %endif
  %if ISFIELD(system,"InitializeFcn")
    %<LibSetSystemField(system, "CachedInitializeFcn", "")>
  %endif
  %if ISFIELD(system,"OutputFcn")
    %<LibSetSystemField(system, "CachedOutputFcn", "")>
  %endif
  %if ISFIELD(system,"OutputUpdateFcn")
    %<LibSetSystemField(system, "CachedOutputFcn", "")>
    %<LibSetSystemField(system, "CachedUpdateFcn", "")>
  %endif
  %if ISFIELD(system,"UpdateFcn")
    %<LibSetSystemField(system, "CachedUpdateFcn", "")>
  %endif
  %if ISFIELD(system,"DerivativeFcn")
    %<LibSetSystemField(system, "CachedDerivativeFcn", "")>
  %endif
  %if ISFIELD(system,"ProjectionFcn")
    %<LibSetSystemField(system, "CachedProjectionFcn", "")>
  %endif
  %if ISFIELD(system,"ZeroCrossingFcn")
    %<LibSetSystemField(system, "CachedZeroCrossingFcn", "")>
  %endif
  %if ISFIELD(system,"DisableFcn")
    %<LibSetSystemField(system, "CachedDisableFcn", "")>
  %endif
  %if ISFIELD(system,"TerminateFcn")
    %<LibSetSystemField(system, "CachedTerminateFcn", "")>
  %endif
%endfunction %% SLibExtModeHostOnlyStub


%endif %% _COMMONBODLIB_

%% [EOF] commonbodlib.tlc
