利用MxTNI JTAG库和SVF文件编程Xilinx PROM器件

本应用笔记阐述了如何利用mxtni™ jtag库以及串行向量格式(svf)文件来编程xilinx® prom器件。假定读者已经对jtag和可编程逻辑器件有了一定认识。
介绍maxim微型网络接口(mxtni)是dallas semiconductor (maxim integrated的全资子公司)开发的一个平台。它包含了一套小型却功能强大的芯片组以及java®可编程虚拟机。芯片组具有处理、控制、器件级通信和网络互连的能力。为了和任何jtag器件通信,tinis400适配板在j21端具有4引脚jtag输出。 这些引脚将直接连到jtag器件上标准jtag引脚tdi、tdo、tms和tck。
在系统编程prom可以进行单独编程,或者级连编程。链中的所有器件共享tck和tms信号。mxtni的tdi信号接到边界扫描链中第一个器件的tdi输入端。第一个器件的tdo信号接到链中第二个器件的tdi输入上,如此连接下去。链中的最后一个器件的tdo输出接到mxtni的tdo引脚上,见图1所示。
图1. 所有jtag操作都通过器件的测试访问端口进行控制
所有jtag操作都是由器件的测试访问端口(tap)控制的。tap包括四个信号:tms、tdi、tdo和tck。 这些信号通过tap控制器,即16状态有限状态机与器件相互作用。jtag的tms信号控制状态间的转换。指令和数据由tdi引脚移入器件,并由tdo引脚移出。tdi和tdo信号的所有状态转换和行为都与tck同步。见 图2 。
图2.
所有jtag操作都是将数据移入或移出jtag指令和数据寄存器。tap控制器可对所有这些寄存器直接访问。有两类jtag寄存器:指令寄存器(ir)和数据寄存器(dr)。访问ir通过移位-ir (shift-ir)状态实现,而访问dr通过移位-dr (shift-ir)状态实现。ir长度通常是大于2位的任意长度。除了由ieee® std. 1149.1定义的bypass指令为全1以外,生产商定义所有其它的指令位码。
在本应用笔记中,java样例代码将解释说明串行向量格式(svf)文件来进行编程。这里所用的svf是描述高层ieee 1149.1 (jtag)总线操作的语法规范。jtag设备和软件提供商已经将svf作为标准用于数据交换。svf以紧凑和可移植的形式描述jtag链操作。svf文件通过描述需要移入器件链的信息,记录jtag操作。通过xilinx impact (详细信息见下面)软件,将jtag操作记录在svf文件中。svf文件写成ascii文本形式,因此可以在任何文本编辑器中人工读、修改和写。“许多第三方编程工具使用svf文件作为输入,这样利用包含在svf文件中的信息可以对jtag链中的xilinx器件编程。”
jtag库简要说明所开发的jtag类库可帮助用户使用mxtni与jtag器件进行通信。一个可能的应用是:从遥远的位置对可编程逻辑进行动态和在系统更新。用户能够将tap控制器初始化到初始状态、浏览16个状态、获得或设置tap状态、产生时钟信号、发送命令和数据等等。以下为jtag类方法的简要说明:
public jtag(): 加载jtag库。public string getversion(): 返回jtag类的版本。public int runclock( int numticks ): 以numticks指定的数量运行时钟。public byte initialize(): 先将tms置高达五个tck时钟脉冲,然后tms置低1个时钟并进入缺省状态run-test-idle。public byte setstate( byte astate ): 将目标状态设置为astate指定的状态。public byte getstate(): 返回目标状态。public byte scanstate( byte state ): 将tap控制器的状态机转换到参数state指定的状态。public string displaystate(byte state): 显示tap控制器的状态。public byte waitstate( int msecs ): 进程延时一定毫秒数。public byte gettdo(): 获得引脚tdo的当前状态。public void settdi(byte logic): 引脚tdi设定为指定的逻辑状态。public byte gettdi(): 获得引脚tdi的当前状态。public void settms(byte logic): s引脚tms设定为指定的逻辑状态。public byte gettms(): 获得引脚tms的当前状态。public void settck(byte logic): 引脚tck设定为指定的逻辑状态。public byte gettck(): 获得引脚tck的当前状态。public byte sendnrcv(byte[] data, int offset, int size, byte numberofbits, boolean state, boolean update, byte extraheaderclock, byte headerbitval,byte extratrailerclock, byte trailerbitval): 发送数据字节数组,并接收返回的字节数组。public byte sendnrcv(int[] data, int offset, int size, byte numberofbits, boolean state, boolean update,byte extraheaderclock, byte headerbitval,byte extratrailerclock, byte trailerbitval): 发送数据整形数组,并接收返回的整形数组。硬件和软件需求以下为所需要的硬件和软件:
tini400评估板,并配置有mxtni os 1.12或更高版本。jtag器件(可编程逻辑)。器件链中jtag器件模型的svf文件。编程步骤第1步: 将mxtni板的4个jtag引脚与jtag器件的4个jtag引脚相连。
第2步: 遵循svf文件的命令并使用jtag库编写java应用程序,来对jtag器件进行编程,编译后加载到mxtni。
(附录a: 一个样例idcode.svf文件,实现从单独的xc18v02 xilinx器件读取idcode。)
(附录b: 样例appjtag.java程序,将svf文件作为输入并产生jtag信号来读取idcode。该样例程序是用来处理单独器件的(对于级连器件的详细信息见附录c)。)
(附录c: 展示了由已有的svf文件编程级连器件的步骤。)
第3步: 运行java程序。可执行appjtag.tini将加载到mxtni板。在mxtni提示符下录入“java appjtag.tini idcode.svf”来运行程序。程序将产生jtag信号与jtag器件进行通信。注意:
生成的编程jtag器件svf文件应该与器件链中设计的确切模型一致。所有操作码,例如编程jtag器件的read、write、erase及其它命令等,都是由生产商定义的。svf文件应该包含用户需要的所有操作码。示例以下示例说明了如何利用jtag库从xilinx jtag器件xc18v02中读取idcode。完整的样例代码,请查阅附录b。
生成器件模型的svf文件:
使用xilinx web start来生成svf文件。
执行impact并选择单选按钮“prepare configuration files”选项,然后点击next。选择单选按钮“boundary scan file”并点击next。选择“svf file”然后点击finish。在对话框中录入svf文件名,例如example,并点击ok。选择要加载的name_of_mcs_file.mcs文件,并从列表中选择prom器件(xc18v02_vq44)。xc18v02已加到模型中。点击我们要编程的xc18v02器件型号。器件将为高亮显示。点击鼠标右键,并选择编程选项。勾选“get idcode”。在模型外点击鼠标以取消高亮显示器件,右击并选择option以关闭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发送命令。svf规范提供了四个全局填充指令:头指令寄存器(hir)、尾部指令寄存器(tir)、头数据寄存器(hdr)和尾部数据寄存器(tdr)。这些全局命令规定了移位操作的开始和结尾处要填充的位数,从而解决旁路器件问题,并为svf文件压缩提供了一种简单的方法。一旦指定,这些位会出现在sir或者sdr命令的每一组比特位的前面或者后面。以下两个示例说明如何把svf命令解释为jtag库命令。示例1: 带有全局填充指令的svf语法结构
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 0byte 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语法结构
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 0byte 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);}结论由提供的svf文件来编程xilinx prom器件是非常简单的。但是,如果用户能够正确分析svf文件并理解如何确定对器件链中哪个器件进行编程,会更有好处。知道了这些信息,编程者能够更加高效地使用jtag库。软件小组要对遥远位置的xilinx jtag器件进行编程,已有实际应用。利用开发包中的嵌入式jtag编程软件,并以mcs文件作为输入文件,这是很容易做到的。


增收不增利,三孚新科上半年净亏损同比扩大11.11%
基于卷积的框架有效实现及视觉Transformer背后的关键成分
RCP实现混合型电力滤波器
网关有辐射吗_网关地址如何修复
用于电流模式DC-DC转换器的统一LTspice AC模型
利用MxTNI JTAG库和SVF文件编程Xilinx PROM器件
芯片开发商ARM宣布对CPU与GPU的一系列改进,性能大幅提升
人工智能是什么?与机器学习有何不同?
超级电容器改善汽车启动性能原理分析
高温线与普通线的区别,高温线的优势是什么
华硕千元高端声卡评测 一款兼顾两批发烧友的产品
伺服电机的转速控制与抗干扰措施
用于DDR-QDR4存储器的超薄稳压器LTM4632
AMD最新显卡即将上市 或支持VR头显的流式传输
智能井盖NBLORA井盖检测物联网智能井盖检测设备
专访天马总经理孙永茂,大谈天马业务情况
苹果加速自研芯片之路,联发科希望再落空
Apache服务器和Nginx服务器
静电触摸开关原理是什么
单结晶体管结构及应用