3.17 Scaling Data with the FBCL Instruction

To minimize quantization errors that are associated with data processing using DSP instructions, it is important to utilize the complete numerical result of the operations. This may require scaling data up to avoid underflow (i.e., when processing data from a 12-bit ADC) or scaling data down to avoid overflow (i.e., when sending data to a 10-bit DAC). The scaling, which must be performed to minimize quantization error, depends on the dynamic range of the input data which is operated on and the required dynamic range of the output data. At times, these conditions may be known beforehand and fixed scaling may be employed. In other cases, scaling conditions may not be fixed or known and then dynamic scaling must be used to process data.

The FBCL instruction (Find First Bit Change Left) can efficiently be used to perform dynamic scaling, because it determines the exponent of a value. A fixed point or integer value’s exponent represents the amount that the value may be shifted before overflowing. This information is valuable because it may be used to bring the data value to “full scale”, meaning that its numeric representation utilizes all the bits of the register it is stored in.

The FBCL instruction determines the exponent of a word by detecting the first bit change, starting from the value’s Sign bit and working towards the LSB. Since the dsPIC33A device’s barrel shifter uses negative values to specify a left shift, the FBCL instruction returns the negated exponent of a value. If the value is being scaled up, this allows the ensuing shift to be performed immediately with the value returned by FBCL. Additionally, since the FBCL instruction only operates on signed quantities, FBCL produces results in the range of -15:0 for word operation and -31:0 for long word operation. When the FBCL instruction returns 0, it indicates that the value is already at full scale. When the instruction returns -31, it indicates that the value cannot be scaled (as is the case with 0x0 and 0xFFFFFFFF). Table 3-15 shows word data with various dynamic ranges, their exponents and the value after scaling the data to maximize the dynamic range. Scaling with FBCL shows how the FBCL instruction may be used for block processing.

Table 3-15. Scaling Examples
Word ValueExponentFull-Scale Value

(Word Value << Exponent)

0x0001140x4000
0x0002130x4000
0x0004120x4000
0x010060x4000
0x01FF60x7FC0
0x080630x4030
0x200710x400E
0x480000x4800
0x700000x7000
0x800000x8000
0x900A00x900A
0xE00120x8004
0xFF0770x8380
Note: For the word values, 0x0000 and 0xFFFF, the FBCL instruction returns -15.

As a practical example, assume that block processing is performed on a sequence of data with very low dynamic range stored in 1.15 fractional format. To minimize quantization errors, the data may be scaled up to prevent any quantization loss that may occur as it is processed. The FBCL instruction can be executed on the sample with the largest magnitude to determine the optimal scaling value for processing the data. Note that scaling the data up is performed by left shifting the data. This is demonstrated with the code snippet below.

Scaling with FBCL

; assume W0 contains the largest absolute value of the data block
; assume W4 points to the beginning of the data block
; assume the block of data contains BLOCK_SIZE words
; determine the exponent to use for scaling
FBCL		W0, W2					; store exponent in W2
; scale the entire data block before processing
DO		#(BLOCK_SIZE-1), SCALE
LAC		[W4], A					; move the next data sample to ACCA
SFTAC		A, W2					; shift ACCA by W2 bits
SCALE:
SAC		A, [W4++]				    ; store scaled input (overwrite original)
; now process the data
; (processing block goes here)