Boundary Scan Description Language (BSDL) Explained

Boundary Scan Description Language (BSDL) provides a description of testability features within ICs that comply with the IEEE 1149.1 Standard (hereinafter used interchangeably with the term “JTAG”). Having a good understanding of the BSDL leads to a deeper knowledge of JTAG, that in turn grants insight into the technology behind IEEE 1687, also known as IJTAG.

And these in turn lead to insights into semiconductor Design for Test (DFT) – that is, Memory Built-In Self Test (MBIST), Logic Test, Scan Insertion, Test Pattern Generation, etc. If you really want to understand how things work “on the metal”, a firm grasp of JTAG and BSDL is essential.

In this article, I’ll provide a tutorial and practical description of the BSDL, and how it is used as a platform all of the test, validation, debug, and programming applications, on chips and boards, that JTAG and IJTAG enable.

To see how BSDL works in practice, I’ll start with the actual BSDL file that belongs to the Spartan 6 FPGA used on our IJTAG demonstration vehicle, the Opal Kelly board. The BSDL file is over a thousand lines long, so it’s best viewed in a separate window: Spartan 6 BSDL.txt. We’ll use this as a reference, and dissect and describe some (but not all) of the major sections therein.

The generic layout of a BSDL file’s contents is as follows:

entity <component name> is

<generic parameter>

<logical port description>

<standard use statement>

{<use statement>}

<component conformance statement>

<device package pin mappings>

[<grouped port identification>]

<scan port identification>

[<compliance-enable description>]

<instruction register description>

[<optional register description>]

[<register access description>]

<boundary-scan register description>

[<runbist description>]

[<intest description>]

[<system clock description>]

{<register mnemonics description>}

{<register fields description>}

{<register assembly description>}

{<register constraints description>}

{<register association description>}

{<power port association description>}

{<BSDL extensions>}

[<design warning>]

end <component name>;

The statements listed above that are shown between braces “{}” and “[]” are considered optional.

And, of the statements above, the below were introduced within IEEE 1149.1-2013.

[<system clock description>]

{<register mnemonics description>}

{<register fields description>}

{<register assembly description>}

{<register constraints description>}

{<register association description>}

{<power port association description>}

If you’d like to learn more about the innovations introduced in this most recent version of JTAG, the articles  The IEEE 1149.1-2013 Standard for Test Access Port and Boundary-Scan Architecture: An Overview and IEEE 1149.1-2013: Excludable Segments are good introductions. In the interest of brevity, in this article, I’ll focus on the main statements that provide insight into the inner JTAG workings of ICs, and restrict coverage to the most widely deployed version of boundary scan, IEEE 1149.-2001.

Component Name

entity <component name> refers to the Spartan 6 FPGA; in this case, XC6SLX9_FTG256. It is worthy to note that prior to the 2013 revision of IEEE 1149.1,  BSDL was considered to be a “proper subset” of VHDL; but with IEEE 1149.1-2013, that requirement has been relaxed, and BSDL is now considered to be “based upon” VHDL. This allows the use of new pin type keywords that we’ll see below.

Generic Parameter

For our Spartan 6, the generic parameter is:

generic (PHYSICAL_PIN_MAP : string := "FTG256" );

This parameter can be passed in to the application that parses the BSDL, or given a default, in this case “FTG256”. This selects an IC packaging option.

Logical Port Description

This section gives logical names to the I/O and TAP pins, as well as describes their function as input, output, bidirectional, etc. A subset of the list from the BSDL is shown below. You can see that the DONE bit is bidirectional (inout). The two dashes “–” denote a comment; for DONE, it’s used as a reminder that this is a synonym for the DONE_2 pin, as per the Spartan 6 pinout document: https://docs.xilinx.com/v/u/en-US/ug385. An excerpt for the Spartan 6 is below:

