%if EXISTS("_BLOCK_SETUP_LIB_") == 0
%assign _BLOCK_SETUP_LIB_ = 1
%%
%%Copyright2019TheMathWorks,Inc.
%%
 
%%============================================================================
%%Beforecodegenerationbegins,makeapassthroughthemodeland:
%%
%%oInitializeUserDefinedRWork,UserDefinedIWork,andUserDefinedPWork
%%tozero.Thisinitializationmustbeperformedbeforecallingthe
%%block'sBlockInstanceSetupfunctionsinceitistherethattheuser
%%willdefine(redefine)theirworkvectors.
%%
%%oExecuteeachblocks"BlockInstanceSetup"function.
%%
%%oExecuteablocks"BlockTypeSetup"functionthefirsttimetheblock
%%typeisencountered.
%%
%%oPromotedefinedRWork,IWork,PWorkandDWorkintoparentscope.
%%
%%oInitializeeachblockoutputasnotneededtobedeclaredinfunction
%%scope.Thiswillbeusedtotrackblockoutputsignalsthatarenotin
%%theglobalBlockIOvector,andhenceneedtobelocallydeclaredinthe
%%appropriatefunctions.
%%
%%oForceexpressionfoldingoffiftheblockisnotcompliant.
%%
%%oForcescalarexpandedinputexpressionsoffunlessotherwisespecified.
%%
 
