llvm / llvm/circt

Feature Request: Native support for negedge clock in FIRRTL

Open
#10,329 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C++
Stars
2.2k
Forks
524
Avg merge
3d 2h
Merged PRs (30d)
46

Description

# Summary

When implementing hardware designs that require negedge-clocked registers, the current FIRRTL/CIRCT infrastructure requires low-level workarounds that are fragile, non-portable, and produce suboptimal Verilog output.

# Use cases: Negedge-clocked registers:

Many standard cell designs require registers clocked on the negative edge of a clock signal (e.g., CDC synchronizers, JTAG TAP state machines with negedge tck for shift/output registers, timing reference registers in clock-ratio synchronizers).

Current workaround: Manually construct an inverted clock using low-level MLIR C-API operations `clk → AsUIntPrim → NotPrim → AsClockPrim` use as clock in a locally scoped register
This works but:
- Requires importing java.lang.foreign.Arena, org.llvm.mlir.scalalib.capi.ir.{Block, Context}, and CIRCT FIRRTL dialect operations — none of which are user-facing APIs
- The generated Verilog uses posedge _inverted_clk with an explicit assign _inverted_clk = ~clk, instead of the idiomatic negedge clk that downstream tools expect
- Formal verification tools (e.g., Synopsys Formality) sometimes cannot automatically match posedge ~clk against negedge clk in equivalence checking

# Proposed Improvements

First-class negedge clock support — Allow Clock to carry an edge attribute, or provide a `NegEdgeClock(clk)` primitive that generates idiomatic `negedge clk` in Verilog output

# AI-assisted declaimer

This Issue is drafted by Claude, and edited by Jiuyang Liu. We are using AI to migrate many old Verilog-based modules with Zaozi eDSL, and found these incompatibilities.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the Clock representation and the FIRRTL-to-Verilog path involved in the current AsUIntPrim → NotPrim → AsClockPrim workaround. Compare the proposed edge attribute with a NegEdgeClock primitive, then verify that the completed change emits idiomatic negedge clk rather than an inverted-clock assign.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.