aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2019-03-02 16:01:31 -0800
committerGitHub <noreply@github.com>2019-03-02 16:01:31 -0800
commitdddf837f69ba8ec54540b14d2328604c6d871a40 (patch)
tree5497828d0a1e4fa70feaceec76bf15a7ab8fe38e
parentce6695e22c7d2b8856ec5bb93a94264555aa55b5 (diff)
parentae9286386de117991f887f919f5af3fac40173cc (diff)
downloadyosys-dddf837f69ba8ec54540b14d2328604c6d871a40.tar.gz
yosys-dddf837f69ba8ec54540b14d2328604c6d871a40.tar.bz2
yosys-dddf837f69ba8ec54540b14d2328604c6d871a40.zip
Merge pull request #849 from YosysHQ/clifford/dynports
Only run derive on blackbox modules when ports have dynamic size
-rw-r--r--README.md3
-rw-r--r--frontends/ast/ast.h1
-rw-r--r--frontends/ast/simplify.cc19
-rw-r--r--passes/hierarchy/hierarchy.cc2
4 files changed, 24 insertions, 1 deletions
diff --git a/README.md b/README.md
index f17046488..9bac468a7 100644
--- a/README.md
+++ b/README.md
@@ -309,6 +309,9 @@ Verilog Attributes and non-standard features
passes to identify input and output ports of cells. The Verilog backend
also does not output blackbox modules on default.
+- The ``dynports'' attribute is used by the Verilog front-end to mark modules
+ that have ports with a width that depends on a parameter.
+
- The ``keep`` attribute on cells and wires is used to mark objects that should
never be removed by the optimizer. This is used for example for cells that
have hidden connections that are not part of the netlist, such as IO pads.
diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h
index 89f7e6e4f..8b185ff51 100644
--- a/frontends/ast/ast.h
+++ b/frontends/ast/ast.h
@@ -239,6 +239,7 @@ namespace AST
bool has_const_only_constructs(bool &recommend_const_eval);
void replace_variables(std::map<std::string, varinfo_t> &variables, AstNode *fcall);
AstNode *eval_const_function(AstNode *fcall);
+ bool is_simple_const_expr();
// create a human-readable text representation of the AST (for debugging)
void dumpAst(FILE *f, std::string indent) const;
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index d0b31078a..7160c6c0f 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -328,6 +328,15 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
for (size_t i = 0; i < children.size(); i++) {
AstNode *node = children[i];
if (node->type == AST_WIRE) {
+ if (node->children.size() == 1 && node->children[0]->type == AST_RANGE) {
+ for (auto c : node->children[0]->children) {
+ if (!c->is_simple_const_expr()) {
+ if (attributes.count("\\dynports"))
+ delete attributes.at("\\dynports");
+ attributes["\\dynports"] = AstNode::mkconst_int(1, true);
+ }
+ }
+ }
if (this_wire_scope.count(node->str) > 0) {
AstNode *first_node = this_wire_scope[node->str];
if (first_node->is_input && node->is_reg)
@@ -3323,6 +3332,16 @@ bool AstNode::has_const_only_constructs(bool &recommend_const_eval)
return false;
}
+bool AstNode::is_simple_const_expr()
+{
+ if (type == AST_IDENTIFIER)
+ return false;
+ for (auto child : children)
+ if (!child->is_simple_const_expr())
+ return false;
+ return true;
+}
+
// helper function for AstNode::eval_const_function()
void AstNode::replace_variables(std::map<std::string, AstNode::varinfo_t> &variables, AstNode *fcall)
{
diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc
index 2d8edebb5..88c339e8c 100644
--- a/passes/hierarchy/hierarchy.cc
+++ b/passes/hierarchy/hierarchy.cc
@@ -910,7 +910,7 @@ struct HierarchyPass : public Pass {
if (m == nullptr)
continue;
- if (m->get_bool_attribute("\\blackbox") && !cell->parameters.empty()) {
+ if (m->get_bool_attribute("\\blackbox") && !cell->parameters.empty() && m->get_bool_attribute("\\dynports")) {
IdString new_m_name = m->derive(design, cell->parameters, true);
if (new_m_name.empty())
continue;