2 * Copyright (c) 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: sys_time.c,v 1.12 2007/03/14 04:05:51 steve Exp $"
23 # include "vpi_config.h"
25 # include "vpi_user.h"
30 static vpiHandle
module_of_function(vpiHandle obj
)
32 while (vpi_get(vpiType
, obj
) != vpiModule
) {
33 obj
= vpi_handle(vpiScope
, obj
);
40 static PLI_INT32
sys_time_sizetf(PLI_BYTE8
*x
)
45 static PLI_INT32
sys_stime_sizetf(PLI_BYTE8
*x
)
50 static PLI_INT32
sys_time_calltf(PLI_BYTE8
*name
)
54 vpiHandle call_handle
;
60 call_handle
= vpi_handle(vpiSysTfCall
, 0);
63 mod
= module_of_function(call_handle
);
65 now
.type
= vpiSimTime
;
66 vpi_get_time(0, &now
);
68 /* All the variants but $simtime return the time in units of
69 the local scope. The $simtime function returns the
71 if (strcmp(name
, "$simtime") == 0)
72 units
= vpi_get(vpiTimePrecision
, 0);
74 units
= vpi_get(vpiTimeUnit
, mod
);
76 prec
= vpi_get(vpiTimePrecision
, 0);
78 while (units
> prec
) {
83 assert(8*sizeof(long long) >= 64);
84 { long long tmp_now
= ((long long)now
.high
) << 32;
85 tmp_now
+= (long long)now
.low
;
86 frac
= tmp_now
% (long long)scale
;
87 tmp_now
/= (long long)scale
;
89 /* Round to the nearest integer, which may be up. */
90 if ((scale
> 1) && (frac
>= scale
/2))
93 now
.low
= tmp_now
& 0xffffffff;
94 now
.high
= tmp_now
>> 32LL;
97 val
.format
= vpiTimeVal
;
98 val
.value
.time
= &now
;
100 vpi_put_value(call_handle
, &val
, 0, vpiNoDelay
);
105 static PLI_INT32
sys_realtime_calltf(PLI_BYTE8
*name
)
109 vpiHandle call_handle
;
113 call_handle
= vpi_handle(vpiSysTfCall
, 0);
116 mod
= module_of_function(call_handle
);
118 now
.type
= vpiSimTime
;
119 vpi_get_time(0, &now
);
121 units
= vpi_get(vpiTimeUnit
, mod
);
122 prec
= vpi_get(vpiTimePrecision
, 0);
124 val
.format
= vpiRealVal
;
125 val
.value
.real
= pow(10.0, prec
-units
) * now
.low
;
126 assert(now
.high
== 0);
128 vpi_put_value(call_handle
, &val
, 0, vpiNoDelay
);
133 void sys_time_register()
135 s_vpi_systf_data tf_data
;
137 tf_data
.type
= vpiSysFunc
;
138 tf_data
.tfname
= "$time";
139 tf_data
.calltf
= sys_time_calltf
;
140 tf_data
.compiletf
= 0;
141 tf_data
.sizetf
= sys_time_sizetf
;
142 tf_data
.user_data
= "$time";
143 vpi_register_systf(&tf_data
);
145 tf_data
.type
= vpiSysFunc
;
146 tf_data
.tfname
= "$realtime";
147 tf_data
.calltf
= sys_realtime_calltf
;
148 tf_data
.compiletf
= 0;
150 tf_data
.user_data
= "$realtime";
151 vpi_register_systf(&tf_data
);
153 tf_data
.type
= vpiSysFunc
;
154 tf_data
.tfname
= "$stime";
155 tf_data
.calltf
= sys_time_calltf
;
156 tf_data
.compiletf
= 0;
157 tf_data
.sizetf
= sys_stime_sizetf
;
158 tf_data
.user_data
= "$stime";
159 vpi_register_systf(&tf_data
);
161 tf_data
.type
= vpiSysFunc
;
162 tf_data
.tfname
= "$simtime";
163 tf_data
.calltf
= sys_time_calltf
;
164 tf_data
.compiletf
= 0;
165 tf_data
.sizetf
= sys_time_sizetf
;
166 tf_data
.user_data
= "$simtime";
167 vpi_register_systf(&tf_data
);
171 * $Log: sys_time.c,v $
172 * Revision 1.12 2007/03/14 04:05:51 steve
173 * VPI tasks take PLI_BYTE* by the standard.
175 * Revision 1.11 2006/10/30 22:45:37 steve
176 * Updates for Cygwin portability (pr1585922)
178 * Revision 1.10 2004/01/21 01:22:53 steve
179 * Give the vip directory its own configure and vpi_config.h
181 * Revision 1.9 2003/06/18 00:54:28 steve
182 * Account for all 64 bits in results of $time.
184 * Revision 1.8 2003/02/07 02:44:25 steve
185 * Properly round inter time values from $time.
187 * Revision 1.7 2003/01/28 04:41:55 steve
188 * Use more precise pow function to scale time by units.
190 * Revision 1.6 2003/01/27 00:14:37 steve
191 * Support in various contexts the $realtime
194 * Revision 1.5 2002/12/21 00:55:58 steve
195 * The $time system task returns the integer time
196 * scaled to the local units. Change the internal
197 * implementation of vpiSystemTime the $time functions
198 * to properly account for this. Also add $simtime
199 * to get the simulation time.
201 * Revision 1.4 2002/08/12 01:35:05 steve
202 * conditional ident string using autoconfig.
204 * Revision 1.3 2002/01/11 05:20:59 steve
205 * Add the stime system function.
207 * Revision 1.2 2001/07/25 03:10:50 steve
208 * Create a config.h.in file to hold all the config
209 * junk, and support gcc 3.0. (Stephan Boettcher)
211 * Revision 1.1 2000/11/01 03:19:36 steve
212 * Add the general $time system function.