[circt-verilog][arcilator] `arcilator` fails to lower `llhd.constant_time` generated from simple SV delay (`#1`)
- Dominant language
- C++
- Stars
- 2.2k
- Forks
- 524
- Avg merge
- 3d 2h
- Merged PRs (30d)
- 46
Description
## Title
[circt-verilog][arcilator] `arcilator` fails to lower `llhd.constant_time` generated from simple SV delay (`#1`)
## Summary
I ran into a failure in the arcilator flow with a minimal SystemVerilog module using a single `#1` delay. The same design runs under Verilator, but arcilator reports `llhd.constant_time` as illegal during conversion to `arcs` and stops. I did a preliminary source-level analysis (below) and would like to discuss with maintainers whether this behavior is expected or should be treated as a bug.
## Details
The SV design is intentionally minimal and only uses an `initial` block with a
single `#1` delay. There are no clocks, resets, or inputs. The only signals are
two outputs (`q` and `ok`) to indicate observable state and a success message.
Behavior:
- At time 0, both `q` and `ok` are set to `0`.
- After `#1`, `q` is set to `1`, `ok` is set to `1`, and a `$display` message is
printed.
Observed issue:
- `circt-verilog --ir-hw` converts the `#1` delay into `llhd.constant_time`.
- The arcilator pipeline then fails when lowering to `arcs`, reporting that
`llhd.constant_time` is illegal and the conversion fails.
- The same SV code runs successfully under Verilator, so the issue appears
specific to the arcilator lowering path.
## Reproduction
### arcilator
Create `top.sv`:
```systemverilog
module top(output logic q, output logic ok);
initial begin
q = 1'b0;
ok = 1'b0;
#1 q = 1'b1;
ok = 1'b1;
$display("OK: arcilator run completed");
end
endmodule
```
Run:
```bash
circt-verilog --ir-hw top.sv -o top.mlir
arcilator top.mlir --state-file=top.json | opt -O3 --strip-debug -S | llc -O3 --filetype=obj -o top.o
cc top.o -o top
./top
```
### verilator
Use the same `top.sv` content as above.
Run:
```bash
verilator -Wall --cc top.sv --exe sim_main.cpp
make -C obj_dir -f Vtop.mk Vtop
./obj_dir/Vtop
```
## Actual Result (arcilator)
```
top.mlir:4:10: error: failed to legalize operation 'llhd.constant_time' that was explicitly marked illegal
%0 = llhd.constant_time <1000000fs, 0d, 0e>
^
top.mlir:1:1: error: conversion to arcs failed
module {
^
```
## Expected Result
The minimal delay should either:
- be supported by arcilator, or
- be lowered to something legal for `arcs` without failing.
### Question:
How to solve this problem and simulate this sv problem?
## Analysis of Failure Cause
Based on the current sources, my preliminary analysis is that the failure stems from a missing legalization pattern in the `ConvertToArcs` pass:
- `llhd.constant_time` is a valid LLHD op produced by `circt-verilog --ir-hw` for `#1` delays.
- The arcilator pipeline runs `ConvertToArcs`, which marks the entire LLHD dialect illegal and only provides conversions for `llhd.combinational` and `llhd.yield`.
https://github.com/llvm/circt/blob/3c58046f1d8fc6f5355a7f2c2b73b43ffb37ba4d/lib/Conversion/ConvertToArcs/ConvertToArcs.cpp#L567-L585
- As a result, `llhd.constant_time` remains illegal with no rewrite available, and the dialect conversion reports a legalization failure.
## Environment
- OS: Linux 5.15.0-164-generic
- CIRCT: firtool-1.139.0
- LLVM: 22.0.0git
- Verilator: 5.022 2024-02-24 (rev v5.020-157-g2b4852048)
- Git commit: 2e2f4775452d1e0bb2c8075d845808f781268049
## Notes
The failure appears at the `llhd.constant_time` op introduced during `circt-verilog --ir-hw`, before `arcilator` lowers to `arcs`.
## Relevant Source References
- `llhd.constant_time` is a core LLHD op that materializes a time constant. It is defined as `llhd.constant_time` in the LLHD value ops definition file. See `include/circt/Dialect/LLHD/IR/LLHDValueOps.td`.
- The `ConvertToArcs` pass marks the entire LLHD dialect as illegal and only provides conversion patterns for `llhd.combinational` and `llhd.yield`. This means any other LLHD ops (including `llhd.constant_time`) remain illegal and will trigger a legalization failure. See `lib/Conversion/ConvertToArcs/ConvertToArcs.cpp`.
- The arcilator pipeline explicitly runs `ConvertToArcs` as part of its arc conversion pipeline. See `lib/Tools/arcilator/pipelines.cpp`.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with lib/Conversion/ConvertToArcs/ConvertToArcs.cpp at the referenced conversion patterns, then inspect lib/Tools/arcilator/pipelines.cpp and the llhd.constant_time definition in include/circt/Dialect/LLHD/IR/LLHDValueOps.td. Reproduce the failure with the minimal top.sv and arcilator command, then determine whether the delay should be supported or converted into an arcs-legal form; done means the pipeline no longer fails on this case.
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