merged BSDL parser from branches/bsdl 787:903 to trunk

git-svn-id: https://urjtag.svn.sourceforge.net/svnroot/urjtag/trunk@904 b68d4a1b-bc3d-0410-92ed-d4ac073336b7
master
Arnim Läuger 17 years ago
parent 5819ae250d
commit b62f2996f0

@ -1,5 +1,6 @@
2007-12-30 Arnim Laeuger <arniml@users.sourceforge.net>
* many files: integration of BSDL parser
* data/xilinx/PARTS: added xc2v80-fg256,xc2v250-fg256,xc2v1000-fg256
'[ 1859678 ] jtag support for xilinx xc2v80-fg256, xc2v250, xc2v1000 FPGA' (Alexander Didebulidze)
* data/altera/ep1c12/ep1c12: CLAMP and HIGHZ instructions activated

@ -4,6 +4,7 @@ Also see libbrux/NEWS for more news, especially regarding the flash support.
urjtag-n/a
* Integration of BSDL parser (Arnim Laeuger)
* New and updated cable drivers
- Vision EP9307 GPIO (Hartley Sweeten)
* Added new JTAG declarations for

@ -68,6 +68,7 @@ AC_CONFIG_FILES(
src/bus/Makefile
src/cmd/Makefile
src/svf/Makefile
src/bsdl/Makefile
po/Makefile.in
)

@ -59,6 +59,7 @@ nobase_dist_pkgdata_DATA = \
analog/bf533/bf533 \
analog/PARTS \
analog/sharc21065l/STEPPINGS \
analog/sharc21065l/sharc21065l
analog/sharc21065l/sharc21065l \
brecis/PARTS \
brecis/msp2006/STEPPINGS \
@ -72,6 +73,8 @@ nobase_dist_pkgdata_DATA = \
broadcom/bcm4712/bcm4712 \
broadcom/bcm5421s/STEPPINGS \
broadcom/bcm5421s/bcm5421s \
bsdl/STD_1149_1_1990 \
bsdl/STD_1149_1_1994 \
dec/PARTS \
dec/sa1100/STEPPINGS \
dec/sa1100/sa1100 \

@ -0,0 +1,149 @@
package STD_1149_1_1990 is
-- Give pin mapping declarations
attribute PIN_MAP : string;
subtype PIN_MAP_STRING is string;
-- Give TAP control declarations
type CLOCK_LEVEL is (LOW, BOTH);
type CLOCK_INFO is record
FREQ : real;
LEVEL: CLOCK_LEVEL;
end record;
attribute TAP_SCAN_IN : boolean;
attribute TAP_SCAN_OUT : boolean;
attribute TAP_SCAN_CLOCK: CLOCK_INFO;
attribute TAP_SCAN_MODE : boolean;
attribute TAP_SCAN_RESET: boolean;
-- Give instruction register declarations
attribute INSTRUCTION_LENGTH : integer;
attribute INSTRUCTION_OPCODE : string;
attribute INSTRUCTION_CAPTURE : string;
attribute INSTRUCTION_DISABLE : string;
attribute INSTRUCTION_GUARD : string;
attribute INSTRUCTION_PRIVATE : string;
attribute INSTRUCTION_USAGE : string;
attribute INSTRUCTION_SEQUENCE : string;
-- Give ID and USER code declarations
type ID_BITS is ('0', '1', 'x', 'X');
type ID_STRING is array (31 downto 0) of ID_BITS;
attribute IDCODE_REGISTER : ID_STRING;
attribute USERCODE_REGISTER: ID_STRING;
-- Give register declarations
attribute REGISTER_ACCESS : string;
-- Give boundary cell declarations
type BSCAN_INST is (EXTEST, SAMPLE, INTEST, RUNBIST);
type CELL_TYPE is (INPUT, INTERNAL, CLOCK,
CONTROL, CONTROLR, OUTPUT2,
OUTPUT3, BIDIR_IN, BIDIR_OUT);
type CAP_DATA is (PI, PO, UPD, CAP, X, ZERO, ONE);
type CELL_DATA is record
CT : CELL_TYPE;
I : BSCAN_INST;
CD : CAP_DATA;
end record;
type CELL_INFO is array (positive range <>) of CELL_DATA;
-- Boundary cell deferred constants (see package body)
constant BC_1 : CELL_INFO;
constant BC_2 : CELL_INFO;
constant BC_3 : CELL_INFO;
constant BC_4 : CELL_INFO;
constant BC_5 : CELL_INFO;
constant BC_6 : CELL_INFO;
-- Boundary register declarations
attribute BOUNDARY_CELLS : string;
attribute BOUNDARY_LENGTH : integer;
attribute BOUNDARY_REGISTER : string;
-- Miscellaneous
attribute DESIGN_WARNING : string;
end STD_1149_1_1990; -- End of IEEE Std 1149.1-1990 Package
package body STD_1149_1_1990 is -- Standard boundary cells
-- Description for f10-12, f10-16, f10-18c, f10-18d, f10-21c
constant BC_1 : CELL_INFO :=
((INPUT, EXTEST, PI), (OUTPUT2, EXTEST, PI),
(INPUT, SAMPLE, PI), (OUTPUT2, SAMPLE, PI),
(INPUT, INTEST, PI), (OUTPUT2, INTEST, PI),
(INPUT, RUNBIST, PI), (OUTPUT2, RUNBIST, PI),
(OUTPUT3, EXTEST, PI), (INTERNAL, EXTEST, PI),
(OUTPUT3, SAMPLE, PI), (INTERNAL, SAMPLE, PI),
(OUTPUT3, INTEST, PI), (INTERNAL, INTEST, PI),
(OUTPUT3, RUNBIST, PI), (INTERNAL, RUNBIST, PI),
(CONTROL, EXTEST, PI), (CONTROLR, EXTEST, PI),
(CONTROL, SAMPLE, PI), (CONTROLR, SAMPLE, PI),
(CONTROL, INTEST, PI), (CONTROLR, INTEST, PI),
(CONTROL, RUNBIST, PI), (CONTROLR, RUNBIST, PI) );
-- Description for f10-8, f10-17, f10-19c, f10-19d, f10-22c
constant BC_2 : CELL_INFO :=
((INPUT, EXTEST, PI), (OUTPUT2, EXTEST, UPD),
(INPUT, SAMPLE, PI), (OUTPUT2, SAMPLE, PI),
(INPUT, INTEST, UPD), -- Intest on output2 not supported
(INPUT, RUNBIST, UPD), (OUTPUT2, RUNBIST, UPD),
(OUTPUT3, EXTEST, UPD), (INTERNAL, EXTEST, PI),
(OUTPUT3, SAMPLE, PI), (INTERNAL, SAMPLE, PI),
(OUTPUT3, INTEST, PI), (INTERNAL, INTEST, UPD),
(OUTPUT3, RUNBIST, PI), (INTERNAL, RUNBIST, UPD),
(CONTROL, EXTEST, UPD), (CONTROLR, EXTEST, UPD),
(CONTROL, SAMPLE, PI), (CONTROLR, SAMPLE, PI),
(CONTROL, INTEST, PI), (CONTROLR, INTEST, PI),
(CONTROL, RUNBIST, PI), (CONTROLR, RUNBIST, PI) );
-- Description for f10-9
constant BC_3 : CELL_INFO :=
((INPUT, EXTEST, PI), (INTERNAL, EXTEST, PI),
(INPUT, SAMPLE, PI), (INTERNAL, SAMPLE, PI),
(INPUT, INTEST, PI), (INTERNAL, INTEST, PI),
(INPUT, RUNBIST, PI), (INTERNAL, RUNBIST, PI) );
-- Description for f10-10, f10-11
constant BC_4 : CELL_INFO :=
((INPUT, EXTEST, PI), -- Intest on input not supported
(INPUT, SAMPLE, PI), -- Runbist on input not supported
(CLOCK, EXTEST, PI), (INTERNAL, EXTEST, PI),
(CLOCK, SAMPLE, PI), (INTERNAL, SAMPLE, PI),
(CLOCK, INTEST, PI), (INTERNAL, INTEST, PI),
(CLOCK, RUNBIST, PI), (INTERNAL, RUNBIST, PI) );
-- Description for f10-20c, a combined input/control
constant BC_5 : CELL_INFO :=
((INPUT, EXTEST, PI), (CONTROL, EXTEST, PI),
(INPUT, SAMPLE, PI), (CONTROL, SAMPLE, PI),
(INPUT, INTEST, UPD), (CONTROL, INTEST, UPD),
(INPUT, RUNBIST, PI), (CONTROL, RUNBIST, PI) );
-- Description for f10-22d, a reversible cell
constant BC_6 : CELL_INFO :=
((BIDIR_IN, EXTEST, PI), (BIDIR_OUT, EXTEST, UPD),
(BIDIR_IN, SAMPLE, PI), (BIDIR_OUT, SAMPLE, PI),
(BIDIR_IN, INTEST, UPD), (BIDIR_OUT, INTEST, PI),
(BIDIR_IN, RUNBIST, UPD), (BIDIR_OUT, RUNBIST, PI) );
end STD_1149_1_1990; -- End of 1990 Package Body

