From 73e60f4b81fd1567a97e8e5acddbac982496114d Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Tue, 20 Nov 2007 22:20:22 -0800 Subject: [PATCH] Match parsed IOPATH to cell and modpath to be annotated. --- vpi/sdf_lexor.lex | 9 ++++- vpi/sdf_parse.y | 49 ++++++++++++++++-------- vpi/sdf_priv.h | 8 ++++ vpi/sys_sdf.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 146 insertions(+), 16 deletions(-) diff --git a/vpi/sdf_lexor.lex b/vpi/sdf_lexor.lex index 7f75d6ef8..44d0aa94b 100644 --- a/vpi/sdf_lexor.lex +++ b/vpi/sdf_lexor.lex @@ -26,6 +26,7 @@ # include "sdf_parse.h" # include # include +# include static void process_quoted_string(void); static int lookup_keyword(const char*text); @@ -104,9 +105,15 @@ static int lookup_keyword(const char*text) return IDENTIFIER; } +/* + * Create a string witout the leading and trailing quotes. + */ static void process_quoted_string(void) { - yylval.string_val = strdup(yytext); + yylval.string_val = strdup(yytext+1); + char*endp = yylval.string_val+strlen(yylval.string_val); + assert(endp[-1] == '"'); + endp[-1] = 0; } extern int sdfparse(void); diff --git a/vpi/sdf_parse.y b/vpi/sdf_parse.y index 1e8d21d93..3afe61c3e 100644 --- a/vpi/sdf_parse.y +++ b/vpi/sdf_parse.y @@ -23,7 +23,12 @@ extern int sdflex(void); static void yyerror(const char*msg); # include "vpi_user.h" # include "sdf_parse_priv.h" +# include "sdf_priv.h" # include + +/* This is the hierarchy separator to use. */ +static char use_hchar = '.'; + %} %union { @@ -41,6 +46,11 @@ static void yyerror(const char*msg); %token REAL_NUMBER %token INTEGER +%type celltype +%type cell_instance +%type hierarchical_identifier +%type port port_instance port_spec + %% source_file @@ -68,8 +78,7 @@ sdf_header_item sdfversion : '(' K_SDFVERSION QSTRING ')' - { vpi_printf("SDFVERSION: %s\n", $3); - free($3); + { free($3); } ; @@ -106,8 +115,8 @@ program_version : '(' K_VERSION QSTRING ')' ; hierarchy_divider - : '(' K_DIVIDER '.' ')' { vpi_printf("SDF Use . for hierarchy\n"); } - | '(' K_DIVIDER '/' ')' { vpi_printf("SDF Use / for hierarchy\n"); } + : '(' K_DIVIDER '.' ')' { use_hchar = '.'; } + | '(' K_DIVIDER '/' ')' { use_hchar = '/'; } ; voltage @@ -139,22 +148,27 @@ cell_list ; cell - : '(' K_CELL celltype cell_instance timing_spec_list ')' + : '(' K_CELL celltype cell_instance + { sdf_select_instance($3, $4); /* find the instance in the design */} + timing_spec_list + ')' + { free($3); + free($4); } | '(' K_CELL error ')' - { vpi_printf("%s:%d: Syntax error in CELL\n", - sdf_parse_path, @2.first_line); } + { vpi_printf("%s:%d: Syntax error in CELL\n", + sdf_parse_path, @2.first_line); } ; celltype : '(' K_CELLTYPE QSTRING ')' - { vpi_printf("%s:%d: SDF CELL TYPE: %s\n", sdf_parse_path, @1.first_line, $3); - free($3); - } + { $$ = $3; } ; cell_instance : '(' K_INSTANCE hierarchical_identifier ')' + { $$ = $3; } | '(' K_INSTANCE '*' ')' + { $$ = 0; } ; timing_spec_list @@ -189,9 +203,13 @@ del_def_list del_def : '(' K_IOPATH port_spec port_instance delval_list ')' + { sdf_iopath_delays($3, $4); + free($3); + free($4); + } | '(' K_IOPATH error ')' - { vpi_printf("%s:%d: Invalid/malformed IOPATH\n", - sdf_parse_path, @2.first_line); } + { vpi_printf("%s:%d: Invalid/malformed IOPATH\n", + sdf_parse_path, @2.first_line); } ; port_spec @@ -200,12 +218,13 @@ port_spec ; port_instance - : port + : port { $$ = $1; } ; port : hierarchical_identifier - | hierarchical_identifier '[' INTEGER ']' + { $$ = $1; } + /* | hierarchical_identifier '[' INTEGER ']' */ ; delval_list @@ -226,7 +245,7 @@ rvalue hierarchical_identifier : IDENTIFIER - { free($1); } + { $$ = $1; } ; rtriple diff --git a/vpi/sdf_priv.h b/vpi/sdf_priv.h index 82f26fed2..f5707c87c 100644 --- a/vpi/sdf_priv.h +++ b/vpi/sdf_priv.h @@ -28,4 +28,12 @@ */ extern void sdf_process_file(FILE*fd, const char*path); + +/* **** + * These functions are called by the parser to process the SDF file as + * it is parsed. + */ +extern void sdf_select_instance(const char*celltype, const char*inst); +extern void sdf_iopath_delays(const char*src, const char*dst); + #endif diff --git a/vpi/sys_sdf.c b/vpi/sys_sdf.c index 5a4b27e5e..75ae2bbe2 100644 --- a/vpi/sys_sdf.c +++ b/vpi/sys_sdf.c @@ -25,6 +25,99 @@ # include # include +/* + * These are static context + */ + + /* Scope of the $sdf_annotate call. Annotation starts here. */ +static vpiHandle sdf_scope; + /* The cell in process. */ +static vpiHandle sdf_cur_cell; + +/* + * These functions are called by the SDF parser during parsing to + * handling items discovered in the parse. + */ +void sdf_select_instance(const char*celltype, const char*cellinst) +{ + vpiHandle idx = vpi_iterate(vpiModule, sdf_scope); + assert(idx); + + vpiHandle cur; + while ( (cur = vpi_scan(idx)) ) { + + /* If we find the cell in this scope, then save it for + future processing. */ + if ( strcmp(cellinst, vpi_get_str(vpiName,cur)) == 0) { + sdf_cur_cell = cur; + vpi_free_object(idx); + + /* The scope that matches should be a module. */ + if (vpi_get(vpiType,sdf_cur_cell) != vpiModule) { + vpi_printf("SDF ERROR: Scope %s in %s is not a module.\n", + cellinst, vpi_get_str(vpiName,sdf_scope)); + } + /* The matching scope (a module) should have the + expected type. */ + if (strcmp(celltype,vpi_get_str(vpiDefName,sdf_cur_cell)) != 0) { + vpi_printf("SDF ERROR: Module %s in %s is not a %s; " + "it is an %s\n", cellinst, + vpi_get_str(vpiName,sdf_scope), celltype, + vpi_get_str(vpiDefName,sdf_cur_cell)); + } + + return; + } + } + + sdf_cur_cell = 0; + vpi_printf("SDF WARNING: Unable to find %s in current scope\n", cellinst); +} + +void sdf_iopath_delays(const char*src, const char*dst) +{ + assert(sdf_cur_cell); + + vpiHandle idx = vpi_iterate(vpiModPath, sdf_cur_cell); + assert(idx); + + /* Search for the modpath that matches the IOPATH by looking + for the modpath that uses the same ports as the ports that + the parser has found. */ + vpiHandle path; + while ( (path = vpi_scan(idx)) ) { + vpiHandle path_in = vpi_handle(vpiModPathIn,path); + vpiHandle path_out = vpi_handle(vpiModPathOut,path); + + path_in = vpi_handle(vpiExpr,path_in); + path_out = vpi_handle(vpiExpr,path_out); + assert(vpi_get(vpiType,path_in) == vpiNet); + assert(vpi_get(vpiType,path_out) == vpiNet); + + /* If the src name doesn't match, go on. */ + if (strcmp(src,vpi_get_str(vpiName,path_in)) != 0) + continue; + + /* If the dst name doesn't match, go on. */ + if (strcmp(dst,vpi_get_str(vpiName,path_out)) != 0) + continue; + + /* Ah, this must be a match! */ + break; + } + + 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)); + return; + } + + /* No longer need the iterator. */ + vpi_free_object(idx); + + vpi_printf("XXXX Found the modpath object.\n"); +} + static PLI_INT32 sys_sdf_annotate_compiletf(PLI_BYTE8*name) { return 0; @@ -55,6 +148,9 @@ static PLI_INT32 sys_sdf_annotate_calltf(PLI_BYTE8*name) FILE*sdf_fd = fopen(path_str, "r"); assert(sdf_fd); + sdf_scope = vpi_handle(vpiScope,sys); + sdf_cur_cell = 0; + sdf_process_file(sdf_fd, path_str); fclose(sdf_fd);