/* * count and list all acc world (prim terminal) drivers */ void mei_count_drivers(handle inst, handle net) { int count = 0; handle term; char s1[1024], s2[1024]; io_printf(" ... processing drivers for %s:\n", acc_fetch_fullname(net)); for (term = acc_next_driver(net, NULL); term != NULL; term = acc_next_driver(net, term)) { if (mei_isinside(inst, term) == 1) { strcpy(s1, "inside"); count++; } else strcpy(s1, "outside"); if (acc_fetch_type(term) == accTerminal) { sprintf(s2, "prim %s port %d", acc_fetch_fullname(acc_handle_parent(term)), acc_fetch_index(term)); } else strcpy(s2, acc_fetch_fullname(term)); io_printf(" +++ %s is %s driver of %s in %s.\n", s2, s1, acc_fetch_fullname(net), acc_fetch_fullname(inst)); } io_printf("net %s has %d inside drivers.\n", acc_fetch_name(net), count); }
/* * variable value change call back routine */ int var_prt_vclchg(p_vc_record vcp) { /* unsigned long long now, chgtim; */ int otyp, ltime, htime; handle net; char s1[1024], s2[1024], s3[1024]; /* current time */ ltime = tf_getlongsimtime(&htime); /* -- now = ((unsigned long long) ((unsigned long) htime)) << 32 | ((unsigned long long) ((unsigned long) ltime)); -* vc record time *- chgtim = ((unsigned long long) ((unsigned long) vcp->vc_hightime)) << 32 | ((unsigned long long) ((unsigned long) vcp->vc_lowtime)); -- */ /* net handle assigned to user data field */ net = (handle) vcp->user_data; otyp = acc_fetch_type(net); if (vcp->vc_reason != event_value_change) { /* these do not have value, i.e. get va8ue return NULL with error */ if (otyp == accPort || otyp == accPortBit || otyp == accTerminal) { sprintf(s1, "obj=%s", acc_fetch_type_str(otyp)); } else strcpy(s1, acc_fetch_value(net, "%b", NULL)); } switch (vcp->vc_reason) { case logic_value_change: sprintf(s2, "scalar=%u(%s)", (unsigned) vcp->out_value.logic_value, s1); break; case sregister_value_change: sprintf(s2, "sr-scalar=%u(%s)", (unsigned) vcp->out_value.logic_value, s1); break; case real_value_change: case realtime_value_change: sprintf(s2, "**error**"); break; case event_value_change: strcpy(s2, "**event**"); break; default: sprintf(s2, "vector=%s", s1); } /* -- io_printf("--> now %uL (chg time %uL): %s=%s\n", now, chgtim, -- */ if (otyp != accTerminal) strcpy(s3, acc_fetch_fullname(net)); else strcpy(s3, "**terminal**"); io_printf("--> now %d (chg time %d): %s=%s\n", ltime, vcp->vc_lowtime, s3, s2); return(0); }
handle next_level(handle h, int l) { handle child_handle; if (l == 0) return null; child_handle = null; while (child_handle = acc_next_child (h, child_handle)) { next_level (child_handle, l-1); fprintf (fp, "%s\n", acc_fetch_fullname (child_handle)); } }
/* * process one instance and recursively process all under instances * processing is top down depth first */ static void process_inst(handle up_ihref) { int isiz; handle ihref; /* iproc_rtn(up_ihref); */ isiz = acc_count(acc_next_child, up_ihref); io_printf(" There are %d instances in %s.\n", isiz, acc_fetch_fullname(up_ihref)); for (ihref = NULL;;) { if ((ihref = acc_next_child(up_ihref, ihref)) == NULL) return; process_inst(ihref); } }
/* * set up change call back for all nets/regs of some type in iter * * now sure how acc_supposed to work - scopes inside module instance * are all tasks, functions, and labeled blocks in init/always blocks */ static void setup_1scope_chgcbs(handle scope) { static int varlist[] = { accReg, accIntegerVar, accTimeVar, 0 }; handle inscope, var; io_printf("... setting up vcls for scope %s\n", acc_fetch_fullname(scope)); /* set up value change call backs for all variables in this scope */ for (var = acc_next(varlist, scope, NULL); var != NULL; var = acc_next(varlist, scope, var)) add_vcl(var); /* also or all contained scopes */ for (inscope = acc_next_scope(scope, NULL); inscope != NULL; inscope = acc_next_scope(scope, inscope)) setup_1scope_chgcbs(inscope); }
/* * wire strength change value change call back routine */ int wire_prt_vclchg(p_vc_record vcp) { /* unsigned long long now, chgtim; */ int typ, ltime, htime; handle net; char s1[1024], s2[1024], s3[1024]; /* current time */ ltime = tf_getlongsimtime(&htime); /* --- now = ((unsigned long long) ((unsigned long) htime)) << 32 | ((unsigned long long) ((unsigned long) ltime)); -* vc record time *- chgtim = ((unsigned long long) ((unsigned long) vcp->vc_hightime)) << 32 | ((unsigned long long) ((unsigned long) vcp->vc_lowtime)); --- */ /* net handle assigned to user data field */ net = (handle) vcp->user_data; /* build strength value string */ sprintf(s1, "<%d, %d>=%d", (int) vcp->out_value.strengths_s.strength1, (int) vcp->out_value.strengths_s.strength2, (int) vcp->out_value.strengths_s.logic_value); /* also get value as internal strength %v string */ strcpy(s2, acc_fetch_value(net, "%v", NULL)); if (vcp->vc_reason != strength_value_change) { io_printf("*** ERROR: wire change reason %d - strength change expected\n", vcp->vc_reason); } /* --- io_printf("--> now %uL (chg time %uL): %s=%s(%s)\n", now, chgtim, -- */ /* terminals do not have names */ typ = acc_fetch_type(net); if (typ != accTerminal) strcpy(s3, acc_fetch_fullname(net)); else strcpy(s3, "**terminal**"); io_printf("--> now %d (chg time %d): %s=%s(%s)\n", ltime, vcp->vc_lowtime, s3, s2, s1); return(0); }
GpiObjHdl* FliImpl::native_check_create(void *raw_hdl, GpiObjHdl *parent) { LOG_DEBUG("Trying to convert a raw handle to an FLI Handle."); const char * c_name = acc_fetch_name(raw_hdl); const char * c_fullname = acc_fetch_fullname(raw_hdl); if (!c_name) { LOG_DEBUG("Unable to query the name of the raw handle."); return NULL; } std::string name = c_name; std::string fq_name = c_fullname; PLI_INT32 accType = acc_fetch_type(raw_hdl); PLI_INT32 accFullType = acc_fetch_fulltype(raw_hdl); return create_gpi_obj_from_handle(raw_hdl, name, fq_name, accType, accFullType); }
/* * process one instance and recursively process all under instances * processing is top down depth first */ static void process_inst(handle upinst) { handle inst, net; io_printf("... processing instance %s.\n", acc_fetch_fullname(upinst)); for (net = acc_next_net(upinst, NULL); net != NULL; net = acc_next_net(upinst, net)) { mei_count_drivers(upinst, net); mei_count_loads(upinst, net); mei_count_cellloads(upinst, net); } for (inst = NULL;;) { if ((inst = acc_next_child(upinst, inst)) == NULL) return; process_inst(inst); } }
/* * routine to add vcl to one net/reg/var/event */ static void add_vcl(handle net) { int typ, fulltyp; char s1[1024]; /* DBG remove -- */ typ = acc_fetch_type(net); fulltyp = acc_fetch_fulltype(net); if (typ != accTerminal) strcpy(s1, acc_fetch_fullname(net)); else strcpy(s1, "**terminal**"); io_printf("Adding vcl for %s type %s (fulltype %s)\n", s1, acc_fetch_type_str(typ), acc_fetch_type_str(fulltyp)); /* --- */ if (typ == accNet) { acc_vcl_add(net, wire_prt_vclchg, (void *) net, vcl_verilog_strength); } else acc_vcl_add(net, var_prt_vclchg, (void *) net, vcl_verilog_logic); }
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); }
/************************************************* 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 }
/************************************************* 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; }
/* * process one instance and recursively process all under instances * processing is top down depth first */ static int process_inst(handle upinst) { handle scope, inst, net, bit, var, prim, term, port; static int varlist[] = { accReg, accIntegerVar, accTimeVar, 0 }; io_printf("... setting up vcls for instance %s\n", acc_fetch_fullname(upinst)); /* first strength vcls on all nets */ /* first add vcls for nets */ io_printf("... vcls for wires\n"); for (net = acc_next_net(upinst, NULL); net != NULL; net = acc_next_net(upinst, net)) { if (acc_fetch_size(net) == 1) add_vcl(net); else { /* for vector wires, must put vcl on bit - need to access strength */ for (bit = acc_next_bit(net, NULL); bit != NULL; bit = acc_next_bit(net, bit)) add_vcl(bit); } } /* then variables */ io_printf("... vcls for variables\n"); for (var = acc_next(varlist, upinst, NULL); var != NULL; var = acc_next(varlist, upinst, var)) add_vcl(var); io_printf("... vcls for primitive terminals\n"); /* then primitives output terminals */ for (prim = acc_next_primitive(upinst, NULL); prim != NULL; prim = acc_next_primitive(upinst, prim)) { for (term = acc_next_terminal(prim, NULL); term != NULL; term = acc_next_terminal(prim, term)) { /* only output terminals can have vcl added */ if (acc_fetch_direction(term) == accInput) continue; add_vcl(term); } } /* then module ports */ io_printf("... vcls for ports\n"); for (port = acc_next_port(upinst, NULL); port != NULL; port = acc_next_port(upinst, port)) { if (acc_fetch_size(port) == 1) add_vcl(port); else { /* for vector ports, must put vcl on bit - need to access strength */ for (bit = acc_next_bit(port, NULL); bit != NULL; bit = acc_next_bit(port, bit)) add_vcl(bit); } } /* finally all variables in contained scopes */ for (scope = acc_next_scope(upinst, NULL); scope != NULL; scope = acc_next_scope(upinst, scope)) { /* final step setup vcls for contained scopes */ setup_1scope_chgcbs(scope); } for (inst = NULL;;) { if ((inst = acc_next_child(upinst, inst)) == NULL) break; process_inst(inst); } return(0); }