应用笔记 3339

利用MxTNI JTAG库和SVF文件编程Xilinx PROM器件


摘要 : 本应用笔记阐述了如何利用MxTNI™ JTAG库以及串行向量格式(SVF)文件来编程Xilinx® PROM器件。假定读者已经对JTAG和可编程逻辑器件有了一定认识。

介绍

Maxim微型网络接口(MxTNI)是Dallas Semiconductor (Maxim Integrated的全资子公司)开发的一个平台。它包含了一套小型却功能强大的芯片组以及Java®可编程虚拟机。芯片组具有处理、控制、器件级通信和网络互连的能力。为了和任何JTAG器件通信,TINIs400适配板在J21端具有4引脚JTAG输出。 这些引脚将直接连到JTAG器件上标准JTAG引脚TDI、TDO、TMS和TCK。

在系统编程PROM可以进行单独编程,或者级连编程。链中的所有器件共享TCK和TMS信号。MxTNI的TDI信号接到边界扫描链中第一个器件的TDI输入端。第一个器件的TDO信号接到链中第二个器件的TDI输入上,如此连接下去。链中的最后一个器件的TDO输出接到MxTNI的TDO引脚上,见图1所示。

图1. 所有JTAG操作都通过器件的测试访问端口进行控制
图1. 所有JTAG操作都通过器件的测试访问端口进行控制

所有JTAG操作都是由器件的测试访问端口(TAP)控制的。TAP包括四个信号:TMS、TDI、TDO和TCK。 这些信号通过TAP控制器,即16状态有限状态机与器件相互作用。JTAG的TMS信号控制状态间的转换。指令和数据由TDI引脚移入器件,并由TDO引脚移出。TDI和TDO信号的所有状态转换和行为都与TCK同步。见图2

图2.
图2.

所有JTAG操作都是将数据移入或移出JTAG指令和数据寄存器。TAP控制器可对所有这些寄存器直接访问。有两类JTAG寄存器:指令寄存器(IR)和数据寄存器(DR)。访问IR通过移位-IR (Shift-IR)状态实现,而访问DR通过移位-DR (Shift-IR)状态实现。IR长度通常是大于2位的任意长度。除了由IEEE® Std. 1149.1定义的BYPASS指令为全1以外,生产商定义所有其它的指令位码。

在本应用笔记中,JAVA样例代码将解释说明串行向量格式(SVF)文件来进行编程。这里所用的SVF是描述高层IEEE 1149.1 (JTAG)总线操作的语法规范。JTAG设备和软件提供商已经将SVF作为标准用于数据交换。SVF以紧凑和可移植的形式描述JTAG链操作。SVF文件通过描述需要移入器件链的信息,记录JTAG操作。通过Xilinx iMPACT (详细信息见下面)软件,将JTAG操作记录在SVF文件中。SVF文件写成ASCII文本形式,因此可以在任何文本编辑器中人工读、修改和写。“许多第三方编程工具使用SVF文件作为输入,这样利用包含在SVF文件中的信息可以对JTAG链中的Xilinx器件编程。”

JTAG库简要说明

