2 * Copyright (c) 1999-2000 Stephen Williams (steve@icarus.com)
4 * This source code is free software; you can redistribute it
5 * and/or modify it in source code form under the terms of the GNU
6 * General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 #ident "$Id: vpi_priv.c,v 1.5 2002/08/12 01:35:05 steve Exp $"
23 # include "vpi_priv.h"
31 * Keep a list of vpi_systf_data structures. This list is searched
32 * forward whenever a function is invoked by name, and items are
33 * pushed in front of the list whenever they are registered. This
34 * allows entries to override older entries.
37 struct systf_entry
* next
;
38 s_vpi_systf_data systf_data
;
41 static struct systf_entry
*systf_func_list
= 0;
42 static struct systf_entry
*systf_task_list
= 0;
44 /* This is the handle of the task currently being called. */
45 static struct __vpiSysTaskCall
*vpip_cur_task
;
47 void vpip_calltask(struct __vpiScope
*scope
, const char*fname
,
48 unsigned nparms
, vpiHandle
*parms
)
50 struct systf_entry
*idx
;
51 struct __vpiSysTaskCall cur_task
;
52 cur_task
.base
.vpi_type
= vpip_get_systask_rt();
53 cur_task
.scope
= scope
;
54 cur_task
.args
= parms
;
55 cur_task
.nargs
= nparms
;
59 vpip_cur_task
= &cur_task
;
61 /* Look for a systf function to invoke. */
62 for (idx
= systf_task_list
; idx
; idx
= idx
->next
)
63 if (strcmp(fname
, idx
->systf_data
.tfname
) == 0) {
64 cur_task
.info
= &idx
->systf_data
;
65 idx
->systf_data
.calltf(idx
->systf_data
.user_data
);
70 /* Finally, if nothing is found then something is not
71 right. Print out the function name all the parameters
72 passed, so that someone can deal with it. */
73 vpi_printf("Call %s\n", fname
);
77 * System functions are kept in the same sort of table as the system
78 * tasks, and we call them in a similar manner.
80 void vpip_callfunc(const char*fname
, unsigned nres
, vpip_bit_t
*res
,
81 unsigned nparms
, vpiHandle
*parms
)
83 struct systf_entry
*idx
;
84 struct __vpiSysTaskCall cur_task
;
85 cur_task
.base
.vpi_type
= vpip_get_sysfunc_rt();
86 cur_task
.args
= parms
;
87 cur_task
.nargs
= nparms
;
91 vpip_cur_task
= &cur_task
;
93 /* Look for a systf function to invoke. */
94 for (idx
= systf_func_list
; idx
; idx
= idx
->next
)
95 if (strcmp(fname
, idx
->systf_data
.tfname
) == 0) {
96 cur_task
.info
= &idx
->systf_data
;
97 idx
->systf_data
.calltf(idx
->systf_data
.user_data
);
102 /* Finally, if nothing is found then something is not
103 right. Print out the function name all the parameters
104 passed, so that someone can deal with it. */
105 vpi_printf("Call %s with width==%u\n", fname
, nres
);
109 int vpi_free_object(vpiHandle ref
)
115 static int vpip_get_global(int property
)
118 case vpiTimePrecision
:
119 return vpip_get_simulation_obj()->time_precision
;
127 int vpi_get(int property
, vpiHandle ref
)
129 if (property
== vpiType
)
130 return ref
->vpi_type
->type_code
;
133 return vpip_get_global(property
);
135 if (ref
->vpi_type
->vpi_get_
== 0)
138 return (ref
->vpi_type
->vpi_get_
)(property
, ref
);
141 char* vpi_get_str(int property
, vpiHandle ref
)
143 if (ref
->vpi_type
->vpi_get_str_
== 0)
146 return (char*)(ref
->vpi_type
->vpi_get_str_
)(property
, ref
);
149 void vpi_get_time(vpiHandle obj
, s_vpi_time
*t
)
152 vpiHandle tm
= vpip_sim_time();
153 value
.format
= vpiTimeVal
;
154 vpi_get_value(tm
, &value
);
155 memcpy(t
, value
.value
.time
, sizeof (*t
));
158 void vpi_get_value(vpiHandle expr
, s_vpi_value
*vp
)
160 if (expr
->vpi_type
->vpi_get_value_
) {
161 (expr
->vpi_type
->vpi_get_value_
)(expr
, vp
);
165 vp
->format
= vpiSuppressVal
;
168 vpiHandle
vpi_put_value(vpiHandle obj
, s_vpi_value
*vp
,
169 s_vpi_time
*tp
, int flags
)
171 if (obj
->vpi_type
->vpi_put_value_
)
172 return (obj
->vpi_type
->vpi_put_value_
)(obj
, vp
, tp
, flags
);
177 vpiHandle
vpi_handle(int type
, vpiHandle ref
)
179 if (type
== vpiSysTfCall
) {
181 return &vpip_cur_task
->base
;
184 assert(ref
->vpi_type
->handle_
);
185 return (ref
->vpi_type
->handle_
)(type
, ref
);
189 * This function asks the object to return an iterator for
190 * the specified reference. It is up to the iterate_ method to
191 * allocate a properly formed iterator.
193 vpiHandle
vpi_iterate(int type
, vpiHandle ref
)
195 assert(ref
->vpi_type
->iterate_
);
196 return (ref
->vpi_type
->iterate_
)(type
, ref
);
199 vpiHandle
vpi_handle_by_index(vpiHandle ref
, int idx
)
201 assert(ref
->vpi_type
->index_
);
202 return (ref
->vpi_type
->index_
)(ref
, idx
);
205 extern void vpi_vprintf(const char*fmt
, va_list ap
)
210 extern void vpi_printf(const char *fmt
, ...)
220 * This function adds the information that the user supplies to a list
223 void vpi_register_systf(const struct t_vpi_systf_data
*systf
)
225 struct systf_entry
*cur
= calloc(1, sizeof(struct systf_entry
));
226 cur
->systf_data
= *systf
;
227 cur
->systf_data
.tfname
= strdup(systf
->tfname
);
228 switch (systf
->type
) {
230 cur
->next
= systf_func_list
;
231 systf_func_list
= cur
;
234 cur
->next
= systf_task_list
;
235 systf_task_list
= cur
;
243 * $Log: vpi_priv.c,v $
244 * Revision 1.5 2002/08/12 01:35:05 steve
245 * conditional ident string using autoconfig.
247 * Revision 1.4 2001/10/26 02:29:10 steve
248 * const/non-const warnings. (Stephan Boettcher)
250 * Revision 1.3 2001/06/19 14:57:10 steve
251 * Get va_start arguments in right order.
253 * Revision 1.2 2001/06/12 03:53:10 steve
254 * Change the VPI call process so that loaded .vpi modules
255 * use a function table instead of implicit binding.
257 * Revision 1.1 2001/03/14 19:27:44 steve
258 * Rearrange VPI support libraries.
260 * Revision 1.11 2000/10/28 00:51:42 steve
261 * Add scope to threads in vvm, pass that scope
262 * to vpi sysTaskFunc objects, and add vpi calls
263 * to access that information.
265 * $display displays scope in %m (PR#1)
267 * Revision 1.10 2000/10/06 23:11:39 steve
268 * Replace data references with function calls. (Venkat)
270 * Revision 1.9 2000/08/20 17:49:05 steve
271 * Clean up warnings and portability issues.
273 * Revision 1.8 2000/07/26 03:53:12 steve
274 * Make simulation precision available to VPI.
276 * Revision 1.7 2000/05/07 18:20:08 steve
277 * Import MCD support from Stephen Tell, and add
278 * system function parameter support to the IVL core.
280 * Revision 1.6 2000/05/04 03:37:59 steve
281 * Add infrastructure for system functions, move
282 * $time to that structure and add $random.
284 * Revision 1.5 2000/02/23 02:56:56 steve
285 * Macintosh compilers do not support ident.
287 * Revision 1.4 2000/02/13 19:18:28 steve
288 * Accept memory words as parameter to $display.
290 * Revision 1.3 2000/01/20 06:04:55 steve
291 * $dumpall checkpointing in VCD dump.
293 * Revision 1.2 1999/12/15 04:01:14 steve
294 * Add the VPI implementation of $readmemh.
296 * Revision 1.1 1999/10/28 00:47:25 steve
297 * Rewrite vvm VPI support to make objects more
298 * persistent, rewrite the simulation scheduler
299 * in C (to interface with VPI) and add VPI support