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.
This commit is contained in:
Stephen Williams 2007-12-13 20:42:06 -08:00
parent 8d9998c44e
commit a14d836be3
9 changed files with 90 additions and 46 deletions

View File

@ -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 },

View File

@ -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 <string_val> celltype
%type <string_val> cell_instance
%type <string_val> hierarchical_identifier
%type <string_val> port port_instance port_spec
%type <string_val> port port_instance
%type <real_val> rvalue rtriple signed_real_number
%type <real_val> delval
%type <int_val> edge_identifier
%type <port_with_edge> port_edge port_spec
%type <delval_list> 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;

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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") ;
}

View File

@ -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