/*---------------------------------------------------------------------------- * int * check_mon() * entry point for $check_mon * * Return Value -- * always 0 * * Design -- * syscall return is whether we should finish * first param of syscall returns why * Side effects -- * none *---------------------------------------------------------------------------- */ int check_mon() { tf_putp(2, ms.finish_pending); tf_putp(1, ms.finish_type); return 0; }
/* * routine to setup memory filling routine - set param to 0 on error else 1 * function: $plisetupmemfill(memsiz, memwid) */ static void plisetupmemfill(int data, int reason) { char *chp; /* get file name as + verilog argument */ if ((chp = mc_scan_plusargs("memfile+")) == NULL || strcmp(chp, "") == 0) { tf_error("missing or empty +memfile+[file name] memory file argument"); tf_putp(0, 0); return; } /* open the file */ if ((memval_s = fopen(chp, "r")) == NULL) { tf_error("unable to open +memfile+ memory file %s", chp); tf_putp(0, 0); return; } /* need memory size for checking */ memsiz = tf_getp(1); memwid = tf_getp(2); tf_putp(0, 1); /* assume memory goes from 1 to size */ last_i = 0; }
int util_get_plus_args_num() { /* Example use integer num_vectors; // number of test vectors integer MAX_FAILURES; // max failed vectors before aborting initial begin // get integers from plus argument values num_vectors = $util_get_plus_args_num("num_vectors"); MAX_FAILURES = $util_get_plus_args_num("max_failures"); $display("%d VECTORS IN TEST FILE.", num_vectors); $display("Maximum number of failures is %d", MAX_FAILURES); end */ /* Input: [unsigned int which is a string | * C string ] * Returns: Arg. value in 32 bit integer. * On error returns VERILOG_C_ERROR * Action: Gets the parameter, calls 'mc_scan_plusargs' * to get the arg. value. * */ int np; char *cp; np = tf_nump(); if ( np != 1 ) { if (DEBUG_PLUS_ARGS) { io_printf("get_plus_args_num(): Error: Number of args != 1.\n"); } tf_putp(0, VERILOG_ERROR); return(VERILOG_ERROR); } cp = mc_scan_plusargs(tf_getcstringp(1)); if (cp == NULL ) { if (DEBUG_PLUS_ARGS) { io_printf("get_plus_args_num(): Matching number is not found: %d\n", tf_getcstringp(1)); } tf_putp(0, VERILOG_ERROR); return(VERILOG_ERROR); } if (DEBUG_PLUS_ARGS) io_printf("get_plus_args_num(): Got integer value: %d\n", atoi(cp)); tf_putp(0, atoi(cp) ); return(VERILOG_OK); }
/* * routine to set memory * function: $pli_memfill(mem[i], i) */ static void plimemfill(int data, int reason) { int i; char memval[1024]; i = tf_getp(2); if (i < 0 || i > memsiz) { tf_error("cannot fill memory location %d - memory has only %d cells"); tf_putp(0, 0); return; } if (fscanf(memval_s, "%s", memval) != 1) { /* problably should access OS error name here */ tf_error("error reading memory value for cell %d", i); tf_putp(0, 0); return; } /* probably should add code to check for memval as legal binary number */ /* but can be any width since putp assignment will widen or truncate */ /* make sure index i is legal - since must have used i in memory select */ /* only for checking */ if (i != last_i + 1) { tf_error("memory index %d non in sequence - %d expected", i, last_i + 1); tf_putp(0, 0); return; } last_i = i; /* this is #0, in CVC you would use extension routine tf_strputp */ /* it is identical to tf_strdelputp except string assignment immediate */ #ifdef __HAS_STRPUTP__ /* notice need final delay type parameter since may need to cancel */ /* events if delay form used elsewhere */ printf("*** using tf_strputp\n"); if (tf_strputp(1, memwid, 'b', memval) == 0) #else if (tf_strdelputp(1, memwid, 'b', memval, 0, 0) == 0) #endif { tf_error("strdelput of index memory failed"); tf_putp(0, 0); return; } tf_putp(0, 1); }
int pliopen_call () { int i; char * filename; FILE * fp; /* Get the filename and attempt to open it and get a file pointer. */ filename = tf_getcstringp(1); fp = fopen (filename, "r"); if (!fp) { printf ("\nPLIOPEN: Error opening file %s!", filename); return 1; } /* We need to return a handle. Find first non-zero handle. */ for (i = 0; i < MAX_FILES; i++) { if (fptab[i] == 0) { /* Found one. */ fptab[i] = fp; /* Stick this integer handle into 2nd argument */ tf_putp (2, i); return 1; } } if (PLIREAD_VERBOSE) printf ("\nPLIOPEN: Successfully opened file %s with handle of %d.", filename, i); return 0; }
/*------------------------------------------------------------------------------- if find x in the variable, kill simulation. --------------------------------------------------------------------------------*/ void x_checker_call() { char* avalPtr, *bvalPtr; int word, groups, size; s_tfnodeinfo node_info; tf_nodeinfo(1, &node_info); switch(node_info.node_type){ case TF_MEMORY_NODE : word = node_info.node_ngroups * 2; for(size = 0;size < node_info.node_mem_size;size++){ avalPtr = node_info.node_value.memoryval_p + size * word; bvalPtr = avalPtr + node_info.node_ngroups; for(groups = node_info.node_ngroups - 1; groups >= 0;groups--) if(bvalPtr[groups])handle_error(1); } break; case TF_REG_NODE : for(groups = 0; groups < node_info.node_ngroups ; groups++){ if(node_info.node_value.vecval_p[groups].bvalbits)handle_error(1); } break; case TF_NETVECTOR_NODE : for(groups = 0; groups < node_info.node_ngroups ; groups++){ if(node_info.node_value.vecval_p[groups].bvalbits)handle_error(1); } break; } tf_putp(0, 0);//indicates error }
/* * routine to set memory using tf_propagatep method * * must be 32 bits or less otherwise would need to write vecval manipulation * routines * * function: $pli_memfil2(mem[i], i) * here tfputp would be better choice since only allows non x/z forms */ static void plimemfil2(int data, int reason) { int i; unsigned memval; struct t_vecval *vecp; i = tf_getp(2); if (i < 0 || i > memsiz) { tf_error("cannot fill memory location %d - memory has only %d cells"); tf_putp(0, 0); return; } if (fscanf(memval_s, "%u", &memval) != 1) { /* problably should access OS error name here */ tf_error("error reading memory value for cell %d", i); tf_putp(0, 0); return; } /* probably should add code to check for memval as legal binary number */ /* but can be any width since putp assignment will widen or truncate */ /* make sure index i is legal - since must have used i in memory select */ /* only for checking */ if (i != last_i + 1) { tf_error("memory index %d non in sequence - %d expected", i, last_i + 1); tf_putp(0, 0); return; } last_i = i; tf_exprinfo(1, &xinfo); /* set value - using 32 bit value else would need string to 0*/ vecp = xinfo.expr_value_p; vecp[0].avalbits = (int) memval; vecp[0].bvalbits = 0; /* do assign - notice this forces re-evaluate of argument during assign */ /* SJM 12/20/02 - following LRM, fail is 1 not 0 */ if (tf_propagatep(1) == 1) { tf_error("tf_propagatep of indexed memory failed"); tf_putp(0, 0); } else tf_putp(0, 1); }
int fseq_calltf() { int N, result; N = tf_getp(1); result = fibonacci(N); tf_putp(0, result); return(0); }
/*------------------------------------------------------------------------------- --------------------------------------------------------------------------------*/ void handle_error(int loc) { handle hand; hand = acc_handle_tfarg(loc); io_printf("(%0d)Error:unkown value detected name(%s) value(%s)\n", tf_gettime(), acc_fetch_name(hand), acc_fetch_value(hand, "%h", 0)); tf_putp(0, 1);//indicates error }
static int calltf(int user_data, int reason) { // char *inst = tf_getinstance(); (void)user_data; /* Parameter is not used. */ (void)reason; /* Parameter is not used. */ tf_putp (0, tf_getp(1)); return 0; }
int pliread_call () { char line[200]; int fhandle; char * fmt; int value; FILE * fp; /* Get the handle */ fhandle = tf_getp (1); /* Check it out first */ if (fhandle < 0 || fhandle >= MAX_FILES) { printf ("\nPLIREAD: Invalid file handle. Aborting read."); return 1; } /* Handle is used to look up actual FILE pointer */ fp = fptab[fhandle]; if (fp == 0) { printf ("\nPLIREAD: File appears to be closed. Aborting read."); return 1; } /* OK. Try and read a line, check for EOFs.. */ if (!feof(fp)) { fgets (line, sizeof(line), fp); if (!feof(fp)) { if (strlen(line) > 0) { /* Got a promising line. Get format string from user */ fmt = tf_getcstringp(2); if (PLIREAD_VERBOSE) printf ("\nPLIREAD: Using format string of <%s>.", fmt); /* Here is the actual read */ sscanf (line, fmt, &value); if (PLIREAD_VERBOSE) printf ("\nPLIREAD: Read integer value of %d (0x%X).", value, value); /* That's it. Stick value back into caller's 3rd argument */ tf_putp(3, value); } } } return 0; }
int util_get_plus_args_str() { /* Example use: invocation script (bosox is passed in as first argument) ----------------- set basename = $1 verilog mymodule.v +tst_file_name${basename}.tst +log_file_name${basename}.log +err_file_name${basename}.err +result_file_name${basename}.result mymodule.v ---------- reg [32*8:1] tst_file_name; // plus argument string value reg [32*8:1] err_file_name; // plus argument string value reg [32*8:1] log_file_name; // plus argument string value reg [32*8:1] result_file_name; // plus argument string value integer plus_arg_ok; // 0 if ok, 1 if no plus argument value initial begin // get strings from plus argument values plus_arg_ok = $util_get_plus_args_str("tst_file_name", tst_file_name); plus_arg_ok = $util_get_plus_args_str("err_file_name", err_file_name); plus_arg_ok = $util_get_plus_args_str("log_file_name", log_file_name); plus_arg_ok = $util_get_plus_args_str("result_file_name",result_file_name); $display("tst_file_name is %s", tst_file_name); $display("err_file_name is %s", err_file_name); $display("log_file_name is %s", log_file_name); $display("result_file_name is %s", result_file_name); end */ /* Input is string Returning value is string. */ handle wrk_out; char *strArgIn; int sizeOut,sizeS_in; int numArgs; int cnt,size; char *buffer, *bufferout; s_setval_value value_out; s_setval_delay delay_out; delay_out.model = accNoDelay; delay_out.time.type = accRealTime; delay_out.time.real = 0.0; value_out.format = accHexStrVal; acc_initialize(); numArgs = tf_nump(); if(numArgs !=2) { tf_error("$get_plus_arg_string must have two arguments"); tf_putp(0,VERILOG_ERROR); return(VERILOG_ERROR); } /* Fetch the input register and size */ wrk_out = acc_handle_tfarg(2); sizeOut = (acc_fetch_size(wrk_out)/8); /* Get the string value */ strArgIn = mc_scan_plusargs(tf_getcstringp(1)); if (strArgIn == NULL) { if (DEBUG_PLUS_ARGS) io_printf("get_plus_args_str(): Matching string is not found: %s.\n", tf_getcstringp(1)); tf_putp(0,VERILOG_ERROR); return(VERILOG_ERROR); } if (strArgIn) { if (DEBUG_PLUS_ARGS) io_printf("get_plus_args_str(): Got string value: %s\n",strArgIn); } else { io_printf("get_plus_args_str(): Bad input string value.\n"); tf_putp(0,VERILOG_ERROR); return(VERILOG_ERROR); } /* Build new string */ sizeS_in = strlen(strArgIn); bufferout = (char *) malloc(sizeS_in + 1); sprintf(bufferout, "%s",strArgIn); if (sizeOut < sizeS_in) { tf_error("get_plus_args_str(): Register %s is not large enough.\n", acc_fetch_fullname(wrk_out)); tf_putp(0,VERILOG_ERROR); return(VERILOG_ERROR); } size = sizeS_in*2; buffer = (char *) malloc(size + 1); for (cnt =0; cnt < size; cnt +=2){ if (cnt < size){ /* Convert string into HEX code */ sprintf(&buffer[cnt],"%x",bufferout[cnt/2]); } } /* Null out the rest of the register else { buffer[cnt] = '\0'; buffer[cnt +1] = '\0'; } */ /* assign buffer to the verilog register */ value_out.value.str = buffer; acc_set_value(wrk_out, &value_out, &delay_out); tf_putp(0,VERILOG_OK); acc_close(); free(buffer); free(bufferout); return(VERILOG_OK); }
/*---------------------------------------------------------------------------- * int * check_num_dispmon_errors() * entry point for $check_num_dispmon_errors * * Return Value -- * always 0 * * Design -- * * Side effects -- * none *---------------------------------------------------------------------------- */ int check_num_dispmon_errors() { tf_putp(1, ms.global_errors); return 0; }
/* Get the current calue of the counter. 1st argument to PLI call should be the receiving register. */ int mypli_getcount_call () { /* printf ("\nMYPLI_GETCOUNT: ... 'tf_getp(1)' = %x", tf_getp(1)); */ tf_putp (1, counter); return 0; }