%% $RCSfile: sdsppad.tlc,v $ %% $Revision: 1.3 $ %% $Date: 2000/08/09 21:36:55 $ %% %% Copyright 1995-2000 The MathWorks, Inc. %% %% Abstract: Pad library block %implements sdsppad "C" %% Function: BlockInstanceSetup =============================================== %% %function BlockInstanceSetup(block, system) void %assign INPORT = 0 %assign OUTPORT = 0 %% %% Block data type (same for input, output, and pad value): %% %assign DTYPE_ID = LibBlockInputSignalDataTypeId( INPORT) %assign DTYPE_NAME = LibBlockInputSignalDataTypeName( INPORT,"%") %assign DTYPE_SIZE = SLibGetDataTypeSizeFromId(DTYPE_ID) %% %% Note: Complexity of PAD_VALUE may be different %% from complexity of input and/or output ports. %% For instance, the output may be a complex signal %% due to the input being complex, but the pad value %% may be real. Similarly, the input port complexity %% may be real while the pad value is complex, which %% makes the output port necessarily complex. This %% means that we must cache the complexity of each of %% these separately. %% %assign INP_COMPLEX = LibBlockInputSignalIsComplex( INPORT) %assign OUT_COMPLEX = LibBlockOutputSignalIsComplex(OUTPORT) %% %% Input dimensions: %% %assign NUM_INP_DIMS = LibBlockInputSignalNumDimensions(INPORT) %assign INPUT_DIMS = LibBlockInputSignalDimensions( INPORT) %assign NUM_INP_ROWS = INPUT_DIMS[0] %assign NUM_INP_COLS = (NUM_INP_DIMS == 2) ? INPUT_DIMS[1] : 1 %assign INP_WIDTH = NUM_INP_ROWS * NUM_INP_COLS %assign BYTES_PER_INP_SAMPLE = DTYPE_SIZE * (1 + INP_COMPLEX) %assign BYTES_PER_INP_COL = NUM_INP_ROWS * BYTES_PER_INP_SAMPLE %assign TOTAL_INP_BYTES = INP_WIDTH * BYTES_PER_INP_SAMPLE %% %% Output dimensions: %% %assign NUM_OUT_DIMS = LibBlockOutputSignalNumDimensions(OUTPORT) %assign OUTPUT_DIMS = LibBlockOutputSignalDimensions( OUTPORT) %assign NUM_OUT_ROWS = OUTPUT_DIMS[0] %assign NUM_OUT_COLS = (NUM_OUT_DIMS == 2) ? OUTPUT_DIMS[1] : 1 %assign OUT_WIDTH = NUM_OUT_ROWS * NUM_OUT_COLS %assign BYTES_PER_OUT_SAMPLE = DTYPE_SIZE * (1 + OUT_COMPLEX) %assign BYTES_PER_OUT_COL = NUM_OUT_ROWS * BYTES_PER_OUT_SAMPLE %assign TOTAL_OUT_BYTES = OUT_WIDTH * BYTES_PER_OUT_SAMPLE %% %% Pad value parameter: %% %assign PAD_VALUE_RE = SFcnParamSettings.PadValueRe %assign PAD_VALUE_IM = SFcnParamSettings.PadValueIm %assign PAD_VALUE_COMPLEX = SFcnParamSettings.PadValueCplx %% %% Pad truncation action mode: %% %assign TRUNCATE_ERR_MODE = SFcnParamSettings.TruncErrMode %assign WARN_ON_TRUNCATE = 2 %assign ERROR_ON_TRUNCATE = 3 %assign TRUNC_WARNING_MSG_STR = "Input signal has been truncated by Pad block." %assign TRUNC_ERROR_MSG_STR = "Input signal truncation will occur." %% %% Add defined constants to block record: %% %assign block = block + INPORT + OUTPORT + DTYPE_ID + DTYPE_NAME + DTYPE_SIZE %assign block = block + INP_COMPLEX + OUT_COMPLEX + NUM_INP_DIMS + INPUT_DIMS %assign block = block + NUM_INP_ROWS + NUM_INP_COLS + INP_WIDTH %assign block = block + BYTES_PER_INP_SAMPLE + BYTES_PER_INP_COL %assign block = block + TOTAL_INP_BYTES + NUM_OUT_DIMS + OUTPUT_DIMS %assign block = block + NUM_OUT_ROWS + NUM_OUT_COLS + OUT_WIDTH %assign block = block + BYTES_PER_OUT_SAMPLE + BYTES_PER_OUT_COL + TOTAL_OUT_BYTES %assign block = block + PAD_VALUE_RE + PAD_VALUE_IM + PAD_VALUE_COMPLEX %assign block = block + TRUNCATE_ERR_MODE + 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 Pad (%) - % */ %if (LibBlockInputSignalBufferDstPort(INPORT) != OUTPORT) %if (NUM_OUT_DIMS == 2) && (OUT_WIDTH > 1) % %elseif (NUM_OUT_DIMS == 1) && (OUT_WIDTH > 1) % %else %% Scalar output (degenerate case) % %endif %% NUM_OUT_DIMS (2-D vs. 1-D code gen choices) %else /* * Pad output width is identical to input width, and * the output buffer shares space with the input buffer. * Therefore, no code is required to perform the pad. */ %endif %endfunction %% Outputs %% Function: GenerateScalarCode ==================================================== %% %function GenerateScalarCode(block) Output %% %% For this case, the output is a scalar. Therefore we are guaranteed %% that the input and output have the same data type and complexity. %% Just need to copy a single input value to the output. %% %if (INP_WIDTH > 1) %if (TRUNCATE_ERR_MODE == WARN_ON_TRUNCATE) %warning % %elseif (TRUNCATE_ERR_MODE == ERROR_ON_TRUNCATE) %error % %endif %endif /* Copy input value to (scalar) output */ %if OUT_COMPLEX memcpy( (byte_T *)%, \ (byte_T *)%, \ % ); %else *(%) = *(%); %endif %endfunction %% Generate1DCode %% Function: Generate1DCode ==================================================== %% %function Generate1DCode(block) Output /* Input width: %, output width: % */ %if (INP_WIDTH >= OUT_WIDTH) % %else % %endif %endfunction %% Generate1DCode %% Function: Generate2DCode ==================================================== %% %function Generate2DCode(block) Output /* Input dimensions: [% x %], output dimensions: [% x %] */ %if ( (NUM_INP_ROWS == NUM_OUT_ROWS) && (NUM_OUT_COLS == NUM_INP_COLS) ) % %elseif ( (NUM_OUT_ROWS < NUM_INP_ROWS) || (NUM_OUT_COLS < NUM_INP_COLS) ) %% Input truncation case: either (or both) rows or cols truncated % %else % %endif %endfunction %% Generate2DCode %% Function: Generate1DCopyOrTruncateCode ================================= %% %function Generate1DCopyOrTruncateCode(block) Output %if (INP_WIDTH > OUT_WIDTH) %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 %% %% Note: code sharing between 2D and 1D cases: % %% %endfunction %% Generate1DCopyOrTruncateCode %% Function: Generate2DCopyCode ===================================== %% %function Generate2DCopyCode(block) Output memcpy( (byte_T *)%, \ (byte_T *)%, \ % ); %endfunction %% Generate2DCopyCode %% Function: Generate1DGeneralPurposeCode ==================================================== %% %function Generate1DGeneralPurposeCode(block) Output { %if OUT_COMPLEX c% *y = (c% *)%; %else % *y = (% *)%; %endif %% %if (BYTES_PER_OUT_SAMPLE == BYTES_PER_INP_SAMPLE) /* Copy inputs to outputs */ memcpy( (byte_T *)%, \ (byte_T *)%, \ % ); y += %; %else /* Copy REAL inputs to COMPLEX outputs */ { real_T *u = (real_T *)%; %if INP_WIDTH > 1 register int_T i; for (i=0; i++<%; ) { y->re = *u++; y++->im = 0.0; } %else y->re = *u; y++->im = 0.0; %endif } %endif /* Pad the remaining output samples */ %if PAD_VALUE_COMPLEX | OUT_COMPLEX %if ((OUT_WIDTH - INP_WIDTH) > 1) { register int_T i; for (i = 0; i++ < %; ) { y->re = %; y++->im = %; } } %else y->re = %; y->im = %; %endif %else %if ((OUT_WIDTH - INP_WIDTH) > 1) { register int_T i; for (i = 0; i++ < %; ) { *y++ = %; } } %else *y = %; %endif %endif } %endfunction %% Generate1DGeneralPurposeCode %% Function: Generate2DTruncateCode ===================================== %% %function Generate2DTruncateCode(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 %% { byte_T *u = (byte_T *)%; byte_T *y = (byte_T *)%; %% %if (NUM_OUT_COLS > 1) register int_T colIdx; for (colIdx = 0; 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 %% { %% %if INP_COMPLEX c% *u = (c% *)%; %else % *u = (% *)%; %endif %% %if OUT_COMPLEX c% *y = (c% *)%; %else % *y = (% *)%; %endif %% %if (NUM_INP_COLS > 1) register int_T colIdx; /* Copy inputs to outputs */ for (colIdx = 0; colIdx++ < %; ) { %endif %% (NUM_INP_COLS > 1) register int_T rowIdx; for (rowIdx = 0; rowIdx++ < %; ) { %if (OUT_COMPLEX != INP_COMPLEX) y->re = *u++; y++->im = 0.0; %else *y++ = *u++; %endif } %if (NUM_INP_COLS > 1) u += %; %endif %if (NUM_INP_COLS > 1) } %endif %% %% Pad any extra columns %% %if (NUM_OUT_COLS > NUM_INP_COLS) %% %assign totalSamplesToPad = (NUM_OUT_COLS - NUM_INP_COLS) * NUM_OUT_ROWS %% /* Append additional pad values to output */ { %if OUT_COMPLEX register int_T padCount; for (padCount=0; padCount++<%; ) { y->re = %; y++->im = %; } %else register int_T padCount; for (padCount=0; padCount++<%; ) { *y++ = %; } %endif } %endif %% } %else %% Case: (NUM_OUT_COLS < NUM_INP_COLS) only %% %% Truncate number of cols only %% { %% %if INP_COMPLEX c% *u = (c% *)%; %else % *u = (% *)%; %endif %% %if OUT_COMPLEX c% *y = (c% *)%; %else % *y = (% *)%; %endif %% %if (NUM_OUT_COLS > 1) register int_T colIdx; for (colIdx = 0; colIdx++ < %; ) { %endif %% (NUM_OUT_COLS > 1) %% /* Copy inputs to outputs */ register int_T rowIdx; for (rowIdx = 0; rowIdx++ < NUM_INP_ROWS; ) { %if (OUT_COMPLEX != INP_COMPLEX) y->re = *u++; y++->im = 0.0; %else *y++ = *u++; %endif } %% %assign numOutColSamplesToPad = NUM_OUT_ROWS - NUM_INP_ROWS %% %if (numOutColSamplesToPad > 0) /* Append additional pad values to output */ { %if OUT_COMPLEX register int_T padCount; for (padCount = 0; padCount++ < %; ) { y->re = %; y++->im = %; } %else register int_T padCount; for (padCount = 0; padCount++ < %; ) { *y++ = %; } %endif } %endif } %endif %% Various row/column truncation cases %endfunction %% Generate2DTruncateCode %% Function: Generate2DGeneralPurposeCode ====================================== %% %function Generate2DGeneralPurposeCode(block) Output %if (NUM_INP_ROWS == NUM_OUT_ROWS) { %if INP_COMPLEX c% *u = (c% *)%; %else % *u = (% *)%; %endif %% %if OUT_COMPLEX c% *y = (c% *)%; %else % *y = (% *)%; %endif /* Copy inputs to outputs */ register int_T rowIdx; for (rowIdx = 0; rowIdx++ < %; ) { %if (OUT_COMPLEX != INP_COMPLEX) y->re = *u++; y++->im = 0.0; %else *y++ = *u++; %endif } %assign numOutSamplesRemaining = (NUM_OUT_COLS - NUM_INP_COLS) * NUM_OUT_ROWS /* Append additional pad values to output */ { %if OUT_COMPLEX register int_T padCount; for (padCount = 0; padCount++ < %; ) { y->re = %; y++->im = %; } %else register int_T padCount; for (padCount = 0; padCount++ < %; ) { *y++ = %; } %endif } } %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 %% { %if INP_COMPLEX c% *u = (c% *)%; %else % *u = (% *)%; %endif %% %if OUT_COMPLEX c% *y = (c% *)%; %else % *y = (% *)%; %endif %% /* Copy inputs to outputs */ %if (NUM_INP_COLS > 1) register int_T colIdx; for (colIdx = 0; colIdx++ < %; ) { %endif %% (NUM_INP_COLS > 1) %if (NUM_INP_ROWS > 1) register int_T numInpRows = %; while(numInpRows-- > 0) { %if (OUT_COMPLEX != INP_COMPLEX) y->re = *u++; y++->im = 0.0; %else *y++ = *u++; %endif } %else %if (OUT_COMPLEX != INP_COMPLEX) y->re = *u++; y++->im = 0.0; %else *y++ = *u++; %endif %endif %% (NUM_INP_ROWS > 1) %assign numOutRowsPad = NUM_OUT_ROWS - NUM_INP_ROWS %if ( (numOutRowsPad > 0) && (NUM_INP_COLS > 1) ) /* Append additional pad values to output */ %if (numOutRowsPad > 1) { register int_T additionalOutputRows = %; while (additionalOutputRows-- > 0) { %if (OUT_COMPLEX) y->re = %; y++->im = %; %else *y++ = %; %endif } } %else %if (OUT_COMPLEX) y->re = %; y++->im = %; %else *y++ = %; %endif %endif %endif %if (NUM_INP_COLS > 1) } %endif %% (NUM_INP_COLS > 1) %% %% Pad any extra columns %% %if (NUM_OUT_COLS > NUM_INP_COLS) %assign totalOutSamples = NUM_OUT_ROWS * NUM_OUT_COLS %assign totalSamplesSoFar = (NUM_INP_ROWS + numOutRowsPad) * NUM_INP_COLS %assign extraColSamples = totalOutSamples - totalSamplesSoFar %% %if (NUM_INP_COLS == 1) %%Include missing bytes from the end of the first column also %%(excluded in generated code above!!!) %assign totalSamplesToPad = extraColSamples + numOutRowsPad %if (totalSamplesToPad > 1) { register int_T remainingSamplesToPad = %; while (remainingSamplesToPad-- > 0) { %if (OUT_COMPLEX) y->re = %; y++->im = %; %else *y++ = %; %endif } } %elseif (totalSamplesToPad == 1) %if (OUT_COMPLEX) y->re = %; y->im = %; %else *y = %; %endif %endif %else %% Case: NUM_INP_COLS > 1 %if (extraColSamples > 1) { register int_T remainingSamplesToPad = %; while (remainingSamplesToPad-- > 0) { %if (OUT_COMPLEX) y->re = %; y++->im = %; %else *y++ = %; %endif } } %elseif (extraColSamples == 1) %if (OUT_COMPLEX) y->re = %; y->im = %; %else *y = %; %endif %endif %endif %elseif ( (NUM_INP_COLS == 1) && (numOutRowsPad > 0) ) %%Include missing bytes from the end of the first column also!!! %%(excluded in generated code above!!!) %if (numOutRowsPad > 1) { register int_T remainingSamplesToPad = %; while (remainingSamplesToPad-- > 0) { %if (OUT_COMPLEX) y->re = %; y++->im = %; %else *y++ = %; %endif } } %else %if (OUT_COMPLEX) y->re = %; y->im = %; %else *y = %; %endif %endif %endif %% (NUM_OUT_COLS > NUM_INP_COLS) } %endif %% (NUM_INP_ROWS == NUM_OUT_ROWS) %endfunction %% Generate2DGeneralPurposeCode %% [EOF] sdsppad.tlc