%% $RCSfile: smatrxcat.ttlc,v $ %% File : smatrxcat.tlc generated from smatrxcat.ttlc revsion 1.3 %% $Date: 2000/08/09 14:48:37 $ %% %% Steve Conahan %% Copyright 1990-2000 The MathWorks, Inc. %% %% Abstract: Matrix Concatenation %% %implements smatrxcat "Ada" %% Function: BlockInstanceSetup =============================================== %% %% Abstract: %% Rename the S-Function parameters for easy reference. %% %function BlockInstanceSetup(block, system) void %% %assign OUTPORT = 0 %assign OUT_COMPLEX = LibBlockOutputSignalIsComplex(OUTPORT) %assign dTypeId = LibBlockOutputSignalDataTypeId(0) %if OUT_COMPLEX %assign OUT_DTYPE_NAME = "%" %else %assign OUT_DTYPE_NAME = "%" %endif %% %assign HORIZONTAL = 1 %assign CAT_METHOD = SFcnParamSettings.CatMethod %% %if (CAT_METHOD == HORIZONTAL) %% Number of ROWS is constant for all input and output ports %assign outDims = LibBlockOutputSignalDimensions(OUTPORT) %assign CONST_HORIZROWS_OR_VERTCOLS = outDims[0] %else %% Number of COLUMNS is constant for all input and output ports %assign numOutDims = LibBlockOutputSignalNumDimensions(OUTPORT) %assign outDims = LibBlockOutputSignalDimensions(OUTPORT) %assign CONST_HORIZROWS_OR_VERTCOLS = (numOutDims == 2) ? outDims[1] : 1 %endif %% (CAT_METHOD == HORIZONTAL) %% %% If the output is complex, determine if ALL inputs are complex %% (for code generation optimizations). %% %if OUT_COMPLEX %assign realInputDetected = 0 %foreach inpCnt = NumDataInputPorts %assign realInputDetected = ... realInputDetected || ( !LibBlockInputSignalIsComplex(inpCnt) ) %endforeach %else %assign realInputDetected = 1 %endif %% OUT_COMPLEX %% %if realInputDetected %assign ALL_INPUTS_COMPLEX = 0 %else %assign ALL_INPUTS_COMPLEX = 1 %endif %% realInputDetected %% %% NOTE: The following only works for SL built-in types %% (i.e. not for custom types) %assign outDtypeId = LibBlockOutputSignalDataTypeId(OUTPORT) %assign numBytesPerRealElmt = SLibGetDataTypeSizeFromId(outDtypeId) %assign numBytesPerCplxElmt = 2 * numBytesPerRealElmt %% %assign block = block + OUTPORT + OUT_COMPLEX + OUT_DTYPE_NAME + ... outDims + numBytesPerRealElmt + numBytesPerCplxElmt %assign block = block + HORIZONTAL + CAT_METHOD %assign block = block + CONST_HORIZROWS_OR_VERTCOLS + ALL_INPUTS_COMPLEX %endfunction %% BlockInstanceSetup %% Function: Outputs ========================================================== %% %function Outputs(block, system) Output %% -- Matrix Concatenation: % %if (NumDataInputPorts > 1) %if (CAT_METHOD == HORIZONTAL) % %else % %endif %% (CAT_METHOD == HORIZONTAL) %else % %endif %% (NumDataInputPorts > 1) %endfunction %% Outputs %% Function: GenerateCopyCode ============================================= %% %function GenerateCopyCode(block) Output %% %% One input port - check and see if we share I/O or not %% %assign in_place = (LibBlockInputSignalBufferDstPort(0) == OUTPORT) %% %if in_place -- No code required: input port and output port buffers shared. %else %if OUT_COMPLEX -- One input, complex, data type: %. %else -- One input, real, data type: %. %endif %% OUT_COMPLEX %% -- [%x%] %assign u = LibBlockInputSignalAddr(0, "", "", 0) %assign y = LibBlockOutputSignalAddr(0, "", "", 0) % := %; %endif %% in_place %endfunction %% GenerateCopyCode %% Function: GenerateHorizCatCode ============================================= %% %function GenerateHorizCatCode(block) Output %% %% There are two cases to consider: %% %% Easy case (all inputs same complexity) -> %% Render a series of array slice assignment (no loops required). %% %% Mixed case (some inputs real, some inputs complex) -> %% Render a combination of either array slice assignment %% statements, or loops based on input port complexity. Worst case %% for N-1 ports real and 1 port complex is that we render %% N-1 for-loops. Must check each input complexity as we go. %% %if !OUT_COMPLEX || ALL_INPUTS_COMPLEX % %else % %endif %endfunction %% GenerateHorizCatCode %% Function: GenerateVertCatCode ============================================== %% %function GenerateVertCatCode(block) Output %% %% Vertical Concatenation: %% %% There are two cases to consider: %% %% Easier case -> All inputs same complexity. %% Mixed case -> Some inputs real, some inputs complex. %% %if !OUT_COMPLEX || ALL_INPUTS_COMPLEX % %else % %endif %endfunction %% GenerateVertCatCode %% Function: GenHorizCatSameComplexity ======================================== %% %function GenHorizCatSameComplexity(block) Output %if OUT_COMPLEX -- Horizontal matrix concatenation, ... -- % inputs, complex, data type: %. %else -- Horizontal matrix concatenation, -- % inputs, real, data type: %. %endif %% OUT_COMPLEX %% %assign y = LibBlockOutputSignalAddr(0, "", "", 0) %assign yWidth = LibBlockOutputSignalWidth(0) declare Out_Array : %_Array(0 .. %); for Out_Array'Address use %'Address; %foreach portNum = NumDataInputPorts %assign iAddr = LibBlockInputSignalAddr(portNum, "", "", 0) %assign iWidth = DataInputPort[portNum].Width In% : %_Array(0 .. %); for In%'Address use %'Address; %endforeach begin %% %assign outIndex = 0 %foreach portNum = NumDataInputPorts %assign inDims = LibBlockInputSignalDimensions(portNum) %assign colDim = LibBlockInputSignalWidth(portNum) / inDims[0] %assign iWidthMinusOne = DataInputPort[portNum].Width-1 %if iWidthMinusOne == 0 Out_Array(%) := In%(0); \ %else Out_Array(%..%) := ... In%(0..%); \ %endif -- Input %: [%x%] %assign outIndex = outIndex + iWidthMinusOne + 1 %endforeach end; %% %endfunction %% GenHorizCatSameComplexity %% Function: GenHorizCatDifferentComplexity =================================== %% %function GenHorizCatDifferentComplexity(block) Output %assign dTypeId = LibBlockOutputSignalDataTypeId(0) %assign ELEMENT_DTYPE_NAME = "%" %assign zero = SLibGetFormattedValueFromId(dTypeId, 0) -- Horizontal matrix concatenation, -- % inputs, real and complex, ... data type: %. %% %assign y = LibBlockOutputSignalAddr(0, "", "", 0) %assign yWidth = LibBlockOutputSignalWidth(0) declare Out_Array : %_Array(0 .. %); for Out_Array'Address use %'Address; %foreach portNum = NumDataInputPorts %assign iAddr = LibBlockInputSignalAddr(portNum, "", "", 0) %assign iWidth = DataInputPort[portNum].Width %assign isComplex = LibBlockInputSignalIsComplex(portNum) %if isComplex %assign dTypeName = OUT_DTYPE_NAME %else %assign dTypeName = ELEMENT_DTYPE_NAME %endif In% : %_Array(0 .. %); for In%'Address use %'Address; %endforeach begin %% %assign outIndex = 0 %foreach portNum = NumDataInputPorts %assign isComplex = LibBlockInputSignalIsComplex(portNum) %assign iWidthMinusOne = DataInputPort[portNum].Width-1 %assign inDims = LibBlockInputSignalDimensions(portNum) %assign colDim = LibBlockInputSignalWidth(portNum) / inDims[0] %if isComplex %if iWidthMinusOne == 0 -- Input %: complex scalar, copy array element Out_Array(%) := In%(0); %else -- Input %: [%x%] complex, ... copy array slice %if outIndex == 0 Out_Array(0..%) := ... In%(0..%); %else Out_Array(%..%) := ... In%(0..%); %endif %endif %else %if iWidthMinusOne == 0 -- Input %: scalar real, ... zeroize imaginary part of output element Out_Array(%) := (In%(0), %); %else -- Input %: [%x%] real, ... zeroize imaginary part of output element for I in 0 .. % loop %if outIndex == 0 Out_Array(I) := (In%(I), %); %else Out_Array(%+I) := (In%(I), %); %endif end loop; %endif %endif %assign outIndex = outIndex + iWidthMinusOne + 1 %endforeach end; %% %endfunction %% GenHorizCatDifferentComplexity %% Function: GenVertCatSameComplexity ======================================== %% %function GenVertCatSameComplexity(block) Output %if OUT_COMPLEX -- Vertical matrix concatenation, -- % inputs, complex, data type: %. %else -- Vertical matrix concatenation, -- % inputs, real, data type: %. %endif %% OUT_COMPLEX %% %if (CONST_HORIZROWS_OR_VERTCOLS > 1) %assign y = LibBlockOutputSignalAddr(0, "", "", 0) %assign yWidth = LibBlockOutputSignalWidth(0) %assign outDims = DataOutputPort.Dimensions declare Out_Array : %_Array(0 .. %); for Out_Array'Address use %'Address; %foreach portNum = NumDataInputPorts %assign iAddr = LibBlockInputSignalAddr(portNum, "", "", 0) %assign iWidth = DataInputPort[portNum].Width In% : %_Array(0 .. %); for In%'Address use %'Address; %endforeach Out_Index_Base, Out_Index, In_Index : integer; begin %assign cumulativeRows = 0 for I in 0 .. % loop Out_Index_Base := I*%; %foreach portNum = NumDataInputPorts %assign inDims = LibBlockInputSignalDimensions(portNum) %assign colDim = LibBlockInputSignalWidth(portNum) / inDims[0] %% %% Out_Index = (Ith Column) * (# of rows in Out_Array) %% + (rolling count of # rows in In_Matrices) %% %% Starting index into Input Array = %% (Ith column) * (number of rows in In_Matrices) %% %if cumulativeRows == 0 Out_Index := Out_Index_Base; %else Out_Index := Out_Index_Base+%; %endif %if inDims[0] == 1 In_Index := I; %else In_Index := I*%; %endif %% Update cumativeRows with Input Array row dimension %assign cumulativeRows = cumulativeRows + inDims[0] %% %% Offset of range is the number of rows on the Ith Input Array %% minus one (ie: rows-1) %% %assign rangeOffset = inDims[0] - 1 %assign comment = "-- Input %: [%x%]" %if rangeOffset == 0 Out_Array(Out_Index) := In%(In_Index); % %else Out_Array(Out_Index .. Out_Index+%) := ... In%(In_Index .. In_Index+%); % %endif %endforeach end loop; end; %else %assign y = LibBlockOutputSignalAddr(0, "", "", 0) %assign yWidth = LibBlockOutputSignalWidth(0) declare Out_Array : %_Array(0 .. %); for Out_Array'Address use %'Address; %foreach portNum = NumDataInputPorts %assign iAddr = LibBlockInputSignalAddr(portNum, "", "", 0) %assign iWidth = DataInputPort[portNum].Width In% : %_Array(0 .. %); for In%'Address use %'Address; %endforeach begin %assign outIndex = 0 %foreach portNum = NumDataInputPorts %assign iWidthMinusOne = DataInputPort[portNum].Width-1 %assign inDims = LibBlockInputSignalDimensions(portNum) %assign colDim = LibBlockInputSignalWidth(portNum) / inDims[0] %assign comment = "-- Input %: [%x%]" %if iWidthMinusOne == 0 Out_Array(%) := In%(0); % %else Out_Array(% .. %) := ... In%(0 .. %); % %endif %assign outIndex = outIndex + iWidthMinusOne + 1 %endforeach end; %endif %endfunction %% GenVertCatSameComplexity %% Function: GenVertCatDifferentComplexity ==================================== %% %function GenVertCatDifferentComplexity(block) Output %assign dTypeId = LibBlockOutputSignalDataTypeId(0) %assign zero = SLibGetFormattedValueFromId(dTypeId, 0) %assign ELEMENT_DTYPE_NAME = "%" -- Vertical matrix concatenation, -- % inputs, real and complex, ... data type: %. %if (CONST_HORIZROWS_OR_VERTCOLS > 1) %assign y = LibBlockOutputSignalAddr(0, "", "", 0) %assign yWidth = LibBlockOutputSignalWidth(0) %assign outDims = DataOutputPort.Dimensions declare Out_Array : %_Array(0 .. %); for Out_Array'Address use %'Address; %foreach portNum = NumDataInputPorts %assign iAddr = LibBlockInputSignalAddr(portNum, "", "", 0) %assign iWidth = DataInputPort[portNum].Width %assign isComplex = LibBlockInputSignalIsComplex(portNum) %if isComplex %assign dTypeName = OUT_DTYPE_NAME %else %assign dTypeName = ELEMENT_DTYPE_NAME %endif In% : %_Array(0 .. %); for In%'Address use %'Address; %endforeach Out_Index_Base, Out_Index, In_Index : integer; begin %assign cumulativeRows = 0 for I in 0 .. % loop Out_Index_Base := I*%; %foreach portNum = NumDataInputPorts %assign inDims = LibBlockInputSignalDimensions(portNum) %assign colDim = LibBlockInputSignalWidth(portNum) / inDims[0] %% %% Out_Index = (Ith Column) * (# of rows in Out_Array) %% + (rolling count of # rows in In_Matrices) %% %% Starting index into Input Array = %% (Ith column) * (number of rows in In_Matrices) %if cumulativeRows == 0 Out_Index := Out_Index_Base; %else Out_Index := Out_Index_Base+%; %endif %if inDims[0] == 1 In_Index := I; %else In_Index := I*%; %endif %% Update cumativeRows with Input Array row dimension %assign cumulativeRows = cumulativeRows + inDims[0] %% Offset of range is the number of rows on the Ith Input Array %% minus one (ie: rows-1) %% %assign rangeOffset = inDims[0] - 1 %assign isComplex = LibBlockInputSignalIsComplex(portNum) %if isComplex %if rangeOffset == 0 -- Input %: complex scalar, copy array element Out_Array(Out_Index) := In%(In_Index); %else %assign dimStr = "[%x%]" -- Input %: % complex, copy array slice Out_Array(Out_Index .. Out_Index+%) := ... In%(In_Index .. In_Index+%); %endif %else %if rangeOffset == 0 -- Input %: real scalar, copy array element Out_Array(Out_Index) := (In%(In_Index), %); %else %assign dimStr = "[%x%]" -- Input %: % real, ... zeroize imaginary part of output element for I in 0 .. % loop Out_Array(Out_Index+I) := (In%(In_Index+I), %); end loop; %endif %endif %endforeach end loop; end; %else %assign y = LibBlockOutputSignalAddr(0, "", "", 0) %assign yWidth = LibBlockOutputSignalWidth(0) declare Out_Array : %_Array(0 .. %); for Out_Array'Address use %'Address; %foreach portNum = NumDataInputPorts %assign iAddr = LibBlockInputSignalAddr(portNum, "", "", 0) %assign iWidth = DataInputPort[portNum].Width %assign isComplex = LibBlockInputSignalIsComplex(portNum) %if isComplex %assign dTypeName = OUT_DTYPE_NAME %else %assign dTypeName = ELEMENT_DTYPE_NAME %endif In% : %_Array(0 .. %); for In%'Address use %'Address; %endforeach begin %assign outIndex = 0 %foreach portNum = NumDataInputPorts %assign isComplex = LibBlockInputSignalIsComplex(portNum) %assign iWidthMinusOne = DataInputPort[portNum].Width-1 %assign inDims = LibBlockInputSignalDimensions(portNum) %assign colDim = LibBlockInputSignalWidth(portNum) / inDims[0] %if isComplex %if iWidthMinusOne == 0 -- Input %: complex scalar, copy array element Out_Array(%) := In%(0); %else %assign dimStr = "[%x%]" -- Input %: % complex, copy array slice Out_Array(% .. %) := ... In%(0 .. %); %endif %else %if iWidthMinusOne == 0 -- Input %: real scalar, copy array element Out_Array(%) := (In%(0), %); %else %assign dimStr = "[%x%]" -- Input %: % real, ... zeroize imaginary part of output element for I in 0 .. % loop %if outIndex == 0 Out_Array(I) := (In%(I), %); %else Out_Array(%+I) := (In%(I), %); %endif end loop; %endif %endif %assign outIndex = outIndex + iWidthMinusOne + 1 %endforeach end; %endif %endfunction %% GenVertCatDifferentComplexity %% [EOF] smatrxcat.ttlc