38 while ((
'a' <= expr[id_len] && expr[id_len] <=
'z') || (
'A' <= expr[id_len] && expr[id_len] <=
'Z') ||
39 (
'0' <= expr[id_len] && expr[id_len] <=
'9') || expr[id_len] ==
'.' || expr[id_len] ==
'_') id_len++;
42 log_error(
"Expected identifier at `%s'.\n", expr);
44 if (id_len == 1 && (*expr ==
'0' || *expr ==
'1'))
48 if (!module->
wires_.count(
id))
52 return module->
wires_.at(
id);
92 int top = int(stack.size())-1;
94 if (0 <= top-1 && stack[top].type == 0 && stack[top-1].type ==
'!') {
102 if (0 <= top-1 && stack[top].type ==
'\'' && stack[top-1].type == 0) {
110 if (0 <= top && stack[top].type == 0) {
111 if (next_token.
type ==
'\'')
117 if (0 <= top-2 && stack[top-2].type == 1 && stack[top-1].type ==
'^' && stack[top].type == 1) {
126 if (0 <= top && stack[top].type == 1) {
127 if (next_token.
type ==
'^')
133 if (0 <= top-1 && stack[top-1].type == 2 && stack[top].type == 2) {
141 if (0 <= top-2 && stack[top-2].type == 2 && (stack[top-1].type ==
'*' || stack[top-1].type ==
'&') && stack[top].type == 2) {
150 if (0 <= top && stack[top].type == 2) {
151 if (next_token.
type ==
'*' || next_token.
type ==
'&' || next_token.
type == 0 || next_token.
type ==
'(')
157 if (0 <= top-2 && stack[top-2].type == 3 && (stack[top-1].type ==
'+' || stack[top-1].type ==
'|') && stack[top].type == 3) {
166 if (0 <= top-2 && stack[top-2].type ==
'(' && stack[top-1].type == 3 && stack[top].type ==
')') {
180 const char *orig_expr = expr;
181 std::vector<token_t> stack;
185 if (*expr ==
' ' || *expr ==
'\t' || *expr ==
'\r' || *expr ==
'\n' || *expr ==
'"') {
191 if (*expr ==
'(' || *expr ==
')' || *expr ==
'\'' || *expr ==
'!' || *expr ==
'^' || *expr ==
'*' || *expr ==
'+' || *expr ==
'|')
192 next_token =
token_t(*(expr++));
197 stack.push_back(next_token);
203 for (
size_t i = 0; i < stack.size(); i++)
204 if (stack[i].type < 16)
205 log(
"%3d: %d %s\n",
int(i), stack[i].type,
log_signal(stack[i].sig));
207 log(
"%3d: %c\n",
int(i), stack[i].type);
210 if (stack.size() != 1 || stack.back().type != 3)
211 log_error(
"Parser error in function expr `%s'.\n", orig_expr);
213 return stack.back().sig;
222 bool clk_polarity =
true, clear_polarity =
true, preset_polarity =
true;
224 for (
auto child : node->children) {
225 if (child->id ==
"clocked_on")
227 if (child->id ==
"next_state")
229 if (child->id ==
"clear")
231 if (child->id ==
"preset")
235 if (clk_sig.size() == 0 || data_sig.size() == 0)
236 log_error(
"FF cell %s has no next_state and/or clocked_on attribute.\n",
log_id(module->
name));
238 for (
bool rerun_invert_rollback =
true; rerun_invert_rollback;)
240 rerun_invert_rollback =
false;
242 for (
auto &it : module->
cells_) {
243 if (it.second->type ==
"$_NOT_" && it.second->getPort(
"\\Y") ==
clk_sig) {
244 clk_sig = it.second->getPort(
"\\A");
246 rerun_invert_rollback =
true;
248 if (it.second->type ==
"$_NOT_" && it.second->getPort(
"\\Y") == clear_sig) {
249 clear_sig = it.second->getPort(
"\\A");
250 clear_polarity = !clear_polarity;
251 rerun_invert_rollback =
true;
253 if (it.second->type ==
"$_NOT_" && it.second->getPort(
"\\Y") == preset_sig) {
254 preset_sig = it.second->getPort(
"\\A");
255 preset_polarity = !preset_polarity;
256 rerun_invert_rollback =
true;
266 cell->
setPort(
"\\D", data_sig);
270 if (clear_sig.size() == 0 && preset_sig.size() == 0) {
271 cell->
type =
stringf(
"$_DFF_%c_", clk_polarity ?
'P' :
'N');
274 if (clear_sig.size() == 1 && preset_sig.size() == 0) {
275 cell->
type =
stringf(
"$_DFF_%c%c0_", clk_polarity ?
'P' :
'N', clear_polarity ?
'P' :
'N');
276 cell->
setPort(
"\\R", clear_sig);
279 if (clear_sig.size() == 0 && preset_sig.size() == 1) {
280 cell->
type =
stringf(
"$_DFF_%c%c1_", clk_polarity ?
'P' :
'N', preset_polarity ?
'P' :
'N');
281 cell->
setPort(
"\\R", preset_sig);
284 if (clear_sig.size() == 1 && preset_sig.size() == 1) {
285 cell->
type =
stringf(
"$_DFFSR_%c%c%c_", clk_polarity ?
'P' :
'N', preset_polarity ?
'P' :
'N', clear_polarity ?
'P' :
'N');
286 cell->
setPort(
"\\S", preset_sig);
287 cell->
setPort(
"\\R", clear_sig);
299 bool enable_polarity =
true, clear_polarity =
true, preset_polarity =
true;
301 for (
auto child : node->children) {
302 if (child->id ==
"enable")
304 if (child->id ==
"data_in")
306 if (child->id ==
"clear")
308 if (child->id ==
"preset")
312 if (enable_sig.size() == 0 || data_sig.size() == 0)
313 log_error(
"Latch cell %s has no data_in and/or enable attribute.\n",
log_id(module->
name));
315 for (
bool rerun_invert_rollback =
true; rerun_invert_rollback;)
317 rerun_invert_rollback =
false;
319 for (
auto &it : module->
cells_) {
320 if (it.second->type ==
"$_NOT_" && it.second->getPort(
"\\Y") == enable_sig) {
321 enable_sig = it.second->getPort(
"\\A");
322 enable_polarity = !enable_polarity;
323 rerun_invert_rollback =
true;
325 if (it.second->type ==
"$_NOT_" && it.second->getPort(
"\\Y") == clear_sig) {
326 clear_sig = it.second->getPort(
"\\A");
327 clear_polarity = !clear_polarity;
328 rerun_invert_rollback =
true;
330 if (it.second->type ==
"$_NOT_" && it.second->getPort(
"\\Y") == preset_sig) {
331 preset_sig = it.second->getPort(
"\\A");
332 preset_polarity = !preset_polarity;
333 rerun_invert_rollback =
true;
342 if (clear_sig.size() == 1)
347 if (clear_polarity ==
true || clear_polarity != enable_polarity)
350 inv->
setPort(
"\\A", clear_sig);
353 if (clear_polarity ==
true)
354 clear_negative = inv->
getPort(
"\\Y");
355 if (clear_polarity != enable_polarity)
356 clear_enable = inv->
getPort(
"\\Y");
360 data_gate->
setPort(
"\\A", data_sig);
361 data_gate->
setPort(
"\\B", clear_negative);
365 enable_gate->
setPort(
"\\A", enable_sig);
366 enable_gate->
setPort(
"\\B", clear_enable);
370 if (preset_sig.size() == 1)
375 if (preset_polarity ==
false || preset_polarity != enable_polarity)
378 inv->
setPort(
"\\A", preset_sig);
381 if (preset_polarity ==
false)
382 preset_positive = inv->
getPort(
"\\Y");
383 if (preset_polarity != enable_polarity)
384 preset_enable = inv->
getPort(
"\\Y");
388 data_gate->
setPort(
"\\A", data_sig);
389 data_gate->
setPort(
"\\B", preset_positive);
393 enable_gate->
setPort(
"\\A", enable_sig);
394 enable_gate->
setPort(
"\\B", preset_enable);
399 cell->
setPort(
"\\D", data_sig);
401 cell->
setPort(
"\\E", enable_sig);
410 log(
" read_liberty [filename]\n");
412 log(
"Read cells from liberty file as modules into current design.\n");
415 log(
" only create empty blackbox modules\n");
417 log(
" -ignore_redef\n");
418 log(
" ignore re-definitions of modules. (the default behavior is to\n");
419 log(
" create an error message.)\n");
421 log(
" -ignore_miss_func\n");
422 log(
" ignore cells with missing function specification of outputs\n");
424 log(
" -ignore_miss_dir\n");
425 log(
" ignore cells with a missing or invalid direction\n");
426 log(
" specification on a pin\n");
428 log(
" -setattr <attribute_name>\n");
429 log(
" set the specified attribute (to the value 1) on all loaded modules\n");
435 bool flag_ignore_redef =
false;
436 bool flag_ignore_miss_func =
false;
437 bool flag_ignore_miss_dir =
false;
438 std::vector<std::string> attributes;
443 for (argidx = 1; argidx < args.size(); argidx++) {
444 std::string arg = args[argidx];
449 if (arg ==
"-ignore_redef") {
450 flag_ignore_redef =
true;
453 if (arg ==
"-ignore_miss_func") {
454 flag_ignore_miss_func =
true;
457 if (arg ==
"-ignore_miss_dir") {
458 flag_ignore_miss_dir =
true;
461 if (arg ==
"-setattr" && argidx+1 < args.size()) {
472 for (
auto cell : parser.ast->children)
474 if (cell->id !=
"cell" || cell->args.size() != 1)
479 if (design->
has(cell_name)) {
480 if (flag_ignore_redef)
488 module->
name = cell_name;
491 module->set_bool_attribute(
"\\blackbox");
493 for (
auto &attr : attributes)
494 module->attributes[attr] = 1;
496 for (
auto node : cell->children)
497 if (node->id ==
"pin" && node->args.size() == 1) {
498 LibertyAst *dir = node->find(
"direction");
499 if (!dir || (dir->value !=
"input" && dir->value !=
"output" && dir->value !=
"inout" && dir->value !=
"internal"))
501 if (!flag_ignore_miss_dir)
503 log_error(
"Missing or invalid direction for pin %s of cell %s.\n", node->args.at(0).c_str(),
log_id(module->
name));
505 log(
"Ignoring cell %s with missing or invalid direction for pin %s.\n",
log_id(module->
name), node->args.at(0).c_str());
510 if (!flag_lib || dir->value !=
"internal")
514 for (
auto node : cell->children)
517 if (node->id ==
"ff" && node->args.size() == 2)
519 if (node->id ==
"latch" && node->args.size() == 2)
523 if (node->id ==
"pin" && node->args.size() == 1)
525 LibertyAst *dir = node->find(
"direction");
527 if (flag_lib && dir->value ==
"internal")
532 if (dir && dir->value ==
"inout") {
537 if (dir && dir->value ==
"input") {
542 if (dir && dir->value ==
"output")
548 LibertyAst *func = node->find(
"function");
551 if (!flag_ignore_miss_func)
572 log(
"Imported %d cell types from liberty file.\n", cell_count);
static std::string next_token(bool pass_newline=false)
std::string stringf(const char *fmt,...)
RTLIL::Cell * addCell(RTLIL::IdString name, RTLIL::IdString type)
void add(RTLIL::Module *module)
void log_header(const char *format,...)
#define YOSYS_NAMESPACE_END
std::map< RTLIL::IdString, RTLIL::Wire * > wires_
static std::string unescape_id(std::string str)
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
token_t(char t, RTLIL::SigSpec s)
static RTLIL::SigSpec parse_func_identifier(RTLIL::Module *module, const char *&expr)
void log_error(const char *format,...)
static RTLIL::SigSpec create_and_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B)
static void create_latch(RTLIL::Module *module, LibertyAst *node)
static void create_ff(RTLIL::Module *module, LibertyAst *node)
LibertyFrontend LibertyFrontend
static std::string escape_id(std::string str)
void connect(const RTLIL::SigSig &conn)
const RTLIL::SigSpec & getPort(RTLIL::IdString portname) const
static RTLIL::SigSpec create_inv_cell(RTLIL::Module *module, RTLIL::SigSpec A)
static RTLIL::SigSpec parse_func_expr(RTLIL::Module *module, const char *expr)
#define log_assert(_assert_expr_)
RTLIL::Wire * addWire(RTLIL::IdString name, int width=1)
bool has(RTLIL::IdString id) const
std::map< RTLIL::IdString, RTLIL::Cell * > cells_
#define YOSYS_NAMESPACE_BEGIN
void log(const char *format,...)
virtual void execute(std::istream *&f, std::string filename, std::vector< std::string > args, RTLIL::Design *design)
static RTLIL::SigSpec create_or_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B)
static bool parse_func_reduce(RTLIL::Module *module, std::vector< token_t > &stack, token_t next_token)
static RTLIL::SigSpec create_xor_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B)
std::pair< SigSpec, SigSpec > SigSig
const char * log_id(RTLIL::IdString str)
void extra_args(std::istream *&f, std::string &filename, std::vector< std::string > args, size_t argidx)