Fix operator == for unpacked struct, if elements are VlUnpacked arrays (#4247)

This commit is contained in:
Risto Pejašinović 2023-05-31 14:34:34 +02:00 committed by GitHub
parent 338acabe2b
commit 7f471d862e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 20 deletions

View File

@ -1066,6 +1066,9 @@ struct VlUnpacked final {
// Similar to 'neq' above, *this = that used for change detection
void assign(const VlUnpacked<T_Value, T_Depth>& that) { *this = that; }
bool operator==(const VlUnpacked<T_Value, T_Depth>& that) const { return !neq(that); }
bool operator!=(const VlUnpacked<T_Value, T_Depth>& that) { return neq(that); }
// Dumping. Verilog: str = $sformatf("%p", assoc)
std::string to_string() const {
std::string out = "'{";

View File

@ -17,6 +17,7 @@
#include "config_build.h"
#include "verilatedos.h"
#include "V3Ast.h"
#include "V3EmitC.h"
#include "V3EmitCConstInit.h"
#include "V3Global.h"
@ -239,25 +240,18 @@ class EmitCHeader final : public EmitCConstInit {
puts(";\n");
}
puts("\nbool operator==(const " + EmitCBase::prefixNameProtect(sdtypep) + "& rhs){\n");
puts("\nbool operator==(const " + EmitCBase::prefixNameProtect(sdtypep)
+ "& rhs) const {\n");
puts("return ");
for (const AstMemberDType* itemp = sdtypep->membersp(); itemp;
itemp = VN_AS(itemp->nextp(), MemberDType)) {
if (itemp != sdtypep->membersp()) puts("\n && ");
if (AstUnpackArrayDType* const adtypep
= VN_CAST(itemp->subDTypep(), UnpackArrayDType)) {
for (uint32_t i = 0; i < adtypep->arrayUnpackedElements(); i++) {
if (i != 0) puts("\n && ");
puts(itemp->nameProtect() + "[" + std::to_string(i) + "U] == " + "rhs."
+ itemp->nameProtect() + "[" + std::to_string(i) + "U]");
}
} else {
puts(itemp->nameProtect() + " == " + "rhs." + itemp->nameProtect());
}
puts(itemp->nameProtect() + " == " + "rhs." + itemp->nameProtect());
}
puts(";\n");
puts("}\n");
puts("bool operator!=(const " + EmitCBase::prefixNameProtect(sdtypep) + "& rhs){\n");
puts("bool operator!=(const " + EmitCBase::prefixNameProtect(sdtypep)
+ "& rhs) const {\n");
puts("return !(*this == rhs);\n}\n");
puts("};\n");
}

View File

@ -17,30 +17,47 @@
// SPDX-License-Identifier: CC0-1.0
module t;
typedef struct{
logic [31:0] subarr[4];
} arr_str_t;
typedef struct {
string txt;
struct {
logic m0;
logic [3:0] m1;
logic [7:0] arr[2][3];
arr_str_t str[5];
} sub;
logic [7:0] arr[2];
} struct_t;
struct_t s1;
struct_t s2;
struct_t s3;
assign {s1.sub.m0, s1.sub.m1} = {1'b0, 4'h5};
assign {s2.sub.m0, s2.sub.m1} = {1'b0, 4'h5};
assign s1.txt = "text";
assign s2.txt = "text";
assign s1.arr[0] = 8'h77;
assign s2.arr[0] = 8'h77;
assign s1.arr[1] = 8'h33;
assign s2.arr[1] = 8'h33;
assign {s1.sub.arr[0][0], s2.sub.arr[0][0]} = {8'h01, 8'h01};
assign {s1.sub.arr[0][1], s2.sub.arr[0][1]} = {8'h02, 8'h02};
assign {s1.sub.arr[0][2], s2.sub.arr[0][2]} = {8'h03, 8'h03};
assign {s1.sub.arr[1][0], s2.sub.arr[1][0]} = {8'h04, 8'h04};
assign {s1.sub.arr[1][1], s2.sub.arr[1][1]} = {8'h05, 8'h05};
assign {s1.sub.arr[1][2], s2.sub.arr[1][2]} = {8'h06, 8'h06};
assign {s3.sub.m0, s3.sub.m1} = {1'b0, 4'h5};
assign s3.txt = "text";
assign s3.sub.arr[0][0] = 8'h01;
assign s3.sub.arr[0][1] = 8'h02;
assign s3.sub.arr[0][2] = 8'h03;
assign s3.sub.arr[1][0] = 8'h24; // One mismatch
assign s3.sub.arr[1][1] = 8'h05;
assign s3.sub.arr[1][2] = 8'h06;
initial begin
if(s1 != s2) $stop;
if(s1.sub != s2.sub) $stop;
if(s1 == s2) begin
if(s3 == s1) $stop;
if(s1 == s2 && s3 != s1) begin
$write("*-* All Finished *-*\n");
$finish;
end else begin