diff options
-rw-r--r-- | frontends/aiger/aigerparse.cc | 2 | ||||
-rw-r--r-- | frontends/ast/simplify.cc | 3 | ||||
-rw-r--r-- | frontends/verilog/Makefile.inc | 2 | ||||
-rw-r--r-- | frontends/verilog/verilog_parser.y | 37 | ||||
-rw-r--r-- | passes/cmds/Makefile.inc | 1 | ||||
-rw-r--r-- | passes/cmds/exec.cc | 203 | ||||
-rw-r--r-- | passes/fsm/fsm_extract.cc | 6 | ||||
-rw-r--r-- | passes/techmap/iopadmap.cc | 24 | ||||
-rw-r--r-- | techlibs/ice40/cells_sim.v | 4 | ||||
-rw-r--r-- | techlibs/ice40/synth_ice40.cc | 1 | ||||
-rw-r--r-- | techlibs/xilinx/cells_xtra.py | 2 | ||||
-rw-r--r-- | techlibs/xilinx/cells_xtra.v | 1 | ||||
-rw-r--r-- | tests/various/bug1781.ys | 33 | ||||
-rw-r--r-- | tests/various/exec.ys | 6 | ||||
-rw-r--r-- | tests/various/ice40_mince_abc9.ys | 17 |
15 files changed, 318 insertions, 24 deletions
diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index a42569301..50c2a3ce6 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -444,7 +444,7 @@ void AigerReader::parse_xaiger() } } else if (c == 'r') { - uint32_t dataSize = parse_xaiger_literal(f); + uint32_t dataSize YS_ATTRIBUTE(unused) = parse_xaiger_literal(f); flopNum = parse_xaiger_literal(f); log_debug("flopNum = %u\n", flopNum); log_assert(dataSize == (flopNum+1) * sizeof(uint32_t)); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 04c02d893..743c7e18f 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -432,7 +432,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, while (node->simplify(true, false, false, 1, -1, false, node->type == AST_PARAMETER || node->type == AST_LOCALPARAM)) did_something = true; if (node->type == AST_ENUM) { - for (auto enode : node->children){ + for (auto enode YS_ATTRIBUTE(unused) : node->children){ log_assert(enode->type==AST_ENUM_ITEM); while (node->simplify(true, false, false, 1, -1, false, in_param)) did_something = true; @@ -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/Makefile.inc b/frontends/verilog/Makefile.inc index 6a8462b41..cf9b9531e 100644 --- a/frontends/verilog/Makefile.inc +++ b/frontends/verilog/Makefile.inc @@ -10,7 +10,7 @@ frontends/verilog/verilog_parser.tab.cc: frontends/verilog/verilog_parser.y frontends/verilog/verilog_parser.tab.hh: frontends/verilog/verilog_parser.tab.cc -frontends/verilog/verilog_lexer.cc: frontends/verilog/verilog_lexer.l +frontends/verilog/verilog_lexer.cc: frontends/verilog/verilog_lexer.l frontends/verilog/verilog_parser.tab.cc $(Q) mkdir -p $(dir $@) $(P) flex -o frontends/verilog/verilog_lexer.cc $< diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index d04b32509..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; diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc index 20b38bf8e..60f20fa6d 100644 --- a/passes/cmds/Makefile.inc +++ b/passes/cmds/Makefile.inc @@ -1,4 +1,5 @@ +OBJS += passes/cmds/exec.o OBJS += passes/cmds/add.o OBJS += passes/cmds/delete.o OBJS += passes/cmds/design.o diff --git a/passes/cmds/exec.cc b/passes/cmds/exec.cc new file mode 100644 index 000000000..399cb0ebb --- /dev/null +++ b/passes/cmds/exec.cc @@ -0,0 +1,203 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/register.h" +#include "kernel/log.h" +#include <cstdio> + +#if defined(_WIN32) +# define WIFEXITED(x) 1 +# define WIFSIGNALED(x) 0 +# define WIFSTOPPED(x) 0 +# define WEXITSTATUS(x) ((x) & 0xff) +# define WTERMSIG(x) SIGTERM +#else +# include <sys/wait.h> +#endif + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct ExecPass : public Pass { + ExecPass() : Pass("exec", "execute commands in the operating system shell") { } + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" exec [options] -- [command]\n"); + log("\n"); + log("Execute a command in the operating system shell. All supplied arguments are\n"); + log("concatenated and passed as a command to popen(3). Whitespace is not guaranteed\n"); + log("to be preserved, even if quoted. stdin and stderr are not connected, while stdout is\n"); + log("logged unless the \"-q\" option is specified.\n"); + log("\n"); + log("\n"); + log(" -q\n"); + log(" Suppress stdout and stderr from subprocess\n"); + log("\n"); + log(" -expect-return <int>\n"); + log(" Generate an error if popen() does not return specified value.\n"); + log(" May only be specified once; the final specified value is controlling\n"); + log(" if specified multiple times.\n"); + log("\n"); + log(" -expect-stdout <regex>\n"); + log(" Generate an error if the specified regex does not match any line\n"); + log(" in subprocess's stdout. May be specified multiple times.\n"); + log("\n"); + log(" -not-expect-stdout <regex>\n"); + log(" Generate an error if the specified regex matches any line\n"); + log(" in subprocess's stdout. May be specified multiple times.\n"); + log("\n"); + log("\n"); + log(" Example: exec -q -expect-return 0 -- echo \"bananapie\" | grep \"nana\"\n"); + log("\n"); + log("\n"); + } + void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + { + std::string cmd = ""; + char buf[1024] = {}; + std::string linebuf = ""; + bool flag_cmd = false; + bool flag_quiet = false; + bool flag_expect_return = false; + int expect_return_value = 0; + bool flag_expect_stdout = false; + struct expect_stdout_elem { + bool matched; + bool polarity; //true: this regex must match at least one line + //false: this regex must not match any line + std::string str; + YS_REGEX_TYPE re; + + expect_stdout_elem() : matched(false), polarity(true), str(), re(){}; + }; + std::vector<expect_stdout_elem> expect_stdout; + + if(args.size() == 0) + log_cmd_error("No command provided.\n"); + + for(size_t argidx = 1; argidx < args.size(); ++argidx) { + if (flag_cmd) { + cmd += args[argidx] + (argidx != (args.size() - 1)? " " : ""); + } else { + if (args[argidx] == "--") + flag_cmd = true; + else if (args[argidx] == "-q") + flag_quiet = true; + else if (args[argidx] == "-expect-return") { + flag_expect_return = true; + ++argidx; + if (argidx >= args.size()) + log_cmd_error("No expected return value specified.\n"); + + expect_return_value = atoi(args[argidx].c_str()); + } else if (args[argidx] == "-expect-stdout") { + flag_expect_stdout = true; + ++argidx; + if (argidx >= args.size()) + log_cmd_error("No expected regular expression specified.\n"); + + try{ + expect_stdout_elem x; + x.str = args[argidx]; + x.re = YS_REGEX_COMPILE(args[argidx]); + expect_stdout.push_back(x); + } catch (const YS_REGEX_NS::regex_error& e) { + log_cmd_error("Error in regex expression '%s' !\n", args[argidx].c_str()); + } + } else if (args[argidx] == "-not-expect-stdout") { + flag_expect_stdout = true; + ++argidx; + if (argidx >= args.size()) + log_cmd_error("No expected regular expression specified.\n"); + + try{ + expect_stdout_elem x; + x.str = args[argidx]; + x.re = YS_REGEX_COMPILE(args[argidx]); + x.polarity = false; + expect_stdout.push_back(x); + } catch (const YS_REGEX_NS::regex_error& e) { + log_cmd_error("Error in regex expression '%s' !\n", args[argidx].c_str()); + } + + } else + log_cmd_error("Unknown option \"%s\" or \"--\" doesn\'t precede command.", args[argidx].c_str()); + } + } + + log_header(design, "Executing command \"%s\".\n", cmd.c_str()); + log_push(); + + fflush(stdout); + bool keep_reading = true; + int status = 0; + int retval = 0; + +#ifndef EMSCRIPTEN + FILE *f = popen(cmd.c_str(), "r"); + if (f == nullptr) + log_cmd_error("errno %d after popen() returned NULL.\n", errno); + while (keep_reading) { + keep_reading = (fgets(buf, sizeof(buf), f) != nullptr); + linebuf += buf; + memset(buf, 0, sizeof(buf)); + + auto pos = linebuf.find('\n'); + while (pos != std::string::npos) { + std::string line = linebuf.substr(0, pos); + linebuf.erase(0, pos + 1); + if (!flag_quiet) + log("%s\n", line.c_str()); + + if (flag_expect_stdout) + for(auto &x : expect_stdout) + if (YS_REGEX_NS::regex_search(line, x.re)) + x.matched = true; + + pos = linebuf.find('\n'); + } + } + status = pclose(f); +#endif + + if(WIFEXITED(status)) { + retval = WEXITSTATUS(status); + } + else if(WIFSIGNALED(status)) { + retval = WTERMSIG(status); + } + else if(WIFSTOPPED(status)) { + retval = WSTOPSIG(status); + } + + if (flag_expect_return && retval != expect_return_value) + log_cmd_error("Return value %d did not match expected return value %d.\n", retval, expect_return_value); + + if (flag_expect_stdout) + for (auto &x : expect_stdout) + if (x.polarity ^ x.matched) + log_cmd_error("Command stdout did%s have a line matching given regex \"%s\".\n", (x.polarity? " not" : ""), x.str.c_str()); + + log_pop(); + } +} ExecPass; + +PRIVATE_NAMESPACE_END diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index a85c3bec0..0f7b4d106 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -422,11 +422,7 @@ struct FsmExtractPass : public Pass { log_header(design, "Executing FSM_EXTRACT pass (extracting FSM from design).\n"); extra_args(args, 1, design); - CellTypes ct; - ct.setup_internals(); - ct.setup_internals_mem(); - ct.setup_stdcells(); - ct.setup_stdcells_mem(); + CellTypes ct(design); for (auto &mod_it : design->modules_) { diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index f63012d1a..8b1862237 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -308,7 +308,9 @@ struct IopadmapPass : public Pass { { log("Mapping port %s.%s[%d] using %s.\n", log_id(module), log_id(wire), i, tinoutpad_celltype.c_str()); - Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(tinoutpad_celltype)); + Cell *cell = module->addCell( + module->uniquify(stringf("$iopadmap$%s.%s[%d]", log_id(module), log_id(wire), i)), + RTLIL::escape_id(tinoutpad_celltype)); cell->setPort(RTLIL::escape_id(tinoutpad_portname_oe), en_sig); cell->attributes[ID::keep] = RTLIL::Const(1); @@ -328,7 +330,9 @@ struct IopadmapPass : public Pass { } else { log("Mapping port %s.%s[%d] using %s.\n", log_id(module), log_id(wire), i, toutpad_celltype.c_str()); - Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(toutpad_celltype)); + Cell *cell = module->addCell( + module->uniquify(stringf("$iopadmap$%s.%s[%d]", log_id(module), log_id(wire), i)), + RTLIL::escape_id(toutpad_celltype)); cell->setPort(RTLIL::escape_id(toutpad_portname_oe), en_sig); cell->setPort(RTLIL::escape_id(toutpad_portname_i), data_sig); @@ -406,7 +410,9 @@ struct IopadmapPass : public Pass { SigBit wire_bit(wire, i); - RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype)); + RTLIL::Cell *cell = module->addCell( + module->uniquify(stringf("$iopadmap$%s.%s", log_id(module->name), log_id(wire->name))), + RTLIL::escape_id(celltype)); cell->setPort(RTLIL::escape_id(portname_int), wire_bit); if (!portname_pad.empty()) @@ -420,12 +426,16 @@ struct IopadmapPass : public Pass { } else { - RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype)); + RTLIL::Cell *cell = module->addCell( + module->uniquify(stringf("$iopadmap$%s.%s", log_id(module->name), log_id(wire->name))), + RTLIL::escape_id(celltype)); cell->setPort(RTLIL::escape_id(portname_int), RTLIL::SigSpec(wire)); if (!portname_pad.empty()) { RTLIL::Wire *new_wire = NULL; - new_wire = module->addWire(NEW_ID, wire); + new_wire = module->addWire( + module->uniquify(stringf("$iopadmap$%s", log_id(wire))), + wire); module->swap_names(new_wire, wire); wire->attributes.clear(); cell->setPort(RTLIL::escape_id(portname_pad), RTLIL::SigSpec(new_wire)); @@ -446,7 +456,9 @@ struct IopadmapPass : public Pass { for (auto &it : rewrite_bits) { RTLIL::Wire *wire = it.first; - RTLIL::Wire *new_wire = module->addWire(NEW_ID, wire); + RTLIL::Wire *new_wire = module->addWire( + module->uniquify(stringf("$iopadmap$%s", log_id(wire))), + wire); module->swap_names(new_wire, wire); wire->attributes.clear(); for (int i = 0; i < wire->width; i++) diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index aa1d7aa86..6a0e3031e 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -2382,9 +2382,9 @@ module SB_SPRAM256KA ( // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13167 //$setup(negedge STANDBY, posedge CLOCK, 1715); // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13206 - $setup(WREN, posedge CLK, 289); + $setup(WREN, posedge CLOCK, 289); // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13207-L13222 - (posedge RCLK => (DATAOUT : 16'bx)) = 1821; + (posedge CLOCK => (DATAOUT : 16'bx)) = 1821; // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13223-L13238 (posedge SLEEP => (DATAOUT : 16'b0)) = 1099; endspecify diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index 80bd05a84..b8aedaadf 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -345,6 +345,7 @@ struct SynthIce40Pass : public ScriptPass if (min_ce_use >= 0) { run("opt_merge"); run(stringf("dff2dffe -unmap-mince %d", min_ce_use)); + run("simplemap t:$dff"); } run("techmap -D NO_LUT -D NO_ADDER -map +/ice40/cells_map.v"); run("opt_expr -mux_undef"); diff --git a/techlibs/xilinx/cells_xtra.py b/techlibs/xilinx/cells_xtra.py index 749b1e0a7..f086291ab 100644 --- a/techlibs/xilinx/cells_xtra.py +++ b/techlibs/xilinx/cells_xtra.py @@ -302,7 +302,7 @@ CELLS = [ Cell('IOBUF_DCIEN', port_attrs={'IO': ['iopad_external_pin']}), Cell('IOBUF_INTERMDISABLE', port_attrs={'IO': ['iopad_external_pin']}), Cell('IOBUFE3', port_attrs={'IO': ['iopad_external_pin']}), - Cell('IOBUFDS', port_attrs={'IO': ['iopad_external_pin']}), + Cell('IOBUFDS', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}), Cell('IOBUFDS_DCIEN', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}), Cell('IOBUFDS_INTERMDISABLE', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}), Cell('IOBUFDS_DIFF_OUT', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}), diff --git a/techlibs/xilinx/cells_xtra.v b/techlibs/xilinx/cells_xtra.v index ac4ad4e36..3021f6b5a 100644 --- a/techlibs/xilinx/cells_xtra.v +++ b/techlibs/xilinx/cells_xtra.v @@ -7072,6 +7072,7 @@ module IOBUFDS (...); output O; (* iopad_external_pin *) inout IO; + (* iopad_external_pin *) inout IOB; input I; input T; diff --git a/tests/various/bug1781.ys b/tests/various/bug1781.ys new file mode 100644 index 000000000..60dcc0830 --- /dev/null +++ b/tests/various/bug1781.ys @@ -0,0 +1,33 @@ +read_verilog <<EOT + +module top(input clk, input rst); + +reg [1:0] state; + +always @(posedge clk, posedge rst) begin + if (rst) + state <= 0; + else + case (state) + 2'b00: state <= 2'b01; + 2'b01: state <= 2'b10; + 2'b10: state <= 2'b00; + endcase +end + +sub sub_i(.i(state == 0)); + +endmodule + + +(* blackbox, keep *) +module sub(input i); +endmodule + +EOT + +proc +fsm + +# Make sure there is a driver +select -assert-any t:sub %ci %a w:* %i %ci c:* %i diff --git a/tests/various/exec.ys b/tests/various/exec.ys new file mode 100644 index 000000000..0eec00719 --- /dev/null +++ b/tests/various/exec.ys @@ -0,0 +1,6 @@ +exec -expect-return 0 -- exit 0 +exec -expect-return 27 -- exit 27 +exec -expect-stdout nana -expect-stdout api -not-expect-stdout giraffe -- echo "bananapie" + +logger -expect error "stdout did have a line" 1 +exec -not-expect-stdout giraffe -- echo "giraffe" diff --git a/tests/various/ice40_mince_abc9.ys b/tests/various/ice40_mince_abc9.ys new file mode 100644 index 000000000..408e16f05 --- /dev/null +++ b/tests/various/ice40_mince_abc9.ys @@ -0,0 +1,17 @@ +read_verilog <<EOT + +module top(input clk, ce, input [2:0] a, b, output reg [2:0] q); + + reg [2:0] aa, bb; + + always @(posedge clk) begin + if (ce) begin + aa <= a; + end + bb <= b; + q <= aa + bb; + end +endmodule +EOT + +synth_ice40 -abc9 -dffe_min_ce_use 4 |