所开发的JTAG类库可帮助用户使用MxTNI与JTAG器件进行通信。一个可能的应用是:从遥远的位置对可编程逻辑进行动态和在系统更新。用户能够将TAP控制器初始化到初始状态、浏览16个状态、获得或设置TAP状态、产生时钟信号、发送命令和数据等等。以下为JTAG类方法的简要说明:
  • public jtag(): 加载jtag库。
  • public String getVersion(): 返回jtag类的版本。
  • public int runClock( int numticks ): 以numticks指定的数量运行时钟。
  • public byte initialize(): 先将TMS置高达五个TCK时钟脉冲,然后TMS置低1个时钟并进入缺省状态Run-Test-Idle。
  • public byte setState( byte aState ): 将目标状态设置为aState指定的状态。
  • public byte getState(): 返回目标状态。
  • public byte scanState( byte state ): 将TAP控制器的状态机转换到参数state指定的状态。
  • public String displayState(byte state): 显示TAP控制器的状态。
  • public byte waitState( int msecs ): 进程延时一定毫秒数。
  • public byte getTDO(): 获得引脚TDO的当前状态。
  • public void setTDI(byte logic): 引脚TDI设定为指定的逻辑状态。
  • public byte getTDI(): 获得引脚TDI的当前状态。
  • public void setTMS(byte logic): s引脚TMS设定为指定的逻辑状态。
  • public byte getTMS(): 获得引脚TMS的当前状态。
  • public void setTCK(byte logic): 引脚TCK设定为指定的逻辑状态。
  • public byte getTCK(): 获得引脚TCK的当前状态。
  • public byte sendNrcv(byte[] data, int offset, int size, byte numberOfBits, boolean state, boolean update, byte extraHeaderClock, byte HeaderBitVal,byte extraTrailerClock, byte TrailerBitVal): 发送数据字节数组,并接收返回的字节数组。
  • public byte sendNrcv(int[] data, int offset, int size, byte numberOfBits, boolean state, boolean update,byte extraHeaderClock, byte HeaderBitVal,byte extraTrailerClock, byte TrailerBitVal): 发送数据整形数组,并接收返回的整形数组。
关于JTAG类的更多详细信息,请访问http://files.maximintegrated.com/tini/appnotes/jtaglib。

硬件和软件需求

以下为所需要的硬件和软件:

编程步骤

第1步: 将MxTNI板的4个JTAG引脚与JTAG器件的4个JTAG引脚相连。
第2步: 遵循SVF文件的命令并使用JTAG库编写JAVA应用程序,来对JTAG器件进行编程,编译后加载到MxTNI。
(附录A: 一个样例Idcode.svf文件,实现从单独的XC18V02 Xilinx器件读取IDCODE。)
(附录B: 样例AppJtag.java程序,将SVF文件作为输入并产生JTAG信号来读取IDCODE。该样例程序是用来处理单独器件的(对于级连器件的详细信息见附录C)。)
(附录C: 展示了由已有的SVF文件编程级连器件的步骤。)
第3步: 运行JAVA程序。可执行AppJtag.tini将加载到MxTNI板。在MxTNI提示符下录入“java AppJtag.tini Idcode.svf”来运行程序。程序将产生JTAG信号与JTAG器件进行通信。注意:
  1. 生成的编程JTAG器件SVF文件应该与器件链中设计的确切模型一致。
  2. 所有操作码,例如编程JTAG器件的READ、WRITE、ERASE及其它命令等,都是由生产商定义的。SVF文件应该包含用户需要的所有操作码。

示例

以下示例说明了如何利用JTAG库从Xilinx JTAG器件XC18V02中读取Idcode。完整的样例代码,请查阅附录B。
  1. 生成器件模型的SVF文件:
    使用Xilinx WEB START来生成SVF文件。
    • 执行iMPACT并选择单选按钮“Prepare Configuration Files”选项,然后点击next。选择单选按钮“Boundary Scan file”并点击next。选择“SVF File”然后点击finish。
    • 在对话框中录入SVF文件名,例如example,并点击OK。
    • 选择要加载的name_of_mcs_file.mcs文件,并从列表中选择PROM器件(XC18V02_vq44)。
    • XC18V02已加到模型中。
    • 点击我们要编程的XC18V02器件型号。器件将为高亮显示。
    • 点击鼠标右键,并选择编程选项。勾选“Get Idcode”。
    • 在模型外点击鼠标以取消高亮显示器件,右击并选择option以关闭SVF。这时就生成了模型的SVF文件。
  2. 读取SVF文件并使用JTAG库来编程XC18V02器件。
    • 以下为SVF文件的部分样例代码:
    // Created using Xilinx iMPACT Software [ISE WebPACK - 5.1i]
    TRST OFF;
    ENDIR IDLE;
    ENDDR IDLE;
    STATE RESET IDLE;
    TIR 0 ;
    HIR 0 ;
    TDR 0 ;
    HDR 0 ;
    // Validating chain...
    TIR 0 ;
    HIR 0 ;
    TDR 0 ;
    HDR 0 ;
    SIR 8 TDI (ff) SMASK (ff) ;
    TIR 0 ;
    HIR 5 TDI (1f) SMASK (1f) ;
    HDR 1 TDI (00) SMASK (01) ;
    TDR 0 ;
    //Loading device with 'idcode' instruction.
    SIR 8 TDI (fe) SMASK (ff) ;
    SDR 32 TDI (00000000) SMASK (ffffffff) TDO (05025093) MASK (ffffffff) ;
    //Loading device with 'conld' instruction.
    SIR 8 TDI (f0) ;
    RUNTEST 110000 TCK;
    
    • 遵循SVF命令并使用库向XC18V02发送命令。
    • SVF规范提供了四个全局填充指令:头指令寄存器(HIR)、尾部指令寄存器(TIR)、头数据寄存器(HDR)和尾部数据寄存器(TDR)。这些全局命令规定了移位操作的开始和结尾处要填充的位数,从而解决旁路器件问题,并为SVF文件压缩提供了一种简单的方法。一旦指定,这些位会出现在SIR或者SDR命令的每一组比特位的前面或者后面。
    • 以下两个示例说明如何把SVF命令解释为JTAG库命令。