@ -0,0 +1,170 @@
package STD_1149_1_1994 is
-- Give component conformance declaration
attribute COMPONENT_CONFORMANCE : string;
-- Give pin mapping declarations
attribute PIN_MAP : string;
subtype PIN_MAP_STRING is string;
-- Give TAP control declarations
type CLOCK_LEVEL is (LOW, BOTH);
type CLOCK_INFO is record
FREQ : real;
LEVEL: CLOCK_LEVEL;
end record;
attribute TAP_SCAN_IN : boolean;
attribute TAP_SCAN_OUT : boolean;
attribute TAP_SCAN_CLOCK: CLOCK_INFO;
attribute TAP_SCAN_MODE : boolean;
attribute TAP_SCAN_RESET: boolean;
-- Give instruction register declarations
attribute INSTRUCTION_LENGTH : integer;
attribute INSTRUCTION_OPCODE : string;
attribute INSTRUCTION_CAPTURE : string;
attribute INSTRUCTION_PRIVATE : string;
-- Give ID and USER code declarations
type ID_BITS is ('0', '1', 'x', 'X');
type ID_STRING is array (31 downto 0) of ID_BITS;
attribute IDCODE_REGISTER : ID_STRING;
attribute USERCODE_REGISTER: ID_STRING;
-- Give register declarations
attribute REGISTER_ACCESS : string;
-- Give boundary cell declarations
type BSCAN_INST is (EXTEST, SAMPLE, INTEST);
type CELL_TYPE is (INPUT, INTERNAL, CLOCK, OBSERVE_ONLY,
CONTROL, CONTROLR, OUTPUT2,
OUTPUT3, BIDIR_IN, BIDIR_OUT);
type CAP_DATA is (PI, PO, UPD, CAP, X, ZERO, ONE);
type CELL_DATA is record
CT : CELL_TYPE;
I : BSCAN_INST;
CD : CAP_DATA;
end record;
type CELL_INFO is array (positive range <>) of CELL_DATA;
-- Boundary cell deferred constants (see package body)
constant BC_0 : CELL_INFO;
constant BC_1 : CELL_INFO;
constant BC_2 : CELL_INFO;
constant BC_3 : CELL_INFO;
constant BC_4 : CELL_INFO;
constant BC_5 : CELL_INFO;
constant BC_6 : CELL_INFO;
constant BC_7 : CELL_INFO;
-- Boundary register declarations
attribute BOUNDARY_LENGTH : integer;
attribute BOUNDARY_REGISTER : string;
-- Miscellaneous
attribute PORT_GROUPING : string;
attribute RUNBIST_EXECUTION : string;
attribute INTEST_EXECUTION : string;
subtype BSDL_EXTENSION is string;
attribute COMPLIANCE_PATTERNS : string;
attribute DESIGN_WARNING : string;
end STD_1149_1_1994; -- End of 1149.1-1994 Package
package body STD_1149_1_1994 is -- Standard boundary cells
-- Generic cell capturing minimum allowed data
constant BC_0 : CELL_INFO :=
((INPUT, EXTEST, PI), (OUTPUT2, EXTEST, X),
(INPUT, SAMPLE, PI), (OUTPUT2, SAMPLE, PI),
(INPUT, INTEST, X), (OUTPUT2, INTEST, PI),
(OUTPUT3, EXTEST, X), (INTERNAL, EXTEST, X),
(OUTPUT3, SAMPLE, PI), (INTERNAL, SAMPLE, X),
(OUTPUT3, INTEST, PI), (INTERNAL, INTEST, X),
(CONTROL, EXTEST, X), (CONTROLR, EXTEST, X),
(CONTROL, SAMPLE, PI), (CONTROLR, SAMPLE, PI),
(CONTROL, INTEST, PI), (CONTROLR, INTEST, PI),
(BIDIR_IN,EXTEST, PI), (BIDIR_OUT, EXTEST, X ),
(BIDIR_IN,SAMPLE, PI), (BIDIR_OUT, SAMPLE, PI),
(BIDIR_IN,INTEST, X ), (BIDIR_OUT, INTEST, PI),
(OBSERVE_ONLY, SAMPLE, PI), (OBSERVE_ONLY, EXTEST, PI) );
-- Description for f10-18, f10-29, f10-31c, f10-31d, f10-33c, f10-41d
constant BC_1 : CELL_INFO :=
((INPUT, EXTEST, PI), (OUTPUT2, EXTEST, PI),
(INPUT, SAMPLE, PI), (OUTPUT2, SAMPLE, PI),
(INPUT, INTEST, PI), (OUTPUT2, INTEST, PI),
(OUTPUT3, EXTEST, PI), (INTERNAL, EXTEST, PI),
(OUTPUT3, SAMPLE, PI), (INTERNAL, SAMPLE, PI),
(OUTPUT3, INTEST, PI), (INTERNAL, INTEST, PI),
(CONTROL, EXTEST, PI), (CONTROLR, EXTEST, PI),
(CONTROL, SAMPLE, PI), (CONTROLR, SAMPLE, PI),
(CONTROL, INTEST, PI), (CONTROLR, INTEST, PI) );
-- Description for f10-14, f10-30, f10-32c, f10-32d, f10-35c
constant BC_2 : CELL_INFO :=
((INPUT, EXTEST, PI), (OUTPUT2, EXTEST, UPD),
(INPUT, SAMPLE, PI), (OUTPUT2, SAMPLE, PI),
(INPUT, INTEST, UPD), -- Intest on output2 not supported
(OUTPUT3, EXTEST, UPD), (INTERNAL, EXTEST, PI),
(OUTPUT3, SAMPLE, PI), (INTERNAL, SAMPLE, PI),
(OUTPUT3, INTEST, PI), (INTERNAL, INTEST, UPD),
(CONTROL, EXTEST, UPD), (CONTROLR, EXTEST, UPD),
(CONTROL, SAMPLE, PI), (CONTROLR, SAMPLE, PI),
(CONTROL, INTEST, PI), (CONTROLR, INTEST, PI) );
-- Description for f10-15
constant BC_3 : CELL_INFO :=
((INPUT, EXTEST, PI), (INTERNAL, EXTEST, PI),
(INPUT, SAMPLE, PI), (INTERNAL, SAMPLE, PI),
(INPUT, INTEST, PI), (INTERNAL, INTEST, PI) );
-- Description for f10-16, f10-17
constant BC_4 : CELL_INFO :=
((INPUT, EXTEST, PI), -- Intest on input not supported
(INPUT, SAMPLE, PI),
(OBSERVE_ONLY, EXTEST, PI),
(OBSERVE_ONLY, SAMPLE, PI), -- Intest on observe_only not supported
(CLOCK, EXTEST, PI), (INTERNAL, EXTEST, PI),
(CLOCK, SAMPLE, PI), (INTERNAL, SAMPLE, PI),
(CLOCK, INTEST, PI), (INTERNAL, INTEST, PI) );
-- Description for f10-41c, a combined input/control
constant BC_5 : CELL_INFO :=
((INPUT, EXTEST, PI), (CONTROL, EXTEST, PI),
(INPUT, SAMPLE, PI), (CONTROL, SAMPLE, PI),
(INPUT, INTEST, UPD), (CONTROL, INTEST, UPD) );
-- Description for f10-35d, a reversible cell
-- !! Not recommended; replaced by BC_7 below !!
constant BC_6 : CELL_INFO :=
((BIDIR_IN, EXTEST, PI), (BIDIR_OUT, EXTEST, UPD),
(BIDIR_IN, SAMPLE, PI), (BIDIR_OUT, SAMPLE, PI),
(BIDIR_IN, INTEST, UPD), (BIDIR_OUT, INTEST, PI) );
-- Description for f10-34d, self monitor reversible
-- !! Recommended over cell BC_6 !!
constant BC_7 : CELL_INFO :=
((BIDIR_IN, EXTEST, PI), (BIDIR_OUT, EXTEST, PO),
(BIDIR_IN, SAMPLE, PI), (BIDIR_OUT, SAMPLE, PI),
(BIDIR_IN, INTEST, UPD), (BIDIR_OUT, INTEST, PI) );
end STD_1149_1_1994; -- End of IEEE Std 1149.1-1994 Package Body

