久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 9014|回復(fù): 3
打印 上一主題 下一主題
收起左側(cè)

虛擬JTAG工具在FPGA調(diào)試中的應(yīng)用

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
本帖最后由 51黑fan 于 2016-1-31 04:16 編輯

                  最近學(xué)習(xí)了Altera的Virtual JTAG工具的使用。下面是我的使用心得。



    Altera在Quartus II 6.0中加入了一個(gè)sld_virtual_jtag 參數(shù)化宏單元模塊,并提供了相應(yīng)的Tcl程序包。有了這套工具,使用sld_virtual_jtag 和相應(yīng)的Tcl命令,我們就可以構(gòu)建自己的虛擬JTAG鏈路,并進(jìn)行自定義的JTAG調(diào)試了。

一、 相關(guān)文件

    后面的鏈接是Quartus幫助文件中的內(nèi)容,前兩個(gè)是我從Help里拷出來用Word保存的html文件,由于里面的一些鏈接指向本地文件,會(huì)被當(dāng)作危險(xiǎn)代碼,不理就是了,不是病毒。


  •     sld_virtual_jtag 的說明: sld_virtual_jtag .rar (8.96 KB, 下載次數(shù): 20) 。只給出了VHDL的例化方式,對(duì)于各個(gè)選項(xiàng)的配置給了說明。  
  •     ::quartus::jtag Tcl命令包的說明: Tcl命令包.rar (11.62 KB, 下載次數(shù): 17) 。每個(gè)命令都給了使用的例子,拷到一個(gè)空Tcl文件中,保存后用Quartus的Tcl scripts工具運(yùn)行即可。
  •   Altera提供的用戶指南:太大了傳不上來,給個(gè)鏈接,自己下吧。里面有JTAG協(xié)議的講解和兩個(gè)示例。

二、 Virtual JTAG要點(diǎn)解析

    澄清一個(gè)概念:所謂虛擬JTAG,是Altera用PLD上的硬件JTAG電路和可編程邏輯資源搭建的一個(gè)IP core。這個(gè)IP core實(shí)現(xiàn)了JTAG接口電路的功能,但本身不是硬件JTAG電路的一部分,是用可編程邏輯“虛擬”出來的。

    這個(gè)IP core有兩個(gè)接口:一個(gè)接口在布局布線時(shí)連接到硬件JTAG電路上,用戶不可見;一個(gè)接口由用戶通過電路圖或者HDL例化到代碼中,并通過這個(gè)接口自定義JTAG操作。

    這個(gè)IP core的功能 = JTAG信號(hào)hub + JTAG TAP控制器 + IR/DR IO。

    用戶看到的是虛擬JTAG電路對(duì)內(nèi)的接口,看不到硬件JTAG電路接口;并且這個(gè)接口是從JTAG TAP控制器引出的,信號(hào)方向和大家通常從外部對(duì)JTAG電路的理解不一樣,所以容易引起混淆,理解上會(huì)有一定的困難。

    用戶看到(可以利用)的接口有四組:


  • JTAG協(xié)議中的接口(TDI、TDO、TCK)。TDI是IP core的輸出;TDO是IP core的輸入;沒有TMS,這個(gè)引腳的功能被另一組接口解析并代替了;TCK是唯一沒有變化的引腳。  
  • 命令寄存器接口(IR_IN[]、IR_OUT[])。這組接口是Tcl命令和用戶邏輯交互的接口,很有用。也可用來簡(jiǎn)單地傳遞數(shù)據(jù)。  
  • 虛擬JTAG TAP控制器狀態(tài)接口(virtual_state_...)。這組接口是虛擬JTAG的狀態(tài)機(jī)輸出,一個(gè)狀態(tài)對(duì)應(yīng)一個(gè)輸出,可以看作狀態(tài)信號(hào)燈。這組信號(hào)就是TMS的解析。如果需要實(shí)現(xiàn)復(fù)雜地?cái)?shù)據(jù)傳遞功能,一定要理解這組信號(hào)的功能。  
  • 硬件JTAG TAP控制器狀態(tài)接口(jtag_state_...)。這組接口是硬件JTAG的狀態(tài)機(jī)輸出。這些功能暫時(shí)不會(huì)用,可能是用來實(shí)現(xiàn)更高級(jí)控制和數(shù)據(jù)傳遞功能的。



    理解虛擬JTAG概念的關(guān)鍵有以下兩點(diǎn):


  • 在IP core的背后有四根看不見的JTAG信號(hào),這四根信號(hào)才是我們通常從外部理解的JTAG。  
  • 看得見的TDI和TDO是兩根等待連接的信號(hào)(就像墻上插座里的兩根線),我們通過在這兩根線之間或串接或并接或簡(jiǎn)單或復(fù)雜的邏輯,實(shí)現(xiàn)我們的JTAG鏈路。

    理解了這些概念,看懂用戶指南應(yīng)該不成問題了。然后再看示例程序的verilog代碼。

    我的一個(gè)空想:如果Altera能夠把用戶不可見的硬件JTAG電路接口開放出來(用戶可見),那么用戶就可以把這個(gè)接口上的標(biāo)準(zhǔn)JTAG接口連接到PLD的引腳上,再把這組引腳連接到外部JTAG電路上,那么這個(gè)IP core就不再是“虛擬”的了。


