% render "layouts/basic.html" do %# HTML tags can be embedded in mark down files if you want to do specific custom %# formatting like this, but in most cases that is not required.
.gemspec
~~~ruby
spec.add_development_dependency "origen_jtag", ">= <%= Origen.app.version %>"
~~~
__NOTE:__ You will also need to include require 'origen_jtag'
somewhere in your environment. This can be done in config/environment.rb
for example.
### How To Use
#### New Style Example
The driver no longer requires specific pin names (or aliases), supports sub_block instantiation and DUTs with multiple JTAG ports.
You are no longer required to include "OrigenJTAG" in your DUT class.
Here is an example integration:
~~~ruby
class Pioneer
include Origen::TopLevel
# TCK covers 4 tester cycles, 2 high then 2 low for each effective TCK pulse
# Strobe TDO only when TCK high. Only store TDO on last cycle (3)
JTAG_CONFIG = {
:tclk_format => :rl,
:tclk_multiple => 4,
:tdo_strobe => :tclk_high,
:tdo_store_cycle => 3,
}
def initialize
add_pin :tclk
add_pin :tdi
add_pin :tdo
add_pin :tms
add_pin :tck2
add_pin :tdi2
add_pin :tdo2
add_pin :tms2
# In this first instance TCK covers 4 tester cycles,
# 2 high then 2 low for each effective TCK pulse.
# Strobe TDO only when TCK high. Only store TDO on last cycle (3)
# several pluggins use dut.jtag, your default port driver should be named jtag for compatibility
sub_block :jtag, class_name: 'OrigenJTAG::Driver',
tclk_format: :rl,
tclk_multiple: 4,
tdo_strobe: :tclk_high,
tdo_store_cycle: 3,
tck_pin: pin(:tclk),
tdi_pin: pin(:tdi),
tdo_pin: pin(:tdo),
tms_pin: pin(:tms)
# create a driver for a 2nd port like this
# note different configuration settings can be used
sub_block :jtag_port2, class_name: 'OrigenJTAG::Driver',
tclk_format: :rh,
tclk_multiple: 2,
tdo_strobe: :tclk_high,
tdo_store_cycle: 1,
tck_pin: pin(:tck2),
tdi_pin: pin(:tdi2),
tdo_pin: pin(:tdo2),
tms_pin: pin(:tms2)
end
end
dut.jtag # => jtag driver for the first port (tclk, tdi, tdo, tms)
dut.jtag_port2 # => jtag driver for the second port (tck2, tdi2, tdo2, tms2)
~~~
#### Legacy Example
Include the OrigenJTAG
module to add a JTAG driver to your class and
define the required pins.
Normally the pins would be an alias to existing DUT pins and therefore the
JTAG driver module cannot assume them.
Including the module adds a jtag
method which will return an instance of
[OrigenJTAG::Driver
](<%= path "api/OrigenJTAG/Driver.html" %>).
The following attributes can be customized by defining a JTAG_CONFIG
hash:
* **tclk_format** - TCLK timing format, Return High (:rh) or Return Low (:rl). Default is :rh.
* **tclk_multiple** - Number of cycles for a single TCLK pulse to cover, to support cases where TCLK needs to be a fraction of another clock period. Assumes 50% duty cycle, specify only even numbers if > 1. Default is :r1.
* **tdo_strobe** - When using multiple cycles for TCK, which state of TCK to strobe for TDO, :tclk_high or :tclk_low or :tclk_all. Default :tclk_high.
* **tdo_store_cycle** - When using multiple cycles for TCK, which cycle of TCK to store for TDO if store requested (0 to number of tclk_multiple-1). Default 0
Here is an example integration:
~~~ruby
class Pioneer
include OrigenJTAG
include Origen::Pins
# TCK covers 4 tester cycles, 2 high then 2 low for each effective TCK pulse
# Strobe TDO only when TCK high. Only store TDO on last cycle (3)
JTAG_CONFIG = {
:tclk_format => :rl,
:tclk_multiple => 4,
:tdo_strobe => :tclk_high,
:tdo_store_cycle => 3,
}
def initialize
add_pin :tclk
add_pin :tdi
add_pin :tdo
add_pin :tms
end
end
Pioneer.new.jtag # => An instance of OrigenJTAG::Driver
~~~
#### APIs
Two APIs are provided, the primary one provides canned methods to read and
write to the IR and DR registers.
These accept either an absolute data value or an Origen register/bit collection.
~~~ruby
jtag.write_dr 0x1234, :size => 16
# The size option is not required when a register is supplied
jtag.write_dr $dut.reg(:clkdiv)
# Although it can still be added if the register is not the full data width
jtag.write_dr $dut.reg(:clkdiv), :size => 32
# A rich read method is available which supports bit-level read, store and overlay operations
$dut.reg(:clkdiv).bits(:div).read(0x55)
jtag.read $dut.reg(:clkdiv)
# In cases where both shift in (TDI) and shift out data (TDO) are critical, (e.g. compare shift
# out data on a write, or shfit in specific data on a read) the shift_in_data and
# shift_out_data options can be specified. By default, TDO will be dont care on writes
# and TDI will be 0 on reads.
jtag.write_dr $dut.reg(:clkdiv), :shift_out_data => 0x4321
jtag.read_dr $udt.reg(:clkdiv), :shift_in_data => 0x5678
# Similar methods exist for the instruction register
jtag.write_ir 0x1F, :size => 5
jtag.read_ir 0x1F, :size => 5
~~~
A secondary API provides low level control of the TAP Controller state machine.
~~~ruby
jtag.pause_dr do
jtag.shift_dr do
# The shift method accepts the same arguments as the canned read/write methods
jtag.shift 0x55, :size => 32
end
end
~~~
See the [OrigenJTAG::Driver
](<%= path "api/OrigenJTAG/Driver.html" %>) and
[OrigenJTAG::TAPController
](<%= path "api/OrigenJTAG/TAPController.html" %>)
APIs for more details about the available driver methods.
Any model/controller within a target runtime environment can listen out for JTAG state
changes by implementing the following callback handler:
~~~ruby
def on_jtag_state_change(new_state)
if new_state == :update_dr
# Do something every time we enter this state
end
end
~~~
### How To Setup a Development Environment
[Clone the repository from Github](https://github.com/Origen-SDK/origen_jtag).
An instance of the OrigenJTAG driver is hooked up to a dummy DUT
object for use in the console:
~~~
origen i
> $dut.jtag
=> #