From a96c775a7301645b27486a5e663c75fca460f577 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 7 Jan 2018 16:36:13 +0100 Subject: [PATCH] Add support for "yosys -E" Signed-off-by: Clifford Wolf --- frontends/ast/simplify.cc | 1 + frontends/verilog/preproc.cc | 6 ++++-- kernel/driver.cc | 27 ++++++++++++++++++++++++++- kernel/register.cc | 2 ++ kernel/yosys.cc | 6 +++++- kernel/yosys.h | 3 +++ passes/cmds/qwp.cc | 1 + passes/cmds/select.cc | 2 ++ passes/cmds/show.cc | 5 +++++ passes/cmds/stat.cc | 1 + passes/cmds/tee.cc | 1 + passes/cmds/write_file.cc | 1 + passes/techmap/techmap.cc | 1 + 13 files changed, 53 insertions(+), 4 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index f61f7cf7c..c454fb907 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -2638,6 +2638,7 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m std::ifstream f; f.open(mem_filename.c_str()); + yosys_input_files.insert(mem_filename); if (f.fail()) log_error("Can not open file `%s` for %s at %s:%d.\n", mem_filename.c_str(), str.c_str(), filename.c_str(), linenum); diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 00bdcee43..c43ff4e3a 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -400,10 +400,12 @@ std::string frontend_verilog_preproc(std::istream &f, std::string filename, cons if (!ff.fail()) break; } } - if (ff.fail()) + if (ff.fail()) { output_code.push_back("`file_notfound " + fn); - else + } else { input_file(ff, fixed_fn); + yosys_input_files.insert(fixed_fn); + } continue; } diff --git a/kernel/driver.cc b/kernel/driver.cc index c5e31d718..f49f6023b 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -160,6 +160,7 @@ int main(int argc, char **argv) std::vector plugin_filenames; std::string output_filename = ""; std::string scriptfile = ""; + std::string depsfile = ""; bool scriptfile_tcl = false; bool got_output_filename = false; bool print_banner = true; @@ -256,6 +257,9 @@ int main(int argc, char **argv) printf(" if a warning message matches the regex, it is printes as regular\n"); printf(" message instead.\n"); printf("\n"); + printf(" -E \n"); + printf(" write a Makefile dependencies file with in- and output file names\n"); + printf("\n"); printf(" -V\n"); printf(" print version information and exit\n"); printf("\n"); @@ -276,7 +280,7 @@ int main(int argc, char **argv) } int opt; - while ((opt = getopt(argc, argv, "MXAQTVSm:f:Hh:b:o:p:l:L:qv:tds:c:W:w:D:")) != -1) + while ((opt = getopt(argc, argv, "MXAQTVSm:f:Hh:b:o:p:l:L:qv:tds:c:W:w:D:E:")) != -1) { switch (opt) { @@ -392,6 +396,9 @@ int main(int argc, char **argv) } } break; + case 'E': + depsfile = optarg; + break; default: fprintf(stderr, "Run '%s -h' for help.\n", argv[0]); exit(1); @@ -442,6 +449,24 @@ int main(int argc, char **argv) if (!backend_command.empty()) run_backend(output_filename, backend_command); + if (!depsfile.empty()) + { + FILE *f = fopen(depsfile.c_str(), "wt"); + if (f == nullptr) + log_error("Can't open dependencies file for writing: %s\n", strerror(errno)); + bool first = true; + for (auto fn : yosys_output_files) { + fprintf(f, "%s%s", first ? "" : " ", fn.c_str()); + first = false; + } + fprintf(f, ":"); + for (auto fn : yosys_input_files) { + if (yosys_output_files.count(fn) == 0) + fprintf(f, " %s", fn.c_str()); + } + fprintf(f, "\n"); + } + if (print_stats) { std::string hash = log_hasher->final().substr(0, 10); diff --git a/kernel/register.cc b/kernel/register.cc index 983577682..e30414f44 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -428,6 +428,7 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vectoropen(filename.c_str()); + yosys_input_files.insert(filename); if (ff->fail()) delete ff; else @@ -543,6 +544,7 @@ void Backend::extra_args(std::ostream *&f, std::string &filename, std::vectoropen(filename.c_str(), std::ofstream::trunc); + yosys_output_files.insert(filename); if (ff->fail()) { delete ff; log_cmd_error("Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno)); diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 34665a0ad..987ebcdce 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -64,6 +64,8 @@ CellTypes yosys_celltypes; Tcl_Interp *yosys_tcl_interp = NULL; #endif +std::set yosys_input_files, yosys_output_files; + bool memhasher_active = false; uint32_t memhasher_rng = 123456; std::vector memhasher_store; @@ -831,8 +833,10 @@ void run_frontend(std::string filename, std::string command, std::string *backen FILE *f = stdin; - if (filename != "-") + if (filename != "-") { f = fopen(filename.c_str(), "r"); + yosys_input_files.insert(filename); + } if (f == NULL) log_error("Can't open script file `%s' for reading: %s\n", filename.c_str(), strerror(errno)); diff --git a/kernel/yosys.h b/kernel/yosys.h index 5ec681b32..14cbcd610 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -305,6 +305,9 @@ void run_frontend(std::string filename, std::string command, RTLIL::Design *desi void run_backend(std::string filename, std::string command, RTLIL::Design *design = nullptr); void shell(RTLIL::Design *design); +// journal of all input and output files read (for "yosys -E") +extern std::set yosys_input_files, yosys_output_files; + // from kernel/version_*.o (cc source generated from Makefile) extern const char *yosys_version_str; diff --git a/passes/cmds/qwp.cc b/passes/cmds/qwp.cc index 1b800b6df..f2dfa760e 100644 --- a/passes/cmds/qwp.cc +++ b/passes/cmds/qwp.cc @@ -835,6 +835,7 @@ struct QwpPass : public Pass { } if (args[argidx] == "-dump" && argidx+1 < args.size()) { config.dump_file.open(args[++argidx], std::ofstream::trunc); + yosys_output_files.insert(args[argidx]); continue; } break; diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 7d2f4262b..ae301040a 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -1263,6 +1263,7 @@ struct SelectPass : public Pass { log_cmd_error("Option -read can not be combined with a selection expression.\n"); std::ifstream f(read_file); + yosys_input_files.insert(read_file); if (f.fail()) log_error("Can't open '%s' for reading: %s\n", read_file.c_str(), strerror(errno)); @@ -1331,6 +1332,7 @@ struct SelectPass : public Pass { FILE *f = NULL; if (!write_file.empty()) { f = fopen(write_file.c_str(), "w"); + yosys_output_files.insert(write_file); if (f == NULL) log_error("Can't open '%s' for writing: %s\n", write_file.c_str(), strerror(errno)); } diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 02624cf30..56e1122bf 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -681,6 +681,7 @@ struct ShowPass : public Pass { bool flag_enum = false; bool flag_abbreviate = true; bool flag_notitle = false; + bool custom_prefix = false; RTLIL::IdString colorattr; size_t argidx; @@ -697,6 +698,7 @@ struct ShowPass : public Pass { } if (arg == "-prefix" && argidx+1 < args.size()) { prefix = args[++argidx]; + custom_prefix = true; continue; } if (arg == "-color" && argidx+2 < args.size()) { @@ -782,6 +784,7 @@ struct ShowPass : public Pass { for (auto filename : libfiles) { std::ifstream f; f.open(filename.c_str()); + yosys_input_files.insert(filename); if (f.fail()) log_error("Can't open lib file `%s'.\n", filename.c_str()); RTLIL::Design *lib = new RTLIL::Design; @@ -797,6 +800,8 @@ struct ShowPass : public Pass { log("Writing dot description to `%s'.\n", dot_file.c_str()); FILE *f = fopen(dot_file.c_str(), "w"); + if (custom_prefix) + yosys_output_files.insert(dot_file); if (f == NULL) { for (auto lib : libs) delete lib; diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index a887fbb6a..e52a192db 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -190,6 +190,7 @@ void read_liberty_cellarea(dict &cell_area, string liberty_fil { std::ifstream f; f.open(liberty_file.c_str()); + yosys_input_files.insert(liberty_file); if (f.fail()) log_cmd_error("Can't open liberty file `%s': %s\n", liberty_file.c_str(), strerror(errno)); LibertyParser libparser(f); diff --git a/passes/cmds/tee.cc b/passes/cmds/tee.cc index 3db2dbf0e..b68c089e9 100644 --- a/passes/cmds/tee.cc +++ b/passes/cmds/tee.cc @@ -65,6 +65,7 @@ struct TeePass : public Pass { if ((args[argidx] == "-o" || args[argidx] == "-a") && argidx+1 < args.size()) { const char *open_mode = args[argidx] == "-o" ? "w" : "a+"; FILE *f = fopen(args[++argidx].c_str(), open_mode); + yosys_input_files.insert(args[argidx]); if (f == NULL) { for (auto cf : files_to_close) fclose(cf); diff --git a/passes/cmds/write_file.cc b/passes/cmds/write_file.cc index b78265933..70892a945 100644 --- a/passes/cmds/write_file.cc +++ b/passes/cmds/write_file.cc @@ -67,6 +67,7 @@ struct WriteFileFrontend : public Frontend { extra_args(f, filename, args, argidx); FILE *of = fopen(output_filename.c_str(), append_mode ? "a" : "w"); + yosys_output_files.insert(output_filename); char buffer[64 * 1024]; int bytes; diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index d9e81e808..d7756e2cd 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -1095,6 +1095,7 @@ struct TechmapPass : public Pass { std::ifstream f; rewrite_filename(fn); f.open(fn.c_str()); + yosys_input_files.insert(fn); if (f.fail()) log_cmd_error("Can't open map file `%s'\n", fn.c_str()); Frontend::frontend_call(map, &f, fn, (fn.size() > 3 && fn.substr(fn.size()-3) == ".il") ? "ilang" : verilog_frontend); -- 2.30.2