Fixed-point is a rational numeric data type whose range and precision you define by configuring the number of stored bits and the value assigned to those bits. Fixed-point numbers are important for implementing FPGA programs because many FPGAs do not efficiently support floating-point data types and because fixed-point numbers allow you to use the minimum number of bits to achieve the range and precision required by your algorithm.
A fixed-point number is composed of a specified number of bits and a binary point. Fixed-point numbers can be either signed or unsigned. The position of the binary point in relation to the total number of stored bits determines the place value assigned to each bit.
Consider a scenario using an arbitrary set of four bits. The value of the set of bits 1001 changes depending on where you set the binary point. The value of the number 10.01 differs from the value of the number 1.001 because the binary point determines the place value of each bit. The following image demonstrates this principle for an unsigned fixed-point number that has a positive number of stored bits for both its integer and fractional parts.
Fixed-point numbers are either unsigned or signed. Unsigned fixed-point numbers only represent positive values. Signed fixed-point numbers can represent both positive and negative values. For signed fixed-point numbers, the leftmost bit of the stored set of bits determines if the value of the bits is positive or negative. If the first stored bit is 1, the value of the bits is negative. If the first stored bit is 0, the value of the bits is positive. Signed fixed-point numbers are interpreted using an encoding called two's complement. The following image shows an example fixed-point number with two integer bits and two fractional bits. Notice that the exponents of all place values remain the same between signed and unsigned numbers, but in a signed fixed-point number, the value of the leftmost place is negative.
Using the previous image, consider a scenario where both the signed and unsigned instances of the fixed-point number hold the bits 1011. The result of multiplying each bit by its place value, and adding the resulting value of each bit together, is the decimal value for any set of bits in a fixed-point number. For the unsigned instance of this fixed-point number, the decimal value of the bits 1011 is equal to 1 × 2^{1} + 0 × 2^{0} + 1 × 2^{-1} + 1 × 2^{-2} or 2.75. For the signed instance of this fixed-point number, the decimal value of the bits 1011 is equal to 1 × (-2^{1}) + 0 × 2^{0} + 1 × 2^{-1} + 1 × 2^{-2} or -1.25.
For any signed and unsigned fixed-point number with the same integer and fractional number of bits, the unsigned type is able to represent larger positive values, while the signed type can represent both positive and negative values. For example, between the signed and unsigned instances of a 4-bit fixed-point number with two integer and two fractional bits, the unsigned instance has a range of 0 to 3.75, while the signed instance has a range of -2 to 1.75.
Increasing the total number of bits stored for any fixed-point number increases the range the data type can represent. Increasing the number of fractional bits stored for any fixed-point number increases the precision that the number can store.
The range of a fixed-point number is the set of values that a particular fixed-point data type can represent. To determine the range of a fixed-point number, you need to know the maximum and minimum values the number can represent, and the increment between each value. The increment between each value is also called the precision, or delta, of the fixed-point number.
Consider a 2-bit unsigned fixed-point number that stores two integer bits and zero fractional bits. Because each stored bit can hold either a 0 or 1, the 2-bit number can represent four unique combinations: 00, 01, 10, or 11. The place value of the left bit in this example is 2^{1} and the place value of the right bit is 2^{0}. The following table shows the decimal value of each possible bit combination for the 2-bit unsigned fixed-point number in this example.
Possible Bit Combination | Bit Value | Representable Decimal Value |
---|---|---|
00 | 0 × 2^{1} + 0 × 2^{0} | 0 |
01 | 0 × 2^{1} + 1 × 2^{0} | 1 |
10 | 1 × 2^{1} + 0 × 2^{0} | 2 |
11 | 1 × 2^{1} + 1 × 2^{0} | 3 |
In this case, the range of the fixed-point number is 0 to 3 and the delta is 1. Adding a fractional bit increases the overall range and increases the precision that the fixed-point number can represent. Adding a fractional bit increases the range to 0 to 3.5 and reduces the distance between possible stored values from 1 down to 0.5. The same principles apply when you add or subtract bits from larger fixed-point numbers.