int monitor_checktf(void) { int nump=tf_nump(); if (nump < 3) { cDispmon("disp", MON_ERR, "Usage: $dispmon(\"unit\", tag, " "\"printf-style-format\", modulename, reg-or-int, " "reg-or-int);\nin instance %s", tf_mipname()); } else if (tf_typep(1) != tf_string) { cDispmon("disp", MON_ERR,"dispmon unit name is not a string\n" "in instance %s",tf_mipname()); } else if (tf_typep(3) != tf_string) { cDispmon("disp", MON_ERR, "dispmon format field is not a string\n" "in instance %s", tf_mipname()); } else { size_t nargs=monitor_nfmtargs(tf_getcstringp(3)); if(nargs+3!=nump) { cDispmon("disp",MON_ERR, "wrong number of parameters for format string \"%s\"\n" "in instance %s", tf_getcstringp(3), tf_mipname()); } } return 0; }
static int insert_var(RStr *output, FmtInfo *fi, int pn) { switch(fi->cvt_spec) { case 'm': expanding_strcat(output,tf_mipname()); /* calling module */ break; case 't': expanding_strcat(output,tf_strgettime()); /* current simulator time */ break; case '%': expanding_strcat(output,"%"); /* percent sign */ break; default: /* don't need this check if checktf errors */ if(strchr(has_nfld,fi->cvt_spec)) { char *text; /* translate x's to h's for hex; NC segfaults if you don't */ if(fi->cvt_spec=='x') fi->cvt_spec='h'; if(fi->cvt_spec=='X') fi->cvt_spec='H'; text= format_val(fi, fi->cvt_spec=='s' ? tf_getcstringp(pn) : tf_strgetp(pn,fi->cvt_spec)); expanding_strcat(output,text); free(text); pn++; } } return pn; }
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; }
/*---------------------------------------------------------------------------- * static void * do_mon(int p_add_newline) * error check Verilog side arguments, generate then print line * * Return Value -- * none * * Design -- * * Side effects --1H * possible death, modifies global_errors *---------------------------------------------------------------------------- */ static int do_mon(int p_add_newline) { char *unit_name_arg = tf_getcstringp(1); char *l_unit; int l_tag = tf_getp(2); int l_mon_type; if(!unit_name_arg) { char *mipname = tf_mipname(); printf("ERROR: failed to read first argument to $dispmon or " "$writemon, in 'do_mon()'. Hierarchy is '%s'\n", mipname ? mipname : "NULL"); return 0; } else { l_unit = strdup(unit_name_arg); if(!l_unit) { printf("ERROR: strdup failed in 'do_mon()'\n"); return 0; } } if(!ms.unit_tbl) init_unit_tbl(); l_mon_type=mon_type_for(l_unit, l_tag); if(l_mon_type!=NO_MON_TYPE) { int l_input_parms = tf_nump(); char *l_output=dispmon_parse(tf_getcstringp(3), l_input_parms, 4, l_unit); if (0!=l_output) { print_tagged_line("", l_unit, l_output, l_mon_type, p_add_newline); free(l_output); } } free(l_unit); return 0; }
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; }
size_t monitor_nfmtargs(char *fmt) { /* validate # of parameters and correct tokens by parsing format */ FmtArray *f=parse_fmt(fmt); size_t i=0,nargs=0; for(i=0; i<f->used; i++) { if(!f->f[i]->text && !strchr(no_nparam, f->f[i]->cvt_spec)) nargs++; if(f->f[i]->failed) cDispmon("disp", MON_ERR, "invalid format spec: \"%s\" in " "format string \"%s\"\nin instance %s", f->f[i]->text, tf_getcstringp(3),tf_mipname()); } FmtArray_delete(f); return nargs; }
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 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(); } }