diff options
Diffstat (limited to 'frontends/ast/ast.cc')
-rw-r--r-- | frontends/ast/ast.cc | 66 |
1 files changed, 42 insertions, 24 deletions
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 68b3327f9..57de725d8 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -2,11 +2,11 @@ * yosys -- Yosys Open SYnthesis Suite * * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> - * + * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. - * + * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR @@ -30,15 +30,6 @@ #include "libs/sha1/sha1.h" #include "ast.h" -#include <sstream> -#include <stdarg.h> - -#if defined(__APPLE__) -# include <cmath> -#else -# include <math.h> -#endif - YOSYS_NAMESPACE_BEGIN using namespace AST; @@ -53,12 +44,12 @@ namespace AST { // instanciate global variables (private API) namespace AST_INTERNAL { - bool flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_autowire; + bool flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomeminit, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_autowire; AstNode *current_ast, *current_ast_mod; std::map<std::string, AstNode*> current_scope; const dict<RTLIL::SigBit, RTLIL::SigBit> *genRTLIL_subst_ptr = NULL; RTLIL::SigSpec ignoreThisSignalsInInitial; - AstNode *current_top_block, *current_block, *current_block_child; + AstNode *current_always, *current_top_block, *current_block, *current_block_child; AstModule *current_module; } @@ -90,6 +81,7 @@ std::string AST::type2str(AstNodeType type) X(AST_IDENTIFIER) X(AST_PREFIX) X(AST_ASSERT) + X(AST_ASSUME) X(AST_FCALL) X(AST_TO_BITS) X(AST_TO_SIGNED) @@ -132,6 +124,7 @@ std::string AST::type2str(AstNodeType type) X(AST_TERNARY) X(AST_MEMRD) X(AST_MEMWR) + X(AST_MEMINIT) X(AST_TCALL) X(AST_ASSIGN) X(AST_CELL) @@ -144,6 +137,8 @@ std::string AST::type2str(AstNodeType type) X(AST_ASSIGN_LE) X(AST_CASE) X(AST_COND) + X(AST_CONDX) + X(AST_CONDZ) X(AST_DEFAULT) X(AST_FOR) X(AST_WHILE) @@ -156,6 +151,7 @@ std::string AST::type2str(AstNodeType type) X(AST_POSEDGE) X(AST_NEGEDGE) X(AST_EDGE) + X(AST_PACKAGE) #undef X default: log_abort(); @@ -327,7 +323,7 @@ static std::string id2vl(std::string txt) return txt; } -// dump AST node as verilog pseudo-code +// dump AST node as Verilog pseudo-code void AstNode::dumpVlog(FILE *f, std::string indent) { bool first = true; @@ -499,7 +495,12 @@ void AstNode::dumpVlog(FILE *f, std::string indent) break; case AST_CASE: - fprintf(f, "%s" "case (", indent.c_str()); + if (!children.empty() && children[0]->type == AST_CONDX) + fprintf(f, "%s" "casex (", indent.c_str()); + else if (!children.empty() && children[0]->type == AST_CONDZ) + fprintf(f, "%s" "casez (", indent.c_str()); + else + fprintf(f, "%s" "case (", indent.c_str()); children[0]->dumpVlog(f, ""); fprintf(f, ")\n"); for (size_t i = 1; i < children.size(); i++) { @@ -510,6 +511,8 @@ void AstNode::dumpVlog(FILE *f, std::string indent) break; case AST_COND: + case AST_CONDX: + case AST_CONDZ: for (auto child : children) { if (child->type == AST_BLOCK) { fprintf(f, ":\n"); @@ -553,7 +556,7 @@ void AstNode::dumpVlog(FILE *f, std::string indent) children[1]->dumpVlog(f, ""); fprintf(f, "}}"); break; - + if (0) { case AST_BIT_NOT: txt = "~"; } if (0) { case AST_REDUCE_AND: txt = "&"; } if (0) { case AST_REDUCE_OR: txt = "|"; } @@ -697,7 +700,7 @@ AstNode *AstNode::mkconst_bits(const std::vector<RTLIL::State> &v, bool is_signe for (size_t i = 0; i < 32; i++) { if (i < node->bits.size()) node->integer |= (node->bits[i] == RTLIL::S1) << i; - else if (is_signed) + else if (is_signed && !node->bits.empty()) node->integer |= (node->bits.back() == RTLIL::S1) << i; } node->range_valid = true; @@ -818,7 +821,7 @@ uint64_t AstNode::asInt(bool is_signed) } if (type == AST_REALVALUE) - return realvalue; + return uint64_t(realvalue); log_abort(); } @@ -829,7 +832,7 @@ double AstNode::asReal(bool is_signed) { RTLIL::Const val(bits); - bool is_negative = is_signed && val.bits.back() == RTLIL::State::S1; + bool is_negative = is_signed && !val.bits.empty() && val.bits.back() == RTLIL::State::S1; if (is_negative) val = const_neg(val, val, false, false, val.bits.size()); @@ -892,7 +895,7 @@ static AstModule* process_module(AstNode *ast, bool defer) AstNode *ast_before_simplify = ast->clone(); if (flag_dump_ast1) { - log("Dumping verilog AST before simplification:\n"); + log("Dumping Verilog AST before simplification:\n"); ast->dumpAst(NULL, " "); log("--- END OF AST DUMP ---\n"); } @@ -902,13 +905,13 @@ static AstModule* process_module(AstNode *ast, bool defer) while (ast->simplify(!flag_noopt, false, false, 0, -1, false, false)) { } if (flag_dump_ast2) { - log("Dumping verilog AST after simplification:\n"); + log("Dumping Verilog AST after simplification:\n"); ast->dumpAst(NULL, " "); log("--- END OF AST DUMP ---\n"); } if (flag_dump_vlog) { - log("Dumping verilog AST (as requested by dump_vlog option):\n"); + log("Dumping Verilog AST (as requested by dump_vlog option):\n"); ast->dumpVlog(NULL, " "); log("--- END OF AST DUMP ---\n"); } @@ -957,6 +960,7 @@ static AstModule* process_module(AstNode *ast, bool defer) current_module->ast = ast_before_simplify; current_module->nolatches = flag_nolatches; + current_module->nomeminit = flag_nomeminit; current_module->nomem2reg = flag_nomem2reg; current_module->mem2reg = flag_mem2reg; current_module->lib = flag_lib; @@ -968,13 +972,14 @@ static AstModule* process_module(AstNode *ast, bool defer) } // create AstModule instances for all modules in the AST tree and add them to 'design' -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) +void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool dump_vlog, bool nolatches, bool nomeminit, bool nomem2reg, bool mem2reg, bool lib, bool noopt, bool icells, bool ignore_redef, bool defer, bool autowire) { current_ast = ast; flag_dump_ast1 = dump_ast1; flag_dump_ast2 = dump_ast2; flag_dump_vlog = dump_vlog; flag_nolatches = nolatches; + flag_nomeminit = nomeminit; flag_nomem2reg = nomem2reg; flag_mem2reg = mem2reg; flag_lib = lib; @@ -992,6 +997,14 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump for (auto n : global_decls) (*it)->children.push_back(n->clone()); + for (auto n : design->verilog_packages){ + for (auto o : n->children) { + AstNode *cloned_node = o->clone(); + cloned_node->str = n->str + std::string("::") + cloned_node->str.substr(1); + (*it)->children.push_back(cloned_node); + } + } + if (flag_icells && (*it)->str.substr(0, 2) == "\\$") (*it)->str = (*it)->str.substr(1); @@ -1009,6 +1022,9 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump design->add(process_module(*it, defer)); } + else if ((*it)->type == AST_PACKAGE){ + design->verilog_packages.push_back((*it)->clone()); + } else global_decls.push_back(*it); } @@ -1029,13 +1045,14 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R if (stripped_name.substr(0, 9) == "$abstract") stripped_name = stripped_name.substr(9); - log_header("Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", stripped_name.c_str()); + log_header(design, "Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", stripped_name.c_str()); current_ast = NULL; flag_dump_ast1 = false; flag_dump_ast2 = false; flag_dump_vlog = false; flag_nolatches = nolatches; + flag_nomeminit = nomeminit; flag_nomem2reg = nomem2reg; flag_mem2reg = mem2reg; flag_lib = lib; @@ -1102,6 +1119,7 @@ RTLIL::Module *AstModule::clone() const new_mod->ast = ast->clone(); new_mod->nolatches = nolatches; + new_mod->nomeminit = nomeminit; new_mod->nomem2reg = nomem2reg; new_mod->mem2reg = mem2reg; new_mod->lib = lib; |