aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile16
-rw-r--r--backends/firrtl/firrtl.cc1
-rw-r--r--frontends/rpc/Makefile.inc3
-rw-r--r--frontends/verilog/verilog_parser.y55
-rw-r--r--kernel/driver.cc15
-rw-r--r--kernel/log.cc17
-rw-r--r--kernel/log.h24
-rw-r--r--kernel/yosys.cc4
-rw-r--r--passes/cmds/add.cc58
-rw-r--r--passes/cmds/logger.cc38
-rw-r--r--tests/various/logger_error.ys6
-rw-r--r--tests/various/logger_nowarning.ys6
-rw-r--r--tests/various/logger_warn.ys6
-rw-r--r--tests/various/logger_warning.ys6
-rw-r--r--tests/various/src.ys8
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
diff --git a/Makefile b/Makefile
index 864be3c2e..49ab780d5 100644
--- a/Makefile
+++ b/Makefile
@@ -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