From cdc728b6f009ba9faa9829e26332f428896a0b77 Mon Sep 17 00:00:00 2001 From: Gus Smith Date: Fri, 20 Feb 2026 09:33:51 -0800 Subject: [PATCH 001/354] Suggest use of YW when possible --- passes/sat/sim.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 27d6d12c1..5392cd9e5 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -2624,6 +2624,7 @@ struct SimPass : public Pass { log(" -r \n"); log(" read simulation or formal results file\n"); log(" File formats supported: FST, VCD, AIW, WIT and .yw\n"); + log(" Yosys witness (.yw) replay is preferred when possible.\n"); log(" VCD support requires vcd2fst external tool to be present\n"); log("\n"); log(" -width \n"); From b454582f540753343524d33e7d2e3ad8ca95972b Mon Sep 17 00:00:00 2001 From: Gus Smith Date: Fri, 20 Feb 2026 11:00:59 -0800 Subject: [PATCH 002/354] Detect undriven and error/warn --- passes/sat/sim.cc | 81 ++++++++++++++++++++++++++++++++--- tests/sim/undriven_replay.v | 7 +++ tests/sim/undriven_replay.vcd | 15 +++++++ tests/sim/undriven_replay.ys | 10 +++++ 4 files changed, 108 insertions(+), 5 deletions(-) create mode 100644 tests/sim/undriven_replay.v create mode 100644 tests/sim/undriven_replay.vcd create mode 100644 tests/sim/undriven_replay.ys diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 5392cd9e5..bd723f5f1 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -26,6 +26,7 @@ #include "kernel/yw.h" #include "kernel/json.h" #include "kernel/fmt.h" +#include "kernel/drivertools.h" #include @@ -125,6 +126,8 @@ struct SimShared bool serious_asserts = false; bool fst_noinit = false; bool initstate = true; + bool undriven_check = true; + bool undriven_warning = false; }; void zinit(Const &v) @@ -426,7 +429,7 @@ struct SimInstance Const value = builder.build(); if (shared->debug) - log("[%s] get %s: %s\n", hiername(), log_signal(sig), log_signal(value)); + log("[%s] get %s: %s\n", hiername(), log_signal(sig, true), log_signal(value, true)); return value; } @@ -445,7 +448,7 @@ struct SimInstance } if (shared->debug) - log("[%s] set %s: %s\n", hiername(), log_signal(sig), log_signal(value)); + log("[%s] set %s: %s\n", hiername(), log_signal(sig, true), log_signal(value, true)); return did_something; } @@ -1192,6 +1195,54 @@ struct SimInstance child.second->addAdditionalInputs(); } + // Preconditions / assumptions: + // 1) fst_handles is populated for this instance (0 handle means not in trace). + // 2) fst_inputs is finalized (top-level inputs + addAdditionalInputs() for $anyseq). + // 3) module has no processes (sim enforces proc-lowered input before this point). + // 4) sigmap is valid for per-bit queries on this instance. + // 5) shared->fst is active, i.e. this is called from FST/VCD replay flow. + int checkUndrivenReplaySignals() + { + int issue_count = 0; + bool has_replay_candidates = false; + + for (auto &item : fst_handles) + if (item.second != 0 && !fst_inputs.count(item.first)) { + has_replay_candidates = true; + break; + } + + if (has_replay_candidates) { + DriverMap drivermap(module->design); + drivermap.add(module); + + for (auto &item : fst_handles) { + Wire *wire = item.first; + if (item.second == 0 || fst_inputs.count(wire)) + continue; + + SigSpec undriven; + for (auto bit : sigmap(wire)) + if (bit.wire != nullptr && drivermap(DriveBit(bit)).is_none()) + undriven.append(bit); + + undriven.sort_and_unify(); + if (undriven.empty()) + continue; + + issue_count++; + std::string wire_name = scope + "." + RTLIL::unescape_id(wire->name); + log_warning("Input trace contains undriven signal `%s` (%s); values for this signal are not replayed from FST/VCD input.\n", + wire_name.c_str(), log_signal(undriven, true)); + } + } + + for (auto child : children) + issue_count += child.second->checkUndrivenReplaySignals(); + + return issue_count; + } + bool setInputs() { bool did_something = false; @@ -1248,7 +1299,7 @@ struct SimInstance } else if (shared->sim_mode == SimulationMode::gate && !fst_val.is_fully_def()) { // FST data contains X for(int i=0;isim_mode == SimulationMode::gold && !sim_val.is_fully_def()) { // sim data contains X for(int i=0;iaddAdditionalInputs(); + if (undriven_check) { + int issue_count = top->checkUndrivenReplaySignals(); + if (issue_count > 0 && !undriven_warning) + log_cmd_error("Found %d undriven signal%s in the replay trace. Use -undriven-warn to continue or -no-undriven-check to disable this check.\n", + issue_count, issue_count == 1 ? "" : "s"); + } uint64_t startCount = 0; uint64_t stopCount = 0; @@ -2627,6 +2684,12 @@ struct SimPass : public Pass { log(" Yosys witness (.yw) replay is preferred when possible.\n"); log(" VCD support requires vcd2fst external tool to be present\n"); log("\n"); + log(" -no-undriven-check\n"); + log(" skip undriven-signal checks for FST/VCD replay\n"); + log("\n"); + log(" -undriven-warn\n"); + log(" downgrade undriven-signal replay errors to warnings\n"); + log("\n"); log(" -width \n"); log(" cycle width in generated simulation output (must be divisible by 2).\n"); log("\n"); @@ -2844,6 +2907,14 @@ struct SimPass : public Pass { worker.fst_noinit = true; continue; } + if (args[argidx] == "-no-undriven-check") { + worker.undriven_check = false; + continue; + } + if (args[argidx] == "-undriven-warn") { + worker.undriven_warning = true; + continue; + } if (args[argidx] == "-x") { worker.ignore_x = true; continue; diff --git a/tests/sim/undriven_replay.v b/tests/sim/undriven_replay.v new file mode 100644 index 000000000..501f438a1 --- /dev/null +++ b/tests/sim/undriven_replay.v @@ -0,0 +1,7 @@ +module undriven_replay ( + input wire in, + output wire out, + output wire undrv +); + assign out = in; +endmodule diff --git a/tests/sim/undriven_replay.vcd b/tests/sim/undriven_replay.vcd new file mode 100644 index 000000000..e9cc35ae5 --- /dev/null +++ b/tests/sim/undriven_replay.vcd @@ -0,0 +1,15 @@ +$version Yosys $end +$scope module undriven_replay $end +$var wire 1 ! in $end +$var wire 1 " out $end +$var wire 1 # undrv $end +$upscope $end +$enddefinitions $end +#0 +b0 ! +b0 " +b1 # +#10 +b1 ! +b1 " +b0 # diff --git a/tests/sim/undriven_replay.ys b/tests/sim/undriven_replay.ys new file mode 100644 index 000000000..9766a8d60 --- /dev/null +++ b/tests/sim/undriven_replay.ys @@ -0,0 +1,10 @@ +read_verilog undriven_replay.v +prep -top undriven_replay + +logger -expect error "Found 1 undriven signal in the replay trace" 1 +sim -r undriven_replay.vcd -scope undriven_replay -q + +logger -expect warning "Input trace contains undriven signal" 1 +sim -r undriven_replay.vcd -scope undriven_replay -q -undriven-warn + +sim -r undriven_replay.vcd -scope undriven_replay -q -no-undriven-check From c0f1654028736cd88d2fa7cae5b0335371e8e866 Mon Sep 17 00:00:00 2001 From: Gus Smith Date: Mon, 23 Feb 2026 10:27:36 -0800 Subject: [PATCH 003/354] Expand test into three tests for three cases (1) no check, (2) check with warning, (3) check with error. Previously the single test was not testing all cases, as it was exiting after the first error. --- tests/sim/undriven_replay.ys | 5 ----- tests/sim/undriven_replay_nocheck.ys | 4 ++++ tests/sim/undriven_replay_warn.ys | 5 +++++ 3 files changed, 9 insertions(+), 5 deletions(-) create mode 100644 tests/sim/undriven_replay_nocheck.ys create mode 100644 tests/sim/undriven_replay_warn.ys diff --git a/tests/sim/undriven_replay.ys b/tests/sim/undriven_replay.ys index 9766a8d60..854a40049 100644 --- a/tests/sim/undriven_replay.ys +++ b/tests/sim/undriven_replay.ys @@ -3,8 +3,3 @@ prep -top undriven_replay logger -expect error "Found 1 undriven signal in the replay trace" 1 sim -r undriven_replay.vcd -scope undriven_replay -q - -logger -expect warning "Input trace contains undriven signal" 1 -sim -r undriven_replay.vcd -scope undriven_replay -q -undriven-warn - -sim -r undriven_replay.vcd -scope undriven_replay -q -no-undriven-check diff --git a/tests/sim/undriven_replay_nocheck.ys b/tests/sim/undriven_replay_nocheck.ys new file mode 100644 index 000000000..dcb1cfc92 --- /dev/null +++ b/tests/sim/undriven_replay_nocheck.ys @@ -0,0 +1,4 @@ +read_verilog undriven_replay.v +prep -top undriven_replay + +sim -r undriven_replay.vcd -scope undriven_replay -q -no-undriven-check diff --git a/tests/sim/undriven_replay_warn.ys b/tests/sim/undriven_replay_warn.ys new file mode 100644 index 000000000..ca3b1937c --- /dev/null +++ b/tests/sim/undriven_replay_warn.ys @@ -0,0 +1,5 @@ +read_verilog undriven_replay.v +prep -top undriven_replay + +logger -expect warning "Input trace contains undriven signal" 1 +sim -r undriven_replay.vcd -scope undriven_replay -q -undriven-warn From 366f98ae25bf45be94a6ea8118abe431eb676bdf Mon Sep 17 00:00:00 2001 From: Gus Smith Date: Mon, 23 Feb 2026 11:51:54 -0800 Subject: [PATCH 004/354] ADd clarification --- passes/sat/sim.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index bd723f5f1..ddc256384 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -2685,7 +2685,7 @@ struct SimPass : public Pass { log(" VCD support requires vcd2fst external tool to be present\n"); log("\n"); log(" -no-undriven-check\n"); - log(" skip undriven-signal checks for FST/VCD replay\n"); + log(" skip undriven-signal checks for FST/VCD replay (can be expensive for large designs)\n"); log("\n"); log(" -undriven-warn\n"); log(" downgrade undriven-signal replay errors to warnings\n"); From 89d83a34104f0cf5e6010494e6debbcc6a15f3b6 Mon Sep 17 00:00:00 2001 From: Codexplorer Date: Fri, 9 Jan 2026 15:44:14 -0800 Subject: [PATCH 005/354] Logging now handles classes with an IdString "name" member --- kernel/io.h | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/kernel/io.h b/kernel/io.h index 171f47a80..1585987b8 100644 --- a/kernel/io.h +++ b/kernel/io.h @@ -197,6 +197,28 @@ check_format(std::string_view fmt, int fmt_start, bool *has_escapes, FoundFormat ensure_no_format_spec(fmt, fmt_start, has_escapes); } +template +static auto has_name_member_imp(int) + -> decltype(static_cast(std::declval().name), std::true_type{}); + +template +static auto has_name_member_imp(long) + -> std::false_type; + +template +struct has_name_member : decltype(has_name_member_imp(0)){}; + +template +static auto ptr_has_name_member_imp(int) + -> decltype(static_cast(std::declval()->name), std::true_type{}); + +template +static auto ptr_has_name_member_imp(long) + -> std::false_type; + +template +struct ptr_has_name_member : decltype(ptr_has_name_member_imp(0)){}; + // Check that the format string `fmt.substr(fmt_start)` is valid for the given type arguments. // Fills `specs` with the FoundFormatSpecs found in the format string. // `int_args_consumed` is the number of int arguments already consumed to satisfy the @@ -245,7 +267,9 @@ constexpr void check_format(std::string_view fmt, int fmt_start, bool *has_escap if constexpr (!std::is_convertible_v && !std::is_convertible_v && !std::is_convertible_v && - !std::is_convertible_v) { + !std::is_convertible_v && + !has_name_member() && + !ptr_has_name_member()) { YOSYS_ABORT("Expected type convertible to char *"); } *specs = found; @@ -343,6 +367,16 @@ inline void format_emit_one(std::string &result, std::string_view fmt, const Fou format_emit_idstring(result, spec, dynamic_ints, num_dynamic_ints, s); return; } + if constexpr (has_name_member()) { + const std::string &s = arg.name.unescape(); + format_emit_string(result, spec, dynamic_ints, num_dynamic_ints, s); + return; + } + if constexpr (ptr_has_name_member()) { + const std::string &s = arg->name.unescape(); + format_emit_string(result, spec, dynamic_ints, num_dynamic_ints, s); + return; + } break; case CONVSPEC_VOID_PTR: if constexpr (std::is_convertible_v) { From e41b969da25fee5ccd8542b8c4c45824ddae568b Mon Sep 17 00:00:00 2001 From: Codexplorer Date: Fri, 8 May 2026 00:01:43 -0700 Subject: [PATCH 006/354] Refactored uses of log_id() --- backends/aiger/aiger.cc | 40 ++++---- backends/aiger/xaiger.cc | 28 +++--- backends/aiger2/aiger.cc | 30 +++--- backends/blif/blif.cc | 6 +- backends/btor/btor.cc | 59 ++++++------ backends/cxxrtl/cxxrtl_backend.cc | 30 +++--- backends/edif/edif.cc | 10 +- backends/firrtl/firrtl.cc | 28 +++--- backends/intersynth/intersynth.cc | 30 +++--- backends/json/json.cc | 6 +- backends/simplec/simplec.cc | 46 +++++----- backends/smt2/smt2.cc | 56 +++++------ backends/smv/smv.cc | 14 +-- backends/spice/spice.cc | 6 +- backends/table/table.cc | 12 +-- backends/verilog/verilog_backend.cc | 4 +- .../source/code_examples/extensions/my_cmd.cc | 4 +- examples/cxx-api/scopeinfo_example.cc | 12 +-- frontends/aiger/aigerparse.cc | 16 ++-- frontends/aiger2/xaiger.cc | 8 +- frontends/ast/ast.cc | 10 +- frontends/ast/genrtlil.cc | 4 +- frontends/ast/simplify.cc | 2 +- frontends/blif/blifparse.cc | 2 +- frontends/json/jsonparse.cc | 54 +++++------ frontends/rpc/rpc_frontend.cc | 2 +- frontends/rtlil/rtlil_frontend.cc | 2 +- frontends/verific/verific.cc | 12 +-- kernel/cost.cc | 2 +- kernel/drivertools.cc | 6 +- kernel/ff.cc | 2 +- kernel/functional.cc | 8 +- kernel/log.cc | 2 +- kernel/mem.cc | 8 +- kernel/modtools.h | 4 +- kernel/rtlil.cc | 32 +++---- kernel/rtlil_bufnorm.cc | 12 +-- kernel/satgen.cc | 4 +- kernel/scopeinfo.h | 2 +- kernel/timinginfo.h | 22 ++--- kernel/yosys.cc | 12 +-- passes/cmds/abstract.cc | 8 +- passes/cmds/autoname.cc | 10 +- passes/cmds/box_derive.cc | 4 +- passes/cmds/bugpoint.cc | 20 ++-- passes/cmds/check.cc | 32 +++---- passes/cmds/chformal.cc | 4 +- passes/cmds/connect.cc | 2 +- passes/cmds/connwrappers.cc | 4 +- passes/cmds/design.cc | 4 +- passes/cmds/design_equal.cc | 72 +++++++-------- passes/cmds/dft_tag.cc | 12 +-- passes/cmds/edgetypes.cc | 8 +- passes/cmds/example_dt.cc | 10 +- passes/cmds/future.cc | 4 +- passes/cmds/linecoverage.cc | 6 +- passes/cmds/ltp.cc | 8 +- passes/cmds/portarcs.cc | 6 +- passes/cmds/portlist.cc | 4 +- passes/cmds/printattrs.cc | 10 +- passes/cmds/rename.cc | 8 +- passes/cmds/sdc/sdc.cc | 2 +- passes/cmds/select.cc | 2 +- passes/cmds/setattr.cc | 4 +- passes/cmds/show.cc | 8 +- passes/cmds/splice.cc | 2 +- passes/cmds/splitcells.cc | 10 +- passes/cmds/sta.cc | 16 ++-- passes/cmds/stat.cc | 22 ++--- passes/cmds/timeest.cc | 16 ++-- passes/cmds/torder.cc | 6 +- passes/cmds/trace.cc | 12 +-- passes/cmds/viz.cc | 8 +- passes/cmds/wrapcell.cc | 8 +- passes/cmds/xprop.cc | 12 +-- passes/equiv/equiv_induct.cc | 4 +- passes/equiv/equiv_make.cc | 14 +-- passes/equiv/equiv_mark.cc | 2 +- passes/equiv/equiv_miter.cc | 12 +-- passes/equiv/equiv_purge.cc | 6 +- passes/equiv/equiv_remove.cc | 2 +- passes/equiv/equiv_simple.cc | 10 +- passes/equiv/equiv_status.cc | 6 +- passes/equiv/equiv_struct.cc | 14 +-- passes/fsm/fsm_detect.cc | 10 +- passes/fsm/fsm_expand.cc | 6 +- passes/fsm/fsm_export.cc | 2 +- passes/fsm/fsm_info.cc | 2 +- passes/fsm/fsm_recode.cc | 2 +- passes/hierarchy/flatten.cc | 10 +- passes/hierarchy/hierarchy.cc | 40 ++++---- passes/hierarchy/keep_hierarchy.cc | 8 +- passes/hierarchy/uniquify.cc | 6 +- passes/memory/memory_bram.cc | 66 ++++++------- passes/memory/memory_libmap.cc | 34 +++---- passes/memory/memory_memx.cc | 2 +- passes/memory/memory_share.cc | 6 +- passes/opt/muxpack.cc | 4 +- passes/opt/opt_balance_tree.cc | 4 +- passes/opt/opt_clean/inits.cc | 2 +- passes/opt/opt_demorgan.cc | 2 +- passes/opt/opt_dff.cc | 44 ++++----- passes/opt/opt_expr.cc | 54 +++++------ passes/opt/opt_hier.cc | 26 +++--- passes/opt/opt_lut.cc | 12 +-- passes/opt/opt_lut_ins.cc | 4 +- passes/opt/opt_mem.cc | 6 +- passes/opt/opt_mem_feedback.cc | 4 +- passes/opt/opt_mem_widen.cc | 2 +- passes/opt/opt_muxtree.cc | 12 +-- passes/opt/opt_share.cc | 4 +- passes/opt/pmux2shiftx.cc | 12 +-- passes/opt/share.cc | 38 ++++---- passes/opt/wreduce.cc | 30 +++--- passes/pmgen/generate.h | 4 +- passes/pmgen/test_pmgen.cc | 16 ++-- passes/proc/proc_arst.cc | 2 +- passes/proc/proc_clean.cc | 2 +- passes/proc/proc_dlatch.cc | 2 +- passes/proc/proc_memwr.cc | 2 +- passes/proc/proc_rmdead.cc | 4 +- passes/sat/assertpmux.cc | 2 +- passes/sat/async2sync.cc | 10 +- passes/sat/clk2fflogic.cc | 18 ++-- passes/sat/cutpoint.cc | 8 +- passes/sat/eval.cc | 20 ++-- passes/sat/expose.cc | 4 +- passes/sat/fmcombine.cc | 16 ++-- passes/sat/formalff.cc | 62 ++++++------- passes/sat/mutate.cc | 38 ++++---- passes/sat/qbfsat.cc | 2 +- passes/sat/recover_names.cc | 6 +- passes/sat/sat.cc | 2 +- passes/sat/sim.cc | 92 +++++++++---------- passes/sat/supercover.cc | 2 +- passes/sat/synthprop.cc | 10 +- passes/techmap/abc.cc | 2 +- passes/techmap/abc9.cc | 8 +- passes/techmap/abc9_ops.cc | 78 ++++++++-------- passes/techmap/abc_new.cc | 2 +- passes/techmap/aigmap.cc | 6 +- passes/techmap/alumacc.cc | 24 ++--- passes/techmap/arith_tree.cc | 2 +- passes/techmap/attrmap.cc | 14 +-- passes/techmap/attrmvcp.cc | 4 +- passes/techmap/booth.cc | 6 +- passes/techmap/bufnorm.cc | 8 +- passes/techmap/cellmatch.cc | 18 ++-- passes/techmap/clkbufmap.cc | 4 +- passes/techmap/deminout.cc | 2 +- passes/techmap/dffinit.cc | 8 +- passes/techmap/dfflegalize.cc | 8 +- passes/techmap/extract.cc | 12 +-- passes/techmap/extract_counter.cc | 14 +-- passes/techmap/extract_fa.cc | 14 +-- passes/techmap/extractinv.cc | 4 +- passes/techmap/flowmap.cc | 18 ++-- passes/techmap/insbuf.cc | 8 +- passes/techmap/iopadmap.cc | 18 ++-- passes/techmap/lut2bmux.cc | 2 +- passes/techmap/lut2mux.cc | 2 +- passes/techmap/maccmap.cc | 2 +- passes/techmap/muxcover.cc | 2 +- passes/techmap/shregmap.cc | 2 +- passes/techmap/simplemap.cc | 2 +- passes/techmap/techmap.cc | 88 +++++++++--------- passes/techmap/tribuf.cc | 2 +- passes/techmap/zinit.cc | 2 +- passes/tests/raise_error.cc | 2 +- passes/tests/test_cell.cc | 32 +++---- techlibs/anlogic/anlogic_fixcarry.cc | 4 +- techlibs/efinix/efinix_fixcarry.cc | 4 +- techlibs/greenpak4/greenpak4_dffinv.cc | 2 +- techlibs/ice40/ice40_dsp.cc | 20 ++-- techlibs/ice40/ice40_opt.cc | 6 +- techlibs/lattice/lattice_gsr.cc | 8 +- techlibs/microchip/microchip_dffopt.cc | 4 +- techlibs/microchip/microchip_dsp.cc | 18 ++-- techlibs/quicklogic/ql_bram_merge.cc | 6 +- techlibs/quicklogic/ql_bram_types.cc | 2 +- techlibs/quicklogic/ql_dsp_io_regs.cc | 6 +- techlibs/quicklogic/ql_dsp_macc.cc | 4 +- techlibs/quicklogic/ql_dsp_simd.cc | 6 +- techlibs/xilinx/xilinx_dffopt.cc | 4 +- techlibs/xilinx/xilinx_dsp.cc | 52 +++++------ techlibs/xilinx/xilinx_srl.cc | 12 +-- 186 files changed, 1219 insertions(+), 1220 deletions(-) diff --git a/backends/aiger/aiger.cc b/backends/aiger/aiger.cc index 0c49e84b8..1320937a0 100644 --- a/backends/aiger/aiger.cc +++ b/backends/aiger/aiger.cc @@ -340,7 +340,7 @@ struct AigerWriter if (cell->type == ID($scopeinfo)) continue; - log_error("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell)); + log_error("Unsupported cell type: %s (%s)\n", cell->type.unescape(), cell); } for (auto bit : unused_bits) @@ -349,10 +349,10 @@ struct AigerWriter if (!undriven_bits.empty()) { undriven_bits.sort(); for (auto bit : undriven_bits) { - log_warning("Treating undriven bit %s.%s like $anyseq.\n", log_id(module), log_signal(bit)); + log_warning("Treating undriven bit %s.%s like $anyseq.\n", module, log_signal(bit)); input_bits.insert(bit); } - log_warning("Treating a total of %d undriven bits in %s like $anyseq.\n", GetSize(undriven_bits), log_id(module)); + log_warning("Treating a total of %d undriven bits in %s like $anyseq.\n", GetSize(undriven_bits), module); } init_map.sort(); @@ -635,35 +635,35 @@ struct AigerWriter int a = aig_map.at(sig[i]); log_assert((a & 1) == 0); if (GetSize(wire) != 1) - symbols[stringf("i%d", (a >> 1)-1)].push_back(stringf("%s[%d]", log_id(wire), i)); + symbols[stringf("i%d", (a >> 1)-1)].push_back(stringf("%s[%d]", wire, i)); else - symbols[stringf("i%d", (a >> 1)-1)].push_back(stringf("%s", log_id(wire))); + symbols[stringf("i%d", (a >> 1)-1)].push_back(stringf("%s", wire)); } if (wire->port_output) { int o = ordered_outputs.at(SigSpec(wire, i)); if (GetSize(wire) != 1) - symbols[stringf("%c%d", miter_mode ? 'b' : 'o', o)].push_back(stringf("%s[%d]", log_id(wire), i)); + symbols[stringf("%c%d", miter_mode ? 'b' : 'o', o)].push_back(stringf("%s[%d]", wire, i)); else - symbols[stringf("%c%d", miter_mode ? 'b' : 'o', o)].push_back(stringf("%s", log_id(wire))); + symbols[stringf("%c%d", miter_mode ? 'b' : 'o', o)].push_back(stringf("%s", wire)); } if (init_inputs.count(sig[i])) { int a = init_inputs.at(sig[i]); log_assert((a & 1) == 0); if (GetSize(wire) != 1) - symbols[stringf("i%d", (a >> 1)-1)].push_back(stringf("init:%s[%d]", log_id(wire), i)); + symbols[stringf("i%d", (a >> 1)-1)].push_back(stringf("init:%s[%d]", wire, i)); else - symbols[stringf("i%d", (a >> 1)-1)].push_back(stringf("init:%s", log_id(wire))); + symbols[stringf("i%d", (a >> 1)-1)].push_back(stringf("init:%s", wire)); } if (ordered_latches.count(sig[i])) { int l = ordered_latches.at(sig[i]); const char *p = (zinit_mode && (aig_latchinit.at(l) == 1)) ? "!" : ""; if (GetSize(wire) != 1) - symbols[stringf("l%d", l)].push_back(stringf("%s%s[%d]", p, log_id(wire), i)); + symbols[stringf("l%d", l)].push_back(stringf("%s%s[%d]", p, wire, i)); else - symbols[stringf("l%d", l)].push_back(stringf("%s%s", p, log_id(wire))); + symbols[stringf("l%d", l)].push_back(stringf("%s%s", p, wire)); } } } @@ -705,30 +705,30 @@ struct AigerWriter int index = no_startoffset ? i : (wire->start_offset+i); if (verbose_map) - wire_lines[a] += stringf("wire %d %d %s\n", a, index, log_id(wire)); + wire_lines[a] += stringf("wire %d %d %s\n", a, index, wire); if (wire->port_input) { log_assert((a & 1) == 0); - input_lines[a] += stringf("input %d %d %s\n", (a >> 1)-1, index, log_id(wire)); + input_lines[a] += stringf("input %d %d %s\n", (a >> 1)-1, index, wire); } if (wire->port_output) { int o = ordered_outputs.at(SigSpec(wire, i)); - output_lines[o] += stringf("output %d %d %s\n", o, index, log_id(wire)); + output_lines[o] += stringf("output %d %d %s\n", o, index, wire); } if (init_inputs.count(sig[i])) { int a = init_inputs.at(sig[i]); log_assert((a & 1) == 0); - init_lines[a] += stringf("init %d %d %s\n", (a >> 1)-1, index, log_id(wire)); + init_lines[a] += stringf("init %d %d %s\n", (a >> 1)-1, index, wire); } if (ordered_latches.count(sig[i])) { int l = ordered_latches.at(sig[i]); if (zinit_mode && (aig_latchinit.at(l) == 1)) - latch_lines[l] += stringf("invlatch %d %d %s\n", l, index, log_id(wire)); + latch_lines[l] += stringf("invlatch %d %d %s\n", l, index, wire); else - latch_lines[l] += stringf("latch %d %d %s\n", l, index, log_id(wire)); + latch_lines[l] += stringf("latch %d %d %s\n", l, index, wire); } } } @@ -1027,12 +1027,12 @@ struct AigerBackend : public Backend { log_error("Can't find top module in current design!\n"); if (!design->selected_whole_module(top_module)) - log_cmd_error("Can't handle partially selected module %s!\n", log_id(top_module)); + log_cmd_error("Can't handle partially selected module %s!\n", top_module); if (!top_module->processes.empty()) - log_error("Found unmapped processes in module %s: unmapped processes are not supported in AIGER backend!\n", log_id(top_module)); + log_error("Found unmapped processes in module %s: unmapped processes are not supported in AIGER backend!\n", top_module); if (!top_module->memories.empty()) - log_error("Found unmapped memories in module %s: unmapped memories are not supported in AIGER backend!\n", log_id(top_module)); + log_error("Found unmapped memories in module %s: unmapped memories are not supported in AIGER backend!\n", top_module); AigerWriter writer(top_module, no_sort, zinit_mode, imode, omode, bmode, lmode); writer.write_aiger(*f, ascii_mode, miter_mode, symbols_mode); diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 988bc558b..cc1085f96 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -268,7 +268,7 @@ struct XAigerWriter if (ys_debug(1)) { static pool> seen; if (seen.emplace(inst_module->name, i.first).second) log("%s.%s[%d] abc9_arrival = %d\n", - log_id(cell->type), log_id(i.first.name), offset, d); + cell->type.unescape(), i.first.name.unescape(), offset, d); } #endif arrival_times[rhs[offset]] = d; @@ -285,7 +285,7 @@ struct XAigerWriter auto is_input = (port_wire && port_wire->port_input) || !cell_known || cell->input(c.first); auto is_output = (port_wire && port_wire->port_output) || !cell_known || cell->output(c.first); if (!is_input && !is_output) - log_error("Connection '%s' on cell '%s' (type '%s') not recognised!\n", log_id(c.first), log_id(cell), log_id(cell->type)); + log_error("Connection '%s' on cell '%s' (type '%s') not recognised!\n", c.first.unescape(), cell, cell->type.unescape()); if (is_input) for (auto b : c.second) { @@ -303,7 +303,7 @@ struct XAigerWriter } } - //log_warning("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell)); + //log_warning("Unsupported cell type: %s (%s)\n", cell->type.unescape(), cell); } dict> box_ports; @@ -325,12 +325,12 @@ struct XAigerWriter if (w->get_bool_attribute(ID::abc9_carry)) { if (w->port_input) { if (carry_in != IdString()) - log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", log_id(box_module)); + log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", box_module); carry_in = port_name; } if (w->port_output) { if (carry_out != IdString()) - log_error("Module '%s' contains more than one 'abc9_carry' output port.\n", log_id(box_module)); + log_error("Module '%s' contains more than one 'abc9_carry' output port.\n", box_module); carry_out = port_name; } } @@ -339,9 +339,9 @@ struct XAigerWriter } if (carry_in != IdString() && carry_out == IdString()) - log_error("Module '%s' contains an 'abc9_carry' input port but no output port.\n", log_id(box_module)); + log_error("Module '%s' contains an 'abc9_carry' input port but no output port.\n", box_module); if (carry_in == IdString() && carry_out != IdString()) - log_error("Module '%s' contains an 'abc9_carry' output port but no input port.\n", log_id(box_module)); + log_error("Module '%s' contains an 'abc9_carry' output port but no input port.\n", box_module); if (carry_in != IdString()) { r.first->second.push_back(carry_in); r.first->second.push_back(carry_out); @@ -612,7 +612,7 @@ struct XAigerWriter write_r_buffer(mergeability); State init = init_map.at(q, State::Sx); - log_debug("Cell '%s' (type %s) has (* init *) value '%s'.\n", log_id(cell), log_id(cell->type), log_signal(init)); + log_debug("Cell '%s' (type %s) has (* init *) value '%s'.\n", cell, cell->type.unescape(), log_signal(init)); if (init == State::S1) write_s_buffer(1); else if (init == State::S0) @@ -692,12 +692,12 @@ struct XAigerWriter if (input_bits.count(b)) { int a = aig_map.at(b); log_assert((a & 1) == 0); - input_lines[a] += stringf("input %d %d %s\n", (a >> 1)-1, wire->start_offset+i, log_id(wire)); + input_lines[a] += stringf("input %d %d %s\n", (a >> 1)-1, wire->start_offset+i, wire); } if (output_bits.count(b)) { int o = ordered_outputs.at(b); - output_lines[o] += stringf("output %d %d %s\n", o - GetSize(co_bits), wire->start_offset+i, log_id(wire)); + output_lines[o] += stringf("output %d %d %s\n", o - GetSize(co_bits), wire->start_offset+i, wire); } } } @@ -709,7 +709,7 @@ struct XAigerWriter int box_count = 0; for (auto cell : box_list) - f << stringf("box %d %d %s\n", box_count++, 0, log_id(cell->name)); + f << stringf("box %d %d %s\n", box_count++, 0, cell->name.unescape()); output_lines.sort(); for (auto &it : output_lines) @@ -774,12 +774,12 @@ struct XAigerBackend : public Backend { log_error("Can't find top module in current design!\n"); if (!design->selected_whole_module(top_module)) - log_cmd_error("Can't handle partially selected module %s!\n", log_id(top_module)); + log_cmd_error("Can't handle partially selected module %s!\n", top_module); if (!top_module->processes.empty()) - log_error("Found unmapped processes in module %s: unmapped processes are not supported in XAIGER backend!\n", log_id(top_module)); + log_error("Found unmapped processes in module %s: unmapped processes are not supported in XAIGER backend!\n", top_module); if (!top_module->memories.empty()) - log_error("Found unmapped memories in module %s: unmapped memories are not supported in XAIGER backend!\n", log_id(top_module)); + log_error("Found unmapped memories in module %s: unmapped memories are not supported in XAIGER backend!\n", top_module); XAigerWriter writer(top_module, dff_mode); writer.write_aiger(*f, ascii_mode); diff --git a/backends/aiger2/aiger.cc b/backends/aiger2/aiger.cc index 2f28869d9..c0ab8a65c 100644 --- a/backends/aiger2/aiger.cc +++ b/backends/aiger2/aiger.cc @@ -132,7 +132,7 @@ struct Index { continue; if (!submodule || submodule->get_blackbox_attribute()) log_error("Unsupported cell type: %s (%s in %s)\n", - log_id(cell->type), log_id(cell), log_id(m)); + cell->type.unescape(), cell, m); } } } @@ -537,7 +537,7 @@ struct Index { Design *design = index.design; auto &minfo = leaf_minfo(index); if (!minfo.suboffsets.count(cell)) - log_error("Reached unsupported cell %s (%s in %s)\n", log_id(cell->type), log_id(cell), log_id(cell->module)); + log_error("Reached unsupported cell %s (%s in %s)\n", cell->type.unescape(), cell, cell->module); Module *def = design->module(cell->type); log_assert(def); levels.push_back(Level(index.modules.at(def), cell)); @@ -636,10 +636,10 @@ struct Index { Wire *w = def->wire(portname); if (!w) log_error("Output port %s on instance %s of %s doesn't exist\n", - log_id(portname), log_id(driver), log_id(def)); + portname.unescape(), driver, def); if (bit.offset >= w->width) log_error("Bit position %d of output port %s on instance %s of %s is out of range (port has width %d)\n", - bit.offset, log_id(portname), log_id(driver), log_id(def), w->width); + bit.offset, portname.unescape(), driver, def, w->width); ret = visit(cursor, SigBit(w, bit.offset)); } cursor.exit(*this); @@ -655,11 +655,11 @@ struct Index { IdString portname = bit.wire->name; if (!instance->hasPort(portname)) log_error("Input port %s on instance %s of %s unconnected\n", - log_id(portname), log_id(instance), log_id(instance->type)); + portname.unescape(), instance, instance->type); auto &port = instance->getPort(portname); if (bit.offset >= port.size()) log_error("Bit %d of input port %s on instance %s of %s unconnected\n", - bit.offset, log_id(portname), log_id(instance), log_id(instance->type)); + bit.offset, portname.unescape(), instance, instance->type.unescape()); ret = visit(cursor, port[bit.offset]); } cursor.enter(*this, instance); @@ -1048,7 +1048,7 @@ struct XAigerWriter : AigerWriter { } else if (!is_input && !inputs) { for (auto &bit : conn.second) { if (!bit.wire || (bit.wire->port_input && !bit.wire->port_output)) - log_error("Bad connection %s/%s ~ %s\n", log_id(box), log_id(conn.first), log_signal(conn.second)); + log_error("Bad connection %s/%s ~ %s\n", box, conn.first.unescape(), conn.second); ensure_pi(bit, cursor); @@ -1073,9 +1073,9 @@ struct XAigerWriter : AigerWriter { void prep_boxes(int pending_pos_num) { XAigerAnalysis analysis; - log_debug("preforming analysis on '%s'\n", log_id(top)); + log_debug("preforming analysis on '%s'\n", top); analysis.analyze(top); - log_debug("analysis on '%s' done\n", log_id(top)); + log_debug("analysis on '%s' done\n", top); // boxes which have timing data, maybe a whitebox model std::vector> nonopaque_boxes; @@ -1089,7 +1089,7 @@ struct XAigerWriter : AigerWriter { for (auto box : minfo.found_blackboxes) { log_debug(" - %s.%s (type %s): ", cursor.path(), RTLIL::unescape_id(box->name), - log_id(box->type)); + box->type.unescape()); Module *box_module = design->module(box->type), *box_derived; @@ -1158,7 +1158,7 @@ struct XAigerWriter : AigerWriter { } else { // FIXME: hierarchical path log_warning("connection on port %s[%d] of instance %s (type %s) missing, using 1'bx\n", - log_id(port_id), i, log_id(box), log_id(box->type)); + port_id.unescape(), i, box, box->type.unescape()); bit = RTLIL::Sx; } @@ -1193,7 +1193,7 @@ struct XAigerWriter : AigerWriter { } else { // FIXME: hierarchical path log_warning("connection on port %s[%d] of instance %s (type %s) missing\n", - log_id(port_id), i, log_id(box), log_id(box->type)); + port_id.unescape(), i, box, box->type.unescape()); pad_pi(); continue; } @@ -1210,7 +1210,7 @@ struct XAigerWriter : AigerWriter { holes_wb->setPort(port_id, w); } else { log_error("Ambiguous port direction on %s/%s\n", - log_id(box->type), log_id(port_id)); + box->type.unescape(), port_id.unescape()); } } } @@ -1405,7 +1405,7 @@ struct Aiger2Backend : Backend { continue; if (known_ops(cell.type)) continue; - std::string name = log_id(cell.type); + std::string name = cell.type.unescape(); if (col + name.size() + 2 > 72) { log("\n "); col = 0; @@ -1427,7 +1427,7 @@ struct Aiger2Backend : Backend { continue; if (known_ops(cell.type)) continue; - std::string name = log_id(cell.type); + std::string name = cell.type.unescape(); if (col + name.size() + 2 > 72) { log("\n "); col = 0; diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index cc339bcbc..d16d39e5e 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -150,7 +150,7 @@ struct BlifDumper void dump_params(const char *command, dict ¶ms) { for (auto ¶m : params) { - f << stringf("%s %s ", command, log_id(param.first)); + f << stringf("%s %s ", command, param.first.unescape()); if (param.second.flags & RTLIL::CONST_FLAG_STRING) { std::string str = param.second.decode_string(); f << stringf("\""); @@ -678,9 +678,9 @@ struct BlifBackend : public Backend { continue; if (module->processes.size() != 0) - log_error("Found unmapped processes in module %s: unmapped processes are not supported in BLIF backend!\n", log_id(module->name)); + log_error("Found unmapped processes in module %s: unmapped processes are not supported in BLIF backend!\n", module->name.unescape()); if (module->memories.size() != 0) - log_error("Found unmapped memories in module %s: unmapped memories are not supported in BLIF backend!\n", log_id(module->name)); + log_error("Found unmapped memories in module %s: unmapped memories are not supported in BLIF backend!\n", module->name.unescape()); if (module->name == RTLIL::escape_id(top_module_name)) { BlifDumper::dump(*f, module, design, config); diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index ca7cf8a7f..497ecc954 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -119,7 +119,7 @@ struct BtorWorker template string getinfo(T *obj, bool srcsym = false) { - string infostr = log_id(obj); + string infostr = obj->name.unescape(); if (!srcsym && !print_internal_names && infostr[0] == '$') return ""; if (obj->attributes.count(ID::src)) { string src = obj->attributes.at(ID::src).decode_string().c_str(); @@ -243,12 +243,12 @@ struct BtorWorker if (cell_recursion_guard.count(cell)) { string cell_list; for (auto c : cell_recursion_guard) - cell_list += stringf("\n %s", log_id(c)); - log_error("Found topological loop while processing cell %s. Active cells:%s\n", log_id(cell), cell_list); + cell_list += stringf("\n %s", c); + log_error("Found topological loop while processing cell %s. Active cells:%s\n", cell, cell_list); } cell_recursion_guard.insert(cell); - btorf_push(log_id(cell)); + btorf_push(cell->name.unescape()); if (cell->type.in(ID($add), ID($sub), ID($mul), ID($and), ID($or), ID($xor), ID($xnor), ID($shl), ID($sshl), ID($shr), ID($sshr), ID($shift), ID($shiftx), ID($concat), ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_))) @@ -726,7 +726,7 @@ struct BtorWorker if (symbol.empty() || (!print_internal_names && symbol[0] == '$')) btorf("%d state %d\n", nid, sid); else - btorf("%d state %d %s\n", nid, sid, log_id(symbol)); + btorf("%d state %d %s\n", nid, sid, symbol.unescape()); if (cell->get_bool_attribute(ID(clk2fflogic))) ywmap_state(cell->getPort(ID::D)); // For a clk2fflogic FF the named signal is the D input not the Q output @@ -804,12 +804,12 @@ struct BtorWorker if (asyncwr && syncwr) log_error("Memory %s.%s has mixed async/sync write ports.\n", - log_id(module), log_id(mem->memid)); + module, mem->memid.unescape()); for (auto &port : mem->rd_ports) { if (port.clk_enable) log_error("Memory %s.%s has sync read ports. Please use memory_nordff to convert them first.\n", - log_id(module), log_id(mem->memid)); + module, mem->memid.unescape()); } int data_sid = get_bv_sid(mem->width); @@ -871,7 +871,7 @@ struct BtorWorker if (mem->memid[0] == '$') btorf("%d state %d\n", nid, sid); else - btorf("%d state %d %s\n", nid, sid, log_id(mem->memid)); + btorf("%d state %d %s\n", nid, sid, mem->memid.unescape()); ywmap_state(cell); @@ -948,21 +948,20 @@ struct BtorWorker if (cell->type.in(ID($dffe), ID($sdff), ID($sdffe), ID($sdffce)) || cell->type.str().substr(0, 6) == "$_SDFF" || (cell->type.str().substr(0, 6) == "$_DFFE" && cell->type.str().size() == 10)) { log_error("Unsupported cell type %s for cell %s.%s -- please run `dffunmap` before `write_btor`.\n", - log_id(cell->type), log_id(module), log_id(cell)); + cell->type.unescape(), module, cell); } if (cell->type.in(ID($adff), ID($adffe), ID($aldff), ID($aldffe), ID($dffsr), ID($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF" || cell->type.str().substr(0, 7) == "$_ALDFF") { log_error("Unsupported cell type %s for cell %s.%s -- please run `async2sync; dffunmap` or `clk2fflogic` before `write_btor`.\n", - log_id(cell->type), log_id(module), log_id(cell)); + cell->type.unescape(), module, cell); } if (cell->type.in(ID($sr), ID($dlatch), ID($adlatch), ID($dlatchsr)) || cell->type.str().substr(0, 8) == "$_DLATCH" || cell->type.str().substr(0, 5) == "$_SR_") { log_error("Unsupported cell type %s for cell %s.%s -- please run `clk2fflogic` before `write_btor`.\n", - log_id(cell->type), log_id(module), log_id(cell)); + cell->type.unescape(), module, cell); } log_error("Unsupported cell type %s for cell %s.%s.\n", - log_id(cell->type), log_id(module), log_id(cell)); - + cell->type.unescape(), module, cell); okay: - btorf_pop(log_id(cell)); + btorf_pop(cell->name.unescape()); cell_recursion_guard.erase(cell); } @@ -1167,7 +1166,7 @@ struct BtorWorker f(f), sigmap(module), module(module), verbose(verbose), single_bad(single_bad), cover_mode(cover_mode), print_internal_names(print_internal_names), info_filename(info_filename) { if (!info_filename.empty()) - infof("name %s\n", log_id(module)); + infof("name %s\n", module); if (!ywmap_filename.empty()) ywmap_json.write_to_file(ywmap_filename); @@ -1257,19 +1256,19 @@ struct BtorWorker if (!wire->port_id || !wire->port_output) continue; - btorf_push(stringf("output %s", log_id(wire))); + btorf_push(stringf("output %s", wire)); int nid = get_sig_nid(wire); btorf("%d output %d%s\n", next_nid++, nid, getinfo(wire)); - btorf_pop(stringf("output %s", log_id(wire))); + btorf_pop(stringf("output %s", wire)); } for (auto cell : module->cells()) { if (cell->type == ID($assume)) { - btorf_push(log_id(cell)); + btorf_push(cell->name.unescape()); int sid = get_bv_sid(1); int nid_a = get_sig_nid(cell->getPort(ID::A)); @@ -1284,12 +1283,12 @@ struct BtorWorker if (ywmap_json.active()) ywmap_assumes.emplace_back(cell); - btorf_pop(log_id(cell)); + btorf_pop(cell->name.unescape()); } if (cell->type == ID($assert)) { - btorf_push(log_id(cell)); + btorf_push(cell->name.unescape()); int sid = get_bv_sid(1); int nid_a = get_sig_nid(cell->getPort(ID::A)); @@ -1313,12 +1312,12 @@ struct BtorWorker } } - btorf_pop(log_id(cell)); + btorf_pop(cell->name.unescape()); } if (cell->type == ID($cover) && cover_mode) { - btorf_push(log_id(cell)); + btorf_push(cell->name.unescape()); int sid = get_bv_sid(1); int nid_a = get_sig_nid(cell->getPort(ID::A)); @@ -1334,7 +1333,7 @@ struct BtorWorker btorf("%d bad %d%s\n", nid, nid_en_and_a, getinfo(cell, true)); } - btorf_pop(log_id(cell)); + btorf_pop(cell->name.unescape()); } } @@ -1343,7 +1342,7 @@ struct BtorWorker if (wire->port_id || wire->name[0] == '$') continue; - btorf_push(stringf("wire %s", log_id(wire))); + btorf_push(stringf("wire %s", wire)); int sid = get_bv_sid(GetSize(wire)); int nid = get_sig_nid(sigmap(wire)); @@ -1356,7 +1355,7 @@ struct BtorWorker if (info_clocks.count(nid)) info_clocks[this_nid] |= info_clocks[nid]; - btorf_pop(stringf("wire %s", log_id(wire))); + btorf_pop(stringf("wire %s", wire)); continue; } @@ -1370,14 +1369,14 @@ struct BtorWorker int nid = it.first; Cell *cell = it.second; - btorf_push(stringf("next %s", log_id(cell))); + btorf_push(stringf("next %s", cell)); SigSpec sig = sigmap(cell->getPort(ID::D)); int nid_q = get_sig_nid(sig); int sid = get_bv_sid(GetSize(sig)); btorf("%d next %d %d %d%s\n", next_nid++, sid, nid, nid_q, getinfo(cell)); - btorf_pop(stringf("next %s", log_id(cell))); + btorf_pop(stringf("next %s", cell)); } vector> mtodo; @@ -1388,7 +1387,7 @@ struct BtorWorker int nid = it.first; Mem *mem = it.second; - btorf_push(stringf("next %s", log_id(mem->memid))); + btorf_push(stringf("next %s", mem->memid.unescape())); int abits = ceil_log2(mem->size); @@ -1436,7 +1435,7 @@ struct BtorWorker int nid2 = next_nid++; btorf("%d next %d %d %d%s\n", nid2, sid, nid, nid_head, (mem->cell ? getinfo(mem->cell) : getinfo(mem->mem))); - btorf_pop(stringf("next %s", log_id(mem->memid))); + btorf_pop(stringf("next %s", mem->memid.unescape())); } } @@ -1630,7 +1629,7 @@ struct BtorBackend : public Backend { log_cmd_error("No top module found.\n"); *f << stringf("; BTOR description generated by %s for module %s.\n", - yosys_maybe_version(), log_id(topmod)); + yosys_maybe_version(), topmod); BtorWorker(*f, topmod, verbose, single_bad, cover_mode, print_internal_names, info_filename, ywmap_filename); diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index ab5576e43..3ebe62b90 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -251,7 +251,7 @@ CxxrtlPortType cxxrtl_port_type(RTLIL::Module *module, RTLIL::IdString port) bool is_sync = output_wire->get_bool_attribute(ID(cxxrtl_sync)); if (is_comb && is_sync) log_cmd_error("Port `%s.%s' is marked as both `cxxrtl_comb` and `cxxrtl_sync`.\n", - log_id(module), log_signal(output_wire)); + module, log_signal(output_wire)); else if (is_comb) return CxxrtlPortType::COMB; else if (is_sync) @@ -851,7 +851,7 @@ struct CxxrtlWorker { return {}; if (!(module->attributes.at(ID(cxxrtl_template)).flags & RTLIL::CONST_FLAG_STRING)) - log_cmd_error("Attribute `cxxrtl_template' of module `%s' is not a string.\n", log_id(module)); + log_cmd_error("Attribute `cxxrtl_template' of module `%s' is not a string.\n", module); std::vector param_names = split_by(module->get_string_attribute(ID(cxxrtl_template)), " \t"); for (const auto ¶m_name : param_names) { @@ -861,7 +861,7 @@ struct CxxrtlWorker { if (!isupper(param_name[0])) log_cmd_error("Attribute `cxxrtl_template' of module `%s' includes a parameter `%s', " "which does not start with an uppercase letter.\n", - log_id(module), param_name.c_str()); + module, param_name.c_str()); } return param_names; } @@ -907,12 +907,12 @@ struct CxxrtlWorker { RTLIL::IdString id_param_name = '\\' + param_name; if (!cell->hasParam(id_param_name)) log_cmd_error("Cell `%s.%s' does not have a parameter `%s', which is required by the templated module `%s'.\n", - log_id(cell->module), log_id(cell), param_name.c_str(), log_id(cell_module)); + cell->module, cell, param_name.c_str(), cell_module); RTLIL::Const param_value = cell->getParam(id_param_name); if (((param_value.flags & ~RTLIL::CONST_FLAG_SIGNED) != 0) || param_value.as_int() < 0) log_cmd_error("Parameter `%s' of cell `%s.%s', which is required by the templated module `%s', " "is not a positive integer.\n", - param_name.c_str(), log_id(cell->module), log_id(cell), log_id(cell_module)); + param_name.c_str(), cell->module, cell, cell_module); params += std::to_string(cell->getParam(id_param_name).as_int()); } params += ">"; @@ -2576,7 +2576,7 @@ struct CxxrtlWorker { } dec_indent(); - log_debug("Debug information statistics for module `%s':\n", log_id(module)); + log_debug("Debug information statistics for module `%s':\n", module); log_debug(" Scopes: %zu", count_scopes); log_debug(" Public wires: %zu, of which:\n", count_public_wires); log_debug(" Member wires: %zu, of which:\n", count_member_wires); @@ -2940,7 +2940,7 @@ struct CxxrtlWorker { RTLIL::Const edge_attr = wire->attributes[ID(cxxrtl_edge)]; if (!(edge_attr.flags & RTLIL::CONST_FLAG_STRING) || (int)edge_attr.decode_string().size() != GetSize(wire)) log_cmd_error("Attribute `cxxrtl_edge' of port `%s.%s' is not a string with one character per bit.\n", - log_id(module), log_signal(wire)); + module, log_signal(wire)); std::string edges = wire->get_string_attribute(ID(cxxrtl_edge)); for (int i = 0; i < GetSize(wire); i++) { @@ -2953,7 +2953,7 @@ struct CxxrtlWorker { default: log_cmd_error("Attribute `cxxrtl_edge' of port `%s.%s' contains specifiers " "other than '-', 'p', 'n', or 'a'.\n", - log_id(module), log_signal(wire)); + module, log_signal(wire)); } } } @@ -2978,7 +2978,7 @@ struct CxxrtlWorker { for (auto cell : module->cells()) { if (!cell->known()) - log_cmd_error("Unknown cell `%s'.\n", log_id(cell->type)); + log_cmd_error("Unknown cell `%s'.\n", cell->type.unescape()); if (cell->is_mem_cell()) continue; @@ -2987,7 +2987,7 @@ struct CxxrtlWorker { if (cell_module && cell_module->get_blackbox_attribute() && !cell_module->get_bool_attribute(ID(cxxrtl_blackbox))) - log_cmd_error("External blackbox cell `%s' is not marked as a CXXRTL blackbox.\n", log_id(cell->type)); + log_cmd_error("External blackbox cell `%s' is not marked as a CXXRTL blackbox.\n", cell->type.unescape()); if (cell_module && cell_module->get_bool_attribute(ID(cxxrtl_blackbox)) && @@ -3116,9 +3116,9 @@ struct CxxrtlWorker { } if (!feedback_wires.empty()) { has_feedback_arcs = true; - log("Module `%s' contains feedback arcs through wires:\n", log_id(module)); + log("Module `%s' contains feedback arcs through wires:\n", module); for (auto wire : feedback_wires) - log(" %s\n", log_id(wire)); + log(" %s\n", wire); } // Conservatively assign wire types. Assignment of types BUFFERED and MEMBER is final, but assignment @@ -3189,7 +3189,7 @@ struct CxxrtlWorker { if (wire->name.isPublic() && !inline_public) continue; if (flow.is_inlinable(wire, live_wires[wire])) { if (flow.wire_comb_defs[wire].size() > 1) - log_cmd_error("Wire %s.%s has multiple drivers!\n", log_id(module), log_id(wire)); + log_cmd_error("Wire %s.%s has multiple drivers!\n", module, wire); log_assert(flow.wire_comb_defs[wire].size() == 1); FlowGraph::Node *node = *flow.wire_comb_defs[wire].begin(); switch (node->type) { @@ -3237,9 +3237,9 @@ struct CxxrtlWorker { buffered_comb_wires.insert(wire); if (!buffered_comb_wires.empty()) { has_buffered_comb_wires = true; - log("Module `%s' contains buffered combinatorial wires:\n", log_id(module)); + log("Module `%s' contains buffered combinatorial wires:\n", module); for (auto wire : buffered_comb_wires) - log(" %s\n", log_id(wire)); + log(" %s\n", wire); } // Record whether eval() requires only one delta cycle in this module. diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index 145477b6b..180c3739b 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -207,9 +207,9 @@ struct EdifBackend : public Backend { top_module_name = module->name.str(); if (module->processes.size() != 0) - log_error("Found unmapped processes in module %s: unmapped processes are not supported in EDIF backend!\n", log_id(module->name)); + log_error("Found unmapped processes in module %s: unmapped processes are not supported in EDIF backend!\n", module->name.unescape()); if (module->memories.size() != 0) - log_error("Found unmapped memories in module %s: unmapped memories are not supported in EDIF backend!\n", log_id(module->name)); + log_error("Found unmapped memories in module %s: unmapped memories are not supported in EDIF backend!\n", module->name.unescape()); for (auto cell : module->cells()) { @@ -317,12 +317,12 @@ struct EdifBackend : public Backend { for (auto &dep : it.second) if (module_deps.count(dep) > 0) goto not_ready_yet; - // log("Next in topological sort: %s\n", log_id(it.first->name)); + // log("Next in topological sort: %s\n", it.first->name.unescape()); sorted_modules.push_back(it.first); not_ready_yet:; } if (sorted_modules_idx == sorted_modules.size()) - log_error("Cyclic dependency between modules found! Cycle includes module %s.\n", log_id(module_deps.begin()->first->name)); + log_error("Cyclic dependency between modules found! Cycle includes module %s.\n", module_deps.begin()->first->name.unescape()); while (sorted_modules_idx < sorted_modules.size()) module_deps.erase(sorted_modules.at(sorted_modules_idx++)); } @@ -486,7 +486,7 @@ struct EdifBackend : public Backend { for (int i = 0; i < GetSize(sig); i++) if (sig[i].wire == NULL && sig[i] != RTLIL::State::S0 && sig[i] != RTLIL::State::S1) log_warning("Bit %d of cell port %s.%s.%s driven by %s will be left unconnected in EDIF output.\n", - i, log_id(module), log_id(cell), log_id(p.first), log_signal(sig[i])); + i, module, cell, p.first.unescape(), log_signal(sig[i])); else { int member_idx = lsbidx ? i : GetSize(sig)-i-1; auto m = design->module(cell->type); diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc index 577d95ad7..db5036552 100644 --- a/backends/firrtl/firrtl.cc +++ b/backends/firrtl/firrtl.cc @@ -82,7 +82,7 @@ const char *make_id(IdString id) if (namecache.count(id) != 0) return namecache.at(id).c_str(); - string new_id = log_id(id); + string new_id = id.unescape(); for (int i = 0; i < GetSize(new_id); i++) { @@ -263,7 +263,7 @@ void emit_extmodule(RTLIL::Cell *cell, RTLIL::Module *mod_instance, std::ostream if (wire->port_input && wire->port_output) { - log_error("Module port %s.%s is inout!\n", log_id(mod_instance), log_id(wire)); + log_error("Module port %s.%s is inout!\n", mod_instance, wire); } const std::string portDecl = stringf("%s%s %s: UInt<%d> %s\n", @@ -559,12 +559,12 @@ struct FirrtlWorker if (wire->attributes.count(ID::init)) { log_warning("Initial value (%s) for (%s.%s) not supported\n", wire->attributes.at(ID::init).as_string().c_str(), - log_id(module), log_id(wire)); + module, wire); } if (wire->port_id) { if (wire->port_input && wire->port_output) - log_error("Module port %s.%s is inout!\n", log_id(module), log_id(wire)); + log_error("Module port %s.%s is inout!\n", module, wire); port_decls.push_back(stringf("%s%s %s: UInt<%d> %s\n", indent, wire->port_input ? "input" : "output", wireName, wire->width, wireFileinfo.c_str())); } @@ -833,7 +833,7 @@ struct FirrtlWorker primop = "shl"; int shiftAmount = b_sig.as_int(); if (shiftAmount < 0) { - log_error("Negative power exponent - %d: %s.%s\n", shiftAmount, log_id(module), log_id(cell)); + log_error("Negative power exponent - %d: %s.%s\n", shiftAmount, module, cell); } b_expr = std::to_string(shiftAmount); firrtl_width = a_width + shiftAmount; @@ -844,7 +844,7 @@ struct FirrtlWorker firrtl_width = a_width + (1 << b_width) - 1; } } else { - log_error("Non power 2: %s.%s\n", log_id(module), log_id(cell)); + log_error("Non power 2: %s.%s\n", module, cell); } } @@ -905,7 +905,7 @@ struct FirrtlWorker { bool clkpol = cell->parameters.at(ID::CLK_POLARITY).as_bool(); if (clkpol == false) - log_error("Negative edge clock on FF %s.%s.\n", log_id(module), log_id(cell)); + log_error("Negative edge clock on FF %s.%s.\n", module, cell); int width = cell->parameters.at(ID::WIDTH).as_int(); string expr = make_expr(cell->getPort(ID::D)); @@ -983,7 +983,7 @@ struct FirrtlWorker if (cell->type == ID($scopeinfo)) continue; - log_error("Cell type not supported: %s (%s.%s)\n", log_id(cell->type), log_id(module), log_id(cell)); + log_error("Cell type not supported: %s (%s.%s)\n", cell->type.unescape(), module, cell); } for (auto &mem : memories) { @@ -991,10 +991,10 @@ struct FirrtlWorker Const init_data = mem.get_init_data(); if (!init_data.is_fully_undef()) - log_error("Memory with initialization data: %s.%s\n", log_id(module), log_id(mem.memid)); + log_error("Memory with initialization data: %s.%s\n", module, mem.memid.unescape()); if (mem.start_offset != 0) - log_error("Memory with nonzero offset: %s.%s\n", log_id(module), log_id(mem.memid)); + log_error("Memory with nonzero offset: %s.%s\n", module, mem.memid.unescape()); for (int i = 0; i < GetSize(mem.rd_ports); i++) { @@ -1002,7 +1002,7 @@ struct FirrtlWorker string port_name(stringf("%s.r%d", mem_id, i)); if (port.clk_enable) - log_error("Clocked read port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid)); + log_error("Clocked read port %d on memory %s.%s.\n", i, module, mem.memid.unescape()); std::ostringstream rpe; @@ -1023,12 +1023,12 @@ struct FirrtlWorker string port_name(stringf("%s.w%d", mem_id, i)); if (!port.clk_enable) - log_error("Unclocked write port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid)); + log_error("Unclocked write port %d on memory %s.%s.\n", i, module, mem.memid.unescape()); if (!port.clk_polarity) - log_error("Negedge write port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid)); + log_error("Negedge write port %d on memory %s.%s.\n", i, module, mem.memid.unescape()); for (int i = 1; i < GetSize(port.en); i++) if (port.en[0] != port.en[i]) - log_error("Complex write enable on port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid)); + log_error("Complex write enable on port %d on memory %s.%s.\n", i, module, mem.memid.unescape()); std::ostringstream wpe; diff --git a/backends/intersynth/intersynth.cc b/backends/intersynth/intersynth.cc index ad16d50ab..5e1a3fc8d 100644 --- a/backends/intersynth/intersynth.cc +++ b/backends/intersynth/intersynth.cc @@ -133,26 +133,26 @@ struct IntersynthBackend : public Backend { if (selected && !design->selected_whole_module(module->name)) { if (design->selected_module(module->name)) - log_cmd_error("Can't handle partially selected module %s!\n", log_id(module->name)); + log_cmd_error("Can't handle partially selected module %s!\n", module->name.unescape()); continue; } - log("Generating netlist %s.\n", log_id(module->name)); + log("Generating netlist %s.\n", module->name.unescape()); if (module->memories.size() != 0 || module->processes.size() != 0) log_error("Can't generate a netlist for a module with unprocessed memories or processes!\n"); std::set constcells_code; - netlists_code += stringf("# Netlist of module %s\n", log_id(module->name)); - netlists_code += stringf("netlist %s\n", log_id(module->name)); + netlists_code += stringf("# Netlist of module %s\n", module->name.unescape()); + netlists_code += stringf("netlist %s\n", module->name.unescape()); // Module Ports: "std::set celltypes_code" prevents duplicate top level ports for (auto wire : module->wires()) { if (wire->port_input || wire->port_output) { celltypes_code.insert(stringf("celltype !%s b%d %sPORT\n" "%s %s %d %s PORT\n", - log_id(wire->name), wire->width, wire->port_input ? "*" : "", - wire->port_input ? "input" : "output", log_id(wire->name), wire->width, log_id(wire->name))); - netlists_code += stringf("node %s %s PORT %s\n", log_id(wire->name), log_id(wire->name), + wire->name.unescape(), wire->width, wire->port_input ? "*" : "", + wire->port_input ? "input" : "output", wire->name.unescape(), wire->width, wire->name.unescape())); + netlists_code += stringf("node %s %s PORT %s\n", wire->name.unescape(), wire->name.unescape(), netname(conntypes_code, celltypes_code, constcells_code, sigmap(wire)).c_str()); } } @@ -163,26 +163,26 @@ struct IntersynthBackend : public Backend { std::string celltype_code, node_code; if (!ct.cell_known(cell->type)) - log_error("Found unknown cell type %s in module!\n", log_id(cell->type)); + log_error("Found unknown cell type %s in module!\n", cell->type.unescape()); - celltype_code = stringf("celltype %s", log_id(cell->type)); - node_code = stringf("node %s %s", log_id(cell->name), log_id(cell->type)); + celltype_code = stringf("celltype %s", cell->type.unescape()); + node_code = stringf("node %s %s", cell->name.unescape(), cell->type.unescape()); for (auto &port : cell->connections()) { RTLIL::SigSpec sig = sigmap(port.second); if (sig.size() != 0) { conntypes_code.insert(stringf("conntype b%d %d 2 %d\n", sig.size(), sig.size(), sig.size())); - celltype_code += stringf(" b%d %s%s", sig.size(), ct.cell_output(cell->type, port.first) ? "*" : "", log_id(port.first)); - node_code += stringf(" %s %s", log_id(port.first), netname(conntypes_code, celltypes_code, constcells_code, sig)); + celltype_code += stringf(" b%d %s%s", sig.size(), ct.cell_output(cell->type, port.first) ? "*" : "", port.first.unescape()); + node_code += stringf(" %s %s", port.first.unescape(), netname(conntypes_code, celltypes_code, constcells_code, sig)); } } for (auto ¶m : cell->parameters) { - celltype_code += stringf(" cfg:%d %s", int(param.second.size()), log_id(param.first)); + celltype_code += stringf(" cfg:%d %s", int(param.second.size()), param.first.unescape()); if (param.second.size() != 32) { - node_code += stringf(" %s '", log_id(param.first)); + node_code += stringf(" %s '", param.first.unescape()); for (int i = param.second.size()-1; i >= 0; i--) node_code += param.second[i] == State::S1 ? "1" : "0"; } else - node_code += stringf(" %s 0x%x", log_id(param.first), param.second.as_int()); + node_code += stringf(" %s 0x%x", param.first.unescape(), param.second.as_int()); } celltypes_code.insert(celltype_code + "\n"); diff --git a/backends/json/json.cc b/backends/json/json.cc index b04083622..234574ed1 100644 --- a/backends/json/json.cc +++ b/backends/json/json.cc @@ -152,7 +152,7 @@ struct JsonWriter sigidcounter = 2; if (module->has_processes()) { - log_error("Module %s contains processes, which are not supported by JSON backend (run `proc` first).\n", log_id(module)); + log_error("Module %s contains processes, which are not supported by JSON backend (run `proc` first).\n", module); } f << stringf(" %s: {\n", get_name(module->name)); @@ -316,13 +316,13 @@ struct JsonWriter f << stringf(" /* %3d */ [ ", node_idx); if (node.portbit >= 0) f << stringf("\"%sport\", \"%s\", %d", node.inverter ? "n" : "", - log_id(node.portname), node.portbit); + node.portname.unescape(), node.portbit); else if (node.left_parent < 0 && node.right_parent < 0) f << stringf("\"%s\"", node.inverter ? "true" : "false"); else f << stringf("\"%s\", %d, %d", node.inverter ? "nand" : "and", node.left_parent, node.right_parent); for (auto &op : node.outports) - f << stringf(", \"%s\", %d", log_id(op.first), op.second); + f << stringf(", \"%s\", %d", op.first.unescape(), op.second); f << stringf(" ]"); node_idx++; } diff --git a/backends/simplec/simplec.cc b/backends/simplec/simplec.cc index 8ebc685f0..baf5aa006 100644 --- a/backends/simplec/simplec.cc +++ b/backends/simplec/simplec.cc @@ -78,7 +78,7 @@ struct HierDirtyFlags for (Cell *cell : module->cells()) { Module *mod = module->design->module(cell->type); if (mod) children[cell->name] = new HierDirtyFlags(mod, cell->name, this, - prefix + cid(cell->name) + ".", log_prefix + "." + prefix + log_id(cell->name)); + prefix + cid(cell->name) + ".", log_prefix + "." + prefix + cell->name.unescape()); } } @@ -354,23 +354,23 @@ struct SimplecWorker struct_declarations.push_back(" // Input Ports"); for (Wire *w : mod->wires()) if (w->port_input) - struct_declarations.push_back(stringf(" %s %s; // %s", sigtype(w->width), cid(w->name), log_id(w))); + struct_declarations.push_back(stringf(" %s %s; // %s", sigtype(w->width), cid(w->name), w)); struct_declarations.push_back(""); struct_declarations.push_back(" // Output Ports"); for (Wire *w : mod->wires()) if (!w->port_input && w->port_output) - struct_declarations.push_back(stringf(" %s %s; // %s", sigtype(w->width), cid(w->name), log_id(w))); + struct_declarations.push_back(stringf(" %s %s; // %s", sigtype(w->width), cid(w->name), w)); struct_declarations.push_back(""); struct_declarations.push_back(" // Internal Wires"); for (Wire *w : mod->wires()) if (!w->port_input && !w->port_output) - struct_declarations.push_back(stringf(" %s %s; // %s", sigtype(w->width), cid(w->name), log_id(w))); + struct_declarations.push_back(stringf(" %s %s; // %s", sigtype(w->width), cid(w->name), w)); for (Cell *c : mod->cells()) if (design->module(c->type)) - struct_declarations.push_back(stringf(" struct %s_state_t %s; // %s", cid(c->type), cid(c->name), log_id(c))); + struct_declarations.push_back(stringf(" struct %s_state_t %s; // %s", cid(c->type), cid(c->name), c)); struct_declarations.push_back(stringf("};")); struct_declarations.push_back("#endif"); @@ -391,7 +391,7 @@ struct SimplecWorker log_assert(y.wire); funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) + - stringf(" // %s (%s)", log_id(cell), log_id(cell->type))); + stringf(" // %s (%s)", cell, cell->type.unescape())); work->set_dirty(y); return; @@ -418,7 +418,7 @@ struct SimplecWorker log_assert(y.wire); funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) + - stringf(" // %s (%s)", log_id(cell), log_id(cell->type))); + stringf(" // %s (%s)", cell, cell->type.unescape())); work->set_dirty(y); return; @@ -441,7 +441,7 @@ struct SimplecWorker log_assert(y.wire); funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) + - stringf(" // %s (%s)", log_id(cell), log_id(cell->type))); + stringf(" // %s (%s)", cell, cell->type.unescape())); work->set_dirty(y); return; @@ -466,7 +466,7 @@ struct SimplecWorker log_assert(y.wire); funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) + - stringf(" // %s (%s)", log_id(cell), log_id(cell->type))); + stringf(" // %s (%s)", cell, cell->type.unescape())); work->set_dirty(y); return; @@ -490,13 +490,13 @@ struct SimplecWorker log_assert(y.wire); funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) + - stringf(" // %s (%s)", log_id(cell), log_id(cell->type))); + stringf(" // %s (%s)", cell, cell->type.unescape())); work->set_dirty(y); return; } - log_error("No C model for %s available at the moment (FIXME).\n", log_id(cell->type)); + log_error("No C model for %s available at the moment (FIXME).\n", cell->type.unescape()); } void eval_dirty(HierDirtyFlags *work) @@ -517,7 +517,7 @@ struct SimplecWorker if (chunk.wire == nullptr) continue; if (verbose) - log(" Propagating %s.%s[%d:%d].\n", work->log_prefix, log_id(chunk.wire), chunk.offset+chunk.width-1, chunk.offset); + log(" Propagating %s.%s[%d:%d].\n", work->log_prefix, chunk.wire, chunk.offset+chunk.width-1, chunk.offset); funct_declarations.push_back(stringf(" // Updated signal in %s: %s", work->log_prefix, log_signal(chunk))); } @@ -539,8 +539,8 @@ struct SimplecWorker work->parent->set_dirty(parent_bit); if (verbose) - log(" Propagating %s.%s[%d] -> %s.%s[%d].\n", work->log_prefix, log_id(bit.wire), bit.offset, - work->parent->log_prefix.c_str(), log_id(parent_bit.wire), parent_bit.offset); + log(" Propagating %s.%s[%d] -> %s.%s[%d].\n", work->log_prefix, bit.wire, bit.offset, + work->parent->log_prefix.c_str(), parent_bit.wire, parent_bit.offset); } for (auto &port : bit2cell[work->module][bit]) @@ -556,12 +556,12 @@ struct SimplecWorker child->set_dirty(child_bit); if (verbose) - log(" Propagating %s.%s[%d] -> %s.%s.%s[%d].\n", work->log_prefix, log_id(bit.wire), bit.offset, - work->log_prefix.c_str(), log_id(std::get<0>(port)), log_id(child_bit.wire), child_bit.offset); + log(" Propagating %s.%s[%d] -> %s.%s.%s[%d].\n", work->log_prefix, bit.wire, bit.offset, + work->log_prefix.c_str(), std::get<0>(port), child_bit.wire, child_bit.offset); } else { if (verbose) - log(" Marking cell %s.%s (via %s.%s[%d]).\n", work->log_prefix, log_id(std::get<0>(port)), - work->log_prefix.c_str(), log_id(bit.wire), bit.offset); + log(" Marking cell %s.%s (via %s.%s[%d]).\n", work->log_prefix, std::get<0>(port), + work->log_prefix.c_str(), bit.wire, bit.offset); work->set_dirty(std::get<0>(port)); } } @@ -576,10 +576,10 @@ struct SimplecWorker if (cell == nullptr || topoidx.at(cell) < topoidx.at(c)) cell = c; - string hiername = work->log_prefix + "." + log_id(cell); + string hiername = work->log_prefix + "." + cell->name.unescape(); if (verbose) - log(" Evaluating %s (%s, best of %d).\n", hiername, log_id(cell->type), GetSize(work->dirty_cells)); + log(" Evaluating %s (%s, best of %d).\n", hiername, cell->type.unescape(), GetSize(work->dirty_cells)); if (activated_cells.count(hiername)) reactivated_cells.insert(hiername); @@ -618,8 +618,8 @@ struct SimplecWorker if (verbose) log(" Propagating alias %s.%s[%d] -> %s.%s[%d].\n", - work->log_prefix.c_str(), log_id(canonical_bit.wire), canonical_bit.offset, - work->log_prefix.c_str(), log_id(bit.wire), bit.offset); + work->log_prefix.c_str(), canonical_bit.wire, canonical_bit.offset, + work->log_prefix.c_str(), bit.wire, bit.offset); } work->sticky_dirty_bits.clear(); @@ -716,7 +716,7 @@ struct SimplecWorker { create_module_struct(mod); - HierDirtyFlags work(mod, IdString(), nullptr, "state->", log_id(mod->name)); + HierDirtyFlags work(mod, IdString(), nullptr, "state->", mod->name.unescape()); make_init_func(&work); make_eval_func(&work); diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc index 9d0ebc2aa..a9030e18a 100644 --- a/backends/smt2/smt2.cc +++ b/backends/smt2/smt2.cc @@ -60,7 +60,7 @@ struct Smt2Worker const char *get_id(IdString n) { if (ids.count(n) == 0) { - std::string str = log_id(n); + std::string str = n.unescape(); for (int i = 0; i < GetSize(str); i++) { if (str[i] == '\\') str[i] = '/'; @@ -207,7 +207,7 @@ struct Smt2Worker } else if (is_output || !is_input) log_error("Unsupported or unknown directionality on port %s of cell %s.%s (%s).\n", - log_id(conn.first), log_id(module), log_id(cell), log_id(cell->type)); + conn.first.unescape(), module, cell, cell->type.unescape()); if (cell->type.in(ID($dff), ID($_DFF_P_), ID($_DFF_N_)) && conn.first.in(ID::CLK, ID::C)) { @@ -448,7 +448,7 @@ struct Smt2Worker } if (verbose) - log("%*s-> import cell: %s\n", 2+2*GetSize(recursive_cells), "", log_id(cell)); + log("%*s-> import cell: %s\n", 2+2*GetSize(recursive_cells), "", cell); decls.push_back(stringf("(define-fun |%s#%d| ((state |%s_s|)) Bool %s) ; %s\n", get_id(module), idcounter, get_id(module), processed_expr.c_str(), log_signal(bit))); @@ -498,7 +498,7 @@ struct Smt2Worker processed_expr = stringf("((_ extract %d 0) %s)", GetSize(sig_y)-1, processed_expr); if (verbose) - log("%*s-> import cell: %s\n", 2+2*GetSize(recursive_cells), "", log_id(cell)); + log("%*s-> import cell: %s\n", 2+2*GetSize(recursive_cells), "", cell); if (type == 'b') { decls.push_back(stringf("(define-fun |%s#%d| ((state |%s_s|)) Bool %s) ; %s\n", @@ -529,7 +529,7 @@ struct Smt2Worker processed_expr += ch; if (verbose) - log("%*s-> import cell: %s\n", 2+2*GetSize(recursive_cells), "", log_id(cell)); + log("%*s-> import cell: %s\n", 2+2*GetSize(recursive_cells), "", cell); decls.push_back(stringf("(define-fun |%s#%d| ((state |%s_s|)) Bool %s) ; %s\n", get_id(module), idcounter, get_id(module), processed_expr.c_str(), log_signal(sig_y))); @@ -541,7 +541,7 @@ struct Smt2Worker { if (verbose) log("%*s=> export_cell %s (%s) [%s]\n", 2+2*GetSize(recursive_cells), "", - log_id(cell), log_id(cell->type), exported_cells.count(cell) ? "old" : "new"); + cell, cell->type.unescape(), exported_cells.count(cell) ? "old" : "new"); if (recursive_cells.count(cell)) log_error("Found logic loop in module %s! See cell %s.\n", get_id(module), get_id(cell)); @@ -750,7 +750,7 @@ struct Smt2Worker get_bv(sig_b.extract(i*width, width)).c_str(), processed_expr.c_str()); if (verbose) - log("%*s-> import cell: %s\n", 2+2*GetSize(recursive_cells), "", log_id(cell)); + log("%*s-> import cell: %s\n", 2+2*GetSize(recursive_cells), "", cell); RTLIL::SigSpec sig = sigmap(cell->getPort(ID::Y)); decls.push_back(stringf("(define-fun |%s#%d| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", @@ -786,9 +786,9 @@ struct Smt2Worker has_async_wr = true; } if (has_async_wr && has_sync_wr) - log_error("Memory %s.%s has mixed clocked/nonclocked write ports. This is not supported by \"write_smt2\".\n", log_id(cell), log_id(module)); + log_error("Memory %s.%s has mixed clocked/nonclocked write ports. This is not supported by \"write_smt2\".\n", cell, module); - decls.push_back(stringf("; yosys-smt2-memory %s %d %d %d %d %s\n", get_id(mem->memid), abits, mem->width, GetSize(mem->rd_ports), GetSize(mem->wr_ports), has_async_wr ? "async" : "sync")); + decls.push_back(stringf("; yosys-smt2-memory %s %d %d %d %d %s\n", mem->memid.unescape(), abits, mem->width, GetSize(mem->rd_ports), GetSize(mem->wr_ports), has_async_wr ? "async" : "sync")); decls.push_back(witness_memory(get_id(mem->memid), cell, mem)); string memstate; @@ -813,7 +813,7 @@ struct Smt2Worker if (port.clk_enable) log_error("Read port %d (%s) of memory %s.%s is clocked. This is not supported by \"write_smt2\"! " - "Call \"memory\" with -nordff to avoid this error.\n", i, log_signal(port.data), log_id(mem->memid), log_id(module)); + "Call \"memory\" with -nordff to avoid this error.\n", i, log_signal(port.data), mem->memid.unescape(), module); decls.push_back(stringf("(define-fun |%s_m:R%dA %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", get_id(module), i, get_id(mem->memid), get_id(module), abits, addr.c_str(), log_signal(addr_sig))); @@ -857,7 +857,7 @@ struct Smt2Worker if (port.clk_enable) log_error("Read port %d (%s) of memory %s.%s is clocked. This is not supported by \"write_smt2\"! " - "Call \"memory\" with -nordff to avoid this error.\n", i, log_signal(port.data), log_id(mem->memid), log_id(module)); + "Call \"memory\" with -nordff to avoid this error.\n", i, log_signal(port.data), mem->memid.unescape(), module); decls.push_back(stringf("(define-fun |%s_m:R%dA %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", get_id(module), i, get_id(mem->memid), get_id(module), abits, addr.c_str(), log_signal(addr_sig))); @@ -928,30 +928,30 @@ struct Smt2Worker if (cell->type.in(ID($dffe), ID($sdff), ID($sdffe), ID($sdffce)) || cell->type.str().substr(0, 6) == "$_SDFF" || (cell->type.str().substr(0, 6) == "$_DFFE" && cell->type.str().size() == 10)) { log_error("Unsupported cell type %s for cell %s.%s -- please run `dffunmap` before `write_smt2`.\n", - log_id(cell->type), log_id(module), log_id(cell)); + cell->type.unescape(), module, cell); } if (cell->type.in(ID($adff), ID($adffe), ID($aldff), ID($aldffe), ID($dffsr), ID($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF" || cell->type.str().substr(0, 7) == "$_ALDFF") { log_error("Unsupported cell type %s for cell %s.%s -- please run `async2sync; dffunmap` or `clk2fflogic` before `write_smt2`.\n", - log_id(cell->type), log_id(module), log_id(cell)); + cell->type.unescape(), module, cell); } if (cell->type.in(ID($sr), ID($dlatch), ID($adlatch), ID($dlatchsr)) || cell->type.str().substr(0, 8) == "$_DLATCH" || cell->type.str().substr(0, 5) == "$_SR_") { log_error("Unsupported cell type %s for cell %s.%s -- please run `clk2fflogic` before `write_smt2`.\n", - log_id(cell->type), log_id(module), log_id(cell)); + cell->type, module, cell); } log_error("Unsupported cell type %s for cell %s.%s.\n", - log_id(cell->type), log_id(module), log_id(cell)); + cell->type, module, cell); } void verify_smtlib2_module() { if (!module->get_blackbox_attribute()) - log_error("Module %s with smtlib2_module attribute must also have blackbox attribute.\n", log_id(module)); + log_error("Module %s with smtlib2_module attribute must also have blackbox attribute.\n", module); if (module->cells().size() > 0) - log_error("Module %s with smtlib2_module attribute must not have any cells inside it.\n", log_id(module)); + log_error("Module %s with smtlib2_module attribute must not have any cells inside it.\n", module); for (auto wire : module->wires()) if (!wire->port_id) - log_error("Wire %s.%s must be input or output since module has smtlib2_module attribute.\n", log_id(module), - log_id(wire)); + log_error("Wire %s.%s must be input or output since module has smtlib2_module attribute.\n", module, + wire); } void run() @@ -991,8 +991,8 @@ struct Smt2Worker } bool is_smtlib2_comb_expr = wire->has_attribute(ID::smtlib2_comb_expr); if (is_smtlib2_comb_expr && !is_smtlib2_module) - log_error("smtlib2_comb_expr is only valid in a module with the smtlib2_module attribute: wire %s.%s", log_id(module), - log_id(wire)); + log_error("smtlib2_comb_expr is only valid in a module with the smtlib2_module attribute: wire %s.%s", module, + wire); if (wire->port_id || is_register || contains_clock || wire->get_bool_attribute(ID::keep) || (wiresmode && wire->name.isPublic())) { RTLIL::SigSpec sig = sigmap(wire); std::vector comments; @@ -1023,10 +1023,10 @@ struct Smt2Worker smtlib2_comb_expr = "(let (\n" + smtlib2_inputs + ")\n" + wire->get_string_attribute(ID::smtlib2_comb_expr) + "\n)"; if (wire->port_input || !wire->port_output) - log_error("smtlib2_comb_expr is only valid on output: wire %s.%s", log_id(module), log_id(wire)); + log_error("smtlib2_comb_expr is only valid on output: wire %s.%s", module, wire); if (!bvmode && GetSize(sig) > 1) log_error("smtlib2_comb_expr is unsupported on multi-bit wires when -nobv is specified: wire %s.%s", - log_id(module), log_id(wire)); + module, wire); comments.push_back(witness_signal("blackbox", wire->width, 0, get_id(wire), -1, wire)); } @@ -1075,7 +1075,7 @@ struct Smt2Worker if (wire->attributes.count(ID::init)) { if (is_smtlib2_module) log_error("init attribute not allowed on wires in module with smtlib2_module attribute: wire %s.%s", - log_id(module), log_id(wire)); + module, wire); RTLIL::SigSpec sig = sigmap(wire); Const val = wire->attributes.at(ID::init); @@ -1381,7 +1381,7 @@ struct Smt2Worker } } - if (verbose) log("=> finalizing SMT2 representation of %s.\n", log_id(module)); + if (verbose) log("=> finalizing SMT2 representation of %s.\n", module); for (auto c : hiercells) { assert_list.push_back(stringf("(|%s_a| (|%s_h %s| state))", get_id(c->type), get_id(module), get_id(c->name))); @@ -1867,12 +1867,12 @@ struct Smt2Backend : public Backend { for (auto &dep : it.second) if (module_deps.count(dep) > 0) goto not_ready_yet; - // log("Next in topological sort: %s\n", log_id(it.first->name)); + // log("Next in topological sort: %s\n", it.first->name.unescape()); sorted_modules.push_back(it.first); not_ready_yet:; } if (sorted_modules_idx == sorted_modules.size()) - log_error("Cyclic dependency between modules found! Cycle includes module %s.\n", log_id(module_deps.begin()->first->name)); + log_error("Cyclic dependency between modules found! Cycle includes module %s.\n", module_deps.begin()->first->name.unescape()); while (sorted_modules_idx < sorted_modules.size()) module_deps.erase(sorted_modules.at(sorted_modules_idx++)); } @@ -1902,7 +1902,7 @@ struct Smt2Backend : public Backend { if (module->has_processes_warn()) continue; - log("Creating SMT-LIBv2 representation of module %s.\n", log_id(module)); + log("Creating SMT-LIBv2 representation of module %s.\n", module); Smt2Worker worker(module, bvmode, memmode, wiresmode, verbose, statebv, statedt, forallmode, mod_stbv_width, mod_clk_cache); worker.run(); diff --git a/backends/smv/smv.cc b/backends/smv/smv.cc index acefad060..01f95ef45 100644 --- a/backends/smv/smv.cc +++ b/backends/smv/smv.cc @@ -217,7 +217,7 @@ struct SmvWorker partial_assignment_wires.insert(wire); if (wire->port_input) - inputvars.push_back(stringf("%s : unsigned word[%d]; -- %s", cid(wire->name), wire->width, log_id(wire))); + inputvars.push_back(stringf("%s : unsigned word[%d]; -- %s", cid(wire->name), wire->width, wire)); if (wire->attributes.count(ID::init)) assignments.push_back(stringf("init(%s) := %s;", lvalue(wire), rvalue(wire->attributes.at(ID::init)))); @@ -579,18 +579,18 @@ struct SmvWorker if (cell->type[0] == '$') { if (cell->type.in(ID($dffe), ID($sdff), ID($sdffe), ID($sdffce)) || cell->type.str().substr(0, 6) == "$_SDFF" || (cell->type.str().substr(0, 6) == "$_DFFE" && cell->type.str().size() == 10)) { log_error("Unsupported cell type %s for cell %s.%s -- please run `dffunmap` before `write_smv`.\n", - log_id(cell->type), log_id(module), log_id(cell)); + cell->type.unescape(), module, cell); } if (cell->type.in(ID($adff), ID($adffe), ID($aldff), ID($aldffe), ID($dffsr), ID($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF" || cell->type.str().substr(0, 7) == "$_ALDFF") { log_error("Unsupported cell type %s for cell %s.%s -- please run `async2sync; dffunmap` or `clk2fflogic` before `write_smv`.\n", - log_id(cell->type), log_id(module), log_id(cell)); + cell->type.unescape(), module, cell); } if (cell->type.in(ID($sr), ID($dlatch), ID($adlatch), ID($dlatchsr)) || cell->type.str().substr(0, 8) == "$_DLATCH" || cell->type.str().substr(0, 5) == "$_SR_") { log_error("Unsupported cell type %s for cell %s.%s -- please run `clk2fflogic` before `write_smv`.\n", - log_id(cell->type), log_id(module), log_id(cell)); + cell->type.unescape(), module, cell); } log_error("Unsupported cell type %s for cell %s.%s.\n", - log_id(cell->type), log_id(module), log_id(cell)); + cell->type.unescape(), module, cell); } // f << stringf(" %s : %s;\n", cid(cell->name), cid(cell->type)); @@ -799,7 +799,7 @@ struct SmvBackend : public Backend { *f << stringf("-- SMV description generated by %s\n", yosys_maybe_version()); - log("Creating SMV representation of module %s.\n", log_id(module)); + log("Creating SMV representation of module %s.\n", module); SmvWorker worker(module, verbose, *f); worker.run(); @@ -819,7 +819,7 @@ struct SmvBackend : public Backend { *f << stringf("-- SMV description generated by %s\n", yosys_maybe_version()); for (auto module : modules) { - log("Creating SMV representation of module %s.\n", log_id(module)); + log("Creating SMV representation of module %s.\n", module); SmvWorker worker(module, verbose, *f); worker.run(); } diff --git a/backends/spice/spice.cc b/backends/spice/spice.cc index 16458d647..36caf6359 100644 --- a/backends/spice/spice.cc +++ b/backends/spice/spice.cc @@ -82,7 +82,7 @@ static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::De if (design->module(cell->type) == nullptr) { log_warning("no (blackbox) module for cell type `%s' (%s.%s) found! Guessing order of ports.\n", - log_id(cell->type), log_id(module), log_id(cell)); + cell->type.unescape(), module, cell); for (auto &conn : cell->connections()) { RTLIL::SigSpec sig = sigmap(conn.second); port_sigs.push_back(sig); @@ -224,9 +224,9 @@ struct SpiceBackend : public Backend { continue; if (module->processes.size() != 0) - log_error("Found unmapped processes in module %s: unmapped processes are not supported in SPICE backend!\n", log_id(module)); + log_error("Found unmapped processes in module %s: unmapped processes are not supported in SPICE backend!\n", module); if (module->memories.size() != 0) - log_error("Found unmapped memories in module %s: unmapped memories are not supported in SPICE backend!\n", log_id(module)); + log_error("Found unmapped memories in module %s: unmapped memories are not supported in SPICE backend!\n", module); if (module->name == RTLIL::escape_id(top_module_name)) { top_module = module; diff --git a/backends/table/table.cc b/backends/table/table.cc index 2bf64e7b1..bbb533965 100644 --- a/backends/table/table.cc +++ b/backends/table/table.cc @@ -77,8 +77,8 @@ struct TableBackend : public Backend { if (wire->port_id == 0) continue; - *f << log_id(module) << "\t"; - *f << log_id(wire) << "\t"; + *f << module->name.unescape() << "\t"; + *f << wire->name.unescape() << "\t"; *f << "-" << "\t"; *f << "-" << "\t"; @@ -97,10 +97,10 @@ struct TableBackend : public Backend { for (auto cell : module->cells()) for (auto conn : cell->connections()) { - *f << log_id(module) << "\t"; - *f << log_id(cell) << "\t"; - *f << log_id(cell->type) << "\t"; - *f << log_id(conn.first) << "\t"; + *f << module->name.unescape() << "\t"; + *f << cell->name.unescape() << "\t"; + *f << cell->type.unescape() << "\t"; + *f << conn.first.unescape() << "\t"; if (cell->input(conn.first) && cell->output(conn.first)) *f << "inout" << "\t"; diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 73ffcbf3e..473918264 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -2388,7 +2388,7 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) log_warning("Module %s contains RTLIL processes with sync rules. Such RTLIL " "processes can't always be mapped directly to Verilog always blocks. " "unintended changes in simulation behavior are possible! Use \"proc\" " - "to convert processes to logic networks and registers.\n", log_id(module)); + "to convert processes to logic networks and registers.\n", module); f << stringf("\n"); for (auto it = module->processes.begin(); it != module->processes.end(); ++it) @@ -2714,7 +2714,7 @@ struct VerilogBackend : public Backend { continue; if (selected && !design->selected_whole_module(module->name)) { if (design->selected_module(module->name)) - log_cmd_error("Can't handle partially selected module %s!\n", log_id(module->name)); + log_cmd_error("Can't handle partially selected module %s!\n", module->name.unescape()); continue; } log("Dumping module `%s'.\n", module->name); diff --git a/docs/source/code_examples/extensions/my_cmd.cc b/docs/source/code_examples/extensions/my_cmd.cc index d52268b4a..742697b6e 100644 --- a/docs/source/code_examples/extensions/my_cmd.cc +++ b/docs/source/code_examples/extensions/my_cmd.cc @@ -14,7 +14,7 @@ struct MyPass : public Pass { log("Modules in current design:\n"); for (auto mod : design->modules()) - log(" %s (%d wires, %d cells)\n", log_id(mod), + log(" %s (%d wires, %d cells)\n", mod, GetSize(mod->wires()), GetSize(mod->cells())); } } MyPass; @@ -28,7 +28,7 @@ struct Test1Pass : public Pass { log_error("A module with the name absval already exists!\n"); RTLIL::Module *module = design->addModule("\\absval"); - log("Name of this module: %s\n", log_id(module)); + log("Name of this module: %s\n", module); RTLIL::Wire *a = module->addWire("\\a", 4); a->port_input = true; diff --git a/examples/cxx-api/scopeinfo_example.cc b/examples/cxx-api/scopeinfo_example.cc index fd5d2a781..edbd1533f 100644 --- a/examples/cxx-api/scopeinfo_example.cc +++ b/examples/cxx-api/scopeinfo_example.cc @@ -61,7 +61,7 @@ struct ScopeinfoExamplePass : public Pass { if (do_wires) { for (auto module : design->selected_modules()) { - log("Source hierarchy for all selected wires within %s:\n", log_id(module)); + log("Source hierarchy for all selected wires within %s:\n", module); ModuleHdlnameIndex index(module); index.index_scopeinfo_cells(); @@ -73,11 +73,11 @@ struct ScopeinfoExamplePass : public Pass { auto wire_scope = index.containing_scope(wire); if (!wire_scope.first.valid()) { - log_warning("Couldn't find containing scope for %s in index\n", log_id(wire)); + log_warning("Couldn't find containing scope for %s in index\n", wire); continue; } - log("%s %s\n", wire_scope.first.path_str(), log_id(wire_scope.second)); + log("%s %s\n", wire_scope.first.path_str(), wire_scope.second.unescape()); for (auto src : index.sources(wire)) log(" - %s\n", src); } @@ -127,9 +127,9 @@ struct ScopeinfoExamplePass : public Pass { continue; log("common_ancestor(%s %s%s%s, %s %s%s%s) = %s %s\n", - log_id(module), scope_i.first.path_str().c_str(), scope_i.first.is_root() ? "" : " ", log_id(scope_i.second), - log_id(module), scope_j.first.path_str().c_str(), scope_j.first.is_root() ? "" : " ", log_id(scope_j.second), - log_id(module), common.path_str().c_str() + module, scope_i.first.path_str().c_str(), scope_i.first.is_root() ? "" : " ", scope_i.second.unescape(), + module, scope_j.first.path_str().c_str(), scope_j.first.is_root() ? "" : " ", scope_j.second.unescape(), + module, common.path_str().c_str() ); if (++limit == 10) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 9931ef78f..b2cc613f2 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -224,7 +224,7 @@ AigerReader::AigerReader(RTLIL::Design *design, std::istream &f, RTLIL::IdString module = new RTLIL::Module; module->name = module_name; if (design->module(module->name)) - log_error("Duplicate definition of module %s!\n", log_id(module->name)); + log_error("Duplicate definition of module %s!\n", module->name.unescape()); } void AigerReader::parse_aiger() @@ -821,7 +821,7 @@ void AigerReader::post_process() RTLIL::Wire* wire = inputs[variable]; log_assert(wire); log_assert(wire->port_input); - log_debug("Renaming input %s", log_id(wire)); + log_debug("Renaming input %s", wire); RTLIL::Wire *existing = nullptr; if (index == 0) { @@ -835,7 +835,7 @@ void AigerReader::post_process() wire->port_input = false; module->connect(wire, existing); } - log_debug(" -> %s\n", log_id(escaped_s)); + log_debug(" -> %s\n", escaped_s.unescape()); } else { RTLIL::IdString indexed_name = stringf("%s[%d]", escaped_s, index); @@ -846,7 +846,7 @@ void AigerReader::post_process() module->connect(wire, existing); wire->port_input = false; } - log_debug(" -> %s\n", log_id(indexed_name)); + log_debug(" -> %s\n", indexed_name.unescape()); } if (wideports && !existing) { @@ -866,7 +866,7 @@ void AigerReader::post_process() RTLIL::Wire* wire = outputs[variable + co_count]; log_assert(wire); log_assert(wire->port_output); - log_debug("Renaming output %s", log_id(wire)); + log_debug("Renaming output %s", wire); RTLIL::Wire *existing; if (index == 0) { @@ -882,7 +882,7 @@ void AigerReader::post_process() module->connect(wire, existing); wire = existing; } - log_debug(" -> %s\n", log_id(escaped_s)); + log_debug(" -> %s\n", escaped_s.unescape()); } else { RTLIL::IdString indexed_name = stringf("%s[%d]", escaped_s, index); @@ -894,7 +894,7 @@ void AigerReader::post_process() existing->port_output = true; module->connect(wire, existing); } - log_debug(" -> %s\n", log_id(indexed_name)); + log_debug(" -> %s\n", indexed_name.unescape()); } if (wideports && !existing) { @@ -912,7 +912,7 @@ void AigerReader::post_process() else if (type == "box") { RTLIL::Cell* cell = module->cell(stringf("$box%d", variable)); if (!cell) - log_debug("Box %d (%s) no longer exists.\n", variable, log_id(escaped_s)); + log_debug("Box %d (%s) no longer exists.\n", variable, escaped_s.unescape()); else module->rename(cell, escaped_s); } diff --git a/frontends/aiger2/xaiger.cc b/frontends/aiger2/xaiger.cc index bbec47861..a62c52169 100644 --- a/frontends/aiger2/xaiger.cc +++ b/frontends/aiger2/xaiger.cc @@ -86,7 +86,7 @@ struct Xaiger2Frontend : public Frontend { Module *module = design->module(module_name); if (!module) - log_error("Module '%s' not found\n", log_id(module_name)); + log_error("Module '%s' not found\n", module_name.unescape()); std::ifstream map_file; map_file.open(map_filename); @@ -158,7 +158,7 @@ struct Xaiger2Frontend : public Frontend { } if (!def) - log_error("Bad map file: no module found for box type '%s'\n", log_id(box->type)); + log_error("Bad map file: no module found for box type '%s'\n", box->type.unescape()); if (box_seq >= (int) boxes.size()) { boxes.resize(box_seq + 1); @@ -276,9 +276,9 @@ struct Xaiger2Frontend : public Frontend { uint32_t nins = read_be32(*f); for (uint32_t j = 0; j < nins; j++) cell.ins.push_back(read_idstring(*f)); - log_debug("M: Cell %s (out %s, ins", log_id(cell.type), log_id(cell.out)); + log_debug("M: Cell %s (out %s, ins", cell.type.unescape(), cell.out.unescape()); for (auto in : cell.ins) - log_debug(" %s", log_id(in)); + log_debug(" %s", in.unescape()); log_debug(")\n"); } diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index c190bc7d4..256321252 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1544,7 +1544,7 @@ void AST::explode_interface_port(AstNode *module_ast, RTLIL::Module * intfmodule for (auto w : intfmodule->wires()){ auto loc = module_ast->location; auto wire = std::make_unique(loc, AST_WIRE, std::make_unique(loc, AST_RANGE, AstNode::mkconst_int(loc, w->width -1, true), AstNode::mkconst_int(loc, 0, true))); - std::string origname = log_id(w->name); + std::string origname = w->name.unescape(); std::string newname = intfname + "." + origname; wire->str = newname; if (modport != NULL) { @@ -1584,7 +1584,7 @@ bool AstModule::reprocess_if_necessary(RTLIL::Design *design) continue; if (design->module(modname) || design->module("$abstract" + modname)) { log("Reprocessing module %s because instantiated module %s has become available.\n", - log_id(name), log_id(modname)); + name.unescape(), modname); loadconfig(); process_and_replace_module(design, this, ast.get(), NULL); return true; @@ -1606,7 +1606,7 @@ void AstModule::expand_interfaces(RTLIL::Design *design, const dictwires()){ auto wire = std::make_unique(loc, AST_WIRE, std::make_unique(loc, AST_RANGE, AstNode::mkconst_int(loc, w->width -1, true), AstNode::mkconst_int(loc, 0, true))); - std::string newname = log_id(w->name); + std::string newname = w->name.unescape(); newname = intfname + "." + newname; wire->str = newname; new_ast->children.push_back(std::move(wire)); @@ -1679,7 +1679,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dictname); + interf_info += intf.second->name.unescape(); has_interfaces = true; } @@ -1735,7 +1735,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dictset_bool_attribute(ID::is_interface); } else { - log_error("No port with matching name found (%s) in %s. Stopping\n", log_id(intf.first), modname); + log_error("No port with matching name found (%s) in %s. Stopping\n", intf.first, modname); } } diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index d9bafcd3a..718d5aa23 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -2197,10 +2197,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) const auto* value = child->children[0].get(); if (value->type == AST_REALVALUE) log_file_warning(*location.begin.filename, location.begin.line, "Replacing floating point parameter %s.%s = %f with string.\n", - log_id(cell), log_id(paraname), value->realvalue); + cell, paraname.unescape(), value->realvalue); else if (value->type != AST_CONSTANT) input_error("Parameter %s.%s with non-constant value!\n", - log_id(cell), log_id(paraname)); + cell, paraname.unescape()); cell->parameters[paraname] = value->asParaConst(); continue; } diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 48a4291d2..1b98166e5 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1492,7 +1492,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin const RTLIL::Wire *ref = module->wire(port_name); if (ref == nullptr) input_error("Cell instance refers to port %s which does not exist in module %s!.\n", - log_id(port_name), log_id(module->name)); + port_name.unescape(), module->name.unescape()); // select the argument, if present log_assert(child->children.size() <= 1); diff --git a/frontends/blif/blifparse.cc b/frontends/blif/blifparse.cc index 350d7cafe..2eae64fa1 100644 --- a/frontends/blif/blifparse.cc +++ b/frontends/blif/blifparse.cc @@ -175,7 +175,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool obj_attributes = &module->attributes; obj_parameters = nullptr; if (design->module(module->name)) - log_error("Duplicate definition of module %s in line %d!\n", log_id(module->name), line_count); + log_error("Duplicate definition of module %s in line %d!\n", module->name.unescape(), line_count); design->add(module); continue; } diff --git a/frontends/json/jsonparse.cc b/frontends/json/jsonparse.cc index 803931f32..0fac902b5 100644 --- a/frontends/json/jsonparse.cc +++ b/frontends/json/jsonparse.cc @@ -295,7 +295,7 @@ void json_import(Design *design, string &modname, JsonNode *node) module->name = RTLIL::escape_id(modname.c_str()); if (design->module(module->name)) - log_error("Re-definition of module %s.\n", log_id(module->name)); + log_error("Re-definition of module %s.\n", module->name.unescape()); design->add(module); @@ -320,22 +320,22 @@ void json_import(Design *design, string &modname, JsonNode *node) JsonNode *port_node = ports_node->data_dict.at(ports_node->data_dict_keys[port_id-1]); if (port_node->type != 'D') - log_error("JSON port node '%s' is not a dictionary.\n", log_id(port_name)); + log_error("JSON port node '%s' is not a dictionary.\n", port_name.unescape()); if (port_node->data_dict.count("direction") == 0) - log_error("JSON port node '%s' has no direction attribute.\n", log_id(port_name)); + log_error("JSON port node '%s' has no direction attribute.\n", port_name.unescape()); if (port_node->data_dict.count("bits") == 0) - log_error("JSON port node '%s' has no bits attribute.\n", log_id(port_name)); + log_error("JSON port node '%s' has no bits attribute.\n", port_name.unescape()); JsonNode *port_direction_node = port_node->data_dict.at("direction"); JsonNode *port_bits_node = port_node->data_dict.at("bits"); if (port_direction_node->type != 'S') - log_error("JSON port node '%s' has non-string direction attribute.\n", log_id(port_name)); + log_error("JSON port node '%s' has non-string direction attribute.\n", port_name.unescape()); if (port_bits_node->type != 'A') - log_error("JSON port node '%s' has non-array bits attribute.\n", log_id(port_name)); + log_error("JSON port node '%s' has non-array bits attribute.\n", port_name.unescape()); Wire *port_wire = module->wire(port_name); @@ -370,7 +370,7 @@ void json_import(Design *design, string &modname, JsonNode *node) port_wire->port_input = true; port_wire->port_output = true; } else - log_error("JSON port node '%s' has invalid '%s' direction attribute.\n", log_id(port_name), port_direction_node->data_string); + log_error("JSON port node '%s' has invalid '%s' direction attribute.\n", port_name.unescape(), port_direction_node->data_string); port_wire->port_id = port_id; @@ -390,7 +390,7 @@ void json_import(Design *design, string &modname, JsonNode *node) module->connect(sigbit, State::Sz); else log_error("JSON port node '%s' has invalid '%s' bit string value on bit %d.\n", - log_id(port_name), bitval_node->data_string.c_str(), i); + port_name.unescape(), bitval_node->data_string.c_str(), i); } else if (bitval_node->type == 'N') { int bitidx = bitval_node->data_number; @@ -405,7 +405,7 @@ void json_import(Design *design, string &modname, JsonNode *node) signal_bits[bitidx] = sigbit; } } else - log_error("JSON port node '%s' has invalid bit value on bit %d.\n", log_id(port_name), i); + log_error("JSON port node '%s' has invalid bit value on bit %d.\n", port_name.unescape(), i); } } @@ -425,15 +425,15 @@ void json_import(Design *design, string &modname, JsonNode *node) JsonNode *net_node = net.second; if (net_node->type != 'D') - log_error("JSON netname node '%s' is not a dictionary.\n", log_id(net_name)); + log_error("JSON netname node '%s' is not a dictionary.\n", net_name.unescape()); if (net_node->data_dict.count("bits") == 0) - log_error("JSON netname node '%s' has no bits attribute.\n", log_id(net_name)); + log_error("JSON netname node '%s' has no bits attribute.\n", net_name.unescape()); JsonNode *bits_node = net_node->data_dict.at("bits"); if (bits_node->type != 'A') - log_error("JSON netname node '%s' has non-array bits attribute.\n", log_id(net_name)); + log_error("JSON netname node '%s' has non-array bits attribute.\n", net_name.unescape()); Wire *wire = module->wire(net_name); @@ -468,7 +468,7 @@ void json_import(Design *design, string &modname, JsonNode *node) module->connect(sigbit, State::Sz); else log_error("JSON netname node '%s' has invalid '%s' bit string value on bit %d.\n", - log_id(net_name), bitval_node->data_string.c_str(), i); + net_name.unescape(), bitval_node->data_string.c_str(), i); } else if (bitval_node->type == 'N') { int bitidx = bitval_node->data_number; @@ -479,7 +479,7 @@ void json_import(Design *design, string &modname, JsonNode *node) signal_bits[bitidx] = sigbit; } } else - log_error("JSON netname node '%s' has invalid bit value on bit %d.\n", log_id(net_name), i); + log_error("JSON netname node '%s' has invalid bit value on bit %d.\n", net_name.unescape(), i); } if (net_node->data_dict.count("attributes")) @@ -500,27 +500,27 @@ void json_import(Design *design, string &modname, JsonNode *node) JsonNode *cell_node = cell_node_it.second; if (cell_node->type != 'D') - log_error("JSON cells node '%s' is not a dictionary.\n", log_id(cell_name)); + log_error("JSON cells node '%s' is not a dictionary.\n", cell_name.unescape()); if (cell_node->data_dict.count("type") == 0) - log_error("JSON cells node '%s' has no type attribute.\n", log_id(cell_name)); + log_error("JSON cells node '%s' has no type attribute.\n", cell_name.unescape()); JsonNode *type_node = cell_node->data_dict.at("type"); if (type_node->type != 'S') - log_error("JSON cells node '%s' has a non-string type.\n", log_id(cell_name)); + log_error("JSON cells node '%s' has a non-string type.\n", cell_name.unescape()); IdString cell_type = RTLIL::escape_id(type_node->data_string.c_str()); Cell *cell = module->addCell(cell_name, cell_type); if (cell_node->data_dict.count("connections") == 0) - log_error("JSON cells node '%s' has no connections attribute.\n", log_id(cell_name)); + log_error("JSON cells node '%s' has no connections attribute.\n", cell_name.unescape()); JsonNode *connections_node = cell_node->data_dict.at("connections"); if (connections_node->type != 'D') - log_error("JSON cells node '%s' has non-dictionary connections attribute.\n", log_id(cell_name)); + log_error("JSON cells node '%s' has non-dictionary connections attribute.\n", cell_name.unescape()); for (auto &conn_it : connections_node->data_dict) { @@ -528,7 +528,7 @@ void json_import(Design *design, string &modname, JsonNode *node) JsonNode *conn_node = conn_it.second; if (conn_node->type != 'A') - log_error("JSON cells node '%s' connection '%s' is not an array.\n", log_id(cell_name), log_id(conn_name)); + log_error("JSON cells node '%s' connection '%s' is not an array.\n", cell_name.unescape(), conn_name.unescape()); SigSpec sig; @@ -547,7 +547,7 @@ void json_import(Design *design, string &modname, JsonNode *node) sig.append(State::Sz); else log_error("JSON cells node '%s' connection '%s' has invalid '%s' bit string value on bit %d.\n", - log_id(cell_name), log_id(conn_name), bitval_node->data_string.c_str(), i); + cell_name.unescape(), conn_name.unescape(), bitval_node->data_string.c_str(), i); } else if (bitval_node->type == 'N') { int bitidx = bitval_node->data_number; @@ -556,7 +556,7 @@ void json_import(Design *design, string &modname, JsonNode *node) sig.append(signal_bits.at(bitidx)); } else log_error("JSON cells node '%s' connection '%s' has invalid bit value on bit %d.\n", - log_id(cell_name), log_id(conn_name), i); + cell_name.unescape(), conn_name.unescape(), i); } @@ -587,20 +587,20 @@ void json_import(Design *design, string &modname, JsonNode *node) mem->name = memory_name; if (memory_node->type != 'D') - log_error("JSON memory node '%s' is not a dictionary.\n", log_id(memory_name)); + log_error("JSON memory node '%s' is not a dictionary.\n", memory_name.unescape()); if (memory_node->data_dict.count("width") == 0) - log_error("JSON memory node '%s' has no width attribute.\n", log_id(memory_name)); + log_error("JSON memory node '%s' has no width attribute.\n", memory_name.unescape()); JsonNode *width_node = memory_node->data_dict.at("width"); if (width_node->type != 'N') - log_error("JSON memory node '%s' has a non-number width.\n", log_id(memory_name)); + log_error("JSON memory node '%s' has a non-number width.\n", memory_name.unescape()); mem->width = width_node->data_number; if (memory_node->data_dict.count("size") == 0) - log_error("JSON memory node '%s' has no size attribute.\n", log_id(memory_name)); + log_error("JSON memory node '%s' has no size attribute.\n", memory_name.unescape()); JsonNode *size_node = memory_node->data_dict.at("size"); if (size_node->type != 'N') - log_error("JSON memory node '%s' has a non-number size.\n", log_id(memory_name)); + log_error("JSON memory node '%s' has a non-number size.\n", memory_name.unescape()); mem->size = size_node->data_number; mem->start_offset = 0; diff --git a/frontends/rpc/rpc_frontend.cc b/frontends/rpc/rpc_frontend.cc index c21867b30..bc5ef013d 100644 --- a/frontends/rpc/rpc_frontend.cc +++ b/frontends/rpc/rpc_frontend.cc @@ -212,7 +212,7 @@ struct RpcModule : RTLIL::Module { for (auto module : derived_design->modules_) { std::string mangled_name = name_mangling[module.first.str()]; - log("Importing `%s' as `%s'.\n", log_id(module.first), log_id(mangled_name)); + log("Importing `%s' as `%s'.\n", module.first.unescape(), mangled_name); module.second->name = mangled_name; module.second->design = design; diff --git a/frontends/rtlil/rtlil_frontend.cc b/frontends/rtlil/rtlil_frontend.cc index 7e2ec5460..4709c76ed 100644 --- a/frontends/rtlil/rtlil_frontend.cc +++ b/frontends/rtlil/rtlil_frontend.cc @@ -332,7 +332,7 @@ struct RTLILFrontendWorker { error("No wires found for legalization"); int hash = hash_ops::hash(id).yield(); RTLIL::Wire *wire = current_module->wire_at(abs(hash % wires_size)); - log("Legalizing wire `%s' to `%s'.\n", log_id(id), log_id(wire->name)); + log("Legalizing wire `%s' to `%s'.\n", id.unescape(), wire->name.unescape()); return wire; } diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 6a1c81aa4..ec3d21ccd 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -1392,13 +1392,13 @@ void VerificImporter::merge_past_ffs_clock(pool &candidates, SigBi RTLIL::Cell *new_ff = module->addDff(NEW_ID, clock, sig_d, sig_q, clock_pol); if (verific_verbose) - log(" merging single-bit past_ffs into new %d-bit ff %s.\n", GetSize(sig_d), log_id(new_ff)); + log(" merging single-bit past_ffs into new %d-bit ff %s.\n", GetSize(sig_d), new_ff); for (int i = 0; i < GetSize(sig_d); i++) for (auto old_ff : dbits_db[sig_d[i]]) { if (verific_verbose) - log(" replacing old ff %s on bit %d.\n", log_id(old_ff), i); + log(" replacing old ff %s on bit %d.\n", old_ff, i); SigBit old_q = old_ff->getPort(ID::Q); SigBit new_q = sig_q[i]; @@ -1736,7 +1736,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma RTLIL::IdString wire_name = module->uniquify(mode_names || net->IsUserDeclared() ? RTLIL::escape_id(net->Name()) : new_verific_id(net)); if (verific_verbose) - log(" importing net %s as %s.\n", net->Name(), log_id(wire_name)); + log(" importing net %s as %s.\n", net->Name(), wire_name.unescape()); RTLIL::Wire *wire = module->addWire(wire_name); import_attributes(wire->attributes, net, nl, 1); @@ -1760,7 +1760,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma RTLIL::IdString wire_name = module->uniquify(mode_names || netbus->IsUserDeclared() ? RTLIL::escape_id(netbus->Name()) : new_verific_id(netbus)); if (verific_verbose) - log(" importing netbus %s as %s.\n", netbus->Name(), log_id(wire_name)); + log(" importing netbus %s as %s.\n", netbus->Name(), wire_name.unescape()); RTLIL::Wire *wire = module->addWire(wire_name, netbus->Size()); wire->start_offset = min(netbus->LeftIndex(), netbus->RightIndex()); @@ -1894,7 +1894,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma RTLIL::IdString inst_name = module->uniquify(mode_names || inst->IsUserDeclared() ? RTLIL::escape_id(inst->Name()) : new_verific_id(inst)); if (verific_verbose) - log(" importing cell %s (%s) as %s.\n", inst->Name(), inst->View()->Owner()->Name(), log_id(inst_name)); + log(" importing cell %s (%s) as %s.\n", inst->Name(), inst->View()->Owner()->Name(), inst_name.unescape()); if (mode_verific) goto import_verific_cells; @@ -2258,7 +2258,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma for (auto &it : cell_port_conns) { if (verific_verbose) - log(" .%s(%s)\n", log_id(it.first), log_signal(it.second)); + log(" .%s(%s)\n", it.first.unescape(), log_signal(it.second)); cell->setPort(it.first, it.second); } } diff --git a/kernel/cost.cc b/kernel/cost.cc index 4942823d3..230afdeb1 100644 --- a/kernel/cost.cc +++ b/kernel/cost.cc @@ -210,6 +210,6 @@ unsigned int CellCosts::get(RTLIL::Cell *cell) // TODO: $fsm // ignored: $pow $memrd $memwr $meminit (and v2 counterparts) - log_warning("Can't determine cost of %s cell (%d parameters).\n", log_id(cell->type), GetSize(cell->parameters)); + log_warning("Can't determine cost of %s cell (%d parameters).\n", cell->type.unescape(), GetSize(cell->parameters)); return 1; } diff --git a/kernel/drivertools.cc b/kernel/drivertools.cc index 90bfb0ee7..55616dea1 100644 --- a/kernel/drivertools.cc +++ b/kernel/drivertools.cc @@ -866,7 +866,7 @@ DriveSpec DriverMap::operator()(DriveSpec spec) std::string log_signal(DriveChunkWire const &chunk) { - const char *id = log_id(chunk.wire->name); + std::string id = chunk.wire->name.unescape(); if (chunk.is_whole()) return id; if (chunk.width == 1) @@ -877,8 +877,8 @@ std::string log_signal(DriveChunkWire const &chunk) std::string log_signal(DriveChunkPort const &chunk) { - const char *cell_id = log_id(chunk.cell->name); - const char *port_id = log_id(chunk.port); + std::string cell_id = chunk.cell->name.unescape(); + std::string port_id = chunk.port.unescape(); if (chunk.is_whole()) return stringf("%s <%s>", cell_id, port_id); if (chunk.width == 1) diff --git a/kernel/ff.cc b/kernel/ff.cc index 7dd5e24ac..727a9d9cb 100644 --- a/kernel/ff.cc +++ b/kernel/ff.cc @@ -792,7 +792,7 @@ void FfData::flip_bits(const pool &bits) { Wire *new_q = module->addWire(NEW_ID, width); if (has_sr && cell) { - log_warning("Flipping D/Q/init and inserting priority fixup to legalize %s.%s [%s].\n", log_id(module->name), log_id(cell->name), log_id(cell->type)); + log_warning("Flipping D/Q/init and inserting priority fixup to legalize %s.%s [%s].\n", module->name.unescape(), cell->name.unescape(), cell->type.unescape()); } if (is_fine) { diff --git a/kernel/functional.cc b/kernel/functional.cc index 2a1bf598a..4d1423b28 100644 --- a/kernel/functional.cc +++ b/kernel/functional.cc @@ -572,7 +572,7 @@ private: const auto &wr = mem->wr_ports[i]; if (wr.clk_enable) log_error("Write port %zd of memory %s.%s is clocked. This is not supported by the functional backend. " - "Call async2sync or clk2fflogic to avoid this error.\n", i, log_id(mem->module), log_id(mem->memid)); + "Call async2sync or clk2fflogic to avoid this error.\n", i, mem->module, mem->memid.unescape()); Node en = enqueue(driver_map(DriveSpec(wr.en))); Node addr = enqueue(driver_map(DriveSpec(wr.addr))); Node new_data = enqueue(driver_map(DriveSpec(wr.data))); @@ -582,12 +582,12 @@ private: } if (mem->rd_ports.empty()) log_error("Memory %s.%s has no read ports. This is not supported by the functional backend. " - "Call opt_clean to remove it.", log_id(mem->module), log_id(mem->memid)); + "Call opt_clean to remove it.", mem->module, mem->memid.unescape()); for (size_t i = 0; i < mem->rd_ports.size(); i++) { const auto &rd = mem->rd_ports[i]; if (rd.clk_enable) log_error("Read port %zd of memory %s.%s is clocked. This is not supported by the functional backend. " - "Call memory_nordff to avoid this error.\n", i, log_id(mem->module), log_id(mem->memid)); + "Call memory_nordff to avoid this error.\n", i, mem->module, mem->memid.unescape()); Node addr = enqueue(driver_map(DriveSpec(rd.addr))); read_results.push_back(factory.memory_read(node, addr)); } @@ -609,7 +609,7 @@ private: FfData ff(&ff_initvals, cell); if (!ff.has_gclk) log_error("The design contains a %s flip-flop at %s. This is not supported by the functional backend. " - "Call async2sync or clk2fflogic to avoid this error.\n", log_id(cell->type), log_id(cell)); + "Call async2sync or clk2fflogic to avoid this error.\n", cell->type.unescape(), cell); auto &state = factory.add_state(ff.name, ID($state), Sort(ff.width)); Node q_value = factory.value(state); factory.suggest_name(q_value, ff.name); diff --git a/kernel/log.cc b/kernel/log.cc index b114f1eaf..fd3f75502 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -586,7 +586,7 @@ void log_flush() } void log_dump_val_worker(RTLIL::IdString v) { - log("%s", log_id(v)); + log("%s", v.unescape()); } void log_dump_val_worker(RTLIL::SigSpec v) { diff --git a/kernel/mem.cc b/kernel/mem.cc index 02d12dea4..2f7f16c7a 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -663,15 +663,15 @@ namespace { auto addr = cell->getPort(ID::ADDR); auto data = cell->getPort(ID::DATA); if (!addr.is_fully_const()) - log_error("Non-constant address %s in memory initialization %s.\n", log_signal(addr), log_id(cell)); + log_error("Non-constant address %s in memory initialization %s.\n", log_signal(addr), cell); if (!data.is_fully_const()) - log_error("Non-constant data %s in memory initialization %s.\n", log_signal(data), log_id(cell)); + log_error("Non-constant data %s in memory initialization %s.\n", log_signal(data), cell); init.addr = addr.as_const(); init.data = data.as_const(); if (cell->type == ID($meminit_v2)) { auto en = cell->getPort(ID::EN); if (!en.is_fully_const()) - log_error("Non-constant enable %s in memory initialization %s.\n", log_signal(en), log_id(cell)); + log_error("Non-constant enable %s in memory initialization %s.\n", log_signal(en), cell); init.en = en.as_const(); } else { init.en = RTLIL::Const(State::S1, mem->width); @@ -1022,7 +1022,7 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { if (c) log("Extracted %s FF from read port %d of %s.%s: %s\n", trans_use_addr ? "addr" : "data", - idx, log_id(module), log_id(memid), log_id(c)); + idx, module, memid.unescape(), c); port.en = State::S1; port.clk = State::S0; diff --git a/kernel/modtools.h b/kernel/modtools.h index 285f22b2a..bdcb0f108 100644 --- a/kernel/modtools.h +++ b/kernel/modtools.h @@ -320,8 +320,8 @@ struct ModIndex : public RTLIL::Monitor if (it.second.is_output) log(" PRIMARY OUTPUT\n"); for (auto &port : it.second.ports) - log(" PORT: %s.%s[%d] (%s)\n", log_id(port.cell), - log_id(port.port), port.offset, log_id(port.cell->type)); + log(" PORT: %s.%s[%d] (%s)\n", port.cell, + port.port.unescape(), port.offset, port.cell->type.unescape()); } } }; diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index a99f0803e..020a4ec0c 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1226,7 +1226,7 @@ void RTLIL::Design::add(RTLIL::Module *module) mon->notify_module_add(module); if (yosys_xtrace) { - log("#X# New Module: %s\n", log_id(module)); + log("#X# New Module: %s\n", module); log_backtrace("-X- ", yosys_xtrace-1); } } @@ -1252,7 +1252,7 @@ RTLIL::Module *RTLIL::Design::addModule(RTLIL::IdString name) mon->notify_module_add(module); if (yosys_xtrace) { - log("#X# New Module: %s\n", log_id(module)); + log("#X# New Module: %s\n", module); log_backtrace("-X- ", yosys_xtrace-1); } @@ -1330,7 +1330,7 @@ void RTLIL::Design::remove(RTLIL::Module *module) mon->notify_module_del(module); if (yosys_xtrace) { - log("#X# Remove Module: %s\n", log_id(module)); + log("#X# Remove Module: %s\n", module); log_backtrace("-X- ", yosys_xtrace-1); } @@ -1472,22 +1472,22 @@ std::vector RTLIL::Design::selected_modules(RTLIL::SelectPartial switch (boxes) { case RTLIL::SB_UNBOXED_WARN: - log_warning("Ignoring boxed module %s.\n", log_id(it.first)); + log_warning("Ignoring boxed module %s.\n", it.first.unescape()); break; case RTLIL::SB_EXCL_BB_WARN: - log_warning("Ignoring blackbox module %s.\n", log_id(it.first)); + log_warning("Ignoring blackbox module %s.\n", it.first.unescape()); break; case RTLIL::SB_UNBOXED_ERR: - log_error("Unsupported boxed module %s.\n", log_id(it.first)); + log_error("Unsupported boxed module %s.\n", it.first.unescape()); break; case RTLIL::SB_EXCL_BB_ERR: - log_error("Unsupported blackbox module %s.\n", log_id(it.first)); + log_error("Unsupported blackbox module %s.\n", it.first.unescape()); break; case RTLIL::SB_UNBOXED_CMDERR: - log_cmd_error("Unsupported boxed module %s.\n", log_id(it.first)); + log_cmd_error("Unsupported boxed module %s.\n", it.first.unescape()); break; case RTLIL::SB_EXCL_BB_CMDERR: - log_cmd_error("Unsupported blackbox module %s.\n", log_id(it.first)); + log_cmd_error("Unsupported blackbox module %s.\n", it.first.unescape()); break; default: break; @@ -1496,13 +1496,13 @@ std::vector RTLIL::Design::selected_modules(RTLIL::SelectPartial switch(partials) { case RTLIL::SELECT_WHOLE_WARN: - log_warning("Ignoring partially selected module %s.\n", log_id(it.first)); + log_warning("Ignoring partially selected module %s.\n", it.first.unescape()); break; case RTLIL::SELECT_WHOLE_ERR: - log_error("Unsupported partially selected module %s.\n", log_id(it.first)); + log_error("Unsupported partially selected module %s.\n", it.first.unescape()); break; case RTLIL::SELECT_WHOLE_CMDERR: - log_cmd_error("Unsupported partially selected module %s.\n", log_id(it.first)); + log_cmd_error("Unsupported partially selected module %s.\n", it.first.unescape()); break; default: break; @@ -2796,14 +2796,14 @@ bool RTLIL::Module::has_processes() const bool RTLIL::Module::has_memories_warn() const { if (!memories.empty()) - log_warning("Ignoring module %s because it contains memories (run 'memory' command first).\n", log_id(this)); + log_warning("Ignoring module %s because it contains memories (run 'memory' command first).\n", this); return !memories.empty(); } bool RTLIL::Module::has_processes_warn() const { if (!processes.empty()) - log_warning("Ignoring module %s because it contains processes (run 'proc' command first).\n", log_id(this)); + log_warning("Ignoring module %s because it contains processes (run 'proc' command first).\n", this); return !processes.empty(); } @@ -3095,7 +3095,7 @@ void RTLIL::Module::connect(const RTLIL::SigSig &conn) } if (yosys_xtrace) { - log("#X# Connect (SigSig) in %s: %s = %s (%d bits)\n", log_id(this), log_signal(conn.first), log_signal(conn.second), GetSize(conn.first)); + log("#X# Connect (SigSig) in %s: %s = %s (%d bits)\n", this, log_signal(conn.first), log_signal(conn.second), GetSize(conn.first)); log_backtrace("-X- ", yosys_xtrace-1); } @@ -3118,7 +3118,7 @@ void RTLIL::Module::new_connections(const std::vector &new_conn) mon->notify_connect(this, new_conn); if (yosys_xtrace) { - log("#X# New connections vector in %s:\n", log_id(this)); + log("#X# New connections vector in %s:\n", this); for (auto &conn: new_conn) log("#X# %s = %s (%d bits)\n", log_signal(conn.first), log_signal(conn.second), GetSize(conn.first)); log_backtrace("-X- ", yosys_xtrace-1); diff --git a/kernel/rtlil_bufnorm.cc b/kernel/rtlil_bufnorm.cc index 5f74b3380..19474b565 100644 --- a/kernel/rtlil_bufnorm.cc +++ b/kernel/rtlil_bufnorm.cc @@ -146,7 +146,7 @@ void RTLIL::Module::bufNormalize() // already enqueued or becomes reachable when denormalizing $buf or // $connect cells. auto enqueue_cell_port = [&](Cell *cell, IdString port) { - xlog("processing cell port %s.%s\n", log_id(cell), log_id(port)); + xlog("processing cell port %s.%s\n", cell, port.unescape()); // An empty cell type means the cell got removed if (cell->type.empty()) @@ -270,7 +270,7 @@ void RTLIL::Module::bufNormalize() // normalized mode). while (wire_queue_pos < GetSize(wire_queue_entries)) { auto wire = wire_queue_entries[wire_queue_pos++]; - xlog("processing wire %s\n", log_id(wire)); + xlog("processing wire %s\n", wire); if (wire->driverCell_) { Cell *cell = wire->driverCell_; @@ -287,7 +287,7 @@ void RTLIL::Module::bufNormalize() log_assert(connect_cell->type == ID($connect)); SigSpec const &sig_a = connect_cell->getPort(ID::A); SigSpec const &sig_b = connect_cell->getPort(ID::B); - xlog("found $connect cell %s: %s <-> %s\n", log_id(connect_cell), log_signal(sig_a), log_signal(sig_b)); + xlog("found $connect cell %s: %s <-> %s\n", connect_cell, log_signal(sig_a), log_signal(sig_b)); for (auto &side : {sig_a, sig_b}) for (auto chunk : side.chunks()) if (chunk.wire) @@ -452,7 +452,7 @@ void RTLIL::Module::bufNormalize() } if (wire->driverCell_ == nullptr) { - xlog("wire %s drivers %s\n", log_id(wire), log_signal(wire_drivers)); + xlog("wire %s drivers %s\n", wire, log_signal(wire_drivers)); addBuf(NEW_ID, wire_drivers, wire); } } @@ -541,7 +541,7 @@ void RTLIL::Cell::unsetPort(RTLIL::IdString portname) mon->notify_connect(this, conn_it->first, conn_it->second, signal); if (yosys_xtrace) { - log("#X# Unconnect %s.%s.%s\n", log_id(this->module), log_id(this), log_id(portname)); + log("#X# Unconnect %s.%s.%s\n", this->module, this, portname.unescape()); log_backtrace("-X- ", yosys_xtrace-1); } @@ -601,7 +601,7 @@ void RTLIL::Cell::setPort(RTLIL::IdString portname, RTLIL::SigSpec signal) mon->notify_connect(this, conn_it->first, conn_it->second, signal); if (yosys_xtrace) { - log("#X# Connect %s.%s.%s = %s (%d)\n", log_id(this->module), log_id(this), log_id(portname), log_signal(signal), GetSize(signal)); + log("#X# Connect %s.%s.%s = %s (%d)\n", this->module, this, portname.unescape(), log_signal(signal), GetSize(signal)); log_backtrace("-X- ", yosys_xtrace-1); } diff --git a/kernel/satgen.cc b/kernel/satgen.cc index 7fbcba1b2..9fddc303e 100644 --- a/kernel/satgen.cc +++ b/kernel/satgen.cc @@ -1395,9 +1395,9 @@ void report_missing_model(bool warn_only, RTLIL::Cell* cell) { std::string s; if (cell->is_builtin_ff()) - s = stringf("No SAT model available for async FF cell %s (%s). Consider running `async2sync` or `clk2fflogic` first.\n", log_id(cell), log_id(cell->type)); + s = stringf("No SAT model available for async FF cell %s (%s). Consider running `async2sync` or `clk2fflogic` first.\n", cell, cell->type.unescape()); else - s = stringf("No SAT model available for cell %s (%s).\n", log_id(cell), log_id(cell->type)); + s = stringf("No SAT model available for cell %s (%s).\n", cell, cell->type.unescape()); if (warn_only) { log_formatted_warning_noprefix(s); diff --git a/kernel/scopeinfo.h b/kernel/scopeinfo.h index a3939b903..e06beb1dc 100644 --- a/kernel/scopeinfo.h +++ b/kernel/scopeinfo.h @@ -328,7 +328,7 @@ struct ModuleItem { [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(ptr); return h; } }; -static inline void log_dump_val_worker(typename IdTree::Cursor cursor ) { log("%p %s", cursor.target, log_id(cursor.scope_name)); } +static inline void log_dump_val_worker(typename IdTree::Cursor cursor ) { log("%p %s", cursor.target, cursor.scope_name.unescape()); } template static inline void log_dump_val_worker(const typename std::unique_ptr &cursor ) { log("unique %p", cursor.get()); } diff --git a/kernel/timinginfo.h b/kernel/timinginfo.h index ff60415bd..e2e094b62 100644 --- a/kernel/timinginfo.h +++ b/kernel/timinginfo.h @@ -105,21 +105,21 @@ struct TimingInfo auto dst = cell->getPort(ID::DST); for (const auto &c : src.chunks()) if (!c.wire || !c.wire->port_input) - log_error("Module '%s' contains specify cell '%s' where SRC '%s' is not a module input.\n", log_id(module), log_id(cell), log_signal(src)); + log_error("Module '%s' contains specify cell '%s' where SRC '%s' is not a module input.\n", module, cell, log_signal(src)); for (const auto &c : dst.chunks()) if (!c.wire || !c.wire->port_output) - log_error("Module '%s' contains specify cell '%s' where DST '%s' is not a module output.\n", log_id(module), log_id(cell), log_signal(dst)); + log_error("Module '%s' contains specify cell '%s' where DST '%s' is not a module output.\n", module, cell, log_signal(dst)); int rise_max = cell->getParam(ID::T_RISE_MAX).as_int(); int fall_max = cell->getParam(ID::T_FALL_MAX).as_int(); int max = std::max(rise_max,fall_max); if (max < 0) - log_error("Module '%s' contains specify cell '%s' with T_{RISE,FALL}_MAX < 0.\n", log_id(module), log_id(cell)); + log_error("Module '%s' contains specify cell '%s' with T_{RISE,FALL}_MAX < 0.\n", module, cell); if (cell->getParam(ID::FULL).as_bool()) { for (const auto &s : src) for (const auto &d : dst) { auto r = t.comb.insert(BitBit(s,d)); if (!r.second) - log_error("Module '%s' contains multiple specify cells for SRC '%s' and DST '%s'.\n", log_id(module), log_signal(s), log_signal(d)); + log_error("Module '%s' contains multiple specify cells for SRC '%s' and DST '%s'.\n", module, log_signal(s), log_signal(d)); r.first->second = max; } } @@ -130,7 +130,7 @@ struct TimingInfo const auto &d = dst[i]; auto r = t.comb.insert(BitBit(s,d)); if (!r.second) - log_error("Module '%s' contains multiple specify cells for SRC '%s' and DST '%s'.\n", log_id(module), log_signal(s), log_signal(d)); + log_error("Module '%s' contains multiple specify cells for SRC '%s' and DST '%s'.\n", module, log_signal(s), log_signal(d)); r.first->second = max; } } @@ -139,15 +139,15 @@ struct TimingInfo auto src = cell->getPort(ID::SRC).as_bit(); auto dst = cell->getPort(ID::DST); if (!src.wire || !src.wire->port_input) - log_error("Module '%s' contains specify cell '%s' where SRC '%s' is not a module input.\n", log_id(module), log_id(cell), log_signal(src)); + log_error("Module '%s' contains specify cell '%s' where SRC '%s' is not a module input.\n", module, cell, log_signal(src)); for (const auto &c : dst.chunks()) if (!c.wire->port_output) - log_error("Module '%s' contains specify cell '%s' where DST '%s' is not a module output.\n", log_id(module), log_id(cell), log_signal(dst)); + log_error("Module '%s' contains specify cell '%s' where DST '%s' is not a module output.\n", module, cell, log_signal(dst)); int rise_max = cell->getParam(ID::T_RISE_MAX).as_int(); int fall_max = cell->getParam(ID::T_FALL_MAX).as_int(); int max = std::max(rise_max,fall_max); if (max < 0) { - log_warning("Module '%s' contains specify cell '%s' with T_{RISE,FALL}_MAX < 0 which is currently unsupported. Clamping to 0.\n", log_id(module), log_id(cell)); + log_warning("Module '%s' contains specify cell '%s' with T_{RISE,FALL}_MAX < 0 which is currently unsupported. Clamping to 0.\n", module, cell); max = 0; } for (const auto &d : dst) { @@ -167,12 +167,12 @@ struct TimingInfo auto dst = cell->getPort(ID::DST).as_bit(); for (const auto &c : src.chunks()) if (!c.wire || !c.wire->port_input) - log_error("Module '%s' contains specify cell '%s' where SRC '%s' is not a module input.\n", log_id(module), log_id(cell), log_signal(src)); + log_error("Module '%s' contains specify cell '%s' where SRC '%s' is not a module input.\n", module, cell, log_signal(src)); if (!dst.wire || !dst.wire->port_input) - log_error("Module '%s' contains specify cell '%s' where DST '%s' is not a module input.\n", log_id(module), log_id(cell), log_signal(dst)); + log_error("Module '%s' contains specify cell '%s' where DST '%s' is not a module input.\n", module, cell, log_signal(dst)); int max = cell->getParam(ID::T_LIMIT_MAX).as_int(); if (max < 0) { - log_warning("Module '%s' contains specify cell '%s' with T_LIMIT_MAX < 0 which is currently unsupported. Clamping to 0.\n", log_id(module), log_id(cell)); + log_warning("Module '%s' contains specify cell '%s' with T_LIMIT_MAX < 0 which is currently unsupported. Clamping to 0.\n", module, cell); max = 0; } for (const auto &s : src) { diff --git a/kernel/yosys.cc b/kernel/yosys.cc index b3688b77b..5643ed7b0 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -954,7 +954,7 @@ static char *readline_obj_generator(const char *text, int state) { for (auto mod : design->modules()) if (RTLIL::unescape_id(mod->name).compare(0, len, text) == 0) - obj_names.push_back(strdup(log_id(mod->name))); + obj_names.push_back(strdup(mod->name.unescape().c_str())); } else if (design->module(design->selected_active_module) != nullptr) { @@ -962,19 +962,19 @@ static char *readline_obj_generator(const char *text, int state) for (auto w : module->wires()) if (RTLIL::unescape_id(w->name).compare(0, len, text) == 0) - obj_names.push_back(strdup(log_id(w->name))); + obj_names.push_back(strdup(w->name.unescape().c_str())); for (auto &it : module->memories) if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0) - obj_names.push_back(strdup(log_id(it.first))); + obj_names.push_back(strdup(it.first.unescape().c_str())); for (auto cell : module->cells()) if (RTLIL::unescape_id(cell->name).compare(0, len, text) == 0) - obj_names.push_back(strdup(log_id(cell->name))); + obj_names.push_back(strdup(cell->name.unescape().c_str())); for (auto &it : module->processes) if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0) - obj_names.push_back(strdup(log_id(it.first))); + obj_names.push_back(strdup(it.first.unescape().c_str())); } std::sort(obj_names.begin(), obj_names.end()); @@ -1179,7 +1179,7 @@ struct ScriptCmdPass : public Pass { if (!mod->selected(w)) continue; if (!c.second.is_fully_const()) - log_error("RHS of selected wire %s.%s is not constant.\n", log_id(mod), log_id(w)); + log_error("RHS of selected wire %s.%s is not constant.\n", mod, w); auto v = c.second.as_const(); Pass::call_on_module(design, mod, v.decode_string()); } diff --git a/passes/cmds/abstract.cc b/passes/cmds/abstract.cc index 2ea71268b..2519daf5c 100644 --- a/passes/cmds/abstract.cc +++ b/passes/cmds/abstract.cc @@ -67,7 +67,7 @@ struct Slice { int wire_offset(RTLIL::Wire *wire, int index) const { int rtl_offset = indices == RtlilSlice ? index : wire->from_hdl_index(index); if (rtl_offset < 0 || rtl_offset >= wire->width) { - log_error("Slice %s is out of bounds for wire %s in module %s", to_string(), log_id(wire), log_id(wire->module)); + log_error("Slice %s is out of bounds for wire %s in module %s", to_string(), wire, wire->module); } return rtl_offset; } @@ -187,7 +187,7 @@ unsigned int abstract_state(Module* mod, EnableLogic enable, const std::vector& wire_score) for (auto bit : conn.second) if (bit.wire != nullptr && bit.wire->name[0] != '$') { if (suffix.empty()) - suffix = stringf("_%s_%s", log_id(cell->type), log_id(conn.first)); + suffix = stringf("_%s_%s", cell->type.unescape(), conn.first.unescape()); name_proposal proposed_name( bit.wire->name.str() + suffix, cell->output(conn.first) ? 0 : wire_score.at(bit.wire) @@ -66,7 +66,7 @@ int autoname_worker(Module *module, const dict& wire_score) for (auto bit : conn.second) if (bit.wire != nullptr && bit.wire->name[0] == '$' && !bit.wire->port_id) { if (suffix.empty()) - suffix = stringf("_%s", log_id(conn.first)); + suffix = stringf("_%s", conn.first.unescape()); name_proposal proposed_name( cell->name.str() + suffix, cell->output(conn.first) ? 0 : wire_score.at(bit.wire) @@ -90,7 +90,7 @@ int autoname_worker(Module *module, const dict& wire_score) if (best_name < it.second) continue; IdString n = module->uniquify(IdString(it.second.name)); - log_debug("Rename cell %s in %s to %s.\n", log_id(it.first), log_id(module), log_id(n)); + log_debug("Rename cell %s in %s to %s.\n", it.first, module, n.unescape()); module->rename(it.first, n); count++; } @@ -99,7 +99,7 @@ int autoname_worker(Module *module, const dict& wire_score) if (best_name < it.second) continue; IdString n = module->uniquify(IdString(it.second.name)); - log_debug("Rename wire %s in %s to %s.\n", log_id(it.first), log_id(module), log_id(n)); + log_debug("Rename wire %s in %s to %s.\n", it.first, module, n.unescape()); module->rename(it.first, n); count++; } @@ -151,7 +151,7 @@ struct AutonamePass : public Pass { count += n; } if (count > 0) - log("Renamed %d objects in module %s (%d iterations).\n", count, log_id(module), iter); + log("Renamed %d objects in module %s (%d iterations).\n", count, module, iter); } } } AutonamePass; diff --git a/passes/cmds/box_derive.cc b/passes/cmds/box_derive.cc index 2590baa93..2d5ee2440 100644 --- a/passes/cmds/box_derive.cc +++ b/passes/cmds/box_derive.cc @@ -79,7 +79,7 @@ struct BoxDerivePass : Pass { if (!base_name.empty()) { base_override = d->module(base_name); if (!base_override) - log_cmd_error("Base module %s not found.\n", log_id(base_name)); + log_cmd_error("Base module %s not found.\n", base_name.unescape()); } dict>, Module*> done; @@ -109,7 +109,7 @@ struct BoxDerivePass : Pass { IdString new_name = RTLIL::escape_id(derived->get_string_attribute(naming_attr)); if (!new_name.isPublic()) log_error("Derived module %s cannot be renamed to private name %s.\n", - log_id(derived), log_id(new_name)); + derived, new_name.unescape()); derived->attributes.erase(naming_attr); d->rename(derived, new_name); } diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index 0ced09dd9..6a630ca4b 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -212,7 +212,7 @@ struct BugpointPass : public Pass { if (index++ == seed) { - log_header(design, "Trying to remove module %s.\n", log_id(module)); + log_header(design, "Trying to remove module %s.\n", module); removed_module = module; break; } @@ -242,7 +242,7 @@ struct BugpointPass : public Pass { if (index++ == seed) { - log_header(design, "Trying to remove module port %s.\n", log_id(wire)); + log_header(design, "Trying to remove module port %s.\n", wire); wire->port_input = wire->port_output = false; mod->fixup_ports(); return design_copy; @@ -265,7 +265,7 @@ struct BugpointPass : public Pass { if (index++ == seed) { - log_header(design, "Trying to remove cell %s.%s.\n", log_id(mod), log_id(cell)); + log_header(design, "Trying to remove cell %s.%s.\n", mod, cell); removed_cell = cell; break; } @@ -296,7 +296,7 @@ struct BugpointPass : public Pass { if (index++ == seed) { - log_header(design, "Trying to remove cell port %s.%s.%s.\n", log_id(mod), log_id(cell), log_id(it.first)); + log_header(design, "Trying to remove cell port %s.%s.%s.\n", mod, cell, it.first.unescape()); RTLIL::SigSpec port_x(State::Sx, port.size()); cell->unsetPort(it.first); cell->setPort(it.first, port_x); @@ -305,7 +305,7 @@ struct BugpointPass : public Pass { if (!stage2 && (cell->input(it.first) || cell->output(it.first)) && index++ == seed) { - log_header(design, "Trying to expose cell port %s.%s.%s as module port.\n", log_id(mod), log_id(cell), log_id(it.first)); + log_header(design, "Trying to expose cell port %s.%s.%s as module port.\n", mod, cell, it.first.unescape()); RTLIL::Wire *wire = mod->addWire(NEW_ID, port.size()); wire->set_bool_attribute(ID($bugpoint)); wire->port_input = cell->input(it.first); @@ -334,7 +334,7 @@ struct BugpointPass : public Pass { if (index++ == seed) { - log_header(design, "Trying to remove process %s.%s.\n", log_id(mod), log_id(process.first)); + log_header(design, "Trying to remove process %s.%s.\n", mod, process.first.unescape()); removed_process = process.second; break; } @@ -363,7 +363,7 @@ struct BugpointPass : public Pass { { if (index++ == seed) { - log_header(design, "Trying to remove assign %s %s in %s.%s.\n", log_signal(it->first), log_signal(it->second), log_id(mod), log_id(pr.first)); + log_header(design, "Trying to remove assign %s %s in %s.%s.\n", log_signal(it->first), log_signal(it->second), mod, pr.first.unescape()); cs->actions.erase(it); return design_copy; } @@ -389,7 +389,7 @@ struct BugpointPass : public Pass { { if (index++ == seed) { - log_header(design, "Trying to remove sync %s update %s %s in %s.%s.\n", log_signal(sy->signal), log_signal(it->first), log_signal(it->second), log_id(mod), log_id(pr.first)); + log_header(design, "Trying to remove sync %s update %s %s in %s.%s.\n", log_signal(sy->signal), log_signal(it->first), log_signal(it->second), mod, pr.first.unescape()); sy->actions.erase(it); return design_copy; } @@ -399,7 +399,7 @@ struct BugpointPass : public Pass { { if (index++ == seed) { - log_header(design, "Trying to remove sync %s memwr %s %s %s %s in %s.%s.\n", log_signal(sy->signal), log_id(it->memid), log_signal(it->address), log_signal(it->data), log_signal(it->enable), log_id(mod), log_id(pr.first)); + log_header(design, "Trying to remove sync %s memwr %s %s %s %s in %s.%s.\n", log_signal(sy->signal), it->memid.unescape(), log_signal(it->address), log_signal(it->data), log_signal(it->enable), mod, pr.first.unescape()); sy->mem_write_actions.erase(it); // Remove the bit for removed action from other actions' priority masks. for (auto it2 = sy->mem_write_actions.begin(); it2 != sy->mem_write_actions.end(); ++it2) { @@ -437,7 +437,7 @@ struct BugpointPass : public Pass { if (index++ == seed) { - log_header(design, "Trying to remove wire %s.%s.\n", log_id(mod), log_id(wire)); + log_header(design, "Trying to remove wire %s.%s.\n", mod, wire); removed_wire = wire; break; } diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc index 1019c2955..6e0d65297 100644 --- a/passes/cmds/check.cc +++ b/passes/cmds/check.cc @@ -117,7 +117,7 @@ struct CheckPass : public Pass { for (auto module : design->selected_whole_modules_warn()) { - log("Checking module %s...\n", log_id(module)); + log("Checking module %s...\n", module); SigMap sigmap(module); dict> wire_drivers; @@ -133,7 +133,7 @@ struct CheckPass : public Pass { for (auto bit : sigmap(action.first)) wire_drivers[bit].push_back( stringf("action %s <= %s (case rule) in process %s", - log_signal(action.first), log_signal(action.second), log_id(proc_it.first))); + log_signal(action.first), log_signal(action.second), proc_it.first.unescape())); for (auto bit : sigmap(action.second)) if (bit.wire) used_wires.insert(bit); @@ -154,7 +154,7 @@ struct CheckPass : public Pass { for (auto bit : sigmap(action.first)) wire_drivers[bit].push_back( stringf("action %s <= %s (sync rule) in process %s", - log_signal(action.first), log_signal(action.second), log_id(proc_it.first))); + log_signal(action.first), log_signal(action.second), proc_it.first.unescape())); for (auto bit : sigmap(action.second)) if (bit.wire) used_wires.insert(bit); } @@ -259,7 +259,7 @@ struct CheckPass : public Pass { { if (mapped && cell->type.begins_with("$") && design->module(cell->type) == nullptr) { if (allow_tbuf && cell->type == ID($_TBUF_)) goto cell_allowed; - log_warning("Cell %s.%s is an unmapped internal cell of type %s.\n", log_id(module), log_id(cell), log_id(cell->type)); + log_warning("Cell %s.%s is an unmapped internal cell of type %s.\n", module, cell, cell->type.unescape()); counter++; cell_allowed:; } @@ -275,10 +275,10 @@ struct CheckPass : public Pass { if (input && bit.wire) used_wires.insert(bit); if (output && !input && bit.wire) - wire_drivers_count[bit]++; + wire_drivers_count[bit]++; if (output && (bit.wire || !input)) - wire_drivers[bit].push_back(stringf("port %s[%d] of cell %s (%s)", log_id(conn.first), i, - log_id(cell), log_id(cell->type))); + wire_drivers[bit].push_back(stringf("port %s[%d] of cell %s (%s)", conn.first.unescape(), i, + cell, cell->type.unescape())); if (output) driver_cells[bit] = cell; } @@ -298,7 +298,7 @@ struct CheckPass : public Pass { SigSpec sig = sigmap(wire); for (int i = 0; i < GetSize(sig); i++) if (sig[i].wire || !wire->port_output) - wire_drivers[sig[i]].push_back(stringf("module input %s[%d]", log_id(wire), i)); + wire_drivers[sig[i]].push_back(stringf("module input %s[%d]", wire, i)); } if (wire->port_output) for (auto bit : sigmap(wire)) @@ -312,7 +312,7 @@ struct CheckPass : public Pass { if (initval[i] == State::S0 || initval[i] == State::S1) init_bits.insert(sigmap(SigBit(wire, i))); if (noinit) { - log_warning("Wire %s.%s has an unprocessed 'init' attribute.\n", log_id(module), log_id(wire)); + log_warning("Wire %s.%s has an unprocessed 'init' attribute.\n", module, wire); counter++; } } @@ -329,7 +329,7 @@ struct CheckPass : public Pass { for (auto it : wire_drivers) if (wire_drivers_count[it.first] > 1) { - string message = stringf("multiple conflicting drivers for %s.%s:\n", log_id(module), log_signal(it.first)); + string message = stringf("multiple conflicting drivers for %s.%s:\n", module, log_signal(it.first)); for (auto str : it.second) message += stringf(" %s\n", str); log_warning("%s", message); @@ -338,13 +338,13 @@ struct CheckPass : public Pass { for (auto bit : used_wires) if (!wire_drivers.count(bit)) { - log_warning("Wire %s.%s is used but has no driver.\n", log_id(module), log_signal(bit)); + log_warning("Wire %s.%s is used but has no driver.\n", module, log_signal(bit)); counter++; } topo.sort(); for (auto &loop : topo.loops) { - string message = stringf("found logic loop in module %s:\n", log_id(module)); + string message = stringf("found logic loop in module %s:\n", module); // `loop` only contains wire bits, or an occasional special helper node for cells for // which we have done the edges fallback. The cell and its ports that led to an edge are @@ -378,8 +378,8 @@ struct CheckPass : public Pass { SigBit edge_to = sigmap(cell->getPort(to_port))[to_bit]; if (edge_from == from && edge_to == to && nhits++ < HITS_LIMIT) - message += stringf(" %s[%d] --> %s[%d]\n", log_id(from_port), from_bit, - log_id(to_port), to_bit); + message += stringf(" %s[%d] --> %s[%d]\n", from_port.unescape(), from_bit, + to_port.unescape(), to_bit); if (nhits == HITS_LIMIT) message += " ...\n"; } @@ -397,7 +397,7 @@ struct CheckPass : public Pass { driver_src = stringf(" source: %s", src_attr); } - message += stringf(" cell %s (%s)%s\n", log_id(driver), log_id(driver->type), driver_src); + message += stringf(" cell %s (%s)%s\n", driver, driver->type.unescape(), driver_src); if (!coarsened_cells.count(driver)) { MatchingEdgePrinter printer(message, sigmap, prev, bit); @@ -437,7 +437,7 @@ struct CheckPass : public Pass { init_sig.sort_and_unify(); for (auto chunk : init_sig.chunks()) { - log_warning("Wire %s.%s has 'init' attribute and is not driven by an FF cell.\n", log_id(module), log_signal(chunk)); + log_warning("Wire %s.%s has 'init' attribute and is not driven by an FF cell.\n", module, log_signal(chunk)); counter++; } } diff --git a/passes/cmds/chformal.cc b/passes/cmds/chformal.cc index ccda023c0..fca943d86 100644 --- a/passes/cmds/chformal.cc +++ b/passes/cmds/chformal.cc @@ -330,7 +330,7 @@ struct ChformalPass : public Pass { for (auto cell : constr_cells) { if (is_triggered_check_cell(cell)) - log_error("Cannot delay edge triggered $check cell %s, run async2sync or clk2fflogic first.\n", log_id(cell)); + log_error("Cannot delay edge triggered $check cell %s, run async2sync or clk2fflogic first.\n", cell); for (int i = 0; i < mode_arg; i++) { @@ -411,7 +411,7 @@ struct ChformalPass : public Pass { continue; if (is_triggered_check_cell(cell)) - log_error("Cannot lower edge triggered $check cell %s, run async2sync or clk2fflogic first.\n", log_id(cell)); + log_error("Cannot lower edge triggered $check cell %s, run async2sync or clk2fflogic first.\n", cell); Cell *plain_cell = module->addCell(NEW_ID, formal_flavor(cell)); diff --git a/passes/cmds/connect.cc b/passes/cmds/connect.cc index c6d3320ea..b8a61d532 100644 --- a/passes/cmds/connect.cc +++ b/passes/cmds/connect.cc @@ -122,7 +122,7 @@ struct ConnectPass : public Pass { RTLIL::Module *module = nullptr; for (auto mod : design->selected_modules()) { if (module != nullptr) - log_cmd_error("Multiple modules selected: %s, %s\n", log_id(module->name), log_id(mod->name)); + log_cmd_error("Multiple modules selected: %s, %s\n", module->name.unescape(), mod->name.unescape()); module = mod; } if (module == nullptr) diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc index 5677c666d..dcc6f0004 100644 --- a/passes/cmds/connwrappers.cc +++ b/passes/cmds/connwrappers.cc @@ -134,8 +134,8 @@ struct ConnwrappersWorker } if (old_sig.size()) - log("Connected extended bits of %s.%s:%s: %s -> %s\n", log_id(module->name), log_id(cell->name), - log_id(conn.first), log_signal(old_sig), log_signal(conn.second)); + log("Connected extended bits of %s.%s:%s: %s -> %s\n", module->name.unescape(), cell->name.unescape(), + conn.first.unescape(), log_signal(old_sig), log_signal(conn.second)); } } } diff --git a/passes/cmds/design.cc b/passes/cmds/design.cc index ddbd98bfd..68b778790 100644 --- a/passes/cmds/design.cc +++ b/passes/cmds/design.cc @@ -266,7 +266,7 @@ struct DesignPass : public Pass { for (auto mod : copy_src_modules) { - log("Importing %s as %s.\n", log_id(mod), log_id(prefix)); + log("Importing %s as %s.\n", mod, prefix); RTLIL::Module *t = mod->clone(); t->name = prefix; @@ -295,7 +295,7 @@ struct DesignPass : public Pass { { std::string trg_name = prefix + "." + (cell->type.c_str() + (*cell->type.c_str() == '\\')); - log("Importing %s as %s.\n", log_id(fmod), log_id(trg_name)); + log("Importing %s as %s.\n", fmod, trg_name); if (copy_to_design->module(trg_name) != nullptr) copy_to_design->remove(copy_to_design->module(trg_name)); diff --git a/passes/cmds/design_equal.cc b/passes/cmds/design_equal.cc index d5f0d617a..1912a823e 100644 --- a/passes/cmds/design_equal.cc +++ b/passes/cmds/design_equal.cc @@ -38,9 +38,9 @@ public: [[noreturn]] void formatted_error(std::string err) { - log("Module A: %s\n", log_id(mod_a->name)); + log("Module A: %s\n", mod_a->name.unescape()); log_module(mod_a, " "); - log("Module B: %s\n", log_id(mod_b->name)); + log("Module B: %s\n", mod_b->name.unescape()); log_module(mod_b, " "); log_cmd_error("Designs are different: %s\n", err); } @@ -68,20 +68,20 @@ public: { for (const auto &it : a->attributes) { if (b->attributes.count(it.first) == 0) - return "missing attribute " + std::string(log_id(it.first)) + " in second design"; + return "missing attribute " + std::string(it.first.unescape()) + " in second design"; if (it.second != b->attributes.at(it.first)) - return "attribute " + std::string(log_id(it.first)) + " mismatch: " + log_const(it.second) + " != " + log_const(b->attributes.at(it.first)); + return "attribute " + std::string(it.first.unescape()) + " mismatch: " + log_const(it.second) + " != " + log_const(b->attributes.at(it.first)); } for (const auto &it : b->attributes) if (a->attributes.count(it.first) == 0) - return "missing attribute " + std::string(log_id(it.first)) + " in first design"; + return "missing attribute " + std::string(it.first.unescape()) + " in first design"; return ""; } std::string compare_wires(const RTLIL::Wire *a, const RTLIL::Wire *b) { if (a->name != b->name) - return "name mismatch: " + std::string(log_id(a->name)) + " != " + log_id(b->name); + return "name mismatch: " + std::string(a->name.unescape()) + " != " + b->name.unescape(); if (a->width != b->width) return "width mismatch: " + std::to_string(a->width) + " != " + std::to_string(b->width); if (a->start_offset != b->start_offset) @@ -105,19 +105,19 @@ public: { for (const auto &it : mod_a->wires_) { if (mod_b->wires_.count(it.first) == 0) - error("Module %s missing wire %s in second design.\n", log_id(mod_a->name), log_id(it.first)); + error("Module %s missing wire %s in second design.\n", mod_a->name.unescape(), it.first.unescape()); if (std::string mismatch = compare_wires(it.second, mod_b->wires_.at(it.first)); !mismatch.empty()) - error("Module %s wire %s %s.\n", log_id(mod_a->name), log_id(it.first), mismatch); + error("Module %s wire %s %s.\n", mod_a->name.unescape(), it.first.unescape(), mismatch); } for (const auto &it : mod_b->wires_) if (mod_a->wires_.count(it.first) == 0) - error("Module %s missing wire %s in first design.\n", log_id(mod_b->name), log_id(it.first)); + error("Module %s missing wire %s in first design.\n", mod_b->name.unescape(), it.first.unescape()); } std::string compare_memories(const RTLIL::Memory *a, const RTLIL::Memory *b) { if (a->name != b->name) - return "name mismatch: " + std::string(log_id(a->name)) + " != " + log_id(b->name); + return "name mismatch: " + std::string(a->name.unescape()) + " != " + b->name.unescape(); if (a->width != b->width) return "width mismatch: " + std::to_string(a->width) + " != " + std::to_string(b->width); if (a->start_offset != b->start_offset) @@ -132,31 +132,31 @@ public: std::string compare_cells(const RTLIL::Cell *a, const RTLIL::Cell *b) { if (a->name != b->name) - return "name mismatch: " + std::string(log_id(a->name)) + " != " + log_id(b->name); + return "name mismatch: " + std::string(a->name.unescape()) + " != " + b->name.unescape(); if (a->type != b->type) - return "type mismatch: " + std::string(log_id(a->type)) + " != " + log_id(b->type); + return "type mismatch: " + std::string(a->type.unescape()) + " != " + b->type.unescape(); if (std::string mismatch = compare_attributes(a, b); !mismatch.empty()) return mismatch; for (const auto &it : a->parameters) { if (b->parameters.count(it.first) == 0) - return "parameter mismatch: missing parameter " + std::string(log_id(it.first)) + " in second design"; + return "parameter mismatch: missing parameter " + std::string(it.first.unescape()) + " in second design"; if (it.second != b->parameters.at(it.first)) - return "parameter mismatch: " + std::string(log_id(it.first)) + " mismatch: " + log_const(it.second) + " != " + log_const(b->parameters.at(it.first)); + return "parameter mismatch: " + std::string(it.first.unescape()) + " mismatch: " + log_const(it.second) + " != " + log_const(b->parameters.at(it.first)); } for (const auto &it : b->parameters) if (a->parameters.count(it.first) == 0) - return "parameter mismatch: missing parameter " + std::string(log_id(it.first)) + " in first design"; + return "parameter mismatch: missing parameter " + std::string(it.first.unescape()) + " in first design"; for (const auto &it : a->connections()) { if (b->connections().count(it.first) == 0) - return "connection mismatch: missing connection " + std::string(log_id(it.first)) + " in second design"; + return "connection mismatch: missing connection " + std::string(it.first.unescape()) + " in second design"; if (!compare_sigspec(it.second, b->connections().at(it.first))) - return "connection " + std::string(log_id(it.first)) + " mismatch: " + log_signal(it.second) + " != " + log_signal(b->connections().at(it.first)); + return "connection " + std::string(it.first.unescape()) + " mismatch: " + log_signal(it.second) + " != " + log_signal(b->connections().at(it.first)); } for (const auto &it : b->connections()) if (a->connections().count(it.first) == 0) - return "connection mismatch: missing connection " + std::string(log_id(it.first)) + " in first design"; + return "connection mismatch: missing connection " + std::string(it.first.unescape()) + " in first design"; return ""; } @@ -165,26 +165,26 @@ public: { for (const auto &it : mod_a->cells_) { if (mod_b->cells_.count(it.first) == 0) - error("Module %s missing cell %s in second design.\n", log_id(mod_a->name), log_id(it.first)); + error("Module %s missing cell %s in second design.\n", mod_a->name.unescape(), it.first.unescape()); if (std::string mismatch = compare_cells(it.second, mod_b->cells_.at(it.first)); !mismatch.empty()) - error("Module %s cell %s %s.\n", log_id(mod_a->name), log_id(it.first), mismatch); + error("Module %s cell %s %s.\n", mod_a->name.unescape(), it.first.unescape(), mismatch); } for (const auto &it : mod_b->cells_) if (mod_a->cells_.count(it.first) == 0) - error("Module %s missing cell %s in first design.\n", log_id(mod_b->name), log_id(it.first)); + error("Module %s missing cell %s in first design.\n", mod_b->name.unescape(), it.first.unescape()); } void check_memories() { for (const auto &it : mod_a->memories) { if (mod_b->memories.count(it.first) == 0) - error("Module %s missing memory %s in second design.\n", log_id(mod_a->name), log_id(it.first)); + error("Module %s missing memory %s in second design.\n", mod_a->name.unescape(), it.first.unescape()); if (std::string mismatch = compare_memories(it.second, mod_b->memories.at(it.first)); !mismatch.empty()) - error("Module %s memory %s %s.\n", log_id(mod_a->name), log_id(it.first), mismatch); + error("Module %s memory %s %s.\n", mod_a->name.unescape(), it.first.unescape(), mismatch); } for (const auto &it : mod_b->memories) if (mod_a->memories.count(it.first) == 0) - error("Module %s missing memory %s in first design.\n", log_id(mod_b->name), log_id(it.first)); + error("Module %s missing memory %s in first design.\n", mod_b->name.unescape(), it.first.unescape()); } std::string compare_case_rules(const RTLIL::CaseRule *a, const RTLIL::CaseRule *b) @@ -251,7 +251,7 @@ public: const auto &ma = a->mem_write_actions[i]; const auto &mb = b->mem_write_actions[i]; if (ma.memid != mb.memid) - return "mem_write_actions " + std::to_string(i) + " memid mismatch: " + log_id(ma.memid) + " != " + log_id(mb.memid); + return "mem_write_actions " + std::to_string(i) + " memid mismatch: " + ma.memid.unescape() + " != " + mb.memid.unescape(); if (!compare_sigspec(ma.address, mb.address)) return "mem_write_actions " + std::to_string(i) + " address mismatch: " + log_signal(ma.address) + " != " + log_signal(mb.address); if (!compare_sigspec(ma.data, mb.data)) @@ -268,7 +268,7 @@ public: std::string compare_processes(const RTLIL::Process *a, const RTLIL::Process *b) { - if (a->name != b->name) return "name mismatch: " + std::string(log_id(a->name)) + " != " + log_id(b->name); + if (a->name != b->name) return "name mismatch: " + std::string(a->name.unescape()) + " != " + b->name.unescape(); if (std::string mismatch = compare_attributes(a, b); !mismatch.empty()) return mismatch; if (std::string mismatch = compare_case_rules(&a->root_case, &b->root_case); !mismatch.empty()) @@ -285,13 +285,13 @@ public: { for (auto &it : mod_a->processes) { if (mod_b->processes.count(it.first) == 0) - error("Module %s missing process %s in second design.\n", log_id(mod_a->name), log_id(it.first)); + error("Module %s missing process %s in second design.\n", mod_a->name.unescape(), it.first.unescape()); if (std::string mismatch = compare_processes(it.second, mod_b->processes.at(it.first)); !mismatch.empty()) - error("Module %s process %s %s.\n", log_id(mod_a->name), log_id(it.first), mismatch.c_str()); + error("Module %s process %s %s.\n", mod_a->name.unescape(), it.first.unescape(), mismatch.c_str()); } for (auto &it : mod_b->processes) if (mod_a->processes.count(it.first) == 0) - error("Module %s missing process %s in first design.\n", log_id(mod_b->name), log_id(it.first)); + error("Module %s missing process %s in first design.\n", mod_b->name.unescape(), it.first.unescape()); } void check_connections() @@ -299,13 +299,13 @@ public: const auto &conns_a = mod_a->connections(); const auto &conns_b = mod_b->connections(); if (conns_a.size() != conns_b.size()) { - error("Module %s connection count differs: %zu != %zu\n", log_id(mod_a->name), conns_a.size(), conns_b.size()); + error("Module %s connection count differs: %zu != %zu\n", mod_a->name.unescape(), conns_a.size(), conns_b.size()); } else { for (size_t i = 0; i < conns_a.size(); i++) { if (!compare_sigspec(conns_a[i].first, conns_b[i].first)) - error("Module %s connection %zu LHS %s != %s.\n", log_id(mod_a->name), i, log_signal(conns_a[i].first), log_signal(conns_b[i].first)); + error("Module %s connection %zu LHS %s != %s.\n", mod_a->name.unescape(), i, log_signal(conns_a[i].first), log_signal(conns_b[i].first)); if (!compare_sigspec(conns_a[i].second, conns_b[i].second)) - error("Module %s connection %zu RHS %s != %s.\n", log_id(mod_a->name), i, log_signal(conns_a[i].second), log_signal(conns_b[i].second)); + error("Module %s connection %zu RHS %s != %s.\n", mod_a->name.unescape(), i, log_signal(conns_a[i].second), log_signal(conns_b[i].second)); } } } @@ -313,9 +313,9 @@ public: void check() { if (mod_a->name != mod_b->name) - error("Modules have different names: %s != %s\n", log_id(mod_a->name), log_id(mod_b->name)); + error("Modules have different names: %s != %s\n", mod_a->name.unescape(), mod_b->name.unescape()); if (std::string mismatch = compare_attributes(mod_a, mod_b); !mismatch.empty()) - error("Module %s %s.\n", log_id(mod_a->name), mismatch); + error("Module %s %s.\n", mod_a->name.unescape(), mismatch); check_wires(); check_cells(); check_memories(); @@ -349,7 +349,7 @@ struct DesignEqualPass : public Pass { for (auto &it : design->modules_) { RTLIL::Module *mod = it.second; if (!other->has(mod->name)) - log_error("Second design missing module %s.\n", log_id(mod->name)); + log_error("Second design missing module %s.\n", mod->name.unescape()); ModuleComparator cmp(mod, other->module(mod->name)); cmp.check(); @@ -357,7 +357,7 @@ struct DesignEqualPass : public Pass { for (auto &it : other->modules_) { RTLIL::Module *mod = it.second; if (!design->has(mod->name)) - log_error("First design missing module %s.\n", log_id(mod->name)); + log_error("First design missing module %s.\n", mod->name.unescape()); } log("Designs are identical.\n"); diff --git a/passes/cmds/dft_tag.cc b/passes/cmds/dft_tag.cc index 0a306d113..216f66b2c 100644 --- a/passes/cmds/dft_tag.cc +++ b/passes/cmds/dft_tag.cc @@ -98,7 +98,7 @@ struct DftTagWorker { } for (auto cell : overwrite_cells) { - log_debug("Applying $overwrite_tag %s for signal %s\n", log_id(cell->name), log_signal(cell->getPort(ID::A))); + log_debug("Applying $overwrite_tag %s for signal %s\n", cell->name.unescape(), log_signal(cell->getPort(ID::A))); SigSpec orig_signal = cell->getPort(ID::A); SigSpec interposed_signal = divert_users(orig_signal); auto *set_tag_cell = module->addSetTag(NEW_ID, cell->getParam(ID::TAG).decode_string(), orig_signal, cell->getPort(ID::SET), cell->getPort(ID::CLR), interposed_signal); @@ -470,9 +470,9 @@ struct DftTagWorker { if (!warned_cells.insert(cell).second) return; if (cell->type.isPublic()) - log_warning("Unhandled cell %s (%s) during tag propagation\n", log_id(cell), log_id(cell->type)); + log_warning("Unhandled cell %s (%s) during tag propagation\n", cell, cell->type.unescape()); else - log_debug("Unhandled cell %s (%s) during tag propagation\n", log_id(cell), log_id(cell->type)); + log_debug("Unhandled cell %s (%s) during tag propagation\n", cell, cell->type.unescape()); } void process_cell(IdString tag, Cell *cell) @@ -691,7 +691,7 @@ struct DftTagWorker { // TODO handle some more variants if ((ff.has_clk || ff.has_gclk) && !ff.has_ce && !ff.has_aload && !ff.has_srst && !ff.has_arst && !ff.has_sr) { if (ff.has_clk && !tags(ff.sig_clk).empty()) - log_warning("Tags on CLK input ignored for %s (%s)\n", log_id(cell), log_id(cell->type)); + log_warning("Tags on CLK input ignored for %s (%s)\n", cell, cell->type.unescape()); int width = ff.width; @@ -709,7 +709,7 @@ struct DftTagWorker { emit_tag_signal(tag, sig_q, ff.sig_q); return; } else { - log_warning("Unhandled FF-cell %s (%s), consider running clk2fflogic, async2sync and/or dffunmap\n", log_id(cell), log_id(cell->type)); + log_warning("Unhandled FF-cell %s (%s), consider running clk2fflogic, async2sync and/or dffunmap\n", cell, cell->type.unescape()); // For unhandled FFs, the default propagation would cause combinational loops emit_tag_signal(tag, ff.sig_q, Const(0, ff.width)); @@ -739,7 +739,7 @@ struct DftTagWorker { // which is an over-approximation (unless the cell is a module that // generates tags itself in which case it could be arbitrary). if (warned_cells.insert(cell).second) - log_warning("Unhandled cell %s (%s) while emitting tag signals\n", log_id(cell), log_id(cell->type)); + log_warning("Unhandled cell %s (%s) while emitting tag signals\n", cell, cell->type.unescape()); } void emit_tags() diff --git a/passes/cmds/edgetypes.cc b/passes/cmds/edgetypes.cc index 9324cf630..2f100d724 100644 --- a/passes/cmds/edgetypes.cc +++ b/passes/cmds/edgetypes.cc @@ -92,12 +92,12 @@ struct EdgetypePass : public Pass { auto sink_bit_index = std::get<2>(sink); string source_str = multibit_ports.count(std::pair(source_cell_type, source_port_name)) ? - stringf("%s.%s[%d]", log_id(source_cell_type), log_id(source_port_name), source_bit_index) : - stringf("%s.%s", log_id(source_cell_type), log_id(source_port_name)); + stringf("%s.%s[%d]", source_cell_type.unescape(), source_port_name.unescape(), source_bit_index) : + stringf("%s.%s", source_cell_type.unescape(), source_port_name.unescape()); string sink_str = multibit_ports.count(std::pair(sink_cell_type, sink_port_name)) ? - stringf("%s.%s[%d]", log_id(sink_cell_type), log_id(sink_port_name), sink_bit_index) : - stringf("%s.%s", log_id(sink_cell_type), log_id(sink_port_name)); + stringf("%s.%s[%d]", sink_cell_type.unescape(), sink_port_name.unescape(), sink_bit_index) : + stringf("%s.%s", sink_cell_type.unescape(), sink_port_name.unescape()); edge_cache.insert(source_str + " " + sink_str); } diff --git a/passes/cmds/example_dt.cc b/passes/cmds/example_dt.cc index b10f50502..b18277010 100644 --- a/passes/cmds/example_dt.cc +++ b/passes/cmds/example_dt.cc @@ -226,13 +226,13 @@ struct ExampleDtPass : public Pass { auto ref = compute_graph[i]; log("n%d ", i); - log("%s", log_id(ref.function().name)); + log("%s", ref.function().name.unescape()); for (auto const ¶m : ref.function().parameters) { if (param.second.empty()) - log("[%s]", log_id(param.first)); + log("[%s]", param.first.unescape()); else - log("[%s=%s]", log_id(param.first), log_const(param.second)); + log("[%s=%s]", param.first.unescape(), log_const(param.second)); } log("("); @@ -244,13 +244,13 @@ struct ExampleDtPass : public Pass } log(")\n"); if (ref.has_sparse_attr()) - log("// wire %s\n", log_id(ref.sparse_attr())); + log("// wire %s\n", ref.sparse_attr().unescape()); log("// was #%d %s\n", ref.attr(), log_signal(queue[ref.attr()])); } for (auto const &key : compute_graph.keys()) { - log("return %d as %s \n", key.second, log_id(key.first)); + log("return %d as %s \n", key.second, key.first.unescape()); } } log("Plugin test passed!\n"); diff --git a/passes/cmds/future.cc b/passes/cmds/future.cc index 81cc86bff..15f4b8bd1 100644 --- a/passes/cmds/future.cc +++ b/passes/cmds/future.cc @@ -86,13 +86,13 @@ struct FutureWorker { log_error("Found multiple drivers for future_ff target signal %s\n", log_signal(bit)); auto driver = *found_driver->second.begin(); if (!driver.cell->is_builtin_ff() && driver.cell->type != ID($anyinit)) - log_error("Driver for future_ff target signal %s has non-FF cell type %s\n", log_signal(bit), log_id(driver.cell->type)); + log_error("Driver for future_ff target signal %s has non-FF cell type %s\n", log_signal(bit), driver.cell->type.unescape()); FfData ff(&initvals, driver.cell); if (!ff.has_clk && !ff.has_gclk) log_error("Driver for future_ff target signal %s has cell type %s, which is not clocked\n", log_signal(bit), - log_id(driver.cell->type)); + driver.cell->type.unescape()); ff.unmap_ce_srst(); diff --git a/passes/cmds/linecoverage.cc b/passes/cmds/linecoverage.cc index 26adcce76..2f77f6f21 100644 --- a/passes/cmds/linecoverage.cc +++ b/passes/cmds/linecoverage.cc @@ -93,9 +93,9 @@ struct CoveragePass : public Pass { for (auto module : design->modules()) { - log_debug("Module %s:\n", log_id(module)); + log_debug("Module %s:\n", module); for (auto wire: module->wires()) { - log_debug("%s\t%s\t%s\n", module->selected(wire) ? "*" : " ", wire->get_src_attribute(), log_id(wire->name)); + log_debug("%s\t%s\t%s\n", module->selected(wire) ? "*" : " ", wire->get_src_attribute(), wire->name.unescape()); for (auto src: wire->get_strpool_attribute(ID::src)) { auto filename = extract_src_filename(src); if (filename.empty()) continue; @@ -109,7 +109,7 @@ struct CoveragePass : public Pass { } } for (auto cell: module->cells()) { - log_debug("%s\t%s\t%s\n", module->selected(cell) ? "*" : " ", cell->get_src_attribute(), log_id(cell->name)); + log_debug("%s\t%s\t%s\n", module->selected(cell) ? "*" : " ", cell->get_src_attribute(), cell->name.unescape()); for (auto src: cell->get_strpool_attribute(ID::src)) { auto filename = extract_src_filename(src); if (filename.empty()) continue; diff --git a/passes/cmds/ltp.cc b/passes/cmds/ltp.cc index b3134b110..303abea6c 100644 --- a/passes/cmds/ltp.cc +++ b/passes/cmds/ltp.cc @@ -90,7 +90,7 @@ struct LtpWorker return; if (busy.count(bit) > 0) { - log_warning("Detected loop at %s in %s\n", log_signal(bit), log_id(module)); + log_warning("Detected loop at %s in %s\n", log_signal(bit), module); return; } @@ -117,7 +117,7 @@ struct LtpWorker auto &bitinfo = bits.at(bit); if (get<2>(bitinfo)) { printpath(get<1>(bitinfo)); - log("%5d: %s (via %s)\n", get<0>(bitinfo), log_signal(bit), log_id(get<2>(bitinfo))); + log("%5d: %s (via %s)\n", get<0>(bitinfo), log_signal(bit), get<2>(bitinfo)); } else { log("%5d: %s\n", get<0>(bitinfo), log_signal(bit)); } @@ -130,13 +130,13 @@ struct LtpWorker runner(it.first, 0, State::Sx, nullptr); log("\n"); - log("Longest topological path in %s (length=%d):\n", log_id(module), maxlvl); + log("Longest topological path in %s (length=%d):\n", module, maxlvl); if (maxlvl >= 0) printpath(maxbit); if (bit2ff.count(maxbit)) - log("%5s: %s (via %s)\n", "ff", log_signal(get<0>(bit2ff.at(maxbit))), log_id(get<1>(bit2ff.at(maxbit)))); + log("%5s: %s (via %s)\n", "ff", log_signal(get<0>(bit2ff.at(maxbit))), get<1>(bit2ff.at(maxbit))); } }; diff --git a/passes/cmds/portarcs.cc b/passes/cmds/portarcs.cc index 4344d6cb2..581a8bebf 100644 --- a/passes/cmds/portarcs.cc +++ b/passes/cmds/portarcs.cc @@ -107,7 +107,7 @@ struct PortarcsPass : Pass { log_assert(w->port_input || w->port_output); if (w->port_input && w->port_output) { log_warning("Module '%s' with ambiguous direction on port %s ignored.\n", - log_id(m), log_id(w)); + m, w); ambiguous_ports = true; break; } @@ -128,7 +128,7 @@ struct PortarcsPass : Pass { if (!cell->type.in(ID($buf), ID($input_port), ID($connect), ID($tribuf))) { auto tdata = tinfo.find(cell->type); if (tdata == tinfo.end()) - log_cmd_error("Missing timing data for module '%s'.\n", log_id(cell->type)); + log_cmd_error("Missing timing data for module '%s'.\n", cell->type.unescape()); for (auto [edge, delay] : tdata->second.comb) { auto from = edge.first.get_connection(cell); auto to = edge.second.get_connection(cell); @@ -141,7 +141,7 @@ struct PortarcsPass : Pass { } if (!sort.sort()) - log_error("Failed to sort instances in module %s.\n", log_id(m)); + log_error("Failed to sort instances in module %s.\n", m); ordering = sort.sorted; } diff --git a/passes/cmds/portlist.cc b/passes/cmds/portlist.cc index b109ce22a..0804d3a68 100644 --- a/passes/cmds/portlist.cc +++ b/passes/cmds/portlist.cc @@ -71,9 +71,9 @@ struct PortlistPass : public Pass { ports.push_back(stringf("%s [%d:%d] %s", w->port_input ? w->port_output ? "inout" : "input" : "output", w->upto ? w->start_offset : w->start_offset + w->width - 1, w->upto ? w->start_offset + w->width - 1 : w->start_offset, - log_id(w))); + w)); } - log("module %s%s\n", log_id(module), m_mode ? " (" : ""); + log("module %s%s\n", module, m_mode ? " (" : ""); for (int i = 0; i < GetSize(ports); i++) log("%s%s\n", ports[i], m_mode && i+1 < GetSize(ports) ? "," : ""); if (m_mode) diff --git a/passes/cmds/printattrs.cc b/passes/cmds/printattrs.cc index 6a1fab072..6de2ffee3 100644 --- a/passes/cmds/printattrs.cc +++ b/passes/cmds/printattrs.cc @@ -47,9 +47,9 @@ struct PrintAttrsPass : public Pass { static void log_const(RTLIL::IdString s, const RTLIL::Const &x, const unsigned int indent) { if (x.flags & RTLIL::CONST_FLAG_STRING) - log("%s(* %s=\"%s\" *)\n", get_indent_str(indent), log_id(s), x.decode_string()); + log("%s(* %s=\"%s\" *)\n", get_indent_str(indent), s.unescape(), x.decode_string()); else if (x.flags == RTLIL::CONST_FLAG_NONE || x.flags == RTLIL::CONST_FLAG_SIGNED) - log("%s(* %s=%s *)\n", get_indent_str(indent), log_id(s), x.as_string()); + log("%s(* %s=%s *)\n", get_indent_str(indent), s.unescape(), x.as_string()); else log_assert(x.flags & RTLIL::CONST_FLAG_STRING || x.flags == RTLIL::CONST_FLAG_NONE); //intended to fail } @@ -63,14 +63,14 @@ struct PrintAttrsPass : public Pass { for (auto mod : design->selected_modules()) { if (design->selected_whole_module(mod)) { - log("%s%s\n", get_indent_str(indent), log_id(mod->name)); + log("%s%s\n", get_indent_str(indent), mod->name.unescape()); indent += 2; for (auto &it : mod->attributes) log_const(it.first, it.second, indent); } for (auto cell : mod->selected_cells()) { - log("%s%s\n", get_indent_str(indent), log_id(cell->name)); + log("%s%s\n", get_indent_str(indent), cell->name.unescape()); indent += 2; for (auto &it : cell->attributes) log_const(it.first, it.second, indent); @@ -78,7 +78,7 @@ struct PrintAttrsPass : public Pass { } for (auto wire : mod->selected_wires()) { - log("%s%s\n", get_indent_str(indent), log_id(wire->name)); + log("%s%s\n", get_indent_str(indent), wire->name.unescape()); indent += 2; for (auto &it : wire->attributes) log_const(it.first, it.second, indent); diff --git a/passes/cmds/rename.cc b/passes/cmds/rename.cc index a07d588c4..15b6bf539 100644 --- a/passes/cmds/rename.cc +++ b/passes/cmds/rename.cc @@ -37,7 +37,7 @@ static void rename_in_module(RTLIL::Module *module, std::string from_name, std:: RTLIL::Cell *cell_to_rename = module->cell(from_name); if (wire_to_rename != nullptr) { - log("Renaming wire %s to %s in module %s.\n", log_id(wire_to_rename), log_id(to_name), log_id(module)); + log("Renaming wire %s to %s in module %s.\n", wire_to_rename, to_name, module); module->rename(wire_to_rename, to_name); if (wire_to_rename->port_id || flag_output) { if (flag_output) @@ -50,7 +50,7 @@ static void rename_in_module(RTLIL::Module *module, std::string from_name, std:: if (cell_to_rename != nullptr) { if (flag_output) log_cmd_error("Called with -output but the specified object is a cell.\n"); - log("Renaming cell %s to %s in module %s.\n", log_id(cell_to_rename), log_id(to_name), log_id(module)); + log("Renaming cell %s to %s in module %s.\n", cell_to_rename, to_name, module); module->rename(cell_to_rename, to_name); return; } @@ -518,7 +518,7 @@ struct RenamePass : public Pass { if (module == nullptr) log_cmd_error("No top module found!\n"); - log("Renaming module %s to %s.\n", log_id(module), log_id(new_name)); + log("Renaming module %s to %s.\n", module, new_name.unescape()); design->rename(module, new_name); } else @@ -532,7 +532,7 @@ struct RenamePass : public Pass { for (auto module : design->selected_modules()) { if (module->memories.size() != 0 || module->processes.size() != 0) { - log_warning("Skipping module %s with unprocessed memories or processes\n", log_id(module)); + log_warning("Skipping module %s with unprocessed memories or processes\n", module); continue; } diff --git a/passes/cmds/sdc/sdc.cc b/passes/cmds/sdc/sdc.cc index 635aad016..cb0b074d5 100644 --- a/passes/cmds/sdc/sdc.cc +++ b/passes/cmds/sdc/sdc.cc @@ -168,7 +168,7 @@ struct SdcObjects { RTLIL::Wire *wire = top->wire(port); if (!wire) { // This should not be possible. See https://github.com/YosysHQ/yosys/pull/5594#issue-3791198573 - log_error("Port %s doesn't exist", log_id(port)); + log_error("Port %s doesn't exist", port.unescape()); } design_ports.push_back(std::make_pair(port.str().substr(1), wire)); } diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 2359efe03..bcb34d1d4 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -1817,7 +1817,7 @@ struct LsPass : public Pass { log("\n%d %s:\n", int(matches.size()), "modules"); std::sort(matches.begin(), matches.end(), RTLIL::sort_by_id_str()); for (auto id : matches) - log(" %s%s\n", log_id(id), design->selected_whole_module(design->module(id)) ? "" : "*"); + log(" %s%s\n", id.unescape(), design->selected_whole_module(design->module(id)) ? "" : "*"); } } else diff --git a/passes/cmds/setattr.cc b/passes/cmds/setattr.cc index 25d8fd34c..9491ef19b 100644 --- a/passes/cmds/setattr.cc +++ b/passes/cmds/setattr.cc @@ -246,9 +246,9 @@ struct ChparamPass : public Pass { if (!new_parameters.empty()) log_cmd_error("The options -set and -list cannot be used together.\n"); for (auto module : design->selected_modules()) { - log("%s:\n", log_id(module)); + log("%s:\n", module); for (auto param : module->avail_parameters) - log(" %s\n", log_id(param)); + log(" %s\n", param.unescape()); } return; } diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 14a251c41..f45a2aeee 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -645,16 +645,16 @@ struct ShowWorker module = mod; if (design->selected_whole_module(module->name)) { if (module->get_blackbox_attribute()) { - // log("Skipping blackbox module %s.\n", log_id(module->name)); + //log("Skipping blackbox module %s.\n", module->name.unescape()); continue; } else if (module->cells().size() == 0 && module->connections().empty() && module->processes.empty()) { - log("Skipping empty module %s.\n", log_id(module->name)); + log("Skipping empty module %s.\n", module->name.unescape()); continue; } else - log("Dumping module %s to page %d.\n", log_id(module->name), ++page_counter); + log("Dumping module %s to page %d.\n", module->name.unescape(), ++page_counter); } else - log("Dumping selected parts of module %s to page %d.\n", log_id(module->name), ++page_counter); + log("Dumping selected parts of module %s to page %d.\n", module->name.unescape(), ++page_counter); handle_module(); } } diff --git a/passes/cmds/splice.cc b/passes/cmds/splice.cc index 2993c3d3a..9439a3a2e 100644 --- a/passes/cmds/splice.cc +++ b/passes/cmds/splice.cc @@ -149,7 +149,7 @@ struct SpliceWorker void run() { - log("Splicing signals in module %s:\n", log_id(module->name)); + log("Splicing signals in module %s:\n", module->name.unescape()); driven_bits.push_back(RTLIL::State::Sm); driven_bits.push_back(RTLIL::State::Sm); diff --git a/passes/cmds/splitcells.cc b/passes/cmds/splitcells.cc index d2063a0c8..a99e4d268 100644 --- a/passes/cmds/splitcells.cc +++ b/passes/cmds/splitcells.cc @@ -89,7 +89,7 @@ struct SplitcellsWorker if (GetSize(slices) <= 1) return 0; slices.push_back(GetSize(outsig)); - log("Splitting %s cell %s/%s into %d slices:\n", log_id(cell->type), log_id(module), log_id(cell), GetSize(slices)-1); + log("Splitting %s cell %s/%s into %d slices:\n", cell->type.unescape(), module, cell, GetSize(slices)-1); for (int i = 1; i < GetSize(slices); i++) { int slice_msb = slices[i]-1; @@ -126,7 +126,7 @@ struct SplitcellsWorker if (slice->hasParam(ID::WIDTH)) slice->setParam(ID::WIDTH, GetSize(slice->getPort(ID::Y))); - log(" slice %d: %s => %s\n", i, log_id(slice_name), log_signal(slice->getPort(ID::Y))); + log(" slice %d: %s => %s\n", i, slice_name, log_signal(slice->getPort(ID::Y))); } module->remove(cell); @@ -155,7 +155,7 @@ struct SplitcellsWorker if (GetSize(slices) <= 1) return 0; slices.push_back(GetSize(outsig)); - log("Splitting %s cell %s/%s into %d slices:\n", log_id(cell->type), log_id(module), log_id(cell), GetSize(slices)-1); + log("Splitting %s cell %s/%s into %d slices:\n", cell->type.unescape(), module, cell, GetSize(slices)-1); for (int i = 1; i < GetSize(slices); i++) { int slice_msb = slices[i]-1; @@ -185,7 +185,7 @@ struct SplitcellsWorker slice->setParam(ID::WIDTH, GetSize(slice->getPort(ID::Q))); - log(" slice %d: %s => %s\n", i, log_id(slice_name), log_signal(slice->getPort(ID::Q))); + log(" slice %d: %s => %s\n", i, slice_name.unescape(), log_signal(slice->getPort(ID::Q))); } module->remove(cell); @@ -258,7 +258,7 @@ struct SplitcellsPass : public Pass { if (count_split_pre) log("Split %d cells in module %s into %d cell slices.\n", - count_split_pre, log_id(module), count_split_post); + count_split_pre, module, count_split_post); } } } SplitnetsPass; diff --git a/passes/cmds/sta.cc b/passes/cmds/sta.cc index 5dfac1575..259794d32 100644 --- a/passes/cmds/sta.cc +++ b/passes/cmds/sta.cc @@ -66,12 +66,12 @@ struct StaWorker Module *inst_module = design->module(cell->type); if (!inst_module) { if (unrecognised_cells.insert(cell->type).second) - log_warning("Cell type '%s' not recognised! Ignoring.\n", log_id(cell->type)); + log_warning("Cell type '%s' not recognised! Ignoring.\n", cell->type.unescape()); continue; } if (!inst_module->get_blackbox_attribute()) { - log_warning("Cell type '%s' is not a black- nor white-box! Ignoring.\n", log_id(cell->type)); + log_warning("Cell type '%s' is not a black- nor white-box! Ignoring.\n", cell->type.unescape()); continue; } @@ -82,7 +82,7 @@ struct StaWorker if (!timing.count(derived_type)) { auto &t = timing.setup_module(inst_module); if (t.has_inputs && t.comb.empty() && t.arrival.empty() && t.required.empty()) - log_warning("Module '%s' has no timing arcs!\n", log_id(cell->type)); + log_warning("Module '%s' has no timing arcs!\n", cell->type.unescape()); } auto &t = timing.at(derived_type); @@ -203,10 +203,10 @@ struct StaWorker return; } - log("Latest arrival time in '%s' is %d:\n", log_id(module), maxarrival); + log("Latest arrival time in '%s' is %d:\n", module, maxarrival); auto it = endpoints.find(maxbit); if (it != endpoints.end() && it->second.sink) - log(" %6d %s (%s.%s)\n", maxarrival, log_id(it->second.sink), log_id(it->second.sink->type), log_id(it->second.port)); + log(" %6d %s (%s.%s)\n", maxarrival, it->second.sink, it->second.sink->type.unescape(), it->second.port.unescape()); else { log(" %6d (%s)\n", maxarrival, b.wire->port_output ? "" : ""); if (!b.wire->port_output) @@ -217,7 +217,7 @@ struct StaWorker int arrival = b.wire->get_intvec_attribute(ID::sta_arrival)[b.offset]; if (jt->second.driver) { log(" %s\n", log_signal(b)); - log(" %6d %s (%s.%s->%s)\n", arrival, log_id(jt->second.driver), log_id(jt->second.driver->type), log_id(jt->second.src_port), log_id(jt->second.dst_port)); + log(" %6d %s (%s.%s->%s)\n", arrival, jt->second.driver, jt->second.driver->type.unescape(), jt->second.src_port.unescape(), jt->second.dst_port.unescape()); } else if (b.wire->port_input) log(" %6d %s (%s)\n", arrival, log_signal(b), ""); @@ -234,13 +234,13 @@ struct StaWorker continue; if (!b.wire->attributes.count(ID::sta_arrival)) { - log_warning("Endpoint %s.%s has no (* sta_arrival *) value.\n", log_id(module), log_signal(b)); + log_warning("Endpoint %s.%s has no (* sta_arrival *) value.\n", module, log_signal(b)); continue; } auto arrival = b.wire->get_intvec_attribute(ID::sta_arrival)[b.offset]; if (arrival < 0) { - log_warning("Endpoint %s.%s has no (* sta_arrival *) value.\n", log_id(module), log_signal(b)); + log_warning("Endpoint %s.%s has no (* sta_arrival *) value.\n", module, log_signal(b)); continue; } arrival += i.second.required; diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index 9494d6032..de767b96a 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -523,7 +523,7 @@ struct statdata_t { print_log_line("cells", local_num_cells, local_area, num_cells, area, 0, print_area, print_hierarchical, print_global_only); for (auto &it : num_cells_by_type) if (it.second) { - auto name = string(log_id(it.first)); + auto name = string(it.first.unescape()); print_log_line(name, local_num_cells_by_type.count(it.first) ? local_num_cells_by_type.at(it.first) : 0, local_area_cells_by_type.count(it.first) ? local_area_cells_by_type.at(it.first) : 0, it.second, area_cells_by_type.at(it.first), 1, print_area, print_hierarchical, print_global_only); @@ -533,7 +533,7 @@ struct statdata_t { print_global_only); for (auto &it : num_submodules_by_type) if (it.second) - print_log_line(string(log_id(it.first)), it.second, 0, it.second, + print_log_line(string(it.first.unescape()), it.second, 0, it.second, submodules_area_by_type.count(it.first) ? submodules_area_by_type.at(it.first) : 0, 1, print_area, print_hierarchical, print_global_only); } @@ -607,7 +607,7 @@ struct statdata_t { if (it.second) { if (!first_line) log(",\n"); - log(" %s: %s", json11::Json(log_id(it.first)).dump(), + log(" %s: %s", json11::Json(it.first.unescape()).dump(), json_line(local_num_cells_by_type.count(it.first) ? local_num_cells_by_type.at(it.first) : 0, local_area_cells_by_type.count(it.first) ? local_area_cells_by_type.at(it.first) : 0, it.second, area_cells_by_type.at(it.first)) @@ -621,7 +621,7 @@ struct statdata_t { if (it.second) { if (!first_line) log(",\n"); - log(" %s: %s", json11::Json(log_id(it.first)).dump(), + log(" %s: %s", json11::Json(it.first.unescape()).dump(), json_line(0, 0, it.second, submodules_area_by_type.count(it.first) ? submodules_area_by_type.at(it.first) : 0) .c_str()); @@ -662,14 +662,14 @@ struct statdata_t { if (it.second) { if (!first_line) log(",\n"); - log(" %s: %u", json11::Json(log_id(it.first)).dump(), it.second); + log(" %s: %u", json11::Json(it.first.unescape()).dump(), it.second); first_line = false; } for (auto &it : num_submodules_by_type) if (it.second) { if (!first_line) log(",\n"); - log(" %s: %u", json11::Json(log_id(it.first)).dump(), it.second); + log(" %s: %u", json11::Json(it.first.unescape()).dump(), it.second); first_line = false; } log("\n"); @@ -697,14 +697,14 @@ struct statdata_t { if (it.second) { if (!first_line) log(",\n"); - log(" %s: %u", json11::Json(log_id(it.first)).dump(), it.second); + log(" %s: %u", json11::Json(it.first.unescape()).dump(), it.second); first_line = false; } for (auto &it : num_submodules_by_type) if (it.second) { if (!first_line) log(",\n"); - log(" %s: %u", json11::Json(log_id(it.first)).dump(), it.second); + log(" %s: %u", json11::Json(it.first.unescape()).dump(), it.second); first_line = false; } log("\n"); @@ -734,7 +734,7 @@ statdata_t hierarchy_worker(std::map &mod_stat, RTL for (auto &it : mod_data.num_submodules_by_type) { if (mod_stat.count(it.first) > 0) { if (!quiet) - mod_data.print_log_line(string(log_id(it.first)), mod_stat.at(it.first).local_num_cells, + mod_data.print_log_line(string(it.first.unescape()), mod_stat.at(it.first).local_num_cells, mod_stat.at(it.first).local_area, mod_stat.at(it.first).num_cells, mod_stat.at(it.first).area, level, has_area, hierarchy_mode); hierarchy_worker(mod_stat, it.first, level + 1, quiet, has_area, hierarchy_mode) * it.second; @@ -1009,7 +1009,7 @@ struct StatPass : public Pass { first_module = false; } else { log("\n"); - log("=== %s%s ===\n", log_id(mod->name), mod->is_selected_whole() ? "" : " (partially selected)"); + log("=== %s%s ===\n", mod->name.unescape(), mod->is_selected_whole() ? "" : " (partially selected)"); log("\n"); data.log_data(mod->name, false, has_area, hierarchy_mode); } @@ -1026,7 +1026,7 @@ struct StatPass : public Pass { log("=== design hierarchy ===\n"); log("\n"); mod_stat[top_mod->name].print_log_header(has_area, hierarchy_mode, true); - mod_stat[top_mod->name].print_log_line(log_id(top_mod->name), mod_stat[top_mod->name].local_num_cells, + mod_stat[top_mod->name].print_log_line(top_mod->name.unescape(), mod_stat[top_mod->name].local_num_cells, mod_stat[top_mod->name].local_area, mod_stat[top_mod->name].num_cells, mod_stat[top_mod->name].area, 0, has_area, hierarchy_mode, true); } diff --git a/passes/cmds/timeest.cc b/passes/cmds/timeest.cc index 1caa1ddaf..3105affa1 100644 --- a/passes/cmds/timeest.cc +++ b/passes/cmds/timeest.cc @@ -83,7 +83,7 @@ struct EstimateSta { void run() { - log("\nModule %s\n", log_id(m)); + log("\nModule %s\n", m); if (clk.has_value()) log("Domain %s\n", log_signal(*clk)); @@ -97,7 +97,7 @@ struct EstimateSta { FfData ff(nullptr, cell); if (!ff.has_clk) { log_warning("Ignoring unsupported storage element '%s' (%s)\n", - log_id(cell), log_id(cell->type)); + cell, cell->type.unescape()); continue; } if (ff.sig_clk != clk) @@ -121,7 +121,7 @@ struct EstimateSta { aigs.emplace(fingerprint, Aig(cell)); if (aigs.at(fingerprint).name.empty()) { log_error("Unsupported cell '%s' in module '%s'", - log_id(cell->type), log_id(m)); + cell->type.unescape(), m); } } @@ -141,7 +141,7 @@ struct EstimateSta { for (auto &mem : Mem::get_all_memories(m)) { for (auto &rd : mem.rd_ports) { if (!rd.clk_enable) { - log_error("Unsupported async memory port '%s'\n", log_id(rd.cell)); + log_error("Unsupported async memory port '%s'\n", rd.cell); continue; } if (sigmap(rd.clk) != clk) @@ -165,7 +165,7 @@ struct EstimateSta { } else if (port->port_output && !port->port_input) { all_outputs.append(port); } else if (port->port_output && port->port_input) { - log_warning("Ignoring bi-directional port %s\n", log_id(port)); + log_warning("Ignoring bi-directional port %s\n", port); } } add_seq(nullptr, all_inputs, all_outputs); @@ -216,7 +216,7 @@ struct EstimateSta { } if (!topo.sort()) - log_error("Module '%s' contains combinational loops", log_id(m)); + log_error("Module '%s' contains combinational loops", m); // now we determine how long it takes for signals to stabilize @@ -342,7 +342,7 @@ struct EstimateSta { std::string src_attr = cell->get_src_attribute(); cell_src = stringf(" source: %s", src_attr); } - log(" cell %s (%s)%s\n", log_id(cell), log_id(cell->type), cell_src); + log(" cell %s (%s)%s\n", cell, cell->type.unescape(), cell_src); printed.insert(cell); } } else { @@ -425,7 +425,7 @@ struct TimeestPass : Pass { if (clk_domain_specified) { if (!m->wire(RTLIL::escape_id(clk_name))) { - log_warning("No domain '%s' in module %s\n", clk_name.c_str(), log_id(m)); + log_warning("No domain '%s' in module %s\n", clk_name.c_str(), m); continue; } diff --git a/passes/cmds/torder.cc b/passes/cmds/torder.cc index 52c00072f..828b65c24 100644 --- a/passes/cmds/torder.cc +++ b/passes/cmds/torder.cc @@ -74,7 +74,7 @@ struct TorderPass : public Pass { for (auto module : design->selected_modules()) { - log("module %s\n", log_id(module)); + log("module %s\n", module); SigMap sigmap(module); dict> bit_drivers, bit_users; @@ -116,12 +116,12 @@ struct TorderPass : public Pass { for (auto &it : toposort.loops) { log(" loop"); for (auto cell : it) - log(" %s", log_id(cell)); + log(" %s", cell); log("\n"); } for (auto cell : toposort.sorted) - log(" cell %s\n", log_id(cell)); + log(" cell %s\n", cell); } } } TorderPass; diff --git a/passes/cmds/trace.cc b/passes/cmds/trace.cc index 222fecaca..37f7da89b 100644 --- a/passes/cmds/trace.cc +++ b/passes/cmds/trace.cc @@ -28,34 +28,34 @@ struct TraceMonitor : public RTLIL::Monitor { void notify_module_add(RTLIL::Module *module) override { - log("#TRACE# Module add: %s\n", log_id(module)); + log("#TRACE# Module add: %s\n", module); } void notify_module_del(RTLIL::Module *module) override { - log("#TRACE# Module delete: %s\n", log_id(module)); + log("#TRACE# Module delete: %s\n", module); } void notify_connect(RTLIL::Cell *cell, RTLIL::IdString port, const RTLIL::SigSpec &old_sig, const RTLIL::SigSpec &sig) override { - log("#TRACE# Cell connect: %s.%s.%s = %s (was: %s)\n", log_id(cell->module), log_id(cell), log_id(port), log_signal(sig), log_signal(old_sig)); + log("#TRACE# Cell connect: %s.%s.%s = %s (was: %s)\n", cell->module, cell, port.unescape(), log_signal(sig), log_signal(old_sig)); } void notify_connect(RTLIL::Module *module, const RTLIL::SigSig &sigsig) override { - log("#TRACE# Connection in module %s: %s = %s\n", log_id(module), log_signal(sigsig.first), log_signal(sigsig.second)); + log("#TRACE# Connection in module %s: %s = %s\n", module, log_signal(sigsig.first), log_signal(sigsig.second)); } void notify_connect(RTLIL::Module *module, const std::vector &sigsig_vec) override { - log("#TRACE# New connections in module %s:\n", log_id(module)); + log("#TRACE# New connections in module %s:\n", module); for (auto &sigsig : sigsig_vec) log("## %s = %s\n", log_signal(sigsig.first), log_signal(sigsig.second)); } void notify_blackout(RTLIL::Module *module) override { - log("#TRACE# Blackout in module %s:\n", log_id(module)); + log("#TRACE# Blackout in module %s:\n", module); } }; diff --git a/passes/cmds/viz.cc b/passes/cmds/viz.cc index e3b09d029..9eb35d6c2 100644 --- a/passes/cmds/viz.cc +++ b/passes/cmds/viz.cc @@ -279,7 +279,7 @@ struct Graph { Graph(Module *module, const VizConfig &config) : module(module), config(config) { - log("Running 'viz -%d' for module %s:\n", config.effort, log_id(module)); + log("Running 'viz -%d' for module %s:\n", config.effort, module); log(" Phase %d: Construct initial graph\n", phase_counter++); SigMap sigmap(module); @@ -718,7 +718,7 @@ struct VizWorker void write_dot(FILE *f) { - fprintf(f, "digraph \"%s\" {\n", log_id(module)); + fprintf(f, "digraph \"%s\" {\n", module); fprintf(f, " rankdir = LR;\n"); dict>> extra_lines; @@ -734,7 +734,7 @@ struct VizWorker buffer.emplace_back(); for (auto name : g->names()) - buffer.back().push_back(log_id(name)); + buffer.back().push_back(name.unescape()); std::sort(buffer.back().begin(), buffer.back().end()); std::sort(buffer.begin(), buffer.end()); @@ -782,7 +782,7 @@ struct VizWorker g->names().sort(); std::string label; // = stringf("vg=%d\\n", g->index); for (auto n : g->names()) - label = label + (label.empty() ? "" : "\\n") + log_id(n); + label = label + (label.empty() ? "" : "\\n") + n.unescape(); fprintf(f, "\tn%d [shape=rectangle,label=\"%s\"];\n", g->index, label.c_str()); } else { std::string label = stringf("vg=%d | %d cells", g->index, GetSize(g->names())); diff --git a/passes/cmds/wrapcell.cc b/passes/cmds/wrapcell.cc index 4c6f44ed7..1d73decc5 100644 --- a/passes/cmds/wrapcell.cc +++ b/passes/cmds/wrapcell.cc @@ -70,7 +70,7 @@ std::optional format_with_params(std::string fmt, const dicttype)) log_error("Non-internal cell type '%s' on cell '%s' in module '%s' unsupported\n", - log_id(cell->type), log_id(cell), log_id(module)); + cell->type.unescape(), cell, module); std::vector> unused_outputs, used_outputs; for (auto conn : cell->connections()) { @@ -233,7 +233,7 @@ struct WrapcellPass : Pass { std::optional unescaped_name = format_with_params(name_fmt, cell->parameters, context); if (!unescaped_name) log_error("Formatting error when processing cell '%s' in module '%s'\n", - log_id(cell), log_id(module)); + cell, module); IdString name = RTLIL::escape_id(unescaped_name.value()); if (d->module(name)) @@ -274,7 +274,7 @@ struct WrapcellPass : Pass { if (!value) log_error("Formatting error when processing cell '%s' in module '%s'\n", - log_id(cell), log_id(module)); + cell, module); subm->set_string_attribute(rule.name, value.value()); } diff --git a/passes/cmds/xprop.cc b/passes/cmds/xprop.cc index 3f40e72ab..25c1a7320 100644 --- a/passes/cmds/xprop.cc +++ b/passes/cmds/xprop.cc @@ -467,7 +467,7 @@ struct XpropWorker return; } - log_warning("Unhandled cell %s (%s) during maybe-x marking\n", log_id(cell), log_id(cell->type)); + log_warning("Unhandled cell %s (%s) during maybe-x marking\n", cell, cell->type.unescape()); mark_outputs_maybe_x(cell); } @@ -862,7 +862,7 @@ struct XpropWorker if ((ff.has_clk || ff.has_gclk) && !ff.has_ce && !ff.has_aload && !ff.has_srst && !ff.has_arst && !ff.has_sr) { if (ff.has_clk && maybe_x(ff.sig_clk)) { - log_warning("Only non-x CLK inputs are currently supported for %s (%s)\n", log_id(cell), log_id(cell->type)); + log_warning("Only non-x CLK inputs are currently supported for %s (%s)\n", cell, cell->type.unescape()); } else { auto init_q = ff.val_init; auto init_q_is_1 = init_q; @@ -907,7 +907,7 @@ struct XpropWorker return; } } else { - log_warning("Unhandled FF-cell %s (%s), consider running clk2fflogic, async2sync and/or dffunmap\n", log_id(cell), log_id(cell->type)); + log_warning("Unhandled FF-cell %s (%s), consider running clk2fflogic, async2sync and/or dffunmap\n", cell, cell->type.unescape()); } } @@ -964,9 +964,9 @@ struct XpropWorker log("Running 'demuxmap' preserves x-propagation and can be run before 'xprop'.\n"); if (options.required) - log_error("Unhandled cell %s (%s)\n", log_id(cell), log_id(cell->type)); + log_error("Unhandled cell %s (%s)\n", cell, cell->type.unescape()); else - log_warning("Unhandled cell %s (%s)\n", log_id(cell), log_id(cell->type)); + log_warning("Unhandled cell %s (%s)\n", cell, cell->type.unescape()); } void split_ports() @@ -980,7 +980,7 @@ struct XpropWorker auto wire = module->wire(port); if (module->design->selected(module, wire)) { if (wire->port_input == wire->port_output) { - log_warning("Port %s not an input or an output port which is not supported by xprop\n", log_id(wire)); + log_warning("Port %s not an input or an output port which is not supported by xprop\n", wire); } else if ((options.split_inputs && !options.assume_def_inputs && wire->port_input) || (options.split_outputs && wire->port_output)) { auto port_d = module->uniquify(stringf("%s_d", port)); auto port_x = module->uniquify(stringf("%s_x", port)); diff --git a/passes/equiv/equiv_induct.cc b/passes/equiv/equiv_induct.cc index e4480c893..c2308462e 100644 --- a/passes/equiv/equiv_induct.cc +++ b/passes/equiv/equiv_induct.cc @@ -84,7 +84,7 @@ struct EquivInductWorker : public EquivWorker<> void run() { - log("Found %d unproven $equiv cells in module %s:\n", GetSize(workset), log_id(module)); + log("Found %d unproven $equiv cells in module %s:\n", GetSize(workset), module); if (satgen.model_undef) { for (auto cell : cells) @@ -217,7 +217,7 @@ struct EquivInductPass : public Pass { } if (unproven_equiv_cells.empty()) { - log("No selected unproven $equiv cells found in %s.\n", log_id(module)); + log("No selected unproven $equiv cells found in %s.\n", module); continue; } diff --git a/passes/equiv/equiv_make.cc b/passes/equiv/equiv_make.cc index bae7452f7..53e86cdae 100644 --- a/passes/equiv/equiv_make.cc +++ b/passes/equiv/equiv_make.cc @@ -159,7 +159,7 @@ struct EquivMakeWorker if (encdata.count(id)) { - log("Creating encoder/decoder for signal %s.\n", log_id(id)); + log("Creating encoder/decoder for signal %s.\n", id.unescape()); Wire *dec_wire = equiv_mod->addWire(id.str() + "_decoded", gold_wire->width); Wire *enc_wire = equiv_mod->addWire(id.str() + "_encoded", gate_wire->width); @@ -226,15 +226,15 @@ struct EquivMakeWorker if (gold_wire == nullptr || gate_wire == nullptr || gold_wire->width != gate_wire->width) { if (gold_wire && gold_wire->port_id) - log_error("Can't match gold port `%s' to a gate port.\n", log_id(gold_wire)); + log_error("Can't match gold port `%s' to a gate port.\n", gold_wire); if (gate_wire && gate_wire->port_id) - log_error("Can't match gate port `%s' to a gold port.\n", log_id(gate_wire)); + log_error("Can't match gate port `%s' to a gold port.\n", gate_wire); continue; } log("Presumably equivalent wires: %s (%s), %s (%s) -> %s\n", - log_id(gold_wire), log_signal(assign_map(gold_wire)), - log_id(gate_wire), log_signal(assign_map(gate_wire)), log_id(id)); + gold_wire, log_signal(assign_map(gold_wire)), + gate_wire, log_signal(assign_map(gate_wire)), id.unescape()); if (gold_wire->port_output || gate_wire->port_output) { @@ -313,7 +313,7 @@ struct EquivMakeWorker new_sig[i] = old_sig[i]; if (old_sig != new_sig) { log("Changing input %s of cell %s (%s): %s -> %s\n", - log_id(conn.first), log_id(c), log_id(c->type), + conn.first.unescape(), c, c->type.unescape(), log_signal(old_sig), log_signal(new_sig)); c->setPort(conn.first, new_sig); } @@ -344,7 +344,7 @@ struct EquivMakeWorker goto try_next_cell_name; log("Presumably equivalent cells: %s %s (%s) -> %s\n", - log_id(gold_cell), log_id(gate_cell), log_id(gold_cell->type), log_id(id)); + gold_cell, gate_cell, gold_cell->type.unescape(), id.unescape()); for (auto gold_conn : gold_cell->connections()) { diff --git a/passes/equiv/equiv_mark.cc b/passes/equiv/equiv_mark.cc index 97a2a38dd..0f355af4e 100644 --- a/passes/equiv/equiv_mark.cc +++ b/passes/equiv/equiv_mark.cc @@ -109,7 +109,7 @@ struct EquivMarkWorker void run() { - log("Running equiv_mark on module %s:\n", log_id(module)); + log("Running equiv_mark on module %s:\n", module); // marking region 0 diff --git a/passes/equiv/equiv_miter.cc b/passes/equiv/equiv_miter.cc index 6acfe85a9..b8372ceb0 100644 --- a/passes/equiv/equiv_miter.cc +++ b/passes/equiv/equiv_miter.cc @@ -82,7 +82,7 @@ struct EquivMiterWorker for (auto c : source_module->selected_cells()) if (c->type == ID($equiv)) { - log("Seed $equiv cell: %s\n", log_id(c)); + log("Seed $equiv cell: %s\n", c); seed_cells.insert(c); } @@ -194,11 +194,11 @@ struct EquivMiterWorker w->port_input = true; } if (w->port_output && w->port_input) - log("Created miter inout port %s.\n", log_id(w)); + log("Created miter inout port %s.\n", w); else if (w->port_output) - log("Created miter output port %s.\n", log_id(w)); + log("Created miter output port %s.\n", w); else if (w->port_input) - log("Created miter input port %s.\n", log_id(w)); + log("Created miter input port %s.\n", w); } miter_module->fixup_ports(); @@ -252,7 +252,7 @@ struct EquivMiterWorker void run() { - log("Creating miter %s from module %s.\n", log_id(miter_module), log_id(source_module)); + log("Creating miter %s from module %s.\n", miter_module, source_module); find_miter_cells_wires(); copy_to_miter(); make_stuff(); @@ -320,7 +320,7 @@ struct EquivMiterPass : public Pass { extra_args(args, argidx, design); if (design->module(worker.miter_name)) - log_cmd_error("Miter module %s already exists.\n", log_id(worker.miter_name)); + log_cmd_error("Miter module %s already exists.\n", worker.miter_name.unescape()); worker.source_module = nullptr; for (auto m : design->selected_modules()) { diff --git a/passes/equiv/equiv_purge.cc b/passes/equiv/equiv_purge.cc index 5b0696d9b..4062161bb 100644 --- a/passes/equiv/equiv_purge.cc +++ b/passes/equiv/equiv_purge.cc @@ -37,7 +37,7 @@ struct EquivPurgeWorker Wire *wire = sig.as_wire(); if (wire->name.isPublic()) { if (!wire->port_output) { - log(" Module output: %s (%s)\n", log_signal(wire), log_id(cellname)); + log(" Module output: %s (%s)\n", log_signal(wire), cellname.unescape()); wire->port_output = true; } return wire; @@ -53,7 +53,7 @@ struct EquivPurgeWorker Wire *wire = module->addWire(name, GetSize(sig)); wire->port_output = true; module->connect(wire, sig); - log(" Module output: %s (%s)\n", log_signal(wire), log_id(cellname)); + log(" Module output: %s (%s)\n", log_signal(wire), cellname.unescape()); return wire; } } @@ -87,7 +87,7 @@ struct EquivPurgeWorker void run() { - log("Running equiv_purge on module %s:\n", log_id(module)); + log("Running equiv_purge on module %s:\n", module); for (auto wire : module->wires()) { wire->port_input = false; diff --git a/passes/equiv/equiv_remove.cc b/passes/equiv/equiv_remove.cc index 5d1823e12..c871cd9ef 100644 --- a/passes/equiv/equiv_remove.cc +++ b/passes/equiv/equiv_remove.cc @@ -69,7 +69,7 @@ struct EquivRemovePass : public Pass { { for (auto cell : module->selected_cells()) if (cell->type == ID($equiv) && (mode_gold || mode_gate || cell->getPort(ID::A) == cell->getPort(ID::B))) { - log("Removing $equiv cell %s.%s (%s).\n", log_id(module), log_id(cell), log_signal(cell->getPort(ID::Y))); + log("Removing $equiv cell %s.%s (%s).\n", module, cell, log_signal(cell->getPort(ID::Y))); module->connect(cell->getPort(ID::Y), mode_gate ? cell->getPort(ID::B) : cell->getPort(ID::A)); module->remove(cell); remove_count++; diff --git a/passes/equiv/equiv_simple.cc b/passes/equiv/equiv_simple.cc index e498928c3..6f3c9dc71 100644 --- a/passes/equiv/equiv_simple.cc +++ b/passes/equiv/equiv_simple.cc @@ -205,10 +205,10 @@ struct EquivSimpleWorker : public EquivWorker (GetSize(cone_a.cells) + GetSize(cone_b.cells)) - GetSize(cells)); #if 0 for (auto cell : short_cells_cone_a) - log(" A-side cell: %s\n", log_id(cell)); + log(" A-side cell: %s\n", cell); for (auto cell : short_cells_cone_b) - log(" B-side cell: %s\n", log_id(cell)); + log(" B-side cell: %s\n", cell); #endif } void report_new_assume_cells(const pool& extra_problem_cells, int old_size, const pool& problem_cells) const @@ -219,7 +219,7 @@ struct EquivSimpleWorker : public EquivWorker old_size - (GetSize(problem_cells) - GetSize(extra_problem_cells))); #if 0 for (auto cell : extra_problem_cells) - log(" cell: %s\n", log_id(cell)); + log(" cell: %s\n", cell); #endif } } @@ -305,7 +305,7 @@ struct EquivSimpleWorker : public EquivWorker pool seed_b = { bit_b }; if (cfg.verbose) { - log(" Trying to prove $equiv cell %s:\n", log_id(cell)); + log(" Trying to prove $equiv cell %s:\n", cell); log(" A = %s, B = %s, Y = %s\n", log_signal(bit_a), log_signal(bit_b), log_signal(cell->getPort(ID::Y))); } else { log(" Trying to prove $equiv for %s:", log_signal(cell->getPort(ID::Y))); @@ -477,7 +477,7 @@ struct EquivSimplePass : public Pass { continue; log("Found %d unproven $equiv cells (%d groups) in %s:\n", - unproven_cells_counter, GetSize(unproven_equiv_cells), log_id(module)); + unproven_cells_counter, GetSize(unproven_equiv_cells), module); for (auto cell : module->cells()) { if (!ct.cell_known(cell->type)) diff --git a/passes/equiv/equiv_status.cc b/passes/equiv/equiv_status.cc index b221be27c..da53c60a2 100644 --- a/passes/equiv/equiv_status.cc +++ b/passes/equiv/equiv_status.cc @@ -67,17 +67,17 @@ struct EquivStatusPass : public Pass { } if (unproven_equiv_cells.empty() && !proven_equiv_cells) { - log("No $equiv cells found in %s.\n", log_id(module)); + log("No $equiv cells found in %s.\n", module); continue; } - log("Found %d $equiv cells in %s:\n", GetSize(unproven_equiv_cells) + proven_equiv_cells, log_id(module)); + log("Found %d $equiv cells in %s:\n", GetSize(unproven_equiv_cells) + proven_equiv_cells, module); log(" Of those cells %d are proven and %d are unproven.\n", proven_equiv_cells, GetSize(unproven_equiv_cells)); if (unproven_equiv_cells.empty()) { log(" Equivalence successfully proven!\n"); } else { for (auto cell : unproven_equiv_cells) - log(" Unproven $equiv %s: %s %s\n", log_id(cell), log_signal(cell->getPort(ID::A)), log_signal(cell->getPort(ID::B))); + log(" Unproven $equiv %s: %s %s\n", cell, log_signal(cell->getPort(ID::A)), log_signal(cell->getPort(ID::B))); } unproven_count += GetSize(unproven_equiv_cells); diff --git a/passes/equiv/equiv_struct.cc b/passes/equiv/equiv_struct.cc index 411f0dd5c..7f8d8d282 100644 --- a/passes/equiv/equiv_struct.cc +++ b/passes/equiv/equiv_struct.cc @@ -79,7 +79,7 @@ struct EquivStructWorker inputs_a.append(bits_a[i]); inputs_b.append(bits_b[i]); input_names.push_back(GetSize(bits_a) == 1 ? port_a.first.str() : - stringf("%s[%d]", log_id(port_a.first), i)); + stringf("%s[%d]", port_a.first.unescape(), i)); } } @@ -111,7 +111,7 @@ struct EquivStructWorker } auto merged_attr = cell_b->get_strpool_attribute(ID::equiv_merged); - merged_attr.insert(log_id(cell_b)); + merged_attr.insert(cell_b->name.unescape()); cell_a->add_strpool_attribute(ID::equiv_merged, merged_attr); module->remove(cell_b); } @@ -144,7 +144,7 @@ struct EquivStructWorker SigBit sig_b = sigmap(cell->getPort(ID::B).as_bit()); SigBit sig_y = sigmap(cell->getPort(ID::Y).as_bit()); if (sig_a == sig_b && equiv_inputs.count(sig_y)) { - log(" Purging redundant $equiv cell %s.\n", log_id(cell)); + log(" Purging redundant $equiv cell %s.\n", cell); module->connect(sig_y, sig_a); module->remove(cell); merge_count++; @@ -266,9 +266,9 @@ struct EquivStructWorker run_strategy: int total_group_size = GetSize(gold_cells) + GetSize(gate_cells) + GetSize(other_cells); log(" %s merging %d %s cells (from group of %d) using strategy %s:\n", phase ? "Bwd" : "Fwd", - 2*GetSize(cell_pairs), log_id(cells_type), total_group_size, strategy); + 2*GetSize(cell_pairs), cells_type.unescape(), total_group_size, strategy); for (auto it : cell_pairs) { - log(" Merging cells %s and %s.\n", log_id(it.first), log_id(it.second)); + log(" Merging cells %s and %s.\n", it.first, it.second); merge_cell_pair(it.first, it.second); } } @@ -347,7 +347,7 @@ struct EquivStructPass : public Pass { for (auto module : design->selected_modules()) { int module_merge_count = 0; - log("Running equiv_struct on module %s:\n", log_id(module)); + log("Running equiv_struct on module %s:\n", module); for (int iter = 0;; iter++) { if (iter == max_iter) { log(" Reached iteration limit of %d.\n", iter); @@ -359,7 +359,7 @@ struct EquivStructPass : public Pass { module_merge_count += worker.merge_count; } if (module_merge_count) - log(" Performed a total of %d merges in module %s.\n", module_merge_count, log_id(module)); + log(" Performed a total of %d merges in module %s.\n", module_merge_count, module); } } } EquivStructPass; diff --git a/passes/fsm/fsm_detect.cc b/passes/fsm/fsm_detect.cc index 5f491a16c..dfe99f512 100644 --- a/passes/fsm/fsm_detect.cc +++ b/passes/fsm/fsm_detect.cc @@ -132,7 +132,7 @@ static void detect_fsm(RTLIL::Wire *wire, bool ignore_self_reset=false) if (wire->width <= 1) { if (has_fsm_encoding_attr) { - log_warning("Removing fsm_encoding attribute from 1-bit net: %s.%s\n", log_id(wire->module), log_id(wire)); + log_warning("Removing fsm_encoding attribute from 1-bit net: %s.%s\n", wire->module, wire); wire->attributes.erase(ID::fsm_encoding); } return; @@ -230,23 +230,23 @@ static void detect_fsm(RTLIL::Wire *wire, bool ignore_self_reset=false) warnings.push_back("FSM seems to be self-resetting. Possible simulation-synthesis mismatch!\n"); if (!warnings.empty()) { - string warnmsg = stringf("Regarding the user-specified fsm_encoding attribute on %s.%s:\n", log_id(wire->module), log_id(wire)); + string warnmsg = stringf("Regarding the user-specified fsm_encoding attribute on %s.%s:\n", wire->module, wire); for (auto w : warnings) warnmsg += " " + w; log_warning("%s", warnmsg); } else { - log("FSM state register %s.%s already has fsm_encoding attribute.\n", log_id(wire->module), log_id(wire)); + log("FSM state register %s.%s already has fsm_encoding attribute.\n", wire->module, wire); } } else if (looks_like_state_reg && looks_like_good_state_reg && !has_init_attr && !is_module_port && !is_self_resetting) { - log("Found FSM state register %s.%s.\n", log_id(wire->module), log_id(wire)); + log("Found FSM state register %s.%s.\n", wire->module, wire); wire->attributes[ID::fsm_encoding] = RTLIL::Const("auto"); } else if (looks_like_state_reg) { - log("Not marking %s.%s as FSM state register:\n", log_id(wire->module), log_id(wire)); + log("Not marking %s.%s as FSM state register:\n", wire->module, wire); if (is_module_port) log(" Register is connected to module port.\n"); diff --git a/passes/fsm/fsm_expand.cc b/passes/fsm/fsm_expand.cc index b11f0d3be..40c1d9904 100644 --- a/passes/fsm/fsm_expand.cc +++ b/passes/fsm/fsm_expand.cc @@ -189,12 +189,12 @@ struct FsmExpand if (GetSize(input_sig) > 10) log_warning("Cell %s.%s (%s) has %d input bits, merging into FSM %s.%s might be problematic.\n", - log_id(cell->module), log_id(cell), log_id(cell->type), - GetSize(input_sig), log_id(fsm_cell->module), log_id(fsm_cell)); + cell->module, cell, cell->type.unescape(), + GetSize(input_sig), fsm_cell->module, fsm_cell); if (GetSize(fsm_data.transition_table) > 10000) log_warning("Transition table for FSM %s.%s already has %d rows, merging more cells " - "into this FSM might be problematic.\n", log_id(fsm_cell->module), log_id(fsm_cell), + "into this FSM might be problematic.\n", fsm_cell->module, fsm_cell, GetSize(fsm_data.transition_table)); std::vector new_transition_table; diff --git a/passes/fsm/fsm_export.cc b/passes/fsm/fsm_export.cc index 7c79a53cc..1b06b18c2 100644 --- a/passes/fsm/fsm_export.cc +++ b/passes/fsm/fsm_export.cc @@ -64,7 +64,7 @@ void write_kiss2(struct RTLIL::Module *module, struct RTLIL::Cell *cell, std::st kiss_name.assign(attr_it->second.decode_string()); } else { - kiss_name.assign(log_id(module) + std::string("-") + log_id(cell) + ".kiss2"); + kiss_name.assign(module->name.unescape() + std::string("-") + cell->name.unescape() + ".kiss2"); } log("\n"); diff --git a/passes/fsm/fsm_info.cc b/passes/fsm/fsm_info.cc index ff3714021..7b3b59ee9 100644 --- a/passes/fsm/fsm_info.cc +++ b/passes/fsm/fsm_info.cc @@ -50,7 +50,7 @@ struct FsmInfoPass : public Pass { for (auto cell : mod->selected_cells()) if (cell->type == ID($fsm)) { log("\n"); - log("FSM `%s' from module `%s':\n", log_id(cell), log_id(mod)); + log("FSM `%s' from module `%s':\n", cell, mod); FsmData fsm_data; fsm_data.copy_from_cell(cell); fsm_data.log_info(cell); diff --git a/passes/fsm/fsm_recode.cc b/passes/fsm/fsm_recode.cc index e4cd53a07..5c813e481 100644 --- a/passes/fsm/fsm_recode.cc +++ b/passes/fsm/fsm_recode.cc @@ -96,7 +96,7 @@ static void fsm_recode(RTLIL::Cell *cell, RTLIL::Module *module, FILE *fm_set_fs log_error("FSM encoding `%s' is not supported!\n", encoding); if (encfile) - fprintf(encfile, ".fsm %s %s\n", log_id(module), RTLIL::unescape_id(cell->parameters[ID::NAME].decode_string()).c_str()); + fprintf(encfile, ".fsm %s %s\n", module, RTLIL::unescape_id(cell->parameters[ID::NAME].decode_string()).c_str()); int state_idx_counter = fsm_data.reset_state >= 0 ? 1 : 0; for (int i = 0; i < int(fsm_data.state_table.size()); i++) diff --git a/passes/hierarchy/flatten.cc b/passes/hierarchy/flatten.cc index 17bd6e340..2dd20302c 100644 --- a/passes/hierarchy/flatten.cc +++ b/passes/hierarchy/flatten.cc @@ -149,7 +149,7 @@ struct FlattenWorker hier_wire->attributes.erase(ID::hierconn); if (GetSize(hier_wire) < GetSize(tpl_wire)) { log_warning("Widening signal %s.%s to match size of %s.%s (via %s.%s).\n", - log_id(module), log_id(hier_wire), log_id(tpl), log_id(tpl_wire), log_id(module), log_id(cell)); + module, hier_wire, tpl, tpl_wire, module, cell); hier_wire->width = GetSize(tpl_wire); } new_wire = hier_wire; @@ -261,7 +261,7 @@ struct FlattenWorker if (sigmap(new_conn.first).has_const()) log_error("Cell port %s.%s.%s is driving constant bits: %s <= %s\n", - log_id(module), log_id(cell), log_id(port_it.first), log_signal(new_conn.first), log_signal(new_conn.second)); + module, cell, port_it.first.unescape(), log_signal(new_conn.first), log_signal(new_conn.second)); module->connect(new_conn); sigmap.add(new_conn.first, new_conn.second); @@ -316,12 +316,12 @@ struct FlattenWorker continue; if (cell->get_bool_attribute(ID::keep_hierarchy) || tpl->get_bool_attribute(ID::keep_hierarchy)) { - log("Keeping %s.%s (found keep_hierarchy attribute).\n", log_id(module), log_id(cell)); + log("Keeping %s.%s (found keep_hierarchy attribute).\n", module, cell); used_modules.insert(tpl); continue; } - log_debug("Flattening %s.%s (%s).\n", log_id(module), log_id(cell), log_id(cell->type)); + log_debug("Flattening %s.%s (%s).\n", module, cell, cell->type.unescape()); // If a design is fully selected and has a top module defined, topological sorting ensures that all cells // added during flattening are black boxes, and flattening is finished in one pass. However, when flattening // individual modules, this isn't the case, and the newly added cells might have to be flattened further. @@ -443,7 +443,7 @@ struct FlattenPass : public Pass { if (cleanup && top != nullptr) for (auto module : design->modules().to_vector()) if (!used_modules[module] && !module->get_blackbox_attribute(worker.ignore_wb)) { - log("Deleting now unused module %s.\n", log_id(module)); + log("Deleting now unused module %s.\n", module); design->remove(module); } diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 416997bee..67475eda0 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -225,7 +225,7 @@ struct IFExpander // about it and don't set has_interfaces_not_found (to avoid a // loop). log_warning("Could not find interface instance for `%s' in `%s'\n", - log_id(interface_name), log_id(&module)); + interface_name.unescape(), &module); } // Handle an interface connection from the module @@ -268,12 +268,12 @@ struct IFExpander // Go over all wires in interface, and add replacements to lists. for (auto mod_wire : mod_replace_ports->wires()) { - std::string signal_name1 = conn_name.str() + "." + log_id(mod_wire->name); - std::string signal_name2 = interface_name.str() + "." + log_id(mod_wire); + std::string signal_name1 = conn_name.str() + "." + mod_wire->name.unescape(); + std::string signal_name2 = interface_name.str() + "." + mod_wire->name.unescape(); connections_to_add_name.push_back(RTLIL::IdString(signal_name1)); if(module.wire(signal_name2) == nullptr) { log_error("Could not find signal '%s' in '%s'\n", - signal_name2.c_str(), log_id(module.name)); + signal_name2.c_str(), module.name.unescape()); } else { RTLIL::Wire *wire_in_parent = module.wire(signal_name2); @@ -432,7 +432,7 @@ void check_cell_connections(const RTLIL::Module &module, RTLIL::Cell &cell, RTLI if (id <= 0 || id > GetSize(mod.ports)) log_error("Module `%s' referenced in module `%s' in cell `%s' " "has only %d ports, requested port %d.\n", - log_id(cell.type), log_id(&module), log_id(&cell), + cell.type.unescape(), &module, &cell, GetSize(mod.ports), id); continue; } @@ -441,8 +441,8 @@ void check_cell_connections(const RTLIL::Module &module, RTLIL::Cell &cell, RTLI if (!wire || wire->port_id == 0) { log_error("Module `%s' referenced in module `%s' in cell `%s' " "does not have a port named '%s'.\n", - log_id(cell.type), log_id(&module), log_id(&cell), - log_id(conn.first)); + cell.type.unescape(), &module, &cell, + conn.first.unescape()); } } for (auto ¶m : cell.parameters) { @@ -450,7 +450,7 @@ void check_cell_connections(const RTLIL::Module &module, RTLIL::Cell &cell, RTLI if (id <= 0 || id > GetSize(mod.avail_parameters)) log_error("Module `%s' referenced in module `%s' in cell `%s' " "has only %d parameters, requested parameter %d.\n", - log_id(cell.type), log_id(&module), log_id(&cell), + cell.type.unescape(), &module, &cell, GetSize(mod.avail_parameters), id); continue; } @@ -460,8 +460,8 @@ void check_cell_connections(const RTLIL::Module &module, RTLIL::Cell &cell, RTLI strchr(param.first.c_str(), '.') == NULL) { log_error("Module `%s' referenced in module `%s' in cell `%s' " "does not have a parameter named '%s'.\n", - log_id(cell.type), log_id(&module), log_id(&cell), - log_id(param.first)); + cell.type.unescape(), &module, &cell, + param.first.unescape()); } } } @@ -1036,7 +1036,7 @@ struct HierarchyPass : public Pass { if (top_mod == nullptr) for (auto mod : design->modules()) if (mod->get_bool_attribute(ID::top)) { - log("Attribute `top' found on module `%s'. Setting top module to %s.\n", log_id(mod), log_id(mod)); + log("Attribute `top' found on module `%s'. Setting top module to %s.\n", mod, mod); top_mod = mod; } @@ -1057,12 +1057,12 @@ struct HierarchyPass : public Pass { dict db; for (Module *mod : design->selected_modules()) { int score = find_top_mod_score(design, mod, db); - log("root of %3d design levels: %-20s\n", score, log_id(mod)); + log("root of %3d design levels: %-20s\n", score, mod); if (!top_mod || score > db[top_mod]) top_mod = mod; } if (top_mod != nullptr) - log("Automatically selected %s as design top module.\n", log_id(top_mod)); + log("Automatically selected %s as design top module.\n", top_mod); } if (top_mod != nullptr && top_mod->name.begins_with("$abstract")) { @@ -1162,7 +1162,7 @@ struct HierarchyPass : public Pass { std::map cache; for (auto mod : design->modules()) if (set_keep_print(cache, mod)) { - log("Module %s directly or indirectly displays text -> setting \"keep\" attribute.\n", log_id(mod)); + log("Module %s directly or indirectly displays text -> setting \"keep\" attribute.\n", mod); mod->set_bool_attribute(ID::keep); } } @@ -1171,7 +1171,7 @@ struct HierarchyPass : public Pass { std::map cache; for (auto mod : design->modules()) if (set_keep_assert(cache, mod)) { - log("Module %s directly or indirectly contains formal properties -> setting \"keep\" attribute.\n", log_id(mod)); + log("Module %s directly or indirectly contains formal properties -> setting \"keep\" attribute.\n", mod); mod->set_bool_attribute(ID::keep); } } @@ -1190,7 +1190,7 @@ struct HierarchyPass : public Pass { src += ": "; log_error("%sProperty `%s' in module `%s' uses unsupported SVA constructs. See frontend warnings for details, run `chformal -remove a:unsupported_sva' to ignore.\n", - src, log_id(cell->name), log_id(mod->name)); + src, cell->name.unescape(), mod->name.unescape()); } } } @@ -1499,7 +1499,7 @@ struct HierarchyPass : public Pass { bool resize_widths = !keep_portwidths && GetSize(w) != GetSize(conn.second); if (resize_widths && verific_mod && boxed_params) log_debug("Ignoring width mismatch on %s.%s.%s from verific, is port width parametrizable?\n", - log_id(module), log_id(cell), log_id(conn.first) + module, cell, conn.first.unescape() ); else if (resize_widths) { if (GetSize(w) < GetSize(conn.second)) @@ -1523,14 +1523,14 @@ struct HierarchyPass : public Pass { } if (!conn.second.is_fully_const() || !w->port_input || w->port_output) - log_warning("Resizing cell port %s.%s.%s from %d bits to %d bits.\n", log_id(module), log_id(cell), - log_id(conn.first), GetSize(conn.second), GetSize(sig)); + log_warning("Resizing cell port %s.%s.%s from %d bits to %d bits.\n", module, cell, + conn.first.unescape(), GetSize(conn.second), GetSize(sig)); cell->setPort(conn.first, sig); } if (w->port_output && !w->port_input && sig.has_const()) log_error("Output port %s.%s.%s (%s) is connected to constants: %s\n", - log_id(module), log_id(cell), log_id(conn.first), log_id(cell->type), log_signal(sig)); + module, cell, conn.first.unescape(), cell->type.unescape(), log_signal(sig)); } } } diff --git a/passes/hierarchy/keep_hierarchy.cc b/passes/hierarchy/keep_hierarchy.cc index 9d77b5239..aa3ac72e3 100644 --- a/passes/hierarchy/keep_hierarchy.cc +++ b/passes/hierarchy/keep_hierarchy.cc @@ -42,7 +42,7 @@ struct ThresholdHierarchyKeeping { return 0; if (module->get_blackbox_attribute()) - log_error("Missing cost information on instanced blackbox %s\n", log_id(module)); + log_error("Missing cost information on instanced blackbox %s\n", module); if (done.count(module)) return done.at(module); @@ -61,13 +61,13 @@ struct ThresholdHierarchyKeeping { RTLIL::Module *submodule = design->module(cell->type); if (!submodule) log_error("Hierarchy contains unknown module '%s' (instanced as %s in %s)\n", - log_id(cell->type), log_id(cell), log_id(module)); + cell->type.unescape(), cell, module); size += visit(submodule); } } if (size > threshold) { - log("Keeping %s (estimated size above threshold: %" PRIu64 " > %" PRIu64 ").\n", log_id(module), size, threshold); + log("Keeping %s (estimated size above threshold: %" PRIu64 " > %" PRIu64 ").\n", module, size, threshold); module->set_bool_attribute(ID::keep_hierarchy); size = 0; } @@ -124,7 +124,7 @@ struct KeepHierarchyPass : public Pass { worker.visit(top); } else { for (auto module : design->selected_modules()) { - log("Marking %s.\n", log_id(module)); + log("Marking %s.\n", module); module->set_bool_attribute(ID::keep_hierarchy); } } diff --git a/passes/hierarchy/uniquify.cc b/passes/hierarchy/uniquify.cc index 49b59c8df..941f4dce8 100644 --- a/passes/hierarchy/uniquify.cc +++ b/passes/hierarchy/uniquify.cc @@ -71,7 +71,7 @@ struct UniquifyPass : public Pass { for (auto cell : module->selected_cells()) { Module *tmod = design->module(cell->type); - IdString newname = module->name.str() + "." + log_id(cell->name); + IdString newname = module->name.str() + "." + cell->name.unescape(); if (tmod == nullptr) continue; @@ -82,14 +82,14 @@ struct UniquifyPass : public Pass { if (tmod->get_bool_attribute(ID::unique) && newname == tmod->name) continue; - log("Creating module %s from %s.\n", log_id(newname), log_id(tmod)); + log("Creating module %s from %s.\n", newname.unescape(), tmod); auto smod = tmod->clone(); smod->name = newname; cell->type = newname; smod->set_bool_attribute(ID::unique); if (smod->attributes.count(ID::hdlname) == 0) - smod->attributes[ID::hdlname] = string(log_id(tmod->name)); + smod->attributes[ID::hdlname] = string(tmod->name.unescape()); design->add(smod); did_something = true; diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index 10301b44a..833aa634b 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -44,7 +44,7 @@ struct rules_t void dump_config() const { - log(" bram %s # variant %d\n", log_id(name), variant); + log(" bram %s # variant %d\n", name.unescape(), variant); log(" init %d\n", init); log(" abits %d\n", abits); log(" dbits %d\n", dbits); @@ -61,16 +61,16 @@ struct rules_t void check_vectors() const { - if (groups != GetSize(ports)) log_error("Bram %s variant %d has %d groups but only %d entries in 'ports'.\n", log_id(name), variant, groups, GetSize(ports)); - if (groups != GetSize(wrmode)) log_error("Bram %s variant %d has %d groups but only %d entries in 'wrmode'.\n", log_id(name), variant, groups, GetSize(wrmode)); - if (groups != GetSize(enable)) log_error("Bram %s variant %d has %d groups but only %d entries in 'enable'.\n", log_id(name), variant, groups, GetSize(enable)); - if (groups != GetSize(transp)) log_error("Bram %s variant %d has %d groups but only %d entries in 'transp'.\n", log_id(name), variant, groups, GetSize(transp)); - if (groups != GetSize(clocks)) log_error("Bram %s variant %d has %d groups but only %d entries in 'clocks'.\n", log_id(name), variant, groups, GetSize(clocks)); - if (groups != GetSize(clkpol)) log_error("Bram %s variant %d has %d groups but only %d entries in 'clkpol'.\n", log_id(name), variant, groups, GetSize(clkpol)); + if (groups != GetSize(ports)) log_error("Bram %s variant %d has %d groups but only %d entries in 'ports'.\n", name.unescape(), variant, groups, GetSize(ports)); + if (groups != GetSize(wrmode)) log_error("Bram %s variant %d has %d groups but only %d entries in 'wrmode'.\n", name.unescape(), variant, groups, GetSize(wrmode)); + if (groups != GetSize(enable)) log_error("Bram %s variant %d has %d groups but only %d entries in 'enable'.\n", name.unescape(), variant, groups, GetSize(enable)); + if (groups != GetSize(transp)) log_error("Bram %s variant %d has %d groups but only %d entries in 'transp'.\n", name.unescape(), variant, groups, GetSize(transp)); + if (groups != GetSize(clocks)) log_error("Bram %s variant %d has %d groups but only %d entries in 'clocks'.\n", name.unescape(), variant, groups, GetSize(clocks)); + if (groups != GetSize(clkpol)) log_error("Bram %s variant %d has %d groups but only %d entries in 'clkpol'.\n", name.unescape(), variant, groups, GetSize(clkpol)); int group = 0; for (auto e : enable) - if (e > dbits) log_error("Bram %s variant %d group %d has %d enable bits but only %d dbits.\n", log_id(name), variant, group, e, dbits); + if (e > dbits) log_error("Bram %s variant %d group %d has %d enable bits but only %d dbits.\n", name.unescape(), variant, group, e, dbits); } vector make_portinfos() const @@ -100,7 +100,7 @@ struct rules_t log_assert(name == other.name); if (groups != other.groups) - log_error("Bram %s variants %d and %d have different values for 'groups'.\n", log_id(name), variant, other.variant); + log_error("Bram %s variants %d and %d have different values for 'groups'.\n", name.unescape(), variant, other.variant); if (abits != other.abits) variant_params[ID::CFG_ABITS] = abits; @@ -112,7 +112,7 @@ struct rules_t for (int i = 0; i < groups; i++) { if (ports[i] != other.ports[i]) - log_error("Bram %s variants %d and %d have different number of %c-ports.\n", log_id(name), variant, other.variant, 'A'+i); + log_error("Bram %s variants %d and %d have different number of %c-ports.\n", name.unescape(), variant, other.variant, 'A'+i); if (wrmode[i] != other.wrmode[i]) variant_params[stringf("\\CFG_WRMODE_%c", 'A' + i)] = wrmode[i]; if (enable[i] != other.enable[i]) @@ -428,7 +428,7 @@ bool replace_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals, const transp_max = max(transp_max, pi.transp); } - log(" Mapping to bram type %s (variant %d):\n", log_id(bram.name), bram.variant); + log(" Mapping to bram type %s (variant %d):\n", bram.name.unescape(), bram.variant); // bram.dump_config(); std::vector shuffle_map; @@ -715,21 +715,21 @@ grow_read_ports:; for (auto it : match.min_limits) { if (!match_properties.count(it.first)) log_error("Unknown property '%s' in match rule for bram type %s.\n", - it.first.c_str(), log_id(match.name)); + it.first.c_str(), match.name.unescape()); if (match_properties[it.first] >= it.second) continue; log(" Rule for bram type %s rejected: requirement 'min %s %d' not met.\n", - log_id(match.name), it.first.c_str(), it.second); + match.name.unescape(), it.first.c_str(), it.second); return false; } for (auto it : match.max_limits) { if (!match_properties.count(it.first)) log_error("Unknown property '%s' in match rule for bram type %s.\n", - it.first.c_str(), log_id(match.name)); + it.first.c_str(), match.name.unescape()); if (match_properties[it.first] <= it.second) continue; log(" Rule for bram type %s rejected: requirement 'max %s %d' not met.\n", - log_id(match.name), it.first.c_str(), it.second); + match.name.unescape(), it.first.c_str(), it.second); return false; } @@ -759,13 +759,13 @@ grow_read_ports:; if (!exists) ss << "!"; IdString key = std::get<1>(sums.front()); - ss << log_id(key); + ss << key.unescape(); const Const &value = rules.map_case(std::get<2>(sums.front())); if (exists && value != Const(1)) ss << "=\"" << value.decode_string() << "\""; log(" Rule for bram type %s rejected: requirement 'attribute %s ...' not met.\n", - log_id(match.name), ss.str().c_str()); + match.name.unescape(), ss.str().c_str()); return false; } } @@ -874,7 +874,7 @@ grow_read_ports:; for (int dupidx = 0; dupidx < dup_count; dupidx++) { Cell *c = module->addCell(module->uniquify(stringf("%s.%d.%d.%d", mem.memid, grid_d, grid_a, dupidx)), bram.name); - log(" Creating %s cell at grid position <%d %d %d>: %s\n", log_id(bram.name), grid_d, grid_a, dupidx, log_id(c)); + log(" Creating %s cell at grid position <%d %d %d>: %s\n", bram.name.unescape(), grid_d, grid_a, dupidx, c); for (auto &vp : variant_params) c->setParam(vp.first, vp.second); @@ -1004,7 +1004,7 @@ grow_read_ports:; void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals) { - log("Processing %s.%s:\n", log_id(mem.module), log_id(mem.memid)); + log("Processing %s.%s:\n", mem.module, mem.memid.unescape()); mem.narrow(); bool cell_init = !mem.inits.empty(); @@ -1031,7 +1031,7 @@ void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals) auto &match = rules.matches.at(i); if (!rules.brams.count(rules.matches[i].name)) - log_error("No bram description for resource %s found!\n", log_id(rules.matches[i].name)); + log_error("No bram description for resource %s found!\n", rules.matches[i].name.unescape()); for (int vi = 0; vi < GetSize(rules.brams.at(match.name)); vi++) { @@ -1047,7 +1047,7 @@ void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals) avail_wr_ports += GetSize(bram.ports) < j ? bram.ports.at(j) : 0; } - log(" Checking rule #%d for bram type %s (variant %d):\n", i+1, log_id(bram.name), bram.variant); + log(" Checking rule #%d for bram type %s (variant %d):\n", i+1, bram.name.unescape(), bram.variant); log(" Bram geometry: abits=%d dbits=%d wports=%d rports=%d\n", bram.abits, bram.dbits, avail_wr_ports, avail_rd_ports); int dups = avail_rd_ports ? (match_properties["rports"] + avail_rd_ports - 1) / avail_rd_ports : 1; @@ -1077,11 +1077,11 @@ void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals) goto next_match_rule; log(" Metrics for %s: awaste=%d dwaste=%d bwaste=%d waste=%d efficiency=%d\n", - log_id(match.name), awaste, dwaste, bwaste, waste, efficiency); + match.name.unescape(), awaste, dwaste, bwaste, waste, efficiency); if (cell_init && bram.init == 0) { log(" Rule #%d for bram type %s (variant %d) rejected: cannot be initialized.\n", - i+1, log_id(bram.name), bram.variant); + i+1, bram.name.unescape(), bram.variant); goto next_match_rule; } @@ -1090,11 +1090,11 @@ void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals) continue; if (!match_properties.count(it.first)) log_error("Unknown property '%s' in match rule for bram type %s.\n", - it.first.c_str(), log_id(match.name)); + it.first.c_str(), match.name.unescape()); if (match_properties[it.first] >= it.second) continue; log(" Rule #%d for bram type %s (variant %d) rejected: requirement 'min %s %d' not met.\n", - i+1, log_id(bram.name), bram.variant, it.first.c_str(), it.second); + i+1, bram.name.unescape(), bram.variant, it.first.c_str(), it.second); goto next_match_rule; } @@ -1103,11 +1103,11 @@ void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals) continue; if (!match_properties.count(it.first)) log_error("Unknown property '%s' in match rule for bram type %s.\n", - it.first.c_str(), log_id(match.name)); + it.first.c_str(), match.name.unescape()); if (match_properties[it.first] <= it.second) continue; log(" Rule #%d for bram type %s (variant %d) rejected: requirement 'max %s %d' not met.\n", - i+1, log_id(bram.name), bram.variant, it.first.c_str(), it.second); + i+1, bram.name.unescape(), bram.variant, it.first.c_str(), it.second); goto next_match_rule; } @@ -1137,18 +1137,18 @@ void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals) if (!exists) ss << "!"; IdString key = std::get<1>(sums.front()); - ss << log_id(key); + ss << key.unescape(); const Const &value = rules.map_case(std::get<2>(sums.front())); if (exists && value != Const(1)) ss << "=\"" << value.decode_string() << "\""; log(" Rule for bram type %s (variant %d) rejected: requirement 'attribute %s ...' not met.\n", - log_id(bram.name), bram.variant, ss.str().c_str()); + bram.name.unescape(), bram.variant, ss.str().c_str()); goto next_match_rule; } } - log(" Rule #%d for bram type %s (variant %d) accepted.\n", i+1, log_id(bram.name), bram.variant); + log(" Rule #%d for bram type %s (variant %d) accepted.\n", i+1, bram.name.unescape(), bram.variant); if (or_next_if_better || !best_rule_cache.empty()) { @@ -1156,7 +1156,7 @@ void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals) log_error("Found 'or_next_if_better' in last match rule.\n"); if (!replace_memory(mem, rules, initvals, bram, match, match_properties, 1)) { - log(" Mapping to bram type %s failed.\n", log_id(match.name)); + log(" Mapping to bram type %s failed.\n", match.name.unescape()); failed_brams.insert(pair(bram.name, bram.variant)); goto next_match_rule; } @@ -1183,12 +1183,12 @@ void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals) auto &best_bram = rules.brams.at(rules.matches.at(best_rule.first).name).at(best_rule.second); if (!replace_memory(mem, rules, initvals, best_bram, rules.matches.at(best_rule.first), match_properties, 2)) - log_error("Mapping to bram type %s (variant %d) after pre-selection failed.\n", log_id(best_bram.name), best_bram.variant); + log_error("Mapping to bram type %s (variant %d) after pre-selection failed.\n", best_bram.name.unescape(), best_bram.variant); return; } if (!replace_memory(mem, rules, initvals, bram, match, match_properties, 0)) { - log(" Mapping to bram type %s failed.\n", log_id(match.name)); + log(" Mapping to bram type %s failed.\n", match.name.unescape()); failed_brams.insert(pair(bram.name, bram.variant)); goto next_match_rule; } diff --git a/passes/memory/memory_libmap.cc b/passes/memory/memory_libmap.cc index 87adaa26d..a7be16577 100644 --- a/passes/memory/memory_libmap.cc +++ b/passes/memory/memory_libmap.cc @@ -204,7 +204,7 @@ struct MemMapping { if (!check_init(rdef)) continue; if (rdef.prune_rom && mem.wr_ports.empty()) { - log_debug("memory %s.%s: rejecting mapping to %s: ROM mapping disabled (prune_rom set)\n", log_id(mem.module->name), log_id(mem.memid), log_id(rdef.id)); + log_debug("memory %s.%s: rejecting mapping to %s: ROM mapping disabled (prune_rom set)\n", mem.module->name.unescape(), mem.memid.unescape(), rdef.id.unescape()); continue; } MemConfig cfg; @@ -323,7 +323,7 @@ struct MemMapping { void log_reject(const Ram &ram, std::string message) { if(ys_debug(1)) { - rejected_cfg_debug_msgs += stringf("can't map to to %s: ", log_id(ram.id)); + rejected_cfg_debug_msgs += stringf("can't map to to %s: ", ram.id.unescape()); rejected_cfg_debug_msgs += message; rejected_cfg_debug_msgs += "\n"; } @@ -338,7 +338,7 @@ struct MemMapping { rejected_cfg_debug_msgs += portname; first = false; } - rejected_cfg_debug_msgs += stringf("] of %s: ", log_id(ram.id)); + rejected_cfg_debug_msgs += stringf("] of %s: ", ram.id.unescape()); rejected_cfg_debug_msgs += message; rejected_cfg_debug_msgs += "\n"; } @@ -361,7 +361,7 @@ struct MemMapping { rejected_cfg_debug_msgs += portname; first = false; } - rejected_cfg_debug_msgs += stringf("] of %s: ", log_id(ram.id)); + rejected_cfg_debug_msgs += stringf("] of %s: ", ram.id.unescape()); rejected_cfg_debug_msgs += message; rejected_cfg_debug_msgs += "\n"; } @@ -380,7 +380,7 @@ void MemMapping::dump_configs(int stage) { default: abort(); } - log_debug("Memory %s.%s mapping candidates (%s):\n", log_id(mem.module->name), log_id(mem.memid), stage_name); + log_debug("Memory %s.%s mapping candidates (%s):\n", mem.module->name.unescape(), mem.memid.unescape(), stage_name); if (logic_ok) { log_debug("- logic fallback\n"); log_debug(" - cost: %f\n", logic_cost); @@ -391,7 +391,7 @@ void MemMapping::dump_configs(int stage) { } void MemMapping::dump_config(MemConfig &cfg) { - log_debug("- %s:\n", log_id(cfg.def->id)); + log_debug("- %s:\n", cfg.def->id.unescape()); for (auto &it: cfg.def->options) log_debug(" - option %s %s\n", it.first, log_const(it.second)); log_debug(" - emulation score: %d\n", cfg.score_emu); @@ -527,7 +527,7 @@ void MemMapping::determine_style() { auto find_attr = search_for_attribute(mem, ID::lram); if (find_attr.first && find_attr.second.as_bool()) { kind = RamKind::Huge; - log("found attribute 'lram' on memory %s.%s, forced mapping to huge RAM\n", log_id(mem.module->name), log_id(mem.memid)); + log("found attribute 'lram' on memory %s.%s, forced mapping to huge RAM\n", mem.module->name.unescape(), mem.memid.unescape()); return; } for (auto attr: {ID::ram_block, ID::rom_block, ID::ram_style, ID::rom_style, ID::ramstyle, ID::romstyle, ID::syn_ramstyle, ID::syn_romstyle}) { @@ -536,7 +536,7 @@ void MemMapping::determine_style() { Const val = find_attr.second; if (val == 1) { kind = RamKind::NotLogic; - log("found attribute '%s = 1' on memory %s.%s, disabled mapping to FF\n", log_id(attr), log_id(mem.module->name), log_id(mem.memid)); + log("found attribute '%s = 1' on memory %s.%s, disabled mapping to FF\n", attr.unescape(), mem.module->name.unescape(), mem.memid.unescape()); return; } std::string val_s = val.decode_string(); @@ -549,20 +549,20 @@ void MemMapping::determine_style() { // Nothing. } else if (val_s == "logic" || val_s == "registers") { kind = RamKind::Logic; - log("found attribute '%s = %s' on memory %s.%s, forced mapping to FF\n", log_id(attr), val_s, log_id(mem.module->name), log_id(mem.memid)); + log("found attribute '%s = %s' on memory %s.%s, forced mapping to FF\n", attr.unescape(), val_s, mem.module->name.unescape(), mem.memid.unescape()); } else if (val_s == "distributed") { kind = RamKind::Distributed; - log("found attribute '%s = %s' on memory %s.%s, forced mapping to distributed RAM\n", log_id(attr), val_s, log_id(mem.module->name), log_id(mem.memid)); + log("found attribute '%s = %s' on memory %s.%s, forced mapping to distributed RAM\n", attr.unescape(), val_s, mem.module->name.unescape(), mem.memid.unescape()); } else if (val_s == "block" || val_s == "block_ram" || val_s == "ebr") { kind = RamKind::Block; - log("found attribute '%s = %s' on memory %s.%s, forced mapping to block RAM\n", log_id(attr), val_s, log_id(mem.module->name), log_id(mem.memid)); + log("found attribute '%s = %s' on memory %s.%s, forced mapping to block RAM\n", attr.unescape(), val_s, mem.module->name.unescape(), mem.memid.unescape()); } else if (val_s == "huge" || val_s == "ultra") { kind = RamKind::Huge; - log("found attribute '%s = %s' on memory %s.%s, forced mapping to huge RAM\n", log_id(attr), val_s, log_id(mem.module->name), log_id(mem.memid)); + log("found attribute '%s = %s' on memory %s.%s, forced mapping to huge RAM\n", attr.unescape(), val_s, mem.module->name.unescape(), mem.memid.unescape()); } else { kind = RamKind::NotLogic; style = val_s; - log("found attribute '%s = %s' on memory %s.%s, forced mapping to %s RAM\n", log_id(attr), val_s, log_id(mem.module->name), log_id(mem.memid), val_s); + log("found attribute '%s = %s' on memory %s.%s, forced mapping to %s RAM\n", attr.unescape(), val_s, mem.module->name.unescape(), mem.memid.unescape(), val_s); } return; } @@ -1991,7 +1991,7 @@ void MemMapping::emit_port(const MemConfig &cfg, std::vector &cells, cons } void MemMapping::emit(const MemConfig &cfg) { - log("mapping memory %s.%s via %s\n", log_id(mem.module->name), log_id(mem.memid), log_id(cfg.def->id)); + log("mapping memory %s.%s via %s\n", mem.module->name.unescape(), mem.memid.unescape(), cfg.def->id.unescape()); // First, handle emulations. if (cfg.emu_read_first) mem.emulate_read_first(&worker.initvals); @@ -2252,9 +2252,9 @@ struct MemoryLibMapPass : public Pass { int best = map.logic_cost; if (!map.logic_ok) { if (map.cfgs.empty()) { - log_debug("Rejected candidates for mapping memory %s.%s:\n", log_id(module->name), log_id(mem.memid)); + log_debug("Rejected candidates for mapping memory %s.%s:\n", module->name.unescape(), mem.memid.unescape()); log_debug("%s", map.rejected_cfg_debug_msgs); - log_error("no valid mapping found for memory %s.%s\n", log_id(module->name), log_id(mem.memid)); + log_error("no valid mapping found for memory %s.%s\n", module->name.unescape(), mem.memid.unescape()); } idx = 0; best = map.cfgs[0].cost; @@ -2266,7 +2266,7 @@ struct MemoryLibMapPass : public Pass { } } if (idx == -1) { - log("using FF mapping for memory %s.%s\n", log_id(module->name), log_id(mem.memid)); + log("using FF mapping for memory %s.%s\n", module->name.unescape(), mem.memid.unescape()); } else { map.emit(map.cfgs[idx]); // Rebuild indices after modifying module diff --git a/passes/memory/memory_memx.cc b/passes/memory/memory_memx.cc index 22aebb43f..54c71a0e8 100644 --- a/passes/memory/memory_memx.cc +++ b/passes/memory/memory_memx.cc @@ -60,7 +60,7 @@ struct MemoryMemxPass : public Pass { { if (port.clk_enable) log_error("Memory %s.%s has a synchronous read port. Synchronous read ports are not supported by memory_memx!\n", - log_id(module), log_id(mem.memid)); + module, mem.memid.unescape()); SigSpec addr_ok = make_addr_check(mem, port.addr); Wire *raw_rdata = module->addWire(NEW_ID, GetSize(port.data)); diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index fe884772a..fbe41431a 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -80,7 +80,7 @@ struct MemoryShareWorker if (GetSize(mem.rd_ports) <= 1) return false; - log("Consolidating read ports of memory %s.%s by address:\n", log_id(module), log_id(mem.memid)); + log("Consolidating read ports of memory %s.%s by address:\n", module, mem.memid.unescape()); bool changed = false; int abits = 0; @@ -197,7 +197,7 @@ struct MemoryShareWorker if (GetSize(mem.wr_ports) <= 1) return false; - log("Consolidating write ports of memory %s.%s by address:\n", log_id(module), log_id(mem.memid)); + log("Consolidating write ports of memory %s.%s by address:\n", module, mem.memid.unescape()); bool changed = false; int abits = 0; @@ -316,7 +316,7 @@ struct MemoryShareWorker if (eligible_ports.size() <= 1) return; - log("Consolidating write ports of memory %s.%s using sat-based resource sharing:\n", log_id(module), log_id(mem.memid)); + log("Consolidating write ports of memory %s.%s using sat-based resource sharing:\n", module, mem.memid.unescape()); // Group eligible ports by clock domain and width. diff --git a/passes/opt/muxpack.cc b/passes/opt/muxpack.cc index ac47f6bf7..e737cd498 100644 --- a/passes/opt/muxpack.cc +++ b/passes/opt/muxpack.cc @@ -193,7 +193,7 @@ struct MuxpackWorker { for (auto cell : candidate_cells) { - log_debug("Considering %s (%s)\n", log_id(cell), log_id(cell->type)); + log_debug("Considering %s (%s)\n", cell, cell->type.unescape()); SigSpec a_sig = sigmap(cell->getPort(ID::A)); if (cell->type == ID($mux)) { @@ -273,7 +273,7 @@ struct MuxpackWorker Cell *last_cell = chain[cursor+cases-1]; log("Converting %s.%s ... %s.%s to a pmux with %d cases.\n", - log_id(module), log_id(first_cell), log_id(module), log_id(last_cell), cases); + module, first_cell, module, last_cell, cases); mux_count += cases; pmux_count += 1; diff --git a/passes/opt/opt_balance_tree.cc b/passes/opt/opt_balance_tree.cc index 129a27376..98d5b9928 100644 --- a/passes/opt/opt_balance_tree.cc +++ b/passes/opt/opt_balance_tree.cc @@ -279,7 +279,7 @@ struct OptBalanceTreeWorker { if (inner_cells) { // Create a tree - log_debug(" Creating tree for %s with %d sources and %d inner cells...\n", log_id(head_cell), GetSize(sources), inner_cells); + log_debug(" Creating tree for %s with %d sources and %d inner cells...\n", head_cell, GetSize(sources), inner_cells); // Build a vector of all source signals vector source_signals; @@ -369,7 +369,7 @@ struct OptBalanceTreePass : public Pass { // Log stats for (auto cell_type : cell_types) - log("Converted %d %s cells into trees.\n", cell_count[cell_type], log_id(cell_type)); + log("Converted %d %s cells into trees.\n", cell_count[cell_type], cell_type.unescape()); // Clean up Yosys::run_pass("clean -purge"); diff --git a/passes/opt/opt_clean/inits.cc b/passes/opt/opt_clean/inits.cc index 70c2ef9e2..0618e739a 100644 --- a/passes/opt/opt_clean/inits.cc +++ b/passes/opt/opt_clean/inits.cc @@ -109,7 +109,7 @@ bool remove_redundant_inits(ShardedVector wires, bool verbose) { bool did_something = false; for (RTLIL::Wire *wire : wires) { if (verbose) - log_debug(" removing redundant init attribute on %s.\n", log_id(wire)); + log_debug(" removing redundant init attribute on %s.\n", wire); wire->attributes.erase(ID::init); did_something = true; } diff --git a/passes/opt/opt_demorgan.cc b/passes/opt/opt_demorgan.cc index 1a2c1fe82..b9aab1850 100644 --- a/passes/opt/opt_demorgan.cc +++ b/passes/opt/opt_demorgan.cc @@ -43,7 +43,7 @@ void demorgan_worker( if (GetSize(insig) < 1) return; - log("Inspecting %s cell %s (%d inputs)\n", log_id(cell->type), log_id(cell->name), GetSize(insig)); + log("Inspecting %s cell %s (%d inputs)\n", cell->type.unescape(), cell->name.unescape(), GetSize(insig)); int num_inverted = 0; for(int i=0; iconnect(ff.sig_q[i], State::S0); log("Handling always-active CLR at position %d on %s (%s) from module %s (changing to const driver).\n", - i, log_id(cell), log_id(cell->type), log_id(module)); + i, cell, cell->type.unescape(), module); sr_removed = true; } else if (is_always_active(ff.sig_set[i], ff.pol_set)) { initvals.remove_init(ff.sig_q[i]); @@ -312,7 +312,7 @@ struct OptDffWorker else module->addNot(NEW_ID, ff.sig_clr[i], ff.sig_q[i]); log("Handling always-active SET at position %d on %s (%s) from module %s (changing to combinatorial circuit).\n", - i, log_id(cell), log_id(cell->type), log_id(module)); + i, cell, cell->type.unescape(), module); sr_removed = true; } else { keep_bits.push_back(i); @@ -335,7 +335,7 @@ struct OptDffWorker if (clr_inactive && signal_all_same(ff.sig_set)) { log("Removing never-active CLR on %s (%s) from module %s.\n", - log_id(cell), log_id(cell->type), log_id(module)); + cell, cell->type.unescape(), module); ff.has_sr = false; ff.has_arst = true; ff.pol_arst = ff.pol_set; @@ -344,7 +344,7 @@ struct OptDffWorker changed = true; } else if (set_inactive && signal_all_same(ff.sig_clr)) { log("Removing never-active SET on %s (%s) from module %s.\n", - log_id(cell), log_id(cell->type), log_id(module)); + cell, cell->type.unescape(), module); ff.has_sr = false; ff.has_arst = true; ff.pol_arst = ff.pol_clr; @@ -370,7 +370,7 @@ struct OptDffWorker if (!failed) { log("Converting CLR/SET to ARST on %s (%s) from module %s.\n", - log_id(cell), log_id(cell->type), log_id(module)); + cell, cell->type.unescape(), module); ff.has_sr = false; ff.has_arst = true; ff.val_arst = val_arst_builder.build(); @@ -389,7 +389,7 @@ struct OptDffWorker // Converts constant Async Load to ARST if (is_always_inactive(ff.sig_aload, ff.pol_aload)) { log("Removing never-active async load on %s (%s) from module %s.\n", - log_id(cell), log_id(cell->type), log_id(module)); + cell, cell->type.unescape(), module); ff.has_aload = false; changed = true; return false; @@ -398,7 +398,7 @@ struct OptDffWorker if (is_active(ff.sig_aload, ff.pol_aload)) { // ALOAD always active log("Handling always-active async load on %s (%s) from module %s (changing to combinatorial circuit).\n", - log_id(cell), log_id(cell->type), log_id(module)); + cell, cell->type.unescape(), module); ff.remove(); if (ff.has_sr) { @@ -433,7 +433,7 @@ struct OptDffWorker // AD is constant -> ARST if (ff.sig_ad.is_fully_const() && !ff.has_arst && !ff.has_sr) { log("Changing const-value async load to async reset on %s (%s) from module %s.\n", - log_id(cell), log_id(cell->type), log_id(module)); + cell, cell->type.unescape(), module); ff.has_arst = true; ff.has_aload = false; ff.sig_arst = ff.sig_aload; @@ -450,12 +450,12 @@ struct OptDffWorker // Removes ARST if never active or replaces FF if always active if (is_inactive(ff.sig_arst, ff.pol_arst)) { log("Removing never-active ARST on %s (%s) from module %s.\n", - log_id(cell), log_id(cell->type), log_id(module)); + cell, cell->type.unescape(), module); ff.has_arst = false; changed = true; } else if (is_always_active(ff.sig_arst, ff.pol_arst)) { log("Handling always-active ARST on %s (%s) from module %s (changing to const driver).\n", - log_id(cell), log_id(cell->type), log_id(module)); + cell, cell->type.unescape(), module); ff.remove(); module->connect(ff.sig_q, ff.val_arst); return true; @@ -469,12 +469,12 @@ struct OptDffWorker // Removes SRST if never active or forces D to reset value if always active if (is_inactive(ff.sig_srst, ff.pol_srst)) { log("Removing never-active SRST on %s (%s) from module %s.\n", - log_id(cell), log_id(cell->type), log_id(module)); + cell, cell->type.unescape(), module); ff.has_srst = false; changed = true; } else if (is_always_active(ff.sig_srst, ff.pol_srst)) { log("Handling always-active SRST on %s (%s) from module %s (changing to const D).\n", - log_id(cell), log_id(cell->type), log_id(module)); + cell, cell->type.unescape(), module); ff.has_srst = false; if (!ff.ce_over_srst) ff.has_ce = false; @@ -489,7 +489,7 @@ struct OptDffWorker if (is_always_inactive(ff.sig_ce, ff.pol_ce)) { if (ff.has_srst && !ff.ce_over_srst) { log("Handling never-active EN on %s (%s) from module %s (connecting SRST instead).\n", - log_id(cell), log_id(cell->type), log_id(module)); + cell, cell->type.unescape(), module); ff.pol_ce = ff.pol_srst; ff.sig_ce = ff.sig_srst; ff.has_srst = false; @@ -497,7 +497,7 @@ struct OptDffWorker changed = true; } else if (!opt.keepdc || ff.val_init.is_fully_def()) { log("Handling never-active EN on %s (%s) from module %s (removing D path).\n", - log_id(cell), log_id(cell->type), log_id(module)); + cell, cell->type.unescape(), module); ff.has_ce = ff.has_clk = ff.has_srst = false; changed = true; } else { @@ -507,7 +507,7 @@ struct OptDffWorker } } else if (is_active(ff.sig_ce, ff.pol_ce)) { log("Removing always-active EN on %s (%s) from module %s.\n", - log_id(cell), log_id(cell->type), log_id(module)); + cell, cell->type.unescape(), module); ff.has_ce = false; changed = true; } @@ -517,7 +517,7 @@ struct OptDffWorker { if (!opt.keepdc || ff.val_init.is_fully_def()) { log("Handling const CLK on %s (%s) from module %s (removing D path).\n", - log_id(cell), log_id(cell->type), log_id(module)); + cell, cell->type.unescape(), module); ff.has_ce = ff.has_clk = ff.has_srst = false; changed = true; } else if (ff.has_ce || ff.has_srst || ff.sig_d != ff.sig_q) { @@ -532,7 +532,7 @@ struct OptDffWorker // Detect feedback loops where D is hardwired to Q if (ff.has_clk && ff.has_srst) { log("Handling D = Q on %s (%s) from module %s (conecting SRST instead).\n", - log_id(cell), log_id(cell->type), log_id(module)); + cell, cell->type.unescape(), module); if (ff.has_ce && ff.ce_over_srst) { SigSpec ce = ff.pol_ce ? ff.sig_ce : create_not(ff.sig_ce, ff.is_fine); SigSpec srst = ff.pol_srst ? ff.sig_srst : create_not(ff.sig_srst, ff.is_fine); @@ -549,7 +549,7 @@ struct OptDffWorker changed = true; } else if (!opt.keepdc || ff.val_init.is_fully_def()) { log("Handling D = Q on %s (%s) from module %s (removing D path).\n", - log_id(cell), log_id(cell->type), log_id(module)); + cell, cell->type.unescape(), module); ff.has_gclk = ff.has_clk = ff.has_ce = false; changed = true; } @@ -627,7 +627,7 @@ struct OptDffWorker dff_cells.push_back(new_cell); log("Adding SRST signal on %s (%s) from module %s (D = %s, Q = %s, rval = %s).\n", - log_id(cell), log_id(cell->type), log_id(module), + cell, cell->type.unescape(), module, log_signal(new_ff.sig_d), log_signal(new_ff.sig_q), log_signal(new_ff.val_srst)); } @@ -701,7 +701,7 @@ struct OptDffWorker dff_cells.push_back(new_cell); log("Adding EN signal on %s (%s) from module %s (D = %s, Q = %s).\n", - log_id(cell), log_id(cell->type), log_id(module), + cell, cell->type.unescape(), module, log_signal(new_ff.sig_d), log_signal(new_ff.sig_q)); } @@ -768,7 +768,7 @@ struct OptDffWorker if (ff.has_aload && !ff.has_clk && ff.sig_ad == ff.sig_q) { log("Handling AD = Q on %s (%s) from module %s (removing async load path).\n", - log_id(cell), log_id(cell->type), log_id(module)); + cell, cell->type.unescape(), module); ff.has_aload = false; changed = true; } @@ -885,7 +885,7 @@ struct OptDffWorker } log("Setting constant %d-bit at position %d on %s (%s) from module %s.\n", - val ? 1 : 0, i, log_id(cell), log_id(cell->type), log_id(module)); + val ? 1 : 0, i, cell, cell->type.unescape(), module); // Replace the Q output with the constant value initvals.remove_init(ff.sig_q[i]); diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 2c040b09d..48a9aa1da 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -88,7 +88,7 @@ void replace_undriven(RTLIL::Module *module, const NewCellTypes &ct) } } - log_debug("Setting undriven signal in %s to constant: %s = %s\n", log_id(module), log_signal(sig), log_signal(val)); + log_debug("Setting undriven signal in %s to constant: %s = %s\n", module, log_signal(sig), log_signal(val)); module->connect(sig, val); did_something = true; } @@ -105,11 +105,11 @@ void replace_undriven(RTLIL::Module *module, const NewCellTypes &ct) initval.set(i, State::Sx); } if (initval.is_fully_undef()) { - log_debug("Removing init attribute from %s/%s.\n", log_id(module), log_id(wire)); + log_debug("Removing init attribute from %s/%s.\n", module, wire); wire->attributes.erase(ID::init); did_something = true; } else if (initval != wire->attributes.at(ID::init)) { - log_debug("Updating init attribute on %s/%s: %s\n", log_id(module), log_id(wire), log_signal(initval)); + log_debug("Updating init attribute on %s/%s: %s\n", module, wire, log_signal(initval)); wire->attributes[ID::init] = initval; did_something = true; } @@ -196,7 +196,7 @@ bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool commutativ return false; log_debug("Replacing %s cell `%s' in module `%s' with cells using grouped bits:\n", - log_id(cell->type), log_id(cell), log_id(module)); + cell->type.unescape(), cell, module); for (int i = 0; i < GRP_N; i++) { @@ -224,7 +224,7 @@ bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool commutativ new_a.replace(dict{{State::Sx, State::S1}, {State::Sz, State::S1}}, &new_b); else log_abort(); } - log_debug(" Direct Connection: %s (%s with %s)\n", log_signal(new_b), log_id(cell->type), log_signal(new_a)); + log_debug(" Direct Connection: %s (%s with %s)\n", log_signal(new_b), cell->type.unescape(), log_signal(new_a)); module->connect(new_y, new_b); module->connect(new_conn); continue; @@ -261,7 +261,7 @@ bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool commutativ } } if (!undef_y.empty()) { - log_debug(" Direct Connection: %s (%s with %s)\n", log_signal(undef_b), log_id(cell->type), log_signal(undef_a)); + log_debug(" Direct Connection: %s (%s with %s)\n", log_signal(undef_b), cell->type.unescape(), log_signal(undef_a)); module->connect(undef_y, undef_b); if (def_y.empty()) { module->connect(new_conn); @@ -292,7 +292,7 @@ bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool commutativ module->connect(new_conn); - log_debug(" New cell `%s': A=%s", log_id(c), log_signal(new_a)); + log_debug(" New cell `%s': A=%s", c, log_signal(new_a)); if (b_name == ID::B) log_debug(", B=%s", log_signal(new_b)); log_debug("\n"); @@ -308,7 +308,7 @@ void handle_polarity_inv(Cell *cell, IdString port, IdString param, const SigMap SigSpec sig = assign_map(cell->getPort(port)); if (invert_map.count(sig)) { log_debug("Inverting %s of %s cell `%s' in module `%s': %s -> %s\n", - log_id(port), log_id(cell->type), log_id(cell), log_id(cell->module), + port.unescape(), cell->type.unescape(), cell, cell->module, log_signal(sig), log_signal(invert_map.at(sig))); cell->setPort(port, (invert_map.at(sig))); cell->setParam(param, !cell->getParam(param).as_bool()); @@ -337,7 +337,7 @@ void handle_clkpol_celltype_swap(Cell *cell, string type1, string type2, IdStrin SigSpec sig = assign_map(cell->getPort(port)); if (invert_map.count(sig)) { log_debug("Inverting %s of %s cell `%s' in module `%s': %s -> %s\n", - log_id(port), log_id(cell->type), log_id(cell), log_id(cell->module), + port.unescape(), cell->type.unescape(), cell, cell->module, log_signal(sig), log_signal(invert_map.at(sig))); cell->setPort(port, (invert_map.at(sig))); cell->type = cell->type == type1 ? type2 : type1; @@ -511,7 +511,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (!cells.sort()) { // There might be a combinational loop, or there might be constants on the output of cells. 'check' may find out more. // ...unless this is a coarse-grained cell loop, but not a bit loop, in which case it won't, and all is good. - log("Couldn't topologically sort cells, optimizing module %s may take a longer time.\n", log_id(module)); + log("Couldn't topologically sort cells, optimizing module %s may take a longer time.\n", module); } for (auto cell : cells.sorted) @@ -631,7 +631,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons { if (cell->type == ID($reduce_xnor)) { log_debug("Replacing %s cell `%s' in module `%s' with $not cell.\n", - log_id(cell->type), log_id(cell->name), log_id(module)); + cell->type.unescape(), cell->name.unescape(), module); cell->type = ID($not); did_something = true; } else { @@ -651,7 +651,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (a_fully_const != b_fully_const) { log_debug("Replacing %s cell `%s' in module `%s' having one fully constant input\n", - log_id(cell->type), log_id(cell->name), log_id(module)); + cell->type.unescape(), cell->name.unescape(), module); RTLIL::SigSpec sig_y = assign_map(cell->getPort(ID::Y)); int width = GetSize(cell->getPort(ID::Y)); @@ -932,7 +932,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons break; } if (i > 0) { - log_debug("Stripping %d LSB bits of %s cell %s in module %s.\n", i, log_id(cell->type), log_id(cell), log_id(module)); + log_debug("Stripping %d LSB bits of %s cell %s in module %s.\n", i, cell->type.unescape(), cell, module); SigSpec new_a = sig_a.extract_end(i); SigSpec new_b = sig_b.extract_end(i); if (new_a.empty() && is_signed) @@ -988,7 +988,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons break; } if (i > 0) { - log_debug("Stripping %d LSB bits of %s cell %s in module %s.\n", i, log_id(cell->type), log_id(cell), log_id(module)); + log_debug("Stripping %d LSB bits of %s cell %s in module %s.\n", i, cell->type.unescape(), cell, module); SigSpec new_a = sig_a.extract_end(i); SigSpec new_b = sig_b.extract_end(i); if (new_a.empty() && is_signed) @@ -1062,7 +1062,7 @@ skip_fine_alu: } if (cell->type.in(ID($_MUX_), ID($mux)) && invert_map.count(assign_map(cell->getPort(ID::S))) != 0) { - log_debug("Optimizing away select inverter for %s cell `%s' in module `%s'.\n", log_id(cell->type), log_id(cell), log_id(module)); + log_debug("Optimizing away select inverter for %s cell `%s' in module `%s'.\n", cell->type.unescape(), cell, module); RTLIL::SigSpec tmp = cell->getPort(ID::A); cell->setPort(ID::A, cell->getPort(ID::B)); cell->setPort(ID::B, tmp); @@ -1241,7 +1241,7 @@ skip_fine_alu: RTLIL::SigSpec input = b; ACTION_DO(ID::Y, cell->getPort(ID::A)); } else { - log_debug("Replacing %s cell `%s' in module `%s' with inverter.\n", log_id(cell->type), log_id(cell), log_id(module)); + log_debug("Replacing %s cell `%s' in module `%s' with inverter.\n", cell->type.unescape(), cell, module); cell->type = ID($not); cell->parameters.erase(ID::B_WIDTH); cell->parameters.erase(ID::B_SIGNED); @@ -1255,8 +1255,8 @@ skip_fine_alu: if (cell->type.in(ID($eq), ID($ne)) && (assign_map(cell->getPort(ID::A)).is_fully_zero() || assign_map(cell->getPort(ID::B)).is_fully_zero())) { - log_debug("Replacing %s cell `%s' in module `%s' with %s.\n", log_id(cell->type), log_id(cell), - log_id(module), cell->type == ID($eq) ? "$logic_not" : "$reduce_bool"); + log_debug("Replacing %s cell `%s' in module `%s' with %s.\n", cell->type.unescape(), cell, + module, cell->type == ID($eq) ? "$logic_not" : "$reduce_bool"); cell->type = cell->type == ID($eq) ? ID($logic_not) : ID($reduce_bool); if (assign_map(cell->getPort(ID::A)).is_fully_zero()) { cell->setPort(ID::A, cell->getPort(ID::B)); @@ -1303,7 +1303,7 @@ skip_fine_alu: } log_debug("Replacing %s cell `%s' (B=%s, SHR=%d) in module `%s' with fixed wiring: %s\n", - log_id(cell->type), log_id(cell), log_signal(assign_map(cell->getPort(ID::B))), shift_bits, log_id(module), log_signal(sig_y)); + cell->type.unescape(), cell, log_signal(assign_map(cell->getPort(ID::B))), shift_bits, module, log_signal(sig_y)); module->connect(cell->getPort(ID::Y), sig_y); module->remove(cell); @@ -1428,7 +1428,7 @@ skip_identity: if (mux_bool && cell->type.in(ID($mux), ID($_MUX_)) && cell->getPort(ID::A) == State::S1 && cell->getPort(ID::B) == State::S0) { - log_debug("Replacing %s cell `%s' in module `%s' with inverter.\n", log_id(cell->type), log_id(cell), log_id(module)); + log_debug("Replacing %s cell `%s' in module `%s' with inverter.\n", cell->type.unescape(), cell, module); cell->setPort(ID::A, cell->getPort(ID::S)); cell->unsetPort(ID::B); cell->unsetPort(ID::S); @@ -1446,7 +1446,7 @@ skip_identity: } if (consume_x && mux_bool && cell->type.in(ID($mux), ID($_MUX_)) && cell->getPort(ID::A) == State::S0) { - log_debug("Replacing %s cell `%s' in module `%s' with and-gate.\n", log_id(cell->type), log_id(cell), log_id(module)); + log_debug("Replacing %s cell `%s' in module `%s' with and-gate.\n", cell->type.unescape(), cell, module); cell->setPort(ID::A, cell->getPort(ID::S)); cell->unsetPort(ID::S); if (cell->type == ID($mux)) { @@ -1465,7 +1465,7 @@ skip_identity: } if (consume_x && mux_bool && cell->type.in(ID($mux), ID($_MUX_)) && cell->getPort(ID::B) == State::S1) { - log_debug("Replacing %s cell `%s' in module `%s' with or-gate.\n", log_id(cell->type), log_id(cell), log_id(module)); + log_debug("Replacing %s cell `%s' in module `%s' with or-gate.\n", cell->type.unescape(), cell, module); cell->setPort(ID::B, cell->getPort(ID::S)); cell->unsetPort(ID::S); if (cell->type == ID($mux)) { @@ -1515,7 +1515,7 @@ skip_identity: } if (cell->getPort(ID::S).size() != new_s.size()) { log_debug("Optimized away %d select inputs of %s cell `%s' in module `%s'.\n", - GetSize(cell->getPort(ID::S)) - GetSize(new_s), log_id(cell->type), log_id(cell), log_id(module)); + GetSize(cell->getPort(ID::S)) - GetSize(new_s), cell->type.unescape(), cell, module); cell->setPort(ID::A, new_a); cell->setPort(ID::B, new_b); cell->setPort(ID::S, new_s); @@ -2021,7 +2021,7 @@ skip_alu_split: Const y_value(cell->type.in(ID($eq), ID($eqx)) ? 0 : 1, GetSize(y_sig)); log_debug("Replacing cell `%s' in module `%s' with constant driver %s.\n", - log_id(cell), log_id(module), log_signal(y_value)); + cell, module, log_signal(y_value)); module->connect(y_sig, y_value); module->remove(cell); @@ -2033,7 +2033,7 @@ skip_alu_split: if (redundant_bits) { log_debug("Removed %d redundant input bits from %s cell `%s' in module `%s'.\n", - redundant_bits, log_id(cell->type), log_id(cell), log_id(module)); + redundant_bits, cell->type.unescape(), cell, module); cell->setPort(ID::A, sig_a); cell->setPort(ID::B, sig_b); @@ -2172,7 +2172,7 @@ skip_alu_split: if (replace || remove) { log_debug("Replacing %s cell `%s' (implementing %s) with %s.\n", - log_id(cell->type), log_id(cell), condition.c_str(), replacement.c_str()); + cell->type.unescape(), cell, condition.c_str(), replacement.c_str()); if (replace) module->connect(cell->getPort(ID::Y), replace_sig); module->remove(cell); @@ -2295,7 +2295,7 @@ struct OptExprPass : public Pass { NewCellTypes ct(design); for (auto module : design->selected_modules()) { - log("Optimizing module %s.\n", log_id(module)); + log("Optimizing module %s.\n", module); if (undriven) { did_something = false; diff --git a/passes/opt/opt_hier.cc b/passes/opt/opt_hier.cc index 5c3b09b31..532bcad63 100644 --- a/passes/opt/opt_hier.cc +++ b/passes/opt/opt_hier.cc @@ -101,7 +101,7 @@ struct ModuleIndex { if (!port || (!port->port_input && !port->port_output) || port->width != value.size()) { log_error("Port %s connected on instance %s not found in module %s" " or width is not matching\n", - log_id(port_name), log_id(instantiation), log_id(module)); + port_name.unescape(), instantiation, module); } if (port->port_input && port->port_output) { @@ -145,12 +145,12 @@ struct ModuleIndex { if (nunused > 0) { log("Disconnected %d input bits of instance '%s' (type '%s') in '%s'\n", - nunused, log_id(instantiation), log_id(instantiation->type), log_id(parent.module)); + nunused, instantiation, instantiation->type.unescape(), parent.module); changed = true; } if (nconstants > 0) { log("Substituting constant for %d output bits of instance '%s' (type '%s') in '%s'\n", - nconstants, log_id(instantiation), log_id(instantiation->type), log_id(parent.module)); + nconstants, instantiation, instantiation->type.unescape(), parent.module); changed = true; } } @@ -189,7 +189,7 @@ struct ModuleIndex { if (ntie_togethers > 0) { log("Replacing %d output bits with tie-togethers on instance '%s' of '%s' in '%s'\n", - ntie_togethers, log_id(instantiation), log_id(instantiation->type), log_id(parent.module)); + ntie_togethers, instantiation, instantiation->type.unescape(), parent.module); changed = true; } @@ -290,7 +290,7 @@ struct UsageData { if (!port || (!port->port_input && !port->port_output) || port->width != value.size()) { log_error("Port %s connected on instance %s not found in module %s" " or width is not matching\n", - log_id(port_name), log_id(instance), log_id(module)); + port_name.unescape(), instance, module); } if (port->port_input && port->port_output) { @@ -347,7 +347,7 @@ struct UsageData { }; module->rewrite_sigspecs(disconnect_rewrite); for (auto chunk : disconnect_outputs.chunks()) { - log("Disconnected unused output terminal '%s' in module '%s'\n", log_signal(chunk), log_id(module)); + log("Disconnected unused output terminal '%s' in module '%s'\n", log_signal(chunk), module); did_something = true; module->connect(chunk, SigSpec(RTLIL::Sx, chunk.size())); } @@ -368,7 +368,7 @@ struct UsageData { SigSpec const_ = chunk; const_.replace(constant_inputs); log("Substituting constant %s for input terminal '%s' in module '%s'\n", - log_signal(const_), log_signal(chunk), log_id(module)); + log_signal(const_), log_signal(chunk), module); } // Propagate tied-together inputs @@ -397,7 +397,7 @@ struct UsageData { module->rewrite_sigspecs(ties_rewrite); if (applied_ties.size()) { log("Replacing %zu input terminal bits with tie-togethers in module '%s'\n", - applied_ties.size(), log_id(module)); + applied_ties.size(), module); } return did_something; } @@ -433,7 +433,7 @@ struct OptHierPass : Pass { dict indices; for (auto module : d->modules()) { - log_debug("Building index for %s\n", log_id(module)); + log_debug("Building index for %s\n", module); indices.emplace(module->name, ModuleIndex(module)); } @@ -442,14 +442,14 @@ struct OptHierPass : Pass { if (module->get_bool_attribute(ID::top)) continue; - log_debug("Starting usage data for %s\n", log_id(module)); + log_debug("Starting usage data for %s\n", module); usage_datas.emplace(module->name, UsageData(module)); } for (auto module : d->modules()) { for (auto cell : module->cells()) { if (usage_datas.count(cell->type)) { - log_debug("Account for instance %s of %s in %s\n", log_id(cell), log_id(cell->type), log_id(module)); + log_debug("Account for instance %s of %s in %s\n", cell, cell->type.unescape(), module); usage_datas.at(cell->type).refine(cell, indices.at(module->name)); } } @@ -460,13 +460,13 @@ struct OptHierPass : Pass { ModuleIndex &parent_index = indices.at(module->name); if (usage_datas.count(module->name)) { - log_debug("Applying usage data changes to %s\n", log_id(module)); + log_debug("Applying usage data changes to %s\n", module); did_something |= usage_datas.at(module->name).apply_changes(parent_index); } for (auto cell : module->cells()) { if (indices.count(cell->type)) { - log_debug("Applying changes to instance %s of %s in %s\n", log_id(cell), log_id(cell->type), log_id(module)); + log_debug("Applying changes to instance %s of %s in %s\n", cell, cell->type.unescape(), module); did_something |= indices.at(cell->type).apply_changes(parent_index, cell); } } diff --git a/passes/opt/opt_lut.cc b/passes/opt/opt_lut.cc index c0a017748..3768eed32 100644 --- a/passes/opt/opt_lut.cc +++ b/passes/opt/opt_lut.cc @@ -121,7 +121,7 @@ struct OptLutWorker SigSpec lut_input = cell->getPort(ID::A); int lut_arity = 0; - log_debug("Found $lut\\WIDTH=%d cell %s.%s.\n", lut_width, log_id(module), log_id(cell)); + log_debug("Found $lut\\WIDTH=%d cell %s.%s.\n", lut_width, module, cell); luts.insert(cell); // First, find all dedicated logic we're connected to. This results in an overapproximation @@ -162,7 +162,7 @@ struct OptLutWorker { if (lut_width <= dlogic_conn.first) { - log_debug(" LUT has illegal connection to %s cell %s.%s.\n", lut_dlogic.second->type, log_id(module), log_id(lut_dlogic.second)); + log_debug(" LUT has illegal connection to %s cell %s.%s.\n", lut_dlogic.second->type, module, lut_dlogic.second); log_debug(" LUT input A[%d] not present.\n", dlogic_conn.first); legal = false; break; @@ -173,7 +173,7 @@ struct OptLutWorker if (sigmap(lut_input[dlogic_conn.first]) != sigmap(lut_dlogic.second->getPort(dlogic_conn.second)[0])) { - log_debug(" LUT has illegal connection to %s cell %s.%s.\n", lut_dlogic.second->type, log_id(module), log_id(lut_dlogic.second)); + log_debug(" LUT has illegal connection to %s cell %s.%s.\n", lut_dlogic.second->type, module, lut_dlogic.second); log_debug(" LUT input A[%d] (wire %s) not connected to %s port %s (wire %s).\n", dlogic_conn.first, log_signal(lut_input[dlogic_conn.first]), lut_dlogic.second->type, dlogic_conn.second, log_signal(lut_dlogic.second->getPort(dlogic_conn.second))); legal = false; break; @@ -182,7 +182,7 @@ struct OptLutWorker if (legal) { - log_debug(" LUT has legal connection to %s cell %s.%s.\n", lut_dlogic.second->type, log_id(module), log_id(lut_dlogic.second)); + log_debug(" LUT has legal connection to %s cell %s.%s.\n", lut_dlogic.second->type, module, lut_dlogic.second); lut_legal_dlogics.insert(lut_dlogic); for (auto &dlogic_conn : dlogic_map) lut_dlogic_inputs.insert(dlogic_conn.first); @@ -258,7 +258,7 @@ struct OptLutWorker if (const0_match || const1_match || input_match != -1) { - log_debug("Found redundant cell %s.%s.\n", log_id(module), log_id(lut)); + log_debug("Found redundant cell %s.%s.\n", module, lut); SigBit value; if (const0_match) @@ -341,7 +341,7 @@ struct OptLutWorker int lutB_arity = luts_arity[lutB]; pool &lutB_dlogic_inputs = luts_dlogic_inputs[lutB]; - log_debug("Found %s.%s (cell A) feeding %s.%s (cell B).\n", log_id(module), log_id(lutA), log_id(module), log_id(lutB)); + log_debug("Found %s.%s (cell A) feeding %s.%s (cell B).\n", module, lutA, module, lutB); if (index.query_is_output(lutA->getPort(ID::Y))) { diff --git a/passes/opt/opt_lut_ins.cc b/passes/opt/opt_lut_ins.cc index 580853b51..c1355da25 100644 --- a/passes/opt/opt_lut_ins.cc +++ b/passes/opt/opt_lut_ins.cc @@ -64,7 +64,7 @@ struct OptLutInsPass : public Pass { for (auto module : design->selected_modules()) { - log("Optimizing LUTs in %s.\n", log_id(module)); + log("Optimizing LUTs in %s.\n", module); std::vector remove_cells; // Gather LUTs. @@ -181,7 +181,7 @@ struct OptLutInsPass : public Pass { } if (!doit) continue; - log(" Optimizing lut %s (%d -> %d)\n", log_id(cell), GetSize(inputs), GetSize(new_inputs)); + log(" Optimizing lut %s (%d -> %d)\n", cell, GetSize(inputs), GetSize(new_inputs)); if (techname == "lattice" || techname == "ecp5") { // Pad the LUT to 4 inputs, adding consts from the front. int extra = 4 - GetSize(new_inputs); diff --git a/passes/opt/opt_mem.cc b/passes/opt/opt_mem.cc index 9c5a6d83e..0bd97f5f9 100644 --- a/passes/opt/opt_mem.cc +++ b/passes/opt/opt_mem.cc @@ -108,13 +108,13 @@ struct OptMemPass : public Pass { } State bit; if (!always_0[i]) { - log("%s.%s: removing const-1 lane %d\n", log_id(module->name), log_id(mem.memid), i); + log("%s.%s: removing const-1 lane %d\n", module->name.unescape(), mem.memid.unescape(), i); bit = State::S1; } else if (!always_1[i]) { - log("%s.%s: removing const-0 lane %d\n", log_id(module->name), log_id(mem.memid), i); + log("%s.%s: removing const-0 lane %d\n", module->name.unescape(), mem.memid.unescape(), i); bit = State::S0; } else { - log("%s.%s: removing const-x lane %d\n", log_id(module->name), log_id(mem.memid), i); + log("%s.%s: removing const-x lane %d\n", module->name.unescape(), mem.memid.unescape(), i); bit = State::Sx; } // Reconnect read port data. diff --git a/passes/opt/opt_mem_feedback.cc b/passes/opt/opt_mem_feedback.cc index 20a2a79ed..fe5157934 100644 --- a/passes/opt/opt_mem_feedback.cc +++ b/passes/opt/opt_mem_feedback.cc @@ -163,7 +163,7 @@ struct OptMemFeedbackWorker { auto &port = mem.wr_ports[i]; - log(" Analyzing %s.%s write port %d.\n", log_id(module), log_id(mem.memid), i); + log(" Analyzing %s.%s write port %d.\n", module, mem.memid.unescape(), i); for (int sub = 0; sub < (1 << port.wide_log2); sub++) { @@ -232,7 +232,7 @@ struct OptMemFeedbackWorker // Okay, let's do it. - log("Populating enable bits on write ports of memory %s.%s with async read feedback:\n", log_id(module), log_id(mem.memid)); + log("Populating enable bits on write ports of memory %s.%s with async read feedback:\n", module, mem.memid.unescape()); // If a write port has a feedback path that we're about to bypass, // but also has priority over some other write port, the feedback diff --git a/passes/opt/opt_mem_widen.cc b/passes/opt/opt_mem_widen.cc index 95e01088c..f642666db 100644 --- a/passes/opt/opt_mem_widen.cc +++ b/passes/opt/opt_mem_widen.cc @@ -65,7 +65,7 @@ struct OptMemWidenPass : public Pass { factor_log2 = port.wide_log2; if (factor_log2 == 0) continue; - log("Widening base width of memory %s in module %s by factor %d.\n", log_id(mem.memid), log_id(module->name), 1 << factor_log2); + log("Widening base width of memory %s in module %s by factor %d.\n", mem.memid.unescape(), module->name.unescape(), 1 << factor_log2); total_count++; // The inits are too messy to expand one-by-one, for they may // collide with one another after expansion. Just hit it with diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index 8bf151e71..af77ff46d 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -229,7 +229,7 @@ struct OptMuxtreeWorker for (int mux_idx = 0; mux_idx < GetSize(root_muxes); mux_idx++) if (root_muxes.at(mux_idx)) { - log_debug(" Root of a mux tree: %s%s\n", log_id(mux2info[mux_idx].cell), root_enable_muxes.at(mux_idx) ? " (pure)" : ""); + log_debug(" Root of a mux tree: %s%s\n", mux2info[mux_idx].cell, root_enable_muxes.at(mux_idx) ? " (pure)" : ""); root_mux_rerun.erase(mux_idx); eval_root_mux(mux_idx); if (glob_evals_left == 0) { @@ -240,7 +240,7 @@ struct OptMuxtreeWorker while (!root_mux_rerun.empty()) { int mux_idx = *root_mux_rerun.begin(); - log_debug(" Root of a mux tree: %s (rerun as non-pure)\n", log_id(mux2info[mux_idx].cell)); + log_debug(" Root of a mux tree: %s (rerun as non-pure)\n", mux2info[mux_idx].cell); log_assert(root_enable_muxes.at(mux_idx)); root_mux_rerun.erase(mux_idx); eval_root_mux(mux_idx); @@ -437,7 +437,7 @@ struct OptMuxtreeWorker // Ran out of subtree depth, re-eval this input tree in the next re-run root_mux_rerun.insert(m); root_enable_muxes.at(m) = true; - log_debug(" Removing pure flag from root mux %s.\n", log_id(mux2info[m].cell)); + log_debug(" Removing pure flag from root mux %s.\n", mux2info[m].cell); } else { auto new_limits = limits.subtree(); // Since our knowledge includes assumption, @@ -517,8 +517,8 @@ struct OptMuxtreeWorker } if (did_something) { - log(" Replacing known input bits on port %s of cell %s: %s -> %s\n", log_id(portname), - log_id(muxinfo.cell), log_signal(muxinfo.cell->getPort(portname)), log_signal(sig)); + log(" Replacing known input bits on port %s of cell %s: %s -> %s\n", portname.unescape(), + muxinfo.cell, log_signal(muxinfo.cell->getPort(portname)), log_signal(sig)); muxinfo.cell->setPort(portname, sig); } } @@ -530,7 +530,7 @@ struct OptMuxtreeWorker glob_evals_left--; muxinfo_t &muxinfo = mux2info[mux_idx]; - log_debug("\t\teval %s (replace %d enable %d)\n", log_id(muxinfo.cell), limits.do_replace_known, limits.do_mark_ports_observable); + log_debug("\t\teval %s (replace %d enable %d)\n", muxinfo.cell, limits.do_replace_known, limits.do_mark_ports_observable); // set input ports to constants if we find known active or inactive signals if (limits.do_replace_known) { diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index bf9569d99..b213048aa 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -560,9 +560,9 @@ struct OptSharePass : public Pass { log(" Found cells that share an operand and can be merged by moving the %s %s in front " "of " "them:\n", - log_id(shared.mux->type), log_id(shared.mux)); + shared.mux->type.unescape(), shared.mux); for (const auto& op : shared.ports) - log(" %s\n", log_id(op.op)); + log(" %s\n", op.op); log("\n"); merge_operators(module, shared.mux, shared.ports, shared.shared_operand, sigmap); diff --git a/passes/opt/pmux2shiftx.cc b/passes/opt/pmux2shiftx.cc index 4a0864df0..6668ff2de 100644 --- a/passes/opt/pmux2shiftx.cc +++ b/passes/opt/pmux2shiftx.cc @@ -390,7 +390,7 @@ struct Pmux2ShiftxPass : public Pass { if (verbose) { printed_pmux_header = true; - log("Inspecting $pmux cell %s/%s.\n", log_id(module), log_id(cell)); + log("Inspecting $pmux cell %s/%s.\n", module, cell); log(" data width: %d (next power-of-2 = %d, log2 = %d)\n", width, extwidth, width_bits); } @@ -441,7 +441,7 @@ struct Pmux2ShiftxPass : public Pass { if (!printed_pmux_header) { printed_pmux_header = true; - log("Inspecting $pmux cell %s/%s.\n", log_id(module), log_id(cell)); + log("Inspecting $pmux cell %s/%s.\n", module, cell); log(" data width: %d (next power-of-2 = %d, log2 = %d)\n", width, extwidth, width_bits); } @@ -714,7 +714,7 @@ struct Pmux2ShiftxPass : public Pass { Cell *c = module->addShiftx(NEW_ID, data, shifted_cmp, outsig, false, src); updated_S.append(en); updated_B.append(outsig); - log(" created $shiftx cell %s.\n", log_id(c)); + log(" created $shiftx cell %s.\n", c); // remove this sig and continue with the next block seldb.erase(sig); @@ -799,7 +799,7 @@ struct OnehotPass : public Pass { continue; if (verbose) - log("Checking $eq(%s, %s) cell %s/%s.\n", log_signal(A), log_signal(B), log_id(module), log_id(cell)); + log("Checking $eq(%s, %s) cell %s/%s.\n", log_signal(A), log_signal(B), module, cell); if (!onehot_db.query(A)) { if (verbose) @@ -831,7 +831,7 @@ struct OnehotPass : public Pass { if (verbose) log(" replacing with constant 0 driver.\n"); else - log("Replacing one-hot $eq(%s, %s) cell %s/%s with constant 0 driver.\n", log_signal(A), log_signal(B), log_id(module), log_id(cell)); + log("Replacing one-hot $eq(%s, %s) cell %s/%s with constant 0 driver.\n", log_signal(A), log_signal(B), module, cell); module->connect(Y, SigSpec(1, GetSize(Y))); } else @@ -840,7 +840,7 @@ struct OnehotPass : public Pass { if (verbose) log(" replacing with signal %s.\n", log_signal(sig)); else - log("Replacing one-hot $eq(%s, %s) cell %s/%s with signal %s.\n",log_signal(A), log_signal(B), log_id(module), log_id(cell), log_signal(sig)); + log("Replacing one-hot $eq(%s, %s) cell %s/%s with signal %s.\n",log_signal(A), log_signal(B), module, cell, log_signal(sig)); sig.extend_u0(GetSize(Y)); module->connect(Y, sig); } diff --git a/passes/opt/share.cc b/passes/opt/share.cc index bc363e251..119243d48 100644 --- a/passes/opt/share.cc +++ b/passes/opt/share.cc @@ -958,7 +958,7 @@ struct ShareWorker optimize_activation_patterns(activation_patterns_cache[cell]); if (activation_patterns_cache[cell].empty()) { - log("%sFound cell that is never activated: %s\n", indent, log_id(cell)); + log("%sFound cell that is never activated: %s\n", indent, cell); RTLIL::SigSpec cell_outputs = modwalker.cell_outputs[cell]; module->connect(RTLIL::SigSig(cell_outputs, RTLIL::SigSpec(RTLIL::State::Sx, cell_outputs.size()))); cells_to_remove.insert(cell); @@ -1123,7 +1123,7 @@ struct ShareWorker for (auto &loop : toposort.loops) { log("### loop ###\n"); for (auto &c : loop) - log("%s (%s)\n", log_id(c), log_id(c->type)); + log("%s (%s)\n", c, c->type.unescape()); } return found_scc; @@ -1240,14 +1240,14 @@ struct ShareWorker return; log("Found %d cells in module %s that may be considered for resource sharing.\n", - GetSize(shareable_cells), log_id(module)); + GetSize(shareable_cells), module); while (!shareable_cells.empty() && config.limit != 0) { RTLIL::Cell *cell = *shareable_cells.begin(); shareable_cells.erase(cell); - log(" Analyzing resource sharing options for %s (%s):\n", log_id(cell), log_id(cell->type)); + log(" Analyzing resource sharing options for %s (%s):\n", cell, cell->type.unescape()); const pool &cell_activation_patterns = find_cell_activation_patterns(cell, " "); RTLIL::SigSpec cell_activation_signals = bits_from_activation_patterns(cell_activation_patterns); @@ -1275,12 +1275,12 @@ struct ShareWorker log(" Found %d candidates:", GetSize(candidates)); for (auto c : candidates) - log(" %s", log_id(c)); + log(" %s", c); log("\n"); for (auto other_cell : candidates) { - log(" Analyzing resource sharing with %s (%s):\n", log_id(other_cell), log_id(other_cell->type)); + log(" Analyzing resource sharing with %s (%s):\n", other_cell, other_cell->type.unescape()); const pool &other_cell_activation_patterns = find_cell_activation_patterns(other_cell, " "); RTLIL::SigSpec other_cell_activation_signals = bits_from_activation_patterns(other_cell_activation_patterns); @@ -1332,13 +1332,13 @@ struct ShareWorker RTLIL::SigSpec all_ctrl_signals; for (auto &p : filtered_cell_activation_patterns) { - log(" Activation pattern for cell %s: %s = %s\n", log_id(cell), log_signal(p.first), log_signal(p.second)); + log(" Activation pattern for cell %s: %s = %s\n", cell, log_signal(p.first), log_signal(p.second)); cell_active.push_back(qcsat.ez->vec_eq(qcsat.importSig(p.first), qcsat.importSig(p.second))); all_ctrl_signals.append(p.first); } for (auto &p : filtered_other_cell_activation_patterns) { - log(" Activation pattern for cell %s: %s = %s\n", log_id(other_cell), log_signal(p.first), log_signal(p.second)); + log(" Activation pattern for cell %s: %s = %s\n", other_cell, log_signal(p.first), log_signal(p.second)); other_cell_active.push_back(qcsat.ez->vec_eq(qcsat.importSig(p.first), qcsat.importSig(p.second))); all_ctrl_signals.append(p.first); } @@ -1349,13 +1349,13 @@ struct ShareWorker qcsat.prepare(); if (!qcsat.ez->solve(sub1)) { - log(" According to the SAT solver the cell %s is never active. Sharing is pointless, we simply remove it.\n", log_id(cell)); + log(" According to the SAT solver the cell %s is never active. Sharing is pointless, we simply remove it.\n", cell); cells_to_remove.insert(cell); break; } if (!qcsat.ez->solve(sub2)) { - log(" According to the SAT solver the cell %s is never active. Sharing is pointless, we simply remove it.\n", log_id(other_cell)); + log(" According to the SAT solver the cell %s is never active. Sharing is pointless, we simply remove it.\n", other_cell); cells_to_remove.insert(other_cell); shareable_cells.erase(other_cell); continue; @@ -1391,20 +1391,20 @@ struct ShareWorker if (restrict_activation_patterns(optimized_cell_activation_patterns, optimized_other_cell_activation_patterns)) { for (auto &p : optimized_cell_activation_patterns) - log(" Simplified activation pattern for cell %s: %s = %s\n", log_id(cell), log_signal(p.first), log_signal(p.second)); + log(" Simplified activation pattern for cell %s: %s = %s\n", cell, log_signal(p.first), log_signal(p.second)); for (auto &p : optimized_other_cell_activation_patterns) - log(" Simplified activation pattern for cell %s: %s = %s\n", log_id(other_cell), log_signal(p.first), log_signal(p.second)); + log(" Simplified activation pattern for cell %s: %s = %s\n", other_cell, log_signal(p.first), log_signal(p.second)); } } if (find_in_input_cone(cell, other_cell)) { - log(" Sharing not possible: %s is in input cone of %s.\n", log_id(other_cell), log_id(cell)); + log(" Sharing not possible: %s is in input cone of %s.\n", other_cell, cell); continue; } if (find_in_input_cone(other_cell, cell)) { - log(" Sharing not possible: %s is in input cone of %s.\n", log_id(cell), log_id(other_cell)); + log(" Sharing not possible: %s is in input cone of %s.\n", cell, other_cell); continue; } @@ -1424,14 +1424,14 @@ struct ShareWorker if (cell_select_score <= other_cell_select_score) { RTLIL::SigSpec act = make_cell_activation_logic(optimized_cell_activation_patterns, supercell_aux); supercell = make_supercell(cell, other_cell, act, supercell_aux); - log(" Activation signal for %s: %s\n", log_id(cell), log_signal(act)); + log(" Activation signal for %s: %s\n", cell, log_signal(act)); } else { RTLIL::SigSpec act = make_cell_activation_logic(optimized_other_cell_activation_patterns, supercell_aux); supercell = make_supercell(other_cell, cell, act, supercell_aux); - log(" Activation signal for %s: %s\n", log_id(other_cell), log_signal(act)); + log(" Activation signal for %s: %s\n", other_cell, log_signal(act)); } - log(" New cell: %s (%s)\n", log_id(supercell), log_id(supercell->type)); + log(" New cell: %s (%s)\n", supercell, supercell->type.unescape()); cells_to_remove.insert(cell); cells_to_remove.insert(other_cell); @@ -1476,9 +1476,9 @@ struct ShareWorker } if (!cells_to_remove.empty()) { - log("Removing %d cells in module %s:\n", GetSize(cells_to_remove), log_id(module)); + log("Removing %d cells in module %s:\n", GetSize(cells_to_remove), module); for (auto c : cells_to_remove) { - log(" Removing cell %s (%s).\n", log_id(c), log_id(c->type)); + log(" Removing cell %s (%s).\n", c, c->type.unescape()); remove_cell(c); } } diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index 359c76d42..d70299ab8 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -104,14 +104,14 @@ struct WreduceWorker sig_removed.append(bits_removed[i]); if (GetSize(bits_removed) == GetSize(sig_y)) { - log("Removed cell %s.%s (%s).\n", log_id(module), log_id(cell), log_id(cell->type)); + log("Removed cell %s.%s (%s).\n", module, cell, cell->type.unescape()); module->connect(sig_y, sig_removed); module->remove(cell); return; } log("Removed top %d bits (of %d) from mux cell %s.%s (%s).\n", - GetSize(sig_removed), GetSize(sig_y), log_id(module), log_id(cell), log_id(cell->type)); + GetSize(sig_removed), GetSize(sig_y), module, cell, cell->type.unescape()); int n_removed = GetSize(sig_removed); int n_kept = GetSize(sig_y) - GetSize(sig_removed); @@ -204,13 +204,13 @@ struct WreduceWorker return; if (GetSize(sig_q) == 0) { - log("Removed cell %s.%s (%s).\n", log_id(module), log_id(cell), log_id(cell->type)); + log("Removed cell %s.%s (%s).\n", module, cell, cell->type.unescape()); module->remove(cell); return; } log("Removed top %d bits (of %d) from FF cell %s.%s (%s).\n", width_before - GetSize(sig_q), width_before, - log_id(module), log_id(cell), log_id(cell->type)); + module, cell, cell->type.unescape()); for (auto bit : sig_d) work_queue_bits.insert(bit); @@ -258,7 +258,7 @@ struct WreduceWorker if (bits_removed) { log("Removed top %d bits (of %d) from port %c of cell %s.%s (%s).\n", - bits_removed, GetSize(sig) + bits_removed, port, log_id(module), log_id(cell), log_id(cell->type)); + bits_removed, GetSize(sig) + bits_removed, port, module, cell, cell->type.unescape()); cell->setPort(stringf("\\%c", port), sig); did_something = true; } @@ -331,7 +331,7 @@ struct WreduceWorker if (!port_a_signed && !port_b_signed && signed_cost < unsigned_cost) { log("Converting cell %s.%s (%s) from unsigned to signed.\n", - log_id(module), log_id(cell), log_id(cell->type)); + module, cell, cell->type.unescape()); cell->setParam(ID::A_SIGNED, 1); cell->setParam(ID::B_SIGNED, 1); port_a_signed = true; @@ -339,7 +339,7 @@ struct WreduceWorker did_something = true; } else if (port_a_signed && port_b_signed && unsigned_cost < signed_cost) { log("Converting cell %s.%s (%s) from signed to unsigned.\n", - log_id(module), log_id(cell), log_id(cell->type)); + module, cell, cell->type.unescape()); cell->setParam(ID::A_SIGNED, 0); cell->setParam(ID::B_SIGNED, 0); port_a_signed = false; @@ -359,7 +359,7 @@ struct WreduceWorker if (GetSize(sig_a) > 0 && sig_a[GetSize(sig_a)-1] == State::S0 && GetSize(sig_b) > 0 && sig_b[GetSize(sig_b)-1] == State::S0) { log("Converting cell %s.%s (%s) from signed to unsigned.\n", - log_id(module), log_id(cell), log_id(cell->type)); + module, cell, cell->type.unescape()); cell->setParam(ID::A_SIGNED, 0); cell->setParam(ID::B_SIGNED, 0); port_a_signed = false; @@ -372,7 +372,7 @@ struct WreduceWorker SigSpec sig_a = mi.sigmap(cell->getPort(ID::A)); if (GetSize(sig_a) > 0 && sig_a[GetSize(sig_a)-1] == State::S0) { log("Converting cell %s.%s (%s) from signed to unsigned.\n", - log_id(module), log_id(cell), log_id(cell->type)); + module, cell, cell->type.unescape()); cell->setParam(ID::A_SIGNED, 0); port_a_signed = false; did_something = true; @@ -431,14 +431,14 @@ struct WreduceWorker } if (GetSize(sig) == 0) { - log("Removed cell %s.%s (%s).\n", log_id(module), log_id(cell), log_id(cell->type)); + log("Removed cell %s.%s (%s).\n", module, cell, cell->type.unescape()); module->remove(cell); return; } if (bits_removed) { log("Removed top %d bits (of %d) from port Y of cell %s.%s (%s).\n", - bits_removed, GetSize(sig) + bits_removed, log_id(module), log_id(cell), log_id(cell->type)); + bits_removed, GetSize(sig) + bits_removed, module, cell, cell->type.unescape()); cell->setPort(ID::Y, sig); did_something = true; } @@ -510,7 +510,7 @@ struct WreduceWorker if (complete_wires[mi.sigmap(w).extract(0, GetSize(w) - unused_top_bits)]) continue; - log("Removed top %d bits (of %d) from wire %s.%s.\n", unused_top_bits, GetSize(w), log_id(module), log_id(w)); + log("Removed top %d bits (of %d) from wire %s.%s.\n", unused_top_bits, GetSize(w), module, w); Wire *nw = module->addWire(NEW_ID, GetSize(w) - unused_top_bits); module->connect(nw, SigSpec(w).extract(0, GetSize(nw))); module->swap_names(w, nw); @@ -603,7 +603,7 @@ struct WreducePass : public Pass { } if (original_a_width != GetSize(A)) { log("Removed top %d bits (of %d) from port A of cell %s.%s (%s).\n", - original_a_width-GetSize(A), original_a_width, log_id(module), log_id(c), log_id(c->type)); + original_a_width-GetSize(A), original_a_width, module, c, c->type.unescape()); c->setPort(ID::A, A); c->setParam(ID::A_WIDTH, GetSize(A)); } @@ -619,7 +619,7 @@ struct WreducePass : public Pass { } if (original_b_width != GetSize(B)) { log("Removed top %d bits (of %d) from port B of cell %s.%s (%s).\n", - original_b_width-GetSize(B), original_b_width, log_id(module), log_id(c), log_id(c->type)); + original_b_width-GetSize(B), original_b_width, module, c, c->type.unescape()); c->setPort(ID::B, B); c->setParam(ID::B_WIDTH, GetSize(B)); } @@ -635,7 +635,7 @@ struct WreducePass : public Pass { log("Removed top %d address bits (of %d) from memory %s port %s.%s (%s).\n", cur_addrbits-max_addrbits, cur_addrbits, c->type == ID($memrd) ? "read" : c->type == ID($memwr) ? "write" : "init", - log_id(module), log_id(c), log_id(memid)); + module, c, memid.unescape()); c->setParam(ID::ABITS, max_addrbits); c->setPort(ID::ADDR, c->getPort(ID::ADDR).extract(0, max_addrbits)); } diff --git a/passes/pmgen/generate.h b/passes/pmgen/generate.h index 85e208774..e44ff58e8 100644 --- a/passes/pmgen/generate.h +++ b/passes/pmgen/generate.h @@ -106,7 +106,7 @@ void generate_pattern(std::function)> run, const if (found_match) { Module *m = design->addModule(stringf("\\pmtest_%s_%s_%05d", pmclass, pattern, modcnt++)); - log("Creating module %s with %d cells.\n", log_id(m), cellcnt); + log("Creating module %s with %d cells.\n", m, cellcnt); mod->cloneInto(m); pmtest_addports(m); mods.push_back(m); @@ -126,7 +126,7 @@ void generate_pattern(std::function)> run, const } Module *m = design->addModule(stringf("\\pmtest_%s_%s", pmclass, pattern)); - log("Creating module %s with %d cells.\n", log_id(m), GetSize(mods)); + log("Creating module %s with %d cells.\n", m, GetSize(mods)); for (auto mod : mods) { Cell *c = m->addCell(mod->name, mod->name); for (auto port : mod->ports) { diff --git a/passes/pmgen/test_pmgen.cc b/passes/pmgen/test_pmgen.cc index f6d6a3f93..18bc12346 100644 --- a/passes/pmgen/test_pmgen.cc +++ b/passes/pmgen/test_pmgen.cc @@ -37,7 +37,7 @@ void reduce_chain(test_pmgen_pm &pm) if (ud.longest_chain.empty()) return; - log("Found chain of length %d (%s):\n", GetSize(ud.longest_chain), log_id(st.first->type)); + log("Found chain of length %d (%s):\n", GetSize(ud.longest_chain), st.first->type.unescape()); SigSpec A; SigSpec Y = ud.longest_chain.front().first->getPort(ID::Y); @@ -51,7 +51,7 @@ void reduce_chain(test_pmgen_pm &pm) } else { A.append(cell->getPort(it.second == ID::A ? ID::B : ID::A)); } - log(" %s\n", log_id(cell)); + log(" %s\n", cell); pm.autoremove(cell); } @@ -66,7 +66,7 @@ void reduce_chain(test_pmgen_pm &pm) else log_abort(); - log(" -> %s (%s)\n", log_id(c), log_id(c->type)); + log(" -> %s (%s)\n", c, c->type.unescape()); } void reduce_tree(test_pmgen_pm &pm) @@ -81,8 +81,8 @@ void reduce_tree(test_pmgen_pm &pm) SigSpec Y = st.first->getPort(ID::Y); pm.autoremove(st.first); - log("Found %s tree with %d leaves for %s (%s).\n", log_id(st.first->type), - GetSize(A), log_signal(Y), log_id(st.first)); + log("Found %s tree with %d leaves for %s (%s).\n", st.first->type.unescape(), + GetSize(A), log_signal(Y), st.first); Cell *c; @@ -95,7 +95,7 @@ void reduce_tree(test_pmgen_pm &pm) else log_abort(); - log(" -> %s (%s)\n", log_id(c), log_id(c->type)); + log(" -> %s (%s)\n", c, c->type.unescape()); } void opt_eqpmux(test_pmgen_pm &pm) @@ -109,11 +109,11 @@ void opt_eqpmux(test_pmgen_pm &pm) SigSpec NE = st.pmux->getPort(ID::B).extract(st.pmux_slice_ne*width, width); log("Found eqpmux circuit driving %s (eq=%s, ne=%s, pmux=%s).\n", - log_signal(Y), log_id(st.eq), log_id(st.ne), log_id(st.pmux)); + log_signal(Y), st.eq, st.ne, st.pmux); pm.autoremove(st.pmux); Cell *c = pm.module->addMux(NEW_ID, NE, EQ, st.eq->getPort(ID::Y), Y); - log(" -> %s (%s)\n", log_id(c), log_id(c->type)); + log(" -> %s (%s)\n", c, c->type.unescape()); } struct TestPmgenPass : public Pass { diff --git a/passes/proc/proc_arst.cc b/passes/proc/proc_arst.cc index 92d8d0569..f754bc948 100644 --- a/passes/proc/proc_arst.cc +++ b/passes/proc/proc_arst.cc @@ -215,7 +215,7 @@ void proc_arst(RTLIL::Module *mod, RTLIL::Process *proc, SigMap &assign_map) RTLIL::SigSpec en = apply_reset(mod, proc, sync, assign_map, root_sig, polarity, memwr.enable, memwr.enable); if (!en.is_fully_zero()) { log_error("Async reset %s causes memory write to %s.\n", - log_signal(sync->signal), log_id(memwr.memid)); + log_signal(sync->signal), memwr.memid.unescape()); } apply_reset(mod, proc, sync, assign_map, root_sig, polarity, memwr.address, memwr.address); apply_reset(mod, proc, sync, assign_map, root_sig, polarity, memwr.data, memwr.data); diff --git a/passes/proc/proc_clean.cc b/passes/proc/proc_clean.cc index 8cccb96c4..0df9fc0b2 100644 --- a/passes/proc/proc_clean.cc +++ b/passes/proc/proc_clean.cc @@ -216,7 +216,7 @@ struct ProcCleanPass : public Pass { if (proc->syncs.size() == 0 && proc->root_case.switches.size() == 0 && proc->root_case.actions.size() == 0) { if (!quiet) - log("Removing empty process `%s.%s'.\n", log_id(mod), proc->name); + log("Removing empty process `%s.%s'.\n", mod, proc->name); delme.push_back(proc); } } diff --git a/passes/proc/proc_dlatch.cc b/passes/proc/proc_dlatch.cc index bda2d272f..5e07dbcb0 100644 --- a/passes/proc/proc_dlatch.cc +++ b/passes/proc/proc_dlatch.cc @@ -438,7 +438,7 @@ void proc_dlatch(proc_dlatch_db_t &db, RTLIL::Process *proc) db.module->name.c_str(), log_signal(lhs), db.module->name.c_str(), proc->name.c_str()); else log("Latch inferred for signal `%s.%s' from process `%s.%s': %s\n", - db.module->name.c_str(), log_signal(lhs), db.module->name.c_str(), proc->name.c_str(), log_id(cell)); + db.module->name.c_str(), log_signal(lhs), db.module->name.c_str(), proc->name.c_str(), cell); } offset += width; diff --git a/passes/proc/proc_memwr.cc b/passes/proc/proc_memwr.cc index a5ae0d6d5..e79d24e96 100644 --- a/passes/proc/proc_memwr.cc +++ b/passes/proc/proc_memwr.cc @@ -75,7 +75,7 @@ void proc_memwr(RTLIL::Module *mod, RTLIL::Process *proc, dict &n cell->setParam(ID::CLK_ENABLE, State::S1); cell->setParam(ID::CLK_POLARITY, State::S0); } else { - log_error("process memory write with unsupported sync type in %s.%s", log_id(mod), log_id(proc)); + log_error("process memory write with unsupported sync type in %s.%s", mod, proc); } } sr->mem_write_actions.clear(); diff --git a/passes/proc/proc_rmdead.cc b/passes/proc/proc_rmdead.cc index 8f5eda085..be7961e76 100644 --- a/passes/proc/proc_rmdead.cc +++ b/passes/proc/proc_rmdead.cc @@ -154,10 +154,10 @@ struct ProcRmdeadPass : public Pass { proc_rmdead(switch_it, counter, full_case_counter); if (counter > 0) log("Removed %d dead cases from process %s in module %s.\n", counter, - log_id(proc), log_id(mod)); + proc, mod); if (full_case_counter > 0) log("Marked %d switch rules as full_case in process %s in module %s.\n", - full_case_counter, log_id(proc), log_id(mod)); + full_case_counter, proc, mod); total_counter += counter; } } diff --git a/passes/sat/assertpmux.cc b/passes/sat/assertpmux.cc index 7b3357f82..314535e84 100644 --- a/passes/sat/assertpmux.cc +++ b/passes/sat/assertpmux.cc @@ -148,7 +148,7 @@ struct AssertpmuxWorker void run(Cell *pmux) { - log("Adding assert for $pmux cell %s.%s.\n", log_id(module), log_id(pmux)); + log("Adding assert for $pmux cell %s.%s.\n", module, pmux); int swidth = pmux->getParam(ID::S_WIDTH).as_int(); int cntbits = ceil_log2(swidth+1); diff --git a/passes/sat/async2sync.cc b/passes/sat/async2sync.cc index 086dd5278..be2355e00 100644 --- a/passes/sat/async2sync.cc +++ b/passes/sat/async2sync.cc @@ -91,7 +91,7 @@ struct Async2syncPass : public Pass { int trg_width = cell->getParam(ID(TRG_WIDTH)).as_int(); if (trg_width > 1) - log_error("$check cell %s with TRG_WIDTH > 1 is not support by async2sync, use clk2fflogic.\n", log_id(cell)); + log_error("$check cell %s with TRG_WIDTH > 1 is not support by async2sync, use clk2fflogic.\n", cell); if (trg_width == 0) { if (initstate == State::S0) @@ -147,7 +147,7 @@ struct Async2syncPass : public Pass { ff.unmap_ce_srst(); log("Replacing %s.%s (%s): SET=%s, CLR=%s, D=%s, Q=%s\n", - log_id(module), log_id(cell), log_id(cell->type), + module, cell, cell->type.unescape(), log_signal(ff.sig_set), log_signal(ff.sig_clr), log_signal(ff.sig_d), log_signal(ff.sig_q)); initvals.remove_init(ff.sig_q); @@ -212,7 +212,7 @@ struct Async2syncPass : public Pass { ff.unmap_ce_srst(); log("Replacing %s.%s (%s): ALOAD=%s, AD=%s, D=%s, Q=%s\n", - log_id(module), log_id(cell), log_id(cell->type), + module, cell, cell->type, log_signal(ff.sig_aload), log_signal(ff.sig_ad), log_signal(ff.sig_d), log_signal(ff.sig_q)); initvals.remove_init(ff.sig_q); @@ -245,7 +245,7 @@ struct Async2syncPass : public Pass { ff.unmap_srst(); log("Replacing %s.%s (%s): ARST=%s, D=%s, Q=%s\n", - log_id(module), log_id(cell), log_id(cell->type), + module, cell, cell->type.unescape(), log_signal(ff.sig_arst), log_signal(ff.sig_d), log_signal(ff.sig_q)); initvals.remove_init(ff.sig_q); @@ -279,7 +279,7 @@ struct Async2syncPass : public Pass { { // Latch. log("Replacing %s.%s (%s): EN=%s, D=%s, Q=%s\n", - log_id(module), log_id(cell), log_id(cell->type), + module, cell, cell->type.unescape(), log_signal(ff.sig_aload), log_signal(ff.sig_ad), log_signal(ff.sig_q)); initvals.remove_init(ff.sig_q); diff --git a/passes/sat/clk2fflogic.cc b/passes/sat/clk2fflogic.cc index b75c8aab1..0b928ddf6 100644 --- a/passes/sat/clk2fflogic.cc +++ b/passes/sat/clk2fflogic.cc @@ -173,7 +173,7 @@ struct Clk2fflogicPass : public Pass { auto &port = mem.rd_ports[i]; if (port.clk_enable) log_error("Read port %d of memory %s.%s is clocked. This is not supported by \"clk2fflogic\"! " - "Call \"memory\" with -nordff to avoid this error.\n", i, log_id(mem.memid), log_id(module)); + "Call \"memory\" with -nordff to avoid this error.\n", i, mem.memid.unescape(), module); } for (int i = 0; i < GetSize(mem.wr_ports); i++) @@ -184,10 +184,10 @@ struct Clk2fflogicPass : public Pass { continue; log("Modifying write port %d on memory %s.%s: CLK=%s, A=%s, D=%s\n", - i, log_id(module), log_id(mem.memid), log_signal(port.clk), + i, module, mem.memid.unescape(), log_signal(port.clk), log_signal(port.addr), log_signal(port.data)); - Wire *past_clk = module->addWire(NEW_ID_SUFFIX(stringf("%s#%d#past_clk#%s", log_id(mem.memid), i, log_signal(port.clk)))); + Wire *past_clk = module->addWire(NEW_ID_SUFFIX(stringf("%s#%d#past_clk#%s", mem.memid.unescape(), i, log_signal(port.clk)))); past_clk->attributes[ID::init] = port.clk_polarity ? State::S1 : State::S0; module->addFf(NEW_ID, port.clk, past_clk); @@ -203,13 +203,13 @@ struct Clk2fflogicPass : public Pass { SigSpec clock_edge = module->Eqx(NEW_ID, {port.clk, SigSpec(past_clk)}, clock_edge_pattern); - SigSpec en_q = module->addWire(NEW_ID_SUFFIX(stringf("%s#%d#en_q", log_id(mem.memid), i)), GetSize(port.en)); + SigSpec en_q = module->addWire(NEW_ID_SUFFIX(stringf("%s#%d#en_q", mem.memid.unescape(), i)), GetSize(port.en)); module->addFf(NEW_ID, port.en, en_q); - SigSpec addr_q = module->addWire(NEW_ID_SUFFIX(stringf("%s#%d#addr_q", log_id(mem.memid), i)), GetSize(port.addr)); + SigSpec addr_q = module->addWire(NEW_ID_SUFFIX(stringf("%s#%d#addr_q", mem.memid.unescape(), i)), GetSize(port.addr)); module->addFf(NEW_ID, port.addr, addr_q); - SigSpec data_q = module->addWire(NEW_ID_SUFFIX(stringf("%s#%d#data_q", log_id(mem.memid), i)), GetSize(port.data)); + SigSpec data_q = module->addWire(NEW_ID_SUFFIX(stringf("%s#%d#data_q", mem.memid.unescape(), i)), GetSize(port.data)); module->addFf(NEW_ID, port.data, data_q); port.clk = State::S0; @@ -291,16 +291,16 @@ struct Clk2fflogicPass : public Pass { if (ff.has_clk) { log("Replacing %s.%s (%s): CLK=%s, D=%s, Q=%s\n", - log_id(module), log_id(cell), log_id(cell->type), + module, cell, cell->type.unescape(), log_signal(ff.sig_clk), log_signal(ff.sig_d), log_signal(ff.sig_q)); } else if (ff.has_aload) { log("Replacing %s.%s (%s): EN=%s, D=%s, Q=%s\n", - log_id(module), log_id(cell), log_id(cell->type), + module, cell, cell->type.unescape(), log_signal(ff.sig_aload), log_signal(ff.sig_ad), log_signal(ff.sig_q)); } else { // $sr. log("Replacing %s.%s (%s): SET=%s, CLR=%s, Q=%s\n", - log_id(module), log_id(cell), log_id(cell->type), + module, cell, cell->type.unescape(), log_signal(ff.sig_set), log_signal(ff.sig_clr), log_signal(ff.sig_q)); } diff --git a/passes/sat/cutpoint.cc b/passes/sat/cutpoint.cc index 1a68776ff..ff1ae2628 100644 --- a/passes/sat/cutpoint.cc +++ b/passes/sat/cutpoint.cc @@ -93,7 +93,7 @@ struct CutpointPass : public Pass { for (auto module : design->all_selected_modules()) { if (module->is_selected_whole()) { - log("Making all outputs of module %s cut points, removing module contents.\n", log_id(module)); + log("Making all outputs of module %s cut points, removing module contents.\n", module); module->new_connections(std::vector()); for (auto cell : vector(module->cells())) module->remove(cell); @@ -125,7 +125,7 @@ struct CutpointPass : public Pass { for (auto cell : module->selected_cells()) { if (cell->type == ID($anyseq)) continue; - log("Removing cell %s.%s, making all cell outputs cutpoints.\n", log_id(module), log_id(cell)); + log("Removing cell %s.%s, making all cell outputs cutpoints.\n", module, cell); for (auto &conn : cell->connections()) { if (cell->output(conn.first)) { bool do_cut = true; @@ -171,7 +171,7 @@ struct CutpointPass : public Pass { for (auto wire : module->selected_wires()) { if (wire->port_output) { - log("Making output wire %s.%s a cutpoint.\n", log_id(module), log_id(wire)); + log("Making output wire %s.%s a cutpoint.\n", module, wire); Wire *new_wire = module->addWire(NEW_ID, wire); module->swap_names(wire, new_wire); module->connect(new_wire, flag_undef ? Const(State::Sx, GetSize(new_wire)) : module->Anyseq(NEW_ID, GetSize(new_wire))); @@ -180,7 +180,7 @@ struct CutpointPass : public Pass { wire->port_output = false; continue; } - log("Making wire %s.%s a cutpoint.\n", log_id(module), log_id(wire)); + log("Making wire %s.%s a cutpoint.\n", module, wire); for (auto bit : sigmap(wire)) cutpoint_bits.insert(bit); } diff --git a/passes/sat/eval.cc b/passes/sat/eval.cc index b0eaaca22..a192fba9b 100644 --- a/passes/sat/eval.cc +++ b/passes/sat/eval.cc @@ -149,7 +149,7 @@ struct VlogHammerReporter for (auto c : module->cells()) if (!satgen.importCell(c)) - log_error("Failed to import cell %s (type %s) to SAT database.\n", log_id(c->name), log_id(c->type)); + log_error("Failed to import cell %s (type %s) to SAT database.\n", c->name.unescape(), c->type.unescape()); ez->assume(satgen.signals_eq(recorded_set_vars, recorded_set_vals)); @@ -262,21 +262,21 @@ struct VlogHammerReporter if (module == modules.front()) { RTLIL::SigSpec sig(wire); if (!ce.eval(sig)) - log_error("Can't read back value for port %s!\n", log_id(inputs[i])); + log_error("Can't read back value for port %s!\n", inputs[i].unescape()); input_pattern_list += stringf(" %s", sig.as_const().as_string()); - log("++PAT++ %d %s %s #\n", idx, log_id(inputs[i]), sig.as_const().as_string()); + log("++PAT++ %d %s %s #\n", idx, inputs[i].unescape(), sig.as_const().as_string()); } } if (module->wire(ID(y)) == nullptr) - log_error("No output wire (y) found in module %s!\n", log_id(module->name)); + log_error("No output wire (y) found in module %s!\n", module->name.unescape()); RTLIL::SigSpec sig(module->wire(ID(y))); RTLIL::SigSpec undef; while (!ce.eval(sig, undef)) { - // log_error("Evaluation of y in module %s failed: sig=%s, undef=%s\n", log_id(module->name), log_signal(sig), log_signal(undef)); - log_warning("Setting signal %s in module %s to undef.\n", log_signal(undef), log_id(module->name)); + // log_error("Evaluation of y in module %s failed: sig=%s, undef=%s\n", module, log_signal(sig), log_signal(undef)); + log_warning("Setting signal %s in module %s to undef.\n", log_signal(undef), module->name.unescape()); ce.set(undef, RTLIL::Const(RTLIL::State::Sx, undef.size())); } @@ -288,7 +288,7 @@ struct VlogHammerReporter sat_check(module, recorded_set_vars, recorded_set_vals, sig, true); } else if (rtl_sig.size() > 0) { if (rtl_sig.size() != sig.size()) - log_error("Output (y) has a different width in module %s compared to rtl!\n", log_id(module->name)); + log_error("Output (y) has a different width in module %s compared to rtl!\n", module->name.unescape()); for (int i = 0; i < GetSize(sig); i++) if (rtl_sig[i] == RTLIL::State::Sx) sig[i] = RTLIL::State::Sx; @@ -319,10 +319,10 @@ struct VlogHammerReporter RTLIL::IdString esc_name = RTLIL::escape_id(name); for (auto mod : modules) { if (mod->wire(esc_name) == nullptr) - log_error("Can't find input %s in module %s!\n", name, log_id(mod->name)); + log_error("Can't find input %s in module %s!\n", name, mod->name.unescape()); RTLIL::Wire *port = mod->wire(esc_name); if (!port->port_input || port->port_output) - log_error("Wire %s in module %s is not an input!\n", name, log_id(mod->name)); + log_error("Wire %s in module %s is not an input!\n", name, mod->name.unescape()); if (width >= 0 && width != port->width) log_error("Port %s has different sizes in the different modules!\n", name); width = port->width; @@ -443,7 +443,7 @@ struct EvalPass : public Pass { for (auto mod : design->selected_modules()) { if (module) log_cmd_error("Only one module must be selected for the EVAL pass! (selected: %s and %s)\n", - log_id(module->name), log_id(mod->name)); + module->name.unescape(), mod->name.unescape()); module = mod; } if (module == NULL) diff --git a/passes/sat/expose.cc b/passes/sat/expose.cc index 1e975db0f..ef00a6956 100644 --- a/passes/sat/expose.cc +++ b/passes/sat/expose.cc @@ -210,7 +210,7 @@ void create_dff_dq_map(std::map &map, RTLIL::Mo RTLIL::Wire *add_new_wire(RTLIL::Module *module, RTLIL::IdString name, int width = 1) { if (module->count_id(name)) - log_error("Attempting to create wire %s, but a wire of this name exists already! Hint: Try another value for -sep.\n", log_id(name)); + log_error("Attempting to create wire %s, but a wire of this name exists already! Hint: Try another value for -sep.\n", name.unescape()); return module->addWire(name, width); } @@ -673,7 +673,7 @@ struct ExposePass : public Pass { } for (auto cell : delete_cells) { - log("Removing cell: %s/%s (%s)\n", log_id(module), log_id(cell), log_id(cell->type)); + log("Removing cell: %s/%s (%s)\n", module, cell, cell->type.unescape()); module->remove(cell); } } diff --git a/passes/sat/fmcombine.cc b/passes/sat/fmcombine.cc index 505526c14..27a153921 100644 --- a/passes/sat/fmcombine.cc +++ b/passes/sat/fmcombine.cc @@ -77,7 +77,7 @@ struct FmcombineWorker void import_hier_cell(Cell *cell) { if (!cell->parameters.empty()) - log_cmd_error("Cell %s.%s has unresolved instance parameters.\n", log_id(original), log_id(cell)); + log_cmd_error("Cell %s.%s has unresolved instance parameters.\n", original, cell); FmcombineWorker sub_worker(design, cell->type, opts); sub_worker.generate(); @@ -95,11 +95,11 @@ struct FmcombineWorker void generate() { if (design->module(combined_type)) { - // log("Combined module %s already exists.\n", log_id(combined_type)); + // log("Combined module %s already exists.\n", combined_type.unescape()); return; } - log("Generating combined module %s from module %s.\n", log_id(combined_type), log_id(orig_type)); + log("Generating combined module %s from module %s.\n", combined_type.unescape(), orig_type.unescape()); module = design->addModule(combined_type); for (auto wire : original->wires()) { @@ -332,15 +332,15 @@ struct FmcombinePass : public Pass { module = design->module(module_name); if (module == nullptr) - log_cmd_error("Module %s not found.\n", log_id(module_name)); + log_cmd_error("Module %s not found.\n", module_name.unescape()); gold_cell = module->cell(gold_name); if (gold_cell == nullptr) - log_cmd_error("Gold cell %s not found in module %s.\n", log_id(gold_name), log_id(module)); + log_cmd_error("Gold cell %s not found in module %s.\n", gold_name.unescape(), module); gate_cell = module->cell(gate_name); if (gate_cell == nullptr) - log_cmd_error("Gate cell %s not found in module %s.\n", log_id(gate_name), log_id(module)); + log_cmd_error("Gate cell %s not found in module %s.\n", gate_name.unescape(), module); } else { @@ -363,13 +363,13 @@ struct FmcombinePass : public Pass { FmcombineWorker worker(design, gold_cell->type, opts); worker.generate(); - IdString combined_cell_name = module->uniquify(stringf("\\%s_%s", log_id(gold_cell), log_id(gate_cell))); + IdString combined_cell_name = module->uniquify(stringf("\\%s_%s", gold_cell, gate_cell)); Cell *cell = module->addCell(combined_cell_name, worker.combined_type); cell->attributes = gold_cell->attributes; cell->add_strpool_attribute(ID::src, gate_cell->get_strpool_attribute(ID::src)); - log("Combining cells %s and %s in module %s into new cell %s.\n", log_id(gold_cell), log_id(gate_cell), log_id(module), log_id(cell)); + log("Combining cells %s and %s in module %s into new cell %s.\n", gold_cell, gate_cell, module, cell); for (auto &conn : gold_cell->connections()) cell->setPort(conn.first.str() + "_gold", conn.second); diff --git a/passes/sat/formalff.cc b/passes/sat/formalff.cc index 452e0e59b..bdf673169 100644 --- a/passes/sat/formalff.cc +++ b/passes/sat/formalff.cc @@ -402,7 +402,7 @@ struct PropagateWorker sigmap.apply(bit); if (replaced_clk_bits.count(bit)) log_error("derived signal %s driven by %s (%s) from module %s is used as clock, derived clocks are only supported with clk2fflogic.\n", - log_signal(bit), log_id(cell->name), log_id(cell->type), log_id(module)); + log_signal(bit), cell->name.unescape(), cell->type.unescape(), module); } } } @@ -436,7 +436,7 @@ struct PropagateWorker if (it != replaced_clk_bits.end()) { if (it->second != polarity) log_error("signal %s from module %s is used as clock with different polarities, run clk2fflogic instead.\n", - log_signal(bit), log_id(module)); + log_signal(bit), module); return; } @@ -659,7 +659,7 @@ struct FormalFfPass : public Pass { // XXX $check $print } - log_debug("%s has %d clk bits\n", log_id(module), GetSize(clk_bits)); + log_debug("%s has %d clk bits\n", module, GetSize(clk_bits)); for (auto port : module->ports) { Wire *wire = module->wire(port); @@ -675,7 +675,7 @@ struct FormalFfPass : public Pass { } } } - log_debug("%s has %d non-input clk bits\n", log_id(module), GetSize(clk_bits)); + log_debug("%s has %d non-input clk bits\n", module, GetSize(clk_bits)); if (clk_bits.empty()) continue; @@ -687,21 +687,21 @@ struct FormalFfPass : public Pass { vector &clocked_cells = clk_bit.second; if (!clk.is_wire()) { - log_debug("constant clk bit %s.%s\n", log_id(module), log_signal(SigSpec(clk))); + log_debug("constant clk bit %s.%s\n", module, log_signal(SigSpec(clk))); continue; } if (input_bits.count(clk)) { - log_debug("input clk bit %s.%s\n", log_id(module), log_signal(SigSpec(clk))); + log_debug("input clk bit %s.%s\n", module, log_signal(SigSpec(clk))); continue; } auto found = modwalker.signal_drivers.find(clk); if (found == modwalker.signal_drivers.end() || found->second.empty()) { - log_debug("undriven clk bit %s.%s\n", log_id(module), log_signal(SigSpec(clk))); + log_debug("undriven clk bit %s.%s\n", module, log_signal(SigSpec(clk))); continue; } if (found->second.size() > 1) { - log_debug("multiple drivers for clk bit %s.%s\n", log_id(module), log_signal(SigSpec(clk))); + log_debug("multiple drivers for clk bit %s.%s\n", module, log_signal(SigSpec(clk))); continue; } @@ -711,9 +711,9 @@ struct FormalFfPass : public Pass { pol_clk ? driver.cell->type.in(ID($and), ID($_AND_)) : driver.cell->type.in(ID($or), ID($_OR_)); if (!is_gate) { - log_debug("unsupported gating logic %s.%s (%s) for clock %s %s.%s\n", log_id(module), - log_id(driver.cell), log_id(driver.cell->type), pol_clk ? "posedge" : "negedge", - log_id(module), log_signal(SigSpec(clk))); + log_debug("unsupported gating logic %s.%s (%s) for clock %s %s.%s\n", module, + driver.cell, driver.cell->type.unescape(), pol_clk ? "posedge" : "negedge", + module, log_signal(SigSpec(clk))); continue; } @@ -724,28 +724,28 @@ struct FormalFfPass : public Pass { for (int i = 0; i < 2; i++) { std::swap(gate_clock, gate_enable); - log_debug("clock %s.%s for gated clk bit %s.%s\n", log_id(module), log_signal(SigSpec(gate_clock)), - log_id(module), log_signal(SigSpec(clk))); - log_debug("enable %s.%s for gated clk bit %s.%s\n", log_id(module), log_signal(SigSpec(gate_enable)), - log_id(module), log_signal(SigSpec(clk))); + log_debug("clock %s.%s for gated clk bit %s.%s\n", module, log_signal(SigSpec(gate_clock)), + module, log_signal(SigSpec(clk))); + log_debug("enable %s.%s for gated clk bit %s.%s\n", module, log_signal(SigSpec(gate_enable)), + module, log_signal(SigSpec(clk))); found = modwalker.signal_drivers.find(gate_enable); if (found == modwalker.signal_drivers.end() || found->second.empty()) { - log_debug("undriven gate enable %s.%s of gated clk bit %s.%s\n", log_id(module), - log_signal(SigSpec(gate_enable)), log_id(module), log_signal(SigSpec(clk))); + log_debug("undriven gate enable %s.%s of gated clk bit %s.%s\n", module, + log_signal(SigSpec(gate_enable)), module, log_signal(SigSpec(clk))); continue; } if (found->second.size() > 1) { - log_debug("multiple drivers for gate enable %s.%s of gated clk bit %s.%s\n", log_id(module), - log_signal(SigSpec(gate_enable)), log_id(module), log_signal(SigSpec(clk))); + log_debug("multiple drivers for gate enable %s.%s of gated clk bit %s.%s\n", module, + log_signal(SigSpec(gate_enable)), module, log_signal(SigSpec(clk))); continue; } auto gate_driver = *found->second.begin(); if (!gate_driver.cell->is_builtin_ff()) { - log_debug("non FF driver for gate enable %s.%s of gated clk bit %s.%s\n", log_id(module), - log_signal(SigSpec(gate_enable)), log_id(module), log_signal(SigSpec(clk))); + log_debug("non FF driver for gate enable %s.%s of gated clk bit %s.%s\n", module, + log_signal(SigSpec(gate_enable)), module, log_signal(SigSpec(clk))); continue; } @@ -753,8 +753,8 @@ struct FormalFfPass : public Pass { if (ff.has_gclk || ff.has_ce || ff.has_sr || ff.has_srst || ff.has_arst || (ff.has_aload && ff.has_clk)) { log_debug( "FF driver for gate enable %s.%s of gated clk bit %s.%s has incompatible type: %s\n", - log_id(module), log_signal(SigSpec(gate_enable)), log_id(module), log_signal(SigSpec(clk)), - log_id(gate_driver.cell->type)); + module, log_signal(SigSpec(gate_enable)), module, log_signal(SigSpec(clk)), + gate_driver.cell->type.unescape()); continue; } @@ -770,8 +770,8 @@ struct FormalFfPass : public Pass { if (!ff.has_clk || sigmap(ff.sig_clk) != gate_clock || ff.pol_clk != pol_clk) { log_debug("FF driver for gate enable %s.%s of gated clk bit %s.%s has incompatible clocking: " "%s %s.%s\n", - log_id(module), log_signal(SigSpec(gate_enable)), log_id(module), - log_signal(SigSpec(clk)), ff.pol_clk ? "posedge" : "negedge", log_id(module), + module, log_signal(SigSpec(gate_enable)), module, + log_signal(SigSpec(clk)), ff.pol_clk ? "posedge" : "negedge", module, log_signal(SigSpec(ff.sig_clk))); continue; } @@ -781,8 +781,8 @@ struct FormalFfPass : public Pass { log_debug("found clock gate, rewriting %d cells\n", GetSize(clocked_cells)); for (auto clocked_cell : clocked_cells) { - log_debug("rewriting cell %s.%s (%s)\n", log_id(module), log_id(clocked_cell), - log_id(clocked_cell->type)); + log_debug("rewriting cell %s.%s (%s)\n", module, clocked_cell, + clocked_cell->type.unescape()); if (clocked_cell->is_builtin_ff()) { @@ -855,7 +855,7 @@ struct FormalFfPass : public Pass { if (ff.val_init != before) { log("Setting unused undefined initial value of %s.%s (%s) from %s to %s\n", - log_id(module), log_id(cell), log_id(cell->type), + module, cell, cell->type.unescape(), log_const(before), log_const(ff.val_init)); worker.initvals.set_init(ff.sig_q, ff.val_init); } @@ -892,10 +892,10 @@ struct FormalFfPass : public Pass { if (flag_clk2ff && ff.has_clk) { if (ff.sig_clk.is_fully_const()) log_error("Const CLK on %s (%s) from module %s, run async2sync first.\n", - log_id(cell), log_id(cell->type), log_id(module)); + cell, cell->type, module); if (ff.has_aload || ff.has_arst || ff.has_sr) log_error("Async inputs on %s (%s) from module %s, run async2sync first.\n", - log_id(cell), log_id(cell->type), log_id(module)); + cell, cell->type.unescape(), module); auto clk_wire = ff.sig_clk.is_wire() ? ff.sig_clk.as_wire() : nullptr; @@ -912,7 +912,7 @@ struct FormalFfPass : public Pass { if (!attr.empty() && attr != clk_polarity) log_error("CLK %s on %s (%s) from module %s also used with opposite polarity, run clk2fflogic instead.\n", - log_id(clk_wire), log_id(cell), log_id(cell->type), log_id(module)); + clk_wire, cell, cell->type.unescape(), module); attr = clk_polarity; clk_wire->set_bool_attribute(ID::keep); diff --git a/passes/sat/mutate.cc b/passes/sat/mutate.cc index 79ffcd88d..63a8de277 100644 --- a/passes/sat/mutate.cc +++ b/passes/sat/mutate.cc @@ -558,7 +558,7 @@ void mutate_list(Design *design, const mutate_opts_t &opts, const string &filena if (opts.none) { string str = "mutate"; if (!opts.ctrl_name.empty()) - str += stringf(" -ctrl %s %d %d", log_id(opts.ctrl_name), opts.ctrl_width, ctrl_value++); + str += stringf(" -ctrl %s %d %d", opts.ctrl_name.unescape(), opts.ctrl_width, ctrl_value++); str += " -mode none"; if (filename.empty()) log("%s\n", str); @@ -569,20 +569,20 @@ void mutate_list(Design *design, const mutate_opts_t &opts, const string &filena for (auto &entry : database) { string str = "mutate"; if (!opts.ctrl_name.empty()) - str += stringf(" -ctrl %s %d %d", log_id(opts.ctrl_name), opts.ctrl_width, ctrl_value++); + str += stringf(" -ctrl %s %d %d", opts.ctrl_name.unescape(), opts.ctrl_width, ctrl_value++); str += stringf(" -mode %s", entry.mode); if (!entry.module.empty()) - str += stringf(" -module %s", log_id(entry.module)); + str += stringf(" -module %s", entry.module.unescape()); if (!entry.cell.empty()) - str += stringf(" -cell %s", log_id(entry.cell)); + str += stringf(" -cell %s", entry.cell.unescape()); if (!entry.port.empty()) - str += stringf(" -port %s", log_id(entry.port)); + str += stringf(" -port %s", entry.port.unescape()); if (entry.portbit >= 0) str += stringf(" -portbit %d", entry.portbit); if (entry.ctrlbit >= 0) str += stringf(" -ctrlbit %d", entry.ctrlbit); if (!entry.wire.empty()) - str += stringf(" -wire %s", log_id(entry.wire)); + str += stringf(" -wire %s", entry.wire.unescape()); if (entry.wirebit >= 0) str += stringf(" -wirebit %d", entry.wirebit); for (auto &s : entry.src) @@ -600,7 +600,7 @@ SigSpec mutate_ctrl_sig(Module *module, IdString name, int width) if (ctrl_wire == nullptr) { - log("Adding ctrl port %s to module %s.\n", log_id(name), log_id(module)); + log("Adding ctrl port %s to module %s.\n", name.unescape(), module); ctrl_wire = module->addWire(name, width); ctrl_wire->port_input = true; @@ -614,7 +614,7 @@ SigSpec mutate_ctrl_sig(Module *module, IdString name, int width) SigSpec ctrl = mutate_ctrl_sig(mod, name, width); - log("Connecting ctrl port to cell %s in module %s.\n", log_id(cell), log_id(mod)); + log("Connecting ctrl port to cell %s in module %s.\n", cell, mod); cell->setPort(name, ctrl); } } @@ -652,13 +652,13 @@ void mutate_inv(Design *design, const mutate_opts_t &opts) if (cell->input(opts.port)) { - log("Add input inverter at %s.%s.%s[%d].\n", log_id(module), log_id(cell), log_id(opts.port), opts.portbit); + log("Add input inverter at %s.%s.%s[%d].\n", module, cell, opts.port.unescape(), opts.portbit); SigBit outbit = module->Not(NEW_ID, bit); bit = mutate_ctrl_mux(module, opts, bit, outbit); } else { - log("Add output inverter at %s.%s.%s[%d].\n", log_id(module), log_id(cell), log_id(opts.port), opts.portbit); + log("Add output inverter at %s.%s.%s[%d].\n", module, cell, opts.port.unescape(), opts.portbit); SigBit inbit = module->addWire(NEW_ID); SigBit outbit = module->Not(NEW_ID, inbit); module->connect(bit, mutate_ctrl_mux(module, opts, inbit, outbit)); @@ -680,13 +680,13 @@ void mutate_const(Design *design, const mutate_opts_t &opts, bool one) if (cell->input(opts.port)) { - log("Add input constant %d at %s.%s.%s[%d].\n", one ? 1 : 0, log_id(module), log_id(cell), log_id(opts.port), opts.portbit); + log("Add input constant %d at %s.%s.%s[%d].\n", one ? 1 : 0, module, cell, opts.port.unescape(), opts.portbit); SigBit outbit = one ? State::S1 : State::S0; bit = mutate_ctrl_mux(module, opts, bit, outbit); } else { - log("Add output constant %d at %s.%s.%s[%d].\n", one ? 1 : 0, log_id(module), log_id(cell), log_id(opts.port), opts.portbit); + log("Add output constant %d at %s.%s.%s[%d].\n", one ? 1 : 0, module, cell, opts.port.unescape(), opts.portbit); SigBit inbit = module->addWire(NEW_ID); SigBit outbit = one ? State::S1 : State::S0; module->connect(bit, mutate_ctrl_mux(module, opts, inbit, outbit)); @@ -709,13 +709,13 @@ void mutate_cnot(Design *design, const mutate_opts_t &opts, bool one) if (cell->input(opts.port)) { - log("Add input cnot%d at %s.%s.%s[%d,%d].\n", one ? 1 : 0, log_id(module), log_id(cell), log_id(opts.port), opts.portbit, opts.ctrlbit); + log("Add input cnot%d at %s.%s.%s[%d,%d].\n", one ? 1 : 0, module, cell, opts.port.unescape(), opts.portbit, opts.ctrlbit); SigBit outbit = one ? module->Xor(NEW_ID, bit, ctrl) : module->Xnor(NEW_ID, bit, ctrl); bit = mutate_ctrl_mux(module, opts, bit, outbit); } else { - log("Add output cnot%d at %s.%s.%s[%d,%d].\n", one ? 1 : 0, log_id(module), log_id(cell), log_id(opts.port), opts.portbit, opts.ctrlbit); + log("Add output cnot%d at %s.%s.%s[%d,%d].\n", one ? 1 : 0, module, cell, opts.port.unescape(), opts.portbit, opts.ctrlbit); SigBit inbit = module->addWire(NEW_ID); SigBit outbit = one ? module->Xor(NEW_ID, inbit, ctrl) : module->Xnor(NEW_ID, inbit, ctrl); module->connect(bit, mutate_ctrl_mux(module, opts, inbit, outbit)); @@ -947,26 +947,26 @@ struct MutatePass : public Pass { Module *module = design->module(opts.module); if (module == nullptr) - log_cmd_error("Module %s not found.\n", log_id(opts.module)); + log_cmd_error("Module %s not found.\n", opts.module.unescape()); if (opts.cell.empty()) log_cmd_error("Missing -cell argument.\n"); Cell *cell = module->cell(opts.cell); if (cell == nullptr) - log_cmd_error("Cell %s not found in module %s.\n", log_id(opts.cell), log_id(opts.module)); + log_cmd_error("Cell %s not found in module %s.\n", opts.cell.unescape(), opts.module.unescape()); if (opts.port.empty()) log_cmd_error("Missing -port argument.\n"); if (!cell->hasPort(opts.port)) - log_cmd_error("Port %s not found on cell %s.%s.\n", log_id(opts.port), log_id(opts.module), log_id(opts.cell)); + log_cmd_error("Port %s not found on cell %s.%s.\n", opts.port.unescape(), opts.module.unescape(), opts.cell.unescape()); if (opts.portbit < 0) log_cmd_error("Missing -portbit argument.\n"); if (GetSize(cell->getPort(opts.port)) <= opts.portbit) - log_cmd_error("Out-of-range -portbit argument for port %s on cell %s.%s.\n", log_id(opts.port), log_id(opts.module), log_id(opts.cell)); + log_cmd_error("Out-of-range -portbit argument for port %s on cell %s.%s.\n", opts.port.unescape(), opts.module.unescape(), opts.cell.unescape()); if (opts.mode == "inv") { mutate_inv(design, opts); @@ -982,7 +982,7 @@ struct MutatePass : public Pass { log_cmd_error("Missing -ctrlbit argument.\n"); if (GetSize(cell->getPort(opts.port)) <= opts.ctrlbit) - log_cmd_error("Out-of-range -ctrlbit argument for port %s on cell %s.%s.\n", log_id(opts.port), log_id(opts.module), log_id(opts.cell)); + log_cmd_error("Out-of-range -ctrlbit argument for port %s on cell %s.%s.\n", opts.port.unescape(), opts.module.unescape(), opts.cell.unescape()); if (opts.mode == "cnot0" || opts.mode == "cnot1") { mutate_cnot(design, opts, opts.mode == "cnot1"); diff --git a/passes/sat/qbfsat.cc b/passes/sat/qbfsat.cc index b011227e2..b892683a8 100644 --- a/passes/sat/qbfsat.cc +++ b/passes/sat/qbfsat.cc @@ -597,7 +597,7 @@ struct QbfSatPass : public Pass { RTLIL::Module *module = nullptr; for (auto mod : design->selected_modules()) { if (module) - log_cmd_error("Only one module must be selected for the QBF-SAT pass! (selected: %s and %s)\n", log_id(module), log_id(mod)); + log_cmd_error("Only one module must be selected for the QBF-SAT pass! (selected: %s and %s)\n", module, mod); module = mod; } if (module == nullptr) diff --git a/passes/sat/recover_names.cc b/passes/sat/recover_names.cc index 7939a64e0..e2c93df65 100644 --- a/passes/sat/recover_names.cc +++ b/passes/sat/recover_names.cc @@ -641,8 +641,8 @@ struct RecoverNamesWorker { for (auto gate_bit : gate_bits) { if (solved_gate.count(gate_bit.bit)) continue; - log_debug(" attempting to prove %s[%d] == %s%s[%d]\n", log_id(gold_bit.name), gold_bit.bit, - gate_bit.inverted ? "" : "!", log_id(gate_bit.bit.name), gate_bit.bit.bit); + log_debug(" attempting to prove %s[%d] == %s%s[%d]\n", gold_bit.name.unescape(), gold_bit.bit, + gate_bit.inverted ? "" : "!", gate_bit.bit.name.unescape(), gate_bit.bit.bit); if (!prove_equiv(gold_worker, gate_worker, gold_anchors, gate_anchors, gold_bit, gate_bit.bit, gate_bit.inverted)) continue; log_debug(" success!\n"); @@ -660,7 +660,7 @@ struct RecoverNamesWorker { break; } } - log("Recovered %d net name pairs in module `%s' out.\n", GetSize(gate2gold), log_id(gate_mod)); + log("Recovered %d net name pairs in module `%s' out.\n", GetSize(gate2gold), gate_mod); gate_worker.do_rename(gold_mod, gate2gold, buffer_types); } diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index 9988eef62..accfe0399 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -1369,7 +1369,7 @@ struct SatPass : public Pass { RTLIL::Module *module = NULL; for (auto mod : design->selected_modules()) { if (module) - log_cmd_error("Only one module must be selected for the SAT pass! (selected: %s and %s)\n", log_id(module), log_id(mod)); + log_cmd_error("Only one module must be selected for the SAT pass! (selected: %s and %s)\n", module, mod); module = mod; } if (module == NULL) diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 1be993154..23af70fa5 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -250,11 +250,11 @@ struct SimInstance if (module->get_blackbox_attribute(true)) log_error("Cannot simulate blackbox module %s (instantiated at %s).\n", - log_id(module->name), hiername().c_str()); + module->name.unescape(), hiername().c_str()); if (module->has_processes()) log_error("Found processes in simulation hierarchy (in module %s at %s). Run 'proc' first.\n", - log_id(module), hiername().c_str()); + module, hiername().c_str()); if (parent) { log_assert(parent->children.count(instance) == 0); @@ -413,9 +413,9 @@ struct SimInstance std::string hiername() const { if (instance != nullptr) - return parent->hiername() + "." + log_id(instance->name); + return parent->hiername() + "." + instance->name.unescape(); - return log_id(module->name); + return module->name.unescape(); } vector witness_full_path() const @@ -520,7 +520,7 @@ struct SimInstance { auto &state = mem_database[memid]; if (offset >= state.mem->size * state.mem->width) - log_error("Addressing out of bounds bit %d/%d of memory %s\n", offset, state.mem->size * state.mem->width, log_id(memid)); + log_error("Addressing out of bounds bit %d/%d of memory %s\n", offset, state.mem->size * state.mem->width, memid.unescape()); if (state.data[offset] != data) { state.data.set(offset, data); dirty_memories.insert(memid); @@ -573,7 +573,7 @@ struct SimInstance if (has_y) sig_y = cell->getPort(ID::Y); if (shared->debug) - log("[%s] eval %s (%s)\n", hiername(), log_id(cell), log_id(cell->type)); + log("[%s] eval %s (%s)\n", hiername(), cell, cell->type.unescape()); bool err = false; RTLIL::Const eval_state; @@ -593,7 +593,7 @@ struct SimInstance err = true; if (err) - log_warning("Unsupported evaluable cell type: %s (%s.%s)\n", log_id(cell->type), log_id(module), log_id(cell)); + log_warning("Unsupported evaluable cell type: %s (%s.%s)\n", cell->type.unescape(), module, cell); else set_state(sig_y, eval_state); return; @@ -602,7 +602,7 @@ struct SimInstance if (cell->type == ID($print)) return; - log_error("Unsupported cell type: %s (%s.%s)\n", log_id(cell->type), log_id(module), log_id(cell)); + log_error("Unsupported cell type: %s (%s.%s)\n", cell->type.unescape(), module, cell); } void update_memory(IdString id) { @@ -616,7 +616,7 @@ struct SimInstance Const data = Const(State::Sx, mem.width << port.wide_log2); if (port.clk_enable) - log_error("Memory %s.%s has clocked read ports. Run 'memory_nordff' to transform the circuit to remove those.\n", log_id(module), log_id(mem.memid)); + log_error("Memory %s.%s has clocked read ports. Run 'memory_nordff' to transform the circuit to remove those.\n", module, mem.memid.unescape()); if (addr.is_fully_def()) { int addr_int = addr.as_int(); @@ -819,14 +819,14 @@ struct SimInstance log_assert(cell->module == module); bool has_src = cell->has_attribute(ID::src); log("%s %s%s\n", opening_verbiage, - log_id(cell), has_src ? " at" : ""); + cell, has_src ? " at" : ""); log_source(cell); struct SimInstance *sim = this; while (sim->instance) { has_src = sim->instance->has_attribute(ID::src); - log(" in instance %s of module %s%s\n", log_id(sim->instance), - log_id(sim->instance->type), has_src ? " at" : ""); + log(" in instance %s of module %s%s\n", sim->instance, + sim->instance->type.unescape(), has_src ? " at" : ""); log_source(sim->instance); sim = sim->parent; } @@ -927,7 +927,7 @@ struct SimInstance { for (auto cell : formal_database) { - string label = log_id(cell); + string label = cell->name.unescape(); if (cell->attributes.count(ID::src)) label = cell->attributes.at(ID::src).decode_string(); @@ -939,17 +939,17 @@ struct SimInstance } if (cell->type == ID($cover) && en == State::S1 && a == State::S1) - log("Cover %s.%s (%s) reached.\n", hiername(), log_id(cell), label); + log("Cover %s.%s (%s) reached.\n", hiername(), cell, label); if (cell->type == ID($assume) && en == State::S1 && a != State::S1) - log("Assumption %s.%s (%s) failed.\n", hiername(), log_id(cell), label); + log("Assumption %s.%s (%s) failed.\n", hiername(), cell, label); if (cell->type == ID($assert) && en == State::S1 && a != State::S1) { log_cell_w_hierarchy("Failed assertion", cell); if (shared->serious_asserts) - log_error("Assertion %s.%s (%s) failed.\n", hiername(), log_id(cell), label); + log_error("Assertion %s.%s (%s) failed.\n", hiername(), cell, label); else - log_warning("Assertion %s.%s (%s) failed.\n", hiername(), log_id(cell), label); + log_warning("Assertion %s.%s (%s) failed.\n", hiername(), cell, label); } } } @@ -970,7 +970,7 @@ struct SimInstance { if (!ff_database.empty() || !mem_database.empty()) { if (wbmods.count(module)) - log_error("Instance %s of module %s is not unique: Writeback not possible. (Fix by running 'uniquify'.)\n", hiername(), log_id(module)); + log_error("Instance %s of module %s is not unique: Writeback not possible. (Fix by running 'uniquify'.)\n", hiername(), module); wbmods.insert(module); } @@ -1061,7 +1061,7 @@ struct SimInstance for (auto name : hdlname) exit_scope(); } else - register_signal(log_id(signal.first->name), GetSize(signal.first), signal.first, signal.second.id, registers.count(signal.first)!=0); + register_signal(signal.first->name.unescape().c_str(), GetSize(signal.first), signal.first, signal.second.id, registers.count(signal.first)!=0); } for (auto &trace_mem : trace_mem_database) @@ -1082,7 +1082,7 @@ struct SimInstance for (auto name : hdlname) enter_scope("\\" + name); } else { - signal_name = log_id(memid); + signal_name = memid.unescape(); } for (auto &trace_index : trace_mem.second) { @@ -1269,13 +1269,13 @@ struct SimInstance Const fst_val = Const::from_string(shared->fst->valueOf(item.second)); Const sim_val = get_state(item.first); if (sim_val.size()!=fst_val.size()) { - log_warning("Signal '%s.%s' size is different in gold and gate.\n", scope, log_id(item.first)); + log_warning("Signal '%s.%s' size is different in gold and gate.\n", scope, item.first); continue; } if (shared->sim_mode == SimulationMode::gate && !fst_val.is_fully_def()) { // FST data contains X for(int i=0;isim_mode == SimulationMode::gold && !sim_val.is_fully_def()) { // sim data contains X for(int i=0;imodule->wire(portname); if (w == nullptr) - log_error("Can't find port %s on module %s.\n", log_id(portname), log_id(top->module)); + log_error("Can't find port %s on module %s.\n", portname.unescape(), top->module); top->set_state(w, value); } @@ -1492,24 +1492,24 @@ struct SimWorker : SimShared { Wire *w = topmod->wire(portname); if (!w) - log_error("Can't find port %s on module %s.\n", log_id(portname), log_id(top->module)); + log_error("Can't find port %s on module %s.\n", portname.unescape(), top->module); if (!w->port_input) - log_error("Clock port %s on module %s is not input.\n", log_id(portname), log_id(top->module)); + log_error("Clock port %s on module %s is not input.\n", portname.unescape(), top->module); fstHandle id = fst->getHandle(scope + "." + RTLIL::unescape_id(portname)); if (id==0) - log_error("Can't find port %s.%s in FST.\n", scope, log_id(portname)); + log_error("Can't find port %s.%s in FST.\n", scope, portname.unescape()); fst_clock.push_back(id); } for (auto portname : clockn) { Wire *w = topmod->wire(portname); if (!w) - log_error("Can't find port %s on module %s.\n", log_id(portname), log_id(top->module)); + log_error("Can't find port %s on module %s.\n", portname.unescape(), top->module); if (!w->port_input) - log_error("Clock port %s on module %s is not input.\n", log_id(portname), log_id(top->module)); + log_error("Clock port %s on module %s is not input.\n", portname.unescape(), top->module); fstHandle id = fst->getHandle(scope + "." + RTLIL::unescape_id(portname)); if (id==0) - log_error("Can't find port %s.%s in FST.\n", scope, log_id(portname)); + log_error("Can't find port %s.%s in FST.\n", scope, portname.unescape()); fst_clock.push_back(id); } @@ -1630,7 +1630,7 @@ struct SimWorker : SimShared escaped_s = RTLIL::escape_id(cell_name(symbol)); Cell *c = topmod->cell(escaped_s); if (!c) - log_warning("Wire/cell %s not present in module %s\n",symbol,log_id(topmod)); + log_warning("Wire/cell %s not present in module %s\n",symbol,topmod); if (c->is_mem_cell()) { std::string memid = c->parameters.at(ID::MEMID).decode_string(); @@ -1829,7 +1829,7 @@ struct SimWorker : SimShared if (!w) { Cell *c = topmod->cell(escaped_s); if (!c) - log_warning("Wire/cell %s not present in module %s\n",log_id(escaped_s),log_id(topmod)); + log_warning("Wire/cell %s not present in module %s\n",escaped_s.unescape(),topmod); else if (c->type.in(ID($anyconst), ID($anyseq))) { SigSpec sig_y= c->getPort(ID::Y); if ((int)parts[1].size() != GetSize(sig_y)) @@ -1844,9 +1844,9 @@ struct SimWorker : SimShared } else { Cell *c = topmod->cell(escaped_s); if (!c) - log_error("Cell %s not present in module %s\n",log_id(escaped_s),log_id(topmod)); + log_error("Cell %s not present in module %s\n",escaped_s.unescape(),topmod); if (!c->is_mem_cell()) - log_error("Cell %s is not memory cell in module %s\n",log_id(escaped_s),log_id(topmod)); + log_error("Cell %s is not memory cell in module %s\n",escaped_s.unescape(),topmod); Const addr = Const::from_string(parts[1].substr(1,parts[1].size()-2)); Const data = Const::from_string(parts[2]); @@ -2077,13 +2077,13 @@ struct SimWorker : SimShared json.entry("version", "Yosys sim summary"); json.entry("generator", yosys_maybe_version()); json.entry("steps", step); - json.entry("top", log_id(top->module->name)); + json.entry("top", top->module->name.unescape()); json.name("assertions"); json.begin_array(); for (auto &assertion : triggered_assertions) { json.begin_object(); json.entry("step", assertion.step); - json.entry("type", log_id(assertion.cell->type)); + json.entry("type", assertion.cell->type.unescape()); json.entry("path", assertion.instance->witness_full_path(assertion.cell)); auto src = assertion.cell->get_string_attribute(ID::src); if (!src.empty()) { @@ -2148,12 +2148,12 @@ struct SimWorker : SimShared { Wire *w = topmod->wire(portname); if (!w) - log_error("Can't find port %s on module %s.\n", log_id(portname), log_id(top->module)); + log_error("Can't find port %s on module %s.\n", portname.unescape(), top->module); if (!w->port_input) - log_error("Clock port %s on module %s is not input.\n", log_id(portname), log_id(top->module)); + log_error("Clock port %s on module %s is not input.\n", portname.unescape(), top->module); fstHandle id = fst->getHandle(scope + "." + RTLIL::unescape_id(portname)); if (id==0) - log_error("Can't find port %s.%s in FST.\n", scope, log_id(portname)); + log_error("Can't find port %s.%s in FST.\n", scope, portname.unescape()); fst_clock.push_back(id); clocks[w] = id; } @@ -2161,12 +2161,12 @@ struct SimWorker : SimShared { Wire *w = topmod->wire(portname); if (!w) - log_error("Can't find port %s on module %s.\n", log_id(portname), log_id(top->module)); + log_error("Can't find port %s on module %s.\n", portname.unescape(), top->module); if (!w->port_input) - log_error("Clock port %s on module %s is not input.\n", log_id(portname), log_id(top->module)); + log_error("Clock port %s on module %s is not input.\n", portname.unescape(), top->module); fstHandle id = fst->getHandle(scope + "." + RTLIL::unescape_id(portname)); if (id==0) - log_error("Can't find port %s.%s in FST.\n", scope, log_id(portname)); + log_error("Can't find port %s.%s in FST.\n", scope, portname.unescape()); fst_clock.push_back(id); clocks[w] = id; } @@ -2359,7 +2359,7 @@ struct VCDWriter : public OutputWriter vcdfile << stringf("$timescale %s $end\n", worker->timescale); worker->top->write_output_header( - [this](IdString name) { vcdfile << stringf("$scope module %s $end\n", log_id(name)); }, + [this](IdString name) { vcdfile << stringf("$scope module %s $end\n", name.unescape()); }, [this]() { vcdfile << stringf("$upscope $end\n");}, [this,use_signal](const char *name, int size, Wire *w, int id, bool is_reg) { if (!use_signal.at(id)) return; @@ -2425,7 +2425,7 @@ struct FSTWriter : public OutputWriter fstWriterSetRepackOnClose(fstfile, 1); worker->top->write_output_header( - [this](IdString name) { fstWriterSetScope(fstfile, FST_ST_VCD_MODULE, stringf("%s",log_id(name)).c_str(), nullptr); }, + [this](IdString name) { fstWriterSetScope(fstfile, FST_ST_VCD_MODULE, stringf("%s",name.unescape()).c_str(), nullptr); }, [this]() { fstWriterSetUpscope(fstfile); }, [this,use_signal](const char *name, int size, Wire *w, int id, bool is_reg) { if (!use_signal.at(id)) return; @@ -2488,7 +2488,7 @@ struct AIWWriter : public OutputWriter RTLIL::IdString escaped_s = RTLIL::escape_id(symbol); Wire *w = worker->top->module->wire(escaped_s); if (!w) - log_error("Wire %s not present in module %s\n",log_id(escaped_s),log_id(worker->top->module)); + log_error("Wire %s not present in module %s\n",escaped_s.unescape(),worker->top->module); if (index < w->start_offset || index > w->start_offset + w->width) log_error("Index %d for wire %s is out of range\n", index, log_signal(w)); if (type == "input") { diff --git a/passes/sat/supercover.cc b/passes/sat/supercover.cc index f1b3ad09c..a2192dc8a 100644 --- a/passes/sat/supercover.cc +++ b/passes/sat/supercover.cc @@ -64,7 +64,7 @@ struct SupercoverPass : public Pass { pool handled_bits; int cnt_wire = 0, cnt_bits = 0; - log("Adding cover cells to module %s.\n", log_id(module)); + log("Adding cover cells to module %s.\n", module); for (auto wire : module->selected_wires()) { bool counted_wire = false; diff --git a/passes/sat/synthprop.cc b/passes/sat/synthprop.cc index d94b4a7f7..a54eef199 100644 --- a/passes/sat/synthprop.cc +++ b/passes/sat/synthprop.cc @@ -60,20 +60,20 @@ struct SynthPropWorker void SynthPropWorker::tracing(RTLIL::Module *mod, int depth, TrackingData &tracing_data, std::string hier_path) { - log("%*sTracing in module %s..\n", 2*depth, "", log_id(mod)); + log("%*sTracing in module %s..\n", 2*depth, "", mod); tracing_data[mod] = TrackingItem(); int cnt = 0; for (auto cell : mod->cells()) { if (cell->type == ID($assert)) { - log("%*sFound assert %s..\n", 2*(depth+1), "", log_id(cell)); + log("%*sFound assert %s..\n", 2*(depth+1), "", cell); tracing_data[mod].assertion_cells.emplace(cell); if (!or_outputs) { - tracing_data[mod].names.push_back(hier_path + "." + log_id(cell)); + tracing_data[mod].names.push_back(hier_path + "." + cell->name.unescape()); } cnt++; } else if (RTLIL::Module *submod = design->module(cell->type)) { - tracing(submod, depth+1, tracing_data, hier_path + "." + log_id(cell)); + tracing(submod, depth+1, tracing_data, hier_path + "." + cell->name.unescape()); if (!or_outputs) { for (size_t i = 0; i < tracing_data[submod].names.size(); i++) tracing_data[mod].names.push_back(tracing_data[submod].names[i]); @@ -93,7 +93,7 @@ void SynthPropWorker::run() log_error("Module is not TOP module\n"); TrackingData tracing_data; - tracing(module, 0, tracing_data, log_id(module->name)); + tracing(module, 0, tracing_data, module->name.unescape()); for (auto &data : tracing_data) { if (data.second.names.size() == 0) continue; diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index 71c238ec7..e26dbf34f 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -2427,7 +2427,7 @@ struct AbcPass : public Pass { for (auto mod : design->selected_modules()) { if (mod->processes.size() > 0) { - log("Skipping module %s as it contains processes.\n", log_id(mod)); + log("Skipping module %s as it contains processes.\n", mod); continue; } diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 90c48ae34..309365a11 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -386,7 +386,7 @@ struct Abc9Pass : public ScriptPass for (auto mod : selected_modules) { if (mod->processes.size() > 0) { - log("Skipping module %s as it contains processes.\n", log_id(mod)); + log("Skipping module %s as it contains processes.\n", mod); continue; } @@ -395,7 +395,7 @@ struct Abc9Pass : public ScriptPass // this check does nothing because the above line adds the whole module to the selection if (!active_design->selected_whole_module(mod)) - log_error("Can't handle partially selected module %s!\n", log_id(mod)); + log_error("Can't handle partially selected module %s!\n", mod); std::string tempdir_name; if (cleanup) @@ -416,7 +416,7 @@ struct Abc9Pass : public ScriptPass log("Extracted %d AND gates and %d wires from module `%s' to a netlist network with %d inputs and %d outputs.\n", active_design->scratchpad_get_int("write_xaiger.num_ands"), active_design->scratchpad_get_int("write_xaiger.num_wires"), - log_id(mod), + mod, active_design->scratchpad_get_int("write_xaiger.num_inputs"), num_outputs); if (num_outputs) { @@ -429,7 +429,7 @@ struct Abc9Pass : public ScriptPass else abc9_exe_cmd += stringf(" -box %s", box_file); run_nocheck(abc9_exe_cmd); - run_nocheck(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod), tempdir_name, tempdir_name)); + run_nocheck(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", mod, tempdir_name, tempdir_name)); run_nocheck(stringf("abc9_ops -reintegrate %s", dff_mode ? "-dff" : "")); } else diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index e7cf8c637..d6cf731f1 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -48,7 +48,7 @@ void check(RTLIL::Design *design, bool dff_mode) auto r = box_lookup.insert(std::make_pair(stringf("$__boxid%d", id), m->name)); if (!r.second) log_error("Module '%s' has the same abc9_box_id = %d value as '%s'.\n", - log_id(m), id, log_id(r.first->second)); + m, id, r.first->second.unescape()); } // Make carry in the last PI, and carry out the last PO @@ -60,21 +60,21 @@ void check(RTLIL::Design *design, bool dff_mode) if (w->get_bool_attribute(ID::abc9_carry)) { if (w->port_input) { if (carry_in != IdString()) - log_error("Module '%s' contains more than one (* abc9_carry *) input port.\n", log_id(m)); + log_error("Module '%s' contains more than one (* abc9_carry *) input port.\n", m); carry_in = port_name; } if (w->port_output) { if (carry_out != IdString()) - log_error("Module '%s' contains more than one (* abc9_carry *) output port.\n", log_id(m)); + log_error("Module '%s' contains more than one (* abc9_carry *) output port.\n", m); carry_out = port_name; } } } if (carry_in != IdString() && carry_out == IdString()) - log_error("Module '%s' contains an (* abc9_carry *) input port but no output port.\n", log_id(m)); + log_error("Module '%s' contains an (* abc9_carry *) input port but no output port.\n", m); if (carry_in == IdString() && carry_out != IdString()) - log_error("Module '%s' contains an (* abc9_carry *) output port but no input port.\n", log_id(m)); + log_error("Module '%s' contains an (* abc9_carry *) output port but no input port.\n", m); if (flop) { int num_outputs = 0; @@ -83,7 +83,7 @@ void check(RTLIL::Design *design, bool dff_mode) if (wire->port_output) num_outputs++; } if (num_outputs != 1) - log_error("Module '%s' with (* abc9_flop *) has %d outputs (expect 1).\n", log_id(m), num_outputs); + log_error("Module '%s' with (* abc9_flop *) has %d outputs (expect 1).\n", m, num_outputs); } } @@ -121,7 +121,7 @@ void check(RTLIL::Design *design, bool dff_mode) if (!derived_module->get_bool_attribute(ID::abc9_flop)) continue; if (derived_module->get_blackbox_attribute(true /* ignore_wb */)) - log_error("Module '%s' with (* abc9_flop *) is a blackbox.\n", log_id(derived_type)); + log_error("Module '%s' with (* abc9_flop *) is a blackbox.\n", derived_type.unescape()); if (derived_module->has_processes()) Pass::call_on_module(design, derived_module, "proc -noopt"); @@ -130,20 +130,20 @@ void check(RTLIL::Design *design, bool dff_mode) for (auto derived_cell : derived_module->cells()) { if (derived_cell->type.in(ID($dff), ID($_DFF_N_), ID($_DFF_P_))) { if (found) - log_error("Whitebox '%s' with (* abc9_flop *) contains more than one $_DFF_[NP]_ cell.\n", log_id(derived_module)); + log_error("Whitebox '%s' with (* abc9_flop *) contains more than one $_DFF_[NP]_ cell.\n", derived_module); found = true; SigBit Q = derived_cell->getPort(ID::Q); log_assert(GetSize(Q.wire) == 1); if (!Q.wire->port_output) - log_error("Whitebox '%s' with (* abc9_flop *) contains a %s cell where its 'Q' port does not drive a module output.\n", log_id(derived_module), log_id(derived_cell->type)); + log_error("Whitebox '%s' with (* abc9_flop *) contains a %s cell where its 'Q' port does not drive a module output.\n", derived_module, derived_cell->type.unescape()); Const init = Q.wire->attributes.at(ID::init, State::Sx); log_assert(GetSize(init) == 1); } else if (unsupported.count(derived_cell->type)) - log_error("Whitebox '%s' with (* abc9_flop *) contains a %s cell, which is not supported for sequential synthesis.\n", log_id(derived_module), log_id(derived_cell->type)); + log_error("Whitebox '%s' with (* abc9_flop *) contains a %s cell, which is not supported for sequential synthesis.\n", derived_module, derived_cell->type.unescape()); } } } @@ -217,7 +217,7 @@ void prep_hier(RTLIL::Design *design, bool dff_mode) // Block sequential synthesis on cells with (* init *) != 1'b0 // because ABC9 doesn't support them if (init != State::S0) { - log_warning("Whitebox '%s' with (* abc9_flop *) contains a %s cell with non-zero initial state -- this is not supported for ABC9 sequential synthesis. Treating as a blackbox.\n", log_id(derived_module), log_id(derived_cell->type)); + log_warning("Whitebox '%s' with (* abc9_flop *) contains a %s cell with non-zero initial state -- this is not supported for ABC9 sequential synthesis. Treating as a blackbox.\n", derived_module, derived_cell->type.unescape()); derived_module->set_bool_attribute(ID::abc9_flop, false); } break; @@ -474,7 +474,7 @@ void prep_dff(RTLIL::Design *design) // be instantiating the derived module which will have had any parameters constant-propagated. // This task is expected to be performed by `abc9_ops -prep_hier`, but it looks like it failed to do so for this design. // Please file a bug report! - log_error("Not expecting parameters on cell '%s' instantiating module '%s' marked (* abc9_flop *)\n", log_id(cell->name), log_id(cell->type)); + log_error("Not expecting parameters on cell '%s' instantiating module '%s' marked (* abc9_flop *)\n", cell->name.unescape(), cell->type.unescape()); } modules_sel.select(inst_module); } @@ -621,7 +621,7 @@ void prep_delays(RTLIL::Design *design, bool dff_mode) std::vector cells; for (auto module : design->selected_modules()) { if (module->processes.size() > 0) { - log("Skipping module %s as it contains processes.\n", log_id(module)); + log("Skipping module %s as it contains processes.\n", module); continue; } @@ -669,7 +669,7 @@ void prep_delays(RTLIL::Design *design, bool dff_mode) auto port_wire = inst_module->wire(i.first.name); if (!port_wire) log_error("Port %s in cell %s (type %s) from module %s does not actually exist", - log_id(i.first.name), log_id(cell), log_id(cell->type), log_id(module)); + i.first.name.unescape(), cell, cell->type.unescape(), module); log_assert(port_wire->port_input); auto d = i.second.first; @@ -688,7 +688,7 @@ void prep_delays(RTLIL::Design *design, bool dff_mode) if (ys_debug(1)) { static pool> seen; if (seen.emplace(cell->type, i.first).second) log("%s.%s[%d] abc9_required = %d\n", - log_id(cell->type), log_id(i.first.name), offset, d); + cell->type.unescape(), i.first.name.unescape(), offset, d); } #endif auto r = box_cache.insert(d); @@ -848,7 +848,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff) for (auto cell_name : it) { auto cell = module->cell(cell_name); log_assert(cell); - log("\t%s (%s @ %s)\n", log_id(cell), log_id(cell->type), cell->get_src_attribute()); + log("\t%s (%s @ %s)\n", cell, cell->type.unescape(), cell->get_src_attribute()); } } } @@ -882,7 +882,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff) // be instantiating the derived module which will have had any parameters constant-propagated. // This task is expected to be performed by `abc9_ops -prep_hier`, but it looks like it failed to do so for this design. // Please file a bug report! - log_error("Not expecting parameters on cell '%s' instantiating module '%s' marked (* abc9_box *)\n", log_id(cell_name), log_id(cell->type)); + log_error("Not expecting parameters on cell '%s' instantiating module '%s' marked (* abc9_box *)\n", cell_name.unescape(), cell->type.unescape()); } log_assert(box_module->get_blackbox_attribute()); @@ -917,7 +917,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff) } } else if (w->port_output) - conn = holes_module->addWire(stringf("%s.%s", cell->type, log_id(port_name)), GetSize(w)); + conn = holes_module->addWire(stringf("%s.%s", cell->type, port_name.unescape()), GetSize(w)); } } else // box_module is a blackbox @@ -929,7 +929,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff) log_assert(w); if (!w->port_output) continue; - Wire *holes_wire = holes_module->addWire(stringf("$abc%s.%s", cell->name, log_id(port_name)), GetSize(w)); + Wire *holes_wire = holes_module->addWire(stringf("$abc%s.%s", cell->name, port_name.unescape()), GetSize(w)); holes_wire->port_output = true; holes_wire->port_id = port_id++; holes_module->ports.push_back(holes_wire->name); @@ -965,12 +965,12 @@ void prep_lut(RTLIL::Design *design, int maxlut) if (o == TimingInfo::NameBit()) o = d; else if (o != d) - log_error("Module '%s' with (* abc9_lut *) has more than one output.\n", log_id(module)); + log_error("Module '%s' with (* abc9_lut *) has more than one output.\n", module); delays.push_back(i.second); } if (GetSize(delays) == 0) - log_error("Module '%s' with (* abc9_lut *) has no specify entries.\n", log_id(module)); + log_error("Module '%s' with (* abc9_lut *) has no specify entries.\n", module); if (maxlut && GetSize(delays) > maxlut) continue; // ABC requires non-decreasing LUT input delays @@ -981,9 +981,9 @@ void prep_lut(RTLIL::Design *design, int maxlut) auto r = table.emplace(K, entry); if (!r.second) { if (r.first->second.area != entry.area) - log_error("Modules '%s' and '%s' have conflicting (* abc9_lut *) values.\n", log_id(module), log_id(r.first->second.name)); + log_error("Modules '%s' and '%s' have conflicting (* abc9_lut *) values.\n", module, r.first->second.name.unescape()); if (r.first->second.delays != entry.delays) - log_error("Modules '%s' and '%s' have conflicting specify entries.\n", log_id(module), log_id(r.first->second.name)); + log_error("Modules '%s' and '%s' have conflicting specify entries.\n", module, r.first->second.name.unescape()); } } @@ -1002,7 +1002,7 @@ void prep_lut(RTLIL::Design *design, int maxlut) ss << std::endl; } for (const auto &i : table) { - ss << "# " << log_id(i.second.name) << std::endl; + ss << "# " << i.second.name.unescape() << std::endl; ss << i.first << " " << i.second.area; for (const auto &j : i.second.delays) ss << " " << j; @@ -1046,7 +1046,7 @@ void prep_box(RTLIL::Design *design) } log_assert(num_outputs == 1); - ss << log_id(module) << " " << r.first->second.as_int(); + ss << module->name.unescape() << " " << r.first->second.as_int(); log_assert(module->get_bool_attribute(ID::whitebox)); ss << " " << "1"; ss << " " << num_inputs << " " << num_outputs << std::endl; @@ -1061,13 +1061,13 @@ void prep_box(RTLIL::Design *design) first = false; else ss << " "; - ss << log_id(wire); + ss << wire->name.unescape(); } ss << std::endl; auto &t = timing.setup_module(module).required; if (t.empty()) - log_error("Module '%s' with (* abc9_flop *) has no clk-to-q timing (and thus no connectivity) information.\n", log_id(module)); + log_error("Module '%s' with (* abc9_flop *) has no clk-to-q timing (and thus no connectivity) information.\n", module); first = true; for (auto port_name : module->ports) { @@ -1089,8 +1089,8 @@ void prep_box(RTLIL::Design *design) #ifndef NDEBUG if (ys_debug(1)) { static std::set> seen; - if (seen.emplace(module->name, port_name).second) log("%s.%s abc9_required = %d\n", log_id(module), - log_id(port_name), it->second.first); + if (seen.emplace(module->name, port_name).second) log("%s.%s abc9_required = %d\n", module, + port_name.unescape(), it->second.first); } #endif } @@ -1135,7 +1135,7 @@ void prep_box(RTLIL::Design *design) outputs.emplace_back(wire, i); } - ss << log_id(module) << " " << module->attributes.at(ID::abc9_box_id).as_int(); + ss << module->name.unescape() << " " << module->attributes.at(ID::abc9_box_id).as_int(); bool has_model = module->get_bool_attribute(ID::whitebox) || !module->get_bool_attribute(ID::blackbox); ss << " " << (has_model ? "1" : "0"); ss << " " << GetSize(inputs) << " " << GetSize(outputs) << std::endl; @@ -1148,15 +1148,15 @@ void prep_box(RTLIL::Design *design) else ss << " "; if (GetSize(i.wire) == 1) - ss << log_id(i.wire); + ss << i.wire->name.unescape(); else - ss << log_id(i.wire) << "[" << i.offset << "]"; + ss << i.wire->name.unescape() << "[" << i.offset << "]"; } ss << std::endl; auto &t = timing.setup_module(module); if (t.comb.empty() && !outputs.empty() && !inputs.empty()) { - log_error("Module '%s' with (* abc9_box *) has no timing (and thus no connectivity) information.\n", log_id(module)); + log_error("Module '%s' with (* abc9_box *) has no timing (and thus no connectivity) information.\n", module); } for (const auto &o : outputs) { @@ -1174,9 +1174,9 @@ void prep_box(RTLIL::Design *design) } ss << " # "; if (GetSize(o.wire) == 1) - ss << log_id(o.wire); + ss << o.wire->name.unescape(); else - ss << log_id(o.wire) << "[" << o.offset << "]"; + ss << o.wire->name.unescape() << "[" << o.offset << "]"; ss << std::endl; } ss << std::endl; @@ -1206,7 +1206,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode) RTLIL::Module *mapped_mod = design->module(stringf("%s$abc9", module->name)); if (mapped_mod == NULL) - log_error("ABC output file does not contain a module `%s$abc'.\n", log_id(module)); + log_error("ABC output file does not contain a module `%s$abc'.\n", module); for (auto w : mapped_mod->wires()) { auto nw = module->addWire(remap_name(w->name), GetSize(w)); @@ -1387,7 +1387,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode) else { RTLIL::Cell *existing_cell = module->cell(mapped_cell->name); if (!existing_cell) - log_error("Cannot find existing box cell with name '%s' in original design.\n", log_id(mapped_cell)); + log_error("Cannot find existing box cell with name '%s' in original design.\n", mapped_cell); if (existing_cell->type.begins_with("$paramod$__ABC9_DELAY\\DELAY=")) { SigBit I = mapped_cell->getPort(ID(i)); @@ -1924,12 +1924,12 @@ struct Abc9OpsPass : public Pass { for (auto mod : design->selected_modules()) { if (mod->processes.size() > 0) { - log("Skipping module %s as it contains processes.\n", log_id(mod)); + log("Skipping module %s as it contains processes.\n", mod); continue; } if (!design->selected_whole_module(mod)) - log_error("Can't handle partially selected module %s!\n", log_id(mod)); + log_error("Can't handle partially selected module %s!\n", mod); if (!write_lut_dst.empty()) write_lut(mod, write_lut_dst); diff --git a/passes/techmap/abc_new.cc b/passes/techmap/abc_new.cc index 9850ff609..0a312fb77 100644 --- a/passes/techmap/abc_new.cc +++ b/passes/techmap/abc_new.cc @@ -178,7 +178,7 @@ struct AbcNewPass : public ScriptPass { tmpdir = make_temp_dir(tmpdir); modname = mod->name.str(); exe_options = abc_exe_options; - log_header(active_design, "Mapping module '%s'.\n", log_id(mod)); + log_header(active_design, "Mapping module '%s'.\n", mod); log_push(); active_design->select(mod); } diff --git a/passes/techmap/aigmap.cc b/passes/techmap/aigmap.cc index 19e568a61..6b7e0c377 100644 --- a/passes/techmap/aigmap.cc +++ b/passes/techmap/aigmap.cc @@ -150,21 +150,21 @@ struct AigmapPass : public Pass { if (not_replaced_count == 0 && replaced_cells.empty()) continue; - log("Module %s: replaced %d cells with %d new cells, skipped %d cells.\n", log_id(module), + log("Module %s: replaced %d cells with %d new cells, skipped %d cells.\n", module, GetSize(replaced_cells), GetSize(module->cells()) - orig_num_cells, not_replaced_count); if (!stat_replaced.empty()) { stat_replaced.sort(); log(" replaced %d cell types:\n", GetSize(stat_replaced)); for (auto &it : stat_replaced) - log("%8d %s\n", it.second, log_id(it.first)); + log("%8d %s\n", it.second, it.first.unescape()); } if (!stat_not_replaced.empty()) { stat_not_replaced.sort(); log(" not replaced %d cell types:\n", GetSize(stat_not_replaced)); for (auto &it : stat_not_replaced) - log("%8d %s\n", it.second, log_id(it.first)); + log("%8d %s\n", it.second, it.first.unescape()); } for (auto cell : replaced_cells) diff --git a/passes/techmap/alumacc.cc b/passes/techmap/alumacc.cc index 10f93d925..5cce8c0ee 100644 --- a/passes/techmap/alumacc.cc +++ b/passes/techmap/alumacc.cc @@ -156,7 +156,7 @@ struct AlumaccWorker if (!cell->type.in(ID($pos), ID($neg), ID($add), ID($sub), ID($mul))) continue; - log(" creating $macc model for %s (%s).\n", log_id(cell), log_id(cell->type)); + log(" creating $macc model for %s (%s).\n", cell, cell->type.unescape()); maccnode_t *n = new maccnode_t; Macc::term_t new_term; @@ -267,7 +267,7 @@ struct AlumaccWorker if (GetSize(other_n->y) != GetSize(n->y) && macc_may_overflow(other_n->macc, GetSize(other_n->y), port.is_signed)) continue; - log(" merging $macc model for %s into %s.\n", log_id(other_n->cell), log_id(n->cell)); + log(" merging $macc model for %s into %s.\n", other_n->cell, n->cell); bool do_subtract = port.do_subtract; for (int j = 0; j < GetSize(other_n->macc.terms); j++) { @@ -351,7 +351,7 @@ struct AlumaccWorker if (!subtract_b && B < A && GetSize(B)) std::swap(A, B); - log(" creating $alu model for $macc %s.\n", log_id(n->cell)); + log(" creating $alu model for $macc %s.\n", n->cell); alunode = new alunode_t; alunode->cells.push_back(n->cell); @@ -383,7 +383,7 @@ struct AlumaccWorker macc_counter++; - log(" creating $macc cell for %s: %s\n", log_id(n->cell), log_id(cell)); + log(" creating $macc cell for %s: %s\n", n->cell, cell); cell->set_src_attribute(n->cell->get_src_attribute()); @@ -412,7 +412,7 @@ struct AlumaccWorker for (auto cell : lge_cells) { - log(" creating $alu model for %s (%s):", log_id(cell), log_id(cell->type)); + log(" creating $alu model for %s (%s):", cell, cell->type.unescape()); bool cmp_less = cell->type.in(ID($lt), ID($le)); bool cmp_equal = cell->type.in(ID($le), ID($ge)); @@ -451,7 +451,7 @@ struct AlumaccWorker sig_alu[RTLIL::SigSig(A, B)].insert(n); log(" new $alu\n"); } else { - log(" merged with %s.\n", log_id(n->cells.front())); + log(" merged with %s.\n", n->cells.front()); } n->cells.push_back(cell); @@ -484,7 +484,7 @@ struct AlumaccWorker } if (n != nullptr) { - log(" creating $alu model for %s (%s): merged with %s.\n", log_id(cell), log_id(cell->type), log_id(n->cells.front())); + log(" creating $alu model for %s (%s): merged with %s.\n", cell, cell->type.unescape(), n->cells.front()); n->cells.push_back(cell); n->cmp.push_back(std::make_tuple(false, false, cmp_equal, !cmp_equal, false, Y)); } @@ -503,8 +503,8 @@ struct AlumaccWorker log(" creating $pos cell for "); for (int i = 0; i < GetSize(n->cells); i++) - log("%s%s", i ? ", ": "", log_id(n->cells[i])); - log(": %s\n", log_id(n->alu_cell)); + log("%s%s", i ? ", ": "", n->cells[i]); + log(": %s\n", n->alu_cell); goto delete_node; } @@ -514,8 +514,8 @@ struct AlumaccWorker log(" creating $alu cell for "); for (int i = 0; i < GetSize(n->cells); i++) - log("%s%s", i ? ", ": "", log_id(n->cells[i])); - log(": %s\n", log_id(n->alu_cell)); + log("%s%s", i ? ", ": "", n->cells[i]); + log(": %s\n", n->alu_cell); if (n->cells.size() > 0) n->alu_cell->set_src_attribute(n->cells[0]->get_src_attribute()); @@ -562,7 +562,7 @@ struct AlumaccWorker void run() { - log("Extracting $alu and $macc cells in module %s:\n", log_id(module)); + log("Extracting $alu and $macc cells in module %s:\n", module); count_bit_users(); extract_macc(); diff --git a/passes/techmap/arith_tree.cc b/passes/techmap/arith_tree.cc index 9494fa958..259e0c5bb 100644 --- a/passes/techmap/arith_tree.cc +++ b/passes/techmap/arith_tree.cc @@ -316,7 +316,7 @@ struct Rewriter { int compressor_count; auto [a, b] = wallace_reduce_scheduled(module, extended, width, &compressor_count); - log(" %s -> %d $fa + 1 $add (%d operands, module %s)\n", desc, compressor_count, (int)operands.size(), log_id(module)); + log(" %s -> %d $fa + 1 $add (%d operands, module %s)\n", desc, compressor_count, (int)operands.size(), module); // Emit final add module->addAdd(NEW_ID, a, b, result_y, false); diff --git a/passes/techmap/attrmap.cc b/passes/techmap/attrmap.cc index 58ac25f51..4c97f6ab1 100644 --- a/passes/techmap/attrmap.cc +++ b/passes/techmap/attrmap.cc @@ -131,13 +131,13 @@ void attrmap_apply(string objname, vector> &actio if (new_attr != attr) log("Changed attribute on %s: %s=%s -> %s=%s\n", objname, - log_id(attr.first), log_const(attr.second), log_id(new_attr.first), log_const(new_attr.second)); + attr.first.unescape(), log_const(attr.second), new_attr.first.unescape(), log_const(new_attr.second)); new_attributes[new_attr.first] = new_attr.second; if (0) delete_this_attr: - log("Removed attribute on %s: %s=%s\n", objname, log_id(attr.first), log_const(attr.second)); + log("Removed attribute on %s: %s=%s\n", objname, attr.first.unescape(), log_const(attr.second)); } attributes.swap(new_attributes); @@ -264,14 +264,14 @@ struct AttrmapPass : public Pass { if (modattr_mode) { for (auto module : design->all_selected_whole_modules()) - attrmap_apply(stringf("%s", log_id(module)), actions, module->attributes); + attrmap_apply(stringf("%s", module), actions, module->attributes); } else { for (auto module : design->all_selected_modules()) { for (auto memb : module->selected_members()) - attrmap_apply(stringf("%s.%s", log_id(module), log_id(memb)), actions, memb->attributes); + attrmap_apply(stringf("%s.%s", module, memb), actions, memb->attributes); // attrmap already applied to process itself during above loop, but not its children for (auto proc : module->selected_processes()) @@ -280,10 +280,10 @@ struct AttrmapPass : public Pass { while (!all_cases.empty()) { RTLIL::CaseRule *cs = all_cases.back(); all_cases.pop_back(); - attrmap_apply(stringf("%s.%s (case)", log_id(module), log_id(proc)), actions, cs->attributes); + attrmap_apply(stringf("%s.%s (case)", module, proc), actions, cs->attributes); for (auto &sw : cs->switches) { - attrmap_apply(stringf("%s.%s (switch)", log_id(module), log_id(proc)), actions, sw->attributes); + attrmap_apply(stringf("%s.%s (switch)", module, proc), actions, sw->attributes); all_cases.insert(all_cases.end(), sw->cases.begin(), sw->cases.end()); } } @@ -328,7 +328,7 @@ struct ParamapPass : public Pass { for (auto module : design->selected_modules()) for (auto cell : module->selected_cells()) - attrmap_apply(stringf("%s.%s", log_id(module), log_id(cell)), actions, cell->parameters); + attrmap_apply(stringf("%s.%s", module, cell), actions, cell->parameters); } } ParamapPass; diff --git a/passes/techmap/attrmvcp.cc b/passes/techmap/attrmvcp.cc index 65b63daf1..cff7d8697 100644 --- a/passes/techmap/attrmvcp.cc +++ b/passes/techmap/attrmvcp.cc @@ -121,8 +121,8 @@ struct AttrmvcpPass : public Pass { for (auto bit : sigmap(wire)) if (net2cells.count(bit)) for (auto cell : net2cells.at(bit)) { - log("Moving attribute %s=%s from %s.%s to %s.%s.\n", log_id(attr.first), log_const(attr.second), - log_id(module), log_id(wire), log_id(module), log_id(cell)); + log("Moving attribute %s=%s from %s.%s to %s.%s.\n", attr.first.unescape(), log_const(attr.second), + module, wire, module, cell); cell->attributes[attr.first] = attr.second; did_something = true; } diff --git a/passes/techmap/booth.cc b/passes/techmap/booth.cc index c0bad784a..630c83f8c 100644 --- a/passes/techmap/booth.cc +++ b/passes/techmap/booth.cc @@ -224,7 +224,7 @@ struct BoothPassWorker { macc.from_cell(cell); if (!macc.is_simple_product()) { - log_debug("Not mapping cell %s: not a simple macc cell\n", log_id(cell)); + log_debug("Not mapping cell %s: not a simple macc cell\n", cell); continue; } @@ -240,11 +240,11 @@ struct BoothPassWorker { if (x_sz < 4 || y_sz < 4 || z_sz < 8) { log_debug("Not mapping cell %s sized at %dx%x, %x: size below threshold\n", - log_id(cell), x_sz, y_sz, z_sz); + cell, x_sz, y_sz, z_sz); continue; } - log("Mapping cell %s to %s Booth multiplier\n", log_id(cell), is_signed ? "signed" : "unsigned"); + log("Mapping cell %s to %s Booth multiplier\n", cell, is_signed ? "signed" : "unsigned"); // To simplify the generator size the arguments // to be the same. Then allow logic synthesis to diff --git a/passes/techmap/bufnorm.cc b/passes/techmap/bufnorm.cc index 123687255..9e6ca2e30 100644 --- a/passes/techmap/bufnorm.cc +++ b/passes/techmap/bufnorm.cc @@ -249,7 +249,7 @@ struct BufnormPass : public Pass { for (auto module : design->selected_modules()) { - log("Buffer-normalizing module %s.\n", log_id(module)); + log("Buffer-normalizing module %s.\n", module); SigMap sigmap(module); module->new_connections({}); @@ -293,7 +293,7 @@ struct BufnormPass : public Pass { bit2wires[keybit].insert(wire); if (wire->port_input) { - log(" primary input: %s\n", log_id(wire)); + log(" primary input: %s\n", wire); for (auto bit : SigSpec(wire)) mapped_bits[sigmap(bit)] = bit; } else { @@ -392,7 +392,7 @@ struct BufnormPass : public Pass { if (w->name.isPublic()) log(" directly driven by cell %s port %s: %s\n", - log_id(cell), log_id(conn.first), log_id(w)); + cell, conn.first.unescape(), w); for (auto bit : SigSpec(w)) mapped_bits[sigmap(bit)] = bit; @@ -502,7 +502,7 @@ struct BufnormPass : public Pass { if (conn.second != newsig) { log(" fixing input signal on cell %s port %s: %s\n", - log_id(cell), log_id(conn.first), log_signal(newsig)); + cell, conn.first.unescape(), newsig); cell->setPort(conn.first, newsig); count_updated_cellports++; } diff --git a/passes/techmap/cellmatch.cc b/passes/techmap/cellmatch.cc index ce1a75193..a2e2393d0 100644 --- a/passes/techmap/cellmatch.cc +++ b/passes/techmap/cellmatch.cc @@ -20,7 +20,7 @@ SigSpec module_inputs(Module *m) continue; if (w->width != 1) log_error("Unsupported wide port (%s) of non-unit width found in module %s.\n", - log_id(w), log_id(m)); + w, m); ret.append(w); } return ret; @@ -36,7 +36,7 @@ SigSpec module_outputs(Module *m) continue; if (w->width != 1) log_error("Unsupported wide port (%s) of non-unit width found in module %s.\n", - log_id(w), log_id(m)); + w, m); ret.append(w); } return ret; @@ -96,7 +96,7 @@ bool derive_module_luts(Module *m, std::vector &luts) ff_types.setup_stdcells_mem(); for (auto cell : m->cells()) { if (ff_types.cell_known(cell->type)) { - log("Ignoring module '%s' which isn't purely combinational.\n", log_id(m)); + log("Ignoring module '%s' which isn't purely combinational.\n", m); return false; } } @@ -106,7 +106,7 @@ bool derive_module_luts(Module *m, std::vector &luts) int ninputs = inputs.size(), noutputs = outputs.size(); if (ninputs > 6) { - log_warning("Skipping module %s with more than 6 inputs bits.\n", log_id(m)); + log_warning("Skipping module %s with more than 6 inputs bits.\n", m); return false; } @@ -123,7 +123,7 @@ bool derive_module_luts(Module *m, std::vector &luts) if (!ceval.eval(bit)) { log("Failed to evaluate output '%s' in module '%s'.\n", - log_signal(outputs[j]), log_id(m)); + log_signal(outputs[j]), m); return false; } @@ -203,7 +203,7 @@ struct CellmatchPass : Pass { for (auto lut : luts) p_classes.insert(p_class(ninputs, lut)); - log_debug("Registered %s\n", log_id(m)); + log_debug("Registered %s\n", m); // save as a viable target targets[p_classes].push_back(Target{m, luts}); @@ -237,7 +237,7 @@ struct CellmatchPass : Pass { p_classes.insert(p_class(inputs.size(), lut)); for (auto target : targets[p_classes]) { - log_debug("Candidate %s for matching to %s\n", log_id(target.module), log_id(m)); + log_debug("Candidate %s for matching to %s\n", target.module, m); SigSpec target_inputs = module_inputs(target.module); SigSpec target_outputs = module_outputs(target.module); @@ -271,10 +271,10 @@ struct CellmatchPass : Pass { } if (match) { - log("Module %s matches %s\n", log_id(m), log_id(target.module)); + log("Module %s matches %s\n", m, target.module); // Add target.module to map_design ("$cellmatch") // as a techmap rule to match m and replace it with target.module - Module *map = map_design->addModule(stringf("\\_60_%s_%s", log_id(m), log_id(target.module))); + Module *map = map_design->addModule(stringf("\\_60_%s_%s", m, target.module)); Cell *cell = map->addCell(ID::_TECHMAP_REPLACE_, target.module->name); map->attributes[ID(techmap_celltype)] = m->name.str(); diff --git a/passes/techmap/clkbufmap.cc b/passes/techmap/clkbufmap.cc index 7003c6656..7954b7891 100644 --- a/passes/techmap/clkbufmap.cc +++ b/passes/techmap/clkbufmap.cc @@ -257,14 +257,14 @@ struct ClkbufmapPass : public Pass { RTLIL::Cell *cell = nullptr; bool is_input = wire->port_input && !inpad_celltype.empty() && module->get_bool_attribute(ID::top); if (!buf_celltype.empty() && (!is_input || buffer_inputs)) { - log("Inserting %s on %s.%s[%d].\n", buf_celltype, log_id(module), log_id(wire), i); + log("Inserting %s on %s.%s[%d].\n", buf_celltype, module, wire, i); cell = module->addCell(NEW_ID, RTLIL::escape_id(buf_celltype)); iwire = module->addWire(NEW_ID); cell->setPort(RTLIL::escape_id(buf_portname), mapped_wire_bit); cell->setPort(RTLIL::escape_id(buf_portname2), iwire); } if (is_input) { - log("Inserting %s on %s.%s[%d].\n", inpad_celltype, log_id(module), log_id(wire), i); + log("Inserting %s on %s.%s[%d].\n", inpad_celltype, module, wire, i); RTLIL::Cell *cell2 = module->addCell(NEW_ID, RTLIL::escape_id(inpad_celltype)); if (iwire) { cell2->setPort(RTLIL::escape_id(inpad_portname), iwire); diff --git a/passes/techmap/deminout.cc b/passes/techmap/deminout.cc index 5245331f8..103fba103 100644 --- a/passes/techmap/deminout.cc +++ b/passes/techmap/deminout.cc @@ -126,7 +126,7 @@ struct DeminoutPass : public Pass { } if (new_input != new_output) { - log("Demoting inout port %s.%s to %s.\n", log_id(module), log_id(wire), new_input ? "input" : "output"); + log("Demoting inout port %s.%s to %s.\n", module, wire, new_input ? "input" : "output"); wire->port_input = new_input; wire->port_output = new_output; keep_running = true; diff --git a/passes/techmap/dffinit.cc b/passes/techmap/dffinit.cc index 013675c8a..912f7fb81 100644 --- a/passes/techmap/dffinit.cc +++ b/passes/techmap/dffinit.cc @@ -123,14 +123,14 @@ struct DffinitPass : public Pass { if (noreinit && value[i] != State::Sx && value[i] != initval[i]) log_error("Trying to assign a different init value for %s.%s.%s which technically " "have a conflicted init value.\n", - log_id(module), log_id(cell), log_id(it.second)); + module, cell, it.second.unescape()); value.set(i, initval[i]); } if (highlow_mode && GetSize(value) != 0) { if (GetSize(value) != 1) log_error("Multi-bit init value for %s.%s.%s is incompatible with -highlow mode.\n", - log_id(module), log_id(cell), log_id(it.second)); + module, cell, it.second.unescape()); if (value[0] == State::S1) value = Const(high_string); else @@ -138,8 +138,8 @@ struct DffinitPass : public Pass { } if (value.size() != 0) { - log("Setting %s.%s.%s (port=%s, net=%s) to %s.\n", log_id(module), log_id(cell), log_id(it.second), - log_id(it.first), log_signal(sig), log_signal(value)); + log("Setting %s.%s.%s (port=%s, net=%s) to %s.\n", module, cell, it.second.unescape(), + it.first.unescape(), log_signal(sig), log_signal(value)); cell->setParam(it.second, value); } } diff --git a/passes/techmap/dfflegalize.cc b/passes/techmap/dfflegalize.cc index dc29750c8..3cba527b2 100644 --- a/passes/techmap/dfflegalize.cc +++ b/passes/techmap/dfflegalize.cc @@ -263,7 +263,7 @@ struct DffLegalizePass : public Pass { } void fail_ff(const FfData &ff, const char *reason) { - log_error("FF %s.%s (type %s) cannot be legalized: %s\n", log_id(ff.module->name), log_id(ff.cell->name), log_id(ff.cell->type), reason); + log_error("FF %s.%s (type %s) cannot be legalized: %s\n", ff.module->name.unescape(), ff.cell->name.unescape(), ff.cell->type.unescape(), reason); } bool try_flip(FfData &ff, int supported_mask) { @@ -381,7 +381,7 @@ struct DffLegalizePass : public Pass { if (ff.has_ce && !supported_cells[FF_ADFFE]) ff.unmap_ce(); - log_warning("Emulating async set + reset with several FFs and a mux for %s.%s\n", log_id(ff.module->name), log_id(ff.cell->name)); + log_warning("Emulating async set + reset with several FFs and a mux for %s.%s\n", ff.module->name.unescape(), ff.cell->name.unescape()); log_assert(ff.width == 1); ff.remove(); @@ -600,7 +600,7 @@ struct DffLegalizePass : public Pass { ff.unmap_ce(); if (ff.cell) - log_warning("Emulating mismatched async reset and init with several FFs and a mux for %s.%s\n", log_id(ff.module->name), log_id(ff.cell->name)); + log_warning("Emulating mismatched async reset and init with several FFs and a mux for %s.%s\n", ff.module->name.unescape(), ff.cell->name.unescape()); emulate_split_init_arst(ff); return; } @@ -752,7 +752,7 @@ struct DffLegalizePass : public Pass { // The only hope left is breaking down to adlatch + dlatch + dlatch + mux. if (ff.cell) - log_warning("Emulating mismatched async reset and init with several latches and a mux for %s.%s\n", log_id(ff.module->name), log_id(ff.cell->name)); + log_warning("Emulating mismatched async reset and init with several latches and a mux for %s.%s\n", ff.module->name.unescape(), ff.cell->name.unescape()); ff.remove(); emulate_split_init_arst(ff); diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index 7461e21d8..d4d13d673 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -155,12 +155,12 @@ bool module2graph(SubCircuit::Graph &graph, RTLIL::Module *mod, bool constports, std::map sig_bit_ref; if (sel && !sel->selected(mod)) { - log(" Skipping module %s as it is not selected.\n", log_id(mod->name)); + log(" Skipping module %s as it is not selected.\n", mod->name.unescape()); return false; } if (mod->processes.size() > 0) { - log(" Skipping module %s as it contains unprocessed processes.\n", log_id(mod->name)); + log(" Skipping module %s as it contains unprocessed processes.\n", mod->name.unescape()); return false; } @@ -674,7 +674,7 @@ struct ExtractPass : public Pass { } RTLIL::Cell *new_cell = replace(needle_map.at(result.needleGraphId), haystack_map.at(result.haystackGraphId), result); design->select(haystack_map.at(result.haystackGraphId), new_cell); - log(" new cell: %s\n", log_id(new_cell->name)); + log(" new cell: %s\n", new_cell->name.unescape()); } } } @@ -691,12 +691,12 @@ struct ExtractPass : public Pass { for (auto &result: results) { log("\nFrequent SubCircuit with %d nodes and %d matches:\n", int(result.nodes.size()), result.totalMatchesAfterLimits); - log(" primary match in %s:", log_id(haystack_map.at(result.graphId)->name)); + log(" primary match in %s:", haystack_map.at(result.graphId)->name.unescape()); for (auto &node : result.nodes) log(" %s", RTLIL::unescape_id(node.nodeId)); log("\n"); for (auto &it : result.matchesPerGraph) - log(" matches in %s: %d\n", log_id(haystack_map.at(it.first)->name), it.second); + log(" matches in %s: %d\n", haystack_map.at(it.first)->name.unescape(), it.second); RTLIL::Module *mod = haystack_map.at(result.graphId); std::set cells; @@ -716,7 +716,7 @@ struct ExtractPass : public Pass { } RTLIL::Module *newMod = new RTLIL::Module; - newMod->name = stringf("\\needle%05d_%s_%dx", needleCounter++, log_id(haystack_map.at(result.graphId)->name), result.totalMatchesAfterLimits); + newMod->name = stringf("\\needle%05d_%s_%dx", needleCounter++, haystack_map.at(result.graphId)->name.unescape(), result.totalMatchesAfterLimits); map->add(newMod); for (auto wire : wires) { diff --git a/passes/techmap/extract_counter.cc b/passes/techmap/extract_counter.cc index c45792f66..c0e45a70e 100644 --- a/passes/techmap/extract_counter.cc +++ b/passes/techmap/extract_counter.cc @@ -541,7 +541,7 @@ void counter_worker( { extract_value = *sa.begin(); log(" Signal %s declared at %s has COUNT_EXTRACT = %s\n", - log_id(port_wire), + port_wire, count_reg_src.c_str(), extract_value.c_str()); @@ -604,14 +604,14 @@ void counter_worker( { log_error( "Counter extraction is set to FORCE on register %s, but a counter could not be inferred (%s)\n", - log_id(port_wire), + port_wire, reasons[reason]); } return; } //Get new cell name - string countname = string("$COUNTx$") + log_id(extract.rwire->name.str()); + string countname = string("$COUNTx$") + extract.rwire->name.unescape(); //Wipe all of the old connections to the ALU cell->unsetPort(ID::A); @@ -697,7 +697,7 @@ void counter_worker( //Hook up any parallel outputs for(auto load : extract.pouts) { - log(" Counter has parallel output to cell %s port %s\n", log_id(load.cell->name), log_id(load.port)); + log(" Counter has parallel output to cell %s port %s\n", load.cell->name.unescape(), load.port.unescape()); } if(extract.has_pout) { @@ -731,7 +731,7 @@ void counter_worker( countname.c_str(), extract.count_is_up ? "to" : "from", extract.count_value, - log_id(extract.rwire->name), + extract.rwire->name.unescape(), count_reg_src.c_str()); //Optimize the counter @@ -887,13 +887,13 @@ struct ExtractCounterPass : public Pass { for(auto cell : cells_to_remove) { - //log("Removing cell %s\n", log_id(cell->name)); + //log("Removing cell %s\n", cell); module->remove(cell); } for(auto cpair : cells_to_rename) { - //log("Renaming cell %s to %s\n", log_id(cpair.first->name), cpair.second); + //log("Renaming cell %s to %s\n", cpair.first, cpair.second); module->rename(cpair.first, cpair.second); } } diff --git a/passes/techmap/extract_fa.cc b/passes/techmap/extract_fa.cc index 46ab7e520..15cdc54c9 100644 --- a/passes/techmap/extract_fa.cc +++ b/passes/techmap/extract_fa.cc @@ -289,7 +289,7 @@ struct ExtractFaWorker void run() { - log("Extracting full/half adders from %s:\n", log_id(module)); + log("Extracting full/half adders from %s:\n", module); for (auto it : driver) { @@ -381,7 +381,7 @@ struct ExtractFaWorker auto &fa = facache.at(fakey); X = get<0>(fa); Y = get<1>(fa); - log(" Reusing $fa cell %s.\n", log_id(get<2>(fa))); + log(" Reusing $fa cell %s.\n", get<2>(fa)); } else if (facache.count(fakey_inv)) @@ -390,14 +390,14 @@ struct ExtractFaWorker invert_xy = true; X = get<0>(fa); Y = get<1>(fa); - log(" Reusing $fa cell %s.\n", log_id(get<2>(fa))); + log(" Reusing $fa cell %s.\n", get<2>(fa)); } else { Cell *cell = module->addCell(NEW_ID, ID($fa)); cell->setParam(ID::WIDTH, 1); - log(" Created $fa cell %s.\n", log_id(cell)); + log(" Created $fa cell %s.\n", cell); cell->setPort(ID::A, f3i.inv_a ? module->NotGate(NEW_ID, A) : A); cell->setPort(ID::B, f3i.inv_b ? module->NotGate(NEW_ID, B) : B); @@ -488,7 +488,7 @@ struct ExtractFaWorker auto &fa = facache.at(fakey); X = get<0>(fa); Y = get<1>(fa); - log(" Reusing $fa cell %s.\n", log_id(get<2>(fa))); + log(" Reusing $fa cell %s.\n", get<2>(fa)); } else if (facache.count(fakey_inv)) @@ -497,14 +497,14 @@ struct ExtractFaWorker invert_xy = true; X = get<0>(fa); Y = get<1>(fa); - log(" Reusing $fa cell %s.\n", log_id(get<2>(fa))); + log(" Reusing $fa cell %s.\n", get<2>(fa)); } else { Cell *cell = module->addCell(NEW_ID, ID($fa)); cell->setParam(ID::WIDTH, 1); - log(" Created $fa cell %s.\n", log_id(cell)); + log(" Created $fa cell %s.\n", cell); cell->setPort(ID::A, f2i.inv_a ? module->NotGate(NEW_ID, A) : A); cell->setPort(ID::B, f2i.inv_b ? module->NotGate(NEW_ID, B) : B); diff --git a/passes/techmap/extractinv.cc b/passes/techmap/extractinv.cc index 5050e1464..7444369cc 100644 --- a/passes/techmap/extractinv.cc +++ b/passes/techmap/extractinv.cc @@ -100,7 +100,7 @@ struct ExtractinvPass : public Pass { continue; SigSpec sig = port.second; if (it2->second.size() != sig.size()) - log_error("The inversion parameter needs to be the same width as the port (%s.%s port %s parameter %s)", log_id(module->name), log_id(cell->type), log_id(port.first), log_id(param_name)); + log_error("The inversion parameter needs to be the same width as the port (%s.%s port %s parameter %s)", module->name.unescape(), cell->type.unescape(), port.first.unescape(), param_name.unescape()); RTLIL::Const invmask = it2->second; cell->parameters.erase(param_name); if (invmask.is_fully_zero()) @@ -111,7 +111,7 @@ struct ExtractinvPass : public Pass { RTLIL::Cell *icell = module->addCell(NEW_ID, RTLIL::escape_id(inv_celltype)); icell->setPort(RTLIL::escape_id(inv_portname), SigSpec(iwire, i)); icell->setPort(RTLIL::escape_id(inv_portname2), sig[i]); - log("Inserting %s on %s.%s.%s[%d].\n", inv_celltype, log_id(module), log_id(cell->type), log_id(port.first), i); + log("Inserting %s on %s.%s.%s[%d].\n", inv_celltype, module, cell->type.unescape(), port.first.unescape(), i); sig[i] = SigBit(iwire, i); } cell->setPort(port.first, sig); diff --git a/passes/techmap/flowmap.cc b/passes/techmap/flowmap.cc index f5f225a9b..c9d561a4c 100644 --- a/passes/techmap/flowmap.cc +++ b/passes/techmap/flowmap.cc @@ -598,7 +598,7 @@ struct FlowmapWorker continue; if (!cell->known()) - log_error("Cell %s (%s.%s) is unknown.\n", cell->type, log_id(module), log_id(cell)); + log_error("Cell %s (%s.%s) is unknown.\n", cell->type, module, cell); pool fanout; for (auto conn : cell->connections()) @@ -636,7 +636,7 @@ struct FlowmapWorker if (fanin > order) log_error("Cell %s (%s.%s) with fan-in %d cannot be mapped to a %d-LUT.\n", - cell->type.c_str(), log_id(module), log_id(cell), fanin, order); + cell->type.c_str(), module, cell, fanin, order); gate_count++; gate_area += 1 << fanin; @@ -1356,14 +1356,14 @@ struct FlowmapWorker auto origin = node_origins[node]; if (origin.cell->getPort(origin.port).size() == 1) log("Packing %s.%s.%s (%s).\n", - log_id(module), log_id(origin.cell), origin.port.c_str(), log_signal(node)); + module, origin.cell, origin.port.c_str(), log_signal(node)); else log("Packing %s.%s.%s [%d] (%s).\n", - log_id(module), log_id(origin.cell), origin.port.c_str(), origin.offset, log_signal(node)); + module, origin.cell, origin.port.c_str(), origin.offset, log_signal(node)); } else { - log("Packing %s.%s.\n", log_id(module), log_signal(node)); + log("Packing %s.%s.\n", module, log_signal(node)); } for (auto gate_node : lut_gates[node]) @@ -1376,10 +1376,10 @@ struct FlowmapWorker auto gate_origin = node_origins[gate_node]; if (gate_origin.cell->getPort(gate_origin.port).size() == 1) log(" Packing %s.%s.%s (%s).\n", - log_id(module), log_id(gate_origin.cell), gate_origin.port.c_str(), log_signal(gate_node)); + module, gate_origin.cell, gate_origin.port.c_str(), log_signal(gate_node)); else log(" Packing %s.%s.%s [%d] (%s).\n", - log_id(module), log_id(gate_origin.cell), gate_origin.port.c_str(), gate_origin.offset, log_signal(gate_node)); + module, gate_origin.cell, gate_origin.port.c_str(), gate_origin.offset, log_signal(gate_node)); } vector input_nodes(lut_edges_bw[node].begin(), lut_edges_bw[node].end()); @@ -1423,9 +1423,9 @@ struct FlowmapWorker lut_area += lut_table.size(); if ((int)input_nodes.size() >= minlut) - log(" Packed into a %d-LUT %s.%s.\n", GetSize(input_nodes), log_id(module), log_id(lut)); + log(" Packed into a %d-LUT %s.%s.\n", GetSize(input_nodes), module, lut); else - log(" Packed into a %d-LUT %s.%s (implemented as %d-LUT).\n", GetSize(input_nodes), log_id(module), log_id(lut), minlut); + log(" Packed into a %d-LUT %s.%s (implemented as %d-LUT).\n", GetSize(input_nodes), module, lut, minlut); } for (auto node : mapped_nodes) diff --git a/passes/techmap/insbuf.cc b/passes/techmap/insbuf.cc index f288987a1..5674de71f 100644 --- a/passes/techmap/insbuf.cc +++ b/passes/techmap/insbuf.cc @@ -83,7 +83,7 @@ struct InsbufPass : public Pass { if (!lhs.wire || !design->selected(module, lhs.wire)) { new_conn.first.append(lhs); new_conn.second.append(rhs); - log("Skip %s: %s -> %s\n", log_id(module), log_signal(rhs), log_signal(lhs)); + log("Skip %s: %s -> %s\n", module, log_signal(rhs), log_signal(lhs)); continue; } @@ -98,7 +98,7 @@ struct InsbufPass : public Pass { cell->setPort(in_portname, rhs); cell->setPort(out_portname, lhs); - log("Add %s/%s: %s -> %s\n", log_id(module), log_id(cell), log_signal(rhs), log_signal(lhs)); + log("Add %s/%s: %s -> %s\n", module, cell, log_signal(rhs), log_signal(lhs)); bufcells.insert(cell); } @@ -115,8 +115,8 @@ struct InsbufPass : public Pass { auto s = sigmap(port.second); if (s == port.second) continue; - log("Rewrite %s/%s/%s: %s -> %s\n", log_id(module), log_id(cell), - log_id(port.first), log_signal(port.second), log_signal(s)); + log("Rewrite %s/%s/%s: %s -> %s\n", module, cell, + port.first.unescape(), log_signal(port.second), log_signal(s)); cell->setPort(port.first, s); } } diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index d929de300..d7667d6f5 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -231,7 +231,7 @@ struct IopadmapPass : public Pass { for (int i = 0; i < GetSize(wire); i++) if (buf_bits.count(sigmap(SigBit(wire, i)))) { buf_ports.insert(make_pair(module->name, make_pair(wire->name, i))); - log("Marking already mapped port: %s.%s[%d].\n", log_id(module), log_id(wire), i); + log("Marking already mapped port: %s.%s[%d].\n", module, wire, i); } } @@ -324,10 +324,10 @@ struct IopadmapPass : public Pass { if (wire->port_input) { - log("Mapping port %s.%s[%d] using %s.\n", log_id(module), log_id(wire), i, tinoutpad_celltype); + log("Mapping port %s.%s[%d] using %s.\n", module, wire, i, tinoutpad_celltype); Cell *cell = module->addCell( - module->uniquify(stringf("$iopadmap$%s.%s[%d]", log_id(module), log_id(wire), i)), + module->uniquify(stringf("$iopadmap$%s.%s[%d]", module, wire, i)), RTLIL::escape_id(tinoutpad_celltype)); if (tinoutpad_neg_oe) @@ -348,10 +348,10 @@ struct IopadmapPass : public Pass { if (!tinoutpad_portname_pad.empty()) rewrite_bits[wire][i] = make_pair(cell, RTLIL::escape_id(tinoutpad_portname_pad)); } else { - log("Mapping port %s.%s[%d] using %s.\n", log_id(module), log_id(wire), i, toutpad_celltype); + log("Mapping port %s.%s[%d] using %s.\n", module, wire, i, toutpad_celltype); Cell *cell = module->addCell( - module->uniquify(stringf("$iopadmap$%s.%s[%d]", log_id(module), log_id(wire), i)), + module->uniquify(stringf("$iopadmap$%s.%s[%d]", module, wire, i)), RTLIL::escape_id(toutpad_celltype)); if (toutpad_neg_oe) @@ -433,7 +433,7 @@ struct IopadmapPass : public Pass { SigBit wire_bit(wire, i); RTLIL::Cell *cell = module->addCell( - module->uniquify(stringf("$iopadmap$%s.%s", log_id(module->name), log_id(wire->name))), + module->uniquify(stringf("$iopadmap$%s.%s", module->name.unescape(), wire->name.unescape())), RTLIL::escape_id(celltype)); cell->setPort(RTLIL::escape_id(portname_int), wire_bit); @@ -449,14 +449,14 @@ struct IopadmapPass : public Pass { else { RTLIL::Cell *cell = module->addCell( - module->uniquify(stringf("$iopadmap$%s.%s", log_id(module->name), log_id(wire->name))), + module->uniquify(stringf("$iopadmap$%s.%s", module->name.unescape(), wire->name.unescape())), RTLIL::escape_id(celltype)); cell->setPort(RTLIL::escape_id(portname_int), RTLIL::SigSpec(wire)); if (!portname_pad.empty()) { RTLIL::Wire *new_wire = NULL; new_wire = module->addWire( - module->uniquify(stringf("$iopadmap$%s", log_id(wire))), + module->uniquify(stringf("$iopadmap$%s", wire)), wire); module->swap_names(new_wire, wire); wire->attributes.clear(); @@ -500,7 +500,7 @@ struct IopadmapPass : public Pass { for (auto &it : rewrite_bits) { RTLIL::Wire *wire = it.first; RTLIL::Wire *new_wire = module->addWire( - module->uniquify(stringf("$iopadmap$%s", log_id(wire))), + module->uniquify(stringf("$iopadmap$%s", wire)), wire); module->swap_names(new_wire, wire); wire->attributes.clear(); diff --git a/passes/techmap/lut2bmux.cc b/passes/techmap/lut2bmux.cc index 42042c942..1073b1208 100644 --- a/passes/techmap/lut2bmux.cc +++ b/passes/techmap/lut2bmux.cc @@ -49,7 +49,7 @@ struct Lut2BmuxPass : public Pass { cell->setPort(ID::A, cell->getParam(ID::LUT)); cell->unsetParam(ID::LUT); cell->fixup_parameters(); - log("Converted %s.%s to BMUX cell.\n", log_id(module), log_id(cell)); + log("Converted %s.%s to BMUX cell.\n", module, cell); } } } diff --git a/passes/techmap/lut2mux.cc b/passes/techmap/lut2mux.cc index 3d45734ec..2ddb16d61 100644 --- a/passes/techmap/lut2mux.cc +++ b/passes/techmap/lut2mux.cc @@ -97,7 +97,7 @@ struct Lut2muxPass : public Pass { if (cell->type == ID($lut)) { IdString cell_name = cell->name; int count = lut2mux(cell, word_mode); - log("Converted %s.%s to %d MUX cells.\n", log_id(module), log_id(cell_name), count); + log("Converted %s.%s to %d MUX cells.\n", module, cell_name.unescape(), count); } } } diff --git a/passes/techmap/maccmap.cc b/passes/techmap/maccmap.cc index 42b615002..cb041f615 100644 --- a/passes/techmap/maccmap.cc +++ b/passes/techmap/maccmap.cc @@ -404,7 +404,7 @@ struct MaccmapPass : public Pass { for (auto mod : design->selected_modules()) for (auto cell : mod->selected_cells()) if (cell->type.in(ID($macc), ID($macc_v2))) { - log("Mapping %s.%s (%s).\n", log_id(mod), log_id(cell), log_id(cell->type)); + log("Mapping %s.%s (%s).\n", mod, cell, cell->type.unescape()); maccmap(mod, cell, unmap_mode); mod->remove(cell); } diff --git a/passes/techmap/muxcover.cc b/passes/techmap/muxcover.cc index 2656f30ce..719a346d8 100644 --- a/passes/techmap/muxcover.cc +++ b/passes/techmap/muxcover.cc @@ -596,7 +596,7 @@ struct MuxcoverWorker void run() { - log("Covering MUX trees in module %s..\n", log_id(module)); + log("Covering MUX trees in module %s..\n", module); treeify(); diff --git a/passes/techmap/shregmap.cc b/passes/techmap/shregmap.cc index 928182970..9f4e307f9 100644 --- a/passes/techmap/shregmap.cc +++ b/passes/techmap/shregmap.cc @@ -284,7 +284,7 @@ struct ShregmapWorker Cell *last_cell = chain[cursor+depth-1]; log("Converting %s.%s ... %s.%s to a shift register with depth %d.\n", - log_id(module), log_id(first_cell), log_id(module), log_id(last_cell), depth); + module, first_cell, module, last_cell, depth); dff_count += depth; shreg_count += 1; diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index 93001df35..2c252deb3 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -580,7 +580,7 @@ struct SimplemapPass : public Pass { continue; if (!design->selected(mod, cell)) continue; - log("Mapping %s.%s (%s).\n", log_id(mod), log_id(cell), log_id(cell->type)); + log("Mapping %s.%s (%s).\n", mod, cell, cell->type.unescape()); mappers.at(cell->type)(mod, cell); mod->remove(cell); } diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index cf7ce56e2..5827feb92 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -93,17 +93,17 @@ struct TechmapWorker RTLIL::SigBit bit = sigmap(conn.second[i]); if (bit.wire == nullptr) { if (verbose) - log(" Constant input on bit %d of port %s: %s\n", i, log_id(conn.first), log_signal(bit)); - constmap_info += stringf("|%s %d %d", log_id(conn.first), i, bit.data); + log(" Constant input on bit %d of port %s: %s\n", i, conn.first.unescape(), log_signal(bit)); + constmap_info += stringf("|%s %d %d", conn.first.unescape(), i, bit.data); } else if (connbits_map.count(bit)) { if (verbose) - log(" Bit %d of port %s and bit %d of port %s are connected.\n", i, log_id(conn.first), - connbits_map.at(bit).second, log_id(connbits_map.at(bit).first)); - constmap_info += stringf("|%s %d %s %d", log_id(conn.first), i, - log_id(connbits_map.at(bit).first), connbits_map.at(bit).second); + log(" Bit %d of port %s and bit %d of port %s are connected.\n", i, conn.first.unescape(), + connbits_map.at(bit).second, connbits_map.at(bit).first.unescape()); + constmap_info += stringf("|%s %d %s %d", conn.first.unescape(), i, + connbits_map.at(bit).first.unescape(), connbits_map.at(bit).second); } else { connbits_map.emplace(bit, std::make_pair(conn.first, i)); - constmap_info += stringf("|%s %d", log_id(conn.first), i); + constmap_info += stringf("|%s %d", conn.first.unescape(), i); } } @@ -146,7 +146,7 @@ struct TechmapWorker if (tpl->processes.size() != 0) { log("Technology map yielded processes:"); for (auto &it : tpl->processes) - log(" %s",log_id(it.first)); + log(" %s",it.first.unescape()); log("\n"); if (autoproc_mode) { Pass::call_on_module(tpl->design, tpl, "proc"); @@ -435,7 +435,7 @@ struct TechmapWorker if (celltypeMap.count(cell->type) == 0) { if (assert_mode && !cell->type.ends_with("_")) - log_error("(ASSERT MODE) No matching template cell for type %s found.\n", log_id(cell->type)); + log_error("(ASSERT MODE) No matching template cell for type %s found.\n", cell->type.unescape()); continue; } @@ -498,10 +498,10 @@ struct TechmapWorker { if ((extern_mode && !in_recursion) || extmapper_name == "wrap") { - std::string m_name = stringf("$extern:%s:%s", extmapper_name, log_id(cell->type)); + std::string m_name = stringf("$extern:%s:%s", extmapper_name, cell->type.unescape()); for (auto &c : cell->parameters) - m_name += stringf(":%s=%s", log_id(c.first), log_signal(c.second)); + m_name += stringf(":%s=%s", c.first.unescape(), log_signal(c.second)); if (extmapper_name == "wrap") m_name += ":" + sha1(tpl->attributes.at(ID::techmap_wrap).decode_string()); @@ -531,24 +531,24 @@ struct TechmapWorker extmapper_module->check(); if (extmapper_name == "simplemap") { - log("Creating %s with simplemap.\n", log_id(extmapper_module)); + log("Creating %s with simplemap.\n", extmapper_module); if (simplemap_mappers.count(extmapper_cell->type) == 0) - log_error("No simplemap mapper for cell type %s found!\n", log_id(extmapper_cell->type)); + log_error("No simplemap mapper for cell type %s found!\n", extmapper_cell->type.unescape()); simplemap_mappers.at(extmapper_cell->type)(extmapper_module, extmapper_cell); extmapper_module->remove(extmapper_cell); } if (extmapper_name == "maccmap") { - log("Creating %s with maccmap.\n", log_id(extmapper_module)); + log("Creating %s with maccmap.\n", extmapper_module); if (!extmapper_cell->type.in(ID($macc), ID($macc_v2))) - log_error("The maccmap mapper can only map $macc/$macc_v2 (not %s) cells!\n", log_id(extmapper_cell->type)); + log_error("The maccmap mapper can only map $macc/$macc_v2 (not %s) cells!\n", extmapper_cell->type.unescape()); maccmap(extmapper_module, extmapper_cell); extmapper_module->remove(extmapper_cell); } if (extmapper_name == "wrap") { std::string cmd_string = tpl->attributes.at(ID::techmap_wrap).decode_string(); - log("Running \"%s\" on wrapper %s.\n", cmd_string, log_id(extmapper_module)); + log("Running \"%s\" on wrapper %s.\n", cmd_string, extmapper_module); mkdebug.on(); Pass::call_on_module(extmapper_design, extmapper_module, cmd_string); log_continue = true; @@ -563,31 +563,31 @@ struct TechmapWorker goto use_wrapper_tpl; } - auto msg = stringf("Using extmapper %s for cells of type %s.", log_id(extmapper_module), log_id(cell->type)); + auto msg = stringf("Using extmapper %s for cells of type %s.", extmapper_module, cell->type.unescape()); if (!log_msg_cache.count(msg)) { log_msg_cache.insert(msg); log("%s\n", msg); } - log_debug("%s %s.%s (%s) to %s.\n", mapmsg_prefix, log_id(module), log_id(cell), log_id(cell->type), log_id(extmapper_module)); + log_debug("%s %s.%s (%s) to %s.\n", mapmsg_prefix, module, cell, cell->type.unescape(), extmapper_module); } else { - auto msg = stringf("Using extmapper %s for cells of type %s.", extmapper_name, log_id(cell->type)); + auto msg = stringf("Using extmapper %s for cells of type %s.", extmapper_name, cell->type.unescape()); if (!log_msg_cache.count(msg)) { log_msg_cache.insert(msg); log("%s\n", msg); } - log_debug("%s %s.%s (%s) with %s.\n", mapmsg_prefix, log_id(module), log_id(cell), log_id(cell->type), extmapper_name); + log_debug("%s %s.%s (%s) with %s.\n", mapmsg_prefix, module, cell, cell->type.unescape(), extmapper_name); if (extmapper_name == "simplemap") { if (simplemap_mappers.count(cell->type) == 0) - log_error("No simplemap mapper for cell type %s found!\n", log_id(cell->type)); + log_error("No simplemap mapper for cell type %s found!\n", cell->type.unescape()); simplemap_mappers.at(cell->type)(module, cell); } if (extmapper_name == "maccmap") { if (!cell->type.in(ID($macc), ID($macc_v2))) - log_error("The maccmap mapper can only map $macc/$macc_v2 (not %s) cells!\n", log_id(cell->type)); + log_error("The maccmap mapper can only map $macc/$macc_v2 (not %s) cells!\n", cell->type.unescape()); maccmap(module, cell); } @@ -621,21 +621,21 @@ struct TechmapWorker parameters.emplace(ID::_TECHMAP_CELLNAME_, RTLIL::unescape_id(cell->name)); for (auto &conn : cell->connections()) { - if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONSTMSK_%s_", log_id(conn.first))) != 0) { + if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONSTMSK_%s_", conn.first.unescape())) != 0) { std::vector v = sigmap(conn.second).to_sigbit_vector(); for (auto &bit : v) bit = RTLIL::SigBit(bit.wire == nullptr ? RTLIL::State::S1 : RTLIL::State::S0); - parameters.emplace(stringf("\\_TECHMAP_CONSTMSK_%s_", log_id(conn.first)), RTLIL::SigSpec(v).as_const()); + parameters.emplace(stringf("\\_TECHMAP_CONSTMSK_%s_", conn.first.unescape()), RTLIL::SigSpec(v).as_const()); } - if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONSTVAL_%s_", log_id(conn.first))) != 0) { + if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONSTVAL_%s_", conn.first.unescape())) != 0) { std::vector v = sigmap(conn.second).to_sigbit_vector(); for (auto &bit : v) if (bit.wire != nullptr) bit = RTLIL::SigBit(RTLIL::State::Sx); - parameters.emplace(stringf("\\_TECHMAP_CONSTVAL_%s_", log_id(conn.first)), RTLIL::SigSpec(v).as_const()); + parameters.emplace(stringf("\\_TECHMAP_CONSTVAL_%s_", conn.first.unescape()), RTLIL::SigSpec(v).as_const()); } - if (tpl->avail_parameters.count(stringf("\\_TECHMAP_WIREINIT_%s_", log_id(conn.first))) != 0) { - parameters.emplace(stringf("\\_TECHMAP_WIREINIT_%s_", log_id(conn.first)), initvals(conn.second)); + if (tpl->avail_parameters.count(stringf("\\_TECHMAP_WIREINIT_%s_", conn.first.unescape())) != 0) { + parameters.emplace(stringf("\\_TECHMAP_WIREINIT_%s_", conn.first.unescape()), initvals(conn.second)); } } @@ -648,7 +648,7 @@ struct TechmapWorker unique_bit_id[RTLIL::State::Sz] = unique_bit_id_counter++; for (auto &conn : cell->connections()) - if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONNMAP_%s_", log_id(conn.first))) != 0) { + if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONNMAP_%s_", conn.first.unescape())) != 0) { for (auto &bit : sigmap(conn.second)) if (unique_bit_id.count(bit) == 0) unique_bit_id[bit] = unique_bit_id_counter++; @@ -665,7 +665,7 @@ struct TechmapWorker parameters[ID::_TECHMAP_BITS_CONNMAP_] = bits; for (auto &conn : cell->connections()) - if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONNMAP_%s_", log_id(conn.first))) != 0) { + if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONNMAP_%s_", conn.first.unescape())) != 0) { SigSpec sm = sigmap(conn.second); RTLIL::Const::Builder builder(GetSize(sm) * bits); for (auto &bit : sm) { @@ -675,7 +675,7 @@ struct TechmapWorker val = val >> 1; } } - parameters.emplace(stringf("\\_TECHMAP_CONNMAP_%s_", log_id(conn.first)), builder.build()); + parameters.emplace(stringf("\\_TECHMAP_CONNMAP_%s_", conn.first.unescape()), builder.build()); } } @@ -724,7 +724,7 @@ struct TechmapWorker RTLIL::SigSpec value = elem.value; if (value.is_fully_const() && value.as_bool()) { log("Not using module `%s' from techmap as it contains a %s marker wire with non-zero value %s.\n", - derived_name.c_str(), log_id(elem.wire->name), log_signal(value)); + derived_name.c_str(), elem.wire->name.unescape(), log_signal(value)); techmap_do_cache[tpl] = false; } } @@ -741,7 +741,7 @@ struct TechmapWorker auto &data = it.second.front(); if (!data.value.is_fully_const()) - log_error("Techmap yielded config wire %s with non-const value %s.\n", log_id(data.wire->name), log_signal(data.value)); + log_error("Techmap yielded config wire %s with non-const value %s.\n", data.wire->name.unescape(), log_signal(data.value)); techmap_wire_names.erase(it.first); @@ -758,7 +758,7 @@ struct TechmapWorker log("Analyzing pattern of constant bits for this cell:\n"); IdString new_tpl_name = constmap_tpl_name(sigmap, tpl, cell, true); - log("Creating constmapped module `%s'.\n", log_id(new_tpl_name)); + log("Creating constmapped module `%s'.\n", new_tpl_name.unescape()); log_assert(map->module(new_tpl_name) == nullptr); RTLIL::Module *new_tpl = map->addModule(new_tpl_name); @@ -865,16 +865,16 @@ struct TechmapWorker TechmapWires twd = techmap_find_special_wires(tpl); for (auto &it : twd) { if (!it.first.ends_with("_TECHMAP_FAIL_") && (!it.first.begins_with("\\_TECHMAP_REMOVEINIT_") || !it.first.ends_with("_")) && !it.first.contains("_TECHMAP_DO_") && !it.first.contains("_TECHMAP_DONE_")) - log_error("Techmap yielded unknown config wire %s.\n", log_id(it.first)); + log_error("Techmap yielded unknown config wire %s.\n", it.first.unescape()); if (techmap_do_cache[tpl]) for (auto &it2 : it.second) if (!it2.value.is_fully_const()) - log_error("Techmap yielded config wire %s with non-const value %s.\n", log_id(it2.wire->name), log_signal(it2.value)); + log_error("Techmap yielded config wire %s with non-const value %s.\n", it2.wire->name.unescape(), log_signal(it2.value)); techmap_wire_names.erase(it.first); } for (auto &it : techmap_wire_names) - log_error("Techmap special wire %s disappeared. This is considered a fatal error.\n", log_id(it)); + log_error("Techmap special wire %s disappeared. This is considered a fatal error.\n", it.unescape()); if (recursive_mode) { if (log_continue) { @@ -914,7 +914,7 @@ struct TechmapWorker if (extern_mode && !in_recursion) { - std::string m_name = stringf("$extern:%s", log_id(tpl)); + std::string m_name = stringf("$extern:%s", tpl); if (!design->module(m_name)) { @@ -924,18 +924,18 @@ struct TechmapWorker module_queue.insert(m); } - log_debug("%s %s.%s to imported %s.\n", mapmsg_prefix, log_id(module), log_id(cell), log_id(m_name)); + log_debug("%s %s.%s to imported %s.\n", mapmsg_prefix, module, cell, m_name); cell->type = m_name; cell->parameters.clear(); } else { - auto msg = stringf("Using template %s for cells of type %s.", log_id(tpl), log_id(cell->type)); + auto msg = stringf("Using template %s for cells of type %s.", tpl, cell->type.unescape()); if (!log_msg_cache.count(msg)) { log_msg_cache.insert(msg); log("%s\n", msg); } - log_debug("%s %s.%s (%s) using %s.\n", mapmsg_prefix, log_id(module), log_id(cell), log_id(cell->type), log_id(tpl)); + log_debug("%s %s.%s (%s) using %s.\n", mapmsg_prefix, module, cell, cell->type.unescape(), tpl); techmap_module_worker(design, module, cell, tpl); cell = nullptr; } @@ -945,7 +945,7 @@ struct TechmapWorker } if (assert_mode && !mapped_cell) - log_error("(ASSERT MODE) Failed to map cell %s.%s (%s).\n", log_id(module), log_id(cell), log_id(cell->type)); + log_error("(ASSERT MODE) Failed to map cell %s.%s (%s).\n", module, cell, cell->type.unescape()); handled_cells.insert(cell); } @@ -1265,8 +1265,8 @@ struct TechmapPass : public Pass { i.second.sort(RTLIL::sort_by_id_str()); std::string maps = ""; for (auto &map : i.second) - maps += stringf(" %s", log_id(map)); - log_debug(" %s:%s\n", log_id(i.first), maps); + maps += stringf(" %s", map); + log_debug(" %s:%s\n", i.first.unescape(), maps); } log_debug("\n"); diff --git a/passes/techmap/tribuf.cc b/passes/techmap/tribuf.cc index b45cd268a..07f51bdae 100644 --- a/passes/techmap/tribuf.cc +++ b/passes/techmap/tribuf.cc @@ -142,7 +142,7 @@ struct TribufWorker { auto conflict = module->And(NEW_ID, cell_s, other_s); - std::string name = stringf("$tribuf_conflict$%s", log_id(cell->name)); + std::string name = stringf("$tribuf_conflict$%s", cell->name.unescape()); auto assert_cell = module->addAssert(name, module->Not(NEW_ID, conflict), SigSpec(true)); assert_cell->set_src_attribute(cell->get_src_attribute()); diff --git a/passes/techmap/zinit.cc b/passes/techmap/zinit.cc index 809651ebd..5b6a3adaf 100644 --- a/passes/techmap/zinit.cc +++ b/passes/techmap/zinit.cc @@ -68,7 +68,7 @@ struct ZinitPass : public Pass { FfData ff(&initvals, cell); - log("FF init value for cell %s (%s): %s = %s\n", log_id(cell), log_id(cell->type), + log("FF init value for cell %s (%s): %s = %s\n", cell, cell->type.unescape(), log_signal(ff.sig_q), log_signal(ff.val_init)); pool bits; diff --git a/passes/tests/raise_error.cc b/passes/tests/raise_error.cc index b21ec7d1d..95b477bc8 100644 --- a/passes/tests/raise_error.cc +++ b/passes/tests/raise_error.cc @@ -71,7 +71,7 @@ struct RaiseErrorPass : public Pass { int err_no = 1; string err_msg = ""; if (err_obj != nullptr) { - log("Raising error from '%s'.\n", log_id(err_obj)); + log("Raising error from '%s'.\n", err_obj); err_no = err_obj->attributes[ID::raise_error].as_int(); if (err_no > 256) { err_msg = err_obj->get_string_attribute(ID::raise_error); diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index 4d28e659b..3f2588bd1 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -596,20 +596,20 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, bool nosat, std:: for (auto port : gold_mod->ports) { RTLIL::Wire *wire = gold_mod->wire(port); if (wire->port_input) - vlog_file << stringf(" reg [%d:0] %s;\n", GetSize(wire)-1, log_id(wire)); + vlog_file << stringf(" reg [%d:0] %s;\n", GetSize(wire)-1, wire); else - vlog_file << stringf(" wire [%d:0] %s_expr, %s_noexpr;\n", GetSize(wire)-1, log_id(wire), log_id(wire)); + vlog_file << stringf(" wire [%d:0] %s_expr, %s_noexpr;\n", GetSize(wire)-1, wire, wire); } vlog_file << stringf(" %s_expr uut_expr(", uut_name); for (int i = 0; i < GetSize(gold_mod->ports); i++) - vlog_file << stringf("%s.%s(%s%s)", i ? ", " : "", log_id(gold_mod->ports[i]), log_id(gold_mod->ports[i]), + vlog_file << stringf("%s.%s(%s%s)", i ? ", " : "", gold_mod->ports[i].unescape(), gold_mod->ports[i].unescape(), gold_mod->wire(gold_mod->ports[i])->port_input ? "" : "_expr"); vlog_file << stringf(");\n"); vlog_file << stringf(" %s_expr uut_noexpr(", uut_name); for (int i = 0; i < GetSize(gold_mod->ports); i++) - vlog_file << stringf("%s.%s(%s%s)", i ? ", " : "", log_id(gold_mod->ports[i]), log_id(gold_mod->ports[i]), + vlog_file << stringf("%s.%s(%s%s)", i ? ", " : "", gold_mod->ports[i].unescape(), gold_mod->ports[i].unescape(), gold_mod->wire(gold_mod->ports[i])->port_input ? "" : "_noexpr"); vlog_file << stringf(");\n"); @@ -654,7 +654,7 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, bool nosat, std:: } if (verbose) - log("%s: %s\n", log_id(gold_wire), log_signal(in_value)); + log("%s: %s\n", gold_wire, log_signal(in_value)); in_sig.append(gold_wire); in_val.append(in_value); @@ -663,10 +663,10 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, bool nosat, std:: gate_ce.set(gate_wire, in_value); if (vlog_file.is_open() && GetSize(in_value) > 0) { - vlog_file << stringf(" %s = 'b%s;\n", log_id(gold_wire), in_value.as_string()); + vlog_file << stringf(" %s = 'b%s;\n", gold_wire, in_value.as_string()); if (!vlog_pattern_info.empty()) vlog_pattern_info += " "; - vlog_pattern_info += stringf("%s=%s", log_id(gold_wire), log_signal(in_value)); + vlog_pattern_info += stringf("%s=%s", gold_wire, log_signal(in_value)); } } @@ -690,10 +690,10 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, bool nosat, std:: RTLIL::SigSpec gate_outval(gate_wire); if (!gold_ce.eval(gold_outval)) - log_error("Failed to eval %s in gold module.\n", log_id(gold_wire)); + log_error("Failed to eval %s in gold module.\n", gold_wire); if (!gate_ce.eval(gate_outval)) - log_error("Failed to eval %s in gate module.\n", log_id(gate_wire)); + log_error("Failed to eval %s in gate module.\n", gate_wire); bool gold_gate_mismatch = false; for (int i = 0; i < GetSize(gold_wire); i++) { @@ -706,19 +706,19 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, bool nosat, std:: } if (gold_gate_mismatch) - log_error("Mismatch in output %s: gold:%s != gate:%s\n", log_id(gate_wire), log_signal(gold_outval), log_signal(gate_outval)); + log_error("Mismatch in output %s: gold:%s != gate:%s\n", gate_wire, log_signal(gold_outval), log_signal(gate_outval)); if (verbose) - log("%s: %s\n", log_id(gold_wire), log_signal(gold_outval)); + log("%s: %s\n", gold_wire, log_signal(gold_outval)); out_sig.append(gold_wire); out_val.append(gold_outval); if (vlog_file.is_open()) { vlog_file << stringf(" $display(\"[%s] %s expected: %%b, expr: %%b, noexpr: %%b\", %d'b%s, %s_expr, %s_noexpr);\n", - vlog_pattern_info.c_str(), log_id(gold_wire), GetSize(gold_outval), gold_outval.as_string().c_str(), log_id(gold_wire), log_id(gold_wire)); - vlog_file << stringf(" if (%s_expr !== %d'b%s) begin $display(\"ERROR\"); $finish; end\n", log_id(gold_wire), GetSize(gold_outval), gold_outval.as_string()); - vlog_file << stringf(" if (%s_noexpr !== %d'b%s) begin $display(\"ERROR\"); $finish; end\n", log_id(gold_wire), GetSize(gold_outval), gold_outval.as_string()); + vlog_pattern_info.c_str(), gold_wire, GetSize(gold_outval), gold_outval.as_string().c_str(), gold_wire, gold_wire); + vlog_file << stringf(" if (%s_expr !== %d'b%s) begin $display(\"ERROR\"); $finish; end\n", gold_wire, GetSize(gold_outval), gold_outval.as_string()); + vlog_file << stringf(" if (%s_noexpr !== %d'b%s) begin $display(\"ERROR\"); $finish; end\n", gold_wire, GetSize(gold_outval), gold_outval.as_string()); } } @@ -1102,10 +1102,10 @@ struct TestCellPass : public Pass { int charcount = 100; for (auto &it : cell_types) { if (charcount > 60) { - cell_type_list += stringf("\n%s", + log_id(it.first)); + cell_type_list += stringf("\n%s", it.first.unescape()); charcount = 0; } else - cell_type_list += stringf(" %s", log_id(it.first)); + cell_type_list += stringf(" %s", it.first.unescape()); charcount += GetSize(it.first); } log_cmd_error("The cell type `%s' is currently not supported. Try one of these:%s\n", diff --git a/techlibs/anlogic/anlogic_fixcarry.cc b/techlibs/anlogic/anlogic_fixcarry.cc index e8d061b93..5d09498f2 100644 --- a/techlibs/anlogic/anlogic_fixcarry.cc +++ b/techlibs/anlogic/anlogic_fixcarry.cc @@ -69,7 +69,7 @@ static void fix_carry_chain(Module *module) continue; adders_to_fix_cells.push_back(cell); - log("Found %s cell named %s with invalid 'c' signal.\n", log_id(cell->type), log_id(cell)); + log("Found %s cell named %s with invalid 'c' signal.\n", cell->type.unescape(), cell); } } @@ -78,7 +78,7 @@ static void fix_carry_chain(Module *module) SigBit bit_ci = get_bit_or_zero(cell->getPort(ID(c))); SigBit canonical_bit = sigmap(bit_ci); auto bit = mapping_bits.at(canonical_bit); - log("Fixing %s cell named %s breaking carry chain.\n", log_id(cell->type), log_id(cell)); + log("Fixing %s cell named %s breaking carry chain.\n", cell->type.unescape(), cell); Cell *c = module->addCell(NEW_ID, ID(AL_MAP_ADDER)); SigBit new_bit = module->addWire(NEW_ID); SigBit dummy_bit = module->addWire(NEW_ID); diff --git a/techlibs/efinix/efinix_fixcarry.cc b/techlibs/efinix/efinix_fixcarry.cc index c61fa79b8..5056dec1a 100644 --- a/techlibs/efinix/efinix_fixcarry.cc +++ b/techlibs/efinix/efinix_fixcarry.cc @@ -65,7 +65,7 @@ static void fix_carry_chain(Module *module) continue; adders_to_fix_cells.push_back(cell); - log("Found %s cell named %s with invalid CI signal.\n", log_id(cell->type), log_id(cell)); + log("Found %s cell named %s with invalid CI signal.\n", cell->type.unescape(), cell); } } @@ -74,7 +74,7 @@ static void fix_carry_chain(Module *module) SigBit bit_ci = get_bit_or_zero(cell->getPort(ID::CI)); SigBit canonical_bit = sigmap(bit_ci); auto bit = mapping_bits.at(canonical_bit); - log("Fixing %s cell named %s breaking carry chain.\n", log_id(cell->type), log_id(cell)); + log("Fixing %s cell named %s breaking carry chain.\n", cell->type.unescape(), cell); Cell *c = module->addCell(NEW_ID, ID(EFX_ADD)); SigBit new_bit = module->addWire(NEW_ID); c->setParam(ID(I0_POLARITY), State::S1); diff --git a/techlibs/greenpak4/greenpak4_dffinv.cc b/techlibs/greenpak4/greenpak4_dffinv.cc index 4f60a5c37..691013c8e 100644 --- a/techlibs/greenpak4/greenpak4_dffinv.cc +++ b/techlibs/greenpak4/greenpak4_dffinv.cc @@ -86,7 +86,7 @@ void invert_gp_dff(Cell *cell, bool invert_input) cell->type = stringf("\\GP_DFF%s%s%s", cell_type_s ? "S" : "", cell_type_r ? "R" : "", cell_type_i ? "I" : ""); log("Merged %s inverter into cell %s.%s: %s -> %s\n", invert_input ? "input" : "output", - log_id(cell->module), log_id(cell), cell_type.c_str()+1, log_id(cell->type)); + cell->module, cell, cell_type.c_str()+1, cell->type.unescape()); } struct Greenpak4DffInvPass : public Pass { diff --git a/techlibs/ice40/ice40_dsp.cc b/techlibs/ice40/ice40_dsp.cc index 995cdb97e..7942943c4 100644 --- a/techlibs/ice40/ice40_dsp.cc +++ b/techlibs/ice40/ice40_dsp.cc @@ -29,7 +29,7 @@ void create_ice40_dsp(ice40_dsp_pm &pm) { auto &st = pm.st_ice40_dsp; - log("Checking %s.%s for iCE40 DSP inference.\n", log_id(pm.module), log_id(st.mul)); + log("Checking %s.%s for iCE40 DSP inference.\n", pm.module, st.mul); log_debug("ffA: %s\n", log_id(st.ffA, "--")); log_debug("ffB: %s\n", log_id(st.ffB, "--")); @@ -64,7 +64,7 @@ void create_ice40_dsp(ice40_dsp_pm &pm) Cell *cell = st.mul; if (cell->type == ID($mul)) { - log(" replacing %s with SB_MAC16 cell.\n", log_id(st.mul->type)); + log(" replacing %s with SB_MAC16 cell.\n", st.mul->type.unescape()); cell = pm.module->addCell(NEW_ID, ID(SB_MAC16)); pm.module->swap_names(cell, st.mul); @@ -135,22 +135,22 @@ void create_ice40_dsp(ice40_dsp_pm &pm) log(" clock: %s (%s)", log_signal(st.clock), st.clock_pol ? "posedge" : "negedge"); if (st.ffA) - log(" ffA:%s", log_id(st.ffA)); + log(" ffA:%s", st.ffA); if (st.ffB) - log(" ffB:%s", log_id(st.ffB)); + log(" ffB:%s", st.ffB); if (st.ffCD) - log(" ffCD:%s", log_id(st.ffCD)); + log(" ffCD:%s", st.ffCD); if (st.ffFJKG) - log(" ffFJKG:%s", log_id(st.ffFJKG)); + log(" ffFJKG:%s", st.ffFJKG); if (st.ffH) - log(" ffH:%s", log_id(st.ffH)); + log(" ffH:%s", st.ffH); if (st.ffO) - log(" ffO:%s", log_id(st.ffO)); + log(" ffO:%s", st.ffO); log("\n"); } @@ -196,9 +196,9 @@ void create_ice40_dsp(ice40_dsp_pm &pm) if (st.add) { accum = (st.ffO && st.add->getPort(st.addAB == ID::A ? ID::B : ID::A) == st.sigO); if (accum) - log(" accumulator %s (%s)\n", log_id(st.add), log_id(st.add->type)); + log(" accumulator %s (%s)\n", st.add, st.add->type.unescape()); else - log(" adder %s (%s)\n", log_id(st.add), log_id(st.add->type)); + log(" adder %s (%s)\n", st.add, st.add->type.unescape()); cell->setPort(ID(ADDSUBTOP), st.add->type == ID($add) ? State::S0 : State::S1); cell->setPort(ID(ADDSUBBOT), st.add->type == ID($add) ? State::S0 : State::S1); } else { diff --git a/techlibs/ice40/ice40_opt.cc b/techlibs/ice40/ice40_opt.cc index c88fd69b6..67d3813a7 100644 --- a/techlibs/ice40/ice40_opt.cc +++ b/techlibs/ice40/ice40_opt.cc @@ -83,7 +83,7 @@ static void run_ice40_opts(Module *module) module->connect(cell->getPort(ID::CO)[0], replacement_output); module->design->scratchpad_set_bool("opt.did_something", true); log("Optimized away SB_CARRY cell %s.%s: CO=%s\n", - log_id(module), log_id(cell), log_signal(replacement_output)); + module, cell, log_signal(replacement_output)); module->remove(cell); } continue; @@ -137,7 +137,7 @@ static void run_ice40_opts(Module *module) module->connect(cell->getPort(ID::CO)[0], replacement_output); module->design->scratchpad_set_bool("opt.did_something", true); log("Optimized $__ICE40_CARRY_WRAPPER cell back to logic (without SB_CARRY) %s.%s: CO=%s\n", - log_id(module), log_id(cell), log_signal(replacement_output)); + module, cell, log_signal(replacement_output)); cell->type = ID($lut); auto I3 = get_bit_or_zero(cell->getPort(cell->getParam(ID(I3_IS_CI)).as_bool() ? ID::CI : ID(I3))); cell->setPort(ID::A, { I3, inbit[1], inbit[0], get_bit_or_zero(cell->getPort(ID(I0))) }); @@ -175,7 +175,7 @@ static void run_ice40_opts(Module *module) remap_lut: module->design->scratchpad_set_bool("opt.did_something", true); - log("Mapping SB_LUT4 cell %s.%s back to logic.\n", log_id(module), log_id(cell)); + log("Mapping SB_LUT4 cell %s.%s back to logic.\n", module, cell); cell->type = ID($lut); cell->setParam(ID::WIDTH, 4); diff --git a/techlibs/lattice/lattice_gsr.cc b/techlibs/lattice/lattice_gsr.cc index d7d41eca5..a60b54b16 100644 --- a/techlibs/lattice/lattice_gsr.cc +++ b/techlibs/lattice/lattice_gsr.cc @@ -57,7 +57,7 @@ struct LatticeGsrPass : public Pass { for (auto module : design->selected_modules()) { - log("Handling GSR in %s.\n", log_id(module)); + log("Handling GSR in %s.\n", module); SigMap sigmap(module); @@ -69,11 +69,11 @@ struct LatticeGsrPass : public Pass { if (cell->type != ID(GSR) && cell->type != ID(SGSR)) continue; if (found_gsr) - log_error("Found more than one GSR or SGSR cell in module %s.\n", log_id(module)); + log_error("Found more than one GSR or SGSR cell in module %s.\n", module); found_gsr = true; SigSpec sig_gsr = cell->getPort(ID(GSR)); if (GetSize(sig_gsr) < 1) - log_error("GSR cell %s has disconnected GSR input.\n", log_id(cell)); + log_error("GSR cell %s has disconnected GSR input.\n", cell); gsr = sigmap(sig_gsr[0]); } @@ -97,7 +97,7 @@ struct LatticeGsrPass : public Pass { // For finding active low FF inputs pool inverted_gsr; - log_debug("GSR net in module %s is %s.\n", log_id(module), log_signal(gsr)); + log_debug("GSR net in module %s is %s.\n", module, log_signal(gsr)); for (auto cell : module->selected_cells()) { if (cell->type != ID($_NOT_)) diff --git a/techlibs/microchip/microchip_dffopt.cc b/techlibs/microchip/microchip_dffopt.cc index 98e2f17a7..140ef2c9f 100644 --- a/techlibs/microchip/microchip_dffopt.cc +++ b/techlibs/microchip/microchip_dffopt.cc @@ -121,7 +121,7 @@ struct MicrochipDffOptPass : public Pass { extra_args(args, argidx, design); for (auto module : design->selected_modules()) { - log("Optimizing FFs in %s.\n", log_id(module)); + log("Optimizing FFs in %s.\n", module); SigMap sigmap(module); dict> bit_to_lut; @@ -294,7 +294,7 @@ struct MicrochipDffOptPass : public Pass { ports += " + S"; if (worthy_post_ce) ports += " + CE"; - log(" Merging D%s LUTs for %s/%s (%d -> %d)\n", ports, log_id(cell), log_id(sig_Q.wire), + log(" Merging D%s LUTs for %s/%s (%d -> %d)\n", ports, cell, sig_Q.wire, GetSize(lut_d.second), GetSize(final_lut.second)); // Okay, we're doing it. Unmap ports. diff --git a/techlibs/microchip/microchip_dsp.cc b/techlibs/microchip/microchip_dsp.cc index df7093bc5..01c77644f 100644 --- a/techlibs/microchip/microchip_dsp.cc +++ b/techlibs/microchip/microchip_dsp.cc @@ -31,13 +31,13 @@ void microchip_dsp_pack(microchip_dsp_pm &pm) { auto &st = pm.st_microchip_dsp_pack; - log("Analysing %s.%s for Microchip MACC_PA packing.\n", log_id(pm.module), log_id(st.dsp)); + log("Analysing %s.%s for Microchip MACC_PA packing.\n", pm.module, st.dsp); Cell *cell = st.dsp; // pack pre-adder if (st.preAdderStatic) { SigSpec &pasub = cell->connections_.at(ID(PASUB)); - log(" static PASUB preadder %s (%s)\n", log_id(st.preAdderStatic), log_id(st.preAdderStatic->type)); + log(" static PASUB preadder %s (%s)\n", st.preAdderStatic, st.preAdderStatic->type.unescape()); bool D_SIGNED = st.preAdderStatic->getParam(ID::B_SIGNED).as_bool(); bool B_SIGNED = st.preAdderStatic->getParam(ID::A_SIGNED).as_bool(); st.sigB.extend_u0(18, B_SIGNED); @@ -60,7 +60,7 @@ void microchip_dsp_pack(microchip_dsp_pm &pm) } // pack post-adder if (st.postAdderStatic) { - log(" postadder %s (%s)\n", log_id(st.postAdderStatic), log_id(st.postAdderStatic->type)); + log(" postadder %s (%s)\n", st.postAdderStatic, st.postAdderStatic->type.unescape()); SigSpec &sub = cell->connections_.at(ID(SUB)); // Post-adder in MACC_PA also supports subtraction // Determines the sign of the output from the multiplier. @@ -171,13 +171,13 @@ void microchip_dsp_pack(microchip_dsp_pm &pm) log(" clock: %s (%s)\n", log_signal(st.clock), "posedge"); if (st.ffA) - log(" \t ffA:%s\n", log_id(st.ffA)); + log(" \t ffA:%s\n", st.ffA); if (st.ffB) - log(" \t ffB:%s\n", log_id(st.ffB)); + log(" \t ffB:%s\n", st.ffB); if (st.ffD) - log(" \t ffD:%s\n", log_id(st.ffD)); + log(" \t ffD:%s\n", st.ffD); if (st.ffP) - log(" \t ffP:%s\n", log_id(st.ffP)); + log(" \t ffP:%s\n", st.ffP); } log("\n"); @@ -194,7 +194,7 @@ void microchip_dsp_packC(microchip_dsp_CREG_pm &pm) { auto &st = pm.st_microchip_dsp_packC; - log_debug("Analysing %s.%s for Microchip DSP packing (REG_C).\n", log_id(pm.module), log_id(st.dsp)); + log_debug("Analysing %s.%s for Microchip DSP packing (REG_C).\n", pm.module, st.dsp); log_debug("ffC: %s\n", log_id(st.ffC, "--")); Cell *cell = st.dsp; @@ -264,7 +264,7 @@ void microchip_dsp_packC(microchip_dsp_CREG_pm &pm) log(" clock: %s (%s)", log_signal(st.clock), "posedge"); if (st.ffC) - log(" ffC:%s", log_id(st.ffC)); + log(" ffC:%s", st.ffC); log("\n"); } diff --git a/techlibs/quicklogic/ql_bram_merge.cc b/techlibs/quicklogic/ql_bram_merge.cc index 7b99d74e5..eeb06060e 100644 --- a/techlibs/quicklogic/ql_bram_merge.cc +++ b/techlibs/quicklogic/ql_bram_merge.cc @@ -128,7 +128,7 @@ struct QlBramMergeWorker { // Create the new cell RTLIL::Cell* merged = module->addCell(NEW_ID, merged_cell_type); - log_debug("Merging split BRAM cells %s and %s -> %s\n", log_id(bram1->name), log_id(bram2->name), log_id(merged->name)); + log_debug("Merging split BRAM cells %s and %s -> %s\n", bram1->name.unescape(), bram2->name.unescape(), merged->name.unescape()); for (auto &it : param_map(false)) { @@ -146,14 +146,14 @@ struct QlBramMergeWorker { if (bram1->hasPort(it.first)) merged->setPort(it.second, bram1->getPort(it.first)); else - log_error("Can't find port %s on cell %s!\n", log_id(it.first), log_id(bram1->name)); + log_error("Can't find port %s on cell %s!\n", it.first.unescape(), bram1->name.unescape()); } for (auto &it : port_map(true)) { if (bram2->hasPort(it.first)) merged->setPort(it.second, bram2->getPort(it.first)); else - log_error("Can't find port %s on cell %s!\n", log_id(it.first), log_id(bram2->name)); + log_error("Can't find port %s on cell %s!\n", it.first.unescape(), bram2->name.unescape()); } merged->attributes = bram1->attributes; for (auto attr: bram2->attributes) diff --git a/techlibs/quicklogic/ql_bram_types.cc b/techlibs/quicklogic/ql_bram_types.cc index cf42703aa..2599303bd 100644 --- a/techlibs/quicklogic/ql_bram_types.cc +++ b/techlibs/quicklogic/ql_bram_types.cc @@ -155,7 +155,7 @@ struct QlBramTypesPass : public Pass { } cell->type = RTLIL::escape_id(type); - log_debug("Changed type of memory cell %s to %s\n", log_id(cell->name), log_id(cell->type)); + log_debug("Changed type of memory cell %s to %s\n", cell->name.unescape(), cell->type.unescape()); } } diff --git a/techlibs/quicklogic/ql_dsp_io_regs.cc b/techlibs/quicklogic/ql_dsp_io_regs.cc index ecf163dbf..d7255d761 100644 --- a/techlibs/quicklogic/ql_dsp_io_regs.cc +++ b/techlibs/quicklogic/ql_dsp_io_regs.cc @@ -83,19 +83,19 @@ struct QlDspIORegs : public Pass { for (auto cfg_port : {ID(register_inputs), ID(output_select)}) if (!cell->hasPort(cfg_port) || !sigmap(cell->getPort(cfg_port)).is_fully_const()) log_error("Missing or non-constant '%s' port on DSP cell %s\n", - log_id(cfg_port), log_id(cell)); + cfg_port, cell); int reg_in_i = sigmap(cell->getPort(ID(register_inputs))).as_int(); int out_sel_i = sigmap(cell->getPort(ID(output_select))).as_int(); // Get the feedback port if (!cell->hasPort(ID(feedback))) - log_error("Missing 'feedback' port on %s", log_id(cell)); + log_error("Missing 'feedback' port on %s", cell); SigSpec feedback = sigmap(cell->getPort(ID(feedback))); // Check the top two bits on 'feedback' to be constant zero. // That's what we are expecting from inference. if (feedback.extract(1, 2) != SigSpec(0, 2)) - log_error("Unexpected feedback configuration on %s\n", log_id(cell)); + log_error("Unexpected feedback configuration on %s\n", cell); // Build new type name std::string new_type = "\\QL_DSP2_MULT"; diff --git a/techlibs/quicklogic/ql_dsp_macc.cc b/techlibs/quicklogic/ql_dsp_macc.cc index f0669da6c..febfaddf1 100644 --- a/techlibs/quicklogic/ql_dsp_macc.cc +++ b/techlibs/quicklogic/ql_dsp_macc.cc @@ -73,11 +73,11 @@ static void create_ql_macc_dsp(ql_dsp_macc_pm &pm) } type = RTLIL::escape_id(cell_base_name + cell_size_name + "_cfg_ports"); - log("Inferring MACC %zux%zu->%zu as %s from:\n", a_width, b_width, z_width, log_id(type)); + log("Inferring MACC %zux%zu->%zu as %s from:\n", a_width, b_width, z_width, type); for (auto cell : {st.mul, st.add, st.mux, st.ff}) if (cell) - log(" %s (%s)\n", log_id(cell), log_id(cell->type)); + log(" %s (%s)\n", cell, cell->type.unescape()); // Add the DSP cell RTLIL::Cell *cell = pm.module->addCell(NEW_ID, type); diff --git a/techlibs/quicklogic/ql_dsp_simd.cc b/techlibs/quicklogic/ql_dsp_simd.cc index cd509ce7f..da252673f 100644 --- a/techlibs/quicklogic/ql_dsp_simd.cc +++ b/techlibs/quicklogic/ql_dsp_simd.cc @@ -150,13 +150,13 @@ struct QlDspSimdPass : public Pass { // Create the new cell Cell *simd = module->addCell(NEW_ID, m_SimdDspType); - log(" SIMD: %s (%s) + %s (%s) => %s (%s)\n", log_id(dsp_a), log_id(dsp_a->type), - log_id(dsp_b), log_id(dsp_b->type), log_id(simd), log_id(simd->type)); + log(" SIMD: %s (%s) + %s (%s) => %s (%s)\n", dsp_a, dsp_a->type.unescape(), + dsp_b, dsp_b->type.unescape(), simd, simd->type.unescape()); // Check if the target cell is known (important to know // its port widths) if (!simd->known()) - log_error(" The target cell type '%s' is not known!", log_id(simd)); + log_error(" The target cell type '%s' is not known!", simd); // Connect common ports for (const auto &it : m_DspCfgPorts) diff --git a/techlibs/xilinx/xilinx_dffopt.cc b/techlibs/xilinx/xilinx_dffopt.cc index 8a6d3e015..96420be6a 100644 --- a/techlibs/xilinx/xilinx_dffopt.cc +++ b/techlibs/xilinx/xilinx_dffopt.cc @@ -131,7 +131,7 @@ struct XilinxDffOptPass : public Pass { for (auto module : design->selected_modules()) { - log("Optimizing FFs in %s.\n", log_id(module)); + log("Optimizing FFs in %s.\n", module); SigMap sigmap(module); dict> bit_to_lut; @@ -305,7 +305,7 @@ unmap: if (worthy_post_r) ports += " + R"; if (worthy_post_s) ports += " + S"; if (worthy_post_ce) ports += " + CE"; - log(" Merging D%s LUTs for %s/%s (%d -> %d)\n", ports, log_id(cell), log_id(sig_Q.wire), GetSize(lut_d.second), GetSize(final_lut.second)); + log(" Merging D%s LUTs for %s/%s (%d -> %d)\n", ports, cell, sig_Q.wire, GetSize(lut_d.second), GetSize(final_lut.second)); // Okay, we're doing it. Unmap ports. if (worthy_post_r) { diff --git a/techlibs/xilinx/xilinx_dsp.cc b/techlibs/xilinx/xilinx_dsp.cc index 194b9ac10..94fad6453 100644 --- a/techlibs/xilinx/xilinx_dsp.cc +++ b/techlibs/xilinx/xilinx_dsp.cc @@ -140,7 +140,7 @@ void xilinx_simd_pack(Module *module, const std::vector &selected_cells) } } - log("Analysing %s.%s for Xilinx DSP SIMD12 packing.\n", log_id(module), log_id(lane1)); + log("Analysing %s.%s for Xilinx DSP SIMD12 packing.\n", module, lane1); Cell *cell = addDsp(module); cell->setParam(ID(USE_SIMD), Const("FOUR12")); @@ -221,7 +221,7 @@ void xilinx_simd_pack(Module *module, const std::vector &selected_cells) Cell *lane2 = simd24.front(); simd24.pop_front(); - log("Analysing %s.%s for Xilinx DSP SIMD24 packing.\n", log_id(module), log_id(lane1)); + log("Analysing %s.%s for Xilinx DSP SIMD24 packing.\n", module, lane1); Cell *cell = addDsp(module); cell->setParam(ID(USE_SIMD), Const("TWO24")); @@ -260,7 +260,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm) { auto &st = pm.st_xilinx_dsp_pack; - log("Analysing %s.%s for Xilinx DSP packing.\n", log_id(pm.module), log_id(st.dsp)); + log("Analysing %s.%s for Xilinx DSP packing.\n", pm.module, st.dsp); log_debug("preAdd: %s\n", log_id(st.preAdd, "--")); log_debug("preSub: %s\n", log_id(st.preSub, "--")); @@ -282,7 +282,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm) if (st.preAdd || st.preSub) { Cell* preAdder = st.preAdd ? st.preAdd : st.preSub; - log(" preadder %s (%s)\n", log_id(preAdder), log_id(preAdder->type)); + log(" preadder %s (%s)\n", preAdder, preAdder->type.unescape()); bool A_SIGNED = preAdder->getParam(ID::A_SIGNED).as_bool(); bool D_SIGNED = preAdder->getParam(ID::B_SIGNED).as_bool(); if (st.sigA == preAdder->getPort(ID::B)) @@ -312,7 +312,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm) pm.autoremove(preAdder); } if (st.postAdd) { - log(" postadder %s (%s)\n", log_id(st.postAdd), log_id(st.postAdd->type)); + log(" postadder %s (%s)\n", st.postAdd, st.postAdd->type.unescape()); SigSpec &opmode = cell->connections_.at(ID(OPMODE)); if (st.postAddMux) { @@ -338,7 +338,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm) pm.autoremove(st.postAdd); } if (st.overflow) { - log(" overflow %s (%s)\n", log_id(st.overflow), log_id(st.overflow->type)); + log(" overflow %s (%s)\n", st.overflow, st.overflow->type.unescape()); cell->setParam(ID(USE_PATTERN_DETECT), Const("PATDET")); cell->setParam(ID(SEL_PATTERN), Const("PATTERN")); cell->setParam(ID(SEL_MASK), Const("MASK")); @@ -456,28 +456,28 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm) log(" clock: %s (%s)", log_signal(st.clock), "posedge"); if (st.ffA2) { - log(" ffA2:%s", log_id(st.ffA2)); + log(" ffA2:%s", st.ffA2); if (st.ffA1) - log(" ffA1:%s", log_id(st.ffA1)); + log(" ffA1:%s", st.ffA1); } if (st.ffAD) - log(" ffAD:%s", log_id(st.ffAD)); + log(" ffAD:%s", st.ffAD); if (st.ffB2) { - log(" ffB2:%s", log_id(st.ffB2)); + log(" ffB2:%s", st.ffB2); if (st.ffB1) - log(" ffB1:%s", log_id(st.ffB1)); + log(" ffB1:%s", st.ffB1); } if (st.ffD) - log(" ffD:%s", log_id(st.ffD)); + log(" ffD:%s", st.ffD); if (st.ffM) - log(" ffM:%s", log_id(st.ffM)); + log(" ffM:%s", st.ffM); if (st.ffP) - log(" ffP:%s", log_id(st.ffP)); + log(" ffP:%s", st.ffP); } log("\n"); @@ -493,7 +493,7 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm) { auto &st = pm.st_xilinx_dsp48a_pack; - log("Analysing %s.%s for Xilinx DSP48A/DSP48A1 packing.\n", log_id(pm.module), log_id(st.dsp)); + log("Analysing %s.%s for Xilinx DSP48A/DSP48A1 packing.\n", pm.module, st.dsp); log_debug("preAdd: %s\n", log_id(st.preAdd, "--")); log_debug("ffA1: %s\n", log_id(st.ffA1, "--")); @@ -511,7 +511,7 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm) SigSpec &opmode = cell->connections_.at(ID(OPMODE)); if (st.preAdd) { - log(" preadder %s (%s)\n", log_id(st.preAdd), log_id(st.preAdd->type)); + log(" preadder %s (%s)\n", st.preAdd, st.preAdd->type.unescape()); bool D_SIGNED = st.preAdd->getParam(ID::A_SIGNED).as_bool(); bool B_SIGNED = st.preAdd->getParam(ID::B_SIGNED).as_bool(); st.sigB.extend_u0(18, B_SIGNED); @@ -529,7 +529,7 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm) pm.autoremove(st.preAdd); } if (st.postAdd) { - log(" postadder %s (%s)\n", log_id(st.postAdd), log_id(st.postAdd->type)); + log(" postadder %s (%s)\n", st.postAdd, st.postAdd->type.unescape()); if (st.postAddMux) { log_assert(st.ffP); @@ -639,23 +639,23 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm) log(" clock: %s (%s)", log_signal(st.clock), "posedge"); if (st.ffA0) - log(" ffA0:%s", log_id(st.ffA0)); + log(" ffA0:%s", st.ffA0); if (st.ffA1) - log(" ffA1:%s", log_id(st.ffA1)); + log(" ffA1:%s", st.ffA1); if (st.ffB0) - log(" ffB0:%s", log_id(st.ffB0)); + log(" ffB0:%s", st.ffB0); if (st.ffB1) - log(" ffB1:%s", log_id(st.ffB1)); + log(" ffB1:%s", st.ffB1); if (st.ffD) - log(" ffD:%s", log_id(st.ffD)); + log(" ffD:%s", st.ffD); if (st.ffM) - log(" ffM:%s", log_id(st.ffM)); + log(" ffM:%s", st.ffM); if (st.ffP) - log(" ffP:%s", log_id(st.ffP)); + log(" ffP:%s", st.ffP); } log("\n"); @@ -671,7 +671,7 @@ void xilinx_dsp_packC(xilinx_dsp_CREG_pm &pm) { auto &st = pm.st_xilinx_dsp_packC; - log_debug("Analysing %s.%s for Xilinx DSP packing (CREG).\n", log_id(pm.module), log_id(st.dsp)); + log_debug("Analysing %s.%s for Xilinx DSP packing (CREG).\n", pm.module, st.dsp); log_debug("ffC: %s\n", log_id(st.ffC, "--")); Cell *cell = st.dsp; @@ -724,7 +724,7 @@ void xilinx_dsp_packC(xilinx_dsp_CREG_pm &pm) log(" clock: %s (%s)", log_signal(st.clock), "posedge"); if (st.ffC) - log(" ffC:%s", log_id(st.ffC)); + log(" ffC:%s", st.ffC); log("\n"); } diff --git a/techlibs/xilinx/xilinx_srl.cc b/techlibs/xilinx/xilinx_srl.cc index 2c23f8f42..e23062eb7 100644 --- a/techlibs/xilinx/xilinx_srl.cc +++ b/techlibs/xilinx/xilinx_srl.cc @@ -30,11 +30,11 @@ void run_fixed(xilinx_srl_pm &pm) { auto &st = pm.st_fixed; auto &ud = pm.ud_fixed; - log("Found fixed chain of length %d (%s):\n", GetSize(ud.longest_chain), log_id(st.first->type)); + log("Found fixed chain of length %d (%s):\n", GetSize(ud.longest_chain), st.first->type.unescape()); SigSpec initval; for (auto cell : ud.longest_chain) { - log_debug(" %s\n", log_id(cell)); + log_debug(" %s\n", cell); if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_), ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_))) { SigBit Q = cell->getPort(ID::Q); log_assert(Q.wire); @@ -100,7 +100,7 @@ void run_fixed(xilinx_srl_pm &pm) else log_abort(); - log(" -> %s (%s)\n", log_id(c), log_id(c->type)); + log(" -> %s (%s)\n", c, c->type.unescape()); } void run_variable(xilinx_srl_pm &pm) @@ -108,13 +108,13 @@ void run_variable(xilinx_srl_pm &pm) auto &st = pm.st_variable; auto &ud = pm.ud_variable; - log("Found variable chain of length %d (%s):\n", GetSize(ud.chain), log_id(st.first->type)); + log("Found variable chain of length %d (%s):\n", GetSize(ud.chain), st.first->type.unescape()); SigSpec initval; for (const auto &i : ud.chain) { auto cell = i.first; auto slice = i.second; - log_debug(" %s\n", log_id(cell)); + log_debug(" %s\n", cell); if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_), ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_), ID($dff), ID($dffe))) { SigBit Q = cell->getPort(ID::Q)[slice]; log_assert(Q.wire); @@ -181,7 +181,7 @@ void run_variable(xilinx_srl_pm &pm) else log_abort(); - log(" -> %s (%s)\n", log_id(c), log_id(c->type)); + log(" -> %s (%s)\n", c, c->type.unescape()); } struct XilinxSrlPass : public Pass { From fb83719745e67ae1bfcd6e977438cbd2bcedf248 Mon Sep 17 00:00:00 2001 From: Leo Moser Date: Sat, 9 May 2026 10:28:07 +0200 Subject: [PATCH 007/354] memlib: fix documentation for `PORT__CLK_POL` Signed-off-by: Leo Moser --- passes/memory/memlib.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/memory/memlib.md b/passes/memory/memlib.md index f3c0dd937..5ad3f7777 100644 --- a/passes/memory/memlib.md +++ b/passes/memory/memlib.md @@ -310,7 +310,7 @@ The port clock is always provided on the memory cell as `PORT__CLK` signal (even if it is also shared). Shared clocks are also provided as `CLK_` signals. -For `anyedge` clocks, the cell gets a `PORT__CLKPOL` parameter that is set +For `anyedge` clocks, the cell gets a `PORT__CLK_POL` parameter that is set to 1 for `posedge` clocks and 0 for `negedge` clocks. If the clock is shared, the same information will also be provided as `CLK__POL` parameter. From 40c14858288e12f838ff1b73cc53c3a19d876b4e Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 11 May 2026 14:37:21 +0200 Subject: [PATCH 008/354] Update ABC, reverts 6aaf0db1e1201d72888a461463485b0b5595075a --- abc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/abc b/abc index d217b3519..98967c9f3 160000 --- a/abc +++ b/abc @@ -1 +1 @@ -Subproject commit d217b351925ffc5e3036073776fef1810d258499 +Subproject commit 98967c9f3afe4fbfae2d4da57bfd97848576c875 From 7fe32137bdf7c78bfccb8ba09e6fdfddfdf57a90 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 11 May 2026 14:47:08 +0200 Subject: [PATCH 009/354] Revert "Fix tests due to ABC improvements" This reverts commit 417e871b06baf709a8de4a66e9eab890a8f9d041. --- tests/arch/analogdevices/logic.ys | 5 +++-- tests/arch/analogdevices/mux.ys | 6 ++++-- tests/arch/ecp5/add_sub.ys | 8 +++++--- tests/arch/ecp5/lutram.ys | 7 ++++--- tests/arch/gowin/logic.ys | 4 ++-- tests/arch/gowin/mux.ys | 19 ++++++++++++------- tests/arch/intel_alm/logic.ys | 4 ++-- tests/arch/nexus/add_sub.ys | 4 ++-- tests/pyosys/test_design_run_pass.py | 8 +++++--- tests/pyosys/test_ecp5_addsub.py | 8 +++++--- 10 files changed, 44 insertions(+), 29 deletions(-) diff --git a/tests/arch/analogdevices/logic.ys b/tests/arch/analogdevices/logic.ys index 2289685ac..9314c7825 100644 --- a/tests/arch/analogdevices/logic.ys +++ b/tests/arch/analogdevices/logic.ys @@ -6,5 +6,6 @@ design -load postopt # load the post-opt design (otherwise equiv_opt loads the p cd top # Constrain all select calls below inside the top module select -assert-count 1 t:LUT1 -select -assert-count 9 t:LUT2 -select -assert-none t:LUT1 t:LUT2 %% t:* %D +select -assert-count 6 t:LUT2 +select -assert-count 2 t:LUT4 +select -assert-none t:LUT1 t:LUT2 t:LUT4 %% t:* %D diff --git a/tests/arch/analogdevices/mux.ys b/tests/arch/analogdevices/mux.ys index 3244b0dc3..375ce90f2 100644 --- a/tests/arch/analogdevices/mux.ys +++ b/tests/arch/analogdevices/mux.ys @@ -41,8 +41,10 @@ equiv_opt -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux16 # Constrain all select calls below inside the top module select -assert-max 2 t:LUT3 -select -assert-max 1 t:LUT5 +select -assert-max 2 t:LUT4 select -assert-min 4 t:LUT6 +select -assert-max 7 t:LUT6 +select -assert-max 2 t:LUTMUX7 dump -select -assert-none t:LUT6 t:LUT5 t:LUT3 %% t:* %D +select -assert-none t:LUT6 t:LUT4 t:LUT3 t:LUTMUX7 %% t:* %D diff --git a/tests/arch/ecp5/add_sub.ys b/tests/arch/ecp5/add_sub.ys index 9c3c03499..c3ce8c56d 100644 --- a/tests/arch/ecp5/add_sub.ys +++ b/tests/arch/ecp5/add_sub.ys @@ -4,7 +4,9 @@ proc equiv_opt -assert -map +/ecp5/cells_sim.v synth_ecp5 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module -select -assert-min 11 t:LUT4 -select -assert-count 2 t:PFUMX -select -assert-none t:LUT4 t:PFUMX %% t:* %D +select -assert-min 25 t:LUT4 +select -assert-max 26 t:LUT4 +select -assert-count 10 t:PFUMX +select -assert-count 6 t:L6MUX21 +select -assert-none t:LUT4 t:PFUMX t:L6MUX21 %% t:* %D diff --git a/tests/arch/ecp5/lutram.ys b/tests/arch/ecp5/lutram.ys index e83890a54..9bef37c68 100644 --- a/tests/arch/ecp5/lutram.ys +++ b/tests/arch/ecp5/lutram.ys @@ -11,8 +11,9 @@ sat -verify -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs mite design -load postopt cd lutram_1w1r -select -assert-count 28 t:LUT4 -select -assert-count 8 t:PFUMX +select -assert-count 8 t:L6MUX21 +select -assert-count 36 t:LUT4 +select -assert-count 16 t:PFUMX select -assert-count 8 t:TRELLIS_DPR16X4 select -assert-count 8 t:TRELLIS_FF -select -assert-none t:LUT4 t:PFUMX t:TRELLIS_DPR16X4 t:TRELLIS_FF %% t:* %D +select -assert-none t:L6MUX21 t:LUT4 t:PFUMX t:TRELLIS_DPR16X4 t:TRELLIS_FF %% t:* %D diff --git a/tests/arch/gowin/logic.ys b/tests/arch/gowin/logic.ys index 15f050e9b..d2b9e4540 100644 --- a/tests/arch/gowin/logic.ys +++ b/tests/arch/gowin/logic.ys @@ -7,7 +7,7 @@ cd top # Constrain all select calls below inside the top module select -assert-count 1 t:LUT1 select -assert-count 6 t:LUT2 -select -assert-count 2 t:LUT3 +select -assert-count 2 t:LUT4 select -assert-count 8 t:IBUF select -assert-count 10 t:OBUF -select -assert-none t:LUT1 t:LUT2 t:LUT3 t:IBUF t:OBUF %% t:* %D +select -assert-none t:LUT1 t:LUT2 t:LUT4 t:IBUF t:OBUF %% t:* %D diff --git a/tests/arch/gowin/mux.ys b/tests/arch/gowin/mux.ys index fddf91d0e..2ca973520 100644 --- a/tests/arch/gowin/mux.ys +++ b/tests/arch/gowin/mux.ys @@ -18,12 +18,13 @@ proc equiv_opt -assert -map +/gowin/cells_sim.v synth_gowin # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux4 # Constrain all select calls below inside the top module -select -assert-count 3 t:LUT* -select -assert-count 1 t:MUX2_LUT5 +select -assert-count 4 t:LUT* +select -assert-count 2 t:MUX2_LUT5 +select -assert-count 1 t:MUX2_LUT6 select -assert-count 6 t:IBUF select -assert-count 1 t:OBUF -select -assert-none t:LUT* t:MUX2_LUT5 t:IBUF t:OBUF %% t:* %D +select -assert-none t:LUT* t:MUX2_LUT6 t:MUX2_LUT5 t:IBUF t:OBUF %% t:* %D design -load read hierarchy -top mux8 @@ -31,13 +32,17 @@ proc equiv_opt -assert -map +/gowin/cells_sim.v synth_gowin # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux8 # Constrain all select calls below inside the top module -select -assert-count 1 t:LUT3 -select -assert-count 5 t:LUT4 -select -assert-count 1 t:MUX2_LUT5 +select -assert-count 3 t:LUT1 +select -assert-count 2 t:LUT3 +select -assert-count 1 t:LUT4 +select -assert-count 5 t:MUX2_LUT5 +select -assert-count 2 t:MUX2_LUT6 +select -assert-count 1 t:MUX2_LUT7 select -assert-count 11 t:IBUF select -assert-count 1 t:OBUF +select -assert-count 1 t:GND -select -assert-none t:LUT* t:MUX2_LUT5 t:IBUF t:OBUF %% t:* %D +select -assert-none t:LUT* t:MUX2_LUT7 t:MUX2_LUT6 t:MUX2_LUT5 t:IBUF t:OBUF t:GND %% t:* %D design -load read hierarchy -top mux16 diff --git a/tests/arch/intel_alm/logic.ys b/tests/arch/intel_alm/logic.ys index 91d6043e0..831f9f174 100644 --- a/tests/arch/intel_alm/logic.ys +++ b/tests/arch/intel_alm/logic.ys @@ -7,6 +7,6 @@ cd top # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_NOT select -assert-count 6 t:MISTRAL_ALUT2 -select -assert-count 2 t:MISTRAL_ALUT3 -select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT2 t:MISTRAL_ALUT3 %% t:* %D +select -assert-count 2 t:MISTRAL_ALUT4 +select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT2 t:MISTRAL_ALUT4 %% t:* %D diff --git a/tests/arch/nexus/add_sub.ys b/tests/arch/nexus/add_sub.ys index c1599c57e..4317bab81 100644 --- a/tests/arch/nexus/add_sub.ys +++ b/tests/arch/nexus/add_sub.ys @@ -16,6 +16,6 @@ equiv_opt -assert -map +/nexus/cells_sim.v synth_nexus -abc9 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module stat -select -assert-count 7 t:LUT4 -select -assert-count 2 t:WIDEFN9 +select -assert-count 6 t:LUT4 +select -assert-count 4 t:WIDEFN9 select -assert-none t:IB t:OB t:VLO t:LUT4 t:WIDEFN9 %% t:* %D diff --git a/tests/pyosys/test_design_run_pass.py b/tests/pyosys/test_design_run_pass.py index 6e31a7f1c..f0013577d 100644 --- a/tests/pyosys/test_design_run_pass.py +++ b/tests/pyosys/test_design_run_pass.py @@ -13,6 +13,8 @@ base.run_pass("equiv_opt -assert -map +/ecp5/cells_sim.v synth_ecp5") postopt = ys.Design() postopt.run_pass("design -load postopt") postopt.run_pass(["cd", "top"]) -postopt.run_pass("select -assert-min 11 t:LUT4") -postopt.run_pass(["select", "-assert-count", "2", "t:PFUMX"]) -postopt.run_pass("select -assert-none t:LUT4 t:PFUMX %% t:* %D") +postopt.run_pass("select -assert-min 25 t:LUT4") +postopt.run_pass("select -assert-max 26 t:LUT4") +postopt.run_pass(["select", "-assert-count", "10", "t:PFUMX"]) +postopt.run_pass(["select", "-assert-count", "6", "t:L6MUX21"]) +postopt.run_pass("select -assert-none t:LUT4 t:PFUMX t:L6MUX21 %% t:* %D") diff --git a/tests/pyosys/test_ecp5_addsub.py b/tests/pyosys/test_ecp5_addsub.py index 96258e3ba..ddc50b775 100644 --- a/tests/pyosys/test_ecp5_addsub.py +++ b/tests/pyosys/test_ecp5_addsub.py @@ -13,6 +13,8 @@ ys.run_pass("equiv_opt -assert -map +/ecp5/cells_sim.v synth_ecp5", base) postopt = ys.Design() ys.run_pass("design -load postopt", postopt) ys.run_pass("cd top", postopt) -ys.run_pass("select -assert-min 11 t:LUT4", postopt) -ys.run_pass("select -assert-count 2 t:PFUMX", postopt) -ys.run_pass("select -assert-none t:LUT4 t:PFUMX %% t:* %D", postopt) +ys.run_pass("select -assert-min 25 t:LUT4", postopt) +ys.run_pass("select -assert-max 26 t:LUT4", postopt) +ys.run_pass("select -assert-count 10 t:PFUMX", postopt) +ys.run_pass("select -assert-count 6 t:L6MUX21", postopt) +ys.run_pass("select -assert-none t:LUT4 t:PFUMX t:L6MUX21 %% t:* %D", postopt) From b61bc1eee0f4bca6ad4fdec172693c8f5eb132b3 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 12 May 2026 08:37:44 +0200 Subject: [PATCH 010/354] Update ABC as per 2026-05-12 --- abc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/abc b/abc index 98967c9f3..5d51a5e42 160000 --- a/abc +++ b/abc @@ -1 +1 @@ -Subproject commit 98967c9f3afe4fbfae2d4da57bfd97848576c875 +Subproject commit 5d51a5e420f5de493d07bf61109a977248c86ffb From b85cad634782fafac275e5f540c056bfacb2b5d2 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 12 May 2026 11:37:23 +0200 Subject: [PATCH 011/354] Release version 0.65 --- CHANGELOG | 10 +++++++++- Makefile | 4 ++-- docs/source/conf.py | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 94e62df4b..f8697205d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,8 +2,16 @@ List of major changes and improvements between releases ======================================================= -Yosys 0.64 .. Yosys 0.65-dev +Yosys 0.64 .. Yosys 0.65 -------------------------- + * New commands and options + - Added "arith_tree" pass to convert add/sub/macc chains + to carry-save adder trees. + - Removed "-force" option from "share" pass. + + * Various + - read_verilog: support positional assignment patterns + for unpacked arrays. Yosys 0.63 .. Yosys 0.64 -------------------------- diff --git a/Makefile b/Makefile index 543ec7f44..5ed3dc5dd 100644 --- a/Makefile +++ b/Makefile @@ -161,7 +161,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.64 +YOSYS_VER := 0.65 ifneq (, $(shell command -v git 2>/dev/null)) ifneq (, $(shell git rev-parse --git-dir 2>/dev/null)) @@ -170,7 +170,7 @@ ifneq (, $(shell git rev-parse --git-dir 2>/dev/null)) YOSYS_VER := $(YOSYS_VER)+$(GIT_COMMIT_COUNT) endif else - YOSYS_VER := $(YOSYS_VER)+post +# YOSYS_VER := $(YOSYS_VER)+post endif endif diff --git a/docs/source/conf.py b/docs/source/conf.py index 9520948cf..b85c391db 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -6,7 +6,7 @@ import os project = 'YosysHQ Yosys' author = 'YosysHQ GmbH' copyright ='2026 YosysHQ GmbH' -yosys_ver = "0.64" +yosys_ver = "0.65" # select HTML theme html_theme = 'furo-ys' From 6f16a5cf5ffa163950e49c0adc8092194cb0bc18 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 12 May 2026 12:32:27 +0200 Subject: [PATCH 012/354] Next dev cycle --- CHANGELOG | 3 +++ Makefile | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index f8697205d..01faf44c2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ List of major changes and improvements between releases ======================================================= +Yosys 0.65 .. Yosys 0.66-dev +-------------------------- + Yosys 0.64 .. Yosys 0.65 -------------------------- * New commands and options diff --git a/Makefile b/Makefile index 5ed3dc5dd..4af083df4 100644 --- a/Makefile +++ b/Makefile @@ -170,7 +170,7 @@ ifneq (, $(shell git rev-parse --git-dir 2>/dev/null)) YOSYS_VER := $(YOSYS_VER)+$(GIT_COMMIT_COUNT) endif else -# YOSYS_VER := $(YOSYS_VER)+post + YOSYS_VER := $(YOSYS_VER)+post endif endif From b06f9bdf18039bd643c2989921abbd87d554889a Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Tue, 12 May 2026 12:51:12 +0200 Subject: [PATCH 013/354] Makefile: error on unused variables --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 543ec7f44..e95d6cace 100644 --- a/Makefile +++ b/Makefile @@ -104,7 +104,7 @@ VPATH := $(YOSYS_SRC) UNITESTPATH := $(YOSYS_SRC)/tests/unit export CXXSTD ?= c++17 -CXXFLAGS := $(CXXFLAGS) -Wall -Wextra -ggdb -I. -I"$(YOSYS_SRC)" -MD -MP -D_YOSYS_ -fPIC -I$(PREFIX)/include +CXXFLAGS := $(CXXFLAGS) -Wall -Wextra -Werror=unused -ggdb -I. -I"$(YOSYS_SRC)" -MD -MP -D_YOSYS_ -fPIC -I$(PREFIX)/include LIBS := $(LIBS) -lstdc++ -lm PLUGIN_LINKFLAGS := PLUGIN_LIBS := From 4eb1c61bd57d182e7ca470f3ff51d2a751edea6c Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Tue, 12 May 2026 12:51:41 +0200 Subject: [PATCH 014/354] hashlib: error on unused containers --- kernel/hashlib.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/kernel/hashlib.h b/kernel/hashlib.h index b43a68abf..937116178 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -55,6 +55,12 @@ namespace hashlib { * instead of pointers. */ +#if defined(__GNUC__) || defined(__clang__) +# define HASHLIB_ATTRIBUTE_WARN_UNUSED __attribute__((warn_unused)) +#else +# define HASHLIB_ATTRIBUTE_WARN_UNUSED +#endif + const int hashtable_size_trigger = 2; const int hashtable_size_factor = 3; @@ -402,7 +408,7 @@ private: }; template -class dict { +class HASHLIB_ATTRIBUTE_WARN_UNUSED dict { struct entry_t { std::pair udata; @@ -877,7 +883,7 @@ public: }; template -class pool +class HASHLIB_ATTRIBUTE_WARN_UNUSED pool { template friend class idict; @@ -1257,7 +1263,7 @@ public: }; template -class idict +class HASHLIB_ATTRIBUTE_WARN_UNUSED idict { pool database; @@ -1360,7 +1366,7 @@ public: * i-prefixed methods operate on indices in parents */ template -class mfp +class HASHLIB_ATTRIBUTE_WARN_UNUSED mfp { idict database; class AtomicParent { From 3a150f28838a8b171de819d712463f29cb7f4411 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Tue, 12 May 2026 12:52:10 +0200 Subject: [PATCH 015/354] remove unused hashlib containers --- passes/equiv/equiv_make.cc | 1 + passes/opt/muxpack.cc | 1 - passes/opt/opt_lut.cc | 4 +--- passes/sat/qbfsat.h | 1 - passes/techmap/abc9_ops.cc | 1 - passes/techmap/flowmap.cc | 4 ++-- 6 files changed, 4 insertions(+), 8 deletions(-) diff --git a/passes/equiv/equiv_make.cc b/passes/equiv/equiv_make.cc index bae7452f7..a9a728f94 100644 --- a/passes/equiv/equiv_make.cc +++ b/passes/equiv/equiv_make.cc @@ -79,6 +79,7 @@ struct EquivMakeWorker if (token == ".fsm") { IdString modname = RTLIL::escape_id(next_token(line)); + (void)modname; IdString signame = RTLIL::escape_id(next_token(line)); if (encdata.count(signame)) log_cmd_error("Re-definition of signal '%s' in encfile '%s'!\n", signame, fn); diff --git a/passes/opt/muxpack.cc b/passes/opt/muxpack.cc index ac47f6bf7..c13790edf 100644 --- a/passes/opt/muxpack.cc +++ b/passes/opt/muxpack.cc @@ -263,7 +263,6 @@ struct MuxpackWorker int cases = GetSize(chain) - cursor; Cell *first_cell = chain[cursor]; - dict taps_dict; if (cases < 2) { cursor++; diff --git a/passes/opt/opt_lut.cc b/passes/opt/opt_lut.cc index c0a017748..81a7e5a43 100644 --- a/passes/opt/opt_lut.cc +++ b/passes/opt/opt_lut.cc @@ -421,13 +421,12 @@ struct OptLutWorker } RTLIL::Cell *lutM, *lutR; - pool lutM_inputs, lutR_inputs; + pool lutR_inputs; pool lutM_dlogic_inputs; if (combine == COMBINE_A) { log_debug(" Combining LUTs into cell A.\n"); lutM = lutA; - lutM_inputs = lutA_inputs; lutM_dlogic_inputs = lutA_dlogic_inputs; lutR = lutB; lutR_inputs = lutB_inputs; @@ -436,7 +435,6 @@ struct OptLutWorker { log_debug(" Combining LUTs into cell B.\n"); lutM = lutB; - lutM_inputs = lutB_inputs; lutM_dlogic_inputs = lutB_dlogic_inputs; lutR = lutA; lutR_inputs = lutA_inputs; diff --git a/passes/sat/qbfsat.h b/passes/sat/qbfsat.h index 253cecce4..3441b7819 100644 --- a/passes/sat/qbfsat.h +++ b/passes/sat/qbfsat.h @@ -170,7 +170,6 @@ struct QbfSolutionType { std::smatch m; bool sat_regex_found = false; bool unsat_regex_found = false; - dict hole_value_recovered; for (const std::string &x : stdout_lines) { if(std::regex_search(x, m, hole_value_regex)) { std::string loc = m[1].str(); diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index e7cf8c637..fc27ac58a 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -97,7 +97,6 @@ void check(RTLIL::Design *design, bool dff_mode) ID($_DLATCHSR_PNN_), ID($_DLATCHSR_PNP_), ID($_DLATCHSR_PPN_), ID($_DLATCHSR_PPP_), ID($_SR_NN_), ID($_SR_NP_), ID($_SR_PN_), ID($_SR_PP_) }; - pool processed; for (auto module : design->selected_modules()) for (auto cell : module->cells()) { auto inst_module = design->module(cell->type); diff --git a/passes/techmap/flowmap.cc b/passes/techmap/flowmap.cc index f5f225a9b..5b447745a 100644 --- a/passes/techmap/flowmap.cc +++ b/passes/techmap/flowmap.cc @@ -1246,14 +1246,14 @@ struct FlowmapWorker } } log(" Breaking LUT %s to %s LUT %s (potential %d).\n", - log_signal(breaking_lut), lut_nodes[breaking_gate] ? "reuse" : "extract", log_signal(breaking_gate), best_potential); + log_signal(breaking_lut), lut_nodes[breaking_gate] ? "reuse" : "extract", log_signal(breaking_gate), best_potential); if (debug_relax) log(" Removing breaking gate %s from LUT.\n", log_signal(breaking_gate)); lut_gates[breaking_lut].erase(breaking_gate); auto cut_inputs = cut_lut_at_gate(breaking_lut, breaking_gate); - pool gate_inputs = cut_inputs.first, other_inputs = cut_inputs.second; + pool gate_inputs = cut_inputs.first; pool worklist = lut_gates[breaking_lut]; pool elim_gates = gate_inputs; From 74efc883c73ab4e6d900e40ff06a052917ac16f5 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Tue, 12 May 2026 23:16:43 +0200 Subject: [PATCH 016/354] threading: temporarily cast to void unused stuff, until we rework single-threaded builds again --- kernel/threading.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/kernel/threading.cc b/kernel/threading.cc index 817a48df0..eda6bb4cb 100644 --- a/kernel/threading.cc +++ b/kernel/threading.cc @@ -45,9 +45,12 @@ int ThreadPool::pool_size(int reserved_cores, int max_worker_threads) #ifdef YOSYS_ENABLE_THREADS int available_threads = std::min(std::thread::hardware_concurrency(), get_max_threads()); int num_threads = std::min(available_threads - reserved_cores, max_worker_threads); - return std::max(0, num_threads); + return std::max(0, num_threads); #else - return 0; + (void)reserved_cores; + (void)max_worker_threads; + (void)get_max_threads(); + return 0; #endif } @@ -146,6 +149,8 @@ void ParallelDispatchThreadPool::run_worker(int thread_num) signal_worker_done(); } signal_worker_done(); +#else + (void)current_work; #endif } From 1e28e8ccab9921e0fdd349bfa9bfa78e78ad1bea Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 13 May 2026 09:49:39 +0200 Subject: [PATCH 017/354] Handle unused variable for WIN32 --- kernel/driver.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/driver.cc b/kernel/driver.cc index 30c9a285f..73b687f80 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -664,6 +664,7 @@ int main(int argc, char **argv) #ifdef _WIN32 log("End of script. Logfile hash: %s\n", hash); + (void)wall_clock_start; #else std::string meminfo; std::string stats_divider = ", "; From 6ff6f8fb3c7c8075a10bec1034176b44e0cc07c0 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 13 May 2026 10:10:59 +0200 Subject: [PATCH 018/354] Bump required standard to C++20 --- .github/workflows/test-compile.yml | 16 ++++++++-------- Makefile | 4 ++-- misc/create_vcxsrc.sh | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/test-compile.yml b/.github/workflows/test-compile.yml index 9c75784bf..c322c25b2 100644 --- a/.github/workflows/test-compile.yml +++ b/.github/workflows/test-compile.yml @@ -82,20 +82,20 @@ jobs: $CXX --version # minimum standard - - name: Build C++17 - shell: bash - run: | - make config-$CC_SHORT - make -j$procs CXXSTD=c++17 compile-only - - # maximum standard, only on newest compilers - name: Build C++20 - if: ${{ matrix.compiler == 'clang-19' || matrix.compiler == 'gcc-14' }} shell: bash run: | make config-$CC_SHORT make -j$procs CXXSTD=c++20 compile-only + # maximum standard, only on newest compilers + - name: Build C++26 + if: ${{ matrix.compiler == 'clang-19' || matrix.compiler == 'gcc-14' }} + shell: bash + run: | + make config-$CC_SHORT + make -j$procs CXXSTD=c++26 compile-only + test-compile-result: runs-on: ubuntu-latest needs: diff --git a/Makefile b/Makefile index 3c5c10cda..afbc11005 100644 --- a/Makefile +++ b/Makefile @@ -103,7 +103,7 @@ VPATH := $(YOSYS_SRC) # Unit test UNITESTPATH := $(YOSYS_SRC)/tests/unit -export CXXSTD ?= c++17 +export CXXSTD ?= c++20 CXXFLAGS := $(CXXFLAGS) -Wall -Wextra -Werror=unused -ggdb -I. -I"$(YOSYS_SRC)" -MD -MP -D_YOSYS_ -fPIC -I$(PREFIX)/include LIBS := $(LIBS) -lstdc++ -lm PLUGIN_LINKFLAGS := @@ -1142,7 +1142,7 @@ vcxsrc: $(GENFILES) $(EXTRA_TARGETS) kernel/version_$(GIT_REV).cc rm -rf $(VCX_DIR_NAME){,.zip} cp -f kernel/version_$(GIT_REV).cc kernel/version.cc set -e; for f in `ls $(filter %.cc %.cpp,$(GENFILES)) $(addsuffix .cc,$(basename $(OBJS))) $(addsuffix .cpp,$(basename $(OBJS))) 2> /dev/null`; do \ - echo "Analyse: $$f" >&2; cpp -std=c++17 -MM -I. -D_YOSYS_ $$f; done | sed 's,.*:,,; s,//*,/,g; s,/[^/]*/\.\./,/,g; y, \\,\n\n,;' | grep '^[^/]' | sort -u | grep -v kernel/version_ > srcfiles.txt + echo "Analyse: $$f" >&2; cpp -std=c++20 -MM -I. -D_YOSYS_ $$f; done | sed 's,.*:,,; s,//*,/,g; s,/[^/]*/\.\./,/,g; y, \\,\n\n,;' | grep '^[^/]' | sort -u | grep -v kernel/version_ > srcfiles.txt echo "libs/fst/fst_win_unistd.h" >> srcfiles.txt echo "kernel/version.cc" >> srcfiles.txt bash misc/create_vcxsrc.sh $(VCX_DIR_NAME) $(YOSYS_VER) diff --git a/misc/create_vcxsrc.sh b/misc/create_vcxsrc.sh index 98c1817bd..c880c2a48 100644 --- a/misc/create_vcxsrc.sh +++ b/misc/create_vcxsrc.sh @@ -35,7 +35,7 @@ popd tail -n +$((n+1)) "$vcxsrc"/YosysVS/YosysVS.vcxproj } > "$vcxsrc"/YosysVS/YosysVS.vcxproj.new -sed -i 's,,\n stdcpp17\n /Zc:__cplusplus %(AdditionalOptions),g' "$vcxsrc"/YosysVS/YosysVS.vcxproj.new +sed -i 's,,\n stdcpp20\n /Zc:__cplusplus %(AdditionalOptions),g' "$vcxsrc"/YosysVS/YosysVS.vcxproj.new sed -i 's,,YOSYS_ENABLE_THREADS;,g' "$vcxsrc"/YosysVS/YosysVS.vcxproj.new if [ -f "/usr/include/FlexLexer.h" ] ; then sed -i 's,,;..\\yosys\\libs\\flex,g' "$vcxsrc"/YosysVS/YosysVS.vcxproj.new From 90e019e319a0b0b81c4b95199937900b20045cce Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 13 May 2026 10:11:36 +0200 Subject: [PATCH 019/354] Fix compiling on GCC11 --- passes/cmds/timeest.cc | 6 +++--- passes/sat/formalff.cc | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/passes/cmds/timeest.cc b/passes/cmds/timeest.cc index 1caa1ddaf..4f6105356 100644 --- a/passes/cmds/timeest.cc +++ b/passes/cmds/timeest.cc @@ -100,7 +100,7 @@ struct EstimateSta { log_id(cell), log_id(cell->type)); continue; } - if (ff.sig_clk != clk) + if (!clk || ff.sig_clk.as_bit() != *clk) continue; launch.append(ff.sig_q); sample.append(ff.sig_d); @@ -144,12 +144,12 @@ struct EstimateSta { log_error("Unsupported async memory port '%s'\n", log_id(rd.cell)); continue; } - if (sigmap(rd.clk) != clk) + if (!clk || sigmap(rd.clk).as_bit() != *clk) continue; add_seq(rd.cell, rd.data, {rd.addr, rd.srst, rd.en}); } for (auto &wr : mem.wr_ports) { - if (sigmap(wr.clk) != clk) + if (!clk || sigmap(wr.clk).as_bit() != *clk) continue; add_seq(wr.cell, {}, {wr.en, wr.addr, wr.data}); } diff --git a/passes/sat/formalff.cc b/passes/sat/formalff.cc index 452e0e59b..5ac93eca7 100644 --- a/passes/sat/formalff.cc +++ b/passes/sat/formalff.cc @@ -767,7 +767,7 @@ struct FormalFfPass : public Pass { ff.sig_d = ff.sig_ad; } - if (!ff.has_clk || sigmap(ff.sig_clk) != gate_clock || ff.pol_clk != pol_clk) { + if (!ff.has_clk || sigmap(ff.sig_clk).as_bit() != gate_clock || ff.pol_clk != pol_clk) { log_debug("FF driver for gate enable %s.%s of gated clk bit %s.%s has incompatible clocking: " "%s %s.%s\n", log_id(module), log_signal(SigSpec(gate_enable)), log_id(module), @@ -798,7 +798,7 @@ struct FormalFfPass : public Pass { auto &mem = memories.at(clocked_cell->name); bool changed = false; for (auto &rd_port : mem.rd_ports) { - if (rd_port.clk_enable && rd_port.clk == clk && rd_port.clk_polarity == pol_clk) { + if (rd_port.clk_enable && rd_port.clk.as_bit() == clk && rd_port.clk_polarity == pol_clk) { log_debug("patching rd port\n"); changed = true; rd_port.clk = gate_clock; @@ -808,7 +808,7 @@ struct FormalFfPass : public Pass { } } for (auto &wr_port : mem.wr_ports) { - if (wr_port.clk_enable && wr_port.clk == clk && wr_port.clk_polarity == pol_clk) { + if (wr_port.clk_enable && wr_port.clk.as_bit() == clk && wr_port.clk_polarity == pol_clk) { log_debug("patching wr port\n"); changed = true; wr_port.clk = gate_clock; From 25459bd8b96d2e6fedf120b6de703578b5126889 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 13 May 2026 11:09:40 +0200 Subject: [PATCH 020/354] Fix for clang-10 toolchain --- .github/workflows/test-compile.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/test-compile.yml b/.github/workflows/test-compile.yml index c322c25b2..2540a8415 100644 --- a/.github/workflows/test-compile.yml +++ b/.github/workflows/test-compile.yml @@ -74,6 +74,7 @@ jobs: uses: aminya/setup-cpp@v1 with: compiler: ${{ matrix.compiler }} + gcc: ${{ (matrix.os == 'ubuntu-latest' && matrix.compiler == 'clang-10') && '10' || '' }} - name: Tool versions shell: bash @@ -81,6 +82,11 @@ jobs: $CC --version $CXX --version + - name: Fix clang-10 toolchain + if: matrix.os == 'ubuntu-latest' && matrix.compiler == 'clang-10' + run: | + echo "CXXFLAGS=--gcc-toolchain=/usr/lib/gcc/x86_64-linux-gnu/10 -stdlib=libstdc++" >> $GITHUB_ENV + # minimum standard - name: Build C++20 shell: bash From 1ef6311e5b80d6a9b5a32cfcd4e987a1f7f93cd1 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 13 May 2026 11:24:45 +0200 Subject: [PATCH 021/354] Update documentation and few more defines --- docs/source/getting_started/installation.rst | 2 +- docs/source/yosys_internals/extending_yosys/contributing.rst | 2 +- docs/source/yosys_internals/index.rst | 2 +- kernel/yosys_common.h | 4 ++-- pyosys/generator.py | 2 +- tests/functional/test_functional.py | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/source/getting_started/installation.rst b/docs/source/getting_started/installation.rst index 43b996353..2a90a8071 100644 --- a/docs/source/getting_started/installation.rst +++ b/docs/source/getting_started/installation.rst @@ -87,7 +87,7 @@ not regularly tested: Build prerequisites ^^^^^^^^^^^^^^^^^^^ -A C++ compiler with C++17 support is required as well as some standard tools +A C++ compiler with C++20 support is required as well as some standard tools such as GNU Flex, GNU Bison (>=3.8), Make, and Python (>=3.11). Some additional tools: readline, libffi, Tcl and zlib; are optional but enabled by default (see :makevar:`ENABLE_*` settings in Makefile). Graphviz and Xdot are used by the diff --git a/docs/source/yosys_internals/extending_yosys/contributing.rst b/docs/source/yosys_internals/extending_yosys/contributing.rst index 1ff77a1fd..8d90d2cbe 100644 --- a/docs/source/yosys_internals/extending_yosys/contributing.rst +++ b/docs/source/yosys_internals/extending_yosys/contributing.rst @@ -286,7 +286,7 @@ have incorrect results in unusual situations. Coding style ~~~~~~~~~~~~ -Yosys is written in C++17. +Yosys is written in C++20. In general Yosys uses ``int`` instead of ``size_t``. To avoid compiler warnings for implicit type casts, always use ``GetSize(foobar)`` instead of diff --git a/docs/source/yosys_internals/index.rst b/docs/source/yosys_internals/index.rst index 483cc2bf8..217b88e36 100644 --- a/docs/source/yosys_internals/index.rst +++ b/docs/source/yosys_internals/index.rst @@ -25,7 +25,7 @@ wide range of real-world designs, including the `OpenRISC 1200 CPU`_, the .. _k68 CPU: http://opencores.org/projects/k68 -Yosys is written in C++, targeting C++17 at minimum. This chapter describes some +Yosys is written in C++, targeting C++20 at minimum. This chapter describes some of the fundamental Yosys data structures. For the sake of simplicity the C++ type names used in the Yosys implementation are used in this chapter, even though the chapter only explains the conceptual idea behind it and can be used diff --git a/kernel/yosys_common.h b/kernel/yosys_common.h index 47dae5473..062036dba 100644 --- a/kernel/yosys_common.h +++ b/kernel/yosys_common.h @@ -120,10 +120,10 @@ # define YS_MAYBE_UNUSED #endif -#if __cplusplus >= 201703L +#if __cplusplus >= 202002L # define YS_FALLTHROUGH [[fallthrough]]; #else -# error "C++17 or later compatible compiler is required" +# error "C++20 or later compatible compiler is required" #endif #if defined(__has_cpp_attribute) && __has_cpp_attribute(gnu::cold) diff --git a/pyosys/generator.py b/pyosys/generator.py index f1d429724..4fd7a5698 100644 --- a/pyosys/generator.py +++ b/pyosys/generator.py @@ -376,7 +376,7 @@ class PyosysWrapperGenerator(object): def make_preprocessor_options(self): py_include = get_paths()["include"] preprocessor_bin = shutil.which("clang++") or "g++" - cxx_std = os.getenv("CXX_STD", "c++17") + cxx_std = os.getenv("CXX_STD", "c++20") return ParserOptions( preprocessor=make_gcc_preprocessor( defines=["_YOSYS_", "YOSYS_ENABLE_PYTHON"], diff --git a/tests/functional/test_functional.py b/tests/functional/test_functional.py index aa7500f8b..661af14d1 100644 --- a/tests/functional/test_functional.py +++ b/tests/functional/test_functional.py @@ -21,7 +21,7 @@ def yosys(script): run([base_path / 'yosys', '-Q', '-p', script]) def compile_cpp(in_path, out_path, args): - run(['g++', '-g', '-std=c++17'] + args + [str(in_path), '-o', str(out_path)]) + run(['g++', '-g', '-std=c++20'] + args + [str(in_path), '-o', str(out_path)]) def yosys_synth(verilog_file, rtlil_file): yosys(f"read_verilog {quote(verilog_file)} ; prep ; setundef -undriven -undef ; write_rtlil {quote(rtlil_file)}") From 81219c58b2504061cfbae10867589ccc0110f984 Mon Sep 17 00:00:00 2001 From: Iztok Jeras Date: Wed, 13 May 2026 11:59:22 +0200 Subject: [PATCH 022/354] documentation: updated description of 'abc' argument '-dont_use' --- passes/techmap/abc.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index 1ed0c867d..bd05aa30d 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -1935,8 +1935,10 @@ struct AbcPass : public Pass { log(" file format).\n"); log("\n"); log(" -dont_use \n"); - log(" generate netlists for the specified cell library (using the liberty\n"); - log(" file format).\n"); + log(" avoid usage of the technology cell when mapping the design.\n"); + log(" this option can be used multiple times with different cell names and\n"); + log(" supports simple glob patterns in the cell name.\n"); + log(" only supported with Liberty cell libraries.\n"); log("\n"); log(" -genlib \n"); log(" generate netlists for the specified cell library (using the SIS Genlib\n"); From 105011a53b7454f9d819c4bb4978fa03ad565bb2 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 13 May 2026 12:05:13 +0200 Subject: [PATCH 023/354] Zero array for for MSVC --- kernel/io.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/io.h b/kernel/io.h index 171f47a80..96b5bb55d 100644 --- a/kernel/io.h +++ b/kernel/io.h @@ -441,7 +441,8 @@ public: private: std::string_view fmt; bool has_escapes = false; - FoundFormatSpec specs[sizeof...(Args)] = {}; + // Making array at least size of one to make MSVC happy and strict to standards + FoundFormatSpec specs[sizeof...(Args) ? sizeof...(Args) : 1] = {}; }; template struct WrapType { using type = T; }; From 9182329fa1c0b8e73909744dff0cd7865bead342 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 13 May 2026 12:05:37 +0200 Subject: [PATCH 024/354] Try making clang-10 to work --- .github/workflows/test-compile.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-compile.yml b/.github/workflows/test-compile.yml index 2540a8415..a896ccf87 100644 --- a/.github/workflows/test-compile.yml +++ b/.github/workflows/test-compile.yml @@ -85,7 +85,7 @@ jobs: - name: Fix clang-10 toolchain if: matrix.os == 'ubuntu-latest' && matrix.compiler == 'clang-10' run: | - echo "CXXFLAGS=--gcc-toolchain=/usr/lib/gcc/x86_64-linux-gnu/10 -stdlib=libstdc++" >> $GITHUB_ENV + echo "CXXFLAGS=--gcc-toolchain=/usr" >> $GITHUB_ENV # minimum standard - name: Build C++20 From 9070c83145068efe16547720c3b6120eb5fdf1f0 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 13 May 2026 13:28:09 +0200 Subject: [PATCH 025/354] Fix for generated project files to work with latest VS --- misc/create_vcxsrc.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/create_vcxsrc.sh b/misc/create_vcxsrc.sh index c880c2a48..dccc31fac 100644 --- a/misc/create_vcxsrc.sh +++ b/misc/create_vcxsrc.sh @@ -25,6 +25,7 @@ if [ -f "/usr/include/FlexLexer.h" ] ; then cp /usr/include/FlexLexer.h libs/flex/FlexLexer.h ls libs/flex/*.h >> ../../srcfiles.txt fi +sed -i '\#libs/../kernel/yosys.h#d' ../../srcfiles.txt popd { From 6d4e5f5ad045899ba9fde0fa00513d01920f2027 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 13 May 2026 14:38:58 +0200 Subject: [PATCH 026/354] Bump versions to safe floor --- .github/workflows/test-compile.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test-compile.yml b/.github/workflows/test-compile.yml index a896ccf87..fe6a43634 100644 --- a/.github/workflows/test-compile.yml +++ b/.github/workflows/test-compile.yml @@ -44,8 +44,8 @@ jobs: - ubuntu-latest compiler: # oldest supported - - 'clang-10' - - 'gcc-10' + - 'clang-14' + - 'gcc-11' # newest, make sure to update maximum standard step to match - 'clang-19' - 'gcc-14' @@ -74,7 +74,7 @@ jobs: uses: aminya/setup-cpp@v1 with: compiler: ${{ matrix.compiler }} - gcc: ${{ (matrix.os == 'ubuntu-latest' && matrix.compiler == 'clang-10') && '10' || '' }} + gcc: ${{ (matrix.os == 'ubuntu-latest' && matrix.compiler == 'clang-14') && '12' || '' }} - name: Tool versions shell: bash @@ -82,10 +82,10 @@ jobs: $CC --version $CXX --version - - name: Fix clang-10 toolchain - if: matrix.os == 'ubuntu-latest' && matrix.compiler == 'clang-10' + - name: Fix clang-14 toolchain + if: matrix.os == 'ubuntu-latest' && matrix.compiler == 'clang-14' run: | - echo "CXXFLAGS=--gcc-toolchain=/usr" >> $GITHUB_ENV + echo 'CXXFLAGS=--gcc-toolchain=/usr -isystem /usr/include/c++/12 -isystem /usr/include/x86_64-linux-gnu/c++/12' >> $GITHUB_ENV # minimum standard - name: Build C++20 From 7d3e56523bf93fb3c63fc19de843278f38e43012 Mon Sep 17 00:00:00 2001 From: nella Date: Wed, 13 May 2026 16:25:15 +0200 Subject: [PATCH 027/354] Preserve param signedness across overrides. --- kernel/rtlil.cc | 9 +++++++++ kernel/rtlil.h | 2 ++ passes/cmds/setattr.cc | 1 + passes/hierarchy/hierarchy.cc | 8 ++++++-- tests/verilog/issue5745.ys | 18 ++++++++++++++++++ 5 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 tests/verilog/issue5745.ys diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index a99f0803e..1a7dc6b41 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -615,6 +615,15 @@ int RTLIL::Const::as_int_saturating(bool is_signed) const return as_int(is_signed); } +void RTLIL::Const::tag_bare_integer_const(const std::string &value) +{ + if (value.empty() || value.find('\'') != std::string::npos) + return; + size_t start = (value[0] == '-' || value[0] == '+') ? 1 : 0; + if (start < value.size() && std::all_of(value.begin() + start, value.end(), ::isdigit)) + flags |= RTLIL::CONST_FLAG_SIGNED; +} + int RTLIL::Const::get_min_size(bool is_signed) const { if (empty()) return 0; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index b32f9ea76..e55caf35a 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1091,6 +1091,8 @@ public: // over/underflow, otherwise the max/min value for int depending on the sign. int as_int_saturating(bool is_signed = false) const; + void tag_bare_integer_const(const std::string &value); + std::string as_string(const char* any = "-") const; static Const from_string(const std::string &str); std::vector to_bits() const; diff --git a/passes/cmds/setattr.cc b/passes/cmds/setattr.cc index 25d8fd34c..ef9bd0d34 100644 --- a/passes/cmds/setattr.cc +++ b/passes/cmds/setattr.cc @@ -41,6 +41,7 @@ struct setunset_t if (!RTLIL::SigSpec::parse(sig_value, nullptr, set_value)) log_cmd_error("Can't decode value '%s'!\n", set_value); value = sig_value.as_const(); + value.tag_bare_integer_const(set_value); } } }; diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 416997bee..34cedfd34 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -985,7 +985,9 @@ struct HierarchyPass : public Pass { SigSpec sig_value; if (!RTLIL::SigSpec::parse(sig_value, NULL, para.second)) log_cmd_error("Can't decode value '%s'!\n", para.second); - top_parameters[RTLIL::escape_id(para.first)] = sig_value.as_const(); + RTLIL::Const c = sig_value.as_const(); + c.tag_bare_integer_const(para.second); + top_parameters[RTLIL::escape_id(para.first)] = c; } } @@ -1073,7 +1075,9 @@ struct HierarchyPass : public Pass { SigSpec sig_value; if (!RTLIL::SigSpec::parse(sig_value, NULL, para.second)) log_cmd_error("Can't decode value '%s'!\n", para.second); - top_parameters[RTLIL::escape_id(para.first)] = sig_value.as_const(); + RTLIL::Const c = sig_value.as_const(); + c.tag_bare_integer_const(para.second); + top_parameters[RTLIL::escape_id(para.first)] = c; } top_mod = design->module(top_mod->derive(design, top_parameters)); diff --git a/tests/verilog/issue5745.ys b/tests/verilog/issue5745.ys new file mode 100644 index 000000000..938ead63a --- /dev/null +++ b/tests/verilog/issue5745.ys @@ -0,0 +1,18 @@ +# Issue #5745: chparam values are unsigned when using read_verilog frontend +# +# When chparam overrides a parameter value, the signed attribute is lost, +# causing signed comparisons to silently use unsigned logic. +# +# m = -32 (signed 9-bit), p2 = 11. Correct signed semantics: -32 < 11, so k = 1. +# Bug: chparam strips the signed attribute from p2. The $lt cell gets A_SIGNED=0, +# B_SIGNED=0, so the comparison treats m as unsigned (480 > 11), giving k = 0. + +read_verilog < Date: Wed, 13 May 2026 16:52:07 +0200 Subject: [PATCH 028/354] Make sure to apply correct signedness to loop vars. --- backends/verilog/verilog_backend.cc | 11 ++--- frontends/ast/simplify.cc | 29 ++++++++----- tests/verilog/for_loop_signed_index.ys | 56 ++++++++++++++++++++++++++ tests/verilog/issue4402.ys | 32 +++++++++++++++ 4 files changed, 112 insertions(+), 16 deletions(-) create mode 100644 tests/verilog/for_loop_signed_index.ys create mode 100644 tests/verilog/issue4402.ys diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 73ffcbf3e..d5f83aefc 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -456,21 +456,22 @@ void dump_wire(std::ostream &f, std::string indent, RTLIL::Wire *wire) if (wire->attributes.count(ID::single_bit_vector)) range = stringf(" [%d:%d]", wire->start_offset, wire->start_offset); } + std::string sign = wire->is_signed ? " signed" : ""; if (wire->port_input && !wire->port_output) - f << stringf("%s" "input%s %s;\n", indent, range, id(wire->name)); + f << stringf("%s" "input%s%s %s;\n", indent, sign, range, id(wire->name)); if (!wire->port_input && wire->port_output) - f << stringf("%s" "output%s %s;\n", indent, range, id(wire->name)); + f << stringf("%s" "output%s%s %s;\n", indent, sign, range, id(wire->name)); if (wire->port_input && wire->port_output) - f << stringf("%s" "inout%s %s;\n", indent, range, id(wire->name)); + f << stringf("%s" "inout%s%s %s;\n", indent, sign, range, id(wire->name)); if (reg_wires.count(wire->name)) { - f << stringf("%s" "reg%s %s", indent, range, id(wire->name)); + f << stringf("%s" "reg%s%s %s", indent, sign, range, id(wire->name)); if (wire->attributes.count(ID::init)) { f << stringf(" = "); dump_const(f, wire->attributes.at(ID::init)); } f << stringf(";\n"); } else - f << stringf("%s" "wire%s %s;\n", indent, range, id(wire->name)); + f << stringf("%s" "wire%s%s %s;\n", indent, sign, range, id(wire->name)); #endif } diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 48a4291d2..3012a4ccf 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -2619,21 +2619,27 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin input_error("Right hand side of 1st expression of %s for-loop is not constant!\n", loop_type_str); auto resolved = current_scope.at(init_ast->children[0]->str); - if (resolved->range_valid) { - int const_size = varbuf->range_left - varbuf->range_right; - int resolved_size = resolved->range_left - resolved->range_right; - if (const_size < resolved_size) { - for (int i = const_size; i < resolved_size; i++) - varbuf->bits.push_back(resolved->is_signed ? varbuf->bits.back() : State::S0); - varbuf->range_left = resolved->range_left; - varbuf->range_right = resolved->range_right; - varbuf->range_swapped = resolved->range_swapped; - varbuf->range_valid = resolved->range_valid; + auto apply_loop_var_type = [&resolved](std::unique_ptr &value) { + if (resolved->range_valid) { + int const_size = value->range_left - value->range_right; + int resolved_size = resolved->range_left - resolved->range_right; + if (const_size < resolved_size) { + for (int i = const_size; i < resolved_size; i++) + value->bits.push_back(resolved->is_signed ? value->bits.back() : State::S0); + value->range_left = resolved->range_left; + value->range_right = resolved->range_right; + value->range_swapped = resolved->range_swapped; + value->range_valid = resolved->range_valid; + } } - } + value->is_signed = resolved->is_signed; + }; + + apply_loop_var_type(varbuf); varbuf = std::make_unique(location, AST_LOCALPARAM, std::move(varbuf)); varbuf->str = init_ast->children[0]->str; + varbuf->is_signed = resolved->is_signed; AstNode *backup_scope_varbuf = current_scope[varbuf->str]; current_scope[varbuf->str] = varbuf.get(); @@ -2708,6 +2714,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin if (buf->type != AST_CONSTANT) input_error("Right hand side of 3rd expression of %s for-loop is not constant (%s)!\n", loop_type_str, type2str(buf->type)); + apply_loop_var_type(buf); varbuf->children[0] = std::move(buf); } diff --git a/tests/verilog/for_loop_signed_index.ys b/tests/verilog/for_loop_signed_index.ys new file mode 100644 index 000000000..a2bde3395 --- /dev/null +++ b/tests/verilog/for_loop_signed_index.ys @@ -0,0 +1,56 @@ +# Regression test: when procedural for-loops are unrolled, the constant +# replacement for the loop variable must keep the variable's declared +# signedness. + +read_verilog < y=0 +# Post-synthesis (unfixed): wire0 loses signed, 1<=0 false -> y=1 (BUG) +# Post-synthesis (fixed): wire0 retains signed, -1<=0 true -> y=0 + +! mkdir -p temp + +read_verilog < Date: Wed, 13 May 2026 10:57:18 -0700 Subject: [PATCH 029/354] Reuse knowledge_t and pass by reference --- passes/opt/opt_muxtree.cc | 56 ++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index 8bf151e71..4c07f61d8 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -200,6 +200,29 @@ struct OptMuxtreeWorker root_muxes.at(driving_mux) = true; } + struct knowledge_t + { + // Known inactive signals + // The payload is a reference counter used to manage the list + // When it is non-zero, the signal in known to be inactive + // When it reaches zero, the map element is removed + std::vector known_inactive; + + // database of known active signals + std::vector known_active; + + // this is just used to keep track of visited muxes in order to prohibit + // endless recursion in mux loops + std::vector visited_muxes; + + // Initialize with the maximum possible sizes + knowledge_t(int num_bits, int num_muxes) { + known_inactive.assign(num_bits, 0); + known_active.assign(num_bits, 0); + visited_muxes.assign(num_muxes, false); + } + }; + OptMuxtreeWorker(RTLIL::Design *design, RTLIL::Module *module) : design(design), module(module), assign_map(module), removed_count(0) { @@ -227,11 +250,13 @@ struct OptMuxtreeWorker populate_roots(); + knowledge_t shared_knowledge(GetSize(bit2info), GetSize(mux2info)); + for (int mux_idx = 0; mux_idx < GetSize(root_muxes); mux_idx++) if (root_muxes.at(mux_idx)) { log_debug(" Root of a mux tree: %s%s\n", log_id(mux2info[mux_idx].cell), root_enable_muxes.at(mux_idx) ? " (pure)" : ""); root_mux_rerun.erase(mux_idx); - eval_root_mux(mux_idx); + eval_root_mux(shared_knowledge, mux_idx); if (glob_evals_left == 0) { log(" Giving up (too many iterations)\n"); return; @@ -243,7 +268,7 @@ struct OptMuxtreeWorker log_debug(" Root of a mux tree: %s (rerun as non-pure)\n", log_id(mux2info[mux_idx].cell)); log_assert(root_enable_muxes.at(mux_idx)); root_mux_rerun.erase(mux_idx); - eval_root_mux(mux_idx); + eval_root_mux(shared_knowledge, mux_idx); if (glob_evals_left == 0) { log(" Giving up (too many iterations)\n"); return; @@ -334,29 +359,6 @@ struct OptMuxtreeWorker return results; } - struct knowledge_t - { - // Known inactive signals - // The payload is a reference counter used to manage the list - // When it is non-zero, the signal in known to be inactive - // When it reaches zero, the map element is removed - std::vector known_inactive; - - // database of known active signals - std::vector known_active; - - // this is just used to keep track of visited muxes in order to prohibit - // endless recursion in mux loops - std::vector visited_muxes; - - // Initialize with the maximum possible sizes - knowledge_t(int num_bits, int num_muxes) { - known_inactive.assign(num_bits, 0); - known_active.assign(num_bits, 0); - visited_muxes.assign(num_muxes, false); - } - }; - static void activate_port(knowledge_t &knowledge, int port_idx, const muxinfo_t &muxinfo) { // First, mark all other ports inactive for (int i = 0; i < GetSize(muxinfo.ports); i++) { @@ -579,14 +581,14 @@ struct OptMuxtreeWorker } } - void eval_root_mux(int mux_idx) + void eval_root_mux(knowledge_t &knowledge, int mux_idx) { log_assert(glob_evals_left > 0); - knowledge_t knowledge(GetSize(bit2info), GetSize(mux2info)); knowledge.visited_muxes[mux_idx] = true; limits_t limits = {}; limits.do_mark_ports_observable = root_enable_muxes.at(mux_idx); eval_mux(knowledge, mux_idx, limits); + knowledge.visited_muxes[mux_idx] = false; } }; From 6ac8758e7eb42ca498b4dfa93672335344e920e5 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 7 May 2026 09:44:42 +0200 Subject: [PATCH 030/354] Generate coverage for tests --- .github/workflows/test-verific.yml | 26 +++++++++++++++++++++++++- Makefile | 1 + 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test-verific.yml b/.github/workflows/test-verific.yml index 132aac589..6e3284167 100644 --- a/.github/workflows/test-verific.yml +++ b/.github/workflows/test-verific.yml @@ -47,7 +47,7 @@ jobs: - name: Build Yosys run: | - make config-clang + make config-gcov echo "ENABLE_VERIFIC := 1" >> Makefile.conf echo "ENABLE_VERIFIC_EDIF := 1" >> Makefile.conf echo "ENABLE_VERIFIC_LIBERTY := 1" >> Makefile.conf @@ -85,6 +85,30 @@ jobs: run: | make -C sby run_ci + - name: Run coverage + if: ${{ github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' }} + run: | + make coverage + + - name: Push coverage + if: ${{ github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' }} + run: | + git clone https://x-access-token:${{ secrets.REPORTS_TOKEN }}@github.com/YosysHQ/reports.git out + rm -rf out/coverage/main + mkdir -p out/coverage/main + cp -r coverage_html/* out/coverage/main/ + cd out + # find . -name "*.html" -type f -print0 | xargs -0 sed -i -z 's#\(Date:[[:space:]]*\)[^<]*\(\)#\1\2#g' + git config user.name "yosyshq-ci" + git config user.email "105224853+yosyshq-ci@users.noreply.github.com" + git add . + if ! git diff --cached --quiet; then + git commit -m "Update coverage" + git push + else + echo "No changes to commit" + fi + test-pyosys: needs: pre_job if: ${{ needs.pre_job.outputs.should_skip != 'true' && github.repository_owner == 'YosysHQ' }} diff --git a/Makefile b/Makefile index 3c5c10cda..f6ba73375 100644 --- a/Makefile +++ b/Makefile @@ -1117,6 +1117,7 @@ coverage: ./$(PROGRAM_PREFIX)yosys -qp 'help; help -all' rm -rf coverage.info coverage_html lcov --capture -d . --no-external -o coverage.info + lcov --remove coverage.info '*/tests/various/*' '*/libs/*' -o coverage.info --ignore-errors unused genhtml coverage.info --output-directory coverage_html clean_coverage: From 70b17181b42f1c1264dcb4c50916575e61a65f3c Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 14 May 2026 10:51:40 +0200 Subject: [PATCH 031/354] Bump gcc and clang versions --- .github/workflows/test-compile.yml | 6 +++--- kernel/fmt.cc | 6 ++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test-compile.yml b/.github/workflows/test-compile.yml index fe6a43634..3e2ac34c9 100644 --- a/.github/workflows/test-compile.yml +++ b/.github/workflows/test-compile.yml @@ -47,8 +47,8 @@ jobs: - 'clang-14' - 'gcc-11' # newest, make sure to update maximum standard step to match - - 'clang-19' - - 'gcc-14' + - 'clang-22' + - 'gcc-15' include: # macOS x86 - os: macos-15-intel @@ -96,7 +96,7 @@ jobs: # maximum standard, only on newest compilers - name: Build C++26 - if: ${{ matrix.compiler == 'clang-19' || matrix.compiler == 'gcc-14' }} + if: ${{ matrix.compiler == 'clang-19' || matrix.compiler == 'clang-22' || matrix.compiler == 'gcc-15' }} shell: bash run: | make config-$CC_SHORT diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 200e7e5ce..15179a75a 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -804,8 +804,10 @@ std::string Fmt::render() const buf += 'X'; else if (has_z) buf += 'Z'; - else - buf += (part.hex_upper ? "0123456789ABCDEF" : "0123456789abcdef")[subvalue.as_int()]; + else { + const char *digits = part.hex_upper ? "0123456789ABCDEF" : "0123456789abcdef"; + buf += digits[subvalue.as_int()]; + } } } else if (part.base == 10) { if (part.show_base) From c6f53aec5fe951022896f89c399b67f3dc7366ae Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 14 May 2026 11:28:16 +0200 Subject: [PATCH 032/354] Fixed log_id instances used with fprintf --- passes/cmds/viz.cc | 2 +- passes/fsm/fsm_recode.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/cmds/viz.cc b/passes/cmds/viz.cc index 9eb35d6c2..0d4e3efda 100644 --- a/passes/cmds/viz.cc +++ b/passes/cmds/viz.cc @@ -718,7 +718,7 @@ struct VizWorker void write_dot(FILE *f) { - fprintf(f, "digraph \"%s\" {\n", module); + fprintf(f, "digraph \"%s\" {\n", module->name.unescape().c_str()); fprintf(f, " rankdir = LR;\n"); dict>> extra_lines; diff --git a/passes/fsm/fsm_recode.cc b/passes/fsm/fsm_recode.cc index 5c813e481..b32c01c39 100644 --- a/passes/fsm/fsm_recode.cc +++ b/passes/fsm/fsm_recode.cc @@ -96,7 +96,7 @@ static void fsm_recode(RTLIL::Cell *cell, RTLIL::Module *module, FILE *fm_set_fs log_error("FSM encoding `%s' is not supported!\n", encoding); if (encfile) - fprintf(encfile, ".fsm %s %s\n", module, RTLIL::unescape_id(cell->parameters[ID::NAME].decode_string()).c_str()); + fprintf(encfile, ".fsm %s %s\n", module->name.unescape().c_str(), RTLIL::unescape_id(cell->parameters[ID::NAME].decode_string()).c_str()); int state_idx_counter = fsm_data.reset_state >= 0 ? 1 : 0; for (int i = 0; i < int(fsm_data.state_table.size()); i++) From 58df27ce7c17ec8881936fea531a4e727a1c1b78 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 14 May 2026 12:21:32 +0200 Subject: [PATCH 033/354] Refactor uses of log_id in pgm files --- passes/opt/peepopt_formal_clockgateff.pmg | 2 +- passes/opt/peepopt_muldiv.pmg | 2 +- passes/opt/peepopt_muldiv_c.pmg | 2 +- passes/opt/peepopt_shiftadd.pmg | 2 +- passes/opt/peepopt_shiftmul_left.pmg | 2 +- passes/opt/peepopt_shiftmul_right.pmg | 2 +- techlibs/microchip/microchip_dsp_cascade.pmg | 4 ++-- techlibs/xilinx/xilinx_dsp_cascade.pmg | 8 ++++---- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/passes/opt/peepopt_formal_clockgateff.pmg b/passes/opt/peepopt_formal_clockgateff.pmg index 835f68bd8..1f44a2cf4 100644 --- a/passes/opt/peepopt_formal_clockgateff.pmg +++ b/passes/opt/peepopt_formal_clockgateff.pmg @@ -44,7 +44,7 @@ endmatch code log("replacing clock gate pattern in %s with ff: latch=%s, and=%s\n", - log_id(module), log_id(latch), log_id(and_gate)); + module, latch, and_gate); // Add a flip-flop and rewire the AND gate to use the output of this flop // instead of the latch. We don't delete the latch in case its output is diff --git a/passes/opt/peepopt_muldiv.pmg b/passes/opt/peepopt_muldiv.pmg index a4e232342..c7eb8ec95 100644 --- a/passes/opt/peepopt_muldiv.pmg +++ b/passes/opt/peepopt_muldiv.pmg @@ -32,7 +32,7 @@ code val_y.extend_u0(GetSize(div_y), param(div, \A_SIGNED).as_bool()); did_something = true; - log("muldiv pattern in %s: mul=%s, div=%s\n", log_id(module), log_id(mul), log_id(div)); + log("muldiv pattern in %s: mul=%s, div=%s\n", module, mul, div); module->connect(div_y, val_y); autoremove(div); accept; diff --git a/passes/opt/peepopt_muldiv_c.pmg b/passes/opt/peepopt_muldiv_c.pmg index 2cf9b028b..eb8b31e13 100644 --- a/passes/opt/peepopt_muldiv_c.pmg +++ b/passes/opt/peepopt_muldiv_c.pmg @@ -119,7 +119,7 @@ code autoremove(div); // Log, fixup, accept - log("muldiv_const pattern in %s: mul=%s, div=%s\n", log_id(module), log_id(mul), log_id(div)); + log("muldiv_const pattern in %s: mul=%s, div=%s\n", module, mul, div); mul->fixup_parameters(); accept; endcode diff --git a/passes/opt/peepopt_shiftadd.pmg b/passes/opt/peepopt_shiftadd.pmg index 58dbefc12..6144e44ef 100644 --- a/passes/opt/peepopt_shiftadd.pmg +++ b/passes/opt/peepopt_shiftadd.pmg @@ -112,7 +112,7 @@ code did_something = true; log("shiftadd pattern in %s: shift=%s, add/sub=%s, offset: %d\n", \ - log_id(module), log_id(shift), log_id(add), offset); + module, shift, add, offset); SigSpec new_a; if(offset<0) { diff --git a/passes/opt/peepopt_shiftmul_left.pmg b/passes/opt/peepopt_shiftmul_left.pmg index 607f8368c..383222195 100644 --- a/passes/opt/peepopt_shiftmul_left.pmg +++ b/passes/opt/peepopt_shiftmul_left.pmg @@ -99,7 +99,7 @@ code } did_something = true; - log("left shiftmul pattern in %s: shift=%s, mul=%s\n", log_id(module), log_id(shift), log_id(mul)); + log("left shiftmul pattern in %s: shift=%s, mul=%s\n", module, shift, mul); int const_factor = mul_const.as_int(); int new_const_factor = 1 << factor_bits; diff --git a/passes/opt/peepopt_shiftmul_right.pmg b/passes/opt/peepopt_shiftmul_right.pmg index 108829d4f..ac0958bb8 100644 --- a/passes/opt/peepopt_shiftmul_right.pmg +++ b/passes/opt/peepopt_shiftmul_right.pmg @@ -76,7 +76,7 @@ code reject; did_something = true; - log("right shiftmul pattern in %s: shift=%s, mul=%s\n", log_id(module), log_id(shift), log_id(mul)); + log("right shiftmul pattern in %s: shift=%s, mul=%s\n", module, shift, mul); int const_factor = mul_const.as_int(); int new_const_factor = 1 << factor_bits; diff --git a/techlibs/microchip/microchip_dsp_cascade.pmg b/techlibs/microchip/microchip_dsp_cascade.pmg index fa276d5b5..ad359138d 100644 --- a/techlibs/microchip/microchip_dsp_cascade.pmg +++ b/techlibs/microchip/microchip_dsp_cascade.pmg @@ -135,10 +135,10 @@ finally } - log_debug("PCOUT -> PCIN cascade for %s -> %s\n", log_id(dsp), log_id(dsp_pcin)); + log_debug("PCOUT -> PCIN cascade for %s -> %s\n", dsp, dsp_pcin); } else { - log_debug(" Blocking %s -> %s cascade (exceeds max: %d)\n", log_id(dsp), log_id(dsp_pcin), MAX_DSP_CASCADE); + log_debug(" Blocking %s -> %s cascade (exceeds max: %d)\n", dsp, dsp_pcin, MAX_DSP_CASCADE); } dsp = dsp_pcin; diff --git a/techlibs/xilinx/xilinx_dsp_cascade.pmg b/techlibs/xilinx/xilinx_dsp_cascade.pmg index 9eebd33c3..587de4713 100644 --- a/techlibs/xilinx/xilinx_dsp_cascade.pmg +++ b/techlibs/xilinx/xilinx_dsp_cascade.pmg @@ -114,7 +114,7 @@ finally } dsp_pcin->setPort(\OPMODE, opmode); - log_debug("PCOUT -> PCIN cascade for %s -> %s\n", log_id(dsp), log_id(dsp_pcin)); + log_debug("PCOUT -> PCIN cascade for %s -> %s\n", dsp, dsp_pcin); } if (AREG >= 0) { Wire *cascade = module->addWire(NEW_ID, 30); @@ -128,7 +128,7 @@ finally dsp->setParam(\ACASCREG, AREG); dsp_pcin->setParam(\A_INPUT, Const("CASCADE")); - log_debug("ACOUT -> ACIN cascade for %s -> %s\n", log_id(dsp), log_id(dsp_pcin)); + log_debug("ACOUT -> ACIN cascade for %s -> %s\n", dsp, dsp_pcin); } if (BREG >= 0) { Wire *cascade = module->addWire(NEW_ID, 18); @@ -161,11 +161,11 @@ finally dsp_pcin->setParam(\B_INPUT, Const("CASCADE")); } - log_debug("BCOUT -> BCIN cascade for %s -> %s\n", log_id(dsp), log_id(dsp_pcin)); + log_debug("BCOUT -> BCIN cascade for %s -> %s\n", dsp, dsp_pcin); } } else { - log_debug(" Blocking %s -> %s cascade (exceeds max: %d)\n", log_id(dsp), log_id(dsp_pcin), MAX_DSP_CASCADE); + log_debug(" Blocking %s -> %s cascade (exceeds max: %d)\n", dsp, dsp_pcin, MAX_DSP_CASCADE); } dsp = dsp_pcin; From 9580ebabc5c4077644afb4beb8b6e0e9002b1836 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 14 May 2026 12:35:01 +0200 Subject: [PATCH 034/354] log_id here was needed for unescaping --- frontends/ast/simplify.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 1b98166e5..95dca27d8 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -3250,7 +3250,7 @@ skip_dynamic_range_lvalue_expansion:; if (stage > 1 && type == AST_IDENTIFIER && id2ast != nullptr && id2ast->type == AST_MEMORY && !in_lvalue && children.size() == 1 && children[0]->type == AST_RANGE && children[0]->children.size() == 1) { if (integer < (unsigned)id2ast->unpacked_dimensions) - input_error("Insufficient number of array indices for %s.\n", log_id(str)); + input_error("Insufficient number of array indices for %s.\n", RTLIL::unescape_id(str)); newNode = std::make_unique(location, AST_MEMRD, children[0]->children[0]->clone()); newNode->str = str; newNode->id2ast = id2ast; @@ -3523,7 +3523,7 @@ skip_dynamic_range_lvalue_expansion:; (children[0]->children.size() == 1 || children[0]->children.size() == 2) && children[0]->children[0]->type == AST_RANGE) { if (children[0]->integer < (unsigned)children[0]->id2ast->unpacked_dimensions) - input_error("Insufficient number of array indices for %s.\n", log_id(str)); + input_error("Insufficient number of array indices for %s.\n", RTLIL::unescape_id(str)); std::stringstream sstr; sstr << "$memwr$" << children[0]->str << "$" << RTLIL::encode_filename(*location.begin.filename) << ":" << location.begin.line << "$" << (autoidx++); @@ -5273,7 +5273,7 @@ void AstNode::mem2reg_as_needed_pass1(dict> &mem2reg AstNode *mem = id2ast; if (integer < (unsigned)mem->unpacked_dimensions) - input_error("Insufficient number of array indices for %s.\n", log_id(str)); + input_error("Insufficient number of array indices for %s.\n", RTLIL::unescape_id(str)); // flag if used after blocking assignment (in same proc) if ((proc_flags[mem] & AstNode::MEM2REG_FL_EQ1) && !(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_EQ2)) { From 4a7878b17fdddc686ccc29033385d02262e8f056 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 14 May 2026 15:58:58 +0200 Subject: [PATCH 035/354] Fixing couple more conversion errors --- frontends/ast/ast.cc | 2 +- passes/cmds/design.cc | 4 ++-- passes/cmds/rename.cc | 8 ++++---- passes/techmap/techmap.cc | 2 +- techlibs/quicklogic/ql_dsp_macc.cc | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 256321252..f5a601c3a 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1584,7 +1584,7 @@ bool AstModule::reprocess_if_necessary(RTLIL::Design *design) continue; if (design->module(modname) || design->module("$abstract" + modname)) { log("Reprocessing module %s because instantiated module %s has become available.\n", - name.unescape(), modname); + name.unescape(), RTLIL::unescape_id(modname)); loadconfig(); process_and_replace_module(design, this, ast.get(), NULL); return true; diff --git a/passes/cmds/design.cc b/passes/cmds/design.cc index 68b778790..cfd5d8af8 100644 --- a/passes/cmds/design.cc +++ b/passes/cmds/design.cc @@ -266,7 +266,7 @@ struct DesignPass : public Pass { for (auto mod : copy_src_modules) { - log("Importing %s as %s.\n", mod, prefix); + log("Importing %s as %s.\n", mod, RTLIL::unescape_id(prefix)); RTLIL::Module *t = mod->clone(); t->name = prefix; @@ -295,7 +295,7 @@ struct DesignPass : public Pass { { std::string trg_name = prefix + "." + (cell->type.c_str() + (*cell->type.c_str() == '\\')); - log("Importing %s as %s.\n", fmod, trg_name); + log("Importing %s as %s.\n", fmod, RTLIL::unescape_id(trg_name)); if (copy_to_design->module(trg_name) != nullptr) copy_to_design->remove(copy_to_design->module(trg_name)); diff --git a/passes/cmds/rename.cc b/passes/cmds/rename.cc index 15b6bf539..2f70126dd 100644 --- a/passes/cmds/rename.cc +++ b/passes/cmds/rename.cc @@ -31,13 +31,13 @@ static void rename_in_module(RTLIL::Module *module, std::string from_name, std:: to_name = RTLIL::escape_id(to_name); if (module->count_id(to_name)) - log_cmd_error("There is already an object `%s' in module `%s'.\n", to_name, module->name); + log_cmd_error("There is already an object `%s' in module `%s'.\n", RTLIL::unescape_id(to_name), module->name); RTLIL::Wire *wire_to_rename = module->wire(from_name); RTLIL::Cell *cell_to_rename = module->cell(from_name); if (wire_to_rename != nullptr) { - log("Renaming wire %s to %s in module %s.\n", wire_to_rename, to_name, module); + log("Renaming wire %s to %s in module %s.\n", wire_to_rename, RTLIL::unescape_id(to_name), module); module->rename(wire_to_rename, to_name); if (wire_to_rename->port_id || flag_output) { if (flag_output) @@ -50,12 +50,12 @@ static void rename_in_module(RTLIL::Module *module, std::string from_name, std:: if (cell_to_rename != nullptr) { if (flag_output) log_cmd_error("Called with -output but the specified object is a cell.\n"); - log("Renaming cell %s to %s in module %s.\n", cell_to_rename, to_name, module); + log("Renaming cell %s to %s in module %s.\n", cell_to_rename, RTLIL::unescape_id(to_name), module); module->rename(cell_to_rename, to_name); return; } - log_cmd_error("Object `%s' not found!\n", from_name); + log_cmd_error("Object `%s' not found!\n", RTLIL::unescape_id(from_name)); } static std::string derive_name_from_src(const std::string &src, int counter) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 5827feb92..e975d2fd2 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -1265,7 +1265,7 @@ struct TechmapPass : public Pass { i.second.sort(RTLIL::sort_by_id_str()); std::string maps = ""; for (auto &map : i.second) - maps += stringf(" %s", map); + maps += stringf(" %s", map.unescape()); log_debug(" %s:%s\n", i.first.unescape(), maps); } log_debug("\n"); diff --git a/techlibs/quicklogic/ql_dsp_macc.cc b/techlibs/quicklogic/ql_dsp_macc.cc index febfaddf1..083dc3ff1 100644 --- a/techlibs/quicklogic/ql_dsp_macc.cc +++ b/techlibs/quicklogic/ql_dsp_macc.cc @@ -73,7 +73,7 @@ static void create_ql_macc_dsp(ql_dsp_macc_pm &pm) } type = RTLIL::escape_id(cell_base_name + cell_size_name + "_cfg_ports"); - log("Inferring MACC %zux%zu->%zu as %s from:\n", a_width, b_width, z_width, type); + log("Inferring MACC %zux%zu->%zu as %s from:\n", a_width, b_width, z_width, type.unescape()); for (auto cell : {st.mul, st.add, st.mux, st.ff}) if (cell) From 965a3e67f072e7f23084c40f23e18c8899f348d3 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 14 May 2026 17:28:10 +0200 Subject: [PATCH 036/354] Remove pmgen related users of log_id --- passes/pmgen/README.md | 4 +-- techlibs/ice40/ice40_dsp.cc | 18 +++++----- techlibs/ice40/ice40_wrapcarry.cc | 4 +-- techlibs/microchip/microchip_dsp.cc | 2 +- techlibs/xilinx/xilinx_dsp.cc | 52 ++++++++++++++--------------- 5 files changed, 40 insertions(+), 40 deletions(-) diff --git a/passes/pmgen/README.md b/passes/pmgen/README.md index 542c2c0e8..15b4f79a1 100644 --- a/passes/pmgen/README.md +++ b/passes/pmgen/README.md @@ -34,8 +34,8 @@ for the pattern`` and calls the callback function for each found match: pm.run_foobar([&](){ - log("found matching 'foo' cell: %s\n", log_id(pm.st.foo)); - log(" with 'bar' cell: %s\n", log_id(pm.st.bar)); + log("found matching 'foo' cell: %s\n", pm.st.foo); + log(" with 'bar' cell: %s\n", pm.st.bar); }); The `.pmg` file declares matcher state variables that are accessible via the diff --git a/techlibs/ice40/ice40_dsp.cc b/techlibs/ice40/ice40_dsp.cc index 7942943c4..1d0f98f2f 100644 --- a/techlibs/ice40/ice40_dsp.cc +++ b/techlibs/ice40/ice40_dsp.cc @@ -31,15 +31,15 @@ void create_ice40_dsp(ice40_dsp_pm &pm) log("Checking %s.%s for iCE40 DSP inference.\n", pm.module, st.mul); - log_debug("ffA: %s\n", log_id(st.ffA, "--")); - log_debug("ffB: %s\n", log_id(st.ffB, "--")); - log_debug("ffCD: %s\n", log_id(st.ffCD, "--")); - log_debug("mul: %s\n", log_id(st.mul, "--")); - log_debug("ffFJKG: %s\n", log_id(st.ffFJKG, "--")); - log_debug("ffH: %s\n", log_id(st.ffH, "--")); - log_debug("add: %s\n", log_id(st.add, "--")); - log_debug("mux: %s\n", log_id(st.mux, "--")); - log_debug("ffO: %s\n", log_id(st.ffO, "--")); + log_debug("ffA: %s\n", st.ffA ? st.ffA->name.unescape() : "--"); + log_debug("ffB: %s\n", st.ffB ? st.ffB->name.unescape() : "--"); + log_debug("ffCD: %s\n", st.ffCD ? st.ffCD->name.unescape() : "--"); + log_debug("mul: %s\n", st.mul ? st.mul->name.unescape() : "--"); + log_debug("ffFJKG: %s\n", st.ffFJKG ? st.ffFJKG->name.unescape() : "--"); + log_debug("ffH: %s\n", st.ffH ? st.ffH->name.unescape() : "--"); + log_debug("add: %s\n", st.add ? st.add->name.unescape() : "--"); + log_debug("mux: %s\n", st.mux ? st.mux->name.unescape() : "--"); + log_debug("ffO: %s\n", st.ffO ? st.ffO->name.unescape() : "--"); log_debug("\n"); if (GetSize(st.sigA) > 16) { diff --git a/techlibs/ice40/ice40_wrapcarry.cc b/techlibs/ice40/ice40_wrapcarry.cc index f62019617..63ebdbfcf 100644 --- a/techlibs/ice40/ice40_wrapcarry.cc +++ b/techlibs/ice40/ice40_wrapcarry.cc @@ -31,8 +31,8 @@ void create_ice40_wrapcarry(ice40_wrapcarry_pm &pm) #if 0 log("\n"); - log("carry: %s\n", log_id(st.carry, "--")); - log("lut: %s\n", log_id(st.lut, "--")); + log("carry: %s\n", st.carry ? st.carry->name.unescape() : "--"); + log("lut: %s\n", st.lut ? st.lut->name.unescape() : "--"); #endif log(" replacing SB_LUT + SB_CARRY with $__ICE40_CARRY_WRAPPER cell.\n"); diff --git a/techlibs/microchip/microchip_dsp.cc b/techlibs/microchip/microchip_dsp.cc index 01c77644f..ff86049eb 100644 --- a/techlibs/microchip/microchip_dsp.cc +++ b/techlibs/microchip/microchip_dsp.cc @@ -195,7 +195,7 @@ void microchip_dsp_packC(microchip_dsp_CREG_pm &pm) auto &st = pm.st_microchip_dsp_packC; log_debug("Analysing %s.%s for Microchip DSP packing (REG_C).\n", pm.module, st.dsp); - log_debug("ffC: %s\n", log_id(st.ffC, "--")); + log_debug("ffC: %s\n", st.ffC ? st.ffC->name.unescape() : "--"); Cell *cell = st.dsp; diff --git a/techlibs/xilinx/xilinx_dsp.cc b/techlibs/xilinx/xilinx_dsp.cc index 94fad6453..5c81bff22 100644 --- a/techlibs/xilinx/xilinx_dsp.cc +++ b/techlibs/xilinx/xilinx_dsp.cc @@ -262,20 +262,20 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm) log("Analysing %s.%s for Xilinx DSP packing.\n", pm.module, st.dsp); - log_debug("preAdd: %s\n", log_id(st.preAdd, "--")); - log_debug("preSub: %s\n", log_id(st.preSub, "--")); - log_debug("ffAD: %s\n", log_id(st.ffAD, "--")); - log_debug("ffA2: %s\n", log_id(st.ffA2, "--")); - log_debug("ffA1: %s\n", log_id(st.ffA1, "--")); - log_debug("ffB2: %s\n", log_id(st.ffB2, "--")); - log_debug("ffB1: %s\n", log_id(st.ffB1, "--")); - log_debug("ffD: %s\n", log_id(st.ffD, "--")); - log_debug("dsp: %s\n", log_id(st.dsp, "--")); - log_debug("ffM: %s\n", log_id(st.ffM, "--")); - log_debug("postAdd: %s\n", log_id(st.postAdd, "--")); - log_debug("postAddMux: %s\n", log_id(st.postAddMux, "--")); - log_debug("ffP: %s\n", log_id(st.ffP, "--")); - log_debug("overflow: %s\n", log_id(st.overflow, "--")); + log_debug("preAdd: %s\n", st.preAdd ? st.preAdd->name.unescape() : "--"); + log_debug("preSub: %s\n", st.preSub ? st.preSub->name.unescape() : "--"); + log_debug("ffAD: %s\n", st.ffAD ? st.ffAD->name.unescape() : "--"); + log_debug("ffA2: %s\n", st.ffA2 ? st.ffA2->name.unescape() : "--"); + log_debug("ffA1: %s\n", st.ffA1 ? st.ffA1->name.unescape() : "--"); + log_debug("ffB2: %s\n", st.ffB2 ? st.ffB2->name.unescape() : "--"); + log_debug("ffB1: %s\n", st.ffB1 ? st.ffB1->name.unescape() : "--"); + log_debug("ffD: %s\n", st.ffD ? st.ffD->name.unescape() : "--"); + log_debug("dsp: %s\n", st.dsp ? st.dsp->name.unescape() : "--"); + log_debug("ffM: %s\n", st.ffM ? st.ffM->name.unescape() : "--"); + log_debug("postAdd: %s\n", st.postAdd ? st.postAdd->name.unescape() : "--"); + log_debug("postAddMux: %s\n", st.postAddMux ? st.postAddMux->name.unescape() : "--"); + log_debug("ffP: %s\n", st.ffP ? st.ffP->name.unescape() : "--"); + log_debug("overflow: %s\n", st.overflow ? st.overflow->name.unescape() : "--"); Cell *cell = st.dsp; @@ -495,17 +495,17 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm) log("Analysing %s.%s for Xilinx DSP48A/DSP48A1 packing.\n", pm.module, st.dsp); - log_debug("preAdd: %s\n", log_id(st.preAdd, "--")); - log_debug("ffA1: %s\n", log_id(st.ffA1, "--")); - log_debug("ffA0: %s\n", log_id(st.ffA0, "--")); - log_debug("ffB1: %s\n", log_id(st.ffB1, "--")); - log_debug("ffB0: %s\n", log_id(st.ffB0, "--")); - log_debug("ffD: %s\n", log_id(st.ffD, "--")); - log_debug("dsp: %s\n", log_id(st.dsp, "--")); - log_debug("ffM: %s\n", log_id(st.ffM, "--")); - log_debug("postAdd: %s\n", log_id(st.postAdd, "--")); - log_debug("postAddMux: %s\n", log_id(st.postAddMux, "--")); - log_debug("ffP: %s\n", log_id(st.ffP, "--")); + log_debug("preAdd: %s\n", st.preAdd ? st.preAdd->name.unescape() : "--"); + log_debug("ffA1: %s\n", st.ffA1 ? st.ffA1->name.unescape() : "--"); + log_debug("ffA0: %s\n", st.ffA0 ? st.ffA0->name.unescape() : "--"); + log_debug("ffB1: %s\n", st.ffB1 ? st.ffB1->name.unescape() : "--"); + log_debug("ffB0: %s\n", st.ffB0 ? st.ffB0->name.unescape() : "--"); + log_debug("ffD: %s\n", st.ffD ? st.ffD->name.unescape() : "--"); + log_debug("dsp: %s\n", st.dsp ? st.dsp->name.unescape() : "--"); + log_debug("ffM: %s\n", st.ffM ? st.ffM->name.unescape() : "--"); + log_debug("postAdd: %s\n", st.postAdd ? st.postAdd->name.unescape() : "--"); + log_debug("postAddMux: %s\n", st.postAddMux ? st.postAddMux->name.unescape() : "--"); + log_debug("ffP: %s\n", st.ffP ? st.ffP->name.unescape() : "--"); Cell *cell = st.dsp; SigSpec &opmode = cell->connections_.at(ID(OPMODE)); @@ -672,7 +672,7 @@ void xilinx_dsp_packC(xilinx_dsp_CREG_pm &pm) auto &st = pm.st_xilinx_dsp_packC; log_debug("Analysing %s.%s for Xilinx DSP packing (CREG).\n", pm.module, st.dsp); - log_debug("ffC: %s\n", log_id(st.ffC, "--")); + log_debug("ffC: %s\n", st.ffC ? st.ffC->name.unescape() : "--"); Cell *cell = st.dsp; From c16e0352f766a2d94a9b1c78b86a22965b7782bc Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 15 May 2026 11:13:59 +0200 Subject: [PATCH 037/354] Bump to clang-22 on macOS as well --- .github/workflows/test-compile.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test-compile.yml b/.github/workflows/test-compile.yml index 3e2ac34c9..99e4973a7 100644 --- a/.github/workflows/test-compile.yml +++ b/.github/workflows/test-compile.yml @@ -52,10 +52,10 @@ jobs: include: # macOS x86 - os: macos-15-intel - compiler: 'clang-19' + compiler: 'clang-22' # macOS arm - os: macos-latest - compiler: 'clang-19' + compiler: 'clang-22' fail-fast: false steps: - name: Checkout Yosys @@ -96,7 +96,7 @@ jobs: # maximum standard, only on newest compilers - name: Build C++26 - if: ${{ matrix.compiler == 'clang-19' || matrix.compiler == 'clang-22' || matrix.compiler == 'gcc-15' }} + if: ${{ matrix.compiler == 'clang-22' || matrix.compiler == 'gcc-15' }} shell: bash run: | make config-$CC_SHORT From 8022b5445b5967ea7fd2065629d3574861a099c8 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 15 May 2026 11:59:22 +0200 Subject: [PATCH 038/354] Convert to using LLVM code coverage --- .github/workflows/test-verific.yml | 9 +++++++++ .gitignore | 4 ++-- Makefile | 19 +++++++++++-------- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/.github/workflows/test-verific.yml b/.github/workflows/test-verific.yml index 6e3284167..bdd35428a 100644 --- a/.github/workflows/test-verific.yml +++ b/.github/workflows/test-verific.yml @@ -44,6 +44,14 @@ jobs: - name: Runtime environment run: | echo "procs=$(nproc)" >> $GITHUB_ENV + mkdir -p "${GITHUB_WORKSPACE}/coverage" + echo "LLVM_PROFILE_FILE=${GITHUB_WORKSPACE}/coverage/coverage_%p.profraw" >> $GITHUB_ENV + echo "LLVM_PROFILE_FILE_BUFFER_SIZE=0" >> $GITHUB_ENV + + - name: Skip generating files + if: ${{ github.event_name != 'merge_group' && github.event_name != 'workflow_dispatch' }} + run: | + echo "LLVM_PROFILE_FILE=/dev/null" >> $GITHUB_ENV - name: Build Yosys run: | @@ -89,6 +97,7 @@ jobs: if: ${{ github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' }} run: | make coverage + make clean_coverage - name: Push coverage if: ${{ github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' }} diff --git a/.gitignore b/.gitignore index a8b04ac45..b39088088 100644 --- a/.gitignore +++ b/.gitignore @@ -65,10 +65,10 @@ /viz.js # other -/coverage.info +/yosys.profdata +/coverage /coverage_html - # these really belong in global gitignore since they're not specific to this project but rather to user tool choice # but too many people don't have a global gitignore configured: # https://docs.github.com/en/get-started/git-basics/ignoring-files#configuring-ignored-files-for-all-repositories-on-your-computer diff --git a/Makefile b/Makefile index f6ba73375..3c9911c1c 100644 --- a/Makefile +++ b/Makefile @@ -456,8 +456,11 @@ endif endif ifeq ($(ENABLE_GCOV),1) -CXXFLAGS += --coverage -LINKFLAGS += --coverage +LLVM_PROFILE_FILE ?= $(realpath $(YOSYS_SRC))/coverage/coverage_%p.profraw +export LLVM_PROFILE_FILE +export LLVM_PROFILE_FILE_BUFFER_SIZE=0 +CXXFLAGS += -fprofile-instr-generate -fcoverage-mapping +LINKFLAGS+= -fprofile-instr-generate endif ifeq ($(ENABLE_GPROF),1) @@ -1115,13 +1118,13 @@ mrproper: clean coverage: ./$(PROGRAM_PREFIX)yosys -qp 'help; help -all' - rm -rf coverage.info coverage_html - lcov --capture -d . --no-external -o coverage.info - lcov --remove coverage.info '*/tests/various/*' '*/libs/*' -o coverage.info --ignore-errors unused - genhtml coverage.info --output-directory coverage_html + rm -rf coverage_html + llvm-profdata merge -sparse coverage/coverage_*.profraw -o yosys.profdata + llvm-cov show ./$(PROGRAM_PREFIX)yosys -instr-profile=yosys.profdata -format=html -output-dir=coverage_html --compilation-dir=. -ignore-filename-regex='(^|.*/)Verific/.*|(^|.*/)libs/.*' clean_coverage: - find . -name "*.gcda" -type f -delete + rm -rf coverage + rm -f yosys.profdata FUNC_KERNEL := functional.cc functional.h sexpr.cc sexpr.h compute_graph.h FUNC_INCLUDES := $(addprefix --include *,functional/* $(FUNC_KERNEL)) @@ -1183,7 +1186,7 @@ config-msys2-64: clean echo "PREFIX := $(MINGW_PREFIX)" >> Makefile.conf config-gcov: clean - echo 'CONFIG := gcc' > Makefile.conf + echo 'CONFIG := clang' > Makefile.conf echo 'ENABLE_GCOV := 1' >> Makefile.conf echo 'ENABLE_DEBUG := 1' >> Makefile.conf From e4a3b44e8e24bfffbda46989e19316106026eba7 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 15 May 2026 12:34:54 +0200 Subject: [PATCH 039/354] Fixed not intentional log_signal removal --- backends/aiger2/aiger.cc | 2 +- passes/techmap/bufnorm.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backends/aiger2/aiger.cc b/backends/aiger2/aiger.cc index c0ab8a65c..6d8ac8a24 100644 --- a/backends/aiger2/aiger.cc +++ b/backends/aiger2/aiger.cc @@ -1048,7 +1048,7 @@ struct XAigerWriter : AigerWriter { } else if (!is_input && !inputs) { for (auto &bit : conn.second) { if (!bit.wire || (bit.wire->port_input && !bit.wire->port_output)) - log_error("Bad connection %s/%s ~ %s\n", box, conn.first.unescape(), conn.second); + log_error("Bad connection %s/%s ~ %s\n", box, conn.first.unescape(), log_signal(conn.second)); ensure_pi(bit, cursor); diff --git a/passes/techmap/bufnorm.cc b/passes/techmap/bufnorm.cc index 9e6ca2e30..c27f2740d 100644 --- a/passes/techmap/bufnorm.cc +++ b/passes/techmap/bufnorm.cc @@ -502,7 +502,7 @@ struct BufnormPass : public Pass { if (conn.second != newsig) { log(" fixing input signal on cell %s port %s: %s\n", - cell, conn.first.unescape(), newsig); + cell, conn.first.unescape(), log_signal(newsig)); cell->setPort(conn.first, newsig); count_updated_cellports++; } From 992eceaaa08ceb4a82e83f2ab286a05ea2057736 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 15 May 2026 12:53:04 +0200 Subject: [PATCH 040/354] Ignore configured location --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 3c9911c1c..6fb79624f 100644 --- a/Makefile +++ b/Makefile @@ -1120,7 +1120,7 @@ coverage: ./$(PROGRAM_PREFIX)yosys -qp 'help; help -all' rm -rf coverage_html llvm-profdata merge -sparse coverage/coverage_*.profraw -o yosys.profdata - llvm-cov show ./$(PROGRAM_PREFIX)yosys -instr-profile=yosys.profdata -format=html -output-dir=coverage_html --compilation-dir=. -ignore-filename-regex='(^|.*/)Verific/.*|(^|.*/)libs/.*' + llvm-cov show ./$(PROGRAM_PREFIX)yosys -instr-profile=yosys.profdata -format=html -output-dir=coverage_html --compilation-dir=. -ignore-filename-regex='(^|.*/)libs/.*|/usr/include/.*|$(subst /,\/,$(VERIFIC_DIR))/.*' clean_coverage: rm -rf coverage From 59c1bc35cbad3b50ef29ec48e443ddffafa6a931 Mon Sep 17 00:00:00 2001 From: Leon White Date: Sat, 16 May 2026 09:12:20 +0200 Subject: [PATCH 041/354] Fix aiger tests when ABCEXTERNAL is set --- tests/aiger/generate_mk.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/aiger/generate_mk.py b/tests/aiger/generate_mk.py index a90a63527..e6f3f4091 100644 --- a/tests/aiger/generate_mk.py +++ b/tests/aiger/generate_mk.py @@ -54,6 +54,13 @@ def create_tests(): "rm -f aigmap.err" ])) -extra = [ f"ABC ?= {gen_tests_makefile.yosys_basedir}/yosys-abc", "SHELL := /usr/bin/env bash" ] +extra = [ + "ifneq ($(ABCEXTERNAL),)", + "ABC ?= $(ABCEXTERNAL)", + "else", + f"ABC ?= {gen_tests_makefile.yosys_basedir}/yosys-abc", + "endif", + "SHELL := /usr/bin/env bash", +] gen_tests_makefile.generate_custom(create_tests, extra) From 8bbc3c359cb28024a10c4ecaa1767057bcbaed82 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 15 May 2026 15:16:09 +0200 Subject: [PATCH 042/354] Remove id2cstr uses in our code base --- backends/cxxrtl/cxxrtl_backend.cc | 2 +- .../source/code_examples/stubnets/stubnets.cc | 6 ++-- frontends/verific/verific.cc | 4 +-- kernel/rtlil.cc | 6 ++-- passes/cmds/scc.cc | 6 ++-- passes/cmds/select.cc | 18 ++++++------ passes/cmds/test_select.cc | 4 +-- passes/equiv/equiv_make.cc | 4 +-- passes/fsm/fsm_detect.cc | 2 +- passes/hierarchy/hierarchy.cc | 28 +++++++++---------- passes/sat/cutpoint.cc | 4 +-- passes/sat/expose.cc | 18 ++++++------ passes/sat/freduce.cc | 10 +++---- passes/sat/miter.cc | 2 +- passes/techmap/iopadmap.cc | 14 +++++----- techlibs/ice40/ice40_braminit.cc | 2 +- 16 files changed, 64 insertions(+), 66 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 3ebe62b90..ac69bda27 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -3420,7 +3420,7 @@ struct CxxrtlWorker { if (!design->selected_whole_module(module)) if (design->selected_module(module)) - log_cmd_error("Can't handle partially selected module `%s'!\n", id2cstr(module->name)); + log_cmd_error("Can't handle partially selected module `%s'!\n", module); if (!design->selected_module(module)) continue; diff --git a/docs/source/code_examples/stubnets/stubnets.cc b/docs/source/code_examples/stubnets/stubnets.cc index 566d24b18..41fb66e82 100644 --- a/docs/source/code_examples/stubnets/stubnets.cc +++ b/docs/source/code_examples/stubnets/stubnets.cc @@ -27,7 +27,7 @@ static void find_stub_nets(RTLIL::Design *design, RTLIL::Module *module, bool re // count output lines for this module (needed only for summary output at the end) int line_count = 0; - log("Looking for stub wires in module %s:\n", RTLIL::id2cstr(module->name)); + log("Looking for stub wires in module %s:\n", module); // For all ports on all cells for (auto &cell_iter : module->cells_) @@ -74,11 +74,11 @@ static void find_stub_nets(RTLIL::Design *design, RTLIL::Module *module, bool re // report stub bits and/or stub wires, don't report single bits // if called with report_bits set to false. if (GetSize(stub_bits) == GetSize(sig)) { - log(" found stub wire: %s\n", RTLIL::id2cstr(wire->name)); + log(" found stub wire: %s\n", wire); } else { if (!report_bits) continue; - log(" found wire with stub bits: %s [", RTLIL::id2cstr(wire->name)); + log(" found wire with stub bits: %s [", wire); for (int bit : stub_bits) log("%s%d", bit == *stub_bits.begin() ? "" : ", ", bit); log("]\n"); diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index ec3d21ccd..6b876c0f1 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -1492,10 +1492,10 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma design->add(module); if (is_blackbox(nl)) { - log("Importing blackbox module %s.\n", RTLIL::id2cstr(module->name)); + log("Importing blackbox module %s.\n", module); module->set_bool_attribute(ID::blackbox); } else { - log("Importing module %s.\n", RTLIL::id2cstr(module->name)); + log("Importing module %s.\n", module); } import_attributes(module->attributes, nl, nl); if (module->name.isPublic()) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 020a4ec0c..31efff63d 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1579,7 +1579,7 @@ void RTLIL::Module::makeblackbox() void RTLIL::Module::expand_interfaces(RTLIL::Design *, const dict &) { - log_error("Class doesn't support expand_interfaces (module: `%s')!\n", id2cstr(name)); + log_error("Class doesn't support expand_interfaces (module: `%s')!\n", name.unescape()); } bool RTLIL::Module::reprocess_if_necessary(RTLIL::Design *) @@ -1591,7 +1591,7 @@ RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, const dictname)); + log(" %s", c); cell2scc[c] = sccList.size(); scc.insert(c); } @@ -201,7 +201,7 @@ struct SccWorker if (!nofeedbackMode && cellToNextCell[cell].count(cell)) { log("Found an SCC:"); pool scc; - log(" %s", RTLIL::id2cstr(cell->name)); + log(" %s", cell); cell2scc[cell] = sccList.size(); scc.insert(cell); sccList.push_back(scc); @@ -221,7 +221,7 @@ struct SccWorker run(cell, 0, maxDepth); } - log("Found %d SCCs in module %s.\n", int(sccList.size()), RTLIL::id2cstr(module->name)); + log("Found %d SCCs in module %s.\n", int(sccList.size()), module); } void select(RTLIL::Selection &sel) diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index bcb34d1d4..1fcc35dfa 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -25,8 +25,6 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -using RTLIL::id2cstr; - static std::vector work_stack; static bool match_ids(RTLIL::IdString id, const std::string &pattern) @@ -1022,9 +1020,9 @@ static std::string describe_selection_for_assert(RTLIL::Design *design, RTLIL::S for (auto mod : design->all_selected_modules()) { if (whole_modules && sel->selected_whole_module(mod->name)) - desc += stringf("%s\n", id2cstr(mod->name)); + desc += stringf("%s\n", mod); for (auto it : mod->selected_members()) - desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(it->name)); + desc += stringf("%s/%s\n", mod, it); } if (push_selection) design->pop_selection(); return desc; @@ -1414,7 +1412,7 @@ struct SelectPass : public Pass { if (arg == "-module" && argidx+1 < args.size()) { RTLIL::IdString mod_name = RTLIL::escape_id(args[++argidx]); if (design->module(mod_name) == nullptr) - log_cmd_error("No such module: %s\n", id2cstr(mod_name)); + log_cmd_error("No such module: %s\n", mod_name.unescape()); design->selected_active_module = mod_name.str(); got_module = true; continue; @@ -1527,10 +1525,10 @@ struct SelectPass : public Pass { for (auto mod : design->all_selected_modules()) { if (sel->selected_whole_module(mod->name) && list_mode) - log("%s\n", id2cstr(mod->name)); + log("%s\n", mod); if (!list_mod_mode) for (auto it : mod->selected_members()) - LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(it->name)) + LOG_OBJECT("%s/%s\n", mod->name.unescape().c_str(), it->name.unescape().c_str()) } if (count_mode) { @@ -1654,10 +1652,10 @@ struct SelectPass : public Pass { if (sel.full_selection) log("*\n"); for (auto &it : sel.selected_modules) - log("%s\n", id2cstr(it)); + log("%s\n", it.unescape()); for (auto &it : sel.selected_members) for (auto &it2 : it.second) - log("%s/%s\n", id2cstr(it.first), id2cstr(it2)); + log("%s/%s\n", it.first.unescape(), it2.unescape()); return; } @@ -1779,7 +1777,7 @@ static void log_matches(const char *title, Module *module, const T &list) log("\n%d %s:\n", int(matches.size()), title); std::sort(matches.begin(), matches.end(), RTLIL::sort_by_id_str()); for (auto id : matches) - log(" %s\n", RTLIL::id2cstr(id)); + log(" %s\n", id.unescape()); } } diff --git a/passes/cmds/test_select.cc b/passes/cmds/test_select.cc index 0076500ce..4a3bbc539 100644 --- a/passes/cmds/test_select.cc +++ b/passes/cmds/test_select.cc @@ -144,10 +144,10 @@ struct TestSelectPass : public Pass { for (auto *mod : sub_sel) { if (mod->is_selected_whole()) { - log_debug(" Adding %s.\n", id2cstr(mod->name)); + log_debug(" Adding %s.\n", mod); selected_modules.insert(mod->name); } else for (auto *memb : mod->selected_members()) { - log_debug(" Adding %s.%s.\n", id2cstr(mod->name), id2cstr(memb->name)); + log_debug(" Adding %s.%s.\n", mod, memb); selected_members[mod->name].insert(memb); } } diff --git a/passes/equiv/equiv_make.cc b/passes/equiv/equiv_make.cc index 3aa3fac63..602ad776d 100644 --- a/passes/equiv/equiv_make.cc +++ b/passes/equiv/equiv_make.cc @@ -285,11 +285,11 @@ struct EquivMakeWorker for (int i = 0; i < wire->width; i++) { if (undriven_bits.count(assign_map(SigBit(gold_wire, i)))) { - log(" Skipping signal bit %s [%d]: undriven on gold side.\n", id2cstr(gold_wire->name), i); + log(" Skipping signal bit %s [%d]: undriven on gold side.\n", gold_wire, i); continue; } if (undriven_bits.count(assign_map(SigBit(gate_wire, i)))) { - log(" Skipping signal bit %s [%d]: undriven on gate side.\n", id2cstr(gate_wire->name), i); + log(" Skipping signal bit %s [%d]: undriven on gate side.\n", gate_wire, i); continue; } equiv_mod->addEquiv(NEW_ID, SigSpec(gold_wire, i), SigSpec(gate_wire, i), SigSpec(wire, i)); diff --git a/passes/fsm/fsm_detect.cc b/passes/fsm/fsm_detect.cc index dfe99f512..7f5107ce9 100644 --- a/passes/fsm/fsm_detect.cc +++ b/passes/fsm/fsm_detect.cc @@ -61,7 +61,7 @@ ret_false: if (recursion_monitor.count(cellport.first)) { log_warning("logic loop in mux tree at signal %s in module %s.\n", - log_signal(sig), RTLIL::id2cstr(module->name)); + log_signal(sig), module); goto ret_false; } diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 67475eda0..f41c19672 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -87,7 +87,7 @@ void generate(RTLIL::Design *design, const std::vector &celltypes, if (decl.index > 0) { portwidths[decl.portname] = max(portwidths[decl.portname], 1); portwidths[decl.portname] = max(portwidths[decl.portname], portwidths[stringf("$%d", decl.index)]); - log(" port %d: %s [%d:0] %s\n", decl.index, decl.input ? decl.output ? "inout" : "input" : "output", portwidths[decl.portname]-1, RTLIL::id2cstr(decl.portname)); + log(" port %d: %s [%d:0] %s\n", decl.index, decl.input ? decl.output ? "inout" : "input" : "output", portwidths[decl.portname]-1, RTLIL::unescape_id(decl.portname)); if (indices.count(decl.index) > ports.size()) log_error("Port index (%d) exceeds number of found ports (%d).\n", decl.index, int(ports.size())); if (indices.count(decl.index) == 0) @@ -108,10 +108,10 @@ void generate(RTLIL::Design *design, const std::vector &celltypes, indices.erase(d.index); ports[d.index-1] = d; portwidths[d.portname] = max(portwidths[d.portname], 1); - log(" port %d: %s [%d:0] %s\n", d.index, d.input ? d.output ? "inout" : "input" : "output", portwidths[d.portname]-1, RTLIL::id2cstr(d.portname)); + log(" port %d: %s [%d:0] %s\n", d.index, d.input ? d.output ? "inout" : "input" : "output", portwidths[d.portname]-1, RTLIL::unescape_id(d.portname)); goto found_matching_decl; } - log_error("Can't match port %s.\n", RTLIL::id2cstr(portname)); + log_error("Can't match port %s.\n", portname.unescape()); found_matching_decl:; portnames.erase(portname); } @@ -133,9 +133,9 @@ void generate(RTLIL::Design *design, const std::vector &celltypes, mod->fixup_ports(); for (auto ¶ : parameters) - log(" ignoring parameter %s.\n", RTLIL::id2cstr(para)); + log(" ignoring parameter %s.\n", para.unescape()); - log(" module %s created.\n", RTLIL::id2cstr(mod->name)); + log(" module %s created.\n", mod); } } @@ -597,7 +597,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check int idx = it.second.first, num = it.second.second; if (design->module(cell->type) == nullptr) - log_error("Array cell `%s.%s' of unknown type `%s'.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); + log_error("Array cell `%s.%s' of unknown type `%s'.\n", module, cell, cell->type.unescape()); RTLIL::Module *mod = design->module(cell->type); @@ -613,12 +613,12 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check } } if (mod->wire(portname) == nullptr) - log_error("Array cell `%s.%s' connects to unknown port `%s'.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(conn.first)); + log_error("Array cell `%s.%s' connects to unknown port `%s'.\n", module, cell, conn.first.unescape()); int port_size = mod->wire(portname)->width; if (conn_size == port_size || conn_size == 0) continue; if (conn_size != port_size*num) - log_error("Array cell `%s.%s' has invalid port vs. signal size for port `%s'.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(conn.first)); + log_error("Array cell `%s.%s' has invalid port vs. signal size for port `%s'.\n", module, cell, conn.first.unescape()); conn.second = conn.second.extract(port_size*idx, port_size); } } @@ -1219,7 +1219,7 @@ struct HierarchyPass : public Pass { if (read_id_num(p.first, &id)) { if (id <= 0 || id > GetSize(cell_mod->avail_parameters)) { log(" Failed to map positional parameter %d of cell %s.%s (%s).\n", - id, RTLIL::id2cstr(mod->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); + id, mod, cell, cell->type.unescape()); } else { params_rename.insert(std::make_pair(p.first, cell_mod->avail_parameters[id - 1])); } @@ -1241,7 +1241,7 @@ struct HierarchyPass : public Pass { RTLIL::Module *module = work.first; RTLIL::Cell *cell = work.second; log("Mapping positional arguments of cell %s.%s (%s).\n", - RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); + module, cell, cell->type.unescape()); dict new_connections; for (auto &conn : cell->connections()) { int id; @@ -1249,7 +1249,7 @@ struct HierarchyPass : public Pass { std::pair key(design->module(cell->type), id); if (pos_map.count(key) == 0) { log(" Failed to map positional argument %d of cell %s.%s (%s).\n", - id, RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); + id, module, cell, cell->type.unescape()); new_connections[conn.first] = conn.second; } else new_connections[pos_map.at(key)] = conn.second; @@ -1283,7 +1283,7 @@ struct HierarchyPass : public Pass { if (m == nullptr) log_error("Cell %s.%s (%s) has implicit port connections but the module it instantiates is unknown.\n", - RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); + module, cell, cell->type.unescape()); // Need accurate port widths for error checking; so must derive blackboxes with dynamic port widths if (m->get_blackbox_attribute() && !cell->parameters.empty() && m->get_bool_attribute(ID::dynports)) { @@ -1312,11 +1312,11 @@ struct HierarchyPass : public Pass { if (parent_wire == nullptr) log_error("No matching wire for implicit port connection `%s' of cell %s.%s (%s).\n", - RTLIL::id2cstr(wire->name), RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); + wire, module, cell, cell->type.unescape()); if (parent_wire->width != wire->width) log_error("Width mismatch between wire (%d bits) and port (%d bits) for implicit port connection `%s' of cell %s.%s (%s).\n", parent_wire->width, wire->width, - RTLIL::id2cstr(wire->name), RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); + wire, module, cell, cell->type.unescape()); cell->setPort(wire->name, parent_wire); } cell->attributes.erase(ID::wildcard_port_conns); diff --git a/passes/sat/cutpoint.cc b/passes/sat/cutpoint.cc index ff1ae2628..6c4023a6a 100644 --- a/passes/sat/cutpoint.cc +++ b/passes/sat/cutpoint.cc @@ -132,7 +132,7 @@ struct CutpointPass : public Pass { if (cell->input(conn.first)) for (auto bit : sigmap(conn.second)) if (wire_drivers.count(bit)) { - log_debug(" Treating inout port '%s' as input.\n", id2cstr(conn.first)); + log_debug(" Treating inout port '%s' as input.\n", conn.first.unescape()); do_cut = false; break; } @@ -140,7 +140,7 @@ struct CutpointPass : public Pass { if (do_cut) { module->connect(conn.second, flag_undef ? Const(State::Sx, GetSize(conn.second)) : module->Anyseq(NEW_ID, GetSize(conn.second))); if (cell->input(conn.first)) { - log_debug(" Treating inout port '%s' as output.\n", id2cstr(conn.first)); + log_debug(" Treating inout port '%s' as output.\n", conn.first.unescape()); for (auto bit : sigmap(conn.second)) wire_drivers.insert(bit); } diff --git a/passes/sat/expose.cc b/passes/sat/expose.cc index ef00a6956..b5f2a437c 100644 --- a/passes/sat/expose.cc +++ b/passes/sat/expose.cc @@ -471,7 +471,7 @@ struct ExposePass : public Pass { { if (!w->port_input) { w->port_input = true; - log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(w->name)); + log("New module port: %s/%s\n", module, w); wire_map[w] = NEW_ID; } } @@ -479,7 +479,7 @@ struct ExposePass : public Pass { { if (!w->port_output) { w->port_output = true; - log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(w->name)); + log("New module port: %s/%s\n", module, w); } if (flag_cut) { @@ -555,7 +555,7 @@ struct ExposePass : public Pass { RTLIL::Wire *wire_q = add_new_wire(module, wire->name.str() + sep + "q", wire->width); wire_q->port_input = true; - log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire_q->name)); + log("New module port: %s/%s\n", module, wire_q); RTLIL::SigSig connect_q; for (size_t i = 0; i < wire_bits_vec.size(); i++) { @@ -569,12 +569,12 @@ struct ExposePass : public Pass { RTLIL::Wire *wire_d = add_new_wire(module, wire->name.str() + sep + "d", wire->width); wire_d->port_output = true; - log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire_d->name)); + log("New module port: %s/%s\n", module, wire_d); module->connect(RTLIL::SigSig(wire_d, info.sig_d)); RTLIL::Wire *wire_c = add_new_wire(module, wire->name.str() + sep + "c"); wire_c->port_output = true; - log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire_c->name)); + log("New module port: %s/%s\n", module, wire_c); if (info.clk_polarity) { module->connect(RTLIL::SigSig(wire_c, info.sig_clk)); } else { @@ -590,7 +590,7 @@ struct ExposePass : public Pass { { RTLIL::Wire *wire_r = add_new_wire(module, wire->name.str() + sep + "r"); wire_r->port_output = true; - log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire_r->name)); + log("New module port: %s/%s\n", module, wire_r); if (info.arst_polarity) { module->connect(RTLIL::SigSig(wire_r, info.sig_arst)); } else { @@ -604,7 +604,7 @@ struct ExposePass : public Pass { RTLIL::Wire *wire_v = add_new_wire(module, wire->name.str() + sep + "v", wire->width); wire_v->port_output = true; - log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire_v->name)); + log("New module port: %s/%s\n", module, wire_v); module->connect(RTLIL::SigSig(wire_v, info.arst_value)); } } @@ -638,7 +638,7 @@ struct ExposePass : public Pass { if (p->port_output) w->port_input = true; - log("New module port: %s/%s (%s)\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(w->name), RTLIL::id2cstr(cell->type)); + log("New module port: %s/%s (%s)\n", module, w, cell->type.unescape()); RTLIL::SigSpec sig; if (cell->hasPort(p->name)) @@ -660,7 +660,7 @@ struct ExposePass : public Pass { if (ct.cell_output(cell->type, it.first)) w->port_input = true; - log("New module port: %s/%s (%s)\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(w->name), RTLIL::id2cstr(cell->type)); + log("New module port: %s/%s (%s)\n", module, w, cell->type.unescape()); if (w->port_input) module->connect(RTLIL::SigSig(it.second, w)); diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index 4b0669c25..d2ca52b6f 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -139,7 +139,7 @@ struct FindReducedInputs if (ez_cells.count(drv.first) == 0) { satgen.setContext(&sigmap, "A"); if (!satgen.importCell(drv.first)) - log_error("Can't create SAT model for cell %s (%s)!\n", RTLIL::id2cstr(drv.first->name), RTLIL::id2cstr(drv.first->type)); + log_error("Can't create SAT model for cell %s (%s)!\n", drv.first, drv.first->type.unescape()); satgen.setContext(&sigmap, "B"); if (!satgen.importCell(drv.first)) log_abort(); @@ -256,7 +256,7 @@ struct PerformReduction std::pair> &drv = drivers.at(out); if (celldone.count(drv.first) == 0) { if (!satgen.importCell(drv.first)) - log_error("Can't create SAT model for cell %s (%s)!\n", RTLIL::id2cstr(drv.first->name), RTLIL::id2cstr(drv.first->type)); + log_error("Can't create SAT model for cell %s (%s)!\n", drv.first, drv.first->type.unescape()); celldone.insert(drv.first); } int max_child_depth = 0; @@ -595,14 +595,14 @@ struct FreduceWorker void dump() { - std::string filename = stringf("%s_%s_%05d.il", dump_prefix, RTLIL::id2cstr(module->name), reduce_counter); + std::string filename = stringf("%s_%s_%05d.il", dump_prefix, module, reduce_counter); log("%s Writing dump file `%s'.\n", reduce_counter ? " " : "", filename); Pass::call(design, stringf("dump -outfile %s %s", filename, design->selected_active_module.empty() ? module->name.c_str() : "")); } int run() { - log("Running functional reduction on module %s:\n", RTLIL::id2cstr(module->name)); + log("Running functional reduction on module %s:\n", module); CellTypes ct; ct.setup_internals(); @@ -749,7 +749,7 @@ struct FreduceWorker } } - log(" Rewired a total of %d signal bits in module %s.\n", rewired_sigbits, RTLIL::id2cstr(module->name)); + log(" Rewired a total of %d signal bits in module %s.\n", rewired_sigbits, module); return rewired_sigbits; } }; diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index 55a41909d..9df88b304 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -128,7 +128,7 @@ void create_miter_equiv(struct Pass *that, std::vector args, RTLIL: log_cmd_error("No matching port in gold module was found for %s!\n", gate_wire->name); } - log("Creating miter cell \"%s\" with gold cell \"%s\" and gate cell \"%s\".\n", RTLIL::id2cstr(miter_name), RTLIL::id2cstr(gold_name), RTLIL::id2cstr(gate_name)); + log("Creating miter cell \"%s\" with gold cell \"%s\" and gate cell \"%s\".\n", miter_name.unescape(), gold_name.unescape(), gate_name.unescape()); RTLIL::Module *miter_module = new RTLIL::Module; miter_module->name = miter_name; diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index d7667d6f5..0a12d4881 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -389,7 +389,7 @@ struct IopadmapPass : public Pass { if (wire->port_input && !wire->port_output) { if (inpad_celltype.empty()) { - log("Don't map input port %s.%s: Missing option -inpad.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire->name)); + log("Don't map input port %s.%s: Missing option -inpad.\n", module, wire); continue; } celltype = inpad_celltype; @@ -398,7 +398,7 @@ struct IopadmapPass : public Pass { } else if (!wire->port_input && wire->port_output) { if (outpad_celltype.empty()) { - log("Don't map output port %s.%s: Missing option -outpad.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire->name)); + log("Don't map output port %s.%s: Missing option -outpad.\n", module, wire); continue; } celltype = outpad_celltype; @@ -407,7 +407,7 @@ struct IopadmapPass : public Pass { } else if (wire->port_input && wire->port_output) { if (inoutpad_celltype.empty()) { - log("Don't map inout port %s.%s: Missing option -inoutpad.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire->name)); + log("Don't map inout port %s.%s: Missing option -inoutpad.\n", module, wire); continue; } celltype = inoutpad_celltype; @@ -417,11 +417,11 @@ struct IopadmapPass : public Pass { log_abort(); if (!flag_bits && wire->width != 1 && widthparam.empty()) { - log("Don't map multi-bit port %s.%s: Missing option -widthparam or -bits.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire->name)); + log("Don't map multi-bit port %s.%s: Missing option -widthparam or -bits.\n", module, wire); continue; } - log("Mapping port %s.%s using %s.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire->name), celltype); + log("Mapping port %s.%s using %s.\n", module, wire, celltype); if (flag_bits) { @@ -442,7 +442,7 @@ struct IopadmapPass : public Pass { if (!widthparam.empty()) cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(1); if (!nameparam.empty()) - cell->parameters[RTLIL::escape_id(nameparam)] = RTLIL::Const(stringf("%s[%d]", RTLIL::id2cstr(wire->name), i)); + cell->parameters[RTLIL::escape_id(nameparam)] = RTLIL::Const(stringf("%s[%d]", wire, i)); cell->attributes[ID::keep] = RTLIL::Const(1); } } @@ -465,7 +465,7 @@ struct IopadmapPass : public Pass { if (!widthparam.empty()) cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(wire->width); if (!nameparam.empty()) - cell->parameters[RTLIL::escape_id(nameparam)] = RTLIL::Const(RTLIL::id2cstr(wire->name)); + cell->parameters[RTLIL::escape_id(nameparam)] = RTLIL::Const(wire->name.unescape()); cell->attributes[ID::keep] = RTLIL::Const(1); } diff --git a/techlibs/ice40/ice40_braminit.cc b/techlibs/ice40/ice40_braminit.cc index 0d07e2522..4a1849642 100644 --- a/techlibs/ice40/ice40_braminit.cc +++ b/techlibs/ice40/ice40_braminit.cc @@ -46,7 +46,7 @@ static void run_ice40_braminit(Module *module) continue; /* Open file */ - log("Processing %s : %s\n", RTLIL::id2cstr(cell->name), init_file); + log("Processing %s : %s\n", cell, init_file); std::ifstream f; f.open(init_file.c_str()); From 75dcbe03c6a61beb893967766fa8e2bac095446a Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 15 May 2026 15:54:07 +0200 Subject: [PATCH 043/354] Convert RTLIL::unescape_id of IdString to unescape() --- backends/aiger2/aiger.cc | 10 +- backends/blif/blif.cc | 4 +- backends/edif/edif.cc | 20 +- backends/functional/cxx.cc | 2 +- backends/functional/smtlib.cc | 4 +- backends/functional/smtlib_rosette.cc | 6 +- backends/functional/test_generic.cc | 6 +- backends/intersynth/intersynth.cc | 2 +- backends/jny/jny.cc | 14 +- backends/json/json.cc | 2 +- backends/spice/spice.cc | 2 +- frontends/liberty/liberty.cc | 24 +- kernel/functional.cc | 8 +- kernel/functional.h | 2 +- kernel/log.cc | 2 +- kernel/satgen.h | 2 +- kernel/scopeinfo.cc | 4 +- kernel/yosys.cc | 10 +- passes/cmds/icell_liberty.cc | 6 +- passes/cmds/portarcs.cc | 2 +- passes/cmds/rename.cc | 2 +- passes/cmds/show.cc | 2 +- passes/cmds/wrapcell.cc | 2 +- passes/equiv/equiv_make.cc.orig | 520 ++++++++++++++++++++++++++ passes/fsm/fsm_recode.cc | 4 +- passes/hierarchy/flatten.cc | 6 +- passes/hierarchy/hierarchy.cc | 6 +- passes/sat/cutpoint.cc | 2 +- passes/sat/expose.cc | 4 +- passes/sat/miter.cc | 12 +- passes/sat/sim.cc | 40 +- passes/techmap/abc.cc | 4 +- passes/techmap/extract.cc | 8 +- passes/techmap/techmap.cc | 4 +- techlibs/common/opensta.cc | 2 +- 35 files changed, 636 insertions(+), 114 deletions(-) create mode 100644 passes/equiv/equiv_make.cc.orig diff --git a/backends/aiger2/aiger.cc b/backends/aiger2/aiger.cc index 6d8ac8a24..0dceaedd6 100644 --- a/backends/aiger2/aiger.cc +++ b/backends/aiger2/aiger.cc @@ -560,9 +560,9 @@ struct Index { if (!first) ret += "."; if (!cell) - ret += RTLIL::unescape_id(minfo.module->name); + ret += minfo.module->name.unescape(); else - ret += RTLIL::unescape_id(cell->name); + ret += cell->name.unescape(); first = false; } return ret; @@ -844,7 +844,7 @@ struct AigerWriter : Index { char buf[32]; snprintf(buf, sizeof(buf), "o%d ", i); f->write(buf, strlen(buf)); - std::string name = RTLIL::unescape_id(bit.wire->name); + std::string name = bit.wire->name.unescape(); f->write(name.data(), name.size()); f->put('\n'); } @@ -857,7 +857,7 @@ struct AigerWriter : Index { char buf[32]; snprintf(buf, sizeof(buf), "i%d ", i); f->write(buf, strlen(buf)); - std::string name = RTLIL::unescape_id(bit.wire->name); + std::string name = bit.wire->name.unescape(); f->write(name.data(), name.size()); f->put('\n'); } @@ -1088,7 +1088,7 @@ struct XAigerWriter : AigerWriter { for (auto box : minfo.found_blackboxes) { log_debug(" - %s.%s (type %s): ", cursor.path(), - RTLIL::unescape_id(box->name), + box, box->type.unescape()); Module *box_module = design->module(box->type), *box_derived; diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index d16d39e5e..ac2e4edde 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -91,7 +91,7 @@ struct BlifDumper const std::string str(RTLIL::IdString id) { - std::string str = RTLIL::unescape_id(id); + std::string str = id.unescape(); for (size_t i = 0; i < str.size(); i++) if (str[i] == '#' || str[i] == '=' || str[i] == '<' || str[i] == '>') str[i] = '?'; @@ -108,7 +108,7 @@ struct BlifDumper return config->undef_type == "-" || config->undef_type == "+" ? config->undef_out.c_str() : "$undef"; } - std::string str = RTLIL::unescape_id(sig.wire->name); + std::string str = sig.wire->name.unescape(); for (size_t i = 0; i < str.size(); i++) if (str[i] == '#' || str[i] == '=' || str[i] == '<' || str[i] == '>') str[i] = '?'; diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index 180c3739b..9d3392e99 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -30,9 +30,11 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -#define EDIF_DEF(_id) edif_names(RTLIL::unescape_id(_id), true) -#define EDIF_DEFR(_id, _ren, _bl, _br) edif_names(RTLIL::unescape_id(_id), true, _ren, _bl, _br) -#define EDIF_REF(_id) edif_names(RTLIL::unescape_id(_id), false) +#define EDIF_DEF(_id) edif_names(_id.unescape(), true) +#define EDIF_DEFR(_id, _ren, _bl, _br) edif_names(_id.unescape(), true, _ren, _bl, _br) +#define EDIF_REF(_id) edif_names(_id.unescape(), false) +#define EDIF_DEF_STR(_id) edif_names(RTLIL::unescape_id(_id), true) +#define EDIF_REF_STR(_id) edif_names(RTLIL::unescape_id(_id), false) struct EdifNames { @@ -227,7 +229,7 @@ struct EdifBackend : public Backend { if (top_module_name.empty()) log_error("No module found in design!\n"); - *f << stringf("(edif %s\n", EDIF_DEF(top_module_name)); + *f << stringf("(edif %s\n", EDIF_DEF_STR(top_module_name)); *f << stringf(" (edifVersion 2 0 0)\n"); *f << stringf(" (edifLevel 0)\n"); *f << stringf(" (keywordMap (keywordLevel 0))\n"); @@ -534,7 +536,7 @@ struct EdifBackend : public Backend { if (netname[i] == ' ' || netname[i] == '\\') netname.erase(netname.begin() + i--); } - *f << stringf(" (net %s (joined\n", EDIF_DEF(netname)); + *f << stringf(" (net %s (joined\n", EDIF_DEF_STR(netname)); for (auto &ref : it.second) *f << stringf(" %s\n", ref.first); if (sig.wire == NULL) { @@ -572,7 +574,7 @@ struct EdifBackend : public Backend { if (keepmode) { - *f << stringf(" (net %s (joined\n", EDIF_DEF(netname)); + *f << stringf(" (net %s (joined\n", EDIF_DEF_STR(netname)); auto &refs = net_join_db.at(mapped_sig); for (auto &ref : refs) @@ -588,7 +590,7 @@ struct EdifBackend : public Backend { } else { - log_warning("Ignoring conflicting 'keep' property on net %s. Use -keep to generate the extra net nevertheless.\n", EDIF_DEF(netname)); + log_warning("Ignoring conflicting 'keep' property on net %s. Use -keep to generate the extra net nevertheless.\n", EDIF_DEF_STR(netname)); } } } @@ -599,8 +601,8 @@ struct EdifBackend : public Backend { } *f << stringf(" )\n"); - *f << stringf(" (design %s\n", EDIF_DEF(top_module_name)); - *f << stringf(" (cellRef %s (libraryRef DESIGN))\n", EDIF_REF(top_module_name)); + *f << stringf(" (design %s\n", EDIF_DEF_STR(top_module_name)); + *f << stringf(" (cellRef %s (libraryRef DESIGN))\n", EDIF_REF_STR(top_module_name)); *f << stringf(" )\n"); *f << stringf(")\n"); diff --git a/backends/functional/cxx.cc b/backends/functional/cxx.cc index 7f4ad1ea7..d67bc9143 100644 --- a/backends/functional/cxx.cc +++ b/backends/functional/cxx.cc @@ -89,7 +89,7 @@ struct CxxStruct { } f.print("\n\t\ttemplate void visit(T &&fn) {{\n"); for (auto p : types) { - f.print("\t\t\tfn(\"{}\", {});\n", RTLIL::unescape_id(p.first), scope(p.first, p.first)); + f.print("\t\t\tfn(\"{}\", {});\n", p.first.unescape(), scope(p.first, p.first)); } f.print("\t\t}}\n"); f.print("\t}};\n\n"); diff --git a/backends/functional/smtlib.cc b/backends/functional/smtlib.cc index 1504c8fba..0451af4c7 100644 --- a/backends/functional/smtlib.cc +++ b/backends/functional/smtlib.cc @@ -80,7 +80,7 @@ public: SmtStruct(std::string name, SmtScope &scope) : scope(scope), name(name) {} void insert(IdString field_name, SmtSort sort) { field_names(field_name); - auto accessor = scope.unique_name("\\" + name + "_" + RTLIL::unescape_id(field_name)); + auto accessor = scope.unique_name("\\" + name + "_" + field_name.unescape()); fields.emplace_back(Field{sort, accessor}); } void write_definition(SExprWriter &w) { @@ -99,7 +99,7 @@ public: w.open(list(name)); for(auto field_name : field_names) { w << fn(field_name); - w.comment(RTLIL::unescape_id(field_name), true); + w.comment(field_name.unescape(), true); } w.close(); } diff --git a/backends/functional/smtlib_rosette.cc b/backends/functional/smtlib_rosette.cc index 73e1b48c6..b37f948b6 100644 --- a/backends/functional/smtlib_rosette.cc +++ b/backends/functional/smtlib_rosette.cc @@ -106,7 +106,7 @@ public: w.open(list(name)); for(auto field_name : field_names) { w << fn(field_name); - w.comment(RTLIL::unescape_id(field_name), true); + w.comment(field_name.unescape(), true); } w.close(); } @@ -281,7 +281,7 @@ struct SmtrModule { w.push(); w.open(list()); w.open(list("assoc-result")); - w << list("assoc", "\"" + RTLIL::unescape_id(input->name) + "\"", inputs_name); + w << list("assoc", "\"" + input->name.unescape() + "\"", inputs_name); w.pop(); w.open(list("if", "assoc-result")); w << list("cdr", "assoc-result"); @@ -298,7 +298,7 @@ struct SmtrModule { w << list(*output_helper_name, outputs_name); w.open(list("list")); for (auto output : ir.outputs()) { - w << list("cons", "\"" + RTLIL::unescape_id(output->name) + "\"", output_struct.access("outputs", output->name)); + w << list("cons", "\"" + output->name.unescape() + "\"", output_struct.access("outputs", output->name)); } w.pop(); } diff --git a/backends/functional/test_generic.cc b/backends/functional/test_generic.cc index c01649a0f..343fcfc0f 100644 --- a/backends/functional/test_generic.cc +++ b/backends/functional/test_generic.cc @@ -146,11 +146,11 @@ struct FunctionalTestGeneric : public Pass log("Dumping module `%s'.\n", module->name); auto fir = Functional::IR::from_module(module); for(auto node : fir) - std::cout << RTLIL::unescape_id(node.name()) << " = " << node.to_string([](auto n) { return RTLIL::unescape_id(n.name()); }) << "\n"; + std::cout << node.name().unescape() << " = " << node.to_string([](auto n) { return n.name().unescape(); }) << "\n"; for(auto output : fir.all_outputs()) - std::cout << RTLIL::unescape_id(output->kind) << " " << RTLIL::unescape_id(output->name) << " = " << RTLIL::unescape_id(output->value().name()) << "\n"; + std::cout << output->kind.unescape() << " " << output->name.unescape() << " = " << output->value().name().unescape() << "\n"; for(auto state : fir.all_states()) - std::cout << RTLIL::unescape_id(state->kind) << " " << RTLIL::unescape_id(state->name) << " = " << RTLIL::unescape_id(state->next_value().name()) << "\n"; + std::cout << state->kind.unescape() << " " << state->name.unescape() << " = " << state->next_value().name().unescape() << "\n"; } } } FunctionalCxxBackend; diff --git a/backends/intersynth/intersynth.cc b/backends/intersynth/intersynth.cc index 5e1a3fc8d..1704ba429 100644 --- a/backends/intersynth/intersynth.cc +++ b/backends/intersynth/intersynth.cc @@ -41,7 +41,7 @@ static std::string netname(std::set &conntypes_code, std::setname); + return sig.as_wire()->name.unescape(); } struct IntersynthBackend : public Backend { diff --git a/backends/jny/jny.cc b/backends/jny/jny.cc index ee0c0d14c..00650f5d8 100644 --- a/backends/jny/jny.cc +++ b/backends/jny/jny.cc @@ -91,7 +91,7 @@ struct JnyWriter { _cells.clear(); for (auto cell : mod->cells()) { - const auto cell_type = escape_string(RTLIL::unescape_id(cell->type)); + const auto cell_type = escape_string(cell->type.unescape()); if (_cells.find(cell_type) == _cells.end()) _cells.emplace(cell_type, std::vector()); @@ -214,7 +214,7 @@ struct JnyWriter void write_cell_conn(const std::pair& sig, uint16_t indent_level = 0) { const auto _indent = gen_indent(indent_level); f << _indent << " {\n"; - f << _indent << " \"name\": \"" << escape_string(RTLIL::unescape_id(sig.first)) << "\",\n"; + f << _indent << " \"name\": \"" << escape_string(sig.first.unescape()) << "\",\n"; f << _indent << " \"signals\": [\n"; write_sigspec(sig.second, indent_level + 2); @@ -232,7 +232,7 @@ struct JnyWriter const auto _indent = gen_indent(indent_level); f << _indent << "{\n"; - f << stringf(" %s\"name\": \"%s\",\n", _indent, escape_string(RTLIL::unescape_id(mod->name))); + f << stringf(" %s\"name\": \"%s\",\n", _indent, escape_string(mod->name.unescape())); f << _indent << " \"cell_sorts\": [\n"; bool first_sort{true}; @@ -280,7 +280,7 @@ struct JnyWriter f << ",\n"; f << _indent << " {\n"; - f << stringf(" %s\"name\": \"%s\",\n", _indent, escape_string(RTLIL::unescape_id(con.first))); + f << stringf(" %s\"name\": \"%s\",\n", _indent, escape_string(con.first.unescape())); f << _indent << " \"direction\": \""; if (port_cell->input(con.first)) f << "i"; @@ -351,10 +351,10 @@ struct JnyWriter f << stringf(",\n"); const auto param_val = param.second; if (!param_val.empty()) { - f << stringf(" %s\"%s\": ", _indent, escape_string(RTLIL::unescape_id(param.first))); + f << stringf(" %s\"%s\": ", _indent, escape_string(param.first.unescape())); write_param_val(param_val); } else { - f << stringf(" %s\"%s\": true", _indent, escape_string(RTLIL::unescape_id(param.first))); + f << stringf(" %s\"%s\": true", _indent, escape_string(param.first.unescape())); } first_param = false; @@ -366,7 +366,7 @@ struct JnyWriter log_assert(cell != nullptr); f << _indent << " {\n"; - f << stringf(" %s\"name\": \"%s\"", _indent, escape_string(RTLIL::unescape_id(cell->name))); + f << stringf(" %s\"name\": \"%s\"", _indent, escape_string(cell->name.unescape())); if (_include_connections) { f << ",\n" << _indent << " \"connections\": [\n"; diff --git a/backends/json/json.cc b/backends/json/json.cc index 234574ed1..23d18fb15 100644 --- a/backends/json/json.cc +++ b/backends/json/json.cc @@ -76,7 +76,7 @@ struct JsonWriter string get_name(IdString name) { - return get_string(RTLIL::unescape_id(name)); + return get_string(name.unescape()); } string get_bits(SigSpec sig) diff --git a/backends/spice/spice.cc b/backends/spice/spice.cc index 36caf6359..5f14a2a66 100644 --- a/backends/spice/spice.cc +++ b/backends/spice/spice.cc @@ -30,7 +30,7 @@ PRIVATE_NAMESPACE_BEGIN static string spice_id2str(IdString id) { static const char *escape_chars = "$\\[]()<>="; - string s = RTLIL::unescape_id(id); + string s = id.unescape(); for (auto &ch : s) if (strchr(escape_chars, ch) != nullptr) ch = '_'; diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index a006ae649..447f438a8 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -41,14 +41,14 @@ static RTLIL::SigSpec parse_func_identifier(RTLIL::Module *module, const char *& expr[id_len] == '_' || expr[id_len] == '[' || expr[id_len] == ']') id_len++; if (id_len == 0) - log_error("Expected identifier at `%s' in %s.\n", expr, RTLIL::unescape_id(module->name)); + log_error("Expected identifier at `%s' in %s.\n", expr, module); if (id_len == 1 && (*expr == '0' || *expr == '1')) return *(expr++) == '0' ? RTLIL::State::S0 : RTLIL::State::S1; std::string id = RTLIL::escape_id(std::string(expr, id_len)); if (!module->wires_.count(id)) - log_error("Can't resolve wire name %s in %s.\n", RTLIL::unescape_id(id), RTLIL::unescape_id(module->name)); + log_error("Can't resolve wire name %s in %s.\n", RTLIL::unescape_id(id), module); expr += id_len; return module->wires_.at(id); @@ -175,7 +175,7 @@ static RTLIL::SigSpec parse_func_expr(RTLIL::Module *module, const char *expr) #endif if (stack.size() != 1 || stack.back().type != 3) - log_error("Parser error in function expr `%s'in %s.\n", orig_expr, RTLIL::unescape_id(module->name)); + log_error("Parser error in function expr `%s'in %s.\n", orig_expr, module); return stack.back().sig; } @@ -211,7 +211,7 @@ static void create_ff(RTLIL::Module *module, const LibertyAst *node) auto [iq_sig, iqn_sig] = find_latch_ff_wires(module, node); RTLIL::SigSpec clk_sig, data_sig, clear_sig, preset_sig; bool clk_polarity = true, clear_polarity = true, preset_polarity = true; - const std::string name = RTLIL::unescape_id(module->name); + const std::string name = module->name.unescape(); std::optional clear_preset_var1; std::optional clear_preset_var2; @@ -339,9 +339,9 @@ static bool create_latch(RTLIL::Module *module, const LibertyAst *node, bool fla if (enable_sig.size() == 0 || data_sig.size() == 0) { if (!flag_ignore_miss_data_latch) - log_error("Latch cell %s has no data_in and/or enable attribute.\n", RTLIL::unescape_id(module->name)); + log_error("Latch cell %s has no data_in and/or enable attribute.\n", module); else - log("Ignored latch cell %s with no data_in and/or enable attribute.\n", RTLIL::unescape_id(module->name)); + log("Ignored latch cell %s with no data_in and/or enable attribute.\n", module); return false; } @@ -632,9 +632,9 @@ struct LibertyFrontend : public Frontend { { if (!flag_ignore_miss_dir) { - log_error("Missing or invalid direction for pin %s on cell %s.\n", node->args.at(0), RTLIL::unescape_id(module->name)); + log_error("Missing or invalid direction for pin %s on cell %s.\n", node->args.at(0), module); } else { - log("Ignoring cell %s with missing or invalid direction for pin %s.\n", RTLIL::unescape_id(module->name), node->args.at(0)); + log("Ignoring cell %s with missing or invalid direction for pin %s.\n", module, node->args.at(0)); delete module; goto skip_cell; } @@ -646,7 +646,7 @@ struct LibertyFrontend : public Frontend { if (node->id == "bus" && node->args.size() == 1) { if (flag_ignore_buses) { - log("Ignoring cell %s with a bus interface %s.\n", RTLIL::unescape_id(module->name), node->args.at(0)); + log("Ignoring cell %s with a bus interface %s.\n", module, node->args.at(0)); delete module; goto skip_cell; } @@ -663,7 +663,7 @@ struct LibertyFrontend : public Frontend { } if (!dir || (dir->value != "input" && dir->value != "output" && dir->value != "inout" && dir->value != "internal")) - log_error("Missing or invalid direction for bus %s on cell %s.\n", node->args.at(0), RTLIL::unescape_id(module->name)); + log_error("Missing or invalid direction for bus %s on cell %s.\n", node->args.at(0), module); simple_comb_cell = false; @@ -758,9 +758,9 @@ struct LibertyFrontend : public Frontend { if (dir->value != "inout") { // allow inout with missing function, can be used for power pins if (!flag_ignore_miss_func) { - log_error("Missing function on output %s of cell %s.\n", RTLIL::unescape_id(wire->name), RTLIL::unescape_id(module->name)); + log_error("Missing function on output %s of cell %s.\n", wire, module); } else { - log("Ignoring cell %s with missing function on output %s.\n", RTLIL::unescape_id(module->name), RTLIL::unescape_id(wire->name)); + log("Ignoring cell %s with missing function on output %s.\n", module, wire); delete module; goto skip_cell; } diff --git a/kernel/functional.cc b/kernel/functional.cc index 4d1423b28..d04677332 100644 --- a/kernel/functional.cc +++ b/kernel/functional.cc @@ -136,7 +136,7 @@ struct PrintVisitor : DefaultVisitor { std::string Node::to_string() { - return to_string([](Node n) { return RTLIL::unescape_id(n.name()); }); + return to_string([](Node n) { return n.name().unescape(); }); } std::string Node::to_string(std::function np) @@ -677,7 +677,7 @@ public: factory.update_pending(pending, node); } else { DriveSpec driver = driver_map(DriveSpec(wire_chunk)); - check_undriven(driver, RTLIL::unescape_id(wire_chunk.wire->name)); + check_undriven(driver, wire_chunk.wire->name.unescape()); Node node = enqueue(driver); factory.suggest_name(node, wire_chunk.wire->name); factory.update_pending(pending, node); @@ -695,7 +695,7 @@ public: factory.update_pending(pending, node); } else { DriveSpec driver = driver_map(DriveSpec(port_chunk)); - check_undriven(driver, RTLIL::unescape_id(port_chunk.cell->name) + " port " + RTLIL::unescape_id(port_chunk.port)); + check_undriven(driver, port_chunk.cell->name.unescape() + " port " + port_chunk.port.unescape()); factory.update_pending(pending, enqueue(driver)); } } else { @@ -744,7 +744,7 @@ void IR::topological_sort() { log_warning("Combinational loop:\n"); for (int *i = begin; i != end; ++i) { Node node(_graph[*i]); - log("- %s = %s\n", RTLIL::unescape_id(node.name()), node.to_string()); + log("- %s = %s\n", node.name().unescape(), node.to_string()); } log("\n"); scc = true; diff --git a/kernel/functional.h b/kernel/functional.h index 073adf40a..3334f02c8 100644 --- a/kernel/functional.h +++ b/kernel/functional.h @@ -588,7 +588,7 @@ namespace Functional { _used_names.insert(std::move(name)); } std::string unique_name(IdString suggestion) { - std::string str = RTLIL::unescape_id(suggestion); + std::string str = suggestion.unescape(); for(size_t i = 0; i < str.size(); i++) if(!is_character_legal(str[i], i)) str[i] = substitution_character; diff --git a/kernel/log.cc b/kernel/log.cc index fd3f75502..272b69589 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -614,7 +614,7 @@ std::string log_const(const RTLIL::Const &value, bool autoint) const char *log_id(const RTLIL::IdString &str) { - std::string unescaped = RTLIL::unescape_id(str); + std::string unescaped = str.unescape(); log_id_cache.push_back(strdup(unescaped.c_str())); return log_id_cache.back(); } diff --git a/kernel/satgen.h b/kernel/satgen.h index c11d480a4..722433d62 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -102,7 +102,7 @@ struct SatGen else vec.push_back(bit == (undef_mode ? RTLIL::State::Sx : RTLIL::State::S1) ? ez->CONST_TRUE : ez->CONST_FALSE); } else { - std::string wire_name = RTLIL::unescape_id(bit.wire->name); + std::string wire_name = bit.wire->name.unescape(); std::string name = pf + (bit.wire->width == 1 ? wire_name : stringf("%s [%d]", wire_name, bit.offset)); vec.push_back(ez->frozen_literal(name)); diff --git a/kernel/scopeinfo.cc b/kernel/scopeinfo.cc index 59dd746b5..aac83d564 100644 --- a/kernel/scopeinfo.cc +++ b/kernel/scopeinfo.cc @@ -100,13 +100,13 @@ static const char *attr_prefix(ScopeinfoAttrs attrs) bool scopeinfo_has_attribute(const RTLIL::Cell *scopeinfo, ScopeinfoAttrs attrs, RTLIL::IdString id) { log_assert(scopeinfo->type == ID($scopeinfo)); - return scopeinfo->has_attribute(attr_prefix(attrs) + RTLIL::unescape_id(id)); + return scopeinfo->has_attribute(attr_prefix(attrs) + id.unescape()); } RTLIL::Const scopeinfo_get_attribute(const RTLIL::Cell *scopeinfo, ScopeinfoAttrs attrs, RTLIL::IdString id) { log_assert(scopeinfo->type == ID($scopeinfo)); - auto found = scopeinfo->attributes.find(attr_prefix(attrs) + RTLIL::unescape_id(id)); + auto found = scopeinfo->attributes.find(attr_prefix(attrs) + id.unescape()); if (found == scopeinfo->attributes.end()) return RTLIL::Const(); return found->second; diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 5643ed7b0..de5baaee8 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -953,7 +953,7 @@ static char *readline_obj_generator(const char *text, int state) if (design->selected_active_module.empty()) { for (auto mod : design->modules()) - if (RTLIL::unescape_id(mod->name).compare(0, len, text) == 0) + if (mod->name.unescape().compare(0, len, text) == 0) obj_names.push_back(strdup(mod->name.unescape().c_str())); } else if (design->module(design->selected_active_module) != nullptr) @@ -961,19 +961,19 @@ static char *readline_obj_generator(const char *text, int state) RTLIL::Module *module = design->module(design->selected_active_module); for (auto w : module->wires()) - if (RTLIL::unescape_id(w->name).compare(0, len, text) == 0) + if (w->name.unescape().compare(0, len, text) == 0) obj_names.push_back(strdup(w->name.unescape().c_str())); for (auto &it : module->memories) - if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0) + if (it.first.unescape().compare(0, len, text) == 0) obj_names.push_back(strdup(it.first.unescape().c_str())); for (auto cell : module->cells()) - if (RTLIL::unescape_id(cell->name).compare(0, len, text) == 0) + if (cell->name.unescape().compare(0, len, text) == 0) obj_names.push_back(strdup(cell->name.unescape().c_str())); for (auto &it : module->processes) - if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0) + if (it.first.unescape().compare(0, len, text) == 0) obj_names.push_back(strdup(it.first.unescape().c_str())); } diff --git a/passes/cmds/icell_liberty.cc b/passes/cmds/icell_liberty.cc index 1d3628f1f..e0a73d08f 100644 --- a/passes/cmds/icell_liberty.cc +++ b/passes/cmds/icell_liberty.cc @@ -71,10 +71,10 @@ struct LibertyStubber { std::sort(sorted_ports.begin(), sorted_ports.end(), cmp); std::string clock_pin_name = ""; for (auto x : sorted_ports) { - std::string port_name = RTLIL::unescape_id(x); + std::string port_name = x.unescape(); bool is_input = base_type.inputs.count(x); bool is_output = base_type.outputs.count(x); - f << "\t\tpin (" << RTLIL::unescape_id(x.str()) << ") {\n"; + f << "\t\tpin (" << x.unescape() << ") {\n"; if (is_input && !is_output) { i.item("direction", "input"); } else if (!is_input && is_output) { @@ -132,7 +132,7 @@ struct LibertyStubber { for (auto x : derived->ports) { bool is_input = base_type.inputs.count(x); bool is_output = base_type.outputs.count(x); - f << "\t\tpin (" << RTLIL::unescape_id(x.str()) << ") {\n"; + f << "\t\tpin (" << x.unescape() << ") {\n"; if (is_input && !is_output) { f << "\t\t\tdirection : input;\n"; } else if (!is_input && is_output) { diff --git a/passes/cmds/portarcs.cc b/passes/cmds/portarcs.cc index 581a8bebf..89a4581ce 100644 --- a/passes/cmds/portarcs.cc +++ b/passes/cmds/portarcs.cc @@ -244,7 +244,7 @@ struct PortarcsPass : Pass { if (draw_mode) { auto bit_str = [](SigBit bit) { - return stringf("%s%d", RTLIL::unescape_id(bit.wire->name.str()), bit.offset); + return stringf("%s%d", bit.wire, bit.offset); }; std::vector headings; diff --git a/passes/cmds/rename.cc b/passes/cmds/rename.cc index 2f70126dd..0da132521 100644 --- a/passes/cmds/rename.cc +++ b/passes/cmds/rename.cc @@ -621,7 +621,7 @@ struct RenamePass : public Pass { RTLIL::Module *module_to_rename = nullptr; for (auto module : design->modules()) - if (module->name == from_name || RTLIL::unescape_id(module->name) == from_name) { + if (module->name == from_name || module->name.unescape() == from_name) { module_to_rename = module; break; } diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index f45a2aeee..919d13b96 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -549,7 +549,7 @@ struct ShowWorker net_conn_map[node].color = nextColor(sig, net_conn_map[node].color); } - std::string proc_src = RTLIL::unescape_id(proc->name); + std::string proc_src = proc->name.unescape(); if (proc->attributes.count(ID::src) > 0) proc_src = proc->attributes.at(ID::src).decode_string(); fprintf(f, "p%d [shape=box, style=rounded, label=\"PROC %s\\n%s\", %s];\n", pidx, findLabel(proc->name.str()), proc_src.c_str(), findColor(proc->name).c_str()); diff --git a/passes/cmds/wrapcell.cc b/passes/cmds/wrapcell.cc index 1d73decc5..9d73a63c0 100644 --- a/passes/cmds/wrapcell.cc +++ b/passes/cmds/wrapcell.cc @@ -227,7 +227,7 @@ struct WrapcellPass : Pass { if (!unused_outputs.empty()) { context.unused_outputs += "_unused"; for (auto chunk : collect_chunks(unused_outputs)) - context.unused_outputs += "_" + RTLIL::unescape_id(chunk.format(cell)); + context.unused_outputs += "_" + chunk.format(cell).unescape(); } std::optional unescaped_name = format_with_params(name_fmt, cell->parameters, context); diff --git a/passes/equiv/equiv_make.cc.orig b/passes/equiv/equiv_make.cc.orig new file mode 100644 index 000000000..3aa3fac63 --- /dev/null +++ b/passes/equiv/equiv_make.cc.orig @@ -0,0 +1,520 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xenia Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/yosys.h" +#include "kernel/sigtools.h" +#include "kernel/celltypes.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct EquivMakeWorker +{ + Module *gold_mod, *gate_mod, *equiv_mod; + pool wire_names, cell_names; + CellTypes ct; + + bool inames; + vector blacklists; + vector encfiles; + bool make_assert; + + pool blacklist_names; + dict> encdata; + + pool undriven_bits; + SigMap assign_map; + + void read_blacklists() + { + for (auto fn : blacklists) + { + std::ifstream f(fn); + if (f.fail()) + log_cmd_error("Can't open blacklist file '%s'!\n", fn); + + string line, token; + while (std::getline(f, line)) { + while (1) { + token = next_token(line); + if (token.empty()) + break; + blacklist_names.insert(RTLIL::escape_id(token)); + } + } + } + } + + void read_encfiles() + { + for (auto fn : encfiles) + { + std::ifstream f(fn); + if (f.fail()) + log_cmd_error("Can't open encfile '%s'!\n", fn); + + dict *ed = nullptr; + string line, token; + while (std::getline(f, line)) + { + token = next_token(line); + if (token.empty() || token[0] == '#') + continue; + + if (token == ".fsm") { + IdString modname = RTLIL::escape_id(next_token(line)); + (void)modname; + IdString signame = RTLIL::escape_id(next_token(line)); + if (encdata.count(signame)) + log_cmd_error("Re-definition of signal '%s' in encfile '%s'!\n", signame, fn); + encdata[signame] = dict(); + ed = &encdata[signame]; + continue; + } + + if (token == ".map") { + Const gold_bits = Const::from_string(next_token(line)); + Const gate_bits = Const::from_string(next_token(line)); + (*ed)[gold_bits] = gate_bits; + continue; + } + + log_cmd_error("Syntax error in encfile '%s'!\n", fn); + } + } + } + + void copy_to_equiv() + { + Module *gold_clone = gold_mod->clone(); + Module *gate_clone = gate_mod->clone(); + + for (auto it : gold_clone->wires().to_vector()) { + if ((it->name.isPublic() || inames) && blacklist_names.count(it->name) == 0) + wire_names.insert(it->name); + gold_clone->rename(it, it->name.str() + "_gold"); + } + + for (auto it : gold_clone->cells().to_vector()) { + if ((it->name.isPublic() || inames) && blacklist_names.count(it->name) == 0) + cell_names.insert(it->name); + gold_clone->rename(it, it->name.str() + "_gold"); + } + + for (auto it : gate_clone->wires().to_vector()) { + if ((it->name.isPublic() || inames) && blacklist_names.count(it->name) == 0) + wire_names.insert(it->name); + gate_clone->rename(it, it->name.str() + "_gate"); + } + + for (auto it : gate_clone->cells().to_vector()) { + if ((it->name.isPublic() || inames) && blacklist_names.count(it->name) == 0) + cell_names.insert(it->name); + gate_clone->rename(it, it->name.str() + "_gate"); + } + + gold_clone->cloneInto(equiv_mod); + gate_clone->cloneInto(equiv_mod); + delete gold_clone; + delete gate_clone; + } + + void add_eq_assertion(const SigSpec &gold_sig, const SigSpec &gate_sig) + { + auto eq_wire = equiv_mod->Eqx(NEW_ID, gold_sig, gate_sig); + equiv_mod->addAssert(NEW_ID_SUFFIX("assert"), eq_wire, State::S1); + } + + void find_same_wires() + { + SigMap assign_map(equiv_mod); + SigMap rd_signal_map; + SigPool primary_inputs; + + // list of cells without added $equiv cells + auto cells_list = equiv_mod->cells().to_vector(); + + for (auto id : wire_names) + { + IdString gold_id = id.str() + "_gold"; + IdString gate_id = id.str() + "_gate"; + + Wire *gold_wire = equiv_mod->wire(gold_id); + Wire *gate_wire = equiv_mod->wire(gate_id); + + if (encdata.count(id)) + { + log("Creating encoder/decoder for signal %s.\n", id.unescape()); + + Wire *dec_wire = equiv_mod->addWire(id.str() + "_decoded", gold_wire->width); + Wire *enc_wire = equiv_mod->addWire(id.str() + "_encoded", gate_wire->width); + + SigSpec dec_a, dec_b, dec_s; + SigSpec enc_a, enc_b, enc_s; + + dec_a = SigSpec(State::Sx, dec_wire->width); + enc_a = SigSpec(State::Sx, enc_wire->width); + + for (auto &it : encdata.at(id)) + { + SigSpec dec_sig = gate_wire, dec_pat = it.second; + SigSpec enc_sig = dec_wire, enc_pat = it.first; + + if (GetSize(dec_sig) != GetSize(dec_pat)) + log_error("Invalid pattern %s for signal %s of size %d!\n", + log_signal(dec_pat), log_signal(dec_sig), GetSize(dec_sig)); + + if (GetSize(enc_sig) != GetSize(enc_pat)) + log_error("Invalid pattern %s for signal %s of size %d!\n", + log_signal(enc_pat), log_signal(enc_sig), GetSize(enc_sig)); + + SigSpec reduced_dec_sig, reduced_dec_pat; + for (int i = 0; i < GetSize(dec_sig); i++) + if (dec_pat[i] == State::S0 || dec_pat[i] == State::S1) { + reduced_dec_sig.append(dec_sig[i]); + reduced_dec_pat.append(dec_pat[i]); + } + + SigSpec reduced_enc_sig, reduced_enc_pat; + for (int i = 0; i < GetSize(enc_sig); i++) + if (enc_pat[i] == State::S0 || enc_pat[i] == State::S1) { + reduced_enc_sig.append(enc_sig[i]); + reduced_enc_pat.append(enc_pat[i]); + } + + SigSpec dec_result = it.first; + for (auto &bit : dec_result) + if (bit != State::S1) bit = State::S0; + + SigSpec enc_result = it.second; + for (auto &bit : enc_result) + if (bit != State::S1) bit = State::S0; + + SigSpec dec_eq = equiv_mod->addWire(NEW_ID); + SigSpec enc_eq = equiv_mod->addWire(NEW_ID); + + equiv_mod->addEq(NEW_ID, reduced_dec_sig, reduced_dec_pat, dec_eq); + cells_list.push_back(equiv_mod->addEq(NEW_ID, reduced_enc_sig, reduced_enc_pat, enc_eq)); + + dec_s.append(dec_eq); + enc_s.append(enc_eq); + dec_b.append(dec_result); + enc_b.append(enc_result); + } + + equiv_mod->addPmux(NEW_ID, dec_a, dec_b, dec_s, dec_wire); + equiv_mod->addPmux(NEW_ID, enc_a, enc_b, enc_s, enc_wire); + + rd_signal_map.add(assign_map(gate_wire), enc_wire); + gate_wire = dec_wire; + } + + if (gold_wire == nullptr || gate_wire == nullptr || gold_wire->width != gate_wire->width) { + if (gold_wire && gold_wire->port_id) + log_error("Can't match gold port `%s' to a gate port.\n", gold_wire); + if (gate_wire && gate_wire->port_id) + log_error("Can't match gate port `%s' to a gold port.\n", gate_wire); + continue; + } + + log("Presumably equivalent wires: %s (%s), %s (%s) -> %s\n", + gold_wire, log_signal(assign_map(gold_wire)), + gate_wire, log_signal(assign_map(gate_wire)), id.unescape()); + + if (gold_wire->port_output || gate_wire->port_output) + { + gold_wire->port_input = false; + gate_wire->port_input = false; + gold_wire->port_output = false; + gate_wire->port_output = false; + + Wire *wire = equiv_mod->addWire(id, gold_wire->width); + wire->port_output = true; + + if (make_assert) + { + add_eq_assertion(gold_wire, gate_wire); + equiv_mod->connect(wire, gold_wire); + } + else + { + for (int i = 0; i < wire->width; i++) + equiv_mod->addEquiv(NEW_ID, SigSpec(gold_wire, i), SigSpec(gate_wire, i), SigSpec(wire, i)); + } + + rd_signal_map.add(assign_map(gold_wire), wire); + rd_signal_map.add(assign_map(gate_wire), wire); + } + else + if (gold_wire->port_input || gate_wire->port_input) + { + Wire *wire = equiv_mod->addWire(id, gold_wire->width); + wire->port_input = true; + gold_wire->port_input = false; + gate_wire->port_input = false; + equiv_mod->connect(gold_wire, wire); + equiv_mod->connect(gate_wire, wire); + primary_inputs.add(assign_map(gold_wire)); + primary_inputs.add(assign_map(gate_wire)); + primary_inputs.add(wire); + } + else + { + if (make_assert) + add_eq_assertion(gold_wire, gate_wire); + + else { + Wire *wire = equiv_mod->addWire(id, gold_wire->width); + SigSpec rdmap_gold, rdmap_gate, rdmap_equiv; + + for (int i = 0; i < wire->width; i++) { + if (undriven_bits.count(assign_map(SigBit(gold_wire, i)))) { + log(" Skipping signal bit %s [%d]: undriven on gold side.\n", id2cstr(gold_wire->name), i); + continue; + } + if (undriven_bits.count(assign_map(SigBit(gate_wire, i)))) { + log(" Skipping signal bit %s [%d]: undriven on gate side.\n", id2cstr(gate_wire->name), i); + continue; + } + equiv_mod->addEquiv(NEW_ID, SigSpec(gold_wire, i), SigSpec(gate_wire, i), SigSpec(wire, i)); + rdmap_gold.append(SigBit(gold_wire, i)); + rdmap_gate.append(SigBit(gate_wire, i)); + rdmap_equiv.append(SigBit(wire, i)); + } + + rd_signal_map.add(rdmap_gold, rdmap_equiv); + rd_signal_map.add(rdmap_gate, rdmap_equiv); + } + } + } + + for (auto c : cells_list) + for (auto &conn : c->connections()) + if (!ct.cell_output(c->type, conn.first)) { + SigSpec old_sig = assign_map(conn.second); + SigSpec new_sig = rd_signal_map(old_sig); + for (int i = 0; i < GetSize(old_sig); i++) + if (primary_inputs.check(old_sig[i])) + new_sig[i] = old_sig[i]; + if (old_sig != new_sig) { + log("Changing input %s of cell %s (%s): %s -> %s\n", + conn.first.unescape(), c, c->type.unescape(), + log_signal(old_sig), log_signal(new_sig)); + c->setPort(conn.first, new_sig); + } + } + + equiv_mod->fixup_ports(); + } + + void find_same_cells() + { + SigMap assign_map(equiv_mod); + + for (auto id : cell_names) + { + IdString gold_id = id.str() + "_gold"; + IdString gate_id = id.str() + "_gate"; + + Cell *gold_cell = equiv_mod->cell(gold_id); + Cell *gate_cell = equiv_mod->cell(gate_id); + + if (gold_cell == nullptr || gate_cell == nullptr || gold_cell->type != gate_cell->type || !ct.cell_known(gold_cell->type) || + gold_cell->parameters != gate_cell->parameters || GetSize(gold_cell->connections()) != GetSize(gate_cell->connections())) + try_next_cell_name: + continue; + + for (auto gold_conn : gold_cell->connections()) + if (!gate_cell->connections().count(gold_conn.first)) + goto try_next_cell_name; + + log("Presumably equivalent cells: %s %s (%s) -> %s\n", + gold_cell, gate_cell, gold_cell->type.unescape(), id.unescape()); + + for (auto gold_conn : gold_cell->connections()) + { + SigSpec gold_sig = assign_map(gold_conn.second); + SigSpec gate_sig = assign_map(gate_cell->getPort(gold_conn.first)); + + if (ct.cell_output(gold_cell->type, gold_conn.first)) { + equiv_mod->connect(gate_sig, gold_sig); + continue; + } + + if (make_assert) + { + if (gold_sig != gate_sig) + add_eq_assertion(gold_sig, gate_sig); + } + else + { + for (int i = 0; i < GetSize(gold_sig); i++) + if (gold_sig[i] != gate_sig[i]) { + Wire *w = equiv_mod->addWire(NEW_ID); + equiv_mod->addEquiv(NEW_ID, gold_sig[i], gate_sig[i], w); + gold_sig[i] = w; + } + } + + gold_cell->setPort(gold_conn.first, gold_sig); + } + + equiv_mod->remove(gate_cell); + equiv_mod->rename(gold_cell, id); + } + } + + void find_undriven_nets(bool mark) + { + undriven_bits.clear(); + assign_map.set(equiv_mod); + + for (auto wire : equiv_mod->wires()) { + for (auto bit : assign_map(wire)) + if (bit.wire) + undriven_bits.insert(bit); + } + + for (auto wire : equiv_mod->wires()) { + if (wire->port_input) + for (auto bit : assign_map(wire)) + undriven_bits.erase(bit); + } + + for (auto cell : equiv_mod->cells()) { + for (auto &conn : cell->connections()) + if (!ct.cell_known(cell->type) || ct.cell_output(cell->type, conn.first)) + for (auto bit : assign_map(conn.second)) + undriven_bits.erase(bit); + } + + if (mark) { + SigSpec undriven_sig(undriven_bits); + undriven_sig.sort_and_unify(); + + for (auto chunk : undriven_sig.chunks()) { + log("Setting undriven nets to undef: %s\n", log_signal(chunk)); + equiv_mod->connect(chunk, SigSpec(State::Sx, chunk.width)); + } + } + } + + void run() + { + copy_to_equiv(); + find_undriven_nets(false); + find_same_wires(); + find_same_cells(); + find_undriven_nets(true); + } +}; + +struct EquivMakePass : public Pass { + EquivMakePass() : Pass("equiv_make", "prepare a circuit for equivalence checking") { } + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" equiv_make [options] gold_module gate_module equiv_module\n"); + log("\n"); + log("This creates a module annotated with $equiv cells from two presumably\n"); + log("equivalent modules. Use commands such as 'equiv_simple' and 'equiv_status'\n"); + log("to work with the created equivalent checking module.\n"); + log("\n"); + log(" -inames\n"); + log(" Also match cells and wires with $... names.\n"); + log("\n"); + log(" -blacklist \n"); + log(" Do not match cells or signals that match the names in the file.\n"); + log("\n"); + log(" -encfile \n"); + log(" Match FSM encodings using the description from the file.\n"); + log(" See 'help fsm_recode' for details.\n"); + log("\n"); + log(" -make_assert\n"); + log(" Check equivalence with $assert cells instead of $equiv.\n"); + log(" $eqx (===) is used to compare signals."); + log("\n"); + log("Note: The circuit created by this command is not a miter (with something like\n"); + log("a trigger output), but instead uses $equiv cells to encode the equivalence\n"); + log("checking problem. Use 'miter -equiv' if you want to create a miter circuit.\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) override + { + EquivMakeWorker worker; + worker.ct.setup(design); + worker.inames = false; + worker.make_assert = false; + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + if (args[argidx] == "-inames") { + worker.inames = true; + continue; + } + if (args[argidx] == "-blacklist" && argidx+1 < args.size()) { + worker.blacklists.push_back(args[++argidx]); + continue; + } + if (args[argidx] == "-encfile" && argidx+1 < args.size()) { + worker.encfiles.push_back(args[++argidx]); + continue; + } + if (args[argidx] == "-make_assert") { + worker.make_assert = true; + continue; + } + break; + } + + if (argidx+3 != args.size()) + log_cmd_error("Invalid number of arguments.\n"); + + worker.gold_mod = design->module(RTLIL::escape_id(args[argidx])); + worker.gate_mod = design->module(RTLIL::escape_id(args[argidx+1])); + worker.equiv_mod = design->module(RTLIL::escape_id(args[argidx+2])); + + if (worker.gold_mod == nullptr) + log_cmd_error("Can't find gold module %s.\n", args[argidx]); + + if (worker.gate_mod == nullptr) + log_cmd_error("Can't find gate module %s.\n", args[argidx+1]); + + if (worker.equiv_mod != nullptr) + log_cmd_error("Equiv module %s already exists.\n", args[argidx+2]); + + if (worker.gold_mod->has_memories() || worker.gold_mod->has_processes()) + log_cmd_error("Gold module contains memories or processes. Run 'memory' or 'proc' respectively.\n"); + + if (worker.gate_mod->has_memories() || worker.gate_mod->has_processes()) + log_cmd_error("Gate module contains memories or processes. Run 'memory' or 'proc' respectively.\n"); + + worker.read_blacklists(); + worker.read_encfiles(); + + log_header(design, "Executing EQUIV_MAKE pass (creating equiv checking module).\n"); + + worker.equiv_mod = design->addModule(RTLIL::escape_id(args[argidx+2])); + worker.run(); + } +} EquivMakePass; + +PRIVATE_NAMESPACE_END diff --git a/passes/fsm/fsm_recode.cc b/passes/fsm/fsm_recode.cc index b32c01c39..aa96ec6de 100644 --- a/passes/fsm/fsm_recode.cc +++ b/passes/fsm/fsm_recode.cc @@ -39,7 +39,7 @@ static void fm_set_fsm_print(RTLIL::Cell *cell, RTLIL::Module *module, FsmData & for (int i = fsm_data.state_bits-1; i >= 0; i--) fprintf(f, " %s_reg[%d]", name[0] == '\\' ? name.substr(1).c_str() : name.c_str(), i); fprintf(f, " } -name {%s_%s} {%s:/WORK/%s}\n", prefix, RTLIL::unescape_id(name).c_str(), - prefix, RTLIL::unescape_id(module->name).c_str()); + prefix, module->name.unescape().c_str()); fprintf(f, "set_fsm_encoding {"); for (int i = 0; i < GetSize(fsm_data.state_table); i++) { @@ -49,7 +49,7 @@ static void fm_set_fsm_print(RTLIL::Cell *cell, RTLIL::Module *module, FsmData & } fprintf(f, " } -name {%s_%s} {%s:/WORK/%s}\n", prefix, RTLIL::unescape_id(name).c_str(), - prefix, RTLIL::unescape_id(module->name).c_str()); + prefix, module->name.unescape().c_str()); } static void fsm_recode(RTLIL::Cell *cell, RTLIL::Module *module, FILE *fm_set_fsm_file, FILE *encfile, std::string default_encoding) diff --git a/passes/hierarchy/flatten.cc b/passes/hierarchy/flatten.cc index 2dd20302c..29e7205ee 100644 --- a/passes/hierarchy/flatten.cc +++ b/passes/hierarchy/flatten.cc @@ -281,13 +281,13 @@ struct FlattenWorker if (attr.first == ID::hdlname) scopeinfo->attributes.insert(attr); else - scopeinfo->attributes.emplace(stringf("\\cell_%s", RTLIL::unescape_id(attr.first)), attr.second); + scopeinfo->attributes.emplace(stringf("\\cell_%s", attr.first.unescape()), attr.second); } for (auto const &attr : tpl->attributes) - scopeinfo->attributes.emplace(stringf("\\module_%s", RTLIL::unescape_id(attr.first)), attr.second); + scopeinfo->attributes.emplace(stringf("\\module_%s", attr.first.unescape()), attr.second); - scopeinfo->attributes.emplace(ID(module), RTLIL::unescape_id(tpl->name)); + scopeinfo->attributes.emplace(ID(module), tpl->name.unescape()); } module->remove(cell); diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index f41c19672..4580f14be 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -50,7 +50,7 @@ void generate(RTLIL::Design *design, const std::vector &celltypes, if (cell->type.begins_with("$") && !cell->type.begins_with("$__")) continue; for (auto &pattern : celltypes) - if (patmatch(pattern.c_str(), RTLIL::unescape_id(cell->type).c_str())) + if (patmatch(pattern.c_str(), cell->type.unescape().c_str())) found_celltypes.insert(cell->type); } @@ -100,7 +100,7 @@ void generate(RTLIL::Design *design, const std::vector &celltypes, while (portnames.size() > 0) { RTLIL::IdString portname = *portnames.begin(); for (auto &decl : portdecls) - if (decl.index == 0 && patmatch(decl.portname.c_str(), RTLIL::unescape_id(portname).c_str())) { + if (decl.index == 0 && patmatch(decl.portname.c_str(), portname.unescape().c_str())) { generate_port_decl_t d = decl; d.portname = portname.str(); d.index = *indices.begin(); @@ -397,7 +397,7 @@ RTLIL::Module *get_module(RTLIL::Design &design, }; for (auto &ext : extensions_list) { - std::string filename = dir + "/" + RTLIL::unescape_id(cell.type) + ext.first; + std::string filename = dir + "/" + cell.type.unescape() + ext.first; if (!check_file_exists(filename)) continue; diff --git a/passes/sat/cutpoint.cc b/passes/sat/cutpoint.cc index 6c4023a6a..2680252a7 100644 --- a/passes/sat/cutpoint.cc +++ b/passes/sat/cutpoint.cc @@ -159,7 +159,7 @@ struct CutpointPass : public Pass { if (attr.first == ID::hdlname) scopeinfo->attributes.insert(attr); else - scopeinfo->attributes.emplace(stringf("\\cell_%s", RTLIL::unescape_id(attr.first)), attr.second); + scopeinfo->attributes.emplace(stringf("\\cell_%s", attr.first.unescape()), attr.second); } } diff --git a/passes/sat/expose.cc b/passes/sat/expose.cc index b5f2a437c..e84bd9e89 100644 --- a/passes/sat/expose.cc +++ b/passes/sat/expose.cc @@ -632,7 +632,7 @@ struct ExposePass : public Pass { if (!p->port_input && !p->port_output) continue; - RTLIL::Wire *w = add_new_wire(module, cell->name.str() + sep + RTLIL::unescape_id(p->name), p->width); + RTLIL::Wire *w = add_new_wire(module, cell->name.str() + sep + p->name.unescape(), p->width); if (p->port_input) w->port_output = true; if (p->port_output) @@ -654,7 +654,7 @@ struct ExposePass : public Pass { { for (auto &it : cell->connections()) { - RTLIL::Wire *w = add_new_wire(module, cell->name.str() + sep + RTLIL::unescape_id(it.first), it.second.size()); + RTLIL::Wire *w = add_new_wire(module, cell->name.str() + sep + it.first.unescape(), it.second.size()); if (ct.cell_input(cell->type, it.first)) w->port_output = true; if (ct.cell_output(cell->type, it.first)) diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index 9df88b304..5dd1b07b4 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -143,7 +143,7 @@ void create_miter_equiv(struct Pass *that, std::vector args, RTLIL: { if (gold_cross_ports.count(gold_wire)) { - SigSpec w = miter_module->addWire("\\cross_" + RTLIL::unescape_id(gold_wire->name), gold_wire->width); + SigSpec w = miter_module->addWire("\\cross_" + gold_wire->name.unescape(), gold_wire->width); gold_cell->setPort(gold_wire->name, w); if (flag_ignore_gold_x) { RTLIL::SigSpec w_x = miter_module->addWire(NEW_ID, GetSize(w)); @@ -159,7 +159,7 @@ void create_miter_equiv(struct Pass *that, std::vector args, RTLIL: if (gold_wire->port_input) { - RTLIL::Wire *w = miter_module->addWire("\\in_" + RTLIL::unescape_id(gold_wire->name), gold_wire->width); + RTLIL::Wire *w = miter_module->addWire("\\in_" + gold_wire->name.unescape(), gold_wire->width); w->port_input = true; gold_cell->setPort(gold_wire->name, w); @@ -168,10 +168,10 @@ void create_miter_equiv(struct Pass *that, std::vector args, RTLIL: if (gold_wire->port_output) { - RTLIL::Wire *w_gold = miter_module->addWire("\\gold_" + RTLIL::unescape_id(gold_wire->name), gold_wire->width); + RTLIL::Wire *w_gold = miter_module->addWire("\\gold_" + gold_wire->name.unescape(), gold_wire->width); w_gold->port_output = flag_make_outputs; - RTLIL::Wire *w_gate = miter_module->addWire("\\gate_" + RTLIL::unescape_id(gold_wire->name), gold_wire->width); + RTLIL::Wire *w_gate = miter_module->addWire("\\gate_" + gold_wire->name.unescape(), gold_wire->width); w_gate->port_output = flag_make_outputs; gold_cell->setPort(gold_wire->name, w_gold); @@ -244,7 +244,7 @@ void create_miter_equiv(struct Pass *that, std::vector args, RTLIL: if (flag_make_outcmp) { - RTLIL::Wire *w_cmp = miter_module->addWire("\\cmp_" + RTLIL::unescape_id(gold_wire->name)); + RTLIL::Wire *w_cmp = miter_module->addWire("\\cmp_" + gold_wire->name.unescape()); w_cmp->port_output = true; miter_module->connect(RTLIL::SigSig(w_cmp, this_condition)); } @@ -252,7 +252,7 @@ void create_miter_equiv(struct Pass *that, std::vector args, RTLIL: if (flag_make_cover) { auto cover_condition = miter_module->Not(NEW_ID, this_condition); - miter_module->addCover("\\cover_" + RTLIL::unescape_id(gold_wire->name), cover_condition, State::S1); + miter_module->addCover("\\cover_" + gold_wire->name.unescape(), cover_condition, State::S1); } all_conditions.append(this_condition); diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 23af70fa5..3de13cc1a 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -275,9 +275,9 @@ struct SimInstance } if ((shared->fst) && !(shared->hide_internal && wire->name[0] == '$')) { - fstHandle id = shared->fst->getHandle(scope + "." + RTLIL::unescape_id(wire->name)); + fstHandle id = shared->fst->getHandle(scope + "." + wire->name.unescape()); if (id==0 && wire->name.isPublic()) - log_warning("Unable to find wire %s in input file.\n", (scope + "." + RTLIL::unescape_id(wire->name))); + log_warning("Unable to find wire %s in input file.\n", (scope + "." + wire->name.unescape())); fst_handles[wire] = id; } @@ -316,7 +316,7 @@ struct SimInstance Module *mod = module->design->module(cell->type); if (mod != nullptr) { - dirty_children.insert(new SimInstance(shared, scope + "." + RTLIL::unescape_id(cell->name), mod, cell, this)); + dirty_children.insert(new SimInstance(shared, scope + "." + cell->name.unescape(), mod, cell, this)); } for (auto &port : cell->connections()) { @@ -1209,7 +1209,7 @@ struct SimInstance } } if (!found) - log_error("Unable to find required '%s' signal in file\n",(scope + "." + RTLIL::unescape_id(sig_y.as_wire()->name))); + log_error("Unable to find required '%s' signal in file\n",(scope + "." + sig_y.as_wire()->name.unescape())); } } } @@ -1495,7 +1495,7 @@ struct SimWorker : SimShared log_error("Can't find port %s on module %s.\n", portname.unescape(), top->module); if (!w->port_input) log_error("Clock port %s on module %s is not input.\n", portname.unescape(), top->module); - fstHandle id = fst->getHandle(scope + "." + RTLIL::unescape_id(portname)); + fstHandle id = fst->getHandle(scope + "." + portname.unescape()); if (id==0) log_error("Can't find port %s.%s in FST.\n", scope, portname.unescape()); fst_clock.push_back(id); @@ -1507,7 +1507,7 @@ struct SimWorker : SimShared log_error("Can't find port %s on module %s.\n", portname.unescape(), top->module); if (!w->port_input) log_error("Clock port %s on module %s is not input.\n", portname.unescape(), top->module); - fstHandle id = fst->getHandle(scope + "." + RTLIL::unescape_id(portname)); + fstHandle id = fst->getHandle(scope + "." + portname.unescape()); if (id==0) log_error("Can't find port %s.%s in FST.\n", scope, portname.unescape()); fst_clock.push_back(id); @@ -1517,9 +1517,9 @@ struct SimWorker : SimShared for (auto wire : topmod->wires()) { if (wire->port_input) { - fstHandle id = fst->getHandle(scope + "." + RTLIL::unescape_id(wire->name)); + fstHandle id = fst->getHandle(scope + "." + wire->name.unescape()); if (id==0) - log_error("Unable to find required '%s' signal in file\n",(scope + "." + RTLIL::unescape_id(wire->name))); + log_error("Unable to find required '%s' signal in file\n",(scope + "." + wire->name.unescape())); top->fst_inputs[wire] = id; } } @@ -2114,12 +2114,12 @@ struct SimWorker : SimShared std::stringstream f; if (wire->width==1) - f << stringf("%s", RTLIL::unescape_id(wire->name)); + f << stringf("%s", wire); else if (wire->upto) - f << stringf("[%d:%d] %s", wire->start_offset, wire->width - 1 + wire->start_offset, RTLIL::unescape_id(wire->name)); + f << stringf("[%d:%d] %s", wire->start_offset, wire->width - 1 + wire->start_offset, wire); else - f << stringf("[%d:%d] %s", wire->width - 1 + wire->start_offset, wire->start_offset, RTLIL::unescape_id(wire->name)); + f << stringf("[%d:%d] %s", wire->width - 1 + wire->start_offset, wire->start_offset, wire); return f.str(); } @@ -2127,7 +2127,7 @@ struct SimWorker : SimShared { std::stringstream f; for(auto item=signals.begin();item!=signals.end();item++) - f << stringf("%c%s", (item==signals.begin() ? ' ' : ','), RTLIL::unescape_id(item->first->name)); + f << stringf("%c%s", (item==signals.begin() ? ' ' : ','), item->first); return f.str(); } @@ -2151,7 +2151,7 @@ struct SimWorker : SimShared log_error("Can't find port %s on module %s.\n", portname.unescape(), top->module); if (!w->port_input) log_error("Clock port %s on module %s is not input.\n", portname.unescape(), top->module); - fstHandle id = fst->getHandle(scope + "." + RTLIL::unescape_id(portname)); + fstHandle id = fst->getHandle(scope + "." + portname.unescape()); if (id==0) log_error("Can't find port %s.%s in FST.\n", scope, portname.unescape()); fst_clock.push_back(id); @@ -2164,7 +2164,7 @@ struct SimWorker : SimShared log_error("Can't find port %s on module %s.\n", portname.unescape(), top->module); if (!w->port_input) log_error("Clock port %s on module %s is not input.\n", portname.unescape(), top->module); - fstHandle id = fst->getHandle(scope + "." + RTLIL::unescape_id(portname)); + fstHandle id = fst->getHandle(scope + "." + portname.unescape()); if (id==0) log_error("Can't find port %s.%s in FST.\n", scope, portname.unescape()); fst_clock.push_back(id); @@ -2176,9 +2176,9 @@ struct SimWorker : SimShared std::map outputs; for (auto wire : topmod->wires()) { - fstHandle id = fst->getHandle(scope + "." + RTLIL::unescape_id(wire->name)); + fstHandle id = fst->getHandle(scope + "." + wire->name.unescape()); if (id==0 && (wire->port_input || wire->port_output)) - log_error("Unable to find required '%s' signal in file\n",(scope + "." + RTLIL::unescape_id(wire->name))); + log_error("Unable to find required '%s' signal in file\n",(scope + "." + wire->name.unescape())); if (wire->port_input) if (clocks.find(wire)==clocks.end()) inputs[wire] = id; @@ -2244,13 +2244,13 @@ struct SimWorker : SimShared } int data_len = clk_len + inputs_len + outputs_len + 32; f << "\n"; - f << stringf("\t%s uut(",RTLIL::unescape_id(topmod->name)); + f << stringf("\t%s uut(",topmod); for(auto item=clocks.begin();item!=clocks.end();item++) - f << stringf("%c.%s(%s)", (item==clocks.begin() ? ' ' : ','), RTLIL::unescape_id(item->first->name), RTLIL::unescape_id(item->first->name)); + f << stringf("%c.%s(%s)", (item==clocks.begin() ? ' ' : ','), item->first, item->first); for(auto &item : inputs) - f << stringf(",.%s(%s)", RTLIL::unescape_id(item.first->name), RTLIL::unescape_id(item.first->name)); + f << stringf(",.%s(%s)", item.first, item.first); for(auto &item : outputs) - f << stringf(",.%s(%s)", RTLIL::unescape_id(item.first->name), RTLIL::unescape_id(item.first->name)); + f << stringf(",.%s(%s)", item.first, item.first); f << ");\n"; f << "\n"; f << "\tinteger i;\n"; diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index 7742fa989..5e804922c 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -1565,7 +1565,7 @@ void AbcModuleState::extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL { if (builtin_lib) { - cell_stats[RTLIL::unescape_id(c->type)]++; + cell_stats[c->type.unescape()]++; if (c->type.in(ID(ZERO), ID(ONE))) { RTLIL::SigSig conn; RTLIL::IdString name_y = remap_name(c->getPort(ID::Y).as_wire()->name); @@ -1706,7 +1706,7 @@ void AbcModuleState::extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL } } else - cell_stats[RTLIL::unescape_id(c->type)]++; + cell_stats[c->type.unescape()]++; if (c->type.in(ID(_const0_), ID(_const1_))) { RTLIL::SigSig conn; diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index d4d13d673..f63123a23 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -626,7 +626,7 @@ struct ExtractPass : public Pass { if (!mine_mode) for (auto module : map->modules()) { SubCircuit::Graph mod_graph; - std::string graph_name = "needle_" + RTLIL::unescape_id(module->name); + std::string graph_name = "needle_" + module->name.unescape(); log("Creating needle graph %s.\n", graph_name); if (module2graph(mod_graph, module, constports)) { solver.addGraph(graph_name, mod_graph); @@ -637,7 +637,7 @@ struct ExtractPass : public Pass { for (auto module : design->modules()) { SubCircuit::Graph mod_graph; - std::string graph_name = "haystack_" + RTLIL::unescape_id(module->name); + std::string graph_name = "haystack_" + module->name.unescape(); log("Creating haystack graph %s.\n", graph_name); if (module2graph(mod_graph, module, constports, design, mine_mode ? mine_max_fanout : -1, mine_mode ? &mine_split : nullptr)) { solver.addGraph(graph_name, mod_graph); @@ -654,8 +654,8 @@ struct ExtractPass : public Pass { for (auto needle : needle_list) for (auto &haystack_it : haystack_map) { - log("Solving for %s in %s.\n", ("needle_" + RTLIL::unescape_id(needle->name)), haystack_it.first); - solver.solve(results, "needle_" + RTLIL::unescape_id(needle->name), haystack_it.first, false); + log("Solving for %s in %s.\n", ("needle_" + needle->name.unescape()), haystack_it.first); + solver.solve(results, "needle_" + needle->name.unescape(), haystack_it.first, false); } log("Found %d matches.\n", GetSize(results)); diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index e975d2fd2..984926be8 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -616,9 +616,9 @@ struct TechmapWorker } if (tpl->avail_parameters.count(ID::_TECHMAP_CELLTYPE_) != 0) - parameters.emplace(ID::_TECHMAP_CELLTYPE_, RTLIL::unescape_id(cell->type)); + parameters.emplace(ID::_TECHMAP_CELLTYPE_, cell->type.unescape()); if (tpl->avail_parameters.count(ID::_TECHMAP_CELLNAME_) != 0) - parameters.emplace(ID::_TECHMAP_CELLNAME_, RTLIL::unescape_id(cell->name)); + parameters.emplace(ID::_TECHMAP_CELLNAME_, cell->name.unescape()); for (auto &conn : cell->connections()) { if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONSTMSK_%s_", conn.first.unescape())) != 0) { diff --git a/techlibs/common/opensta.cc b/techlibs/common/opensta.cc index 655fdbf2d..6061f6b74 100644 --- a/techlibs/common/opensta.cc +++ b/techlibs/common/opensta.cc @@ -98,7 +98,7 @@ struct OpenstaPass : public Pass f_script << "read_verilog " << verilog_filename << "\n"; f_script << "read_lib " << liberty_filename << "\n"; - f_script << "link_design " << RTLIL::unescape_id(top_mod->name) << "\n"; + f_script << "link_design " << top_mod->name.unescape() << "\n"; f_script << "read_sdc " << sdc_filename << "\n"; f_script << "write_sdc " << sdc_expanded_filename << "\n"; f_script.close(); From caba96515e8eb5df67cbf88529c3f938c5f113e5 Mon Sep 17 00:00:00 2001 From: Yuheng Su Date: Sun, 17 May 2026 02:27:55 +0000 Subject: [PATCH 044/354] smt2: use canonical SMT names in memory metadata --- backends/smt2/smt2.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc index a9030e18a..66ae4d51c 100644 --- a/backends/smt2/smt2.cc +++ b/backends/smt2/smt2.cc @@ -788,7 +788,7 @@ struct Smt2Worker if (has_async_wr && has_sync_wr) log_error("Memory %s.%s has mixed clocked/nonclocked write ports. This is not supported by \"write_smt2\".\n", cell, module); - decls.push_back(stringf("; yosys-smt2-memory %s %d %d %d %d %s\n", mem->memid.unescape(), abits, mem->width, GetSize(mem->rd_ports), GetSize(mem->wr_ports), has_async_wr ? "async" : "sync")); + decls.push_back(stringf("; yosys-smt2-memory %s %d %d %d %d %s\n", get_id(mem->memid), abits, mem->width, GetSize(mem->rd_ports), GetSize(mem->wr_ports), has_async_wr ? "async" : "sync")); decls.push_back(witness_memory(get_id(mem->memid), cell, mem)); string memstate; From ef092e1f15a205d027cd0e03279ec580c8071a33 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 18 May 2026 08:50:20 +0200 Subject: [PATCH 045/354] Include conf so individual test running works --- tests/gen_tests_makefile.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/gen_tests_makefile.py b/tests/gen_tests_makefile.py index 38596f63b..e4e44241c 100644 --- a/tests/gen_tests_makefile.py +++ b/tests/gen_tests_makefile.py @@ -94,6 +94,9 @@ def generate_tests(argv, cmds): def print_header(extra=None): print(f"include {common_mk}") + print(f"ifneq ($(wildcard {yosys_basedir}/Makefile.conf),)") + print(f"include {yosys_basedir}/Makefile.conf") + print(f"endif") print(f"YOSYS ?= {yosys_basedir}/yosys") print("") print("export YOSYS_MAX_THREADS := 4") From 4a4c3a3be616098a34ae4079b24e501dcfbb7130 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 18 May 2026 08:50:38 +0200 Subject: [PATCH 046/354] Make better validation --- tests/memories/generate_mk.py | 48 +------------- tests/memories/validate.py | 116 ++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+), 47 deletions(-) create mode 100644 tests/memories/validate.py diff --git a/tests/memories/generate_mk.py b/tests/memories/generate_mk.py index cfb29acb9..93a5bec04 100644 --- a/tests/memories/generate_mk.py +++ b/tests/memories/generate_mk.py @@ -8,51 +8,5 @@ import gen_tests_makefile gen_tests_makefile.generate_autotest("*.v", "", """if grep -Eq 'expect-(wr-ports|rd-ports|rd-clk)' $@; then \\ $(YOSYS) -f verilog -qp "proc; opt; memory -nomap; dump -outfile $(@:.v=).dmp t:\\$$mem_v2" $@; \\ - if grep -q expect-wr-ports $@; then \\ - val=$$(gawk '/expect-wr-ports/ { print $$3; }' $@); \\ - grep -Fq "parameter \\\\WR_PORTS $$val" $(@:.v=).dmp || { echo " ERROR: Unexpected number of write ports."; exit 1; }; \\ - fi; \\ - if grep -q expect-wr-wide-continuation $@; then \\ - val=$$(gawk '/expect-wr-wide-continuation/ { print $$3; }' $@); \\ - grep -Fq "parameter \\\\WR_WIDE_CONTINUATION $$val" $(@:.v=).dmp || { echo " ERROR: Unexpected write wide continuation."; exit 1; }; \\ - fi; \\ - if grep -q expect-rd-ports $@; then \\ - val=$$(gawk '/expect-rd-ports/ { print $$3; }' $@); \\ - grep -Fq "parameter \\\\RD_PORTS $$val" $(@:.v=).dmp || { echo " ERROR: Unexpected number of read ports."; exit 1; }; \\ - fi; \\ - if grep -q expect-rd-clk $@; then \\ - val=$$(gawk '/expect-rd-clk/ { print $$3; }' $@); \\ - grep -Fq "connect \\\\RD_CLK $$val" $(@:.v=).dmp || { echo " ERROR: Unexpected read clock."; exit 1; }; \\ - fi; \\ - if grep -q expect-rd-en $@; then \\ - val=$$(gawk '/expect-rd-en/ { print $$3; }' $@); \\ - grep -Fq "connect \\\\RD_EN $$val" $(@:.v=).dmp || { echo " ERROR: Unexpected read enable."; exit 1; }; \\ - fi; \\ - if grep -q expect-rd-srst-sig $@; then \\ - val=$$(gawk '/expect-rd-srst-sig/ { print $$3; }' $@); \\ - grep -Fq "connect \\\\RD_SRST $$val" $(@:.v=).dmp || { echo " ERROR: Unexpected read sync reset."; exit 1; }; \\ - fi; \\ - if grep -q expect-rd-srst-val $@; then \\ - val=$$(gawk '/expect-rd-srst-val/ { print $$3; }' $@); \\ - grep -Fq "parameter \\\\RD_SRST_VALUE $$val" $(@:.v=).dmp || { echo " ERROR: Unexpected read sync reset value."; exit 1; }; \\ - fi; \\ - if grep -q expect-rd-arst-sig $@; then \\ - val=$$(gawk '/expect-rd-arst-sig/ { print $$3; }' $@); \\ - grep -Fq "connect \\\\RD_ARST $$val" $(@:.v=).dmp || { echo " ERROR: Unexpected read async reset."; exit 1; }; \\ - fi; \\ - if grep -q expect-rd-arst-val $@; then \\ - val=$$(gawk '/expect-rd-arst-val/ { print $$3; }' $@); \\ - grep -Fq "parameter \\\\RD_ARST_VALUE $$val" $(@:.v=).dmp || { echo " ERROR: Unexpected read async reset value."; exit 1; }; \\ - fi; \\ - if grep -q expect-rd-init-val $@; then \\ - val=$$(gawk '/expect-rd-init-val/ { print $$3; }' $@); \\ - grep -Fq "parameter \\\\RD_INIT_VALUE $$val" $(@:.v=).dmp || { echo " ERROR: Unexpected read init value."; exit 1; }; \\ - fi; \\ - if grep -q expect-rd-wide-continuation $@; then \\ - val=$$(gawk '/expect-rd-wide-continuation/ { print $$3; }' $@); \\ - grep -Fq "parameter \\\\RD_WIDE_CONTINUATION $$val" $(@:.v=).dmp || { echo " ERROR: Unexpected read wide continuation."; exit 1; }; \\ - fi; \\ - if grep -q expect-no-rd-clk $@; then \\ - grep -Fq "connect \\\\RD_CLK 1'x" $(@:.v=).dmp || { echo " ERROR: Expected no read clock."; exit 1; }; \\ - fi; \\ + python3 validate.py $@ $(@:.v=).dmp; \\ fi""") diff --git a/tests/memories/validate.py b/tests/memories/validate.py new file mode 100644 index 000000000..88aabdd49 --- /dev/null +++ b/tests/memories/validate.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python3 +import re +import sys +from pathlib import Path + +CHECKS = [ + ( + "expect-wr-ports", + r"parameter \\WR_PORTS {val}$", + "ERROR: Unexpected number of write ports.", + ), + ( + "expect-wr-wide-continuation", + r"parameter \\WR_WIDE_CONTINUATION {val}$", + "ERROR: Unexpected write wide continuation.", + ), + ( + "expect-rd-ports", + r"parameter \\RD_PORTS {val}$", + "ERROR: Unexpected number of read ports.", + ), + ( + "expect-rd-clk", + r"connect \\RD_CLK {val}$", + "ERROR: Unexpected read clock.", + ), + ( + "expect-rd-en", + r"connect \\RD_EN {val}$", + "ERROR: Unexpected read enable.", + ), + ( + "expect-rd-srst-sig", + r"connect \\RD_SRST {val}$", + "ERROR: Unexpected read sync reset.", + ), + ( + "expect-rd-srst-val", + r"parameter \\RD_SRST_VALUE {val}$", + "ERROR: Unexpected read sync reset value.", + ), + ( + "expect-rd-arst-sig", + r"connect \\RD_ARST {val}$", + "ERROR: Unexpected read async reset.", + ), + ( + "expect-rd-arst-val", + r"parameter \\RD_ARST_VALUE {val}$", + "ERROR: Unexpected read async reset value.", + ), + ( + "expect-rd-init-val", + r"parameter \\RD_INIT_VALUE {val}$", + "ERROR: Unexpected read init value.", + ), + ( + "expect-rd-wide-continuation", + r"parameter \\RD_WIDE_CONTINUATION {val}$", + "ERROR: Unexpected read wide continuation.", + ), + ( + "expect-no-rd-clk", + r"connect \\RD_CLK 1'x$", + "ERROR: Expected no read clock.", + ), +] + + +def extract_expect_value(src_text: str, key: str): + pattern = rf"{re.escape(key)}\s+(\S+)" + m = re.search(pattern, src_text) + return m.group(1) if m else None + + +def main(): + if len(sys.argv) != 3: + print(f"Usage: {sys.argv[0]} ", file=sys.stderr) + return 2 + + srcfile = Path(sys.argv[1]) + dmpfile = Path(sys.argv[2]) + + try: + src_text = srcfile.read_text() + except Exception as e: + print(f"ERROR: Failed to read {srcfile}: {e}", file=sys.stderr) + return 2 + + try: + dmp_text = dmpfile.read_text() + except Exception as e: + print(f"ERROR: Failed to read {dmpfile}: {e}", file=sys.stderr) + return 2 + + for key, pattern_template, errmsg in CHECKS: + if "{val}" in pattern_template: + val = extract_expect_value(src_text, key) + if val is None: + continue + pattern = pattern_template.format(val=re.escape(val)) + else: + if key not in src_text: + continue + pattern = pattern_template + + if not re.search(pattern, dmp_text, re.MULTILINE): + print(errmsg, file=sys.stderr) + return 1 + + print("ok.") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) From 35d13e1c3268884791b47ee6f567775ec669ae14 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 18 May 2026 09:13:46 +0200 Subject: [PATCH 047/354] Update documentation/demos based on cleanup --- docs/source/code_examples/functional/dummy.cc | 14 +++++++------- .../yosys_internals/extending_yosys/extensions.rst | 3 +-- .../extending_yosys/functional_ir.rst | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/docs/source/code_examples/functional/dummy.cc b/docs/source/code_examples/functional/dummy.cc index 42b05b339..a339bc275 100644 --- a/docs/source/code_examples/functional/dummy.cc +++ b/docs/source/code_examples/functional/dummy.cc @@ -24,19 +24,19 @@ struct FunctionalDummyBackend : public Backend { // write node functions for (auto node : ir) - *f << " assign " << id2cstr(node.name()) + *f << " assign " << node.name().unescape() << " = " << node.to_string() << "\n"; *f << "\n"; // write outputs and next state for (auto output : ir.outputs()) - *f << " " << id2cstr(output->kind) - << " " << id2cstr(output->name) - << " = " << id2cstr(output->value().name()) << "\n"; + *f << " " << output->kind.unescape() + << " " << output->name.unescape() + << " = " << output->value().name().unescape() << "\n"; for (auto state : ir.states()) - *f << " " << id2cstr(state->kind) - << " " << id2cstr(state->name) - << " = " << id2cstr(state->next_value().name()) << "\n"; + *f << " " << state->kind.unescape() + << " " << state->name.unescape() + << " = " << state->next_value().name().unescape() << "\n"; } } } FunctionalDummyBackend; diff --git a/docs/source/yosys_internals/extending_yosys/extensions.rst b/docs/source/yosys_internals/extending_yosys/extensions.rst index 74a7d72d6..949c78586 100644 --- a/docs/source/yosys_internals/extending_yosys/extensions.rst +++ b/docs/source/yosys_internals/extending_yosys/extensions.rst @@ -230,8 +230,7 @@ Use ``log_error()`` to report a non-recoverable error: .. code:: C++ if (design->modules.count(module->name) != 0) - log_error("A module with the name %s already exists!\n", - RTLIL::id2cstr(module->name)); + log_error("A module with the name %s already exists!\n", module); Use ``log_cmd_error()`` to report a recoverable error: diff --git a/docs/source/yosys_internals/extending_yosys/functional_ir.rst b/docs/source/yosys_internals/extending_yosys/functional_ir.rst index 4f363623e..1c4ab5281 100644 --- a/docs/source/yosys_internals/extending_yosys/functional_ir.rst +++ b/docs/source/yosys_internals/extending_yosys/functional_ir.rst @@ -181,7 +181,7 @@ pointer ``f`` to the output file, or stdout if none is given. For this minimal example all we are doing is printing out each node. The ``node.name()`` method returns an ``RTLIL::IdString``, which we convert for -printing with ``id2cstr()``. Then, to print the function of the node, we use +printing with ``unescape()``. Then, to print the function of the node, we use ``node.to_string()`` which gives us a string of the form ``function(args)``. The ``function`` part is the result of ``Functional::IR::fn_to_string(node.fn())``; while ``args`` is the zero or more arguments passed to the function, most From d322e2fbe0369fe58163c5e336469c142b9632e5 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Tue, 12 May 2026 11:43:32 +0200 Subject: [PATCH 048/354] threading: redirect locks to no-op when ENABLE_THREADS=0 or undefined YOSYS_ENABLE_THREADS --- kernel/threading.cc | 14 +++--- kernel/threading.h | 105 +++++++++++++++++++++++--------------------- 2 files changed, 60 insertions(+), 59 deletions(-) diff --git a/kernel/threading.cc b/kernel/threading.cc index eda6bb4cb..a49ee7d4e 100644 --- a/kernel/threading.cc +++ b/kernel/threading.cc @@ -70,7 +70,7 @@ ThreadPool::ThreadPool(int pool_size, std::function b) for (int i = 0; i < pool_size; i++) threads.emplace_back([i, this]{ body(i); }); #else - log_assert(pool_size == 0); + (void)pool_size; #endif } @@ -96,11 +96,13 @@ IntRange item_range_for_worker(int num_items, int thread_num, int num_threads) } ParallelDispatchThreadPool::ParallelDispatchThreadPool(int pool_size) - : num_worker_threads_(std::max(1, pool_size) - 1) -{ #ifdef YOSYS_ENABLE_THREADS - main_to_workers_signal.resize(num_worker_threads_, 0); + : num_worker_threads_(std::max(1, pool_size) - 1) +#else + : num_worker_threads_(0) #endif +{ + main_to_workers_signal.resize(num_worker_threads_, 0); // Don't start the threads until we've constructed all our data members. thread_pool = std::make_unique(num_worker_threads_, [this](int thread_num){ run_worker(thread_num); @@ -109,14 +111,12 @@ ParallelDispatchThreadPool::ParallelDispatchThreadPool(int pool_size) ParallelDispatchThreadPool::~ParallelDispatchThreadPool() { -#ifdef YOSYS_ENABLE_THREADS if (num_worker_threads_ == 0) return; current_work = nullptr; num_active_worker_threads_.store(num_worker_threads_, std::memory_order_relaxed); signal_workers_start(); wait_for_workers_done(); -#endif } void ParallelDispatchThreadPool::run(std::function work, int max_threads) @@ -127,13 +127,11 @@ void ParallelDispatchThreadPool::run(std::function work, i work({{0}, 1}); return; } -#ifdef YOSYS_ENABLE_THREADS num_active_worker_threads_.store(num_active_worker_threads, std::memory_order_relaxed); current_work = &work; signal_workers_start(); work({{0}, num_active_worker_threads + 1}); wait_for_workers_done(); -#endif } void ParallelDispatchThreadPool::run_worker(int thread_num) diff --git a/kernel/threading.h b/kernel/threading.h index 3a31b0633..98d3068c4 100644 --- a/kernel/threading.h +++ b/kernel/threading.h @@ -15,6 +15,33 @@ YOSYS_NAMESPACE_BEGIN +// Redirect to no-op to avoid dependence on +// and in single-threaded builds +#ifdef YOSYS_ENABLE_THREADS +using Mutex = std::mutex; +using CondVar = std::condition_variable; +template using UniqueLock = std::unique_lock; +template using LockGuard = std::lock_guard; +#else +struct Mutex { + void lock() {} + void unlock() {} + bool try_lock() { return true; } +}; +struct CondVar { + template void wait(L &) {} + template void wait(L &, P) {} + void notify_one() {} + void notify_all() {} +}; +template struct UniqueLock { + UniqueLock(M &) {} +}; +template struct LockGuard { + LockGuard(M &) {} +}; +#endif + // Concurrent queue implementation. Not fast, but simple. // Multi-producer, multi-consumer, optionally bounded. // When YOSYS_ENABLE_THREADS is not defined, this is just a non-thread-safe non-blocking deque. @@ -27,26 +54,20 @@ public: // Push an element into the queue. If it's at capacity, block until there is room. void push_back(T t) { -#ifdef YOSYS_ENABLE_THREADS - std::unique_lock lock(mutex); + UniqueLock lock(mutex); not_full_condition.wait(lock, [this] { return static_cast(contents.size()) < capacity; }); if (contents.empty()) not_empty_condition.notify_one(); -#endif log_assert(!closed); contents.push_back(std::move(t)); -#ifdef YOSYS_ENABLE_THREADS if (static_cast(contents.size()) < capacity) not_full_condition.notify_one(); -#endif } // Signal that no more elements will be produced. `pop_front()` will return nullopt. void close() { -#ifdef YOSYS_ENABLE_THREADS - std::unique_lock lock(mutex); + UniqueLock lock(mutex); not_empty_condition.notify_all(); -#endif closed = true; } // Pop an element from the queue. Blocks until an element is available @@ -62,39 +83,28 @@ public: return pop_front_internal(false); } private: -#ifdef YOSYS_ENABLE_THREADS std::optional pop_front_internal(bool wait) { - std::unique_lock lock(mutex); + UniqueLock lock(mutex); if (wait) { not_empty_condition.wait(lock, [this] { return !contents.empty() || closed; }); } -#else - std::optional pop_front_internal(bool) - { -#endif if (contents.empty()) return std::nullopt; -#ifdef YOSYS_ENABLE_THREADS if (static_cast(contents.size()) == capacity) not_full_condition.notify_one(); -#endif T result = std::move(contents.front()); contents.pop_front(); -#ifdef YOSYS_ENABLE_THREADS if (!contents.empty()) not_empty_condition.notify_one(); -#endif return std::move(result); } -#ifdef YOSYS_ENABLE_THREADS - std::mutex mutex; + Mutex mutex; // Signals one waiter thread when the queue changes and is not full. - std::condition_variable not_full_condition; + CondVar not_full_condition; // Signals one waiter thread when the queue changes and is not empty. - std::condition_variable not_empty_condition; -#endif + CondVar not_empty_condition; std::deque contents; int capacity; bool closed = false; @@ -245,15 +255,14 @@ private: // is maintained. std::atomic num_active_worker_threads_ = 0; -#ifdef YOSYS_ENABLE_THREADS // Not especially efficient for large numbers of threads. Worker wakeup could scale // better by conceptually organising workers into a tree and having workers wake // up their children. - std::mutex main_to_workers_signal_mutex; - std::condition_variable main_to_workers_signal_cv; + Mutex main_to_workers_signal_mutex; + CondVar main_to_workers_signal_cv; std::vector main_to_workers_signal; void signal_workers_start() { - std::unique_lock lock(main_to_workers_signal_mutex); + UniqueLock lock(main_to_workers_signal_mutex); int num_active_worker_threads = num_active_worker_threads_.load(std::memory_order_relaxed); std::fill(main_to_workers_signal.begin(), main_to_workers_signal.begin() + num_active_worker_threads, 1); // When `num_active_worker_threads_` is small compared to `num_worker_threads_`, we have a "thundering herd" @@ -261,14 +270,14 @@ private: main_to_workers_signal_cv.notify_all(); } void worker_wait_for_start(int thread_num) { - std::unique_lock lock(main_to_workers_signal_mutex); + UniqueLock lock(main_to_workers_signal_mutex); main_to_workers_signal_cv.wait(lock, [this, thread_num] { return main_to_workers_signal[thread_num] > 0; }); main_to_workers_signal[thread_num] = 0; } std::atomic done_workers = 0; - std::mutex workers_to_main_signal_mutex; - std::condition_variable workers_to_main_signal_cv; + Mutex workers_to_main_signal_mutex; + CondVar workers_to_main_signal_cv; void signal_worker_done() { // Must read `num_active_worker_threads_` before we increment `d`! Otherwise // it is possible we would increment `d`, and then another worker signals the @@ -277,19 +286,18 @@ private: int num_active_worker_threads = num_active_worker_threads_.load(std::memory_order_relaxed); int d = done_workers.fetch_add(1, std::memory_order_release); if (d + 1 == num_active_worker_threads) { - std::unique_lock lock(workers_to_main_signal_mutex); + UniqueLock lock(workers_to_main_signal_mutex); workers_to_main_signal_cv.notify_all(); } } void wait_for_workers_done() { - std::unique_lock lock(workers_to_main_signal_mutex); + UniqueLock lock(workers_to_main_signal_mutex); workers_to_main_signal_cv.wait(lock, [this] { int num_active_worker_threads = num_active_worker_threads_.load(std::memory_order_relaxed); return done_workers.load(std::memory_order_acquire) == num_active_worker_threads; }); done_workers.store(0, std::memory_order_relaxed); } -#endif // Ensure `thread_pool` is destroyed before any other members, // forcing all threads to be joined before destroying the // members (e.g. workers_to_main_signal_mutex) they might be using. @@ -301,15 +309,11 @@ class ConcurrentStack { public: void push_back(T &&t) { -#ifdef YOSYS_ENABLE_THREADS - std::lock_guard lock(mutex); -#endif + LockGuard lock(mutex); contents.push_back(std::move(t)); } std::optional try_pop_back() { -#ifdef YOSYS_ENABLE_THREADS - std::lock_guard lock(mutex); -#endif + LockGuard lock(mutex); if (contents.empty()) return std::nullopt; T result = std::move(contents.back()); @@ -317,9 +321,7 @@ public: return result; } private: -#ifdef YOSYS_ENABLE_THREADS - std::mutex mutex; -#endif + Mutex mutex; std::vector contents; }; @@ -596,12 +598,12 @@ public: return; bool was_empty; { - std::unique_lock lock(thread_state.batches_lock); + UniqueLock lock(thread_state.batches_lock); was_empty = thread_state.batches.empty(); thread_state.batches.push_back(std::move(thread_state.next_batch)); } if (was_empty) { - std::unique_lock lock(waiters_lock); + UniqueLock lock(waiters_lock); if (num_waiters > 0) { waiters_cv.notify_one(); } @@ -617,7 +619,7 @@ public: return std::move(thread_state.next_batch); // Empty our own work queue first. { - std::unique_lock lock(thread_state.batches_lock); + UniqueLock lock(thread_state.batches_lock); if (!thread_state.batches.empty()) { std::vector batch = std::move(thread_state.batches.back()); thread_state.batches.pop_back(); @@ -634,8 +636,9 @@ public: // them will eventually enter this loop and there will be no further // notifications on waiters_cv, so all will eventually increment // num_waiters and wait, so num_waiters == num_threads() - // will become true. - std::unique_lock lock(waiters_lock); + // will become true. In single-threaded builds, num_threads() is 1, + // so we always terminate on the first iteration. + UniqueLock lock(waiters_lock); ++num_waiters; if (num_waiters == num_threads()) { waiters_cv.notify_all(); @@ -654,7 +657,7 @@ private: for (int i = 1; i < num_threads(); i++) { int other_thread_num = (thread.thread_num + i) % num_threads(); ThreadState &other_thread_state = thread_states[other_thread_num]; - std::unique_lock lock(other_thread_state.batches_lock); + UniqueLock lock(other_thread_state.batches_lock); if (!other_thread_state.batches.empty()) { std::vector batch = std::move(other_thread_state.batches.front()); other_thread_state.batches.pop_front(); @@ -670,15 +673,15 @@ private: // Entirely thread-local. std::vector next_batch; - std::mutex batches_lock; + Mutex batches_lock; // Only the associated thread ever adds to this, and only at the back. // Other threads can remove elements from the front. std::deque> batches; }; std::vector thread_states; - std::mutex waiters_lock; - std::condition_variable waiters_cv; + Mutex waiters_lock; + CondVar waiters_cv; // Number of threads waiting for work. Their queues are empty. int num_waiters = 0; }; From 1c831aa50de37556406e10985f94be882210dc92 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Tue, 12 May 2026 12:19:06 +0200 Subject: [PATCH 049/354] threading: whitespace --- kernel/threading.cc | 8 ++++---- tests/unit/kernel/threadingTest.cc | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/kernel/threading.cc b/kernel/threading.cc index a49ee7d4e..a334dfa4c 100644 --- a/kernel/threading.cc +++ b/kernel/threading.cc @@ -66,11 +66,11 @@ ThreadPool::ThreadPool(int pool_size, std::function b) : body(std::move(b)) { #ifdef YOSYS_ENABLE_THREADS - threads.reserve(pool_size); - for (int i = 0; i < pool_size; i++) - threads.emplace_back([i, this]{ body(i); }); + threads.reserve(pool_size); + for (int i = 0; i < pool_size; i++) + threads.emplace_back([i, this]{ body(i); }); #else - (void)pool_size; + (void)pool_size; #endif } diff --git a/tests/unit/kernel/threadingTest.cc b/tests/unit/kernel/threadingTest.cc index cbab4d118..4e204fc61 100644 --- a/tests/unit/kernel/threadingTest.cc +++ b/tests/unit/kernel/threadingTest.cc @@ -109,8 +109,10 @@ TEST_F(ThreadingTest, IntRangeIteration) { TEST_F(ThreadingTest, IntRangeEmpty) { IntRange range{5, 5}; - for (int _ : range) + for (int _ : range) { + (void)_; FAIL(); + } } TEST_F(ThreadingTest, ItemRangeForWorker) { From 0c2786be1f34e5bbadcc38e02e8bf291a4d7a21f Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Mon, 18 May 2026 16:13:19 +0200 Subject: [PATCH 050/354] threading: make no-op locks specialized to Mutex instead of templates --- kernel/threading.h | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/kernel/threading.h b/kernel/threading.h index 98d3068c4..c843b23ae 100644 --- a/kernel/threading.h +++ b/kernel/threading.h @@ -20,8 +20,8 @@ YOSYS_NAMESPACE_BEGIN #ifdef YOSYS_ENABLE_THREADS using Mutex = std::mutex; using CondVar = std::condition_variable; -template using UniqueLock = std::unique_lock; -template using LockGuard = std::lock_guard; +using UniqueLock = std::unique_lock; +using LockGuard = std::lock_guard; #else struct Mutex { void lock() {} @@ -34,11 +34,11 @@ struct CondVar { void notify_one() {} void notify_all() {} }; -template struct UniqueLock { - UniqueLock(M &) {} +struct UniqueLock { + UniqueLock(Mutex &) {} }; -template struct LockGuard { - LockGuard(M &) {} +struct LockGuard { + LockGuard(Mutex &) {} }; #endif @@ -54,7 +54,7 @@ public: // Push an element into the queue. If it's at capacity, block until there is room. void push_back(T t) { - UniqueLock lock(mutex); + UniqueLock lock(mutex); not_full_condition.wait(lock, [this] { return static_cast(contents.size()) < capacity; }); if (contents.empty()) not_empty_condition.notify_one(); @@ -66,7 +66,7 @@ public: // Signal that no more elements will be produced. `pop_front()` will return nullopt. void close() { - UniqueLock lock(mutex); + UniqueLock lock(mutex); not_empty_condition.notify_all(); closed = true; } @@ -85,7 +85,7 @@ public: private: std::optional pop_front_internal(bool wait) { - UniqueLock lock(mutex); + UniqueLock lock(mutex); if (wait) { not_empty_condition.wait(lock, [this] { return !contents.empty() || closed; }); } @@ -262,7 +262,7 @@ private: CondVar main_to_workers_signal_cv; std::vector main_to_workers_signal; void signal_workers_start() { - UniqueLock lock(main_to_workers_signal_mutex); + UniqueLock lock(main_to_workers_signal_mutex); int num_active_worker_threads = num_active_worker_threads_.load(std::memory_order_relaxed); std::fill(main_to_workers_signal.begin(), main_to_workers_signal.begin() + num_active_worker_threads, 1); // When `num_active_worker_threads_` is small compared to `num_worker_threads_`, we have a "thundering herd" @@ -270,7 +270,7 @@ private: main_to_workers_signal_cv.notify_all(); } void worker_wait_for_start(int thread_num) { - UniqueLock lock(main_to_workers_signal_mutex); + UniqueLock lock(main_to_workers_signal_mutex); main_to_workers_signal_cv.wait(lock, [this, thread_num] { return main_to_workers_signal[thread_num] > 0; }); main_to_workers_signal[thread_num] = 0; } @@ -286,12 +286,12 @@ private: int num_active_worker_threads = num_active_worker_threads_.load(std::memory_order_relaxed); int d = done_workers.fetch_add(1, std::memory_order_release); if (d + 1 == num_active_worker_threads) { - UniqueLock lock(workers_to_main_signal_mutex); + UniqueLock lock(workers_to_main_signal_mutex); workers_to_main_signal_cv.notify_all(); } } void wait_for_workers_done() { - UniqueLock lock(workers_to_main_signal_mutex); + UniqueLock lock(workers_to_main_signal_mutex); workers_to_main_signal_cv.wait(lock, [this] { int num_active_worker_threads = num_active_worker_threads_.load(std::memory_order_relaxed); return done_workers.load(std::memory_order_acquire) == num_active_worker_threads; @@ -309,11 +309,11 @@ class ConcurrentStack { public: void push_back(T &&t) { - LockGuard lock(mutex); + LockGuard lock(mutex); contents.push_back(std::move(t)); } std::optional try_pop_back() { - LockGuard lock(mutex); + LockGuard lock(mutex); if (contents.empty()) return std::nullopt; T result = std::move(contents.back()); @@ -598,12 +598,12 @@ public: return; bool was_empty; { - UniqueLock lock(thread_state.batches_lock); + UniqueLock lock(thread_state.batches_lock); was_empty = thread_state.batches.empty(); thread_state.batches.push_back(std::move(thread_state.next_batch)); } if (was_empty) { - UniqueLock lock(waiters_lock); + UniqueLock lock(waiters_lock); if (num_waiters > 0) { waiters_cv.notify_one(); } @@ -619,7 +619,7 @@ public: return std::move(thread_state.next_batch); // Empty our own work queue first. { - UniqueLock lock(thread_state.batches_lock); + UniqueLock lock(thread_state.batches_lock); if (!thread_state.batches.empty()) { std::vector batch = std::move(thread_state.batches.back()); thread_state.batches.pop_back(); @@ -638,7 +638,7 @@ public: // num_waiters and wait, so num_waiters == num_threads() // will become true. In single-threaded builds, num_threads() is 1, // so we always terminate on the first iteration. - UniqueLock lock(waiters_lock); + UniqueLock lock(waiters_lock); ++num_waiters; if (num_waiters == num_threads()) { waiters_cv.notify_all(); @@ -657,7 +657,7 @@ private: for (int i = 1; i < num_threads(); i++) { int other_thread_num = (thread.thread_num + i) % num_threads(); ThreadState &other_thread_state = thread_states[other_thread_num]; - UniqueLock lock(other_thread_state.batches_lock); + UniqueLock lock(other_thread_state.batches_lock); if (!other_thread_state.batches.empty()) { std::vector batch = std::move(other_thread_state.batches.front()); other_thread_state.batches.pop_front(); From 2159a0e6340a1e2b2adbb5077979c1df43538216 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 18 May 2026 17:00:16 +0200 Subject: [PATCH 051/354] Remove file added by mistake --- passes/equiv/equiv_make.cc.orig | 520 -------------------------------- 1 file changed, 520 deletions(-) delete mode 100644 passes/equiv/equiv_make.cc.orig diff --git a/passes/equiv/equiv_make.cc.orig b/passes/equiv/equiv_make.cc.orig deleted file mode 100644 index 3aa3fac63..000000000 --- a/passes/equiv/equiv_make.cc.orig +++ /dev/null @@ -1,520 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Claire Xenia Wolf - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#include "kernel/yosys.h" -#include "kernel/sigtools.h" -#include "kernel/celltypes.h" - -USING_YOSYS_NAMESPACE -PRIVATE_NAMESPACE_BEGIN - -struct EquivMakeWorker -{ - Module *gold_mod, *gate_mod, *equiv_mod; - pool wire_names, cell_names; - CellTypes ct; - - bool inames; - vector blacklists; - vector encfiles; - bool make_assert; - - pool blacklist_names; - dict> encdata; - - pool undriven_bits; - SigMap assign_map; - - void read_blacklists() - { - for (auto fn : blacklists) - { - std::ifstream f(fn); - if (f.fail()) - log_cmd_error("Can't open blacklist file '%s'!\n", fn); - - string line, token; - while (std::getline(f, line)) { - while (1) { - token = next_token(line); - if (token.empty()) - break; - blacklist_names.insert(RTLIL::escape_id(token)); - } - } - } - } - - void read_encfiles() - { - for (auto fn : encfiles) - { - std::ifstream f(fn); - if (f.fail()) - log_cmd_error("Can't open encfile '%s'!\n", fn); - - dict *ed = nullptr; - string line, token; - while (std::getline(f, line)) - { - token = next_token(line); - if (token.empty() || token[0] == '#') - continue; - - if (token == ".fsm") { - IdString modname = RTLIL::escape_id(next_token(line)); - (void)modname; - IdString signame = RTLIL::escape_id(next_token(line)); - if (encdata.count(signame)) - log_cmd_error("Re-definition of signal '%s' in encfile '%s'!\n", signame, fn); - encdata[signame] = dict(); - ed = &encdata[signame]; - continue; - } - - if (token == ".map") { - Const gold_bits = Const::from_string(next_token(line)); - Const gate_bits = Const::from_string(next_token(line)); - (*ed)[gold_bits] = gate_bits; - continue; - } - - log_cmd_error("Syntax error in encfile '%s'!\n", fn); - } - } - } - - void copy_to_equiv() - { - Module *gold_clone = gold_mod->clone(); - Module *gate_clone = gate_mod->clone(); - - for (auto it : gold_clone->wires().to_vector()) { - if ((it->name.isPublic() || inames) && blacklist_names.count(it->name) == 0) - wire_names.insert(it->name); - gold_clone->rename(it, it->name.str() + "_gold"); - } - - for (auto it : gold_clone->cells().to_vector()) { - if ((it->name.isPublic() || inames) && blacklist_names.count(it->name) == 0) - cell_names.insert(it->name); - gold_clone->rename(it, it->name.str() + "_gold"); - } - - for (auto it : gate_clone->wires().to_vector()) { - if ((it->name.isPublic() || inames) && blacklist_names.count(it->name) == 0) - wire_names.insert(it->name); - gate_clone->rename(it, it->name.str() + "_gate"); - } - - for (auto it : gate_clone->cells().to_vector()) { - if ((it->name.isPublic() || inames) && blacklist_names.count(it->name) == 0) - cell_names.insert(it->name); - gate_clone->rename(it, it->name.str() + "_gate"); - } - - gold_clone->cloneInto(equiv_mod); - gate_clone->cloneInto(equiv_mod); - delete gold_clone; - delete gate_clone; - } - - void add_eq_assertion(const SigSpec &gold_sig, const SigSpec &gate_sig) - { - auto eq_wire = equiv_mod->Eqx(NEW_ID, gold_sig, gate_sig); - equiv_mod->addAssert(NEW_ID_SUFFIX("assert"), eq_wire, State::S1); - } - - void find_same_wires() - { - SigMap assign_map(equiv_mod); - SigMap rd_signal_map; - SigPool primary_inputs; - - // list of cells without added $equiv cells - auto cells_list = equiv_mod->cells().to_vector(); - - for (auto id : wire_names) - { - IdString gold_id = id.str() + "_gold"; - IdString gate_id = id.str() + "_gate"; - - Wire *gold_wire = equiv_mod->wire(gold_id); - Wire *gate_wire = equiv_mod->wire(gate_id); - - if (encdata.count(id)) - { - log("Creating encoder/decoder for signal %s.\n", id.unescape()); - - Wire *dec_wire = equiv_mod->addWire(id.str() + "_decoded", gold_wire->width); - Wire *enc_wire = equiv_mod->addWire(id.str() + "_encoded", gate_wire->width); - - SigSpec dec_a, dec_b, dec_s; - SigSpec enc_a, enc_b, enc_s; - - dec_a = SigSpec(State::Sx, dec_wire->width); - enc_a = SigSpec(State::Sx, enc_wire->width); - - for (auto &it : encdata.at(id)) - { - SigSpec dec_sig = gate_wire, dec_pat = it.second; - SigSpec enc_sig = dec_wire, enc_pat = it.first; - - if (GetSize(dec_sig) != GetSize(dec_pat)) - log_error("Invalid pattern %s for signal %s of size %d!\n", - log_signal(dec_pat), log_signal(dec_sig), GetSize(dec_sig)); - - if (GetSize(enc_sig) != GetSize(enc_pat)) - log_error("Invalid pattern %s for signal %s of size %d!\n", - log_signal(enc_pat), log_signal(enc_sig), GetSize(enc_sig)); - - SigSpec reduced_dec_sig, reduced_dec_pat; - for (int i = 0; i < GetSize(dec_sig); i++) - if (dec_pat[i] == State::S0 || dec_pat[i] == State::S1) { - reduced_dec_sig.append(dec_sig[i]); - reduced_dec_pat.append(dec_pat[i]); - } - - SigSpec reduced_enc_sig, reduced_enc_pat; - for (int i = 0; i < GetSize(enc_sig); i++) - if (enc_pat[i] == State::S0 || enc_pat[i] == State::S1) { - reduced_enc_sig.append(enc_sig[i]); - reduced_enc_pat.append(enc_pat[i]); - } - - SigSpec dec_result = it.first; - for (auto &bit : dec_result) - if (bit != State::S1) bit = State::S0; - - SigSpec enc_result = it.second; - for (auto &bit : enc_result) - if (bit != State::S1) bit = State::S0; - - SigSpec dec_eq = equiv_mod->addWire(NEW_ID); - SigSpec enc_eq = equiv_mod->addWire(NEW_ID); - - equiv_mod->addEq(NEW_ID, reduced_dec_sig, reduced_dec_pat, dec_eq); - cells_list.push_back(equiv_mod->addEq(NEW_ID, reduced_enc_sig, reduced_enc_pat, enc_eq)); - - dec_s.append(dec_eq); - enc_s.append(enc_eq); - dec_b.append(dec_result); - enc_b.append(enc_result); - } - - equiv_mod->addPmux(NEW_ID, dec_a, dec_b, dec_s, dec_wire); - equiv_mod->addPmux(NEW_ID, enc_a, enc_b, enc_s, enc_wire); - - rd_signal_map.add(assign_map(gate_wire), enc_wire); - gate_wire = dec_wire; - } - - if (gold_wire == nullptr || gate_wire == nullptr || gold_wire->width != gate_wire->width) { - if (gold_wire && gold_wire->port_id) - log_error("Can't match gold port `%s' to a gate port.\n", gold_wire); - if (gate_wire && gate_wire->port_id) - log_error("Can't match gate port `%s' to a gold port.\n", gate_wire); - continue; - } - - log("Presumably equivalent wires: %s (%s), %s (%s) -> %s\n", - gold_wire, log_signal(assign_map(gold_wire)), - gate_wire, log_signal(assign_map(gate_wire)), id.unescape()); - - if (gold_wire->port_output || gate_wire->port_output) - { - gold_wire->port_input = false; - gate_wire->port_input = false; - gold_wire->port_output = false; - gate_wire->port_output = false; - - Wire *wire = equiv_mod->addWire(id, gold_wire->width); - wire->port_output = true; - - if (make_assert) - { - add_eq_assertion(gold_wire, gate_wire); - equiv_mod->connect(wire, gold_wire); - } - else - { - for (int i = 0; i < wire->width; i++) - equiv_mod->addEquiv(NEW_ID, SigSpec(gold_wire, i), SigSpec(gate_wire, i), SigSpec(wire, i)); - } - - rd_signal_map.add(assign_map(gold_wire), wire); - rd_signal_map.add(assign_map(gate_wire), wire); - } - else - if (gold_wire->port_input || gate_wire->port_input) - { - Wire *wire = equiv_mod->addWire(id, gold_wire->width); - wire->port_input = true; - gold_wire->port_input = false; - gate_wire->port_input = false; - equiv_mod->connect(gold_wire, wire); - equiv_mod->connect(gate_wire, wire); - primary_inputs.add(assign_map(gold_wire)); - primary_inputs.add(assign_map(gate_wire)); - primary_inputs.add(wire); - } - else - { - if (make_assert) - add_eq_assertion(gold_wire, gate_wire); - - else { - Wire *wire = equiv_mod->addWire(id, gold_wire->width); - SigSpec rdmap_gold, rdmap_gate, rdmap_equiv; - - for (int i = 0; i < wire->width; i++) { - if (undriven_bits.count(assign_map(SigBit(gold_wire, i)))) { - log(" Skipping signal bit %s [%d]: undriven on gold side.\n", id2cstr(gold_wire->name), i); - continue; - } - if (undriven_bits.count(assign_map(SigBit(gate_wire, i)))) { - log(" Skipping signal bit %s [%d]: undriven on gate side.\n", id2cstr(gate_wire->name), i); - continue; - } - equiv_mod->addEquiv(NEW_ID, SigSpec(gold_wire, i), SigSpec(gate_wire, i), SigSpec(wire, i)); - rdmap_gold.append(SigBit(gold_wire, i)); - rdmap_gate.append(SigBit(gate_wire, i)); - rdmap_equiv.append(SigBit(wire, i)); - } - - rd_signal_map.add(rdmap_gold, rdmap_equiv); - rd_signal_map.add(rdmap_gate, rdmap_equiv); - } - } - } - - for (auto c : cells_list) - for (auto &conn : c->connections()) - if (!ct.cell_output(c->type, conn.first)) { - SigSpec old_sig = assign_map(conn.second); - SigSpec new_sig = rd_signal_map(old_sig); - for (int i = 0; i < GetSize(old_sig); i++) - if (primary_inputs.check(old_sig[i])) - new_sig[i] = old_sig[i]; - if (old_sig != new_sig) { - log("Changing input %s of cell %s (%s): %s -> %s\n", - conn.first.unescape(), c, c->type.unescape(), - log_signal(old_sig), log_signal(new_sig)); - c->setPort(conn.first, new_sig); - } - } - - equiv_mod->fixup_ports(); - } - - void find_same_cells() - { - SigMap assign_map(equiv_mod); - - for (auto id : cell_names) - { - IdString gold_id = id.str() + "_gold"; - IdString gate_id = id.str() + "_gate"; - - Cell *gold_cell = equiv_mod->cell(gold_id); - Cell *gate_cell = equiv_mod->cell(gate_id); - - if (gold_cell == nullptr || gate_cell == nullptr || gold_cell->type != gate_cell->type || !ct.cell_known(gold_cell->type) || - gold_cell->parameters != gate_cell->parameters || GetSize(gold_cell->connections()) != GetSize(gate_cell->connections())) - try_next_cell_name: - continue; - - for (auto gold_conn : gold_cell->connections()) - if (!gate_cell->connections().count(gold_conn.first)) - goto try_next_cell_name; - - log("Presumably equivalent cells: %s %s (%s) -> %s\n", - gold_cell, gate_cell, gold_cell->type.unescape(), id.unescape()); - - for (auto gold_conn : gold_cell->connections()) - { - SigSpec gold_sig = assign_map(gold_conn.second); - SigSpec gate_sig = assign_map(gate_cell->getPort(gold_conn.first)); - - if (ct.cell_output(gold_cell->type, gold_conn.first)) { - equiv_mod->connect(gate_sig, gold_sig); - continue; - } - - if (make_assert) - { - if (gold_sig != gate_sig) - add_eq_assertion(gold_sig, gate_sig); - } - else - { - for (int i = 0; i < GetSize(gold_sig); i++) - if (gold_sig[i] != gate_sig[i]) { - Wire *w = equiv_mod->addWire(NEW_ID); - equiv_mod->addEquiv(NEW_ID, gold_sig[i], gate_sig[i], w); - gold_sig[i] = w; - } - } - - gold_cell->setPort(gold_conn.first, gold_sig); - } - - equiv_mod->remove(gate_cell); - equiv_mod->rename(gold_cell, id); - } - } - - void find_undriven_nets(bool mark) - { - undriven_bits.clear(); - assign_map.set(equiv_mod); - - for (auto wire : equiv_mod->wires()) { - for (auto bit : assign_map(wire)) - if (bit.wire) - undriven_bits.insert(bit); - } - - for (auto wire : equiv_mod->wires()) { - if (wire->port_input) - for (auto bit : assign_map(wire)) - undriven_bits.erase(bit); - } - - for (auto cell : equiv_mod->cells()) { - for (auto &conn : cell->connections()) - if (!ct.cell_known(cell->type) || ct.cell_output(cell->type, conn.first)) - for (auto bit : assign_map(conn.second)) - undriven_bits.erase(bit); - } - - if (mark) { - SigSpec undriven_sig(undriven_bits); - undriven_sig.sort_and_unify(); - - for (auto chunk : undriven_sig.chunks()) { - log("Setting undriven nets to undef: %s\n", log_signal(chunk)); - equiv_mod->connect(chunk, SigSpec(State::Sx, chunk.width)); - } - } - } - - void run() - { - copy_to_equiv(); - find_undriven_nets(false); - find_same_wires(); - find_same_cells(); - find_undriven_nets(true); - } -}; - -struct EquivMakePass : public Pass { - EquivMakePass() : Pass("equiv_make", "prepare a circuit for equivalence checking") { } - void help() override - { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("\n"); - log(" equiv_make [options] gold_module gate_module equiv_module\n"); - log("\n"); - log("This creates a module annotated with $equiv cells from two presumably\n"); - log("equivalent modules. Use commands such as 'equiv_simple' and 'equiv_status'\n"); - log("to work with the created equivalent checking module.\n"); - log("\n"); - log(" -inames\n"); - log(" Also match cells and wires with $... names.\n"); - log("\n"); - log(" -blacklist \n"); - log(" Do not match cells or signals that match the names in the file.\n"); - log("\n"); - log(" -encfile \n"); - log(" Match FSM encodings using the description from the file.\n"); - log(" See 'help fsm_recode' for details.\n"); - log("\n"); - log(" -make_assert\n"); - log(" Check equivalence with $assert cells instead of $equiv.\n"); - log(" $eqx (===) is used to compare signals."); - log("\n"); - log("Note: The circuit created by this command is not a miter (with something like\n"); - log("a trigger output), but instead uses $equiv cells to encode the equivalence\n"); - log("checking problem. Use 'miter -equiv' if you want to create a miter circuit.\n"); - log("\n"); - } - void execute(std::vector args, RTLIL::Design *design) override - { - EquivMakeWorker worker; - worker.ct.setup(design); - worker.inames = false; - worker.make_assert = false; - - size_t argidx; - for (argidx = 1; argidx < args.size(); argidx++) - { - if (args[argidx] == "-inames") { - worker.inames = true; - continue; - } - if (args[argidx] == "-blacklist" && argidx+1 < args.size()) { - worker.blacklists.push_back(args[++argidx]); - continue; - } - if (args[argidx] == "-encfile" && argidx+1 < args.size()) { - worker.encfiles.push_back(args[++argidx]); - continue; - } - if (args[argidx] == "-make_assert") { - worker.make_assert = true; - continue; - } - break; - } - - if (argidx+3 != args.size()) - log_cmd_error("Invalid number of arguments.\n"); - - worker.gold_mod = design->module(RTLIL::escape_id(args[argidx])); - worker.gate_mod = design->module(RTLIL::escape_id(args[argidx+1])); - worker.equiv_mod = design->module(RTLIL::escape_id(args[argidx+2])); - - if (worker.gold_mod == nullptr) - log_cmd_error("Can't find gold module %s.\n", args[argidx]); - - if (worker.gate_mod == nullptr) - log_cmd_error("Can't find gate module %s.\n", args[argidx+1]); - - if (worker.equiv_mod != nullptr) - log_cmd_error("Equiv module %s already exists.\n", args[argidx+2]); - - if (worker.gold_mod->has_memories() || worker.gold_mod->has_processes()) - log_cmd_error("Gold module contains memories or processes. Run 'memory' or 'proc' respectively.\n"); - - if (worker.gate_mod->has_memories() || worker.gate_mod->has_processes()) - log_cmd_error("Gate module contains memories or processes. Run 'memory' or 'proc' respectively.\n"); - - worker.read_blacklists(); - worker.read_encfiles(); - - log_header(design, "Executing EQUIV_MAKE pass (creating equiv checking module).\n"); - - worker.equiv_mod = design->addModule(RTLIL::escape_id(args[argidx+2])); - worker.run(); - } -} EquivMakePass; - -PRIVATE_NAMESPACE_END From 44a1abdadeabf9a9a3d30ccb468ae7a9b14e6864 Mon Sep 17 00:00:00 2001 From: nella Date: Tue, 19 May 2026 12:16:29 +0200 Subject: [PATCH 052/354] Don't repeat VCD warnings + fixups. --- passes/sat/sim.cc | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index ddc256384..2b2982ceb 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -429,7 +429,7 @@ struct SimInstance Const value = builder.build(); if (shared->debug) - log("[%s] get %s: %s\n", hiername(), log_signal(sig, true), log_signal(value, true)); + log("[%s] get %s: %s\n", hiername(), log_signal(sig), log_signal(value, true)); return value; } @@ -448,7 +448,7 @@ struct SimInstance } if (shared->debug) - log("[%s] set %s: %s\n", hiername(), log_signal(sig, true), log_signal(value, true)); + log("[%s] set %s: %s\n", hiername(), log_signal(sig), log_signal(value, true)); return did_something; } @@ -1201,7 +1201,7 @@ struct SimInstance // 3) module has no processes (sim enforces proc-lowered input before this point). // 4) sigmap is valid for per-bit queries on this instance. // 5) shared->fst is active, i.e. this is called from FST/VCD replay flow. - int checkUndrivenReplaySignals() + int checkUndrivenReplaySignals(bool &any_undriven_found) { int issue_count = 0; bool has_replay_candidates = false; @@ -1231,14 +1231,14 @@ struct SimInstance continue; issue_count++; + any_undriven_found = true; std::string wire_name = scope + "." + RTLIL::unescape_id(wire->name); - log_warning("Input trace contains undriven signal `%s` (%s); values for this signal are not replayed from FST/VCD input.\n", - wire_name.c_str(), log_signal(undriven, true)); + log_warning("Input trace contains undriven signal `%s` (%s).\n", wire_name.c_str(), log_signal(undriven)); } } for (auto child : children) - issue_count += child.second->checkUndrivenReplaySignals(); + issue_count += child.second->checkUndrivenReplaySignals(any_undriven_found); return issue_count; } @@ -1550,7 +1550,10 @@ struct SimWorker : SimShared top->addAdditionalInputs(); if (undriven_check) { - int issue_count = top->checkUndrivenReplaySignals(); + bool any_undriven_found = false; + int issue_count = top->checkUndrivenReplaySignals(any_undriven_found); + if (any_undriven_found) + log_warning("Values for the undriven signal(s) listed above are not replayed from FST/VCD input.\n"); if (issue_count > 0 && !undriven_warning) log_cmd_error("Found %d undriven signal%s in the replay trace. Use -undriven-warn to continue or -no-undriven-check to disable this check.\n", issue_count, issue_count == 1 ? "" : "s"); From c0779f488afdbb2e789ea5ede63a3a7e720fc0e4 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 19 May 2026 14:26:07 +0200 Subject: [PATCH 053/354] Make out of tree build testing possible --- tests/Makefile | 2 +- tests/arch/xilinx/macc.sh | 4 ++-- tests/arch/xilinx/tribuf.sh | 4 ++-- tests/bram/run-single.sh | 2 +- tests/bugpoint/failures.ys | 20 ++++++++++---------- tests/bugpoint/mod_constraints.ys | 20 ++++++++++---------- tests/bugpoint/proc_constraints.ys | 14 +++++++------- tests/bugpoint/raise_error.ys | 14 +++++++------- tests/common.mk | 12 ++++++++++++ tests/functional/test_functional.py | 6 +++--- tests/gen_tests_makefile.py | 4 ++-- tests/liberty/generate_mk.py | 3 +-- tests/memfile/generate_mk.py | 6 +++--- tests/memlib/generate_mk.py | 2 +- tests/rpc/frontend.py | 2 +- tests/rtlil/roundtrip-design.sh | 5 ++--- tests/rtlil/roundtrip-text.sh | 7 +++---- tests/sdc/side-effects.sh | 2 +- tests/sdc/unknown-getter.sh | 2 +- tests/sva/runtest.sh | 8 ++++---- tests/techmap/bug5495.sh | 2 +- tests/techmap/mem_simple_4x1_runtest.sh | 2 +- tests/techmap/recursive_runtest.sh | 2 +- tests/tools/autotest.sh | 11 +++++++---- tests/various/async.sh | 8 ++++---- tests/various/chparam.sh | 8 ++++---- tests/various/clk2fflogic_effects.sh | 4 ++-- tests/various/ezcmdline_plugin.sh | 8 ++++---- tests/various/hierarchy.sh | 6 +++--- tests/various/logger_cmd_error.sh | 2 +- tests/various/logger_fail.sh | 2 +- tests/various/plugin.sh | 10 +++++----- tests/various/sv_implicit_ports.sh | 20 ++++++++++---------- tests/various/svalways.sh | 10 +++++----- tests/verilog/dynamic_range_lhs.sh | 2 +- tests/verilog/local_include.sh | 12 ++++++------ tests/xprop/test.py | 2 +- 37 files changed, 131 insertions(+), 119 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index 794e99c46..05e5410b7 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -100,7 +100,7 @@ makefile-./%: %/Makefile .PHONY: functional functional: ifeq ($(ENABLE_FUNCTIONAL_TESTS),1) - @cd functional && ./run-test.sh + -@cd functional && ./run-test.sh endif vanilla-test: prep makefile-tests functional diff --git a/tests/arch/xilinx/macc.sh b/tests/arch/xilinx/macc.sh index 58b97b646..84798e76b 100644 --- a/tests/arch/xilinx/macc.sh +++ b/tests/arch/xilinx/macc.sh @@ -1,6 +1,6 @@ -../../../yosys -qp "synth_xilinx -top macc2; rename -top macc2_uut" -o macc_uut.v macc.v +${YOSYS} -qp "synth_xilinx -top macc2; rename -top macc2_uut" -o macc_uut.v macc.v iverilog -o test_macc macc_tb.v macc_uut.v macc.v ../../../techlibs/xilinx/cells_sim.v vvp -N ./test_macc -../../../yosys -qp "synth_xilinx -family xc6s -top macc2; rename -top macc2_uut" -o macc_uut.v macc.v +${YOSYS} -qp "synth_xilinx -family xc6s -top macc2; rename -top macc2_uut" -o macc_uut.v macc.v iverilog -o test_macc macc_tb.v macc_uut.v macc.v ../../../techlibs/xilinx/cells_sim.v vvp -N ./test_macc diff --git a/tests/arch/xilinx/tribuf.sh b/tests/arch/xilinx/tribuf.sh index eca33e490..354117b74 100644 --- a/tests/arch/xilinx/tribuf.sh +++ b/tests/arch/xilinx/tribuf.sh @@ -1,5 +1,5 @@ -../../../yosys -f verilog -qp "synth_xilinx" ../common/tribuf.v -../../../yosys -f verilog -qp "synth_xilinx -iopad; \ +${YOSYS} -f verilog -qp "synth_xilinx" ../common/tribuf.v +${YOSYS} -f verilog -qp "synth_xilinx -iopad; \ select -assert-count 2 t:IBUF; \ select -assert-count 1 t:INV; \ select -assert-count 1 t:OBUFT" ../common/tribuf.v diff --git a/tests/bram/run-single.sh b/tests/bram/run-single.sh index 358423f32..f7ce6f644 100644 --- a/tests/bram/run-single.sh +++ b/tests/bram/run-single.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash set -e -../../yosys -qq -f verilog -p "proc; opt; memory -nomap -bram temp/brams_${2}.txt; opt -fast -full" \ +${YOSYS} -qq -f verilog -p "proc; opt; memory -nomap -bram temp/brams_${2}.txt; opt -fast -full" \ -l temp/synth_${1}_${2}.log -o temp/synth_${1}_${2}.v temp/brams_${1}.v iverilog -Dvcd_file=\"temp/tb_${1}_${2}.vcd\" -DSIMLIB_MEMDELAY=1 -o temp/tb_${1}_${2}.tb temp/brams_${1}_tb.v \ temp/brams_${1}_ref.v temp/synth_${1}_${2}.v temp/brams_${2}.v ../../techlibs/common/simlib.v diff --git a/tests/bugpoint/failures.ys b/tests/bugpoint/failures.ys index ce8daa8cc..1f7168e33 100644 --- a/tests/bugpoint/failures.ys +++ b/tests/bugpoint/failures.ys @@ -1,29 +1,29 @@ write_file fail.temp << EOF logger -expect error "Missing -script or -command option." 1 -bugpoint -suffix fail -yosys ../../yosys +bugpoint -suffix fail -yosys ${YOSYS} EOF -exec -expect-return 0 -- ../../yosys -qq mods.il -s fail.temp +exec -expect-return 0 -- ${YOSYS} -qq mods.il -s fail.temp write_file fail.temp << EOF logger -expect error "do not crash on this design" 1 -bugpoint -suffix fail -yosys ../../yosys -command "dump" +bugpoint -suffix fail -yosys ${YOSYS} -command "dump" EOF -exec -expect-return 0 -- ../../yosys -qq mods.il -s fail.temp +exec -expect-return 0 -- ${YOSYS} -qq mods.il -s fail.temp write_file fail.temp << EOF logger -expect error "returned value 3 instead of expected 7" 1 -bugpoint -suffix fail -yosys ../../yosys -command raise_error -expect-return 7 +bugpoint -suffix fail -yosys ${YOSYS} -command raise_error -expect-return 7 EOF -exec -expect-return 0 -- ../../yosys -qq mods.il -s fail.temp +exec -expect-return 0 -- ${YOSYS} -qq mods.il -s fail.temp write_file fail.temp << EOF logger -expect error "not found in the log file!" 1 -bugpoint -suffix fail -yosys ../../yosys -command raise_error -grep "nope" +bugpoint -suffix fail -yosys ${YOSYS} -command raise_error -grep "nope" EOF -exec -expect-return 0 -- ../../yosys -qq mods.il -s fail.temp +exec -expect-return 0 -- ${YOSYS} -qq mods.il -s fail.temp write_file fail.temp << EOF logger -expect error "not found in stderr log!" 1 -bugpoint -suffix fail -yosys ../../yosys -command raise_error -err-grep "nope" +bugpoint -suffix fail -yosys ${YOSYS} -command raise_error -err-grep "nope" EOF -exec -expect-return 0 -- ../../yosys -qq mods.il -s fail.temp +exec -expect-return 0 -- ${YOSYS} -qq mods.il -s fail.temp diff --git a/tests/bugpoint/mod_constraints.ys b/tests/bugpoint/mod_constraints.ys index f35095510..23b4bf68c 100644 --- a/tests/bugpoint/mod_constraints.ys +++ b/tests/bugpoint/mod_constraints.ys @@ -6,35 +6,35 @@ design -stash base # everything is removed by default design -load base -bugpoint -suffix mods -yosys ../../yosys -command raise_error -expect-return 3 +bugpoint -suffix mods -yosys ${YOSYS} -command raise_error -expect-return 3 select -assert-count 1 w:* select -assert-mod-count 1 =* select -assert-none c:* # don't remove wires design -load base -bugpoint -suffix mods -yosys ../../yosys -command raise_error -expect-return 3 -modules -cells +bugpoint -suffix mods -yosys ${YOSYS} -command raise_error -expect-return 3 -modules -cells select -assert-count 3 w:* select -assert-mod-count 1 =* select -assert-none c:* # don't remove cells or their connections design -load base -bugpoint -suffix mods -yosys ../../yosys -command raise_error -expect-return 3 -wires -modules +bugpoint -suffix mods -yosys ${YOSYS} -command raise_error -expect-return 3 -wires -modules select -assert-count 5 w:* select -assert-mod-count 1 =* select -assert-count 4 c:* # don't remove cells but do remove their connections design -load base -bugpoint -suffix mods -yosys ../../yosys -command raise_error -expect-return 3 -wires -modules -connections +bugpoint -suffix mods -yosys ${YOSYS} -command raise_error -expect-return 3 -wires -modules -connections select -assert-count 1 w:* select -assert-mod-count 1 =* select -assert-count 4 c:* # don't remove modules design -load base -bugpoint -suffix mods -yosys ../../yosys -command raise_error -expect-return 3 -wires -cells +bugpoint -suffix mods -yosys ${YOSYS} -command raise_error -expect-return 3 -wires -cells select -assert-count 1 w:* select -assert-mod-count 3 =* select -assert-none c:* @@ -42,7 +42,7 @@ select -assert-none c:* # can keep wires design -load base setattr -set bugpoint_keep 1 w:w_b -bugpoint -suffix mods -yosys ../../yosys -command raise_error -expect-return 3 +bugpoint -suffix mods -yosys ${YOSYS} -command raise_error -expect-return 3 select -assert-count 2 w:* select -assert-mod-count 1 =* select -assert-none c:* @@ -50,7 +50,7 @@ select -assert-none c:* # a wire with keep won't keep the cell/module containing it design -load base setattr -set bugpoint_keep 1 w:w_o -bugpoint -suffix mods -yosys ../../yosys -command raise_error -expect-return 3 +bugpoint -suffix mods -yosys ${YOSYS} -command raise_error -expect-return 3 select -assert-count 1 w:* select -assert-mod-count 1 =* select -assert-none c:* @@ -58,7 +58,7 @@ select -assert-none c:* # can keep cells (and do it without the associated module) design -load base setattr -set bugpoint_keep 1 c:c_a -bugpoint -suffix mods -yosys ../../yosys -command raise_error -expect-return 3 +bugpoint -suffix mods -yosys ${YOSYS} -command raise_error -expect-return 3 select -assert-count 1 w:* select -assert-mod-count 1 =* select -assert-count 1 c:* @@ -66,7 +66,7 @@ select -assert-count 1 c:* # can keep modules design -load base setattr -mod -set bugpoint_keep 1 m_a -bugpoint -suffix mods -yosys ../../yosys -command raise_error -expect-return 3 +bugpoint -suffix mods -yosys ${YOSYS} -command raise_error -expect-return 3 select -assert-count 1 w:* select -assert-mod-count 2 =* select -assert-none c:* @@ -77,7 +77,7 @@ write_file script.temp << EOF select -assert-none w:w_a %co* w:w_c %ci* %i EOF design -load base -bugpoint -suffix mods -yosys ../../yosys -script script.temp -grep "Assertion failed" +bugpoint -suffix mods -yosys ${YOSYS} -script script.temp -grep "Assertion failed" select -assert-count 5 w:* select -assert-mod-count 2 =* select -assert-count 2 c:* diff --git a/tests/bugpoint/proc_constraints.ys b/tests/bugpoint/proc_constraints.ys index 22b8b3c60..6c905b48c 100644 --- a/tests/bugpoint/proc_constraints.ys +++ b/tests/bugpoint/proc_constraints.ys @@ -4,18 +4,18 @@ design -stash err_q # processes get removed by default design -load err_q -bugpoint -suffix procs -yosys ../../yosys -command raise_error -expect-return 4 +bugpoint -suffix procs -yosys ${YOSYS} -command raise_error -expect-return 4 select -assert-none p:* # individual processes can be kept design -load err_q setattr -set bugpoint_keep 1 p:proc_a -bugpoint -suffix procs -yosys ../../yosys -command raise_error -expect-return 4 +bugpoint -suffix procs -yosys ${YOSYS} -command raise_error -expect-return 4 select -assert-count 1 p:* # all processes can be kept design -load err_q -bugpoint -suffix procs -yosys ../../yosys -command raise_error -expect-return 4 -wires +bugpoint -suffix procs -yosys ${YOSYS} -command raise_error -expect-return 4 -wires select -assert-count 2 p:* # d and clock are connected after proc @@ -26,24 +26,24 @@ select -assert-count 3 w:clock %co # no assigns means no d design -load err_q -bugpoint -suffix procs -yosys ../../yosys -command raise_error -expect-return 4 -assigns +bugpoint -suffix procs -yosys ${YOSYS} -command raise_error -expect-return 4 -assigns proc select -assert-count 1 w:d %co # no updates means no clock design -load err_q -bugpoint -suffix procs -yosys ../../yosys -command raise_error -expect-return 4 -updates +bugpoint -suffix procs -yosys ${YOSYS} -command raise_error -expect-return 4 -updates proc select -assert-count 1 w:clock %co # can remove ports design -load err_q select -assert-count 5 x:* -bugpoint -suffix procs -yosys ../../yosys -command raise_error -expect-return 4 -ports +bugpoint -suffix procs -yosys ${YOSYS} -command raise_error -expect-return 4 -ports select -assert-none x:* # can keep ports design -load err_q setattr -set bugpoint_keep 1 i:d o:q -bugpoint -suffix procs -yosys ../../yosys -command raise_error -expect-return 4 -ports +bugpoint -suffix procs -yosys ${YOSYS} -command raise_error -expect-return 4 -ports select -assert-count 2 x:* diff --git a/tests/bugpoint/raise_error.ys b/tests/bugpoint/raise_error.ys index 79127deff..3985c7115 100644 --- a/tests/bugpoint/raise_error.ys +++ b/tests/bugpoint/raise_error.ys @@ -24,21 +24,21 @@ logger -check-expected design -load read setattr -mod -unset raise_error def other dump -bugpoint -suffix error -yosys ../../yosys -command raise_error -expect-return 7 +bugpoint -suffix error -yosys ${YOSYS} -command raise_error -expect-return 7 select -assert-mod-count 1 =* select -assert-mod-count 1 top # raise_error -always still uses 'raise_error' attribute if possible design -load read setattr -mod -unset raise_error def other -bugpoint -suffix error -yosys ../../yosys -command "raise_error -always" -expect-return 7 +bugpoint -suffix error -yosys ${YOSYS} -command "raise_error -always" -expect-return 7 select -assert-mod-count 1 =* select -assert-mod-count 1 top # raise_error with string prints message and exits with 1 design -load read setattr -mod -unset raise_error top def -bugpoint -suffix error -yosys ../../yosys -command raise_error -grep "help me" -expect-return 1 +bugpoint -suffix error -yosys ${YOSYS} -command raise_error -grep "help me" -expect-return 1 select -assert-mod-count 1 =* select -assert-mod-count 1 other @@ -46,18 +46,18 @@ select -assert-mod-count 1 other design -load read setattr -mod -unset raise_error top delete other -bugpoint -suffix error -yosys ../../yosys -command raise_error -expect-return 1 +bugpoint -suffix error -yosys ${YOSYS} -command raise_error -expect-return 1 select -assert-mod-count 1 =* select -assert-mod-count 1 def # raise_error -stderr prints to stderr and exits with 1 design -load read setattr -mod -unset raise_error top def -bugpoint -suffix error -yosys ../../yosys -command "raise_error -stderr" -err-grep "help me" -expect-return 1 +bugpoint -suffix error -yosys ${YOSYS} -command "raise_error -stderr" -err-grep "help me" -expect-return 1 select -assert-mod-count 1 =* select -assert-mod-count 1 other # empty design can raise_error -always design -reset -bugpoint -suffix error -yosys ../../yosys -command "raise_error -always" -grep "ERROR: No 'raise_error' attribute found" -expect-return 1 -bugpoint -suffix error -yosys ../../yosys -command "raise_error -always -stderr" -err-grep "No 'raise_error' attribute found" -expect-return 1 +bugpoint -suffix error -yosys ${YOSYS} -command "raise_error -always" -grep "ERROR: No 'raise_error' attribute found" -expect-return 1 +bugpoint -suffix error -yosys ${YOSYS} -command "raise_error -always -stderr" -err-grep "No 'raise_error' attribute found" -expect-return 1 diff --git a/tests/common.mk b/tests/common.mk index 044054e0c..59ea599c0 100644 --- a/tests/common.mk +++ b/tests/common.mk @@ -1,3 +1,15 @@ +ROOT_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) +BUILD_DIR ?= $(ROOT_DIR)/.. + +YOSYS ?= $(BUILD_DIR)/yosys +ABC ?= $(BUILD_DIR)/yosys-abc +YOSYS_FILTERLIB ?= $(BUILD_DIR)/yosys-filterlib +YOSYS_CONFIG ?= $(BUILD_DIR)/yosys-config + +export YOSYS +export YOSYS_CONFIG +export ABC + all: ifndef OVERRIDE_MAIN diff --git a/tests/functional/test_functional.py b/tests/functional/test_functional.py index 661af14d1..9df832864 100644 --- a/tests/functional/test_functional.py +++ b/tests/functional/test_functional.py @@ -1,6 +1,6 @@ import subprocess import pytest -import sys +import os import shlex from pathlib import Path @@ -18,7 +18,7 @@ def run(cmd, **kwargs): assert status.returncode == 0, f"{cmd[0]} failed" def yosys(script): - run([base_path / 'yosys', '-Q', '-p', script]) + run([os.environ.get("YOSYS", "../../yosys"), '-Q', '-p', script]) def compile_cpp(in_path, out_path, args): run(['g++', '-g', '-std=c++20'] + args + [str(in_path), '-o', str(out_path)]) @@ -35,7 +35,7 @@ def yosys_sim(rtlil_file, vcd_reference_file, vcd_out_file, preprocessing = ""): # since yosys sim aborts on simulation mismatch to generate vcd output # we have to re-run with a different set of flags # on this run we ignore output and return code, we just want a best-effort attempt to get a vcd - subprocess.run([base_path / 'yosys', '-Q', '-p', + subprocess.run([os.environ.get("YOSYS", "../../yosys"), '-Q', '-p', f'read_rtlil {quote(rtlil_file)}; sim -vcd {quote(vcd_out_file)} -a -r {quote(vcd_reference_file)} -scope gold -timescale 1us -fst-noinit'], capture_output=True, check=False) raise diff --git a/tests/gen_tests_makefile.py b/tests/gen_tests_makefile.py index e4e44241c..77602a9a0 100644 --- a/tests/gen_tests_makefile.py +++ b/tests/gen_tests_makefile.py @@ -97,7 +97,7 @@ def print_header(extra=None): print(f"ifneq ($(wildcard {yosys_basedir}/Makefile.conf),)") print(f"include {yosys_basedir}/Makefile.conf") print(f"endif") - print(f"YOSYS ?= {yosys_basedir}/yosys") + print("") print("export YOSYS_MAX_THREADS := 4") if extra: @@ -128,7 +128,7 @@ def generate_custom(callback, extra=None): callback() def generate_autotest_file(test_file, commands): - cmd = f"../tools/autotest.sh -G -j ${{SEEDOPT}} ${{EXTRA_FLAGS}} {test_file}; \\\n{commands}" + cmd = f"../tools/autotest.sh -G -j ${{SEEDOPT}} -Y ${{YOSYS}} ${{EXTRA_FLAGS}} {test_file}; \\\n{commands}" generate_target(test_file, cmd) def generate_autotest(pattern, extra_flags, cmds=""): diff --git a/tests/liberty/generate_mk.py b/tests/liberty/generate_mk.py index b2559cced..45a26caa9 100644 --- a/tests/liberty/generate_mk.py +++ b/tests/liberty/generate_mk.py @@ -36,8 +36,7 @@ def main(): lib_tests() ys_tests() - gen_tests_makefile.generate_custom(callback, - [f"YOSYS_FILTERLIB ?= {gen_tests_makefile.yosys_basedir}/yosys-filterlib"]) + gen_tests_makefile.generate_custom(callback) if __name__ == "__main__": diff --git a/tests/memfile/generate_mk.py b/tests/memfile/generate_mk.py index e6351bc51..a43257d35 100644 --- a/tests/memfile/generate_mk.py +++ b/tests/memfile/generate_mk.py @@ -40,19 +40,19 @@ def create_tests(): gen_tests_makefile.generate_cmd_test("child_content1", [ f"{setup}", - 'cd temp && ../$(YOSYS) -qp "read_verilog -defer ../memory.v; ' + 'cd temp && $(YOSYS) -qp "read_verilog -defer ../memory.v; ' 'chparam -set MEMFILE \\"content1.dat\\" memory"' ]) gen_tests_makefile.generate_cmd_test("child_content2_temp", [ f"{setup}", - 'cd temp && ../$(YOSYS) -qp "read_verilog -defer ../memory.v; ' + 'cd temp && $(YOSYS) -qp "read_verilog -defer ../memory.v; ' 'chparam -set MEMFILE \\"temp/content2.dat\\" memory"' ]) gen_tests_makefile.generate_cmd_test("child_content2_direct", [ f"{setup}", - 'cd temp && ../$(YOSYS) -qp "read_verilog -defer ../memory.v; ' + 'cd temp && $(YOSYS) -qp "read_verilog -defer ../memory.v; ' 'chparam -set MEMFILE \\"temp/content2.dat\\" memory"' ]) diff --git a/tests/memlib/generate_mk.py b/tests/memlib/generate_mk.py index 5f846a573..13b62b1d8 100644 --- a/tests/memlib/generate_mk.py +++ b/tests/memlib/generate_mk.py @@ -1574,7 +1574,7 @@ def create_tests(): for lib in t.libs: libs_args += f" -l memlib_{lib}.v" cmd = ( - f"../tools/autotest.sh -G -j ${{SEEDOPT}} ${{EXTRA_FLAGS}} " + f"../tools/autotest.sh -G -j ${{SEEDOPT}} -Y ${{YOSYS}} " f"-p 'script ../t_{t.name}.ys'" f"{libs_args} " f"t_{t.name}.v || (cat t_{t.name}.err; exit 1)" diff --git a/tests/rpc/frontend.py b/tests/rpc/frontend.py index 2729cd472..6619fb153 100644 --- a/tests/rpc/frontend.py +++ b/tests/rpc/frontend.py @@ -87,7 +87,7 @@ def main(): sock.bind(args.path) try: sock.listen(1) - ys_proc = subprocess.Popen(["../../yosys", "-ql", "unix.log", "-p", "connect_rpc -path {}; read_verilog design.v; hierarchy -top top; flatten; select -assert-count 1 t:$neg".format(args.path)]) + ys_proc = subprocess.Popen([os.environ.get("YOSYS", "../../yosys"), "-ql", "unix.log", "-p", "connect_rpc -path {}; read_verilog design.v; hierarchy -top top; flatten; select -assert-count 1 t:$neg".format(args.path)]) conn, addr = sock.accept() file = conn.makefile("rw") while True: diff --git a/tests/rtlil/roundtrip-design.sh b/tests/rtlil/roundtrip-design.sh index 018e363c7..5d6f62c41 100644 --- a/tests/rtlil/roundtrip-design.sh +++ b/tests/rtlil/roundtrip-design.sh @@ -1,10 +1,9 @@ set -euo pipefail -YS=../../yosys mkdir -p temp -$YS -p "read_verilog -sv everything.v; write_rtlil temp/roundtrip-design-push.il; design -push; design -pop; write_rtlil temp/roundtrip-design-pop.il" +${YOSYS} -p "read_verilog -sv everything.v; write_rtlil temp/roundtrip-design-push.il; design -push; design -pop; write_rtlil temp/roundtrip-design-pop.il" diff temp/roundtrip-design-push.il temp/roundtrip-design-pop.il -$YS -p "read_verilog -sv everything.v; write_rtlil temp/roundtrip-design-save.il; design -save foo; design -load foo; write_rtlil temp/roundtrip-design-load.il" +${YOSYS} -p "read_verilog -sv everything.v; write_rtlil temp/roundtrip-design-save.il; design -save foo; design -load foo; write_rtlil temp/roundtrip-design-load.il" diff temp/roundtrip-design-save.il temp/roundtrip-design-load.il diff --git a/tests/rtlil/roundtrip-text.sh b/tests/rtlil/roundtrip-text.sh index 35417cff7..7d562723b 100644 --- a/tests/rtlil/roundtrip-text.sh +++ b/tests/rtlil/roundtrip-text.sh @@ -1,5 +1,4 @@ set -euo pipefail -YS=../../yosys mkdir -p temp @@ -11,7 +10,7 @@ remove_empty_lines() { } # write_rtlil and dump are equivalent -$YS -p "read_verilog -sv everything.v; copy alu zzz; proc zzz; dump -o temp/roundtrip-text.dump.il; write_rtlil temp/roundtrip-text.write.il" +${YOSYS} -p "read_verilog -sv everything.v; copy alu zzz; proc zzz; dump -o temp/roundtrip-text.dump.il; write_rtlil temp/roundtrip-text.write.il" remove_empty_lines temp/roundtrip-text.dump.il remove_empty_lines temp/roundtrip-text.write.il # Trim first line ("Generated by Yosys ...") @@ -19,13 +18,13 @@ tail -n +2 temp/roundtrip-text.write.il > temp/roundtrip-text.write-nogen.il diff temp/roundtrip-text.dump.il temp/roundtrip-text.write-nogen.il # Loading and writing it out again doesn't change the RTLIL -$YS -p "read_rtlil temp/roundtrip-text.dump.il; write_rtlil temp/roundtrip-text.reload.il" +${YOSYS} -p "read_rtlil temp/roundtrip-text.dump.il; write_rtlil temp/roundtrip-text.reload.il" remove_empty_lines temp/roundtrip-text.reload.il tail -n +2 temp/roundtrip-text.reload.il > temp/roundtrip-text.reload-nogen.il diff temp/roundtrip-text.dump.il temp/roundtrip-text.reload-nogen.il # Hashing differences don't change the RTLIL -$YS --hash-seed=2345678 -p "read_rtlil temp/roundtrip-text.dump.il; write_rtlil temp/roundtrip-text.reload-hash.il" +${YOSYS} --hash-seed=2345678 -p "read_rtlil temp/roundtrip-text.dump.il; write_rtlil temp/roundtrip-text.reload-hash.il" remove_empty_lines temp/roundtrip-text.reload-hash.il tail -n +2 temp/roundtrip-text.reload-hash.il > temp/roundtrip-text.reload-hash-nogen.il diff temp/roundtrip-text.dump.il temp/roundtrip-text.reload-hash-nogen.il diff --git a/tests/sdc/side-effects.sh b/tests/sdc/side-effects.sh index 88d6154a1..23b1a601e 100755 --- a/tests/sdc/side-effects.sh +++ b/tests/sdc/side-effects.sh @@ -1,4 +1,4 @@ #!/usr/bin/env bash -../../yosys -p 'read_verilog alu_sub.v; proc; hierarchy -auto-top; sdc side-effects.sdc' | grep 'This should print something: +${YOSYS} -p 'read_verilog alu_sub.v; proc; hierarchy -auto-top; sdc side-effects.sdc' | grep 'This should print something: YOSYS_SDC_MAGIC_NODE_0' diff --git a/tests/sdc/unknown-getter.sh b/tests/sdc/unknown-getter.sh index 9038834c6..acf5f5cf1 100755 --- a/tests/sdc/unknown-getter.sh +++ b/tests/sdc/unknown-getter.sh @@ -2,4 +2,4 @@ set -euo pipefail -! ../../yosys -p 'read_verilog alu_sub.v; proc; hierarchy -auto-top; sdc get_foo.sdc' 2>&1 | grep 'Unknown getter' +! ${YOSYS} -p 'read_verilog alu_sub.v; proc; hierarchy -auto-top; sdc get_foo.sdc' 2>&1 | grep 'Unknown getter' diff --git a/tests/sva/runtest.sh b/tests/sva/runtest.sh index 7692a5f9a..db6c37011 100644 --- a/tests/sva/runtest.sh +++ b/tests/sva/runtest.sh @@ -59,7 +59,7 @@ generate_sby() { if [ -f $prefix.ys ]; then set -x - $PWD/../../yosys -q -e "Assert .* failed." -s $prefix.ys + ${YOSYS} -q -e "Assert .* failed." -s $prefix.ys elif [ -f $prefix.sv ]; then generate_sby pass > ${prefix}_pass.sby generate_sby fail > ${prefix}_fail.sby @@ -67,8 +67,8 @@ elif [ -f $prefix.sv ]; then # Check that SBY is up to date enough for this yosys version if sby --help | grep -q -e '--status'; then set -x - sby --yosys $PWD/../../yosys -f ${prefix}_pass.sby - sby --yosys $PWD/../../yosys -f ${prefix}_fail.sby + sby --yosys ${YOSYS} -f ${prefix}_pass.sby + sby --yosys ${YOSYS} -f ${prefix}_fail.sby else echo "sva test '${prefix}' requires an up to date SBY, skipping" fi @@ -78,7 +78,7 @@ else # Check that SBY is up to date enough for this yosys version if sby --help | grep -q -e '--status'; then set -x - sby --yosys $PWD/../../yosys -f ${prefix}.sby + sby --yosys ${YOSYS} -f ${prefix}.sby else echo "sva test '${prefix}' requires an up to date SBY, skipping" fi diff --git a/tests/techmap/bug5495.sh b/tests/techmap/bug5495.sh index 476727755..d1ade0fb2 100755 --- a/tests/techmap/bug5495.sh +++ b/tests/techmap/bug5495.sh @@ -5,7 +5,7 @@ if ! which timeout ; then exit 0 fi -if ! timeout 10 ../../yosys bug5495.v -p 'hierarchy; techmap; abc -script bug5495.abc' ; then +if ! timeout 10 ${YOSYS} bug5495.v -p 'hierarchy; techmap; abc -script bug5495.abc' ; then echo "Yosys failed to complete" exit 1 fi diff --git a/tests/techmap/mem_simple_4x1_runtest.sh b/tests/techmap/mem_simple_4x1_runtest.sh index d7738aafb..4d8494a6e 100644 --- a/tests/techmap/mem_simple_4x1_runtest.sh +++ b/tests/techmap/mem_simple_4x1_runtest.sh @@ -1,3 +1,3 @@ #!/usr/bin/env bash -exec ../tools/autotest.sh -G -j $@ -p 'proc; opt; memory -nomap; techmap -map ../mem_simple_4x1_map.v;; techmap; opt; abc;; stat' mem_simple_4x1_uut.v +exec ../tools/autotest.sh -G -Y ${YOSYS} -j $@ -p 'proc; opt; memory -nomap; techmap -map ../mem_simple_4x1_map.v;; techmap; opt; abc;; stat' mem_simple_4x1_uut.v diff --git a/tests/techmap/recursive_runtest.sh b/tests/techmap/recursive_runtest.sh index 564d678fa..541e323f7 100644 --- a/tests/techmap/recursive_runtest.sh +++ b/tests/techmap/recursive_runtest.sh @@ -1,3 +1,3 @@ set -e -../../yosys -p 'read_verilog recursive.v; hierarchy -top top; techmap -map recursive_map.v -max_iter 1; select -assert-count 2 t:sub; select -assert-count 2 t:bar' +${YOSYS} -p 'read_verilog recursive.v; hierarchy -top top; techmap -map recursive_map.v -max_iter 1; select -assert-count 2 t:sub; select -assert-count 2 t:bar' diff --git a/tests/tools/autotest.sh b/tests/tools/autotest.sh index 0fd80cdaf..47c199cf7 100755 --- a/tests/tools/autotest.sh +++ b/tests/tools/autotest.sh @@ -24,6 +24,7 @@ warn_iverilog_git=false firrtl2verilog="" xfirrtl="../xfirrtl" abcprog="$toolsdir/../../yosys-abc" +yosysprog="$toolsdir/../../yosys" exec {lock}<"$toolsdir"; flock "$lock" 1>&2 if [ ! -f "$toolsdir/cmp_tbdata" -o "$toolsdir/cmp_tbdata.c" -nt "$toolsdir/cmp_tbdata" ]; then @@ -31,7 +32,7 @@ if [ ! -f "$toolsdir/cmp_tbdata" -o "$toolsdir/cmp_tbdata.c" -nt "$toolsdir/cmp_ fi flock -u "$lock"; exec {lock}>&- -while getopts xmGl:wkjvref:s:p:n:S:I:A:-: opt; do +while getopts xmGl:wkjvref:s:p:n:S:I:A:Y:-: opt; do case "$opt" in x) use_xsim=true ;; @@ -70,6 +71,8 @@ while getopts xmGl:wkjvref:s:p:n:S:I:A:-: opt; do minclude_opts="$minclude_opts +incdir+$OPTARG" ;; A) abcprog="$OPTARG" ;; + Y) + yosysprog="$OPTARG" ;; -) case "${OPTARG}" in xfirrtl) @@ -159,7 +162,7 @@ do fi if [ ! -f ../${bn}_tb.v ]; then - "$toolsdir"/../../yosys -f "$frontend $include_opts -D_AUTOTB" -b "test_autotb $autotb_opts" -o ${bn}_tb.v ${bn}_ref.${refext} + $yosysprog -f "$frontend $include_opts -D_AUTOTB" -b "test_autotb $autotb_opts" -o ${bn}_tb.v ${bn}_ref.${refext} else cp ../${bn}_tb.v ${bn}_tb.v fi @@ -173,7 +176,7 @@ do test_count=0 test_passes() { - "$toolsdir"/../../yosys -b "verilog $backend_opts" -o ${bn}_syn${test_count}.v "$@" + $yosysprog -b "verilog $backend_opts" -o ${bn}_syn${test_count}.v "$@" touch ${bn}.iverilog compile_and_run ${bn}_tb_syn${test_count} ${bn}_out_syn${test_count} \ ${bn}_tb.v ${bn}_syn${test_count}.v "${libs[@]}" \ @@ -203,7 +206,7 @@ do test_passes -f "$frontend $include_opts" -p "hierarchy; synth -run coarse; techmap; opt; abc -dff" ${bn}_ref.${refext} if [ -n "$firrtl2verilog" ]; then if test -z "$xfirrtl" || ! grep "$fn" "$xfirrtl" ; then - "$toolsdir"/../../yosys -b "firrtl" -o ${bn}_ref.fir -f "$frontend $include_opts" -p "prep; proc; opt -nodffe -nosdff; fsm; opt; memory; opt -full -fine; pmuxtree" ${bn}_ref.${refext} + $yosysprog -b "firrtl" -o ${bn}_ref.fir -f "$frontend $include_opts" -p "prep; proc; opt -nodffe -nosdff; fsm; opt; memory; opt -full -fine; pmuxtree" ${bn}_ref.${refext} $firrtl2verilog -i ${bn}_ref.fir -o ${bn}_ref.fir.v test_passes -f "$frontend $include_opts" -p "hierarchy; proc; opt -nodffe -nosdff; fsm; opt; memory; opt -full -fine" ${bn}_ref.fir.v fi diff --git a/tests/various/async.sh b/tests/various/async.sh index 9d956c1cd..df56f6427 100644 --- a/tests/various/async.sh +++ b/tests/various/async.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash set -ex -../../yosys -q -o async_syn.v -r uut -p 'synth; rename uut syn' async.v -../../yosys -q -o async_prp.v -r uut -p 'prep; rename uut prp' async.v -../../yosys -q -o async_a2s.v -r uut -p 'prep; async2sync; rename uut a2s' async.v -../../yosys -q -o async_ffl.v -r uut -p 'prep; clk2fflogic; rename uut ffl' async.v +${YOSYS} -q -o async_syn.v -r uut -p 'synth; rename uut syn' async.v +${YOSYS} -q -o async_prp.v -r uut -p 'prep; rename uut prp' async.v +${YOSYS} -q -o async_a2s.v -r uut -p 'prep; async2sync; rename uut a2s' async.v +${YOSYS} -q -o async_ffl.v -r uut -p 'prep; clk2fflogic; rename uut ffl' async.v iverilog -o async_sim -DTESTBENCH async.v async_???.v vvp -N async_sim > async.out tail async.out diff --git a/tests/various/chparam.sh b/tests/various/chparam.sh index 0c237112e..d793dfc5b 100644 --- a/tests/various/chparam.sh +++ b/tests/various/chparam.sh @@ -35,18 +35,18 @@ module top #( endmodule EOT -if ../../yosys -q -p 'verific -sv chparam1.sv'; then - ../../yosys -q -p 'verific -sv chparam1.sv; hierarchy -chparam X 123123123 -top top; prep -flatten' \ +if ${YOSYS} -q -p 'verific -sv chparam1.sv'; then + ${YOSYS} -q -p 'verific -sv chparam1.sv; hierarchy -chparam X 123123123 -top top; prep -flatten' \ -p 'async2sync' \ -p 'sat -verify -prove-asserts -show-ports -set din[0] 1' \ -p 'sat -falsify -prove-asserts -show-ports -set din[0] 0' - ../../yosys -q -p 'verific -sv chparam2.sv; hierarchy -chparam X 123123123 -top top; prep -flatten' \ + ${YOSYS} -q -p 'verific -sv chparam2.sv; hierarchy -chparam X 123123123 -top top; prep -flatten' \ -p 'async2sync' \ -p 'sat -verify -prove-asserts -show-ports -set din[0] 1' \ -p 'sat -falsify -prove-asserts -show-ports -set din[0] 0' fi -../../yosys -q -p 'read_verilog -sv chparam2.sv; hierarchy -chparam X 123123123 -top top; prep -flatten' \ +${YOSYS} -q -p 'read_verilog -sv chparam2.sv; hierarchy -chparam X 123123123 -top top; prep -flatten' \ -p 'async2sync' \ -p 'sat -verify -prove-asserts -show-ports -set din[0] 1' \ -p 'sat -falsify -prove-asserts -show-ports -set din[0] 0' diff --git a/tests/various/clk2fflogic_effects.sh b/tests/various/clk2fflogic_effects.sh index 0d133ffdd..6d0046161 100755 --- a/tests/various/clk2fflogic_effects.sh +++ b/tests/various/clk2fflogic_effects.sh @@ -3,14 +3,14 @@ set -e # TODO: when sim gets native $check support, remove the -DNO_ASSERT here echo Running yosys sim -../../yosys -q -p " +${YOSYS} -q -p " read_verilog -formal -DNO_ASSERT clk2fflogic_effects.sv hierarchy -top top; proc;; tee -q -o clk2fflogic_effects.sim.log sim -q -n 32 " echo Running yosys clk2fflogic sim -../../yosys -q -p " +${YOSYS} -q -p " read_verilog -formal clk2fflogic_effects.sv hierarchy -top top; proc;; clk2fflogic;; diff --git a/tests/various/ezcmdline_plugin.sh b/tests/various/ezcmdline_plugin.sh index cad0475a8..91579d7cb 100644 --- a/tests/various/ezcmdline_plugin.sh +++ b/tests/various/ezcmdline_plugin.sh @@ -4,9 +4,9 @@ DIR=$(cd "$(dirname "$0")" && pwd) BASEDIR=$(cd "$DIR/../.." && pwd) rm -f "$DIR/ezcmdline_plugin.so" chmod +x "$DIR/ezcmdline_dummy_solver" -CXXFLAGS=$("$BASEDIR/yosys-config" --cxxflags) -DATDIR=$("$BASEDIR/yosys-config" --datdir) +CXXFLAGS=$(${YOSYS_CONFIG} --cxxflags) +DATDIR=$(${YOSYS_CONFIG} --datdir) DATDIR=${DATDIR//\//\\\/} CXXFLAGS=${CXXFLAGS//$DATDIR/..\/..\/share} -"$BASEDIR/yosys-config" --exec --cxx ${CXXFLAGS} -I"$BASEDIR" --ldflags -shared -o "$DIR/ezcmdline_plugin.so" "$DIR/ezcmdline_plugin.cc" -"$BASEDIR/yosys" -m "$DIR/ezcmdline_plugin.so" -p "ezcmdline_test -cmd $DIR/ezcmdline_dummy_solver" | grep -q "ezcmdline_test passed!" +${YOSYS_CONFIG} --exec --cxx ${CXXFLAGS} -I"$BASEDIR" --ldflags -shared -o "$DIR/ezcmdline_plugin.so" "$DIR/ezcmdline_plugin.cc" +${YOSYS} -m "$DIR/ezcmdline_plugin.so" -p "ezcmdline_test -cmd $DIR/ezcmdline_dummy_solver" | grep -q "ezcmdline_test passed!" diff --git a/tests/various/hierarchy.sh b/tests/various/hierarchy.sh index 9dbd1c89f..637f4be87 100644 --- a/tests/various/hierarchy.sh +++ b/tests/various/hierarchy.sh @@ -4,7 +4,7 @@ set -e echo -n " TOP first - " -../../yosys -s - <<- EOY | grep "Automatically selected TOP as design top module" +${YOSYS} -s - <<- EOY | grep "Automatically selected TOP as design top module" read_verilog << EOV module TOP(a, y); input a; @@ -23,7 +23,7 @@ echo -n " TOP first - " EOY echo -n " TOP last - " -../../yosys -s - <<- EOY | grep "Automatically selected TOP as design top module" +${YOSYS} -s - <<- EOY | grep "Automatically selected TOP as design top module" read_verilog << EOV module aoi12(a, y); input a; @@ -42,7 +42,7 @@ echo -n " TOP last - " EOY echo -n " no explicit top - " -../../yosys -s - <<- EOY | grep "Automatically selected noTop as design top module." +${YOSYS} -s - <<- EOY | grep "Automatically selected noTop as design top module." read_verilog << EOV module aoi12(a, y); input a; diff --git a/tests/various/logger_cmd_error.sh b/tests/various/logger_cmd_error.sh index dd0585965..1a1ca474c 100755 --- a/tests/various/logger_cmd_error.sh +++ b/tests/various/logger_cmd_error.sh @@ -2,7 +2,7 @@ trap 'echo "ERROR in logger_cmd_error.sh" >&2; exit 1' ERR -(../../yosys -v 3 -C <&1` + output=`${YOSYS} -q "$@" 2>&1` if [ $? -ne 1 ]; then fail "exit code for '$desc' was not 1" fi diff --git a/tests/various/plugin.sh b/tests/various/plugin.sh index 75b4c9e56..4e645ee17 100644 --- a/tests/various/plugin.sh +++ b/tests/various/plugin.sh @@ -1,12 +1,12 @@ set -e rm -f plugin.so rm -rf plugin_search -CXXFLAGS=$(../../yosys-config --cxxflags) -DATDIR=$(../../yosys-config --datdir) +CXXFLAGS=$(${YOSYS_CONFIG} --cxxflags) +DATDIR=$(${YOSYS_CONFIG} --datdir) DATDIR=${DATDIR//\//\\\/} CXXFLAGS=${CXXFLAGS//$DATDIR/..\/..\/share} -../../yosys-config --exec --cxx ${CXXFLAGS} --ldflags -shared -o plugin.so plugin.cc -../../yosys -m ./plugin.so -p "test" | grep -q "Plugin test passed!" +${YOSYS_CONFIG} --exec --cxx ${CXXFLAGS} --ldflags -shared -o plugin.so plugin.cc +${YOSYS} -m ./plugin.so -p "test" | grep -q "Plugin test passed!" mkdir -p plugin_search mv plugin.so plugin_search/plugin.so -YOSYS_PLUGIN_PATH=$PWD/plugin_search ../../yosys -m plugin.so -p "test" | grep -q "Plugin test passed!" +YOSYS_PLUGIN_PATH=$PWD/plugin_search ${YOSYS} -m plugin.so -p "test" | grep -q "Plugin test passed!" diff --git a/tests/various/sv_implicit_ports.sh b/tests/various/sv_implicit_ports.sh index 5266fffe5..ace95b3ba 100755 --- a/tests/various/sv_implicit_ports.sh +++ b/tests/various/sv_implicit_ports.sh @@ -3,7 +3,7 @@ trap 'echo "ERROR in sv_implicit_ports.sh" >&2; exit 1' ERR # Simple case -../../yosys -f "verilog -sv" -qp "prep -flatten -top top; select -assert-count 1 t:\$add" - <&1 | grep -F "ERROR: No matching wire for implicit port connection \`b' of cell top.add_i (add)." > /dev/null # Incorrectly sized wire -((../../yosys -f "verilog -sv" -qp "hierarchy -top top" - || true) <&1 | grep -F "ERROR: Width mismatch between wire (7 bits) and port (8 bits) for implicit port connection \`b' of cell top.add_i (add)." > /dev/null # Defaults -../../yosys -f "verilog -sv" -qp "prep -flatten -top top; select -assert-count 1 t:\$add" - <&1 | grep -F "ERROR: Width mismatch between wire (8 bits) and port (6 bits) for implicit port connection \`q' of cell top.add_i (add)." > /dev/null # Mixed implicit and explicit 1 -../../yosys -f "verilog -sv" -qp "prep -flatten -top top; select -assert-count 1 t:\$add" - <&2; exit 1' ERR # Good case -../../yosys -f "verilog -sv" -qp proc - <&1 | grep -F ":3: ERROR: syntax error, unexpected '@'" > /dev/null # Incorrect use of always_comb -((../../yosys -f "verilog -sv" -qp proc -|| true) <&1 | grep -F "ERROR: Latch inferred for signal \`\\top.\\q' from always_comb process" > /dev/null # Incorrect use of always_latch -((../../yosys -f "verilog -sv" -qp proc -|| true) <&1 | grep -F "ERROR: No latch inferred for signal \`\\top.\\q' from always_latch process" > /dev/null # Incorrect use of always_ff -((../../yosys -f "verilog -sv" -qp proc -|| true) < $include -$yosys $test $source +$yosyscmd $test $source # include local to cwd mkdir -p $subdir cp $source $subdir -$yosys $test $subdir/$source +$yosyscmd $test $subdir/$source # include local to source mv $include $subdir -$yosys $test $subdir/$source +$yosyscmd $test $subdir/$source # include local to source, and source is given as an absolute path -$yosys $test $(pwd)/$subdir/$source +$yosyscmd $test $(pwd)/$subdir/$source diff --git a/tests/xprop/test.py b/tests/xprop/test.py index e2cddf679..94c52aecc 100644 --- a/tests/xprop/test.py +++ b/tests/xprop/test.py @@ -47,7 +47,7 @@ if "clean" in steps: def yosys(command): - subprocess.check_call(["../../../yosys", "-Qp", command]) + subprocess.check_call([os.environ.get("YOSYS", "../../yosys"), "-Qp", command]) def remove(file): try: From 15e09163cdc3d45c9c80933dbf7bff21d5737f96 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 19 May 2026 14:29:06 +0200 Subject: [PATCH 054/354] Do not use Makefile.conf --- tests/aiger/generate_mk.py | 5 ----- tests/common.mk | 2 ++ tests/gen_tests_makefile.py | 6 ------ 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/tests/aiger/generate_mk.py b/tests/aiger/generate_mk.py index e6f3f4091..47e94884a 100644 --- a/tests/aiger/generate_mk.py +++ b/tests/aiger/generate_mk.py @@ -55,11 +55,6 @@ def create_tests(): ])) extra = [ - "ifneq ($(ABCEXTERNAL),)", - "ABC ?= $(ABCEXTERNAL)", - "else", - f"ABC ?= {gen_tests_makefile.yosys_basedir}/yosys-abc", - "endif", "SHELL := /usr/bin/env bash", ] diff --git a/tests/common.mk b/tests/common.mk index 59ea599c0..1636a880b 100644 --- a/tests/common.mk +++ b/tests/common.mk @@ -5,10 +5,12 @@ YOSYS ?= $(BUILD_DIR)/yosys ABC ?= $(BUILD_DIR)/yosys-abc YOSYS_FILTERLIB ?= $(BUILD_DIR)/yosys-filterlib YOSYS_CONFIG ?= $(BUILD_DIR)/yosys-config +YOSYS_MAX_THREADS ?= 4 export YOSYS export YOSYS_CONFIG export ABC +export YOSYS_MAX_THREADS all: diff --git a/tests/gen_tests_makefile.py b/tests/gen_tests_makefile.py index 77602a9a0..034883a2c 100644 --- a/tests/gen_tests_makefile.py +++ b/tests/gen_tests_makefile.py @@ -94,12 +94,6 @@ def generate_tests(argv, cmds): def print_header(extra=None): print(f"include {common_mk}") - print(f"ifneq ($(wildcard {yosys_basedir}/Makefile.conf),)") - print(f"include {yosys_basedir}/Makefile.conf") - print(f"endif") - - print("") - print("export YOSYS_MAX_THREADS := 4") if extra: for line in extra: print(line) From 2b3f4c37f5bebc06e56fb8be74b96e31f13a0d99 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 19 May 2026 14:42:08 +0200 Subject: [PATCH 055/354] Fix functional tests --- tests/common.mk | 2 ++ tests/functional/test_smtbmc_witness_mismatch.py | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/common.mk b/tests/common.mk index 1636a880b..1d70c20a9 100644 --- a/tests/common.mk +++ b/tests/common.mk @@ -5,10 +5,12 @@ YOSYS ?= $(BUILD_DIR)/yosys ABC ?= $(BUILD_DIR)/yosys-abc YOSYS_FILTERLIB ?= $(BUILD_DIR)/yosys-filterlib YOSYS_CONFIG ?= $(BUILD_DIR)/yosys-config +YOSYS_SMTBMC ?= $(BUILD_DIR)/yosys-smtbmc YOSYS_MAX_THREADS ?= 4 export YOSYS export YOSYS_CONFIG +export YOSYS_SMTBMC export ABC export YOSYS_MAX_THREADS diff --git a/tests/functional/test_smtbmc_witness_mismatch.py b/tests/functional/test_smtbmc_witness_mismatch.py index f13620f1d..60cd87073 100644 --- a/tests/functional/test_smtbmc_witness_mismatch.py +++ b/tests/functional/test_smtbmc_witness_mismatch.py @@ -1,3 +1,4 @@ +import os import json import shutil import subprocess @@ -21,7 +22,7 @@ def write_smt2(tmp_path, verilog_text): vfile = tmp_path / "design.v" smt2 = tmp_path / "design.smt2" vfile.write_text(verilog_text) - run([base_path / "yosys", "-Q", "-p", + run([os.environ.get("YOSYS", "../../yosys"), "-Q", "-p", f"read_verilog {vfile}; prep -top top; write_smt2 {smt2}"]) return smt2 @@ -61,7 +62,7 @@ def write_yw(yw_path, signals, bits): def run_smtbmc(smt2_path, yw_path): """Run yosys-smtbmc on the SMT2 file with a witness trace.""" cmd = [ - base_path / "yosys-smtbmc", + os.environ.get("YOSYS_SMTBMC", "../../yosys-smtbmc"), "-s", "z3", "-m", "top", "--check-witness", From 07924a3c6219374cdb58db01230f1e7636cc72a2 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 19 May 2026 15:15:41 +0200 Subject: [PATCH 056/354] Use common.mk for sva tests as well --- tests/sva/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/sva/Makefile b/tests/sva/Makefile index dcabcf42b..d8c206664 100644 --- a/tests/sva/Makefile +++ b/tests/sva/Makefile @@ -1,3 +1,5 @@ +OVERRIDE_MAIN=1 +include ../common.mk TESTS = $(sort $(basename $(wildcard *.sv)) $(basename $(wildcard *.vhd))) From 4c8e61a52bccc8b889b7390d705df47302afbd1e Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 19 May 2026 16:08:21 +0200 Subject: [PATCH 057/354] Expose SBY binary location --- tests/common.mk | 2 ++ tests/sva/runtest.sh | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/common.mk b/tests/common.mk index 1d70c20a9..ef6982514 100644 --- a/tests/common.mk +++ b/tests/common.mk @@ -1,6 +1,7 @@ ROOT_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) BUILD_DIR ?= $(ROOT_DIR)/.. +SBY ?= sby YOSYS ?= $(BUILD_DIR)/yosys ABC ?= $(BUILD_DIR)/yosys-abc YOSYS_FILTERLIB ?= $(BUILD_DIR)/yosys-filterlib @@ -12,6 +13,7 @@ export YOSYS export YOSYS_CONFIG export YOSYS_SMTBMC export ABC +export SBY export YOSYS_MAX_THREADS all: diff --git a/tests/sva/runtest.sh b/tests/sva/runtest.sh index db6c37011..6a855188f 100644 --- a/tests/sva/runtest.sh +++ b/tests/sva/runtest.sh @@ -65,10 +65,10 @@ elif [ -f $prefix.sv ]; then generate_sby fail > ${prefix}_fail.sby # Check that SBY is up to date enough for this yosys version - if sby --help | grep -q -e '--status'; then + if ${SBY} --help | grep -q -e '--status'; then set -x - sby --yosys ${YOSYS} -f ${prefix}_pass.sby - sby --yosys ${YOSYS} -f ${prefix}_fail.sby + ${SBY} --yosys ${YOSYS} -f ${prefix}_pass.sby + ${SBY} --yosys ${YOSYS} -f ${prefix}_fail.sby else echo "sva test '${prefix}' requires an up to date SBY, skipping" fi @@ -76,9 +76,9 @@ else generate_sby pass > ${prefix}.sby # Check that SBY is up to date enough for this yosys version - if sby --help | grep -q -e '--status'; then + if ${SBY} --help | grep -q -e '--status'; then set -x - sby --yosys ${YOSYS} -f ${prefix}.sby + ${SBY} --yosys ${YOSYS} -f ${prefix}.sby else echo "sva test '${prefix}' requires an up to date SBY, skipping" fi From f69a5fc0779ba91eb92a6152dc33d29523e43347 Mon Sep 17 00:00:00 2001 From: nella Date: Wed, 29 Apr 2026 11:21:26 +0200 Subject: [PATCH 058/354] Elim equiv bits. --- passes/opt/opt_dff.cc | 284 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 283 insertions(+), 1 deletion(-) diff --git a/passes/opt/opt_dff.cc b/passes/opt/opt_dff.cc index 709b5fc4c..cc669f902 100644 --- a/passes/opt/opt_dff.cc +++ b/passes/opt/opt_dff.cc @@ -919,6 +919,286 @@ struct OptDffWorker return did_something; } + + struct EqBit { + Cell *cell; + int idx; + SigBit q; + }; + + struct SigKey { + enum Flag : uint16_t { + InitOne = 1u << 0, + InitX = 1u << 1, + PolClk = 1u << 2, + PolCe = 1u << 3, + PolSrst = 1u << 4, + PolArst = 1u << 5, + PolAload = 1u << 6, + PolClr = 1u << 7, + PolSet = 1u << 8, + CeOverSrst = 1u << 9, + }; + + SigBit clk, ce, srst, arst, aload, clr, set; + IdString cell_type; // for SR + uint16_t flags; + + bool operator==(const SigKey &o) const { + return flags == o.flags && clk == o.clk && ce == o.ce && srst == o.srst && arst == o.arst + && aload == o.aload && clr == o.clr && set == o.set && cell_type == o.cell_type; + } + + Hasher hash_into(Hasher h) const { + h.eat(flags); + h.eat(clk); + h.eat(ce); + h.eat(srst); + h.eat(arst); + h.eat(aload); + h.eat(clr); + h.eat(set); + h.eat(cell_type); + return h; + } + }; + + bool is_def(State s) { + return s == State::S0 || s == State::S1; + } + + int sat_mux(QuickConeSat &qcsat, int s, int a, int b) { + return qcsat.ez->OR(qcsat.ez->AND(s, a), qcsat.ez->AND(qcsat.ez->NOT(s), b)); + } + + int sat_const(QuickConeSat &qcsat, State v) { + return v == State::S1 ? qcsat.ez->CONST_TRUE : qcsat.ez->CONST_FALSE; + } + + bool run_eqbits() + { + std::vector bits; + std::vector keys; + dict ff_for_cell; + + // Collect FF bits eligible for merging + for (auto cell : module->selected_cells()) { + if (!cell->is_builtin_ff()) + continue; + + FfData ff(&initvals, cell); + if (!ff.has_clk && !ff.has_gclk) + continue; + + ff_for_cell.emplace(cell, ff); + + for (int i = 0; i < ff.width; i++) { + // X value + if (ff.has_srst && !is_def(ff.val_srst[i])) continue; + if (ff.has_arst && !is_def(ff.val_arst[i])) continue; + + // Missing anchor + bool def_init = is_def(ff.val_init[i]); + if (!def_init && !ff.has_srst && !ff.has_arst) + continue; + + SigKey k = {}; + + // Flags + if (def_init && ff.val_init[i] == State::S1) + k.flags |= SigKey::InitOne; + else if (!def_init) + k.flags |= SigKey::InitX; + + if (ff.has_clk) { + k.clk = ff.sig_clk; + if (ff.pol_clk) k.flags |= SigKey::PolClk; + } + if (ff.has_ce) { + k.ce = ff.sig_ce; + if (ff.pol_ce) k.flags |= SigKey::PolCe; + } + if (ff.has_srst) { + k.srst = ff.sig_srst; + if (ff.pol_srst) k.flags |= SigKey::PolSrst; + if (ff.ce_over_srst) k.flags |= SigKey::CeOverSrst; + } + if (ff.has_arst) { + k.arst = ff.sig_arst; + if (ff.pol_arst) k.flags |= SigKey::PolArst; + } + if (ff.has_aload) { + k.aload = ff.sig_aload; + if (ff.pol_aload) k.flags |= SigKey::PolAload; + } + if (ff.has_sr) { + k.clr = ff.sig_clr[i]; + k.set = ff.sig_set[i]; + k.cell_type = cell->type; + if (ff.pol_clr) k.flags |= SigKey::PolClr; + if (ff.pol_set) k.flags |= SigKey::PolSet; + } + + bits.push_back({cell, i, ff.sig_q[i]}); + keys.push_back(k); + } + } + + if (GetSize(bits) < 2) + return false; + + // Group bits by control signature + dict> buckets; + for (int i = 0; i < GetSize(bits); i++) + buckets[keys[i]].push_back(i); + + std::vector> classes; + classes.reserve(GetSize(buckets)); + for (auto &kv : buckets) + if (GetSize(kv.second) >= 2) + classes.push_back(std::move(kv.second)); + + if (classes.empty()) + return false; + + ModWalker modwalker(module->design, module); + QuickConeSat qcsat(modwalker); + std::vector q_lit(bits.size(), -1); + std::vector n_lit(bits.size(), -1); + + // Per candidate SAT for its next state, model difference + for (auto &cls : classes) { + for (int idx : cls) { + const EqBit &eb = bits[idx]; + const FfData &ff = ff_for_cell.at(eb.cell); + q_lit[idx] = qcsat.importSigBit(eb.q); + int n = qcsat.importSigBit(ff.sig_d[eb.idx]); + + if (ff.has_aload) { + int al = qcsat.importSigBit(ff.sig_aload); + if (!ff.pol_aload) al = qcsat.ez->NOT(al); + int ad = qcsat.importSigBit(ff.sig_ad[eb.idx]); + n = sat_mux(qcsat, al, ad, n); + } + if (ff.has_arst) { + int ar = qcsat.importSigBit(ff.sig_arst); + if (!ff.pol_arst) ar = qcsat.ez->NOT(ar); + n = sat_mux(qcsat, ar, sat_const(qcsat, ff.val_arst[eb.idx]), n); + } + if (ff.has_sr) { + int clr = qcsat.importSigBit(ff.sig_clr[eb.idx]); + if (!ff.pol_clr) clr = qcsat.ez->NOT(clr); + int set = qcsat.importSigBit(ff.sig_set[eb.idx]); + if (!ff.pol_set) set = qcsat.ez->NOT(set); + n = qcsat.ez->AND(qcsat.ez->NOT(clr), qcsat.ez->OR(set, n)); + } + if (ff.has_srst) { + int srst = qcsat.importSigBit(ff.sig_srst); + if (!ff.pol_srst) srst = qcsat.ez->NOT(srst); + n = sat_mux(qcsat,srst, sat_const(qcsat, ff.val_srst[eb.idx]), n); + } + + n_lit[idx] = n; + } + } + + qcsat.prepare(); + bool any_change = false; + bool changed = true; + + // Bit = class rep, split classes whenever two next states differ + while (changed) { + changed = false; + int joint = qcsat.ez->CONST_TRUE; + + for (auto &cls : classes) { + int rep = cls[0]; + for (int k = 1; k < GetSize(cls); k++) + joint = qcsat.ez->AND(joint, qcsat.ez->IFF(q_lit[rep], q_lit[cls[k]])); + } + + std::vector> new_classes; + new_classes.reserve(classes.size()); + + for (auto &cls : classes) { + std::vector> subs; + for (int b : cls) { + bool placed = false; + + // Identical literal - trivially eq + for (auto &sub : subs) { + if (n_lit[sub[0]] == n_lit[b]) { + sub.push_back(b); + placed = true; + break; + } + } + + if (placed) continue; + + for (auto &sub : subs) { + int rep = sub[0]; + int query = qcsat.ez->NOT(qcsat.ez->IFF(n_lit[rep], n_lit[b])); + if (!qcsat.ez->solve(joint, query)) { + sub.push_back(b); + placed = true; + break; + } + } + + if (!placed) + subs.push_back({b}); + } + + if (GetSize(subs) > 1) + changed = true; + for (auto &sub : subs) + if (GetSize(sub) >= 2) + new_classes.push_back(std::move(sub)); + } + + classes = std::move(new_classes); + if (changed) + any_change = true; + } + + if (classes.empty()) + return any_change; + + dict> remove_bits; + + // Drive every non-rep Q from its class rep, drop merged bits from their FFs + for (auto &cls : classes) { + SigBit rep_q = bits[cls[0]].q; + for (int k = 1; k < GetSize(cls); k++) { + const EqBit &eb = bits[cls[k]]; + initvals.remove_init(eb.q); + module->connect(eb.q, rep_q); + remove_bits[eb.cell].insert(eb.idx); + } + } + + for (auto &kv : remove_bits) { + Cell *cell = kv.first; + const std::set &drop = kv.second; + FfData &ff = ff_for_cell.at(cell); + std::vector keep; + + for (int i = 0; i < ff.width; i++) + if (!drop.count(i)) + keep.push_back(i); + + if (keep.empty()) { + module->remove(cell); + } else { + FfData new_ff = ff.slice(keep); + new_ff.cell = cell; + new_ff.emit(); + } + } + + return true; + } }; struct OptDffPass : public Pass { @@ -946,7 +1226,7 @@ struct OptDffPass : public Pass { log(" -simple-dffe\n"); log(" only enables clock enable recognition transform for obvious cases\n"); log("\n"); - log(" -sat\n"); + log(" -sat AAA\n"); log(" additionally invoke SAT solver to detect and remove flip-flops (with\n"); log(" non-constant inputs) that can also be replaced with a constant driver\n"); log("\n"); @@ -987,6 +1267,8 @@ struct OptDffPass : public Pass { did_something = true; if (worker.run_constbits()) did_something = true; + if (opt.sat && worker.run_eqbits()) + did_something = true; } if (did_something) From d85e3f10de301d1bd594042cf71a3d8f15cf4d8a Mon Sep 17 00:00:00 2001 From: nella Date: Wed, 29 Apr 2026 15:55:45 +0200 Subject: [PATCH 059/354] Add tests. --- passes/opt/opt_dff.cc | 4 +- tests/opt/opt_dff_eqbits.ys | 56 ++++++++ tests/opt/opt_dff_eqbits_large.sv | 231 ++++++++++++++++++++++++++++++ tests/opt/opt_dff_eqbits_small.sv | 30 ++++ 4 files changed, 319 insertions(+), 2 deletions(-) create mode 100644 tests/opt/opt_dff_eqbits.ys create mode 100644 tests/opt/opt_dff_eqbits_large.sv create mode 100644 tests/opt/opt_dff_eqbits_small.sv diff --git a/passes/opt/opt_dff.cc b/passes/opt/opt_dff.cc index cc669f902..241ea6888 100644 --- a/passes/opt/opt_dff.cc +++ b/passes/opt/opt_dff.cc @@ -1095,7 +1095,7 @@ struct OptDffWorker if (ff.has_srst) { int srst = qcsat.importSigBit(ff.sig_srst); if (!ff.pol_srst) srst = qcsat.ez->NOT(srst); - n = sat_mux(qcsat,srst, sat_const(qcsat, ff.val_srst[eb.idx]), n); + n = sat_mux(qcsat, srst, sat_const(qcsat, ff.val_srst[eb.idx]), n); } n_lit[idx] = n; @@ -1226,7 +1226,7 @@ struct OptDffPass : public Pass { log(" -simple-dffe\n"); log(" only enables clock enable recognition transform for obvious cases\n"); log("\n"); - log(" -sat AAA\n"); + log(" -sat\n"); log(" additionally invoke SAT solver to detect and remove flip-flops (with\n"); log(" non-constant inputs) that can also be replaced with a constant driver\n"); log("\n"); diff --git a/tests/opt/opt_dff_eqbits.ys b/tests/opt/opt_dff_eqbits.ys new file mode 100644 index 000000000..10e9045e4 --- /dev/null +++ b/tests/opt/opt_dff_eqbits.ys @@ -0,0 +1,56 @@ +# small test case +design -reset +read_verilog -sv opt_dff_eqbits_small.sv +hierarchy -top test_case +techmap +opt_dff -sat +synth +opt_dff -sat +opt_clean -purge + +select -assert-count 2 t:$_SDFF_PN0_ + +# equivalence +design -reset +read_verilog -sv opt_dff_eqbits_small.sv +hierarchy -top test_case +prep +design -save gold + +opt_dff -sat +design -save gate + +design -copy-from gold -as gold test_case +design -copy-from gate -as gate test_case +equiv_make gold gate equiv +equiv_induct equiv +equiv_status -assert + + +# large test case +design -reset +read_verilog -sv opt_dff_eqbits_large.sv +hierarchy -top test_case +techmap +opt_dff -sat +synth +opt_dff -sat +opt_clean -purge + +select -assert-count 6 t:$_SDFFE_PN0P_ + +# equivalence +design -reset +read_verilog -sv opt_dff_eqbits_large.sv +hierarchy -top test_case +prep +design -save gold + +opt_dff -sat +design -save gate + +design -copy-from gold -as gold test_case +design -copy-from gate -as gate test_case +equiv_make gold gate equiv +equiv_induct equiv +equiv_status -assert diff --git a/tests/opt/opt_dff_eqbits_large.sv b/tests/opt/opt_dff_eqbits_large.sv new file mode 100644 index 000000000..4b32c7f8e --- /dev/null +++ b/tests/opt/opt_dff_eqbits_large.sv @@ -0,0 +1,231 @@ +module test_case ( + input wire clk, + input wire rst_n, + input wire [3:0] chan_0_data, + input wire chan_0_vld, + input wire chan_1_rdy, + output wire chan_0_rdy, + output wire [207:0] chan_1_data, + output wire chan_1_vld, + output wire idle +); + wire [12:0] state_init[0:15]; + assign state_init[0] = 13'h0000; + assign state_init[1] = 13'h0000; + assign state_init[2] = 13'h0000; + assign state_init[3] = 13'h0000; + assign state_init[4] = 13'h0000; + assign state_init[5] = 13'h0000; + assign state_init[6] = 13'h0000; + assign state_init[7] = 13'h0000; + assign state_init[8] = 13'h0000; + assign state_init[9] = 13'h0000; + assign state_init[10] = 13'h0000; + assign state_init[11] = 13'h0000; + assign state_init[12] = 13'h0000; + assign state_init[13] = 13'h0000; + assign state_init[14] = 13'h0000; + assign state_init[15] = 13'h0000; + + wire [12:0] ch1_init[0:15]; + assign ch1_init[0] = 13'h0000; + assign ch1_init[1] = 13'h0000; + assign ch1_init[2] = 13'h0000; + assign ch1_init[3] = 13'h0000; + assign ch1_init[4] = 13'h0000; + assign ch1_init[5] = 13'h0000; + assign ch1_init[6] = 13'h0000; + assign ch1_init[7] = 13'h0000; + assign ch1_init[8] = 13'h0000; + assign ch1_init[9] = 13'h0000; + assign ch1_init[10] = 13'h0000; + assign ch1_init[11] = 13'h0000; + assign ch1_init[12] = 13'h0000; + assign ch1_init[13] = 13'h0000; + assign ch1_init[14] = 13'h0000; + assign ch1_init[15] = 13'h0000; + + wire [12:0] mask_1fff[0:15]; + assign mask_1fff[0] = 13'h1fff; + assign mask_1fff[1] = 13'h1fff; + assign mask_1fff[2] = 13'h1fff; + assign mask_1fff[3] = 13'h1fff; + assign mask_1fff[4] = 13'h1fff; + assign mask_1fff[5] = 13'h1fff; + assign mask_1fff[6] = 13'h1fff; + assign mask_1fff[7] = 13'h1fff; + assign mask_1fff[8] = 13'h1fff; + assign mask_1fff[9] = 13'h1fff; + assign mask_1fff[10] = 13'h1fff; + assign mask_1fff[11] = 13'h1fff; + assign mask_1fff[12] = 13'h1fff; + assign mask_1fff[13] = 13'h1fff; + assign mask_1fff[14] = 13'h1fff; + assign mask_1fff[15] = 13'h1fff; + + reg [12:0] state_array[0:15]; + reg [3:0] ch0_in_buf; + reg ch0_in_buf_vld; + reg [12:0] ch1_out_buf[0:15]; + reg ch1_out_buf_vld; + reg stg1_vld; + + wire ch1_not_vld; + wire [3:0] ch0_sel_data; + wire ch0_is_vld; + wire ch1_vld_we; + wire ch1_data_we; + wire stg0_vld_out; + wire ch0_buf_ready; + wire ch0_pipe_stall; + wire [1:0] sel_concat; + wire ch0_buf_data_we; + wire ch0_buf_vld_rst; + wire stg0_idle; + wire stg1_idle; + wire ch0_is_inactive; + wire ch1_is_inactive; + wire [12:0] next_state_val[0:15]; + wire state_we; + wire ch0_buf_vld_we; + wire stg1_vld_we; + wire pipe_idle; + + assign ch1_not_vld = ~ch1_out_buf_vld; + assign ch0_sel_data = ch0_in_buf_vld ? ch0_in_buf : chan_0_data; + assign ch0_is_vld = chan_0_vld | ch0_in_buf_vld; + assign ch1_vld_we = chan_1_rdy | ch1_not_vld; + assign ch1_data_we = ch0_is_vld & ch1_vld_we; + assign stg0_vld_out = ch0_is_vld & ch1_data_we; + assign ch0_buf_ready = ~ch0_in_buf_vld; + assign ch0_pipe_stall = ~stg0_vld_out; + assign sel_concat = {ch0_is_vld & ch0_sel_data[0], ch0_is_vld & ~ch0_sel_data[0]}; + assign ch0_buf_data_we = chan_0_vld & ch0_buf_ready & ch0_pipe_stall; + assign ch0_buf_vld_rst = ch0_in_buf_vld & stg0_vld_out; + assign stg0_idle = ~ch0_is_vld; + assign stg1_idle = ~stg1_vld; + assign ch0_is_inactive = ~(chan_0_vld & ch0_buf_ready); + assign ch1_is_inactive = ~(ch1_out_buf_vld & chan_1_rdy); + + assign next_state_val[0] = state_array[0] & {13{sel_concat[0]}} | mask_1fff[0] & {13{sel_concat[1]}}; + assign next_state_val[1] = state_array[1] & {13{sel_concat[0]}} | mask_1fff[1] & {13{sel_concat[1]}}; + assign next_state_val[2] = state_array[2] & {13{sel_concat[0]}} | mask_1fff[2] & {13{sel_concat[1]}}; + assign next_state_val[3] = state_array[3] & {13{sel_concat[0]}} | mask_1fff[3] & {13{sel_concat[1]}}; + assign next_state_val[4] = state_array[4] & {13{sel_concat[0]}} | mask_1fff[4] & {13{sel_concat[1]}}; + assign next_state_val[5] = state_array[5] & {13{sel_concat[0]}} | mask_1fff[5] & {13{sel_concat[1]}}; + assign next_state_val[6] = state_array[6] & {13{sel_concat[0]}} | mask_1fff[6] & {13{sel_concat[1]}}; + assign next_state_val[7] = state_array[7] & {13{sel_concat[0]}} | mask_1fff[7] & {13{sel_concat[1]}}; + assign next_state_val[8] = state_array[8] & {13{sel_concat[0]}} | mask_1fff[8] & {13{sel_concat[1]}}; + assign next_state_val[9] = state_array[9] & {13{sel_concat[0]}} | mask_1fff[9] & {13{sel_concat[1]}}; + assign next_state_val[10] = state_array[10] & {13{sel_concat[0]}} | mask_1fff[10] & {13{sel_concat[1]}}; + assign next_state_val[11] = state_array[11] & {13{sel_concat[0]}} | mask_1fff[11] & {13{sel_concat[1]}}; + assign next_state_val[12] = state_array[12] & {13{sel_concat[0]}} | mask_1fff[12] & {13{sel_concat[1]}}; + assign next_state_val[13] = state_array[13] & {13{sel_concat[0]}} | mask_1fff[13] & {13{sel_concat[1]}}; + assign next_state_val[14] = state_array[14] & {13{sel_concat[0]}} | mask_1fff[14] & {13{sel_concat[1]}}; + assign next_state_val[15] = state_array[15] & {13{sel_concat[0]}} | mask_1fff[15] & {13{sel_concat[1]}}; + + assign state_we = stg0_vld_out & ch0_sel_data[0] | stg0_vld_out & ~ch0_sel_data[0]; + assign ch0_buf_vld_we = ch0_buf_data_we | ch0_buf_vld_rst; + assign stg1_vld_we = stg0_vld_out | stg1_vld; + assign pipe_idle = stg0_idle & stg1_idle & ch0_is_inactive & ch1_is_inactive; + + always @(posedge clk) begin + if (!rst_n) begin + state_array[0] <= state_init[0]; + state_array[1] <= state_init[1]; + state_array[2] <= state_init[2]; + state_array[3] <= state_init[3]; + state_array[4] <= state_init[4]; + state_array[5] <= state_init[5]; + state_array[6] <= state_init[6]; + state_array[7] <= state_init[7]; + state_array[8] <= state_init[8]; + state_array[9] <= state_init[9]; + state_array[10] <= state_init[10]; + state_array[11] <= state_init[11]; + state_array[12] <= state_init[12]; + state_array[13] <= state_init[13]; + state_array[14] <= state_init[14]; + state_array[15] <= state_init[15]; + ch0_in_buf <= 4'h0; + ch0_in_buf_vld <= 1'h0; + ch1_out_buf[0] <= ch1_init[0]; + ch1_out_buf[1] <= ch1_init[1]; + ch1_out_buf[2] <= ch1_init[2]; + ch1_out_buf[3] <= ch1_init[3]; + ch1_out_buf[4] <= ch1_init[4]; + ch1_out_buf[5] <= ch1_init[5]; + ch1_out_buf[6] <= ch1_init[6]; + ch1_out_buf[7] <= ch1_init[7]; + ch1_out_buf[8] <= ch1_init[8]; + ch1_out_buf[9] <= ch1_init[9]; + ch1_out_buf[10] <= ch1_init[10]; + ch1_out_buf[11] <= ch1_init[11]; + ch1_out_buf[12] <= ch1_init[12]; + ch1_out_buf[13] <= ch1_init[13]; + ch1_out_buf[14] <= ch1_init[14]; + ch1_out_buf[15] <= ch1_init[15]; + ch1_out_buf_vld <= 1'h0; + stg1_vld <= 1'h0; + end else begin + state_array[0] <= state_we ? next_state_val[0] : state_array[0]; + state_array[1] <= state_we ? next_state_val[1] : state_array[1]; + state_array[2] <= state_we ? next_state_val[2] : state_array[2]; + state_array[3] <= state_we ? next_state_val[3] : state_array[3]; + state_array[4] <= state_we ? next_state_val[4] : state_array[4]; + state_array[5] <= state_we ? next_state_val[5] : state_array[5]; + state_array[6] <= state_we ? next_state_val[6] : state_array[6]; + state_array[7] <= state_we ? next_state_val[7] : state_array[7]; + state_array[8] <= state_we ? next_state_val[8] : state_array[8]; + state_array[9] <= state_we ? next_state_val[9] : state_array[9]; + state_array[10] <= state_we ? next_state_val[10] : state_array[10]; + state_array[11] <= state_we ? next_state_val[11] : state_array[11]; + state_array[12] <= state_we ? next_state_val[12] : state_array[12]; + state_array[13] <= state_we ? next_state_val[13] : state_array[13]; + state_array[14] <= state_we ? next_state_val[14] : state_array[14]; + state_array[15] <= state_we ? next_state_val[15] : state_array[15]; + ch0_in_buf <= ch0_buf_data_we ? chan_0_data : ch0_in_buf; + ch0_in_buf_vld <= ch0_buf_vld_we ? ch0_buf_ready : ch0_in_buf_vld; + ch1_out_buf[0] <= ch1_data_we ? state_array[0] : ch1_out_buf[0]; + ch1_out_buf[1] <= ch1_data_we ? state_array[1] : ch1_out_buf[1]; + ch1_out_buf[2] <= ch1_data_we ? state_array[2] : ch1_out_buf[2]; + ch1_out_buf[3] <= ch1_data_we ? state_array[3] : ch1_out_buf[3]; + ch1_out_buf[4] <= ch1_data_we ? state_array[4] : ch1_out_buf[4]; + ch1_out_buf[5] <= ch1_data_we ? state_array[5] : ch1_out_buf[5]; + ch1_out_buf[6] <= ch1_data_we ? state_array[6] : ch1_out_buf[6]; + ch1_out_buf[7] <= ch1_data_we ? state_array[7] : ch1_out_buf[7]; + ch1_out_buf[8] <= ch1_data_we ? state_array[8] : ch1_out_buf[8]; + ch1_out_buf[9] <= ch1_data_we ? state_array[9] : ch1_out_buf[9]; + ch1_out_buf[10] <= ch1_data_we ? state_array[10] : ch1_out_buf[10]; + ch1_out_buf[11] <= ch1_data_we ? state_array[11] : ch1_out_buf[11]; + ch1_out_buf[12] <= ch1_data_we ? state_array[12] : ch1_out_buf[12]; + ch1_out_buf[13] <= ch1_data_we ? state_array[13] : ch1_out_buf[13]; + ch1_out_buf[14] <= ch1_data_we ? state_array[14] : ch1_out_buf[14]; + ch1_out_buf[15] <= ch1_data_we ? state_array[15] : ch1_out_buf[15]; + ch1_out_buf_vld <= ch1_vld_we ? ch0_is_vld : ch1_out_buf_vld; + stg1_vld <= stg1_vld_we ? stg0_vld_out : stg1_vld; + end + end + + assign chan_0_rdy = ch0_buf_ready; + assign chan_1_data = { + ch1_out_buf[15], + ch1_out_buf[14], + ch1_out_buf[13], + ch1_out_buf[12], + ch1_out_buf[11], + ch1_out_buf[10], + ch1_out_buf[9], + ch1_out_buf[8], + ch1_out_buf[7], + ch1_out_buf[6], + ch1_out_buf[5], + ch1_out_buf[4], + ch1_out_buf[3], + ch1_out_buf[2], + ch1_out_buf[1], + ch1_out_buf[0] + }; + assign chan_1_vld = ch1_out_buf_vld; + assign idle = pipe_idle; +endmodule diff --git a/tests/opt/opt_dff_eqbits_small.sv b/tests/opt/opt_dff_eqbits_small.sv new file mode 100644 index 000000000..7c6aeba7f --- /dev/null +++ b/tests/opt/opt_dff_eqbits_small.sv @@ -0,0 +1,30 @@ +module test_case ( + input wire clk, + input wire rst_n, + input wire in_val, + output wire out_a, + output wire out_b, + output wire out_c, + output wire out_d +); + reg a, b, c, d; + + always @(posedge clk) begin + if (!rst_n) begin + a <= 1'b0; + b <= 1'b0; + c <= 1'b0; + d <= 1'b0; + end else begin + a <= c & in_val; + b <= d & in_val; + c <= b | in_val; + d <= a | in_val; + end + end + + assign out_a = a; + assign out_b = b; + assign out_c = c; + assign out_d = d; +endmodule From c6bf13bb94ed8b3f5f7eee14eb67823f497f0e4a Mon Sep 17 00:00:00 2001 From: nella Date: Wed, 13 May 2026 10:49:12 +0200 Subject: [PATCH 060/354] Implement worklist and SAT counterexample splitting. --- passes/opt/opt_dff.cc | 113 ++++++++++++++++++++++++------------------ 1 file changed, 65 insertions(+), 48 deletions(-) diff --git a/passes/opt/opt_dff.cc b/passes/opt/opt_dff.cc index 241ea6888..ef5c56896 100644 --- a/passes/opt/opt_dff.cc +++ b/passes/opt/opt_dff.cc @@ -1104,62 +1104,76 @@ struct OptDffWorker qcsat.prepare(); bool any_change = false; - bool changed = true; + std::vector worklist; + std::vector in_worklist(GetSize(classes), true); - // Bit = class rep, split classes whenever two next states differ - while (changed) { - changed = false; - int joint = qcsat.ez->CONST_TRUE; + for (int i = 0; i < GetSize(classes); i++) { + worklist.push_back(i); + } - for (auto &cls : classes) { - int rep = cls[0]; - for (int k = 1; k < GetSize(cls); k++) - joint = qcsat.ez->AND(joint, qcsat.ez->IFF(q_lit[rep], q_lit[cls[k]])); + while (!worklist.empty()) { + int cls_idx = worklist.back(); + worklist.pop_back(); + in_worklist[cls_idx] = false; + + auto &cls = classes[cls_idx]; + if (GetSize(cls) < 2) continue; + + std::vector assumptions; + for (auto &c : classes) { + if (GetSize(c) < 2) continue; + int rep = c[0]; + for (int k = 1; k < GetSize(c); k++) { + assumptions.push_back(qcsat.ez->IFF(q_lit[rep], q_lit[c[k]])); + } } - std::vector> new_classes; - new_classes.reserve(classes.size()); + // Split at counterexamples + int rep = cls[0]; + for (int i = 1; i < GetSize(cls); i++) { + // Trivially eqivalent + if (n_lit[rep] == n_lit[cls[i]]) + continue; + + int query = qcsat.ez->NOT(qcsat.ez->IFF(n_lit[rep], n_lit[cls[i]])); + std::vector modelExprs; - for (auto &cls : classes) { - std::vector> subs; for (int b : cls) { - bool placed = false; - - // Identical literal - trivially eq - for (auto &sub : subs) { - if (n_lit[sub[0]] == n_lit[b]) { - sub.push_back(b); - placed = true; - break; - } - } - - if (placed) continue; - - for (auto &sub : subs) { - int rep = sub[0]; - int query = qcsat.ez->NOT(qcsat.ez->IFF(n_lit[rep], n_lit[b])); - if (!qcsat.ez->solve(joint, query)) { - sub.push_back(b); - placed = true; - break; - } - } - - if (!placed) - subs.push_back({b}); + modelExprs.push_back(n_lit[b]); } - if (GetSize(subs) > 1) - changed = true; - for (auto &sub : subs) - if (GetSize(sub) >= 2) - new_classes.push_back(std::move(sub)); - } + std::vector modelVals; + assumptions.push_back(query); + + if (qcsat.ez->solve(modelExprs, modelVals, assumptions)) { + // SAT -> partition entire class + std::vector sub0; + std::vector sub1; - classes = std::move(new_classes); - if (changed) - any_change = true; + for (size_t b_idx = 0; b_idx < cls.size(); b_idx++) { + if (modelVals[b_idx]) + sub1.push_back(cls[b_idx]); + else + sub0.push_back(cls[b_idx]); + } + + classes[cls_idx] = std::move(sub0); + classes.push_back(std::move(sub1)); + in_worklist.push_back(false); + + // Partition was split -> the induction hypo weakened + for (int j = 0; j < GetSize(classes); j++) { + if (GetSize(classes[j]) >= 2 && !in_worklist[j]) { + worklist.push_back(j); + in_worklist[j] = true; + } + } + + break; // Process new splits + } + + assumptions.pop_back(); // Remove query for the next pairwise check if UNSAT + } } if (classes.empty()) @@ -1169,7 +1183,10 @@ struct OptDffWorker // Drive every non-rep Q from its class rep, drop merged bits from their FFs for (auto &cls : classes) { + if (GetSize(cls) < 2) + continue; SigBit rep_q = bits[cls[0]].q; + any_change = true; for (int k = 1; k < GetSize(cls); k++) { const EqBit &eb = bits[cls[k]]; initvals.remove_init(eb.q); @@ -1197,7 +1214,7 @@ struct OptDffWorker } } - return true; + return any_change; } }; From bbec8d2902d3bdf65fb90a99881a94c8dfed520b Mon Sep 17 00:00:00 2001 From: nella Date: Wed, 20 May 2026 15:51:04 +0200 Subject: [PATCH 061/354] Gate behind flag. --- passes/opt/opt_dff.cc | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/passes/opt/opt_dff.cc b/passes/opt/opt_dff.cc index ef5c56896..e657a8a2d 100644 --- a/passes/opt/opt_dff.cc +++ b/passes/opt/opt_dff.cc @@ -41,6 +41,7 @@ struct OptDffOptions bool simple_dffe; bool sat; bool keepdc; + bool eqbits; }; struct OptDffWorker @@ -977,6 +978,10 @@ struct OptDffWorker bool run_eqbits() { + if(!opt.eqbits) { + return false; + } + std::vector bits; std::vector keys; dict ff_for_cell; @@ -1253,6 +1258,11 @@ struct OptDffPass : public Pass { log(" all result bits to be set to x. this behavior changes when 'a+0' is\n"); log(" replaced by 'a'. the -keepdc option disables all such optimizations.\n"); log("\n"); + log(" -eqbits\n"); + log(" finds groups of flip flop bits provably holding always-equal values\n"); + log(" across cycles and collapses each group to a single bit, potentially\n"); + log(" reducing the number of required flip flops.\n"); + log("\n"); } void execute(std::vector args, RTLIL::Design *design) override @@ -1265,6 +1275,7 @@ struct OptDffPass : public Pass { opt.simple_dffe = false; opt.keepdc = false; opt.sat = false; + opt.eqbits = false; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { @@ -1273,6 +1284,7 @@ struct OptDffPass : public Pass { if (args[argidx] == "-simple-dffe") { opt.simple_dffe = true; continue; } if (args[argidx] == "-keepdc") { opt.keepdc = true; continue; } if (args[argidx] == "-sat") { opt.sat = true; continue; } + if (args[argidx] == "-eqbits") { opt.eqbits = true; continue; } break; } extra_args(args, argidx, design); @@ -1284,7 +1296,7 @@ struct OptDffPass : public Pass { did_something = true; if (worker.run_constbits()) did_something = true; - if (opt.sat && worker.run_eqbits()) + if (worker.run_eqbits()) did_something = true; } From 04a1611346afbd7ffbed8b4d625c674694a1f972 Mon Sep 17 00:00:00 2001 From: nella Date: Wed, 20 May 2026 15:58:27 +0200 Subject: [PATCH 062/354] Tests. --- tests/opt/opt_dff_eqbits.ys | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/opt/opt_dff_eqbits.ys b/tests/opt/opt_dff_eqbits.ys index 10e9045e4..181b5d0a7 100644 --- a/tests/opt/opt_dff_eqbits.ys +++ b/tests/opt/opt_dff_eqbits.ys @@ -3,9 +3,9 @@ design -reset read_verilog -sv opt_dff_eqbits_small.sv hierarchy -top test_case techmap -opt_dff -sat +opt_dff -sat -eqbits synth -opt_dff -sat +opt_dff -sat -eqbits opt_clean -purge select -assert-count 2 t:$_SDFF_PN0_ @@ -17,7 +17,7 @@ hierarchy -top test_case prep design -save gold -opt_dff -sat +opt_dff -sat -eqbits design -save gate design -copy-from gold -as gold test_case @@ -32,9 +32,9 @@ design -reset read_verilog -sv opt_dff_eqbits_large.sv hierarchy -top test_case techmap -opt_dff -sat +opt_dff -sat -eqbits synth -opt_dff -sat +opt_dff -sat -eqbits opt_clean -purge select -assert-count 6 t:$_SDFFE_PN0P_ @@ -46,7 +46,7 @@ hierarchy -top test_case prep design -save gold -opt_dff -sat +opt_dff -sat -eqbits design -save gate design -copy-from gold -as gold test_case From 386e63ae20465e401d749ffe160098e7be97f799 Mon Sep 17 00:00:00 2001 From: nella Date: Mon, 25 May 2026 12:49:29 +0200 Subject: [PATCH 063/354] Add prepass for bit simulation. --- kernel/bitsim.h | 79 +++++++++++++++++++++++++++++++++++++++++++ passes/opt/opt_dff.cc | 64 ++++++++++++++++++++++++++++++++++- 2 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 kernel/bitsim.h diff --git a/kernel/bitsim.h b/kernel/bitsim.h new file mode 100644 index 000000000..a0915e28b --- /dev/null +++ b/kernel/bitsim.h @@ -0,0 +1,79 @@ +#ifndef BITSIM_H +#define BITSIM_H + +#include "kernel/modtools.h" + +YOSYS_NAMESPACE_BEGIN + +struct BitSim { + Module *module; + SigMap &sigmap; + ModWalker &modwalker; + dict sim_vals; + uint64_t rng_state; + + BitSim(Module *m, SigMap &sm, ModWalker &mw) + : module(m), sigmap(sm), modwalker(mw), rng_state(1337) {} + + uint64_t xorshift64() { + rng_state ^= rng_state << 13; + rng_state ^= rng_state >> 7; + rng_state ^= rng_state << 17; + return rng_state; + } + + uint64_t eval_bit(SigBit b) { + SigBit mapped = sigmap(b); + if (mapped == State::S0) return 0ULL; + if (mapped == State::S1) return ~0ULL; + if (mapped == State::Sx || mapped == State::Sz) return 0ULL; + + auto it = sim_vals.find(mapped); + if (it != sim_vals.end()) return it->second; + sim_vals[mapped] = 0; + uint64_t res = 0; + + if (!modwalker.has_drivers(mapped)) { + res = xorshift64(); + } else { + auto &drivers = modwalker.signal_drivers[mapped]; + if (drivers.empty()) { + res = xorshift64(); + } else { + auto driver = *drivers.begin(); + Cell *cell = driver.cell; + + if (cell->is_builtin_ff()) { + res = xorshift64(); + } else if (cell->type == ID($_AND_)) { + res = eval_bit(cell->getPort(ID::A)[0]) & eval_bit(cell->getPort(ID::B)[0]); + } else if (cell->type == ID($_OR_)) { + res = eval_bit(cell->getPort(ID::A)[0]) | eval_bit(cell->getPort(ID::B)[0]); + } else if (cell->type == ID($_XOR_)) { + res = eval_bit(cell->getPort(ID::A)[0]) ^ eval_bit(cell->getPort(ID::B)[0]); + } else if (cell->type == ID($_NOT_)) { + res = ~eval_bit(cell->getPort(ID::A)[0]); + } else if (cell->type == ID($_MUX_)) { + uint64_t s = eval_bit(cell->getPort(ID::S)[0]); + uint64_t a = eval_bit(cell->getPort(ID::A)[0]); + uint64_t b = eval_bit(cell->getPort(ID::B)[0]); + res = (a & ~s) | (b & s); + } else if (cell->type == ID($mux)) { + uint64_t s = eval_bit(cell->getPort(ID::S)[0]); + uint64_t a = eval_bit(cell->getPort(ID::A)[driver.offset]); + uint64_t b = eval_bit(cell->getPort(ID::B)[driver.offset]); + res = (a & ~s) | (b & s); + } else { + res = xorshift64(); + } + } + } + + sim_vals[mapped] = res; + return res; + } +}; + +YOSYS_NAMESPACE_END + +#endif diff --git a/passes/opt/opt_dff.cc b/passes/opt/opt_dff.cc index e657a8a2d..dbe0e521a 100644 --- a/passes/opt/opt_dff.cc +++ b/passes/opt/opt_dff.cc @@ -26,6 +26,7 @@ #include "kernel/sigtools.h" #include "kernel/ffinit.h" #include "kernel/ff.h" +#include "kernel/bitsim.h" #include "kernel/pattern.h" #include "passes/techmap/simplemap.h" #include @@ -1067,6 +1068,67 @@ struct OptDffWorker return false; ModWalker modwalker(module->design, module); + BitSim sim(module, sigmap, modwalker); + + // Simulation prepass + // Assume same class + for (auto &cls : classes) { + uint64_t class_q_val = sim.xorshift64(); + for (int idx : cls) { + sim.sim_vals[sigmap(bits[idx].q)] = class_q_val; + } + } + + std::vector> refined_classes; + + for (auto &cls : classes) { + dict> sim_buckets; + for (int idx : cls) { + const EqBit &eb = bits[idx]; + const FfData &ff = ff_for_cell.at(eb.cell); + + uint64_t n_val = sim.eval_bit(ff.sig_d[eb.idx]); + + if (ff.has_aload) { + uint64_t al = sim.eval_bit(ff.sig_aload); + if (!ff.pol_aload) al = ~al; + uint64_t ad = sim.eval_bit(ff.sig_ad[eb.idx]); + n_val = (n_val & ~al) | (ad & al); + } + if (ff.has_arst) { + uint64_t ar = sim.eval_bit(ff.sig_arst); + if (!ff.pol_arst) ar = ~ar; + uint64_t ar_val = (ff.val_arst[eb.idx] == State::S1) ? ~0ULL : 0ULL; + n_val = (n_val & ~ar) | (ar_val & ar); + } + if (ff.has_sr) { + uint64_t clr = sim.eval_bit(ff.sig_clr[eb.idx]); + if (!ff.pol_clr) clr = ~clr; + uint64_t set = sim.eval_bit(ff.sig_set[eb.idx]); + if (!ff.pol_set) set = ~set; + n_val = ~clr & (set | n_val); + } + if (ff.has_srst) { + uint64_t srst = sim.eval_bit(ff.sig_srst); + if (!ff.pol_srst) srst = ~srst; + uint64_t srst_val = (ff.val_srst[eb.idx] == State::S1) ? ~0ULL : 0ULL; + n_val = (n_val & ~srst) | (srst_val & srst); + } + + sim_buckets[n_val].push_back(idx); + } + + for (auto &kv : sim_buckets) { + if (GetSize(kv.second) >= 2) { + refined_classes.push_back(std::move(kv.second)); + } + } + } + + classes = std::move(refined_classes); + if (classes.empty()) + return false; + QuickConeSat qcsat(modwalker); std::vector q_lit(bits.size(), -1); std::vector n_lit(bits.size(), -1); @@ -1136,7 +1198,7 @@ struct OptDffWorker // Split at counterexamples int rep = cls[0]; for (int i = 1; i < GetSize(cls); i++) { - // Trivially eqivalent + // Trivially equivalent if (n_lit[rep] == n_lit[cls[i]]) continue; From 68df0be7d2ef7b3a0dd54abe469b81b9494a48e1 Mon Sep 17 00:00:00 2001 From: nella Date: Mon, 25 May 2026 14:16:55 +0200 Subject: [PATCH 064/354] Remove eqbits flag. --- passes/opt/opt_dff.cc | 106 ++++++++++++++++++++---------------- tests/opt/opt_dff_eqbits.ys | 12 ++-- 2 files changed, 64 insertions(+), 54 deletions(-) diff --git a/passes/opt/opt_dff.cc b/passes/opt/opt_dff.cc index dbe0e521a..500df142e 100644 --- a/passes/opt/opt_dff.cc +++ b/passes/opt/opt_dff.cc @@ -42,7 +42,6 @@ struct OptDffOptions bool simple_dffe; bool sat; bool keepdc; - bool eqbits; }; struct OptDffWorker @@ -977,15 +976,9 @@ struct OptDffWorker return v == State::S1 ? qcsat.ez->CONST_TRUE : qcsat.ez->CONST_FALSE; } - bool run_eqbits() + std::vector> gather_initial_eq_classes(std::vector &bits, dict &ff_for_cell) { - if(!opt.eqbits) { - return false; - } - - std::vector bits; std::vector keys; - dict ff_for_cell; // Collect FF bits eligible for merging for (auto cell : module->selected_cells()) { @@ -1050,27 +1043,26 @@ struct OptDffWorker } } - if (GetSize(bits) < 2) - return false; - - // Group bits by control signature dict> buckets; for (int i = 0; i < GetSize(bits); i++) buckets[keys[i]].push_back(i); std::vector> classes; - classes.reserve(GetSize(buckets)); for (auto &kv : buckets) if (GetSize(kv.second) >= 2) classes.push_back(std::move(kv.second)); - if (classes.empty()) - return false; + return classes; + } - ModWalker modwalker(module->design, module); + std::vector> filter_classes_sim( + const std::vector> &classes, + const std::vector &bits, + const dict &ff_for_cell, + ModWalker &modwalker + ) { BitSim sim(module, sigmap, modwalker); - - // Simulation prepass + // Assume same class for (auto &cls : classes) { uint64_t class_q_val = sim.xorshift64(); @@ -1080,15 +1072,13 @@ struct OptDffWorker } std::vector> refined_classes; - for (auto &cls : classes) { dict> sim_buckets; for (int idx : cls) { const EqBit &eb = bits[idx]; const FfData &ff = ff_for_cell.at(eb.cell); - uint64_t n_val = sim.eval_bit(ff.sig_d[eb.idx]); - + if (ff.has_aload) { uint64_t al = sim.eval_bit(ff.sig_aload); if (!ff.pol_aload) al = ~al; @@ -1118,17 +1108,20 @@ struct OptDffWorker sim_buckets[n_val].push_back(idx); } - for (auto &kv : sim_buckets) { - if (GetSize(kv.second) >= 2) { + for (auto &kv : sim_buckets) + if (GetSize(kv.second) >= 2) refined_classes.push_back(std::move(kv.second)); - } - } } - classes = std::move(refined_classes); - if (classes.empty()) - return false; + return refined_classes; + } + std::vector> filter_classes_sat( + std::vector> classes, + const std::vector &bits, + const dict &ff_for_cell, + ModWalker &modwalker + ) { QuickConeSat qcsat(modwalker); std::vector q_lit(bits.size(), -1); std::vector n_lit(bits.size(), -1); @@ -1144,8 +1137,7 @@ struct OptDffWorker if (ff.has_aload) { int al = qcsat.importSigBit(ff.sig_aload); if (!ff.pol_aload) al = qcsat.ez->NOT(al); - int ad = qcsat.importSigBit(ff.sig_ad[eb.idx]); - n = sat_mux(qcsat, al, ad, n); + n = sat_mux(qcsat, al, qcsat.importSigBit(ff.sig_ad[eb.idx]), n); } if (ff.has_arst) { int ar = qcsat.importSigBit(ff.sig_arst); @@ -1170,13 +1162,11 @@ struct OptDffWorker } qcsat.prepare(); - bool any_change = false; std::vector worklist; std::vector in_worklist(GetSize(classes), true); - for (int i = 0; i < GetSize(classes); i++) { + for (int i = 0; i < GetSize(classes); i++) worklist.push_back(i); - } while (!worklist.empty()) { int cls_idx = worklist.back(); @@ -1190,9 +1180,8 @@ struct OptDffWorker for (auto &c : classes) { if (GetSize(c) < 2) continue; int rep = c[0]; - for (int k = 1; k < GetSize(c); k++) { + for (int k = 1; k < GetSize(c); k++) assumptions.push_back(qcsat.ez->IFF(q_lit[rep], q_lit[c[k]])); - } } // Split at counterexamples @@ -1204,14 +1193,12 @@ struct OptDffWorker int query = qcsat.ez->NOT(qcsat.ez->IFF(n_lit[rep], n_lit[cls[i]])); std::vector modelExprs; - - for (int b : cls) { + for (int b : cls) modelExprs.push_back(n_lit[b]); - } std::vector modelVals; assumptions.push_back(query); - + if (qcsat.ez->solve(modelExprs, modelVals, assumptions)) { // SAT -> partition entire class std::vector sub0; @@ -1243,9 +1230,12 @@ struct OptDffWorker } } - if (classes.empty()) - return any_change; + return classes; + } + bool apply_eq_merges(const std::vector> &classes, const std::vector &bits, dict &ff_for_cell) + { + bool any_change = false; dict> remove_bits; // Drive every non-rep Q from its class rep, drop merged bits from their FFs @@ -1283,6 +1273,33 @@ struct OptDffWorker return any_change; } + + bool run_eqbits() + { + if (!opt.sat) + return false; + + std::vector bits; + dict ff_for_cell; + + std::vector> classes = gather_initial_eq_classes(bits, ff_for_cell); + if (classes.empty()) + return false; + + ModWalker modwalker(module->design, module); + + // Simulation prepass + classes = filter_classes_sim(classes, bits, ff_for_cell, modwalker); + if (classes.empty()) + return false; + + // SAT prove + classes = filter_classes_sat(std::move(classes), bits, ff_for_cell, modwalker); + if (classes.empty()) + return false; + + return apply_eq_merges(classes, bits, ff_for_cell); + } }; struct OptDffPass : public Pass { @@ -1320,11 +1337,6 @@ struct OptDffPass : public Pass { log(" all result bits to be set to x. this behavior changes when 'a+0' is\n"); log(" replaced by 'a'. the -keepdc option disables all such optimizations.\n"); log("\n"); - log(" -eqbits\n"); - log(" finds groups of flip flop bits provably holding always-equal values\n"); - log(" across cycles and collapses each group to a single bit, potentially\n"); - log(" reducing the number of required flip flops.\n"); - log("\n"); } void execute(std::vector args, RTLIL::Design *design) override @@ -1337,7 +1349,6 @@ struct OptDffPass : public Pass { opt.simple_dffe = false; opt.keepdc = false; opt.sat = false; - opt.eqbits = false; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { @@ -1346,7 +1357,6 @@ struct OptDffPass : public Pass { if (args[argidx] == "-simple-dffe") { opt.simple_dffe = true; continue; } if (args[argidx] == "-keepdc") { opt.keepdc = true; continue; } if (args[argidx] == "-sat") { opt.sat = true; continue; } - if (args[argidx] == "-eqbits") { opt.eqbits = true; continue; } break; } extra_args(args, argidx, design); diff --git a/tests/opt/opt_dff_eqbits.ys b/tests/opt/opt_dff_eqbits.ys index 181b5d0a7..10e9045e4 100644 --- a/tests/opt/opt_dff_eqbits.ys +++ b/tests/opt/opt_dff_eqbits.ys @@ -3,9 +3,9 @@ design -reset read_verilog -sv opt_dff_eqbits_small.sv hierarchy -top test_case techmap -opt_dff -sat -eqbits +opt_dff -sat synth -opt_dff -sat -eqbits +opt_dff -sat opt_clean -purge select -assert-count 2 t:$_SDFF_PN0_ @@ -17,7 +17,7 @@ hierarchy -top test_case prep design -save gold -opt_dff -sat -eqbits +opt_dff -sat design -save gate design -copy-from gold -as gold test_case @@ -32,9 +32,9 @@ design -reset read_verilog -sv opt_dff_eqbits_large.sv hierarchy -top test_case techmap -opt_dff -sat -eqbits +opt_dff -sat synth -opt_dff -sat -eqbits +opt_dff -sat opt_clean -purge select -assert-count 6 t:$_SDFFE_PN0P_ @@ -46,7 +46,7 @@ hierarchy -top test_case prep design -save gold -opt_dff -sat -eqbits +opt_dff -sat design -save gate design -copy-from gold -as gold test_case From 6f111118de5faee1c1cfba0aba1955756adae7bb Mon Sep 17 00:00:00 2001 From: junyao Date: Tue, 26 May 2026 00:56:07 +0800 Subject: [PATCH 065/354] proc: ignore nosync temporaries in always_latch checks --- passes/proc/proc_dlatch.cc | 11 +++++++++-- tests/various/svalways.sh | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/passes/proc/proc_dlatch.cc b/passes/proc/proc_dlatch.cc index 5e07dbcb0..50e64f482 100644 --- a/passes/proc/proc_dlatch.cc +++ b/passes/proc/proc_dlatch.cc @@ -395,10 +395,17 @@ void proc_dlatch(proc_dlatch_db_t &db, RTLIL::Process *proc) int offset = 0; for (auto chunk : nolatches_bits.first.chunks()) { SigSpec lhs = chunk, rhs = nolatches_bits.second.extract(offset, chunk.width); - if (proc->get_bool_attribute(ID::always_latch)) + bool is_nosync = true; + for (auto bit : lhs) + if (bit.wire == nullptr || !bit.wire->get_bool_attribute(ID::nosync)) { + is_nosync = false; + break; + } + + if (proc->get_bool_attribute(ID::always_latch) && !is_nosync) log_error("No latch inferred for signal `%s.%s' from always_latch process `%s.%s'.\n", db.module->name.c_str(), log_signal(lhs), db.module->name.c_str(), proc->name.c_str()); - else + else if (!is_nosync) log("No latch inferred for signal `%s.%s' from process `%s.%s'.\n", db.module->name.c_str(), log_signal(lhs), db.module->name.c_str(), proc->name.c_str()); for (auto &bit : lhs) { diff --git a/tests/various/svalways.sh b/tests/various/svalways.sh index b73786735..80cd234d4 100755 --- a/tests/various/svalways.sh +++ b/tests/various/svalways.sh @@ -18,6 +18,20 @@ always_latch endmodule EOT +# Good case: dynamic memory writes in always_latch create nosync mem2reg +# temporaries, but only the memory words themselves should be checked for +# latch inference. +${YOSYS} -f "verilog -sv" -qp proc - < Date: Thu, 28 May 2026 14:50:11 +1200 Subject: [PATCH 066/354] opt_clean: Set group for docs gen --- passes/opt/opt_clean/opt_clean.cc | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/passes/opt/opt_clean/opt_clean.cc b/passes/opt/opt_clean/opt_clean.cc index 87597d721..24085c34e 100644 --- a/passes/opt/opt_clean/opt_clean.cc +++ b/passes/opt/opt_clean/opt_clean.cc @@ -19,6 +19,7 @@ #include "kernel/register.h" #include "kernel/log.h" +#include "kernel/log_help.h" #include "passes/opt/opt_clean/opt_clean.h" USING_YOSYS_NAMESPACE @@ -43,6 +44,12 @@ void rmunused_module(RTLIL::Module *module, bool rminit, CleanRunContext &clean_ struct OptCleanPass : public Pass { OptCleanPass() : Pass("opt_clean", "remove unused cells and wires") { } + bool formatted_help() override + { + auto *help = PrettyHelp::get_current(); + help->set_group("passes/opt"); + return false; + } void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| @@ -99,6 +106,12 @@ struct OptCleanPass : public Pass { struct CleanPass : public Pass { CleanPass() : Pass("clean", "remove unused cells and wires") { } + bool formatted_help() override + { + auto *help = PrettyHelp::get_current(); + help->set_group("passes/opt"); + return false; + } void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| From d6106f141cc66c116c79cdc85bdf16327c43bed8 Mon Sep 17 00:00:00 2001 From: nella Date: Wed, 27 May 2026 13:19:51 +0200 Subject: [PATCH 067/354] Add matching for fused mac operations for Nexus (fix #5906). --- techlibs/lattice/Makefile.inc | 8 ++ techlibs/lattice/dsp_map_nexus.v | 89 +++++++++++++ techlibs/lattice/lattice_dsp_nexus.cc | 36 ++++++ techlibs/lattice/lattice_dsp_nexus.pmg | 165 +++++++++++++++++++++++++ techlibs/lattice/synth_lattice.cc | 3 + tests/arch/nexus/fuse_mac.sv | 76 ++++++++++++ tests/arch/nexus/fuse_mac.ys | 35 ++++++ 7 files changed, 412 insertions(+) create mode 100644 techlibs/lattice/lattice_dsp_nexus.cc create mode 100644 techlibs/lattice/lattice_dsp_nexus.pmg create mode 100644 tests/arch/nexus/fuse_mac.sv create mode 100644 tests/arch/nexus/fuse_mac.ys diff --git a/techlibs/lattice/Makefile.inc b/techlibs/lattice/Makefile.inc index 9084472cf..1fb150e6c 100644 --- a/techlibs/lattice/Makefile.inc +++ b/techlibs/lattice/Makefile.inc @@ -1,6 +1,7 @@ OBJS += techlibs/lattice/synth_lattice.o OBJS += techlibs/lattice/lattice_gsr.o +OBJS += techlibs/lattice/lattice_dsp_nexus.o $(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_ff.vh)) $(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_io.vh)) @@ -50,3 +51,10 @@ $(eval $(call add_share_file_and_rename,share/ecp5,techlibs/lattice/cells_bb_ecp $(eval $(call add_share_file,share/nexus,techlibs/lattice/parse_init.vh)) $(eval $(call add_share_file_and_rename,share/nexus,techlibs/lattice/cells_sim_nexus.v,cells_sim.v)) $(eval $(call add_share_file_and_rename,share/nexus,techlibs/lattice/cells_bb_nexus.v,cells_xtra.v)) + +techlibs/lattice/%_pm.h: passes/pmgen/pmgen.py techlibs/lattice/%.pmg + $(P) mkdir -p $(dir $@) && $(PYTHON_EXECUTABLE) $< -o $@ -p $(notdir $*) $(filter-out $<,$^) + +GENFILES += techlibs/lattice/lattice_dsp_nexus_pm.h +techlibs/lattice/lattice_dsp_nexus.o: techlibs/lattice/lattice_dsp_nexus_pm.h +$(eval $(call add_extra_objs,techlibs/lattice/lattice_dsp_nexus_pm.h)) diff --git a/techlibs/lattice/dsp_map_nexus.v b/techlibs/lattice/dsp_map_nexus.v index b12528309..35caacd10 100644 --- a/techlibs/lattice/dsp_map_nexus.v +++ b/techlibs/lattice/dsp_map_nexus.v @@ -77,3 +77,92 @@ module \$__NX_MUL9X9 (input [8:0] A, input [8:0] B, output [17:0] Y); .Z(Y) ); endmodule + +module \$__NX_MAC18X18 (A, B, C, Y); + + parameter A_WIDTH = 18; + parameter B_WIDTH = 18; + parameter C_WIDTH = 48; + parameter Y_WIDTH = 48; + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter SUBTRACT = 0; + input [17:0] A; + input [17:0] B; + input [47:0] C; + output [47:0] Y; + wire [53:0] Z_out; + assign Y = Z_out[47:0]; + + MULTADDSUB18X18 #( + .REGINPUTA("BYPASS"), + .REGINPUTB("BYPASS"), + .REGINPUTC("BYPASS"), + .REGOUTPUT("BYPASS") + ) _TECHMAP_REPLACE_ ( + .A(A), + .B(B), + .C({6'b0, C}), + .SIGNED(A_SIGNED ? 1'b1 : 1'b0), + .ADDSUB(SUBTRACT ? 1'b1 : 1'b0), + .Z(Z_out) + ); +endmodule + +module \$__NX_PREADD18X18 (A, B, C, Y, CLK); + + parameter PIPELINED = 0; + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter C_SIGNED = 0; + input [17:0] A; + input [17:0] B; + input [17:0] C; + input CLK; + output [47:0] Y; + wire [35:0] Z_out; + assign Y = A_SIGNED ? {{12{Z_out[35]}}, Z_out} : {12'b0, Z_out}; + + MULTPREADD18X18 #( + .REGINPUTA("BYPASS"), + .REGINPUTB("BYPASS"), + .REGINPUTC("BYPASS"), + .REGOUTPUT(PIPELINED ? "REGISTER" : "BYPASS") + ) _TECHMAP_REPLACE_ ( + .A(A), + .B(B), + .C(C), + .CLK(CLK), + .SIGNEDA(A_SIGNED ? 1'b1 : 1'b0), + .SIGNEDB(B_SIGNED ? 1'b1 : 1'b0), + .SIGNEDC(C_SIGNED ? 1'b1 : 1'b0), + .Z(Z_out) + ); +endmodule + +module \$__NX_MAC9X9WIDE_4LANE (A0, B0, A1, B1, A2, B2, A3, B3, Y); + + parameter SIGNED = 0; + input [8:0] A0, B0, A1, B1, A2, B2, A3, B3; + output [47:0] Y; + wire [53:0] Z_out; + assign Y = Z_out[47:0]; + + MULTADDSUB9X9WIDE #( + .REGINPUTAB0("BYPASS"), + .REGINPUTAB1("BYPASS"), + .REGINPUTAB2("BYPASS"), + .REGINPUTAB3("BYPASS"), + .REGINPUTC("BYPASS"), + .REGOUTPUT("BYPASS") + ) _TECHMAP_REPLACE_ ( + .A0(A0), .B0(B0), + .A1(A1), .B1(B1), + .A2(A2), .B2(B2), + .A3(A3), .B3(B3), + .C(54'b0), + .SIGNED(SIGNED ? 1'b1 : 1'b0), + .ADDSUB(4'b0000), + .Z(Z_out) + ); +endmodule diff --git a/techlibs/lattice/lattice_dsp_nexus.cc b/techlibs/lattice/lattice_dsp_nexus.cc new file mode 100644 index 000000000..d072c552d --- /dev/null +++ b/techlibs/lattice/lattice_dsp_nexus.cc @@ -0,0 +1,36 @@ +#include "kernel/yosys.h" +#include "kernel/sigtools.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +#include "techlibs/lattice/lattice_dsp_nexus_pm.h" + +struct LatticeDspNexusPass : public Pass { + LatticeDspNexusPass() : Pass("lattice_dsp_nexus", "Lattice Nexus DSP inference") { } + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" lattice_dsp_nexus [options] [selection]\n"); + log("\n"); + log("Infer Lattice Nexus sysDSP macrocells (MULTADDSUB18X18, MULTPREADD18X18,\n"); + log("MULTADDSUB9X9WIDE) from MAC and dot-product patterns.\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) override + { + log_header(design, "Executing LATTICE_DSP_NEXUS pass.\n"); + extra_args(args, 1, design); + + for (auto module : design->selected_modules()) { + lattice_dsp_nexus_pm pm(module, module->cells()); + + pm.run_nexus_mac9_4lane(); + pm.run_nexus_mac18(); + pm.run_nexus_preadd18(); + } + } +} LatticeDspNexusPass; + +PRIVATE_NAMESPACE_END \ No newline at end of file diff --git a/techlibs/lattice/lattice_dsp_nexus.pmg b/techlibs/lattice/lattice_dsp_nexus.pmg new file mode 100644 index 000000000..73587b91c --- /dev/null +++ b/techlibs/lattice/lattice_dsp_nexus.pmg @@ -0,0 +1,165 @@ +pattern nexus_mac18 + +match mul + select mul->type.in($mul) + select GetSize(port(mul, \A)) <= 18 + select GetSize(port(mul, \B)) <= 18 + select GetSize(port(mul, \Y)) <= 48 +endmatch + +match add + select add->type.in($add, $sub) + select GetSize(port(add, \Y)) <= 48 + choice AB {\A, \B} + index port(add, AB)[0] === port(mul, \Y)[0] +endmatch + +code + SigSpec mul_out = port(mul, \Y); + IdString add_AB; + Cell *mac = module->addCell(NEW_ID, "$__NX_MAC18X18"); + IdString add_C = (add_AB == \A) ? \B : \A; + + mac->setPort(\A, port(mul, \A)); + mac->setPort(\B, port(mul, \B)); + mac->setPort(\C, port(add, add_C)); + mac->setPort(\Y, port(add, \Y)); + mac->setParam(\A_SIGNED, mul->getParam(\A_SIGNED)); + mac->setParam(\B_SIGNED, mul->getParam(\B_SIGNED)); + mac->setParam(\SUBTRACT, add->type == $sub ? State::S1 : State::S0); + + autoremove(mul); + autoremove(add); + + accept; +endcode + +pattern nexus_preadd18 + +match preadd + select preadd->type.in($add, $sub) + select GetSize(port(preadd, \Y)) <= 19 +endmatch + +match mul + select mul->type.in($mul) + select GetSize(port(mul, \Y)) <= 48 + choice mul_AB {\A, \B} + index port(mul, mul_AB)[0] === port(preadd, \Y)[0] +endmatch + +match pipe_ff + select pipe_ff->type.in($dff, $dffe, $sdff, $sdffe) + index port(pipe_ff, \D)[0] === port(mul, \Y)[0] + optional +endmatch + +code + SigSpec preadd_out = port(preadd, \Y); + IdString actual_mul_AB; + Cell *mac = module->addCell(NEW_ID, "$__NX_PREADD18X18"); + + IdString mul_other = (actual_mul_AB == \A) ? \B : \A; + IdString sgn_AC = (mul_other == \A) ? \B_SIGNED : \A_SIGNED; + IdString sgn_B = (mul_other == \A) ? \A_SIGNED : \B_SIGNED; + + SigSpec sig_A = port(preadd, \A); + SigSpec sig_C = port(preadd, \B); + SigSpec sig_B = port(mul, mul_other); + + sig_A.extend_u0(18, false); + sig_C.extend_u0(18, false); + sig_B.extend_u0(18, false); + + mac->setPort(\A, sig_A.extract(0, 18)); + mac->setPort(\C, sig_C.extract(0, 18)); + mac->setPort(\B, sig_B.extract(0, 18)); + + if (pipe_ff) { + mac->setPort(\Y, port(pipe_ff, \Q)); + mac->setPort(\CLK, port(pipe_ff, \CLK)); + mac->setParam(\PIPELINED, State::S1); + } else { + mac->setPort(\Y, port(mul, \Y)); + mac->setPort(\CLK, State::S0); + mac->setParam(\PIPELINED, State::S0); + } + + mac->setParam(\A_SIGNED, mul->getParam(sgn_AC)); + mac->setParam(\B_SIGNED, mul->getParam(sgn_B)); + mac->setParam(\C_SIGNED, mul->getParam(sgn_AC)); + + if (pipe_ff) autoremove(pipe_ff); + autoremove(mul); + autoremove(preadd); + accept; +endcode + +pattern nexus_mac9_4lane + +match add_top + select add_top->type == $add +endmatch + +match add_mid + select add_mid->type == $add + index port(add_mid, \Y)[0] === port(add_top, \A)[0] +endmatch + +match add_bot + select add_bot->type == $add + index port(add_bot, \Y)[0] === port(add_mid, \A)[0] +endmatch + +match mul3 + select mul3->type == $mul + select GetSize(port(mul3, \A)) <= 9 && GetSize(port(mul3, \B)) <= 9 + index port(mul3, \Y)[0] === port(add_top, \B)[0] +endmatch + +match mul2 + select mul2->type == $mul + select GetSize(port(mul2, \A)) <= 9 && GetSize(port(mul2, \B)) <= 9 + index port(mul2, \Y)[0] === port(add_mid, \B)[0] +endmatch + +match mul1 + select mul1->type == $mul + select GetSize(port(mul1, \A)) <= 9 && GetSize(port(mul1, \B)) <= 9 + index port(mul1, \Y)[0] === port(add_bot, \B)[0] +endmatch + +match mul0 + select mul0->type == $mul + select GetSize(port(mul0, \A)) <= 9 && GetSize(port(mul0, \B)) <= 9 + index port(mul0, \Y)[0] === port(add_bot, \A)[0] +endmatch + +code + Cell *mac = module->addCell(NEW_ID, "$__NX_MAC9X9WIDE_4LANE"); + bool is_signed = mul0->getParam(\A_SIGNED).as_bool(); + auto ext9 = [&](SigSpec s) { + s.extend_u0(9, is_signed); + return s; + }; + + mac->setPort(\A0, ext9(port(mul0, \A))); + mac->setPort(\B0, ext9(port(mul0, \B))); + mac->setPort(\A1, ext9(port(mul1, \A))); + mac->setPort(\B1, ext9(port(mul1, \B))); + mac->setPort(\A2, ext9(port(mul2, \A))); + mac->setPort(\B2, ext9(port(mul2, \B))); + mac->setPort(\A3, ext9(port(mul3, \A))); + mac->setPort(\B3, ext9(port(mul3, \B))); + mac->setPort(\Y, port(add_top, \Y)); + mac->setParam(\SIGNED, mul0->getParam(\A_SIGNED)); + + autoremove(add_top); + autoremove(add_mid); + autoremove(add_bot); + autoremove(mul0); + autoremove(mul1); + autoremove(mul2); + autoremove(mul3); + accept; +endcode diff --git a/techlibs/lattice/synth_lattice.cc b/techlibs/lattice/synth_lattice.cc index 382dae3d8..43fb7b1c2 100644 --- a/techlibs/lattice/synth_lattice.cc +++ b/techlibs/lattice/synth_lattice.cc @@ -425,9 +425,12 @@ struct SynthLatticePass : public ScriptPass run("opt_clean"); if (help_mode) { + run("lattice_dsp_nexus", "(only if -family lifcl/lfd2nx and unless -nodsp)"); run("techmap -map +/mul2dsp.v [...]", "(unless -nodsp)"); run("techmap -map +/lattice/dsp_map" + dsp_map + ".v", "(unless -nodsp)"); } else if (have_dsp && !nodsp) { + if (is_nexus) + run("lattice_dsp_nexus"); for (const auto &rule : dsp_rules) { run(stringf("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=%d -D DSP_B_MAXWIDTH=%d -D DSP_A_MINWIDTH=%d -D DSP_B_MINWIDTH=%d -D DSP_NAME=%s", rule.a_maxwidth, rule.b_maxwidth, rule.a_minwidth, rule.b_minwidth, rule.prim)); diff --git a/tests/arch/nexus/fuse_mac.sv b/tests/arch/nexus/fuse_mac.sv new file mode 100644 index 000000000..cf16bd261 --- /dev/null +++ b/tests/arch/nexus/fuse_mac.sv @@ -0,0 +1,76 @@ +// https://github.com/YosysHQ/yosys/issues/5906 + +module mac ( + input bit clk, rst, + input bit [17:0] a, b, + input bit clear, + output bit [47:0] p +); + bit [17:0] a_r, b_r; bit clear_r; bit [47:0] p_r; + always_ff @(posedge clk) begin + if (rst) begin a_r<=0; b_r<=0; clear_r<=0; p_r<=0; end + else begin + a_r<=a; b_r<=b; clear_r<=clear; + p_r <= clear_r ? 48'(a_r*b_r) : 48'(p_r + 48'(a_r*b_r)); + end + end + assign p = p_r; +endmodule + +module madd_pre ( + input bit clk, rst, + input bit [17:0] a, b, c, d, + output bit [47:0] p +); + bit [17:0] a_r, b_r, c_r, d_r; bit [47:0] m_r, p_r; + always_ff @(posedge clk) begin + if (rst) begin a_r<=0; b_r<=0; c_r<=0; d_r<=0; m_r<=0; p_r<=0; end + else begin + a_r<=a; b_r<=b; c_r<=c; d_r<=d; + m_r <= 48'((a_r - d_r) * b_r); + p_r <= 48'(m_r + 48'(c_r)); + end + end + assign p = p_r; +endmodule + +module dot4 ( + input bit clk, rst, + input bit [8:0] a0, b0, a1, b1, a2, b2, a3, b3, + output bit [19:0] p +); + bit [8:0] a0_r, b0_r, a1_r, b1_r, a2_r, b2_r, a3_r, b3_r; + bit [19:0] p_r; + always_ff @(posedge clk) begin + if (rst) begin + a0_r<=0; b0_r<=0; a1_r<=0; b1_r<=0; + a2_r<=0; b2_r<=0; a3_r<=0; b3_r<=0; + p_r<=0; + end else begin + a0_r<=a0; b0_r<=b0; a1_r<=a1; b1_r<=b1; + a2_r<=a2; b2_r<=b2; a3_r<=a3; b3_r<=b3; + p_r <= 20'(20'(a0_r*b0_r) + 20'(a1_r*b1_r) + 20'(a2_r*b2_r) + 20'(a3_r*b3_r)); + end + end + assign p = p_r; +endmodule + +// Oversized 24x24 MAC +module neg_mac24 (input clk, clear, input [23:0] a, b, output [47:0] p); + reg [23:0] a_r, b_r; reg [47:0] p_r; reg clear_r; + always_ff @(posedge clk) begin + a_r <= a; b_r <= b; clear_r <= clear; + p_r <= clear_r ? 48'(a_r*b_r) : 48'(p_r + 48'(a_r*b_r)); + end + assign p = p_r; +endmodule + +// Dot product with mixed 9x9 and 18x18 lanes +module neg_dot_mixed (input clk, input [8:0] a0,b0,a1,b1, input [17:0] a2, b2, output [35:0] p); + reg [8:0] a0_r,b0_r,a1_r,b1_r; reg [17:0] a2_r, b2_r; reg [35:0] p_r; + always_ff @(posedge clk) begin + a0_r<=a0; b0_r<=b0; a1_r<=a1; b1_r<=b1; a2_r<=a2; b2_r<=b2; + p_r <= 36'(36'(a0_r*b0_r) + 36'(a1_r*b1_r) + 36'(a2_r*b2_r)); + end + assign p = p_r; +endmodule diff --git a/tests/arch/nexus/fuse_mac.ys b/tests/arch/nexus/fuse_mac.ys new file mode 100644 index 000000000..e3e117130 --- /dev/null +++ b/tests/arch/nexus/fuse_mac.ys @@ -0,0 +1,35 @@ +read_verilog -sv fuse_mac.sv + +design -save pristine + +# 18x18 MAC +design -load pristine +hierarchy -top mac; +synth_nexus -family lifcl -top mac +select -assert-count 1 t:MULTADDSUB18X18 +select -assert-count 0 t:CCU2 + +# 18x18 pre-add MAC +design -load pristine +hierarchy -top madd_pre; +synth_nexus -family lifcl -top madd_pre +select -assert-count 1 t:MULTPREADD18X18 + +# 4-lane 9x9 dot product +design -load pristine +hierarchy -top dot4; +synth_nexus -family lifcl -top dot4 +select -assert-count 1 t:MULTADDSUB9X9WIDE + +# 24x24 MAC +design -load pristine +hierarchy -top neg_mac24; +synth_nexus -family lifcl -top neg_mac24 +select -assert-count 0 t:MULTADDSUB18X18 + +# mixed +design -load pristine +hierarchy -top neg_dot_mixed; +synth_nexus -family lifcl -top neg_dot_mixed +select -assert-count 0 t:MULTADDSUB9X9WIDE +select -assert-count 2 t:MULTADDSUB18X18 From 7fef67a1413c463af027265aa5f5c514dc6ca43a Mon Sep 17 00:00:00 2001 From: nella Date: Wed, 27 May 2026 15:09:27 +0200 Subject: [PATCH 068/354] Simplify nexus map. --- techlibs/lattice/dsp_map_nexus.v | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/techlibs/lattice/dsp_map_nexus.v b/techlibs/lattice/dsp_map_nexus.v index 35caacd10..61d2d96a8 100644 --- a/techlibs/lattice/dsp_map_nexus.v +++ b/techlibs/lattice/dsp_map_nexus.v @@ -78,7 +78,7 @@ module \$__NX_MUL9X9 (input [8:0] A, input [8:0] B, output [17:0] Y); ); endmodule -module \$__NX_MAC18X18 (A, B, C, Y); +module \$__NX_MAC18X18 (input [17:0] A, input [17:0] B, input [47:0] C, output [53:0] Y); parameter A_WIDTH = 18; parameter B_WIDTH = 18; @@ -87,12 +87,6 @@ module \$__NX_MAC18X18 (A, B, C, Y); parameter A_SIGNED = 0; parameter B_SIGNED = 0; parameter SUBTRACT = 0; - input [17:0] A; - input [17:0] B; - input [47:0] C; - output [47:0] Y; - wire [53:0] Z_out; - assign Y = Z_out[47:0]; MULTADDSUB18X18 #( .REGINPUTA("BYPASS"), @@ -105,23 +99,16 @@ module \$__NX_MAC18X18 (A, B, C, Y); .C({6'b0, C}), .SIGNED(A_SIGNED ? 1'b1 : 1'b0), .ADDSUB(SUBTRACT ? 1'b1 : 1'b0), - .Z(Z_out) + .Z(Y) ); endmodule -module \$__NX_PREADD18X18 (A, B, C, Y, CLK); +module \$__NX_PREADD18X18 (input [17:0] A, input [17:0] B, input [17:0] C, input CLK, output [35:0] Y); parameter PIPELINED = 0; parameter A_SIGNED = 0; parameter B_SIGNED = 0; parameter C_SIGNED = 0; - input [17:0] A; - input [17:0] B; - input [17:0] C; - input CLK; - output [47:0] Y; - wire [35:0] Z_out; - assign Y = A_SIGNED ? {{12{Z_out[35]}}, Z_out} : {12'b0, Z_out}; MULTPREADD18X18 #( .REGINPUTA("BYPASS"), @@ -136,17 +123,13 @@ module \$__NX_PREADD18X18 (A, B, C, Y, CLK); .SIGNEDA(A_SIGNED ? 1'b1 : 1'b0), .SIGNEDB(B_SIGNED ? 1'b1 : 1'b0), .SIGNEDC(C_SIGNED ? 1'b1 : 1'b0), - .Z(Z_out) + .Z(Y) ); endmodule -module \$__NX_MAC9X9WIDE_4LANE (A0, B0, A1, B1, A2, B2, A3, B3, Y); +module \$__NX_MAC9X9WIDE_4LANE (input [8:0] A0, B0, A1, B1, A2, B2, A3, B3, output [53:0] Y); parameter SIGNED = 0; - input [8:0] A0, B0, A1, B1, A2, B2, A3, B3; - output [47:0] Y; - wire [53:0] Z_out; - assign Y = Z_out[47:0]; MULTADDSUB9X9WIDE #( .REGINPUTAB0("BYPASS"), @@ -163,6 +146,6 @@ module \$__NX_MAC9X9WIDE_4LANE (A0, B0, A1, B1, A2, B2, A3, B3, Y); .C(54'b0), .SIGNED(SIGNED ? 1'b1 : 1'b0), .ADDSUB(4'b0000), - .Z(Z_out) + .Z(Y) ); endmodule From 14140126761cc94fe66f5af87bd588b4cddd5dbd Mon Sep 17 00:00:00 2001 From: nella Date: Wed, 27 May 2026 15:09:50 +0200 Subject: [PATCH 069/354] Add sign and op checks. --- techlibs/lattice/lattice_dsp_nexus.pmg | 175 +++++++++++++++---------- 1 file changed, 109 insertions(+), 66 deletions(-) diff --git a/techlibs/lattice/lattice_dsp_nexus.pmg b/techlibs/lattice/lattice_dsp_nexus.pmg index 73587b91c..5fb828bb9 100644 --- a/techlibs/lattice/lattice_dsp_nexus.pmg +++ b/techlibs/lattice/lattice_dsp_nexus.pmg @@ -15,21 +15,35 @@ match add endmatch code - SigSpec mul_out = port(mul, \Y); - IdString add_AB; - Cell *mac = module->addCell(NEW_ID, "$__NX_MAC18X18"); - IdString add_C = (add_AB == \A) ? \B : \A; + if (mul->getParam(\A_SIGNED).as_bool() != mul->getParam(\B_SIGNED).as_bool()) { + reject; + } - mac->setPort(\A, port(mul, \A)); - mac->setPort(\B, port(mul, \B)); - mac->setPort(\C, port(add, add_C)); - mac->setPort(\Y, port(add, \Y)); - mac->setParam(\A_SIGNED, mul->getParam(\A_SIGNED)); - mac->setParam(\B_SIGNED, mul->getParam(\B_SIGNED)); - mac->setParam(\SUBTRACT, add->type == $sub ? State::S1 : State::S0); + { + SigSpec mul_out = port(mul, \Y); + IdString add_AB; - autoremove(mul); - autoremove(add); + if (GetSize(port(add, \A)) >= GetSize(mul_out) && port(add, \A).extract(0, GetSize(mul_out)) == mul_out) { + add_AB = \A; + } else if (GetSize(port(add, \B)) >= GetSize(mul_out) && port(add, \B).extract(0, GetSize(mul_out)) == mul_out) { + add_AB = \B; + } else { + reject; + } + + Cell *mac = module->addCell(NEW_ID, "$__NX_MAC18X18"); + IdString add_C = (add_AB == \A) ? \B : \A; + + mac->setPort(\A, port(mul, \A)); + mac->setPort(\B, port(mul, \B)); + mac->setPort(\C, port(add, add_C)); + mac->setPort(\Y, port(add, \Y)); + mac->setParam(\A_SIGNED, mul->getParam(\A_SIGNED)); + mac->setParam(\SUBTRACT, add->type == $sub ? State::S1 : State::S0); + + autoremove(mul); + autoremove(add); + } accept; endcode @@ -57,41 +71,53 @@ endmatch code SigSpec preadd_out = port(preadd, \Y); IdString actual_mul_AB; - Cell *mac = module->addCell(NEW_ID, "$__NX_PREADD18X18"); - IdString mul_other = (actual_mul_AB == \A) ? \B : \A; - IdString sgn_AC = (mul_other == \A) ? \B_SIGNED : \A_SIGNED; - IdString sgn_B = (mul_other == \A) ? \A_SIGNED : \B_SIGNED; - - SigSpec sig_A = port(preadd, \A); - SigSpec sig_C = port(preadd, \B); - SigSpec sig_B = port(mul, mul_other); - - sig_A.extend_u0(18, false); - sig_C.extend_u0(18, false); - sig_B.extend_u0(18, false); - - mac->setPort(\A, sig_A.extract(0, 18)); - mac->setPort(\C, sig_C.extract(0, 18)); - mac->setPort(\B, sig_B.extract(0, 18)); - - if (pipe_ff) { - mac->setPort(\Y, port(pipe_ff, \Q)); - mac->setPort(\CLK, port(pipe_ff, \CLK)); - mac->setParam(\PIPELINED, State::S1); + if (GetSize(port(mul, \A)) >= GetSize(preadd_out) && port(mul, \A).extract(0, GetSize(preadd_out)) == preadd_out) { + actual_mul_AB = \A; + } else if (GetSize(port(mul, \B)) >= GetSize(preadd_out) && port(mul, \B).extract(0, GetSize(preadd_out)) == preadd_out) { + actual_mul_AB = \B; } else { - mac->setPort(\Y, port(mul, \Y)); - mac->setPort(\CLK, State::S0); - mac->setParam(\PIPELINED, State::S0); + reject; } - mac->setParam(\A_SIGNED, mul->getParam(sgn_AC)); - mac->setParam(\B_SIGNED, mul->getParam(sgn_B)); - mac->setParam(\C_SIGNED, mul->getParam(sgn_AC)); + { + Cell *mac = module->addCell(NEW_ID, "$__NX_PREADD18X18"); + + IdString mul_other = (actual_mul_AB == \A) ? \B : \A; + IdString sgn_AC = (mul_other == \A) ? \B_SIGNED : \A_SIGNED; + IdString sgn_B = (mul_other == \A) ? \A_SIGNED : \B_SIGNED; + + SigSpec sig_A = port(preadd, \A); + SigSpec sig_C = port(preadd, \B); + SigSpec sig_B = port(mul, mul_other); + + sig_A.extend_u0(18, false); + sig_C.extend_u0(18, false); + sig_B.extend_u0(18, false); + + mac->setPort(\A, sig_A.extract(0, 18)); + mac->setPort(\C, sig_C.extract(0, 18)); + mac->setPort(\B, sig_B.extract(0, 18)); + + if (pipe_ff) { + mac->setPort(\Y, port(pipe_ff, \Q)); + mac->setPort(\CLK, port(pipe_ff, \CLK)); + mac->setParam(\PIPELINED, State::S1); + } else { + mac->setPort(\Y, port(mul, \Y)); + mac->setPort(\CLK, State::S0); + mac->setParam(\PIPELINED, State::S0); + } + + mac->setParam(\A_SIGNED, mul->getParam(sgn_AC)); + mac->setParam(\B_SIGNED, mul->getParam(sgn_B)); + mac->setParam(\C_SIGNED, mul->getParam(sgn_AC)); + + if (pipe_ff) autoremove(pipe_ff); + autoremove(mul); + autoremove(preadd); + } - if (pipe_ff) autoremove(pipe_ff); - autoremove(mul); - autoremove(preadd); accept; endcode @@ -136,30 +162,47 @@ match mul0 endmatch code - Cell *mac = module->addCell(NEW_ID, "$__NX_MAC9X9WIDE_4LANE"); bool is_signed = mul0->getParam(\A_SIGNED).as_bool(); - auto ext9 = [&](SigSpec s) { - s.extend_u0(9, is_signed); - return s; - }; - mac->setPort(\A0, ext9(port(mul0, \A))); - mac->setPort(\B0, ext9(port(mul0, \B))); - mac->setPort(\A1, ext9(port(mul1, \A))); - mac->setPort(\B1, ext9(port(mul1, \B))); - mac->setPort(\A2, ext9(port(mul2, \A))); - mac->setPort(\B2, ext9(port(mul2, \B))); - mac->setPort(\A3, ext9(port(mul3, \A))); - mac->setPort(\B3, ext9(port(mul3, \B))); - mac->setPort(\Y, port(add_top, \Y)); - mac->setParam(\SIGNED, mul0->getParam(\A_SIGNED)); + if ( + mul0->getParam(\B_SIGNED).as_bool() != is_signed || + mul1->getParam(\A_SIGNED).as_bool() != is_signed || + mul1->getParam(\B_SIGNED).as_bool() != is_signed || + mul2->getParam(\A_SIGNED).as_bool() != is_signed || + mul2->getParam(\B_SIGNED).as_bool() != is_signed || + mul3->getParam(\A_SIGNED).as_bool() != is_signed || + mul3->getParam(\B_SIGNED).as_bool() != is_signed + ) { + reject; + } + + { + Cell *mac = module->addCell(NEW_ID, "$__NX_MAC9X9WIDE_4LANE"); + + auto ext9 = [&](SigSpec s) { + s.extend_u0(9, is_signed); + return s; + }; + + mac->setPort(\A0, ext9(port(mul0, \A))); + mac->setPort(\B0, ext9(port(mul0, \B))); + mac->setPort(\A1, ext9(port(mul1, \A))); + mac->setPort(\B1, ext9(port(mul1, \B))); + mac->setPort(\A2, ext9(port(mul2, \A))); + mac->setPort(\B2, ext9(port(mul2, \B))); + mac->setPort(\A3, ext9(port(mul3, \A))); + mac->setPort(\B3, ext9(port(mul3, \B))); + mac->setPort(\Y, port(add_top, \Y)); + mac->setParam(\SIGNED, is_signed ? State::S1 : State::S0); + + autoremove(add_top); + autoremove(add_mid); + autoremove(add_bot); + autoremove(mul0); + autoremove(mul1); + autoremove(mul2); + autoremove(mul3); + } - autoremove(add_top); - autoremove(add_mid); - autoremove(add_bot); - autoremove(mul0); - autoremove(mul1); - autoremove(mul2); - autoremove(mul3); accept; -endcode +endcode \ No newline at end of file From d8587f44f0566b5d442216ed12860f03cd7a49e2 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 28 May 2026 11:13:29 +0200 Subject: [PATCH 070/354] Putting back some Makefile.conf --- tests/common.mk | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/common.mk b/tests/common.mk index ef6982514..0e85e9fb9 100644 --- a/tests/common.mk +++ b/tests/common.mk @@ -1,9 +1,16 @@ ROOT_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) BUILD_DIR ?= $(ROOT_DIR)/.. +ifneq ($(wildcard $(ROOT_DIR)/../Makefile.conf),) +include $(ROOT_DIR)/../Makefile.conf +endif SBY ?= sby YOSYS ?= $(BUILD_DIR)/yosys +ifneq ($(ABCEXTERNAL),) +ABC ?= $(ABCEXTERNAL) +else ABC ?= $(BUILD_DIR)/yosys-abc +endif YOSYS_FILTERLIB ?= $(BUILD_DIR)/yosys-filterlib YOSYS_CONFIG ?= $(BUILD_DIR)/yosys-config YOSYS_SMTBMC ?= $(BUILD_DIR)/yosys-smtbmc From 1d86b3cd6eba3516a27ad1af91f0eeab7b4d5d87 Mon Sep 17 00:00:00 2001 From: Patrick Urban Date: Thu, 28 May 2026 14:46:25 +0200 Subject: [PATCH 071/354] gatemate: add option to create 'scopename' attributes when flattening the netlist --- techlibs/gatemate/synth_gatemate.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/techlibs/gatemate/synth_gatemate.cc b/techlibs/gatemate/synth_gatemate.cc index f7cdcbd12..6861b6780 100644 --- a/techlibs/gatemate/synth_gatemate.cc +++ b/techlibs/gatemate/synth_gatemate.cc @@ -56,6 +56,9 @@ struct SynthGateMatePass : public ScriptPass log(" -noflatten\n"); log(" do not flatten design before synthesis.\n"); log("\n"); + log(" -scopename\n"); + log(" create 'scopename' attributes when flattening the netlist.\n"); + log("\n"); log(" -nobram\n"); log(" do not use CC_BRAM_20K or CC_BRAM_40K cells in output netlist.\n"); log("\n"); @@ -94,7 +97,7 @@ struct SynthGateMatePass : public ScriptPass } string top_opt, vlog_file, json_file; - bool noflatten, nobram, noaddf, nomult, nomx4, nomx8, luttree, dff, retime, noiopad, noclkbuf, abc_new; + bool noflatten, scopename, nobram, noaddf, nomult, nomx4, nomx8, luttree, dff, retime, noiopad, noclkbuf, abc_new; void clear_flags() override { @@ -102,6 +105,7 @@ struct SynthGateMatePass : public ScriptPass vlog_file = ""; json_file = ""; noflatten = false; + scopename = false; nobram = false; noaddf = false; nomult = false; @@ -147,6 +151,10 @@ struct SynthGateMatePass : public ScriptPass noflatten = true; continue; } + if (args[argidx] == "-scopename") { + scopename = true; + continue; + } if (args[argidx] == "-nobram") { nobram = true; continue; @@ -220,7 +228,8 @@ struct SynthGateMatePass : public ScriptPass run("proc"); if (!noflatten) { run("check"); - run("flatten"); + std::string flatten_args = scopename ? " -scopename" : ""; + run("flatten" + flatten_args); } run("tribuf -logic"); run("deminout"); From 07e3d648aa26fb9f24802b5bb0b5b2e7b5d1c85b Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 29 May 2026 18:40:23 +1200 Subject: [PATCH 072/354] Add check_mem command Comes with a set of tests which (currently) pass with `read_verilog` but fail with `verific` based on #5878. Add `--check-sv`, an alternative to `--prove-sv` with generator defined yosys commands. Helpful for when you want to run the same set of commands on a bunch of sv files. --- passes/cmds/check.cc | 78 +++++++++++++++++++++++++++++++++ tests/check_mem/bad_il.ys | 47 ++++++++++++++++++++ tests/check_mem/generate_mk.py | 8 ++++ tests/check_mem/init.sv | 15 +++++++ tests/check_mem/non_zero.sv | 21 +++++++++ tests/check_mem/power_of_two.sv | 24 ++++++++++ tests/gen_tests_makefile.py | 21 +++++++-- 7 files changed, 210 insertions(+), 4 deletions(-) create mode 100644 tests/check_mem/bad_il.ys create mode 100644 tests/check_mem/generate_mk.py create mode 100644 tests/check_mem/init.sv create mode 100644 tests/check_mem/non_zero.sv create mode 100644 tests/check_mem/power_of_two.sv diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc index 6e0d65297..9a0070996 100644 --- a/passes/cmds/check.cc +++ b/passes/cmds/check.cc @@ -23,6 +23,7 @@ #include "kernel/newcelltypes.h" #include "kernel/utils.h" #include "kernel/log_help.h" +#include "kernel/mem.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -453,4 +454,81 @@ struct CheckPass : public Pass { } } CheckPass; +struct CheckMemPass : public Pass { + CheckMemPass() : Pass("check_mem", "check for obvious memory problems in the design") { } + bool formatted_help() override { + auto *help = PrettyHelp::get_current(); + help->set_group("passes/status"); + + auto content_root = help->get_root(); + + content_root->usage("check_mem [selection]"); + content_root->paragraph( + "This pass identifies the following problems in the current design: " + "addressing invalid memory." + ); + + content_root->option("-assert", "produce a runtime error if any problems are found in the current design"); + + return true; + } + void execute(std::vector args, RTLIL::Design *design) override + { + int counter = 0; + bool assert_mode = false; + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-assert") { + assert_mode = true; + continue; + } + break; + } + + extra_args(args, argidx, design); + + log_header(design, "Executing CHECK_MEM pass.\n"); + + for (auto *module : design->selected_unboxed_modules_warn()) { + for (auto mem : Mem::get_selected_memories(module)) { + int min_addr = mem.mem->start_offset; + int max_addr = mem.mem->size + min_addr - 1; + for (auto &init : mem.inits) { + int start = init.addr.as_int(); + if (start < min_addr) { + log_warning("Mem %s.%s starts at %d but initializes address %d.\n", log_id(module), log_id(mem.mem), min_addr, start); + counter++; + } + int end = start + (GetSize(init.data) / mem.width) - 1; + if (end > max_addr) { + log_warning("Mem %s.%s ends at %d but initializes address %d.\n", log_id(module), log_id(mem.mem), max_addr, end); + counter++; + } + } + + auto check_addr = [min_addr, max_addr, &counter, module, &mem](SigSpec &addr_sig, const char* access) { + if (addr_sig.is_fully_const()) { + auto addr = addr_sig.as_int(); + if (addr < min_addr || addr > max_addr) { + log_warning("Mem %s.%s contains entries for addresses %d..%d but %s address %d.\n", log_id(module), log_id(mem.mem), min_addr, max_addr, access, addr); + counter++; + } + } else { + // TODO test variable addresses? may need sat solver + } + }; + + // TODO test ABITS and WIDTH? + for (auto &rd_port : mem.rd_ports) + check_addr(rd_port.addr, "reads"); + for (auto &wr_port : mem.wr_ports) + check_addr(wr_port.addr, "writes"); + } + } + + if (assert_mode && counter > 0) + log_error("Found %d problems in 'check_mem -assert'.\n", counter); + } +} CheckMemPass; + PRIVATE_NAMESPACE_END diff --git a/tests/check_mem/bad_il.ys b/tests/check_mem/bad_il.ys new file mode 100644 index 000000000..06968c32c --- /dev/null +++ b/tests/check_mem/bad_il.ys @@ -0,0 +1,47 @@ +read_rtlil << EOF +module \top + wire input 1 \clk + wire output 1 \o + memory size 2 offset 1 \my_array + cell $meminit \bad_init + parameter \WORDS 1 + parameter \MEMID "\\my_array" + parameter \ABITS 32 + parameter \WIDTH 1 + parameter \PRIORITY 1 + connect \ADDR 0 + connect \DATA 1'0 + end + cell $memwr \bad_wr + parameter \MEMID "\\my_array" + parameter \CLK_ENABLE 1 + parameter \CLK_POLARITY 1 + parameter \PRIORITY 1 + parameter \ABITS 2 + parameter \WIDTH 1 + connect \EN 1'1 + connect \CLK \clk + connect \ADDR 2'00 + connect \DATA 1'0 + end + cell $memrd \bad_rd + parameter \MEMID "\\my_array" + parameter \CLK_ENABLE 0 + parameter \CLK_POLARITY 1 + parameter \TRANSPARENT 0 + parameter \ABITS 2 + parameter \WIDTH 1 + connect \CLK 1'x + connect \EN 1'x + connect \ADDR 2'11 + connect \DATA \o + end +end +EOF + +logger -expect warning "initializes address 0" 1 +logger -expect warning "writes address 0" 1 +logger -expect warning "reads address 3" 1 +check_mem +logger -check-expected +design -reset diff --git a/tests/check_mem/generate_mk.py b/tests/check_mem/generate_mk.py new file mode 100644 index 000000000..ee8dbeb44 --- /dev/null +++ b/tests/check_mem/generate_mk.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("..") + +import gen_tests_makefile + +gen_tests_makefile.generate(["--check-sv", "--yosys-scripts"], yosys_cmds="hierarchy; proc; check_mem -assert") diff --git a/tests/check_mem/init.sv b/tests/check_mem/init.sv new file mode 100644 index 000000000..f55a0d1c5 --- /dev/null +++ b/tests/check_mem/init.sv @@ -0,0 +1,15 @@ +module top ( + input logic clk, + input logic idx, + output logic [2:0] out_data +); + (* nomem2reg *) + logic my_array [3:2][2:0] = '{'{0, 1, 1}, '{1, 0, 1}}; + + always_comb begin + for (int i=0; i < 3; i++) begin + out_data[i] = my_array[{1'b1, idx}][i]; + end + end + +endmodule diff --git a/tests/check_mem/non_zero.sv b/tests/check_mem/non_zero.sv new file mode 100644 index 000000000..5b3f45c0a --- /dev/null +++ b/tests/check_mem/non_zero.sv @@ -0,0 +1,21 @@ +module top ( + input logic clk, + input logic [3:1][2:0] in_data, + output logic [3:1][2:0] out_data +); + (* nomem2reg *) + logic [2:0] my_array [3:1]; + + always_ff @(posedge clk) begin + for (int i = 1; i <= 3; i++) begin + my_array[i] <= in_data[i]; + end + end + + always_comb begin + for (int i = 1; i <= 3; i++) begin + out_data[i] = my_array[i]; + end + end + +endmodule diff --git a/tests/check_mem/power_of_two.sv b/tests/check_mem/power_of_two.sv new file mode 100644 index 000000000..786168ea0 --- /dev/null +++ b/tests/check_mem/power_of_two.sv @@ -0,0 +1,24 @@ +module top ( + input logic clk, + input logic [1:0][5:0] in_data, + output logic [1:0][5:0] out_data +); + (* nomem2reg *) + logic my_array [1:0][5:0]; + + always_ff @(posedge clk) begin + for (int i = 0; i < 2; i++) begin + for (int j = 0; j <= 5; j++) begin + my_array[i][j] <= in_data[i][j]; + end + end + end + + always_comb begin + for (int i = 0; i < 2; i++) begin + for (int j = 0; j <= 5; j++) begin + out_data[i][j] = my_array[i][j]; + end + end + end +endmodule diff --git a/tests/gen_tests_makefile.py b/tests/gen_tests_makefile.py index 034883a2c..efaa9a652 100644 --- a/tests/gen_tests_makefile.py +++ b/tests/gen_tests_makefile.py @@ -37,6 +37,11 @@ def generate_tcl_test(tcl_file, yosys_args="", commands=""): cmd += f"; \\\n{commands}" generate_target(tcl_file, cmd) +def generate_sv_check(sv_file, yosys_args="", yosys_cmds=""): + yosys_cmd = f'read -sv {sv_file}; {yosys_cmds}' + cmd = f'$(YOSYS) -ql {sv_file}.err -p "{yosys_cmd}" {yosys_args} && mv {sv_file}.err {sv_file}.log' + generate_target(sv_file, cmd) + def generate_sv_test(sv_file, yosys_args="", commands=""): base = os.path.splitext(sv_file)[0] if not os.path.exists(base + ".ys"): @@ -62,19 +67,23 @@ def unpack_cmd(cmd): def generate_cmd_test(test_name, cmd, yosys_args="", deps = None): generate_target(test_name, unpack_cmd(cmd), deps) -def generate_tests(argv, cmds): +def generate_tests(argv, cmds, yosys_cmds=""): parser = argparse.ArgumentParser(add_help=False) parser.add_argument("-y", "--yosys-scripts", action="store_true") parser.add_argument("-t", "--tcl-scripts", action="store_true") + parser.add_argument("-c", "--check-sv", action="store_true") parser.add_argument("-s", "--prove-sv", action="store_true") parser.add_argument("-b", "--bash", action="store_true") parser.add_argument("-a", "--yosys-args", default="") args = parser.parse_args(argv) - if not (args.yosys_scripts or args.tcl_scripts or args.prove_sv or args.bash): + if not (args.yosys_scripts or args.tcl_scripts or args.check_sv or args.prove_sv or args.bash): raise RuntimeError("No file types selected") + if args.check_sv and args.prove_sv: + raise RuntimeError("Unable to use --check-sv and --prove-sv together") + if args.yosys_scripts: for f in sorted(glob.glob("*.ys")): generate_ys_test(f, args.yosys_args, cmds) @@ -83,6 +92,10 @@ def generate_tests(argv, cmds): for f in sorted(glob.glob("*.tcl")): generate_tcl_test(f, args.yosys_args, cmds) + if args.check_sv: + for f in sorted(glob.glob("*.sv")): + generate_sv_check(f, args.yosys_args, yosys_cmds) + if args.prove_sv: for f in sorted(glob.glob("*.sv")): generate_sv_test(f, args.yosys_args, cmds) @@ -109,11 +122,11 @@ def redirect_stdout(new_target): finally: sys.stdout = old_target -def generate(argv, extra=None, cmds=""): +def generate(argv, extra=None, cmds="", yosys_cmds=""): with open("Makefile", "w") as f: with redirect_stdout(f): print_header(extra) - generate_tests(argv, cmds) + generate_tests(argv, cmds, yosys_cmds) def generate_custom(callback, extra=None): with open("Makefile", "w") as f: From 7cf0c554665f40a8ba717e98ab393b009fe819f1 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 29 May 2026 18:40:23 +1200 Subject: [PATCH 073/354] verific: Fix non-contiguous memory flattening May not be the best approach, insofar as it uses empty memory elements for padding out the alignment, but it does avoid costly address arithmetic. Still needs to adjust ascii init val addresses, but should work fine for read/write accesses. --- frontends/verific/verific.cc | 81 ++++++++++++++++++++++++++++++------ 1 file changed, 69 insertions(+), 12 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 6b876c0f1..76a5c13bc 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -1630,22 +1630,78 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma import_attributes(memory->attributes, net, nl); int number_of_bits = net->Size(); - int bits_in_word = number_of_bits; + int min_bits_in_word = number_of_bits; + int max_bits_in_addr = 0; + + // get the size of each memory access FOREACH_PORTREF_OF_NET(net, si, pr) { - if (pr->GetInst()->Type() == OPER_READ_PORT) { - bits_in_word = min(bits_in_word, pr->GetInst()->OutputSize()); - continue; + auto *inst = pr->GetInst(); + int bits_in_word; + if (inst->Type() == OPER_READ_PORT) + bits_in_word = inst->OutputSize(); + else if (inst->Type() == OPER_WRITE_PORT || inst->Type() == OPER_CLOCKED_WRITE_PORT) + bits_in_word = inst->Input2Size(); + else + log_error("%sVerific RamNet %s is connected to unsupported instance type %s (%s).\n", announce_src_location(inst), + net->Name(), inst->View()->Owner()->Name(), inst->Name()); + + if (bits_in_word < min_bits_in_word) { + min_bits_in_word = bits_in_word; + max_bits_in_addr = inst->Input1Size(); } - if (pr->GetInst()->Type() == OPER_WRITE_PORT || pr->GetInst()->Type() == OPER_CLOCKED_WRITE_PORT) { - bits_in_word = min(bits_in_word, pr->GetInst()->Input2Size()); - continue; - } - log_error("%sVerific RamNet %s is connected to unsupported instance type %s (%s).\n", announce_src_location(pr->GetInst()), - net->Name(), pr->GetInst()->View()->Owner()->Name(), pr->GetInst()->Name()); } - memory->width = bits_in_word; - memory->size = number_of_bits / bits_in_word; + int number_of_words = number_of_bits / min_bits_in_word; + // TODO Verific has u64 sizes + int size = 1 << max_bits_in_addr; + int min_idx = 0; + int max_idx = size - 1; + + // attempt to infer min/max address for memory definition + RTLIL::SigSpec min_addr, max_addr; + auto typeRange = net->GetOrigTypeRange(); + while (typeRange) { + RTLIL::SigSpec min_addr_chunk(RTLIL::Const(typeRange->RightRangeBound(), typeRange->NumBits())); + min_addr_chunk.reverse(); + min_addr.append(min_addr_chunk); + + RTLIL::SigSpec max_addr_chunk(RTLIL::Const(typeRange->LeftRangeBound(), typeRange->NumBits())); + max_addr_chunk.reverse(); + max_addr.append(max_addr_chunk); + + typeRange = typeRange->GetNext(); + } + min_addr = min_addr.extract(0, max_bits_in_addr); + max_addr = max_addr.extract(0, max_bits_in_addr); + min_addr.reverse(); + max_addr.reverse(); + + if (min_addr.convertible_to_int()) { + min_idx = min_addr.as_int(); + if (max_addr.convertible_to_int()) { + max_idx = max_addr.as_int(); + } else { + log_debug("Unable to set maximum index\n"); + } + size = max_idx - min_idx + 1; + } else { + log_debug("Unable to set minimum index\n"); + } + + // sanity check we haven't shrunk the memory + log_assert(size >= number_of_words); + + memory->width = min_bits_in_word; + memory->size = size; + memory->start_offset = min_idx; + + // warn on oversize memories + // TODO consider using a minimum ratio? + if (size > number_of_words) { + float ratio = size / (float)number_of_words; + log_warning("RAM for identifier '%s' may be up to %.0f%% oversize due to addressing\n", net->Name(), (ratio-1)*100); + log_debug("Expected memory of size %d words, but got %d for address range %d to %d (inclusive)\n", number_of_words, size, min_idx, max_idx); + } const char *ascii_initdata = net->GetWideInitialValue(); if (ascii_initdata) { @@ -1672,6 +1728,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma if (initval_valid) { RTLIL::Cell *cell = module->addCell(new_verific_id(net), ID($meminit)); cell->parameters[ID::WORDS] = 1; + // TODO non contiguous memory addressing if (net->GetOrigTypeRange()->LeftRangeBound() < net->GetOrigTypeRange()->RightRangeBound()) cell->setPort(ID::ADDR, word_idx); else From 099c664dc9cb08955dba5ae508bc7801b24e3e54 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 29 May 2026 18:40:23 +1200 Subject: [PATCH 074/354] verific: Fix upto ranges --- frontends/verific/verific.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 76a5c13bc..74ebcc2be 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -1661,11 +1661,13 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma RTLIL::SigSpec min_addr, max_addr; auto typeRange = net->GetOrigTypeRange(); while (typeRange) { - RTLIL::SigSpec min_addr_chunk(RTLIL::Const(typeRange->RightRangeBound(), typeRange->NumBits())); + auto left = typeRange->LeftRangeBound(); + auto right = typeRange->RightRangeBound(); + RTLIL::SigSpec min_addr_chunk(RTLIL::Const(left > right ? right : left, typeRange->NumBits())); min_addr_chunk.reverse(); min_addr.append(min_addr_chunk); - RTLIL::SigSpec max_addr_chunk(RTLIL::Const(typeRange->LeftRangeBound(), typeRange->NumBits())); + RTLIL::SigSpec max_addr_chunk(RTLIL::Const(left > right ? left : right, typeRange->NumBits())); max_addr_chunk.reverse(); max_addr.append(max_addr_chunk); From f6327cc4447187f19658e01833eb2d6ec26f553c Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 29 May 2026 18:40:24 +1200 Subject: [PATCH 075/354] check_mem: Add -non-const option Can identify potentially dangerous addressing, but also prone to false-positives. --- passes/cmds/check.cc | 20 ++++++++++-- tests/check_mem/variable.ys | 65 +++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 tests/check_mem/variable.ys diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc index 9a0070996..426216800 100644 --- a/passes/cmds/check.cc +++ b/passes/cmds/check.cc @@ -468,6 +468,7 @@ struct CheckMemPass : public Pass { "addressing invalid memory." ); + content_root->option("-non-const", "also check non-const address signals (may produce false-positives)"); content_root->option("-assert", "produce a runtime error if any problems are found in the current design"); return true; @@ -476,12 +477,17 @@ struct CheckMemPass : public Pass { { int counter = 0; bool assert_mode = false; + bool nonconst_mode = false; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { if (args[argidx] == "-assert") { assert_mode = true; continue; } + if (args[argidx] == "-non-const") { + nonconst_mode = true; + continue; + } break; } @@ -506,19 +512,27 @@ struct CheckMemPass : public Pass { } } - auto check_addr = [min_addr, max_addr, &counter, module, &mem](SigSpec &addr_sig, const char* access) { + auto check_addr = [min_addr, max_addr, &counter, module, &mem, &nonconst_mode](SigSpec &addr_sig, const char* access) { if (addr_sig.is_fully_const()) { auto addr = addr_sig.as_int(); if (addr < min_addr || addr > max_addr) { log_warning("Mem %s.%s contains entries for addresses %d..%d but %s address %d.\n", log_id(module), log_id(mem.mem), min_addr, max_addr, access, addr); counter++; } - } else { - // TODO test variable addresses? may need sat solver + } else if (nonconst_mode) { + // TODO check addr_sig.has_const() for constant MSb/LSb that may change effective min/max + // TODO consider sat solver for variable addresses + int addr_sig_min = 0; + int addr_sig_max = (1 << addr_sig.size()) - 1; + if (min_addr > addr_sig_min || max_addr < addr_sig_max) { + log_warning("Mem %s.%s contains entries for addresses %d..%d but has a potentially dangerous non-const input %s\n", log_id(module), log_id(mem.mem), min_addr, max_addr, log_signal(addr_sig)); + counter++; + } } }; // TODO test ABITS and WIDTH? + // TODO can we limit ports via selection? for (auto &rd_port : mem.rd_ports) check_addr(rd_port.addr, "reads"); for (auto &wr_port : mem.wr_ports) diff --git a/tests/check_mem/variable.ys b/tests/check_mem/variable.ys new file mode 100644 index 000000000..8da49758b --- /dev/null +++ b/tests/check_mem/variable.ys @@ -0,0 +1,65 @@ + + +read_rtlil << EOF +module \top + wire input 1 \clk + wire input 2 width 2 \addr + wire output 1 \o + memory size 3 offset 0 \my_array + # potentially dangerous - requires external control to avoid illegal access + cell $memrd \bad_rd + parameter \MEMID "\\my_array" + parameter \CLK_ENABLE 0 + parameter \CLK_POLARITY 1 + parameter \TRANSPARENT 0 + parameter \ABITS 2 + parameter \WIDTH 1 + connect \CLK 1'x + connect \EN 1'x + connect \ADDR \addr + connect \DATA \o + end + wire width 2 \n_addr + cell $not \not_addr + parameter \A_SIGNED 0 + parameter \A_WIDTH 2 + parameter \Y_WIDTH 2 + connect \A \addr + connect \Y \n_addr + end + # address is partially const, making the illegal access of 2'11 impossible + cell $memrd \partial_const_rd + parameter \MEMID "\\my_array" + parameter \CLK_ENABLE 0 + parameter \CLK_POLARITY 1 + parameter \TRANSPARENT 0 + parameter \ABITS 2 + parameter \WIDTH 1 + connect \CLK 1'x + connect \EN 1'x + connect \ADDR { 1'0 \addr [0] } + connect \DATA \o + end + # address is non-const but limited to 2'10 and 2'01 - both of which are valid + cell $memrd \limited_rd + parameter \MEMID "\\my_array" + parameter \CLK_ENABLE 0 + parameter \CLK_POLARITY 1 + parameter \TRANSPARENT 0 + parameter \ABITS 2 + parameter \WIDTH 1 + connect \CLK 1'x + connect \EN 1'x + connect \ADDR { \n_addr [0] \addr [0] } + connect \DATA \o + end +end +EOF + +logger -expect warning "potentially dangerous non-const input \\addr" 1 +# unhandled false-positives +# logger -werror "potentially dangerous non-const input \{ 1'0" +# logger -werror "potentially dangerous non-const input \{ \\n_addr" +check_mem -non-const +logger -check-expected +design -reset From aac7366862af73a4b51b452f44fb1339f828d607 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 29 May 2026 18:40:24 +1200 Subject: [PATCH 076/354] tests: Add check_mem to vanilla-test --- tests/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Makefile b/tests/Makefile index 05e5410b7..6c2689c79 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -78,6 +78,7 @@ MK_TEST_DIRS += ./liberty MK_TEST_DIRS += ./memories MK_TEST_DIRS += ./aiger MK_TEST_DIRS += ./alumacc +MK_TEST_DIRS += ./check_mem all: vanilla-test From ab5f25db9a0c498342caac1d19afce83bbd7e1cd Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 29 May 2026 18:40:24 +1200 Subject: [PATCH 077/354] Add test for non-contiguous memory init Also negative memory addresses. --- tests/check_mem/init_correct.ys | 44 +++++++++++++++++++++++++++++++++ tests/check_mem/negative_idx.sv | 13 ++++++++++ 2 files changed, 57 insertions(+) create mode 100644 tests/check_mem/init_correct.ys create mode 100644 tests/check_mem/negative_idx.sv diff --git a/tests/check_mem/init_correct.ys b/tests/check_mem/init_correct.ys new file mode 100644 index 000000000..5e922c7df --- /dev/null +++ b/tests/check_mem/init_correct.ys @@ -0,0 +1,44 @@ +read -sv << EOT +module top; + (* nomem2reg *) + logic a1 [2:3][3:1] = '{'{0, 1, 1}, '{1, 0, 1}}; + + always_comb begin + assert(a1[2][3] == 0); + assert(a1[2][2] == 1); + assert(a1[2][1] == 1); + assert(a1[3][3] == 1); + assert(a1[3][2] == 0); + assert(a1[3][1] == 1); + end + + (* nomem2reg *) + logic [1:0] a2 [6:5][2:4] = '{'{0, 1, 2}, '{1, 0, 3}}; + + always_comb begin + assert(a2[6][2] == 0); + assert(a2[6][3] == 1); + assert(a2[6][4] == 2); + assert(a2[5][2] == 1); + assert(a2[5][3] == 0); + assert(a2[5][4] == 3); + end + + (* nomem2reg *) + logic [1:0] a3 [-2:-1][-1:1] = '{'{0, 1, 2}, '{1, 0, 3}}; + + always_comb begin + assert(a3[-2][-1] == 0); + assert(a3[-2][0] == 1); + assert(a3[-2][1] == 2); + assert(a3[-1][-1] == 1); + assert(a3[-1][0] == 0); + assert(a3[-1][1] == 3); + end +endmodule +EOT +hierarchy +proc +memory +async2sync +sat -enable_undef -verify -prove-asserts diff --git a/tests/check_mem/negative_idx.sv b/tests/check_mem/negative_idx.sv new file mode 100644 index 000000000..dcfad94a3 --- /dev/null +++ b/tests/check_mem/negative_idx.sv @@ -0,0 +1,13 @@ +module top; + (* nomem2reg *) + logic [1:0] a3 [-2:-1][-1:1] = '{'{0, 1, 2}, '{1, 0, 3}}; + + always_comb begin + assert(a3[-2][-1] == 0); + assert(a3[-2][0] == 1); + assert(a3[-2][1] == 2); + assert(a3[-1][-1] == 1); + assert(a3[-1][0] == 0); + assert(a3[-1][1] == 3); + end +endmodule \ No newline at end of file From 21966ef496fc11ffc6a9e5076a095f5d30e7ce92 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 29 May 2026 18:40:25 +1200 Subject: [PATCH 078/354] verific: Fix non-contiguous memory init Recurse over nested type ranges to calculate true addresses. --- frontends/verific/verific.cc | 66 +++++++++++++++++++++--------------- frontends/verific/verific.h | 3 ++ 2 files changed, 42 insertions(+), 27 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 74ebcc2be..24c91c3c4 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -1444,6 +1444,44 @@ static std::string sha1_if_contain_spaces(std::string str) return str; } +void VerificImporter::recurse_ascii_initdata(RTLIL::Module *module, RTLIL::Memory *memory, Net *net, const char *&ascii_initdata, TypeRange *typeRange, int base_idx) { + if (typeRange == nullptr) + typeRange = net->GetOrigTypeRange(); + + auto *nextRange = typeRange->GetNext(); + base_idx <<= typeRange->NumBits(); + auto left = typeRange->LeftRangeBound(); + auto right = typeRange->RightRangeBound(); + for (auto i = left; left < right ? i <= right : i >= right; left < right ? i++ : i--) { + auto next_idx = base_idx + i; + if (nextRange != nullptr) { + recurse_ascii_initdata(module, memory, net, ascii_initdata, nextRange, next_idx); + } else { + Const initval = Const(State::Sx, memory->width); + bool initval_valid = false; + for (int bit_idx = memory->width-1; bit_idx >= 0; bit_idx--) { + if (*ascii_initdata == 0) + break; + if (*ascii_initdata == '0' || *ascii_initdata == '1') { + initval.set(bit_idx, (*ascii_initdata == '0') ? State::S0 : State::S1); + initval_valid = true; + } + ascii_initdata++; + } + if (initval_valid) { + RTLIL::Cell *cell = module->addCell(new_verific_id(net), ID($meminit)); + cell->parameters[ID::WORDS] = 1; + cell->setPort(ID::ADDR, next_idx); + cell->setPort(ID::DATA, initval); + cell->parameters[ID::MEMID] = RTLIL::Const(memory->name.str()); + cell->parameters[ID::ABITS] = 32; + cell->parameters[ID::WIDTH] = memory->width; + cell->parameters[ID::PRIORITY] = RTLIL::Const(autoidx-1); + } + } + } +} + void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::map &nl_todo, bool norename) { std::string netlist_name = nl->GetAtt(" \\top") || is_blackbox(nl) ? nl->CellBaseName() : nl->Owner()->Name(); @@ -1715,33 +1753,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma log_assert(*ascii_initdata == 'b'); ascii_initdata++; } - for (int word_idx = 0; word_idx < memory->size; word_idx++) { - Const initval = Const(State::Sx, memory->width); - bool initval_valid = false; - for (int bit_idx = memory->width-1; bit_idx >= 0; bit_idx--) { - if (*ascii_initdata == 0) - break; - if (*ascii_initdata == '0' || *ascii_initdata == '1') { - initval.set(bit_idx, (*ascii_initdata == '0') ? State::S0 : State::S1); - initval_valid = true; - } - ascii_initdata++; - } - if (initval_valid) { - RTLIL::Cell *cell = module->addCell(new_verific_id(net), ID($meminit)); - cell->parameters[ID::WORDS] = 1; - // TODO non contiguous memory addressing - if (net->GetOrigTypeRange()->LeftRangeBound() < net->GetOrigTypeRange()->RightRangeBound()) - cell->setPort(ID::ADDR, word_idx); - else - cell->setPort(ID::ADDR, memory->size - word_idx - 1); - cell->setPort(ID::DATA, initval); - cell->parameters[ID::MEMID] = RTLIL::Const(memory->name.str()); - cell->parameters[ID::ABITS] = 32; - cell->parameters[ID::WIDTH] = memory->width; - cell->parameters[ID::PRIORITY] = RTLIL::Const(autoidx-1); - } - } + recurse_ascii_initdata(module, memory, net, ascii_initdata); } continue; } diff --git a/frontends/verific/verific.h b/frontends/verific/verific.h index f33a380f7..478ab82cb 100644 --- a/frontends/verific/verific.h +++ b/frontends/verific/verific.h @@ -66,6 +66,9 @@ struct VerificClocking { struct VerificImporter { +private: + void recurse_ascii_initdata(RTLIL::Module *module, RTLIL::Memory *memory, Verific::Net *net, const char *&ascii_initdata, Verific::TypeRange *typeRange = nullptr, int base_idx = 0); +public: RTLIL::Module *module; Verific::Netlist *netlist; From 52e0030cc52a3af6a65de62c54b47f3476244f64 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 29 May 2026 18:40:25 +1200 Subject: [PATCH 079/354] tests/check_mem: Add problematic case Verific reports it as 16 2-bit addresses, meaning we have to iterate over the last dimension while skipping indices. --- tests/check_mem/negative_idx.sv | 2 +- tests/check_mem/sub_addr.sv | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 tests/check_mem/sub_addr.sv diff --git a/tests/check_mem/negative_idx.sv b/tests/check_mem/negative_idx.sv index dcfad94a3..99a26cdae 100644 --- a/tests/check_mem/negative_idx.sv +++ b/tests/check_mem/negative_idx.sv @@ -10,4 +10,4 @@ module top; assert(a3[-1][0] == 0); assert(a3[-1][1] == 3); end -endmodule \ No newline at end of file +endmodule diff --git a/tests/check_mem/sub_addr.sv b/tests/check_mem/sub_addr.sv new file mode 100644 index 000000000..cc4cb3ba3 --- /dev/null +++ b/tests/check_mem/sub_addr.sv @@ -0,0 +1,32 @@ +module memtest05(clk, addr, wdata, rdata, wen); + +input clk; +input [1:0] addr; +input [7:0] wdata; +output reg [7:0] rdata; +input [3:0] wen; + +reg [7:0] mem [0:3] = {8'h01, 8'h23, 8'h45, 8'h67}; + +integer i; +always @(posedge clk) begin + for (i = 0; i < 4; i = i+1) + if (wen[i]) mem[addr][i*2 +: 2] <= wdata[i*2 +: 2]; + rdata <= mem[addr]; +end + +always @(posedge clk) begin + // not sure how to verify this one without SBY + // or alternatively, how to replicate the problematic sub addressing without the read&write + assume (wen == 0); + assert (mem[0][7:4] == 4'h0); + assert (mem[0][3:0] == 4'h1); + assert (mem[1][7:4] == 4'h2); + assert (mem[1][3:0] == 4'h3); + assert (mem[2][7:4] == 4'h4); + assert (mem[2][3:0] == 4'h5); + assert (mem[3][7:4] == 4'h6); + assert (mem[3][3:0] == 4'h7); +end + +endmodule From 5f53410db71d76f55af5f98cf998ffa4e567169e Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 29 May 2026 18:40:25 +1200 Subject: [PATCH 080/354] verific: Fix negative array dimensions Recurse over memory dimensions once, doing both our min/max address checking and parsing out the initval. This also avoids problems with negative numbers (if `a < b` and one or both are negative, `a` might be the intended `max_addr_chunk`). Fix sub addressing, where we use some but not all of the current dimension's bits. --- frontends/verific/verific.cc | 119 ++++++++++++++++------------------- frontends/verific/verific.h | 2 +- 2 files changed, 56 insertions(+), 65 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 24c91c3c4..4d1bd0e48 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -1444,30 +1444,48 @@ static std::string sha1_if_contain_spaces(std::string str) return str; } -void VerificImporter::recurse_ascii_initdata(RTLIL::Module *module, RTLIL::Memory *memory, Net *net, const char *&ascii_initdata, TypeRange *typeRange, int base_idx) { +void VerificImporter::recurse_mem_dimensions(RTLIL::Module *module, RTLIL::Memory *memory, Net *net, const char *&ascii_initdata, int max_bits_in_addr, const RTLIL::SigSpec &prefix, TypeRange *typeRange) { if (typeRange == nullptr) typeRange = net->GetOrigTypeRange(); auto *nextRange = typeRange->GetNext(); - base_idx <<= typeRange->NumBits(); auto left = typeRange->LeftRangeBound(); auto right = typeRange->RightRangeBound(); - for (auto i = left; left < right ? i <= right : i >= right; left < right ? i++ : i--) { - auto next_idx = base_idx + i; - if (nextRange != nullptr) { - recurse_ascii_initdata(module, memory, net, ascii_initdata, nextRange, next_idx); + bool is_up = left < right; + for (auto i = left; is_up ? i <= right : i >= right; is_up ? i++ : i--) { + // TODO verific can do u64 + auto max_bits = max_bits_in_addr - prefix.size(); + auto next_sig = SigSpec(Const(i, typeRange->NumBits())); + auto extra_bits = next_sig.size() - max_bits; + if (extra_bits > 0) { + next_sig = next_sig.extract_end(extra_bits); + auto extra_inc = (1 << extra_bits) - 1; + i = is_up ? i + extra_inc : i - extra_inc; + } + next_sig.append(prefix); + if (nextRange != nullptr && extra_bits < 0) { + recurse_mem_dimensions(module, memory, net, ascii_initdata, max_bits_in_addr, next_sig, nextRange); } else { + if (next_sig.size() != max_bits_in_addr) { + // TODO verific can do u64 + log_error("Expected %d bits for addr but got %d!\n", max_bits_in_addr, next_sig.size()); + } Const initval = Const(State::Sx, memory->width); bool initval_valid = false; - for (int bit_idx = memory->width-1; bit_idx >= 0; bit_idx--) { - if (*ascii_initdata == 0) - break; - if (*ascii_initdata == '0' || *ascii_initdata == '1') { - initval.set(bit_idx, (*ascii_initdata == '0') ? State::S0 : State::S1); - initval_valid = true; + if (ascii_initdata) { + for (int bit_idx = memory->width-1; bit_idx >= 0; bit_idx--) { + if (*ascii_initdata == 0) + break; + if (*ascii_initdata == '0' || *ascii_initdata == '1') { + initval.set(bit_idx, (*ascii_initdata == '0') ? State::S0 : State::S1); + initval_valid = true; + } + ascii_initdata++; } - ascii_initdata++; } + if (!next_sig.convertible_to_int()) + log_error("Address %s on RAM for identifier '%s' too wide!\n", log_signal(next_sig), net->Name()); + auto next_idx = next_sig.as_int(); if (initval_valid) { RTLIL::Cell *cell = module->addCell(new_verific_id(net), ID($meminit)); cell->parameters[ID::WORDS] = 1; @@ -1478,6 +1496,8 @@ void VerificImporter::recurse_ascii_initdata(RTLIL::Module *module, RTLIL::Memor cell->parameters[ID::WIDTH] = memory->width; cell->parameters[ID::PRIORITY] = RTLIL::Const(autoidx-1); } + memory->start_offset = min(memory->start_offset, next_idx); + memory->size = max(memory->size, next_idx); } } } @@ -1690,58 +1710,10 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma } int number_of_words = number_of_bits / min_bits_in_word; - // TODO Verific has u64 sizes - int size = 1 << max_bits_in_addr; - int min_idx = 0; - int max_idx = size - 1; - - // attempt to infer min/max address for memory definition - RTLIL::SigSpec min_addr, max_addr; - auto typeRange = net->GetOrigTypeRange(); - while (typeRange) { - auto left = typeRange->LeftRangeBound(); - auto right = typeRange->RightRangeBound(); - RTLIL::SigSpec min_addr_chunk(RTLIL::Const(left > right ? right : left, typeRange->NumBits())); - min_addr_chunk.reverse(); - min_addr.append(min_addr_chunk); - - RTLIL::SigSpec max_addr_chunk(RTLIL::Const(left > right ? left : right, typeRange->NumBits())); - max_addr_chunk.reverse(); - max_addr.append(max_addr_chunk); - - typeRange = typeRange->GetNext(); - } - min_addr = min_addr.extract(0, max_bits_in_addr); - max_addr = max_addr.extract(0, max_bits_in_addr); - min_addr.reverse(); - max_addr.reverse(); - - if (min_addr.convertible_to_int()) { - min_idx = min_addr.as_int(); - if (max_addr.convertible_to_int()) { - max_idx = max_addr.as_int(); - } else { - log_debug("Unable to set maximum index\n"); - } - size = max_idx - min_idx + 1; - } else { - log_debug("Unable to set minimum index\n"); - } - - // sanity check we haven't shrunk the memory - log_assert(size >= number_of_words); memory->width = min_bits_in_word; - memory->size = size; - memory->start_offset = min_idx; - - // warn on oversize memories - // TODO consider using a minimum ratio? - if (size > number_of_words) { - float ratio = size / (float)number_of_words; - log_warning("RAM for identifier '%s' may be up to %.0f%% oversize due to addressing\n", net->Name(), (ratio-1)*100); - log_debug("Expected memory of size %d words, but got %d for address range %d to %d (inclusive)\n", number_of_words, size, min_idx, max_idx); - } + memory->size = 0; + memory->start_offset = INT_MAX; const char *ascii_initdata = net->GetWideInitialValue(); if (ascii_initdata) { @@ -1753,7 +1725,26 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma log_assert(*ascii_initdata == 'b'); ascii_initdata++; } - recurse_ascii_initdata(module, memory, net, ascii_initdata); + } + + // process initdata and fixup min/max address + auto prefix = SigSpec(); + recurse_mem_dimensions(module, memory, net, ascii_initdata, max_bits_in_addr, prefix); + + auto min_idx = memory->start_offset; + auto max_idx = memory->size; + memory->size = max_idx - min_idx + 1; + + // sanity check we haven't shrunk the memory + if (memory->size < number_of_words) + log_error("Expected memory of size %d words, but got %d for address range %d to %d (inclusive)\n", number_of_words, memory->size, min_idx, max_idx); + + // warn on oversize memories + // TODO consider using a minimum ratio? + if (memory->size > number_of_words) { + float ratio = memory->size / (float)number_of_words; + log_warning("RAM for identifier '%s' may be up to %.0f%% oversize due to addressing\n", net->Name(), (ratio-1)*100); + log_debug("Expected memory of size %d words, but got %d for address range %d to %d (inclusive)\n", number_of_words, memory->size, min_idx, max_idx); } continue; } diff --git a/frontends/verific/verific.h b/frontends/verific/verific.h index 478ab82cb..0bd4d800a 100644 --- a/frontends/verific/verific.h +++ b/frontends/verific/verific.h @@ -67,7 +67,7 @@ struct VerificClocking { struct VerificImporter { private: - void recurse_ascii_initdata(RTLIL::Module *module, RTLIL::Memory *memory, Verific::Net *net, const char *&ascii_initdata, Verific::TypeRange *typeRange = nullptr, int base_idx = 0); + void recurse_mem_dimensions(RTLIL::Module *module, RTLIL::Memory *memory, Verific::Net *net, const char *&ascii_initdata, int max_bits_in_addr, const RTLIL::SigSpec &prefix, Verific::TypeRange *typeRange = nullptr); public: RTLIL::Module *module; Verific::Netlist *netlist; From 80bdbaa010d16a7602a1f36ff640cdb3c32081ed Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Fri, 29 May 2026 11:37:08 +0200 Subject: [PATCH 081/354] genrtlil: don't avoid emitting flops for nosync --- frontends/ast/genrtlil.cc | 12 ------------ tests/verilog/automatic_lifetime.ys | 5 +++++ 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 718d5aa23..f7c5bb7bd 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -406,18 +406,6 @@ struct AST_INTERNAL::ProcessGenerator if (GetSize(syncrule->signal) != 1) always->input_error("Found posedge/negedge event on a signal that is not 1 bit wide!\n"); addChunkActions(syncrule->actions, subst_lvalue_from, subst_lvalue_to, true); - // Automatic (nosync) variables must not become flip-flops: remove - // them from clocked sync rules so that proc_dff does not infer - // an unnecessary register for a purely combinational temporary. - syncrule->actions.erase( - std::remove_if(syncrule->actions.begin(), syncrule->actions.end(), - [](const RTLIL::SigSig &ss) { - for (auto &chunk : ss.first.chunks()) - if (chunk.wire && chunk.wire->get_bool_attribute(ID::nosync)) - return true; - return false; - }), - syncrule->actions.end()); proc->syncs.push_back(syncrule); } if (proc->syncs.empty()) { diff --git a/tests/verilog/automatic_lifetime.ys b/tests/verilog/automatic_lifetime.ys index 84e21e088..7df02e67f 100644 --- a/tests/verilog/automatic_lifetime.ys +++ b/tests/verilog/automatic_lifetime.ys @@ -15,6 +15,7 @@ module t1(input a, b, c, output reg y); endmodule EOF proc +opt_clean async2sync # no state elements for tmp select -assert-none t:$dff t:$dlatch %% @@ -39,6 +40,7 @@ module t2(input [3:0] a, b, input sel, output reg [3:0] y, output reg co); endmodule EOF proc +opt_clean async2sync select -assert-none t:$dff t:$dlatch %% sat -verify -prove-asserts -show-all @@ -59,6 +61,7 @@ module t3(input clk, rst, input [7:0] data, output reg [7:0] result); endmodule EOF proc +opt_clean # Exactly one DFF (for result), zero latches, no DFF for tmp select -assert-count 1 t:$dff %% select -assert-none t:$dlatch %% @@ -80,6 +83,7 @@ module t4(input [7:0] a, b, input sub, output reg [7:0] y); endmodule EOF proc +opt_clean async2sync select -assert-none t:$dff t:$dlatch %% sat -verify -prove-asserts -show-all @@ -100,5 +104,6 @@ module t5(input en, d, output reg q); endmodule EOF proc +opt_clean # No latch for tmp — X propagates instead of old value select -assert-none t:$dff t:$dlatch %% From a14650d07b8415db6eb98d11c19dfff1825aec03 Mon Sep 17 00:00:00 2001 From: Mike Inouye Date: Fri, 29 May 2026 17:53:31 +0000 Subject: [PATCH 082/354] verilog backend: runtime optimization for keyword pool Signed-off-by: Mike Inouye --- backends/verilog/verilog_backend.cc | 2 +- backends/verilog/verilog_backend.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 473918264..fd9986144 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -38,7 +38,7 @@ USING_YOSYS_NAMESPACE using namespace VERILOG_BACKEND; -const pool VERILOG_BACKEND::verilog_keywords() { +const pool &VERILOG_BACKEND::verilog_keywords() { static const pool res = { // IEEE 1800-2017 Annex B "accept_on", "alias", "always", "always_comb", "always_ff", "always_latch", "and", "assert", "assign", "assume", "automatic", "before", diff --git a/backends/verilog/verilog_backend.h b/backends/verilog/verilog_backend.h index 7e550a37c..affad995b 100644 --- a/backends/verilog/verilog_backend.h +++ b/backends/verilog/verilog_backend.h @@ -29,7 +29,7 @@ YOSYS_NAMESPACE_BEGIN namespace VERILOG_BACKEND { - const pool verilog_keywords(); + const pool &verilog_keywords(); bool char_is_verilog_escaped(char c); bool id_is_verilog_escaped(const std::string &str); From 0360a4bd0af91ba8b019dbf77d2dd9b8a0f7b095 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Sat, 30 May 2026 11:06:11 +1200 Subject: [PATCH 083/354] tests/check_mem: Drop unused init check It was also raising an error in `read_verilog`. --- tests/check_mem/sub_addr.sv | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/tests/check_mem/sub_addr.sv b/tests/check_mem/sub_addr.sv index cc4cb3ba3..025bdc881 100644 --- a/tests/check_mem/sub_addr.sv +++ b/tests/check_mem/sub_addr.sv @@ -6,7 +6,7 @@ input [7:0] wdata; output reg [7:0] rdata; input [3:0] wen; -reg [7:0] mem [0:3] = {8'h01, 8'h23, 8'h45, 8'h67}; +reg [7:0] mem [0:3]; integer i; always @(posedge clk) begin @@ -15,18 +15,4 @@ always @(posedge clk) begin rdata <= mem[addr]; end -always @(posedge clk) begin - // not sure how to verify this one without SBY - // or alternatively, how to replicate the problematic sub addressing without the read&write - assume (wen == 0); - assert (mem[0][7:4] == 4'h0); - assert (mem[0][3:0] == 4'h1); - assert (mem[1][7:4] == 4'h2); - assert (mem[1][3:0] == 4'h3); - assert (mem[2][7:4] == 4'h4); - assert (mem[2][3:0] == 4'h5); - assert (mem[3][7:4] == 4'h6); - assert (mem[3][3:0] == 4'h7); -end - endmodule From c89cfe1e6e28c46e6d20e6677b7e0e059a1922d3 Mon Sep 17 00:00:00 2001 From: Philippe Sauter Date: Sat, 30 May 2026 00:06:34 +0200 Subject: [PATCH 084/354] peepopt: add shiftpow2 pattern Rewrite power-of-two indexed word selects to $bmux when the shift amount already carries the scale as low zero bits. Keep the rule to non-overlapping selections and bound the generated mux ways. Add regressions for aligned shifts, padding, signed extension, and shiftmul handoff cases. --- passes/opt/Makefile.inc | 1 + passes/opt/peepopt.cc | 7 ++ passes/opt/peepopt_shiftpow2.pmg | 87 +++++++++++++++++ tests/various/peepopt.ys | 163 ++++++++++++++++++++++++++++++- 4 files changed, 253 insertions(+), 5 deletions(-) create mode 100644 passes/opt/peepopt_shiftpow2.pmg diff --git a/passes/opt/Makefile.inc b/passes/opt/Makefile.inc index e7b62fc6a..4a22c2301 100644 --- a/passes/opt/Makefile.inc +++ b/passes/opt/Makefile.inc @@ -32,6 +32,7 @@ $(eval $(call add_extra_objs,passes/opt/peepopt_pm.h)) PEEPOPT_PATTERN = passes/opt/peepopt_shiftmul_right.pmg PEEPOPT_PATTERN += passes/opt/peepopt_shiftmul_left.pmg PEEPOPT_PATTERN += passes/opt/peepopt_shiftadd.pmg +PEEPOPT_PATTERN += passes/opt/peepopt_shiftpow2.pmg PEEPOPT_PATTERN += passes/opt/peepopt_muldiv.pmg PEEPOPT_PATTERN += passes/opt/peepopt_muldiv_c.pmg PEEPOPT_PATTERN += passes/opt/peepopt_formal_clockgateff.pmg diff --git a/passes/opt/peepopt.cc b/passes/opt/peepopt.cc index fa7cf74a0..ac5b571f7 100644 --- a/passes/opt/peepopt.cc +++ b/passes/opt/peepopt.cc @@ -68,6 +68,12 @@ struct PeepoptPass : public Pass { log(" limits the amount of padding to a multiple of the data, \n"); log(" to avoid high resource usage from large temporary MUX trees.\n"); log("\n"); + log(" * shiftpow2 - Replace A>>(B<type.in($shift, $shiftx, $shr) + filter !port(shift, \B).empty() +endmatch + +code +{ + // make sure the shift amount cannot be negative + SigSpec amount = port(shift, \B); + bool b_signed = shift->type.in($shift, $shiftx) && param(shift, \B_SIGNED).as_bool(); + if (!b_signed) + amount.append(State::S0); + if (amount.bits().back() != State::S0) + reject; + + while (GetSize(amount) > 1 && amount.bits().back() == State::S0) + amount.remove(GetSize(amount) - 1); + + // low zero bits encode the power-of-two scale + int log2scale = 0; + while (!amount.empty() && amount[0] == State::S0) { + amount.remove(0); + log2scale++; + } + + if (log2scale < 1) + reject; + + if (amount.empty() || amount.is_fully_const()) + reject; + + SigSpec sel = amount; + int sel_width = GetSize(sel); + int width = param(shift, \Y_WIDTH).as_int(); + if (log2scale >= 8 * (int)sizeof(int) - 1) + reject; + int stride = 1 << log2scale; + + // avoid overlapping selections + if (width > stride) + reject; + + if (sel_width > 20) + reject; + long long ways = 1LL << sel_width; + + SigSpec A = port(shift, \A); + int a_width = GetSize(A); + bool a_signed = !shift->type.in($shiftx) && param(shift, \A_SIGNED).as_bool(); + int extended_a_width = a_signed ? std::max(a_width, width) : a_width; + + // limit padding for out-of-range select values + int max_ratio = module->design->scratchpad_get_int("peepopt.shiftpow2.max_data_multiple", 2); + if (ways * (long long)width > (long long)max_ratio * std::max(a_width, width)) + reject; + + did_something = true; + log("shiftpow2 pattern in %s: shift=%s, index=%s, stride=%d, width=%d, ways=%lld\n", + module, shift, log_signal(sel), stride, width, ways); + + // way m holds A[m*stride +: width], way 0 in the LSBs + State fill = shift->type.in($shiftx) ? State::Sx : State::S0; + SigSpec bmux_a; + for (long long m = 0; m < ways; m++) { + long long base = m * (long long)stride; + for (int b = 0; b < width; b++) { + long long idx = base + b; + if (idx < a_width) + bmux_a.append(A[idx]); + else if (idx < extended_a_width) + bmux_a.append(A.back()); + else + bmux_a.append(fill); + } + } + + module->addBmux(NEW_ID, bmux_a, sel, port(shift, \Y)); + autoremove(shift); + accept; +} +endcode diff --git a/tests/various/peepopt.ys b/tests/various/peepopt.ys index cbbd477e8..e0b9946cf 100644 --- a/tests/various/peepopt.ys +++ b/tests/various/peepopt.ys @@ -8,8 +8,8 @@ prep -nokeepdc equiv_opt -assert peepopt design -load postopt clean -select -assert-count 1 t:$shiftx -select -assert-count 0 t:$shiftx t:* %D +select -assert-count 1 t:$bmux +select -assert-count 0 t:$bmux t:* %D #################### @@ -72,9 +72,10 @@ design -import gate -as gate peepopt_shiftmul_3 miter -equiv -make_assert -make_outputs -ignore_gold_x -flatten gold gate miter sat -verify -show-public -enable_undef -prove-asserts miter cd gate -select -assert-count 1 t:$shr -select -assert-count 1 t:$mul -select -assert-count 0 t:$shr t:$mul %% t:* %D +clean +select -assert-count 1 t:$bmux +select -assert-count 0 t:$shr +select -assert-count 0 t:$mul #################### @@ -92,3 +93,155 @@ equiv_opt -assert peepopt design -load postopt clean select -assert-count 0 t:* + +#################### + +# shiftpow2: a power-of-two part-select i[s*W+:W] becomes a $bmux word mux +design -reset +read_verilog <> (S*8), checked by SAT miter +design -reset +read_verilog <> (S*8); +endmodule +EOT + +prep +design -save gold +peepopt +design -stash gate + +design -import gold -as gold peepopt_shiftpow2_1 +design -import gate -as gate peepopt_shiftpow2_1 + +miter -equiv -make_assert -make_outputs -ignore_gold_x -flatten gold gate miter +sat -verify -show-public -enable_undef -prove-asserts miter +cd gate +clean +select -assert-count 1 t:$bmux +select -assert-count 0 t:$shr + +#################### + +# shiftpow2: width smaller than stride is non-overlapping +design -reset +read_verilog <> (S*8); +endmodule +EOT + +prep +design -save gold +peepopt +design -stash gate + +design -import gold -as gold peepopt_shiftpow2_narrow +design -import gate -as gate peepopt_shiftpow2_narrow + +miter -equiv -make_assert -make_outputs -ignore_gold_x -flatten gold gate miter +sat -verify -show-public -enable_undef -prove-asserts miter +cd gate +clean +select -assert-count 1 t:$bmux +select -assert-count 0 t:$shr + +#################### + +# shiftpow2: signed part-select with out-of-range padding +design -reset +read_verilog <> (S*8); +endmodule +EOT + +prep +design -save gold +peepopt +design -stash gate + +design -import gold -as gold peepopt_shiftpow2_signed_shr +design -import gate -as gate peepopt_shiftpow2_signed_shr + +miter -equiv -make_assert -make_outputs -flatten gold gate miter +sat -verify -show-public -prove-asserts miter +cd gate +clean +select -assert-count 1 t:$bmux +select -assert-count 0 t:$shr + +#################### + +# shiftpow2 must NOT fire for overlapping selections +design -reset +read_verilog <> (S*4); +endmodule +EOT + +prep -nokeepdc +peepopt +clean +select -assert-count 0 t:$bmux +select -assert-count 1 t:$shr + +#################### + +# shiftpow2: shiftmul can expose a non-overlapping power-of-two stride +design -reset +read_verilog < Date: Mon, 1 Jun 2026 09:59:04 +0200 Subject: [PATCH 085/354] Fix wheels --- .github/workflows/wheels.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 8139b5af5..9450534be 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -66,6 +66,7 @@ jobs: run: | mkdir -p bison curl -L https://ftpmirror.gnu.org/gnu/bison/bison-3.8.2.tar.gz | tar --strip-components=1 -xzC bison + sed -i 's/-Werror=unused//g' Makefile ## Software installed by default in GitHub Action Runner VMs: ## https://github.com/actions/runner-images - if: ${{ matrix.os.family == 'macos' }} From 86f2ddebce7e98ce7cacc27e8a5c14cb53b51b51 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 1 Jun 2026 17:01:26 +0200 Subject: [PATCH 086/354] Release version 0.66 --- CHANGELOG | 12 +++++++++++- Makefile | 4 ++-- docs/source/conf.py | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 01faf44c2..5810cf08f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,8 +2,18 @@ List of major changes and improvements between releases ======================================================= -Yosys 0.65 .. Yosys 0.66-dev +Yosys 0.65 .. Yosys 0.66 -------------------------- + * Various + - C++ compiler with C++20 support is required. + - Please be aware that next release will also + migrate to CMake build system. + + * New commands and options + - Added "lattice_dsp_nexus" pass for Lattice Nexus + DSP inference. + - Added "-scopename" option to "synth_gatemate" pass + that is propagated to "flatten". Yosys 0.64 .. Yosys 0.65 -------------------------- diff --git a/Makefile b/Makefile index 6ee34070d..99a00fd40 100644 --- a/Makefile +++ b/Makefile @@ -161,7 +161,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.65 +YOSYS_VER := 0.66 ifneq (, $(shell command -v git 2>/dev/null)) ifneq (, $(shell git rev-parse --git-dir 2>/dev/null)) @@ -170,7 +170,7 @@ ifneq (, $(shell git rev-parse --git-dir 2>/dev/null)) YOSYS_VER := $(YOSYS_VER)+$(GIT_COMMIT_COUNT) endif else - YOSYS_VER := $(YOSYS_VER)+post +# YOSYS_VER := $(YOSYS_VER)+post endif endif diff --git a/docs/source/conf.py b/docs/source/conf.py index b85c391db..92975d3df 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -6,7 +6,7 @@ import os project = 'YosysHQ Yosys' author = 'YosysHQ GmbH' copyright ='2026 YosysHQ GmbH' -yosys_ver = "0.65" +yosys_ver = "0.66" # select HTML theme html_theme = 'furo-ys' From 8bb194af22d1ced67bd96c6597c4a2898b6d89a5 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 1 Jun 2026 18:23:28 +0200 Subject: [PATCH 087/354] Next dev cycle --- CHANGELOG | 3 +++ Makefile | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 5810cf08f..61b221bc9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ List of major changes and improvements between releases ======================================================= +Yosys 0.66 .. Yosys 0.67-dev +-------------------------- + Yosys 0.65 .. Yosys 0.66 -------------------------- * Various diff --git a/Makefile b/Makefile index 99a00fd40..8bb1c0b2a 100644 --- a/Makefile +++ b/Makefile @@ -170,7 +170,7 @@ ifneq (, $(shell git rev-parse --git-dir 2>/dev/null)) YOSYS_VER := $(YOSYS_VER)+$(GIT_COMMIT_COUNT) endif else -# YOSYS_VER := $(YOSYS_VER)+post + YOSYS_VER := $(YOSYS_VER)+post endif endif From bcc736ed7d44d0d1a9e0dc1d0a02cea75f432bb6 Mon Sep 17 00:00:00 2001 From: Catherine Date: Thu, 28 May 2026 13:44:43 +0000 Subject: [PATCH 088/354] Revert "Putting back some Makefile.conf" This reverts commit d8587f44f0566b5d442216ed12860f03cd7a49e2. --- tests/common.mk | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/common.mk b/tests/common.mk index 0e85e9fb9..ef6982514 100644 --- a/tests/common.mk +++ b/tests/common.mk @@ -1,16 +1,9 @@ ROOT_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) BUILD_DIR ?= $(ROOT_DIR)/.. -ifneq ($(wildcard $(ROOT_DIR)/../Makefile.conf),) -include $(ROOT_DIR)/../Makefile.conf -endif SBY ?= sby YOSYS ?= $(BUILD_DIR)/yosys -ifneq ($(ABCEXTERNAL),) -ABC ?= $(ABCEXTERNAL) -else ABC ?= $(BUILD_DIR)/yosys-abc -endif YOSYS_FILTERLIB ?= $(BUILD_DIR)/yosys-filterlib YOSYS_CONFIG ?= $(BUILD_DIR)/yosys-config YOSYS_SMTBMC ?= $(BUILD_DIR)/yosys-smtbmc From a727e7f6e73c610624c694fcf4b756af416140c5 Mon Sep 17 00:00:00 2001 From: Catherine Date: Tue, 12 May 2026 05:33:04 +0000 Subject: [PATCH 089/354] Migrate build system to CMake See #5895 for details. This commit does not include CI or documentation changes. --- .gitignore | 4 + CMakeLists.txt | 523 +++++++ Makefile | 1219 ----------------- backends/CMakeLists.txt | 18 + backends/aiger/CMakeLists.txt | 8 + backends/aiger/Makefile.inc | 4 - backends/aiger2/CMakeLists.txt | 5 + backends/aiger2/Makefile.inc | 1 - backends/blif/CMakeLists.txt | 3 + backends/blif/Makefile.inc | 3 - backends/btor/CMakeLists.txt | 7 + backends/btor/Makefile.inc | 3 - backends/cxxrtl/CMakeLists.txt | 19 + backends/cxxrtl/Makefile.inc | 11 - backends/edif/CMakeLists.txt | 3 + backends/edif/Makefile.inc | 3 - backends/firrtl/CMakeLists.txt | 8 + backends/firrtl/Makefile.inc | 3 - backends/functional/CMakeLists.txt | 12 + backends/functional/Makefile.inc | 4 - backends/intersynth/CMakeLists.txt | 3 + backends/intersynth/Makefile.inc | 3 - backends/jny/CMakeLists.txt | 5 + backends/jny/Makefile.inc | 2 - backends/json/CMakeLists.txt | 5 + backends/json/Makefile.inc | 3 - backends/rtlil/CMakeLists.txt | 11 + backends/rtlil/Makefile.inc | 3 - backends/simplec/CMakeLists.txt | 3 + backends/simplec/Makefile.inc | 3 - backends/smt2/CMakeLists.txt | 20 + backends/smt2/Makefile.inc | 46 - backends/smt2/smtbmc.py | 4 +- backends/smt2/witness.py | 4 +- backends/smv/CMakeLists.txt | 7 + backends/smv/Makefile.inc | 3 - backends/spice/CMakeLists.txt | 3 + backends/spice/Makefile.inc | 3 - backends/table/CMakeLists.txt | 3 + backends/table/Makefile.inc | 3 - backends/verilog/CMakeLists.txt | 8 + backends/verilog/Makefile.inc | 3 - cmake/CheckLibcFeatures.cmake | 40 + cmake/Condition.cmake | 35 + cmake/FindDlfcn.cmake | 24 + cmake/FindPyosysEnv.cmake | 42 + cmake/FindPython3Embed.cmake | 16 + cmake/PkgConfig.cmake | 43 + cmake/PmgenCommand.cmake | 60 + cmake/YosysAbc.cmake | 96 ++ cmake/YosysAbcSubmodule.cmake | 64 + cmake/YosysComponent.cmake | 321 +++++ cmake/YosysConfigScript.cmake | 66 + cmake/YosysInstallDirs.cmake | 9 + cmake/YosysLinkTarget.cmake | 101 ++ cmake/YosysVerific.cmake | 48 + cmake/YosysVersion.cmake | 162 +++ cmake/YosysVersionData.cmake | 2 + cmake/toolchain/toolchain-mingw-i686.cmake | 8 + cmake/toolchain/toolchain-mingw-x86_64.cmake | 8 + docs/Makefile | 27 + docs/source/code_examples/extensions/Makefile | 5 +- docs/source/code_examples/stubnets/Makefile | 12 +- examples/cxx-api/demomain.cc | 4 +- flake.lock | 14 +- flake.nix | 94 +- frontends/CMakeLists.txt | 10 + frontends/aiger/CMakeLists.txt | 6 + frontends/aiger/Makefile.inc | 3 - frontends/aiger2/CMakeLists.txt | 3 + frontends/aiger2/Makefile.inc | 2 - frontends/ast/CMakeLists.txt | 13 + frontends/ast/Makefile.inc | 7 - frontends/ast/dpicall.cc | 6 +- frontends/blif/CMakeLists.txt | 8 + frontends/blif/Makefile.inc | 3 - frontends/json/CMakeLists.txt | 3 + frontends/json/Makefile.inc | 3 - frontends/liberty/CMakeLists.txt | 5 + frontends/liberty/Makefile.inc | 3 - frontends/rpc/CMakeLists.txt | 8 + frontends/rpc/Makefile.inc | 3 - frontends/rtlil/CMakeLists.txt | 3 + frontends/rtlil/Makefile.inc | 1 - frontends/verific/CMakeLists.txt | 70 + frontends/verific/Makefile.inc | 23 - frontends/verilog/CMakeLists.txt | 43 + frontends/verilog/Makefile.inc | 29 - kernel/CMakeLists.txt | 187 +++ {techlibs/common => kernel}/cellhelp.py | 0 kernel/fstdata.cc | 14 +- kernel/log.cc | 4 +- kernel/register.cc | 8 +- kernel/threading.h | 8 +- kernel/version.cc.in | 4 + kernel/yosys.cc | 12 +- kernel/yosys_common.h | 4 + kernel/yosys_config.h.in | 22 + libs/CMakeLists.txt | 9 + libs/bigint/CMakeLists.txt | 14 + libs/dlfcn-win32/CMakeLists.txt | 9 + libs/ezsat/CMakeLists.txt | 16 + libs/ezsat/ezcmdline.cc | 2 +- libs/flex/FlexLexer.h | 220 +++ libs/flex/README.txt | 2 + libs/fst/CMakeLists.txt | 18 + libs/json11/CMakeLists.txt | 8 + libs/minisat/CMakeLists.txt | 24 + libs/sha1/CMakeLists.txt | 8 + libs/subcircuit/CMakeLists.txt | 4 + misc/cmake/check_missing_depends.sh | 9 + misc/cmake/script_pass_depends.py | 29 + nix/cross/tcl.nix | 66 + nix/cross/win-overlay.nix | 51 + nix/cross/win32.nix | 15 + nix/cross/win64.nix | 15 + nix/pkgs/yosys.nix | 53 + passes/CMakeLists.txt | 11 + passes/cmds/CMakeLists.txt | 213 +++ passes/cmds/Makefile.inc | 64 - passes/cmds/sdc/CMakeLists.txt | 9 + passes/cmds/sdc/Makefile.inc | 3 - passes/cmds/sdc/sdc.cc | 1 + passes/cmds/show.cc | 8 +- passes/cmds/viz.cc | 6 +- passes/equiv/CMakeLists.txt | 54 + passes/equiv/Makefile.inc | 12 - passes/fsm/CMakeLists.txt | 52 + passes/fsm/Makefile.inc | 11 - passes/hierarchy/CMakeLists.txt | 22 + passes/hierarchy/Makefile.inc | 7 - passes/memory/CMakeLists.txt | 59 + passes/memory/Makefile.inc | 15 - passes/opt/.gitignore | 1 - passes/opt/CMakeLists.txt | 97 ++ passes/opt/Makefile.inc | 44 - passes/opt/opt_clean/CMakeLists.txt | 11 + passes/opt/opt_clean/Makefile.inc | 10 - passes/pmgen/.gitignore | 1 - passes/pmgen/CMakeLists.txt | 15 + passes/pmgen/Makefile.inc | 10 - passes/proc/CMakeLists.txt | 47 + passes/proc/Makefile.inc | 12 - passes/sat/CMakeLists.txt | 74 + passes/sat/Makefile.inc | 23 - passes/techmap/CMakeLists.txt | 225 +++ passes/techmap/Makefile.inc | 68 - passes/techmap/abc.cc | 2 +- passes/tests/CMakeLists.txt | 13 + passes/tests/Makefile.inc | 6 - pyosys/.gitignore | 2 - pyosys/CMakeLists.txt | 29 + pyosys/generator.py | 41 +- pyosys/{__init__.py => modinit.py} | 0 pyosys/wrappers_tpl.cc | 4 - techlibs/.gitignore | 2 - techlibs/CMakeLists.txt | 20 + techlibs/achronix/CMakeLists.txt | 28 + techlibs/achronix/Makefile.inc | 6 - techlibs/analogdevices/CMakeLists.txt | 65 + techlibs/analogdevices/Makefile.inc | 21 - techlibs/anlogic/CMakeLists.txt | 45 + techlibs/anlogic/Makefile.inc | 13 - techlibs/common/.gitignore | 2 - techlibs/common/CMakeLists.txt | 87 ++ techlibs/common/Makefile.inc | 41 - techlibs/common/opensta.cc | 2 +- techlibs/coolrunner2/CMakeLists.txt | 42 + techlibs/coolrunner2/Makefile.inc | 10 - techlibs/easic/CMakeLists.txt | 19 + techlibs/easic/Makefile.inc | 3 - techlibs/efinix/CMakeLists.txt | 40 + techlibs/efinix/Makefile.inc | 10 - techlibs/fabulous/CMakeLists.txt | 41 + techlibs/fabulous/Makefile.inc | 11 - techlibs/gatemate/.gitignore | 2 - techlibs/gatemate/CMakeLists.txt | 65 + techlibs/gatemate/Makefile.inc | 34 - techlibs/gatemate/make_lut_tree_lib.py | 4 +- techlibs/gowin/CMakeLists.txt | 55 + techlibs/gowin/Makefile.inc | 16 - techlibs/greenpak4/CMakeLists.txt | 42 + techlibs/greenpak4/Makefile.inc | 12 - techlibs/ice40/CMakeLists.txt | 84 ++ techlibs/ice40/Makefile.inc | 26 - techlibs/intel/CMakeLists.txt | 52 + techlibs/intel/Makefile.inc | 14 - techlibs/intel_alm/CMakeLists.txt | 57 + techlibs/intel_alm/Makefile.inc | 26 - techlibs/lattice/CMakeLists.txt | 101 ++ techlibs/lattice/Makefile.inc | 60 - techlibs/microchip/CMakeLists.txt | 76 + techlibs/microchip/Makefile.inc | 40 - techlibs/nanoxplore/CMakeLists.txt | 68 + techlibs/nanoxplore/Makefile.inc | 31 - techlibs/quicklogic/.gitignore | 1 - techlibs/quicklogic/CMakeLists.txt | 104 ++ techlibs/quicklogic/Makefile.inc | 44 - techlibs/sf2/CMakeLists.txt | 34 + techlibs/sf2/Makefile.inc | 7 - techlibs/xilinx/CMakeLists.txt | 125 ++ techlibs/xilinx/Makefile.inc | 64 - tests/unit/CMakeLists.txt | 29 + tests/unit/kernel/CMakeLists.txt | 14 + tests/unit/opt/CMakeLists.txt | 5 + tests/unit/techmap/CMakeLists.txt | 5 + 206 files changed, 5184 insertions(+), 2303 deletions(-) create mode 100644 CMakeLists.txt delete mode 100644 Makefile create mode 100644 backends/CMakeLists.txt create mode 100644 backends/aiger/CMakeLists.txt delete mode 100644 backends/aiger/Makefile.inc create mode 100644 backends/aiger2/CMakeLists.txt delete mode 100644 backends/aiger2/Makefile.inc create mode 100644 backends/blif/CMakeLists.txt delete mode 100644 backends/blif/Makefile.inc create mode 100644 backends/btor/CMakeLists.txt delete mode 100644 backends/btor/Makefile.inc create mode 100644 backends/cxxrtl/CMakeLists.txt delete mode 100644 backends/cxxrtl/Makefile.inc create mode 100644 backends/edif/CMakeLists.txt delete mode 100644 backends/edif/Makefile.inc create mode 100644 backends/firrtl/CMakeLists.txt delete mode 100644 backends/firrtl/Makefile.inc create mode 100644 backends/functional/CMakeLists.txt delete mode 100644 backends/functional/Makefile.inc create mode 100644 backends/intersynth/CMakeLists.txt delete mode 100644 backends/intersynth/Makefile.inc create mode 100644 backends/jny/CMakeLists.txt delete mode 100644 backends/jny/Makefile.inc create mode 100644 backends/json/CMakeLists.txt delete mode 100644 backends/json/Makefile.inc create mode 100644 backends/rtlil/CMakeLists.txt delete mode 100644 backends/rtlil/Makefile.inc create mode 100644 backends/simplec/CMakeLists.txt delete mode 100644 backends/simplec/Makefile.inc create mode 100644 backends/smt2/CMakeLists.txt delete mode 100644 backends/smt2/Makefile.inc mode change 100644 => 100755 backends/smt2/smtbmc.py mode change 100644 => 100755 backends/smt2/witness.py create mode 100644 backends/smv/CMakeLists.txt delete mode 100644 backends/smv/Makefile.inc create mode 100644 backends/spice/CMakeLists.txt delete mode 100644 backends/spice/Makefile.inc create mode 100644 backends/table/CMakeLists.txt delete mode 100644 backends/table/Makefile.inc create mode 100644 backends/verilog/CMakeLists.txt delete mode 100644 backends/verilog/Makefile.inc create mode 100644 cmake/CheckLibcFeatures.cmake create mode 100644 cmake/Condition.cmake create mode 100644 cmake/FindDlfcn.cmake create mode 100644 cmake/FindPyosysEnv.cmake create mode 100644 cmake/FindPython3Embed.cmake create mode 100644 cmake/PkgConfig.cmake create mode 100644 cmake/PmgenCommand.cmake create mode 100644 cmake/YosysAbc.cmake create mode 100644 cmake/YosysAbcSubmodule.cmake create mode 100644 cmake/YosysComponent.cmake create mode 100644 cmake/YosysConfigScript.cmake create mode 100644 cmake/YosysInstallDirs.cmake create mode 100644 cmake/YosysLinkTarget.cmake create mode 100644 cmake/YosysVerific.cmake create mode 100644 cmake/YosysVersion.cmake create mode 100644 cmake/YosysVersionData.cmake create mode 100644 cmake/toolchain/toolchain-mingw-i686.cmake create mode 100644 cmake/toolchain/toolchain-mingw-x86_64.cmake create mode 100644 frontends/CMakeLists.txt create mode 100644 frontends/aiger/CMakeLists.txt delete mode 100644 frontends/aiger/Makefile.inc create mode 100644 frontends/aiger2/CMakeLists.txt delete mode 100644 frontends/aiger2/Makefile.inc create mode 100644 frontends/ast/CMakeLists.txt delete mode 100644 frontends/ast/Makefile.inc create mode 100644 frontends/blif/CMakeLists.txt delete mode 100644 frontends/blif/Makefile.inc create mode 100644 frontends/json/CMakeLists.txt delete mode 100644 frontends/json/Makefile.inc create mode 100644 frontends/liberty/CMakeLists.txt delete mode 100644 frontends/liberty/Makefile.inc create mode 100644 frontends/rpc/CMakeLists.txt delete mode 100644 frontends/rpc/Makefile.inc create mode 100644 frontends/rtlil/CMakeLists.txt delete mode 100644 frontends/rtlil/Makefile.inc create mode 100644 frontends/verific/CMakeLists.txt delete mode 100644 frontends/verific/Makefile.inc create mode 100644 frontends/verilog/CMakeLists.txt delete mode 100644 frontends/verilog/Makefile.inc create mode 100644 kernel/CMakeLists.txt rename {techlibs/common => kernel}/cellhelp.py (100%) create mode 100644 kernel/version.cc.in create mode 100644 kernel/yosys_config.h.in create mode 100644 libs/CMakeLists.txt create mode 100644 libs/bigint/CMakeLists.txt create mode 100644 libs/dlfcn-win32/CMakeLists.txt create mode 100644 libs/ezsat/CMakeLists.txt create mode 100644 libs/flex/FlexLexer.h create mode 100644 libs/flex/README.txt create mode 100644 libs/fst/CMakeLists.txt create mode 100644 libs/json11/CMakeLists.txt create mode 100644 libs/minisat/CMakeLists.txt create mode 100644 libs/sha1/CMakeLists.txt create mode 100644 libs/subcircuit/CMakeLists.txt create mode 100644 misc/cmake/check_missing_depends.sh create mode 100644 misc/cmake/script_pass_depends.py create mode 100644 nix/cross/tcl.nix create mode 100644 nix/cross/win-overlay.nix create mode 100644 nix/cross/win32.nix create mode 100644 nix/cross/win64.nix create mode 100644 nix/pkgs/yosys.nix create mode 100644 passes/CMakeLists.txt create mode 100644 passes/cmds/CMakeLists.txt delete mode 100644 passes/cmds/Makefile.inc create mode 100644 passes/cmds/sdc/CMakeLists.txt delete mode 100644 passes/cmds/sdc/Makefile.inc create mode 100644 passes/equiv/CMakeLists.txt delete mode 100644 passes/equiv/Makefile.inc create mode 100644 passes/fsm/CMakeLists.txt delete mode 100644 passes/fsm/Makefile.inc create mode 100644 passes/hierarchy/CMakeLists.txt delete mode 100644 passes/hierarchy/Makefile.inc create mode 100644 passes/memory/CMakeLists.txt delete mode 100644 passes/memory/Makefile.inc delete mode 100644 passes/opt/.gitignore create mode 100644 passes/opt/CMakeLists.txt delete mode 100644 passes/opt/Makefile.inc create mode 100644 passes/opt/opt_clean/CMakeLists.txt delete mode 100644 passes/opt/opt_clean/Makefile.inc delete mode 100644 passes/pmgen/.gitignore create mode 100644 passes/pmgen/CMakeLists.txt delete mode 100644 passes/pmgen/Makefile.inc create mode 100644 passes/proc/CMakeLists.txt delete mode 100644 passes/proc/Makefile.inc create mode 100644 passes/sat/CMakeLists.txt delete mode 100644 passes/sat/Makefile.inc create mode 100644 passes/techmap/CMakeLists.txt delete mode 100644 passes/techmap/Makefile.inc create mode 100644 passes/tests/CMakeLists.txt delete mode 100644 passes/tests/Makefile.inc delete mode 100644 pyosys/.gitignore create mode 100644 pyosys/CMakeLists.txt rename pyosys/{__init__.py => modinit.py} (100%) delete mode 100644 techlibs/.gitignore create mode 100644 techlibs/CMakeLists.txt create mode 100644 techlibs/achronix/CMakeLists.txt delete mode 100644 techlibs/achronix/Makefile.inc create mode 100644 techlibs/analogdevices/CMakeLists.txt delete mode 100644 techlibs/analogdevices/Makefile.inc create mode 100644 techlibs/anlogic/CMakeLists.txt delete mode 100644 techlibs/anlogic/Makefile.inc delete mode 100644 techlibs/common/.gitignore create mode 100644 techlibs/common/CMakeLists.txt delete mode 100644 techlibs/common/Makefile.inc create mode 100644 techlibs/coolrunner2/CMakeLists.txt delete mode 100644 techlibs/coolrunner2/Makefile.inc create mode 100644 techlibs/easic/CMakeLists.txt delete mode 100644 techlibs/easic/Makefile.inc create mode 100644 techlibs/efinix/CMakeLists.txt delete mode 100644 techlibs/efinix/Makefile.inc create mode 100644 techlibs/fabulous/CMakeLists.txt delete mode 100644 techlibs/fabulous/Makefile.inc create mode 100644 techlibs/gatemate/CMakeLists.txt delete mode 100644 techlibs/gatemate/Makefile.inc create mode 100644 techlibs/gowin/CMakeLists.txt delete mode 100644 techlibs/gowin/Makefile.inc create mode 100644 techlibs/greenpak4/CMakeLists.txt delete mode 100644 techlibs/greenpak4/Makefile.inc create mode 100644 techlibs/ice40/CMakeLists.txt delete mode 100644 techlibs/ice40/Makefile.inc create mode 100644 techlibs/intel/CMakeLists.txt delete mode 100644 techlibs/intel/Makefile.inc create mode 100644 techlibs/intel_alm/CMakeLists.txt delete mode 100644 techlibs/intel_alm/Makefile.inc create mode 100644 techlibs/lattice/CMakeLists.txt delete mode 100644 techlibs/lattice/Makefile.inc create mode 100644 techlibs/microchip/CMakeLists.txt delete mode 100644 techlibs/microchip/Makefile.inc create mode 100644 techlibs/nanoxplore/CMakeLists.txt delete mode 100644 techlibs/nanoxplore/Makefile.inc delete mode 100644 techlibs/quicklogic/.gitignore create mode 100644 techlibs/quicklogic/CMakeLists.txt delete mode 100644 techlibs/quicklogic/Makefile.inc create mode 100644 techlibs/sf2/CMakeLists.txt delete mode 100644 techlibs/sf2/Makefile.inc create mode 100644 techlibs/xilinx/CMakeLists.txt delete mode 100644 techlibs/xilinx/Makefile.inc create mode 100644 tests/unit/CMakeLists.txt create mode 100644 tests/unit/kernel/CMakeLists.txt create mode 100644 tests/unit/opt/CMakeLists.txt create mode 100644 tests/unit/techmap/CMakeLists.txt diff --git a/.gitignore b/.gitignore index b39088088..84d11a7cb 100644 --- a/.gitignore +++ b/.gitignore @@ -49,7 +49,9 @@ /tests/unit/objtest/ /tests/ystests /build +/build-* /result +/result-* /dist # pyosys @@ -86,3 +88,5 @@ __pycache__ /qtcreator.creator /qtcreator.creator.user /compile_commands.json +/.direnv +/.envrc diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..51c40ec41 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,523 @@ +if (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR) + set(rm "rm -rf") + if (WIN32) + set(rm "del /s /q") + endif() + message(FATAL_ERROR + "In-tree builds are not supported. Instead, run:\n" + "${rm} CMakeCache.txt CMakeFiles ; cmake -B build " + ) +endif() + +cmake_minimum_required(VERSION 3.27) +project(yosys LANGUAGES C CXX) + +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) +include(CMakeDependentOption) +include(FeatureSummary) +include(CheckPIESupported) + +include(Condition) +include(CheckLibcFeatures) +include(PkgConfig) +include(PmgenCommand) +include(YosysVersion) +include(YosysInstallDirs) +include(YosysConfigScript) +include(YosysComponent) +include(YosysLinkTarget) +include(YosysAbc) +include(YosysAbcSubmodule) +include(YosysVerific) + +# Build options. +set(YOSYS_COMPILER_LAUNCHER "" CACHE STRING "Compiler launcher (ccache, sccache)") +option(YOSYS_ENABLE_COVERAGE "Enable code coverage" OFF) +option(YOSYS_ENABLE_PROFILING "Enable instruction profiling" OFF) + +set(YOSYS_PROGRAM_PREFIX "" CACHE STRING "Name prefix for programs, libraries, and data") +set(YOSYS_COMPONENTS "everything" CACHE STRING "List of components to build (use pass names)") +option(BUILD_SHARED_LIBS "Build libyosys as a shared library" ON) + +option(YOSYS_DISABLE_THREADS "Disable threading" OFF) +set(YOSYS_ABC_EXECUTABLE "" CACHE FILEPATH + "Path to the ABC executable (empty for vendored, 'INTEGRATED-NOTFOUND' for in-process)") +option(YOSYS_WITHOUT_ABC "Disable ABC support (not recommended)" OFF) +option(YOSYS_WITHOUT_ZLIB "Disable zlib integration" OFF) +option(YOSYS_WITHOUT_LIBFFI "Disable libffi integration" OFF) +option(YOSYS_WITHOUT_READLINE "Disable readline integration" OFF) +option(YOSYS_WITHOUT_EDITLINE "Disable editline integration" OFF) +option(YOSYS_WITHOUT_TCL "Disable Tcl integration" OFF) +option(YOSYS_WITH_PYTHON "Enable Python integration" OFF) + +set(YOSYS_VERIFIC_DIR "" CACHE FILEPATH "Path to the Verific source code (empty to disable)") +set(YOSYS_VERIFIC_COMPONENTS "" CACHE STRING + "List of Verific components to link (empty for autodetect)") +set(YOSYS_VERIFIC_FEATURES "" CACHE STRING + "List of Yosys Verific frontend features to enable (empty for autodetect)") + +option(YOSYS_INSTALL_DRIVER "Install Yosys executable" ON) +option(YOSYS_INSTALL_LIBRARY "Install libyosys library" OFF) +cmake_dependent_option(YOSYS_INSTALL_PYTHON "Install Python extension module" OFF + YOSYS_WITH_PYTHON OFF) +set(YOSYS_INSTALL_PYTHON_SITEDIR "" CACHE STRING "Path to Python package installation directory") + +# Configure compiler. +set(CMAKE_EXPORT_COMPILE_COMMANDS YES) + +if (YOSYS_COMPILER_LAUNCHER) + set(CMAKE_C_COMPILER_LAUNCHER "${YOSYS_COMPILER_LAUNCHER}") + set(CMAKE_CXX_COMPILER_LAUNCHER "${YOSYS_COMPILER_LAUNCHER}") +endif() + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED YES) + +set(CMAKE_POSITION_INDEPENDENT_CODE ON) +check_pie_supported() # opportunistically enable PIE + +if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + set(CMAKE_CXX_FLAGS_DEBUG "-Og -ggdb") + set(CMAKE_CXX_FLAGS_RELEASE "-O3") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -ggdb") + set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os") + set(CMAKE_CXX_FLAGS_SANITIZE "-O1 -fno-omit-frame-pointer -fno-optimize-sibling-calls") + if ("${SANITIZE}" MATCHES "memory") + set(CMAKE_CXX_FLAGS_SANITIZE "${CMAKE_CXX_FLAGS_SANITIZE} -fsanitize-memory-track-origins") + endif() + set(no_abc_options + "$<$>>,$>:-fsanitize=${SANITIZE}>" + "$<$>>:-Wall;-Wextra;-Werror=unused>" + ) + add_compile_options("${no_abc_options}") + add_link_options("${no_abc_options}") +elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + set(CMAKE_CXX_FLAGS_DEBUG "/Od /DEBUG") + set(CMAKE_CXX_FLAGS_RELEASE "/O2") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/O2 /DEBUG") + set(CMAKE_CXX_FLAGS_MINSIZEREL "/Os") + add_compile_options(/Zc:__cplusplus) + add_definitions( + _CRT_NONSTDC_NO_DEPRECATE + _CRT_SECURE_NO_WARNINGS + ) +else() + # We have to do this because CMake adds `-DNDEBUG` in release builds by default, and there's + # no particularly good way to prevent this without also erasing optimization flags. + # If you see this message, reproduce the block above with the flags supported by your compiler. + message(FATAL_ERROR "${CMAKE_CXX_COMPILER_ID} compiler is not supported") +endif() + +if (YOSYS_ENABLE_COVERAGE) + if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") + elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-instr-generate -fcoverage-mapping") + else() + message(FATAL_ERROR "Code coverage is not supported on ${CMAKE_CXX_COMPILER_ID} compiler") + endif() +endif() + +if (YOSYS_ENABLE_PROFILING) + if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg") + else() + message(FATAL_ERROR "Instruction profiling is not supported on ${CMAKE_CXX_COMPILER_ID} compiler") + endif() +endif() + +if (NOT CMAKE_C_COMPILER_ID STREQUAL CMAKE_CXX_COMPILER_ID) + message(FATAL_ERROR "C and C++ compilers must be provided by the same vendor") +endif() +set(CMAKE_C_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") +set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") +set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") +set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}") +set(CMAKE_C_FLAGS_SANITIZE "${CMAKE_CXX_FLAGS_SANITIZE}") + +if (CMAKE_SYSTEM_NAME STREQUAL "WASI") + add_compile_options( + -fwasm-exceptions -mllvm -wasm-use-legacy-eh=false + -D_WASI_EMULATED_PROCESS_CLOCKS + ) + add_link_options( + -fwasm-exceptions -mllvm -wasm-use-legacy-eh=false -lunwind + -lwasi-emulated-process-clocks + -Wl,--stack-first,-z,stack-size=8388608 + ) +endif() + +if (MINGW AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "16.0.0") + # GCC 15.2 sometimes refuses to construct an import directory for yosys.exe/libyosys.dll with: + # .../ld.exe: error: export ordinal too large: 67035 + # The cause is unknown. + message(WARNING "MinGW GCC is supported starting with version 16.0.0") +endif() + +# Required dependencies. +find_package(FLEX) +set_package_properties(FLEX PROPERTIES + URL "https://github.com/westes/flex" + DESCRIPTION "The Fast Lexical Analyzer" + PURPOSE "Compiling the Verilog lexer" + TYPE REQUIRED +) + +find_package(BISON) +set_package_properties(BISON PROPERTIES + URL "https://www.gnu.org/software/bison/" + DESCRIPTION "The Yacc-compatible Parser Generator" + PURPOSE "Compiling the Verilog parser" + TYPE REQUIRED +) + +find_package(Python3 3.7 COMPONENTS Interpreter) +set_package_properties(Python3 PROPERTIES + URL "https://www.python.org/" + DESCRIPTION "Dynamic programming language (Interpreter)" + PURPOSE "Generating data files\n Running external SMT2 solvers" + TYPE REQUIRED +) + +# Optional dependencies. +check_glob() +check_system() +check_popen() +find_package(Threads QUIET) +check_pthread_create() +find_package(Dlfcn QUIET) + +find_package(PkgConfig) +set_package_properties(PkgConfig PROPERTIES + URL "https://www.freedesktop.org/wiki/Software/pkg-config/" + DESCRIPTION "Library metadata manager" + PURPOSE "Discovering dependencies" + TYPE RECOMMENDED +) + +pkg_config_import(zlib) +set_package_properties(zlib PROPERTIES + URL "https://github.com/madler/zlib" + DESCRIPTION "A massively spiffy yet delicately unobtrusive compression library" + PURPOSE "Handling Gzip and FST file formats" +) + +pkg_config_import(libffi) +set_package_properties(libffi PROPERTIES + URL "https://sourceware.org/libffi/" + DESCRIPTION "A Portable Foreign Function Interface Library" + PURPOSE "Implementing Verilog DPI-C" +) + +pkg_config_import(editline MODULES libedit) +set_package_properties(editline PROPERTIES + URL "https://www.thrysoee.dk/editline/" + DESCRIPTION "Line editing and history library (BSD)" + PURPOSE "Enhancing the command prompt" + TYPE RECOMMENDED +) + +pkg_config_import(readline) +set_package_properties(readline PROPERTIES + URL "https://tiswww.case.edu/php/chet/readline/rltop.html" + DESCRIPTION "Line editing and history library (GPL)" + PURPOSE "Enhancing the command prompt" + TYPE RECOMMENDED +) + +# See https://core.tcl-lang.org/tips/doc/trunk/tip/538.md +pkg_config_import(tcl MODULES tcl) +set_package_properties(tcl PROPERTIES + URL "https://www.tcl-lang.org/" + DESCRIPTION "Dynamic programming language" + PURPOSE "Parsing SDC constraint files\n Binding Yosys API" +) + +if (tcl_FOUND) + get_target_property(tcl_options PkgConfig::tcl INTERFACE_COMPILE_OPTIONS) + if (tcl_options MATCHES "TCL_WITH_EXTERNAL_TOMMATH") + pkg_config_import(libtommath) + set_package_properties(libtommath PROPERTIES + URL "https://www.libtom.net/LibTomMath/" + DESCRIPTION "Multiple-precision integer library" + PURPOSE "Required by this build of Tcl" + TYPE REQUIRED + ) + # Unfortunately the pkg-config file for Tcl includes libtommath as a private dependency, + # while it should be public since it is exposed in the public API and necessary for its use. + target_link_libraries(PkgConfig::tcl INTERFACE PkgConfig::libtommath) + else() + # Vendored within Tcl itself. + set(libtommath_FOUND TRUE) + endif() +endif() + +if (YOSYS_WITH_PYTHON) + find_package(Python3Embed REQUIRED) + set_property(GLOBAL PROPERTY _CMAKE_Python3Embed_REQUIRED_VERSION "== ${Python3_VERSION}") + set_package_properties(Python3Embed PROPERTIES + URL "https://www.python.org/" + DESCRIPTION "Dynamic programming language (Embedding)" + PURPOSE "Binding Yosys API" + ) + + find_package(PyosysEnv REQUIRED) + set_package_properties(PyosysEnv PROPERTIES + DESCRIPTION "Pyosys wrapper generator environment" + PURPOSE "Either 'uv' or 'pybind11>3,<4 cxxheaderparser'" + ) +endif() + +find_package(GTest) +set_package_properties(GTest PROPERTIES + URL "https://google.github.io/googletest/" + DESCRIPTION "C++ testing and mocking framework by Google" + PURPOSE "Running unit tests" + TYPE RECOMMENDED +) + +# Configure features based on dependency availability. +message(VERBOSE "Conditional features:") +condition(YOSYS_ENABLE_GLOB HAVE_GLOB) +condition(YOSYS_ENABLE_SPAWN HAVE_SYSTEM AND HAVE_POPEN) +condition(YOSYS_ENABLE_THREADS Threads_FOUND AND HAVE_PTHREAD_CREATE AND NOT YOSYS_DISABLE_THREADS) +condition(YOSYS_ENABLE_PLUGINS Dlfcn_FOUND) +condition(YOSYS_ENABLE_ABC NOT YOSYS_WITHOUT_ABC) +condition(YOSYS_ENABLE_ZLIB zlib_FOUND AND NOT YOSYS_WITHOUT_ZLIB) +condition(YOSYS_ENABLE_LIBFFI Dlfcn_FOUND AND libffi_FOUND AND NOT YOSYS_WITHOUT_LIBFFI) +condition(YOSYS_ENABLE_READLINE readline_FOUND AND NOT YOSYS_WITHOUT_READLINE) +condition(YOSYS_ENABLE_EDITLINE editline_FOUND AND NOT YOSYS_WITHOUT_EDITLINE AND NOT YOSYS_ENABLE_READLINE) +condition(YOSYS_ENABLE_TCL tcl_FOUND AND libtommath_FOUND AND NOT YOSYS_WITHOUT_TCL) +condition(YOSYS_ENABLE_PYTHON Python3Embed_FOUND AND PyosysEnv_FOUND AND YOSYS_WITH_PYTHON) +condition(YOSYS_ENABLE_VERIFIC YOSYS_VERIFIC_DIR AND zlib_FOUND) +condition(YOSYS_ENABLE_HELP_SOURCE NOT CMAKE_BUILD_TYPE MATCHES "^(Release|RelWithDebInfo)$") + +# Describe dependencies and features +# CMake 4.0 would let us use proper conditions, but that's too new for now. +add_feature_info(have_glob YOSYS_ENABLE_GLOB "Glob expansion in filenames") +add_feature_info(have_spawn YOSYS_ENABLE_SPAWN "Passes that invoke external tools") +add_feature_info(have_threads YOSYS_ENABLE_THREADS "Multithreaded netlist operations") +add_feature_info(have_plugins YOSYS_ENABLE_PLUGINS "Dynamically loadable binary plugins") +add_feature_info(with_abc YOSYS_ENABLE_ABC "Production-quality logic synthesis flow") +add_feature_info(with_zlib YOSYS_ENABLE_ZLIB "Transparent Gzip decompression and FST file format support") +add_feature_info(with_libffi YOSYS_ENABLE_LIBFFI "Verilog DPI-C foreign function interface") +add_feature_info(with_readline YOSYS_ENABLE_READLINE "Using readline for prompt editing and history") +add_feature_info(with_editline YOSYS_ENABLE_EDITLINE "Using editline for prompt editing and history") +add_feature_info(with_tcl YOSYS_ENABLE_TCL "Tcl scripting and SDC parsing") +add_feature_info(with_python YOSYS_ENABLE_PYTHON "Python scripting and embedding") +add_feature_info(with_verific YOSYS_ENABLE_VERIFIC "Verific frontend integration") +message(STATUS "") +feature_summary(WHAT PACKAGES_FOUND + DEFAULT_DESCRIPTION) +feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND + DEFAULT_DESCRIPTION QUIET_ON_EMPTY FATAL_ON_MISSING_REQUIRED_PACKAGES +) +feature_summary(WHAT PACKAGES_NOT_FOUND + DEFAULT_DESCRIPTION QUIET_ON_EMPTY +) +feature_summary(WHAT ENABLED_FEATURES + DEFAULT_DESCRIPTION QUIET_ON_EMPTY) +feature_summary(WHAT DISABLED_FEATURES + DEFAULT_DESCRIPTION QUIET_ON_EMPTY) + +# Describe project version. +yosys_extract_version() + +# Describe ABC integration. +if (YOSYS_ENABLE_ABC AND NOT YOSYS_ENABLE_SPAWN AND NOT YOSYS_ABC_EXECUTABLE STREQUAL "INTEGRATED-NOTFOUND") + message(WARNING "ABC support on this platform forces -DYOSYS_ABC_EXECUTABLE=INTEGRATED-NOTFOUND") + set(YOSYS_ABC_EXECUTABLE "INTEGRATED-NOTFOUND" CACHE FILEPATH "" FORCE) +endif() + +set(YOSYS_LINK_ABC 0) +if (YOSYS_ENABLE_ABC) + if (NOT YOSYS_ABC_EXECUTABLE AND NOT YOSYS_SKIP_ABC_SUBMODULE_CHECK) + yosys_check_abc_submodule() + endif() + if (YOSYS_ABC_EXECUTABLE STREQUAL "INTEGRATED-NOTFOUND") + set(YOSYS_LINK_ABC 1) + message(STATUS "Building ABC: (integrated)") + elseif (YOSYS_ABC_EXECUTABLE STREQUAL "") + set(abc_filename ${YOSYS_PROGRAM_PREFIX}yosys-abc${CMAKE_EXECUTABLE_SUFFIX}) + message(STATUS "Building ABC: ${YOSYS_INSTALL_FULL_BINDIR}/${abc_filename}") + else() + message(STATUS "External ABC: ${YOSYS_ABC_EXECUTABLE}") + endif() +endif() + +# Ensure invalid dependencies fail at configuration time, not link time. +set(CMAKE_LINK_LIBRARIES_ONLY_TARGETS ON) + +# Pseudo-library that injects common compilation options into every Yosys component. +add_library(yosys_common INTERFACE) +target_compile_definitions(yosys_common INTERFACE + _YOSYS_ + $<$:DEBUG> +) +target_include_directories(yosys_common INTERFACE + ${CMAKE_SOURCE_DIR} + ${CMAKE_BINARY_DIR} +) +if (SANITIZE) + target_compile_options(yosys_common INTERFACE + ${sanitize_options} + ) +endif() + +# Two pseudo-components used for dependency tracking only. +yosys_core(essentials BOOTSTRAP) +yosys_core(everything BOOTSTRAP) + +# All of the source code. +add_subdirectory(libs) +add_subdirectory(kernel) +add_subdirectory(passes) +add_subdirectory(frontends) +add_subdirectory(backends) +add_subdirectory(techlibs) +if (YOSYS_ENABLE_PYTHON) + add_subdirectory(pyosys) +endif() + +# ABC submodule. +if (YOSYS_ENABLE_ABC AND NOT YOSYS_ABC_EXECUTABLE) + set(YOSYS_ABC_INSTALL NO) + if (YOSYS_ABC_EXECUTABLE STREQUAL "" AND (YOSYS_INSTALL_DRIVER OR YOSYS_INSTALL_LIBRARY)) + set(YOSYS_ABC_INSTALL YES) + endif() + yosys_abc_target(libyosys-abc yosys-abc + INSTALL_IF ${YOSYS_ABC_INSTALL} + ) +endif() + +# Compute a transitive closure of enabled components. +yosys_expand_components(library_components essentials ${YOSYS_COMPONENTS}) +yosys_expand_components(driver_components driver ${YOSYS_COMPONENTS}) + +# Main Yosys executable (compiler driver). +yosys_cxx_executable(yosys + OUTPUT_NAME yosys + INSTALL_IF ${YOSYS_INSTALL_DRIVER} +) +yosys_link_components(yosys PRIVATE ${driver_components}) +set_property(TARGET yosys PROPERTY ENABLE_EXPORTS ON) +if (MINGW) + target_link_options(yosys PRIVATE LINKER:--export-all-symbols) + set_target_properties(yosys PROPERTIES + # Final name: `yosys.exe.a` (linked to explicitly) + IMPORT_PREFIX "" + IMPORT_SUFFIX ".exe.a" + ) + if (YOSYS_INSTALL_DRIVER) + install(FILES ${CMAKE_BINARY_DIR}/yosys.exe.a DESTINATION ${YOSYS_INSTALL_LIBDIR}) + endif() +endif() + +target_compile_options(yosys PRIVATE -fsanitize=undefined) + +# Yosys components as a library. +if (BUILD_SHARED_LIBS) + set(libyosys_type SHARED) +else() + set(libyosys_type STATIC) +endif() +yosys_cxx_library(libyosys ${libyosys_type} + OUTPUT_NAME libyosys + INSTALL_IF ${YOSYS_INSTALL_LIBRARY} +) +yosys_link_components(libyosys PRIVATE ${library_components}) +add_library(Yosys::libyosys ALIAS libyosys) +if (MINGW) + set_target_properties(libyosys PROPERTIES + # Final name: `libyosys.dll.a` (linked to via `-lyosys`) + IMPORT_PREFIX "" + ) +endif() + +# Yosys data files (mainly headers and technological libraries). +if (YOSYS_INSTALL_DRIVER OR YOSYS_INSTALL_LIBRARY) + yosys_install_component_data(${library_components} DESTINATION ${YOSYS_INSTALL_DATADIR}) +endif() + +# Python binary extension (for using Yosys as a Python library). +if (YOSYS_ENABLE_PYTHON) + yosys_cxx_library(pyosys MODULE + OUTPUT_NAME pyosys + ) + yosys_link_components(pyosys PRIVATE ${library_components}) + set_target_properties(pyosys PROPERTIES EXCLUDE_FROM_ALL FALSE) # build but not install + if (YOSYS_ENABLE_ABC AND YOSYS_ABC_EXECUTABLE STREQUAL "") + add_dependencies(pyosys yosys-abc) + endif() + + if (YOSYS_INSTALL_PYTHON) + string(REPLACE "-" "_" PYOSYS_MODULE_PREFIX "${YOSYS_PROGRAM_PREFIX}") + if (YOSYS_INSTALL_PYTHON_SITEDIR STREQUAL "") + set(YOSYS_INSTALL_PYTHON_SITEDIR ${Python3_SITEARCH}) + endif() + set(pyosys_install_dir ${YOSYS_INSTALL_PYTHON_SITEDIR}/${PYOSYS_MODULE_PREFIX}pyosys) + install(FILES pyosys/modinit.py + RENAME __init__.py + DESTINATION ${pyosys_install_dir} + ) + install(FILES $ + RENAME libyosys${CMAKE_SHARED_MODULE_SUFFIX} + DESTINATION ${pyosys_install_dir} + ) + if (YOSYS_ENABLE_ABC AND YOSYS_ABC_EXECUTABLE STREQUAL "") + # If ABC is vendored it needs to be installed as a part of pyosys. + install(TARGETS yosys-abc + DESTINATION ${pyosys_install_dir} + ) + endif() + yosys_install_component_data(${library_components} DESTINATION ${pyosys_install_dir}/share) + endif() +endif() + +# Plugin build tool. +yosys_config_script(BUILD) +if (YOSYS_INSTALL_DRIVER OR YOSYS_INSTALL_LIBRARY) + yosys_config_script(INSTALL) +endif() + +# Tests. +add_subdirectory(tests/unit) +# TODO(cmake): other tests + +# Docs. +add_custom_target(docs-prepare + COMMAND make -C ${CMAKE_SOURCE_DIR}/docs gen + BUILD_DIR=${CMAKE_BINARY_DIR} + PROGRAM_PREFIX=${YOSYS_PROGRAM_PREFIX} + YOSYS=$ +) +foreach (format html latexpdf) + add_custom_target(docs-${format} + COMMAND make -C ${CMAKE_SOURCE_DIR}/docs ${format} + DEPENDS docs-prepare + ) +endforeach() + +# Utilities. +add_custom_target(print-version + COMMAND ${CMAKE_COMMAND} -E echo ${YOSYS_VERSION} + VERBATIM +) + +yosys_expand_components(all_components everything QUIET) +list(TRANSFORM all_components PREPEND "COMMAND;${CMAKE_COMMAND};-E;echo;" OUTPUT_VARIABLE echo_all_components) +add_custom_target(print-yosys-components + ${echo_all_components} + VERBATIM +) + +math(EXPR YOSYS_VERSION_MINOR_next "${YOSYS_VERSION_MINOR} + 1") +add_custom_target(increment-minor-version + COMMAND ${CMAKE_COMMAND} -E echo + "set(YOSYS_VERSION_MAJOR ${YOSYS_VERSION_MAJOR})" + > ${CMAKE_SOURCE_DIR}/cmake/YosysVersionData.cmake + COMMAND ${CMAKE_COMMAND} -E echo + "set(YOSYS_VERSION_MINOR ${YOSYS_VERSION_MINOR_next})" + >> ${CMAKE_SOURCE_DIR}/cmake/YosysVersionData.cmake + VERBATIM +) diff --git a/Makefile b/Makefile deleted file mode 100644 index 8bb1c0b2a..000000000 --- a/Makefile +++ /dev/null @@ -1,1219 +0,0 @@ - -CONFIG := none -# CONFIG := clang -# CONFIG := gcc -# CONFIG := wasi -# CONFIG := msys2-32 -# CONFIG := msys2-64 - -# features (the more the better) -ENABLE_TCL := 1 -ENABLE_ABC := 1 -ENABLE_GLOB := 1 -ENABLE_PLUGINS := 1 -ENABLE_READLINE := 1 -ENABLE_EDITLINE := 0 -ENABLE_GHDL := 0 -ENABLE_VERIFIC := 0 -ENABLE_VERIFIC_SYSTEMVERILOG := 1 -ENABLE_VERIFIC_VHDL := 1 -ENABLE_VERIFIC_HIER_TREE := 1 -ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS := 0 -ENABLE_VERIFIC_EDIF := 0 -ENABLE_VERIFIC_LIBERTY := 0 -ENABLE_LIBYOSYS := 0 -ENABLE_LIBYOSYS_STATIC := 0 -ENABLE_ZLIB := 1 -ENABLE_HELP_SOURCE := 0 - -# python wrappers -ENABLE_PYOSYS := 0 -PYOSYS_USE_UV := 1 - -# other configuration flags -ENABLE_GCOV := 0 -ENABLE_GPROF := 0 -ENABLE_DEBUG := 0 -ENABLE_LTO := 0 -ENABLE_CCACHE := 0 -# sccache is not always a drop-in replacement for ccache in practice -ENABLE_SCCACHE := 0 -ENABLE_FUNCTIONAL_TESTS := 0 -LINK_CURSES := 0 -LINK_TERMCAP := 0 -LINK_ABC := 0 -# Needed for environments that can't run executables (i.e. emscripten, wasm) -DISABLE_SPAWN := 0 -# Needed for environments that don't have proper thread support (i.e. emscripten, wasm--for now) -ENABLE_THREADS := 1 -ifeq ($(ENABLE_THREADS),1) -DISABLE_ABC_THREADS := 0 -else -DISABLE_ABC_THREADS := 1 -endif - -# clang sanitizers -SANITIZER = -# SANITIZER = address -# SANITIZER = memory -# SANITIZER = undefined -# SANITIZER = cfi - -# Prefer using ENABLE_DEBUG over setting these -OPT_LEVEL := -O3 -GCC_LTO := -CLANG_LTO := -flto=thin - -PROGRAM_PREFIX := - -OS := $(shell uname -s) -PREFIX ?= /usr/local -INSTALL_SUDO := -ifneq ($(filter MINGW%,$(OS)),) -OS := MINGW -endif - -ifneq ($(wildcard Makefile.conf),) -include Makefile.conf -endif - -ifeq ($(ENABLE_PYOSYS),1) -ENABLE_LIBYOSYS := 1 -endif - -BINDIR := $(PREFIX)/bin -LIBDIR := $(PREFIX)/lib/$(PROGRAM_PREFIX)yosys -DATDIR := $(PREFIX)/share/$(PROGRAM_PREFIX)yosys - -EXE = -OBJS = -GENFILES = -EXTRA_OBJS = -EXTRA_TARGETS = -TARGETS = $(PROGRAM_PREFIX)yosys$(EXE) $(PROGRAM_PREFIX)yosys-config - -PRETTY = 1 -SMALL = 0 - -all: top-all - -YOSYS_SRC := $(dir $(firstword $(MAKEFILE_LIST))) -VPATH := $(YOSYS_SRC) - -# Unit test -UNITESTPATH := $(YOSYS_SRC)/tests/unit - -export CXXSTD ?= c++20 -CXXFLAGS := $(CXXFLAGS) -Wall -Wextra -Werror=unused -ggdb -I. -I"$(YOSYS_SRC)" -MD -MP -D_YOSYS_ -fPIC -I$(PREFIX)/include -LIBS := $(LIBS) -lstdc++ -lm -PLUGIN_LINKFLAGS := -PLUGIN_LIBS := -EXE_LINKFLAGS := -EXE_LIBS := -ifeq ($(OS), MINGW) -EXE_LINKFLAGS := -Wl,--export-all-symbols -Wl,--out-implib,libyosys_exe.a -PLUGIN_LINKFLAGS += -L"$(LIBDIR)" -PLUGIN_LIBS := -lyosys_exe -endif - -ifeq ($(ENABLE_HELP_SOURCE),1) -CXXFLAGS += -DYOSYS_ENABLE_HELP_SOURCE -endif - -PKG_CONFIG ?= pkg-config -SED ?= sed -BISON ?= bison -STRIP ?= strip -AWK ?= awk - -ifeq ($(OS), Darwin) -PLUGIN_LINKFLAGS += -undefined dynamic_lookup -LINKFLAGS += -rdynamic - -# homebrew search paths -ifneq ($(shell :; command -v brew),) -BREW_PREFIX := $(shell brew --prefix)/opt -$(info $$BREW_PREFIX is [${BREW_PREFIX}]) -CXXFLAGS += -I$(BREW_PREFIX)/readline/include -I$(BREW_PREFIX)/flex/include -LINKFLAGS += -L$(BREW_PREFIX)/readline/lib -L$(BREW_PREFIX)/flex/lib -PKG_CONFIG_PATH := $(BREW_PREFIX)/libffi/lib/pkgconfig:$(PKG_CONFIG_PATH) -PKG_CONFIG_PATH := $(BREW_PREFIX)/tcl-tk/lib/pkgconfig:$(PKG_CONFIG_PATH) -export PATH := $(BREW_PREFIX)/bison/bin:$(BREW_PREFIX)/gettext/bin:$(BREW_PREFIX)/flex/bin:$(PATH) - -# macports search paths -else ifneq ($(shell :; command -v port),) -PORT_PREFIX := $(patsubst %/bin/port,%,$(shell :; command -v port)) -CXXFLAGS += -I$(PORT_PREFIX)/include -LINKFLAGS += -L$(PORT_PREFIX)/lib -PKG_CONFIG_PATH := $(PORT_PREFIX)/lib/pkgconfig:$(PKG_CONFIG_PATH) -export PATH := $(PORT_PREFIX)/bin:$(PATH) -endif - -else -LINKFLAGS += -rdynamic -ifneq ($(OS), OpenBSD) -LIBS += -lrt -endif -endif - -ifeq ($(OS), Haiku) -# Allow usage of non-posix vasprintf, mkstemps functions -CXXFLAGS += -D_DEFAULT_SOURCE -endif - -YOSYS_VER := 0.66 - -ifneq (, $(shell command -v git 2>/dev/null)) -ifneq (, $(shell git rev-parse --git-dir 2>/dev/null)) - GIT_COMMIT_COUNT := $(or $(shell git rev-list --count v$(YOSYS_VER)..HEAD 2>/dev/null),0) - ifneq ($(GIT_COMMIT_COUNT),0) - YOSYS_VER := $(YOSYS_VER)+$(GIT_COMMIT_COUNT) - endif -else - YOSYS_VER := $(YOSYS_VER)+post -endif -endif - -YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1) -YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1) -YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2) -CXXFLAGS += -DYOSYS_VER=\\"$(YOSYS_VER)\\" \ - -DYOSYS_MAJOR=$(YOSYS_MAJOR) \ - -DYOSYS_MINOR=$(YOSYS_MINOR) \ - -DYOSYS_COMMIT=$(YOSYS_COMMIT) - -# Note: We arrange for .gitcommit to contain the (short) commit hash in -# tarballs generated with git-archive(1) using .gitattributes. The git repo -# will have this file in its unexpanded form tough, in which case we fall -# back to calling git directly. -TARBALL_GIT_REV := $(shell cat $(YOSYS_SRC)/.gitcommit) -ifneq ($(findstring Format:,$(TARBALL_GIT_REV)),) -GIT_REV := $(shell GIT_DIR=$(YOSYS_SRC)/.git git rev-parse --short=9 HEAD || echo UNKNOWN) -GIT_DIRTY := $(shell GIT_DIR=$(YOSYS_SRC)/.git git diff --exit-code --quiet 2>/dev/null; if [ $$? -ne 0 ]; then echo "-dirty"; fi) -else -GIT_REV := $(TARBALL_GIT_REV) -GIT_DIRTY := "" -endif - -OBJS = kernel/version_$(GIT_REV).o - -ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABC_USE_NAMESPACE=abc VERBOSE=$(Q) - -# set ABCEXTERNAL = to use an external ABC instance -# Note: The in-tree ABC (yosys-abc) will not be installed when ABCEXTERNAL is set. -ABCEXTERNAL ?= - -define newline - - -endef - -ifneq ($(wildcard Makefile.conf),) -# don't echo Makefile.conf contents when invoked to print source versions -ifeq ($(findstring echo-,$(MAKECMDGOALS)),) -$(info $(subst $$--$$,$(newline),$(shell sed 's,^,[Makefile.conf] ,; s,$$,$$--$$,;' < Makefile.conf | tr -d '\n' | sed 's,\$$--\$$$$,,'))) -endif -include Makefile.conf -endif - -PYTHON_EXECUTABLE ?= $(shell if python3 -c ""; then echo "python3"; else echo "python"; fi) -ifeq ($(ENABLE_PYOSYS),1) -PYTHON_VERSION_TESTCODE := "import sys;t='{v[0]}.{v[1]}'.format(v=list(sys.version_info[:2]));print(t)" -PYTHON_VERSION := $(shell $(PYTHON_EXECUTABLE) -c ""$(PYTHON_VERSION_TESTCODE)"") -PYTHON_MAJOR_VERSION := $(shell echo $(PYTHON_VERSION) | cut -f1 -d.) - -PYTHON_CONFIG := $(PYTHON_EXECUTABLE)-config -PYTHON_CONFIG_FOR_EXE := $(PYTHON_CONFIG) -PYTHON_CONFIG_EMBED_AVAILABLE ?= $(shell $(PYTHON_EXECUTABLE)-config --embed --libs > /dev/null && echo 1) -ifeq ($(PYTHON_CONFIG_EMBED_AVAILABLE),1) -PYTHON_CONFIG_FOR_EXE := $(PYTHON_CONFIG) --embed -endif - -PYTHON_DESTDIR := $(shell $(PYTHON_EXECUTABLE) -c "import site; print(site.getsitepackages()[-1]);") - -# Reload Makefile.conf to override python specific variables if defined -ifneq ($(wildcard Makefile.conf),) -include Makefile.conf -endif - -endif - -ABC_ARCHFLAGS = "" -ifeq ($(OS), OpenBSD) -ABC_ARCHFLAGS += "-DABC_NO_RLIMIT" -endif - -# This gets overridden later. -LTOFLAGS := $(GCC_LTO) - -ifeq ($(CONFIG),clang) -CXX = clang++ -CXXFLAGS += -std=$(CXXSTD) $(OPT_LEVEL) -ifeq ($(ENABLE_LTO),1) -LINKFLAGS += -fuse-ld=lld -endif -ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H $(ABC_ARCHFLAGS)" -LTOFLAGS := $(CLANG_LTO) - -ifneq ($(SANITIZER),) -$(info [Clang Sanitizer] $(SANITIZER)) -CXXFLAGS += -g -O1 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize=$(SANITIZER) -LINKFLAGS += -g -fsanitize=$(SANITIZER) -ifneq ($(findstring memory,$(SANITIZER)),) -CXXFLAGS += -fPIE -fsanitize-memory-track-origins -LINKFLAGS += -fPIE -fsanitize-memory-track-origins -endif -ifneq ($(findstring cfi,$(SANITIZER)),) -CXXFLAGS += -flto -LINKFLAGS += -flto -LTOFLAGS = -endif -endif - -else ifeq ($(CONFIG),gcc) -CXX = g++ -CXXFLAGS += -std=$(CXXSTD) $(OPT_LEVEL) -ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H $(ABC_ARCHFLAGS)" - -else ifeq ($(CONFIG),gcc-static) -LINKFLAGS := $(filter-out -rdynamic,$(LINKFLAGS)) -static -LIBS := $(filter-out -lrt,$(LIBS)) -CXXFLAGS := $(filter-out -fPIC,$(CXXFLAGS)) -CXXFLAGS += -std=$(CXXSTD) $(OPT_LEVEL) -ABCMKARGS = CC="$(CC)" CXX="$(CXX)" LD="$(CXX)" ABC_USE_LIBSTDCXX=1 LIBS="-lm -lpthread -static" OPTFLAGS="-O" \ - ARCHFLAGS="-DABC_USE_STDINT_H -DABC_NO_DYNAMIC_LINKING=1 -Wno-unused-but-set-variable $(ARCHFLAGS)" ABC_USE_NO_READLINE=1 -ifeq ($(DISABLE_ABC_THREADS),1) -ABCMKARGS += "ABC_USE_NO_PTHREADS=1" -endif - -else ifeq ($(CONFIG),wasi) -ifeq ($(WASI_SDK),) -CXX = clang++ -AR = llvm-ar -RANLIB = llvm-ranlib -WASIFLAGS := -target wasm32-wasip1 $(WASIFLAGS) -else -CXX = $(WASI_SDK)/bin/clang++ -AR = $(WASI_SDK)/bin/ar -RANLIB = $(WASI_SDK)/bin/ranlib -endif -CXXFLAGS := $(WASIFLAGS) -std=$(CXXSTD) $(OPT_LEVEL) -D_WASI_EMULATED_PROCESS_CLOCKS -fwasm-exceptions -mllvm -wasm-use-legacy-eh=false $(filter-out -fPIC,$(CXXFLAGS)) -LINKFLAGS := $(WASIFLAGS) -Wl,-z,stack-size=1048576 $(filter-out -rdynamic,$(LINKFLAGS)) -fwasm-exceptions -lunwind -LIBS := -lwasi-emulated-process-clocks $(filter-out -lrt,$(LIBS)) -ABCMKARGS += AR="$(AR)" RANLIB="$(RANLIB)" -ABCMKARGS += ARCHFLAGS="$(WASIFLAGS) -D_WASI_EMULATED_PROCESS_CLOCKS -DABC_USE_STDINT_H -DABC_NO_DYNAMIC_LINKING -DABC_NO_RLIMIT" -ABCMKARGS += OPTFLAGS="-Os" -LTOFLAGS = -EXE = .wasm - -DISABLE_SPAWN := 1 - -ifeq ($(ENABLE_ABC),1) -LINK_ABC := 1 -ENABLE_THREADS := 0 -DISABLE_ABC_THREADS := 1 -endif - -else ifeq ($(CONFIG),msys2-32) -CXX = i686-w64-mingw32-g++ -CXXFLAGS += -std=$(CXXSTD) $(OPT_LEVEL) -D_POSIX_SOURCE -DYOSYS_WIN32_UNIX_DIR -CXXFLAGS := $(filter-out -fPIC,$(CXXFLAGS)) -LINKFLAGS := $(filter-out -rdynamic,$(LINKFLAGS)) -s -LIBS := $(filter-out -lrt,$(LIBS)) -ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DWIN32_NO_DLL -DWIN32 -DHAVE_STRUCT_TIMESPEC -fpermissive -w" -ABCMKARGS += LIBS="-lpthread -lshlwapi -s" ABC_USE_NO_READLINE=0 CC="i686-w64-mingw32-gcc" CXX="$(CXX)" -EXE = .exe - -else ifeq ($(CONFIG),msys2-64) -CXX = x86_64-w64-mingw32-g++ -CXXFLAGS += -std=$(CXXSTD) $(OPT_LEVEL) -D_POSIX_SOURCE -DYOSYS_WIN32_UNIX_DIR -CXXFLAGS := $(filter-out -fPIC,$(CXXFLAGS)) -LINKFLAGS := $(filter-out -rdynamic,$(LINKFLAGS)) -s -LIBS := $(filter-out -lrt,$(LIBS)) -ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DWIN32_NO_DLL -DWIN32 -DHAVE_STRUCT_TIMESPEC -fpermissive -w" -ABCMKARGS += LIBS="-lpthread -lshlwapi -s" ABC_USE_NO_READLINE=0 CC="x86_64-w64-mingw32-gcc" CXX="$(CXX)" -EXE = .exe - -else ifeq ($(CONFIG),none) -CXXFLAGS += -std=$(CXXSTD) $(OPT_LEVEL) -ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H $(ABC_ARCHFLAGS)" -LTOFLAGS = - -else -$(error Invalid CONFIG setting '$(CONFIG)'. Valid values: clang, gcc, msys2-32, msys2-64, none) -endif - - -ifeq ($(ENABLE_LTO),1) -CXXFLAGS += $(LTOFLAGS) -LINKFLAGS += $(LTOFLAGS) -endif - -ifeq ($(ENABLE_LIBYOSYS),1) -TARGETS += libyosys.so -ifeq ($(ENABLE_LIBYOSYS_STATIC),1) -TARGETS += libyosys.a -endif -endif - -PY_WRAPPER_FILE = pyosys/wrappers - -# running make clean on just those and then recompiling saves a lot of -# time when running cibuildwheel -PYTHON_OBJECTS = pyosys/wrappers.o kernel/drivers.o kernel/yosys.o passes/cmds/plugin.o - -ifeq ($(ENABLE_PYOSYS),1) -# python-config --ldflags includes -l and -L, but LINKFLAGS is only -L - -UV_ENV := -ifeq ($(PYOSYS_USE_UV),1) -UV_ENV := uv run --no-project --with 'pybind11>3,<4' --with 'cxxheaderparser' -endif - -LINKFLAGS += $(filter-out -l%,$(shell $(PYTHON_CONFIG) --ldflags)) -LIBS += $(shell $(PYTHON_CONFIG) --libs) -EXE_LIBS += $(filter-out $(LIBS),$(shell $(PYTHON_CONFIG_FOR_EXE) --libs)) -PYBIND11_INCLUDE ?= $(shell $(UV_ENV) $(PYTHON_EXECUTABLE) -m pybind11 --includes) -CXXFLAGS += -I$(PYBIND11_INCLUDE) -DYOSYS_ENABLE_PYTHON -CXXFLAGS += $(shell $(PYTHON_CONFIG) --includes) -DYOSYS_ENABLE_PYTHON - -OBJS += $(PY_WRAPPER_FILE).o -PY_GEN_SCRIPT = $(YOSYS_SRC)/pyosys/generator.py -PY_WRAP_INCLUDES := $(shell $(UV_ENV) $(PYTHON_EXECUTABLE) $(PY_GEN_SCRIPT) --print-includes) -endif # ENABLE_PYOSYS - -ifeq ($(ENABLE_READLINE),1) -CXXFLAGS += -DYOSYS_ENABLE_READLINE -ifeq ($(OS), $(filter $(OS),FreeBSD OpenBSD NetBSD)) -CXXFLAGS += -I/usr/local/include -endif -LIBS += -lreadline -ifeq ($(LINK_CURSES),1) -LIBS += -lcurses -ABCMKARGS += "ABC_READLINE_LIBRARIES=-lcurses -lreadline" -endif -ifeq ($(LINK_TERMCAP),1) -LIBS += -ltermcap -ABCMKARGS += "ABC_READLINE_LIBRARIES=-lreadline -ltermcap" -endif -else -ifeq ($(ENABLE_EDITLINE),1) -CXXFLAGS += -DYOSYS_ENABLE_EDITLINE -LIBS += -ledit -endif -ABCMKARGS += "ABC_USE_NO_READLINE=1" -endif - -ifeq ($(DISABLE_ABC_THREADS),1) -ABCMKARGS += "ABC_USE_NO_PTHREADS=1" -endif - -ifeq ($(LINK_ABC),1) -ABCMKARGS += "ABC_USE_PIC=1" -endif - -ifeq ($(DISABLE_SPAWN),1) -CXXFLAGS += -DYOSYS_DISABLE_SPAWN -endif - -ifeq ($(ENABLE_PLUGINS),1) -CXXFLAGS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --silence-errors --cflags libffi) -DYOSYS_ENABLE_PLUGINS -ifeq ($(OS), MINGW) -CXXFLAGS += -Ilibs/dlfcn-win32 -endif -LIBS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --silence-errors --libs libffi || echo -lffi) -ifneq ($(OS), $(filter $(OS),FreeBSD OpenBSD NetBSD MINGW)) -LIBS += -ldl -endif -endif - -ifeq ($(ENABLE_GLOB),1) -CXXFLAGS += -DYOSYS_ENABLE_GLOB -endif - -ifeq ($(ENABLE_ZLIB),1) -CXXFLAGS += -DYOSYS_ENABLE_ZLIB -LIBS += -lz -endif - - -ifeq ($(ENABLE_TCL),1) -TCL_VERSION ?= tcl$(shell bash -c "tclsh <(echo 'puts [info tclversion]')") -ifeq ($(OS), $(filter $(OS),FreeBSD OpenBSD NetBSD)) -# BSDs usually use tcl8.6, but the lib is named "libtcl86" -TCL_INCLUDE ?= /usr/local/include/$(TCL_VERSION) -TCL_LIBS ?= -l$(subst .,,$(TCL_VERSION)) -else -TCL_INCLUDE ?= /usr/include/$(TCL_VERSION) -TCL_LIBS ?= -l$(TCL_VERSION) -endif - -CXXFLAGS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --silence-errors --cflags tcl || echo -I$(TCL_INCLUDE)) -DYOSYS_ENABLE_TCL -LIBS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --silence-errors --libs tcl || echo $(TCL_LIBS)) -ifneq (,$(findstring TCL_WITH_EXTERNAL_TOMMATH,$(CXXFLAGS))) -LIBS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --silence-errors --libs libtommath || echo) -endif -endif - -ifeq ($(ENABLE_GCOV),1) -LLVM_PROFILE_FILE ?= $(realpath $(YOSYS_SRC))/coverage/coverage_%p.profraw -export LLVM_PROFILE_FILE -export LLVM_PROFILE_FILE_BUFFER_SIZE=0 -CXXFLAGS += -fprofile-instr-generate -fcoverage-mapping -LINKFLAGS+= -fprofile-instr-generate -endif - -ifeq ($(ENABLE_GPROF),1) -CXXFLAGS += -pg -LINKFLAGS += -pg -endif - -ifeq ($(ENABLE_DEBUG),1) -CXXFLAGS := -Og -DDEBUG $(filter-out $(OPT_LEVEL),$(CXXFLAGS)) -STRIP := -endif - -ifeq ($(ENABLE_THREADS),1) -CXXFLAGS += -DYOSYS_ENABLE_THREADS -LIBS += -lpthread -endif - -ifeq ($(ENABLE_ABC),1) -CXXFLAGS += -DYOSYS_ENABLE_ABC -ifeq ($(LINK_ABC),1) -CXXFLAGS += -DYOSYS_LINK_ABC -ifeq ($(DISABLE_ABC_THREADS),0) -LIBS += -lpthread -endif -else -ifeq ($(ABCEXTERNAL),) -TARGETS := $(PROGRAM_PREFIX)yosys-abc$(EXE) $(TARGETS) -endif -ifeq ($(DISABLE_SPAWN),1) -$(error ENABLE_ABC=1 requires either LINK_ABC=1 or DISABLE_SPAWN=0) -endif -endif -endif - -ifeq ($(ENABLE_GHDL),1) -GHDL_PREFIX ?= $(PREFIX) -GHDL_INCLUDE_DIR ?= $(GHDL_PREFIX)/include -GHDL_LIB_DIR ?= $(GHDL_PREFIX)/lib -CXXFLAGS += -I$(GHDL_INCLUDE_DIR) -DYOSYS_ENABLE_GHDL -LIBS += $(GHDL_LIB_DIR)/libghdl.a $(file <$(GHDL_LIB_DIR)/libghdl.link) -endif - -LIBS_VERIFIC = -ifeq ($(ENABLE_VERIFIC),1) -VERIFIC_DIR ?= /usr/local/src/verific_lib -VERIFIC_COMPONENTS ?= database util containers -ifeq ($(ENABLE_VERIFIC_HIER_TREE),1) -VERIFIC_COMPONENTS += hier_tree -CXXFLAGS += -DVERIFIC_HIER_TREE_SUPPORT -else -ifneq ($(wildcard $(VERIFIC_DIR)/hier_tree),) -VERIFIC_COMPONENTS += hier_tree -endif -endif -ifeq ($(ENABLE_VERIFIC_SYSTEMVERILOG),1) -VERIFIC_COMPONENTS += verilog -CXXFLAGS += -DVERIFIC_SYSTEMVERILOG_SUPPORT -else -ifneq ($(wildcard $(VERIFIC_DIR)/verilog),) -VERIFIC_COMPONENTS += verilog -endif -endif -ifeq ($(ENABLE_VERIFIC_VHDL),1) -VERIFIC_COMPONENTS += vhdl -CXXFLAGS += -DVERIFIC_VHDL_SUPPORT -else -ifneq ($(wildcard $(VERIFIC_DIR)/vhdl),) -VERIFIC_COMPONENTS += vhdl -endif -endif -ifeq ($(ENABLE_VERIFIC_EDIF),1) -VERIFIC_COMPONENTS += edif -CXXFLAGS += -DVERIFIC_EDIF_SUPPORT -endif -ifeq ($(ENABLE_VERIFIC_LIBERTY),1) -VERIFIC_COMPONENTS += synlib -CXXFLAGS += -DVERIFIC_LIBERTY_SUPPORT -endif -ifeq ($(ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS),1) -VERIFIC_COMPONENTS += extensions -CXXFLAGS += -DYOSYSHQ_VERIFIC_EXTENSIONS -else -# YosysHQ flavor of Verific always needs extensions linked -# if disabled it will just not be invoked but parts -# are required for it to initialize properly -ifneq ($(wildcard $(VERIFIC_DIR)/extensions),) -VERIFIC_COMPONENTS += extensions -OBJS += kernel/log_compat.o -endif -endif -CXXFLAGS += $(patsubst %,-I$(VERIFIC_DIR)/%,$(VERIFIC_COMPONENTS)) -DYOSYS_ENABLE_VERIFIC -ifeq ($(OS), Darwin) -LIBS_VERIFIC += $(foreach comp,$(patsubst %,$(VERIFIC_DIR)/%/*-mac.a,$(VERIFIC_COMPONENTS)),-Wl,-force_load $(comp)) -lz -else -LIBS_VERIFIC += -Wl,--whole-archive $(patsubst %,$(VERIFIC_DIR)/%/*-linux.a,$(VERIFIC_COMPONENTS)) -Wl,--no-whole-archive -lz -endif -endif - -ifeq ($(ENABLE_CCACHE),1) -CXX := ccache $(CXX) -else -ifeq ($(ENABLE_SCCACHE),1) -CXX := sccache $(CXX) -endif -endif - -define add_share_file -EXTRA_TARGETS += $(subst //,/,$(1)/$(notdir $(2))) -$(subst //,/,$(1)/$(notdir $(2))): $(2) - $$(P) mkdir -p $(1) - $$(Q) cp "$(YOSYS_SRC)"/$(2) $(subst //,/,$(1)/$(notdir $(2))) -endef - -define add_share_file_and_rename -EXTRA_TARGETS += $(subst //,/,$(1)/$(3)) -$(subst //,/,$(1)/$(3)): $(2) - $$(P) mkdir -p $(1) - $$(Q) cp "$(YOSYS_SRC)"/$(2) $(subst //,/,$(1)/$(3)) -endef - -define add_gen_share_file -EXTRA_TARGETS += $(subst //,/,$(1)/$(notdir $(2))) -$(subst //,/,$(1)/$(notdir $(2))): $(2) - $$(P) mkdir -p $(1) - $$(Q) cp $(2) $(subst //,/,$(1)/$(notdir $(2))) -endef - -define add_include_file -$(eval $(call add_share_file,$(dir share/include/$(1)),$(1))) -endef - -define add_extra_objs -EXTRA_OBJS += $(1) -.SECONDARY: $(1) -endef - -ifeq ($(PRETTY), 1) -P_STATUS = 0 -P_OFFSET = 0 -P_UPDATE = $(eval P_STATUS=$(shell echo $(OBJS) $(PROGRAM_PREFIX)yosys$(EXE) | $(AWK) 'BEGIN { RS = " "; I = $(P_STATUS)+0; } $$1 == "$@" && NR > I { I = NR; } END { print I; }')) -P_SHOW = [$(shell $(AWK) "BEGIN { N=$(words $(OBJS) $(PROGRAM_PREFIX)yosys$(EXE)); printf \"%3d\", $(P_OFFSET)+90*$(P_STATUS)/N; exit; }")%] -P = @echo "$(if $(findstring $@,$(TARGETS) $(EXTRA_TARGETS)),$(eval P_OFFSET = 10))$(call P_UPDATE)$(call P_SHOW) Building $@"; -Q = @ -S = -s -else -P_SHOW = -> -P = -Q = -S = -endif - -$(eval $(call add_include_file,kernel/binding.h)) -$(eval $(call add_include_file,kernel/bitpattern.h)) -$(eval $(call add_include_file,kernel/cellaigs.h)) -$(eval $(call add_include_file,kernel/celledges.h)) -$(eval $(call add_include_file,kernel/celltypes.h)) -$(eval $(call add_include_file,kernel/newcelltypes.h)) -$(eval $(call add_include_file,kernel/consteval.h)) -$(eval $(call add_include_file,kernel/constids.inc)) -$(eval $(call add_include_file,kernel/cost.h)) -$(eval $(call add_include_file,kernel/drivertools.h)) -$(eval $(call add_include_file,kernel/ff.h)) -$(eval $(call add_include_file,kernel/ffinit.h)) -$(eval $(call add_include_file,kernel/ffmerge.h)) -$(eval $(call add_include_file,kernel/fmt.h)) -ifeq ($(ENABLE_ZLIB),1) -$(eval $(call add_include_file,kernel/fstdata.h)) -endif -$(eval $(call add_include_file,kernel/gzip.h)) -$(eval $(call add_include_file,kernel/hashlib.h)) -$(eval $(call add_include_file,kernel/io.h)) -$(eval $(call add_include_file,kernel/json.h)) -$(eval $(call add_include_file,kernel/log.h)) -$(eval $(call add_include_file,kernel/macc.h)) -$(eval $(call add_include_file,kernel/modtools.h)) -$(eval $(call add_include_file,kernel/mem.h)) -$(eval $(call add_include_file,kernel/qcsat.h)) -$(eval $(call add_include_file,kernel/register.h)) -$(eval $(call add_include_file,kernel/rtlil.h)) -$(eval $(call add_include_file,kernel/satgen.h)) -$(eval $(call add_include_file,kernel/scopeinfo.h)) -$(eval $(call add_include_file,kernel/sexpr.h)) -$(eval $(call add_include_file,kernel/sigtools.h)) -$(eval $(call add_include_file,kernel/threading.h)) -$(eval $(call add_include_file,kernel/timinginfo.h)) -$(eval $(call add_include_file,kernel/utils.h)) -$(eval $(call add_include_file,kernel/yosys.h)) -$(eval $(call add_include_file,kernel/yosys_common.h)) -$(eval $(call add_include_file,kernel/yw.h)) -$(eval $(call add_include_file,libs/ezsat/ezsat.h)) -$(eval $(call add_include_file,libs/ezsat/ezminisat.h)) -$(eval $(call add_include_file,libs/ezsat/ezcmdline.h)) -ifeq ($(ENABLE_ZLIB),1) -$(eval $(call add_include_file,libs/fst/fstapi.h)) -endif -$(eval $(call add_include_file,libs/sha1/sha1.h)) -$(eval $(call add_include_file,libs/json11/json11.hpp)) -$(eval $(call add_include_file,passes/fsm/fsmdata.h)) -$(eval $(call add_include_file,passes/techmap/libparse.h)) -$(eval $(call add_include_file,frontends/blif/blifparse.h)) -$(eval $(call add_include_file,backends/rtlil/rtlil_backend.h)) - -OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o kernel/yosys.o kernel/io.o kernel/gzip.o -OBJS += kernel/rtlil_bufnorm.o -OBJS += kernel/log_help.o -ifeq ($(ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS),1) -OBJS += kernel/log_compat.o -endif -OBJS += kernel/binding.o kernel/tclapi.o -OBJS += kernel/cellaigs.o kernel/celledges.o kernel/cost.o kernel/satgen.o kernel/scopeinfo.o kernel/qcsat.o kernel/mem.o kernel/ffmerge.o kernel/ff.o kernel/yw.o kernel/json.o kernel/fmt.o kernel/sexpr.o -OBJS += kernel/drivertools.o kernel/functional.o kernel/threading.o -ifeq ($(ENABLE_ZLIB),1) -OBJS += kernel/fstdata.o -endif -ifeq ($(ENABLE_PLUGINS),1) -ifeq ($(OS), MINGW) -OBJS += libs/dlfcn-win32/dlfcn.o -endif -endif - -kernel/log.o: CXXFLAGS += -DYOSYS_SRC='"$(YOSYS_SRC)"' -kernel/yosys.o: CXXFLAGS += -DYOSYS_DATDIR='"$(DATDIR)"' -DYOSYS_PROGRAM_PREFIX='"$(PROGRAM_PREFIX)"' -ifeq ($(ENABLE_ABC),1) -ifneq ($(ABCEXTERNAL),) -kernel/yosys.o: CXXFLAGS += -DABCEXTERNAL='"$(ABCEXTERNAL)"' -endif -endif - -OBJS += libs/bigint/BigIntegerAlgorithms.o libs/bigint/BigInteger.o libs/bigint/BigIntegerUtils.o -OBJS += libs/bigint/BigUnsigned.o libs/bigint/BigUnsignedInABase.o - -OBJS += libs/sha1/sha1.o - -OBJS += libs/json11/json11.o - -OBJS += libs/ezsat/ezsat.o -OBJS += libs/ezsat/ezminisat.o -OBJS += libs/ezsat/ezcmdline.o - -OBJS += libs/minisat/Options.o -OBJS += libs/minisat/SimpSolver.o -OBJS += libs/minisat/Solver.o -OBJS += libs/minisat/System.o - -ifeq ($(ENABLE_ZLIB),1) -OBJS += libs/fst/fstapi.o -OBJS += libs/fst/fastlz.o -OBJS += libs/fst/lz4.o -endif - -techlibs/%_pm.h: passes/pmgen/pmgen.py techlibs/%.pmg - $(P) mkdir -p $(dir $@) && $(PYTHON_EXECUTABLE) $< -o $@ -p $(notdir $*) $(filter-out $<,$^) - -ifneq ($(SMALL),1) - -OBJS += libs/subcircuit/subcircuit.o - -include $(YOSYS_SRC)/frontends/*/Makefile.inc -include $(YOSYS_SRC)/passes/*/Makefile.inc -include $(YOSYS_SRC)/backends/*/Makefile.inc -include $(YOSYS_SRC)/techlibs/*/Makefile.inc - -else - -include $(YOSYS_SRC)/frontends/verilog/Makefile.inc -ifeq ($(ENABLE_VERIFIC),1) -include $(YOSYS_SRC)/frontends/verific/Makefile.inc -endif -include $(YOSYS_SRC)/frontends/rtlil/Makefile.inc -include $(YOSYS_SRC)/frontends/ast/Makefile.inc -include $(YOSYS_SRC)/frontends/blif/Makefile.inc - -OBJS += passes/hierarchy/hierarchy.o -OBJS += passes/cmds/select.o -OBJS += passes/cmds/show.o -OBJS += passes/cmds/stat.o -OBJS += passes/cmds/design.o -OBJS += passes/cmds/plugin.o - -include $(YOSYS_SRC)/passes/proc/Makefile.inc -include $(YOSYS_SRC)/passes/opt/Makefile.inc -include $(YOSYS_SRC)/passes/techmap/Makefile.inc - -include $(YOSYS_SRC)/backends/verilog/Makefile.inc -include $(YOSYS_SRC)/backends/rtlil/Makefile.inc - -include $(YOSYS_SRC)/techlibs/common/Makefile.inc - -endif - -ifeq ($(LINK_ABC),1) -OBJS += $(PROGRAM_PREFIX)yosys-libabc.a -endif - -# prevent the CXXFLAGS set by this Makefile from reaching abc/Makefile, -# especially the -MD flag which will break the build when CXX is clang -unexport CXXFLAGS - -top-all: $(TARGETS) $(EXTRA_TARGETS) - @echo "" - @echo " Build successful." - @echo "" - -.PHONY: compile-only -compile-only: $(OBJS) $(GENFILES) $(EXTRA_TARGETS) - @echo "" - @echo " Compile successful." - @echo "" - -.PHONY: share -share: $(EXTRA_TARGETS) - @echo "" - @echo " Share directory created." - @echo "" - -$(PROGRAM_PREFIX)yosys$(EXE): $(OBJS) - $(P) $(CXX) -o $(PROGRAM_PREFIX)yosys$(EXE) $(EXE_LINKFLAGS) $(LINKFLAGS) $(OBJS) $(EXE_LIBS) $(LIBS) $(LIBS_VERIFIC) - -libyosys.so: $(filter-out kernel/driver.o,$(OBJS)) -ifeq ($(OS), Darwin) - $(P) $(CXX) -o libyosys.so -shared -undefined dynamic_lookup -Wl,-install_name,libyosys.so $(LINKFLAGS) $^ $(LIBS) $(LIBS_VERIFIC) -else - $(P) $(CXX) -o libyosys.so -shared -Wl,-soname,libyosys.so $(LINKFLAGS) $^ $(LIBS) $(LIBS_VERIFIC) -endif - -libyosys.a: $(filter-out kernel/driver.o,$(OBJS)) - $(P) $(AR) rcs $@ $^ - -%.o: %.cc - $(Q) mkdir -p $(dir $@) - $(P) $(CXX) -o $@ -c $(CPPFLAGS) $(CXXFLAGS) $< - -%.pyh: %.h - $(Q) mkdir -p $(dir $@) - $(P) cat $< | grep -E -v "#[ ]*(include|error)" | $(CXX) $(CXXFLAGS) -x c++ -o $@ -E -P - - -ifeq ($(ENABLE_PYOSYS),1) -$(PY_WRAPPER_FILE).cc: $(PY_GEN_SCRIPT) pyosys/wrappers_tpl.cc $(PY_WRAP_INCLUDES) pyosys/hashlib.h - $(Q) mkdir -p $(dir $@) - $(P) $(UV_ENV) $(PYTHON_EXECUTABLE) $(PY_GEN_SCRIPT) $(PY_WRAPPER_FILE).cc -endif - -%.o: %.cpp - $(Q) mkdir -p $(dir $@) - $(P) $(CXX) -o $@ -c $(CPPFLAGS) $(CXXFLAGS) $< - -YOSYS_REPO := -ifneq (, $(shell command -v git 2>/dev/null)) -ifneq (, $(shell git rev-parse --git-dir 2>/dev/null)) - GIT_REMOTE := $(strip $(shell git config --get remote.origin.url 2>/dev/null | $(AWK) '{print tolower($$0)}')) - ifneq ($(strip $(GIT_REMOTE)),) - YOSYS_REPO := $(strip $(shell echo $(GIT_REMOTE) | $(AWK) -F '[:/]' '{gsub(/\.git$$/, "", $$NF); printf "%s/%s", $$(NF-1), $$NF}')) - endif - ifeq ($(strip $(YOSYS_REPO)),yosyshq/yosys) - YOSYS_REPO := - endif - GIT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD 2>/dev/null) - ifeq ($(filter main HEAD release/v%,$(GIT_BRANCH)),) - YOSYS_REPO := $(YOSYS_REPO) at $(GIT_BRANCH) - endif - YOSYS_REPO := $(strip $(YOSYS_REPO)) -endif -endif - -YOSYS_GIT_STR := $(GIT_REV)$(GIT_DIRTY) -YOSYS_COMPILER := $(notdir $(CXX)) $(shell $(CXX) --version | tr ' ()' '\n' | grep '^[0-9]' | head -n1) $(filter -f% -m% -O% -DNDEBUG,$(CXXFLAGS)) -YOSYS_VER_STR := Yosys $(YOSYS_VER) (git sha1 $(YOSYS_GIT_STR), $(YOSYS_COMPILER)) -ifneq ($(strip $(YOSYS_REPO)),) - YOSYS_VER_STR := $(YOSYS_VER_STR) [$(YOSYS_REPO)] -endif - -kernel/version_$(GIT_REV).cc: $(YOSYS_SRC)/Makefile - $(P) rm -f kernel/version_*.o kernel/version_*.d kernel/version_*.cc - $(Q) mkdir -p kernel && echo "namespace Yosys { extern const char *yosys_version_str; const char *yosys_version_str=\"$(YOSYS_VER_STR)\"; const char *yosys_git_hash_str=\"$(YOSYS_GIT_STR)\"; }" > kernel/version_$(GIT_REV).cc - -ifeq ($(ENABLE_VERIFIC),1) -CXXFLAGS_NOVERIFIC = $(foreach v,$(CXXFLAGS),$(if $(findstring $(VERIFIC_DIR),$(v)),,$(v))) -LIBS_NOVERIFIC = $(foreach v,$(LIBS),$(if $(findstring $(VERIFIC_DIR),$(v)),,$(v))) -else -CXXFLAGS_NOVERIFIC = $(CXXFLAGS) -LIBS_NOVERIFIC = $(LIBS) -endif - -$(PROGRAM_PREFIX)yosys-config: misc/yosys-config.in $(YOSYS_SRC)/Makefile - $(P) $(SED) -e 's#@CXXFLAGS@#$(subst -Ilibs/dlfcn-win32,,$(subst -I. -I"$(YOSYS_SRC)",-I"$(DATDIR)/include",$(strip $(CXXFLAGS_NOVERIFIC))))#;' \ - -e 's#@CXX@#$(strip $(CXX))#;' -e 's#@LINKFLAGS@#$(strip $(LINKFLAGS) $(PLUGIN_LINKFLAGS))#;' -e 's#@LIBS@#$(strip $(LIBS_NOVERIFIC) $(PLUGIN_LIBS))#;' \ - -e 's#@BINDIR@#$(strip $(BINDIR))#;' -e 's#@DATDIR@#$(strip $(DATDIR))#;' < $< > $(PROGRAM_PREFIX)yosys-config - $(Q) chmod +x $(PROGRAM_PREFIX)yosys-config - -.PHONY: check-git-abc - -check-git-abc: - @if [ ! -d "$(YOSYS_SRC)/abc" ] && git -C "$(YOSYS_SRC)" status >/dev/null 2>&1; then \ - echo "Error: The 'abc' directory does not exist."; \ - echo "Initialize the submodule: Run 'git submodule update --init' to set up 'abc' as a submodule."; \ - exit 1; \ - elif git -C "$(YOSYS_SRC)" submodule status abc 2>/dev/null | grep -q '^ '; then \ - exit 0; \ - elif [ -f "$(YOSYS_SRC)/abc/.gitcommit" ] && ! grep -q '\$$Format:%[hH]\$$' "$(YOSYS_SRC)/abc/.gitcommit"; then \ - echo "'abc' comes from a tarball. Continuing."; \ - exit 0; \ - elif git -C "$(YOSYS_SRC)" submodule status abc 2>/dev/null | grep -q '^+'; then \ - echo "'abc' submodule does not match expected commit."; \ - echo "Run 'git submodule update' to check out the correct version."; \ - echo "Note: If testing a different version of abc, call 'git commit abc' in the Yosys source directory to update the expected commit."; \ - exit 1; \ - elif git -C "$(YOSYS_SRC)" submodule status abc 2>/dev/null | grep -q '^U'; then \ - echo "'abc' submodule has merge conflicts."; \ - echo "Please resolve merge conflicts before continuing."; \ - exit 1; \ - elif [ -f "$(YOSYS_SRC)/abc/.gitcommit" ] && grep -q '\$$Format:%[hH]\$$' "$(YOSYS_SRC)/abc/.gitcommit"; then \ - echo "Error: 'abc' is not configured as a git submodule."; \ - echo "To resolve this:"; \ - echo "1. Back up your changes: Save any modifications from the 'abc' directory to another location."; \ - echo "2. Remove the existing 'abc' directory: Delete the 'abc' directory and all its contents."; \ - echo "3. Initialize the submodule: Run 'git submodule update --init' to set up 'abc' as a submodule."; \ - echo "4. Reapply your changes: Move your saved changes back to the 'abc' directory, if necessary."; \ - exit 1; \ - elif ! git -C "$(YOSYS_SRC)" status >/dev/null 2>&1; then \ - echo "$(realpath $(YOSYS_SRC)) is not configured as a git repository, and 'abc' folder is missing."; \ - echo "If you already have ABC, set 'ABCEXTERNAL' make variable to point to ABC executable."; \ - echo "Otherwise, download release archive 'yosys.tar.gz' from https://github.com/YosysHQ/yosys/releases."; \ - echo " ('Source code' archive does not contain submodules.)"; \ - exit 1; \ - else \ - echo "Initialize the submodule: Run 'git submodule update --init' to set up 'abc' as a submodule."; \ - exit 1; \ - fi - -.git-abc-submodule-hash: FORCE - @new=$$(cd abc 2>/dev/null && git rev-parse HEAD 2>/dev/null || echo none); \ - old=$$(cat .git-abc-submodule-hash 2>/dev/null || echo none); \ - if [ "$$new" != "$$old" ]; then \ - echo "$$new" > .git-abc-submodule-hash; \ - fi - -abc/abc$(EXE) abc/libabc.a: .git-abc-submodule-hash | check-git-abc - @if [ "$$(cd abc 2>/dev/null && git rev-parse HEAD 2>/dev/null)" != "$$(cat ../.git-abc-submodule-hash 2>/dev/null || echo none)" ]; then \ - rm -f abc/abc$(EXE); \ - fi - $(P) - $(Q) mkdir -p abc && $(MAKE) -C $(PROGRAM_PREFIX)abc -f "$(realpath $(YOSYS_SRC)/abc/Makefile)" ABCSRC="$(realpath $(YOSYS_SRC)/abc/)" $(S) $(ABCMKARGS) $(if $(filter %.a,$@),PROG="abc",PROG="abc$(EXE)") MSG_PREFIX="$(eval P_OFFSET = 5)$(call P_SHOW)$(eval P_OFFSET = 10) ABC: " $(if $(filter %.a,$@),libabc.a) - -$(PROGRAM_PREFIX)yosys-abc$(EXE): abc/abc$(EXE) - $(P) cp $< $(PROGRAM_PREFIX)yosys-abc$(EXE) - -$(PROGRAM_PREFIX)yosys-libabc.a: abc/libabc.a - $(P) cp $< $(PROGRAM_PREFIX)yosys-libabc.a - -ifneq ($(SEED),) -SEEDOPT="-S $(SEED)" -else -SEEDOPT="" -endif - -ifneq ($(ABCEXTERNAL),) -ABCOPT="-A $(ABCEXTERNAL)" -else -ABCOPT="" -endif - -test: vanilla-test unit-test - -.PHONY: vanilla-test - -vanilla-test: $(TARGETS) $(EXTRA_TARGETS) - @$(MAKE) -C tests vanilla-test \ - $(if $(ENABLE_VERIFIC),ENABLE_VERIFIC=$(ENABLE_VERIFIC)) \ - $(if $(YOSYS_NOVERIFIC),YOSYS_NOVERIFIC=$(YOSYS_NOVERIFIC)) \ - SEEDOPT=$(SEEDOPT) ABCOPT=$(ABCOPT) - -VALGRIND ?= valgrind --error-exitcode=1 --leak-check=full --show-reachable=yes --errors-for-leak-kinds=all - -vgtest: $(TARGETS) $(EXTRA_TARGETS) - $(VALGRIND) ./yosys -p 'setattr -mod -unset top; synth' $$( ls tests/simple/*.v | grep -v repwhile.v ) - @echo "" - @echo " Passed \"make vgtest\"." - @echo "" - -vloghtb: $(TARGETS) $(EXTRA_TARGETS) - +cd tests/vloghtb && bash run-test.sh - @echo "" - @echo " Passed \"make vloghtb\"." - @echo "" - -ystests: $(TARGETS) $(EXTRA_TARGETS) - rm -rf tests/ystests - git clone https://github.com/YosysHQ/yosys-tests.git tests/ystests - +$(MAKE) PATH="$$PWD:$$PATH" -C tests/ystests - @echo "" - @echo " Finished \"make ystests\"." - @echo "" - -# Unit test -unit-test: libyosys.so - @$(MAKE) -f $(UNITESTPATH)/Makefile CXX="$(CXX)" CC="$(CC)" CPPFLAGS="$(CPPFLAGS)" \ - CXXFLAGS="$(CXXFLAGS)" LINKFLAGS="$(LINKFLAGS)" LIBS="$(LIBS)" ROOTPATH="$(CURDIR)" - -clean-unit-test: - @$(MAKE) -f $(UNITESTPATH)/Makefile clean - -install-dev: $(PROGRAM_PREFIX)yosys-config share - $(INSTALL_SUDO) mkdir -p $(DESTDIR)$(BINDIR) - $(INSTALL_SUDO) cp $(PROGRAM_PREFIX)yosys-config $(DESTDIR)$(BINDIR) - $(INSTALL_SUDO) mkdir -p $(DESTDIR)$(DATDIR) - $(INSTALL_SUDO) cp -r share/. $(DESTDIR)$(DATDIR)/. - -install: $(TARGETS) $(EXTRA_TARGETS) - $(INSTALL_SUDO) mkdir -p $(DESTDIR)$(BINDIR) - $(INSTALL_SUDO) cp $(filter-out libyosys.so libyosys.a,$(TARGETS)) $(DESTDIR)$(BINDIR) -ifneq ($(filter $(PROGRAM_PREFIX)yosys$(EXE),$(TARGETS)),) - if [ -n "$(STRIP)" ]; then $(INSTALL_SUDO) $(STRIP) -S $(DESTDIR)$(BINDIR)/$(PROGRAM_PREFIX)yosys$(EXE); fi -endif -ifneq ($(filter $(PROGRAM_PREFIX)yosys-abc$(EXE),$(TARGETS)),) - if [ -n "$(STRIP)" ]; then $(INSTALL_SUDO) $(STRIP) $(DESTDIR)$(BINDIR)/$(PROGRAM_PREFIX)yosys-abc$(EXE); fi -endif -ifneq ($(filter $(PROGRAM_PREFIX)yosys-filterlib$(EXE),$(TARGETS)),) - if [ -n "$(STRIP)" ]; then $(INSTALL_SUDO) $(STRIP) $(DESTDIR)$(BINDIR)/$(PROGRAM_PREFIX)yosys-filterlib$(EXE); fi -endif - $(INSTALL_SUDO) mkdir -p $(DESTDIR)$(DATDIR) - $(INSTALL_SUDO) cp -r share/. $(DESTDIR)$(DATDIR)/. -ifeq ($(ENABLE_LIBYOSYS),1) - $(INSTALL_SUDO) mkdir -p $(DESTDIR)$(LIBDIR) - $(INSTALL_SUDO) cp libyosys.so $(DESTDIR)$(LIBDIR)/ - if [ -n "$(STRIP)" ]; then $(INSTALL_SUDO) $(STRIP) -S $(DESTDIR)$(LIBDIR)/libyosys.so; fi -ifeq ($(ENABLE_LIBYOSYS_STATIC),1) - $(INSTALL_SUDO) cp libyosys.a $(DESTDIR)$(LIBDIR)/ -endif -ifeq ($(ENABLE_PYOSYS),1) - $(INSTALL_SUDO) mkdir -p $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys - $(INSTALL_SUDO) cp $(YOSYS_SRC)/pyosys/__init__.py $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/__init__.py - $(INSTALL_SUDO) cp libyosys.so $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/libyosys.so - $(INSTALL_SUDO) cp -r share $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys -ifeq ($(ENABLE_ABC),1) -ifeq ($(ABCEXTERNAL),) - $(INSTALL_SUDO) cp $(PROGRAM_PREFIX)yosys-abc$(EXE) $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/yosys-abc$(EXE) -endif -endif -endif -endif -ifeq ($(ENABLE_PLUGINS),1) -ifeq ($(OS), MINGW) - $(INSTALL_SUDO) mkdir -p $(DESTDIR)$(LIBDIR) - $(INSTALL_SUDO) cp libyosys_exe.a $(DESTDIR)$(LIBDIR)/ -endif -endif - -uninstall: - $(INSTALL_SUDO) rm -vf $(addprefix $(DESTDIR)$(BINDIR)/,$(notdir $(TARGETS))) - $(INSTALL_SUDO) rm -rvf $(DESTDIR)$(DATDIR) -ifeq ($(ENABLE_LIBYOSYS),1) - $(INSTALL_SUDO) rm -vf $(DESTDIR)$(LIBDIR)/libyosys.so -ifeq ($(ENABLE_LIBYOSYS_STATIC),1) - $(INSTALL_SUDO) rm -vf $(DESTDIR)$(LIBDIR)/libyosys.a -endif -ifeq ($(ENABLE_PYOSYS),1) - $(INSTALL_SUDO) rm -vf $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/libyosys.so - $(INSTALL_SUDO) rm -vf $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/__init__.py - $(INSTALL_SUDO) rmdir $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys -endif -endif - -docs/source/generated/cmds.json: docs/source/generated $(TARGETS) $(EXTRA_TARGETS) - $(Q) ./$(PROGRAM_PREFIX)yosys -p 'help -dump-cmds-json $@' - -docs/source/generated/cells.json: docs/source/generated $(TARGETS) $(EXTRA_TARGETS) - $(Q) ./$(PROGRAM_PREFIX)yosys -p 'help -dump-cells-json $@' - -docs/source/generated/%.cc: backends/%.cc - $(Q) mkdir -p $(@D) - $(Q) cp $< $@ - -# diff returns exit code 1 if the files are different, but it's not an error -docs/source/generated/functional/rosette.diff: backends/functional/smtlib.cc backends/functional/smtlib_rosette.cc - $(Q) mkdir -p $(@D) - $(Q) diff -U 20 $^ > $@ || exit 0 - -PHONY: docs/gen/functional_ir -docs/gen/functional_ir: docs/source/generated/functional/smtlib.cc docs/source/generated/functional/rosette.diff - -docs/source/generated/%.log: docs/source/generated $(TARGETS) $(EXTRA_TARGETS) - $(Q) ./$(PROGRAM_PREFIX)yosys -qQT -h '$*' -l $@ - -docs/source/generated/chformal.cc: passes/cmds/chformal.cc docs/source/generated - $(Q) cp $< $@ - -PHONY: docs/gen/chformal -docs/gen/chformal: docs/source/generated/chformal.log docs/source/generated/chformal.cc - -PHONY: docs/gen docs/usage docs/reqs -docs/gen: $(TARGETS) - $(Q) $(MAKE) -C docs gen - -docs/source/generated: - $(Q) mkdir -p docs/source/generated - -# some commands return an error and print the usage text to stderr -define DOC_USAGE_STDERR -docs/source/generated/$(1): $(TARGETS) docs/source/generated FORCE - -$(Q) ./$(PROGRAM_PREFIX)$(1) --help 2> $$@ -endef -DOCS_USAGE_STDERR := yosys-filterlib - -# The in-tree ABC (yosys-abc) is only built when ABCEXTERNAL is not set. -ifeq ($(ABCEXTERNAL),) -DOCS_USAGE_STDERR += yosys-abc -endif - -$(foreach usage,$(DOCS_USAGE_STDERR),$(eval $(call DOC_USAGE_STDERR,$(usage)))) - -# others print to stdout -define DOC_USAGE_STDOUT -docs/source/generated/$(1): $(TARGETS) docs/source/generated - $(Q) ./$(PROGRAM_PREFIX)$(1) --help > $$@ || rm $$@ -endef -DOCS_USAGE_STDOUT := yosys yosys-smtbmc yosys-witness yosys-config -$(foreach usage,$(DOCS_USAGE_STDOUT),$(eval $(call DOC_USAGE_STDOUT,$(usage)))) - -docs/usage: $(addprefix docs/source/generated/,$(DOCS_USAGE_STDOUT) $(DOCS_USAGE_STDERR)) - -docs/reqs: - $(Q) $(MAKE) -C docs reqs - -.PHONY: docs/prep -docs/prep: docs/source/generated/cells.json docs/source/generated/cmds.json docs/gen docs/usage docs/gen/functional_ir docs/gen/chformal - -DOC_TARGET ?= html -docs: docs/prep - $(Q) $(MAKE) -C docs $(DOC_TARGET) - -clean: clean-py clean-unit-test - rm -rf share - rm -f $(OBJS) $(GENFILES) $(TARGETS) $(EXTRA_TARGETS) $(EXTRA_OBJS) - rm -f kernel/version_*.o kernel/version_*.cc - rm -f libs/*/*.d frontends/*/*.d passes/*/*.d backends/*/*.d kernel/*.d techlibs/*/*.d - rm -rf vloghtb/Makefile vloghtb/refdat vloghtb/rtl vloghtb/scripts vloghtb/spec vloghtb/check_yosys vloghtb/vloghammer_tb.tar.bz2 vloghtb/temp vloghtb/log_test_* - -$(MAKE) -C $(YOSYS_SRC)/tests clean - -$(MAKE) -C $(YOSYS_SRC)/docs clean - rm -rf docs/util/__pycache__ - rm -f libyosys.so - -clean-py: - rm -f $(PY_WRAPPER_FILE).inc.cc $(PY_WRAPPER_FILE).cc - rm -f $(PYTHON_OBJECTS) - rm -f *.whl - rm -f libyosys.so libyosys.a - rm -rf kernel/*.pyh - -clean-abc: - $(MAKE) -C $(YOSYS_SRC)/abc DEP= clean - rm -f $(PROGRAM_PREFIX)yosys-abc$(EXE) $(PROGRAM_PREFIX)yosys-libabc.a abc/abc-[0-9a-f]* abc/libabc-[0-9a-f]*.a .git-abc-submodule-hash - -mrproper: clean - git clean -xdf - -coverage: - ./$(PROGRAM_PREFIX)yosys -qp 'help; help -all' - rm -rf coverage_html - llvm-profdata merge -sparse coverage/coverage_*.profraw -o yosys.profdata - llvm-cov show ./$(PROGRAM_PREFIX)yosys -instr-profile=yosys.profdata -format=html -output-dir=coverage_html --compilation-dir=. -ignore-filename-regex='(^|.*/)libs/.*|/usr/include/.*|$(subst /,\/,$(VERIFIC_DIR))/.*' - -clean_coverage: - rm -rf coverage - rm -f yosys.profdata - -FUNC_KERNEL := functional.cc functional.h sexpr.cc sexpr.h compute_graph.h -FUNC_INCLUDES := $(addprefix --include *,functional/* $(FUNC_KERNEL)) -coverage_functional: - rm -rf coverage.info coverage_html - lcov --capture -d backends/functional -d kernel $(FUNC_INCLUDES) --no-external -o coverage.info - genhtml coverage.info --output-directory coverage_html - -qtcreator: - echo "$(CXXFLAGS)" | grep -o '\-D[^ ]*' | tr ' ' '\n' | sed 's/-D/#define /' | sed 's/=/ /'> qtcreator.config - { for file in $(basename $(OBJS)); do \ - for prefix in cc y l; do if [ -f $${file}.$${prefix} ]; then echo $$file.$${prefix}; fi; done \ - done; find backends frontends kernel libs passes -type f \( -name '*.h' -o -name '*.hh' \); } > qtcreator.files - { echo .; find backends frontends kernel libs passes -type f \( -name '*.h' -o -name '*.hh' \) -printf '%h\n' | sort -u; } > qtcreator.includes - touch qtcreator.creator - -VCX_DIR_NAME := yosys-win32-vcxsrc-$(YOSYS_VER) -vcxsrc: $(GENFILES) $(EXTRA_TARGETS) kernel/version_$(GIT_REV).cc - rm -rf $(VCX_DIR_NAME){,.zip} - cp -f kernel/version_$(GIT_REV).cc kernel/version.cc - set -e; for f in `ls $(filter %.cc %.cpp,$(GENFILES)) $(addsuffix .cc,$(basename $(OBJS))) $(addsuffix .cpp,$(basename $(OBJS))) 2> /dev/null`; do \ - echo "Analyse: $$f" >&2; cpp -std=c++20 -MM -I. -D_YOSYS_ $$f; done | sed 's,.*:,,; s,//*,/,g; s,/[^/]*/\.\./,/,g; y, \\,\n\n,;' | grep '^[^/]' | sort -u | grep -v kernel/version_ > srcfiles.txt - echo "libs/fst/fst_win_unistd.h" >> srcfiles.txt - echo "kernel/version.cc" >> srcfiles.txt - bash misc/create_vcxsrc.sh $(VCX_DIR_NAME) $(YOSYS_VER) - zip $(VCX_DIR_NAME)/genfiles.zip $(GENFILES) kernel/version.cc - zip -r $(VCX_DIR_NAME).zip $(VCX_DIR_NAME)/ - rm -f srcfiles.txt kernel/version.cc - -config-clean: clean - rm -f Makefile.conf - -config-clang: clean - echo 'CONFIG := clang' > Makefile.conf - -config-gcc: clean - echo 'CONFIG := gcc' > Makefile.conf - -config-gcc-static: clean - echo 'CONFIG := gcc-static' > Makefile.conf - echo 'ENABLE_PLUGINS := 0' >> Makefile.conf - echo 'ENABLE_READLINE := 0' >> Makefile.conf - echo 'ENABLE_TCL := 0' >> Makefile.conf - -config-wasi: clean - echo 'CONFIG := wasi' > Makefile.conf - echo 'ENABLE_TCL := 0' >> Makefile.conf - echo 'ENABLE_ABC := 0' >> Makefile.conf - echo 'ENABLE_PLUGINS := 0' >> Makefile.conf - echo 'ENABLE_READLINE := 0' >> Makefile.conf - echo 'ENABLE_ZLIB := 0' >> Makefile.conf - -config-msys2-32: clean - echo 'CONFIG := msys2-32' > Makefile.conf - echo "PREFIX := $(MINGW_PREFIX)" >> Makefile.conf - -config-msys2-64: clean - echo 'CONFIG := msys2-64' > Makefile.conf - echo "PREFIX := $(MINGW_PREFIX)" >> Makefile.conf - -config-gcov: clean - echo 'CONFIG := clang' > Makefile.conf - echo 'ENABLE_GCOV := 1' >> Makefile.conf - echo 'ENABLE_DEBUG := 1' >> Makefile.conf - -config-gprof: clean - echo 'CONFIG := gcc' > Makefile.conf - echo 'ENABLE_GPROF := 1' >> Makefile.conf - -config-sudo: - echo "INSTALL_SUDO := sudo" >> Makefile.conf - -echo-yosys-ver: - @echo "$(YOSYS_VER)" - -echo-git-rev: - @echo "$(GIT_REV)" - -echo-cxx: - @echo "$(CXX)" - --include libs/*/*.d --include frontends/*/*.d --include passes/*/*.d --include backends/*/*.d --include kernel/*.d --include techlibs/*/*.d - -FORCE: - -.PHONY: all top-all abc test install-dev install install-abc docs clean mrproper qtcreator coverage vcxsrc -.PHONY: config-clean config-clang config-gcc config-gcc-static config-gprof config-sudo diff --git a/backends/CMakeLists.txt b/backends/CMakeLists.txt new file mode 100644 index 000000000..a38c2ec94 --- /dev/null +++ b/backends/CMakeLists.txt @@ -0,0 +1,18 @@ +add_subdirectory(aiger) +add_subdirectory(aiger2) +add_subdirectory(blif) +add_subdirectory(btor) +add_subdirectory(cxxrtl) +add_subdirectory(edif) +add_subdirectory(firrtl) +add_subdirectory(functional) +add_subdirectory(intersynth) +add_subdirectory(jny) +add_subdirectory(json) +add_subdirectory(rtlil) +add_subdirectory(simplec) +add_subdirectory(smt2) +add_subdirectory(smv) +add_subdirectory(spice) +add_subdirectory(table) +add_subdirectory(verilog) diff --git a/backends/aiger/CMakeLists.txt b/backends/aiger/CMakeLists.txt new file mode 100644 index 000000000..4cf940196 --- /dev/null +++ b/backends/aiger/CMakeLists.txt @@ -0,0 +1,8 @@ +yosys_backend(aiger + aiger.cc + REQUIRES + json11 +) +yosys_backend(xaiger + xaiger.cc +) diff --git a/backends/aiger/Makefile.inc b/backends/aiger/Makefile.inc deleted file mode 100644 index 4a4cf30bd..000000000 --- a/backends/aiger/Makefile.inc +++ /dev/null @@ -1,4 +0,0 @@ - -OBJS += backends/aiger/aiger.o -OBJS += backends/aiger/xaiger.o - diff --git a/backends/aiger2/CMakeLists.txt b/backends/aiger2/CMakeLists.txt new file mode 100644 index 000000000..f77b8d9ee --- /dev/null +++ b/backends/aiger2/CMakeLists.txt @@ -0,0 +1,5 @@ +yosys_backend(aiger2 + aiger.cc + PROVIDES + write_xaiger2 +) diff --git a/backends/aiger2/Makefile.inc b/backends/aiger2/Makefile.inc deleted file mode 100644 index 494b8d6c6..000000000 --- a/backends/aiger2/Makefile.inc +++ /dev/null @@ -1 +0,0 @@ -OBJS += backends/aiger2/aiger.o diff --git a/backends/blif/CMakeLists.txt b/backends/blif/CMakeLists.txt new file mode 100644 index 000000000..06b177513 --- /dev/null +++ b/backends/blif/CMakeLists.txt @@ -0,0 +1,3 @@ +yosys_backend(blif + blif.cc +) diff --git a/backends/blif/Makefile.inc b/backends/blif/Makefile.inc deleted file mode 100644 index 517dabaf2..000000000 --- a/backends/blif/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ - -OBJS += backends/blif/blif.o - diff --git a/backends/btor/CMakeLists.txt b/backends/btor/CMakeLists.txt new file mode 100644 index 000000000..ca40d538e --- /dev/null +++ b/backends/btor/CMakeLists.txt @@ -0,0 +1,7 @@ +yosys_backend(btor + btor.cc + REQUIRES + bmuxmap + demuxmap + bwmuxmap +) diff --git a/backends/btor/Makefile.inc b/backends/btor/Makefile.inc deleted file mode 100644 index af7ab14dc..000000000 --- a/backends/btor/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ - -OBJS += backends/btor/btor.o - diff --git a/backends/cxxrtl/CMakeLists.txt b/backends/cxxrtl/CMakeLists.txt new file mode 100644 index 000000000..f5d10539a --- /dev/null +++ b/backends/cxxrtl/CMakeLists.txt @@ -0,0 +1,19 @@ +yosys_backend(cxxrtl + cxxrtl_backend.cc + DATA_DIR + include/backends/cxxrtl + DATA_FILES + runtime/README.txt + runtime/cxxrtl/cxxrtl.h + runtime/cxxrtl/cxxrtl_vcd.h + runtime/cxxrtl/cxxrtl_time.h + runtime/cxxrtl/cxxrtl_replay.h + runtime/cxxrtl/capi/cxxrtl_capi.cc + runtime/cxxrtl/capi/cxxrtl_capi.h + runtime/cxxrtl/capi/cxxrtl_capi_vcd.cc + runtime/cxxrtl/capi/cxxrtl_capi_vcd.h + REQUIRES + hierarchy + flatten + proc +) diff --git a/backends/cxxrtl/Makefile.inc b/backends/cxxrtl/Makefile.inc deleted file mode 100644 index dd77d2ad3..000000000 --- a/backends/cxxrtl/Makefile.inc +++ /dev/null @@ -1,11 +0,0 @@ - -OBJS += backends/cxxrtl/cxxrtl_backend.o - -$(eval $(call add_include_file,backends/cxxrtl/runtime/cxxrtl/cxxrtl.h)) -$(eval $(call add_include_file,backends/cxxrtl/runtime/cxxrtl/cxxrtl_vcd.h)) -$(eval $(call add_include_file,backends/cxxrtl/runtime/cxxrtl/cxxrtl_time.h)) -$(eval $(call add_include_file,backends/cxxrtl/runtime/cxxrtl/cxxrtl_replay.h)) -$(eval $(call add_include_file,backends/cxxrtl/runtime/cxxrtl/capi/cxxrtl_capi.cc)) -$(eval $(call add_include_file,backends/cxxrtl/runtime/cxxrtl/capi/cxxrtl_capi.h)) -$(eval $(call add_include_file,backends/cxxrtl/runtime/cxxrtl/capi/cxxrtl_capi_vcd.cc)) -$(eval $(call add_include_file,backends/cxxrtl/runtime/cxxrtl/capi/cxxrtl_capi_vcd.h)) diff --git a/backends/edif/CMakeLists.txt b/backends/edif/CMakeLists.txt new file mode 100644 index 000000000..126d09f07 --- /dev/null +++ b/backends/edif/CMakeLists.txt @@ -0,0 +1,3 @@ +yosys_backend(edif + edif.cc +) diff --git a/backends/edif/Makefile.inc b/backends/edif/Makefile.inc deleted file mode 100644 index 93de0e24f..000000000 --- a/backends/edif/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ - -OBJS += backends/edif/edif.o - diff --git a/backends/firrtl/CMakeLists.txt b/backends/firrtl/CMakeLists.txt new file mode 100644 index 000000000..2f38cd208 --- /dev/null +++ b/backends/firrtl/CMakeLists.txt @@ -0,0 +1,8 @@ +yosys_backend(firrtl + firrtl.cc + REQUIRES + pmuxtree + bmuxmap + demuxmap + bwmuxmap +) diff --git a/backends/firrtl/Makefile.inc b/backends/firrtl/Makefile.inc deleted file mode 100644 index fdf100d34..000000000 --- a/backends/firrtl/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ - -OBJS += backends/firrtl/firrtl.o - diff --git a/backends/functional/CMakeLists.txt b/backends/functional/CMakeLists.txt new file mode 100644 index 000000000..5e7a6e92f --- /dev/null +++ b/backends/functional/CMakeLists.txt @@ -0,0 +1,12 @@ +yosys_backend(functional_cxx + cxx.cc +) +yosys_backend(functional_smt2 + smtlib.cc +) +yosys_backend(functional_rosette + smtlib_rosette.cc +) +yosys_test_pass(generic + test_generic.cc +) diff --git a/backends/functional/Makefile.inc b/backends/functional/Makefile.inc deleted file mode 100644 index 16d1c0542..000000000 --- a/backends/functional/Makefile.inc +++ /dev/null @@ -1,4 +0,0 @@ -OBJS += backends/functional/cxx.o -OBJS += backends/functional/smtlib.o -OBJS += backends/functional/smtlib_rosette.o -OBJS += backends/functional/test_generic.o diff --git a/backends/intersynth/CMakeLists.txt b/backends/intersynth/CMakeLists.txt new file mode 100644 index 000000000..e34bab4e1 --- /dev/null +++ b/backends/intersynth/CMakeLists.txt @@ -0,0 +1,3 @@ +yosys_backend(intersynth + intersynth.cc +) diff --git a/backends/intersynth/Makefile.inc b/backends/intersynth/Makefile.inc deleted file mode 100644 index 85df1b393..000000000 --- a/backends/intersynth/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ - -OBJS += backends/intersynth/intersynth.o - diff --git a/backends/jny/CMakeLists.txt b/backends/jny/CMakeLists.txt new file mode 100644 index 000000000..e76a74e97 --- /dev/null +++ b/backends/jny/CMakeLists.txt @@ -0,0 +1,5 @@ +yosys_backend(jny + jny.cc + PROVIDES + jny +) diff --git a/backends/jny/Makefile.inc b/backends/jny/Makefile.inc deleted file mode 100644 index 5e417128e..000000000 --- a/backends/jny/Makefile.inc +++ /dev/null @@ -1,2 +0,0 @@ - -OBJS += backends/jny/jny.o diff --git a/backends/json/CMakeLists.txt b/backends/json/CMakeLists.txt new file mode 100644 index 000000000..99c404d92 --- /dev/null +++ b/backends/json/CMakeLists.txt @@ -0,0 +1,5 @@ +yosys_backend(json + json.cc + PROVIDES + json +) diff --git a/backends/json/Makefile.inc b/backends/json/Makefile.inc deleted file mode 100644 index a463daf91..000000000 --- a/backends/json/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ - -OBJS += backends/json/json.o - diff --git a/backends/rtlil/CMakeLists.txt b/backends/rtlil/CMakeLists.txt new file mode 100644 index 000000000..40b3cffe0 --- /dev/null +++ b/backends/rtlil/CMakeLists.txt @@ -0,0 +1,11 @@ +yosys_backend(rtlil + rtlil_backend.cc + rtlil_backend.h + PROVIDES + dump + DATA_DIR + include/backends/rtlil + DATA_FILES + rtlil_backend.h + ESSENTIAL +) diff --git a/backends/rtlil/Makefile.inc b/backends/rtlil/Makefile.inc deleted file mode 100644 index f691282ca..000000000 --- a/backends/rtlil/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ - -OBJS += backends/rtlil/rtlil_backend.o - diff --git a/backends/simplec/CMakeLists.txt b/backends/simplec/CMakeLists.txt new file mode 100644 index 000000000..1a9feed9f --- /dev/null +++ b/backends/simplec/CMakeLists.txt @@ -0,0 +1,3 @@ +yosys_backend(simplec + simplec.cc +) diff --git a/backends/simplec/Makefile.inc b/backends/simplec/Makefile.inc deleted file mode 100644 index fee1376c5..000000000 --- a/backends/simplec/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ - -OBJS += backends/simplec/simplec.o - diff --git a/backends/smt2/CMakeLists.txt b/backends/smt2/CMakeLists.txt new file mode 100644 index 000000000..c60bace7b --- /dev/null +++ b/backends/smt2/CMakeLists.txt @@ -0,0 +1,20 @@ +yosys_backend(smt2 + smt2.cc + REQUIRES + json11 + DATA_DIR + python3 + DATA_FILES + smtio.py + ywio.py + REQUIRES + bmuxmap + demuxmap +) + +yosys_python_executable(yosys-smtbmc smtbmc.py + INSTALL_IF YOSYS_INSTALL_DRIVER OR YOSYS_INSTALL_LIBRARY +) +yosys_python_executable(yosys-witness witness.py + INSTALL_IF YOSYS_INSTALL_DRIVER OR YOSYS_INSTALL_LIBRARY +) diff --git a/backends/smt2/Makefile.inc b/backends/smt2/Makefile.inc deleted file mode 100644 index 3afe990e7..000000000 --- a/backends/smt2/Makefile.inc +++ /dev/null @@ -1,46 +0,0 @@ - -OBJS += backends/smt2/smt2.o - -ifneq ($(CONFIG),mxe) -ifneq ($(CONFIG),emcc) - -# MSYS targets support yosys-smtbmc, but require a launcher script -ifeq ($(CONFIG),$(filter $(CONFIG),msys2 msys2-64)) -TARGETS += $(PROGRAM_PREFIX)yosys-smtbmc.exe $(PROGRAM_PREFIX)yosys-smtbmc-script.py -TARGETS += $(PROGRAM_PREFIX)yosys-witness.exe $(PROGRAM_PREFIX)yosys-witness-script.py -# Needed to find the Python interpreter for yosys-smtbmc scripts. -# Override if necessary, it is only used for msys2 targets. -PYTHON := $(shell cygpath -w -m $(PREFIX)/bin/python3) - -$(PROGRAM_PREFIX)yosys-smtbmc-script.py: backends/smt2/smtbmc.py - $(P) sed -e 's|##yosys-sys-path##|sys.path += [os.path.dirname(os.path.realpath(__file__)) + p for p in ["/share/python3", "/../share/$(PROGRAM_PREFIX)yosys/python3"]]|;' \ - -e "s|#!/usr/bin/env python3|#!$(PYTHON)|" < $< > $@ - -$(PROGRAM_PREFIX)yosys-witness-script.py: backends/smt2/witness.py - $(P) sed -e 's|##yosys-sys-path##|sys.path += [os.path.dirname(os.path.realpath(__file__)) + p for p in ["/share/python3", "/../share/$(PROGRAM_PREFIX)yosys/python3"]]|;' \ - -e "s|#!/usr/bin/env python3|#!$(PYTHON)|" < $< > $@ - -$(PROGRAM_PREFIX)yosys-smtbmc.exe: misc/launcher.c $(PROGRAM_PREFIX)yosys-smtbmc-script.py - $(P) $(CXX) -DGUI=0 -O -s -o $@ $< - -$(PROGRAM_PREFIX)yosys-witness.exe: misc/launcher.c $(PROGRAM_PREFIX)yosys-witness-script.py - $(P) $(CXX) -DGUI=0 -O -s -o $@ $< -# Other targets -else -TARGETS += $(PROGRAM_PREFIX)yosys-smtbmc $(PROGRAM_PREFIX)yosys-witness - -$(PROGRAM_PREFIX)yosys-smtbmc: backends/smt2/smtbmc.py - $(P) sed 's|##yosys-sys-path##|sys.path += [os.path.dirname(os.path.realpath(__file__)) + p for p in ["/share/python3", "/../share/$(PROGRAM_PREFIX)yosys/python3"]]|;' < $< > $@.new - $(Q) chmod +x $@.new - $(Q) mv $@.new $@ - -$(PROGRAM_PREFIX)yosys-witness: backends/smt2/witness.py - $(P) sed 's|##yosys-sys-path##|sys.path += [os.path.dirname(os.path.realpath(__file__)) + p for p in ["/share/python3", "/../share/$(PROGRAM_PREFIX)yosys/python3"]]|;' < $< > $@.new - $(Q) chmod +x $@.new - $(Q) mv $@.new $@ -endif - -$(eval $(call add_share_file,share/python3,backends/smt2/smtio.py)) -$(eval $(call add_share_file,share/python3,backends/smt2/ywio.py)) -endif -endif diff --git a/backends/smt2/smtbmc.py b/backends/smt2/smtbmc.py old mode 100644 new mode 100755 index 9dfbd2a25..60fa97e36 --- a/backends/smt2/smtbmc.py +++ b/backends/smt2/smtbmc.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!@PYTHON_SHEBANG@ # # yosys -- Yosys Open SYnthesis Suite # @@ -18,7 +18,7 @@ # import os, sys, getopt, re, bisect, json -##yosys-sys-path## +sys.path += [os.path.dirname(os.path.realpath(__file__)) + p for p in ["/share/python3", "/../share/@YOSYS_PROGRAM_PREFIX@yosys/python3"]] from smtio import SmtIo, SmtOpts, MkVcd from ywio import ReadWitness, WriteWitness, WitnessValues from collections import defaultdict diff --git a/backends/smt2/witness.py b/backends/smt2/witness.py old mode 100644 new mode 100755 index b7e25851c..83416c695 --- a/backends/smt2/witness.py +++ b/backends/smt2/witness.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!@PYTHON_SHEBANG@ # # yosys -- Yosys Open SYnthesis Suite # @@ -18,7 +18,7 @@ # import os, sys, itertools, re -##yosys-sys-path## +sys.path += [os.path.dirname(os.path.realpath(__file__)) + p for p in ["/share/python3", "/../share/@YOSYS_PROGRAM_PREFIX@yosys/python3"]] import json import click diff --git a/backends/smv/CMakeLists.txt b/backends/smv/CMakeLists.txt new file mode 100644 index 000000000..ea9e85f28 --- /dev/null +++ b/backends/smv/CMakeLists.txt @@ -0,0 +1,7 @@ +yosys_backend(smv + smv.cc + REQUIRES + bmuxmap + demuxmap + bwmuxmap +) diff --git a/backends/smv/Makefile.inc b/backends/smv/Makefile.inc deleted file mode 100644 index 66c192d80..000000000 --- a/backends/smv/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ - -OBJS += backends/smv/smv.o - diff --git a/backends/spice/CMakeLists.txt b/backends/spice/CMakeLists.txt new file mode 100644 index 000000000..efbfc84d0 --- /dev/null +++ b/backends/spice/CMakeLists.txt @@ -0,0 +1,3 @@ +yosys_backend(spice + spice.cc +) diff --git a/backends/spice/Makefile.inc b/backends/spice/Makefile.inc deleted file mode 100644 index 9c8530cb2..000000000 --- a/backends/spice/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ - -OBJS += backends/spice/spice.o - diff --git a/backends/table/CMakeLists.txt b/backends/table/CMakeLists.txt new file mode 100644 index 000000000..371d1e8f0 --- /dev/null +++ b/backends/table/CMakeLists.txt @@ -0,0 +1,3 @@ +yosys_backend(table + table.cc +) diff --git a/backends/table/Makefile.inc b/backends/table/Makefile.inc deleted file mode 100644 index 8cd1dc619..000000000 --- a/backends/table/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ - -OBJS += backends/table/table.o - diff --git a/backends/verilog/CMakeLists.txt b/backends/verilog/CMakeLists.txt new file mode 100644 index 000000000..6de8dd1f6 --- /dev/null +++ b/backends/verilog/CMakeLists.txt @@ -0,0 +1,8 @@ +yosys_backend(verilog + verilog_backend.cc + verilog_backend.h + REQUIRES + bmuxmap + demuxmap + clean_zerowidth +) diff --git a/backends/verilog/Makefile.inc b/backends/verilog/Makefile.inc deleted file mode 100644 index c2dffef7a..000000000 --- a/backends/verilog/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ - -OBJS += backends/verilog/verilog_backend.o - diff --git a/cmake/CheckLibcFeatures.cmake b/cmake/CheckLibcFeatures.cmake new file mode 100644 index 000000000..3fc32afe3 --- /dev/null +++ b/cmake/CheckLibcFeatures.cmake @@ -0,0 +1,40 @@ +include(CMakePushCheckState) +include(CheckSourceCompiles) +include(CheckCXXSymbolExists) + +function(check_glob) + check_cxx_symbol_exists(glob "glob.h" HAVE_GLOB) + return (PROPAGATE HAVE_BLOB) +endfunction() + +function(check_pthread_create) + if (Threads_FOUND) + # On WASI, `pthread_create()` is always available, but always fails on triples without threading + # support. Probe for it while requesting the stub implementation to be hidden, otherwise we will + # end up always crashing at runtime on thread creation. + cmake_push_check_state(RESET) + set(CMAKE_REQUIRED_DEFINITIONS -D_WASI_STRICT_PTHREAD) + set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) + check_source_compiles(CXX [[ + #include + int main() { + pthread_create(0, 0, 0, 0); + } + ]] HAVE_PTHREAD_CREATE) + cmake_pop_check_state() + endif() + return (PROPAGATE HAVE_PTHREAD_CREATE) +endfunction() + +function(check_system) + check_cxx_symbol_exists(system "stdlib.h" HAVE_SYSTEM) +endfunction() + +function(check_popen) + check_cxx_symbol_exists(popen "stdio.h" HAVE_POPEN) + if (NOT HAVE_POPEN) + unset(HAVE_POPEN CACHE) + # https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/popen-wpopen + check_cxx_symbol_exists(_popen "stdio.h" HAVE_POPEN) + endif() +endfunction() diff --git a/cmake/Condition.cmake b/cmake/Condition.cmake new file mode 100644 index 000000000..6ef400a32 --- /dev/null +++ b/cmake/Condition.cmake @@ -0,0 +1,35 @@ +# Syntax: +# +# condition( ...) +# +# If `...` is truthful (evaluated as in `if()`) then assigns 1 to ``, else assigns 0. +# The assigned value is `0`/`1` rather than `TRUE`/`FALSE` for ease of use in generator expressions. +# Note that `...` *must* be unquoted. +# +# To understand how a certain outcome is reached, reconfigure the project with `--log-level VERBOSE`. +# +# Believe it or not, CMake doesn't have this built in! +# +macro(condition var) + if (${ARGN}) + set(${var} 1) + else() + set(${var} 0) + endif() + + set(_debug_expr) + foreach (token ${ARGN}) + if (DEFINED ${token}) + if (${${token}}) + list(APPEND _debug_expr "${token}:1") + else() + list(APPEND _debug_expr "${token}:0") + endif() + else() + list(APPEND _debug_expr "${token}") + endif() + endforeach() + string(JOIN " " _debug_expr ${_debug_expr}) + message(VERBOSE " ${var} = ${${var}} (${_debug_expr})") + unset(_debug_expr) +endmacro() diff --git a/cmake/FindDlfcn.cmake b/cmake/FindDlfcn.cmake new file mode 100644 index 000000000..201745a3f --- /dev/null +++ b/cmake/FindDlfcn.cmake @@ -0,0 +1,24 @@ +include(CMakePushCheckState) +include(CheckCXXSymbolExists) +include(FindPackageHandleStandardArgs) + +if (WIN32 OR MSYS) + # Windows; dlopen is available via a polyfill `libs/dlfcn-win32`. + set(Dlfcn_LIBRARIES dlfcn) +else() + # Unix and Wasm; dlopen may or may not be available depending on platform. + cmake_push_check_state(RESET) + set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_DL_LIBS}) + check_cxx_symbol_exists(dlopen "dlfcn.h" HAVE_DLOPEN) + cmake_pop_check_state() + + if (HAVE_DLOPEN) + add_library(dlfcn INTERFACE) + target_link_libraries(dlfcn INTERFACE ${CMAKE_DL_LIBS}) + set(Dlfcn_LIBRARIES dlfcn) + endif() +endif() + +find_package_handle_standard_args(Dlfcn + REQUIRED_VARS Dlfcn_LIBRARIES +) diff --git a/cmake/FindPyosysEnv.cmake b/cmake/FindPyosysEnv.cmake new file mode 100644 index 000000000..be4672ef7 --- /dev/null +++ b/cmake/FindPyosysEnv.cmake @@ -0,0 +1,42 @@ +# We need a *third* `FindPython`-style call in this codebase because the host +# `Python3_EXECUTABLE` may not have pybind11 and cxxheaderparser installed, +# and installing it can be onerous. To work around this problem we try to detect +# whether the host interpreter has the necessary dependencies first, and if it +# does not, fall back to using `uv`. + +foreach (strategy host uv fail) + if (strategy STREQUAL "host") + set(PyosysEnv_PYTHON ${Python3_EXECUTABLE}) + elseif (strategy STREQUAL "uv") + set(PyosysEnv_PYTHON uv run --no-project --with pybind11>3,<4 --with cxxheaderparser python) + else() + set(PyosysEnv_PYTHON) + break() + endif() + + execute_process( + COMMAND ${PyosysEnv_PYTHON} -m pybind11 --includes + RESULT_VARIABLE result + OUTPUT_VARIABLE output + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + if (result EQUAL 0) + string(REGEX REPLACE " ?-I" ";" pybind11_INCLUDE_DIR "${output}") + list(FILTER pybind11_INCLUDE_DIR INCLUDE REGEX "/pybind11/") + + execute_process( + COMMAND ${PyosysEnv_PYTHON} ${CMAKE_SOURCE_DIR}/pyosys/generator.py --help + RESULT_VARIABLE result + OUTPUT_QUIET + ERROR_QUIET + ) + if (result EQUAL 0) + break() + endif() + endif() +endforeach() + +find_package_handle_standard_args(PyosysEnv + REQUIRED_VARS PyosysEnv_PYTHON pybind11_INCLUDE_DIR +) diff --git a/cmake/FindPython3Embed.cmake b/cmake/FindPython3Embed.cmake new file mode 100644 index 000000000..f3fda9070 --- /dev/null +++ b/cmake/FindPython3Embed.cmake @@ -0,0 +1,16 @@ +# Wrapper to improve behavior of `FindPython3` during cross-compilation. +# Does not entirely fix the problem; CMake 4.0 introduces `Python_ARTIFACTS_PREFIX`, which will. + +# Stash the package found status +get_property(packages_found GLOBAL PROPERTY PACKAGES_FOUND) +get_property(packages_not_found GLOBAL PROPERTY PACKAGES_NOT_FOUND) +get_property(required_version GLOBAL PROPERTY _CMAKE_Python3_REQUIRED_VERSION) + +# The `EXACT` specifier prevents the situation of `FindPython3` discovering a newer libpython-dev +# than the interpreter found in the past, rejecting it because it is too new, and giving up. +find_package(Python3 EXACT ${Python3_VERSION} COMPONENTS Development.Embed) +set(Python3Embed_FOUND ${Python3_Development.Embed_FOUND}) + +set_property(GLOBAL PROPERTY PACKAGES_FOUND "${packages_found}") +set_property(GLOBAL PROPERTY PACKAGES_NOT_FOUND "${packages_not_found}") +set_property(GLOBAL PROPERTY _CMAKE_Python3_REQUIRED_VERSION "${required_version}") diff --git a/cmake/PkgConfig.cmake b/cmake/PkgConfig.cmake new file mode 100644 index 000000000..b37d74622 --- /dev/null +++ b/cmake/PkgConfig.cmake @@ -0,0 +1,43 @@ +# Syntax: +# +# pkg_config_import() +# +# To use this command, `find_package(PkgConfig)` must be used beforehand, but it does +# not have to succeed. If the `PkgConfig` package is not found, all imports silently fail. +# +# Imports `` as a CMake `IMPORTED` target `PkgConfig::`. +# Updates the global `PACKAGES_FOUND` and `PACKAGES_NOT_FOUND` properties and defines +# the `_FOUND` variable. +# +function(pkg_config_import arg_PREFIX) + cmake_parse_arguments(PARSE_ARGV 1 arg "" "" "MODULES") + if (NOT arg_MODULES) + set(arg_MODULES ${arg_PREFIX}) + endif() + + if (PkgConfig_FOUND) + # Once CMake 4.1 is available, this call should be replaced with `cmake_pkg_config()`. + pkg_check_modules(${arg_PREFIX} IMPORTED_TARGET ${arg_MODULES}) + if (${arg_PREFIX}_FOUND) + # We found the pkgconfig file, but is it actually a usable package? + # The main cause of failure here would be cross-compiling, which pkg-config does not + # handle very well (especially pre-`cmake_pkg_config()`). + try_compile(is_usable + SOURCE_FROM_CONTENT "main.cc" "int main() {}" + LINK_LIBRARIES PkgConfig::${arg_PREFIX} + LOG_DESCRIPTION "Checking if PkgConfig::${arg_PREFIX} is usable" + ) + if (NOT is_usable) + message(STATUS "Modules '${arg_MODULES}' unusable (bad \$PKG_CONFIG_LIBDIR?)") + set(${arg_PREFIX}_FOUND 0) + endif() + endif() + endif() + + if (${arg_PREFIX}_FOUND) + set_property(GLOBAL APPEND PROPERTY PACKAGES_FOUND ${arg_PREFIX}) + else() + set_property(GLOBAL APPEND PROPERTY PACKAGES_NOT_FOUND ${arg_PREFIX}) + endif() + return (PROPAGATE ${arg_PREFIX}_FOUND) +endfunction() diff --git a/cmake/PmgenCommand.cmake b/cmake/PmgenCommand.cmake new file mode 100644 index 000000000..889d7653e --- /dev/null +++ b/cmake/PmgenCommand.cmake @@ -0,0 +1,60 @@ +# Syntax: +# +# pmgen_command( +# [...] +# [PREFIX ] +# [DEBUG] +# ) +# +# Builds `_pm.h` in the current binary directory from pmgen source files ``, which must have +# the `*.pmg` extension. If `...` contains more than one file, `` must be provided. +# +# Defines the following variables: +# - `PMGEN__DEFINED`: Boolean indicating whether this command was successfully invoked. +# - `PMGEN__OUTPUT`: The header file generated by `pmgen`. +# +# Usage example: +# +# pmgen_command(my_dsp +# my_dsp.pmg +# ) +# yosys_pass(my_dsp +# my_dsp.cc +# ${PMGEN_my_dsp_OUTPUT} +# ) +# +# Usage example with multiple files: +# +# pmgen_command(my_dsp +# my_dsp_macc.pmg +# my_dsp_carry.pmg +# PREFIX +# my_dsp +# ) +# +function(pmgen_command arg_NAME) + cmake_parse_arguments(PARSE_ARGV 1 arg "DEBUG" "PREFIX" "") + set(arg_INPUTS ${arg_UNPARSED_ARGUMENTS}) + + set(pmgen_script ${CMAKE_SOURCE_DIR}/passes/pmgen/pmgen.py) + set(pmgen_output ${CMAKE_CURRENT_BINARY_DIR}/${arg_NAME}_pm.h) + cmake_path(RELATIVE_PATH pmgen_output BASE_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_VARIABLE pmgen_output_rel) + add_custom_command( + DEPENDS ${pmgen_script} ${arg_INPUTS} + OUTPUT ${pmgen_output} + COMMAND ${Python3_EXECUTABLE} + ${pmgen_script} + "$<$:-g>" + "$<$:-p;${arg_PREFIX}>" + -o ${pmgen_output} + ${arg_INPUTS} + COMMAND_EXPAND_LISTS + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + VERBATIM + COMMENT "Compiling pattern matcher ${pmgen_output_rel}" + ) + + # The usage of this command is somewhat inspired by `flex_target()` and `bison_target()`. + set(PMGEN_${arg_NAME}_DEFINED TRUE) + set(PMGEN_${arg_NAME}_OUTPUT ${pmgen_output} PARENT_SCOPE) +endfunction() diff --git a/cmake/YosysAbc.cmake b/cmake/YosysAbc.cmake new file mode 100644 index 000000000..3b2267504 --- /dev/null +++ b/cmake/YosysAbc.cmake @@ -0,0 +1,96 @@ +include(CheckCompilerFlag) + +define_property(TARGET PROPERTY YOSYS_IS_ABC) + +function(target_safe_compile_options target scope) + foreach (lang C CXX) + foreach (flag ${ARGN}) + check_compiler_flag(${lang} ${flag} HAVE_${lang}_${flag}) + if (HAVE_${lang}_${flag}) + target_compile_options(${target} ${scope} $<$:${flag}>) + endif() + endforeach() + endforeach() +endfunction() + +function(_yosys_abc_extract_makefile result vardecl filename) + # Parse a Makefile fragment and extracts the first matching variable assignment into + # a list of values. + file(READ ${filename} contents) + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${filename}) + if ("${contents}" MATCHES "${vardecl}(\\\\\n|[ \t])*(([^\\\\\n]|\\\\\n)+)") + string(REGEX REPLACE "(\\\\\n|[ \t])+" ";" ${result} "${CMAKE_MATCH_2}") + endif() + return (PROPAGATE ${result}) +endfunction() + +function(yosys_abc_target arg_LIBNAME arg_EXENAME) + cmake_parse_arguments(PARSE_ARGV 2 arg "" "INSTALL_IF" "") + + # Instead of using either the ABC Make or CMake build system, we parse the source + # of truth: ABC's `module.make` files. This turns out to be quite trivial. + # This way, no assumptions about the environment are made, and Yosys can be compiled + # on Windows without MSYS as a result (while benefitting other platforms as well). + set(all_sources) + _yosys_abc_extract_makefile(module_files "MODULES :=" ${CMAKE_SOURCE_DIR}/abc/Makefile) + _yosys_abc_extract_makefile(module_files_cudd "MODULES \\+=" ${CMAKE_SOURCE_DIR}/abc/Makefile) + list(REMOVE_ITEM module_files "$(wildcard" "src/ext*)") + foreach (module_file ${module_files} ${module_files_cudd}) + _yosys_abc_extract_makefile(module_sources "SRC \\+=" ${CMAKE_SOURCE_DIR}/abc/${module_file}/module.make) + list(APPEND all_sources ${module_sources}) + endforeach() + list(TRANSFORM all_sources PREPEND abc/) + + # Required to get `-DABC_NAMESPACE` below to work consistently. + set_source_files_properties(${all_sources} PROPERTIES LANGUAGE CXX) + + set(main_source abc/src/base/main/main.c) + list(REMOVE_ITEM all_sources ${main_source}) + + find_package(Threads) + yosys_cxx_library(${arg_LIBNAME} STATIC + OUTPUT_NAME ${arg_LIBNAME} + ) + target_sources(${arg_LIBNAME} PRIVATE ${all_sources}) + target_include_directories(${arg_LIBNAME} PRIVATE abc/src) + target_compile_definitions(${arg_LIBNAME} PUBLIC + WIN32_NO_DLL + ABC_NAMESPACE=abc + ABC_USE_STDINT_H=1 + ABC_USE_CUDD=1 + ABC_NO_DYNAMIC_LINKING + $<${YOSYS_ENABLE_THREADS}:ABC_USE_PTHREADS> + $<${YOSYS_ENABLE_READLINE}:ABC_USE_READLINE> + ABC_NO_RLIMIT + ) + target_safe_compile_options(${arg_LIBNAME} PRIVATE + -fpermissive + -fno-exceptions + -Wno-write-strings + -Wno-changes-meaning + -Wno-attributes + -Wno-deprecated-declarations + -Wno-deprecated-comma-subscript + -Wno-format + -Wno-constant-logical-operand + ) + target_link_libraries(${arg_LIBNAME} PUBLIC + $<${YOSYS_ENABLE_THREADS}:Threads::Threads> + $<${YOSYS_ENABLE_READLINE}:PkgConfig::readline> + $<$:-lshlwapi> + ) + set_target_properties(${arg_LIBNAME} PROPERTIES + YOSYS_IS_ABC ON + ) + + yosys_cxx_executable(${arg_EXENAME} + OUTPUT_NAME ${arg_EXENAME} + INSTALL_IF "${arg_INSTALL_IF}" + ) + target_sources(${arg_EXENAME} PRIVATE ${main_source}) + target_include_directories(${arg_EXENAME} PRIVATE abc/src) + target_link_libraries(${arg_EXENAME} PRIVATE ${arg_LIBNAME}) + set_target_properties(${arg_EXENAME} PROPERTIES + YOSYS_IS_ABC ON + ) +endfunction() diff --git a/cmake/YosysAbcSubmodule.cmake b/cmake/YosysAbcSubmodule.cmake new file mode 100644 index 000000000..2a648a7e0 --- /dev/null +++ b/cmake/YosysAbcSubmodule.cmake @@ -0,0 +1,64 @@ +# depends on YosysVersion.cmake + +function(yosys_check_abc_submodule) + yosys_call_git(status) + set(yosys_status "tarball") + if (git_result EQUAL 0) + set(yosys_status "git") + endif() + + yosys_call_git(submodule status abc) + set(git_commit) + if (EXISTS "${CMAKE_SOURCE_DIR}/abc/.gitcommit") + file(READ "${CMAKE_SOURCE_DIR}/abc/.gitcommit" git_commit) + string(STRIP "${git_commit}" git_commit) + endif() + set(abc_status "none") + if (git_result EQUAL 0 AND git_output MATCHES "^ ") + set(abc_status "git") + elseif (git_result EQUAL 0 AND git_output MATCHES "^\\+") + set(abc_status "git-changed") + elseif (git_result EQUAL 0 AND git_output MATCHES "^U") + set(abc_status "git-conflict") + elseif (git_commit MATCHES "^[0-9a-fA-F]+$") + set(abc_status "tarball") + elseif (git_commit MATCHES "\\$Format:%[hH]\\$") + set(abc_status "unknown") + endif() + + if (abc_status STREQUAL "git" OR abc_status STREQUAL "tarball") + # Normal submodule or a tarball. + elseif (abc_status STREQUAL "git-changed") + message(FATAL_ERROR + "'abc' submodule does not match expected commit.\n" + "Run 'git submodule update' to check out the correct version.\n" + "Note: If testing a different version of ABC, call 'git commit abc' " + "in the Yosys source directory to update the expected commit.\n" + ) + elseif (abc_status STREQUAL "git-conflict") + message(FATAL_ERROR + "'abc' submodule has merge conflicts.\n" + "Please resolve merge conflicts before continuing.\n" + ) + elseif (abc_status STREQUAL "unknown") # OK + message(FATAL_ERROR + "Error: 'abc' is not configured as a git submodule.\n" + "To resolve this:\n" + "1. Back up your changes: Save any modifications from the 'abc' directory to another location.\n" + "2. Remove the existing 'abc' directory: Delete the 'abc' directory and all its contents.\n" + "3. Initialize the submodule: Run 'git submodule update --init' to set up 'abc' as a submodule.\n" + "4. Reapply your changes: Move your saved changes back to the 'abc' directory, if necessary.\n" + ) + elseif (yosys_status STREQUAL "git") # OK + message(FATAL_ERROR + "Initialize the submodule: Run 'git submodule update --init' to set up 'abc' as a submodule.\n" + ) + else() # + message(FATAL_ERROR + "${CMAKE_SOURCE_DIR} is not configured as a git repository, and 'abc' folder is missing.\n" + "If you already have ABC, set 'ABCEXTERNAL' make variable to point to ABC executable.\n" + "Otherwise, download release archive 'yosys.tar.gz' from https://github.com/YosysHQ/yosys/releases.\n" + " ('Source code' archive does not contain submodules.)\n" + ) + endif() +endfunction() diff --git a/cmake/YosysComponent.cmake b/cmake/YosysComponent.cmake new file mode 100644 index 000000000..9786ba156 --- /dev/null +++ b/cmake/YosysComponent.cmake @@ -0,0 +1,321 @@ +set(namespace "yosys") + +# Properties internal to the component system. +define_property(TARGET PROPERTY YOSYS_COMPONENT) +define_property(TARGET PROPERTY YOSYS_PROVIDES) +define_property(TARGET PROPERTY YOSYS_REQUIRES) +define_property(TARGET PROPERTY YOSYS_DATA_FILES) +define_property(TARGET PROPERTY YOSYS_ENABLE_IF) + +# Syntax: +# +# yosys_component( [INTERFACE] +# [...] +# [DEFINITIONS ...] +# [INCLUDE_DIRS ...] +# [LIBRARIES ...] +# [PROVIDES ...] +# [REQUIRES ...] +# [DATA_DIR ] +# [DATA_FILES ...] +# [DATA_EXPLICIT [ ]...] +# [ESSENTIAL] +# [ENABLE_IF ""] +# ) +# +# Creates a target `yosys_` (if `` is empty) or `yosys__` (if `` is not empty). +# This target is an library target with some Yosys-specific behavior that simplifies partitioning the compiler +# into small pieces with explicitly defined compile-time and run-time dependency metadata. Circular dependencies +# between compilation units in different components are allowed. +# +# Parameter description: +# - `INTERFACE` should be specified for header-only libraries. +# - `...` is a shortcut for `target_sources(PRIVATE)`. +# - `DEFINITIONS ...` is a shortcut for `target_compile_definitions(PRIVATE)`. +# - `INCLUDE_DIRS ...` is a shortcut for `target_include_directories(PRIVATE)`. +# - `LIBRARIES ...` is a shortcut for `target_link_libraries(PRIVATE)`. +# - `PROVIDES ...` creates aliases to each `` component name. +# - `REQUIRES ...` ensures that if this target is linked into the Yosys binary, then every +# `` component is also linked in. +# - `DATA_DIR ` configures a base directory for installing data files; this directory +# is (relative to the root build directory or the installation prefix) `share/` if +# `DATA_DIR` is provided, and `share` if not. +# - `DATA_FILES ...` installs each of `` as `share///`, +# where `` is the directory name of `` and `` is the filename of ``. +# - `DATA_EXPLICIT [ ]...` installs each `` as `share//`. +# Where possible, `DATA_FILES` should be used instead. +# - `ESSENTIAL` ensures that this target is always linked into the Yosys binary. +# - `ENABLE_IF ""` marks the component as available only when `if()` would run. +# +# Avoid using this function directly. Instead, use one of the wrappers below as follows: +# - to define a normal pass, use `yosys_pass()` to add a component called ``. +# - to define a test pass, use `yosys_test_pass()` to add a component called `test_`. +# - to define a frontend, use `yosys_frontend()` to add a component called `read_`. +# - to define a backend, use `yosys_backend()` to add a component called `write_`. +# - if the component sources define more than one pass, use `PROVIDES` with names of the other passes. +# - if the component uses `Pass::call()`, `Frontend::frontend_call()`, `Backend::backend_call()`, or other +# similar functions, use `REQUIRES` with names of all possibly needed passes. +# - if the component needs an essential pass, add the latter to `REQUIRES` anyway for completeness. +# - if the component subclasses a `ScriptPass`, build Yosys, then run `misc/script_pass_depends.py ` +# to extract the names of all referenced passes. +# - in general, component names should be the same as corresponding pass names (as used in the REPL), +# but this is not a hard requirement and any suitable name can be used if desired. +# +function(yosys_component arg_PREFIX arg_NAME) + cmake_parse_arguments(PARSE_ARGV 2 arg + "INTERFACE;ESSENTIAL;BOOTSTRAP" + "DATA_DIR;ENABLE_IF" + "DEFINITIONS;INCLUDE_DIRS;LIBRARIES;DATA_FILES;DATA_EXPLICIT;PROVIDES;REQUIRES" + ) + set(arg_SOURCES ${arg_UNPARSED_ARGUMENTS}) + if ("${arg_ENABLE_IF}" STREQUAL "") + set(arg_ENABLE_IF TRUE) + endif() + + if (arg_PREFIX STREQUAL "") + set(component "${arg_NAME}") + else() + set(component "${arg_PREFIX}_${arg_NAME}") + endif() + set(target "${namespace}_${component}") + list(TRANSFORM arg_PROVIDES PREPEND ${namespace}_ OUTPUT_VARIABLE provides_targets) + + # An OBJECT library is used to allow for circular symbol dependencies between any source files. + # Unfortunately, public dependencies between OBJECT libraries aren't handled correctly, so we have + # to do it ourselves. + if (arg_SOURCES AND NOT arg_INTERFACE) + add_library(${target} EXCLUDE_FROM_ALL OBJECT) + target_sources(${target} PRIVATE ${arg_SOURCES}) + target_include_directories(${target} PRIVATE ${arg_INCLUDE_DIRS}) + target_compile_definitions(${target} PRIVATE ${arg_DEFINITIONS}) + target_link_libraries(${target} PUBLIC yosys_common ${arg_LIBRARIES}) + foreach (alias ${provides_targets}) + add_library(${alias} ALIAS ${target}) + endforeach() + else() + add_library(${target} EXCLUDE_FROM_ALL INTERFACE) + endif() + set_target_properties(${target} PROPERTIES + YOSYS_COMPONENT YES + YOSYS_PROVIDES "${arg_PROVIDES}" + YOSYS_REQUIRES "${arg_REQUIRES}" + YOSYS_DATA_FILES "" + YOSYS_ENABLE_IF "${arg_ENABLE_IF}" + ) + + set(share_file_pairs) + foreach (share_file ${arg_DATA_FILES}) + list(APPEND share_file_pairs ${share_file} ${share_file}) + endforeach() + list(APPEND share_file_pairs ${arg_DATA_EXPLICIT}) + if (share_file_pairs) + set(data_depends) + set(share_root ${CMAKE_BINARY_DIR}/share) + while (share_file_pairs) + list(LENGTH share_file_pairs share_file_unpaired) + if (share_file_unpaired EQUAL 1) + message(FATAL_ERROR "Unpaired DATA_EXPLICIT argument: ${share_file_pairs}") + endif() + list(POP_FRONT share_file_pairs dst_file src_file) + cmake_path(ABSOLUTE_PATH src_file BASE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + set(out_dir ${arg_DATA_DIR}) + cmake_path(GET dst_file PARENT_PATH dst_parent) + cmake_path(APPEND out_dir ${dst_parent}) + cmake_path(GET dst_file FILENAME dst_filename) + cmake_path(APPEND out_dir ${dst_filename} OUTPUT_VARIABLE out_file) + file(MAKE_DIRECTORY ${share_root}/${out_dir}) + add_custom_command( + DEPENDS ${src_file} + OUTPUT ${share_root}/${out_file} + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src_file} ${share_root}/${out_file} + VERBATIM + COMMENT "Copying share/${out_file}" + ) + set_property(TARGET ${target} APPEND PROPERTY YOSYS_DATA_FILES ${out_file}) + list(APPEND data_depends ${share_root}/${out_file}) + endwhile() + add_custom_target(${target}-data DEPENDS ${data_depends}) + add_dependencies(${target} ${target}-data) + endif() + + if (NOT arg_BOOTSTRAP) + set_property(TARGET yosys_everything APPEND PROPERTY YOSYS_REQUIRES ${component}) + if (arg_ESSENTIAL) + set_property(TARGET yosys_essentials APPEND PROPERTY YOSYS_REQUIRES ${component}) + endif() + endif() +endfunction() + +# Syntax: +# +# yosys_core( [