diff --git a/vpi/sdf_lexor.lex b/vpi/sdf_lexor.lex index fe11a8343..f373534f1 100644 --- a/vpi/sdf_lexor.lex +++ b/vpi/sdf_lexor.lex @@ -104,6 +104,8 @@ static struct { { "INTERCONNECT",K_INTERCONNECT }, { "INSTANCE", K_INSTANCE }, { "IOPATH", K_IOPATH }, + { "NEGEDGE", K_NEGEDGE }, + { "POSEDGE", K_POSEDGE }, { "PROCESS", K_PROCESS }, { "PROGRAM", K_PROGRAM }, { "RECOVERY", K_RECOVERY }, diff --git a/vpi/sdf_parse.y b/vpi/sdf_parse.y index 58dc93789..69d57300d 100644 --- a/vpi/sdf_parse.y +++ b/vpi/sdf_parse.y @@ -38,12 +38,13 @@ char sdf_use_hchar = '.'; double real_val; char* string_val; + struct port_with_edge_s port_with_edge; struct sdf_delval_list_s delval_list; }; %token K_ABSOLUTE K_CELL K_CELLTYPE K_DATE K_DELAYFILE K_DELAY K_DESIGN %token K_DIVIDER K_HOLD K_INCREMENT K_INSTANCE K_INTERCONNECT K_IOPATH -%token K_PROCESS K_PROGRAM K_RECOVERY K_REMOVAL +%token K_NEGEDGE K_POSEDGE K_PROCESS K_PROGRAM K_RECOVERY K_REMOVAL %token K_SDFVERSION K_SETUP K_SETUPHOLD K_TEMPERATURE K_TIMESCALE %token K_TIMINGCHECK K_VENDOR K_VERSION K_VOLTAGE K_WIDTH @@ -55,11 +56,14 @@ char sdf_use_hchar = '.'; %type celltype %type cell_instance %type hierarchical_identifier -%type port port_instance port_spec +%type port port_instance %type rvalue rtriple signed_real_number %type delval +%type edge_identifier +%type port_edge port_spec + %type delval_list %% @@ -241,8 +245,8 @@ del_def_list del_def : '(' K_IOPATH port_spec port_instance delval_list ')' - { sdf_iopath_delays($3, $4, &$5); - free($3); + { sdf_iopath_delays($3.vpi_edge, $3.string_val, $4, &$5); + free($3.string_val); free($4); } | '(' K_IOPATH error ')' @@ -281,8 +285,8 @@ port_tchk ; port_spec - : port_instance - /* | port_edge */ + : port_instance { $$.vpi_edge = vpiNoEdge; $$.string_val = $1; } + | port_edge { $$ = $1; } ; port_instance @@ -295,6 +299,16 @@ port /* | hierarchical_identifier '[' INTEGER ']' */ ; +port_edge + : '(' edge_identifier port_instance ')' + { $$.vpi_edge = $2; $$.string_val = $3; } + ; + +edge_identifier + : K_POSEDGE { $$ = vpiPosedge; } + | K_NEGEDGE { $$ = vpiNegedge; } + ; + delval_list : delval_list delval { int idx; diff --git a/vpi/sdf_parse_priv.h b/vpi/sdf_parse_priv.h index 7f745cecc..8957473e2 100644 --- a/vpi/sdf_parse_priv.h +++ b/vpi/sdf_parse_priv.h @@ -24,6 +24,11 @@ * used to share declarations between the parse and the lexor. */ +struct port_with_edge_s { + int vpi_edge; + char*string_val; +}; + /* Path to source for error messages. */ extern const char*sdf_parse_path; diff --git a/vpi/sdf_priv.h b/vpi/sdf_priv.h index d76e5626b..a71d76958 100644 --- a/vpi/sdf_priv.h +++ b/vpi/sdf_priv.h @@ -42,7 +42,7 @@ struct sdf_delval_list_s { }; extern void sdf_select_instance(const char*celltype, const char*inst); -extern void sdf_iopath_delays(const char*src, const char*dst, +extern void sdf_iopath_delays(int vpi_edge, const char*src, const char*dst, const struct sdf_delval_list_s*delval); #endif diff --git a/vpi/sys_sdf.c b/vpi/sys_sdf.c index 1188e412e..a8a47f7c8 100644 --- a/vpi/sys_sdf.c +++ b/vpi/sys_sdf.c @@ -113,7 +113,18 @@ void sdf_select_instance(const char*celltype, const char*cellinst) } -void sdf_iopath_delays(const char*src, const char*dst, +static const char*edge_str(int vpi_edge) +{ + if (vpi_edge == vpiNoEdge) + return ""; + if (vpi_edge == vpiPosedge) + return "posedge "; + if (vpi_edge == vpiNegedge) + return "negedge "; + return "edge.. "; +} + +void sdf_iopath_delays(int vpi_edge, const char*src, const char*dst, const struct sdf_delval_list_s*delval_list) { if (sdf_cur_cell == 0) @@ -127,17 +138,24 @@ void sdf_iopath_delays(const char*src, const char*dst, the parser has found. */ vpiHandle path; while ( (path = vpi_scan(iter)) ) { - vpiHandle path_in = vpi_handle(vpiModPathIn,path); - vpiHandle path_out = vpi_handle(vpiModPathOut,path); + vpiHandle path_t_in = vpi_handle(vpiModPathIn,path); + vpiHandle path_t_out = vpi_handle(vpiModPathOut,path); - path_in = vpi_handle(vpiExpr,path_in); - path_out = vpi_handle(vpiExpr,path_out); + vpiHandle path_in = vpi_handle(vpiExpr,path_t_in); + vpiHandle path_out = vpi_handle(vpiExpr,path_t_out); + + /* The expressions for the path terms must be signals, + vpiNet or vpiReg. */ assert(vpi_get(vpiType,path_in) == vpiNet); - assert(vpi_get(vpiType,path_out) == vpiNet); + assert(vpi_get(vpiType,path_out) == vpiNet + || vpi_get(vpiType,path_out) == vpiReg); /* If the src name doesn't match, go on. */ if (strcmp(src,vpi_get_str(vpiName,path_in)) != 0) continue; + /* The edge type must match too. */ + if (vpi_get(vpiEdge,path_t_in) != vpi_edge) + continue; /* If the dst name doesn't match, go on. */ if (strcmp(dst,vpi_get_str(vpiName,path_out)) != 0) @@ -148,8 +166,8 @@ void sdf_iopath_delays(const char*src, const char*dst, } if (path == 0) { - vpi_printf("SDF ERROR: Unable to find ModPath %s -> %s in %s\n", - src, dst, vpi_get_str(vpiName,sdf_cur_cell)); + vpi_printf("SDF ERROR: Unable to find ModPath %s%s -> %s in %s\n", + edge_str(vpi_edge), src, dst, vpi_get_str(vpiName,sdf_cur_cell)); return; } diff --git a/vpi_user.h b/vpi_user.h index b9bc65997..e1c0d4952 100644 --- a/vpi_user.h +++ b/vpi_user.h @@ -316,6 +316,17 @@ typedef struct t_vpi_delay { #define vpiNetType 22 # define vpiWire 1 #define vpiArray 28 +#define vpiEdge 36 +# define vpiNoEdge 0x00 /* No edge */ +# define vpiEdge01 0x01 /* 0 --> 1 */ +# define vpiEdge10 0x02 /* 1 --> 0 */ +# define vpiEdge0x 0x04 /* 0 --> x */ +# define vpiEdgex1 0x08 /* x --> 1 */ +# define vpiEdge1x 0x10 /* 1 --> x */ +# define vpiEdgex0 0x20 /* x --> 0 */ +# define vpiPosedge (vpiEdgex1|vpiEdge01|vpiEdge0x) +# define vpiNegedge (vpiEdgex0|vpiEdge10|vpiEdge1x) +# define vpiAnyEdge (vpiPosedge|vpiNegedge) #define vpiConstType 40 # define vpiDecConst 1 # define vpiRealConst 2 diff --git a/vvp/compile.cc b/vvp/compile.cc index e0435e6cf..92ca96b2f 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -1160,6 +1160,7 @@ static struct __vpiModPathSrc*make_modpath_src(struct __vpiModPath*path, vvp_fun_modpath_src*obj = 0; + int vpi_edge = vpiNoEdge; if (edge == 0) { obj = new vvp_fun_modpath_src(use_delay); @@ -1167,17 +1168,21 @@ static struct __vpiModPathSrc*make_modpath_src(struct __vpiModPath*path, bool posedge, negedge; switch (edge) { case '+': + vpi_edge = vpiPosedge; posedge = true; negedge = false; break; case '-': + vpi_edge = vpiNegedge; posedge = false; negedge = true; break; +#if 0 case '*': posedge = true; - negedge = false; + negedge = true; break; +#endif default: fprintf(stderr, "Unknown edge identifier %c(%d).\n", edge, edge); @@ -1187,16 +1192,12 @@ static struct __vpiModPathSrc*make_modpath_src(struct __vpiModPath*path, } 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 ) ; struct __vpiModPathSrc* srcobj = vpip_make_modpath_src (path, use_delay, net) ; vpip_attach_to_current_scope(vpi_handle(srcobj)); - net->fun = obj; + + /* Save the vpiEdge directory into the input path term. */ + srcobj->path_term_in.edge = vpi_edge; input_connect(net, 0, src.text); dst->add_modpath_src(obj); diff --git a/vvp/delay.cc b/vvp/delay.cc index 4497f8901..151da558b 100644 --- a/vvp/delay.cc +++ b/vvp/delay.cc @@ -666,6 +666,18 @@ static void modpath_src_get_delays ( vpiHandle ref, p_vpi_delay delays ) } } +static int pathterm_get(int code, vpiHandle ref) +{ + struct __vpiModPathTerm*obj = vpip_modpath_term_from_handle(ref); + assert(obj); + + switch (code) { + case vpiEdge: + return obj->edge; + default: + return 0; + } +} static vpiHandle pathterm_get_handle(int code, vpiHandle ref) { @@ -701,7 +713,7 @@ static const struct __vpirt vpip_modpath_src_rt = { static const struct __vpirt vpip_modpath_term_rt = { vpiPathTerm, - 0, // vpi_get + pathterm_get, 0, // vpi_get_str 0, // vpi_get_value, 0, // vpi_put_value, @@ -717,6 +729,7 @@ static void initialize_path_term(struct __vpiModPathTerm&obj) { obj.base.vpi_type = &vpip_modpath_term_rt; obj.expr = 0; + obj.edge = vpiNoEdge; } /* @@ -783,15 +796,3 @@ struct __vpiModPathSrc* vpip_modpath_src_from_handle(vpiHandle ref) 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") ; - - -} diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index c47751bbf..864ec243c 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -223,6 +223,8 @@ extern __vpiSignal* vpip_signal_from_handle(vpiHandle obj); struct __vpiModPathTerm { struct __vpiHandle base; vpiHandle expr; + /* The value returned by vpi_get(vpiEdge, ...); */ + int edge; }; struct __vpiModPathSrc { @@ -272,16 +274,6 @@ extern struct __vpiModPathSrc* vpip_make_modpath_src (struct __vpiModPath*path_ extern struct __vpiModPath* vpip_make_modpath(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 ) ; - /* * These methods support the vpi creation of events. The name string