mirror of https://github.com/YosysHQ/yosys.git
Allow structs within structs.
This commit is contained in:
parent
f482c9c016
commit
17f050d3c6
|
@ -238,7 +238,6 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode)
|
||||||
%union {
|
%union {
|
||||||
std::string *string;
|
std::string *string;
|
||||||
struct YOSYS_NAMESPACE_PREFIX AST::AstNode *ast;
|
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;
|
YOSYS_NAMESPACE_PREFIX dict<YOSYS_NAMESPACE_PREFIX RTLIL::IdString, YOSYS_NAMESPACE_PREFIX AST::AstNode*> *al;
|
||||||
struct specify_target *specify_target_ptr;
|
struct specify_target *specify_target_ptr;
|
||||||
struct specify_triple *specify_triple_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 <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 <boolean> opt_signed opt_property unique_case_attr always_comb_or_latch always_or_always_ff
|
||||||
%type <al> attr case_attr
|
%type <al> attr case_attr
|
||||||
%type <type> struct_union
|
%type <ast> struct_union
|
||||||
|
|
||||||
%type <specify_target_ptr> specify_target
|
%type <specify_target_ptr> specify_target
|
||||||
%type <specify_triple_ptr> specify_triple specify_opt_triple
|
%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_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:
|
struct_union:
|
||||||
TOK_STRUCT { $$ = AST_STRUCT; }
|
TOK_STRUCT { $$ = new AstNode(AST_STRUCT); }
|
||||||
| TOK_UNION { $$ = AST_UNION; }
|
| TOK_UNION { $$ = new AstNode(AST_UNION); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
struct_body: opt_packed '{' struct_member_list '}'
|
||||||
|
;
|
||||||
|
|
||||||
opt_packed: TOK_PACKED opt_signed_struct
|
opt_packed: TOK_PACKED opt_signed_struct
|
||||||
| { frontend_verilog_yyerror("Only PACKED supported at this time"); }
|
| { 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
|
member_type
|
||||||
| hierarchical_type_id {
|
| hierarchical_type_id {
|
||||||
// use a clone of the typedef definition nodes
|
// use a clone of the typedef definition nodes
|
||||||
|
@ -1569,6 +1570,16 @@ member_type_token_list:
|
||||||
delete astbuf1;
|
delete astbuf1;
|
||||||
astbuf1 = template_node;
|
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
|
member_type: type_atom type_signing
|
||||||
|
|
|
@ -15,6 +15,13 @@ module top;
|
||||||
bit [7:0] d;
|
bit [7:0] d;
|
||||||
} pack1;
|
} pack1;
|
||||||
|
|
||||||
|
struct packed {
|
||||||
|
byte a;
|
||||||
|
struct packed {
|
||||||
|
byte x, y;
|
||||||
|
} b;
|
||||||
|
} s2;
|
||||||
|
|
||||||
assign s.a = '1;
|
assign s.a = '1;
|
||||||
assign s.b = '1;
|
assign s.b = '1;
|
||||||
assign s.c = 8'hAA;
|
assign s.c = 8'hAA;
|
||||||
|
@ -25,6 +32,7 @@ module top;
|
||||||
assign pack1.b = 16'hAAAA;
|
assign pack1.b = 16'hAAAA;
|
||||||
assign pack1.c = '1;
|
assign pack1.c = '1;
|
||||||
assign pack1.d = 8'h55;
|
assign pack1.d = 8'h55;
|
||||||
|
assign s2.b.x = 'h42;
|
||||||
|
|
||||||
always_comb assert(s.a == 1'b1);
|
always_comb assert(s.a == 1'b1);
|
||||||
always_comb assert(s.c == 8'hAA);
|
always_comb assert(s.c == 8'hAA);
|
||||||
|
@ -35,5 +43,6 @@ module top;
|
||||||
always_comb assert(pack1.c == 8'hFF);
|
always_comb assert(pack1.c == 8'hFF);
|
||||||
always_comb assert(pack1[15:8] == 8'hFF);
|
always_comb assert(pack1[15:8] == 8'hFF);
|
||||||
always_comb assert(pack1.d == 8'h55);
|
always_comb assert(pack1.d == 8'h55);
|
||||||
|
always_comb assert(s2.b.x == 'h42);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
@ -58,4 +58,15 @@ module top;
|
||||||
assert(ir1.u.imm == 'hAA01);
|
assert(ir1.u.imm == 'hAA01);
|
||||||
end
|
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
|
endmodule
|
||||||
|
|
Loading…
Reference in New Issue