%if EXISTS("_MODELREFVARDIMSUTIL_") == 0
%assign _MODELREFVARDIMSUTIL_ = 1
%function SLibGetArgUseCanDimSizeDW(arg)
%return ISFIELD(arg, "CanonicalDimSizeDWorkIdx")
%endfunction
%function SLibGetCanDimSizeDWIdxForArg(arg)
%assert(SLibGetArgUseCanDimSizeDW(arg))
%return arg.CanonicalDimSizeDWorkIdx
%endfunction
%function SLibGetArgUseSharedDimSizeDW(arg)
%return ISFIELD(arg, "DimSizeDWork")
%endfunction
%function SLibGetArgIsVarDims(arg)
%return SLibGetArgUseCanDimSizeDW(arg) || SLibGetArgUseSharedDimSizeDW(arg)
%endfunction
%function SLibGetExternalIOIsVarDims(canIO)
%return SLibGetArgUseCanDimSizeDW(canIO)
%endfunction
%function SLibGetCanIOIsVarDims(canIO)
%return SLibGetArgUseCanDimSizeDW(canIO)
%endfunction
%function SLibGetCanDWorkIsCanDimSizeDWork(cdwIdx)
%if ISFIELD(CanonicalDWorkArgDef[cdwIdx], "IsCanDimSizeDWork")
%assign isDimSizeDWork = CanonicalDWorkArgDef[cdwIdx].IsCanDimSizeDWork
%else
%assign isDimSizeDWork = TLC_FALSE
%foreach argIdx = NumCanonicalInputArgDefs
%assign ci = CanonicalInputArgDef[argIdx]
%if SLibGetCanIOIsVarDims(ci) && ...
cdwIdx == SLibGetCanDimSizeDWIdxForArg(ci)
%assign isDimSizeDWork = TLC_TRUE
%break
%endif
%endforeach
%if !isDimSizeDWork
%foreach argIdx = NumCanonicalOutputArgDefs
%assign co = CanonicalOutputArgDef[argIdx]
%if SLibGetCanIOIsVarDims(co) && ...
cdwIdx == SLibGetCanDimSizeDWIdxForArg(co)
%assign isDimSizeDWork = TLC_TRUE
%break
%endif
%endforeach
%endif
%addtorecord CanonicalDWorkArgDef[cdwIdx] IsCanDimSizeDWork isDimSizeDWork
%endif
%return isDimSizeDWork
%endfunction
%function SLibGetDWorkIsCanDimSizeDWorkInBaseSys(dwIdx)
%if ISFIELD(::CompiledModel.DWorks.DWork[dwIdx], "IsCanDimSizeDWorkInBaseSysem")
%assign isCanDimSizeDWork = ::CompiledModel.DWorks.DWork[dwIdx].IsCanDimSizeDWorkInBaseSystem
%else
%assign isCanDimSizeDWork = TLC_FALSE
%assign baseSysIdx = GetBaseSystemIdx()
%assign baseSys = ::CompiledModel.System[baseSysIdx]
%with baseSys.Interface
%foreach cdwIdx = NumCanonicalDWorkArgDefs
%assign canDW = CanonicalDWorkArgDef[cdwIdx]
%if canDW.FirstSignalSrc == dwIdx
%if SLibGetCanDWorkIsCanDimSizeDWork(cdwIdx)
%assign isCanDimSizeDWork = TLC_TRUE
%endif
%break
%endif
%endforeach
%endwith
%addtorecord ::CompiledModel.DWorks.DWork[dwIdx] IsCanDimSizeDWorkInBaseSysem isCanDimSizeDWork
%endif
%return isCanDimSizeDWork
%endfunction
%function SLibGetDimSizeDWorkFullPath(dimSizeDWorkIdx)
%assign dworkRec = ::CompiledModel.DWorks.DWork[dimSizeDWorkIdx]
%if ISFIELD(dworkRec, "VarGroupIdx")
%assign varGroup = ::CompiledModel.VarGroups.VarGroup[dworkRec.VarGroupIdx[0]]
%assign varGroupTypeIdx = varGroup.CGTypeIdx
%assign varGroupType = ::CompiledModel.CGTypes.CGType[varGroupTypeIdx]
%assign memberId = LibCGTypeMemberName(varGroupTypeIdx, dworkRec.VarGroupIdx[1])
%assign memberTypeIdx = LibCGTypeMemberCGTypeIdx(varGroupTypeIdx, dworkRec.VarGroupIdx[1])
%if IsModelReferenceTarget()
%assign name = varGroup.LocalName
%else
%assign name = varGroup.Name
%endif
%if IsModelReferenceTarget() || varGroup.IsPointer
%assign fullpath = name + "->" + memberId
%else
%assign fullpath = name + "." + memberId
%endif
%assign width = LibCGTypeWidth(memberTypeIdx)
%if width == 1
%assign fullpath = "&" + fullpath
%else
%assert width > 1
%assign fullpath = "&" + fullpath + "[0]"
%endif
%else
%assign dataLayout = SLibGetDataLayout(dworkRec)
%assign name = dworkRec.Identifier
%assign isPointer = dworkRec.StorageClass == "ImportedExternPointer" ? ...
TLC_TRUE : TLC_FALSE
%if (isPointer)
%assign fullpath = "%<name>"
%else
%assign fullpath = "&%<name>%"
%endif
%endif
%return fullpath
%endfunction
%function SLibGetDimSizeDWorkFullPathForFcnArg(dimSizeDWorkIdx, baseIdx, cross)
%assign dworkRec = ::CompiledModel.DWorks.DWork[dimSizeDWorkIdx]
%if ISFIELD(dworkRec, "VarGroupIdx") && !SLibIsLegacyStorageClassForDataRecord(dworkRec)
%assign varGroup = ::CompiledModel.VarGroups.VarGroup[dworkRec.VarGroupIdx[0]]
%assign varGroupTypeIdx = varGroup.CGTypeIdx
%assign varGroupType = ::CompiledModel.CGTypes.CGType[varGroupTypeIdx]
%assign memberId = LibCGTypeMemberName(varGroupTypeIdx, dworkRec.VarGroupIdx[1])
%assign memberTypeIdx = LibCGTypeMemberCGTypeIdx(varGroupTypeIdx, dworkRec.VarGroupIdx[1])
%if LibGetVarGroupCategory(dworkRec.VarGroupIdx[0]) == "ExternalInputSize"
%assign fullpath = varGroup.Name + "."
%else
%assign fullpath = SLibCGIRVarGroupPath(dworkRec.VarGroupIdx[0], baseIdx, cross)
%endif
%assign fullpath = fullpath + memberId
%assign width = LibCGTypeWidth(memberTypeIdx)
%if width == 1
%assign fullpath = "&" + fullpath
%else
%assert width > 1
%assign fullpath = "&" + fullpath + "[0]"
%endif
%elseif !SLibIsLegacyStorageClassForDataRecord(dworkRec)
%assign dataLayout = SLibGetDataLayout(dworkRec)
%assign name = dworkRec.Identifier
%assign isPointer = dworkRec.StorageClass == "ImportedExternPointer" ? ...
TLC_TRUE : TLC_FALSE
%if (isPointer)
%assign fullpath = "%<name>"
%else
%assign fullpath = "&%<name>%"
%endif
%else
%assign fullpath = LibCustomData(dworkRec, "address", "", "")
%endif
%return fullpath
%endfunction
%function SLibGetBlockOutputVarDimsIdentifierFromRecord(dimSizeDWorkIdx, accessSysIdx) void
%assign dworkRec = ::CompiledModel.DWorks.DWork[dimSizeDWorkIdx]
%if ISFIELD(dworkRec, "VarGroupIdx")
%assign varGroupIdx = dworkRec.VarGroupIdx[0]
%assign varGroup = ::CompiledModel.VarGroups.VarGroup[dworkRec.VarGroupIdx[0]]
%assign varGroupTypeIdx = varGroup.CGTypeIdx
%if LibCGTypeIsMatrix(varGroupTypeIdx)
%assign varGroupTypeIdx = SLibGetBaseTypeForVarGroupUsedAsMatrix(varGroupTypeIdx)
%endif
%assign memberId = LibCGTypeMemberName(varGroupTypeIdx, dworkRec.VarGroupIdx[1])
%if LibGetVarGroupCategory(dworkRec.VarGroupIdx[0]) == "ExternalInputSize"
%assign identiPath = varGroup.Name + "."
%else
%assign identiPath = SLibCGIRVarGroupPath(varGroupIdx,accessSysIdx,TLC_FALSE)
%endif
%assign identipath = identiPath + memberId
%else
%assign dataLayout = SLibGetDataLayout(dworkRec)
%assign name = dworkRec.Identifier
%assign isPointer = dworkRec.StorageClass == "ImportedExternPointer" ? ...
TLC_TRUE : TLC_FALSE
%if (isPointer)
%assign identipath = "%<name>"
%else
%assign identipath = "&%<name>%"
%endif
%endif
%return identipath
%endfunction
%function SLibGetExternalOutputVarDimsIdentifierFromRecord(SizeVarGroupIdx, accessSysIdx) void
%assign varGroupIdx = SizeVarGroupIdx[0]
%assign varGroupMemberIdx = SizeVarGroupIdx[1]
%assign varGroup = ::CompiledModel.VarGroups.VarGroup[varGroupIdx]
%assign varGroupTypeIdx = varGroup.CGTypeIdx
%if LibCGTypeIsMatrix(varGroupTypeIdx)
%assign varGroupTypeIdx = SLibGetBaseTypeForVarGroupUsedAsMatrix(varGroupTypeIdx)
%endif
%assign memberId = FcnSLibCGIRGetVarGroupMemberName(varGroupIdx, varGroupMemberIdx)
%if LibGetVarGroupCategory(varGroupIdx) == "ExternalOutputSize"
%assign identiPath = varGroup.Name + "."
%else
%assign identiPath = SLibCGIRVarGroupPath(varGroupIdx,accessSysIdx,TLC_FALSE)
%endif
%assign identipath = identiPath + memberId
%return identipath
%endfunction
%function SLibGetStructDWorkIdxForModelRefBlk(block)
%if ISFIELD(block, "StructDWorkIdx")
%assign structDWorkIdx = block.StructDWorkIdx
%else
%assign structDWorkIdx = -1
%foreach dworkIdx = block.NumDWork
%if LibCGTypeIsUnknown(::CompiledModel.DWorks.DWork[block.DWork[dworkIdx].FirstRootIdx].CGTypeIdx)
%assign structDWorkIdx = dworkIdx
%break
%endif
%endforeach
%addtorecord block StructDWorkIdx structDWorkIdx
%endif
%return structDWorkIdx
%endfunction
%function FcnAddNeededCanDimSizeDWForCanInp(sysFcn, sysIdx, idx, ...
skipCanDWork) void
%assign ci = CanonicalInputArgDef[idx]
%assign skipThisArg = 0
%if IDNUM(ci.SignalSrc[0])[0] == "F"
%assign skipThisArg = 1
%endif
%if IDNUM(ci.SignalSrc[0])[0] == "L"
%if (sysFcn != "Output" && sysFcn!= "Update" &&...
sysFcn!= "RootUpdate" && sysFcn!= "OutputUpdate")
%assign skipThisArg = 1
%endif
%endif
%if skipThisArg==0
%if SLibGetCanIOIsVarDims(ci)
%assign cdwIdx = SLibGetCanDimSizeDWIdxForArg(ci)
%if !skipCanDWork[cdwIdx]
%assign cdw = CanonicalDWorkArgDef[cdwIdx]
%assign cTID = System[sysIdx].CurrentTID
%assign isRG = SLibSystemFcnPeriodicRateGrouping(System[sysIdx], sysFcn)
%if SysFcnArgNeeded(sysFcn, cdw, cTID, isRG)
%assign identi = LibGetRecordIdentifier(cdw)
%assign dwRec = ::CompiledModel.DWorks.DWork[cdw.FirstSignalSrc]
%assign dwWidth = SLibDWorkWidth(dwRec)
%assign dataType = "const " + SLibGetRecordDataTypeName(dwRec, "") + " "
%if dwWidth > 1
%assign argDef = identi + "[%<dwWidth>]"
%else
%assign argDef = "*" + identi
%endif
%<FcnAddParameter(dataType, argDef)>
%endif
%endif
%endif
%endif
%endfunction
%function FcnAddNeededCanDimSizeDWForCanOut(sysFcn, sysIdx, idx, ...
skipCanDWork) void
%assign co = CanonicalOutputArgDef[idx]
%if SLibGetCanIOIsVarDims(co)
%assign cdwIdx = SLibGetCanDimSizeDWIdxForArg(co)
%if !skipCanDWork[cdwIdx]
%assign cdw = CanonicalDWorkArgDef[cdwIdx]
%assign cTID = System[sysIdx].CurrentTID
%assign isRG = SLibSystemFcnPeriodicRateGrouping(System[sysIdx], sysFcn)
%if SysFcnArgNeeded(sysFcn, cdw, cTID, isRG)
%assign identi = LibGetRecordIdentifier(cdw)
%assign dwRec = ::CompiledModel.DWorks.DWork[cdw.FirstSignalSrc]
%assign dwWidth = SLibDWorkWidth(dwRec)
%assign dataType = SLibGetRecordDataTypeName(dwRec, "") + " "
%if dwWidth > 1
%assign argDef = identi + "[%<dwWidth>]"
%else
%assign argDef = "*" + identi
%endif
%<FcnAddParameter(dataType, argDef)>
%endif
%endif
%endif
%endfunction
%function FcnGetModelRefDWork(aArgClass, aCanIOIdx, aCanDWorkIdx) void
%assign canDWork = CanonicalDWorkArgDef[aCanDWorkIdx]
%assign dwIdx = canDWork.FirstSignalSrc
%assign dwRec = ::CompiledModel.DWorks.DWork[dwIdx]
%assign dwWidth = SLibDWorkWidth(dwRec)
%if dwWidth == 1
%return "&" + aArgClass + "VarDims_%<aCanIOIdx>"
%else
%return aArgClass + "VarDims_%<aCanIOIdx>"
%endif
%endfunction
%function FcnGetAdditionalCanDimSizeDWForCanInp(sysFcn, sysIdx, ...
accessSysIdx, callSiteIdx, idx, comma, args, skipCanDWork) void
%if SLibGetCanIOIsVarDims(CanonicalInputArgDef[idx])
%assign cTID = System[sysIdx].CurrentTID
%assign isRG = SLibSystemFcnPeriodicRateGrouping(System[sysIdx], sysFcn)
%assign candIdx = SLibGetCanDimSizeDWIdxForArg(CanonicalInputArgDef[idx])
%if !skipCanDWork[candIdx] && ...
SysFcnArgNeeded(sysFcn, CanonicalDWorkArgDef[candIdx], cTID, isRG)
%assign cs = System[sysIdx].CallSites[callSiteIdx]
%assert System[cs[0]].HStructDeclSystemIdx == ...
System[accessSysIdx].HStructDeclSystemIdx
%with System[cs[0]]
%assign ssBlk = System[cs[2]].Block[cs[3]]
%with ssBlk
%assign skipThisArg = 0
%assign ci = System[sysIdx].Interface.CanonicalInputArgDef[idx]
%if IDNUM(ci.SignalSrc[0])[0] == "F"
%assign skipThisArg = 1
%endif
%if IDNUM(ci.SignalSrc[0])[0] == "L"
%if (sysFcn != "Output" && sysFcn!= "Update" &&...
sysFcn!= "RootUpdate" && sysFcn!= "OutputUpdate")
%assign skipThisArg = 1
%endif
%endif
%if !skipThisArg
%if IsModelReferenceTarget() && accessSysIdx == NumSystems-1
%assign args = args + comma + ...
FcnGetModelRefDWork("In", idx, candIdx)
%else
%assign ci = CallSiteInfo.CanonicalInputArg[idx]
%assign idNum = IDNUM(ci.SignalSrc[0])
%assign interface = System[System[cs[0]].HStructDeclSystemIdx].Interface
%assign canInputArg = interface.CanonicalInputArgDef[idNum[1]]
%assign args = args + comma + LibGetRecordIdentifier(interface.CanonicalDWorkArgDef[candIdx])
%<SLibAccessArgHelper(interface.CanonicalDWorkArgDef[candIdx],"",...
System[accessSysIdx].CurrentTID)>
%endif
%assign comma = ", "
%endif
%endwith
%endwith
%endif
%endif
%return ["%<comma>", "%<args>"]
%endfunction
%function FcnGetAdditionalCanDimSizeDWForCanOut(sysFcn, sysIdx, ...
accessSysIdx, callSiteIdx, idx, comma, args, skipCanDWork) void
%if SLibGetCanIOIsVarDims(CanonicalOutputArgDef[idx])
%assign cTID = System[sysIdx].CurrentTID
%assign isRG = SLibSystemFcnPeriodicRateGrouping(System[sysIdx], sysFcn)
%assign candIdx = SLibGetCanDimSizeDWIdxForArg(CanonicalOutputArgDef[idx])
%if !skipCanDWork[candIdx] && ...
SysFcnArgNeeded(sysFcn, CanonicalDWorkArgDef[candIdx], cTID, isRG)
%assign cs = System[sysIdx].CallSites[callSiteIdx]
%assert System[cs[0]].HStructDeclSystemIdx == ...
System[accessSysIdx].HStructDeclSystemIdx
%with System[cs[0]]
%assign ssBlk = System[cs[2]].Block[cs[3]]
%with ssBlk
%if IsModelReferenceTarget() && accessSysIdx == NumSystems-1
%assign args = args + comma + ...
FcnGetModelRefDWork("Out", idx, candIdx)
%else
%assign interface = System[System[cs[0]].HStructDeclSystemIdx].Interface
%assign idNum = IDNUM(CallSiteInfo.CanonicalDWorkArg[candIdx].SignalSrc)
%assert(ISEQUAL(idNum[0], "dp"))
%assign cdIdx = idNum[1]
%assign args = args + comma + LibGetRecordIdentifier(interface.CanonicalDWorkArgDef[cdIdx])
%<SLibAccessArgHelper(interface.CanonicalDWorkArgDef[cdIdx],"",...
System[accessSysIdx].CurrentTID)>
%endif
%assign comma = ", "
%endwith
%endwith
%endif
%endif
%return ["%<comma>", "%<args>"]
%endfunction
%function SLibDumpSfcnInpDimsMode(idx)
%if SLibGetExternalIOIsVarDims(ExternalInput[idx]) && ...
!LibCGTypeIsStruct(ExternalInput[idx].CGTypeIdx)
%return "ssSetInputPortDimensionsMode(S, %<idx>, VARIABLE_DIMS_MODE);"
%else
%return "ssSetInputPortDimensionsMode(S, %<idx>, FIXED_DIMS_MODE);"
%endif
%endfunction
%function SLibDumpSfcnOutDimsMode(idx)
%if SLibGetExternalIOIsVarDims(ExternalOutput[idx]) && ...
!LibCGTypeIsStruct(ExternalOutput[idx].CGTypeIdx)
%return "ssSetOutputPortDimensionsMode(S, %<idx>, VARIABLE_DIMS_MODE);"
%else
%return "ssSetOutputPortDimensionsMode(S, %<idx>, FIXED_DIMS_MODE);"
%endif
%endfunction
%function SLibModelHasVarDimsInput()
%assign hasVarDimsInp = TLC_FALSE
%with ExternalInputs
%foreach idx = NumExternalInputs
%if SLibGetExternalIOIsVarDims(ExternalInput[idx])
%assign hasVarDimsInp = TLC_TRUE
%break
%endif
%endforeach
%endwith
%return hasVarDimsInp
%endfunction
%function SLibModelHasVarDimsOutput()
%assign hasVarDimsOut = TLC_FALSE
%with ExternalOutputs
%foreach idx = NumExternalOutputs
%if SLibGetExternalIOIsVarDims(ExternalOutput[idx])
%assign hasVarDimsOut = TLC_TRUE
%break
%endif
%endforeach
%endwith
%return hasVarDimsOut
%endfunction
%function SLibModelOutputSizeDependOnlyInputSize()
%return SLibModelHasVarDimsInput() && ...
ISFIELD(::CompiledModel, "SignalSizeComputeType") && ...
ISEQUAL(::CompiledModel.SignalSizeComputeType, "FromInputSize")
%endfunction
%function GenerateModelRefSetDimsCall(subsys, type) void
%assign fcnInfo = LibGetFcnInfo(subsys, type, subsys.CurrentTID)
%if type == "SetDims"
%return LibGenSubsystemFcnCall(["outIdx", "ruleIdx"], fcnInfo, SystemIdx, subsys.SystemIdx, 0)
%else
%return LibGenSubsystemFcnCall([], fcnInfo, SystemIdx, subsys.SystemIdx, 0)
%endif
%endfunction
%function WriteModelrefSFunctionVarDimsSetDimsMethods(type) Output
%if SLibModelOutputSizeDependOnlyInputSize()
%assign baseSysIdx = GetBaseSystemIdx()
%assign fcnEmpty = TLC_FALSE
%if type == "SetDims" && !SLibModelHasVarDimsOutput() || ...
type == "FinalizeDims" && LibSystemFcnIsEmpty(System[baseSysIdx], "FinalizeDims")
%assign fcnEmpty = TLC_TRUE
%endif
%if !fcnEmpty
%assign fcnReturns = "static void"
%if type == "SetDims"
%assign fcnName = "mdlSetOutputDimsRuleFcn"
%assign fcnParams = "SimStruct *S, int outIdx, int ruleIdx"
%else
%assert type == "FinalizeDims"
%assign fcnName = "mdlFinalizeDimsFcn"
%assign fcnParams = "SimStruct *S"
%endif
%createrecord fcnRec {Name fcnName; Returns fcnReturns; Params fcnParams; Abstract ""; ...
Category "model"; GeneratedBy "modelrefvardimsutil.tlc"; Type "FinalizeDims"}
%<SLibDumpFunctionBanner(fcnRec)>
%undef fcnRec
%<fcnReturns> %<fcnName>(%<fcnParams>)
%with System[baseSysIdx]
{
/* call to reusable function */
%with Interface
%foreach argIdx=NumCanonicalOutputArgDefs
%if SLibGetArgIsVarDims(CanonicalOutputArgDef[argIdx])
%assign idx = CanonicalOutputArgDef[argIdx].RootOutputIdx
%assign co = CanonicalOutputArgDef[argIdx]
%assign dataType = SLibGetRecordDataTypeName(co, "")
%<dataType> *OutPort_%<argIdx> = ...
(%<dataType> *) ...
ssGetOutputPortSignal(S, %<idx>);
%endif
%endforeach
%assign vardimsDeclInit = CommonDeclarationAndInitCanIOVarDims(TLC_FALSE, "", 0)
%assign hasDwork = %<ModelrefBlockNeedsDwork()>
%if hasDwork
%assert !IsModelRefScalableBuild()
%<tsysMdlrefDWorkType> *dw = (%<tsysMdlrefDWorkType> *) ssGetDWork(S, 0);
%endif
%endwith
%endwith
% /
% /
%with System[NumSystems-1]
%assign subsys = System[NumSystems-2]
%<GenerateModelRefSetDimsCall(subsys, type)> /
%endwith
%assign baseSysIdx = GetBaseSystemIdx()
%assign cTID = System[baseSysIdx].CurrentTID
%assign isRG = SLibSystemFcnPeriodicRateGrouping(System[baseSysIdx], type)
%<SLibGenOutportCurrentDimsWrites(type, cTID, isRG)>
}
%endif
%endif
%endfunction
%function GetInputCurrentDimensions(cgTypeId, dst, inpIdx, startOffset) Output
%assign eOffset = startOffset
%with CGTypes
%if LibCGTypeIsStruct(cgTypeId)
%foreach idxE = LibCGTypeNumMembers(cgTypeId)
%assign eName = LibCGTypeMemberName(cgTypeId, idxE)
%assign eDTypeId = LibCGTypeMemberCGTypeIdx(cgTypeId, idxE)
%assign eOffset = %<GetInputCurrentDimensions(eDTypeId, dst+"."+eName, inpIdx, eOffset)>
%endforeach
%else
%if LibCGTypeIsMatrix(cgTypeId)
%assign eWidth = LibCGTypeWidth(cgTypeId)
%assign dataType = CGType[LibCGTypeBaseIndex(cgTypeId)].Name
%foreach dimIdx = eWidth
%<dst>[%<dimIdx>] = ...
(%<dataType>)ssGetCurrentInputPortDimensions(S, %<inpIdx>, %<eOffset>);
%assign eOffset = eOffset + 1
%endforeach
%else
%assign dataType = CGType[cgTypeId].Name
%<dst> = ...
(%<dataType>)ssGetCurrentInputPortDimensions(S, %<inpIdx>, %<eOffset>);
%assign eOffset = eOffset + 1
%endif
%endif
%endwith
%return %<eOffset>
%endfunction
%function GetOutputCurrentDimensions(cgTypeId, dst, outIdx, startOffset) Output
%assign eOffset = startOffset
%with CGTypes
%if LibCGTypeIsStruct(cgTypeId)
%foreach idxE = LibCGTypeNumMembers(cgTypeId)
%assign eName = LibCGTypeMemberName(cgTypeId, idxE)
%assign eDTypeId = LibCGTypeMemberCGTypeIdx(cgTypeId, idxE)
%assign eOffset = %<GetOutputCurrentDimensions(eDTypeId, dst+"."+eName, outIdx, eOffset)>
%endforeach
%else
%if LibCGTypeIsMatrix(cgTypeId)
%assign eWidth = LibCGTypeWidth(cgTypeId)
%assign dataType = CGType[LibCGTypeBaseIndex(cgTypeId)].Name
%foreach dimIdx = eWidth
%<dst>[%<dimIdx>] = ...
(%<dataType>)ssGetCurrentOutputPortDimensions(S, %<outIdx>, %<eOffset>);
%assign eOffset = eOffset + 1
%endforeach
%else
%assign dataType = CGType[cgTypeId].Name
%<dst> = ...
(%<dataType>)ssGetCurrentOutputPortDimensions(S, %<outIdx>, %<eOffset>);
%assign eOffset = eOffset + 1
%endif
%endif
%endwith
%return %<eOffset>
%endfunction
%function CommonDeclarationAndInitCanIOVarDims(checkAccess, tid, isPeriodicRateGrouping)
%assign ioVarDimsDeclBuffer = ""
%assign ioVarDimsInitBuffer = ""
%assign inportVarDimsNamePrefix = "InVarDims_"
%assign outportVarDimsNamePrefix = "OutVarDims_"
%assign hasVarDimsIO = TLC_FALSE
%openfile ioVarDimsDeclBuffer
%foreach argIdx=NumCanonicalInputArgDefs
%assign ci = CanonicalInputArgDef[argIdx]
%if SLibGetCanIOIsVarDims(ci)
%assign cdIdx = SLibGetCanDimSizeDWIdxForArg(ci)
%assign canDWork = CanonicalDWorkArgDef[cdIdx]
%if !checkAccess || FcnArgNeeded(canDWork, tid, isPeriodicRateGrouping)
%assign inputPortInfo = ci.SignalSrc
%assign u_str_idx = IDNUM(inputPortInfo[0])
%assign u_idx = u_str_idx[1]
%assign dwIdx = canDWork.FirstSignalSrc
%assign dwRec = DWorks.DWork[dwIdx]
%assign dataType = SLibGetRecordDataTypeName(dwRec, "")
%assign dwWidth = SLibDWorkWidth(dwRec)
%if dwWidth == 1
%<dataType> %<inportVarDimsNamePrefix>%<argIdx>;
%else
%<dataType> %<inportVarDimsNamePrefix>%<argIdx>[%<dwWidth>];
%endif
%endif
%assign hasVarDimsIO = TLC_TRUE
%endif
%endforeach
%foreach argIdx=NumCanonicalOutputArgDefs
%assign co = CanonicalOutputArgDef[argIdx]
%if SLibGetCanIOIsVarDims(co)
%assign cdwIdx = SLibGetCanDimSizeDWIdxForArg(co)
%assign canDWork = CanonicalDWorkArgDef[cdwIdx]
%if !checkAccess || FcnArgNeeded(canDWork, tid, isPeriodicRateGrouping)
%assign idx = co.RootOutputIdx
%assign dwIdx = canDWork.FirstSignalSrc
%assign dwRec = DWorks.DWork[dwIdx]
%assign dataType = SLibGetRecordDataTypeName(dwRec, "")
%assign dwWidth = SLibDWorkWidth(dwRec)
%if dwWidth == 1
%<dataType> %<outportVarDimsNamePrefix>%<argIdx>;
%else
%<dataType> %<outportVarDimsNamePrefix>%<argIdx>[%<dwWidth>];
%endif
%endif
%assign hasVarDimsIO = TLC_TRUE
%endif
%endforeach
%if hasVarDimsIO
%openfile ioVarDimsInitBuffer
%assign hasConstOutput = MdlRefHasConstantOutput()
%assign asyncTID = LibAsynchronousTriggeredTID(tid)
%if hasConstOutput && ...
((NumCanonicalInputArgDefs > 0) || (NumCanonicalOutputArgDefs > 0)) && ...
(::BlockFcn == "Output" || ::BlockFcn == "OutputUpdate") && ...
!asyncTID
if (%<::CompiledModel.GlobalScope.tTID> != CONSTANT_TID) {
%endif
%foreach argIdx=NumCanonicalInputArgDefs
%assign ci = CanonicalInputArgDef[argIdx]
%if SLibGetCanIOIsVarDims(ci)
%assign cdwIdx = SLibGetCanDimSizeDWIdxForArg(ci)
%assign canDWork = CanonicalDWorkArgDef[cdwIdx]
%if !checkAccess || FcnArgNeeded(canDWork, tid, isPeriodicRateGrouping)
%assign inputPortInfo = ci.SignalSrc
%assign u_str_idx = IDNUM(inputPortInfo[0])
%assign u_idx = u_str_idx[1]
%assign dwIdx = canDWork.FirstSignalSrc
%assign dwRec = DWorks.DWork[dwIdx]
%assign dataType = SLibGetRecordDataTypeName(dwRec, "")
%assign dwWidth = SLibDWorkWidth(dwRec)
/* Get current dimensions of input port %<u_idx> */
%assign sizeDWName = "%<inportVarDimsNamePrefix>%<argIdx>"
%assign eOffset = %<GetInputCurrentDimensions(DWorks.DWork[dwIdx].CGTypeIdx, sizeDWName, u_idx, 0)>
%endif
%endif
%endforeach
%foreach argIdx=NumCanonicalOutputArgDefs
%assign co = CanonicalOutputArgDef[argIdx]
%if SLibGetCanIOIsVarDims(co)
%assign cdwIdx = SLibGetCanDimSizeDWIdxForArg(co)
%assign canDWork = CanonicalDWorkArgDef[cdwIdx]
%if !checkAccess || FcnArgNeeded(canDWork, tid, isPeriodicRateGrouping)
%assign idx = co.RootOutputIdx
%assign dwIdx = canDWork.FirstSignalSrc
%assign dwRec = DWorks.DWork[dwIdx]
%assign dataType = SLibGetRecordDataTypeName(dwRec, "")
%assign dwWidth = SLibDWorkWidth(dwRec)
/* Get current dimensions of output port %<idx> */
%assign sizeDWName = "%<outportVarDimsNamePrefix>%<argIdx>"
%assign eOffset = %<GetOutputCurrentDimensions(DWorks.DWork[dwIdx].CGTypeIdx, sizeDWName, idx, 0)>
%endif
%endif
%endforeach
%if hasConstOutput && ...
((NumCanonicalInputArgDefs > 0) || (NumCanonicalOutputArgDefs > 0)) && ...
(::BlockFcn == "Output" || ::BlockFcn == "OutputUpdate") && ...
!asyncTID
}
%endif
%closefile ioVarDimsInitBuffer
%endif
%closefile ioVarDimsDeclBuffer
%return ["%<ioVarDimsDeclBuffer>", "%<ioVarDimsInitBuffer>"]
%endfunction
%function GetBlockInputCanDimSizeDWInterface(sysIdx, sysFcn, tid)
%assign inDWStr = ""
%assign thisSystem = System[sysIdx]
%assign currentTID = tid
%assign isPeriodicRateGrouping = SLibSystemFcnPeriodicRateGrouping(thisSystem, sysFcn)
%assign comma = ""
%assign inCounter = 0
%assign numInputs = ExternalInputs.NumExternalInputs
%foreach argIdx = NumCanonicalInputArgDefs
%assign idx = SLibGetModelRefRootInputIdx(sysIdx, argIdx)
%assign numZeroToAdd = idx - inCounter
%if numZeroToAdd > 0
%assign inDWStr = AppendZeroToString(inDWStr, comma, numZeroToAdd)
%assign comma = ", "
%endif
%assign inCounter = idx
%if SLibGetCanIOIsVarDims(CanonicalInputArgDef[argIdx]) && ...
FcnArgNeeded(CanonicalDWorkArgDef[SLibGetCanDimSizeDWIdxForArg(CanonicalInputArgDef[argIdx])], ...
currentTID,isPeriodicRateGrouping)
%assign inDWStr = "%<inDWStr>%<comma>1"
%else
%assign inDWStr = "%<inDWStr>%<comma>0"
%endif
%assign comma = ", "
%assign inCounter = inCounter + 1
%endforeach
%assign numZeroToAdd = numInputs - inCounter
%if numZeroToAdd > 0
%assign inDWStr = AppendZeroToString(inDWStr, comma, numZeroToAdd)
%assign comma = ", "
%endif
%assign inCounter = numInputs
%return "%<inDWStr>"
%endfunction
%function GetBlockOutputCanDimSizeDWInterface(sysIdx, sysFcn, tid)
%assign outDWStr = ""
%assign thisSystem = System[sysIdx]
%assign currentTID = tid
%assign isPeriodicRateGrouping = SLibSystemFcnPeriodicRateGrouping(thisSystem, sysFcn)
%assign comma = ""
%assign outCounter = 0
%assign numOutputs = ExternalOutputs.NumExternalOutputs
%foreach argIdx = NumCanonicalOutputArgDefs
%assign idx = SLibGetModelRefRootOutputIdx(sysIdx, argIdx)
%assign numZeroToAdd = idx - outCounter
%if numZeroToAdd > 0
%assign outDWStr = AppendZeroToString(outDWStr, comma, numZeroToAdd)
%assign comma = ", "
%endif
%assign outCounter = idx
%if SLibGetCanIOIsVarDims(CanonicalOutputArgDef[argIdx]) && ...
FcnArgNeeded(CanonicalDWorkArgDef[SLibGetCanDimSizeDWIdxForArg(CanonicalOutputArgDef[argIdx])], ...
currentTID,isPeriodicRateGrouping)
%assign outDWStr = "%<outDWStr>%<comma>1"
%else
%assign outDWStr = "%<outDWStr>%<comma>0"
%endif
%assign comma = ", "
%assign outCounter = outCounter + 1
%endforeach
%assign numZeroToAdd = numOutputs - outCounter
%if numZeroToAdd > 0
%assign outDWStr = AppendZeroToString(outDWStr, comma, numZeroToAdd)
%assign comma = ", "
%endif
%assign outCounter = numOutputs
%return "%<outDWStr>"
%endfunction
%function AppendModelReferenceRegFcnInputCanDimSizeDWArgs(idx, currentTID, ...
isPeriodicRateGrouping, recArgs)
%if SLibGetCanIOIsVarDims(CanonicalInputArgDef[idx])
%assign ci = CanonicalInputArgDef[idx]
%assign cdwIdx = SLibGetCanDimSizeDWIdxForArg(ci)
%assign canDWork = CanonicalDWorkArgDef[cdwIdx]
%if FcnArgNeeded(canDWork, currentTID, isPeriodicRateGrouping)
%assign dwIdx = canDWork.FirstSignalSrc
%assign dwRec = ::CompiledModel.DWorks.DWork[dwIdx]
%assign dwWidth = SLibDWorkWidth(dwRec)
%assign identi = LibGetRecordIdentifier(canDWork)
%assign dataType = SLibGetRecordDataTypeName(dwRec, "")
%if dwWidth > 1
%assign argDef = "const " + dataType + " " + identi + "[%<dwWidth>]"
%else
%assign argDef = "const " + dataType + " *" + identi
%endif
%assign recArgs = recArgs + argDef
%endif
%endif
%return recArgs
%endfunction
%function AppendModelReferenceRegFcnOutputCanDimSizeDWArgs(idx, currentTID, ...
isPeriodicRateGrouping, recArgs)
%if SLibGetCanIOIsVarDims(CanonicalOutputArgDef[idx])
%assign co = CanonicalOutputArgDef[idx]
%assign cdwIdx = SLibGetCanDimSizeDWIdxForArg(co)
%assign canDWork = CanonicalDWorkArgDef[cdwIdx]
%if FcnArgNeeded(canDWork, currentTID, isPeriodicRateGrouping)
%assign dwIdx = canDWork.FirstSignalSrc
%assign dwRec = ::CompiledModel.DWorks.DWork[dwIdx]
%assign dwWidth = SLibDWorkWidth(dwRec)
%assign identi = LibGetRecordIdentifier(canDWork)
%assign dataType = SLibGetRecordDataTypeName(dwRec, "")
%if dwWidth > 1
%assign argDef = dataType + " " + identi + "[%<dwWidth>]"
%else
%assign argDef = dataType + " *" + identi
%endif
%endif
%endif
%return recArgs
%endfunction
%function SLibGetDimsFromIF(block, portIdx, kind) void
%return SLibInvokeTLCInterface(block, kind, portIdx, 0, TLC_FALSE, ...
"", "", 0, "")
%endfunction
%function SLibGetInputCanDimSizeDWForFunctionStr(block, portIdx, fcnInfo, ...
sysFcnName) void
%assign arg = []
%assign canInDWorkInfo = fcnInfo.InDimSizeDW
%if canInDWorkInfo[portIdx] > 0
%<SLibGetDimsFromIF(block, portIdx, "InputDims")>
%assign baseSystemIdx = GetBaseSystemIdx()
%assign baseSystem = ::CompiledModel.System[baseSystemIdx]
%assign dataPort = block.DataInputPort[portIdx]
%assert SLibGetArgIsVarDims(dataPort)
%if SLibGetArgUseCanDimSizeDW(dataPort)
%assign ownerSysIdx = block.BlockIdx[1]
%assign currentTID = ::CompiledModel.System[ownerSysIdx].CurrentTID
%assign cdwIdx = SLibGetCanDimSizeDWIdxForArg(dataPort)
%if sysFcnName == "RegistrationFcn"
%if ISFIELD(baseSystem.Interface,"CanonicalDWorkArgDef")
%assign canDWork = baseSystem.Interface.CanonicalDWorkArgDef[cdwIdx]
%assign arg = "%<LibGetRecordIdentifier(canDWork)>"
%<SLibAccessArgHelper(canDWork, "", currentTID)>
%else
%assign cdwIdx = dataPort.DimSizeDWorkMR
%assign cross = baseSystem.CrossNoArgFcnBound
%assign arg = ...
"%<SLibGetDimSizeDWorkFullPathForFcnArg(cdwIdx, baseSystemIdx, cross)>"
%<SLibAccessArgHelper(baseSystem.Interface.DWorkArgDef,"","")>
%endif
%else
%assign hstructSysIdx = ...
::CompiledModel.System[BlockIdx[1]].HStructDeclSystemIdx
%assign interface = ::CompiledModel.System[hstructSysIdx].Interface
%assign canDWork = interface.CanonicalDWorkArgDef[cdwIdx]
%if System[BlockIdx[1]].CrossNoArgFcnBound
%assign arg = "%<canDWork.GlobalIdentifier>"
%<SLibAccessArgHelper(canDWork, "Global", currentTID)>
%else
%assign arg = "%<LibGetRecordIdentifier(canDWork)>"
%endif
%<SLibAccessArgHelper(canDWork, "", currentTID)>
%endif
%else
%assert SLibGetArgUseSharedDimSizeDW(dataPort)
%assign blkSysIdx = ::CompiledModel.System[BlockIdx[1]].SystemIdx
%assign dwIdx = dataPort.DimSizeDWork
%assign cross = ::CompiledModel.System[blkSysIdx].CrossNoArgFcnBound
%assign arg = ...
"%<SLibGetDimSizeDWorkFullPathForFcnArg(dwIdx, blkSysIdx, cross)>"
%if sysFcnName == "RegistrationFcn"
%<SLibAccessArgHelper(baseSystem.Interface.DWorkArgDef,"","")>
%else
%assign hstructSysIdx = ...
::CompiledModel.System[BlockIdx[1]].HStructDeclSystemIdx
%assign hstructSys = ::CompiledModel.System[hstructSysIdx]
%assign dwArgDef = hstructSys.Interface.DWorkArgDef
%<SLibAccessArgHelper(dwArgDef, "", hstructSys.CurrentTID)>
%endif
%endif
%endif
%return arg
%endfunction
%function SLibGetOutputCanDimSizeDWForFunctionStr(block, portIdx, fcnInfo, ...
sysFcnName) void
%assign arg = []
%assign canOutDWorkInfo = fcnInfo.OutDimSizeDW
%if canOutDWorkInfo[portIdx] > 0
%<SLibGetDimsFromIF(block, portIdx, "OutputDims")>
%assign baseSystemIdx = GetBaseSystemIdx()
%assign baseSystem = ::CompiledModel.System[baseSystemIdx]
%assign dataPort = block.DataOutputPort[portIdx]
%if SLibGetArgUseCanDimSizeDW(dataPort)
%assign cdwIdx = SLibGetCanDimSizeDWIdxForArg(dataPort)
%if sysFcnName == "RegistrationFcn"
%assign canDWork = baseSystem.Interface.CanonicalDWorkArgDef[cdwIdx]
%else
%assign blkSysIdx = System[BlockIdx[1]].HStructDeclSystemIdx
%assign interface = System[blkSysIdx].Interface
%assign canDWork = interface.CanonicalDWorkArgDef[cdwIdx]
%endif
%assign currentTID = ::CompiledModel.System[BlockIdx[1]].CurrentTID
%if System[BlockIdx[1]].CrossNoArgFcnBound
%assign arg = "%<canDWork.GlobalIdentifier>"
%<SLibAccessArgHelper(canDWork, "Global", currentTID)>
%else
%assign arg = "%<LibGetRecordIdentifier(canDWork)>"
%endif
%<SLibAccessArgHelper(canDWork,"",currentTID)>
%elseif SLibGetArgUseSharedDimSizeDW(dataPort)
%assign blkSysIdx = ::CompiledModel.System[BlockIdx[1]].SystemIdx
%assign cross = ::CompiledModel.System[blkSysIdx].CrossNoArgFcnBound
%assign dwIdx = dataPort.DimSizeDWork
%assign arg = ...
"%<SLibGetDimSizeDWorkFullPathForFcnArg(dwIdx, blkSysIdx, cross)>"
%if sysFcnName == "RegistrationFcn"
%assign dworkArgDef = baseSystem.Interface.DWorkArgDef
%<SLibAccessArgHelper(dworkArgDef, "", currentTID)>
%endif
%endif
%endif
%return arg
%endfunction
%function SetOutputCurrentDimensions(cgTypeId, src, outIdx, startOffset) Output
%assign eOffset = startOffset
%with CGTypes
%if LibCGTypeIsStruct(cgTypeId)
%foreach idxE = LibCGTypeNumMembers(cgTypeId)
%assign eName = LibCGTypeMemberName(cgTypeId, idxE)
%assign eDTypeId = LibCGTypeMemberCGTypeIdx(cgTypeId, idxE)
%assign eOffset = %<SetOutputCurrentDimensions(eDTypeId, src+"."+eName, outIdx, eOffset)>
%endforeach
%else
%if LibCGTypeIsMatrix(cgTypeId)
%assign eWidth = LibCGTypeWidth(cgTypeId)
%foreach dimIdx = eWidth
ssSetCurrentOutputPortDimensions(S, %<outIdx>, %<eOffset>, (int)%<src>[%<dimIdx>]);
%assign eOffset = eOffset + 1
%endforeach
%else
ssSetCurrentOutputPortDimensions(S, %<outIdx>, %<eOffset>, (int)%<src>);
%assign eOffset = eOffset + 1
%endif
%endif
%endwith
%return %<eOffset>
%endfunction
%function SLibGenOutportCurrentDimsWrites(sysFcn, cTID, isRG) Output
%assign baseSysIdx = GetBaseSystemIdx()
%with System[baseSysIdx]
%with Interface
%foreach argIdx = NumCanonicalOutputArgDefs
%if SLibGetCanIOIsVarDims(CanonicalOutputArgDef[argIdx])
%assign idx = CanonicalOutputArgDef[argIdx].RootOutputIdx
%assign cdwIdx = SLibGetCanDimSizeDWIdxForArg(CanonicalOutputArgDef[argIdx])
%if SysFcnArgNeeded(sysFcn, CanonicalDWorkArgDef[cdwIdx], cTID, isRG)
%assign dwIdx = CanonicalDWorkArgDef[cdwIdx].FirstSignalSrc
%assign dwRec = DWorks.DWork[dwIdx]
%assign dwWidth = SLibDWorkWidth(dwRec)
/* Set current dimensions for output port %<idx> */
%assign sizeDWName = "OutVarDims_%<argIdx>"
%assign eOffset = %<SetOutputCurrentDimensions(DWorks.DWork[dwIdx].CGTypeIdx, sizeDWName, idx, 0)>
%endif
%endif
%endforeach
%endwith
%endwith
%endfunction
%endif