Main Content

Implement Control Signals-Based Mathematical Functions by Using HDL Coder

HDL Coder™ provides HDLMathLib blocks that have control signal based fixed point mathematical functions. This example shows how to implement various mathematical function blocks that have control ports, such as Sqrt, Atan2, SinCos, Reciprocal and Divide blocks.

HDLMathLib include these blocks that have control ports:

  • Sqrt

  • Atan2

  • Sin

  • Cos

  • SinCos

  • Cos+jSin

  • Reciprocal

  • Divide

HDLMathLib Library With Control Ports for Mathematical Functions

To see all the mathematical function blocks in the HDLMathLib library, open the library by using this command.

open_system('HDLMathLib')

Block Parameters

In the Block Parameter dialog box, you can set these parameters for the HDL Math Library blocks.

Latency Strategy - Select the latency strategy

  • Specify whether to map the blocks in your design to MAX, CUSTOM, or ZERO latency. See also LatencyStrategy.

  • Values: 'Max' (default), 'Custom', 'Zero'

Custom latency - Specify the custom latency value

  • When Latency Strategy is set to Custom, use this property to specify a custom latency value between ZERO and MAX latency. See also CustomLatency.

  • Values: '0' (default)

Output data type - Select the output data type

  • Specify the output data type. The data type can be inherited or specified directly. This parameter is available for only Sqrt, Divide and Reciprocal blocks.

  • Values: 'Inherit: Inherit via internal rule', 'Inherit: Inherit via back propagation' , 'Inherit: Same as first input' , 'double' , 'single' , 'half' , 'int8' , 'uint8' , int16 , 'uint16' , 'int32' , 'uint32' , 'int64' , 'uint64' , 'fixdt(1,16,0)' , 'fixdt(1,16,2^0,0)' , 'fixdt(1,16,2^0,0)' , '<data type expression>'

  • Limitation: Floating-point data types, such as half, single, and double are not supported for HDL code generation.

Saturate on integer overflow - Choose the behavior when integer overflow occurs

  • Specify whether overflows saturate or wrap. When you select this check box, overflows saturate to either the minimum or maximum value that the data type can represent. This parameter is available for only Sqrt, Divide, and Reciprocal blocks.

  • Values: 'on' (default), 'off'

Integer rounding mode - Select the rounding mode

  • Specify the rounding mode. This parameter is available only for Sqrt, Divide, and Reciprocal blocks.

  • Values: 'Zero' (default), 'Ceiling' , 'Convergent' , 'Floor' , 'Nearest' , 'Round' , 'Simplest'

  • Limitation: HDL code generation has these rounding mode limitations for HDL Math library blocks:

  1. Convergent and Round mode are not supported for Sqrt block.

  2. Only Zero and Simplest mode are supported for Divide block.

  3. Only Zero mode is supported for Reciprocal block.

Number of iterations - Number of iterations used

  • Specify the number of iterations to perform the CORDIC algorithm. The default value is 11. This parameter is available for Sin, Cos, SinCos, Cos+jSin, and Atan2 blocks.

  • Values: '11' (default)

Sqrt Block That have Control Signals

The table lists the input and output ports in the Sqrt block.

When you open the Sqrt block, it uses MATLAB® Function blocks for the data and valid lines.

open_system('hdlcoder_sqrt_bitset_control')
open_system('hdlcoder_sqrt_bitset_control/Sqrt')

Implement Control Signals-Based Sqrt Block

You can implement control signal-based Square root block and generate HDL code by using HDL Coder™.

Open and Run Simulink Model

Before opening the model, set the input. You can choose to set different inputs according to your particular requirements. This example uses these inputs, which are linear.

SQRT_input = fi(1/2^17:1/2^17:1,0,18,17)';

Specify the wordlength for fixed-point datatypes and the pipeline latency for the model.

WL = 18;  latency = 20;

Open the model hdlcoder_sqrt_bitset_control and specify sufficient stop time that required to process all the input combinations.

stoptime = length(SQRT_input)-1+latency;
open_system('hdlcoder_sqrt_bitset_control')
sim('hdlcoder_sqrt_bitset_control')

The figure shows the simulation waveform for the model. You can see that dataOut is valid when validOut is high.

Validate Simulink Output by Using Reference Output

To validate the output obtained by simulating the Simulink model, you can compare the Simulink output to a reference output. To obtain the reference output, use the sqrt function.

Compute the reference output by using the sqrt function.

ref_SQRT = sqrt(double(SQRT_input));

Use logical indexing to extract valid output.

implementation_SQRT = simulink_SQRT(valid_output);

To validate the output, plot the comparison results by using the comparison_plot function in this example. You can see that the maximum error from the comparison results is small.

comparison_plot_sqrt(ref_SQRT,implementation_SQRT,1,'SQRT linear input');
Maximum Error SQRT linear input 3.814697e-06 
Maximum PctError SQRT linear input 3.803159e-02 

Generate HDL Code for Square Root Implementation

Before you generate code, you can see the HDL settings saved on the model by using the hdlsaveparams function.

