Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Clock Domain Crossing Rules Guide: Version J-2014.12 December 2014 Comments? E-Mail Your Comments About This Manual To

Download as pdf or txt
Download as pdf or txt
You are on page 1of 150
At a glance
Powered by AI
The document discusses rules for clock domain crossing and synchronizing data between different clock domains using FIFOs.

The document discusses rules and guidelines for synchronizing data between different clock domains in a design using FIFO buffers.

The document discusses rules that must be followed when implementing FIFO synchronizers between different clock domains to ensure data integrity and stability.

Leda

Clock Domain Crossing Rules


Guide
Version J-2014.12
December 2014
Comments?
E-mail your comments about this manual to
leda-support@synopsys.com.

Copyright Notice and Proprietary Information

Copyright 2014 Synopsys, Inc. All rights reserved. This software and documentation contain confidential and proprietary
information that is the property of Synopsys, Inc. The software and documentation are furnished under a license agreement and
may be used or copied only in accordance with the terms of the license agreement. No part of the software and documentation may
be reproduced, transmitted, or translated, in any form or by any means, electronic, mechanical, manual, optical, or otherwise,
without prior written permission of Synopsys, Inc., or as expressly provided by the license agreement.

Destination Control Statement


All technical data contained in this publication is subject to the export control laws of the United States of America.
Disclosure to nationals of other countries contrary to United States law is prohibited. It is the readers responsibility to
determine the applicable regulations and to comply with them.

Disclaimer
SYNOPSYS, INC., AND ITS LICENSORS MAKE NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH
REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

Registered Trademarks ()
Synopsys, AMPS, Arcadia, C Level Design, C2HDL, C2V, C2VHDL, Cadabra, Calaveras Algorithm, CATS, CSim,
Design Compiler, DesignPower, DesignWare, EPIC, Formality, HSPICE, Hypermodel, iN-Phase, in-Sync, Leda, MAST,
Meta, Meta-Software, ModelAccess, ModelTools, NanoSim, OpenVera, PathMill, Photolynx, Physical Compiler,
PowerMill, PrimeTime, RailMill, Raphael, RapidScript, Saber, SiVL, SNUG, SolvNet, Stream Driven Simulator,
Superlog, System Compiler, Testify, TetraMAX, TimeMill, TMA, VCS, Vera, and Virtual Stepper are registered
trademarks of Synopsys, Inc.

Trademarks ()
abraCAD, abraMAP, Active Parasitics, AFGen, Apollo, Apollo II, Apollo-DPII, Apollo-GA, ApolloGAII, Astro, Astro-Rail,
Astro-Xtalk, Aurora, AvanTestchip, AvanWaves, BCView, Behavioral Compiler, BOA, BRT, Cedar, ChipPlanner, Circuit
Analysis, Columbia, Columbia-CE, Comet 3D, Cosmos, CosmosEnterprise, CosmosLE, CosmosScope, CosmosSE,
Cyclelink, Davinci, DC Expert, DC Expert Plus, DC Professional, DC Ultra, DC Ultra Plus, Design Advisor, Design
Analyzer, Design Vision, DesignerHDL, DesignTime, DFM-Workbench, DFT Compiler, Direct RTL, Direct Silicon
Access, Discovery, DW8051, DWPCI, Dynamic-Macromodeling, Dynamic Model Switcher, ECL Compiler, ECO
Compiler, EDAnavigator, Encore, Encore PQ, Evaccess, ExpressModel, Floorplan Manager, Formal Model Checker,
FoundryModel, FPGA Compiler II, FPGA Express, Frame Compiler, Galaxy, Gatran, HDL Advisor, HDL Compiler,
Hercules, Hercules-Explorer, Hercules-II, Hierarchical Optimization Technology, High Performance Option, HotPlace,
HSPICE-Link, iN-Tandem, Integrator, Interactive Waveform Viewer, i-Virtual Stepper, Jupiter, Jupiter-DP, JupiterXT,
JupiterXT-ASIC, JVXtreme, Liberty, Libra-Passport, Library Compiler, Libra-Visa, Magellan, Mars, Mars-Rail, MarsXtalk, Medici, Metacapture, Metacircuit, Metamanager, Metamixsim, Milkyway, ModelSource, Module Compiler, MS3200, MS-3400, Nova Product Family, Nova-ExploreRTL, Nova-Trans, Nova-VeriLint, Nova-VHDLlint, Optimum
Silicon, Orion_ec, Parasitic View, Passport, Planet, Planet-PL, Planet-RTL, Polaris, Polaris-CBS, Polaris-MT, Power
Compiler, PowerCODE, PowerGate, ProFPGA, ProGen, Prospector, Protocol Compiler, PSMGen, Raphael-NES,
RoadRunner, RTL Analyzer, Saturn, ScanBand, Schematic Compiler, Scirocco, Scirocco-i, Shadow Debugger, Silicon
Blueprint, Silicon Early Access, SinglePass-SoC, Smart Extraction, SmartLicense, SmartModel Library, Softwire,
Source-Level Design, Star, Star-DC, Star-MS, Star-MTB, Star-Power, Star-Rail, Star-RC, Star-RCXT, Star-Sim, StarSimXT, Star-Time, Star-XP, SWIFT, Taurus, Taurus-Device, Taurus-Layout, Taurus-Lithography, Taurus-Process,
Taurus-Topography, Taurus-Visual, Taurus-Workbench, TimeSlice, TimeTracker, Timing Annotator, TopoPlace,
TopoRoute, Trace-On-Demand, True-Hspice, TSUPREM-4, TymeWare, VCS Express, VCSi, Venus, Verification
Portal, VFormal, VHDL Compiler, VHDL System Simulator, and VMC are trademarks of Synopsys, Inc.

Service Marks (SM)


MAP-in, SVP Caf, and TAP-in are service marks of Synopsys, Inc.
SystemC is a trademark of the Open SystemC Initiative and is used under license.
ARM and AMBA are registered trademarks of ARM Limited.
All other product or company names may be trademarks of their respective owners.

Contents

Contents
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
About this Manual . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
How Rules are Organized . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Related Documents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Manual Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Typographical and Symbol Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Getting Leda Help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
The Synopsys Web Site . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

7
7
7
8
8
8
9
9

Chapter 1
Clock Domain Crossing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Background . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Clock domain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Meta-stability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Guidelines for Effective CDC Verification . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Clock Inference with Clock Gating Cells . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Synchronization Techniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Synchronization of Control Signals with 2-FF Synchronizers . . . . . . . . . . . . .

11
11
13
13
14
15
17
18
18

Input Data Stability to Avoid Data Loss


Gray Encoding to Avoid Data Incoherence (For Vector CDC Control Signals)

Synchronization of CDC Data Signals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21


Passing Data through MUX Synchronizer . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Handshaking Data between Clock Domains . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Passing Data by FIFO between Clock Domains . . . . . . . . . . . . . . . . . . . . . . . . 22
User-defined Synchronizers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
CDC Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Structural Analysis to Identify CDC Signals and appropriate Synchronizers . . 24
Structural Analysis to Identify Structural Defects before and after Synchronization
24
Convergence in the Crossover Path
Divergence in the Crossover Path
Divergence of Meta-stable Signal
Re-convergence of Synchronized Signals
Determination and Validation of appropriate Properties for every Synchronizer

Leda - CDC Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30


Automatically Generated CDC Assertions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3

Contents

Synchronizers Identified by Leda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31


Flip-flop Synchronizers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Description
Implementation

MUX Synchronizers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Description
Implementation

Handshake Synchronizers (Push) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34


Description
Implementation

Dual Clock FIFO Synchronizers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37


Description
Implementation

Complex Synchronizers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Quasi Static Signal for Identifying Double FF Synchronizer . . . . . . . . . . . . . . . . . 42
Example

Gray Code Encoding for Vector Control Signals . . . . . . . . . . . . . . . . . . . . . . . . . . 43


Description
Implementation

CDC AEP Rule Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .


Naming Convention for Automatically Generated CDC AEP Files . . . . . . . . . . . .
Binding the Assertion Definitions to the Design . . . . . . . . . . . . . . . . . . . . . . . .
Using Generated Assertions in VCS and Magellan . . . . . . . . . . . . . . . . . . . . . .
Failure Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Configuring Latches in CDC Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
CDC Tcl Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
set_cdc_ignored_path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

45
47
47
48
48
49
49
49

Support of Wildcard in set_cdc_ignored_path Command

set_cdc_synchronizer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
set_cdc_input_delay . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
extract_cdc_info . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
report_cdc_info . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
clear_cdc_info . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
set_cdc_parameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

52
53
53
54
54
54

Chapter 2
Clock Domain Crossing Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
CDC Usage Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
..............................................................
CDC Ruleset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

57
57
58
58
59

Contents

NTL_CDC00 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
NTL_CDC01 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Message: No synchronization scheme found for signals
crossing clock domains

NTL_CDC01_0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Message: Flip-flop Synchronizer detected

NTL_CDC01_1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Message: Logic Synchronizer detected

NTL_CDC01_3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Message: Complex Synchronizer detected

NTL_CDC01_4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Message: User-Defined Synchronizer detected

NTL_CDC01_5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Message: Fifo Synchronizer detected

NTL_CDC01_6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Message: Handshake Synchronizer detected

NTL_CDC02 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Message: Convergence found in clock domain crossing path

NTL_CDC03 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
Message: Divergence found in clock domain crossing path

NTL_CDC04 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Message: Divergence of meta-stable signal detected

NTL_CDC05 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Message: Convergence between signals coming from different synchronizers

NTL_CDC06 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
Message: CDC control signal must be stable enough (property generated)

NTL_CDC07 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
Message: Reconverging control path detected
Detailed Explanations for Rules NTL_CDC05 and NTL_CDC07

NTL_CDC08 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
Message: Multiple CDC control signals must be gray coded, property generated
Difference between rules NTL_CDC07 and NTL_CDC08 :

NTL_CDC09 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
Message: CDC control signal must not be part of a BUS

NTL_CDC10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
Message: Different clock polarity FFs in the simple synchronizer

NTL_CDC11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
Message: One of the FFs in a 2-FF simple synchronizer has a gated clock (single-bit CDC
signal)

NTL_CDC12 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
Message: A vector is synchronized by a set of 2-FF simple synchronizers where one of the 2FF synchronizers has a gated clock FF

NTL_CDC13 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
Message: There exists an unscented control path driven by a CDC asynchronous reset signal

Contents

NTL_CDC14 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
Message: Control and Data Signals of a MUX (Logic) Synchronizer must be Stable Enough
(Property Generated)

NTL_CDC15 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
Message: A Handshake Synchronizer Must Implement The Handshake Protocol and Data
Stability Correctly (Property Generated)

NTL_CDC16 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
Message: A FIFO Synchronizer Must Implement the FIFO Protocol and Data Stability
Correctly (Property Generated)

Preface

Preface
About this Manual
This book contains reference information for prepackaged rules that come with the Leda
Checker tool. This information mirrors the information available in the HTML-based
help files that you access directly from the Leda Checker tools Error Report. The
purpose of this book is to provide a reference that you can view online or print out so
that you can review available prepackaged rules and decide which ones you want to use
before running the Checker tool on your HDL source files. On the other hand, the
HTML-based help system is designed to provide random access to this same
information from the Checker Error Report, so that you can quickly access more
information about a specific rule that was violated, including in some cases, circuit
diagrams and valid and invalid examples of Verilog or VHDL code.
This book is intended for use by hardware design and quality assurance engineers who
are already familiar with VHDL or Verilog.

How Rules are Organized


Rules are organized into major categories called policies, which have multiple rulesets.
Each ruleset can contain multiple rules. You use the prepackaged rules to check your
VHDL or Verilog source code for compliance with various standards and compatibility
with downstream tools in the design and verification flow. Some rules apply just to
Verilog or VHDL and some apply to both HDLs. The documentation for each rule, both
in the HTML-based help system and in this manual clearly labels which languages each
rule applies to.
Note

There is a separate book for each policy (set of prepackaged rules) that Leda
supports.

Preface

Related Documents
This manual is part of the Leda document set. To see a complete listing or to navigate to
another online document in the set, refer to the Leda Document Navigator.

Manual Overview
This manual contains the following chapters:
Preface

Describes the manual and lists the typographical


conventions and symbols used in it; explains how to get
technical assistance.

Chapter 1
Clock Domain Crossing

Detailed information of Clock Domain Crossing.

Chapter 2
Clock Domain Crossing Rules

Detailed information about CDC rules.

Typographical and Symbol Conventions


The following conventions are used throughout this document:
Table 1: Documentation Conventions
Convention

Description and Example

Represents the UNIX prompt.

Bold

User input (text entered by the user).


% cd $LMC_HOME/hdl

Monospace

System-generated text (prompts, messages, files, reports).


No Mismatches: 66 Vectors processed: 66 Possible"

Italic or Italic

Variables for which you supply a specific value. As a command


line example:
% setenv LMC_HOME prod_dir

In body text:
In the previous example, prod_dir is the directory where your
product must be installed.
| (Vertical rule)

Choice among alternatives, as in the following syntax example:


-effort_level low | medium | high

Preface

Table 1: Documentation Conventions (Continued)


Convention
[ ] (Square brackets)

Description and Example


Enclose optional parameters:
pin1 [pin2 ... pinN]

In this example, you must enter at least one pin name (pin1), but
others are optional ([pin2 pinN]).
TopMenu > SubMenu

Pulldown menu paths, such as:


File > Save As

Getting Leda Help


For help with Leda, send a detailed explanation of the problem, including contact
information, to leda-support@synopsys.com.

The Synopsys Web Site


General information about Synopsys and its products is available at this URL:
http://www.synopsys.com

Preface

10

Chapter 1: Clock Domain Crossing

1
Clock Domain Crossing
Overview
As modern System-on-Chip (SoC) designs continue to face increasing size and
complexity challenges, multiple asynchronous clock domains have been employed for
different I/O interfaces. A CDC-based (Clock Domain Crossing) design is a design that
has one clock asynchronous to, or has a variable phase relation with, another clock. A
CDC signal is a signal latched by a flip-flop (FF) in one clock domain and sampled in
another asynchronous clock domain. Transferring signals between asynchronous clock
domains may lead to setup or hold timing violations of flip-flops. These violations may
cause signals to be meta-stable. Even if synchronizers could eliminate the meta-stability,
incorrect use, such as convergence of synchronized signals or improper synchronization
protocols, may also result in functional CDC errors. Functional validation of such SoC
designs is one of the most complex and expensive tasks. Simulation on register transfer
level (RTL) is still the most widely used method. However, standard RTL simulation can
not model the effect of meta-stability.
Within one clock domain, proper static timing analysis (STA) can guarantee that data
does not change within clock setup and hold times. When signals pass from one clock
domain to another asynchronous domain, there is no way to avoid meta-stability since
data can change at any time.
As the CDC errors are not addressed and verified early in the design cycles, many
designs exhibit functional errors only late in their design cycles or during post-silicon
verification. Several coverage metrics are proposed to measure the validation's
adequacy and progress, such as code based coverage, finite state machine coverage, and
functional coverage. Nevertheless, these coverage metrics do not have direct relations
with CDC issues.
To address clock domain problems due to meta-stability and data sampling issues,
designers typically employ several types of synchronizers. The most commonly used
synchronizer is based on the well-known two-flip-flop circuit. Other types of

11

Chapter 1: Clock Domain Crossing

synchronizers are based on handshaking protocols or FIFOs. In a limited number of


cases it may be useful to employ dual-clock FIFO buffers or other mechanisms
optimized for domains with similar clock frequencies.
To accurately verify clock domain crossings, both structural and functional CDC
analysis should be carried out. Structural clock domain analysis looks for issues like
insufficient synchronization, or combinational logic driving flip-flop based
synchronizers. Functional clock domain analysis uses assertion-based verification to
check the correct usage of synchronizers. Assertions may be used to find problems such
as data stability violations when going from a fast clock domain to a slower one.
Assertions generated in PSL or other assertion languages such as OpenVera or
SystemVerilog, can then be used in formal model checking or simulation.
This chapter is organized in the following sections:
Background - Prepares the background required for further discussions.
Synchronization Techniques - Discusses the synchronization techniques.
CDC Analysis - Discusses the various steps of CDC analysis.
Leda-CDC Flow - Provides information on the basic Leda-CDC tool flow.
Automatically Generated CDC Assertions - Provides a detailed specification of the
Leda supported assertions.
Synchronizers Identified by Leda - Describes the types of synchronizers identified
by Leda.
CDC AEP Rule Usage & Naming Conventions for Automatically Generated CDC
AEP Files - Provides further detail of assertion related topics.
CDC Tcl Interface - Provides information about CDC Tcl Interface.

12

Chapter 1: Clock Domain Crossing

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].

13

Chapter 1: Clock Domain Crossing

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

setup hold

clk
d

metastable

q
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.

14

Chapter 1: Clock Domain Crossing

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

aclk
adat changing

adat
bclk
bdat1

Clocked signal is initially


Metastable and is still
metastable on the next
active clock edge

In a multi-clock design, meta-stability is inevitable, but there are certain design


techniques that help to avoid the chance of getting meta-stable.

Guidelines for Effective CDC Verification


Proper CDC (Clock Domain Crossing) verification needs careful building of
verification environment. One of the primary requirements of CDC verification is to
have proper clock domain extraction. If the clock domain extraction is wrong, CDC
verification would lead to false results. To ensure that clock domains have been
extracted correctly from a complex design, follow these steps:
Proper set_case_analysis values and clock gating cell settings - In general, most of
the logic in clock path includes MUXs and clock gating cells. By providing
appropriate information, you can reduce the number of clock origins that Leda
infers for a clock path having complex logic. The following paragraphs describes
how to handle these two combinational logics in Leda:
MUX
A MUX is used to select one of the multiple clocks in its fan-in cone. In a single
CDC checking, this selection needs to be static. If you do not provide any selection
value during the checks, Leda infers a new clock origin at the output of the MUX.

15

Chapter 1: Clock Domain Crossing

Therefore, if you intent to pass only one clock origin at the output of the MUX, you
need to provide the exact value of the 'MUX select signal' to using
'set_case_analysis'. An example of set_case_analysis value setting is given below.
set_case_analysis 0 top.mod1.mux_sel (full hierarchical name of
the MUX select signal)

