完整版请点击 https://hifpga.com/问题/719

索取源码,向博主本人提问FPGA相关问题

作者:Rock.Ding(莱迪思半导体公司)
关键字:MCU, JTAG, 在线编程, CPLD。

前言

CPLD(Complex Programmable Logic Device)复杂可编程逻辑器件,是从PAL和GAL器件发展出来的器件,相对而言规模大,结构复杂,属于大规模集成电路范围。是一种用户根据各自需要而自行构造逻辑功能的数字集成电路。其基本设计方法是借助集成开发软件平台,用原理图、硬件描述语言等方法,通过编译,映射,布局布线,最后生成相应的JED文件,然后通过CPLD厂家提供的下载电缆和下载软件把JED文件下载器件里面,实现用户的功能。在实际应用中,根据设计需要或修复之前设计中的Bug,常常需要在线升级CPLD的内容。目前各厂家都有提供相应的方案,可以在嵌入式系统中通过CPU来更新CPLD。厂家考虑到方案的兼容性,往往实现编程的代码都比较复杂,而且占用内存资源较大。不适合MCU这样的小系统。本文以Lattice XO2系列的CPLD为例,详细介绍JTAG的编程原理及如何用MCU来模拟JTAG编程Lattice XO2 CPLD。理解了JTAG编程原理后,也可以很容易实现模拟JTAG编程其它的CPLD和FPGA。

一,JTAG介绍

JTAG最初是用来对芯片进行测试的,JTAG的基本原理是在器件内部定义一个TAP(Test Access Port;测试访问口)通过专用的JTAG测试工具对内部节点进行测试。JTAG测试允许多个器件通过JTAG接口串联在一起,形成一个JTAG链,能实现对各个器件分别测试。如今,JTAG接口还常用于实现ISP(In-System Programmer,在系统编程),对CPLD,FPGA等器件进行编程。
JTAG编程方式是在线编程,传统生产流程中先对芯片进行预编程然后再装到板上,简化的流程为先固定器件到电路板上,再用JTAG编程,从而大大加快工程进度及编程的灵活性。
JTAG引脚定义
具有JTAG口的芯片都有如下JTAG引脚定义:

  • TCK——测试时钟/编程时钟输入;
  • TDI——测试数据/编程数据输入,数据通过TDI输入JTAG口;
  • TDO——测试数据/编程数据输出,数据通过TDO从JTAG口输出;
  • TMS——测试模式选择/改变TAP内部的状态机的状态。
  • TDI, TMS上的数据输入及TDO上的数据输出都是在TCK时钟的作用下完成的。

二,JED文件介绍

JED文件是一个包含了器件的编程内容的文本文件。本文以Lattice XO2系列的CPLD的JED文件为例,简约介绍JED文件的格式,下面是Lattice的开发工具生成的JED文件中截取的一部分:

NOTE Diamond_1.2_Production (92) JEDEC Compatible Fuse File.*
NOTE Copyright (C), 1992-2010, Lattice Semiconductor Corporation.*
QP132*
QF343936*
G0*
F0*
L000000
1111111111111111101111011011001111111111111111110011101100000000000000000
NOTE EBR_INIT DATA*
L137984
1111111111111111111111111111111111110110000000000000000000000000000000000
NOTE END CONFIG DATA*
L184832
0000000000000000000000000000000000000000000000000000000000000000000000000
NOTE TAG DATA*
L343808
0100010001000100000010001000000000000000000100010000000000000000000000000
C5CC8*
NOTE FEATURE_ROW*
E0000000000000000000000000000000000100001000010000000000000000000
NOTE User Electronic Signature Data*
UHCAFEBABE*
6243

...

三,模拟JTAG编程。

1,怎样获得JTAG的编程细节?

如果手上没有某个CPLD的具体JTAG编程指导文档,可以用厂家的编程工具生成SVF(Serial Vector Format)文件,该文件包含JTAG编程的详细流程和编程类容。以Lattice最新的编程工具Diamond Programmer为例,它附带了一个小工具,叫做Deployment Tool(图1),就可以生成SVF文件。

SVF文件是文本文件,里面包含定义好的各种命令,详细描述了JTAG的编程行为。具体可参考Serial Vector Format Specification标准。SVF文件里面的命令很容易理解,下面从SVF文件中摘取一段擦除器件的SVF代码,做简单介绍:

! Erase the Flash
! Shift in ISC ERASE(0x0E) instruction
SIR 8 TDI (0E); SDR 8 TDI (0E);
RUNTEST IDLE 2 TCK;
! Shift in LSC_CHECK_BUSY(0xF0) instruction
SIR 8 TDI (F0);
LOOP 350 ;
RUNTEST IDLE 2 TCK 1.00E-002 SEC;
SDR 1 TDI (0) TDO (0);
ENDLOOP ;

