Added techmap -extern
authorClifford Wolf <clifford@clifford.at>
Sun, 27 Jul 2014 19:13:23 +0000 (21:13 +0200)
committerClifford Wolf <clifford@clifford.at>
Sun, 27 Jul 2014 19:31:18 +0000 (21:31 +0200)
passes/techmap/techmap.cc
tests/vloghtb/common.sh
tests/vloghtb/test_mapopt.sh

index 3595b7b534769131c4605c1c1ae4d78467d00b79..79e70a59ceecc3e491c467cad753169752556585 100644 (file)
@@ -58,6 +58,7 @@ struct TechmapWorker
        std::map<std::string, void(*)(RTLIL::Module*, RTLIL::Cell*)> simplemap_mappers;
        std::map<std::pair<RTLIL::IdString, std::map<RTLIL::IdString, RTLIL::Const>>, RTLIL::Module*> techmap_cache;
        std::map<RTLIL::Module*, bool> techmap_do_cache;
+       std::set<RTLIL::Module*> module_queue;
 
        struct TechmapWireData {
                RTLIL::Wire *wire;
@@ -215,7 +216,7 @@ struct TechmapWorker
        }
 
        bool techmap_module(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Design *map, std::set<RTLIL::Cell*> &handled_cells,
-                       const std::map<RTLIL::IdString, std::set<RTLIL::IdString>> &celltypeMap, bool flatten_mode)
+                       const std::map<RTLIL::IdString, std::set<RTLIL::IdString>> &celltypeMap, bool flatten_mode, bool extern_mode)
        {
                if (!design->selected(module))
                        return false;
@@ -282,15 +283,24 @@ struct TechmapWorker
 
                                if (!flatten_mode)
                                {
-                                       if (tpl->get_bool_attribute("\\techmap_simplemap")) {
-                                               log("Mapping %s.%s (%s) with simplemap.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type));
-                                               if (simplemap_mappers.count(cell->type) == 0)
-                                                       log_error("No simplemap mapper for cell type %s found!\n", RTLIL::id2cstr(cell->type));
-                                               simplemap_mappers.at(cell->type)(module, cell);
-                                               module->remove(cell);
-                                               cell = NULL;
-                                               did_something = true;
-                                               break;
+                                       if (tpl->get_bool_attribute("\\techmap_simplemap"))
+                                       {
+                                               if (extern_mode)
+                                               {
+                                                       log("WARNING: Mapping simplat cell %s.%s (%s) in -extern mode is not supported yet.\n", log_id(module), log_id(cell), log_id(cell->type));
+                                                       break;
+                                               }
+                                               else
+                                               {
+                                                       log("Mapping %s.%s (%s) with simplemap.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type));
+                                                       if (simplemap_mappers.count(cell->type) == 0)
+                                                               log_error("No simplemap mapper for cell type %s found!\n", RTLIL::id2cstr(cell->type));
+                                                       simplemap_mappers.at(cell->type)(module, cell);
+                                                       module->remove(cell);
+                                                       cell = NULL;
+                                                       did_something = true;
+                                                       break;
+                                               }
                                        }
 
                                        for (auto conn : cell->connections()) {
@@ -454,9 +464,33 @@ struct TechmapWorker
                                        log_continue = false;
                                }
 
-                               techmap_module_worker(design, module, cell, tpl, flatten_mode);
+                               if (extern_mode)
+                               {
+                                       std::string m_name = stringf("$extern:%s", log_id(tpl));
+
+                                       if (!design->module(m_name))
+                                       {
+                                               RTLIL::Module *m = design->addModule(m_name);
+                                               tpl->cloneInto(m);
+
+                                               for (auto cell : m->cells()) {
+                                                       if (cell->type.substr(0, 2) == "\\$")
+                                                               cell->type = cell->type.substr(1);
+                                               }
+
+                                               module_queue.insert(m);
+                                       }
+
+                                       log("Mapping %s.%s to imported %s.\n", log_id(module), log_id(cell), log_id(m_name));
+                                       cell->type = m_name;
+                                       cell->parameters.clear();
+                               }
+                               else
+                               {
+                                       techmap_module_worker(design, module, cell, tpl, flatten_mode);
+                                       cell = NULL;
+                               }
                                did_something = true;
-                               cell = NULL;
                                break;
                        }
 
@@ -495,6 +529,10 @@ struct TechmapPass : public Pass {
                log("        yosys data files are). this is mainly used internally when techmap\n");
                log("        is called from other commands.\n");
                log("\n");
+               log("    -extern\n");
+               log("        load the cell implementations as separate modules into the design\n");
+               log("        instead of inlining them.\n");
+               log("\n");
                log("    -max_iter <number>\n");
                log("        only run the specified number of iterations.\n");
                log("\n");
@@ -576,6 +614,7 @@ struct TechmapPass : public Pass {
 
                std::vector<std::string> map_files;
                std::string verilog_frontend = "verilog -ignore_redef";
+               bool extern_mode = false;
                int max_iter = -1;
 
                size_t argidx;
@@ -601,6 +640,10 @@ struct TechmapPass : public Pass {
                                verilog_frontend += " -I " + args[++argidx];
                                continue;
                        }
+                       if (args[argidx] == "-extern") {
+                               extern_mode = true;
+                               continue;
+                       }
                        break;
                }
                extra_args(args, argidx, design);
@@ -641,12 +684,17 @@ struct TechmapPass : public Pass {
                                celltypeMap[it.first].insert(it.first);
                }
 
-               for (auto module : design->modules()) {
+               worker.module_queue = design->modules();
+               while (!worker.module_queue.empty())
+               {
+                       RTLIL::Module *module = *worker.module_queue.begin();
+                       worker.module_queue.erase(module);
+
                        bool did_something = true;
                        std::set<RTLIL::Cell*> handled_cells;
                        while (did_something) {
                                did_something = false;
-                                       if (worker.techmap_module(design, module, map, handled_cells, celltypeMap, false))
+                                       if (worker.techmap_module(design, module, map, handled_cells, celltypeMap, false, extern_mode))
                                                did_something = true;
                                if (did_something)
                                        module->check();
@@ -699,11 +747,11 @@ struct FlattenPass : public Pass {
                while (did_something) {
                        did_something = false;
                        if (top_mod != NULL) {
-                               if (worker.techmap_module(design, top_mod, design, handled_cells, celltypeMap, true))
+                               if (worker.techmap_module(design, top_mod, design, handled_cells, celltypeMap, true, false))
                                        did_something = true;
                        } else {
                                for (auto mod : design->modules())
-                                       if (worker.techmap_module(design, mod, design, handled_cells, celltypeMap, true))
+                                       if (worker.techmap_module(design, mod, design, handled_cells, celltypeMap, true, false))
                                                did_something = true;
                        }
                }
index 1c60d794fb6306b022b16096f42d9772260f58ce..3f7fc258dcd5fc1828c8ad8ccebb86af384c93ff 100644 (file)
@@ -8,6 +8,32 @@ log_fail()
        printf "%-15s %s %s %s\n" "$1" "$2" "`printf "%20s" "$2" | tr -d a-zA-Z0-9_ | tr ' ' .`" "FAIL."
 }
 
+test_autotest()
+{
+       # Usage:
+       # test_autotest <test_name> <mod_name> <vlog_file> <autotest_cmd_line_options>
+
+       test_name="$1"
+       mod_name="$2"
+       vlog_file="$3"
+       shift 3
+
+       mkdir -p log_test_$test_name
+       rm -rf log_test_$test_name/$mod_name.*
+
+       cp $vlog_file log_test_$test_name/$mod_name.v
+
+       cd log_test_$test_name
+       if bash ../../tools/autotest.sh "$@" $mod_name.v > /dev/null 2>&1; then
+               mv $mod_name.out $mod_name.txt
+               log_pass test_$test_name $mod_name
+       else
+               log_fail test_$test_name $mod_name
+       fi
+
+       cd ..
+}
+
 test_equiv()
 {
        # Usage:
index ad8b3ef61841ce4cd6140ae2d528ae2384dfc147..ba39adb31a30cb75b4d43d058960cbbf4052b2bb 100644 (file)
@@ -6,6 +6,7 @@ source common.sh
 f=$1
 n=$(basename ${f%.v})
 
-test_equiv mapopt "opt -fine; techmap; opt" "-set-def-inputs" $n $f
+test_equiv mapopt_1 "opt -fine; techmap; opt" "-set-def-inputs" $n $f
+test_autotest mapopt_2 $n $f -p "opt; techmap -extern; opt"
 
 exit 0