@ -0,0 +1,34 @@
/*
* $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 <arniml@users.sourceforge.net>, 2007.
*
*/
#ifndef BSDL_H
#define BSDL_H
extern int bsdl_debug;
int bsdl_read_file(const char *, int, char *);
void bsdl_set_path(const char *);
int bsdl_scan_files(const char *, int);
#endif /* BSDL_H */

@ -29,7 +29,8 @@ SUBDIRS = \
part \
bus \
cmd \
svf
svf \
bsdl
bin_PROGRAMS = \
jtag \
@ -53,7 +54,8 @@ jtag_DEPENDENCIES = \
part/libpart.a \
bus/libbus.a \
cmd/libcmd.a \
svf/libsvf.a
svf/libsvf.a \
bsdl/libbsdl.a
jtag_LDADD = \
-Ltap -ltap \
@ -64,6 +66,7 @@ jtag_LDADD = \
-L../libbrux -lbrux \
-Lbus -lbus \
-Lsvf -lsvf \
-Lbsdl -lbsdl \
-lm \
@FTD2XXLIB@ \
@LIBINTL@

@ -0,0 +1,39 @@
#
# $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.
#
include $(top_srcdir)/Makefile.rules
noinst_LIBRARIES = libbsdl.a
libbsdl_a_SOURCES = \
bsdl.c \
bsdl_bison.y \
bsdl_flex.l \
bsdl_sem.c
AM_LFLAGS = -i
MAINTAINERCLEANFILES = \
bsdl_bison.c \
bsdl_bison.h \
bsdl_flex.c
INCLUDES = -DJTAG_DATA_DIR=\"$(pkgdatadir)\"

