2 * Copyright (c) 2001-2008 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 # include "vpi_priv.h"
30 static int string_get(int code
, vpiHandle ref
)
32 struct __vpiStringConst
*rfp
;
36 rfp
= (struct __vpiStringConst
*)ref
;
38 assert((ref
->vpi_type
->type_code
== vpiConstant
)
39 || ((ref
->vpi_type
->type_code
== vpiParameter
)));
41 //fprintf(stderr, "String:|%s|, Length: %d\n", rfp->value, strlen(rfp->value));
42 return strlen(rfp
->value
)*8;
48 return vpiStringConst
;
51 fprintf(stderr
, "vvp error: get %d not supported "
52 "by vpiStringConst\n", code
);
58 static void string_value(vpiHandle ref
, p_vpi_value vp
)
62 struct __vpiStringConst
*rfp
= (struct __vpiStringConst
*)ref
;
63 int size
= strlen(rfp
->value
);
67 assert((ref
->vpi_type
->type_code
== vpiConstant
)
68 || ((ref
->vpi_type
->type_code
== vpiParameter
)));
72 /* String parameters by default have vpiStringVal values. */
73 vp
->format
= vpiStringVal
;
76 rbuf
= need_result_buf(size
+ 1, RBUF_VAL
);
77 strcpy(rbuf
, (char*)rfp
->value
);
83 // We only support standard integers. Ignore other bytes...
85 fprintf(stderr
, "Warning (vpi_const.cc): %%d on constant strings only looks "
86 "at first 4 bytes!\n");
88 rbuf
= need_result_buf(size
+ 1, RBUF_VAL
);
90 for(int i
=0; i
<size
;i
++){
92 uint_value
+= (unsigned char)(rfp
->value
[i
]);
94 sprintf(rbuf
, "%u", uint_value
);
99 rbuf
= need_result_buf(8 * size
+ 1, RBUF_VAL
);
101 for(int i
=0; i
<size
;i
++){
102 for(int bit
=7;bit
>=0; bit
--){
103 *cp
++ = "01"[ (rfp
->value
[i
]>>bit
)&1 ];
107 vp
->value
.str
= rbuf
;
111 rbuf
= need_result_buf(2 * size
+ 1, RBUF_VAL
);
113 for(int i
=0; i
<size
;i
++){
114 for(int nibble
=1;nibble
>=0; nibble
--){
115 *cp
++ = "0123456789abcdef"[ (rfp
->value
[i
]>>(nibble
*4))&15 ];
119 vp
->value
.str
= rbuf
;
123 fprintf(stderr
, "ERROR (vpi_const.cc): %%o display of constant strings not yet implemented\n");
128 vp
->value
.integer
= 0;
129 for(int i
=0; i
<size
;i
++){
130 for(int bit
=7;bit
>=0; bit
--){
131 vp
->value
.integer
<<= 1;
132 vp
->value
.integer
+= (rfp
->value
[i
]>>bit
)&1;
138 vp
->value
.vector
= (p_vpi_vecval
) calloc((size
+3)/4,
139 sizeof(s_vpi_vecval
));
141 vecp
= vp
->value
.vector
;
142 for(int i
=0; i
<size
;i
++){
143 vecp
->aval
|= rfp
->value
[i
] << uint_value
*8;
145 if (uint_value
> 3) {
154 fprintf(stderr
, "ERROR (vpi_const.cc): vp->format: %d\n", vp
->format
);
157 vp
->format
= vpiSuppressVal
;
162 static const struct __vpirt vpip_string_rt
= {
172 static int free_temp_string(vpiHandle obj
)
174 struct __vpiStringConst
*rfp
= (struct __vpiStringConst
*)obj
;
175 assert(obj
->vpi_type
->type_code
== vpiConstant
);
182 static const struct __vpirt vpip_string_temp_rt
= {
197 * Strings are described at the level of the vvp source as a string
198 * with literal characters or octal escapes. No other escapes are
199 * included, they are processed already by the compiler that generated
202 static void vpip_process_string(struct __vpiStringConst
*obj
)
204 char*chr
= obj
->value
;
205 char*dp
= obj
->value
;
208 char next_char
= *chr
;
210 /* Process octal escapes that I might find. */
212 for (int idx
= 1 ; idx
<= 3 ; idx
+= 1) {
213 assert(chr
[idx
] != 0);
214 assert(chr
[idx
] < '8');
215 assert(chr
[idx
] >= '0');
216 next_char
= next_char
*8 + chr
[idx
] - '0';
224 obj
->value_len
= dp
- obj
->value
;
227 vpiHandle
vpip_make_string_const(char*text
, bool persistent_flag
)
229 struct __vpiStringConst
*obj
;
231 obj
= (struct __vpiStringConst
*)
232 malloc(sizeof (struct __vpiStringConst
));
233 obj
->base
.vpi_type
= persistent_flag
235 : &vpip_string_temp_rt
;
238 vpip_process_string(obj
);
244 struct __vpiStringParam
: public __vpiStringConst
{
246 struct __vpiScope
* scope
;
251 static int string_param_get(int code
, vpiHandle ref
)
253 struct __vpiStringParam
*rfp
= (struct __vpiStringParam
*)ref
;
255 assert(ref
->vpi_type
->type_code
== vpiParameter
);
257 if (code
== vpiLineNo
) {
261 return string_get(code
, ref
);
264 static char* string_param_get_str(int code
, vpiHandle obj
)
266 struct __vpiStringParam
*rfp
= (struct __vpiStringParam
*)obj
;
268 assert(obj
->vpi_type
->type_code
== vpiParameter
);
270 if (code
== vpiFile
) {
271 return simple_set_rbuf_str(file_names
[rfp
->file_idx
]);
274 return generic_get_str(code
, &rfp
->scope
->base
, rfp
->basename
, NULL
);
277 static vpiHandle
string_param_handle(int code
, vpiHandle obj
)
279 struct __vpiStringParam
*rfp
= (struct __vpiStringParam
*)obj
;
281 assert(obj
->vpi_type
->type_code
== vpiParameter
);
285 return &rfp
->scope
->base
;
292 static const struct __vpirt vpip_string_param_rt
= {
295 string_param_get_str
,
307 vpiHandle
vpip_make_string_param(char*name
, char*text
,
308 long file_idx
, long lineno
)
310 struct __vpiStringParam
*obj
;
312 obj
= (struct __vpiStringParam
*)
313 malloc(sizeof (struct __vpiStringParam
));
314 obj
->base
.vpi_type
= &vpip_string_param_rt
;
317 obj
->basename
= name
;
318 obj
->scope
= vpip_peek_current_scope();
319 obj
->file_idx
= (unsigned) file_idx
;
320 obj
->lineno
= (unsigned) lineno
;
322 vpip_process_string(obj
);
327 static int binary_get(int code
, vpiHandle ref
)
329 struct __vpiBinaryConst
*rfp
= (struct __vpiBinaryConst
*)ref
;
330 assert(ref
->vpi_type
->type_code
== vpiConstant
331 || ref
->vpi_type
->type_code
== vpiParameter
);
335 return vpiBinaryConst
;
338 return 0; // Not implemented for now!
341 return rfp
->signed_flag
? 1 : 0;
344 return rfp
->bits
.size();
347 fprintf(stderr
, "vvp error: get %d not supported "
348 "by vpiBinaryConst\n", code
);
355 static void binary_value(vpiHandle ref
, p_vpi_value vp
)
357 assert(ref
->vpi_type
->type_code
== vpiConstant
358 || ref
->vpi_type
->type_code
== vpiParameter
);
360 struct __vpiBinaryConst
*rfp
= (struct __vpiBinaryConst
*)ref
;
363 switch (vp
->format
) {
375 vpip_vec4_get_value(rfp
->bits
, rfp
->bits
.size(),
376 rfp
->signed_flag
, vp
);
380 fprintf(stderr
, "vvp error: format %d not supported "
381 "by vpiBinaryConst\n", vp
->format
);
382 vp
->format
= vpiSuppressVal
;
387 static const struct __vpirt vpip_binary_rt
= {
398 * Make a VPI constant from a vector string. The string is normally a
399 * ASCII string, with each letter a 4-value bit. The first character
400 * may be an 's' if the vector is signed.
402 vpiHandle
vpip_make_binary_const(unsigned wid
, const char*bits
)
404 struct __vpiBinaryConst
*obj
;
406 obj
= new __vpiBinaryConst
;
407 obj
->base
.vpi_type
= &vpip_binary_rt
;
409 obj
->signed_flag
= 0;
411 obj
->bits
= vvp_vector4_t(wid
);
413 const char*bp
= bits
;
416 obj
->signed_flag
= 1;
419 for (unsigned idx
= 0 ; idx
< wid
; idx
+= 1) {
420 vvp_bit4_t val
= BIT4_0
;
421 switch (bp
[wid
-idx
-1]) {
436 obj
->bits
.set_bit(idx
, val
);
442 struct __vpiBinaryParam
: public __vpiBinaryConst
{
444 struct __vpiScope
*scope
;
449 static int binary_param_get(int code
, vpiHandle ref
)
451 struct __vpiBinaryParam
*rfp
= (struct __vpiBinaryParam
*)ref
;
453 assert(ref
->vpi_type
->type_code
== vpiParameter
);
455 if (code
== vpiLineNo
) {
459 return binary_get(code
, ref
);
462 static char* binary_param_get_str(int code
, vpiHandle obj
)
464 struct __vpiBinaryParam
*rfp
= (struct __vpiBinaryParam
*)obj
;
466 assert(obj
->vpi_type
->type_code
== vpiParameter
);
468 if (code
== vpiFile
) {
469 return simple_set_rbuf_str(file_names
[rfp
->file_idx
]);
472 return generic_get_str(code
, &rfp
->scope
->base
, rfp
->basename
, NULL
);
475 static vpiHandle
binary_param_handle(int code
, vpiHandle obj
)
477 struct __vpiBinaryParam
*rfp
= (struct __vpiBinaryParam
*)obj
;
479 assert(obj
->vpi_type
->type_code
== vpiParameter
);
483 return &rfp
->scope
->base
;
490 static const struct __vpirt vpip_binary_param_rt
= {
493 binary_param_get_str
,
504 vpiHandle
vpip_make_binary_param(char*name
, const vvp_vector4_t
&bits
,
506 long file_idx
, long lineno
)
508 struct __vpiBinaryParam
*obj
= new __vpiBinaryParam
;
510 obj
->base
.vpi_type
= &vpip_binary_param_rt
;
512 obj
->signed_flag
= signed_flag
? 1 : 0;
514 obj
->basename
= name
;
515 obj
->scope
= vpip_peek_current_scope();
516 obj
->file_idx
= (unsigned) file_idx
;
517 obj
->lineno
= (unsigned) lineno
;
523 static int dec_get(int code
, vpiHandle ref
)
537 fprintf(stderr
, "vvp error: get %d not supported "
538 "by vpiDecConst\n", code
);
545 static void dec_value(vpiHandle ref
, p_vpi_value vp
)
547 struct __vpiDecConst
*rfp
= (struct __vpiDecConst
*)ref
;
548 assert(ref
->vpi_type
->type_code
== vpiConstant
);
549 char*rbuf
= need_result_buf(64 + 1, RBUF_VAL
);
552 switch (vp
->format
) {
556 vp
->value
.integer
= rfp
->value
;
561 sprintf(rbuf
, "%d", rfp
->value
);
563 vp
->value
.str
= rbuf
;
567 for(int bit
=31; bit
<=0;bit
--){
568 *cp
++ = "01"[ (rfp
->value
>>bit
)&1 ];
572 vp
->value
.str
= rbuf
;
576 sprintf(rbuf
, "%08x", rfp
->value
);
578 vp
->value
.str
= rbuf
;
582 sprintf(rbuf
, "%011x", rfp
->value
);
584 vp
->value
.str
= rbuf
;
588 fprintf(stderr
, "vvp error (vpi_const.cc): format %d not supported "
589 "by vpiDecConst\n", vp
->format
);
590 vp
->format
= vpiSuppressVal
;
595 static const struct __vpirt vpip_dec_rt
= {
605 vpiHandle
vpip_make_dec_const(struct __vpiDecConst
*obj
, int value
)
607 obj
->base
.vpi_type
= &vpip_dec_rt
;
613 vpiHandle
vpip_make_dec_const(int value
)
615 struct __vpiDecConst
*obj
;
617 obj
= (struct __vpiDecConst
*)
618 malloc(sizeof (struct __vpiDecConst
));
619 return vpip_make_dec_const(obj
, value
);
623 static int real_get(int code
, vpiHandle ref
)
628 return 0; // Not implemented for now!
640 fprintf(stderr
, "vvp error: get %d not supported "
641 "by vpiDecConst\n", code
);
647 static void real_value(vpiHandle ref
, p_vpi_value vp
)
649 struct __vpiRealConst
*rfp
= (struct __vpiRealConst
*)ref
;
650 assert((ref
->vpi_type
->type_code
== vpiConstant
) ||
651 (ref
->vpi_type
->type_code
== vpiParameter
));
653 switch (vp
->format
) {
655 vp
->format
= vpiRealVal
;
657 vp
->value
.real
= rfp
->value
;
660 fprintf(stderr
, "vvp error: unsupported format %d.\n", vp
->format
);
665 static const struct __vpirt vpip_real_rt
= {
675 vpiHandle
vpip_make_real_const(struct __vpiRealConst
*obj
, double value
)
677 obj
->base
.vpi_type
= &vpip_real_rt
;
682 vpiHandle
vpip_make_real_const(double value
)
684 struct __vpiRealConst
*obj
;
685 obj
=(struct __vpiRealConst
*) malloc(sizeof (struct __vpiRealConst
));
686 return vpip_make_real_const(obj
, value
);
689 struct __vpiRealParam
: public __vpiRealConst
{
691 struct __vpiScope
* scope
;
696 static int real_param_get(int code
, vpiHandle ref
)
698 struct __vpiRealParam
*rfp
= (struct __vpiRealParam
*)ref
;
700 assert(ref
->vpi_type
->type_code
== vpiParameter
);
702 if (code
== vpiLineNo
) {
706 return real_get(code
, ref
);
709 static char* real_param_get_str(int code
, vpiHandle obj
)
711 struct __vpiRealParam
*rfp
= (struct __vpiRealParam
*)obj
;
713 assert(obj
->vpi_type
->type_code
== vpiParameter
);
715 if (code
== vpiFile
) {
716 return simple_set_rbuf_str(file_names
[rfp
->file_idx
]);
719 return generic_get_str(code
, &rfp
->scope
->base
, rfp
->basename
, NULL
);
722 static vpiHandle
real_param_handle(int code
, vpiHandle obj
)
724 struct __vpiRealParam
*rfp
= (struct __vpiRealParam
*)obj
;
726 assert(obj
->vpi_type
->type_code
== vpiParameter
);
730 return &rfp
->scope
->base
;
737 static const struct __vpirt vpip_real_param_rt
= {
751 vpiHandle
vpip_make_real_param(char*name
, double value
,
752 long file_idx
, long lineno
)
754 struct __vpiRealParam
*obj
;
756 obj
= (struct __vpiRealParam
*)
757 malloc(sizeof (struct __vpiRealParam
));
758 obj
->base
.vpi_type
= &vpip_real_param_rt
;
760 obj
->basename
= name
;
761 obj
->scope
= vpip_peek_current_scope();
762 obj
->file_idx
= (unsigned) file_idx
;
763 obj
->lineno
= (unsigned) lineno
;