From 0c5b1f32d49540b8cbbfbd610e9dca82d75a7893 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 14 Jan 2014 19:28:20 +0100 Subject: [PATCH] Added hierarchy -libdir option --- passes/hierarchy/hierarchy.cc | 52 ++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index d46757029..f77ded9d2 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -133,22 +133,56 @@ static void generate(RTLIL::Design *design, const std::vector &cell } } -static bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check) +static bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check, std::vector &libdirs) { bool did_something = false; + std::string filename; - for (auto &cell_it : module->cells) { + for (auto &cell_it : module->cells) + { RTLIL::Cell *cell = cell_it.second; - if (design->modules.count(cell->type) == 0) { + + if (design->modules.count(cell->type) == 0) + { + if (cell->type[0] == '$') + continue; + + for (auto &dir : libdirs) + { + filename = dir + "/" + RTLIL::unescape_id(cell->type) + ".v"; + if (access(filename.c_str(), F_OK) == 0) { + std::vector args; + args.push_back(filename); + Frontend::frontend_call(design, NULL, filename, "verilog"); + goto loaded_module; + } + + filename = dir + "/" + RTLIL::unescape_id(cell->type) + ".il"; + if (access(filename.c_str(), F_OK) == 0) { + std::vector args; + args.push_back(filename); + Frontend::frontend_call(design, NULL, filename, "ilang"); + goto loaded_module; + } + } + if (flag_check && 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; + + loaded_module: + if (design->modules.count(cell->type) == 0) + log_error("File `%s' from libdir does not declare module `%s'.\n", filename.c_str(), cell->type.c_str()); + did_something = true; } + if (cell->parameters.size() == 0) continue; + if (design->modules.at(cell->type)->get_bool_attribute("\\blackbox")) continue; + RTLIL::Module *mod = design->modules[cell->type]; cell->type = mod->derive(design, cell->parameters); cell->parameters.clear(); @@ -212,6 +246,11 @@ 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(" -libdir \n"); + log(" search for files named .v in the specified directory\n"); + log(" for unkown modules and automatically run read_verilog for each\n"); + log(" unknown module.\n"); + log("\n"); log(" -keep_positionals\n"); log(" per default this pass also converts positional arguments in cells\n"); log(" to arguments using port names. this option disables this behavior.\n"); @@ -247,6 +286,7 @@ struct HierarchyPass : public Pass { bool flag_check = false; RTLIL::Module *top_mod = NULL; + std::vector libdirs; bool generate_mode = false; bool keep_positionals = false; @@ -303,6 +343,10 @@ struct HierarchyPass : public Pass { keep_positionals = true; continue; } + if (args[argidx] == "-libdir" && argidx+1 < args.size()) { + libdirs.push_back(args[++argidx]); + continue; + } if (args[argidx] == "-top") { if (++argidx >= args.size()) log_cmd_error("Option -top requires an additional argument!\n"); @@ -344,7 +388,7 @@ struct HierarchyPass : public Pass { for (auto &modname : modnames) { if (design->modules.count(modname) == 0) continue; - if (expand_module(design, design->modules[modname], flag_check)) + if (expand_module(design, design->modules[modname], flag_check, libdirs)) did_something = true; } if (did_something)