diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 4cdda6165..b7eb6af48 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -20,9 +20,11 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" #include "kernel/celltypes.h" +#include "kernel/json.h" #include "kernel/log.h" #include "kernel/utils.h" #include "libs/sha1/sha1.h" +#include #include #include #include @@ -117,6 +119,44 @@ bool verific_no_split_complex_ports; // SILIMATE: disable splitting of complex p #ifdef VERIFIC_SYSTEMVERILOG_SUPPORT vector verific_incdirs, verific_libdirs, verific_libexts; + +static void dump_verific_file_closure(const char *output_path, Array *file_names) +{ + std::set seen; + Json::array files_json; + auto add_file = [&](const char *path) { + if (!path) return; + char *abs_name = FileSystem::Convert2AbsolutePath(path, 1); + if (abs_name && seen.insert(abs_name).second) + files_json.push_back(std::string(abs_name)); + Strings::free(abs_name); + }; + + unsigned i; + char *file_name; + FOREACH_ARRAY_ITEM(file_names, i, file_name) + add_file(file_name); + + MapIter mi; + VeriModule *veri_module; + FOREACH_VERILOG_MODULE(mi, veri_module) + add_file(LineFile::GetFileName(veri_module->Linefile())); + + const Map *included_files = veri_file::GetIncludedFiles(); + if (included_files) { + char *included_file; + verific_uintptr included_from; + FOREACH_MAP_ITEM(included_files, mi, &included_file, &included_from) + add_file(included_file); + } + + PrettyJson json; + if (!json.write_to_file(output_path)) + log_cmd_error("Cannot write file closure '%s'.\n", output_path); + json.begin_object(); + json.entry_json("files", Json(files_json)); + json.end_object(); +} #endif void msg_func(msg_type_t msg_type, const char *message_id, linefile_type linefile, const char *msg, va_list args) @@ -3662,6 +3702,7 @@ struct VerificPass : public Pass { int argidx = 1; std::string work = "work"; + std::string dump_file_closure; bool is_work_set = false; (void)is_work_set; #ifdef VERIFIC_SYSTEMVERILOG_SUPPORT @@ -3797,6 +3838,12 @@ struct VerificPass : public Pass { } #ifdef VERIFIC_SYSTEMVERILOG_SUPPORT + if (GetSize(args) > argidx && args[argidx] == "-dump-file-closure") { + if (++argidx >= GetSize(args)) + log_cmd_error("Missing JSON output path for -dump-file-closure.\n"); + dump_file_closure = args[argidx++]; + } + if (GetSize(args) > argidx && args[argidx] == "-optimization") { verific_opt = true; goto check_error; @@ -4010,6 +4057,9 @@ struct VerificPass : public Pass { } #endif + if (!dump_file_closure.empty()) + dump_verific_file_closure(dump_file_closure.c_str(), file_names); + delete file_names; verific_import_pending = true; goto check_error; @@ -4085,9 +4135,11 @@ struct VerificPass : public Pass { Map map(POINTER_HASH); add_modules_to_map(map, work, flag_lib); if (!veri_file::AnalyzeMultipleFiles(&file_names, verilog_mode, work.c_str(), veri_file::MFCU)) { - verific_error_msg.clear(); - log_cmd_error("Reading Verilog/SystemVerilog sources failed.\n"); + verific_error_msg.clear(); + log_cmd_error("Reading Verilog/SystemVerilog sources failed.\n"); } + if (!dump_file_closure.empty()) + dump_verific_file_closure(dump_file_closure.c_str(), &file_names); char* fn; int i = 0;