From c5950e3aa684837afdc55e7b1c45a0eb56516a74 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sun, 18 Nov 2007 17:36:03 -0800 Subject: [PATCH] Add stub $sdf_annotate function. Add the $sdf_annotate function infrastructure, and a stub parser that can parse miniman SDF files. Signed-off-by: Stephen Williams --- vpi/Makefile.in | 13 ++- vpi/configure.in | 8 ++ vpi/sdf_lexor.lex | 120 +++++++++++++++++++++ vpi/sdf_parse.y | 247 +++++++++++++++++++++++++++++++++++++++++++ vpi/sdf_parse_priv.h | 30 ++++++ vpi/sdf_priv.h | 31 ++++++ vpi/sys_sdf.c | 76 +++++++++++++ vpi/sys_table.c | 2 + 8 files changed, 525 insertions(+), 2 deletions(-) create mode 100644 vpi/sdf_lexor.lex create mode 100644 vpi/sdf_parse.y create mode 100644 vpi/sdf_parse_priv.h create mode 100644 vpi/sdf_priv.h create mode 100644 vpi/sys_sdf.c diff --git a/vpi/Makefile.in b/vpi/Makefile.in index 7f8c2c696..730b64fe4 100644 --- a/vpi/Makefile.in +++ b/vpi/Makefile.in @@ -39,6 +39,8 @@ CC = @CC@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ +LEX = @LEX@ +YACC = @YACC@ CPPFLAGS = @ident_support@ -I. -I$(srcdir)/.. -I$(srcdir) -I.. @file64_support@ @CPPFLAGS@ @DEFS@ @PICFLAG@ CFLAGS = -Wall @CFLAGS@ @@ -62,8 +64,9 @@ dep: O = sys_table.o sys_convert.o sys_deposit.o sys_display.o sys_fileio.o \ sys_finish.o sys_plusargs.o sys_random.o sys_random_mti.o \ -sys_readmem.o sys_readmem_lex.o sys_scanf.o \ -sys_time.o sys_vcd.o sys_vcdoff.o vcd_priv.o mt19937int.o priv.o stringheap.o +sys_readmem.o sys_readmem_lex.o sys_scanf.o sys_sdf.o \ +sys_time.o sys_vcd.o sys_vcdoff.o vcd_priv.o \ +mt19937int.o priv.o sdf_lexor.o sdf_parse.o stringheap.o ifeq (@HAVE_LIBZ@,yes) ifeq (@HAVE_LIBBZ2@,yes) @@ -84,6 +87,12 @@ system.vpi: $O ../vvp/libvpi.a sys_readmem_lex.c: sys_readmem_lex.lex flex -t -Preadmem $(srcdir)/sys_readmem_lex.lex > sys_readmem_lex.c +sdf_lexor.c: sdf_lexor.lex + flex -t -Psdf $(srcdir)/sdf_lexor.lex > sdf_lexor.c + +sdf_parse.c sdf_parse.h: $(srcdir)/sdf_parse.y + $(YACC) --verbose -d -p sdf -o sdf_parse.c $(srcdir)/sdf_parse.y + ifeq (@enable_vvp32@,yes) all32: bin32 bin32/system.vpi diff --git a/vpi/configure.in b/vpi/configure.in index 172378351..e4e98738c 100644 --- a/vpi/configure.in +++ b/vpi/configure.in @@ -15,6 +15,14 @@ then exit 1 fi +AC_CHECK_PROGS(YACC,bison,none) +if test "$YACC" = "none" +then + echo "*** Error: No suitable bison found. ***" + echo " Please install the 'bison' package." + exit 1 +fi + AC_EXEEXT AC_SUBST(EXEEXT) diff --git a/vpi/sdf_lexor.lex b/vpi/sdf_lexor.lex new file mode 100644 index 000000000..7f75d6ef8 --- /dev/null +++ b/vpi/sdf_lexor.lex @@ -0,0 +1,120 @@ + +%option never-interactive + +%{ +/* + * Copyright (c) 2007 Stephen Williams (steve@icarus.com) + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form under the terms of the GNU + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +# include "sdf_priv.h" +# include "sdf_parse_priv.h" +# include "sdf_parse.h" +# include +# include + +static void process_quoted_string(void); +static int lookup_keyword(const char*text); +const char*sdf_parse_path = 0; + +static int yywrap(void) +{ + return 1; +} + + +# define yylval sdflval +%} + +%% + +[ \m\t] { /* Skip white space. */; } + + /* Count lines so that the parser can assign line numbers. */ +\n { sdflloc.first_line += 1; } + + /* Real values */ +[0-9]+(\.[0-9]+)?([Ee][+-]?[0-9]+)? { + yylval.real_val = strtod(yytext, 0); + return REAL_NUMBER; +} + +[a-zA-Z]+ { + return lookup_keyword(yytext); +} + +\"[^\"]*\" { + process_quoted_string(); + return QSTRING; +} + +. { return yytext[0]; } + +%% + +static struct { + const char*name; + int code; +} keywords[] = { + { "ABSOLUTE", K_ABSOLUTE }, + { "CELL", K_CELL }, + { "CELLTYPE", K_CELLTYPE }, + { "DATE", K_DATE }, + { "DELAY", K_DELAY }, + { "DELAYFILE", K_DELAYFILE }, + { "DESIGN", K_DESIGN }, + { "DIVIDER", K_DIVIDER }, + { "INCREMENT", K_INCREMENT }, + { "INSTANCE", K_INSTANCE }, + { "IOPATH", K_IOPATH }, + { "PROCESS", K_PROCESS }, + { "PROGRAM", K_PROGRAM }, + { "SDFVERSION", K_SDFVERSION }, + { "TEMPERATURE",K_TEMPERATURE }, + { "TIMESCALE", K_TIMESCALE }, + { "VENDOR", K_VENDOR }, + { "VERSION", K_VERSION }, + { "VOLTAGE", K_VOLTAGE }, + { 0, IDENTIFIER } +}; + +static int lookup_keyword(const char*text) +{ + int idx; + for (idx = 0 ; keywords[idx].name ; idx += 1) { + if (strcasecmp(text, keywords[idx].name) == 0) + return keywords[idx].code; + } + + yylval.string_val = strdup(yytext); + return IDENTIFIER; +} + +static void process_quoted_string(void) +{ + yylval.string_val = strdup(yytext); +} + +extern int sdfparse(void); +void sdf_process_file(FILE*fd, const char*path) +{ + yyrestart(fd); + + sdf_parse_path = path; + sdfparse(); + sdf_parse_path = 0; +} diff --git a/vpi/sdf_parse.y b/vpi/sdf_parse.y new file mode 100644 index 000000000..1e8d21d93 --- /dev/null +++ b/vpi/sdf_parse.y @@ -0,0 +1,247 @@ + +%{ +/* + * Copyright (c) 1998-2007 Stephen Williams (steve@icarus.com) + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form under the terms of the GNU + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +extern int sdflex(void); +static void yyerror(const char*msg); +# include "vpi_user.h" +# include "sdf_parse_priv.h" +# include +%} + +%union { + unsigned long int_val; + double real_val; + char* string_val; +}; + +%token K_ABSOLUTE K_CELL K_CELLTYPE K_DATE K_DELAYFILE K_DELAY K_DESIGN +%token K_DIVIDER K_INCREMENT K_INSTANCE K_IOPATH +%token K_PROCESS K_PROGRAM K_SDFVERSION K_TEMPERATURE K_TIMESCALE +%token K_VENDOR K_VERSION K_VOLTAGE + +%token QSTRING IDENTIFIER +%token REAL_NUMBER +%token INTEGER + +%% + +source_file + : '(' K_DELAYFILE sdf_header_list cell_list ')' + ; + +sdf_header_list + : sdf_header_list sdf_header_item + | sdf_header_item + ; + +sdf_header_item + : sdfversion + | design_name + | date + | vendor + | program_name + | program_version + | hierarchy_divider + | voltage + | process + | temperature + | time_scale + ; + +sdfversion + : '(' K_SDFVERSION QSTRING ')' + { vpi_printf("SDFVERSION: %s\n", $3); + free($3); + } + ; + +design_name + : '(' K_DESIGN QSTRING ')' + { vpi_printf("SDF Design: %s\n", $3); + free($3); + } + ; + +date + : '(' K_DATE QSTRING ')' + { vpi_printf("SDF Date: %s\n", $3); + free($3); + } + ; + +vendor : '(' K_VENDOR QSTRING ')' + { vpi_printf("SDF Vendor: %s\n", $3); + free($3); + } +; + +program_name : '(' K_PROGRAM QSTRING ')' + { vpi_printf("SDF Program: %s\n", $3); + free($3); + } +; + +program_version : '(' K_VERSION QSTRING ')' + { vpi_printf("SDF Program Version: %s\n", $3); + free($3); + } +; + +hierarchy_divider + : '(' K_DIVIDER '.' ')' { vpi_printf("SDF Use . for hierarchy\n"); } + | '(' K_DIVIDER '/' ')' { vpi_printf("SDF Use / for hierarchy\n"); } + ; + +voltage + : '(' K_VOLTAGE rtriple ')' + | '(' K_VOLTAGE signed_real_number ')' + ; + +process : '(' K_PROCESS QSTRING ')' + { vpi_printf("SDF Process: %s\n", $3); + free($3); + } +; + +temperature + : '(' K_TEMPERATURE rtriple ')' + | '(' K_TEMPERATURE signed_real_number ')' + ; + +time_scale + : '(' K_TIMESCALE REAL_NUMBER IDENTIFIER ')' + { vpi_printf("SDF TIMESCALE : %f%s\n", $3, $4); + free($4); + } + ; + +cell_list + : cell_list cell + | cell + ; + +cell + : '(' K_CELL celltype cell_instance timing_spec_list ')' + | '(' K_CELL error ')' + { 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); + } + ; + +cell_instance + : '(' K_INSTANCE hierarchical_identifier ')' + | '(' K_INSTANCE '*' ')' + ; + +timing_spec_list + : timing_spec_list timing_spec + | timing_spec + ; + +timing_spec + : '(' K_DELAY deltype_list ')' + | '(' K_DELAY error ')' + { vpi_printf("%s:%d: Syntax error in CELL DELAY SPEC\n", + sdf_parse_path, @2.first_line); } + ; + +deltype_list + : deltype_list deltype + | deltype + ; + +deltype + : '(' K_ABSOLUTE del_def_list ')' + | '(' K_INCREMENT del_def_list ')' + | '(' error ')' + { vpi_printf("%s:%d: Invalid/malformed delay type\n", + sdf_parse_path, @1.first_line); } + ; + +del_def_list + : del_def_list del_def + | del_def + ; + +del_def + : '(' K_IOPATH port_spec port_instance delval_list ')' + | '(' K_IOPATH error ')' + { vpi_printf("%s:%d: Invalid/malformed IOPATH\n", + sdf_parse_path, @2.first_line); } + ; + +port_spec + : port_instance + /* | port_edge */ + ; + +port_instance + : port + ; + +port + : hierarchical_identifier + | hierarchical_identifier '[' INTEGER ']' + ; + +delval_list + : delval_list delval + | delval + ; + +delval + : rvalue + | '(' rvalue rvalue ')' + | '(' rvalue rvalue rvalue ')' + ; + +rvalue + : '(' signed_real_number ')' + | '(' rtriple ')' + ; + +hierarchical_identifier + : IDENTIFIER + { free($1); } + ; + +rtriple + : signed_real_number ':' signed_real_number ':' signed_real_number + ; + +signed_real_number + : REAL_NUMBER + | '+' REAL_NUMBER + | '-' REAL_NUMBER + ; + +%% + +void yyerror(const char*msg) +{ + fprintf(stderr, "SDF ERROR: %s\n", msg); +} diff --git a/vpi/sdf_parse_priv.h b/vpi/sdf_parse_priv.h new file mode 100644 index 000000000..9ecce9dad --- /dev/null +++ b/vpi/sdf_parse_priv.h @@ -0,0 +1,30 @@ +#ifndef _sdf_parse_priv_h +#define _sdf_parse_priv_h +/* + * Copyright (c) 2007 Stephen Williams (steve@icarus.com) + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form under the terms of the GNU + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +/* + * This file is only included by sdf_parse.y and sdf_lexor.lex. It is + * used to share declarations between the parse and the lexor. + */ + + /* Path to source for error messages. */ +extern const char*sdf_parse_path; + +#endif diff --git a/vpi/sdf_priv.h b/vpi/sdf_priv.h new file mode 100644 index 000000000..82f26fed2 --- /dev/null +++ b/vpi/sdf_priv.h @@ -0,0 +1,31 @@ +#ifndef _sdf_priv_h +#define _sdf_priv_h +/* + * Copyright (c) 2007 Stephen Williams (steve@icarus.com) + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form under the terms of the GNU + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +# include + +/* + * Invoke the parser to parse the opened SDF file. The fd is the SDF + * file already opened and ready for reading. The path is the path to + * the file and is only used for error messages. + */ +extern void sdf_process_file(FILE*fd, const char*path); + +#endif diff --git a/vpi/sys_sdf.c b/vpi/sys_sdf.c new file mode 100644 index 000000000..5a4b27e5e --- /dev/null +++ b/vpi/sys_sdf.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2007 Stephen Williams (steve@icarus.com) + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form under the terms of the GNU + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +# include "vpi_config.h" + +# include "vpi_user.h" +# include "sdf_priv.h" +# include +# include +# include + +static PLI_INT32 sys_sdf_annotate_compiletf(PLI_BYTE8*name) +{ + return 0; +} + +static PLI_INT32 sys_sdf_annotate_calltf(PLI_BYTE8*name) +{ + s_vpi_value value; + vpiHandle sys = vpi_handle(vpiSysTfCall,0); + vpiHandle argv = vpi_iterate(vpiArgument, sys); + + vpiHandle path = vpi_scan(argv); + assert(path); + + vpi_free_object(argv); + + value.format = vpiStringVal; + vpi_get_value(path, &value); + + if ((value.format != vpiStringVal) || !value.value.str) { + vpi_printf("ERROR: %s: File name argument (type=%d)" + " does not have a string value\n", + name, vpi_get(vpiType, path)); + return 0; + } + + char*path_str = strdup(value.value.str); + FILE*sdf_fd = fopen(path_str, "r"); + assert(sdf_fd); + + sdf_process_file(sdf_fd, path_str); + + fclose(sdf_fd); + free(path_str); + return 0; +} + +void sys_sdf_register() +{ + s_vpi_systf_data tf_data; + + tf_data.type = vpiSysTask; + tf_data.tfname = "$sdf_annotate"; + tf_data.calltf = sys_sdf_annotate_calltf; + tf_data.compiletf = sys_sdf_annotate_compiletf; + tf_data.sizetf = 0; + tf_data.user_data = "$sdf_annotate"; + vpi_register_systf(&tf_data); +} diff --git a/vpi/sys_table.c b/vpi/sys_table.c index ceb7e0033..be260e8bc 100644 --- a/vpi/sys_table.c +++ b/vpi/sys_table.c @@ -36,6 +36,7 @@ extern void sys_random_register(); extern void sys_random_mti_register(); extern void sys_readmem_register(); extern void sys_scanf_register(); +extern void sys_sdf_register(); extern void sys_time_register(); extern void sys_vcd_register(); extern void sys_vcdoff_register(); @@ -176,6 +177,7 @@ void (*vlog_startup_routines[])() = { sys_scanf_register, sys_time_register, sys_lxt_or_vcd_register, + sys_sdf_register, 0 };