In this case, you can choose to pass clock at input 0 of the MUX to MUX output.

Clk1

Clk3

Clk2

mux_sel

For more information about set_case_analysis, see the Leda User Guide. For
information about clock gating cell, see the next section.
Proper BBOX settings - In complex designs, multiple memory blocks, analog
blocks, third party IPs are commonly used. There form portions of the design that
may not need CDC analysis. You should properly set these modules as Black-boxes
in Leda for proper CDC checks. For more information about setting black-boxes in
Leda, see the Leda User Guide.
Grouping of Leda extracted clock origins - Leda, as a static checker, uses an
algorithm while detecting clock sources (or clock origins) in the design. Therefore,
Leda might detect larger number of clock origins. These extra clock origins are
usually output of combinational blocks in the clock path of various design clock
sources. You need to group these extra origins to appropriate clock sources to
extract proper clock domain crossing paths.

16

Chapter 1: Clock Domain Crossing

Example
Suppose in a design, four clock origins - top.clk1, top.internal1, top.internal2, top.clk2
have been extracted. However, you intent to generate only two clocks top.clk1 and
top.clk2. In this case, you need to provide the following clock grouping to Leda.
set_clock_groups -name CLK1 -asynchronous -group {\
top.clk1 \
top.internal1 \
}
set_clock_groups -name CLK2 -asynchronous -group {\
top.clk2 \
top.internal2 \
}

Clock Inference with Clock Gating Cells


Leda treats clock gating cell as special cells that you can use in a clock path to control
the operation of some sub parts of the design. A clock gating cell can have multiple
inputs. One of these inputs is marked as a clock pin (clock_gating_clock_pin). The other
pins include 'enable pin', etc.
If a clock gating cell is present in the clock path of a FF, then the output of that cell is not
considered as a clock origin (specifically a 'gated clock origin'). Instead, the signal that
is connected to the 'clock' pin of the cell is treated as the clock origin of this FF clock
pin.
The following figure gives an example scenario of this:

FF2
clk

out1
clock_gating_cell

FF1

17

Chapter 1: Clock Domain Crossing

In this example, for standard clock gating cell, Leda infers signal clk as clock origin
and not the signal out1. Even if FF1 is not there, Leda would still infer signal clk as
clock origin.

Synchronization Techniques
The main responsibility of a synchronizer is to allow sufficient time such that any metasable 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

dat

adat

bdat1

bdat2

aclk
bclk

Synchronization of Control Signals with 2-FF


Synchronizers
In a 2-FF synchronizer, the first flip-flop samples the asynchronous input signal into the
destination clock domain and waits for a full destination clock cycle to permit any metastability on the stage-1 output signal to decay, then the stage-1 signal is sampled by the
same clock into a second stage flip-flop, with the intended goal that the stage-2 signal is
now a stable and valid signal synchronized into the destination clock domain. It is
theoretically possible for the stage-1 signal to still be sufficiently meta-stable by the
time the signal is clocked into the second stage to cause the stage-2 signal to also go
meta-stable.
However, note that the meta-stability is a probabilistic phenomenon. The meta-stable
output converges to a stable value with time. Therefore, even if the input to the stage-2
FF still remains meta-stable, the probability that the output of the stage-2 FF will remain
meta-stable for a full destination clock cycle is asymptotically close to zero. This
calculation of the probability of the time between synchronization failures (MTBF) is a

18

Chapter 1: Clock Domain Crossing

function of multiple variables including the clock frequencies used to generate the input
signal and to clock the synchronizing flip-flops. For most synchronization applications,
a 2-FF synchronizer is sufficient to remove all likely meta-stability.
Even if a 2-FF synchronizer helps to prevent propagation of meta-stable values, for the
correct operation of the design, some other issues needs to be tackled. These issues are
explained in the following sections.

Input Data Stability to Avoid Data Loss


A synchronizer circuit ensures avoiding propagation of meta-stability into the
destination clock domain, but it can't ensure propagation of correct value as the metastable signal non-deterministically converges to any stable value (1 or 0). However, for
correct operation of the design, every transition on the input signal needs to be correctly
propagated to the destination domain. To ensure preventing data loss (losing input
transitions), the input signal needs to hold its value a minimum amount of 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
bclk
adat

Keep values stable

bdat1

Correct value
propagated

Gray Encoding to Avoid Data Incoherence (For Vector CDC


Control Signals)
Similar to the case of syncing a single bit control signal, the natural way to transfer a
vector control signal is to model each bit of the vector to be separately synchronized by
a FF synchronizer. You have already seen that even if you use FF synchronizers, it
usually takes more than one cycle to propagate correct input values to the destination
domain. Now consider a case where every bit of the vector takes a transition very close
to the destination clock edge. Also assume that, by virtue of meta-stability, only some of

19

Chapter 1: Clock Domain Crossing

these transitions are correctly captured by the destination domain in the first cycle. Now,
if the bit values of the vector decide the state of the destination domain, after the first
cycle, the destination domain may move into an invalid state.
Figure 6: Scenario indicating Data Incoherence
dclk

Sig [2]
Sig [1]
Sig [0]

dSig [2]
dSig [1]
dSig [0]
Invalid state

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.

20

Chapter 1: Clock Domain Crossing

Synchronization of CDC Data Signals


One of the challenges in designing a multi-clock based system is to enable correct
transfer of data buses from one clock domain to another. The difficulty arises, as
individual bits of a data bus can change randomly while changing clock boundaries.
Using synchronizers/gray code to handle the passing of data bus is generally
unacceptable.
Three common methods for synchronizing data between clock domains are:
Using MUX based synchronizers.
Using Handshake signals.
Using FIFOs (First In First Out memories) to store data with one clock domain and
to retrieve data with another clock domain.

Passing Data through MUX Synchronizer


As shown in the following figure (Figure 7), in a MUX synchronizer, the control path is
usually FF-synchronized while the synced-in control signal is used to synchronize the
data paths.
Figure 7: A MUX synchronizer

clk1

21

Chapter 1: Clock Domain Crossing

Handshaking Data between Clock Domains


Data can be passed between clock domains using a set of handshake control signals,
depending on the application and the paranoia of the design engineer. When it comes to
handshaking, the more control signals that are used, the longer the latency to pass data
from one clock domain to another. The biggest disadvantage in using handshaking is the
latency required to pass and recognize all of the handshaking signals for each data word
that is transferred. Figure 8 shows a typical handshake synchronizer.
Figure 8: A Handshake Synchronizer

For many open-ended data-passing applications, a simple two-line handshaking


sequence is sufficient. The sender places data onto a data bus and then 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.

Passing Data by FIFO between Clock Domains


One of the most popular methods of passing data between clock domains is to use a
FIFO. A dual port memory is used for the FIFO storage. One port is controlled by the
sender, which puts data into the memory as fast as one data word (or one data bit for
serial applications) per write clock. The other port is controlled by the receiver, which
pulls data out of memory; one data word per read clock. Two control signals are used to
indicate if the FIFO is empty, full, or partially full. Two additional control signals are
frequently used to indicate if the FIFO is almost full or almost empty. In theory, placing

22

Chapter 1: Clock Domain Crossing

data into a shared memory with one clock and removing the data from the shared
memory with another clock seems like an easy and ideal solution to passing data
between clock domains. For the most part it is, but generating accurate full and empty
flags can be challenging.
Figure 9: A dual-clock FIFO Synchronizer

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

23

Chapter 1: Clock Domain Crossing

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.

Structural Analysis to Identify Structural Defects


before and after Synchronization
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 multi-clock based
systems are as follows.

Convergence in the Crossover Path


Using combinational elements in a CDC path before synchronization can lead to
functional problems. For example, it is important that glitches in the driving clock
domain not be propagated into the receiving clock domain. Since the flip-flops in the
receiving clock domain can sample the signals from the driving clock domain at any
point, there is no way through static timing analysis to ensure that the glitch will not be

24

Chapter 1: Clock Domain Crossing

propagated. Figure 11 shows an example of combinational logic (convergence) that


could cause a glitch to pass from one clock domain to another. Rule NTL_CDC02
detects this issue.
Figure 11: Glitch propagation due to convergence in CDC Path
a

a
out

out1

CLK1

a
b
a
b
out

CLK2

out1

Note

One of the possible ways to avoid this problem is to register the output of the
AND gate which is clocked by (source domain) CLK1. It is better to have
the n-FF CDC synchronizer where FF driven from CLK1 domain need to be
directly connected to the 2-FF synchronizer clocked by CLK2.

25

Chapter 1: Clock Domain Crossing

Divergence in the Crossover Path


Design styles which allow divergent logic on a CDC signal to multiple synchronization
paths, may cause functional errors. As Figure 12 illustrates, a single control signal
(Trans_en) from the source clock domain (clk1) is used to activate both the "addr" and
"data" transfer unit in the destination clock domain (clk2). The purpose is to enable both
the logics at the same time. To model this, fan-outs of Trans_en has been used before the
synchronization takes place. However, due to the propagation delay and different metastable settling times, the two fan-outs ('addr_en' and 'data_en') could reach the Address
and Data transfer logics at different times. Therefore these two logics may start at
different time causing functional errors. This type of structure should be avoided by
fanning out a single FF synchronized 'common enable' signal to the two transfer logics.
Rule NTL_CDC03 detects this issue.
Figure 12: Divergence in the crossover path
adr_en_sync

FF1

FF0

Address
Transfer
Logic

Trans_en
data_en_sync

clk1

FF3
clk2

26

FF2

FF4

Data
Transfer
Logic

Chapter 1: Clock Domain Crossing

Divergence of Meta-stable Signal


Using a meta-stable signal in a design can be erroneous. Therefore multiple fan-out of
the output of the first FF of a FF synchronizer can cause functional errors. Rule
NTL_CDC04 detects this issue.
Figure 13: Divergence of meta-stable signal

FF0
clk1

FF1

FF2

clk2

Other Logic

27

Chapter 1: Clock Domain Crossing

Re-convergence of Synchronized Signals


Synchronization and glitch elimination alone are not enough to ensure reliable transfer
of data across clock domains. When a signal goes meta-stable, a 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 NTL_CDC07 detect this issue.
Figure 14: The simplest form of re-convergence

ASig1

SSig1

CLKA

L
O

CLKB

G
I

ASig2
CLKA

SSig2

CLKB

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.
Note

One of the possible ways to avoid this problem is to have the distinction
between control and data logic synchronization mechanism or to use the
gray encoding circuit at the time of convergence (after the synchronization).

28

Chapter 1: Clock Domain Crossing

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/08 - Reports all kinds of re-convergence of synchronized
signals in the design. There is a subtle difference between rule NTL_CDC05,
NTL_CDC07, and NTL_CDC08. For more information about the difference,
see the section CDC Ruleset in chapter 2.

Determination and Validation of appropriate Properties for


every Synchronizer
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

29

Chapter 1: Clock Domain Crossing

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.

Leda - CDC Flow


The complete Leda CDC flow is given in Figure 15. The main CDC related modules
have been colored. The CDC verification engine takes help of the Magellan/VCS for
checking the Leda CDC assertions (statically/dynamically).
Figure 15: The complete Leda CDC flow

RTL

Hardware Inference
Error Fix
Netlist Generation

Clock origin/domain
Inference

CDC information
Extraction

30

Verify CDC

Magellan/VCS

Chapter 1: Clock Domain Crossing

Automatically Generated CDC Assertions


Structural analysis primarily checks whether there exists a synchronizer in the CDC
paths. Having a synchronizer connected only solves the verification problem partially.
You additionally need to check the following two features.
1. The environment (associated logic) must interact properly with the synchronizer.
2. The synchronizer itself behaves correctly.
These two checks are mandatory to ensure valid operation in real life. The AEP
(automatically extracted properties) engine of Leda generates and binds assertions that
check correct functionality of the synchronizers and validates correct use of the
synchronizers by its environment. To identify the synchronizers, the AEP engine uses
the Leda structural analyzer. In the following paragraphs, you will categorically
enumerate the synchronizer related checks for ABV (assertion based verification).

Synchronizers Identified by Leda


Leda identifies the following synchronizers:

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.

31

Chapter 1: Clock Domain Crossing

Input data values must be stable for m+1 destination clock edges.
Figure 16: Flip-flop Synchronizers
m flip-flops
rst

R
D Q

din

clk
sclk

R
D Q

R
D Q

clk

clk

dout

dclk

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);

To configure the detection of FF synchronizers according to the design usage, see


set_cdc_synchronizer on page 52.

32

Chapter 1: Clock Domain Crossing

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

din

ready_in

data

sDR

dout

0
MUX

dDR

sready

dready
m flip-flop sync.
dclk

sclk

33

Chapter 1: Clock Domain Crossing

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);

Handshake Synchronizers (Push)


Description
There are different types of handshake synchronizers in practice, but most come down to
the fundamental working principle of synchronizing a single-bit request into the
destination clock domain and waiting for a synchronized version of the acknowledge to
come back. The differences in the architecture of the handshake synchronizers take
place because of the higher level protocols for the associated interfaces, data
management, etc.
The handshake synchronizers use two m-flip-flop synchronizers to generate request and
acknowledge signals. The associated properties are given as follows.
Input Data Stability for the m-flip-flop Synchronizers - Input data values must be
stable for m+1 destination clock edges (Re-use of the assertion in 6.a)
Protocol check - The sender and the receiver should follow the handshake protocol
correctly.

34

Chapter 1: Clock Domain Crossing

Data Stability - The data must be present when request is asserted on the destination
and remain stable until the acknowledgment is generated.
Figure 18: Handshake synchronizers

data

sDR

dDR

sL
dCtrl
Src

sreq
sack

m flip-flop sync.
m flip-flop sync.

sclk

dreq

Dest

dack

dclk

Implementation
The following assertions cover the proper use of the m-flip-flop synchronizers, the
handshake protocol, and the corresponding data stability.
1. Input Data Stability for the m-flip-flop synchronizers
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
Flip-flop 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.

35

Chapter 1: Clock Domain Crossing

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.

36

Chapter 1: Clock Domain Crossing

Dual Clock FIFO Synchronizers


Description
Another common CDC synchronization circuit, which is used when the high latency of
the handshake protocols cannot be tolerated, is the dual-clock asynchronous FIFO as
shown in Fig 19. Although many implementation variations exist, the basic operation is
the same; data is written into a dual-port RAM block from the source clock domain and
the RAM is read in the destination clock domain. Gray-coded read and write pointers
are passed into the alternate clock domain (using two m-flip-flop synchronizers) to
generate full and empty status flags. The following properties are generated for the dualclock asynchronous FIFO:
The producer never writes when the FIFO is full.
The consumer never reads when the FIFO is empty.
Read and Write pointers must be gray-coded at source.
Checks for data integrity (FIFO preserves Order and Data Value).
Figure 19: FIFO Based Synchronizer

37

Chapter 1: Clock Domain Crossing

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));

38

Chapter 1: Clock Domain Crossing

Order and Data Preservation


//- The following code mimics the gray 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
A_p_data_integrity: assert property (p_data_integrity);

Complex Synchronizers
Any synchronizer identified by Leda's CDC manager, which does not fall in the
category of Single FF-Synchronizer, MUX Synchronizer, Handshake Synchronizer,
User-given Synchronizer, and FIFO Synchronizer is called a Complex Synchronizer.
Following are the examples of Complex Synchronizer:
A vector signal when FF-Synchronized constitutes a Complex Synchronizer. A
group of FF-Synchronizers when do not synchronize any CDC data path can create
a Complex Synchronizer.
In many cases, Leda might identify part of a real synchronizer and mark it as a
complex one. Therefore a Complex Synchronizer might need your intervention for
proper categorization.
.

39

Chapter 1: Clock Domain Crossing

For example,
- If CDC manager identifies part of FIFO synchronizer, then it might be
identified as a Complex Synchronizer.
- If CDC manager adds one or two more signals to a MUX/Handshake
Synchronizer, it would be a Complex Synchronizer.
Following is a case of Complex Synchronizer identification by Leda:
In the following test case, Leda identifies that a vector signal has been FF-Synchronized
and is used in the destination domain (converges to some combo logic). It therefore
group all these bits and try to find out whether they are giving rise to another known
synchronizer. In this case, it will not be inferred as a Complex Synchronizer.
module test (in1, in2, clk1, clk2, out2, sel);
input clk1, clk2, sel;
input [2:0] in1, in2;
output out2;
reg [2:0] out1, first, src;
reg out2;
wire temp;
always @(posedge clk1)
src <= in1;
always @(posedge clk2) begin
first <= src;
out1 <= first;
end
assign temp = out1[0] & out1[1] & out1[2];
always @(posedge clk2)
out2 <= temp;
endmodule

Note

For the above example, three violations of NTL_CDC01_0 (Flip-flop


Synchronizer found) is also reported (see the next page). The reason is that
Leda will report all FF synchronizer of the design irrespective of whether it
is a part of any other synchronizer.

40

Chapter 1: Clock Domain Crossing

config.tcl:
rule_deselect -all
rule_select -rule NTL_CDC01
rule_select -rule NTL_CDC01_0
rule_select -rule NTL_CDC01_3

