当前位置:首页 > 技术学院 > 技术前线
[导读]JTAG是20世纪80年代开发的IEEE标准(1149.1),用来解决电路板的生产制造检修问题。现在JTAG还可以用来烧程序、调试以及检测端口状态。本文主要介绍JTAG的基本功能,边界扫描。

1、JTAG是什么?

JTAG是20世纪80年代开发的IEEE标准(1149.1),用来解决电路板的生产制造检修问题。

现在JTAG还可以用来烧程序、调试以及检测端口状态。本文主要介绍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.1 PC控制JTAG

一般我们用JTAG连接线来连接PC和JTAG端口,电脑端口有并行端口(也叫打印机端口db25)、USB端口以及网线端口。对于数据量不大的情况下推荐并行端口,操作简单。对于大数据量推荐USB端口和网口,其速度快但是操作复杂一些。

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,下面介绍这四根信号线分别代表什么意思。

TCKTCK是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和10位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有几条强制的指令必须都有:

BYPASSEXTESTSAMPLE/PRELOADIDCODE(这个不是强制的,但是非常常见)每个芯片的都有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);

// 将JTAG链置于复位状态

// 根据JTAG标准,通过一系列TMS信号(通常是特定的序列)将JTAG接口置于复位状态

// 这里简单地假设连续5个TMS时钟信号足以实现复位

for(i=0; i<5; i++) JTAG_clock(TMS);

// 从复位状态转移到Shift-IR状态

// Shift-IR状态允许数据被移入到JTAG链上每个设备的指令寄存器(IR)中

// 这里的序列是JTAG标准定义的一部分,用于进入Shift-IR状态

JTAG_clock(0);

JTAG_clock(TMS);

JTAG_clock(TMS);

JTAG_clock(0);

JTAG_clock(0);

// 向IR寄存器发送多个1

// 因为BYPASS指令在大多数JTAG设备中是通过在IR寄存器中设置全1来实现的

// 所以这里通过发送999个1(实际上只需要足够多的1以确保所有设备都接收到BYPASS指令)

// 来确保所有设备都进入BYPASS模式

for(i=0; i<999; i++) JTAG_clock(1);

JTAG_clock(1 | TMS); // 发送最后一个1时,同时激活TMS以退出Shift-IR状态

// 从Exit1-IR状态转移到Shift-DR状态

// Shift-DR状态允许数据被移入到JTAG链上每个设备的数据寄存器(DR)中

// 同样,这里的序列是JTAG标准定义的一部分

JTAG_clock(TMS);

JTAG_clock(TMS);

JTAG_clock(0);

JTAG_clock(0);

// 发送多个0到DR寄存器以清空它们

// 在进入测量模式前,先通过发送一系列0来清空DR寄存器中的任何残留数据

for(i=0; i<1000; i++) JTAG_clock(0);

// 现在发送1,直到接收到返回的1

// 在BYPASS模式下,DR寄存器被简化为一个单触发器,它会将TDI的输入延时一个时钟周期后输出到TDO

// 通过发送一系列1并检查TDO输出,我们可以测量从发送到接收的延时,从而计算出JTAG链上的设备数量

// 当TDO返回1时,循环结束

for(i=0; i<1000; i++) if(JTAG_clock(1)) break;

// i的值现在等于JTAG链上设备的数量(加1,因为包括发送的那个时钟周期)

// 但由于我们是在寻找TDO返回1的时钟周期,所以实际的设备数量应该是i

nbDevices = i;

// 打印JTAG链上的设备数量

printf("There are %d device(s) in the JTAG chain\n", nbDevices);

啰嗦解释一下:

由于BYPASS模式下,每个设备都会将输入数据延时一个时钟周期后输出,因此,我们可以通过发送一个数据位,并测量从发送到接收到该数据位的时间(即时钟周期数),来推断JTAG链上设备的数量。具体做法如下:

初始化JTAG链:首先,通过一系列TMS信号将JTAG链置于复位状态,然后切换到Shift-IR状态,向每个设备的IR寄存器发送全1(即BYPASS指令),最后将JTAG链切换到Shift-DR状态。清空DR寄存器:在发送BYPASS指令后,通过向DR寄存器发送一系列0来清空可能存在的旧数据。发送并接收数据:向TDI发送一个1,然后逐个时钟周期地检查TDO输出。由于每个设备都会将输入延时一个时钟周期,所以TDO将在(设备数量+1)个时钟周期后输出1(加1是因为包括发送数据的那个时钟周期)。计算设备数量:通过记录从发送数据到接收到数据所经过的时钟周期数,减去1(发送数据的那个周期),即可得到JTAG链上的设备数量。C程序它首先通过一系列TMS信号将JTAG链置于正确的状态,然后发送BYPASS指令到每个设备的IR寄存器,并清空DR寄存器。最后,通过发送一系列1到TDI并检查TDO的输出来计算设备数量。当TDO输出1时,循环结束,此时循环的迭代次数(减去1)即为JTAG链上的设备数量。

2.5 获得JTAG链上芯片的ID

大部分的芯片JTAG模块都支持IDCODE指令**,这个指令对应的DR寄存器是32位,具体数值代表者不同芯片的ID。**

不同于BYPASS指令,INCODE指令的IR寄存器数值不是标准的,我们可以通过器件手册来查询。

还有一种方法,当TAP控制器的状态处于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;

从上面这个文件我们可以知道:

IR寄存器的长度是10位;IR指令寄存器的指令清单,比如SAMPLE的是0000000101,也就是0x005;该器件的IDCODE,00001101110是厂商的代号(阿尔特拉);边界扫描链的长度是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寄存器结构图,各层级关系比较一目了然。

我们可以得出以下信息:

IR指令寄存器(Instruction Register)的值决定采用什么指令以及选择对应的DR寄存器(Data Register);Bypass Register只有一位,其指令BYPASS我们上文已经讲过,其提供从TDI到TDO最短路径;边界扫描寄存器是个移位寄存器,由芯片上所有的管脚BSC组成。阿尔特拉的BSC全称是Booundary scan cell,它可以将信号施加到管脚,或者获得管脚上的数据和内部逻辑信号。我们JTAG测试的数据也是串行输入到BSC单元中,捕获到的数据也是串行从BSC输出,进而判断测试结果。根据我的理解,此处的BSC就是我们上文提到的IO pad芯片管脚处理模块。3.3、JTAG还可以做什么?

控制芯片的引脚状态,对应的IR指令为EXTEST,表示外部测试,可以让输出管脚输出高低逻辑电平,根据输入接受到的电平信号检测JTAG链中任何设备管脚处的开路和短路情况;用于FPGA和CPLD的配置;JTAG接口可以作为调试端口。怎么样,通过本文的讲解是不是对JTAG有了基本的认识。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