From f019e44e74e33ea48c8039c86cf69d841a13a3c3 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Fri, 13 Jun 2025 21:27:31 +0200 Subject: [PATCH 01/20] verificsva: Support the followed-by operator in cover mode The implementation for the implication operator in cover mode actually implements the followed-by operator, so we can re-use it unchanged. It is not always the correct behavior for the implication operator in cover mode, but a) it will only cause false positives not miss anything so if the behavior is unexpected it will be visible in the produced traces, b) it is unlikely to make a difference for most properties one would practically use in cover mode, c) at least one other widely used SVA implementations behaves the same way and d) it's not clear whether we can fix this without rewriting most of verificsva.cc --- frontends/verific/verificsva.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/frontends/verific/verificsva.cc b/frontends/verific/verificsva.cc index 860d3c166..7652f8130 100644 --- a/frontends/verific/verificsva.cc +++ b/frontends/verific/verificsva.cc @@ -1613,7 +1613,10 @@ struct VerificSvaImporter } else if (inst->Type() == PRIM_SVA_OVERLAPPED_IMPLICATION || - inst->Type() == PRIM_SVA_NON_OVERLAPPED_IMPLICATION) + inst->Type() == PRIM_SVA_NON_OVERLAPPED_IMPLICATION || + (mode_cover && ( + inst->Type() == PRIM_SVA_OVERLAPPED_FOLLOWED_BY || + inst->Type() == PRIM_SVA_NON_OVERLAPPED_IMPLICATION))) { Net *antecedent_net = inst->GetInput1(); Net *consequent_net = inst->GetInput2(); @@ -1621,7 +1624,7 @@ struct VerificSvaImporter SvaFsm antecedent_fsm(clocking, trig); node = parse_sequence(antecedent_fsm, antecedent_fsm.createStartNode(), antecedent_net); - if (inst->Type() == PRIM_SVA_NON_OVERLAPPED_IMPLICATION) { + if (inst->Type() == PRIM_SVA_NON_OVERLAPPED_IMPLICATION || inst->Type() == PRIM_SVA_NON_OVERLAPPED_FOLLOWED_BY) { int next_node = antecedent_fsm.createNode(); antecedent_fsm.createEdge(node, next_node); node = next_node; From 45131f44251b151381f4bb38eed98d8a758be741 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Sat, 14 Jun 2025 10:54:06 +1200 Subject: [PATCH 02/20] chformal: Add -assert2cover option Also add to chformal tests. --- passes/cmds/chformal.cc | 13 +++++++++++++ tests/various/chformal_check.ys | 11 +++++++++++ 2 files changed, 24 insertions(+) diff --git a/passes/cmds/chformal.cc b/passes/cmds/chformal.cc index e027103bb..572ed2153 100644 --- a/passes/cmds/chformal.cc +++ b/passes/cmds/chformal.cc @@ -115,6 +115,7 @@ struct ChformalPass : public Pass { log("\n"); #endif log(" -assert2assume\n"); + log(" -assert2cover\n"); log(" -assume2assert\n"); log(" -live2fair\n"); log(" -fair2live\n"); @@ -129,6 +130,7 @@ struct ChformalPass : public Pass { void execute(std::vector args, RTLIL::Design *design) override { bool assert2assume = false; + bool assert2cover = false; bool assume2assert = false; bool live2fair = false; bool fair2live = false; @@ -187,6 +189,11 @@ struct ChformalPass : public Pass { mode = 'c'; continue; } + if ((mode == 0 || mode == 'c') && args[argidx] == "-assert2cover") { + assert2cover = true; + mode = 'c'; + continue; + } if ((mode == 0 || mode == 'c') && args[argidx] == "-assume2assert") { assume2assert = true; mode = 'c'; @@ -218,6 +225,10 @@ struct ChformalPass : public Pass { constr_types.insert(ID($cover)); } + if (assert2assume && assert2cover) { + log_cmd_error("Cannot use both -assert2assume and -assert2cover.\n"); + } + if (mode == 0) log_cmd_error("Mode option is missing.\n"); @@ -381,6 +392,8 @@ struct ChformalPass : public Pass { IdString flavor = formal_flavor(cell); if (assert2assume && flavor == ID($assert)) set_formal_flavor(cell, ID($assume)); + if (assert2cover && flavor == ID($assert)) + set_formal_flavor(cell, ID($cover)); else if (assume2assert && flavor == ID($assume)) set_formal_flavor(cell, ID($assert)); else if (live2fair && flavor == ID($live)) diff --git a/tests/various/chformal_check.ys b/tests/various/chformal_check.ys index 951543fa5..2b2d292e4 100644 --- a/tests/various/chformal_check.ys +++ b/tests/various/chformal_check.ys @@ -36,6 +36,12 @@ select -assert-count 1 t:$assert design -load prep +chformal -assert2cover + +select -assert-count 1 t:$check r:FLAVOR=cover %i + +design -load prep + chformal -assert2assume async2sync chformal -lower @@ -66,3 +72,8 @@ design -copy-from gate -as gate top miter -equiv -flatten -make_assert gold gate miter sat -verify -prove-asserts -tempinduct miter + +design -load prep + +logger -expect error "Cannot use both" 1 +chformal -assert2assume -assert2cover From fa68299b251127eb8a7375790e8a2a5294a914d1 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Sat, 14 Jun 2025 11:06:38 +1200 Subject: [PATCH 03/20] tests/verific: Add chformal tests --- tests/verific/chformal.ys | 74 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 tests/verific/chformal.ys diff --git a/tests/verific/chformal.ys b/tests/verific/chformal.ys new file mode 100644 index 000000000..0734f7bb7 --- /dev/null +++ b/tests/verific/chformal.ys @@ -0,0 +1,74 @@ +verific -formal < Date: Tue, 24 Jun 2025 12:01:12 +0200 Subject: [PATCH 04/20] dfflibmap: propagate negated next_state to output correctly --- passes/techmap/dfflibmap.cc | 18 +++- tests/techmap/dfflibmap_dffsr_not_next.lib | 28 +++++ tests/techmap/dfflibmap_formal.ys | 116 +++++++++++++++++++++ 3 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 tests/techmap/dfflibmap_dffsr_not_next.lib create mode 100644 tests/techmap/dfflibmap_formal.ys diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index d00fee83b..f0b0ef20b 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -392,9 +392,21 @@ static void find_cell_sr(std::vector cells, IdString cell_ty continue; if (!parse_next_state(cell, ff->find("next_state"), cell_next_pin, cell_next_pol, cell_enable_pin, cell_enable_pol)) continue; - if (!parse_pin(cell, ff->find("preset"), cell_set_pin, cell_set_pol) || cell_set_pol != setpol) + + if (!parse_pin(cell, ff->find("preset"), cell_set_pin, cell_set_pol)) continue; - if (!parse_pin(cell, ff->find("clear"), cell_clr_pin, cell_clr_pol) || cell_clr_pol != clrpol) + if (!parse_pin(cell, ff->find("clear"), cell_clr_pin, cell_clr_pol)) + continue; + if (!cell_next_pol) { + // next_state is negated + // we later propagate this inversion to the output, + // which requires the swap of set and reset + std::swap(cell_set_pin, cell_clr_pin); + std::swap(cell_set_pol, cell_clr_pol); + } + if (cell_set_pol != setpol) + continue; + if (cell_clr_pol != clrpol) continue; std::map this_cell_ports; @@ -432,12 +444,14 @@ static void find_cell_sr(std::vector cells, IdString cell_ty for (size_t pos = value.find_first_of("\" \t"); pos != std::string::npos; pos = value.find_first_of("\" \t")) value.erase(pos, 1); if (value == ff->args[0]) { + // next_state negation propagated to output this_cell_ports[pin->args[0]] = cell_next_pol ? 'Q' : 'q'; if (cell_next_pol) found_noninv_output = true; found_output = true; } else if (value == ff->args[1]) { + // next_state negation propagated to output this_cell_ports[pin->args[0]] = cell_next_pol ? 'q' : 'Q'; if (!cell_next_pol) found_noninv_output = true; diff --git a/tests/techmap/dfflibmap_dffsr_not_next.lib b/tests/techmap/dfflibmap_dffsr_not_next.lib new file mode 100644 index 000000000..579dedb10 --- /dev/null +++ b/tests/techmap/dfflibmap_dffsr_not_next.lib @@ -0,0 +1,28 @@ +library (test_not_next) { + cell (dffsr_not_next) { + area : 1.0; + pin (Q) { + direction : output; + function : "STATE"; + } + pin (CLK) { + clock : true; + direction : input; + } + pin (D) { + direction : input; + } + pin (RN) { + direction : input; + } + pin (SN) { + direction : input; + } + ff (STATE,STATEN) { + clear : "!SN"; + clocked_on : "CLK"; + next_state : "!D"; + preset : "!RN"; + } + } +} \ No newline at end of file diff --git a/tests/techmap/dfflibmap_formal.ys b/tests/techmap/dfflibmap_formal.ys new file mode 100644 index 000000000..11c90ea6c --- /dev/null +++ b/tests/techmap/dfflibmap_formal.ys @@ -0,0 +1,116 @@ +################################################################## + +read_verilog -sv -icells < Date: Tue, 24 Jun 2025 12:31:30 +0200 Subject: [PATCH 05/20] fixup! dfflibmap: propagate negated next_state to output correctly --- tests/techmap/dfflibmap_dffr_not_next.lib | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 tests/techmap/dfflibmap_dffr_not_next.lib diff --git a/tests/techmap/dfflibmap_dffr_not_next.lib b/tests/techmap/dfflibmap_dffr_not_next.lib new file mode 100644 index 000000000..74004bea1 --- /dev/null +++ b/tests/techmap/dfflibmap_dffr_not_next.lib @@ -0,0 +1,33 @@ +library(test) { + cell (dffr_not_next) { + area : 6; + ff("IQ", "IQN") { + next_state : "!D"; + clocked_on : "CLK"; + clear : "CLEAR"; + preset : "PRESET"; + clear_preset_var1 : L; + clear_preset_var2 : L; + } + pin(D) { + direction : input; + } + pin(CLK) { + direction : input; + } + pin(CLEAR) { + direction : input; + } + pin(PRESET) { + direction : input; + } + pin(Q) { + direction: output; + function : "IQ"; + } + pin(QN) { + direction: output; + function : "IQN"; + } + } +} From 2b659626a3b5f4c3fe506e624f4d4aa55c835fc4 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Fri, 13 Jun 2025 14:25:22 +0200 Subject: [PATCH 06/20] rename: add -unescape --- backends/verilog/verilog_backend.cc | 106 ++++++++++++++++------------ backends/verilog/verilog_backend.h | 39 ++++++++++ passes/cmds/rename.cc | 75 ++++++++++++++++++++ tests/various/rename_unescape.ys | 41 +++++++++++ 4 files changed, 215 insertions(+), 46 deletions(-) create mode 100644 backends/verilog/verilog_backend.h create mode 100644 tests/various/rename_unescape.ys diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 997740a7c..1cef7be60 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -28,12 +28,71 @@ #include "kernel/ff.h" #include "kernel/mem.h" #include "kernel/fmt.h" +#include "backends/verilog/verilog_backend.h" #include #include #include #include USING_YOSYS_NAMESPACE + +using namespace VERILOG_BACKEND; + +const pool VERILOG_BACKEND::verilog_keywords() { + static const pool res = { + // IEEE 1800-2017 Annex B + "accept_on", "alias", "always", "always_comb", "always_ff", "always_latch", "and", "assert", "assign", "assume", "automatic", "before", + "begin", "bind", "bins", "binsof", "bit", "break", "buf", "bufif0", "bufif1", "byte", "case", "casex", "casez", "cell", "chandle", + "checker", "class", "clocking", "cmos", "config", "const", "constraint", "context", "continue", "cover", "covergroup", "coverpoint", + "cross", "deassign", "default", "defparam", "design", "disable", "dist", "do", "edge", "else", "end", "endcase", "endchecker", + "endclass", "endclocking", "endconfig", "endfunction", "endgenerate", "endgroup", "endinterface", "endmodule", "endpackage", + "endprimitive", "endprogram", "endproperty", "endsequence", "endspecify", "endtable", "endtask", "enum", "event", "eventually", + "expect", "export", "extends", "extern", "final", "first_match", "for", "force", "foreach", "forever", "fork", "forkjoin", "function", + "generate", "genvar", "global", "highz0", "highz1", "if", "iff", "ifnone", "ignore_bins", "illegal_bins", "implements", "implies", + "import", "incdir", "include", "initial", "inout", "input", "inside", "instance", "int", "integer", "interconnect", "interface", + "intersect", "join", "join_any", "join_none", "large", "let", "liblist", "library", "local", "localparam", "logic", "longint", + "macromodule", "matches", "medium", "modport", "module", "nand", "negedge", "nettype", "new", "nexttime", "nmos", "nor", + "noshowcancelled", "not", "notif0", "notif1", "null", "or", "output", "package", "packed", "parameter", "pmos", "posedge", "primitive", + "priority", "program", "property", "protected", "pull0", "pull1", "pulldown", "pullup", "pulsestyle_ondetect", "pulsestyle_onevent", + "pure", "rand", "randc", "randcase", "randsequence", "rcmos", "real", "realtime", "ref", "reg", "reject_on", "release", "repeat", + "restrict", "return", "rnmos", "rpmos", "rtran", "rtranif0", "rtranif1", "s_always", "s_eventually", "s_nexttime", "s_until", + "s_until_with", "scalared", "sequence", "shortint", "shortreal", "showcancelled", "signed", "small", "soft", "solve", "specify", + "specparam", "static", "string", "strong", "strong0", "strong1", "struct", "super", "supply0", "supply1", "sync_accept_on", + "sync_reject_on", "table", "tagged", "task", "this", "throughout", "time", "timeprecision", "timeunit", "tran", "tranif0", "tranif1", + "tri", "tri0", "tri1", "triand", "trior", "trireg", "type", "typedef", "union", "unique", "unique0", "unsigned", "until", "until_with", + "untyped", "use", "uwire", "var", "vectored", "virtual", "void", "wait", "wait_order", "wand", "weak", "weak0", "weak1", "while", + "wildcard", "wire", "with", "within", "wor", "xnor", "xor", + }; + return res; +} + +bool VERILOG_BACKEND::char_is_verilog_escaped(char c) { + if ('0' <= c && c <= '9') + return false; + if ('a' <= c && c <= 'z') + return false; + if ('A' <= c && c <= 'Z') + return false; + if (c == '_') + return false; + + return true; +} + +bool VERILOG_BACKEND::id_is_verilog_escaped(const std::string &str) { + if ('0' <= str[0] && str[0] <= '9') + return true; + + for (int i = 0; str[i]; i++) + if (char_is_verilog_escaped(str[i])) + return true; + + if (verilog_keywords().count(str)) + return true; + + return false; +} + PRIVATE_NAMESPACE_BEGIN bool verbose, norename, noattr, attr2comment, noexpr, nodec, nohex, nostr, extmem, defparam, decimal, siminit, systemverilog, simple_lhs, noparallelcase; @@ -105,7 +164,6 @@ std::string next_auto_id() std::string id(RTLIL::IdString internal_id, bool may_rename = true) { const char *str = internal_id.c_str(); - bool do_escape = false; if (may_rename && auto_name_map.count(internal_id) != 0) return stringf("%s_%0*d_", auto_prefix.c_str(), auto_name_digits, auto_name_offset + auto_name_map[internal_id]); @@ -113,51 +171,7 @@ std::string id(RTLIL::IdString internal_id, bool may_rename = true) if (*str == '\\') str++; - if ('0' <= *str && *str <= '9') - do_escape = true; - - for (int i = 0; str[i]; i++) - { - if ('0' <= str[i] && str[i] <= '9') - continue; - if ('a' <= str[i] && str[i] <= 'z') - continue; - if ('A' <= str[i] && str[i] <= 'Z') - continue; - if (str[i] == '_') - continue; - do_escape = true; - break; - } - - static const pool keywords = { - // IEEE 1800-2017 Annex B - "accept_on", "alias", "always", "always_comb", "always_ff", "always_latch", "and", "assert", "assign", "assume", "automatic", "before", - "begin", "bind", "bins", "binsof", "bit", "break", "buf", "bufif0", "bufif1", "byte", "case", "casex", "casez", "cell", "chandle", - "checker", "class", "clocking", "cmos", "config", "const", "constraint", "context", "continue", "cover", "covergroup", "coverpoint", - "cross", "deassign", "default", "defparam", "design", "disable", "dist", "do", "edge", "else", "end", "endcase", "endchecker", - "endclass", "endclocking", "endconfig", "endfunction", "endgenerate", "endgroup", "endinterface", "endmodule", "endpackage", - "endprimitive", "endprogram", "endproperty", "endsequence", "endspecify", "endtable", "endtask", "enum", "event", "eventually", - "expect", "export", "extends", "extern", "final", "first_match", "for", "force", "foreach", "forever", "fork", "forkjoin", "function", - "generate", "genvar", "global", "highz0", "highz1", "if", "iff", "ifnone", "ignore_bins", "illegal_bins", "implements", "implies", - "import", "incdir", "include", "initial", "inout", "input", "inside", "instance", "int", "integer", "interconnect", "interface", - "intersect", "join", "join_any", "join_none", "large", "let", "liblist", "library", "local", "localparam", "logic", "longint", - "macromodule", "matches", "medium", "modport", "module", "nand", "negedge", "nettype", "new", "nexttime", "nmos", "nor", - "noshowcancelled", "not", "notif0", "notif1", "null", "or", "output", "package", "packed", "parameter", "pmos", "posedge", "primitive", - "priority", "program", "property", "protected", "pull0", "pull1", "pulldown", "pullup", "pulsestyle_ondetect", "pulsestyle_onevent", - "pure", "rand", "randc", "randcase", "randsequence", "rcmos", "real", "realtime", "ref", "reg", "reject_on", "release", "repeat", - "restrict", "return", "rnmos", "rpmos", "rtran", "rtranif0", "rtranif1", "s_always", "s_eventually", "s_nexttime", "s_until", - "s_until_with", "scalared", "sequence", "shortint", "shortreal", "showcancelled", "signed", "small", "soft", "solve", "specify", - "specparam", "static", "string", "strong", "strong0", "strong1", "struct", "super", "supply0", "supply1", "sync_accept_on", - "sync_reject_on", "table", "tagged", "task", "this", "throughout", "time", "timeprecision", "timeunit", "tran", "tranif0", "tranif1", - "tri", "tri0", "tri1", "triand", "trior", "trireg", "type", "typedef", "union", "unique", "unique0", "unsigned", "until", "until_with", - "untyped", "use", "uwire", "var", "vectored", "virtual", "void", "wait", "wait_order", "wand", "weak", "weak0", "weak1", "while", - "wildcard", "wire", "with", "within", "wor", "xnor", "xor", - }; - if (keywords.count(str)) - do_escape = true; - - if (do_escape) + if (id_is_verilog_escaped(str)) return "\\" + std::string(str) + " "; return std::string(str); } diff --git a/backends/verilog/verilog_backend.h b/backends/verilog/verilog_backend.h new file mode 100644 index 000000000..7e550a37c --- /dev/null +++ b/backends/verilog/verilog_backend.h @@ -0,0 +1,39 @@ +/* + * 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. + * + * --- + * + * A simple and straightforward Verilog backend. + * + */ + +#ifndef VERILOG_BACKEND_H +#define VERILOG_BACKEND_H + +#include + +YOSYS_NAMESPACE_BEGIN +namespace VERILOG_BACKEND { + + const pool verilog_keywords(); + bool char_is_verilog_escaped(char c); + bool id_is_verilog_escaped(const std::string &str); + +}; /* namespace VERILOG_BACKEND */ +YOSYS_NAMESPACE_END + +#endif /* VERILOG_BACKEND_H */ diff --git a/passes/cmds/rename.cc b/passes/cmds/rename.cc index fe8b4a444..02cab3221 100644 --- a/passes/cmds/rename.cc +++ b/passes/cmds/rename.cc @@ -20,6 +20,7 @@ #include "kernel/register.h" #include "kernel/rtlil.h" #include "kernel/log.h" +#include "backends/verilog/verilog_backend.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -186,6 +187,26 @@ static bool rename_witness(RTLIL::Design *design, dict &ca return has_witness_signals; } +static std::string renamed_unescaped(const std::string& str) +{ + std::string new_str = ""; + + if ('0' <= str[0] && str[0] <= '9') + new_str = '_' + new_str; + + for (char c : str) { + if (VERILOG_BACKEND::char_is_verilog_escaped(c)) + new_str += '_'; + else + new_str += c; + } + + if (VERILOG_BACKEND::verilog_keywords().count(str)) + new_str += "_"; + + return new_str; +} + struct RenamePass : public Pass { RenamePass() : Pass("rename", "rename object in the design") { } void help() override @@ -252,6 +273,12 @@ struct RenamePass : public Pass { log("can be used to change the random number generator seed from the default, but it\n"); log("must be non-zero.\n"); log("\n"); + log("\n"); + log(" rename -unescape [selection]\n"); + log("\n"); + log("Rename all selected public wires and cells that have to be escaped.\n"); + log("Replaces characters with underscores or adds additional underscores and numbers.\n"); + log("\n"); } void execute(std::vector args, RTLIL::Design *design) override { @@ -265,6 +292,7 @@ struct RenamePass : public Pass { bool flag_top = false; bool flag_output = false; bool flag_scramble_name = false; + bool flag_unescape = false; bool got_mode = false; unsigned int seed = 1; @@ -312,6 +340,11 @@ struct RenamePass : public Pass { got_mode = true; continue; } + if (arg == "-unescape" && !got_mode) { + flag_unescape = true; + got_mode = true; + continue; + } if (arg == "-pattern" && argidx+1 < args.size() && args[argidx+1].find('%') != std::string::npos) { int pos = args[++argidx].find('%'); pattern_prefix = args[argidx].substr(0, pos); @@ -491,6 +524,48 @@ struct RenamePass : public Pass { module->rename(it.first, it.second); } } + else if (flag_unescape) + { + extra_args(args, argidx, design); + + for (auto module : design->selected_modules()) + { + dict new_wire_names; + dict new_cell_names; + + for (auto wire : module->selected_wires()) { + auto name = wire->name.str(); + if (name[0] != '\\') + continue; + name = name.substr(1); + if (!VERILOG_BACKEND::id_is_verilog_escaped(name)) + continue; + new_wire_names[wire] = module->uniquify("\\" + renamed_unescaped(name)); + auto new_name = new_wire_names[wire].str().substr(1); + if (VERILOG_BACKEND::id_is_verilog_escaped(new_name)) + log_error("Failed to rename wire %s -> %s\n", name.c_str(), new_name.c_str()); + } + + for (auto cell : module->selected_cells()) { + auto name = cell->name.str(); + if (name[0] != '\\') + continue; + name = name.substr(1); + if (!VERILOG_BACKEND::id_is_verilog_escaped(name)) + continue; + new_cell_names[cell] = module->uniquify("\\" + renamed_unescaped(name)); + auto new_name = new_cell_names[cell].str().substr(1); + if (VERILOG_BACKEND::id_is_verilog_escaped(new_name)) + log_error("Failed to rename cell %s -> %s\n", name.c_str(), new_name.c_str()); + } + + for (auto &it : new_wire_names) + module->rename(it.first, it.second); + + for (auto &it : new_cell_names) + module->rename(it.first, it.second); + } + } else { if (argidx+2 != args.size()) diff --git a/tests/various/rename_unescape.ys b/tests/various/rename_unescape.ys new file mode 100644 index 000000000..546d97357 --- /dev/null +++ b/tests/various/rename_unescape.ys @@ -0,0 +1,41 @@ +read_verilog < Date: Wed, 2 Jul 2025 12:39:18 +1000 Subject: [PATCH 07/20] Gowin. BUGFIX. Fix multi-line descriptions. If let's say the enumeration of inputs took several lines, then all after the first one were ignored. Since the first line ended with a comma, an error was generated when trying to use the resulting file. Signed-off-by: YRabbit --- techlibs/gowin/cells_xtra.py | 10 + techlibs/gowin/cells_xtra_gw5a.v | 601 +++++++++++++++++++++++++++++-- 2 files changed, 585 insertions(+), 26 deletions(-) diff --git a/techlibs/gowin/cells_xtra.py b/techlibs/gowin/cells_xtra.py index be2e0eff3..7a7c9ac0a 100644 --- a/techlibs/gowin/cells_xtra.py +++ b/techlibs/gowin/cells_xtra.py @@ -11,6 +11,7 @@ import re class State(Enum): OUTSIDE = auto() IN_MODULE = auto() + IN_MODULE_MULTILINE = auto() IN_PARAMETER = auto() _skip = { # These are already described, no need to extract them from the vendor files @@ -47,12 +48,20 @@ def xtract_cells_decl(dir, fout): fout.write(l) if l[-1] != '\n': fout.write('\n') + if l.rstrip()[-1] != ';': + state = State.IN_MODULE_MULTILINE elif l.startswith('parameter') and state == State.IN_MODULE: fout.write(l) if l.rstrip()[-1] == ',': state = State.IN_PARAMETER if l[-1] != '\n': fout.write('\n') + elif l and state == State.IN_MODULE_MULTILINE: + fout.write(l) + if l[-1] != '\n': + fout.write('\n') + if l.rstrip()[-1] == ';': + state = State.IN_MODULE elif state == State.IN_PARAMETER: fout.write(l) if l.rstrip()[-1] == ';': @@ -65,6 +74,7 @@ def xtract_cells_decl(dir, fout): if l[-1] != '\n': fout.write('\n') + if __name__ == '__main__': parser = ArgumentParser(description='Extract Gowin blackbox cell definitions.') parser.add_argument('gowin_dir', nargs='?', default='/opt/gowin/') diff --git a/techlibs/gowin/cells_xtra_gw5a.v b/techlibs/gowin/cells_xtra_gw5a.v index d19435f85..c82f6af25 100644 --- a/techlibs/gowin/cells_xtra_gw5a.v +++ b/techlibs/gowin/cells_xtra_gw5a.v @@ -80,19 +80,8 @@ endmodule module MIPI_OBUF_A (...); output O, OB; input I, IB, IL, MODESEL; -endmodule - -module IBUF_R (...); -input I; -input RTEN; -output O; -endmodule - -module IOBUF_R (...); -input I,OEN; -input RTEN; -output O; -inout IO; +inout IO, IOB; +input OEN, OENB; endmodule module ELVDS_IOBUF_R (...); @@ -113,6 +102,21 @@ input I, IB; input ADCEN; endmodule +module MIPI_CPHY_IBUF (...); +output OH0, OL0, OB0, OH1, OL1, OB1, OH2, OL2, OB2; +inout IO0, IOB0, IO1, IOB1, IO2, IOB2; +input I0, IB0, I1, IB1, I2, IB2; +input OEN, OENB; +input HSEN; +endmodule + +module MIPI_CPHY_OBUF (...); +output O0, OB0, O1, OB1, O2, OB2; +input I0, IB0, IL0, I1, IB1, IL1, I2, IB2, IL2; +inout IO0, IOB0, IO1, IOB1, IO2, IOB2; +input OEN, OENB, MODESEL, VCOME; +endmodule + module SDPB (...); parameter READ_MODE = 1'b0; parameter BIT_WIDTH_0 = 32; @@ -598,8 +602,8 @@ endmodule module SDP36KE (...); -parameter ECC_WRITE_EN="FALSE"; -parameter ECC_READ_EN="FALSE"; +parameter ECC_WRITE_EN="TRUE"; +parameter ECC_READ_EN="TRUE"; parameter READ_MODE = 1'b0; parameter BLK_SEL_A = 3'b000; parameter BLK_SEL_B = 3'b000; @@ -764,6 +768,14 @@ output [7:0] ECCP; endmodule +module SDP136K (...); +input CLKA, CLKB; +input WE, RE; +input [10:0] ADA, ADB; +input [67:0] DI; +output [67:0] DO; +endmodule + module MULTADDALU12X12 (...); parameter A0REG_CLK = "BYPASS"; parameter A0REG_CE = "CE0"; @@ -980,6 +992,24 @@ input PSEL; input PADDSUB; endmodule +module MULTACC (...); +output [23:0] DATAO, CASO; +input CE, CLK; +input [5:0] COFFIN0, COFFIN1, COFFIN2; +input [9:0] DATAIN0, DATAIN1; +input [9:0] DATAIN2; +input RSTN; +input [23:0] CASI; +parameter COFFIN_WIDTH = 4; +parameter DATAIN_WIDTH = 8; +parameter IREG = 1'b0; +parameter OREG = 1'b0; +parameter PREG = 1'b0; +parameter ACC_EN = "FALSE"; +parameter CASI_EN = "FALSE"; +parameter CASO_EN = "FALSE"; +endmodule + module IDDR_MEM (...); input D, ICLK, PCLK; input [2:0] WADDR; @@ -1048,6 +1078,12 @@ output Q0, Q1; endmodule +module OSER14 (...); +input D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13; +input PCLK, FCLK, RESET; +output Q; +endmodule + module IODELAY (...); parameter C_STATIC_DLY = 0; parameter DYN_DLY_EN = "FALSE"; @@ -1066,13 +1102,39 @@ output [31:0] Q; input D; input PCLK, FCLKP, FCLKN, FCLKQP, FCLKQN; input RESET; -output DF; -input SDTAP; -input VALUE; -input [7:0] DLYSTEP; -parameter C_STATIC_DLY = 0; -parameter DYN_DLY_EN = "FALSE"; -parameter ADAPT_EN = "FALSE"; +output DF0, DF1; +input SDTAP0, SDTAP1; +input VALUE0,VALUE1; +input [7:0] DLYSTEP0,DLYSTEP1; +parameter C_STATIC_DLY_0 = 0; +parameter DYN_DLY_EN_0 = "FALSE"; +parameter ADAPT_EN_0 = "FALSE"; +parameter C_STATIC_DLY_1 = 0; +parameter DYN_DLY_EN_1 = "FALSE"; +parameter ADAPT_EN_1 = "FALSE"; +endmodule + +module OSIDES64 (...); +output [63:0] Q; +input D; +input PCLK, FCLKP, FCLKN, FCLKQP, FCLKQN; +input RESET; +output DF0, DF1, DF2, DF3; +input SDTAP0, SDTAP1, SDTAP2, SDTAP3; +input VALUE0, VALUE1, VALUE2, VALUE3; +input [7:0] DLYSTEP0, DLYSTEP1, DLYSTEP2, DLYSTEP3; +parameter C_STATIC_DLY_0 = 0; +parameter DYN_DLY_EN_0 = "FALSE"; +parameter ADAPT_EN_0 = "FALSE"; +parameter C_STATIC_DLY_1 = 0; +parameter DYN_DLY_EN_1 = "FALSE"; +parameter ADAPT_EN_1 = "FALSE"; +parameter C_STATIC_DLY_2 = 0; +parameter DYN_DLY_EN_2 = "FALSE"; +parameter ADAPT_EN_2 = "FALSE"; +parameter C_STATIC_DLY_3 = 0; +parameter DYN_DLY_EN_3 = "FALSE"; +parameter ADAPT_EN_3 = "FALSE"; endmodule module DCE (...); @@ -1132,6 +1194,17 @@ output OSCOUT; input OSCEN; endmodule +module OSCB (...); +parameter FREQ_MODE = "25"; +parameter FREQ_DIV = 10; +parameter DYN_TRIM_EN = "FALSE"; +output OSCOUT; +output OSCREF; +input OSCEN, FMODE; +input [7:0] RTRIM; +input [5:0] RTCTRIM; +endmodule + module PLL (...); input CLKIN; input CLKFB; @@ -1571,8 +1644,8 @@ input ADWSEL; endmodule module OTP (...); -parameter MODE = 1'b0; -input READ, SHIFT; +parameter MODE = 2'b01; +input CLK, READ, SHIFT; output DOUT; endmodule @@ -1615,6 +1688,31 @@ input ERR0INJECT,ERR1INJECT; input [6:0] ERRINJ0LOC,ERRINJ1LOC; endmodule +module CMSERB (...); +output RUNNING; +output CRCERR; +output CRCDONE; +output ECCCORR; +output ECCUNCORR; +output [12:0] ERRLOC; +output ECCDEC; +output DSRRD; +output DSRWR; +output ASRRESET; +output ASRINC; +output REFCLK; +input CLK; +input [2:0] SEREN; +input ERR0INJECT,ERR1INJECT; +input [6:0] ERRINJ0LOC,ERRINJ1LOC; +endmodule + +module SAMBA (...); +parameter MODE = 2'b00; +input SPIAD; +input LOAD; +endmodule + module ADCLRC (...); endmodule @@ -1624,6 +1722,12 @@ endmodule module ADC (...); endmodule +module ADC_SAR (...); +endmodule + +module LICD (...); +endmodule + module MIPI_DPHY (...); output RX_CLK_O, TX_CLK_O; output [15:0] D0LN_HSRXD, D1LN_HSRXD, D2LN_HSRXD, D3LN_HSRXD; @@ -1632,6 +1736,7 @@ input D0LN_HSRX_DREN, D1LN_HSRX_DREN, D2LN_HSRX_DREN, D3LN_HSRX_DREN; output DI_LPRX0_N, DI_LPRX0_P, DI_LPRX1_N, DI_LPRX1_P, DI_LPRX2_N, DI_LPRX2_P, DI_LPRX3_N, DI_LPRX3_P, DI_LPRXCK_N, DI_LPRXCK_P; inout CK_N, CK_P, D0_N, D0_P, D1_N, D1_P, D2_N, D2_P, D3_N, D3_P; input HSRX_STOP, HSTXEN_LN0, HSTXEN_LN1, HSTXEN_LN2, HSTXEN_LN3, HSTXEN_LNCK, + LPTXEN_LN0, LPTXEN_LN1, LPTXEN_LN2, LPTXEN_LN3, LPTXEN_LNCK; input PWRON_RX, PWRON_TX, RESET, RX_CLK_1X, TX_CLK_1X; input TXDPEN_LN0, TXDPEN_LN1, TXDPEN_LN2, TXDPEN_LN3, TXDPEN_LNCK, TXHCLK_EN; input [15:0] CKLN_HSTXD,D0LN_HSTXD,D1LN_HSTXD,D2LN_HSTXD,D3LN_HSTXD; @@ -1639,6 +1744,8 @@ input HSTXD_VLD; input CK0, CK90, CK180, CK270; input DO_LPTX0_N, DO_LPTX1_N, DO_LPTX2_N, DO_LPTX3_N, DO_LPTXCK_N, DO_LPTX0_P, DO_LPTX1_P, DO_LPTX2_P, DO_LPTX3_P, DO_LPTXCK_P; input HSRX_EN_CK, HSRX_EN_D0, HSRX_EN_D1, HSRX_EN_D2, HSRX_EN_D3, HSRX_ODTEN_CK, + HSRX_ODTEN_D0, HSRX_ODTEN_D1, HSRX_ODTEN_D2, HSRX_ODTEN_D3, LPRX_EN_CK, + LPRX_EN_D0, LPRX_EN_D1, LPRX_EN_D2, LPRX_EN_D3; input RX_DRST_N, TX_DRST_N, WALIGN_DVLD; output [7:0] MRDATA; input MA_INC, MCLK; @@ -1714,7 +1821,7 @@ parameter RX_RD_START_DEPTH = 5'b00001; parameter RX_SYNC_MODE = 1'b0 ; parameter RX_WORD_ALIGN_BYPASS = 1'b0 ; parameter RX_WORD_ALIGN_DATA_VLD_SRC_SEL = 1'b0 ; -parameter RX_WORD_LITTLE_ENDIAN = 1'b0 ; +parameter RX_WORD_LITTLE_ENDIAN = 1'b1 ; parameter TX_BYPASS_MODE = 1'b0 ; parameter TX_BYTECLK_SYNC_MODE = 1'b0 ; parameter TX_OCLK_USE_CIBCLK = 1'b0 ; @@ -1917,6 +2024,437 @@ parameter TEST_P_IMP_LN3 = 1'b0 ; parameter TEST_P_IMP_LNCK = 1'b0 ; endmodule +module MIPI_DPHYA (...); +output RX_CLK_O, TX_CLK_O; +output [15:0] D0LN_HSRXD, D1LN_HSRXD, D2LN_HSRXD, D3LN_HSRXD; +output D0LN_HSRXD_VLD,D1LN_HSRXD_VLD,D2LN_HSRXD_VLD,D3LN_HSRXD_VLD; +input D0LN_HSRX_DREN, D1LN_HSRX_DREN, D2LN_HSRX_DREN, D3LN_HSRX_DREN; +output DI_LPRX0_N, DI_LPRX0_P, DI_LPRX1_N, DI_LPRX1_P, DI_LPRX2_N, DI_LPRX2_P, DI_LPRX3_N, DI_LPRX3_P, DI_LPRXCK_N, DI_LPRXCK_P; +inout CK_N, CK_P, D0_N, D0_P, D1_N, D1_P, D2_N, D2_P, D3_N, D3_P; +input HSRX_STOP, HSTXEN_LN0, HSTXEN_LN1, HSTXEN_LN2, HSTXEN_LN3, HSTXEN_LNCK, + LPTXEN_LN0, LPTXEN_LN1, LPTXEN_LN2, LPTXEN_LN3, LPTXEN_LNCK; +input PWRON_RX, PWRON_TX, RESET, RX_CLK_1X, TX_CLK_1X; +input TXDPEN_LN0, TXDPEN_LN1, TXDPEN_LN2, TXDPEN_LN3, TXDPEN_LNCK, TXHCLK_EN; +input [15:0] CKLN_HSTXD,D0LN_HSTXD,D1LN_HSTXD,D2LN_HSTXD,D3LN_HSTXD; +input HSTXD_VLD; +input CK0, CK90, CK180, CK270; +input DO_LPTX0_N, DO_LPTX1_N, DO_LPTX2_N, DO_LPTX3_N, DO_LPTXCK_N, DO_LPTX0_P, DO_LPTX1_P, DO_LPTX2_P, DO_LPTX3_P, DO_LPTXCK_P; +input HSRX_EN_CK, HSRX_EN_D0, HSRX_EN_D1, HSRX_EN_D2, HSRX_EN_D3, HSRX_ODTEN_CK, + HSRX_ODTEN_D0, HSRX_ODTEN_D1, HSRX_ODTEN_D2, HSRX_ODTEN_D3, LPRX_EN_CK, + LPRX_EN_D0, LPRX_EN_D1, LPRX_EN_D2, LPRX_EN_D3; +input RX_DRST_N, TX_DRST_N, WALIGN_DVLD; +output [7:0] MRDATA; +input MA_INC, MCLK; +input [1:0] MOPCODE; +input [7:0] MWDATA; +input SPLL_CKN, SPLL_CKP; +output ALPEDO_LANE0, ALPEDO_LANE1, ALPEDO_LANE2, ALPEDO_LANE3, ALPEDO_LANECK; +output D1LN_DESKEW_DONE,D2LN_DESKEW_DONE,D3LN_DESKEW_DONE,D0LN_DESKEW_DONE; +output D1LN_DESKEW_ERROR, D2LN_DESKEW_ERROR, D3LN_DESKEW_ERROR, D0LN_DESKEW_ERROR; +input D0LN_DESKEW_REQ, D1LN_DESKEW_REQ, D2LN_DESKEW_REQ, D3LN_DESKEW_REQ; +input HSRX_DLYDIR_LANE0, HSRX_DLYDIR_LANE1, HSRX_DLYDIR_LANE2, HSRX_DLYDIR_LANE3, HSRX_DLYDIR_LANECK; +input HSRX_DLYLDN_LANE0, HSRX_DLYLDN_LANE1, HSRX_DLYLDN_LANE2, HSRX_DLYLDN_LANE3, HSRX_DLYLDN_LANECK; +input HSRX_DLYMV_LANE0, HSRX_DLYMV_LANE1, HSRX_DLYMV_LANE2, HSRX_DLYMV_LANE3, HSRX_DLYMV_LANECK; +input ALP_EDEN_LANE0, ALP_EDEN_LANE1, ALP_EDEN_LANE2, ALP_EDEN_LANE3, ALP_EDEN_LANECK, ALPEN_LN0, ALPEN_LN1, ALPEN_LN2, ALPEN_LN3, ALPEN_LNCK; +parameter TX_PLLCLK = "NONE"; +parameter RX_ALIGN_BYTE = 8'b10111000 ; +parameter RX_HS_8BIT_MODE = 1'b0 ; +parameter RX_LANE_ALIGN_EN = 1'b0 ; +parameter TX_HS_8BIT_MODE = 1'b0 ; +parameter HSREG_EN_LN0 = 1'b0; +parameter HSREG_EN_LN1 = 1'b0; +parameter HSREG_EN_LN2 = 1'b0; +parameter HSREG_EN_LN3 = 1'b0; +parameter HSREG_EN_LNCK = 1'b0; +parameter LANE_DIV_SEL = 2'b00; +parameter HSRX_EN = 1'b1 ; +parameter HSRX_LANESEL = 4'b1111 ; +parameter HSRX_LANESEL_CK = 1'b1 ; +parameter HSTX_EN_LN0 = 1'b0 ; +parameter HSTX_EN_LN1 = 1'b0 ; +parameter HSTX_EN_LN2 = 1'b0 ; +parameter HSTX_EN_LN3 = 1'b0 ; +parameter HSTX_EN_LNCK = 1'b0 ; +parameter LPTX_EN_LN0 = 1'b1 ; +parameter LPTX_EN_LN1 = 1'b1 ; +parameter LPTX_EN_LN2 = 1'b1 ; +parameter LPTX_EN_LN3 = 1'b1 ; +parameter LPTX_EN_LNCK = 1'b1 ; +parameter TXDP_EN_LN0 = 1'b0 ; +parameter TXDP_EN_LN1 = 1'b0 ; +parameter TXDP_EN_LN2 = 1'b0 ; +parameter TXDP_EN_LN3 = 1'b0 ; +parameter TXDP_EN_LNCK = 1'b0 ; +parameter SPLL_DIV_SEL = 2'b00; +parameter DPHY_CK_SEL = 2'b01; +parameter CKLN_DELAY_EN = 1'b0; +parameter CKLN_DELAY_OVR_VAL = 7'b0000000; +parameter D0LN_DELAY_EN = 1'b0; +parameter D0LN_DELAY_OVR_VAL = 7'b0000000; +parameter D0LN_DESKEW_BYPASS = 1'b0; +parameter D1LN_DELAY_EN = 1'b0; +parameter D1LN_DELAY_OVR_VAL = 7'b0000000; +parameter D1LN_DESKEW_BYPASS = 1'b0; +parameter D2LN_DELAY_EN = 1'b0; +parameter D2LN_DELAY_OVR_VAL = 7'b0000000; +parameter D2LN_DESKEW_BYPASS = 1'b0; +parameter D3LN_DELAY_EN = 1'b0; +parameter D3LN_DELAY_OVR_VAL = 7'b0000000; +parameter D3LN_DESKEW_BYPASS = 1'b0; +parameter DESKEW_EN_LOW_DELAY = 1'b0; +parameter DESKEW_EN_ONE_EDGE = 1'b0; +parameter DESKEW_FAST_LOOP_TIME = 4'b0000; +parameter DESKEW_FAST_MODE = 1'b0; +parameter DESKEW_HALF_OPENING = 6'b010110; +parameter DESKEW_LSB_MODE = 2'b00; +parameter DESKEW_M = 3'b011; +parameter DESKEW_M_TH = 13'b0000110100110; +parameter DESKEW_MAX_SETTING = 7'b0100001; +parameter DESKEW_ONE_CLK_EDGE_EN = 1'b0 ; +parameter DESKEW_RST_BYPASS = 1'b0 ; +parameter RX_BYTE_LITTLE_ENDIAN = 1'b1 ; +parameter RX_CLK_1X_SYNC_SEL = 1'b0 ; +parameter RX_INVERT = 1'b0 ; +parameter RX_ONE_BYTE0_MATCH = 1'b0 ; +parameter RX_RD_START_DEPTH = 5'b00001; +parameter RX_SYNC_MODE = 1'b0 ; +parameter RX_WORD_ALIGN_BYPASS = 1'b0 ; +parameter RX_WORD_ALIGN_DATA_VLD_SRC_SEL = 1'b0 ; +parameter RX_WORD_LITTLE_ENDIAN = 1'b1 ; +parameter TX_BYPASS_MODE = 1'b0 ; +parameter TX_BYTECLK_SYNC_MODE = 1'b0 ; +parameter TX_OCLK_USE_CIBCLK = 1'b0 ; +parameter TX_RD_START_DEPTH = 5'b00001; +parameter TX_SYNC_MODE = 1'b0 ; +parameter TX_WORD_LITTLE_ENDIAN = 1'b1 ; +parameter EQ_CS_LANE0 = 3'b100; +parameter EQ_CS_LANE1 = 3'b100; +parameter EQ_CS_LANE2 = 3'b100; +parameter EQ_CS_LANE3 = 3'b100; +parameter EQ_CS_LANECK = 3'b100; +parameter EQ_RS_LANE0 = 3'b100; +parameter EQ_RS_LANE1 = 3'b100; +parameter EQ_RS_LANE2 = 3'b100; +parameter EQ_RS_LANE3 = 3'b100; +parameter EQ_RS_LANECK = 3'b100; +parameter HSCLK_LANE_LN0 = 1'b0; +parameter HSCLK_LANE_LN1 = 1'b0; +parameter HSCLK_LANE_LN2 = 1'b0; +parameter HSCLK_LANE_LN3 = 1'b0; +parameter HSCLK_LANE_LNCK = 1'b1; +parameter ALP_ED_EN_LANE0 = 1'b1 ; +parameter ALP_ED_EN_LANE1 = 1'b1 ; +parameter ALP_ED_EN_LANE2 = 1'b1 ; +parameter ALP_ED_EN_LANE3 = 1'b1 ; +parameter ALP_ED_EN_LANECK = 1'b1 ; +parameter ALP_ED_TST_LANE0 = 1'b0 ; +parameter ALP_ED_TST_LANE1 = 1'b0 ; +parameter ALP_ED_TST_LANE2 = 1'b0 ; +parameter ALP_ED_TST_LANE3 = 1'b0 ; +parameter ALP_ED_TST_LANECK = 1'b0 ; +parameter ALP_EN_LN0 = 1'b0 ; +parameter ALP_EN_LN1 = 1'b0 ; +parameter ALP_EN_LN2 = 1'b0 ; +parameter ALP_EN_LN3 = 1'b0 ; +parameter ALP_EN_LNCK = 1'b0 ; +parameter ALP_HYS_EN_LANE0 = 1'b1 ; +parameter ALP_HYS_EN_LANE1 = 1'b1 ; +parameter ALP_HYS_EN_LANE2 = 1'b1 ; +parameter ALP_HYS_EN_LANE3 = 1'b1 ; +parameter ALP_HYS_EN_LANECK = 1'b1 ; +parameter ALP_TH_LANE0 = 4'b1000 ; +parameter ALP_TH_LANE1 = 4'b1000 ; +parameter ALP_TH_LANE2 = 4'b1000 ; +parameter ALP_TH_LANE3 = 4'b1000 ; +parameter ALP_TH_LANECK = 4'b1000 ; +parameter ANA_BYTECLK_PH = 2'b00 ; +parameter BIT_REVERSE_LN0 = 1'b0 ; +parameter BIT_REVERSE_LN1 = 1'b0 ; +parameter BIT_REVERSE_LN2 = 1'b0 ; +parameter BIT_REVERSE_LN3 = 1'b0 ; +parameter BIT_REVERSE_LNCK = 1'b0 ; +parameter BYPASS_TXHCLKEN = 1'b1 ; +parameter BYPASS_TXHCLKEN_SYNC = 1'b0 ; +parameter BYTE_CLK_POLAR = 1'b0 ; +parameter BYTE_REVERSE_LN0 = 1'b0 ; +parameter BYTE_REVERSE_LN1 = 1'b0 ; +parameter BYTE_REVERSE_LN2 = 1'b0 ; +parameter BYTE_REVERSE_LN3 = 1'b0 ; +parameter BYTE_REVERSE_LNCK = 1'b0 ; +parameter EN_CLKB1X = 1'b1 ; +parameter EQ_PBIAS_LANE0 = 4'b1000 ; +parameter EQ_PBIAS_LANE1 = 4'b1000 ; +parameter EQ_PBIAS_LANE2 = 4'b1000 ; +parameter EQ_PBIAS_LANE3 = 4'b1000 ; +parameter EQ_PBIAS_LANECK = 4'b1000 ; +parameter EQ_ZLD_LANE0 = 4'b1000 ; +parameter EQ_ZLD_LANE1 = 4'b1000 ; +parameter EQ_ZLD_LANE2 = 4'b1000 ; +parameter EQ_ZLD_LANE3 = 4'b1000 ; +parameter EQ_ZLD_LANECK = 4'b1000 ; +parameter HIGH_BW_LANE0 = 1'b1 ; +parameter HIGH_BW_LANE1 = 1'b1 ; +parameter HIGH_BW_LANE2 = 1'b1 ; +parameter HIGH_BW_LANE3 = 1'b1 ; +parameter HIGH_BW_LANECK = 1'b1 ; +parameter HSREG_VREF_CTL = 3'b100 ; +parameter HSREG_VREF_EN = 1'b1 ; +parameter HSRX_DLY_CTL_CK = 7'b0000000 ; +parameter HSRX_DLY_CTL_LANE0 = 7'b0000000 ; +parameter HSRX_DLY_CTL_LANE1 = 7'b0000000 ; +parameter HSRX_DLY_CTL_LANE2 = 7'b0000000 ; +parameter HSRX_DLY_CTL_LANE3 = 7'b0000000 ; +parameter HSRX_DLY_SEL_LANE0 = 1'b0 ; +parameter HSRX_DLY_SEL_LANE1 = 1'b0 ; +parameter HSRX_DLY_SEL_LANE2 = 1'b0 ; +parameter HSRX_DLY_SEL_LANE3 = 1'b0 ; +parameter HSRX_DLY_SEL_LANECK = 1'b0 ; +parameter HSRX_DUTY_LANE0 = 4'b1000 ; +parameter HSRX_DUTY_LANE1 = 4'b1000 ; +parameter HSRX_DUTY_LANE2 = 4'b1000 ; +parameter HSRX_DUTY_LANE3 = 4'b1000 ; +parameter HSRX_DUTY_LANECK = 4'b1000 ; +parameter HSRX_EQ_EN_LANE0 = 1'b1 ; +parameter HSRX_EQ_EN_LANE1 = 1'b1 ; +parameter HSRX_EQ_EN_LANE2 = 1'b1 ; +parameter HSRX_EQ_EN_LANE3 = 1'b1 ; +parameter HSRX_EQ_EN_LANECK = 1'b1 ; +parameter HSRX_IBIAS = 4'b0011 ; +parameter HSRX_IBIAS_TEST_EN = 1'b0 ; +parameter HSRX_IMARG_EN = 1'b0 ; +parameter HSRX_ODT_EN = 1'b1 ; +parameter HSRX_ODT_TST = 4'b0000 ; +parameter HSRX_ODT_TST_CK = 1'b0 ; +parameter HSRX_SEL = 4'b0000 ; +parameter HSRX_STOP_EN = 1'b0 ; +parameter HSRX_TST = 4'b0000 ; +parameter HSRX_TST_CK = 1'b0 ; +parameter HSRX_WAIT4EDGE = 1'b1 ; +parameter HYST_NCTL = 2'b01 ; +parameter HYST_PCTL = 2'b01 ; +parameter IBIAS_TEST_EN = 1'b0 ; +parameter LB_CH_SEL = 1'b0 ; +parameter LB_EN_LN0 = 1'b0 ; +parameter LB_EN_LN1 = 1'b0 ; +parameter LB_EN_LN2 = 1'b0 ; +parameter LB_EN_LN3 = 1'b0 ; +parameter LB_EN_LNCK = 1'b0 ; +parameter LB_POLAR_LN0 = 1'b0 ; +parameter LB_POLAR_LN1 = 1'b0 ; +parameter LB_POLAR_LN2 = 1'b0 ; +parameter LB_POLAR_LN3 = 1'b0 ; +parameter LB_POLAR_LNCK = 1'b0 ; +parameter LOW_LPRX_VTH = 1'b0 ; +parameter LPBK_DATA2TO1 = 4'b0000; +parameter LPBK_DATA2TO1_CK = 1'b0 ; +parameter LPBK_EN = 1'b0 ; +parameter LPBK_SEL = 4'b0000; +parameter LPBKTST_EN = 4'b0000; +parameter LPBKTST_EN_CK = 1'b0 ; +parameter LPRX_EN = 1'b1 ; +parameter LPRX_TST = 4'b0000; +parameter LPRX_TST_CK = 1'b0 ; +parameter LPTX_DAT_POLAR_LN0 = 1'b0 ; +parameter LPTX_DAT_POLAR_LN1 = 1'b0 ; +parameter LPTX_DAT_POLAR_LN2 = 1'b0 ; +parameter LPTX_DAT_POLAR_LN3 = 1'b0 ; +parameter LPTX_DAT_POLAR_LNCK = 1'b0 ; +parameter LPTX_NIMP_LN0 = 3'b100 ; +parameter LPTX_NIMP_LN1 = 3'b100 ; +parameter LPTX_NIMP_LN2 = 3'b100 ; +parameter LPTX_NIMP_LN3 = 3'b100 ; +parameter LPTX_NIMP_LNCK = 3'b100 ; +parameter LPTX_PIMP_LN0 = 3'b100 ; +parameter LPTX_PIMP_LN1 = 3'b100 ; +parameter LPTX_PIMP_LN2 = 3'b100 ; +parameter LPTX_PIMP_LN3 = 3'b100 ; +parameter LPTX_PIMP_LNCK = 3'b100 ; +parameter MIPI_PMA_DIS_N = 1'b1 ; +parameter PGA_BIAS_LANE0 = 4'b1000 ; +parameter PGA_BIAS_LANE1 = 4'b1000 ; +parameter PGA_BIAS_LANE2 = 4'b1000 ; +parameter PGA_BIAS_LANE3 = 4'b1000 ; +parameter PGA_BIAS_LANECK = 4'b1000 ; +parameter PGA_GAIN_LANE0 = 4'b1000 ; +parameter PGA_GAIN_LANE1 = 4'b1000 ; +parameter PGA_GAIN_LANE2 = 4'b1000 ; +parameter PGA_GAIN_LANE3 = 4'b1000 ; +parameter PGA_GAIN_LANECK = 4'b1000 ; +parameter RX_ODT_TRIM_LANE0 = 4'b1000 ; +parameter RX_ODT_TRIM_LANE1 = 4'b1000 ; +parameter RX_ODT_TRIM_LANE2 = 4'b1000 ; +parameter RX_ODT_TRIM_LANE3 = 4'b1000 ; +parameter RX_ODT_TRIM_LANECK = 4'b1000 ; +parameter SLEWN_CTL_LN0 = 4'b1111 ; +parameter SLEWN_CTL_LN1 = 4'b1111 ; +parameter SLEWN_CTL_LN2 = 4'b1111 ; +parameter SLEWN_CTL_LN3 = 4'b1111 ; +parameter SLEWN_CTL_LNCK = 4'b1111 ; +parameter SLEWP_CTL_LN0 = 4'b1111 ; +parameter SLEWP_CTL_LN1 = 4'b1111 ; +parameter SLEWP_CTL_LN2 = 4'b1111 ; +parameter SLEWP_CTL_LN3 = 4'b1111 ; +parameter SLEWP_CTL_LNCK = 4'b1111 ; +parameter STP_UNIT = 2'b01 ; +parameter TERMN_CTL_LN0 = 4'b1000 ; +parameter TERMN_CTL_LN1 = 4'b1000 ; +parameter TERMN_CTL_LN2 = 4'b1000 ; +parameter TERMN_CTL_LN3 = 4'b1000 ; +parameter TERMN_CTL_LNCK = 4'b1000 ; +parameter TERMP_CTL_LN0 = 4'b1000 ; +parameter TERMP_CTL_LN1 = 4'b1000 ; +parameter TERMP_CTL_LN2 = 4'b1000 ; +parameter TERMP_CTL_LN3 = 4'b1000 ; +parameter TERMP_CTL_LNCK = 4'b1000 ; +parameter TEST_EN_LN0 = 1'b0 ; +parameter TEST_EN_LN1 = 1'b0 ; +parameter TEST_EN_LN2 = 1'b0 ; +parameter TEST_EN_LN3 = 1'b0 ; +parameter TEST_EN_LNCK = 1'b0 ; +parameter TEST_N_IMP_LN0 = 1'b0 ; +parameter TEST_N_IMP_LN1 = 1'b0 ; +parameter TEST_N_IMP_LN2 = 1'b0 ; +parameter TEST_N_IMP_LN3 = 1'b0 ; +parameter TEST_N_IMP_LNCK = 1'b0 ; +parameter TEST_P_IMP_LN0 = 1'b0 ; +parameter TEST_P_IMP_LN1 = 1'b0 ; +parameter TEST_P_IMP_LN2 = 1'b0 ; +parameter TEST_P_IMP_LN3 = 1'b0 ; +parameter TEST_P_IMP_LNCK = 1'b0 ; +endmodule + +module MIPI_CPHY (...); +output [41:0] D0LN_HSRXD, D1LN_HSRXD, D2LN_HSRXD; +output D0LN_HSRXD_VLD, D1LN_HSRXD_VLD, D2LN_HSRXD_VLD; +output [1:0] D0LN_HSRX_DEMAP_INVLD, D1LN_HSRX_DEMAP_INVLD, D2LN_HSRX_DEMAP_INVLD; +output D0LN_HSRX_FIFO_RDE_ERR, D0LN_HSRX_FIFO_WRF_ERR, D1LN_HSRX_FIFO_RDE_ERR, D1LN_HSRX_FIFO_WRF_ERR, D2LN_HSRX_FIFO_RDE_ERR, D2LN_HSRX_FIFO_WRF_ERR; +output [1:0] D0LN_HSRX_WA, D1LN_HSRX_WA, D2LN_HSRX_WA; +output D0LN_RX_CLK_1X_O, D1LN_RX_CLK_1X_O, D2LN_RX_CLK_1X_O; +output HSTX_FIFO_AE, HSTX_FIFO_AF; +output HSTX_FIFO_RDE_ERR, HSTX_FIFO_WRF_ERR; +output RX_CLK_MUXED; +output TX_CLK_1X_O; +output DI_LPRX0_A, DI_LPRX0_B, DI_LPRX0_C, DI_LPRX1_A, DI_LPRX1_B, DI_LPRX1_C, DI_LPRX2_A, DI_LPRX2_B, DI_LPRX2_C; +output [7:0] MDRP_RDATA; +inout D0A, D0B, D0C, D1A, D1B, D1C, D2A, D2B, D2C; +input D0LN_HSRX_EN, D0LN_HSTX_EN, D1LN_HSRX_EN, D1LN_HSTX_EN, D2LN_HSRX_EN, D2LN_HSTX_EN; +input [41:0] D0LN_HSTX_DATA,D1LN_HSTX_DATA, D2LN_HSTX_DATA; +input D0LN_HSTX_DATA_VLD, D1LN_HSTX_DATA_VLD, D2LN_HSTX_DATA_VLD; +input [1:0] D0LN_HSTX_MAP_DIS, D1LN_HSTX_MAP_DIS, D2LN_HSTX_MAP_DIS; +input D0LN_RX_CLK_1X_I,D1LN_RX_CLK_1X_I, D2LN_RX_CLK_1X_I; +input D0LN_RX_DRST_N, D0LN_TX_DRST_N, D1LN_RX_DRST_N, D1LN_TX_DRST_N, D2LN_RX_DRST_N, D2LN_TX_DRST_N; +input HSTX_ENLN0, HSTX_ENLN1, HSTX_ENLN2, LPTX_ENLN0, LPTX_ENLN1, LPTX_ENLN2; +input [7:0] MDRP_A_D_I; +input MDRP_A_INC_I; +input MDRP_CLK_I; +input [1:0] MDRP_OPCODE_I; +input PWRON_RX_LN0, PWRON_RX_LN1, PWRON_RX_LN2, PWRON_TX; +input ARST_RXLN0, ARST_RXLN1, ARST_RXLN2; +input ARSTN_TX; +input RX_CLK_EN_LN0, RX_CLK_EN_LN1, RX_CLK_EN_LN2; +input TX_CLK_1X_I; +input TXDP_ENLN0, TXDP_ENLN1, TXDP_ENLN2; +input TXHCLK_EN; +input DO_LPTX_A_LN0, DO_LPTX_A_LN1, DO_LPTX_A_LN2, DO_LPTX_B_LN0, DO_LPTX_B_LN1, DO_LPTX_B_LN2, DO_LPTX_C_LN0, DO_LPTX_C_LN1, DO_LPTX_C_LN2; +input GPLL_CK0,GPLL_CK90, GPLL_CK180, GPLL_CK270; +input HSRX_EN_D0, HSRX_EN_D1, HSRX_EN_D2; +input HSRX_ODT_EN_D0, HSRX_ODT_EN_D1, HSRX_ODT_EN_D2; +input LPRX_EN_D0, LPRX_EN_D1, LPRX_EN_D2; +input SPLL0_CKN, SPLL0_CKP, SPLL1_CKN, SPLL1_CKP; +parameter TX_PLLCLK = "NONE"; +parameter D0LN_HS_TX_EN = 1'b1; +parameter D1LN_HS_TX_EN = 1'b1; +parameter D2LN_HS_TX_EN = 1'b1; +parameter D0LN_HS_RX_EN = 1'b1; +parameter D1LN_HS_RX_EN = 1'b1; +parameter D2LN_HS_RX_EN = 1'b1; +parameter TX_HS_21BIT_MODE = 1'b0; +parameter RX_OUTCLK_SEL = 2'b00; +parameter TX_W_LENDIAN = 1'b1; +parameter CLK_SEL = 2'b00; +parameter LNDIV_RATIO = 4'b0000; +parameter LNDIV_EN = 1'b0; +parameter D0LN_TX_REASGN_A = 2'b00; +parameter D0LN_TX_REASGN_B = 2'b01; +parameter D0LN_TX_REASGN_C = 2'b10; +parameter D0LN_RX_HS_21BIT_MODE = 1'b0; +parameter D0LN_RX_WA_SYNC_PAT0_EN = 1'b1; +parameter D0LN_RX_WA_SYNC_PAT0_H = 7'b1001001; +parameter D0LN_RX_WA_SYNC_PAT0_L = 8'b00100100; +parameter D0LN_RX_WA_SYNC_PAT1_EN = 1'b1; +parameter D0LN_RX_WA_SYNC_PAT1_H = 7'b0101001; +parameter D0LN_RX_WA_SYNC_PAT1_L = 8'b00100100; +parameter D0LN_RX_WA_SYNC_PAT2_EN = 1'b1; +parameter D0LN_RX_WA_SYNC_PAT2_H = 7'b0011001; +parameter D0LN_RX_WA_SYNC_PAT2_L = 8'b00100100; +parameter D0LN_RX_WA_SYNC_PAT3_EN = 1'b0; +parameter D0LN_RX_WA_SYNC_PAT3_H = 7'b0001001; +parameter D0LN_RX_WA_SYNC_PAT3_L = 8'b00100100; +parameter D0LN_RX_W_LENDIAN = 1'b1; +parameter D0LN_RX_REASGN_A = 2'b00; +parameter D0LN_RX_REASGN_B = 2'b01; +parameter D0LN_RX_REASGN_C = 2'b10; +parameter HSRX_LNSEL = 3'b111; +parameter EQ_RS_LN0 = 3'b001; +parameter EQ_CS_LN0 = 3'b101; +parameter PGA_GAIN_LN0 = 4'b0110; +parameter PGA_BIAS_LN0 = 4'b1000; +parameter EQ_PBIAS_LN0 = 4'b0100; +parameter EQ_ZLD_LN0 = 4'b1000; +parameter D1LN_TX_REASGN_A = 2'b00; +parameter D1LN_TX_REASGN_B = 2'b01; +parameter D1LN_TX_REASGN_C = 2'b10; +parameter D1LN_RX_HS_21BIT_MODE = 1'b0; +parameter D1LN_RX_WA_SYNC_PAT0_EN = 1'b1; +parameter D1LN_RX_WA_SYNC_PAT0_H = 7'b1001001; +parameter D1LN_RX_WA_SYNC_PAT0_L = 8'b00100100; +parameter D1LN_RX_WA_SYNC_PAT1_EN = 1'b1; +parameter D1LN_RX_WA_SYNC_PAT1_H = 7'b0101001; +parameter D1LN_RX_WA_SYNC_PAT1_L = 8'b00100100; +parameter D1LN_RX_WA_SYNC_PAT2_EN = 1'b1; +parameter D1LN_RX_WA_SYNC_PAT2_H = 7'b0011001; +parameter D1LN_RX_WA_SYNC_PAT2_L = 8'b00100100; +parameter D1LN_RX_WA_SYNC_PAT3_EN = 1'b0; +parameter D1LN_RX_WA_SYNC_PAT3_H = 7'b0001001; +parameter D1LN_RX_WA_SYNC_PAT3_L = 8'b00100100; +parameter D1LN_RX_W_LENDIAN = 1'b1; +parameter D1LN_RX_REASGN_A = 2'b00; +parameter D1LN_RX_REASGN_B = 2'b01; +parameter D1LN_RX_REASGN_C = 2'b10; +parameter EQ_RS_LN1 = 3'b001; +parameter EQ_CS_LN1 = 3'b101; +parameter PGA_GAIN_LN1 = 4'b0110; +parameter PGA_BIAS_LN1 = 4'b1000; +parameter EQ_PBIAS_LN1 = 4'b0100; +parameter EQ_ZLD_LN1 = 4'b1000; +parameter D2LN_TX_REASGN_A = 2'b00; +parameter D2LN_TX_REASGN_B = 2'b01; +parameter D2LN_TX_REASGN_C = 2'b10; +parameter D2LN_RX_HS_21BIT_MODE = 1'b0; +parameter D2LN_RX_WA_SYNC_PAT0_EN = 1'b1; +parameter D2LN_RX_WA_SYNC_PAT0_H = 7'b1001001; +parameter D2LN_RX_WA_SYNC_PAT0_L = 8'b00100100; +parameter D2LN_RX_WA_SYNC_PAT1_EN = 1'b1; +parameter D2LN_RX_WA_SYNC_PAT1_H = 7'b0101001; +parameter D2LN_RX_WA_SYNC_PAT1_L = 8'b00100100; +parameter D2LN_RX_WA_SYNC_PAT2_EN = 1'b1; +parameter D2LN_RX_WA_SYNC_PAT2_H = 7'b0011001; +parameter D2LN_RX_WA_SYNC_PAT2_L = 8'b00100100; +parameter D2LN_RX_WA_SYNC_PAT3_EN = 1'b0; +parameter D2LN_RX_WA_SYNC_PAT3_H = 7'b0001001; +parameter D2LN_RX_WA_SYNC_PAT3_L = 8'b00100100; +parameter D2LN_RX_W_LENDIAN = 1'b1; +parameter D2LN_RX_REASGN_A = 2'b00; +parameter D2LN_RX_REASGN_B = 2'b01; +parameter D2LN_RX_REASGN_C = 2'b10; +parameter EQ_RS_LN2 = 3'b001; +parameter EQ_CS_LN2 = 3'b101; +parameter PGA_GAIN_LN2 = 4'b0110; +parameter PGA_BIAS_LN2 = 4'b1000; +parameter EQ_PBIAS_LN2 = 4'b0100; +parameter EQ_ZLD_LN2 = 4'b1000; +endmodule + module GTR12_QUAD (...); endmodule @@ -1926,6 +2464,18 @@ endmodule module GTR12_PMAC (...); endmodule +module GTR12_QUADA (...); +endmodule + +module GTR12_UPARA (...); +endmodule + +module GTR12_PMACA (...); +endmodule + +module GTR12_QUADB (...); +endmodule + module DQS (...); input DQSIN,PCLK,FCLK,RESET; input [3:0] READ; @@ -1941,4 +2491,3 @@ parameter RD_PNTR = 3'b000; parameter DQS_MODE = "X1"; parameter HWL = "false"; endmodule - From 5feb1a1752a7469fd5a02ec8afdb68794e55ef8f Mon Sep 17 00:00:00 2001 From: Gary Wong Date: Thu, 3 Jul 2025 20:51:12 -0600 Subject: [PATCH 08/20] verilog: add support for SystemVerilog string literals. Differences are new escape sequences (including escaped newline continuations and hex escapes) and triple-quoted literals. --- docs/source/yosys_internals/verilog.rst | 3 + frontends/verilog/verilog_lexer.l | 168 ++++++++++++---- tests/verilog/bug5160.v | 5 - tests/verilog/string-literals.ys | 257 ++++++++++++++++++++++++ 4 files changed, 386 insertions(+), 47 deletions(-) delete mode 100644 tests/verilog/bug5160.v create mode 100644 tests/verilog/string-literals.ys diff --git a/docs/source/yosys_internals/verilog.rst b/docs/source/yosys_internals/verilog.rst index 0039aaab7..d67553aa9 100644 --- a/docs/source/yosys_internals/verilog.rst +++ b/docs/source/yosys_internals/verilog.rst @@ -381,3 +381,6 @@ from SystemVerilog: will process conditionals using these keywords by annotating their representation with the appropriate ``full_case`` and/or ``parallel_case`` attributes, which are described above.) + +- SystemVerilog string literals are supported (triple-quoted strings and + escape sequences such as line continuations and hex escapes). diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index 40162b8d3..e2d7a2cd9 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -112,6 +112,129 @@ static bool isUserType(std::string &s) return false; } +static bool is_hex_dig(char c, int *val) +{ + if ('0' <= c && c <= '9') { + *val = c - '0'; + return true; + } else if ('a' <= c && c <= 'f') { + *val = c - 'a' + 0xA; + return true; + } else if ('A' <= c && c <= 'F') { + *val = c - 'A' + 0xA; + return true; + } else if (c == 'x' || c == 'X' || c == 'z' || c == 'Z' || c == '?') { + log_file_warning(AST::current_filename.c_str(), frontend_verilog_yyget_lineno(), "'%c' not a valid digit in hex escape sequence.\n", c); + *val = 0; // not semantically valid in hex escape... + return true; // ...but still processed as part of hex token + } + + return false; +} + +static bool is_oct_dig(char c, int *val) +{ + if ('0' <= c && c <= '7') { + *val = c - '0'; + return true; + } else if (c == 'x' || c == 'X' || c == 'z' || c == 'Z' || c == '?') { + log_file_warning(AST::current_filename.c_str(), frontend_verilog_yyget_lineno(), "'%c' not a valid digit in octal escape sequence.\n", c); + *val = 0; // not semantically valid in octal escape... + return true; // ...but still processed as part of octal token + } + + return false; +} + +static std::string *process_str(char *str, int len, bool triple) +{ + char *in, *out; // Overwrite input buffer: flex manual states "Actions + // are free to modify 'yytext' except for lengthening it". + + for (in = str, out = str; in < str + len; in++) + switch (*in) { + case '\n': + case '\r': + if (in + 1 < str + len && (in[1] ^ *in) == ('\n' ^ '\r')) + in++; + if (!triple) + log_file_warning(AST::current_filename.c_str(), frontend_verilog_yyget_lineno(), "Multi-line string literals should be triple-quoted or escaped.\n"); + *out++ = '\n'; + break; + case '\\': + in++; + log_assert(in < str + len); + switch (*in) { + case 'a': + *out++ = '\a'; + break; + case 'f': + *out++ = '\f'; + break; + case 'n': + *out++ = '\n'; + break; + case 'r': /* not part of IEEE-1800 2023, but seems + like a good idea to support it anyway */ + *out++ = '\r'; + break; + case 't': + *out++ = '\t'; + break; + case 'v': + *out++ = '\v'; + break; + case 'x': + int val; + if (in + 1 < str + len && is_hex_dig(in[1], &val)) { + *out = val; + in++; + if (in + 1 < str + len && is_hex_dig(in[1], &val)) { + *out = *out * 0x10 + val; + in++; + } + out++; + } else + log_file_warning(AST::current_filename.c_str(), frontend_verilog_yyget_lineno(), "ignoring invalid hex escape.\n"); + break; + case '\\': + *out++ = '\\'; + break; + case '"': + *out++ = '"'; + break; + case '\n': + case '\r': + if (in + 1 < str + len && (in[1] ^ *in) == ('\n' ^ '\r')) + in++; + break; + default: + if ('0' <= *in && *in <= '7') { + int val; + + *out = *in - '0'; + if (in + 1 < str + len && is_oct_dig(in[1], &val)) { + *out = *out * 010 + val; + in++; + if (in + 1 < str + len && is_oct_dig(in[1], &val)) { + if (*out >= 040) + log_file_warning(AST::current_filename.c_str(), frontend_verilog_yyget_lineno(), "octal escape exceeds \\377\n"); + *out = *out * 010 + val; + in++; + } + } + out++; + } else + *out++ = *in; + } + break; + default: + *out++ = *in; + } + + return new std::string(str, out - str); +} + %} %option yylineno @@ -122,7 +245,6 @@ static bool isUserType(std::string &s) %option prefix="frontend_verilog_yy" %x COMMENT -%x STRING %x SYNOPSYS_TRANSLATE_OFF %x SYNOPSYS_FLAGS %x IMPORT_DPI @@ -335,47 +457,9 @@ TIME_SCALE_SUFFIX [munpf]?s return TOK_REALVAL; } -\" { BEGIN(STRING); } -([^\\"]|\\.)+ { yymore(); real_location = old_location; } -\" { - BEGIN(0); - char *yystr = strdup(yytext); - yystr[strlen(yytext) - 1] = 0; - int i = 0, j = 0; - while (yystr[i]) { - if (yystr[i] == '\\' && yystr[i + 1]) { - i++; - if (yystr[i] == 'a') - yystr[i] = '\a'; - else if (yystr[i] == 'f') - yystr[i] = '\f'; - else if (yystr[i] == 'n') - yystr[i] = '\n'; - else if (yystr[i] == 'r') - yystr[i] = '\r'; - else if (yystr[i] == 't') - yystr[i] = '\t'; - else if (yystr[i] == 'v') - yystr[i] = '\v'; - else if ('0' <= yystr[i] && yystr[i] <= '7') { - yystr[i] = yystr[i] - '0'; - if ('0' <= yystr[i + 1] && yystr[i + 1] <= '7') { - yystr[i + 1] = yystr[i] * 8 + yystr[i + 1] - '0'; - i++; - } - if ('0' <= yystr[i + 1] && yystr[i + 1] <= '7') { - yystr[i + 1] = yystr[i] * 8 + yystr[i + 1] - '0'; - i++; - } - } - } - yystr[j++] = yystr[i++]; - } - yystr[j] = 0; - yylval->string = new std::string(yystr, j); - free(yystr); - return TOK_STRING; -} +\"([^\\"]|\\.|\\\n)*\" { yylval->string = process_str(yytext + 1, yyleng - 2, false); return TOK_STRING; } + +\"{3}(\"{0,2}([^\\"]|\\.|\\\n))*\"{3} { yylval->string = process_str(yytext + 3, yyleng - 6, true); return TOK_STRING; } and|nand|or|nor|xor|xnor|not|buf|bufif0|bufif1|notif0|notif1 { yylval->string = new std::string(yytext); diff --git a/tests/verilog/bug5160.v b/tests/verilog/bug5160.v deleted file mode 100644 index 5b141a360..000000000 --- a/tests/verilog/bug5160.v +++ /dev/null @@ -1,5 +0,0 @@ -// Regression test for bug mentioned in #5160: -// https://github.com/YosysHQ/yosys/pull/5160#issuecomment-2983643084 -module top; - initial $display( "\\" ); -endmodule diff --git a/tests/verilog/string-literals.ys b/tests/verilog/string-literals.ys new file mode 100644 index 000000000..a0f0f0460 --- /dev/null +++ b/tests/verilog/string-literals.ys @@ -0,0 +1,257 @@ +# Test valid escape sequences yield correct results: +logger -expect-no-warnings +read_verilog << EOF +module top; + wire[7:0] sp = "\ "; + wire[7:0] spval = 32; + wire[7:0] ex = "\!"; + wire[7:0] exval = 33; + wire[7:0] dq = "\""; + wire[7:0] dqval = 34; + wire[7:0] ha = "\#"; + wire[7:0] haval = 35; + wire[7:0] do = "\$"; + wire[7:0] doval = 36; + wire[7:0] pc = "\%"; + wire[7:0] pcval = 37; + wire[7:0] am = "\&"; + wire[7:0] amval = 38; + wire[7:0] sq = "\'"; + wire[7:0] sqval = 39; + wire[7:0] op = "\("; + wire[7:0] opval = 40; + wire[7:0] cp = "\)"; + wire[7:0] cpval = 41; + wire[7:0] as = "\*"; + wire[7:0] asval = 42; + wire[7:0] pl = "\+"; + wire[7:0] plval = 43; + wire[7:0] co = "\,"; + wire[7:0] coval = 44; + wire[7:0] mi = "\-"; + wire[7:0] mival = 45; + wire[7:0] do = "\."; + wire[7:0] doval = 46; + wire[7:0] sl = "\/"; + wire[7:0] slval = 47; + + wire[7:0] dig0 = "\012"; + wire[7:0] dig0val = 10; + wire[7:0] dig8 = "\8"; // not octal, a literal '8' + wire[7:0] dig8val = 56; + wire[7:0] dig9 = "\9"; // not octal, a literal '9' + wire[7:0] dig9val = 57; + + wire[7:0] cl = "\:"; + wire[7:0] clval = 58; + wire[7:0] sc = "\;"; + wire[7:0] scval = 59; + wire[7:0] lt = "\<"; + wire[7:0] ltval = 60; + wire[7:0] eq = "\="; + wire[7:0] eqval = 61; + wire[7:0] gt = "\>"; + wire[7:0] gtval = 62; + wire[7:0] qu = "\?"; + wire[7:0] quval = 63; + wire[7:0] at = "\@"; + wire[7:0] atval = 64; + + wire[7:0] A = "\A"; + wire[7:0] Aval = 65; // etc. etc. + + wire[7:0] os = "\["; + wire[7:0] osval = 91; + wire[7:0] bs = "\\"; + wire[7:0] bsval = 92; + wire[7:0] cs = "\]"; + wire[7:0] csval = 93; + wire[7:0] ca = "\^"; + wire[7:0] caval = 94; + wire[7:0] us = "\_"; + wire[7:0] usval = 95; + wire[7:0] bq = "\`"; + wire[7:0] bqval = 96; + + wire[7:0] a = "\a"; // alert, ASCII BEL=7 + wire[7:0] aval = 7; + wire[7:0] b = "\b"; + wire[7:0] bval = 98; + wire[7:0] c = "\c"; + wire[7:0] cval = 99; + wire[7:0] d = "\d"; + wire[7:0] dval = 100; + wire[7:0] e = "\e"; + wire[7:0] eval = 101; + wire[7:0] f = "\f"; // form feed, ASCII FF=12 + wire[7:0] fval = 12; + wire[7:0] g = "\g"; + wire[7:0] gval = 103; + wire[7:0] h = "\h"; + wire[7:0] hval = 104; + wire[7:0] i = "\i"; + wire[7:0] ival = 105; + wire[7:0] j = "\j"; + wire[7:0] jval = 106; + wire[7:0] k = "\k"; + wire[7:0] kval = 107; + wire[7:0] l = "\l"; + wire[7:0] lval = 108; + wire[7:0] m = "\m"; + wire[7:0] mval = 109; + wire[7:0] n = "\n"; // new line, ASCII LF=10 + wire[7:0] nval = 10; + wire[7:0] o = "\o"; + wire[7:0] oval = 111; + wire[7:0] p = "\p"; + wire[7:0] pval = 112; + wire[7:0] q = "\q"; + wire[7:0] qval = 113; + wire[7:0] r = "\r"; // carriage return, ASCII CR=13, not IEEE 1800-2023 + wire[7:0] rval = 13; + wire[7:0] s = "\s"; + wire[7:0] sval = 115; + wire[7:0] t = "\t"; // tab, ASCII HT=9 + wire[7:0] tval = 9; + wire[7:0] u = "\u"; + wire[7:0] uval = 117; + wire[7:0] v = "\v"; // vertical tab, ASCII VT=11 + wire[7:0] vval = 11; + wire[7:0] w = "\w"; + wire[7:0] wval = 119; + wire[7:0] x = "\x2A"; // hex escape + wire[7:0] xval = 42; + wire[7:0] y = "\y"; + wire[7:0] yval = 121; + wire[7:0] z = "\z"; + wire[7:0] zval = 122; + + wire[7:0] ob = "\{"; + wire[7:0] obval = 123; + wire[7:0] vb = "\|"; + wire[7:0] vbval = 124; + wire[7:0] cb = "\}"; + wire[7:0] cbval = 125; + wire[7:0] ti = "\~"; + wire[7:0] tival = 126; +endmodule +EOF +sat -prove sp spval -prove ex exval -prove dq dqval -prove ha haval -prove do doval -prove pc pcval -prove am amval -prove sq sqval -prove op opval -prove cp cpval -prove as asval -prove pl plval -prove co coval -prove mi mival -prove do doval -prove sl slval -verify +sat -prove dig0 dig0val -prove dig8 dig8val -prove dig9 dig9val -verify +sat -prove cl clval -prove sc scval -prove lt ltval -prove eq eqval -prove gt gtval -prove qu quval -prove at atval -prove A Aval -verify +sat -prove os osval -prove bs bsval -prove cs csval -prove ca caval -prove us usval -prove bq bqval -verify +sat -prove a aval -prove b bval -prove c cval -prove d dval -prove e eval -prove f fval -prove g gval -prove h hval -prove i ival -prove j jval -prove k kval -prove l lval -prove m mval -prove n nval -prove o oval -prove p pval -prove q qval -prove r rval -prove s sval -prove t tval -prove u uval -prove v vval -prove w wval -prove x xval -prove y yval -prove z zval -verify +sat -prove ob obval -prove vb vbval -prove cb cbval -prove ti tival -verify +logger -check-expected +design -reset + +# Test octal escape out of range. +logger -expect warning "octal escape exceeds \\377" 1 +read_verilog << EOF +module top; + wire[7:0] x = "\400"; +endmodule +EOF +logger -check-expected +design -reset + +# Test invalid octal digit. +logger -expect warning "'\?' not a valid digit in octal escape sequence" 1 +read_verilog << EOF +module top; + wire[7:0] x = "\0?"; +endmodule +EOF +logger -check-expected +design -reset + +# Test invalid hex digit. +logger -expect warning "'X' not a valid digit in hex escape sequence" 1 +read_verilog << EOF +module top; + wire[7:0] x = "\x0X"; +endmodule +EOF +logger -check-expected +design -reset + +# Test hex escape with no hex digits at all. +logger -expect warning "ignoring invalid hex escape" 1 +read_verilog << EOF +module top; + wire[7:0] x = "\xy"; +endmodule +EOF +logger -check-expected +design -reset + +# Test hex escape interrupted by end of string. +logger -expect warning "ignoring invalid hex escape" 1 +read_verilog << EOF +module top; + wire[7:0] x = "\x"; +endmodule +EOF +logger -check-expected +design -reset + +# Test multi-line string. +logger -expect warning "Multi-line string literals should be triple-quoted or escaped" 1 +read_verilog << EOF +module top; + wire[31:0] x = "A +BC"; + wire[31:0] xval = 32'h410A4243; +endmodule +EOF +logger -check-expected +design -reset + +# Test multi-line triple-quoted string. +logger -expect-no-warnings +read_verilog << EOF +module top; + wire[31:0] x = """A +BC"""; + wire[31:0] xval = 32'h410A4243; +endmodule +EOF +logger -check-expected +sat -prove x xval -verify +design -reset + +# Test escaped multi-line string. +logger -expect-no-warnings +read_verilog << EOF +module top; + wire[31:0] x = "AB\ +CD"; + wire[31:0] xval = 32'h41424344; +endmodule +EOF +logger -check-expected +sat -prove x xval -verify +design -reset + +# Test octal escape with surrounding data. +logger -expect-no-warnings +read_verilog << EOF +module top; + wire[31:0] x = "AB\234C"; + wire[31:0] xval = 32'h41429C43; +endmodule +EOF +logger -check-expected +sat -prove x xval -verify +design -reset + +# Test hex escape with surrounding data. +logger -expect-no-warnings +read_verilog << EOF +module top; + wire[31:0] x = "A\xBCDE"; + wire[31:0] xval = 32'h41BC4445; +endmodule +EOF +logger -check-expected +sat -prove x xval -verify From 60f126cd00c94892782470192d6c9f7abebe7c05 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 7 Jul 2025 11:16:07 +0200 Subject: [PATCH 09/20] Release version 0.55 --- CHANGELOG | 6 +++++- Makefile | 4 ++-- docs/source/conf.py | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 537c5682d..b6b7c587b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,8 +2,12 @@ List of major changes and improvements between releases ======================================================= -Yosys 0.54 .. Yosys 0.55-dev +Yosys 0.54 .. Yosys 0.55 -------------------------- + * Various + - read_verilog: Implemented SystemVerilog unique/priority if. + - "attrmap" pass is able to alter memory attributes. + - verific: Support SVA followed-by operator in cover mode. Yosys 0.53 .. Yosys 0.54 -------------------------- diff --git a/Makefile b/Makefile index 26bc60be3..074553918 100644 --- a/Makefile +++ b/Makefile @@ -160,7 +160,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.54+37 +YOSYS_VER := 0.55 YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1) YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1) YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2) @@ -183,7 +183,7 @@ endif OBJS = kernel/version_$(GIT_REV).o bumpversion: - sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline db72ec3.. | wc -l`/;" Makefile +# sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline db72ec3.. | wc -l`/;" Makefile ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABC_USE_NAMESPACE=abc VERBOSE=$(Q) diff --git a/docs/source/conf.py b/docs/source/conf.py index 100605336..05dcb7d5f 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -6,7 +6,7 @@ import os project = 'YosysHQ Yosys' author = 'YosysHQ GmbH' copyright ='2025 YosysHQ GmbH' -yosys_ver = "0.54" +yosys_ver = "0.55" # select HTML theme html_theme = 'furo-ys' From 8af60b7e17d2cf1d092b06ca180868146ca3dd03 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 7 Jul 2025 12:40:53 +0200 Subject: [PATCH 10/20] Next dev cycle --- CHANGELOG | 3 +++ Makefile | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index b6b7c587b..d8f2f8804 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ List of major changes and improvements between releases ======================================================= +Yosys 0.55 .. Yosys 0.56-dev +-------------------------- + Yosys 0.54 .. Yosys 0.55 -------------------------- * Various diff --git a/Makefile b/Makefile index 074553918..b7928f33a 100644 --- a/Makefile +++ b/Makefile @@ -160,7 +160,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.55 +YOSYS_VER := 0.55+0 YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1) YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1) YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2) @@ -183,7 +183,7 @@ endif OBJS = kernel/version_$(GIT_REV).o bumpversion: -# sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline db72ec3.. | wc -l`/;" Makefile + sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 60f126c.. | wc -l`/;" Makefile ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABC_USE_NAMESPACE=abc VERBOSE=$(Q) From 658c7dd424c5c93387415ed51e8d922a11df76c5 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Mon, 7 Jul 2025 16:16:57 +0200 Subject: [PATCH 11/20] rename: fix help --- passes/cmds/rename.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/cmds/rename.cc b/passes/cmds/rename.cc index 02cab3221..e0586ec7e 100644 --- a/passes/cmds/rename.cc +++ b/passes/cmds/rename.cc @@ -276,7 +276,7 @@ struct RenamePass : public Pass { log("\n"); log(" rename -unescape [selection]\n"); log("\n"); - log("Rename all selected public wires and cells that have to be escaped.\n"); + log("Rename all selected public wires and cells that have to be escaped in Verilog.\n"); log("Replaces characters with underscores or adds additional underscores and numbers.\n"); log("\n"); } From e60cf3e2facf8a2d7e27068bc99775183356b8d0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 8 Jul 2025 00:25:06 +0000 Subject: [PATCH 12/20] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b7928f33a..e14be4ad2 100644 --- a/Makefile +++ b/Makefile @@ -160,7 +160,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.55+0 +YOSYS_VER := 0.55+3 YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1) YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1) YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2) From ad80e2bd39917eaae922fbeac2ed9aaab0180f94 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Tue, 8 Jul 2025 13:39:03 +0200 Subject: [PATCH 13/20] libparse: install headers for use in plugins --- Makefile | 1 + passes/techmap/libparse.h | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/Makefile b/Makefile index e14be4ad2..0379adf57 100644 --- a/Makefile +++ b/Makefile @@ -627,6 +627,7 @@ endif $(eval $(call add_include_file,libs/sha1/sha1.h)) $(eval $(call add_include_file,libs/json11/json11.hpp)) $(eval $(call add_include_file,passes/fsm/fsmdata.h)) +$(eval $(call add_include_file,passes/techmap/libparse.h)) $(eval $(call add_include_file,frontends/ast/ast.h)) $(eval $(call add_include_file,frontends/ast/ast_binding.h)) $(eval $(call add_include_file,frontends/blif/blifparse.h)) diff --git a/passes/techmap/libparse.h b/passes/techmap/libparse.h index 949adbdcf..8a2ab22e0 100644 --- a/passes/techmap/libparse.h +++ b/passes/techmap/libparse.h @@ -26,6 +26,11 @@ #include #include +/** + * This file is likely to change in the near future. + * Rely on it in your plugins at your own peril + */ + namespace Yosys { struct LibertyAst From 478b6a2b3fbab0fd4097b841914cbe8bb9f67268 Mon Sep 17 00:00:00 2001 From: George Rennie Date: Mon, 16 Jun 2025 13:40:07 +0100 Subject: [PATCH 14/20] kernel: treat zero width constant as zero --- kernel/rtlil.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 189db0648..8a0080dbf 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -384,7 +384,7 @@ bool RTLIL::Const::convertible_to_int(bool is_signed) const { auto size = get_min_size(is_signed); - if (size <= 0) + if (size < 0) return false; // If it fits in 31 bits it is definitely convertible @@ -5509,6 +5509,9 @@ bool RTLIL::SigSpec::convertible_to_int(bool is_signed) const if (!is_fully_const()) return false; + if (empty()) + return true; + return RTLIL::Const(chunks_[0].data).convertible_to_int(is_signed); } @@ -5520,6 +5523,9 @@ std::optional RTLIL::SigSpec::try_as_int(bool is_signed) const if (!is_fully_const()) return std::nullopt; + if (empty()) + return 0; + return RTLIL::Const(chunks_[0].data).try_as_int(is_signed); } @@ -5529,7 +5535,10 @@ int RTLIL::SigSpec::as_int_saturating(bool is_signed) const pack(); log_assert(is_fully_const() && GetSize(chunks_) <= 1); - log_assert(!empty()); + + if (empty()) + return 0; + return RTLIL::Const(chunks_[0].data).as_int_saturating(is_signed); } From 743df9f0f943c62835ebd21d31bea68a0395edac Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 8 Jul 2025 23:53:38 +0000 Subject: [PATCH 15/20] Fix space leak in `SatGen::importSigSpecWorker()` by avoiding `log_id()`. Calling `log_id()` leaks a copy of the ID into `log_id_cache` until the end of the pass, which causes exorbitant memory usage. See issue #5210. --- kernel/satgen.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kernel/satgen.h b/kernel/satgen.h index 8a89ff9db..2c8cbda13 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -101,7 +101,9 @@ struct SatGen else vec.push_back(bit == (undef_mode ? RTLIL::State::Sx : RTLIL::State::S1) ? ez->CONST_TRUE : ez->CONST_FALSE); } else { - std::string name = pf + (bit.wire->width == 1 ? stringf("%s", log_id(bit.wire)) : stringf("%s [%d]", log_id(bit.wire->name), bit.offset)); + std::string wire_name = RTLIL::unescape_id(bit.wire->name); + std::string name = pf + + (bit.wire->width == 1 ? wire_name : stringf("%s [%d]", wire_name.c_str(), bit.offset)); vec.push_back(ez->frozen_literal(name)); imported_signals[pf][bit] = vec.back(); } From 7566af4a4b588640ed54438aa571fa9e94870846 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 9 Jul 2025 00:25:57 +0000 Subject: [PATCH 16/20] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e14be4ad2..59becefac 100644 --- a/Makefile +++ b/Makefile @@ -160,7 +160,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.55+3 +YOSYS_VER := 0.55+8 YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1) YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1) YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2) From e47f5369fd897dab4c3c8da2143986dd7d040411 Mon Sep 17 00:00:00 2001 From: "N. Engelhardt" Date: Wed, 9 Jul 2025 15:58:35 +0200 Subject: [PATCH 17/20] verificsva: check -L value is small enough for code to work --- frontends/verific/verific.cc | 3 +++ frontends/verific/verificsva.cc | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index d83db3410..241b2db30 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -4124,6 +4124,9 @@ struct VerificPass : public Pass { if (argidx > GetSize(args) && args[argidx].compare(0, 1, "-") == 0) cmd_error(args, argidx, "unknown option"); + if ((unsigned long)verific_sva_fsm_limit >= sizeof(1ull)*8) + log_cmd_error("-L %d: limit too large; maximum allowed value is %zu.\n", verific_sva_fsm_limit, sizeof(1ull)*8-1); + std::set top_mod_names; if (mode_all) diff --git a/frontends/verific/verificsva.cc b/frontends/verific/verificsva.cc index 7652f8130..6e87bd267 100644 --- a/frontends/verific/verificsva.cc +++ b/frontends/verific/verificsva.cc @@ -479,14 +479,14 @@ struct SvaFsm GetSize(dnode.ctrl), verific_sva_fsm_limit); } - for (int i = 0; i < (1 << GetSize(dnode.ctrl)); i++) + for (unsigned long long i = 0; i < (1ull << GetSize(dnode.ctrl)); i++) { Const ctrl_val(i, GetSize(dnode.ctrl)); pool ctrl_bits; - for (int i = 0; i < GetSize(dnode.ctrl); i++) - if (ctrl_val[i] == State::S1) - ctrl_bits.insert(dnode.ctrl[i]); + for (int j = 0; j < GetSize(dnode.ctrl); j++) + if (ctrl_val[j] == State::S1) + ctrl_bits.insert(dnode.ctrl[j]); vector new_state; bool accept = false, cond = false; From f34c4f2e26f0e18df7eb3393ec755b5e6c288b00 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Wed, 9 Jul 2025 16:20:27 +0200 Subject: [PATCH 18/20] log: deduplicate unescape_id from log_id --- kernel/log.cc | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/kernel/log.cc b/kernel/log.cc index fabbe09fd..679a55562 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -664,15 +664,9 @@ const char *log_const(const RTLIL::Const &value, bool autoint) const char *log_id(const RTLIL::IdString &str) { - log_id_cache.push_back(strdup(str.c_str())); - const char *p = log_id_cache.back(); - if (p[0] != '\\') - return p; - if (p[1] == '$' || p[1] == '\\' || p[1] == 0) - return p; - if (p[1] >= '0' && p[1] <= '9') - return p; - return p+1; + std::string unescaped = RTLIL::unescape_id(str); + log_id_cache.push_back(strdup(unescaped.c_str())); + return log_id_cache.back(); } const char *log_str(const char *str) From 7fe817c52f51591eaeb780e3022fe8f2a4114abc Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Thu, 10 Jul 2025 18:54:43 +0200 Subject: [PATCH 19/20] dfflibmap: test negated state next_state with mixed polarities --- tests/techmap/dfflibmap.ys | 16 ++++++++++ tests/techmap/dfflibmap_dffsr_mixedpol.lib | 35 ++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 tests/techmap/dfflibmap_dffsr_mixedpol.lib diff --git a/tests/techmap/dfflibmap.ys b/tests/techmap/dfflibmap.ys index 77488d60f..822d87a36 100644 --- a/tests/techmap/dfflibmap.ys +++ b/tests/techmap/dfflibmap.ys @@ -81,3 +81,19 @@ clean select -assert-count 0 t:dffn select -assert-count 5 t:dffsr select -assert-count 1 t:dffe + +design -load orig +dfflibmap -liberty dfflibmap.lib -liberty dfflibmap_dffsr_mixedpol.lib -dont_use dffsr +clean +# We have one more _NOT_ than with the regular dffsr +select -assert-count 6 t:$_NOT_ +select -assert-count 1 t:dffn +select -assert-count 4 t:dffsr_mixedpol +select -assert-count 1 t:dffe +# The additional NOT is on ff2. +# Originally, ff2.R is an active high "set". +# dffsr_mixedpol has functionally swapped labels due to the next_state inversion, +# so we use its CLEAR port for the "set", +# but we have to invert it because the CLEAR pin is active low. +# ff2.CLEAR = !R +select -assert-count 1 c:ff2 %x:+[CLEAR] %ci t:$_NOT_ %i diff --git a/tests/techmap/dfflibmap_dffsr_mixedpol.lib b/tests/techmap/dfflibmap_dffsr_mixedpol.lib new file mode 100644 index 000000000..8c6a2f509 --- /dev/null +++ b/tests/techmap/dfflibmap_dffsr_mixedpol.lib @@ -0,0 +1,35 @@ +library(test) { + cell (dffsr_mixedpol) { + area : 6; + ff("IQ", "IQN") { + // look here + next_state : "!D"; + clocked_on : "CLK"; + // look here + clear : "!CLEAR"; + preset : "PRESET"; + clear_preset_var1 : L; + clear_preset_var2 : L; + } + pin(D) { + direction : input; + } + pin(CLK) { + direction : input; + } + pin(CLEAR) { + direction : input; + } + pin(PRESET) { + direction : input; + } + pin(Q) { + direction: output; + function : "IQ"; + } + pin(QN) { + direction: output; + function : "IQN"; + } + } +} From e57a2b944239eb5214c66e0fa897cae397c907dc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 11 Jul 2025 00:25:36 +0000 Subject: [PATCH 20/20] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 3fbd8762a..d9f3b937c 100644 --- a/Makefile +++ b/Makefile @@ -160,7 +160,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.55+8 +YOSYS_VER := 0.55+23 YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1) YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1) YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2)