port (

     CMPCS_B: in bit; --  CMPCS_B_2

     DONE: inout bit; --  DONE_2

     GND: linkage bit_vector (1 to 26);

     HSWAPEN: in bit; --  PAD1

     IO_A10: inout bit; --  PAD24

     IO_A11: inout bit; --  PAD32

     IO_A12: inout bit; --  PAD36

     IO_A13: inout bit; --  PAD38

     IO_A14: inout bit; --  PAD42

     IO_A2: inout bit; --  PAD192

     IO_A3: inout bit; --  PAD200

Within the logical port description, the pin types or functions supported for each pin are:

Label Meaning
In An input-only pin
Out An output-only pin that could be connected to a bus wire driven by multiple drivers. The driver of this pin must be a 3-state, or open-collector (etc.) driver compatible with busing
Buffer A two-state output-only pin where both states are actively driven, that cannot be attached to a multiple-driver bus
Inout A bidirectional pin
Linkage Other pin types such as power, ground, no-connect or analog

 

Standard Use Statement

This refers to external definitions found in packages and package bodies, sort of an “include” statement for header file(s) as you might see in higher level languages. In our Spartan6 BSDL file example, this is:

use STD_1149_1_2001.all;

This package listed above contains declarations for the TAP, instruction register, IDCODE register, boundary register cells, and other IEEE 1149.1 attributes, and is listed in its entirety below. It is worthwhile studying and mapping back the use of these definitions within the Spartan 6 BSDL. For example, the TCK definition within the BSDL is:

attribute TAP_SCAN_CLOCK of TCK : signal is (25.0e6, BOTH);

And within the STD_1149_1_2001 file, we see:

attribute  TAP_SCAN_CLOCK: CLOCK_INFO;

where the definitions for CLOCK_INFO and CLOCK_LEVEL are:

type CLOCK_LEVEL is (LOW, BOTH);

 type CLOCK_INFO  is record

   FREQ : real;

   LEVEL: CLOCK_LEVEL;

 end record;

The entirety of the STD_1149_1_2001 file is below:

package STD_1149_1_2001 is             -- Created 20010530


-- 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 defered 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;

 constant BC_8  : CELL_INFO;

 constant BC_9  : CELL_INFO;

 constant BC_10 : 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;

 attribute COMPONENT_CONFORMANCE : string;

end STD_1149_1_2001;  -- End of 1149.1-2001 Package


package body STD_1149_1_2001 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 f11-18, f11-30, f11-34c, f11-34d, f11-36c, f11-46d

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 f11-14, f11-31, f11-35c, f11-35d, f11-37c,

--                 f11-38c, f11-39(output) and f11-41c

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 f11-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 f11-16, f11-17, f11-39(input)

constant BC_4 : CELL_INFO :=

 ((INPUT,        EXTEST, PI),  -- Intest on input/observe_only not supported

  (INPUT,        SAMPLE, PI), 

  (CLOCK,        EXTEST, PI),  (INTERNAL,     EXTEST, PI),

  (CLOCK,        SAMPLE, PI),  (INTERNAL,     SAMPLE, PI),

  (CLOCK,        INTEST, PI),  (INTERNAL,     INTEST, PI),

  (OBSERVE_ONLY, SAMPLE, PI),  (OBSERVE_ONLY, EXTEST, PI) );


-- Description for f11-46c, 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 f11-38d, 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 f11-37d, 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) );


-- Description for 11-40, f11-41d

constant BC_8 : CELL_INFO :=

 -- Intest on bidir not supported

 ((BIDIR_IN, EXTEST,  PI),  (BIDIR_OUT, EXTEST,  PO),

  (BIDIR_IN, SAMPLE,  PI),  (BIDIR_OUT, SAMPLE,  PO) );


-- Description for f11-32

constant BC_9 : CELL_INFO :=

 -- Self-monitoring output that supports Intest

 ((OUTPUT2, EXTEST,  PO),   (OUTPUT3, EXTEST,  PO),

  (OUTPUT2, SAMPLE,  PI),   (OUTPUT3, SAMPLE,  PI),

  (OUTPUT2, INTEST,  PI),   (OUTPUT3, INTEST,  PI) );


-- Description for f11-33

constant BC_10 : CELL_INFO :=

 -- Self-monitoring output that does not support Intest

 ((OUTPUT2, EXTEST,  PO),   (OUTPUT3, EXTEST,  PO),

  (OUTPUT2, SAMPLE,  PO),   (OUTPUT3, SAMPLE,  PO) );

end STD_1149_1_2001;  -- End of 1149.1-2001 Package Body

You can ignore the comments with the “f11-33”, “f11-32” for example above. These refer to the figure diagrams in the actual Standard. If you want to delve into the BC boundary scan cell architectures, pick up a copy of the Standard, or Ken Parker’s Boundary Scan Handbook (note that the Fourth Edition, published in 2016 and having some great content on IEEE 1149.1-2013 and IEEE 1149.6-2015, is available on Amazon for $100 USD).

