File: t_dpi_var.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 (148 lines) | stat: -rw-r--r-- 4,935 bytes parent folder | download | duplicates (2)
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
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2010-2011 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
//
//*************************************************************************

#include VM_PREFIX_INCLUDE
#include "verilated.h"
#include "verilated_syms.h"

#include "svdpi.h"

//======================================================================

struct MyMon {
    uint32_t* sigsp[2];
    MyMon() {
        sigsp[0] = NULL;
        sigsp[1] = NULL;
    }
};
MyMon mons[2];

void mon_register_a(const char* namep, void* sigp, bool isOut) {
    // Callback from initial block in monitor
#ifdef TEST_VERBOSE
    VL_PRINTF("-     mon_register_a(\"%s\", %p, %d);\n", namep, sigp, isOut);
#endif
    mons[0].sigsp[isOut] = (uint32_t*)sigp;
}

void mon_do(MyMon* monp) {
    if (!monp->sigsp[0]) vl_fatal(__FILE__, __LINE__, "", "never registered");
    if (!monp->sigsp[1]) vl_fatal(__FILE__, __LINE__, "", "never registered");
    *monp->sigsp[1] = (*(monp->sigsp[0])) + 1;

#ifdef TEST_VERBOSE
    VL_PRINTF("-     mon_do(%08x(&%p) -> %08x(&%p));\n", *(monp->sigsp[0]), monp->sigsp[0],
              *(monp->sigsp[1]), monp->sigsp[1]);
#endif
}

void mon_class_name(const char* namep) {
#ifdef TEST_VERBOSE
    VL_PRINTF("-     mon_class_name(\"%s\");\n", namep);
#endif
    // Check the C's calling name of "" doesn't lead to extra dots in the name()
    if (namep && namep[0] == '.')
        vl_fatal(__FILE__, __LINE__, "", ("Unexp class name "s + namep).c_str());
}

extern "C" void mon_scope_name(const char* namep);
void mon_scope_name(const char* namep) {
    const char* modp = svGetNameFromScope(svGetScope());
#ifdef TEST_VERBOSE
    VL_PRINTF("-     mon_scope_name('%s', \"%s\");\n", modp, namep);
#endif
    if (std::strcmp(namep, "t.sub"))
        vl_fatal(__FILE__, __LINE__, "", ("Unexp scope name "s + namep).c_str());
    if (std::strcmp(modp, "t.sub"))
        vl_fatal(__FILE__, __LINE__, "", ("Unexp dpiscope name "s + modp).c_str());
}

extern "C" void mon_register_b(const char* namep, int isOut);
void mon_register_b(const char* namep, int isOut) {
    const char* modp = svGetNameFromScope(svGetScope());
#ifdef TEST_VERBOSE
    VL_PRINTF("-     mon_register_b('%s', \"%s\", %d);\n", modp, namep, isOut);
#endif
    // Use scope to get pointer and size of signal
    const VerilatedScope* scopep = Verilated::dpiScope();
    const VerilatedVar* varp = scopep->varFind(namep);
    if (!varp) {
        VL_PRINTF("%%Warning: mon_register_b signal not found: \"%s\"\n", namep);
    } else if (varp->vltype() != VLVT_UINT32) {
        VL_PRINTF("%%Warning: wrong type for signal: \"%s\"\n", namep);
    } else {
        uint32_t* datap = (uint32_t*)(varp->datap());
        VL_PRINTF("-     mon_register_b('%s', \"%s\", %p, %d);\n", modp, namep, datap, isOut);
        mons[1].sigsp[isOut] = (uint32_t*)(varp->datap());
    }
}

extern "C" void mon_register_done();
void mon_register_done() {
#ifdef TEST_VERBOSE
    const char* modp = svGetNameFromScope(svGetScope());
    VL_PRINTF("-     mon_register_done('%s');\n", modp);
#endif
    // Print list of all signals - if we didn't register2 anything we'd pick them off here
    const VerilatedScope* scopep = Verilated::dpiScope();
    if (VerilatedVarNameMap* varsp = scopep->varsp()) {
        for (VerilatedVarNameMap::const_iterator it = varsp->begin(); it != varsp->end(); ++it) {
            VL_PRINTF("-       mon2: %s\n", it->first);
        }
    }
}

extern "C" void mon_eval();
void mon_eval() {
    // Callback from always@ negedge
    mon_do(&mons[0]);
    mon_do(&mons[1]);
}

//======================================================================

int main(int argc, char** argv) {
    const std::unique_ptr<VerilatedContext> contextp{new VerilatedContext};

    uint64_t sim_time = 1100;
    contextp->debug(0);
    contextp->commandArgs(argc, argv);

    const std::unique_ptr<VM_PREFIX> topp{new VM_PREFIX{contextp.get(),
                                                        // Note null name - we're flattening it out
                                                        ""}};

    // clang-format off
#ifdef VERILATOR
# ifdef TEST_VERBOSE
    contextp->scopesDump();
# endif
#endif
    // clang-format on

    topp->eval();
    topp->clk = 0;
    contextp->timeInc(10);

    while (contextp->time() < sim_time && !contextp->gotFinish()) {
        contextp->timeInc(1);
        topp->eval();
        topp->clk = !topp->clk;
        // mon_do();
    }
    if (!contextp->gotFinish()) {
        vl_fatal(__FILE__, __LINE__, "main", "%Error: Timeout; never got a $finish");
    }
    topp->final();

    return 0;
}