Conversation
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>
|
clang-tidy review says "All clean, LGTM! 👍" |
There was a problem hiding this comment.
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.
| 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" \ |
There was a problem hiding this comment.
| parameter int DATA_WIDTH = 64 | ||
| )( | ||
| input logic clock, | ||
| input logic reset, |
There was a problem hiding this comment.
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,
There was a problem hiding this comment.
well.... this is a test and interfaces can be fixed and inplementations may or may not use reset...
|
Looks like gemini has some thoughts to address before I look. |
|
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. |
|
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>
|
clang-tidy review says "All clean, LGTM! 👍" |
|
/gemini review |
There was a problem hiding this comment.
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.
| module multiplier( | ||
| input logic [31:0] b, | ||
| input logic clk, | ||
| input logic rst, | ||
| output logic [31:0] o, | ||
| input logic [31:0] a | ||
| ); | ||
| endmodule |
There was a problem hiding this comment.
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
- Rely on the toolchain to handle blackboxes instead of providing stubs that conflict with actual implementations during netlist stitching.
| 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 |
There was a problem hiding this comment.
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
- 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"]), |
There was a problem hiding this comment.
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
- Define tunable parameters and control macros as named constants or arguments instead of relying on defaults.
Claude Response to Gemini reviewThanks for the review. Status of each comment: ✅ Fixed (commit
|
|
@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...? |
|
@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... |
…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>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
|
clang-tidy review says "All clean, LGTM! 👍" |
1 similar comment
|
clang-tidy review says "All clean, LGTM! 👍" |
|
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>
|
clang-tidy review says "All clean, LGTM! 👍" |
|
@maliberty I just merged w master and pr-head works. CI problem? |
|
@vvbandeira @maliberty I think this is just some CI outage https://jenkins.openroad.tools/job/OpenROAD-Public/job/PR-10172-merge/6/display/redirect
|



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