Skip to content

BSDL

A TAP-only BSDL emitter: the file the ICL AccessLink written by to_icl points at, so ICL, BSDL and PDL together say how to reach the network. It is not a chip-level BSDL -- it declares no boundary register, so tools that require one will reject it. See the module docstring below for the exact scope, what EXTEST means for a SIB network, and what is (and is not) independently validated.

from warptap import insert_test_access, to_bsdl, to_icl

IDCODE = 0x5CA1AB1F  # your own: 32 bits, bit 0 set (IEEE 1149.1)

verilog, graph, root = insert_test_access(sources, "mem_subsystem_mbist", specs, idcode_value=IDCODE)
bsdl_text = to_bsdl("mem_subsystem_mbist", tck_max_freq_hz=10e6, idcode_value=IDCODE)
icl_text = to_icl(graph, root, bsdl_entity_name="mem_subsystem_mbist")

Give to_bsdl the same idcode_value the TAP was inserted with: the BSDL's IDCODE_REGISTER must match what the hardware shifts out. Without it, both use warptap.tap_model.IDCODE_VALUE, a placeholder whose manufacturer field lands in an assigned JEP106 slot, so set your own for anything you ship. TapModel and tap_integrity.TapConfig take the same idcode_value when modelling or testing that TAP.

warptap.bsdl_emit

BSDL (IEEE 1149.1 Boundary-Scan Description Language) emitter for the TAP warptap inserts.

Scope is exactly what an IEEE 1687 ICL AccessLink ... Of STD_1149_1_2001 needs to point at: the entity, the five TAP pins, the TAP scan attributes, the instruction register (length, opcodes, capture pattern), the IDCODE register, and the instruction that reaches the IJTAG network. Every value comes from :mod:warptap.tap_model / :mod:warptap.tap_ports -- no literal is duplicated here -- so this file can only drift from rtl/tap_core.v if tap_model itself does, which tests/test_tap_fsm_cross_sim.py checks against the RTL.

This is NOT a chip-level BSDL. It declares no BOUNDARY_LENGTH and no BOUNDARY_REGISTER. Standard-following BSDL parsers and boundary-scan tools treat the boundary register as mandatory (IEEE 1149.1's BYPASS/SAMPLE/PRELOAD/EXTEST requirements all concern it), so expect such a tool to reject this file or report it incomplete; a permissive parser that only checks syntax (UrJTAG's bsdl test) accepts it. The mandatory-attribute list here was taken from secondary sources (ASSET InterTech's BSDL overview, Lauterbach's boundary-scan guide, the IEEE 1149.1 working group's published STD_1149_1_2012 package declarations); the primary IEEE 1149.1 text is paywalled and was not read. When a design has a boundary-scan register (via :mod:warptap.bsr_insert), extending this emitter to describe it is a follow-up, not something this module attempts.

What EXTEST means here. In real 1149.1, EXTEST drives the boundary register. In a warptap SIB design there is none: rtl/tap_core.v presents the SIB chain's tail (external_dr_tdo) at tdo for every instruction that is neither IDCODE nor BYPASS, but :mod:warptap.sib_insert decodes EXTEST into every top-level SIB's select, so only EXTEST moves the IJTAG network: under SAMPLE/PRELOAD its tail reaches tdo but it holds still (see :data:warptap.tap_model.NETWORK_ACCESS_INSTRUCTION). The emitted DESIGN_WARNING says so. The network's length depends on SIB state, so it cannot be declared as a fixed-length REGISTER_ACCESS entry and is deliberately not.

IJTAG_ACCESS. For a TAP inserted with ijtag_access_opcode, pass to_bsdl the same value: it declares an IJTAG_ACCESS instruction at that opcode, the one that selects the network, and REGISTER_ACCESS gives EXTEST, SAMPLE and PRELOAD the BYPASS register, which is what they select in that TAP. A tool that holds those three to the boundary register will object; there is none to give them, and the DESIGN_WARNING says so.

The IDCODE is whatever the design's tap_core was built with: pass to_bsdl the same idcode_value given to insert_test_access/insert_sib_network. The default, :data:warptap.tap_model.IDCODE_VALUE, is a placeholder, and only then does the output call it one.

No independent BSDL parser validates this output. The one candidate that would accept a TAP-only file, UrJTAG (its parser checks syntax and structure only), was installed and tried; the Ubuntu-packaged 0.10+r2007 build is unusable -- see tests/test_bsdl_emit.py's docstring for the evidence. Standard-following parsers require the boundary register, so no independent tool could check conformance of this file anyway: it is non-conformant by design. What is checked instead: the emitted text is read back and compared with tap_model (tests/test_bsdl_emit.py), and every behavioral claim is verified by driving the real TAP RTL under Icarus (tests/test_bsdl_emit_cross_sim.py).

BsdlEmitError

Bases: WarptapError

Raised for an entity name that isn't a valid BSDL/VHDL identifier, or a TCK frequency that isn't a finite positive number.

to_bsdl

to_bsdl(entity_name: str, *, tck_max_freq_hz: float, idcode_value: int = IDCODE_VALUE, ijtag_access_opcode: int | None = None) -> str

Render the BSDL for the TAP warptap inserts, as the entity entity_name (use the same string passed to to_icl as its BSDLEntity -- the real top module's name).

tck_max_freq_hz is required: BSDL's mandatory TAP_SCAN_CLOCK states the maximum TCK frequency, and TCK timing is not something the RTL tells warptap -- the integrator must state it. The clock is declared safe to stop in either state (BOTH): rtl/tap_core.v is fully static edge-triggered logic. Raises :class:BsdlEmitError for an entity name that isn't a valid BSDL/VHDL identifier (letters, digits, single underscores, starts with a letter, not a VHDL reserved word) or a non-positive/non-finite frequency.

idcode_value must be the IDCODE the design's tap_core was built with (the idcode_value given to insert_test_access/insert_sib_network): a 32-bit value with bit 0 set, as IEEE 1149.1 requires, else :class:BsdlEmitError. Only the default, :data:~warptap.tap_model.IDCODE_VALUE, is described as a placeholder in the output.

ijtag_access_opcode must be the one the design's TAP was built with (None, the default, for a TAP whose network instruction is EXTEST). With it, an IJTAG_ACCESS instruction is declared at that opcode and REGISTER_ACCESS gives EXTEST, SAMPLE and PRELOAD the BYPASS register; an opcode no TAP can have raises :class:BsdlEmitError.

See the module docstring for what this file is not (a chip-level BSDL) and what is and isn't independently validated.