204 LibertyAst *best_cell =
NULL;
205 std::map<std::string, char> best_cell_ports;
206 int best_cell_pins = 0;
207 double best_cell_area = 0;
209 if (ast->id !=
"library")
210 log_error(
"Format error in liberty file.\n");
212 for (
auto cell : ast->children)
214 if (cell->id !=
"cell" || cell->args.size() != 1)
217 LibertyAst *ff = cell->find(
"ff");
221 std::string cell_clk_pin, cell_set_pin, cell_clr_pin, cell_next_pin;
222 bool cell_clk_pol, cell_set_pol, cell_clr_pol, cell_next_pol;
224 if (!
parse_pin(cell, ff->find(
"clocked_on"), cell_clk_pin, cell_clk_pol) || cell_clk_pol != clkpol)
226 if (!
parse_pin(cell, ff->find(
"next_state"), cell_next_pin, cell_next_pol))
228 if (!
parse_pin(cell, ff->find(
"preset"), cell_set_pin, cell_set_pol) || cell_set_pol != setpol)
230 if (!
parse_pin(cell, ff->find(
"clear"), cell_clr_pin, cell_clr_pol) || cell_clr_pol != clrpol)
233 std::map<std::string, char> this_cell_ports;
234 this_cell_ports[cell_clk_pin] =
'C';
235 this_cell_ports[cell_set_pin] =
'S';
236 this_cell_ports[cell_clr_pin] =
'R';
237 this_cell_ports[cell_next_pin] =
'D';
240 LibertyAst *ar = cell->find(
"area");
241 if (ar !=
NULL && !ar->value.empty())
242 area = atof(ar->value.c_str());
245 bool found_output =
false;
246 for (
auto pin : cell->children)
248 if (pin->id !=
"pin" || pin->args.size() != 1)
251 LibertyAst *dir = pin->find(
"direction");
252 if (dir ==
NULL || dir->value ==
"internal")
256 if (dir->value ==
"input" && this_cell_ports.count(pin->args[0]) == 0)
257 goto continue_cell_loop;
259 LibertyAst *func = pin->find(
"function");
260 if (dir->value ==
"output" && func !=
NULL) {
261 std::string value = func->value;
262 for (
size_t pos = value.find_first_of(
"\" \t"); pos != std::string::npos; pos = value.find_first_of(
"\" \t"))
264 if ((cell_next_pol ==
true && value == ff->args[0]) || (cell_next_pol ==
false && value == ff->args[1])) {
265 this_cell_ports[pin->args[0]] =
'Q';
270 if (this_cell_ports.count(pin->args[0]) == 0)
271 this_cell_ports[pin->args[0]] = 0;
274 if (!found_output || (best_cell !=
NULL && num_pins > best_cell_pins))
277 if (best_cell !=
NULL && num_pins == best_cell_pins && area > best_cell_area)
281 best_cell_pins = num_pins;
282 best_cell_area = area;
283 best_cell_ports.swap(this_cell_ports);
287 if (best_cell !=
NULL) {
288 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());
static std::map< RTLIL::IdString, cell_mapping > cell_mappings
void log_error(const char *format,...)
void log(const char *format,...)
static bool parse_pin(LibertyAst *cell, LibertyAst *attr, std::string &pin_name, bool &pin_pol)