Allow structs within structs.
authorPeter Crozier <peter@crozier.com>
Tue, 12 May 2020 16:20:34 +0000 (17:20 +0100)
committerPeter Crozier <peter@crozier.com>
Tue, 12 May 2020 16:20:34 +0000 (17:20 +0100)
frontends/verilog/verilog_parser.y
tests/svtypes/struct_simple.sv
tests/svtypes/union_simple.sv

index fff02f33a3db40fc286e6111c8c7ba242d6474b5..e72d09524d251de8c67b562f19e1c34b6f6a8dc0 100644 (file)
@@ -238,7 +238,6 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode)
 %union {
        std::string *string;
        struct YOSYS_NAMESPACE_PREFIX AST::AstNode *ast;
-       YOSYS_NAMESPACE_PREFIX AST::AstNodeType type;
        YOSYS_NAMESPACE_PREFIX dict<YOSYS_NAMESPACE_PREFIX RTLIL::IdString, YOSYS_NAMESPACE_PREFIX AST::AstNode*> *al;
        struct specify_target *specify_target_ptr;
        struct specify_triple *specify_triple_ptr;
@@ -279,7 +278,7 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode)
 %type <ast> opt_enum_init enum_type struct_type non_wire_data_type
 %type <boolean> opt_signed opt_property unique_case_attr always_comb_or_latch always_or_always_ff
 %type <al> attr case_attr
-%type <type> struct_union
+%type <ast> struct_union
 
 %type <specify_target_ptr> specify_target
 %type <specify_triple_ptr> specify_triple specify_opt_triple
@@ -1507,14 +1506,16 @@ enum_decl: enum_type enum_var_list ';'          { delete $1; }
 struct_decl: struct_type struct_var_list ';'   { delete astbuf2; }
        ;
 
-struct_type: struct_union { astbuf2 = new AstNode($1); } opt_packed '{' struct_member_list '}'         { $$ = astbuf2; }
+struct_type: struct_union { astbuf2 = $1; } struct_body { $$ = astbuf2; }
        ;
 
 struct_union:
-         TOK_STRUCT            { $$ = AST_STRUCT; }
-       | TOK_UNION             { $$ = AST_UNION; }
+         TOK_STRUCT            { $$ = new AstNode(AST_STRUCT); }
+       | TOK_UNION             { $$ = new AstNode(AST_UNION); }
        ;
 
+struct_body: opt_packed '{' struct_member_list '}'
+       ;
 
 opt_packed: TOK_PACKED opt_signed_struct
        | { frontend_verilog_yyerror("Only PACKED supported at this time"); }
@@ -1547,10 +1548,10 @@ member_name: TOK_ID {
                }
        ;
 
-struct_member_type: { astbuf1 = new AstNode(AST_STRUCT_ITEM); } member_type_token_list
+struct_member_type: { astbuf1 = new AstNode(AST_STRUCT_ITEM); } member_type_token
        ;
 
-member_type_token_list:
+member_type_token:
          member_type 
        | hierarchical_type_id {
                        // use a clone of the typedef definition nodes
@@ -1569,6 +1570,16 @@ member_type_token_list:
                        delete astbuf1;
                        astbuf1 = template_node;
                }
+       | struct_union {
+                       // stash state on ast_stack
+                       ast_stack.push_back(astbuf2);
+                       astbuf2 = $1;
+               } struct_body  {
+                       astbuf1 = astbuf2;
+                       // recover state
+                       astbuf2 = ast_stack.back();
+                       ast_stack.pop_back();
+               }
        ;
 
 member_type: type_atom type_signing
index e29489fb7a961f229e24678c4e3e6d1b7dcc1f21..c74289cc3eb1593d4da156e4d6b9acc5f7c4d356 100644 (file)
@@ -15,6 +15,13 @@ module top;
                bit [7:0] d;
        } pack1;
 
+       struct packed {
+               byte a;
+               struct packed {
+                       byte x, y;
+               } b;
+       } s2;
+
        assign s.a = '1;
        assign s.b = '1;
        assign s.c = 8'hAA;
@@ -25,6 +32,7 @@ module top;
        assign pack1.b = 16'hAAAA;
        assign pack1.c = '1;
        assign pack1.d = 8'h55;
+       assign s2.b.x = 'h42;
 
        always_comb assert(s.a == 1'b1);
        always_comb assert(s.c == 8'hAA);
@@ -35,5 +43,6 @@ module top;
        always_comb assert(pack1.c == 8'hFF);
        always_comb assert(pack1[15:8] == 8'hFF);
        always_comb assert(pack1.d == 8'h55);
+       always_comb assert(s2.b.x == 'h42);
 
 endmodule
index fc23fe6e8a15b8e9cce97cb649ff8af1844f24f2..12e4b376f9723ace95de6a719311a9a3d7c8d9b1 100644 (file)
@@ -58,4 +58,15 @@ module top;
                assert(ir1.u.imm == 'hAA01);
        end
 
+       union packed {
+               int word;
+               struct packed {
+                       byte a, b, c, d;
+               } byte4;
+       } u;
+       assign u.word = 'h42;
+       always_comb begin
+               assert(u.byte4.d == 'h42);
+       end
+
 endmodule