Skip to content

Feature Request: Native support for negedge clock in FIRRTL #10329

@sequencer

Description

@sequencer

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions