原创 【博客大赛】【原创】Virtual JTAG调试平台的建设

2012-12-3 12:17 4112 15 24 分类: FPGA/CPLD 文集: Virtual JTAG
  • Virtual JTAG megafunction 端口定义

表1 VJ核输入端口

Port Name

Required

Description

Comments

tdo

Yes

Writes to the TDO pin on the device.

 

ir_out[]

No

Virtual JTAG instruction register output. The value is captured whenever virtual_state_cir is high.

Specify the width of this bus with the SLD_IR_WIDTH parameter.

 

 

表2 VJ核输出端口:

Port Name

Required

Description

Comments

tck

 

Yes

JTAG test clock.

Connected directly to the TCK device pin. Shared among all virtual JTAG instances.

tdi

 

Yes

TDI input data on the device. Used when the virtual JTAG megafunction instance is in when virtual_state_sdr is high.

 

Shared among all virtual JTAG instances.

ir_in[]

 

No

Virtual JTAG instruction register data. The value is available and latched when virtual_state_uir is high.

Specify the width of this bus with the SLD_IR_WIDTH parameter.

    

      表3 High-level Virtual JTAG State Signals

Port Name

Required

Description

Comments

virtual_state_cdr

No

Indicates that virtual JTAG is in Capture_DR state.

 

virtual_state_sdr

Yes

Indicates that virtual JTAG is in Shift_DR state.

In this state, this instance is required to establish the JTAG chain for this device.

virtual_state_e1dr

No

Indicates that virtual JTAG is in Exit1_DR state.

 

virtual_state pdr

No

Indicates that virtual JTAG is in Pause_DR state.

The Quartus II software does not cycle through this state using the TCL command.

virtual_state_e2dr

No

Indicates that virtual JTAG is in Exit2_DR state.

The Quartus II software does not cycle through this state using the TCL command.

virtual_state_udr

No

Indicates that virtual JTAG is in Update_DR state.

 

virtual_state_cir

No

Indicates that virtual JTAG is in Capture_IR state.

 

virtual_state_uir

No

Indicates that virtual JTAG is in Update_IR state.

 

 

上面三个表是VJ核的基本端口描述,在VJ核的user guide或者Quartus II软件的帮助里可以找得到。

      

       关于Virtual JTAG测试平台的建设,主要分两个部分,一个部分是基于FPGA的底层设计,主要就是例化VJ核,以及相关的逻辑接口设计;另外一个部分是应用层的用户接口(GUI)的设计,主要是采用TCL语言设计友好的用户界面。

 

  • 基于Virtual JTAG的底层FPGA逻辑设计

      

       FPGA的底层逻辑设计,在前面的“如何有效利用Virtual JTAG进行电路调试”一文中有过简略介绍。在那个文章里介绍了如何在FPGA里例化一个FIFO和VJ和进行交互,再通过TCL建立的用户接口经由VJ访问FIFO.

 

       在实际的实践中可以将一些非实时的数据暂存在FIFO里,当需要分析的时候再从FIFO里读出来进行分析。这里我们希望介绍一些相对比较复杂的应用,在本人实际应用中,我在之前基于FIFO的基础上再加入了对FPGA内部寄存器的读写(或者说对一些参数可以进行实时地配置),另外加入了VJ对于FPGA外挂的SDRAM的访问。

 

        前面文章已经介绍了如何例化VJ,这里不赘述,只是需要提醒的是对user来说,逻辑里只有ir_in和tck这两个端口会经常用到,另外作为状态的控制,cdr,cir,sdr,udr,以及uir这几个状态指示引脚在相关的数据或者命令锁存的时候要用到。这里给出一个简单的例子:

 

------------------------------------------------------
--Tcl只负责发送写命令,写fifo的数据由FPGA自己产生
-------------------------------------------------------
process(clkin,reset)
begin
        if reset = '0' then
             write_en <= '0';
        elsif clkin'event and clkin= '1' then
             if ir_in = fifowr_cmd and uir = '1' then
                  write_en <= '1';
             else
                  write_en <= '0';
             end if;
        end if;
end process;

 

