Add "read_ilang -[no]overwrite"
authorClifford Wolf <clifford@clifford.at>
Sun, 23 Dec 2018 14:45:09 +0000 (15:45 +0100)
committerClifford Wolf <clifford@clifford.at>
Sun, 23 Dec 2018 14:45:09 +0000 (15:45 +0100)
Signed-off-by: Clifford Wolf <clifford@clifford.at>
frontends/ilang/ilang_frontend.cc
frontends/ilang/ilang_frontend.h
frontends/ilang/ilang_parser.y

index d8783ac1d3eef217cf1ed85a57feea4c7d4e9621..6b302a79626676f3a5ae0c8a08630bfd766585cb 100644 (file)
@@ -44,11 +44,39 @@ struct IlangFrontend : public Frontend {
                log("Load modules from an ilang file to the current design. (ilang is a text\n");
                log("representation of a design in yosys's internal format.)\n");
                log("\n");
+               log("    -nooverwrite\n");
+               log("        ignore re-definitions of modules. (the default behavior is to\n");
+               log("        create an error message if the existing module is not a blackbox\n");
+               log("        module, and overwrite the existing module if it is  a blackbox module.)\n");
+               log("\n");
+               log("    -overwrite\n");
+               log("        overwrite existing modules with the same name\n");
+               log("\n");
        }
        void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
        {
+               ILANG_FRONTEND::flag_nooverwrite = false;
+               ILANG_FRONTEND::flag_overwrite = false;
+
                log_header(design, "Executing ILANG frontend.\n");
-               extra_args(f, filename, args, 1);
+
+               size_t argidx;
+               for (argidx = 1; argidx < args.size(); argidx++) {
+                       std::string arg = args[argidx];
+                       if (arg == "-nooverwrite") {
+                               ILANG_FRONTEND::flag_nooverwrite = true;
+                               ILANG_FRONTEND::flag_overwrite = false;
+                               continue;
+                       }
+                       if (arg == "-overwrite") {
+                               ILANG_FRONTEND::flag_nooverwrite = false;
+                               ILANG_FRONTEND::flag_overwrite = true;
+                               continue;
+                       }
+                       break;
+               }
+               extra_args(f, filename, args, argidx);
+
                log("Input filename: %s\n", filename.c_str());
 
                ILANG_FRONTEND::lexin = f;
index ad3ffec90e47a22edec5fda87c7c2592459925e3..052dd4cb28dbcd14f41a7c1d00b6702bf1ecc43d 100644 (file)
@@ -32,6 +32,8 @@ YOSYS_NAMESPACE_BEGIN
 namespace ILANG_FRONTEND {
        extern std::istream *lexin;
        extern RTLIL::Design *current_design;
+       extern bool flag_nooverwrite;
+       extern bool flag_overwrite;
 }
 
 YOSYS_NAMESPACE_END
index b957ecd9656f1f49f4376ff4bd7fc5bc95ad26b5..5bcc01f42ee64d1f9d173954404ee70b88b23cc8 100644 (file)
@@ -37,6 +37,8 @@ namespace ILANG_FRONTEND {
        std::vector<std::vector<RTLIL::SwitchRule*>*> switch_stack;
        std::vector<RTLIL::CaseRule*> case_stack;
        dict<RTLIL::IdString, RTLIL::Const> attrbuf;
+       bool flag_nooverwrite, flag_overwrite;
+       bool delete_current_module;
 }
 using namespace ILANG_FRONTEND;
 YOSYS_NAMESPACE_END
@@ -93,18 +95,36 @@ design:
 
 module:
        TOK_MODULE TOK_ID EOL {
-               if (current_design->has($2))
-                       rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of module %s.", $2).c_str());
+               delete_current_module = false;
+               if (current_design->has($2)) {
+                       RTLIL::Module *existing_mod = current_design->module($2);
+                       if (!flag_overwrite && attrbuf.count("\\blackbox") && attrbuf.at("\\blackbox").as_bool()) {
+                               log("Ignoring blackbox re-definition of module %s.\n", $2);
+                               delete_current_module = true;
+                       } else if (!flag_nooverwrite && !flag_overwrite && !existing_mod->get_bool_attribute("\\blackbox")) {
+                               rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of module %s.", $2).c_str());
+                       } else if (flag_nooverwrite) {
+                               log("Ignoring re-definition of module %s.\n", $2);
+                               delete_current_module = true;
+                       } else {
+                               log("Replacing existing%s module %s.\n", existing_mod->get_bool_attribute("\\blackbox") ? " blackbox" : "", $2);
+                               current_design->remove(existing_mod);
+                       }
+               }
                current_module = new RTLIL::Module;
                current_module->name = $2;
                current_module->attributes = attrbuf;
-               current_design->add(current_module);
+               if (!delete_current_module)
+                       current_design->add(current_module);
                attrbuf.clear();
                free($2);
        } module_body TOK_END {
                if (attrbuf.size() != 0)
                        rtlil_frontend_ilang_yyerror("dangling attribute");
                current_module->fixup_ports();
+               if (delete_current_module)
+                       delete current_module;
+               current_module = nullptr;
        } EOL;
 
 module_body: