1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
|
// -*- mode: C++; c-file-style: "cc-mode" -*-
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2022 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
#include VM_PREFIX_INCLUDE
using namespace sc_core;
using namespace sc_dt;
VM_PREFIX* tb = nullptr;
bool pass = true;
double sc_time_stamp() { return 0; }
void compare_signals(const sc_signal<sc_bv<256>>& ls, const sc_signal<sc_bv<256>>& rs) {
if (ls.read() != rs.read()) {
pass &= false;
VL_PRINTF("%%Error: Data mismatch in signals %s and %s\n", ls.name(), rs.name());
}
}
void compareWls(int obits, WDataInP const lwp, WDataInP const rwp) {
const int words = VL_WORDS_I(obits);
bool same = true;
for (int i = 0; (i < (words - 1)); ++i) {
if (lwp[i] != rwp[i]) same = false;
}
if ((lwp[words - 1] & VL_MASK_E(obits)) != (rwp[words - 1] & VL_MASK_E(obits))) {
same = false;
}
if (!same) {
pass &= false;
VL_PRINTF("%%Error: There is a difference in VlWide variable %d bits wide\n", obits);
}
}
// old macro which is correct but has MT issue with range
#define VL_ASSIGN_SBW_MT_ISSUE(obits, svar, rwp) \
{ \
sc_biguint<(obits)> _butemp; \
for (int i = 0; i < VL_WORDS_I(obits); ++i) { \
int msb = ((i + 1) * VL_IDATASIZE) - 1; \
msb = (msb >= (obits)) ? ((obits)-1) : msb; \
_butemp.range(msb, i* VL_IDATASIZE) = (rwp)[i]; \
} \
(svar).write(_butemp); \
}
#ifdef SYSTEMC_VERSION
int sc_main(int, char**)
#else
int main()
#endif
{
Verilated::debug(0);
tb = new VM_PREFIX{"tb"};
VlWide<8> /*255:0*/ input_var;
VlWide<8> /*255:0*/ out_var;
// msb is always set to F not to be false positive on checking equality
input_var.m_storage[0] = 0xF2341234;
input_var.m_storage[1] = 0xFEADBEEF;
input_var.m_storage[2] = 0xF5A5A5A5;
input_var.m_storage[3] = 0xF1B2C3D4;
input_var.m_storage[4] = 0xFFFFFFFF;
input_var.m_storage[5] = 0xFAAABBBB;
input_var.m_storage[6] = 0xF000AAAA;
input_var.m_storage[7] = 0xF0101010;
#ifdef SYSTEMC_VERSION
// clang-format off
sc_signal<sc_bv<256>> SC_NAMED(i_29_s), SC_NAMED(i_29_old_s), SC_NAMED(o_29_s), SC_NAMED(o_29_old_s),
SC_NAMED(i_30_s), SC_NAMED(i_30_old_s), SC_NAMED(o_30_s), SC_NAMED(o_30_old_s),
SC_NAMED(i_31_s), SC_NAMED(i_31_old_s), SC_NAMED(o_31_s), SC_NAMED(o_31_old_s),
SC_NAMED(i_32_s), SC_NAMED(i_32_old_s), SC_NAMED(o_32_s), SC_NAMED(o_32_old_s),
SC_NAMED(i_59_s), SC_NAMED(i_59_old_s), SC_NAMED(o_59_s), SC_NAMED(o_59_old_s),
SC_NAMED(i_60_s), SC_NAMED(i_60_old_s), SC_NAMED(o_60_s), SC_NAMED(o_60_old_s),
SC_NAMED(i_62_s), SC_NAMED(i_62_old_s), SC_NAMED(o_62_s), SC_NAMED(o_62_old_s),
SC_NAMED(i_64_s), SC_NAMED(i_64_old_s), SC_NAMED(o_64_s), SC_NAMED(o_64_old_s),
SC_NAMED(i_119_s), SC_NAMED(i_119_old_s), SC_NAMED(o_119_s), SC_NAMED(o_119_old_s),
SC_NAMED(i_120_s), SC_NAMED(i_120_old_s), SC_NAMED(o_120_s), SC_NAMED(o_120_old_s),
SC_NAMED(i_121_s), SC_NAMED(i_121_old_s), SC_NAMED(o_121_s), SC_NAMED(o_121_old_s),
SC_NAMED(i_127_s), SC_NAMED(i_127_old_s), SC_NAMED(o_127_s), SC_NAMED(o_127_old_s),
SC_NAMED(i_128_s), SC_NAMED(i_128_old_s), SC_NAMED(o_128_s), SC_NAMED(o_128_old_s),
SC_NAMED(i_255_s), SC_NAMED(i_255_old_s), SC_NAMED(o_255_s), SC_NAMED(o_255_old_s),
SC_NAMED(i_256_s), SC_NAMED(i_256_old_s), SC_NAMED(o_256_s), SC_NAMED(o_256_old_s);
tb->i_29(i_29_s); tb->i_29_old(i_29_old_s); tb->o_29(o_29_s); tb->o_29_old(o_29_old_s);
tb->i_30(i_30_s); tb->i_30_old(i_30_old_s); tb->o_30(o_30_s); tb->o_30_old(o_30_old_s);
tb->i_31(i_31_s); tb->i_31_old(i_31_old_s); tb->o_31(o_31_s); tb->o_31_old(o_31_old_s);
tb->i_32(i_32_s); tb->i_32_old(i_32_old_s); tb->o_32(o_32_s); tb->o_32_old(o_32_old_s);
tb->i_59(i_59_s); tb->i_59_old(i_59_old_s); tb->o_59(o_59_s); tb->o_59_old(o_59_old_s);
tb->i_60(i_60_s); tb->i_60_old(i_60_old_s); tb->o_60(o_60_s); tb->o_60_old(o_60_old_s);
tb->i_62(i_62_s); tb->i_62_old(i_62_old_s); tb->o_62(o_62_s); tb->o_62_old(o_62_old_s);
tb->i_64(i_64_s); tb->i_64_old(i_64_old_s); tb->o_64(o_64_s); tb->o_64_old(o_64_old_s);
tb->i_119(i_119_s); tb->i_119_old(i_119_old_s); tb->o_119(o_119_s); tb->o_119_old(o_119_old_s);
tb->i_120(i_120_s); tb->i_120_old(i_120_old_s); tb->o_120(o_120_s); tb->o_120_old(o_120_old_s);
tb->i_121(i_121_s); tb->i_121_old(i_121_old_s); tb->o_121(o_121_s); tb->o_121_old(o_121_old_s);
tb->i_127(i_127_s); tb->i_127_old(i_127_old_s); tb->o_127(o_127_s); tb->o_127_old(o_127_old_s);
tb->i_128(i_128_s); tb->i_128_old(i_128_old_s); tb->o_128(o_128_s); tb->o_128_old(o_128_old_s);
tb->i_255(i_255_s); tb->i_255_old(i_255_old_s); tb->o_255(o_255_s); tb->o_255_old(o_255_old_s);
tb->i_256(i_256_s); tb->i_256_old(i_256_old_s); tb->o_256(o_256_s); tb->o_256_old(o_256_old_s);
// clang-format on
#endif
#ifdef SYSTEMC_VERSION
sc_start(1, SC_NS);
#else
tb->eval();
#endif
// This testcase is testing multi-thread safe VL_ASSIGN_SBW and VL_ASSIGN_WSB macros.
// Testbench is assigning different number of bits from VlWide input_var variable to different
// inputs. Values around multiple of 30 (i.e. BITS_PER_DIGIT defined in SystemC sc_nbdefs.h)
// are tested with the special care, since it is the value by which the data_ptr of sc_biguint
// underlying data type is increased by (and not expected 32, as width of uint32_t).
// Correctness of the output is compared against the 'old' macro, which is correct but has
// multi-threaded issue since it's using range function. Second part is testing VL_ASSIGN_WSB
// in a reverse way, it is reading signals from the previous test, and comparing the output
// with (fraction) of VlWide input_var variable.
VL_ASSIGN_SBW(29, i_29_s, input_var);
VL_ASSIGN_SBW_MT_ISSUE(29, i_29_old_s, input_var);
VL_ASSIGN_SBW(30, i_30_s, input_var);
VL_ASSIGN_SBW_MT_ISSUE(30, i_30_old_s, input_var);
VL_ASSIGN_SBW(31, i_31_s, input_var);
VL_ASSIGN_SBW_MT_ISSUE(31, i_31_old_s, input_var);
VL_ASSIGN_SBW(32, i_32_s, input_var);
VL_ASSIGN_SBW_MT_ISSUE(32, i_32_old_s, input_var);
VL_ASSIGN_SBW(59, i_59_s, input_var);
VL_ASSIGN_SBW_MT_ISSUE(59, i_59_old_s, input_var);
VL_ASSIGN_SBW(60, i_60_s, input_var);
VL_ASSIGN_SBW_MT_ISSUE(60, i_60_old_s, input_var);
VL_ASSIGN_SBW(62, i_62_s, input_var);
VL_ASSIGN_SBW_MT_ISSUE(62, i_62_old_s, input_var);
VL_ASSIGN_SBW(64, i_64_s, input_var);
VL_ASSIGN_SBW_MT_ISSUE(64, i_64_old_s, input_var);
VL_ASSIGN_SBW(119, i_119_s, input_var);
VL_ASSIGN_SBW_MT_ISSUE(119, i_119_old_s, input_var);
VL_ASSIGN_SBW(120, i_120_s, input_var);
VL_ASSIGN_SBW_MT_ISSUE(120, i_120_old_s, input_var);
VL_ASSIGN_SBW(121, i_121_s, input_var);
VL_ASSIGN_SBW_MT_ISSUE(121, i_121_old_s, input_var);
VL_ASSIGN_SBW(127, i_127_s, input_var);
VL_ASSIGN_SBW_MT_ISSUE(127, i_127_old_s, input_var);
VL_ASSIGN_SBW(128, i_128_s, input_var);
VL_ASSIGN_SBW_MT_ISSUE(128, i_128_old_s, input_var);
VL_ASSIGN_SBW(255, i_255_s, input_var);
VL_ASSIGN_SBW_MT_ISSUE(255, i_255_old_s, input_var);
VL_ASSIGN_SBW(256, i_256_s, input_var);
VL_ASSIGN_SBW_MT_ISSUE(256, i_256_old_s, input_var);
#ifdef SYSTEMC_VERSION
sc_start(1, SC_NS);
#else
tb->eval();
#endif
compare_signals(o_29_s, o_29_old_s);
compare_signals(o_30_s, o_30_old_s);
compare_signals(o_31_s, o_31_old_s);
compare_signals(o_32_s, o_32_old_s);
compare_signals(o_59_s, o_59_old_s);
compare_signals(o_60_s, o_60_old_s);
compare_signals(o_62_s, o_62_old_s);
compare_signals(o_64_s, o_64_old_s);
compare_signals(o_119_s, o_119_old_s);
compare_signals(o_120_s, o_120_old_s);
compare_signals(o_121_s, o_121_old_s);
compare_signals(o_127_s, o_127_old_s);
compare_signals(o_128_s, o_128_old_s);
compare_signals(o_255_s, o_255_old_s);
compare_signals(o_256_s, o_256_old_s);
////////////////////////////////
VL_ASSIGN_WSB(29, out_var, o_29_s);
compareWls(29, input_var.data(), out_var.data());
VL_ASSIGN_WSB(30, out_var, o_30_s);
compareWls(30, input_var.data(), out_var.data());
VL_ASSIGN_WSB(31, out_var, o_31_s);
compareWls(31, input_var.data(), out_var.data());
VL_ASSIGN_WSB(32, out_var, o_32_s);
compareWls(32, input_var.data(), out_var.data());
VL_ASSIGN_WSB(59, out_var, o_59_s);
compareWls(59, input_var.data(), out_var.data());
VL_ASSIGN_WSB(60, out_var, o_60_s);
compareWls(60, input_var.data(), out_var.data());
VL_ASSIGN_WSB(62, out_var, o_62_s);
compareWls(62, input_var.data(), out_var.data());
VL_ASSIGN_WSB(64, out_var, o_64_s);
compareWls(64, input_var.data(), out_var.data());
VL_ASSIGN_WSB(119, out_var, o_119_s);
compareWls(119, input_var.data(), out_var.data());
VL_ASSIGN_WSB(120, out_var, o_120_s);
compareWls(120, input_var.data(), out_var.data());
VL_ASSIGN_WSB(121, out_var, o_121_s);
compareWls(121, input_var.data(), out_var.data());
VL_ASSIGN_WSB(127, out_var, o_127_s);
compareWls(127, input_var.data(), out_var.data());
VL_ASSIGN_WSB(128, out_var, o_128_s);
compareWls(128, input_var.data(), out_var.data());
VL_ASSIGN_WSB(255, out_var, o_255_s);
compareWls(255, input_var.data(), out_var.data());
VL_ASSIGN_WSB(256, out_var, o_256_s);
compareWls(256, input_var.data(), out_var.data());
tb->final();
VL_DO_DANGLING(delete tb, tb);
if (pass) {
VL_PRINTF("*-* All Finished *-*\n");
} else {
vl_fatal(__FILE__, __LINE__, "top", "Unexpected results from test\n");
}
return 0;
}
|