1 /* Copyright (c) 1995-2003 Pragmatic C Software Corp. */
2 /*
3 * example to find cause statements only in top module initial/always
4 *
5 * real program would descend to all instances to find all modules
6 * and keep track of seen module types to not repeat search
7 */
8
9 #include <stdio.h>
10
11 #include "vpi_user.h"
12 #include "cv_vpi_user.h"
13 #include <string.h>
14
15 static int num_causes;
16
17 /* local prototypes */
18 static void blk_findcaus(vpiHandle);
19 static void blk_findcaus(vpiHandle);
20
21 /* global prototypes */
22 extern int findcaus(struct t_cb_data *);
23 extern int my_error_handler(struct t_cb_data *);
24 extern void register_scan_cb(void);
25
findcaus(struct t_cb_data * cbp)26 int findcaus(struct t_cb_data *cbp)
27 {
28 int iatyp, sttyp, isiz;
29 vpiHandle href, href2, href3;
30 vpiHandle modiref, ia_iref;
31
32 /* build the iterator for each module */
33 modiref = vpi_iterate(vpiModule, NULL);
34 isiz = vpi_get(vpiSize, modiref);
35 vpi_printf("module iterator has size %d.\n", isiz);
36
37 for (num_causes = 0;;)
38 {
39 if ((href = vpi_scan(modiref)) == NULL) break;
40 vpi_printf("... processing instance %s\n", vpi_get_str(vpiFullName, href));
41
42 /* build the initial/always process iterator */
43 ia_iref = vpi_iterate(vpiProcess, href);
44 isiz = vpi_get(vpiSize, ia_iref);
45 vpi_printf("init/always iterator has size %d.\n", isiz);
46 for (;;)
47 {
48 if ((href2 = vpi_scan(ia_iref)) == NULL) break;
49 iatyp = vpi_get(vpiType, href2);
50 if (iatyp == vpiInitial) vpi_printf("... processing initial\n");
51 else if (iatyp == vpiAlways) vpi_printf("...processing always\n");
52 else vpi_printf("... expected initial/always not found");
53
54 href3 = vpi_handle(vpiStmt, href2);
55 sttyp = vpi_get(vpiType, href3);
56 vpi_printf("... processing %d type.\n", sttyp);
57 switch (sttyp) {
58 case vpiEventStmt: num_causes++; break;
59 case vpiBegin: case vpiFork: case vpiNamedBegin: case vpiNamedFork:
60 blk_findcaus(href3);
61 break;
62 default: ; /* anything else just ignored */
63 }
64 }
65 }
66 vpi_printf("There were %d total cause statements in top modules.\n",
67 num_causes);
68 return(0);
69 }
70
71 /*
72 * find causes in blocks (maybe named and can be nested)
73 */
blk_findcaus(vpiHandle blkhref)74 static void blk_findcaus(vpiHandle blkhref)
75 {
76 int sttyp, isiz;
77 vpiHandle ihref, href;
78
79 /* build the list of statements in block iterator */
80 ihref = vpi_iterate(vpiStmt, blkhref);
81 isiz = vpi_get(vpiSize, ihref);
82 vpi_printf("block stmt iterator has size %d.\n", isiz);
83 for (;;)
84 {
85 if ((href = vpi_scan(ihref)) == NULL) break;
86 sttyp = vpi_get(vpiType, href);
87 vpi_printf("... processing %d type.\n", sttyp);
88 switch (sttyp) {
89 case vpiEventStmt: num_causes++; break;
90 case vpiBegin: case vpiFork: case vpiNamedBegin: case vpiNamedFork:
91 blk_findcaus(href);
92 break;
93 default: ; /* anything else just ignored */
94 }
95 }
96 }
97
98 /*
99 * routine to build an error indication string
100 */
my_error_handler(struct t_cb_data * cbp)101 int my_error_handler(struct t_cb_data *cbp)
102 {
103 struct t_vpi_error_info einfotab;
104 struct t_vpi_error_info *einfop;
105 char s1[128];
106
107 einfop = &einfotab;
108 vpi_chk_error(einfop);
109
110 if (einfop->state == vpiCompile) strcpy(s1, "vpiCompile");
111 else if (einfop->state == vpiPLI) strcpy(s1, "vpiPLI");
112 else if (einfop->state == vpiRun) strcpy(s1, "vpiRun");
113 else strcpy(s1, "**unknown**");
114
115 vpi_printf("%s: %s error (level %d) at **%s(%d):\n %s\n",
116 einfop->code, s1, einfop->level, einfop->file, einfop->line,
117 einfop->message);
118
119 /* if serious error give up */
120 if (einfop->level == vpiError || einfop->level == vpiSystem
121 || einfop->level == vpiInternal)
122 {
123 vpi_printf("**FATAL: encountered error - giving up\n");
124 vpi_sim_control(vpiFinish, 0);
125 }
126 return(0);
127 }
128
129 /* Template functin table for added user systf tasks and functions.
130 See file vpi_user.h for structure definition
131 Note only vpi_register_systf and vpi_ or tf_ utility routines that
132 do not access the simulation data base may be called from these routines
133 */
134
135 /* all routines are called to register cbs */
136 /* called just after all PLI 1.0 tf_ veriusertfs table routines are set up */
137 /* before source is read */
138 void (*vlog_startup_routines[]) () =
139 {
140 register_scan_cb,
141 0
142 };
143
144 /* routine to do the systf registering - probably should go in other file */
145 /* usually only vpi_ PLI 2.0 systf or cb registering is done here */
146
147 /*
148 * register the start of sim scan call back and set up error handling
149 *
150 * notice making version of Cver that prints some stuff to start but
151 * is a normal Cver
152 *
153 * since handle not saved (passed back?), no way to find out cb info
154 */
register_scan_cb(void)155 void register_scan_cb(void)
156 {
157 vpiHandle href, href2;
158 struct t_cb_data *ecbp, *cbp;
159 struct t_cb_data cbrec, cbrec2;
160
161 /* notice cb records must be in global storage */
162 ecbp = &cbrec;
163 ecbp->reason = cbPLIError;
164 ecbp->cb_rtn = my_error_handler;
165 ecbp->obj = NULL;
166 ecbp->time = NULL;
167 ecbp->value = NULL;
168 ecbp->user_data = NULL;
169
170 /* probably should check for error here */
171 if ((href = vpi_register_cb(ecbp)) == NULL)
172 vpi_printf(
173 "**ERR: $hello PLI 2.0 task cannot register end of compile check routine");
174
175 cbp = &cbrec2;
176 cbp->reason = cbStartOfSimulation;
177 cbp->cb_rtn = findcaus;
178 cbp->obj = NULL;
179 cbp->time = NULL;
180 cbp->value = NULL;
181 cbp->user_data = NULL;
182
183 /* probably should check for error here */
184 if ((href2 = vpi_register_cb(cbp)) == NULL)
185 vpi_printf(
186 "**ERR: $hello PLI 2.0 task cannot register end of compile check routine");
187 /* if not registered will be no call backs */
188 }
189
190 /* dummy +loadvpi= boostrap routine - mimics old style exec all routines */
191 /* in standard PLI vlog_startup_routines table */
vpi_compat_bootstrap(void)192 void vpi_compat_bootstrap(void)
193 {
194 int i;
195
196 for (i = 0;; i++)
197 {
198 if (vlog_startup_routines[i] == NULL) break;
199 vlog_startup_routines[i]();
200 }
201 }
202