Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 5 additions & 5 deletions examples/smtbmc/glift/mux2.ys
Original file line number Diff line number Diff line change
@@ -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 <<EOT
Expand Down
38 changes: 35 additions & 3 deletions kernel/io.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "kernel/log.h"
#include <iostream>
#include <string>
#include <iomanip>

#if !defined(WIN32)
#include <dirent.h>
Expand Down Expand Up @@ -37,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] == '"' && (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 + ";";
Expand Down Expand Up @@ -592,4 +594,34 @@ 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) {
for (auto c : {' ', '\\', '#', ';', '"', '\''}) {
if (s.find(c) != std::string::npos) return true;
}
return false;
}

std::string quote(const std::string &s) {
std::ostringstream ss;
if (s.find('\'') != std::string::npos)
ss << std::quoted(s);
else
ss << '\'' << s << '\'';
return ss.str();
}

std::string unquote(const std::string &s) {
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
4 changes: 4 additions & 0 deletions kernel/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@
// Collect another int for the dynamic width precision/args
// for the next format conversion specifier.
if constexpr (std::is_convertible_v<Arg, int>) {
dynamic_ints[static_cast<uint8_t>(num_dynamic_ints)] = arg;

Check warning on line 387 in kernel/io.h

View workflow job for this annotation

GitHub Actions / test-compile (ubuntu-latest, gcc-10)

array subscript 2 is outside array bounds of ‘int [2]’ [-Warray-bounds]

Check warning on line 387 in kernel/io.h

View workflow job for this annotation

GitHub Actions / test-compile (ubuntu-latest, gcc-10)

array subscript 2 is outside array bounds of ‘int [2]’ [-Warray-bounds]

Check warning on line 387 in kernel/io.h

View workflow job for this annotation

GitHub Actions / test-compile (ubuntu-latest, gcc-10)

array subscript 2 is outside array bounds of ‘int [2]’ [-Warray-bounds]

Check warning on line 387 in kernel/io.h

View workflow job for this annotation

GitHub Actions / test-compile (ubuntu-latest, gcc-10)

array subscript 2 is outside array bounds of ‘int [2]’ [-Warray-bounds]

Check warning on line 387 in kernel/io.h

View workflow job for this annotation

GitHub Actions / test-compile (ubuntu-latest, gcc-10)

array subscript 2 is outside array bounds of ‘int [2]’ [-Warray-bounds]

Check warning on line 387 in kernel/io.h

View workflow job for this annotation

GitHub Actions / test-compile (ubuntu-latest, gcc-10)

array subscript 2 is outside array bounds of ‘int [2]’ [-Warray-bounds]

Check warning on line 387 in kernel/io.h

View workflow job for this annotation

GitHub Actions / test-compile (ubuntu-latest, gcc-10)

array subscript 2 is outside array bounds of ‘int [2]’ [-Warray-bounds]

Check warning on line 387 in kernel/io.h

View workflow job for this annotation

GitHub Actions / test-compile (ubuntu-latest, gcc-10)

array subscript 2 is outside array bounds of ‘int [2]’ [-Warray-bounds]

Check warning on line 387 in kernel/io.h

View workflow job for this annotation

GitHub Actions / test-compile (ubuntu-latest, gcc-10)

array subscript 2 is outside array bounds of ‘int [2]’ [-Warray-bounds]

Check warning on line 387 in kernel/io.h

View workflow job for this annotation

GitHub Actions / test-compile (ubuntu-latest, gcc-14)

array subscript 2 is outside array bounds of ‘int [2]’ [-Warray-bounds=]

Check warning on line 387 in kernel/io.h

View workflow job for this annotation

GitHub Actions / test-compile (ubuntu-latest, gcc-14)

array subscript 2 is outside array bounds of ‘int [2]’ [-Warray-bounds=]

Check warning on line 387 in kernel/io.h

View workflow job for this annotation

GitHub Actions / test-compile (ubuntu-latest, gcc-14)

array subscript 2 is outside array bounds of ‘int [2]’ [-Warray-bounds=]

Check warning on line 387 in kernel/io.h

View workflow job for this annotation

GitHub Actions / test-compile (ubuntu-latest, gcc-14)

array subscript 2 is outside array bounds of ‘int [2]’ [-Warray-bounds=]

Check warning on line 387 in kernel/io.h

View workflow job for this annotation

GitHub Actions / test-compile (ubuntu-latest, gcc-14)

array subscript 2 is outside array bounds of ‘int [2]’ [-Warray-bounds=]

Check warning on line 387 in kernel/io.h

View workflow job for this annotation

GitHub Actions / test-compile (ubuntu-latest, gcc-14)

array subscript 2 is outside array bounds of ‘int [2]’ [-Warray-bounds=]
} else {
YOSYS_ABORT("Internal error");
}
Expand Down Expand Up @@ -470,6 +470,10 @@
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
10 changes: 6 additions & 4 deletions kernel/register.cc
Original file line number Diff line number Diff line change
Expand Up @@ -222,15 +222,15 @@ 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)
call(design, "clean");
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')
Expand All @@ -256,8 +256,10 @@ void Pass::call(RTLIL::Design *design, std::vector<std::string> 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");
}

Expand Down
15 changes: 2 additions & 13 deletions passes/cmds/bugpoint.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -471,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()) {
Expand Down Expand Up @@ -550,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;
Expand Down
4 changes: 0 additions & 4 deletions passes/cmds/logger.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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));
Expand All @@ -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));
Expand Down Expand Up @@ -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");
Expand Down
2 changes: 0 additions & 2 deletions passes/cmds/scratchpad.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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);
Expand Down
61 changes: 40 additions & 21 deletions passes/cmds/setattr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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 <name> <value>\n");
log(" -setstr <name> <strvalue>\n");
log(" set the named attribute to the given value, string values must use\n");
log(" the -setstr option\n");
log("\n");
log(" -unset <name>\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<std::string> args, RTLIL::Design *design) override
Expand All @@ -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()) {
Expand Down Expand Up @@ -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 parameters on the selected cells.\n");
log("\n");
log(" -type\n");
log(" change the cell type of the selected cells\n");
log("\n");
log(" -set <name> <value>\n");
log(" -setstr <name> <strvalue>\n");
log(" set the named parameter to the given value, string values must use\n");
log(" the -setstr option\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(" -unset <name>\n");
log(" unset the named parameter\n");
log("\n");
log("The -type option can be used to change the cell type of the selected cells.\n");
log("The options -setstr, -set, and -unset can be specified multiple times.\n");
log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *design) override
Expand All @@ -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()) {
Expand Down Expand Up @@ -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");
Expand All @@ -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") {
Expand Down
1 change: 0 additions & 1 deletion passes/cmds/setenv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
2 changes: 1 addition & 1 deletion passes/techmap/abc9.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Loading
Loading