diff --git a/jtag/configure.ac b/jtag/configure.ac index ab3be0c2..c4d028ce 100644 --- a/jtag/configure.ac +++ b/jtag/configure.ac @@ -549,6 +549,18 @@ AC_CHECK_LIB([m], [fmax], [ ]) +dnl Enable use of DMALLOC library? +AC_ARG_ENABLE(dmalloc, +[AS_HELP_STRING([--enable-dmalloc], [Enable heap debugging with dmalloc library])], +[dmalloc=$enableval], [dmalloc=no]) +AS_IF([test "x$dmalloc" = xyes], [ + AM_CONDITIONAL(DMALLOC, true) + AC_DEFINE(DMALLOC, 1, [define for dmalloc library]) +],[ + AM_CONDITIONAL(DMALLOC, false) +]) + + AC_OUTPUT dnl diff --git a/jtag/data/Makefile.am b/jtag/data/Makefile.am index 7f477944..0ff7066b 100644 --- a/jtag/data/Makefile.am +++ b/jtag/data/Makefile.am @@ -89,6 +89,8 @@ nobase_dist_pkgdata_DATA = \ bsdl/STD_1149_1_1990 \ bsdl/STD_1149_1_1994 \ bsdl/STD_1149_1_2001 \ + bsdl/STD_1532_2001 \ + bsdl/STD_1532_2002 \ dec/PARTS \ dec/sa1100/STEPPINGS \ dec/sa1100/sa1100 \ diff --git a/jtag/data/bsdl/STD_1532_2001 b/jtag/data/bsdl/STD_1532_2001 new file mode 100644 index 00000000..e18fde1f --- /dev/null +++ b/jtag/data/bsdl/STD_1532_2001 @@ -0,0 +1,19 @@ +Package STD_1532_2001 is -- Attribute definitions for ISC description + use STD_1149_1_2001.all; -- Refer to BSDL definitions + + attribute ISC_Conformance: BSDL_Extension; + attribute ISC_Pin_Behavior: BSDL_Extension; + attribute ISC_Fixed_System_Pins: BSDL_Extension; -- Optional + attribute ISC_Status: BSDL_Extension; + attribute ISC_Blank_Usercode: BSDL_Extension; + attribute ISC_Security: BSDL_Extension; -- Optional + attribute ISC_Flow: BSDL_Extension; + attribute ISC_Procedure: BSDL_Extension; + attribute ISC_Action: BSDL_Extension; + attribute ISC_Illegal_Exit: BSDL_Extension; -- Optional + attribute ISC_Design_Warning: BSDL_Extension; -- Optional +end STD_1532_2001; + +Package Body STD_1532_2001 is + -- No content, this package body is required by BSDL syntax +end STD_1532_2001; diff --git a/jtag/data/bsdl/STD_1532_2002 b/jtag/data/bsdl/STD_1532_2002 new file mode 100644 index 00000000..91635db8 --- /dev/null +++ b/jtag/data/bsdl/STD_1532_2002 @@ -0,0 +1,19 @@ +Package STD_1532_2002 is -- Attribute definitions for ISC description + use STD_1149_1_2001.all; -- Refer to BSDL definitions + + attribute ISC_Conformance: BSDL_Extension; + attribute ISC_Pin_Behavior: BSDL_Extension; + attribute ISC_Fixed_System_Pins: BSDL_Extension; -- Optional + attribute ISC_Status: BSDL_Extension; + attribute ISC_Blank_Usercode: BSDL_Extension; + attribute ISC_Security: BSDL_Extension; -- Optional + attribute ISC_Flow: BSDL_Extension; + attribute ISC_Procedure: BSDL_Extension; + attribute ISC_Action: BSDL_Extension; + attribute ISC_Illegal_Exit: BSDL_Extension; -- Optional + attribute ISC_Design_Warning: BSDL_Extension; -- Optional +end STD_1532_2002; + +Package Body STD_1532_2002 is + -- No content, this package body is required by BSDL syntax +end STD_1532_2002; diff --git a/jtag/src/Makefile.am b/jtag/src/Makefile.am index 85995529..a38e2a74 100644 --- a/jtag/src/Makefile.am +++ b/jtag/src/Makefile.am @@ -92,5 +92,9 @@ jtag_LDADD += -Ljim -ljim jtag_DEPENDENCIES += jim/libjim.a endif +if DMALLOC +jtag_LDADD += -ldmalloc +endif + localedir = $(datadir)/locale INCLUDES = -DLOCALEDIR=\"$(localedir)\" diff --git a/jtag/src/bsdl/Makefile.am b/jtag/src/bsdl/Makefile.am index af311569..24612b09 100644 --- a/jtag/src/bsdl/Makefile.am +++ b/jtag/src/bsdl/Makefile.am @@ -23,19 +23,37 @@ include $(top_srcdir)/Makefile.rules noinst_LIBRARIES = libbsdl.a -libbsdl_a_SOURCES = \ +libbsdl_a_SOURCES = \ + vhdl_bison.y \ + vhdl_flex.l \ bsdl_bison.y \ - bsdl_flex.l \ - bsdl.c \ + bsdl_flex.l \ + bsdl.c \ bsdl_sem.c -bsdl_flex.$(OBJEXT) bsdl_sem.$(OBJEXT): bsdl_bison.$(OBJEXT) +# additional dependencies +# - all files depend on bsdl_config.h which dynamically generated +# - *_flex files must be processed after their *_bison counterparts +# to ensure that *_bison.h is present +vhdl_flex.$(OBJEXT): vhdl_bison.$(OBJEXT) bsdl_config.h +vhdl_bison.$(OBJEXT): bsdl_config.h +bsdl_flex.$(OBJEXT): bsdl_bison.$(OBJEXT) bsdl_config.h +bsdl_bison.$(OBJEXT): bsdl_config.h +bsdl.$(OBJEXT) : bsdl_config.h +bsdl_sem.$(OBJEXT): bsdl_config.h +vhdl_bison.h: vhdl_bison.c bsdl_bison.h: bsdl_bison.c +bsdl_config.h: ../../config.h + grep 'DMALLOC' $< > $@ + AM_LFLAGS = -i MAINTAINERCLEANFILES = \ + vhdl_bison.c \ + vhdl_bison.h \ bsdl_bison.c \ bsdl_bison.h \ - bsdl_flex.c + vhdl_flex.c \ + bsdl_config.h diff --git a/jtag/src/bsdl/bsdl.c b/jtag/src/bsdl/bsdl.c index 4688178d..1b9de6d7 100644 --- a/jtag/src/bsdl/bsdl.c +++ b/jtag/src/bsdl/bsdl.c @@ -36,148 +36,206 @@ #include "jtag.h" #include "cmd.h" -#include "bsdl_local.h" +//#include "bsdl_local.h" +#include "bsdl_types.h" +#include "vhdl_parser.h" +#include "bsdl_parser.h" +#include "bsdl_msg.h" -void bsdl_msg(int type, const char *format, ...) +#ifdef DMALLOC +#include "dmalloc.h" +#endif + + +/***************************************************************************** + * bsdl_msg( type, format, ... ) + * + * Main printing function for the BSDL subsystem. + * + * Parameters + * type : one of the BSDL_MSG_* defines, determines message tag + * format : printf format + * ... : additional parameters to fill the printf format string + * + * Returns + * void + ****************************************************************************/ +void bsdl_msg( int type, const char *format, ... ) { va_list lst; - va_start(lst, format); - switch (type) { + va_start( lst, format ); + switch (type) + { case BSDL_MSG_NOTE: - printf("-N- "); + printf( "-N- " ); break; case BSDL_MSG_WARN: - printf("-W- "); + printf( "-W- " ); break; case BSDL_MSG_ERR: - printf("-E- "); + printf( "-E- " ); break; case BSDL_MSG_FATAL: - printf("-F- "); + printf( "-F- " ); break; default: - printf("-?- "); + printf( "-?- " ); break; } - vprintf(format, lst); - va_end(lst); + vprintf( format, lst ); + va_end( lst ); } /***************************************************************************** - * bsdl_read_file(BSDL_File_Name, mode, idcode) + * bsdl_read_file( chain, BSDL_File_Name, mode, idcode ) + * + * Read, parse and optionally apply contents of BSDL file. * - * mode: -1 -> read file - * no further action based on components - * 0 -> read file and extract all components - * dump commands to stdout, do not execute commands - * 1 -> read file and extract all components - * execute commands + * Parameters + * chain : pointer to active chain structure + * BSDL_File_Name : name of BSDL file to read + * mode : -1 -> read file + * no further action based on components + * 0 -> read file and extract all components + * dump commands to stdout, do not execute commands + * 1 -> read file and extract all components + * execute commands + * idcode : reference idcode string * - * Return value: - * < 0 : Error occured, parse/syntax problems or out of memory - * = 0 : No errors, idcode not checked or mismatching - * > 0 : No errors, idcode checked and matched + * Returns + * < 0 : Error occured, parse/syntax problems or out of memory + * = 0 : No errors, idcode not checked or mismatching + * > 0 : No errors, idcode checked and matched * ****************************************************************************/ -int bsdl_read_file(chain_t *chain, const char *BSDL_File_Name, int mode, const char *idcode) +int bsdl_read_file( chain_t *chain, const char *BSDL_File_Name, int mode, + const char *idcode ) { bsdl_globs_t *globs = &(chain->bsdl); FILE *BSDL_File; - parser_priv_t *parser_priv; + vhdl_parser_priv_t *vhdl_parser_priv; + bsdl_parser_priv_t *bsdl_parser_priv; + jtag_ctrl_t jtag_ctrl; int Compile_Errors = 1; int idcode_match = 0; - BSDL_File = fopen(BSDL_File_Name, "r"); + jtag_ctrl.mode = mode; + jtag_ctrl.debug = globs->debug; + + /* perform some basic checks */ + if (mode >= 0) + { + if (mode >= 1) + { + if (chain == NULL) + { + bsdl_msg( BSDL_MSG_ERR, _("No JTAG chain available\n") ); + return -1; + } + if (chain->parts == NULL) + { + bsdl_msg( BSDL_MSG_ERR, _("Chain without any parts\n") ); + return -1; + } + if (!(chain && chain->parts)) + return -1; + + jtag_ctrl.chain = chain; + jtag_ctrl.part = chain->parts->parts[chain->active_part]; + } + else + { + jtag_ctrl.chain = NULL; + jtag_ctrl.part = NULL; + } + } + else + { + jtag_ctrl.chain = NULL; + jtag_ctrl.part = NULL; + } + + BSDL_File = fopen( BSDL_File_Name, "r" ); if (globs->debug || (mode == 0)) - bsdl_msg(BSDL_MSG_NOTE, _("Reading file '%s'\n"), BSDL_File_Name); + bsdl_msg( BSDL_MSG_NOTE, _("Reading file '%s'\n"), BSDL_File_Name ); if (BSDL_File == NULL) { - bsdl_msg(BSDL_MSG_ERR, _("Unable to open BSDL_file '%s'\n"), BSDL_File_Name); + bsdl_msg( BSDL_MSG_ERR, _("Unable to open BSDL file '%s'\n"), BSDL_File_Name ); return -1; } - if ((parser_priv = bsdl_parser_init(BSDL_File, mode, globs->debug))) { - if (mode >= 0) { - if (mode >= 1) { - if (chain == NULL) { - bsdl_msg(BSDL_MSG_ERR, _("No JTAG chain available\n")); - bsdl_parser_deinit(parser_priv); - fclose(BSDL_File); - return -1; - } - if (chain->parts == NULL) { - bsdl_msg(BSDL_MSG_ERR, _("Chain without any parts\n")); - bsdl_parser_deinit(parser_priv); - fclose(BSDL_File); - return -1; - } - if (!(chain && chain->parts)) { - bsdl_parser_deinit(parser_priv); - fclose(BSDL_File); - return -1; - } - parser_priv->jtag_ctrl.chain = chain; - parser_priv->jtag_ctrl.part = chain->parts->parts[chain->active_part]; - } else { - parser_priv->jtag_ctrl.chain = NULL; - parser_priv->jtag_ctrl.part = NULL; - } - } else { - parser_priv->jtag_ctrl.chain = NULL; - parser_priv->jtag_ctrl.part = NULL; - } + if ((vhdl_parser_priv = vhdl_parser_init( BSDL_File, &jtag_ctrl ))) + { + vhdl_parser_priv->jtag_ctrl->idcode = NULL; - parser_priv->jtag_ctrl.idcode = NULL; - - bsdlparse(parser_priv); - - Compile_Errors = bsdl_flex_get_compile_errors(parser_priv->scanner); - if (Compile_Errors == 0) { - if (globs->debug) - bsdl_msg(BSDL_MSG_NOTE, _("BSDL file '%s' compiled correctly\n"), BSDL_File_Name); - } else { - if (globs->debug || (mode >= 0)) - bsdl_msg(BSDL_MSG_ERR, _("BSDL file '%s' contains errors, stopping\n"), BSDL_File_Name); - } + vhdlparse( vhdl_parser_priv ); + Compile_Errors = vhdl_flex_get_compile_errors( vhdl_parser_priv->scanner ); if (Compile_Errors == 0) - bsdl_ac_finalize(parser_priv); - - if ((Compile_Errors == 0) && parser_priv->jtag_ctrl.idcode) { + { if (globs->debug) - bsdl_msg(BSDL_MSG_NOTE, _("Got IDCODE: %s\n"), parser_priv->jtag_ctrl.idcode); - - /* should be compare the idcodes? */ - if (idcode) { - if (strlen(idcode) == strlen(parser_priv->jtag_ctrl.idcode)) { - int idx; - - /* compare given idcode with idcode from BSDL file - including the end of string character */ - idcode_match = 1; - for (idx = 0; idx <= strlen(idcode); idx++) - if (parser_priv->jtag_ctrl.idcode[idx] != 'X') - if (idcode[idx] != parser_priv->jtag_ctrl.idcode[idx]) - idcode_match = 0; - - if (globs->debug) { - if (idcode_match) - bsdl_msg(BSDL_MSG_NOTE, _("IDCODE matched\n") ); - else - bsdl_msg(BSDL_MSG_NOTE, _("IDCODE mismatch\n") ); + bsdl_msg( BSDL_MSG_NOTE, _("BSDL file '%s' passed VHDL stage correctly\n"), + BSDL_File_Name ); + + if ((bsdl_parser_priv = bsdl_parser_init( &jtag_ctrl ))) + { + + Compile_Errors = bsdl_sem_process_elements( bsdl_parser_priv ); + + if ((Compile_Errors == 0) && globs->debug) + bsdl_msg( BSDL_MSG_NOTE, _("BSDL file '%s' passed BSDL stage correctly\n"), + BSDL_File_Name ); + + + /* handle IDCODE comparison */ + if ((Compile_Errors == 0) && jtag_ctrl.idcode) + { + if (globs->debug) + bsdl_msg( BSDL_MSG_NOTE, _("Got IDCODE: %s\n"), jtag_ctrl.idcode ); + + /* should we compare the idcodes? */ + if (idcode) + { + if (strlen( idcode ) == strlen(jtag_ctrl.idcode)) + { + int idx; + + /* compare given idcode with idcode from BSDL file + including the end of string character */ + idcode_match = 1; + for (idx = 0; idx <= strlen( idcode ); idx++) + if (jtag_ctrl.idcode[idx] != 'X') + if (idcode[idx] != jtag_ctrl.idcode[idx]) + idcode_match = 0; + + if (globs->debug) + { + if (idcode_match) + bsdl_msg( BSDL_MSG_NOTE, _("IDCODE matched\n") ); + else + bsdl_msg( BSDL_MSG_NOTE, _("IDCODE mismatch\n") ); + } + } } } - } - if (parser_priv->jtag_ctrl.idcode) - free(parser_priv->jtag_ctrl.idcode); - parser_priv->jtag_ctrl.idcode = NULL; + + bsdl_parser_deinit( bsdl_parser_priv ); + } + } + else + { + if (globs->debug || (mode >= 0)) + bsdl_msg( BSDL_MSG_ERR, _("BSDL file '%s' contains errors in VHDL stage, stopping\n"), + BSDL_File_Name ); } - bsdl_parser_deinit(parser_priv); + + + vhdl_parser_deinit( vhdl_parser_priv ); } return Compile_Errors == 0 ? idcode_match : -1; @@ -185,83 +243,93 @@ int bsdl_read_file(chain_t *chain, const char *BSDL_File_Name, int mode, const c /***************************************************************************** - * void bsdl_set_path(const char *pathlist) + * void bsdl_set_path( chain, pathlist ) * * Dissects pathlist and enters its elements to the global variable * bsdl.path_list. * - * Return value: - * void + * Parameters + * chain : pointer to active chain structure + * pathlist : string containing the paths to be stored, format: + * ;;;... + * + * Returns + * void ****************************************************************************/ -void bsdl_set_path(chain_t *chain, const char *pathlist) +void bsdl_set_path( chain_t *chain, const char *pathlist ) { bsdl_globs_t *globs = &(chain->bsdl); - char *delim; - char *elem; - char *pathelem; - int num; + char *delim; + char *elem; + char *pathelem; + int num; size_t len; /* free memory of current path list */ - if (globs->path_list) { + if (globs->path_list) + { for (num = 0; globs->path_list[num]; num++) if (globs->path_list[num]) - free(globs->path_list[num]); - free(globs->path_list); + free( globs->path_list[num] ); + free( globs->path_list ); globs->path_list = NULL; } /* run through path list and determine number of elements */ - for (num = 0, elem = (char *)pathlist; strlen(elem) > 0; ) { - delim = strchr(elem, ';'); - if ((delim - elem > 0) || (delim == NULL)) { + for (num = 0, elem = (char *)pathlist; strlen(elem) > 0; ) + { + delim = strchr( elem, ';' ); + if ((delim - elem > 0) || (delim == NULL)) + { num++; /* extend path list array */ - globs->path_list = (char **)realloc(globs->path_list, (num+1) * sizeof(char *)); + globs->path_list = (char **)realloc( globs->path_list, (num+1) * sizeof(char *) ); /* enter path element up to the delimeter */ if (delim == NULL) - len = strlen(elem); + len = strlen( elem ); else len = delim-elem; - pathelem = malloc(len + 1); - memcpy(pathelem, elem, len); + pathelem = malloc( len + 1 ); + memcpy( pathelem, elem, len ); pathelem[len] = '\0'; globs->path_list[num-1] = pathelem; globs->path_list[num] = NULL; } - elem = delim ? delim + 1 : elem + strlen(elem); + elem = delim ? delim + 1 : elem + strlen( elem ); } if (globs->debug) - for (num = 0; globs->path_list[num] != NULL; num++) { - bsdl_msg(BSDL_MSG_NOTE, "%s\n", globs->path_list[num]); - } + for (num = 0; globs->path_list[num] != NULL; num++) + bsdl_msg( BSDL_MSG_NOTE, "%s\n", globs->path_list[num] ); } /***************************************************************************** - * int bsdl_scan_files(const char *idcode, int mode) + * bsdl_scan_files( chain, idcode, mode ) * * Scans through all files found via the elements in bsdl_path_list * and does a test read on each of them. * If mode >= 1 is requested, it will read the first BSDL file with matching * idcode in "execute" mode. I.e. all extracted statements are applied to * the current part. - * - * mode: -1 -> read file - * no further action based on components - * 0 -> read file and extract all components - * dump commands to stdout, do not execute commands - * 1 -> read file and extract all components - * execute commands * - * Return value: - * < 0 : Error occured, parse/syntax problems or out of memory - * = 0 : No errors, idcode not checked or mismatching - * > 0 : No errors, idcode checked and matched + * Parameters + * chain : pointer to active chain structure + * idcode : reference idcode string + * mode : -1 -> read file + * no further action based on components + * 0 -> read file and extract all components + * dump commands to stdout, do not execute commands + * 1 -> read file and extract all components + * execute commands + * + * Returns + * < 0 : Error occured, parse/syntax problems or out of memory + * = 0 : No errors, idcode not checked or mismatching + * > 0 : No errors, idcode checked and matched * ****************************************************************************/ -int bsdl_scan_files(chain_t *chain, const char *idcode, int mode) +int bsdl_scan_files( chain_t *chain, const char *idcode, int mode ) { bsdl_globs_t *globs = &(chain->bsdl); int idx = 0; @@ -271,50 +339,70 @@ int bsdl_scan_files(chain_t *chain, const char *idcode, int mode) if (globs->path_list == NULL) return 0; - while (globs->path_list[idx] && (result <= 0)) { + while (globs->path_list[idx] && (result <= 0)) + { DIR *dir; - if ((dir = opendir(globs->path_list[idx]))) { + if ((dir = opendir( globs->path_list[idx] ))) + { struct dirent *elem; /* run through all elements in the current directory */ - while ((elem = readdir(dir)) && (result <= 0)) { + while ((elem = readdir( dir )) && (result <= 0)) + { char *name; - name = (char *)malloc(strlen(globs->path_list[idx]) + strlen(elem->d_name) + 1 + 1); - if (name) { + name = (char *)malloc( strlen( globs->path_list[idx] ) + + strlen( elem->d_name ) + 1 + 1 ); + if (name) + { struct stat buf; - strcpy(name, globs->path_list[idx]); - strcat(name, "/"); - strcat(name, elem->d_name); + strcpy( name, globs->path_list[idx] ); + strcat( name, "/" ); + strcat( name, elem->d_name ); - if (stat(name, &buf) == 0) { - if (buf.st_mode & S_IFREG) { - if (mode >= 1) { + if (stat( name, &buf ) == 0) + { + if (buf.st_mode & S_IFREG) + { + if (mode >= 1) + { /* now we know we can finally read the file */ /* do a test read first */ - result = bsdl_read_file(chain, name, -1, idcode); - if (result > 0) { + result = bsdl_read_file( chain, name, -1, idcode ); + if (result > 0) + { /* read in BSDL file if IDCODE matched */ printf( _(" Filename: %s\n"), name ); - result = bsdl_read_file(chain, name, 1, idcode); + result = bsdl_read_file( chain, name, 1, idcode ); } - } else - result = bsdl_read_file(chain, name, mode, idcode); + } + else + result = bsdl_read_file( chain, name, mode, idcode ); } } - free(name); + free( name ); } } - closedir(dir); - } else - bsdl_msg(BSDL_MSG_WARN, _("Cannot open directory %s\n"), globs->path_list[idx]); + closedir( dir ); + } + else + bsdl_msg( BSDL_MSG_WARN, _("Cannot open directory %s\n"), globs->path_list[idx] ); idx++; } return result; } + + +/* + Local Variables: + mode:C + c-default-style:gnu + indent-tabs-mode:nil + End: +*/ diff --git a/jtag/src/bsdl/bsdl_bison.y b/jtag/src/bsdl/bsdl_bison.y index 9eeb4b10..9e3632be 100644 --- a/jtag/src/bsdl/bsdl_bison.y +++ b/jtag/src/bsdl/bsdl_bison.y @@ -118,7 +118,7 @@ LEGAL NOTICES: %pure-parser -%parse-param {parser_priv_t *priv_data} +%parse-param {bsdl_parser_priv_t *priv_data} %defines %name-prefix="bsdl" @@ -130,862 +130,1388 @@ LEGAL NOTICES: #include "bsdl_sysdep.h" +#include "bsdl_types.h" +#include "bsdl_msg.h" + /* interface to flex */ #include "bsdl_bison.h" -#include "bsdl_local.h" +#include "bsdl_parser.h" + +#ifdef DMALLOC +#include "dmalloc.h" +#endif #define YYLEX_PARAM priv_data->scanner int yylex (YYSTYPE *, void *); #if 1 -#define ERROR_LIMIT 15 -#define BUMP_ERROR if (bsdl_flex_postinc_compile_errors(priv_data->scanner)>ERROR_LIMIT) \ - {Give_Up_And_Quit(priv_data);YYABORT;} +#define ERROR_LIMIT 0 +#define BUMP_ERROR if (bsdl_flex_postinc_compile_errors( priv_data->scanner ) > ERROR_LIMIT) \ + {Give_Up_And_Quit( priv_data ); YYABORT;} #else -#define BUMP_ERROR {Give_Up_And_Quit(priv_data);YYABORT;} +#define BUMP_ERROR {Give_Up_And_Quit( priv_data );YYABORT;} #endif -static void Init_Text(parser_priv_t *); -static void Store_Text(parser_priv_t *, char *); -static void Print_Error(parser_priv_t *, const char *); -static void Print_Warning(parser_priv_t *, const char *); -static void Give_Up_And_Quit(parser_priv_t *); +static void Print_Error( bsdl_parser_priv_t *, const char * ); +static void Print_Warning( bsdl_parser_priv_t *, const char * ); +static void Give_Up_And_Quit( bsdl_parser_priv_t * ); -void yyerror(parser_priv_t *, const char *); +/* semantic functions */ +static void add_instruction( bsdl_parser_priv_t *, char *, char * ); +static void ac_set_register( bsdl_parser_priv_t *, char *, int ); +static void ac_add_instruction( bsdl_parser_priv_t *, char * ); +static void ac_apply_assoc( bsdl_parser_priv_t * ); +static void prt_add_name( bsdl_parser_priv_t *, char * ); +static void prt_add_bit( bsdl_parser_priv_t * ); +static void prt_add_range( bsdl_parser_priv_t *, int, int ); +static void ci_no_disable( bsdl_parser_priv_t * ); +static void ci_set_cell_spec_disable( bsdl_parser_priv_t *, int, int, int ); +static void ci_set_cell_spec( bsdl_parser_priv_t *, int, char * ); +static void ci_append_cell_info( bsdl_parser_priv_t *, int ); + +void yyerror( bsdl_parser_priv_t *, const char * ); %} %union { - int integer; - char *str; + int integer; + char *str; } -%token ENTITY PORT GENERIC USE ATTRIBUTE IS -%token OF CONSTANT STRING END ALL PIN_MAP -%token PHYSICAL_PIN_MAP PIN_MAP_STRING TRUE FALSE SIGNAL -%token TAP_SCAN_IN TAP_SCAN_OUT TAP_SCAN_MODE TAP_SCAN_RESET -%token TAP_SCAN_CLOCK LOW BOTH IN OUT INOUT -%token BUFFER LINKAGE BIT BIT_VECTOR TO DOWNTO -%token PACKAGE BODY TYPE SUBTYPE RECORD ARRAY -%token POSITIVE RANGE CELL_INFO INSTRUCTION_LENGTH -%token INSTRUCTION_OPCODE INSTRUCTION_CAPTURE INSTRUCTION_DISABLE -%token INSTRUCTION_GUARD INSTRUCTION_PRIVATE INSTRUCTION_USAGE -%token INSTRUCTION_SEQUENCE REGISTER_ACCESS BOUNDARY_CELLS -%token BOUNDARY_LENGTH BOUNDARY_REGISTER IDCODE_REGISTER -%token USERCODE_REGISTER DESIGN_WARNING BOUNDARY BYPASS HIGHZ IDCODE DEVICE_ID -%token USERCODE INPUT OUTPUT2 OUTPUT3 CONTROL CONTROLR INTERNAL -%token CLOCK BIDIR BIDIR_IN BIDIR_OUT EXTEST SAMPLE -%token INTEST RUNBIST PI PO UPD CAP X -%token ZERO ONE Z WEAK0 WEAK1 IDENTIFIER +%token CONSTANT PIN_MAP +%token PHYSICAL_PIN_MAP PIN_MAP_STRING +%token TAP_SCAN_IN TAP_SCAN_OUT TAP_SCAN_MODE TAP_SCAN_RESET +%token TAP_SCAN_CLOCK +%token INSTRUCTION_LENGTH INSTRUCTION_OPCODE INSTRUCTION_CAPTURE INSTRUCTION_DISABLE +%token INSTRUCTION_GUARD INSTRUCTION_PRIVATE +%token REGISTER_ACCESS +%token BOUNDARY_LENGTH BOUNDARY_REGISTER IDCODE_REGISTER +%token USERCODE_REGISTER BOUNDARY DEVICE_ID +%token INPUT OUTPUT2 OUTPUT3 CONTROL CONTROLR INTERNAL +%token CLOCK BIDIR BIDIR_IN BIDIR_OUT +%token Z WEAK0 WEAK1 IDENTIFIER %token PULL0 PULL1 KEEPER -%token SINGLE_QUOTE QUOTED_STRING DECIMAL_NUMBER BINARY_PATTERN -%token BIN_X_PATTERN REAL_NUMBER CONCATENATE SEMICOLON COMMA -%token LPAREN RPAREN LBRACKET RBRACKET COLON ASTERISK -%token BOX COLON_EQUAL PERIOD ILLEGAL -%token COMPONENT_CONFORMANCE PORT_GROUPING RUNBIST_EXECUTION -%token INTEST_EXECUTION BSDL_EXTENSION COMPLIANCE_PATTERNS +%token DECIMAL_NUMBER BINARY_PATTERN +%token BIN_X_PATTERN COMMA +%token LPAREN RPAREN LBRACKET RBRACKET COLON ASTERISK +%token COMPLIANCE_PATTERNS %token OBSERVE_ONLY +%token BYPASS CLAMP EXTEST HIGHZ IDCODE INTEST PRELOAD RUNBIST SAMPLE USERCODE +%token COMPONENT_CONFORMANCE STD_1149_1_1990 STD_1149_1_1993 STD_1149_1_2001 +%token ISC_CONFORMANCE STD_1532_2001 STD_1532_2002 +%token ISC_PIN_BEHAVIOR +%token ISC_FIXED_SYSTEM_PINS +%token ISC_STATUS IMPLEMENTED +%token ISC_BLANK_USERCODE +%token ISC_SECURITY ISC_DISABLE_READ ISC_DISABLE_PROGRAM ISC_DISABLE_ERASE ISC_DISABLE_KEY +%token ISC_FLOW UNPROCESSED EXIT_ON_ERROR ARRAY SECURITY INITIALIZE REPEAT TERMINATE +%token LOOP MIN MAX DOLLAR EQUAL HEX_STRING WAIT REAL_NUMBER +%token PLUS MINUS SH_RIGHT SH_LEFT TILDE QUESTION_MARK EXCLAMATION_MARK QUESTION_EXCLAMATION +%token CRC OST +%token ISC_PROCEDURE +%token ISC_ACTION PROPRIETARY OPTIONAL RECOMMENDED +%token ISC_ILLEGAL_EXIT +%token ILLEGAL +%type HEX_STRING %type BIN_X_PATTERN %type IDENTIFIER -%type QUOTED_STRING %type BINARY_PATTERN %type Binary_Pattern %type Binary_Pattern_List -%type DECIMAL_NUMBER %type REAL_NUMBER +%type DECIMAL_NUMBER %type Cell_Function %type Safe_Value %type Disable_Value %type Standard_Reg -%type Standard_Inst +%type Instruction_Name -%start BSDL_Program +%start BSDL_Statement %% /* End declarations, begin rules */ -BSDL_Program : Begin_BSDL Part_1 Part_2 End_BSDL - ; -Begin_BSDL : ENTITY IDENTIFIER IS - { bsdl_set_entity(priv_data, $2); } - | error - {Print_Error(priv_data, _("Improper Entity declaration")); - Print_Error(priv_data, _("Check if source file is BSDL")); - BUMP_ERROR; YYABORT; /* Probably not a BSDL source file */ - } - ; -Part_1 : VHDL_Generic /* 1994 and later */ - VHDL_Port - VHDL_Use_Part - VHDL_Component_Conformance - VHDL_Pin_Map - VHDL_Constant_List - | VHDL_Generic /* 1990 */ - VHDL_Port - VHDL_Use_Part - VHDL_Pin_Map - VHDL_Constant_List - | error - {Print_Error(priv_data, _("Syntax Error")); - BUMP_ERROR; YYABORT; } - ; -Part_2 : VHDL_Tap_Signals - VHDL_Compliance_Patterns - VHDL_Inst_Length - VHDL_Inst_Opcode - VHDL_Inst_Details - VHDL_Boundary_Details - VHDL_Boundary_Register - | VHDL_Tap_Signals - VHDL_Inst_Length - VHDL_Inst_Opcode - VHDL_Inst_Details - VHDL_Boundary_Details - VHDL_Boundary_Register - | error - {Print_Error(priv_data, _("Syntax Error")); - BUMP_ERROR; YYABORT; } - ; -End_BSDL : VHDL_Design_Warning END IDENTIFIER SEMICOLON - { free($3); } +BSDL_Statement : BSDL_Pin_Map + | BSDL_Map_String + | BSDL_Tap_Scan_In + | BSDL_Tap_Scan_Out + | BSDL_Tap_Scan_Mode + | BSDL_Tap_Scan_Reset + | BSDL_Tap_Scan_Clock + | BSDL_Inst_Length + | BSDL_Opcode + | BSDL_Inst_Capture + | BSDL_Inst_Disable + | BSDL_Inst_Guard + | BSDL_Inst_Private + | BSDL_Idcode_Register + | BSDL_Usercode_Register + | BSDL_Register_Access + | BSDL_Boundary_Length + | BSDL_Boundary_Register + | BSDL_Compliance_Patterns + | BSDL_Component_Conformance + | ISC_Extension | error - {Print_Error(priv_data, _("Syntax Error")); - BUMP_ERROR; YYABORT; } - ; -VHDL_Generic : GENERIC LPAREN PHYSICAL_PIN_MAP COLON STRING COLON_EQUAL - Quoted_String RPAREN SEMICOLON { - bsdl_flex_switch_buffer(priv_data->scanner, - priv_data->buffer_for_switch); + Print_Error( priv_data, _("Unsupported BSDL construct found") ); + BUMP_ERROR; + YYABORT; } - IDENTIFIER - { free($11); } - ; -VHDL_Port : PORT LPAREN Port_Specifier_List RPAREN SEMICOLON - | error - {Print_Error(priv_data, _("Improper Port declaration")); - BUMP_ERROR; YYABORT; } - ; -Port_Specifier_List : Port_Specifier - | Port_Specifier_List SEMICOLON Port_Specifier - ; -Port_Specifier : Port_List COLON Function Scaler_Or_Vector - { - bsdl_prt_apply_port(priv_data); - } - ; -Port_List : IDENTIFIER - { bsdl_prt_add_name(priv_data, $1); } - | Port_List COMMA IDENTIFIER - { - bsdl_prt_add_name(priv_data, $3); - } - ; -Function : IN | OUT | INOUT | BUFFER | LINKAGE - ; -Scaler_Or_Vector : BIT - { bsdl_prt_add_bit(priv_data); } - | BIT_VECTOR LPAREN Vector_Range RPAREN - ; -Vector_Range : DECIMAL_NUMBER TO DECIMAL_NUMBER - { bsdl_prt_add_range(priv_data, $1, $3); } - | DECIMAL_NUMBER DOWNTO DECIMAL_NUMBER - { bsdl_prt_add_range(priv_data, $3, $1); } - ; -VHDL_Use_Part : Standard_Use - | Standard_Use VHDL_Use_List - | error - {Print_Error(priv_data, _("Error in Package declaration(s)")); - BUMP_ERROR; YYABORT; } - ; -Standard_Use : USE IDENTIFIER - {/* Parse Standard 1149.1 Package */ - strcpy(priv_data->Package_File_Name, $2); - free($2); - } - PERIOD ALL SEMICOLON - { - priv_data->Reading_Package = 1; - bsdl_flex_switch_file(priv_data->scanner, - priv_data->Package_File_Name); - } - Standard_Package - { - priv_data->Reading_Package = 0; - } - ; -Standard_Package : PACKAGE IDENTIFIER IS Standard_Decls Defered_Constants - Standard_Decls END IDENTIFIER SEMICOLON Package_Body - { free($2); free($8); } - | error - {Print_Error(priv_data, _("Error in Standard Package")); - BUMP_ERROR; YYABORT; } - ; -Standard_Decls : Standard_Decl - | Standard_Decls Standard_Decl - ; -Standard_Decl : ATTRIBUTE Standard_Attributes COLON Attribute_Type SEMICOLON - | TYPE IDENTIFIER IS Type_Body SEMICOLON - { free($2); } - | TYPE CELL_INFO IS ARRAY LPAREN POSITIVE RANGE BOX RPAREN - OF IDENTIFIER SEMICOLON - { free($11); } - | SUBTYPE PIN_MAP_STRING IS STRING SEMICOLON - | SUBTYPE BSDL_EXTENSION IS STRING SEMICOLON - | error - {Print_Error(priv_data, _("Error in Standard Declarations")); - BUMP_ERROR; YYABORT; } - ; -Standard_Attributes : PIN_MAP | TAP_SCAN_IN | TAP_SCAN_OUT - | TAP_SCAN_CLOCK | TAP_SCAN_MODE | TAP_SCAN_RESET - | COMPONENT_CONFORMANCE | PORT_GROUPING | RUNBIST_EXECUTION - | INTEST_EXECUTION | COMPLIANCE_PATTERNS - | INSTRUCTION_LENGTH | INSTRUCTION_OPCODE - | INSTRUCTION_CAPTURE | INSTRUCTION_DISABLE - | INSTRUCTION_GUARD | INSTRUCTION_PRIVATE - | INSTRUCTION_USAGE | INSTRUCTION_SEQUENCE - | IDCODE_REGISTER | USERCODE_REGISTER - | REGISTER_ACCESS | BOUNDARY_CELLS - | BOUNDARY_LENGTH | BOUNDARY_REGISTER - | DESIGN_WARNING - | error - {Print_Error(priv_data, _("Error in Attribute identifier")); - BUMP_ERROR; YYABORT; } - ; -Attribute_Type : IDENTIFIER - { free($1); } - | STRING - | DECIMAL_NUMBER - | error - {Print_Error(priv_data, _("Error in Attribute type identification")); - BUMP_ERROR; YYABORT; } - ; -Type_Body : LPAREN ID_Bits RPAREN - | LPAREN ID_List RPAREN - | LPAREN LOW COMMA BOTH RPAREN - | ARRAY LPAREN DECIMAL_NUMBER TO DECIMAL_NUMBER RPAREN - OF IDENTIFIER - { free($8); } - | ARRAY LPAREN DECIMAL_NUMBER DOWNTO DECIMAL_NUMBER RPAREN - OF IDENTIFIER - { free($8); } - | RECORD Record_Body END RECORD - | error - {Print_Error(priv_data, _("Error in Type definition")); - BUMP_ERROR; YYABORT; } - ; -ID_Bits : ID_Bit - | ID_Bits COMMA ID_Bit - ; -ID_List : IDENTIFIER - { free($1); } - | ID_List COMMA IDENTIFIER - { free($3); } - ; -ID_Bit : SINGLE_QUOTE BIN_X_PATTERN SINGLE_QUOTE - { free($2); } - | error - {Print_Error(priv_data, _("Error in Bit definition")); - BUMP_ERROR; YYABORT; } - ; -Record_Body : Record_Element - | Record_Body Record_Element - ; -Record_Element : IDENTIFIER COLON IDENTIFIER SEMICOLON - { free($1); free($3); } - | error - {Print_Error(priv_data, _("Error in Record Definition")); - BUMP_ERROR; YYABORT; } - ; -Defered_Constants: Defered_Constant - | Defered_Constants Defered_Constant - ; -Defered_Constant : CONSTANT Constant_Body - ; -Constant_Body : IDENTIFIER COLON CELL_INFO SEMICOLON - { free($1); } - | error - {Print_Error(priv_data, _("Error in defered constant")); - BUMP_ERROR; YYABORT; } - ; -VHDL_Use_List : VHDL_Use - | VHDL_Use_List VHDL_Use - ; -Package_Body : PACKAGE BODY IDENTIFIER IS Constant_List END IDENTIFIER - { free($3); free($7); } - SEMICOLON - | error - {Print_Error(priv_data, _("Error in Package Body definition")); - BUMP_ERROR; YYABORT; } - ; -Constant_List : Cell_Constant - | Constant_List Cell_Constant - ; -Cell_Constant : CONSTANT IDENTIFIER COLON CELL_INFO COLON_EQUAL - LPAREN Triples_List RPAREN SEMICOLON - { free($2); } - | error - {Print_Error(priv_data, _("Error in Cell Constant definition")); - BUMP_ERROR; YYABORT; } - ; -Triples_List : Triple - | Triples_List COMMA Triple - ; -Triple : LPAREN Triple_Function COMMA Triple_Inst COMMA CAP_Data - RPAREN - | error - {Print_Error(priv_data, _("Error in Cell Data Record")); - BUMP_ERROR; YYABORT; } - ; -Triple_Function : INPUT | OUTPUT2 | OUTPUT3 | INTERNAL | CONTROL - | CONTROLR | CLOCK | BIDIR_IN | BIDIR_OUT - | OBSERVE_ONLY - | error - {Print_Error(priv_data, _("Error in Cell_Type Function field")); - BUMP_ERROR; YYABORT; } - ; -Triple_Inst : EXTEST | SAMPLE | INTEST | RUNBIST - | error - {Print_Error(priv_data, _("Error in BScan_Inst Instruction field")); - BUMP_ERROR; YYABORT; } - ; -CAP_Data : PI | PO | UPD | CAP | X | ZERO | ONE - | error - {Print_Error(priv_data, _("Error in Constant CAP data source field")); - BUMP_ERROR; YYABORT; } - ; -VHDL_Use : USE IDENTIFIER - {/* Parse Standard 1149.1 Package */ - strcpy(priv_data->Package_File_Name, $2); - free($2); - } - PERIOD ALL SEMICOLON - { - priv_data->Reading_Package = 1; - bsdl_flex_switch_file(priv_data->scanner, - priv_data->Package_File_Name); - } - User_Package - { - priv_data->Reading_Package = 0; - } - ; -User_Package : PACKAGE IDENTIFIER - IS Defered_Constants END IDENTIFIER SEMICOLON Package_Body - { free($2); free($6); } - | error - {Print_Error(priv_data, _("Error in User-Defined Package declarations")); - BUMP_ERROR; YYABORT; } - ; -VHDL_Pin_Map : ATTRIBUTE PIN_MAP OF IDENTIFIER - COLON ENTITY IS PHYSICAL_PIN_MAP SEMICOLON - { free($4); } - | error - {Print_Error(priv_data, _("Error in Pin_Map Attribute")); - BUMP_ERROR; YYABORT; } - ; -VHDL_Constant_List : VHDL_Constant - | VHDL_Constant_List VHDL_Constant - ; -VHDL_Constant : CONSTANT VHDL_Constant_Part - ; -VHDL_Constant_Part : IDENTIFIER COLON PIN_MAP_STRING COLON_EQUAL - Quoted_String SEMICOLON - { - bsdl_flex_switch_buffer(priv_data->scanner, - priv_data->buffer_for_switch); - } - BSDL_Map_String - { free($1); } - | error - {Print_Error(priv_data, _("Error in Pin_Map_String constant declaration")); - BUMP_ERROR; YYABORT; } - ; -BSDL_Map_String : Pin_Mapping - | BSDL_Map_String COMMA Pin_Mapping - ; -Pin_Mapping : IDENTIFIER COLON Physical_Pin_Desc - { free($1); } - ; -Physical_Pin_Desc: Physical_Pin - | LPAREN Physical_Pin_List RPAREN - ; -Physical_Pin_List: Physical_Pin - | Physical_Pin_List COMMA Physical_Pin - ; -Physical_Pin : IDENTIFIER - { free($1); } - | IDENTIFIER LPAREN DECIMAL_NUMBER RPAREN - { free($1); } - | DECIMAL_NUMBER - ; -VHDL_Tap_Signals : VHDL_Tap_Signal - | VHDL_Tap_Signals VHDL_Tap_Signal - ; -VHDL_Tap_Signal : VHDL_Tap_Scan_In - | VHDL_Tap_Scan_Out - | VHDL_Tap_Scan_Clock - | VHDL_Tap_Scan_Mode - | VHDL_Tap_Scan_Reset - ; -VHDL_Tap_Scan_In : ATTRIBUTE TAP_SCAN_IN OF IDENTIFIER - COLON SIGNAL IS Boolean SEMICOLON - { free($4); } - ; -VHDL_Tap_Scan_Out : ATTRIBUTE TAP_SCAN_OUT OF IDENTIFIER - COLON SIGNAL IS Boolean SEMICOLON - { free($4); } - ; -VHDL_Tap_Scan_Mode : ATTRIBUTE TAP_SCAN_MODE OF IDENTIFIER - COLON SIGNAL IS Boolean SEMICOLON - { free($4); } - ; -VHDL_Tap_Scan_Reset : ATTRIBUTE TAP_SCAN_RESET OF IDENTIFIER - COLON SIGNAL IS Boolean SEMICOLON - { free($4); } - ; -VHDL_Tap_Scan_Clock : ATTRIBUTE TAP_SCAN_CLOCK OF IDENTIFIER COLON SIGNAL - IS LPAREN REAL_NUMBER COMMA Stop RPAREN SEMICOLON - { free($4); free($9); } - ; -Stop : LOW | BOTH - ; -Boolean : TRUE | FALSE - ; -VHDL_Inst_Length : ATTRIBUTE INSTRUCTION_LENGTH OF IDENTIFIER - COLON ENTITY IS DECIMAL_NUMBER SEMICOLON - { - bsdl_set_instruction_length(priv_data, $8); - free($4); - } - ; -VHDL_Inst_Opcode : ATTRIBUTE INSTRUCTION_OPCODE OF IDENTIFIER - COLON ENTITY IS Quoted_String SEMICOLON - { - bsdl_flex_switch_buffer(priv_data->scanner, - priv_data->buffer_for_switch); - } - BSDL_Opcode_Table - { free($4); } - ; -BSDL_Opcode_Table: Opcode_Desc - | BSDL_Opcode_Table COMMA Opcode_Desc - | error - {Print_Error(priv_data, - _("Error in Instruction_Opcode attribute statement")); - BUMP_ERROR; - YYABORT; } - ; -Opcode_Desc : IDENTIFIER LPAREN Binary_Pattern_List RPAREN - { bsdl_add_instruction(priv_data, $1, $3); } - ; +; + +/****************************************************************************/ +BSDL_Pin_Map : PIN_MAP PHYSICAL_PIN_MAP +; + +/****************************************************************************/ +BSDL_Map_String : PIN_MAP_STRING Pin_Mapping + | BSDL_Map_String COMMA Pin_Mapping +; +Pin_Mapping : IDENTIFIER COLON Physical_Pin_Desc + { free( $1 ); } +; +Physical_Pin_Desc : Physical_Pin + | LPAREN Physical_Pin_List RPAREN +; +Physical_Pin_List : Physical_Pin + | Physical_Pin_List COMMA Physical_Pin +; +Physical_Pin : IDENTIFIER + { free( $1 ); } + | IDENTIFIER LPAREN DECIMAL_NUMBER RPAREN + { free( $1 ); } + | DECIMAL_NUMBER +; + +/****************************************************************************/ +BSDL_Tap_Scan_In : TAP_SCAN_IN DECIMAL_NUMBER +; + +/****************************************************************************/ +BSDL_Tap_Scan_Out : TAP_SCAN_OUT DECIMAL_NUMBER +; + +/****************************************************************************/ +BSDL_Tap_Scan_Mode : TAP_SCAN_MODE DECIMAL_NUMBER +; + +/****************************************************************************/ +BSDL_Tap_Scan_Reset : TAP_SCAN_RESET DECIMAL_NUMBER +; + +/****************************************************************************/ +BSDL_Tap_Scan_Clock : TAP_SCAN_CLOCK DECIMAL_NUMBER +; + +/****************************************************************************/ +BSDL_Inst_Length : INSTRUCTION_LENGTH DECIMAL_NUMBER + { priv_data->jtag_ctrl->instr_len = $2; } +; + +/****************************************************************************/ +BSDL_Opcode : INSTRUCTION_OPCODE BSDL_Opcode_Table +; +BSDL_Opcode_Table : Opcode_Desc + | BSDL_Opcode_Table COMMA Opcode_Desc + | error + { + Print_Error( priv_data, + _("Error in Instruction_Opcode attribute statement") ); + BUMP_ERROR; + YYABORT; + } +; +Opcode_Desc : IDENTIFIER LPAREN Binary_Pattern_List RPAREN + { add_instruction( priv_data, $1, $3 ); } +; Binary_Pattern_List : Binary_Pattern - { $$ = $1; } - | Binary_Pattern_List COMMA Binary_Pattern - { - Print_Warning(priv_data, - _("Multiple opcode patterns are not supported, first pattern will be used")); - $$ = $1; - free($3); - } - ; -Binary_Pattern : BINARY_PATTERN - { $$ = $1; } - ; -VHDL_Inst_Details: VHDL_Inst_Detail - | VHDL_Inst_Details VHDL_Inst_Detail - ; -VHDL_Inst_Detail : VHDL_Inst_Capture - | VHDL_Inst_Disable - | VHDL_Inst_Guard - | VHDL_Inst_Private - | VHDL_Register_Access - | VHDL_Inst_Usage - | VHDL_Inst_Sequence - | VHDL_Idcode_Register - | VHDL_Usercode_Register - ; -VHDL_Inst_Capture: ATTRIBUTE INSTRUCTION_CAPTURE OF IDENTIFIER - COLON ENTITY IS Quoted_String SEMICOLON - { - bsdl_flex_switch_buffer(priv_data->scanner, - priv_data->buffer_for_switch); - } - BIN_X_PATTERN - { free($4); free($11); } - ; -VHDL_Inst_Disable: ATTRIBUTE INSTRUCTION_DISABLE OF IDENTIFIER - COLON ENTITY IS Quoted_String SEMICOLON - { - bsdl_flex_switch_buffer(priv_data->scanner, - priv_data->buffer_for_switch); - } - IDENTIFIER - { free($4); free($11); } - ; -VHDL_Inst_Guard : ATTRIBUTE INSTRUCTION_GUARD OF IDENTIFIER - COLON ENTITY IS Quoted_String SEMICOLON - { - bsdl_flex_switch_buffer(priv_data->scanner, - priv_data->buffer_for_switch); - } - IDENTIFIER - { free($4); free($11); } - ; -VHDL_Inst_Private: ATTRIBUTE INSTRUCTION_PRIVATE OF IDENTIFIER - COLON ENTITY IS Quoted_String SEMICOLON - { - bsdl_flex_switch_buffer(priv_data->scanner, - priv_data->buffer_for_switch); - } - Private_Opcode_List - { free($4); } - ; + { $$ = $1; } + | Binary_Pattern_List COMMA Binary_Pattern + { + Print_Warning( priv_data, + _("Multiple opcode patterns are not supported, first pattern will be used") ); + $$ = $1; + free( $3 ); + } +; +Binary_Pattern : BINARY_PATTERN + { $$ = $1; } +; + +/****************************************************************************/ +BSDL_Inst_Capture : INSTRUCTION_CAPTURE BIN_X_PATTERN + { free( $2 ); } +; + +/****************************************************************************/ +BSDL_Inst_Disable : INSTRUCTION_DISABLE IDENTIFIER + { free( $2 ); } +; + +/****************************************************************************/ +BSDL_Inst_Guard : INSTRUCTION_GUARD IDENTIFIER + { free( $2 ); } +; + +/****************************************************************************/ +BSDL_Inst_Private : INSTRUCTION_PRIVATE Private_Opcode_List +; Private_Opcode_List : Private_Opcode - | Private_Opcode_List COMMA Private_Opcode - | error - {Print_Error(priv_data, _("Error in Opcode List")); - BUMP_ERROR; - YYABORT; } - ; -Private_Opcode : IDENTIFIER - { free($1); } - ; -VHDL_Inst_Usage : ATTRIBUTE INSTRUCTION_USAGE OF IDENTIFIER - COLON ENTITY IS Quoted_String SEMICOLON - {/* Syntax of string content to be changed in future */ - free($4); } - ; -VHDL_Inst_Sequence : ATTRIBUTE INSTRUCTION_SEQUENCE OF IDENTIFIER - COLON ENTITY IS Quoted_String SEMICOLON - {/* Syntax of string content to be determined in future */ - free($4); } - ; -VHDL_Idcode_Register: ATTRIBUTE IDCODE_REGISTER OF IDENTIFIER - COLON ENTITY IS Quoted_String SEMICOLON - { - bsdl_flex_switch_buffer(priv_data->scanner, - priv_data->buffer_for_switch); - } - BIN_X_PATTERN - { - bsdl_set_idcode(priv_data, $11); - free($4); - } - ; -VHDL_Usercode_Register: ATTRIBUTE USERCODE_REGISTER OF IDENTIFIER - COLON ENTITY IS Quoted_String SEMICOLON - { - bsdl_flex_switch_buffer(priv_data->scanner, - priv_data->buffer_for_switch); - } - BIN_X_PATTERN - { - bsdl_set_usercode(priv_data, $11); - free($4); - } - ; -VHDL_Register_Access: ATTRIBUTE REGISTER_ACCESS OF IDENTIFIER - COLON ENTITY IS Quoted_String SEMICOLON - { - bsdl_flex_switch_buffer(priv_data->scanner, - priv_data->buffer_for_switch); - } - Register_String - { free($4); } - ; -Register_String : Register_Assoc - | Register_String COMMA Register_Assoc - ; -Register_Assoc : Register_Decl LPAREN Reg_Opcode_List RPAREN - { bsdl_ac_apply_assoc(priv_data); } - ; -Register_Decl : Standard_Reg - { bsdl_ac_set_register(priv_data, $1, 0); } - | IDENTIFIER LBRACKET DECIMAL_NUMBER RBRACKET - { bsdl_ac_set_register(priv_data, $1, $3); } - ; -Standard_Reg : BOUNDARY - { $$ = strdup("BOUNDARY"); } - | BYPASS - { $$ = strdup("BYPASS"); } - | IDCODE - { $$ = strdup("IDCODE"); } - | USERCODE - { $$ = strdup("USERCODE"); } - | DEVICE_ID - { $$ = strdup("DEVICE_ID"); } - ; -Reg_Opcode_List : Reg_Opcode - | Reg_Opcode_List COMMA Reg_Opcode - ; -Standard_Inst : BOUNDARY - { $$ = strdup("BOUNDARY"); } - | BYPASS - { $$ = strdup("BYPASS"); } - | HIGHZ - { $$ = strdup("HIGHZ"); } - | IDCODE - { $$ = strdup("IDCODE"); } - | USERCODE - { $$ = strdup("USERCODE"); } - ; -Reg_Opcode : IDENTIFIER - { bsdl_ac_add_instruction(priv_data, $1); } - | Standard_Inst - { bsdl_ac_add_instruction(priv_data, $1); } - ; -VHDL_Boundary_Details: VHDL_Boundary_Detail - | VHDL_Boundary_Details VHDL_Boundary_Detail - ; -VHDL_Boundary_Detail: VHDL_Boundary_Cells - | VHDL_Boundary_Length - ; -VHDL_Boundary_Cells: ATTRIBUTE BOUNDARY_CELLS OF IDENTIFIER - COLON ENTITY IS Quoted_String SEMICOLON - { - bsdl_flex_switch_buffer(priv_data->scanner, - priv_data->buffer_for_switch); - } - BSDL_Cell_List - { free($4); } - ; -BSDL_Cell_List : BCell_Identifier - | BSDL_Cell_List COMMA BCell_Identifier - ; -BCell_Identifier : IDENTIFIER - { free($1); } - ; -VHDL_Boundary_Length: ATTRIBUTE BOUNDARY_LENGTH OF IDENTIFIER - COLON ENTITY IS DECIMAL_NUMBER SEMICOLON - { - bsdl_set_bsr_length(priv_data, $8); - free($4); - } - ; -VHDL_Boundary_Register: ATTRIBUTE BOUNDARY_REGISTER OF IDENTIFIER - COLON ENTITY IS Quoted_String SEMICOLON - { - bsdl_flex_switch_buffer(priv_data->scanner, - priv_data->buffer_for_switch); - } - BSDL_Cell_Table - { free($4); } - ; -BSDL_Cell_Table : Cell_Entry - | BSDL_Cell_Table COMMA Cell_Entry - | error - {Print_Error(priv_data, _("Error in Boundary Cell description")); - BUMP_ERROR; YYABORT; } - ; -Cell_Entry : DECIMAL_NUMBER LPAREN Cell_Info RPAREN - { bsdl_ci_apply_cell_info(priv_data, $1); } - ; -Cell_Info : Cell_Spec - { bsdl_ci_no_disable(priv_data); } - | Cell_Spec COMMA Disable_Spec - ; -Cell_Spec : IDENTIFIER COMMA Port_Name COMMA Cell_Function - COMMA Safe_Value - { - free($1); - bsdl_ci_set_cell_spec(priv_data, $5, $7); - } - ; -Port_Name : IDENTIFIER - { - bsdl_prt_add_name(priv_data, $1); - bsdl_prt_add_bit(priv_data); - } - | IDENTIFIER LPAREN DECIMAL_NUMBER RPAREN - { - bsdl_prt_add_name(priv_data, $1); - bsdl_prt_add_range(priv_data, $3, $3); - } - | ASTERISK - { - bsdl_prt_add_name(priv_data, strdup("*")); - bsdl_prt_add_bit(priv_data); - } - ; -Cell_Function : INPUT - { $$ = INPUT; } - | OUTPUT2 - { $$ = OUTPUT2; } - | OUTPUT3 - { $$ = OUTPUT3; } - | CONTROL - { $$ = CONTROL; } - | CONTROLR - { $$ = CONTROLR; } - | INTERNAL - { $$ = INTERNAL; } - | CLOCK - { $$ = CLOCK; } - | BIDIR - { $$ = BIDIR; } - | OBSERVE_ONLY - { $$ = OBSERVE_ONLY; } - ; -Safe_Value : IDENTIFIER - { $$ = $1; } - | DECIMAL_NUMBER - { - char *tmp; - tmp = (char *)malloc(2); - snprintf(tmp, 2, "%i", $1); - tmp[1] = '\0'; - $$ = tmp; - } - ; -Disable_Spec : DECIMAL_NUMBER COMMA DECIMAL_NUMBER COMMA Disable_Value - { bsdl_ci_set_cell_spec_disable(priv_data, $1, $3, $5); } - ; -Disable_Value : Z - { $$ = Z; } - | WEAK0 - { $$ = WEAK0; } - | WEAK1 - { $$ = WEAK1; } - | PULL0 - { $$ = PULL0; } - | PULL1 - { $$ = PULL1; } - | KEEPER - { $$ = KEEPER; } - ; -VHDL_Design_Warning: /* Null Statement */ - | ATTRIBUTE DESIGN_WARNING OF IDENTIFIER - COLON ENTITY IS Quoted_String SEMICOLON - { free($4); } - ; -VHDL_Component_Conformance: ATTRIBUTE COMPONENT_CONFORMANCE OF IDENTIFIER - COLON ENTITY IS Quoted_String SEMICOLON - { free($4); } - ; -VHDL_Compliance_Patterns: ATTRIBUTE COMPLIANCE_PATTERNS OF IDENTIFIER - COLON ENTITY IS Quoted_String SEMICOLON - { - bsdl_flex_switch_buffer(priv_data->scanner, - priv_data->buffer_for_switch); - } - BSDL_Compliance_Pattern - { free($4); } - ; + | Private_Opcode_List COMMA Private_Opcode + | error + { + Print_Error( priv_data, _("Error in Opcode List") ); + BUMP_ERROR; + YYABORT; + } +; +Private_Opcode : IDENTIFIER + { free( $1 ); } +; + +/****************************************************************************/ +BSDL_Idcode_Register : IDCODE_REGISTER BIN_X_PATTERN + { priv_data->jtag_ctrl->idcode = $2; } +; + +/****************************************************************************/ +BSDL_Usercode_Register : USERCODE_REGISTER BIN_X_PATTERN + { priv_data->jtag_ctrl->usercode = $2; } +; + +/****************************************************************************/ +BSDL_Register_Access : REGISTER_ACCESS Register_String +; +Register_String : Register_Assoc + | Register_String COMMA Register_Assoc +; +Register_Assoc : Register_Decl LPAREN Reg_Opcode_List RPAREN + { ac_apply_assoc( priv_data ); } +; +Register_Decl : Standard_Reg + { ac_set_register( priv_data, $1, 0 ); } + | IDENTIFIER LBRACKET DECIMAL_NUMBER RBRACKET + { ac_set_register( priv_data, $1, $3 ); } +; +Standard_Reg : BOUNDARY + { $$ = strdup( "BOUNDARY" ); } + | BYPASS + { $$ = strdup( "BYPASS" ); } + | IDCODE + { $$ = strdup( "IDCODE" ); } + | USERCODE + { $$ = strdup( "USERCODE" ); } + | DEVICE_ID + { $$ = strdup( "DEVICE_ID" ); } +; +Reg_Opcode_List : Reg_Opcode + | Reg_Opcode_List COMMA Reg_Opcode +; +Instruction_Name : BYPASS + { $$ = strdup( "BYPASS" ); } + | CLAMP + { $$ = strdup( "CLAMP" ); } + | EXTEST + { $$ = strdup( "EXTEST" ); } + | HIGHZ + { $$ = strdup( "HIGHZ" ); } + | IDCODE + { $$ = strdup( "IDCODE" ); } + | INTEST + { $$ = strdup( "INTEST" ); } + | PRELOAD + { $$ = strdup( "PRELOAD" ); } + | RUNBIST + { $$ = strdup( "RUNBIST" ); } + | SAMPLE + { $$ = strdup( "SAMPLE" ); } + | USERCODE + { $$ = strdup( "USERCODE" ); } + | IDENTIFIER + { $$ = $1; } +; +Reg_Opcode : Instruction_Name + { ac_add_instruction( priv_data, $1 ); } +; + + +/****************************************************************************/ +BSDL_Boundary_Length : BOUNDARY_LENGTH DECIMAL_NUMBER + { priv_data->jtag_ctrl->bsr_len = $2; } +; + +/****************************************************************************/ +BSDL_Boundary_Register : BOUNDARY_REGISTER BSDL_Cell_Table +; +BSDL_Cell_Table : Cell_Entry + | BSDL_Cell_Table COMMA Cell_Entry + | error + {Print_Error( priv_data, _("Error in Boundary Cell description") ); + BUMP_ERROR; YYABORT; } +; +Cell_Entry : DECIMAL_NUMBER LPAREN Cell_Info RPAREN + { ci_append_cell_info( priv_data, $1 ); } +; +Cell_Info : Cell_Spec + { ci_no_disable( priv_data ); } + | Cell_Spec COMMA Disable_Spec +; +Cell_Spec : IDENTIFIER COMMA Port_Name COMMA Cell_Function + COMMA Safe_Value + { + free( $1 ); + ci_set_cell_spec( priv_data, $5, $7 ); + } +; +Port_Name : IDENTIFIER + { + prt_add_name( priv_data, $1 ); + prt_add_bit( priv_data ); + } + | IDENTIFIER LPAREN DECIMAL_NUMBER RPAREN + { + prt_add_name( priv_data, $1 ); + prt_add_range( priv_data, $3, $3 ); + } + | ASTERISK + { + prt_add_name( priv_data, strdup( "*" ) ); + prt_add_bit( priv_data ); + } +; +Cell_Function : INPUT + { $$ = INPUT; } + | OUTPUT2 + { $$ = OUTPUT2; } + | OUTPUT3 + { $$ = OUTPUT3; } + | CONTROL + { $$ = CONTROL; } + | CONTROLR + { $$ = CONTROLR; } + | INTERNAL + { $$ = INTERNAL; } + | CLOCK + { $$ = CLOCK; } + | BIDIR + { $$ = BIDIR; } + | OBSERVE_ONLY + { $$ = OBSERVE_ONLY; } +; +Safe_Value : IDENTIFIER + { $$ = $1; } + | DECIMAL_NUMBER + { + char *tmp; + tmp = (char *)malloc( 2 ); + snprintf( tmp, 2, "%i", $1 ); + tmp[1] = '\0'; + $$ = tmp; + } +; +Disable_Spec : DECIMAL_NUMBER COMMA DECIMAL_NUMBER COMMA Disable_Value + { ci_set_cell_spec_disable( priv_data, $1, $3, $5 ); } +; +Disable_Value : Z + { $$ = Z; } + | WEAK0 + { $$ = WEAK0; } + | WEAK1 + { $$ = WEAK1; } + | PULL0 + { $$ = PULL0; } + | PULL1 + { $$ = PULL1; } + | KEEPER + { $$ = KEEPER; } +; + +/****************************************************************************/ +BSDL_Compliance_Patterns : COMPLIANCE_PATTERNS BSDL_Compliance_Pattern +; BSDL_Compliance_Pattern : LPAREN Physical_Pin_List RPAREN - {bsdl_flex_set_bin_x(priv_data->scanner);} - LPAREN Bin_X_Pattern_List RPAREN - ; + { bsdl_flex_set_bin_x( priv_data->scanner ); } + LPAREN Bin_X_Pattern_List RPAREN +; Bin_X_Pattern_List : BIN_X_PATTERN - { free($1); } + { free( $1 ); } | Bin_X_Pattern_List COMMA BIN_X_PATTERN - { free($3); } - ; -Quoted_String : QUOTED_STRING - {Init_Text(priv_data); - Store_Text(priv_data, $1); - free($1); } - | Quoted_String CONCATENATE QUOTED_STRING - {Store_Text(priv_data, $3); - free($3); } - ; + { free( $3 ); } +; + +/****************************************************************************/ +BSDL_Component_Conformance : COMPONENT_CONFORMANCE STD_1149_1_1990 + { priv_data->jtag_ctrl->conformance = CONF_1990; } + | COMPONENT_CONFORMANCE STD_1149_1_1993 + { priv_data->jtag_ctrl->conformance = CONF_1993; } + | COMPONENT_CONFORMANCE STD_1149_1_2001 + { priv_data->jtag_ctrl->conformance = CONF_2001; } +; +/****************************************************************************/ +ISC_Extension : ISC_Conformance + | ISC_Pin_Behavior + | ISC_Fixed_System_Pins + | ISC_Status + | ISC_Blank_Usercode + | ISC_Security + | ISC_Flow + | ISC_Procedure + | ISC_Action + | ISC_Illegal_Exit +; +/****************************************************************************/ +ISC_Conformance : ISC_CONFORMANCE STD_1532_2001 + | ISC_CONFORMANCE STD_1532_2002 +; +/****************************************************************************/ +ISC_Pin_Behavior : ISC_PIN_BEHAVIOR Pin_Behavior_Option +; +Pin_Behavior_Option : HIGHZ + | CLAMP + | error + { + Print_Error( priv_data, _("Error in ISC_Pin_Behavior Definition") ); + BUMP_ERROR; + YYABORT; + } +; +/****************************************************************************/ +ISC_Fixed_System_Pins : ISC_FIXED_SYSTEM_PINS Fixed_Pin_List +; +Fixed_Pin_List : Port_Id + | Fixed_Pin_List COMMA Port_Id + | error + { + Print_Error( priv_data, _("Error in ISC_Fixed_System_Pins Definition") ); + BUMP_ERROR; + YYABORT; + } +; +Port_Id : IDENTIFIER + { free( $1 ); } + | IDENTIFIER LPAREN DECIMAL_NUMBER RPAREN + { free( $1 ); } +; +/****************************************************************************/ +ISC_Status : ISC_STATUS Status_Modifier IMPLEMENTED +; +Status_Modifier : /* empty */ + | IDENTIFIER + { free( $1 ); } +; +/****************************************************************************/ +ISC_Blank_Usercode : ISC_BLANK_USERCODE BIN_X_PATTERN + { free( $2 ); } +; +/****************************************************************************/ +ISC_Security : ISC_SECURITY Protection_Spec +; +Protection_Spec : Read_Spec COMMA Program_Spec COMMA Erase_Spec COMMA Key_Spec + | error + { + Print_Error( priv_data, _("Error in ISC_Security Definition") ); + BUMP_ERROR; + YYABORT; + } +; +Read_Spec : ISC_DISABLE_READ Bit_Spec +; +Program_Spec : ISC_DISABLE_PROGRAM Bit_Spec +; +Erase_Spec : ISC_DISABLE_ERASE Bit_Spec +; +Key_Spec : ISC_DISABLE_KEY Bit_Range +; +Bit_Spec : ASTERISK + | DECIMAL_NUMBER +; +Bit_Range : ASTERISK + | DECIMAL_NUMBER MINUS DECIMAL_NUMBER +; +/****************************************************************************/ +ISC_Flow : ISC_FLOW Flow_Definition_List +; +Flow_Definition_List : Flow_Definition + | Flow_Definition_List COMMA Flow_Definition +; +Flow_Definition : Flow_Descriptor + | Flow_Descriptor Initialize_Block + | Flow_Descriptor Initialize_Block Repeat_Block + | Flow_Descriptor Initialize_Block Repeat_Block Terminate_Block + | Flow_Descriptor Repeat_Block + | Flow_Descriptor Repeat_Block Terminate_Block + | Flow_Descriptor Terminate_Block + | error + { + Print_Error( priv_data, _("Error in ISC_Flow Definition") ); + BUMP_ERROR; + YYABORT; + } +; +Flow_Descriptor : IDENTIFIER + { free( $1 ); } + | IDENTIFIER Data_Name + { free( $1 ); } + | IDENTIFIER Data_Name UNPROCESSED + { free( $1 ); } + | IDENTIFIER Data_Name UNPROCESSED EXIT_ON_ERROR + { free( $1 ); } + | IDENTIFIER UNPROCESSED + { free( $1 ); } + | IDENTIFIER UNPROCESSED EXIT_ON_ERROR + { free( $1 ); } + | IDENTIFIER EXIT_ON_ERROR + { free( $1 ); } +; +Data_Name : LPAREN Standard_Data_Name RPAREN + | LPAREN IDENTIFIER RPAREN + { free( $2 ); } +; +Standard_Data_Name : ARRAY | USERCODE | SECURITY | IDCODE | PRELOAD +; +Initialize_Block : INITIALIZE Activity_List +; +Repeat_Block : REPEAT DECIMAL_NUMBER Activity_List +; +Terminate_Block : TERMINATE Activity_List +; +Activity_List : Activity_Element + | Activity_List Activity_Element +; +Activity_Element : Activity + | Loop_Block +; +Loop_Block : LOOP Loop_Min_Spec Loop_Max_Spec LPAREN Loop_Activity_List RPAREN +; +Loop_Min_Spec : /* empty */ + | MIN DECIMAL_NUMBER +; +Loop_Max_Spec : MAX DECIMAL_NUMBER +; +Loop_Activity_List : Activity + | Loop_Activity_List Activity +; +Activity : LPAREN Instruction_Name Wait_Specification RPAREN + { free( $2 ); } + | LPAREN Instruction_Name Update_Field_List Wait_Specification RPAREN + { free( $2 ); } + | LPAREN Instruction_Name Wait_Specification Capture_Field_List RPAREN + { free( $2 ); } + | LPAREN Instruction_Name Update_Field_List Wait_Specification Capture_Field_List RPAREN + { free( $2 ); } +; +Update_Field_List : Update_Field + | Update_Field_List COMMA Update_Field +; +Update_Field : DECIMAL_NUMBER + | DECIMAL_NUMBER COLON + { bsdl_flex_set_hex( priv_data->scanner ); } + Data_Expression + { bsdl_flex_set_decimal( priv_data->scanner ); } +; +Data_Expression : HEX_STRING + { free( $1 ); } + | Input_Specifier + | Variable_Expression +; +Variable_Expression : Variable + | Variable_Assignment + | Variable_Update +; +Variable_Assignment : Variable EQUAL + { bsdl_flex_set_hex( priv_data->scanner ); } + HEX_STRING + { + free( $4 ); + bsdl_flex_set_decimal( priv_data->scanner ); + } + | Variable Input_Specifier +; +Variable_Update : Variable Complement_Operator + | Variable Binary_Operator DECIMAL_NUMBER +; +Input_Specifier : Input_Operator + | IO_Operator +; +Capture_Field_List : Capture_Field + | Capture_Field_List COMMA Capture_Field +; +Capture_Field : DECIMAL_NUMBER COLON + { bsdl_flex_set_hex( priv_data->scanner ); } + Capture_Field_Rest + { bsdl_flex_set_decimal( priv_data->scanner ); } +; +Capture_Field_Rest : Capture_Specification + | Capture_Specification CRC_Tag + | Capture_Specification CRC_Tag OST_Tag + | Capture_Specification OST_Tag +; +Capture_Specification : Expected_Data + | Expected_Data Compare_Mask +; +Expected_Data : /* empty */ + | Output_Operator + | Output_Operator Data_Expression + | Data_Expression +; +Compare_Mask : ASTERISK + | ASTERISK Output_Operator + | ASTERISK Output_Operator Data_Expression + | ASTERISK Data_Expression +; +Wait_Specification : WAIT Duration_Specification + | WAIT Duration_Specification MIN + | WAIT Duration_Specification MIN COLON Duration_Specification MAX +; +Duration_Specification : Clock_Cycles + | REAL_NUMBER + { free( $1 ); } + | Clock_Cycles COMMA REAL_NUMBER + { free( $3 ); } +; +Clock_Cycles : Port_Id DECIMAL_NUMBER +; +Variable : DOLLAR IDENTIFIER + { free( $2 ); } +; +Binary_Operator : PLUS + { bsdl_flex_set_decimal( priv_data->scanner ); } + | MINUS + { bsdl_flex_set_decimal( priv_data->scanner ); } + | SH_RIGHT + { bsdl_flex_set_decimal( priv_data->scanner ); } + | SH_LEFT + { bsdl_flex_set_decimal( priv_data->scanner ); } +; +Complement_Operator : TILDE +; +Input_Operator : QUESTION_MARK +; +Output_Operator : EXCLAMATION_MARK +; +IO_Operator : QUESTION_EXCLAMATION +; +CRC_Tag : COLON CRC +; +OST_Tag : COLON OST +; +/****************************************************************************/ +ISC_Procedure : ISC_PROCEDURE Procedure_List +; +Procedure_List : Procedure + | Procedure_List COMMA Procedure +; +Procedure : IDENTIFIER EQUAL LPAREN Flow_Descriptor_List RPAREN + { free( $1 ); } + | IDENTIFIER Data_Name EQUAL LPAREN Flow_Descriptor_List RPAREN + { free( $1 ); } + | error + { + Print_Error( priv_data, _("Error in ISC_Procedure Definition") ); + BUMP_ERROR; + YYABORT; + } +; +Flow_Descriptor_List : Flow_Descriptor + | Flow_Descriptor_List COMMA Flow_Descriptor +; +/****************************************************************************/ +ISC_Action : ISC_ACTION Action_List +; +Action_List : Action + | Action_List COMMA Action +; +Action : IDENTIFIER EQUAL LPAREN Action_Specification_List RPAREN + { free( $1 ); } + | IDENTIFIER Data_Name EQUAL LPAREN Action_Specification_List RPAREN + { free( $1 ); } + | IDENTIFIER PROPRIETARY EQUAL LPAREN Action_Specification_List RPAREN + { free( $1 ); } + | IDENTIFIER Data_Name PROPRIETARY EQUAL LPAREN Action_Specification_List RPAREN + { free( $1 ); } + | error + { + Print_Error( priv_data, _("Error in ISC_Action Definition") ); + BUMP_ERROR; + YYABORT; + } +; +Action_Specification_List : Action_Specification + | Action_Specification_List COMMA Action_Specification +; +Action_Specification : IDENTIFIER + { free( $1 ); } + | IDENTIFIER Data_Name + { free( $1 ); } + | IDENTIFIER Data_Name PROPRIETARY + { free( $1 ); } + | IDENTIFIER Data_Name Option_Specification + { free( $1 ); } + | IDENTIFIER Data_Name PROPRIETARY Option_Specification + { free( $1 ); } + | IDENTIFIER PROPRIETARY + { free( $1 ); } + | IDENTIFIER PROPRIETARY Option_Specification + { free( $1 ); } + | IDENTIFIER Option_Specification + { free( $1 ); } +; +Option_Specification : OPTIONAL | RECOMMENDED +; +/****************************************************************************/ +ISC_Illegal_Exit : ISC_ILLEGAL_EXIT Exit_Instruction_List +; +Exit_Instruction_List : IDENTIFIER + { free( $1 ); } + | Exit_Instruction_List COMMA IDENTIFIER + { free( $3 ); } +; %% /* End rules, begin programs */ /*----------------------------------------------------------------------*/ -static void Init_Text(parser_priv_t *priv_data) +static void Print_Error( bsdl_parser_priv_t *priv_data, const char *Errmess ) { - if (priv_data->len_buffer_for_switch == 0) { - priv_data->buffer_for_switch = (char *)malloc(160); - priv_data->len_buffer_for_switch = 160; - } - priv_data->buffer_for_switch[0] = '\0'; + if (priv_data->jtag_ctrl->debug || (priv_data->jtag_ctrl->mode >= 0)) + bsdl_msg( BSDL_MSG_ERR, _("Line %d, %s.\n"), + priv_data->lineno, + Errmess ); } /*----------------------------------------------------------------------*/ -static void Store_Text(parser_priv_t *priv_data, char *Source) -{ /* Save characters from VHDL string in local string buffer. */ - size_t req_len; - char *SourceEnd; - - SourceEnd = ++Source; /* skip leading '"' */ - while (*SourceEnd && (*SourceEnd != '"') && (*SourceEnd != '\n')) - SourceEnd++; - /* terminate Source string with NUL character */ - *SourceEnd = '\0'; - - req_len = strlen(priv_data->buffer_for_switch) + strlen(Source) + 1; - if (req_len > priv_data->len_buffer_for_switch) { - priv_data->buffer_for_switch = (char *)realloc(priv_data->buffer_for_switch, - req_len); - priv_data->len_buffer_for_switch = req_len; - } - strcat(priv_data->buffer_for_switch, Source); +static void Print_Warning( bsdl_parser_priv_t *priv_data, const char *Warnmess ) +{ + if (priv_data->jtag_ctrl->debug || (priv_data->jtag_ctrl->mode >= 0)) + bsdl_msg( BSDL_MSG_WARN, _("Line %d, %s.\n"), + priv_data->lineno, + Warnmess ); } /*----------------------------------------------------------------------*/ -static void Print_Error(parser_priv_t *priv_data, const char *Errmess) +static void Give_Up_And_Quit( bsdl_parser_priv_t *priv_data ) { - if (priv_data->Reading_Package) - bsdl_msg(BSDL_MSG_ERR, _("In Package %s, Line %d, %s.\n"), - priv_data->Package_File_Name, - bsdl_flex_get_lineno(priv_data->scanner), - Errmess); - else - if (priv_data->jtag_ctrl.debug || (priv_data->jtag_ctrl.mode >= 0)) - bsdl_msg(BSDL_MSG_ERR, _("Line %d, %s.\n"), - bsdl_flex_get_lineno(priv_data->scanner), - Errmess); + //Print_Error( priv_data, "Too many errors" ); + bsdl_flex_stop_buffer( priv_data->scanner ); } /*----------------------------------------------------------------------*/ -static void Print_Warning(parser_priv_t *priv_data, const char *Warnmess) +void yyerror( bsdl_parser_priv_t *priv_data, const char *error_string ) { - if (priv_data->Reading_Package) - bsdl_msg(BSDL_MSG_WARN, _("In Package %s, Line %d, %s.\n"), - priv_data->Package_File_Name, - bsdl_flex_get_lineno(priv_data->scanner), - Warnmess); - else - if (priv_data->jtag_ctrl.debug || (priv_data->jtag_ctrl.mode >= 0)) - bsdl_msg(BSDL_MSG_WARN, _("Line %d, %s.\n"), - bsdl_flex_get_lineno(priv_data->scanner), - Warnmess); } -/*----------------------------------------------------------------------*/ -static void Give_Up_And_Quit(parser_priv_t *priv_data) + + +/***************************************************************************** + * void bsdl_sem_init( bsdl_parser_priv_t *priv ) + * + * Initializes storage elements in the private parser and jtag control + * structures that are used for semantic purposes. + * + * Parameters + * priv : private data container for parser related tasks + * + * Returns + * void + ****************************************************************************/ +static void bsdl_sem_init( bsdl_parser_priv_t *priv ) { - Print_Error(priv_data, "Too many errors"); + jtag_ctrl_t *jc = priv->jtag_ctrl; + + jc->instr_len = -1; + jc->bsr_len = -1; + jc->conformance = CONF_UNKNOWN; + jc->idcode = NULL; + jc->usercode = NULL; + + jc->instr_list = NULL; + + priv->ainfo.next = NULL; + priv->ainfo.reg = NULL; + priv->ainfo.instr_list = NULL; + jc->ainfo_list = NULL; + + priv->tmp_cell_info.next = NULL; + priv->tmp_cell_info.port_name = NULL; + priv->tmp_cell_info.basic_safe_value = NULL; + jc->cell_info_first = NULL; + jc->cell_info_last = NULL; + + priv->tmp_port_desc.names_list = NULL; + priv->tmp_port_desc.next = NULL; } -/*----------------------------------------------------------------------*/ -void yyerror(parser_priv_t *priv_data, const char *error_string) + + +/***************************************************************************** + * void free_instr_list( struct instr_elem *il ) + * + * Deallocates the given list of instr_elem. + * + * Parameters + * il : first instr_elem to deallocate + * + * Returns + * void + ****************************************************************************/ +static void free_instr_list( instr_elem_t *il ) { + if (il) + { + if (il->instr) + free( il->instr ); + if (il->opcode) + free( il->opcode ); + free_instr_list( il->next ); + free( il ); + } } -/*----------------------------------------------------------------------*/ -parser_priv_t *bsdl_parser_init(FILE *f, int mode, int debug) + + +/***************************************************************************** + * void free_ainfo_list( ainfo_elem_t *ai, int free_me ) + * + * Deallocates the given list of ainfo_elem. + * + * Parameters + * ai : first ainfo_elem to deallocate + * free_me : set to 1 to free memory for ai as well + * + * Returns + * void + ****************************************************************************/ +static void free_ainfo_list( ainfo_elem_t *ai, int free_me ) { - parser_priv_t *new_priv; + if (ai) + { + if (ai->reg) + free( ai->reg ); - if (!(new_priv = (parser_priv_t *)malloc(sizeof(parser_priv_t)))) { - bsdl_msg(BSDL_MSG_ERR, _("Out of memory, %s line %i\n"), __FILE__, __LINE__); - return NULL; + free_instr_list( ai->instr_list ); + free_ainfo_list( ai->next, 1 ); + + if (free_me) + free( ai ); } +} - new_priv->jtag_ctrl.mode = mode; - new_priv->jtag_ctrl.debug = debug; - new_priv->Reading_Package = 0; - new_priv->buffer_for_switch = NULL; - new_priv->len_buffer_for_switch = 0; +/***************************************************************************** + * void free_string_list( string_elem_t *sl ) + * + * Deallocates the given list of string_elem items. + * + * Parameters + * sl : first string_elem to deallocate + * + * Returns + * void + ****************************************************************************/ +static void free_string_list( string_elem_t *sl) +{ + if (sl) + { + if (sl->string) + free( sl->string ); + free_string_list( sl->next ); + free( sl ); + } +} + - if (!(new_priv->scanner = bsdl_flex_init(f, mode, debug))) { +/***************************************************************************** + * void free_c_list( cell_info_t *ci, int free_me ) + * + * Deallocates the given list of cell_info items. + * + * Parameters + * ci : first cell_info item to deallocate + * free_me : 1 -> free memory for *ci as well + * 0 -> don't free *ci memory + * + * Returns + * void + ****************************************************************************/ +static void free_ci_list( cell_info_t *ci, int free_me ) +{ + if (ci) + { + free_ci_list( ci->next, 1 ); + + if (ci->port_name) + free( ci->port_name ); + + if (ci->basic_safe_value) + free( ci->basic_safe_value ); + + if (free_me) + free( ci ); + } +} + + +/***************************************************************************** + * void bsdl_sem_deinit( bsdl_parser_priv_t *priv ) + * + * Frees and deinitializes storage elements in the private parser and + * jtag control structures that were filled by semantic rules. + * + * Parameters + * priv : private data container for parser related tasks + * + * Returns + * void + ****************************************************************************/ +static void bsdl_sem_deinit( bsdl_parser_priv_t *priv ) +{ + jtag_ctrl_t *jc = priv->jtag_ctrl; + + if (jc->idcode) + { + free( jc->idcode ); + jc->idcode = NULL; + } + + if (jc->usercode) + { + free( jc->usercode ); + jc->usercode = NULL; + } + + /* free cell_info list */ + free_ci_list( jc->cell_info_first, 1 ); + jc->cell_info_first = jc->cell_info_last = NULL; + free_ci_list( &(priv->tmp_cell_info), 0 ); + + /* free instr_list */ + free_instr_list( jc->instr_list ); + jc->instr_list = NULL; + + /* free ainfo_list */ + free_ainfo_list( jc->ainfo_list, 1 ); + jc->ainfo_list = NULL; + free_ainfo_list( &(priv->ainfo), 0 ); + + /* free string list in temporary port descritor */ + free_string_list( priv->tmp_port_desc.names_list ); + priv->tmp_port_desc.names_list = NULL; +} + + +/***************************************************************************** + * bsdl_parser_priv_t *bsdl_parser_init( jtag_ctrl_t *jtag_ctrl ) + * + * Initializes storage elements in the private parser structure that are + * used for parser maintenance purposes. + * Subsequently calls initializer functions for the scanner and the semantic + * parts. + * + * Parameters + * jtag_ctrl : pointer to jtag control structure + * + * Returns + * pointer to private parser structure + ****************************************************************************/ +bsdl_parser_priv_t *bsdl_parser_init( jtag_ctrl_t *jtag_ctrl ) +{ + bsdl_parser_priv_t *new_priv; + + if (!(new_priv = (bsdl_parser_priv_t *)malloc( sizeof( bsdl_parser_priv_t ) ))) { + bsdl_msg( BSDL_MSG_ERR, _("Out of memory, %s line %i\n"), __FILE__, __LINE__ ); + return NULL; + } + + new_priv->jtag_ctrl = jtag_ctrl; + + if (!(new_priv->scanner = bsdl_flex_init( jtag_ctrl->mode, jtag_ctrl->debug ))) { free(new_priv); new_priv = NULL; } - bsdl_sem_init(new_priv); + bsdl_sem_init( new_priv ); return new_priv; } -/*----------------------------------------------------------------------*/ -void bsdl_parser_deinit(parser_priv_t *priv_data) + + +/***************************************************************************** + * void bsdl_parser_deinit( bsdl_parser_priv_t *priv ) + * + * Frees storage elements in the private parser structure that are + * used for parser maintenance purposes. + * Subsequently calls deinitializer functions for the scanner and the semantic + * parts. + * + * Parameters + * priv : private data container for parser related tasks + * + * Returns + * void + ****************************************************************************/ +void bsdl_parser_deinit( bsdl_parser_priv_t *priv_data ) { - bsdl_sem_deinit(priv_data); - bsdl_flex_deinit(priv_data->scanner); - free(priv_data); + bsdl_sem_deinit( priv_data ); + bsdl_flex_deinit( priv_data->scanner ); + free( priv_data ); } + + +/***************************************************************************** + * void add_instruction( bsdl_parser_priv_t *priv, char *instr, char *opcode ) + * + * Converts the instruction specification into a member of the main + * list of instructions at priv->jtag_ctrl->instr_list. + * + * Parameters + * priv : private data container for parser related tasks + * instr : instruction name + * opcode : instruction opcode + * + * Returns + * void + ****************************************************************************/ +static void add_instruction( bsdl_parser_priv_t *priv, char *instr, char *opcode ) +{ + instr_elem_t *new_instr; + + new_instr = (instr_elem_t *)malloc( sizeof( instr_elem_t ) ); + if (new_instr) + { + new_instr->next = priv->jtag_ctrl->instr_list; + new_instr->instr = instr; + new_instr->opcode = opcode; + + priv->jtag_ctrl->instr_list = new_instr; + } + else + bsdl_msg( BSDL_MSG_FATAL, _("Out of memory, %s line %i\n"), __FILE__, __LINE__ ); +} + + +/***************************************************************************** + * void ac_set_register( bsdl_parser_priv_t *priv, char *reg, int reg_len ) + * Register Access management function + * + * Stores the register specification values for the current register access + * specification in the temporary storage region for later usage. + * + * Parameters + * priv : private data container for parser related tasks + * reg : register name + * reg_len : optional register length + * + * Returns + * void + ****************************************************************************/ +static void ac_set_register( bsdl_parser_priv_t *priv, char *reg, int reg_len ) +{ + ainfo_elem_t *tmp_ai = &(priv->ainfo); + + tmp_ai->reg = reg; + tmp_ai->reg_len = reg_len; +} + + +/***************************************************************************** + * void ac_add_instruction( bsdl_parser_priv_t *priv, char *instr ) + * Register Access management function + * + * Appends the specified instruction to the list of instructions for the + * current register access specification in the temporary storage region + * for later usage. + * + * Parameters + * priv : private data container for parser related tasks + * instr : instruction name + * + * Returns + * void + ****************************************************************************/ +static void ac_add_instruction( bsdl_parser_priv_t *priv, char *instr ) +{ + ainfo_elem_t *tmp_ai = &(priv->ainfo); + instr_elem_t *new_instr; + + new_instr = (instr_elem_t *)malloc( sizeof( instr_elem_t ) ); + if (new_instr) + { + new_instr->next = tmp_ai->instr_list; + new_instr->instr = instr; + new_instr->opcode = NULL; + + tmp_ai->instr_list = new_instr; + } + else + bsdl_msg( BSDL_MSG_FATAL, _("Out of memory, %s line %i\n"), __FILE__, __LINE__ ); +} + + +/***************************************************************************** + * void ac_apply_assoc( bsdl_parser_priv_t *priv ) + * Register Access management function + * + * Appends the collected register access specification from the temporary + * storage region to the main ainfo list. + * + * Parameters + * priv : private data container for parser related tasks + * + * Returns + * void + ****************************************************************************/ +static void ac_apply_assoc( bsdl_parser_priv_t *priv ) +{ + jtag_ctrl_t *jc = priv->jtag_ctrl; + ainfo_elem_t *tmp_ai = &(priv->ainfo); + ainfo_elem_t *new_ai; + + new_ai = (ainfo_elem_t *)malloc( sizeof( ainfo_elem_t ) ); + if (new_ai) + { + new_ai->next = jc->ainfo_list; + new_ai->reg = tmp_ai->reg; + new_ai->reg_len = tmp_ai->reg_len; + new_ai->instr_list = tmp_ai->instr_list; + + jc->ainfo_list = new_ai; + } + else + bsdl_msg( BSDL_MSG_FATAL, _("Out of memory, %s line %i\n"), __FILE__, __LINE__ ); + + /* clean up obsolete temporary entries */ + tmp_ai->reg = NULL; + tmp_ai->reg_len = 0; + tmp_ai->instr_list = NULL; +} + + +/***************************************************************************** + * void prt_add_name( bsdl_parser_priv_t *priv, char *name ) + * Port name management function + * + * Sets the name field of the temporary storage area for port description + * (port_desc) to the parameter name. + * + * Parameters + * priv : private data container for parser related tasks + * name : base name of the port, memory get's free'd lateron + * + * Returns + * void + ****************************************************************************/ +static void prt_add_name( bsdl_parser_priv_t *priv, char *name ) +{ + port_desc_t *pd = &(priv->tmp_port_desc); + string_elem_t *new_string; + + new_string = (string_elem_t *)malloc( sizeof( string_elem_t ) ); + if (new_string) + { + new_string->next = pd->names_list; + new_string->string = name; + + pd->names_list = new_string; + } + else + bsdl_msg( BSDL_MSG_FATAL, _("Out of memory, %s line %i\n"), __FILE__, __LINE__ ); +} + + +/***************************************************************************** + * void prt_add_bit( bsdl_parser_priv_t *priv ) + * Port name management function + * + * Sets the vector and index fields of the temporary storage area for port + * description (port_desc) to non-vector information. The low and high indice + * are set to equal numbers (exact value is irrelevant). + * + * Parameters + * priv : private data container for parser related tasks + * + * Returns + * void + ****************************************************************************/ +static void prt_add_bit( bsdl_parser_priv_t *priv ) +{ + port_desc_t *pd = &(priv->tmp_port_desc); + + pd->is_vector = 0; + pd->low_idx = 0; + pd->high_idx = 0; +} + + +/***************************************************************************** + * void prt_add_range( bsdl_parser_priv_t *priv, int low, int high ) + * Port name management function + * + * Sets the vector and index fields of the temporary storage area for port + * description (port_desc) to the specified vector information. + * + * Parameters + * priv : private data container for parser related tasks + * low : low index of vector + * high : high index of vector + * + * Returns + * void + ****************************************************************************/ +static void prt_add_range( bsdl_parser_priv_t *priv, int low, int high ) +{ + port_desc_t *pd = &(priv->tmp_port_desc); + + pd->is_vector = 1; + pd->low_idx = low; + pd->high_idx = high; +} + + +/***************************************************************************** + * void ci_no_disable( bsdl_parser_priv_t *priv ) + * Cell Info management function + * + * Tracks that there is no disable term for the current cell info. + * + * Parameters + * priv : private data container for parser related tasks + * + * Returns + * void + ****************************************************************************/ +static void ci_no_disable( bsdl_parser_priv_t *priv ) +{ + priv->tmp_cell_info.ctrl_bit_num = -1; +} + + +/***************************************************************************** + * void ci_set_cell_spec_disable( bsdl_parser_priv_t *priv, int ctrl_bit_num, + * int safe_value, int disable_value ) + * Cell Info management function + * + * Applies the disable specification of the current cell spec to the variables + * for temporary storage of these information elements. + * + * Parameters + * priv : private data container for parser related tasks + * ctrl_bit_num : bit number of related control cell + * safe_value : safe value for initialization of this cell + * disable_value : currently ignored + * + * Returns + * void + ****************************************************************************/ +static void ci_set_cell_spec_disable( bsdl_parser_priv_t *priv, int ctrl_bit_num, + int safe_value, int disable_value ) +{ + cell_info_t *ci = &(priv->tmp_cell_info); + + ci->ctrl_bit_num = ctrl_bit_num; + ci->disable_safe_value = safe_value; + /* disable value is ignored at the moment */ +} + + +/***************************************************************************** + * void ci_set_cell_spec( bsdl_parser_priv_t *priv, + * int function, char *safe_value ) + * Cell Info management function + * + * Sets the specified values of the current cell_spec (without disable term) + * to the variables for temporary storage of these information elements. + * The name of the related port is taken from the port_desc structure that + * was filled in previously by the rule Port_Name. + * + * Parameters + * priv : private data container for parser related tasks + * function : cell function indentificator + * safe_value : safe value for initialization of this cell + * + * Returns + * void + ****************************************************************************/ +static void ci_set_cell_spec( bsdl_parser_priv_t *priv, + int function, char *safe_value ) +{ + cell_info_t *ci = &(priv->tmp_cell_info); + port_desc_t *pd = &(priv->tmp_port_desc); + string_elem_t *name = priv->tmp_port_desc.names_list; + char *port_string; + size_t str_len, name_len; + + ci->cell_function = function; + ci->basic_safe_value = safe_value; + + /* handle indexed port name: + - names of scalar ports are simply copied from the port_desc structure + to the final string that goes into ci + - names of vectored ports are expanded with their decimal index as + collected earlier earlier in rule Port_Name + */ + name_len = strlen( name->string ); + str_len = name_len + 1 + 10 + 1 + 1; + if ((port_string = (char *)malloc( str_len )) != NULL) + { + if (pd->is_vector) + snprintf( port_string, str_len-1, "%s(%d)", name->string, pd->low_idx ); + else + strncpy( port_string, name->string, str_len-1 ); + port_string[str_len-1] = '\0'; + + ci->port_name = port_string; + } + else + { + bsdl_msg( BSDL_MSG_FATAL, _("Out of memory, %s line %i\n"), __FILE__, __LINE__ ); + ci->port_name = NULL; + } + + free_string_list( priv->tmp_port_desc.names_list ); + priv->tmp_port_desc.names_list = NULL; +} + + +/***************************************************************************** + * void ci_append_cell_info( bsdl_parser_priv_t *priv, int bit_num ) + * Cell Info management function + * + * Appends the temporary cell info to the global list of cell infos. + * + * Parameters + * priv : private data container for parser related tasks + * bit_num : bit number of current cell + * + * Returns + * void + ****************************************************************************/ +static void ci_append_cell_info( bsdl_parser_priv_t *priv, int bit_num ) +{ + cell_info_t *tmp_ci = &(priv->tmp_cell_info); + cell_info_t *ci; + jtag_ctrl_t *jc = priv->jtag_ctrl; + + ci = (cell_info_t *)malloc( sizeof( cell_info_t ) ); + if (ci) + { + ci->next = NULL; + if (jc->cell_info_last) + jc->cell_info_last->next = ci; + else + jc->cell_info_first = ci; + jc->cell_info_last = ci; + + ci->bit_num = bit_num; + ci->port_name = tmp_ci->port_name; + ci->cell_function = tmp_ci->cell_function; + ci->basic_safe_value = tmp_ci->basic_safe_value; + ci->ctrl_bit_num = tmp_ci->ctrl_bit_num; + ci->disable_safe_value = tmp_ci->disable_safe_value; + + tmp_ci->port_name = NULL; + tmp_ci->basic_safe_value = NULL; + } + else + bsdl_msg( BSDL_MSG_FATAL, _("Out of memory, %s line %i\n"), __FILE__, __LINE__ ); +} + + +/* + Local Variables: + mode:C + c-default-style:gnu + indent-tabs-mode:nil + End: +*/ diff --git a/jtag/src/bsdl/bsdl_flex.l b/jtag/src/bsdl/bsdl_flex.l index 48b34a9f..78607ac4 100644 --- a/jtag/src/bsdl/bsdl_flex.l +++ b/jtag/src/bsdl/bsdl_flex.l @@ -129,16 +129,23 @@ LEGAL NOTICES: #include "bsdl_sysdep.h" +#include "bsdl_msg.h" + #include "bsdl_bison.h" -#include "bsdl_local.h" +#include "bsdl_parser.h" + +#ifdef DMALLOC +#include "dmalloc.h" +#endif #define YY_EXTRA_TYPE scan_extra_t * -static char *new_string(const char *); +static char *new_string( const char * ); #define BINARY 0 #define DECIMAL 1 #define BIN_X 2 +#define HEX 3 %} %a 2800 @@ -147,95 +154,68 @@ static char *new_string(const char *); %n 520 %k 140 %o 3000 -%START RES BOU REG PAC +%START RES BOU REG PAC ISC White [ \t\b\r]* VHDL_Comment \-\-[^\n]* Binary_Pattern [0-1]+ Bin_X_Pattern [0-1X]+ +Hex_String [0-9A-F]+ Digit [0-9] Exponent [E][+-]?{Digit}+ Real_Number {Digit}+[\.]{Digit}+{Exponent} Decimal_Number {Digit}+ Identifier [A-Z][A-Z0-9_]* -Quoted_String \"[^\"\n]*\" -Concatenate & -Single_Quote [\'] -Semicolon ; Eol [\n] Comma [,] Lparen [\(] Rparen [\)] Lbracket [\[] Rbracket [\]] -Colon_Equal \:\= Colon [\:] -Period [\.] Asterisk [\*] -Box [\<][\>] -Illegal [^A-Z0-9 \t\b\n\r\"\&\'\*\(\)\[\]\_\:\.\,\;\<\>] -Entity ENTITY -Port PORT -Generic GENERIC -Use USE -Attribute ATTRIBUTE -Is IS -Of OF +Dollar [\$] +Equal [\=] +Plus [\+] +Minus [\-] +Sh_Right [\>][\>] +Sh_Left [\<][\<] +Tilde [\~] +Question_Exclamation [\?][\!] +Question [\?] +Exclamation [\!] +Illegal [^A-Z0-9 \t\b\n\r\"\&\'\*\(\)\[\]\_\:\.\,\;\$\=\+\-\>\<\~\?\!] Constant CONSTANT -String STRING -End END -All ALL Physical_Pin_Map PHYSICAL_PIN_MAP Pin_Map PIN_MAP Pin_Map_String PIN_MAP_STRING -True TRUE -False FALSE -Signal SIGNAL Tap_Scan_In TAP_SCAN_IN Tap_Scan_Out TAP_SCAN_OUT Tap_Scan_Clock TAP_SCAN_CLOCK Tap_Scan_Mode TAP_SCAN_MODE Tap_Scan_Reset TAP_SCAN_RESET -Low LOW -Both BOTH -Out OUT -Inout INOUT -In IN -Buffer BUFFER -Linkage LINKAGE -Bit_Vector BIT_VECTOR -Bit BIT -To TO -Downto DOWNTO -Package PACKAGE -Body BODY -Type TYPE -Subtype SUBTYPE -Record RECORD -Array ARRAY -Positive POSITIVE -Range RANGE -Cell_Info CELL_INFO Instruction_Length INSTRUCTION_LENGTH Instruction_Opcode INSTRUCTION_OPCODE Instruction_Capture INSTRUCTION_CAPTURE Instruction_Disable INSTRUCTION_DISABLE Instruction_Guard INSTRUCTION_GUARD Instruction_Private INSTRUCTION_PRIVATE -Instruction_Usage INSTRUCTION_USAGE -Instruction_Sequence INSTRUCTION_SEQUENCE Register_Access REGISTER_ACCESS -Boundary_Cells BOUNDARY_CELLS Boundary_Length BOUNDARY_LENGTH Boundary_Register BOUNDARY_REGISTER Idcode_Register IDCODE_REGISTER Usercode_Register USERCODE_REGISTER -Design_Warning DESIGN_WARNING Boundary BOUNDARY Bypass BYPASS +Clamp CLAMP +Extest EXTEST Highz HIGHZ Idcode IDCODE -Device_Id DEVICE_ID +Intest INTEST +Preload PRELOAD +Runbist RUNBIST +Sample SAMPLE Usercode USERCODE +Device_Id DEVICE_ID Input INPUT Output2 OUTPUT2 Output3 OUTPUT3 @@ -253,185 +233,219 @@ Weak1 WEAK1 Pull0 PULL0 Pull1 PULL1 Keeper KEEPER -Extest EXTEST -Sample SAMPLE -Intest INTEST -Runbist RUNBIST -Pi PI -Po PO -Upd UPD -Cap CAP -X X -Zero ZERO -One ONE -Component_Conformance COMPONENT_CONFORMANCE -Port_Grouping PORT_GROUPING -Runbist_Execution RUNBIST_EXECUTION -Intest_Execution INTEST_EXECUTION -Bsdl_Extension BSDL_EXTENSION Compliance_Patterns COMPLIANCE_PATTERNS +Component_Conformance COMPONENT_CONFORMANCE +Std_1149_1_1990 STD_1149_1_1990 +Std_1149_1_1993 STD_1149_1_1993 +Std_1149_1_2001 STD_1149_1_2001 +ISC_Conformance ISC_CONFORMANCE +Std_1532_2001 STD_1532_2001 +Std_1532_2002 STD_1532_2002 +ISC_Pin_Behavior ISC_PIN_BEHAVIOR +ISC_Fixed_System_Pins ISC_FIXED_SYSTEM_PINS +ISC_Status ISC_STATUS +Implemented IMPLEMENTED +ISC_Blank_Usercode ISC_BLANK_USERCODE +ISC_Security ISC_SECURITY +ISC_Disable_Read ISC_DISABLE_READ +ISC_Disable_Program ISC_DISABLE_PROGRAM +ISC_Disable_Erase ISC_DISABLE_ERASE +ISC_Disable_Key ISC_DISABLE_KEY +ISC_Flow ISC_FLOW +Unprocessed UNPROCESSED +Exit_On_Error EXIT_ON_ERROR +Array ARRAY +Security SECURITY +Initialize INITIALIZE +Repeat REPEAT +Terminate TERMINATE +Loop LOOP +Wait WAIT +Min MIN +Max MAX +Crc CRC +Ost OST +ISC_Procedure ISC_PROCEDURE +ISC_Action ISC_ACTION +Proprierary PROPRIETARY +Optional OPTIONAL +Recommended RECOMMENDED +ISC_Illegal_Exit ISC_ILLEGAL_EXIT %% -{Entity} {return(ENTITY); } -{Port} {yyextra->Base = DECIMAL; /* Default number base */ - return(PORT); } -{Generic} {yyextra->Base = DECIMAL; return(GENERIC); } -{Use} {yyextra->Base = DECIMAL; return(USE); } -{Attribute} {yyextra->Base = DECIMAL; return(ATTRIBUTE); } -{Is} {return(IS); } -{Constant} {yyextra->Base = DECIMAL; return(CONSTANT); } -{String} {return(STRING); } -{End} {yyextra->Base = DECIMAL; - BEGIN INITIAL; /* Turn off start conditions */ - return(END); } -{All} {return(ALL); } -{Of} {return(OF); } -{Pin_Map} {return(PIN_MAP); } -{Physical_Pin_Map} {return(PHYSICAL_PIN_MAP); } -{Pin_Map_String} {return(PIN_MAP_STRING); } -{True} {return(TRUE); } -{False} {return(FALSE); } -{Signal} {return(SIGNAL); } -{Tap_Scan_In} {return(TAP_SCAN_IN); } -{Tap_Scan_Out} {return(TAP_SCAN_OUT); } -{Tap_Scan_Clock} {return(TAP_SCAN_CLOCK); } -{Tap_Scan_Mode} {return(TAP_SCAN_MODE); } -{Tap_Scan_Reset} {return(TAP_SCAN_RESET); } -{Low} {return(LOW); } -{Both} {return(BOTH); } -{In} {return(IN); } -{Out} {return(OUT); } -{Inout} {return(INOUT); } -{Buffer} {return(BUFFER); } -{Linkage} {return(LINKAGE); } -{Bit} {return(BIT); } -{Bit_Vector} {return(BIT_VECTOR); } -{To} {return(TO); } -{Downto} {return(DOWNTO); } -{Package} {return(PACKAGE); } -{Body} {return(BODY); } -{Type} {return(TYPE); } -{Subtype} {return(SUBTYPE); } -{Record} {return(RECORD); } -{Array} {yyextra->Base = DECIMAL; return(ARRAY); } -{Positive} {return(POSITIVE); } -{Range} {return(RANGE); } -{Cell_Info} {BEGIN PAC; return(CELL_INFO); } -{Instruction_Length} {return(INSTRUCTION_LENGTH); } +{Constant} {yyextra->Base = DECIMAL; return( CONSTANT ); } +{Pin_Map} {return( PIN_MAP ); } +{Physical_Pin_Map} {return( PHYSICAL_PIN_MAP ); } +{Pin_Map_String} {return( PIN_MAP_STRING ); } +{Tap_Scan_In} {return( TAP_SCAN_IN ); } +{Tap_Scan_Out} {return( TAP_SCAN_OUT ); } +{Tap_Scan_Clock} {return( TAP_SCAN_CLOCK ); } +{Tap_Scan_Mode} {return( TAP_SCAN_MODE ); } +{Tap_Scan_Reset} {return( TAP_SCAN_RESET ); } +{Instruction_Length} {yyextra->Base = DECIMAL; return( INSTRUCTION_LENGTH ); } {Instruction_Opcode} {yyextra->Base = BINARY; /* Enable Binary Patterns */ - return(INSTRUCTION_OPCODE); } + return( INSTRUCTION_OPCODE ); } {Instruction_Capture} {yyextra->Base = BIN_X; /* Enable Bin_X Patterns */ - return(INSTRUCTION_CAPTURE); } -{Instruction_Disable} {return(INSTRUCTION_DISABLE); } -{Instruction_Guard} {return(INSTRUCTION_GUARD); } -{Instruction_Private} {return(INSTRUCTION_PRIVATE); } -{Instruction_Usage} {return(INSTRUCTION_USAGE); } -{Instruction_Sequence} {return(INSTRUCTION_SEQUENCE); } -{Register_Access} {BEGIN REG; return(REGISTER_ACCESS); } -{Boundary_Cells} {return(BOUNDARY_CELLS); } -{Boundary_Length} {return(BOUNDARY_LENGTH); } -{Boundary_Register} {BEGIN BOU; return(BOUNDARY_REGISTER); } -{Idcode_Register} {yyextra->Base = BIN_X; return(IDCODE_REGISTER); } -{Usercode_Register} {yyextra->Base = BIN_X; return(USERCODE_REGISTER); } -{Design_Warning} {return(DESIGN_WARNING); } -{Component_Conformance} {return(COMPONENT_CONFORMANCE); } -{Port_Grouping} {return(PORT_GROUPING); } -{Runbist_Execution} {return(RUNBIST_EXECUTION); } -{Intest_Execution} {return(INTEST_EXECUTION); } -{Bsdl_Extension} {return(BSDL_EXTENSION); } -{Compliance_Patterns} {yyextra->Base = DECIMAL; return(COMPLIANCE_PATTERNS); } -{Boundary} {return(BOUNDARY); } -{Bypass} {return(BYPASS); } -{Highz} {return(HIGHZ); } -{Idcode} {return(IDCODE); } -{Usercode} {return(USERCODE); } -{Device_Id} {return(DEVICE_ID); } -{Input} {return(INPUT); } -{Output2} {return(OUTPUT2); } -{Output3} {return(OUTPUT3); } -{Controlr} {return(CONTROLR); } -{Control} {return(CONTROL); } -{Internal} {return(INTERNAL); } -{Clock} {return(CLOCK); } -{Observe_Only} {return(OBSERVE_ONLY); } -{Bidir} {return(BIDIR); } -{Bidir_In} {return(BIDIR_IN); } -{Bidir_Out} {return(BIDIR_OUT); } -{Extest} {return(EXTEST); } -{Sample} {return(SAMPLE); } -{Intest} {return(INTEST); } -{Runbist} {return(RUNBIST); } -{Pi} {return(PI); } -{Po} {return(PO); } -{Upd} {return(UPD); } -{Cap} {return(CAP); } -{X} {return(X); } -{Zero} {return(ZERO); } -{One} {return(ONE); } -{Z} {return(Z); } -{Weak0} {return(WEAK0); } -{Weak1} {return(WEAK1); } -{Pull0} {return(PULL0); } -{Pull1} {return(PULL1); } -{Keeper} {return(KEEPER); } + return( INSTRUCTION_CAPTURE ); } +{Instruction_Disable} {return( INSTRUCTION_DISABLE ); } +{Instruction_Guard} {return( INSTRUCTION_GUARD ); } +{Instruction_Private} {return( INSTRUCTION_PRIVATE ); } +{Register_Access} {BEGIN(REG); yyextra->Base = DECIMAL; + return( REGISTER_ACCESS ); } +{Boundary_Length} {return( BOUNDARY_LENGTH ); } +{Boundary_Register} {BEGIN(BOU); yyextra->Base = DECIMAL; + return( BOUNDARY_REGISTER ); } +{Idcode_Register} {yyextra->Base = BIN_X; return( IDCODE_REGISTER ); } +{Usercode_Register} {yyextra->Base = BIN_X; return( USERCODE_REGISTER ); } +{Compliance_Patterns} {yyextra->Base = DECIMAL; return( COMPLIANCE_PATTERNS ); } +{Component_Conformance} {return( COMPONENT_CONFORMANCE ); } +{Std_1149_1_1990} {return( STD_1149_1_1990 ); } +{Std_1149_1_1993} {return( STD_1149_1_1993 ); } +{Std_1149_1_2001} {return( STD_1149_1_2001 ); } +{ISC_Conformance} {yyextra->Base = DECIMAL; return( ISC_CONFORMANCE ); } +{Std_1532_2001} {return( STD_1532_2001 ); } +{Std_1532_2002} {return( STD_1532_2002 ); } +{ISC_Pin_Behavior} {BEGIN(ISC); yyextra->Base = DECIMAL; return( ISC_PIN_BEHAVIOR ); } +{ISC_Fixed_System_Pins} {yyextra->Base = DECIMAL; return( ISC_FIXED_SYSTEM_PINS ); } +{ISC_Status} {yyextra->Base = DECIMAL; return( ISC_STATUS ); } +{Implemented} {return( IMPLEMENTED ); } +{ISC_Blank_Usercode} {yyextra->Base = BIN_X; return( ISC_BLANK_USERCODE ); } +{ISC_Security} {yyextra->Base = DECIMAL; return( ISC_SECURITY ); } +{ISC_Disable_Read} {yyextra->Base = DECIMAL; return( ISC_DISABLE_READ ); } +{ISC_Disable_Program} {yyextra->Base = DECIMAL; return( ISC_DISABLE_PROGRAM ); } +{ISC_Disable_Erase} {yyextra->Base = DECIMAL; return( ISC_DISABLE_ERASE ); } +{ISC_Disable_Key} {yyextra->Base = DECIMAL; return( ISC_DISABLE_KEY ); } +{ISC_Flow} {yyextra->Base = DECIMAL; return( ISC_FLOW ); } +{Unprocessed} {return( UNPROCESSED ); } +{Exit_On_Error} {return( EXIT_ON_ERROR ); } +{Array} {return( ARRAY ); } +{Security} {return( SECURITY ); } +{Preload} {return( PRELOAD ); } +{Initialize} {return( INITIALIZE ); } +{Repeat} {yyextra->Base = DECIMAL; return( REPEAT ); } +{Terminate} {return( TERMINATE ); } +{Loop} {return( LOOP ); } +{Wait} {return( WAIT ); } +{Min} {return( MIN ); } +{Max} {return( MAX ); } +{Crc} {return( CRC ); } +{Ost} {return( OST ); } +{Dollar} {return( DOLLAR ); } +{Equal} {return( EQUAL ); } +{Plus} {return( PLUS ); } +{Minus} {return( MINUS ); } +{Sh_Right} {return( SH_RIGHT ); } +{Sh_Left} {return( SH_LEFT ); } +{Tilde} {return( TILDE ); } +{Question_Exclamation} {return( QUESTION_EXCLAMATION ); } +{Question} {return( QUESTION_MARK ); } +{Exclamation} {return( EXCLAMATION_MARK ); } +{ISC_Procedure} {yyextra->Base = DECIMAL; return( ISC_PROCEDURE ); } +{ISC_Action} {yyextra->Base = DECIMAL; return( ISC_ACTION ); } +{Proprierary} {return( PROPRIETARY ); } +{Optional} {return( OPTIONAL ); } +{Recommended} {return( RECOMMENDED ); } +{ISC_Illegal_Exit} {return( ISC_ILLEGAL_EXIT ); } +{Bypass} {return( BYPASS ); } +{Boundary} {return( BOUNDARY ); } +{Clamp} {return( CLAMP ); } +{Extest} {return( EXTEST ); } +{Highz} {return( HIGHZ ); } +{Idcode} {return( IDCODE ); } +{Intest} {return( INTEST ); } +{Preload} {return( PRELOAD ); } +{Runbist} {return( RUNBIST ); } +{Sample} {return( SAMPLE ); } +{Usercode} {return( USERCODE ); } +{Device_Id} {return( DEVICE_ID ); } +{Input} {return( INPUT ); } +{Output2} {return( OUTPUT2 ); } +{Output3} {return( OUTPUT3 ); } +{Controlr} {return( CONTROLR ); } +{Control} {return( CONTROL ); } +{Internal} {return( INTERNAL ); } +{Clock} {return( CLOCK ); } +{Observe_Only} {return( OBSERVE_ONLY ); } +{Bidir} {return( BIDIR ); } +{Bidir_In} {return( BIDIR_IN ); } +{Bidir_Out} {return( BIDIR_OUT ); } +{Z} {return( Z ); } +{Weak0} {return( WEAK0 ); } +{Weak1} {return( WEAK1 ); } +{Pull0} {return( PULL0 ); } +{Pull1} {return( PULL1 ); } +{Keeper} {return( KEEPER ); } {Eol} {yylineno++; /* Count lines */} -{Comma} {return(COMMA); } -{Lparen} {return(LPAREN);} -{Rparen} {return(RPAREN);} -{Period} {return(PERIOD); } -{Lbracket} {return(LBRACKET); } -{Rbracket} {return(RBRACKET); } -{Colon} {return(COLON); } -{Asterisk} {return(ASTERISK); } -{Box} {return(BOX); } -{Single_Quote} {yyextra->Base = BIN_X; return(SINGLE_QUOTE); } -{Colon_Equal} {return(COLON_EQUAL); } +{Comma} {return( COMMA ); } +{Lparen} {return( LPAREN );} +{Rparen} {return( RPAREN );} +{Lbracket} {return( LBRACKET ); } +{Rbracket} {return( RBRACKET ); } +{Colon} {return( COLON ); } +{Asterisk} {return( ASTERISK ); } {White} { /* Do Nothing on White Space */ } {VHDL_Comment} { /* Do Nothing on Comments */ } {Bin_X_Pattern} {if (yyextra->Base != BIN_X) REJECT; - yylval->str = new_string(yytext); - return(BIN_X_PATTERN);} -{Identifier} {yylval->str = new_string(yytext); - return(IDENTIFIER); } -{Quoted_String} {yylval->str = new_string(yytext); - return(QUOTED_STRING); } + yylval->str = new_string( yytext ); + return( BIN_X_PATTERN );} +{Hex_String} {if (yyextra->Base != HEX) REJECT; + yylval->str = new_string( yytext ); + return( HEX_STRING );} +{Identifier} {yylval->str = new_string( yytext ); + return( IDENTIFIER ); } {Binary_Pattern} {if (yyextra->Base != BINARY) REJECT; - yylval->str = new_string(yytext); - return(BINARY_PATTERN);} + yylval->str = new_string( yytext ); + return( BINARY_PATTERN );} {Decimal_Number} {if (yyextra->Base != DECIMAL) REJECT; - yylval->integer = atoi((char *)yytext); - return(DECIMAL_NUMBER);} -{Real_Number} {yylval->str = new_string(yytext); - return(REAL_NUMBER);} -{Concatenate} {return(CONCATENATE);} -{Semicolon} {return(SEMICOLON);} + yylval->integer = atoi( (char *)yytext ); + return( DECIMAL_NUMBER );} +{Real_Number} {yylval->str = new_string( yytext ); + return( REAL_NUMBER );} {Illegal} {if (yyextra->debug || (yyextra->mode >= 0)) - bsdl_msg(BSDL_MSG_ERR, - _("Illegal character %c (/%03o) at line %d:\n"), - (char)yytext[yyleng-1], (int)yytext[yyleng-1], - yylineno); + bsdl_msg( BSDL_MSG_ERR, + _("Illegal character %c (/%03o) at line %d:\n"), + (char)yytext[yyleng-1], (int)yytext[yyleng-1], + yylineno ); yyextra->Compile_Errors++; - return(ILLEGAL); /* Will cause syntax error */} + return( ILLEGAL ); /* Will cause syntax error */} <> { - yypop_buffer_state(yyscanner); + yypop_buffer_state( yyscanner ); if ( !YY_CURRENT_BUFFER ) yyterminate(); } %% -void *bsdl_flex_init(FILE *f, int mode, int debug) +/***************************************************************************** + * void *bsdl_flex_init( int mode, int debug ) + * + * Initializes the scanner and storage elements extra data structure. + * + * Parameters + * mode : -1 -> read file + * no further action based on components + * 0 -> read file and extract all components + * dump commands to stdout, do not execute commands + * 1 -> read file and extract all components + * execute commands + * debug : 1 -> emit failure messages + * 0 -> no failure messages + * + * Returns + * pointer to newly initialized scanner structure + ****************************************************************************/ +void *bsdl_flex_init( int mode, int debug ) { scan_extra_t *extra; yyscan_t scanner; /* get our scanner structure */ - if (yylex_init(&scanner) != 0) { - bsdl_msg(BSDL_MSG_FATAL, _("Scanner could not be initialized\n") ); + if (yylex_init(&scanner) != 0) + { + bsdl_msg( BSDL_MSG_FATAL, _("Scanner could not be initialized\n") ); return NULL; } - yyset_in(f, scanner); - if (!(extra = (scan_extra_t *)malloc(sizeof(scan_extra_t)))) { - bsdl_msg(BSDL_MSG_FATAL, _("Out of memory, %s line %i\n"), __FILE__, __LINE__); - yylex_destroy(scanner); + if (!(extra = (scan_extra_t *)malloc( sizeof( scan_extra_t ) ))) { + bsdl_msg( BSDL_MSG_FATAL, _("Out of memory, %s line %i\n"), __FILE__, __LINE__ ); + yylex_destroy( scanner ); return NULL; } @@ -440,142 +454,252 @@ void *bsdl_flex_init(FILE *f, int mode, int debug) extra->Compile_Errors = 0; extra->Base = DECIMAL; - yyset_extra(extra, scanner); + yyset_extra( extra, scanner ); return scanner; } -void bsdl_flex_deinit(void *scanner) + +/***************************************************************************** + * void bsdl_flex_deinit( void *scanner ) + * + * Deinitializes the scanner and closes the input file. + * + * Parameters + * scanner : pointer to scanner definition structure + * + * Returns + * void + ****************************************************************************/ +void bsdl_flex_deinit( void *scanner ) { - if (yyget_in(scanner)) { + if (yyget_in( scanner )) + { /* file might still be open so close it in any case e.g. when a compile error occured and the parser didn't hit EOF/yywrap() */ - fclose(yyget_in(scanner)); - yyset_in(NULL, scanner); + fclose( yyget_in( scanner ) ); + yyset_in( NULL, scanner ); } - free(yyget_extra(scanner)); - yylex_destroy(scanner); + free( yyget_extra( scanner ) ); + yylex_destroy( scanner ); } -int yywrap(yyscan_t scanner) +/***************************************************************************** + * void yywrap( yyscan_t scanner ) + * + * Closes the input file upon EOF condition. + * + * Parameters + * scanner : pointer to scanner definition structure + * + * Returns + * 1 + ****************************************************************************/ +int yywrap( yyscan_t scanner ) { - if (yyget_in(scanner)) { - fclose(yyget_in(scanner)); - yyset_in(NULL, scanner); + if (yyget_in( scanner )) { + fclose( yyget_in( scanner ) ); + yyset_in( NULL, scanner ); } - return(1); + return 1; } -static char *new_string(const char *str) +/***************************************************************************** + * char *new_string( const char *str ) + * + * Allocates memory for a string and copies the contents of *str. + * + * Parameters + * str : pointer to string to be duplicated + * + * Returns + * pointer to allocated and initialized string memory + ****************************************************************************/ +static char *new_string( const char *str ) { char *n_str; size_t n_str_size; - n_str_size = strlen(str) + 1; - if ((n_str = (char *)malloc(n_str_size))) { - strncpy(n_str, str, n_str_size-1); + n_str_size = strlen( str ) + 1; + if ((n_str = (char *)malloc( n_str_size ))) + { + strncpy( n_str, str, n_str_size-1 ); n_str[n_str_size-1] = '\0'; /* set very last element to EOS */ - } else + } + else bsdl_msg(BSDL_MSG_FATAL, _("Out of memory, %s line %i\n"), __FILE__, __LINE__); return(n_str); } -void bsdl_flex_switch_file(yyscan_t scanner, char *filename) -{ - scan_extra_t *extra; - FILE *f; - char *s; - - /* convert filename to all upper case */ - s = filename; - while (*s) { - if (islower(*s)) - *s = toupper(*s); - s++; - } - - /* file in current directory has precedence */ - f = fopen(filename, "r"); - if (!f) { - const char *db_path = jtag_get_data_dir(); - char *db_file; - - if ((db_file = (char *)malloc(strlen(db_path) + - 1 + /* "/" */ - 4 + /* "bsdl" */ - 1 + /* "/" */ - strlen(filename) + - 1))) { - strcpy(db_file, db_path); - strcat(db_file, "/"); - strcat(db_file, "bsdl"); - strcat(db_file, "/"); - strcat(db_file, filename); - f = fopen(db_file, "r"); - - if (!f) - bsdl_msg(BSDL_MSG_FATAL, _("Cannot open file %s or %s.\n"), filename, db_file); - free(db_file); - if (!f) - return; - } - } - - yypush_buffer_state(yy_create_buffer(f, YY_BUF_SIZE, scanner), scanner); - extra = yyget_extra(scanner); - yyset_lineno(1, scanner); -} - -void bsdl_flex_switch_buffer(yyscan_t scanner, const char *buffer) +/***************************************************************************** + * void bsdl_flex_switch_buffer( yyscan_t scanner, const char *buffer, int lineno ) + * + * Selects the specified string buffer for further scanning. + * + * Parameters + * scanner : pointer to scanner definition structure + * buffer : pointer to string buffer to be scanned + * lineno : initial line number offset + * + * Returns + * void + ****************************************************************************/ +void bsdl_flex_switch_buffer( yyscan_t scanner, const char *buffer, int lineno ) { /* ugly, ulgy, ugly prepare yyg for later use of YY_CURRENT_BUFFER */ struct yyguts_t * yyg = (struct yyguts_t*)scanner; - int lineno; - lineno = yyget_lineno(scanner); /* yy_scan_string() switches to the string buffer internally, so we must save the current buffer state explicitly by pushing the stack and setting top of stack to the current buffer state again. yy_scan_string() can then savely switch YY_CURRENT_BUFFER to the string buffer. yypop_buffer_state() will delete the string buffer afterwards and pop the saved current buffer state. */ - yypush_buffer_state(YY_CURRENT_BUFFER, scanner); - yy_scan_string(buffer, scanner); - yyset_lineno(lineno, scanner); + yypush_buffer_state( YY_CURRENT_BUFFER, scanner ); + yy_scan_string( buffer, scanner ); + yyset_lineno( lineno, scanner ); } -int bsdl_flex_get_compile_errors(yyscan_t scanner) + +/***************************************************************************** + * void bsdl_flex_stop_buffer( yyscan_t scanner ) + * + * Removes the current buffer from the scanner stack. + * + * Parameters + * scanner : pointer to scanner definition structure + * + * Returns + * void + ****************************************************************************/ +void bsdl_flex_stop_buffer( yyscan_t scanner ) +{ + yypop_buffer_state( scanner ); +// if ( !YY_CURRENT_BUFFER ) +// yyterminate(); +} + + +/***************************************************************************** + * int bsdl_flex_get_compile_errors( yyscan_t scanner ) + * + * Retrieves the accumulated number of compile errors encountered so far. + * + * Parameters + * scanner : pointer to scanner definition structure + * + * Returns + * number of compile errors + ****************************************************************************/ +int bsdl_flex_get_compile_errors( yyscan_t scanner ) { - scan_extra_t *extra = yyget_extra(scanner); + scan_extra_t *extra = yyget_extra( scanner ); return extra->Compile_Errors; } -static void bsdl_flex_set_compile_errors(int n, yyscan_t scanner) + +/***************************************************************************** + * void bsdl_flex_set_compile_errors( int n, yyscan_t scanner ) + * + * Sets the number of compile errors to n. + * + * Parameters + * n : preset number + * scanner : pointer to scanner definition structure + * + * Returns + * void + ****************************************************************************/ +static void bsdl_flex_set_compile_errors( int n, yyscan_t scanner ) { - scan_extra_t *extra = yyget_extra(scanner); + scan_extra_t *extra = yyget_extra( scanner ); extra->Compile_Errors = n; } -int bsdl_flex_postinc_compile_errors(yyscan_t scanner) + +/***************************************************************************** + * int bsdl_flex_postinc_compile_errors( yyscan_t scanner ) + * + * Increments the number of compile errors. + * + * Parameters + * scanner : pointer to scanner definition structure + * + * Returns + * number of compile errors before increment + ****************************************************************************/ +int bsdl_flex_postinc_compile_errors( yyscan_t scanner ) { - int errors = bsdl_flex_get_compile_errors(scanner); + int errors = bsdl_flex_get_compile_errors( scanner ); - bsdl_flex_set_compile_errors(errors+1, scanner); + bsdl_flex_set_compile_errors( errors+1, scanner ); return errors; } -int bsdl_flex_get_lineno(yyscan_t scanner) + +/***************************************************************************** + * void bsdl_flex_set_bin_x( yyscan_t scanner ) + * + * Selects BIN_X mode for pattern matching. + * + * Parameters + * scanner : pointer to scanner definition structure + * + * Returns + * void + ****************************************************************************/ +void bsdl_flex_set_bin_x( yyscan_t scanner ) +{ + scan_extra_t *extra = yyget_extra( scanner ); + extra->Base = BIN_X; +} + + +/***************************************************************************** + * void bsdl_flex_set_hex( yyscan_t scanner ) + * + * Selects HEX mode for pattern matching. + * + * Parameters + * scanner : pointer to scanner definition structure + * + * Returns + * void + ****************************************************************************/ +void bsdl_flex_set_hex( yyscan_t scanner ) { - return yyget_lineno(scanner); + scan_extra_t *extra = yyget_extra( scanner ); + extra->Base = HEX; } -void bsdl_flex_set_bin_x(yyscan_t scanner) + +/***************************************************************************** + * void bsdl_flex_set_decimal( yyscan_t scanner ) + * + * Selects DECIMAL mode for pattern matching. + * + * Parameters + * scanner : pointer to scanner definition structure + * + * Returns + * void + ****************************************************************************/ +void bsdl_flex_set_decimal( yyscan_t scanner ) { - scan_extra_t *extra = yyget_extra(scanner); - extra->Base = BIN_X; + scan_extra_t *extra = yyget_extra( scanner ); + extra->Base = DECIMAL; } + + +/* + Local Variables: + mode:C + c-default-style:gnu + indent-tabs-mode:nil + End: +*/ diff --git a/jtag/src/bsdl/bsdl_local.h b/jtag/src/bsdl/bsdl_local.h deleted file mode 100644 index 7d1ca4da..00000000 --- a/jtag/src/bsdl/bsdl_local.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - * $Id$ - * - * Copyright (C) 2007, Arnim Laeuger - * - * This program is free software; you can redistribute it and/or - * modify it 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. - * - * Written by Arnim Laeuger , 2007. - * - */ - -#ifndef BSDL_LOCAL_H -#define BSDL_LOCAL_H - -#include - - -/* message types for bsdl_msg() */ -#define BSDL_MSG_NOTE 0 -#define BSDL_MSG_WARN 1 -#define BSDL_MSG_ERR 2 -#define BSDL_MSG_FATAL 3 - - -/* private data of the flex scanner - handled internally in bsdl_flex.l as yyextra */ -struct scan_extra { - int mode; - int debug; - int Compile_Errors; - int Base; -}; -typedef struct scan_extra scan_extra_t; - - -/* list of instructions - the instruction name and its opcode (optional) is stored here */ -struct instr_elem { - struct instr_elem *next; - char *instr; - char *opcode; -}; - -/* register access information - * derived from the entries of the REGISTER_ACCESS attribute - * ainfo_elem describes a register and its accosiated instructions - * - register name - * - register length (optional) - * - list of associated instructions - */ -struct ainfo_elem { - struct ainfo_elem *next; - char *reg; - int reg_len; - struct instr_elem *instr_list; -}; - -/* the access_data structure is the entry point into the register access - management data - it contains the pointer to the main list of REGISTER_ACCESS entries plus - components that store temporary data while an entry is parser/built */ -struct access_data { - struct ainfo_elem *ainfo_list; - /* temporary private data for building the "current" access info entry */ - char *reg; - int reg_len; - struct instr_elem *instr_list; -}; - -/* structure cell_info collects bit/cell information from the - BOUNDARY_REGISTER attribute - each Cell_Entry fills in the structure and the contents is used for the - respective 'bit' command */ -struct cell_info { - /* basic cell spec entries */ - int bit_num; - char *port_name; - int cell_function; - char *basic_safe_value; - /* the disable spec entries */ - int ctrl_bit_num; - int disable_safe_value; -}; - -/* structure string_elem enables to build lists of strings */ -struct string_elem { - struct string_elem *next; - char *string; -}; - -/* structure port_desc contains all descriptive information for a port - definition: - - one or more names - - flag showing whether it's a vector (element) or a scalar - - low and high indice if it's a vector */ -struct port_desc { - struct string_elem *names_list; - int is_vector; - int low_idx; - int high_idx; -}; - -/* structure jtag_ctrl collects all elements that are required to interface - with jtag internals */ -struct jtag_ctrl { - int mode; - int debug; - char *idcode; /* IDCODE string */ - chain_t *chain; - part_t *part; - struct port_desc port_desc; - struct cell_info cell_info; - struct instr_elem *instr_list; - struct access_data access_data; -}; - -/* private data of the bison parser - used to store variables the would end up as globals otherwise */ -struct parser_priv { - char Package_File_Name[100]; - int Reading_Package; - char *buffer_for_switch; - size_t len_buffer_for_switch; - void *scanner; - struct jtag_ctrl jtag_ctrl; -}; -typedef struct parser_priv parser_priv_t; - - -void bsdl_msg(int, const char *, ...); - -/* BSDL lexer declarations */ -void *bsdl_flex_init(FILE *, int, int); -void bsdl_flex_deinit(void *); -void bsdl_flex_switch_file(void *, char *); -void bsdl_flex_switch_buffer(void *, const char *); -int bsdl_flex_get_compile_errors(void *); -int bsdl_flex_postinc_compile_errors(void *); -int bsdl_flex_get_lineno(void *); -void bsdl_flex_set_bin_x(void *); - -/* BSDL parser declarations */ -parser_priv_t *bsdl_parser_init(FILE *, int, int); -void bsdl_parser_deinit(parser_priv_t *); -int bsdlparse(parser_priv_t *); - -/* BSDL / JTAG semantic action interface */ -void bsdl_sem_init(parser_priv_t *); -void bsdl_sem_deinit(parser_priv_t *); -void bsdl_set_entity(parser_priv_t *, char *); -void bsdl_set_instruction_length(parser_priv_t *, int); -void bsdl_prt_add_name(parser_priv_t *, char *); -void bsdl_prt_add_bit(parser_priv_t *); -void bsdl_prt_add_range(parser_priv_t *, int, int); -void bsdl_prt_apply_port(parser_priv_t *); -void bsdl_set_idcode(parser_priv_t *, char *); -void bsdl_set_usercode(parser_priv_t *, char *); -void bsdl_add_instruction(parser_priv_t *, char *, char *); -void bsdl_set_bsr_length(parser_priv_t *, int); -void bsdl_ci_no_disable(parser_priv_t *); -void bsdl_ci_set_cell_spec(parser_priv_t *, int, char *); -void bsdl_ci_set_cell_spec_disable(parser_priv_t *, int, int, int); -void bsdl_ci_apply_cell_info(parser_priv_t *, int); -void bsdl_ac_set_register(parser_priv_t *, char *, int); -void bsdl_ac_add_instruction(parser_priv_t *, char *); -void bsdl_ac_apply_assoc(parser_priv_t *); -void bsdl_ac_finalize(parser_priv_t *); - -#endif /* BSDL_LOCAL_H */ diff --git a/jtag/src/bsdl/bsdl_msg.h b/jtag/src/bsdl/bsdl_msg.h new file mode 100644 index 00000000..11f4a967 --- /dev/null +++ b/jtag/src/bsdl/bsdl_msg.h @@ -0,0 +1,36 @@ +/* + * $Id$ + * + * Copyright (C) 2008, Arnim Laeuger + * + * This program is free software; you can redistribute it and/or + * modify it 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. + * + * Written by Arnim Laeuger , 2007. + * + */ + +#ifndef BSDL_MSG_H +#define BSDL_MSG_H + +/* message types for bsdl_msg() */ +#define BSDL_MSG_NOTE 0 +#define BSDL_MSG_WARN 1 +#define BSDL_MSG_ERR 2 +#define BSDL_MSG_FATAL 3 + +void bsdl_msg( int, const char *, ... ); + +#endif /* BSDL_MSG_H */ diff --git a/jtag/src/bsdl/bsdl_parser.h b/jtag/src/bsdl/bsdl_parser.h new file mode 100644 index 00000000..33ebda69 --- /dev/null +++ b/jtag/src/bsdl/bsdl_parser.h @@ -0,0 +1,49 @@ +/* + * $Id$ + * + * Copyright (C) 2008, Arnim Laeuger + * + * This program is free software; you can redistribute it and/or + * modify it 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. + * + * Written by Arnim Laeuger , 2008. + * + */ + +#ifndef BSDL_PARSER_H +#define BSDL_PARSER_H + +#include "bsdl_types.h" + +/* VHDL lexer declarations */ +void *bsdl_flex_init( int, int ); +void bsdl_flex_deinit( void * ); +void bsdl_flex_set_bin_x( void * ); +void bsdl_flex_set_hex( void * ); +void bsdl_flex_set_decimal( void * ); +int bsdl_flex_get_compile_errors( void * ); +int bsdl_flex_postinc_compile_errors( void * ); +void bsdl_flex_switch_buffer( void *, const char *, int ); +void bsdl_flex_stop_buffer( void * ); + +/* BSDL parser declarations */ +bsdl_parser_priv_t *bsdl_parser_init( jtag_ctrl_t * ); +void bsdl_parser_deinit( bsdl_parser_priv_t * ); +int bsdlparse( bsdl_parser_priv_t * ); + +/* BSDL semantic functions */ +int bsdl_sem_process_elements( bsdl_parser_priv_t * ); + +#endif /* BSDL_PARSER_H */ diff --git a/jtag/src/bsdl/bsdl_sem.c b/jtag/src/bsdl/bsdl_sem.c index 6cc7655c..578f2c7f 100644 --- a/jtag/src/bsdl/bsdl_sem.c +++ b/jtag/src/bsdl/bsdl_sem.c @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) 2007, Arnim Laeuger + * Copyright (C) 2008, Arnim Laeuger * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -34,9 +34,15 @@ #include "bsdl_sysdep.h" +#include "bsdl_types.h" +#include "bsdl_msg.h" + +#include "bsdl_parser.h" #include "bsdl_bison.h" -#include "bsdl_local.h" +#ifdef DMALLOC +#include "dmalloc.h" +#endif /***************************************************************************** * void print_cmd(char **cmd) @@ -63,269 +69,40 @@ static void print_cmd(char **cmd) /***************************************************************************** - * void bsdl_sem_init(parser_priv_t *priv) - * - * Performs initialization of data structures for the semantic action - * routines. - * - * Parameters - * priv : private data container for parser related tasks - * - * Returns - * void - ****************************************************************************/ -void bsdl_sem_init(parser_priv_t *priv) -{ - struct access_data *ad = &(priv->jtag_ctrl.access_data); - struct port_desc *pd = &(priv->jtag_ctrl.port_desc); - - ad->ainfo_list = NULL; - ad->instr_list = NULL; - - pd->names_list = NULL; - - priv->jtag_ctrl.instr_list = NULL; -} - - -/***************************************************************************** - * void free_instr_list(struct instr_elem *il) - * - * Deallocates the given list of instr_elem. - * - * Parameters - * il : first instr_elem to deallocate - * - * Returns - * void - ****************************************************************************/ -static void free_instr_list(struct instr_elem *il) -{ - if (il) { - if (il->instr) - free(il->instr); - if (il->opcode) - free(il->opcode); - free_instr_list(il->next); - free(il); - } -} - - -/***************************************************************************** - * void free_ainfo_list(struct ainfo_elem *ai) - * - * Deallocates the given list of ainfo_elem. - * - * Parameters - * ai : first ainfo_elem to deallocate - * - * Returns - * void - ****************************************************************************/ -static void free_ainfo_list(struct ainfo_elem *ai) -{ - if (ai) { - if (ai->reg) - free(ai->reg); - free_instr_list(ai->instr_list); - free_ainfo_list(ai->next); - free(ai); - } -} - - -/***************************************************************************** - * void free_string_list(struct string_elem *sl) - * - * Deallocates the given list of string_elem. - * - * Parameters - * sl : first string_elem to deallocate - * - * Returns - * void - ****************************************************************************/ -static void free_string_list(struct string_elem *sl) -{ - if (sl) { - if (sl->string) - free(sl->string); - free_string_list(sl->next); - free(sl); - } -} - - -/***************************************************************************** - * void bsdl_sem_deinit(parser_priv_t *priv) - * - * Performs deinitialization of data structures for the semantic action - * routines. - * - * Parameters - * priv : private data container for parser related tasks - * - * Returns - * void - ****************************************************************************/ -void bsdl_sem_deinit(parser_priv_t *priv) -{ - struct access_data *ad = &(priv->jtag_ctrl.access_data); - struct port_desc *pd = &(priv->jtag_ctrl.port_desc); - - if (ad->ainfo_list) { - free_ainfo_list(ad->ainfo_list); - ad->ainfo_list = NULL; - } - - if (priv->jtag_ctrl.instr_list) { - free_instr_list(priv->jtag_ctrl.instr_list); - priv->jtag_ctrl.instr_list = NULL; - } - - if (pd->names_list) { - free_string_list(pd->names_list); - pd->names_list = NULL; - } -} - - -/***************************************************************************** - * void bsdl_set_entity(parser_priv_t *priv, char *entityname) + * void bsdl_set_instruction_length( jtag_ctrl_t *jc ) * - * Applies the entity name from BSDL as the part name. + * Sets the specified length of the instruction register via shell command + * instruction length * * Parameters - * priv : private data container for parser related tasks - * entityname : entity name string, memory gets free'd + * jc : jtag control structure * * Returns * void ****************************************************************************/ -void bsdl_set_entity(parser_priv_t *priv, char *entityname) -{ - if (priv->jtag_ctrl.mode >= 1) { - strncpy(priv->jtag_ctrl.part->part, entityname, MAXLEN_PART); - priv->jtag_ctrl.part->part[MAXLEN_PART] = '\0'; - } - - free(entityname); -} - - -/***************************************************************************** - * void bsdl_set_instruction_length(parser_priv_t *priv, int len) - * - * Sets the specified length of the instruction register via shell command - * instruction length - * - * Parameters - * priv : private data container for parser related tasks - * len : number of bits (= length) of instruction register - ****************************************************************************/ -void bsdl_set_instruction_length(parser_priv_t *priv, int len) +static void bsdl_set_instruction_length( jtag_ctrl_t *jc ) { - if (priv->jtag_ctrl.mode >= 0) { + if (jc->mode >= 0) + { char lenstring[6]; char *cmd[] = {"instruction", "length", lenstring, NULL}; - snprintf(lenstring, 6, "%i", len); + snprintf( lenstring, 6, "%i", jc->instr_len ); lenstring[5] = '\0'; - if (priv->jtag_ctrl.mode >= 1) - cmd_run(priv->jtag_ctrl.chain, cmd); + if (jc->mode >= 1) + cmd_run( jc->chain, cmd ); else - print_cmd(cmd); + print_cmd( cmd ); } } /***************************************************************************** - * void bsdl_prt_add_name(parser_priv_t *priv, char *name) - * Port name management function - * - * Sets the name field of the temporary storage area for port description - * (port_desc) to the parameter name. - * - * Parameters - * priv : private data container for parser related tasks - * name : base name of the port, memory get's free'd lateron - * - * Returns - * void - ****************************************************************************/ -void bsdl_prt_add_name(parser_priv_t *priv, char *name) -{ - struct port_desc *pd = &(priv->jtag_ctrl.port_desc); - struct string_elem *new_string; - - new_string = (struct string_elem *)malloc(sizeof(struct string_elem)); - if (new_string) { - new_string->next = pd->names_list; - new_string->string = name; - - pd->names_list = new_string; - } else - bsdl_msg(BSDL_MSG_FATAL, _("Out of memory, %s line %i\n"), __FILE__, __LINE__); -} - - -/***************************************************************************** - * void bsdl_prt_add_bit(parser_priv_t *priv) - * Port name management function - * - * Sets the vector and index fields of the temporary storage area for port - * description (port_desc) to non-vector information. The low and high indice - * are set to equal numbers (exact value is irrelevant). - * - * Parameters - * priv : private data container for parser related tasks - * - * Returns - * void - ****************************************************************************/ -void bsdl_prt_add_bit(parser_priv_t *priv) -{ - struct port_desc *pd = &(priv->jtag_ctrl.port_desc); - - pd->is_vector = 0; - pd->low_idx = 0; - pd->high_idx = 0; -} - - -/***************************************************************************** - * void bsdl_prt_add_range(parser_priv_t *priv, int low, int high) - * Port name management function - * - * Sets the vector and index fields of the temporary storage area for port - * description (port_desc) to the specified vector information. - * - * Parameters - * priv : private data container for parser related tasks - * low : low index of vector - * high : high index of vector - * - * Returns - * void - ****************************************************************************/ -void bsdl_prt_add_range(parser_priv_t *priv, int low, int high) -{ - struct port_desc *pd = &(priv->jtag_ctrl.port_desc); - - pd->is_vector = 1; - pd->low_idx = low; - pd->high_idx = high; -} - - -/***************************************************************************** - * void bsdl_prt_apply_port(parser_priv_t *priv) - * Port name management function + * void bsdl_emit_ports( jtag_ctrl_t *jc ) * * Adds the specified port name as a signal via shell command * signal @@ -336,16 +113,16 @@ void bsdl_prt_add_range(parser_priv_t *priv, int low, int high) * (there's a names_list in port_desc). * * Parameters - * priv : private data container for parser related tasks + * jc : jtag control structure * * Returns * void ****************************************************************************/ -void bsdl_prt_apply_port(parser_priv_t *priv) +static void bsdl_emit_ports(jtag_ctrl_t *jc) { - struct port_desc *pd = &(priv->jtag_ctrl.port_desc); + port_desc_t *pd = jc->port_desc; - if (priv->jtag_ctrl.mode >= 0) { + if (jc->mode >= 0) { char *cmd[] = {"signal", NULL, NULL}; @@ -354,64 +131,67 @@ void bsdl_prt_apply_port(parser_priv_t *priv) char *port_string; int idx; - name = pd->names_list; - while (name) { - /* handle indexed port name: - - names of scalar ports are simply copied from the port_desc structure - to the final string that goes into ci - - names of vectored ports are expanded with their decimal index as - collected earlier in rule Scalar_or_Vector - */ - name_len = strlen(name->string); - str_len = name_len + 1 + 10 + 1 + 1; - if ((port_string = (char *)malloc(str_len)) != NULL) { - cmd[1] = port_string; - - for (idx = pd->low_idx; idx <= pd->high_idx; idx++) { - if (pd->is_vector) - snprintf(port_string, str_len-1, "%s(%d)", name->string, idx); - else - strncpy(port_string, name->string, str_len-1); - port_string[str_len-1] = '\0'; - - if (priv->jtag_ctrl.mode >= 1) - cmd_run(priv->jtag_ctrl.chain, cmd); - else - print_cmd(cmd); + while (pd) + { + name = pd->names_list; + while (name) { + /* handle indexed port name: + - names of scalar ports are simply copied from the port_desc structure + to the final string that goes into ci + - names of vectored ports are expanded with their decimal index as + collected earlier in rule Scalar_or_Vector + */ + name_len = strlen( name->string ); + str_len = name_len + 1 + 10 + 1 + 1; + if ((port_string = (char *)malloc( str_len )) != NULL) + { + cmd[1] = port_string; + + for (idx = pd->low_idx; idx <= pd->high_idx; idx++) + { + if (pd->is_vector) + snprintf( port_string, str_len-1, "%s(%d)", name->string, idx ); + else + strncpy( port_string, name->string, str_len-1 ); + port_string[str_len-1] = '\0'; + + if (jc->mode >= 1) + cmd_run( jc->chain, cmd ); + else + print_cmd( cmd ); + } + + free( port_string ); } + else + bsdl_msg( BSDL_MSG_FATAL, _("Out of memory, %s line %i\n"), __FILE__, __LINE__ ); - free(port_string); - } else - bsdl_msg(BSDL_MSG_FATAL, _("Out of memory, %s line %i\n"), __FILE__, __LINE__); + name = name->next; + } - name = name->next; + pd = pd->next; } } - - if (pd->names_list) { - free_string_list(pd->names_list); - pd->names_list = NULL; - } } /***************************************************************************** - * void create_register(parser_priv_t *priv, char *reg_name, size_t len) + * void create_register( jtag_ctrl_t *jc, char *reg_name, size_t len ) * * Generic function to create a jtag register via shell command * register * * Parameters - * priv : private data container for parser related tasks + * jc : jtag control structure * reg_name : name of the new register * len : number of bits (= length) of new register * * Returns * void ****************************************************************************/ -static void create_register(parser_priv_t *priv, char *reg_name, size_t len) +static void create_register( jtag_ctrl_t *jc, char *reg_name, size_t len) { - if (priv->jtag_ctrl.mode >= 0) { + if (jc->mode >= 0) { const size_t str_len = 10; char len_str[str_len+1]; char *cmd[] = {"register", @@ -419,235 +199,97 @@ static void create_register(parser_priv_t *priv, char *reg_name, size_t len) len_str, NULL}; - if (part_find_data_register(priv->jtag_ctrl.part, reg_name)) + if (part_find_data_register( jc->part, reg_name )) return; /* convert length information to string */ - snprintf(len_str, str_len, "%i", len); + snprintf( len_str, str_len, "%i", len ); - if (priv->jtag_ctrl.mode >= 1) - cmd_run(priv->jtag_ctrl.chain, cmd); + if (jc->mode >= 1) + cmd_run( jc->chain, cmd ); else - print_cmd(cmd); + print_cmd( cmd ); } } /***************************************************************************** - * void bsdl_set_idcode(parser_priv_t *priv, char *idcode) + * void bsdl_process_idcode( jtag_ctrl_t *jc ) * - * Stores the specified IDCODE of the device for later use and creates - * the DIR register. + * Creates the DIR register based on the extracted idcode. * * Parameters - * priv : private data container for parser related tasks - * idcode : string containing the device's IDCODE + * jc : jtag control structure * * Returns * void ****************************************************************************/ -void bsdl_set_idcode(parser_priv_t *priv, char *idcode) +static void bsdl_process_idcode(jtag_ctrl_t *jc) { - priv->jtag_ctrl.idcode = idcode; - - create_register(priv, "DIR", strlen(idcode)); + if (jc->idcode) + create_register( jc, "DIR", strlen( jc->idcode ) ); + else + bsdl_msg( BSDL_MSG_WARN, _("No IDCODE specification found.\n") ); } /***************************************************************************** - * void bsdl_set_usercode(parser_priv_t *priv, char *usercode) + * void bsdl_process_usercode( jtag_ctrl_t *jc ) * * Creates the USERCODE register, the contents of the usercode string is * ignored. * * Parameters - * priv : private data container for parser related tasks - * usercode : string containing the device's USERCODE, memory gets free'd + * jc : jtag control structure * * Returns * void ****************************************************************************/ -void bsdl_set_usercode(parser_priv_t *priv, char *usercode) +static void bsdl_process_usercode( jtag_ctrl_t *jc ) { - create_register(priv, "USERCODE", strlen(usercode)); + if (jc->usercode) + create_register( jc, "USERCODE", strlen( jc->usercode ) ); /* we're not interested in the usercode value at all */ - free(usercode); -} - - -/***************************************************************************** - * void bsdl_add_instruction(parser_priv_t *priv, char *instr, char *opcode) - * - * Converts the instruction specification into a member of the main - * list of instructions at priv->jtag_ctrl.instr_list. - * - * Parameters - * priv : private data container for parser related tasks - * instr : instruction name - * opcode : instruction opcode - * - * Returns - * void - ****************************************************************************/ -void bsdl_add_instruction(parser_priv_t *priv, char *instr, char *opcode) -{ - struct instr_elem *new_instr; - - new_instr = (struct instr_elem *)malloc(sizeof(struct instr_elem)); - if (new_instr) { - new_instr->next = priv->jtag_ctrl.instr_list; - new_instr->instr = instr; - new_instr->opcode = opcode; - - priv->jtag_ctrl.instr_list = new_instr; - } else - bsdl_msg(BSDL_MSG_FATAL, _("Out of memory, %s line %i\n"), __FILE__, __LINE__); } /***************************************************************************** - * void bsdl_set_bsr_length(parser_priv_t *priv, int len) + * void bsdl_set_bsr_length( jtag_ctrl_t *jc ) * * Creates the BSR register based on the specified length. * * Parameters - * priv : private data container for parser related tasks - * len : number of bits (= length) of BSR register - * - * Returns - * void - ****************************************************************************/ -void bsdl_set_bsr_length(parser_priv_t *priv, int len) -{ - create_register(priv, "BSR", len); -} - - -/***************************************************************************** - * Cell Info management function - * void bsdl_ci_no_disable(parser_priv_t *priv) - * - * Tracks that there is no disable term for the current cell info. - * - * Parameters - * priv : private data container for parser related tasks - * - * Returns - * void - ****************************************************************************/ -void bsdl_ci_no_disable(parser_priv_t *priv) -{ - priv->jtag_ctrl.cell_info.ctrl_bit_num = -1; -} - - -/***************************************************************************** - * Cell Info management function - * void bsdl_ci_set_cell_spec(parser_priv_t *priv, - * int function, char *safe_value) - * - * Sets the specified values of the current cell_spec (without disable term) - * to the variables for temporary storage of these information elements. - * The name of the related port is taken from the port_desc structure that - * was filled in previously by the rule Port_Name. - * - * Parameters - * priv : private data container for parser related tasks - * function : cell function indentificator - * safe_value : safe value for initialization of this cell - * - * Returns - * void - ****************************************************************************/ -void bsdl_ci_set_cell_spec(parser_priv_t *priv, - int function, char *safe_value) -{ - struct cell_info *ci = &(priv->jtag_ctrl.cell_info); - struct port_desc *pd = &(priv->jtag_ctrl.port_desc); - struct string_elem *name = priv->jtag_ctrl.port_desc.names_list; - char *port_string; - size_t str_len, name_len; - - ci->cell_function = function; - ci->basic_safe_value = safe_value; - - /* handle indexed port name: - - names of scalar ports are simply copied from the port_desc structure - to the final string that goes into ci - - names of vectored ports are expanded with their decimal index as - collected earlier earlier in rule Port_Name - */ - name_len = strlen(name->string); - str_len = name_len + 1 + 10 + 1 + 1; - if ((port_string = (char *)malloc(str_len)) != NULL) { - if (pd->is_vector) - snprintf(port_string, str_len-1, "%s(%d)", name->string, pd->low_idx); - else - strncpy(port_string, name->string, str_len-1); - port_string[str_len-1] = '\0'; - - ci->port_name = port_string; - } else { - bsdl_msg(BSDL_MSG_FATAL, _("Out of memory, %s line %i\n"), __FILE__, __LINE__); - ci->port_name = NULL; - } - - free(name->string); - free(name); - priv->jtag_ctrl.port_desc.names_list = NULL; -} - - -/***************************************************************************** - * Cell Info management function - * void bsdl_ci_set_cell_spec_disable(parser_priv_t *priv, - * int ctrl_bit_num, int safe_value, int disable_value) - * - * Applies the disable specification of the current cell spec to the variables - * for temporary storage of these information elements. - * - * Parameters - * priv : private data container for parser related tasks - * ctrl_bit_num : bit number of related control cell - * safe_value : safe value for initialization of this cell - * disable_value : currently ignored + * jc : jtag control structure * * Returns * void ****************************************************************************/ -void bsdl_ci_set_cell_spec_disable(parser_priv_t *priv, - int ctrl_bit_num, int safe_value, int disable_value) +static void bsdl_set_bsr_length( jtag_ctrl_t *jc ) { - struct cell_info *ci = &(priv->jtag_ctrl.cell_info); - - ci->ctrl_bit_num = ctrl_bit_num; - ci->disable_safe_value = safe_value; - /* disable value is ignored at the moment */ + create_register( jc, "BSR", jc->bsr_len ); } /***************************************************************************** + * void bsdl_process_cell_info( jtag_ctrl_t *jc ) * Cell Info management function - * void bsdl_ci_apply_cell_info(parser_priv_t *priv, int bit_num) * * Creates a BSR cell from the temporary storage variables via shell command * bit [ Z] * * Parameters - * priv : private data container for parser related tasks - * bit_num : bit number of current cell + * jc : jtag control structure * * Returns * void ****************************************************************************/ -void bsdl_ci_apply_cell_info(parser_priv_t *priv, int bit_num) +static void bsdl_process_cell_info( jtag_ctrl_t *jc ) { - struct cell_info *ci = &(priv->jtag_ctrl.cell_info); + cell_info_t *ci = jc->cell_info_first; - ci->bit_num = bit_num; - - if (priv->jtag_ctrl.mode >= 0) { + if (jc->mode >= 0) + { const size_t str_len = 10; char bit_num_str[str_len+1]; char ctrl_bit_num_str[str_len+1]; @@ -662,168 +304,74 @@ void bsdl_ci_apply_cell_info(parser_priv_t *priv, int bit_num) "Z", NULL}; - /* convert bit number to string */ - snprintf(bit_num_str, str_len, "%i", ci->bit_num); - bit_num_str[str_len] = '\0'; - /* convert cell function from BSDL token to jtag syntax */ - switch (ci->cell_function) { - case INTERNAL: - /* fall through */ - case OUTPUT2: - /* fall through */ - case OUTPUT3: - cmd[2] = "O"; - break; - case OBSERVE_ONLY: - /* fall through */ - case INPUT: - /* fall through */ - case CLOCK: - cmd[2] = "I"; - break; - case CONTROL: - /* fall through */ - case CONTROLR: - cmd[2] = "C"; - break; - case BIDIR: - cmd[2] = "B"; - break; - default: - /* spoil command */ - cmd[2] = "?"; - break; - } - /* convert basic safe value */ - cmd[3] = strcasecmp(ci->basic_safe_value, "x") == 0 ? "?" : ci->basic_safe_value; - /* apply port name */ - cmd[4] = ci->port_name; - - /* add disable spec if present */ - if (ci->ctrl_bit_num >= 0) { + while (ci) + { /* convert bit number to string */ - snprintf(ctrl_bit_num_str, str_len, "%i", ci->ctrl_bit_num); - ctrl_bit_num_str[str_len] = '\0'; - /* convert disable safe value to string */ - snprintf(disable_safe_value_str, str_len, "%i", ci->disable_safe_value); - disable_safe_value_str[str_len] = '\0'; - } else - /* stop command procssing here */ - cmd[5] = NULL; - - if (priv->jtag_ctrl.mode >= 1) - cmd_run(priv->jtag_ctrl.chain, cmd); - else - print_cmd(cmd); - } - - /* free malloc'ed memory */ - if (ci->port_name) { - free(ci->port_name); - ci->port_name = NULL; - } - if (ci->basic_safe_value) { - free(ci->basic_safe_value); - ci->basic_safe_value = NULL; - } -} - - -/***************************************************************************** - * Register Access management function - * void bsdl_ac_set_register(parser_priv_t *priv, char *reg, int reg_len) - * - * Stores the register specification values for the current register access - * specification in the temporary storage region for later usage. - * - * Parameters - * priv : private data container for parser related tasks - * reg : register name - * reg_len : optional register length - * - * Returns - * void - ****************************************************************************/ -void bsdl_ac_set_register(parser_priv_t *priv, char *reg, int reg_len) -{ - struct access_data *ad = &(priv->jtag_ctrl.access_data); - - ad->reg = reg; - ad->reg_len = reg_len; -} - - -/***************************************************************************** - * Register Access management function - * void bsdl_ac_add_instruction(parser_priv_t *priv, char *instr) - * - * Appends the specified instruction to the list of instructions for the - * current register access specification in the temporary storage region - * for later usage. - * - * Parameters - * priv : private data container for parser related tasks - * instr : instruction name - * - * Returns - * void - ****************************************************************************/ -void bsdl_ac_add_instruction(parser_priv_t *priv, char *instr) -{ - struct access_data *ad = &(priv->jtag_ctrl.access_data); - struct instr_elem *new_instr; - - new_instr = (struct instr_elem *)malloc(sizeof(struct instr_elem)); - if (new_instr) { - new_instr->next = ad->instr_list; - new_instr->instr = instr; - new_instr->opcode = NULL; - - ad->instr_list = new_instr; - } else - bsdl_msg(BSDL_MSG_FATAL, _("Out of memory, %s line %i\n"), __FILE__, __LINE__); -} + snprintf( bit_num_str, str_len, "%i", ci->bit_num ); + bit_num_str[str_len] = '\0'; + /* convert cell function from BSDL token to jtag syntax */ + switch (ci->cell_function) + { + case INTERNAL: + /* fall through */ + case OUTPUT2: + /* fall through */ + case OUTPUT3: + cmd[2] = "O"; + break; + case OBSERVE_ONLY: + /* fall through */ + case INPUT: + /* fall through */ + case CLOCK: + cmd[2] = "I"; + break; + case CONTROL: + /* fall through */ + case CONTROLR: + cmd[2] = "C"; + break; + case BIDIR: + cmd[2] = "B"; + break; + default: + /* spoil command */ + cmd[2] = "?"; + break; + } + /* convert basic safe value */ + cmd[3] = strcasecmp( ci->basic_safe_value, "x" ) == 0 ? "?" : ci->basic_safe_value; + /* apply port name */ + cmd[4] = ci->port_name; + + /* add disable spec if present */ + if (ci->ctrl_bit_num >= 0) + { + /* convert bit number to string */ + snprintf( ctrl_bit_num_str, str_len, "%i", ci->ctrl_bit_num ); + ctrl_bit_num_str[str_len] = '\0'; + /* convert disable safe value to string */ + snprintf( disable_safe_value_str, str_len, "%i", ci->disable_safe_value ); + disable_safe_value_str[str_len] = '\0'; + } + else + /* stop command procssing here */ + cmd[5] = NULL; + if (jc->mode >= 1) + cmd_run( jc->chain, cmd ); + else + print_cmd( cmd ); -/***************************************************************************** - * Register Access management function - * void bsdl_ac_apply_assoc(parser_priv_t *priv) - * - * Appends the collected register access specification from the temporary - * storage region to the main ainfo list. - * - * Parameters - * priv : private data container for parser related tasks - * - * Returns - * void - ****************************************************************************/ -void bsdl_ac_apply_assoc(parser_priv_t *priv) -{ - struct access_data *ad = &(priv->jtag_ctrl.access_data); - struct ainfo_elem *new_ainfo; - - new_ainfo = (struct ainfo_elem *)malloc(sizeof(struct ainfo_elem)); - if (new_ainfo) { - new_ainfo->next = ad->ainfo_list; - new_ainfo->reg = ad->reg; - new_ainfo->reg_len = ad->reg_len; - new_ainfo->instr_list = ad->instr_list; - - ad->ainfo_list = new_ainfo; - } else - bsdl_msg(BSDL_MSG_FATAL, _("Out of memory, %s line %i\n"), __FILE__, __LINE__); - - /* clean up obsolete temporary entries */ - ad->reg = NULL; - ad->reg_len = 0; - ad->instr_list = NULL; + ci = ci->next; + } + } } /***************************************************************************** + * void bsdl_process_register_access( jtag_ctrl_t *jc ) * Register Access management function - * void bsdl_ac_finalize(parser_priv_t *priv) * * Runs through the main instruction list and builds the instruction/register * association for each instruction from the register access specifications @@ -839,12 +387,12 @@ void bsdl_ac_apply_assoc(parser_priv_t *priv) * optional in the BSDL standard). * * Parameters - * priv : private data container for parser related tasks + * jc : jtag control structure * * Returns * void ****************************************************************************/ -void bsdl_ac_finalize(parser_priv_t *priv) +static void bsdl_process_register_access( jtag_ctrl_t *jc ) { /* ensure that all mandatory registers are created prior to handling the instruction/register associations @@ -852,25 +400,26 @@ void bsdl_ac_finalize(parser_priv_t *priv) + DEVICE_ID/DIR has been generated during the parsing process */ /* we need a BYPASS register */ - create_register(priv, "BYPASS", 1); + create_register( jc, "BYPASS", 1 ); - if (priv->jtag_ctrl.mode >= 0) { - struct ainfo_elem *ai; - struct instr_elem *cinst; + if (jc->mode >= 0) { + ainfo_elem_t *ai; + instr_elem_t *cinst; /* next scan through all register_access definitions and create the non-standard registers */ - ai = priv->jtag_ctrl.access_data.ainfo_list; - while (ai) { + ai = jc->ainfo_list; + while (ai) + { int is_std = 0; - if (strcasecmp(ai->reg, "BOUNDARY" ) == 0) is_std = 1; - if (strcasecmp(ai->reg, "BYPASS" ) == 0) is_std = 1; - if (strcasecmp(ai->reg, "DEVICE_ID") == 0) is_std = 1; - if (strcasecmp(ai->reg, "USERCODE" ) == 0) is_std = 1; + if (strcasecmp( ai->reg, "BOUNDARY" ) == 0) is_std = 1; + if (strcasecmp( ai->reg, "BYPASS" ) == 0) is_std = 1; + if (strcasecmp( ai->reg, "DEVICE_ID" ) == 0) is_std = 1; + if (strcasecmp( ai->reg, "USERCODE" ) == 0) is_std = 1; if (!is_std) - create_register(priv, ai->reg, ai->reg_len); + create_register( jc, ai->reg, ai->reg_len ); ai = ai->next; } @@ -878,23 +427,27 @@ void bsdl_ac_finalize(parser_priv_t *priv) /* next scan through all instruction/opcode definitions and resolve the instruction/register associations for these */ - cinst = priv->jtag_ctrl.instr_list; - while (cinst) { + cinst = jc->instr_list; + while (cinst) + { char *reg_name = NULL; char *instr_name = NULL; /* now see which of the register_access elements matches this instruction */ - ai = priv->jtag_ctrl.access_data.ainfo_list; - while (ai && (reg_name == NULL)) { - struct instr_elem *tinst = ai->instr_list; - - while (tinst && (reg_name == NULL)) { - if (strcasecmp(tinst->instr, cinst->instr) == 0) { + ai = jc->ainfo_list; + while (ai && (reg_name == NULL)) + { + instr_elem_t *tinst = ai->instr_list; + + while (tinst && (reg_name == NULL)) + { + if (strcasecmp( tinst->instr, cinst->instr ) == 0) + { /* found the instruction inside the current access info, now set the register name map some standard register names to different internal names*/ - if (strcasecmp(ai->reg, "BOUNDARY") == 0) reg_name = "BSR"; - else if (strcasecmp(ai->reg, "DEVICE_ID") == 0) reg_name = "DIR"; + if (strcasecmp( ai->reg, "BOUNDARY" ) == 0) reg_name = "BSR"; + else if (strcasecmp( ai->reg, "DEVICE_ID" ) == 0) reg_name = "DIR"; else reg_name = ai->reg; } @@ -904,40 +457,161 @@ void bsdl_ac_finalize(parser_priv_t *priv) ai = ai->next; } - if (reg_name == NULL) { + if (reg_name == NULL) + { /* BSDL file didn't specify an explicit register_access definition if we're looking at a standard mandatory instruction, we should build the association ourselves */ - if (strcasecmp(cinst->instr, "BYPASS" ) == 0) reg_name = "BYPASS"; - else if (strcasecmp(cinst->instr, "CLAMP" ) == 0) reg_name = "BYPASS"; - else if (strcasecmp(cinst->instr, "EXTEST" ) == 0) reg_name = "BSR"; - else if (strcasecmp(cinst->instr, "HIGHZ" ) == 0) reg_name = "BYPASS"; - else if (strcasecmp(cinst->instr, "IDCODE" ) == 0) reg_name = "DIR"; - else if (strcasecmp(cinst->instr, "INTEST" ) == 0) reg_name = "BSR"; - else if (strcasecmp(cinst->instr, "PRELOAD" ) == 0) reg_name = "BSR"; - else if (strcasecmp(cinst->instr, "SAMPLE" ) == 0) reg_name = "BSR"; - else if (strcasecmp(cinst->instr, "USERCODE") == 0) reg_name = "USERCODE"; + if (strcasecmp( cinst->instr, "BYPASS" ) == 0) reg_name = "BYPASS"; + else if (strcasecmp( cinst->instr, "CLAMP" ) == 0) reg_name = "BYPASS"; + else if (strcasecmp( cinst->instr, "EXTEST" ) == 0) reg_name = "BSR"; + else if (strcasecmp( cinst->instr, "HIGHZ" ) == 0) reg_name = "BYPASS"; + else if (strcasecmp( cinst->instr, "IDCODE" ) == 0) reg_name = "DIR"; + else if (strcasecmp( cinst->instr, "INTEST" ) == 0) reg_name = "BSR"; + else if (strcasecmp( cinst->instr, "PRELOAD" ) == 0) reg_name = "BSR"; + else if (strcasecmp( cinst->instr, "SAMPLE" ) == 0) reg_name = "BSR"; + else if (strcasecmp( cinst->instr, "USERCODE" ) == 0) reg_name = "USERCODE"; } - if (strcasecmp(cinst->instr, "SAMPLE" ) == 0) + if (strcasecmp( cinst->instr, "SAMPLE" ) == 0) instr_name = "SAMPLE/PRELOAD"; else instr_name = cinst->instr; - if (reg_name) { + if (reg_name) + { char *cmd[] = {"instruction", instr_name, cinst->opcode, reg_name, NULL}; - if (priv->jtag_ctrl.mode >= 1) - cmd_run(priv->jtag_ctrl.chain, cmd); + if (jc->mode >= 1) + cmd_run( jc->chain, cmd ); else - print_cmd(cmd); + print_cmd( cmd ); } cinst = cinst->next; } } } + + +static int parse_vhdl_elem( bsdl_parser_priv_t *priv, vhdl_elem_t *elem ) +{ + char *buf; + size_t buf_len; + char *type_string = NULL; + size_t type_string_len = 0; + size_t name_string_len; + size_t elem_string_len; + +#if 0 + /* decode element type and set initial string for the parser */ + switch (elem->type) + { + case VET_CONSTANT: + type_string = "CONSTANT "; + break; + case VET_UNKNOWN: + /* use default initializations */ + break; + default: + type_string = "ATTRIBUTE "; + break; + } + + type_string_len = type_string ? strlen( type_string ) : 0; +#endif + + name_string_len = elem->name ? strlen( elem->name ) : 0; + elem_string_len = elem->payload ? strlen( elem->payload ) : 0; + + /* allocate enough memory for total buffer */ + buf_len = type_string_len + name_string_len + 1 + elem_string_len + 1; + buf = (char *)malloc( buf_len ); + if (!buf) + { + bsdl_msg( BSDL_MSG_FATAL, _("Out of memory, %s line %i\n"), __FILE__, __LINE__ ); + return -1; + } + buf[0] = '\0'; + + if (type_string_len > 0) + strncat( buf, type_string, buf_len ); + + if (name_string_len > 0) + strncat( buf, elem->name, buf_len - type_string_len ); + strncat( buf, " ", buf_len - type_string_len - name_string_len ); + + if (elem_string_len > 0) + strncat( buf, elem->payload, buf_len - type_string_len - name_string_len - 1 ); + + buf[buf_len - 1] = '\0'; + + priv->lineno = elem->line; + + /* buffer is prepared for string parsing */ + bsdl_flex_switch_buffer( priv->scanner, buf, elem->line ); + bsdlparse( priv ); + + free( buf ); + + return bsdl_flex_get_compile_errors( priv->scanner ); +} + + +static int build_commands( bsdl_parser_priv_t *priv ) +{ + jtag_ctrl_t *jc = priv->jtag_ctrl; + + bsdl_emit_ports( jc ); + + bsdl_set_instruction_length( jc ); + + bsdl_process_idcode( jc ); + + bsdl_process_usercode( jc ); + + bsdl_set_bsr_length( jc ); + + bsdl_process_register_access( jc ); + + bsdl_process_cell_info( jc ); + + return 0; +} + + +int bsdl_sem_process_elements( bsdl_parser_priv_t *priv ) +{ + vhdl_elem_t *el = priv->jtag_ctrl->vhdl_elem_first; + int result = 0; + + while (el && (result == 0)) + { + result = parse_vhdl_elem( priv, el ); + + el = el->next; + } + + if (result != 0) + { + bsdl_msg( BSDL_MSG_ERR, _("BSDL stage reported errors, aborting.\n") ); + return result; + } + + result = build_commands( priv ); + + return result; +} + + +/* + Local Variables: + mode:C + c-default-style:gnu + indent-tabs-mode:nil + End: +*/ diff --git a/jtag/src/bsdl/bsdl_sysdep.h b/jtag/src/bsdl/bsdl_sysdep.h index e6b1e90e..3f53e50b 100644 --- a/jtag/src/bsdl/bsdl_sysdep.h +++ b/jtag/src/bsdl/bsdl_sysdep.h @@ -26,6 +26,8 @@ #define BSDL_SYSDEP_H +#include "bsdl_config.h" + #include "gettext.h" #define _(s) gettext(s) #define N_(s) gettext_noop(s) diff --git a/jtag/src/bsdl/bsdl_types.h b/jtag/src/bsdl/bsdl_types.h new file mode 100644 index 00000000..458fad37 --- /dev/null +++ b/jtag/src/bsdl/bsdl_types.h @@ -0,0 +1,195 @@ +/* + * $Id$ + * + * Copyright (C) 2008, Arnim Laeuger + * + * This program is free software; you can redistribute it and/or + * modify it 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. + * + * Written by Arnim Laeuger , 2008. + * + */ + +#ifndef BSDL_TYPES_H +#define BSDL_TYPES_H + +#include + +/* private data of the flex scanner + handled internally in bsdl_flex.l as yyextra */ +struct scan_extra +{ + int mode; + int debug; + int Compile_Errors; + int Base; +}; +typedef struct scan_extra scan_extra_t; + +/* list of instructions + the instruction name and its opcode (optional) is stored here */ +struct instr_elem +{ + struct instr_elem *next; + char *instr; + char *opcode; +}; +typedef struct instr_elem instr_elem_t; + +/* register access information + * derived from the entries of the REGISTER_ACCESS attribute + * ainfo_elem describes a register and its accosiated instructions + * - register name + * - register length (optional) + * - list of associated instructions + */ +struct ainfo_elem +{ + struct ainfo_elem *next; + char *reg; + int reg_len; + instr_elem_t *instr_list; +}; +typedef struct ainfo_elem ainfo_elem_t; + +/* structure cell_info collects bit/cell information from the + BOUNDARY_REGISTER attribute + each Cell_Entry fills in the structure and the contents is used for the + respective 'bit' command */ +struct cell_info +{ + struct cell_info *next; + /* basic cell spec entries */ + int bit_num; + char *port_name; + int cell_function; + char *basic_safe_value; + /* the disable spec entries */ + int ctrl_bit_num; + int disable_safe_value; +}; +typedef struct cell_info cell_info_t; + +/* structure string_elem enables to build lists of strings */ +struct string_elem +{ + struct string_elem *next; + char *string; +}; +typedef struct string_elem string_elem_t; + +/* structure port_desc contains all descriptive information for a port + definition: + - one or more names + - flag showing whether it's a vector (element) or a scalar + - low and high indice if it's a vector */ +struct port_desc +{ + string_elem_t *names_list; + struct port_desc *next; + int is_vector; + int low_idx; + int high_idx; +}; +typedef struct port_desc port_desc_t; + +typedef enum +{ + VET_CONSTANT, + VET_ATTRIBUTE_STRING, + VET_ATTRIBUTE_DECIMAL, + VET_UNKNOWN +} vhdl_elem_type_t; + +struct vhdl_elem +{ + struct vhdl_elem *next; + vhdl_elem_type_t type; + char *name; + char *payload; + int line; +}; +typedef struct vhdl_elem vhdl_elem_t; + +typedef enum +{ + CONF_1990, + CONF_1993, + CONF_2001, + CONF_UNKNOWN +} bsdl_conformance_t; + +/* structure jtag_ctrl collects all elements that are required to interface + with jtag internals */ +struct jtag_ctrl +{ + int mode; + int debug; + chain_t *chain; + part_t *part; + /* collected by VHDL parser */ + port_desc_t *port_desc; + vhdl_elem_t *vhdl_elem_first; + vhdl_elem_t *vhdl_elem_last; + /* collected by BSDL parser */ + char *idcode; /* IDCODE string */ + char *usercode; /* USERCODE string */ + int instr_len; + int bsr_len; + bsdl_conformance_t conformance; + instr_elem_t *instr_list; + ainfo_elem_t *ainfo_list; + cell_info_t *cell_info_first; + cell_info_t *cell_info_last; +}; +typedef struct jtag_ctrl jtag_ctrl_t; + +/* private data of the VHDL bison parser + used to store variables the would end up as globals otherwise */ +struct vhdl_parser_priv +{ + char Package_File_Name[100]; + int Reading_Package; + char *buffer; + size_t len_buffer; + void *scanner; + jtag_ctrl_t *jtag_ctrl; + port_desc_t tmp_port_desc; +}; +typedef struct vhdl_parser_priv vhdl_parser_priv_t; + +/* private data of the BSDL bison parser + used to store variables the would end up as globals otherwise */ +struct bsdl_parser_priv +{ + void *scanner; + jtag_ctrl_t *jtag_ctrl; + int lineno; + ainfo_elem_t ainfo; + cell_info_t tmp_cell_info; + port_desc_t tmp_port_desc; +}; +typedef struct bsdl_parser_priv bsdl_parser_priv_t; + +#endif /* BSDL_TYPES_H */ + + +/* + Local Variables: + mode:C + c-default-style:gnu + indent-tabs-mode:nil + End: +*/ diff --git a/jtag/src/bsdl/vhdl_bison.y b/jtag/src/bsdl/vhdl_bison.y new file mode 100644 index 00000000..038a9451 --- /dev/null +++ b/jtag/src/bsdl/vhdl_bison.y @@ -0,0 +1,1125 @@ +/* + * $Id$ + * + * Original Yacc code by Ken Parker, 1990 + * Extensions and adaptions for UrJTAG by Arnim Laeuger, 2007 + * + */ + +/* ----------------------------------------------------------------------- */ +/* */ +/* Yacc code for BSDL */ +/* */ +/* ----------------------------------------------------------------------- */ +/* Date: 901003 */ + +/* + +Email header accompanying the original Yacc code: + http://www.eda.org/vug_bbs/bsdl.parser + +-----------------------------------8<-------------------------------------- + +Hello All, + +This is this first mailing of the BSDL* Version 0.0 parser specifications +we are sending to people who request it from our publicized E-Mail address; + + bsdl%hpmtlx@hplabs.HP.com + +You are free to redistribute this at will, but we feel that it would be +better if respondents asked for it directly so that their addresses can +be entered into our list for future mailings and updates. + +It would be helpful if you could confirm receipt of this transmission. +We also would be very interested to hear about your experiences with this +information and what you are planning to do with BSDL. + +Regards, + +Ken Parker +Hewlett-Packard Company + + +*Boundary-Scan Description Language - as documented in: + +"A Language for Describing Boundary-Scan Devices", K.P. Parker +and S. Oresjo, Proceedings 1990 International Test Conference, +Washington DC, pp 222-234 + + +- -----------------cut here--------------------------------------------------- + + +901004.0721 Hewlett-Packard Company +901016.1049 Manufacturing Test Division + P.O. Box 301 + Loveland, Colorado 80537 + USA + + October 1990 +Hello BSDL Parser Requestor, + + This Electronic Mail reply contains the computer specifications for +Hewlett-Packard's Version 0.0 BSDL parser. This section of the reply +explains the contents of the rest of this file. + +This file is composed of seven (7) parts: + + 1) How to use this file + + 2) UNIX* Lex source (lexicographical tokenizing rules) + + 3) UNIX* Yacc source (BNF-like syntax description) + + 4) A sample main program to recognize BSDL. + + 5) A BSDL description of the Texas Instruments 74bct8374 that is + recognized by the parser, for testing purposes. + + 6) The VHDL package STD_1149_1_1990 needed by this parser. + + 7) [added 901016] Porting experiences to other systems. + + +RECOMMENDATION: Save a copy of this file in archival storage before + processing it via the instructions below. This will + allow you to recover from errors, and allow you to + compare subsequently released data for changes. + +DISCLAIMERS: + +1. The IEEE 1149.1 Working Group has not endorsed BSDL Version 0.0 and + therefore no person may represent it as an IEEE standard or imply that + a resulting IEEE standard will be identical to it. + +2. The IEEE 1149.1 Working Group recognizes that BSDL Version 0.0 is a + well-conceived initiative that is likely to excelerate the creation + of tools that support the 1149.1 standard. As such, changes and + enhancements will be carefully considered so as not to needlessly + disrupt these development efforts. The overriding goal is the + ultimate success of the 1149.1 standard. + +LEGAL NOTICES: + + Hewlett-Packard Company makes no warranty of any kind with regard to + this information, including, but not limited to, the implied + waranties of merchantability and fitness for a particular purpose. + + Hewlett-Packard Company shall not be liable for errors contained + herein or direct, indirect, special, incidental, or consequential + damages in connection with the furnishing, performance, or use of + this material. + + +*UNIX is a trademark of AT&T in the USA and other countries. + +*/ + + +%pure-parser +%parse-param {vhdl_parser_priv_t *priv_data} +%defines +%name-prefix="vhdl" + +%{ +#include +#include +#include +#include + +#include "bsdl_sysdep.h" + +#include "bsdl_types.h" +#include "bsdl_msg.h" + +/* interface to flex */ +#include "vhdl_bison.h" +#include "vhdl_parser.h" + +#ifdef DMALLOC +#include "dmalloc.h" +#endif + +#define YYLEX_PARAM priv_data->scanner +int yylex (YYSTYPE *, void *); + +#if 1 +#define ERROR_LIMIT 15 +#define BUMP_ERROR if (vhdl_flex_postinc_compile_errors( priv_data->scanner ) > ERROR_LIMIT) \ + {Give_Up_And_Quit( priv_data );YYABORT;} +#else +#define BUMP_ERROR {Give_Up_And_Quit( priv_data );YYABORT;} +#endif + +static void Init_Text( vhdl_parser_priv_t * ); +static void Store_Text( vhdl_parser_priv_t *, char * ); +static void Print_Error( vhdl_parser_priv_t *, const char * ); +static void Give_Up_And_Quit( vhdl_parser_priv_t * ); + +/* VHDL semantic action interface */ +static void vhdl_set_entity( vhdl_parser_priv_t *, char * ); +static void vhdl_port_add_name( vhdl_parser_priv_t *, char * ); +static void vhdl_port_add_bit( vhdl_parser_priv_t * ); +static void vhdl_port_add_range( vhdl_parser_priv_t *, int, int ); +static void vhdl_port_apply_port( vhdl_parser_priv_t * ); + +//static void set_attr_bool( vhdl_parser_priv_t *, char *, int ); +static void set_attr_decimal( vhdl_parser_priv_t *, char *, int ); +static void set_attr_string( vhdl_parser_priv_t *, char *, char * ); +//static void set_attr_real( vhdl_parser_priv_t *, char *, char * ); +//static void set_attr_const( vhdl_parser_priv_t *, char *, char * ); + +void yyerror( vhdl_parser_priv_t *, const char * ); +%} + +%union +{ + int integer; + char *str; +} + + +%token ENTITY PORT GENERIC USE ATTRIBUTE IS +%token OF CONSTANT STRING END ALL +%token PHYSICAL_PIN_MAP PIN_MAP_STRING TRUE FALSE SIGNAL +%token LOW BOTH IN OUT INOUT +%token BUFFER LINKAGE BIT BIT_VECTOR TO DOWNTO +%token PACKAGE BODY TYPE SUBTYPE RECORD ARRAY +%token POSITIVE RANGE CELL_INFO +%token INPUT OUTPUT2 OUTPUT3 CONTROL CONTROLR INTERNAL +%token CLOCK BIDIR BIDIR_IN BIDIR_OUT EXTEST SAMPLE +%token INTEST RUNBIST PI PO UPD CAP X BIN_X_PATTERN +%token ZERO ONE Z IDENTIFIER +%token SINGLE_QUOTE QUOTED_STRING DECIMAL_NUMBER +%token REAL_NUMBER CONCATENATE SEMICOLON COMMA +%token LPAREN RPAREN COLON +%token BOX COLON_EQUAL PERIOD ILLEGAL +%token BSDL_EXTENSION +%token OBSERVE_ONLY +%token STD_1532_2001 STD_1532_2002 + +%type BIN_X_PATTERN +%type IDENTIFIER +%type QUOTED_STRING +%type DECIMAL_NUMBER +%type Boolean +%type REAL_NUMBER + +%start BSDL_Program + +%% /* End declarations, begin rules */ + +BSDL_Program : Begin_BSDL BSDL_Body End_BSDL +; +Begin_BSDL : ENTITY IDENTIFIER IS + { vhdl_set_entity( priv_data, $2 ); } + | error + { + Print_Error( priv_data, _("Improper Entity declaration") ); + Print_Error( priv_data, _("Check if source file is BSDL") ); + BUMP_ERROR; YYABORT; /* Probably not a BSDL source file */ + } +; +BSDL_Body : VHDL_Generic + VHDL_Port + VHDL_Use_Part + VHDL_Elements + | error + { + Print_Error( priv_data, _("Syntax Error") ); + BUMP_ERROR; YYABORT; + } +; +End_BSDL : END IDENTIFIER SEMICOLON + { free( $2 ); } + | error + { + Print_Error( priv_data, _("Syntax Error") ); + BUMP_ERROR; YYABORT; + } +; +VHDL_Generic : GENERIC LPAREN PHYSICAL_PIN_MAP COLON STRING COLON_EQUAL + Quoted_String RPAREN SEMICOLON +; +VHDL_Port : PORT LPAREN Port_Specifier_List RPAREN SEMICOLON + | error + { + Print_Error( priv_data, _("Improper Port declaration") ); + BUMP_ERROR; YYABORT; + } +; +Port_Specifier_List : Port_Specifier + | Port_Specifier_List SEMICOLON Port_Specifier +; +Port_Specifier : Port_List COLON Function Scaler_Or_Vector + { vhdl_port_apply_port( priv_data ); } +; +Port_List : IDENTIFIER + { vhdl_port_add_name( priv_data, $1 ); } + | Port_List COMMA IDENTIFIER + { vhdl_port_add_name( priv_data, $3 ); } +; +Function : IN | OUT | INOUT | BUFFER | LINKAGE +; +Scaler_Or_Vector : BIT + { vhdl_port_add_bit( priv_data ); } + | BIT_VECTOR LPAREN Vector_Range RPAREN +; +Vector_Range : DECIMAL_NUMBER TO DECIMAL_NUMBER + { vhdl_port_add_range( priv_data, $1, $3 ); } + | DECIMAL_NUMBER DOWNTO DECIMAL_NUMBER + { vhdl_port_add_range( priv_data, $3, $1 ); } +; +VHDL_Use_Part : ISC_Use + | Standard_Use + | Standard_Use ISC_Use + | Standard_Use VHDL_Use_List + | error + { + Print_Error( priv_data, _("Error in Package declaration(s)") ); + BUMP_ERROR; YYABORT; + } +; +Standard_Use : USE IDENTIFIER + {/* Parse Standard 1149.1 Package */ + strcpy( priv_data->Package_File_Name, $2 ); + free( $2 ); + } + PERIOD ALL SEMICOLON + { + priv_data->Reading_Package = 1; + vhdl_flex_switch_file( priv_data->scanner, + priv_data->Package_File_Name ); + } + Standard_Package + { + priv_data->Reading_Package = 0; + } +; +Standard_Package : PACKAGE IDENTIFIER IS Standard_Decls Defered_Constants + Standard_Decls END IDENTIFIER SEMICOLON Package_Body + { free( $2 ); free( $8 ); } + | error + { + Print_Error( priv_data, _("Error in Standard Package") ); + BUMP_ERROR; YYABORT; + } +; +Standard_Decls : Standard_Decl + | Standard_Decls Standard_Decl +; +Standard_Decl : ATTRIBUTE IDENTIFIER COLON Attribute_Type SEMICOLON + { free( $2 ); } + | TYPE IDENTIFIER IS Type_Body SEMICOLON + { free( $2 ); } + | TYPE CELL_INFO IS ARRAY LPAREN POSITIVE RANGE BOX RPAREN + OF IDENTIFIER SEMICOLON + { free( $11 ); } + | SUBTYPE PIN_MAP_STRING IS STRING SEMICOLON + | SUBTYPE BSDL_EXTENSION IS STRING SEMICOLON + | error + { + Print_Error( priv_data, _("Error in Standard Declarations") ); + BUMP_ERROR; YYABORT; + } +; +Attribute_Type : IDENTIFIER + { free( $1 ); } + | STRING + | DECIMAL_NUMBER + | BSDL_EXTENSION + | error + { + Print_Error( priv_data, _("Error in Attribute type identification") ); + BUMP_ERROR; YYABORT; + } +; +Type_Body : LPAREN ID_Bits RPAREN + | LPAREN ID_List RPAREN + | LPAREN LOW COMMA BOTH RPAREN + | ARRAY LPAREN DECIMAL_NUMBER TO DECIMAL_NUMBER RPAREN + OF IDENTIFIER + { free( $8 ); } + | ARRAY LPAREN DECIMAL_NUMBER DOWNTO DECIMAL_NUMBER RPAREN + OF IDENTIFIER + { free( $8 ); } + | RECORD Record_Body END RECORD + | error + { + Print_Error( priv_data, _("Error in Type definition") ); + BUMP_ERROR; YYABORT; + } +; +ID_Bits : ID_Bit + | ID_Bits COMMA ID_Bit +; +ID_List : IDENTIFIER + { free( $1 ); } + | ID_List COMMA IDENTIFIER + { free( $3 ); } +; +ID_Bit : SINGLE_QUOTE BIN_X_PATTERN SINGLE_QUOTE + { free( $2 ); } + | error + { + Print_Error( priv_data, _("Error in Bit definition") ); + BUMP_ERROR; YYABORT; + } +; +Record_Body : Record_Element + | Record_Body Record_Element +; +Record_Element : IDENTIFIER COLON IDENTIFIER SEMICOLON + { free( $1 ); free( $3 ); } + | error + { + Print_Error( priv_data, _("Error in Record Definition") ); + BUMP_ERROR; YYABORT; + } +; +Defered_Constants : Defered_Constant + | Defered_Constants Defered_Constant +; +Defered_Constant : CONSTANT Constant_Body +; +Constant_Body : IDENTIFIER COLON CELL_INFO SEMICOLON + { free( $1 ); } + | error + { + Print_Error( priv_data, _("Error in defered constant") ); + BUMP_ERROR; YYABORT; + } +; +VHDL_Use_List : VHDL_Use + | VHDL_Use_List VHDL_Use +; +Package_Body : PACKAGE BODY IDENTIFIER IS Constant_List END IDENTIFIER + { free( $3 ); free( $7 ); } + SEMICOLON + | error + { + Print_Error( priv_data, _("Error in Package Body definition") ); + BUMP_ERROR; YYABORT; + } +; +Constant_List : Cell_Constant + | Constant_List Cell_Constant +; +Cell_Constant : CONSTANT IDENTIFIER COLON CELL_INFO COLON_EQUAL + LPAREN Triples_List RPAREN SEMICOLON + { free( $2 ); } + | error + { + Print_Error( priv_data, _("Error in Cell Constant definition") ); + BUMP_ERROR; YYABORT; + } +; +Triples_List : Triple + | Triples_List COMMA Triple +; +Triple : LPAREN Triple_Function COMMA Triple_Inst COMMA CAP_Data + RPAREN + | error + { + Print_Error( priv_data, _("Error in Cell Data Record") ); + BUMP_ERROR; YYABORT; + } +; +Triple_Function : INPUT | OUTPUT2 | OUTPUT3 | INTERNAL | CONTROL + | CONTROLR | CLOCK | BIDIR_IN | BIDIR_OUT + | OBSERVE_ONLY + | error + { + Print_Error( priv_data, _("Error in Cell_Type Function field") ); + BUMP_ERROR; YYABORT; + } +; +Triple_Inst : EXTEST | SAMPLE | INTEST | RUNBIST + | error + { + Print_Error( priv_data, _("Error in BScan_Inst Instruction field") ); + BUMP_ERROR; YYABORT; + } +; +CAP_Data : PI | PO | UPD | CAP | X | ZERO | ONE + | error + { + Print_Error( priv_data, _("Error in Constant CAP data source field") ); + BUMP_ERROR; YYABORT; + } +; +VHDL_Use : USE IDENTIFIER + {/* Parse Standard 1149.1 Package */ + strcpy(priv_data->Package_File_Name, $2); + free($2); + } + PERIOD ALL SEMICOLON + { + priv_data->Reading_Package = 1; + vhdl_flex_switch_file(priv_data->scanner, + priv_data->Package_File_Name); + } + User_Package + { + priv_data->Reading_Package = 0; + } +; +User_Package : PACKAGE IDENTIFIER + IS Defered_Constants END IDENTIFIER SEMICOLON Package_Body + { free($2); free($6); } + | error + {Print_Error(priv_data, _("Error in User-Defined Package declarations")); + BUMP_ERROR; YYABORT; } +; +VHDL_Elements : VHDL_Element + | VHDL_Elements VHDL_Element +; +VHDL_Element : VHDL_Constant + | VHDL_Attribute +; +VHDL_Constant : CONSTANT VHDL_Constant_Part +; +VHDL_Constant_Part : IDENTIFIER COLON PIN_MAP_STRING COLON_EQUAL + Quoted_String SEMICOLON + // { set_attr_const( priv_data, $1, strdup( "PIN_MAP_STRING" ) ); } + { free( $1 ); } +; +VHDL_Attribute : VHDL_Attr_Boolean + | VHDL_Attr_Decimal + | VHDL_Attr_Real + | VHDL_Attr_String + | VHDL_Attr_PhysicalPinMap +; +VHDL_Attr_Boolean : ATTRIBUTE IDENTIFIER OF IDENTIFIER + COLON SIGNAL IS Boolean SEMICOLON + { + //set_attr_bool( priv_data, $2, $8 ); + //free( $4 ); + /* skip boolean attributes for the time being */ + free( $2 ); free( $4 ); + } +; +Boolean : TRUE + { $$ = 1; } + | FALSE + { $$ = 0; } +; +VHDL_Attr_Decimal : ATTRIBUTE IDENTIFIER OF IDENTIFIER + COLON ENTITY IS DECIMAL_NUMBER SEMICOLON + { + set_attr_decimal( priv_data, $2, $8 ); + free( $4 ); + /* skip decimal attributes for the time being */ + //free( $2 ); free( $4 ); + } +; +VHDL_Attr_Real : ATTRIBUTE IDENTIFIER OF IDENTIFIER COLON SIGNAL + IS LPAREN REAL_NUMBER COMMA Stop RPAREN SEMICOLON + { + //set_attr_real( priv_data, $2, $9 ); + //free( $4 ); + /* skip real attributes for the time being */ + free( $2 ); free( $4 ); free( $9 ); + } +; +Stop : LOW | BOTH +; +VHDL_Attr_String : ATTRIBUTE IDENTIFIER OF IDENTIFIER + COLON ENTITY IS Quoted_String SEMICOLON + { + set_attr_string( priv_data, $2, strdup( priv_data->buffer ) ); + free( $4 ); + } +; +VHDL_Attr_PhysicalPinMap : ATTRIBUTE IDENTIFIER OF IDENTIFIER + COLON ENTITY IS PHYSICAL_PIN_MAP SEMICOLON + { free( $2 ); free( $4 ); } +; +Quoted_String : QUOTED_STRING + { + Init_Text( priv_data ); + Store_Text( priv_data, $1 ); + free( $1 ); + } + | Quoted_String CONCATENATE QUOTED_STRING + { + Store_Text( priv_data, $3 ); + free( $3 ); + } +; +ISC_Use : USE ISC_Packages PERIOD ALL SEMICOLON + { + priv_data->Reading_Package = 1; + vhdl_flex_switch_file( priv_data->scanner, + priv_data->Package_File_Name ); + } + ISC_Package + { + priv_data->Reading_Package = 0; + } +; +ISC_Packages : STD_1532_2001 + { + strcpy( priv_data->Package_File_Name, "STD_1532_2001" ); + } + | STD_1532_2002 + { + strcpy( priv_data->Package_File_Name, "STD_1532_2002" ); + } +; +ISC_Package : ISC_Package_Header ISC_Package_Body +; +ISC_Package_Header : PACKAGE ISC_Packages IS + Standard_Use + { + priv_data->Reading_Package = 1; + } + Standard_Decls + END ISC_Packages SEMICOLON +; +ISC_Package_Body : PACKAGE BODY ISC_Packages IS + END ISC_Packages SEMICOLON +; +%% /* End rules, begin programs */ +/***************************************************************************** + * void Init_Text( vhdl_parser_priv_t *priv ) + * + * Allocates the internal test buffer if not already existing. + * + * Parameters + * priv : private data container for parser related tasks + * + * Returns + * void + ****************************************************************************/ +static void Init_Text( vhdl_parser_priv_t *priv ) +{ + if (priv->len_buffer == 0) + { + priv->buffer = (char *)malloc( 160 ); + priv->len_buffer = 160; + } + priv->buffer[0] = '\0'; +} + + +/***************************************************************************** + * void Store_Text( vhdl_parser_priv_t *priv, char *Source ) + * + * Appends the given String to the internal text buffer. The buffer + * is extended if the string does not fit into the current size. + * + * Parameters + * priv : private data container for parser related tasks + * String : pointer to string that is to be added to buffer + * + * Returns + * void + ****************************************************************************/ +static void Store_Text( vhdl_parser_priv_t *priv, char *Source ) +{ /* Save characters from VHDL string in local string buffer. */ + size_t req_len; + char *SourceEnd; + + SourceEnd = ++Source; /* skip leading '"' */ + while (*SourceEnd && (*SourceEnd != '"') && (*SourceEnd != '\n')) + SourceEnd++; + /* terminate Source string with NUL character */ + *SourceEnd = '\0'; + + req_len = strlen( priv->buffer ) + strlen( Source ) + 1; + if (req_len > priv->len_buffer) + { + priv->buffer = (char *)realloc( priv->buffer, req_len ); + priv->len_buffer = req_len; + } + strcat( priv->buffer, Source ); +} +/*----------------------------------------------------------------------*/ +static void Print_Error( vhdl_parser_priv_t *priv_data, const char *Errmess ) +{ + if (priv_data->Reading_Package) + bsdl_msg( BSDL_MSG_ERR, _("In Package %s, Line %d, %s.\n"), + priv_data->Package_File_Name, + vhdl_flex_get_lineno( priv_data->scanner ), + Errmess ); + else + if (priv_data->jtag_ctrl->debug || (priv_data->jtag_ctrl->mode >= 0)) + bsdl_msg( BSDL_MSG_ERR, _("Line %d, %s.\n"), + vhdl_flex_get_lineno( priv_data->scanner ), + Errmess ); +} +/*----------------------------------------------------------------------*/ +static void Give_Up_And_Quit( vhdl_parser_priv_t *priv_data ) +{ + Print_Error( priv_data, _("Too many errors") ); +} +/*----------------------------------------------------------------------*/ +void yyerror( vhdl_parser_priv_t *priv_data, const char *error_string ) +{ +} + + +/***************************************************************************** + * void vhdl_sem_init( vhdl_parser_priv_t *priv ) + * + * Initializes storage elements in the private parser and jtag control + * structures that are used for semantic purposes. + * + * Parameters + * priv : private data container for parser related tasks + * + * Returns + * void + ****************************************************************************/ +static void vhdl_sem_init( vhdl_parser_priv_t *priv ) +{ + priv->tmp_port_desc.names_list = NULL; + priv->tmp_port_desc.next = NULL; + + priv->jtag_ctrl->port_desc = NULL; + + priv->jtag_ctrl->vhdl_elem_first = NULL; + priv->jtag_ctrl->vhdl_elem_last = NULL; +} + + +/***************************************************************************** + * void free_string_list( string_elem_t *sl ) + * + * Deallocates the given list of string_elem items. + * + * Parameters + * sl : first string_elem to deallocate + * + * Returns + * void + ****************************************************************************/ +static void free_string_list( string_elem_t *sl ) +{ + if (sl) + { + if (sl->string) + free( sl->string ); + free_string_list( sl->next ); + free( sl ); + } +} + + +/***************************************************************************** + * void free_port_list( port_desc_t *pl, int free_me ) + * + * Deallocates the given list of port_desc. + * + * Parameters + * pl : first port_desc to deallocate + * free_me : set to 1 to free memory for ai as well + * + * Returns + * void + ****************************************************************************/ +static void free_port_list( port_desc_t *pl, int free_me ) +{ + if (pl) + { + free_string_list( pl->names_list ); + free_port_list( pl->next, 1 ); + + if (free_me) + free( pl ); + } +} + + +/***************************************************************************** + * void free_elem_list( vhdl_elem_t *el ) + * + * Deallocates the given list of vhdl_elem items. + * + * Parameters + * el : first vhdl_elem to deallocate + * + * Returns + * void + ****************************************************************************/ +static void free_elem_list( vhdl_elem_t *el ) +{ + if (el) + { + free_elem_list( el->next ); + + if (el->name) + free( el->name ); + + if (el->payload) + free( el->payload ); + free( el ); + } +} + + +/***************************************************************************** + * void vhdl_sem_deinit( vhdl_parser_priv_t *priv ) + * + * Frees and deinitializes storage elements in the private parser and + * jtag control structures that were filled by semantic rules. + * + * Parameters + * priv : private data container for parser related tasks + * + * Returns + * void + ****************************************************************************/ +static void vhdl_sem_deinit( vhdl_parser_priv_t *priv_data ) +{ + port_desc_t *pd = priv_data->jtag_ctrl->port_desc; + vhdl_elem_t *el = priv_data->jtag_ctrl->vhdl_elem_first; + + /* free port_desc list */ + free_port_list( pd, 1 ); + free_port_list( &(priv_data->tmp_port_desc), 0 ); + + /* free VHDL element list */ + free_elem_list( el ); + + priv_data->jtag_ctrl = NULL; +} + + +/***************************************************************************** + * vhdl_parser_priv_t *vhdl_parser_init( FILE *f, jtag_ctrl_t *jtag_ctrl ) + * + * Initializes storage elements in the private parser structure that are + * used for parser maintenance purposes. + * Subsequently calls initializer functions for the scanner and the semantic + * parts. + * + * Parameters + * f : descriptor of file for scanning + * jtag_ctrl : pointer to jtag control structure + * + * Returns + * pointer to private parser structure + ****************************************************************************/ +vhdl_parser_priv_t *vhdl_parser_init( FILE *f, jtag_ctrl_t *jtag_ctrl ) +{ + vhdl_parser_priv_t *new_priv; + + if (!(new_priv = (vhdl_parser_priv_t *)malloc( sizeof( vhdl_parser_priv_t ) ))) + { + bsdl_msg( BSDL_MSG_ERR, _("Out of memory, %s line %i\n"), __FILE__, __LINE__ ); + return NULL; + } + + new_priv->jtag_ctrl = jtag_ctrl; + + new_priv->Reading_Package = 0; + new_priv->buffer = NULL; + new_priv->len_buffer = 0; + + if (!(new_priv->scanner = vhdl_flex_init( f, jtag_ctrl->mode, jtag_ctrl->debug ))) + { + free( new_priv ); + new_priv = NULL; + } + + vhdl_sem_init( new_priv ); + + return new_priv; +} + + +/***************************************************************************** + * void vhdl_parser_deinit( vhdl_parser_priv_t *priv ) + * + * Frees storage elements in the private parser structure that are + * used for parser maintenance purposes. + * Subsequently calls deinitializer functions for the scanner and the semantic + * parts. + * + * Parameters + * priv : private data container for parser related tasks + * + * Returns + * void + ****************************************************************************/ +void vhdl_parser_deinit( vhdl_parser_priv_t *priv_data ) +{ + if (priv_data->buffer) + { + free( priv_data->buffer ); + priv_data->buffer = NULL; + } + + vhdl_sem_deinit( priv_data ); + vhdl_flex_deinit( priv_data->scanner ); + free( priv_data ); +} + +/***************************************************************************** + * void vhdl_set_entity( vhdl_parser_priv_t *priv, char *entityname ) + * + * Applies the entity name from BSDL as the part name. + * + * Parameters + * priv : private data container for parser related tasks + * entityname : entity name string, memory gets free'd + * + * Returns + * void + ****************************************************************************/ +static void vhdl_set_entity( vhdl_parser_priv_t *priv, char *entityname ) +{ + if (priv->jtag_ctrl->mode >= 1) + { + strncpy( priv->jtag_ctrl->part->part, entityname, MAXLEN_PART ); + priv->jtag_ctrl->part->part[MAXLEN_PART] = '\0'; + } + + free( entityname ); +} + +/***************************************************************************** + * void vhdl_port_add_name( vhdl_parser_priv_t *priv, char *name ) + * Port name management function + * + * Sets the name field of the temporary storage area for port description + * (port_desc) to the parameter name. + * + * Parameters + * priv : private data container for parser related tasks + * name : base name of the port, memory get's free'd lateron + * + * Returns + * void + ****************************************************************************/ +static void vhdl_port_add_name( vhdl_parser_priv_t *priv, char *name ) +{ + port_desc_t *pd = &(priv->tmp_port_desc); + string_elem_t *new_string; + + new_string = (string_elem_t *)malloc( sizeof( string_elem_t ) ); + if (new_string) + { + new_string->next = pd->names_list; + new_string->string = name; + + pd->names_list = new_string; + } + else + bsdl_msg( BSDL_MSG_FATAL, _("Out of memory, %s line %i\n"), __FILE__, __LINE__ ); +} + + +/***************************************************************************** + * void vhdl_port_add_bit( vhdl_parser_priv_t *priv ) + * Port name management function + * + * Sets the vector and index fields of the temporary storage area for port + * description (port_desc) to non-vector information. The low and high indice + * are set to equal numbers (exact value is irrelevant). + * + * Parameters + * priv : private data container for parser related tasks + * + * Returns + * void + ****************************************************************************/ +static void vhdl_port_add_bit( vhdl_parser_priv_t *priv ) +{ + port_desc_t *pd = &(priv->tmp_port_desc); + + pd->is_vector = 0; + pd->low_idx = 0; + pd->high_idx = 0; +} + + +/***************************************************************************** + * void vhdl_port_add_range( vhdl_parser_priv_t *priv, int low, int high ) + * Port name management function + * + * Sets the vector and index fields of the temporary storage area for port + * description (port_desc) to the specified vector information. + * + * Parameters + * priv : private data container for parser related tasks + * low : low index of vector + * high : high index of vector + * + * Returns + * void + ****************************************************************************/ +static void vhdl_port_add_range( vhdl_parser_priv_t *priv, int low, int high ) +{ + port_desc_t *pd = &(priv->tmp_port_desc); + + pd->is_vector = 1; + pd->low_idx = low; + pd->high_idx = high; +} + +/***************************************************************************** + * void vhdl_port_apply_port( vhdl_parser_priv_t *priv ) + * Port name management function + * + * Applies the current temporary port description to the final list + * of port descriptions. + * + * Parameters + * priv : private data container for parser related tasks + * + * Returns + * void + ****************************************************************************/ +static void vhdl_port_apply_port( vhdl_parser_priv_t *priv ) +{ + port_desc_t *tmp_pd = &(priv->tmp_port_desc); + port_desc_t *pd = (port_desc_t *)malloc( sizeof( port_desc_t ) ); + + if (pd) + { + /* insert at top of list */ + pd->next = priv->jtag_ctrl->port_desc; + priv->jtag_ctrl->port_desc = pd; + + /* copy information from temporary port descriptor */ + pd->names_list = tmp_pd->names_list; + pd->is_vector = tmp_pd->is_vector; + pd->low_idx = tmp_pd->low_idx; + pd->high_idx = tmp_pd->high_idx; + + /* and reset temporary port descriptor */ + tmp_pd->names_list = NULL; + tmp_pd->next = NULL; + } + else + bsdl_msg( BSDL_MSG_FATAL, _("Out of memory, %s line %i\n"), __FILE__, __LINE__ ); +} + +static void add_elem( vhdl_parser_priv_t *priv, vhdl_elem_t *el ) +{ + jtag_ctrl_t *jc = priv->jtag_ctrl; + + el->next = NULL; + if (jc->vhdl_elem_last) + jc->vhdl_elem_last->next = el; + jc->vhdl_elem_last = el; + + if (!jc->vhdl_elem_first) + jc->vhdl_elem_first = el; + + el->line = vhdl_flex_get_lineno( priv->scanner ); +} + +#if 0 +static void set_attr_bool( vhdl_parser_priv_t *priv, char *name, int value ) +{ + vhdl_elem_t *el = (vhdl_elem_t *)malloc( sizeof( vhdl_elem_t ) ); + + if (el) + { + el->type = VET_ATTRIBUTE_BOOL; + el->name = name; + el->payload.bool = value; + + add_elem( priv, el ); + } + else + bsdl_msg( BSDL_MSG_FATAL, _("Out of memory, %s line %i\n"), __FILE__, __LINE__ ); +} +#endif + +static void set_attr_decimal( vhdl_parser_priv_t *priv, char *name, int value ) +{ + vhdl_elem_t *el = (vhdl_elem_t *)malloc( sizeof( vhdl_elem_t ) ); + char *string = (char *)malloc( 10 ); + + if (el && string) + { + el->type = VET_ATTRIBUTE_DECIMAL; + el->name = name; + snprintf( string, 10, "%d", value ); + el->payload = string; + + add_elem( priv, el ); + } + else + bsdl_msg( BSDL_MSG_FATAL, _("Out of memory, %s line %i\n"), __FILE__, __LINE__ ); +} + +static void set_attr_string( vhdl_parser_priv_t *priv, char *name, char *string ) +{ + vhdl_elem_t *el = (vhdl_elem_t *)malloc( sizeof( vhdl_elem_t ) ); + + /* skip certain attributes */ + if ( (strcasecmp( name, "DESIGN_WARNING" ) == 0) + || (strcasecmp( name, "BOUNDARY_CELLS" ) == 0) + || (strcasecmp( name, "INSTRUCTION_SEQUENCE" ) == 0) + || (strcasecmp( name, "INSTRUCTION_USAGE" ) == 0) + || (strcasecmp( name, "ISC_DESIGN_WARNING" ) == 0)) + { + free( name ); + free( string ); + free( el ); + return; + } + + if (el) + { + el->type = VET_ATTRIBUTE_STRING; + el->name = name; + el->payload = string; + + add_elem(priv, el); + } + else + bsdl_msg( BSDL_MSG_FATAL, _("Out of memory, %s line %i\n"), __FILE__, __LINE__ ); +} + +#if 0 +static void set_attr_real( vhdl_parser_priv_t *priv, char *name, char *string ) +{ + vhdl_elem_t *el = (vhdl_elem_t *)malloc( sizeof( vhdl_elem_t ) ); + + if (el) + { + el->type = VET_ATTRIBUTE_REAL; + el->name = name; + el->payload.real = string; + + add_elem( priv, el ); + } + else + bsdl_msg( BSDL_MSG_FATAL, _("Out of memory, %s line %i\n"), __FILE__, __LINE__ ); +} +#endif + +#if 0 +static void set_attr_const( vhdl_parser_priv_t *priv, char *name, char *string ) +{ + vhdl_elem_t *el = (vhdl_elem_t *)malloc( sizeof( vhdl_elem_t ) ); + + if (el) + { + el->type = VET_CONSTANT; + el->name = name; + el->payload = string; + + add_elem( priv, el ); + } + else + bsdl_msg( BSDL_MSG_FATAL, _("Out of memory, %s line %i\n"), __FILE__, __LINE__ ); +} +#endif + + +/* + Local Variables: + mode:C + c-default-style:gnu + indent-tabs-mode:nil + End: +*/ diff --git a/jtag/src/bsdl/vhdl_flex.l b/jtag/src/bsdl/vhdl_flex.l new file mode 100644 index 00000000..5ea61af0 --- /dev/null +++ b/jtag/src/bsdl/vhdl_flex.l @@ -0,0 +1,612 @@ +/* + * $Id$ + * + * Original Lex source by Ken Parker, 1990 + * Extensions and adaptions for UrJTAG by Arnim Laeuger, 2007 + * + */ + +/*---------------------------------------------------------- + * + * Lex source for BSDL + * + *----------------------------------------------------------*/ +/* Date: 901003 */ + +/* + +Email header accompanying the original Yacc code: + http://www.eda.org/vug_bbs/bsdl.parser + +-----------------------------------8<-------------------------------------- + +Hello All, + +This is this first mailing of the BSDL* Version 0.0 parser specifications +we are sending to people who request it from our publicized E-Mail address; + + bsdl%hpmtlx@hplabs.HP.com + +You are free to redistribute this at will, but we feel that it would be +better if respondents asked for it directly so that their addresses can +be entered into our list for future mailings and updates. + +It would be helpful if you could confirm receipt of this transmission. +We also would be very interested to hear about your experiences with this +information and what you are planning to do with BSDL. + +Regards, + +Ken Parker +Hewlett-Packard Company + + +*Boundary-Scan Description Language - as documented in: + +"A Language for Describing Boundary-Scan Devices", K.P. Parker +and S. Oresjo, Proceedings 1990 International Test Conference, +Washington DC, pp 222-234 + + +- -----------------cut here--------------------------------------------------- + + +901004.0721 Hewlett-Packard Company +901016.1049 Manufacturing Test Division + P.O. Box 301 + Loveland, Colorado 80537 + USA + + October 1990 +Hello BSDL Parser Requestor, + + This Electronic Mail reply contains the computer specifications for +Hewlett-Packard's Version 0.0 BSDL parser. This section of the reply +explains the contents of the rest of this file. + +This file is composed of seven (7) parts: + + 1) How to use this file + + 2) UNIX* Lex source (lexicographical tokenizing rules) + + 3) UNIX* Yacc source (BNF-like syntax description) + + 4) A sample main program to recognize BSDL. + + 5) A BSDL description of the Texas Instruments 74bct8374 that is + recognized by the parser, for testing purposes. + + 6) The VHDL package STD_1149_1_1990 needed by this parser. + + 7) [added 901016] Porting experiences to other systems. + + +RECOMMENDATION: Save a copy of this file in archival storage before + processing it via the instructions below. This will + allow you to recover from errors, and allow you to + compare subsequently released data for changes. + +DISCLAIMERS: + +1. The IEEE 1149.1 Working Group has not endorsed BSDL Version 0.0 and + therefore no person may represent it as an IEEE standard or imply that + a resulting IEEE standard will be identical to it. + +2. The IEEE 1149.1 Working Group recognizes that BSDL Version 0.0 is a + well-conceived initiative that is likely to excelerate the creation + of tools that support the 1149.1 standard. As such, changes and + enhancements will be carefully considered so as not to needlessly + disrupt these development efforts. The overriding goal is the + ultimate success of the 1149.1 standard. + +LEGAL NOTICES: + + Hewlett-Packard Company makes no warranty of any kind with regard to + this information, including, but not limited to, the implied + waranties of merchantability and fitness for a particular purpose. + + Hewlett-Packard Company shall not be liable for errors contained + herein or direct, indirect, special, incidental, or consequential + damages in connection with the furnishing, performance, or use of + this material. + + +*UNIX is a trademark of AT&T in the USA and other countries. + +*/ + +%option bison-bridge +%option reentrant +%option prefix="vhdl" +%option outfile="lex.yy.c" + +%{ +/* Begin lex input specifications */ + +#include +#include + +#include "bsdl_sysdep.h" + +#include "bsdl_msg.h" + +#include "vhdl_bison.h" +#include "vhdl_parser.h" + +#ifdef DMALLOC +#include "dmalloc.h" +#endif + +#define YY_EXTRA_TYPE scan_extra_t * + +static char *new_string( const char * ); + +#define BINARY 0 +#define DECIMAL 1 +#define BIN_X 2 + +%} +%a 2800 +%e 1200 +%p 4700 +%n 520 +%k 140 +%o 3000 +%START RES BOU REG PAC +White [ \t\b\r]* +VHDL_Comment \-\-[^\n]* +Bin_X_Pattern [0-1X]+ +Digit [0-9] +Exponent [E][+-]?{Digit}+ +Real_Number {Digit}+[\.]{Digit}+{Exponent} +Decimal_Number {Digit}+ +Identifier [A-Z][A-Z0-9_]* +Quoted_String \"[^\"\n]*\" +Concatenate & +Single_Quote [\'] +Semicolon ; +Eol [\n] +Comma [,] +Lparen [\(] +Rparen [\)] +Colon_Equal \:\= +Colon [\:] +Period [\.] +Box [\<][\>] +Illegal [^A-Z0-9 \t\b\n\r\"\&\'\*\(\)\[\]\_\:\.\,\;\<\>] +Entity ENTITY +Port PORT +Generic GENERIC +Use USE +Attribute ATTRIBUTE +Is IS +Of OF +Constant CONSTANT +String STRING +End END +All ALL +Physical_Pin_Map PHYSICAL_PIN_MAP +Pin_Map_String PIN_MAP_STRING +True TRUE +False FALSE +Signal SIGNAL +Low LOW +Both BOTH +Out OUT +Inout INOUT +In IN +Buffer BUFFER +Linkage LINKAGE +Bit_Vector BIT_VECTOR +Bit BIT +To TO +Downto DOWNTO +Package PACKAGE +Body BODY +Type TYPE +Subtype SUBTYPE +Record RECORD +Array ARRAY +Positive POSITIVE +Range RANGE +Cell_Info CELL_INFO +Input INPUT +Output2 OUTPUT2 +Output3 OUTPUT3 +Control CONTROL +Controlr CONTROLR +Internal INTERNAL +Clock CLOCK +Observe_Only OBSERVE_ONLY +Bidir BIDIR +Bidir_In BIDIR_IN +Bidir_Out BIDIR_OUT +Z Z +Extest EXTEST +Sample SAMPLE +Intest INTEST +Runbist RUNBIST +Pi PI +Po PO +Upd UPD +Cap CAP +X X +Zero ZERO +One ONE +Bsdl_Extension BSDL_EXTENSION +Std_1532_2001 STD_1532_2001 +Std_1532_2002 STD_1532_2002 +%% +{Entity} {return( ENTITY ); } +{Port} {yyextra->Base = DECIMAL; /* Default number base */ + return( PORT ); } +{Generic} {yyextra->Base = DECIMAL; return( GENERIC ); } +{Use} {yyextra->Base = DECIMAL; return( USE ); } +{Attribute} {yyextra->Base = DECIMAL; return( ATTRIBUTE ); } +{Is} {return( IS ); } +{Constant} {yyextra->Base = DECIMAL; return( CONSTANT ); } +{String} {return( STRING ); } +{End} {yyextra->Base = DECIMAL; + BEGIN INITIAL; /* Turn off start conditions */ + return( END ); } +{All} {return( ALL ); } +{Of} {return( OF ); } +{Physical_Pin_Map} {return( PHYSICAL_PIN_MAP ); } +{Pin_Map_String} {return( PIN_MAP_STRING ); } +{True} {return( TRUE ); } +{False} {return( FALSE ); } +{Signal} {return( SIGNAL ); } +{Low} {return( LOW ); } +{Both} {return( BOTH ); } +{In} {return( IN ); } +{Out} {return( OUT ); } +{Inout} {return( INOUT ); } +{Buffer} {return( BUFFER ); } +{Linkage} {return( LINKAGE ); } +{Bit} {return( BIT ); } +{Bit_Vector} {return( BIT_VECTOR ); } +{To} {return( TO ); } +{Downto} {return( DOWNTO ); } +{Package} {return( PACKAGE ); } +{Body} {return( BODY ); } +{Type} {return( TYPE ); } +{Subtype} {return( SUBTYPE ); } +{Record} {return( RECORD ); } +{Array} {yyextra->Base = DECIMAL; return( ARRAY ); } +{Positive} {return( POSITIVE ); } +{Range} {return( RANGE ); } +{Cell_Info} {BEGIN PAC; return( CELL_INFO ); } +{Bsdl_Extension} {return( BSDL_EXTENSION ); } +{Std_1532_2001} {return( STD_1532_2001 ); } +{Std_1532_2002} {return( STD_1532_2002 ); } +{Input} {return( INPUT ); } +{Output2} {return( OUTPUT2 ); } +{Output3} {return( OUTPUT3 ); } +{Controlr} {return( CONTROLR ); } +{Control} {return( CONTROL ); } +{Internal} {return( INTERNAL ); } +{Clock} {return( CLOCK ); } +{Observe_Only} {return( OBSERVE_ONLY ); } +{Bidir} {return( BIDIR ); } +{Bidir_In} {return( BIDIR_IN ); } +{Bidir_Out} {return( BIDIR_OUT ); } +{Extest} {return( EXTEST ); } +{Sample} {return( SAMPLE ); } +{Intest} {return( INTEST ); } +{Runbist} {return( RUNBIST ); } +{Pi} {return( PI ); } +{Po} {return( PO ); } +{Upd} {return( UPD ); } +{Cap} {return( CAP ); } +{X} {return( X ); } +{Zero} {return( ZERO ); } +{One} {return( ONE ); } +{Z} {return( Z ); } +{Eol} {yylineno++; /* Count lines */} +{Comma} {return( COMMA ); } +{Lparen} {return( LPAREN );} +{Rparen} {return( RPAREN );} +{Period} {return( PERIOD ); } +{Colon} {return( COLON ); } +{Box} {return( BOX ); } +{Single_Quote} {yyextra->Base = BIN_X; return( SINGLE_QUOTE ); } +{Colon_Equal} {return( COLON_EQUAL ); } +{White} { /* Do Nothing on White Space */ } +{VHDL_Comment} { /* Do Nothing on Comments */ } +{Bin_X_Pattern} {if (yyextra->Base != BIN_X) REJECT; + yylval->str = new_string( yytext ); + return( BIN_X_PATTERN );} +{Identifier} {yylval->str = new_string( yytext ); + return( IDENTIFIER ); } +{Quoted_String} {yylval->str = new_string( yytext ); + return( QUOTED_STRING ); } +{Decimal_Number} {if (yyextra->Base != DECIMAL) REJECT; + yylval->integer = atoi( (char *)yytext ); + return( DECIMAL_NUMBER );} +{Real_Number} {yylval->str = new_string( yytext ); + return( REAL_NUMBER );} +{Concatenate} {return( CONCATENATE );} +{Semicolon} {return( SEMICOLON );} +{Illegal} {if (yyextra->debug || (yyextra->mode >= 0)) + bsdl_msg( BSDL_MSG_ERR, + _("Illegal character %c (/%03o) at line %d:\n"), + (char)yytext[yyleng-1], (int)yytext[yyleng-1], + yylineno ); + yyextra->Compile_Errors++; + return( ILLEGAL ); /* Will cause syntax error */} +<> { + yypop_buffer_state( yyscanner ); + if ( !YY_CURRENT_BUFFER ) + yyterminate(); +} +%% +/***************************************************************************** + * void *vhdl_flex_init( FILE *f, int mode, int debug ) + * + * Initializes the scanner and storage elements extra data structure. + * + * Parameters + * f : descriptor of file for scanning + * mode : -1 -> read file + * no further action based on components + * 0 -> read file and extract all components + * dump commands to stdout, do not execute commands + * 1 -> read file and extract all components + * execute commands + * debug : 1 -> emit failure messages + * 0 -> no failure messages + * + * Returns + * pointer to newly initialized scanner structure + ****************************************************************************/ +void *vhdl_flex_init( FILE *f, int mode, int debug ) +{ + scan_extra_t *extra; + yyscan_t scanner; + + /* get our scanner structure */ + if (yylex_init( &scanner ) != 0) + { + bsdl_msg( BSDL_MSG_FATAL, _("Scanner could not be initialized\n") ); + return NULL; + } + yyset_in( f, scanner ); + + if (!(extra = (scan_extra_t *)malloc( sizeof( scan_extra_t ) ))) + { + bsdl_msg( BSDL_MSG_FATAL, _("Out of memory, %s line %i\n"), __FILE__, __LINE__ ); + yylex_destroy( scanner ); + return NULL; + } + + extra->mode = mode; + extra->debug = debug; + extra->Compile_Errors = 0; + extra->Base = DECIMAL; + + yyset_extra( extra, scanner ); + + return scanner; +} + + +/***************************************************************************** + * void vhdl_flex_deinit( void *scanner ) + * + * Deinitializes the scanner and closes the input file. + * + * Parameters + * scanner : pointer to scanner definition structure + * + * Returns + * void + ****************************************************************************/ +void vhdl_flex_deinit( void *scanner ) +{ + if (yyget_in( scanner )) + { + /* file might still be open so close it in any case + e.g. when a compile error occured and the parser didn't hit EOF/yywrap() */ + fclose( yyget_in( scanner ) ); + yyset_in( NULL, scanner ); + } + free( yyget_extra( scanner ) ); + yylex_destroy( scanner ); +} + + +/***************************************************************************** + * void yywrap( yyscan_t scanner ) + * + * Closes the input file upon EOF condition. + * + * Parameters + * scanner : pointer to scanner definition structure + * + * Returns + * 1 + ****************************************************************************/ +int yywrap( yyscan_t scanner ) +{ + if (yyget_in( scanner )) + { + fclose( yyget_in( scanner ) ); + yyset_in( NULL, scanner ); + } + return 1; +} + + +/***************************************************************************** + * char *new_string( const char *str ) + * + * Allocates memory for a string and copies the contents of *str. + * + * Parameters + * str : pointer to string to be duplicated + * + * Returns + * pointer to allocated and initialized string memory + ****************************************************************************/ +static char *new_string( const char *str ) +{ + char *n_str; + size_t n_str_size; + + n_str_size = strlen( str ) + 1; + if ((n_str = (char *)malloc( n_str_size ))) + { + strncpy( n_str, str, n_str_size-1 ); + n_str[n_str_size-1] = '\0'; /* set very last element to EOS */ + } + else + bsdl_msg( BSDL_MSG_FATAL, _("Out of memory, %s line %i\n"), __FILE__, __LINE__ ); + + return n_str; +} + + +/***************************************************************************** + * void vhdl_flex_switch_file( yyscan_t scanner, char *filename ) + * + * Selects the specified file for further scanning. + * + * Parameters + * scanner : pointer to scanner definition structure + * filename : name of the new file to be scanned + * + * Returns + * void + ****************************************************************************/ +void vhdl_flex_switch_file( yyscan_t scanner, char *filename ) +{ + scan_extra_t *extra; + FILE *f; + char *s; + + /* convert filename to all upper case */ + s = filename; + while (*s) + { + if (islower( *s )) + *s = toupper( *s ); + s++; + } + + /* file in current directory has precedence */ + f = fopen( filename, "r" ); + if (!f) + { + const char *db_path = jtag_get_data_dir(); + char *db_file; + + if ((db_file = (char *)malloc( strlen( db_path ) + + 1 + /* "/" */ + 4 + /* "bsdl" */ + 1 + /* "/" */ + strlen( filename ) + + 1 ))) + { + strcpy( db_file, db_path ); + strcat( db_file, "/" ); + strcat( db_file, "bsdl" ); + strcat( db_file, "/" ); + strcat( db_file, filename ); + f = fopen( db_file, "r" ); + + if (!f) + bsdl_msg( BSDL_MSG_FATAL, _("Cannot open file %s or %s.\n"), filename, db_file ); + free( db_file ); + if (!f) + return; + } + } + + yypush_buffer_state( yy_create_buffer( f, YY_BUF_SIZE, scanner ), scanner ); + extra = yyget_extra( scanner ); + yyset_lineno( 1, scanner ); +} + + +/***************************************************************************** + * int vhdl_flex_get_compile_errors( yyscan_t scanner ) + * + * Retrieves the accumulated number of compile errors encountered so far. + * + * Parameters + * scanner : pointer to scanner definition structure + * + * Returns + * number of compile errors + ****************************************************************************/ +int vhdl_flex_get_compile_errors( yyscan_t scanner ) +{ + scan_extra_t *extra = yyget_extra( scanner ); + return extra->Compile_Errors; +} + + +/***************************************************************************** + * void vhdl_flex_set_compile_errors( int n, yyscan_t scanner ) + * + * Sets the number of compile errors to n. + * + * Parameters + * n : preset number + * scanner : pointer to scanner definition structure + * + * Returns + * void + ****************************************************************************/ +static void vhdl_flex_set_compile_errors( int n, yyscan_t scanner ) +{ + scan_extra_t *extra = yyget_extra( scanner ); + extra->Compile_Errors = n; +} + + +/***************************************************************************** + * int vhdl_flex_postinc_compile_errors( yyscan_t scanner ) + * + * Increments the number of compile errors. + * + * Parameters + * scanner : pointer to scanner definition structure + * + * Returns + * number of compile errors before increment + ****************************************************************************/ +int vhdl_flex_postinc_compile_errors( yyscan_t scanner ) +{ + int errors = vhdl_flex_get_compile_errors( scanner ); + + vhdl_flex_set_compile_errors( errors+1, scanner ); + return errors; +} + + +/***************************************************************************** + * int vhdl_flex_get_lineno( yyscan_t scanner ) + * + * Returns the current line number in the scanned file. + * + * Parameters + * scanner : pointer to scanner definition structure + * + * Returns + * current line number + ****************************************************************************/ +int vhdl_flex_get_lineno( yyscan_t scanner ) +{ + return yyget_lineno( scanner ); +} + + +/* + Local Variables: + mode:C + c-default-style:gnu + indent-tabs-mode:nil + End: +*/ diff --git a/jtag/src/bsdl/vhdl_parser.h b/jtag/src/bsdl/vhdl_parser.h new file mode 100644 index 00000000..f429baf7 --- /dev/null +++ b/jtag/src/bsdl/vhdl_parser.h @@ -0,0 +1,43 @@ +/* + * $Id$ + * + * Copyright (C) 2008, Arnim Laeuger + * + * This program is free software; you can redistribute it and/or + * modify it 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. + * + * Written by Arnim Laeuger , 2008. + * + */ + +#ifndef VHDL_PARSER_H +#define VHDL_PARSER_H + +#include "bsdl_types.h" + +/* VHDL lexer declarations */ +void *vhdl_flex_init( FILE *, int, int ); +void vhdl_flex_deinit( void * ); +void vhdl_flex_switch_file( void *, char * ); +int vhdl_flex_get_compile_errors( void * ); +int vhdl_flex_postinc_compile_errors( void * ); +int vhdl_flex_get_lineno( void * ); + +/* VHDL parser declarations */ +vhdl_parser_priv_t *vhdl_parser_init( FILE *, jtag_ctrl_t * ); +void vhdl_parser_deinit( vhdl_parser_priv_t * ); +int vhdlparse( vhdl_parser_priv_t * ); + +#endif /* VHDL_PARSER_H */