@ -0,0 +1,304 @@
/*
* $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 <arniml@users.sourceforge.net>, 2007.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#define __USE_GNU
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#include "sysdep.h"
#include <jtag.h>
#include <brux/cmd.h>
#include "bsdl.h"
static char **bsdl_path_list = NULL;
int bsdl_debug = 0;
void bsdl_msg(int type, char *format, ...)
{
va_list lst;
va_start(lst, format);
switch (type) {
case BSDL_MSG_NOTE:
printf("-N- ");
break;
case BSDL_MSG_WARN:
printf("-W- ");
break;
case BSDL_MSG_ERR:
printf("-E- ");
break;
default:
printf("-?- ");
break;
}
vprintf(format, lst);
va_end(lst);
}
/*****************************************************************************
* bsdl_read_file(BSDL_File_Name, mode, idcode)
*
* 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
*
****************************************************************************/
int bsdl_read_file(const char *BSDL_File_Name, int mode, const char *idcode)
{
FILE *BSDL_File;
parser_priv_t *parser_priv;
int Compile_Errors = 1;
int idcode_match = 0;
BSDL_File = fopen(BSDL_File_Name, "r");
if (bsdl_debug || (mode == 0))
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);
return -1;
}
if ((parser_priv = bsdl_parser_init(BSDL_File))) {
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, _("Shain 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.part = chain->parts->parts[chain->active_part];
} else
parser_priv->jtag_ctrl.part = NULL;
} else
parser_priv->jtag_ctrl.part = NULL;
parser_priv->jtag_ctrl.mode = mode;
parser_priv->jtag_ctrl.idcode = NULL;
bsdlparse(parser_priv);
Compile_Errors = bsdl_flex_get_compile_errors(parser_priv->scanner);
if (Compile_Errors == 0) {
if (bsdl_debug)
bsdl_msg(BSDL_MSG_NOTE, "BSDL file '%s' compiled correctly\n", BSDL_File_Name);
} else {
bsdl_msg(BSDL_MSG_ERR, "BSDL file '%s' contains errors, stopping\n", BSDL_File_Name);
}
if (Compile_Errors == 0)
bsdl_ac_finalize(parser_priv);
if ((Compile_Errors == 0) && parser_priv->jtag_ctrl.idcode) {
if (bsdl_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 (bsdl_debug) {
if (idcode_match)
bsdl_msg(BSDL_MSG_NOTE, _("IDCODE matched\n") );
else
bsdl_msg(BSDL_MSG_NOTE, _("IDCODE mismatch\n") );
}
}
}
free(parser_priv->jtag_ctrl.idcode);
parser_priv->jtag_ctrl.idcode = NULL;
}
bsdl_parser_deinit(parser_priv);
}
return Compile_Errors == 0 ? idcode_match : -1;
}
/*****************************************************************************
* void bsdl_set_path(const char *pathlist)
*
* Dissects pathlist and enters its elements to the global variable
* bsdl_path_list.
*
* Return value:
* void
****************************************************************************/
void bsdl_set_path(const char *pathlist)
{
char *delim;
char *elem;
int num;
/* free memory of current path list */
if (bsdl_path_list) {
for (num = 0; bsdl_path_list[num]; num++)
if (bsdl_path_list[num])
free(bsdl_path_list[num]);
free(bsdl_path_list);
bsdl_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)) {
num++;
/* extend path list array */
bsdl_path_list = (char **)realloc(bsdl_path_list, (num+1) * sizeof(char *));
/* enter path element up to the delimeter */
bsdl_path_list[num-1] = strndup(elem, (size_t)(delim - elem));
bsdl_path_list[num] = NULL;
}
elem = delim ? delim + 1 : elem + strlen(elem);
}
if (bsdl_debug)
for (num = 0; bsdl_path_list[num] != NULL; num++) {
bsdl_msg(BSDL_MSG_NOTE, "%s\n", bsdl_path_list[num]);
}
}
/*****************************************************************************
* int bsdl_scan_files(const char *idcode, int 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
*
****************************************************************************/
int bsdl_scan_files(const char *idcode, int mode)
{
int idx = 0;
int result = 0;
/* abort if no path list was specified */
if (bsdl_path_list == NULL)
return 0;
while (bsdl_path_list[idx] && (result <= 0)) {
DIR *dir;
if ((dir = opendir(bsdl_path_list[idx]))) {
struct dirent *elem;
/* run through all elements in the current directory */
while ((elem = readdir(dir)) && (result <= 0)) {
char *name;
name = (char *)malloc(strlen(bsdl_path_list[idx]) + strlen(elem->d_name) + 1 + 1);
if (name) {
struct stat buf;
strcpy(name, bsdl_path_list[idx]);
strcat(name, "/");
strcat(name, elem->d_name);
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(name, -1, idcode);
if (result > 0) {
/* read in BSDL file if IDCODE matched */
printf( _(" Filename: %s\n"), name );
result = bsdl_read_file(name, 1, idcode);
}
} else
result = bsdl_read_file(name, mode, idcode);
}
}
free(name);
}
}
closedir(dir);
} else
bsdl_msg(BSDL_MSG_WARN, "Warning: Cannot open directory %s\n", bsdl_path_list[idx]);
idx++;
}
return result;
}

@ -0,0 +1,151 @@
/*
* $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 <arniml@users.sourceforge.net>, 2007.
*
*/
#include <jtag.h>
/* message types for bsdl_msg() */
#define BSDL_MSG_NOTE 0
#define BSDL_MSG_WARN 1
#define BSDL_MSG_ERR 2
/* private data of the flex scanner
handled internally in bsdl_flex.l as yyextra */
struct scan_extra {
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 jtag_ctrl collects all elements that are required to interface
with jtag internals */
struct jtag_ctrl {
int mode;
char *idcode; /* IDCODE string */
part_t *part;
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 String_Val[150];
char Package_File_Name[100];
int Reading_Package;
char *buffer_for_switch;
size_t len_buffer_for_switch;
int idx_to_buffer;
void *scanner;
struct jtag_ctrl jtag_ctrl;
};
typedef struct parser_priv parser_priv_t;
void bsdl_msg(int, char *, ...);
/* BSDL lexer declarations */
void *bsdl_flex_init(FILE *);
void bsdl_flex_deinit(void *);
void bsdl_flex_switch_file(void *, const 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 *);
/* BSDL parser declarations */
parser_priv_t *bsdl_parser_init(FILE *);
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_add_pin(parser_priv_t *, char *);
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 *, char *, 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 *);

