llvm / llvm/circt

[FIRRTL] Incorrect Register Parsing

Open
#5,202 0 comments 1 reaction 0 assignees View on GitHub
bug FIRRTL
Dominant language
C++
Stars
2.2k
Forks
524
Avg merge
3d 2h
Merged PRs (30d)
46

Description

The FIRRTL parser uses the reset initial value being the reset as a shorthand for "this is a reset-less register". However, it only narrowly means that if the reset signal is `UInt<1>(0)`. Consider the following:

```
circuit Foo :
module Foo :
input clock: Clock
input a: UInt<1>
output b: UInt<1>

reg r: UInt<1>, clock with: (reset => (UInt<1>(1), r))

r <= a
b <= r
```

This register never exits an indeterminate state and can be optimized to some constant. CIRCT currently thinks this is a reset-less register:

```verilog
module Foo(
input clock,
a,
output b
);

reg r;
always @(posedge clock)
r <= a;
assign b = r;
endmodule
```

SFC will produce:
```verilog
module Foo(
input clock,
input a,
output b
);
assign b = 1'h0;
endmodule
```

Note: this code is impossible to emit from Chisel due to limitations of how it works.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by tracing the FIRRTL register parser using the example in the issue, focusing on how the reset initial value is classified. Done means a register reset with UInt<1>(1) is not treated as reset-less and the resulting output preserves the behavior shown by SFC rather than the incorrect CIRCT Verilog.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.