FPGA:JTAG接口
大多數FPGA都支持JTAG。
本文引用地址:http://www.j9360.com/article/202401/454547.htmJTAG 1 - 什么是JTAG?
JTAG 是 1149 年代開發的 IEEE 標準 (1.1980),用于解決電子板制造問題。 如今,它更多地用作編程、調試和探測端口。
但首先,讓我們看看JTAG的原始用途,邊界測試。
邊界測試
這是一個簡單的電子板(也稱為“PCB”,意為“印刷電路板”),帶有兩個 IC(“集成電路”)、一個 CPU 和一個 FPGA。典型的電路板可能有更多的IC。
IC可以有很多引腳。 因此,當然,IC通過許多連接(PCB走線)連接在一起。
我們在這里只展示四個。 但是你可以很容易地在PCB上有幾千個。
現在,如果你構建了一千個板子,每個板子都有幾千個連接,你不可避免地會有一些壞板子。 您如何測試所有這些電路板?您必須確保所有這些連接都正常。 您不能只手動測試所有這些連接。于是JTAG誕生了。
JTAG可以控制(或劫持)所有IC的引腳。 從圖上看,也許JTAG將使所有CPU引腳輸出,所有FPGA引腳輸入。 然后,通過從CPU引腳發送一些數據,并從FPGA引腳讀取值,JTAG可以確保電路板連接正常。
現在JTAG實際上由四個邏輯信號組成,分別命名為TDI、TDO、TMS和TCK。 從PC的角度來看,這是三個輸出和一個輸入。
這四個信號需要以特定的方式連接。 首先,TMS和TCK并聯到所有JTAG IC。
然后TDI和TDO連接起來形成鏈。 在JTAG術語中,您經常聽到“JTAG鏈”一詞,這就是它的由來。
如您所見,每個JTAG兼容IC都有四個用于JTAG的引腳(三個輸入和一個輸出)。 第五個名為TRST的引腳是可選的(JTAG復位)。 JTAG引腳通常是專用的(不共享用于其他目的)。
所有大型IC都使用JTAG進行邊界測試 - 邊界測試是創建JTAG的最初原因。 如今,JTAG的使用已經擴展到允許配置FPGA之類的事情,然后在FPGA內核中使用JTAG進行調試。
JTAG 2 - JTAG的工作原理
現在我們知道了如何將JTAG連接到不同的IC,讓我們詳細了解JTAG是如何工作的,以及如何從PC控制它。
從PC控制JTAG
您可以使用“JTAG電纜”從PC控制JTAG總線。 JTAG電纜只是控制來自PC的四個JTAG信號的一種方式。 JTAG電纜可以連接到PC的并行(打印機)端口,USB端口或以太網端口... 最簡單的是并行端口(不幸的是,僅在較舊的 PC 上可用)。 USB和以太網JTAG電纜也很好。 它們在流式傳輸大量數據時速度更快,但控制起來更復雜,并且對于少量數據的開銷更大(=更慢)。
并行端口
并行端口可以看作是PC的74位輸出,PC的125位輸入。 JTAG只需要一個<>位輸出和一個<>位輸入,所以這沒有問題。 例如,請看一下 Xilinx 并聯 III 電纜的原理圖。 左邊是PC的并行信號,右邊是JTAG連接器,中間是幾個<>HC<>電子緩沖器。
從軟件的角度來看,并行端口是理想的選擇,因為它非常易于控制。
例如,以下C代碼顯示了如何切換Altera ByteBlaster JTAG電纜的TCK信號。
#define lpt_addr 0x378#define TCK 0x01void toggle_TCK()
{
outport(lpt_addr, 0);
outport(lpt_addr, TCK);
outport(lpt_addr, 0);
}
Windows 2000/XP/Vista 的一個小問題是“outport”IO 指令受到限制,但 GiveIO 和 UserPort 是開放 IO 空間的免費通用驅動程序。
JTAG TAP控制器
我們知道PC連接到JTAG總線,如下圖所示:
因此,我們有 4 個信號(TDI、TDO、TMS、TCK)需要處理。
SCl的
TCK是JTAG時鐘信號。 其他JTAG信號(TDI、TDO、TMS)與TCK同步。 因此,TCK 必須切換才能發生任何事情(通常事情發生在 TCK 的上升邊緣)。
TMS技術
每個JTAG IC內部都有一個JTAG TAP控制器。 在上圖中,這意味著 CPU 中有一個 TAP 控制器,FPGA 中有一個 TAP 控制器。
TAP控制器主要是一個具有16個狀態的狀態機。 TMS 是控制 TAP 控制器的信號。 由于TMS并聯到所有JTAG IC,因此所有TAP控制器一起移動(到相同的狀態)。
下面是 TAP 控制器狀態機:
每個箭頭附近的小數字(“0”或“1”)是用于更改狀態的 TMS 的值。 例如,如果TAP控制器處于“選擇DR-Scan”狀態,TMS為“0”,并且TCK切換,則狀態將更改為“Capture-DR”。
為了使JTAG正常工作,JTAG鏈的抽頭控制器必須始終處于相同的狀態。 通電后,它們可能不同步,但有一個技巧。 查看狀態機,請注意,無論您處于什么狀態,如果 TMS 在五個時鐘中保持在“1”,則 TAP 控制器將返回到“Test-Logic-Reset”狀態。 它用于同步 TAP 控制器。
因此,假設我們想在通電后轉到“Shift-IR”:
// first sync everybody to the test-logic-reset state
for(i=0; i<5; i++) JTAG_clock(TMS);
// now that everybody is in a known and identical state, we can move together to another state
// let's go to Shift-IR
JTAG_clock(0);
JTAG_clock(TMS);
JTAG_clock(TMS);
JTAG_clock(0);
JTAG_clock(0);
TDI 和 TDO
現在我們知道了如何更改狀態,我們可以使用兩個最重要的JTAG狀態,即“Shift-DR”和“Shift-IR”。
Shift-DR 和 Shift-IR 與 TDI 和 TDO 生產線結合使用。
讓我們從 Shift-IR 開始。
每個 IC TAP 控制器都有一個寄存器,稱為 IR,即“指令寄存器”。 你在這個寄存器中寫入一個值,該值與你想用JTAG做什么相對應(每個IC都有一個可能的指令列表)。
此外,每個 IC IR 寄存器都有特定的長度。 例如,假設 CPU 的 IR 為 5 位長,FPGA 的 IR 為 10 位長。 IR 寄存器形成一條鏈,通過 TDI 和 TDO 引腳加載。
從 PC 的角度來看,上面的 IR 鏈長 15 位。
要加載 IR 值,PC 必須確保 TAP 控制器處于 Shift-IR 狀態,并通過 TDI 發送 15 位。 一旦移位,前 10 位實際上最終會進入 FPGA IR,最后 5 位最終會進入 CPU IR。 如果 PC 發送的位超過 15 位,它將開始在 TDO 上接收它發送的內容(延遲 15 個時鐘)。
例如,讓我們將 00100 發送到 CPU 的 IR 中,然后0000000010到 FPGA 的 IR 中。
// Because the bits are shifted through in a chain, we must start sending the data for the device that is at the end of the chain
// so we send the 10 FPGA IR bits first
JTAG_clock(0);
JTAG_clock(1);
JTAG_clock(0);
JTAG_clock(0);
JTAG_clock(0);
JTAG_clock(0);
JTAG_clock(0);
JTAG_clock(0);
JTAG_clock(0);
JTAG_clock(0);
// then send the 5 CPU IR bits
JTAG_clock(0);
JTAG_clock(0);
JTAG_clock(1);
JTAG_clock(0);
JTAG_clock(0 | TMS); // last bit needs to have TMS active (to exit shift-IR)
在我們的示例中,CPU 的 IR 長度為 5 位(即可以保存 0 到 31 之間的值)。 這意味著它可以支持多達 32 個 JTAG 指令。 在實踐中,CPU 可能使用 5 到 10 條指令,其余的 IR 值未使用。
FPGA 也是如此,它有一個 10 位長的 IR,可以容納 1024 條指令,其中大部分未使用。
JTAG有一些強制性指令(這些指令的作用將在后面說明):
旁路
EXTEST公司
樣品/預加載
IDCODE(不是強制性的,但經常實現)
要獲取特定 IC 支持的可能 IR 值列表,請查看 IC 的數據表(或 BSDL 文件 - 稍后會詳細介紹)。
DR 寄存器
每個 TAP 控制器只有一個 IR 寄存器,但有多個 DR 寄存器。 DR 寄存器類似于 IR 寄存器(它們的移位方式與 IR 寄存器相同,但使用 Shift-DR 狀態而不是 Shift-IR)。
每個 IR 值選擇不同的 DR 寄存器。 因此,在我們的示例中,CPU 最多可以有 32 個 DR 寄存器(如果實現了所有 IR 指令)。
JTAG 3 - 查詢JTAG鏈
計算JTAG鏈中的器件數量
一個重要的 IR 值是“all-one”值。 對于 CPU 來說,這將是 11111,對于 FPGA,這是1111111111。 此值對應于稱為 BYPASS 的強制性 IR 指令。 在旁路模式下,TAP控制器DR寄存器始終是一個觸發器,除了在輸出到TDO之前將TDI輸入延遲一個時鐘周期外,什么也做不了。
使用這種旁路模式的一種有趣方法是計算JTAG鏈中存在的IC數量。
如果每個JTAG IC將TDI-TDO鏈延遲一個時鐘,我們可以發送一些數據并檢查延遲了多長時間。 這為我們提供了鏈中IC的數量。
下面是一個示例:
// go to reset state
for(i=0; i<5; i++) JTAG_clock(TMS);
// go to Shift-IR
JTAG_clock(0);
JTAG_clock(TMS);
JTAG_clock(TMS);
JTAG_clock(0);
JTAG_clock(0);
// Send plenty of ones into the IR registers
// That makes sure all devices are in BYPASS!
for(i=0; i<999; i++) JTAG_clock(1);
JTAG_clock(1 | TMS); // last bit needs to have TMS active, to exit shift-IR
// we are in Exit1-IR, go to Shift-DR
JTAG_clock(TMS);
JTAG_clock(TMS);
JTAG_clock(0);
JTAG_clock(0);
// Send plenty of zeros into the DR registers to flush them
for(i=0; i<1000; i++) JTAG_clock(0);
// now send ones until we receive one back
for(i=0; i<1000; i++) if(JTAG_clock(1)) break;
nbDevices = i;
printf("There are %d device(s) in the JTAG chainn", nbDevices);
獲取JTAG鏈中器件的ID
大多數JTAG IC都支持IDCODE指令。 在 IDCODE 模式下,DR 寄存器加載了一個 32 位值,該值表示設備 ID。
與 BYPASS 指令不同,IDCODE 的 IR 值不是標準的。 幸運的是,每次TAP控制器進入Test-Logic-Reset時,它都會進入IDCODE模式(并將IDCODE加載到DR中)。
下面是一個示例:
// go to reset state (that loads IDCODE into IR of all the devices)
for(i=0; i<5; i++) JTAG_clock(TMS);
// go to Shift-DR
JTAG_clock(0);
JTAG_clock(TMS);
JTAG_clock(0);
JTAG_clock(0);
// and read the IDCODES
for(i=0; i < nbDevices; i++)
{
printf("IDCODE for device %d is %08Xn", i+1, JTAG_read(32));
}
JTAG 4 - 運行邊界掃描
現在,讓我們讓 TAP 控制器進入邊界掃描模式,其中 DR 鏈通過每個 IO 塊,可以讀取或劫持每個引腳!
即使設備正在運行,也可以使用邊界掃描。 例如,在FPGA上使用JTAG,您可以在FPGA運行時判斷每個引腳的狀態。
樣本
讓我們嘗試讀取引腳的值。 為此,我們使用一個名為SAMPLE的JTAG指令。 每個IC指令代碼列表都不同。 您必須查看 IC 數據表或 IC BSDL 文件才能獲得代碼。
BSDL文件實際上是描述IC邊界鏈的VHDL文件。
以下是 Altera BSDL 文件(TQFP 1 引腳封裝的 Cyclone EP3C100)的有趣部分。
attribute INSTRUCTION_LENGTH of EP1C3T100 : entity is 10;
attribute INSTRUCTION_OPCODE of EP1C3T100 : entity is
"BYPASS (1111111111), "&
"EXTEST (0000000000), "&
"SAMPLE (0000000101), "&
"IDCODE (0000000110), "&
"USERCODE (0000000111), "&
"CLAMP (0000001010), "&
"HIGHZ (0000001011), "&
"CONFIG_IO (0000001101)";
attribute INSTRUCTION_CAPTURE of EP1C3T100 : entity is "0101010101";
attribute IDCODE_REGISTER of EP1C3T100 : entity is
"0000"& --4-bit Version
"0010000010000001"& --16-bit Part Number (hex 2081)
"00001101110"& --11-bit Manufacturer's Identity
"1"; --Mandatory LSB
attribute BOUNDARY_LENGTH of EP1C3T100 : entity is 339;
以下是我們從該設備的 BSDL 中學到的內容:
IR 寄存器的長度(10 位長)。
可能的 IR 指令列表及其 10 位代碼。SAMPLE 的代碼為 0000000101b = 0x005。
部件的 IDCODE(制造商代碼為 00001101110b = 0x6E,即 Altera。Xilinx 本來是 00001001001b = 0x49)。
邊界掃描鏈的長度(339 位長)。
邊界掃描的長度為 339 位。 這并不意味著有 339 個引腳。
每個引腳在IC芯片上使用IO焊盤。 一些 IO 焊盤使用鏈中的一位、兩位或三位(取決于引腳是僅輸入、三態輸出,還是兩者兼而有之)。 有關詳細信息,請參閱本頁底部的鏈接。 此外,有些寄存器對應于可能沒有邊界的IO焊盤(它們存在于IC芯片上,但無法從外部訪問)。 這就解釋了為什么 100 引腳器件可以具有 339 位邊界掃描鏈。
回到BSDL文件,我們也得到這個:
attribute BOUNDARY_REGISTER of EP1C3T100 : entity is
--BSC group 0 for I/O pin 100
"0 (BC_1, IO100, input, X)," &
"1 (BC_1, *, control, 1)," &
"2 (BC_1, IO100, output3, X, 1, 1, Z)," &
--BSC group 1 for I/O pin 99
"3 (BC_1, IO99, input, X)," &
"4 (BC_1, *, control, 1)," &
"5 (BC_1, IO99, output3, X, 4, 1, Z)," &
...
...
...
--BSC group 112 for I/O pin 1
"336 (BC_1, IO1, input, X)," &
"337 (BC_1, *, control, 1)," &
"338 (BC_1, IO1, output3, X, 337, 1, Z)" ;
這列出了鏈的所有 339 位,以及它們的作用。 例如,位 3 是告訴我們引腳 99 的值是多少的位。
讓我們讀取邊界掃描寄存器,并打印引腳 99 的值:
// go to reset state
for(i=0; i<5; i++) JTAG_clock(TMS);
// go to Shift-IR
JTAG_clock(0);
JTAG_clock(TMS);
JTAG_clock(TMS);
JTAG_clock(0);
JTAG_clock(0);
// Assuming that IR is 10 bits long,
// that there is only one device in the chain,
// and that SAMPLE code = 0000000101b
JTAG_clock(1);
JTAG_clock(0);
JTAG_clock(1);
JTAG_clock(0);
JTAG_clock(0);
JTAG_clock(0);
JTAG_clock(0);
JTAG_clock(0);
JTAG_clock(0);
JTAG_clock(0 or TMS); // last bit needs to have TMS active, to exit shift-IR
// we are in Exit1-IR, go to Shift-DR
JTAG_clock(TMS);
JTAG_clock(TMS);
JTAG_clock(0);
JTAG_clock(0);
// read the boundary-scan chain bits in an array called BSB
JTAG_read(BSB, 339);
printf("Status of pin 99 = %dn, BSB[3]);
很簡單,對吧?
使用JTAG做更多事情
JTAG可以劫持引腳。 JTAG指令是EXTEST(“外部測試”)。
JTAG可以執行FPGA配置。例如,請參閱此文件。
JTAG可用作調試端口,例如Altera的SignalTap和Xilinx的ChipScope。
輪到你來實驗了!
評論