ir_in端口当前只是处于FIFO写命令状态(需要注意的是VJ根据ir_in端口宽度可以编码出一定量的命令,比如ir_in为4bit的时候最多支持16个命令,所以在搭建调试平台的时候一定要事先确定好最终你需要的命令数,当然你也可以在不够的时候进行例化修改),那么uir指示了何时可以稳定锁存此命令,这时候就相当于FPGA收到了平台发过来的写FIFO的命令了,那么到底写什么数据呢?这个可以事先约定,或者也可以通过TCL平台传递需要写入的数据,这里是根据此命令,将相关逻辑已经处理好的数据写入FIFO以待后续分析。其他状态以及命令类似处理。对于VJ逻辑模块的设计,主要是VJ核的例化,还有就是VJ各个命令的编码,接着就是对于各个编码好的命令进行相应的解码以及后续处理。比如上述代码中“ir_in = fifowr_cmd”的fifowr_cmd是个常量,是VJ命令的一个编码值,上面给出的代码就是对此命令的部分逻辑处理。

 

      处理VJ逻辑,另外一个部分就是用户逻辑处理,比如上述FIFO的例化以及FIFO的读写控制。这里需要加入的是FPGA内部寄存器的读写控制,以及SDRAM的控制器逻辑代码。当然增加了用户逻辑,相应地也要在VJ逻辑处理里增加相应的命令编码以及解码处理逻辑。

       这里增加了VJ与SDRAM的通信,只是为了调试SDRAM控制器,调试结束后,为了节约资源完全可以注释掉VJ相关部分或者全部模块。至于如何在FPGA设计SDRAM的控制器有很多人有过相关的文章,而且Xilinx和ALTERA都有参考设计可以参考,本人也有专门的博文介绍自己的体验,这里也不再赘述。本文最后的问题描述部分给出我在实际项目中使用SDRAM的时候碰到的问题以及解决过程。

 

 

  • 基于Virtual JTAG应用层TCL用户界面设计

      

        FPGA底层逻辑设计好以后,就是搭建应用层的用户界面,其实这两个部分可以同时交互进行,因为随着设计的丰富,你也许要逐步的增加调试项目,也即是要增加VJ的命令端口数目。在前面的两篇“Virtual JATG初探”中对于VJ TCL命令进行了相关的介绍,这里不再赘述。这里给出上述FIFO写的时候对应的VJ TCL代码

 

;###FIFO Write command.通过tcl发命令给FPGA,让FPGA将FIFO写满。
proc FIFO_Push_CMD {} {
     .top.t insert end "\n Command: Single Write FIFO\n"

     device_lock -timeout 10000
         device_virtual_ir_shift -instance_index 0 -ir_value 1 -no_captured_ir_value
         set usedw [device_virtual_dr_shift -instance_index 0 -length 32 -value_in_hex]
         device_unlock
         set tmp 0x
         append tmp $usedw
         set usedw [format "%i" $tmp]
        
     set DataWidth 32
     set value [.top.slider get]
     
     if {$usedw!=255} {
         if {$value > 2097152} {
              .top.t insert end "\nvalue entered exceeds 21 bits\n" }
         
         set push_value [int2bits $value]
         set diff [expr {21 - [string length $push_value]%21}];#这里的“%”似乎没什么作用(求余数),如果去掉“%21”运行结果无变化,反正就是获取字符长度
         
         if {$diff != 21} {
               set push_value [format %0${diff}d$push_value 0]
         }
         
         .top.t insert end "$push_value\n"
         
         device_lock -timeout 10000
         device_virtual_ir_shift -instance_index 0 -ir_value 4 -no_captured_ir_value
         
         device_virtual_dr_shift -instance_index 0 -dr_value $push_value -length 21 -no_captured_dr_value
         device_unlock
     } else {
         .top.t insert end "\nCan't write the FIFO, for it is full now!\n"
     }
}

 

上述代码中“device_virtual_ir_shift -instance_index 0 -ir_value 4 -no_captured_ir_value”定义了ir_value为4,那么也就是在FPGA中逻辑设计中对于此命令的编码值就是4,也即常量fifowr_cmd等于4.这点一定要注意,TCL和FPGA逻辑对于命令的编码值一定要一一对应,否则就无法正确的进行命令解析以致无法正常的进行调试。

 

  • 实例演示

     

      1. 基于FIFO的测试平台

1.jpg
                图1 基于FIFO的测试平台

       此阶段性测试平台具备以下功能:
        1)、具备给FPGA发生一个系统复位功能;
        2)、读取FIFO的usedw、full以及empty标志信息;
        3)、给FPGA发一个命令,让其将FIFO填满数据;
        4)、通过tcl将FIFO里的数据一次读出来;读出来的数据可以显示在当前text框里,同时可以存储在一个文件里供离线分析;
        5)、从一个文件里往FPGA的存储器或者外挂的存储器里写入大量的初始数据;
        6)、读取系统内部状态标志,一次可以读取32个标志“位”;
        7)、向系统写入参数,写入的参数可以通过输入窗口进行设定。

      2. 加入SDRAM访问的测试平台

1.jpg
图2 加入SDRAM访问的测试平台

      此阶段性测试平台具备以下功能:

      1). 加入SDRAM单个写控制按钮,写入的地址和数据通过参数设置窗口设定;目前支持设置的地址和写入的数据是一样的。
      2). 加入SDRAM大批量写按钮;写入的数据是通过逐一读取当前目录下的文件里的数据写入,写入的地址根据逐次写入操作加1,起始地址默认是0.
      3). 加入SDRAM读按钮,此按钮可以支持单个读,以及批量读1024个地址数据;当滑动条设置为0时为批量读,非0时为单个读;批量读默认从0开始读1024个数据,单个读的地址由参数设置窗口设定。

     
      问题描述

     

       1. VJ测试平台访问SDRAM的问题

      上述SDRAM在批次写的时候,第一个数据不是文件里的第一个数据,而是上一次留在SDRAM数据线上的数据;文件里的第一个数据被写入在第二个位置,如图2中的0地址上的数据3不是文件里的第一个数据;而文件里的第一个数据“0000”被写在了地址1位置。经过查时序,这个问题算是找到了,把第一个数据改成x“5555”,为了好看。用signaltap抓了一下发现是在大批次写的时候第一个地址是从1开始而不是0开始,而大批次读的第一个地址是0.如图3所示

1.jpg
图3 用SignalTap找到SDRAM写问题所在

大家看最后一行的“sdr_wr_adr"正好是地址1,而此时的写入数据”data_from_sys“是我定义的第一个数据0x5555,也就是在SDRAM写的时候第一个数据0x5555没有被写入地址0.修改SDRAM的控制器解决此问题,SDRAM的读写均无问题,如图4所示。

1.jpg

图4 解决SDRAM访问问提

      2. SDRAM single operation mode下节约访问时间的探讨

      SDRAM的Single Write写如图5图所示,从c_state的状态可以看出一次完整的Single Write花费了11个时钟周期,根据SDRAM的时序关系,可以缩短状态C和E(状态E可以省略),至于为何可以缩短可以查相关的SDRAM芯片的数据手册可以得到各个命令的具体时间参数。

1.jpg
图5 SDRAM single Write写控制时序

修改SDRAM控制器,这里暂时保留状态E,这时候single Write控制时序如图6所示:

sys.jpg
图6 修改后建设单个写时间的控制时序

同样对于single read模式下,如图7所示,观察状态c_state,发现整个single read需要11个时钟周期,对照SDRAM时序图,可以修改逻辑使单个读减少到6个时钟,即去除图7中的状态A .

sys.jpg
图7 SDRAM single read模式下修改前时序关系

图8是修改后的SDRAM单个读时序图,此时没有状态A了 :

1.jpg
图8 修改控制器后SDRAM单个读时序图

 

文章评论9条评论)

登录后参与讨论

coyoo 2015-7-30 09:05

1、FIFO使用的是系统时钟,不是TCK;所以设计存在多时钟域处理。 2、你的理解是对的。因为这个设计简单,所以fifo的写就简单控制。 3、读的时候,由于存在从fifo的clk到JTAG的TCK跨越,所以需要进行跨时钟域控制,也就是要根据TCL的控制命令产生读fifo的控制,即产生握手信号后产生fifo的读控制信号。

用户1738735 2015-7-29 22:35

又要再次打扰Co大了,想请教几个您文章中关于TCL控制FIFO的问题: 1. FIFO是FPGA内部生成的,由FPGA内部控制,TCL仅发送读写命令,那FIFO的时钟是FPGA分频产生的吗?还是说用的tck? 2. 如果是FPGA产生的,那TCL在发送写命令时,FPGA将wrreq置高,数据被源源不断由FPGA写入FIFO,写满为止,这个还算方便实现,不知这个理解是否您文章中的意思? 3. 是在将读取FIFO数据保存至txt文档中,发送读命令,rdreq被置高时,每个读CLK都会产生一个数据,但TCL脚本并不一定有足够快的速度将上一次读取的值存储到txt文本中,就可能造成数据遗漏现象,FIFO又不能像RAM一样,可以在确定读取出一个数据后在控制地址加1,难道是预估算FIFO写入一次的时间调整FIFO的读CLK?不知前辈是如何解决的,望前辈指点一二。

用户1738735 2015-7-24 11:28

非常感谢,测试成功了,虽然还有许多小问题,但总算看到Virtual JTAG的大门了,再次感谢Co大的指点

coyoo 2015-7-24 09:05

这个命令需要在dos命令行下执行。从Windows开始菜单下找到“运行”,执行cmd调出命令行

用户1738735 2015-7-23 17:06

