aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Shah <dave@ds0.me>2019-09-20 11:46:37 +0100
committerDavid Shah <dave@ds0.me>2019-10-03 09:54:14 +0100
commitaf25585170f87506bcc7dbe5afe0fec868290d5b (patch)
treeb66b8b2c1d4bd322d6179b9acc111d512f3354da
parent30d23260309ef392a0e69fe5294c38b71ad0692e (diff)
downloadyosys-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.cc26
-rw-r--r--tests/svtypes/typedef_memory_2.sv10
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