From a14d836be3134cf612a8423ac6059ef1aca78a83 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Thu, 13 Dec 2007 20:42:06 -0800 Subject: [PATCH] Support annotation of edge paths Parse SDF file annotations of edge sensitive delay paths. Add vpi support for getting the specified edge sensitivity of an edge sensitive path, and annotate paths with proper attention to the edge that is specified for the path. --- vpi/sdf_lexor.lex | 2 ++ vpi/sdf_parse.y | 26 ++++++++++++++++++++------ vpi/sdf_parse_priv.h | 5 +++++ vpi/sdf_priv.h | 2 +- vpi/sys_sdf.c | 34 ++++++++++++++++++++++++++-------- vpi_user.h | 11 +++++++++++ vvp/compile.cc | 17 +++++++++-------- vvp/delay.cc | 27 ++++++++++++++------------- vvp/vpi_priv.h | 12 ++---------- 9 files changed, 90 insertions(+), 46 deletions(-) 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