From 26a3478d8dc8401f393e6a6339b0c1a4d6ae98ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 24 Oct 2024 11:33:53 +0200 Subject: [PATCH 1/9] Drop timestamp in generate_bram_types_sim.py I'm working on build reproducibility of Fedora packages, and this patch fixes an issue observed in test rebuilds: the timestamp was set to the actual time of the build, making builds nonreproducible. Other "Generated by" strings do not include a timestamp, so drop it here too. --- techlibs/quicklogic/qlf_k6n10f/generate_bram_types_sim.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/techlibs/quicklogic/qlf_k6n10f/generate_bram_types_sim.py b/techlibs/quicklogic/qlf_k6n10f/generate_bram_types_sim.py index e57c04a08..65bb25476 100644 --- a/techlibs/quicklogic/qlf_k6n10f/generate_bram_types_sim.py +++ b/techlibs/quicklogic/qlf_k6n10f/generate_bram_types_sim.py @@ -1,10 +1,9 @@ import sys -from datetime import datetime, timezone def generate(filename): with open(filename, "w") as f: f.write("// **AUTOGENERATED FILE** **DO NOT EDIT**\n") - f.write(f"// Generated by {sys.argv[0]} at {datetime.now(timezone.utc)}\n") + f.write(f"// Generated by {sys.argv[0]}\n") f.write("`timescale 1ns /10ps\n") for a_width in [1,2,4,9,18,36]: From 1836a571c992ea2981325f8979028b418eca247b Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Tue, 7 Jan 2025 19:25:15 +0100 Subject: [PATCH 2/9] share: fix misleading log message --- passes/opt/share.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/passes/opt/share.cc b/passes/opt/share.cc index 1408c512a..a4c17795c 100644 --- a/passes/opt/share.cc +++ b/passes/opt/share.cc @@ -1255,7 +1255,6 @@ struct ShareWorker qcsat.max_cell_count = 100; } - pool sat_cells; std::set bits_queue; std::vector cell_active, other_cell_active; @@ -1298,8 +1297,8 @@ struct ShareWorker qcsat.ez->assume(qcsat.ez->AND(sub1, sub2)); - log(" Size of SAT problem: %d cells, %d variables, %d clauses\n", - GetSize(sat_cells), qcsat.ez->numCnfVariables(), qcsat.ez->numCnfClauses()); + log(" Size of SAT problem: %d variables, %d clauses\n", + qcsat.ez->numCnfVariables(), qcsat.ez->numCnfClauses()); if (qcsat.ez->solve(sat_model, sat_model_values)) { log(" According to the SAT solver this pair of cells can not be shared.\n"); From 652a1b98066bf6eb2e39098e896d2636ddd41090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Fri, 13 Dec 2024 18:10:10 +0100 Subject: [PATCH 3/9] macc: Stop using the B port The B port is for single-bit summands. These can just as well be represented as an additional summand on the A port (which supports summands of arbitrary width). An upcoming `$macc_v2` cell won't be special-casing single-bit summands in any way. In preparation, make the following changes: * remove the `bit_ports` field from the `Macc` helper (instead add any single-bit summands to `ports` next to other summands) * leave `B` empty on cells emitted from `Macc::to_cell` --- Makefile | 1 + kernel/consteval.h | 3 -- kernel/macc.h | 32 ++++-------------- kernel/satgen.cc | 7 ---- passes/opt/share.cc | 2 +- passes/techmap/alumacc.cc | 2 +- passes/techmap/maccmap.cc | 24 ++++++++++---- passes/tests/test_cell.cc | 13 ++++---- tests/alumacc/macc_b_port_compat.ys | 50 +++++++++++++++++++++++++++++ tests/alumacc/run-test.sh | 6 ++++ 10 files changed, 89 insertions(+), 51 deletions(-) create mode 100644 tests/alumacc/macc_b_port_compat.ys create mode 100644 tests/alumacc/run-test.sh diff --git a/Makefile b/Makefile index 0614235ca..59f6652ca 100644 --- a/Makefile +++ b/Makefile @@ -869,6 +869,7 @@ endif SH_ABC_TEST_DIRS = SH_ABC_TEST_DIRS += tests/memories SH_ABC_TEST_DIRS += tests/aiger +SH_ABC_TEST_DIRS += tests/alumacc # seed-tests/ is a dummy string, not a directory .PHONY: seed-tests diff --git a/kernel/consteval.h b/kernel/consteval.h index 73d05f0b3..331d8f128 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -315,9 +315,6 @@ struct ConstEval Macc macc; macc.from_cell(cell); - if (!eval(macc.bit_ports, undef, cell)) - return false; - for (auto &port : macc.ports) { if (!eval(port.in_a, undef, cell)) return false; diff --git a/kernel/macc.h b/kernel/macc.h index 4af08cfd8..55940769d 100644 --- a/kernel/macc.h +++ b/kernel/macc.h @@ -30,14 +30,11 @@ struct Macc RTLIL::SigSpec in_a, in_b; bool is_signed, do_subtract; }; - std::vector ports; - RTLIL::SigSpec bit_ports; void optimize(int width) { std::vector new_ports; - RTLIL::SigSpec new_bit_ports; RTLIL::Const off(0, width); for (auto &port : ports) @@ -48,11 +45,6 @@ struct Macc if (GetSize(port.in_a) < GetSize(port.in_b)) std::swap(port.in_a, port.in_b); - if (GetSize(port.in_a) == 1 && GetSize(port.in_b) == 0 && !port.is_signed && !port.do_subtract) { - bit_ports.append(port.in_a); - continue; - } - if (port.in_a.is_fully_const() && port.in_b.is_fully_const()) { RTLIL::Const v = port.in_a.as_const(); if (GetSize(port.in_b)) @@ -79,12 +71,6 @@ struct Macc new_ports.push_back(port); } - for (auto &bit : bit_ports) - if (bit == State::S1) - off = const_add(off, RTLIL::Const(1, width), false, false, width); - else if (bit != State::S0) - new_bit_ports.append(bit); - if (off.as_bool()) { port_t port; port.in_a = off; @@ -94,7 +80,6 @@ struct Macc } new_ports.swap(ports); - bit_ports = new_bit_ports; } void from_cell(RTLIL::Cell *cell) @@ -102,7 +87,6 @@ struct Macc RTLIL::SigSpec port_a = cell->getPort(ID::A); ports.clear(); - bit_ports = cell->getPort(ID::B); auto config_bits = cell->getParam(ID::CONFIG); int config_cursor = 0; @@ -145,6 +129,9 @@ struct Macc ports.push_back(this_port); } + for (auto bit : cell->getPort(ID::B)) + ports.push_back(port_t{{bit}, {}, false, false}); + log_assert(config_cursor == config_width); log_assert(port_a_cursor == GetSize(port_a)); } @@ -190,11 +177,11 @@ struct Macc } cell->setPort(ID::A, port_a); - cell->setPort(ID::B, bit_ports); + cell->setPort(ID::B, {}); cell->setParam(ID::CONFIG, config_bits); cell->setParam(ID::CONFIG_WIDTH, GetSize(config_bits)); cell->setParam(ID::A_WIDTH, GetSize(port_a)); - cell->setParam(ID::B_WIDTH, GetSize(bit_ports)); + cell->setParam(ID::B_WIDTH, 0); } bool eval(RTLIL::Const &result) const @@ -219,19 +206,12 @@ struct Macc result = const_add(result, summand, port.is_signed, port.is_signed, GetSize(result)); } - for (auto bit : bit_ports) { - if (bit.wire) - return false; - result = const_add(result, bit.data, false, false, GetSize(result)); - } - return true; } bool is_simple_product() { - return bit_ports.empty() && - ports.size() == 1 && + return ports.size() == 1 && !ports[0].in_b.empty() && !ports[0].do_subtract; } diff --git a/kernel/satgen.cc b/kernel/satgen.cc index ba6d664db..dd15b51f3 100644 --- a/kernel/satgen.cc +++ b/kernel/satgen.cc @@ -743,7 +743,6 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep) if (cell->type == ID($macc)) { std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); - std::vector b = importDefSigSpec(cell->getPort(ID::B), timestep); std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); Macc macc; @@ -785,12 +784,6 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep) } } - for (int i = 0; i < GetSize(b); i++) { - std::vector val(GetSize(y), ez->CONST_FALSE); - val.at(0) = b.at(i); - tmp = ez->vec_add(tmp, val); - } - if (model_undef) { std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); diff --git a/passes/opt/share.cc b/passes/opt/share.cc index 1408c512a..5d4e2d67d 100644 --- a/passes/opt/share.cc +++ b/passes/opt/share.cc @@ -117,7 +117,7 @@ struct ShareWorker static int bits_macc(const Macc &m, int width) { - int bits = GetSize(m.bit_ports); + int bits = 0; for (auto &p : m.ports) bits += bits_macc_port(p, width); return bits; diff --git a/passes/techmap/alumacc.cc b/passes/techmap/alumacc.cc index 05a3d1702..d89a6fbec 100644 --- a/passes/techmap/alumacc.cc +++ b/passes/techmap/alumacc.cc @@ -283,7 +283,7 @@ struct AlumaccWorker for (auto &it : sig_macc) { auto n = it.second; - RTLIL::SigSpec A, B, C = n->macc.bit_ports; + RTLIL::SigSpec A, B, C; bool a_signed = false, b_signed = false; bool subtract_b = false; alunode_t *alunode; diff --git a/passes/techmap/maccmap.cc b/passes/techmap/maccmap.cc index 2235bdef9..911d66cfa 100644 --- a/passes/techmap/maccmap.cc +++ b/passes/techmap/maccmap.cc @@ -286,19 +286,23 @@ void maccmap(RTLIL::Module *module, RTLIL::Cell *cell, bool unmap) log(" %s %s * %s (%dx%d bits, %s)\n", port.do_subtract ? "sub" : "add", log_signal(port.in_a), log_signal(port.in_b), GetSize(port.in_a), GetSize(port.in_b), port.is_signed ? "signed" : "unsigned"); - if (GetSize(macc.bit_ports) != 0) - log(" add bits %s (%d bits)\n", log_signal(macc.bit_ports), GetSize(macc.bit_ports)); - if (unmap) { typedef std::pair summand_t; std::vector summands; + RTLIL::SigSpec bit_ports; + for (auto &port : macc.ports) { summand_t this_summand; if (GetSize(port.in_b)) { this_summand.first = module->addWire(NEW_ID, width); module->addMul(NEW_ID, port.in_a, port.in_b, this_summand.first, port.is_signed); + } else if (GetSize(port.in_a) == 1 && GetSize(port.in_b) == 0 && !port.is_signed && !port.do_subtract) { + // Mimic old 'bit_ports' treatment in case it's relevant for performance, + // i.e. defer single-bit summands to be the last ones + bit_ports.append(port.in_a); + continue; } else if (GetSize(port.in_a) != width) { this_summand.first = module->addWire(NEW_ID, width); module->addPos(NEW_ID, port.in_a, this_summand.first, port.is_signed); @@ -309,7 +313,7 @@ void maccmap(RTLIL::Module *module, RTLIL::Cell *cell, bool unmap) summands.push_back(this_summand); } - for (auto &bit : macc.bit_ports) + for (auto &bit : bit_ports) summands.push_back(summand_t(bit, false)); if (GetSize(summands) == 0) @@ -346,14 +350,20 @@ void maccmap(RTLIL::Module *module, RTLIL::Cell *cell, bool unmap) else { MaccmapWorker worker(module, width); + RTLIL::SigSpec bit_ports; - for (auto &port : macc.ports) - if (GetSize(port.in_b) == 0) + for (auto &port : macc.ports) { + // Mimic old 'bit_ports' treatment in case it's relevant for performance, + // i.e. defer single-bit summands to be the last ones + if (GetSize(port.in_a) == 1 && GetSize(port.in_b) == 0 && !port.is_signed && !port.do_subtract) + bit_ports.append(port.in_a); + else if (GetSize(port.in_b) == 0) worker.add(port.in_a, port.is_signed, port.do_subtract); else worker.add(port.in_a, port.in_b, port.is_signed, port.do_subtract); + } - for (auto &bit : macc.bit_ports) + for (auto bit : bit_ports) worker.add(bit, 0); module->connect(cell->getPort(ID::Y), worker.synth()); diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index b9b4d2195..39b7ccd3a 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -201,18 +201,19 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce this_port.do_subtract = xorshift32(2) == 1; macc.ports.push_back(this_port); } - - wire = module->addWire(ID::B); - wire->width = xorshift32(mulbits_a ? xorshift32(4)+1 : xorshift32(16)+1); - wire->port_input = true; - macc.bit_ports = wire; + // Macc::to_cell sets the input ports + macc.to_cell(cell); wire = module->addWire(ID::Y); wire->width = width; wire->port_output = true; cell->setPort(ID::Y, wire); - macc.to_cell(cell); + // override the B input (macc helpers always sets an empty vector) + wire = module->addWire(ID::B); + wire->width = xorshift32(mulbits_a ? xorshift32(4)+1 : xorshift32(16)+1); + wire->port_input = true; + cell->setPort(ID::B, wire); } if (cell_type == ID($lut)) diff --git a/tests/alumacc/macc_b_port_compat.ys b/tests/alumacc/macc_b_port_compat.ys new file mode 100644 index 000000000..1ed2ad34c --- /dev/null +++ b/tests/alumacc/macc_b_port_compat.ys @@ -0,0 +1,50 @@ +# We don't set the B port on $macc cells anymore, +# test compatibility with older RTLIL files which can +# have the B port populated + +read_verilog < Date: Wed, 8 Jan 2025 13:04:14 +0100 Subject: [PATCH 4/9] write_json: add option to include $scopeinfo cells --- backends/json/json.cc | 27 ++++++++++++++++++----- tests/various/json_scopeinfo.ys | 38 +++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 tests/various/json_scopeinfo.ys diff --git a/backends/json/json.cc b/backends/json/json.cc index 287c01ead..197223c63 100644 --- a/backends/json/json.cc +++ b/backends/json/json.cc @@ -34,6 +34,7 @@ struct JsonWriter bool use_selection; bool aig_mode; bool compat_int_mode; + bool scopeinfo_mode; Design *design; Module *module; @@ -43,9 +44,9 @@ struct JsonWriter dict sigids; pool aig_models; - JsonWriter(std::ostream &f, bool use_selection, bool aig_mode, bool compat_int_mode) : + JsonWriter(std::ostream &f, bool use_selection, bool aig_mode, bool compat_int_mode, bool scopeinfo_mode) : f(f), use_selection(use_selection), aig_mode(aig_mode), - compat_int_mode(compat_int_mode) { } + compat_int_mode(compat_int_mode), scopeinfo_mode(scopeinfo_mode) { } string get_string(string str) { @@ -194,7 +195,7 @@ struct JsonWriter continue; // Eventually we will want to emit $scopeinfo, but currently this // will break JSON netlist consumers like nextpnr - if (c->type == ID($scopeinfo)) + if (!scopeinfo_mode && c->type == ID($scopeinfo)) continue; f << stringf("%s\n", first ? "" : ","); f << stringf(" %s: {\n", get_name(c->name).c_str()); @@ -356,6 +357,9 @@ struct JsonBackend : public Backend { log(" -selected\n"); log(" output only select module\n"); log("\n"); + log(" -scopeinfo\n"); + log(" include $scopeinfo cells in the output\n"); + log("\n"); log("\n"); log("The general syntax of the JSON output created by this command is as follows:\n"); log("\n"); @@ -601,6 +605,7 @@ struct JsonBackend : public Backend { bool aig_mode = false; bool compat_int_mode = false; bool use_selection = false; + bool scopeinfo_mode = false; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) @@ -617,13 +622,17 @@ struct JsonBackend : public Backend { use_selection = true; continue; } + if (args[argidx] == "-scopeinfo") { + scopeinfo_mode = true; + continue; + } break; } extra_args(f, filename, args, argidx); log_header(design, "Executing JSON backend.\n"); - JsonWriter json_writer(*f, use_selection, aig_mode, compat_int_mode); + JsonWriter json_writer(*f, use_selection, aig_mode, compat_int_mode, scopeinfo_mode); json_writer.write_design(design); } } JsonBackend; @@ -648,6 +657,9 @@ struct JsonPass : public Pass { log(" emit 32-bit or smaller fully-defined parameter values directly\n"); log(" as JSON numbers (for compatibility with old parsers)\n"); log("\n"); + log(" -scopeinfo\n"); + log(" include $scopeinfo cells in the output\n"); + log("\n"); log("See 'help write_json' for a description of the JSON format used.\n"); log("\n"); } @@ -656,6 +668,7 @@ struct JsonPass : public Pass { std::string filename; bool aig_mode = false; bool compat_int_mode = false; + bool scopeinfo_mode = false; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) @@ -672,6 +685,10 @@ struct JsonPass : public Pass { compat_int_mode = true; continue; } + if (args[argidx] == "-scopeinfo") { + scopeinfo_mode = true; + continue; + } break; } extra_args(args, argidx, design); @@ -693,7 +710,7 @@ struct JsonPass : public Pass { f = &buf; } - JsonWriter json_writer(*f, true, aig_mode, compat_int_mode); + JsonWriter json_writer(*f, true, aig_mode, compat_int_mode, scopeinfo_mode); json_writer.write_design(design); if (!empty) { diff --git a/tests/various/json_scopeinfo.ys b/tests/various/json_scopeinfo.ys new file mode 100644 index 000000000..50219f16e --- /dev/null +++ b/tests/various/json_scopeinfo.ys @@ -0,0 +1,38 @@ +read_verilog < Date: Wed, 8 Jan 2025 14:46:47 +0100 Subject: [PATCH 5/9] emit $scopeinfo cells by default --- backends/json/json.cc | 22 ++++++++++------------ tests/various/json_scopeinfo.ys | 12 ++++++------ 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/backends/json/json.cc b/backends/json/json.cc index 197223c63..20d42f626 100644 --- a/backends/json/json.cc +++ b/backends/json/json.cc @@ -193,8 +193,6 @@ struct JsonWriter for (auto c : module->cells()) { if (use_selection && !module->selected(c)) continue; - // Eventually we will want to emit $scopeinfo, but currently this - // will break JSON netlist consumers like nextpnr if (!scopeinfo_mode && c->type == ID($scopeinfo)) continue; f << stringf("%s\n", first ? "" : ","); @@ -357,8 +355,8 @@ struct JsonBackend : public Backend { log(" -selected\n"); log(" output only select module\n"); log("\n"); - log(" -scopeinfo\n"); - log(" include $scopeinfo cells in the output\n"); + log(" -noscopeinfo\n"); + log(" don't include $scopeinfo cells in the output\n"); log("\n"); log("\n"); log("The general syntax of the JSON output created by this command is as follows:\n"); @@ -605,7 +603,7 @@ struct JsonBackend : public Backend { bool aig_mode = false; bool compat_int_mode = false; bool use_selection = false; - bool scopeinfo_mode = false; + bool scopeinfo_mode = true; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) @@ -622,8 +620,8 @@ struct JsonBackend : public Backend { use_selection = true; continue; } - if (args[argidx] == "-scopeinfo") { - scopeinfo_mode = true; + if (args[argidx] == "-noscopeinfo") { + scopeinfo_mode = false; continue; } break; @@ -657,8 +655,8 @@ struct JsonPass : public Pass { log(" emit 32-bit or smaller fully-defined parameter values directly\n"); log(" as JSON numbers (for compatibility with old parsers)\n"); log("\n"); - log(" -scopeinfo\n"); - log(" include $scopeinfo cells in the output\n"); + log(" -noscopeinfo\n"); + log(" don't include $scopeinfo cells in the output\n"); log("\n"); log("See 'help write_json' for a description of the JSON format used.\n"); log("\n"); @@ -668,7 +666,7 @@ struct JsonPass : public Pass { std::string filename; bool aig_mode = false; bool compat_int_mode = false; - bool scopeinfo_mode = false; + bool scopeinfo_mode = true; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) @@ -685,8 +683,8 @@ struct JsonPass : public Pass { compat_int_mode = true; continue; } - if (args[argidx] == "-scopeinfo") { - scopeinfo_mode = true; + if (args[argidx] == "-noscopeinfo") { + scopeinfo_mode = false; continue; } break; diff --git a/tests/various/json_scopeinfo.ys b/tests/various/json_scopeinfo.ys index 50219f16e..a5adbde10 100644 --- a/tests/various/json_scopeinfo.ys +++ b/tests/various/json_scopeinfo.ys @@ -26,13 +26,13 @@ flatten -scopename prep write_json json_scopeinfo.out -!grep -qvF '$scopeinfo' json_scopeinfo.out - -write_json -scopeinfo json_scopeinfo.out !grep -qF '$scopeinfo' json_scopeinfo.out +write_json -noscopeinfo json_scopeinfo.out +!grep -qvF '$scopeinfo' json_scopeinfo.out + json -o json_scopeinfo.out -!grep -qvF '$scopeinfo' json_scopeinfo.out - -json -scopeinfo -o json_scopeinfo.out !grep -qF '$scopeinfo' json_scopeinfo.out + +json -noscopeinfo -o json_scopeinfo.out +!grep -qvF '$scopeinfo' json_scopeinfo.out From 828ccfac4bf2f2d823d30b647da98b72363c72c0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 9 Jan 2025 00:21:05 +0000 Subject: [PATCH 6/9] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 5842a8bc3..195404e1d 100644 --- a/Makefile +++ b/Makefile @@ -153,7 +153,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.48+57 +YOSYS_VER := 0.48+62 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 13b183c9c550c296a7071e36f91e8437831d9cd3 Mon Sep 17 00:00:00 2001 From: mikesinouye Date: Thu, 9 Jan 2025 18:30:23 -0800 Subject: [PATCH 7/9] Add option for a custom flatten block separator char --- passes/techmap/flatten.cc | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/passes/techmap/flatten.cc b/passes/techmap/flatten.cc index ea5855a09..619fa4a68 100644 --- a/passes/techmap/flatten.cc +++ b/passes/techmap/flatten.cc @@ -28,22 +28,22 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -IdString concat_name(RTLIL::Cell *cell, IdString object_name) +IdString concat_name(RTLIL::Cell *cell, IdString object_name, const std::string &separator = ".") { if (object_name[0] == '\\') - return stringf("%s.%s", cell->name.c_str(), object_name.c_str() + 1); + return stringf("%s%s%s", cell->name.c_str(), separator.c_str(), object_name.c_str() + 1); else { std::string object_name_str = object_name.str(); if (object_name_str.substr(0, 8) == "$flatten") object_name_str.erase(0, 8); - return stringf("$flatten%s.%s", cell->name.c_str(), object_name_str.c_str()); + return stringf("$flatten%s%s%s", cell->name.c_str(), separator.c_str(), object_name_str.c_str()); } } template -IdString map_name(RTLIL::Cell *cell, T *object) +IdString map_name(RTLIL::Cell *cell, T *object, const std::string &separator = ".") { - return cell->module->uniquify(concat_name(cell, object->name)); + return cell->module->uniquify(concat_name(cell, object->name, separator)); } void map_sigspec(const dict &map, RTLIL::SigSpec &sig, RTLIL::Module *into = nullptr) @@ -60,6 +60,7 @@ struct FlattenWorker bool ignore_wb = false; bool create_scopeinfo = true; bool create_scopename = false; + std::string separator = "."; template void map_attributes(RTLIL::Cell *cell, T *object, IdString orig_object_name) @@ -107,13 +108,13 @@ struct FlattenWorker } } - void flatten_cell(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Cell *cell, RTLIL::Module *tpl, SigMap &sigmap, std::vector &new_cells) + void flatten_cell(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Cell *cell, RTLIL::Module *tpl, SigMap &sigmap, std::vector &new_cells, const std::string &separator) { // Copy the contents of the flattened cell dict memory_map; for (auto &tpl_memory_it : tpl->memories) { - RTLIL::Memory *new_memory = module->addMemory(map_name(cell, tpl_memory_it.second), tpl_memory_it.second); + RTLIL::Memory *new_memory = module->addMemory(map_name(cell, tpl_memory_it.second, separator), tpl_memory_it.second); map_attributes(cell, new_memory, tpl_memory_it.second->name); memory_map[tpl_memory_it.first] = new_memory->name; design->select(module, new_memory); @@ -127,7 +128,7 @@ struct FlattenWorker RTLIL::Wire *new_wire = nullptr; if (tpl_wire->name[0] == '\\') { - RTLIL::Wire *hier_wire = module->wire(concat_name(cell, tpl_wire->name)); + RTLIL::Wire *hier_wire = module->wire(concat_name(cell, tpl_wire->name, separator)); if (hier_wire != nullptr && hier_wire->get_bool_attribute(ID::hierconn)) { hier_wire->attributes.erase(ID::hierconn); if (GetSize(hier_wire) < GetSize(tpl_wire)) { @@ -139,7 +140,7 @@ struct FlattenWorker } } if (new_wire == nullptr) { - new_wire = module->addWire(map_name(cell, tpl_wire), tpl_wire); + new_wire = module->addWire(map_name(cell, tpl_wire, separator), tpl_wire); new_wire->port_input = new_wire->port_output = false; new_wire->port_id = false; } @@ -150,7 +151,7 @@ struct FlattenWorker } for (auto &tpl_proc_it : tpl->processes) { - RTLIL::Process *new_proc = module->addProcess(map_name(cell, tpl_proc_it.second), tpl_proc_it.second); + RTLIL::Process *new_proc = module->addProcess(map_name(cell, tpl_proc_it.second, separator), tpl_proc_it.second); map_attributes(cell, new_proc, tpl_proc_it.second->name); for (auto new_proc_sync : new_proc->syncs) for (auto &memwr_action : new_proc_sync->mem_write_actions) @@ -161,14 +162,14 @@ struct FlattenWorker } for (auto tpl_cell : tpl->cells()) { - RTLIL::Cell *new_cell = module->addCell(map_name(cell, tpl_cell), tpl_cell); + RTLIL::Cell *new_cell = module->addCell(map_name(cell, tpl_cell, separator), tpl_cell); map_attributes(cell, new_cell, tpl_cell->name); if (new_cell->has_memid()) { IdString memid = new_cell->getParam(ID::MEMID).decode_string(); new_cell->setParam(ID::MEMID, Const(memory_map.at(memid).str())); } else if (new_cell->is_mem_cell()) { IdString memid = new_cell->getParam(ID::MEMID).decode_string(); - new_cell->setParam(ID::MEMID, Const(concat_name(cell, memid).str())); + new_cell->setParam(ID::MEMID, Const(concat_name(cell, memid, separator).str())); } auto rewriter = [&](RTLIL::SigSpec &sig) { map_sigspec(wire_map, sig); }; new_cell->rewrite_sigspecs(rewriter); @@ -279,7 +280,7 @@ struct FlattenWorker module->rename(scopeinfo, cell_name); } - void flatten_module(RTLIL::Design *design, RTLIL::Module *module, pool &used_modules) + void flatten_module(RTLIL::Design *design, RTLIL::Module *module, pool &used_modules, const std::string &separator) { if (!design->selected(module) || module->get_blackbox_attribute(ignore_wb)) return; @@ -308,7 +309,7 @@ struct FlattenWorker // 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. - flatten_cell(design, module, cell, tpl, sigmap, worklist); + flatten_cell(design, module, cell, tpl, sigmap, worklist, separator); } } }; @@ -345,6 +346,9 @@ struct FlattenPass : public Pass { log(" with a public name the enclosing scope can be found via their\n"); log(" 'hdlname' attribute.\n"); log("\n"); + log(" -separator \n"); + log(" Use this separator char instead of '.' when concatenating design levels.\n"); + log("\n"); } void execute(std::vector args, RTLIL::Design *design) override { @@ -367,6 +371,10 @@ struct FlattenPass : public Pass { worker.create_scopename = true; continue; } + if (args[argidx] == "-separator" && argidx + 1 < args.size()) { + worker.separator = args[++argidx]; + continue; + } break; } extra_args(args, argidx, design); @@ -401,7 +409,7 @@ struct FlattenPass : public Pass { log_error("Cannot flatten a design containing recursive instantiations.\n"); for (auto module : topo_modules.sorted) - worker.flatten_module(design, module, used_modules); + worker.flatten_module(design, module, used_modules, worker.separator); if (top != nullptr) for (auto module : design->modules().to_vector()) From 27be9a6b77fb59bfd2b8f63961572ec1d25fd67a Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Fri, 10 Jan 2025 14:03:09 -0800 Subject: [PATCH 8/9] keep_hierarchy.cc: use strictly correct syntax for printf of uint64_t values Removes two warnings from the compile, at least on amd64 arch --- passes/hierarchy/keep_hierarchy.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/passes/hierarchy/keep_hierarchy.cc b/passes/hierarchy/keep_hierarchy.cc index bfae9fa38..9d77b5239 100644 --- a/passes/hierarchy/keep_hierarchy.cc +++ b/passes/hierarchy/keep_hierarchy.cc @@ -17,6 +17,7 @@ * */ +#include #include "kernel/yosys.h" #include "kernel/cost.h" @@ -66,7 +67,7 @@ struct ThresholdHierarchyKeeping { } if (size > threshold) { - log("Keeping %s (estimated size above threshold: %llu > %llu).\n", log_id(module), size, threshold); + log("Keeping %s (estimated size above threshold: %" PRIu64 " > %" PRIu64 ").\n", log_id(module), size, threshold); module->set_bool_attribute(ID::keep_hierarchy); size = 0; } From 502c39b875f788bae422047fbbc06f2ef5fc17f0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 11 Jan 2025 00:21:05 +0000 Subject: [PATCH 9/9] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 195404e1d..90b33970a 100644 --- a/Makefile +++ b/Makefile @@ -153,7 +153,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.48+62 +YOSYS_VER := 0.48+70 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo