Access to modpaths via VPI

Add support for accessing the modpath nodes via PLI,
and add support for the vpi_set_delays and vpi_put_delays
functions to set the delays on those paths.

- GSoC 2007
This commit is contained in:
yang yun ju 2007-09-10 15:30:00 -07:00 committed by Stephen Williams
parent 8fe3cc5318
commit 9d39b3a514
7 changed files with 878 additions and 5 deletions

View File

@ -79,6 +79,15 @@ typedef struct t_vpi_vlog_info
typedef struct t_vpi_time {
/*
Type can be :
vpiScaledRealTime == 1
vpiSimTime == 2
vpiSuppressTime == 3
*/
PLI_INT32 type;
PLI_UINT32 high;
PLI_UINT32 low;
@ -116,6 +125,114 @@ typedef struct t_vpi_value {
} value;
} s_vpi_value, *p_vpi_value;
/*
Conform the IEEE 1364, We add the
Standard vpi_delay structure to
enable the modpath delay values
Conform IEEE 1364, Pg 670 :
The "da" field of the s_vpi_delay
structure shall be a user allocated
array of "s_vpi_time" struture
The arrary shall store delay values returned
by vpi_get_delay(). The number of elements in
the array shall be determined by
(1) The number of delays to be retrived
( normally this is used in vpi_get_delays (..) )
{
(1.1) Setted by "no_of_delays" field
(1.2) For the primitive_object, the no_of_delays
shall be 2 or 3
(1.3) For path_delay object the no_of_delays shall
be 1,2,3,6, 12
(1.4) For timing_check_object, the no_of_delays shall
be match the number of limits existing in the
Time Check
(1.5) For intermodule_path object, the no_of_delays shall
be 2 or 3
}
(2) The "mtm_flag" && "pulsere_flag"
Normally, if you set mtm = X, pulsere = Y
then, you will need allocate (num * no_of_delay)
s_vpi_time elements for 'da' array before calling
the vpi_get/put_delays (..)
---------------------------------------------------------------------------
| | | |
| mtm_flag | No of s_vpi_time array | order in which delay |
| pulsere_flag | element required by the | elements shall be filed |
| | s_vpi_delay->da | |
| | | |
|----------------|-------------------------|------------------------------|
| | | 1o delay da[0]--> 1o delay |
| mtm = false | no_of_delay | 2o delay da[1]--> 2o delay |
| pulere = false | | |
| | | |
|----------------|-------------------------|------------------------------|
| | | 1o delay da[0]--> min delay |
| mtm = true | | da[1]--> typ delay |
| pulere = false | 3*no_of_delay | da[2]--> max delay |
| | | 2o delay da[3]--> min delay |
| | | da[4]--> typ delay |
| | | .... |
|----------------|-------------------------|------------------------------|
| | | 1o delay da[0]--> delay |
| mtm = false | | da[1]--> rej limit |
| pulere = true | 3*no_of_delay | da[2]--> err limit |
| | | 2o delay da[3]--> delay |
| | | da[4]--> rej limit |
| | | .... |
|----------------|-------------------------|------------------------------|
| | | 1o delay da[0]--> min delay |
| mtm = true | | da[1]--> typ delay |
| pulere = true | 9*no_of_delay | da[2]--> max delay |
| | | da[3]--> min delay |
| | | da[4]--> typ delay |
| | | da[5]--> max delay |
| | | da[6]--> min delay |
| | | da[7]--> typ delay |
| | | da[8]--> max delay |
| | | 2o delay da[9]--> min delay |
| | | .... |
-------------------------------------------------------------------------
IMPORTANT :
The delay Structure has to be allocated before passing a pointer to
"vpi_get_delays ( )".
*/
typedef struct t_vpi_delay {
struct t_vpi_time *da; /* Array of delay datas */
PLI_INT32 no_of_delays ;
PLI_INT32 time_type; /* vpiScaledRealTime, vpiSimTime */
PLI_INT32 mtm_flag;
PLI_INT32 append_flag;
PLI_INT32 plusere_flag;
} s_vpi_delay, *p_vpi_delay;
/* These are valid codes for the format of the t_vpi_value structure. */
#define vpiBinStrVal 1
#define vpiOctStrVal 2
@ -158,6 +275,7 @@ typedef struct t_vpi_value {
#define vpiIterator 27
#define vpiMemory 29
#define vpiMemoryWord 30
#define vpiModPath 31
#define vpiModule 32
#define vpiNamedBegin 33
#define vpiNamedEvent 34
@ -177,6 +295,8 @@ typedef struct t_vpi_value {
#define vpiSysTfCall 85
#define vpiArgument 89
#define vpiInternalScope 92
#define vpiModPathIn 95
#define vpiModPathOut 96
#define vpiVariables 100
#define vpiCallback 1000
@ -361,6 +481,18 @@ extern vpiHandle vpi_put_value(vpiHandle obj, p_vpi_value value,
extern PLI_INT32 vpi_free_object(vpiHandle ref);
extern PLI_INT32 vpi_get_vlog_info(p_vpi_vlog_info vlog_info_p);
/*
These Routines will enable the modpath vpiHandle
to read/write delay values
*/
extern void vpi_get_delays(vpiHandle expr, p_vpi_delay delays);
extern void vpi_put_delays(vpiHandle expr, p_vpi_delay delays);
/*
* These functions support attaching user data to an instance of a
* system task or function. These functions only apply to

View File

@ -47,6 +47,21 @@
unsigned compile_errors = 0;
/* Auxiliary variable used to guard actual modpath input */
char *actual_modpath_input ;
/* Auxiliary variable used to guard actual scope label */
char *actual_modpath_label ;
/* Flag used to identify if actual modpath have been created */
int modpath_flag = 0 ;
vpiHandle vpiobj, srcobj ;
vvp_net_t *actual_modpath_input_net ;
/*
* The opcode table lists all the code mnemonics, along with their
* opcode and operand types. The table is written sorted by mnemonic
@ -1127,8 +1142,27 @@ vvp_fun_modpath* compile_modpath(char*label, struct symb_s src)
input_connect(net, 0, src.text);
define_functor_symbol(label, net);
free(label);
actual_modpath_input_net = net ;
// Make the vpiHandle for the vpiModPath
actual_modpath_input=(char *)calloc(strlen(src.text)+1,sizeof(char)) ;
strcpy ( actual_modpath_input, src.text ) ;
actual_modpath_label =(char *)calloc(strlen(label)+1, sizeof (char )) ;
strcpy ( actual_modpath_label, label ) ;
vpiobj = 0 ;
modpath_flag = 0 ; /*
If we are compiling a new
modpath vpiobj, we have to set
the flag = 0, indicating a
new modpath vpiHandle have to
be created
*/
free(label);
return obj;
}
@ -1145,6 +1179,31 @@ static vvp_net_t*make_modpath_src(vvp_fun_modpath*dst, char edge,
numbv_clear(&vals);
vvp_fun_modpath_src*obj = 0;
/*
Added By Yang
if the modpath_flag is NULL, then,
we have to call the modpath maker
to create a new modpath vpiHandle,
and insert all modpath_src into the vpi
else
just call the vpip_modpath_add_src to
insert new modpath source datas
*/
if ( modpath_flag == 0 )
{
vpiobj = vpip_make_modpath ( actual_modpath_label, actual_modpath_input , actual_modpath_input_net ) ;
modpath_flag = 1 ;
free ( actual_modpath_label ) ;
free ( actual_modpath_input ) ;
}
if (edge == 0) {
obj = new vvp_fun_modpath_src(use_delay);
@ -1173,11 +1232,20 @@ static vvp_net_t*make_modpath_src(vvp_fun_modpath*dst, char edge,
}
vvp_net_t*net = new vvp_net_t;
/*
Added by Yang
Compiling the delays values into actual modpath vpiHandle
*/
//vpip_add_mopdath_delay ( vpiobj, src.text, use_delay ) ;
srcobj = vpip_make_modpath_src ( src.text, use_delay, net ) ;
vpip_add_modpath_src ( vpiobj, srcobj ) ;
net->fun = obj;
input_connect(net, 0, src.text);
dst->add_modpath_src(obj);
return net;
}

View File

@ -427,7 +427,17 @@ void vvp_fun_modpath::run_run()
vvp_fun_modpath_src::vvp_fun_modpath_src(vvp_time64_t del[12])
{
for (unsigned idx = 0 ; idx < 12 ; idx += 1)
{
delay_[idx] = del[idx];
/*
Added By Yang.
Make the delay[12] value to be Public
make the get_delays(), put_delays() to
be possible
*/
delay [idx] = del[idx];
}
next_ = 0;
wake_time_ = 0;

View File

@ -185,9 +185,17 @@ class vvp_fun_modpath_src : public vvp_net_fun_t {
public:
void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit);
virtual bool test_vec4(const vvp_vector4_t&bit);
/*
Added By Yang.
Make the Delay Value be Public too
make the get_delays(), put_delays() be possible
*/
vvp_time64_t delay[12];
private:
// FIXME: Needs to be a 12-value array
vvp_time64_t delay_[12];

View File

@ -841,6 +841,70 @@ vpiHandle vpi_handle_by_name(const char *name, vpiHandle scope)
return 0;
}
/*
We Increment the tow vpi methods to enable the
read/write SDF delay values from/into
the modpath vpiHandle
baiscally, they will redirect the generic vpi_interface
vpi_get_delay ( .. )
vpi_put_delay ( .. )
to the
modpath_get_delay ( .. ) ;
modpath_put_delay ( .. ) ;
*/
void vpi_get_delays(vpiHandle expr, p_vpi_delay delays)
{
assert(expr);
assert(delays);
if (expr->vpi_type->vpi_get_delays_)
{
(expr->vpi_type->vpi_get_delays_)(expr, delays);
if (vpi_trace)
{
fprintf(vpi_trace,
"vpi_get_delays(%s, %p) -->\n", expr, delays);
}
}
}
void vpi_put_delays(vpiHandle expr, p_vpi_delay delays)
{
assert(expr );
assert(delays );
if (expr->vpi_type->vpi_put_delays_)
{
(expr->vpi_type->vpi_put_delays_)(expr, delays);
if (vpi_trace)
{
fprintf(vpi_trace,
"vpi_put_delays(%s, %p) -->\n", expr, delays);
}
}
}
extern "C" PLI_INT32 vpi_vprintf(const char*fmt, va_list ap)
{
return vpi_mcd_vprintf(1, fmt, ap);

View File

@ -27,6 +27,14 @@
# include "vvp_net.h"
# include "memory.h"
/*
* Added to use some "vvp_fun_modpath_src"
* and "vvp_fun_modpath" classes definitions
*/
#include "delay.h"
/*
* This header file contains the internal definitions that the vvp
* program uses to implement the public interface in the vpi_user.h
@ -84,6 +92,13 @@ struct __vpirt {
/* This implements the vpi_free_object method. */
int (*vpi_free_object_)(vpiHandle);
/*
This tow method are used to read/write delay
value from/into modpath record
*/
void (*vpi_get_delays_)(vpiHandle, p_vpi_delay);
void (*vpi_put_delays_)(vpiHandle, p_vpi_delay);
};
/*
@ -194,6 +209,109 @@ extern vpiHandle vpip_make_net(const char*name, int msb, int lsb,
extern __vpiSignal* vpip_signal_from_handle(vpiHandle obj);
struct __vpiModPathSrc {
struct __vpiHandle base ;
struct __vpiScope *scope ;
int type ;
char *label ; /*
Must Be removed in Future
because the ModPathSrc have
no label
*/
char *name ;
struct __vpiModPathSrc *next ;
/* Just Temporary */
vvp_time64_t use_delay [12] ;
/*
Conform the IEEE1364, we use the
standard delay value structure
(p_vpi_time) to represent delay values
of each modpath_src delay
the "p_vpi_time" is defined in the
"vpi_user.h"
*/
p_vpi_delay delays ;
/*
The Posedge, Negedge are already defined
in the "delays->p_vpi_time(da)->high/low"
bool posedge, negedge ;
*/
vvp_net_t *node;
} ;
/*
*
* The vpiMoaPath vpiHandle will define
* a vpiModPath of record .modpath as defined
* in the IEEE 1364
*
*/
struct __vpiModPath {
struct __vpiHandle base ;
struct __vpiScope *scope ;
/*
* The name, input must be removed
* in future um ModPathSrc have no
* name.
*/
char *name ;
char *input ;
vvp_net_t *input_net ;
struct __vpiModPathSrc *src_list ;
/*
* Keep an array of internal modpath_src
* vpiHandle
*/
struct __vpiHandle **src ;
/*
* Registering the number of modpath_src
* number
*/
unsigned int src_no ;
};
/*
* The Function is used to create the vpiHandle
* for vpiModPath && vpiModPathIn objects
*/
extern vpiHandle vpip_make_modpath_src ( char *name,
vvp_time64_t use_delay[12] ,
vvp_net_t *net ) ;
extern vpiHandle vpip_make_modpath ( char *name,
char *input,
vvp_net_t *net ) ;
extern void vpip_add_mopdath_delay ( vpiHandle vpiobj,
char *label,
vvp_time64_t use_delay[12] ) ;
extern void vpip_add_mopdath_edge ( vpiHandle vpiobj,
char *label,
vvp_time64_t use_delay[12],
bool posedge ,
bool negedge ) ;
extern void vpip_add_modpath_src ( vpiHandle modpath,
vpiHandle src ) ;
extern __vpiModPath* vpip_modpath_from_handle ( vpiHandle obj);
extern __vpiModPathSrc* vpip_modpath_src_from_handle( vpiHandle obj);
/*
* These methods support the vpi creation of events. The name string
* passed in will be saved, so the caller must allocate it (or not

View File

@ -655,6 +655,377 @@ static const struct __vpirt vpip_net_rt = {
0
};
/*
vpiModPath vpiHandle interanl operations :
we have
vpi_get == modpath_get (..) ;
vpi_get_str == modpath_get_str (..) ;
vpi_get_value == modpath_get_value (..) ;
vpi_put_value == modpath_put_value (..) ;
vpi_get_handle == modpath_get_handle (..) ;
vpi_iterate == modpath_iterate (..) ;
vpi_index == modpath_index ( .. ) ;
vpi_free_object == modpath_free_object ( .. ) ;
vpi_get_delay == modpath_get_delay (..) ;
vpi_put_delay == modpath_put_delay (..) ;
*/
static int modpath_get(int code, vpiHandle ref)
{
assert((ref->vpi_type->type_code == vpiModPath));
return 0 ;
}
static char* modpath_get_str(int code, vpiHandle ref)
{
assert((ref->vpi_type->type_code == vpiModPath));
struct __vpiModPath *refp = (struct __vpiModPath *)ref;
char *bn = strdup(vpi_get_str(vpiFullName, &refp->scope->base));
char *nm = (char *)refp->name ;
char *rbuf = need_result_buf(strlen(bn) + strlen(nm) + 2, RBUF_STR);
switch (code)
{
case vpiFullName:
sprintf(rbuf, "%s.%s", bn, nm);
free(bn);
return rbuf;
case vpiName:
strcpy(rbuf, nm);
free(bn);
return rbuf;
}
free(bn);
return 0;
}
static void modpath_get_value(vpiHandle ref, p_vpi_value vp)
{
assert((ref->vpi_type->type_code == vpiModPath));
// struct __vpiModPath* modpath = vpip_modpath_from_handle( ref) ;
// assert ( modpath ) ;
return ;
}
static vpiHandle modpath_put_value(vpiHandle ref, s_vpi_value *vp )
{
assert((ref->vpi_type->type_code == vpiModPath));
// struct __vpiModPath* modpath = vpip_modpath_from_handle( ref) ;
// assert ( modpath ) ;
return 0 ;
}
static vpiHandle modpath_get_handle(int code, vpiHandle ref)
{
assert( (ref->vpi_type->type_code==vpiModPath) );
struct __vpiModPath *rfp = (struct __vpiModPath *)ref ;
switch (code)
{
case vpiScope:
return &rfp->scope->base ;
case vpiModule:
{
struct __vpiScope*scope = rfp->scope;
while (scope && scope->base.vpi_type->type_code != vpiModule)
scope = scope->scope;
assert(scope);
return &scope->base;
}
}
return 0;
}
static vpiHandle modpath_iterate (int code , vpiHandle ref )
{
assert( (ref->vpi_type->type_code == vpiModPath) );
return 0 ;
}
static vpiHandle modpath_index ( vpiHandle ref, int code )
{
assert( (ref->vpi_type->type_code == vpiModPath) );
return 0 ;
}
static int modpath_free_object( vpiHandle ref )
{
assert( (ref->vpi_type->type_code == vpiModPath) );
free ( ref ) ;
return 1 ;
}
/*
This Struct will be used by the make_vpi_modpath ( )
to initializa the vpiModPath vpiHandle type, and assign
method routines
*/
static const struct __vpirt vpip_modpath_rt = {
vpiModPath,
modpath_get,
modpath_get_str,
modpath_get_value,
modpath_put_value,
modpath_get_handle,
modpath_iterate,
modpath_index,
modpath_free_object,
0, // modpath_get_delays,
0 // modpath_put_delays
};
/*
* All the below routines that begin with
* modpath_src_* belong the internal function
* of an vpiModPathIn object. This is used to
* make some specific delays path operations
*
*/
static int modpath_src_get(int code, vpiHandle ref)
{
assert((ref->vpi_type->type_code == vpiModPath));
return 0 ;
}
/*
* This routine will return an modpathIn input port
* name for an modpath vpiHandle object
*
*/
static char* modpath_src_get_str(int code, vpiHandle ref)
{
assert((ref->vpi_type->type_code == vpiModPathIn));
struct __vpiModPathSrc *refp = (struct __vpiModPathSrc *)ref;
char *bn = strdup(vpi_get_str(vpiFullName, &refp->scope->base));
char *nm = (char *)refp->name ;
char *rbuf = need_result_buf(strlen(bn) + strlen(nm) + 2, RBUF_STR);
switch (code)
{
case vpiFullName:
sprintf(rbuf, "%s.%s", bn, nm);
free(bn);
return rbuf;
case vpiName:
strcpy(rbuf, nm);
free(bn);
return rbuf;
}
free(bn);
return 0;
}
static void modpath_src_get_value(vpiHandle ref, p_vpi_value vp)
{
assert((ref->vpi_type->type_code == vpiModPathIn));
struct __vpiModPathSrc* modpathsrc = vpip_modpath_src_from_handle( ref) ;
assert ( modpathsrc ) ;
return ;
}
static vpiHandle modpath_src_put_value(vpiHandle ref, s_vpi_value *vp )
{
assert((ref->vpi_type->type_code == vpiModPathIn));
struct __vpiModPathSrc* modpathsrc = vpip_modpath_src_from_handle( ref) ;
assert ( modpathsrc ) ;
return 0 ;
}
static vpiHandle modpath_src_get_handle(int code, vpiHandle ref)
{
assert( (ref->vpi_type->type_code==vpiModPathIn ) );
struct __vpiModPathSrc *rfp = (struct __vpiModPathSrc *)ref ;
switch (code)
{
case vpiScope:
return &rfp->scope->base ;
case vpiModule:
{
struct __vpiScope*scope = rfp->scope;
while (scope && scope->base.vpi_type->type_code != vpiModule)
scope = scope->scope;
assert(scope);
return &scope->base;
}
}
return 0;
}
static vpiHandle modpath_src_index ( vpiHandle ref, int code )
{
assert( (ref->vpi_type->type_code == vpiModPathIn ) );
return 0 ;
}
static int modpath_src_free_object( vpiHandle ref )
{
assert( (ref->vpi_type->type_code == vpiModPathIn ) );
free ( ref ) ;
return 1 ;
}
/*
* This Routine will put specific demension of delay[] values
* into a vpiHandle. In this case, he will put an
* specific delays values in a vpiModPathIn object
*
*/
static void modpath_src_put_delays ( vpiHandle ref, p_vpi_delay delays )
{
int i ;
assert((ref->vpi_type->type_code == vpiModPathIn));
struct __vpiModPathSrc * src = vpip_modpath_src_from_handle( ref) ;
assert ( src ) ;
vvp_fun_modpath_src *fun = dynamic_cast<vvp_fun_modpath_src*>(src->node->fun);
assert( fun );
for ( i = 0 ; i < delays->no_of_delays ; i++)
{
fun->delay[i] = delays->da[ i ].real ;
}
}
/*
* This Routine will retrive the delay[12] values
* of an vpiHandle. In this case, he will get an
* specific delays values from an vpiModPathIn
* object
*
*/
static void modpath_src_get_delays ( vpiHandle ref, p_vpi_delay delays )
{
int i ;
assert(( ref->vpi_type->type_code == vpiModPathIn ));
struct __vpiModPathSrc * src = vpip_modpath_src_from_handle( ref) ;
assert ( src ) ;
vvp_fun_modpath_src *fun = dynamic_cast<vvp_fun_modpath_src*>(src->node->fun);
assert( fun );
for ( i = 0 ; i < delays->no_of_delays ; i++)
delays->da[ i ].real = fun->delay[i];
}
/*
This Struct will be used by the make_vpi_modpath_src ( )
to initializa the vpiModPathIn vpiHandle type, and assign
method routines
vpiModPathIn vpiHandle interanl operations :
we have
vpi_get == modpath_src_get (..) ;
vpi_get_str == modpath_src_get_str (..) ;
vpi_get_value == modpath_src_get_value (..) ;
vpi_put_value == modpath_src_put_value (..) ;
vpi_get_handle == modpath_src_get_handle (..) ;
vpi_iterate == modpath_src_iterate (..) ;
vpi_index == modpath_src_index ( .. ) ;
vpi_free_object == modpath_src_free_object ( .. ) ;
vpi_get_delay == modpath_src_get_delay (..) ;
vpi_put_delay == modpath_src_put_delay (..) ;
*/
static const struct __vpirt vpip_modpath_src = {
vpiModPathIn,
modpath_src_get,
modpath_src_get_str,
modpath_src_get_value,
modpath_src_put_value,
modpath_src_get_handle,
0, /* modpath_src_iterate,*/
modpath_src_index,
modpath_src_free_object,
modpath_src_get_delays,
modpath_src_put_delays
};
/*
* Construct a vpiIntegerVar object. Indicate the type using a flag
* to minimize the code modifications. Icarus implements integers
@ -722,3 +1093,105 @@ vpiHandle vpip_make_net(const char*name, int msb, int lsb,
return &obj->base;
}
/*
this Routine will safetly convert a modpath vpiHandle
to a struct __vpiModPath { }
*/
struct __vpiModPath* vpip_modpath_from_handle(vpiHandle ref)
{
if (ref->vpi_type->type_code != vpiModPath)
return 0;
return (struct __vpiModPath *) ref;
}
/*
this Routine will safetly convert a modpathsrc vpiHandle
to a struct __vpiModPathSrc { }, This is equivalent ao
vpiModPathIn handle
*/
struct __vpiModPathSrc* vpip_modpath_src_from_handle(vpiHandle ref)
{
if (ref->vpi_type->type_code != vpiModPathIn)
return 0;
return (struct __vpiModPathSrc *) ref;
}
void vpip_add_mopdath_edge ( vpiHandle vpiobj, char *label,
vvp_time64_t use_delay[12] ,
bool posedge , bool negedge )
{
// printf(" In the vpip_add_mopdath_edge( ) \n") ;
}
void vpip_add_modpath_src ( vpiHandle modpath, vpiHandle src )
{
assert( (src->vpi_type->type_code == vpiModPathIn ));
assert( (modpath->vpi_type->type_code == vpiModPath ));
return ;
}
/*
* This function will Construct a vpiModPath Object.
* give a respective "net", and will point to his
* respective functor
*/
vpiHandle vpip_make_modpath ( char *name, char *input, vvp_net_t *net )
{
struct __vpiModPath *obj = (struct __vpiModPath *) calloc (1, sizeof ( struct __vpiModPath ) ) ;
obj->base.vpi_type = &vpip_modpath_rt ;
obj->scope = vpip_peek_current_scope ( );
obj->name = (char *)calloc(strlen(name) + 1 , sizeof ( char )) ;
strcpy ( obj->name, name ) ;
obj->input = (char *)calloc(strlen(input) + 1 , sizeof ( char )) ;
strcpy ( obj->input,input ) ;
obj->input_net = net ;
vpip_attach_to_current_scope (&obj->base) ;
return &obj->base ;
}
/*
* This function will Constructs a vpiModPathIn
* ( struct __vpiModPathSrc ) Object. will give
* a delays[12] values, and point to the specified functor
*
*/
vpiHandle vpip_make_modpath_src ( char *name, vvp_time64_t use_delay[12] , vvp_net_t *net )
{
struct __vpiModPathSrc *obj = (struct __vpiModPathSrc *) calloc (1, sizeof ( struct __vpiModPathSrc ) ) ;
obj->base.vpi_type = &vpip_modpath_src;
obj->scope = vpip_peek_current_scope ( );
obj->name = (char *)calloc(strlen(name) + 1 , sizeof ( char )) ;
strcpy ( obj->name, name ) ;
obj->node = net ;
vpip_attach_to_current_scope (&obj->base) ;
return &obj->base ;
}