Add automatic verific import in hierarchy command
authorClifford Wolf <clifford@clifford.at>
Wed, 20 Jun 2018 21:45:01 +0000 (23:45 +0200)
committerClifford Wolf <clifford@clifford.at>
Wed, 20 Jun 2018 21:45:01 +0000 (23:45 +0200)
Signed-off-by: Clifford Wolf <clifford@clifford.at>
frontends/verific/verific.cc
frontends/verific/verific.h
passes/hierarchy/hierarchy.cc

index f67337754d9fe6944ce1bd69659eecec8f0d6b74..ab5c545a1efe0225640d6d4bf9b4af884b77fdb3 100644 (file)
@@ -62,6 +62,7 @@ using namespace Verific;
 YOSYS_NAMESPACE_BEGIN
 
 int verific_verbose;
+bool verific_import_pending;
 string verific_error_msg;
 
 void msg_func(msg_type_t msg_type, const char *message_id, linefile_type linefile, const char *msg, va_list args)
@@ -1613,6 +1614,52 @@ struct VerificExtNets
        }
 };
 
+void verific_import(Design *design, std::string top)
+{
+       std::set<Netlist*> nl_todo, nl_done;
+
+       {
+               VhdlLibrary *vhdl_lib = vhdl_file::GetLibrary("work", 1);
+               VeriLibrary *veri_lib = veri_file::GetLibrary("work", 1);
+
+               Array veri_libs, vhdl_libs;
+               if (vhdl_lib) vhdl_libs.InsertLast(vhdl_lib);
+               if (veri_lib) veri_libs.InsertLast(veri_lib);
+
+               Array *netlists = hier_tree::ElaborateAll(&veri_libs, &vhdl_libs);
+               Netlist *nl;
+               int i;
+
+               FOREACH_ARRAY_ITEM(netlists, i, nl) {
+                       if (top.empty() || nl->Owner()->Name() == top)
+                               nl_todo.insert(nl);
+               }
+
+               delete netlists;
+       }
+
+       if (!verific_error_msg.empty())
+               log_error("%s\n", verific_error_msg.c_str());
+
+       while (!nl_todo.empty()) {
+               Netlist *nl = *nl_todo.begin();
+               if (nl_done.count(nl) == 0) {
+                       VerificImporter importer(false, false, false, false, false, false);
+                       importer.import_netlist(design, nl, nl_todo);
+               }
+               nl_todo.erase(nl);
+               nl_done.insert(nl);
+       }
+
+       veri_file::Reset();
+       vhdl_file::Reset();
+       Libset::Reset();
+       verific_import_pending = false;
+
+       if (!verific_error_msg.empty())
+               log_error("%s\n", verific_error_msg.c_str());
+}
+
 YOSYS_NAMESPACE_END
 #endif /* YOSYS_ENABLE_VERIFIC */
 
@@ -1789,6 +1836,7 @@ struct VerificPass : public Pass {
                        if (!veri_file::AnalyzeMultipleFiles(&file_names, verilog_mode, "work", veri_file::MFCU))
                                        log_cmd_error("Reading Verilog/SystemVerilog sources failed.\n");
 
+                       verific_import_pending = true;
                        goto check_error;
                }
 
@@ -1797,6 +1845,7 @@ struct VerificPass : public Pass {
                        for (argidx++; argidx < GetSize(args); argidx++)
                                if (!vhdl_file::Analyze(args[argidx].c_str(), "work", vhdl_file::VHDL_87))
                                        log_cmd_error("Reading `%s' in VHDL_87 mode failed.\n", args[argidx].c_str());
+                       verific_import_pending = true;
                        goto check_error;
                }
 
@@ -1805,6 +1854,7 @@ struct VerificPass : public Pass {
                        for (argidx++; argidx < GetSize(args); argidx++)
                                if (!vhdl_file::Analyze(args[argidx].c_str(), "work", vhdl_file::VHDL_93))
                                        log_cmd_error("Reading `%s' in VHDL_93 mode failed.\n", args[argidx].c_str());
+                       verific_import_pending = true;
                        goto check_error;
                }
 
@@ -1813,6 +1863,7 @@ struct VerificPass : public Pass {
                        for (argidx++; argidx < GetSize(args); argidx++)
                                if (!vhdl_file::Analyze(args[argidx].c_str(), "work", vhdl_file::VHDL_2K))
                                        log_cmd_error("Reading `%s' in VHDL_2K mode failed.\n", args[argidx].c_str());
+                       verific_import_pending = true;
                        goto check_error;
                }
 
@@ -1821,6 +1872,7 @@ struct VerificPass : public Pass {
                        for (argidx++; argidx < GetSize(args); argidx++)
                                if (!vhdl_file::Analyze(args[argidx].c_str(), "work", vhdl_file::VHDL_2008))
                                        log_cmd_error("Reading `%s' in VHDL_2008 mode failed.\n", args[argidx].c_str());
+                       verific_import_pending = true;
                        goto check_error;
                }
 
@@ -2031,6 +2083,7 @@ struct VerificPass : public Pass {
                        veri_file::Reset();
                        vhdl_file::Reset();
                        Libset::Reset();
+                       verific_import_pending = false;
                        goto check_error;
                }
 
index 86a743ea16b6a32189cfb0eda218bdaa2fcbb7ca..cbd9314dbc4615040f62a510f07cd7e1edd6478b 100644 (file)
@@ -25,6 +25,9 @@ YOSYS_NAMESPACE_BEGIN
 
 extern int verific_verbose;
 
+extern bool verific_import_pending;
+extern void verific_import(Design *design, std::string top = std::string());
+
 extern pool<int> verific_sva_prims;
 
 struct VerificImporter;
index bfb8e7f9566da3182f86bbfcb4cf757006a14ff0..e6185148133e6e3388bd110edc2282253bd77e85 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include "kernel/yosys.h"
+#include "frontends/verific/verific.h"
 #include <stdlib.h>
 #include <stdio.h>
 #include <set>
@@ -421,6 +422,7 @@ struct HierarchyPass : public Pass {
                bool flag_simcheck = false;
                bool purge_lib = false;
                RTLIL::Module *top_mod = NULL;
+               std::string load_top_mod;
                std::vector<std::string> libdirs;
 
                bool auto_top_mode = false;
@@ -511,7 +513,7 @@ struct HierarchyPass : public Pass {
                                        top_mod = design->modules_.count(RTLIL::escape_id(args[argidx])) ? design->modules_.at(RTLIL::escape_id(args[argidx])) : NULL;
                                }
                                if (top_mod == NULL)
-                                       log_cmd_error("Module `%s' not found!\n", args[argidx].c_str());
+                                       load_top_mod = args[argidx];
                                continue;
                        }
                        if (args[argidx] == "-auto-top") {
@@ -522,6 +524,22 @@ struct HierarchyPass : public Pass {
                }
                extra_args(args, argidx, design, false);
 
+               if (!load_top_mod.empty()) {
+#ifdef YOSYS_ENABLE_VERIFIC
+                       if (verific_import_pending) {
+                               verific_import(design, load_top_mod);
+                               top_mod = design->module(RTLIL::escape_id(load_top_mod));
+                       }
+#endif
+                       if (top_mod == NULL)
+                               log_cmd_error("Module `%s' not found!\n", load_top_mod.c_str());
+               } else {
+#ifdef YOSYS_ENABLE_VERIFIC
+                       if (verific_import_pending)
+                               verific_import(design);
+#endif
+               }
+
                if (generate_mode) {
                        generate(design, generate_cells, generate_ports);
                        return;