Skip to content

Drop chisel#10172

Open
oharboe wants to merge 14 commits intoThe-OpenROAD-Project:masterfrom
oharboe:drop-chisel
Open

Drop chisel#10172
oharboe wants to merge 14 commits intoThe-OpenROAD-Project:masterfrom
oharboe:drop-chisel

Conversation

@oharboe
Copy link
Copy Markdown
Collaborator

@oharboe oharboe commented Apr 17, 2026

I asked claude to ditch chisel and use system verilog for test/orfs/mock-array....

Needs review...

oharboe and others added 9 commits April 17, 2026 16:48
Idiomatic SystemVerilog replacement for the Chisel-generated
MockArray. Uses parameterized modules with generate blocks,
unpacked arrays, and a concrete Element wrapper (ElementInner
holds the parameterized logic) to avoid parameterized
instantiation syntax that OpenROAD's Verilog reader cannot parse.

The multiplier blackbox stub is included for hierarchical
synthesis: the actual Amaranth-generated gate-level multiplier.v
is joined after synthesis via genrule.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Replace the Chisel/firtool synthesis pipeline with hierarchical
synthesis using the slang SystemVerilog frontend:

- Element RTL synthesized with slang (multiplier blackboxed via
  SYNTH_BLACKBOXES + --ignore-unknown-modules --empty-blackboxes)
- multiplier.v synthesized separately with native Yosys frontend
  (Amaranth-generated Verilog triggers a yosys-slang assertion
  with --keep-hierarchy)
- Netlists joined via genrule cat, fed to orfs_flow via
  SYNTH_NETLIST_FILES

Update IO constraint scripts (io.tcl, element-io.tcl) and
load_mock_array.tcl for the new port naming (bracket-indexed
unpacked arrays instead of Chisel's underscore-separated flat
ports). Update simulate.cpp for wide-bus Verilator interface.

Remove chisel_binary rule from BUILD; replace fir_library pipeline
in mock-array.bzl with filegroups and orfs_synth().

This also tests hierarchical synthesis in OpenROAD, which was
not previously covered.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Apply the non-Chisel pieces of the earlier fcd1b551b work on top of
the slang+SystemVerilog conversion:

