techmap: Add support for [] wildcards in techmap_celltype.

Fixes #1826.
This commit is contained in:
Marcelina Kościelnicka 2020-08-02 12:31:25 +02:00
parent c39ebe6ae0
commit 522788f016
3 changed files with 36 additions and 8 deletions

View File

@ -1007,7 +1007,9 @@ struct TechmapPass : public Pass {
log("\n"); log("\n");
log("When a module in the map file has the 'techmap_celltype' attribute set, it will\n"); log("When a module in the map file has the 'techmap_celltype' attribute set, it will\n");
log("match cells with a type that match the text value of this attribute. Otherwise\n"); log("match cells with a type that match the text value of this attribute. Otherwise\n");
log("the module name will be used to match the cell.\n"); log("the module name will be used to match the cell. Multiple space-separated cell\n");
log("types can be listed, and wildcards using [] will be expanded (ie. \"$_DFF_[PN]_\"\n");
log("is the same as \"$_DFF_P_ $_DFF_N_\").\n");
log("\n"); log("\n");
log("When a module in the map file has the 'techmap_simplemap' attribute set, techmap\n"); log("When a module in the map file has the 'techmap_simplemap' attribute set, techmap\n");
log("will use 'simplemap' (see 'help simplemap') to map cells matching the module.\n"); log("will use 'simplemap' (see 'help simplemap') to map cells matching the module.\n");
@ -1199,8 +1201,27 @@ struct TechmapPass : public Pass {
for (auto module : map->modules()) { for (auto module : map->modules()) {
if (module->attributes.count(ID::techmap_celltype) && !module->attributes.at(ID::techmap_celltype).bits.empty()) { if (module->attributes.count(ID::techmap_celltype) && !module->attributes.at(ID::techmap_celltype).bits.empty()) {
char *p = strdup(module->attributes.at(ID::techmap_celltype).decode_string().c_str()); char *p = strdup(module->attributes.at(ID::techmap_celltype).decode_string().c_str());
for (char *q = strtok(p, " \t\r\n"); q; q = strtok(nullptr, " \t\r\n")) for (char *q = strtok(p, " \t\r\n"); q; q = strtok(nullptr, " \t\r\n")) {
celltypeMap[RTLIL::escape_id(q)].insert(module->name); std::vector<std::string> queue;
queue.push_back(q);
while (!queue.empty()) {
std::string name = queue.back();
queue.pop_back();
auto pos = name.find('[');
if (pos == std::string::npos) {
// No further expansion.
celltypeMap[RTLIL::escape_id(name)].insert(module->name);
} else {
// Expand [] in this name.
auto epos = name.find(']', pos);
if (epos == std::string::npos)
log_error("Malformed techmap_celltype pattern %s\n", q);
for (size_t i = pos + 1; i < epos; i++) {
queue.push_back(name.substr(0, pos) + name[i] + name.substr(epos + 1, std::string::npos));
}
}
}
}
free(p); free(p);
} else { } else {
IdString module_name = module->name.begins_with("\\$") ? IdString module_name = module->name.begins_with("\\$") ?
@ -1208,8 +1229,15 @@ struct TechmapPass : public Pass {
celltypeMap[module_name].insert(module->name); celltypeMap[module_name].insert(module->name);
} }
} }
for (auto &i : celltypeMap) log_debug("Cell type mappings to use:\n");
for (auto &i : celltypeMap) {
i.second.sort(RTLIL::sort_by_id_str()); i.second.sort(RTLIL::sort_by_id_str());
std::string maps = "";
for (auto &map : i.second)
maps += stringf(" %s", log_id(map));
log_debug(" %s:%s\n", log_id(i.first), maps.c_str());
}
log_debug("\n");
for (auto module : design->modules()) for (auto module : design->modules())
worker.module_queue.insert(module); worker.module_queue.insert(module);

View File

@ -1,5 +1,5 @@
`ifdef DFF `ifdef DFF
(* techmap_celltype = "$_DFF_N_ $_DFF_P_" *) (* techmap_celltype = "$_DFF_[PN]_" *)
module $_DFF_x_(input C, D, output Q); module $_DFF_x_(input C, D, output Q);
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
parameter _TECHMAP_CELLTYPE_ = ""; parameter _TECHMAP_CELLTYPE_ = "";

View File

@ -1,4 +1,4 @@
(* techmap_celltype = "$_DFFE_PP0P_ $_DFFE_PP0N_ $_DFFE_PP1P_ $_DFFE_PP1N_ $_DFFE_PN0P_ $_DFFE_PN0N_ $_DFFE_PN1P_ $_DFFE_PN1N_ $_DFFE_NP0P_ $_DFFE_NP0N_ $_DFFE_NP1P_ $_DFFE_NP1N_ $_DFFE_NN0P_ $_DFFE_NN0N_ $_DFFE_NN1P_ $_DFFE_NN1N_" *) (* techmap_celltype = "$_DFFE_[PN][PN][01][PN]_" *)
module \$_DFFE_xxxx_ (input D, C, R, E, output Q); module \$_DFFE_xxxx_ (input D, C, R, E, output Q);
parameter _TECHMAP_CELLTYPE_ = ""; parameter _TECHMAP_CELLTYPE_ = "";
@ -17,7 +17,7 @@ module \$_DFFE_xxxx_ (input D, C, R, E, output Q);
endmodule endmodule
(* techmap_celltype = "$_SDFFE_PP0P_ $_SDFFE_PP0N_ $_SDFFE_PP1P_ $_SDFFE_PP1N_ $_SDFFE_PN0P_ $_SDFFE_PN0N_ $_SDFFE_PN1P_ $_SDFFE_PN1N_ $_SDFFE_NP0P_ $_SDFFE_NP0N_ $_SDFFE_NP1P_ $_SDFFE_NP1N_ $_SDFFE_NN0P_ $_SDFFE_NN0N_ $_SDFFE_NN1P_ $_SDFFE_NN1N_" *) (* techmap_celltype = "$_SDFFE_[PN][PN][01][PN]_" *)
module \$_SDFFE_xxxx_ (input D, C, R, E, output Q); module \$_SDFFE_xxxx_ (input D, C, R, E, output Q);
parameter _TECHMAP_CELLTYPE_ = ""; parameter _TECHMAP_CELLTYPE_ = "";
@ -36,7 +36,7 @@ module \$_SDFFE_xxxx_ (input D, C, R, E, output Q);
endmodule endmodule
(* techmap_celltype = "$_SDFFCE_PP0P_ $_SDFFCE_PP0N_ $_SDFFCE_PP1P_ $_SDFFCE_PP1N_ $_SDFFCE_PN0P_ $_SDFFCE_PN0N_ $_SDFFCE_PN1P_ $_SDFFCE_PN1N_ $_SDFFCE_NP0P_ $_SDFFCE_NP0N_ $_SDFFCE_NP1P_ $_SDFFCE_NP1N_ $_SDFFCE_NN0P_ $_SDFFCE_NN0N_ $_SDFFCE_NN1P_ $_SDFFCE_NN1N_" *) (* techmap_celltype = "$_SDFFCE_[PN][PN][01][PN]_" *)
module \$_SDFFCE_xxxx_ (input D, C, R, E, output Q); module \$_SDFFCE_xxxx_ (input D, C, R, E, output Q);
parameter _TECHMAP_CELLTYPE_ = ""; parameter _TECHMAP_CELLTYPE_ = "";