summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--passes/hierarchy/hierarchy.cc53
-rw-r--r--passes/techmap/dfflibmap.cc2
-rw-r--r--passes/techmap/libparse.cc14
-rw-r--r--passes/techmap/libparse.h6
4 files changed, 60 insertions, 15 deletions
diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc
index d4675702..01e287e9 100644
--- a/passes/hierarchy/hierarchy.cc
+++ b/passes/hierarchy/hierarchy.cc
@@ -23,6 +23,7 @@
#include <stdio.h>
#include <fnmatch.h>
#include <set>
+#include <unistd.h>
namespace {
struct generate_port_decl_t {
@@ -133,22 +134,56 @@ static void generate(RTLIL::Design *design, const std::vector<std::string> &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<std::string> &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<std::string> 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<std::string> 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 +247,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 <directory>\n");
+ log(" search for files named <module_name>.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 +287,7 @@ struct HierarchyPass : public Pass {
bool flag_check = false;
RTLIL::Module *top_mod = NULL;
+ std::vector<std::string> libdirs;
bool generate_mode = false;
bool keep_positionals = false;
@@ -303,6 +344,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 +389,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)
diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc
index 40caf780..23d93353 100644
--- a/passes/techmap/dfflibmap.cc
+++ b/passes/techmap/dfflibmap.cc
@@ -470,7 +470,7 @@ struct DfflibmapPass : public Pass {
FILE *f = fopen(liberty_file.c_str(), "r");
if (f == NULL)
log_cmd_error("Can't open liberty file `%s': %s\n", liberty_file.c_str(), strerror(errno));
- LibertyParer libparser(f);
+ LibertyParser libparser(f);
fclose(f);
find_cell(libparser.ast, "$_DFF_N_", false, false, false, false);
diff --git a/passes/techmap/libparse.cc b/passes/techmap/libparse.cc
index 8fc03b5c..8f4a1a5f 100644
--- a/passes/techmap/libparse.cc
+++ b/passes/techmap/libparse.cc
@@ -79,7 +79,7 @@ void LibertyAst::dump(FILE *f, std::string indent, std::string path, bool path_o
fprintf(f, " ;\n");
}
-int LibertyParer::lexer(std::string &str)
+int LibertyParser::lexer(std::string &str)
{
int c;
@@ -87,11 +87,11 @@ int LibertyParer::lexer(std::string &str)
c = fgetc(f);
} while (c == ' ' || c == '\t' || c == '\r');
- if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_' || c == '-' || c == '.') {
+ if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_' || c == '-' || c == '+' || c == '.') {
str = c;
while (1) {
c = fgetc(f);
- if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_' || c == '-' || c == '.')
+ if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_' || c == '-' || c == '+' || c == '.')
str += c;
else
break;
@@ -154,7 +154,7 @@ int LibertyParer::lexer(std::string &str)
return c;
}
-LibertyAst *LibertyParer::parse()
+LibertyAst *LibertyParser::parse()
{
std::string str;
@@ -219,14 +219,14 @@ LibertyAst *LibertyParer::parse()
#ifndef FILTERLIB
-void LibertyParer::error()
+void LibertyParser::error()
{
log_error("Syntax error in line %d.\n", line);
}
#else
-void LibertyParer::error()
+void LibertyParser::error()
{
fprintf(stderr, "Syntax error in line %d.\n", line);
exit(1);
@@ -611,7 +611,7 @@ int main(int argc, char **argv)
}
}
- LibertyParer parser(f);
+ LibertyParser parser(f);
if (parser.ast) {
if (flag_verilogsim)
gen_verilogsim(parser.ast);
diff --git a/passes/techmap/libparse.h b/passes/techmap/libparse.h
index 8c4a2f5c..eff268bb 100644
--- a/passes/techmap/libparse.h
+++ b/passes/techmap/libparse.h
@@ -39,13 +39,13 @@ namespace PASS_DFFLIBMAP
static std::set<std::string> whitelist;
};
- struct LibertyParer
+ struct LibertyParser
{
FILE *f;
int line;
LibertyAst *ast;
- LibertyParer(FILE *f) : f(f), line(1), ast(parse()) {}
- ~LibertyParer() { if (ast) delete ast; }
+ LibertyParser(FILE *f) : f(f), line(1), ast(parse()) {}
+ ~LibertyParser() { if (ast) delete ast; }
int lexer(std::string &str);
LibertyAst *parse();
void error();