From 8918f17c17443c420444cdd3cf14a466a45908af Mon Sep 17 00:00:00 2001 From: Ilya Barkov <37960110+Zvord@users.noreply.github.com> Date: Sat, 21 Jan 2023 21:20:02 +0300 Subject: [PATCH] Support class queue equality (#3895) --- include/verilated_types.h | 7 ++++ test_regress/t/t_assoc_compare.pl | 21 ++++++++++ test_regress/t/t_assoc_compare.v | 67 +++++++++++++++++++++++++++++++ test_regress/t/t_class_compare.pl | 21 ++++++++++ test_regress/t/t_class_compare.v | 27 +++++++++++++ test_regress/t/t_queue_compare.pl | 21 ++++++++++ test_regress/t/t_queue_compare.v | 61 ++++++++++++++++++++++++++++ 7 files changed, 225 insertions(+) create mode 100755 test_regress/t/t_assoc_compare.pl create mode 100644 test_regress/t/t_assoc_compare.v create mode 100755 test_regress/t/t_class_compare.pl create mode 100644 test_regress/t/t_class_compare.v create mode 100755 test_regress/t/t_queue_compare.pl create mode 100644 test_regress/t/t_queue_compare.v diff --git a/include/verilated_types.h b/include/verilated_types.h index 22185477d..1442f7d1d 100644 --- a/include/verilated_types.h +++ b/include/verilated_types.h @@ -273,6 +273,8 @@ public: VlQueue(VlQueue&&) = default; VlQueue& operator=(const VlQueue&) = default; VlQueue& operator=(VlQueue&&) = default; + bool operator==(const VlQueue& rhs) const { return m_deque == rhs.m_deque; } + bool operator!=(const VlQueue& rhs) const { return m_deque != rhs.m_deque; } // Standard copy constructor works. Verilog: assoca = assocb // Also must allow conversion from a different T_MaxSize queue @@ -692,6 +694,8 @@ public: VlAssocArray(VlAssocArray&&) = default; VlAssocArray& operator=(const VlAssocArray&) = default; VlAssocArray& operator=(VlAssocArray&&) = default; + bool operator==(const VlAssocArray& rhs) const { return m_map == rhs.m_map; } + bool operator!=(const VlAssocArray& rhs) const { return m_map != rhs.m_map; } // METHODS T_Value& atDefault() { return m_defaultValue; } @@ -1225,6 +1229,9 @@ public: T_Class* operator->() const { return m_objp; } // For 'if (ptr)...' operator bool() const { return m_objp; } + // In SV A == B iff both are handles to the same object (IEEE 1800-2017 8.4) + bool operator==(const VlClassRef& rhs) const { return m_objp == rhs.m_objp; }; + bool operator!=(const VlClassRef& rhs) const { return m_objp != rhs.m_objp; }; }; template diff --git a/test_regress/t/t_assoc_compare.pl b/test_regress/t/t_assoc_compare.pl new file mode 100755 index 000000000..9a15dd2cc --- /dev/null +++ b/test_regress/t/t_assoc_compare.pl @@ -0,0 +1,21 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2019 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(simulator => 1); + +compile( + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_assoc_compare.v b/test_regress/t/t_assoc_compare.v new file mode 100644 index 000000000..1311b7cab --- /dev/null +++ b/test_regress/t/t_assoc_compare.v @@ -0,0 +1,67 @@ +// DESCRIPTION: Verilator: Check == and != operations performed on associative arrays +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2023 by Ilya Barkov. +// SPDX-License-Identifier: CC0-1.0 + +`define stop $stop +`define check_comp(lhs, rhs, op, exp) if ((exp) != ((lhs) op (rhs))) begin $write("%%Error: %s:%0d: op comparison shall return 'b%x\n", `__FILE__, `__LINE__, (exp)); `stop; end +// Two checks because == and != may not be derived from each other +`define check_eq(lhs, rhs) `check_comp(lhs, rhs, ==, 1'b1) `check_comp(lhs, rhs, !=, 1'b0) +`define check_ne(lhs, rhs) `check_comp(lhs, rhs, ==, 1'b0) `check_comp(lhs, rhs, !=, 1'b1) + +class Cls; + int i; +endclass + +module t; + initial begin + begin // simple case + int assoc1[int]; + int assoc2[int]; + // Empty are equal + `check_eq(assoc1, assoc2) + // Make different + assoc1[10] = 15; + assoc2[-1] = 365; + `check_ne(assoc1, assoc2) + // Make same + assoc1[-1] = 365; + assoc2[10] = 15; + `check_eq(assoc1, assoc2) + // Don't actually change + assoc1[-1] = 365; + `check_eq(assoc1, assoc2) + // Compare different sizes + assoc1[3] = 0; + `check_ne(assoc1, assoc2) + end + begin // check that a class as key is fine + int assoc1[Cls]; + int assoc2[Cls]; + Cls a = new; + Cls b = new; + int t; + assoc1[a] = 0; + `check_ne(assoc1, assoc2) + assoc2[a] = 0; + `check_eq(assoc1, assoc2) + assoc2.delete(a); + assoc2[b] = 0; + `check_ne(assoc1, assoc2) + end + begin // check that a class as value is fine + Cls assoc1[int]; + Cls assoc2[int]; + Cls a = new; + Cls b = new; + assoc1[1] = a; + assoc2[1] = b; + `check_ne(assoc1, assoc2) + assoc2[1] = a; + `check_eq(assoc1, assoc2) + end + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/t_class_compare.pl b/test_regress/t/t_class_compare.pl new file mode 100755 index 000000000..9a15dd2cc --- /dev/null +++ b/test_regress/t/t_class_compare.pl @@ -0,0 +1,21 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2019 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(simulator => 1); + +compile( + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_class_compare.v b/test_regress/t/t_class_compare.v new file mode 100644 index 000000000..ee4826725 --- /dev/null +++ b/test_regress/t/t_class_compare.v @@ -0,0 +1,27 @@ +// DESCRIPTION: Verilator: Check == and != operations performed on class objects +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2023 by Ilya Barkov. +// SPDX-License-Identifier: CC0-1.0 + +`define stop $stop +`define check_comp(lhs, rhs, op, exp) if ((exp) != ((lhs) op (rhs))) begin $write("%%Error: %s:%0d: op comparison shall return 'b%x\n", `__FILE__, `__LINE__, (exp)); `stop; end +// Two checks because == and != may not be derived from each other +`define check_eq(lhs, rhs) `check_comp(lhs, rhs, ==, 1'b1) `check_comp(lhs, rhs, !=, 1'b0) +`define check_ne(lhs, rhs) `check_comp(lhs, rhs, ==, 1'b0) `check_comp(lhs, rhs, !=, 1'b1) + +class Cls; + int i; +endclass + +module t; + initial begin + Cls a = new; + Cls b = new; + `check_ne(a, b) + a = b; + `check_eq(a, b) + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/t_queue_compare.pl b/test_regress/t/t_queue_compare.pl new file mode 100755 index 000000000..9a15dd2cc --- /dev/null +++ b/test_regress/t/t_queue_compare.pl @@ -0,0 +1,21 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2019 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(simulator => 1); + +compile( + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_queue_compare.v b/test_regress/t/t_queue_compare.v new file mode 100644 index 000000000..2ae40e991 --- /dev/null +++ b/test_regress/t/t_queue_compare.v @@ -0,0 +1,61 @@ +// DESCRIPTION: Verilator: Check == and != operations performed on queues +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2023 by Ilya Barkov. +// SPDX-License-Identifier: CC0-1.0 + +`define stop $stop +`define check_comp(lhs, rhs, op, exp) if ((exp) != ((lhs) op (rhs))) begin $write("%%Error: %s:%0d: op comparison shall return 'b%x\n", `__FILE__, `__LINE__, (exp)); `stop; end +// Two checks because == and != may not be derived from each other +`define check_eq(lhs, rhs) `check_comp(lhs, rhs, ==, 1'b1) `check_comp(lhs, rhs, !=, 1'b0) +`define check_ne(lhs, rhs) `check_comp(lhs, rhs, ==, 1'b0) `check_comp(lhs, rhs, !=, 1'b1) + +class Cls; + int i; +endclass + +module t; + initial begin + begin // integers + int q1[$]; + bit[31:0] q2[$]; + q1.push_back(1); + q2.push_back(1); + q1.push_back(-2); + q2.push_back(-2); + `check_eq(q1, q2) + + q2.push_back(3); + `check_ne(q1, q2) + end + begin // strings + string q1[$]; + string q2[$]; + q1.push_back("one"); + q2.push_back("one"); + q1.push_back("two"); + q2.push_back("two"); + `check_eq(q1, q2) + + q2.push_back("three"); + `check_ne(q1, q2) + end + + begin // classes + Cls a = new; + Cls b = new; + Cls q1[$]; + Cls q2[$]; + q1.push_back(a); + q2.push_back(b); + `check_ne(q1, q2) + + q1.push_back(b); + q2.push_front(a); + `check_eq(q1, q2) + end + + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule