Merge pull request #585 from larsclausen/packed-array-direct-struct-enum

Support direct packed arrays of struct and enums and packed arrays of scoped types
This commit is contained in:
Stephen Williams 2022-01-15 18:51:11 -08:00 committed by GitHub
commit f1c543194c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 26 deletions

View File

@ -1,6 +1,10 @@
// Check that packed arrays of all sorts get elaborated without an error and
// that the resulting type has the right packed width.
package p;
typedef logic [2:0] vector;
endpackage
module test;
typedef bit bit2;
@ -8,6 +12,7 @@ typedef logic [1:0] vector;
bit2 [1:0] b;
vector [2:0] l;
p::vector [3:0] scoped_pa;
typedef enum logic [7:0] {
A
@ -23,6 +28,10 @@ EP [2:0] epp1;
EPP epp2;
EPP [3:0] eppp;
enum logic [7:0] {
B
} [1:0] ep3;
typedef struct packed {
longint x;
} S1;
@ -54,28 +63,35 @@ SP [9:0] spp1;
SPP spp2;
SPP [1:0] sppp;
struct packed {
S2 s;
} [3:0] sp3;
bit failed = 1'b0;
initial begin
// Packed arrays of basic types
failed |= $bits(b) !== 2;
failed |= $bits(l) !== 2 * 3;
failed |= $bits(scoped_pa) !== 3 * 4;
// Packed arrays of enums
failed |= $bits(e) !== 8;
failed |= $bits(ep1) !== $bits(e) * 2;
failed |= $bits(ep2) !== $bits(ep1);
failed |= $bits(ep3) !== $bits(ep1);
failed |= $bits(epp1) !== $bits(ep1) * 3;
failed |= $bits(epp2) !== $bits(epp1);
failed |= $bits(eppp) !== $bits(epp1) * 4;
// Packed arrays of structs
failed |= $bits(s) !== S_SIZE;
failed |= $bits(sp1) != $bits(s) * 4;
failed |= $bits(sp2) != $bits(sp1);
failed |= $bits(spp1) != $bits(sp1) * 10;
failed |= $bits(spp1) != $bits(spp2);
failed |= $bits(sppp) != $bits(spp1) * 2;
failed |= $bits(sp1) !== $bits(s) * 4;
failed |= $bits(sp2) !== $bits(sp1);
failed |= $bits(sp3) !== $bits(sp1);
failed |= $bits(spp1) !== $bits(sp1) * 10;
failed |= $bits(spp1) !== $bits(spp2);
failed |= $bits(sppp) !== $bits(spp1) * 2;
if (failed)
$display("FAILED");

52
parse.y
View File

@ -637,6 +637,7 @@ static void current_function_set_statement(const YYLTYPE&loc, std::vector<Statem
%type <data_type> data_type data_type_or_implicit data_type_or_implicit_or_void
%type <data_type> simple_type_or_string let_formal_type
%type <data_type> packed_array_data_type
%type <class_type> class_identifier
%type <struct_member> struct_union_member
%type <struct_members> struct_union_member_list
@ -1170,6 +1171,30 @@ data_declaration /* IEEE1800-2005: A.2.1.3 */
| attribute_list_opt package_import_declaration
;
/* Data types that can have packed dimensions directly attached to it */
packed_array_data_type /* IEEE1800-2005: A.2.2.1 */
: enum_data_type
{ $$ = $1; }
| struct_data_type
{ if (!$1->packed_flag) {
yyerror(@1, "sorry: Unpacked structs not supported.");
}
$$ = $1;
}
| TYPE_IDENTIFIER
{ pform_set_type_referenced(@1, $1.text);
delete[]$1.text;
$$ = $1.type;
}
| PACKAGE_IDENTIFIER K_SCOPE_RES
{ lex_in_package_scope($1); }
TYPE_IDENTIFIER
{ lex_in_package_scope(0);
$$ = $4.type;
delete[]$4.text;
}
;
data_type /* IEEE1800-2005: A.2.2.1 */
: integer_vector_type unsigned_signed_opt dimensions_opt
{ ivl_variable_type_t use_vtype = $1;
@ -1188,14 +1213,6 @@ data_type /* IEEE1800-2005: A.2.2.1 */
FILE_NAME(tmp, @1);
$$ = tmp;
}
| struct_data_type
{ if (!$1->packed_flag) {
yyerror(@1, "sorry: Unpacked structs not supported.");
}
$$ = $1;
}
| enum_data_type
{ $$ = $1; }
| atom2_type signed_unsigned_opt
{ atom2_type_t*tmp = new atom2_type_t($1, $2);
FILE_NAME(tmp, @1);
@ -1214,21 +1231,14 @@ data_type /* IEEE1800-2005: A.2.2.1 */
tmp->reg_flag = !gn_system_verilog();
$$ = tmp;
}
| TYPE_IDENTIFIER dimensions_opt
{ pform_set_type_referenced(@1, $1.text);
if ($2) {
parray_type_t*tmp = new parray_type_t($1.type, $2);
| packed_array_data_type dimensions_opt
{ if ($2) {
parray_type_t*tmp = new parray_type_t($1, $2);
FILE_NAME(tmp, @1);
$$ = tmp;
} else $$ = $1.type;
delete[]$1.text;
}
| PACKAGE_IDENTIFIER K_SCOPE_RES
{ lex_in_package_scope($1); }
TYPE_IDENTIFIER
{ lex_in_package_scope(0);
$$ = $4.type;
delete[]$4.text;
} else {
$$ = $1;
}
}
| K_string
{ string_type_t*tmp = new string_type_t;