Skip to content

Commit bd5b05e

Browse files
authored
Merge pull request #1299 from diffblue/verilog-packed-structs
Verilog: packed/unpacked structs
2 parents 9867c06 + 8e853e0 commit bd5b05e

File tree

7 files changed

+34
-5
lines changed

7 files changed

+34
-5
lines changed

regression/verilog/structs/structs4.sv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ module main;
1212
s.field3 = 'b1110011;
1313
end
1414

15-
// structs can be converted without cast to bit-vectors
15+
// packed structs can be converted without cast to bit-vectors
1616
wire [8:0] w = s;
1717

1818
// Expected to pass.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CORE
2+
unpacked_struct1.sv
3+
4+
^file .* line 9: failed to convert `struct' to `\[8:0\]'$
5+
^EXIT=2$
6+
^SIGNAL=0$
7+
--
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module main;
2+
3+
// an unpacked struct
4+
struct {
5+
bit field;
6+
} s;
7+
8+
// unpacked structs cannot be converted to bit-vectors
9+
wire [8:0] w = s;
10+
11+
endmodule

src/verilog/expr2verilog.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2149,7 +2149,10 @@ std::string expr2verilogt::convert(const typet &type)
21492149
}
21502150
else if(type.id() == ID_struct)
21512151
{
2152-
return "struct";
2152+
if(type.get_bool(ID_packed))
2153+
return "struct packed";
2154+
else
2155+
return "struct";
21532156
}
21542157
else if(type.id() == ID_union)
21552158
{

src/verilog/parser.y

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1552,6 +1552,8 @@ data_type:
15521552
| struct_union packed_opt signing_opt
15531553
'{' struct_union_member_brace '}' packed_dimension_brace
15541554
{ $$=$1;
1555+
if(stack_expr($2).id() == ID_packed)
1556+
stack_type($1).set(ID_packed, true);
15551557
addswap($$, ID_declaration_list, $5); }
15561558
| TOK_ENUM enum_base_type_opt '{' enum_name_declaration_list '}'
15571559
{ // Like in C, these do _not_ create a scope.

src/verilog/verilog_elaborate_type.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -425,8 +425,14 @@ typet verilog_typecheck_exprt::elaborate_type(const typet &src)
425425
}
426426
}
427427

428-
return struct_union_typet{src.id(), std::move(components)}
429-
.with_source_location(src.source_location());
428+
auto result =
429+
struct_union_typet{src.id(), std::move(components)}.with_source_location(
430+
src.source_location());
431+
432+
if(src.get_bool(ID_packed))
433+
result.set(ID_packed, true);
434+
435+
return result;
430436
}
431437
else if(src.id() == ID_verilog_string)
432438
{

src/verilog/verilog_typecheck_expr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2385,7 +2385,7 @@ void verilog_typecheck_exprt::struct_decay(exprt &expr) const
23852385
// Verilog packed struct types decay to a vector type [$bits(t)-1:0]
23862386
// when used in relational or arithmetic expressions.
23872387
auto &type = expr.type();
2388-
if(type.id() == ID_struct)
2388+
if(type.id() == ID_struct && type.get_bool(ID_packed))
23892389
{
23902390
auto new_type =
23912391
unsignedbv_typet{numeric_cast_v<std::size_t>(get_width(type))};

0 commit comments

Comments
 (0)