Merge pull request #1034 from smunaut/fix-for-structs

Couple of fixes for struct supports
This commit is contained in:
Cary R 2023-11-16 03:37:18 -08:00 committed by GitHub
commit c9548f0332
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 90 additions and 6 deletions

View File

@ -2486,8 +2486,8 @@ static NetExpr* check_for_struct_members(const LineInfo*li,
} else if (const netenum_t*tmp_enum = dynamic_cast<const netenum_t*> (member_type)) {
// If the element is an enum, then we don't have
// anything special to do.
// If the element is an enum, then we only need to check if
// there is a part select for it
if (debug_elaborate) {
cerr << li->get_fileline() << ": check_for_struct_members: "
<< "Tail element is an enum" << *tmp_enum
@ -2495,6 +2495,24 @@ static NetExpr* check_for_struct_members(const LineInfo*li,
}
struct_type = 0;
if (!member_comp.index.empty()) {
if (member_comp.index.size() > 1) {
cerr << li->get_fileline() << ": error: "
<< "Too many index expressions for enum member." << endl;
des->errors += 1;
return 0;
}
long tail_off = 0;
unsigned long tail_wid = 0;
bool rc = calculate_part(li, des, scope, member_comp.index.back(), tail_off, tail_wid);
if (! rc) return 0;
off += tail_off;
use_width = tail_wid;
}
} else if (const netvector_t*mem_vec = dynamic_cast<const netvector_t*>(member_type)) {
if (debug_elaborate) {

View File

@ -2172,10 +2172,17 @@ static bool get_array_info(const NetExpr*arg, long dim,
long &left, long &right, bool&defer)
{
if (const NetEConstParam*param = dynamic_cast<const NetEConstParam*>(arg)) {
ivl_assert(*arg, dim == 1);
left = param->expr_width() - 1;
right = 0;
return false;
ivl_assert(*arg, dim == 1);
left = param->expr_width() - 1;
right = 0;
return false;
}
if (const NetESelect*select = dynamic_cast<const NetESelect*>(arg)) {
const netranges_t&dim_vals = select->net_type()->slice_dimensions();
const netrange_t&range = dim_vals[dim-1];
left = range.get_msb();
right = range.get_lsb();
return false;
}
/* The argument must be a signal that has enough dimensions. */
const NetESignal*esig = dynamic_cast<const NetESignal*>(arg);

View File

@ -0,0 +1,24 @@
module main;
typedef enum logic [2:0] {
ENUM_VAL = 3'b110
} enumtype;
typedef struct packed {
enumtype e;
} structtype;
structtype s;
initial
begin
s.e = ENUM_VAL;
$display("s.e[2] = %d, s.e[1] = %d, s.e[0] = %d", s.e[2], s.e[1], s.e[0]);
if ((s.e[2] != 1'b1) || (s.e[1] != 1'b1) || (s.e[0] != 1'b0)) begin
$display("FAILED");
$finish;
end
$display("PASSED");
end
endmodule

View File

@ -0,0 +1,23 @@
module main;
typedef struct packed {
logic [15:8] f;
} structtype;
structtype s;
initial
begin
$display("$left(s.f) = %2d, $right(s.f) = %2d", $left(s.f), $right(s.f));
if ($left(s.f) !== 15) begin
$display("FAILED -- $left(s.f) = %2d", $left(s.f));
$finish;
end
if ($right(s.f) !== 8) begin
$display("FAILED -- $right(s.f) = %2d", $right(s.f));
$finish;
end
$display("PASSED");
end
endmodule

View File

@ -46,6 +46,8 @@ pr903 vvp_tests/pr903.json
pr903-vlog95 vvp_tests/pr903-vlog95.json
pv_wr_fn_vec2 vvp_tests/pv_wr_fn_vec2.json
pv_wr_fn_vec4 vvp_tests/pv_wr_fn_vec4.json
struct_enum_partsel vvp_tests/struct_enum_partsel.json
struct_field_left_right vvp_tests/struct_field_left_right.json
struct_packed_write_read vvp_tests/struct_packed_write_read.json
struct_packed_write_read2 vvp_tests/struct_packed_write_read2.json
sv_2state_array_init_prop vvp_tests/sv_2state_array_init_prop.json

View File

@ -0,0 +1,5 @@
{
"type" : "normal",
"source" : "struct_enum_partsel.v",
"iverilog-args" : [ "-g2009" ]
}

View File

@ -0,0 +1,5 @@
{
"type" : "normal",
"source" : "struct_field_left_right.v",
"iverilog-args" : [ "-g2009" ]
}