Violation
12: out1 <= first;
^
test.v:12: CDC> [WARNING] NTL_CDC01_0: Flip-flop Synchronizer Detected
test.out1(0)
--- Source Clock: test.clk1 (file: test.v, line: 2)
--- Target Clock: test.clk2 (file: test.v, line: 2)
--- Source Register: test.src(0) (file: test.v, line: 9)
--- Target Register: test.out1(0) (file: test.v, line: 5)
12: out1 <= first;
^
test.v:12: CDC> [WARNING] NTL_CDC01_0: Flip-flop Synchronizer Detected
test.out1(1)
--- Source Clock: test.clk1 (file: test.v, line: 2)
--- Target Clock: test.clk2 (file: test.v, line: 2)
--- Source Register: test.src(1) (file: test.v, line: 9)
--- Target Register: test.out1(1) (file: test.v, line: 5)
12: out1 <= first;
^
test.v:12: CDC> [WARNING] NTL_CDC01_0: Flip-flop Synchronizer Detected
test.out1(2)
--- Source Clock: test.clk1 (file: test.v, line: 2)
--- Target Clock: test.clk2 (file: test.v, line: 2)
--- Source Register: test.src(2) (file: test.v, line: 9)
--- Target Register: test.out1(2) (file: test.v, line: 5)
1: module test (in1, in2, clk1, clk2, out2, sel);
^
test.v:1: CDC> [WARNING] NTL_CDC01_3: Complex Synchronizer Detected test
--- Source Clock: test.clk1 (file: test.v, line: 2)
--- Target Clock: test.clk2 (file: test.v, line: 2)
--- Source Register: test.src(0) (file: test.v, line: 9)
--- Target Register: test.out1(0) (file: test.v, line: 5)
--- Source Register: test.src(1) (file: test.v, line: 9)
--- Target Register: test.out1(1) (file: test.v, line: 5)
--- Source Register: test.src(2) (file: test.v, line: 9)
--- Target Register: test.out1(2) (file: test.v, line: 5)

41

Chapter 1: Clock Domain Crossing

Quasi Static Signal for Identifying Double FF


Synchronizer
Proper identification of a double FF (flip-flop) synchronization often needs specification
of 'quasi static inputs'. Typically, Leda does not allow any combinational logic between
the synchronizing FFs of a double FF synchronizer. Given some parameter, Leda allows
only inverter and buffer. However, in some cases, a 'quasi static signal' is often
connected to MUX select pins that enable functionality of a double FF synchronizer. In
these scenarios, a MUX is placed between the FFs of the double FF synchronizer, whose
select pin is driven by the quasi static signal. A typical schematic of such
synchronization schemes is given in following figure:

The dashed box is source FF in source clock domain (CLK1) and sold lined boxes are
synchronizing FFs in destination clock domain (CLK2).
By default, Leda will not treat the circuit having a MUX between a double FF
synchronizer as a 2-FF synchronizer. However, if you specify the MUX select pin as a
quasi static signal using the below Tcl command, then Leda takes this information and
recognizes the circuit as a double FF synchronizer.
set_quasi_static_signals
signal3, }

-signal_list

{top.mod1.mux_sel, signal2,

Note

You need to mention the signal with hierarchical information.


You can apply this Tcl command directly in Leda and use the -clock_file option in
batch mode.

42

Chapter 1: Clock Domain Crossing

Example
The following Verilog module works as a double FF synchronizer only if the following
command is set.
set_quasi_static_signals -signal_list {top.sel}

module top (in1, clk1, clk2, out1, sel);


input clk1, clk2, in1, sel;
output out1;
reg out1, first, src;
always @(posedge clk1) //- CDC src register
src <= in1;
always @(posedge clk2) //- 1 FF
begin
if (sel)
first <= src;
else
first <= first;
end
always @(posedge clk2)
begin
if (sel)
out1 <= first;
else
out1 <= out1;
end

//- 2 FF

endmodule

Gray Code Encoding for Vector Control


Signals
Description
This check addresses multi-bit signals (bit vectors or a collection of individual signals)
that originate in one clock domain with the clocking event sclk and then re-converge in
another clock domain with the clocking event dclk without using any of the above
handshake-based synchronization schemes. Such signals must all have m-flip-flop
synchronizers and in addition they must be Gray-code encoded before entering the

43

Chapter 1: Clock Domain Crossing

synchronizers. In this way, when there is a change from one state of the multi-bit signal
to another, only one bit changes at a time. It ensures that the destination side will not
sample inconsistent state values due to different skews and meta-stability delays on each
bit. The Gray code may be decoded on the destination side, after the individual
synchronizers.
Figure 20: Multi-bit Data Transfer
Gray code
assertion
Source
domain
logic

m flip-flop sync.
din

n bits

data_out

Destination
domain
logic

m flip-flop sync.
sclk

dclk

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 multibit 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.

44

Chapter 1: Clock Domain Crossing

CDC AEP Rule Usage


Clock Domain Crossing is a global problem and Leda currently has an effective solution
for CDC verification. In this section, the CDC rules that generate assertions for
verifying functionality of each of the CDC synchronizer recognized in the design
(NTL_CDC06, and NTL_CDC14 - NTL_CDC16) are elaborated. In addition, there is a
rule NTL_CDC08, which checks for the correct implementation of gray coding for each
vector CDC control signal detected in the design.
The purpose of adding these five rules is to provide the following information:
NTL_CDC06 - Indicates that FF synchronizers have been used in the design. For
each of these FF synchronizers, Leda generates assertion for checking the signal
stability property of the associated CDC control signal.
NTL_CDC08 - The purpose of NTL_CDC08 is two fold. First to report 'reconvergence scenario' for a set of individually synchronized signals. The second
purpose is to generate gray code assertions for "re-converging" vector signals. For
each of such vector CDC control (synchronized) signal, Leda generates assertion for
checking whether the associated vector has been gray coded. Note that
NTL_CDC08 does not generate gray code property for re-converging non-vector
signals.
NTL_CDC14 - Indicates that MUX synchronizers have been used in the design. For
each of such MUX synchronizers, Leda generates assertions for checking signal
stability of the associated control and data signals.
NTL_CDC15 - Indicates that Handshake (Push/Pull) synchronizers have been used
in the design. For each of such Handshake synchronizers, Leda generates assertions
for checking signal stability of the associated control and data signals. In addition, it
generates assertions for checking the correctness of the associated handshake
protocol.
NTL_CDC16 - Indicates that FIFO synchronizers have been used in the design. For
each of such FIFO synchronizers, Leda generates assertions for checking empty/full
criterion of the associated FIFO. In addition, it generates assertions for checking the
(a) data signal integrity of the FIFO, and (b) gray coding of the FIFO read/write
pointers.
Furthermore, the detailed structural analysis statistics for the CDC synchronizers (such
as the numbers, locations etc.) can be accessed in the following ways:
While using Tcl mode (switch leda +tcl_shell), there is a command called
'report_cdc_info', which displays all types of detected CDC structures.

45

Chapter 1: Clock Domain Crossing

There are 7 rules (NTL_CDC01, NTL_CDC01_0, NTL_CDC01_1, ,


NTL_CDC01_6) which when selected displays all types of CDC structures
(synchronized, unsynchronized) detected in a design by Leda.
The section CDC Tcl Interface provides details of the current CDC Tcl interface.
Additionally, each of the CDC assertion specific rules NTL_CDC14 - NTL_CDC16
also provides signal specific information about the CDC synchronizers. An example is
provided in the section CDC Analysis.

46

Chapter 1: Clock Domain Crossing

Naming Convention for Automatically


Generated CDC AEP Files
For each of the rules specified in previous section, Leda generates a separate assertion
file. This file contains the template/definition for the associated assertion. The naming
convention of the assertion files (also definitions) follows the specific issue for which
the assertion has been generated. For example, 'aep_signal_stability.v' file contains
assertion definition for checking the control signal stability. The generated file names
along with their purposes are given as follows:
aep_signal_stability.v - Checks control signal stability.
aep_mux_data_signal_stability.v - Checks data signal stability of a MUX
synchronizer.
aep_handshake_data_signal_stability.v - Checks data signal stability of a
Handshake synchronizer.
aep_handshake_protocol_check.v - Checks handshake protocol checks for a
Handshake synchronizer.
aep_fifo_validate_assertions.v - Checks fifo properties (full/empty, data integrity)
for a FIFO synchronizer.
Each of these assertion definition files are generated only once. As every complex
synchronizer (MUX, FIFO, and Handshake) uses FF synchronizers for synchronizing
the control signals, aep_signal_satbility.v is also re-used for each of them.

Binding the Assertion Definitions to the Design


The generated assertion definitions are attached to the design signals using a set of 'bind'
statements. These bind statements are generated in a separate file named
'leda_top_properties.v'. As there can be multiple instances of a specific synchronizer, for
each of these instances, a separate bind statement is generated. The instance name of the
assertion definitions (used in the bind statements) is numbered.
The general idea for generating properties is to use prepackage modules containing
assertions and bind them to the verified design. The bind should try 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:
bind <property_module_name> #( <parameters> ) <bind_instance_name> (
<port_list>);
where, <bind_instance_name> is of the form:
i_<RULE_LABEL>_<INSTANCE_NUMBER>

47

Chapter 1: Clock Domain Crossing

For example if there are three FF synchronizers detected in a design, there would be one
control signal stability assertion definition and three separate bind statements generated
with three unique assertion instances namely - i_NTL_CDC06_1, i_NTL_CDC06_2,
and i_NTL_CDC06_3.
Sometimes, if you want to avoid explosion of the simulation time or Magellan running
time, you can also bound the number of properties that are generated. The
set_max_properties command placed in the design configuration file allows controlling
this number. This command is not specific to the CDC Manager; it is part of the property
generation manager.
set_aep_max_properties -value max_value

Using Generated Assertions in VCS and Magellan


The generated assertions can be verified on the design using (1) VCS (simulation based
verification) or (2) Magellan (formal verification). To simplify building of the
assertions, a file (named leda_prop_file.lst) containing the list of automatically
generated files is created. As a result, you only need to attach file 'leda_prop_file.lst' to
the associated checker tool.
The set of assertion related files are generated in a directory naming 'ForMG'. This
directory is located by default in .leda_work or in case .leda_work is missing in the 'run
directory.
Moreover, for Magellan, a project file template (named 'LedaMgPrjFile.prj') is also
generated. You (sometimes) may need to add additional information like - the clock
periods, the reset configurations etc. in this template. You don't need to use any switch
for generating the assertions. The assertions and the associated files are created by
default.
For Mixed designs (having both VHDL and Verilog models), CDC assertion evaluation
needs manual intervention. Moreover, for generating Magellan project file for MX flow,
you need to set the following environment variable:
setenv

LEDA_MG_MX_FLOW 1

After generating the project file, contact Leda support for further assistance.

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.

48

Chapter 1: Clock Domain Crossing

Configuring Latches in CDC Analysis


A Latch can lead to the following scenarios during CDC analysis:
Latch as an endpoint - If you want to use Latch as a source or destination point of a
clock domain crossing path, then use the following command.
set_cdc_parameter -name "STOP_AT_LATCH" -value 1

Latch as a combinational logic (transparent element) - This is the default behavior


of Leda. In many designs, Latches are used as a pass through combinational logic
during CDC analysis. In this case, Leda does not treat the Latch as a CDC path
endpoint.
set_cdc_parameter -name "STOP_AT_LATCH" -value 0

CDC Tcl Interface


The following is the command reference information for built-in Tcl commands that you
can use to manage the CDC 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
-to

Specify the source flip-flop name.


Specify the target flip-flop name.

49

Chapter 1: Clock Domain Crossing

Although -from and -to are optional, at least one of the options must be used. If you
dont specify any one of the options, then its value is considered as any. For example:
module cdc01_4 (in1, in2, clk1, clk2, out2, sel);
input clk1, clk2, sel;
input in1, in2;
output out2;
reg out1, first, src;
reg out2;
wire muxout1, muxout2;
wire temp;
always @(posedge clk1)
src <= in1;
always @(posedge clk2)
begin
if (sel)
first <= src;
else
first <= first;
end
always @(posedge clk2)
begin
if (sel)
out1 <= first;
else
out1 <= out1;
end
//assign temp = out1[0] & out1[1] & out1[2];
always @(posedge clk2)
out2 <= out1;
endmodule

Script file(script.tcl)
read_verilog cdc01_4.v +v2k
elaborate -top cdc01_4

50

Chapter 1: Clock Domain Crossing

check -config cfg.tcl


report
clear_cdc_info
elaborate -top cdc01_4
set_cdc_ignored_path -from cdc01_4.src
check -config cfg.tcl
report

As mentioned above, user has to clear CDC information using the command
clear_ cdc_info before setting the ignored path. Any path starting from the src signal
will be ignored by Leda for CDC checks.

Support of Wildcard in set_cdc_ignored_path Command


You can use wildcard for signals specified with the Tcl command
set_cdc_ignored_path. For example:
# sample command
set_cdc_ignored_path -from

top.sub1.I1.qout_1

set_cdc_ignored_path -from

top.sub1.I1.qout_2

set_cdc_ignored_path -from

top.sub1.I1.qout_3

set_cdc_ignored_path -from

top.sub1.I1.qout_4

Now by using wildcard, you can specify the signal as follows:


set_cdc_ignored_path -from top.sub1.I1.qout_*

This makes sure that all the signals qout_1, qout_2, qout_3, and qout_4 are applied to
the set_cdc_ignored_path command.
If you see $ sign in the hierarchical path, for example,
top.sub1.$_U1.I1.qout_1, then you should prefix \, as shown below, to filter
the violation message.
set_cdc_ignored_path -from top.sub1.\$_U1.I1.qout_*

51

Chapter 1: Clock Domain Crossing

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 to
all synchronizers

Parameters applicable to
FIFO synchronizer

-source_clock

-source_clock

-source_clock

-target_clock

-target_clock

-target_clock

-write_signal

-handshake kind (can be


pushhanshake or
pullhandshake)

-read_signal

-transmit_signal

-fifo_full

-receive_signal

-fifo_empty

52

Parameters applicable to
handshake synchronizer

Chapter 1: Clock Domain Crossing

Table 2: Parameters of different synchronizers


Parameters applicable to
all synchronizers

Parameters applicable to
FIFO synchronizer

Parameters applicable to
handshake synchronizer

-write_reset_signal
-write_read_signal
-data_signal

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}

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

53

Chapter 1: Clock Domain Crossing

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.

Note

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

54

Chapter 1: Clock Domain Crossing

set_cdc_parameter [-name cdc_parameter_name] [-value cdc_parameter_value]

Arguments
-name

Specifies the CDC Parameter Name

-value

Specifies the CDC Parameter Value

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 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.
STOP_AT_LATCH - This parameter is used when you want to use Latch as a source
or destination point of a clock domain crossing path.

55

Chapter 1: Clock Domain Crossing

56

Chapter 2: Clock Domain Crossing Rules

2
Clock Domain Crossing Rules
Introduction
This chapter presents detailed reference information about the rules contained in the
CDC ruleset of Design policy. This ruleset specifies rules that covers many aspects of
clock domain crossing (CDC).

Note

Clock domain crossing rules under CDC ruleset of Design policy is


currently a beta feature.

57

Chapter 2: Clock Domain Crossing Rules

CDC Usage Model


To generate the complete CDC results from Leda, perform the following steps:
1. Do the following setting:
% setenv LEDA_MAX_CLOCKS 1
2. In your configuration file, make sure that you have chosen the CDC rules.
You can choose the CDC rules in the config file as follows:
rule_select policy DESIGN ruleset CDC
3. Run Leda in batch or Tcl mode.
You will see that Leda will flag a message saying:
WARNING: Leda has extracted x clock origins (x clock domains), which is
suspicious...
WARNING: Therefore no chip-level, netlist or sdc checks have been executed
WARNING: Please check the list of clock origins as dumped in
leda_<topname>_clocks.tcl,
WARNING: modify this file to group synchronous clocks using set_clock_groups
command,
WARNING: set $LEDA_CLOCK_FILE or use option -clock_file to point to this
file and re-run the checker
The clock grouping file with the name leda_<topname>_clocks.tcl that is generated
by Leda in the pwd, has to be grouped by the user and given back to Leda using the
option clock_file.
4. Run Leda specifying the clock grouping file using the option clock_file and the
configuration file using the option config.
5. All the CDC violations will be present in the leda.log file.

58

Chapter 2: Clock Domain Crossing Rules

CDC Ruleset
The following rules are from the CDC ruleset:

NTL_CDC00
Message: Clock domain crossing detected.
Description

This rule fires when Leda detects a clock domain crossing.

Policy

DESIGN

Ruleset

CDC

Language

VHDL/Verilog

Type

Hardware

Severity

Fatal

Example
This is an example of invalid Verilog code that illustrates the problem:
module NTL_CDC00 (d0, d1, q1, clk0, clk1);
input d0, d1, clk0, clk1;
output q1;
reg q0, q1;
wire n0;
// clock domain crossing from clk0 to clk1 detected here
always @ (posedge clk0) q0 <= d0;
assign n0 = ~q0;
always @ (posedge clk1)
q1 <= n0;
endmodule

59

Chapter 2: Clock Domain Crossing Rules

Violations
T11: q0 <= d0;
^
NTL_CDC00.v:11: CDC> [NOTE] NTL_CDC00: Clock domain crossing detected
NTL_CDC00.q0
--- Source clock: NTL_CDC00.clk0 (file: NTL_CDC00.v, line: 3)
--- Target register: NTL_CDC00.q1 (file: NTL_CDC00.v, line: 16)
--- Target clock: NTL_CDC00.clk1 (file: NTL_CDC00.v, line: 3)

Schematic

60

Chapter 2: Clock Domain Crossing Rules

NTL_CDC01
Message: No synchronization scheme found for signals
crossing clock domains
Description

Leda flags this rule when it finds signals (one or more) crossing from
one clock domain (say A) to another clock domain (say B) and no
global synchronization scheme is found.
This rule fires only one message for all the signals crossing between
domains.
You can use the rule_set_parameter Tcl command to configure the
following parameters:

SHOW_ALL_PATHS You can configure this parameter


to value 0, if you want Leda to show one violation per
path. If you set the value to 1, then Leda flags only one
violation for the CDC element. For example:
leda> rule_set_parameter -rule NTL_CDC01
-parameter SHOW_ALL_PATHS -value {1}

SHOW_CONTROL_PATHS You can configure this


parameter to display the control paths in the track info.
For this, you need to set the value of parameter
SHOW_CONTROL_PATHS to 1 and the value of
parameter SHOW_ALL_PATHS to 1. For example:
leda> rule_set_parameter -rule NTL_CDC01
-parameter SHOW_CONTROL_PATHS -value {1}

REPORT_BUS_ONLY When this parameter is


enabled, only unsynchronized CDC Bus signals would be
reported with NTL_CDC01 rule.
Therefore, if 'sig' is a bit, with parameter
REPORT_BUS_ONLY enabled, there will be no
NTL_CDC01 violations.
To set this parameter, modify the configuration file as
follows:
leda> rule_select -rule NTL_CDC01
leda> rule_set_parameter -rule NTL_CDC01
-parameter REPORT_BUS_ONLY -value 1

