// -*- mode: C++; c-file-style: "cc-mode" -*- // //************************************************************************* // // Code available from: https://verilator.org // // Copyright 2022-2023 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 // //************************************************************************* #ifndef T_DIST_ATTRIBUTES_BAD_H_ #define T_DIST_ATTRIBUTES_BAD_H_ #include "verilatedos.h" #include "verilated.h" #include #define NO_ANNOTATION #define CALL_0(prefix, annotation, aarg_type, aarg, val) prefix##_##annotation(val) #define CALL_1(prefix, annotation, aarg_type, aarg, val) prefix##_##annotation(val) #define SIG_ANNOTATED_0(prefix, annotation, aarg_type, aarg, val) \ void prefix##_##annotation(aarg_type aarg) annotation #define SIG_ANNOTATED_1(prefix, annotation, aarg_type, aarg, val) \ void prefix##_##annotation(aarg_type aarg) annotation(aarg) #define SIG_UNANNOTATED_0(prefix, annotation, aarg_type, aarg, val) \ void prefix##_##annotation(aarg_type aarg) #define SIG_UNANNOTATED_1(prefix, annotation, aarg_type, aarg, val) \ void prefix##_##annotation(aarg_type aarg) // clang-format off #define EMIT_ALL(before, sig_prefix, val, after) \ before##_0(sig_prefix, NO_ANNOTATION, VerilatedMutex&, mtx, val) after \ before##_0(sig_prefix, VL_PURE, VerilatedMutex&, mtx, val) after \ before##_0(sig_prefix, VL_MT_SAFE, VerilatedMutex&, mtx, val) after \ before##_0(sig_prefix, VL_MT_SAFE_POSTINIT, VerilatedMutex&, mtx, val) after \ before##_0(sig_prefix, VL_MT_UNSAFE, VerilatedMutex&, mtx, val) after \ before##_0(sig_prefix, VL_MT_UNSAFE_ONE, VerilatedMutex&, mtx, val) after \ before##_0(sig_prefix, VL_MT_START, VerilatedMutex&, mtx, val) after \ before##_1(sig_prefix, VL_ACQUIRE, VerilatedMutex&, mtx, val) after \ before##_1(sig_prefix, VL_REQUIRES, VerilatedMutex&, mtx, val) after \ before##_1(sig_prefix, VL_RELEASE, VerilatedMutex&, mtx, val) after \ before##_1(sig_prefix, VL_ACQUIRE_SHARED, VerilatedMutex&, mtx, val) after \ before##_1(sig_prefix, VL_RELEASE_SHARED, VerilatedMutex&, mtx, val) after \ before##_1(sig_prefix, VL_EXCLUDES, VerilatedMutex&, mtx, val) after \ before##_1(sig_prefix, VL_MT_SAFE_EXCLUDES, VerilatedMutex&, mtx, val) after // clang-format on // Non-Static Functions, Annotated declaration, Unannotated definition. // (declarations) EMIT_ALL(SIG_ANNOTATED, nsf_au, /**/, ;) // Non-Static Functions, Unannotated declaration, Annotated definition. // (declarations) EMIT_ALL(SIG_UNANNOTATED, nsf_ua, /**/, ;) // Non-Static Functions, Annotated declaration, Annotated definition. // (declarations) EMIT_ALL(SIG_ANNOTATED, nsf_aa, /**/, ;) // Non-Static Functions, Annotated declaration, Annotated definition. // Definitions have extra annotations. // (declarations) EMIT_ALL(SIG_ANNOTATED, nsf_ae, /**/, ;) // Non-Static Functions, Annotated declaration, Annotated definition. // Declarations have extra annotations. // (declarations) EMIT_ALL(SIG_ANNOTATED, nsf_ea, /**/, VL_PURE VL_MT_SAFE;) // Non-Static Functions (call test in header). EMIT_ALL(inline SIG_ANNOTATED, nsf_test_caller_func_hdr, /**/, { VerilatedMutex m; EMIT_ALL(CALL, nsf_au, m, ;) EMIT_ALL(CALL, nsf_ua, m, ;) EMIT_ALL(CALL, nsf_aa, m, ;) EMIT_ALL(CALL, nsf_ae, m, ;) EMIT_ALL(CALL, nsf_ea, m, ;) }) // Inline Functions in Header. EMIT_ALL(inline SIG_ANNOTATED, ifh, /**/, {}) // Inline Functions in Header (call test in header). EMIT_ALL(inline SIG_ANNOTATED, ifh_test_caller_func_hdr, /**/, { VerilatedMutex m; EMIT_ALL(CALL, ifh, m, ;) }) struct GuardMe { void safe_if_guarded_or_local() {} operator int() const { return 4; } GuardMe& operator+=(int) { return *this; } }; class TestClass { VerilatedMutex m_mtx; GuardMe m_guardme VL_GUARDED_BY(m_mtx); GuardMe m_guardme_unguarded; public: // Static Class Methods, Annotated declaration, Unannotated definition. // (declarations) EMIT_ALL(static SIG_ANNOTATED, scm_au, /**/, ;) // Static Class Methods, Unannotated declaration, Annotated definition. // (declarations) EMIT_ALL(static SIG_UNANNOTATED, scm_ua, /**/, ;) // Static Class Methods, Annotated declaration, Annotated definition. // (declarations) EMIT_ALL(static SIG_ANNOTATED, scm_aa, /**/, ;) // Static Class Methods, Annotated declaration, Annotated definition. // Definitions have extra annotations. // (declarations) EMIT_ALL(static SIG_ANNOTATED, scm_ae, /**/, ;) // Static Class Methods, Annotated declaration, Annotated definition. // Declarations have extra annotations. // (declarations) EMIT_ALL(static SIG_ANNOTATED, scm_ea, /**/, VL_PURE VL_MT_SAFE;) // Static Class Methods (call test in header). EMIT_ALL(static SIG_ANNOTATED, scm_test_caller_smethod_hdr, /**/, { VerilatedMutex m; EMIT_ALL(CALL, TestClass::scm_au, m, ;) EMIT_ALL(CALL, TestClass::scm_ua, m, ;) EMIT_ALL(CALL, TestClass::scm_aa, m, ;) EMIT_ALL(CALL, TestClass::scm_ae, m, ;) EMIT_ALL(CALL, TestClass::scm_ea, m, ;) TestClass tc; EMIT_ALL(CALL, tc.scm_au, m, ;) EMIT_ALL(CALL, tc.scm_ua, m, ;) EMIT_ALL(CALL, tc.scm_aa, m, ;) EMIT_ALL(CALL, tc.scm_ae, m, ;) EMIT_ALL(CALL, tc.scm_ea, m, ;) TestClass* tcp = &tc; EMIT_ALL(CALL, tcp->scm_au, m, ;) EMIT_ALL(CALL, tcp->scm_ua, m, ;) EMIT_ALL(CALL, tcp->scm_aa, m, ;) EMIT_ALL(CALL, tcp->scm_ae, m, ;) EMIT_ALL(CALL, tcp->scm_ea, m, ;) }) // Static Class Methods (call test). // (declaration) EMIT_ALL(static SIG_ANNOTATED, scm_test_caller_smethod, /**/, ;) // Inline Static Class Methods. EMIT_ALL(static SIG_ANNOTATED, iscm, /**/, {}) // Inline Static Class Methods (call test in header). EMIT_ALL(static SIG_ANNOTATED, iscm_test_caller_smethod_hdr, /**/, { VerilatedMutex m; EMIT_ALL(CALL, TestClass::iscm, m, ;) TestClass tc; EMIT_ALL(CALL, tc.iscm, m, ;) TestClass* tcp = &tc; EMIT_ALL(CALL, tcp->iscm, m, ;) }) // Inline Static Class Methods (call test). // (declaration) EMIT_ALL(static SIG_ANNOTATED, iscm_test_caller_smethod, /**/, ;) // Class Methods, Annotated declaration, Unannotated definition. // (declarations) EMIT_ALL(SIG_ANNOTATED, cm_au, /**/, ;) // Class Methods, Unannotated declaration, Annotated definition. // (declarations) EMIT_ALL(SIG_UNANNOTATED, cm_ua, /**/, ;) // Class Methods, Annotated declaration, Annotated definition. // (declarations) EMIT_ALL(SIG_ANNOTATED, cm_aa, /**/, ;) // Class Methods, Annotated declaration, Annotated definition. // Definitions have extra annotations. // (declarations) EMIT_ALL(SIG_ANNOTATED, cm_ae, /**/, ;) // Class Methods, Annotated declaration, Annotated definition. // Declarations have extra annotations. // (declarations) EMIT_ALL(SIG_ANNOTATED, cm_ea, /**/, VL_PURE VL_MT_SAFE;) // Class Methods (call test in header). EMIT_ALL(SIG_ANNOTATED, cm_test_caller_smethod_hdr, /**/, { VerilatedMutex m; TestClass tc; EMIT_ALL(CALL, tc.cm_au, m, ;) EMIT_ALL(CALL, tc.cm_ua, m, ;) EMIT_ALL(CALL, tc.cm_aa, m, ;) EMIT_ALL(CALL, tc.cm_ae, m, ;) EMIT_ALL(CALL, tc.cm_ea, m, ;) TestClass* tcp = &tc; EMIT_ALL(CALL, tcp->cm_au, m, ;) EMIT_ALL(CALL, tcp->cm_ua, m, ;) EMIT_ALL(CALL, tcp->cm_aa, m, ;) EMIT_ALL(CALL, tcp->cm_ae, m, ;) EMIT_ALL(CALL, tcp->cm_ea, m, ;) }) // Class Methods (call test). // (declaration) EMIT_ALL(SIG_ANNOTATED, cm_test_caller_smethod, /**/, ;) // Inline Class Methods. EMIT_ALL(SIG_ANNOTATED, icm, /**/, {}) // Inline Class Methods (call test in header). EMIT_ALL(SIG_ANNOTATED, icm_test_caller_smethod_hdr, /**/, { VerilatedMutex m; TestClass tc; EMIT_ALL(CALL, tc.icm, m, ;) TestClass* tcp = &tc; EMIT_ALL(CALL, tcp->icm, m, ;) }) // Inline Class Methods (call test). // (declaration) EMIT_ALL(SIG_ANNOTATED, icm_test_caller_smethod, /**/, ;) void guarded_by_test_pass(GuardMe& guardme_arg) VL_MT_SAFE { guardme_arg.safe_if_guarded_or_local(); int a = guardme_arg; guardme_arg += 4; m_mtx.lock(); m_guardme.safe_if_guarded_or_local(); int b = m_guardme; m_guardme += 4; m_mtx.unlock(); GuardMe guardme_local; guardme_local.safe_if_guarded_or_local(); int c = guardme_local; guardme_local += 4; } void guarded_by_test_fail() VL_MT_SAFE { m_guardme_unguarded.safe_if_guarded_or_local(); int a = m_guardme_unguarded; m_guardme_unguarded += 4; } }; #endif // T_DIST_ATTRIBUTES_BAD_H_