hdlsaveparams('hdlcoder_sqrt_bitset_control')
%% Set Model 'hdlcoder_sqrt_bitset_control' HDL parameters
hdlset_param('hdlcoder_sqrt_bitset_control', 'Backannotation', 'on');
hdlset_param('hdlcoder_sqrt_bitset_control', 'HDLSubsystem', 'hdlcoder_sqrt_bitset_control/Sqrt');
hdlset_param('hdlcoder_sqrt_bitset_control', 'ResetType', 'Synchronous');
hdlset_param('hdlcoder_sqrt_bitset_control', 'ResourceReport', 'on');
hdlset_param('hdlcoder_sqrt_bitset_control', 'SynthesisTool', 'Xilinx Vivado');
hdlset_param('hdlcoder_sqrt_bitset_control', 'SynthesisToolChipFamily', 'Virtex7');
hdlset_param('hdlcoder_sqrt_bitset_control', 'SynthesisToolDeviceName', 'xc7v2000t');
hdlset_param('hdlcoder_sqrt_bitset_control', 'SynthesisToolPackageName', 'fhg1761');
hdlset_param('hdlcoder_sqrt_bitset_control', 'SynthesisToolSpeedValue', '-2');
hdlset_param('hdlcoder_sqrt_bitset_control', 'TargetDirectory', 'hdl_prj\hdlsrc');
hdlset_param('hdlcoder_sqrt_bitset_control', 'TargetFrequency', 500);
hdlset_param('hdlcoder_sqrt_bitset_control', 'Traceability', 'on');

% Set SubSystem HDL parameters
hdlset_param('hdlcoder_sqrt_bitset_control/Sqrt', 'FlattenHierarchy', 'on');

hdlset_param('hdlcoder_sqrt_bitset_control/Sqrt/LumpLatency', 'Architecture', 'MATLAB Datapath');
% Set SubSystem HDL parameters
hdlset_param('hdlcoder_sqrt_bitset_control/Sqrt/LumpLatency', 'FlattenHierarchy', 'on');

% Set Sqrt HDL parameters
hdlset_param('hdlcoder_sqrt_bitset_control/Sqrt/Sqrt', 'LatencyStrategy', 'Max');

hdlset_param('hdlcoder_sqrt_bitset_control/Sqrt/ValidLine', 'Architecture', 'MATLAB Datapath');
% Set SubSystem HDL parameters
hdlset_param('hdlcoder_sqrt_bitset_control/Sqrt/ValidLine', 'FlattenHierarchy', 'on');

To generate HDL code for the Sqrt block in the model, use the makehdl function.

  makehdl('hdlcoder_sqrt_bitset_control/Sqrt')
  close_system('hdlcoder_sqrt_bitset_control')
  close all;
### Generating HDL for 'hdlcoder_sqrt_bitset_control/Sqrt'.
### Using the config set for model <a href="matlab:configset.showParameterGroup('hdlcoder_sqrt_bitset_control', { 'HDL Code Generation' } )">hdlcoder_sqrt_bitset_control</a> for HDL code generation parameters.
### Running HDL checks on the model 'hdlcoder_sqrt_bitset_control'.
### Begin compilation of the model 'hdlcoder_sqrt_bitset_control'...
### Applying HDL optimizations on the model 'hdlcoder_sqrt_bitset_control'...
### <a href="matlab:configset.internal.open('hdlcoder_sqrt_bitset_control','AdaptivePipelining')">'AdaptivePipelining'</a> is set to 'Off' for the model. 'AdaptivePipelining' can improve the achievable clock frequency and reduce the area usage on FPGA boards. To enable adaptive pipelining, please set the option to 'On'. When adaptive pipelining is enabled, it inserts pipeline registers to create patterns that efficiently map blocks to DSP units on the target FPGA device.
### <a href="matlab:configset.internal.open('hdlcoder_sqrt_bitset_control','LUTMapToRAM')">'LUTMapToRAM'</a> is set to 'On' for the model. This option is used to map lookup tables to a block RAM in hardware.  To disable pipeline insertion for mapping lookup tables to RAM, please set the option to 'Off'.
### Begin model generation.
### Model generation complete.
### Begin VHDL Code Generation for 'hdlcoder_sqrt_bitset_control'.
### Working on hdlcoder_sqrt_bitset_control/Sqrt/Sqrt as hdl_prj/hdlsrc/hdlcoder_sqrt_bitset_control/Sqrt_block.vhd.
### Working on hdlcoder_sqrt_bitset_control/Sqrt as hdl_prj/hdlsrc/hdlcoder_sqrt_bitset_control/Sqrt.vhd.
### Generating package file hdl_prj/hdlsrc/hdlcoder_sqrt_bitset_control/Sqrt_pkg.vhd.
### Code Generation for 'hdlcoder_sqrt_bitset_control' completed.
### Generating HTML files for code generation report at <a href="matlab:web('/tmp/Bdoc22a_1891349_33737/tp039321ee/ex55107189/hdl_prj/hdlsrc/hdlcoder_sqrt_bitset_control/html/hdlcoder_sqrt_bitset_control_codegen_rpt.html');">hdlcoder_sqrt_bitset_control_codegen_rpt.html</a>
### Creating HDL Code Generation Check Report file:///tmp/Bdoc22a_1891349_33737/tp039321ee/ex55107189/hdl_prj/hdlsrc/hdlcoder_sqrt_bitset_control/Sqrt_report.html
### HDL check for 'hdlcoder_sqrt_bitset_control' complete with 0 errors, 1 warnings, and 2 messages.
### HDL code generation complete.

