/ecp5_jtag

Use ECP5 JTAG port to interact with user design

Primary LanguageVerilog

Lattice ECP5 User JTAG

Most FPGAs have a mechanism to bridge the standard JTAG IO pins of the FPGA into the core logic domain:

  • Intel has Virtual JTAG, probably the most advanced system with almost an unlimited number of user JTAG slave blocks.
  • Xilinx has the BSCAN class of cell primitives. For example, Xilinx 7 has the BSCANE2 cell, which there can be a maximum of 4, each for a different USER JTAG instruction.
  • Lattice has the JTAGx primitive.

The JTAGx primitives are listed in the Lattice FPGA Libraries Reference Guide.
There are currently 6 different versions:

  • JTAGA: LatticeSC/M architecture
  • JTAGB: LatticeECP/ECP and LatticeXP architecture
  • JTAGC: LatticeECP2/M architecture
  • JTAGD: LatticeECP2/M architecture
  • JTAGE: LatticeECP3 and LatticeXP2 architectures
  • JTAGF: MachXO2, MachX03D, MachX03L, and Platform Manager 2 architectures
  • JTAGG: LatticeECP5 architecture

Except for JTAGA, the pins of these primitives are mostly the same.

The primitive manual describes the functionality of these cells pretty well, except for ECP5, which says:

The JTAGG element is used to provide access to internal JTAG signals from within the FPGA fabric. This element is used for some cores, such as Reveal Logic Analyzer, and other purposes. Most users would typically not use this component directly.

However, since the pinout of JTAGG is identical to the one of earlier primitives, you can simply use those descriptions and it works just fine.

Note that using the JTAGG primitive will probably result in the inability to use Lattice Reveal Logic Analyzer, but that's OK if you're using the Yosys/NextPnR-based open source tool flow.

I googled a bit around for projects that use the JTAGG primitive. You can check those out below in the resources section.

Fundamentally, the cell is pretty simple: it supports 2 8-bit JTAG instructions: ER1 (0x32) and ER2 (0x38), and that's it. The user defined core logic can attach whichever scan logic it wants to these 2 instructions.

The JTAGG primitive has the following IO pins:

  • JTCK: output. Connected to the external TCK pin.
  • JTDI: output. Connected to a registered version of the external TDI pin (registered to JTCK posedge).
  • JSHIFT: output. High when the FPGA TAP is in Shift-DR state.
  • JUPDATE: output. High when the FPGA TAP is in Update-DR state.
  • JRSTN: output. Low when the TAP is in Test-Logic-Reset state.
  • JCE1: output. High when the ER1 instruction is selected and the TAP is in Capture-DR or Shift-DR state.
  • JCE2: output. High when the ER2 instruction is selected and the TAP is in Capture-DR or Shift-DR state.
  • JRT1: output. High when the ER1 instruction is selected and the TAP is in Run-Test/Idle state.
  • JRT2: output. High when the ER2 instruction is selected and the TAP is in Run-Test/Idle state.
  • JTDO1: input. Connected to TDO when ER1 instruction is selected, through a register clocked on JTCK negedge.
  • JTDO2: input. Connected to TDO when ER2 instruction is selected, through a register clocked on JTCK negedge.

The pins above are sufficient to shift data in and out of the TAP when ER1 or ER2 instructions are selected.

SpinalHDL Example

In the `./spinal directory, you can find a SpinalHDL example that uses the JTAGG primitive. In typical SpinalHDL fashion, there are lot of abstraction layers that make thing sometimes hard to follow, but it also allows easily porting over an example from one FPGA family to another. I've documentated the SpinalHDL specific bits in here.

The code requires SpinalHDL version 1.4.2 (as I write this, this is the latest release.) In earlier SpinalHDL versions, the JTAG infrastructure was quite a bit different.

Resources: