SV環境構建篇之二:模塊定義與例化


在展開驗證環境的構建之前,我們需要先了解模塊的端口定義以及在SV環境下的例化。在這里, 我們以MCDF(multi-channel data formatter)中的寄存器模塊ctrl_regs為例,來看看常見的模塊定義方式有哪些。

 

模塊定義

Verilog 模塊定義1

Verilog 模塊定義2

 

上面的兩種定義方式是Verilog設計常見的做法,區別在於端口的方向可以在端口聲明時定義,或者在端口聲明完畢后再定義。我們再來看一看,如果用VHDL來定義ctrl_regs的接口會怎么來定義。

 

VHDL 模塊定義1

VHDL 模塊定義2

 

從上面兩種VHDL端口定義的方式來看,第一種VHDL定義方式與之前的Verilog定義方式一致,而第二種定義方式需要作特別說明。

 

由於VHDL的數據類型中,有record類型,該類型作為硬件定義初衷是為了做硬件信號集束(signal collection)的。例如,上面首先定義了一個包mcdf_pkg,而在其中定義了兩種數據類型:reg2fmt_t和reg2arb_t。隨后,在ctrl_regs端口定義時,使用了這兩種數據端口類型,進而使得ctrl_regs模塊送給formatter模塊的信號被集束在一個新定義的數據類型中。

對於稍后我們會提到的模塊例化,如果MCDF的各個模塊均為VHDL定義描述的,那么對於接口類型是record定義的模塊在於其它相鄰模塊連接時,可以通過相同的record類型用來做信號對接,也可以通過信號分散賦值的形式進行連接。

 

我們需要額外注意的是,如果遇到了Verilog模塊與VHDL模塊的連接,或者Verilog模塊中例化VHDL的時候,需要對VHDL record類型進行特別處理。

 

所以,我們接下來進入模塊的例化部分。這里,我們將ctrl_regs的testbench稱之為ctrl_regs_tb,首先我們需要對ctrl_regs進行例化。

 

模塊例化

對verilog ctrl_reg2的例化

 

 

對於VHDL的 ctrl_reg3的例化也同上面對ctrl_regs2的例化,而需要注意的是,如果SV或者Verilog作為頂層,來例化含有record類型接口的時候,我們建議通用的方法是,驗證人員需要首先新建立一個VHDL wrapper來作為一個盒子用來將ctrl_regs4的兩種record類型接口reg2fmt_o和reg2arb_o進一步轉化為通用的std_logic_vector類型,即ctrl_reg3的接口形式。否則,如果在SV或者Verilog內部直接例化含有record類型接口,經常會有接口類型無法匹配的編譯問題。

 

對於VHDL record接口類型在Verilog中例化的問題,一些工具廠商如MentorGraphics的仿真工具QuestaSim提出了Verilog/VHDL/SV數據定義包混用的編譯選項-mixedsvvh,用來做工具一側的支持,而有些工具商則沒有提出類似方案。所以就測試平台的移植性來看,我們依然建議通過首先改造VHDL record接口,再者進行驗證平台內DUT實例化的方式來進行。

 

參數使用

在IP設計中,經常會遇到參數化的模塊。例如,我們可以將ctrl_regs模塊的地址寬度和數據寬度參數化,從而得到這樣的端口定義:

 

參數化端口定義

 

 

 

對此,我們可以在模塊例化時再決定端口的寬度,例如:

 

上面的例子在模塊例化時,將地址寬度addr_width修改為16,而保持了數據寬度data_width的默認值32。

 

參數修改

對設計和驗證環境引入參數的優點在於,通過參數可以更方便地調整結構和數據類型,而不需要修改對象內部的定義。

 

除了我們上面提到的模塊參數可以在例化時修改以外,我們還可以在什么時候對參數加以修改呢?在討論之前,我們首先需要闡述關於目前主流HDL仿真器編譯仿真代碼的過程。通過對比不同仿真器(simulator),我們可以統一將代碼編譯運行的過程分為三個部分:

  • 編譯階段(compilation):工具通過閱讀目標代碼,進行語法和語義分析分析,將每個模塊分別編入庫中(library)。

  • 建模階段(elaboration):工具將各個模塊按照設計集成關系最終組成頂層模塊。這一過程包括了各個模塊(module)的例化、接口(interface)例化、程序(program)例化、層次集成、計算參數、解決層次信號引用、建立模塊連接等。這一過程發生在了編譯階段之后,仿真階段之前,類似於軟件編譯的link階段。

  • 仿真階段(simulation):通過讀取建模階段的對象文件,建立硬件RTL模型和驗證環境,通過周期驅動(cycle-driven)或者事件驅動(event-driven)的方式來進行仿真。

 

所以從數據修改的手段上來看,參數修改可以在編譯階段修改即通過模塊例化時的參數傳入的方式進行,也可以在建模階段通過工具提供的參數修改的elaboration命令選項來修改。參數無法在仿真階段進行修改。

 

不同仿真器對於這三個階段的執行方式是不相同的,例如QuestaSim會首先執行compilation將各個模塊編譯到庫中,而接下來的仿真階段實際上會首先進行內置的elaboration環節,所以參數可以在仿真階段通過命令行修改。而VCS則將上述三個階段獨立開來,使得compilation與elaboration可以通過仿真前的命令行單獨執行,而simualtion階段則直接運行已經建立好的模型。

 

事先清楚不同仿真器對於上述階段的處理,就明白了針對不同的仿真器何時可以修改參數。QuestaSim需要在仿真階段修改,而VCS需要在獨立的elaboration階段修改。

 

宏定義

除了parameter的方式,我們還可以通過宏定義的方式進行參數化設計。例如上面的例子ctrl_regs5可以修改為宏定義的方式:

針對宏定義的形式,用戶如果要修改上面端口的寬度,必須在compilation階段完成。這使得通常,針對宏定義的形式,我們會將公共使用的宏存放在公共的空間作為頭文件(header file),在編譯之前通過修改宏的定義,或者調用不同的頭文件來決定端口寬度,或者別的設計和環境參數。

 

 

通過認識如何進行模塊的例化,我們已經可以在首先將DUT置入到測試平台中,下一節課我們將對SV的重要特性——接口(interface)進行討論,從而掌握如何通過接口讓硬件部分DUT與隨后的驗證環境相連接。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM