Use Delay Absorption While Modeling with Latency
Learn how to model your design with latency to apply the delay absorption optimization that runs when you generate HDL code with delay balancing.
Delay absorption is part of the delay balancing optimization. Delay absorption uses design delays in place of pipeline delays introduced from optimizations to prevent unused latency from being added to your design. You can use delay absorption by modeling with latency, which means that you add design delays to your model to take the place of introduced latency from optimizations. By modeling your design with latency, HDL Coder™ can use delay absorption to absorb the design delays and not introduce extra pipeline delays that add latency to your model, which prevents timing differences between the original model and generated model and allows HDL Coder to generate a functionally equivalent model to the generated HDL code.
Delays in your design can either be design delays or pipeline delays. Design delays are delays that you manually insert in your design by using Delay blocks, or other blocks that have state, including Queue, HDL FIFO, or Buffer blocks. Pipeline delays are delays that are generated by optimization settings, such as input or output pipelining options or block implementation settings, such as the ShiftAdd
implementation for a Divide block and the CORDIC
approximation for a Trigonometric Function block.
Certain block implementations, floating-point operations, and optimization settings, such as input pipelining or resource sharing, introduce latency to the generated HDL code and generated model. The additional latency results in a timing difference between the original model and the generated model. To avoid this timing difference, such as when you are using a control system with a feedback loop, you can add design delays to your model. For delay absorption to absorb the design delays:
Place a Delay block after the block that is introducing latency. You can place the Delay block anywhere downstream on the data path from the block that introduces latency.
Set the Delay block Delay length parameter to a value equal to the block latency.
By adding Delay blocks to your original model, you can simulate your original model with latency.
These blocks can introduce latency:
Divide, Sqrt, and Reciprocal blocks that have custom latency value greater than zero
Trigonometric Function blocks that have Function set to
sin
,cos
,sincos
,cos+jsin
, oratan2
and Approximation method set toCORDIC
Native floating-point operators that have the HDL block property LatencyStrategy set to
Max
,Min
, or a custom value greater than zero
To learn about blocks that have custom latency with fixed-point types, open the HDLMathLib
library. The library contains fixed-point blocks that have control signals.
open_system('HDLMathLib')
Model with Latency When Blocks Introduce Latency
To learn how HDL Coder absorbs delays, open the model hdlcoder_absorb_delay_timing
.
open_system('hdlcoder_absorb_delays') set_param('hdlcoder_absorb_delays', 'SimulationCommand', 'Update')
Inside the HDL_DUT
subsystem, you see a Delay block that has Delay length equal to 12
beside the Divide block. This Delay length corresponds to the latency of the division operation for fixed-point data types. In this case, the required Delay length is the sum of the bitwidth, 8
, and 4
, which is equal to 12
.
load_system('hdlcoder_absorb_delays') open_system('hdlcoder_absorb_delays/HDL_DUT')
To generate HDL code for the DUT subsystem, use the makehdl
function.
makehdl('hdlcoder_absorb_delays/HDL_DUT')
### Generating HDL for 'hdlcoder_absorb_delays/HDL_DUT'. ### Using the config set for model <a href="matlab:configset.showParameterGroup('hdlcoder_absorb_delays', { 'HDL Code Generation' } )">hdlcoder_absorb_delays</a> for HDL code generation parameters. ### Running HDL checks on the model 'hdlcoder_absorb_delays'. ### Begin compilation of the model 'hdlcoder_absorb_delays'... ### Begin compilation of the model 'hdlcoder_absorb_delays'... ### Working on the model 'hdlcoder_absorb_delays'... ### Working on... <a href="matlab:configset.internal.open('hdlcoder_absorb_delays', 'GenerateModel')">GenerateModel</a> ### Begin model generation 'gm_hdlcoder_absorb_delays' .... ### Rendering DUT with optimization related changes (IO, Area, Pipelining)... ### Model generation complete. ### Begin VHDL Code Generation for 'hdlcoder_absorb_delays'. ### Working on hdlcoder_absorb_delays/HDL_DUT/Divide as hdlsrc/hdlcoder_absorb_delays/Divide.vhd. ### Working on hdlcoder_absorb_delays/HDL_DUT as hdlsrc/hdlcoder_absorb_delays/HDL_DUT.vhd. ### Code Generation for 'hdlcoder_absorb_delays' completed. ### Creating HDL Code Generation Check Report file:///tmp/Bdoc23a_2213998_3297964/tp044801a7/hdlcoder-ex00529152/hdlsrc/hdlcoder_absorb_delays/HDL_DUT_report.html ### HDL check for 'hdlcoder_absorb_delays' complete with 0 errors, 0 warnings, and 0 messages. ### HDL code generation complete.
In the generated model, the delays beside the Divide block are absorbed into the block latency. When you double-click this Divide
block, you see the original Divide block and the Delay block with Delay length of 12
.
For an example that shows delay absorption for floating-point operations, see Latency Considerations with Native Floating Point.
Model with Latency When Optimizations Introduce Latency
Optimizations such as distributed pipelining can introduce latency. For example, open this model hdlcoder_absorb_delay_sharing
. The DUT
subsystem contains two subsystems sub_scalar
and sub_add
.
load_system('hdlcoder_absorb_delay_sharing') open_system('hdlcoder_absorb_delay_sharing') set_param('hdlcoder_absorb_delay_sharing', 'SimulationCommand', 'Update')
The sub_scalar
subsystem consists of 12
Product blocks that have a unit delay beside them. To share these Product blocks, a SharingFactor of 12
is specified on the sub_scalar
subsystem.
open_system('hdlcoder_absorb_delay_sharing/DUT/sub_scalar')
To generate HDL code for the DUT
subsystem, use the makehdl
function.
makehdl('hdlcoder_absorb_delay_sharing/DUT')
### Generating HDL for 'hdlcoder_absorb_delay_sharing/DUT'. ### Using the config set for model <a href="matlab:configset.showParameterGroup('hdlcoder_absorb_delay_sharing', { 'HDL Code Generation' } )">hdlcoder_absorb_delay_sharing</a> for HDL code generation parameters. ### Running HDL checks on the model 'hdlcoder_absorb_delay_sharing'. ### Begin compilation of the model 'hdlcoder_absorb_delay_sharing'... ### Working on the model 'hdlcoder_absorb_delay_sharing'... ### Working on... <a href="matlab:configset.internal.open('hdlcoder_absorb_delay_sharing', 'GenerateModel')">GenerateModel</a> ### Begin model generation 'gm_hdlcoder_absorb_delay_sharing' .... ### Rendering DUT with optimization related changes (IO, Area, Pipelining)... ### Model generation complete. ### Estimated critical path for design: <a href="matlab:run('hdlsrc/hdlcoder_absorb_delay_sharing/criticalPathEstimated')">hdlsrc/hdlcoder_absorb_delay_sharing/criticalPathEstimated.m</a> ### To clear highlighting, click the following MATLAB script: <a href="matlab:run('hdlsrc/hdlcoder_absorb_delay_sharing/clearhighlighting.m')">hdlsrc/hdlcoder_absorb_delay_sharing/clearhighlighting.m</a> ### Generating new validation model: <a href="matlab:open_system('hdlsrc/hdlcoder_absorb_delay_sharing/gm_hdlcoder_absorb_delay_sharing_vnl')">gm_hdlcoder_absorb_delay_sharing_vnl</a>. ### Validation model generation complete. ### Begin Verilog Code Generation for 'hdlcoder_absorb_delay_sharing'. ### MESSAGE: The design requires 12 times faster clock with respect to the base rate = 0.001. ### Begin Verilog Code Generation for 'DUT_tc'. ### Working on DUT_tc as hdlsrc/hdlcoder_absorb_delay_sharing/DUT_tc.v. ### Code Generation for 'DUT_tc' completed. ### Working on... <a href="matlab:configset.internal.open('hdlcoder_absorb_delay_sharing', 'Traceability')">Traceability</a> ### Working on... <a href="matlab:configset.internal.open('hdlcoder_absorb_delay_sharing', 'HDLGenerateWebview')">HDLGenerateWebview</a> ### Working on hdlcoder_absorb_delay_sharing/DUT/sub_add as hdlsrc/hdlcoder_absorb_delay_sharing/sub_add.v. ### Working on hdlcoder_absorb_delay_sharing/DUT/sub_scalar as hdlsrc/hdlcoder_absorb_delay_sharing/sub_scalar.v. ### Working on hdlcoder_absorb_delay_sharing/DUT as hdlsrc/hdlcoder_absorb_delay_sharing/DUT.v. ### Code Generation for 'hdlcoder_absorb_delay_sharing' completed. ### Generating HTML files for code generation report at <a href="matlab:web('/tmp/Bdoc23a_2213998_3297964/tp044801a7/hdlcoder-ex00529152/hdlsrc/hdlcoder_absorb_delay_sharing/html/hdlcoder_absorb_delay_sharing_codegen_rpt.html')">hdlcoder_absorb_delay_sharing_codegen_rpt.html</a> Warning: Model Web view in code generation report requires Simulink Report Generator, which is not installed. ### Creating HDL Code Generation Check Report file:///tmp/Bdoc23a_2213998_3297964/tp044801a7/hdlcoder-ex00529152/hdlsrc/hdlcoder_absorb_delay_sharing/DUT_report.html ### HDL check for 'hdlcoder_absorb_delay_sharing' complete with 0 errors, 3 warnings, and 4 messages. ### HDL code generation complete.
When you specify a value greater than 1
for the SharingFactor, Deserializer blocks that have 1
sample delay are inserted after HDL code generation. By adding the unit Delay blocks beside the Product blocks in the original model, these delays are absorbed into the Product block after you perform the sharing optimization.
In the generated model, the delays are absorbed in the Deserializer block.
Model with Latency in a Feedback Loop
When you model with latency in a feedback loop, you can either:
Use clock-rate pipelining. For more information see Clock-Rate Pipelining.
Use delay absorption. For example, you can model a feedback loop at the clock rate with some of amount of latency expressed as design delays to absorb the latency introduced from native floating-point operators or pipeline optimizations.
In this example, use delay absorption to model with latency in a feedback loop.
This example contains output pipelines to help optimize the speed of the design, but at the cost of introducing an extra cycle of latency for each pipeline. This additional latency is balanced during delay balancing so that the numerics and functionality of the algorithm are preserved. However, in a feedback loop, delay balancing requires you to model with latency in order to absorb the design delays to prevent a timing mismatch as a result of the pipeline optimizations.
For example, if you generate code with output pipelines added in a feedback loop without modeling with latency, HDL Coder generates a delay balancing error. You can observe this in the delay_absorption_feedback_loop
model, where the subsystem delay_absorption_feedback_loop/DUT/Subsystem
is in a feedback loop and the delay_absorption_feedback_loop/DUT/Feed_Forward/Sum
block has the HDL block property OutputPipeline
set to 2.
Load and open the model to its DUT subsystem.
load_system('delay_absorption_feedback_loop'); open_system('delay_absorption_feedback_loop/DUT');
View the non-default parameters by using hdlsaveparams
to see the OutputPipeline
setting for the Sum block.
hdlsaveparams('delay_absorption_feedback_loop');
%% Set Model 'delay_absorption_feedback_loop' HDL parameters hdlset_param('delay_absorption_feedback_loop', 'GenerateValidationModel', 'on'); hdlset_param('delay_absorption_feedback_loop', 'HDLSubsystem', 'delay_absorption_feedback_loop/DUT'); hdlset_param('delay_absorption_feedback_loop', 'OptimizationReport', 'on'); % Set Sum HDL parameters hdlset_param('delay_absorption_feedback_loop/DUT/Feed_Forward/Sum', 'OutputPipeline', 2);
If you generate code by using the makehdl
function, there is a delay balancing error in the HDL Code Generation Report. To fix this error, you need to add enough latency in your design to match the amount of latency added from the output pipelining optimization.
In this example, you need two unit delays total, or a single design delay with a Delay Length of two. The error mentions only one extra cycle of latency because the current Delay block in the feedback path is absorbed to handle one of the two extra cycles of latency. Increase the feedback delay block from a Delay Length of one to a Delay Length of two. You can do this by setting the parameter in the Delay block or by using this command:
set_param('delay_absorption_feedback_loop/DUT/Delay', 'DelayLength', '2');
Generate HDL code by using the makehdl
function.
makehdl('delay_absorption_feedback_loop/DUT');
### Generating HDL for 'delay_absorption_feedback_loop/DUT'. ### Using the config set for model <a href="matlab:configset.showParameterGroup('delay_absorption_feedback_loop', { 'HDL Code Generation' } )">delay_absorption_feedback_loop</a> for HDL code generation parameters. ### Running HDL checks on the model 'delay_absorption_feedback_loop'. ### Begin compilation of the model 'delay_absorption_feedback_loop'... ### Working on the model 'delay_absorption_feedback_loop'... ### The code generation and optimization options you have chosen have introduced additional pipeline delays. ### The delay balancing feature has automatically inserted matching delays for compensation. ### The DUT requires an initial pipeline setup latency. Each output port experiences these additional delays. ### Output port 1: 2 cycles. ### Working on... <a href="matlab:configset.internal.open('delay_absorption_feedback_loop', 'GenerateModel')">GenerateModel</a> ### Begin model generation 'gm_delay_absorption_feedback_loop' .... ### Rendering DUT with optimization related changes (IO, Area, Pipelining)... ### Model generation complete. ### Generating new validation model: <a href="matlab:open_system('hdlsrc/delay_absorption_feedback_loop/gm_delay_absorption_feedback_loop_vnl')">gm_delay_absorption_feedback_loop_vnl</a>. ### Validation model generation complete. ### Begin VHDL Code Generation for 'delay_absorption_feedback_loop'. ### Working on delay_absorption_feedback_loop/DUT/Feed_Forward as hdlsrc/delay_absorption_feedback_loop/Feed_Forward.vhd. ### Working on delay_absorption_feedback_loop/DUT as hdlsrc/delay_absorption_feedback_loop/DUT.vhd. ### Generating package file hdlsrc/delay_absorption_feedback_loop/DUT_pkg.vhd. ### Code Generation for 'delay_absorption_feedback_loop' completed. ### Generating HTML files for code generation report at <a href="matlab:web('/tmp/Bdoc23a_2213998_3297964/tp044801a7/hdlcoder-ex00529152/hdlsrc/delay_absorption_feedback_loop/html/delay_absorption_feedback_loop_codegen_rpt.html')">delay_absorption_feedback_loop_codegen_rpt.html</a> ### Creating HDL Code Generation Check Report file:///tmp/Bdoc23a_2213998_3297964/tp044801a7/hdlcoder-ex00529152/hdlsrc/delay_absorption_feedback_loop/DUT_report.html ### HDL check for 'delay_absorption_feedback_loop' complete with 0 errors, 0 warnings, and 0 messages. ### HDL code generation complete.
Open the generated model to view the absorbed design delays. The feedback delays were absorbed and moved into the Feed_Forward
subsystem to handle the latency added from output pipelining. No extra latency is introduced as a result of delay absorption.
open_system('gm_delay_absorption_feedback_loop/DUT'); set_param('gm_delay_absorption_feedback_loop', 'SimulationCommand', 'update');
When applying delay absorption in a feedback loop, follow these guidelines:
Add the design delays to be absorbed at the same subsystem level as the feedback loop.
Delay absorption cannot absorb upstream latency from a feedback loop, which means that if there are design delays placed before a feedback loop in your model, delay absorption does not absorb those upstream design delays. If you do have upstream latency that is not absorbed, HDL code generation produces a delay balancing error message in the HDL code generation report. Use clock-rate pipelining to model with latency when there is upstream latency in your design.
Delay absorption cannot absorb design delays separated from the block that introduces latency by a component that takes in a zero-input value and outputs a non-zero value, such as a NOT Logical Operator block.