cocotbext-jtag

jtag modules for cocotb


Keywords
jtag, cocotb
License
MIT
Install
pip install cocotbext-jtag==0.0.12

Documentation

JTAG interface modules for Cocotb

Build Status codecov PyPI version Downloads

GitHub repository: https://github.com/daxzio/cocotbext-jtag

Introduction

JTAG simulation models for cocotb.

Installation

Installation from pip (release version, stable):

$ pip install cocotbext-jtag

Installation from git (latest development version, potentially unstable):

$ pip install https://github.com/daxzio/cocotbext-jtag/archive/main.zip

Installation for active development:

$ git clone https://github.com/daxzio/cocotbext-jtag
$ pip install -e cocotbext-jtag

Documentation and usage examples

See the tests directory for complete testbenches using these modules.

JTAG Bus

The JTAGBus is used to map to a JTAG interface on the dut. These hold instances of bus objects for the individual channels, which are currently extensions of cocotb_bus.bus.Bus. Class methods from_entity and from_prefix are provided to facilitate signal default name matching.

Required:

  • tck
  • tms
  • tdi
  • tdo

Optional:

  • trst

JTAG Driver

The JTAGDriver class implement a JTAG driver and is capable of generating read and write operations against JTAG devices, either singularly or in a chain.

To use these modules, import the one you need and connect it to the DUT:

from cocotbext.jtag import JTAGDriver, JTAGBus, JTAGDevice

bus = JTAGBus(dut)
jtag_driver = JTAGDriver(bus)
jtag_driver.add_device(JTAGDevice())

The first argument to the constructor accepts an JTAGBus object. These objects are containers for the interface signals and include class methods to automate connections.

Once the module is instantiated, read and write operations can be initiated in a couple of different ways.

Additional optional arguments for JTAGDriver

  • period: Clock frequency period of tck, default 100
  • units: Clock units, default ns
  • logging_enabled: Logging enable, default True

Methods

  • add_device(device): Add device to jtag chain, must be of type JTAGDevice
  • set_reset(num): Reset for num if trst is present in JTAGBus, raise warning if trst is not present
  • reset_finished(): Asyn wait until reset is finished
  • reset_fsm(): Send 5 tck pulses while tms is held high in JTAGBus, this resets the finite state machine inside a JTAG TAP
  • send_val(addr, val, device, write): Send addr to device (default: 0). The val is used to write if write is True or verify against if write is False
  • write_val(addr, val, device=0): Write val to addr of device (default: 0).
  • read_val(addr, val=None, device=0): Read from addr of device (default: 0). If val present verify against returned value.
  • read_idcode(device): Read device number device and confirm it matched the IDCODE set for that device

JTAG Device

JTAGDriver needs to be told what devices are in the JTAG chain it is communicating with inside the dut. A JTAGDevice needs to be defined for this purpose or a device that inherits from this base class.

A JTAGDevice needs a name, idcode and ir_len. It also seens to have the IR Register map defined and the width of the the register. 'BYPASS' is prepopulated in the base class at last address in the IRLEN address map.

First inherit from the base class, , and after add all the other IR regiters using the add_jtag_reg method.

from cocotbext.jtag import JTAGDevice

class J1JTAGDevice(JTAGDevice):
    def __init__(self, name='jtaglet1', idcode=0x53817905, ir_len=5):
        super().__init__(name, idcode, ir_len)
        self.add_jtag_reg("IDCODE", 32, 0x1e)
        self.add_jtag_reg('USERDATA', 32, 0x8)
        self.add_jtag_reg('USEROP', 8, 0x9)
        self.idle_delay = 6
  • add_jtag_reg(name, width, address): Add an IR register to JTAGDevice. name is a string, width is the DR shift width of the register and the address, which should be with in the range if the ir_len of JTAGDevice

This results in a JTAGDevice that has 4 IR register defined:

0x08: USERDATA[31:0] 
0x09: USEROP[7:0] 
0x1e: IDCODE[31:0] 
0x1f: BYPASS[0:0] 

Multiple devices inside the JTAG chain:

from cocotbext.jtag import JTAGDriver
from cocotbext.jtag import JTAGBus

class testbench:
    def __init__(self, dut):
        bus = JTAGBus(dut)
        self.jtag = JTAGDriver(bus)
        self.jtag.add_device(J1JTAGDevice())
        self.jtag.add_device(J2JTAGDevice())