diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 16 | ||||
-rw-r--r-- | backends/firrtl/firrtl.cc | 1 | ||||
-rw-r--r-- | frontends/rpc/Makefile.inc | 3 | ||||
-rw-r--r-- | frontends/verilog/verilog_parser.y | 55 | ||||
-rw-r--r-- | kernel/driver.cc | 15 | ||||
-rw-r--r-- | kernel/log.cc | 17 | ||||
-rw-r--r-- | kernel/log.h | 24 | ||||
-rw-r--r-- | kernel/yosys.cc | 4 | ||||
-rw-r--r-- | passes/cmds/add.cc | 58 | ||||
-rw-r--r-- | passes/cmds/logger.cc | 38 | ||||
-rw-r--r-- | tests/various/logger_error.ys | 6 | ||||
-rw-r--r-- | tests/various/logger_nowarning.ys | 6 | ||||
-rw-r--r-- | tests/various/logger_warn.ys | 6 | ||||
-rw-r--r-- | tests/various/logger_warning.ys | 6 | ||||
-rw-r--r-- | tests/various/src.ys | 8 |
16 files changed, 202 insertions, 62 deletions
diff --git a/.gitignore b/.gitignore index 76f53cd06..0460c7c13 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ __pycache__ /yosys /yosys.exe /yosys.js +/yosys.wasm /yosys-abc /yosys-abc.exe /yosys-config @@ -237,7 +237,8 @@ ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DABC_MEMALIGN=8" EMCCFLAGS := -Os -Wno-warn-absolute-paths EMCCFLAGS += --memory-init-file 0 --embed-file share -s NO_EXIT_RUNTIME=1 EMCCFLAGS += -s EXPORTED_FUNCTIONS="['_main','_run','_prompt','_errmsg']" -EMCCFLAGS += -s TOTAL_MEMORY=128*1024*1024 +EMCCFLAGS += -s TOTAL_MEMORY=134217728 +EMCCFLAGS += -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' # https://github.com/kripken/emscripten/blob/master/src/settings.js CXXFLAGS += $(EMCCFLAGS) LDFLAGS += $(EMCCFLAGS) @@ -256,10 +257,10 @@ viz.js: wget -O viz.js.part https://github.com/mdaines/viz.js/releases/download/0.0.3/viz.js mv viz.js.part viz.js -yosysjs-$(YOSYS_VER).zip: yosys.js viz.js misc/yosysjs/* +yosysjs-$(YOSYS_VER).zip: yosys.js yosys.wasm viz.js misc/yosysjs/* rm -rf yosysjs-$(YOSYS_VER) yosysjs-$(YOSYS_VER).zip mkdir -p yosysjs-$(YOSYS_VER) - cp viz.js misc/yosysjs/* yosys.js yosysjs-$(YOSYS_VER)/ + cp viz.js misc/yosysjs/* yosys.js yosys.wasm yosysjs-$(YOSYS_VER)/ zip -r yosysjs-$(YOSYS_VER).zip yosysjs-$(YOSYS_VER) yosys.html: misc/yosys.html @@ -668,7 +669,8 @@ ifneq ($(ABCREV),default) $(Q) if ( cd abc 2> /dev/null && ! git diff-index --quiet HEAD; ); then \ echo 'REEBE: NOP pbagnvaf ybpny zbqvsvpngvbaf! Frg NOPERI=qrsnhyg va Lbflf Znxrsvyr!' | tr 'A-Za-z' 'N-ZA-Mn-za-m'; false; \ fi - $(Q) if test "`cd abc 2> /dev/null && git rev-parse --short HEAD`" != "$(ABCREV)"; then \ +# set a variable so the test fails if git fails to run - when comparing outputs directly, empty string would match empty string + $(Q) if ! (cd abc && rev="`git rev-parse $(ABCREV)`" && test "`git rev-parse HEAD`" == "$$rev"); then \ test $(ABCPULL) -ne 0 || { echo 'REEBE: NOP abg hc gb qngr naq NOPCHYY frg gb 0 va Znxrsvyr!' | tr 'A-Za-z' 'N-ZA-Mn-za-m'; exit 1; }; \ echo "Pulling ABC from $(ABCURL):"; set -x; \ test -d abc || git clone $(ABCURL) abc; \ @@ -765,7 +767,7 @@ clean-unit-test: install: $(TARGETS) $(EXTRA_TARGETS) $(INSTALL_SUDO) mkdir -p $(DESTDIR)$(BINDIR) - $(INSTALL_SUDO) cp $(TARGETS) $(DESTDIR)$(BINDIR) + $(INSTALL_SUDO) cp $(filter-out libyosys.so,$(TARGETS)) $(DESTDIR)$(BINDIR) ifneq ($(filter yosys,$(TARGETS)),) $(INSTALL_SUDO) $(STRIP) -S $(DESTDIR)$(BINDIR)/yosys endif @@ -895,6 +897,7 @@ config-emcc: clean echo 'ENABLE_ABC := 0' >> Makefile.conf echo 'ENABLE_PLUGINS := 0' >> Makefile.conf echo 'ENABLE_READLINE := 0' >> Makefile.conf + echo 'ENABLE_ZLIB := 0' >> Makefile.conf config-mxe: clean echo 'CONFIG := mxe' > Makefile.conf @@ -929,6 +932,9 @@ echo-yosys-ver: echo-git-rev: @echo "$(GIT_REV)" +echo-abc-rev: + @echo "$(ABCREV)" + -include libs/*/*.d -include frontends/*/*.d -include passes/*/*.d diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc index 87db0edf7..22aa686a7 100644 --- a/backends/firrtl/firrtl.cc +++ b/backends/firrtl/firrtl.cc @@ -25,7 +25,6 @@ #include "kernel/log.h" #include <algorithm> #include <string> -#include <regex> #include <vector> #include <cmath> diff --git a/frontends/rpc/Makefile.inc b/frontends/rpc/Makefile.inc index 9af505098..7b270b6fe 100644 --- a/frontends/rpc/Makefile.inc +++ b/frontends/rpc/Makefile.inc @@ -1,2 +1,3 @@ - +ifneq ($(CONFIG),emcc) OBJS += frontends/rpc/rpc_frontend.o +endif diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index b4c9016dc..1132e97ae 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -2114,18 +2114,22 @@ simple_behavioral_stmt: lvalue '=' delay expr { AstNode *node = new AstNode(AST_ASSIGN_EQ, $1, $4); ast_stack.back()->children.push_back(node); + SET_AST_NODE_LOC(node, @1, @4); } | lvalue TOK_INCREMENT { AstNode *node = new AstNode(AST_ASSIGN_EQ, $1, new AstNode(AST_ADD, $1->clone(), AstNode::mkconst_int(1, true))); ast_stack.back()->children.push_back(node); + SET_AST_NODE_LOC(node, @1, @2); } | lvalue TOK_DECREMENT { AstNode *node = new AstNode(AST_ASSIGN_EQ, $1, new AstNode(AST_SUB, $1->clone(), AstNode::mkconst_int(1, true))); ast_stack.back()->children.push_back(node); + SET_AST_NODE_LOC(node, @1, @2); } | lvalue OP_LE delay expr { AstNode *node = new AstNode(AST_ASSIGN_LE, $1, $4); ast_stack.back()->children.push_back(node); + SET_AST_NODE_LOC(node, @1, @4); }; // this production creates the obligatory if-else shift/reduce conflict @@ -2183,6 +2187,7 @@ behavioral_stmt: } behavioral_stmt { SET_AST_NODE_LOC(ast_stack.back(), @13, @13); ast_stack.pop_back(); + SET_AST_NODE_LOC(ast_stack.back(), @2, @13); ast_stack.pop_back(); } | attr TOK_WHILE '(' expr ')' { @@ -2336,6 +2341,7 @@ gen_case_item: ast_stack.push_back(node); } case_select { case_type_stack.push_back(0); + SET_AST_NODE_LOC(ast_stack.back(), @2, @2); } gen_stmt_or_null { case_type_stack.pop_back(); ast_stack.pop_back(); @@ -2347,10 +2353,14 @@ case_select: case_expr_list: TOK_DEFAULT { - ast_stack.back()->children.push_back(new AstNode(AST_DEFAULT)); + AstNode *node = new AstNode(AST_DEFAULT); + SET_AST_NODE_LOC(node, @1, @1); + ast_stack.back()->children.push_back(node); } | TOK_SVA_LABEL { - ast_stack.back()->children.push_back(new AstNode(AST_IDENTIFIER)); + AstNode *node = new AstNode(AST_IDENTIFIER); + SET_AST_NODE_LOC(node, @1, @1); + ast_stack.back()->children.push_back(node); ast_stack.back()->children.back()->str = *$1; delete $1; } | @@ -2497,6 +2507,7 @@ expr: $$->children.push_back($1); $$->children.push_back($4); $$->children.push_back($6); + SET_AST_NODE_LOC($$, @1, @$); append_attr($$, $3); }; @@ -2519,6 +2530,7 @@ basic_expr: frontend_verilog_yyerror("Cast operation must be applied on sized constants, e.g. <ID>\'d0, while %s is not a sized constant.", $2->c_str()); AstNode *bits = new AstNode(AST_IDENTIFIER); bits->str = *$1; + SET_AST_NODE_LOC(bits, @1, @1); AstNode *val = const2ast(*$2, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode); if (val == NULL) log_error("Value conversion failed: `%s'\n", $2->c_str()); @@ -2539,6 +2551,7 @@ basic_expr: if ((*$1)[j] != '_') p[i++] = (*$1)[j], p[i] = 0; $$->realvalue = strtod(p, &q); + SET_AST_NODE_LOC($$, @1, @1); log_assert(*q == 0); delete $1; free(p); @@ -2552,6 +2565,7 @@ basic_expr: node->str = *$1; delete $1; ast_stack.push_back(node); + SET_AST_NODE_LOC(node, @1, @1); append_attr(node, $2); } '(' arg_list optional_comma ')' { $$ = ast_stack.back(); @@ -2581,148 +2595,185 @@ basic_expr: } | '~' attr basic_expr %prec UNARY_OPS { $$ = new AstNode(AST_BIT_NOT, $3); + SET_AST_NODE_LOC($$, @1, @3); append_attr($$, $2); } | basic_expr '&' attr basic_expr { $$ = new AstNode(AST_BIT_AND, $1, $4); + SET_AST_NODE_LOC($$, @1, @4); append_attr($$, $3); } | basic_expr OP_NAND attr basic_expr { $$ = new AstNode(AST_BIT_NOT, new AstNode(AST_BIT_AND, $1, $4)); + SET_AST_NODE_LOC($$, @1, @4); append_attr($$, $3); } | basic_expr '|' attr basic_expr { $$ = new AstNode(AST_BIT_OR, $1, $4); + SET_AST_NODE_LOC($$, @1, @4); append_attr($$, $3); } | basic_expr OP_NOR attr basic_expr { $$ = new AstNode(AST_BIT_NOT, new AstNode(AST_BIT_OR, $1, $4)); + SET_AST_NODE_LOC($$, @1, @4); append_attr($$, $3); } | basic_expr '^' attr basic_expr { $$ = new AstNode(AST_BIT_XOR, $1, $4); + SET_AST_NODE_LOC($$, @1, @4); append_attr($$, $3); } | basic_expr OP_XNOR attr basic_expr { $$ = new AstNode(AST_BIT_XNOR, $1, $4); + SET_AST_NODE_LOC($$, @1, @4); append_attr($$, $3); } | '&' attr basic_expr %prec UNARY_OPS { $$ = new AstNode(AST_REDUCE_AND, $3); + SET_AST_NODE_LOC($$, @1, @3); append_attr($$, $2); } | OP_NAND attr basic_expr %prec UNARY_OPS { $$ = new AstNode(AST_REDUCE_AND, $3); + SET_AST_NODE_LOC($$, @1, @3); append_attr($$, $2); $$ = new AstNode(AST_LOGIC_NOT, $$); } | '|' attr basic_expr %prec UNARY_OPS { $$ = new AstNode(AST_REDUCE_OR, $3); + SET_AST_NODE_LOC($$, @1, @3); append_attr($$, $2); } | OP_NOR attr basic_expr %prec UNARY_OPS { $$ = new AstNode(AST_REDUCE_OR, $3); + SET_AST_NODE_LOC($$, @1, @3); append_attr($$, $2); $$ = new AstNode(AST_LOGIC_NOT, $$); + SET_AST_NODE_LOC($$, @1, @3); } | '^' attr basic_expr %prec UNARY_OPS { $$ = new AstNode(AST_REDUCE_XOR, $3); + SET_AST_NODE_LOC($$, @1, @3); append_attr($$, $2); } | OP_XNOR attr basic_expr %prec UNARY_OPS { $$ = new AstNode(AST_REDUCE_XNOR, $3); + SET_AST_NODE_LOC($$, @1, @3); append_attr($$, $2); } | basic_expr OP_SHL attr basic_expr { $$ = new AstNode(AST_SHIFT_LEFT, $1, new AstNode(AST_TO_UNSIGNED, $4)); + SET_AST_NODE_LOC($$, @1, @4); append_attr($$, $3); } | basic_expr OP_SHR attr basic_expr { $$ = new AstNode(AST_SHIFT_RIGHT, $1, new AstNode(AST_TO_UNSIGNED, $4)); + SET_AST_NODE_LOC($$, @1, @4); append_attr($$, $3); } | basic_expr OP_SSHL attr basic_expr { $$ = new AstNode(AST_SHIFT_SLEFT, $1, new AstNode(AST_TO_UNSIGNED, $4)); + SET_AST_NODE_LOC($$, @1, @4); append_attr($$, $3); } | basic_expr OP_SSHR attr basic_expr { $$ = new AstNode(AST_SHIFT_SRIGHT, $1, new AstNode(AST_TO_UNSIGNED, $4)); + SET_AST_NODE_LOC($$, @1, @4); append_attr($$, $3); } | basic_expr '<' attr basic_expr { $$ = new AstNode(AST_LT, $1, $4); + SET_AST_NODE_LOC($$, @1, @4); append_attr($$, $3); } | basic_expr OP_LE attr basic_expr { $$ = new AstNode(AST_LE, $1, $4); + SET_AST_NODE_LOC($$, @1, @4); append_attr($$, $3); } | basic_expr OP_EQ attr basic_expr { $$ = new AstNode(AST_EQ, $1, $4); + SET_AST_NODE_LOC($$, @1, @4); append_attr($$, $3); } | basic_expr OP_NE attr basic_expr { $$ = new AstNode(AST_NE, $1, $4); + SET_AST_NODE_LOC($$, @1, @4); append_attr($$, $3); } | basic_expr OP_EQX attr basic_expr { $$ = new AstNode(AST_EQX, $1, $4); + SET_AST_NODE_LOC($$, @1, @4); append_attr($$, $3); } | basic_expr OP_NEX attr basic_expr { $$ = new AstNode(AST_NEX, $1, $4); + SET_AST_NODE_LOC($$, @1, @4); append_attr($$, $3); } | basic_expr OP_GE attr basic_expr { $$ = new AstNode(AST_GE, $1, $4); + SET_AST_NODE_LOC($$, @1, @4); append_attr($$, $3); } | basic_expr '>' attr basic_expr { $$ = new AstNode(AST_GT, $1, $4); + SET_AST_NODE_LOC($$, @1, @4); append_attr($$, $3); } | basic_expr '+' attr basic_expr { $$ = new AstNode(AST_ADD, $1, $4); + SET_AST_NODE_LOC($$, @1, @4); append_attr($$, $3); } | basic_expr '-' attr basic_expr { $$ = new AstNode(AST_SUB, $1, $4); + SET_AST_NODE_LOC($$, @1, @4); append_attr($$, $3); } | basic_expr '*' attr basic_expr { $$ = new AstNode(AST_MUL, $1, $4); + SET_AST_NODE_LOC($$, @1, @4); append_attr($$, $3); } | basic_expr '/' attr basic_expr { $$ = new AstNode(AST_DIV, $1, $4); + SET_AST_NODE_LOC($$, @1, @4); append_attr($$, $3); } | basic_expr '%' attr basic_expr { $$ = new AstNode(AST_MOD, $1, $4); + SET_AST_NODE_LOC($$, @1, @4); append_attr($$, $3); } | basic_expr OP_POW attr basic_expr { $$ = new AstNode(AST_POW, $1, $4); + SET_AST_NODE_LOC($$, @1, @4); append_attr($$, $3); } | '+' attr basic_expr %prec UNARY_OPS { $$ = new AstNode(AST_POS, $3); + SET_AST_NODE_LOC($$, @1, @3); append_attr($$, $2); } | '-' attr basic_expr %prec UNARY_OPS { $$ = new AstNode(AST_NEG, $3); + SET_AST_NODE_LOC($$, @1, @3); append_attr($$, $2); } | basic_expr OP_LAND attr basic_expr { $$ = new AstNode(AST_LOGIC_AND, $1, $4); + SET_AST_NODE_LOC($$, @1, @4); append_attr($$, $3); } | basic_expr OP_LOR attr basic_expr { $$ = new AstNode(AST_LOGIC_OR, $1, $4); + SET_AST_NODE_LOC($$, @1, @4); append_attr($$, $3); } | '!' attr basic_expr %prec UNARY_OPS { $$ = new AstNode(AST_LOGIC_NOT, $3); + SET_AST_NODE_LOC($$, @1, @3); append_attr($$, $2); }; diff --git a/kernel/driver.cc b/kernel/driver.cc index 398c89e03..5f0959776 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -413,22 +413,13 @@ int main(int argc, char **argv) scriptfile_tcl = true; break; case 'W': - log_warn_regexes.push_back(std::regex(optarg, - std::regex_constants::nosubs | - std::regex_constants::optimize | - std::regex_constants::egrep)); + log_warn_regexes.push_back(YS_REGEX_COMPILE(optarg)); break; case 'w': - log_nowarn_regexes.push_back(std::regex(optarg, - std::regex_constants::nosubs | - std::regex_constants::optimize | - std::regex_constants::egrep)); + log_nowarn_regexes.push_back(YS_REGEX_COMPILE(optarg)); break; case 'e': - log_werror_regexes.push_back(std::regex(optarg, - std::regex_constants::nosubs | - std::regex_constants::optimize | - std::regex_constants::egrep)); + log_werror_regexes.push_back(YS_REGEX_COMPILE(optarg)); break; case 'D': vlog_defines.push_back(optarg); diff --git a/kernel/log.cc b/kernel/log.cc index 72181ebe8..d84a4381e 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -41,8 +41,8 @@ YOSYS_NAMESPACE_BEGIN std::vector<FILE*> log_files; std::vector<std::ostream*> log_streams; std::map<std::string, std::set<std::string>> log_hdump; -std::vector<std::regex> log_warn_regexes, log_nowarn_regexes, log_werror_regexes; -std::vector<std::pair<std::regex,LogExpectedItem>> log_expect_log, log_expect_warning, log_expect_error; +std::vector<YS_REGEX_TYPE> log_warn_regexes, log_nowarn_regexes, log_werror_regexes; +std::vector<std::pair<YS_REGEX_TYPE,LogExpectedItem>> log_expect_log, log_expect_warning, log_expect_error; std::set<std::string> log_warnings, log_experimentals, log_experimentals_ignored; int log_warnings_count = 0; int log_warnings_count_noexpect = 0; @@ -177,11 +177,11 @@ void logv(const char *format, va_list ap) if (!linebuffer.empty() && linebuffer.back() == '\n') { for (auto &re : log_warn_regexes) - if (std::regex_search(linebuffer, re)) + if (YS_REGEX_NS::regex_search(linebuffer, re)) log_warning("Found log message matching -W regex:\n%s", str.c_str()); for (auto &item : log_expect_log) - if (std::regex_search(linebuffer, item.first)) + if (YS_REGEX_NS::regex_search(linebuffer, item.first)) item.second.current_count++; linebuffer.clear(); @@ -238,7 +238,7 @@ static void logv_warning_with_prefix(const char *prefix, bool suppressed = false; for (auto &re : log_nowarn_regexes) - if (std::regex_search(message, re)) + if (YS_REGEX_NS::regex_search(message, re)) suppressed = true; if (suppressed) @@ -251,12 +251,12 @@ static void logv_warning_with_prefix(const char *prefix, log_make_debug = 0; for (auto &re : log_werror_regexes) - if (std::regex_search(message, re)) + if (YS_REGEX_NS::regex_search(message, re)) log_error("%s", message.c_str()); bool warning_match = false; for (auto &item : log_expect_warning) - if (std::regex_search(message, item.first)) { + if (YS_REGEX_NS::regex_search(message, item.first)) { item.second.current_count++; warning_match = true; } @@ -349,7 +349,7 @@ static void logv_error_with_prefix(const char *prefix, log_error_atexit(); for (auto &item : log_expect_error) - if (std::regex_search(log_last_error, item.first)) + if (YS_REGEX_NS::regex_search(log_last_error, item.first)) item.second.current_count++; if (check_expected_logs) @@ -695,7 +695,6 @@ void log_check_expected() log_warn_regexes.clear(); log("Expected error pattern '%s' found !!!\n", item.second.pattern.c_str()); #ifdef EMSCRIPTEN - log_files = backup_log_files; throw 0; #elif defined(_MSC_VER) _exit(0); diff --git a/kernel/log.h b/kernel/log.h index 603938f4c..cd0e8185c 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -23,7 +23,25 @@ #define LOG_H #include <time.h> -#include <regex> + +// In GCC 4.8 std::regex is not working correctlty, in order to make features +// using regular expressions to work replacement regex library is used +#if defined(__GNUC__) && !defined( __clang__) && ( __GNUC__ == 4 && __GNUC_MINOR__ <= 8) + #include <boost/xpressive/xpressive.hpp> + #define YS_REGEX_TYPE boost::xpressive::sregex + #define YS_REGEX_NS boost::xpressive + #define YS_REGEX_COMPILE(param) boost::xpressive::sregex::compile(param, \ + boost::xpressive::regex_constants::nosubs | \ + boost::xpressive::regex_constants::optimize) +# else + #include <regex> + #define YS_REGEX_TYPE std::regex + #define YS_REGEX_NS std + #define YS_REGEX_COMPILE(param) std::regex(param, \ + std::regex_constants::nosubs | \ + std::regex_constants::optimize | \ + std::regex_constants::egrep) +#endif #ifndef _WIN32 # include <sys/time.h> @@ -49,7 +67,7 @@ struct log_cmd_error_exception { }; extern std::vector<FILE*> log_files; extern std::vector<std::ostream*> log_streams; extern std::map<std::string, std::set<std::string>> log_hdump; -extern std::vector<std::regex> log_warn_regexes, log_nowarn_regexes, log_werror_regexes; +extern std::vector<YS_REGEX_TYPE> log_warn_regexes, log_nowarn_regexes, log_werror_regexes; extern std::set<std::string> log_warnings, log_experimentals, log_experimentals_ignored; extern int log_warnings_count; extern int log_warnings_count_noexpect; @@ -151,7 +169,7 @@ struct LogExpectedItem std::string pattern; }; -extern std::vector<std::pair<std::regex,LogExpectedItem>> log_expect_log, log_expect_warning, log_expect_error; +extern std::vector<std::pair<YS_REGEX_TYPE,LogExpectedItem>> log_expect_log, log_expect_warning, log_expect_error; void log_check_expected(); const char *log_signal(const RTLIL::SigSpec &sig, bool autoint = true); diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 8190d8902..7694fc9b6 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -341,7 +341,11 @@ int run_command(const std::string &command, std::function<void(const std::string if (!process_line) return system(command.c_str()); +#ifdef EMSCRIPTEN + FILE *f = nullptr; +#else FILE *f = popen(command.c_str(), "r"); +#endif if (f == nullptr) return -1; diff --git a/passes/cmds/add.cc b/passes/cmds/add.cc index 62c253bed..7b76f3d4a 100644 --- a/passes/cmds/add.cc +++ b/passes/cmds/add.cc @@ -22,6 +22,42 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN +static bool is_formal_celltype(const std::string &celltype) +{ + if(celltype == "assert" || celltype == "assume" || celltype == "live" || celltype == "fair" || celltype == "cover") + return true; + else + return false; +} + +static void add_formal(RTLIL::Module *module, const std::string &celltype, const std::string &name, const std::string &enable_name) +{ + std::string escaped_name = RTLIL::escape_id(name); + std::string escaped_enable_name = (enable_name != "") ? RTLIL::escape_id(enable_name) : ""; + RTLIL::Wire *wire = module->wire(escaped_name); + log_assert(is_formal_celltype(celltype)); + + if (wire == nullptr) { + log_error("Could not find wire with name \"%s\".\n", name.c_str()); + } + else { + RTLIL::Cell *formal_cell = module->addCell(NEW_ID, "$" + celltype); + formal_cell->setPort(ID(A), wire); + if(enable_name == "") { + formal_cell->setPort(ID(EN), State::S1); + log("Added $%s cell for wire \"%s.%s\"\n", celltype.c_str(), module->name.str().c_str(), name.c_str()); + } + else { + RTLIL::Wire *enable_wire = module->wire(escaped_enable_name); + if(enable_wire == nullptr) + log_error("Could not find enable wire with name \"%s\".\n", enable_name.c_str()); + + formal_cell->setPort(ID(EN), enable_wire); + log("Added $%s cell for wire \"%s.%s\" enabled by wire \"%s.%s\".\n", celltype.c_str(), module->name.str().c_str(), name.c_str(), module->name.str().c_str(), enable_name.c_str()); + } + } +} + static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string name, int width, bool flag_input, bool flag_output, bool flag_global) { RTLIL::Wire *wire = nullptr; @@ -103,6 +139,12 @@ struct AddPass : public Pass { log("selected modules.\n"); log("\n"); log("\n"); + log(" add {-assert|-assume|-live|-fair|-cover} <name1> [-if <name2>]\n"); + log("\n"); + log("Add an $assert, $assume, etc. cell connected to a wire named name1, with its\n"); + log("enable signal optionally connected to a wire named name2 (default: 1'b1).\n"); + log("\n"); + log("\n"); log(" add -mod <name[s]>\n"); log("\n"); log("Add module[s] with the specified name[s].\n"); @@ -112,6 +154,7 @@ struct AddPass : public Pass { { std::string command; std::string arg_name; + std::string enable_name = ""; bool arg_flag_input = false; bool arg_flag_output = false; bool arg_flag_global = false; @@ -141,6 +184,17 @@ struct AddPass : public Pass { argidx++; break; } + if (arg.length() > 0 && arg[0] == '-' && is_formal_celltype(arg.substr(1))) { + if (argidx + 1 >= args.size()) + break; + command = arg.substr(1); + arg_name = args[++argidx]; + if (argidx + 2 < args.size() && args[argidx + 1] == "-if") { + enable_name = args[argidx + 2]; + argidx += 2; + } + continue; + } break; } @@ -160,7 +214,9 @@ struct AddPass : public Pass { if (module->get_bool_attribute("\\blackbox")) continue; - if (command == "wire") + if (is_formal_celltype(command)) + add_formal(module, command, arg_name, enable_name); + else if (command == "wire") add_wire(design, module, arg_name, arg_width, arg_flag_input, arg_flag_output, arg_flag_global); } } diff --git a/passes/cmds/logger.cc b/passes/cmds/logger.cc index bd1038a7e..9a27952d4 100644 --- a/passes/cmds/logger.cc +++ b/passes/cmds/logger.cc @@ -96,12 +96,9 @@ struct LoggerPass : public Pass { if (pattern.front() == '\"' && pattern.back() == '\"') pattern = pattern.substr(1, pattern.size() - 2); try { log("Added regex '%s' for warnings to warn list.\n", pattern.c_str()); - log_warn_regexes.push_back(std::regex(pattern, - std::regex_constants::nosubs | - std::regex_constants::optimize | - std::regex_constants::egrep)); + log_warn_regexes.push_back(YS_REGEX_COMPILE(pattern)); } - catch (const std::regex_error& e) { + catch (const YS_REGEX_NS::regex_error& e) { log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str()); } continue; @@ -111,12 +108,9 @@ struct LoggerPass : public Pass { if (pattern.front() == '\"' && pattern.back() == '\"') pattern = pattern.substr(1, pattern.size() - 2); try { log("Added regex '%s' for warnings to nowarn list.\n", pattern.c_str()); - log_nowarn_regexes.push_back(std::regex(pattern, - std::regex_constants::nosubs | - std::regex_constants::optimize | - std::regex_constants::egrep)); + log_nowarn_regexes.push_back(YS_REGEX_COMPILE(pattern)); } - catch (const std::regex_error& e) { + catch (const YS_REGEX_NS::regex_error& e) { log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str()); } continue; @@ -126,12 +120,9 @@ struct LoggerPass : public Pass { if (pattern.front() == '\"' && pattern.back() == '\"') pattern = pattern.substr(1, pattern.size() - 2); try { log("Added regex '%s' for warnings to werror list.\n", pattern.c_str()); - log_werror_regexes.push_back(std::regex(pattern, - std::regex_constants::nosubs | - std::regex_constants::optimize | - std::regex_constants::egrep)); + log_werror_regexes.push_back(YS_REGEX_COMPILE(pattern)); } - catch (const std::regex_error& e) { + catch (const YS_REGEX_NS::regex_error& e) { log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str()); } continue; @@ -168,22 +159,13 @@ struct LoggerPass : public Pass { log("Added regex '%s' for warnings to expected %s list.\n", pattern.c_str(), type.c_str()); try { if (type=="error") - log_expect_error.push_back(std::make_pair(std::regex(pattern, - std::regex_constants::nosubs | - std::regex_constants::optimize | - std::regex_constants::egrep), LogExpectedItem(pattern, count))); + log_expect_error.push_back(std::make_pair(YS_REGEX_COMPILE(pattern), LogExpectedItem(pattern, count))); else if (type=="warning") - log_expect_warning.push_back(std::make_pair(std::regex(pattern, - std::regex_constants::nosubs | - std::regex_constants::optimize | - std::regex_constants::egrep), LogExpectedItem(pattern, count))); + log_expect_warning.push_back(std::make_pair(YS_REGEX_COMPILE(pattern), LogExpectedItem(pattern, count))); else - log_expect_log.push_back(std::make_pair(std::regex(pattern, - std::regex_constants::nosubs | - std::regex_constants::optimize | - std::regex_constants::egrep), LogExpectedItem(pattern, count))); + log_expect_log.push_back(std::make_pair(YS_REGEX_COMPILE(pattern), LogExpectedItem(pattern, count))); } - catch (const std::regex_error& e) { + catch (const YS_REGEX_NS::regex_error& e) { log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str()); } continue; diff --git a/tests/various/logger_error.ys b/tests/various/logger_error.ys new file mode 100644 index 000000000..46fe7f506 --- /dev/null +++ b/tests/various/logger_error.ys @@ -0,0 +1,6 @@ +logger -werror "is implicitly declared." -expect error "is implicitly declared." 1 +read_verilog << EOF +module top(...); + assign b = w; +endmodule +EOF diff --git a/tests/various/logger_nowarning.ys b/tests/various/logger_nowarning.ys new file mode 100644 index 000000000..87cbbc644 --- /dev/null +++ b/tests/various/logger_nowarning.ys @@ -0,0 +1,6 @@ +logger -expect-no-warnings -nowarn "is implicitly declared." +read_verilog << EOF +module top(...); + assign b = w; +endmodule +EOF diff --git a/tests/various/logger_warn.ys b/tests/various/logger_warn.ys new file mode 100644 index 000000000..2316ae4c6 --- /dev/null +++ b/tests/various/logger_warn.ys @@ -0,0 +1,6 @@ +logger -warn "Successfully finished Verilog frontend." -expect warning "Successfully finished Verilog frontend." 1 +read_verilog << EOF +module top(...); + assign b = w; +endmodule +EOF diff --git a/tests/various/logger_warning.ys b/tests/various/logger_warning.ys new file mode 100644 index 000000000..642b1b97b --- /dev/null +++ b/tests/various/logger_warning.ys @@ -0,0 +1,6 @@ +logger -expect warning "is implicitly declared." 2 +read_verilog << EOF +module top(...); + assign b = w; +endmodule +EOF diff --git a/tests/various/src.ys b/tests/various/src.ys new file mode 100644 index 000000000..89d6700ca --- /dev/null +++ b/tests/various/src.ys @@ -0,0 +1,8 @@ +logger -expect warning "wire '\\o' is assigned in a block at <<EOT:2.11-2.17" 1 +logger -expect warning "wire '\\p' is assigned in a block at <<EOT:3.11-3.16" 1 +read_verilog <<EOT +module top(input i, output o, p); +always @* o <= i; +always @* p = i; +endmodule +EOT |