From 5c1dd0c5b24716ecfcad80cd17410c2203b14788 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 24 Sep 2025 12:07:30 +1200 Subject: [PATCH 01/16] Testing quoted strings --- tests/scripts/.gitignore | 1 + tests/scripts/file name.v | 2 ++ tests/scripts/file name.ys | 1 + tests/scripts/plugin.cc | 57 ++++++++++++++++++++++++++++++++++ tests/scripts/run-test.sh | 4 +++ tests/scripts/space_in_name.sh | 47 ++++++++++++++++++++++++++++ tests/scripts/space_in_name.ys | 14 +++++++++ 7 files changed, 126 insertions(+) create mode 100644 tests/scripts/.gitignore create mode 100644 tests/scripts/file name.v create mode 100644 tests/scripts/file name.ys create mode 100644 tests/scripts/plugin.cc create mode 100755 tests/scripts/run-test.sh create mode 100755 tests/scripts/space_in_name.sh create mode 100755 tests/scripts/space_in_name.ys diff --git a/tests/scripts/.gitignore b/tests/scripts/.gitignore new file mode 100644 index 000000000..8a84f1935 --- /dev/null +++ b/tests/scripts/.gitignore @@ -0,0 +1 @@ +/plugin.so diff --git a/tests/scripts/file name.v b/tests/scripts/file name.v new file mode 100644 index 000000000..dc95c3d21 --- /dev/null +++ b/tests/scripts/file name.v @@ -0,0 +1,2 @@ +module top(); +endmodule diff --git a/tests/scripts/file name.ys b/tests/scripts/file name.ys new file mode 100644 index 000000000..41ab1c375 --- /dev/null +++ b/tests/scripts/file name.ys @@ -0,0 +1 @@ +log Hello! diff --git a/tests/scripts/plugin.cc b/tests/scripts/plugin.cc new file mode 100644 index 000000000..b06fee189 --- /dev/null +++ b/tests/scripts/plugin.cc @@ -0,0 +1,57 @@ +#include "kernel/yosys.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct TestArgsPass : public Pass { + TestArgsPass() : Pass("test_args", "dummy pass to test arg parsing") { + internal(); + } + void execute(std::vector args, RTLIL::Design*) override { + int argidx; + for (argidx = 0; argidx < GetSize(args); argidx++) + { + log("%s\n", args[argidx]); + } + } +} TestArgsPass; + +struct TestArgsFrontend : public Frontend { + TestArgsFrontend() : Frontend("test_args", "dummy frontend to test arg parsing") { + internal(); + } + void execute(std::istream *&f, std::string filename, std::vector args, RTLIL::Design *) override { + int argidx; + log("pass: %s\n", args[0]); + for (argidx = 1; argidx < GetSize(args); argidx++) { + if (args[argidx] == "-arg" && argidx+1 < GetSize(args)) { + log("arg: %s\n", args[++argidx]); + continue; + } + break; + } + extra_args(f, filename, args, argidx); + log("filename: %s\n", filename); + } +} TestArgsFrontend; + +struct TestArgsBackend : public Backend { + TestArgsBackend() : Backend("test_args", "dummy backend to test arg parsing") { + internal(); + } + void execute(std::ostream *&f, std::string filename, std::vector args, RTLIL::Design *) override { + int argidx; + log("pass: %s\n", args[0]); + for (argidx = 1; argidx < GetSize(args); argidx++) { + if (args[argidx] == "-arg" && argidx+1 < GetSize(args)) { + log("arg: %s\n", args[++argidx]); + continue; + } + break; + } + extra_args(f, filename, args, argidx); + log("filename: %s\n", filename); + } +} TestArgsBackend; + +PRIVATE_NAMESPACE_END diff --git a/tests/scripts/run-test.sh b/tests/scripts/run-test.sh new file mode 100755 index 000000000..70b282a9a --- /dev/null +++ b/tests/scripts/run-test.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -eu +source ../gen-tests-makefile.sh +generate_mk --bash diff --git a/tests/scripts/space_in_name.sh b/tests/scripts/space_in_name.sh new file mode 100755 index 000000000..01954d0ae --- /dev/null +++ b/tests/scripts/space_in_name.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +set -eu + +yosys="$PWD/../../yosys" + +# these ones are fine because bash handles it +$yosys "file name.ys" +$yosys file\ name.ys + +$yosys "file name.v" -o "file name.out" -b verilog +$yosys file\ name.v -o file\ name.out -b verilog + +# these already have special handling in Yosys thanks to `extra_args` +$yosys -p 'read_verilog "file name.v"' +$yosys -p 'write_verilog "file name.out"' + +# this one isn't a normal frontend so doesn't +# $yosys -p 'script "file name.ys"' + +# these get split by space and treated as two separate filenames +# $yosys -p script\ "file name.ys" +# $yosys -p script\ file\ name.ys +# $yosys -p read_verilog\ "file name.v" +# $yosys -p read_verilog\ file\ name.v +# $yosys -p write_verilog\ file\ name.out +# $yosys -p write_verilog\ "file name.out" + +# what does test_args say +rm -f plugin.so +CXXFLAGS=$(../../yosys-config --cxxflags) +DATDIR=$(../../yosys-config --datdir) +DATDIR=${DATDIR//\//\\\/} +CXXFLAGS=${CXXFLAGS//$DATDIR/..\/..\/share} +../../yosys-config --exec --cxx ${CXXFLAGS} --ldflags -shared -o plugin.so plugin.cc +yosys_plugin="$yosys -m ./plugin.so" + +$yosys_plugin -p test_args\ "quoted spaces" +$yosys_plugin -p test_args\ escaped\ spaces +$yosys_plugin -p test_args\ \"escaped\ quotes\" +$yosys_plugin -p 'test_args "inner quotes"' +$yosys_plugin -p 'test_args "inner \"escaped quotes\""' + +$yosys_plugin -p 'read_test_args "file name.v" "file name.ys"' +$yosys_plugin -p 'write_test_args "file name.out"' + +# and as a script +$yosys_plugin space_in_name.ys diff --git a/tests/scripts/space_in_name.ys b/tests/scripts/space_in_name.ys new file mode 100755 index 000000000..cc4f0e4e2 --- /dev/null +++ b/tests/scripts/space_in_name.ys @@ -0,0 +1,14 @@ +echo on + +# pass +test_args "quoted spaces" +test_args escaped\ spaces +test_args \"escaped quotes\" +test_args "inner \"escaped quotes\"" +test_args -opt "some value here" -b "some other \"escaped value\"" + +# frontend/backend +read_test_args -arg "inner \"escaped quotes\"" "file name.v" "file name.ys" +write_test_args -arg "inner \"escaped quotes\"" "file name.out" +read_test_args -arg no_quotes plugin.cc +write_test_args -arg no_quotes From 0a88c159c17d8d55ce6577497935aec4e8e44a1b Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 24 Sep 2025 14:03:49 +1200 Subject: [PATCH 02/16] tests/scripts: Also check hashes in quotes i.e. they should be part of the quote instead of starting a comment --- tests/scripts/space_in_name.ys | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/scripts/space_in_name.ys b/tests/scripts/space_in_name.ys index cc4f0e4e2..f6bbb8d46 100755 --- a/tests/scripts/space_in_name.ys +++ b/tests/scripts/space_in_name.ys @@ -12,3 +12,8 @@ read_test_args -arg "inner \"escaped quotes\"" "file name.v" "file name.ys" write_test_args -arg "inner \"escaped quotes\"" "file name.out" read_test_args -arg no_quotes plugin.cc write_test_args -arg no_quotes + +# hash in string? +test_args "this is \\ #not a comment" +test_args this is #a comment +test_args "#no comment" From 0ab1d6d28c0b59237ee99a5df3d871e474fa9991 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 24 Sep 2025 14:20:12 +1200 Subject: [PATCH 03/16] Handle quoted arguments in passes Use `std::quoted()` from `` to quote/unquote pass arguments. In order to maintain handling of (unquoted) comments and semicolons this occurs when adding the token to the arg list, rather than in the tokenization itself. Passes no longer receive tokenized-but-raw arguments and are instead pre-unquoted. This will cause problems for some passes (e.g. `setparam`) which rely on arguments having quotation marks for disambiguation. In order to maintain reproducibility with `echo on`, arguments which require quoting will automatically quote (arguments which were quoted but didn't need to be will not be quoted in the echo). --- kernel/io.cc | 18 ++++++++++++++++++ kernel/io.h | 4 ++++ kernel/register.cc | 10 ++++++---- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/kernel/io.cc b/kernel/io.cc index 4c593501c..483d303a9 100644 --- a/kernel/io.cc +++ b/kernel/io.cc @@ -2,6 +2,7 @@ #include "kernel/log.h" #include #include +#include #if !defined(WIN32) #include @@ -592,4 +593,21 @@ void format_emit_void_ptr(std::string &result, std::string_view spec, int *dynam format_emit_stringf(result, spec, dynamic_ints, num_dynamic_ints, arg); } +bool needs_quote(const std::string &s) { + return (s.find(' ') != std::string::npos) || (s.find('\\') != std::string::npos); +} + +std::string quote(const std::string &s) { + std::ostringstream ss; + ss << std::quoted(s); + return ss.str(); +} + +std::string unquote(const std::string &s) { + std::string result; + std::istringstream ss(s); + ss >> std::quoted(result); + return result; +} + YOSYS_NAMESPACE_END diff --git a/kernel/io.h b/kernel/io.h index 2ad0a6466..64caae078 100644 --- a/kernel/io.h +++ b/kernel/io.h @@ -470,6 +470,10 @@ void remove_directory(std::string dirname); bool create_directory(const std::string& dirname); std::string escape_filename_spaces(const std::string& filename); +bool needs_quote(const std::string &s); +std::string quote(const std::string &s); +std::string unquote(const std::string &s); + YOSYS_NAMESPACE_END #endif // YOSYS_IO_H diff --git a/kernel/register.cc b/kernel/register.cc index bd12dcc38..a255c4805 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -222,7 +222,7 @@ void Pass::call(RTLIL::Design *design, std::string command) while (!tok.empty() && tok.back() == ';') tok.resize(tok.size()-1), num_semikolon++; if (!tok.empty()) - args.push_back(tok); + args.push_back(unquote(tok)); call(design, args); args.clear(); if (num_semikolon == 2) @@ -230,7 +230,7 @@ void Pass::call(RTLIL::Design *design, std::string command) if (num_semikolon == 3) call(design, "clean -purge"); } else - args.push_back(tok); + args.push_back(unquote(tok)); bool found_nl = false; for (auto c : cmd_buf) { if (c == ' ' || c == '\t') @@ -256,8 +256,10 @@ void Pass::call(RTLIL::Design *design, std::vector args) if (echo_mode) { log("%s", create_prompt(design, 0)); - for (size_t i = 0; i < args.size(); i++) - log("%s%s", i ? " " : "", args[i]); + for (size_t i = 0; i < args.size(); i++) { + auto maybe_quoted = needs_quote(args[i]) ? quote(args[i]) : args[i]; + log("%s%s", i ? " " : "", maybe_quoted); + } log("\n"); } From 6328c808db77fd7255f45985b5660462a73fa6b4 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 24 Sep 2025 15:20:46 +1200 Subject: [PATCH 04/16] io.cc: Quoting fixes Add other special characters to `needs_quote()` check. Fix `"\" ` being treated as a complete quoted string because of the space after the `"` even though it's escaped. --- kernel/io.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/kernel/io.cc b/kernel/io.cc index 483d303a9..d6fe2863c 100644 --- a/kernel/io.cc +++ b/kernel/io.cc @@ -41,7 +41,7 @@ std::string next_token(std::string &text, const char *sep, bool long_strings) if (long_strings && pos_begin != text.size() && text[pos_begin] == '"') { std::string sep_string = sep; for (size_t i = pos_begin+1; i < text.size(); i++) { - if (text[i] == '"' && (i+1 == text.size() || sep_string.find(text[i+1]) != std::string::npos)) { + if (text[i-1] != '\\' && text[i] == '"' && (i+1 == text.size() || sep_string.find(text[i+1]) != std::string::npos)) { std::string token = text.substr(pos_begin, i-pos_begin+1); text = text.substr(i+1); return token; @@ -594,7 +594,10 @@ void format_emit_void_ptr(std::string &result, std::string_view spec, int *dynam } bool needs_quote(const std::string &s) { - return (s.find(' ') != std::string::npos) || (s.find('\\') != std::string::npos); + for (auto c : {' ', '\\', '#', ';', '"'}) { + if (s.find(c) != std::string::npos) return true; + } + return false; } std::string quote(const std::string &s) { From d6f3ac60f1ef985a6b516f31656da4ec8564aa46 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 24 Sep 2025 17:24:40 +1200 Subject: [PATCH 05/16] io.cc: Support single quoted arguments Single quoted strings have no escape character and are treated verbatim. This is useful for minimizing the number of backslashes in (for example) `logger -expect` regexps (e.g. `"\\\""` -> `'\"'`). `Yosys::quote()` will use single quotes by default, unless the string contains a single quote and then it will use `std::quoted()`. Fix strange behaviour arrising from always using `std::quoted(result)`. Because of the way the function interacts with streams, if there is only one quotation mark then the result would end at the first whitespace. --- kernel/io.cc | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/kernel/io.cc b/kernel/io.cc index d6fe2863c..6cdf18448 100644 --- a/kernel/io.cc +++ b/kernel/io.cc @@ -38,15 +38,16 @@ std::string next_token(std::string &text, const char *sep, bool long_strings) if (pos_begin == std::string::npos) pos_begin = text.size(); - if (long_strings && pos_begin != text.size() && text[pos_begin] == '"') { + if (long_strings && pos_begin != text.size() && (text[pos_begin] == '"' || text[pos_begin] == '\'')) { std::string sep_string = sep; for (size_t i = pos_begin+1; i < text.size(); i++) { - if (text[i-1] != '\\' && text[i] == '"' && (i+1 == text.size() || sep_string.find(text[i+1]) != std::string::npos)) { + bool close_quote = (text[i] == text[pos_begin]) && (text[i-1] != '\\' || text[pos_begin] == '\''); + if (close_quote && (i+1 == text.size() || sep_string.find(text[i+1]) != std::string::npos)) { std::string token = text.substr(pos_begin, i-pos_begin+1); text = text.substr(i+1); return token; } - if (i+1 < text.size() && text[i] == '"' && text[i+1] == ';' && (i+2 == text.size() || sep_string.find(text[i+2]) != std::string::npos)) { + if (i+1 < text.size() && close_quote && text[i+1] == ';' && (i+2 == text.size() || sep_string.find(text[i+2]) != std::string::npos)) { std::string token = text.substr(pos_begin, i-pos_begin+1); text = text.substr(i+2); return token + ";"; @@ -594,7 +595,7 @@ void format_emit_void_ptr(std::string &result, std::string_view spec, int *dynam } bool needs_quote(const std::string &s) { - for (auto c : {' ', '\\', '#', ';', '"'}) { + for (auto c : {' ', '\\', '#', ';', '"', '\''}) { if (s.find(c) != std::string::npos) return true; } return false; @@ -602,15 +603,25 @@ bool needs_quote(const std::string &s) { std::string quote(const std::string &s) { std::ostringstream ss; - ss << std::quoted(s); + if (s.find('\'') != std::string::npos) + ss << std::quoted(s); + else + ss << '\'' << s << '\''; return ss.str(); } std::string unquote(const std::string &s) { - std::string result; - std::istringstream ss(s); - ss >> std::quoted(result); - return result; + if (s.length() >= 2) { + if (s.front() == '\'' && s.back() == '\'') + return s.substr(1, s.length()-2); + else if (s.front() == '"' && s.back() == '"') { + std::string result; + std::istringstream ss(s); + ss >> std::quoted(result); + return result; + } + } + return s; } YOSYS_NAMESPACE_END From 51dc09ca4aca23287ff252caf69ded7e538a9a58 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 24 Sep 2025 17:25:53 +1200 Subject: [PATCH 06/16] logger.cc: Don't unquote args --- passes/cmds/logger.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/passes/cmds/logger.cc b/passes/cmds/logger.cc index cab4ab81c..1e3f5e821 100644 --- a/passes/cmds/logger.cc +++ b/passes/cmds/logger.cc @@ -106,7 +106,6 @@ struct LoggerPass : public Pass { } if (args[argidx] == "-warn" && argidx+1 < args.size()) { std::string pattern = args[++argidx]; - if (pattern.front() == '\"' && pattern.back() == '\"') pattern = pattern.substr(1, pattern.size() - 2); try { log("Added regex '%s' for warnings to warn list.\n", pattern); log_warn_regexes.push_back(YS_REGEX_COMPILE(pattern)); @@ -118,7 +117,6 @@ struct LoggerPass : public Pass { } if (args[argidx] == "-nowarn" && argidx+1 < args.size()) { std::string pattern = args[++argidx]; - if (pattern.front() == '\"' && pattern.back() == '\"') pattern = pattern.substr(1, pattern.size() - 2); try { log("Added regex '%s' for warnings to nowarn list.\n", pattern); log_nowarn_regexes.push_back(YS_REGEX_COMPILE(pattern)); @@ -130,7 +128,6 @@ struct LoggerPass : public Pass { } if (args[argidx] == "-werror" && argidx+1 < args.size()) { std::string pattern = args[++argidx]; - if (pattern.front() == '\"' && pattern.back() == '\"') pattern = pattern.substr(1, pattern.size() - 2); try { log("Added regex '%s' for warnings to werror list.\n", pattern); log_werror_regexes.push_back(YS_REGEX_COMPILE(pattern)); @@ -164,7 +161,6 @@ struct LoggerPass : public Pass { if ((type=="error" || type=="prefix-error") && log_expect_error.size()>0) log_cmd_error("Only single error message can be expected !\n"); std::string pattern = args[++argidx]; - if (pattern.front() == '\"' && pattern.back() == '\"') pattern = pattern.substr(1, pattern.size() - 2); int count = atoi(args[++argidx].c_str()); if (count<=0) log_cmd_error("Number of expected messages must be higher then 0 !\n"); From ab6bdb50a995ed356e0180fff18ea842dccbc6c6 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 24 Sep 2025 17:26:55 +1200 Subject: [PATCH 07/16] tests/scripts: Use logger -check-expected --- tests/scripts/space_in_name.sh | 4 +- tests/scripts/space_in_name.ys | 105 +++++++++++++++++++++++++++++---- 2 files changed, 97 insertions(+), 12 deletions(-) diff --git a/tests/scripts/space_in_name.sh b/tests/scripts/space_in_name.sh index 01954d0ae..ba3b97773 100755 --- a/tests/scripts/space_in_name.sh +++ b/tests/scripts/space_in_name.sh @@ -14,8 +14,8 @@ $yosys file\ name.v -o file\ name.out -b verilog $yosys -p 'read_verilog "file name.v"' $yosys -p 'write_verilog "file name.out"' -# this one isn't a normal frontend so doesn't -# $yosys -p 'script "file name.ys"' +# this one works if passes get their arguments unquoted +$yosys -p 'script "file name.ys"' # these get split by space and treated as two separate filenames # $yosys -p script\ "file name.ys" diff --git a/tests/scripts/space_in_name.ys b/tests/scripts/space_in_name.ys index f6bbb8d46..7172478f1 100755 --- a/tests/scripts/space_in_name.ys +++ b/tests/scripts/space_in_name.ys @@ -1,19 +1,104 @@ -echo on +logger -expect-no-warnings -# pass -test_args "quoted spaces" -test_args escaped\ spaces +# quoted strings are a single argument to passes +logger -expect log "quoted space" 1 +logger -expect log "quoted" 2 +logger -expect log "space" 2 +logger -expect log '\\"escaped' 1 +logger -expect log 'quotes\\"' 1 + +test_args unquoted space +test_args "quoted space" test_args \"escaped quotes\" -test_args "inner \"escaped quotes\"" + +logger -check-expected + +# empty strings can be arguments +logger -expect log "a b c" 2 + +log a " " b "" c +log a ' ' b '' c + +logger -check-expected + +# quotes can be arguments +logger -expect log '^"' 2 +logger -expect log "^'" 1 +test_args "'" '"' "\"" +logger -check-expected + +# whitespace (or a lack thereof) shouldn't break things +logger -expect log 'a. .b' 2 +log a" "b +log a' 'b + +logger -expect log '.a.b c' 2 +log "a"b c +log 'a'b c + +logger -check-expected + +# numeric literals don't need quotes (unless they include a space) +logger -expect log "1'd2" 1 +logger -expect log "3'b 011" 1 + +test_args 1'd2 +test_args "3'b 011" + +logger -check-expected + +# sidenote that apparently logger regexp ends with '\n$', but \n in the pattern is rejected +logger -expect log "^('|\").$" 2 +log " +log ' + +logger -check-expected + +# bonus test test_args -opt "some value here" -b "some other \"escaped value\"" -# frontend/backend +# special characters can appear in strings +logger -expect log "#no comment" 2 +logger -expect log ";" 1 +logger -warn "a comment" + +log "this is #no comment" +log this is #a comment +log "semicolon; "; log "#no comment" + +logger -check-expected + +# special characters are quoted in echo +logger -expect log "'#'" 1 +logger -expect log "';'" 1 +logger -expect log "' '" 1 +logger -expect log "\"'\"" 1 +logger -expect log "'\"'" 1 +logger -expect log '.\\.' 1 + +echo on +log '#' +log ';' +log ' ' +log "'" +log '"' +log '\' +echo off + +logger -check-expected + +# should this be a backslash or an escaped space? +log escaped\ space? + +# frontend/backend args also work as expected +logger -expect log "arg: inner \"escaped quotes\"" 3 +logger -expect log 'filename: file name\..{1,3}' 3 +logger -expect log "filename: " 1 +logger -expect log "arg: no_quotes" 2 + read_test_args -arg "inner \"escaped quotes\"" "file name.v" "file name.ys" write_test_args -arg "inner \"escaped quotes\"" "file name.out" read_test_args -arg no_quotes plugin.cc write_test_args -arg no_quotes -# hash in string? -test_args "this is \\ #not a comment" -test_args this is #a comment -test_args "#no comment" +logger -check-expected From 137a801b4a2eef3cbb3ea99391668fcb34a095d4 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 24 Sep 2025 17:39:57 +1200 Subject: [PATCH 08/16] Don't unquote args in bugpoint or setenv --- passes/cmds/bugpoint.cc | 3 --- passes/cmds/setenv.cc | 1 - 2 files changed, 4 deletions(-) diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index 897dd8459..21058f50d 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -149,9 +149,6 @@ struct BugpointPass : public Pass { if (grep.empty()) return true; - if (grep.size() > 2 && grep.front() == '"' && grep.back() == '"') - grep = grep.substr(1, grep.size() - 2); - string bugpoint_file = "bugpoint-case"; if (suffix.size()) bugpoint_file += stringf(".%.8s", suffix); diff --git a/passes/cmds/setenv.cc b/passes/cmds/setenv.cc index 90eeab702..39a6c73ca 100644 --- a/passes/cmds/setenv.cc +++ b/passes/cmds/setenv.cc @@ -46,7 +46,6 @@ struct SetenvPass : public Pass { std::string name = args[1]; std::string value = args[2]; - if (value.front() == '\"' && value.back() == '\"') value = value.substr(1, value.size() - 2); #if defined(_WIN32) _putenv_s(name.c_str(), value.c_str()); From 8ff55f184bd5a49d2635a65d68695597f9d180e9 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 6 Oct 2025 11:27:21 +1300 Subject: [PATCH 09/16] bugpoint.cc: Quoting fixes Don't strip runner/suffix quotes. Quote script/command argument. --- passes/cmds/bugpoint.cc | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index 21058f50d..9df254513 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -468,13 +468,13 @@ struct BugpointPass : public Pass { if (args[argidx] == "-script" && argidx + 1 < args.size()) { if (!yosys_arg.empty()) log_cmd_error("A -script or -command option can be only provided once!\n"); - yosys_arg = stringf("-s %s", args[++argidx]); + yosys_arg = stringf("-s %s", quote(args[++argidx])); continue; } if (args[argidx] == "-command" && argidx + 1 < args.size()) { if (!yosys_arg.empty()) log_cmd_error("A -script or -command option can be only provided once!\n"); - yosys_arg = stringf("-p %s", args[++argidx]); + yosys_arg = stringf("-p %s", quote(args[++argidx])); continue; } if (args[argidx] == "-grep" && argidx + 1 < args.size()) { @@ -547,18 +547,10 @@ struct BugpointPass : public Pass { } if (args[argidx] == "-runner" && argidx + 1 < args.size()) { runner = args[++argidx]; - if (runner.size() && runner.at(0) == '"') { - log_assert(runner.back() == '"'); - runner = runner.substr(1, runner.size() - 2); - } continue; } if (args[argidx] == "-suffix" && argidx + 1 < args.size()) { suffix = args[++argidx]; - if (suffix.size() && suffix.at(0) == '"') { - log_assert(suffix.back() == '"'); - suffix = suffix.substr(1, suffix.size() - 2); - } continue; } break; From a685bab9e2f4781795f6a893a6a427aeec435962 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 6 Oct 2025 11:28:05 +1300 Subject: [PATCH 10/16] scratchpad.cc: Don't strip quotes --- passes/cmds/scratchpad.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/passes/cmds/scratchpad.cc b/passes/cmds/scratchpad.cc index f64ce943c..671e1382b 100644 --- a/passes/cmds/scratchpad.cc +++ b/passes/cmds/scratchpad.cc @@ -89,7 +89,6 @@ struct ScratchpadPass : public Pass { if (RTLIL::constpad.count(identifier)) log_error("scratchpad entry \"%s\" is a global constant\n", identifier); string value = args[++argidx]; - if (value.front() == '\"' && value.back() == '\"') value = value.substr(1, value.size() - 2); design->scratchpad_set_string(identifier, value); continue; } @@ -116,7 +115,6 @@ struct ScratchpadPass : public Pass { if (args[argidx] == "-assert" && argidx+2 < args.size()) { string identifier = args[++argidx]; string expected = args[++argidx]; - if (expected.front() == '\"' && expected.back() == '\"') expected = expected.substr(1, expected.size() - 2); if (design->scratchpad.count(identifier) == 0) log_error("scratchpad entry '%s' is not defined\n", identifier); string value = design->scratchpad_get_string(identifier); From 40cd1729d5de19ed28e9d4006a55034cce1976c8 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 6 Oct 2025 11:30:26 +1300 Subject: [PATCH 11/16] setattr.cc: Explicit -setstr option Don't rely on strings being quoted, instead we introduce `-setstr`. Change the help text formatting for `setattr` and `setparam` to avoid the line being too long. Instead use a generic `[options]` and list the options separately. --- passes/cmds/setattr.cc | 61 +++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 21 deletions(-) diff --git a/passes/cmds/setattr.cc b/passes/cmds/setattr.cc index 25d8fd34c..85105bed8 100644 --- a/passes/cmds/setattr.cc +++ b/passes/cmds/setattr.cc @@ -32,10 +32,10 @@ struct setunset_t setunset_t(std::string unset_name) : name(RTLIL::escape_id(unset_name)), value(), unset(true) { } - setunset_t(std::string set_name, std::string set_value) : name(RTLIL::escape_id(set_name)), value(), unset(false) + setunset_t(std::string set_name, std::string set_value, bool is_str) : name(RTLIL::escape_id(set_name)), value(), unset(false) { - if (set_value.compare(0, 1, "\"") == 0 && set_value.compare(GetSize(set_value)-1, std::string::npos, "\"") == 0) { - value = RTLIL::Const(set_value.substr(1, GetSize(set_value)-2)); + if (is_str) { + value = RTLIL::Const(set_value); } else { RTLIL::SigSpec sig_value; if (!RTLIL::SigSpec::parse(sig_value, nullptr, set_value)) @@ -60,13 +60,22 @@ struct SetattrPass : public Pass { { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" setattr [ -mod ] [ -set name value | -unset name ]... [selection]\n"); + log(" setattr [options] [selection]\n"); log("\n"); - log("Set/unset the given attributes on the selected objects. String values must be\n"); - log("passed in double quotes (\").\n"); + log("Set/unset attributes on the selected objects.\n"); log("\n"); - log("When called with -mod, this command will set and unset attributes on modules\n"); - log("instead of objects within modules.\n"); + log(" -mod\n"); + log(" apply changes to modules instead of objects within modules\n"); + log("\n"); + log(" -set \n"); + log(" -setstr \n"); + log(" set the named attribute to the given value, string values must use\n"); + log(" the -setstr option\n"); + log("\n"); + log(" -unset \n"); + log(" unset the named attribute\n"); + log("\n"); + log("The options -setstr, -set, and -unset can be specified multiple times.\n"); log("\n"); } void execute(std::vector args, RTLIL::Design *design) override @@ -78,10 +87,10 @@ struct SetattrPass : public Pass { for (argidx = 1; argidx < args.size(); argidx++) { std::string arg = args[argidx]; - if (arg == "-set" && argidx+2 < args.size()) { + if ((arg == "-set" || arg == "-setstr") && argidx+2 < args.size()) { string set_key = args[++argidx]; string set_val = args[++argidx]; - setunset_list.push_back(setunset_t(set_key, set_val)); + setunset_list.push_back(setunset_t(set_key, set_val, arg == "-setstr")); continue; } if (arg == "-unset" && argidx+1 < args.size()) { @@ -147,12 +156,22 @@ struct SetparamPass : public Pass { { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" setparam [ -type cell_type ] [ -set name value | -unset name ]... [selection]\n"); + log(" setparam [options] [selection]\n"); log("\n"); - log("Set/unset the given parameters on the selected cells. String values must be\n"); - log("passed in double quotes (\").\n"); + log("Set/unset parameters on the selected cells.\n"); log("\n"); - log("The -type option can be used to change the cell type of the selected cells.\n"); + log(" -type\n"); + log(" change the cell type of the selected cells\n"); + log("\n"); + log(" -set \n"); + log(" -setstr \n"); + log(" set the named parameter to the given value, string values must use\n"); + log(" the -setstr option\n"); + log("\n"); + log(" -unset \n"); + log(" unset the named parameter\n"); + log("\n"); + log("The options -setstr, -set, and -unset can be specified multiple times.\n"); log("\n"); } void execute(std::vector args, RTLIL::Design *design) override @@ -164,10 +183,10 @@ struct SetparamPass : public Pass { for (argidx = 1; argidx < args.size(); argidx++) { std::string arg = args[argidx]; - if (arg == "-set" && argidx+2 < args.size()) { + if ((arg == "-set" || arg == "-setstr") && argidx+2 < args.size()) { string set_key = args[++argidx]; string set_val = args[++argidx]; - setunset_list.push_back(setunset_t(set_key, set_val)); + setunset_list.push_back(setunset_t(set_key, set_val, arg == "-setstr")); continue; } if (arg == "-unset" && argidx+1 < args.size()) { @@ -199,10 +218,10 @@ struct ChparamPass : public Pass { { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" chparam [ -set name value ]... [selection]\n"); + log(" chparam [ -set[str] name value ]... [selection]\n"); log("\n"); - log("Re-evaluate the selected modules with new parameters. String values must be\n"); - log("passed in double quotes (\").\n"); + log("Re-evaluate the selected modules with new parameters. String values must use\n"); + log("the -setstr option.\n"); log("\n"); log("\n"); log(" chparam -list [selection]\n"); @@ -220,10 +239,10 @@ struct ChparamPass : public Pass { for (argidx = 1; argidx < args.size(); argidx++) { std::string arg = args[argidx]; - if (arg == "-set" && argidx+2 < args.size()) { + if ((arg == "-set" || arg == "-setstr") && argidx+2 < args.size()) { string set_key = args[++argidx]; string set_val = args[++argidx]; - setunset_list.push_back(setunset_t(set_key, set_val)); + setunset_list.push_back(setunset_t(set_key, set_val, arg == "-setstr")); continue; } if (arg == "-list") { From 4006dafefc7f4cfdbc2664268f99cd6425fc8dbe Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 6 Oct 2025 11:38:00 +1300 Subject: [PATCH 12/16] Makefile: Add tests/scripts --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 02f8fa0e9..e0634c2f8 100644 --- a/Makefile +++ b/Makefile @@ -886,6 +886,7 @@ MK_TEST_DIRS += tests/arch/xilinx MK_TEST_DIRS += tests/bugpoint MK_TEST_DIRS += tests/opt MK_TEST_DIRS += tests/sat +MK_TEST_DIRS += tests/scripts MK_TEST_DIRS += tests/sim MK_TEST_DIRS += tests/svtypes MK_TEST_DIRS += tests/techmap From 7630e24bbfa1bbf62cd6e1caa31859e7d22d2724 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 6 Oct 2025 11:38:55 +1300 Subject: [PATCH 13/16] Tests: Use setattr -setstr --- tests/arch/ecp5/memories.ys | 24 ++++++++++++------------ tests/arch/ice40/memories.ys | 10 +++++----- tests/arch/xilinx/attributes_test.ys | 2 +- tests/arch/xilinx/blockram.ys | 4 ++-- tests/techmap/clkbufmap.ys | 10 +++++----- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/tests/arch/ecp5/memories.ys b/tests/arch/ecp5/memories.ys index f075182c8..904be565b 100644 --- a/tests/arch/ecp5/memories.ys +++ b/tests/arch/ecp5/memories.ys @@ -19,14 +19,14 @@ select -assert-count 9 t:TRELLIS_DPR16X4 design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp hierarchy -top sync_ram_sdp -setattr -set syn_ramstyle "block_ram" m:memory +setattr -setstr syn_ramstyle block_ram m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:DP16KD design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp hierarchy -top sync_ram_sdp -setattr -set syn_ramstyle "Block_RAM" m:memory +setattr -setstr syn_ramstyle Block_RAM m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:DP16KD # any case works @@ -41,7 +41,7 @@ select -assert-count 9 t:TRELLIS_DPR16X4 design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp hierarchy -top sync_ram_sdp -setattr -set syn_ramstyle "registers" m:memory +setattr -setstr syn_ramstyle registers m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 0 t:DP16KD # requested FFRAM explicitly select -assert-count 180 t:TRELLIS_FF @@ -98,14 +98,14 @@ select -assert-count 5 t:TRELLIS_DPR16X4 design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp hierarchy -top sync_ram_sdp -setattr -set syn_ramstyle "block_ram" m:memory +setattr -setstr syn_ramstyle block_ram m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:DP16KD design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp hierarchy -top sync_ram_sdp -setattr -set syn_ramstyle "Block_RAM" m:memory +setattr -setstr syn_ramstyle Block_RAM m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:DP16KD # any case works @@ -120,7 +120,7 @@ select -assert-count 5 t:TRELLIS_DPR16X4 design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp hierarchy -top sync_ram_sdp -setattr -set syn_ramstyle "registers" m:memory +setattr -setstr syn_ramstyle registers m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 0 t:DP16KD # requested FFRAM explicitly select -assert-count 90 t:TRELLIS_FF @@ -146,14 +146,14 @@ select -assert-count 1 t:TRELLIS_DPR16X4 design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 4 -set DATA_WIDTH 4 sync_ram_sdp hierarchy -top sync_ram_sdp -setattr -set syn_ramstyle "distributed" m:memory +setattr -setstr syn_ramstyle distributed m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:TRELLIS_DPR16X4 design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 4 -set DATA_WIDTH 4 sync_ram_sdp hierarchy -top sync_ram_sdp -setattr -set syn_ramstyle "registers" m:memory +setattr -setstr syn_ramstyle registers m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 0 t:TRELLIS_DPR16X4 # requested FFRAM explicitly select -assert-count 68 t:TRELLIS_FF @@ -187,7 +187,7 @@ select -assert-min 18 t:LUT4 design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom hierarchy -top sync_rom -setattr -set syn_romstyle "ebr" m:memory +setattr -setstr syn_romstyle ebr m:memory synth_ecp5 -top sync_rom; cd sync_rom select -assert-count 1 t:DP16KD @@ -201,7 +201,7 @@ select -assert-count 1 t:DP16KD design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 3 -set DATA_WIDTH 36 sync_rom hierarchy -top sync_rom -setattr -set syn_romstyle "logic" m:memory +setattr -setstr syn_romstyle logic m:memory synth_ecp5 -top sync_rom; cd sync_rom select -assert-count 0 t:DP16KD # requested LUTROM explicitly select -assert-min 18 t:LUT4 @@ -234,7 +234,7 @@ select -assert-min 9 t:LUT4 design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_rom hierarchy -top sync_rom -setattr -set syn_romstyle "ebr" m:memory +setattr -setstr syn_romstyle ebr m:memory synth_ecp5 -top sync_rom; cd sync_rom select -assert-count 1 t:DP16KD @@ -248,7 +248,7 @@ select -assert-count 1 t:DP16KD design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 3 -set DATA_WIDTH 18 sync_rom hierarchy -top sync_rom -setattr -set syn_romstyle "logic" m:memory +setattr -setstr syn_romstyle logic m:memory synth_ecp5 -top sync_rom; cd sync_rom select -assert-count 0 t:DP16KD # requested LUTROM explicitly select -assert-min 9 t:LUT4 diff --git a/tests/arch/ice40/memories.ys b/tests/arch/ice40/memories.ys index d480a3abe..c2eb5924d 100644 --- a/tests/arch/ice40/memories.ys +++ b/tests/arch/ice40/memories.ys @@ -37,14 +37,14 @@ select -assert-min 1 t:SB_DFFE design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp hierarchy -top sync_ram_sdp -setattr -set syn_ramstyle "block_ram" m:memory +setattr -setstr syn_ramstyle block_ram m:memory synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:SB_RAM40_4K design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp hierarchy -top sync_ram_sdp -setattr -set syn_ramstyle "Block_RAM" m:memory +setattr -setstr syn_ramstyle Block_RAM m:memory synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:SB_RAM40_4K # any case works @@ -58,7 +58,7 @@ select -assert-count 1 t:SB_RAM40_4K design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp hierarchy -top sync_ram_sdp -setattr -set syn_ramstyle "registers" m:memory +setattr -setstr syn_ramstyle registers m:memory synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 0 t:SB_RAM40_4K # requested FFRAM explicitly select -assert-min 1 t:SB_DFFE @@ -110,7 +110,7 @@ select -assert-min 1 t:SB_LUT4 design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom hierarchy -top sync_rom -setattr -set syn_romstyle "ebr" m:memory +setattr -setstr syn_romstyle ebr m:memory synth_ice40 -top sync_rom; cd sync_rom select -assert-count 1 t:SB_RAM40_4K @@ -124,7 +124,7 @@ select -assert-count 1 t:SB_RAM40_4K design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom hierarchy -top sync_rom -setattr -set syn_romstyle "logic" m:memory +setattr -setstr syn_romstyle logic m:memory synth_ice40 -top sync_rom; cd sync_rom select -assert-count 0 t:SB_RAM40_4K # requested LUTROM explicitly select -assert-min 1 t:SB_LUT4 diff --git a/tests/arch/xilinx/attributes_test.ys b/tests/arch/xilinx/attributes_test.ys index 74861850f..7d1a54537 100644 --- a/tests/arch/xilinx/attributes_test.ys +++ b/tests/arch/xilinx/attributes_test.ys @@ -16,7 +16,7 @@ select -assert-count 1 t:RAM32M # Set ram_style distributed to blockram memory; will be implemented as distributed design -reset read_verilog ../common/memory_attributes/attributes_test.v -setattr -set ram_style "distributed" block_ram/m:* +setattr -setstr ram_style distributed block_ram/m:* synth_xilinx -top block_ram -noiopad cd block_ram # Constrain all select calls below inside the top module select -assert-count 16 t:RAM256X1S diff --git a/tests/arch/xilinx/blockram.ys b/tests/arch/xilinx/blockram.ys index c2b7aede7..474fecf9b 100644 --- a/tests/arch/xilinx/blockram.ys +++ b/tests/arch/xilinx/blockram.ys @@ -51,7 +51,7 @@ select -assert-count 1 t:RAMB36E1 design -reset read_verilog ../common/blockram.v hierarchy -top sync_ram_sdp -chparam ADDRESS_WIDTH 12 -chparam DATA_WIDTH 1 -setattr -set ram_style "block" m:memory +setattr -setstr ram_style block m:memory synth_xilinx -top sync_ram_sdp -noiopad cd sync_ram_sdp select -assert-count 1 t:RAMB18E1 @@ -67,7 +67,7 @@ select -assert-count 0 t:RAMB18E1 design -reset read_verilog ../common/blockram.v hierarchy -top sync_ram_sdp -chparam ADDRESS_WIDTH 8 -chparam DATA_WIDTH 1 -setattr -set ram_style "block" m:memory +setattr -setstr ram_style block m:memory synth_xilinx -top sync_ram_sdp -noiopad cd sync_ram_sdp select -assert-count 1 t:RAMB18E1 diff --git a/tests/techmap/clkbufmap.ys b/tests/techmap/clkbufmap.ys index abe830109..8cac96fc7 100644 --- a/tests/techmap/clkbufmap.ys +++ b/tests/techmap/clkbufmap.ys @@ -82,7 +82,7 @@ select -assert-count 0 w:clk2 %a %co t:clkbuf %i design -load ref setattr -set clkbuf_inhibit 1 w:clk1 -setattr -set buffer_type "bufg" w:clk2 +setattr -setstr buffer_type bufg w:clk2 clkbufmap -buf clkbuf o:i w:* a:buffer_type=none a:buffer_type=bufr %u %d select -assert-count 3 top/t:clkbuf select -assert-count 3 sub/t:clkbuf @@ -98,10 +98,10 @@ select -assert-count 1 @clk2 %x:+[o] %co c:s1 %i # And that one fanout is 's0 # ---------------------- design -load ref -setattr -set buffer_type "none" w:clk1 -setattr -set buffer_type "bufr" w:clk2 -setattr -set buffer_type "bufr" w:sclk4 -setattr -set buffer_type "bufr" w:sclk5 +setattr -setstr buffer_type none w:clk1 +setattr -setstr buffer_type bufr w:clk2 +setattr -setstr buffer_type bufr w:sclk4 +setattr -setstr buffer_type bufr w:sclk5 clkbufmap -buf clkbuf o:i w:* a:buffer_type=none a:buffer_type=bufr %u %d select -assert-count 0 w:clk1 %a %co t:clkbuf %i select -assert-count 0 w:clk2 %a %co t:clkbuf %i From 4b4ea671e563df2a85680780045c48b6f15bd881 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 6 Oct 2025 14:10:29 +1300 Subject: [PATCH 14/16] abc9.cc: Use setattr -setstr --- passes/techmap/abc9.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 2cf28f849..d681d254a 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -321,7 +321,7 @@ struct Abc9Pass : public ScriptPass // then select all its fanins // then select all fanouts of all that // lastly remove $_DFF_[NP]_ cells - run("setattr -set submod \"$abc9_flop\" t:$_DFF_?_ %ci* %co* t:$_DFF_?_ %d", " (only if -dff)"); + run("setattr -setstr submod \"$abc9_flop\" t:$_DFF_?_ %ci* %co* t:$_DFF_?_ %d", " (only if -dff)"); run("submod", " (only if -dff)"); run("setattr -mod -set whitebox 1 -set abc9_flop 1 -set abc9_box 1 *_$abc9_flop", "(only if -dff)"); if (help_mode) { From 1248af1e022e38211febf510976a0799cb767524 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 6 Oct 2025 14:22:18 +1300 Subject: [PATCH 15/16] Tests: Prefer single quotes for regex Replaces double quotes on problematic regex strings (mostly ones that have escape sequences that are easier to preserve in single quotes). Necessitates also changing single quotes to `.`, i.e match any. For some (mostly ones that only have a single escaped character, or were using `\.` to match a literal fullstop) keep the double quotes and fix the regex instead. --- examples/smtbmc/glift/mux2.ys | 10 +++++----- tests/arch/xilinx/abc9_dff.ys | 12 ++++++------ tests/scripts/space_in_name.ys | 7 ++++--- tests/select/boxes_import.ys | 4 ++-- tests/select/unset.ys | 2 +- tests/svtypes/typedef_initial_and_assign.ys | 16 ++++++++-------- tests/various/printattr.ys | 2 +- tests/various/src.ys | 4 ++-- tests/various/sta.ys | 6 +++--- tests/various/stat.ys | 4 ++-- tests/various/stat_high_level.ys | 4 ++-- tests/various/stat_high_level2.ys | 4 ++-- tests/various/sv_defines_mismatch.ys | 2 +- tests/various/sv_defines_too_few.ys | 2 +- tests/verilog/always_comb_latch_1.ys | 2 +- tests/verilog/always_comb_latch_2.ys | 2 +- tests/verilog/always_comb_latch_3.ys | 2 +- tests/verilog/always_comb_latch_4.ys | 2 +- tests/verilog/block_end_label_only.ys | 2 +- tests/verilog/block_end_label_wrong.ys | 2 +- tests/verilog/block_labels.ys | 2 +- tests/verilog/bug2493.ys | 2 +- tests/verilog/conflict_assert.ys | 2 +- tests/verilog/conflict_cell_memory.ys | 2 +- tests/verilog/conflict_interface_port.ys | 2 +- tests/verilog/conflict_memory_wire.ys | 2 +- tests/verilog/conflict_pwire.ys | 2 +- tests/verilog/conflict_wire_memory.ys | 2 +- tests/verilog/gen_block_end_label_only.ys | 2 +- tests/verilog/gen_block_end_label_wrong.ys | 2 +- tests/verilog/genblk_port_decl.ys | 2 +- tests/verilog/hidden_decl.ys | 2 +- tests/verilog/macro_unapplied.ys | 2 +- tests/verilog/macro_unapplied_newline.ys | 2 +- tests/verilog/module_end_label.ys | 2 +- tests/verilog/package_end_label.ys | 2 +- tests/verilog/param_no_default_unbound_1.ys | 2 +- tests/verilog/param_no_default_unbound_2.ys | 2 +- tests/verilog/param_no_default_unbound_3.ys | 2 +- tests/verilog/param_no_default_unbound_4.ys | 2 +- tests/verilog/param_no_default_unbound_5.ys | 2 +- tests/verilog/string-literals.ys | 4 ++-- tests/verilog/wire_and_var.ys | 10 +++++----- 43 files changed, 74 insertions(+), 73 deletions(-) diff --git a/examples/smtbmc/glift/mux2.ys b/examples/smtbmc/glift/mux2.ys index a8e99912b..e844e96e3 100644 --- a/examples/smtbmc/glift/mux2.ys +++ b/examples/smtbmc/glift/mux2.ys @@ -1,9 +1,9 @@ logger -expect log "SAT proof finished - no model found: SUCCESS!" 1 -logger -expect log "Number of cells:.*[\t ]12" 1 -logger -expect log "Number of cells:.*[\t ]20" 1 -logger -expect log "Problem is satisfiable with \\gate.__glift_weight = 11." 1 -logger -expect log "Problem is NOT satisfiable with \\gate.__glift_weight <= 10." 1 -logger -expect log "Wire \\gate.__glift_weight is minimized at 11." 1 +logger -expect log 'Number of cells:.*[\t ]12' 1 +logger -expect log 'Number of cells:.*[\t ]20' 1 +logger -expect log 'Problem is satisfiable with \\gate.__glift_weight = 11.' 1 +logger -expect log 'Problem is NOT satisfiable with \\gate.__glift_weight <= 10.' 1 +logger -expect log 'Wire \\gate.__glift_weight is minimized at 11.' 1 logger -expect log "Specializing .* from file with .* = 1." 2 logger -expect log "Specializing .* from file with .* = 0." 4 read_verilog < Date: Mon, 6 Oct 2025 14:33:41 +1300 Subject: [PATCH 16/16] tests/memfile: Fix chparam -set --- tests/memfile/run-test.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/memfile/run-test.sh b/tests/memfile/run-test.sh index db0ec54ee..d9b344fbf 100755 --- a/tests/memfile/run-test.sh +++ b/tests/memfile/run-test.sh @@ -8,27 +8,27 @@ cp content1.dat temp/content2.dat cd .. echo "Running from the parent directory with content1.dat" -../yosys -qp "read_verilog -defer memfile/memory.v; chparam -set MEMFILE \"content1.dat\" memory" +../yosys -qp "read_verilog -defer memfile/memory.v; chparam -setstr MEMFILE \"content1.dat\" memory" echo "Running from the parent directory with temp/content2.dat" -../yosys -qp "read_verilog -defer memfile/memory.v; chparam -set MEMFILE \"temp/content2.dat\" memory" +../yosys -qp "read_verilog -defer memfile/memory.v; chparam -setstr MEMFILE \"temp/content2.dat\" memory" echo "Running from the parent directory with memfile/temp/content2.dat" -../yosys -qp "read_verilog -defer memfile/memory.v; chparam -set MEMFILE \"memfile/temp/content2.dat\" memory" +../yosys -qp "read_verilog -defer memfile/memory.v; chparam -setstr MEMFILE \"memfile/temp/content2.dat\" memory" cd memfile echo "Running from the same directory with content1.dat" -../../yosys -qp "read_verilog -defer memory.v; chparam -set MEMFILE \"content1.dat\" memory" +../../yosys -qp "read_verilog -defer memory.v; chparam -setstr MEMFILE \"content1.dat\" memory" echo "Running from the same directory with temp/content2.dat" -../../yosys -qp "read_verilog -defer memory.v; chparam -set MEMFILE \"temp/content2.dat\" memory" +../../yosys -qp "read_verilog -defer memory.v; chparam -setstr MEMFILE \"temp/content2.dat\" memory" cd temp echo "Running from a child directory with content1.dat" -../../../yosys -qp "read_verilog -defer ../memory.v; chparam -set MEMFILE \"content1.dat\" memory" +../../../yosys -qp "read_verilog -defer ../memory.v; chparam -setstr MEMFILE \"content1.dat\" memory" echo "Running from a child directory with temp/content2.dat" -../../../yosys -qp "read_verilog -defer ../memory.v; chparam -set MEMFILE \"temp/content2.dat\" memory" +../../../yosys -qp "read_verilog -defer ../memory.v; chparam -setstr MEMFILE \"temp/content2.dat\" memory" echo "Running from a child directory with content2.dat" -../../../yosys -qp "read_verilog -defer ../memory.v; chparam -set MEMFILE \"temp/content2.dat\" memory" +../../../yosys -qp "read_verilog -defer ../memory.v; chparam -setstr MEMFILE \"temp/content2.dat\" memory" cd ..