static PLI_INT32 delay_callback(p_cb_data cb_data) { s_vpi_time time_s; s_cb_data cb_data_s; vpiHandle cb_h; // register readonly callback // time_s.type = vpiSimTime; time_s.high = 0; time_s.low = 0; cb_data_s.reason = cbReadOnlySynch; cb_data_s.user_data = NULL; cb_data_s.cb_rtn = readonly_callback; cb_data_s.obj = NULL; cb_data_s.time = &time_s; cb_data_s.value = NULL; cb_h = vpi_register_cb(&cb_data_s); vpi_free_object(cb_h); // register delta callback // time_s.type = vpiSimTime; time_s.high = 0; time_s.low = 1; cb_data_s.reason = cbAfterDelay; cb_data_s.user_data = NULL; cb_data_s.cb_rtn = delta_callback; cb_data_s.obj = NULL; cb_data_s.time = &time_s; cb_data_s.value = NULL; cb_h = vpi_register_cb(&cb_data_s); vpi_free_object(cb_h); return(0); }
static PLI_INT32 sys_dumpfile_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); char *path; /* $dumpfile must be called before $dumpvars starts! */ if (dumpvars_status != 0) { char msg[64]; snprintf(msg, sizeof(msg), "LXT warning: %s:%d:", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); msg[sizeof(msg)-1] = 0; vpi_printf("%s %s called after $dumpvars started,\n", msg, name); vpi_printf("%*s using existing file (%s).\n", (int) strlen(msg), " ", dump_path); vpi_free_object(argv); return 0; } path = get_filename(callh, name, vpi_scan(argv)); vpi_free_object(argv); if (! path) return 0; if (dump_path) { vpi_printf("LXT warning: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("Overriding dump file %s with %s.\n", dump_path, path); free(dump_path); } dump_path = path; return 0; }
static PLI_INT32 sys_dumpvars_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle item; s_vpi_value value; unsigned depth = 0; (void)name; /* Parameter is not used. */ if (dump_file == 0) { open_dumpfile(callh); if (dump_file == 0) { if (argv) vpi_free_object(argv); return 0; } } if (install_dumpvars_callback()) { if (argv) vpi_free_object(argv); return 0; } /* Get the depth if it exists. */ if (argv) { value.format = vpiIntVal; vpi_get_value(vpi_scan(argv), &value); depth = value.value.integer; } if (!depth) depth = 10000; /* This dumps all the modules in the design if none are given. */ if (!argv || !(item = vpi_scan(argv))) { argv = vpi_iterate(vpiModule, 0x0); assert(argv); /* There must be at least one top level module. */ item = vpi_scan(argv); } for ( ; item; item = vpi_scan(argv)) { int dep = draw_scope(item); scan_item(depth, item, 0); /* The scope list must be sorted after we scan an item. */ vcd_names_sort(&lxt_tab); while (dep--) pop_scope(); } /* Most effective compression. */ if (lxm_optimum_mode == LXM_SPACE) { lt_set_no_interlace(dump_file); } return 0; }
static PLI_INT32 delta_callback(p_cb_data cb_data) { s_cb_data cb_data_s; s_vpi_time time_s; vpiHandle reg_iter, reg_handle, cb_h; s_vpi_value value_s; if (delta == 0) { return(0); } /* skip time value */ strtok(bufcp, " "); reg_iter = vpi_iterate(vpiArgument, from_myhdl_systf_handle); value_s.format = vpiHexStrVal; while ((value_s.value.str = strtok(NULL, " ")) != NULL) { reg_handle = vpi_scan(reg_iter); vpi_put_value(reg_handle, &value_s, NULL, vpiNoDelay); vpi_free_object(reg_handle); } if (reg_iter != NULL) { vpi_free_object(reg_iter); } // register readonly callback // time_s.type = vpiSimTime; time_s.high = 0; time_s.low = 0; cb_data_s.reason = cbReadOnlySynch; cb_data_s.user_data = NULL; cb_data_s.cb_rtn = readonly_callback; cb_data_s.obj = NULL; cb_data_s.time = &time_s; cb_data_s.value = NULL; cb_h = vpi_register_cb(&cb_data_s); vpi_free_object(cb_h); // register delta callback // time_s.type = vpiSimTime; time_s.high = 0; time_s.low = 1; cb_data_s.reason = cbAfterDelay; cb_data_s.user_data = NULL; cb_data_s.cb_rtn = delta_callback; cb_data_s.obj = NULL; cb_data_s.time = &time_s; cb_data_s.value = NULL; cb_h = vpi_register_cb(&cb_data_s); vpi_free_object(cb_h); return(0); }
static PLI_INT32 sys_sdf_annotate_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); FILE *sdf_fd; char *fname = get_filename(callh, name, vpi_scan(argv)); if (fname == 0) return 0; sdf_fd = fopen(fname, "r"); if (sdf_fd == 0) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("Unable to open SDF file \"%s\"." " Skipping this annotation.\n", fname); return 0; } /* The optional second argument is the scope to annotate. */ sdf_scope = vpi_scan(argv); if (sdf_scope) vpi_free_object(argv); else sdf_scope = vpi_handle(vpiScope, callh); /* Select which delay to use. */ sdf_min_typ_max = vpi_get(_vpiDelaySelection, 0); sdf_cur_cell = 0; sdf_callh = callh; sdf_process_file(sdf_fd, fname); sdf_callh = 0; fclose(sdf_fd); free(fname); return 0; }
static PLI_INT32 simbus_poll_compiletf(char*my_name) { vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle bus_h = vpi_scan(argv); if (bus_h == 0) { vpi_printf("%s:%d: Missing argument to $simbus_poll function\n", vpi_get_str(vpiFile, sys), (int)vpi_get(vpiLineNo, sys)); vpi_control(vpiFinish, 1); return 0; } vpiHandle trig = vpi_scan(argv); if (trig == 0) { vpi_printf("%s:%d: Missing argument to $simbus_poll function\n", vpi_get_str(vpiFile, sys), (int)vpi_get(vpiLineNo, sys)); vpi_control(vpiFinish, 1); return 0; } if (vpi_get(vpiType, trig) != vpiReg || vpi_get(vpiSize, trig) != 1) { vpi_printf("%s:%d: Trigger argument to $simbus_poll must be a single-bit reg.\n", vpi_get_str(vpiFile, sys), (int)vpi_get(vpiLineNo, sys)); vpi_control(vpiFinish, 1); return 0; } vpi_free_object(argv); return 0; }
static int sys_ungetc_compiletf(char*name) { int type; vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle item = vpi_scan(argv); if (item == 0) { vpi_printf("%s: mcd parameter missing.\n", name); return 0; } type = vpi_get(vpiType, item); switch (type) { case vpiReg: case vpiRealVal: case vpiIntegerVar: break; default: vpi_printf("ERROR: %s mcd parameter must be of integral", name); vpi_printf(", got vpiType=%d\n", type); vpi_free_object(argv); return 0; } return 0; }
/* * Implement $fclose system function */ static int sys_fclose_calltf(char *name) { unsigned int mcd; int type; s_vpi_value value; vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle item = vpi_scan(argv); if (item == 0) { vpi_printf("%s: mcd parameter missing.\n", name); return 0; } type = vpi_get(vpiType, item); switch (type) { case vpiReg: case vpiRealVal: case vpiIntegerVar: break; default: vpi_printf("ERROR: %s mcd parameter must be of integral type", name); vpi_printf(", got vpiType=%d\n", type); vpi_free_object(argv); return 0; } value.format = vpiIntVal; vpi_get_value(item, &value); mcd = value.value.integer; vpi_mcd_close(mcd); return 0; }
static int sys_fgets_compiletf(char*name) { vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle item = vpi_scan(argv); int type; if (item == 0) { vpi_printf("%s: string parameter missing.\n", name); return 0; } type = vpi_get(vpiType, item); if (type != vpiReg) { vpi_printf("%s: string parameter must be a reg.\n", name); vpi_free_object(argv); return 0; } item = vpi_scan(argv); if (item == 0) { vpi_printf("%s: mcd parameter missing.\n", name); return 0; } /* That should be all the arguments. */ item = vpi_scan(argv); assert(item == 0); return 0; }
static PLI_INT32 sys_fscanf_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); s_vpi_value val; struct byte_source src; FILE *fd; errno = 0; val.format = vpiIntVal; vpi_get_value(vpi_scan(argv), &val); fd = vpi_get_file(val.value.integer); if (!fd) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("invalid file descriptor (0x%x) given to %s.\n", (int)val.value.integer, name); errno = EBADF; val.format = vpiIntVal; val.value.integer = EOF; vpi_put_value(callh, &val, 0, vpiNoDelay); vpi_free_object(argv); return 0; } src.str = 0; src.fd = fd; scan_format(callh, &src, argv, name); return 0; }
// System function to permit code in the simulator to fail a test // TODO: Pass in an error string static int system_function_overload(char *userdata) { vpiHandle systfref, args_iter, argh; struct t_vpi_value argval; const char *msg = "*** NO MESSAGE PROVIDED ***"; // Obtain a handle to the argument list systfref = vpi_handle(vpiSysTfCall, NULL); args_iter = vpi_iterate(vpiArgument, systfref); // The first argument to fatal is the FinishNum which we discard if (args_iter && *userdata == systf_fatal_level) { argh = vpi_scan(args_iter); } if (args_iter) { // Grab the value of the first argument argh = vpi_scan(args_iter); argval.format = vpiStringVal; vpi_get_value(argh, &argval); vpi_free_object(args_iter); msg = argval.value.str; } gpi_log("simulator", *userdata, vpi_get_str(vpiFile, systfref), "", (long)vpi_get(vpiLineNo, systfref), msg ); // Fail the test for critical errors if (GPICritical == *userdata) gpi_embed_event(SIM_TEST_FAIL, argval.value.str); return 0; }
static int interface_init_calltf(char*user_data) { vpiHandle argh; struct t_vpi_value fno, fni; // Obtain a handle to the argument list vpiHandle systfref = vpi_handle(vpiSysTfCall, NULL); vpiHandle args_iter = vpi_iterate(vpiArgument, systfref); // Grab the value of the first argument argh = vpi_scan(args_iter); fno.format = vpiStringVal; vpi_get_value(argh, &fno); f_o = open (fno.value.str, O_RDONLY); if (f_o<0) printf ("VPI_ERROR: Error opening O file: \"%s\"\n", fno.value.str); else printf ("VPI_DEBUG: Success opening O file: \"%s\"\n", fno.value.str); // Grab the value of the first argument argh = vpi_scan(args_iter); fni.format = vpiStringVal; vpi_get_value(argh, &fni); f_i = open (fni.value.str, O_WRONLY); if (f_i<0) printf ("VPI_ERROR: Error opening O file: \"%s\"\n", fni.value.str); else printf ("VPI_DEBUG: Success opening O file: \"%s\"\n", fni.value.str); // Cleanup and return vpi_free_object(args_iter); return 0; }
static PLI_INT32 number_compiletf(PLI_BYTE8 *x) #endif { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; char *name; s_vpi_value var; (void)x; /* Parameter is not used. */ if (argv == 0) { vpi_printf("ERROR: missing required numeric argument.\n"), vpi_control(vpiFinish, 1); return 0; } arg = vpi_scan(argv); /* Check to see what vpi_get_value does during compiletf. */ name = vpi_get_str(vpiName, arg); vpi_printf("vpi_get_value (%s):\n", name ? name : "<N/A>"); var.format = vpiObjTypeVal; vpi_get_value(arg, &var); vpi_printf(" format = %d\n", (int) var.format); var.format = vpiDecStrVal; vpi_get_value(arg, &var); vpi_printf(" value = %s\n", var.value.str); vpi_free_object(argv); return 0; }
int writeWord_calltf(char *user_data) { vpiHandle systf_handle, arg_iterator, arg_handle, reg_handle; s_vpi_value current_value1; s_vpi_value current_value2; //unsigned long long instruction; /* obtain a handle to the system task instance. */ systf_handle = vpi_handle(vpiSysTfCall, 0); /* obtain handle to system task argument. */ arg_iterator = vpi_iterate(vpiArgument, systf_handle); reg_handle = vpi_scan(arg_iterator); /* read current value */ current_value1.format = vpiIntVal; /* read value as a integer */ vpi_get_value(reg_handle, ¤t_value1); reg_handle = vpi_scan(arg_iterator); current_value2.format = vpiIntVal; /* read value as a integer */ vpi_get_value(reg_handle, ¤t_value2); /* free iterator memory */ vpi_free_object(arg_iterator); //vpi_printf("-----------\n"); //vpi_printf("WriteWord-> Addr:%x Data writen:%x\n",(unsigned int)current_value2.value.integer,(unsigned int) current_value1.value.integer); VMEM[0]->write_word((unsigned int)current_value1.value.integer,(unsigned int)current_value2.value.integer); //vpi_printf("Addr:%x Data Read:%x\n",(unsigned int)current_value2.value.integer,VMEM[0]->read_word((unsigned int)current_value2.value.integer)); return(0); }
static PLI_INT32 sys_finish_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh, argv; s_vpi_value val; long diag_msg = 1; /* Get the argument list and look for the diagnostic message level. */ callh = vpi_handle(vpiSysTfCall, 0); argv = vpi_iterate(vpiArgument, callh); if (argv) { vpiHandle arg = vpi_scan(argv); vpi_free_object(argv); val.format = vpiIntVal; vpi_get_value(arg, &val); diag_msg = val.value.integer; } if (strcmp((const char*)name, "$stop") == 0) { vpi_control(vpiStop, diag_msg); return 0; } vpi_control(vpiFinish, diag_msg); return 0; }
int writeHalf_calltf(char *user_data) { unsigned short src; vpiHandle systf_handle, arg_iterator, arg_handle, reg_handle; s_vpi_value current_value1; s_vpi_value current_value2; //unsigned long long instruction; /* obtain a handle to the system task instance. */ systf_handle = vpi_handle(vpiSysTfCall, 0); /* obtain handle to system task argument. */ arg_iterator = vpi_iterate(vpiArgument, systf_handle); reg_handle = vpi_scan(arg_iterator); /* read current value */ current_value1.format = vpiIntVal; /* read value as a integer (Value to be writen) */ vpi_get_value(reg_handle, ¤t_value1); src = (unsigned short) current_value1.value.integer; reg_handle = vpi_scan(arg_iterator); current_value2.format = vpiIntVal; /* read value as a integer (Address in the memory) */ vpi_get_value(reg_handle, ¤t_value2); /* free iterator memory */ vpi_free_object(arg_iterator); //vpi_printf("Data writen \t%x\n",current_value2.value.integer); VMEM[0]->write_half(src,current_value2.value.integer); return(0); }
/* * check - must be at end of compile after sim data structure set up */ PLI_INT32 hello_chk(struct t_cb_data *cbp) { vpiHandle href, iref; struct t_vpi_error_info einfotab; vpi_printf("... executing EndOfCompile callback for checking.\n"); href = vpi_handle(vpiSysTfCall, NULL); if (vpi_chk_error(&einfotab)) { if (href != NULL) vpi_printf("... why is handle not nil\n"); vpi_printf("** ERR: $hello PLI 2.0 can not access systf call handle\n"); prtvpiemsg(&einfotab); /* vpi_sim_control(vpiFinish, 0); */ } iref = vpi_iterate(vpiArgument, href); if (vpi_chk_error(&einfotab)) { vpi_printf("** ERR: vpi_iterate error:\n"); prtvpiemsg(&einfotab); vpi_sim_control(vpiFinish, 0); } if (iref != NULL) { vpi_printf( "** ERR: $hello PLI 2.0 task called with %d arguments but none allowed", count_systf_args(iref)); vpi_free_object(iref); vpi_sim_control(vpiFinish, 0); } return(0); }
static PLI_INT32 from_myhdl_calltf(PLI_BYTE8 *user_data) { vpiHandle reg_iter, reg_handle; s_vpi_time verilog_time_s; char buf[MAXLINE]; char s[MAXWIDTH]; int n; static int from_myhdl_flag = 0; if (from_myhdl_flag) { vpi_printf("ERROR: $from_myhdl called more than once\n"); vpi_control(vpiFinish, 1); /* abort simulation */ return(0); } from_myhdl_flag = 1; init_pipes(); verilog_time_s.type = vpiSimTime; vpi_get_time(NULL, &verilog_time_s); verilog_time = timestruct_to_time(&verilog_time_s); if (verilog_time != 0) { vpi_printf("ERROR: $from_myhdl should be called at time 0\n"); vpi_control(vpiFinish, 1); /* abort simulation */ return(0); } sprintf(buf, "FROM 0 "); pli_time = 0; delta = 0; from_myhdl_systf_handle = vpi_handle(vpiSysTfCall, NULL); reg_iter = vpi_iterate(vpiArgument, from_myhdl_systf_handle); while ((reg_handle = vpi_scan(reg_iter)) != NULL) { if (vpi_get(vpiType, reg_handle) != vpiReg) { vpi_printf("ERROR: $from_myhdl argument %s should be a reg\n", vpi_get_str(vpiName, reg_handle)); vpi_control(vpiFinish, 1); /* abort simulation */ return(0); } strcat(buf, vpi_get_str(vpiName, reg_handle)); strcat(buf, " "); sprintf(s, "%d ", vpi_get(vpiSize, reg_handle)); strcat(buf, s); vpi_free_object(reg_handle); } //vpi_free_object(reg_iter); n = write(wpipe, buf, strlen(buf)); if ((n = read(rpipe, buf, MAXLINE)) == 0) { vpi_printf("Info: MyHDL simulator down\n"); vpi_control(vpiFinish, 1); /* abort simulation */ return(0); } assert(n > 0); buf[n] = '\0'; return(0); }
static PLI_INT32 sys_fscanf_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); /* Check that there are arguments. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires at least three argument.\n", name); vpi_control(vpiFinish, 1); return 0; } /* The first argument must be a file descriptor. */ if (! is_numeric_obj(vpi_scan(argv))) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's first argument (fd) must be numeric.\n", name); vpi_control(vpiFinish, 1); vpi_free_object(argv); return 0; } if (sys_check_args(callh, argv, name)) vpi_control(vpiFinish, 1); return 0; }
/* * Implement $fclose system function */ static PLI_INT32 sys_fclose_calltf(PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle fd = vpi_scan(argv); s_vpi_value val; PLI_UINT32 fd_mcd; errno = 0; vpi_free_object(argv); /* Get the file/MC descriptor and verify that it is valid. */ val.format = vpiIntVal; vpi_get_value(fd, &val); fd_mcd = val.value.integer; if ((! IS_MCD(fd_mcd) && vpi_get_file(fd_mcd) == NULL) || ( IS_MCD(fd_mcd) && vpi_mcd_printf(fd_mcd, "%s", "") == EOF) || (! fd_mcd)) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("invalid file descriptor/MCD (0x%x) given to %s.\n", (unsigned int)fd_mcd, name); errno = EBADF; return 0; } /* We need to cancel any active $fstrobe()'s for this FD/MCD. * For now we check in the strobe callback and skip the output * generation when needed. */ vpi_mcd_close(fd_mcd); return 0; }
static PLI_INT32 sys_fopenrwa_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); s_vpi_value val; char *fname; const char *mode; errno = 0; /* Get the mode. */ mode = name + strlen(name) - 1; /* Get the file name. */ fname = get_filename(callh, name, vpi_scan(argv)); vpi_free_object(argv); if (fname == 0) return 0; /* Open the file and return the result. */ val.format = vpiIntVal; val.value.integer = vpi_fopen(fname, mode); vpi_put_value(callh, &val, 0, vpiNoDelay); free(fname); return 0; }
int VpiCbHdl::cleanup_callback(void) { if (m_state == GPI_FREE) return 0; /* If the one-time callback has not come back then * remove it, it is has then free it. The remove is done * internally */ if (m_state == GPI_PRIMED) { if (!m_obj_hdl) { LOG_CRITICAL("VPI: passed a NULL pointer : ABORTING"); } if (!(vpi_remove_cb(get_handle<vpiHandle>()))) { LOG_CRITICAL("VPI: unbale to remove callback : ABORTING"); } check_vpi_error(); } else { #ifndef MODELSIM /* This is disabled for now, causes a small leak going to put back in */ if (!(vpi_free_object(get_handle<vpiHandle>()))) { LOG_CRITICAL("VPI: unbale to free handle : ABORTING"); } #endif } m_obj_hdl = NULL; m_state = GPI_FREE; return 0; }
/* * tf_putlongp implemented using VPI interface */ void tf_putlongp(int n, int lowvalue, int highvalue) { vpiHandle sys_h, sys_i, arg_h = 0; s_vpi_value val; int type; char str[20]; assert(n >= 0); /* get task/func handle */ sys_h = vpi_handle(vpiSysTfCall, 0); sys_i = vpi_iterate(vpiArgument, sys_h); type = vpi_get(vpiType, sys_h); /* verify function */ assert(!(n == 0 && type != vpiSysFuncCall)); /* find nth arg */ while (n > 0) { if (!(arg_h = vpi_scan(sys_i))) assert(0); n--; } if (!arg_h) arg_h = sys_h; /* fill in vpi_value */ sprintf(str, "%x%08x", highvalue, lowvalue); val.format = vpiHexStrVal; val.value.str = str; (void)vpi_put_value(arg_h, &val, 0, vpiNoDelay); vpi_free_object(sys_i); }
static PLI_INT32 sys_fflush_calltf(PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; s_vpi_value val; PLI_UINT32 fd_mcd; FILE *fp; (void) name; /* Not used! */ /* If we have no argument then flush all the streams. */ if (argv == 0) { fflush(NULL); return 0; } /* Get the file/MC descriptor. */ arg = vpi_scan(argv); vpi_free_object(argv); val.format = vpiIntVal; vpi_get_value(arg, &val); fd_mcd = val.value.integer; if (IS_MCD(fd_mcd)) { vpi_mcd_flush(fd_mcd); } else { /* If we have a valid file descriptor flush the file. */ fp = vpi_get_file(fd_mcd); if (fp) fflush(fp); } return 0; }
static PLI_INT32 sys_mti_dist_uniform_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh, argv, seed, start, end; s_vpi_value val; long i_seed, i_start, i_end; /* Get the argument handles and convert them. */ callh = vpi_handle(vpiSysTfCall, 0); argv = vpi_iterate(vpiArgument, callh); seed = vpi_scan(argv); start = vpi_scan(argv); end = vpi_scan(argv); val.format = vpiIntVal; vpi_get_value(seed, &val); i_seed = val.value.integer; vpi_get_value(start, &val); i_start = val.value.integer; vpi_get_value(end, &val); i_end = val.value.integer; /* Calculate and return the result. */ val.value.integer = mti_dist_uniform(&i_seed, i_start, i_end); vpi_put_value(callh, &val, 0, vpiNoDelay); /* Return the seed. */ val.value.integer = i_seed; vpi_put_value(seed, &val, 0, vpiNoDelay); vpi_free_object(argv); return 0; }
static PLI_INT32 sys_sdf_annotate_compiletf(PLI_BYTE8*name) { check_command_line_args(); vpiHandle sys = vpi_handle(vpiSysTfCall,0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle path = vpi_scan(argv); if (path == 0) { vpi_printf("SDF ERROR: First argument of %s is required.\n", name); vpi_control(vpiFinish, 1); return 0; } assert(path); vpiHandle scope = vpi_scan(argv); if (scope == 0) return 0; if (vpi_get(vpiType,scope) != vpiModule) { vpi_printf("SDF ERROR: The second argument of %s" " must be a module instance.\n", name); vpi_control(vpiFinish, 1); } vpi_free_object(argv); return 0; }
static PLI_INT32 to_vec_compiletf(ICARUS_VPI_CONST PLI_BYTE8*user_data) { (void) user_data; /* Parameter is not used. */ vpiHandle systf_handle, arg_iterator, arg_handle; PLI_INT32 arg_type[2]; /* obtain a handle to the system task instance */ systf_handle = vpi_handle(vpiSysTfCall, NULL); if (systf_handle == NULL) { vpi_printf("ERROR: $ivl_darray_method$to_vec failed to obtain systf handle\n"); vpi_control(vpiFinish,0); /* abort simulation */ return 0; } /* obtain handles to system task arguments */ arg_iterator = vpi_iterate(vpiArgument, systf_handle); if (arg_iterator == NULL) { vpi_printf("ERROR: $ivl_darray_method$to_vec requires 2 arguments\n"); vpi_control(vpiFinish, 0); return 0; } /* check the type of object in system task arguments */ arg_handle = vpi_scan(arg_iterator); for(int i = 0; i < 2; ++i) { arg_type[i] = vpi_get(vpiType, arg_handle); arg_handle = vpi_scan(arg_iterator); } if (arg_handle != NULL) { /* are there more arguments? */ vpi_printf("ERROR: $ivl_darray_method$to_vec can only have 2 arguments\n"); vpi_free_object(arg_iterator); vpi_control(vpiFinish, 0); return 0; } if ((arg_type[0] != vpiRegArray) || (arg_type[1] != vpiNet && arg_type[1] != vpiReg && arg_type[1] != vpiBitVar)) { vpi_printf("ERROR: $ivl_darray_method$to_vec value arguments must be a dynamic array and a net or reg\n"); vpi_free_object(arg_iterator); vpi_control(vpiFinish, 0); return 0; } return 0; }
static int interface_event_calltf(char*user_data) { vpiHandle argh; struct t_vpi_value c_i, d_i, d_o, c_o; unsigned int c_i_size, d_i_size, d_o_size, c_o_size; // size of vector/structure // Obtain a handle to the argument list vpiHandle systfref = vpi_handle(vpiSysTfCall, NULL); vpiHandle args_iter = vpi_iterate(vpiArgument, systfref); // grab argument c_i argh = vpi_scan(args_iter); c_i.format = vpiIntVal; vpi_get_value(argh, &c_i); // compute the size of the c_i structure c_i_size = sizeof(PLI_INT32); // send c_i over pipe c_i_size = write (f_i, &c_i.value.integer, c_i_size); // grab argument d_i argh = vpi_scan(args_iter); d_i.format = vpiVectorVal; vpi_get_value(argh, &d_i); // compute the size of the d_i structure d_i_size = vpi_get(vpiSize, argh); d_i_size = (d_i_size-1)/(8*sizeof(PLI_INT32))+1; d_i_size = d_i_size*sizeof(struct t_vpi_vecval); // send d_i over pipe d_i_size = write (f_i, d_i.value.vector, d_i_size); // grab argument d_o argh = vpi_scan(args_iter); d_o.format = vpiVectorVal; vpi_get_value(argh, &d_o); // compute the size of the d_o structure d_o_size = vpi_get(vpiSize, argh); d_o_size = (d_o_size-1)/(8*sizeof(PLI_INT32))+1; d_o_size = d_o_size*sizeof(struct t_vpi_vecval); // receive d_i over pipe d_o_size = read (f_o, d_o.value.vector, d_o_size); // put d_o signals vpi_put_value(argh, &d_o, NULL, vpiNoDelay); // grab argument c_o argh = vpi_scan(args_iter); c_o.format = vpiIntVal; vpi_get_value(argh, &c_o); // compute the size of the c_o structure c_o_size = sizeof(PLI_INT32); // receive c_i over pipe c_o_size = read (f_o, &c_o.value.integer, c_o_size); // put c_o signals vpi_put_value(argh, &c_o, NULL, vpiNoDelay); // Cleanup vpi_free_object(args_iter); return 0; }
static int sys_random_calltf(char*name) { s_vpi_value val; vpiHandle call_handle; vpiHandle argv; vpiHandle seed = 0; int i_seed = 0; struct context_s *context; call_handle = vpi_handle(vpiSysTfCall, 0); assert(call_handle); /* Get the argument list and look for a seed. If it is there, get the value and reseed the random number generator. */ argv = vpi_iterate(vpiArgument, call_handle); if (argv) { seed = vpi_scan(argv); vpi_free_object(argv); val.format = vpiIntVal; vpi_get_value(seed, &val); i_seed = val.value.integer; /* Since there is a seed use the current context or create a new one */ context = (struct context_s *)vpi_get_userdata(call_handle); if (!context) { context = (struct context_s *)calloc(1, sizeof(*context)); context->mti = NP1; assert(context); /* squrrel away context */ vpi_put_userdata(call_handle, (void *)context); } /* If the argument is not the Icarus cookie, then reseed context */ if (i_seed != COOKIE) sgenrand(context, i_seed); } else { /* use global context */ context = &global_context; } val.format = vpiIntVal; val.value.integer = genrand(context); vpi_put_value(call_handle, &val, 0, vpiNoDelay); /* mark seed with cookie */ if (seed && i_seed != COOKIE) { val.format = vpiIntVal; val.value.integer = COOKIE; vpi_put_value(seed, &val, 0, vpiNoDelay); } return 0; }
static PLI_INT32 ivlh_attribute_event_compiletf(ICARUS_VPI_CONST PLI_BYTE8*data) { event_type_t type = (event_type_t) data; vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle arg; struct monitor_data*mon; struct t_cb_data cb; struct t_vpi_time tb; struct t_vpi_value vb; /* Check that there are arguments. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, sys), (int)vpi_get(vpiLineNo, sys)); vpi_printf("(compiler error) %s requires a single argument.\n", func_names[type]); vpi_control(vpiFinish, 1); return 0; } /* Icarus either returns 0 above or has one argument. */ arg = vpi_scan(argv); assert(arg); mon = malloc(sizeof(struct monitor_data)); /* Add this to the list of data. */ mdata_count += 1; mdata = (struct monitor_data **) realloc(mdata, sizeof(struct monitor_data **) * mdata_count); mdata[mdata_count-1] = mon; tb.type = vpiSimTime; vb.format = vpiScalarVal; cb.reason = cbValueChange; cb.cb_rtn = monitor_events; cb.obj = arg; cb.time = &tb; cb.value = &vb; cb.user_data = (char*) (mon); vpi_register_cb(&cb); vpi_put_userdata(sys, mon); /* Check that there is no more than one argument. */ arg = vpi_scan(argv); if (arg != 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, sys), (int)vpi_get(vpiLineNo, sys)); vpi_printf("(compiler error) %s only takes a single argument.\n", func_names[type]); vpi_free_object(argv); vpi_control(vpiFinish, 1); } return 0; }