diff options
Diffstat (limited to 'passes/techmap/dfflibmap.cc')
-rw-r--r-- | passes/techmap/dfflibmap.cc | 113 |
1 files changed, 73 insertions, 40 deletions
diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index 07993b868..b0318a0b3 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -23,7 +23,8 @@ #include <string.h> #include <errno.h> -using namespace PASS_DFFLIBMAP; +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN struct cell_mapping { std::string cell_name; @@ -102,12 +103,12 @@ 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; int best_cell_pins = 0; - float best_cell_area = 0; + double best_cell_area = 0; if (ast->id != "library") log_error("Format error in liberty file.\n"); @@ -143,7 +144,7 @@ static void find_cell(LibertyAst *ast, std::string cell_type, bool clkpol, bool this_cell_ports[cell_rst_pin] = 'R'; this_cell_ports[cell_next_pin] = 'D'; - float area = 0; + double area = 0; LibertyAst *ar = cell->find("area"); if (ar != NULL && !ar->value.empty()) area = atof(ar->value.c_str()); @@ -192,18 +193,27 @@ 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; int best_cell_pins = 0; - float best_cell_area = 0; + double best_cell_area = 0; if (ast->id != "library") log_error("Format error in liberty file.\n"); @@ -235,7 +245,7 @@ static void find_cell_sr(LibertyAst *ast, std::string cell_type, bool clkpol, bo this_cell_ports[cell_clr_pin] = 'R'; this_cell_ports[cell_next_pin] = 'D'; - float area = 0; + double area = 0; LibertyAst *ar = cell->find("area"); if (ar != NULL && !ar->value.empty()) area = atof(ar->value.c_str()); @@ -284,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; + } } } @@ -346,8 +365,12 @@ static void map_sr_to_arst(const char *from, const char *to) if (!cell_mappings.count(from) || cell_mappings.count(to) > 0) return; - char from_clk_pol = from[8], from_set_pol = from[9], from_clr_pol = from[10]; - char to_clk_pol = to[6], to_rst_pol = to[7], to_rst_val = to[8]; + char from_clk_pol YS_ATTRIBUTE(unused) = from[8]; + char from_set_pol = from[9]; + char from_clr_pol = from[10]; + char to_clk_pol YS_ATTRIBUTE(unused) = to[6]; + char to_rst_pol YS_ATTRIBUTE(unused) = to[7]; + char to_rst_val = to[8]; log_assert(from_clk_pol == to_clk_pol); log_assert(to_rst_pol == from_set_pol && to_rst_pol == from_clr_pol); @@ -383,7 +406,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()); @@ -402,7 +425,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; @@ -411,7 +434,7 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module) } else if (port.second == 'q') { RTLIL::SigSpec old_sig = cell_connections[std::string("\\") + char(port.second - ('a' - 'A'))]; - sig = module->addWire(NEW_ID, SIZE(old_sig)); + sig = module->addWire(NEW_ID, GetSize(old_sig)); module->addNotGate(NEW_ID, sig, old_sig); } else if ('a' <= port.second && port.second <= 'z') { @@ -438,7 +461,7 @@ struct DfflibmapPass : public Pass { virtual void help() { log("\n"); - log(" dfflibmap -liberty <file> [selection]\n"); + log(" dfflibmap [-prepare] -liberty <file> [selection]\n"); log("\n"); log("Map internal flip-flop cells to the flip-flop cells in the technology\n"); log("library specified in the given liberty file.\n"); @@ -446,12 +469,17 @@ struct DfflibmapPass : public Pass { log("This pass may add inverters as needed. Therefore it is recommended to\n"); log("first run this pass and then map the logic paths to the target technology.\n"); log("\n"); + log("When called with -prepare, this command will convert the internal FF cells\n"); + log("to the internal cell types that best match the cells found in the given\n"); + log("liberty file.\n"); + log("\n"); } virtual void execute(std::vector<std::string> args, RTLIL::Design *design) { 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++) @@ -461,6 +489,10 @@ struct DfflibmapPass : public Pass { liberty_file = args[++argidx]; continue; } + if (arg == "-prepare") { + prepare_mode = true; + continue; + } break; } extra_args(args, argidx, design); @@ -475,26 +507,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 @@ -532,9 +564,10 @@ 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(); } } DfflibmapPass; +PRIVATE_NAMESPACE_END |