示例1: 带有全局填充指令的SVF语法结构
a/ SVF file commands:
STATE RESET IDLE;
TIR 0 ;
HIR 5 TDI (1f) SMASK (1f) ;
HDR 1 TDI (00) SMASK (01) ;
TDR 0 ;
//Loading device with 'idcode' instruction.
SIR 8 TDI (fe) SMASK (ff) ;
SDR 32 TDI (00000000) SMASK (ffffffff) TDO (05025093) MASK (ffffffff) ;
//Loading device with 'conld' instruction.
SIR 8 TDI (f0) ;
RUNTEST 110000 TCK;
//Check for Read/Write Protect.
SIR 8 TDI (ff) TDO (01) MASK (ff) ;
//Loading device with 'idcode' instruction.
SIR 8 TDI (fe) ;
SDR 32 TDI (00000000) TDO (05025093) ;
//Loading device with 'conld' instruction.
SIR 8 TDI (f0) ;
RUNTEST 110000 TCK;
//Check for Read/Write Protect.
SIR 8 TDI (ff) TDO (01) ;
TIR 0 ;
HIR 0 ;
TDR 0 ;
HDR 0 ;
b/ Sample JAVA program using JTAG library:
import java.io.*;
import javax.comm.*;
import com.dalsemi.comm.*
public static void main(String[] args)
{
myJtag = new jtag();
int SIZE = 0x1000;
byte[] byteArray = new byte[SIZE];
byte HeaderInstBitVal = (byte)0x00;
byte TrailerInstBitVal = (byte)0x00;
byte HeaderDataBitVal= (byte)0x00;
byte TrailerDataBitVal= (byte)0x00;
// STATE RESET IDLE;
myJtag.initialize();//This JTAG library method will initialize
		  // XC18V02 TAP controller and stay at
		  // Run-Test/Idle
// TIR 0 ;
byte TIR = (byte)0x00;
// HIR 5 TDI (1f) SMASK (1f) ;
byte HIR = (byte)0x05;
HeaderInstBitVal = (byte)0x01;
// HDR 1 TDI (00) SMASK (01) ;
byte HDR = (byte)0x01;
HeaderDataBitVal = (byte)0x00;
// TDR 0
byte TDR = (byte)0x00;
// SIR 8 TDI (fe) SMASK (ff) ;
byteArray[0] = (byte)0xfe;
myJtag.sendNrcv(byteArray,0,1,(byte)8,true,false,(byte)HIR,
(byte)HeaderInstBitVal,(byte)TIR,(byte)TrailerInstBitVal);
// SDR 32 TDI (00000000) SMASK (ffffffff) TDO (05025093) MASK
// (ffffffff) ;
byteArray[0] = (byte)0x00;
byteArray[1] = (byte)0x00;
byteArray[2] = (byte)0x00;
byteArray[3] = (byte)0x00;
myJtag.sendNrcv(byteArray,0,4,(byte)8,false,false,(byte)HDR,
(byte)HeaderDataBitVal,(byte)TDR,(byte)TrailerDataBitVal);
// SIR 8 TDI (f0) ;
byteArray[0] = (byte)0xf0;
myJtag.sendNrcv(byteArray,0,1,(byte)8,true,false,(byte)HIR,
(byte)HeaderInstBitVal,(byte)TIR,(byte)TrailerInstBitVal);
// RUNTEST 110000 TCK;
myJtag.waitState(100); // Depend on operation frequency, user can
			 // calculate how many miliseconds to wait.
}
示例2: 无全局填充指令的SVF语法结构
a/ SVF file commands:
STATE RESET IDLE;
TIR 0 ;
HIR 0 ;
TDR 0 ;
HDR 0 ;
SIR 13 TDI (1fff) SMASK (1fff) ;
SDR 2 TDI (00) SMASK (03) ;
SIR 13 TDI (1fff) TDO (0021) MASK (1c63) ;
// Loading devices with 'ispen' or 'bypass'  instruction.
SIR 13 TDI (1d1f) ;
SDR 7 TDI (68) SMASK (7f) ;
// Loading device with 'faddr' instruction.
SIR 13 TDI (1d7f) ;
SDR 17 TDI (000002) SMASK (01ffff) ;
RUNTEST 1 TCK;
// Loading device with 'ferase' instruction.
SIR 13 TDI (1d9f) ;
RUNTEST 100000 TCK;
// Loading device with a 'faddr' instruction.
SIR 13 TDI (1d7f) ;
SDR 17 TDI (000002) ;
RUNTEST 1 TCK;
// Loading device with 'serase' instruction.
SIR 13 TDI (015f) ;
RUNTEST 37000 TCK;
// Loading devices with 'conld' or 'bypass' instruction.
SIR 13 TDI (1e1f) ;
RUNTEST 110000 TCK;
// Loading devices with 'ispen' or 'bypass'  instruction.
SIR 13 TDI (1d1f) ;
SDR 7 TDI (68) SMASK (7f) ;
// Loading device with a 'fdata0' instruction.
SIR 13 TDI (1dbf) ;
b/ Sample JAVA program using JTAG library:
import java.io.*;
import javax.comm.*;
import com.dalsemi.comm.*
public static void main(String[] args)
{
myJtag = new jtag();
int SIZE = 0x1000;
int[] intArray = new int[SIZE];
byte HeaderInstBitVal = (byte)0x00;
byte TrailerInstBitVal = (byte)0x00;
byte HeaderDataBitVal= (byte)0x00;
byte TrailerDataBitVal= (byte)0x00;
// STATE RESET IDLE;
myJtag.initialize();//This JTAG library method will initialize
	  // XC18V02 TAP controller and stay at
	  // Run-Test/Idle
// TIR 0 ;
byte TIR = (byte)0x00;
// HIR 0 ;
byte HIR = (byte)0x00;
// HDR 0 ;
byte HDR = (byte)0x00;
// TDR 0
byte TDR = (byte)0x00;
// SIR 13 TDI (1fff) SMASK (1fff) ;
intArray[0] = (int)(0x1fff&0x1fff);
myJtag.sendNrcv(intArray,0,1,(byte)13,true,false,(byte)HIR,
(byte)HeaderInstBitVal,(byte)TIR,(byte)TrailerInstBitVal);
// SDR 2 TDI (00) SMASK (03) ;
intArray[0] = (int)(0x00&0x03);
myJtag.sendNrcv(intArray,0,1,(byte)2,false,false,(byte)HDR,
(byte)HeaderDataBitVal,(byte)TDR,(byte)TrailerDataBitVal);
// SIR 13 TDI (1fff) TDO (0021) MASK (1c63) ;
intArray[0] = (byte)0x1fff;
myJtag.sendNrcv(intArray,0,1,(byte)13,true,false,(byte)HIR,
(byte)HeaderInstBitVal,(byte)TIR,(byte)TrailerInstBitVal);
// SIR 13 TDI (1d1f) ;
intArray[0] = (byte)0x1d1f;
myJtag.sendNrcv(intArray,0,1,(byte)13,true,false,(byte)HIR,
(byte)HeaderInstBitVal,(byte)TIR,(byte)TrailerInstBitVal);
// SDR 7 TDI (68) SMASK (7f) ;
intArray[0] = (int)(0x68&0x7f);
myJtag.sendNrcv(intArray,0,1,(byte)7,false,false,(byte)HDR,
(byte)HeaderDataBitVal,(byte)TDR,(byte)TrailerDataBitVal);
// SIR 13 TDI (1d7f) ;
intArray[0] = (byte)0x1d7f;
myJtag.sendNrcv(intArray,0,1,(byte)13,true,false,(byte)HIR,
(byte)HeaderInstBitVal,(byte)TIR,(byte)TrailerInstBitVal);
// SDR 17 TDI (000002) SMASK (01ffff) ;
intArray[0] = (int)(0x0002 & 0xffff);
TDR = (byte)0x01;
myJtag.sendNrcv(intArray,0,1,(byte)16,false,false,(byte)HDR,
(byte)HeaderDataBitVal,(byte)TDR,(byte)TrailerDataBitVal);
// RUNTEST 1 TCK;
myJtag.waitState(1);
// SIR 13 TDI (1d9f) ;
intArray[0] = (byte)0x1d9f;
myJtag.sendNrcv(intArray,0,1,(byte)13,true,false,(byte)HIR,
(byte)HeaderInstBitVal,(byte)TIR,(byte)TrailerInstBitVal);
// RUNTEST 100000 TCK;
myJtag.waitState(1000);
// SIR 13 TDI (1d7f) ;
intArray[0] = (byte)0x1d7f;
myJtag.sendNrcv(intArray,0,1,(byte)13,true,false,(byte)HIR,
(byte)HeaderInstBitVal,(byte)TIR,(byte)TrailerInstBitVal);
// SDR 17 TDI (000002) ;
intArray[0] = (int)(0x0002 & 0xffff);
TDR = (byte)0x01;
myJtag.sendNrcv(intArray,0,1,(byte)16,false,false,(byte)HDR,
(byte)HeaderDataBitVal,(byte)TDR,(byte)TrailerDataBitVal);
// RUNTEST 1 TCK;
myJtag.waitState(1);
// SIR 13 TDI (015f) ;
intArray[0] = (byte)0x015f;
myJtag.sendNrcv(intArray,0,1,(byte)13,true,false,(byte)HIR,
(byte)HeaderInstBitVal,(byte)TIR,(byte)TrailerInstBitVal);
// RUNTEST 37000 TCK;
myJtag.waitState(100);
// SIR 13 TDI (1e1f) ;
intArray[0] = (byte)0x1e1f;
myJtag.sendNrcv(intArray,0,1,(byte)13,true,false,(byte)HIR,
(byte)HeaderInstBitVal,(byte)TIR,(byte)TrailerInstBitVal);
// RUNTEST 110000 TCK;
myJtag.waitState(110);
// SIR 13 TDI (1d1f) ;
intArray[0] = (byte)0x1d1f;
myJtag.sendNrcv(intArray,0,1,(byte)13,true,false,(byte)HIR,
(byte)HeaderInstBitVal,(byte)TIR,(byte)TrailerInstBitVal);
// SDR 7 TDI (68) SMASK (7f) ;
intArray[0] = (int)(0x68 & 0x7f);
TDR = (byte)0x00;
myJtag.sendNrcv(intArray,0,1,(byte)7,false,false,(byte)HDR,
(byte)HeaderDataBitVal,(byte)TDR,(byte)TrailerDataBitVal);
// SIR 13 TDI (1dbf) ;
intArray[0] = (byte)0x1dbf;
myJtag.sendNrcv(intArray,0,1,(byte)13,true,false,(byte)HIR,
(byte)HeaderInstBitVal,(byte)TIR,(byte)TrailerInstBitVal);
}

