%% Floating Point Support: Field-Oriented Control Algorithm
% In this example you review a Field-Oriented Control (FOC) algorithm
% for a Permanent Magnet Synchronous Machine (PMSM) implemented using 
% single-precision and half-precision floating-point types.

% Copyright 2014-2020 The MathWorks, Inc.

%% Introduction
% You have seen the fixed-point version of this design in  
% <docid:hdlcoder_ug#example-hdlcoderFocCurrentFixptScript> that takes
% a deep dive into how to implement current control algorithm using
% fixed-point types. The model was converted to fixed-point before
% generating HDL code.
%
% 
% You can use floating-point single-precision types in your design and
% generate HDL code natively without converting to fixed-point types. This
% example shows design considerations when generating code from
% floating-point single-precision and half-precision variants* of the fixed
% point model hdlcoderFocCurrentFixptHdl. 
%
% The testbench model 'hdlcoderFocCurrentTestBench' has reference 
% block pointing to the DUT implemented in fixed-point or
% floating-point.
%% Salient features of Native Floating Point support.
% 
% * Vendor independent and target agnostic RTL for FPGA and/or ASIC design
% * Full range of IEEE-754 features including support for rounding modes,
% inf and nan data types, and optional support for denormal numbers.
% * Extensive math block (add,mul,div,recip,log,exp,sqrt, rsqrt) and
% trigonometric block (sin, cos, sincos, atan, atan2) support.
%
%% Why Use Floating-Point Types 
%
% Sometimes you may want to start and stay in floating-point to target HDL
% for the following reasons:
%
% * Your algorithms have large or unknown dynamic ranges (for example
% integrators in feedback loops)
% * Your algorithm uses operations that are difficult to design in
% fixed-point (ex: atan2)
%
% In the fixed-point version of the example hdlcoderFocCurrentFloatHDL.slx
% you notice that several fixed-point rounding and saturation
% decisions are made to preserve the numerical behavior of the algorithm. For
% example the block
% 'hdlcoderFocCurrentFixptHdl/FOC_Current_Control/DQ_Current_Control/D_Current_Control/Saturate'
% which is a saturation block has been placed in the integrator loop 
% so that results do not overflow due to accumulation in the loop.
%

open_system('hdlcoderFocCurrentFixptHdl');
open_system('hdlcoderFocCurrentFixptHdl/FOC_Current_Control/DQ_Current_Control/D_Current_Control/Saturate');
%%
%
% Sometimes, the task of fixed-point conversion could take several weeks to
% months with multiple levels of algorithm re-validation. It may also lead
% to undesirable loss of precision which might not be acceptable for some
% mission critical applications requiring very high accuracy. 
%
% In these situations, you can choose to use native floating point 
% synthesis features available in HDL Coder.
%
%% Single-Precision FOC Model
%
% To open the single-precision version of the algorithm, run these
% commands:

load_system('hdlcoderFocCurrentFloatHdl');
open_system('hdlcoderFocCurrentFloatHdl/FOC_Current_Control')
%%
% In comparison to the fixed-point algorithm, the single-precision model 
% does not require additional rounding and saturation blocks and settings 
% as can be seen in the floating-point version of the model
% 'hdlcoderFocCurrentFloatHdl/FOC_Current_Control/DQ_Current_Control/D_Current_Control'

open_system('hdlcoderFocCurrentFloatHdl/FOC_Current_Control/DQ_Current_Control/D_Current_Control')

%%
% To verify the behavior through simulation, run these commands:
hasSimPowerSystems = license ('test', 'Power_System_Blocks');
if hasSimPowerSystems
   open_system('hdlcoderFocCurrentTestBench')
   
   % set single-precision floating-point model in the testbench
   set_param('hdlcoderFocCurrentTestBench/Controller', 'ModelName', 'hdlcoderFocCurrentFloatHdl');
   
   set_param('hdlcoderFocCurrentTestBench','IgnoredZcDiagnostic','none');
   sim('hdlcoderFocCurrentTestBench')
   set_param('hdlcoderFocCurrentTestBench','IgnoredZcDiagnostic','warn');
end

%%
% You can generate HDL code and view the generated code for the controller.
%
hdlset_param('hdlcoderFocCurrentFloatHdl', 'FloatingPointTargetConfiguration', hdlcoder.createFloatingPointTargetConfig('NATIVEFLOATINGPOINT'));
makehdl('hdlcoderFocCurrentFloatHdl/FOC_Current_Control');

%% Half-Precision FOC Model
%
% For applications that require smaller dynamic range, you can use |half| 
% types without having to convert your design to use fixed-point types.
% Using |half| types consumes much less memory, has lower latency, and
% saves FPGA resources.
%
%
% Advantages of half-precision floating point types in hardware
% perspective:
%
% * Low latency
% * Low Area
% * High speed
% * 16-bit floating point behavior which will be useful for optimal storage
% * Wider dynamic range compared to integer or fixed point data types of
% same size
%
% Half-precision types have same features as single- and double-precision
% floating-point types. Supported operators include basic arithmetic
% operators(EX: Add/Sub, Mul, Div/Recip) and Gain, Relational operators,
% Data type conversions.
%

load_system('hdlcoderFocCurrentFloatHalfHdl');
open_system('hdlcoderFocCurrentFloatHalfHdl/FOC_Current_Control')
%%
% To verify the behavior through simulation, run these commands:
hasSimPowerSystems = license ('test', 'Power_System_Blocks');
if hasSimPowerSystems
   open_system('hdlcoderFocCurrentTestBench')
   
   % set half-precision floating-point model in the testbench
   set_param('hdlcoderFocCurrentTestBench/Controller', 'ModelName', 'hdlcoderFocCurrentFloatHalfHdl');
   
   set_param('hdlcoderFocCurrentTestBench','IgnoredZcDiagnostic','none');
   sim('hdlcoderFocCurrentTestBench')
   set_param('hdlcoderFocCurrentTestBench','IgnoredZcDiagnostic','warn');
end
%%
% You can generate HDL code and view the generated code for the controller.
%
hdlset_param('hdlcoderFocCurrentFloatHalfHdl', 'FloatingPointTargetConfiguration', hdlcoder.createFloatingPointTargetConfig('NATIVEFLOATINGPOINT'));
makehdl('hdlcoderFocCurrentFloatHalfHdl/FOC_Current_Control');
%%
% You can refer to documentation for full native floating-point capabilities
% available in HDL Coder. See link in the 
% <docid:hdlcoder_ug#bvcdkxk-1>.

displayEndOfDemoMessage(mfilename)