@ -0,0 +1,970 @@
/*
* $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:
-----------------------------------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 {parser_priv_t *priv_data}
%defines
%name-prefix="bsdl"
%{
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
/* interface to flex */
#include "bsdl_bison.h"
#include "bsdl.h"
#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;}
#else
#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 Make_String(char *, char *);
static void Print_Error(parser_priv_t *, char *);
static void Print_Warning(parser_priv_t *, char *);
static void Give_Up_And_Quit(parser_priv_t *);
void yyerror(parser_priv_t *, const char *);
%}
%union {
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 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 OBSERVE_ONLY
%type <str> BIN_X_PATTERN
%type <str> IDENTIFIER
%type <str> QUOTED_STRING
%type <str> BINARY_PATTERN
%type <str> Binary_Pattern
%type <str> Pattern_List
%type <integer> DECIMAL_NUMBER
%type <str> REAL_NUMBER
%type <str> Port_Name
%type <integer> Cell_Function
%type <str> Safe_Value
%type <integer> Disable_Value
%type <str> Standard_Reg
%type <str> Standard_Inst
%start BSDL_Program
%% /* 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");
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); }
| 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);
}
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
;
Port_List : IDENTIFIER
{ free($1); }
| Port_List COMMA IDENTIFIER
{ free($3); }
;
Function : IN | OUT | INOUT | BUFFER | LINKAGE
;
Scaler_Or_Vector : BIT
| BIT_VECTOR LPAREN Vector_Range RPAREN
;
Vector_Range : DECIMAL_NUMBER TO DECIMAL_NUMBER
| DECIMAL_NUMBER DOWNTO DECIMAL_NUMBER
;
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
{
bsdl_add_pin(priv_data, $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); }
| 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 Pattern_List RPAREN
{ bsdl_add_instruction(priv_data, $1, $3); }
;
Pattern_List : Binary_Pattern
{ $$ = $1; }
| 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); }
;
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, $3, $5, $7);
}
;
Port_Name : IDENTIFIER
{ $$ = $1; }
| IDENTIFIER LPAREN DECIMAL_NUMBER RPAREN
{
Print_Warning(priv_data, "Port name index not supported in Boundary Cell description");
$$ = NULL;
free($1);
}
| ASTERISK
{ $$ = strdup("*"); }
;
Cell_Function : INPUT
{ $$ = INPUT; }
| OUTPUT2
{ $$ = OUTPUT2; }
| OUTPUT3
{ $$ = OUTPUT3; }
| CONTROL
{ $$ = CONTROL; }
| CONTROLR
{ $$ = CONTROLR; }
| INTERNAL
{ $$ = INTERNAL; }
| CLOCK
{ $$ = CLOCK; }
| BIDIR
{ $$ = BIDIR; }
;
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); }
;
BSDL_Compliance_Pattern: LPAREN Physical_Pin_List RPAREN
LPAREN BIN_X_PATTERN RPAREN
{ free($5); }
;
Quoted_String : QUOTED_STRING
{Make_String($1, priv_data->String_Val);
Init_Text(priv_data);
Store_Text(priv_data, priv_data->String_Val);
free($1); }
| Quoted_String CONCATENATE QUOTED_STRING
{Make_String($3, priv_data->String_Val);
Store_Text(priv_data, priv_data->String_Val);
free($3); }
;
%% /* End rules, begin programs */
/*----------------------------------------------------------------------*/
static void Init_Text(parser_priv_t *priv_data)
{
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';
priv_data->idx_to_buffer = 0;
}
/*----------------------------------------------------------------------*/
static void Store_Text(parser_priv_t *priv_data, char *String)
{ /* Save characters from VHDL string in local string buffer. */
size_t req_len;
req_len = strlen(priv_data->buffer_for_switch) + strlen(String) + 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;
}
strcpy(&(priv_data->buffer_for_switch[priv_data->idx_to_buffer]), String);
priv_data->idx_to_buffer += strlen(String);
}
/*----------------------------------------------------------------------*/
static void Make_String(char *Source, char *Dest)
{
char Ch;
for (Source++; Ch = *Source, (Ch != '"') && (Ch != '\n'); Source++, Dest++)
*Dest = *Source;
*Dest = '\0';
}
/*----------------------------------------------------------------------*/
static void Print_Error(parser_priv_t *priv_data, char *Errmess)
{
if (priv_data->Reading_Package)
bsdl_msg(BSDL_MSG_ERR, "Error in Package %s, Line %d, %s.\n",
priv_data->Package_File_Name,
bsdl_flex_get_lineno(priv_data->scanner),
Errmess);
else
bsdl_msg(BSDL_MSG_ERR, "Error, Line %d, %s.\n",
bsdl_flex_get_lineno(priv_data->scanner),
Errmess);
}
/*----------------------------------------------------------------------*/
static void Print_Warning(parser_priv_t *priv_data, char *Warnmess)
{
if (priv_data->Reading_Package)
bsdl_msg(BSDL_MSG_WARN, "Warning in Package %s, Line %d, %s.\n",
priv_data->Package_File_Name,
bsdl_flex_get_lineno(priv_data->scanner),
Warnmess);
else
bsdl_msg(BSDL_MSG_WARN, "Warning, Line %d, %s.\n",
bsdl_flex_get_lineno(priv_data->scanner),
Warnmess);
}
/*----------------------------------------------------------------------*/
static void Give_Up_And_Quit(parser_priv_t *priv_data)
{
Print_Error(priv_data, "Too many errors");
}
/*----------------------------------------------------------------------*/
void yyerror(parser_priv_t *priv_data, const char *error_string)
{
}
/*----------------------------------------------------------------------*/
parser_priv_t *bsdl_parser_init(FILE *f)
{
parser_priv_t *new_priv;
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;
}
new_priv->Reading_Package = 0;
new_priv->buffer_for_switch = NULL;
new_priv->len_buffer_for_switch = 0;
if (!(new_priv->scanner = bsdl_flex_init(f))) {
free(new_priv);
new_priv = NULL;
}
bsdl_sem_init(new_priv);
return new_priv;
}
/*----------------------------------------------------------------------*/
void bsdl_parser_deinit(parser_priv_t *priv_data)
{
bsdl_sem_deinit(priv_data);
bsdl_flex_deinit(priv_data->scanner);
free(priv_data);
}

