Support for wide modulus operations.
[iverilog.git] / libveriuser / a_vcl.c
blob5609bfbbf5c83bbdaaaef5a6b5241dd06a762f0b
1 /*
2 * Copyright (c) 2003 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)
8 * any later version.
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
19 #ifdef HAVE_CVS_IDENT
20 #ident "$Id: a_vcl.c,v 1.7 2004/10/04 01:10:56 steve Exp $"
21 #endif
23 #include <vpi_user.h>
24 #include <acc_user.h>
25 #include <stdlib.h>
26 #ifdef HAVE_MALLOC_H
27 #include <malloc.h>
28 #endif
29 #include "priv.h"
30 #include <assert.h>
33 * This is the structure of a record that I use locally to hold the
34 * information about a VCL. This record includes a pointer to the vpi
35 * callback that is actually watching the value, and that callback has
36 * a pointer to this record in its user_data so that I can get to it
37 * when the value changes.
39 * Keep all these records in a vcl_list so that I can get access to
40 * them for the vcl_delete.
42 struct vcl_record {
43 /* Object who's value I'm watching. */
44 vpiHandle obj;
45 /* User's callback routine. */
46 PLI_INT32(*consumer)(p_vc_record);
47 void*user_data;
49 PLI_INT32 vcl_flag;
51 vpiHandle callback;
52 struct vcl_record*next;
55 static struct vcl_record*vcl_list = 0;
57 static int vpi_strength_to_vcl(int vs)
59 switch (vs) {
60 case vpiSupplyDrive:
61 return vclSupply;
62 case vpiStrongDrive:
63 return vclStrong;
64 case vpiPullDrive:
65 return vclPull;
66 case vpiLargeCharge:
67 return vclLarge;
68 case vpiWeakDrive:
69 return vclWeak;
70 case vpiMediumCharge:
71 return vclMedium;
72 case vpiSmallCharge:
73 return vclSmall;
74 case vpiHiZ:
75 return vclHighZ;
76 default:
77 return -1;
82 * This is a VPI callback that notices the value change. This function
83 * further dispatches the information about the callback to the
84 * consumer function.
86 static PLI_INT32 vcl_value_callback(struct t_cb_data*cb)
88 s_vpi_time sim_time;
89 s_vpi_value obj_value;
90 struct t_vc_record vcr;
91 struct vcl_record*cur = (struct vcl_record*)cb->user_data;
93 sim_time.type = vpiSimTime;
94 vpi_get_time(cur->obj, &sim_time);
96 switch (cur->vcl_flag) {
97 case VCL_VERILOG_LOGIC:
98 vpi_printf("XXXX vcl_value_callback(%s=%d);\n",
99 vpi_get_str(vpiName, cur->obj), -1);
101 vcr.vc_reason = logic_value_change;
102 break;
104 case VCL_VERILOG_STRENGTH:
105 vcr.vc_reason = strength_value_change;
106 obj_value.format = vpiStrengthVal;
107 vpi_get_value(cur->obj, &obj_value);
108 assert(obj_value.format == vpiStrengthVal);
109 switch (obj_value.value.strength[0].logic) {
110 case vpi0:
111 vcr.out_value.strengths_s.logic_value = acc0;
112 vcr.out_value.strengths_s.strength1 =
113 vpi_strength_to_vcl(obj_value.value.strength[0].s0);
114 vcr.out_value.strengths_s.strength2 =
115 vpi_strength_to_vcl(obj_value.value.strength[0].s0);
116 break;
117 case vpi1:
118 vcr.out_value.strengths_s.logic_value = acc1;
119 vcr.out_value.strengths_s.strength1 =
120 vpi_strength_to_vcl(obj_value.value.strength[0].s1);
121 vcr.out_value.strengths_s.strength2 =
122 vpi_strength_to_vcl(obj_value.value.strength[0].s1);
123 break;
124 case vpiX:
125 vcr.out_value.strengths_s.logic_value = accX;
126 vcr.out_value.strengths_s.strength1 =
127 vpi_strength_to_vcl(obj_value.value.strength[0].s1);
128 vcr.out_value.strengths_s.strength2 =
129 vpi_strength_to_vcl(obj_value.value.strength[0].s0);
130 break;
131 case vpiZ:
132 vcr.out_value.strengths_s.logic_value = accZ;
133 vcr.out_value.strengths_s.strength1 = vclHighZ;
134 vcr.out_value.strengths_s.strength2 = vclHighZ;
135 break;
136 default:
137 assert(0);
140 if (pli_trace) {
141 fprintf(pli_trace,
142 "Call vcl_value_callback(%s=%d <s1=%d,s2=%d>)\n",
143 vpi_get_str(vpiFullName, cur->obj),
144 vcr.out_value.strengths_s.logic_value,
145 vcr.out_value.strengths_s.strength1,
146 vcr.out_value.strengths_s.strength2);
148 break;
150 default:
151 assert(0);
154 vcr.vc_hightime = sim_time.high;
155 vcr.vc_lowtime = sim_time.low;
156 vcr.user_data = cur->user_data;
158 (cur->consumer) (&vcr);
159 return 0;
162 void acc_vcl_add(handle obj, PLI_INT32(*consumer)(p_vc_record),
163 void*data, PLI_INT32 vcl_flag)
165 struct vcl_record*cur;
166 struct t_cb_data cb;
168 switch (vpi_get(vpiType, obj)) {
169 case vpiNet:
170 cur = malloc(sizeof (struct vcl_record));
171 cur->obj = obj;
172 cur->consumer = consumer;
173 cur->user_data = data;
174 cur->vcl_flag = vcl_flag;
175 cur->next = vcl_list;
176 vcl_list = cur;
178 cb.reason = cbValueChange;
179 cb.cb_rtn = vcl_value_callback;
180 cb.obj = obj;
181 cb.time = 0;
182 cb.value = 0;
183 cb.user_data = (void*)cur;
184 cur->callback = vpi_register_cb(&cb);
186 if (pli_trace) {
187 fprintf(pli_trace, "acc_vcl_add(<%s>, ..., %p, %d)\n",
188 vpi_get_str(vpiFullName, obj), data, vcl_flag);
190 break;
192 default:
193 vpi_printf("XXXX acc_vcl_add(<type=%d>, ..., %d);\n",
194 vpi_get(vpiType, obj), vcl_flag);
195 break;
200 void acc_vcl_delete(handle obj, PLI_INT32(*consumer)(p_vc_record),
201 void*data, PLI_INT32 vcl_flag)
203 vpi_printf("XXXX acc_vcl_delete(...)\n");
208 * $Log: a_vcl.c,v $
209 * Revision 1.7 2004/10/04 01:10:56 steve
210 * Clean up spurious trailing white space.
212 * Revision 1.6 2003/06/17 16:55:07 steve
213 * 1) setlinebuf() for vpi_trace
214 * 2) Addes error checks for trace file opens
215 * 3) removes now extraneous flushes
216 * 4) fixes acc_next() bug
218 * Revision 1.5 2003/05/18 00:16:35 steve
219 * Add PLI_TRACE tracing of PLI1 modules.
221 * Add tf_isetdelay and friends, and add
222 * callback return values for acc_vcl support.
224 * Revision 1.4 2003/04/30 01:09:29 steve
225 * Conditionally include malloc.h
227 * Revision 1.3 2003/04/24 02:02:37 steve
228 * Clean up some simple warnings.
230 * Revision 1.2 2003/04/20 02:48:39 steve
231 * Support value change callbacks.
233 * Revision 1.1 2003/04/12 18:57:14 steve
234 * More acc_ function stubs.