Within the package STD_1149_1_2001, you’ll see the package body STD_1149_1_2001, that defines the boundary scan cells within the Spartan 6 boundary scan register (BSR). These in turn refer back to the CELL_INFO structure, which is an array of type CELL_DATA. It’s worthwhile researching these structures if you want to go to the next level of detail.

Device Package Pin Mappings

This section maps package pins to logical port names, the latter of which is described above. For the Spartan 6, we have only one package (FTG256), which is the default, and an excerpt of the BSDL file contains:

attribute PIN_MAP of XC6SLX9_FTG256 : entity is PHYSICAL_PIN_MAP;

constant FTG256: PIN_MAP_STRING:=

     "CMPCS_B:L11," &

     "DONE:P13," &

     "GND:(A1,A16,B7,B11,D4,D13,E9,G2,G8,G15," &

           "H7,H9,H12,J5,J8,K7,K9,L2,L15,M8," &

           "N13,P3,R6,R10,T1,T16)," &

     "HSWAPEN:C4," &

     "IO_A10:A10," &

     "IO_A11:A11," &

     "IO_A12:A12," &

     "IO_A13:A13," &

     "IO_A14:A14," &

     "IO_A2:A2," &

     "IO_A3:A3," &

Correlating with the Logical Port Description above, for example, we see that the DONE signal is a bidirectional signal on pin (ball) number P13. And GND is a linkage pin_vector (1 to 26), and on this package, GND is on pins A1, A16, B7, B11, D4, D13, E9, G2, G8, G15, H7, H9, H12, J5, J8, K7, K9, L2, L15, M8, N13, P3, R6, R10, T1, and T16.

Instruction Register Description

This section of the BSDL enumerates the TAP instructions that are supported on the device. Thus, it provides the following information:

– Length of the instruction register

– Supported instructions listed by name

– Opcode(s) for each instruction

– Instruction register capture pattern

– Information on private instructions

For the Spartan 6, this section of the BSDL is listed below:

attribute INSTRUCTION_LENGTH of XC6SLX9_FTG256 : entity is 6;

attribute INSTRUCTION_OPCODE of XC6SLX9_FTG256 : entity is

   "EXTEST      (001111)," &

   "SAMPLE      (000001)," &

   "PRELOAD     (000001)," & -- Same as SAMPLE

   "USER1       (000010)," & -- Not available until after configuration

   "USER2       (000011)," & -- Not available until after configuration

   "USER3       (011010)," & -- Not available until after configuration

   "USER4       (011011)," & -- Not available until after configuration

   "CFG_OUT     (000100)," & -- Not available during configuration with another mode.

   "CFG_IN      (000101)," & -- Not available during configuration with another mode.

   "INTEST      (000111)," &

   "USERCODE    (001000)," &

   "IDCODE      (001001)," &

   "HIGHZ       (001010)," &

   "JPROGRAM    (001011)," & -- Not available during configuration with another mode.

   "JSTART      (001100)," & -- Not available during configuration with another mode.

   "JSHUTDOWN   (001101)," & -- Not available during configuration with another mode.

   "BYPASS         (111111)," &

   "FUSE_UPDATE    (111010)," &

   "FUSE_KEY       (111011)," &

   "FUSE_OPTIONS   (111100)," &

   "FUSE_CNTL      (111101)," &

   "ISC_FUSE_WRITE (110001)," &

   "ISC_IOIMISR    (110010)," &

   "ISC_ENABLE     (010000)," &

   "ISC_PROGRAM    (010001)," &

   "ISC_PROGRAM_KEY (010010)," &

   "ISC_ADDRESS_SHIFT (010011)," &

   "ISC_NOOP       (010100)," &

   "ISC_READ       (010101)," &

   "ISC_DISABLE    (010110)," &

   "ISC_DNA        (110000)";

attribute INSTRUCTION_CAPTURE of XC6SLX9_FTG256 : entity is

-- Bit 5 is 1 when DONE is released (part of startup sequence)

-- Bit 4 is 1 if house-cleaning is complete

-- Bit 3 is ISC_Enabled

-- Bit 2 is ISC_Done

  "XXXX01" ;