- MockArray.sv: make Element accept ELEMENT_COLS via \`define (set
  through SYNTH_SLANG_ARGS -DELEMENT_COLS) and MockArray honor
  WIDTH/HEIGHT/DATA_WIDTH via VERILOG_TOP_PARAMS, so 4x4 actually
  synthesizes with 4 columns rather than the default 8.
- mock-array.bzl: wire ELEMENT_COLS define and VERILOG_TOP_PARAMS
  into the orfs_synth calls; gate verilator_cc_library / simulator /
  vcd generation and the VCD-based power tests (openroad/power/
  power_instances) on v != "base", since Verilator can't compile
  uniquified post-P&R base netlists and flat netlists don't map to
  hierarchical VCD scope names. path_groups (timing-only) still
  runs on both variants.
- load_mock_array.tcl: only read per-Element SPEF for the
  hierarchical (base) flow.
- simulate.cpp: clang-format fixes and free the VCD trace object
  before return.
- rules-4x4_{base,flat}.json: drop synth__design__instance__area__
  stdcell, N/A when the flow consumes a pre-synthesized combined
  netlist via SYNTH_NETLIST_FILES.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
The Chisel generator was replaced by hand-written SystemVerilog in
the earlier SV conversion commits; MockArray.scala is no longer
referenced by any BUILD rule. Remove it and the now-empty scala
subtree.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
With test/orfs/mock-array switched to hand-written SystemVerilog, no
BUILD rule in this repo loads @rules_chisel, @rules_scala, or @maven
directly. Remove the dev-only bazel_deps, the chisel/scala_config/
scala_deps/maven extensions, the SCALA/CHISEL/FIRTOOL_RESOLVER version
constants, the maven_install.json lock file, and the
rules-chisel-dev-dep.patch used to keep rules_chisel dev-only.

rules_jvm_external is still pulled in transitively by grpc-java,
or-tools, and protobuf — that's fine, it just no longer needs to be
a top-level dependency here.

Regenerated MODULE.bazel.lock (-192 lines).

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
The new flow pre-synthesizes Element and multiplier in separate
orfs_synth targets and consumes the combined netlist via
SYNTH_NETLIST_FILES. At the MockArray top, Element is blackboxed
(SYNTH_BLACKBOXES = "multiplier Element"), so MockArray synthesis
only produces the top-level routing/glue — hence the much smaller
area/stdcell/wirelength numbers (e.g. 4x4 placeopt area 5719 -> 136,
8x8 finish area 22491 -> 343). Timing slack also tightens because
there are far fewer cells on any critical path.

Generated by:
  bazelisk run //test/orfs/mock-array:MockArray_{4x4,8x8}_{base,flat}_update_rules
then copying the staged rules.json from tmp/ over the checked-in
files.

Also drops synth__design__instance__area__stdcell from the 8x8
JSONs (already dropped from 4x4 earlier) - the flow consumes a
pre-synthesized netlist so the synth-time stdcell area metric is
N/A and was being emitted as "Will use N/A" by genRuleFile.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
…config

The MockArray_{name}_slang_synth targets all used variant = "netlist",
which made the 4x4 and 8x8 targets try to write the same output path
(results/asap7/MockArray/netlist/...). Bazel detected the conflicting
actions and refused to build. Use "{name}_netlist" so each config has
its own result directory.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Nothing in this repo referenced @circt after the Chisel removal —
firtool was the CIRCT tool used to lower FIRRTL to Verilog, which
is no longer part of any build target here.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
The compare_interfaces test was never ported over with the Chisel
removal — it required generating reference Verilog from the Chisel
generator at build time, which is the opposite of what this cleanup
is trying to achieve. Remove the stale reference from the Running
Tests section.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
@oharboe oharboe requested a review from maliberty April 17, 2026 15:12
@github-actions
Copy link
Copy Markdown
Contributor

clang-tidy review says "All clean, LGTM! 👍"

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request replaces the Chisel-based MockArray implementation with a SystemVerilog version, removing Scala and Chisel dependencies and updating the Bazel build and OpenROAD flow scripts. Feedback identifies a critical syntax error in MockArray.sv caused by duplicated generate block labels, which necessitates updates to hierarchical paths in the TCL scripts. Furthermore, the glob patterns for pin matching in the TCL scripts likely require adjustment to correctly match packed and unpacked array indices, and an unused reset input was found in the MockArray module.

Comment thread test/orfs/mock-array/MockArray.sv Outdated
puts "read_spef for Element macros"
for { set r 0 } { $r < $::env(ARRAY_ROWS) } { incr r } {
for { set c 0 } { $c < $::env(ARRAY_COLS) } { incr c } {
log_cmd read_spef -path "ces\[${r}\].ces\[${c}\].ces" \
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The hierarchical path ces\[${r}\].ces\[${c}\].ces is based on an invalid SystemVerilog structure in MockArray.sv where generate block labels are duplicated. Once the generate block labels in MockArray.sv are fixed to be unique, this path will need to be updated to match the new valid hierarchy.

Comment thread test/orfs/mock-array/element-io.tcl
Comment thread test/orfs/mock-array/io.tcl
parameter int DATA_WIDTH = 64
)(
input logic clock,
input logic reset,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The reset input to MockArray is declared but never used within the module. The rst inputs to the underlying Multiplier instances are all tied to 1'b0. If a reset is not necessary for this design, this input should be removed from the module's port list to improve clarity and avoid confusion.

  input  logic                  clock,

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well.... this is a test and interfaces can be fixed and inplementations may or may not use reset...

@maliberty
Copy link
Copy Markdown
Member

Looks like gemini has some thoughts to address before I look.

@oharboe
Copy link
Copy Markdown
Collaborator Author

oharboe commented Apr 17, 2026

out of sight, out of mind for now. I'm good with this change, but my focus is elsewhere right now, so I don't want to think about nursing it through.

@oharboe oharboe closed this Apr 17, 2026
@oharboe oharboe reopened this Apr 19, 2026
@github-actions
Copy link
Copy Markdown
Contributor

clang-tidy review says "All clean, LGTM! 👍"

Rename duplicated 'ces' generate labels in MockArray.sv to 'ces_row'
and 'ces_col' so labels are unique within their enclosing scope, and
update the load_mock_array.tcl read_spef path to match the new
hierarchy. Keep the instance name 'ces' so the leaf identifier still
matches the power scripts.

Also drop a stray blank line in MODULE.bazel to appease buildifier.

Signed-off-by: Øyvind Harboe <oyvind@ascenium.com>
@github-actions
Copy link
Copy Markdown
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@oharboe
Copy link
Copy Markdown
Collaborator Author

oharboe commented Apr 19, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request replaces the Chisel-based MockArray design with a native SystemVerilog implementation and updates the Bazel build flow to support hierarchical synthesis. Key changes include removing Scala/Chisel dependencies, adding MockArray.sv, and refactoring mock-array.bzl to manage netlist stitching. Feedback identifies potential duplicate module definition errors during synthesis; it is recommended to guard the multiplier stub and Element wrapper in MockArray.sv with preprocessor macros and update the build configuration to define these macros during top-level synthesis.

Comment on lines +10 to +17
module multiplier(
input logic [31:0] b,
input logic clk,
input logic rst,
output logic [31:0] o,
input logic [31:0] a
);
endmodule
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The multiplier stub module will cause duplicate module definition errors during hierarchical synthesis because it is also provided by multiplier.v. Since the build flow in mock-array.bzl concatenates the netlists, this stub should be guarded with `ifndef SYNTHESIS to avoid conflicts in the final stitched Verilog.

