Code Generation

With the Real-Time Workshop, the Fixed-Point Blockset can generate C code. The code generated from fixed-point blocks uses only integer types and automatically includes all operations, such as shifts, needed to account for differences in fixed-point locations. You can use the generated code on embedded fixed-point processors or rapid prototyping systems even if they contain a floating-point processor. The code is structured so that key operations can be readily replaced by optimized target-specific libraries that you supply. You can also use the Target Language Compiler to customize the generated code. For more information about code generation, refer to the Real-Time Workshop User's Guide and the Target Language Compiler Reference Guide.

You can also generate code for testing on a rapid prototyping system such as xPC, the Real-Time Windows Target, or dSPACE. The target compiler and processor may support floating-point operations in software or in hardware. In any case, the fixed-point blocks will generate pure integer code and will not use floating-point operations. This allows valid bit-true testing even on a floating-point processor.

You can also generate code for non real-time testing. For example, code can be generated to run in non real-time on computers running any supported operating system. Even though the processors have floating-point hardware, the code generated by fixed-point blocks is pure integer code. The Generic Real-Time Target (GRT) and the Simulink Accelerator are examples of where non real-time code is generated and run.

Code Generation Support

All fixed-point blocks support code generation, but not every simulation feature is supported. The code generation support is described below.

Languages

  • C support only

  • No Ada support

Storage Class of Variables

  • Fixed-Point Blockset code generation handles variables that do not match the target compiler's sizes for char, short, int, or long. Code generation supports any variable having a width less than or equal to a long, either signed or unsigned. For example, the C40 compiler defines a long to be 32 bits. Therefore, the allowable sizes for variables range between 1 and 32 bits. This capability is particularly useful if you want to: 

    • Prototype on one target chip, but use a different target chip for production.

    • Provide bit-true simulation in a rapid prototyping environment for odd data type sizes used by FPGAs, ASICs, 24-bit DSPs, and so on.

  • No floating-point support except for the fixed-point gateway blocks.

Storage Class of Parameters

  • The Real-Time Workshop external mode support requires that parameters be 1 to 32 bits, either signed or unsigned. The parameter size must also be compatible with the target C compiler.

  • No floating-point support

Rounding Modes

  • All four rounding modes are supported.

  • Rounding to floor generates the most efficient code for most cases.

Overflow Handling

  • Saturation mode is supported.

  • Wrapping mode is supported and generates the most efficient code.

  • Automatic exclusion of saturation code when hardware saturation is available is currently not supported. Wrapping must be selected for the Real-Time Workshop to exclude saturation code.

Blocks

All blocks generate code for all operations with a few exceptions:

  • The FixPt Look-Up Table, FixPt Look-Up Table (2D), and FixPt Dynamic Look-Up Table blocks generate code for all look-up methods except extrapolation.

  • A few combinations of scaling and operations lead to highly inefficient code. These few cases are described in the next section.

Scaling

  • Radix point-only scaling is supported.

  • Slope/bias scaling is supported for all blocks except when it leads to highly inefficient code. All blocks except four support all cases of slope/bias scaling. The FixPt Gain, FixPt Matrix Gain, and FixPt FIR blocks support matched slope/bias scaling where the block input signals and output signals have the same slopes and biases, but not mismatched slope/bias scaling. The FixPt Product block supports mismatched slope, but not mismatched bias. For more information about matched and mismatched slope/bias scaling, refer to Signal Conversions.

  • It is generally recommended that signals with slope/bias scaling (such as a sensor input) are immediately converted to radix point-only scaling. This will typically produce more efficient code.

Generating Pure Integer Code

All blocks generate pure integer code except for the FixPt Gateway In, FixPt Gateway In Inherited, and FixPt Gateway Out blocks. These blocks must generate floating-point code when handling floating-point input or output. However, if the input or output is an integer and the block is configured to treat the input or output as a stored integer, then these blocks will also generate pure integer code.

Example: Generating Pure Integer Code

This example outlines the steps you should take when generating pure integer code for your Fixed-Point Blockset model. The steps follow the description in the fxpdemo_code_only demo, which includes the model shown below.

