參考博文:http://www.lujun.org.cn/
1,indago系列工具介紹
indago工具,是cadence工具,推出的一系列debug工具。在啟動simvision工具時,就會彈出一個窗口,里面就提到了indago工具。
這套工具,非常的強大,但是就是網上介紹的資料不多。因為,有很多人,都不知道這個工具。
主要包括3個工具:
-
debug analyzer app
-
protocol debug app
-
embedded software debug app,簡稱eswd工具
這三個工具,我只用過debug analyzer app(之后,均簡稱為indago)和eswd,這兩個工具,后面,就對這個兩個工具進行詳細的介紹。
對於indago,主要用來debug uvm驗證環境,會非常有用,當然也可以用來debug RTL。因為該工具,可以查看仿真過程中任意時刻的仿真狀態。除了可以往后單步,還能往前單步。因為需要在仿真過程中,將整個仿真過程給記錄,因此帶來的一個問題,就是造成仿真速度較慢。
而eswed工具,我認為是針對cpu,最強的軟件debug工具。該工具,可以將cpu執行的trace流(需要自己開發monitor,從RTL中,將cpu的執行流抓出來),和elf程序,進行一一對應,並且還能和波形進行對應,讓我們可以清晰的指導,cpu在每個時刻,在執行什么程序,以及當前的cpu狀態。
2,如何產生indago database
首先介紹下indago工具,也就是debug analyzer app。
在debug uvm驗證環境時,我們一般是通過增加打印,然后仿真,根據仿真打印的log,來確定問題。如果打印加得不夠,還得修改源代碼,增加代碼代碼。
有了indago工具之后,就再也不需要在環境中,增加額外的打印代碼。因為indago工具,可以查看仿真時刻的任意狀態。
那indago是如何實現的了?其中的關鍵,就在於,使用irun工具仿真的時候,需要產生indago database,將仿真過程中的信息,給記錄下來。最后使用indago工具,載入這個database,實現信息的回看。
下面,就說一下,如何生成這個indago database。
一、編譯階段
在編譯階段,要加入如下三個選項:
-
-ida: 使能indago debug analyzer。 如果使用xrun工具,不需要加該選項。
-
-linedebug:支持代碼行調試,必加
-
-uvmlinedebug: 支持uvm庫代碼行調試,可選
二、仿真階段
在仿真階段,需要加入 +UVM_HYPERLINKS=ON 選項,和-input run.tcl 選項,來指定仿真所需要的tcl文件。
在run.tcl中,可以精細化的控制indago database生成。因為產生indago database會降低仿真速度,因此需要使用run.tcl,來精細化控制,database的生成過程。
下面是一個參考的run.tcl腳本。
1
2
3
|
ida_probe -log -sv_flow -uvm_reg -log_objects -sv_modules -wave -wave_probe_args=
"top_tb -depth all –all memories"
run
exit
|
三、ida_probe命令
ida_probe,指定database中記錄產生的數據。
這個命令很重要,因為后面indago能回看的數據,完全是由這個命令,來指定的。比如,ida_probe,指定了database要記錄波形,那么將來在indago工具中,才可以看到波形。
下圖,是ida_probe命令的說明:
這里,說明一下這個命令的一些常用選項:
1、-start_time/-end_time
指定database記錄仿真狀態的起始時間和結束時間。主要用來,記錄關鍵一段仿真過程的狀態。
2、-log
記錄打印的信息
3、-log_objects
記錄打印信息中的,動態對象。
4、-uvm
記錄uvm package信息。如果使用這個選項,需要編譯帶上 –linedebug 選項。
開啟這個選項,會將uvm的基類,比如uvm_test,uvm_env等這些基類進行記錄,這樣將來在indago工具中,可以在這些基類中,回看仿真過程。
如果不關心uvm基類的底層過程,可以不用加這個選項。
5、-uvm_reg
記錄uvm_reg的信息,需要在編譯選項,加入 –uvmlinedebug。當uvm環境中,有uvm寄存器模型,需要將該選項加上。
6、-wava/-wave_probe_args=xxx
-wave開啟波形記錄。 -wave_probe_args,指定波形記錄的形式。xxx參數,是傳遞給probe的參數。
對於probe命令,其說明如下:
如-wave_probe_args= "dut_top -depth all –all memories",表示記錄dut_top模塊的內部信號波形,以及該模塊之下所有模塊的內部波形。因為還有-all選項,因此還會記錄memory的波形。
7、-sv_files
允許記錄systemverilog文件
8、-sv_flow
允許記錄systemverilog信息
9、-sv_modules
允許記錄systemverilog的module信息。默認為是不記錄systemverilog的module信息的。
10、-sv_packages= "pkg"
記錄指定systemverilog package的信息
11、-include_build_phase
記錄systemverilog flow中,build phase的信息。默認為uvm,不記錄build phase的信息,如果想要記錄,需要加入這個選項。
12、-ignore_sv_files= "files"
不記錄,指定的sv文件。可以使用匹配表達式
13、-ignore_sv_instances= "insts"
不記錄,指定的sv的模塊。
-ignore_sv_instances= "top.router",不記錄top下router模塊的信息。top.router必須是module,而不能是動態對象(比如class對象)。
14、-ignore_sv_packages= "pkgs"
不記錄,指定的systemverilog package信息。
15、-ignore_sv_functions= "functs"
不記錄,指定systemverilog的function和task。
例如,-ignore_sv_functions= "bar*" ,不記錄bar開頭的函數和任務
16、例子
1
|
ida_probe –log –sv_flow –ignore_sv_packages=
"cdn_gpio cdn_mem"
|
表示,記錄log,以及systemverilog,但是不記錄cnd_gpio和cdn_mem這2個package。
1
|
ida_probe –log –start_time=100ns –end_time=20000ns –wave –wave_probe_args=
"dut_top –depth all"
|
表示,記錄從100ns開始,200000ns結束,在這一段時間中,記錄log,和波形,波形記錄dut_top模塊以及這個模塊之下的所有信息。
17、ida_probe命令小結
因為使用ida_probe之后,會降低仿真速度,因此需要合理的使用提供的選項,記錄關鍵的信息。而不是全記錄。
比如不需要記錄RTL波形,那么就不要加-wave選項。
比如,關心一段時間的仿真狀態,那么就要使用-start_time/-end_time,這兩個選項。來限定記錄的時間。
四、indago啟動
通過run.tcl腳本,指定產生database的信息。irun工具仿真完畢后,會在當前目錄下,生成ida.db文件夾。
直接使用indago命令,啟動indago工具,indago會自動載入ida.db文件夾內容。
界面如下所示:
3,indago工具的使用
啟動indago工具之后,indago的界面,如下圖所示:
下面,就介紹一些,indago的炫酷技能。
一、smartlog
smartlog,顯示log,並且可以將打印的一行log,和仿真狀態進行關聯。
在每行log的開頭,有一個向前或者向后的按鈕,點擊,表示,將仿真狀態,定義到這一時刻,此時,代碼窗口,顯示打印這行log的代碼處。
在smartlog的界面,可以配置,打印log的verbosity級別,以及log的類型。便於查看自己想要看的log。
在代碼處,右鍵,選擇add smartprint to log。
輸入想打印的變量,然后選擇時間范圍,如果不選擇,就默認為整個仿真時間,在設置打印的verbosity。
點擊add之后,就會發現神奇的一幕出現了。
在smartlog界面,會將代碼被調用的時刻,把設置的變量全部打印出來。這就意味着,將來再也不需要在環境中,增加額外的打印代碼,來幫助調試了。
二、代碼區
在代碼區,可以查看代碼,包括RTL和tb,都可以。
如果代碼行,前面有向前或者向后的按鈕,表示,這行代碼,在仿真過程中,有執行過,可以點擊按鈕,將當前的仿真狀態,恢復到執行這一行代碼的狀態。
上圖中的紅色框的按鈕,是控制仿真過程的按鈕,可以執行:
-
向前單步
-
向后單步
-
向前跳過
-
向后跳過
indago的一個很炫酷的功能,是可以支持向后跳轉,也就是我們可以知道,當前仿真狀態的前一個仿真狀態是什么。
點擊左上角的 Files,可以加載指定的文件。
文件前面的黃色標志,表示,當前仿真狀態在執行這個文件。代碼行前的黃色標志,表示當前仿真狀態,要執行這一行代碼。
如果打開,variable界面,那么在該界面,會自動顯示各個變量的值。
三、top界面
在top界面,可以查看design和test bench的代碼。對於rtl代碼,可以選擇信號,加入到波形中。
在波形窗口中,對波形信號,雙擊,會跳轉到rtl代碼中,並且將仿真狀態,切換到該波形時刻。
四、active threads
在active threads窗口,點擊刷新按鈕,可以查看激活的線程,有哪一些。選擇任意一個線程,就可以跳轉到代碼處。
五、call stack
call stack界面,用來查看調用棧,也就是函數的調用關系層次是怎么樣的。
對於my_driver中的driver_one_pkt函數,是由my_driver中的main_phase函數調用的。
六、diagnostics
診斷窗口,會顯示,在產生indago database過程中,影響仿真速度的一些文件和代碼。
從該界面中,可以知道哪些文件影響了仿真速度,如果該文件,對查看狀態不影響,可以在ida_probe命令中,將這個文件ingore掉。從而提高仿真速度。
七、總結
該工具,還有其他的一些功能,這個就需要大家自己去使用的時候,研究了。這里,只是給大家簡單介紹indago工具的使用。
總的來說,indago工具,根據仿真得到的database,以圖形化界面呈現給我們,讓我們能夠回看仿真的任意時刻狀態,從而方便我們去debug。
4,仿真加速indago database
indago工具很強大,對於debug環境,非常好用。但是因為仿真過程中,會產生indago database,而database,會記錄仿真的所有狀態,因此必然就會造成仿真速度慢。如果環境非常復雜,那么仿真速度會奇慢無比。
因此,就需要一些手段,來限制indago database的生成,不能記錄仿真所有的狀態,而是記錄關鍵的狀態,以提高仿真速度。
indago database的產生,是依賴於仿真執行的sim.tcl文件中的ida_probe命令,來指定的,因此就需要在這個命令上,做些文章。
一、去掉-log選項
-log選項,會將仿真打印的log,和代碼以及仿真狀態進行關聯。這個feature,在熟悉環境的時候,其實是不需要的,因為我們知道,打印的log,是在什么地方打印的。因此可以考慮去掉。以提高仿真速度。
二、去掉-wave
我們一般使用verdi工具,查看波形,因此將-wave選項去掉,database中不產生波形。
三、-ignore_sv_instances="dut頂層的層次"
RTL的波形,可以在verdi工具中查看,因此也不需要在indago database中,記錄rtl的狀態,直接將rtl從頂層到底層,都給ignore掉,均不記錄。
四、-ignore_sv_files="files"
對於一些不關心的文件,通過-ingore_sv_files選項,將這些文件,也ignore掉,不記錄。
五、-uvm –uvm_reg
如果不調試底層的UVM代碼,那么去掉-uvm選項。如果環境中,沒有register model,去掉-uvm_reg選項。
六、總結
因為indago工具,仿真過程會產生database,降低了仿真速度。為了不讓仿真速度太慢,需要我們自己控制,產生database的記錄條件。
5,最強cpu debug工具-eswd
我們在編寫c程序,在調試的時候,希望能夠使用visual studio工具,或者eclipse工具,實現單步調試,讓我們能夠查看c程序的執行狀態,從而幫助我們去調試我們寫的c程序。
那在soc驗證或cpu core驗證(以下簡稱core驗證)的時候。我們也是寫了c程序(或者匯編程序,以下不區別),在驗證環境中運行,怎么能夠知道程序在core上的執行結果呢?我們也希望能有像eclipse這樣的工具,能夠通過IDE工具,能夠知道程序的執行過程以及執行結果。
這個時候,indago中的embedded software debug app(以下簡稱eswd)工具橫空出世,解決了上述問題。
一、eswd工具
首先上圖,以下是eswd的界面。cpu的名字,叫xxx。支持aarch64和aarch32兩種arm架構指令集。包含8個core。
左上角是源代碼區,中間是反匯編區,右上角是狀態區(用來查看core狀態,以及切換core),最下面界面是波形區,顯示各個core指令流的波形(只記錄了pc)。
通過這個工具,就能夠知道,我們編寫的程序,在cpu上的執行過程,以及執行結果。還能夠,單步仿真,單步跳過。而單步功能,不僅僅支持向前跳轉,還可以向后跳轉。
eswd工具,支持多個core,可以分別查看每個core的執行過程,在狀態窗口的狀態欄,會顯示,當前查看的是哪一個core,以及該core的EL。
在源代碼窗口,可以加載源文件。
對於加載的源代碼,如果代碼有執行過,那么在代碼行的前面會有向前向后的按鈕,點擊該按鈕,可以將當前的狀態,恢復到執行該行代碼的狀態。
在debug界面,可以查看變量的值,以及調用棧。
在代碼處,右鍵,選擇 choose execution。
會彈出time tables窗口,顯示,這個函數,在那些時刻有執行過。
在波形窗口,能夠看到各個core的執行pc,以及該pc,所在的函數。
二、總結
該工具,可以讓我們知道,程序在cpu上的執行過程,以及執行結果,方便我們去定位問題。而不需要去分析波形,才能得到cpu的執行過程與執行結果。
要想使用eswd工具,顯示出這些信息,需要我們去做一些工作,產生database,給eswd工具來分析。
產生database,需要如下的一些文件:
-
程序的elf文件
-
cpu架構的描述
-
trace的配置文件
-
cpu的執行結果trace
后面,就要詳細來說明一下,如何得到上面的文件,最終產生database,並使用eswd工具進行分析。
6,eswd工具配置與仿真
上一文介紹了eswd工具的使用,該工具,可以將cpu的執行流,與elf程序對應起來,讓我們方便的去debug。
下面,就說一下,怎么實現上述過程。
需要三個文件
-
cpu架構描述文件
-
cpu執行的指令流文件,下文簡稱tarmac文件
-
eswd配置文件
一、cpu架構的描述
eswd工具,需要cpu架構的描述文件。我們使用自定義架構的方式,傳遞給eswd工具。
這款自定義架構的處理為xxx(基於ARMv8)。定義xxx_eswd.conf文件。
首先是xxx(架構的名字),隨后跟着一個大括號,描述這款架構的信息。
-
disassembly_tool:定義反匯編工具,因為ARMv8支持aarch64和aarch32兩種架構,因此這里有2個反匯編工具。
-
pc:定義pc寄存器的名字,后面程序的對應,就根據該名字進行對應
-
reg_alias: 寄存器的別名,ARMv8有X和W寄存器的區別,W寄存器,其實就是X寄存器的低32bit。
ARMv8架構,包括了aarch32的R寄存器,因此在reg_alias中,也需要進行定義。
1、reg_banks
reg_banks,定義寄存器。需要查看的寄存器,需要在這里定義。格式如下圖:
這里定義了系統寄存器,向量寄存器,通用寄存器。圖中的。。。,是省略的寄存器描述,需要自己填寫完整。
對於寄存器描述,需要如下的描述信息
寄存器的名字 "寄存器位寬,寄存器描述"
-
寄存器的名字:該寄存器將來顯示在eswd工具上的寄存器的名字,eswd工具,會從cpu仿真log中,查找該寄存器名字,並將值進行關聯。
-
寄存器位寬:指定寄存器的位寬
-
寄存器描述:該寄存器的功能
如 CPSR "32,program status register"
表示,有一個系統寄存器CPSR,32bit寄存器,是program status register。
將自己關心的寄存器,給描述出來。不關心的寄存器,可以不用描述。寄存器描述多了,會減慢eswd分析的過程。
有描述的寄存器,在eswd工具的registers子界面,就可以看到寄存器的值。
2、modes
modes,定義cpu允許的模式。其格式如下:
對於ARMv8,使用CPSR,來判斷當前cpu的模式。
mode_reg,指定cpu mode,關聯的寄存器,后面的0x1f,表示取該寄存器的低5個bit。
mode_enum:對cpu的mode的枚舉描述,第一列是cpu的模式,第二列是對應寄存器的值,也就是 CPSR & 0x1f的值。
對於cpu架構,描述這些信息,就已足夠了。更多的內容,要查看eswd工具的userguide。
3、dwarf_regs
dwarf_regs段,用來描述cpu的不同mode下,dwarf寄存器與物理寄存器的映射關系。
在xxx架構中,描述如下:
上圖是dwarf_regs段描述的一部分,對於modes段,指定的每個cpu模式,都需要進行定義。
4、event
event的定義如下,可以用來追蹤一些event。
如果tarmac文件中,有相應的event關鍵字,那么會在波形文件中,有顯示。
如以下,定義了三個event。mode_change是自帶的event。
events mode_change,RESET_EVENT,CALL_EXCEPTION |
indago工具中,顯示如下。
在569465ns,出現過CALL_EXCEPTION這個event。和tarmac文件中一致。
二、cpu執行的指令流
要將cpu的仿真指令流,最終轉化成tarmac文件。將來提供給eswd工具使用。
tarmac文件的格式如下圖:
1、pc change
對於pc change,格式如下圖:
2、寄存器訪問
對於寄存器,格式如下圖:
有了寄存器的信息,indago界面,才可以顯示出寄存器的值。
3、memory訪問
對於memory訪問,格式要復雜一些:
有了memory的信息,我們就可以在indago界面中,看到c代碼的各個變量的值。
4、event
對event,格式如下圖:
5、自己實現
只有tarmac的格式,符合上面定義的格式,eswd工具,才能夠將tarmac的結果,與elf程序給對應起來。
打印的tarmac的格式如下圖所示:
第一列,表示仿真時間,第二列是時間單位。
如果是指令的信息,PC表示指令的PC,后續跟指令碼。最后跟反匯編。反匯編信息這一列,可以不要。
如果是指令的執行結果,REG表示寄存器,后續跟寄存器的值。這里的寄存器,要和cpu架構描述文件中的寄存器描述的名字要一致。
如果是EVENT,EVENT表示事件,后面跟時間的名字,名字要和cpu架構描述文件中,event指定的事件一致。
對於CPSR,在17905ns,值是0x600003cd,和0x1f與,結果是0x0000000d。從cpu架構描述文件中,可以知道,當前cpu處於EL3H模式。
時間,最好和波形中的時間一致,這樣當發現問題后,可以很快的定位到波形的位置。
cpu仿真打印的log,可能和eswd要求的log格式不一致,因此需要腳本進行處理,將cpu仿真打印的log,和eswd要求的log格式一致。
三、eswd配置文件
在提供了cpu架構描述文件,cpu執行指令流log(以下簡稱tarmac文件)后,還需要配置文件。
配置文件,以config關鍵字開始,配置的描述,都在config包圍的大括號中。
tarmacfile_optional 1:如果該core的tarmac文件不存在,那么忽略該core的分析。xxx是一個8core的cpu,在某些情況下,可能只有某幾個cpu在跑。
1、archs段
描述架構信息,格式如下圖:
我實現的如下圖:
archs段,描述cpu的架構信息。corecfgfile,指定cpu架構描述文件,initmode指定cpu在初始時刻,的cpu模式。archs段中,可以描述多個cpu的架構信息。
2、processors段
processors段,指定處理器的配置信息。processor中,可以嵌套多個processors。
對於嵌套的每一個processors,name表示該processors的名字,cores,表示該processors中包含的core。
對於每個core:
-
name表示該core的名字
-
coretype,指定archs段中的cpu架構
-
tarmactype:PROCTARMAC,表示使用tarmac文件的方式進行追蹤,還有一種是使用shm波形文件方式。
-
tarmacfile:cpu執行的指令流log文件
-
imagefile:core上執行的elf文件
-
events:指定event,eswd工具,支持在不同的時刻,載入不同的elf程序。如果有這樣的需求,就在events中指定。
上面的描述,在eswd的cores界面如下:
如果processors描述如下:
那么eswd工具上,cores的子界面如下圖所示:
通過該配置文件,就告訴了eswd工具,追蹤的cpu架構,cpu架構文件,tarmac文件,elf文件。
四、仿真
完成上述工作后,就是用使用irun工具,搭配-esw選項,產生eswd database,之后使用eswd工具分析。
irun -log logfile -64bit -esw arch_config:./xxx_eswd.conf -esw config:./config_proctarmac_aarch64.in |
-
-esw arch_config: 指定cpu架構描述文件
-
-esw config: 指定eswd配置文件
仿真完畢后,會生成ida.db,esw.db,eswtarmac.shm這3個文件夾。這些就是eswd database。
指定indago -64bit命令,就會啟動indago工具。
3、總結
要使用cadence公司提供的eswd工具,需要進行一些配置。配置比較花時間與精力,但是花費的時間與精力是值得的。因為通過這個工具,我們能夠看到軟件,在cpu上的執行流程以及執行結果,從而方便我們去debug。
eswd還有其他的一些更高級的功能,這部分,我就不介紹了,大家可以看到eswd的userguide。
到這里,cadence indago征程,就結束了,主要是介紹了indago系列的2個工具,debug app與eswd。至於另外一個協議分析,我沒有用過,因此就不再介紹。