References
  1. Rely on the toolchain to handle blackboxes instead of providing stubs that conflict with actual implementations during netlist stitching.

Comment on lines +134 to +148
module Element(
input logic clock,
input logic [63:0] io_ins_left,
input logic [63:0] io_ins_up,
input logic [63:0] io_ins_right,
input logic [63:0] io_ins_down,
output logic [63:0] io_outs_left,
output logic [63:0] io_outs_up,
output logic [63:0] io_outs_right,
output logic [63:0] io_outs_down,
input logic [`ELEMENT_COLS-1:0] io_lsbIns,
output logic [`ELEMENT_COLS-1:0] io_lsbOuts
);
ElementInner #(.DATA_WIDTH(64), .COLS(`ELEMENT_COLS)) inner(.*);
endmodule
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The Element wrapper module is defined in the same file as MockArray. During hierarchical synthesis of MockArray, this definition will be included in the output netlist even if blackboxed, leading to duplicate module errors when stitched with the actual Element netlist. Consider guarding this definition with a macro (e.g., `ifndef BLACKBOX_ELEMENT) so it can be disabled when synthesizing the top-level array.

References
  1. Avoid duplicate module definitions in concatenated netlists by guarding sub-module wrappers during top-level synthesis.

arguments = {
"SYNTH_BLACKBOXES": "multiplier Element",
"SYNTH_HDL_FRONTEND": "slang",
"SYNTH_SLANG_ARGS": "--ignore-unknown-modules --empty-blackboxes -DELEMENT_COLS={}".format(config["cols"]),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To support the suggested guarding of the Element module in MockArray.sv during hierarchical synthesis, the BLACKBOX_ELEMENT macro should be defined here for the MockArray synthesis run.

References
  1. Define tunable parameters and control macros as named constants or arguments instead of relying on defaults.

@oharboe
Copy link
Copy Markdown
Collaborator Author

oharboe commented Apr 19, 2026

Claude Response to Gemini review

Thanks for the review. Status of each comment:

✅ Fixed (commit 0fd71c20a5)

  • Critical — duplicate generate-block label ces in MockArray.sv. Inner/outer loops now use ces_row / ces_col.
  • Criticalload_mock_array.tcl hierarchical path updated to ces_row[${r}].ces_col[${c}].ces.

❌ Not applicable — Tcl regex, not glob

  • Highelement-io.tcl io_lsbIns.* pattern.
  • Highio.tcl .* patterns on unpacked array ports.

match_pins in test/orfs/mock-array/util.tcl:38-56 uses Tcl regexp, not string match:

foreach pin [get_ports -regex .*] {
  set input [get_property $pin name]
  # We want the Tcl regex
  if { ![regexp $regex $input] } {
    continue
  }
  ...
}

In Tcl regex, . matches any character (including [), so io_lsbIns.* correctly matches io_lsbIns[0], io_lsbIns[1], …, and io_ins_down.* matches io_ins_down[0][0], etc. CI confirms I/O placement works. No change needed.

🚫 Rejected — covered in inline reply

  • Medium — unused reset on MockArray. Already replied: this is a test, interfaces can be fixed and implementations may or may not use reset.

❌ Not applicable — Yosys already strips blackboxes

  • Highmultiplier stub should be `ifndef SYNTHESIS-guarded.
  • HighElement wrapper should be `ifndef BLACKBOX_ELEMENT-guarded.
  • Medium — define BLACKBOX_ELEMENT in mock-array.bzl.

Verified locally by inspecting the synth output (1_2_yosys.v):

$ grep '^module ' bazel-bin/.../MockArray/4x4_netlist/1_2_yosys.v
module MockArray(reset, clock, io_ins_left, ...);

$ grep '^module ' bazel-bin/.../Element/4x4_slang/1_2_yosys.v
module Element(clock, io_ins_left, ...);

Each slang-synth output contains exactly one module definition. Yosys's write_verilog strips modules marked blackbox via SYNTH_BLACKBOXES, so the concatenated netlist (MockArray netlist + Element netlist + multiplier netlist) has no duplicates. There is no error — CI passes.

I also tried the proposed guards locally. Both variants break synthesis:

  • -DBLACKBOX_ELEMENT on the MockArray synth:
    ERROR: Module `\Element' referenced in module `\MockArray' in cell
    `\ces_row[3].ces_col[3].ces' is not part of the design.
    
  • -DBLACKBOX_MULTIPLIER on the Element synth:
    ERROR: Module `\multiplier' referenced in module
    `\Multiplier$Element.inner.mult_left' in cell `\mult_inst' is not part of the design.
    

slang's --ignore-unknown-modules --empty-blackboxes silence the parse-time warning but don't register a blackbox in Yosys's design. The stub/wrapper definitions are required during slang elaboration so Yosys can derive port lists; the SYNTH_BLACKBOXES pass then strips the bodies before write_verilog. Adding the guards would regress a working flow.

Result

No new commit is warranted. All actionable critical issues were resolved in 0fd71c20a5; the remaining suggestions are based on an incorrect tooling model (Tcl regex vs glob, and Yosys blackbox semantics).

@oharboe
Copy link
Copy Markdown
Collaborator Author

oharboe commented Apr 19, 2026

@maliberty as long as this passes, I think we might be better off merging it and cleaning it up more later?

At least SystemVerilog means more people will touch it with a ten foot pole now...?

@oharboe
Copy link
Copy Markdown
Collaborator Author

oharboe commented Apr 19, 2026

@maliberty I dont think it is necessarily a bad thing that the test is a bit fuzzed(different).mock array tests are either very effective pre merge or there is little breakage in this area these days...

@oharboe
Copy link
Copy Markdown
Collaborator Author

oharboe commented Apr 19, 2026

something is wrong...

image

@oharboe oharboe closed this Apr 19, 2026
oharboe and others added 2 commits April 19, 2026 18:04
…m flatten regression

The SystemVerilog rewrite was pre-synthesizing MockArray, Element and
multiplier separately and concatenating the three netlists into one
SYNTH_NETLIST_FILES input. OpenROAD then linked the Element instances in
MockArray against the full Element body in the combined file rather than
the Element LEF/LIB abstract supplied via `macros=[...]`, flattening the
N x N grid of Element macros into top-level std cells at floorplan time
(0 Element macros found, instance area dropping from ~5700 to ~140).

Fix:
  * Feed only the MockArray slang netlist to the flow so Element (and
    the inner multiplier) stay as unresolved references resolved by the
    macro abstract. Same netlist is used for both variants; base vs flat
    differ only in OPENROAD_HIERARCHICAL.
  * Pin the layout with an explicit, parameterized
    `place_mock_array.tcl` (MACRO_PLACEMENT_TCL) for both variants so
    RTLMP cannot drift off-grid or miss M5 track alignment at 8x8.
  * Restore master's rules-*.json caps; the prior HEAD values had been
    regenerated against the flattened flow. Drop
    `synth__design__instance__area__stdcell` which is N/A when the flow
    consumes a pre-synthesized netlist.

Add a regression test, `MockArray_{4x4,8x8}_{base,flat}_macro_layout_test`,
built on orfs_run + ok.sh. `check_macro_layout.tcl` loads the floorplan
ODB, locates Element macro instances, and verifies:
  * count == ARRAY_ROWS * ARRAY_COLS,
  * exactly ARRAY_ROWS distinct row-Y values (row 0 bottom, increasing up),
  * each row has ARRAY_COLS macros at consistent X positions,
  * columns are abutted (dx == macro width),
  * all macros share one orientation.

Validated on origin/master (all four tests pass) before fixing HEAD.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
@oharboe oharboe reopened this Apr 19, 2026
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
@github-actions
Copy link
Copy Markdown
Contributor

clang-tidy review says "All clean, LGTM! 👍"

1 similar comment
@github-actions
Copy link
Copy Markdown
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@oharboe
Copy link
Copy Markdown
Collaborator Author

oharboe commented Apr 19, 2026

Looks sane now:

bazelisk run --//:platform=gui test/orfs/mock-array:MockArray_8x8_base_final gui_final
image

@github-actions
Copy link
Copy Markdown
Contributor

clang-tidy review says "All clean, LGTM! 👍"

Split the orientation-mismatch error message across two lines so
check_macro_layout.tcl passes tclint's 100-char line-length rule.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
@github-actions
Copy link
Copy Markdown
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@oharboe
Copy link
Copy Markdown
Collaborator Author

oharboe commented Apr 19, 2026

@maliberty I just merged w master and pr-head works. CI problem?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants