diff --git a/vpi_user.h b/vpi_user.h index d255f56d4..c7662f853 100644 --- a/vpi_user.h +++ b/vpi_user.h @@ -282,6 +282,7 @@ typedef struct t_vpi_delay { #define vpiNamedFork 35 #define vpiNet 36 #define vpiParameter 41 +#define vpiPathTerm 43 #define vpiRealVar 47 #define vpiReg 48 #define vpiSysFuncCall 56 @@ -331,6 +332,7 @@ typedef struct t_vpi_delay { # define vpiSysFuncTime vpiTimeFunc # define vpiSysFuncSized vpiSizedFunc #define vpiSigned 65 +#define vpiExpr 102 /* IVL private properties */ #define _vpiNexusId 0x1000000 diff --git a/vvp/compile.cc b/vvp/compile.cc index 46765f823..ed3ec4a4d 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -1120,19 +1120,22 @@ void compile_extend_signed(char*label, long wid, struct symb_s arg) input_connect(ptr, 0, arg.text); } -struct __vpiModPath* compile_modpath(char*label, struct symb_s src) +struct __vpiModPath* compile_modpath(char*label, struct symb_s drv, + struct symb_s dest) { vvp_net_t*net = new vvp_net_t; vvp_fun_modpath*obj = new vvp_fun_modpath(net); net->fun = obj; - input_connect(net, 0, src.text); + input_connect(net, 0, drv.text); define_functor_symbol(label, net); - vpiHandle tmp = vpip_make_modpath(label, src.text, net); + vpiHandle tmp = vpip_make_modpath(label, drv.text, net); __vpiModPath*modpath = vpip_modpath_from_handle(tmp); + compile_vpi_lookup(&modpath->path_term_out.expr, dest.text); + modpath->modpath = obj; return modpath; } diff --git a/vvp/compile.h b/vvp/compile.h index 05edb50c4..05b51aff8 100644 --- a/vvp/compile.h +++ b/vvp/compile.h @@ -175,7 +175,9 @@ extern void compile_dff(char*label, struct symb_s arg_a); class __vpiModPath; -extern __vpiModPath* compile_modpath(char*label, struct symb_s src); +extern __vpiModPath* compile_modpath(char*label, + struct symb_s drv, + struct symb_s dest); extern void compile_modpath_src(__vpiModPath*dst, char edge, struct symb_s input, diff --git a/vvp/delay.cc b/vvp/delay.cc index 8642e1208..d89893338 100644 --- a/vvp/delay.cc +++ b/vvp/delay.cc @@ -756,24 +756,24 @@ static vpiHandle modpath_put_value(vpiHandle ref, s_vpi_value *vp ) static vpiHandle modpath_get_handle(int code, vpiHandle ref) { - assert( (ref->vpi_type->type_code==vpiModPath) ); - struct __vpiModPath *rfp = (struct __vpiModPath *)ref ; + struct __vpiModPath *rfp = vpip_modpath_from_handle(ref); + assert(rfp); - 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; - } - } + switch (code) { + case vpiScope: + return vpi_handle(rfp->scope); + + case vpiModule: + { struct __vpiScope*scope = rfp->scope; + while (scope && scope->base.vpi_type->type_code != vpiModule) + scope = scope->scope; + assert(scope); + return vpi_handle(scope); + } + + case vpiModPathOut: + return vpi_handle(&rfp->path_term_out); + } return 0; } @@ -798,6 +798,18 @@ static int modpath_free_object( vpiHandle ref ) return 1 ; } +static vpiHandle pathterm_get_handle(int code, vpiHandle ref) +{ + struct __vpiModPathTerm*obj = vpip_modpath_term_from_handle(ref); + assert(obj); + + switch (code) { + case vpiExpr: + return obj->expr; + default: + return 0; + } +} /* @@ -819,6 +831,26 @@ static const struct __vpirt vpip_modpath_rt = { 0 // modpath_put_delays }; +static const struct __vpirt vpip_modpath_term_rt = { + vpiPathTerm, + 0, // vpi_get + 0, // vpi_get_str + 0, // vpi_get_value, + 0, // vpi_put_value, + pathterm_get_handle, + 0, // vpi_iterate, + 0, // vpi_index, + 0, // vpi_free_object, + 0, // vpi_get_delays, + 0 // vpi_put_delays +}; + +static void initialize_path_term(struct __vpiModPathTerm&obj) +{ + obj.base.vpi_type = &vpip_modpath_term_rt; + obj.expr = 0; +} + /* * This function will Construct a vpiModPath Object. * give a respective "net", and will point to his @@ -829,8 +861,10 @@ 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->base.vpi_type = &vpip_modpath_rt ; + obj->scope = vpip_peek_current_scope ( ); + + initialize_path_term(obj->path_term_out); obj->name = (char *)calloc(strlen(name) + 1 , sizeof ( char )) ; strcpy ( obj->name, name ) ; @@ -858,6 +892,14 @@ struct __vpiModPath* vpip_modpath_from_handle(vpiHandle ref) return (struct __vpiModPath *) ref; } +struct __vpiModPathTerm* vpip_modpath_term_from_handle(vpiHandle ref) +{ + if (ref->vpi_type->type_code != vpiPathTerm) + return 0; + + return (struct __vpiModPathTerm*) ref; +} + /* this Routine will safetly convert a modpathsrc vpiHandle to a struct __vpiModPathSrc { }, This is equivalent ao diff --git a/vvp/parse.y b/vvp/parse.y index 47257808a..022ebc8ae 100644 --- a/vvp/parse.y +++ b/vvp/parse.y @@ -320,17 +320,17 @@ statement node takes two form, one with an array of constants and a single input, and another with an array of inputs. */ - | T_LABEL K_DELAY delay symbol ';' - { compile_delay($1, $3, $4); } - | T_LABEL K_DELAY symbols ';' - { struct symbv_s obj = $3; - compile_delay($1, obj.cnt, obj.vect); - } + | T_LABEL K_DELAY delay symbol ';' + { compile_delay($1, $3, $4); } + | T_LABEL K_DELAY symbols ';' + { struct symbv_s obj = $3; + compile_delay($1, obj.cnt, obj.vect); + } - | T_LABEL K_MODPATH symbol ',' - { modpath_dst = compile_modpath($1, $3); } - modpath_src_list ';' - { modpath_dst = 0; } + | T_LABEL K_MODPATH symbol symbol ',' + { modpath_dst = compile_modpath($1, $3, $4); } + modpath_src_list ';' + { modpath_dst = 0; } /* DFF nodes have an output and take exactly 4 inputs. */ diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index 4ff520eaa..1dcb7f8e1 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -253,6 +253,11 @@ struct __vpiModPathSrc { } ; +struct __vpiModPathTerm { + struct __vpiHandle base; + vpiHandle expr; +}; + /* * * The vpiMoaPath vpiHandle will define @@ -267,6 +272,8 @@ struct __vpiModPath { class vvp_fun_modpath*modpath; + struct __vpiModPathTerm path_term_out; + /* * The name, input must be removed * in future um ModPathSrc have no @@ -289,6 +296,7 @@ struct __vpiModPath { }; extern struct __vpiModPath* vpip_modpath_from_handle(vpiHandle ref); +extern struct __vpiModPathTerm* vpip_modpath_term_from_handle(vpiHandle ref); extern struct __vpiModPathSrc* vpip_modpath_src_from_handle(vpiHandle ref);