riple

Stay Hungry, Stay Foolish.

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

0
阅读(6537)

三、 Tcl命令的使用。

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

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

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

#### 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

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

1. 真实jtag操作。

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

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

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

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

2. 虚拟jtag操作。

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

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

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

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

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

Baidu
map