From: Peter Crozier Date: Tue, 12 May 2020 16:20:34 +0000 (+0100) Subject: Allow structs within structs. X-Git-Tag: working-ls180~504^2~1 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=17f050d3c6b8934141c42f96a3418de67a687b2c;p=yosys.git Allow structs within structs. --- diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index fff02f33a..e72d09524 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -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 *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 opt_enum_init enum_type struct_type non_wire_data_type %type opt_signed opt_property unique_case_attr always_comb_or_latch always_or_always_ff %type attr case_attr -%type struct_union +%type struct_union %type specify_target %type 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 diff --git a/tests/svtypes/struct_simple.sv b/tests/svtypes/struct_simple.sv index e29489fb7..c74289cc3 100644 --- a/tests/svtypes/struct_simple.sv +++ b/tests/svtypes/struct_simple.sv @@ -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 diff --git a/tests/svtypes/union_simple.sv b/tests/svtypes/union_simple.sv index fc23fe6e8..12e4b376f 100644 --- a/tests/svtypes/union_simple.sv +++ b/tests/svtypes/union_simple.sv @@ -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