diff options
author | Clifford Wolf <clifford@clifford.at> | 2016-11-15 13:35:19 +0100 |
---|---|---|
committer | Clifford Wolf <clifford@clifford.at> | 2016-11-15 13:35:19 +0100 |
commit | 70d7a02cae7ef38eb4f3afcf325979b80e87518e (patch) | |
tree | 431ec96bb8b4e8d4749cac8fd2bde537b070f354 /frontends | |
parent | a926a6afc2cf6ab7aed2c18950c6cd38d21f2a51 (diff) | |
download | yosys-70d7a02cae7ef38eb4f3afcf325979b80e87518e.tar.gz yosys-70d7a02cae7ef38eb4f3afcf325979b80e87518e.tar.bz2 yosys-70d7a02cae7ef38eb4f3afcf325979b80e87518e.zip |
Added support for hierarchical defparams
Diffstat (limited to 'frontends')
-rw-r--r-- | frontends/ast/ast.cc | 9 | ||||
-rw-r--r-- | frontends/ast/simplify.cc | 43 | ||||
-rw-r--r-- | frontends/verilog/verilog_parser.y | 5 |
3 files changed, 41 insertions, 16 deletions
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 5b4a4af47..2d58c682f 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1113,8 +1113,13 @@ 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(); + 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; diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 3432c61da..58db882d3 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -685,19 +685,40 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, current_scope.clear(); // convert defparam nodes to cell parameters - if (type == AST_DEFPARAM && !str.empty()) { - size_t pos = str.rfind('.'); + if (type == AST_DEFPARAM && !children.empty()) + { + if (children[0]->type != AST_IDENTIFIER) + log_error("Module name in defparam at %s:%d contains non-constant expressions!\n", filename.c_str(), linenum); + + string modname, paramname = children[0]->str; + + size_t pos = paramname.rfind('.'); + + while (pos != 0 && pos != std::string::npos) + { + modname = paramname.substr(0, pos); + + if (current_scope.count(modname)) + break; + + pos = paramname.rfind('.', pos - 1); + } + if (pos == std::string::npos) - log_error("Defparam `%s' does not contain a dot (module/parameter separator) at %s:%d!\n", - RTLIL::unescape_id(str).c_str(), filename.c_str(), linenum); - std::string modname = str.substr(0, pos), paraname = "\\" + str.substr(pos+1); - if (current_scope.count(modname) == 0 || current_scope.at(modname)->type != AST_CELL) - log_error("Can't find cell for defparam `%s . %s` at %s:%d!\n", RTLIL::unescape_id(modname).c_str(), RTLIL::unescape_id(paraname).c_str(), filename.c_str(), linenum); - AstNode *cell = current_scope.at(modname), *paraset = clone(); + log_error("Can't find object for defparam `%s` at %s:%d!\n", RTLIL::unescape_id(paramname).c_str(), filename.c_str(), linenum); + + paramname = "\\" + paramname.substr(pos+1); + + if (current_scope.at(modname)->type != AST_CELL) + log_error("Defparam argument `%s . %s` does not match a cell at %s:%d!\n", + RTLIL::unescape_id(modname).c_str(), RTLIL::unescape_id(paramname).c_str(), filename.c_str(), linenum); + + AstNode *paraset = new AstNode(AST_PARASET, children[1]->clone(), GetSize(children) > 2 ? children[2]->clone() : NULL); + paraset->str = paramname; + + AstNode *cell = current_scope.at(modname); cell->children.insert(cell->children.begin() + 1, paraset); - paraset->type = AST_PARASET; - paraset->str = paraname; - str.clear(); + delete_children(); } // resolve constant prefixes diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 5bbda5355..607c48a81 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -666,14 +666,13 @@ defparam_decl_list: single_defparam_decl | defparam_decl_list ',' single_defparam_decl; single_defparam_decl: - range hierarchical_id '=' expr { + range rvalue '=' expr { AstNode *node = new AstNode(AST_DEFPARAM); - node->str = *$2; + node->children.push_back($2); node->children.push_back($4); if ($1 != NULL) node->children.push_back($1); ast_stack.back()->children.push_back(node); - delete $2; }; wire_decl: |