%%============================================================================
%%LoopthroughtheSystemrecordsand...
%%
%%TopTester:test/toolbox/simulink/blocks/CPPCodeGen/tsmlk_core_cpp_coverage.m
%%TopTester:test/toolbox/simulink/variants/inlineVariants/variantSource/systemtests/tmg1317695_VC1.m
%%TopTester:test/toolbox/simulink/blocks/sb2sl/tsb2slmdlref.m
%%
%function BlockSetupAndCompatibilityCheck() void
  %with ::CompiledModel
  %foreach sysIdx = ::CompiledModel.NumSystems
    %assign ::system = ::CompiledModel.System[sysIdx]
    %with ::system
       
      %% Add NumTotalBlocks to system record for backward compatibiltiy
      %if ISFIELD(::system, "Block")
        %addtorecord ::system NumTotalBlocks SIZE(system.Block,1)
      %else
        %addtorecord ::system NumTotalBlocks 0
      %endif
       
      %foreach blkIdx = ::system.NumBlocks
        %assign ::block = ::system.Block[blkIdx]
        %with ::block
       
          %if ::block.Type != "Opaque"
             
            %% Promote RWork defines into parent scope if the block defines RWorks
            %foreach idx = ::block.NumRWorkDefines
              %assign work = ::block.RWorkDefine[idx]
              %if !ISFIELD(::block,"%<work.Name>")
                %assign %<work.Name> = work
                %assign ::block = ::block + %<work.Name>
              %endif
            %endforeach
             
            %% Promote IWork defines into parent scope if the block defines IWorks
            %foreach idx = ::block.NumIWorkDefines
              %assign work = ::block.IWorkDefine[idx]
              %assign %<work.Name> = work
              %assign ::block = ::block + %<work.Name>
            %endforeach
             
            %% Promote IWork defines into parent scope if the block defines PWorks
            %foreach idx = ::block.NumPWorkDefines
              %assign work = ::block.PWorkDefine[idx]
              %if !ISFIELD(::block,"%<work.Name>")
                %assign %<work.Name> = work
                %assign ::block = ::block + %<work.Name>
              %endif
            %endforeach
 
            %% Promote DWork into parent scope.
            %foreach idx = ::block.NumDWork
              %assign work = ::block.DWork[idx]
              %assign %<work.Name> = work
              %assign ::block = ::block + %<work.Name>
            %endforeach
          %endif %% Type != "Opaque"
 
          %addtorecord ::block BlkSysIdx system.SystemIdx
 
          %assign ::CurrentSFcnBlockName = ""
          %if ::block.Type == "S-Function"
            %if LibSystemIsReusedLibraryFcn(::system)
              %assign ::CurrentSFcnBlockName = ::block.ParamSettings.FunctionName
            %endif
          %endif
     
          %assign _globalVar = SLibBlockTypeSetupName(sysIdx, blkIdx)
     
          %if !EXISTS("::%<_globalVar>")
            %if SLibIsMainCodeGenPhase()
              %assign blkTypeInit = ...
                CGMODEL_ACCESS("FileRepository.initializeBlockType",_globalVar)
            %endif
            %<GENERATE(::block, "BlockTypeSetup", ::system)>/
            %assign ::%<_globalVar> = 1
          %else
            %if SLibIsMainCodeGenPhase()
              %assign vcond = SLibGetBlockVariantCondition(::block)
              %assign updateCond = ...
                CGMODEL_ACCESS("FileRepository.updateHeaderConditionBasedOnType", ...
                _globalVar, vcond)
            %endif
          %endif
     
          %% Reset S-function name if one was assigned
          %assign ::CurrentSFcnBlockName = ""
 
          %% Execute the block's BlockInstanceSetup function
          %assign ::BlockFcn = "BlockInstanceSetup"
 
          %<GENERATE(::block, "BlockInstanceSetup", ::system)>/
          %assign ::BlockFcn = "Unknown"
  
          %if ::block.UseTLC
            %if SLibBlockIsExpressionCompliant(::block)
              %%
              %% Disallow scalar expanded expression (unless otherwise specified)
              %% This is why:
              %% Suppose we have a block with multiple input expressions, at least
              %% one wide, at one scalar. Then expansion of the scalar inputs
              %% causes those inputs to be duplicated which harms throughput.
              %%
              %% For example, say we have a Sum block with a wide input "u1"
              %% and scalar input "u2". If we accept expressions at the scalar
              %% input we will end up with something like
              %%
              %% for (i = 0; i < 10; i++) {
              %% output[i] = sin(cos(u1[i])) + sin(cos(u2));
              %% }
              %%
              %% Here we see sin(cos(u2)) repeatedly and calculated due to scalar
              %% expansion of an expression.
              %%
              %foreach opIdx = ::block.NumDataOutputPorts
                %if LibBlockOutputSignalWidth(opIdx) > 1
                  %foreach ipIdx = ::block.NumDataInputPorts
                    %if LibBlockInputSignalWidth(ipIdx) == 1 && ...
                      !SLibBlockInputSignalAllowScalarExpandedExpr(::block, ipIdx)
                      %<SLibSetBlockInputSignalIsNotExpr(::block, ipIdx)>
                    %endif
                  %endforeach
                %endif
              %endforeach
            %else
              %%
              %% Check expression folding compliance
              %% If not compliant, don't allow nonconst expressions at the
              %% output port, nor (nonconst) expressions at the input ports.
              %%
              %foreach ipIdx = ::block.NumDataInputPorts
                %<SLibSetBlockInputSignalIsNotExpr(::block, ipIdx)>
              %endforeach
              %<SLibSetBlockOutputSignalsAreNotExpr(::block)>
            %endif
          %endif
        %endwith %% block
      %endforeach
 
      %% Check each non-virtual system for the existence of RTWdata in a
      %% empty subsystem. If EmptySubsysInfo exists and RTWdata.TLCFile
      %% exists, execute the designated TLC file. This loop is used for the
      %% custom code block, but can also be used to call a tlc file for any
      %% other empty subsystems that have RTWdata records by assigning the
      %% field TLCFile to be the name of the tlc file. Note: the RTWdata
      %% attached to a block should be processed by that blocks own tlc file.
      %if EXISTS("EmptySubsysInfo")
        %with EmptySubsysInfo
          %foreach idx = NumRTWdatas
            %assign temp = RTWdata[idx]
            %if ISFIELD(temp,"IncludePath")
              %addincludepath temp.IncludePath
            %endif
            %if ISFIELD(temp,"TLCFile")
              %if FILE_EXISTS(GENERATE_FILENAME(temp.TLCFile))
                %<GENERATE_TYPE(temp, "ProcessRTWdata", temp.TLCFile, system)>
              %else
                %if system.Type != "root"
                  %assign sysName = LibUnmangledPathName(system.Name)
                %else
                  %assign sysName = ::CompiledModel.Name
                %endif
                %openfile errTxt
         
         
Cannot locate TLC file %<temp.TLCFile>.tlc
 
A block specified RTWData without a corresponding TLC file. /
RTWData must include the TLC file name. For example,
 
data.Foo = '1';
data.TLCFile = 'foofile';
set_param(gcb, 'RTWData', data);
 
RTWData {
  Foo "1"
  TLCFile "foofile"
}
 
The specified TLC file either does not exist, or is not on the TLC /
path, or is incorrect.
 
The block was located in system: %<sysName>
                %closefile errTxt
                %<LibReportError(errTxt)>
              %endif
            %endif
          %endforeach
        %endwith
      %endif
    %endwith %% system
  %endforeach
  %endwith %% ::CompiledModel
  %undef ::system, ::block, param, bo, work, temp
%endfunction %% BlockSetupAndCompatibilityCheck
 
 
%function SLibSetupSharedGlobalVariables() void
  %%
  %% Accelerator flag. Used in conjuction with the S-Function code format.
  %%
  %if !EXISTS("::Accelerator")
    %assign ::Accelerator = 0
  %endif
%endfunction
 
%endif %% _BLOCK_SETUP_LIB_