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-d4ac073336b7master
parent
5819ae250d
commit
b62f2996f0
@ -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 */
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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: ***
|
||||
*/
|
Loading…
Reference in New Issue