JTAG,IEEE STD 1149.1, 是FPGA设计中非常常见的接口。JTAG最早的意义之一,是用来检测芯片的管脚,但由于特别适合于在线调试,所以Xilinx FPGA的JTAG,更多的用于配置和调试。关于IEEE的标准,可以参考IEEE 1149.1的文档。这里,就简单聊聊JTAG的一些内容。
首先,JTAG接口有几根线。
7根: TCK TMS TDI TDO Vcc GND RESET
TCK,时钟信号,TMS,状态控制,最重要的两个信号。单个芯片感受不深,多个芯片串接的时候TCK和TMS的扇出会很大,对PCB设计有要求。
TDI,数据输入,TDO,数据输出。方向是从芯片角度说。从控制看,需要控制TDI的发送数据,抓取TDO的接收数据。
电源和地,算是硬件设计,操作时不用考虑。不过请注意,这里的电源不是供电电源,而是参考电压。
RESET要单独说一说。因为大部分的JTAG接口,都木有这个RESET。先看下面这张图
JTAG TAP状态机是一个摩尔状态机(摩尔和米利状态机的区别,请自行查看)。从状态机中可以看到,在任意状态下,TMS持续5个TCK,状态机就一定会回到复位,所以管脚上的复位确实不是必须的。
iMPACT可以控制这个JTAG TAP状态机,不过需要一个bit一个bit来处理,有点麻烦。另外,需要Xilinx原厂下载器。
Xilinx所有的FPGA都有一个JTAG可以直接访问的寄存器,IDCODE。下面用这个寄存器举例子,来说明JTAG TAP状态机的运行。
准备工作: 通过iMPACT或者手册,查询到Nexys 4使用的是A7 100T的IDCODE是 3931093, IR Length是 6, IDCODE的命令是0x09。
首先,保证出发点是Test-logic-Reset,然后通过控制TMS把状态机控制到Shift_IR,然后串行输入IDCODE的指令,6bit,0x09,即为001001。发送时从最低位发送。
JTAG TAP状态机可以算是一个通信的协议中最底层的部分。利用这个状态机,可以只使用4根线进行主从模式的双向通信。
当然,为了用起来JTAG,仅仅有一个TAP状态机是远远不够的,后面会陆续讲到JTAG接口涉及的其它部分。
以最常见的Xilinx FPGA平台为例,一般是一台装有iMPACT软件的PC端通过一根USB Cable连接到开发板上。Cable的一端使用USB接口,与PC相连;另一端为JTAG接口,与开发板相连。
不讨论USB驱动、传输及操作系统的内容,不讨论Cable的工作细节。那么整个步骤就是,iMPACT软件发出一些指令,传递到Cable中去;Cable接收到指令后,运行TAP状态机,把适当的数据(指令数据和传输的数据)通过JTAG的四根通信接口传递到FPGA中去,并进行读取操作。
可以看到,上次介绍的JTAG TAP状态机在其中起到的关键作用,有连接的关系,又有隔离的意思。
这就有两个问题,如何控制软件往支持JTAG的cable发数据,和FPGA收到的数据是什么。
具体说,就是用户发出什么样的指令,让软件发出信息给cable,然后cable又发出什么样的信息给FPGA,FPGA会执行读取IDCODE的操作。
在PC端的操作,是JTAG标准的一部分,叫SVF(Serial Vector Format)。编写SVF命令,然后任意一款支持JTAG的工具都可以发出正确的JTAG信号给FPGA芯片。
这就像书写C语言或者HDL语言一样,只要书写正确,就能实现正确的功能,至于是软件功能还是硬件网表,由于已经是非常成熟的了,可以不用非常在意。JTAG已经成为IEEE标准,所以SVF如何翻译成底层信号,已经Cable收到怎么样的数据来控制TAP状态机,已经标准化,不用关心这个细节。
而另一端,FPGA收到的是什么数据,这个取决于FPGA本身寄存器的定义。或者成为Boundary-Scan Instructions.
到这里 JTAG整个链接,分为了两部分。软件操作命令SVF和硬件指令寄存器。 以后会对这两部分分别展开描述。
会先对JTAG硬件指令寄存器进行介绍,比如介绍IDCODE指令。然后在介绍SVF,这样,有条件的就可以书写SVF然后实际测试下了。
可以看到,指令寄存器和TAP状态机共同决定JTAG的操作。
TAP分为DR和IR两部分,DR即为数据寄存器,IR是指令寄存器。一个完整的命令,需要同时用到IR和DR。
比如读取IDCODE这一步,首先要到IR中,输入IDCODE的命令,然后在到DR寄存器中,读取相关信息。
所以,每一个JTAG指令,都是有一个同过IR访问的指令和一个可以访问的寄存器构成。而由于JTAG是是单向的(固定从TDI输入,TDO输出),所以每一个寄存器都是单向的,即,要么只读,要么只写。
JTAG协议中,常用的寄存器有SAMPLE、INTEST、EXTEST、BYPASS等, Xilinx 7系列的FPGA中去掉了INTEST, 加入了其他一些寄存器,如IDCODE。详细的寄存器列表可以查阅相关文档。
从这个表中可以看到 IDCODE的指令是 001001,即0x09。之前的例子中,输入的数据也是0x09。
回顾之前的操作,要读取IDCODE值,首先需要对IR进行操作,输入0x09这个指令。然后,再通过TAP状态机转移到DR寄存器,由于IDCODE是只读,所以TDI输入什么数据不重要,抓取TDO的输出即是需要的数据。
JTAG是可以串行级联的,那么在JTAG链中是如何访问某一个器件呢。比如,JTAG链路上有三个器件,如下图所示。
假设三个器件都是7系列的FPGA,则IR Length都为6,现在要访问第二个器件的IDCODE。
由于操作是针对第二个器件,则第一个和第三个都需要设置为bypass模式,那么所需要的命令是:
Device 0 : 0x3F
Device 1 : 0x09
Device 2 : 0x3F
把这三条6bit的数据连接在一起,就是 111111_001001_111111,即0x3F27F。
把这个指令从TDI发送出去,第一个和第三个器件收到BYPASS命令,第二个收到IDCODE命令。
然后切换到DR,抓取TDO的输出。
这一需要说明一下,IR Length可能不同,但是BYPASS寄存器是固定的。不管IR Length是多长,全部是1,则是BYPASS指令,而所有的BYPASS指令,都为1位寄存器。
所以,需要的数据是32bit的IDCODE,前后各加一位bypass的数据,即为输出数据,根据这个数据来提取相对应的数据即可。
这就是JTAG的指令寄存器相关内容。其他寄存器的操作和IDCODE、BYPASS寄存器是一样的。只要知道有哪些寄存器,就可以通过JTAG来进行发送操作命令。
那么,下一个问题是,软件是这么知道这些寄存器的信息的?
上一次讲到JTAG的指令,最后列举了JTAG链上多个器件的例子。从例子中可以看到,JTAG一次只能访问一个器件,链上的其他器件需要设为bypass模式。
同时,JTAG对需要访问的器件,也需要了解一些信息,比如IR寄存器的长度,即IR Length,指令内容和相对应的寄存器长度,比如IDCODE需要知道为0x09,对应的寄存器长度为32位。
JTAG的控制软件,如Xilinx ISE中的iMPACT,是如何得知芯片的具体信息呢?
Boundary Scan Description Language (BSDL)文件,属于IEEE 1149标准的一部分。该文件用VHDL写成,里面包含器件中JTAG的相关信息。这个文件是存储在PC上。当安装ISE或者Vivado的时候,会附带安装上这些文件。
Xilinx每一款FPGA器件都会配有一个BSDL文件,如果没有该文件,就无法使用JTAG。
比如,ISE的最后一个版本 14.7发布的时候,Artix-7的最后两款芯片 35T和50T还没有发布。所以默认的ISE 14.7是无法配置这两个芯片的。但是,可以通过手动添加文件来让ISE 支持35T和50T,在添加的文件中,就有BDSL文件。
下面的连接时Nexys-4上的XC7A100T-1CSG324C芯片的BSDL文件。
http://pan.baidu.com/s/1i3nEISd
如果JTAG链上串联有其他器件,比如非Xilinx的芯片,对iMPACT工具来说,需要知道这个芯片的IR Length。得知这个值后,输入全零即为该芯片的BYPASS指令,这样就就可以继续访问芯片中其他可以访问的FPGA芯片了。
这个BSDL文件可以算是VHDL小众的应用,不过,如果认为JTAG很重要,那么VHDL在FPGA设计中也就连带有相当重要的作用了。
SVF的全称是Serial Vector Format,是IEEE 1149.1的一部分。SVF主要用来控制JTAG收发数据。由于JTAG是串行的,所以收发是一起的。
使用SVF可以控制JTAG的发送端,而不用考虑JTAG TAP状态机的细节。
通过SVF,就可以控制JTAG来传输数据。
目前,Vivado 2015.1没有发布,所以SVF的操作只能通过iMPACT来实现。
这一篇主要讲解SVF文件的生成。
iMPACT生成SVF的方法,其实类似于捕获操作。下面用读取FPGA的IDCODE来介绍如何生成SVF。
首先,启动iMPACT,并点击Boundary Scan。
然后,在右边的区域,鼠标右键点击,弹出菜单,然后点击Initialize Chain。
iMPACT会扫描JTAG链,扫描到Nexys-4上的A7后会如下图所示
看到100t后,在iMPACT的菜单上,Output,然后点击“SVF File"下的“Create SVF File”,随后会要求选择路径和填写文件名,便于保存该文件。
从这一步开始,所有的图形化界面操作会被捕获,并被记录为SVF文件。
示例的操作很简单,如下图所示点击“Get Device ID”即可,iMPACT不会去读取IDCODE,而是记录下这个操作。
最后一步,停止SVF的记录,如下图所示
SVF文件会被填写好。
生成SVF的步骤就是这样,在开始和停止中间的操作会被记录下来。可以读取IDCODE或者下载bit文件,甚至做间接编程。
需要注意的是,这个示例的步骤开始需要连接到板子上,由于SVF的生成并不需要真实的操作,所以这一步也可以取消。在初始化Chain的那一步,选择添加Xilinx Device
然后添加一个正确器件的bit文件或者BSDL文件即可。
有兴趣可以尝试一下。
生成的SVF文件共享在百度云上
http://pan.baidu.com/s/1i35qdST
联系客服