diff options
author | Zachary Snow <zach@zachjs.com> | 2021-03-02 10:43:53 -0500 |
---|---|---|
committer | Zachary Snow <zach@zachjs.com> | 2021-03-02 10:43:53 -0500 |
commit | d738b2c1272b02d8799e9feda83b1eae8ba10c07 (patch) | |
tree | 5edd76126d7c9969f3dfd695e7fad415d364fec9 /frontends/ast | |
parent | 375af199ef4df45ccf02c66e0171b4282c6cf1eb (diff) | |
download | yosys-d738b2c1272b02d8799e9feda83b1eae8ba10c07.tar.gz yosys-d738b2c1272b02d8799e9feda83b1eae8ba10c07.tar.bz2 yosys-d738b2c1272b02d8799e9feda83b1eae8ba10c07.zip |
sv: support for parameters without default values
- Modules with a parameter without a default value will be automatically
deferred until the hierarchy pass
- Allows for parameters without defaults as module items, rather than
just int the `parameter_port_list`, despite being forbidden in the LRM
- Check for parameters without defaults that haven't been overriden
- Add location info to parameter/localparam declarations
Diffstat (limited to 'frontends/ast')
-rw-r--r-- | frontends/ast/ast.cc | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 57552d86c..7fb61bb34 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -968,6 +968,14 @@ void AST::set_src_attr(RTLIL::AttrObject *obj, const AstNode *ast) obj->attributes[ID::src] = ast->loc_string(); } +static bool param_has_no_default(const AstNode *param) { + const auto &children = param->children; + log_assert(param->type == AST_PARAMETER); + log_assert(children.size() <= 2); + return children.empty() || + (children.size() == 1 && children[0]->type == AST_RANGE); +} + // create a new AstModule from an AST_MODULE AST node static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast = NULL, bool quiet = false) { @@ -1006,6 +1014,10 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast if (!defer) { + for (const AstNode *node : ast->children) + if (node->type == AST_PARAMETER && param_has_no_default(node)) + log_file_error(node->filename, node->location.first_line, "Parameter `%s' has no default value and has not been overridden!\n", node->str.c_str()); + bool blackbox_module = flag_lib; if (!blackbox_module && !flag_noblackbox) { @@ -1229,7 +1241,18 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump if (flag_icells && (*it)->str.compare(0, 2, "\\$") == 0) (*it)->str = (*it)->str.substr(1); - if (defer) + bool defer_local = defer; + if (!defer_local) + for (const AstNode *node : (*it)->children) + if (node->type == AST_PARAMETER && param_has_no_default(node)) + { + log("Deferring `%s' because it contains parameter(s) without defaults.\n", ast->str.c_str()); + defer_local = true; + break; + } + + + if (defer_local) (*it)->str = "$abstract" + (*it)->str; if (design->has((*it)->str)) { @@ -1248,7 +1271,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump } } - design->add(process_module(*it, defer)); + design->add(process_module(*it, defer_local)); current_ast_mod = nullptr; } else if ((*it)->type == AST_PACKAGE) { @@ -1619,6 +1642,8 @@ std::string AstModule::derive_common(RTLIL::Design *design, const dict<RTLIL::Id } continue; rewrite_parameter: + if (param_has_no_default(child)) + child->children.insert(child->children.begin(), nullptr); delete child->children.at(0); if ((it->second.flags & RTLIL::CONST_FLAG_REAL) != 0) { child->children[0] = new AstNode(AST_REALVALUE); |