61

Chapter 2: Clock Domain Crossing Rules

Policy

DESIGN

Ruleset

CDC

Language

VHDL/Verilog

Type

Hardware

Severity

Fatal

Example
Following is an example of the rule:
module cdc01 (rst, clk1, clk2, clk3, din, dout);
input clk1;
input clk2;
input clk3;
input rst;
input din;
output dout;
reg dout;
reg d_reg0;
always @(posedge clk1 or negedge rst)
begin
if (~rst)
d_reg0 <= 1'b0;
else
d_reg0 <= din;
end
always @(posedge clk2 or negedge rst)
begin
if(~rst)
dout <= 1'b0;
else
dout <= d_reg0;
end
endmodule

62

Chapter 2: Clock Domain Crossing Rules

Violations
22: dout <= d_reg0;
^
NTL_CDC01.v:22: CDC> [FATAL] NTL_CDC01: no synchronization scheme found
for signals crossing clock domains cdc01.dout
--- Source Clock: cdc01.clk1 (file: NTL_CDC01.v, line: 2)
--- Target Clock: cdc01.clk2 (file: NTL_CDC01.v, line: 3)
--- Source Register: cdc01.d_reg0 (file: NTL_CDC01.v, line: 15)
--- Target Register: cdc01.dout (file: NTL_CDC01.v, line: 22)

Schematic

Note

You need to have NTL_CDC01 rule selected in the config file to have the
below mentioned rules working.
NTL_CDC01_0, NTL_CDC01_1, NTL_CDC01_3, NTL_CDC01_4,
NTL_CDC01_5, NTL_CDC01_6.

63

Chapter 2: Clock Domain Crossing Rules

NTL_CDC01_0
Message: Flip-flop Synchronizer detected
Description

This rule is flagged when Leda detects a flip-flop synchronizer.

Policy

DESIGN

Ruleset

CDC

Language

VHDL/Verilog

Type

Hardware

Severity

Warning

Note

To run this rule, you must select the NTL_CDC01 rule in the configuration
file.

64

Chapter 2: Clock Domain Crossing Rules

Example
Following is an example of this rule:
module cdc01_0 (rst, clk1, clk2, clk3, din, dout);
input clk1;
input clk2;
input clk3;
input rst;
input din;
output dout;
reg dout;
reg d_reg0;
reg d_reg1;
reg d_reg2;
always @(posedge clk1 or negedge rst)
begin
if (~rst)
d_reg0 <= 1'b0;
else
d_reg0 <= din;
end
always @(posedge clk2 or negedge rst)
begin
if (~rst) begin
d_reg1 <= 1'b0;
d_reg2 <= 1'b0; end
else begin
d_reg1 <= d_reg0;
d_reg2 <= d_reg1; end
end
always @(posedge clk2 or negedge rst)
begin
if(~rst)
dout <= 1'b0;
else
dout <= d_reg2;
end
endmodule

65

Chapter 2: Clock Domain Crossing Rules

Violations
27: d_reg2 <= d_reg1;
^
NTL_CDC01_0.v:27: CDC> [WARNING] NTL_CDC01_0: Flip-flop Synchronizer
Detected cdc01_0.d_reg2
--- Source Clock: cdc01_0.clk1 (file: NTL_CDC01_0.v, line: 2)
--- Target Clock: cdc01_0.clk2 (file: NTL_CDC01_0.v, line: 3)
--- Source Register: cdc01_0.d_reg0 (file: NTL_CDC01_0.v, line: 17)
--- Target Register: cdc01_0.d_reg2 (file: NTL_CDC01_0.v, line: 11)

66

Chapter 2: Clock Domain Crossing Rules

NTL_CDC01_1
Message: Logic Synchronizer detected
Description

This rule is flagged when Leda detects a logic synchronizer.

Policy

DESIGN

Ruleset

CDC

Language

VHDL/Verilog

Type

Hardware

Severity

Warning

Note

To run this rule, you must select the NTL_CDC01 rule in the configuration
file.
Example
Following is an example of this rule:
In the following figure, a 4-bit data path from clock domain of clk1 is passed through a
MUX 'm' to the domain of 'clk2'. The MUX is enabled by a 2-FF synchronized control
signal 'rx_dsel'. Clearly this arrangement is a MUX synchronizer.

67

Chapter 2: Clock Domain Crossing Rules

68

Chapter 2: Clock Domain Crossing Rules

module cdc01_1 (rst, clk1, clk2, din, sel, dout);


input rst, clk1, clk2, sel;
input [3:0] din;
output [3:0] dout;
wire tx_dsel; wire [3:0] tx_data;
reg meta_tx_dsel, rx_dsel;
tx tx(rst, clk1, din, sel, tx_data, tx_dsel);
always @(posedge clk2)
if (rst) begin
meta_tx_dsel <= 0; rx_dsel <= 0;
end
else begin
meta_tx_dsel <= tx_dsel;
rx_dsel <= meta_tx_dsel;
end
rx rx(rst, clk2, tx_data, rx_dsel, dout);
endmodule
module tx (rst, clk1, din, sel, tx_data, tx_dsel);
input rst, clk1, sel;
input [3:0] din;
output [3:0] tx_data;
output tx_dsel;
reg [3:0] tx_data; reg tx_dsel;
always @(posedge clk1)
if (rst) begin
tx_data <= 0; tx_dsel <= 0;
end
else begin
tx_data <= din;
tx_dsel <= sel;
end
endmodule
module rx (rst, clk2, rx_data, rx_dsel, dout);
input rst, clk2, rx_dsel;
input [3:0] rx_data;
output [3:0] dout;
reg [3:0] dout;
wire [3:0] data;
assign data =rx_dsel? rx_data : dout;

69

Chapter 2: Clock Domain Crossing Rules

always @(posedge clk2)


if (rst)
dout <= 0;
else
dout <= data;
endmodule

Violations
1: module cdc01_1 (rst, clk1, clk2, din, sel, dout);
^
NTL_CDC01_1.v:1: CDC> [WARNING] NTL_CDC01_1: Logic Synchronizer Detected
cdc01_1
--- Source Clock: cdc01_1.clk1 (file: NTL_CDC01_1.v, line: 2)
--- Target Clock: cdc01_1.clk2 (file: NTL_CDC01_1.v, line: 2)
--- Source Register: cdc01_1.tx.tx_dsel (file: NTL_CDC01_1.v, line: 30)
--- Target Register: cdc01_1.rx_dsel (file: NTL_CDC01_1.v, line: 6)
--- Source Register: cdc01_1.tx.tx_data(0) (file: NTL_CDC01_1.v, line:
29)
--- Target Register: cdc01_1.rx.dout(0) (file: NTL_CDC01_1.v, line: 45)
--- Source Register: cdc01_1.tx.tx_data(1) (file: NTL_CDC01_1.v, line:
29)
--- Target Register: cdc01_1.rx.dout(1) (file: NTL_CDC01_1.v, line: 45)
--- Source Register: cdc01_1.tx.tx_data(2) (file: NTL_CDC01_1.v, line:
29)
--- Target Register: cdc01_1.rx.dout(2) (file: NTL_CDC01_1.v, line: 45)
--- Source Register: cdc01_1.tx.tx_data(3) (file: NTL_CDC01_1.v, line:
29)
--- Target Register: cdc01_1.rx.dout(3) (file: NTL_CDC01_1.v, line: 45)

Note

Leda not only flags NTL_CDC01_1, but also flags NTL_CDC01_0 (2FF
synchronizer found) for the 2ff synchronizer that is present on the control
signal path of the MUX synchronizer.

70

Chapter 2: Clock Domain Crossing Rules

NTL_CDC01_3
Message: Complex Synchronizer detected
Description

This rule is flagged when Leda detects a complex synchronizer.


Please refer Synchronizers Identified by Leda for Ledas inference
of Complex Synchronizers.

Policy

DESIGN

Ruleset

CDC

Language

VHDL/Verilog

Type

Hardware

Severity

Warning

Note

To run this rule, you must select the NTL_CDC01 rule in the configuration
file.

71

Chapter 2: Clock Domain Crossing Rules

Example
Following example illustrates the rule:
module cdc01_3 (in1, in2, clk1, clk2, out2, sel);
input clk1, clk2, sel;
input [2:0] in1, in2;
output out2;
reg [2:0] out1, first, src;
reg out2;
wire temp;
always @(posedge clk1)
src <= in1;
always @(posedge clk2) begin
first <= src;
out1 <= first;
end
assign temp = out1[0] & out1[1] & out1[2];
always @(posedge clk2)
out2 <= temp;
endmodule

Violations
1: module cdc01_3 (in1, in2, clk1, clk2, out2, sel);
^
NTL_CDC01_3.v:1: CDC> [WARNING] NTL_CDC01_3: Complex Synchronizer
Detected cdc01_3
--- Source Clock: cdc01_3.clk1 (file: NTL_CDC01_3.v, line: 2)
--- Target Clock: cdc01_3.clk2 (file: NTL_CDC01_3.v, line: 2)
--- Source Register: cdc01_3.src(0) (file: NTL_CDC01_3.v, line: 10)
--- Target Register: cdc01_3.out1(0) (file: NTL_CDC01_3.v, line: 5)
--- Source Register: cdc01_3.src(1) (file: NTL_CDC01_3.v, line: 10)
--- Target Register: cdc01_3.out1(1) (file: NTL_CDC01_3.v, line: 5)
--- Source Register: cdc01_3.src(2) (file: NTL_CDC01_3.v, line: 10)
--- Target Register: cdc01_3.out1(2) (file: NTL_CDC01_3.v, line: 5)

72

Chapter 2: Clock Domain Crossing Rules

NTL_CDC01_4
Message: User-Defined Synchronizer detected
Description

This rule is flagged when Leda detects a user-defined synchronizer.

Policy

DESIGN

Ruleset

CDC

Language

VHDL/Verilog

Type

Hardware

Severity

Warning

Note

To run this rule, you must select the NTL_CDC01 rule in the configuration
file.

73

Chapter 2: Clock Domain Crossing Rules

Example
Following is an example of this rule:
module cdc01_4 (in1, in2, clk1, clk2, out2, sel);
input clk1, clk2, sel;
input in1, in2;
output out2;
reg out1, first, src;
reg out2;
wire muxout1, muxout2;
wire temp;
always @(posedge clk1)
src <= in1;
always @(posedge clk2)
begin
if (sel)
first <= src;
else
first <= first;
end
always @(posedge clk2)
begin
if (sel)
out1 <= first;
else
out1 <= out1;
end
//assign temp = out1[0] & out1[1] & out1[2];
always @(posedge clk2)
out2 <= out1;
endmodule

User given info (param.tcl)


set_cdc_synchronizer -name {cdc01_4}

Run command
$LEDA_PATH/bin/leda -top test -config config.tcl test.v -clock_file
param.tcl -netlist

74

Chapter 2: Clock Domain Crossing Rules

Violations
16: first <= first;
^
NTL_CDC01_4.v:16: CDC> [WARNING] NTL_CDC01_4: User defined Synchronizer
Detected cdc01_4.first
--- Source Clock: cdc01_4.clk1 (file: NTL_CDC01_4.v, line: 2)
--- Target Clock: cdc01_4.clk2 (file: NTL_CDC01_4.v, line: 2)
--- Source Register: cdc01_4.src (file: NTL_CDC01_4.v, line: 10)
--- Target Register: cdc01_4.first (file: NTL_CDC01_4.v, line: 16)

NTL_CDC01_5
Message: Fifo Synchronizer detected
Description

This rule is flagged when Leda detects a FIFO synchronizer.

Policy

DESIGN

Ruleset

CDC

Language

VHDL/Verilog

Type

Hardware

Severity

Warning

Note

To run this rule, you must select the NTL_CDC01 rule in the configuration
file.

75

Chapter 2: Clock Domain Crossing Rules

Example
In the following figure, an 8-bit data path from clock domain (clk1) is fed to clk2
domain (via a FIFO synchronizer). The interface of the FIFO module is given as
follows:

clk1
full

clk2

empty
read

write
write_data

76

FIFO Module
read_data

Chapter 2: Clock Domain Crossing Rules

When the associated design is checked enabling rule NTL_CDC01_5, Leda detects the
synchronizer, and provides the following text. Set the following Tcl command for proper
detection of a FIFO synchronizer.
set_cdc_synchronizer -name test -synchro_type fifo
module cdc01_5 (x,y,z,d_out,f_full_flag,f_half_full_flag,f_empty_flag,
f_almost_full_flag,f_almost_empty_flag,d_in,r_en,w_en,
CLKIN_IN,RST_IN,reset);
parameter
parameter
parameter
parameter
parameter
parameter

f_width=8;
f_depth=16;
f_ptr_width=4;
f_half_full_value=8;
f_almost_full_value=14;
f_almost_empty_value=2;

output [f_width-1:0] d_out;


//reg [f_width-1:0] d_out;
//outputs
output f_full_flag,f_half_full_flag, f_almost_full_flag, f_empty_flag;
output f_almost_empty_flag;
output x,y,z;
input [f_width-1:0] d_in;
input r_en,w_en,CLKIN_IN,RST_IN;
input reset;
a_fifo5 a_fifo55(d_out,f_full_flag,f_half_full_flag,f_empty_flag,
f_almost_full_flag,f_almost_empty_flag,d_in,r_en,
w_en,CLK0_OUT,CLKDV_OUT,reset); //instantiate fifo
endmodule

module a_fifo5 (d_out,f_full_flag,f_half_full_flag,f_empty_flag,


f_almost_full_flag,f_almost_empty_flag,d_in,r_en,
w_en,r_clk,w_clk,reset);
parameter f_width=8; //FIFO width
parameter f_depth=16; //FIFO depth
parameter f_ptr_width=4; //because depth =16;
parameter f_half_full_value=8;
parameter f_almost_full_value=14;
parameter f_almost_empty_value=2;
output [f_width-1:0] d_out; reg [f_width-1:0] d_out;

77

Chapter 2: Clock Domain Crossing Rules

//outputs
output f_full_flag,f_half_full_flag,f_almost_full_flag, f_empty_flag;
output f_almost_empty_flag;
input [f_width-1:0] d_in;
input r_en,w_en,r_clk,w_clk;
input reset;
//internal registers,wires
wire [f_ptr_width-1:0] r_ptr,w_ptr;
reg r_next_en,w_next_en;
reg [f_ptr_width-1:0] ptr_diff;
reg [f_width-1:0] f_memory[f_depth-1:0];
assign
assign
assign
assign
assign

f_full_flag=(ptr_diff==(f_depth-1)); //assign FIFO status


f_empty_flag=(ptr_diff==0);
f_half_full_flag=(ptr_diff==f_half_full_value);
f_almost_full_flag=(ptr_diff==f_almost_full_value);
f_almost_empty_flag=(ptr_diff==f_almost_empty_value);

always @(posedge w_clk) //write to memory


begin
if (reset)
f_memory [w_ptr] <= 0;
else if(w_en) begin
if(!f_full_flag)
f_memory[w_ptr]<=d_in;
end
end
always @(posedge r_clk) //read from memory
begin
if(reset)
d_out<=0; //f_memory[r_ptr];
else if(r_en) begin
if(!f_empty_flag)
d_out<=f_memory[r_ptr];
end
else d_out<=0;
end
always @(*) //ptr_diff changes as read or write clock change
begin
if(w_ptr>r_ptr)
ptr_diff<=w_ptr-r_ptr;
else if(w_ptr<r_ptr)
ptr_diff<=((f_depth-r_ptr)+w_ptr);
else ptr_diff<=0;
end

78

Chapter 2: Clock Domain Crossing Rules

always @(*) //after empty flag activated fifo read counter should not
increment;
begin
if(r_en && (!f_empty_flag))
r_next_en=1;
else r_next_en=0;
end
always @(*) //after full flag activated fifo write counter should not
increment;
begin
if(w_en && (!f_full_flag))
w_next_en=1;
else w_next_en=0;
end
b_counter r_b_counter(.c_out(r_ptr),.c_reset(reset),. c_clk(r_clk),
.en(r_next_en));
b_counter w_b_counter(.c_out(w_ptr),.c_reset(reset),.c_clk(w_clk),
.en(w_next_en));
endmodule
module b_counter(c_out,c_reset,c_clk,en);
parameter c_width=4; //counter width
output [c_width-1:0] c_out; reg [c_width-1:0] c_out;
input c_reset,c_clk,en;
always @(posedge c_clk or posedge c_reset)
begin
if (c_reset)
c_out <= 0;
else if(en)
c_out <= c_out + 1;
end
endmodule

Set the following Tcl command for proper detection of a FIFO synchronizer.
set_cdc_synchronizer -name fifo_top -synchro_type fifo

The Leda command is:


leda -top fifo_top -config config.tcl -clock_file param.tcl test_fifo.v
+v2k

Select rule 'NTL_CDC01_5' in the config.tcl file.

79

Chapter 2: Clock Domain Crossing Rules

NTL_CDC01_6
Message: Handshake Synchronizer detected
Description

This rule is flagged when Leda detects a handshake synchronizer.

Policy

DESIGN

Ruleset

CDC

Language

VHDL/Verilog

Type

Hardware

Severity

Warning

Note

To run this rule, you must select the NTL_CDC01 rule in the configuration
file.

80

Chapter 2: Clock Domain Crossing Rules

Example
In the following figure, a 3-bit data path from clock domain of clk1 is fed to domain of
clk2 via a Handshake synchronizer. The Synchronizer uses two 2-FF synchronized
control signals (tx_valid and rx_done) to complete the handshake protocol. Leda
automatically detects this arrangement and CDC01_6 rule generates stability assertions
for control signal 'tx_valid', 'rx_done' and data path 'tx_data'.
tx_data

tx_valid

rx_sync2

Tx Side

Rx Side

(domain clk1)

(domain clk2)
tx_sync2

rx_done

module NTL_CDC01_6 (rst, clk1, clk2, din, dout);


