aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--frontends/aiger/aigerparse.cc2
-rw-r--r--frontends/ast/simplify.cc3
-rw-r--r--frontends/verilog/Makefile.inc2
-rw-r--r--frontends/verilog/verilog_parser.y37
-rw-r--r--passes/cmds/Makefile.inc1
-rw-r--r--passes/cmds/exec.cc203
-rw-r--r--passes/fsm/fsm_extract.cc6
-rw-r--r--passes/techmap/iopadmap.cc24
-rw-r--r--techlibs/ice40/cells_sim.v4
-rw-r--r--techlibs/ice40/synth_ice40.cc1
-rw-r--r--techlibs/xilinx/cells_xtra.py2
-rw-r--r--techlibs/xilinx/cells_xtra.v1
-rw-r--r--tests/various/bug1781.ys33
-rw-r--r--tests/various/exec.ys6
-rw-r--r--tests/various/ice40_mince_abc9.ys17
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