我原先計划把vcs的ug看完然后每章都整理一些筆記和心得,但是在完成前三章之后我發現這可能要花費我特別多的時間和精力,並且其中很多東西就算記下來了也只是單純的記下來了,也不知道怎么用,什么時候會用。更糟糕的是我回過頭來看一下自己前面寫的東西,其實就是在翻譯文檔,那寫博客就真的沒有什么意義了。所以我決定改變自己的做法,只選取一些常用到的東西來記錄。比如說vcs,這個東西說白了是一個仿真的軟件,那我首先要寫的是怎么把它用起來,完成一次仿真,其他的技術細節留到后面再探討,這樣也可以避免把寫博客變成翻譯文檔。因此這篇博客就圍繞“如何用vcs完成一次仿真”來寫。
vcs是編譯型的仿真器,支持verilog,VHDL,System C等多種形式的設計輸入。現在我也只對verilog有一點了解,所以就不多寫另外幾種了,主要以verilog為主。所謂編譯型仿真器就是要先將設計編譯為可執行文件然后進行仿真,所以大體上可以將仿真流程分為兩部分:編譯+仿真。
1 簡介
vcs的工作流程可以分為兩種,分別是three-step
和two-step
。首先是three-step
1-1 three-step flow
three-step flow可以應用到所有vcs支持的設計輸入方式上。所謂的三步指的是:analysis
,elaboration
,simulation
。
1-1-1 Analysis
這一步的作用是檢查設計是否有語法錯誤,同時將設計以一種中間形式進行保存以供后續的Elaboration使用。針對不同的設計輸入方式有vlogan
,和vhdlan
兩種工具可以使用。從名字也可以看出它們分別是用在verilog和VHDL的設計上的,本文就只說一下前者吧。為了方便測試,我寫了一個簡單的格雷碼計數器,這里貼一下我的ugly code
module gray_counter(ptr,clk,rst_n,inc,full,empty);
parameter COUNTER_WIDTH = 8;
input clk,rst_n;
input inc,full,empty;
output reg [COUNTER_WIDTH-1:0] ptr;
reg [COUNTER_WIDTH-1:0] bin_counter;
wire [COUNTER_WIDTH-1:0] next_bin_counter;
wire [COUNTER_WIDTH-1:0] next_gray_counter;
always@(posedge clk, negedge rst_n)
if(!rst_n)
bin_counter <= 'd0;
else
bin_counter <= next_bin_counter;
assign next_bin_counter = bin_counter + {{COUNTER_WIDTH-1{1'b0}},inc&~empty&~full};
assign next_gray_counter = {1'b0,next_bin_counter[COUNTER_WIDTH-1:1]} ^ next_bin_counter;
always@(posedge clk, negedge rst_n)
if(!rst_n)
ptr <= 'd0;
else
ptr <= next_gray_counter;
endmodule
然后還有一個testbench,這里就不貼了,文件名是gray_counter_test.v。下面按照three-step flow,先進行analysis
$ vlogan gray_counter.v gray_counter_test.v
這個命令的執行模板如下
$ vlogan [vlogan_options] Verilog_filename_list
這里說明一下我認為比較有用的options
-help
這個參數是干啥的無需多言-nc
屏蔽掉Synopsys的版權信息
如果不加這個參數的話analysis會出現下面的結果
-f filename
這個參數可以把設計包含的文件名放到一個文件里然后通過這個參數傳入,如果設計包含的文件比較多的話用這個方法就很方便了,比如我這個設計,就可以建一個design.f
gray_counter.v
gray_counter_test.v
然后analysis的時候這樣
$ vlogan -f design.f
-full64
這個參數其實我現在還不知道究竟有什么好處,唯一用到的一次就是之前我用了一個虛擬機,調用vcs總是報錯,版本有問題之類的,加上這個參數就可以了。文檔里對它的說明是:Analyzes the design for 64-bit simulation-l
filename 將analysis的log打印到文件里-sverilog
支持SystemVerilog-timescale=time_unit/time_precision
為仿真添加時間單位和精度,需要注意的是只對沒有`timescale的文件生效+define+macro
定義文本宏+incdir+directory
指定搜索路徑,比如有些.v會include其他的.v
這只是一部分的選項(我知道含義的),后續肯定有一些其他的,再查文檔吧……
1-1-2 Elaboration
這一步是利用Analysis產生的數據產生用於仿真的二進制文件simv以及其他一些數據。這一步使用的工具是vcs,格式如下
$ vcs [elab_options] [libname.] design_unit
design_unit在verilog里指的是top module的名字,這里我的top就是testbench的名字,比如是top
$ vcs top
同樣下面列舉一些參數
-h
或者-help
full64
-l filename
定義log文件
這一步執行完就已經產生可執行的二進制文件了,其實到這里仿真就約等於完成了
1-1-3 Simulation
如果只是要做仿真的話,直接這樣就可以了
$ ./simv
這樣就完成了仿真。比如testbench里添加了一些display什么的,現在就會起作用了。但是這顯然不能滿足我們的需求,最起碼連波形都沒有怎么debug。這部分放到后面再講,下面先說一下two-step flow
1-2 twp-step flow
two-step flow將真個仿真分為了Compilation
和Simulation
兩部分。需要注意的是two-step flow僅適用與Verilog和SystemVerilog的設計。
Simulation的作用類似於three-step中的Analysis+Elaboration。編譯設計並產生可執行的二進制文件。其實Simulation和Elaboration有很多相似之處,包括后面的Simulation也和three-step的simulation很相似。因為目前我主要使用的語言是Verilog,所以這部分的內容我放到下面一節來寫,包括了一些參數,以及如何產生波形,聯合Verdi進行調試等等。
2 Debug
這一部分我介紹一下two-step的流程以及一些簡單的debug選項。按照two-step的流程,先介紹Elaboration
2-1 Compilation
Elaboration使用vcs命令,執行的模板如下
$ vcs [compile options] Verilog_files
例如我這個設計就是
$ vcs gray_counter.v gray_counter_top.v
下面說一下部分參數
-h
或者-help
+incdir+directory
添加搜索路徑-pvalue+parameter_hierarchical_name=value
這個參數的作用是指定設計中的parameter的值。-parameters filename
從文件里指定parameter的值,文件的語法如下
assign value path_to_parameter
並且parameter的路徑中要用/代替.
+define+macro=value+
定義文本宏-f filename
-R
編譯鏈接完成之后直接執行仿真
到這一步已經可以編譯出可執行的simv,但是這時候還是處於所謂的batch mode,即仿真確實是只執行仿真而不保存仿真過程中的信息,也就沒辦法debug,這種模式一般是用在設計的后期regression,應為不保存仿真信息所以執行的速度也會快一些。設計的初期一般需要的是debug_mode
2-2 Debug Mode
2-2-1 -debug_access
要啟用Debug Mode,在compilation的時候需要通過-debug_access(+<option>)
或者-debug_region=(<option>)(+<option>)
選項來開啟。例如
$ vcs -debug_access+all -f design.f
下面說一下-debug_access的可選項
r
對整個設計開啟讀功能,可以讀取仿真過程中變量的值,這個也是最小的debug選項w
對整個設計的register和variable開啟寫功能wn
對整個設計的net開啟寫功能。其實這個我沒搞懂fn
對整個設計的net開啟force功能fwn
對整個設計的net開啟force和write功能f
等效於-debug_access+r+w+fndrivers
開啟driver debugging功能,這個我也不懂line
開啟line debugging,可以單步調試,這個我沒試過cbk
開啟SystemVerilog的string類型的dump,以及基於PLI的對register,nets和variables的回調cbkd
開啟基於PLI的對定義在calss的動態nets,registers和variables的回調和dumping,以及class對象的debuggingthread
開啟對SystemVerilog threads的debugclass
等效於-debug_access+r+w+thread+line+cbk+cbkdpp
等效於-debug_access+w+cbk+driversall
等效於-debug+r+w+wn+f+fn+fwn+drivers+line+cbk+cbkd+thread+class+pp-memcbk
注意這里是-號。這里文檔的描述是關閉對memory和多維數組的回調,還說-debug_access默認是開啟對memories和多維數組的回調的。但是我測試了一下發現不行,經過查下資料我發現應該是這樣:默認情況下確實會保存多維數組,但是是通過下面的命令調用的
$fsdbDumpMDA(level,path);
如果想通過$fsdbDumpvars保存的話需要這樣寫
$fsdbDumpvars(level,path,"+mda");
這樣也可以保存。這一部分詳細的放到后面再說。
-debug_access的可用選項還有很多,但是現在也看不太明白或者用不到,這里也不往上寫了。另外這里添加一個選項的說明:-lca
。這個選項是允許用戶使用一些Synopsys在開發中未經測試的功能,如果需要這個參數的話在編譯的時候會報錯並提示,否則就不用管。
2-2-2 -debug_region
上面提到的-debug_access是用來啟動全局的debug模式的,有時候考慮到性能等因素可能要進一步精確控制debug的功能,這就要通過-debug_region來實現。這個指令調用的模板為
$ vcs -debug_access -debug_region(option_name)(option_name)
注意-debug_region必須要和-debug_access一起才可以,這個也很好理解,畢竟只有開啟了功能才能做調整。下面簡單說明一下-debug_region的參數
+cell
開啟對read cell和real cell的端口的debug功能。這里提到的cell module現在也還不知道是什么+cellports
對real cell和lib cell的端口開啟debug功能
-debug_region還可以通過下面的語法指定-debug_access到某個instance
-debug_region=level,path
這個功能我沒有試驗過。
3 Verdi
Synopsys非常nb的調試工具。一開始是novas公司的產品,后來被springsoft收購了,然后springsoft又被Synopsys收購了。其實到現在verdi默認的波形文件名也是叫novas.rc,很有意思。直接百度verdi發現出來的是下面這個人
Verdi以前叫Debussy,下面這個
看來這個老板也是個愛好音樂的人。
3-1 DumpFile
這個工具本身的使用也非常復雜,這里就只簡單地介紹一下怎么把它啟動起來吧。既然是要看波形,首先就要保存波形。verilog保存的波形可以是ASCII形式的VCD格式,也可以是FSDB的二進制格式,這里就只說一下怎么保存FSDB文件,保存波形文件調用的是下面的系統函數
$fsdbDumpfile(filename);
$fsdbDumpvars(level,path);
注意肯定是先dump文件再dump數據。在testbench中加入這個語句塊編譯(編譯需要又-debug_access)再執行結束之后就可以看到fsdb文件了。除了$fsdbDumpvars
還有一個我前面提到的用於保存MDA的$fsdbDumpMDA
。
3-2 KDB
KDB的全稱是Verdi Knowledge Database。不管是two-step還是three-step,要保存kdb的話除了Simulation步驟都需要添加-kdb
。仿真完成之后,verdi可以通過-dbdir
選項指定路徑以保證vcs和Verdi使用的是相同的數據,同時也可以通過-ssf
指定打開的fsdb文件。例如這樣
$ verdi -ssf test.fsdb -dbdir simv.daidir/
就可以加載仿真的波形以及設計了。
4 Summary
到這里已經可以用vcs和verdi完成簡單的仿真了。總結一下流程,假設我們采用verilog做設計輸入並且采用two-step flow。首先是Compilation設計
$ vcs -f design.f -debug_access+all -kdb
然后執行仿真(其實可以在上一步添加-R
選項合並Compilation和Simulation)
$ ./simv
然后通過啟動verdi進行debug
$ verdi -ssf test.fsdb -dbdir simv.daidir/
5 參數
下面是一些學習過程中了解到的有用的參數,想起來了就記下來吧