output [2:0] dout;
input [2:0] din;
input clk1, clk2, rst;
wire tx_valid, rx_done;
wire [2:0] data;
reg rx_sync1, rx_sync2, tx_sync1, tx_sync2;
always @(posedge clk2) begin
rx_sync1 <= tx_valid;
rx_sync2 <= rx_sync1;
end
always @(posedge clk1) begin
tx_sync1 <= rx_done;
tx_sync2 <= tx_sync1;
end
tx tx(rst, clk1, din, tx_sync2, tx_valid, data);
rx rx(rst, clk2, rx_sync2, data, rx_done, dout);
endmodule

81

Chapter 2: Clock Domain Crossing Rules

module tx (rst, clk1, din, tx_done, tx_valid, tx_data);


input rst, clk1; input [2:0] din;
input tx_done;
output tx_valid;
reg tx_valid;
output [2:0] tx_data;
reg [2:0] tx_data;
always @(posedge clk1) begin
if (rst)
tx_data <= 0;
else begin
if (!tx_valid & !tx_done)
tx_data <= din;
else
tx_data <= tx_data;
end
end
always @(posedge clk1) begin
if (rst)
tx_valid <= 0;
else begin
if (!tx_done)
tx_valid <= 1;
else
tx_valid <= 0;
end
end
endmodule

module rx (rst, clk2, rx_valid, rx_data, rx_done, dout);


input rst, clk2;
input rx_valid;
input [2:0] rx_data;
output rx_done;
reg rx_done;
output [2:0] dout;
reg [2:0] dout;
always @(posedge clk2) begin
if (rst)
rx_done <= 0;
else
if (rx_valid)
rx_done <= 1;
else
rx_done <= 0;

82

Chapter 2: Clock Domain Crossing Rules

end
always @(posedge clk2) begin
if (rst)
dout <= 0;
else
if (rx_valid)
dout <= rx_data;
end
endmodule

83

Chapter 2: Clock Domain Crossing Rules

Violations
1: module NTL_CDC01_6 (rst, clk1, clk2, din, dout);
^
NTL_CDC01_6_fail.v:1: CDC> [WARNING] NTL_CDC01_6: Handshake Synchronizer
Detected NTL_CDC01_6_fail
../NTL_CDC01_6/NTL_CDC01_6_fail.v:4: :NTL_CDC01_6_fail_inst: Source
Clock: NTL_CDC01_6_fail.clk1
../NTL_CDC01_6/NTL_CDC01_6_fail.v:4: :NTL_CDC01_6_fail_inst: Target
Clock: NTL_CDC01_6_fail.clk2
../NTL_CDC01_6/NTL_CDC01_6_fail.v:49: :tx: Source Register:
NTL_CDC01_6_fail.tx.tx_valid
../NTL_CDC01_6/NTL_CDC01_6_fail.v:7: :NTL_CDC01_6_fail: Target
Register: NTL_CDC01_6_fail.rx_sync2
../NTL_CDC01_6/NTL_CDC01_6_fail.v:71: :rx: Source Register:
NTL_CDC01_6_fail.rx.rx_done
../NTL_CDC01_6/NTL_CDC01_6_fail.v:7: :NTL_CDC01_6_fail: Target
Register: NTL_CDC01_6_fail.tx_sync2
../NTL_CDC01_6/NTL_CDC01_6_fail.v:38: :tx: Source Register:
NTL_CDC01_6_fail.tx.tx_data(0)
../NTL_CDC01_6/NTL_CDC01_6_fail.v:79: :rx: Target Register:
NTL_CDC01_6_fail.rx.dout(0)
../NTL_CDC01_6/NTL_CDC01_6_fail.v:38: :tx: Source Register:
NTL_CDC01_6_fail.tx.tx_data(1)
../NTL_CDC01_6/NTL_CDC01_6_fail.v:79: :rx: Target Register:
NTL_CDC01_6_fail.rx.dout(1)
../NTL_CDC01_6/NTL_CDC01_6_fail.v:38: :tx: Source Register:
NTL_CDC01_6_fail.tx.tx_data(2)
../NTL_CDC01_6/NTL_CDC01_6_fail.v:79: :rx: Target Register:
NTL_CDC01_6_fail.rx.dout(2)

84

Chapter 2: Clock Domain Crossing Rules

NTL_CDC02
Message: Convergence found in clock domain crossing path
Description

Leda flags this rule when any signal in the cross over path has more
than one driver or any object in the cross over path has more than one
input. The rule parameters allow to control the kind of path on which
the rule must be applied. By default, this rule checks only control
paths because many synchronization techniques have convergence
on data paths. You can use the rule_set_parameter Tcl command to
configure the following parameters:
CHECK_CONTROL_PATHS You can configure this
parameter to check only control paths at clock domain crossings.
Leda checks control paths by default, as they are very critical.
The default value of this parameter is 1. For example:
leda> rule_set_parameter -rule NTL_CDC02
-parameter CHECK_CONTROL_PATHS -value {1}

CHECK_DATA_PATHS You can configure this parameter to


check only data paths at clock domain crossings. Since data paths
can have convergence point in some synchronizing method, Leda
doesnt check data paths by default. The default value of this
parameter is 0. For example:
leda> rule_set_parameter -rule NTL_CDC02
-parameter CHECK_DATA_PATHS -value {0}

Policy

DESIGN

Ruleset

CDC

Language

VHDL/Verilog

Type

Hardware

Severity

Warning

85

Chapter 2: Clock Domain Crossing Rules

Example
The following is the part of RTL example and the report that Leda generates for a multiinput gate convergence:
module cdc02 (data_out, data_in, cp_a, cp_b, data_ready, data_enable);
// parameter to define bus parameter
parameter DATA_BUS_WIDTH = 4'd4;
output [DATA_BUS_WIDTH : 0] data_out;
input [DATA_BUS_WIDTH : 0] data_in;
input cp_a, cp_b, data_ready, data_enable;
reg [DATA_BUS_WIDTH : 0] data_out;
reg [DATA_BUS_WIDTH : 0] q0_0;
reg ctrl_sample, ctrl1, ctrl2, switch_signal;
wire ctrl0;
wire [DATA_BUS_WIDTH : 0] data_sample;
// data path
always @(posedge cp_a) begin
q0_0 <= data_in;
end
assign data_sample = switch_signal ? q0_0 : data_out;
always @(posedge cp_b) begin
data_out <= data_sample;
end
// control path
always @(posedge cp_a) begin
ctrl_sample <= data_ready;
end
// insert combo here for cdc02 demo
assign ctrl0 = ctrl_sample & data_enable;
// synchronizer
always @(posedge cp_b) begin
ctrl1 <= ctrl0;
ctrl2 <= ctrl1;
switch_signal <= ctrl2;
end
endmodule

86

Chapter 2: Clock Domain Crossing Rules

//Case schematic:

Configuration File
rule_deselect -all
rule_select -rule NTL_CDC02
rule_set_parameter -rule NTL_CDC02 -parameter CHECK_CONTROL_PATHS -value
{1}
rule_set_parameter -rule NTL_CDC02 -parameter CHECK_DATA_PATHS -value
{0}

Violations
25: assign ctrl0 = ctrl_sample & data_enable;
^
NTL_CDC02.v:25: CDC> [WARNING] NTL_CDC02: Convergence found in clock
domain crossing path cdc02.&CAS2.~band0
--- Source register: cdc02.ctrl_sample (file: NTL_CDC02.v, line: 9)
--- Source register clock: cdc02.cp_a (file: NTL_CDC02.v, line: 6)
--- Target register: cdc02.ctrl1 (file: NTL_CDC02.v, line: 9)
--- Target register clock: cdc02.cp_b (file: NTL_CDC02.v, line: 6)
--- Convergent Point Location: cdc02.&CAS2.~band0 (file:
NTL_CDC02.v, line: 25)

87

Chapter 2: Clock Domain Crossing Rules

Schematic

88

Chapter 2: Clock Domain Crossing Rules

NTL_CDC03
Message: Divergence found in clock domain crossing path
Description

Leda flags this rule when any signal in the cross over path has more
than one fanout or any object in the cross over path has more than
one output. The rule parameters allow to control the kind of path on
which the rule must be applied. By default, this rule checks both
control path and data path. You can use the rule_set_parameter Tcl
command to configure the following parameters:
CHECK_CONTROL_PATHS You can configure this
parameter to check only control paths at clock domain crossings.
Leda checks control paths by default, as they are very critical.
The default value of this parameter is 1. For example:
leda> rule_set_parameter -rule NTL_CDC03
-parameter CHECK_CONTROL_PATHS -value {1}

CHECK_DATA_PATHS You can configure this parameter to


check data paths at clock domain crossings. The default value of
this parameter is 1. For example:
leda> rule_set_parameter -rule NTL_CDC03
-parameter CHECK_DATA_PATHS -value {1}

Policy

DESIGN

Ruleset

CDC

Language

VHDL/Verilog

Type

Hardware

Severity

Warning

89

Chapter 2: Clock Domain Crossing Rules

Example
Here is the part of RTL example and the report that Leda generates for a multi fanout
divergence:
module cdc03 (data_out, data_in, cp_a, cp_b, data_ready, ctrl_probe);
// parameter to define bus parameter
parameter DATA_BUS_WIDTH = 4'd1;
output [DATA_BUS_WIDTH : 0] data_out;
output ctrl_probe;
input [DATA_BUS_WIDTH : 0] data_in;
input cp_a, cp_b, data_ready;
reg [DATA_BUS_WIDTH : 0] data_out;
reg [DATA_BUS_WIDTH : 0] q0_0;
reg ctrl_sample, ctrl1, ctrl2, switch_signal;
wire ctrl0;
wire [DATA_BUS_WIDTH : 0] data_sample;
// data path
always @(posedge cp_a) begin
q0_0 <= data_in;
end
assign data_sample = switch_signal ? q0_0 : data_out;
always @(posedge cp_b) begin
data_out <= data_sample;
end
// control path
always @(posedge cp_a) begin
ctrl_sample <= data_ready;
end
assign ctrl0 = ~ ctrl_sample;
assign ctrl_probe = ~ctrl0;
// synchronizer
always @(posedge cp_b) begin
ctrl1 <= ctrl0;
ctrl2 <= ctrl1;
switch_signal <= ctrl2;
end
endmodule

90

Chapter 2: Clock Domain Crossing Rules

Case Schematic

// Configuration File:
rule_deselect -all
rule_select -rule NTL_CDC03
rule_set_parameter -rule NTL_CDC03 -parameter CHECK_CONTROL_PATHS -value
{1}
rule_set_parameter -rule NTL_CDC03 -parameter CHECK_DATA_PATHS -value
{1}

Violations
11: wire ctrl0;
^
NTL_CDC03.v:11: CDC> [WARNING] NTL_CDC03: Divergence found in clock
domain crossing path cdc03.ctrl0
--- Source register: cdc03.ctrl_sample (file: NTL_CDC03.v, line: 10)
--- Source register clock: cdc03.cp_a (file: NTL_CDC03.v, line: 7)
--- Target register: cdc03.ctrl1 (file: NTL_CDC03.v, line: 10)
--- Target register clock: cdc03.cp_b (file: NTL_CDC03.v, line: 7)

91

Chapter 2: Clock Domain Crossing Rules

Schematic

92

Chapter 2: Clock Domain Crossing Rules

NTL_CDC04
Message: Divergence of meta-stable signal detected
Description

Leda flags this rule when any meta-stable signal (output signal of the
first flip-flop encountered in the target clock domain) has more than
one fanout. This rule verify only for 2 Flip-Flop synchronized
signals. This rule is not valid for data signals in the case of DMUX,
AND, handshake and FIFO synchronizers. The rule parameters allow
to control the kind of path on which the rule should be applied. This
rule checks both control path and data path.

Policy

DESIGN

Ruleset

CDC

Language

VHDL/Verilog

Type

Hardware

Severity

Warning

Example
Here is the example and the report that Leda generates:
module cdc04 (rst, clk1, clk2, clk3, din, pout,dout);
input clk1;
input clk2;
input clk3;
input rst;
input din;
output dout;
output pout;
reg dout;
reg d_reg0;
reg d_reg1;
reg d_reg2;
always @(posedge clk1 or negedge rst) begin
if (~rst)
d_reg0 <= 1'b0;
else
d_reg0 <= din;
end

93

Chapter 2: Clock Domain Crossing Rules

always @(posedge clk2 or negedge rst) begin


if (~rst) begin
d_reg1 <= 1'b0;
d_reg2 <= 1'b0;
end
else begin
d_reg1 <= d_reg0;
d_reg2 <= d_reg1;
end
end
assign pout = d_reg1;
always @(posedge clk2 or negedge rst)
begin
if(~rst)
dout <= 1'b0;
else
dout <= d_reg2;
end
endmodule

Violations
11: reg d_reg1;
^
NTL_CDC04.v:11: CDC> [WARNING] NTL_CDC04: Divergence of meta-stable
signal detected cdc04.d_reg1
--- Source register: cdc04.d_reg0 (file: NTL_CDC04.v, line: 10)
--- Source register clock: cdc04.clk1 (file: NTL_CDC04.v, line: 2)
--- Target register: cdc04.d_reg1 (file: NTL_CDC04.v, line: 11)
--- Target register clock: cdc04.clk2 (file: NTL_CDC04.v, line: 3)
--- Divergence fanout: cdc04.&AS2.~ff0 (file: NTL_CDC04.v, line: 28)
--- Divergence fanout: cdc04.&CAS1.~tie0(file: NTL_CDC04.v, line:32)

94

Chapter 2: Clock Domain Crossing Rules

Schematic

95

Chapter 2: Clock Domain Crossing Rules

NTL_CDC05
Message: Convergence between signals coming from
different synchronizers
Description

Leda flags this rule if more than one synchronizer is found between
clock domains.Those signals that are not synchronized by the same
synchronizer should never converge in the target clock domain. You
can use the rule_set_parameter Tcl command to configure the
following parameters:
CHECK_CONTROL_PATHS You can configure this
parameter to check only control paths at clock domain crossings.
Leda checks control paths by default, as they are very critical.
The default value of this parameter is 1. For example:
leda> rule_set_parameter -rule NTL_CDC05
-parameter CHECK_CONTROL_PATHS -value {1}

CHECK_DATA_PATHS You can configure this parameter to


check only data paths at clock domain crossings. The default
value of this parameter is 1. For example:
leda> rule_set_parameter -rule NTL_CDC05
-parameter CHECK_DATA_PATHS -value {1}

Policy

DESIGN

Ruleset

CDC

Language

VHDL/Verilog

Type

Hardware

Severity

Fatal

96

Chapter 2: Clock Domain Crossing Rules

Example
Here is the part of RTL example and the report that Leda generates:
Independent synchronized signals (by different synchronizers) should not
re-converge.
//- Test case for NTL_CDC05: two independent control signals re-converge
after synchronization

module cdc05 (S1,S2,CLK1,CLK2,CLK3,D_OUT);


input S1,S2,CLK1,CLK2,CLK3;
output D_OUT;
wire converted_sig;
reg tmp1, tmp2, tmp11, tmp22, D_OUT, tmp111, tmp222, D_OUT1, tmp1111,
tmp2222;
always@(posedge CLK1) begin
tmp1 <= S1;
tmp2 <= S2;
end
always@(posedge CLK2) begin
tmp11 <= tmp1;
tmp111 <= tmp11; //- 2 FF Synchronizer
end
always@(posedge CLK3) begin
tmp22 <= tmp2;
tmp222 <= tmp22; //- 2 FF Synchronizer
end
assign converted_sig = tmp111 & tmp222;
always@(posedge CLK2) begin
D_OUT <= converted_sig;
end
endmodule

97

Chapter 2: Clock Domain Crossing Rules

Violations
4: wire converted_sig;
^
NTL_CDC05.v:4: CDC> [FATAL] NTL_CDC05: Convergence between signals
coming from different synchronizers cdc05.converted_sig
--- First source register : cdc05.tmp111 (file: NTL_CDC05.v, line: 5)
--- First source clock : cdc05.CLK1 (file: NTL_CDC05.v, line: 2)
--- First target clock : cdc05.CLK2 (file: NTL_CDC05.v, line: 2)
--- Second source register : cdc05.tmp222 (file: NTL_CDC05.v, line: 5)
--- Second source clock : cdc05.CLK1 (file: NTL_CDC05.v, line: 2)
--- Second target clock : cdc05.CLK3 (file: NTL_CDC05.v, line: 2)
--- Convergence point after 0 Sequential levels : cdc05.converted_sig
(file: NTL_CDC05.v, line: 4)

Schematic

98

Chapter 2: Clock Domain Crossing Rules

NTL_CDC06
Message: CDC control signal must be stable enough
(property generated)
Description

This rule is flagged if there is a flip-flop synchronizer in the CDC


path. A CDC control signal must be stable enough for the flip-flop
synchronizer (value must be stable for at least N target clock cycles,
where N, being the number of flip-flops used for synchronizers).
Leda alone cannot check this rule but displays an error message in
the Leda error viewer and a property (assertion) is generated for
simulation or formal verification.

Policy

DESIGN

Ruleset

CDC

Language

VHDL/Verilog

Type

Hardware

Severity

Warning

99

Chapter 2: Clock Domain Crossing Rules

Example
Here is the part of RTL example and the report that Leda generates:
module cdc06 (cp_a, cp_b, data_ready, rst, switch_signal);
input cp_a, cp_b, data_ready, rst;
output switch_signal;
reg ctrl_sample, ctrl1, ctrl2, switch_signal;
// The following always block models the input for the CDC path
always @(posedge cp_a) begin
if (!rst)
begin
ctrl_sample <= 1'b0;
end
else begin
ctrl_sample <= data_ready;
end
end
// 3 FF synchronizer
always @(posedge cp_b) begin
if (!rst)
begin
ctrl1 <= 1'b0;
ctrl2 <= 1'b0;
switch_signal <= 1'b0;
end
else
begin
ctrl1 <= ctrl_sample;
ctrl2 <= ctrl1;
switch_signal <= ctrl2;
end
end
endmodule

Configuration File
rule_deselect -all
rule_select -rule NTL_CDC06

100

Chapter 2: Clock Domain Crossing Rules

Violations
29:

ctrl1 <= ctrl_sample;


