原创 虚拟JTAG工具在FPGA调试中的应用(续一)

2006-11-1 19:22 7593 8 17 分类: FPGA/CPLD

三、 Tcl命令的使用。 riple


    ::quartus::jtag Tcl命令包中的各条命令都有英文注释,这里就不挨个翻译了。 riple


    下面,把用户指南里给出的第一个例子逐句分析一下,后面还会给出一个模板。 riple


    示例如下。其中只给::quartus::jtag Tcl命令包中的命令加上了绿色,其余简单的Tcl命令可以按照E文的意义理解,稍微复杂一些的Tcl命令可以参考相关书籍。为了区别原注释,我的注释一概用红色标出。 riple


 


#### Script begins ######################################################


set loop 3


## 检测下载电缆,从命令行输出检测到的下载电缆名称。原示例只检测USB下载线,我给改了。 ##


# get hardware names : get download cable name
foreach hardware_name [get_hardware_names] {
    puts "\n$hardware_name"
    if { [string match "ByteBlasterMV*" $hardware_name] } {
        set byteblaster_name $hardware_name
    }
}
puts "\nSelect JTAG chain connected to $byteblaster_name.\n";


 


## 检测下载电缆对应的jtag链路,从命令行输出检测到的器件名称。并选中第一个作为操作对象。##



# List all devices on the chain, and select the first device on the chain.
puts "\nDevices on the JTAG chain:"
foreach device_name [get_device_names -hardware_name $byteblaster_name] {
    puts $device_name
    if { [string match "@1*" $device_name] } {
        set test_device $device_name
    }
}
puts "\nSelect device: $test_device.\n";


 


## 打开器件 ##



# Open device
open_device -hardware_name $byteblaster_name -device_name $test_device


 


## 获得器件的jtag编号。需要先发送jtag命令--获取ID,命令值是“6”。然后读取jtag数据,得到32位的ID值。##


## 由于该步骤需要两个操作,这两个操作之间不能插入其他操作,所以需要lock一下。##



# Retrieve device id code.
# IDCODE instruction value is 6; The ID code is 32 bits long.


# IR and DR shift should be locked together to ensure that other applications
# will not change the instruction register before the id code value is shifted
# out while the instruction register is still holding the IDCODE instruction.
device_lock -timeout 10000
device_ir_shift -ir_value 6 -no_captured_ir_value               ## 发送jtag命令 6。注意:这里的jtag是真实的jtag ##
puts "IDCODE: 0x[device_dr_shift -length 32 -value_in_hex]"     ## 获取jtag数据 ##
device_unlock


## real jtag operation completed ##


## 以下是virtual jtag的操作 ##



# SAMPLE instruction samples a 8-bit bus; the captured value shows the number of sample performed.
# FEED instruction supplies a 8-bit value to the logic connected to this instance.
# Both data registers corresponding to the IR are 8 bit wide.


## 循环采样数据部分 ##


# Send SAMPLE instruction to IR, read captured IR for the sampling number.
# Capture the DR register for the current sampled value.


## 设置循环参数 ##
set run_script 0
while {$run_script != $loop} {
    set run_script [expr $run_script +1]
    set counter1 0
    set counter2 1


    ## 获取采样数据 ##


    device_lock -timeout 10000
    while {$counter1!=$counter2} {


        device_virtual_ir_shift -instance_index 0 -ir_value 1                               ## 发送virtual jtag命令 1 ##
        set counter1 [device_virtual_dr_shift -instance_index 0 -length 4 -value_in_hex]    ## 获取virtual jtag数据 ##


        device_virtual_ir_shift -instance_index 1 -ir_value 1                               ## 发送virtual jtag命令 1 ##
        set counter2 [device_virtual_dr_shift -instance_index 1 -length 4 -value_in_hex]    ## 获取virtual jtag数据 ##


        puts "Value of {counter2,counter1} is <$counter2,$counter1>"


        ## 设置延时参数 ##


        set delay 0
        while {$delay != 120000} {
            set delay [expr $delay+1]
        }
        puts ""
    }


    device_unlock


##  交互输入,设定FPGA计数器初值部分 ##



## instead of stopping at the equal value, force a value of supplied by the user in both  counters and then end.
# Send FEED instruction to IR, read a two-digit hex string from the console,
# then send the new value to the DR register.
    puts "\nType in a digit in hexadecimal to update the contents of the counters:"
    gets stdin update_value
    set update_value2 [expr $update_value+1]



    device_lock -timeout 10000
    device_virtual_ir_shift -instance_index 0 -ir_value 2 -no_captured_ir_value ## 发送virtual jtag命令 2 ##
    device_virtual_dr_shift -instance_index 0  -length 4 -dr_value $update_value -value_in_hex -no_captured_dr_value ## 获取virtual jtag数据 ##
    device_virtual_ir_shift -instance_index 1 -ir_value 2 -no_captured_ir_value ## 发送virtual jtag命令 2 ##
    device_virtual_dr_shift -instance_index 1  -length 4 -dr_value $update_value2 -value_in_hex -no_captured_dr_value ## 获取virtual jtag数据 ##
    device_unlock



}
# Close device
close_device


    如果要读懂上述代码,建议按照用户指南中的步骤设置好工程,记得一定要把引脚按照自己电路板的情况分配上(可以不用LED)。先把## real jtag operation completed ##之前的代码运行一下,看看有什么反应。如果反应很好的话,那么祝贺你,你已经克服了对jtag和Tcl的恐惧心理。 riple


    上述代码的组织结构如下: riple