感谢Co的耐心解答,通过学习Tcl Scripting了解了后缀名的含义,但是quartus_stp.exe这个执行程序我始终还是无法进入呢,到Quartus 13.1的安装目录下双击这个应用程序,出来个黑色窗口,然后就出现7排左右的文字就闪退了,根本不等我输入指令,不知道这是个什么情况呢,还是说应该用Quartus调用这个应用程序呢?如果用Quartus调用不知道什么菜单可以调出quartus_stp运行环境呢?

coyoo 2015-7-23 08:52

正常的使用应该是: quartus_stp -t vjgui_sep.tcl quartus_stp -s 后面要带参数,具体参数意义,留给你自己研究,就当给你的一个作业。

用户1738735 2015-7-22 10:52

非常感谢Co大的解答,昨天看了您的另一篇博文才发现Quartus 13.1不能在TCL Console中运行了,然后尝试打开quartus_stp,可是每每打开quartus_stp就迅速被关闭了,下载了您的gui_yd也是一打开就迅速关闭了,一头雾水,只好先按照Tcl Scripting中的例子学习,在TCL Console中运行quartus_fit --tcl_eval help,又再次报错,还在继续学习Tcl Scripting,好想尽快尝试出一个可以正常以Tcl运行出的工程,不知道Co大能否推荐个带操作步骤的例程呢?

coyoo 2015-7-22 09:01

这个问题,其实在错误提示中告诉你原因了,即"get_hardware_names" 命令仅在特定的解析工具中才能使用;它不能直接在TCL Console中直接运行,可以在quartus_stp下运行。

用户1738735 2015-7-21 22:28

酷大,目前想学习下Virtual JTAG,根据您写的文章做了一个尝试,但是在Tcl的刚入门阶段就过不去了呢,我在Tcl Console里面输入 puts "Programming Hardwares:" foreach hardware_name [get_hardware_names] { puts $hardware_name if { [string match "USB-Blaster*" $hardware_name] } { set usbblaster_name $hardware_name } }这个语句后就会出现错误, Error:ERROR: Quartus II Tcl command "get_hardware_names" is only available for use in the following executables: Error: quartus_sh Error: quartus_stp Error: while executing Error:"get_hardware_names" Error: invoked from within Error:"foreach hardware_name [get_hardware_names] {puts $hardware_name if { [string match "USB-Blaster*" $hardware_name] } {set usbblaster_name $hardware_nam..." 折腾了好久,只用Tcl脚本文件自动分配过FPGA引脚,还在学习中,网上这方面的问题也搜不出结果,不知道前辈能否帮忙解决个疑惑,非常感谢!
相关推荐阅读
coyoo 2024-12-03 12:20
比较器检测模拟脉冲说明(四)
概述 说明(三)探讨的是比较器一般带有滞回(Hysteresis)功能,为了解决输入信号转换速率不够的问题。前文还提到,即便使能滞回(Hysteresis)功能,还是无法解决SiPM读出测试系统需要解...
coyoo 2024-11-16 13:54
不同ADC采样同一前端模拟信号时转换用时差异分析
概述 同一组前端模拟信号接入由不同型号ADC组成的模数转换电路时,采样后在FPGA中发现采样用时差异较大。本文主要分析这个时间差异形成的原因,并记录该差异产生对系统造成的影响。系统数字化简介 项目前端...
coyoo 2024-11-10 13:04
ALTERA Cyclone 10器件的使用-7:FPGA片内RAM资源利用率思考
概述 项目使用的FPGA目标器件为Cyclone 10 GX系列规模最大一颗料,由于功能升级增加了功能模块更多,发现器件片内RAM不够使用了。为了探索片内RAM使用的利用率问题,从代码RTL级与编译软...
coyoo 2024-11-10 12:30
转知乎:幽灵般的人体成像技术-PET
幽灵般的人体成像技术——PET - 知乎...
coyoo 2024-11-09 10:26
AD9633默认情况下调试记录(二)
概述 所谓默认情况,即如器件手册中图2所标示那样。对应AD9633的调试,除了涉及到ADC自身,还需要兼顾前端驱动器,系统中AD9633驱动器使用了差分运算放大器,这里不在赘述,笔者已有相关文章论述。...
coyoo 2024-11-07 10:40
AD9633默认情况下调试记录(一)
AD9633在旁路SPI接口时如何在FPGA逻辑中确认字边界概述 AD9633与FPGA之间的LVDS接口初调试,ADC可以通过SPI接口对其内部寄存器进行各项配置。在SPI接口未调通之前,对LVDS...
我要评论
9
15
关闭 站长推荐上一条 /2 下一条