Clean up modpath vpi interface

Clean up rather poorly written modpath vpi support, fixing the
parse of the modpath syntax element to not use pointless globals.
Collect the modpath code into the delay.cc file instead of the
inapropriate vpi_signal.cc source file.

Signed-off-by: Stephen Williams <steve@icarus.com>
This commit is contained in:
Stephen Williams 2007-10-30 20:14:40 -07:00
parent 54aae2c1c2
commit 148e6768f6
6 changed files with 436 additions and 600 deletions

View File

@ -47,21 +47,6 @@
unsigned compile_errors = 0; 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 * The opcode table lists all the code mnemonics, along with their
* opcode and operand types. The table is written sorted by mnemonic * opcode and operand types. The table is written sorted by mnemonic
@ -1135,7 +1120,7 @@ void compile_extend_signed(char*label, long wid, struct symb_s arg)
input_connect(ptr, 0, arg.text); input_connect(ptr, 0, arg.text);
} }
vvp_fun_modpath* compile_modpath(char*label, struct symb_s src) struct __vpiModPath* compile_modpath(char*label, struct symb_s src)
{ {
vvp_net_t*net = new vvp_net_t; vvp_net_t*net = new vvp_net_t;
vvp_fun_modpath*obj = new vvp_fun_modpath(net); vvp_fun_modpath*obj = new vvp_fun_modpath(net);
@ -1145,34 +1130,19 @@ vvp_fun_modpath* compile_modpath(char*label, struct symb_s src)
define_functor_symbol(label, net); define_functor_symbol(label, net);
actual_modpath_input_net = net ; vpiHandle tmp = vpip_make_modpath(label, src.text, net);
// Make the vpiHandle for the vpiModPath __vpiModPath*modpath = vpip_modpath_from_handle(tmp);
actual_modpath_input=(char *)calloc(strlen(src.text)+1,sizeof(char)) ; modpath->modpath = obj;
return modpath;
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;
} }
static vvp_net_t*make_modpath_src(vvp_fun_modpath*dst, char edge, static vvp_net_t*make_modpath_src(struct __vpiModPath*path, char edge,
struct symb_s src, struct numbv_s vals) struct symb_s src, struct numbv_s vals)
{ {
vvp_time64_t use_delay[12]; vvp_fun_modpath*dst = path->modpath;
vvp_time64_t use_delay[12];
assert(vals.cnt == 12); assert(vals.cnt == 12);
for (unsigned idx = 0 ; idx < vals.cnt ; idx += 1) { for (unsigned idx = 0 ; idx < vals.cnt ; idx += 1) {
use_delay[idx] = vals.nvec[idx]; use_delay[idx] = vals.nvec[idx];
@ -1181,31 +1151,6 @@ static vvp_net_t*make_modpath_src(vvp_fun_modpath*dst, char edge,
numbv_clear(&vals); numbv_clear(&vals);
vvp_fun_modpath_src*obj = 0; 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) { if (edge == 0) {
obj = new vvp_fun_modpath_src(use_delay); obj = new vvp_fun_modpath_src(use_delay);
@ -1240,9 +1185,8 @@ static vvp_net_t*make_modpath_src(vvp_fun_modpath*dst, char edge,
Compiling the delays values into actual modpath vpiHandle Compiling the delays values into actual modpath vpiHandle
*/ */
//vpip_add_mopdath_delay ( vpiobj, src.text, use_delay ) ; //vpip_add_mopdath_delay ( vpiobj, src.text, use_delay ) ;
srcobj = vpip_make_modpath_src ( src.text, use_delay, net ) ; vpiHandle srcobj = vpip_make_modpath_src ( src.text, use_delay, net ) ;
vpip_add_modpath_src ( vpiobj, srcobj ) ; vpip_add_modpath_src (vpi_handle(path), srcobj);
net->fun = obj; net->fun = obj;
input_connect(net, 0, src.text); input_connect(net, 0, src.text);
@ -1251,13 +1195,13 @@ static vvp_net_t*make_modpath_src(vvp_fun_modpath*dst, char edge,
return net; return net;
} }
void compile_modpath_src(vvp_fun_modpath*dst, char edge, void compile_modpath_src(struct __vpiModPath*dst, char edge,
struct symb_s src, struct numbv_s vals) struct symb_s src, struct numbv_s vals)
{ {
make_modpath_src(dst, edge, src, vals); make_modpath_src(dst, edge, src, vals);
} }
void compile_modpath_src(vvp_fun_modpath*dst, char edge, void compile_modpath_src(struct __vpiModPath*dst, char edge,
struct symb_s src, struct symb_s src,
struct numbv_s vals, struct numbv_s vals,
struct symb_s condit_src) struct symb_s condit_src)

View File

@ -174,13 +174,13 @@ extern void compile_dff(char*label,
struct symb_s arg_e, struct symb_s arg_e,
struct symb_s arg_a); struct symb_s arg_a);
class vvp_fun_modpath; class __vpiModPath;
extern vvp_fun_modpath* compile_modpath(char*label, struct symb_s src); extern __vpiModPath* compile_modpath(char*label, struct symb_s src);
extern void compile_modpath_src(vvp_fun_modpath*dst, extern void compile_modpath_src(__vpiModPath*dst,
char edge, char edge,
struct symb_s input, struct symb_s input,
struct numbv_s d); struct numbv_s d);
extern void compile_modpath_src(vvp_fun_modpath*dst, extern void compile_modpath_src(__vpiModPath*dst,
char edge, char edge,
struct symb_s input, struct symb_s input,
struct numbv_s d, struct numbv_s d,

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005 Stephen Williams <steve@icarus.com> * Copyright (c) 2005-2007 Stephen Williams <steve@icarus.com>
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -16,12 +16,10 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: delay.cc,v 1.19 2007/03/04 06:26:58 steve Exp $"
#endif
#include "delay.h" #include "delay.h"
#include "schedule.h" #include "schedule.h"
#include "vpi_priv.h"
#include <iostream> #include <iostream>
#include <assert.h> #include <assert.h>
@ -489,56 +487,409 @@ bool vvp_fun_modpath_edge::test_vec4(const vvp_vector4_t&bit)
return false; return false;
} }
/* /*
* $Log: delay.cc,v $ * All the below routines that begin with
* Revision 1.19 2007/03/04 06:26:58 steve * modpath_src_* belong the internal function
* Assert that modpath finds a delay. * of an vpiModPathIn object. This is used to
* * make some specific delays path operations
* Revision 1.18 2007/03/02 06:13:22 steve
* Add support for edge sensitive spec paths.
*
* Revision 1.17 2007/03/01 06:19:39 steve
* Add support for conditional specify delay paths.
*
* Revision 1.16 2007/01/26 05:15:41 steve
* More literal implementation of inertial delay model.
*
* Revision 1.15 2006/09/29 03:57:01 steve
* Modpath delay chooses correct delay for edge.
*
* Revision 1.14 2006/09/23 04:57:19 steve
* Basic support for specify timing.
*
* Revision 1.13 2006/07/08 21:48:00 steve
* Delay object supports real valued delays.
*
* Revision 1.12 2006/01/02 05:32:07 steve
* Require explicit delay node from source.
*
* Revision 1.11 2005/11/10 13:27:16 steve
* Handle very wide % and / operations using expanded vector2 support.
*
* Revision 1.10 2005/09/20 18:34:02 steve
* Clean up compiler warnings.
*
* Revision 1.9 2005/07/06 04:29:25 steve
* Implement real valued signals and arith nodes.
*
* Revision 1.8 2005/06/22 00:04:49 steve
* Reduce vvp_vector4 copies by using const references.
*
* Revision 1.7 2005/06/09 05:04:45 steve
* Support UDP initial values.
*
* Revision 1.6 2005/06/02 16:02:11 steve
* Add support for notif0/1 gates.
* Make delay nodes support inertial delay.
* Add the %force/link instruction.
*
* Revision 1.5 2005/05/14 19:43:23 steve
* Move functor delays to vvp_delay_fun object.
*
* Revision 1.4 2005/04/03 05:45:51 steve
* Rework the vvp_delay_t class.
* *
*/ */
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
};
/*
* 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 ;
}
/*
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
};
/*
* 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 ) ;
fprintf(stderr, "XXXX: Add vpiModpath...\n");
obj->input_net = net ;
vpip_attach_to_current_scope (&obj->base) ;
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 ;
}

View File

@ -42,7 +42,7 @@ extern FILE*yyin;
* When parsing a modpath list, this is the processed destination that * When parsing a modpath list, this is the processed destination that
* the source items will attach themselves to. * the source items will attach themselves to.
*/ */
static vvp_fun_modpath*modpath_dst = 0; static struct __vpiModPath*modpath_dst = 0;
%} %}
%union { %union {

View File

@ -101,6 +101,14 @@ struct __vpirt {
void (*vpi_put_delays_)(vpiHandle, p_vpi_delay); void (*vpi_put_delays_)(vpiHandle, p_vpi_delay);
}; };
/*
* In general a vpi object is a structure that contains the member
* "base" that is a __vpiHandle object. This template can convert any
* of those structures into a vpiHandle object.
*/
template <class T> struct __vpiHandle*vpi_handle(T obj)
{ return &obj->base; }
/* /*
* The vpiHandle for an iterator has this structure. The definition of * The vpiHandle for an iterator has this structure. The definition of
* the methods lives in vpi_iter.c * the methods lives in vpi_iter.c
@ -257,6 +265,8 @@ struct __vpiModPath {
struct __vpiHandle base ; struct __vpiHandle base ;
struct __vpiScope *scope ; struct __vpiScope *scope ;
class vvp_fun_modpath*modpath;
/* /*
* The name, input must be removed * The name, input must be removed
* in future um ModPathSrc have no * in future um ModPathSrc have no
@ -278,6 +288,8 @@ struct __vpiModPath {
unsigned int src_no ; unsigned int src_no ;
}; };
extern struct __vpiModPath* vpip_modpath_from_handle(vpiHandle ref);
extern struct __vpiModPathSrc* vpip_modpath_src_from_handle(vpiHandle ref);
/* /*

View File

@ -656,376 +656,6 @@ static const struct __vpirt vpip_net_rt = {
}; };
/*
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 * Construct a vpiIntegerVar object. Indicate the type using a flag
* to minimize the code modifications. Icarus implements integers * to minimize the code modifications. Icarus implements integers
@ -1094,104 +724,3 @@ vpiHandle vpip_make_net(const char*name, int msb, int lsb,
return &obj->base; 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 ;
}