^
NTL_CDC06.v:29: CDC> [WARNING] NTL_CDC06: CDC control signal must be
stable enough (property generated) cdc06.ctrl1
--- Source Register: cdc06.ctrl_sample (file: NTL_CDC06.v, line: 15)
--- Target Register: cdc06.ctrl1 (file: NTL_CDC06.v, line: 29)

Schematic

101

Chapter 2: Clock Domain Crossing Rules

Generated assertion files


leda_top_properties.v
bind cdc06 sync_signal_stablility_sva_assertion
#(2)
i_NTL_CDC06_1
(cdc06.cp_b, cdc06.ctrl1, !cdc06.rst);

aep_signal_stability.v
module sync_signal_stablility_sva_assertion (dclk, din, rst);
parameter NFF=2; //- Number of FFs in the FF synchronizer
parameter WIDTH=1; //- Width of the CDC control signal
input dclk; //- Clk of the Destination domain
input [WIDTH-1:0] din; //- CDC control signal
input rst; //- Reset

CDC_CSS: assert property (


disable iff (rst)
@(posedge dclk) ##1 !$stable(din) |=> $stable(din)[*NFF]);
endmodule

102

Chapter 2: Clock Domain Crossing Rules

NTL_CDC07
Message: Reconverging control path detected
Description

This rule is flagged if the control signals of a given synchronizer


reconverges. For CDC paths that have a common source in a given
synchronization scheme, this rule checks if the paths are
reconverging and flag reconvergence. This is equivalent to the gray
coding rule, but can be checked statically (since the control paths are
reconvergent, they cannot be gray coded).

Policy

DESIGN

Ruleset

CDC

Language

VHDL/Verilog

Type

Hardware

Severity

Fatal

Example
Synchronized signals coming from the same source should not re-converge. Same
control signal has improper fan-out to multiple synchronizers.
module cdc07 (S1,S2,CLK1,CLK2,D_OUT);
input S1,S2,CLK1,CLK2; output D_OUT;
wire converted_sig;
reg tmp1,tmp11,tmp22,D_OUT,tmp111,tmp222,D_OUT1;
always@(posedge CLK1) begin
tmp1 <= S1;
end
always@(posedge CLK2) begin
tmp11 <= tmp1;
tmp111 <= tmp11;
tmp22 <= tmp1;
tmp222 <= tmp22;
end
assign converted_sig = tmp111 & tmp222;
always@(posedge CLK2) begin
D_OUT <= converted_sig;
end
endmodule

103

Chapter 2: Clock Domain Crossing Rules

Violations
3: wire converted_sig;
^
NTL_CDC07.v:3: CDC> [FATAL] NTL_CDC07: Reconverging control path
detected cdc07.converted_sig
--- First path from : cdc07.S1 (file: NTL_CDC07.v, line: 2)
--- to : cdc07.tmp111 (file: NTL_CDC07.v, line: 4)
--- Second path from : cdc07.S1 (file: NTL_CDC07.v, line: 2)
--- to : cdc07.tmp222 (file: NTL_CDC07.v, line: 4)
--- Convergence point: cdc07.converted_sig (file: NTL_CDC07.v, line: 3)

Schematic

104

Chapter 2: Clock Domain Crossing Rules

Detailed Explanations for Rules NTL_CDC05 and


NTL_CDC07
Both of these rules check a common CDC scenario - called the "re-convergence of
synchronized signals".
Loss of correlation can also occur when two apparently independent signals are
synchronized separately, but ultimately fed into the same logic. This scenario,
sometimes dubbed re-convergence, is especially difficult to detect by manual inspection
of the synchronization schemes during design review.
Another form of correlation loss can occur when a signal has fan-outs into multiple
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.

105

Chapter 2: Clock Domain Crossing Rules

NTL_CDC08
Message: Multiple CDC control signals must be gray coded,
property generated
Description

When more than one control signal passes clock domains and
converge on a common logic, these signals become candidate to be
gray coded (to avoid that two control signals change at the same
time). The rule serves two purposes. The first purpose is to inform
the user through error message to take care of the reconvergent
scenario for the multiple control signals.
The second purpose is to generate assertion for gray coding
requirement on control signals which are part of the same vector.

Policy

DESIGN

Ruleset

CDC

Language

VHDL/Verilog

Type

Hardware

Severity

Warning

106

Chapter 2: Clock Domain Crossing Rules

Example
Here is an example assertion file generated by Leda for this rule:
module cdc08 (in1, in2, clk1, clk2, out2,out3, sel);
input clk1, clk2, sel;
input [2:0] in1, in2;
output out2, out3;
reg [2:0] out1, first, src;
reg out2, out3;
wire temp, temp_2;
reg [2:0] tmp1, tmp11, tmp2, tmp22;
always @(posedge clk1)
src <= in1;
always @(posedge clk2) begin
first <= src;
out1 <= first;
tmp1 <= src;
tmp11 <= tmp1;
tmp2 <= src;
tmp22 <= tmp2;
end
assign temp = out1[0] & out1[1] & out1[2];
assign temp_2 = tmp11 & tmp22;
always @(posedge clk2)
out2 <= temp;
always @(posedge clk2)
out3 <= temp_2;
endmodule

107

Chapter 2: Clock Domain Crossing Rules

Violations
5: reg [2:0] out1, first, src;
^
NTL_CDC08.v:5: CDC> [WARNING] NTL_CDC08: Multiple CDC control signals
must be gray coded, property generated cdc08.src(0)
--- From clock : cdc08.clk1 (file: NTL_CDC08.v, line: 2)
--- To clock : cdc08.clk2 (file: NTL_CDC08.v, line: 2)
--- signal : cdc08.src(0) (file: NTL_CDC08.v, line: 5)
--- signal : cdc08.src(1) (file: NTL_CDC08.v, line: 5)
--- signal : cdc08.src(2) (file: NTL_CDC08.v, line: 5)
--cdc08 (file: NTL_CDC08.v, line: 1)

The general format of the assertion is as follows:


bind MODULE_NAME aep_assert_gray_coding
#( WIDTH_OF_CONTROL_SIGNAL,"Multi bit control signals must be gray
coded"
) {NTL_CDC08}_{INSTANCE_LOCATION_OF_CONTROL_SIGNAL}
( SOURCE_CLOCK_SIGNAL_NAME, RESET_SIGNAL_NAME,
{CONTROL_SIGNAL_NAME,CONTROL_SIGNAL_NAME});

where,
MODULE_NAME - Name of the module to bind for the assertion;
WIDTH_OF_CONTROL_SIGNAL - Size of the multi-bit control signal;
INSTANCE_LOCATION_OF_CONTROL_SIGNAL - Instance name and location
to be used for the binding (normally LABEL_filename_line);
SOURCE_CLOCK_SIGNAL_NAME - Name of the clock to be used for gray code
assertion;
RESET_SIGNAL_NAME - Name of the reset signal (value should be '0' if no reset
is present);
CONTROL_SIGNAL_NAME - Name of the control signal (can be an expression
concatenating all the source signals);

108

Chapter 2: Clock Domain Crossing Rules

Generated assertion files


