福利!
之前有写过一篇关于JTAG Master工具的使用文档,但是tcl复杂的命令让很多初学者感到困难。
这里使用tcl脚本做了一个调试界面。即使对tcl一点都不了解,也可以通过该界面方便的进行FPGA寄存器的调试。
由于CSDN博客不太方便上传附件,这里直接贴源码。大家把代码保存后,另存为mem_test.tcl文件即可。
使用方法在文章末尾。
########################################################################
### TCL GUI For Memory/Register Test ###
### Author : Arth Ding ###
### E-mail : 903201008@qq.com ###
### Date : 2016/12/1 ###
########################################################################
namespace eval FEM_gui {
proc add_combo_entry {dash group handle label_text tooltip combo_entries default_entry onchange} {
dashboard_add $dash $handle group $group
dashboard_set_property $dash $handle title ""
dashboard_set_property $dash $handle itemsPerRow 2
dashboard_add $dash ${handle}_label label $handle
dashboard_set_property $dash ${handle}_label text $label_text
dashboard_set_property $dash ${handle}_label preferredWidth 20
dashboard_set_property $dash ${handle}_label toolTip $tooltip
dashboard_add $dash ${handle}_entry comboBox $handle
dashboard_set_property $dash ${handle}_entry options $combo_entries
dashboard_set_property $dash ${handle}_entry selected $default_entry
dashboard_set_property $dash ${handle}_entry preferredWidth 100
dashboard_set_property $dash ${handle}_entry onChange $onchange
dashboard_set_property $dash ${handle}_entry toolTip $tooltip
}
proc add_text_entry {dash group handle label_text tooltip default_value onchange} {
dashboard_add $dash $handle group $group
dashboard_set_property $dash $handle title ""
dashboard_set_property $dash $handle itemsPerRow 2
dashboard_add $dash ${handle}_label label $handle
dashboard_set_property $dash ${handle}_label text $label_text
dashboard_set_property $dash ${handle}_label preferredWidth 20
dashboard_set_property $dash ${handle}_label toolTip $tooltip
dashboard_add $dash ${handle}_entry textField $handle
dashboard_set_property $dash ${handle}_entry text $default_value
dashboard_set_property $dash ${handle}_entry toolTip $tooltip
dashboard_set_property $dash ${handle}_entry preferredWidth 100
}
variable jd_path
set jd_path 0
variable PaddingType
set PaddingType 0
variable writedata
set writedata 0
set dash [add_service dashboard dashboard_example "Memory Debug GUI" "Tools/Example"]
dashboard_set_property $dash self visible true
set TestLength 1000
dashboard_set_property $dash self itemsPerRow 2
dashboard_set_property $dash self foregroundColor blue
dashboard_add $dash mytabGroup tabbedGroup self
dashboard_set_property $dash mytabGroup expandableX true
dashboard_set_property $dash mytabGroup expandableY true
dashboard_add $dash tabgeneralGroup group mytabGroup
dashboard_set_property $dash tabgeneralGroup title "General"
dashboard_set_property $dash tabgeneralGroup itemsPerRow 2
dashboard_set_property $dash tabgeneralGroup expandableX true
dashboard_add $dash tuningGroup1a group tabgeneralGroup
dashboard_set_property $dash tuningGroup1a title "Demo Start"
dashboard_set_property $dash tuningGroup1a expandableX true
dashboard_set_property $dash tuningGroup1a expandableY true
dashboard_set_property $dash tuningGroup1a itemsPerRow 2
dashboard_add $dash dialsGroup group tabgeneralGroup
dashboard_set_property $dash dialsGroup title "Test Status"
dashboard_set_property $dash dialsGroup itemsPerRow 2
dashboard_set_property $dash dialsGroup expandableY true
dashboard_set_property $dash dialsGroup expandableX true
dashboard_add $dash EtherCATReg group tabgeneralGroup
dashboard_set_property $dash EtherCATReg title "Memory Access"
dashboard_set_property $dash EtherCATReg itemsPerRow 2
dashboard_set_property $dash EtherCATReg expandableY true
dashboard_set_property $dash EtherCATReg expandableX true
dashboard_add $dash dial0 dial dialsGroup
dashboard_set_property $dash dial0 expandableX false
dashboard_set_property $dash dial0 expandableY false
dashboard_set_property $dash dial0 title "Pcocess rate (%)"
dashboard_set_property $dash dial0 min 0
dashboard_set_property $dash dial0 max 100
dashboard_set_property $dash dial0 tickSize 5
dashboard_set_property $dash dial0 value 0
dashboard_set_property $dash dial0 preferredHeight 200
dashboard_set_property $dash dial0 preferredWidth 290
dashboard_add $dash tuningStatusGroup group dialsGroup
dashboard_set_property $dash tuningStatusGroup title "Status"
dashboard_set_property $dash tuningStatusGroup preferredWidth 300
dashboard_set_property $dash tuningStatusGroup expandableX false
dashboard_set_property $dash tuningStatusGroup expandableY false
dashboard_set_property $dash tuningStatusGroup itemsPerRow 1
dashboard_add $dash tuningGroup1b button tuningGroup1a
dashboard_set_property $dash tuningGroup1b text "Connect JTAG"
dashboard_set_property $dash tuningGroup1b onClick {::FEM_gui::connect 1}
add_combo_entry $dash tuningGroup1a PaddingType "Padding Type:" "The Data of Padding Type" [list random 0x5A5A5A5A increment 0x0 0xffffffff] 0 {::FEM_gui::padding_type_update PaddingType}
add_text_entry $dash tuningGroup1a TestBaseAddr "Test Base Address:" "DDR Read/Write Length" "0x0" dummy_callback
add_text_entry $dash tuningGroup1a TestLength "Test Length:" "DDR Read/Write Length" "1000" dummy_callback
add_text_entry $dash tuningStatusGroup UsedTime "Used Time :" "Used Time" "0" dummy_callback
add_text_entry $dash tuningStatusGroup ErrorNum "Error Num :" "Read/Write error num" "0" dummy_callback
dashboard_add $dash tuningGroup1d button tuningGroup1a
dashboard_set_property $dash tuningGroup1d text "Start Test"
dashboard_set_property $dash tuningGroup1d onClick {::FEM_gui::memory_test }
add_text_entry $dash EtherCATReg RegAddr "Reg Address:" "Register Address" "0x0000" dummy_callback
add_text_entry $dash EtherCATReg ReadLength "Data Length:" "Data Length" "1" dummy_callback
add_text_entry $dash EtherCATReg WriteData "Write Data :" "Write Data" "0x0" dummy_callback
dashboard_add $dash EtherCATReg1a button EtherCATReg
dashboard_set_property $dash EtherCATReg1a text "Register Write"
dashboard_set_property $dash EtherCATReg1a onClick {::FEM_gui::memory_write }
dashboard_add $dash EtherCATReg1a button EtherCATReg
dashboard_set_property $dash EtherCATReg1a text "Register Read"
dashboard_set_property $dash EtherCATReg1a onClick {::FEM_gui::memory_read }
set frame_send_sum 0
set connected 0
proc connect {a} {
variable connected
variable dash
if {$connected == 0} {
set devices [ get_service_paths device]
set device [lindex $devices 0]
set masters [get_service_paths master]
set j 0
set found_master 0
foreach master $masters {
#alternative method to get info on master type
if [regexp -nocase {usb_debug_master_0.([a-z0-9_]+)} $master mstrall mstr1] {
send_message info "Connecting to USB Master $master"
set found_master 1
break;
}
incr j
}
if {$found_master == 0} {
foreach master $masters {
#alternative method to get info on master type
if [regexp -nocase {jtag_master.([a-z0-9_]+)} $master mstrall mstr1] {
send_message info "Connecting to JTAG Master $master"
set found_master 1
break;
} elseif [regexp -nocase {phy_[0-9]/master} $master mstrall mstr1] {
send_message info "Connecting to JTAG Master $master"
set found_master 1
break;
} elseif [regexp -nocase {alt_jtagavalon_wrapper_[0-9]} $master mstrall mstr1] {
send_message info "Connecting to JTAG Master $master"
set found_master 1
break;
} elseif [regexp -nocase {jtagmem_[0-9]} $master mstrall mstr1] {
send_message info "Connecting to JTAG Master $master"
set found_master 1
break;
}
incr j
}
}
set ::FEM_gui::jd_path $master
send_message info "Connecting to JTAG Master $master"
open_service master $::FEM_gui::jd_path
set connected 1
dashboard_set_property $dash tuningGroup1b text "Disconnect JTAG"
} else {
close_service master $::FEM_gui::jd_path
set connected 0
dashboard_set_property $dash tuningGroup1b text "Connect JTAG"
}
}
proc memory_read {} {
variable dash
set regaddr [dashboard_get_property $dash RegAddr_entry text]
set datalength [dashboard_get_property $dash ReadLength_entry text]
set readdata [master_read_32 $::FEM_gui::jd_path $regaddr $datalength]
puts "$readdata"
}
proc memory_write {} {
variable dash
set regaddr [dashboard_get_property $dash RegAddr_entry text]
set datalength [dashboard_get_property $dash ReadLength_entry text]
set writedata [dashboard_get_property $dash WriteData_entry text]
master_write_32 $::FEM_gui::jd_path $regaddr $writedata
}
proc memory_test {} {
#connect JTAG Master
variable dash
variable writedata
set test_cnt 0
set test_num [dashboard_get_property $dash TestLength_entry text]
set num_div100 [expr $test_num / 100]
set process_rate 0
set usedTime 0
set usedTimeOld 0
set memory_base_addr [dashboard_get_property $dash TestBaseAddr_entry text]
set readdata 0
set error_num 0
dashboard_set_property $dash UsedTime_entry text $usedTime
dashboard_set_property $dash dial0 value $process_rate
set startTime [clock seconds]
set padding_type $::FEM_gui::PaddingType
while {$test_cnt < $test_num} {
if {$padding_type == 0} {
set writedata [expr int([expr [::tcl::mathfunc::rand] * 32768 *32768])]
} elseif { $padding_type == 1 } {
set writedata 0x5A5A5A5A
} elseif { $padding_type ==2 } {
incr writedata
} elseif { $padding_type ==3 } {
set writedata 0x00000000
} elseif { $padding_type ==4 } {
set writedata 0xffffffff
}
master_write_32 $::FEM_gui::jd_path [expr $memory_base_addr + $test_cnt *4] $writedata
set readdata [master_read_32 $::FEM_gui::jd_path [expr $memory_base_addr + $test_cnt *4] 1]
if { $writedata != $readdata } {
incr error_num
}
incr test_cnt
set endTime [clock seconds]
set usedTime [expr $endTime - $startTime]
dashboard_set_property $dash UsedTime_entry text $usedTime
dashboard_set_property $dash ErrorNum_entry text $error_num
if {$test_cnt > $num_div100 * 100} {
dashboard_set_property $dash dial0 value 100
} elseif {$test_cnt % $num_div100 == 0} {
set process_rate [expr $test_cnt / $num_div100 ]
dashboard_set_property $dash dial0 value $process_rate
} else {
#do nothing
}
}
if {$error_num == 0} {
send_message info "Test Done! No Error"
}
}
proc padding_type_update {combohandle} {
variable dash
variable writedata
set padding_type [dashboard_get_property $dash ${combohandle}_entry selected]
send_message info "updating padding type to $padding_type"
set ::FEM_gui::PaddingType $padding_type
set writedata 0
}
}
------------------------------------------------------------------分割线----------------------------------------------------------------------------
使用方法:
1. 插上JTAG下载器,将带Jtag Master IP核的工程下载到FPGA,通过Quartus打开System Console,右键点击script。如下图所示。点击Open User Scripts Folder ,如果不存在该文件夹,系统会提示是否创建该文件夹,点击创建后
打开script文件夹。将保存的mem_test.tcl文件复制到script文件夹中。 点击script文件夹前面的+号展开,双击mem_test.tcl即可执行该脚本。
2. 执行脚本后打开如下界面,点击Connect JTAG。如果成功按钮会变成Unconnect JTAG。失败左侧的Message区域会报错。连接JTAG成功后,就可以直接修改Memory Access区域中的地址,长度和数据等。然后通过Register Read或者Register Write操作进行寄存器的读写。