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:
parent
8fe3cc5318
commit
9d39b3a514
132
vpi_user.h
132
vpi_user.h
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
10
vvp/delay.cc
10
vvp/delay.cc
|
|
@ -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;
|
||||
|
|
|
|||
10
vvp/delay.h
10
vvp/delay.h
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
118
vvp/vpi_priv.h
118
vvp/vpi_priv.h
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 ;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue