%% 
%% $Revision: 1.1.6.3 $
%% 
%%
%% Copyright 1994-2003 The MathWorks, Inc.
%%
%% Abstract: Absolute Value (Abs) block target file

%implements Abs "C"

%% Function: BlockInstanceSetup ==============================================
%% Abstract:
%%   Set expression folding compliance
%%
%function BlockInstanceSetup(block, system) void
  %if !AbsvalIsInFixptMode
    %<LibBlockSetIsExpressionCompliant(block)>
  %else
    %<FixPt_Setup(block, system)>
  %endif
  

%endfunction


%% Function: Outputs ==========================================================
%% Abstract:
%%      Y[i] = fabs(U[i]) if U[i] is real or
%%      Y[i] = sqrt(U[i].re^2 + U[i].im^2) if U[i] is complex.
%%
%function Outputs(block, system) Output
  %if !AbsvalIsInFixptMode
    %% NonFixPt data type 
    %assign outDType = LibBlockOutputSignalDataTypeId(0)
    %assign doSaturate = SLibHandleSaturateOnOverflow(block)
    %% 1) case with zero crossings
    %if NumNonsampledZCs > 0
      if (%<RTMIs("MajorTimeStep")>) {
	%assign rollVars = ["U", "Mode"]
	%roll sigIdx = RollRegions, lcv = RollThreshold, block, "Roller", rollVars
	  %<LibBlockMode("", lcv, sigIdx)> \
	  = %<LibBlockInputSignal(0, "", lcv, sigIdx)> >= 0.0;
	%endroll
      }
      %assign rollVars = ["U", "Y", "Mode"]
      %roll sigIdx = RollRegions, lcv = RollThreshold, block, "Roller", rollVars
	%assign u = LibBlockInputSignal(0, "", lcv, sigIdx)
	%<LibBlockOutputSignal(0, "", lcv, sigIdx)> \
	= (%<LibBlockMode("", lcv, sigIdx)>)? %<u>:-(%<u>);
      %endroll
      %% 2) complex case
    %else
      %assign inputIsComplex = LibBlockInputSignalIsComplex(0)
      %%
      %assign rollVars = ["U", "Y"]
      %if inputIsComplex
	%roll sigIdx = RollRegions, lcv = RollThreshold, block, "Roller", rollVars
	  %%
	  %assign ur = LibBlockInputSignal( 0, "", lcv, "%<tRealPart>%<sigIdx>")
	  %assign ui = LibBlockInputSignal( 0, "", lcv, "%<tImagPart>%<sigIdx>")
	  %assign y = LibBlockOutputSignal(0, "", lcv, sigIdx)
	  %%
	  %switch LibGetDataTypeIdAliasedThruToFromId(outDType)
	    %case tSS_DOUBLE
	    %case tSS_SINGLE
	      %<y> = %<LibGenMathFcnCall("sqrt", outDType, " %<ur>*%<ur> + %<ui>*%<ui> ","")>;
	      %break
	      %% START_ASSERT
	    %default
	      %assign errTxt = "Unsupported/Unhandled complex datatype: %<outDType>"
	      %<LibBlockReportFatalError(block, errTxt)>
	      %break
	      %% END_ASSERT
	  %endswitch
	%endroll
	%% 3) noncomplex case with no zero crossings
      %else
	%roll sigIdx = RollRegions, lcv = RollThreshold, block, "Roller", rollVars
	  %assign y = LibBlockOutputSignal(0, "", lcv, sigIdx)
	  %assign u = LibBlockInputSignal(0, "", lcv, sigIdx)
	  %switch LibGetDataTypeIdAliasedThruToFromId(outDType)
	    %case tSS_DOUBLE
	    %case tSS_SINGLE
	      %<y> = %<LibGenMathFcnCall("abs", outDType, "%<u>", "")>;
	      %break
	    %case tSS_INT32
	    %case tSS_INT16
	    %case tSS_INT8
	      if (%<u> < 0) {
	      %if (doSaturate == 1)
		if (%<u> == %<LibMinIntValue(outDType)>) {
		%<y> = %<LibMaxIntValue(outDType)>;
		} else {
	      %endif
	      %<y> = -%<u>;
	      %if (doSaturate == 1)
		}
	      %endif
	      %if (%<LibBlockInputSignalBufferDstPort(0)> == 0)
		%if (ShowEliminatedStatements)
		  /* Buffer Reuse Active; Following statement(s) unnecessary */
		  /* } else { */
		  /*   %<y> = %<u>; */
		%endif
	      %else
		} else {
		%<y> = %<u>;
	      %endif
	      }
	      %break
            %%START_ASSERT
	    %case tSS_UINT32
	    %case tSS_UINT16
	    %case tSS_UINT8
	      %%
	      %assign errTxt = "Block should have been reduced"
	      %<LibBlockReportFatalError(block, errTxt)>
	      %break
	    %default
	      %assign errTxt = "Unsupported/Unknown datatype: %<outDType>"
	      %<LibBlockReportFatalError(block, errTxt)>
	      %break
	      %%END_ASSERT
	  %endswitch
	%endroll
      %endif
       %endif 
    %else %% We are in fixpt world
      %%
      %% Roll around signal width
      %%
      %assign rollVars = ["U", "Y"]
      %%
      %% create header comment
      %%
      %openfile commentBuffer
      %% 
      %% Block name is explicitly put here.  In fixpt mode, we have
      %% not registered as being expression compliant.  The generate comment
      %% infrastructure only appends block name when expression compliant.
      %%
       * %<SLibBlkType(block)> Block: '%<SLibBlkName(block)>'
      %%
      %% add general comments
      %%
      %<FixPt_GeneralComments()>\
      %%
      %% END: header comment
      %%
      %closefile commentBuffer
      %%
      %<LibCacheBlockComment(block,commentBuffer)>\
      %%
      %assign y0DT = FixPt_GetOutputDataType(0)
      %%
      %assign y0IsFloat = FixPt_DataTypeIsFloat(y0DT)
      %%
      %if y0IsFloat
	%%
	%% if the output is floating point then saturation is not used
	%% 
	%assign localFixPtSaturationMode = "Wrap"
      %else
	%assign localFixPtSaturationMode = FixPtSaturationMode    
      %endif
      %%
      %if localFixPtSaturationMode == "Saturate"
	%%
	%assign outMax = FixPt_GetMaxStr(y0DT)
	%assign outMin = SPow2NegStr(y0DT.RequiredBits-1)
      %endif
      %%
      %assign uDestPort = LibBlockInputSignalBufferDstPort(0)
      %%
      %%
      %% if input (and Output) are complex then two cases to handle
      %% otherwise only one
      %%
      %assign casesToHandle = 1 + LibBlockOutputSignalIsComplex(0)
      %%
      %roll sigIdx = RollRegions, lcv = RollThreshold, block, "Roller", rollVars
	%%
	%foreach iCase = casesToHandle
	  %%
	  %if iCase == 0
	    %%
	    %assign riSigIdx = tRealPart + STRING(sigIdx)
	    %%
	  %else
	    %%START_ASSERT
	    %assign riSigIdx = tImagPart + STRING(sigIdx)
	    %%END_ASSERT
	  %endif
	  %%
	  %% Get input
	  %%  PROCESS THE SECOND INPUT!!!!
	  %%
	  %assign uiLabel = LibBlockInputSignal(0, "", lcv, riSigIdx)
	  %%
	  %% Get output
	  %%
	  %assign y0Label = LibBlockOutputSignal(0, "", lcv, riSigIdx)
	  %%
	  %% Handle operation
	  %%
	  %%
	  %if y0IsFloat || y0DT.IsSigned
	    %%
	    %% non-zero bias is NOT supported
	    %%
	    if ( %<uiLabel> < 0 )
	    {
	      %%
	      %if localFixPtSaturationMode == "Saturate"
		if ( %<uiLabel> <= %<outMin> )
		{
		  %<y0Label> = %<outMax>;
		}
		else
		{
		  %<y0Label> = -%<uiLabel>;
		}
	      %else
		%<y0Label> = -%<uiLabel>;
	      %endif
	      %%
	    }
	    %%
	    %if (uDestPort != 0)
	      else
	      {
		%<y0Label> = %<uiLabel>;
	      }
	    %endif
	  %else %% Unsigned, ie STUPID Case to apply ABS
	    %%
	    %if (uDestPort != 0)
	      %%START_ASSERT
	      %<y0Label> = %<uiLabel>;
	      %%END_ASSERT
	    %else
	      /* Abs block does NOT need to do anything here */
	    %endif
	  %endif
	  %%
	  %<FixPt_EmulationSignExt(y0Label,y0DT)>\
	  %%
	%endforeach
	%%
      %endroll
    %endif
      %%
      %% blank line for formating
      
  %endfunction