Sqrt Block Synthesis Performance

The figure shows the Sqrt block synthesis performance on the Xilinx® Virtex® 7 and Intel® Stratix® V devices.

Atan2 Block with Control Signals

The table lists the input and output ports for Atan2.

The Atan2 block has number of iterations as mask parameter. The default value is 11 and latency depends on this masked parameter.

When you open the Atan2 block, it uses MATLAB Function blocks for the data and valid lines.

open_system('hdlcoder_atan2_control')
open_system('hdlcoder_atan2_control/Atan2')
open_system('hdlcoder_atan2_control/Atan2','force')

Implement Control Signal based Atan2 Block

You can implement control signal based Atan2 block and generate HDL code by using HDL Coder™.

Open and Run Simulink Model

Before opening the model, set the input as follows. You can chose to set different input as per your requirement. This example uses following inputs which is linear and sweep through input values -pi to pi.

input_values = (-pi:.01/(2*pi):pi)';
RADIUS = 10.^(-2.5:.25:0);

Specify the wordlength for fixed-point datatypes and the pipeline latency for the model. The latency depends up on the number of iterations.

WL_atan2 = 18; latency_atan2 = 14;

Setup variables for logging input x and y values.

x_log = zeros(length(input_values)*length(RADIUS),1);
y_log = zeros(length(input_values)*length(RADIUS),1);
for outerindex = 0:length(RADIUS)-1
    for index = 1:length(input_values)
        input = input_values(index);  % access current value
        y = RADIUS(outerindex+1)*sin(input);               % compute y
        x = RADIUS(outerindex+1)*cos(input);               % compute x
        addr = outerindex*length(input_values)+index;
        y_log(addr) = y;
        x_log(addr) = x;
    end
end

Open the model hdlcoder_atan2_control and specify sufficient stop time that required to process all the input combinations. The model has Atan2 block that implements the Atan2 using CORDIC algorithm for a validIn control signal.

stoptime_atan2 = length(x_log)-1+latency_atan2;
close all
open_system('hdlcoder_atan2_control')
sim('hdlcoder_atan2_control')

You can see the below waveform when you simulate the above model. You can see that dataOut is valid when validOut is high.

Validate Simulink Output By Using Reference Output

To validate the output obtained by simulating the Simulink model, you can compare the Simulink output with a reference output. To obtain the reference output, use the atan2 MATLAB function.

Compute the reference output by using the atan2 function. You can see that the maximum error observed from the comparison results is quite small.

comparison_plot_atan2(atan2(y_log,x_log),sim_final_theta(valid_out),3,'theta');
Maximum Error theta 7.233221e-03 

Generate HDL Code for Atan2 Implementation

Before you generate code, you can see the HDL settings saved on the model by using the hdlsaveparams function.

hdlsaveparams('hdlcoder_atan2_control')
%% Set Model 'hdlcoder_atan2_control' HDL parameters
hdlset_param('hdlcoder_atan2_control', 'HDLSubsystem', 'hdlcoder_atan2_control/Atan2');
hdlset_param('hdlcoder_atan2_control', 'ResetType', 'Synchronous');
hdlset_param('hdlcoder_atan2_control', 'SynthesisTool', 'Xilinx Vivado');
hdlset_param('hdlcoder_atan2_control', 'SynthesisToolChipFamily', 'Virtex7');
hdlset_param('hdlcoder_atan2_control', 'SynthesisToolDeviceName', 'xc7v2000t');
hdlset_param('hdlcoder_atan2_control', 'SynthesisToolPackageName', 'fhg1761');
hdlset_param('hdlcoder_atan2_control', 'SynthesisToolSpeedValue', '-2');
hdlset_param('hdlcoder_atan2_control', 'TargetDirectory', 'hdl_prj\hdlsrc');
hdlset_param('hdlcoder_atan2_control', 'TargetFrequency', 500);

hdlset_param('hdlcoder_atan2_control/Atan2/Atan2', 'Architecture', 'Cordic');

hdlset_param('hdlcoder_atan2_control/Atan2/LumpLatency', 'Architecture', 'MATLAB Datapath');
% Set SubSystem HDL parameters
hdlset_param('hdlcoder_atan2_control/Atan2/LumpLatency', 'FlattenHierarchy', 'on');

hdlset_param('hdlcoder_atan2_control/Atan2/ValidLine', 'Architecture', 'MATLAB Datapath');
% Set SubSystem HDL parameters
hdlset_param('hdlcoder_atan2_control/Atan2/ValidLine', 'FlattenHierarchy', 'on');

