摘要:本應(yīng)用筆記闡述了如何利用MxTNI? JTAG庫以及串行向量格式(SVF)文件來編程Xilinx? PROM器件。假定讀者已經(jīng)對JTAG和可編程邏輯器件有了一定認(rèn)識。
介紹
Maxim微型網(wǎng)絡(luò)接口(MxTNI)是Dallas Semiconductor (Maxim Integrated的全資子公司)開發(fā)的一個平臺。它包含了一套小型卻功能強(qiáng)大的芯片組以及Java?可編程虛擬機(jī)。芯片組具有處理、控制、器件級通信和網(wǎng)絡(luò)互連的能力。為了和任何JTAG器件通信,TINIs400適配板在J21端具有4引腳JTAG輸出。 這些引腳將直接連到JTAG器件上標(biāo)準(zhǔn)JTAG引腳TDI、TDO、TMS和TCK。
在系統(tǒng)編程PROM可以進(jìn)行單獨(dú)編程,或者級連編程。鏈中的所有器件共享TCK和TMS信號。MxTNI的TDI信號接到邊界掃描鏈中第一個器件的TDI輸入端。第一個器件的TDO信號接到鏈中第二個器件的TDI輸入上,如此連接下去。鏈中的最后一個器件的TDO輸出接到MxTNI的TDO引腳上,見圖1所示。
?
圖1. 所有JTAG操作都通過器件的測試訪問端口進(jìn)行控制
所有JTAG操作都是由器件的測試訪問端口(TAP)控制的。TAP包括四個信號:TMS、TDI、TDO和TCK。 這些信號通過TAP控制器,即16狀態(tài)有限狀態(tài)機(jī)與器件相互作用。JTAG的TMS信號控制狀態(tài)間的轉(zhuǎn)換。指令和數(shù)據(jù)由TDI引腳移入器件,并由TDO引腳移出。TDI和TDO信號的所有狀態(tài)轉(zhuǎn)換和行為都與TCK同步。見圖2。
?
圖2
所有JTAG操作都是將數(shù)據(jù)移入或移出JTAG指令和數(shù)據(jù)寄存器。TAP控制器可對所有這些寄存器直接訪問。有兩類JTAG寄存器:指令寄存器(IR)和數(shù)據(jù)寄存器(DR)。訪問IR通過移位-IR (Shift-IR)狀態(tài)實現(xiàn),而訪問DR通過移位-DR (Shift-IR)狀態(tài)實現(xiàn)。IR長度通常是大于2位的任意長度。除了由IEEE? Std. 1149.1定義的BYPASS指令為全1以外,生產(chǎn)商定義所有其它的指令位碼。
在本應(yīng)用筆記中,JAVA樣例代碼將解釋說明串行向量格式(SVF)文件來進(jìn)行編程。這里所用的SVF是描述高層IEEE 1149.1 (JTAG)總線操作的語法規(guī)范。JTAG設(shè)備和軟件提供商已經(jīng)將SVF作為標(biāo)準(zhǔn)用于數(shù)據(jù)交換。SVF以緊湊和可移植的形式描述JTAG鏈操作。SVF文件通過描述需要移入器件鏈的信息,記錄JTAG操作。通過Xilinx iMPACT (詳細(xì)信息見下面)軟件,將JTAG操作記錄在SVF文件中。SVF文件寫成ASCII文本形式,因此可以在任何文本編輯器中人工讀、修改和寫?!霸S多第三方編程工具使用SVF文件作為輸入,這樣利用包含在SVF文件中的信息可以對JTAG鏈中的Xilinx器件編程?!?/p>
JTAG庫簡要說明
所開發(fā)的JTAG類庫可幫助用戶使用MxTNI與JTAG器件進(jìn)行通信。一個可能的應(yīng)用是:從遙遠(yuǎn)的位置對可編程邏輯進(jìn)行動態(tài)和在系統(tǒng)更新。用戶能夠?qū)AP控制器初始化到初始狀態(tài)、瀏覽16個狀態(tài)、獲得或設(shè)置TAP狀態(tài)、產(chǎn)生時鐘信號、發(fā)送命令和數(shù)據(jù)等等。以下為JTAG類方法的簡要說明:
public jtag(): 加載jtag庫。
public String getVersion(): 返回jtag類的版本。
public int runClock( int numticks ): 以numticks指定的數(shù)量運(yùn)行時鐘。
public byte initialize(): 先將TMS置高達(dá)五個TCK時鐘脈沖,然后TMS置低1個時鐘并進(jìn)入缺省狀態(tài)Run-Test-Idle。
public byte setState( byte aState ): 將目標(biāo)狀態(tài)設(shè)置為aState指定的狀態(tài)。
public byte getState(): 返回目標(biāo)狀態(tài)。
public byte scanState( byte state ): 將TAP控制器的狀態(tài)機(jī)轉(zhuǎn)換到參數(shù)state指定的狀態(tài)。
public String displayState(byte state): 顯示TAP控制器的狀態(tài)。
public byte waitState( int msecs ): 進(jìn)程延時一定毫秒數(shù)。
public byte getTDO(): 獲得引腳TDO的當(dāng)前狀態(tài)。
public void setTDI(byte logic): 引腳TDI設(shè)定為指定的邏輯狀態(tài)。
public byte getTDI(): 獲得引腳TDI的當(dāng)前狀態(tài)。
public void setTMS(byte logic): s引腳TMS設(shè)定為指定的邏輯狀態(tài)。
public byte getTMS(): 獲得引腳TMS的當(dāng)前狀態(tài)。
public void setTCK(byte logic): 引腳TCK設(shè)定為指定的邏輯狀態(tài)。
public byte getTCK(): 獲得引腳TCK的當(dāng)前狀態(tài)。
public byte sendNrcv(byte[] data, int offset, int size, byte numberOfBits, boolean state, boolean update, byte extraHeaderClock, byte HeaderBitVal,byte extraTrailerClock, byte TrailerBitVal): 發(fā)送數(shù)據(jù)字節(jié)數(shù)組,并接收返回的字節(jié)數(shù)組。
public byte sendNrcv(int[] data, int offset, int size, byte numberOfBits, boolean state, boolean update,byte extraHeaderClock, byte HeaderBitVal,byte extraTrailerClock, byte TrailerBitVal): 發(fā)送數(shù)據(jù)整形數(shù)組,并接收返回的整形數(shù)組。
關(guān)于JTAG類的更多詳細(xì)信息,請訪問 。
硬件和軟件需求
以下為所需要的硬件和軟件:
TINI400評估板,并配置有MxTNI OS 1.12或更高版本(見 https://www.maximintegrated.com/cn/app-notes/index.mvp/id/612 )。
JTAG器件(可編程邏輯)。
器件鏈中JTAG器件模型的SVF文件。關(guān)于SVF文件的更多信息,請查閱 。
MxTNI JTAG庫。關(guān)于JTAG類的更多信息請訪問 。
編程步驟
第1步: 將MxTNI板的4個JTAG引腳與JTAG器件的4個JTAG引腳相連。
第2步: 遵循SVF文件的命令并使用JTAG庫編寫JAVA應(yīng)用程序,來對JTAG器件進(jìn)行編程,編譯后加載到MxTNI。
(附錄A: 一個樣例Idcode.svf文件,實現(xiàn)從單獨(dú)的XC18V02 Xilinx器件讀取IDCODE。)
(附錄B: 樣例AppJtag.java程序,將SVF文件作為輸入并產(chǎn)生JTAG信號來讀取IDCODE。該樣例程序是用來處理單獨(dú)器件的(對于級連器件的詳細(xì)信息見附錄C)。)
(附錄C: 展示了由已有的SVF文件編程級連器件的步驟。)
第3步: 運(yùn)行JAVA程序。可執(zhí)行AppJtag.tini將加載到MxTNI板。在MxTNI提示符下錄入“java AppJtag.tini Idcode.svf”來運(yùn)行程序。程序?qū)a(chǎn)生JTAG信號與JTAG器件進(jìn)行通信。注意:
1、生成的編程JTAG器件SVF文件應(yīng)該與器件鏈中設(shè)計的確切模型一致。
2、所有操作碼,例如編程JTAG器件的READ、WRITE、ERASE及其它命令等,都是由生產(chǎn)商定義的。SVF文件應(yīng)該包含用戶需要的所有操作碼。
示例
以下示例說明了如何利用JTAG庫從Xilinx JTAG器件XC18V02中讀取Idcode。完整的樣例代碼,請查閱附錄B。
1、生成器件模型的SVF文件:
使用Xilinx WEB START來生成SVF文件。
執(zhí)行iMPACT并選擇單選按鈕“Prepare Configuration Files”選項,然后點(diǎn)擊next。選擇單選按鈕“Boundary Scan file”并點(diǎn)擊next。選擇“SVF File”然后點(diǎn)擊finish。
在對話框中錄入SVF文件名,例如example,并點(diǎn)擊OK。
選擇要加載的name_of_mcs_file.mcs文件,并從列表中選擇PROM器件(XC18V02_vq44)。
XC18V02已加到模型中。
點(diǎn)擊我們要編程的XC18V02器件型號。器件將為高亮顯示。
點(diǎn)擊鼠標(biāo)右鍵,并選擇編程選項。勾選“Get Idcode”。
在模型外點(diǎn)擊鼠標(biāo)以取消高亮顯示器件,右擊并選擇option以關(guān)閉SVF。這時就生成了模型的SVF文件。
讀取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發(fā)送命令。
SVF規(guī)范提供了四個全局填充指令:頭指令寄存器(HIR)、尾部指令寄存器(TIR)、頭數(shù)據(jù)寄存器(HDR)和尾部數(shù)據(jù)寄存器(TDR)。這些全局命令規(guī)定了移位操作的開始和結(jié)尾處要填充的位數(shù),從而解決旁路器件問題,并為SVF文件壓縮提供了一種簡單的方法。一旦指定,這些位會出現(xiàn)在SIR或者SDR命令的每一組比特位的前面或者后面。
以下兩個示例說明如何把SVF命令解釋為JTAG庫命令。
示例1: 帶有全局填充指令的SVF語法結(jié)構(gòu)
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語法結(jié)構(gòu)
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);
}
結(jié)論
由提供的SVF文件來編程Xilinx PROM器件是非常簡單的。但是,如果用戶能夠正確分析SVF文件并理解如何確定對器件鏈中哪個器件進(jìn)行編程,會更有好處。知道了這些信息,編程者能夠更加高效地使用JTAG庫。軟件小組要對遙遠(yuǎn)位置的Xilinx JTAG器件進(jìn)行編程,已有實際應(yīng)用。利用開發(fā)包中的嵌入式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
讀取單獨(dú)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
如何擴(kuò)展樣例SVF文件,使之能工作于級連器件中。
附錄A和B給出了如何操作單獨(dú)或單一的器件?,F(xiàn)實中,用戶需要對級連到一起的許多Xilinx器件操作。例如,我們有一個串接到一起的Xilinx器件鏈,如下圖所示:
?
圖3.
按照以下步驟對鏈中的器件B進(jìn)行操作:
第1步:按以上所述為單一器件B生成SVF文件。
第2步:從BSDL文件中收集關(guān)于鏈中所有其它Xilinx器件的指令長度屬性、指令操作碼屬性等數(shù)據(jù)。更多信息請訪問網(wǎng)站 。
第3步:編輯SVF文件并修改相應(yīng)的TIR、HIR、TDR和HDR的值。假設(shè)器件A的IR長度為5位,器件B的IR長度為6位,器件C的IR長度為7位。如果我們想操作器件B,那么我們需要對SVF中TIR、HIR、TDR和HDR的值進(jìn)行替換,如以下所示:
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) ;
評論
查看更多