/* * 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); }
/************************************************* 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 }
handle acc_next_scope(handle scope, handle prev) { PLI_INT32 type[2] = {accScope, 0}; return acc_next(type, scope, prev); }
/* * 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); }