1. 真实jtag操作。 riple


1.1 检测电缆。(如果你用的是并口下载线,并且没有修改原代码的话,在这一步你就会遇到拦路虎) riple


1.2 查找器件。(如果你的电路板上串接了不只一个jtag器件的话,你要修改你的代码,否则这一步也是过不去的) riple


1.3 打开器件。(前两关过去了,这一步应该不成问题) riple


1.4 获得器件的jtag编号。(IDCODE命令)(个人觉得没有什么大用处,也许可以起到初始化IR的作用) riple


 


2. 虚拟jtag操作。 riple  riple


2.1 循环采样计数器值。(SAMPLE命令)(通过jtag链路从FPGA读数据) riple


2.2 设置计数器初值。(FEED命令)(通过jtag链路向FPGA发数据) riple


    需要说明的是,2中的SAMPLE命令(2'b01)和FEED命令(2'b10)是用户自定义的virtual jtag命令(随便定,只要你的verilog代码中是对应译码的就可以),1中的IDCODE命令(在Cyclone器件中是10'b0000000110)是由Altera定义的,返回值是一组32位的二进制数。 riple


    把上面的代码结合着::quartus::jtag Tcl命令包的帮助文件(我已经给了)逐条分析一下,对于::quartus::jtag Tcl命令包的使用就没有问题了。 riple


    我做的一个Tcl模板rar,根据上面代码改的,可以检查jtag链路,并由用户选择使用哪个器件,可以读取一次jtag数据,然后由用户输入一次jtag数据。如果需要循环功能,还要根据上面代码加入Tcl命令。以后有更好的再传上来。 riple

PARTNER CONTENT

文章评论9条评论)

登录后参与讨论

coyoo 2009-8-13 11:50

上午拿你的例子,即老版ug的第一个例子,直接quartus_stp -t *.tcl 是可行的。新版ug例子的tcl中仅仅使用了proc例如:proc push {value},好像就不行了。

coyoo 2009-8-13 10:13

喔,这里回复怎么不能编辑啊。 上面是一个tcl例子,在bat中加入 quartus_stp -t *.tcl quartus_stp -s 两句,发现该tcl似乎没有执行,还是需要source一下

coyoo 2009-8-13 10:11

