This example illustrates the floating-point workflow that integrates IP libraries provided by vendors, such as Altera and Xilinx. For more information on how to map designs to floating-point libraries, see Generate HDL Code for FPGA Floating-Point Target Libraries.
Implementing designs with floating-point arithmetic enable you to model with higher precision and wider dynamic range and saves time by skipping floating-point to fixed-point conversion. This is particularly beneficial for model-based design, where high-level algorithms are modeled with floating-point and does not have implementation timing details, such as pipelining and timing constraints. However, they are necessary to map operations to floating-point IP modules. HDL Coder automatically optimizes and implements your designs with these timing details and provides interfaces for you to adjust them. Floating-point math is finally implemented by integrating with floating-point IP modules from vendor libraries.
This Field-Oriented Control (FOC) algorithm example demonstrates the basic steps in this workflow to map designs to floating-point libraries. See the example Field-Oriented Control of a Permanent Magnet Synchronous Machine for details about this application.
This model uses single-precision and contains blocks that perform basic math operators, such as adders, multipliers, comparators, and complex sin and cos functions.
Signal rates in this model are modeled at 20 or 50 KHz only. Notice that this model contains only the numerical implementation, and doesn't have any FPGA implementation timing details, such as operation latencies. All numerical operations, including sin and cos functions, compute in a single sample time-step.
open_system('hdlcoderFocCurrentSingleTargetHdl'); open_system('hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control/Sine_Cosine');
In order to map to a vendor floating-point library, set the FPGA device.
hdlset_param('hdlcoderFocCurrentSingleTargetHdl', 'SynthesisToolChipFamily', 'Arria 10'); hdlset_param('hdlcoderFocCurrentSingleTargetHdl', 'SynthesisTool', 'Altera Quartus II');
Setup target library tools.
hdlsetuptoolpath('ToolName', 'Altera Quartus II','ToolPath', quartuspath); hdlsetuptoolpath('ToolName', 'XILINX ISE','ToolPath', isepath);
Prepending following Altera Quartus II path(s) to the system path: /mathworks/hub/share/apps/HDLTools/Altera/18.1-mw-0/Linux/quartus/bin Setting QUARTUS_64BIT environment variable to 1 to turn on 64-bit processing. Setting XILINX environment variable to: /mathworks/hub/share/apps/HDLTools/Xilinx_ISE/14.7-mw-0/Lin/ISE_DS/ISE Setting XILINX_EDK environment variable to: /mathworks/hub/share/apps/HDLTools/Xilinx_ISE/14.7-mw-0/Lin/ISE_DS/EDK Setting XILINX_PLANAHEAD environment variable to: /mathworks/hub/share/apps/HDLTools/Xilinx_ISE/14.7-mw-0/Lin/ISE_DS/PlanAhead Prepending following XILINX ISE path(s) to the system path: /mathworks/hub/share/apps/HDLTools/Xilinx_ISE/14.7-mw-0/Lin/ISE_DS/ISE/bin/lin64:/mathworks/hub/share/apps/HDLTools/Xilinx_ISE/14.7-mw-0/Lin/ISE_DS/EDK/bin/lin64:/mathworks/hub/share/apps/HDLTools/Xilinx_ISE/14.7-mw-0/Lin/ISE_DS/PlanAhead/bin
quartuspath and isepath return synthesis tool paths in our environment. Refer to hdlsetuptoolpath
for how to setup tools in your environment.
The first step is to choose a vendor library. For Xilinx devices, you can use 'XILINXLOGICORE', and for Altera devices, you can select 'ALTERAFPFUNCTIONS' or 'ALTFP'. Check library documentation for their supported devices.
Create a floating-point target configuration object for ALTERAFPFUNCTIONS.
fc = hdlcoder.createFloatingPointTargetConfig('ALTERAFPFUNCTIONS');
Set the configuration object on the model
hdlset_param('hdlcoderFocCurrentSingleTargetHdl', 'FloatingPointTargetConfiguration', fc);
To compile and simulate the generated code with QuestaSim, you have to compile Altera simulation library and set its path on model with the SimulationLibPath parameter. Check Tool Setup for more information. alterasimulationlibpath returns the path to the compiled Altera simulation library in our environment.
hdlset_param('hdlcoderFocCurrentSingleTargetHdl', 'SimulationLibPath', alterasimulationlibpath);
Altera Megafunction (ALTERAFPFUNCTIONS) library allows generating IP modules for a given target frequency. In this example, the target frequency is set to 250MHz.
hdlset_param('hdlcoderFocCurrentSingleTargetHdl', 'TargetFrequency', 250);
Generate code
try makehdl('hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control'); catch me disp(me.message); end
### Generating HDL for 'hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control'. ### Using the config set for model <a href="matlab:configset.showParameterGroup('hdlcoderFocCurrentSingleTargetHdl', { 'HDL Code Generation' } )">hdlcoderFocCurrentSingleTargetHdl</a> for HDL code generation parameters. ### Starting HDL check. ### Creating HDL Code Generation Check Report file:///tmp/BR2020bd_1444674_32127/publish_examples5/tp5035f7c5/hdlsrc/hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control_report.html ### HDL check for 'hdlcoderFocCurrentSingleTargetHdl' complete with 1 errors, 0 warnings, and 0 messages. For the block 'hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control/DQ_Current_Control/D_Current_Control/Saturate_Output/Saturation_Dynamic' This block is not supported for Altera Megafunction mapping.
The error message indicates that the Dynamic Saturation block cannot map to floating-point library.
hilite_system('hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control/DQ_Current_Control/D_Current_Control/Saturate_Output/Saturation_Dynamic');
The blocks supported for floating-point library mapping is a subset of all HDL Coder supported blocks. Saturation dynamic is an example of a block that is supported for fixed-point, but not floating-point mapping. In these cases, the block may be described as a sub-graph of the supported subset. For a complete list of blocks and modes that can map to floating-point libraries, check HDL Coder Support for FPGA Floating-Point Library Mapping.
In this example, we will replace the Saturate_Output subsystems that contains Dynamic Saturation blocks with an alternative implementation.
open_system('floatFocUtils'); blocksToReplace = {'hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control/DQ_Current_Control/D_Current_Control/Saturate_Output', ... 'hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control/DQ_Current_Control/Q_Current_Control/Saturate_Output'... }; position1 = get_param(blocksToReplace{1}, 'Position'); delete_block(blocksToReplace{1}); add_block('floatFocUtils/Saturate_Output_Detailed', ... blocksToReplace{1}, 'Position', position1); position2 = get_param(blocksToReplace{2}, 'Position'); delete_block(blocksToReplace{2}); add_block('floatFocUtils/Saturate_Output_Detailed', ... blocksToReplace{2}, 'Position', position2); bdclose('floatFocUtils'); open_system(blocksToReplace{1}, 'force');
Try to generate code again
try makehdl('hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control'); catch me disp(me.message); end
### Generating HDL for 'hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control'. ### Using the config set for model <a href="matlab:configset.showParameterGroup('hdlcoderFocCurrentSingleTargetHdl', { 'HDL Code Generation' } )">hdlcoderFocCurrentSingleTargetHdl</a> for HDL code generation parameters. ### Starting HDL check. ### Using /mathworks/hub/share/apps/HDLTools/Altera/18.1-mw-0/Linux/quartus/bin/../sopc_builder/bin/ip-generate for the selected floating point IP library. ### Generating Altera(R) megafunction: alterafpf_add_single for target frequency of 250 MHz. ### alterafpf_add_single takes 3 cycles. ### Done. ### Generating Altera(R) megafunction: alterafpf_mul_single for target frequency of 250 MHz. ### alterafpf_mul_single takes 3 cycles. ### Done. ### Generating Altera(R) megafunction: alterafpf_sub_single for target frequency of 250 MHz. ### alterafpf_sub_single takes 3 cycles. ### Done. ### Generating Altera(R) megafunction: alterafpf_neq_single_NEQ for target frequency of 250 MHz. ### alterafpf_neq_single_NEQ takes 0 cycles. ### Done. ### Generating Altera(R) megafunction: alterafpf_le_single_LE for target frequency of 250 MHz. ### alterafpf_le_single_LE takes 1 cycles. ### Done. ### Generating Altera(R) megafunction: alterafpf_ge_single_GE for target frequency of 250 MHz. ### alterafpf_ge_single_GE takes 1 cycles. ### Done. ### Generating Altera(R) megafunction: alterafpf_gt_single_GT for target frequency of 250 MHz. ### alterafpf_gt_single_GT takes 1 cycles. ### Done. ### Generating Altera(R) megafunction: alterafpf_lt_single_LT for target frequency of 250 MHz. ### alterafpf_lt_single_LT takes 1 cycles. ### Done. ### Generating Altera(R) megafunction: alterafpf_trig_single_SIN for target frequency of 250 MHz. ### alterafpf_trig_single_SIN takes 26 cycles. ### Done. ### Generating Altera(R) megafunction: alterafpf_trig_single_COS for target frequency of 250 MHz. ### alterafpf_trig_single_COS takes 25 cycles. ### Done. ### Creating HDL Code Generation Check Report file:///tmp/BR2020bd_1444674_32127/publish_examples5/tp5035f7c5/hdlsrc/hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control_report.html ### HDL check for 'hdlcoderFocCurrentSingleTargetHdl' complete with 5 errors, 0 warnings, and 0 messages. ### HDL check for 'hdlcoderFocCurrentSingleTargetHdl' complete with 5 errors, 0 warnings, and 0 messages. Target-specific code generation cannot complete for the following reason(s): 'Cannot allocate 1 delays for hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control/DQ_Current_Control/D_Current_Control/Saturate_relop_lower.'.
These error messages indicate that HDL Coder cannot replace operations in feedback loops with floating-point IP modules, because those loops are modeled with fewer delays than the latency of the equivalent floating-point IP modules to be replaced with. Floating-point IP modules are implemented as pipelined blocks. For some modules, there are minimum latency requirements. As changing the latency of the feedback loop generates an incorrect implementation, HDL Coder prevents the addition of such latency inside feedback loop.
The error indicates that the adder inside the feedback loop requires multiple cycles but the loop has only one delay.
hilite_system('hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control/DQ_Current_Control/D_Current_Control/Add');
There are a few options available in this situation:
Reduce the target frequency may lower the pipelining depth requirement. But, this may also slow down all other IP modules in the design.
Configure the IP modules used in the loop with a smaller latency. This also slows down the IP modules' operating frequency, but only for specified IP modules.
Apply clock rate pipelining. When the data rate is slower than the FPGA clock rate, FPGA has multiple cycles at clock rate to finish operations and still retains the numerical consistency. For more information about clock rate pipelining, see Clock-Rate Pipelining.
Let us apply the clock-rate pipelining option to solve the feedback loop problem, since the sample time of 20 and the FPGA target frequency of 250 MHz (or 4 ns). Thus, we define the Oversampling factor as the ratio of the two values, i.e. 5000, meaning that one unit delay, such as the one shown in the loop, with sample time of 20
in the original model, is equivalent to 5000 clock rate cycles at sample time of 4 ns on the FPGA. They are sufficient for floating-point IP modules in the loops. Clock rate pipelining is an ideal option for this design.
Set oversampling to 5000.
hdlset_param('hdlcoderFocCurrentSingleTargetHdl', 'Oversampling', 5000);
Generate code
makehdl('hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control');
### Generating HDL for 'hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control'. ### Using the config set for model <a href="matlab:configset.showParameterGroup('hdlcoderFocCurrentSingleTargetHdl', { 'HDL Code Generation' } )">hdlcoderFocCurrentSingleTargetHdl</a> for HDL code generation parameters. ### Starting HDL check. ### Using /mathworks/hub/share/apps/HDLTools/Altera/18.1-mw-0/Linux/quartus/bin/../sopc_builder/bin/ip-generate for the selected floating point IP library. ### Generating Altera(R) megafunction: alterafpf_add_single for target frequency of 250 MHz. ### Found an existing generated file in a previous session: (/tmp/BR2020bd_1444674_32127/publish_examples5/tp5035f7c5/hdlsrc/hdlcoderFocCurrentSingleTargetHdl/Altera/Arria_10/unspecified/F250/synth/alterafpf_add_single.vhd). Reusing the generated file. ### alterafpf_add_single takes 3 cycles. ### Done. ### Generating Altera(R) megafunction: alterafpf_mul_single for target frequency of 250 MHz. ### Found an existing generated file in a previous session: (/tmp/BR2020bd_1444674_32127/publish_examples5/tp5035f7c5/hdlsrc/hdlcoderFocCurrentSingleTargetHdl/Altera/Arria_10/unspecified/F250/synth/alterafpf_mul_single.vhd). Reusing the generated file. ### alterafpf_mul_single takes 3 cycles. ### Done. ### Generating Altera(R) megafunction: alterafpf_gt_single_GT for target frequency of 250 MHz. ### Found an existing generated file in a previous session: (/tmp/BR2020bd_1444674_32127/publish_examples5/tp5035f7c5/hdlsrc/hdlcoderFocCurrentSingleTargetHdl/Altera/Arria_10/unspecified/F250/synth/alterafpf_gt_single_GT.vhd). Reusing the generated file. ### alterafpf_gt_single_GT takes 1 cycles. ### Done. ### Generating Altera(R) megafunction: alterafpf_lt_single_LT for target frequency of 250 MHz. ### Found an existing generated file in a previous session: (/tmp/BR2020bd_1444674_32127/publish_examples5/tp5035f7c5/hdlsrc/hdlcoderFocCurrentSingleTargetHdl/Altera/Arria_10/unspecified/F250/synth/alterafpf_lt_single_LT.vhd). Reusing the generated file. ### alterafpf_lt_single_LT takes 1 cycles. ### Done. ### Generating Altera(R) megafunction: alterafpf_sub_single for target frequency of 250 MHz. ### Found an existing generated file in a previous session: (/tmp/BR2020bd_1444674_32127/publish_examples5/tp5035f7c5/hdlsrc/hdlcoderFocCurrentSingleTargetHdl/Altera/Arria_10/unspecified/F250/synth/alterafpf_sub_single.vhd). Reusing the generated file. ### alterafpf_sub_single takes 3 cycles. ### Done. ### Generating Altera(R) megafunction: alterafpf_trig_single_SIN for target frequency of 250 MHz. ### Found an existing generated file in a previous session: (/tmp/BR2020bd_1444674_32127/publish_examples5/tp5035f7c5/hdlsrc/hdlcoderFocCurrentSingleTargetHdl/Altera/Arria_10/unspecified/F250/synth/alterafpf_trig_single_SIN.vhd). Reusing the generated file. ### alterafpf_trig_single_SIN takes 26 cycles. ### Done. ### Generating Altera(R) megafunction: alterafpf_trig_single_COS for target frequency of 250 MHz. ### Found an existing generated file in a previous session: (/tmp/BR2020bd_1444674_32127/publish_examples5/tp5035f7c5/hdlsrc/hdlcoderFocCurrentSingleTargetHdl/Altera/Arria_10/unspecified/F250/synth/alterafpf_trig_single_COS.vhd). Reusing the generated file. ### alterafpf_trig_single_COS takes 25 cycles. ### Done. ### Generating Altera(R) megafunction: alterafpf_le_single_LE for target frequency of 250 MHz. ### Found an existing generated file in a previous session: (/tmp/BR2020bd_1444674_32127/publish_examples5/tp5035f7c5/hdlsrc/hdlcoderFocCurrentSingleTargetHdl/Altera/Arria_10/unspecified/F250/synth/alterafpf_le_single_LE.vhd). Reusing the generated file. ### alterafpf_le_single_LE takes 1 cycles. ### Done. ### Generating Altera(R) megafunction: alterafpf_ge_single_GE for target frequency of 250 MHz. ### Found an existing generated file in a previous session: (/tmp/BR2020bd_1444674_32127/publish_examples5/tp5035f7c5/hdlsrc/hdlcoderFocCurrentSingleTargetHdl/Altera/Arria_10/unspecified/F250/synth/alterafpf_ge_single_GE.vhd). Reusing the generated file. ### alterafpf_ge_single_GE takes 1 cycles. ### Done. ### Generating Altera(R) megafunction: alterafpf_neq_single_NEQ for target frequency of 250 MHz. ### Found an existing generated file in a previous session: (/tmp/BR2020bd_1444674_32127/publish_examples5/tp5035f7c5/hdlsrc/hdlcoderFocCurrentSingleTargetHdl/Altera/Arria_10/unspecified/F250/synth/alterafpf_neq_single_NEQ.vhd). Reusing the generated file. ### alterafpf_neq_single_NEQ takes 0 cycles. ### Done. ### The code generation and optimization options you have chosen have introduced additional pipeline delays. ### The delay balancing feature has automatically inserted matching delays for compensation. ### The DUT requires an initial pipeline setup latency. Each output port experiences these additional delays. ### Output port 0: 2 cycles. ### Clock-rate pipelining results can be diagnosed by running this script: <a href="matlab:run('hdlsrc/hdlcoderFocCurrentSingleTargetHdl/highlightClockRatePipelining')">hdlsrc/hdlcoderFocCurrentSingleTargetHdl/highlightClockRatePipelining.m</a> ### To clear highlighting, click the following MATLAB script: <a href="matlab:run('hdlsrc/hdlcoderFocCurrentSingleTargetHdl/clearhighlighting.m')">hdlsrc/hdlcoderFocCurrentSingleTargetHdl/clearhighlighting.m</a> ### Generating new validation model: <a href="matlab:open_system('gm_hdlcoderFocCurrentSingleTargetHdl_vnl')">gm_hdlcoderFocCurrentSingleTargetHdl_vnl</a>. ### Validation model generation complete. ### Begin VHDL Code Generation for 'hdlcoderFocCurrentSingleTargetHdl'. ### MESSAGE: The design requires 5000 times faster clock with respect to the base rate = 2e-05. ### Working on hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control/DQ_Current_Control/D_Current_Control/Saturate_Output as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/Saturate_Output.vhd. ### Working on hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control/DQ_Current_Control/D_Current_Control as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/D_Current_Control.vhd. ### Working on hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control/DQ_Current_Control as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/DQ_Current_Control.vhd. ### Working on hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control/Clarke_Transform as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/Clarke_Transform.vhd. ### Working on hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control/Sine_Cosine as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/Sine_Cosine.vhd. ### Working on hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control/Park_Transform as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/Park_Transform.vhd. ### Working on hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control/Inverse_Park_Transform as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/Inverse_Park_Transform.vhd. ### Working on hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control/Inverse_Clarke_Transform as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/Inverse_Clarke_Transform.vhd. ### Working on hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control/Space_Vector_Modulation as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/Space_Vector_Modulation.vhd. ### Working on FOC_Current_Control_tc as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control_tc.vhd. ### Working on hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control.vhd. ### Generating package file hdlsrc/hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control_pkg.vhd. ### Generating HTML files for code generation report at <a href="matlab:web('/tmp/BR2020bd_1444674_32127/publish_examples5/tp5035f7c5/hdlsrc/hdlcoderFocCurrentSingleTargetHdl/html/hdlcoderFocCurrentSingleTargetHdl_codegen_rpt.html');">hdlcoderFocCurrentSingleTargetHdl_codegen_rpt.html</a> ### Creating HDL Code Generation Check Report file:///tmp/BR2020bd_1444674_32127/publish_examples5/tp5035f7c5/hdlsrc/hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control_report.html ### HDL check for 'hdlcoderFocCurrentSingleTargetHdl' complete with 0 errors, 0 warnings, and 2 messages. ### HDL code generation complete.
Now, the entire design is mapped to floating-point IP modules. The target code generation report summarizes the floating IP module usage.
Inspect the generated model for implementation details. For example, subsystem gm_hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control/DQ_Current_Control/D_Current_Control/Add corresponding to hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control/DQ_Current_Control/D_Current_Control/Add in the original model shows that this operation takes 3 cycles.
hilite_system('gm_hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control/DQ_Current_Control/D_Current_Control/Add/Add_pd1'); get_param('gm_hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control/DQ_Current_Control/D_Current_Control/Add/Add_pd1', ... 'DelayLength')
ans = '3'
Since floating-point IP modules introduce latencies across the design, HDL Coder automatically adds necessary matching delays to maintain data synchronization. See Delay Balancing for more details.
Floating-point IP modules are suitable to share, because they are usually identical for the same kind. Floating point IPs are typically expensive operations and it is desirable to share these resources, if possible, to reduce the area footprint. HDL Coder shares resources in the same subsystem. In order to allow more resources to share, we flatten the subsystem hierarchy and set resource sharing factor on the top network.
hdlset_param('hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control', 'FlattenHierarchy', 'on'); hdlset_param('hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control', 'SharingFactor', 4);
Generate code
makehdl('hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control');
### Generating HDL for 'hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control'. ### Using the config set for model <a href="matlab:configset.showParameterGroup('hdlcoderFocCurrentSingleTargetHdl', { 'HDL Code Generation' } )">hdlcoderFocCurrentSingleTargetHdl</a> for HDL code generation parameters. ### Starting HDL check. ### Generating Altera(R) megafunction: alterafpf_trig_single_COS for target frequency of 250 MHz. ### Found an existing generated file in a previous session: (/tmp/BR2020bd_1444674_32127/publish_examples5/tp5035f7c5/hdlsrc/hdlcoderFocCurrentSingleTargetHdl/Altera/Arria_10/unspecified/F250/synth/alterafpf_trig_single_COS.vhd). Reusing the generated file. ### alterafpf_trig_single_COS takes 25 cycles. ### Done. ### Generating Altera(R) megafunction: alterafpf_trig_single_SIN for target frequency of 250 MHz. ### Found an existing generated file in a previous session: (/tmp/BR2020bd_1444674_32127/publish_examples5/tp5035f7c5/hdlsrc/hdlcoderFocCurrentSingleTargetHdl/Altera/Arria_10/unspecified/F250/synth/alterafpf_trig_single_SIN.vhd). Reusing the generated file. ### alterafpf_trig_single_SIN takes 26 cycles. ### Done. ### Generating Altera(R) megafunction: alterafpf_mul_single for target frequency of 250 MHz. ### Found an existing generated file in a previous session: (/tmp/BR2020bd_1444674_32127/publish_examples5/tp5035f7c5/hdlsrc/hdlcoderFocCurrentSingleTargetHdl/Altera/Arria_10/unspecified/F250/synth/alterafpf_mul_single.vhd). Reusing the generated file. ### alterafpf_mul_single takes 3 cycles. ### Done. ### Generating Altera(R) megafunction: alterafpf_add_single for target frequency of 250 MHz. ### Found an existing generated file in a previous session: (/tmp/BR2020bd_1444674_32127/publish_examples5/tp5035f7c5/hdlsrc/hdlcoderFocCurrentSingleTargetHdl/Altera/Arria_10/unspecified/F250/synth/alterafpf_add_single.vhd). Reusing the generated file. ### alterafpf_add_single takes 3 cycles. ### Done. ### Generating Altera(R) megafunction: alterafpf_sub_single for target frequency of 250 MHz. ### Found an existing generated file in a previous session: (/tmp/BR2020bd_1444674_32127/publish_examples5/tp5035f7c5/hdlsrc/hdlcoderFocCurrentSingleTargetHdl/Altera/Arria_10/unspecified/F250/synth/alterafpf_sub_single.vhd). Reusing the generated file. ### alterafpf_sub_single takes 3 cycles. ### Done. ### Generating Altera(R) megafunction: alterafpf_gt_single_GT for target frequency of 250 MHz. ### Found an existing generated file in a previous session: (/tmp/BR2020bd_1444674_32127/publish_examples5/tp5035f7c5/hdlsrc/hdlcoderFocCurrentSingleTargetHdl/Altera/Arria_10/unspecified/F250/synth/alterafpf_gt_single_GT.vhd). Reusing the generated file. ### alterafpf_gt_single_GT takes 1 cycles. ### Done. ### Generating Altera(R) megafunction: alterafpf_lt_single_LT for target frequency of 250 MHz. ### Found an existing generated file in a previous session: (/tmp/BR2020bd_1444674_32127/publish_examples5/tp5035f7c5/hdlsrc/hdlcoderFocCurrentSingleTargetHdl/Altera/Arria_10/unspecified/F250/synth/alterafpf_lt_single_LT.vhd). Reusing the generated file. ### alterafpf_lt_single_LT takes 1 cycles. ### Done. ### Generating Altera(R) megafunction: alterafpf_neq_single_NEQ for target frequency of 250 MHz. ### Found an existing generated file in a previous session: (/tmp/BR2020bd_1444674_32127/publish_examples5/tp5035f7c5/hdlsrc/hdlcoderFocCurrentSingleTargetHdl/Altera/Arria_10/unspecified/F250/synth/alterafpf_neq_single_NEQ.vhd). Reusing the generated file. ### alterafpf_neq_single_NEQ takes 0 cycles. ### Done. ### Generating Altera(R) megafunction: alterafpf_ge_single_GE for target frequency of 250 MHz. ### Found an existing generated file in a previous session: (/tmp/BR2020bd_1444674_32127/publish_examples5/tp5035f7c5/hdlsrc/hdlcoderFocCurrentSingleTargetHdl/Altera/Arria_10/unspecified/F250/synth/alterafpf_ge_single_GE.vhd). Reusing the generated file. ### alterafpf_ge_single_GE takes 1 cycles. ### Done. ### Generating Altera(R) megafunction: alterafpf_le_single_LE for target frequency of 250 MHz. ### Found an existing generated file in a previous session: (/tmp/BR2020bd_1444674_32127/publish_examples5/tp5035f7c5/hdlsrc/hdlcoderFocCurrentSingleTargetHdl/Altera/Arria_10/unspecified/F250/synth/alterafpf_le_single_LE.vhd). Reusing the generated file. ### alterafpf_le_single_LE takes 1 cycles. ### Done. ### Using /mathworks/hub/share/apps/HDLTools/Altera/18.1-mw-0/Linux/quartus/bin/../sopc_builder/bin/ip-generate for the selected floating point IP library. ### Generating new validation model: <a href="matlab:open_system('gm_hdlcoderFocCurrentSingleTargetHdl_vnl')">gm_hdlcoderFocCurrentSingleTargetHdl_vnl</a>. ### Validation model generation complete. ### Begin VHDL Code Generation for 'hdlcoderFocCurrentSingleTargetHdl'. ### MESSAGE: The design requires 5000 times faster clock with respect to the base rate = 2e-05. ### Working on crp_temp_shared as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/crp_temp_shared.vhd. ### Working on crp_temp_shared_block as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/crp_temp_shared_block.vhd. ### Working on crp_temp_shared_block1 as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/crp_temp_shared_block1.vhd. ### Working on crp_temp_shared_block2 as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/crp_temp_shared_block2.vhd. ### Working on crp_temp_shared_block3 as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/crp_temp_shared_block3.vhd. ### Working on crp_temp_shared_block4 as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/crp_temp_shared_block4.vhd. ### Working on crp_temp_shared_block5 as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/crp_temp_shared_block5.vhd. ### Working on crp_temp_shared_block6 as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/crp_temp_shared_block6.vhd. ### Working on crp_temp_shared_block7 as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/crp_temp_shared_block7.vhd. ### Working on crp_temp_shared_block8 as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/crp_temp_shared_block8.vhd. ### Working on crp_temp_shared_block9 as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/crp_temp_shared_block9.vhd. ### Working on crp_temp_shared_block10 as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/crp_temp_shared_block10.vhd. ### Working on crp_temp_shared_block11 as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/crp_temp_shared_block11.vhd. ### Working on crp_temp_shared_block12 as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/crp_temp_shared_block12.vhd. ### Working on crp_temp_shared_block13 as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/crp_temp_shared_block13.vhd. ### Working on crp_temp_shared_block14 as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/crp_temp_shared_block14.vhd. ### Working on FOC_Current_Control_tc as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control_tc.vhd. ### Working on hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control as hdlsrc/hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control.vhd. ### Generating package file hdlsrc/hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control_pkg.vhd. ### Generating HTML files for code generation report at <a href="matlab:web('/tmp/BR2020bd_1444674_32127/publish_examples5/tp5035f7c5/hdlsrc/hdlcoderFocCurrentSingleTargetHdl/html/hdlcoderFocCurrentSingleTargetHdl_codegen_rpt.html');">hdlcoderFocCurrentSingleTargetHdl_codegen_rpt.html</a> ### Creating HDL Code Generation Check Report file:///tmp/BR2020bd_1444674_32127/publish_examples5/tp5035f7c5/hdlsrc/hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control_report.html ### HDL check for 'hdlcoderFocCurrentSingleTargetHdl' complete with 0 errors, 0 warnings, and 1 messages. ### HDL code generation complete.
We can confirm that fewer IP modules are inferred from the Floating-point resource report now.
We can also observe the resource sharing results by inspecting the generated model.
open_system('gm_hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control'); set_param('gm_hdlcoderFocCurrentSingleTargetHdl', 'SimulationCommand', 'update'); set_param('gm_hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control', 'ZoomFactor', 'FitSystem'); hilite_system('gm_hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control/crp_temp_shared'); hilite_system('gm_hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control/crp_temp_shared1'); hilite_system('gm_hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control/crp_temp_shared2'); hilite_system('gm_hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control/crp_temp_shared3'); hilite_system('gm_hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control/crp_temp_shared4'); hilite_system('gm_hdlcoderFocCurrentSingleTargetHdl/FOC_Current_Control/crp_temp_shared5');
Floating point IP libraries provide some customization options for their IP modules. In this section, we illustrate how to control this configuration in the HDL Coder workflow.
We will use XILINX LOGICORE and a simple model containing one add block for this section.
Create a floating-point target configuration object for XILINX LOGICORE.
fc = hdlcoder.createFloatingPointTargetConfig('XILINXLOGICORE');
In addition to library name, the configuration object has two other fields for library settings and individual IP module settings, respectively.
fc
fc = FloatingPointTargetConfig with properties: Library: 'XILINXLOGICORE' LibrarySettings: [1x1 fpconfig.LatencyDrivenMode] IPConfig: [1x1 hdlcoder.FloatingPointTargetConfig.IPConfig]
LibrarySettings contains library-wide settings. Check the setting for XILINX LOGICORE library.
fc.LibrarySettings
ans = LatencyDrivenMode with properties: LatencyStrategy: 'MIN' Objective: 'SPEED'
These are the settings applicable to all IP modules from this library. For example Objective specifies the c_optimization parameter to XILINX LOGICORE. We can switch it to 'AREA'.
fc.LibrarySettings.Objective = 'AREA';
fc.LibrarySettings
ans = LatencyDrivenMode with properties: LatencyStrategy: 'MIN' Objective: 'AREA'
Library settings are library specific. See Generate HDL Code for FPGA Floating-Point Target Libraries for all settings for specific libraries.
IPConfig provides settings, such as Latency and ExtraArgs, for individual IP modules.
As shown in the previous section, latency is a critical property for IP mapping. HDL Coder infers latency based on library settings and target frequency, if applicable. We can also specify latency for individual IP module with the configuration object and HDL Coder uses them for code generation and optimizations.
fc.IPConfig.customize('ADDSUB', 'SINGLE', 'Latency', 11); fc.IPConfig
ans = Name DataType MinLatency MaxLatency Latency ExtraArgs ___________ _________________________ __________ __________ _______ __________ {'ADDSUB' } {'DOUBLE' } 12 12 -1 {0x0 char} {'ADDSUB' } {'SINGLE' } 12 12 11 {0x0 char} {'CONVERT'} {'DOUBLE_TO_NUMERICTYPE'} 6 6 -1 {0x0 char} {'CONVERT'} {'NUMERICTYPE_TO_DOUBLE'} 6 6 -1 {0x0 char} {'CONVERT'} {'NUMERICTYPE_TO_SINGLE'} 6 6 -1 {0x0 char} {'CONVERT'} {'SINGLE_TO_NUMERICTYPE'} 6 6 -1 {0x0 char} {'DIV' } {'DOUBLE' } 57 57 -1 {0x0 char} {'DIV' } {'SINGLE' } 28 28 -1 {0x0 char} {'MUL' } {'DOUBLE' } 9 9 -1 {0x0 char} {'MUL' } {'SINGLE' } 8 8 -1 {0x0 char} {'RELOP' } {'DOUBLE' } 2 2 -1 {0x0 char} {'RELOP' } {'SINGLE' } 2 2 -1 {0x0 char} {'SQRT' } {'DOUBLE' } 57 57 -1 {0x0 char} {'SQRT' } {'SINGLE' } 28 28 -1 {0x0 char}
The latency for the ADDSUB IP becomes 11 instead of the default value 12.
Other IP specific settings are specified with ExtraArgs. For example, HDL Coder calls XILINX LOGICORE to generate floating-point IP modules without using any DSP blocks by default. XILINX LOGICORE provides a parameter c_mult_usage to control DSP usage. In order to use DSP blocks, we can pass a different setting with ExtraArgs to override the default behavior. Because the ExtraArgs string is appended to the default IP module generation parameters, it must comply with library setting syntax. Check IP library documents for parameter usage and syntax.
fc.IPConfig.customize('ADDSUB', 'SINGLE', 'ExtraArgs', 'CSET c_mult_usage=Full_Usage'); fc.IPConfig
ans = Name DataType MinLatency MaxLatency Latency ExtraArgs ___________ _________________________ __________ __________ _______ ________________________________ {'ADDSUB' } {'DOUBLE' } 12 12 -1 {0x0 char } {'ADDSUB' } {'SINGLE' } 12 12 11 {'CSET c_mult_usage=Full_Usage'} {'CONVERT'} {'DOUBLE_TO_NUMERICTYPE'} 6 6 -1 {0x0 char } {'CONVERT'} {'NUMERICTYPE_TO_DOUBLE'} 6 6 -1 {0x0 char } {'CONVERT'} {'NUMERICTYPE_TO_SINGLE'} 6 6 -1 {0x0 char } {'CONVERT'} {'SINGLE_TO_NUMERICTYPE'} 6 6 -1 {0x0 char } {'DIV' } {'DOUBLE' } 57 57 -1 {0x0 char } {'DIV' } {'SINGLE' } 28 28 -1 {0x0 char } {'MUL' } {'DOUBLE' } 9 9 -1 {0x0 char } {'MUL' } {'SINGLE' } 8 8 -1 {0x0 char } {'RELOP' } {'DOUBLE' } 2 2 -1 {0x0 char } {'RELOP' } {'SINGLE' } 2 2 -1 {0x0 char } {'SQRT' } {'DOUBLE' } 57 57 -1 {0x0 char } {'SQRT' } {'SINGLE' } 28 28 -1 {0x0 char }
Open the model and set the configuration object on it.
open_system('hdlcoder_targetIP_configuration'); hdlset_param('hdlcoder_targetIP_configuration', 'FloatingPointTargetConfiguration', fc);
Run synthesis and mapping to confirm the DSP block usage.
hWC = hdlcoder.WorkflowConfig('SynthesisTool','Xilinx ISE', ... 'TargetWorkflow','Generic ASIC/FPGA'); hWC.SkipPreRouteTimingAnalysis = true; hWC.RunTaskAnnotateModelWithSynthesisResult = false; hWC.GenerateRTLCode = true; hWC.validate; hdlcoder.runWorkflow('hdlcoder_targetIP_configuration/Add_Subsystem', hWC);
HDL Coder bridges the gap between high level algorithms modeled with floating-point and low level FPGA implementation details. It not only automates the process for fast prototyping, but also allows you to explore high level algorithm design choices efficiently. This example demonstrates the necessary steps to generate synthesizable floating-point HDL code. The command-line APIs used in this example helps to automate your entire code generation process and design space exploration. All the APIs have corresponding GUI settings for ease of usage. For more information about the APIs and GUI options, check Generate HDL Code for FPGA Floating-Point Target Libraries.