aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile10
-rw-r--r--backends/aiger/xaiger.cc18
-rw-r--r--frontends/rpc/Makefile.inc3
-rw-r--r--frontends/verilog/verilog_parser.y10
-rw-r--r--kernel/log.cc1
-rw-r--r--kernel/register.cc12
-rw-r--r--kernel/register.h1
-rw-r--r--kernel/yosys.cc4
-rw-r--r--passes/cmds/add.cc37
-rw-r--r--passes/techmap/abc.cc5
-rw-r--r--passes/techmap/abc9.cc14
-rw-r--r--passes/techmap/abc9_ops.cc23
-rw-r--r--passes/techmap/deminout.cc3
-rw-r--r--tests/simple/partsel.v4
-rw-r--r--tests/various/deminout_unused.ys14
16 files changed, 96 insertions, 64 deletions
diff --git a/.gitignore b/.gitignore
index 76f53cd06..0460c7c13 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,6 +21,7 @@ __pycache__
/yosys
/yosys.exe
/yosys.js
+/yosys.wasm
/yosys-abc
/yosys-abc.exe
/yosys-config
diff --git a/Makefile b/Makefile
index e9dfd9df0..a911e6103 100644
--- a/Makefile
+++ b/Makefile
@@ -128,7 +128,7 @@ bumpversion:
# is just a symlink to your actual ABC working directory, as 'make mrproper'
# will remove the 'abc' directory and you do not want to accidentally
# delete your work on ABC..
-ABCREV = 71f2b40
+ABCREV = ed90ce2
ABCPULL = 1
ABCURL ?= https://github.com/berkeley-abc/abc
ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1
@@ -237,7 +237,8 @@ ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DABC_MEMALIGN=8"
EMCCFLAGS := -Os -Wno-warn-absolute-paths
EMCCFLAGS += --memory-init-file 0 --embed-file share -s NO_EXIT_RUNTIME=1
EMCCFLAGS += -s EXPORTED_FUNCTIONS="['_main','_run','_prompt','_errmsg']"
-EMCCFLAGS += -s TOTAL_MEMORY=128*1024*1024
+EMCCFLAGS += -s TOTAL_MEMORY=134217728
+EMCCFLAGS += -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]'
# https://github.com/kripken/emscripten/blob/master/src/settings.js
CXXFLAGS += $(EMCCFLAGS)
LDFLAGS += $(EMCCFLAGS)
@@ -256,10 +257,10 @@ viz.js:
wget -O viz.js.part https://github.com/mdaines/viz.js/releases/download/0.0.3/viz.js
mv viz.js.part viz.js
-yosysjs-$(YOSYS_VER).zip: yosys.js viz.js misc/yosysjs/*
+yosysjs-$(YOSYS_VER).zip: yosys.js yosys.wasm viz.js misc/yosysjs/*
rm -rf yosysjs-$(YOSYS_VER) yosysjs-$(YOSYS_VER).zip
mkdir -p yosysjs-$(YOSYS_VER)
- cp viz.js misc/yosysjs/* yosys.js yosysjs-$(YOSYS_VER)/
+ cp viz.js misc/yosysjs/* yosys.js yosys.wasm yosysjs-$(YOSYS_VER)/
zip -r yosysjs-$(YOSYS_VER).zip yosysjs-$(YOSYS_VER)
yosys.html: misc/yosys.html
@@ -895,6 +896,7 @@ config-emcc: clean
echo 'ENABLE_ABC := 0' >> Makefile.conf
echo 'ENABLE_PLUGINS := 0' >> Makefile.conf
echo 'ENABLE_READLINE := 0' >> Makefile.conf
+ echo 'ENABLE_ZLIB := 0' >> Makefile.conf
config-mxe: clean
echo 'CONFIG := mxe' > Makefile.conf
diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc
index 402f41597..cde6d066a 100644
--- a/backends/aiger/xaiger.cc
+++ b/backends/aiger/xaiger.cc
@@ -174,11 +174,12 @@ struct XAigerWriter
undriven_bits.insert(bit);
unused_bits.insert(bit);
- bool keep = wire->get_bool_attribute(ID::keep);
- if (wire->port_input || keep)
+ bool scc = wire->attributes.count(ID(abc9_scc));
+ if (wire->port_input || scc)
input_bits.insert(bit);
- if (wire->port_output || keep) {
+ bool keep = wire->get_bool_attribute(ID::keep);
+ if (wire->port_output || keep || scc) {
if (bit != wirebit)
alias_map[wirebit] = bit;
output_bits.insert(wirebit);
@@ -223,8 +224,6 @@ struct XAigerWriter
alias_map[Q] = D;
auto r YS_ATTRIBUTE(unused) = ff_bits.insert(std::make_pair(D, cell));
log_assert(r.second);
- if (input_bits.erase(Q))
- log_assert(Q.wire->attributes.count(ID::keep));
continue;
}
@@ -378,11 +377,6 @@ struct XAigerWriter
alias_map[O] = b;
ci_bits.emplace_back(b);
undriven_bits.erase(O);
- // If PI and CI, then must be a (* keep *) wire
- if (input_bits.erase(O)) {
- log_assert(output_bits.count(O));
- log_assert(O.wire->get_bool_attribute(ID::keep));
- }
}
}
@@ -467,8 +461,8 @@ struct XAigerWriter
for (const auto &bit : output_bits) {
ordered_outputs[bit] = aig_o++;
int aig;
- // Unlike bit2aig() which checks aig_map first, for
- // inout/keep bits, since aig_map will point to
+ // Unlike bit2aig() which checks aig_map first for
+ // inout/scc bits, since aig_map will point to
// the PI, first attempt to find the NOT/AND driver
// before resorting to an aig_map lookup (which
// could be another PO)
diff --git a/frontends/rpc/Makefile.inc b/frontends/rpc/Makefile.inc
index 9af505098..7b270b6fe 100644
--- a/frontends/rpc/Makefile.inc
+++ b/frontends/rpc/Makefile.inc
@@ -1,2 +1,3 @@
-
+ifneq ($(CONFIG),emcc)
OBJS += frontends/rpc/rpc_frontend.o
+endif
diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y
index be8b39e9f..91982e2a3 100644
--- a/frontends/verilog/verilog_parser.y
+++ b/frontends/verilog/verilog_parser.y
@@ -593,13 +593,15 @@ non_opt_range:
} |
'[' expr TOK_POS_INDEXED expr ']' {
$$ = new AstNode(AST_RANGE);
- $$->children.push_back(new AstNode(AST_SUB, new AstNode(AST_ADD, $2->clone(), $4), AstNode::mkconst_int(1, true)));
- $$->children.push_back(new AstNode(AST_ADD, $2, AstNode::mkconst_int(0, true)));
+ AstNode *expr = new AstNode(AST_CONCAT, $2);
+ $$->children.push_back(new AstNode(AST_SUB, new AstNode(AST_ADD, expr->clone(), $4), AstNode::mkconst_int(1, true)));
+ $$->children.push_back(new AstNode(AST_ADD, expr, AstNode::mkconst_int(0, true)));
} |
'[' expr TOK_NEG_INDEXED expr ']' {
$$ = new AstNode(AST_RANGE);
- $$->children.push_back(new AstNode(AST_ADD, $2, AstNode::mkconst_int(0, true)));
- $$->children.push_back(new AstNode(AST_SUB, new AstNode(AST_ADD, $2->clone(), AstNode::mkconst_int(1, true)), $4));
+ AstNode *expr = new AstNode(AST_CONCAT, $2);
+ $$->children.push_back(new AstNode(AST_ADD, expr, AstNode::mkconst_int(0, true)));
+ $$->children.push_back(new AstNode(AST_SUB, new AstNode(AST_ADD, expr->clone(), AstNode::mkconst_int(1, true)), $4));
} |
'[' expr ']' {
$$ = new AstNode(AST_RANGE);
diff --git a/kernel/log.cc b/kernel/log.cc
index 72181ebe8..2f8ce9e8c 100644
--- a/kernel/log.cc
+++ b/kernel/log.cc
@@ -695,7 +695,6 @@ void log_check_expected()
log_warn_regexes.clear();
log("Expected error pattern '%s' found !!!\n", item.second.pattern.c_str());
#ifdef EMSCRIPTEN
- log_files = backup_log_files;
throw 0;
#elif defined(_MSC_VER)
_exit(0);
diff --git a/kernel/register.cc b/kernel/register.cc
index e59d59654..af8c1b8e8 100644
--- a/kernel/register.cc
+++ b/kernel/register.cc
@@ -400,6 +400,18 @@ void ScriptPass::run(std::string command, std::string info)
}
}
+void ScriptPass::run_nocheck(std::string command, std::string info)
+{
+ if (active_design == nullptr) {
+ if (info.empty())
+ log(" %s\n", command.c_str());
+ else
+ log(" %s %s\n", command.c_str(), info.c_str());
+ } else {
+ Pass::call(active_design, command);
+ }
+}
+
void ScriptPass::run_script(RTLIL::Design *design, std::string run_from, std::string run_to)
{
help_mode = false;
diff --git a/kernel/register.h b/kernel/register.h
index 4622845b6..3d89386b7 100644
--- a/kernel/register.h
+++ b/kernel/register.h
@@ -84,6 +84,7 @@ struct ScriptPass : Pass
bool check_label(std::string label, std::string info = std::string());
void run(std::string command, std::string info = std::string());
+ void run_nocheck(std::string command, std::string info = std::string());
void run_script(RTLIL::Design *design, std::string run_from = std::string(), std::string run_to = std::string());
void help_script();
};
diff --git a/kernel/yosys.cc b/kernel/yosys.cc
index 8190d8902..7694fc9b6 100644
--- a/kernel/yosys.cc
+++ b/kernel/yosys.cc
@@ -341,7 +341,11 @@ int run_command(const std::string &command, std::function<void(const std::string
if (!process_line)
return system(command.c_str());
+#ifdef EMSCRIPTEN
+ FILE *f = nullptr;
+#else
FILE *f = popen(command.c_str(), "r");
+#endif
if (f == nullptr)
return -1;
diff --git a/passes/cmds/add.cc b/passes/cmds/add.cc
index 459b29f35..7b76f3d4a 100644
--- a/passes/cmds/add.cc
+++ b/passes/cmds/add.cc
@@ -60,24 +60,23 @@ static void add_formal(RTLIL::Module *module, const std::string &celltype, const
static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string name, int width, bool flag_input, bool flag_output, bool flag_global)
{
- RTLIL::Wire *wire = NULL;
+ RTLIL::Wire *wire = nullptr;
name = RTLIL::escape_id(name);
if (module->count_id(name) != 0)
{
- if (module->wires_.count(name) > 0)
- wire = module->wires_.at(name);
+ wire = module->wire(name);
- if (wire != NULL && wire->width != width)
- wire = NULL;
+ if (wire != nullptr && wire->width != width)
+ wire = nullptr;
- if (wire != NULL && wire->port_input != flag_input)
- wire = NULL;
+ if (wire != nullptr && wire->port_input != flag_input)
+ wire = nullptr;
- if (wire != NULL && wire->port_output != flag_output)
- wire = NULL;
+ if (wire != nullptr && wire->port_output != flag_output)
+ wire = nullptr;
- if (wire == NULL)
+ if (wire == nullptr)
log_cmd_error("Found incompatible object with same name in module %s!\n", module->name.c_str());
log("Module %s already has such an object.\n", module->name.c_str());
@@ -89,7 +88,6 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n
wire->port_output = flag_output;
if (flag_input || flag_output) {
- wire->port_id = module->wires_.size();
module->fixup_ports();
}
@@ -99,21 +97,20 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n
if (!flag_global)
return;
- for (auto &it : module->cells_)
+ for (auto cell : module->cells())
{
- if (design->modules_.count(it.second->type) == 0)
+ RTLIL::Module *mod = design->module(cell->type);
+ if (mod == nullptr)
continue;
-
- RTLIL::Module *mod = design->modules_.at(it.second->type);
if (!design->selected_whole_module(mod->name))
continue;
if (mod->get_blackbox_attribute())
continue;
- if (it.second->hasPort(name))
+ if (cell->hasPort(name))
continue;
- it.second->setPort(name, wire);
- log("Added connection %s to cell %s.%s (%s).\n", name.c_str(), module->name.c_str(), it.first.c_str(), it.second->type.c_str());
+ cell->setPort(name, wire);
+ log("Added connection %s to cell %s.%s (%s).\n", name.c_str(), module->name.c_str(), cell->name.c_str(), cell->type.c_str());
}
}
@@ -209,9 +206,9 @@ struct AddPass : public Pass {
extra_args(args, argidx, design);
- for (auto &mod : design->modules_)
+ for (auto module : design->modules())
{
- RTLIL::Module *module = mod.second;
+ log_assert(module != nullptr);
if (!design->selected_whole_module(module->name))
continue;
if (module->get_bool_attribute("\\blackbox"))
diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc
index 581652a41..e6c189c3e 100644
--- a/passes/techmap/abc.cc
+++ b/passes/techmap/abc.cc
@@ -1553,6 +1553,11 @@ struct AbcPass : public Pass {
show_tempdir = design->scratchpad_get_bool("abc.showtmp", show_tempdir);
markgroups = design->scratchpad_get_bool("abc.markgroups", markgroups);
+ if (design->scratchpad_get_bool("abc.debug")) {
+ cleanup = false;
+ show_tempdir = true;
+ }
+
size_t argidx, g_argidx;
bool g_arg_from_cmd = false;
char pwd [PATH_MAX];
diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc
index 5e650230d..212e0692d 100644
--- a/passes/techmap/abc9.cc
+++ b/passes/techmap/abc9.cc
@@ -332,9 +332,9 @@ struct Abc9Pass : public ScriptPass
tempdir_name = make_temp_dir(tempdir_name);
if (!lut_mode)
- run(stringf("abc9_ops -write_lut %s/input.lut", tempdir_name.c_str()));
- run(stringf("abc9_ops -write_box %s/input.box", tempdir_name.c_str()));
- run(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str()));
+ run_nocheck(stringf("abc9_ops -write_lut %s/input.lut", tempdir_name.c_str()));
+ run_nocheck(stringf("abc9_ops -write_box %s/input.box", tempdir_name.c_str()));
+ run_nocheck(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str()));
int num_outputs = active_design->scratchpad_get_int("write_xaiger.num_outputs");
@@ -350,9 +350,9 @@ struct Abc9Pass : public ScriptPass
if (!lut_mode)
abc9_exe_cmd += stringf(" -lut %s/input.lut", tempdir_name.c_str());
abc9_exe_cmd += stringf(" -box %s/input.box", tempdir_name.c_str());
- run(abc9_exe_cmd);
- run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod), tempdir_name.c_str(), tempdir_name.c_str()));
- run("abc9_ops -reintegrate");
+ run_nocheck(abc9_exe_cmd);
+ run_nocheck(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod), tempdir_name.c_str(), tempdir_name.c_str()));
+ run_nocheck("abc9_ops -reintegrate");
}
else
log("Don't call ABC as there is nothing to map.\n");
@@ -361,7 +361,7 @@ struct Abc9Pass : public ScriptPass
log("Removing temp directory.\n");
remove_directory(tempdir_name);
}
-
+ mod->check();
active_design->selection().selected_modules.clear();
log_pop();
}
diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc
index b0bd81698..e1baf4e3d 100644
--- a/passes/techmap/abc9_ops.cc
+++ b/passes/techmap/abc9_ops.cc
@@ -93,9 +93,10 @@ void check(RTLIL::Design *design)
void mark_scc(RTLIL::Module *module)
{
// For every unique SCC found, (arbitrarily) find the first
- // cell in the component, and convert all wires driven by
- // its output ports into a new PO, and drive its previous
- // sinks with a new PI
+ // cell in the component, and replace its output connections
+ // with a new wire driven by the old connection but with a
+ // special (* abc9_scc *) attribute set (which is used by
+ // write_xaiger to break this wire into PI and POs)
pool<RTLIL::Const> ids_seen;
for (auto cell : module->cells()) {
auto it = cell->attributes.find(ID(abc9_scc_id));
@@ -109,15 +110,13 @@ void mark_scc(RTLIL::Module *module)
for (auto &c : cell->connections_) {
if (c.second.is_fully_const()) continue;
if (cell->output(c.first)) {
- SigBit b = c.second.as_bit();
- Wire *w = b.wire;
- w->set_bool_attribute(ID::keep);
- w->attributes[ID(abc9_scc_id)] = id.as_int();
+ Wire *w = module->addWire(NEW_ID, GetSize(c.second));
+ w->set_bool_attribute(ID(abc9_scc));
+ module->connect(w, c.second);
+ c.second = w;
}
}
}
-
- module->fixup_ports();
}
void prep_dff(RTLIL::Module *module)
@@ -967,10 +966,8 @@ void reintegrate(RTLIL::Module *module)
RTLIL::Wire *mapped_wire = mapped_mod->wire(port);
RTLIL::Wire *wire = module->wire(port);
log_assert(wire);
- if (wire->attributes.erase(ID(abc9_scc_id))) {
- auto r YS_ATTRIBUTE(unused) = wire->attributes.erase(ID::keep);
- log_assert(r);
- }
+ wire->attributes.erase(ID(abc9_scc));
+
RTLIL::Wire *remap_wire = module->wire(remap_name(port));
RTLIL::SigSpec signal(wire, 0, GetSize(remap_wire));
log_assert(GetSize(signal) >= GetSize(remap_wire));
diff --git a/passes/techmap/deminout.cc b/passes/techmap/deminout.cc
index b976b401b..35d43b106 100644
--- a/passes/techmap/deminout.cc
+++ b/passes/techmap/deminout.cc
@@ -121,8 +121,7 @@ struct DeminoutPass : public Pass {
goto tribuf_bit;
} else {
tribuf_bit:
- if (bits_used.count(bit))
- new_input = true;
+ new_input = true;
}
}
diff --git a/tests/simple/partsel.v b/tests/simple/partsel.v
index 7461358ad..83493fcb0 100644
--- a/tests/simple/partsel.v
+++ b/tests/simple/partsel.v
@@ -60,3 +60,7 @@ always @(posedge clk) begin
end
endmodule
+
+module partsel_test003(input [2:0] a, b, input [31:0] din, output [3:0] dout);
+assign dout = din[a*b +: 2];
+endmodule
diff --git a/tests/various/deminout_unused.ys b/tests/various/deminout_unused.ys
new file mode 100644
index 000000000..5ed00509d
--- /dev/null
+++ b/tests/various/deminout_unused.ys
@@ -0,0 +1,14 @@
+read_verilog <<EOT
+module top(input clk, inout [7:0] x);
+
+reg [3:0] ctr;
+always @(posedge clk) ctr <= ctr + 1'b1;
+
+assign x[7:4] = ctr;
+endmodule
+EOT
+proc
+tribuf
+deminout
+select -assert-count 1 i:x o:x %i
+