leda_top_properties.v
bind cdc08 aep_assert_gray_coding
#( 3,"Multi bit control signals must be gray coded")
i_NTL_CDC08_1
( cdc08.clk1, 1'b0, cdc08.src[2:0]);

aep_assert_gray_coding.v

module aep_assert_gray_coding (clk, rst, data_in);


parameter WIDTH = 1; //- Width of the gray coded vector
parameter MSG = " "; //- Assertion failure message

input clk, rst; //- Clock and Reset Signals


input [WIDTH-1:0] data_in; //- Gray coded vector
//- Property that checks whether the vector 'data_in' is gray coded
//- Before $onehot0(), ##1 is given to take care of the first cycle
property gray_code_a;
disable iff (rst)
@(posedge clk) ##1 $onehot0($past(data_in)^data_in);
endproperty
gray_code : assert property (gray_code_a);
endmodule

109

Chapter 2: Clock Domain Crossing Rules

Difference between rules NTL_CDC07 and NTL_CDC08 :


The rule NTL_CDC08 informs the user of any multi-bit control signal that crosses from
one clock domain to another without being Gray coded.
It is critical that all of the bits in a multi-bit signal remain aligned when crossing a clock
domain boundary; a Gray code changes only one bit at a time so that it is easy to tell
when the bits have fallen out of alignment.
The checking of alignment differs the way NTL_CDC07 and NTL_CDC08 behaves.
If multi-bit signals which are not part of a vector cross clock domains, got FF
synchronized and re-converge in the destination domain, NTL_CDC07 fires. If these
signals are part of a vector NTL_CDC08 fires.
The following example demonstrates this fact.
The vector out1 is crossing domains, synchronized by 2-FFs and re-converge. We have
NTL_CDC08 in this case.
The two signals (independent) tmp1 and tmp2 are crossing domains, synchronized by
2FFs and re-converging, we have NTL_CDC07.
module NTL_CDC07_08(in1, in2, clk1, clk2, out2,out3, sel);
input clk1, clk2, sel;
input [2:0] in1, in2;
output out2, out3;
reg [2:0] out1, first, src;
reg out2, out3;
wire temp, temp_2;
reg [2:0] tmp1, tmp11, tmp2, tmp22;
always @(posedge clk1)
src <= in1;
always @(posedge clk2) begin
first <= src;
out1 <= first;
tmp1 <= src;
tmp11 <= tmp1;
tmp2 <= src;
tmp22 <= tmp2;
end

110

Chapter 2: Clock Domain Crossing Rules

assign temp = out1[0] & out1[1] & out1[2];


assign temp_2 = tmp11 & tmp22;
always @(posedge clk2)
out2 <= temp;
always @(posedge clk2)
out3 <= temp_2;
endmodule

Violations
11: wire temp, temp_2;
^
my_test.v:11: CDC> [FATAL] NTL_CDC07: Reconverging control path detected
NTL_CDC07_08.temp_2
--- First path from : NTL_CDC07_08.in1(0) (file: my_test.v, line:6)
--- to : test.tmp11(0) (file: my_test.v, line: 12)
--- Second path from : NTL_CDC07_08.in1(0) (file: my_test.v, line:6)
--- to : test.tmp22(0) (file: my_test.v, line: 12)
--- Convergence point:NTL_CDC07_08.temp_2 (file: my_test.v, line:11)
9: reg [2:0] out1, first, src;
^
my_test.v:9: CDC> [WARNING] NTL_CDC08: Multiple CDC control signals must
be gray coded, property generated NTL_CDC07_08.src(0)
--- From clock : NTL_CDC07_08.clk1 (file: my_test.v, line: 5)
--- To clock : NTL_CDC07_08.clk2 (file: my_test.v, line: 5)
--- signal : NTL_CDC07_08.src(0) (file: my_test.v, line: 9)
--- signal : NTL_CDC07_08.src(1) (file: my_test.v, line: 9)
--- signal : NTL_CDC07_08.src(2) (file: my_test.v, line: 9)
--- NTL_CDC07_08 (file: my_test.v, line: 4)

111

Chapter 2: Clock Domain Crossing Rules

NTL_CDC09
Message: CDC control signal must not be part of a BUS
Description

A signal from the source clock (sclk) domain is moving to the


receiving clock (dclk) domain and is connected to a BUS signal in its
way. Fig 21 shows one example. The test case gives a set of
examples.
The following is the rule parameter for this rule:
"SHOW_ONLY_CONTROL_PATHS".
By default, the rule flags on every CDC path (synched and unsynched). But once the parameter is set, it will show only the
synchronized paths (not the un-synched data paths).
rule_set_parameter -rule NTL_CDC09 -parameter
SHOW_ONLY_CONTROL_PATHS -value 1

Policy

DESIGN

Ruleset

CDC

Language

VHDL/Verilog

Type

Hardware

Severity

Warning

The rule NTL_CDC09 fires violations on any type of CDC signal, which is connected to
a BUS signal somewhere in its path (from source register to target register).
Figure 21: The Bus 'sig' is crossing domain
NTL_CDC09 fires on sig

sig

in

112

dout

din

Src
sclk

There can be any


combinational logic

Dst
dclk

Chapter 2: Clock Domain Crossing Rules

Figure 22: The single bit signal 'sig' is crossing domain


sig

in

NTL_CDC09 does not fire on sig

Src
sclk

dout

din

Dst
dclk

113

Chapter 2: Clock Domain Crossing Rules

Example
//- Leda should detect the violations on line 21, 23, 25, 29, 39, 41.
module cdc09 (clk1,clk2, d,q ) ;
input clk1,clk2;
input [4:0] d ;
output [4:0] q ;
wire w1,w2,w3,w4 ;
reg r1,r2,r3,r4,r5,r6,r7,r8;
reg [1:0] rb1,rb2,rb3 ,rb4,rb5,rb6;
assign w1 = d[0] ;
always @(posedge clk1)
r1 <= w1 ;
always @(negedge clk2 )
r2 <= r1 ;
always @(posedge clk2 )
r3 <= r2 ;
assign q[0] = r3 ;
always @(posedge clk1)
rb1 <= d[2:1] ;
always @(posedge clk2 )
rb2 <= rb1 ;
always @(posedge clk2 )
rb3 <= rb2 ;
assign q[2:1] = rb3 ;
always @(posedge clk1)
r4 <= d[3] ;
always @(posedge clk2 )
r5 <= r4 ;
always @(posedge clk2 )
r6 <= r5 ;
assign q[3] = r6 ;
assign w2 = d[4] ;
always @(posedge clk1)
rb4[0] <= w2 ;
always @(posedge clk2 )
r7 <= rb4[0] ;
always @(posedge clk2 )
r8 <= r7 ;
assign q[4] = r8 ;
endmodule

114

Chapter 2: Clock Domain Crossing Rules

Violations
17: rb1 <= d[2:1] ;
^
NTL_CDC09.v:17: CDC> [WARNING] NTL_CDC09: CDC control signal
part of a BUS cdc09.rb1(0)
--- Bus connection point: cdc09.rb1(0) (file: NTL_CDC09.v,
--- Bus connection point: cdc09.rb2(0) (file: NTL_CDC09.v,
--- Bus connection point: cdc09.rb3(0) (file: NTL_CDC09.v,
17: rb1 <= d[2:1] ;
^
NTL_CDC09.v:17: CDC> [WARNING] NTL_CDC09: CDC control signal
part of a BUS cdc09.rb1(1)
--- Bus connection point: cdc09.rb1(1) (file: NTL_CDC09.v,
--- Bus connection point: cdc09.rb2(1) (file: NTL_CDC09.v,
--- Bus connection point: cdc09.rb3(1) (file: NTL_CDC09.v,

must not be
line: 17)
line: 19)
line: 21)

must not be
line: 17)
line: 19)
line: 21)

24: r4 <= d[3] ;


^
NTL_CDC09.v:24: CDC> [WARNING] NTL_CDC09: CDC control signal must not be
part of a BUS cdc09.r4
--- Bus connection point: cdc09.r4 (file: NTL_CDC09.v, line: 24)
32: rb4[0] <= w2 ;
^
NTL_CDC09.v:32: CDC> [WARNING] NTL_CDC09: CDC control signal must not be
part of a BUS cdc09.rb4(0)
--- Bus connection point: cdc09.rb4(0) (file: NTL_CDC09.v, line: 32)
--- Bus connection point: cdc09.r7 (file: NTL_CDC09.v, line: 34)

115

Chapter 2: Clock Domain Crossing Rules

NTL_CDC10
Message: Different clock polarity FFs in the simple
synchronizer
Description

Leda flags this rule when a single-bit signal is synchronized with a 2


flip-flop synchronizer in which the clock polarity of the first and
second flip-flop is different.
A simple 2-FF synchronizer having opposite clock pin polarity
synchronizing FFs, may lead to meta-stability issues. The second
synchronizing flip-flop may not get enough time to sample the metastable signal (output of the first synchronizing FF) because of the
opposite polarity. Therefore the 2-FF synchronizer may fail to
remove meta-stability in the receive clock domain.

Policy

DESIGN

Ruleset

CDC

Language

VHDL/Verilog

Type

Hardware

Severity

Warning

Example
In the following figure, the data in vector data_in starts from clock domain cp_a and
propagates to clock domain cp_b. This forms a clock domain crossing (CDC) path.
However, this CDC path is synchronized by a MUX synchronizer, which uses the
control signal switch_signal synchronized by a 2-FF synchronizer. The 2-FF
synchronizer consists of 2 FFs of opposite polarity clock pin (flip-flop FF1 and FF2).

116

Chapter 2: Clock Domain Crossing Rules

The following example illustrates this rule:


module cdc10 (data_out, data_in, cp_a, cp_b, data_ready);
// parameter to define bus parameter
parameter DATA_BUS_WIDTH = 1;
output [DATA_BUS_WIDTH : 0] data_out;
input [DATA_BUS_WIDTH : 0] data_in;
input cp_a, cp_b, data_ready;
reg [DATA_BUS_WIDTH : 0] data_out, q0_0;
reg ctrl_sample, ctrl1, ctrl2, switch_signal;
wire [DATA_BUS_WIDTH : 0] data_sample;
assign data_sample = switch_signal ? q0_0 : data_out;
// data path
always @(posedge cp_a)
q0_0 <= data_in;
always @(posedge cp_b)
data_out <= data_sample;
// control path
always @(posedge cp_a)
ctrl_sample <= data_ready;
// synchronizer (1st FF)
always @(negedge cp_b) // 2nd FF
ctrl1 <= ctrl_sample;
end
always @(posedge cp_b) begin
ctrl2 <= ctrl1;
switch_signal <= ctrl2;
end endmodule

117

Chapter 2: Clock Domain Crossing Rules

Violations
18:

ctrl1 <= ctrl_sample;


^
NTL_CDC10.v:18: CDC> [WARNING] NTL_CDC10: Different Clock Polarity FFs
in a Simple Synchronizer cdc10.ctrl1
--- The First FF has Negative Polarity Clock Pin: cdc10.ctrl1
(file: NTL_CDC10.v, line: 18)
--- The FF has Positive Polarity Clock Pin: cdc10.ctrl2 (file:
NTL_CDC10.v, line: 8)
--- CDC Info: Target clock domain (that includes the 2-FF
synchronizer) is: cdc10.cp_b (file: NTL_CDC10.v, line: 6)
--- CDC Path Info: The FF (Initiating the CDC Path):
cdc10.ctrl_sample (file: NTL_CDC10.v, line: 15)
--- CDC Info: Source clock domain is: cdc10.cp_a (file:
NTL_CDC10.v, line: 6)

Schematic

118

Chapter 2: Clock Domain Crossing Rules

NTL_CDC11
Message: One of the FFs in a 2-FF simple synchronizer has a
gated clock (single-bit CDC signal)
Description

Leda flags this rule when a single-bit signal is synchronized by a 2FF synchronizer, in which only one of the synchronizing flip-flop has
a gated clock. A gated clock is a signal on a clock path which is an
output of a combinatorial block. A gated clock may disrupt the
synchronization process.

Policy

DESIGN

Ruleset

CDC

Language

VHDL/Verilog

Type

Hardware

Severity

Warning

119

Chapter 2: Clock Domain Crossing Rules

Example
The following example illustrates this rule:
module cdc11 (data_out, data_in, cp_a, cp_b, data_ready, den);
// parameter to define bus parameter
parameter DATA_BUS_WIDTH = 4'd4;
output [DATA_BUS_WIDTH : 0] data_out;
input [DATA_BUS_WIDTH : 0] data_in;
input cp_a, cp_b, den, data_ready;
reg [DATA_BUS_WIDTH : 0] data_out, q0_0;
reg ctrl_sample, ctrl1, ctrl2, switch_signal;
wire [DATA_BUS_WIDTH : 0] data_sample;
wire cp_b2;
assign data_sample = switch_signal ? q0_0 : data_out;
// data path
always @(posedge cp_a)
q0_0 <= data_in;
always @(posedge cp_b)
data_out <= data_sample;
// control path
always @(posedge cp_a)
ctrl_sample <= data_ready;
//- Gated Clk
assign cp_b2 = cp_b & den;
// synchronizer (1st FF)
always @(posedge cp_b2)
ctrl1 <= ctrl_sample;
//- Synchronizer (rest)
always @(posedge cp_b) begin
ctrl2 <= ctrl1;
switch_signal <= ctrl2;
end
endmodule

120

Chapter 2: Clock Domain Crossing Rules

Dat a_sam
pl e
Dat a_I n

Q0_0

Dat a_out

C
p_a
SwI t ch_sI gnal

Dat a_r eady

C
trl1

C
trl_sam
ple
F
F
1

C
trl2
F
F
2

D
en

C
p_b

Violations
20: always @(posedge cp_b2) begin ctrl1 <= ctrl_sample; end
^
NTL_CDC11.v:20: CDC> [WARNING] NTL_CDC11: A single bit CDC signal is
synchronized by a FF synchronizer where one of the synchronizing FF (in
that FF synchronizer) has a Gated Clock cdc11.ctrl1
--- Affected synchronizing FF is : cdc11.ctrl1 (file: NTL_CDC11.v,
line: 20)
--- Affected Gated Clock Pin is : cdc11.cp_b2 (file: NTL_CDC11.v,
line: 10)
--- Driver for the affected gated clock pin : cdc11.&CAS2.~band0
(file: NTL_CDC11.v, line: 18)

Schematic

121

Chapter 2: Clock Domain Crossing Rules

NTL_CDC12
Message: A vector is synchronized by a set of 2-FF simple
synchronizers where one of the 2-FF synchronizers has a
gated clock FF
Description

Leda flags this rule when a multi-bit signal (e.g.: data bus) is
synchronized by a 2-FF synchronizer, in which only one of the
synchronizing flip-flop has a gated clock. A gated clock is a signal on
a clock path which is an output of a combinatorial block. A gated
clock may disrupt the synchronization process.
A separate 2-FF synchronizer synchronizes every bit of the vector.
This type of synchronization is seen in FIFO synchronizer where the
write and read pointers (multi-bit) are synchronized by 2-FF
synchronizers.

Policy

DESIGN

Ruleset

CDC

Language

VHDL/Verilog

Type

Hardware

Severity

Warning

Example
The following example illustrates this rule:
module cdc12 (data_out, data_in, cp_a, cp_b, data_ready, den);
// parameter to define bus parameter
parameter DATA_BUS_WIDTH = 4'd4;
output [DATA_BUS_WIDTH : 0] data_out;
input [DATA_BUS_WIDTH : 0] data_in;
input cp_a, cp_b, den; input [1:0] data_ready;
reg [DATA_BUS_WIDTH : 0] data_out, q0_0;
reg [1:0] ctrl_sample, ctrl1, ctrl2, switch_signal;
wire [DATA_BUS_WIDTH : 0] data_sample;
wire cp_b2;
assign data_sample = (|switch_signal) ? q0_0 : data_out;
// data path
always @(posedge cp_a)
q0_0 <= data_in;

122

Chapter 2: Clock Domain Crossing Rules

always @(posedge cp_b)


data_out <= data_sample;
// control path
always @(posedge cp_a)
ctrl_sample <= data_ready;
//- Gated Clk
assign cp_b2 = cp_b & den;
// synchronizers (1st FF)
always @(posedge cp_b)
ctrl1 <= ctrl_sample;
//- Synchronizers (rest)
always @(posedge cp_b2) begin
ctrl2 <= ctrl1;
switch_signal <= ctrl2;
end
endmodule

Violations
8: reg [1:0] ctrl_sample, ctrl1, ctrl2, switch_signal;
^
NTL_CDC12.v:8: CDC> [WARNING] NTL_CDC12: A CDC vector signal is being
synched by a set of FF synchronizers where at least one of the FF
synchronizers has a synchronizing FF with a gated clock cdc12.ctrl2(0)
--- Affected synchronizing FF is : cdc12.ctrl2(0) (file:
NTL_CDC12.v, line: 8)
--- Affected Gated Clock Pin is : cdc12.cp_b2 (file: NTL_CDC12.v,
line: 10)
--- Driver for the affected gated clock pin : cdc12.&CAS2.~band0
(file: NTL_CDC12.v, line: 18)
--- (NTL_CDC12)
cdc12.ctrl2(1) (file: NTL_CDC12.v, line: 8)
--- Affected synchronizing FF is : cdc12.ctrl2(1) (file:
NTL_CDC12.v, line: 8)
--- Affected Gated Clock Pin is : cdc12.cp_b2 (file: NTL_CDC12.v,
line: 10)
--- Driver for the affected gated clock pin : cdc12.&CAS2.~band0
(file: NTL_CDC12.v, line: 18)

123

Chapter 2: Clock Domain Crossing Rules

Schematic

124

Chapter 2: Clock Domain Crossing Rules

NTL_CDC13
Message: There exists an unscented control path driven by a
CDC asynchronous reset signal
Description

Leda flags this rule when a register having an asynchronous reset


signal is driven by a signal from a different clock domain creates
another CDC path.
A 1-bit signal from the source clock domain is fed to the
asynchronous reset port of a register in the receiving clock domain.
The output of the receiving register does not drive a control signal
synchronizer before driving a register in another clock domain. This
missing synchronizer is the issue.

Policy

DESIGN

Ruleset

CDC

Language

VHDL/Verilog

Type

Hardware (For Netlist)

Severity

Warning

Example
In the following figure, a 1-bit signal from clock domain (cubic) is fed to the
asynchronous reset pin of register ctrl_1 of clock domain cp_a. The output of ctrl_1
is directly fed to another register ctrl_sample of clock domain cp_b. However,
ctrl_sample is not synchronized (synchronizer is missing), thus it forms a CDC path.

st
11
aa
rr
s
t_
_

ct
rl_
1
ct
r
_
1

ctrl_
sam
p
lle
c
tr
_
sa
m
p
le

cp_b

cp_c
cp_a

125

Chapter 2: Clock Domain Crossing Rules

The following example illustrates this rule:


module CDC13_01 (in_1, in_2, cp_a, cp_b, cp_c, ctrl_sample);
output ctrl_sample;
input cp_a, cp_b, cp_c, in_1, in_2;
reg ctrl_sample;
reg arst_1;
reg ctrl_1;
always @(posedge cp_c) begin
arst_1 <= in_1;
end
// control path
always @(posedge cp_a or negedge arst_1)
begin
if (!arst_1) begin
ctrl_1 <= 0;
end
else begin
ctrl_1 <= in_2;
end
end
always @(posedge cp_b)
begin
ctrl_sample <= ctrl_1;
end
endmodule

126

Chapter 2: Clock Domain Crossing Rules

Violations
--- Executing netlist checks on design CDC13_01 ...
21: ctrl_1 <= in_2;
^
CDC13_01.v:21: CDC> [WARNING] NTL_CDC13: A CDC asyncronous reset driven
control signal has no synchronizer CDC13_01.ctrl_1
--- Affected FF is : CDC13_01.ctrl_1 (file: CDC13_01.v, line: 21)
--- CDC Path Info: Source clock origin of the CDC Path is :
CDC13_01.cp_a (file: CDC13_01.v, line: 4)
--- CDC Path Info: Destination clock domain of the CDC Path is :
CDC13_01.cp_b (file: CDC13_01.v, line: 4)
--- Asynchronous Reset Pin of the affected FF is : CDC13_01.arst_1
(file: CDC13_01.v, line: 7)
--- Register driving the Asynchronous reset is : CDC13_01.&AS1.~ff0
(file: CDC13_01.v, line: 11)
--- Clock origin of the source of Asynchronous reset is :
CDC13_01.cp_c (file: CDC13_01.v, line: 4)
--- Netlist checks on design CDC13_01 completed.

127

Chapter 2: Clock Domain Crossing Rules

Schematic

128

Chapter 2: Clock Domain Crossing Rules

NTL_CDC14
Message: Control and Data Signals of a MUX (Logic)
Synchronizer must be Stable Enough (Property Generated)
Description

Leda flags this rule when a CDC data path is synchronized by a


MUX synchronizer. In case of any, it generates properties for
checking 'control and data' signal stability for each of these MUX
synchronizers.
A data path is synchronized by a MUX synchronizer while crossing
domains from source clock (sclk) to destination clock (dclk). Once
such a MUX synchronizer is detected, this rule generates properties
to check 'control and data' signal stability for each of these MUX
synchronizers. These properties are then passed to Magellan or VCS
for formal/simulation based verification.

Policy

DESIGN

Ruleset

CDC

Language

VHDL/Verilog

Type

Hardware (For Netlist)

Severity

Warning

Example
In the following figure, a 4-bit data path from clock domain of clk1 is passed through a
MUX 'm' to the domain of 'clk2'. The MUX is enabled by a 2-FF synchronized control
signal 'rx_dsel'. Clearly this arrangement is a MUX synchronizer.

129

Chapter 2: Clock Domain Crossing Rules

Leda automatically detects this and CDC14 rule generates stability assertions for control
signal 'tx_dsel' and data path 'tx_data'.

module CDC14 (rst, clk1, clk2, din, sel, dout);


input rst, clk1, clk2, sel;
input [3:0] din;
output [3:0] dout;
wire tx_dsel; wire [3:0] tx_data;
reg meta_tx_dsel, rx_dsel;
tx tx(rst, clk1, din, sel, tx_data, tx_dsel);
always @(posedge clk2)
if (rst) begin
meta_tx_dsel <= 0;
rx_dsel <= 0;
end
else begin
meta_tx_dsel <= tx_dsel;
rx_dsel <= meta_tx_dsel;
end
rx rx(rst, clk2, tx_data, rx_dsel, dout);
endmodule
module tx (rst, clk1, din, sel, tx_data, tx_dsel);
input rst, clk1, sel;

130

Chapter 2: Clock Domain Crossing Rules

input [3:0] din;


output [3:0] tx_data;
output tx_dsel;
reg [3:0] tx_data; reg tx_dsel;
always @(posedge clk1)
if (rst) begin
tx_data <= 0;
tx_dsel <= 0;
end
else begin
tx_data <= din;
tx_dsel <= sel;
end
endmodule
module rx (rst, clk2, rx_data, rx_dsel, dout);
input rst, clk2, rx_dsel;
input [3:0] rx_data;
output [3:0] dout;
reg [3:0] dout;
wire [3:0] data;
assign data = rx_dsel? rx_data : dout;
always @(posedge clk2)
if (rst)
dout <= 0;
else
dout <= data;
endmodule

131

Chapter 2: Clock Domain Crossing Rules

Violations
14: meta_tx_dsel <= tx_dsel;
^
NTL_CDC14.v:14: CDC> [WARNING] NTL_CDC14: Control and Data Signals of a
MUX (Logic) Synchronizer must be Stable Enough (Property Generated)
CDC14.meta_tx_dsel
--- Source Register: CDC14.tx.tx_dsel (file: NTL_CDC14.v, line: 32)
31: tx_data <= din;
^
NTL_CDC14.v:31: CDC> [WARNING] NTL_CDC14: Control and Data Signals of a
MUX (Logic) Synchronizer must be Stable Enough (Property Generated)
CDC14.tx.tx_data(0)
--- Other Bits of the Data Path: CDC14.tx.tx_data(1) (file:
NTL_CDC14.v, line: 31)
--- Other Bits of the Data Path: CDC14.tx.tx_data(2) (file:
NTL_CDC14.v, line: 31)
--- Other Bits of the Data Path: CDC14.tx.tx_data(3) (file:
NTL_CDC14.v, line: 31)

The following additional files are generated for Magellan run. These additional files can
be found at directory 'ForMG' in .leda_work or in the 'run directory'.
- aep_signal_stability.v - contains assertion definition for control signal stability
- aep_mux_data_signal_stability.v - contains assertion definition for data signal
stability
- leda_top_properties.v - contains 'bind' statements for attaching the assertions to
the design
- leda_prop_file.lst - contains list of generated files for Magellan integration
- LedaMgPrjFile.prj - automatically generated Magellan project file
- MgCmdFile.tcl - contains command to run Magellan on the design
- LedaMgPrjRun - run script that runs MgCmdFile.tcl (change its mode to '+x'
before running)

132

Chapter 2: Clock Domain Crossing Rules

Generated assertion files


leda_top_properties.v
bind cdc14 sync_signal_stablility_sva_assertion
#(2)
i_NTL_CDC14_1
(cdc14.clk2, cdc14.meta_tx_dsel, cdc14.rst);
bind cdc14 mux_data_signal_stablility_sva_assertion
#(2, 4)
i_NTL_CDC14_dst_2
(cdc14.rx.clk2, cdc14.tx.tx_data[3:0], cdc14.rx_dsel,
cdc14.rx.rst);
aep_signal_stability.v
module sync_signal_stablility_sva_assertion (dclk, din, rst);
parameter NFF=2; //- Number of FFs in the FF synchronizer
parameter WIDTH=1; //- Width of the CDC control signal
input dclk; //- Clk of the Destination domain
input [WIDTH-1:0] din; //- CDC control signal
input rst; //- Reset

CDC_CSS: assert property (


disable iff (rst)
@(posedge dclk) ##1 !$stable(din) |=> $stable(din)[*NFF]);
endmodule
aep_mux_data_signal_stability.v
module mux_data_signal_stablility_sva_assertion (dclk, data, dready,
drst);
parameter NFF=2; //- Number of FFs in the FF synchronizer
parameter WIDTH=1; //- Width of the CDC control signal
input
input
input
input

dclk; //- Clk of the Destination domain


[WIDTH-1:0] data; //- MUX data signal
dready; //- CDC synchronized control signal
drst; //- Destination domain Reset

property mux_data_stable;
disable iff (drst)
@(posedge dclk) (dready) |=> ($stable (data) || !dready);

133

Chapter 2: Clock Domain Crossing Rules

endproperty
CDC_MUX_DATA_CSS: assert property (mux_data_stable);
endmodule

Schematic

134

Chapter 2: Clock Domain Crossing Rules

NTL_CDC15
Message: A Handshake Synchronizer Must Implement The
Handshake Protocol and Data Stability Correctly (Property
Generated)
Description

Leda flags this rule when a CDC data path is synchronized by a


Handshake synchronizer. In case of any, it generates properties for
checking 'control and data' signal stability and 'handshake protocol'
for each of these Handshake synchronizers.
A data path is synchronized by a Handshake synchronizer while
crossing domains from source clock (sclk) to destination clock
(dclk). Once such a Handshake synchronizer is detected, this rule
generates properties to check for 'control and data' signal stability
and 'handshake protocols' for each of these Handshake
synchronizers. These properties are then passed to Magellan or VCS
for formal/simulation based verification.

Policy

DESIGN

Ruleset

CDC

Language

VHDL/Verilog

Type

Hardware (For Netlist)

Severity

Warning

Example
In the following figure, a 3-bit data path from clock domain of clk1 is fed to domain of
clk2 via a Handshake synchronizer. The Synchronizer uses two 2-FF synchronized
control signals (tx_valid and rx_done) to complete the handshake protocol. Leda
automatically detects this arrangement and CDC15 rule generates stability assertions for
control signal 'tx_valid', 'rx_done' and data path 'tx_data'. It also generates assertions for
checking the handshake protocol using signals 'tx_valid' and 'rx_done'.

135

Chapter 2: Clock Domain Crossing Rules

tx_data

tx_valid

rx_sync2

Tx Side

Rx Side

(domain clk1)

(domain clk2)
tx_sync2

rx_done

module cdc15 (rst, clk1, clk2, din, dout);


output [2:0] dout;
input [2:0] din;
input clk1, clk2, rst;
wire tx_valid, rx_done;
wire [2:0] data;
reg rx_sync1, rx_sync2, tx_sync1, tx_sync2;
always @(posedge clk2) begin
rx_sync1 <= tx_valid;
rx_sync2 <= rx_sync1;
end
always @(posedge clk1) begin
tx_sync1 <= rx_done;
tx_sync2 <= tx_sync1;
end
tx tx(rst, clk1, din, tx_sync2, tx_valid, data);
rx rx(rst, clk2, rx_sync2, data, rx_done, dout);
endmodule

136

Chapter 2: Clock Domain Crossing Rules

module tx (rst, clk1, din, tx_done, tx_valid, tx_data);


input rst, clk1; input [2:0] din;
input tx_done;
output tx_valid;
reg tx_valid;
output [2:0] tx_data;
reg [2:0] tx_data;
always @(posedge clk1) begin
if (rst)
tx_data <= 0;
else begin
if (!tx_valid & !tx_done)
tx_data <= din;
else
tx_data <= tx_data;
end
end
always @(posedge clk1) begin
if (rst)
tx_valid <= 0;
else begin
if (!tx_done)
tx_valid <= 1;
else
tx_valid <= 0;
end
end
endmodule

module rx (rst, clk2, rx_valid, rx_data, rx_done, dout);


input rst, clk2;
input rx_valid;
input [2:0] rx_data;
output rx_done;
reg rx_done;
output [2:0] dout;

137

Chapter 2: Clock Domain Crossing Rules

reg [2:0] dout;


always @(posedge clk2) begin
if (rst)
rx_done <= 0;
else
if (rx_valid)
rx_done <= 1;
else
rx_done <= 0;
end
always @(posedge clk2) begin
if (rst)
dout <= 0;
else
if (rx_valid)
dout <= rx_data;
end
endmodule

Violations
9: rx_sync1 <= tx_valid;
^
NTL_CDC15.v:9: CDC> [WARNING] NTL_CDC15: A Handshake Synchronizer Must
Implement The Handshake Protocol and Data Stability Correctly (Property
Generated) cdc15.rx_sync1
--- Source Register: cdc15.tx.tx_valid (file: NTL_CDC15.v, line: 44)
13: tx_sync1 <= rx_done;
^
NTL_CDC15.v:13: CDC> [WARNING] NTL_CDC15: A Handshake Synchronizer Must
Implement The Handshake Protocol and Data Stability Correctly (Property
Generated) cdc15.tx_sync1
--- Source Register: cdc15.rx.rx_done (file: NTL_CDC15.v, line: 65)
34: tx_data <= tx_data;
^
NTL_CDC15.v:34: CDC> [WARNING] NTL_CDC15: A Handshake Synchronizer Must
Implement The Handshake Protocol and Data Stability Correctly (Property
Generated) cdc15.tx.tx_data(0)
--- Other Bits of the Data Path: cdc15.tx.tx_data(1) (file:
NTL_CDC15.v, line: 34)
--- Other Bits of the Data Path: cdc15.tx.tx_data(2) (file:
NTL_CDC15.v, line: 34)

138

Chapter 2: Clock Domain Crossing Rules

The following additional files would be generated which are used for Magellan run.
These additional files can be found at directory 'ForMG' in .leda_work or in the 'run
directory.
- aep_signal_stability.v - contains assertion definition for control signal stability
- aep_handshake_data_signal_stability.v - contains assertion definition for data
signal stability
- aep_handshake_protocol_check.v - contains assertion definition for handshake
protocol check
- leda_top_properties.v - contains 'bind' statement for attaching the assertions to
the design
- leda_prop_file.lst - contains list of generated files for Magellan integration
- LedaMgPrjFile.prj - automatically generated Magellan project file
- MgCmdFile.tcl - contains command to run Magellan on the design
- LedaMgPrjRun - run script that runs MgCmdFile.tcl (change its mode to '+x'
before running)

139

Chapter 2: Clock Domain Crossing Rules

Generated assertion files


leda_top_properties.v
bind cdc15 sync_signal_stablility_sva_assertion
#(2)
i_NTL_CDC15_1
(cdc15.clk2, cdc15.rx_sync1, 1'b0);
bind cdc15 sync_signal_stablility_sva_assertion
#(2)
i_NTL_CDC15_2
(cdc15.clk1, cdc15.tx_sync1, 1'b0);
bind cdc15 handshake_protocol_check_sva_assertion_src
i_NTL_CDC15_src_req_3
(cdc15.clk1, cdc15.tx.tx_valid, cdc15.tx_sync2, 1'b0);
bind cdc15 handshake_protocol_check_sva_assertion_src
i_NTL_CDC15_src_ack_3
(cdc15.clk1, !cdc15.tx.tx_valid, !cdc15.tx_sync2, 1'b0);
bind cdc15 handshake_protocol_check_sva_assertion_dest
i_NTL_CDC15_dst_req_3
(cdc15.rx.clk2, cdc15.rx_sync2, cdc15.rx.rx_done, cdc15.rx.rst);
bind cdc15 handshake_protocol_check_sva_assertion_dest
i_NTL_CDC15_dst_ack_3
(cdc15.rx.clk2, !cdc15.rx_sync2, !cdc15.rx.rx_done,
cdc15.rx.rst);
bind cdc15 handshake_data_signal_stablility_sva_assertion_dest
#(2, 3)
i_NTL_CDC15_dst_4
(cdc15.rx.clk2, cdc15.tx.tx_data[2:0], cdc15.rx_sync2,
cdc15.rx.rx_done, cdc15.rx.rst);
aep_signal_stability.v
module sync_signal_stablility_sva_assertion (dclk, din, rst);
parameter NFF=2; //- Number of FFs in the FF synchronizer
parameter WIDTH=1; //- Width of the CDC control signal
input dclk; //- Clk of the Destination domain
input [WIDTH-1:0] din; //- CDC control signal
input rst; //- Reset

140

Chapter 2: Clock Domain Crossing Rules

CDC_CSS: assert property (


disable iff (rst)
@(posedge dclk) ##1 !$stable(din) |=> $stable(din)[*NFF]);
endmodule
aep_handshake_data_signal_stability.v
module handshake_data_signal_stablility_sva_assertion_dest (clk, data,
req, ack, rst);
parameter NFF=2; //- Number of FFs in the FF synchronizer
parameter WIDTH=1; //- Width of the CDC control signal
parameter MAX=12; //- Default Wait time for the Ack
input
input
input
input
input

clk; //- Clk of the domain


[WIDTH-1:0] data; //- CDC data signal
req; //- req control signal
ack; //- ack control signal
rst; //- Reset

property handshake_data_stable_dest;
disable iff (rst)
@(posedge clk) (req & !ack) |=> $stable(data);
endproperty
CDC_HANDSHAKE_DATA_CSS_DST: assert property
(handshake_data_stable_dest);
endmodule
aep_handshake_protocol_check.v
module handshake_protocol_check_sva_assertion_src (clk, req, ack, rst);
input
input
input
input

clk;
req;
ack;
rst;

////////-

Clk of the domain


req control signal
ack control signal
Reset

property handshake_protocol_check_src;
disable iff (rst)
@(posedge clk) (req && !ack) |=> (req);
endproperty
CDC_HANDSHAKE_PROTOCOL_CHK_SRC: assert property

141

Chapter 2: Clock Domain Crossing Rules

(handshake_protocol_check_src);
endmodule
module handshake_protocol_check_sva_assertion_dest (clk, req, ack, rst);
input
input
input
input

clk;
req;
ack;
rst;

////////-

Clk of the domain


req control signal
ack control signal
Reset

property handshake_protocol_check_dest;
disable iff (rst)
@(posedge clk) (req) |=> (ack);
endproperty
CDC_HANDSHAKE_PROTOCOL_CHK_DST: assert property
(handshake_protocol_check_dest);
endmodule

142

Chapter 2: Clock Domain Crossing Rules

NTL_CDC16
Message: A FIFO Synchronizer Must Implement the FIFO
Protocol and Data Stability Correctly (Property Generated)
Description

Leda flags this rule when a CDC data path is synchronized by a FIFO
synchronizer. In case of any, it generates properties for checking 'Fifo
protocol, gray code for read/write pointers, and data integrity' for
each of these FIFO synchronizers.
A data path is synchronized by a FIFO synchronizer while crossing
domains from source clock (sclk) to destination clock (dclk). Once
such a FIFO synchronizer is detected, this rule generates properties
to check for 'Fifo protocol, gray code for read/write pointers, and data
integrity' for each of these FIFO synchronizers. These properties are
then passed to Magellan or VCS for formal/simulation based
verification.
Please set set_cdc_synchronizer parameter to FIFO synchronizer
for Leda to flag this rule.

Policy

DESIGN

Ruleset

CDC

Language

VHDL/Verilog

Type

Hardware (For Netlist)

Severity

Warning

Example
In the following figure, an 8-bit data path from clock domain (clk1) is fed to clk2
domain (via a FIFO synchronizer). The interface of the FIFO module is given as
follows:

143

Chapter 2: Clock Domain Crossing Rules

clk1
full

clk2

empty
read

write

FIFO Module
read_data

write_data

When the associated design is checked enabling rule NTL_CDC16, Leda detects the
synchronizer, and provides the following text.
Set the following Tcl command for proper detection of a FIFO synchronizer.
set_cdc_synchronizer -name <module_name> -synchro_type fifo

144

Chapter 2: Clock Domain Crossing Rules

FIFO Example (test_fifo.v)


//==================================================
// b_counter.v; 4 bit asynchronous binary up counter
//==============================================================
module b_counter(c_out,c_reset,c_clk,en);
parameter c_width=4; //counter width
output [c_width-1:0] c_out; reg [c_width-1:0] c_out;
input c_reset,c_clk,en;
always @(posedge c_clk or posedge c_reset)
begin
if (c_reset)
c_out <= 0;
else if(en)
c_out <= c_out + 1;
end
endmodule
module a_fifo5 (d_out,f_full_flag,f_half_full_flag,f_empty_flag,
f_almost_full_flag,f_almost_empty_flag,d_in,r_en,
w_en,r_clk,w_clk,reset);
parameter
parameter
parameter
parameter
parameter
parameter

f_width=8; //FIFO width


f_depth=16; //FIFO depth
f_ptr_width=4; //because depth =16;
f_half_full_value=8;
f_almost_full_value=14;
f_almost_empty_value=2;

output [f_width-1:0] d_out; reg [f_width-1:0] d_out; //outputs


output f_full_flag,f_half_full_flag,f_almost_full_flag,f_empty_flag;
output f_almost_empty_flag;
input [f_width-1:0] d_in;
input r_en,w_en,r_clk,w_clk;
input reset;
//internal registers,wires
wire [f_ptr_width-1:0] r_ptr,w_ptr;
reg r_next_en,w_next_en;
reg [f_ptr_width-1:0] ptr_diff;
reg [f_width-1:0] f_memory[f_depth-1:0];
assign
assign
assign
assign

f_full_flag=(ptr_diff==(f_depth-1)); //assign FIFO status


f_empty_flag=(ptr_diff==0);
f_half_full_flag=(ptr_diff==f_half_full_value);
f_almost_full_flag=(ptr_diff==f_almost_full_value);

145

Chapter 2: Clock Domain Crossing Rules

assign f_almost_empty_flag=(ptr_diff==f_almost_empty_value);
always @(posedge w_clk) //write to memory
begin
if (reset)
f_memory [w_ptr] <= 0;
else if(w_en) begin
if(!f_full_flag)
f_memory[w_ptr]<=d_in;
end
end
always @(posedge r_clk) //read from memory
begin
if(reset)
d_out<=0; //f_memory[r_ptr];
else if(r_en) begin
if(!f_empty_flag)
d_out<=f_memory[r_ptr];
end
else d_out<=0;
end
always @(*) //ptr_diff changes as read or write clock change
begin
if(w_ptr>r_ptr)
ptr_diff<=w_ptr-r_ptr;
else if(w_ptr<r_ptr)
ptr_diff<=((f_depth-r_ptr)+w_ptr);
else ptr_diff<=0;
end
always @(*) //after empty flag activated fifo read counter should not
increment;
begin
if(r_en && (!f_empty_flag))
r_next_en=1;
else r_next_en=0;
end
always @(*) //after full flag activated fifo write counter should not
increment;
begin
if(w_en && (!f_full_flag))
w_next_en=1;
else w_next_en=0;
end
b_counter r_b_counter(.c_out(r_ptr),.c_reset(reset),.c_clk(r_clk),
.en(r_next_en));

146

Chapter 2: Clock Domain Crossing Rules

b_counter w_b_counter(.c_out(w_ptr),.c_reset(reset),.c_clk(w_clk),
.en(w_next_en));
endmodule
module CDC16(x,y,z,d_out,f_full_flag,f_half_full_flag,f_empty_flag,
f_almost_full_flag,f_almost_empty_flag,d_in,r_en,w_en,
CLKIN_IN,RST_IN,reset);
parameter
parameter
parameter
parameter
parameter
parameter
output
output
output
output

f_width=8;
f_depth=16;
f_ptr_width=4;
f_half_full_value=8;
f_almost_full_value=14;
f_almost_empty_value=2;

[f_width-1:0] d_out; //reg [f_width-1:0] d_out; //outputs


f_full_flag,f_half_full_flag,f_almost_full_flag,f_empty_flag;
f_almost_empty_flag;
x,y,z;

input [f_width-1:0] d_in;


input r_en,w_en,CLKIN_IN,RST_IN;
input reset;
a_fifo5 a_fifo55(d_out,f_full_flag,f_half_full_flag,f_empty_flag,
f_almost_full_flag,f_almost_empty_flag,d_in,r_en,
w_en,CLK0_OUT,CLKDV_OUT,reset); //instantiate fifo
endmodule

Set the following Tcl command for proper detection of a FIFO synchronizer.
set_cdc_synchronizer -name CDC16 -synchro_type fifo

The Leda command is:


leda -top CDC16 -config config.tcl -clock_file param.tcl test_fifo.v
+v2k

Select rule 'NTL_CDC16' in the config.tcl file.

147

Chapter 2: Clock Domain Crossing Rules

Violations
85: module cdc16 (x,y,z,d_out,f_full_flag,f_half_full_flag,f_empty_flag,
^
NTL_CDC16.v:85: CDC> [WARNING] NTL_CDC16: A FIFO Synchronizer Must
Implement the FIFO Protocol and Data Stability Correctly (Property
Generated) cdc16
--- Source Reset pin::
cdc16.reset (file: NTL_CDC16.v, line: 100)
--- FIFO read pin::
cdc16.r_en (file: NTL_CDC16.v, line: 99)
--- FIFO write pin::
cdc16.w_en (file: NTL_CDC16.v, line: 99)
--- FIFO Full Sig::cdc16.f_almost_full_flag (file: NTL_CDC16.v, line:95)
--- FIFO Empty Sig::
cdc16.f_empty_flag (file: NTL_CDC16.v, line: 95)
--- FIFO Input Data Line::
cdc16.d_out (file: NTL_CDC16.v, line: 94)
--- FIFO Output Data Line::
cdc16.d_out (file: NTL_CDC16.v, line: 94)

The following additional files would be generated which are used for Magellan run.
These additional files can be found at directory 'ForMG' in .leda_work or in the 'run
directory'.
- aep_fifo_validate_assertions.v - contains assertion definition for fifo related
checks
- leda_top_properties.v - contains 'bind' statement for attaching the assertions to
the design
- leda_prop_file.lst - contains list of generated files for Magellan integration
- LedaMgPrjFile.prj - automatically generated Magellan project file
- MgCmdFile.tcl - contains command to run Magellan on the design
- LedaMgPrjRun - run script that runs MgCmdFile.tcl (change its mode to '+x'
before running)

148

Chapter 2: Clock Domain Crossing Rules

Generated assertion files


leda_top_properties.v
bind cdc16 fifo_validating_sva_assertion
#(8)
inst_0
(cdc16., cdc16., cdc16.reset, cdc16.reset,
cdc16.f_almost_full_flag, cdc16.f_empty_flag, cdc16.r_en, cdc16.w_en,
cdc16.d_in[7:0], cdc16.d_out[7:0]);
aep_fifo_validate_assertions.v
module fifo_validating_sva_assertion (src_clk, dst_clk, src_rst,
dst_rst, full_sig, empty_sig, read_sig, write_sig, data_sig,
dataOutSig);
parameter DATA_BUS_WIDTH=16; //- Width of the FIFO data bus
parameter COUNT_WIDTH=8; //- Width of the FIFO Address pointers
input src_clk; //- Clk of the Source domain
input dst_clk; //- Clk of the Destination domain
input [DATA_BUS_WIDTH-1:0] data_sig; //- FIFO Push Data signal
input [DATA_BUS_WIDTH-1:0] dataOutSig; //- FIFO Pop Data signal
input src_rst; //- Src Reset
input dst_rst; //- Dst Reset
input full_sig; //- FIFO FULL signal
input empty_sig; //- FIFO Empty Signal
input write_sig; //- FIFO write Signal
input read_sig; //- FIFO read Signal
//--- Check the FIFO data integrity property/assertion in VCS --//--- The FIFO data integrity property/assertion is disabled in Magellan
check --`ifndef MAGELLAN_DISABLE
reg [DATA_BUS_WIDTH-1:0] rcnt, wcnt;
always @(posedge src_clk or negedge src_rst) begin
if (!src_rst) wcnt = 0;
else if (write_sig) begin
wcnt = wcnt + 1;
end
end
always @(posedge dst_clk or negedge dst_rst) begin
if (!dst_rst) rcnt = 0;
else if (read_sig) begin
rcnt = rcnt + 1;
end

149

Chapter 2: Clock Domain Crossing Rules

end
`endif
property fifo_full_chk;
disable iff (src_rst)
@(src_clk) (write_sig |-> !full_sig);
endproperty
FIFO_FULL_CHK: assert property (fifo_full_chk);

property fifo_empty_chk;
disable iff (dst_rst)
@(dst_clk) (read_sig |-> !empty_sig);
endproperty
FIFO_EMPTY_CHK: assert property (fifo_empty_chk);
//--- Check the FIFO data integrity property/assertion in VCS --//--- The FIFO data integrity property/assertion is disabled in Magellan
--`ifndef MAGELLAN_DISABLE
property fifoDataChk;
logic [DATA_BUS_WIDTH-1:0] tempData;
logic [COUNT_WIDTH-1:0]
dataCount;
disable iff (dst_rst || src_rst)
@(src_clk)
(write_sig, dataCount = wcnt, tempData = data_sig) |=>
@(dst_clk)
(first_match (##[0:$] (read_sig && (rcnt == dataCount))) |->
(dataOutSig ==
tempData));
endproperty
FIFO_DATA_CHK: assert property (fifoDataChk);
`endif
endmodule

150

You might also like