三、 Tcl命令的使用。

    ::quartus::jtag Tcl命令包中的各條命令都有英文注釋,這里就不挨個(gè)翻譯了。

    下面,把用戶指南里給出的第一個(gè)例子逐句分析一下,后面還會(huì)給出一個(gè)模板。

    示例如下。其中只給::quartus::jtag Tcl命令包中的命令加上了綠色,其余簡(jiǎn)單的Tcl命令可以按照E文的意義理解,稍微復(fù)雜一些的Tcl命令可以參考相關(guān)書籍。為了區(qū)別原注釋,我的注釋一概用紅色標(biāo)出。


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

set loop 3

## 檢測(cè)下載電纜,從命令行輸出檢測(cè)到的下載電纜名稱。原示例只檢測(cè)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";


## 檢測(cè)下載電纜對(duì)應(yīng)的jtag鏈路,從命令行輸出檢測(cè)到的器件名稱。并選中第一個(gè)作為操作對(duì)象。##


# 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編號(hào)。需要先發(fā)送jtag命令--獲取ID,命令值是“6”。然后讀取jtag數(shù)據(jù),得到32位的ID值。##

## 由于該步驟需要兩個(gè)操作,這兩個(gè)操作之間不能插入其他操作,所以需要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               ## 發(fā)送jtag命令 6。注意:這里的jtag是真實(shí)的jtag ##
puts "IDCODE: 0x[device_dr_shift -length 32 -value_in_hex]"     ## 獲取jtag數(shù)據(jù) ##
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.

## 循環(huán)采樣數(shù)據(jù)部分 ##

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

## 設(shè)置循環(huán)參數(shù) ##
set run_script 0
while {$run_script != $loop} {
    set run_script [expr $run_script +1]
    set counter1 0
    set counter2 1

    ## 獲取采樣數(shù)據(jù) ##

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

        device_virtual_ir_shift -instance_index 0 -ir_value 1                               ## 發(fā)送virtual jtag命令 1 ##
        set counter1 [device_virtual_dr_shift -instance_index 0 -length 4 -value_in_hex]    ## 獲取virtual jtag數(shù)據(jù) ##

        device_virtual_ir_shift -instance_index 1 -ir_value 1                               ## 發(fā)送virtual jtag命令 1 ##
        set counter2 [device_virtual_dr_shift -instance_index 1 -length 4 -value_in_hex]    ## 獲取virtual jtag數(shù)據(jù) ##

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

        ## 設(shè)置延時(shí)參數(shù) ##

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

    device_unlock

##  交互輸入,設(shè)定FPGA計(jì)數(shù)器初值部分 ##


## 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 ## 發(fā)送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數(shù)據(jù) ##
    device_virtual_ir_shift -instance_index 1 -ir_value 2 -no_captured_ir_value ## 發(fā)送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數(shù)據(jù) ##
    device_unlock


}
# Close device
close_device

    如果要讀懂上述代碼,建議按照用戶指南中的步驟設(shè)置好工程,記得一定要把引腳按照自己電路板的情況分配上(可以不用LED)。先把## real jtag operation completed ##之前的代碼運(yùn)行一下,看看有什么反應(yīng)。如果反應(yīng)很好的話,那么祝賀你,你已經(jīng)克服了對(duì)jtag和Tcl的恐懼心理。

    上述代碼的組織結(jié)構(gòu)如下:

1. 真實(shí)jtag操作。

1.1 檢測(cè)電纜。(如果你用的是并口下載線,并且沒有修改原代碼的話,在這一步你就會(huì)遇到攔路虎)

1.2 查找器件。(如果你的電路板上串接了不只一個(gè)jtag器件的話,你要修改你的代碼,否則這一步也是過不去的)

1.3 打開器件。(前兩關(guān)過去了,這一步應(yīng)該不成問題)

1.4 獲得器件的jtag編號(hào)。(IDCODE命令)(個(gè)人覺得沒有什么大用處,也許可以起到初始化IR的作用)



2. 虛擬jtag操作。

2.1 循環(huán)采樣計(jì)數(shù)器值。(SAMPLE命令)(通過jtag鏈路從FPGA讀數(shù)據(jù))