感叹号后面的类容都是注释,只是为了更好的理解SVF命令。
...

2,解析SVF命令。

如果用厂家的编程工具来编程,是由厂家的软件来控制JTAG口上的输入/输出数据的时序。现在我们通过SVF文件了解JTAG编程具体流程后,也可以解析SVF 命令来模拟这个时序。仔细观察SVF文件,里面主要包括三类指令,SIR,SDR,控制状态机的指令,SDR常用的有三种方式:

  • 1,只在TDI上送入数据,例如:

    SDR 128 TDI (0000B280071D000000623FFC0DB01216);

  • 2,送入数据同时,在TDO上读取数据,并判断读取的数据是否是期望的值,例如:

    SDR 128 TDI (00000000000000000000000000000000)
    TDO (414900000040000000DCFFFFCDBDFFFF);

  • 3,是在TDO上读取数据时,只判断MASK相应Bit位是1的TDO的值是否是期望的值,例如:

    SDR 32 TDI (00000000) TDO (012B2043) MASK (FFFFFFFF);

下面是解析SVF命令的C51函数,可以直接在Keil C51环境下编译。

1,JTAG状态机转换。

通过在TMS管脚上输入不同的01序列来实现JTAG状态机的控制,下面控制状态机的代码是在Lattice编程工具提供的参考代码修改而来。

typedef struct
{     BYTE CurState;/*** From this state ***/BYTE NextState;/*** Step to this state ***/BYTE Pattern;/*** The pattern of TMS ***/BYTE Pulses;/*** The number of steps ***/
}JTAGState;
JTAGState code JTAGStateTable[25]=
{{DRPAUSE,  SHIFTDR,  0x80,  2},{IRPAUSE,  SHIFTIR,  0x80,  2},一共25个状态,篇幅影响,这里只列了2个状态。
};
void Set_JTAG_State_Machine(BYTE nextstate)
{BYTE data i,j,temp;if((CurState == nextstate)&&(CurState != RESET))return;for(i = 0;i < 25;i++){if((CurState == JTAGStateTable[i].CurState)&&(nextstate == JTAGStateTable[i].NextState))break;}CurState = nextstate;temp = JTAGStateTable[i].Pattern;for(j = 0;j < JTAGStateTable[i].Pulses;j++){if((temp & 0x80)== 0x80)TMSPin = 0x01; else TMSPin = 0x00;Send_1Clk(); temp = temp << 1;}TDIPin = 0x00; TMSPin = 0x00;
}

首先定义一个数据结构,....

2,解析SIR(Scan Instruction Register)命令。

SIR是往指令寄存器中送入数据,纵观整个SVF文件,SIR命令送入的数据都是8Bit,实现SIR命令的C51函数如下:

BYTE Excute_SIR(BYTE instruction)
{BYTE data i;....for(i = 0;i < 8;i++){...}Set_JTAG_State_Machine(IRPAUSE); return(SUCCESS);
}

该函数只需输入一个参数instruction,函数开始会把JTAG状态机转换到IRPAUSE状态,然后再转换到SHIFTIR状态,再把8Bit 的instruction从TDI管脚送入JTAG,先送低Bit。最后再把JTAG状态机转换到IRPAUSE状态。注意在for循环中,在TCK上只需送入7个时钟周期,也就是说这里送入的时钟周期比数据少一个。

3,解析SDR(Scan Data Register)命令

SDR命令往数据寄存器中送入和读出数据。编程时的数据输入和输出都是通过这个命令来实现。实现SDR的C51函数如下:

BYTE Excute_SDR(BYTE bit_len,BYTE TDI_mark,BYTE TDO_mark,BYTE mask_mark)
{BYTE data I, TDI_data, TDO_data, mask_data, ptr, result;   ptr = 0;  result = SUCCESS;...for(i = 0;i < bit_len;i++){...}Set_JTAG_State_Machine(DRPAUSE);return(result);
}

上小节说到SDR命令可能有3种模式,不同的模式可能需要用到TDI,TDO,MASK数据,在调用这个函数前,根据需要先把数据存入TDI_Buffer,TDO_Buffer,MASK_Buffer里面,然后调用函数时,把需要送入JTAG的 Bit数据长度,是否有TDI数据,TDO数据及MASK数据四个参数传送给函数。在TDI上送入数据前,先把JTAG状态机转换到DRPAUSE,再转换到SHIFTDR,然后开始送入数据,同样需要注意在送数据时,在TCK上时钟周期数是送入数据Bit数少一个,例如送入128Bit数据,只送127个时钟周期。送完数据后,再把状态机转换到DRPAUSE,这样整个操作完成。函数执行成功,返回1,否则返回0。

