/************************************************* lxt2_recordsetup - specify options ************************************************/ int lxt2_recordsetup( int data, int reason ) { int i; acc_initialize(); switch( reason ) { case reason_checktf: if( tf_nump() == 0 ) { tf_error( "not enough arguments to recordsetup" ); tf_dofinish(); } goto DONE; case reason_calltf: if( lxt.inited ) { tf_error( "recording has already started" ); tf_dofinish(); } break; default: goto DONE; } for( i = 1; i <= tf_nump(); ++i ) { lxt2_option( acc_fetch_tfarg_str(i) ); } DONE: acc_close(); return 0; }
/************************************************* lxt2_recordclose - close lxt file and stop recording ************************************************/ int lxt2_recordclose( int data, int reason ) { acc_initialize(); switch( reason ) { case reason_checktf: if( tf_nump() != 0 ) { tf_error( "too many arguments to recordclose" ); tf_dofinish(); } goto DONE; case reason_calltf: if( !lxt.inited ) { tf_error( "recording has not started" ); tf_dofinish(); goto DONE; } break; default: goto DONE; } lxt2_close(); DONE: acc_close(); return 0; }
/* * FUNCTION: uvm_register_set_hdl * * Given a path, look the path name up using the PLI, * and set it to 'value'. */ void uvm_register_set_hdl(char *path, p_vpi_vecval value) { static int maxsize = -1; int i, size, chunks; vpiHandle r; s_vpi_value value_s; p_vpi_vecval value_p; s_vpi_time time_s = { vpiSimTime, 0, 0 }; r = vpi_handle_by_name(path, 0); if(r == 0) { vpi_printf("FATAL uvm_register : unable to locate hdl path (%s)\n", path); vpi_printf(" Either the name is incorrect, or you may not have PLI visibility to that name"); vpi_printf(" To gain PLI visibility, make sure you use +acc=rmb when you invoke vlog"); vpi_printf(" vlog +acc=rmb ...."); tf_dofinish(); } else { if(maxsize == -1) maxsize = uvm_register_get_max_size(); #ifdef NCSIM // Code for NC size = vpi_get(vpiSize, r); if(size > maxsize) { vpi_printf("FATAL uvm_register : hdl path '%s' is %0d bits,\n", path, size); vpi_printf(" but the maximum size is %0d, redefine using a compile\n", maxsize); vpi_printf(" flag. i.e. %s\n", "vlog ... +define+UVM_REGISTER_MAX_WIDTH=<value>"); tf_dofinish(); } chunks = (size-1)/32 + 1; // Probably should be: // value_p = (p_vpi_vecval)(calloc(1, chunks*8*sizeof(s_vpi_vecval))); value_p = (p_vpi_vecval)(malloc(chunks*8*sizeof(s_vpi_vecval))); value_s.format = vpiVectorVal; value_s.value.vector = value_p; /* Copy a/b, reversing on NC. */ /*dpi and vpi are reversed*/ /* - only in NC. In ModelSim they are the same. */ for(i=0;i<chunks; ++i) { // Reverse a/b on NC. value_p[i].aval = value[i].bval; value_p[i].bval = value[i].aval; } vpi_put_value(r, &value_s, &time_s, vpiNoDelay); free (value_p); #else // Code for Questa value_s.format = vpiVectorVal; value_s.value.vector = value; vpi_put_value(r, &value_s, &time_s, vpiNoDelay); #endif } return; }
/************************************************* lxt2_init - Open lxt file and enable collection ************************************************/ static void lxt2_init() { char* filename; if( lxt.inited ) { tf_error( "recording has alreay begun" ); tf_dofinish(); return; } if( lxt.filename ) { filename = lxt.filename; } else if( lxt.design ) { filename = (char*)malloc( strlen(lxt.design)+4+1 ); if( !filename ) { tf_error( "could not allocate memory" ); tf_dofinish(); return; } sprintf( filename, "%s.lxt", lxt.design ); lxt.filename = filename; } else { char* top = acc_fetch_name( acc_next_topmod(null) ); filename = (char*)malloc( strlen(top)+3+1 ); sprintf( filename, "%s.lxt", top ); lxt.filename = filename; } lxt.t = lxt2_wr_init( filename ); #if DEBUG io_printf( "lxt2_init: %p\n", lxt.t ); #endif if( !lxt.t ) { tf_error( "could not create file '%s'", filename ); tf_dofinish(); return; } lxt2_wr_set_timescale( lxt.t, acc_fetch_precision() ); if( lxt.compress ) { lxt2_wr_set_compression_depth(lxt.t, 9); lxt2_wr_set_partial_off(lxt.t); } else { lxt2_wr_set_compression_depth(lxt.t, 4); lxt2_wr_set_partial_on(lxt.t, 1); } lxt2_wr_set_break_size(lxt.t, lxt.incSize); lxt.inited = 1; lxt.enabled = 1; lxt.updateList = 0; lxt.eventList = 0; lxt.hunk = 0; lxt2_wr_set_initial_value( lxt.t, 'x' ); lxt2_wr_symbol_bracket_stripping( lxt.t, 1 ); lxt2_timemarker(); }
void error_call(int data, int reason) { char *ptr_mipname; char *ptr; int i; int ms, us, ns, ps; get_time (&ms, &us, &ns, &ps); ptr_mipname = tf_mipname(); /* Requires at least two arguments */ if (tf_nump() < ARG2) { tf_error("$error requires at least two arguments, error-disable-tag, and format-string"); tf_dofinish(); return; } /* First argument to $error() must be a string */ if (tf_typep(ARG1) != tf_string) { tf_error("First argument to $error must be a value"); tf_dofinish(); } /* Second argument to $error() must be a string */ if (tf_typep(ARG2) != tf_string) { tf_error("Second argument to $error must be a formating string"); tf_dofinish(); } for (i = 0; i < diserr_num; i++) { ptr = strchr(diserr_arr[i], '.'); if (ptr == NULL) { if (strcmp (tf_getcstringp(ARG1), diserr_arr[i]) == 0) { io_printf ("%05d.%03d.%03d.%03d: ERROR: %s:%s\n", ms,us,ns,ps, ptr_mipname, format(ptr_mipname)); return; } } else { sprintf (format_buffer, "%s.%s\0", tf_getcstringp(ARG1), ptr_mipname); if (strcmp (format_buffer, diserr_arr[i]) == 0) { io_printf ("%05d.%03d.%03d.%03d: ERROR: %s:%s\n", ms,us,ns,ps, ptr_mipname, format(ptr_mipname)); return; } } } io_printf ("%05d.%03d.%03d.%03d: ERROR: %s:%s\n", ms,us,ns,ps, ptr_mipname, format(ptr_mipname)); if (!error_disable) tf_dofinish(); return; }
/* * FUNCTION: uvm_register_set_hdl * * Given a path, look the path name up using the PLI, * and return its 'value'. */ void uvm_register_get_hdl(char *path, p_vpi_vecval value) { static int maxsize = -1; int i, size, chunks; vpiHandle r; s_vpi_value value_s; r = vpi_handle_by_name(path, 0); if(r == 0) { vpi_printf("FATAL uvm_register : unable to locate hdl path %s\n", path); vpi_printf(" Either the name is incorrect, or you may not have PLI visibility to that name"); vpi_printf(" To gain PLI visibility, make sure you use +acc=rmb when you invoke vlog"); vpi_printf(" vlog +acc=rmb ...."); tf_dofinish(); } else { if(maxsize == -1) maxsize = uvm_register_get_max_size(); size = vpi_get(vpiSize, r); if(size > maxsize) { vpi_printf("FATAL uvm_register : hdl path '%s' is %0d bits,\n", path, size); vpi_printf(" but the maximum size is %0d, redefine using a compile\n", maxsize); vpi_printf(" flag. i.e. %s\n", "vlog ... +define+UVM_REGISTER_MAX_WIDTH=<value>"); tf_dofinish(); } chunks = (size-1)/32 + 1; value_s.format = vpiVectorVal; vpi_get_value(r, &value_s); /*dpi and vpi are reversed*/ /* -> Not on Questa, and not in the LRM */ for(i=0;i<chunks; ++i) { #ifdef NCSIM // Code for NC. // Reverse a/b on NC. value[i].aval = value_s.value.vector[i].bval; value[i].bval = value_s.value.vector[i].aval; #else // Code for Questa value[i].aval = value_s.value.vector[i].aval; value[i].bval = value_s.value.vector[i].bval; #endif } } }
static char *format_val(FmtInfo *fi, char *val) { char *ftext; size_t len,width; if(fi->strip && val && *val) while((*val=='0' || *val==' ') && val[1]) val++; len=strlen(val); width=len > fi->width ? len+1 : fi->width+1; ftext=(char*)malloc(width); if(ftext==NULL) { printf("ERROR(%s):Can't get memory to form output!\n",modulename); tf_dofinish(); } if(fi->lalign) { strcpy(ftext,val); memset(ftext+len, ' ',width-len-1); } else { strcpy(ftext+width-len-1,val); memset(ftext, ' ', width-len-1); } ftext[width-1]=0; return ftext; }
/************************************************* lxt2_option - set a option ************************************************/ static void lxt2_option( char* str ) { char* eq = index( str, '=' ); int len = strlen( str ); if( eq ) { len -= strlen( eq ); } else if( !strncmp( str, "incsize", len ) ) { lxt.incSize = atoi( eq+1 ); } else if( !strncmp( str, "speed", len ) ) { lxt.compress = 0; } else if( !strncmp( str, "space", len ) ) { lxt.compress = 1; } else if( !strncmp( str, "sequence", len ) ) { lxt.sequence = 1; } else if( !strncmp( str, "nosequence", len ) ) { lxt.sequence = 0; } else if( !strncmp( str, "design", len ) ) { lxt.design = strdup( eq+1 ); } else if( !strncmp( str, "depth", len ) ) { lxt.depth = atoi( eq+1 ); } else { tf_error( "option %s not supported", str ); tf_dofinish(); } }
void genDumpMod_call(int data, int reason) { handle child_handle, module_handle; char *pargs, *ptr, *mod_name; int pargs_found, level; char buf[128]; pargs = mc_scan_plusargs ("gen_dump_module="); pargs_found = 0; if (pargs != (char *)0) { strcpy(buf, pargs); mod_name = strtok (buf, ":"); ptr = strtok (NULL, " \n"); level = atoi (ptr); if (level > 0 ) {pargs_found = 1;} } if (pargs_found == 0) return; io_printf ("%s %d\n", mod_name, level); if ((fp = fopen("dump.mod", "w")) == 0) tf_error ("can't open dump.mod file\n"); acc_initialize(); module_handle = acc_handle_object (mod_name); child_handle = null; next_level (module_handle, level); acc_close(); fclose (fp); tf_dofinish(); }
void info_call(int data, int reason) { char *ptr_mipname; int i, level; int ms, us, ns, ps; get_time (&ms, &us, &ns, &ps); ptr_mipname = tf_mipname(); /* Requires at least two arguments */ if (tf_nump() < ARG2) { tf_error("$info requires at least two arguments, info-level and format-string"); tf_dofinish(); return; } /* First argument to $info() must be a value */ if (tf_typep(ARG1) != tf_readonly) { tf_error("First argument to $info must be a value"); tf_dofinish(); } /* Second argument to $info() must be a string */ if (tf_typep(ARG2) != tf_string) { tf_error("Second argument to $info must be a formating string"); tf_dofinish(); } level = tf_getp(ARG1); if (level == 0) { io_printf ("%05d.%03d.%03d.%03d: INFO(%d): %s:%s\n", ms,us,ns,ps, level, ptr_mipname, format(ptr_mipname)); } else { for (i = 0; i < mon_path_num; i++) { if ((level <= mon_level[i]) && (strmatch (mon_inst_path[i], ptr_mipname) == 0) ) { io_printf ("%05d.%03d.%03d.%03d: INFO(%d): %s:%s\n", ms,us,ns,ps, level, ptr_mipname, format(ptr_mipname)); } } } return; }
static char *substring(const char *s, const char *e) { size_t textlen; /* =e ? e-s : strlen(s); */ char *text; if(e) { if(e > s) { /* Casts get around lint error involving substracting one ptr from another. Lint doesn't seem to like that, even though we just checked that e > s. */ textlen = (unsigned )e-(unsigned )s; } else { printf("ERROR: Assertion failed, in fn 'substring()', " "in monitor.c\n"); tf_dofinish(); } } else { textlen = strlen(s); } text=(char*)malloc(textlen+1); if(textlen) { if(text==NULL) { printf("ERROR(%s):Not enough memory to copy substring\n",modulename); tf_dofinish(); } /* strlcpy(text,s,textlen+1); NO STRLCPY ! BAD ON SOLARIS 7 ! */ strncpy(text, s, textlen); text[textlen] = 0; } return text; }
/* * process instances top down */ int process_all_insts(int reason, int udata) { handle topinst; for (topinst = NULL;;) { if ((topinst = acc_next_child(NULL, topinst)) == NULL) break; process_inst(topinst); } io_printf(" >>> All instances net drivers processed by acc_.\n"); tf_dofinish(); return(0); }
static FmtArray *FmtArray_add(FmtArray *f, FmtInfo *fmt) { if(f->used==f->sz) { f->sz+=10; if(!(f->f=(FmtInfo**)realloc(f->f,f->sz*sizeof *(f->f)))) { printf("ERROR(%s):Not enough memory to expand FmtArray\n",modulename); tf_dofinish(); } } f->f[f->used++]=fmt; return f; }
static RStr * expanding_strcat(RStr *p_r, const char *p_s) { size_t l_sl=strlen(p_s); size_t l_rl=strlen(p_r->str); if(l_rl+l_sl>=p_r->sz && 0==(p_r->str=(char*)realloc(p_r->str,l_rl+l_sl+100))) { printf("ERROR(%s): can't expand string\n", modulename); tf_dofinish(); } strcat(p_r->str,p_s); return p_r; }
void warn_call(int data, int reason) { char *ptr_mipname; int i; int ms, us, ns, ps; get_time (&ms, &us, &ns, &ps); ptr_mipname = tf_mipname(); /* Requires at least two arguments */ if (tf_nump() < ARG2) { tf_error("$warn requires at least two arguments, warn-disable-tag, and format-string"); tf_dofinish(); return; } /* First argument to $warn() must be a string */ if (tf_typep(ARG1) != tf_string) { tf_error("First argument to $warn must be a value"); tf_dofinish(); } /* Second argument to $warn() must be a string */ if (tf_typep(ARG2) != tf_string) { tf_error("Second argument to $warn must be a formating string"); tf_dofinish(); } for (i = 0; i < diswarn_num; i++) { if (strcmp (tf_getcstringp(ARG1), diswarn_arr[i]) == 0) return; } io_printf ("%05d.%03d.%03d.%03d: WARN: %s:%s\n", ms,us,ns,ps, ptr_mipname, format(ptr_mipname)); return; }
/*---------------------------------------------------------------------------- * static int * mon_type_for(char *p_unit, int p_tag) * look up monitor type * * Return Value -- * returns the monitor type to use for display * * Design -- * Gets unit from hash table, do array look up * defaults to how ever the enables are set for "default" * Side effects -- * none *---------------------------------------------------------------------------- */ static int mon_type_for(const char *p_unit, int p_tag) { UnitInfo *l_ui=(UnitInfo*)ht_get(ms.unit_tbl, p_unit); if(0==l_ui) l_ui=(UnitInfo*)ht_get(ms.unit_tbl, "default"); if(0==l_ui) { printf("ERROR(%s):Unit hash not set up right!\n", modulename); tf_dofinish(); } return l_ui->enable[p_tag] ? tag2mon_type(p_tag) : NO_MON_TYPE; }
/* user creates new text which must be freeable! or null */ static FmtInfo *FmtInfo_new(char cvt_spec,int strip,int lalign, unsigned long long width,int failed,char *text) { FmtInfo *f=(FmtInfo*)malloc(sizeof *f); if(!f) { printf("ERROR(monitor.c):Can't generate new FmtInfo\n"); tf_dofinish(); } f->cvt_spec=cvt_spec; f->strip=strip; f->lalign=lalign; f->width=width; f->failed=failed; f->text=text; return f; }
static FmtArray *FmtArray_new(size_t init_sz) { FmtArray *r=(FmtArray*)malloc(sizeof *r); if(!r) { printf("ERROR(%s):Not enough memory to parse format string\n", modulename); tf_dofinish(); } r->f= init_sz ? (FmtInfo**)malloc(init_sz*sizeof(FmtInfo *)) : 0; r->sz = r->f ? init_sz : 0; r->used=0; return r; }
/*---------------------------------------------------------------------------- * static RStr * * expanding_strcat(RStr *p_r, char *p_s) * concat str in p_r with p_s * * Return Value -- * the RStr * you passed in * * Design -- * realloc more memory if necessary, strcat * * Side effects -- * possible death *---------------------------------------------------------------------------- */ static RStr * expanding_strcat(RStr *p_r, const char *p_s) { size_t l_sl=strlen(p_s); size_t l_rl=strlen(p_r->str); if(l_rl+l_sl>=p_r->sz && 0==(p_r->str=(char*)realloc(p_r->str,l_rl+l_sl+100))) { printf("ERROR(%s): can't expand string\n", modulename); tf_dofinish(); } strcat(p_r->str,p_s); return p_r; } #if 0 /* b/c this is unused, which would make lint complain */ static RStr * expanding_strncat(RStr *p_r, const char *p_s, size_t n) { size_t l_sl=strlen(p_s); size_t l_rl=strlen(p_r->str); if (l_sl > n) l_sl = n; if(((l_rl + l_sl) >= p_r->sz) && ((p_r->str = realloc(p_r->str, l_rl + l_sl + 100)) == NULL)) { printf("ERROR(%s): can't expand string\n", modulename); tf_dofinish(); } strncat(p_r->str, p_s, n); return p_r; }
/*---------------------------------------------------------------------------- * int * errorCheck() * checks to see if we've reached max_errors * * Return Value -- * 1 on error kill, 0 otherwise * * Design -- * inhibit printing warnings and errors if we've reached max_errors * either by dying or turning them off * * Side effects -- * possible death, modifies finish_pending and finish_type *---------------------------------------------------------------------------- */ static int errorCheck() { int l_r=0; if (ms.global_errors >= ms.max_errors) { if(ms.external_finish!=0) { if (ms.finish_pending==0) { UnitInfo **l_ul=(UnitInfo **)ht_sorted_list(ms.unit_tbl, UnitInfo_cmp); UnitInfo **l_uit=0; //printf("Setting finish pending for verilog, and warn_stop as type.\n"); ms.finish_pending = 1; ms.finish_type = 1; /* termination pending due to max error */ /* disable further warn/errors till external */ /* verilog shuts down simulator. */ for(l_uit=l_ul; *l_uit; l_uit++) { (*l_uit)->enable[MON_WARN]=0; (*l_uit)->enable[MON_ERR]=0; } l_r=1; free(l_ul); } } else { printf("\nINFO(%s): MAX ERRORS REACHED - SIMULATION TERMINATED\n", modulename); printf("INFO(%s): TIME %s, ABNORMAL END--" "MONITOR CAUSED END OF SIMULATION\n", modulename, tf_strgettime()); printf("Ending simulation \nSIM_ERR_STATUS:1 \n"); tf_dofinish(); } } return l_r; }
/*---------------------------------------------------------------------------- * int * warningCheck() * checks to see if we've reached max_warnings * * Return Value -- * 1 on warning kill, 0 otherwise * * Design -- * inhibit printing warnings and errors if we've reached max_warnings * either by dying or turning them off * * Side effects -- * possible death, modifies finish_pending and finish_type *---------------------------------------------------------------------------- */ static int warningCheck() { int l_r=0; if (ms.global_warnings >= ms.max_warnings) { if(ms.external_finish!=0) { if(ms.finish_pending==0) { UnitInfo **l_ul=(UnitInfo **)ht_sorted_list(ms.unit_tbl, UnitInfo_cmp); UnitInfo **l_uit=0; //printf("Setting finish pending for verilog, and warn_stop as type.\n"); ms.finish_pending = 1; ms.finish_type = 2; for(l_uit=l_ul; *l_uit; l_uit++) { (*l_uit)->enable[MON_WARN]=0; (*l_uit)->enable[MON_ERR]=0; } l_r=1; free(l_ul); } } else { printf("\nINFO(%s): MAX WARNINGS REACHED - SIMULATION TERMINATED\n", modulename); printf("INFO(%s): TIME %s, ABNORMAL END--" "MONITOR CAUSED END OF SIMULATION\n", modulename, tf_strgettime()); printf("Ending simulation \nSIM_ERR_STATUS:2 \n"); tf_dofinish(); } } return l_r; }
/************************************************* lxt2_recordvars - add objects to be recorded ************************************************/ int lxt2_recordvars( int data, int reason ) { int update = 0; int objects = 0; int i; acc_initialize(); switch( reason ) { case reason_calltf: break; case reason_checktf: goto DONE; case reason_finish: if( lxt.inited ) { lxt2_close(); } goto DONE; case reason_rosynch: update = (lxt.updateList != NULL); while( lxt.updateList ) { info_p info; info = lxt.updateList; lxt2_dump( info, 0 ); lxt.updateList = info->updateNext; info->updateNext = 0; } if( update ) { lxt2_timemarkerp1(); } while( lxt.eventList ) { info_p info; info = lxt.eventList; lxt2_dump( info, 1 ); lxt.eventList = info->updateNext; info->updateNext = 0; } lxt2_nexttimemarker(); goto DONE; default: goto DONE; } ginstance = tf_getinstance(); /* * parse options first */ for( i = 1; i <= tf_nump(); ++i ) { handle object; if( tf_typep(i) == tf_nullparam ) { continue; } if( tf_typep(i) == tf_string ) { char* str = acc_fetch_tfarg_str(i); lxt2_option( str ); continue; } } /* * on first call, initialize structure */ if( !lxt.inited ) { lxt2_init(); } for( i = 1; i <= tf_nump(); ++i ) { handle object; if( tf_typep(i) == tf_nullparam ) { continue; } if( tf_typep(i) == tf_string ) { continue; } object = acc_handle_tfarg(i); if( !object ) { tf_error( "cannot find object" ); tf_dofinish(); goto DONE; } lxt2_add( object, lxt.depth ); objects++; } if( objects == 0 ) { #if DEBUG io_printf( "lxt2_recordvars: defaultpath=%s\n", acc_fetch_fullname(acc_handle_parent(acc_handle_tfinst())), lxt.depth ); #endif lxt2_add( acc_handle_parent(acc_handle_tfinst()), lxt.depth ); } lxt2_dump( lxt.objectList, 1 ); DONE: acc_close(); return 0; }
void monInit_check(int data, int reason) { int i; char *string, *name, *ptr, ch; if (monInit_done) return ; monInit_done = 1 ; /* * plus args for info. * +mon0=cpu0:25 +mon1=ccx:35 */ mon_path_num = 0; while (1) { sprintf (mon_name_buf, "mon%d=\0", mon_path_num); string = mc_scan_plusargs(mon_name_buf); if (string != 0) { strcpy(mon_name_buf, string); ptr = strtok (mon_name_buf, ":"); if (ptr == 0) { tf_error("Syntax error in mon%i plus arg (instance path)\n", mon_path_num); tf_dofinish(); return; } mon_inst_path[mon_path_num] = strdup (ptr); ptr = strtok (NULL, ":"); if (ptr == 0) { tf_error("Syntax error in mon%i plus arg (level)\n", mon_path_num); tf_dofinish(); return; } mon_level[mon_path_num] = atoi (ptr); } else { break; } mon_path_num++; } /* * plus args for diserr. * +diserr=uce:cer:xyz */ diserr_num = 0; string = mc_scan_plusargs("diserr="); if (string != 0) { ptr = strtok (string, ":"); if (ptr == 0) { tf_error("Syntax error in diserr plus arg\n"); tf_dofinish(); return; } while (1) { diserr_arr[diserr_num] = strdup (ptr); diserr_num++; ptr = strtok (NULL, ":"); if (ptr == 0) break; } } /* * plus args for diswarn. * +diswarn=mem0:mem3 */ diswarn_num = 0; string = mc_scan_plusargs("diswarn="); if (string != 0) { ptr = strtok (string, ":"); if (ptr == 0) { tf_error("Syntax error in diswarn plus arg\n"); tf_dofinish(); return; } while (1) { diswarn_arr[diswarn_num] = strdup (ptr); diswarn_num++; ptr = strtok (NULL, ":"); if (ptr == 0) break; } } }
/************************************************* lxt2_add - add object to file ************************************************/ static void lxt2_add( handle object, int depth ) { int real = 0; int event = 0; int flags; int msb; int lsb; info_p info; handle block; handle term; static int filter[] = { accIntegerVar, accNamedEvent, accNet, accRealVar, accRegister, accTimeVar, 0 }; switch( acc_fetch_type(object) ) { case accNamedEvent: flags = LXT2_WR_SYM_F_BITS; event = 1; break; case accRealVar: flags = LXT2_WR_SYM_F_DOUBLE; real = 1; break; case accIntegerVar: case accNet: case accPort: case accReg: case accTimeVar: case accParameter: flags = LXT2_WR_SYM_F_BITS; break; case accStatement: case accTask: case accModule: term = null; while(1) { term = acc_next( filter, object, term ); if( term == null ) { break; } lxt2_add( term, depth ); } if( depth == 1 ) { return; } block = null; while(1) { block = acc_next_child( object, block ); if( block == null ) { break; } lxt2_add( block, (depth==0) ? 0 : depth-1 ); } return; default: return; } info = (info_p)malloc( sizeof(info_t) ); if( !info ) { tf_error( "cannot allocate memory" ); tf_dofinish(); return; } info->object = object; info->name = strdup( acc_fetch_fullname(object) ); info->next = lxt.objectList; lxt.objectList = info; info->sequence = lxt.sequence; info->event = event; info->real = real; info->updateNext = 0; if( real ) { info->symbol = lxt2_wr_symbol_add( lxt.t, info->name, 0, 0, 0, flags ); } else if( event ) { info->symbol = lxt2_wr_symbol_add( lxt.t, info->name, 0, 0, 0, flags ); } else { acc_fetch_range( object, &msb, &lsb ); #if DEBUG io_printf( "lxt2_add: %s [ %d : %d ]\n", info->name, msb, lsb ); #endif info->symbol = lxt2_wr_symbol_add( lxt.t, info->name, 0, msb, lsb, flags ); } acc_vcl_add( object, lxt2_changed, (char*)info, vcl_verilog_logic ); #if DEBUG io_printf( "lxt2_recordvars: adding %p %s\n", info->symbol, info->name ); #endif }
/*---------------------------------------------------------------------------- * static void * print_tagged_line(char *p_prefix, char *p_unit, char *p_output, * int p_mon_type, int p_add_newline) * print out the line with timestamp and unit responsible * * Return Value -- * none * * Design -- * Get timestamp. Go through way too much effort to come up with a module name * put it together to get a tag, call smart_write_tagged_output * Side effects -- * possible death since it calls warningCheck() and errorCheck() * may modify global_errors or global_warnings *---------------------------------------------------------------------------- */ static void print_tagged_line(const char *p_prefix, const char *p_unit, char *p_output, int p_mon_type, int p_add_newline) { char *l_instance=tf_mipname(); char *l_pt1=0; char *l_modname=0; char *l_tag_gen[]={"%s%s%s%s", "%s: WARNING: %s[%s%s]: ", "%s: ERROR: %s[%s%s]: ", "%s: %s[%s%s]: ", "%s: INFO: %s[%s%s]: ", "%s: DBG: %s[%s%s]: "}; /* If l_instance == NULL, then we may be in a callback */ if (l_instance == NULL) { l_instance = "pli callback"; } /* get the module instance name. */ /* Generally, ch_sys.cheetah_mod.cpu..... */ /* Display as: (<mod>...<end_path_name>) */ if (0==(l_pt1 = strchr(l_instance, '.'))) { /* No module */ l_modname=strdup(l_instance); } else { /* we just want the full instance name from the mod level down. */ /* that's what we print out, always! If that's too long and your */ /* printouts end up hard to read, tough! Post process. */ l_modname=strdup(l_pt1+1); } if(0!=l_modname) { char *l_tagbuffer=0; /* lacking a predictable snprintf or asprintf, we guess at how large tagbuffer needs to be */ if(0==(l_tagbuffer=(char*)malloc(strlen(l_tag_gen[p_mon_type])+strlen(p_unit)+ strlen(p_prefix)+strlen(l_modname)+20))) { printf("ERROR(%s): Can not generate tag for output\n",modulename); tf_dofinish(); } sprintf(l_tagbuffer, l_tag_gen[p_mon_type], tf_strgettime(), p_unit, p_prefix, l_modname); if(WARNING_MON_TYPE==p_mon_type) ms.global_warnings++; if(ERROR_MON_TYPE==p_mon_type) { ms.global_errors++; /* if we do a dispmon (not writemon!) with an error monitor type. Force the start of a new line. */ if(p_add_newline && 0==ms.newLine) { puts(""); ms.newLine=1; } } smart_write_tagged_output(l_tagbuffer, p_output, p_add_newline); free(l_modname); free(l_tagbuffer); warningCheck(); errorCheck(); } }
static void socket_read_regs_all_error (int err) { tf_error ("socket-pli: incomplete regs value (from read-regs-all call (%d))\n", err); tf_dofinish(); }
/************************************************* lxt_incinit - close current file and open a new one maintaining the same trace info ************************************************/ static void lxt_incinit() { char* filename; char* dot; info_p info; #if DEBUG io_printf( "lxt_incinit: %p\n", lxt.t ); #endif /* * pinch off old file */ lxt_timemarker(); lt_close( lxt.t ); /* * create new filename */ lxt.hunk++; filename = (char*)malloc( strlen(lxt.filename)+10+1 ); dot = rindex( lxt.filename, '.' ); *dot = 0; if( lxt.hunk > 1 ) { dot = rindex( lxt.filename, '-' ); *dot = 0; } sprintf( filename, "%s-%d.lxt", lxt.filename, lxt.hunk ); free( lxt.filename ); lxt.filename = filename; /* * open new wave file */ lxt.t = lt_init( filename ); if( !lxt.t ) { tf_error( "could not create file '%s'", filename ); tf_dofinish(); return; } lt_set_clock_compress( lxt.t ); if( lxt.compress ) { // lt_set_chg_compress( lxt.t ); } lxt.updateList = 0; lxt.eventList = 0; lt_set_initial_value( lxt.t, 'x' ); lt_symbol_bracket_stripping( lxt.t, 1 ); lt_set_timescale( lxt.t, acc_fetch_precision() ); lxt_timemarker(); /* * add existing objects to new file */ info = lxt.objectList; while( info ) { int flags; int msb; int lsb; if( info->real ) { flags = LT_SYM_F_DOUBLE; } else { flags = LT_SYM_F_BITS; } if( info->real ) { info->symbol = lt_symbol_add( lxt.t, info->name, 0, 0, 0, flags ); } else if( info->event ) { info->symbol = lt_symbol_add( lxt.t, info->name, 0, 0, 0, flags ); } else { acc_fetch_range( info->object, &msb, &lsb ); info->symbol = lt_symbol_add( lxt.t, info->name, 0, msb, lsb, flags ); } info = info->next; } if( lxt.compress ) { lt_set_no_interlace( lxt.t ); } lxt_dump( lxt.objectList, 1 ); }