2.2 設(shè)置計(jì)數(shù)器初值。(FEED命令)(通過jtag鏈路向FPGA發(fā)數(shù)據(jù))

    需要說明的是,2中的SAMPLE命令(2'b01)和FEED命令(2'b10)是用戶自定義的virtual jtag命令(隨便定,只要你的verilog代碼中是對(duì)應(yīng)譯碼的就可以),1中的IDCODE命令(在Cyclone器件中是10'b0000000110)是由Altera定義的,返回值是一組32位的二進(jìn)制數(shù)。

    把上面的代碼結(jié)合著::quartus::jtag Tcl命令包的幫助文件(我已經(jīng)給了)逐條分析一下,對(duì)于::quartus::jtag Tcl命令包的使用就沒有問題了。

    我做的一個(gè)Tcl模板 Tcl模板.rar (1.03 KB, 下載次數(shù): 12) ,根據(jù)上面代碼改的,可以檢查jtag鏈路,并由用戶選擇使用哪個(gè)器件,可以讀取一次jtag數(shù)據(jù),然后由用戶輸入一次jtag數(shù)據(jù)。如果需要循環(huán)功能,還要根據(jù)上面代碼加入Tcl命令。以后有更好的再傳上來。

四、 verilog代碼分析

    先把關(guān)鍵的verilog代碼寫在下面。完整的代碼在最后,按照我的理解和習(xí)慣,對(duì)原示例代碼的寫法作了修改。
wire [3:0] counter1;
reg   [3:0] feed_reg;     // 四位的DR寄存器,用于加載輸入值

wire tdi, tck, cdr, cir, e1dr, e2dr, pdr, sdr, udr, uir;
reg   tdo, bypass_reg;
wire [1:0] ir_in;             // 兩位的IR寄存器輸出,來自my_vji_a
wire sample = ir_in[0];  // IR譯碼,2'b01表示SAMPLE命令
wire feed   = ir_in[1];    // IR譯碼,2'b10表示FEED命令

reg [3:0] offload_reg;    // 四位的DR寄存器,用于輸出


/* instantiation of the vji mega functionc */
my_vji_a VJI_INST(
.ir_out (2'b0), // input to megafunction
.tdo (tdo),      // input to mega function

.ir_in (ir_in),   // output from mega function
.tck (tck),      // output from mega function
.tdi (tdi),        // output from mgafunction

.virtual_state_cdr (cdr), // output from mega function
.virtual_state_e1dr(e1dr), // "
.virtual_state_e2dr(e2dr), //  "
.virtual_state_pdr (pdr), //  "
.virtual_state_sdr (sdr), // "
.virtual_state_udr (udr), //  "

.virtual_state_uir (uir), //  "
.virtual_state_cir (cir)); // "

/* 1. Sample Instruction Handler */  
always @ (posedge tck)  // 針對(duì)SAMPLE指令的處理
  if ( sample && cdr )
    offload_reg <= counter1;
  else if ( sample && sdr )
    offload_reg <= {tdi, offload_reg[3:1]}; // 典型的移位寄存器操作(MSB to LSB),移位輸出counter1的當(dāng)前值

/* 2. Feed Instruction Handler */
always @ (posedge tck)  // 針對(duì)FEED指令的處理
  if ( feed && sdr )
    feed_reg <= {tdi, feed_reg[3:1]}; // 典型的移位寄存器操作(MSB to LSB),移位輸入要賦給counter1的初始值
  
/* 3. Bypass register */  // 旁路寄存器,沒有針對(duì)這個(gè)virtual_jtag的操作就旁路
always @ (posedge tck)
  bypass_reg = tdi;

/* 4. Node TDO Output */  // TDO輸出選擇器,根據(jù)IR的不同,選擇不同的信號(hào)輸出
always @ ( sample, feed, feed_reg[0], offload_reg[0], bypass_reg )
begin
  if (sample)
    tdo <= offload_reg[0];
  else if (feed)
    tdo <= feed_reg[0];   // Used to maintain the continuity of the scan chain. // 在移位輸入時(shí),也要保證jtag鏈路有輸出
  else
    tdo <= bypass_reg;
end

    上面代碼中,/* Sample Instruction Handler */之后的代碼是需要用戶自己編寫的代碼,是使用virtual_jtag的精髓所在,一定要讀懂。

    sld_virtual_jtag 的說明中把TAP控制器的狀態(tài)信號(hào)分為High level和Low level。示例代碼中使用的是High level部分的信號(hào)。High level部分的信號(hào)又可以分為DR寄存器操作對(duì)應(yīng)的一組狀態(tài)信號(hào)(6個(gè))和IR寄存器操作對(duì)應(yīng)的一組狀態(tài)信號(hào)(2個(gè))。

    1. DR寄存器操作對(duì)應(yīng)的一組狀態(tài)是:Capture_DR -> Shift_DR -> Exit1_DR -> Pause_DR -> Exit2_DR -> Update_DR。每一個(gè)狀態(tài)對(duì)應(yīng)一個(gè)*dr信號(hào)。

    對(duì)于數(shù)據(jù)輸出操作(此例中是SAMPLE命令,并行加載,串行輸出),需要在Capture_DR狀態(tài)把被采樣的信號(hào)并行加載到DR寄存器中,在Shift_DR狀態(tài)把DR寄存器串行輸出到virtual jtag鏈路的tdo引腳上(同時(shí)串行載入tdi引腳的數(shù)據(jù)),然后遍歷余下的狀態(tài)并不做任何操作。這一過程就是代碼中對(duì)offload_reg寄存器的操作。

    對(duì)于數(shù)據(jù)輸出操作(此例中是FEED命令,串行輸入,并行加載),在Capture_DR狀態(tài)不進(jìn)行任何操作直接跳轉(zhuǎn)到下一個(gè)狀態(tài),在Shift_DR狀態(tài)串行載入virtual jtag輸入的數(shù)據(jù),在Exit1_DR狀態(tài)把獲得的數(shù)據(jù)并行加載到目標(biāo)寄存器上,然后遍歷余下的狀態(tài)并不做任何操作。這一過程就是代碼中對(duì)feed_reg寄存器的操作。

    2. IR寄存器操作對(duì)應(yīng)的一組狀態(tài)是:Capture_IR -> Shift_IR -> Exit1_IR -> Pause_IR -> Exit2_IR -> Update_IR。由于virtual jtag模塊提供了并行的ir_in端口,簡(jiǎn)化了操作,所以只有首尾兩個(gè)狀態(tài)對(duì)應(yīng)*ir信號(hào)。

    在這個(gè)例子中,只用到了ir_in端口,沒有用到IR操作對(duì)應(yīng)的狀態(tài)及輸出信號(hào)。這也可以看作是virtual jtag的方便之處。

    3. bypass_reg寄存器提供了jtag鏈路的第三條通路,在沒有針對(duì)當(dāng)前virtual jtag操作的情況下,tdi數(shù)據(jù)經(jīng)過一個(gè)tck周期的延時(shí)輸出到tdo引腳。

    4. tdo引腳輸出時(shí),需要根據(jù)ir_in的取值選擇三條通路中的一條,所以這部分代碼也是需要用戶設(shè)計(jì)的。

    看懂了這個(gè)例子,對(duì)virtual jtag的基本輸出和輸入功能就掌握了。

    下圖是用lpm宏單元替換各個(gè)功能塊后編譯得到的RTL視圖。相應(yīng)的代碼可以在此 相應(yīng)的代碼.rar (4.92 KB, 下載次數(shù): 21) 下載。



評(píng)分

參與人數(shù) 1黑幣 +5 收起 理由
lucky421 + 5

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂1 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:617264 發(fā)表于 2019-9-27 23:01 | 只看該作者
好難,,之前已經(jīng)弄了一周了還是沒有搞明白。我現(xiàn)在都快要崩了。。。!
回復(fù)

使用道具 舉報(bào)

板凳
ID:83305 發(fā)表于 2019-10-13 16:04 | 只看該作者
乖乖的好難哦。不知道學(xué)進(jìn)不
回復(fù)

使用道具 舉報(bào)

地板
ID:446139 發(fā)表于 2019-12-13 10:10 | 只看該作者
很有收獲謝謝lz
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 亚洲成人久久久 | 欧洲妇女成人淫片aaa视频 | 国产精品国产a级 | 免费高清av | 午夜视频大全 | h片免费看 | 男人av的天堂 | 激情五月婷婷在线 | 四虎影院在线观看av | 天堂成人av | 狠狠操操 | 国产黄色一级电影 | 一区二区不卡视频 | 日韩精品免费在线观看 | 日韩免费视频一区二区 | 久久99精品国产 | 亚洲xx在线 | 成人免费视频网站在线观看 | av在线一区二区 | 91正在播放 | 97精品国产97久久久久久免费 | 日韩精品视频中文字幕 | 色综合99 | 一区二区中文 | 精品免费观看 | 国产精品中文字幕一区二区三区 | 国产精品色 | 日本不卡一区二区三区在线观看 | 欧美一级在线观看 | 国产亚洲成av人片在线观看桃 | 91精品国产乱码久久蜜臀 | 538在线精品 | 99热碰 | 成人免费看片又大又黄 | 一级毛片在线视频 | 五月婷婷丁香婷婷 | 欧美一区二区三区在线播放 | 黄色毛片免费 | 色噜噜狠狠色综合中国 | 久久国产福利 | 精品福利视频一区二区三区 |