Beruflich Dokumente
Kultur Dokumente
Background
Clock domain
A clock domain is a part of a design that has a clock that operates asynchronous to, or
has a variable phase relationship with, another clock in the design. For example, a
clock and its derived clock (via a clock divider) are in the same clock domain because
they have a constant phase relationship. But, 50MHz and 37MHz clocks (whose
phase relationship changes over time) define two separate clock domains. Figure 1
illustrates three different clocks in a design, but synchronous to each other. CLK, its
inversion and D1 (derived from CLK) are synchronous to each other.
Figure 1: Synchronous Clock
A clock domain crossing signal is a signal from one clock domain that is sampled by
a register in another clock domain. More details of the clock origin/domain inference
engine are given in [1].
Meta-stability
Every flip-flop (FF) that is used in any design has a specified setup and hold time, or
the time in which the data input is not legally permitted to change before and after a
sampling clock edge. This time window is specified as a design parameter precisely
to keep a data signal from changing too close to another synchronizing signal that
could cause the output to go meta-stable.
Figure 2: Setup and hold time of a Flip-flop
However, if some input
(say d in Figure 2)
violates the setup and
hold time of a FF, the
output of the FF (q in
Figure 2) keeps
oscillating for an
indefinite amount of
time. This unstable
value may or may not
non-deterministically
converge to a stable value (either 0 or 1) before the next sampling clock edge arrives.
Example - Consider the 1-bit CDC signal adat, which is sampled by register bdat1 in
Figure 3. Since adat comes from a different clock domain (aclk), its value can change
at any time with respect to bdat1's clock (bclk). If the value of adat changes during
bdat1's setup and hold time, the register bdat1 might/might not assume a state
between 0 and 1. In this state, the register is said to be meta-stable. A meta-stable
register may/may not (unpredictably) settle to either 0 or 1, causing illegal signal
values to be propagated throughout the rest of the design.
Figure 3: Meta-stability scenario
Synchronization Techniques
The main responsibility of a synchronizer is to allow sufficient time such that any
meta-sable output can settle down to a stable value in the destination clock domain.
The most common synchronizer used by designers is two-flip-flop (2-FF)
synchronizers as shown in Figure 4. Usually the control signals in a design are
synchronized by 2-FF synchronizers.
Figure 4: A 2-FF synchronizer
time such that there is at least a single destination sampling clock edge, which
samples the input value correctly (No setup/hold violation; Figure 5 gives such an
example). This stability condition on the input signal is usually checked by putting
assertions. For more information, see the section "Flip-flop Synchronizers".
Figure 5: Stability of input signal value
Example - Suppose a vector control signal Sig [2:0] crosses from Domain 1 to
Domain 2. Signal Sig also decides the state of Domain 2 and you assume that the
value "100" of Sig [2:0] indicates an invalid state for Domain 2. Now, think of a
situation, where the signal Sig wants to change its value from "000" to "101" (both
indicate valid states). This requires the two bits Sig [0] and Sig [2] to transit
simultaneously. Both these transition occurs very close to the destination sampling
clock edge (see Fig 6). By virtue of meta-stability, transition on Sig [2] gets captured
correctly and the transition on Sig [0] is missed. In this way, in the first cycle of the
destination clock, the system moves to state "100" which is invalid.
This case would not have happened, if changing the states of the design requires
changing only a single bit of the vector (Sig in this case). In case of a single bit
transition, either that transition would be captured in the destination domain or not.
This way the design either stays in the previous state or move to a valid state.
Therefore, for vector control signals (multi-bit signals, such as address buses), the
usual solution is to use a Gray code when crossing a clock domain boundary. A Gray
code ensures that only a single bit changes as the bus counts up or down. The
presence of gray coding on vector control signal can be checked by using assertions.
For more information, see the section "Gray Code Encoding for Vector Control
Signals".
synchronizes a "req" signal (request) to the receiving clock domain. When the "req"
signal is recognized in the destination clock domain, the receiver clocks the data into
a register (the data should have been stable for at least two/three sampling clock
edges in the destination clock domain) and then passes an "ack" signal
(acknowledgement) through a synchronizer to the sender. When the sender
recognizes the synchronized "ack" signal, the sender can change the value being
driven onto the data bus.
User-defined
Synchronizers
Sometimes, you may
specify some cells to
be synchronizers. If
this cell is found on
the path between the
FF, the path has to
be considered as
synchronized. Note
that the cell itself may have other inputs than the source flip-flop as shown in the
following illustration. The way of specifying a synchronizer is explained in chapter 2,
section "Using Tcl Command 'set_cdc_synchronizer'".
Figure 10: User-defined Synchronizer
CDC Analysis
Following are the
basic steps for CDC
analysis and checking
(irrespective of toolset
implementation):
Structural
Analysis to
Identify CDC Signals and Appropriate Synchronizers
The most important task of any CDC structural analyzer is to find out all the signals
(CDC) that cross clock boundaries. In Leda, rule NTL_CDC01 (For more information,
see the section "CDC Ruleset" in chapter 2.) reports all the un-synchronized CDC
paths. However a CDC path may be synchronized in the destination clock domain.
Thus, identification of synchronization schemes is very important to avoid reporting
false CDC reports. Automatic detection of synchronizers is very tough and may
depend on the underlying design principle. Therefore, sometime, the designer needs
to provide additional information for the underlying synchronization schemes.
Once extraction of information for all the CDC paths (synchronized and unsynchronized) is over, you need to see whether there are structural defects before and
after the synchronizers.
Many design teams choose a few synchronizer styles, apply them to all signals
crossing clock domains and enforce their usage by design style rules and design
reviews. Although proper synchronizers are essential for multi-clock designs, they are
insufficient to avoid all possible problems regarding signals crossing clock domains.
Considerable extra care must be taken in the design process to avoid these
problems. Some of the structural problems that may cause functional errors in multiclock based systems are as follows.
synchronizer settles it down, but cannot guarantee the precise number of cycles
before the valid signal is available in the receiving clock domain. Therefore, if (1) two
independent signals or (2) bits of a multi-bit signal are independently synchronized
(using same type of synchronizers or different types of synchronizers), the bits may
arrive in the receiving clock domain skewed with respect to one another. A very
simple form of re-convergence is shown in Figure 14. Rule NTL_CDC05 and
Therefore, even when meta-stability does not occur, any pair of bits can get out of
synchronization if routing differences and electrical effects cause the two bits to have
different delays before reaching their respective synchronizers. It is possible for one
synchronizer to sample its input and capture a signal change before the other
synchronizer captures the change, at which point the two copies of the signal will be
skewed by a cycle and no longer correlated.
Leda has six rules that check all the above structural checks for CDC signals. The
purpose of these rules is to provide the following information. Detailed description of
all the Leda structural checks is provided in chapter 2.
a. NTL_CDC01 - Reports all the unsynchronized CDC paths in the design.
b. NTL_CDC02 - Reports all convergence in the crossover paths in the design.
c. NTL_CDC03 - Reports all divergence in the crossover paths in the design.
d. NTL_CDC04 - Reports divergence of any meta-stable signal in the design.
e. NTL_CDC05/07 - Reports all kinds of re-convergence of synchronized signals in
the design. There is a subtle difference between rule NTL_CDC05 and NTL_CDC07.
For more information about the difference, see the section "CDC Ruleset" in chapter
2.
Just having a synchronization circuit connected is only part of the solution; the
associated logic must interact correctly with the synchronization circuit to ensure valid
operation. To ensure this, assertions need to be specified that check correct
functionality of the synchronization circuits and validates correct use of the
synchronizers by the environment in which they are instantiated. You automatically
specify these properties once for every synchronizer and automatically attach them to
all instances of the corresponding synchronization building blocks. The supported
property checks for CDC synchronization circuit elements are given as follows. For
more information about these property specifications, see the section "Automatically
Generated CDC Assertions".
Flip-flop Synchronizer
Control signal stability assertions
MUX Synchronizer
Control signal stability assertions
Data signal stability assertions
Handshake Synchronizer
Control signal stability assertions
Data signal stability assertions
Handshake protocol check assertions
FIFO Synchronizer
Control signal stability assertions
Gray coded assertions for read and write pointers
FIFO protocol (full/empty check) assertions
Data integrity checks
A more complete description of the CDC AEP (automatically extracted properties)
usage is given in the section "CDC AEP Rule Usage".
1. The environment (associated logic) must interact properly with the synchronizer.
2. The
Flip-flop Synchronizers
Description
The FF synchronizers (shown in Fig 16) form the basic building block for most of the
existing synchronization circuits. A simple FF synchronizer consists of m (> 1) FF
modeled as a shift register running on the 'destination clock'. Once the presence of a
FF synchronizer having m stages is detected, the following property is generated to
ensure that the device functions correctly in presence of this synchronizer.
If no assumptions are made about the relationship between the 'source' and
'destination' clock domains, then the following property ensures that all input signal
values can be reliably transported to the synchronizer output.
Input data values must be stable for m+1 destination clock edges.
Figure 16: Flip-flop Synchronizers
Implementation
Example SVA codes for the above properties are given as follows. This assertion
verifies the stability of din as observed in the destination clock domain. Signal rst is
the reset signal (if any, with the appropriate polarity) extracted from the synchronizer
FF, din is the single bit input to the first FF of the synchronizer.
property p_stability;
disable iff (rst)
@(<appropriate_edge> dclk)
!$stable (din) |=> $stable
(din)[*m] );
endproperty
A_p_stability: assert property (p_stability);
MUX Synchronizers
Description
Designs typically have both control and data paths. As shown in the following figure
(Fig 17), the control paths are usually flop-synchronized while the synced-in control
signals are used to synchronize the data paths. Here, these data paths use a
controlled synchronizer MUX for crossing clock domains. These control MUXs are
sometimes called D-MUX, MUX synchronizer, or sync MUX.
Figure 17: MUX synchronizers
The MUX synchronizer has the following functional requirements to ensure correct
results.
sready must be stable for m+1 number of destination clock cycles
(modeled by property p_stability as explained in the section "Flip-flop
Synchronizers").
data should remain stable in the destination clock domain during the data
transfer phase (indicated by the time dready is asserted in dclk domain
and until dready deasserted in dclk domain).
Implementation
Stability of Data
property p_data_stable;
disable iff (drst)
@(<appropriate edge> dclk)
((dready) |=> ($stable (data) ||
(!dready));
endproperty
A_p_data_stable: assert property (p_data_stable);
Implementation
The following assertions cover the proper use of the m-flip-flop synchronizers, the
handshake protocol, and the corresponding data stability.
Request signal (sreq) of the sender and Acknowledgement signal (dack) must be
stable for m+1 'dclk' and 'sclk' cycles respectively as implemented in the section "Flipflop Synchronizers".
2. Protocol check
a. The sender should continue to assert the sreq signal until sack is asserted at the
source clock (sclk) domain.
b. The sender should not assert a new request (sreq) until the acknowledgement for
the previous transfer is de-asserted in the source clock (sclk) domain.
A SVA property that covers the above two checks is given as follows.
property src_conformance (clk, rst, ssig, dsig);
disable iff (rst)
@(<appropriate edge> clk)
ssig && !dsig |=>ssig;
endproperty
A_src_conformance_req: assert property (src_conformance (sclk, srst,
sreq, sack));
A_src_conformance_new_req:
assert property (src_conformance (sclk, srst, !sreq, !sack));
Similar properties for the destination clock domain (dclk) are given as follows.
- The receiver should continue to assert the dack signal till dreq is asserted at the
destination clock (dclk) domain.
- The receiver should not assert a new acknowledgement (dack), until a new request
is received in the destination clock (dclk) domain.
A SVA property that covers the above two checks is given as follows.
property dest_conformance (clk, rst, ssig, dsig);
disable iff (rst)
@(<appropriate edge> clk)
ssig |=>dsig;
endproperty
A_dest_conformance_req: assert property (dest_conformance (dclk, drst,
dreq, dack));
A_dest_conformance_new_req:
assert property (dest_conformance (dclk, drst, !dreq, !dack));
3. Data stability
- The receiver should continue to receive stable data till it asserts the
acknowledgment.
The following SVA property implements the above two scenarios.
property data_stability (clk, rst, dreq, dack, data);
disable iff (rst)
@(<appropriate edge> clk) (dreq && !dack) => $stable (data);
endproperty
A_data_stability_dest:
assert property (dest_stability (dclk, drst, dreq, dack, data));
The checks for Pull synchronizers are similar.
Implementation
The following SVA code provides a possible implementation of these checks. The
p_data_integrity assertion starts a new thread with a unique cnt value whenever
wdata is written to the FIFO and checks the rdata value against the local data variable
whenever the corresponding read occurs. The first_match is required in
p_data_integrity to ensure the property checks rdata on the first occurrence of a read
with the corresponding cnt, otherwise it waits for ever for a rdata match at the rcnt
value. You should create a module M, which contains the assertions. It is then bound
to the nearest top-level module instance containing the FIFO code.
No Load on Full & No Read on Empty
property p_bad_access(clk, inc, flag);
@(<appropriate_edge> clk) inc |-> !flag;
endproperty : p_bad_access
//-- Property for bad write access
A_p_bad_access_write: assert property (p_bad_access (wclk,winc,wfull));
//-- Property for bad read access
A_p_bad_access_read: assert property (p_bad_access (rclk,rinc,rempty));
Order and Data Preservation
//- The following code mimics the grey coded read and write pointers. If
you have
//- those pointers automatically identified from the design, this is not
required
bit [$bit (waddr)-1:0] rcnt=0, wcnt=0;
always @(posedge wclk or negedge wrst_n) begin
if (wrst_n) wcnt <= 0;
else if (winc) begin
wcnt = wcnt + 1;
end
end
always @(posedge rclk or negedge rrst_n) begin
if (rrst_n) rcnt <= 0;
else if (rinc) begin
rcnt = rcnt + 1;
end
end
property p_data_integrity
int cnt; logic [$bits (wdata)-1:0] data;
disable iff (!wrst_n || !rrst_n)
@(posedge wclk)
(winc, cnt = wcnt, data = wdata) |=>
@(posedge rclk)
(first_match (##[0:$] (rinc && (rcnt == cnt))) |->
(rdata == data));
endproperty : p_data_integrity
Once such multi-bit signals are identified, the purpose of the function checks is to
verify that state changes on the source side before entering the bit synchronizers
follow the Gray code.
Implementation
Each individual m-flip-flop synchronizer must satisfy the signal stability properties
indicated in 1.1.2. In addition, the Gray code assertion verifies that whenever there is
a change of value on data_in the next value differs from the preceding one only in one
bit. The vector data_in is formed by concatenating all the variables that are part of the
multi-bit signal.
property p_gray_coded (clk, rst,data);
disable iff (rst)
@(<appropriate_edge> clk) !$stable (data) |-> ($onehot
(data ^ $past (data));
endproperty
A_p_gray_coded: assert property (p_gray_coded (dclk, rst, din));
In the following section, you will read how Leda generates these assertions and how
to use these assertions for verification.
Failure Debugging
In case of any CDC assertion violations for a design, you need to use the debugging
aids of the associated checker (VCS/Magellan) for finding the root cause of the
failure.
generated by CDC
The general idea for generating properties is to use prepackage modules containing
assertions and bind them to the verified design. The bind tries to bind the lowest
possible module in the design hierarchy in order to allow reduction of the design size
for the formal tool. The bind command will have the general following syntax:
Syntax
bind <property_module_name> #(<parameter>) <bind_instance_name>
(<port_list>)
where, <bind_instance_name> is of the form
<RULE_LABEL>_<FILENAME>_<LINENUMBER>
Assertion Library
Instead of generating assertions or properties for each check, Leda uses an assertion
library packaged with the tool. Each check now binds to the module containing the
prepackaged property. This library is a set of modules containing the necessary
properties. These modules may also have parameters to set different options or bit
width.
Grey Coding
The following assertion is generated by the rule that checks if two or more signals
are gray coded (for example, multi-bit control signals).
bind top aep_assert_gray_coding #( BitWidth, "Error : multibit control
signals must be gray coded") CDC08_test_v_40 (ck1, rst, CtrlSig );
synchronizers. The two branches of the signal can have different delays; the electrical
and routing effects can also cause different delays in the clocks going to the two
synchronizers. Therefore, if the two synchronizers sample their inputs at different
times then the two copies of the signal can be skewed by a cycle and no longer
correlated.
To prevent these correlation loss scenarios, Leda has two CDC rules that confirm that
there is no "re-convergence of synchronized signals" in the design.
The first one "NTL_CDC05" confirms that two signals synchronized in two different
synchronizers (thus forming two different CDC elements) never converge.
On the other-hand "NTL_CDC07" confirms that CDC paths synchronized by the same
synchronizer (thus grouped in a single CDC element) never converges after being
synchronized in the target clock domain.
Examples:
For CDC05 rule, two one bit signals are synchronized by two 2-FF synchronizers in
two different target domains (CLK2 and CLK3), thus forms two different CDC
elements. After the synchronization is done, these two signals converge in an AND
gate.
For CDC07 rule, a single bit signal has fan-outs two 2-FF synchronizers. After the
synchronization is done (in the single target domain CLK2 thus forming a single CDC
element), these two signals converge in an AND gate. The HDL codes and related
CDC error messages are given as follows.
For more information about these rules, see the chapter "Clock Domain Crossing
Rules".
set_cdc_ignored_path
Use the set_cdc_ignored_path command to specify a path to be ignored by CDC
analysis.
Syntax
set_cdc_ignored_path [-from source_ff_name] \
[-to target_ff_name]
Arguments
-from Specify the source flip-flop name.
-to Specify the target flip-flop name.
Although -from and -to are optional, at least one of the options must be used. If you
don't specify any one of the options, then it's value is considered as 'any'. For
example:
set_cdc_ignored_path -from top.rst
For the above command, any CDC path from top.rst will be ignored.
set_cdc_synchronizer
Use the set_cdc_synchronizer command to specify a synchronizer cell.
Syntax
set_cdc_synchronizer -name name \
[-synchro_type type [-synchro_parameters {..} ] ]
Arguments
-name Specify the name of the synchronizer cell.
-synchro_type Specify the synchronizer type. It can take one of the
following values:
simple (for flip-flop synchronizers).
logic (for logic synchronizers).
complex (for complex synchronizers).
fifo (for fifo synchronizers).
handshake (for handshake synchronizers).
-synchro_parameters Specify the parameters corresponding to the synchronizer.
For all the specified synchronizers, the parameters are a list of strings that specify
some values. The following table lists the parameters that are applicable for various
synchronizers.
Table 2: Parameters of different synchronizers
Parameters applicable Parameters applicable
to all synchronizers
to FIFO synchronizer
Parameters applicable to
handshake synchronizer
-source_clock
-source_clock
-source_clock
-target_clock
-target_clock
-target_clock
-write_signal
-read_signal
-transmit_signal
-fifo_full
-receive_signal
-fifo_empty
-write_reset_signal
-write_read_signal
-data_signal
set_cdc_group
Use the set_cdc_group command to override the automatic CDC inference. This
command enables you to create a CDC element and specify additional information
like synchronization type. In other words, it allows a complete specification of the
CDC information from you. This command is generated by the dump mode of the
CDC. After CDC inference in dump mode, all the inferred information is dumped
using the set_cdc_group command. If you want to modify the inferred information or
grouping of the different paths, you need to edit the dumped file and adapt the
information.
The rules concerning reconvergent paths and gray coding of control paths are highly
dependent on the grouping. So, make sure that the groups are formed correctly. In
addition to the automatic inference algorithm and the possibility to define
synchronizer, Leda also offers the flexibility to fully customize the CDC information.
The CDC inference engine first uses the information from the set_cdc_group
command. If this information is incomplete, then it tries to automatically complete it.
When the command set_cdc_group contains only the -paths directive and no synchronizer information, then the synchronizer is recognized automatically.
Similarly, if you provide only the synchronizer type information, then the parameters
(specially for fifo and handshake) is computed automatically.
Syntax
set_cdc_group -name group_name \
[-synchro_type type [-synchro_parameters {...} ] ] \
-paths { {s1 t1} {s2 t2}...{sn tn} }
Arguments
-name Specify the name of the synchronizer cell.
-synchro_type Specify the type of synchronizer. It can take the
following values:
simple (for flip-flop synchronizers).
logic (for logic synchronizers).
complex (for complex synchronizers).
fifo (for fifo synchronizers).
handshake (for handshake synchronizers).
-synchro_parameters Specify the parameters corresponding to the synchronizer.
-paths Specify the set of paths, which is just a collection of tuples
representing
different paths.
set_cdc_input_delay
Use the set_cdc_input_delay command to specify a clock that controls the module
pins or ports specified with the option -pin_port_list. This helps you to analyze the
CDC issue in a given module and focus on debugging in that module.
Syntax
set_cdc_input_delay -clock user_clock_name -delay_value delay_value \
-pin_port_list {PIN_PORT_LIST}
Arguments
-clock Specify the clock name.
-delay_value Specify the delay value. Leda actually discards this value
and so you can specify any value.
-pin_port_list Specify the list of pins or ports that the clock controls
For example, if you have a module SYNCHHRONIZER_MODULE that contains the
synchronizer as follows:
module SYNCHRONIZER_MODULE (out_data, in_data, clk);
You can instantiate this module in a design and specify a new clock, say "clk1" that
controls the pin in_data. To avoid debugging the whole design and to just focus on
this synchronizer module, you need to specify the set_cdc_input_delay command in
the leda_clock_file.tcl as follows:
set_cdc_input_delay -clock clk1 -delay_value 1 -pin_port_list
{SYNCHRONIZED_MODULE.in_data}
set_cdc_output_delay
Use the set_cdc_output_delay command to specify the relationship between an
output pin and a clock pin of a hard IP cell.
create_cdc_clock
Use the command to specify a given pin of the cell as a clock pin of a hard IP cell.
Example
The usage of the commands is as follows:
You can specify hard IP blocks and provide information about the relation between
clocks and data ports of the block. A cell which is instantiated from a library and does
not contain any statement (only port definition) is considered a hard IP cell. In such
case, for efficient CDC checking, you can specify the relationship between data pins
and clock pins.
The command to specify a given pin of the cell as a clock pin of a hard IP cell is as
follows:
create_cdc_clock -name clock_name source_objects
The following commands allow creating a relationship between a clock pin and a
data pin.
set_cdc_input_delay -clock clock_name delay_value port_pin_list
set_cdc_output_delay -clock clock_name delay_value port_pin_list
If such information is provided to the checker then efficient CDC checking can be
performed even on designs using hard IP. Else, no checking will be possible since no
connectivity information is available.
For example, the previous illustration shows a hard IP block with two clocks, two input
extract_cdc_info
Use the extract_cdc_info command to run the CDC inference within the Tcl shell
mode in order to refine the different parameters for this inference.
Syntax
extract_cdc_info
You need to execute this command only after elaboration. You can then use the
report_cdc_info command to visualize the inferred CDC elements. You may execute
this command many times, but it is important to run the clear_cdc_info command
before any call.
report_cdc_info
Use the report_cdc_info command to print the inferred CDC elements on the console
or to a file.
Syntax
report_cdc_info [-file filename]
Arguments
-file Specify the file name.
This command reports all the CDC elements set using the command set_cdc_group
syntax. This allows you to visualize the inferred information.
When you redirect the output of this command to a file, the console does not display
any information.
You can customize and source this file from the tcl_shell or the design_config file to
have a clean CDC inference.
clear_cdc_info
Use the clear_cdc_info command to clear all the inferred CDC informations.
Syntax
clear_cdc_info
In the Tcl shell mode, you may be interested to try several parameters until you get
the correct CDC inference. In order to do this incrementally, you can call the
clear_cdc_info command to reset everything and start the inference with new
parameters.
set_cdc_parameter
Use the set_cdc_parameter command to specify a value for the parameters for CDC
inference.
Syntax
set_cdc_parameter [-parameter parameter_name] [-value value]
Arguments
-parameter Specify the parameter.
-value Specify the value for the parameter.
The following parameters shall be used with this command:
NB_FFS_FOR_SYNCHRONIZER - Use this parameter to specify the
number of flip-flops to be used for synchronization. The minimum value of
this parameter is 2. The default value is 2.
ALLOW_BUF_INV_IN_SYNC_FFS - This parameter is used to specify if
the path between the synchronizing flip-flops contain buffers or inverters. If
set to 1, the path between the synchronizing flip-flops may contain buffers
or inverters. The default value is 1.
MAX_NB_PATHS - This parameter is used to specify the maximum
number of path allowed in a valid CDC Element. Above this number, the
CDC element is marked invalid and not taken into account by any CDC
checks.
MAX_NB_DISPLAYED_PATHS - This parameter is used to specify the
maximum paths to be displayed in a single CDC violation. The default
value is 10.
MAX_SYNCHRONIZATION_DEPTH - The CDC Inference algorithm
explores the influence of control signals to find the controlled paths. This
parameter is used to controls the maximum sequential depth to be
explored by Leda. The default value of this parameter is set to 4, to allow
Leda to detect all kinds of synchronizers. In a design using logic
synchronizers, it is recommended to limit this number to 2 or 1.