set usbblaster [lindex [get_hardware_names] 0] set device_name [lindex [get_device_names -hardware_name $usbblaster] 0] #IR scan codes: 001 -> push # 010 -> pop # 011 -> flush # 100 -> reset # 111 -> normal proc push {value} { global device_name usbblaster open_device -device_name $device_name -hardware_name $usbblaster if {$value > 256} { return "value entered exceeds 8 bits" } set push_value [int2bits $value] set diff [expr {8 - [string length $push_value]%8}] if {$diff != 8} { set push_value [format %0${diff}d$push_value 0] } puts $push_value device_lock -timeout 10000 device_virtual_ir_shift -instance_index 0 -ir_value 1 -no_captured_ir_value device_virtual_dr_shift -instance_index 0 -dr_value $push_value -length 8 -no_captured_dr_value device_unlock close_device } proc pop {} { global device_name usbblaster variable x open_device -device_name $device_name -hardware_name $usbblaster device_lock -timeout 10000 device_virtual_ir_shift -instance_index 0 -ir_value 2 -no_captured_ir_value set x [device_virtual_dr_shift -instance_index 0 -length 8] device_unlock close_device puts $x } proc flushfifo {} { global device_name usbblaster open_device -device_name $device_name -hardware_name $usbblaster device_lock -timeout 10000 device_virtual_ir_shift -instance_index 0 -ir_value 3 -no_captured_ir_value device_virtual_ir_shift -instance_index 0 -ir_value 7 -no_captured_ir_value device_unlock close_device } proc end {} { close_device } proc int2bits {i} { set res "" while {$i>0} { set res [expr {$i%2}]$res set i [expr {$i/2}] } if {$res==""} {set res 0} return $res } proc bin2hex bin { ## No sanity checking is done array set t { 0000 0 0001 1 0010 2 0011 3 0100 4 0101 5 0110 6 0111 7 1000 8 1001 9 1010 a 1011 b 1100 c 1101 d 1110 e 1111 f } set diff [expr {4-[string length $bin]%4}] if {$diff != 4} { set bin [format %0${diff}d$bin 0] } regsub -all .... $bin {$t(&)} hex return [subst $hex] }

coyoo 2009-8-13 09:51

加pause只是停顿一下,“按任意键继续”以后就推出shell了,:(。

ash_riple_768180695 2009-8-12 11:25

把这句话写到bat里:quartus_stp -t my_jtag.tcl 。最好再添加一个pause在后面,便于调试。

coyoo 2009-8-12 11:10

谢谢,另外还有一个问题,就是tcl文件的执行除了在QII的consol以及通过command shell下用source命令执行以外。能不能直接写bat文件实现?我试了一下,似乎找不到这样的选项。只能先quartus_stp -s进入tcl shell,然后source *.tcl来实现,这样必须需要两步。

ash_riple_768180695 2009-8-11 16:50

应该可以,可以查找并输出所有的*Blaster为列表,然后由用户自己选择一个。

coyoo 2009-8-11 16:35

有没有可能让tcl自适应下载电缆?

ash_riple_768180695 2006-11-2 09:31

推荐一个很好的网站:http://www.fpga4fun.com/JTAG.html
相关推荐阅读
ash_riple_768180695 2015-12-18 11:06
学习示例程序:FPGA快速系统原型设计--敏捷实践
        学习与开发板配套的示例程序,是敏捷实践的起点。示例程序是厂商针对开发板上提供的硬件资源和接口量身定做的工程,可以展示其FPGA芯片的功能和性能特点。从示例程序入手最大的好处就是:示...
ash_riple_768180695 2015-11-03 16:46
开发板选取:FPGA快速系统原型设计--敏捷实践
    既然是“实践”,就不能只谈编码和仿真,必须要上板运行、调试。这个虚拟项目的目标是实现一块兼容Intel82574L以太网控制器的千兆网卡,需要运行在一块具备PCIe接口和10/100/10...
ash_riple_768180695 2015-10-22 12:41
开篇:FPGA快速系统原型设计--敏捷实践
    虽然借用了 “系统原型开发”的标题,本系列文章将围绕FPGA IP级别的开发这个主题展开,如果可能的话,将扩展至FPGA System级别的开发。     先上一篇PPT:RSPwFP...
ash_riple_768180695 2013-08-26 10:21
学习SystemVerilog(二)——学习它的理由
    学习SystemVerilog的理由也很多,我在阅读SystemVerilog for Design 和 SystemVerilog for Verification两本书前言的过程中,总...
ash_riple_768180695 2013-08-26 10:19
学习SystemVerilog(一)——不学习它的理由
    想要学习SystemVerilog已经很久了。曾经尝试通过Accellera网站上给出的LRM学习,怎奈内容众多,找不出入手点和重点,只能望而却步。虽然手头有三本SystemVerilog...
ash_riple_768180695 2011-06-26 23:20
Hardware-Assisted IEEE1588 Implementation Analysis
06/18/11 11:00:05 PM         最近一段时间在研究IEEE1588-2008精确时间同步协议(PTP)。该协议可以在软件中实现,如果需要提高时间同步...
EE直播间
更多
我要评论
9
8
关闭 站长推荐上一条 /3 下一条