%% Function: BlockOutputSignal =================================================
%% Abstract:
%%      Return an output expression.  This function *may*
%%      be used by Simulink when optimizing the Block IO data structure.
%%
%function BlockOutputSignal(block,system,portIdx,ucv,lcv,idx,retType) void
  %switch retType
    %case "Signal"
      %assign outDType = LibBlockOutputSignalDataTypeId(0)
      %if SLibIsSignedFromId(outDType)
	%assign u =  LibBlockInputSignal(0, ucv, lcv, idx)
	%return LibGenMathFcnCall("abs", outDType, "%<u>","")
      %else
	%%START_ASSERT
	%return LibBlockInputSignal(0, ucv, lcv, idx)
	%%END_ASSERT
      %endif	
      %%START_ASSERT
    %default
      %assign errTxt = "Unsupported return type: %<retType>"
      %<LibBlockReportError(block,errTxt)>
      %%END_ASSERT
  %endswitch
%endfunction  

%% Function: ZeroCrossings =====================================================
%% Abstract:
%%      NSZC[i] = U[i];  use inputs for zero crossing detection
%%
%function ZeroCrossings(block, system) Output
  /* %<Type> Block: %<Name> */
  %if ParamSettings.InputContiguous == "yes"
    %% Input is also contiguous, do run-time loop
    %% ZC indices are always contiguous for this case
    %assign rollVars = ["U", "NSZC"]
    %roll sigIdx = RollRegions, lcv = RollThreshold, block, "Roller", rollVars
      %<LibBlockNonSampledZC("",lcv,sigIdx)> \
      = %<LibBlockInputSignal(0, "", lcv, sigIdx)>;
    %endroll
  %else
    %% Input is not contiguous, do each element separately
    %foreach idx = NumNonsampledZCs
      %<LibBlockNonSampledZC("","",idx)> = \
      %<LibBlockInputSignal(0, "", "", NonsampledZC[idx].MapIdx)>;
    %endforeach
  %endif
  
%endfunction

%% [EOF] absval.tlc
