diff options
author | David Shah <dave@ds0.me> | 2019-09-20 11:46:37 +0100 |
---|---|---|
committer | David Shah <dave@ds0.me> | 2019-10-03 09:54:14 +0100 |
commit | af25585170f87506bcc7dbe5afe0fec868290d5b (patch) | |
tree | b66b8b2c1d4bd322d6179b9acc111d512f3354da | |
parent | 30d23260309ef392a0e69fe5294c38b71ad0692e (diff) | |
download | yosys-af25585170f87506bcc7dbe5afe0fec868290d5b.tar.gz yosys-af25585170f87506bcc7dbe5afe0fec868290d5b.tar.bz2 yosys-af25585170f87506bcc7dbe5afe0fec868290d5b.zip |
sv: Add support for memories of a typedef
Signed-off-by: David Shah <dave@ds0.me>
-rw-r--r-- | frontends/ast/simplify.cc | 26 | ||||
-rw-r--r-- | tests/svtypes/typedef_memory_2.sv | 10 |
2 files changed, 30 insertions, 6 deletions
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index a6ac04037..aaf1188b4 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -793,9 +793,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } // resolve types of wires - if (type == AST_WIRE) { + if (type == AST_WIRE || type == AST_MEMORY) { if (is_custom_type) { - log_assert(children.size() == 1); + log_assert(children.size() >= 1); log_assert(children[0]->type == AST_WIRETYPE); if (!current_scope.count(children[0]->str)) log_file_error(filename, linenum, "Unknown identifier `%s' used as type name\n", children[0]->str.c_str()); @@ -804,12 +804,15 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, log_file_error(filename, linenum, "`%s' does not name a type\n", children[0]->str.c_str()); log_assert(resolved_type->children.size() == 1); AstNode *templ = resolved_type->children[0]; - delete_children(); // type reference no longer needed + // Remove type reference + delete children[0]; + children.erase(children.begin()); // Ensure typedef itself is fully simplified while(templ->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {}; - type = templ->type; + if (type == AST_WIRE) + type = templ->type; is_reg = templ->is_reg; is_logic = templ->is_logic; is_signed = templ->is_signed; @@ -820,8 +823,19 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, range_swapped = templ->range_swapped; range_left = templ->range_left; range_right = templ->range_right; - for (auto template_child : templ->children) - children.push_back(template_child->clone()); + + // Insert clones children from template at beginning + for (int i = 0; i < GetSize(templ->children); i++) + children.insert(children.begin() + i, templ->children[i]->clone()); + + if (type == AST_MEMORY && GetSize(children) == 1) { + // Single-bit memories must have [0:0] range + AstNode *rng = new AstNode(AST_RANGE); + rng->children.push_back(AstNode::mkconst_int(0, true)); + rng->children.push_back(AstNode::mkconst_int(0, true)); + children.insert(children.begin(), rng); + } + did_something = true; } log_assert(!is_custom_type); diff --git a/tests/svtypes/typedef_memory_2.sv b/tests/svtypes/typedef_memory_2.sv new file mode 100644 index 000000000..1e8abb155 --- /dev/null +++ b/tests/svtypes/typedef_memory_2.sv @@ -0,0 +1,10 @@ +module top(input [3:0] addr, wdata, input clk, wen, output reg [3:0] rdata); + typedef logic [3:0] nibble; + + nibble mem[0:15]; + + always @(posedge clk) begin + if (wen) mem[addr] <= wdata; + rdata <= mem[addr]; + end +endmodule
\ No newline at end of file |