Add support for "yosys -E"
authorClifford Wolf <clifford@clifford.at>
Sun, 7 Jan 2018 15:36:13 +0000 (16:36 +0100)
committerClifford Wolf <clifford@clifford.at>
Sun, 7 Jan 2018 15:36:13 +0000 (16:36 +0100)
Signed-off-by: Clifford Wolf <clifford@clifford.at>
13 files changed:
frontends/ast/simplify.cc
frontends/verilog/preproc.cc
kernel/driver.cc
kernel/register.cc
kernel/yosys.cc
kernel/yosys.h
passes/cmds/qwp.cc
passes/cmds/select.cc
passes/cmds/show.cc
passes/cmds/stat.cc
passes/cmds/tee.cc
passes/cmds/write_file.cc
passes/techmap/techmap.cc

index f61f7cf7ca1730d8a27b42fbcffc775e7fa8fc2b..c454fb907ffd4c3752c05382ee0373b2f8d46168 100644 (file)
@@ -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);
index 00bdcee4365ffaab23d19b05bff6bd1bb6bd18c2..c43ff4e3a7efe745f4a73339006e0c575edda7e3 100644 (file)
@@ -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;
                }
 
index c5e31d7189e8a80a96188080ce0da1244669f7a5..f49f6023bbde6f0858ce5790a303299361dfd5ef 100644 (file)
@@ -160,6 +160,7 @@ int main(int argc, char **argv)
        std::vector<std::string> 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 <depsfile>\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);
index 983577682121c7b03d8cf87bf1a2a31fc82a9a84..e30414f44f619361c0529ea19c23beb4e82d773f 100644 (file)
@@ -428,6 +428,7 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector<s
                        }
                        std::ifstream *ff = new std::ifstream;
                        ff->open(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::vector<st
                filename = arg;
                std::ofstream *ff = new std::ofstream;
                ff->open(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));
index 34665a0ade3efc245d7c5eab28f721005f6c6ad0..987ebcdce1d84a18c284e5b279d2a65c514a3c15 100644 (file)
@@ -64,6 +64,8 @@ CellTypes yosys_celltypes;
 Tcl_Interp *yosys_tcl_interp = NULL;
 #endif
 
+std::set<std::string> yosys_input_files, yosys_output_files;
+
 bool memhasher_active = false;
 uint32_t memhasher_rng = 123456;
 std::vector<void*> 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));
index 5ec681b32c94845f64bc491e7199ca2c3e2139f2..14cbcd610111a5d42e5e88ab4e019edfa6ff94b7 100644 (file)
@@ -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<std::string> yosys_input_files, yosys_output_files;
+
 // from kernel/version_*.o (cc source generated from Makefile)
 extern const char *yosys_version_str;
 
index 1b800b6df12e6793482704e3afe856c80c689db8..f2dfa760e20543971cdd5f0c923079e1ae05a974 100644 (file)
@@ -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;
index 7d2f4262b21e00103e87efd210f949ddd050739f..ae301040aff2a4ae9b43acc7d3f69a5253ad36a4 100644 (file)
@@ -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));
                        }
index 02624cf30b792ccae5f810d72be88398c3c5ee50..56e1122bffef42113c2a5f1b58225266291df7c8 100644 (file)
@@ -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;
index a887fbb6a9795eaafe67ddd0804dfa6b5748d686..e52a192db74642a3ed098ff2a0e0d6b08e43a334 100644 (file)
@@ -190,6 +190,7 @@ void read_liberty_cellarea(dict<IdString, double> &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);
index 3db2dbf0e484f2ee70ff7db069336fb9d64119fb..b68c089e9ee633304b9f9848ebcf5e9c1a77686c 100644 (file)
@@ -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);
index b78265933493d0b644e6c9e3ab8567c5919d0727..70892a945b72cfd175a3e3457816b8b6ee235808 100644 (file)
@@ -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;
 
index d9e81e8089282f37e517055b943a36cdc3e51b9e..d7756e2cdb507b8fb3f39180f6713174da367a9d 100644 (file)
@@ -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);