Add "stat -tech xilinx"
authorClifford Wolf <clifford@clifford.at>
Sat, 11 May 2019 07:24:52 +0000 (09:24 +0200)
committerClifford Wolf <clifford@clifford.at>
Sat, 11 May 2019 07:24:52 +0000 (09:24 +0200)
Signed-off-by: Clifford Wolf <clifford@clifford.at>
passes/cmds/stat.cc
techlibs/xilinx/synth_xilinx.cc

index 54f4ea817b170eeb05d461c583fc3924b9f7a235..d22685b62954bfd9b17888618a220e6038c4e634 100644 (file)
@@ -37,7 +37,9 @@ struct statdata_t
        STAT_INT_MEMBERS
        #undef X
        double area;
+       string tech;
 
+       std::map<RTLIL::IdString, int> techinfo;
        std::map<RTLIL::IdString, int, RTLIL::sort_by_id_str> num_cells_by_type;
        std::set<RTLIL::IdString> unknown_cell_area;
 
@@ -70,8 +72,10 @@ struct statdata_t
        #undef X
        }
 
-       statdata_t(RTLIL::Design *design, RTLIL::Module *mod, bool width_mode, const dict<IdString, double> &cell_area)
+       statdata_t(RTLIL::Design *design, RTLIL::Module *mod, bool width_mode, const dict<IdString, double> &cell_area, string techname)
        {
+               tech = techname;
+
        #define X(_name) _name = 0;
                STAT_NUMERIC_MEMBERS
        #undef X
@@ -153,7 +157,8 @@ struct statdata_t
                log("   Number of processes:         %6d\n", num_processes);
                log("   Number of cells:             %6d\n", num_cells);
                for (auto &it : num_cells_by_type)
-                       log("     %-26s %6d\n", RTLIL::id2cstr(it.first), it.second);
+                       if (it.second)
+                               log("     %-26s %6d\n", RTLIL::id2cstr(it.first), it.second);
 
                if (!unknown_cell_area.empty()) {
                        log("\n");
@@ -165,6 +170,59 @@ struct statdata_t
                        log("\n");
                        log("   Chip area for %smodule '%s': %f\n", (top_mod) ? "top " : "", mod_name.c_str(), area);
                }
+
+               if (tech == "xilinx")
+               {
+                       int lut6_cnt = num_cells_by_type["\\LUT6"];
+                       int lut5_cnt = num_cells_by_type["\\LUT5"];
+                       int lut4_cnt = num_cells_by_type["\\LUT4"];
+                       int lut3_cnt = num_cells_by_type["\\LUT3"];
+                       int lut2_cnt = num_cells_by_type["\\LUT2"];
+                       int lut1_cnt = num_cells_by_type["\\LUT1"];
+                       int lc_cnt = 0;
+
+                       lc_cnt += lut6_cnt;
+
+                       lc_cnt += lut5_cnt;
+                       if (lut1_cnt) {
+                               int cnt = std::min(lut5_cnt, lut1_cnt);
+                               lut5_cnt -= cnt;
+                               lut1_cnt -= cnt;
+                       }
+
+                       lc_cnt += lut4_cnt;
+                       if (lut1_cnt) {
+                               int cnt = std::min(lut4_cnt, lut1_cnt);
+                               lut4_cnt -= cnt;
+                               lut1_cnt -= cnt;
+                       }
+                       if (lut2_cnt) {
+                               int cnt = std::min(lut4_cnt, lut2_cnt);
+                               lut4_cnt -= cnt;
+                               lut2_cnt -= cnt;
+                       }
+
+                       lc_cnt += lut3_cnt;
+                       if (lut1_cnt) {
+                               int cnt = std::min(lut3_cnt, lut1_cnt);
+                               lut3_cnt -= cnt;
+                               lut1_cnt -= cnt;
+                       }
+                       if (lut2_cnt) {
+                               int cnt = std::min(lut3_cnt, lut2_cnt);
+                               lut3_cnt -= cnt;
+                               lut2_cnt -= cnt;
+                       }
+                       if (lut3_cnt) {
+                               int cnt = (lut3_cnt + 1) / 2;
+                               lut3_cnt -= cnt;
+                       }
+
+                       lc_cnt += (lut2_cnt + lut1_cnt + 1) / 2;
+
+                       log("\n");
+                       log("   Estimated number of LCs: %10d\n", lc_cnt);
+               }
        }
 };
 
@@ -226,6 +284,10 @@ struct StatPass : public Pass {
                log("    -liberty <liberty_file>\n");
                log("        use cell area information from the provided liberty file\n");
                log("\n");
+               log("    -tech <technology>\n");
+               log("        print area estemate for the specified technology. Corrently supported\n");
+               log("        calues for <technology>: xilinx\n");
+               log("\n");
                log("    -width\n");
                log("        annotate internal cell types with their word width.\n");
                log("        e.g. $add_8 for an 8 bit wide $add cell.\n");
@@ -239,6 +301,7 @@ struct StatPass : public Pass {
                RTLIL::Module *top_mod = NULL;
                std::map<RTLIL::IdString, statdata_t> mod_stat;
                dict<IdString, double> cell_area;
+               string techname;
 
                size_t argidx;
                for (argidx = 1; argidx < args.size(); argidx++)
@@ -253,6 +316,10 @@ struct StatPass : public Pass {
                                read_liberty_cellarea(cell_area, liberty_file);
                                continue;
                        }
+                       if (args[argidx] == "-tech" && argidx+1 < args.size()) {
+                               techname = args[++argidx];
+                               continue;
+                       }
                        if (args[argidx] == "-top" && argidx+1 < args.size()) {
                                if (design->modules_.count(RTLIL::escape_id(args[argidx+1])) == 0)
                                        log_cmd_error("Can't find module %s.\n", args[argidx+1].c_str());
@@ -263,13 +330,16 @@ struct StatPass : public Pass {
                }
                extra_args(args, argidx, design);
 
+               if (techname != "" && techname != "xilinx")
+                       log_cmd_error("Unsupported technology: '%s'\n", techname.c_str());
+
                for (auto mod : design->selected_modules())
                {
                        if (!top_mod && design->full_selection())
                                if (mod->get_bool_attribute("\\top"))
                                        top_mod = mod;
 
-                       statdata_t data(design, mod, width_mode, cell_area);
+                       statdata_t data(design, mod, width_mode, cell_area, techname);
                        mod_stat[mod->name] = data;
 
                        log("\n");
index b022972c925666186cb08922b124bf6dc7af545c..c20cac09b5aa521a40af7d1bd293cc576d3a7655 100644 (file)
@@ -269,7 +269,7 @@ struct SynthXilinxPass : public ScriptPass
 
                if (check_label("check")) {
                        run("hierarchy -check");
-                       run("stat");
+                       run("stat -tech xilinx");
                        run("check -noinit");
                }