This example generates code using the Embedded C Real-Time Target (ERT), whch is available with the RTW Production Coder. If your version of the Real-Time Workshop does not support ERT code generation, then you may want to select the Generic Real-Time Target (GRT). Using GRT, all Fixed-Point Blockset blocks (except the gateway blocks) will generate pure integer code. However, the code related to the GRT infrastructure is not generated to exclude floating-point operations. For example, GRT may decide when to execute blocks based on a floating-point counter. 

  1. Copy the fixed-point portion of your model to a new model.

    1. If your original model includes blocks that represent hardware, analog systems, and other blocks not related to embedded software, then you must create a new model. This new model contains only the fixed-point portion, which represents the software that will be running on the fixed-point processor. For example, the digital controller subsystem shown above contains the fixed-point blocks from the fxpdemo_feedback model used for code generation.

  2. Insert FixPt Gateway In blocks, as needed.

    1. Change the Treat input as: parameter from Real World Value to Stored Integer. This does not change the signal's value, but it is needed to "tag" integers with fixed point scaling information. The FixPt Gateway In block dialog box for this configuration is shown below.

    2. Precede all FixPt Gateway In blocks with root level Inport blocks, and configure the blocks to use the appropriate integer data type. For example, the Inport block shown above is configured to use the built-in int8 data type.

  3. Insert FixPt Gateway Out Blocks, as needed.

    • Change the Treat input as: parameter from Real World Value to Stored Integer. This does not change the signal's value, but it is needed to "strip" fixed-point scaling information from the integer. Also, configure the Output date type: parameter to use the appropriate integer data type. The FixPt Gateway Out block dialog box for this configuration is shown below.

    • Follow all FixPt Gateway Out blocks with root level Outport blocks.

  4. Configure the simulation parameters.

    • Launch Simulink's Simulation Parameter's dialog box by selecting Parameters under the Simulation menu.

    • In the Solver window, configure Solver options: to Fixed-step and discrete (no continuous states), and configure Fixed step size: to the required value. The Solver window for this configuration is shown below.

    • Select the Real-Time Workshop window in the Simulation Parameters dialog box. Configure the System target file parameter to ert.tlc. The Template makefile and Make command parameters are automatically updated. This configuration is shown below.

    • Launch the System Target File Browser by selecting the Browse button in the Configuration panel. If it is available, select Embedded-C Real-Time Target as the system target file and hit the OK button. The System Target File Browser for this configuration is shown below.

      The Fixed-Point Blockset supports all targets except those that generate Ada code. Note that you may not have ERT code generation capability. If this is the case, you should select the Generic Real-Time Target.

    • To configure the code generation parameters, select ERT code generation options from the Category parameter list. Select the Integer code only check box and any other options you may require. To configure additional code generation optimizations such as inlining, select General code generation options from the Category parameter list. The ERT code generation options for this configuration are shown below. If you are using GRT, the dialog box choices are slightly different.

    • Note that all fixed-point blocks except gateway blocks produce pure integer code for all supported targets.

    • Build the code by selecting the Generate code button.

Using External Mode or rsim Target

If you are using the Real-Time Workshop external mode or rsim (rapid simulation) target, there are situations where you may get unexpected errors when tuning block parameters. 

These errors can arise when you use blocks that support constant scaling for best precision and you use the "best precision" scaling option. To avoid these errors, you should use the Use Specified Scaling parameter value. Refer to Example: Constant Scaling for Best Precision for a description of the constant scaling feature. Refer to Chapter 9, Block Reference for a description of blocks that support this feature.

For more information about external mode or rapid simulation target, refer to the Real-Time Workshop User's Guide.

External Mode

If you change a fixed-point block parameter by a sufficient amount (approximately a factor of two), the radix point changes. If you change a parameter such that the radix point moves during an external mode simulation (or during graphical editing) and you reconnect to the target, a checksum error occurs and you must rebuild the code.

For example, suppose a block has a parameter value of -2. You then build the code and connect in external mode. While connected, you change the parameter to -4. If the simulation is stopped and then restarted, this parameter change causes a radix point change. In external mode, the radix point is kept fixed. If you keep the parameter value of -4 and disconnect from the target, then when you reconnect, a checksum error occurs and you must rebuild the code.

Rapid Simulation Target

If a parameter change is great enough, and you are using the best precision mode for constant scaling, then you cannot use the rapid simulation target.

If you change a block parameter by a sufficient amount (approximately a factor of two), the best precision mode changes the radix point. Any change in the radix point requires the code to be rebuilt since the model checksum is changed. This means that if best precision parameters are changed over a great enough range, you cannot use the rapid simulation target and a checksum error message occurs when you initialize the rsim executable.

Customizing Generated Code

You can customize generated code by directly modifying the TLC file fixpttarget.tlc, which is located in the fixpoint directory. The two most important customizations are described below.

Macros Versus Functions

You can modify the TLC file to generate macros or C functions calls. With macros, you can avoid the overhead of a function call. With function calls, you can significantly reduce the overall code size for large routines. Additionally, many debuggers will not allow you to single-step through macros. This is not the case with function calls. The factory default setting is to generate macros.

Bit Sizes for Target C Compiler

You can modify the TLC file to accommodate custom target sizes by explicitly specifying the number of bits defined for char, short, int, or long data types.

If you do not manually override these sizes, then the sizes for the MATLAB host computer are automatically selected. For example, if you are running MATLAB under the Windows operating system, then char, short, int, and long default to 8, 16, 32, and 32 bits, respectively. Most other supported operating systems use the same data type sizes. However, DEC Alpha for example, defines a long as 64 bits.