diff options
-rw-r--r-- | frontends/liberty/liberty.cc | 2 | ||||
-rw-r--r-- | passes/hierarchy/hierarchy.cc | 30 | ||||
-rw-r--r-- | passes/opt/opt_expr.cc | 17 |
3 files changed, 41 insertions, 8 deletions
diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 877b1883e..c9b6a54b2 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -188,7 +188,7 @@ static RTLIL::SigSpec parse_func_expr(RTLIL::Module *module, const char *expr) } token_t next_token(0); - if (*expr == '(' || *expr == ')' || *expr == '\'' || *expr == '!' || *expr == '^' || *expr == '*' || *expr == '+' || *expr == '|') + if (*expr == '(' || *expr == ')' || *expr == '\'' || *expr == '!' || *expr == '^' || *expr == '*' || *expr == '+' || *expr == '|' || *expr == '&') next_token = token_t(*(expr++)); else next_token = token_t(0, parse_func_identifier(module, expr)); diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index ba960faf4..18dfa7184 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -138,7 +138,7 @@ void generate(RTLIL::Design *design, const std::vector<std::string> &celltypes, } } -bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check, std::vector<std::string> &libdirs) +bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check, bool flag_simcheck, std::vector<std::string> &libdirs) { bool did_something = false; std::map<RTLIL::Cell*, std::pair<int, int>> array_cells; @@ -190,7 +190,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check } } - if (flag_check && cell->type[0] != '$') + if ((flag_check || flag_simcheck) && cell->type[0] != '$') log_error("Module `%s' referenced in module `%s' in cell `%s' is not part of the design.\n", cell->type.c_str(), module->name.c_str(), cell->name.c_str()); continue; @@ -200,7 +200,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check log_error("File `%s' from libdir does not declare module `%s'.\n", filename.c_str(), cell->type.c_str()); did_something = true; } else - if (flag_check) + if (flag_check || flag_simcheck) { RTLIL::Module *mod = design->module(cell->type); for (auto &conn : cell->connections()) @@ -218,10 +218,14 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check log_id(cell->type), log_id(module), log_id(cell), log_id(param.first)); } - if (cell->parameters.size() == 0) + if (design->modules_.at(cell->type)->get_bool_attribute("\\blackbox")) { + if (flag_simcheck) + log_error("Module `%s' referenced in module `%s' in cell `%s' is a blackbox module.\n", + cell->type.c_str(), module->name.c_str(), cell->name.c_str()); continue; + } - if (design->modules_.at(cell->type)->get_bool_attribute("\\blackbox")) + if (cell->parameters.size() == 0) continue; RTLIL::Module *mod = design->modules_[cell->type]; @@ -354,6 +358,10 @@ struct HierarchyPass : public Pass { log(" also check the design hierarchy. this generates an error when\n"); log(" an unknown module is used as cell type.\n"); log("\n"); + log(" -simcheck\n"); + log(" like -check, but also thow an error if blackbox modules are\n"); + log(" instantiated, and throw an error if the design has no top module\n"); + log("\n"); log(" -purge_lib\n"); log(" by default the hierarchy command will not remove library (blackbox)\n"); log(" modules. use this option to also remove unused blackbox modules.\n"); @@ -410,6 +418,7 @@ struct HierarchyPass : public Pass { log_header(design, "Executing HIERARCHY pass (managing design hierarchy).\n"); bool flag_check = false; + bool flag_simcheck = false; bool purge_lib = false; RTLIL::Module *top_mod = NULL; std::vector<std::string> libdirs; @@ -425,7 +434,7 @@ struct HierarchyPass : public Pass { size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { - if (args[argidx] == "-generate" && !flag_check && !top_mod) { + if (args[argidx] == "-generate" && !flag_check && !flag_simcheck && !top_mod) { generate_mode = true; log("Entering generate mode.\n"); while (++argidx < args.size()) { @@ -468,6 +477,10 @@ struct HierarchyPass : public Pass { flag_check = true; continue; } + if (args[argidx] == "-simcheck") { + flag_simcheck = true; + continue; + } if (args[argidx] == "-purge_lib") { purge_lib = true; continue; @@ -534,6 +547,9 @@ struct HierarchyPass : public Pass { log("Automatically selected %s as design top module.\n", log_id(top_mod)); } + if (flag_simcheck && top_mod == nullptr) + log_error("Design has no top module.\n"); + bool did_something = true; while (did_something) { @@ -549,7 +565,7 @@ struct HierarchyPass : public Pass { } for (auto module : used_modules) { - if (expand_module(design, module, flag_check, libdirs)) + if (expand_module(design, module, flag_check, flag_simcheck, libdirs)) did_something = true; } } diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 45331aa0b..a54a5c6b8 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -718,6 +718,23 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } } + if (cell->type == "$_TBUF_" || cell->type == "$tribuf") { + RTLIL::SigSpec input = cell->getPort(cell->type == "$_TBUF_" ? "\\E" : "\\EN"); + RTLIL::SigSpec a = cell->getPort("\\A"); + assign_map.apply(input); + assign_map.apply(a); + if (input == State::S1) + ACTION_DO("\\Y", cell->getPort("\\A")); + if (input == State::S0 && !a.is_fully_undef()) { + cover("opt.opt_expr.action_" S__LINE__); + log("Replacing data input of %s cell `%s' in module `%s' with constant undef.\n", + cell->type.c_str(), cell->name.c_str(), module->name.c_str()); + cell->setPort("\\A", SigSpec(State::Sx, GetSize(a))); + did_something = true; + goto next_cell; + } + } + if (cell->type == "$eq" || cell->type == "$ne" || cell->type == "$eqx" || cell->type == "$nex") { RTLIL::SigSpec a = cell->getPort("\\A"); |