aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--COPYING4
-rw-r--r--README.md2
-rw-r--r--backends/firrtl/firrtl.cc1
-rw-r--r--backends/smt2/smt2.cc18
-rw-r--r--backends/smt2/smtbmc.py14
-rw-r--r--backends/smt2/smtio.py12
-rw-r--r--examples/smtbmc/Makefile11
-rw-r--r--examples/smtbmc/demo9.v13
-rw-r--r--frontends/verilog/verilog_lexer.l31
-rw-r--r--frontends/verilog/verilog_parser.y88
-rw-r--r--kernel/driver.cc15
-rw-r--r--kernel/log.cc16
-rw-r--r--kernel/log.h24
-rw-r--r--kernel/yosys.cc2
-rw-r--r--passes/cmds/logger.cc38
-rw-r--r--techlibs/common/gate2lut.v2
-rw-r--r--techlibs/ice40/cells_sim.v13
-rw-r--r--tests/various/bug1745.ys8
-rw-r--r--tests/various/constcomment.ys16
-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
24 files changed, 270 insertions, 90 deletions
diff --git a/COPYING b/COPYING
index 0839088c3..7cd2464cd 100644
--- a/COPYING
+++ b/COPYING
@@ -1,4 +1,6 @@
-Copyright (C) 2012 - 2019 Clifford Wolf <clifford@clifford.at>
+ISC License
+
+Copyright (C) 2012 - 2020 Claire Wolf <claire@symbioticeda.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
diff --git a/README.md b/README.md
index 79801d23f..d1f7ddf8e 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
```
yosys -- Yosys Open SYnthesis Suite
-Copyright (C) 2012 - 2019 Clifford Wolf <clifford@clifford.at>
+Copyright (C) 2012 - 2020 Claire Wolf <claire@symbioticeda.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
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/backends/smt2/smt2.cc b/backends/smt2/smt2.cc
index 081dcda99..ea252b6b9 100644
--- a/backends/smt2/smt2.cc
+++ b/backends/smt2/smt2.cc
@@ -536,6 +536,14 @@ struct Smt2Worker
if (cell->attributes.count("\\reg"))
infostr += " " + cell->attributes.at("\\reg").decode_string();
decls.push_back(stringf("; yosys-smt2-%s %s#%d %d %s\n", cell->type.c_str() + 1, get_id(module), idcounter, GetSize(cell->getPort("\\Y")), infostr.c_str()));
+ if (cell->getPort("\\Y").is_wire() && cell->getPort("\\Y").as_wire()->get_bool_attribute("\\maximize")){
+ decls.push_back(stringf("; yosys-smt2-maximize %s#%d\n", get_id(module), idcounter));
+ log("Wire %s is maximized\n", cell->getPort("\\Y").as_wire()->name.str().c_str());
+ }
+ else if (cell->getPort("\\Y").is_wire() && cell->getPort("\\Y").as_wire()->get_bool_attribute("\\minimize")){
+ decls.push_back(stringf("; yosys-smt2-minimize %s#%d\n", get_id(module), idcounter));
+ log("Wire %s is minimized\n", cell->getPort("\\Y").as_wire()->name.str().c_str());
+ }
makebits(stringf("%s#%d", get_id(module), idcounter), GetSize(cell->getPort("\\Y")), log_signal(cell->getPort("\\Y")));
if (cell->type == "$anyseq")
ex_input_eq.push_back(stringf(" (= (|%s#%d| state) (|%s#%d| other_state))", get_id(module), idcounter, get_id(module), idcounter));
@@ -1500,11 +1508,11 @@ struct Smt2Backend : public Backend {
// extract module dependencies
std::map<RTLIL::Module*, std::set<RTLIL::Module*>> module_deps;
- for (auto &mod_it : design->modules_) {
- module_deps[mod_it.second] = std::set<RTLIL::Module*>();
- for (auto &cell_it : mod_it.second->cells_)
- if (design->modules_.count(cell_it.second->type) > 0)
- module_deps[mod_it.second].insert(design->modules_.at(cell_it.second->type));
+ for (auto mod : design->modules()) {
+ module_deps[mod] = std::set<RTLIL::Module*>();
+ for (auto cell : mod->cells())
+ if (design->has(cell->type))
+ module_deps[mod].insert(design->module(cell->type));
}
// simple good-enough topological sort
diff --git a/backends/smt2/smtbmc.py b/backends/smt2/smtbmc.py
index 3d6d3e1b3..630464419 100644
--- a/backends/smt2/smtbmc.py
+++ b/backends/smt2/smtbmc.py
@@ -1158,6 +1158,8 @@ def smt_forall_assert():
global asserts_cache_dirty
asserts_cache_dirty = False
+ assert (len(smt.modinfo[topmod].maximize) + len(smt.modinfo[topmod].minimize) <= 1)
+
def make_assert_expr(asserts_cache):
expr = list()
for lst in asserts_cache:
@@ -1236,6 +1238,18 @@ def smt_forall_assert():
smt.write("".join(assert_expr))
+ if len(smt.modinfo[topmod].maximize) > 0:
+ for s in states:
+ if s in used_states_db:
+ smt.write("(maximize (|%s| %s))\n" % (smt.modinfo[topmod].maximize.copy().pop(), s))
+ break
+
+ if len(smt.modinfo[topmod].minimize) > 0:
+ for s in states:
+ if s in used_states_db:
+ smt.write("(minimize (|%s| %s))\n" % (smt.modinfo[topmod].minimize.copy().pop(), s))
+ break
+
def smt_push():
global asserts_cache_dirty
asserts_cache_dirty = True
diff --git a/backends/smt2/smtio.py b/backends/smt2/smtio.py
index 34bf7ef38..4c691716e 100644
--- a/backends/smt2/smtio.py
+++ b/backends/smt2/smtio.py
@@ -101,6 +101,8 @@ class SmtModInfo:
self.cells = dict()
self.asserts = dict()
self.covers = dict()
+ self.maximize = set()
+ self.minimize = set()
self.anyconsts = dict()
self.anyseqs = dict()
self.allconsts = dict()
@@ -502,6 +504,12 @@ class SmtIo:
if fields[1] == "yosys-smt2-cover":
self.modinfo[self.curmod].covers["%s_c %s" % (self.curmod, fields[2])] = fields[3]
+ if fields[1] == "yosys-smt2-maximize":
+ self.modinfo[self.curmod].maximize.add(fields[2])
+
+ if fields[1] == "yosys-smt2-minimize":
+ self.modinfo[self.curmod].minimize.add(fields[2])
+
if fields[1] == "yosys-smt2-anyconst":
self.modinfo[self.curmod].anyconsts[fields[2]] = (fields[4], None if len(fields) <= 5 else fields[5])
self.modinfo[self.curmod].asize[fields[2]] = int(fields[3])
@@ -696,7 +704,9 @@ class SmtIo:
if msg is not None:
print("%s waiting for solver (%s)" % (self.timestamp(), msg), flush=True)
- result = self.read()
+ result = ""
+ while result not in ["sat", "unsat"]:
+ result = self.read()
if self.debug_file:
print("(set-info :status %s)" % result, file=self.debug_file)
diff --git a/examples/smtbmc/Makefile b/examples/smtbmc/Makefile
index 96fa058d6..61994f942 100644
--- a/examples/smtbmc/Makefile
+++ b/examples/smtbmc/Makefile
@@ -1,5 +1,5 @@
-all: demo1 demo2 demo3 demo4 demo5 demo6 demo7 demo8
+all: demo1 demo2 demo3 demo4 demo5 demo6 demo7 demo8 demo9
demo1: demo1.smt2
yosys-smtbmc --dump-vcd demo1.vcd demo1.smt2
@@ -28,6 +28,9 @@ demo7: demo7.smt2
demo8: demo8.smt2
yosys-smtbmc -s z3 -t 1 -g demo8.smt2
+demo9: demo9.smt2
+ yosys-smtbmc -s z3 -t 1 -g demo9.smt2
+
demo1.smt2: demo1.v
yosys -ql demo1.yslog -p 'read_verilog -formal demo1.v; prep -top demo1 -nordff; write_smt2 -wires demo1.smt2'
@@ -52,6 +55,9 @@ demo7.smt2: demo7.v
demo8.smt2: demo8.v
yosys -ql demo8.yslog -p 'read_verilog -formal demo8.v; prep -top demo8 -nordff; write_smt2 -stbv -wires demo8.smt2'
+demo9.smt2: demo9.v
+ yosys -ql demo9.yslog -p 'read_verilog -formal demo9.v; prep -top demo9 -nordff; write_smt2 -stbv -wires demo9.smt2'
+
clean:
rm -f demo1.yslog demo1.smt2 demo1.vcd
rm -f demo2.yslog demo2.smt2 demo2.vcd demo2.smtc demo2_tb.v demo2_tb demo2_tb.vcd
@@ -61,6 +67,7 @@ clean:
rm -f demo6.yslog demo6.smt2
rm -f demo7.yslog demo7.smt2
rm -f demo8.yslog demo8.smt2
+ rm -f demo9.yslog demo9.smt2
-.PHONY: demo1 demo2 demo3 demo4 demo5 demo6 demo7 demo8 clean
+.PHONY: demo1 demo2 demo3 demo4 demo5 demo6 demo7 demo8 demo9 clean
diff --git a/examples/smtbmc/demo9.v b/examples/smtbmc/demo9.v
new file mode 100644
index 000000000..f0b91e2ca
--- /dev/null
+++ b/examples/smtbmc/demo9.v
@@ -0,0 +1,13 @@
+module demo9;
+ (* maximize *) wire[7:0] h = $anyconst;
+ wire [7:0] i = $allconst;
+
+ wire [7:0] t0 = ((i << 8'b00000010) + 8'b00000011);
+ wire trigger = (t0 > h) && (h < 8'b00000100);
+
+ always @* begin
+ assume(trigger == 1'b1);
+ cover(1);
+ end
+endmodule
+
diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l
index 0a7c34ec0..d22a18458 100644
--- a/frontends/verilog/verilog_lexer.l
+++ b/frontends/verilog/verilog_lexer.l
@@ -113,8 +113,10 @@ extern int frontend_verilog_yylex(YYSTYPE *yylval_param, YYLTYPE *yyloc_param);
%x SYNOPSYS_TRANSLATE_OFF
%x SYNOPSYS_FLAGS
%x IMPORT_DPI
+%x BASED_CONST
%%
+ int comment_caller;
<INITIAL,SYNOPSYS_TRANSLATE_OFF>"`file_push "[^\n]* {
fn_stack.push_back(current_filename);
@@ -273,9 +275,21 @@ extern int frontend_verilog_yylex(YYSTYPE *yylval_param, YYLTYPE *yyloc_param);
return TOK_CONSTVAL;
}
-[0-9]*[ \t]*\'[sS]?[bodhBODH]?[ \t\r\n]*[0-9a-fA-FzxZX?_]+ {
+\'[01zxZX] {
yylval->string = new std::string(yytext);
- return TOK_CONSTVAL;
+ return TOK_UNBASED_UNSIZED_CONSTVAL;
+}
+
+\'[sS]?[bodhBODH] {
+ BEGIN(BASED_CONST);
+ yylval->string = new std::string(yytext);
+ return TOK_BASE;
+}
+
+<BASED_CONST>[0-9a-fA-FzxZX?][0-9a-fA-FzxZX?_]* {
+ BEGIN(0);
+ yylval->string = new std::string(yytext);
+ return TOK_BASED_CONSTVAL;
}
[0-9][0-9_]*\.[0-9][0-9_]*([eE][-+]?[0-9_]+)? {
@@ -478,16 +492,17 @@ import[ \t\r\n]+\"(DPI|DPI-C)\"[ \t\r\n]+function[ \t\r\n]+ {
return TOK_SPECIFY_AND;
}
-"/*" { BEGIN(COMMENT); }
+<INITIAL,BASED_CONST>"/*" { comment_caller=YY_START; BEGIN(COMMENT); }
<COMMENT>. /* ignore comment body */
<COMMENT>\n /* ignore comment body */
-<COMMENT>"*/" { BEGIN(0); }
+<COMMENT>"*/" { BEGIN(comment_caller); }
-[ \t\r\n] /* ignore whitespaces */
-\\[\r\n] /* ignore continuation sequence */
-"//"[^\r\n]* /* ignore one-line comments */
+<INITIAL,BASED_CONST>[ \t\r\n] /* ignore whitespaces */
+<INITIAL,BASED_CONST>\\[\r\n] /* ignore continuation sequence */
+<INITIAL,BASED_CONST>"//"[^\r\n]* /* ignore one-line comments */
-. { return *yytext; }
+<INITIAL>. { return *yytext; }
+<*>. { BEGIN(0); return *yytext; }
%%
diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y
index 91982e2a3..d04b32509 100644
--- a/frontends/verilog/verilog_parser.y
+++ b/frontends/verilog/verilog_parser.y
@@ -166,6 +166,7 @@ static void addRange(AstNode *parent, int msb = 31, int lsb = 0, bool isSigned =
%token <string> TOK_STRING TOK_ID TOK_CONSTVAL TOK_REALVAL TOK_PRIMITIVE
%token <string> TOK_SVA_LABEL TOK_SPECIFY_OPER TOK_MSG_TASKS
+%token <string> TOK_BASE TOK_BASED_CONSTVAL TOK_UNBASED_UNSIZED_CONSTVAL
%token TOK_ASSERT TOK_ASSUME TOK_RESTRICT TOK_COVER TOK_FINAL
%token ATTR_BEGIN ATTR_END DEFATTR_BEGIN DEFATTR_END
%token TOK_MODULE TOK_ENDMODULE TOK_PARAMETER TOK_LOCALPARAM TOK_DEFPARAM
@@ -188,7 +189,7 @@ static void addRange(AstNode *parent, int msb = 31, int lsb = 0, bool isSigned =
%type <ast> range range_or_multirange non_opt_range non_opt_multirange range_or_signed_int
%type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list
-%type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id hierarchical_type_id
+%type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id hierarchical_type_id integral_number
%type <ast> opt_enum_init
%type <boolean> opt_signed opt_property unique_case_attr always_comb_or_latch always_or_always_ff
%type <al> attr case_attr
@@ -2113,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
@@ -2182,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 ')' {
@@ -2335,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();
@@ -2346,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;
} |
@@ -2369,6 +2380,7 @@ rvalue:
hierarchical_id range {
$$ = new AstNode(AST_IDENTIFIER, $2);
$$->str = *$1;
+ SET_AST_NODE_LOC($$, @1, @1);
delete $1;
if ($2 == nullptr && ($$->str == "\\$initstate" ||
$$->str == "\\$anyconst" || $$->str == "\\$anyseq" ||
@@ -2378,6 +2390,7 @@ rvalue:
hierarchical_id non_opt_multirange {
$$ = new AstNode(AST_IDENTIFIER, $2);
$$->str = *$1;
+ SET_AST_NODE_LOC($$, @1, @1);
delete $1;
};
@@ -2496,6 +2509,7 @@ expr:
$$->children.push_back($1);
$$->children.push_back($4);
$$->children.push_back($6);
+ SET_AST_NODE_LOC($$, @1, @$);
append_attr($$, $3);
};
@@ -2503,7 +2517,7 @@ basic_expr:
rvalue {
$$ = $1;
} |
- '(' expr ')' TOK_CONSTVAL {
+ '(' expr ')' integral_number {
if ($4->compare(0, 1, "'") != 0)
frontend_verilog_yyerror("Cast operation must be applied on sized constants e.g. (<expr>)<constval> , while %s is not a sized constant.", $4->c_str());
AstNode *bits = $2;
@@ -2513,11 +2527,12 @@ basic_expr:
$$ = new AstNode(AST_TO_BITS, bits, val);
delete $4;
} |
- hierarchical_id TOK_CONSTVAL {
+ hierarchical_id integral_number {
if ($2->compare(0, 1, "'") != 0)
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());
@@ -2525,14 +2540,7 @@ basic_expr:
delete $1;
delete $2;
} |
- TOK_CONSTVAL TOK_CONSTVAL {
- $$ = const2ast(*$1 + *$2, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode);
- if ($$ == NULL || (*$2)[0] != '\'')
- log_error("Value conversion failed: `%s%s'\n", $1->c_str(), $2->c_str());
- delete $1;
- delete $2;
- } |
- TOK_CONSTVAL {
+ integral_number {
$$ = const2ast(*$1, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode);
if ($$ == NULL)
log_error("Value conversion failed: `%s'\n", $1->c_str());
@@ -2545,6 +2553,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);
@@ -2558,6 +2567,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();
@@ -2587,148 +2597,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);
};
@@ -2740,3 +2787,18 @@ concat_list:
$$ = $3;
$$->children.push_back($1);
};
+
+integral_number:
+ TOK_CONSTVAL { $$ = $1; } |
+ TOK_UNBASED_UNSIZED_CONSTVAL { $$ = $1; } |
+ TOK_BASE TOK_BASED_CONSTVAL {
+ $1->append(*$2);
+ $$ = $1;
+ delete $2;
+ } |
+ TOK_CONSTVAL TOK_BASE TOK_BASED_CONSTVAL {
+ $1->append(*$2).append(*$3);
+ $$ = $1;
+ delete $2;
+ delete $3;
+ };
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 2f8ce9e8c..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)
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 7694fc9b6..4cb53f05d 100644
--- a/kernel/yosys.cc
+++ b/kernel/yosys.cc
@@ -129,7 +129,7 @@ void yosys_banner()
log(" | |\n");
log(" | yosys -- Yosys Open SYnthesis Suite |\n");
log(" | |\n");
- log(" | Copyright (C) 2012 - 2019 Clifford Wolf <clifford@clifford.at> |\n");
+ log(" | Copyright (C) 2012 - 2020 Claire Wolf <claire@symbioticeda.com> |\n");
log(" | |\n");
log(" | Permission to use, copy, modify, and/or distribute this software for any |\n");
log(" | purpose with or without fee is hereby granted, provided that the above |\n");
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/techlibs/common/gate2lut.v b/techlibs/common/gate2lut.v
index 99c123f4a..15cea3d8d 100644
--- a/techlibs/common/gate2lut.v
+++ b/techlibs/common/gate2lut.v
@@ -79,7 +79,7 @@ module _90_lut_mux (A, B, S, Y);
// A 1010 1010
// B 1100 1100
// S 1111 0000
- .LUT(8'b_1100_1010)
+ .LUT(8'b 1100_1010)
) lut (
.A(AA),
.Y(Y)
diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v
index 17fe2ec99..aa1d7aa86 100644
--- a/techlibs/ice40/cells_sim.v
+++ b/techlibs/ice40/cells_sim.v
@@ -2350,16 +2350,19 @@ module SB_SPRAM256KA (
if (off) begin
DATAOUT <= 0;
end else
- if (CHIPSELECT && !STANDBY && !WREN) begin
- DATAOUT <= mem[ADDRESS];
- end else begin
- if (CHIPSELECT && !STANDBY && WREN) begin
+ if (STANDBY) begin
+ DATAOUT <= 'bx;
+ end else
+ if (CHIPSELECT) begin
+ if (!WREN) begin
+ DATAOUT <= mem[ADDRESS];
+ end else begin
if (MASKWREN[0]) mem[ADDRESS][ 3: 0] = DATAIN[ 3: 0];
if (MASKWREN[1]) mem[ADDRESS][ 7: 4] = DATAIN[ 7: 4];
if (MASKWREN[2]) mem[ADDRESS][11: 8] = DATAIN[11: 8];
if (MASKWREN[3]) mem[ADDRESS][15:12] = DATAIN[15:12];
+ DATAOUT <= 'bx;
end
- DATAOUT <= 'bx;
end
end
`endif
diff --git a/tests/various/bug1745.ys b/tests/various/bug1745.ys
new file mode 100644
index 000000000..2e5b8c2d4
--- /dev/null
+++ b/tests/various/bug1745.ys
@@ -0,0 +1,8 @@
+logger -expect error "syntax error, unexpected TOK_CONSTVAL" 1
+read_verilog <<EOT
+module inverter(input a, output y);
+
+ assign y = (a == 1'b0? 1'b1 : 1'b0);
+
+endmodule // inverter
+EOT
diff --git a/tests/various/constcomment.ys b/tests/various/constcomment.ys
new file mode 100644
index 000000000..f4f2e75d8
--- /dev/null
+++ b/tests/various/constcomment.ys
@@ -0,0 +1,16 @@
+read_verilog <<EOT
+module top1;
+ localparam a = 8 /*foo*/ 'h ab;
+ localparam b = 8 'h /*foo*/ cd;
+ generate
+ if (a != 8'b10101011) $error("a incorrect!");
+ if (b != 8'b11001101) $error("b incorrect!");
+ endgenerate
+endmodule
+EOT
+logger -expect error "syntax error, unexpected TOK_BASE" 1
+read_verilog <<EOT
+module top2;
+ localparam a = 12'h4 /*foo*/'b0;
+endmodule
+EOT
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