MATLAB Examples

Use Multicycle Path Constraints to Meet Timing for Slow Paths

This example shows how to apply multicycle path constraints in your design to meet timing requirements. Using multicycle path constraints can save area and reduce synthesis run times. For more information, see the enable-based multicycle path constraints documentation.

Contents

Introduction

Algorithms modeled in Simulink for HDL code generation can have multiple sample rates. These multiple rates can be part of the Simulink model, or can be introduced with HDL Coder options such as oversampling. With oversampling specified, the generated HDL code will run on the FPGA at a faster clock rate. This faster rate allows additional optimizations to take effect.

When HDL Coder is configured to use a single clock, it generates a timing controller to control clocked elements, such as delays, at different sample rates with clock enables. These clock enables are synchronous to the single clock and toggle at rates that are multiple times slower than the base clock. The data paths between slow clocked element pairs are called multicycle paths, because they allow data to take multiple clock cycles to travel. However, synthesis tools cannot infer this acceptable delay directly from the HDL code. The tools assume that data changes every cycle and must travel from one register to the next within one clock cycle. Synthesis tools have to take more effort to meet the excessive timing requirement and therefore can fail timing. By declaring a set of data paths as multicycle paths and providing the actual timing of these paths to the downstream synthesis tool, HDL Coder can simplify and accelerate the process of meeting the desired timing contstraints for a design.

This example demonstrates how to generate multicycle path constraints in HDL Coder so that timing requirements may be specified, allowing efficient timing analysis in the synthesis tool.

Applying multicycle constraints using HDL Coder

In this example, we use Xilinx Vivado 2016.4 post place and routing static timing analysis results for a Virtex7 device (xc7v2000t, fhg1761, -1) to show the impact of enabled based multicycle path constraints. Other synthesis tools and devices have similar behavior. HDL Coder generates constraint files of XDC format for Xilinx Vivado, UCF format for Xilinx ISE, and SDC format for Altera Quartus II.

Consider the example, hdlcoder_multi_cycle_path_constraints.slx. The model contains a direct form FIR filter with an adder chain in the critical path. While the input data rate of this filter is specified to be 2MHz, we want this design to run as fast as possible so that it can be integrated with other IPs requiring high frequency. We start by choosing a 130MHz clock frequency without any timing optimization by setting 'Oversampling factor' to 65 and 'TargetFrequency' to 130.

bdclose('all');
load_system('hdlcoder_multi_cycle_path_constraints');
open_system('hdlcoder_multi_cycle_path_constraints/Subsystem/Dot Product');
hdlset_param('hdlcoder_multi_cycle_path_constraints', 'Oversampling', 65);
hdlset_param('hdlcoder_multi_cycle_path_constraints', 'TargetFrequency', 130);
set_param('hdlcoder_multi_cycle_path_constraints', 'SimulationCommand', 'update');

Generate HDL with these settings and inspect the generated model. Notice that the generated model is actually idential to the original model.

makehdl('hdlcoder_multi_cycle_path_constraints/Subsystem');
load_system('gm_hdlcoder_multi_cycle_path_constraints');
set_param('gm_hdlcoder_multi_cycle_path_constraints', 'SimulationCommand', 'update');
open_system('gm_hdlcoder_multi_cycle_path_constraints/Subsystem/Dot Product');
### Generating HDL for 'hdlcoder_multi_cycle_path_constraints/Subsystem'.
### Using the config set for model <a href="matlab:configset.showParameterGroup('hdlcoder_multi_cycle_path_constraints', { 'HDL Code Generation' } )">hdlcoder_multi_cycle_path_constraints</a> for HDL code generation parameters.
### Starting HDL check.
### Begin VHDL Code Generation for 'hdlcoder_multi_cycle_path_constraints'.
### MESSAGE: The design requires 65 times faster clock with respect to the base rate = 2.
### Working on hdlcoder_multi_cycle_path_constraints/Subsystem/Dot Product as hdl_prj/hdlsrc/hdlcoder_multi_cycle_path_constraints/Dot_Product.vhd.
### Working on Subsystem_tc as hdl_prj/hdlsrc/hdlcoder_multi_cycle_path_constraints/Subsystem_tc.vhd.
### Working on hdlcoder_multi_cycle_path_constraints/Subsystem as hdl_prj/hdlsrc/hdlcoder_multi_cycle_path_constraints/Subsystem.vhd.
### Generating package file hdl_prj/hdlsrc/hdlcoder_multi_cycle_path_constraints/Subsystem_pkg.vhd.
### Writing Vivado multicycle constraints XDC file <a href="matlab:edit('hdl_prj/hdlsrc/hdlcoder_multi_cycle_path_constraints/Subsystem_constraints.xdc')">hdl_prj/hdlsrc/hdlcoder_multi_cycle_path_constraints/Subsystem_constraints.xdc</a>
### Creating HDL Code Generation Check Report file:///private/tmp/BR2017bd_684186_74069/tp83244cdc/hdl_prj/hdlsrc/hdlcoder_multi_cycle_path_constraints/Subsystem_report.html
### HDL check for 'hdlcoder_multi_cycle_path_constraints' complete with 0 errors, 0 warnings, and 1 messages.
### HDL code generation complete.

The generated HDL fails to meet the timing requirement for the clock at 130MHz. As shown in the timing report snippet below, the timing requirement is 7.692 ns (1/130MHz) and a negative slack indicates a timing violation of this requirement. Other synthesis tools' timing reports may look different, although the critial path from this example design will remain the same.

