%% $RCSfile: sdspzpad2.tlc,v $ %% $Revision: 1.4 $ %% $Date: 2000/07/31 22:11:35 $ %% %% Copyright (c) 1995-1999 The MathWorks, Inc. %% %% Abstract: zero pad %implements sdspzpad2 "C" %% Function: BlockInstanceSetup =============================================== %% %function BlockInstanceSetup(block, system) void %% %assign INPORT = 0 %assign NUM_INP_DIMS = LibBlockInputSignalNumDimensions(INPORT) %assign INPUT_DIMS = LibBlockInputSignalDimensions( INPORT) %% %assign OUTPORT = 0 %assign NUM_OUT_DIMS = LibBlockOutputSignalNumDimensions(OUTPORT) %assign OUTPUT_DIMS = LibBlockOutputSignalDimensions( OUTPORT) %assign COMPLEX = LibBlockOutputSignalIsComplex( OUTPORT) %assign DTYPE_NAME = LibBlockOutputSignalDataTypeName( OUTPORT,"%") %assign DTYPE_ID = LibBlockOutputSignalDataTypeId( OUTPORT) %% %assign BYTES_PER_ELEMENT = (1 + COMPLEX) * SLibGetDataTypeSizeFromId(DTYPE_ID) %% %assign TRUNCATE_ERR_MODE = SFcnParamSettings.TruncErrMode %assign IGNORE_TRUNCATE = 1 %assign WARN_ON_TRUNCATE = 2 %assign ERROR_ON_TRUNCATE = 3 %% %assign TRUNC_WARNING_MSG_STR = "Input signal has been truncated by Zero Pad block." %assign TRUNC_ERROR_MSG_STR = "Input signal truncation will occur." %% %assign block = block + INPORT + OUTPORT + DTYPE_NAME + DTYPE_ID + COMPLEX %assign block = block + BYTES_PER_ELEMENT + NUM_OUT_DIMS + NUM_INP_DIMS %assign block = block + OUTPUT_DIMS + INPUT_DIMS %assign block = block + TRUNCATE_ERR_MODE + IGNORE_TRUNCATE %assign block = block + WARN_ON_TRUNCATE + ERROR_ON_TRUNCATE %assign block = block + TRUNC_WARNING_MSG_STR + TRUNC_ERROR_MSG_STR %% %endfunction %% BlockInstanceSetup %% Function: Outputs ========================================================== %% %function Outputs(block, system) Output /* DSP Blockset Zero Pad (%) - % */ %% %% Only generate code if output buffer does not share the input buffer space. %% %assign need_copy = (LibBlockInputSignalBufferDstPort(INPORT) != OUTPORT) %% %if need_copy %% %% %if COMPLEX /* Data type %: % bytes per each (complex) element */ %else /* Data type %: % bytes per each (real) element */ %endif %% %% %if (NUM_OUT_DIMS == 2) % %else % %endif %% NUM_OUT_DIMS (2-D vs. 1-D code gen choices) %% %% %else /* * Zero-pad output width is identical to input width, and * the output buffer shares space with the input buffer. * Therefore, there's no code required to perform zero-pad. */ %endif %%need_copy %endfunction %% Outputs %% Function: Generate1DCode ==================================================== %% %function Generate1DCode(block) Output %% %% 1-D OUTPUT -> 1-D INPUT ALSO %% %assign INP_WIDTH = INPUT_DIMS[0] %assign OUT_WIDTH = OUTPUT_DIMS[0] %% /* Input width: %, output width: % */ %if (INP_WIDTH >= OUT_WIDTH) %% %% 1-D COPY ONLY (POSSIBLE TRUNCATION OF INPUT) %% %if (INP_WIDTH == OUT_WIDTH) /* Copy input to output (output width is equal to input width) */ %else %if (TRUNCATE_ERR_MODE == WARN_ON_TRUNCATE) %warning % %elseif (TRUNCATE_ERR_MODE == ERROR_ON_TRUNCATE) %error % %endif /* Truncation of input (output width is less than input width) */ %endif %% memcpy( (byte_T *)%, \ (byte_T *)%, \ % ); %% %else %% %% 1-D COPY AND ZERO PAD %% /* Copy inputs to outputs */ memcpy( (byte_T *)%, \ (byte_T *)%, \ % ); /* Zero pad remaining outputs */ { register int_T idx; %if COMPLEX % zero[2]; zero[0] = %; zero[1] = zero[0]; %else const % zero[1] = {%}; %endif for (idx = 0; idx < %; idx++) { memcpy( (byte_T *)% + \ (% + idx) * %,\ (byte_T *)zero, % ); } } %% %endif %% (INP_WIDTH >= OUT_WIDTH) %endfunction %% Generate1DCode %% Function: Generate2DCode ==================================================== %% %function Generate2DCode(block) Output %% %assign NUM_INP_ROWS = INPUT_DIMS[0] %assign NUM_INP_COLS = (NUM_INP_DIMS == 2) ? INPUT_DIMS[1] : 1 %assign NUM_OUT_ROWS = OUTPUT_DIMS[0] %assign NUM_OUT_COLS = OUTPUT_DIMS[1] %% /* Input dimensions: [% x %], output dimensions: [% x %] */ %if ( (NUM_INP_ROWS == NUM_OUT_ROWS) && (NUM_OUT_COLS == NUM_INP_COLS) ) %% %% Degenerate case: just copy inputs to outputs %% %assign OUT_WIDTH = NUM_OUT_ROWS * NUM_OUT_COLS %% memcpy( (byte_T *)%, \ (byte_T *)%, \ % ); %% %else %% %assign block = block + NUM_OUT_ROWS + NUM_OUT_COLS + NUM_INP_ROWS + NUM_INP_COLS %% %if ( (NUM_OUT_ROWS < NUM_INP_ROWS) || (NUM_OUT_COLS < NUM_INP_COLS) ) %% %% Input truncation case: either (or both) rows or cols truncated %% % %% %else %% %% General case: both copy input to output and zero pad output (no truncation) %% % %% %endif %% Truncated vs. general purpose code %endif %% All input/output truncate or not cases %endfunction %% Generate2DCode %% Function: Generate2DInputTruncationCode ===================================== %% %function Generate2DInputTruncationCode(block) Output %% %if (TRUNCATE_ERR_MODE == WARN_ON_TRUNCATE) %warning % %elseif (TRUNCATE_ERR_MODE == ERROR_ON_TRUNCATE) %error % %endif %% /* Note truncation of input dimensions */ %if ( (NUM_OUT_ROWS <= NUM_INP_ROWS) && (NUM_OUT_COLS <= NUM_INP_COLS) ) %% %% Truncate BOTH rows and columns %% %assign bytesPerOutputCol = NUM_OUT_ROWS * BYTES_PER_ELEMENT %assign bytesPerInputCol = NUM_INP_ROWS * BYTES_PER_ELEMENT %% { byte_T *u = (byte_T *)%; byte_T *y = (byte_T *)%; %% %if (NUM_OUT_COLS > 1) register int_T colIdx; for (colIdx = 0; colIdx < %; colIdx++) { %endif %% (NUM_OUT_COLS > 1) %% memcpy(y, u, %); %% %if (NUM_OUT_COLS > 1) u += %; y += %; } %endif %% (NUM_OUT_COLS > 1) %% } %elseif (NUM_OUT_ROWS < NUM_INP_ROWS) %% %% Truncate number of rows only %% %assign bytesPerOutputCol = NUM_OUT_ROWS * BYTES_PER_ELEMENT %assign bytesPerInputCol = NUM_INP_ROWS * BYTES_PER_ELEMENT %% { byte_T *u = (byte_T *)%; byte_T *y = (byte_T *)%; %% %if (NUM_INP_COLS > 1) register int_T colIdx; for (colIdx = 0; colIdx < %; colIdx++) { %endif %% (NUM_INP_COLS > 1) memcpy(y, u, %); %if (NUM_INP_COLS > 1) u += %; y += %; } %endif %% %% Pad any extra columns with zeros %% %if (NUM_OUT_COLS > NUM_INP_COLS) { register int_T rowIdx; %if COMPLEX % zero[2]; zero[0] = %; zero[1] = zero[0]; %else const % zero[1] = {%}; %endif for (rowIdx = 0; rowIdx < %<(NUM_OUT_COLS - NUM_INP_COLS) * NUM_OUT_ROWS>; rowIdx++) { memcpy( y + (rowIdx * %),\ (byte_T *)zero, % ); } } %endif %% } %else %% Case: (NUM_OUT_COLS < NUM_INP_COLS) only %% %% Truncate number of cols only %% %assign bytesPerInputCol = NUM_INP_ROWS * BYTES_PER_ELEMENT %% { byte_T *u = (byte_T *)%; byte_T *y = (byte_T *)%; %% %if (NUM_OUT_COLS > 1) register int_T colIdx; for (colIdx = 0; colIdx < %; colIdx++) { %endif %% (NUM_OUT_COLS > 1) %% memcpy(y, u, %); %% %if (NUM_OUT_COLS > 1) u += %; %endif %% (NUM_OUT_COLS > 1) %% y += %; %% %assign numOutColBytesZeroPad = (NUM_OUT_ROWS - NUM_INP_ROWS) * BYTES_PER_ELEMENT %% %if (numOutColBytesZeroPad > 0) { register int_T rowIdx; %if COMPLEX % zero[2]; zero[0] = %; zero[1] = zero[0]; %else const % zero[1] = {%}; %endif for (rowIdx = 0; rowIdx < %; rowIdx++) { memcpy( y, (byte_T *)zero, % ); y += %; } } %endif %% %if (NUM_OUT_COLS > 1) } %endif %% (NUM_OUT_COLS > 1) %% } %endif %% Various row/column truncation cases %endfunction %% Generate2DInputTruncationCode %% Function: Generate2DGeneralPurposeCode ====================================== %% %function Generate2DGeneralPurposeCode(block) Output %% %assign bytesPerInputCol = NUM_INP_ROWS * BYTES_PER_ELEMENT %% %if (NUM_INP_ROWS == NUM_OUT_ROWS) { byte_T *u = (byte_T *)%; byte_T *y = (byte_T *)%; memcpy(y, u, %); y += %; { register int_T rowIdx; %if COMPLEX % zero[2]; zero[0] = %; zero[1] = zero[0]; %else const % zero[1] = {%}; %endif for (rowIdx = 0; rowIdx < %<(NUM_OUT_COLS - NUM_INP_COLS) * NUM_OUT_ROWS>; rowIdx++) { memcpy( y, (byte_T *)zero, % ); y += %; } } } %else %% %% The number of output rows is greater than num input rows %% The number of ouptut cols is GREATER OR EQUAL to num input cols %% { byte_T *u = (byte_T *)%; byte_T *y = (byte_T *)%; %% %if (NUM_INP_COLS > 1) register int_T colIdx; for (colIdx = 0; colIdx < %; colIdx++) { %endif %% (NUM_INP_COLS > 1) %% memcpy(y, u, %); y += %; %if (NUM_INP_COLS > 1) u += %; %endif %% %assign numOutColBytesZeroPad = (NUM_OUT_ROWS - NUM_INP_ROWS) * BYTES_PER_ELEMENT %% %if ( (numOutColBytesZeroPad > 0) && (NUM_INP_COLS > 1) ) { register int_T rowIdx; %if COMPLEX % zero[2]; zero[0] = %; zero[1] = zero[0]; %else const % zero[1] = {%}; %endif for (rowIdx = 0; rowIdx < %; rowIdx++) { memcpy( y, (byte_T *)zero, % ); y += %; } } %endif %% %if (NUM_INP_COLS > 1) } %endif %% (NUM_INP_COLS > 1) %% %% Pad any extra columns with zeros %% %if (NUM_OUT_COLS > NUM_INP_COLS) %% %assign totalOutBytes = NUM_OUT_ROWS * NUM_OUT_COLS * BYTES_PER_ELEMENT %assign totalBytesSoFar = (bytesPerInputCol + numOutColBytesZeroPad) * NUM_INP_COLS %assign extraZeroColBytes = totalOutBytes - totalBytesSoFar %% %if (NUM_INP_COLS == 1) %%Include missing zero bytes from the end of the first column also %%(excluded in generated code above!!!) %assign totalZeroPadBytes = extraZeroColBytes + numOutColBytesZeroPad %if (totalZeroPadBytes > 0) { register int_T rowIdx; %if COMPLEX % zero[2]; zero[0] = %; zero[1] = zero[0]; %else const % zero[1] = {%}; %endif for (rowIdx = 0; rowIdx < %; rowIdx++) { memcpy( y, (byte_T *)zero, % ); y += %; } } %endif %else %% Case: NUM_INP_COLS > 1 %if (extraZeroColBytes > 0) { register int_T rowIdx; %if COMPLEX % zero[2]; zero[0] = %; zero[1] = zero[0]; %else const % zero[1] = {%}; %endif for (rowIdx = 0; rowIdx < %; rowIdx++) { memcpy( y, (byte_T *)zero, % ); y += %; } } %endif %endif %elseif ( (NUM_INP_COLS == 1) && (numOutColBytesZeroPad > 0) ) %%Include missing zero bytes from the end of the first column also!!! %%(excluded in generated code above!!!) { register int_T rowIdx; %if COMPLEX % zero[2]; zero[0] = %; zero[1] = zero[0]; %else const % zero[1] = {%}; %endif for (rowIdx = 0; rowIdx < %; rowIdx++) { memcpy( y, (byte_T *)zero, % ); y += %; } } %endif %% } %endif %endfunction %% Generate2DGeneralPurposeCode %% [EOF] sdspzpad2.tlc