%% Using the State Control block to generate more efficient code with HDL Coder(TM)
% This example shows how to use the State Control block to generate
% hardware-friendly HDL code using HDL Coder.

%   Copyright 2015-2016 The MathWorks, Inc.

%% Introduction to the State Control block
% The State Control block is a block that modifies the Simulink simulation
% behavior for its containing subsystem and all subsystems nested beneath
% it. Its purpose is to more closely model the synchronous behavior of clocked
% digital hardware, particularly with respect to blocks that have state and use
% explicit enable and reset signals.
%
% When a State Control block is placed in a subsystem and has its parameter set
% to ''Synchronous'', the generated HDL code will be more hardware
% friendly. When a subsystem is in Synchronous mode it is marked with a graphic
% ''S'' in its lower left corner. A State Control block with its parameter set
% to ''Classic'' behaves identically to when there is no State Control block in
% the subsystem.
%
% The simulation behavior difference between the two modes is small, but
% significant to generating efficient HDL code. The differences focus around the
% simulation behavior involving explicit reset and enable signals. For example,
% in Synchronous mode, the explicit block reset input has priority over the block
% enable input signal.

%% Classic mode behavior for Delay with explicit enable input port
% HDL code generated by HDL Coder simulates identically to the model that it is
% generated from.  In Classic State Control mode, the generated code for certain
% constructs implements sub-optimal hardware due to this requirement. For
% example, a Delay block with explicit enable input will generate a bypass
% register, comprised of a register and a multiplexer, in addition to the
% modeled register, to capture the Simulink Classic mode behavior.
%
% Examine the contents of Enabled_Delay.vhd to observe the additional register
% signals and the bypass register.

load_system('hdlcoder_statecontrol_model');
open_system('hdlcoder_statecontrol_model');
set_param('hdlcoder_statecontrol_model', 'SimulationCommand', 'update');
makehdl('hdlcoder_statecontrol_model/MAC FIR Block', 'TargetDirectory', 'hdlsrc_classic');

%%
type hdlsrc_classic/hdlcoder_statecontrol_model/Enabled_Delay.vhd

%% Synchronous mode behavior for Delay with explicit enable input port
% A Delay block with explicit enable in Synchronous State Control mode will
% generate HDL code that creates more efficient hardware. The implementation
% does not contain a bypass register.
% 
% Examine Enabled_Delay_Sync.vhd and note the improvement in the generated code
% as compared to the Classic mode output.

makehdl('hdlcoder_statecontrol_model/MAC FIR Block Sync', 'TargetDirectory', 'hdlsrc_sync');

%% 
type hdlsrc_sync/hdlcoder_statecontrol_model/Enabled_Delay_Sync.vhd

%% Enabled Subsystems
% When a model has an Enabled subsystem in Synchronous mode, the code generated
% for it will also be improved. A Synchronous mode Enabled subsystem will no
% longer generate bypass registers on the subsystem outputs. In addition, any
% registers inside the Enabled subsystem that have explicit enable inputs will
% also show the same improvements as discussed previously.

%% MATLAB Function Blocks and Synchronous Mode
% MATLAB Function Blocks require more precise configuration in order to be used
% in Synchronous mode. If the block contains a direct combinatorial path from
% block input to output, an additional setting must be enabled on the block.
%
% The Edit data menu pick on the MATLAB toolstrip opens the MATLAB Function
% block Ports and Data Manager. Each block containing a combinatorial output
% path must be marked as allowing direct feedthrough.
%
% <<MLFB_editdata1.png>>
%
% <<directfeedthrough1.png>>
%

%%
% This setting allows code to be generated in Synchronous mode from a MATLAB
% Function block, when that block has both combinatorial and sequential paths in
% its code.

open_system('hdlcoder_statecontrol_model/MAC FIR Block Sync/RAM delay line')
open_system('hdlcoder_statecontrol_model/MAC FIR Block Sync/RAM delay line/circular buffer logic')

%% For additional information
% To learn more about the State Control block, please refer to the block 
% <matlab:helpview(fullfile(docroot,'toolbox','hdlcoder','helptargets.map'),'hdlhelp_builtinStateControl_hdldefaultsStateControl')
% documentation>.

displayEndOfDemoMessage(mfilename)
