diff options
-rw-r--r-- | frontends/ast/simplify.cc | 3 | ||||
-rw-r--r-- | frontends/verilog/verilog_parser.y | 62 | ||||
-rw-r--r-- | tests/svtypes/typedef_struct_port.sv | 111 | ||||
-rw-r--r-- | tests/svtypes/typedef_struct_port.ys | 6 |
4 files changed, 152 insertions, 30 deletions
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index d4242f1e7..fc2976c83 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1330,6 +1330,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (template_node->type == AST_STRUCT || template_node->type == AST_UNION) { // replace with wire representing the packed structure newNode = make_packed_struct(template_node, str); + // add original input/output attribute to resolved wire + newNode->is_input = this->is_input; + newNode->is_output = this->is_output; current_scope[str] = this; goto apply_newNode; } diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 6c4b06d7f..0f7f2a57a 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -282,7 +282,7 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode) %token TOK_OR_ASSIGN TOK_XOR_ASSIGN TOK_AND_ASSIGN TOK_SUB_ASSIGN %type <ast> range range_or_multirange non_opt_range non_opt_multirange range_or_signed_int -%type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list +%type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list non_io_wire_type io_wire_type %type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id hierarchical_type_id integral_number %type <string> type_name %type <ast> opt_enum_init enum_type struct_type non_wire_data_type @@ -619,26 +619,19 @@ non_opt_delay: delay: non_opt_delay | %empty; -wire_type: - { - astbuf3 = new AstNode(AST_WIRE); - current_wire_rand = false; - current_wire_const = false; - } wire_type_token_list { - $$ = astbuf3; - SET_RULE_LOC(@$, @2, @$); - }; +io_wire_type: + { astbuf3 = new AstNode(AST_WIRE); current_wire_rand = false; current_wire_const = false; } + wire_type_token_io wire_type_const_rand opt_wire_type_token wire_type_signedness + { $$ = astbuf3; SET_RULE_LOC(@$, @2, @$); }; -wire_type_token_list: - wire_type_token | - wire_type_token_list wire_type_token | - wire_type_token_io | - hierarchical_type_id { - astbuf3->is_custom_type = true; - astbuf3->children.push_back(new AstNode(AST_WIRETYPE)); - astbuf3->children.back()->str = *$1; - delete $1; - }; +non_io_wire_type: + { astbuf3 = new AstNode(AST_WIRE); current_wire_rand = false; current_wire_const = false; } + wire_type_const_rand wire_type_token wire_type_signedness + { $$ = astbuf3; SET_RULE_LOC(@$, @2, @$); }; + +wire_type: + io_wire_type | + non_io_wire_type; wire_type_token_io: TOK_INPUT { @@ -652,7 +645,25 @@ wire_type_token_io: astbuf3->is_output = true; }; +wire_type_signedness: + TOK_SIGNED { astbuf3->is_signed = true; } | + TOK_UNSIGNED { astbuf3->is_signed = false; } | + %empty; + +wire_type_const_rand: + TOK_CONST { current_wire_const = true; } | + TOK_RAND { current_wire_rand = true; } | + %empty; + +opt_wire_type_token: + wire_type_token | %empty; + wire_type_token: + hierarchical_type_id { + astbuf3->is_custom_type = true; + astbuf3->children.push_back(new AstNode(AST_WIRETYPE)); + astbuf3->children.back()->str = *$1; + } | TOK_WIRE { } | TOK_WOR { @@ -682,15 +693,6 @@ wire_type_token: astbuf3->is_signed = true; astbuf3->range_left = 31; astbuf3->range_right = 0; - } | - TOK_SIGNED { - astbuf3->is_signed = true; - } | - TOK_RAND { - current_wire_rand = true; - } | - TOK_CONST { - current_wire_const = true; }; non_opt_range: @@ -1803,7 +1805,7 @@ type_name: TOK_ID // first time seen ; typedef_decl: - TOK_TYPEDEF wire_type range type_name range_or_multirange ';' { + TOK_TYPEDEF non_io_wire_type range type_name range_or_multirange ';' { astbuf1 = $2; astbuf2 = checkRange(astbuf1, $3); if (astbuf2) diff --git a/tests/svtypes/typedef_struct_port.sv b/tests/svtypes/typedef_struct_port.sv new file mode 100644 index 000000000..ecc03bee8 --- /dev/null +++ b/tests/svtypes/typedef_struct_port.sv @@ -0,0 +1,111 @@ +package p; + +typedef struct packed { + byte a; + byte b; +} p_t; + +typedef logic [31:0] l_t; + +endpackage + +module foo1( + input p::p_t p, + output p::p_t o +); + assign o = p; +endmodule + +module foo2(p, o); + input p::p_t p; + output p::p_t o; + assign o = p; +endmodule + +module foo3(input p::l_t p, input p::l_t o); + assign o = p; +endmodule + +module foo4(input logic [15:0] p, input logic [15:0] o); + assign o = p; +endmodule + +module test_parser(a,b,c,d,e,f,g,h,i); +input [7:0] a; // no explicit net declaration - net is unsigned +input [7:0] b; +input signed [7:0] c; +input signed [7:0] d; // no explicit net declaration - net is signed +output [7:0] e; // no explicit net declaration - net is unsigned +output [7:0] f; +output signed [7:0] g; +output signed [7:0] h; // no explicit net declaration - net is signed +output unsigned [7:0] i; +wire signed [7:0] b; // port b inherits signed attribute from net decl. +wire [7:0] c; // net c inherits signed attribute from port +logic signed [7:0] f;// port f inherits signed attribute from logic decl. +logic [7:0] g; // logic g inherits signed attribute from port + + assign a = 8'b10001111; + assign b = 8'b10001111; + assign c = 8'b10001111; + assign d = 8'b10001111; + assign e = 8'b10001111; + assign f = 8'b10001111; + assign g = 8'b10001111; + assign h = 8'b10001111; + assign i = 8'b10001111; + always_comb begin + assert($unsigned(143) == a); + assert($signed(-113) == b); + assert($signed(-113) == c); + assert($signed(-113) == d); + assert($unsigned(143) == e); + assert($unsigned(143) == f); + assert($signed(-113) == g); + assert($signed(-113) == h); + assert($unsigned(143) == i); + end +endmodule + +module top; + p::p_t ps; + assign ps.a = 8'hAA; + assign ps.b = 8'h55; + foo1 foo(.p(ps)); + + p::p_t body; + assign body.a = 8'hBB; + assign body.b = 8'h66; + foo2 foo_b(.p(body)); + + typedef p::l_t local_alias; + + local_alias l_s; + assign l_s = 32'hAAAAAAAA; + foo3 foo_l(.p(l_s)); + + typedef logic [15:0] sl_t; + + sl_t sl_s; + assign sl_s = 16'hBBBB; + foo4 foo_sl(.p(sl_s)); + + typedef sl_t local_alias_st; + + local_alias_st lsl_s; + assign lsl_s = 16'hCCCC; + foo4 foo_lsl(.p(lsl_s)); + + const logic j = 1'b1; + + always_comb begin + assert(8'hAA == ps.a); + assert(8'h55 == ps.b); + assert(8'hBB == body.a); + assert(8'h66 == body.b); + assert(32'hAAAAAAAA == l_s); + assert(16'hBBBB == sl_s); + assert(16'hCCCC == lsl_s); + assert(1'b1 == j); + end +endmodule diff --git a/tests/svtypes/typedef_struct_port.ys b/tests/svtypes/typedef_struct_port.ys new file mode 100644 index 000000000..5b75c3105 --- /dev/null +++ b/tests/svtypes/typedef_struct_port.ys @@ -0,0 +1,6 @@ +read_verilog -sv typedef_struct_port.sv +hierarchy; proc; opt +select -module top +sat -verify -seq 1 -tempinduct -prove-asserts -show-all +select -module test_parser +sat -verify -seq 1 -tempinduct -prove-asserts -show-all |