Guidelines for Using Delays and Goto and From Blocks for HDL Code Generation
These guidelines illustrate the recommended settings for modeling delays in your model. You model delays by using blocks available in the Discrete Library. Each guideline has a severity level that indicates the level of compliance requirements. To learn more, see HDL Modeling Guidelines Severity Levels.
Appropriate Usage of Delay Blocks as Registers
For blocks in your model to be inferred as a flipflop on the target FPGA, use Delay blocks. You can specify a local reset and enable signal for each Delay block.
By default, the Delay length of the block is set to
2. In this case, the input to the block passes to the
output after two time steps. If the Delay length is set to
0, the input passes to the output without
any delay. The generated HDL code treats the
block as a wire. To infer a flipflop or register on the target device, set the
dialog and specify
a Delay length greater than zero.
When using a Delay block that has an external enable port or that is inside the Enabled Subsystem block, it is recommended to use the State Control block in synchronous mode. Similarly, when you use a Delay block that has an external reset port or that is inside the Resettable Subsystem block, it is recommended to use the State Control block in Synchronous mode. To learn more, see HDL Code Generation in Delay.
Do not use the Unit Delay Enabled, Unit Delay Resettable, and Unit Delay Enabled Resettable blocks for HDL code generation. These blocks have been removed. Instead, replace these blocks with the Unit Delay Enabled Synchronous, Unit Delay Resettable Synchronous, and Unit Delay Enabled Resettable Synchronous blocks. These blocks use the State Control block in synchronous hardware mode. To perform this block replacement in your model, run the model check Check for obsolete Unit Delay Enabled/Resettable Blocks.
Absorb Delays to Avoid Timing Difference
Certain block implementations, floating-point operations, and optimization settings such as distributed pipelining introduce latency in the generated HDL code and the 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 feedback loop, use a modeling pattern that can absorb delays. To absorb the delays:
Place a Delay block after the block that is introducing latency.
Set the Delay block Delay length value equal to the block latency.
By adding the Delay block 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
atan2and HDL architecture set to
Native floating-point operators that have LatencyStrategy set to
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.
To learn how HDL Coder™ absorbs delays, open the model
open_system('hdlcoder_absorb_delays') set_param('hdlcoder_absorb_delays', 'SimulationCommand', 'Update')
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,
4, which is equal to
To generate HDL code for the DUT subsystem, use the
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
For an example that shows delay absorption for floating-point operations, see Latency Considerations with Native Floating Point.
Optimizations such as distributed pipelining can introduce latency. For example, open this model
DUT subsystem contains two subsystems
open_system('hdlcoder_absorb_delay_sharing') set_param('hdlcoder_absorb_delay_sharing', 'SimulationCommand', 'Update')
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
To generate HDL code for the
DUT subsystem, use the
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.
Map Large Delays to Block RAM
To save area, when your design contains large design delays and pipeline delays, you can map the delays to block RAM and UltraRAM resources on the FPGA. 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 or block implementation settings such as Newton-Raphson implementation.
To map design delays to RAM:
In the HDL Block Properties dialog box of Delay blocks, set UseRAM to
on. To learn how you can set this option on all Delay blocks in your design programmatically, see Set HDL Block Parameters for Multiple Blocks Programmatically.
To map significantly large delays to UltraRAM resources, you can specify the
ram_styleattribute in the generated HDL code.
-- This VHDL code shows the ramstyle attribute set to ultra: attribute ram_style: string; attribute ram_style of ram : signal is "ultra"; // This Verilog code shows the ramstyle attribute set to ultra: (* ram_style = "ultra" *)
As described in Effects of Streaming and Distributed Pipelining, even if UseRAM is
off, you can map large delays that exceed a threshold value by using the RAM mapping threshold (bits) parameter. You can change this threshold value depending on how large a delay you want to map to RAM.
When you use MATLAB Function blocks, you can map persistent variables in your MATLAB® code to RAM by setting HDL architecture to
MapPersistentVarsToRAMHDL block property to
For pipeline delays that are inserted by optimizations, delay balancing automatically inserts matching delays in parallel paths. If the delay length at the critical path and the number of vector elements in the parallel path take large values, the pipeline delays can also become significantly large.
To map these large delays to Block RAM:
Enable the Map pipeline delays to RAM parameter.
Adjust the RAM mapping threshold (bits) parameter to a value that is smaller than the required RAM size.
RAM size = DelayLength * WordLength * VectorLength * ComplexLength
Required HDL Settings for Goto and From Blocks
Do not use From and Goto blocks across the boundary of the DUT subsystem. To connect the input and output ports of the DUT, use Inport and Outport blocks instead.
Do not use From and Goto blocks across the boundary of an Atomic Subsystem. To connect the input and output ports of the DUT, use Inport and Outport blocks instead.
Using From and Goto blocks across a subsystem
hierarchy can impact the readability of the model. Before generating HDL code,
it is recommended that you use From and Goto
blocks in the same subsystem and use
Scoped visibility. When you generate HDL code, in
the generated model, each Goto and From block
becomes a pair of From and Goto subsystems
connected back to back.