diff options
-rw-r--r-- | passes/techmap/dfflibmap.cc | 85 |
1 files changed, 54 insertions, 31 deletions
diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index a02eafb96..58f0c2542 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -103,7 +103,7 @@ static bool parse_pin(LibertyAst *cell, LibertyAst *attr, std::string &pin_name, return false; } -static void find_cell(LibertyAst *ast, std::string cell_type, bool clkpol, bool has_reset, bool rstpol, bool rstval) +static void find_cell(LibertyAst *ast, std::string cell_type, bool clkpol, bool has_reset, bool rstpol, bool rstval, bool prepare_mode) { LibertyAst *best_cell = NULL; std::map<std::string, char> best_cell_ports; @@ -193,13 +193,22 @@ static void find_cell(LibertyAst *ast, std::string cell_type, bool clkpol, bool } if (best_cell != NULL) { - log(" cell %s (pins=%d, area=%.2f) is a direct match for cell type %s.\n", best_cell->args[0].c_str(), best_cell_pins, best_cell_area, cell_type.substr(1).c_str()); - cell_mappings[cell_type].cell_name = best_cell->args[0]; - cell_mappings[cell_type].ports = best_cell_ports; + log(" cell %s (pins=%d, area=%.2f) is a direct match for cell type %s.\n", best_cell->args[0].c_str(), best_cell_pins, best_cell_area, cell_type.c_str()); + if (prepare_mode) { + cell_mappings[cell_type].cell_name = cell_type; + cell_mappings[cell_type].ports["C"] = 'C'; + if (has_reset) + cell_mappings[cell_type].ports["R"] = 'R'; + cell_mappings[cell_type].ports["D"] = 'D'; + cell_mappings[cell_type].ports["Q"] = 'Q'; + } else { + cell_mappings[cell_type].cell_name = best_cell->args[0]; + cell_mappings[cell_type].ports = best_cell_ports; + } } } -static void find_cell_sr(LibertyAst *ast, std::string cell_type, bool clkpol, bool setpol, bool clrpol) +static void find_cell_sr(LibertyAst *ast, std::string cell_type, bool clkpol, bool setpol, bool clrpol, bool prepare_mode) { LibertyAst *best_cell = NULL; std::map<std::string, char> best_cell_ports; @@ -285,9 +294,18 @@ static void find_cell_sr(LibertyAst *ast, std::string cell_type, bool clkpol, bo } if (best_cell != NULL) { - log(" cell %s (pins=%d, area=%.2f) is a direct match for cell type %s.\n", best_cell->args[0].c_str(), best_cell_pins, best_cell_area, cell_type.substr(1).c_str()); - cell_mappings[cell_type].cell_name = best_cell->args[0]; - cell_mappings[cell_type].ports = best_cell_ports; + log(" cell %s (pins=%d, area=%.2f) is a direct match for cell type %s.\n", best_cell->args[0].c_str(), best_cell_pins, best_cell_area, cell_type.c_str()); + if (prepare_mode) { + cell_mappings[cell_type].cell_name = cell_type; + cell_mappings[cell_type].ports["C"] = 'C'; + cell_mappings[cell_type].ports["S"] = 'S'; + cell_mappings[cell_type].ports["R"] = 'R'; + cell_mappings[cell_type].ports["D"] = 'D'; + cell_mappings[cell_type].ports["Q"] = 'Q'; + } else { + cell_mappings[cell_type].cell_name = best_cell->args[0]; + cell_mappings[cell_type].ports = best_cell_ports; + } } } @@ -384,7 +402,7 @@ static void map_sr_to_arst(const char *from, const char *to) } } -static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module) +static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module, bool prepare_mode) { log("Mapping DFF cells in module `%s':\n", module->name.c_str()); @@ -403,7 +421,7 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module) module->remove(cell); cell_mapping &cm = cell_mappings[cell_type]; - RTLIL::Cell *new_cell = module->addCell(cell_name, "\\" + cm.cell_name); + RTLIL::Cell *new_cell = module->addCell(cell_name, prepare_mode ? cm.cell_name : "\\" + cm.cell_name); for (auto &port : cm.ports) { RTLIL::SigSpec sig; @@ -453,6 +471,7 @@ struct DfflibmapPass : public Pass { log_header("Executing DFFLIBMAP pass (mapping DFF cells to sequential cells from liberty file).\n"); std::string liberty_file; + bool prepare_mode = false; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) @@ -462,6 +481,10 @@ struct DfflibmapPass : public Pass { liberty_file = args[++argidx]; continue; } + if (arg == "-prepare") { + prepare_mode = true; + continue; + } break; } extra_args(args, argidx, design); @@ -476,26 +499,26 @@ struct DfflibmapPass : public Pass { LibertyParser libparser(f); f.close(); - find_cell(libparser.ast, "$_DFF_N_", false, false, false, false); - find_cell(libparser.ast, "$_DFF_P_", true, false, false, false); - - find_cell(libparser.ast, "$_DFF_NN0_", false, true, false, false); - find_cell(libparser.ast, "$_DFF_NN1_", false, true, false, true); - find_cell(libparser.ast, "$_DFF_NP0_", false, true, true, false); - find_cell(libparser.ast, "$_DFF_NP1_", false, true, true, true); - find_cell(libparser.ast, "$_DFF_PN0_", true, true, false, false); - find_cell(libparser.ast, "$_DFF_PN1_", true, true, false, true); - find_cell(libparser.ast, "$_DFF_PP0_", true, true, true, false); - find_cell(libparser.ast, "$_DFF_PP1_", true, true, true, true); - - find_cell_sr(libparser.ast, "$_DFFSR_NNN_", false, false, false); - find_cell_sr(libparser.ast, "$_DFFSR_NNP_", false, false, true); - find_cell_sr(libparser.ast, "$_DFFSR_NPN_", false, true, false); - find_cell_sr(libparser.ast, "$_DFFSR_NPP_", false, true, true); - find_cell_sr(libparser.ast, "$_DFFSR_PNN_", true, false, false); - find_cell_sr(libparser.ast, "$_DFFSR_PNP_", true, false, true); - find_cell_sr(libparser.ast, "$_DFFSR_PPN_", true, true, false); - find_cell_sr(libparser.ast, "$_DFFSR_PPP_", true, true, true); + find_cell(libparser.ast, "$_DFF_N_", false, false, false, false, prepare_mode); + find_cell(libparser.ast, "$_DFF_P_", true, false, false, false, prepare_mode); + + find_cell(libparser.ast, "$_DFF_NN0_", false, true, false, false, prepare_mode); + find_cell(libparser.ast, "$_DFF_NN1_", false, true, false, true, prepare_mode); + find_cell(libparser.ast, "$_DFF_NP0_", false, true, true, false, prepare_mode); + find_cell(libparser.ast, "$_DFF_NP1_", false, true, true, true, prepare_mode); + find_cell(libparser.ast, "$_DFF_PN0_", true, true, false, false, prepare_mode); + find_cell(libparser.ast, "$_DFF_PN1_", true, true, false, true, prepare_mode); + find_cell(libparser.ast, "$_DFF_PP0_", true, true, true, false, prepare_mode); + find_cell(libparser.ast, "$_DFF_PP1_", true, true, true, true, prepare_mode); + + find_cell_sr(libparser.ast, "$_DFFSR_NNN_", false, false, false, prepare_mode); + find_cell_sr(libparser.ast, "$_DFFSR_NNP_", false, false, true, prepare_mode); + find_cell_sr(libparser.ast, "$_DFFSR_NPN_", false, true, false, prepare_mode); + find_cell_sr(libparser.ast, "$_DFFSR_NPP_", false, true, true, prepare_mode); + find_cell_sr(libparser.ast, "$_DFFSR_PNN_", true, false, false, prepare_mode); + find_cell_sr(libparser.ast, "$_DFFSR_PNP_", true, false, true, prepare_mode); + find_cell_sr(libparser.ast, "$_DFFSR_PPN_", true, true, false, prepare_mode); + find_cell_sr(libparser.ast, "$_DFFSR_PPP_", true, true, true, prepare_mode); // try to implement as many cells as possible just by inverting // the SET and RESET pins. If necessary, implement cell types @@ -533,7 +556,7 @@ struct DfflibmapPass : public Pass { for (auto &it : design->modules_) if (design->selected(it.second) && !it.second->get_bool_attribute("\\blackbox")) - dfflibmap(design, it.second); + dfflibmap(design, it.second, prepare_mode); cell_mappings.clear(); } |