To generate HDL code for the Atan2 block in the model, use the makehdl function.

makehdl('hdlcoder_atan2_control/Atan2')
close_system('hdlcoder_atan2_control')
close all;
### Generating HDL for 'hdlcoder_atan2_control/Atan2'.
### Using the config set for model <a href="matlab:configset.showParameterGroup('hdlcoder_atan2_control', { 'HDL Code Generation' } )">hdlcoder_atan2_control</a> for HDL code generation parameters.
### Running HDL checks on the model 'hdlcoder_atan2_control'.
### Begin compilation of the model 'hdlcoder_atan2_control'...
### Applying HDL optimizations on the model 'hdlcoder_atan2_control'...
### <a href="matlab:configset.internal.open('hdlcoder_atan2_control','AdaptivePipelining')">'AdaptivePipelining'</a> is set to 'Off' for the model. 'AdaptivePipelining' can improve the achievable clock frequency and reduce the area usage on FPGA boards. To enable adaptive pipelining, please set the option to 'On'. When adaptive pipelining is enabled, it inserts pipeline registers to create patterns that efficiently map blocks to DSP units on the target FPGA device.
### <a href="matlab:configset.internal.open('hdlcoder_atan2_control','LUTMapToRAM')">'LUTMapToRAM'</a> is set to 'On' for the model. This option is used to map lookup tables to a block RAM in hardware.  To disable pipeline insertion for mapping lookup tables to RAM, please set the option to 'Off'.
### Begin model generation.
### Model generation complete.
### Begin VHDL Code Generation for 'hdlcoder_atan2_control'.
### Working on hdlcoder_atan2_control/Atan2/atan2_cordic_nw as hdl_prj/hdlsrc/hdlcoder_atan2_control/atan2_cordic_nw.vhd.
### Working on hdlcoder_atan2_control/Atan2 as hdl_prj/hdlsrc/hdlcoder_atan2_control/Atan2.vhd.
### Code Generation for 'hdlcoder_atan2_control' completed.
### Creating HDL Code Generation Check Report file:///tmp/Bdoc22a_1891349_33737/tp039321ee/ex55107189/hdl_prj/hdlsrc/hdlcoder_atan2_control/Atan2_report.html
### HDL check for 'hdlcoder_atan2_control' complete with 0 errors, 1 warnings, and 2 messages.
### HDL code generation complete.

Atan2 Block Synthesis Performance

The figure shows the Atan2 block synthesis performance on the Xilinx® Virtex® 7 and Intel® Stratix® V devices.

SinCos Block with Control Signals

The table lists the input and output port for SinCos block.

The SinCos block has number of iterations as the mask parameter. The default value is 11 and latency depends on this masked parameter.

When you open the SinCos block, it uses MATLAB Function blocks for the data and valid lines.

open_system('hdlcoder_sincos_control')
open_system('hdlcoder_sincos_control/SinCos')
open_system('hdlcoder_sincos_control/SinCos','force')

Implement Control Signal based SinCos Block

You can implement control signal based SinCos block and generate HDL code by using HDL Coder™.

Open and Run Simulink Model

Before opening the model, set the input as follows. You can chose to set different input as per your requirement. This example uses following inputs which is linear and sweep through input values -pi to pi.

input_values = (-pi:.01/(2*pi):pi)';

Specify the wordlength for fixed-point datatypes and the pipeline latency for the model. The latency depends up on the number of iterations.

WL_SinCos = 18; latency_SinCos = 12;

Open the model hdlcoder_sincos_control and specify sufficient stop time that required to process all the input combinations. The model has SinCos block that implements the SinCos using CORDIC algorithm for a validIn control signal. The remaining trigonometric function blocks(Sin, Cos and Cos + jSin) use the same CORDIC approximation method and the interface ports differs respectively.

stoptime_sincos = length(input_values)-1+latency_SinCos;
open_system('hdlcoder_sincos_control')
sim('hdlcoder_sincos_control')

You can see this waveform when you simulate the above model. You can see that dataOut is valid when validOut is high.

Validate Simulink Output By Using Reference Output

To validate the output obtained by simulating the Simulink model, you can compare the Simulink output with a reference output. To obtain the reference output, use the sin and cos MATLAB function.

Compute the reference output by using the sin function. You can see that the maximum error observed from the comparison results is quite small.

comparison_plot_sincos(sin(input_values),sim_final_sintheta(valid_out),5,'sin');
Maximum Error sin 1.005291e-03 

Compute the reference output by using the Cos function. You can see that the maximum error observed from the comparison results is quite small.

comparison_plot_sincos(cos(input_values),sim_final_costheta(valid_out),6,'cos');
Maximum Error cos 1.036532e-03 

Generate HDL Code for SinCos Implementation

Before you generate code, you can see the HDL settings saved on the model by using the hdlsaveparams function.