attribute INSTRUCTION_PRIVATE of XC6SLX9_FTG256 : entity is

-- If the device is configured, and a USER instruction is implemented

-- and not private to the FPGA designer, then it should be removed

-- from INSTRUCTION_PRIVATE, and the target register should be defined

-- in REGISTER_ACCESS.

   "USER1," &

   "USER2," &

   "USER3," &

   "USER4," &

   "CFG_OUT," &

   "CFG_IN," &

   "JPROGRAM," &

   "JSTART," &

   "JSHUTDOWN," &

   "FUSE_UPDATE," &

   "FUSE_KEY," &

   "FUSE_OPTIONS," &

   "FUSE_CNTL," &

   "ISC_FUSE_WRITE," &

   "ISC_IOIMISR," &

   "ISC_PROGRAM_KEY," &

   "ISC_ADDRESS_SHIFT," &

   "ISC_READ," &

   "ISC_DNA";

There’s a lot to unpack here, some of which require a deeper dive into the functionality of the Spartan 6. Thus, I’ll just cover some of the key highlights.

The instruction register for the Spartan 6 is six bits wide. This width is fixed for the device. In general, the instruction register must be two or more bits wide. Instructions can have more than one opcode, but the Spartan 6 doesn’t exhibit this capability.

The INSTRUCTION_CAPTURE attribute is kind of subtle; it denotes the bit pattern that is loaded into the instruction register when the TAP controller passes through the Capture-IR state. If you’d like to learn more about Capture, Update and the JTAG State Machine, have a look at Michael Johnson’s blog, Operations of the TAP and the BC_1 Cell. This bit pattern is shifted out whenever a new instruction is shifted in, and the IEEE 1149.1 Standard mandates that the two least significant bits must be 01. In practice, this pattern is not an instruction; rather, it is a test pattern for the integrity of the 1149.1 circuitry. The ‘X’ signifies a “don’t care” or Unknown value.

And of course, INSTRUCTION_PRIVATE refers to private instructions. Stay away from these. It’s a good way to fry your chip or even the board it’s on.

Boundary-Scan Register Description

This section of the BSDL file provides a full description of every cell within the BSR. Depending on the size of the chip, it can range from 10s to thousands of entries. As the Spartan 6 contains 612 cells, I’ll just excerpt an early part of the BSR description here:

attribute BOUNDARY_LENGTH of XC6SLX9_FTG256 : entity is 612;

attribute BOUNDARY_REGISTER of XC6SLX9_FTG256 : entity is

-- cellnum (type, port, function, safe[, ccell, disval, disrslt])

      "   0 (BC_2, *, controlr, 1)," & --  TDO

      "   1 (BC_2, IO_D12, output3, X, 0, 1, Z)," & --  PAD44

      "   2 (BC_2, IO_D12, input, X)," & --  PAD44

      "   3 (BC_2, *, controlr, 1)," &

      "   4 (BC_2, IO_D11, output3, X, 3, 1, Z)," & --  PAD43

      "   5 (BC_2, IO_D11, input, X)," & --  PAD43

      "   6 (BC_2, *, controlr, 1)," &

The BOUNDARY_LENGTH attribute specifies the length of the boundary register, as you might expect.

The BOUNDARY_REGISTER attribute lists each cell, and describes the cell with its num, cell, port, function, safe, ccell, disval, and rslt fields. Let’s look at these individually:

cellnum: is a unique number tagging the cell. Note that cell 0 is closest to TDO.

type: is a specific cell type or design, for example BC_2. These cell types are listed in the package file above, and described at great length in the Standard and Ken Parker’s book. Maybe I’ll write an article on boundary scan cell types in the future.

port: refers to the port as described in the Logical Port Description section of the BSDL to which this cell belongs. If the cell has no attached signal, an asterisk (“*”) appears there.

function: describes the function of the cell, available as listed in the below table:

Function field symbol Meaning
Input Control-and-Observe cell (or an Observe-only cell not supporting INTEST) serving as an input pin.
Clock Observe_only cell at a system clock input. This cell supports INTEST.
Output2 A cell at a 2-state (either symmetric or asymmetric) output pin.
Output3 A cell at a 3-state output pin.
Control A cell that controls a 3-state enable.
Controlr A control that is forced (reset) to its disabling value when the TAP enters the Test-Logic-Reset state.
Internal A placeholder cell not associated with any pin. It may capture undefined data (“X”), static “0” or “1” data, or its own present value.
Bidir A single cell that can both observe a pin and supply data for its output driver. It is connected only to ports of type Inout.
Observe_Only A solitary observe-only cell on an input, or an additional cell observing any device system pin (this cell by itself cannot support INTEST).

