File: t_var_sc_bv.cpp

package info (click to toggle)
verilator 5.038-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 162,552 kB
  • sloc: cpp: 139,204; python: 20,931; ansic: 10,222; yacc: 6,000; lex: 1,925; makefile: 1,260; sh: 494; perl: 282; fortran: 22
file content (222 lines) | stat: -rw-r--r-- 10,044 bytes parent folder | download
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;
}