结论

由提供的SVF文件来编程Xilinx PROM器件是非常简单的。但是,如果用户能够正确分析SVF文件并理解如何确定对器件链中哪个器件进行编程,会更有好处。知道了这些信息,编程者能够更加高效地使用JTAG库。软件小组要对遥远位置的Xilinx JTAG器件进行编程,已有实际应用。利用开发包中的嵌入式JTAG编程软件,并以mcs文件作为输入文件,这是很容易做到的。

附录A
获得器件IDCODE的完整样例IDCODE.SVF文件
// Created using Xilinx iMPACT Software [ISE WebPACK - 5.1i]
TRST OFF;
ENDIR IDLE;
ENDDR IDLE;
STATE RESET IDLE;
TIR 0 ;
HIR 0 ;
TDR 0 ;
HDR 0 ;
// Validating chain...
TIR 0 ;
HIR 0 ;
TDR 0 ;
HDR 0 ;
SIR 13 TDI (1fff) SMASK (1fff) TDO (0021) MASK (1c63) ;
TIR 0 ;
HIR 5 TDI (1f) SMASK (1f) ;
HDR 1 TDI (00) SMASK (01) ;
TDR 0 ;
//Loading device with 'idcode' instruction.
SIR 8 TDI (fe) SMASK (ff) ;
SDR 32 TDI (00000000) SMASK (ffffffff) TDO (05025093) MASK (ffffffff) ;
//Loading device with 'conld' instruction.
SIR 8 TDI (f0) ;
RUNTEST 110000 TCK;
//Check for Read/Write Protect.
SIR 8 TDI (ff) TDO (01) MASK (ff) ;
//Loading device with 'idcode' instruction.
SIR 8 TDI (fe) ;
SDR 32 TDI (00000000) TDO (05025093) ;
//Loading device with 'bypass' instruction.
SIR 8 TDI (ff) ;
TIR 0 ;
HIR 0 ;
TDR 0 ;
HDR 0 ;
SIR 13 TDI (1fff) SMASK (1fff) ;
SDR 2 TDI (00) SMASK (03) ;
附录B
读取单独XILINX器件XC18V02 IDCODE的示例。
NOTES: This sample program will process SVF file with global padding instructions only.
Users need to modify to work with SVF file without global padding.
import java.io.*;
import java.lang.*;
import javax.comm.*;
import com.dalsemi.comm.*;
public final class AppJtag
{
private static jtag myJtag;
// Starting index of data array
static int Offset = 0;
// Number of byte to send within the data array
static   int Size = 0;
// Number of bits/byte or bits/integer
static   byte NumberOfBits = 8;
// State = true (Instruction); State = false (Data)
static   boolean State = true;
// For Xilinc device this variable always false
static   boolean Update = false;
// For Instruction header and trailer
static   byte HIR = 0 , TIR = 0 ;
// For Data header and trailer
static   byte HDR = 0 , TDR = 0;
// For Instruction header and trailer bit value
static   byte HeaderBitInstVal = 1, TrailerBitInstVal = 1;
// For Data header and trailer bit value
static   byte HeaderBitDatVal = 0, TrailerBitDatVal = 0;
static   int Key;
static   byte[] myData = new byte[4096];
static   String line;
static   RandomAccessFile SVFFile;
static   File mySVF ;
public static int ProcessSVFLine()
{
int  loop;
int OBracket = 0, CBracket = 0 ;
int myKey = 0x0;
StringBuffer buffer;
byte myAdd = (byte)0x0;
// Check the size in bits
myKey = Integer.parseInt(line.substring(line.indexOf(' ')+1,line.indexOf(' ',line.indexOf(' ')+1)));
if (myKey != 0)  // myKey != 0
{
// Find value of data in byte format
OBracket = line.indexOf('(');
if ( myKey/8 > line.length())
{
// Copy data string to buffer starting from open bracket to
// end of data line
buffer = new StringBuffer(line.substring(OBracket+1,line.length()));
// Get another line of data and append to buffer
try
{
line = SVFFile.readLine();
while(line != null)
{
	 // Find close bracket
	 CBracket = line.indexOf(')',0);
	 if ( CBracket < 0) //Can not find close bracket
	 {
		buffer.append(line.substring(0,line.length()));
		line = SVFFile.readLine();
	 }
	 else // Find close bracket
	 {
		 buffer.append(line.substring(0,CBracket));
		 line = null;
	 }
}
loop = 0;
// Store data into array to send
for (int x = buffer.length(); x > 0; x--)
{
myData[loop] =(byte) Integer.parseInt((buffer.toString()).substring(x-2,x),16);
loop++; x--; } } catch(IOException a) { System.out.println("Cannot read data "+ a); } } else { // Line of data is within one line."); CBracket = line.indexOf(')',OBracket+1); if (Key <= 3 || Key == 6) // Process header & trailer { if (Key != 6) { // determine value of header and trailer if(Integer.parseInt(line.substring(OBracket+1,CBracket).substring(0,2),16)>0) myAdd = (byte)0x01; else myAdd = (byte)0x00; } } else // Process SIR & SDR { loop = 0; for (int s = CBracket - (OBracket+1); s >0 ; s--) { myData[loop] =(byte) Integer.parseInt((line.substring(OBracket+1,CBracket)).substring(s-2,s),16);
loop++; s--; } } } } switch(Key) { case 0: //System.out.println("TIR & TrailerBitInstVal "); TIR = (byte)myKey; TrailerBitInstVal = myAdd; break; case 1: //System.out.println("HIR & HeaderBitInstVal "); HIR = (byte)myKey; HeaderBitInstVal = myAdd; break; case 2: //System.out.println("TDR & TrailerBitDatVal "); TDR = (byte)myKey; TrailerBitDatVal = myAdd; break; case 3: //System.out.println("HDR & HeaderBitDatVal "); HDR = (byte)myKey; HeaderBitDatVal = myAdd; break; case 4: case 5: Size = myKey; break; default: System.out.println("Invalid opcode."); return 0; } return 1; } public static void main(String[] args) { // The key words of the SVF file include: // TRST OFF: Ignore // ENDIR IDLE: Ignore // ENDDR IDLE: Ignore // STATE RESET IDLE: Ignore // TIR 5 TDI (1f): Key word = 0, length, pin, value(Instruction // trailer) // HIR 5 TDI (1f): Key word = 1, length, pin, value(Instruction // header) // TDR 5 TDI (00): Key word = 2, length, pin, value(Data trailer) // HDR 5 TDI (00): Key word = 3, length, pin, value(Data header) // SIR 13 TDI (1fff)): Key word = 4, length, pin, // value(Instruction) // SDR 32 TDI (00000000)): Key word = 5, length, pin, value(Data) // RUNTEST 110000 TCK: Key word = 0, clock pulse, pin (Run clock) /* // Command send format for Instruction. myJtag.sendNrcv(Data,Offset,Size,(byte)NumberOfBits,State,Update, (byte)HIR,(byte)HeaderBitInstVal,(byte)TIR,(byte)TrailerBitInstVal); // Command send format for Data myJtag.sendNrcv(Data,Offset,Size,(byte)NumberOfBits,State,Update, (byte)HDR,(byte)HeaderBitDatVal,(byte)TDR,(byte)TrailerBitDatVal); */ myJtag = new jtag(); if(args.length != 0) { for (int x = 0; x < args.length ; x++) { mySVF = new File(args[x]); if (mySVF.exists()) { if (mySVF.canRead()) { try { SVFFile= new RandomAccessFile(mySVF.getName(), "r"); // Process one line at a time and set all variables while((line = SVFFile.readLine()) != null) { System.out.println(line); if(line.regionMatches(false,0,"TIR",0,3)) Key = 0; else if(line.regionMatches(false,0,"HIR",0,3)) Key = 1; else if(line.regionMatches(false,0,"TDR",0,3)) Key = 2; else if(line.regionMatches(false,0,"HDR",0,3)) Key = 3; else if(line.regionMatches(false,0,"SIR",0,3)) Key = 4; else if(line.regionMatches(false,0,"SDR",0,3)) Key = 5; else if(line.regionMatches(false,0,"RUNTEST",0,7)) Key = 6; else if(line.regionMatches(false,0,"STATE",0,5)) Key = 7; else { Key = 8; //System.out.println(line); } switch(Key) { case 0: // TIR if (ProcessSVFLine()==0) System.out.println("Fail to fetch TIR and TrailerBitInstVal."); break; case 1: // HIR if (ProcessSVFLine()==0) System.out.println("Fail to fetch HIR and HeaderBitInstVal."); break; case 2: // TDR if (ProcessSVFLine()==0) System.out.println("Fail to fetch TDR and TrailerBitDatVal."); break; case 3: // HDR if (ProcessSVFLine()==0) System.out.println("Fail to fetch THR and HeaderBitDatVal."); break; case 4: // SIR State = true; if (ProcessSVFLine()==1) myJtag.sendNrcv(myData,Offset,Size,(byte)NumberOfBits,State,Update, (byte)HIR,(byte)HeaderBitInstVal,(byte)TIR,(byte)TrailerBitInstVal); else System.out.println("Fail to process ProcessSVFLine."); break; case 5: // SDR State = false; if (ProcessSVFLine()==1) { // Users need to retrieve read data from byte array if needed. myJtag.sendNrcv(myData,Offset,Size,(byte)NumberOfBits,State,Update, (byte)HDR,(byte)HeaderBitDatVal,(byte)TDR,(byte)TrailerBitDatVal); } else System.out.println("Fail to process ProcessSVFLine."); break; case 6: System.out.println("Run clock"); Size = Integer.parseInt(line.substring
(line.indexOf(' ')+1,line.indexOf(' ',line.indexOf(' ')+1))) ; myJtag.waitState((Size/1000)+1); break; case 7: System.out.println("Initialize TAP controller."); myJtag.initialize(); myJtag.initialize(); myJtag.initialize(); break; default:System.out.println("Ignore key word."); break; } } } catch(IOException a) { System.out.println("Cannot create random file "+ a); } } else System.out.println(args[x]+" file cannot be read"); } else System.out.println(args[x]+" file does not exist"); } // Process SVF file } else System.out.println("SVF file is not specified in parameter"); } }
附录C
如何扩展样例SVF文件,使之能工作于级连器件中。