hdlsaveparams('hdlcoder_sincos_control')
%% Set Model 'hdlcoder_sincos_control' HDL parameters
hdlset_param('hdlcoder_sincos_control', 'HDLSubsystem', 'hdlcoder_sincos_control/SinCos');
hdlset_param('hdlcoder_sincos_control', 'ResetType', 'Synchronous');
hdlset_param('hdlcoder_sincos_control', 'SynthesisTool', 'Xilinx Vivado');
hdlset_param('hdlcoder_sincos_control', 'SynthesisToolChipFamily', 'Virtex7');
hdlset_param('hdlcoder_sincos_control', 'SynthesisToolDeviceName', 'xc7v2000t');
hdlset_param('hdlcoder_sincos_control', 'SynthesisToolPackageName', 'fhg1761');
hdlset_param('hdlcoder_sincos_control', 'SynthesisToolSpeedValue', '-2');
hdlset_param('hdlcoder_sincos_control', 'TargetDirectory', 'hdl_prj\hdlsrc');
hdlset_param('hdlcoder_sincos_control', 'TargetFrequency', 500);

hdlset_param('hdlcoder_sincos_control/SinCos/LumpLatency', 'Architecture', 'MATLAB Datapath');
% Set SubSystem HDL parameters
hdlset_param('hdlcoder_sincos_control/SinCos/LumpLatency', 'FlattenHierarchy', 'on');

hdlset_param('hdlcoder_sincos_control/SinCos/LumpLatency1', 'Architecture', 'MATLAB Datapath');
% Set SubSystem HDL parameters
hdlset_param('hdlcoder_sincos_control/SinCos/LumpLatency1', 'FlattenHierarchy', 'on');

hdlset_param('hdlcoder_sincos_control/SinCos/SinCos', 'Architecture', 'Cordic');

hdlset_param('hdlcoder_sincos_control/SinCos/ValidLine', 'Architecture', 'MATLAB Datapath');
% Set SubSystem HDL parameters
hdlset_param('hdlcoder_sincos_control/SinCos/ValidLine', 'FlattenHierarchy', 'on');

To generate HDL code for the SinCos block in the model, use the makehdl function.

makehdl('hdlcoder_sincos_control/SinCos')
close_system('hdlcoder_sincos_control')
close all;
### Generating HDL for 'hdlcoder_sincos_control/SinCos'.
### Using the config set for model <a href="matlab:configset.showParameterGroup('hdlcoder_sincos_control', { 'HDL Code Generation' } )">hdlcoder_sincos_control</a> for HDL code generation parameters.
### Running HDL checks on the model 'hdlcoder_sincos_control'.
### Begin compilation of the model 'hdlcoder_sincos_control'...
### Applying HDL optimizations on the model 'hdlcoder_sincos_control'...
### <a href="matlab:configset.internal.open('hdlcoder_sincos_control','AdaptivePipelining')">'AdaptivePipelining'</a> is set to 'Off' for the model. 'AdaptivePipelining' can improve the achievable clock frequency and reduce the area usage on FPGA boards. To enable adaptive pipelining, please set the option to 'On'. When adaptive pipelining is enabled, it inserts pipeline registers to create patterns that efficiently map blocks to DSP units on the target FPGA device.
### <a href="matlab:configset.internal.open('hdlcoder_sincos_control','LUTMapToRAM')">'LUTMapToRAM'</a> is set to 'On' for the model. This option is used to map lookup tables to a block RAM in hardware.  To disable pipeline insertion for mapping lookup tables to RAM, please set the option to 'Off'.
### Begin model generation.
### Model generation complete.
### Begin VHDL Code Generation for 'hdlcoder_sincos_control'.
### Working on hdlcoder_sincos_control/SinCos/SinCos_cordic_nw as hdl_prj/hdlsrc/hdlcoder_sincos_control/SinCos_cordic_nw.vhd.
### Working on hdlcoder_sincos_control/SinCos as hdl_prj/hdlsrc/hdlcoder_sincos_control/SinCos.vhd.
### Code Generation for 'hdlcoder_sincos_control' completed.
### Creating HDL Code Generation Check Report file:///tmp/Bdoc22a_1891349_33737/tp039321ee/ex55107189/hdl_prj/hdlsrc/hdlcoder_sincos_control/SinCos_report.html
### HDL check for 'hdlcoder_sincos_control' complete with 0 errors, 1 warnings, and 3 messages.
### HDL code generation complete.

SinCos Block Synthesis Performance

The figure shows the SinCos block synthesis performance on the Xilinx Virtex 7 and Intel Stratix V devices.

Reciprocal Block with Control Signals

The table lists the input and output ports of Reciprocal block.

When you open the Reciprocal block, it uses MATLAB Function blocks for the data and valid lines.

open_system('hdlcoder_reciprocal_shiftadd_control')
open_system('hdlcoder_reciprocal_shiftadd_control/Reciprocal')

Implement Control Signal based Reciprocal Block

You can implement control signal based Reciprocal block and generate HDL code by using HDL Coder™.

Open and Run Simulink Model

