mirror of https://github.com/YosysHQ/yosys.git
Merge branch 'master' of https://github.com/ahmedirfan1983/yosys into btor
This commit is contained in:
commit
8661626157
|
@ -23,6 +23,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <fnmatch.h>
|
#include <fnmatch.h>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
struct generate_port_decl_t {
|
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;
|
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;
|
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] != '$')
|
if (flag_check && cell->type[0] != '$')
|
||||||
log_error("Module `%s' referenced in module `%s' in cell `%s' is not part of the design.\n",
|
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());
|
cell->type.c_str(), module->name.c_str(), cell->name.c_str());
|
||||||
continue;
|
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)
|
if (cell->parameters.size() == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (design->modules.at(cell->type)->get_bool_attribute("\\blackbox"))
|
if (design->modules.at(cell->type)->get_bool_attribute("\\blackbox"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
RTLIL::Module *mod = design->modules[cell->type];
|
RTLIL::Module *mod = design->modules[cell->type];
|
||||||
cell->type = mod->derive(design, cell->parameters);
|
cell->type = mod->derive(design, cell->parameters);
|
||||||
cell->parameters.clear();
|
cell->parameters.clear();
|
||||||
|
@ -212,6 +247,11 @@ struct HierarchyPass : public Pass {
|
||||||
log(" also check the design hierarchy. this generates an error when\n");
|
log(" also check the design hierarchy. this generates an error when\n");
|
||||||
log(" an unknown module is used as cell type.\n");
|
log(" an unknown module is used as cell type.\n");
|
||||||
log("\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(" -keep_positionals\n");
|
||||||
log(" per default this pass also converts positional arguments in cells\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");
|
log(" to arguments using port names. this option disables this behavior.\n");
|
||||||
|
@ -247,6 +287,7 @@ struct HierarchyPass : public Pass {
|
||||||
|
|
||||||
bool flag_check = false;
|
bool flag_check = false;
|
||||||
RTLIL::Module *top_mod = NULL;
|
RTLIL::Module *top_mod = NULL;
|
||||||
|
std::vector<std::string> libdirs;
|
||||||
|
|
||||||
bool generate_mode = false;
|
bool generate_mode = false;
|
||||||
bool keep_positionals = false;
|
bool keep_positionals = false;
|
||||||
|
@ -303,6 +344,10 @@ struct HierarchyPass : public Pass {
|
||||||
keep_positionals = true;
|
keep_positionals = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (args[argidx] == "-libdir" && argidx+1 < args.size()) {
|
||||||
|
libdirs.push_back(args[++argidx]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (args[argidx] == "-top") {
|
if (args[argidx] == "-top") {
|
||||||
if (++argidx >= args.size())
|
if (++argidx >= args.size())
|
||||||
log_cmd_error("Option -top requires an additional argument!\n");
|
log_cmd_error("Option -top requires an additional argument!\n");
|
||||||
|
@ -344,7 +389,7 @@ struct HierarchyPass : public Pass {
|
||||||
for (auto &modname : modnames) {
|
for (auto &modname : modnames) {
|
||||||
if (design->modules.count(modname) == 0)
|
if (design->modules.count(modname) == 0)
|
||||||
continue;
|
continue;
|
||||||
if (expand_module(design, design->modules[modname], flag_check))
|
if (expand_module(design, design->modules[modname], flag_check, libdirs))
|
||||||
did_something = true;
|
did_something = true;
|
||||||
}
|
}
|
||||||
if (did_something)
|
if (did_something)
|
||||||
|
|
|
@ -470,7 +470,7 @@ struct DfflibmapPass : public Pass {
|
||||||
FILE *f = fopen(liberty_file.c_str(), "r");
|
FILE *f = fopen(liberty_file.c_str(), "r");
|
||||||
if (f == NULL)
|
if (f == NULL)
|
||||||
log_cmd_error("Can't open liberty file `%s': %s\n", liberty_file.c_str(), strerror(errno));
|
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);
|
fclose(f);
|
||||||
|
|
||||||
find_cell(libparser.ast, "$_DFF_N_", false, false, false, false);
|
find_cell(libparser.ast, "$_DFF_N_", false, false, false, false);
|
||||||
|
|
|
@ -79,7 +79,7 @@ void LibertyAst::dump(FILE *f, std::string indent, std::string path, bool path_o
|
||||||
fprintf(f, " ;\n");
|
fprintf(f, " ;\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int LibertyParer::lexer(std::string &str)
|
int LibertyParser::lexer(std::string &str)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
|
@ -87,11 +87,11 @@ int LibertyParer::lexer(std::string &str)
|
||||||
c = fgetc(f);
|
c = fgetc(f);
|
||||||
} while (c == ' ' || c == '\t' || c == '\r');
|
} 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;
|
str = c;
|
||||||
while (1) {
|
while (1) {
|
||||||
c = fgetc(f);
|
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;
|
str += c;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
@ -154,7 +154,7 @@ int LibertyParer::lexer(std::string &str)
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
LibertyAst *LibertyParer::parse()
|
LibertyAst *LibertyParser::parse()
|
||||||
{
|
{
|
||||||
std::string str;
|
std::string str;
|
||||||
|
|
||||||
|
@ -219,14 +219,14 @@ LibertyAst *LibertyParer::parse()
|
||||||
|
|
||||||
#ifndef FILTERLIB
|
#ifndef FILTERLIB
|
||||||
|
|
||||||
void LibertyParer::error()
|
void LibertyParser::error()
|
||||||
{
|
{
|
||||||
log_error("Syntax error in line %d.\n", line);
|
log_error("Syntax error in line %d.\n", line);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
void LibertyParer::error()
|
void LibertyParser::error()
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Syntax error in line %d.\n", line);
|
fprintf(stderr, "Syntax error in line %d.\n", line);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -611,7 +611,7 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LibertyParer parser(f);
|
LibertyParser parser(f);
|
||||||
if (parser.ast) {
|
if (parser.ast) {
|
||||||
if (flag_verilogsim)
|
if (flag_verilogsim)
|
||||||
gen_verilogsim(parser.ast);
|
gen_verilogsim(parser.ast);
|
||||||
|
|
|
@ -39,13 +39,13 @@ namespace PASS_DFFLIBMAP
|
||||||
static std::set<std::string> whitelist;
|
static std::set<std::string> whitelist;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LibertyParer
|
struct LibertyParser
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
int line;
|
int line;
|
||||||
LibertyAst *ast;
|
LibertyAst *ast;
|
||||||
LibertyParer(FILE *f) : f(f), line(1), ast(parse()) {}
|
LibertyParser(FILE *f) : f(f), line(1), ast(parse()) {}
|
||||||
~LibertyParer() { if (ast) delete ast; }
|
~LibertyParser() { if (ast) delete ast; }
|
||||||
int lexer(std::string &str);
|
int lexer(std::string &str);
|
||||||
LibertyAst *parse();
|
LibertyAst *parse();
|
||||||
void error();
|
void error();
|
||||||
|
|
Loading…
Reference in New Issue