diff options
-rw-r--r-- | Brewfile | 1 | ||||
-rw-r--r-- | COPYING | 4 | ||||
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | backends/smt2/smt2.cc | 18 | ||||
-rw-r--r-- | backends/smt2/smtbmc.py | 14 | ||||
-rw-r--r-- | backends/smt2/smtio.py | 12 | ||||
-rw-r--r-- | examples/smtbmc/Makefile | 11 | ||||
-rw-r--r-- | examples/smtbmc/demo9.v | 13 | ||||
-rw-r--r-- | frontends/ast/simplify.cc | 1 | ||||
-rw-r--r-- | frontends/verilog/verilog_parser.y | 39 | ||||
-rw-r--r-- | kernel/yosys.cc | 2 | ||||
-rw-r--r-- | passes/cmds/select.cc | 319 | ||||
-rw-r--r-- | techlibs/ice40/cells_sim.v | 13 | ||||
-rw-r--r-- | tests/arch/xilinx/tribuf.sh | 6 |
14 files changed, 267 insertions, 188 deletions
@@ -8,3 +8,4 @@ brew "pkg-config" brew "python3" brew "tcl-tk" brew "xdot" +brew "bash" @@ -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 @@ -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/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/ast/simplify.cc b/frontends/ast/simplify.cc index 04c02d893..2fbadcdad 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1811,6 +1811,7 @@ skip_dynamic_range_lvalue_expansion:; newNode->children.push_back(assign_en); AstNode *assertnode = new AstNode(type); + assertnode->location = location; assertnode->str = str; assertnode->children.push_back(new AstNode(AST_IDENTIFIER)); assertnode->children.push_back(new AstNode(AST_IDENTIFIER)); diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 1132e97ae..e32682f18 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -1955,6 +1955,7 @@ assert: delete $5; } else { AstNode *node = new AstNode(assume_asserts_mode ? AST_ASSUME : AST_ASSERT, $5); + SET_AST_NODE_LOC(node, @1, @6); if ($1 != nullptr) node->str = *$1; ast_stack.back()->children.push_back(node); @@ -1967,6 +1968,7 @@ assert: delete $5; } else { AstNode *node = new AstNode(assert_assumes_mode ? AST_ASSERT : AST_ASSUME, $5); + SET_AST_NODE_LOC(node, @1, @6); if ($1 != nullptr) node->str = *$1; ast_stack.back()->children.push_back(node); @@ -1979,6 +1981,7 @@ assert: delete $6; } else { AstNode *node = new AstNode(assume_asserts_mode ? AST_FAIR : AST_LIVE, $6); + SET_AST_NODE_LOC(node, @1, @7); if ($1 != nullptr) node->str = *$1; ast_stack.back()->children.push_back(node); @@ -1991,6 +1994,7 @@ assert: delete $6; } else { AstNode *node = new AstNode(assert_assumes_mode ? AST_LIVE : AST_FAIR, $6); + SET_AST_NODE_LOC(node, @1, @7); if ($1 != nullptr) node->str = *$1; ast_stack.back()->children.push_back(node); @@ -2000,6 +2004,7 @@ assert: } | opt_sva_label TOK_COVER opt_property '(' expr ')' ';' { AstNode *node = new AstNode(AST_COVER, $5); + SET_AST_NODE_LOC(node, @1, @6); if ($1 != nullptr) { node->str = *$1; delete $1; @@ -2008,6 +2013,7 @@ assert: } | opt_sva_label TOK_COVER opt_property '(' ')' ';' { AstNode *node = new AstNode(AST_COVER, AstNode::mkconst_int(1, false)); + SET_AST_NODE_LOC(node, @1, @5); if ($1 != nullptr) { node->str = *$1; delete $1; @@ -2016,6 +2022,7 @@ assert: } | opt_sva_label TOK_COVER ';' { AstNode *node = new AstNode(AST_COVER, AstNode::mkconst_int(1, false)); + SET_AST_NODE_LOC(node, @1, @2); if ($1 != nullptr) { node->str = *$1; delete $1; @@ -2027,6 +2034,7 @@ assert: delete $5; } else { AstNode *node = new AstNode(AST_ASSUME, $5); + SET_AST_NODE_LOC(node, @1, @6); if ($1 != nullptr) node->str = *$1; ast_stack.back()->children.push_back(node); @@ -2041,6 +2049,7 @@ assert: delete $6; } else { AstNode *node = new AstNode(AST_FAIR, $6); + SET_AST_NODE_LOC(node, @1, @7); if ($1 != nullptr) node->str = *$1; ast_stack.back()->children.push_back(node); @@ -2053,35 +2062,45 @@ assert: assert_property: opt_sva_label TOK_ASSERT TOK_PROPERTY '(' expr ')' ';' { - ast_stack.back()->children.push_back(new AstNode(assume_asserts_mode ? AST_ASSUME : AST_ASSERT, $5)); + AstNode *node = new AstNode(assume_asserts_mode ? AST_ASSUME : AST_ASSERT, $5); + SET_AST_NODE_LOC(node, @1, @6); + ast_stack.back()->children.push_back(node); if ($1 != nullptr) { ast_stack.back()->children.back()->str = *$1; delete $1; } } | opt_sva_label TOK_ASSUME TOK_PROPERTY '(' expr ')' ';' { - ast_stack.back()->children.push_back(new AstNode(AST_ASSUME, $5)); + AstNode *node = new AstNode(AST_ASSUME, $5); + SET_AST_NODE_LOC(node, @1, @6); + ast_stack.back()->children.push_back(node); if ($1 != nullptr) { ast_stack.back()->children.back()->str = *$1; delete $1; } } | opt_sva_label TOK_ASSERT TOK_PROPERTY '(' TOK_EVENTUALLY expr ')' ';' { - ast_stack.back()->children.push_back(new AstNode(assume_asserts_mode ? AST_FAIR : AST_LIVE, $6)); + AstNode *node = new AstNode(assume_asserts_mode ? AST_FAIR : AST_LIVE, $6); + SET_AST_NODE_LOC(node, @1, @7); + ast_stack.back()->children.push_back(node); if ($1 != nullptr) { ast_stack.back()->children.back()->str = *$1; delete $1; } } | opt_sva_label TOK_ASSUME TOK_PROPERTY '(' TOK_EVENTUALLY expr ')' ';' { - ast_stack.back()->children.push_back(new AstNode(AST_FAIR, $6)); + AstNode *node = new AstNode(AST_FAIR, $6); + SET_AST_NODE_LOC(node, @1, @7); + ast_stack.back()->children.push_back(node); if ($1 != nullptr) { ast_stack.back()->children.back()->str = *$1; delete $1; } } | opt_sva_label TOK_COVER TOK_PROPERTY '(' expr ')' ';' { - ast_stack.back()->children.push_back(new AstNode(AST_COVER, $5)); + AstNode *node = new AstNode(AST_COVER, $5); + SET_AST_NODE_LOC(node, @1, @6); + ast_stack.back()->children.push_back(node); if ($1 != nullptr) { ast_stack.back()->children.back()->str = *$1; delete $1; @@ -2091,7 +2110,9 @@ assert_property: if (norestrict_mode) { delete $5; } else { - ast_stack.back()->children.push_back(new AstNode(AST_ASSUME, $5)); + AstNode *node = new AstNode(AST_ASSUME, $5); + SET_AST_NODE_LOC(node, @1, @6); + ast_stack.back()->children.push_back(node); if ($1 != nullptr) { ast_stack.back()->children.back()->str = *$1; delete $1; @@ -2102,7 +2123,9 @@ assert_property: if (norestrict_mode) { delete $6; } else { - ast_stack.back()->children.push_back(new AstNode(AST_FAIR, $6)); + AstNode *node = new AstNode(AST_FAIR, $6); + SET_AST_NODE_LOC(node, @1, @7); + ast_stack.back()->children.push_back(node); if ($1 != nullptr) { ast_stack.back()->children.back()->str = *$1; delete $1; @@ -2380,6 +2403,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" || @@ -2389,6 +2413,7 @@ rvalue: hierarchical_id non_opt_multirange { $$ = new AstNode(AST_IDENTIFIER, $2); $$->str = *$1; + SET_AST_NODE_LOC($$, @1, @1); delete $1; }; 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/select.cc b/passes/cmds/select.cc index 0f1f05ccb..1657ef818 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -58,7 +58,7 @@ static bool match_attr_val(const RTLIL::Const &value, std::string pattern, char { RTLIL::SigSpec sig_value; - if (!RTLIL::SigSpec::parse(sig_value, NULL, pattern)) + if (!RTLIL::SigSpec::parse(sig_value, nullptr, pattern)) return false; RTLIL::Const pattern_value = sig_value.as_const(); @@ -152,27 +152,26 @@ static void select_op_neg(RTLIL::Design *design, RTLIL::Selection &lhs) RTLIL::Selection new_sel(false); - for (auto &mod_it : design->modules_) + for (auto mod : design->modules()) { - if (lhs.selected_whole_module(mod_it.first)) + if (lhs.selected_whole_module(mod->name)) continue; - if (!lhs.selected_module(mod_it.first)) { - new_sel.selected_modules.insert(mod_it.first); + if (!lhs.selected_module(mod->name)) { + new_sel.selected_modules.insert(mod->name); continue; } - RTLIL::Module *mod = mod_it.second; - for (auto &it : mod->wires_) - if (!lhs.selected_member(mod_it.first, it.first)) - new_sel.selected_members[mod->name].insert(it.first); + for (auto wire : mod->wires()) + if (!lhs.selected_member(mod->name, wire->name)) + new_sel.selected_members[mod->name].insert(wire->name); for (auto &it : mod->memories) - if (!lhs.selected_member(mod_it.first, it.first)) - new_sel.selected_members[mod->name].insert(it.first); - for (auto &it : mod->cells_) - if (!lhs.selected_member(mod_it.first, it.first)) + if (!lhs.selected_member(mod->name, it.first)) new_sel.selected_members[mod->name].insert(it.first); + for (auto cell : mod->cells()) + if (!lhs.selected_member(mod->name, cell->name)) + new_sel.selected_members[mod->name].insert(cell->name); for (auto &it : mod->processes) - if (!lhs.selected_member(mod_it.first, it.first)) + if (!lhs.selected_member(mod->name, it.first)) new_sel.selected_members[mod->name].insert(it.first); } @@ -223,15 +222,15 @@ static void select_op_random(RTLIL::Design *design, RTLIL::Selection &lhs, int c static void select_op_submod(RTLIL::Design *design, RTLIL::Selection &lhs) { - for (auto &mod_it : design->modules_) + for (auto mod : design->modules()) { - if (lhs.selected_whole_module(mod_it.first)) + if (lhs.selected_whole_module(mod->name)) { - for (auto &cell_it : mod_it.second->cells_) + for (auto cell : mod->cells()) { - if (design->modules_.count(cell_it.second->type) == 0) + if (design->module(cell->type) == nullptr) continue; - lhs.selected_modules.insert(cell_it.second->type); + lhs.selected_modules.insert(cell->type); } } } @@ -240,21 +239,21 @@ static void select_op_submod(RTLIL::Design *design, RTLIL::Selection &lhs) static void select_op_cells_to_modules(RTLIL::Design *design, RTLIL::Selection &lhs) { RTLIL::Selection new_sel(false); - for (auto &mod_it : design->modules_) - if (lhs.selected_module(mod_it.first)) - for (auto &cell_it : mod_it.second->cells_) - if (lhs.selected_member(mod_it.first, cell_it.first) && design->modules_.count(cell_it.second->type)) - new_sel.selected_modules.insert(cell_it.second->type); + for (auto mod : design->modules()) + if (lhs.selected_module(mod->name)) + for (auto cell : mod->cells()) + if (lhs.selected_member(mod->name, cell->name) && (design->module(cell->type) != nullptr)) + new_sel.selected_modules.insert(cell->type); lhs = new_sel; } static void select_op_module_to_cells(RTLIL::Design *design, RTLIL::Selection &lhs) { RTLIL::Selection new_sel(false); - for (auto &mod_it : design->modules_) - for (auto &cell_it : mod_it.second->cells_) - if (design->modules_.count(cell_it.second->type) && lhs.selected_whole_module(cell_it.second->type)) - new_sel.selected_members[mod_it.first].insert(cell_it.first); + for (auto mod : design->modules()) + for (auto cell : mod->cells()) + if ((design->module(cell->type) != nullptr) && lhs.selected_whole_module(cell->type)) + new_sel.selected_members[mod->name].insert(cell->name); lhs = new_sel; } @@ -268,23 +267,23 @@ static void select_op_fullmod(RTLIL::Design *design, RTLIL::Selection &lhs) static void select_op_alias(RTLIL::Design *design, RTLIL::Selection &lhs) { - for (auto &mod_it : design->modules_) + for (auto mod : design->modules()) { - if (lhs.selected_whole_module(mod_it.first)) + if (lhs.selected_whole_module(mod->name)) continue; - if (!lhs.selected_module(mod_it.first)) + if (!lhs.selected_module(mod->name)) continue; - SigMap sigmap(mod_it.second); + SigMap sigmap(mod); SigPool selected_bits; - for (auto &it : mod_it.second->wires_) - if (lhs.selected_member(mod_it.first, it.first)) - selected_bits.add(sigmap(it.second)); + for (auto wire : mod->wires()) + if (lhs.selected_member(mod->name, wire->name)) + selected_bits.add(sigmap(wire)); - for (auto &it : mod_it.second->wires_) - if (!lhs.selected_member(mod_it.first, it.first) && selected_bits.check_any(sigmap(it.second))) - lhs.selected_members[mod_it.first].insert(it.first); + for (auto wire : mod->wires()) + if (!lhs.selected_member(mod->name, wire->name) && selected_bits.check_any(sigmap(wire))) + lhs.selected_members[mod->name].insert(wire->name); } } @@ -323,8 +322,8 @@ static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const R if (!rhs.full_selection && rhs.selected_modules.size() == 0 && rhs.selected_members.size() == 0) return; lhs.full_selection = false; - for (auto &it : design->modules_) - lhs.selected_modules.insert(it.first); + for (auto mod : design->modules()) + lhs.selected_modules.insert(mod->name); } for (auto &it : rhs.selected_modules) { @@ -334,19 +333,19 @@ static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const R for (auto &it : rhs.selected_members) { - if (design->modules_.count(it.first) == 0) + if (design->module(it.first) == nullptr) continue; - RTLIL::Module *mod = design->modules_[it.first]; + RTLIL::Module *mod = design->module(it.first); if (lhs.selected_modules.count(mod->name) > 0) { - for (auto &it : mod->wires_) - lhs.selected_members[mod->name].insert(it.first); + for (auto wire : mod->wires()) + lhs.selected_members[mod->name].insert(wire->name); for (auto &it : mod->memories) lhs.selected_members[mod->name].insert(it.first); - for (auto &it : mod->cells_) - lhs.selected_members[mod->name].insert(it.first); + for (auto cell : mod->cells()) + lhs.selected_members[mod->name].insert(cell->name); for (auto &it : mod->processes) lhs.selected_members[mod->name].insert(it.first); lhs.selected_modules.erase(mod->name); @@ -367,8 +366,8 @@ static void select_op_intersect(RTLIL::Design *design, RTLIL::Selection &lhs, co if (lhs.full_selection) { lhs.full_selection = false; - for (auto &it : design->modules_) - lhs.selected_modules.insert(it.first); + for (auto mod : design->modules()) + lhs.selected_modules.insert(mod->name); } std::vector<RTLIL::IdString> del_list; @@ -431,18 +430,17 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v { int sel_objects = 0; bool is_input, is_output; - for (auto &mod_it : design->modules_) + for (auto mod : design->modules()) { - if (lhs.selected_whole_module(mod_it.first) || !lhs.selected_module(mod_it.first)) + if (lhs.selected_whole_module(mod->name) || !lhs.selected_module(mod->name)) continue; - RTLIL::Module *mod = mod_it.second; std::set<RTLIL::Wire*> selected_wires; auto selected_members = lhs.selected_members[mod->name]; - for (auto &it : mod->wires_) - if (lhs.selected_member(mod_it.first, it.first) && limits.count(it.first) == 0) - selected_wires.insert(it.second); + for (auto wire : mod->wires()) + if (lhs.selected_member(mod->name, wire->name) && limits.count(wire->name) == 0) + selected_wires.insert(wire); for (auto &conn : mod->connections()) { @@ -450,7 +448,7 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v std::vector<RTLIL::SigBit> conn_rhs = conn.second.to_sigbit_vector(); for (size_t i = 0; i < conn_lhs.size(); i++) { - if (conn_lhs[i].wire == NULL || conn_rhs[i].wire == NULL) + if (conn_lhs[i].wire == nullptr || conn_rhs[i].wire == nullptr) continue; if (mode != 'i' && selected_wires.count(conn_rhs[i].wire) && selected_members.count(conn_lhs[i].wire->name) == 0) lhs.selected_members[mod->name].insert(conn_lhs[i].wire->name), sel_objects++, max_objects--; @@ -459,15 +457,15 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v } } - for (auto &cell : mod->cells_) - for (auto &conn : cell.second->connections()) + for (auto cell : mod->cells()) + for (auto &conn : cell->connections()) { char last_mode = '-'; - if (eval_only && !yosys_celltypes.cell_evaluable(cell.second->type)) + if (eval_only && !yosys_celltypes.cell_evaluable(cell->type)) goto exclude_match; for (auto &rule : rules) { last_mode = rule.mode; - if (rule.cell_types.size() > 0 && rule.cell_types.count(cell.second->type) == 0) + if (rule.cell_types.size() > 0 && rule.cell_types.count(cell->type) == 0) continue; if (rule.port_names.size() > 0 && rule.port_names.count(conn.first) == 0) continue; @@ -479,14 +477,14 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v if (last_mode == '+') goto exclude_match; include_match: - is_input = mode == 'x' || ct.cell_input(cell.second->type, conn.first); - is_output = mode == 'x' || ct.cell_output(cell.second->type, conn.first); + is_input = mode == 'x' || ct.cell_input(cell->type, conn.first); + is_output = mode == 'x' || ct.cell_output(cell->type, conn.first); for (auto &chunk : conn.second.chunks()) - if (chunk.wire != NULL) { - if (max_objects != 0 && selected_wires.count(chunk.wire) > 0 && selected_members.count(cell.first) == 0) + if (chunk.wire != nullptr) { + if (max_objects != 0 && selected_wires.count(chunk.wire) > 0 && selected_members.count(cell->name) == 0) if (mode == 'x' || (mode == 'i' && is_output) || (mode == 'o' && is_input)) - lhs.selected_members[mod->name].insert(cell.first), sel_objects++, max_objects--; - if (max_objects != 0 && selected_members.count(cell.first) > 0 && limits.count(cell.first) == 0 && selected_members.count(chunk.wire->name) == 0) + lhs.selected_members[mod->name].insert(cell->name), sel_objects++, max_objects--; + if (max_objects != 0 && selected_members.count(cell->name) > 0 && limits.count(cell->name) == 0 && selected_members.count(chunk.wire->name) == 0) if (mode == 'x' || (mode == 'i' && is_input) || (mode == 'o' && is_output)) lhs.selected_members[mod->name].insert(chunk.wire->name), sel_objects++, max_objects--; } @@ -785,56 +783,55 @@ static void select_stmt(RTLIL::Design *design, std::string arg) } sel.full_selection = false; - for (auto &mod_it : design->modules_) + for (auto mod : design->modules()) { if (arg_mod.compare(0, 2, "A:") == 0) { - if (!match_attr(mod_it.second->attributes, arg_mod.substr(2))) + if (!match_attr(mod->attributes, arg_mod.substr(2))) continue; } else - if (!match_ids(mod_it.first, arg_mod)) + if (!match_ids(mod->name, arg_mod)) continue; if (arg_memb == "") { - sel.selected_modules.insert(mod_it.first); + sel.selected_modules.insert(mod->name); continue; } - RTLIL::Module *mod = mod_it.second; if (arg_memb.compare(0, 2, "w:") == 0) { - for (auto &it : mod->wires_) - if (match_ids(it.first, arg_memb.substr(2))) - sel.selected_members[mod->name].insert(it.first); + for (auto wire : mod->wires()) + if (match_ids(wire->name, arg_memb.substr(2))) + sel.selected_members[mod->name].insert(wire->name); } else if (arg_memb.compare(0, 2, "i:") == 0) { - for (auto &it : mod->wires_) - if (it.second->port_input && match_ids(it.first, arg_memb.substr(2))) - sel.selected_members[mod->name].insert(it.first); + for (auto wire : mod->wires()) + if (wire->port_input && match_ids(wire->name, arg_memb.substr(2))) + sel.selected_members[mod->name].insert(wire->name); } else if (arg_memb.compare(0, 2, "o:") == 0) { - for (auto &it : mod->wires_) - if (it.second->port_output && match_ids(it.first, arg_memb.substr(2))) - sel.selected_members[mod->name].insert(it.first); + for (auto wire : mod->wires()) + if (wire->port_output && match_ids(wire->name, arg_memb.substr(2))) + sel.selected_members[mod->name].insert(wire->name); } else if (arg_memb.compare(0, 2, "x:") == 0) { - for (auto &it : mod->wires_) - if ((it.second->port_input || it.second->port_output) && match_ids(it.first, arg_memb.substr(2))) - sel.selected_members[mod->name].insert(it.first); + for (auto wire : mod->wires()) + if ((wire->port_input || wire->port_output) && match_ids(wire->name, arg_memb.substr(2))) + sel.selected_members[mod->name].insert(wire->name); } else if (arg_memb.compare(0, 2, "s:") == 0) { size_t delim = arg_memb.substr(2).find(':'); if (delim == std::string::npos) { int width = atoi(arg_memb.substr(2).c_str()); - for (auto &it : mod->wires_) - if (it.second->width == width) - sel.selected_members[mod->name].insert(it.first); + for (auto wire : mod->wires()) + if (wire->width == width) + sel.selected_members[mod->name].insert(wire->name); } else { std::string min_str = arg_memb.substr(2, delim); std::string max_str = arg_memb.substr(2+delim+1); int min_width = min_str.empty() ? 0 : atoi(min_str.c_str()); int max_width = max_str.empty() ? -1 : atoi(max_str.c_str()); - for (auto &it : mod->wires_) - if (min_width <= it.second->width && (it.second->width <= max_width || max_width == -1)) - sel.selected_members[mod->name].insert(it.first); + for (auto wire : mod->wires()) + if (min_width <= wire->width && (wire->width <= max_width || max_width == -1)) + sel.selected_members[mod->name].insert(wire->name); } } else if (arg_memb.compare(0, 2, "m:") == 0) { @@ -843,14 +840,14 @@ static void select_stmt(RTLIL::Design *design, std::string arg) sel.selected_members[mod->name].insert(it.first); } else if (arg_memb.compare(0, 2, "c:") ==0) { - for (auto &it : mod->cells_) - if (match_ids(it.first, arg_memb.substr(2))) - sel.selected_members[mod->name].insert(it.first); + for (auto cell : mod->cells()) + if (match_ids(cell->name, arg_memb.substr(2))) + sel.selected_members[mod->name].insert(cell->name); } else if (arg_memb.compare(0, 2, "t:") == 0) { - for (auto &it : mod->cells_) - if (match_ids(it.second->type, arg_memb.substr(2))) - sel.selected_members[mod->name].insert(it.first); + for (auto cell : mod->cells()) + if (match_ids(cell->type, arg_memb.substr(2))) + sel.selected_members[mod->name].insert(cell->name); } else if (arg_memb.compare(0, 2, "p:") == 0) { for (auto &it : mod->processes) @@ -858,35 +855,35 @@ static void select_stmt(RTLIL::Design *design, std::string arg) sel.selected_members[mod->name].insert(it.first); } else if (arg_memb.compare(0, 2, "a:") == 0) { - for (auto &it : mod->wires_) - if (match_attr(it.second->attributes, arg_memb.substr(2))) - sel.selected_members[mod->name].insert(it.first); + for (auto wire : mod->wires()) + if (match_attr(wire->attributes, arg_memb.substr(2))) + sel.selected_members[mod->name].insert(wire->name); for (auto &it : mod->memories) if (match_attr(it.second->attributes, arg_memb.substr(2))) sel.selected_members[mod->name].insert(it.first); - for (auto &it : mod->cells_) - if (match_attr(it.second->attributes, arg_memb.substr(2))) - sel.selected_members[mod->name].insert(it.first); + for (auto cell : mod->cells()) + if (match_attr(cell->attributes, arg_memb.substr(2))) + sel.selected_members[mod->name].insert(cell->name); for (auto &it : mod->processes) if (match_attr(it.second->attributes, arg_memb.substr(2))) sel.selected_members[mod->name].insert(it.first); } else if (arg_memb.compare(0, 2, "r:") == 0) { - for (auto &it : mod->cells_) - if (match_attr(it.second->parameters, arg_memb.substr(2))) - sel.selected_members[mod->name].insert(it.first); + for (auto cell : mod->cells()) + if (match_attr(cell->parameters, arg_memb.substr(2))) + sel.selected_members[mod->name].insert(cell->name); } else { if (arg_memb.compare(0, 2, "n:") == 0) arg_memb = arg_memb.substr(2); - for (auto &it : mod->wires_) - if (match_ids(it.first, arg_memb)) - sel.selected_members[mod->name].insert(it.first); + for (auto wire : mod->wires()) + if (match_ids(wire->name, arg_memb)) + sel.selected_members[mod->name].insert(wire->name); for (auto &it : mod->memories) if (match_ids(it.first, arg_memb)) sel.selected_members[mod->name].insert(it.first); - for (auto &it : mod->cells_) - if (match_ids(it.first, arg_memb)) - sel.selected_members[mod->name].insert(it.first); + for (auto cell : mod->cells()) + if (match_ids(cell->name, arg_memb)) + sel.selected_members[mod->name].insert(cell->name); for (auto &it : mod->processes) if (match_ids(it.first, arg_memb)) sel.selected_members[mod->name].insert(it.first); @@ -899,21 +896,21 @@ static void select_stmt(RTLIL::Design *design, std::string arg) static std::string describe_selection_for_assert(RTLIL::Design *design, RTLIL::Selection *sel) { std::string desc = "Selection contains:\n"; - for (auto mod_it : design->modules_) + for (auto mod : design->modules()) { - if (sel->selected_module(mod_it.first)) { - for (auto &it : mod_it.second->wires_) - if (sel->selected_member(mod_it.first, it.first)) - desc += stringf("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first)); - for (auto &it : mod_it.second->memories) - if (sel->selected_member(mod_it.first, it.first)) - desc += stringf("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first)); - for (auto &it : mod_it.second->cells_) - if (sel->selected_member(mod_it.first, it.first)) - desc += stringf("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first)); - for (auto &it : mod_it.second->processes) - if (sel->selected_member(mod_it.first, it.first)) - desc += stringf("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first)); + if (sel->selected_module(mod->name)) { + for (auto wire : mod->wires()) + if (sel->selected_member(mod->name, wire->name)) + desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(wire->name)); + for (auto &it : mod->memories) + if (sel->selected_member(mod->name, it.first)) + desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(it.first)); + for (auto cell : mod->cells()) + if (sel->selected_member(mod->name, cell->name)) + desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(cell->name)); + for (auto &it : mod->processes) + if (sel->selected_member(mod->name, it.first)) + desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(it.first)); } } return desc; @@ -928,7 +925,7 @@ void handle_extra_select_args(Pass *pass, vector<string> args, size_t argidx, si work_stack.clear(); for (; argidx < args_size; argidx++) { if (args[argidx].compare(0, 1, "-") == 0) { - if (pass != NULL) + if (pass != nullptr) pass->cmd_error(args, argidx, "Unexpected option in selection arguments."); else log_cmd_error("Unexpected option in selection arguments."); @@ -1267,7 +1264,7 @@ struct SelectPass : public Pass { } if (arg == "-module" && argidx+1 < args.size()) { RTLIL::IdString mod_name = RTLIL::escape_id(args[++argidx]); - if (design->modules_.count(mod_name) == 0) + if (design->module(mod_name) == nullptr) log_cmd_error("No such module: %s\n", id2cstr(mod_name)); design->selected_active_module = mod_name.str(); got_module = true; @@ -1353,41 +1350,41 @@ struct SelectPass : public Pass { if (list_mode || count_mode || !write_file.empty()) { - #define LOG_OBJECT(...) { if (list_mode) log(__VA_ARGS__); if (f != NULL) fprintf(f, __VA_ARGS__); total_count++; } + #define LOG_OBJECT(...) { if (list_mode) log(__VA_ARGS__); if (f != nullptr) fprintf(f, __VA_ARGS__); total_count++; } int total_count = 0; - FILE *f = NULL; + FILE *f = nullptr; if (!write_file.empty()) { f = fopen(write_file.c_str(), "w"); yosys_output_files.insert(write_file); - if (f == NULL) + if (f == nullptr) log_error("Can't open '%s' for writing: %s\n", write_file.c_str(), strerror(errno)); } RTLIL::Selection *sel = &design->selection_stack.back(); if (work_stack.size() > 0) sel = &work_stack.back(); sel->optimize(design); - for (auto mod_it : design->modules_) + for (auto mod : design->modules()) { - if (sel->selected_whole_module(mod_it.first) && list_mode) - log("%s\n", id2cstr(mod_it.first)); - if (sel->selected_module(mod_it.first)) { - for (auto &it : mod_it.second->wires_) - if (sel->selected_member(mod_it.first, it.first)) - LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first)) - for (auto &it : mod_it.second->memories) - if (sel->selected_member(mod_it.first, it.first)) - LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first)) - for (auto &it : mod_it.second->cells_) - if (sel->selected_member(mod_it.first, it.first)) - LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first)) - for (auto &it : mod_it.second->processes) - if (sel->selected_member(mod_it.first, it.first)) - LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first)) + if (sel->selected_whole_module(mod->name) && list_mode) + log("%s\n", id2cstr(mod->name)); + if (sel->selected_module(mod->name)) { + for (auto wire : mod->wires()) + if (sel->selected_member(mod->name, wire->name)) + LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(wire->name)) + for (auto &it : mod->memories) + if (sel->selected_member(mod->name, it.first)) + LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(it.first)) + for (auto cell : mod->cells()) + if (sel->selected_member(mod->name, cell->name)) + LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(cell->name)) + for (auto &it : mod->processes) + if (sel->selected_member(mod->name, it.first)) + LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(it.first)) } } if (count_mode) log("%d objects.\n", total_count); - if (f != NULL) + if (f != nullptr) fclose(f); #undef LOG_OBJECT return; @@ -1448,19 +1445,19 @@ struct SelectPass : public Pass { log_cmd_error("No selection to check.\n"); RTLIL::Selection *sel = &work_stack.back(); sel->optimize(design); - for (auto mod_it : design->modules_) - if (sel->selected_module(mod_it.first)) { - for (auto &it : mod_it.second->wires_) - if (sel->selected_member(mod_it.first, it.first)) + for (auto mod : design->modules()) + if (sel->selected_module(mod->name)) { + for (auto wire : mod->wires()) + if (sel->selected_member(mod->name, wire->name)) total_count++; - for (auto &it : mod_it.second->memories) - if (sel->selected_member(mod_it.first, it.first)) + for (auto &it : mod->memories) + if (sel->selected_member(mod->name, it.first)) total_count++; - for (auto &it : mod_it.second->cells_) - if (sel->selected_member(mod_it.first, it.first)) + for (auto cell : mod->cells()) + if (sel->selected_member(mod->name, cell->name)) total_count++; - for (auto &it : mod_it.second->processes) - if (sel->selected_member(mod_it.first, it.first)) + for (auto &it : mod->processes) + if (sel->selected_member(mod->name, it.first)) total_count++; } if (assert_count >= 0 && assert_count != total_count) @@ -1581,15 +1578,13 @@ struct CdPass : public Pass { std::string modname = RTLIL::escape_id(args[1]); - if (design->modules_.count(modname) == 0 && !design->selected_active_module.empty()) { - RTLIL::Module *module = NULL; - if (design->modules_.count(design->selected_active_module) > 0) - module = design->modules_.at(design->selected_active_module); - if (module != NULL && module->cells_.count(modname) > 0) - modname = module->cells_.at(modname)->type.str(); + if (design->module(modname) == nullptr && !design->selected_active_module.empty()) { + RTLIL::Module *module = design->module(design->selected_active_module); + if (module != nullptr && module->cell(modname) != nullptr) + modname = module->cell(modname)->type.str(); } - if (design->modules_.count(modname) > 0) { + if (design->module(modname) != nullptr) { design->selected_active_module = modname; design->selection_stack.back() = RTLIL::Selection(); select_filter_active_mod(design, design->selection_stack.back()); 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/arch/xilinx/tribuf.sh b/tests/arch/xilinx/tribuf.sh index 636aed12a..bd44395cb 100644 --- a/tests/arch/xilinx/tribuf.sh +++ b/tests/arch/xilinx/tribuf.sh @@ -1,5 +1,5 @@ -! ../../../yosys ../common/tribuf.v -qp "synth_xilinx" -../../../yosys ../common/tribuf.v -qp "synth_xilinx -iopad; \ +! ../../../yosys -qp "synth_xilinx" ../common/tribuf.v +../../../yosys -qp "synth_xilinx -iopad; \ select -assert-count 2 t:IBUF; \ select -assert-count 1 t:INV; \ -select -assert-count 1 t:OBUFT" +select -assert-count 1 t:OBUFT" ../common/tribuf.v |