Before opening the model, set the input as follows. You can chose to set different input as per your requirement. This example uses following inputs which is linear.

reciprocal_input = fi(1/2^17:1/2^17:1,0,18,17)';

Specify the wordlength for fixed-point datatypes and the pipeline latency for the model.

WL_recip = 18;  recip_latency = 22;

Open the model hdlcoder_reciprocal_shiftadd_control and specify sufficient stop time that required to process all the input combinations.

stoptime_recip = length(reciprocal_input)-1+recip_latency;
open_system('hdlcoder_reciprocal_shiftadd_control')
sim('hdlcoder_reciprocal_shiftadd_control')

You can see this waveform when you simulate the above model. You can see that dataOut is valid when validOut is high.

Validate Simulink Output By Using Reference Output

To validate the output obtained by simulating the Simulink model, you can compare the Simulink output with a reference output. To obtain the reference output, use the sqrt function.

Compute the reference output by using the reciprocal operation.

ref_reciprocal = 1./double(reciprocal_input);

Use logical indexing to extract valid output.

implementation_reciprocal = simulink_reciprocal(valid_output);

To validate the output, plot the comparison results by using the comparison_plot_reciprocal function in this example. You can see that the maximum error observed from the comparison results is quite small.

comparison_plot_reciprocal(ref_reciprocal,implementation_reciprocal,9,'reciprocal linear input');
Maximum Error reciprocal linear input 9.999771e-01 
Maximum PctError reciprocal linear input 4.999924e+01 

Generate HDL Code for Reciprocal Implementation

Before you generate code, you can see the HDL settings saved on the model by using the hdlsaveparams function.

hdlsaveparams('hdlcoder_reciprocal_shiftadd_control')
%% Set Model 'hdlcoder_reciprocal_shiftadd_control' HDL parameters
hdlset_param('hdlcoder_reciprocal_shiftadd_control', 'Backannotation', 'on');
hdlset_param('hdlcoder_reciprocal_shiftadd_control', 'HDLSubsystem', 'hdlcoder_reciprocal_shiftadd_control/Reciprocal');
hdlset_param('hdlcoder_reciprocal_shiftadd_control', 'ResetType', 'Synchronous');
hdlset_param('hdlcoder_reciprocal_shiftadd_control', 'ResourceReport', 'on');
hdlset_param('hdlcoder_reciprocal_shiftadd_control', 'SynthesisTool', 'Xilinx Vivado');
hdlset_param('hdlcoder_reciprocal_shiftadd_control', 'SynthesisToolChipFamily', 'Virtex7');
hdlset_param('hdlcoder_reciprocal_shiftadd_control', 'SynthesisToolDeviceName', 'xc7v2000t');
hdlset_param('hdlcoder_reciprocal_shiftadd_control', 'SynthesisToolPackageName', 'fhg1761');
hdlset_param('hdlcoder_reciprocal_shiftadd_control', 'SynthesisToolSpeedValue', '-2');
hdlset_param('hdlcoder_reciprocal_shiftadd_control', 'TargetDirectory', 'hdl_prj\hdlsrc');
hdlset_param('hdlcoder_reciprocal_shiftadd_control', 'TargetFrequency', 500);
hdlset_param('hdlcoder_reciprocal_shiftadd_control', 'Traceability', 'on');

% Set SubSystem HDL parameters
hdlset_param('hdlcoder_reciprocal_shiftadd_control/Reciprocal', 'FlattenHierarchy', 'on');

hdlset_param('hdlcoder_reciprocal_shiftadd_control/Reciprocal/LumpLatency', 'Architecture', 'MATLAB Datapath');
% Set SubSystem HDL parameters
hdlset_param('hdlcoder_reciprocal_shiftadd_control/Reciprocal/LumpLatency', 'FlattenHierarchy', 'on');

hdlset_param('hdlcoder_reciprocal_shiftadd_control/Reciprocal/Reciprocal', 'Architecture', 'ShiftAdd');

hdlset_param('hdlcoder_reciprocal_shiftadd_control/Reciprocal/ValidLine', 'Architecture', 'MATLAB Datapath');
% Set SubSystem HDL parameters
hdlset_param('hdlcoder_reciprocal_shiftadd_control/Reciprocal/ValidLine', 'FlattenHierarchy', 'on');

To generate HDL code for the Reciprocal block in the model, use the makehdl function.

