Add file and line information for parameters, etc.
[sverilog.git] / vvp / vpi_const.cc
blob75c96be8d19aee20355482e3f5f880e8bf4adb2b
1 /*
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)
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
20 # include "vpi_priv.h"
21 # include "compile.h"
22 # include <stdio.h>
23 #ifdef HAVE_MALLOC_H
24 # include <malloc.h>
25 #endif
26 # include <stdlib.h>
27 # include <string.h>
28 # include <assert.h>
30 static int string_get(int code, vpiHandle ref)
32 struct __vpiStringConst*rfp;
34 switch (code) {
35 case vpiSize:
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;
44 case vpiSigned:
45 return 0;
47 case vpiConstType:
48 return vpiStringConst;
50 default:
51 fprintf(stderr, "vvp error: get %d not supported "
52 "by vpiStringConst\n", code);
53 assert(0);
54 return 0;
58 static void string_value(vpiHandle ref, p_vpi_value vp)
60 unsigned uint_value;
61 p_vpi_vecval vecp;
62 struct __vpiStringConst*rfp = (struct __vpiStringConst*)ref;
63 int size = strlen(rfp->value);
64 char*rbuf = 0;
65 char*cp;
67 assert((ref->vpi_type->type_code == vpiConstant)
68 || ((ref->vpi_type->type_code == vpiParameter)));
70 switch (vp->format) {
71 case vpiObjTypeVal:
72 /* String parameters by default have vpiStringVal values. */
73 vp->format = vpiStringVal;
75 case vpiStringVal:
76 rbuf = need_result_buf(size + 1, RBUF_VAL);
77 strcpy(rbuf, (char*)rfp->value);
78 vp->value.str = rbuf;
79 break;
81 case vpiDecStrVal:
82 if (size > 4){
83 // We only support standard integers. Ignore other bytes...
84 size = 4;
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);
89 uint_value = 0;
90 for(int i=0; i<size;i ++){
91 uint_value <<=8;
92 uint_value += (unsigned char)(rfp->value[i]);
94 sprintf(rbuf, "%u", uint_value);
95 vp->value.str = rbuf;
96 break;
98 case vpiBinStrVal:
99 rbuf = need_result_buf(8 * size + 1, RBUF_VAL);
100 cp = rbuf;
101 for(int i=0; i<size;i ++){
102 for(int bit=7;bit>=0; bit--){
103 *cp++ = "01"[ (rfp->value[i]>>bit)&1 ];
106 *cp = 0;
107 vp->value.str = rbuf;
108 break;
110 case vpiHexStrVal:
111 rbuf = need_result_buf(2 * size + 1, RBUF_VAL);
112 cp = rbuf;
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 ];
118 *cp = 0;
119 vp->value.str = rbuf;
120 break;
122 case vpiOctStrVal:
123 fprintf(stderr, "ERROR (vpi_const.cc): %%o display of constant strings not yet implemented\n");
124 assert(0);
125 break;
127 case vpiIntVal:
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;
135 break;
137 case vpiVectorVal:
138 vp->value.vector = (p_vpi_vecval) calloc((size+3)/4,
139 sizeof(s_vpi_vecval));
140 uint_value = 0;
141 vecp = vp->value.vector;
142 for(int i=0; i<size;i ++){
143 vecp->aval |= rfp->value[i] << uint_value*8;
144 uint_value += 1;
145 if (uint_value > 3) {
146 uint_value = 0;
147 vecp += 1;
150 break;
153 default:
154 fprintf(stderr, "ERROR (vpi_const.cc): vp->format: %d\n", vp->format);
155 assert(0);
157 vp->format = vpiSuppressVal;
158 break;
162 static const struct __vpirt vpip_string_rt = {
163 vpiConstant,
164 string_get,
166 string_value,
172 static int free_temp_string(vpiHandle obj)
174 struct __vpiStringConst*rfp = (struct __vpiStringConst*)obj;
175 assert(obj->vpi_type->type_code == vpiConstant);
177 free(rfp->value);
178 free(rfp);
179 return 1;
182 static const struct __vpirt vpip_string_temp_rt = {
183 vpiConstant,
184 string_get,
186 string_value,
193 free_temp_string
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
200 * the vvp source.
202 static void vpip_process_string(struct __vpiStringConst*obj)
204 char*chr = obj->value;
205 char*dp = obj->value;
207 while (*chr) {
208 char next_char = *chr;
210 /* Process octal escapes that I might find. */
211 if (*chr == '\\') {
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';
218 chr += 3;
220 *dp++ = next_char;
221 chr += 1;
223 *dp = 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
234 ? &vpip_string_rt
235 : &vpip_string_temp_rt;
236 obj->value = text;
237 obj->value_len = 0;
238 vpip_process_string(obj);
240 return &obj->base;
244 struct __vpiStringParam : public __vpiStringConst {
245 const char*basename;
246 struct __vpiScope* scope;
247 unsigned file_idx;
248 unsigned lineno;
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) {
258 return rfp->lineno;
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);
283 switch (code) {
284 case vpiScope:
285 return &rfp->scope->base;
287 default:
288 return 0;
292 static const struct __vpirt vpip_string_param_rt = {
293 vpiParameter,
294 string_param_get,
295 string_param_get_str,
296 string_value,
299 string_param_handle,
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;
315 obj->value = text;
316 obj->value_len = 0;
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);
324 return &obj->base;
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);
333 switch (code) {
334 case vpiConstType:
335 return vpiBinaryConst;
337 case vpiLineNo:
338 return 0; // Not implemented for now!
340 case vpiSigned:
341 return rfp->signed_flag? 1 : 0;
343 case vpiSize:
344 return rfp->bits.size();
346 default:
347 fprintf(stderr, "vvp error: get %d not supported "
348 "by vpiBinaryConst\n", code);
349 assert(0);
350 return 0;
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) {
365 case vpiObjTypeVal:
366 case vpiBinStrVal:
367 case vpiDecStrVal:
368 case vpiOctStrVal:
369 case vpiHexStrVal:
370 case vpiScalarVal:
371 case vpiIntVal:
372 case vpiVectorVal:
373 case vpiStringVal:
374 case vpiRealVal:
375 vpip_vec4_get_value(rfp->bits, rfp->bits.size(),
376 rfp->signed_flag, vp);
377 break;
379 default:
380 fprintf(stderr, "vvp error: format %d not supported "
381 "by vpiBinaryConst\n", vp->format);
382 vp->format = vpiSuppressVal;
383 break;
387 static const struct __vpirt vpip_binary_rt = {
388 vpiConstant,
389 binary_get,
391 binary_value,
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;
410 obj->sized_flag = 0;
411 obj->bits = vvp_vector4_t(wid);
413 const char*bp = bits;
414 if (*bp == 's') {
415 bp += 1;
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]) {
422 case '0':
423 val = BIT4_0;
424 break;
425 case '1':
426 val = BIT4_1;
427 break;
428 case 'x':
429 val = BIT4_X;
430 break;
431 case 'z':
432 val = BIT4_Z;
433 break;
436 obj->bits.set_bit(idx, val);
439 return &(obj->base);
442 struct __vpiBinaryParam : public __vpiBinaryConst {
443 const char*basename;
444 struct __vpiScope*scope;
445 unsigned file_idx;
446 unsigned lineno;
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) {
456 return rfp->lineno;
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);
481 switch (code) {
482 case vpiScope:
483 return &rfp->scope->base;
485 default:
486 return 0;
490 static const struct __vpirt vpip_binary_param_rt = {
491 vpiParameter,
492 binary_param_get,
493 binary_param_get_str,
494 binary_value,
497 binary_param_handle,
504 vpiHandle vpip_make_binary_param(char*name, const vvp_vector4_t&bits,
505 bool signed_flag,
506 long file_idx, long lineno)
508 struct __vpiBinaryParam*obj = new __vpiBinaryParam;
510 obj->base.vpi_type = &vpip_binary_param_rt;
511 obj->bits = bits;
512 obj->signed_flag = signed_flag? 1 : 0;
513 obj->sized_flag = 0;
514 obj->basename = name;
515 obj->scope = vpip_peek_current_scope();
516 obj->file_idx = (unsigned) file_idx;
517 obj->lineno = (unsigned) lineno;
519 return &obj->base;
523 static int dec_get(int code, vpiHandle ref)
526 switch (code) {
527 case vpiConstType:
528 return vpiDecConst;
530 case vpiSigned:
531 return 1;
533 case vpiSize:
534 return 32;
536 default:
537 fprintf(stderr, "vvp error: get %d not supported "
538 "by vpiDecConst\n", code);
539 assert(0);
540 return 0;
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);
550 char*cp = rbuf;
552 switch (vp->format) {
554 case vpiObjTypeVal:
555 case vpiIntVal: {
556 vp->value.integer = rfp->value;
557 break;
560 case vpiDecStrVal:
561 sprintf(rbuf, "%d", rfp->value);
563 vp->value.str = rbuf;
564 break;
566 case vpiBinStrVal:
567 for(int bit=31; bit<=0;bit--){
568 *cp++ = "01"[ (rfp->value>>bit)&1 ];
570 *cp = 0;
572 vp->value.str = rbuf;
573 break;
575 case vpiHexStrVal:
576 sprintf(rbuf, "%08x", rfp->value);
578 vp->value.str = rbuf;
579 break;
581 case vpiOctStrVal:
582 sprintf(rbuf, "%011x", rfp->value);
584 vp->value.str = rbuf;
585 break;
587 default:
588 fprintf(stderr, "vvp error (vpi_const.cc): format %d not supported "
589 "by vpiDecConst\n", vp->format);
590 vp->format = vpiSuppressVal;
591 break;
595 static const struct __vpirt vpip_dec_rt = {
596 vpiConstant,
597 dec_get,
599 dec_value,
605 vpiHandle vpip_make_dec_const(struct __vpiDecConst*obj, int value)
607 obj->base.vpi_type = &vpip_dec_rt;
608 obj->value = value;
610 return &(obj->base);
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)
626 switch (code) {
627 case vpiLineNo:
628 return 0; // Not implemented for now!
630 case vpiSize:
631 return 1;
633 case vpiConstType:
634 return vpiRealConst;
636 case vpiSigned:
637 return 1;
639 default:
640 fprintf(stderr, "vvp error: get %d not supported "
641 "by vpiDecConst\n", code);
642 assert(0);
643 return 0;
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) {
654 case vpiObjTypeVal:
655 vp->format = vpiRealVal;
656 case vpiRealVal:
657 vp->value.real = rfp->value;
658 break;
659 default:
660 fprintf(stderr, "vvp error: unsupported format %d.\n", vp->format);
661 assert(0);
665 static const struct __vpirt vpip_real_rt = {
666 vpiConstant,
667 real_get,
669 real_value,
675 vpiHandle vpip_make_real_const(struct __vpiRealConst*obj, double value)
677 obj->base.vpi_type = &vpip_real_rt;
678 obj->value = value;
679 return &(obj->base);
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 {
690 const char*basename;
691 struct __vpiScope* scope;
692 unsigned file_idx;
693 unsigned lineno;
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) {
703 return rfp->lineno;
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);
728 switch (code) {
729 case vpiScope:
730 return &rfp->scope->base;
732 default:
733 return 0;
737 static const struct __vpirt vpip_real_param_rt = {
738 vpiParameter,
739 real_param_get,
740 real_param_get_str,
741 real_value,
744 real_param_handle,
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;
759 obj->value = value;
760 obj->basename = name;
761 obj->scope = vpip_peek_current_scope();
762 obj->file_idx = (unsigned) file_idx;
763 obj->lineno = (unsigned) lineno;
765 return &obj->base;