Skip to content

Drop chisel#10172

Closed
oharboe wants to merge 9 commits intoThe-OpenROAD-Project:masterfrom
oharboe:drop-chisel
Closed

Drop chisel#10172
oharboe wants to merge 9 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 on lines +183 to +184
for (genvar r = 0; r < HEIGHT; r++) begin : ces
for (genvar c = 0; c < WIDTH; c++) begin : 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 generate block label ces is duplicated for the inner and outer loops. This is not valid SystemVerilog, as generate block labels must be unique within their scope. This will cause a synthesis error.

You should use unique labels for the generate blocks. For example:

  for (genvar r = 0; r < HEIGHT; r++) begin : ces_row
    for (genvar c = 0; c < WIDTH; c++) begin : ces_col
      Element ces(
        ...
      );
    end
  end

After fixing this, you will also need to update test/orfs/mock-array/load_mock_array.tcl to use the correct hierarchical path that results from this change (e.g., ces_row[${r}].ces_col[${c}].ces).

  for (genvar r = 0; r < HEIGHT; r++) begin : ces_row
    for (genvar c = 0; c < WIDTH; c++) begin : ces_col

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 on lines +20 to +22
{*}[match_pins io_lsbIns.*]] \
[concat \
{*}[match_pins io_lsbOuts_.*]]]]
{*}[match_pins io_lsbOuts.*]]]]
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 glob patterns io_lsbIns.* and io_lsbOuts.* are likely incorrect for matching the pins of the io_lsbIns and io_lsbOuts ports. These ports are defined as packed vectors in MockArray.sv, and synthesis tools typically generate pin names like io_lsbIns[0], io_lsbIns[1], etc. The . character in a Tcl glob pattern matches a literal dot, not the brackets and index. This will likely cause I/O placement to fail.

Please use [*] to match the array indices.

    {*}[match_pins io_lsbIns[*] ]] \
    [concat \
      {*}[match_pins io_lsbOuts[*] ]]]

Comment on lines +6 to +20
{*}[match_pins io_ins_down.*] \
{*}[match_pins io_outs_up.*]] \
bottom \
[concat \
{*}[match_pins io_ins_up_.*] \
{*}[match_pins io_outs_down_.*]] \
{*}[match_pins io_ins_up.*] \
{*}[match_pins io_outs_down.*]] \
left \
[concat \
{*}[match_pins io_ins_right_.*] \
{*}[match_pins io_outs_left_.*]] \
{*}[match_pins io_ins_right.*] \
{*}[match_pins io_outs_left.*]] \
right \
[concat \
{*}[match_pins io_ins_left_.*] \
{*}[match_pins io_outs_right_.*] \
{*}[match_pins io_lsbs_.*]]]
{*}[match_pins io_ins_left.*] \
{*}[match_pins io_outs_right.*] \
{*}[match_pins io_lsbs.*]]]
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 glob patterns using .* to match pins of unpacked array ports (e.g., io_ins_down.*) are likely incorrect. Synthesis tools typically flatten unpacked arrays into pins with names like port_name[0][0], port_name[0][1], etc. The . in the glob pattern matches a literal dot and will likely fail to match these pins, causing I/O placement to fail.

You should use [*] to match array indices. For the multi-dimensional array ports in this file, a pattern like io_ins_down[*][*] might be necessary. Please verify the exact naming convention produced by your synthesis tool and adjust the glob patterns accordingly.

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,

@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
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