@ -0,0 +1,557 @@
/*
* $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:
-----------------------------------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="bsdl"
%option outfile="lex.yy.c"
%{
/* Begin lex input specifications */
#include <stdlib.h>
#include <ctype.h>
#include "bsdl_bison.h"
#include "bsdl.h"
#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]*
Binary_Pattern [0-1]+
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 [\)]
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
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
Highz HIGHZ
Idcode IDCODE
Device_Id DEVICE_ID
Usercode USERCODE
Input INPUT
Output2 OUTPUT2
Output3 OUTPUT3
Control CONTROL
Controlr CONTROLR
Internal INTERNAL
Clock CLOCK
Bidir BIDIR
Bidir_In BIDIR_IN
Bidir_Out BIDIR_OUT
Z Z
Weak0 WEAK0
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
Observe_Only OBSERVE_ONLY
%%
{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); }
{Instruction_Opcode} {yyextra->Base = BINARY; /* Enable Binary Patterns */
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 = BIN_X; return(COMPLIANCE_PATTERNS); }
<REG>{Boundary} {return(BOUNDARY); }
<REG>{Bypass} {return(BYPASS); }
<REG>{Highz} {return(HIGHZ); }
<REG>{Idcode} {return(IDCODE); }
<REG>{Usercode} {return(USERCODE); }
<REG>{Device_Id} {return(DEVICE_ID); }
<BOU,PAC>{Input} {return(INPUT); }
<BOU,PAC>{Output2} {return(OUTPUT2); }
<BOU,PAC>{Output3} {return(OUTPUT3); }
<BOU,PAC>{Controlr} {return(CONTROLR); }
<BOU,PAC>{Control} {return(CONTROL); }
<BOU,PAC>{Internal} {return(INTERNAL); }
<BOU,PAC>{Clock} {return(CLOCK); }
<BOU>{Bidir} {return(BIDIR); }
<PAC>{Bidir_In} {return(BIDIR_IN); }
<PAC>{Bidir_Out} {return(BIDIR_OUT); }
<PAC>{Extest} {return(EXTEST); }
<PAC>{Sample} {return(SAMPLE); }
<PAC>{Intest} {return(INTEST); }
<PAC>{Runbist} {return(RUNBIST); }
<PAC>{Observe_Only} {return(OBSERVE_ONLY); }
<PAC>{Pi} {return(PI); }
<PAC>{Po} {return(PO); }
<PAC>{Upd} {return(UPD); }
<PAC>{Cap} {return(CAP); }
<PAC>{X} {return(X); }
<PAC>{Zero} {return(ZERO); }
<PAC>{One} {return(ONE); }
<BOU>{Z} {return(Z); }
<BOU>{Weak0} {return(WEAK0); }
<BOU>{Weak1} {return(WEAK1); }
<BOU>{Pull0} {return(PULL0); }
<BOU>{Pull1} {return(PULL1); }
<BOU>{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); }
{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); }
{Binary_Pattern} {if (yyextra->Base != BINARY) REJECT;
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);}
{Illegal} {fprintf(stderr,
"Error: 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 */}
<<EOF>> {
yypop_buffer_state(yyscanner);
if ( !YY_CURRENT_BUFFER )
yyterminate();
}
%%
void *bsdl_flex_init(FILE *f) /* Change input file from STDIN to BSDL file */
{
scan_extra_t *extra;
yyscan_t scanner;
/* get our scanner structure */
if (yylex_init(&scanner) != 0) {
printf("%s: Scanner could not be initialized\n", "BSDL");
return NULL;
}
yyset_in(f, scanner);
if (!(extra = (scan_extra_t *)malloc(sizeof(scan_extra_t)))) {
printf("%s: Out of memory\n", "BSDL");
yylex_destroy(scanner);
return NULL;
}
extra->Compile_Errors = 0;
extra->Base = DECIMAL;
yyset_extra(extra, scanner);
return scanner;
}
void bsdl_flex_deinit(void *scanner)
{
free(yyget_extra(scanner));
yylex_destroy(scanner);
}
int yywrap(yyscan_t scanner)
{
if (yyget_in(scanner)) {
fclose(yyget_in(scanner));
yyset_in(NULL, scanner);
}
return(1);
}
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
printf("%s: Out of memory\n", "BSDL");
return(n_str);
}
void bsdl_flex_switch_file(yyscan_t scanner, const char *filename)
{
scan_extra_t *extra;
FILE *f;
/* file in current directory has precedence */
f = fopen(filename, "r");
if (!f) {
char db_path[] = JTAG_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)
printf("%s: Cannot open file %s or %s.\n", "BSDL", 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)
{
/* ugly, ulgy, ugly
prepare yyg for later use of YY_CURRENT_BUFFER */
struct yyguts_t * yyg = (struct yyguts_t*)scanner;
int lineno;
/* printf("bsdl_flex_switch_buffer(%s)\n", buffer);*/
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);
}
int bsdl_flex_get_compile_errors(yyscan_t scanner)
{
scan_extra_t *extra = yyget_extra(scanner);
return extra->Compile_Errors;
}
static void bsdl_flex_set_compile_errors(int n, yyscan_t scanner)
{
scan_extra_t *extra = yyget_extra(scanner);
extra->Compile_Errors = n;
}
int bsdl_flex_postinc_compile_errors(yyscan_t scanner)
{
int errors = bsdl_flex_get_compile_errors(scanner);
bsdl_flex_set_compile_errors(errors+1, scanner);
return errors;
}
int bsdl_flex_get_lineno(yyscan_t scanner)
{
return yyget_lineno(scanner);
}

@ -0,0 +1,770 @@
/*
* $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 <arniml@users.sourceforge.net>, 2007.
*
* This file contains semantic actions that are called by the bison
* parser. They interface between the parser and the jtag application.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <jtag.h>
#include <brux/cmd.h>
#include "bsdl_bison.h"
#include "bsdl.h"
/*****************************************************************************
* void print_cmd(char **cmd)
*
* Prints the strings in array cmd until NULL is encountered.
*
* Parameters
* cmd : array of strings to print, terminated by NULL
*
* Returns
* void
****************************************************************************/
static void print_cmd(char **cmd)
{
int idx = 0;
char *elem;
while ((elem = cmd[idx])) {
printf(" %s", elem);
idx++;
}
printf("\n");
}
/*****************************************************************************
* 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);
ad->ainfo_list = NULL;
ad->instr_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 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);
free_ainfo_list(ad->ainfo_list);
free_instr_list(priv->jtag_ctrl.instr_list);
}
/*****************************************************************************
* void bsdl_set_entity(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
****************************************************************************/
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 <len>
*
* 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)
{
if (priv->jtag_ctrl.mode >= 0) {
char lenstring[6];
char *cmd[] = {"instruction",
"length",
lenstring,
NULL};
snprintf(lenstring, 6, "%i", len);
lenstring[5] = '\0';
if (priv->jtag_ctrl.mode >= 1)
cmd_run(cmd);
else
print_cmd(cmd);
}
}
/*****************************************************************************
* void bsdl_add_pin(parser_priv_t *priv, char *pin)
*
* Adds the specified pin name as a signal via shell command
* signal <pin>
*
* Parameters
* priv : private data container for parser related tasks
* pin : name of the new pin, memory gets free'd
*
* Returns
* void
****************************************************************************/
void bsdl_add_pin(parser_priv_t *priv, char *pin)
{
if (priv->jtag_ctrl.mode >= 0) {
char *cmd[] = {"signal",
pin,
NULL};
if (priv->jtag_ctrl.mode >= 1)
cmd_run(cmd);
else
print_cmd(cmd);
}
free(pin);
}
/*****************************************************************************
* void create_register(parser_priv_t *priv, char *reg_name, size_t len)
*
* Generic function to create a jtag register via shell command
* register <reg_name> <len>
*
* Parameters
* priv : private data container for parser related tasks
* 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)
{
if (priv->jtag_ctrl.mode >= 0) {
const size_t str_len = 10;
char len_str[str_len+1];
char *cmd[] = {"register",
reg_name,
len_str,
NULL};
/* convert length information to string */
snprintf(len_str, str_len, "%i", len);
if (priv->jtag_ctrl.mode >= 1)
cmd_run(cmd);
else
print_cmd(cmd);
}
}
/*****************************************************************************
* void bsdl_set_idcode(parser_priv_t *priv, char *idcode)
*
* Stores the specified IDCODE of the device for later use and creates
* the DIR register.
*
* Parameters
* priv : private data container for parser related tasks
* idcode : string containing the device's IDCODE
*
* Returns
* void
****************************************************************************/
void bsdl_set_idcode(parser_priv_t *priv, char *idcode)
{
priv->jtag_ctrl.idcode = idcode;
create_register(priv, "DIR", strlen(idcode));
}
/*****************************************************************************
* void bsdl_set_usercode(parser_priv_t *priv, char *usercode)
*
* 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
*
* Returns
* void
****************************************************************************/
void bsdl_set_usercode(parser_priv_t *priv, char *usercode)
{
create_register(priv, "USERCODE", strlen(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 = NULL;
new_instr->instr = instr;
new_instr->opcode = opcode;
if (priv->jtag_ctrl.instr_list) {
struct instr_elem *il = priv->jtag_ctrl.instr_list;
while (il->next)
il = il->next;
il->next = new_instr;
} else
priv->jtag_ctrl.instr_list = new_instr;
} else
bsdl_msg(BSDL_MSG_ERR, "Out of memory, %s line %i\n", __FILE__, __LINE__);
}
/*****************************************************************************
* void bsdl_set_bsr_length(parser_priv_t *priv, int len)
*
* 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,
* char *port_name, 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.
*
* Parameters
* priv : private data container for parser related tasks
* port_name : port name this spec applies to
* 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,
char *port_name, int function, char *safe_value)
{
struct cell_info *ci = &(priv->jtag_ctrl.cell_info);
ci->port_name = port_name;
ci->cell_function = function;
ci->basic_safe_value = safe_value;
}
/*****************************************************************************
* 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
*
* Returns
* void
****************************************************************************/
void bsdl_ci_set_cell_spec_disable(parser_priv_t *priv,
int ctrl_bit_num, int safe_value, int disable_value)
{
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 */
}
/*****************************************************************************
* 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 <bit_num> <type> <default> <signal> [<cbit> <cval> Z]
*
* Parameters
* priv : private data container for parser related tasks
* bit_num : bit number of current cell
*
* Returns
* void
****************************************************************************/
void bsdl_ci_apply_cell_info(parser_priv_t *priv, int bit_num)
{
struct cell_info *ci = &(priv->jtag_ctrl.cell_info);
ci->bit_num = bit_num;
if (priv->jtag_ctrl.mode >= 0) {
const size_t str_len = 10;
char bit_num_str[str_len+1];
char ctrl_bit_num_str[str_len+1];
char disable_safe_value_str[str_len+1];
char *cmd[] = {"bit",
bit_num_str,
NULL,
NULL,
NULL,
ctrl_bit_num_str,
disable_safe_value_str,
"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 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 (priv->jtag_ctrl.mode >= 1)
cmd_run(cmd);
else
print_cmd(cmd);
}
/* free malloc'ed memory */
if (ci->port_name)
free(ci->port_name);
if (ci->basic_safe_value)
free(ci->basic_safe_value);
}
/*****************************************************************************
* 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 = NULL;
new_instr->instr = instr;
new_instr->opcode = NULL;
if (ad->instr_list) {
struct instr_elem *il = ad->instr_list;
while (il->next)
il = il->next;
il->next = new_instr;
} else
ad->instr_list = new_instr;
} else
bsdl_msg(BSDL_MSG_ERR, "Out of memory, %s line %i\n", __FILE__, __LINE__);
}
/*****************************************************************************
* 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 = NULL;
new_ainfo->reg = ad->reg;
new_ainfo->reg_len = ad->reg_len;
new_ainfo->instr_list = ad->instr_list;
if (ad->ainfo_list) {
struct ainfo_elem *ai = ad->ainfo_list;
while (ai->next)
ai = ai->next;
ai->next = new_ainfo;
} else
ad->ainfo_list = new_ainfo;
} else
bsdl_msg(BSDL_MSG_ERR, "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;
}
/*****************************************************************************
* 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
* via shell command
* instruction <instruction> <code> <register>
*
* Additional register are created on the fly:
* - standard registers that haven't been created so far
* - non-standard registers encountered in register access specs
*
* Mandatory instruction/register associations are generated also in
* absence of a related register access specification (such specs are
* optional in the BSDL standard).
*
* Parameters
* priv : private data container for parser related tasks
*
* Returns
* void
****************************************************************************/
void bsdl_ac_finalize(parser_priv_t *priv)
{
/* ensure that all mandatory registers are created prior to
handling the instruction/register associations
+ BOUNDARY/BSR has been generated during the parsing process
+ DEVICE_ID/DIR has been generated during the parsing process
*/
/* we need a BYPASS register */
create_register(priv, "BYPASS", 1);
if (priv->jtag_ctrl.mode >= 0) {
struct ainfo_elem *ai;
struct instr_elem *cinst;
/* next scan through all register_access definitions and create
the non-standard registers */
ai = priv->jtag_ctrl.access_data.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 (!is_std)
create_register(priv, ai->reg, ai->reg_len);
ai = ai->next;
}
/* next scan through all instruction/opcode definitions and resolve
the instruction/register associations for these */
cinst = priv->jtag_ctrl.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) {
/* 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";
else reg_name = ai->reg;
}
tinst = tinst->next;
}
ai = ai->next;
}
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, "SAMPLE" ) == 0)
instr_name = "SAMPLE/PRELOAD";
else
instr_name = cinst->instr;
if (reg_name) {
char *cmd[] = {"instruction",
instr_name,
cinst->opcode,
reg_name,
NULL};
if (priv->jtag_ctrl.mode >= 1)
cmd_run(cmd);
else
print_cmd(cmd);
}
cinst = cinst->next;
}
}
}

@ -56,6 +56,7 @@ libcmd_a_SOURCES = \
script.c \
include.c \
cmd.c \
svf.c
svf.c \
bsdl.c
INCLUDES = -DJTAG_DATA_DIR=\"$(pkgdatadir)\"

@ -0,0 +1,115 @@
/*
* $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 <arniml@users.sourceforge.net>, 2007.
*
*/
#include "sysdep.h"
#include <stdio.h>
#include <string.h>
#include <bsdl.h>
#include <cmd.h>
static int
cmd_bsdl_run( char *params[] )
{
int num_params, result = -1;
num_params = cmd_params(params);
if (num_params >= 2) {
if (strcmp(params[1], "test") == 0) {
int debug_save;
debug_save = bsdl_debug;
bsdl_debug = 1;
if (num_params == 3) {
result = bsdl_read_file(params[2], -1, NULL) >= 0 ? 1 : -1;
} else if (num_params == 2) {
bsdl_scan_files(NULL, -1);
result = 1;
}
bsdl_debug = debug_save;
}
if (strcmp(params[1], "dump") == 0) {
if (num_params == 3) {
result = bsdl_read_file(params[2], 0, NULL) >= 0 ? 1 : -1;
} else if (num_params == 2) {
bsdl_scan_files(NULL, 0);
result = 1;
}
}
if (num_params == 3) {
if (strcmp(params[1], "path") == 0) {
bsdl_set_path(params[2]);
result = 1;
}
if (strcmp(params[1], "debug") == 0) {
if (strcmp(params[2], "on") == 0) {
bsdl_debug = 1;
result = 1;
}
if (strcmp(params[2], "off") == 0) {
bsdl_debug = 0;
result = 1;
}
}
}
}
return result;
}
static void
cmd_bsdl_help( void )
{
printf( _(
"Usage: %s path PATHLIST\n"
"Usage: %s test [FILE]\n"
"Usage: %s dump [FILE]\n"
"Usage: %s debug on|off\n"
"Manage BSDL files\n"
"\n"
"PATHLIST semicolon separated list of directory paths to search for BSDL files\n"
"FILE file containing part description in BSDL format\n"
), "bsdl", "bsdl", "bsdl", "bsdl" );
}
cmd_t cmd_bsdl = {
"bsdl",
N_("manage BSDL files"),
cmd_bsdl_help,
cmd_bsdl_run
};
/* Emacs specific variables
;;; Local Variables: ***
;;; indent-tabs-mode:t ***
;;; tab-width:2 ***
;;; End: ***
*/

@ -64,6 +64,7 @@ extern cmd_t cmd_eraseflash;
extern cmd_t cmd_script;
extern cmd_t cmd_include;
extern cmd_t cmd_svf;
extern cmd_t cmd_bsdl;
extern cmd_t cmd_debug;
const cmd_t *cmds[] = {
@ -100,6 +101,7 @@ const cmd_t *cmds[] = {
&cmd_script,
&cmd_include,
&cmd_svf,
&cmd_bsdl,
&cmd_debug,
NULL /* last must be NULL */
};

@ -31,6 +31,8 @@
#include <brux/cmd.h>
#include <bsdl.h>
#include "register.h"
#include "tap.h"
#include "cable.h"
@ -272,6 +274,10 @@ detect_parts( chain_t *chain, char *db_path )
if (did == br)
continue;
chain->active_part = ps->len - 1;
if (bsdl_scan_files(register_get_string( did ), 1) <= 0) {
/* find JTAG declarations for a part with id */
strcpy( data_path, db_path ); /* FIXME: Buffer overrun */
@ -353,11 +359,12 @@ detect_parts( chain_t *chain, char *db_path )
printf( _(" Filename: %s\n"), data_path );
/* run JTAG declarations */
chain->active_part = ps->len - 1;
strcpy( part->manufacturer, manufacturer );
strcpy( part->part, partname );
strcpy( part->stepping, stepping );
cmd_run( cmd );
}
if (part->active_instruction == NULL)
part->active_instruction = part_find_instruction( part, "IDCODE" );
}

Loading…
Cancel
Save