Newsletters - MATLAB Digest
Fixed-Point Blockset: Easier Ways to Create Good Designs
This article will present techniques for using the Fixed-Point Blockset. These techniques make it easier to use the Fixed-Point Blockset and to create designs that can be efficiently implemented on target processors.
The Fixed-Point Blockset gives users a tremendous amount of control over the data type and scaling used for signals and parameters. The downside of this flexibility is having to manually select and specify what data type and scaling to use for every signal and parameter. This is a burden when creating traditional hand-coded designs and for creating designs using the Fixed-Point Blockset. An advantage of the Fixed-Point Blockset is that the data type and/or scaling of many signals and parameters can be automatically set. This article presents techniques that cause the Fixed-Point Blockset to make more of the choices automatically.
Automatic choices for data type and scaling are beneficial if the user gets what they want. In an ideal world, the user wants three things: fixed-point calculations that eliminate range errors such as overflows or saturations, fixed-point calculations that never lose precision, and code (to implement the calculation) that would require minimal amounts of RAM, ROM, and clock cycles. In some cases, all three goals can be satisfied, and the Fixed-Point Blockset can easily set the data type and scaling. In other cases, there will be a tradeoff among the three goals. It is trickier to handle these cases, but the Fixed-Point Blockset can often be set up to automatically give the user choices they deem acceptable.
This article will show how to get automatic selection of data type and/or scaling in both simple and tricky situations.
Constants
Something as seemingly simple as a constant can be tedious to deal with in a Fixed-Point design. In a hand-coded design, three things would need to be determined: data type, scaling, and integer representation. The Fixed-Point Blockset will always automatically handle the step of finding the hexidecimal representation. It can also easily handle the scaling. Selecting the data type is harder because the choice usually depends on how the constant is used. Nonetheless, some methods of determining a sensible data type based on usage will be presented.
Constant Scaling
Consider an odometer as an example. Suppose total tire revolutions are stored in a variable. Prior to display, revolutions need to be converted to tenths of miles or tenths of kilometers. Suppose the tires have a 15-inch nominal radius. The conversion factor from revolutions to tenths of miles is easily determined.
2 * pi * 15 / 12 / 528 tenths of miles per tire revolution
The ideal value is now known, but the three Fixed-Point implementation details must now be determined. Let's assume that a 16-bit microprocessor will be used, so 16 bits is a natural first choice. This number is positive, and it won't be multiplying a signed number, so there's no reason to waste a bit on a sign. In the constant's dialog (Figure 1), the user would enter the ideal value and ufix(16) for the data type. Setting the scaling mode to best precision causes the Fixed-Point Blockset to automatically select the scaling. The user does not need to determine that 2^-21 is the most precise scaling that avoids overflow. In simulation and in code generated with Real Time Workshop®, the Fixed-Point Blockset will automatically use the integer value 62390 (Figure 2) to represent the conversion from revolutions to tenths of miles. The user does not need to determine this integer as they would in hand code.
![]() |
| Figure 1 Click to see enlarged view (8 k) |
![]() |
| Figure 2 Click to see enlarged view (6 k) |
Constants in Inequalities
Constants are often used in inequalities. This is a situation where a natural choice for data type and scaling can be made automatically. The natural choice is based on what the Fixed-Point processor will have to do to test the inequality. The processor will have to put the signal and the constant into a format that has identical data type and scaling for both. It can then do a simple integer comparison. Clearly, if the signal and the constant start with the same data type and scaling, then the first step is unnecessary and implementation requires minimal code. The Fixed-Point Blockset allows the natural choice to be made via data type propagation.
As an example, consider a controller that has to determine if the temperature is close to the freezing point of water. Model2 (Figure 3) shows two somewhat different examples of this operation. Two constants hold the threshold values of values 2.002 and 2.3 Celcius. To have the data type and scaling of these thresholds automatically selected, set the output data type and scaling via back propagation (Figure 4). In both cases, the data type of the temperature signals propagate to the relational operator blocks, and then back propagate to the constant blocks. Figure 3 shows that the constants automatically use the same data types and scaling as the temperature signals that they are testing. Because the choices are the natural ones, the generated code for the relational operators can be as simple as possible.
![]() |
| Figure 3 Click to see enlarged view (9 k) |
![]() |
| Figure 4 Click to see enlarged view (5 k) |
This approach saves the user time and effort. The user does not need to figure out the natural data type and scaling, and does not need to manually enter this in the constant blocks. An especially important fact is that the user never needs to recheck the coordination of the data types and scaling. If the data type and/or scaling of the temperature signals change, then the scaling and data type of the constant will automatically change and the generated code will still be as simple as possible (Figure 5).
![]() |
| Figure 5 Click to see enlarged view. |
Pitfall Constants in Inequalities
There is one potential pitfall to using constants in inequalities that users should be aware of. Constants like other fixed-point parameters will be quantized to the nearest value that the data type and scaling allows. As a result of this quantization, the inequality implemented in the fixed-point world may not agree with the inequality implemented in the ideal world. If there is an inequality error, it will apply to one particular input. Inputs one bit below and one bit above will both produce the correct result.
In Model2, both thresholds had quantization errors when converted to fixed-point.
| 513 * 2^-8 = 2.00390625 != 2.002 131 * 0.4 - 50.0 = 2.4 != 2.3 |
Table 1 shows that the quantization error in the top case had no effect on the fixed-point implementation. Table 2 shows that the quantization error in the bottom case did cause an error. For one and only one of possible input values, the output of the inequality does not agree with the ideal implementation.
| Quantized Input | Ideal Input < 2.002 | Actual Input < 2.00390625 | Compare |
| 2.0 | True | True | Agree |
| 2.00390625 | False | False | Agree |
| 2.0078125 | False | False | Agree |
Table 1
| Quantized Input | Ideal Input < 2.3 | Actual Input < 2.4 | Compare |
| 2.0 | True | True | Agree |
| 2.4 | False | True | Disagree |
| 2.8 | False | False | Agree |
Table 2
Errors of this type are something that users should expect in any fixed-point implementation. In this inequality case, users must know if it is critical for the inequality to be absolutely perfect. It should be noted that the input temperature signal is itself quantized. At the very best, this signal has a worst case quantization error of half a bit. In many cases, the worst case quantization error will actually be much larger due to sensor errors, analog to digital converter errors, quantization in upstream fixed-point calculations, etc. If it really is crucial for the inequality to be absolutely perfect, then the user must carefully analyze the effect of quantization as was done in Tables 1 and 2. Minor modifications to the threshold, changing < and <=, for example will produce the required map between quantized input and relational operator output.