附录A和B给出了如何操作单独或单一的器件。现实中,用户需要对级连到一起的许多Xilinx器件操作。例如,我们有一个串接到一起的Xilinx器件链,如下图所示:

图3.
图3.

按照以下步骤对链中的器件B进行操作:
第1步:按以上所述为单一器件B生成SVF文件。
第2步:从BSDL文件中收集关于链中所有其它Xilinx器件的指令长度属性、指令操作码属性等数据。更多信息请访问网站https://www.xilinx.com/support/documentation/application_notes/xapp503.pdf
第3步:编辑SVF文件并修改相应的TIR、HIR、TDR和HDR的值。假设器件A的IR长度为5位,器件B的IR长度为6位,器件C的IR长度为7位。如果我们想操作器件B,那么我们需要对SVF中TIR、HIR、TDR和HDR的值进行替换,如以下所示:
TIR 5 TDI (1f) SMASK (1f) ;
HIR 7 TDI (7f) SMASK (7f) ;
HDR 1 TDI (00) SMASK (01) ;
TDR 1 TDI (00) SMASK (01) ;
The same procedures to work with device A with step 3:
TIR 0 ;
HIR 13 TDI (1fff) SMASK (1fff) ;
HDR 2 TDI (00) SMASK (02) ;
TDR 0 ;
The same procedures to work with device C with step 3:
TIR 11 TDI (7ff) SMASK (7ff) ;
HIR 0 ;
HDR 0 ;
TDR 2 TDI (00) SMASK (02) ;

下一步
EE-Mail 订阅EE-Mail,接收关于您感兴趣的新文档的自动通知。
© , Maxim Integrated Products, Inc.
The content on this webpage is protected by copyright laws of the United States and of foreign countries. For requests to copy this content, contact us.
APP 3339:
应用笔记 3339,AN3339, AN 3339, APP3339, Appnote3339, Appnote 3339