diff options
Diffstat (limited to 'frontends/ast/ast.cc')
-rw-r--r-- | frontends/ast/ast.cc | 94 |
1 files changed, 61 insertions, 33 deletions
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 92513a24..e79be953 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -44,7 +44,7 @@ namespace AST { // instanciate global variables (private API) namespace AST_INTERNAL { - bool flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_dump_rtlil, flag_nolatches, flag_nomeminit; + bool flag_dump_ast1, flag_dump_ast2, flag_no_dump_ptr, flag_dump_vlog, flag_dump_rtlil, flag_nolatches, flag_nomeminit; bool 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; @@ -84,6 +84,9 @@ std::string AST::type2str(AstNodeType type) X(AST_PREFIX) X(AST_ASSERT) X(AST_ASSUME) + X(AST_LIVE) + X(AST_FAIR) + X(AST_COVER) X(AST_FCALL) X(AST_TO_BITS) X(AST_TO_SIGNED) @@ -168,8 +171,8 @@ bool AstNode::get_bool_attribute(RTLIL::IdString id) AstNode *attr = attributes.at(id); if (attr->type != AST_CONSTANT) - log_error("Attribute `%s' with non-constant value at %s:%d!\n", - id.c_str(), attr->filename.c_str(), attr->linenum); + log_file_error(attr->filename, attr->linenum, "Attribute `%s' with non-constant value!\n", + id.c_str()); return attr->integer != 0; } @@ -188,8 +191,10 @@ AstNode::AstNode(AstNodeType type, AstNode *child1, AstNode *child2, AstNode *ch is_input = false; is_output = false; is_reg = false; + is_logic = false; is_signed = false; is_string = false; + was_checked = false; range_valid = false; range_swapped = false; port_id = 0; @@ -209,7 +214,7 @@ AstNode::AstNode(AstNodeType type, AstNode *child1, AstNode *child2, AstNode *ch } // create a (deep recursive) copy of a node -AstNode *AstNode::clone() +AstNode *AstNode::clone() const { AstNode *that = new AstNode; *that = *this; @@ -221,7 +226,7 @@ AstNode *AstNode::clone() } // create a (deep recursive) copy of a node use 'other' as target root node -void AstNode::cloneInto(AstNode *other) +void AstNode::cloneInto(AstNode *other) const { AstNode *tmp = clone(); other->delete_children(); @@ -251,7 +256,7 @@ AstNode::~AstNode() // create a nice text representation of the node // (traverse tree by recursion, use 'other' pointer for diffing two AST trees) -void AstNode::dumpAst(FILE *f, std::string indent) +void AstNode::dumpAst(FILE *f, std::string indent) const { if (f == NULL) { for (auto f : log_files) @@ -262,10 +267,12 @@ void AstNode::dumpAst(FILE *f, std::string indent) std::string type_name = type2str(type); fprintf(f, "%s%s <%s:%d>", indent.c_str(), type_name.c_str(), filename.c_str(), linenum); - if (id2ast) - fprintf(f, " [%p -> %p]", this, id2ast); - else - fprintf(f, " [%p]", this); + if (!flag_no_dump_ptr) { + if (id2ast) + fprintf(f, " [%p -> %p]", this, id2ast); + else + fprintf(f, " [%p]", this); + } if (!str.empty()) fprintf(f, " str='%s'", str.c_str()); @@ -282,7 +289,9 @@ void AstNode::dumpAst(FILE *f, std::string indent) fprintf(f, " input"); if (is_output) fprintf(f, " output"); - if (is_reg) + if (is_logic) + fprintf(f, " logic"); + if (is_reg) // this is an AST dump, not Verilog - if we see "logic reg" that's fine. fprintf(f, " reg"); if (is_signed) fprintf(f, " signed"); @@ -330,7 +339,7 @@ static std::string id2vl(std::string txt) } // dump AST node as Verilog pseudo-code -void AstNode::dumpVlog(FILE *f, std::string indent) +void AstNode::dumpVlog(FILE *f, std::string indent) const { bool first = true; std::string txt; @@ -649,6 +658,8 @@ bool AstNode::operator==(const AstNode &other) const return false; if (is_output != other.is_output) return false; + if (is_logic != other.is_logic) + return false; if (is_reg != other.is_reg) return false; if (is_signed != other.is_signed) @@ -752,7 +763,7 @@ AstNode *AstNode::mkconst_str(const std::string &str) return node; } -bool AstNode::bits_only_01() +bool AstNode::bits_only_01() const { for (auto bit : bits) if (bit != RTLIL::S0 && bit != RTLIL::S1) @@ -803,7 +814,7 @@ RTLIL::Const AstNode::asParaConst() return val; } -bool AstNode::asBool() +bool AstNode::asBool() const { log_assert(type == AST_CONSTANT); for (auto &bit : bits) @@ -812,7 +823,7 @@ bool AstNode::asBool() return false; } -int AstNode::isConst() +int AstNode::isConst() const { if (type == AST_CONSTANT) return 1; @@ -952,8 +963,8 @@ static AstModule* process_module(AstNode *ast, bool defer) for (auto &attr : ast->attributes) { if (attr.second->type != AST_CONSTANT) - log_error("Attribute `%s' with non-constant value at %s:%d!\n", - attr.first.c_str(), ast->filename.c_str(), ast->linenum); + log_file_error(ast->filename, ast->linenum, "Attribute `%s' with non-constant value!\n", + attr.first.c_str()); current_module->attributes[attr.first] = attr.second->asAttrConst(); } for (size_t i = 0; i < ast->children.size(); i++) { @@ -999,12 +1010,13 @@ 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 dump_rtlil, - bool nolatches, bool nomeminit, 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 no_dump_ptr, bool dump_vlog, bool dump_rtlil, + bool nolatches, bool nomeminit, bool nomem2reg, bool mem2reg, bool lib, bool noopt, bool icells, bool nooverwrite, bool overwrite, bool defer, bool autowire) { current_ast = ast; flag_dump_ast1 = dump_ast1; flag_dump_ast2 = dump_ast2; + flag_no_dump_ptr = no_dump_ptr; flag_dump_vlog = dump_vlog; flag_dump_rtlil = dump_rtlil; flag_nolatches = nolatches; @@ -1016,14 +1028,12 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump flag_icells = icells; flag_autowire = autowire; - std::vector<AstNode*> global_decls; - log_assert(current_ast->type == AST_DESIGN); for (auto it = current_ast->children.begin(); it != current_ast->children.end(); it++) { if ((*it)->type == AST_MODULE) { - for (auto n : global_decls) + for (auto n : design->verilog_globals) (*it)->children.push_back(n->clone()); for (auto n : design->verilog_packages){ @@ -1041,12 +1051,20 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump (*it)->str = "$abstract" + (*it)->str; if (design->has((*it)->str)) { - if (!ignore_redef) - log_error("Re-definition of module `%s' at %s:%d!\n", + RTLIL::Module *existing_mod = design->module((*it)->str); + if (!nooverwrite && !overwrite && !existing_mod->get_bool_attribute("\\blackbox")) { + log_file_error((*it)->filename, (*it)->linenum, "Re-definition of module `%s'!\n", + (*it)->str.c_str()); + } else if (nooverwrite) { + log("Ignoring re-definition of module `%s' at %s:%d.\n", (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); - log("Ignoring re-definition of module `%s' at %s:%d!\n", - (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); - continue; + continue; + } else { + log("Replacing existing%s module `%s' at %s:%d.\n", + existing_mod->get_bool_attribute("\\blackbox") ? " blackbox" : "", + (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); + design->remove(existing_mod); + } } design->add(process_module(*it, defer)); @@ -1054,7 +1072,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump else if ((*it)->type == AST_PACKAGE) design->verilog_packages.push_back((*it)->clone()); else - global_decls.push_back(*it); + design->verilog_globals.push_back((*it)->clone()); } } @@ -1066,7 +1084,7 @@ AstModule::~AstModule() } // create a new parametric module (when needed) and return the name of the generated module -RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters) +RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool) { std::string stripped_name = name.str(); @@ -1105,7 +1123,10 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R rewrite_parameter: para_info += stringf("%s=%s", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id]))); delete child->children.at(0); - child->children[0] = AstNode::mkconst_bits(parameters[para_id].bits, (parameters[para_id].flags & RTLIL::CONST_FLAG_SIGNED) != 0); + if ((parameters[para_id].flags & RTLIL::CONST_FLAG_STRING) != 0) + child->children[0] = AstNode::mkconst_str(parameters[para_id].decode_string()); + else + child->children[0] = AstNode::mkconst_bits(parameters[para_id].bits, (parameters[para_id].flags & RTLIL::CONST_FLAG_SIGNED) != 0); parameters.erase(para_id); continue; } @@ -1115,8 +1136,16 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R goto rewrite_parameter; } } - if (parameters.size() > 0) - log_error("Requested parameter `%s' does not exist in module `%s'!\n", parameters.begin()->first.c_str(), stripped_name.c_str()); + + for (auto param : parameters) { + AstNode *defparam = new AstNode(AST_DEFPARAM, new AstNode(AST_IDENTIFIER)); + defparam->children[0]->str = param.first.str(); + if ((param.second.flags & RTLIL::CONST_FLAG_STRING) != 0) + defparam->children.push_back(AstNode::mkconst_str(param.second.decode_string())); + else + defparam->children.push_back(AstNode::mkconst_bits(param.second.bits, (param.second.flags & RTLIL::CONST_FLAG_SIGNED) != 0)); + new_ast->children.push_back(defparam); + } std::string modname; @@ -1177,4 +1206,3 @@ void AST::use_internal_line_num() } YOSYS_NAMESPACE_END - |