We are going to use multicycle path constraints to meet timing requirments. Check the original model.

open_system('hdlcoder_multi_cycle_path_constraints/Subsystem');

Notice that the Dot Product subsystem is surrounded by delays running at the desired 2MHz data rate. Due to the specified 65x oversampling, the design can tolerate multiple clock cycles for the data to propagate through it. HDL Coder requires multicycle regions to be surrounded by slow clocked elements, such as these delays, so that the constraints can define the paths among them as multicycle paths. Turn MulticyclePathConstraints on and HDL Coder will generate an additional file.

hdlset_param('hdlcoder_multi_cycle_path_constraints', 'MulticyclePathConstraints', 'on');

We can even increase the target frequency to 300MHz.

hdlset_param('hdlcoder_multi_cycle_path_constraints', 'Oversampling', 150);
hdlset_param('hdlcoder_multi_cycle_path_constraints', 'TargetFrequency', 300);

Generate HDL and multicycle path constraints.

makehdl('hdlcoder_multi_cycle_path_constraints/Subsystem');
### Generating HDL for 'hdlcoder_multi_cycle_path_constraints/Subsystem'.
### Using the config set for model <a href="matlab:configset.showParameterGroup('hdlcoder_multi_cycle_path_constraints', { 'HDL Code Generation' } )">hdlcoder_multi_cycle_path_constraints</a> for HDL code generation parameters.
### Starting HDL check.
### Begin VHDL Code Generation for 'hdlcoder_multi_cycle_path_constraints'.
### MESSAGE: The design requires 150 times faster clock with respect to the base rate = 2.
### Working on hdlcoder_multi_cycle_path_constraints/Subsystem/Dot Product as hdl_prj/hdlsrc/hdlcoder_multi_cycle_path_constraints/Dot_Product.vhd.
### Working on Subsystem_tc as hdl_prj/hdlsrc/hdlcoder_multi_cycle_path_constraints/Subsystem_tc.vhd.
### Working on hdlcoder_multi_cycle_path_constraints/Subsystem as hdl_prj/hdlsrc/hdlcoder_multi_cycle_path_constraints/Subsystem.vhd.
### Generating package file hdl_prj/hdlsrc/hdlcoder_multi_cycle_path_constraints/Subsystem_pkg.vhd.
### Writing Vivado multicycle constraints XDC file <a href="matlab:edit('hdl_prj/hdlsrc/hdlcoder_multi_cycle_path_constraints/Subsystem_constraints.xdc')">hdl_prj/hdlsrc/hdlcoder_multi_cycle_path_constraints/Subsystem_constraints.xdc</a>
### Creating HDL Code Generation Check Report file:///private/tmp/BR2017bd_684186_74069/tp83244cdc/hdl_prj/hdlsrc/hdlcoder_multi_cycle_path_constraints/Subsystem_report.html
### HDL check for 'hdlcoder_multi_cycle_path_constraints' complete with 0 errors, 0 warnings, and 1 messages.
### HDL code generation complete.

Inspect the generated constraint XDC file.

dbtype('hdl_prj/hdlsrc/hdlcoder_multi_cycle_path_constraints/Subsystem_constraints.xdc');
1     # Multicycle constraints for clock enable: Subsystem_tc.u1_d150_o0
2     set enbregcell [get_cells -hier -filter {mcp_info=="Subsystem_tc.u1_d150_o0"}]
3     set enbregnet [get_nets -of_objects [get_pins -of_objects $enbregcell -filter {DIRECTION == OUT}]]
4     set reglist [get_cells -of [filter [all_fanout -flat -endpoints_only $enbregnet] IS_ENABLE]]
5     set_multicycle_path 150 -setup -from $reglist -to $reglist -quiet
6     set_multicycle_path 149 -hold  -from $reglist -to $reglist -quiet
7     

These constraints first find flipflops that are driven by the 2MHz clock enable signal. Then, they define the paths among these flipflops multicycle paths to allow up to 150 cycles for data to propagate.

Inspect the generated model.

open_system('gm_hdlcoder_multi_cycle_path_constraints/Subsystem/Dot Product');
set_param('gm_hdlcoder_multi_cycle_path_constraints', 'SimulationCommand', 'update');

The generated model and HDL code are identical to the previous results, because generating enabled based multicycle path constraints does not alter the HDL architecture. The design was previously unable to meet the desired timing at 130MHz. However, when you specify multicycle path constraints, this design can run at 300MHz on the FPGA.

Additional information about multicycle path constraints:

Multicycle path constraints are required for synthesis tools to understand timing requirements. This information is extracted from the Simulink model since it cannot be inferred from the generated HDL code. Multicycle path constraints identify paths between clocked elements driven by the same clock enable. It can fail to meet timing requirements in certain cases. For example, a data path is not recognized as a multicycle path, if it is not gated with both input and output delays or is between two delays of different rates. Therefore, if you want to use multicycle path constraints for certaint parts in your design, it is important to retain the multicycle paths in that region from being altered by optimizations introducing pipelines, such as input and output pipelining, clock rate pipelining, adaptive pipelining resource sharing, streaming, pipelined math operations, e.g. Newton-Raphson method for sqrt or recip, Cordic algorithm for trigonometric functions, and floating-point IP mapping.