Fix for assertion error when expanding macro.
[iverilog.git] / vpi / sys_vcd.c
blobedde342eb51d608b515707c40908c86d77e6eb27
1 /*
2 * Copyright (c) 1999-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: sys_vcd.c,v 1.58 2007/03/14 04:05:51 steve Exp $"
21 #endif
23 # include "sys_priv.h"
26 * This file contains the implementations of the VCD related
27 * funcitons.
30 # include "vpi_user.h"
31 # include <stdio.h>
32 # include <stdlib.h>
33 # include <string.h>
34 # include <assert.h>
35 # include <time.h>
36 #ifdef HAVE_MALLOC_H
37 # include <malloc.h>
38 #endif
39 # include "vcd_priv.h"
41 static char*dump_path = 0;
42 static FILE*dump_file = 0;
44 static const char*units_names[] = {
45 "s",
46 "ms",
47 "us",
48 "ns",
49 "ps",
50 "fs"
53 struct vcd_info {
54 vpiHandle item;
55 vpiHandle cb;
56 struct t_vpi_time time;
57 const char*ident;
58 struct vcd_info* next;
59 struct vcd_info* dmp_next;
60 int scheduled;
64 static char vcdid[8] = "!";
66 static void gen_new_vcd_id(void)
68 static unsigned value = 0;
69 unsigned v = ++value;
70 unsigned int i;
72 for (i=0; i < sizeof(vcdid)-1; i++) {
73 vcdid[i] = (char)((v%94)+33); /* for range 33..126 */
74 v /= 94;
75 if(!v) {
76 vcdid[i+1] = '\0';
77 break;
82 static struct vcd_info *vcd_list = 0;
83 static struct vcd_info *vcd_dmp_list = 0;
84 PLI_UINT64 vcd_cur_time = 0;
85 static int dump_is_off = 0;
86 static long dump_limit = 0;
87 static int dump_is_full = 0;
88 static int finish_status = 0;
90 static char *truncate_bitvec(char *s)
92 char l, r;
94 r=*s;
95 if(r=='1')
96 return s;
97 else
98 s += 1;
100 for(;;s++) {
101 l=r; r=*s;
102 if(!r) return (s-1);
104 if(l!=r)
105 return(((l=='0')&&(r=='1'))?s:s-1);
110 static void show_this_item(struct vcd_info*info)
112 s_vpi_value value;
114 if (vpi_get(vpiType, info->item) == vpiRealVar) {
115 value.format = vpiRealVal;
116 vpi_get_value(info->item, &value);
117 fprintf(dump_file, "r%.16g %s\n", value.value.real, info->ident);
119 } else if (vpi_get(vpiSize, info->item) == 1) {
120 value.format = vpiBinStrVal;
121 vpi_get_value(info->item, &value);
122 fprintf(dump_file, "%s%s\n", value.value.str, info->ident);
123 } else {
124 value.format = vpiBinStrVal;
125 vpi_get_value(info->item, &value);
126 fprintf(dump_file, "b%s %s\n",
127 truncate_bitvec(value.value.str),
128 info->ident);
133 static void show_this_item_x(struct vcd_info*info)
135 if (vpi_get(vpiType, info->item) == vpiRealVar) {
136 /* Some tools dump nothing here...? */
137 fprintf(dump_file, "rNaN %s\n", info->ident);
138 } else if (vpi_get(vpiSize, info->item) == 1) {
139 fprintf(dump_file, "x%s\n", info->ident);
140 } else {
141 fprintf(dump_file, "bx %s\n", info->ident);
147 * managed qsorted list of scope names/variables for duplicates bsearching
150 struct vcd_names_list_s vcd_tab = { 0 };
151 struct vcd_names_list_s vcd_var = { 0 };
154 static int dumpvars_status = 0; /* 0:fresh 1:cb installed, 2:callback done */
155 static PLI_UINT64 dumpvars_time;
156 inline static int dump_header_pending(void)
158 return dumpvars_status != 2;
162 * This function writes out all the traced variables, whether they
163 * changed or not.
165 static void vcd_checkpoint()
167 struct vcd_info*cur;
169 for (cur = vcd_list ; cur ; cur = cur->next)
170 show_this_item(cur);
173 static void vcd_checkpoint_x()
175 struct vcd_info*cur;
177 for (cur = vcd_list ; cur ; cur = cur->next)
178 show_this_item_x(cur);
181 static PLI_INT32 variable_cb_2(p_cb_data cause)
183 struct vcd_info* info = vcd_dmp_list;
184 PLI_UINT64 now = timerec_to_time64(cause->time);
186 if (now != vcd_cur_time) {
187 fprintf(dump_file, "#%" PLI_UINT64_FMT "\n", now);
188 vcd_cur_time = now;
191 do {
192 show_this_item(info);
193 info->scheduled = 0;
194 } while ((info = info->dmp_next) != 0);
196 vcd_dmp_list = 0;
198 return 0;
201 static PLI_INT32 variable_cb_1(p_cb_data cause)
203 struct t_cb_data cb;
204 struct vcd_info*info = (struct vcd_info*)cause->user_data;
206 if (dump_is_full) return 0;
207 if (dump_is_off) return 0;
208 if (dump_header_pending()) return 0;
209 if (info->scheduled) return 0;
211 if ((dump_limit > 0) && (ftell(dump_file) > dump_limit)) {
212 dump_is_full = 1;
213 vpi_printf("WARNING: Dump file limit (%ld bytes) "
214 "exceeded.\n", dump_limit);
215 fprintf(dump_file, "$comment Dump file limit (%ld bytes) "
216 "exceeded. $end\n", dump_limit);
217 return 0;
220 if (!vcd_dmp_list) {
221 cb = *cause;
222 cb.reason = cbReadOnlySynch;
223 cb.cb_rtn = variable_cb_2;
224 vpi_register_cb(&cb);
227 info->scheduled = 1;
228 info->dmp_next = vcd_dmp_list;
229 vcd_dmp_list = info;
231 return 0;
234 static PLI_INT32 dumpvars_cb(p_cb_data cause)
236 if (dumpvars_status != 1)
237 return 0;
239 dumpvars_status = 2;
241 dumpvars_time = timerec_to_time64(cause->time);
242 vcd_cur_time = dumpvars_time;
244 fprintf(dump_file, "$enddefinitions $end\n");
246 if (!dump_is_off) {
247 fprintf(dump_file, "#%" PLI_UINT64_FMT "\n", dumpvars_time);
248 fprintf(dump_file, "$dumpvars\n");
249 vcd_checkpoint();
250 fprintf(dump_file, "$end\n");
253 return 0;
256 static PLI_INT32 finish_cb(p_cb_data cause)
258 if (finish_status != 0)
259 return 0;
261 finish_status = 1;
263 dumpvars_time = timerec_to_time64(cause->time);
265 if (!dump_is_off && !dump_is_full && dumpvars_time != vcd_cur_time) {
266 fprintf(dump_file, "#%" PLI_UINT64_FMT "\n", dumpvars_time);
269 return 0;
272 inline static int install_dumpvars_callback(void)
274 struct t_cb_data cb;
275 static struct t_vpi_time time;
277 if (dumpvars_status == 1)
278 return 0;
280 if (dumpvars_status == 2) {
281 vpi_mcd_printf(1, "VCD warning:"
282 " $dumpvars ignored,"
283 " previously called at simtime %" PLI_UINT64_FMT "\n",
284 dumpvars_time);
285 return 1;
288 time.type = vpiSimTime;
289 cb.time = &time;
290 cb.reason = cbReadOnlySynch;
291 cb.cb_rtn = dumpvars_cb;
292 cb.user_data = 0x0;
293 cb.obj = 0x0;
295 vpi_register_cb(&cb);
297 cb.reason = cbEndOfSimulation;
298 cb.cb_rtn = finish_cb;
300 vpi_register_cb(&cb);
302 dumpvars_status = 1;
303 return 0;
306 static PLI_INT32 sys_dumpoff_calltf(PLI_BYTE8*name)
308 s_vpi_time now;
309 PLI_UINT64 now64;
311 if (dump_is_off)
312 return 0;
314 dump_is_off = 1;
316 if (dump_file == 0)
317 return 0;
319 if (dump_header_pending())
320 return 0;
322 now.type = vpiSimTime;
323 vpi_get_time(0, &now);
324 now64 = timerec_to_time64(&now);
326 if (now64 > vcd_cur_time)
327 fprintf(dump_file, "#%" PLI_UINT64_FMT "\n", now64);
328 vcd_cur_time = now64;
330 fprintf(dump_file, "$dumpoff\n");
331 vcd_checkpoint_x();
332 fprintf(dump_file, "$end\n");
334 return 0;
337 static PLI_INT32 sys_dumpon_calltf(PLI_BYTE8*name)
339 s_vpi_time now;
340 PLI_UINT64 now64;
342 if (!dump_is_off)
343 return 0;
345 dump_is_off = 0;
347 if (dump_file == 0)
348 return 0;
350 if (dump_header_pending())
351 return 0;
353 now.type = vpiSimTime;
354 vpi_get_time(0, &now);
355 now64 = timerec_to_time64(&now);
357 if (now64 > vcd_cur_time)
358 fprintf(dump_file, "#%" PLI_UINT64_FMT "\n", now64);
359 vcd_cur_time = now64;
361 fprintf(dump_file, "$dumpon\n");
362 vcd_checkpoint();
363 fprintf(dump_file, "$end\n");
365 return 0;
368 static PLI_INT32 sys_dumpall_calltf(PLI_BYTE8*name)
370 s_vpi_time now;
371 PLI_UINT64 now64;
373 if (dump_file == 0)
374 return 0;
376 if (dump_header_pending())
377 return 0;
379 now.type = vpiSimTime;
380 vpi_get_time(0, &now);
381 now64 = timerec_to_time64(&now);
383 if (now64 > vcd_cur_time)
384 fprintf(dump_file, "#%" PLI_UINT64_FMT "\n", now64);
385 vcd_cur_time = now.low;
387 fprintf(dump_file, "$dumpall\n");
388 vcd_checkpoint();
389 fprintf(dump_file, "$end\n");
391 return 0;
394 static void open_dumpfile(void)
396 if (dump_path == 0) {
397 dump_path = strdup("dump.vcd");
400 dump_file = fopen(dump_path, "w");
402 if (dump_file == 0) {
403 vpi_mcd_printf(1,
404 "VCD Error: Unable to open %s for output.\n",
405 dump_path);
406 return;
407 } else {
408 int prec = vpi_get(vpiTimePrecision, 0);
409 unsigned scale = 1;
410 unsigned udx = 0;
411 time_t walltime;
413 vpi_mcd_printf(1,
414 "VCD info: dumpfile %s opened for output.\n",
415 dump_path);
417 time(&walltime);
419 assert(prec >= -15);
420 while (prec < 0) {
421 udx += 1;
422 prec += 3;
424 while (prec > 0) {
425 scale *= 10;
426 prec -= 1;
429 fprintf(dump_file, "$date\n");
430 fprintf(dump_file, "\t%s",asctime(localtime(&walltime)));
431 fprintf(dump_file, "$end\n");
432 fprintf(dump_file, "$version\n");
433 fprintf(dump_file, "\tIcarus Verilog\n");
434 fprintf(dump_file, "$end\n");
435 fprintf(dump_file, "$timescale\n");
436 fprintf(dump_file, "\t%u%s\n", scale, units_names[udx]);
437 fprintf(dump_file, "$end\n");
441 static PLI_INT32 sys_dumpfile_compiletf(PLI_BYTE8*name)
443 vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
444 vpiHandle argv = vpi_iterate(vpiArgument, sys);
445 vpiHandle item;
447 char*path;
449 if (argv && (item = vpi_scan(argv))) {
450 s_vpi_value value;
452 if (vpi_get(vpiType, item) != vpiConstant
453 || vpi_get(vpiConstType, item) != vpiStringConst) {
454 vpi_mcd_printf(1,
455 "VCD Error:"
456 " %s parameter must be a string constant\n",
457 name);
458 return 0;
461 value.format = vpiStringVal;
462 vpi_get_value(item, &value);
463 path = strdup(value.value.str);
465 vpi_free_object(argv);
467 } else {
468 path = strdup("dump.vcd");
471 if (dump_path) {
472 vpi_mcd_printf(1, "VCD Warning:"
473 " Overriding dumpfile path %s with %s\n",
474 dump_path, path);
475 free(dump_path);
478 dump_path = path;
480 return 0;
483 static PLI_INT32 sys_dumpfile_calltf(PLI_BYTE8*name)
485 return 0;
488 static PLI_INT32 sys_dumpflush_calltf(PLI_BYTE8*name)
490 if (dump_file)
491 fflush(dump_file);
493 return 0;
496 static PLI_INT32 sys_dumplimit_compiletf(PLI_BYTE8 *name)
498 vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
499 vpiHandle argv = vpi_iterate(vpiArgument, callh);
500 vpiHandle limit;
502 /* Check that there is a argument and get it. */
503 if (argv == 0) {
504 vpi_printf("ERROR: %s requires an argument.\n", name);
505 vpi_control(vpiFinish, 1);
506 return 0;
508 limit = vpi_scan(argv);
510 /* Check that we are not given a string. */
511 switch (vpi_get(vpiType, limit)) {
512 case vpiConstant:
513 case vpiParameter:
514 if (vpi_get(vpiConstType, limit) == vpiStringConst) {
515 vpi_printf("ERROR: %s's argument must be a number.\n", name);
519 /* Check that there is only a single argument. */
520 limit = vpi_scan(argv);
521 if (limit != 0) {
522 vpi_printf("ERROR: %s takes a single argument.\n", name);
523 vpi_control(vpiFinish, 1);
524 return 0;
527 return 0;
530 static PLI_INT32 sys_dumplimit_calltf(PLI_BYTE8 *name)
532 vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
533 vpiHandle argv = vpi_iterate(vpiArgument, callh);
534 vpiHandle limit = vpi_scan(argv);
535 s_vpi_value val;
537 /* Get the value and set the dump limit. */
538 val.format = vpiIntVal;
539 vpi_get_value(limit, &val);
540 dump_limit = val.value.integer;
542 vpi_free_object(argv);
543 return 0;
546 static void scan_item(unsigned depth, vpiHandle item, int skip)
548 struct t_cb_data cb;
549 struct vcd_info* info;
551 const char* type;
552 const char* name;
553 const char* prefix;
554 const char* ident;
555 int nexus_id;
557 /* list of types to iterate upon */
558 int i;
559 static int types[] = {
560 /* Value */
561 vpiNet,
562 vpiReg,
563 vpiVariables,
564 /* Scope */
565 vpiFunction,
566 vpiModule,
567 vpiNamedBegin,
568 vpiNamedFork,
569 vpiTask,
573 switch (vpi_get(vpiType, item)) {
575 case vpiMemory:
576 /* don't know how to watch memories. */
577 break;
579 case vpiNamedEvent:
580 /* There is nothing in named events to dump. */
581 break;
583 case vpiNet: type = "wire"; if(0){
584 case vpiIntegerVar:
585 case vpiTimeVar:
586 case vpiReg: type = "reg"; }
588 /* Skip this signal if it has already been included. */
589 if (vcd_names_search(&vcd_var, vpi_get_str(vpiFullName, item))) {
590 vpi_printf("VCD warning: skipping signal %s, it was "
591 "previously included.\n",
592 vpi_get_str(vpiFullName, item));
593 break;
596 if (skip)
597 break;
599 name = vpi_get_str(vpiName, item);
600 prefix = is_escaped_id(name) ? "\\" : "";
602 nexus_id = vpi_get(_vpiNexusId, item);
604 if (nexus_id) {
605 ident = find_nexus_ident(nexus_id);
606 } else {
607 ident = 0;
610 if (!ident) {
611 ident = strdup(vcdid);
612 gen_new_vcd_id();
614 if (nexus_id)
615 set_nexus_ident(nexus_id, ident);
617 info = malloc(sizeof(*info));
619 info->time.type = vpiSimTime;
620 info->item = item;
621 info->ident = ident;
622 info->scheduled = 0;
624 cb.time = &info->time;
625 cb.user_data = (char*)info;
626 cb.value = NULL;
627 cb.obj = item;
628 cb.reason = cbValueChange;
629 cb.cb_rtn = variable_cb_1;
632 info->next = vcd_list;
633 info->dmp_next = 0;
634 vcd_list = info;
636 info->cb = vpi_register_cb(&cb);
639 fprintf(dump_file, "$var %s %u %s %s%s",
640 type, vpi_get(vpiSize, item), ident,
641 prefix, name);
642 /* FIXME
643 if (vpi_get(vpiVector, item)
645 if (vpi_get(vpiSize, item) > 1
646 || vpi_get(vpiLeftRange, item) != 0) {
647 fprintf(dump_file, " [%i:%i]", vpi_get(vpiLeftRange, item),
648 vpi_get(vpiRightRange, item));
650 fprintf(dump_file, " $end\n");
651 break;
653 case vpiRealVar:
655 /* Skip this signal if it has already been included. */
656 if (vcd_names_search(&vcd_var, vpi_get_str(vpiFullName, item))) {
657 vpi_printf("VCD warning: skipping signal %s, it was "
658 "previously included.\n",
659 vpi_get_str(vpiFullName, item));
660 break;
663 if (skip)
664 break;
666 /* Declare the variable in the VCD file. */
667 name = vpi_get_str(vpiName, item);
668 prefix = is_escaped_id(name) ? "\\" : "";
669 ident = strdup(vcdid);
670 gen_new_vcd_id();
671 fprintf(dump_file, "$var real 1 %s %s%s $end\n",
672 ident, prefix, name);
674 /* Add a callback for the variable. */
675 info = malloc(sizeof(*info));
677 info->time.type = vpiSimTime;
678 info->item = item;
679 info->ident = ident;
680 info->scheduled = 0;
682 cb.time = &info->time;
683 cb.user_data = (char*)info;
684 cb.value = NULL;
685 cb.obj = item;
686 cb.reason = cbValueChange;
687 cb.cb_rtn = variable_cb_1;
689 info->next = vcd_list;
690 info->dmp_next = 0;
691 vcd_list = info;
693 info->cb = vpi_register_cb(&cb);
695 break;
697 case vpiModule: type = "module"; if(0){
698 case vpiNamedBegin: type = "begin"; }if(0){
699 case vpiTask: type = "task"; }if(0){
700 case vpiFunction: type = "function"; }if(0){
701 case vpiNamedFork: type = "fork"; }
703 if (depth > 0) {
704 int nskip;
705 vpiHandle argv;
707 const char* fullname =
708 vpi_get_str(vpiFullName, item);
710 #if 0
711 vpi_mcd_printf(1,
712 "VCD info:"
713 " scanning scope %s, %u levels\n",
714 fullname, depth);
715 #endif
716 nskip = 0 != vcd_names_search(&vcd_tab, fullname);
718 if (!nskip)
719 vcd_names_add(&vcd_tab, fullname);
720 else
721 vpi_mcd_printf(1,
722 "VCD warning:"
723 " ignoring signals"
724 " in previously scanned scope %s\n",
725 fullname);
727 name = vpi_get_str(vpiName, item);
729 fprintf(dump_file, "$scope %s %s $end\n", type, name);
731 for (i=0; types[i]>0; i++) {
732 vpiHandle hand;
733 argv = vpi_iterate(types[i], item);
734 while (argv && (hand = vpi_scan(argv))) {
735 scan_item(depth-1, hand, nskip);
739 fprintf(dump_file, "$upscope $end\n");
741 break;
743 default:
744 vpi_mcd_printf(1,
745 "VCD Error: $dumpvars: Unsupported parameter "
746 "type (%d)\n", vpi_get(vpiType, item));
750 static int draw_scope(vpiHandle item)
752 int depth;
753 const char *name;
754 char *type;
756 vpiHandle scope = vpi_handle(vpiScope, item);
757 if (!scope)
758 return 0;
760 depth = 1 + draw_scope(scope);
761 name = vpi_get_str(vpiName, scope);
763 switch (vpi_get(vpiType, item)) {
764 case vpiNamedBegin: type = "begin"; break;
765 case vpiTask: type = "task"; break;
766 case vpiFunction: type = "function"; break;
767 case vpiNamedFork: type = "fork"; break;
768 default: type = "module"; break;
771 fprintf(dump_file, "$scope %s %s $end\n", type, name);
773 return depth;
777 * This function is also used in sys_lxt to check the arguments of the
778 * lxt variant of $dumpvars.
780 PLI_INT32 sys_vcd_dumpvars_compiletf(PLI_BYTE8*name)
782 vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
783 vpiHandle argv = vpi_iterate(vpiArgument, sys);
784 vpiHandle tmp;
786 if (argv == 0)
787 return 0;
789 tmp = vpi_scan(argv);
790 assert(tmp);
792 switch (vpi_get(vpiType, tmp)) {
793 case vpiConstant:
794 if (vpi_get(vpiConstType, tmp) == vpiStringConst) {
795 vpi_printf("ERROR: %s argument must be "
796 "a number constant.\n", name);
797 vpi_control(vpiFinish, 1);
799 break;
801 case vpiNet:
802 case vpiReg:
803 case vpiIntegerVar:
804 case vpiMemoryWord:
805 break;
807 default:
808 vpi_printf("ERROR: %s argument must be "
809 "a number constant.\n", name);
810 vpi_control(vpiFinish, 1);
811 break;
814 vpi_free_object(argv);
815 return 0;
818 static PLI_INT32 sys_dumpvars_calltf(PLI_BYTE8*name)
820 unsigned depth;
821 s_vpi_value value;
822 vpiHandle item = 0;
823 vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
824 vpiHandle argv;
826 if (dump_file == 0) {
827 open_dumpfile();
828 if (dump_file == 0)
829 return 0;
832 if (install_dumpvars_callback()) {
833 return 0;
836 argv = vpi_iterate(vpiArgument, sys);
838 depth = 0;
839 if (argv && (item = vpi_scan(argv)))
840 switch (vpi_get(vpiType, item)) {
841 case vpiConstant:
842 case vpiNet:
843 case vpiReg:
844 case vpiIntegerVar:
845 case vpiMemoryWord:
846 value.format = vpiIntVal;
847 vpi_get_value(item, &value);
848 depth = value.value.integer;
849 break;
852 if (!depth)
853 depth = 10000;
855 if (!argv) {
856 // $dumpvars;
857 // search for the toplevel module
858 vpiHandle parent = vpi_handle(vpiScope, sys);
859 while (parent) {
860 item = parent;
861 parent = vpi_handle(vpiScope, item);
864 } else if (!item || !(item = vpi_scan(argv))) {
865 // $dumpvars(level);
866 // $dumpvars();
867 // dump the current scope
868 item = vpi_handle(vpiScope, sys);
869 argv = 0x0;
872 for ( ; item; item = argv ? vpi_scan(argv) : 0x0) {
873 const char *scname;
874 int add_var = 0;
876 vcd_names_sort(&vcd_tab);
878 /* If this is a signal make sure it has not already
879 * been included. */
880 switch (vpi_get(vpiType, item)) {
881 case vpiIntegerVar:
882 case vpiNet:
883 case vpiRealVar:
884 case vpiReg:
885 case vpiTimeVar:
886 scname = vpi_get_str(vpiFullName, vpi_handle(vpiScope, item));
887 if (vcd_names_search(&vcd_tab, scname)) {
888 vpi_mcd_printf(1, "VCD warning: skipping signal %s, "
889 "it was previously included.\n",
890 vpi_get_str(vpiFullName, item));
891 continue;
892 } else {
893 add_var = 1;
897 int dep = draw_scope(item);
899 scan_item(depth, item, 0);
901 while (dep--) {
902 fprintf(dump_file, "$upscope $end\n");
905 /* Add this signal to the variable list so we can verify it
906 * is not included twice. This must be done after it has
907 * been added */
908 if (add_var) {
909 vcd_names_add(&vcd_var, vpi_get_str(vpiFullName, item));
910 vcd_names_sort(&vcd_var);
914 return 0;
917 void sys_vcd_register()
919 s_vpi_systf_data tf_data;
921 tf_data.type = vpiSysTask;
922 tf_data.tfname = "$dumpall";
923 tf_data.calltf = sys_dumpall_calltf;
924 tf_data.compiletf = 0;
925 tf_data.sizetf = 0;
926 tf_data.user_data = "$dumpall";
927 vpi_register_systf(&tf_data);
929 tf_data.type = vpiSysTask;
930 tf_data.tfname = "$dumpoff";
931 tf_data.calltf = sys_dumpoff_calltf;
932 tf_data.compiletf = 0;
933 tf_data.sizetf = 0;
934 tf_data.user_data = "$dumpoff";
935 vpi_register_systf(&tf_data);
937 tf_data.type = vpiSysTask;
938 tf_data.tfname = "$dumpon";
939 tf_data.calltf = sys_dumpon_calltf;
940 tf_data.compiletf = 0;
941 tf_data.sizetf = 0;
942 tf_data.user_data = "$dumpon";
943 vpi_register_systf(&tf_data);
945 tf_data.type = vpiSysTask;
946 tf_data.tfname = "$dumpfile";
947 tf_data.calltf = sys_dumpfile_calltf;
948 tf_data.compiletf = sys_dumpfile_compiletf;
949 tf_data.sizetf = 0;
950 tf_data.user_data = "$dumpfile";
951 vpi_register_systf(&tf_data);
953 tf_data.type = vpiSysTask;
954 tf_data.tfname = "$dumpflush";
955 tf_data.calltf = sys_dumpflush_calltf;
956 tf_data.compiletf = 0;
957 tf_data.sizetf = 0;
958 tf_data.user_data = "$dumpflush";
959 vpi_register_systf(&tf_data);
961 tf_data.type = vpiSysTask;
962 tf_data.tfname = "$dumplimit";
963 tf_data.calltf = sys_dumplimit_calltf;
964 tf_data.compiletf = sys_dumplimit_compiletf;
965 tf_data.sizetf = 0;
966 tf_data.user_data = "$dumplimit";
967 vpi_register_systf(&tf_data);
969 tf_data.type = vpiSysTask;
970 tf_data.tfname = "$dumpvars";
971 tf_data.calltf = sys_dumpvars_calltf;
972 tf_data.compiletf = sys_vcd_dumpvars_compiletf;
973 tf_data.sizetf = 0;
974 tf_data.user_data = "$dumpvars";
975 vpi_register_systf(&tf_data);