36 #if defined(__APPLE__)
45 using namespace AST_INTERNAL;
55 namespace AST_INTERNAL {
70 #define X(_item) case _item: return #_item;
168 if (attributes.count(
id) == 0)
171 AstNode *attr = attributes.at(
id);
173 log_error(
"Attribute `%s' with non-constant value at %s:%d!\n",
192 range_swapped =
false;
202 children.push_back(child1);
204 children.push_back(child2);
215 it.second = it.second->
clone();
233 for (
auto &it : children)
237 for (
auto &it : attributes)
258 std::string type_name =
type2str(type);
259 fprintf(f,
"%s%s <%s:%d>", indent.c_str(), type_name.c_str(), filename.c_str(), linenum);
262 fprintf(f,
" [%p -> %p]",
this, id2ast);
264 fprintf(f,
" [%p]",
this);
267 fprintf(f,
" str='%s'", str.c_str());
269 fprintf(f,
" bits='");
270 for (
size_t i = bits.size(); i > 0; i--)
271 fprintf(f,
"%c", bits[i-1] ==
RTLIL::S0 ?
'0' :
275 fprintf(f,
"'(%d)",
GetSize(bits));
278 fprintf(f,
" input");
280 fprintf(f,
" output");
284 fprintf(f,
" signed");
286 fprintf(f,
" port=%d", port_id);
287 if (range_valid || range_left != -1 || range_right != 0)
288 fprintf(f,
" %srange=[%d:%d]%s", range_swapped ?
"swapped_" :
"", range_left, range_right, range_valid ?
"" :
"!");
290 fprintf(f,
" int=%u", (
int)integer);
292 fprintf(f,
" real=%e", realvalue);
293 if (!multirange_dimensions.empty()) {
294 fprintf(f,
" multirange=[");
295 for (
int v : multirange_dimensions)
296 fprintf(f,
" %d", v);
301 for (
auto &it : attributes) {
302 fprintf(f,
"%s ATTR %s:\n", indent.c_str(), it.first.c_str());
303 it.second->dumpAst(f, indent +
" ");
306 for (
size_t i = 0; i < children.size(); i++)
307 children[i]->dumpAst(f, indent +
" ");
311 static std::string
id2vl(std::string txt)
313 if (txt.size() > 1 && txt[0] ==
'\\')
315 for (
size_t i = 0; i < txt.size(); i++) {
316 if (
'A' <= txt[i] && txt[i] <=
'Z')
continue;
317 if (
'a' <= txt[i] && txt[i] <=
'z')
continue;
318 if (
'0' <= txt[i] && txt[i] <=
'9')
continue;
319 if (txt[i] ==
'_')
continue;
320 txt =
"\\" + txt +
" ";
331 std::vector<AstNode*> rem_children1, rem_children2;
339 for (
auto &it : attributes) {
340 fprintf(f,
"%s" "(* %s = ", indent.c_str(),
id2vl(it.first.str()).c_str());
341 it.second->dumpVlog(f,
"");
342 fprintf(f,
" *)%s", indent.empty() ?
"" :
"\n");
348 fprintf(f,
"%s" "module %s(", indent.c_str(),
id2vl(str).c_str());
349 for (
auto child : children)
350 if (child->type ==
AST_WIRE && (child->is_input || child->is_output)) {
351 fprintf(f,
"%s%s", first ?
"" :
", ",
id2vl(child->str).c_str());
356 for (
auto child : children)
358 child->dumpVlog(f, indent +
" ");
360 rem_children1.push_back(child);
362 for (
auto child : rem_children1)
364 child->dumpVlog(f, indent +
" ");
366 rem_children2.push_back(child);
367 rem_children1.clear();
369 for (
auto child : rem_children2)
371 child->dumpVlog(f, indent +
" ");
373 rem_children1.push_back(child);
374 rem_children2.clear();
376 for (
auto child : rem_children1)
377 child->dumpVlog(f, indent +
" ");
378 rem_children1.clear();
380 fprintf(f,
"%s" "endmodule\n", indent.c_str());
384 if (is_input && is_output)
385 fprintf(f,
"%s" "inout", indent.c_str());
387 fprintf(f,
"%s" "input", indent.c_str());
389 fprintf(f,
"%s" "output", indent.c_str());
391 fprintf(f,
"%s" "wire", indent.c_str());
393 fprintf(f,
"%s" "reg", (is_input || is_output) ?
" " : indent.c_str());
395 fprintf(f,
" signed");
396 for (
auto child : children) {
398 child->dumpVlog(f,
"");
400 fprintf(f,
" %s",
id2vl(str).c_str());
405 fprintf(f,
"%s" "memory", indent.c_str());
407 fprintf(f,
" signed");
408 for (
auto child : children) {
410 child->dumpVlog(f,
"");
412 fprintf(f,
" %s",
id2vl(str).c_str());
420 fprintf(f,
"[%d:%d]", range_left, range_right);
422 for (
auto child : children) {
423 fprintf(f,
"%c", first ?
'[' :
':');
424 child->dumpVlog(f,
"");
432 fprintf(f,
"%s" "always @(", indent.c_str());
433 for (
auto child : children) {
438 child->dumpVlog(f,
"");
442 for (
auto child : children) {
444 child->dumpVlog(f, indent +
" ");
449 fprintf(f,
"%s" "initial\n", indent.c_str());
450 for (
auto child : children) {
452 child->dumpVlog(f, indent +
" ");
460 fprintf(f,
"posedge ");
462 fprintf(f,
"negedge ");
463 for (
auto child : children)
464 child->dumpVlog(f,
"");
468 fprintf(f,
"%s",
id2vl(str).c_str());
469 for (
auto child : children)
470 child->dumpVlog(f,
"");
475 fprintf(f,
"\"%s\"", str.c_str());
476 else if (bits.size() == 32)
483 fprintf(f,
"%e", realvalue);
487 if (children.size() == 1) {
488 children[0]->dumpVlog(f, indent);
490 fprintf(f,
"%s" "begin\n", indent.c_str());
491 for (
auto child : children)
492 child->dumpVlog(f, indent +
" ");
493 fprintf(f,
"%s" "end\n", indent.c_str());
498 fprintf(f,
"%s" "case (", indent.c_str());
499 children[0]->dumpVlog(f,
"");
501 for (
size_t i = 1; i < children.size(); i++) {
505 fprintf(f,
"%s" "endcase\n", indent.c_str());
509 for (
auto child : children) {
512 child->dumpVlog(f, indent +
" ");
515 fprintf(f,
"%s", first ? indent.c_str() :
", ");
517 fprintf(f,
"default");
519 child->dumpVlog(f,
"");
527 fprintf(f,
"%s", indent.c_str());
528 children[0]->dumpVlog(f,
"");
530 children[1]->dumpVlog(f,
"");
536 for (
auto child : children) {
539 child->dumpVlog(f,
"");
547 children[0]->dumpVlog(f,
"");
549 children[1]->dumpVlog(f,
"");
559 if (0) {
case AST_POS: txt =
"+"; }
560 if (0) {
case AST_NEG: txt =
"-"; }
562 fprintf(f,
"%s(", txt.c_str());
563 children[0]->dumpVlog(f,
"");
575 if (0) {
case AST_LT: txt =
"<"; }
576 if (0) {
case AST_LE: txt =
"<="; }
577 if (0) {
case AST_EQ: txt =
"=="; }
578 if (0) {
case AST_NE: txt =
"!="; }
579 if (0) {
case AST_EQX: txt =
"==="; }
580 if (0) {
case AST_NEX: txt =
"!=="; }
581 if (0) {
case AST_GE: txt =
">="; }
582 if (0) {
case AST_GT: txt =
">"; }
583 if (0) {
case AST_ADD: txt =
"+"; }
584 if (0) {
case AST_SUB: txt =
"-"; }
585 if (0) {
case AST_MUL: txt =
"*"; }
586 if (0) {
case AST_DIV: txt =
"/"; }
587 if (0) {
case AST_MOD: txt =
"%"; }
588 if (0) {
case AST_POW: txt =
"**"; }
592 children[0]->dumpVlog(f,
"");
593 fprintf(f,
")%s(", txt.c_str());
594 children[1]->dumpVlog(f,
"");
600 children[0]->dumpVlog(f,
"");
602 children[1]->dumpVlog(f,
"");
604 children[2]->dumpVlog(f,
"");
609 std::string type_name =
type2str(type);
610 fprintf(f,
"%s" "/** %s **/%s", indent.c_str(), type_name.c_str(), indent.empty() ?
"" :
"\n");
618 if (type != other.
type)
620 if (children.size() != other.
children.size())
622 if (str != other.
str)
624 if (bits != other.
bits)
630 if (is_reg != other.
is_reg)
648 for (
size_t i = 0; i < children.size(); i++)
649 if (*children[i] != *other.
children[i])
657 return !(*
this == other);
665 for (
auto child : children)
666 if (child->contains(other))
677 for (
int i = 0; i < width; i++) {
693 for (
size_t i = 0; i < 32; i++) {
694 if (i < node->bits.size())
718 std::vector<RTLIL::State> data;
719 data.reserve(str.size() * 8);
720 for (
size_t i = 0; i < str.size(); i++) {
721 unsigned char ch = str[str.size() - i - 1];
722 for (
int j = 0; j < 8; j++) {
735 for (
auto bit : bits)
743 std::vector<RTLIL::State> bits = this->bits;
744 if (width >= 0 && width <
int(bits.size()))
746 if (width >= 0 && width >
int(bits.size())) {
748 if (is_signed && !bits.empty())
749 extbit = bits.back();
750 while (width >
int(bits.size()))
751 bits.push_back(extbit);
758 return bitsAsConst(width, is_signed);
787 for (
auto &bit : bits)
809 for (
int i = 0; i < 64; i++)
811 ret |= uint64_t(1) << i;
833 for (
size_t i = 0; i < val.
bits.size(); i++)
852 double v = round(realvalue);
857 if (!std::isfinite(v)) {
861 bool is_negative = v < 0;
864 for (
int i = 0; i < width; i++, v /= 2)
867 result =
const_neg(result, result,
false,
false, result.
bits.size());
878 log(
"Storing AST representation for module `%s'.\n", ast->
str.c_str());
880 log(
"Generating RTLIL representation for module `%s'.\n", ast->
str.c_str());
884 current_module->name = ast->
str;
891 log(
"Dumping verilog AST before simplification:\n");
893 log(
"--- END OF AST DUMP ---\n");
901 log(
"Dumping verilog AST after simplification:\n");
903 log(
"--- END OF AST DUMP ---\n");
907 log(
"Dumping verilog AST (as requested by dump_vlog option):\n");
909 log(
"--- END OF AST DUMP ---\n");
913 std::vector<AstNode*> new_children;
915 if (child->type ==
AST_WIRE && (child->is_input || child->is_output))
916 new_children.push_back(child);
928 log_error(
"Attribute `%s' with non-constant value at %s:%d!\n",
930 current_module->attributes[attr.first] = attr.second->asAttrConst();
932 for (
size_t i = 0; i < ast->
children.size(); i++) {
937 for (
size_t i = 0; i < ast->
children.size(); i++) {
945 for (
size_t i = 0; i < ast->
children.size(); i++) {
954 current_module->ast = ast_before_simplify;
962 current_module->fixup_ports();
967 void AST::process(
RTLIL::Design *design,
AstNode *ast,
bool dump_ast1,
bool dump_ast2,
bool dump_vlog,
bool nolatches,
bool nomem2reg,
bool mem2reg,
bool lib,
bool noopt,
bool icells,
bool ignore_redef,
bool defer,
bool autowire)
981 std::vector<AstNode*> global_decls;
988 for (
auto n : global_decls)
989 (*it)->children.push_back(
n->clone());
991 if (
flag_icells && (*it)->str.substr(0, 2) ==
"\\$")
992 (*it)->str = (*it)->str.substr(1);
995 (*it)->str =
"$abstract" + (*it)->str;
997 if (design->
has((*it)->str)) {
999 log_error(
"Re-definition of module `%s' at %s:%d!\n",
1000 (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum);
1001 log(
"Ignoring re-definition of module `%s' at %s:%d!\n",
1002 (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum);
1009 global_decls.push_back(*it);
1023 std::string stripped_name = name.
str();
1025 if (stripped_name.substr(0, 9) ==
"$abstract")
1026 stripped_name = stripped_name.substr(9);
1028 log_header(
"Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", stripped_name.c_str());
1043 std::string para_info;
1046 int para_counter = 0;
1047 int orig_parameters_n = parameters.size();
1048 for (
auto it = new_ast->
children.begin(); it != new_ast->
children.end(); it++) {
1053 std::string para_id = child->
str;
1054 if (parameters.count(para_id) > 0) {
1060 parameters.erase(para_id);
1063 para_id =
stringf(
"$%d", para_counter);
1064 if (parameters.count(para_id) > 0) {
1066 goto rewrite_parameter;
1069 if (parameters.size() > 0)
1070 log_error(
"Requested parameter `%s' does not exist in module `%s'!\n", parameters.begin()->first.c_str(), stripped_name.c_str());
1072 std::string modname;
1074 if (orig_parameters_n == 0)
1075 modname = stripped_name;
1076 else if (para_info.size() > 60)
1077 modname =
"$paramod$" +
sha1(para_info) + stripped_name;
1079 modname =
"$paramod" + stripped_name + para_info;
1081 if (!design->
has(modname)) {
1082 new_ast->
str = modname;
1086 log(
"Found cached RTLIL representation for module `%s'.\n", modname.c_str());
1096 new_mod->
name = name;
1104 new_mod->
noopt = noopt;
1105 new_mod->
icells = icells;
1113 int internal_line_num;
1114 void internal_set_line_num(
int n) {
1115 internal_line_num =
n;
1117 int internal_get_line_num() {
1118 return internal_line_num;
std::map< std::string, AstNode * > current_scope
RTLIL::Const bitsAsConst(int width, bool is_signed)
static AstNode * mkconst_int(uint32_t v, bool is_signed, int width=32)
std::string stringf(const char *fmt,...)
static AstModule * process_module(AstNode *ast, bool defer)
AstNode * current_top_block
void add(RTLIL::Module *module)
virtual RTLIL::IdString derive(RTLIL::Design *design, std::map< RTLIL::IdString, RTLIL::Const > parameters)
static AstNode * mkconst_bits(const std::vector< RTLIL::State > &v, bool is_signed)
void log_header(const char *format,...)
static AstNode * mkconst_str(const std::vector< RTLIL::State > &v)
RTLIL::Const asParaConst()
#define YOSYS_NAMESPACE_END
void dumpAst(FILE *f, std::string indent)
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
virtual RTLIL::Module * clone() const
RTLIL::SigSpec genRTLIL(int width_hint=-1, bool sign_hint=false)
void(* set_line_num)(int)
std::map< RTLIL::IdString, AstNode * > attributes
void dumpVlog(FILE *f, std::string indent)
void log_error(const char *format,...)
bool get_bool_attribute(RTLIL::IdString id)
std::string type2str(AstNodeType type)
bool operator==(const AstNode &other) const
void cloneInto(AstNode *other)
RTLIL::SigSpec ignoreThisSignalsInInitial
YOSYS_NAMESPACE_BEGIN std::vector< FILE * > log_files
double asReal(bool is_signed)
int GetSize(RTLIL::Wire *wire)
AstNode(AstNodeType type=AST_NONE, AstNode *child1=NULL, AstNode *child2=NULL)
std::string decode_string() const
#define log_assert(_assert_expr_)
AstNode * current_block_child
static std::string id2vl(std::string txt)
int as_int(bool is_signed=false) const
RTLIL::Module * module(RTLIL::IdString name)
bool has(RTLIL::IdString id) const
bool contains(const AstNode *other) const
std::string current_filename
#define YOSYS_NAMESPACE_BEGIN
bool simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint, bool in_param)
void use_internal_line_num()
AstNode * current_ast_mod
void log(const char *format,...)
std::string sha1(const std::string &string)
std::vector< RTLIL::State > bits
RTLIL::Const const_neg(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
std::vector< AstNode * > children
std::vector< RTLIL::State > bits
void process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool dump_vlog, bool nolatches, bool nomem2reg, bool mem2reg, bool lib, bool noopt, bool icells, bool ignore_redef, bool defer, bool autowire)
const std::map< RTLIL::SigBit, RTLIL::SigBit > * genRTLIL_subst_ptr
AstModule * current_module
uint64_t asInt(bool is_signed)
RTLIL::Const realAsConst(int width)
bool operator!=(const AstNode &other) const
RTLIL::Const asAttrConst()