makehdl('hdlcoder_reciprocal_shiftadd_control/Reciprocal')
close_system('hdlcoder_reciprocal_shiftadd_control')
close all;
### Generating HDL for 'hdlcoder_reciprocal_shiftadd_control/Reciprocal'.
### Using the config set for model <a href="matlab:configset.showParameterGroup('hdlcoder_reciprocal_shiftadd_control', { 'HDL Code Generation' } )">hdlcoder_reciprocal_shiftadd_control</a> for HDL code generation parameters.
### Running HDL checks on the model 'hdlcoder_reciprocal_shiftadd_control'.
### Begin compilation of the model 'hdlcoder_reciprocal_shiftadd_control'...
### Applying HDL optimizations on the model 'hdlcoder_reciprocal_shiftadd_control'...
### <a href="matlab:configset.internal.open('hdlcoder_reciprocal_shiftadd_control','AdaptivePipelining')">'AdaptivePipelining'</a> is set to 'Off' for the model. 'AdaptivePipelining' can improve the achievable clock frequency and reduce the area usage on FPGA boards. To enable adaptive pipelining, please set the option to 'On'. When adaptive pipelining is enabled, it inserts pipeline registers to create patterns that efficiently map blocks to DSP units on the target FPGA device.
### <a href="matlab:configset.internal.open('hdlcoder_reciprocal_shiftadd_control','LUTMapToRAM')">'LUTMapToRAM'</a> is set to 'On' for the model. This option is used to map lookup tables to a block RAM in hardware.  To disable pipeline insertion for mapping lookup tables to RAM, please set the option to 'Off'.
### Begin model generation.
### Model generation complete.
### Begin VHDL Code Generation for 'hdlcoder_reciprocal_shiftadd_control'.
### Working on hdlcoder_reciprocal_shiftadd_control/Reciprocal/Reciprocal as hdl_prj/hdlsrc/hdlcoder_reciprocal_shiftadd_control/Reciprocal_block.vhd.
### Working on hdlcoder_reciprocal_shiftadd_control/Reciprocal as hdl_prj/hdlsrc/hdlcoder_reciprocal_shiftadd_control/Reciprocal.vhd.
### Code Generation for 'hdlcoder_reciprocal_shiftadd_control' completed.
### Generating HTML files for code generation report at <a href="matlab:web('/tmp/Bdoc22a_1891349_33737/tp039321ee/ex55107189/hdl_prj/hdlsrc/hdlcoder_reciprocal_shiftadd_control/html/hdlcoder_reciprocal_shiftadd_control_codegen_rpt.html');">hdlcoder_reciprocal_shiftadd_control_codegen_rpt.html</a>
### Creating HDL Code Generation Check Report file:///tmp/Bdoc22a_1891349_33737/tp039321ee/ex55107189/hdl_prj/hdlsrc/hdlcoder_reciprocal_shiftadd_control/Reciprocal_report.html
### HDL check for 'hdlcoder_reciprocal_shiftadd_control' complete with 0 errors, 1 warnings, and 2 messages.
### HDL code generation complete.

Reciprocal Block Synthesis Performance

The figure shows the Reciprocal block synthesis performance on the Xilinx Virtex 7 and Intel Stratix V devices.

Divide Block with Control Signals

The table lists the input and output ports of Divide block.

When you open the Divide block, it uses MATLAB Function blocks for the data and valid lines.

open_system('hdlcoder_divide_shiftadd_control')
open_system('hdlcoder_divide_shiftadd_control/Divide')

Implement Control Signal based Divide Block

You can implement control signal based Divide block and generate HDL code by using HDL Coder™.

Open and Run Simulink Model

Before opening the model, set the input as follows. You can chose to set different input as per your requirement. This example uses following inputs which is linear.

dividend_input = fi(1/2^17:1/2^17:1,0,18,17)';
divisor_input = fi(1/2^17:1/2^17:1,0,18,13)';

Specify the wordlength for fixed-point datatypes and the pipeline latency for the model.

WL_divide = 18;  divide_latency = 22;

Open the model hdlcoder_divide_shiftadd_control and specify sufficient stop time that required to process all the input combinations.

stoptime_divide = length(dividend_input)-1+divide_latency;
open_system('hdlcoder_divide_shiftadd_control')
sim('hdlcoder_divide_shiftadd_control')

You can see this waveform when you simulate the above model. You can see that dataOut is valid when validOut is high.

Validate Simulink Output By Using Reference Output

To validate the output obtained by simulating the Simulink model, you can compare the Simulink output with a reference output. To obtain the reference output, use the sqrt function.

Compute the reference output by using the divide function.

ref_divide = double(dividend_input)./double(divisor_input);

Use logical indexing to extract valid output.

implementation_divide = simulink_divide(valid_output);

To validate the output, plot the comparison results by using the comparison_plot_divide function in this example. You can see that the maximum error observed from the comparison results is quite small.

comparison_plot_divide(ref_divide,implementation_divide,11,'divide linear input');
Maximum Error divide linear input Inf 
Maximum PctError divide linear input 6.249285e+00 

Generate HDL Code for Divide Implementation

Before you generate code, you can see the HDL settings saved on the model by using the hdlsaveparams function.

