From 23c9828d7015ba9811e1dba08e2194fdf58e9497 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Tue, 9 Jan 2024 12:05:15 +0100 Subject: [PATCH 01/76] opt_clean: Remove dead branch --- passes/opt/opt_clean.cc | 7 ------- 1 file changed, 7 deletions(-) diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 8b56895fef5..19056e7e19b 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -436,13 +436,6 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos if (!raw_used_signals.check_any(s1)) { // delete wires that aren't used by anything directly goto delete_this_wire; - } else - if (!used_signals.check_any(s2)) { - // this path shouldn't be possible: this wire is used directly (otherwise it would get cleaned up above), and indirectly - // used wires are a superset of those used directly - log_assert(false); - // delete wires that aren't used by anything indirectly, even though other wires may alias it - goto delete_this_wire; } if (0) From 158fbf881e0ba514e659e0e948491b045eab9f61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Wed, 6 Mar 2024 15:15:37 +0100 Subject: [PATCH 02/76] memory_map: Explain `-iattr` better --- passes/memory/memory_map.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index cafc0aaf3e0..d1dd0fd882d 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -415,7 +415,7 @@ struct MemoryMapPass : public Pass { log(" to any of the values.\n"); log("\n"); log(" -iattr\n"); - log(" for -attr, ignore case of .\n"); + log(" for -attr, suppress case sensitivity in matching of .\n"); log("\n"); log(" -rom-only\n"); log(" only perform conversion for ROMs (memories with no write ports).\n"); From 56f66596b05251a625de3f8f3cae81efd3d6e482 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 8 Mar 2024 11:09:03 +1300 Subject: [PATCH 03/76] Change default CONFIG to none - Use default value of `CXX` instead of forcing override to `clang++`. - Add base `CXXFLAGS` and `ABCMKARGS` in else condition of `ifeq ($(CONFIG),..)` block and output the value of `CXX`. - Change readme to mention `CXX` envvar and that using `make config-clang` etc will ignore `CXX`. --- Makefile | 7 ++++++- README.md | 8 +++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 81715ded523..62a17168036 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ -CONFIG := clang +CONFIG := none +# CONFIG := clang # CONFIG := gcc # CONFIG := afl-gcc # CONFIG := emcc @@ -362,6 +363,10 @@ EXE = .exe else ifneq ($(CONFIG),none) $(error Invalid CONFIG setting '$(CONFIG)'. Valid values: clang, gcc, emcc, mxe, msys2-32, msys2-64) +else +$(info Using provided C++ compiler, '$(CXX)'.) +CXXFLAGS += -std=$(CXXSTD) -Os +ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H $(ABC_ARCHFLAGS)" endif ifeq ($(ENABLE_LIBYOSYS),1) diff --git a/README.md b/README.md index 660bd5c6d57..d3aea85345d 100644 --- a/README.md +++ b/README.md @@ -105,11 +105,17 @@ For Cygwin use the following command to install all prerequisites, or select the setup-x86_64.exe -q --packages=bison,flex,gcc-core,gcc-g++,git,libffi-devel,libreadline-devel,make,pkg-config,python3,tcl-devel,boost-build,zlib-devel -To configure the build system to use a specific compiler, use one of +The environment variable `CXX` can be used to control the C++ compiler used, or +run one of the following: $ make config-clang $ make config-gcc +Note that these will result in `make` ignoring the `CXX` environment variable, +unless `CXX` is assigned in the call to make, e.g. + + $ make CXX=$CXX + For other compilers and build configurations it might be necessary to make some changes to the config section of the Makefile. From 344ca1823949ece8bc8de3987fd160e08465d839 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 8 Mar 2024 18:08:19 +1300 Subject: [PATCH 04/76] Makefile: Move CXX print to echo-cxx --- Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 62a17168036..8e26d7db0da 100644 --- a/Makefile +++ b/Makefile @@ -364,7 +364,6 @@ EXE = .exe else ifneq ($(CONFIG),none) $(error Invalid CONFIG setting '$(CONFIG)'. Valid values: clang, gcc, emcc, mxe, msys2-32, msys2-64) else -$(info Using provided C++ compiler, '$(CXX)'.) CXXFLAGS += -std=$(CXXSTD) -Os ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H $(ABC_ARCHFLAGS)" endif @@ -1121,6 +1120,9 @@ echo-git-rev: echo-abc-rev: @echo "$(ABCREV)" +echo-cxx: + @echo "$(CXX)" + -include libs/*/*.d -include frontends/*/*.d -include passes/*/*.d From 6e5f40e36497ebcbf1769122e39278508fc13e84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Thu, 1 Feb 2024 10:37:30 +0100 Subject: [PATCH 05/76] utils: Save detected loops with their nodes in-order --- kernel/utils.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/utils.h b/kernel/utils.h index 8fa223824da..3216c5eb5f0 100644 --- a/kernel/utils.h +++ b/kernel/utils.h @@ -149,7 +149,7 @@ template , typename OPS = hash_ops> cla std::map node_to_index; std::vector> edges; std::vector sorted; - std::set> loops; + std::set> loops; TopoSort() : indirect_cmp(nodes) { @@ -220,10 +220,10 @@ template , typename OPS = hash_ops> cla if (active_cells[root_index]) { found_loops = true; if (analyze_loops) { - std::set loop; + std::vector loop; for (int i = GetSize(active_stack) - 1; i >= 0; i--) { const int index = active_stack[i]; - loop.insert(nodes[index]); + loop.push_back(nodes[index]); if (index == root_index) break; } From c5ae74af34e23ab126ca9a8781e1211fabd34c39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Thu, 1 Feb 2024 10:40:45 +0100 Subject: [PATCH 06/76] check: Improve found loop logging Print the detected loop in-order, and include source location for each node, if available. --- passes/cmds/check.cc | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc index d1c83f04d88..c3e775a387a 100644 --- a/passes/cmds/check.cc +++ b/passes/cmds/check.cc @@ -104,8 +104,7 @@ struct CheckPass : public Pass { dict> wire_drivers; dict wire_drivers_count; pool used_wires; - TopoSort topo; - + TopoSort> topo; for (auto &proc_it : module->processes) { std::vector all_cases = {&proc_it.second->root_case}; @@ -164,16 +163,16 @@ struct CheckPass : public Pass { if (cell->input(conn.first)) for (auto bit : sig) if (bit.wire) { - if (logic_cell) - topo.edge(stringf("wire %s", log_signal(bit)), - stringf("cell %s (%s)", log_id(cell), log_id(cell->type))); + if (logic_cell && bit.wire) + topo.edge(std::make_pair(bit.wire->name, bit.offset), + std::make_pair(cell->name, -1)); used_wires.insert(bit); } if (cell->output(conn.first)) for (int i = 0; i < GetSize(sig); i++) { - if (logic_cell) - topo.edge(stringf("cell %s (%s)", log_id(cell), log_id(cell->type)), - stringf("wire %s", log_signal(sig[i]))); + if (logic_cell && sig[i].wire) + topo.edge(std::make_pair(cell->name, -1), + std::make_pair(sig[i].wire->name, sig[i].offset)); if (sig[i].wire || !cell->input(conn.first)) wire_drivers[sig[i]].push_back(stringf("port %s[%d] of cell %s (%s)", @@ -239,8 +238,28 @@ struct CheckPass : public Pass { topo.sort(); for (auto &loop : topo.loops) { string message = stringf("found logic loop in module %s:\n", log_id(module)); - for (auto &str : loop) - message += stringf(" %s\n", str.c_str()); + for (auto &pair : loop) { + RTLIL::AttrObject *obj; + if (pair.second == -1) + obj = module->cell(pair.first); + else + obj = module->wire(pair.first); + log_assert(obj); + std::string src; + if (obj->has_attribute(ID::src)) { + std::string src_attr = obj->get_src_attribute(); + src = stringf(" source: %s", src_attr.c_str()); + } + if (pair.second == -1) { + Cell *cell = module->cell(pair.first); + log_assert(cell); + message += stringf(" cell %s (%s)%s\n", log_id(cell), log_id(cell->type), src.c_str()); + } else { + Wire *wire = module->wire(pair.first); + log_assert(wire); + message += stringf(" wire %s%s\n", log_signal(SigBit(wire, pair.second)), src.c_str()); + } + } log_warning("%s", message.c_str()); counter++; } From fa74d0bd1a070a007292cc260b49f183f00ebfd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 5 Feb 2024 14:44:55 +0100 Subject: [PATCH 07/76] check: Use cell edges data in detecting combinational loops --- passes/cmds/check.cc | 159 ++++++++++++++++++++++++++++++++----------- 1 file changed, 120 insertions(+), 39 deletions(-) diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc index c3e775a387a..9f70dbdc7c8 100644 --- a/passes/cmds/check.cc +++ b/passes/cmds/check.cc @@ -19,6 +19,7 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" +#include "kernel/celledges.h" #include "kernel/celltypes.h" #include "kernel/utils.h" @@ -102,6 +103,7 @@ struct CheckPass : public Pass { SigMap sigmap(module); dict> wire_drivers; + dict driver_cells; dict wire_drivers_count; pool used_wires; TopoSort> topo; @@ -149,6 +151,46 @@ struct CheckPass : public Pass { } } + struct CircuitEdgesDatabase : AbstractCellEdgesDatabase { + TopoSort> &topo; + SigMap sigmap; + + CircuitEdgesDatabase(TopoSort> &topo, SigMap &sigmap) + : topo(topo), sigmap(sigmap) {} + + void add_edge(RTLIL::Cell *cell, RTLIL::IdString from_port, int from_bit, + RTLIL::IdString to_port, int to_bit, int) override { + SigBit from = sigmap(cell->getPort(from_port))[from_bit]; + SigBit to = sigmap(cell->getPort(to_port))[to_bit]; + + if (from.wire && to.wire) + topo.edge(std::make_pair(from.wire->name, from.offset), std::make_pair(to.wire->name, to.offset)); + } + + bool add_edges_from_cell(Cell *cell) { + if (AbstractCellEdgesDatabase::add_edges_from_cell(cell)) + return true; + + // We don't have accurate cell edges, do the fallback of all input-output pairs + for (auto &conn : cell->connections()) { + if (cell->input(conn.first)) + for (auto bit : sigmap(conn.second)) + if (bit.wire) + topo.edge(std::make_pair(bit.wire->name, bit.offset), + std::make_pair(cell->name, -1)); + + if (cell->output(conn.first)) + for (auto bit : sigmap(conn.second)) + if (bit.wire) + topo.edge(std::make_pair(cell->name, -1), + std::make_pair(bit.wire->name, bit.offset)); + } + return true; + } + }; + + CircuitEdgesDatabase edges_db(topo, sigmap); + for (auto cell : module->cells()) { if (mapped && cell->type.begins_with("$") && design->module(cell->type) == nullptr) { @@ -157,31 +199,29 @@ struct CheckPass : public Pass { counter++; cell_allowed:; } + for (auto &conn : cell->connections()) { + bool input = cell->input(conn.first); + bool output = cell->output(conn.first); + SigSpec sig = sigmap(conn.second); - bool logic_cell = yosys_celltypes.cell_evaluable(cell->type); - if (cell->input(conn.first)) - for (auto bit : sig) - if (bit.wire) { - if (logic_cell && bit.wire) - topo.edge(std::make_pair(bit.wire->name, bit.offset), - std::make_pair(cell->name, -1)); - used_wires.insert(bit); - } - if (cell->output(conn.first)) - for (int i = 0; i < GetSize(sig); i++) { - if (logic_cell && sig[i].wire) - topo.edge(std::make_pair(cell->name, -1), - std::make_pair(sig[i].wire->name, sig[i].offset)); - - if (sig[i].wire || !cell->input(conn.first)) - wire_drivers[sig[i]].push_back(stringf("port %s[%d] of cell %s (%s)", - log_id(conn.first), i, log_id(cell), log_id(cell->type))); - } - if (!cell->input(conn.first) && cell->output(conn.first)) - for (auto bit : sig) - if (bit.wire) wire_drivers_count[bit]++; + for (int i = 0; i < sig.size(); i++) { + SigBit bit = sig[i]; + + if (input && bit.wire) + used_wires.insert(bit); + if (output && !input && bit.wire) + 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))); + if (output) + driver_cells[bit] = cell; + } } + + if (yosys_celltypes.cell_evaluable(cell->type)) + edges_db.add_edges_from_cell(cell); } pool init_bits; @@ -238,27 +278,68 @@ struct CheckPass : public Pass { topo.sort(); for (auto &loop : topo.loops) { string message = stringf("found logic loop in module %s:\n", log_id(module)); + + // `loop` only contains wire bits, or an occassional special helper node for cells for + // which we have done the edges fallback. The cell and its ports that led to an edge is + // an information we need to recover now. For that we need to have the previous wire bit + // of the loop at hand. + SigBit prev; + for (auto it = loop.rbegin(); it != loop.rend(); it++) + if (it->second != -1) { // skip the fallback helper nodes + prev = SigBit(module->wire(it->first), it->second); + break; + } + log_assert(prev != SigBit()); + for (auto &pair : loop) { - RTLIL::AttrObject *obj; if (pair.second == -1) - obj = module->cell(pair.first); - else - obj = module->wire(pair.first); - log_assert(obj); - std::string src; - if (obj->has_attribute(ID::src)) { - std::string src_attr = obj->get_src_attribute(); - src = stringf(" source: %s", src_attr.c_str()); + continue; // helper node for edges fallback, we can ignore it + + struct MatchingEdgePrinter : AbstractCellEdgesDatabase { + std::string &message; + SigMap &sigmap; + SigBit from, to; + int nhits; + const int HITS_LIMIT = 3; + + MatchingEdgePrinter(std::string &message, SigMap &sigmap, SigBit from, SigBit to) + : message(message), sigmap(sigmap), from(from), to(to), nhits(0) {} + + void add_edge(RTLIL::Cell *cell, RTLIL::IdString from_port, int from_bit, + RTLIL::IdString to_port, int to_bit, int) override { + SigBit edge_from = sigmap(cell->getPort(from_port))[from_bit]; + 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); + if (nhits == HITS_LIMIT) + message += " ...\n"; + } + }; + + Wire *wire = module->wire(pair.first); + log_assert(wire); + SigBit bit(module->wire(pair.first), pair.second); + log_assert(driver_cells.count(bit)); + Cell *driver = driver_cells.at(bit); + + std::string driver_src; + if (driver->has_attribute(ID::src)) { + std::string src_attr = driver->get_src_attribute(); + driver_src = stringf(" source: %s", src_attr.c_str()); } - if (pair.second == -1) { - Cell *cell = module->cell(pair.first); - log_assert(cell); - message += stringf(" cell %s (%s)%s\n", log_id(cell), log_id(cell->type), src.c_str()); - } else { - Wire *wire = module->wire(pair.first); - log_assert(wire); - message += stringf(" wire %s%s\n", log_signal(SigBit(wire, pair.second)), src.c_str()); + message += stringf(" cell %s (%s)%s\n", log_id(driver), log_id(driver->type), driver_src.c_str()); + MatchingEdgePrinter printer(message, sigmap, prev, bit); + printer.add_edges_from_cell(driver); + + std::string wire_src; + if (wire->has_attribute(ID::src)) { + std::string src_attr = wire->get_src_attribute(); + wire_src = stringf(" source: %s", src_attr.c_str()); } + message += stringf(" wire %s%s\n", log_signal(SigBit(wire, pair.second)), wire_src.c_str()); + prev = bit; } log_warning("%s", message.c_str()); counter++; From 3eef6450f10b672c95864b1e35409febfd501ccd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 5 Feb 2024 14:46:12 +0100 Subject: [PATCH 08/76] check: Add coarse-grain false positive test --- tests/various/check.ys | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 tests/various/check.ys diff --git a/tests/various/check.ys b/tests/various/check.ys new file mode 100644 index 00000000000..cdc944ed371 --- /dev/null +++ b/tests/various/check.ys @@ -0,0 +1,12 @@ +design -reset +read_verilog < Date: Mon, 12 Feb 2024 11:09:24 +0100 Subject: [PATCH 09/76] celledges: Describe asynchronous read ports --- kernel/celledges.cc | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/kernel/celledges.cc b/kernel/celledges.cc index 2ed0d503605..598d7d8060e 100644 --- a/kernel/celledges.cc +++ b/kernel/celledges.cc @@ -307,6 +307,40 @@ void shift_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) } } +void packed_mem_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) +{ + log_assert(cell->type == ID($mem_v2)); + Const rd_clk_enable = cell->getParam(ID::RD_CLK_ENABLE); + int n_rd_ports = cell->getParam(ID::RD_PORTS).as_int(); + int abits = cell->getParam(ID::ABITS).as_int(); + int width = cell->getParam(ID::WIDTH).as_int(); + + for (int i = 0; i < n_rd_ports; i++) { + if (rd_clk_enable[i] != State::S0) + continue; + + for (int j = 0; j < abits; j++) + for (int k = 0; k < width; k++) + db->add_edge(cell, ID::RD_ADDR, i * abits + j, + ID::RD_DATA, i * width + k, -1); + } +} + +void memrd_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) +{ + log_assert(cell->type.in(ID($memrd), ID($memrd_v2))); + + if (cell->getParam(ID::CLK_ENABLE).as_bool()) + return; + + int abits = cell->getParam(ID::ABITS).as_int(); + int width = cell->getParam(ID::WIDTH).as_int(); + + for (int j = 0; j < abits; j++) + for (int k = 0; k < width; k++) + db->add_edge(cell, ID::ADDR, j, ID::DATA, k, -1); +} + PRIVATE_NAMESPACE_END bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL::Cell *cell) @@ -361,6 +395,16 @@ bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL return true; } + if (cell->type == ID($mem_v2)) { + packed_mem_op(this, cell); + return true; + } + + if (cell->type.in(ID($memrd), ID($memrd_v2))) { + memrd_op(this, cell); + return true; + } + // FIXME: $mul $div $mod $divfloor $modfloor $pow $slice $concat $bweqx // FIXME: $lut $sop $alu $lcu $macc $fa $logic_and $logic_or $bwmux From b6112b3551d75f87da8a61e7ee482e6f4b840d0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 12 Feb 2024 11:10:41 +0100 Subject: [PATCH 10/76] check: Consider read ports in loop detection --- passes/cmds/check.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc index 9f70dbdc7c8..070a3fb9d73 100644 --- a/passes/cmds/check.cc +++ b/passes/cmds/check.cc @@ -220,7 +220,7 @@ struct CheckPass : public Pass { } } - if (yosys_celltypes.cell_evaluable(cell->type)) + if (yosys_celltypes.cell_evaluable(cell->type) || cell->type.in(ID($mem_v2), ID($memrd), ID($memrd_v2))) edges_db.add_edges_from_cell(cell); } From e1e77a7fa9cad776975b4f00e94823e078a83824 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 12 Feb 2024 12:32:15 +0100 Subject: [PATCH 11/76] check: Extend testing --- tests/various/check.ys | 33 ++++++++++++++++++++++++++++++++- tests/various/check_2.ys | 17 +++++++++++++++++ tests/various/check_3.ys | 20 ++++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 tests/various/check_2.ys create mode 100644 tests/various/check_3.ys diff --git a/tests/various/check.ys b/tests/various/check.ys index cdc944ed371..41b9960911f 100644 --- a/tests/various/check.ys +++ b/tests/various/check.ys @@ -1,5 +1,5 @@ design -reset -read_verilog < Date: Mon, 12 Feb 2024 12:32:50 +0100 Subject: [PATCH 12/76] check: Assert edges data is not out-of-bounds --- passes/cmds/check.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc index 070a3fb9d73..bb169b4f965 100644 --- a/passes/cmds/check.cc +++ b/passes/cmds/check.cc @@ -160,8 +160,12 @@ struct CheckPass : public Pass { void add_edge(RTLIL::Cell *cell, RTLIL::IdString from_port, int from_bit, RTLIL::IdString to_port, int to_bit, int) override { - SigBit from = sigmap(cell->getPort(from_port))[from_bit]; - SigBit to = sigmap(cell->getPort(to_port))[to_bit]; + SigSpec from_portsig = cell->getPort(from_port); + SigSpec to_portsig = cell->getPort(to_port); + log_assert(from_bit >= 0 && from_bit < from_portsig.size()); + log_assert(to_bit >= 0 && to_bit < to_portsig.size()); + SigBit from = sigmap(from_portsig[from_bit]); + SigBit to = sigmap(to_portsig[to_bit]); if (from.wire && to.wire) topo.edge(std::make_pair(from.wire->name, from.offset), std::make_pair(to.wire->name, to.offset)); From e4296072c42f3812588f78f76aa9aa035ad08f26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 12 Feb 2024 15:09:52 +0100 Subject: [PATCH 13/76] check: Rephrase regex for portability --- tests/various/check_3.ys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/various/check_3.ys b/tests/various/check_3.ys index 53c6fbab2ba..14915ab8d4d 100644 --- a/tests/various/check_3.ys +++ b/tests/various/check_3.ys @@ -16,5 +16,5 @@ EOF hierarchy -top pingpong prep logger -nowarn "found logic loop in module pingpong:" -logger -expect error "Found \d+ problems in 'check -assert'" 1 +logger -expect error "Found [0-9]+ problems in 'check -assert'" 1 check -assert From 4a10e78777a65c3fc18ffcba6e01bf5a62df81c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Fri, 23 Feb 2024 10:44:41 +0100 Subject: [PATCH 14/76] celledges: Emit empty edges for write/init ports --- kernel/celledges.cc | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/kernel/celledges.cc b/kernel/celledges.cc index 598d7d8060e..48475cfdd7a 100644 --- a/kernel/celledges.cc +++ b/kernel/celledges.cc @@ -341,6 +341,18 @@ void memrd_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) db->add_edge(cell, ID::ADDR, j, ID::DATA, k, -1); } +void mem_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) +{ + if (cell->type == ID($mem_v2)) + packed_mem_op(db, cell); + else if (cell->type.in(ID($memrd), ID($memrd_v2))) + memrd_op(db, cell); + else if (cell->type.in(ID($memwr), ID($memwr_v2), ID($meminit))) + return; /* no edges here */ + else + log_abort(); +} + PRIVATE_NAMESPACE_END bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL::Cell *cell) @@ -395,13 +407,8 @@ bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL return true; } - if (cell->type == ID($mem_v2)) { - packed_mem_op(this, cell); - return true; - } - - if (cell->type.in(ID($memrd), ID($memrd_v2))) { - memrd_op(this, cell); + if (cell->type.in(ID($mem_v2), ID($memrd), ID($memrd_v2), ID($memwr), ID($memwr_v2), ID($meminit))) { + mem_op(this, cell); return true; } From 87e72ef86fcd40865b944b5ea65575be1602faf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Fri, 23 Feb 2024 10:58:32 +0100 Subject: [PATCH 15/76] celledges: Add read ports arst paths --- kernel/celledges.cc | 17 ++++++++++++----- tests/various/check_4.ys | 29 +++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 tests/various/check_4.ys diff --git a/kernel/celledges.cc b/kernel/celledges.cc index 48475cfdd7a..1dbe3fd42bc 100644 --- a/kernel/celledges.cc +++ b/kernel/celledges.cc @@ -316,8 +316,11 @@ void packed_mem_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) int width = cell->getParam(ID::WIDTH).as_int(); for (int i = 0; i < n_rd_ports; i++) { - if (rd_clk_enable[i] != State::S0) + if (rd_clk_enable[i] != State::S0) { + for (int k = 0; k < width; k++) + db->add_edge(cell, ID::RD_ARST, i, ID::RD_DATA, i * width + k, -1); continue; + } for (int j = 0; j < abits; j++) for (int k = 0; k < width; k++) @@ -329,13 +332,17 @@ void packed_mem_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) void memrd_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) { log_assert(cell->type.in(ID($memrd), ID($memrd_v2))); - - if (cell->getParam(ID::CLK_ENABLE).as_bool()) - return; - int abits = cell->getParam(ID::ABITS).as_int(); int width = cell->getParam(ID::WIDTH).as_int(); + if (cell->getParam(ID::CLK_ENABLE).as_bool()) { + if (cell->type == ID($memrd_v2)) { + for (int k = 0; k < width; k++) + db->add_edge(cell, ID::ARST, 0, ID::DATA, k, -1); + } + return; + } + for (int j = 0; j < abits; j++) for (int k = 0; k < width; k++) db->add_edge(cell, ID::ADDR, j, ID::DATA, k, -1); diff --git a/tests/various/check_4.ys b/tests/various/check_4.ys new file mode 100644 index 00000000000..010cd01fd53 --- /dev/null +++ b/tests/various/check_4.ys @@ -0,0 +1,29 @@ +# loop involving the asynchronous reset on a memory port +design -reset +read -vlog2k < Date: Fri, 23 Feb 2024 11:41:03 +0100 Subject: [PATCH 16/76] celledges: Register async FF paths --- kernel/celledges.cc | 35 +++++++++++++++++++++++++++++++++++ passes/cmds/check.cc | 3 ++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/kernel/celledges.cc b/kernel/celledges.cc index 1dbe3fd42bc..09cdfd55b96 100644 --- a/kernel/celledges.cc +++ b/kernel/celledges.cc @@ -360,6 +360,34 @@ void mem_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) log_abort(); } +void ff_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) +{ + int width = cell->getPort(ID::Q).size(); + + if (cell->type.in(ID($dlatch), ID($adlatch), ID($dlatchsr))) { + for (int k = 0; k < width; k++) { + db->add_edge(cell, ID::D, k, ID::Q, k, -1); + db->add_edge(cell, ID::EN, 0, ID::Q, k, -1); + } + } + + if (cell->hasPort(ID::CLR)) + for (int k = 0; k < width; k++) + db->add_edge(cell, ID::CLR, 0, ID::Q, k, -1); + if (cell->hasPort(ID::SET)) + for (int k = 0; k < width; k++) + db->add_edge(cell, ID::SET, 0, ID::Q, k, -1); + if (cell->hasPort(ID::ALOAD)) + for (int k = 0; k < width; k++) + db->add_edge(cell, ID::ALOAD, 0, ID::Q, k, -1); + if (cell->hasPort(ID::AD)) + for (int k = 0; k < width; k++) + db->add_edge(cell, ID::AD, k, ID::Q, k, -1); + if (cell->hasPort(ID::ARST)) + for (int k = 0; k < width; k++) + db->add_edge(cell, ID::ARST, 0, ID::Q, k, -1); +} + PRIVATE_NAMESPACE_END bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL::Cell *cell) @@ -419,6 +447,13 @@ bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL return true; } + if (RTLIL::builtin_ff_cell_types().count(cell->type)) { + ff_op(this, cell); + return true; + } + + // FIXME: $mul $div $mod $divfloor $modfloor $slice $concat + // FIXME: $lut $sop $alu $lcu $macc $fa // FIXME: $mul $div $mod $divfloor $modfloor $pow $slice $concat $bweqx // FIXME: $lut $sop $alu $lcu $macc $fa $logic_and $logic_or $bwmux diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc index bb169b4f965..23e4e7c927c 100644 --- a/passes/cmds/check.cc +++ b/passes/cmds/check.cc @@ -224,7 +224,8 @@ struct CheckPass : public Pass { } } - if (yosys_celltypes.cell_evaluable(cell->type) || cell->type.in(ID($mem_v2), ID($memrd), ID($memrd_v2))) + if (yosys_celltypes.cell_evaluable(cell->type) || cell->type.in(ID($mem_v2), ID($memrd), ID($memrd_v2)) \ + || RTLIL::builtin_ff_cell_types().count(cell->type)) edges_db.add_edges_from_cell(cell); } From 5924d97381c95b6ed94ab2767504edb32c870c1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Tue, 27 Feb 2024 12:37:46 +0100 Subject: [PATCH 17/76] tests: Remove part of test involving combinational loops --- tests/opt/opt_dff_qd.ys | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/tests/opt/opt_dff_qd.ys b/tests/opt/opt_dff_qd.ys index 7b0b4c2242a..c6232643f1f 100644 --- a/tests/opt/opt_dff_qd.ys +++ b/tests/opt/opt_dff_qd.ys @@ -7,7 +7,7 @@ module top(...); input CLK; input EN; (* init = 24'h555555 *) -output [19:0] Q; +output [17:0] Q; input SRST; input ARST; input [1:0] CLR; @@ -23,26 +23,20 @@ $sdffce #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_V $dffsr #(.CLK_POLARITY(1'b1), .CLR_POLARITY(1'b1), .SET_POLARITY(1'b0), .WIDTH(2)) ff7 (.CLK(CLK), .SET(SET), .CLR(CLR), .D(Q[15:14]), .Q(Q[15:14])); $dffsre #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b0), .CLR_POLARITY(1'b1), .SET_POLARITY(1'b0), .WIDTH(2)) ff8 (.CLK(CLK), .EN(EN), .SET(SET), .CLR(CLR), .D(Q[17:16]), .Q(Q[17:16])); -$dlatch #(.EN_POLARITY(1'b1), .WIDTH(2)) ff9 (.EN(EN), .D(Q[19:18]), .Q(Q[19:18])); -$adlatch #(.EN_POLARITY(1'b0), .ARST_POLARITY(1'b1), .ARST_VALUE(2'h2), .WIDTH(2)) ff10 (.EN(EN), .ARST(ARST), .D(Q[21:20]), .Q(Q[21:20])); -$dlatchsr #(.EN_POLARITY(1'b0), .CLR_POLARITY(1'b1), .SET_POLARITY(1'b0), .WIDTH(2)) ff11 (.EN(EN), .SET(SET), .CLR(CLR), .D(Q[23:22]), .Q(Q[23:22])); - endmodule EOT design -save orig -# Equivalence check will fail for unmapped adlatch and dlatchsr due to negative hold hack. -delete top/ff10 top/ff11 equiv_opt -undef -assert -multiclock opt_dff -keepdc design -load orig opt_dff -keepdc select -assert-count 1 t:$and select -assert-count 3 t:$dffe -select -assert-count 3 t:$dlatch -select -assert-count 3 t:$sr +select -assert-count 2 t:$dlatch +select -assert-count 2 t:$sr select -assert-none t:$and t:$dffe t:$dlatch t:$sr %% %n t:* %i design -load orig @@ -50,7 +44,7 @@ simplemap opt_dff -keepdc select -assert-count 2 t:$_AND_ select -assert-count 6 t:$_DFFE_??_ -select -assert-count 6 t:$_DLATCH_?_ -select -assert-count 6 t:$_SR_??_ +select -assert-count 4 t:$_DLATCH_?_ +select -assert-count 4 t:$_SR_??_ select -assert-none t:$_AND_ t:$_DFFE_??_ t:$_DLATCH_?_ t:$_SR_??_ %% %n t:* %i From 206d894c56620948670201ec6ff5848b73dfd927 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 4 Mar 2024 11:47:01 +0100 Subject: [PATCH 18/76] check: Omit private wires in loop report --- passes/cmds/check.cc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc index 23e4e7c927c..255c32fbad9 100644 --- a/passes/cmds/check.cc +++ b/passes/cmds/check.cc @@ -338,12 +338,15 @@ struct CheckPass : public Pass { MatchingEdgePrinter printer(message, sigmap, prev, bit); printer.add_edges_from_cell(driver); - std::string wire_src; - if (wire->has_attribute(ID::src)) { - std::string src_attr = wire->get_src_attribute(); - wire_src = stringf(" source: %s", src_attr.c_str()); + if (wire->name.isPublic()) { + std::string wire_src; + if (wire->has_attribute(ID::src)) { + std::string src_attr = wire->get_src_attribute(); + wire_src = stringf(" source: %s", src_attr.c_str()); + } + message += stringf(" wire %s%s\n", log_signal(SigBit(wire, pair.second)), wire_src.c_str()); } - message += stringf(" wire %s%s\n", log_signal(SigBit(wire, pair.second)), wire_src.c_str()); + prev = bit; } log_warning("%s", message.c_str()); From e0389436da92dfb4c3e14a6c69d811d2ae0a1eb2 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 12 Mar 2024 09:18:38 +1300 Subject: [PATCH 19/76] Makefile: Remove narrowing from ABCMKARGS --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 8e26d7db0da..d8d74fd4967 100644 --- a/Makefile +++ b/Makefile @@ -218,7 +218,7 @@ endif ifeq ($(CONFIG),clang) CXX = clang++ CXXFLAGS += -std=$(CXXSTD) -Os -ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -Wno-c++11-narrowing $(ABC_ARCHFLAGS)" +ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H $(ABC_ARCHFLAGS)" ifneq ($(SANITIZER),) $(info [Clang Sanitizer] $(SANITIZER)) @@ -266,7 +266,7 @@ ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H" else ifeq ($(CONFIG),emcc) CXX = emcc CXXFLAGS := -std=$(CXXSTD) $(filter-out -fPIC -ggdb,$(CXXFLAGS)) -ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DABC_MEMALIGN=8 -Wno-c++11-narrowing" +ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DABC_MEMALIGN=8" EMCC_CXXFLAGS := -Os -Wno-warn-absolute-paths EMCC_LINKFLAGS := --embed-file share EMCC_LINKFLAGS += -s NO_EXIT_RUNTIME=1 @@ -318,7 +318,7 @@ CXXFLAGS := $(WASIFLAGS) -std=$(CXXSTD) -Os -D_WASI_EMULATED_PROCESS_CLOCKS $(fi LINKFLAGS := $(WASIFLAGS) -Wl,-z,stack-size=1048576 $(filter-out -rdynamic,$(LINKFLAGS)) 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 -Wno-c++11-narrowing" +ABCMKARGS += ARCHFLAGS="$(WASIFLAGS) -D_WASI_EMULATED_PROCESS_CLOCKS -DABC_USE_STDINT_H -DABC_NO_DYNAMIC_LINKING -DABC_NO_RLIMIT" ABCMKARGS += OPTFLAGS="-Os" EXE = .wasm From 643c9540da774c9fcf1daf016df9555dac2cd32d Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 12 Mar 2024 09:39:25 +1300 Subject: [PATCH 20/76] Makefile: reorder CONFIG=none check --- Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index d8d74fd4967..7104bfc4d97 100644 --- a/Makefile +++ b/Makefile @@ -361,11 +361,12 @@ ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DWIN32_NO_DLL -DHAVE_STRUCT_TIMESPEC ABCMKARGS += LIBS="-lpthread -lshlwapi -s" ABC_USE_NO_READLINE=0 CC="x86_64-w64-mingw32-gcc" CXX="$(CXX)" EXE = .exe -else ifneq ($(CONFIG),none) -$(error Invalid CONFIG setting '$(CONFIG)'. Valid values: clang, gcc, emcc, mxe, msys2-32, msys2-64) -else +else ifeq ($(CONFIG),none) CXXFLAGS += -std=$(CXXSTD) -Os ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H $(ABC_ARCHFLAGS)" + +else +$(error Invalid CONFIG setting '$(CONFIG)'. Valid values: clang, gcc, emcc, mxe, msys2-32, msys2-64, none) endif ifeq ($(ENABLE_LIBYOSYS),1) From 858eae5572375fac376f6c2bb43e976abe73af0d Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 8 Nov 2023 17:10:40 +0100 Subject: [PATCH 21/76] verific_const: convert VHDL values to RTLIL consts --- frontends/verific/verific.cc | 64 +++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 23 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index faa0e1bcdd3..6fc87ced645 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -223,7 +223,7 @@ RTLIL::IdString VerificImporter::new_verific_id(Verific::DesignObj *obj) // // Note: For signed values, verific uses 'sb and decimal values can // also be negative. -static const RTLIL::Const verific_const(const char *value, bool allow_string = true, bool output_signed = false) +static const RTLIL::Const verific_const(const char *value, bool from_vhdl, bool allow_string = true, bool output_signed = false) { size_t found; char *end; @@ -231,26 +231,44 @@ static const RTLIL::Const verific_const(const char *value, bool allow_string = t bool is_signed = false; RTLIL::Const c; std::string val = std::string(value); - if (allow_string && val.size()>1 && val[0]=='\"' && val.back()=='\"') { - c = RTLIL::Const(val.substr(1,val.size()-2)); - } else if ((found = val.find("'sb")) != std::string::npos) { - is_signed = output_signed; - c = RTLIL::Const::from_string(val.substr(found + 3)); - } else if ((found = val.find("'b")) != std::string::npos) { - c = RTLIL::Const::from_string(val.substr(found + 2)); - } else if ((value[0] == '-' || (value[0] >= '0' && value[0] <= '9')) && - ((decimal = std::strtol(value, &end, 10)), !end[0])) { - is_signed = output_signed; - c = RTLIL::Const((int)decimal, 32); - } else if (allow_string) { - c = RTLIL::Const(val); + if (from_vhdl) { + if (val.size()>1 && val[0]=='\"' && val.back()=='\"') { + std::string data = val.substr(1,val.size()-2); + bool isBinary = std::all_of(data.begin(), data.end(), [](char c) {return c=='1' || c=='0'; }); + if (isBinary) + c = RTLIL::Const::from_string(data); + else + c = RTLIL::Const(data); + } else if (val.size()==3 && val[0]=='\'' && val.back()=='\'') { + c = RTLIL::Const::from_string(val.substr(1,val.size()-2)); + } else if ((value[0] == '-' || (value[0] >= '0' && value[0] <= '9')) && + ((decimal = std::strtol(value, &end, 10)), !end[0])) { + is_signed = output_signed; + c = RTLIL::Const((int)decimal, 32); + } else { + log_error("non-expected '%s' constant found", value); + } } else { - log_error("expected numeric constant but found '%s'", value); - } - - if (is_signed) - c.flags |= RTLIL::CONST_FLAG_SIGNED; + if (allow_string && val.size()>1 && val[0]=='\"' && val.back()=='\"') { + c = RTLIL::Const(val.substr(1,val.size()-2)); + } else if ((found = val.find("'sb")) != std::string::npos) { + is_signed = output_signed; + c = RTLIL::Const::from_string(val.substr(found + 3)); + } else if ((found = val.find("'b")) != std::string::npos) { + c = RTLIL::Const::from_string(val.substr(found + 2)); + } else if ((value[0] == '-' || (value[0] >= '0' && value[0] <= '9')) && + ((decimal = std::strtol(value, &end, 10)), !end[0])) { + is_signed = output_signed; + c = RTLIL::Const((int)decimal, 32); + } else if (allow_string) { + c = RTLIL::Const(val); + } else { + log_error("expected numeric constant but found '%s'", value); + } + if (is_signed) + c.flags |= RTLIL::CONST_FLAG_SIGNED; + } return c; } @@ -276,7 +294,7 @@ void VerificImporter::import_attributes(dict &att FOREACH_ATTRIBUTE(obj, mi, attr) { if (attr->Key()[0] == ' ' || attr->Value() == nullptr) continue; - attributes[RTLIL::escape_id(attr->Key())] = verific_const(attr->Value()); + attributes[RTLIL::escape_id(attr->Key())] = verific_const(attr->Value(), obj->IsFromVhdl()); } if (nl) { @@ -298,7 +316,7 @@ void VerificImporter::import_attributes(dict &att const char *k, *v; FOREACH_MAP_ITEM(type_range->GetEnumIdMap(), mi, &k, &v) { if (nl->IsFromVerilog()) { - auto const value = verific_const(v, false); + auto const value = verific_const(v, nl->IsFromVhdl(), false); attributes.emplace(stringf("\\enum_value_%s", value.as_string().c_str()), RTLIL::escape_id(k)); } @@ -1304,7 +1322,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma MapIter mi; FOREACH_PARAMETER_OF_NETLIST(nl, mi, param_name, param_value) { module->avail_parameters(RTLIL::escape_id(param_name)); - module->parameter_default_values[RTLIL::escape_id(param_name)] = verific_const(param_value); + module->parameter_default_values[RTLIL::escape_id(param_name)] = verific_const(param_value, nl->IsFromVhdl()); } SetIter si; @@ -2004,7 +2022,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma const char *param_value ; if (is_blackbox(inst->View())) { FOREACH_PARAMETER_OF_INST(inst, mi2, param_name, param_value) { - cell->setParam(RTLIL::escape_id(param_name), verific_const(param_value)); + cell->setParam(RTLIL::escape_id(param_name), verific_const(param_value, nl->IsFromVhdl())); } } From 4279cea33a91aa934f65072e7b6c34830f55b037 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 11 Mar 2024 09:30:58 +0100 Subject: [PATCH 22/76] improve handling VHDL constants --- frontends/verific/verific.cc | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 6fc87ced645..6dbad4c2ae6 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -223,7 +223,7 @@ RTLIL::IdString VerificImporter::new_verific_id(Verific::DesignObj *obj) // // Note: For signed values, verific uses 'sb and decimal values can // also be negative. -static const RTLIL::Const verific_const(const char *value, bool from_vhdl, bool allow_string = true, bool output_signed = false) +static const RTLIL::Const verific_const(const char *value, DesignObj *obj, bool allow_string = true, bool output_signed = false) { size_t found; char *end; @@ -231,7 +231,7 @@ static const RTLIL::Const verific_const(const char *value, bool from_vhdl, bool bool is_signed = false; RTLIL::Const c; std::string val = std::string(value); - if (from_vhdl) { + if (obj->IsFromVhdl()) { if (val.size()>1 && val[0]=='\"' && val.back()=='\"') { std::string data = val.substr(1,val.size()-2); bool isBinary = std::all_of(data.begin(), data.end(), [](char c) {return c=='1' || c=='0'; }); @@ -245,6 +245,10 @@ static const RTLIL::Const verific_const(const char *value, bool from_vhdl, bool ((decimal = std::strtol(value, &end, 10)), !end[0])) { is_signed = output_signed; c = RTLIL::Const((int)decimal, 32); + } else if (val == "false") { + c = RTLIL::Const::from_string("0"); + } else if (val == "true") { + c = RTLIL::Const::from_string("1"); } else { log_error("non-expected '%s' constant found", value); } @@ -294,7 +298,7 @@ void VerificImporter::import_attributes(dict &att FOREACH_ATTRIBUTE(obj, mi, attr) { if (attr->Key()[0] == ' ' || attr->Value() == nullptr) continue; - attributes[RTLIL::escape_id(attr->Key())] = verific_const(attr->Value(), obj->IsFromVhdl()); + attributes[RTLIL::escape_id(attr->Key())] = verific_const(attr->Value(), obj); } if (nl) { @@ -316,7 +320,7 @@ void VerificImporter::import_attributes(dict &att const char *k, *v; FOREACH_MAP_ITEM(type_range->GetEnumIdMap(), mi, &k, &v) { if (nl->IsFromVerilog()) { - auto const value = verific_const(v, nl->IsFromVhdl(), false); + auto const value = verific_const(v, nl, false); attributes.emplace(stringf("\\enum_value_%s", value.as_string().c_str()), RTLIL::escape_id(k)); } @@ -1322,7 +1326,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma MapIter mi; FOREACH_PARAMETER_OF_NETLIST(nl, mi, param_name, param_value) { module->avail_parameters(RTLIL::escape_id(param_name)); - module->parameter_default_values[RTLIL::escape_id(param_name)] = verific_const(param_value, nl->IsFromVhdl()); + module->parameter_default_values[RTLIL::escape_id(param_name)] = verific_const(param_value, nl); } SetIter si; @@ -2022,7 +2026,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma const char *param_value ; if (is_blackbox(inst->View())) { FOREACH_PARAMETER_OF_INST(inst, mi2, param_name, param_value) { - cell->setParam(RTLIL::escape_id(param_name), verific_const(param_value, nl->IsFromVhdl())); + cell->setParam(RTLIL::escape_id(param_name), verific_const(param_value, inst->View())); } } From 7c09fa572e2eb4cce2cfdfcfdbc7ca327382ad2a Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 14 Mar 2024 10:37:11 +0100 Subject: [PATCH 23/76] real number handling and default to string --- frontends/verific/verific.cc | 50 +++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 6dbad4c2ae6..a5bcd44c48e 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -214,6 +214,22 @@ RTLIL::IdString VerificImporter::new_verific_id(Verific::DesignObj *obj) return s; } +RTLIL::Const mkconst_str(const std::string &str) +{ + RTLIL::Const val; + std::vector data; + data.reserve(str.size() * 8); + for (size_t i = 0; i < str.size(); i++) { + unsigned char ch = str[str.size() - i - 1]; + for (int j = 0; j < 8; j++) { + data.push_back((ch & 1) ? State::S1 : State::S0); + ch = ch >> 1; + } + } + val.bits = data; + val.flags |= RTLIL::CONST_FLAG_STRING; + return val; +} // When used as attributes or parameter values Verific constants come already processed. // - Real string values are already under quotes // - Numeric values with specified width are always converted to binary @@ -223,7 +239,7 @@ RTLIL::IdString VerificImporter::new_verific_id(Verific::DesignObj *obj) // // Note: For signed values, verific uses 'sb and decimal values can // also be negative. -static const RTLIL::Const verific_const(const char *value, DesignObj *obj, bool allow_string = true, bool output_signed = false) +static const RTLIL::Const verific_const(const char* type_name, const char *value, DesignObj *obj, bool allow_string = true, bool output_signed = false) { size_t found; char *end; @@ -232,7 +248,10 @@ static const RTLIL::Const verific_const(const char *value, DesignObj *obj, bool RTLIL::Const c; std::string val = std::string(value); if (obj->IsFromVhdl()) { - if (val.size()>1 && val[0]=='\"' && val.back()=='\"') { + if (type_name && strcmp(type_name, "real")==0) { + c = mkconst_str(val); + c.flags |= RTLIL::CONST_FLAG_REAL; + } else if (val.size()>1 && val[0]=='\"' && val.back()=='\"') { std::string data = val.substr(1,val.size()-2); bool isBinary = std::all_of(data.begin(), data.end(), [](char c) {return c=='1' || c=='0'; }); if (isBinary) @@ -250,10 +269,14 @@ static const RTLIL::Const verific_const(const char *value, DesignObj *obj, bool } else if (val == "true") { c = RTLIL::Const::from_string("1"); } else { - log_error("non-expected '%s' constant found", value); + c = mkconst_str(val); + log_warning("encoding value '%s' of type '%s' as string found", value, type_name ? type_name : "unknown"); } } else { - if (allow_string && val.size()>1 && val[0]=='\"' && val.back()=='\"') { + if (type_name && strcmp(type_name, "real")==0) { + c = mkconst_str(val); + c.flags |= RTLIL::CONST_FLAG_REAL; + } else if (allow_string && val.size()>1 && val[0]=='\"' && val.back()=='\"') { c = RTLIL::Const(val.substr(1,val.size()-2)); } else if ((found = val.find("'sb")) != std::string::npos) { is_signed = output_signed; @@ -267,12 +290,13 @@ static const RTLIL::Const verific_const(const char *value, DesignObj *obj, bool } else if (allow_string) { c = RTLIL::Const(val); } else { - log_error("expected numeric constant but found '%s'", value); + c = mkconst_str(val); + log_warning("encoding value '%s' of type '%s' as string found", value, type_name ? type_name : "unknown"); } - - if (is_signed) - c.flags |= RTLIL::CONST_FLAG_SIGNED; } + + if (is_signed) + c.flags |= RTLIL::CONST_FLAG_SIGNED; return c; } @@ -298,7 +322,7 @@ void VerificImporter::import_attributes(dict &att FOREACH_ATTRIBUTE(obj, mi, attr) { if (attr->Key()[0] == ' ' || attr->Value() == nullptr) continue; - attributes[RTLIL::escape_id(attr->Key())] = verific_const(attr->Value(), obj); + attributes[RTLIL::escape_id(attr->Key())] = verific_const(nullptr, attr->Value(), obj); } if (nl) { @@ -320,7 +344,7 @@ void VerificImporter::import_attributes(dict &att const char *k, *v; FOREACH_MAP_ITEM(type_range->GetEnumIdMap(), mi, &k, &v) { if (nl->IsFromVerilog()) { - auto const value = verific_const(v, nl, false); + auto const value = verific_const(type_name, v, nl, false); attributes.emplace(stringf("\\enum_value_%s", value.as_string().c_str()), RTLIL::escape_id(k)); } @@ -1326,7 +1350,8 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma MapIter mi; FOREACH_PARAMETER_OF_NETLIST(nl, mi, param_name, param_value) { module->avail_parameters(RTLIL::escape_id(param_name)); - module->parameter_default_values[RTLIL::escape_id(param_name)] = verific_const(param_value, nl); + const TypeRange *tr = nl->GetTypeRange(param_name) ; + module->parameter_default_values[RTLIL::escape_id(param_name)] = verific_const(tr->GetTypeName(), param_value, nl); } SetIter si; @@ -2026,7 +2051,8 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma const char *param_value ; if (is_blackbox(inst->View())) { FOREACH_PARAMETER_OF_INST(inst, mi2, param_name, param_value) { - cell->setParam(RTLIL::escape_id(param_name), verific_const(param_value, inst->View())); + const TypeRange *tr = inst->View()->GetTypeRange(param_name) ; + cell->setParam(RTLIL::escape_id(param_name), verific_const(tr->GetTypeName(), param_value, inst->View())); } } From 9eebc801705c6f7c179f354774b9d87174b3ec3f Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 18 Mar 2024 10:35:01 +0100 Subject: [PATCH 24/76] handle standard types --- frontends/verific/verific.cc | 47 +++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index a5bcd44c48e..62c070db589 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -248,9 +248,50 @@ static const RTLIL::Const verific_const(const char* type_name, const char *value RTLIL::Const c; std::string val = std::string(value); if (obj->IsFromVhdl()) { - if (type_name && strcmp(type_name, "real")==0) { - c = mkconst_str(val); - c.flags |= RTLIL::CONST_FLAG_REAL; + if (type_name) { + if (strcmp(type_name, "integer")==0 || strcmp(type_name, "natural")==0 || strcmp(type_name, "positive")==0) { + decimal = std::strtol(value, &end, 10); + c = RTLIL::Const((int)decimal, 32); + } else if (strcmp(type_name, "boolean")==0) { + if (val == "false") { + c = RTLIL::Const::from_string("0"); + } else if (val == "true") { + c = RTLIL::Const::from_string("1"); + } else + log_error("Error parsing boolean\n"); + } else if (strcmp(type_name, "bit")==0 || strcmp(type_name, "STD_LOGIC")==0 || strcmp(type_name, "STD_ULOGIC")==0) { + if (val.size()==3 && val[0]=='\'' && val.back()=='\'') { + c = RTLIL::Const::from_string(val.substr(1,val.size()-2)); + } else + log_error("Error parsing %s\n", type_name); + } else if (strcmp(type_name, "character")==0) { + if (val.size()>1 && val[0]=='\"' && val.back()=='\"') { + c = RTLIL::Const((int)val[1], 32); + } else + log_error("Error parsing character\n"); + } else if (strcmp(type_name, "bit_vector")==0 || strcmp(type_name, "STD_LOGIC_VECTOR")==0 || strcmp(type_name, "STD_ULOGIC_VECTOR")==0 || + strcmp(type_name, "UNSIGNED")==0 || strcmp(type_name, "SIGNED")==0) { + if (val.size()>1 && val[0]=='\"' && val.back()=='\"') { + c = RTLIL::Const::from_string(val.substr(1,val.size()-2)); + } else + log_error("Error parsing %s\n", type_name); + if (strcmp(type_name, "SIGNED")==0) + is_signed = true; + } else if (strcmp(type_name, "real")==0) { + c = mkconst_str(val); + c.flags |= RTLIL::CONST_FLAG_REAL; + } else if (strcmp(type_name, "string")==0) { + if (!(val.size()>1 && val[0]=='\"' && val.back()=='\"')) + log_error("Error parsing string\n"); + c = RTLIL::Const(val.substr(1,val.size()-2)); + } else { + if (val.size()>1 && val[0]=='\"' && val.back()=='\"') + c = RTLIL::Const(val.substr(1,val.size()-2)); + else if (val.size()==3 && val[0]=='\'' && val.back()=='\'') + c = RTLIL::Const(val.substr(1,val.size()-2)); + else + c = RTLIL::Const(val); + } } else if (val.size()>1 && val[0]=='\"' && val.back()=='\"') { std::string data = val.substr(1,val.size()-2); bool isBinary = std::all_of(data.begin(), data.end(), [](char c) {return c=='1' || c=='0'; }); From 4367e176fbfcfc3722dfa4a7a12c66cd430e3bf5 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 19 Mar 2024 09:15:04 +0100 Subject: [PATCH 25/76] code split and cleanup --- frontends/verific/verific.cc | 231 +++++++++++++++++++++-------------- 1 file changed, 141 insertions(+), 90 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 62c070db589..96e0469f6f8 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -230,6 +230,126 @@ RTLIL::Const mkconst_str(const std::string &str) val.flags |= RTLIL::CONST_FLAG_STRING; return val; } + +static const RTLIL::Const extract_vhdl_boolean(std::string &val) +{ + if (val == "false") + return RTLIL::Const::from_string("0"); + if (val == "true") + return RTLIL::Const::from_string("1"); + log_error("Expecting VHDL boolean value.\n"); +} + +static const RTLIL::Const extract_vhdl_bit(std::string &val, std::string &typ) +{ + if (val.size()==3 && val[0]=='\'' && val.back()=='\'') + return RTLIL::Const::from_string(val.substr(1,val.size()-2)); + log_error("Error parsing VHDL %s.\n", typ.c_str()); +} + +static const RTLIL::Const extract_vhdl_bit_vector(std::string &val, std::string &typ) +{ + if (val.size()>1 && val[0]=='\"' && val.back()=='\"') { + RTLIL::Const c = RTLIL::Const::from_string(val.substr(1,val.size()-2)); + if (typ == "signed") + c.flags |= RTLIL::CONST_FLAG_SIGNED; + return c; + } + log_error("Error parsing VHDL %s.\n", typ.c_str()); +} + +static const RTLIL::Const extract_vhdl_integer(std::string &val) +{ + char *end; + return RTLIL::Const((int)std::strtol(val.c_str(), &end, 10), 32); +} + +static const RTLIL::Const extract_vhdl_char(std::string &val) +{ + if (val.size()==3 && val[0]=='\"' && val.back()=='\"') + return RTLIL::Const((int)val[1], 32); + log_error("Error parsing VHDL character.\n"); +} + +static const RTLIL::Const extract_real_value(std::string &val) +{ + RTLIL::Const c = mkconst_str(val); + c.flags |= RTLIL::CONST_FLAG_REAL; + return c; +} + +static const RTLIL::Const extract_vhdl_string(std::string &val) +{ + if (!(val.size()>1 && val[0]=='\"' && val.back()=='\"')) + log_error("Error parsing VHDL string.\n"); + return RTLIL::Const(val.substr(1,val.size()-2)); +} + +static const RTLIL::Const extract_vhdl_const(const char *value, bool output_signed) +{ + RTLIL::Const c; + char *end; + int decimal; + bool is_signed = false; + std::string val = std::string(value); + + if (val.size()>1 && val[0]=='\"' && val.back()=='\"') { + std::string data = val.substr(1,val.size()-2); + bool isBinary = std::all_of(data.begin(), data.end(), [](char c) {return c=='1' || c=='0'; }); + if (isBinary) + c = RTLIL::Const::from_string(data); + else + c = RTLIL::Const(data); + } else if (val.size()==3 && val[0]=='\'' && val.back()=='\'') { + c = RTLIL::Const::from_string(val.substr(1,val.size()-2)); + } else if ((value[0] == '-' || (value[0] >= '0' && value[0] <= '9')) && + ((decimal = std::strtol(value, &end, 10)), !end[0])) { + is_signed = output_signed; + c = RTLIL::Const((int)decimal, 32); + } else if (val == "false") { + c = RTLIL::Const::from_string("0"); + } else if (val == "true") { + c = RTLIL::Const::from_string("1"); + } else { + c = mkconst_str(val); + log_warning("encoding value '%s' as string.\n", value); + } + if (is_signed) + c.flags |= RTLIL::CONST_FLAG_SIGNED; + return c; +} + +static const RTLIL::Const extract_verilog_const(const char *value, bool allow_string, bool output_signed) +{ + RTLIL::Const c; + char *end; + int decimal; + bool is_signed = false; + size_t found; + std::string val = std::string(value); + + if (allow_string && val.size()>1 && val[0]=='\"' && val.back()=='\"') { + c = RTLIL::Const(val.substr(1,val.size()-2)); + } else if ((found = val.find("'sb")) != std::string::npos) { + is_signed = output_signed; + c = RTLIL::Const::from_string(val.substr(found + 3)); + } else if ((found = val.find("'b")) != std::string::npos) { + c = RTLIL::Const::from_string(val.substr(found + 2)); + } else if ((value[0] == '-' || (value[0] >= '0' && value[0] <= '9')) && + ((decimal = std::strtol(value, &end, 10)), !end[0])) { + is_signed = output_signed; + c = RTLIL::Const((int)decimal, 32); + } else if (allow_string) { + c = RTLIL::Const(val); + } else { + c = mkconst_str(val); + log_warning("encoding value '%s' as string.\n", value); + } + if (is_signed) + c.flags |= RTLIL::CONST_FLAG_SIGNED; + return c; +} + // When used as attributes or parameter values Verific constants come already processed. // - Real string values are already under quotes // - Numeric values with specified width are always converted to binary @@ -241,104 +361,35 @@ RTLIL::Const mkconst_str(const std::string &str) // also be negative. static const RTLIL::Const verific_const(const char* type_name, const char *value, DesignObj *obj, bool allow_string = true, bool output_signed = false) { - size_t found; - char *end; - int decimal; - bool is_signed = false; - RTLIL::Const c; std::string val = std::string(value); + // VHDL if (obj->IsFromVhdl()) { if (type_name) { - if (strcmp(type_name, "integer")==0 || strcmp(type_name, "natural")==0 || strcmp(type_name, "positive")==0) { - decimal = std::strtol(value, &end, 10); - c = RTLIL::Const((int)decimal, 32); - } else if (strcmp(type_name, "boolean")==0) { - if (val == "false") { - c = RTLIL::Const::from_string("0"); - } else if (val == "true") { - c = RTLIL::Const::from_string("1"); - } else - log_error("Error parsing boolean\n"); - } else if (strcmp(type_name, "bit")==0 || strcmp(type_name, "STD_LOGIC")==0 || strcmp(type_name, "STD_ULOGIC")==0) { - if (val.size()==3 && val[0]=='\'' && val.back()=='\'') { - c = RTLIL::Const::from_string(val.substr(1,val.size()-2)); - } else - log_error("Error parsing %s\n", type_name); - } else if (strcmp(type_name, "character")==0) { - if (val.size()>1 && val[0]=='\"' && val.back()=='\"') { - c = RTLIL::Const((int)val[1], 32); - } else - log_error("Error parsing character\n"); - } else if (strcmp(type_name, "bit_vector")==0 || strcmp(type_name, "STD_LOGIC_VECTOR")==0 || strcmp(type_name, "STD_ULOGIC_VECTOR")==0 || - strcmp(type_name, "UNSIGNED")==0 || strcmp(type_name, "SIGNED")==0) { - if (val.size()>1 && val[0]=='\"' && val.back()=='\"') { - c = RTLIL::Const::from_string(val.substr(1,val.size()-2)); - } else - log_error("Error parsing %s\n", type_name); - if (strcmp(type_name, "SIGNED")==0) - is_signed = true; - } else if (strcmp(type_name, "real")==0) { - c = mkconst_str(val); - c.flags |= RTLIL::CONST_FLAG_REAL; - } else if (strcmp(type_name, "string")==0) { - if (!(val.size()>1 && val[0]=='\"' && val.back()=='\"')) - log_error("Error parsing string\n"); - c = RTLIL::Const(val.substr(1,val.size()-2)); - } else { + std::string typ = std::string(type_name); + transform(typ.begin(), typ.end(), typ.begin(), ::tolower); + if (typ == "integer" || typ == "natural" || typ=="positive") return extract_vhdl_integer(val); + else if (typ =="boolean") return extract_vhdl_boolean(val); + else if (typ == "bit" || typ =="std_logic" || typ == "std_ulogic") return extract_vhdl_bit(val,typ); + else if (typ == "character") return extract_vhdl_char(val); + else if (typ == "bit_vector" || typ == "std_logic_vector" || typ == "std_ulogic_vector" || + typ == "unsigned" || typ == "signed") return extract_vhdl_bit_vector(val,typ); + else if (typ == "real") return extract_real_value(val); + else if (typ == "string") return extract_vhdl_string(val); + else { if (val.size()>1 && val[0]=='\"' && val.back()=='\"') - c = RTLIL::Const(val.substr(1,val.size()-2)); + return RTLIL::Const(val.substr(1,val.size()-2)); else if (val.size()==3 && val[0]=='\'' && val.back()=='\'') - c = RTLIL::Const(val.substr(1,val.size()-2)); + return RTLIL::Const(val.substr(1,val.size()-2)); else - c = RTLIL::Const(val); + return RTLIL::Const(val); } - } else if (val.size()>1 && val[0]=='\"' && val.back()=='\"') { - std::string data = val.substr(1,val.size()-2); - bool isBinary = std::all_of(data.begin(), data.end(), [](char c) {return c=='1' || c=='0'; }); - if (isBinary) - c = RTLIL::Const::from_string(data); - else - c = RTLIL::Const(data); - } else if (val.size()==3 && val[0]=='\'' && val.back()=='\'') { - c = RTLIL::Const::from_string(val.substr(1,val.size()-2)); - } else if ((value[0] == '-' || (value[0] >= '0' && value[0] <= '9')) && - ((decimal = std::strtol(value, &end, 10)), !end[0])) { - is_signed = output_signed; - c = RTLIL::Const((int)decimal, 32); - } else if (val == "false") { - c = RTLIL::Const::from_string("0"); - } else if (val == "true") { - c = RTLIL::Const::from_string("1"); - } else { - c = mkconst_str(val); - log_warning("encoding value '%s' of type '%s' as string found", value, type_name ? type_name : "unknown"); - } - } else { - if (type_name && strcmp(type_name, "real")==0) { - c = mkconst_str(val); - c.flags |= RTLIL::CONST_FLAG_REAL; - } else if (allow_string && val.size()>1 && val[0]=='\"' && val.back()=='\"') { - c = RTLIL::Const(val.substr(1,val.size()-2)); - } else if ((found = val.find("'sb")) != std::string::npos) { - is_signed = output_signed; - c = RTLIL::Const::from_string(val.substr(found + 3)); - } else if ((found = val.find("'b")) != std::string::npos) { - c = RTLIL::Const::from_string(val.substr(found + 2)); - } else if ((value[0] == '-' || (value[0] >= '0' && value[0] <= '9')) && - ((decimal = std::strtol(value, &end, 10)), !end[0])) { - is_signed = output_signed; - c = RTLIL::Const((int)decimal, 32); - } else if (allow_string) { - c = RTLIL::Const(val); - } else { - c = mkconst_str(val); - log_warning("encoding value '%s' of type '%s' as string found", value, type_name ? type_name : "unknown"); - } + } else extract_vhdl_const(value, output_signed); } - - if (is_signed) - c.flags |= RTLIL::CONST_FLAG_SIGNED; - return c; + // SystemVerilog + if (type_name && strcmp(type_name, "real")==0) { + return extract_real_value(val); + } else + return extract_verilog_const(value, allow_string, output_signed); } static const std::string verific_unescape(const char *value) From 160e3e089a14b79fa76de7c303140d3d4c0fd1da Mon Sep 17 00:00:00 2001 From: Peter Gadfort Date: Fri, 22 Mar 2024 09:20:08 -0400 Subject: [PATCH 26/76] add port statistics to stat command --- passes/cmds/stat.cc | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index 85107b68f33..c2bb72f3bb3 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -36,7 +36,8 @@ struct cell_area_t { struct statdata_t { #define STAT_INT_MEMBERS X(num_wires) X(num_wire_bits) X(num_pub_wires) X(num_pub_wire_bits) \ - X(num_memories) X(num_memory_bits) X(num_cells) X(num_processes) + X(num_ports) X(num_port_bits) X(num_memories) X(num_memory_bits) X(num_cells) \ + X(num_processes) #define STAT_NUMERIC_MEMBERS STAT_INT_MEMBERS X(area) @@ -90,6 +91,11 @@ struct statdata_t for (auto wire : mod->selected_wires()) { + if (wire->port_input || wire->port_output) { + num_ports++; + num_port_bits += wire->width; + } + if (wire->name.isPublic()) { num_pub_wires++; num_pub_wire_bits += wire->width; @@ -239,6 +245,8 @@ struct statdata_t log(" Number of wire bits: %6u\n", num_wire_bits); log(" Number of public wires: %6u\n", num_pub_wires); log(" Number of public wire bits: %6u\n", num_pub_wire_bits); + log(" Number of ports: %6u\n", num_ports); + log(" Number of port bits: %6u\n", num_port_bits); log(" Number of memories: %6u\n", num_memories); log(" Number of memory bits: %6u\n", num_memory_bits); log(" Number of processes: %6u\n", num_processes); @@ -284,6 +292,8 @@ struct statdata_t log(" \"num_wire_bits\": %u,\n", num_wire_bits); log(" \"num_pub_wires\": %u,\n", num_pub_wires); log(" \"num_pub_wire_bits\": %u,\n", num_pub_wire_bits); + log(" \"num_ports\": %u,\n", num_ports); + log(" \"num_port_bits\": %u,\n", num_port_bits); log(" \"num_memories\": %u,\n", num_memories); log(" \"num_memory_bits\": %u,\n", num_memory_bits); log(" \"num_processes\": %u,\n", num_processes); @@ -494,6 +504,8 @@ struct StatPass : public Pass { design->scratchpad_set_int("stat.num_wire_bits", data.num_wire_bits); design->scratchpad_set_int("stat.num_pub_wires", data.num_pub_wires); design->scratchpad_set_int("stat.num_pub_wire_bits", data.num_pub_wire_bits); + design->scratchpad_set_int("stat.num_ports", data.num_ports); + design->scratchpad_set_int("stat.num_port_bits", data.num_port_bits); design->scratchpad_set_int("stat.num_memories", data.num_memories); design->scratchpad_set_int("stat.num_memory_bits", data.num_memory_bits); design->scratchpad_set_int("stat.num_processes", data.num_processes); From b57a803f6097f4b515404ce6a6d0ccbca4327986 Mon Sep 17 00:00:00 2001 From: Rui Chen Date: Sun, 24 Mar 2024 00:41:40 -0400 Subject: [PATCH 27/76] chore: fix master branch refs Signed-off-by: Rui Chen --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- .github/workflows/test-docs.yml | 2 +- backends/jny/jny.cc | 4 ++-- docs/source/getting_started/example_synth.rst | 4 ++-- docs/source/test_suites.rst | 4 ++-- .../using_yosys/more_scripting/interactive_investigation.rst | 4 ++-- docs/source/using_yosys/more_scripting/model_checking.rst | 4 ++-- docs/source/using_yosys/more_scripting/selections.rst | 2 +- docs/source/using_yosys/synthesis/cell_libs.rst | 2 +- docs/source/using_yosys/synthesis/extract.rst | 2 +- docs/source/using_yosys/synthesis/memory.rst | 4 ++-- docs/source/using_yosys/synthesis/proc.rst | 2 +- docs/source/yosys_internals/extending_yosys/extensions.rst | 4 ++-- docs/source/yosys_internals/techmap.rst | 2 +- guidelines/Windows | 2 +- misc/create_vcxsrc.sh | 2 +- misc/jny.schema.json | 2 +- 17 files changed, 24 insertions(+), 24 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 66c0b19715a..e4c776ed914 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -43,7 +43,7 @@ body: attributes: value: > When providing steps to reproduce the issue, please ensure that the issue - is reproducible in the current git master of Yosys. Also ensure to + is reproducible in the current git main of Yosys. Also ensure to provide all necessary source files needed. diff --git a/.github/workflows/test-docs.yml b/.github/workflows/test-docs.yml index e8064e485ae..00e5309bfbe 100644 --- a/.github/workflows/test-docs.yml +++ b/.github/workflows/test-docs.yml @@ -3,7 +3,7 @@ name: Build and test doc code samples on: pull_request: branches: - - master + - main jobs: test-docs: diff --git a/backends/jny/jny.cc b/backends/jny/jny.cc index 9989feed599..1c163dba52e 100644 --- a/backends/jny/jny.cc +++ b/backends/jny/jny.cc @@ -124,7 +124,7 @@ struct JnyWriter design->sort(); f << "{\n"; - f << " \"$schema\": \"https://raw.githubusercontent.com/YosysHQ/yosys/master/misc/jny.schema.json\",\n"; + f << " \"$schema\": \"https://raw.githubusercontent.com/YosysHQ/yosys/main/misc/jny.schema.json\",\n"; f << stringf(" \"generator\": \"%s\",\n", escape_string(yosys_version_str).c_str()); f << " \"version\": \"0.0.1\",\n"; f << " \"invocation\": \"" << escape_string(invk) << "\",\n"; @@ -426,7 +426,7 @@ struct JnyBackend : public Backend { log(" Don't include property information in the netlist output.\n"); log("\n"); log("The JSON schema for JNY output files is located in the \"jny.schema.json\" file\n"); - log("which is located at \"https://raw.githubusercontent.com/YosysHQ/yosys/master/misc/jny.schema.json\"\n"); + log("which is located at \"https://raw.githubusercontent.com/YosysHQ/yosys/main/misc/jny.schema.json\"\n"); log("\n"); } diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index 799b4ec48b4..916bef9fabd 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -633,9 +633,9 @@ with the mapping to ``SB_RAM40_4K`` done by :cmd:ref:`techmap` using into flip flops (the ``logic fallback``) with :cmd:ref:`memory_map`. .. |techlibs/ice40/brams.txt| replace:: :file:`techlibs/ice40/brams.txt` -.. _techlibs/ice40/brams.txt: https://github.com/YosysHQ/yosys/tree/master/techlibs/ice40/brams.txt +.. _techlibs/ice40/brams.txt: https://github.com/YosysHQ/yosys/tree/main/techlibs/ice40/brams.txt .. |techlibs/ice40/brams_map.v| replace:: :file:`techlibs/ice40/brams_map.v` -.. _techlibs/ice40/brams_map.v: https://github.com/YosysHQ/yosys/tree/master/techlibs/ice40/brams_map.v +.. _techlibs/ice40/brams_map.v: https://github.com/YosysHQ/yosys/tree/main/techlibs/ice40/brams_map.v .. literalinclude:: /cmd/synth_ice40.rst :language: yoscrypt diff --git a/docs/source/test_suites.rst b/docs/source/test_suites.rst index 2edb0e67d1a..7a6b7497774 100644 --- a/docs/source/test_suites.rst +++ b/docs/source/test_suites.rst @@ -16,8 +16,8 @@ Automatic testing .. _Yosys Git repo: https://github.com/YosysHQ/yosys -.. |test-linux| image:: https://github.com/YosysHQ/yosys/actions/workflows/test-linux.yml/badge.svg?branch=master -.. |test-macos| image:: https://github.com/YosysHQ/yosys/actions/workflows/test-macos.yml/badge.svg?branch=master +.. |test-linux| image:: https://github.com/YosysHQ/yosys/actions/workflows/test-linux.yml/badge.svg?branch=main +.. |test-macos| image:: https://github.com/YosysHQ/yosys/actions/workflows/test-macos.yml/badge.svg?branch=main For up to date information, including OS versions, refer to `the git actions page`_. diff --git a/docs/source/using_yosys/more_scripting/interactive_investigation.rst b/docs/source/using_yosys/more_scripting/interactive_investigation.rst index ed798d6b694..f56543bebbb 100644 --- a/docs/source/using_yosys/more_scripting/interactive_investigation.rst +++ b/docs/source/using_yosys/more_scripting/interactive_investigation.rst @@ -18,7 +18,7 @@ in the circuit diagrams generated by it. The code used is included in the Yosys code base under |code_examples/show|_. .. |code_examples/show| replace:: :file:`docs/source/code_examples/show` -.. _code_examples/show: https://github.com/YosysHQ/yosys/tree/master/docs/source/code_examples/show +.. _code_examples/show: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/show A simple circuit ^^^^^^^^^^^^^^^^ @@ -337,7 +337,7 @@ The code used is included in the Yosys code base under |code_examples/scrambler|_. .. |code_examples/scrambler| replace:: :file:`docs/source/code_examples/scrambler` -.. _code_examples/scrambler: https://github.com/YosysHQ/yosys/tree/master/docs/source/code_examples/scrambler +.. _code_examples/scrambler: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/scrambler Changing design hierarchy ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/source/using_yosys/more_scripting/model_checking.rst b/docs/source/using_yosys/more_scripting/model_checking.rst index 0b97d384e63..92a9d85ce67 100644 --- a/docs/source/using_yosys/more_scripting/model_checking.rst +++ b/docs/source/using_yosys/more_scripting/model_checking.rst @@ -29,7 +29,7 @@ Let's take a look at an example included in the Yosys code base under |code_examples/synth_flow|_: .. |code_examples/synth_flow| replace:: :file:`docs/source/code_examples/synth_flow` -.. _code_examples/synth_flow: https://github.com/YosysHQ/yosys/tree/master/docs/source/code_examples/synth_flow +.. _code_examples/synth_flow: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/synth_flow .. literalinclude:: /code_examples/synth_flow/techmap_01_map.v :language: verilog @@ -81,7 +81,7 @@ The code used in this section is included in the Yosys code base under |code_examples/axis|_. .. |code_examples/axis| replace:: :file:`docs/source/code_examples/axis` -.. _code_examples/axis: https://github.com/YosysHQ/yosys/tree/master/docs/source/code_examples/axis +.. _code_examples/axis: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/axis The following AXI4 Stream Master has a bug. But the bug is not exposed if the slave keeps ``tready`` asserted all the time. (Something a test bench might do.) diff --git a/docs/source/using_yosys/more_scripting/selections.rst b/docs/source/using_yosys/more_scripting/selections.rst index d4def881cc9..6aa3465cc99 100644 --- a/docs/source/using_yosys/more_scripting/selections.rst +++ b/docs/source/using_yosys/more_scripting/selections.rst @@ -405,7 +405,7 @@ those cases selection variables must be used to capture more complex selections. Example code from |code_examples/selections|_: .. |code_examples/selections| replace:: :file:`docs/source/code_examples/selections` -.. _code_examples/selections: https://github.com/YosysHQ/yosys/tree/master/docs/source/code_examples/selections +.. _code_examples/selections: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/selections .. literalinclude:: /code_examples/selections/select.v :language: verilog diff --git a/docs/source/using_yosys/synthesis/cell_libs.rst b/docs/source/using_yosys/synthesis/cell_libs.rst index a723845379a..476269abfc9 100644 --- a/docs/source/using_yosys/synthesis/cell_libs.rst +++ b/docs/source/using_yosys/synthesis/cell_libs.rst @@ -21,7 +21,7 @@ detail in the :doc:`/getting_started/example_synth` document. To learn more about these commands, check out :ref:`interactive_show`. -.. _example project: https://github.com/YosysHQ/yosys/tree/master/docs/source/code_examples/intro +.. _example project: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/intro A simple counter ~~~~~~~~~~~~~~~~ diff --git a/docs/source/using_yosys/synthesis/extract.rst b/docs/source/using_yosys/synthesis/extract.rst index 678efba868e..bbe1870dfb3 100644 --- a/docs/source/using_yosys/synthesis/extract.rst +++ b/docs/source/using_yosys/synthesis/extract.rst @@ -15,7 +15,7 @@ The extract pass Example code can be found in |code_examples/macc|_. .. |code_examples/macc| replace:: :file:`docs/source/code_examples/macc` -.. _code_examples/macc: https://github.com/YosysHQ/yosys/tree/master/docs/source/code_examples/macc +.. _code_examples/macc: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/macc .. literalinclude:: /code_examples/macc/macc_simple_test.ys diff --git a/docs/source/using_yosys/synthesis/memory.rst b/docs/source/using_yosys/synthesis/memory.rst index 7df75fb8809..3dbafeaab7e 100644 --- a/docs/source/using_yosys/synthesis/memory.rst +++ b/docs/source/using_yosys/synthesis/memory.rst @@ -36,7 +36,7 @@ Example |code_examples/synth_flow|_. .. |code_examples/synth_flow| replace:: :file:`docs/source/code_examples/synth_flow` -.. _code_examples/synth_flow: https://github.com/YosysHQ/yosys/tree/master/docs/source/code_examples/synth_flow +.. _code_examples/synth_flow: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/synth_flow .. figure:: /_images/code_examples/synth_flow/memory_01.* :class: width-helper @@ -92,7 +92,7 @@ leftover memory cells unable to be converted are then picked up by For more on the lib format for :cmd:ref:`memory_libmap`, see `passes/memory/memlib.md -`_ +`_ Supported memory patterns ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/source/using_yosys/synthesis/proc.rst b/docs/source/using_yosys/synthesis/proc.rst index 785be7adc7c..b4983438021 100644 --- a/docs/source/using_yosys/synthesis/proc.rst +++ b/docs/source/using_yosys/synthesis/proc.rst @@ -31,7 +31,7 @@ Example |code_examples/synth_flow|_. .. |code_examples/synth_flow| replace:: :file:`docs/source/code_examples/synth_flow` -.. _code_examples/synth_flow: https://github.com/YosysHQ/yosys/tree/master/docs/source/code_examples/synth_flow +.. _code_examples/synth_flow: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/synth_flow .. literalinclude:: /code_examples/synth_flow/proc_01.v :language: verilog diff --git a/docs/source/yosys_internals/extending_yosys/extensions.rst b/docs/source/yosys_internals/extending_yosys/extensions.rst index 2c159e3f089..68e1740be4a 100644 --- a/docs/source/yosys_internals/extending_yosys/extensions.rst +++ b/docs/source/yosys_internals/extending_yosys/extensions.rst @@ -24,7 +24,7 @@ Code examples from this section are included in the |code_examples/extensions|_ directory of the Yosys source code. .. |code_examples/extensions| replace:: :file:`docs/source/code_examples/extensions` -.. _code_examples/extensions: https://github.com/YosysHQ/yosys/tree/master/docs/source/code_examples/extensions +.. _code_examples/extensions: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/extensions Program components and data formats @@ -254,7 +254,7 @@ The following is the complete code of the "stubnets" example module. It is included in the Yosys source distribution under |code_examples/stubnets|_. .. |code_examples/stubnets| replace:: :file:`docs/source/code_examples/stubnets` -.. _code_examples/stubnets: https://github.com/YosysHQ/yosys/tree/master/docs/source/code_examples/stubnets +.. _code_examples/stubnets: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/stubnets .. literalinclude:: /code_examples/stubnets/stubnets.cc :language: c++ diff --git a/docs/source/yosys_internals/techmap.rst b/docs/source/yosys_internals/techmap.rst index ef2bbd87a28..ab161ed92d3 100644 --- a/docs/source/yosys_internals/techmap.rst +++ b/docs/source/yosys_internals/techmap.rst @@ -16,7 +16,7 @@ Code examples used in this document are included in the Yosys code base under |code_examples/techmap|_. .. |code_examples/techmap| replace:: :file:`docs/source/code_examples/techmap` -.. _code_examples/techmap: https://github.com/YosysHQ/yosys/tree/master/docs/source/code_examples/techmap +.. _code_examples/techmap: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/techmap Mapping OR3X1 diff --git a/guidelines/Windows b/guidelines/Windows index 2af0620fae9..c4548c37cc7 100644 --- a/guidelines/Windows +++ b/guidelines/Windows @@ -44,7 +44,7 @@ Visual Studio builds are not directly supported by build scripts, but they are s 1. Easy way - - Go to https://github.com/YosysHQ/yosys/actions/workflows/vs.yml?query=branch%3Amaster + - Go to https://github.com/YosysHQ/yosys/actions/workflows/vs.yml?query=branch%3Amain - Click on the most recent completed run - In Artifacts region find vcxsrc and click on it to download - Unpack downloaded ZIP file diff --git a/misc/create_vcxsrc.sh b/misc/create_vcxsrc.sh index 8b39d59e30e..eee215015b5 100644 --- a/misc/create_vcxsrc.sh +++ b/misc/create_vcxsrc.sh @@ -46,7 +46,7 @@ Open "Git Bash" in this directory and run: mv yosys yosys.bak git clone https://github.com/YosysHQ/yosys.git yosys cd yosys - git checkout -B master $(git rev-parse HEAD | cut -c1-10) + git checkout -B main $(git rev-parse HEAD | cut -c1-10) unzip ../genfiles.zip EOT diff --git a/misc/jny.schema.json b/misc/jny.schema.json index 0fff8ee57d8..278b1a55f63 100644 --- a/misc/jny.schema.json +++ b/misc/jny.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://raw.githubusercontent.com/YosysHQ/yosys/master/misc/jny.schema.json", + "$id": "https://raw.githubusercontent.com/YosysHQ/yosys/main/misc/jny.schema.json", "title": "Yosys JSON Netlist metadata", "description": "Yosys JSON Netlist", "type": "object", From c38201e15d457388b26d712df4aa10266015c22d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 25 Mar 2024 14:56:17 +0100 Subject: [PATCH 28/76] techmap: Add a Kogge-Stone option for `$lcu` mapping --- techlibs/common/techmap.v | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 7fb8173b069..38ca33cb947 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -230,6 +230,7 @@ module _90_lcu (P, G, CI, CO); // in almost all cases CI will be constant zero g[0] = g[0] | (p[0] & CI); +`ifndef KOGGE_STONE // [[CITE]] Brent Kung Adder // R. P. Brent and H. T. Kung, "A Regular Layout for Parallel Adders", // IEEE Transaction on Computers, Vol. C-31, No. 3, p. 260-264, March, 1982 @@ -249,6 +250,14 @@ module _90_lcu (P, G, CI, CO); p[j] = p[j] & p[j - 2**(i-1)]; end end +`else + for (i = 0; i < $clog2(WIDTH); i = i + 1) begin + for (j = 2**i; j < WIDTH; j = j + 1) begin + g[j] = g[j] | p[j] & g[j - 2**i]; + p[j] = p[j] & p[j - 2**i]; + end + end +`endif end assign CO = g; From 0a854cf4cea669dd78c9a29657c29a70a651ec6d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 26 Mar 2024 00:15:18 +0000 Subject: [PATCH 29/76] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b69ddd2ad7a..391fb7288f3 100644 --- a/Makefile +++ b/Makefile @@ -142,7 +142,7 @@ LIBS += -lrt endif endif -YOSYS_VER := 0.39+124 +YOSYS_VER := 0.39+147 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 4570d064e5bac128f4057874457e306d4e275eb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 25 Mar 2024 18:39:55 +0100 Subject: [PATCH 30/76] techmap: Split out Kogge-Stone into a separate file --- techlibs/common/Makefile.inc | 1 + techlibs/common/choices/kogge-stone.v | 53 +++++++++++++++++++++++++++ techlibs/common/techmap.v | 11 +----- 3 files changed, 55 insertions(+), 10 deletions(-) create mode 100644 techlibs/common/choices/kogge-stone.v diff --git a/techlibs/common/Makefile.inc b/techlibs/common/Makefile.inc index 6b377855e3e..fa5c2a825de 100644 --- a/techlibs/common/Makefile.inc +++ b/techlibs/common/Makefile.inc @@ -35,3 +35,4 @@ $(eval $(call add_share_file,share,techlibs/common/abc9_map.v)) $(eval $(call add_share_file,share,techlibs/common/abc9_unmap.v)) $(eval $(call add_share_file,share,techlibs/common/cmp2lcu.v)) $(eval $(call add_share_file,share,techlibs/common/cmp2softlogic.v)) +$(eval $(call add_share_file,share/choices,techlibs/common/choices/kogge-stone.v)) diff --git a/techlibs/common/choices/kogge-stone.v b/techlibs/common/choices/kogge-stone.v new file mode 100644 index 00000000000..eb97a75d831 --- /dev/null +++ b/techlibs/common/choices/kogge-stone.v @@ -0,0 +1,53 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2024 Martin Povišer + * + * 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. + * + */ + +(* techmap_celltype = "$lcu" *) +module _80_lcu_kogge_stone (P, G, CI, CO); + parameter WIDTH = 2; + + (* force_downto *) + input [WIDTH-1:0] P, G; + input CI; + + (* force_downto *) + output [WIDTH-1:0] CO; + + integer i, j; + (* force_downto *) + reg [WIDTH-1:0] p, g; + + wire [1023:0] _TECHMAP_DO_ = "proc; opt -fast"; + + always @* begin + p = P; + g = G; + + // in almost all cases CI will be constant zero + g[0] = g[0] | (p[0] & CI); + + for (i = 0; i < $clog2(WIDTH); i = i + 1) begin + for (j = 2**i; j < WIDTH; j = j + 1) begin + g[j] = g[j] | p[j] & g[j - 2**i]; + p[j] = p[j] & p[j - 2**i]; + end + end + end + + assign CO = g; +endmodule diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 38ca33cb947..68b276588b5 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -207,7 +207,7 @@ module _90_fa (A, B, C, X, Y); endmodule (* techmap_celltype = "$lcu" *) -module _90_lcu (P, G, CI, CO); +module _90_lcu_brent_kung (P, G, CI, CO); parameter WIDTH = 2; (* force_downto *) @@ -230,7 +230,6 @@ module _90_lcu (P, G, CI, CO); // in almost all cases CI will be constant zero g[0] = g[0] | (p[0] & CI); -`ifndef KOGGE_STONE // [[CITE]] Brent Kung Adder // R. P. Brent and H. T. Kung, "A Regular Layout for Parallel Adders", // IEEE Transaction on Computers, Vol. C-31, No. 3, p. 260-264, March, 1982 @@ -250,14 +249,6 @@ module _90_lcu (P, G, CI, CO); p[j] = p[j] & p[j - 2**(i-1)]; end end -`else - for (i = 0; i < $clog2(WIDTH); i = i + 1) begin - for (j = 2**i; j < WIDTH; j = j + 1) begin - g[j] = g[j] | p[j] & g[j - 2**i]; - p[j] = p[j] & p[j - 2**i]; - end - end -`endif end assign CO = g; From c49d6e78743fb51335c0640af9d4dc8b6c9407cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Wed, 27 Mar 2024 11:08:26 +0100 Subject: [PATCH 31/76] techmap: Add Kogge-Stone test --- tests/techmap/kogge-stone.ys | 1 + 1 file changed, 1 insertion(+) create mode 100644 tests/techmap/kogge-stone.ys diff --git a/tests/techmap/kogge-stone.ys b/tests/techmap/kogge-stone.ys new file mode 100644 index 00000000000..fc3637f10b0 --- /dev/null +++ b/tests/techmap/kogge-stone.ys @@ -0,0 +1 @@ +test_cell -s 1711533949 -n 10 -map +/techmap.v -map +/choices/kogge-stone.v $lcu From bc087f91ed2779fec32c94d99f56cebca3c6a4b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Wed, 27 Mar 2024 18:32:25 +0100 Subject: [PATCH 32/76] techmap: Fix using overwritten results in Kogge-Stone --- techlibs/common/choices/kogge-stone.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/common/choices/kogge-stone.v b/techlibs/common/choices/kogge-stone.v index eb97a75d831..0e25fe86073 100644 --- a/techlibs/common/choices/kogge-stone.v +++ b/techlibs/common/choices/kogge-stone.v @@ -42,7 +42,7 @@ module _80_lcu_kogge_stone (P, G, CI, CO); g[0] = g[0] | (p[0] & CI); for (i = 0; i < $clog2(WIDTH); i = i + 1) begin - for (j = 2**i; j < WIDTH; j = j + 1) begin + for (j = WIDTH - 1; j >= 2**i; j = j - 1) begin g[j] = g[j] | p[j] & g[j - 2**i]; p[j] = p[j] & p[j - 2**i]; end From f536de0e0e585fe3c6146bc7e8f1a4d3b0e14bc4 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 28 Mar 2024 13:21:55 +0100 Subject: [PATCH 33/76] Verific support for VHDL 2019 --- frontends/verific/Makefile.inc | 1 + frontends/verific/verific.cc | 29 ++++++++++++++++++++++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/frontends/verific/Makefile.inc b/frontends/verific/Makefile.inc index c82428613af..df3ac8d2d43 100644 --- a/frontends/verific/Makefile.inc +++ b/frontends/verific/Makefile.inc @@ -14,6 +14,7 @@ ifneq ($(DISABLE_VERIFIC_VHDL),1) $(Q) cp -r $(VERIFIC_DIR)/vhdl_packages/vdbs_1987/. share/verific.new/vhdl_vdbs_1987 $(Q) cp -r $(VERIFIC_DIR)/vhdl_packages/vdbs_1993/. share/verific.new/vhdl_vdbs_1993 $(Q) cp -r $(VERIFIC_DIR)/vhdl_packages/vdbs_2008/. share/verific.new/vhdl_vdbs_2008 + $(Q) cp -r $(VERIFIC_DIR)/vhdl_packages/vdbs_2019/. share/verific.new/vhdl_vdbs_2019 endif $(Q) chmod -R a+rX share/verific.new $(Q) mv share/verific.new share/verific diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index faa0e1bcdd3..a65fde42f2c 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -2699,7 +2699,7 @@ struct VerificPass : public Pass { log("\n"); log("\n"); #ifdef VERIFIC_VHDL_SUPPORT - log(" verific {-vhdl87|-vhdl93|-vhdl2k|-vhdl2008|-vhdl} ..\n"); + log(" verific {-vhdl87|-vhdl93|-vhdl2k|-vhdl2008|-vhdl2019|-vhdl} ..\n"); log("\n"); log("Load the specified VHDL files into Verific.\n"); log("\n"); @@ -3436,6 +3436,29 @@ struct VerificPass : public Pass { goto check_error; } + if (GetSize(args) > argidx && (args[argidx] == "-vhdl2019")) { + vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_2019").c_str()); + bool flag_lib = false; + for (argidx++; argidx < GetSize(args); argidx++) { + if (args[argidx] == "-lib") { + flag_lib = true; + continue; + } + if (args[argidx].compare(0, 1, "-") == 0) { + cmd_error(args, argidx, "unknown option"); + goto check_error; + } + Map map(POINTER_HASH); + add_units_to_map(map, work, flag_lib); + std::string filename = frontent_rewrite(args, argidx, tmp_files); + if (!vhdl_file::Analyze(filename.c_str(), work.c_str(), vhdl_file::VHDL_2019)) + log_cmd_error("Reading `%s' in VHDL_2019 mode failed.\n", filename.c_str()); + set_units_to_blackbox(map, work, flag_lib); + } + verific_import_pending = true; + goto check_error; + } + if (GetSize(args) > argidx && (args[argidx] == "-vhdl2008" || args[argidx] == "-vhdl")) { vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_2008").c_str()); bool flag_lib = false; @@ -3979,7 +4002,7 @@ struct ReadPass : public Pass { log("\n"); log("\n"); #ifdef VERIFIC_VHDL_SUPPORT - log(" read {-vhdl87|-vhdl93|-vhdl2k|-vhdl2008|-vhdl} ..\n"); + log(" read {-vhdl87|-vhdl93|-vhdl2k|-vhdl2008|-vhdl2019|-vhdl} ..\n"); log("\n"); log("Load the specified VHDL files. (Requires Verific.)\n"); log("\n"); @@ -4083,7 +4106,7 @@ struct ReadPass : public Pass { } #ifdef VERIFIC_VHDL_SUPPORT - if (args[1] == "-vhdl87" || args[1] == "-vhdl93" || args[1] == "-vhdl2k" || args[1] == "-vhdl2008" || args[1] == "-vhdl") { + if (args[1] == "-vhdl87" || args[1] == "-vhdl93" || args[1] == "-vhdl2k" || args[1] == "-vhdl2008" || args[1] == "-vhdl2019" || args[1] == "-vhdl") { if (use_verific) { args[0] = "verific"; Pass::call(design, args); From d07a55a852e3e9430daba9068878b1ac10605f0a Mon Sep 17 00:00:00 2001 From: Merry <8682882+merryhime@users.noreply.github.com> Date: Fri, 29 Mar 2024 20:53:26 +0000 Subject: [PATCH 34/76] cxxrtl: Fix sdivmod x = x.neg(); results in the subsequent x.is_neg() always being false. Ditto for the dividend.is_neg() != divisor.is_neg() test. --- backends/cxxrtl/runtime/cxxrtl/cxxrtl.h | 8 +- tests/cxxrtl/test_value_fuzz.cc | 105 ++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 4 deletions(-) diff --git a/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h b/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h index b834cd12019..16aa900f1a5 100644 --- a/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h @@ -625,11 +625,11 @@ struct value : public expr_base> { value remainder; value dividend = sext(); value divisor = other.template sext(); - if (dividend.is_neg()) dividend = dividend.neg(); - if (divisor.is_neg()) divisor = divisor.neg(); + if (is_neg()) dividend = dividend.neg(); + if (other.is_neg()) divisor = divisor.neg(); std::tie(quotient, remainder) = dividend.udivmod(divisor); - if (dividend.is_neg() != divisor.is_neg()) quotient = quotient.neg(); - if (dividend.is_neg()) remainder = remainder.neg(); + if (is_neg() != other.is_neg()) quotient = quotient.neg(); + if (is_neg()) remainder = remainder.neg(); return {quotient.template trunc(), remainder.template trunc()}; } }; diff --git a/tests/cxxrtl/test_value_fuzz.cc b/tests/cxxrtl/test_value_fuzz.cc index 4428e9f6e7f..a7bbb293afc 100644 --- a/tests/cxxrtl/test_value_fuzz.cc +++ b/tests/cxxrtl/test_value_fuzz.cc @@ -25,6 +25,11 @@ T rand_int(T min = std::numeric_limits::min(), T max = std::numeric_limits return dist(generator); } +int64_t sext(size_t bits, uint64_t value) +{ + return (int64_t)(value << (64 - bits)) >> (64 - bits); +} + struct BinaryOperationBase { void tweak_input(uint64_t &a, uint64_t &b) {} @@ -246,6 +251,106 @@ struct CtlzTest } } ctlz; +struct UdivTest : BinaryOperationBase +{ + UdivTest() + { + std::printf("Randomized tests for value::udivmod (div):\n"); + test_binary_operation(*this); + } + + uint64_t reference_impl(size_t bits, uint64_t a, uint64_t b) + { + return a / b; + } + + template + cxxrtl::value testing_impl(cxxrtl::value a, cxxrtl::value b) + { + return std::get<0>(a.udivmod(b)); + } + + void tweak_input(uint64_t &, uint64_t &b) + { + if (b == 0) b = 1; // Avoid divide by zero + } +} udiv; + +struct UmodTest : BinaryOperationBase +{ + UmodTest() + { + std::printf("Randomized tests for value::udivmod (mod):\n"); + test_binary_operation(*this); + } + + uint64_t reference_impl(size_t bits, uint64_t a, uint64_t b) + { + return a % b; + } + + template + cxxrtl::value testing_impl(cxxrtl::value a, cxxrtl::value b) + { + return std::get<1>(a.udivmod(b)); + } + + void tweak_input(uint64_t &, uint64_t &b) + { + if (b == 0) b = 1; // Avoid divide by zero + } +} umod; + +struct SdivTest : BinaryOperationBase +{ + SdivTest() + { + std::printf("Randomized tests for value::sdivmod (div):\n"); + test_binary_operation(*this); + } + + uint64_t reference_impl(size_t bits, uint64_t a, uint64_t b) + { + return (uint64_t)(sext(bits, a) / sext(bits, b)); + } + + template + cxxrtl::value testing_impl(cxxrtl::value a, cxxrtl::value b) + { + return std::get<0>(a.sdivmod(b)); + } + + void tweak_input(uint64_t &, uint64_t &b) + { + if (b == 0) b = 1; // Avoid divide by zero + } +} sdiv; + +struct SmodTest : BinaryOperationBase +{ + SmodTest() + { + std::printf("Randomized tests for value::sdivmod (mod):\n"); + test_binary_operation(*this); + } + + uint64_t reference_impl(size_t bits, uint64_t a, uint64_t b) + { + return (uint64_t)(sext(bits, a) % sext(bits, b)); + } + + template + cxxrtl::value testing_impl(cxxrtl::value a, cxxrtl::value b) + { + return std::get<1>(a.sdivmod(b)); + } + + void tweak_input(uint64_t &, uint64_t &b) + { + if (b == 0) b = 1; // Avoid divide by zero + } +} smod; + int main() { } From b9d3bffda5abcbc5356936a7192c4a3c2b427c3e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 31 Mar 2024 00:18:11 +0000 Subject: [PATCH 35/76] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 391fb7288f3..ca229ca4a52 100644 --- a/Makefile +++ b/Makefile @@ -142,7 +142,7 @@ LIBS += -lrt endif endif -YOSYS_VER := 0.39+147 +YOSYS_VER := 0.39+149 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 73cacd543c98ab29b9ea23104339c5405ce1f6ef Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Tue, 2 Apr 2024 11:23:56 +0200 Subject: [PATCH 36/76] docs: Update linux kernel coding style link --- guidelines/CodingStyle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guidelines/CodingStyle b/guidelines/CodingStyle index ee1e1a2b6a1..8a3df2d62e8 100644 --- a/guidelines/CodingStyle +++ b/guidelines/CodingStyle @@ -19,7 +19,7 @@ Formatting of code blank lines. - Otherwise stick to the Linux Kernel Coding Style: - https://www.kernel.org/doc/Documentation/CodingStyle + https://www.kernel.org/doc/Documentation/process/coding-style.rst C++ Language From a5441bc00c957c268279b35924d055418eb79446 Mon Sep 17 00:00:00 2001 From: Catherine Date: Thu, 28 Mar 2024 06:30:16 +0000 Subject: [PATCH 37/76] =?UTF-8?q?fmt:=20`FmtPart::{STRING=E2=86=92LITERAL}?= =?UTF-8?q?,{CHARACTER=E2=86=92STRING}`.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before this commit, the `STRING` variant inserted a literal string; the `CHARACTER` variant inserted a string. This commit renames them to `LITERAL` and `STRING` respectively. --- backends/cxxrtl/runtime/cxxrtl/cxxrtl.h | 14 ++++---- frontends/ast/genrtlil.cc | 2 +- frontends/ast/simplify.cc | 2 +- kernel/fmt.cc | 44 ++++++++++++------------- kernel/fmt.h | 12 +++---- 5 files changed, 37 insertions(+), 37 deletions(-) diff --git a/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h b/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h index 16aa900f1a5..b1fc7e05c20 100644 --- a/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h @@ -1010,19 +1010,19 @@ struct observer { // Default member initializers would make this a non-aggregate-type in C++11, so they are commented out. struct fmt_part { enum { - STRING = 0, + LITERAL = 0, INTEGER = 1, - CHARACTER = 2, + STRING = 2, VLOG_TIME = 3, } type; - // STRING type + // LITERAL type std::string str; - // INTEGER/CHARACTER types + // INTEGER/STRING types // + value val; - // INTEGER/CHARACTER/VLOG_TIME types + // INTEGER/STRING/VLOG_TIME types enum { RIGHT = 0, LEFT = 1, @@ -1050,10 +1050,10 @@ struct fmt_part { // chunk access if it turns out to be slow enough to matter. std::string buf; switch (type) { - case STRING: + case LITERAL: return str; - case CHARACTER: { + case STRING: { buf.reserve(Bits/8); for (int i = 0; i < Bits; i += 8) { char ch = 0; diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index fe67f00c692..bc7f1ddd1d6 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -790,7 +790,7 @@ struct AST_INTERNAL::ProcessGenerator Fmt fmt; fmt.parse_verilog(args, /*sformat_like=*/false, default_base, /*task_name=*/ast->str, current_module->name); if (ast->str.substr(0, 8) == "$display") - fmt.append_string("\n"); + fmt.append_literal("\n"); fmt.emit_rtlil(cell); } else if (!ast->str.empty()) { log_file_error(ast->filename, ast->location.first_line, "Found unsupported invocation of system task `%s'!\n", ast->str.c_str()); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 43a4e03a29d..3d8478ef160 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1079,7 +1079,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin // when $display()/$write() functions are used in an initial block, print them during synthesis Fmt fmt = processFormat(stage, /*sformat_like=*/false, default_base, /*first_arg_at=*/0, /*may_fail=*/true); if (str.substr(0, 8) == "$display") - fmt.append_string("\n"); + fmt.append_literal("\n"); log("%s", fmt.render().c_str()); } diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 18eb7cb7193..336e3e2ab75 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -22,9 +22,9 @@ USING_YOSYS_NAMESPACE -void Fmt::append_string(const std::string &str) { +void Fmt::append_literal(const std::string &str) { FmtPart part = {}; - part.type = FmtPart::STRING; + part.type = FmtPart::LITERAL; part.str = str; parts.push_back(part); } @@ -46,7 +46,7 @@ void Fmt::parse_rtlil(const RTLIL::Cell *cell) { log_assert(false && "Unexpected '}' in format string"); else if (fmt[i] == '{') { if (!part.str.empty()) { - part.type = FmtPart::STRING; + part.type = FmtPart::LITERAL; parts.push_back(part); part = {}; } @@ -108,7 +108,7 @@ void Fmt::parse_rtlil(const RTLIL::Cell *cell) { part.type = FmtPart::INTEGER; part.base = 16; } else if (fmt[i] == 'c') { - part.type = FmtPart::CHARACTER; + part.type = FmtPart::STRING; } else if (fmt[i] == 't') { part.type = FmtPart::VLOG_TIME; } else if (fmt[i] == 'r') { @@ -150,7 +150,7 @@ void Fmt::parse_rtlil(const RTLIL::Cell *cell) { } } if (!part.str.empty()) { - part.type = FmtPart::STRING; + part.type = FmtPart::LITERAL; parts.push_back(part); } } @@ -161,7 +161,7 @@ void Fmt::emit_rtlil(RTLIL::Cell *cell) const { for (auto &part : parts) { switch (part.type) { - case FmtPart::STRING: + case FmtPart::LITERAL: for (char c : part.str) { if (c == '{') fmt += "{{"; @@ -175,7 +175,7 @@ void Fmt::emit_rtlil(RTLIL::Cell *cell) const { case FmtPart::VLOG_TIME: log_assert(part.sig.size() == 0); YS_FALLTHROUGH - case FmtPart::CHARACTER: + case FmtPart::STRING: log_assert(part.sig.size() % 8 == 0); YS_FALLTHROUGH case FmtPart::INTEGER: @@ -203,7 +203,7 @@ void Fmt::emit_rtlil(RTLIL::Cell *cell) const { if (part.plus) fmt += '+'; fmt += part.signed_ ? 's' : 'u'; - } else if (part.type == FmtPart::CHARACTER) { + } else if (part.type == FmtPart::STRING) { fmt += 'c'; } else if (part.type == FmtPart::VLOG_TIME) { if (part.realtime) @@ -299,12 +299,12 @@ void Fmt::apply_verilog_automatic_sizing_and_add(FmtPart &part) part.width = places; if (part.justify == FmtPart::RIGHT) { - append_string(gap); + append_literal(gap); parts.push_back(part); } else { part.justify = FmtPart::RIGHT; parts.push_back(part); - append_string(gap); + append_literal(gap); } } } @@ -355,7 +355,7 @@ void Fmt::parse_verilog(const std::vector &args, bool sformat_lik part.str += module_name.str(); } else { if (!part.str.empty()) { - part.type = FmtPart::STRING; + part.type = FmtPart::LITERAL; parts.push_back(part); part = {}; } @@ -408,11 +408,11 @@ void Fmt::parse_verilog(const std::vector &args, bool sformat_lik part.type = FmtPart::INTEGER; part.base = 16; } else if (fmt[i] == 'c' || fmt[i] == 'C') { - part.type = FmtPart::CHARACTER; + part.type = FmtPart::STRING; part.sig.extend_u0(8); // %10c and %010c not fully defined in IEEE 1800-2017 and do different things in iverilog } else if (fmt[i] == 's' || fmt[i] == 'S') { - part.type = FmtPart::CHARACTER; + part.type = FmtPart::STRING; if ((part.sig.size() % 8) != 0) part.sig.extend_u0((part.sig.size() + 7) / 8 * 8); // %10s and %010s not fully defined in IEEE 1800-2017 and do the same thing in iverilog @@ -449,12 +449,12 @@ void Fmt::parse_verilog(const std::vector &args, bool sformat_lik } } if (!part.str.empty()) { - part.type = FmtPart::STRING; + part.type = FmtPart::LITERAL; parts.push_back(part); } } else { FmtPart part = {}; - part.type = FmtPart::STRING; + part.type = FmtPart::LITERAL; part.str = arg->str; parts.push_back(part); } @@ -474,7 +474,7 @@ std::vector Fmt::emit_verilog() const for (auto &part : parts) { switch (part.type) { - case FmtPart::STRING: + case FmtPart::LITERAL: for (char c : part.str) { if (c == '%') fmt.str += "%%"; @@ -513,7 +513,7 @@ std::vector Fmt::emit_verilog() const break; } - case FmtPart::CHARACTER: { + case FmtPart::STRING: { VerilogFmtArg arg; arg.type = VerilogFmtArg::INTEGER; arg.sig = part.sig; @@ -599,9 +599,9 @@ void Fmt::emit_cxxrtl(std::ostream &os, std::string indent, std::function parts; - void append_string(const std::string &str); + void append_literal(const std::string &str); void parse_rtlil(const RTLIL::Cell *cell); void emit_rtlil(RTLIL::Cell *cell) const; From 8388846e3a727f42aa6086226863e530c22f07f6 Mon Sep 17 00:00:00 2001 From: Catherine Date: Thu, 28 Mar 2024 06:13:35 +0000 Subject: [PATCH 38/76] fmt,cxxrtl: add support for uppercase hex format. This is necessary for translating Python format strings in Amaranth. --- backends/cxxrtl/runtime/cxxrtl/cxxrtl.h | 3 ++- kernel/fmt.cc | 11 ++++++++--- kernel/fmt.h | 1 + 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h b/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h index b1fc7e05c20..b3a537435f3 100644 --- a/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h @@ -1034,6 +1034,7 @@ struct fmt_part { unsigned base; // = 10; bool signed_; // = false; bool plus; // = false; + bool hex_upper; // = false; // VLOG_TIME type bool realtime; // = false; @@ -1085,7 +1086,7 @@ struct fmt_part { uint8_t value = val.bit(index) | (val.bit(index + 1) << 1) | (val.bit(index + 2) << 2); if (step == 4) value |= val.bit(index + 3) << 3; - buf += "0123456789abcdef"[value]; + buf += (hex_upper ? "0123456789ABCDEF" : "0123456789abcdef")[value]; } std::reverse(buf.begin(), buf.end()); } else if (base == 10) { diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 336e3e2ab75..6fdc18ad0a9 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -107,6 +107,10 @@ void Fmt::parse_rtlil(const RTLIL::Cell *cell) { } else if (fmt[i] == 'h') { part.type = FmtPart::INTEGER; part.base = 16; + } else if (fmt[i] == 'H') { + part.type = FmtPart::INTEGER; + part.base = 16; + part.hex_upper = true; } else if (fmt[i] == 'c') { part.type = FmtPart::STRING; } else if (fmt[i] == 't') { @@ -197,7 +201,7 @@ void Fmt::emit_rtlil(RTLIL::Cell *cell) const { case 2: fmt += 'b'; break; case 8: fmt += 'o'; break; case 10: fmt += 'd'; break; - case 16: fmt += 'h'; break; + case 16: fmt += part.hex_upper ? 'H' : 'h'; break; default: log_abort(); } if (part.plus) @@ -507,7 +511,7 @@ std::vector Fmt::emit_verilog() const case 2: fmt.str += 'b'; break; case 8: fmt.str += 'o'; break; case 10: fmt.str += 'd'; break; - case 16: fmt.str += 'h'; break; + case 16: fmt.str += 'h'; break; // treat uppercase hex as lowercase default: log_abort(); } break; @@ -617,6 +621,7 @@ void Fmt::emit_cxxrtl(std::ostream &os, std::string indent, std::function Date: Thu, 28 Mar 2024 06:59:23 +0000 Subject: [PATCH 39/76] fmt,cxxrtl: support `{,PLUS_,SPACE_}MINUS` integer formats. The first two were already supported with the `plus` boolean flag. The third one is a new specifier, which is allocated the ` ` character. In addition, `MINUS` is now allocated the `-` character, but old format where there is no `+`, `-`, or `-` in the respective position is also accepted for compatibility. --- backends/cxxrtl/runtime/cxxrtl/cxxrtl.h | 13 +++++-- kernel/fmt.cc | 47 ++++++++++++++++++------- kernel/fmt.h | 6 +++- 3 files changed, 50 insertions(+), 16 deletions(-) diff --git a/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h b/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h index b3a537435f3..02050df584e 100644 --- a/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h @@ -1033,7 +1033,11 @@ struct fmt_part { // INTEGER type unsigned base; // = 10; bool signed_; // = false; - bool plus; // = false; + enum { + MINUS = 0, + PLUS_MINUS = 1, + SPACE_MINUS = 2, + } sign; // = MINUS; bool hex_upper; // = false; // VLOG_TIME type @@ -1105,8 +1109,11 @@ struct fmt_part { buf += '0' + remainder.template trunc<4>().template get(); xval = quotient; } - if (negative || plus) - buf += negative ? '-' : '+'; + switch (sign) { + case MINUS: buf += negative ? "-" : ""; break; + case PLUS_MINUS: buf += negative ? "-" : "+"; break; + case SPACE_MINUS: buf += negative ? "-" : " "; break; + } std::reverse(buf.begin(), buf.end()); } else assert(false && "Unsupported base for fmt_part"); break; diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 6fdc18ad0a9..342b508d915 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -128,10 +128,20 @@ void Fmt::parse_rtlil(const RTLIL::Cell *cell) { log_assert(false && "Unexpected end in format substitution"); if (part.type == FmtPart::INTEGER) { - if (fmt[i] == '+') { - part.plus = true; + if (fmt[i] == '-') { + part.sign = FmtPart::MINUS; if (++i == fmt.size()) log_assert(false && "Unexpected end in format substitution"); + } else if (fmt[i] == '+') { + part.sign = FmtPart::PLUS_MINUS; + if (++i == fmt.size()) + log_assert(false && "Unexpected end in format substitution"); + } else if (fmt[i] == ' ') { + part.sign = FmtPart::SPACE_MINUS; + if (++i == fmt.size()) + log_assert(false && "Unexpected end in format substitution"); + } else { + // also accept no sign character and treat like MINUS for compatibility } if (fmt[i] == 'u') @@ -204,8 +214,11 @@ void Fmt::emit_rtlil(RTLIL::Cell *cell) const { case 16: fmt += part.hex_upper ? 'H' : 'h'; break; default: log_abort(); } - if (part.plus) - fmt += '+'; + switch (part.sign) { + case FmtPart::MINUS: fmt += '-'; break; + case FmtPart::PLUS_MINUS: fmt += '+'; break; + case FmtPart::SPACE_MINUS: fmt += ' '; break; + } fmt += part.signed_ ? 's' : 'u'; } else if (part.type == FmtPart::STRING) { fmt += 'c'; @@ -379,7 +392,7 @@ void Fmt::parse_verilog(const std::vector &args, bool sformat_lik part.justify = FmtPart::LEFT; } else if (fmt[i] == '+') { // always show sign; not in IEEE 1800-2017 or verilator but iverilog has it - part.plus = true; + part.sign = FmtPart::PLUS_MINUS; } else break; } if (i == fmt.size()) { @@ -442,7 +455,7 @@ void Fmt::parse_verilog(const std::vector &args, bool sformat_lik if (part.padding == '\0') part.padding = (has_leading_zero && part.justify == FmtPart::RIGHT) ? '0' : ' '; - if (part.type == FmtPart::INTEGER && part.base != 10 && part.plus) + if (part.type == FmtPart::INTEGER && part.base != 10 && part.sign != FmtPart::MINUS) log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with invalid format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1); if (part.type == FmtPart::INTEGER && !has_leading_zero) @@ -495,8 +508,8 @@ std::vector Fmt::emit_verilog() const args.push_back(arg); fmt.str += '%'; - if (part.plus) - fmt.str += '+'; + if (part.sign == FmtPart::PLUS_MINUS || part.sign == FmtPart::SPACE_MINUS) + fmt.str += '+'; // treat space/minus as plus/minus if (part.justify == FmtPart::LEFT) fmt.str += '-'; if (part.width == 0) { @@ -553,7 +566,8 @@ std::vector Fmt::emit_verilog() const args.push_back(arg); fmt.str += '%'; - if (part.plus) + log_assert(part.sign == FmtPart::MINUS || part.sign == FmtPart::PLUS_MINUS); + if (part.sign == FmtPart::PLUS_MINUS) fmt.str += '+'; if (part.justify == FmtPart::LEFT) fmt.str += '-'; @@ -620,7 +634,13 @@ void Fmt::emit_cxxrtl(std::ostream &os, std::string indent, std::function Date: Thu, 28 Mar 2024 07:23:09 +0000 Subject: [PATCH 40/76] fmt,cxxrtl: add support for `NUMERIC` justification. Before this commit, the existing alignments were `LEFT` and `RIGHT`, which added the `padding` character to the right and left just before finishing formatting. However, if `padding == '0'` and the alignment is to the right, then the padding character (digit zero) was added after the sign, if one is present. After this commit, the special case for `padding == '0'` is removed, and the new justification `NUMERIC` adds the padding character like the justification `RIGHT`, except after the sign, if one is present. (Space, for the `SPACE_MINUS` sign mode, counts as the sign.) --- backends/cxxrtl/runtime/cxxrtl/cxxrtl.h | 5 +++-- kernel/fmt.cc | 23 +++++++++++++++++------ kernel/fmt.h | 1 + 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h b/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h index 02050df584e..a987360123e 100644 --- a/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h @@ -1026,6 +1026,7 @@ struct fmt_part { enum { RIGHT = 0, LEFT = 1, + NUMERIC = 2, } justify; // = RIGHT; char padding; // = '\0'; size_t width; // = 0; @@ -1131,9 +1132,9 @@ struct fmt_part { std::string str; assert(width == 0 || padding != '\0'); - if (justify == RIGHT && buf.size() < width) { + if (justify != LEFT && buf.size() < width) { size_t pad_width = width - buf.size(); - if (padding == '0' && (buf.front() == '+' || buf.front() == '-')) { + if (justify == NUMERIC && (buf.front() == '+' || buf.front() == '-' || buf.front() == ' ')) { str += buf.front(); buf.erase(0, 1); } diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 342b508d915..43f60b1d867 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -78,6 +78,8 @@ void Fmt::parse_rtlil(const RTLIL::Cell *cell) { part.justify = FmtPart::RIGHT; else if (fmt[i] == '<') part.justify = FmtPart::LEFT; + else if (fmt[i] == '=') + part.justify = FmtPart::NUMERIC; else log_assert(false && "Unexpected justification in format substitution"); if (++i == fmt.size()) @@ -201,6 +203,8 @@ void Fmt::emit_rtlil(RTLIL::Cell *cell) const { fmt += '>'; else if (part.justify == FmtPart::LEFT) fmt += '<'; + else if (part.justify == FmtPart::NUMERIC) + fmt += '='; else log_abort(); log_assert(part.width == 0 || part.padding != '\0'); fmt += part.padding != '\0' ? part.padding : ' '; @@ -452,8 +456,14 @@ void Fmt::parse_verilog(const std::vector &args, bool sformat_lik log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with incomplete format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1); } - if (part.padding == '\0') - part.padding = (has_leading_zero && part.justify == FmtPart::RIGHT) ? '0' : ' '; + if (part.padding == '\0') { + if (has_leading_zero && part.justify == FmtPart::RIGHT) { + part.padding = '0'; + part.justify = FmtPart::NUMERIC; + } else { + part.padding = ' '; + } + } if (part.type == FmtPart::INTEGER && part.base != 10 && part.sign != FmtPart::MINUS) log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with invalid format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1); @@ -626,8 +636,9 @@ void Fmt::emit_cxxrtl(std::ostream &os, std::string indent, std::function Date: Thu, 28 Mar 2024 07:55:46 +0000 Subject: [PATCH 41/76] fmt,cxxrtl: add `UNICHAR` format type. This format type is used to print an Unicode character (code point) as its UTF-8 serialization. To this end, two UTF-8 decoders (one for fmt, one for cxxrtl) are added for rendering. When converted to a Verilog format specifier, `UNICHAR` degrades to `%c` with the low 7 bits of the code point, which has equivalent behavior for inputs not exceeding ASCII. (SystemVerilog leaves source and display encodings completely undefined.) --- backends/cxxrtl/runtime/cxxrtl/cxxrtl.h | 24 +++++++++++-- kernel/fmt.cc | 47 +++++++++++++++++++++++-- kernel/fmt.h | 5 +-- 3 files changed, 70 insertions(+), 6 deletions(-) diff --git a/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h b/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h index a987360123e..a67915346b2 100644 --- a/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h @@ -1013,13 +1013,14 @@ struct fmt_part { LITERAL = 0, INTEGER = 1, STRING = 2, - VLOG_TIME = 3, + UNICHAR = 3, + VLOG_TIME = 4, } type; // LITERAL type std::string str; - // INTEGER/STRING types + // INTEGER/STRING/UNICHAR types // + value val; // INTEGER/STRING/VLOG_TIME types @@ -1073,6 +1074,25 @@ struct fmt_part { break; } + case UNICHAR: { + uint32_t codepoint = val.template get(); + if (codepoint >= 0x10000) + buf += (char)(0xf0 | (codepoint >> 18)); + else if (codepoint >= 0x800) + buf += (char)(0xe0 | (codepoint >> 12)); + else if (codepoint >= 0x80) + buf += (char)(0xc0 | (codepoint >> 6)); + else + buf += (char)codepoint; + if (codepoint >= 0x10000) + buf += (char)(0x80 | ((codepoint >> 12) & 0x3f)); + if (codepoint >= 0x800) + buf += (char)(0x80 | ((codepoint >> 6) & 0x3f)); + if (codepoint >= 0x80) + buf += (char)(0x80 | ((codepoint >> 0) & 0x3f)); + break; + } + case INTEGER: { size_t width = Bits; if (base != 10) { diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 43f60b1d867..5bd4fd9c8e5 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -42,9 +42,9 @@ void Fmt::parse_rtlil(const RTLIL::Cell *cell) { } else if (fmt.substr(i, 2) == "{{") { part.str += '{'; ++i; - } else if (fmt[i] == '}') + } else if (fmt[i] == '}') { log_assert(false && "Unexpected '}' in format string"); - else if (fmt[i] == '{') { + } else if (fmt[i] == '{') { if (!part.str.empty()) { part.type = FmtPart::LITERAL; parts.push_back(part); @@ -74,6 +74,12 @@ void Fmt::parse_rtlil(const RTLIL::Cell *cell) { part.sig = args.extract(0, arg_size); args.remove(0, arg_size); + if (fmt[i] == 'U') { + part.type = FmtPart::UNICHAR; + ++i; + goto success; + } + if (fmt[i] == '>') part.justify = FmtPart::RIGHT; else if (fmt[i] == '<') @@ -156,6 +162,7 @@ void Fmt::parse_rtlil(const RTLIL::Cell *cell) { log_assert(false && "Unexpected end in format substitution"); } + success: if (fmt[i] != '}') log_assert(false && "Expected '}' after format substitution"); @@ -188,6 +195,11 @@ void Fmt::emit_rtlil(RTLIL::Cell *cell) const { } break; + case FmtPart::UNICHAR: + log_assert(part.sig.size() <= 32); + fmt += "{U}"; + break; + case FmtPart::VLOG_TIME: log_assert(part.sig.size() == 0); YS_FALLTHROUGH @@ -568,6 +580,16 @@ std::vector Fmt::emit_verilog() const break; } + case FmtPart::UNICHAR: { + VerilogFmtArg arg; + arg.type = VerilogFmtArg::INTEGER; + arg.sig = part.sig.extract(0, 7); // only ASCII + args.push_back(arg); + + fmt.str += "%c"; + break; + } + case FmtPart::VLOG_TIME: { VerilogFmtArg arg; arg.type = VerilogFmtArg::TIME; @@ -630,6 +652,7 @@ void Fmt::emit_cxxrtl(std::ostream &os, std::string indent, std::function= 0x10000) + str += (char)(0xf0 | (codepoint >> 18)); + else if (codepoint >= 0x800) + str += (char)(0xe0 | (codepoint >> 12)); + else if (codepoint >= 0x80) + str += (char)(0xc0 | (codepoint >> 6)); + else + str += (char)codepoint; + if (codepoint >= 0x10000) + str += (char)(0x80 | ((codepoint >> 12) & 0x3f)); + if (codepoint >= 0x800) + str += (char)(0x80 | ((codepoint >> 6) & 0x3f)); + if (codepoint >= 0x80) + str += (char)(0x80 | ((codepoint >> 0) & 0x3f)); + break; + } + case FmtPart::INTEGER: case FmtPart::STRING: case FmtPart::VLOG_TIME: { diff --git a/kernel/fmt.h b/kernel/fmt.h index 9dc6341ba57..7fe6fd55e25 100644 --- a/kernel/fmt.h +++ b/kernel/fmt.h @@ -56,13 +56,14 @@ struct FmtPart { LITERAL = 0, INTEGER = 1, STRING = 2, - VLOG_TIME = 3, + UNICHAR = 3, + VLOG_TIME = 4, } type; // LITERAL type std::string str; - // INTEGER/STRING types + // INTEGER/STRING/UNICHAR types RTLIL::SigSpec sig; // INTEGER/STRING/VLOG_TIME types From 7b94599162cf11713299ed1263b4723211d084d9 Mon Sep 17 00:00:00 2001 From: Catherine Date: Thu, 28 Mar 2024 08:33:29 +0000 Subject: [PATCH 42/76] fmt,cxxrtl: add option to print numeric base (`0x`, etc). The option is serialized to RTLIL as `#` (to match Python's and Rust's option with the same symbol), and sets the `show_base` flag. Because the flag is called `show_base` and not e.g. `alternate_format` (which is what Python and Rust call it), in addition to the prefixes `0x`, `0X`, `0o`, `0b`, the RTLIL option also prints the `0d` prefix. --- backends/cxxrtl/runtime/cxxrtl/cxxrtl.h | 7 +++++++ kernel/fmt.cc | 13 +++++++++++++ kernel/fmt.h | 1 + 3 files changed, 21 insertions(+) diff --git a/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h b/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h index a67915346b2..00840123205 100644 --- a/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h @@ -1041,6 +1041,7 @@ struct fmt_part { SPACE_MINUS = 2, } sign; // = MINUS; bool hex_upper; // = false; + bool show_base; // = false; // VLOG_TIME type bool realtime; // = false; @@ -1103,6 +1104,8 @@ struct fmt_part { } if (base == 2) { + if (show_base) + buf += "0b"; for (size_t i = width; i > 0; i--) buf += (val.bit(i - 1) ? '1' : '0'); } else if (base == 8 || base == 16) { @@ -1113,6 +1116,8 @@ struct fmt_part { value |= val.bit(index + 3) << 3; buf += (hex_upper ? "0123456789ABCDEF" : "0123456789abcdef")[value]; } + if (show_base) + buf += (base == 16) ? (hex_upper ? "X0" : "x0") : "o0"; std::reverse(buf.begin(), buf.end()); } else if (base == 10) { bool negative = signed_ && val.is_neg(); @@ -1130,6 +1135,8 @@ struct fmt_part { buf += '0' + remainder.template trunc<4>().template get(); xval = quotient; } + if (show_base) + buf += "d0"; switch (sign) { case MINUS: buf += negative ? "-" : ""; break; case PLUS_MINUS: buf += negative ? "-" : "+"; break; diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 5bd4fd9c8e5..8f4e61722e1 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -152,6 +152,11 @@ void Fmt::parse_rtlil(const RTLIL::Cell *cell) { // also accept no sign character and treat like MINUS for compatibility } + if (fmt[i] == '#') { + part.show_base = true; + ++i; + } + if (fmt[i] == 'u') part.signed_ = false; else if (fmt[i] == 's') @@ -235,6 +240,7 @@ void Fmt::emit_rtlil(RTLIL::Cell *cell) const { case FmtPart::PLUS_MINUS: fmt += '+'; break; case FmtPart::SPACE_MINUS: fmt += ' '; break; } + fmt += part.show_base ? "#" : ""; fmt += part.signed_ ? 's' : 'u'; } else if (part.type == FmtPart::STRING) { fmt += 'c'; @@ -676,6 +682,7 @@ void Fmt::emit_cxxrtl(std::ostream &os, std::string indent, std::function Date: Thu, 28 Mar 2024 08:55:26 +0000 Subject: [PATCH 43/76] fmt,cxxrtl: add option to group digits in numbers. The option is serialized to RTLIL as `_` (to match Python's option with the same symbol), and sets the `group` flag. This flag inserts an `_` symbol between each group of 3 digits (for decimal) or four digits (for binary, hex, and octal). --- backends/cxxrtl/runtime/cxxrtl/cxxrtl.h | 17 ++++++++++++--- kernel/fmt.cc | 29 +++++++++++++++++++++++-- kernel/fmt.h | 1 + 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h b/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h index 00840123205..31085b74554 100644 --- a/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h @@ -1042,6 +1042,7 @@ struct fmt_part { } sign; // = MINUS; bool hex_upper; // = false; bool show_base; // = false; + bool group; // = false; // VLOG_TIME type bool realtime; // = false; @@ -1104,13 +1105,19 @@ struct fmt_part { } if (base == 2) { + for (size_t index = 0; index < width; index++) { + if (group && index > 0 && index % 4 == 0) + buf += '_'; + buf += (val.bit(index) ? '1' : '0'); + } if (show_base) - buf += "0b"; - for (size_t i = width; i > 0; i--) - buf += (val.bit(i - 1) ? '1' : '0'); + buf += "b0"; + std::reverse(buf.begin(), buf.end()); } else if (base == 8 || base == 16) { size_t step = (base == 16) ? 4 : 3; for (size_t index = 0; index < width; index += step) { + if (group && index > 0 && index % (4 * step) == 0) + buf += '_'; uint8_t value = val.bit(index) | (val.bit(index + 1) << 1) | (val.bit(index + 2) << 2); if (step == 4) value |= val.bit(index + 3) << 3; @@ -1126,7 +1133,10 @@ struct fmt_part { if (val.is_zero()) buf += '0'; value<(Bits > 4 ? Bits : 4)> xval = val.template zext<(Bits > 4 ? Bits : 4)>(); + size_t index = 0; while (!xval.is_zero()) { + if (group && index > 0 && index % 3 == 0) + buf += '_'; value<(Bits > 4 ? Bits : 4)> quotient, remainder; if (Bits >= 4) std::tie(quotient, remainder) = xval.udivmod(value<(Bits > 4 ? Bits : 4)>{10u}); @@ -1134,6 +1144,7 @@ struct fmt_part { std::tie(quotient, remainder) = std::make_pair(value<(Bits > 4 ? Bits : 4)>{0u}, xval); buf += '0' + remainder.template trunc<4>().template get(); xval = quotient; + index++; } if (show_base) buf += "d0"; diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 8f4e61722e1..f5793d796f2 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -156,6 +156,10 @@ void Fmt::parse_rtlil(const RTLIL::Cell *cell) { part.show_base = true; ++i; } + if (fmt[i] == '_') { + part.group = true; + ++i; + } if (fmt[i] == 'u') part.signed_ = false; @@ -241,6 +245,7 @@ void Fmt::emit_rtlil(RTLIL::Cell *cell) const { case FmtPart::SPACE_MINUS: fmt += ' '; break; } fmt += part.show_base ? "#" : ""; + fmt += part.group ? "_" : ""; fmt += part.signed_ ? 's' : 'u'; } else if (part.type == FmtPart::STRING) { fmt += 'c'; @@ -683,6 +688,7 @@ void Fmt::emit_cxxrtl(std::ostream &os, std::string indent, std::function 0 && index % 4 == 0) + buf += '_'; + RTLIL::State bit = value[index]; + if (bit == State::Sx) + buf += 'x'; + else if (bit == State::Sz) + buf += 'z'; + else if (bit == State::S1) + buf += '1'; + else /* if (bit == State::S0) */ + buf += '0'; + } if (part.show_base) - buf += "0b"; - buf = value.as_string(); + buf += "b0"; + std::reverse(buf.begin(), buf.end()); } else if (part.base == 8 || part.base == 16) { size_t step = (part.base == 16) ? 4 : 3; for (size_t index = 0; index < (size_t)value.size(); index += step) { + if (part.group && index > 0 && index % (4 * step) == 0) + buf += '_'; RTLIL::Const subvalue = value.extract(index, min(step, value.size() - index)); bool has_x = false, all_x = true, has_z = false, all_z = true; for (State bit : subvalue) { @@ -799,9 +820,13 @@ std::string Fmt::render() const log_assert(absvalue.is_fully_def()); if (absvalue.is_fully_zero()) buf += '0'; + size_t index = 0; while (!absvalue.is_fully_zero()) { + if (part.group && index > 0 && index % 3 == 0) + buf += '_'; buf += '0' + RTLIL::const_mod(absvalue, 10, false, false, 4).as_int(); absvalue = RTLIL::const_div(absvalue, 10, false, false, absvalue.size()); + index++; } if (part.show_base) buf += "d0"; diff --git a/kernel/fmt.h b/kernel/fmt.h index 10b1711f19a..2d4b24979b2 100644 --- a/kernel/fmt.h +++ b/kernel/fmt.h @@ -85,6 +85,7 @@ struct FmtPart { } sign = MINUS; bool hex_upper = false; bool show_base = false; + bool group = false; // VLOG_TIME type bool realtime = false; From ddf7b469559b976225fc35bea340383bcf5c5097 Mon Sep 17 00:00:00 2001 From: Catherine Date: Thu, 28 Mar 2024 09:45:10 +0000 Subject: [PATCH 44/76] fmt,cxxrtl: fix printing of non-decimal signed numbers. Also fix interaction of `NUMERIC` justification with `show_base`. --- backends/cxxrtl/runtime/cxxrtl/cxxrtl.h | 67 ++++++++++------ kernel/fmt.cc | 101 ++++++++++++++---------- 2 files changed, 100 insertions(+), 68 deletions(-) diff --git a/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h b/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h index 31085b74554..da107e03736 100644 --- a/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h @@ -1058,6 +1058,7 @@ struct fmt_part { // We might want to replace some of these bit() calls with direct // chunk access if it turns out to be slow enough to matter. std::string buf; + std::string prefix; switch (type) { case LITERAL: return str; @@ -1096,24 +1097,38 @@ struct fmt_part { } case INTEGER: { + bool negative = signed_ && val.is_neg(); + if (negative) { + prefix = "-"; + val = val.neg(); + } else { + switch (sign) { + case MINUS: break; + case PLUS_MINUS: prefix = "+"; break; + case SPACE_MINUS: prefix = " "; break; + } + } + size_t width = Bits; if (base != 10) { - width = 0; + width = 1; for (size_t index = 0; index < Bits; index++) if (val.bit(index)) width = index + 1; } if (base == 2) { + if (show_base) + prefix += "0b"; for (size_t index = 0; index < width; index++) { if (group && index > 0 && index % 4 == 0) buf += '_'; buf += (val.bit(index) ? '1' : '0'); } - if (show_base) - buf += "b0"; std::reverse(buf.begin(), buf.end()); } else if (base == 8 || base == 16) { + if (show_base) + prefix += (base == 16) ? (hex_upper ? "0X" : "0x") : "0o"; size_t step = (base == 16) ? 4 : 3; for (size_t index = 0; index < width; index += step) { if (group && index > 0 && index % (4 * step) == 0) @@ -1123,13 +1138,10 @@ struct fmt_part { value |= val.bit(index + 3) << 3; buf += (hex_upper ? "0123456789ABCDEF" : "0123456789abcdef")[value]; } - if (show_base) - buf += (base == 16) ? (hex_upper ? "X0" : "x0") : "o0"; std::reverse(buf.begin(), buf.end()); } else if (base == 10) { - bool negative = signed_ && val.is_neg(); - if (negative) - val = val.neg(); + if (show_base) + prefix += "0d"; if (val.is_zero()) buf += '0'; value<(Bits > 4 ? Bits : 4)> xval = val.template zext<(Bits > 4 ? Bits : 4)>(); @@ -1146,13 +1158,6 @@ struct fmt_part { xval = quotient; index++; } - if (show_base) - buf += "d0"; - switch (sign) { - case MINUS: buf += negative ? "-" : ""; break; - case PLUS_MINUS: buf += negative ? "-" : "+"; break; - case SPACE_MINUS: buf += negative ? "-" : " "; break; - } std::reverse(buf.begin(), buf.end()); } else assert(false && "Unsupported base for fmt_part"); break; @@ -1170,17 +1175,29 @@ struct fmt_part { std::string str; assert(width == 0 || padding != '\0'); - if (justify != LEFT && buf.size() < width) { - size_t pad_width = width - buf.size(); - if (justify == NUMERIC && (buf.front() == '+' || buf.front() == '-' || buf.front() == ' ')) { - str += buf.front(); - buf.erase(0, 1); - } - str += std::string(pad_width, padding); + if (prefix.size() + buf.size() < width) { + size_t pad_width = width - prefix.size() - buf.size(); + switch (justify) { + case LEFT: + str += prefix; + str += buf; + str += std::string(pad_width, padding); + break; + case RIGHT: + str += std::string(pad_width, padding); + str += prefix; + str += buf; + break; + case NUMERIC: + str += prefix; + str += std::string(pad_width, padding); + str += buf; + break; + } + } else { + str += prefix; + str += buf; } - str += buf; - if (justify == LEFT && buf.size() < width) - str += std::string(width - buf.size(), padding); return str; } }; diff --git a/kernel/fmt.cc b/kernel/fmt.cc index f5793d796f2..f70f6d3902c 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -491,6 +491,8 @@ void Fmt::parse_verilog(const std::vector &args, bool sformat_lik if (part.type == FmtPart::INTEGER && part.base != 10 && part.sign != FmtPart::MINUS) log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with invalid format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1); + if (part.base != 10) + part.signed_ = false; if (part.type == FmtPart::INTEGER && !has_leading_zero) apply_verilog_automatic_sizing_and_add(part); else @@ -731,11 +733,34 @@ std::string Fmt::render() const case FmtPart::STRING: case FmtPart::VLOG_TIME: { std::string buf; + std::string prefix; if (part.type == FmtPart::INTEGER) { RTLIL::Const value = part.sig.as_const(); + bool has_x = false, all_x = true, has_z = false, all_z = true; + for (State bit : value) { + if (bit == State::Sx) + has_x = true; + else + all_x = false; + if (bit == State::Sz) + has_z = true; + else + all_z = false; + } + + if (!has_z && !has_x && part.signed_ && value[value.size() - 1]) { + prefix = "-"; + value = RTLIL::const_neg(value, {}, part.signed_, {}, value.size() + 1); + } else { + switch (part.sign) { + case FmtPart::MINUS: break; + case FmtPart::PLUS_MINUS: prefix = "+"; break; + case FmtPart::SPACE_MINUS: prefix = " "; break; + } + } if (part.base != 10) { - size_t minimum_size = 0; + size_t minimum_size = 1; for (size_t index = 0; index < (size_t)value.size(); index++) if (value[index] != State::S0) minimum_size = index + 1; @@ -743,6 +768,8 @@ std::string Fmt::render() const } if (part.base == 2) { + if (part.show_base) + prefix += "0b"; for (size_t index = 0; index < (size_t)value.size(); index++) { if (part.group && index > 0 && index % 4 == 0) buf += '_'; @@ -756,10 +783,10 @@ std::string Fmt::render() const else /* if (bit == State::S0) */ buf += '0'; } - if (part.show_base) - buf += "b0"; std::reverse(buf.begin(), buf.end()); } else if (part.base == 8 || part.base == 16) { + if (part.show_base) + prefix += (part.base == 16) ? (part.hex_upper ? "0X" : "0x") : "0o"; size_t step = (part.base == 16) ? 4 : 3; for (size_t index = 0; index < (size_t)value.size(); index += step) { if (part.group && index > 0 && index % (4 * step) == 0) @@ -787,21 +814,10 @@ std::string Fmt::render() const else buf += (part.hex_upper ? "0123456789ABCDEF" : "0123456789abcdef")[subvalue.as_int()]; } - if (part.show_base) - buf += (part.base == 16) ? (part.hex_upper ? "X0" : "x0") : "o0"; std::reverse(buf.begin(), buf.end()); } else if (part.base == 10) { - bool has_x = false, all_x = true, has_z = false, all_z = true; - for (State bit : value) { - if (bit == State::Sx) - has_x = true; - else - all_x = false; - if (bit == State::Sz) - has_z = true; - else - all_z = false; - } + if (part.show_base) + prefix += "0d"; if (all_x) buf += 'x'; else if (all_z) @@ -811,30 +827,17 @@ std::string Fmt::render() const else if (has_z) buf += 'Z'; else { - bool negative = part.signed_ && value[value.size() - 1]; - RTLIL::Const absvalue; - if (negative) - absvalue = RTLIL::const_neg(value, {}, part.signed_, {}, value.size() + 1); - else - absvalue = value; - log_assert(absvalue.is_fully_def()); - if (absvalue.is_fully_zero()) + log_assert(value.is_fully_def()); + if (value.is_fully_zero()) buf += '0'; size_t index = 0; - while (!absvalue.is_fully_zero()) { + while (!value.is_fully_zero()) { if (part.group && index > 0 && index % 3 == 0) buf += '_'; - buf += '0' + RTLIL::const_mod(absvalue, 10, false, false, 4).as_int(); - absvalue = RTLIL::const_div(absvalue, 10, false, false, absvalue.size()); + buf += '0' + RTLIL::const_mod(value, 10, false, false, 4).as_int(); + value = RTLIL::const_div(value, 10, false, false, value.size()); index++; } - if (part.show_base) - buf += "d0"; - switch (part.sign) { - case FmtPart::MINUS: buf += negative ? "-" : ""; break; - case FmtPart::PLUS_MINUS: buf += negative ? "-" : "+"; break; - case FmtPart::SPACE_MINUS: buf += negative ? "-" : " "; break; - } std::reverse(buf.begin(), buf.end()); } } else log_abort(); @@ -846,17 +849,29 @@ std::string Fmt::render() const } log_assert(part.width == 0 || part.padding != '\0'); - if (part.justify != FmtPart::LEFT && buf.size() < part.width) { - size_t pad_width = part.width - buf.size(); - if (part.justify == FmtPart::NUMERIC && (!buf.empty() && (buf.front() == '+' || buf.front() == '-' || buf.front() == ' '))) { - str += buf.front(); - buf.erase(0, 1); + if (prefix.size() + buf.size() < part.width) { + size_t pad_width = part.width - prefix.size() - buf.size(); + switch (part.justify) { + case FmtPart::LEFT: + str += prefix; + str += buf; + str += std::string(pad_width, part.padding); + break; + case FmtPart::RIGHT: + str += std::string(pad_width, part.padding); + str += prefix; + str += buf; + break; + case FmtPart::NUMERIC: + str += prefix; + str += std::string(pad_width, part.padding); + str += buf; + break; } - str += std::string(pad_width, part.padding); + } else { + str += prefix; + str += buf; } - str += buf; - if (part.justify == FmtPart::LEFT && buf.size() < part.width) - str += std::string(part.width - buf.size(), part.padding); break; } } From 27cb4c52b4cffd049dc825865852af75867fce11 Mon Sep 17 00:00:00 2001 From: Catherine Date: Thu, 28 Mar 2024 09:52:59 +0000 Subject: [PATCH 45/76] fmt: allow padding characters other than `'0'` and `' '`. When converted to Verilog, padding characters are replaced with one of these two. Otherwise padding is performed with exactly that character. --- kernel/fmt.cc | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/kernel/fmt.cc b/kernel/fmt.cc index f70f6d3902c..43d8feddfa4 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -91,10 +91,7 @@ void Fmt::parse_rtlil(const RTLIL::Cell *cell) { if (++i == fmt.size()) log_assert(false && "Unexpected end in format substitution"); - if (fmt[i] == '0' || fmt[i] == ' ') - part.padding = fmt[i]; - else - log_assert(false && "Unexpected padding in format substitution"); + part.padding = fmt[i]; if (++i == fmt.size()) log_assert(false && "Unexpected end in format substitution"); @@ -550,7 +547,6 @@ std::vector Fmt::emit_verilog() const if (part.width == 0) { fmt.str += '0'; } else if (part.width > 0) { - log_assert(part.padding == ' ' || part.padding == '0'); if (part.base != 10 || part.padding == '0') fmt.str += '0'; fmt.str += std::to_string(part.width); @@ -576,7 +572,6 @@ std::vector Fmt::emit_verilog() const fmt.str += '-'; if (part.sig.size() == 8) { if (part.width > 0) { - log_assert(part.padding == '0' || part.padding == ' '); if (part.padding == '0') fmt.str += part.padding; fmt.str += std::to_string(part.width); @@ -585,7 +580,6 @@ std::vector Fmt::emit_verilog() const } else { log_assert(part.sig.size() % 8 == 0); if (part.width > 0) { - log_assert(part.padding == ' '); // no zero padding fmt.str += std::to_string(part.width); } fmt.str += 's'; @@ -616,7 +610,6 @@ std::vector Fmt::emit_verilog() const fmt.str += '+'; if (part.justify == FmtPart::LEFT) fmt.str += '-'; - log_assert(part.padding == ' ' || part.padding == '0'); if (part.padding == '0' && part.width > 0) fmt.str += '0'; fmt.str += std::to_string(part.width); From 94170388a9acd639474387de14dfe7145d8436ee Mon Sep 17 00:00:00 2001 From: Catherine Date: Thu, 28 Mar 2024 10:06:18 +0000 Subject: [PATCH 46/76] fmt: if enabled, group padding zeroes. Before this commit, the combination of `_` and `0` format characters would produce a result like `000000001010_1010`. After this commit, it would be `0000_0000_1010_1010`. This has a slight quirk where a format like `{:020_b}` results in the output `0_0000_0000_1010_1010`, which is one character longer than requested. Python has the same behavior, and it's not clear what would be strictly speaking correct, so Python behavior is implemented. --- backends/cxxrtl/runtime/cxxrtl/cxxrtl.h | 22 ++++++++++++++-------- kernel/fmt.cc | 12 +++++++++--- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h b/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h index da107e03736..8546a841189 100644 --- a/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h @@ -1109,28 +1109,27 @@ struct fmt_part { } } - size_t width = Bits; + size_t val_width = Bits; if (base != 10) { - width = 1; + val_width = 1; for (size_t index = 0; index < Bits; index++) if (val.bit(index)) - width = index + 1; + val_width = index + 1; } if (base == 2) { if (show_base) prefix += "0b"; - for (size_t index = 0; index < width; index++) { + for (size_t index = 0; index < val_width; index++) { if (group && index > 0 && index % 4 == 0) buf += '_'; buf += (val.bit(index) ? '1' : '0'); } - std::reverse(buf.begin(), buf.end()); } else if (base == 8 || base == 16) { if (show_base) prefix += (base == 16) ? (hex_upper ? "0X" : "0x") : "0o"; size_t step = (base == 16) ? 4 : 3; - for (size_t index = 0; index < width; index += step) { + for (size_t index = 0; index < val_width; index += step) { if (group && index > 0 && index % (4 * step) == 0) buf += '_'; uint8_t value = val.bit(index) | (val.bit(index + 1) << 1) | (val.bit(index + 2) << 2); @@ -1138,7 +1137,6 @@ struct fmt_part { value |= val.bit(index + 3) << 3; buf += (hex_upper ? "0123456789ABCDEF" : "0123456789abcdef")[value]; } - std::reverse(buf.begin(), buf.end()); } else if (base == 10) { if (show_base) prefix += "0d"; @@ -1158,8 +1156,16 @@ struct fmt_part { xval = quotient; index++; } - std::reverse(buf.begin(), buf.end()); } else assert(false && "Unsupported base for fmt_part"); + if (justify == NUMERIC && group && padding == '0') { + int group_size = base == 10 ? 3 : 4; + while (prefix.size() + buf.size() < width) { + if (buf.size() % (group_size + 1) == group_size) + buf += '_'; + buf += '0'; + } + } + std::reverse(buf.begin(), buf.end()); break; } diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 43d8feddfa4..cbf2d12e9ac 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -776,7 +776,6 @@ std::string Fmt::render() const else /* if (bit == State::S0) */ buf += '0'; } - std::reverse(buf.begin(), buf.end()); } else if (part.base == 8 || part.base == 16) { if (part.show_base) prefix += (part.base == 16) ? (part.hex_upper ? "0X" : "0x") : "0o"; @@ -807,7 +806,6 @@ std::string Fmt::render() const else buf += (part.hex_upper ? "0123456789ABCDEF" : "0123456789abcdef")[subvalue.as_int()]; } - std::reverse(buf.begin(), buf.end()); } else if (part.base == 10) { if (part.show_base) prefix += "0d"; @@ -831,9 +829,17 @@ std::string Fmt::render() const value = RTLIL::const_div(value, 10, false, false, value.size()); index++; } - std::reverse(buf.begin(), buf.end()); } } else log_abort(); + if (part.justify == FmtPart::NUMERIC && part.group && part.padding == '0') { + int group_size = part.base == 10 ? 3 : 4; + while (prefix.size() + buf.size() < part.width) { + if (buf.size() % (group_size + 1) == group_size) + buf += '_'; + buf += '0'; + } + } + std::reverse(buf.begin(), buf.end()); } else if (part.type == FmtPart::STRING) { buf = part.sig.as_const().decode_string(); } else if (part.type == FmtPart::VLOG_TIME) { From cb077101622683716c93707be4c89106ae161359 Mon Sep 17 00:00:00 2001 From: Catherine Date: Tue, 2 Apr 2024 11:26:58 +0000 Subject: [PATCH 47/76] write_verilog: only warn on processes with sync rules. Processes without sync rules correspond to simple decision trees that directly correspond to `always @*` or `always_comb` blocks in Verilog, and do not need a warning. This removes the need to suppress warnings during the RTLIL-to-Verilog conversion performed by Amaranth. --- backends/verilog/verilog_backend.cc | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 05b7c6c4008..a09ae984b3e 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -1070,7 +1070,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) f << stringf(";\n"); return true; } - + if (cell->type == ID($_BUF_)) { f << stringf("%s" "assign ", indent.c_str()); dump_sigspec(f, cell->getPort(ID::Y)); @@ -2276,11 +2276,15 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) active_initdata[sig[i]] = val[i]; } - if (!module->processes.empty()) - log_warning("Module %s contains unmapped RTLIL processes. RTLIL processes\n" - "can't always be mapped directly to Verilog always blocks. Unintended\n" - "changes in simulation behavior are possible! Use \"proc\" to convert\n" - "processes to logic networks and registers.\n", log_id(module)); + bool has_sync_rules = false; + for (auto process : module->processes) + if (!process.second->syncs.empty()) + has_sync_rules = true; + if (has_sync_rules) + 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)); f << stringf("\n"); for (auto it = module->processes.begin(); it != module->processes.end(); ++it) From d8687e87b1f7286636d50c42dd281eb3e93e4898 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Tue, 2 Apr 2024 15:58:06 +0200 Subject: [PATCH 48/76] kernel: Avoid including files outside include guards This adjusts the way the headers kernel/{yosys,rtlil,register,log}.h include each other to avoid the need of including headers outside of include guards as well as avoiding the inclusion of rtlil.h in the middle of yosys.h with rtlil.h depending on the prefix of yosys.h, and the suffix of yosys.h depending on rtlil.h. To do this I moved some of the declaration in yosys.h into a new header yosys_common.h. I'm not sure if that is strictly necessary. Including any of these files still results in the declarations of all these headers being included, so this shouldn't be a breaking change for any passes or external plugins. My main motivation for this is that ccls's (clang based language server) include guard handling gets confused by the previous way the includes were done. It often ends up treating the include guard as a generic disabled preprocessor conditional, breaking navigation and highlighting for the core RTLIL data structures. Additionally I think avoiding cyclic includes in the middle of header files that depend on includes being outside of include guards will also be less confusing for developers reading the code, not only for tools like ccls. --- Makefile | 1 + kernel/log.h | 6 +- kernel/register.h | 5 +- kernel/rtlil.h | 5 +- kernel/yosys.h | 346 +------------------------------------- kernel/yosys_common.h | 379 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 391 insertions(+), 351 deletions(-) create mode 100644 kernel/yosys_common.h diff --git a/Makefile b/Makefile index ca229ca4a52..b62b78fb15b 100644 --- a/Makefile +++ b/Makefile @@ -629,6 +629,7 @@ $(eval $(call add_include_file,kernel/sigtools.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)) diff --git a/kernel/log.h b/kernel/log.h index e4f06c69d19..53aae58c6bc 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -17,11 +17,11 @@ * */ -#include "kernel/yosys.h" - #ifndef LOG_H #define LOG_H +#include "kernel/yosys_common.h" + #include #include @@ -449,4 +449,6 @@ void log_dump_args_worker(const char *p, T first, Args ... args) YOSYS_NAMESPACE_END +#include "kernel/yosys.h" + #endif diff --git a/kernel/register.h b/kernel/register.h index 08ce4b28787..25ea9f2321c 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -17,11 +17,12 @@ * */ -#include "kernel/yosys.h" - #ifndef REGISTER_H #define REGISTER_H +#include "kernel/yosys_common.h" +#include "kernel/yosys.h" + YOSYS_NAMESPACE_BEGIN struct Pass diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 40422dce56d..f9da2949508 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -17,11 +17,12 @@ * */ -#include "kernel/yosys.h" - #ifndef RTLIL_H #define RTLIL_H +#include "kernel/yosys_common.h" +#include "kernel/yosys.h" + YOSYS_NAMESPACE_BEGIN namespace RTLIL diff --git a/kernel/yosys.h b/kernel/yosys.h index 0a4641d1819..5922d9ab752 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -39,323 +39,7 @@ #ifndef YOSYS_H #define YOSYS_H -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef WITH_PYTHON -#include -#endif - -#ifndef _YOSYS_ -# error It looks like you are trying to build Yosys without the config defines set. \ - When building Yosys with a custom make system, make sure you set all the \ - defines the Yosys Makefile would set for your build configuration. -#endif - -#ifdef YOSYS_ENABLE_TCL -# include -# ifdef YOSYS_MXE_HACKS -extern Tcl_Command Tcl_CreateCommand(Tcl_Interp *interp, const char *cmdName, Tcl_CmdProc *proc, ClientData clientData, Tcl_CmdDeleteProc *deleteProc); -extern Tcl_Interp *Tcl_CreateInterp(void); -extern void Tcl_Preserve(ClientData data); -extern void Tcl_Release(ClientData clientData); -extern int Tcl_InterpDeleted(Tcl_Interp *interp); -extern void Tcl_DeleteInterp(Tcl_Interp *interp); -extern int Tcl_Eval(Tcl_Interp *interp, const char *script); -extern int Tcl_EvalFile(Tcl_Interp *interp, const char *fileName); -extern void Tcl_Finalize(void); -extern int Tcl_GetCommandInfo(Tcl_Interp *interp, const char *cmdName, Tcl_CmdInfo *infoPtr); -extern const char *Tcl_GetStringResult(Tcl_Interp *interp); -extern Tcl_Obj *Tcl_NewStringObj(const char *bytes, int length); -extern Tcl_Obj *Tcl_NewIntObj(int intValue); -extern Tcl_Obj *Tcl_NewListObj(int objc, Tcl_Obj *const objv[]); -extern Tcl_Obj *Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, int flags); -# endif -# undef CONST -# undef INLINE -#endif - -#ifdef _WIN32 -# undef NOMINMAX -# define NOMINMAX 1 -# undef YY_NO_UNISTD_H -# define YY_NO_UNISTD_H 1 - -# include -# include -# include - -# define strtok_r strtok_s -# define strdup _strdup -# define snprintf _snprintf -# define getcwd _getcwd -# define mkdir _mkdir -# define popen _popen -# define pclose _pclose - -# ifndef __MINGW32__ -# define PATH_MAX MAX_PATH -# define isatty _isatty -# define fileno _fileno -# endif - -// The following defines conflict with our identifiers: -# undef CONST -// `wingdi.h` defines a TRANSPARENT macro that conflicts with X(TRANSPARENT) entry in kernel/constids.inc -# undef TRANSPARENT -#endif - -#ifndef PATH_MAX -# define PATH_MAX 4096 -#endif - -#define YOSYS_NAMESPACE Yosys -#define PRIVATE_NAMESPACE_BEGIN namespace { -#define PRIVATE_NAMESPACE_END } -#define YOSYS_NAMESPACE_BEGIN namespace Yosys { -#define YOSYS_NAMESPACE_END } -#define YOSYS_NAMESPACE_PREFIX Yosys:: -#define USING_YOSYS_NAMESPACE using namespace Yosys; - -#if defined(__GNUC__) || defined(__clang__) -# define YS_ATTRIBUTE(...) __attribute__((__VA_ARGS__)) -#elif defined(_MSC_VER) -# define YS_ATTRIBUTE(...) -#else -# define YS_ATTRIBUTE(...) -#endif - -#if defined(__GNUC__) || defined(__clang__) -# define YS_MAYBE_UNUSED __attribute__((__unused__)) -#else -# define YS_MAYBE_UNUSED -#endif - -#if __cplusplus >= 201703L -# define YS_FALLTHROUGH [[fallthrough]]; -#elif defined(__clang__) -# define YS_FALLTHROUGH [[clang::fallthrough]]; -#elif defined(__GNUC__) -# define YS_FALLTHROUGH [[gnu::fallthrough]]; -#else -# define YS_FALLTHROUGH -#endif - -YOSYS_NAMESPACE_BEGIN - -// Note: All headers included in hashlib.h must be included -// outside of YOSYS_NAMESPACE before this or bad things will happen. -#ifdef HASHLIB_H -# undef HASHLIB_H -# include "kernel/hashlib.h" -#else -# include "kernel/hashlib.h" -# undef HASHLIB_H -#endif - -using std::vector; -using std::string; -using std::tuple; -using std::pair; - -using std::make_tuple; -using std::make_pair; -using std::get; -using std::min; -using std::max; - -// A primitive shared string implementation that does not -// move its .c_str() when the object is copied or moved. -struct shared_str { - std::shared_ptr content; - shared_str() { } - shared_str(string s) { content = std::shared_ptr(new string(s)); } - shared_str(const char *s) { content = std::shared_ptr(new string(s)); } - const char *c_str() const { return content->c_str(); } - const string &str() const { return *content; } - bool operator==(const shared_str &other) const { return *content == *other.content; } - unsigned int hash() const { return hashlib::hash_ops::hash(*content); } -}; - -using hashlib::mkhash; -using hashlib::mkhash_init; -using hashlib::mkhash_add; -using hashlib::mkhash_xorshift; -using hashlib::hash_ops; -using hashlib::hash_cstr_ops; -using hashlib::hash_ptr_ops; -using hashlib::hash_obj_ops; -using hashlib::dict; -using hashlib::idict; -using hashlib::pool; -using hashlib::mfp; - -namespace RTLIL { - struct IdString; - struct Const; - struct SigBit; - struct SigSpec; - struct Wire; - struct Cell; - struct Memory; - struct Process; - struct Module; - struct Design; - struct Monitor; - enum State : unsigned char; -} - -namespace AST { - struct AstNode; -} - -using RTLIL::IdString; -using RTLIL::Const; -using RTLIL::SigBit; -using RTLIL::SigSpec; -using RTLIL::Wire; -using RTLIL::Cell; -using RTLIL::Module; -using RTLIL::Design; - -namespace hashlib { - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; - - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; -} - -void memhasher_on(); -void memhasher_off(); -void memhasher_do(); - -extern bool memhasher_active; -inline void memhasher() { if (memhasher_active) memhasher_do(); } - -void yosys_banner(); -int ceil_log2(int x) YS_ATTRIBUTE(const); - -inline std::string vstringf(const char *fmt, va_list ap) -{ - // For the common case of strings shorter than 128, save a heap - // allocation by using a stack allocated buffer. - const int kBufSize = 128; - char buf[kBufSize]; - buf[0] = '\0'; - va_list apc; - va_copy(apc, ap); - int n = vsnprintf(buf, kBufSize, fmt, apc); - va_end(apc); - if (n < kBufSize) - return std::string(buf); - - std::string string; - char *str = NULL; -#if defined(_WIN32 )|| defined(__CYGWIN__) - int sz = 2 * kBufSize, rc; - while (1) { - va_copy(apc, ap); - str = (char*)realloc(str, sz); - rc = vsnprintf(str, sz, fmt, apc); - va_end(apc); - if (rc >= 0 && rc < sz) - break; - sz *= 2; - } - if (str != NULL) { - string = str; - free(str); - } - return string; -#else - if (vasprintf(&str, fmt, ap) < 0) - str = NULL; - if (str != NULL) { - string = str; - free(str); - } - return string; -#endif -} - -std::string stringf(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 1, 2)); - -inline std::string stringf(const char *fmt, ...) -{ - std::string string; - va_list ap; - - va_start(ap, fmt); - string = vstringf(fmt, ap); - va_end(ap); - - return string; -} - -int readsome(std::istream &f, char *s, int n); -std::string next_token(std::string &text, const char *sep = " \t\r\n", bool long_strings = false); -std::vector split_tokens(const std::string &text, const char *sep = " \t\r\n"); -bool patmatch(const char *pattern, const char *string); -#if !defined(YOSYS_DISABLE_SPAWN) -int run_command(const std::string &command, std::function process_line = std::function()); -#endif -std::string get_base_tmpdir(); -std::string make_temp_file(std::string template_str = get_base_tmpdir() + "/yosys_XXXXXX"); -std::string make_temp_dir(std::string template_str = get_base_tmpdir() + "/yosys_XXXXXX"); -bool check_file_exists(std::string filename, bool is_exec = false); -bool check_directory_exists(const std::string& dirname); -bool is_absolute_path(std::string filename); -void remove_directory(std::string dirname); -bool create_directory(const std::string& dirname); -std::string escape_filename_spaces(const std::string& filename); - -template int GetSize(const T &obj) { return obj.size(); } -inline int GetSize(RTLIL::Wire *wire); - -extern int autoidx; -extern int yosys_xtrace; - -YOSYS_NAMESPACE_END +#include "kernel/yosys_common.h" #include "kernel/log.h" #include "kernel/rtlil.h" @@ -363,14 +47,6 @@ YOSYS_NAMESPACE_END YOSYS_NAMESPACE_BEGIN -using RTLIL::State; -using RTLIL::SigChunk; -using RTLIL::SigSig; - -namespace hashlib { - template<> struct hash_ops : hash_ops {}; -} - void yosys_setup(); #ifdef WITH_PYTHON @@ -385,26 +61,6 @@ Tcl_Interp *yosys_get_tcl_interp(); extern RTLIL::Design *yosys_design; -RTLIL::IdString new_id(std::string file, int line, std::string func); -RTLIL::IdString new_id_suffix(std::string file, int line, std::string func, std::string suffix); - -#define NEW_ID \ - YOSYS_NAMESPACE_PREFIX new_id(__FILE__, __LINE__, __FUNCTION__) -#define NEW_ID_SUFFIX(suffix) \ - YOSYS_NAMESPACE_PREFIX new_id_suffix(__FILE__, __LINE__, __FUNCTION__, suffix) - -// Create a statically allocated IdString object, using for example ID::A or ID($add). -// -// Recipe for Converting old code that is using conversion of strings like ID::A and -// "$add" for creating IdStrings: Run below SED command on the .cc file and then use for -// example "meld foo.cc foo.cc.orig" to manually compile errors, if necessary. -// -// sed -i.orig -r 's/"\\\\([a-zA-Z0-9_]+)"/ID(\1)/g; s/"(\$[a-zA-Z0-9_]+)"/ID(\1)/g;' -// -#define ID(_id) ([]() { const char *p = "\\" #_id, *q = p[1] == '$' ? p+1 : p; \ - static const YOSYS_NAMESPACE_PREFIX RTLIL::IdString id(q); return id; })() -namespace ID = RTLIL::ID; - RTLIL::Design *yosys_get_design(); std::string proc_self_dirname(); std::string proc_share_dirname(); diff --git a/kernel/yosys_common.h b/kernel/yosys_common.h new file mode 100644 index 00000000000..9f1bc2f58d7 --- /dev/null +++ b/kernel/yosys_common.h @@ -0,0 +1,379 @@ +/* -*- c++ -*- + * 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. + * + */ + +#ifndef YOSYS_COMMON_H +#define YOSYS_COMMON_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef WITH_PYTHON +#include +#endif + +#ifndef _YOSYS_ +# error It looks like you are trying to build Yosys without the config defines set. \ + When building Yosys with a custom make system, make sure you set all the \ + defines the Yosys Makefile would set for your build configuration. +#endif + +#ifdef YOSYS_ENABLE_TCL +# include +# ifdef YOSYS_MXE_HACKS +extern Tcl_Command Tcl_CreateCommand(Tcl_Interp *interp, const char *cmdName, Tcl_CmdProc *proc, ClientData clientData, Tcl_CmdDeleteProc *deleteProc); +extern Tcl_Interp *Tcl_CreateInterp(void); +extern void Tcl_Preserve(ClientData data); +extern void Tcl_Release(ClientData clientData); +extern int Tcl_InterpDeleted(Tcl_Interp *interp); +extern void Tcl_DeleteInterp(Tcl_Interp *interp); +extern int Tcl_Eval(Tcl_Interp *interp, const char *script); +extern int Tcl_EvalFile(Tcl_Interp *interp, const char *fileName); +extern void Tcl_Finalize(void); +extern int Tcl_GetCommandInfo(Tcl_Interp *interp, const char *cmdName, Tcl_CmdInfo *infoPtr); +extern const char *Tcl_GetStringResult(Tcl_Interp *interp); +extern Tcl_Obj *Tcl_NewStringObj(const char *bytes, int length); +extern Tcl_Obj *Tcl_NewIntObj(int intValue); +extern Tcl_Obj *Tcl_NewListObj(int objc, Tcl_Obj *const objv[]); +extern Tcl_Obj *Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, int flags); +# endif +# undef CONST +# undef INLINE +#endif + +#ifdef _WIN32 +# undef NOMINMAX +# define NOMINMAX 1 +# undef YY_NO_UNISTD_H +# define YY_NO_UNISTD_H 1 + +# include +# include +# include + +# define strtok_r strtok_s +# define strdup _strdup +# define snprintf _snprintf +# define getcwd _getcwd +# define mkdir _mkdir +# define popen _popen +# define pclose _pclose + +# ifndef __MINGW32__ +# define PATH_MAX MAX_PATH +# define isatty _isatty +# define fileno _fileno +# endif + +// The following defines conflict with our identifiers: +# undef CONST +// `wingdi.h` defines a TRANSPARENT macro that conflicts with X(TRANSPARENT) entry in kernel/constids.inc +# undef TRANSPARENT +#endif + +#ifndef PATH_MAX +# define PATH_MAX 4096 +#endif + + +#define YOSYS_NAMESPACE Yosys +#define PRIVATE_NAMESPACE_BEGIN namespace { +#define PRIVATE_NAMESPACE_END } +#define YOSYS_NAMESPACE_BEGIN namespace Yosys { +#define YOSYS_NAMESPACE_END } +#define YOSYS_NAMESPACE_PREFIX Yosys:: +#define USING_YOSYS_NAMESPACE using namespace Yosys; + +#if defined(__GNUC__) || defined(__clang__) +# define YS_ATTRIBUTE(...) __attribute__((__VA_ARGS__)) +#elif defined(_MSC_VER) +# define YS_ATTRIBUTE(...) +#else +# define YS_ATTRIBUTE(...) +#endif + +#if defined(__GNUC__) || defined(__clang__) +# define YS_MAYBE_UNUSED __attribute__((__unused__)) +#else +# define YS_MAYBE_UNUSED +#endif + +#if __cplusplus >= 201703L +# define YS_FALLTHROUGH [[fallthrough]]; +#elif defined(__clang__) +# define YS_FALLTHROUGH [[clang::fallthrough]]; +#elif defined(__GNUC__) +# define YS_FALLTHROUGH [[gnu::fallthrough]]; +#else +# define YS_FALLTHROUGH +#endif + + +YOSYS_NAMESPACE_BEGIN + +// Note: All headers included in hashlib.h must be included +// outside of YOSYS_NAMESPACE before this or bad things will happen. +#ifdef HASHLIB_H +# undef HASHLIB_H +# include "kernel/hashlib.h" +#else +# include "kernel/hashlib.h" +# undef HASHLIB_H +#endif + + +using std::vector; +using std::string; +using std::tuple; +using std::pair; + +using std::make_tuple; +using std::make_pair; +using std::get; +using std::min; +using std::max; + +// A primitive shared string implementation that does not +// move its .c_str() when the object is copied or moved. +struct shared_str { + std::shared_ptr content; + shared_str() { } + shared_str(string s) { content = std::shared_ptr(new string(s)); } + shared_str(const char *s) { content = std::shared_ptr(new string(s)); } + const char *c_str() const { return content->c_str(); } + const string &str() const { return *content; } + bool operator==(const shared_str &other) const { return *content == *other.content; } + unsigned int hash() const { return hashlib::hash_ops::hash(*content); } +}; + +using hashlib::mkhash; +using hashlib::mkhash_init; +using hashlib::mkhash_add; +using hashlib::mkhash_xorshift; +using hashlib::hash_ops; +using hashlib::hash_cstr_ops; +using hashlib::hash_ptr_ops; +using hashlib::hash_obj_ops; +using hashlib::dict; +using hashlib::idict; +using hashlib::pool; +using hashlib::mfp; + +namespace RTLIL { + struct IdString; + struct Const; + struct SigBit; + struct SigSpec; + struct Wire; + struct Cell; + struct Memory; + struct Process; + struct Module; + struct Design; + struct Monitor; + struct Selection; + struct SigChunk; + enum State : unsigned char; + + typedef std::pair SigSig; + + namespace ID {} +} + +namespace AST { + struct AstNode; +} + +using RTLIL::IdString; +using RTLIL::Const; +using RTLIL::SigBit; +using RTLIL::SigSpec; +using RTLIL::Wire; +using RTLIL::Cell; +using RTLIL::Module; +using RTLIL::Design; + +using RTLIL::State; +using RTLIL::SigChunk; +using RTLIL::SigSig; + +namespace hashlib { + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; +} + +void memhasher_on(); +void memhasher_off(); +void memhasher_do(); + +extern bool memhasher_active; +inline void memhasher() { if (memhasher_active) memhasher_do(); } + +void yosys_banner(); +int ceil_log2(int x) YS_ATTRIBUTE(const); + +inline std::string vstringf(const char *fmt, va_list ap) +{ + // For the common case of strings shorter than 128, save a heap + // allocation by using a stack allocated buffer. + const int kBufSize = 128; + char buf[kBufSize]; + buf[0] = '\0'; + va_list apc; + va_copy(apc, ap); + int n = vsnprintf(buf, kBufSize, fmt, apc); + va_end(apc); + if (n < kBufSize) + return std::string(buf); + + std::string string; + char *str = NULL; +#if defined(_WIN32 )|| defined(__CYGWIN__) + int sz = 2 * kBufSize, rc; + while (1) { + va_copy(apc, ap); + str = (char*)realloc(str, sz); + rc = vsnprintf(str, sz, fmt, apc); + va_end(apc); + if (rc >= 0 && rc < sz) + break; + sz *= 2; + } + if (str != NULL) { + string = str; + free(str); + } + return string; +#else + if (vasprintf(&str, fmt, ap) < 0) + str = NULL; + if (str != NULL) { + string = str; + free(str); + } + return string; +#endif +} + +std::string stringf(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 1, 2)); + +inline std::string stringf(const char *fmt, ...) +{ + std::string string; + va_list ap; + + va_start(ap, fmt); + string = vstringf(fmt, ap); + va_end(ap); + + return string; +} + +int readsome(std::istream &f, char *s, int n); +std::string next_token(std::string &text, const char *sep = " \t\r\n", bool long_strings = false); +std::vector split_tokens(const std::string &text, const char *sep = " \t\r\n"); +bool patmatch(const char *pattern, const char *string); +#if !defined(YOSYS_DISABLE_SPAWN) +int run_command(const std::string &command, std::function process_line = std::function()); +#endif +std::string get_base_tmpdir(); +std::string make_temp_file(std::string template_str = get_base_tmpdir() + "/yosys_XXXXXX"); +std::string make_temp_dir(std::string template_str = get_base_tmpdir() + "/yosys_XXXXXX"); +bool check_file_exists(std::string filename, bool is_exec = false); +bool check_directory_exists(const std::string& dirname); +bool is_absolute_path(std::string filename); +void remove_directory(std::string dirname); +bool create_directory(const std::string& dirname); +std::string escape_filename_spaces(const std::string& filename); + +template int GetSize(const T &obj) { return obj.size(); } +inline int GetSize(RTLIL::Wire *wire); + +extern int autoidx; +extern int yosys_xtrace; + +RTLIL::IdString new_id(std::string file, int line, std::string func); +RTLIL::IdString new_id_suffix(std::string file, int line, std::string func, std::string suffix); + +#define NEW_ID \ + YOSYS_NAMESPACE_PREFIX new_id(__FILE__, __LINE__, __FUNCTION__) +#define NEW_ID_SUFFIX(suffix) \ + YOSYS_NAMESPACE_PREFIX new_id_suffix(__FILE__, __LINE__, __FUNCTION__, suffix) + +// Create a statically allocated IdString object, using for example ID::A or ID($add). +// +// Recipe for Converting old code that is using conversion of strings like ID::A and +// "$add" for creating IdStrings: Run below SED command on the .cc file and then use for +// example "meld foo.cc foo.cc.orig" to manually compile errors, if necessary. +// +// sed -i.orig -r 's/"\\\\([a-zA-Z0-9_]+)"/ID(\1)/g; s/"(\$[a-zA-Z0-9_]+)"/ID(\1)/g;' +// +#define ID(_id) ([]() { const char *p = "\\" #_id, *q = p[1] == '$' ? p+1 : p; \ + static const YOSYS_NAMESPACE_PREFIX RTLIL::IdString id(q); return id; })() +namespace ID = RTLIL::ID; + +namespace hashlib { + template<> struct hash_ops : hash_ops {}; +} + + +YOSYS_NAMESPACE_END + +#endif From 040605b047e425341a484df3f2f986977834be10 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 3 Apr 2024 00:15:49 +0000 Subject: [PATCH 49/76] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ca229ca4a52..e31b722614b 100644 --- a/Makefile +++ b/Makefile @@ -142,7 +142,7 @@ LIBS += -lrt endif endif -YOSYS_VER := 0.39+149 +YOSYS_VER := 0.39+163 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 4bb3b099d23b07e0b4f8cf85e7b426be1538fafa Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Wed, 3 Apr 2024 10:02:53 +0200 Subject: [PATCH 50/76] opt_demorgan: fix extra args warning --- passes/opt/opt_demorgan.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/opt/opt_demorgan.cc b/passes/opt/opt_demorgan.cc index 1464c4177cd..4db3a810105 100644 --- a/passes/opt/opt_demorgan.cc +++ b/passes/opt/opt_demorgan.cc @@ -183,7 +183,7 @@ struct OptDemorganPass : public Pass { { log_header(design, "Executing OPT_DEMORGAN pass (push inverters through $reduce_* cells).\n"); - int argidx = 0; + int argidx = 1; extra_args(args, argidx, design); unsigned int cells_changed = 0; From d9a4a423899d8c3d90304440761e47d4664211db Mon Sep 17 00:00:00 2001 From: Catherine Date: Wed, 3 Apr 2024 08:01:58 +0000 Subject: [PATCH 51/76] write_verilog: don't `assign` to a `reg`. Fixes #2035. --- backends/verilog/verilog_backend.cc | 23 +++++++++++++++-------- tests/simple/.gitignore | 1 + tests/verilog/.gitignore | 4 ++++ tests/verilog/assign_to_reg.ys | 22 ++++++++++++++++++++++ 4 files changed, 42 insertions(+), 8 deletions(-) create mode 100644 tests/verilog/assign_to_reg.ys diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index a09ae984b3e..31bbc996ffa 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -2014,22 +2014,29 @@ void dump_sync_effect(std::ostream &f, std::string indent, const RTLIL::SigSpec void dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) { - if (simple_lhs) { + bool all_chunks_wires = true; + for (auto &chunk : left.chunks()) + if (chunk.is_wire() && reg_wires.count(chunk.wire->name)) + all_chunks_wires = false; + if (!simple_lhs && all_chunks_wires) { + f << stringf("%s" "assign ", indent.c_str()); + dump_sigspec(f, left); + f << stringf(" = "); + dump_sigspec(f, right); + f << stringf(";\n"); + } else { int offset = 0; for (auto &chunk : left.chunks()) { - f << stringf("%s" "assign ", indent.c_str()); + if (chunk.is_wire() && reg_wires.count(chunk.wire->name)) + f << stringf("%s" "always%s\n%s ", indent.c_str(), systemverilog ? "_comb" : " @*", indent.c_str()); + else + f << stringf("%s" "assign ", indent.c_str()); dump_sigspec(f, chunk); f << stringf(" = "); dump_sigspec(f, right.extract(offset, GetSize(chunk))); f << stringf(";\n"); offset += GetSize(chunk); } - } else { - f << stringf("%s" "assign ", indent.c_str()); - dump_sigspec(f, left); - f << stringf(" = "); - dump_sigspec(f, right); - f << stringf(";\n"); } } diff --git a/tests/simple/.gitignore b/tests/simple/.gitignore index 073f46157e1..5daaadbd734 100644 --- a/tests/simple/.gitignore +++ b/tests/simple/.gitignore @@ -1,2 +1,3 @@ *.log *.out +*.err diff --git a/tests/verilog/.gitignore b/tests/verilog/.gitignore index 96ebe20ba26..cfd72076e4e 100644 --- a/tests/verilog/.gitignore +++ b/tests/verilog/.gitignore @@ -1,6 +1,10 @@ /*.log /*.out +/*.err /run-test.mk /const_arst.v /const_sr.v /doubleslash.v +/roundtrip_proc_1.v +/roundtrip_proc_2.v +/assign_to_reg.v diff --git a/tests/verilog/assign_to_reg.ys b/tests/verilog/assign_to_reg.ys new file mode 100644 index 00000000000..80080e9f372 --- /dev/null +++ b/tests/verilog/assign_to_reg.ys @@ -0,0 +1,22 @@ +# https://github.com/yosyshq/yosys/issues/2035 + +read_ilang < Date: Wed, 3 Apr 2024 20:37:54 +0200 Subject: [PATCH 52/76] docs: Document $macc --- .../yosys_internals/formats/cell_library.rst | 48 ++++++++++++++++- techlibs/common/simlib.v | 51 +++++++++++++++++-- 2 files changed, 94 insertions(+), 5 deletions(-) diff --git a/docs/source/yosys_internals/formats/cell_library.rst b/docs/source/yosys_internals/formats/cell_library.rst index c80b0740255..a4e5adfb70a 100644 --- a/docs/source/yosys_internals/formats/cell_library.rst +++ b/docs/source/yosys_internals/formats/cell_library.rst @@ -619,6 +619,52 @@ Finite state machines Add a brief description of the ``$fsm`` cell type. +Coarse arithmetics +~~~~~~~~~~~~~~~~~~~~~ + +The ``$macc`` cell type represents a multiply and accumulate block, for summing any number of negated and unnegated signals and arithmetic products of pairs of signals. Cell port A concatenates pairs of signals to be multiplied together. When the second signal in a pair is zero length, a constant 1 is used instead as the second factor. Cell port B concatenates 1-bit-wide signals to also be summed, such as "carry in" in adders. + +The cell's ``CONFIG`` parameter determines the layout of cell port ``A``. +In the terms used for this cell, there's mixed meanings for the term "port". To disambiguate: +A cell port is for example the A input (it is constructed in C++ as ``cell->setPort(ID::A, ...))`` +Multiplier ports are pairs of multiplier inputs ("factors"). +If the second signal in such a pair is zero length, no multiplication is necessary, and the first signal is just added to the sum. + +In this pseudocode, ``u(foo)`` means an unsigned int that's foo bits long. +The CONFIG parameter carries the following information: +.. code-block:: + :force: + struct CONFIG { + u4 num_bits; + struct port_field { + bool is_signed; + bool is_subtract; + u(num_bits) factor1_len; + u(num_bits) factor2_len; + }[num_ports]; + }; + +The A cell port carries the following information: +.. code-block:: + :force: + struct A { + u(CONFIG.port_field[0].factor1_len) port0factor1; + u(CONFIG.port_field[0].factor2_len) port0factor2; + u(CONFIG.port_field[1].factor1_len) port1factor1; + u(CONFIG.port_field[1].factor2_len) port1factor2; + ... + }; + +No factor1 may have a zero length. +A factor2 having a zero length implies factor2 is replaced with a constant 1. + +Additionally, B is an array of 1-bit-wide unsigned integers to also be summed up. +Finally, we have: +.. code-block:: + :force: + Y = port0factor1 * port0factor2 + port1factor1 * port1factor2 + ... + * B[0] + B[1] + ... + Specify rules ~~~~~~~~~~~~~ @@ -1152,4 +1198,4 @@ file via ABC using the abc pass. .. todo:: Add information about ``$lut`` and ``$sop`` cells. -.. todo:: Add information about ``$alu``, ``$macc``, ``$fa``, and ``$lcu`` cells. +.. todo:: Add information about ``$alu``, ``$fa``, and ``$lcu`` cells. diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 489281f26a0..1383a2a1374 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -902,18 +902,29 @@ endgenerate endmodule // -------------------------------------------------------- - +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $macc (A, B, Y) +//- +//- Multiply and accumulate. +//- A building block for summing any number of negated and unnegated signals and arithmetic products of pairs of signals. Cell port A concatenates pairs of signals to be multiplied together. When the second signal in a pair is zero length, a constant 1 is used instead as the second factor. Cell port B concatenates 1-bit-wide signals to also be summed, such as "carry in" in adders. +//- Typically created by the `alumacc` pass, which transforms $add and $mul into $macc cells. module \$macc (A, B, Y); parameter A_WIDTH = 0; parameter B_WIDTH = 0; parameter Y_WIDTH = 0; +// CONFIG determines the layout of A, as explained below parameter CONFIG = 4'b0000; parameter CONFIG_WIDTH = 4; -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output reg [Y_WIDTH-1:0] Y; +// In the terms used for this cell, there's mixed meanings for the term "port". To disambiguate: +// A cell port is for example the A input (it is constructed in C++ as cell->setPort(ID::A, ...)) +// Multiplier ports are pairs of multiplier inputs ("factors"). +// If the second signal in such a pair is zero length, no multiplication is necessary, and the first signal is just added to the sum. +input [A_WIDTH-1:0] A; // Cell port A is the concatenation of all arithmetic ports +input [B_WIDTH-1:0] B; // Cell port B is the concatenation of single-bit unsigned signals to be also added to the sum +output reg [Y_WIDTH-1:0] Y; // Output sum // Xilinx XSIM does not like $clog2() below.. function integer my_clog2; @@ -929,10 +940,42 @@ function integer my_clog2; end endfunction +// Bits that a factor's length field in CONFIG per factor in cell port A localparam integer num_bits = CONFIG[3:0] > 0 ? CONFIG[3:0] : 1; +// Number of multiplier ports localparam integer num_ports = (CONFIG_WIDTH-4) / (2 + 2*num_bits); +// Minium bit width of an induction variable to iterate over all bits of cell port A localparam integer num_abits = my_clog2(A_WIDTH) > 0 ? my_clog2(A_WIDTH) : 1; +// In this pseudocode, u(foo) means an unsigned int that's foo bits long. +// The CONFIG parameter carries the following information: +// struct CONFIG { +// u4 num_bits; +// struct port_field { +// bool is_signed; +// bool is_subtract; +// u(num_bits) factor1_len; +// u(num_bits) factor2_len; +// }[num_ports]; +// }; + +// The A cell port carries the following information: +// struct A { +// u(CONFIG.port_field[0].factor1_len) port0factor1; +// u(CONFIG.port_field[0].factor2_len) port0factor2; +// u(CONFIG.port_field[1].factor1_len) port1factor1; +// u(CONFIG.port_field[1].factor2_len) port1factor2; +// ... +// }; +// and log(sizeof(A)) is num_abits. +// No factor1 may have a zero length. +// A factor2 having a zero length implies factor2 is replaced with a constant 1. + +// Additionally, B is an array of 1-bit-wide unsigned integers to also be summed up. +// Finally, we have: +// Y = port0factor1 * port0factor2 + port1factor1 * port1factor2 + ... +// * B[0] + B[1] + ... + function [2*num_ports*num_abits-1:0] get_port_offsets; input [CONFIG_WIDTH-1:0] cfg; integer i, cursor; From 22c5ab90d1580b6d515a58cf1c8be380d188b989 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 4 Apr 2024 00:16:37 +0000 Subject: [PATCH 53/76] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e31b722614b..99834700222 100644 --- a/Makefile +++ b/Makefile @@ -142,7 +142,7 @@ LIBS += -lrt endif endif -YOSYS_VER := 0.39+163 +YOSYS_VER := 0.39+165 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 9510293a9472a239f448cc7dc7b1bed7f1a35e36 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Thu, 4 Apr 2024 18:16:58 +0200 Subject: [PATCH 54/76] fixup --- docs/source/yosys_internals/formats/cell_library.rst | 11 +++++++---- techlibs/common/simlib.v | 9 +++++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/docs/source/yosys_internals/formats/cell_library.rst b/docs/source/yosys_internals/formats/cell_library.rst index a4e5adfb70a..1e0012f461d 100644 --- a/docs/source/yosys_internals/formats/cell_library.rst +++ b/docs/source/yosys_internals/formats/cell_library.rst @@ -632,8 +632,9 @@ If the second signal in such a pair is zero length, no multiplication is necessa In this pseudocode, ``u(foo)`` means an unsigned int that's foo bits long. The CONFIG parameter carries the following information: + .. code-block:: - :force: + struct CONFIG { u4 num_bits; struct port_field { @@ -645,8 +646,9 @@ The CONFIG parameter carries the following information: }; The A cell port carries the following information: + .. code-block:: - :force: + struct A { u(CONFIG.port_field[0].factor1_len) port0factor1; u(CONFIG.port_field[0].factor2_len) port0factor2; @@ -660,10 +662,11 @@ A factor2 having a zero length implies factor2 is replaced with a constant 1. Additionally, B is an array of 1-bit-wide unsigned integers to also be summed up. Finally, we have: + .. code-block:: - :force: + Y = port0factor1 * port0factor2 + port1factor1 * port1factor2 + ... - * B[0] + B[1] + ... + + B[0] + B[1] + ... Specify rules ~~~~~~~~~~~~~ diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 1383a2a1374..7dc03da6d2d 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -907,8 +907,13 @@ endmodule //- $macc (A, B, Y) //- //- Multiply and accumulate. -//- A building block for summing any number of negated and unnegated signals and arithmetic products of pairs of signals. Cell port A concatenates pairs of signals to be multiplied together. When the second signal in a pair is zero length, a constant 1 is used instead as the second factor. Cell port B concatenates 1-bit-wide signals to also be summed, such as "carry in" in adders. -//- Typically created by the `alumacc` pass, which transforms $add and $mul into $macc cells. +//- A building block for summing any number of negated and unnegated signals +//- and arithmetic products of pairs of signals. Cell port A concatenates pairs +//- of signals to be multiplied together. When the second signal in a pair is zero +//- length, a constant 1 is used instead as the second factor. Cell port B +//- concatenates 1-bit-wide signals to also be summed, such as "carry in" in adders. +//- Typically created by the `alumacc` pass, which transforms $add and $mul +//- into $macc cells. module \$macc (A, B, Y); parameter A_WIDTH = 0; From 43ef916f8683e68bbaee9f2358f3719d5000bf1a Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Fri, 5 Apr 2024 14:01:25 +0200 Subject: [PATCH 55/76] Restructure rst --- .../yosys_internals/formats/cell_library.rst | 51 ++++++++----------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/docs/source/yosys_internals/formats/cell_library.rst b/docs/source/yosys_internals/formats/cell_library.rst index 1e0012f461d..2b8dc300154 100644 --- a/docs/source/yosys_internals/formats/cell_library.rst +++ b/docs/source/yosys_internals/formats/cell_library.rst @@ -622,22 +622,36 @@ Add a brief description of the ``$fsm`` cell type. Coarse arithmetics ~~~~~~~~~~~~~~~~~~~~~ -The ``$macc`` cell type represents a multiply and accumulate block, for summing any number of negated and unnegated signals and arithmetic products of pairs of signals. Cell port A concatenates pairs of signals to be multiplied together. When the second signal in a pair is zero length, a constant 1 is used instead as the second factor. Cell port B concatenates 1-bit-wide signals to also be summed, such as "carry in" in adders. +The ``$macc`` cell type represents a generalized multiply and accumulate operation. The cell is purely combinational. It outputs the result of summing up a sequence of products and other injected summands. -The cell's ``CONFIG`` parameter determines the layout of cell port ``A``. -In the terms used for this cell, there's mixed meanings for the term "port". To disambiguate: -A cell port is for example the A input (it is constructed in C++ as ``cell->setPort(ID::A, ...))`` -Multiplier ports are pairs of multiplier inputs ("factors"). -If the second signal in such a pair is zero length, no multiplication is necessary, and the first signal is just added to the sum. +.. code-block:: + + Y = 0 +- a0factor1 * a0factor2 +- a1factor1 * a1factor2 +- ... + + B[0] + B[1] + ... + +The A port consists of concatenated pairs of multiplier inputs ("factors"). +A zero length factor2 acts as a constant 1, turning factor1 into a simple summand. In this pseudocode, ``u(foo)`` means an unsigned int that's foo bits long. + +.. code-block:: + + struct A { + u(CONFIG.mul_info[0].factor1_len) a0factor1; + u(CONFIG.mul_info[0].factor2_len) a0factor2; + u(CONFIG.mul_info[1].factor1_len) a1factor1; + u(CONFIG.mul_info[1].factor2_len) a1factor2; + ... + }; + +The cell's ``CONFIG`` parameter determines the layout of cell port ``A``. The CONFIG parameter carries the following information: .. code-block:: struct CONFIG { u4 num_bits; - struct port_field { + struct mul_info { bool is_signed; bool is_subtract; u(num_bits) factor1_len; @@ -645,28 +659,7 @@ The CONFIG parameter carries the following information: }[num_ports]; }; -The A cell port carries the following information: - -.. code-block:: - - struct A { - u(CONFIG.port_field[0].factor1_len) port0factor1; - u(CONFIG.port_field[0].factor2_len) port0factor2; - u(CONFIG.port_field[1].factor1_len) port1factor1; - u(CONFIG.port_field[1].factor2_len) port1factor2; - ... - }; - -No factor1 may have a zero length. -A factor2 having a zero length implies factor2 is replaced with a constant 1. - -Additionally, B is an array of 1-bit-wide unsigned integers to also be summed up. -Finally, we have: - -.. code-block:: - - Y = port0factor1 * port0factor2 + port1factor1 * port1factor2 + ... - + B[0] + B[1] + ... +B is an array of concatenated 1-bit-wide unsigned integers to also be summed up. Specify rules ~~~~~~~~~~~~~ From 91e41d8c803562d43e2debe30677a86d55035357 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 8 Apr 2024 12:44:37 +0200 Subject: [PATCH 56/76] Move parameters to module declaration --- tests/memlib/memlib_9b1B.v | 20 +++++++++++--------- tests/memlib/memlib_wren.v | 16 ++++++++-------- tests/memories/issue00335.v | 6 ++++-- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/tests/memlib/memlib_9b1B.v b/tests/memlib/memlib_9b1B.v index 55545ebd4db..9a8246c9f19 100644 --- a/tests/memlib/memlib_9b1B.v +++ b/tests/memlib/memlib_9b1B.v @@ -1,4 +1,14 @@ -module RAM_9b1B ( +module RAM_9b1B +#( + parameter INIT = 0, + parameter OPTION_INIT = "UNDEFINED", + parameter PORT_R_WIDTH = 9, + parameter PORT_W_WIDTH = 9, + parameter PORT_R_CLK_POL = 0, + parameter PORT_W_CLK_POL = 0, + parameter PORT_W_WR_EN_WIDTH = 1 +) +( input PORT_R_CLK, input [6:0] PORT_R_ADDR, output reg [PORT_R_WIDTH-1:0] PORT_R_RD_DATA, @@ -8,14 +18,6 @@ module RAM_9b1B ( input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA ); -parameter INIT = 0; -parameter OPTION_INIT = "UNDEFINED"; -parameter PORT_R_WIDTH = 9; -parameter PORT_W_WIDTH = 9; -parameter PORT_R_CLK_POL = 0; -parameter PORT_W_CLK_POL = 0; -parameter PORT_W_WR_EN_WIDTH = 1; - reg [8:0] mem [0:15]; integer i; diff --git a/tests/memlib/memlib_wren.v b/tests/memlib/memlib_wren.v index b9433d42e66..c687184bdca 100644 --- a/tests/memlib/memlib_wren.v +++ b/tests/memlib/memlib_wren.v @@ -1,4 +1,11 @@ -module RAM_WREN ( +module RAM_WREN #( + parameter ABITS=4, + parameter WIDTH=8, + parameter PORT_A_WR_EN_WIDTH=1, + parameter PORT_A_WR_BE_WIDTH=0, + parameter OPTION_BYTESIZE=WIDTH, + parameter WB=OPTION_BYTESIZE +)( input PORT_A_CLK, input [ABITS-1:0] PORT_A_ADDR, input [WIDTH-1:0] PORT_A_WR_DATA, @@ -7,13 +14,6 @@ module RAM_WREN ( input [PORT_A_WR_BE_WIDTH-1:0] PORT_A_WR_BE ); -parameter ABITS=4; -parameter WIDTH=8; -parameter PORT_A_WR_EN_WIDTH=1; -parameter PORT_A_WR_BE_WIDTH=0; -parameter OPTION_BYTESIZE=WIDTH; -parameter WB=OPTION_BYTESIZE; - reg [WIDTH-1:0] mem [0:2**ABITS-1]; integer i; diff --git a/tests/memories/issue00335.v b/tests/memories/issue00335.v index f3b6e5dfe28..305339dd959 100644 --- a/tests/memories/issue00335.v +++ b/tests/memories/issue00335.v @@ -2,13 +2,15 @@ // expect-rd-ports 1 // expect-rd-clk \clk -module ram2 (input clk, +module ram2 #( + parameter SIZE = 5 // Address size + ) (input clk, input sel, input we, input [SIZE-1:0] adr, input [63:0] dat_i, output reg [63:0] dat_o); - parameter SIZE = 5; // Address size + reg [63:0] mem [0:(1 << SIZE)-1]; integer i; From 4ac10040ce79b2d17f3f72c2c61d6e8558b8dab3 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 8 Apr 2024 12:45:43 +0200 Subject: [PATCH 57/76] Enable SV for localparam use by Efinix cell_sim --- techlibs/efinix/cells_sim.v | 49 +++++++++++++++++++------------------ tests/arch/run-test.sh | 2 +- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/techlibs/efinix/cells_sim.v b/techlibs/efinix/cells_sim.v index 22c7bc776da..26e45464613 100644 --- a/techlibs/efinix/cells_sim.v +++ b/techlibs/efinix/cells_sim.v @@ -113,7 +113,31 @@ module EFX_GBUFCE( endmodule -module EFX_RAM_5K( +module EFX_RAM_5K +# ( + parameter READ_WIDTH = 20, + parameter WRITE_WIDTH = 20, + localparam READ_ADDR_WIDTH = + (READ_WIDTH == 16) ? 8 : // 256x16 + (READ_WIDTH == 8) ? 9 : // 512x8 + (READ_WIDTH == 4) ? 10 : // 1024x4 + (READ_WIDTH == 2) ? 11 : // 2048x2 + (READ_WIDTH == 1) ? 12 : // 4096x1 + (READ_WIDTH == 20) ? 8 : // 256x20 + (READ_WIDTH == 10) ? 9 : // 512x10 + (READ_WIDTH == 5) ? 10 : -1, // 1024x5 + + localparam WRITE_ADDR_WIDTH = + (WRITE_WIDTH == 16) ? 8 : // 256x16 + (WRITE_WIDTH == 8) ? 9 : // 512x8 + (WRITE_WIDTH == 4) ? 10 : // 1024x4 + (WRITE_WIDTH == 2) ? 11 : // 2048x2 + (WRITE_WIDTH == 1) ? 12 : // 4096x1 + (WRITE_WIDTH == 20) ? 8 : // 256x20 + (WRITE_WIDTH == 10) ? 9 : // 512x10 + (WRITE_WIDTH == 5) ? 10 : -1 // 1024x5 +) +( input [WRITE_WIDTH-1:0] WDATA, input [WRITE_ADDR_WIDTH-1:0] WADDR, input WE, @@ -126,8 +150,6 @@ module EFX_RAM_5K( (* clkbuf_sink *) input RCLK ); - parameter READ_WIDTH = 20; - parameter WRITE_WIDTH = 20; parameter OUTPUT_REG = 1'b0; parameter RCLK_POLARITY = 1'b1; parameter RE_POLARITY = 1'b1; @@ -155,25 +177,4 @@ module EFX_RAM_5K( parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000; - - localparam READ_ADDR_WIDTH = - (READ_WIDTH == 16) ? 8 : // 256x16 - (READ_WIDTH == 8) ? 9 : // 512x8 - (READ_WIDTH == 4) ? 10 : // 1024x4 - (READ_WIDTH == 2) ? 11 : // 2048x2 - (READ_WIDTH == 1) ? 12 : // 4096x1 - (READ_WIDTH == 20) ? 8 : // 256x20 - (READ_WIDTH == 10) ? 9 : // 512x10 - (READ_WIDTH == 5) ? 10 : -1; // 1024x5 - - localparam WRITE_ADDR_WIDTH = - (WRITE_WIDTH == 16) ? 8 : // 256x16 - (WRITE_WIDTH == 8) ? 9 : // 512x8 - (WRITE_WIDTH == 4) ? 10 : // 1024x4 - (WRITE_WIDTH == 2) ? 11 : // 2048x2 - (WRITE_WIDTH == 1) ? 12 : // 4096x1 - (WRITE_WIDTH == 20) ? 8 : // 256x20 - (WRITE_WIDTH == 10) ? 9 : // 512x10 - (WRITE_WIDTH == 5) ? 10 : -1; // 1024x5 - endmodule diff --git a/tests/arch/run-test.sh b/tests/arch/run-test.sh index a14b795090d..68f925b34d9 100755 --- a/tests/arch/run-test.sh +++ b/tests/arch/run-test.sh @@ -16,7 +16,7 @@ for arch in ../../techlibs/*; do done else echo -n "Test $path ->" - iverilog -t null -I$arch $path + iverilog -t null -I$arch -g2005-sv $path echo " ok" fi done From 5f4d13ee3fdf49d371fe29712b95c07eba9f7f02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 8 Apr 2024 16:44:43 +0200 Subject: [PATCH 58/76] techmap: Note down iteration in Kogge-Stone --- techlibs/common/choices/kogge-stone.v | 1 + 1 file changed, 1 insertion(+) diff --git a/techlibs/common/choices/kogge-stone.v b/techlibs/common/choices/kogge-stone.v index 0e25fe86073..ad2e2b16954 100644 --- a/techlibs/common/choices/kogge-stone.v +++ b/techlibs/common/choices/kogge-stone.v @@ -42,6 +42,7 @@ module _80_lcu_kogge_stone (P, G, CI, CO); g[0] = g[0] | (p[0] & CI); for (i = 0; i < $clog2(WIDTH); i = i + 1) begin + // iterate in reverse so we don't confuse a result from this stage and the previous for (j = WIDTH - 1; j >= 2**i; j = j - 1) begin g[j] = g[j] | p[j] & g[j - 2**i]; p[j] = p[j] & p[j - 2**i]; From bc1499928779bae5b6483e96c2a3db2c8202cf64 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 00:16:14 +0000 Subject: [PATCH 59/76] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6396d57af2e..f8d628010c5 100644 --- a/Makefile +++ b/Makefile @@ -142,7 +142,7 @@ LIBS += -lrt endif endif -YOSYS_VER := 0.39+165 +YOSYS_VER := 0.39+183 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From a1bb0255d654ffd0d8503577274f24b349a42995 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 10 Apr 2024 08:17:27 +0200 Subject: [PATCH 60/76] Release version 0.40 --- CHANGELOG | 13 ++++++++++++- Makefile | 4 ++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index b172988d5db..ba734fb35dd 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,8 +2,19 @@ List of major changes and improvements between releases ======================================================= -Yosys 0.39 .. Yosys 0.40-dev +Yosys 0.39 .. Yosys 0.40 -------------------------- + * New commands and options + - Added option "-vhdl2019" to "read" and "verific" pass. + + * Various + - Major documentation overhaul. + - Added port statistics to "stat" command. + - Added new formatting features to cxxrtl backend. + + * Verific support + - Added better support for VHDL constants import. + - Added support for VHDL 2009. Yosys 0.38 .. Yosys 0.39 -------------------------- diff --git a/Makefile b/Makefile index f8d628010c5..e7ed6c9fedc 100644 --- a/Makefile +++ b/Makefile @@ -142,7 +142,7 @@ LIBS += -lrt endif endif -YOSYS_VER := 0.39+183 +YOSYS_VER := 0.40 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo @@ -158,7 +158,7 @@ endif OBJS = kernel/version_$(GIT_REV).o bumpversion: - sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 0033808.. | wc -l`/;" Makefile +# sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 0033808.. | wc -l`/;" Makefile # set 'ABCREV = default' to use abc/ as it is # From e01e942f81bee11ff5f000cde9970f08f97b12b6 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 10 Apr 2024 08:21:35 +0200 Subject: [PATCH 61/76] Next dev cycle --- CHANGELOG | 3 +++ Makefile | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index ba734fb35dd..f42eaca27e1 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ List of major changes and improvements between releases ======================================================= +Yosys 0.40 .. Yosys 0.41-dev +-------------------------- + Yosys 0.39 .. Yosys 0.40 -------------------------- * New commands and options diff --git a/Makefile b/Makefile index e7ed6c9fedc..6d81b627f03 100644 --- a/Makefile +++ b/Makefile @@ -142,7 +142,7 @@ LIBS += -lrt endif endif -YOSYS_VER := 0.40 +YOSYS_VER := 0.40+0 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo @@ -158,7 +158,7 @@ endif OBJS = kernel/version_$(GIT_REV).o bumpversion: -# sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 0033808.. | wc -l`/;" Makefile + sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline a1bb025.. | wc -l`/;" Makefile # set 'ABCREV = default' to use abc/ as it is # From e2cfcbcf25afc9062d0f85748ab908c7ced71d81 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 10 Apr 2024 10:12:05 +0200 Subject: [PATCH 62/76] fix .gitignore --- docs/source/code_examples/extensions/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/source/code_examples/extensions/.gitignore b/docs/source/code_examples/extensions/.gitignore index ccdd6bd5c68..675a532eda6 100644 --- a/docs/source/code_examples/extensions/.gitignore +++ b/docs/source/code_examples/extensions/.gitignore @@ -1,2 +1,3 @@ my_cmd.so my_cmd.d +*.log From 47bdb3e32f71add7a48ec6215e9838048d52609a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 11 Apr 2024 00:16:34 +0000 Subject: [PATCH 63/76] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6d81b627f03..6d7bb2cecfa 100644 --- a/Makefile +++ b/Makefile @@ -142,7 +142,7 @@ LIBS += -lrt endif endif -YOSYS_VER := 0.40+0 +YOSYS_VER := 0.40+4 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 0c7ac36dcf18ed1afcb2ef5a3011c2a47b8d4118 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 11 Apr 2024 14:56:00 +0200 Subject: [PATCH 64/76] Add workflows and CODEOWNERS and fixed gitignore --- CODEOWNERS | 3 ++- tests/arch/quicklogic/.gitignore | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 7d680e9f2e4..879bb8dee21 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -10,6 +10,7 @@ # PATH (can use glob) USERNAME(S) +CODEOWNERS @nakengelhardt passes/cmds/scratchpad.cc @nakengelhardt frontends/rpc/ @whitequark backends/cxxrtl/ @whitequark @@ -19,7 +20,7 @@ passes/opt/opt_lut.cc @whitequark passes/techmap/abc9*.cc @eddiehung @Ravenslofty backends/aiger/xaiger.cc @eddiehung docs/ @KrystalDelusion - +.github/workflows/*.yml @mmicko ## External Contributors # Only users with write permission to the repository get review diff --git a/tests/arch/quicklogic/.gitignore b/tests/arch/quicklogic/.gitignore index 9a71dca69b0..ae20ed34262 100644 --- a/tests/arch/quicklogic/.gitignore +++ b/tests/arch/quicklogic/.gitignore @@ -1,4 +1,4 @@ *.log -/run-test.mk +run-test.mk +*_synth.v +*_testbench From a48825a604d776becc85ad147d7a767029364cf6 Mon Sep 17 00:00:00 2001 From: Peter Gadfort Date: Fri, 12 Apr 2024 13:57:29 -0400 Subject: [PATCH 65/76] add support for using ABCs library merging when providing multiple liberty files --- passes/techmap/abc.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index 42287966288..b33e1a17df4 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -804,8 +804,10 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin for (std::string dont_use_cell : dont_use_cells) { dont_use_args += stringf("-X \"%s\" ", dont_use_cell.c_str()); } + bool first_lib = true; for (std::string liberty_file : liberty_files) { - abc_script += stringf("read_lib %s -w \"%s\" ; ", dont_use_args.c_str(), liberty_file.c_str()); + abc_script += stringf("read_lib %s %s -w \"%s\" ; ", dont_use_args.c_str(), first_lib ? "" : "-m", liberty_file.c_str()); + first_lib = false; } for (std::string liberty_file : genlib_files) abc_script += stringf("read_library \"%s\"; ", liberty_file.c_str()); From d4b6042e439f2e8c8059820501c0bcaad7576155 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Sat, 13 Apr 2024 11:20:36 +1200 Subject: [PATCH 66/76] Makefile: Separate docs/usage stderr and stdout --- Makefile | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 6d7bb2cecfa..5e9f2163de1 100644 --- a/Makefile +++ b/Makefile @@ -985,16 +985,27 @@ docs/gen_images: $(Q) $(MAKE) -C docs images DOCS_GUIDELINE_FILES := GettingStarted CodingStyle -docs/guidelines: +docs/guidelines docs/source/temp: $(Q) mkdir -p docs/source/temp $(Q) cp -f $(addprefix guidelines/,$(DOCS_GUIDELINE_FILES)) docs/source/temp -# many of these will return an error which can be safely ignored, so we prefix -# the command with a '-' -DOCS_USAGE_PROGS := yosys yosys-config yosys-filterlib yosys-abc yosys-smtbmc yosys-witness -docs/usage: $(addprefix docs/source/temp/,$(DOCS_USAGE_PROGS)) -docs/source/temp/%: docs/guidelines - -$(Q) ./$(PROGRAM_PREFIX)$* --help > $@ 2>&1 +# some commands return an error and print the usage text to stderr +define DOC_USAGE_STDERR +docs/source/temp/$(1): $(PROGRAM_PREFIX)$(1) docs/source/temp + -$(Q) ./$$< --help 2> $$@ +endef +DOCS_USAGE_STDERR := yosys-config yosys-filterlib yosys-abc +$(foreach usage,$(DOCS_USAGE_STDERR),$(eval $(call DOC_USAGE_STDERR,$(usage)))) + +# others print to stdout +define DOC_USAGE_STDOUT +docs/source/temp/$(1): $(PROGRAM_PREFIX)$(1) docs/source/temp + $(Q) ./$$< --help > $$@ +endef +DOCS_USAGE_STDOUT := yosys yosys-smtbmc yosys-witness +$(foreach usage,$(DOCS_USAGE_STDOUT),$(eval $(call DOC_USAGE_STDOUT,$(usage)))) + +docs/usage: $(addprefix docs/source/temp/,$(DOCS_USAGE_STDOUT) $(DOCS_USAGE_STDERR)) docs/reqs: $(Q) $(MAKE) -C docs reqs From 1d7b7ddfd7c7b1322bb5ab0ec98eeaf184f410ce Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Sat, 13 Apr 2024 11:29:11 +1200 Subject: [PATCH 67/76] Docs: Skip footer in logs --- docs/source/code_examples/extensions/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/source/code_examples/extensions/Makefile b/docs/source/code_examples/extensions/Makefile index 288983ed356..5a7994874d3 100644 --- a/docs/source/code_examples/extensions/Makefile +++ b/docs/source/code_examples/extensions/Makefile @@ -13,18 +13,18 @@ my_cmd.so: my_cmd.cc $(YOSYS)-config --exec --cxx $(subst $(DATDIR),../../../../share,$(CXXFLAGS)) --ldflags -o my_cmd.so -shared my_cmd.cc --ldlibs test0.log: my_cmd.so - $(YOSYS) -Ql test0.log_new -m ./my_cmd.so -p 'my_cmd foo bar' absval_ref.v + $(YOSYS) -QTl test0.log_new -m ./my_cmd.so -p 'my_cmd foo bar' absval_ref.v mv test0.log_new test0.log test1.log: my_cmd.so - $(YOSYS) -Ql test1.log_new -m ./my_cmd.so -p 'clean; test1; dump' absval_ref.v + $(YOSYS) -QTl test1.log_new -m ./my_cmd.so -p 'clean; test1; dump' absval_ref.v mv test1.log_new test1.log test1.dot: my_cmd.so $(YOSYS) -m ./my_cmd.so -p 'test1; show -format dot -prefix test1' test2.log: my_cmd.so - $(YOSYS) -Ql test2.log_new -m ./my_cmd.so -p 'hierarchy -top test; test2' sigmap_test.v + $(YOSYS) -QTl test2.log_new -m ./my_cmd.so -p 'hierarchy -top test; test2' sigmap_test.v mv test2.log_new test2.log .PHONY: clean From b3024289c6e6984cbc4111e42901dce9e01bdc0a Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Sat, 13 Apr 2024 11:33:04 +1200 Subject: [PATCH 68/76] Docs: Force read_verilog to avoid verific header --- docs/source/code_examples/extensions/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/source/code_examples/extensions/Makefile b/docs/source/code_examples/extensions/Makefile index 5a7994874d3..8b5fa106af1 100644 --- a/docs/source/code_examples/extensions/Makefile +++ b/docs/source/code_examples/extensions/Makefile @@ -13,18 +13,18 @@ my_cmd.so: my_cmd.cc $(YOSYS)-config --exec --cxx $(subst $(DATDIR),../../../../share,$(CXXFLAGS)) --ldflags -o my_cmd.so -shared my_cmd.cc --ldlibs test0.log: my_cmd.so - $(YOSYS) -QTl test0.log_new -m ./my_cmd.so -p 'my_cmd foo bar' absval_ref.v + $(YOSYS) -QTl test0.log_new -m ./my_cmd.so -p 'my_cmd foo bar' -f verilog absval_ref.v mv test0.log_new test0.log test1.log: my_cmd.so - $(YOSYS) -QTl test1.log_new -m ./my_cmd.so -p 'clean; test1; dump' absval_ref.v + $(YOSYS) -QTl test1.log_new -m ./my_cmd.so -p 'clean; test1; dump' -f verilog absval_ref.v mv test1.log_new test1.log test1.dot: my_cmd.so $(YOSYS) -m ./my_cmd.so -p 'test1; show -format dot -prefix test1' test2.log: my_cmd.so - $(YOSYS) -QTl test2.log_new -m ./my_cmd.so -p 'hierarchy -top test; test2' sigmap_test.v + $(YOSYS) -QTl test2.log_new -m ./my_cmd.so -p 'hierarchy -top test; test2' -f verilog sigmap_test.v mv test2.log_new test2.log .PHONY: clean From ed46453cfc3032d28246e81d93bfb8a8c65f826e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 13 Apr 2024 00:14:07 +0000 Subject: [PATCH 69/76] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6d7bb2cecfa..04cb5edc220 100644 --- a/Makefile +++ b/Makefile @@ -142,7 +142,7 @@ LIBS += -lrt endif endif -YOSYS_VER := 0.40+4 +YOSYS_VER := 0.40+7 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 953f5bbe6ca8ce8b4612383482e42f6b7978fd85 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 15 Apr 2024 09:50:46 +1200 Subject: [PATCH 70/76] Docs: Remove end-before tag for yosys-abc --- docs/source/appendix/auxprogs.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/source/appendix/auxprogs.rst b/docs/source/appendix/auxprogs.rst index b6defbe802e..05a2c646de5 100644 --- a/docs/source/appendix/auxprogs.rst +++ b/docs/source/appendix/auxprogs.rst @@ -38,7 +38,6 @@ two. .. literalinclude:: /temp/yosys-abc :start-at: usage - :end-before: UC Berkeley yosys-smtbmc ------------ From 73d021562f57ab9217a65ee2c7c6e21909378ba3 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 15 Apr 2024 10:13:22 +1200 Subject: [PATCH 71/76] Docs: Rename source/temp to source/generated --- Makefile | 12 ++++++------ docs/.gitignore | 2 +- docs/Makefile | 1 + docs/source/appendix/auxprogs.rst | 10 +++++----- docs/source/cmd_ref.rst | 2 +- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index 5e9f2163de1..acd9e18fa36 100644 --- a/Makefile +++ b/Makefile @@ -985,13 +985,13 @@ docs/gen_images: $(Q) $(MAKE) -C docs images DOCS_GUIDELINE_FILES := GettingStarted CodingStyle -docs/guidelines docs/source/temp: - $(Q) mkdir -p docs/source/temp - $(Q) cp -f $(addprefix guidelines/,$(DOCS_GUIDELINE_FILES)) docs/source/temp +docs/guidelines docs/source/generated: + $(Q) mkdir -p docs/source/generated + $(Q) cp -f $(addprefix guidelines/,$(DOCS_GUIDELINE_FILES)) docs/source/generated # some commands return an error and print the usage text to stderr define DOC_USAGE_STDERR -docs/source/temp/$(1): $(PROGRAM_PREFIX)$(1) docs/source/temp +docs/source/generated/$(1): $(PROGRAM_PREFIX)$(1) docs/source/generated -$(Q) ./$$< --help 2> $$@ endef DOCS_USAGE_STDERR := yosys-config yosys-filterlib yosys-abc @@ -999,13 +999,13 @@ $(foreach usage,$(DOCS_USAGE_STDERR),$(eval $(call DOC_USAGE_STDERR,$(usage)))) # others print to stdout define DOC_USAGE_STDOUT -docs/source/temp/$(1): $(PROGRAM_PREFIX)$(1) docs/source/temp +docs/source/generated/$(1): $(PROGRAM_PREFIX)$(1) docs/source/generated $(Q) ./$$< --help > $$@ endef DOCS_USAGE_STDOUT := yosys yosys-smtbmc yosys-witness $(foreach usage,$(DOCS_USAGE_STDOUT),$(eval $(call DOC_USAGE_STDOUT,$(usage)))) -docs/usage: $(addprefix docs/source/temp/,$(DOCS_USAGE_STDOUT) $(DOCS_USAGE_STDERR)) +docs/usage: $(addprefix docs/source/generated/,$(DOCS_USAGE_STDOUT) $(DOCS_USAGE_STDERR)) docs/reqs: $(Q) $(MAKE) -C docs reqs diff --git a/docs/.gitignore b/docs/.gitignore index d7bfd8e956a..65bbcdeaeb8 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1,6 +1,6 @@ /build/ /source/cmd -/source/temp +/source/generated /source/_images/**/*.log /source/_images/**/*.aux /source/_images/**/*.pdf diff --git a/docs/Makefile b/docs/Makefile index a5b2fed6b7d..701157ee6c3 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -48,6 +48,7 @@ help: clean: clean-examples rm -rf $(BUILDDIR)/* rm -rf source/cmd util/__pycache__ + rm -rf source/generated $(MAKE) -C source/_images clean .PHONY: html diff --git a/docs/source/appendix/auxprogs.rst b/docs/source/appendix/auxprogs.rst index 05a2c646de5..c239136b64e 100644 --- a/docs/source/appendix/auxprogs.rst +++ b/docs/source/appendix/auxprogs.rst @@ -11,7 +11,7 @@ The ``yosys-config`` tool (an auto-generated shell-script) can be used to query compiler options and other information needed for building loadable modules for Yosys. See :doc:`/yosys_internals/extending_yosys/extensions` for details. -.. literalinclude:: /temp/yosys-config +.. literalinclude:: /generated/yosys-config :start-at: Usage .. _sec:filterlib: @@ -25,7 +25,7 @@ The ``yosys-filterlib`` tool is a small utility that can be used to strip or extract information from a Liberty file. This can be useful for removing sensitive or proprietary information such as timing or other trade secrets. -.. literalinclude:: /temp/yosys-filterlib +.. literalinclude:: /generated/yosys-filterlib :start-at: Usage yosys-abc @@ -36,7 +36,7 @@ been accepted upstream. Not all versions of Yosys work with all versions of ABC. So Yosys comes with its own yosys-abc to avoid compatibility issues between the two. -.. literalinclude:: /temp/yosys-abc +.. literalinclude:: /generated/yosys-abc :start-at: usage yosys-smtbmc @@ -45,7 +45,7 @@ yosys-smtbmc The ``yosys-smtbmc`` tool is a utility used by SBY for interacting with smt solvers. -.. literalinclude:: /temp/yosys-smtbmc +.. literalinclude:: /generated/yosys-smtbmc yosys-witness ------------- @@ -54,7 +54,7 @@ yosys-witness This is used in SBY and SCY for producing traces in a consistent format independent of the solver. -.. literalinclude:: /temp/yosys-witness +.. literalinclude:: /generated/yosys-witness :start-at: Usage .. note:: ``yosys-witness`` requires `click`_ Python package for use. diff --git a/docs/source/cmd_ref.rst b/docs/source/cmd_ref.rst index f0c4eaaf927..acf2d1d4141 100644 --- a/docs/source/cmd_ref.rst +++ b/docs/source/cmd_ref.rst @@ -4,7 +4,7 @@ Command line reference ================================================================================ -.. literalinclude:: /temp/yosys +.. literalinclude:: /generated/yosys :start-at: Usage .. toctree:: From 2bd889a59a07a2ce057fa0c941234fb8e521edcc Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Mon, 15 Apr 2024 11:53:30 +0200 Subject: [PATCH 72/76] formalff -setundef: Fix handling for has_srst FFs The `has_srst`` case was checking `sig_ce` instead of `sig_srst` due to a copy and paste error. This would crash when `has_ce` was false and could incorrectly determine that an initial value is unused when `has_ce` and `has_srst` are both set. --- passes/sat/formalff.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/sat/formalff.cc b/passes/sat/formalff.cc index 264a9fb3be0..0eadb69e0eb 100644 --- a/passes/sat/formalff.cc +++ b/passes/sat/formalff.cc @@ -237,7 +237,7 @@ struct InitValWorker return true; if (ff.has_ce && initconst(ff.sig_ce.as_bit()) == (ff.pol_ce ? State::S0 : State::S1)) continue; - if (ff.has_srst && initconst(ff.sig_ce.as_bit()) == (ff.pol_srst ? State::S1 : State::S0)) + if (ff.has_srst && initconst(ff.sig_srst.as_bit()) == (ff.pol_srst ? State::S1 : State::S0)) continue; return true; From af94123730c13ca5e48b231031873b270542ecba Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 15 Apr 2024 17:01:07 +0200 Subject: [PATCH 73/76] verific: expose library name as module attribute --- frontends/verific/verific.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index e6c5865b77c..81e79f7497f 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -1430,6 +1430,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma } import_attributes(module->attributes, nl, nl); module->set_string_attribute(ID::hdlname, nl->CellBaseName()); + module->set_string_attribute(ID(library), nl->Owner()->Owner()->Name()); #ifdef VERIFIC_VHDL_SUPPORT if (nl->IsFromVhdl()) { NameSpace name_space(0); From 40e8f5b69de5063cd2adb6565a00992be83b5515 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Apr 2024 00:15:48 +0000 Subject: [PATCH 74/76] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 87c19786d12..32ca398c26f 100644 --- a/Makefile +++ b/Makefile @@ -142,7 +142,7 @@ LIBS += -lrt endif endif -YOSYS_VER := 0.40+7 +YOSYS_VER := 0.40+22 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From c38bbd7824edee850c328d8798c78494733fd1ef Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 16 Apr 2024 07:50:50 +0200 Subject: [PATCH 75/76] Add new verific testing environment CI --- .github/workflows/test-verific.yml | 77 ++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 .github/workflows/test-verific.yml diff --git a/.github/workflows/test-verific.yml b/.github/workflows/test-verific.yml new file mode 100644 index 00000000000..b4383eba462 --- /dev/null +++ b/.github/workflows/test-verific.yml @@ -0,0 +1,77 @@ +name: Build and run tests with Verific (Linux) + +on: [push, pull_request] + +jobs: + test-verific: + runs-on: [self-hosted, linux, x64] + steps: + - name: Checkout Yosys + uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Runtime environment + run: | + echo "procs=$(nproc)" >> $GITHUB_ENV + + - name: Build Yosys + run: | + make config-clang + echo "ENABLE_VERIFIC := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_EDIF := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_LIBERTY := 1" >> Makefile.conf + echo "ENABLE_CCACHE := 1" >> Makefile.conf + make -j${{ env.procs }} + + - name: Install Yosys + run: | + make install DESTDIR=${GITHUB_WORKSPACE}/.local PREFIX= + + - name: Checkout Documentation + if: ${{ github.ref == 'refs/heads/main' }} + uses: actions/checkout@v4 + with: + path: 'yosys-cmd-ref' + repository: 'YosysHQ-Docs/yosys-cmd-ref' + fetch-depth: 0 + token: ${{ secrets.CI_DOCS_UPDATE_PAT }} + persist-credentials: true + + - name: Update documentation + if: ${{ github.ref == 'refs/heads/main' }} + run: | + make docs + rm -rf docs/build + cd yosys-cmd-ref + rm -rf * + git checkout README.md + cp -R ../docs/* . + rm -rf util/__pycache__ + git add -A . + git diff-index --quiet HEAD || git commit -m "Update" + git push + + - name: Checkout SBY + uses: actions/checkout@v4 + with: + repository: 'YosysHQ/sby' + path: 'sby' + + - name: Build SBY + run: | + make -C sby install DESTDIR=${GITHUB_WORKSPACE}/.local PREFIX= + + - name: Run Yosys tests + run: | + make -j${{ env.procs }} test + + - name: Run Verific specific Yosys tests + run: | + make -C tests/sva + cd tests/svtypes && bash run-test.sh + + - name: Run SBY tests + if: ${{ github.ref == 'refs/heads/main' }} + run: | + make -C sby run_ci From 4897e89547d2e53ebc015052d1b3cad2727ff9a9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 17 Apr 2024 00:16:15 +0000 Subject: [PATCH 76/76] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 32ca398c26f..95a982874d4 100644 --- a/Makefile +++ b/Makefile @@ -142,7 +142,7 @@ LIBS += -lrt endif endif -YOSYS_VER := 0.40+22 +YOSYS_VER := 0.40+25 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo