%% 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 
% <matlab:helpview(fullfile(docroot,'/hdlcoder/ug/enable-based-multicycle-constraints.html'))
% enable-based multicycle path constraints documentation>.

% Copyright 2011-2017 The MathWorks, Inc.

%% 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
% constraints 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 identical 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');

%%
% 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 critical path from this example
% design will remain the same.
%
% <<timingreport_off.png>> 

%%
% We are going to use 
% multicycle path constraints to meet timing requirements.  
% 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');

%%
% Inspect the generated constraint XDC file.
dbtype('hdl_prj/hdlsrc/hdlcoder_multi_cycle_path_constraints/Subsystem_constraints.xdc');

%%
% These constraints first find flip flops that are driven by the
% 2MHz clock enable signal.  Then, they define
% the paths among these flip flops 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.      
%
% <<timingreport_on.png>> 

%% 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 certain 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. 
%
displayEndOfDemoMessage(mfilename)

% LocalWords:  Vivado xc fhg XDC UCF SDC slx IPs timingreport prj xdc Raphson
% LocalWords:  recip ug