safe: represents what a cell’s Update flip-flop should be loaded with when a test software might otherwise choose a random value. “X” means that it doesn’t matter what value is loaded. Note that cellnum 0, that is TDO, is loaded with “1”, as with a pull-up. cellnum 3 and 6 above, which are controlr cells, so that their drivers are enabled upon a reset.

The remaining three fields apply only to output cells, and describe how these outputs are disabled:

ccell: is the cell number of the control cell associated with this output. See above, for example, that cell number 4, which is an output3, has cell number 3 for its control cell. Cell number 3 can be used to disable the driver for cell number 4.

disval: contains either a ‘0’ or a ‘1’, that is loaded into an output cell’s control cell to disable it. So, for cell number 4, if a ‘1’ is loaded into cell number 3, cell number 4’s output is disabled.

disrslt: this is state of the output driver when it is disabled. It can have any of the following values:

disrslt Meaning
Z The driver enters a high-impedance state and does not supply current to its pin. Note that this is NOT a logic state.
Pull0 The (asymmetrical) driver does not supply current to its pin, but an internal pull-down function supplies a weak logical ‘0’ state.
Pull1 The (asymmetrical) driver does not supply current to its pin, but an internal pull-up function supplies a weak logical ‘1’ state.
Weak0 The (asymmetrical) driver does not supply current to its pin. An externally connected pull-down function must supply a weak logical ‘0’ state.
Weak1 The (asymmetrical) driver does not supply current to its pin. An externally connected pull-up function must supply a weak logical ‘1’ state.
Keeper The driver enters a high impedance state. The last strongly driven state supplied by the driver is “kept” by a weak feedback buffer. This is also NOT a logic state.

OK, one more topic of interest to cover. What happens if we run this BSDL through the ScanWorks parser, that will provide feedback on the syntax and semantics? Below is an excerpt of the output:

BSDL Translator Version 2.5

Copyright (C) 1996-2023, ASSET Intertech Inc.  All rights reserved.

Translator messages for input file c:\ScanWorks\Projects\Spartan6_test\Spartan6_BSDL\xc6slx9ftg256-2.bsd:

INFO HSM010: Line 586 - Duplicate opcode value (000001) in instruction_opcode attribute

WARNING HSN123: Line 989 - PULL1 value for boundary register description changed to WEAK1

WARNING HSN123: Line 1091 - PULL1 value for boundary register description changed to WEAK1

WARNING HSN123: Line 1112 - PULL1 value for boundary register description changed to WEAK1

WARNING HSN123: Line 1118 - PULL1 value for boundary register description changed to WEAK1

BSDL file c:\ScanWorks\Projects\Spartan6_test\Spartan6_BSDL\xc6slx9ftg256-2.bsd was successfully compiled and object generated.

This is just information output (INFO and WARNING) to highlight the following:

On line 586 of the BSDL, we see that the SAMPLE and PRELOAD instructions both have the same opcode, 000001. This is perfectly acceptable: in earlier versions of IEEE 1149.1, these were considered one instruction. Eventually it was agreed that they could be two separate instructions, independently coded and executed. But, for the Spartan 6, both use the same opcode. ScanWorks just informationally lets the user know that there is an overlap, that normally would not be allowed.

The following four Warnings relate to where PULL1 or PULL0 values appear in the boundary register description, ScanWorks represents these instead (but equivalently) as WEAK1 or WEAK0. The WARNING HSN123 message is raised to alert users to the fact that downstream reference to the boundary cells with PULL1 or PULL0 values will use the WEAK1 or WEAK0 terminology instead.

Well, that’s it for now. There’s much more to cover about BSDL, but If you’ve gotten this far, you’ll have a basic understanding, and can read any arbitrary BSDL file and get a sense of what is going on under the hood.

Want to learn more about JTAG in general? There’s a lot of material on our website, and I can recommend a high-level tutorial at IEEE 1149.1 JTAG and Boundary Scan Tutorial | Second Edition.

Alan Sguigna