49人参与 • 2024-08-01 • fpga开发
1、jtag是什么?
jtag是20世纪80年代开发的ieee标准(1149.1),用来解决电路板的生产制造检修问题。现在jtag还可以用来烧程序、调试以及检测端口状态。本文主要介绍jtag的基本功能,边界扫描。
1.1边界扫描
如图1所示,在一个电路板上有两个芯片元件,一个cpu和fpga。
图1
每个芯片都会有很多引脚,那么芯片之间的互联就会有很多连线,图2示意图仅仅画了4条连接线。
图2
正常情况下,对于芯片厂商,一次制作成千上万个pcb板子,每个班子上都有许许多多连接线,厂家需要如何保证每根芯片连接线都是正常的呢?这么大的工作量也不可能通过手工来每一根线进行检测。因此jtag就应运而生了。
图3
jtag可以控制芯片的每个引脚,图3中,我们可以通过jtag使得所有的cpu引脚发送数据,而所有的fpga引脚接收数据,然后根据fpga中是否收到准确的数据来判断所有的芯片连接是否正常。
实际上jtag的连接包括4根信号线,分别是tdi、tdo、tms和tck。从电脑主机的角度来看,tdi、tms、tck为输出,tdo为输入,如果从待测试的芯片角度来看则相反。
图4
jtag的四根信号线有特定的连接方式,如图5所示,tms和tck是并联在所有待测芯片上的。
图5
tdi和tdo信号线则是串联在一起形成一个闭环链条。在jtag的技术手册中,这种方式也叫jtag链。
图6
因此,每个jtag链上的芯片都会有四根线连接,其中三个输入,一个输出。在技术手册中,还会有一个可选的信号线trst作为第五根信号线。一般而言,jtag的四个引脚都是专用引脚。
现在所有的jtag应用越来越普遍,基本上所有多引脚的芯片都会包含jtag边界扫描功能。此外正如我们开头所说,cpu和fpga厂商还用jtag接口进行调试,对于可编程硬件fpga和cpld,还可以用jtag接口继续配置和烧录程序。
2、jtag如何起作用?
上一章我们知道了jtag是如何连接芯片,现在学习具体工作原理以及如何通过pc端来控制器运行。
2.1pc控制jtag
一般我们用jtag连接线来连接pc和jtag端口,电脑端口有并行端口(也叫打印机端口db25)、usb端口以及网线端口。对于数据量不大的情况下推荐并行端口,操作简单。对于大数据量推荐usb端口和网口,其速度快但是操作复杂一些。
图7 并行端口db25
2.2、并行端口
电脑主机的并行端口12根线为输出,5根线为输入。对于jtag而言,只用到了3个输出和一个输入(从pc角度来看输入输出)。因此,中间需要用到一些缓存器,如赛灵思的parallel-iii cable。
从软件代码的角度来看,并行端口由于简单是最理想的jtag端口。例如,阿尔特拉的byteblaster jtag接口用c语言改变tck信号代码如下:
#define lpt_addr 0x378
#define tck 0x01
void toggle_tck()
{
outport(lpt_addr, 0);
outport(lpt_addr, tck);
outport(lpt_addr, 0);
}
2.3、jtag tap控制器
pc和芯片之间的jtag连接方式如图6,下面介绍这四根信号线分别代表什么意思。
tck
tck是jtag的时钟信号,另外三个信号tdi、tdo、tms都是跟该时钟信号同步的。一般其他三根信号都是在tck时钟的上升沿发生改变或者状态的切换。
tms
在每个芯片的内部都有jtag tap控制器,图6中有两个cpu和fpga两个芯片,那么就有两个tap控制器。一般我们在数据手册上看到的状态控制器就是这个,它有16个状态,如图8所示。tms就是个控制tap控制器的信号,根据tms的高低电平变化,tap控制器进入这16个状态中的一种,又因为同一个pcb板子上tms是并联所有芯片 ,因此所有芯片都会处于同一状态。
图8
上图中每个状态旁边的0和1代表的是tms的低、高电平。比如如果tap状态控制器处于select dr-scan状态,且tms为0,那么当tck时钟信号切换时,tap的状态就会变化下面的capture-dr。
这里再强调一遍,要想jtag正常工作,所有的链上的tap控制器必须处于同一状态。pcb板上电后,是如何保证所有芯片的tap处于同一状态呢?仔细观察图8,不管tap在哪个状态,如果tms在5个时钟周期内都保持1,那么tap都会变成test-logic-reset状态,这便是用来同步tap状态的方法。
来看下面的代码,如何将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
现在我们已经知道了如何切换tap状态了,下面介绍jtag最重要的两个状态shift-dr和shift-ir。
图9
shift-dr和shift-ir必须结合tdi和tdo信号线才能起作用,首先介绍shift-dr。
每个芯片的tap控制器中都有一个ir寄存器,也叫做指令寄存器。你可以把相关指令写入这个寄存器,然后tap控制器会根据ir寄存器的指令进行相关操作。
每个ir寄存器都有一定的长度,我们假设cpu的ir寄存器是5位,fpga的寄存器是10位,那么通过tdi和tdo的信号线连接方式,cpu和fpga的ir寄存器其实是串联的,如图10所示。
图10
我们从pc主机的角度来看,整个链的ir寄存器是15位的,5位cpu和5位fpga。
要想将ir寄存器写入数据,我们需要将tap控制器的状态切换成shift-ir,然后pc通过tdi信号线写入15位数据。前10位数据写入的是fpga的ir寄存器,后5位数据写入的是cpu的ir寄存器。如果pc写入的数据多于15位,那么溢出的数据就会通过tdo信号线再被pc端给接收,只不过延时了15个时钟周期。
例如,我们想吧数值00100写入cpu的ir寄存器,而0000000010写入fpga的ir寄存器,c语言代码如下:
// 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)。那么cpu的ir寄存器可以支持32条jtag指令。实际上,一个cpu可能只会有5~10条指令,剩下的ir寄存器数值都没有用。
同样的对于fpga,它的ir寄存器是10位,那么它可以支持1024条jtag指令(大部分也是没用的)。
但是jtag有几条强制的指令必须都有:
每个芯片的都有ir数值的指令集,从芯片手册上都可以查到。
每个芯片的tap控制器都只有一个ir寄存器,但是会有很多dr寄存器。我们知道ir寄存器数据切换是通过tap的shift-ir状态,类似的,dr寄存器的数据切换也是这样,只不过状态时tap的shift-dr状态。
每一个ir寄存器的数值都会对应一个不同的dr寄存器,在我们的假设中ir寄存器为5位,那么就有32个ir数值,因此就有32个dr寄存器(如果32个ir数值都被当做指令的话)。
2.4、计算jtag链中元件个数
ir寄存器的指令不同芯片有所区别,但是有一个指令是一样的,那就是bypass指令。它的ir寄存器所有位都是1。对于cpu是11111,对于fpga的ir寄存器,其数值是1111111111。在bypass指令模式下,tap控制器对应的dr寄存器是个单触发器,只是将tdi的输入数据延时一个时钟周期然后通过tdo输出。
根据这个特性,我们可以用bypass指令来计算jtag链上有多少个芯片。在此指令下,每个芯片的dr寄存器会延时一个时钟周期,那么我们发送一个数据后,检查延时多少周期收到数据,即可知道jtag链上芯片的数量。
具体实现的c语言代码如下:
// 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 chain\n", nbdevices);
2.5、获得jtag链上芯片的id
大部分的芯片jtag模块都支持idcode指令,这个指令对应的dr寄存器是32位,具体数值代表者不同芯片的id。
不同于bypass指令,incode指令的ir寄存器数值不是标准的,我们可以通过器件手册来查询。还有一种方法,当tao控制器的状态处于test-logic-reset时,它都会将incode数据写入dr寄存器中,我们可以据此读出dr寄存器的内容,c语言代码如下:
// 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 %08x\n", i+1, jtag_read(32));
}
3、边界扫描
本章节讲解jtag的边界扫描。当tap控制器进入“boundary-scan”的状态,其实也就是ir寄存器存入sample指令、extest指令等,此时对应的dr寄存器就是边界扫描寄存器,这个寄存器将每个i/o单元连接在一起并且可以控制每个引脚。
图11
当芯片正常过程当中也是可以进行边界扫描的,例如对正常运行中的fpga进行边界扫描,它可以将每个管脚的状态显示出来。
3.1、sample
现在我们尝试读取管脚的值,对应的ir寄存器的指令是sample。每个芯片的具体指令数值不同,查找数据手册或者芯片的bsdl文件来获取具体的指令。bsdl全称是boundary scan description language,它是硬件描述语言(vhdl)的一个子集。
一个bsdl文件其实就是一个描述边界链的vhdl文件。下面是阿尔特拉的bsdl文件(cyclone ep1c3 in tqfp 100 pins package):
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;
从上面这个文件我们可以知道:
边界扫描寄存器有339位,并不意味着有339个管脚。
每一个管脚都有一个io pad(芯片管脚处理模块),io pad用1~3位寄存器(取决于该管脚是输入、三态输出或是输入输出均可)。当然一些io pad包含的寄存器不一定包含在边界扫描链中。这就解释了为什么这个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位的用途。
例如,处于第4位(其实是位3,从0开始计算的)保存的是管脚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 = %d\n, bsb[3]);
3.2、边界扫描寄存器
下图是阿尔特拉数据手册中tap状态寄存器、ir寄存器、dr寄存器结构图,各层级关系比较一目了然。
图12
从图12中我们可以得出以下信息:
阿尔特拉的bsc全称是booundary scan cell,它可以讲信号施加到管脚,或者获得管脚上的数据和内部逻辑信号。我们jtag测试的数据也是串行输入到bsc单元中,捕获到的数据也是串行从bsc输出,进而判断测试结果。根据我的理解,此处的bsc就是我们上文提到的io pad芯片管脚处理模块。
图13
3.3、jtag还可以做什么?
怎么样,通过本文的讲解是不是对jtag有了基本的认识,欢迎有疑问的同学联系我交流学习,一起进步。
参考资料:
https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/an/an039.pdf
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论