aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.editorconfig5
-rw-r--r--CHANGELOG4
-rw-r--r--Makefile4
-rw-r--r--backends/cxxrtl/cxxrtl.cc2
-rw-r--r--frontends/ast/ast.cc4
-rw-r--r--frontends/verific/verific.cc96
-rw-r--r--frontends/verific/verific.h2
-rw-r--r--kernel/constids.inc1
-rw-r--r--manual/CHAPTER_Auxprogs.tex5
-rw-r--r--passes/cmds/bugpoint.cc76
10 files changed, 134 insertions, 65 deletions
diff --git a/.editorconfig b/.editorconfig
index 4d6f5ef7a..f5444d81a 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -5,3 +5,8 @@ indent_style = tab
indent_size = tab
trim_trailing_whitespace = true
insert_final_newline = true
+
+[abc/**]
+indent_style = space
+indent_size = 2
+trim_trailing_whitespace = false
diff --git a/CHANGELOG b/CHANGELOG
index df8e14b26..3b36c3182 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -8,7 +8,7 @@ Yosys 0.9 .. Yosys 0.9-dev
* Various
- Added "write_xaiger" backend
- - Added "abc9" pass for timing-aware techmapping (experimental, FPGA only, no FFs)
+ - Added "abc9" pass for timing-aware techmapping (experimental, FPGA only)
- Added "synth_xilinx -abc9" (experimental)
- Added "synth_ice40 -abc9" (experimental)
- Added "synth -abc9" (experimental)
@@ -58,7 +58,6 @@ Yosys 0.9 .. Yosys 0.9-dev
- Added support for SystemVerilog wildcard port connections (.*)
- Added "xilinx_dffopt" pass
- Added "scratchpad" pass
- - Added "abc9 -dff"
- Added "synth_xilinx -dff"
- Improved support of $readmem[hb] Memory Content File inclusion
- Added "opt_lut_ins" pass
@@ -66,6 +65,7 @@ Yosys 0.9 .. Yosys 0.9-dev
- Removed "dffsr2dff" (use opt_rmdff instead)
- Added "design -delete"
- Added "select -unset"
+ - Use YosysHQ/abc instead of upstream berkeley-abc/abc
Yosys 0.8 .. Yosys 0.9
----------------------
diff --git a/Makefile b/Makefile
index c96e9eaa0..abab70cf7 100644
--- a/Makefile
+++ b/Makefile
@@ -133,9 +133,9 @@ 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 = ed90ce2
+ABCREV = d14acd8
ABCPULL = 1
-ABCURL ?= https://github.com/berkeley-abc/abc
+ABCURL ?= https://github.com/YosysHQ/abc
ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1
# set ABCEXTERNAL = <abc-command> to use an external ABC instance
diff --git a/backends/cxxrtl/cxxrtl.cc b/backends/cxxrtl/cxxrtl.cc
index e5351a387..e7711962f 100644
--- a/backends/cxxrtl/cxxrtl.cc
+++ b/backends/cxxrtl/cxxrtl.cc
@@ -732,7 +732,7 @@ struct CxxrtlWorker {
int chunk_width = min(width, CHUNK_SIZE);
uint32_t chunk = data.extract(offset, chunk_width).as_int();
if (fixed_width)
- f << stringf("0x%.*xu", chunk_width / 4, chunk);
+ f << stringf("0x%.*xu", (3 + chunk_width) / 4, chunk);
else
f << stringf("%#xu", chunk);
if (width > CHUNK_SIZE)
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc
index 733556621..6a9af3f57 100644
--- a/frontends/ast/ast.cc
+++ b/frontends/ast/ast.cc
@@ -946,6 +946,7 @@ RTLIL::Const AstNode::realAsConst(int width)
// create a new AstModule from an AST_MODULE AST node
static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast = NULL, bool quiet = false)
{
+ log_assert(current_scope.empty());
log_assert(ast->type == AST_MODULE || ast->type == AST_INTERFACE);
if (defer)
@@ -1117,6 +1118,7 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
}
ignoreThisSignalsInInitial = RTLIL::SigSpec();
+ current_scope.clear();
}
else {
for (auto &attr : ast->attributes) {
@@ -1229,11 +1231,13 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump
// process enum/other declarations
(*it)->simplify(true, false, false, 1, -1, false, false);
design->verilog_packages.push_back((*it)->clone());
+ current_scope.clear();
}
else {
// must be global definition
(*it)->simplify(false, false, false, 1, -1, false, false); //process enum/other declarations
design->verilog_globals.push_back((*it)->clone());
+ current_scope.clear();
}
}
}
diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc
index 89606a5bd..fe4bda68e 100644
--- a/frontends/verific/verific.cc
+++ b/frontends/verific/verific.cc
@@ -149,7 +149,7 @@ RTLIL::IdString VerificImporter::new_verific_id(Verific::DesignObj *obj)
return s;
}
-void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &attributes, DesignObj *obj)
+void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &attributes, DesignObj *obj, Netlist *nl)
{
MapIter mi;
Att *attr;
@@ -163,6 +163,68 @@ void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &att
continue;
attributes[RTLIL::escape_id(attr->Key())] = RTLIL::Const(std::string(attr->Value()));
}
+
+ if (nl) {
+ auto type_range = nl->GetTypeRange(obj->Name());
+ if (!type_range)
+ return;
+ if (!type_range->IsTypeEnum())
+ return;
+ if (nl->IsFromVhdl() && strcmp(type_range->GetTypeName(), "STD_LOGIC") == 0)
+ return;
+ auto type_name = type_range->GetTypeName();
+ if (!type_name)
+ return;
+ attributes.emplace(ID::wiretype, RTLIL::escape_id(type_name));
+
+ MapIter mi;
+ const char *k, *v;
+ FOREACH_MAP_ITEM(type_range->GetEnumIdMap(), mi, &k, &v) {
+ if (nl->IsFromVerilog()) {
+ // Expect <decimal>'b<binary>
+ auto p = strchr(v, '\'');
+ if (p) {
+ if (*(p+1) != 'b')
+ p = nullptr;
+ else
+ for (auto q = p+2; *q != '\0'; q++)
+ if (*q != '0' && *q != '1') {
+ p = nullptr;
+ break;
+ }
+ }
+ if (p == nullptr)
+ log_error("Expected TypeRange value '%s' to be of form <decimal>'b<binary>.\n", v);
+ attributes.emplace(stringf("\\enum_value_%s", p+2), RTLIL::escape_id(k));
+ }
+ else if (nl->IsFromVhdl()) {
+ // Expect "<binary>"
+ auto p = v;
+ if (p) {
+ if (*p != '"')
+ p = nullptr;
+ else {
+ auto *q = p+1;
+ for (; *q != '"'; q++)
+ if (*q != '0' && *q != '1') {
+ p = nullptr;
+ break;
+ }
+ if (p && *(q+1) != '\0')
+ p = nullptr;
+ }
+ }
+ if (p == nullptr)
+ log_error("Expected TypeRange value '%s' to be of form \"<binary>\".\n", v);
+ auto l = strlen(p);
+ auto q = (char*)malloc(l+1-2);
+ strncpy(q, p+1, l-2);
+ q[l-2] = '\0';
+ attributes.emplace(stringf("\\enum_value_%s", q), RTLIL::escape_id(k));
+ free(q);
+ }
+ }
+ }
}
RTLIL::SigSpec VerificImporter::operatorInput(Instance *inst)
@@ -845,7 +907,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
log(" importing port %s.\n", port->Name());
RTLIL::Wire *wire = module->addWire(RTLIL::escape_id(port->Name()));
- import_attributes(wire->attributes, port);
+ import_attributes(wire->attributes, port, nl);
wire->port_id = nl->IndexOf(port) + 1;
@@ -872,7 +934,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
RTLIL::Wire *wire = module->addWire(RTLIL::escape_id(portbus->Name()), portbus->Size());
wire->start_offset = min(portbus->LeftIndex(), portbus->RightIndex());
- import_attributes(wire->attributes, portbus);
+ import_attributes(wire->attributes, portbus, nl);
if (portbus->GetDir() == DIR_INOUT || portbus->GetDir() == DIR_IN)
wire->port_input = true;
@@ -1021,7 +1083,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
log(" importing net %s as %s.\n", net->Name(), log_id(wire_name));
RTLIL::Wire *wire = module->addWire(wire_name);
- import_attributes(wire->attributes, net);
+ import_attributes(wire->attributes, net, nl);
net_map[net] = wire;
}
@@ -1046,7 +1108,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
RTLIL::Wire *wire = module->addWire(wire_name, netbus->Size());
wire->start_offset = min(netbus->LeftIndex(), netbus->RightIndex());
- import_attributes(wire->attributes, netbus);
+ import_attributes(wire->attributes, netbus, nl);
RTLIL::Const initval = Const(State::Sx, GetSize(wire));
bool initval_valid = false;
@@ -1153,30 +1215,6 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
for (auto net : anyseq_nets)
module->connect(net_map_at(net), module->Anyseq(new_verific_id(net)));
- char *id_name;
- TypeRange *type_range;
- FOREACH_MAP_ITEM(nl->GetTypeRangeTable(), mi, &id_name, &type_range)
- {
- if (!type_range)
- continue;
- if (!type_range->IsTypeEnum())
- continue;
- auto wire = module->wire(RTLIL::escape_id(id_name));
- if (!wire) {
- if (net->IsUserDeclared())
- log_warning("Unable to find imported net '%s'.\n", net->Name());
- continue;
- }
- wire->set_string_attribute(ID::wiretype, type_range->GetTypeName());
-
- MapIter mj;
- char *k, *v;
- FOREACH_MAP_ITEM(type_range->GetEnumIdMap(), mj, &k, &v) {
- IdString key = stringf("\\enum_value_%s", v);
- wire->set_string_attribute(key, k);
- }
- }
-
pool<Instance*, hash_ptr_ops> sva_asserts;
pool<Instance*, hash_ptr_ops> sva_assumes;
pool<Instance*, hash_ptr_ops> sva_covers;
diff --git a/frontends/verific/verific.h b/frontends/verific/verific.h
index 2ccfcd42c..f168a2588 100644
--- a/frontends/verific/verific.h
+++ b/frontends/verific/verific.h
@@ -79,7 +79,7 @@ struct VerificImporter
RTLIL::SigBit net_map_at(Verific::Net *net);
RTLIL::IdString new_verific_id(Verific::DesignObj *obj);
- void import_attributes(dict<RTLIL::IdString, RTLIL::Const> &attributes, Verific::DesignObj *obj);
+ void import_attributes(dict<RTLIL::IdString, RTLIL::Const> &attributes, Verific::DesignObj *obj, Verific::Netlist *nl = nullptr);
RTLIL::SigSpec operatorInput(Verific::Instance *inst);
RTLIL::SigSpec operatorInput1(Verific::Instance *inst);
diff --git a/kernel/constids.inc b/kernel/constids.inc
index c5f672d09..27b652e24 100644
--- a/kernel/constids.inc
+++ b/kernel/constids.inc
@@ -29,6 +29,7 @@ X(B)
X(BI)
X(blackbox)
X(B_SIGNED)
+X(bugpoint_keep)
X(B_WIDTH)
X(C)
X(cells_not_processed)
diff --git a/manual/CHAPTER_Auxprogs.tex b/manual/CHAPTER_Auxprogs.tex
index 724d37f0b..f09b18f76 100644
--- a/manual/CHAPTER_Auxprogs.tex
+++ b/manual/CHAPTER_Auxprogs.tex
@@ -19,7 +19,8 @@ for details.
\section{yosys-abc}
-This is a unmodified copy of ABC \citeweblink{ABC}. Not all versions of Yosys
-work with all versions of ABC. So Yosys comes with its own yosys-abc to avoid
+This is a fork of ABC \citeweblink{ABC} with a small set of custom modifications
+that have not yet been accepted upstream. Not all versions of Yosys work with
+all versions of ABC. So Yosys comes with its own yosys-abc to avoid
compatibility issues between the two.
diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc
index a75927393..00aac596f 100644
--- a/passes/cmds/bugpoint.cc
+++ b/passes/cmds/bugpoint.cc
@@ -30,23 +30,21 @@ struct BugpointPass : public Pass {
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
- log(" bugpoint [options]\n");
+ log(" bugpoint [options] -script <filename>\n");
log("\n");
- log("This command minimizes testcases that crash Yosys. It removes an arbitrary part\n");
- log("of the design and recursively invokes Yosys with a given script, repeating these\n");
- log("steps while it can find a smaller design that still causes a crash. Once this\n");
- log("command finishes, it replaces the current design with the smallest testcase it\n");
- log("was able to produce.\n");
+ log("This command minimizes the current design that is known to crash Yosys with the\n");
+ log("given script into a smaller testcase. It does this by removing an arbitrary part\n");
+ log("of the design and recursively invokes a new Yosys process with this modified design\n");
+ log("and the same script, repeating these steps while it can find a smaller design that\n");
+ log("still causes a crash. Once this command finishes, it replaces the current design\n");
+ log("with the smallest testcase it was able to produce.\n");
log("\n");
- log("It is possible to specify the kinds of design part that will be removed. If none\n");
- log("are specified, all parts of design will be removed.\n");
+ log(" -script <filename>\n");
+ log(" use this script to crash Yosys. required.\n");
log("\n");
log(" -yosys <filename>\n");
log(" use this Yosys binary. if not specified, `yosys` is used.\n");
log("\n");
- log(" -script <filename>\n");
- log(" use this script to crash Yosys. required.\n");
- log("\n");
log(" -grep <string>\n");
log(" only consider crashes that place this string in the log file.\n");
log("\n");
@@ -60,14 +58,21 @@ struct BugpointPass : public Pass {
log(" finishing. produces smaller and more useful testcases, but may fail to\n");
log(" produce any testcase at all if the crash is related to dangling wires.\n");
log("\n");
+ log("It is possible to constrain which parts of the design will be considered for\n");
+ log("removal. Unless one or more of the following options are specified, all parts\n");
+ log("will be considered.\n");
+ log("\n");
log(" -modules\n");
- log(" try to remove modules.\n");
+ log(" try to remove modules. modules with a (* bugpoint_keep *) attribute\n");
+ log(" will be skipped.\n");
log("\n");
log(" -ports\n");
- log(" try to remove module ports.\n");
+ log(" try to remove module ports. ports with a (* bugpoint_keep *) attribute\n");
+ log(" will be skipped (useful for clocks, resets, etc.)\n");
log("\n");
log(" -cells\n");
- log(" try to remove cells.\n");
+ log(" try to remove cells. cells with a (* bugpoint_keep *) attribute will\n");
+ log(" be skipped.\n");
log("\n");
log(" -connections\n");
log(" try to reconnect ports to 'x.\n");
@@ -139,9 +144,12 @@ struct BugpointPass : public Pass {
if (module->get_blackbox_attribute())
continue;
+ if (module->get_bool_attribute(ID::bugpoint_keep))
+ continue;
+
if (index++ == seed)
{
- log("Trying to remove module %s.\n", module->name.c_str());
+ log_header(design, "Trying to remove module %s.\n", log_id(module));
removed_module = module;
break;
}
@@ -160,18 +168,21 @@ struct BugpointPass : public Pass {
for (auto wire : mod->wires())
{
+ if (!wire->port_id)
+ continue;
+
if (!stage2 && wire->get_bool_attribute(ID($bugpoint)))
continue;
- if (wire->port_input || wire->port_output)
+ if (wire->get_bool_attribute(ID::bugpoint_keep))
+ continue;
+
+ if (index++ == seed)
{
- if (index++ == seed)
- {
- log("Trying to remove module port %s.\n", log_signal(wire));
- wire->port_input = wire->port_output = false;
- mod->fixup_ports();
- return design_copy;
- }
+ log_header(design, "Trying to remove module port %s.\n", log_id(wire));
+ wire->port_input = wire->port_output = false;
+ mod->fixup_ports();
+ return design_copy;
}
}
}
@@ -183,12 +194,16 @@ struct BugpointPass : public Pass {
if (mod->get_blackbox_attribute())
continue;
+
Cell *removed_cell = nullptr;
for (auto cell : mod->cells())
{
+ if (cell->get_bool_attribute(ID::bugpoint_keep))
+ continue;
+
if (index++ == seed)
{
- log("Trying to remove cell %s.%s.\n", mod->name.c_str(), cell->name.c_str());
+ log_header(design, "Trying to remove cell %s.%s.\n", log_id(mod), log_id(cell));
removed_cell = cell;
break;
}
@@ -219,7 +234,7 @@ struct BugpointPass : public Pass {
if (index++ == seed)
{
- log("Trying to remove cell port %s.%s.%s.\n", mod->name.c_str(), cell->name.c_str(), it.first.c_str());
+ log_header(design, "Trying to remove cell port %s.%s.%s.\n", log_id(mod), log_id(cell), log_id(it.first));
RTLIL::SigSpec port_x(State::Sx, port.size());
cell->unsetPort(it.first);
cell->setPort(it.first, port_x);
@@ -228,7 +243,7 @@ struct BugpointPass : public Pass {
if (!stage2 && (cell->input(it.first) || cell->output(it.first)) && index++ == seed)
{
- log("Trying to expose cell port %s.%s.%s as module port.\n", mod->name.c_str(), cell->name.c_str(), it.first.c_str());
+ log_header(design, "Trying to expose cell port %s.%s.%s as module port.\n", log_id(mod), log_id(cell), log_id(it.first));
RTLIL::Wire *wire = mod->addWire(NEW_ID, port.size());
wire->set_bool_attribute(ID($bugpoint));
wire->port_input = cell->input(it.first);
@@ -260,7 +275,7 @@ struct BugpointPass : public Pass {
{
if (index++ == seed)
{
- log("Trying to remove assign %s %s in %s.%s.\n", log_signal((*it).first), log_signal((*it).second), mod->name.c_str(), pr.first.c_str());
+ log_header(design, "Trying to remove assign %s %s in %s.%s.\n", log_signal(it->first), log_signal(it->second), log_id(mod), log_id(pr.first));
cs->actions.erase(it);
return design_copy;
}
@@ -286,7 +301,7 @@ struct BugpointPass : public Pass {
{
if (index++ == seed)
{
- log("Trying to remove sync %s update %s %s in %s.%s.\n", log_signal(sy->signal), log_signal((*it).first), log_signal((*it).second), mod->name.c_str(), pr.first.c_str());
+ log_header(design, "Trying to remove sync %s update %s %s in %s.%s.\n", log_signal(sy->signal), log_signal(it->first), log_signal(it->second), log_id(mod), log_id(pr.first));
sy->actions.erase(it);
return design_copy;
}
@@ -304,6 +319,9 @@ struct BugpointPass : public Pass {
bool fast = false, clean = false;
bool modules = false, ports = false, cells = false, connections = false, assigns = false, updates = false, has_part = false;
+ log_header(design, "Executing BUGPOINT pass (minimize testcases).\n");
+ log_push();
+
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
{
@@ -447,6 +465,8 @@ struct BugpointPass : public Pass {
design->add(module->clone());
delete crashing_design;
}
+
+ log_pop();
}
} BugpointPass;