aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--frontends/ast/simplify.cc33
-rw-r--r--frontends/verilog/verilog_parser.y21
-rw-r--r--tests/svtypes/typedef_param.sv22
-rw-r--r--tests/svtypes/typedef_simple.sv (renamed from tests/svtypes/typedef1.sv)3
4 files changed, 70 insertions, 9 deletions
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index b94662bcd..9abd2916d 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -790,8 +790,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
log_assert(!children[0]->is_custom_type);
}
- // resolve types of wires and parameters
- if (type == AST_WIRE || type == AST_LOCALPARAM || type == AST_PARAMETER) {
+ // resolve types of wires
+ if (type == AST_WIRE) {
if (is_custom_type) {
log_assert(children.size() == 1);
log_assert(children[0]->type == AST_WIRETYPE);
@@ -820,6 +820,35 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
log_assert(!is_custom_type);
}
+ // resolve types of parameters
+ if (type == AST_LOCALPARAM || type == AST_PARAMETER) {
+ if (is_custom_type) {
+ log_assert(children.size() == 2);
+ log_assert(children[1]->type == AST_WIRETYPE);
+ if (!current_scope.count(children[1]->str))
+ log_file_error(filename, linenum, "Unknown identifier `%s' used as type name", children[1]->str.c_str());
+ AstNode *resolved_type = current_scope.at(children[1]->str);
+ if (resolved_type->type != AST_TYPEDEF)
+ log_file_error(filename, linenum, "`%s' does not name a type", children[1]->str.c_str());
+ log_assert(resolved_type->children.size() == 1);
+ AstNode *templ = resolved_type->children[0];
+ delete children[1];
+ children.pop_back();
+
+ is_signed = templ->is_signed;
+ is_string = templ->is_string;
+ is_custom_type = templ->is_custom_type;
+
+ range_valid = templ->range_valid;
+ 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());
+ }
+ log_assert(!is_custom_type);
+ }
+
// resolve constant prefixes
if (type == AST_PREFIX) {
if (children[0]->type != AST_CONSTANT) {
diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y
index eb091bea6..8cc084fe0 100644
--- a/frontends/verilog/verilog_parser.y
+++ b/frontends/verilog/verilog_parser.y
@@ -327,13 +327,13 @@ single_module_para:
astbuf1 = new AstNode(AST_PARAMETER);
astbuf1->children.push_back(AstNode::mkconst_int(0, true));
append_attr(astbuf1, $1);
- } param_signed param_integer param_range single_param_decl |
+ } int_param_type single_param_decl |
attr TOK_LOCALPARAM {
if (astbuf1) delete astbuf1;
astbuf1 = new AstNode(AST_LOCALPARAM);
astbuf1->children.push_back(AstNode::mkconst_int(0, true));
append_attr(astbuf1, $1);
- } param_signed param_integer param_range single_param_decl |
+ } int_param_type single_param_decl |
single_param_decl;
module_args_opt:
@@ -1158,12 +1158,25 @@ param_range:
}
};
+custom_param_type:
+ hierarchical_id {
+ astbuf1->is_custom_type = true;
+ astbuf1->children.push_back(new AstNode(AST_WIRETYPE));
+ astbuf1->children.back()->str = *$1;
+ };
+
+param_type:
+ param_signed param_integer param_real param_range | custom_param_type;
+
+int_param_type:
+ param_signed param_integer param_range | custom_param_type;
+
param_decl:
attr TOK_PARAMETER {
astbuf1 = new AstNode(AST_PARAMETER);
astbuf1->children.push_back(AstNode::mkconst_int(0, true));
append_attr(astbuf1, $1);
- } param_signed param_integer param_real param_range param_decl_list ';' {
+ } param_type param_decl_list ';' {
delete astbuf1;
};
@@ -1172,7 +1185,7 @@ localparam_decl:
astbuf1 = new AstNode(AST_LOCALPARAM);
astbuf1->children.push_back(AstNode::mkconst_int(0, true));
append_attr(astbuf1, $1);
- } param_signed param_integer param_real param_range param_decl_list ';' {
+ } param_type param_decl_list ';' {
delete astbuf1;
};
diff --git a/tests/svtypes/typedef_param.sv b/tests/svtypes/typedef_param.sv
new file mode 100644
index 000000000..13a522f19
--- /dev/null
+++ b/tests/svtypes/typedef_param.sv
@@ -0,0 +1,22 @@
+`define STRINGIFY(x) `"x`"
+`define STATIC_ASSERT(x) if(!(x)) $error({"assert failed: ", `STRINGIFY(x)})
+
+module top;
+
+ typedef logic [1:0] uint2_t;
+ typedef logic signed [3:0] int4_t;
+ typedef logic signed [7:0] int8_t;
+ typedef int8_t char_t;
+
+ parameter uint2_t int2 = 2'b10;
+ localparam int4_t int4 = -1;
+ localparam int8_t int8 = int4;
+ localparam char_t ch = int8;
+
+
+ `STATIC_ASSERT(int2 == 2'b10);
+ `STATIC_ASSERT(int4 == 4'b1111);
+ `STATIC_ASSERT(int8 == 8'b11111111);
+ `STATIC_ASSERT(ch == 8'b11111111);
+
+endmodule \ No newline at end of file
diff --git a/tests/svtypes/typedef1.sv b/tests/svtypes/typedef_simple.sv
index 9e5d02364..0cf2c072c 100644
--- a/tests/svtypes/typedef1.sv
+++ b/tests/svtypes/typedef_simple.sv
@@ -1,6 +1,3 @@
-`define STRINGIFY(x) `"x`"
-`define STATIC_ASSERT(x) if(!(x)) $error({"assert failed: ", `STRINGIFY(x)})
-
module top;
typedef logic [1:0] uint2_t;