四, MCU模拟JTAG编程CPLD完整例子。

上一节已经讲了实现JTAG编程的3个主要函数,本节主要是怎样调用这三个函数实现对CPLD的编程。本例子用到MCU是STC89LE516RD+,CPLD是Lattice LCMXO1200ZE。
Lattice LCMXO1200ZE大致编程流程是:

  • 1,检查器件ID,2,编程BSCAN 寄存器,3,使能编程,4,擦除Flash,5,编程Flash,一次编程1行128Bit,一种2175行,6, 编程user code,7,校验Flash, 8,校验User code,9,编程Done Bit,10, 退出编程模式, 11,Refresh。每一个操作可以用一个函数来实现,这里只讲解两个典型的操作:
  • 2, 编程Flash ,编程Flash前首先要复位Flash的地址,这个操作只执行一次,接着每编程一行,Flash的地址会自动加一,函数如下:

    BYTE Init_Address(void)
    {BYTE  result;Excute_SIR(0x46); TDI_Buffer[0] = 0x04;result = Excute_SDR(8,1,0,0);Set_JTAG_State_Machine(IDLE);Send_Num_Clk(2);Wait_ms(10);return(result);
    }
    

    然后以行为单位,编程Flash。调用函数前,需要把编程数据放入TDO_Buffer中。函数执行过程,先送PROG_INCR_NV指令,然后送入编程数据,最后检测编程状态,直到Busy Bit为0后才表示编程成功。成功函数返回1,否则返回0。下面是编程一行的函数,根据器件大小,Flash的行数不同,反复调用这个函数来编程Flash。

    BYTE Program_Row(void)
    {BYTE data loop,result;Excute_SIR(0x70); Excute_SDR(128,1,0,0);Set_JTAG_State_Machine(IDLE);Send_Num_Clk(2); Excute_SIR(0xf0);TDI_Buffer[0] = 0x00; TDO_Buffer[0] = 0x00;for(loop = 0;loop < 10;loop++){Set_JTAG_State_Machine(IDLE); Send_Num_Clk(2);Wait_ms(10); result = Excute_SDR(1,1,1,0);if(result == SUCCESS)break;}return(result);
    }
    
  • 3, 校验 Flash ,校验Flash时,也需要先调用复位Flash 地址的函数Init_Address;然后输入LSC_READ_INCR_NV指令,表示开始读取Flash的数据,最后循环调用Verify_Row函数,来读取数据并校验是否正确,在每次调用Verify_Row函数前,需把校验数据放入TDO_Buffer中。相关函数如下:

    BYTE Verify_Row(void)
    {BYTE data result;result = Excute_SDR(128,0,1,0);Set_JTAG_State_Machine(IDLE);Send_Num_Clk(2);  Wait_ms(1);return(result);
    }
    
  • 4, 本例子中所有的命令和数据来自串口,每接收到一个命令执行一次操作。串口函数根据约定好的协议,从上位机接收命令和数据,接收到成功后,把相关命令传送给主函数,主函数调用相关函数执行相应的操作,执行完成后,又回到等待状态,等待下一个命令。上位机界面如下,只需要选择好串口,选好下载文件,点“Start”按钮就可以了。这里下载的文件是从JED文件转换而来,因为JED文件是文本文件,而且包含了很多注释信息,这里只提取了Flash行的类容,并转化为BIN文件。

总结

本例子模拟JTAG编程有关的代码大约只有300行,只要理解JTAG编程原理,就可以化繁为简。根据自己的需求,定制编程流程,不需完全照搬厂家提供的代码,这样在调试或功能改进中都更加容易和灵活。有需要源代码的可以先在下面回复然后发邮件给我,发邮件时记得写上论坛用户名,我的邮箱是:
admin@mail.hifpga.com

参考文献:
1, MachXO2 Family Handbook,HB1010.pdf。
2, Serial Vector Format Specification,SVF_Spec_RevE.pdf。
3, Lattice VME source code。

完整版请点击 https://hifpga.com/问题/719

