diff options
-rw-r--r-- | .editorconfig | 5 | ||||
-rw-r--r-- | CHANGELOG | 4 | ||||
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | backends/cxxrtl/cxxrtl.cc | 2 | ||||
-rw-r--r-- | frontends/ast/ast.cc | 4 | ||||
-rw-r--r-- | frontends/verific/verific.cc | 96 | ||||
-rw-r--r-- | frontends/verific/verific.h | 2 | ||||
-rw-r--r-- | kernel/constids.inc | 1 | ||||
-rw-r--r-- | manual/CHAPTER_Auxprogs.tex | 5 | ||||
-rw-r--r-- | passes/cmds/bugpoint.cc | 76 |
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 @@ -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 ---------------------- @@ -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; |