aboutsummaryrefslogtreecommitdiffstats
path: root/passes/techmap/dfflibmap.cc
diff options
context:
space:
mode:
Diffstat (limited to 'passes/techmap/dfflibmap.cc')
-rw-r--r--passes/techmap/dfflibmap.cc113
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