Bug Report: arcilator fails to legalize 'llhd.process' during class instantiation lowering
Tool: CIRCT v1.144.0 (circt-verilog + arcilator)
Severity: Compilation Error
Description
CIRCT fails to compile SystemVerilog code containing class instantiation in procedural context. The circt-verilog frontend successfully parses the class declaration and generates MLIR, but the arcilator backend crashes with a legalization failure: "failed to legalize operation 'llhd.process' that was explicitly marked illegal". This is a circt compilation error where Verilator and Icarus Verilog successfully compile the same code without errors.
The root cause is that CIRCT incorrectly lowers SystemVerilog class instantiation to llhd.process operations, which Arcilator cannot convert to LLVM IR. The llhd.process dialect is designed for hardware simulation processes, not software object allocation.
Minimal Reproducible Example
module top;
class parent;
endclass
initial begin
parent p = new();
end
endmodule
Reproduction Steps
# CIRCT fails
circt-verilog --ir-hw minimal_testcase.sv | arcilator
# Verilator succeeds
verilator --lint-only --sv minimal_testcase.sv
# Icarus Verilog succeeds
iverilog -g2012 minimal_testcase.sv
Actual Output
$ circt-verilog --ir-hw minimal_testcase.sv | arcilator
minimal_testcase.sv:6:12: warning: initializing a static variable in a procedural context requires an explicit 'static' keyword [-Wexplicit-static]
parent p = new();
^
minimal_testcase.sv:2:9: remark: Class builtin functions (needed for randomization, constraints, and covergroups) are not yet supported and will be dropped during lowering.
class parent;
^
<stdin>:5:5: error: failed to legalize operation 'llhd.process' that was explicitly marked illegal: "llhd.process"() ({...}) : () -> ()
llhd.process {
^
<stdin>:5:5: note: see current operation:
"llhd.process"() ({
%1 = "func.call"(%0) <{callee = @malloc}> : (i64) -> !llvm.ptr
"llhd.halt"() : () -> ()
}) : () -> ()
<stdin>:1:1: error: conversion to arcs failed
module {
^
Expected Output
The code should compile successfully without errors. The testcase is valid IEEE 1800-2023 SystemVerilog:
- Class declaration is valid (IEEE 1800-2023 Section 8.2)
- Class instantiation with
new() is valid (IEEE 1800-2023 Section 8.13)
- Procedural context (
initial block) is valid (IEEE 1800-2023 Section 9.2)
Verilator and Icarus Verilog both compile this code successfully.
Cross-Tool Comparison
| Tool |
Version |
Result |
| Verilator |
5.022 |
Success |
| Icarus Verilog |
13.0 (devel) |
Success |
| CIRCT |
v1.144.0 |
Failure |
Consensus: Most tools handle this correctly; CIRCT has compilation issues with class instantiation due to incorrect lowering to llhd.process dialect.
Root Cause (Preliminary)
CIRCT's circt-verilog frontend lowers class instantiation to llhd.process operations, but Arcilator lacks a legalization pattern to convert llhd.process to LLVM IR. This is a fundamental architectural issue:
-
Incomplete Class Support: CIRCT emits a remark acknowledging classes are unsupported but continues processing instead of rejecting the input with a clear error message.
-
Missing Arcilator Pattern: Arcilator's ConvertToArcs pass marks the entire LLHD dialect as illegal but lacks conversion patterns for llhd.process operations generated by class instantiation.
-
Dialect Design Mismatch: LLHD process constructs represent hardware simulation processes (concurrent behavior), while SystemVerilog class instantiation represents software object allocation. Using llhd.process for classes is a conceptual mismatch.
Failure Point: Arcilator (CIRCT's LLHD-to-LLVM conversion pass), legalization stage before LLVM IR generation.
Standard Compliance Assessment
Classification: Tool Bug (CIRCT Implementation Issue)
IEEE References:
- IEEE 1800-2023 Section 8.2 (Class Declarations)
- IEEE 1800-2023 Section 8.13 (Class Instantiation)
- IEEE 1800-2023 Section 9.2 (Initial Procedures)
Analysis:
The testcase is fully IEEE 1800-2023 compliant. No undefined behavior or ambiguous constructs exist. CIRCT's failure to compile this code is a tool deficiency, not a standard compliance issue. The frontend generates invalid MLIR by lowering class instantiation to an incompatible dialect (llhd.process instead of LLVM dialect), and the backend lacks legalization patterns to handle the result.
Recommended Fix:
- Short-term: Emit a clear error message in
circt-verilog when encountering class instantiation instead of attempting lowering
- Long-term: Implement proper class instantiation lowering directly to LLVM dialect (not LLHD dialect), similar to Verilator's C++ generation strategy
Bug Report: arcilator fails to legalize 'llhd.process' during class instantiation lowering
Tool: CIRCT v1.144.0 (circt-verilog + arcilator)
Severity: Compilation Error
Description
CIRCT fails to compile SystemVerilog code containing class instantiation in procedural context. The
circt-verilogfrontend successfully parses the class declaration and generates MLIR, but thearcilatorbackend crashes with a legalization failure: "failed to legalize operation 'llhd.process' that was explicitly marked illegal". This is a circt compilation error where Verilator and Icarus Verilog successfully compile the same code without errors.The root cause is that CIRCT incorrectly lowers SystemVerilog class instantiation to
llhd.processoperations, which Arcilator cannot convert to LLVM IR. Thellhd.processdialect is designed for hardware simulation processes, not software object allocation.Minimal Reproducible Example
Reproduction Steps
Actual Output
Expected Output
The code should compile successfully without errors. The testcase is valid IEEE 1800-2023 SystemVerilog:
new()is valid (IEEE 1800-2023 Section 8.13)initialblock) is valid (IEEE 1800-2023 Section 9.2)Verilator and Icarus Verilog both compile this code successfully.
Cross-Tool Comparison
Consensus: Most tools handle this correctly; CIRCT has compilation issues with class instantiation due to incorrect lowering to
llhd.processdialect.Root Cause (Preliminary)
CIRCT's
circt-verilogfrontend lowers class instantiation tollhd.processoperations, but Arcilator lacks a legalization pattern to convertllhd.processto LLVM IR. This is a fundamental architectural issue:Incomplete Class Support: CIRCT emits a remark acknowledging classes are unsupported but continues processing instead of rejecting the input with a clear error message.
Missing Arcilator Pattern: Arcilator's ConvertToArcs pass marks the entire LLHD dialect as illegal but lacks conversion patterns for
llhd.processoperations generated by class instantiation.Dialect Design Mismatch: LLHD
processconstructs represent hardware simulation processes (concurrent behavior), while SystemVerilog class instantiation represents software object allocation. Usingllhd.processfor classes is a conceptual mismatch.Failure Point: Arcilator (CIRCT's LLHD-to-LLVM conversion pass), legalization stage before LLVM IR generation.
Standard Compliance Assessment
Classification: Tool Bug (CIRCT Implementation Issue)
IEEE References:
Analysis:
The testcase is fully IEEE 1800-2023 compliant. No undefined behavior or ambiguous constructs exist. CIRCT's failure to compile this code is a tool deficiency, not a standard compliance issue. The frontend generates invalid MLIR by lowering class instantiation to an incompatible dialect (
llhd.processinstead of LLVM dialect), and the backend lacks legalization patterns to handle the result.Recommended Fix:
circt-verilogwhen encountering class instantiation instead of attempting lowering