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.
Word Value | Exponent | Full-Scale Value (Word Value << Exponent) |
---|---|---|
0x0001 | 14 | 0x4000 |
0x0002 | 13 | 0x4000 |
0x0004 | 12 | 0x4000 |
0x0100 | 6 | 0x4000 |
0x01FF | 6 | 0x7FC0 |
0x0806 | 3 | 0x4030 |
0x2007 | 1 | 0x400E |
0x4800 | 0 | 0x4800 |
0x7000 | 0 | 0x7000 |
0x8000 | 0 | 0x8000 |
0x900A | 0 | 0x900A |
0xE001 | 2 | 0x8004 |
0xFF07 | 7 | 0x8380 |
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)