%% Using Multiple Clocks in HDL Coder
% This example shows how to instantiate multiple top-level
% synchronous clock input ports in HDL Coder(TM).

%   Copyright 2011-2020 The MathWorks, Inc.

%% Overview of Clocking Modes
% HDL Coder has two clocking modes. One mode generates a single
% clock input to the Device Under Test (DUT). The other mode generates a
% synchronous primary clock input for each Simulink(R) rate in the DUT.  By
% default, HDL Coder creates an HDL design that 
% uses a single clock port for the DUT.  In single clock mode, if multiple
% rates exist in the Simulink model, a timing controller is created to control
% the clocking to the portions of the model that run at a slower rate.  The
% timing controller generates a set of clock enables with the necessary rate
% and phase information to control the clocking for the design.  Each generated 
% clock enable is an integer multiple slower than the primary clock rate. 
% Each output signal rate is associated with a clock enable output signal that 
% indicates the correct timing to sample the output data.
%
% In synchronous multiple clock mode, the generated code has a set of clock
% ports as primary inputs to the DUT. Each clock port corresponds to a separate rate
% in the model. Transitions between rates require clock enables at a
% given rate that are out of phase with that rate's clock.  These out of
% phase signals are generated with a timing controller. A multiple clock
% model may require multiple timing controllers.
%
% The first example uses a multirate CIC Interpolation filter in single
% clock mode. The filter's input is also presented as an output for this
% example to present a model with output signals running at different rates.

load_system('hdlcoder_clockdemo');
open_system('hdlcoder_clockdemo/DUT');
set_param('hdlcoder_clockdemo', 'SimulationCommand', 'update');

%% Single Clock Mode DUT Timing Interface
% In single clock mode, the HDL code for the DUT has a set of three
% signals that do not appear in the Simulink diagram added to it.
% Collectively, these are a clock bundle that contains signals for clock,
% master clock enable, and reset.  These signals appear in the VHDL
% Entity declaration and are used throughout the generated code.

hdlset_param('hdlcoder_clockdemo', 'Traceability', 'on');
makehdl('hdlcoder_clockdemo/DUT');

%% Clock Summary Reporting in Single Clock Mode
% The file comment block in the HDL DUT code contains Clock Summary
% information. In single clock mode, this report contains a
% table detailing the sample rates for each clock enable output signal.
% The report also contains a table listing each user output signal and its
% associated clock enable output signal.  Any time a HTML report is
% generated, the Clock Summary Report is also generated.

%% Generating Synchronous Multiclock HDL Code
% To generate multiple synchronous clocks for this design, the
% |ClockInputs| property must be set to |multiple|. Either change the
% |ClockInputs| property at the command line using |makehdl| or change
% the *Clock inputs* setting to |Multiple| on the *HDL Code Generation > Global Settings*
% tab of the Configuration Parameters dialog box.

makehdl('hdlcoder_clockdemo/DUT', 'ClockInputs', 'multiple');

%% Clock Summary Information in Multiclock Mode
% The contents of the Clock Summary are different in multiple clock mode.
% The report now contains a clock table. This table has one entry for each
% primary DUT clock. It describes the relative clock ratio between each
% clock and the fastest clock in the model. As with single clock mode,
% this information is presented both in the HDL DUT file comment block and
% the HTML report.

%% Multiclock Mode and HDL Coder Optimizations
% Multiple synchronous clocks can be useful even for a design with only a
% single Simulink rate.  Various optimizations can require clock rates
% faster than indicated in the original model.  The following example
% demonstrates an audio filtering model that applies the same filter on the
% left and right channels. By default, HDL Coder would generate two filter
% modules in hardware. With this configuration, multiple clock mode still
% only generates one clock, just as single clock mode does.

bdclose hdlcoder_clockdemo;
load_system('hdlcoder_audiofiltering');
open_system('hdlcoder_audiofiltering/Audio filter');
hdlset_param('hdlcoder_audiofiltering', 'ClockInputs', 'Multiple');
hdlset_param('hdlcoder_audiofiltering/Audio filter', 'SharingFactor', 0);
makehdl('hdlcoder_audiofiltering/Audio filter', 'Traceability', 'on');

%% Using Multiple Clock Mode with Resource Sharing
% With resource sharing applied to the identical left and right channel
% atomic subsystems, only one filter is generated. To meet the Simulink
% timing requirements, the single filter is run at twice the clock
% rate as the original Simulink model, as is shown below.  Since the
% resource sharing optimization creates a second clock rate, the user can
% use synchronous multiple clock mode to provide external clocks for both
% rates. In this configuration, multiple clock mode still
% only generates one clock. You see the message:
%
% |The design requires 2 times faster clock with respect to the
% base rate = 0.00012207.|

bdclose gm_hdlcoder_audiofiltering;
hdlset_param('hdlcoder_audiofiltering/Audio filter', 'SharingFactor', 2);
makehdl('hdlcoder_audiofiltering/Audio filter', 'Traceability', 'on');
open_system('gm_hdlcoder_audiofiltering/Audio filter');
set_param('gm_hdlcoder_audiofiltering', 'SimulationCommand', 'update');

displayEndOfDemoMessage(mfilename)
