Skip to content

Commit 3cb42a8

Browse files
committed
SystemVerilog Unions
This adds basic support for SystemVerilog unions.
1 parent 73ecda7 commit 3cb42a8

13 files changed

+167
-8
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
KNOWNBUG
2+
unions1.sv
3+
--bound 0
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
--
8+
cast bitvector to union missing

regression/verilog/unions/unions1.sv

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
module main;
2+
3+
union packed {
4+
bit [6:0] field1;
5+
bit [6:0] field2;
6+
} u;
7+
8+
// bit-vectors can be converted without cast to packed unions
9+
initial u = 7'b1010101;
10+
11+
// Expected to pass.
12+
p0: assert property ($bits(u) == 7);
13+
p1: assert property (u.field1 == 7'b1010101);
14+
p2: assert property (u.field2 == 7'b1010101);
15+
16+
endmodule
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CORE
2+
unions2.sv
3+
--bound 0
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
--

regression/verilog/unions/unions2.sv

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module main;
2+
3+
union {
4+
bit field1;
5+
bit [6:0] field2;
6+
} u;
7+
8+
initial begin
9+
u.field2 = 0;
10+
u.field1 = 1;
11+
end
12+
13+
// Expected to pass.
14+
p1: assert property (u.field1 == 1);
15+
p2: assert property (u.field2 == 1);
16+
p3: assert property ($bits(u) == 7);
17+
18+
endmodule
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CORE
2+
unions3.sv
3+
--bound 0
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
--

regression/verilog/unions/unions3.sv

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
module main;
2+
3+
union packed {
4+
// a struct inside a union
5+
struct packed {
6+
bit [7:0] field1;
7+
} field1;
8+
9+
bit [7:0] field2;
10+
} u;
11+
12+
initial begin
13+
u.field1.field1 = 123;
14+
end
15+
16+
// Expected to pass.
17+
p1: assert property (u.field2 == 123);
18+
19+
endmodule

src/hw_cbmc_irep_ids.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ IREP_ID_ONE(wand)
149149
IREP_ID_ONE(automatic)
150150
IREP_ID_TWO(C_verilog_type, #verilog_type)
151151
IREP_ID_ONE(verilog_enum)
152+
IREP_ID_ONE(verilog_packed)
152153
IREP_ID_ONE(verilog_packed_array)
153154
IREP_ID_ONE(verilog_type_reference)
154155
IREP_ID_ONE(verilog_unpacked_array)

src/verilog/verilog_synthesis.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,9 @@ void verilog_synthesist::assignment_rec(
831831
const exprt &lhs_compound = member_expr.struct_op();
832832
auto component_name = member_expr.get_component_name();
833833

834-
if(lhs_compound.type().id() == ID_struct)
834+
if(
835+
lhs_compound.type().id() == ID_struct ||
836+
lhs_compound.type().id() == ID_union)
835837
{
836838
// turn
837839
// s.m=e

src/verilog/verilog_typecheck_base.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,17 @@ Author: Daniel Kroening, kroening@kroening.com
66
77
\*******************************************************************/
88

9-
#include <cassert>
9+
#include "verilog_typecheck_base.h"
1010

1111
#include <util/ebmc_util.h>
1212
#include <util/expr_util.h>
1313
#include <util/prefix.h>
1414
#include <util/std_types.h>
1515

1616
#include "expr2verilog.h"
17-
#include "verilog_typecheck_base.h"
17+
#include "verilog_types.h"
18+
19+
#include <cassert>
1820

1921
/*******************************************************************\
2022
@@ -191,6 +193,15 @@ mp_integer verilog_typecheck_baset::get_width(const typet &type)
191193
return sum;
192194
}
193195

196+
if(type.id() == ID_union)
197+
{
198+
// find the biggest
199+
mp_integer max = 0;
200+
for(auto &component : to_verilog_union_type(type).components())
201+
max = std::max(max, get_width(component.type()));
202+
return max;
203+
}
204+
194205
if(type.id() == ID_verilog_shortint)
195206
return 16;
196207
else if(type.id() == ID_verilog_int)

0 commit comments

Comments
 (0)