hdlsaveparams('hdlcoder_divide_shiftadd_control')
%% Set Model 'hdlcoder_divide_shiftadd_control' HDL parameters
hdlset_param('hdlcoder_divide_shiftadd_control', 'Backannotation', 'on');
hdlset_param('hdlcoder_divide_shiftadd_control', 'HDLSubsystem', 'hdlcoder_divide_shiftadd_control/Divide');
hdlset_param('hdlcoder_divide_shiftadd_control', 'ResetType', 'Synchronous');
hdlset_param('hdlcoder_divide_shiftadd_control', 'ResourceReport', 'on');
hdlset_param('hdlcoder_divide_shiftadd_control', 'SynthesisTool', 'Xilinx Vivado');
hdlset_param('hdlcoder_divide_shiftadd_control', 'SynthesisToolChipFamily', 'Virtex7');
hdlset_param('hdlcoder_divide_shiftadd_control', 'SynthesisToolDeviceName', 'xc7v2000t');
hdlset_param('hdlcoder_divide_shiftadd_control', 'SynthesisToolPackageName', 'fhg1761');
hdlset_param('hdlcoder_divide_shiftadd_control', 'SynthesisToolSpeedValue', '-2');
hdlset_param('hdlcoder_divide_shiftadd_control', 'TargetDirectory', 'hdl_prj\hdlsrc');
hdlset_param('hdlcoder_divide_shiftadd_control', 'TargetFrequency', 500);
hdlset_param('hdlcoder_divide_shiftadd_control', 'Traceability', 'on');

% Set SubSystem HDL parameters
hdlset_param('hdlcoder_divide_shiftadd_control/Divide', 'FlattenHierarchy', 'on');

hdlset_param('hdlcoder_divide_shiftadd_control/Divide/Divide', 'Architecture', 'ShiftAdd');

hdlset_param('hdlcoder_divide_shiftadd_control/Divide/LumpLatency', 'Architecture', 'MATLAB Datapath');
% Set SubSystem HDL parameters
hdlset_param('hdlcoder_divide_shiftadd_control/Divide/LumpLatency', 'FlattenHierarchy', 'on');

hdlset_param('hdlcoder_divide_shiftadd_control/Divide/ValidLine', 'Architecture', 'MATLAB Datapath');
% Set SubSystem HDL parameters
hdlset_param('hdlcoder_divide_shiftadd_control/Divide/ValidLine', 'FlattenHierarchy', 'on');

To generate HDL code for the Divide block in the model, use the makehdl function.

makehdl('hdlcoder_divide_shiftadd_control/Divide')
close_system('hdlcoder_divide_shiftadd_control')
close all;
### Generating HDL for 'hdlcoder_divide_shiftadd_control/Divide'.
### Using the config set for model <a href="matlab:configset.showParameterGroup('hdlcoder_divide_shiftadd_control', { 'HDL Code Generation' } )">hdlcoder_divide_shiftadd_control</a> for HDL code generation parameters.
### Running HDL checks on the model 'hdlcoder_divide_shiftadd_control'.
### Begin compilation of the model 'hdlcoder_divide_shiftadd_control'...
### Applying HDL optimizations on the model 'hdlcoder_divide_shiftadd_control'...
### <a href="matlab:configset.internal.open('hdlcoder_divide_shiftadd_control','AdaptivePipelining')">'AdaptivePipelining'</a> is set to 'Off' for the model. 'AdaptivePipelining' can improve the achievable clock frequency and reduce the area usage on FPGA boards. To enable adaptive pipelining, please set the option to 'On'. When adaptive pipelining is enabled, it inserts pipeline registers to create patterns that efficiently map blocks to DSP units on the target FPGA device.
### <a href="matlab:configset.internal.open('hdlcoder_divide_shiftadd_control','LUTMapToRAM')">'LUTMapToRAM'</a> is set to 'On' for the model. This option is used to map lookup tables to a block RAM in hardware.  To disable pipeline insertion for mapping lookup tables to RAM, please set the option to 'Off'.
### Begin model generation.
### Model generation complete.
### Begin VHDL Code Generation for 'hdlcoder_divide_shiftadd_control'.
### Working on hdlcoder_divide_shiftadd_control/Divide/Divide as hdl_prj/hdlsrc/hdlcoder_divide_shiftadd_control/Divide_block.vhd.
### Working on hdlcoder_divide_shiftadd_control/Divide as hdl_prj/hdlsrc/hdlcoder_divide_shiftadd_control/Divide.vhd.
### Code Generation for 'hdlcoder_divide_shiftadd_control' completed.
### Generating HTML files for code generation report at <a href="matlab:web('/tmp/Bdoc22a_1891349_33737/tp039321ee/ex55107189/hdl_prj/hdlsrc/hdlcoder_divide_shiftadd_control/html/hdlcoder_divide_shiftadd_control_codegen_rpt.html');">hdlcoder_divide_shiftadd_control_codegen_rpt.html</a>
### Creating HDL Code Generation Check Report file:///tmp/Bdoc22a_1891349_33737/tp039321ee/ex55107189/hdl_prj/hdlsrc/hdlcoder_divide_shiftadd_control/Divide_report.html
### HDL check for 'hdlcoder_divide_shiftadd_control' complete with 0 errors, 1 warnings, and 2 messages.
### HDL code generation complete.

Divide Block Synthesis Performance

The figure shows the Divide block synthesis performance on the Xilinx Virtex 7 and Intel Stratix V devices.