{"id":289,"date":"2025-07-12T14:48:39","date_gmt":"2025-07-12T13:48:39","guid":{"rendered":"https:\/\/blog.edgesmart.co.uk\/?p=289"},"modified":"2025-07-26T17:10:40","modified_gmt":"2025-07-26T16:10:40","slug":"vivados-hidden-gem-the-cdc-linter-catch-clock-domain-issues-early","status":"publish","type":"post","link":"https:\/\/blog.edgesmart.co.uk\/index.php\/2025\/07\/12\/vivados-hidden-gem-the-cdc-linter-catch-clock-domain-issues-early\/","title":{"rendered":"CDC-101.2: The CDC Linter \u2014 Catch Clock Domain Issues Early"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\"><\/h1>\n\n\n\n<p>When it comes to FPGA design, <strong>Clock Domain Crossing (CDC)<\/strong> issues are among the most elusive and costly bugs to diagnose. They often appear late \u2014 in the lab or on customer hardware \u2014 and can be extremely hard to reproduce.<\/p>\n\n\n\n<p>What if you could catch them much earlier, without adding third-party tools?<\/p>\n\n\n\n<p><strong>Enter Vivado\u2019s CDC Linter<\/strong> \u2014 a little-known, <strong>built-in static analysis feature<\/strong> that can help you detect CDC issues early in your design flow, <em>without requiring any extra licenses or software<\/em>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The CDC Problem: Why It\u2019s Dangerous<\/h2>\n\n\n\n<p>In FPGA and ASIC designs, signals often need to pass between blocks running on <strong>different clocks<\/strong>. This introduces potential risks:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Metastability<\/strong>, when a flip-flop samples a signal mid-transition<\/li>\n\n\n\n<li><strong>Data loss<\/strong>, due to inadequate synchronization<\/li>\n\n\n\n<li><strong>Glitches<\/strong>, especially in control signals<\/li>\n\n\n\n<li><strong>Inconsistent resets<\/strong>, across clock boundaries<\/li>\n<\/ul>\n\n\n\n<p>These bugs are hard to simulate because:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>They are <strong>data- and timing-dependent<\/strong><\/li>\n\n\n\n<li>They <strong>don\u2019t always manifest<\/strong> during normal testbenches<\/li>\n\n\n\n<li>They show up under <strong>specific PVT (Process, Voltage, Temperature)<\/strong> conditions<\/li>\n<\/ul>\n\n\n\n<p>That\u2019s why <strong>static CDC analysis<\/strong> is a must in any robust verification flow.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What is Vivado\u2019s CDC Linter?<\/h2>\n\n\n\n<p>Vivado\u2019s CDC Linter is a <strong>static, rule-based analysis engine<\/strong> that inspects your RTL code and identifies:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Cross-domain signal transfers<\/li>\n\n\n\n<li>Missing or misused synchronizer structures<\/li>\n\n\n\n<li>Unsafe asynchronous resets<\/li>\n\n\n\n<li>Potential metastability vulnerabilities<\/li>\n<\/ul>\n\n\n\n<p>And unlike full CDC verification tools (like Synopsys VC Formal or Siemens Questa CDC), <strong>Vivado\u2019s Linter runs fast<\/strong> and doesn\u2019t require extra setup, licenses, or formal models.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What the CDC Linter Checks For<\/h2>\n\n\n\n<p>Here\u2019s what Vivado\u2019s CDC Linter can detect:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Check Type<\/th><th>Description<\/th><\/tr><\/thead><tbody><tr><td><strong>Single-bit CDC<\/strong><\/td><td>Identifies clock domain transfers missing proper synchronizer flip-flops<\/td><\/tr><tr><td><strong>Multi-bit CDC<\/strong><\/td><td>Flags multi-bit buses crossing domains without proper handshakes or gray encoding<\/td><\/tr><tr><td><strong>Async Reset Issues<\/strong><\/td><td>Detects reset signals crossing domains without resynchronization<\/td><\/tr><tr><td><strong>Data Fanout<\/strong><\/td><td>Warns if signals fan out from one domain to multiple others, creating timing hazards<\/td><\/tr><tr><td><strong>Missing Acknowledgment<\/strong><\/td><td>Checks for unidirectional handshakes or latches<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Each issue is reported with:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Source and destination clocks<\/strong><\/li>\n\n\n\n<li><strong>Type of crossing<\/strong><\/li>\n\n\n\n<li><strong>Signal name and hierarchy<\/strong><\/li>\n\n\n\n<li><strong>Severity (Warning, Critical, etc.)<\/strong><\/li>\n\n\n\n<li>Suggested mitigation strategies<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">How to Use the CDC Linter in Vivado<\/h2>\n\n\n\n<p>Running the CDC Linter is straightforward:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Option 1: Via Tcl Console<\/strong><\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>report_cdc -verbose -details\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Option 2: Via Vivado GUI<\/strong><\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open your synthesized design<\/li>\n\n\n\n<li>Go to <strong>Tools &gt; Report CDC<\/strong><\/li>\n\n\n\n<li>Choose verbosity level and generate the report<\/li>\n\n\n\n<li>Review flagged issues interactively in the report view<\/li>\n<\/ol>\n\n\n\n<p>You can also export the CDC report to a file for documentation or design reviews.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What the CDC Linter Is (and Isn&#8217;t)<\/h2>\n\n\n\n<p>The CDC Linter is:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Fast static analysis of RTL<\/li>\n\n\n\n<li>Free and built into <strong>all Vivado editions<\/strong> (even Standard)<\/li>\n\n\n\n<li>Great for early-stage verification and design reviews<\/li>\n<\/ul>\n\n\n\n<p>But it\u2019s not:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A full formal CDC checker<\/li>\n\n\n\n<li>A timing analyzer (it doesn&#8217;t analyze actual delays or metastability MTBF)<\/li>\n\n\n\n<li>Meant to replace simulation or functional verification<\/li>\n<\/ul>\n\n\n\n<p>That said, for small to mid-sized designs \u2014 or as a <strong>first-pass CDC filter<\/strong> \u2014 it\u2019s an invaluable tool.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Example Use Case: Missed Synchronizer<\/h2>\n\n\n\n<p>Imagine you&#8217;re designing a UART interface in a slower clock domain and sending status signals to an AXI interface running at a faster clock. A simple <code>tx_done<\/code> pulse crosses from UART to AXI.<\/p>\n\n\n\n<p>If you forget to insert a 2-stage synchronizer, <strong>Vivado\u2019s CDC Linter<\/strong> will flag it \u2014 even if your simulation doesn&#8217;t.<\/p>\n\n\n\n<p>Result: <strong>You catch a potential metastability bug before the testbench is written<\/strong>, saving debug time and downstream pain.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Best Practices<\/h2>\n\n\n\n<p>To get the most out of the CDC Linter:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use consistent clock naming conventions in your RTL<\/li>\n\n\n\n<li>Tag your synchronizer modules or use <code>ASYNC_REG<\/code> attributes<\/li>\n\n\n\n<li>Run CDC linting <strong>as early as possible<\/strong> \u2014 ideally right after RTL handoff<\/li>\n\n\n\n<li>Integrate into your synthesis flow or CI pipeline<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">How This Fits into the Larger Vivado Ecosystem<\/h2>\n\n\n\n<p>AMD continues to evolve Vivado into a more <strong>verification-aware toolchain<\/strong>. Recent versions added:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>UVM simulation support<\/strong><\/li>\n\n\n\n<li><strong>VHDL code coverage in 2025.1<\/strong> <strong>(Existing Verilog\/SystemVerilog code coverage)<\/strong><\/li>\n\n\n\n<li><strong>Functional coverage via SystemVerilog<\/strong><\/li>\n<\/ul>\n\n\n\n<p>Adding <strong>CDC linting<\/strong> to your workflow brings Vivado closer to a full <strong>RTL signoff environment<\/strong>, especially for budget-conscious teams not using third-party EDA tools.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Final Thoughts<\/h2>\n\n\n\n<p>CDC issues are stealthy and hard to simulate \u2014 but they\u2019re easy to <strong>prevent<\/strong> with the right tools.<\/p>\n\n\n\n<p>Vivado\u2019s <strong>CDC Linter<\/strong> is a simple, powerful way to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Improve design reliability<\/li>\n\n\n\n<li>Catch bugs earlier<\/li>\n\n\n\n<li>Build more robust, production-ready FPGA systems<\/li>\n<\/ul>\n\n\n\n<p>And it\u2019s already in your toolbox. Start using it.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When it comes to FPGA design, Clock Domain Crossing (CDC) issues are among the most elusive and costly bugs to diagnose. They often appear late \u2014 in the lab or on customer hardware \u2014 and can be extremely hard to reproduce. What if you could catch them much earlier, without adding third-party tools? Enter Vivado\u2019s &hellip;<br \/><a href=\"https:\/\/blog.edgesmart.co.uk\/index.php\/2025\/07\/12\/vivados-hidden-gem-the-cdc-linter-catch-clock-domain-issues-early\/\" class=\"more-link pen_button pen_element_default pen_icon_arrow_double\">Continue reading <span class=\"screen-reader-text\">CDC-101.2: The CDC Linter \u2014 Catch Clock Domain Issues Early<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-289","post","type-post","status-publish","format-standard","hentry","category-uncategorised"],"_links":{"self":[{"href":"https:\/\/blog.edgesmart.co.uk\/index.php\/wp-json\/wp\/v2\/posts\/289","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.edgesmart.co.uk\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.edgesmart.co.uk\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.edgesmart.co.uk\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.edgesmart.co.uk\/index.php\/wp-json\/wp\/v2\/comments?post=289"}],"version-history":[{"count":4,"href":"https:\/\/blog.edgesmart.co.uk\/index.php\/wp-json\/wp\/v2\/posts\/289\/revisions"}],"predecessor-version":[{"id":313,"href":"https:\/\/blog.edgesmart.co.uk\/index.php\/wp-json\/wp\/v2\/posts\/289\/revisions\/313"}],"wp:attachment":[{"href":"https:\/\/blog.edgesmart.co.uk\/index.php\/wp-json\/wp\/v2\/media?parent=289"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.edgesmart.co.uk\/index.php\/wp-json\/wp\/v2\/categories?post=289"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.edgesmart.co.uk\/index.php\/wp-json\/wp\/v2\/tags?post=289"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}