MCU模拟JTAG接口对LATTICE CPLD FPGA 进行在线编程加载相关推荐

  1. ALTERA CPLD离线烧写方案设计(MCU模拟JTAG)

    在含有CPLD芯片的电子产品中,由于代码中的BUG需要升级固件,如果以前的固件内没有离线烧写系统,那么必须要通过专门的烧写工具把固件下载到CPLD中去(如USB Blaster),但这样非常繁琐,而且 ...

  2. 常见的分词方法接口+ jieba自定义领域内的词表然后加载词表进行分词

    中文分词常见方法_mandagod的博客-CSDN博客_中文分词 另外,我们收集了如下部分分词工具,供参考: 中科院计算所NLPIR http://ictclas.nlpir.org/nlpir/ a ...

  3. 树的懒加载怎么用ajax调接口,ElementUI tree树形控件的懒加载使用

    先看效果: image 1.界面中: :data="treeData" :props="defaultProps" :load="loadNode&q ...

  4. 硬件街机游戏开发,单片机游戏开发,CPLD/FPGA、ARM平台游戏开发群成立

    本超级QQ群成立,上限人数为500. 目标是发展中国游戏产业,提升硬件游戏开发技术交流.提供大的平台. 发展的方向是游戏动漫相结合,此群不是网络游戏开发,为单板街机游戏开发. 所属第三产业.以电脑板游 ...

  5. xilinx FPGA的远程更新(动态加载)详解(Using a Microprocessor to Configure 7 Series FPGAs)

    目录 1 概述 2 参考文件 3 远程更新思路 4 MIC配置FPGA的模式 4.1 slave serial mode情况 4.2 slave selectMAP mode情况 5 FPGA配置时序 ...

  6. 基于FPGA的在线升级

    基于FPGA的在线升级 在线升级的意义 在线升级的策略 整体框架 总结 参考文献 结束语 在线升级的意义 首先什么是FPGA的在线升级? 所谓FPGA的在线升级其实就是不对FPGA进行常规意义下的下载 ...

  7. CPLD/FPGA的UART接口设计之系统时钟(晶振)和波特率关系

    UART(UniversalAsynchronous ReceiverTransmitter,通用异步收发器)是一种广泛使用的异步串行数据通信协议.目前大多数MCU.串口通信IC等芯片或模块均支持UA ...

  8. (4)FPGA JTAG接口连接(学无止境)

    1 JTAG简介 FPGA烧录bit文件需要用到仿真器,仿真器与FPGA硬件板卡通过JTAG接口连接.JTAG主要起作用的只有五个信号:Test Clock Input(TCK).Test Mode ...

  9. (43)FPGA面试题JTAG接口信号及功能

    1.1 FPGA面试题JTAG接口信号及功能 1.1.1 本节目录 1)本节目录: 2)本节引言: 3)FPGA简介: 4)FPGA面试题JTAG接口信号及功能: 5)结束语. 1.1.2 本节引言 ...

最新文章

  1. 威纶通触摸屏可以解密吗_施耐德PLC与威纶触摸屏通讯步骤
  2. C语言图形界面的编程
  3. ajax点击事件触发后台,使用jquery点击事件触发AJAX
  4. CodeCraft-20 (Div. 2) C. Primitive Primes 思维 + 数论
  5. 多iframe下的html同名id,获得同级iframe页面的指定ID元素的几种实现方法
  6. bvp解算器是什么_中科院孙晓明:算法本身并没有善恶,看你想要的目标是什么...
  7. FISCO BCOS 区块链 查看代码版本号
  8. 全面解读新中产:有房有车有贷、半数决策看老婆
  9. 采用计算机对酒店客房进行管理,酒店客房部计算机管理.doc
  10. java 响应式编程_响应式编程
  11. OPA2134UA IC AUDIO 2 CIRCUIT 8SOIC
  12. 转 Apache Ignite——新一代数据库缓存系统
  13. Vmware虚拟机ikuai路由配置
  14. 苹果8android价格,iphone8plus相当于什么档次的安卓机?从这3方面就可看出
  15. android权限集合
  16. 《2022年Java开发者生产力报告》出炉啦
  17. 银行软件测试工作总结
  18. 在windows中对数字证书进行管理
  19. SpringBoot word文档转pdf
  20. unity3d摄像机

热门文章

  1. Android Studio配置文件路径修改的方法
  2. js常见的的6种继承方式
  3. html采购页面,采购单.html
  4. EEMD(集合经验模态分解)
  5. excel手机号码怎么加隐藏中间四位?
  6. Dev-C++中关于函数 was not declared in this scope报错的解决方法
  7. js+php做省份城市选择,三级联动,前后端简单交互,最详细
  8. 关于C语言——应用函数介绍
  9. P7774 KUTEVI
  10. 设计一个三维向量类 并实现向量的加法 减法以及乘法除法