-
Notifications
You must be signed in to change notification settings - Fork 19
SystemVerilog Unions #560
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SystemVerilog Unions #560
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
KNOWNBUG | ||
unions1.sv | ||
--bound 0 | ||
^EXIT=0$ | ||
^SIGNAL=0$ | ||
-- | ||
-- | ||
cast bitvector to union missing |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
module main; | ||
|
||
union packed { | ||
bit [6:0] field1; | ||
bit [6:0] field2; | ||
} u; | ||
|
||
// bit-vectors can be converted without cast to packed unions | ||
initial u = 7'b1010101; | ||
|
||
// Expected to pass. | ||
p0: assert property ($bits(u) == 7); | ||
p1: assert property (u.field1 == 7'b1010101); | ||
p2: assert property (u.field2 == 7'b1010101); | ||
|
||
endmodule |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
CORE | ||
unions2.sv | ||
--bound 0 | ||
^EXIT=0$ | ||
^SIGNAL=0$ | ||
-- | ||
-- |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
module main; | ||
|
||
union { | ||
bit field1; | ||
bit [6:0] field2; | ||
} u; | ||
|
||
initial begin | ||
u.field2 = 0; | ||
u.field1 = 1; | ||
end | ||
|
||
// Expected to pass. | ||
p1: assert property (u.field1 == 1); | ||
p2: assert property (u.field2 == 1); | ||
p3: assert property ($bits(u) == 7); | ||
|
||
endmodule |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
CORE | ||
unions3.sv | ||
--bound 0 | ||
^EXIT=0$ | ||
^SIGNAL=0$ | ||
-- | ||
-- |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
module main; | ||
|
||
union packed { | ||
// a struct inside a union | ||
struct packed { | ||
bit [7:0] field1; | ||
} field1; | ||
|
||
bit [7:0] field2; | ||
} u; | ||
|
||
initial begin | ||
u.field1.field1 = 123; | ||
end | ||
|
||
// Expected to pass. | ||
p1: assert property (u.field2 == 123); | ||
|
||
endmodule |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,15 +6,17 @@ Author: Daniel Kroening, kroening@kroening.com | |
|
||
\*******************************************************************/ | ||
|
||
#include <cassert> | ||
#include "verilog_typecheck_base.h" | ||
|
||
#include <util/ebmc_util.h> | ||
#include <util/expr_util.h> | ||
#include <util/prefix.h> | ||
#include <util/std_types.h> | ||
|
||
#include "expr2verilog.h" | ||
#include "verilog_typecheck_base.h" | ||
#include "verilog_types.h" | ||
|
||
#include <cassert> | ||
|
||
/*******************************************************************\ | ||
|
||
|
@@ -157,7 +159,7 @@ mp_integer verilog_typecheck_baset::array_offset(const array_typet &type) | |
|
||
/*******************************************************************\ | ||
|
||
Function: verilog_typecheck_baset::get_width | ||
Function: verilog_typecheck_baset::get_width_opt | ||
|
||
Inputs: | ||
|
||
|
@@ -167,7 +169,8 @@ Function: verilog_typecheck_baset::get_width | |
|
||
\*******************************************************************/ | ||
|
||
mp_integer verilog_typecheck_baset::get_width(const typet &type) | ||
std::optional<mp_integer> | ||
verilog_typecheck_baset::get_width_opt(const typet &type) | ||
{ | ||
if(type.id()==ID_bool) | ||
return 1; | ||
|
@@ -178,19 +181,36 @@ mp_integer verilog_typecheck_baset::get_width(const typet &type) | |
|
||
if(type.id()==ID_array) | ||
{ | ||
mp_integer element_width = get_width(to_array_type(type).element_type()); | ||
return (array_size(to_array_type(type)) * element_width).to_ulong(); | ||
auto element_width = get_width_opt(to_array_type(type).element_type()); | ||
if(element_width.has_value()) | ||
return array_size(to_array_type(type)) * element_width.value(); | ||
else | ||
return {}; | ||
} | ||
|
||
if(type.id() == ID_struct) | ||
{ | ||
// add them up | ||
mp_integer sum = 0; | ||
for(auto &component : to_struct_type(type).components()) | ||
sum += get_width(component.type()); | ||
{ | ||
auto component_width = get_width_opt(component.type()); | ||
if(!component_width.has_value()) | ||
return {}; | ||
sum += *component_width; | ||
} | ||
return sum; | ||
} | ||
|
||
if(type.id() == ID_union) | ||
{ | ||
// find the biggest | ||
mp_integer max = 0; | ||
for(auto &component : to_verilog_union_type(type).components()) | ||
max = std::max(max, get_width(component.type())); | ||
return max; | ||
} | ||
Comment on lines
+205
to
+212
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That uses C widths, in bytes, whereas we'd need Verilog widths, in bits. That method would need to take a functor that computes the width of a field. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It uses There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If I make it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So perhaps the better route is to produce an implementation that is similar to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll see of those two pieces of code can become one. |
||
|
||
if(type.id() == ID_verilog_shortint) | ||
return 16; | ||
else if(type.id() == ID_verilog_int) | ||
|
@@ -202,8 +222,30 @@ mp_integer verilog_typecheck_baset::get_width(const typet &type) | |
else if(type.id() == ID_verilog_time) | ||
return 64; | ||
|
||
throw errort().with_location(type.source_location()) | ||
<< "type `" << type.id() << "' has unknown width"; | ||
return {}; | ||
} | ||
|
||
/*******************************************************************\ | ||
|
||
Function: verilog_typecheck_baset::get_width | ||
|
||
Inputs: | ||
|
||
Outputs: | ||
|
||
Purpose: | ||
|
||
\*******************************************************************/ | ||
|
||
mp_integer verilog_typecheck_baset::get_width(const typet &type) | ||
{ | ||
auto width_opt = get_width_opt(type); | ||
|
||
if(width_opt.has_value()) | ||
return std::move(width_opt.value()); | ||
else | ||
throw errort().with_location(type.source_location()) | ||
<< "type `" << type.id() << "' has unknown width"; | ||
} | ||
|
||
/*******************************************************************\ | ||
|
Uh oh!
There was an error while loading. Please reload this page.