這里是引用
include 和 import pkg區別
1.作用
`include與C語言中類似,用于在一個文件中插入另一個文件;import用于在一個作用域中引入一個package(或其中的內容),使得這些內容在當前作用域中可以不添加其所在的package就能被識別。
2.用途
`include把一個文件平鋪在插入的文件中,這個過程發生在編譯前。
與verilog中類似,可以把宏定義的參數放在一個文件中,再使用`include插入所需的文件中,使代碼更加整潔。
也可以將一個類寫在一個頭文件中,使用extern方法,在另一個文件中定義類中的方法,方便管理和加密,最后再將所有的文件統一`include到頂層,
而import發生在編譯后,將已編譯的package的作用域擴展到import的域中,例如文章開頭的通過import引入uvm_pkg,從而使自己的驗證環境可以使用UVM的特性和機制
在編程中,include 和 import 是兩個常用的關鍵字,但它們在不同的編程語言和上下文中具有不同的含義和用法。
include:
include 是 C 和 C++ 編程語言中的預處理指令。它用于在源代碼中包含外部文件的內容,通常用于包含頭文件(header files)。
頭文件通常包含函數聲明、宏定義和數據結構的定義等內容,可以在多個源文件中共享和重用。
include 指令會在預處理階段將被包含的文件的內容插入到當前文件中,相當于將文件內容復制粘貼到當前位置。
import:
import 是許多編程語言中用于導入外部模塊或包的關鍵字,例如 Python、Java、JavaScript 等。
在不同的語言中,import 的用法和功能可能會有所不同。一般而言,它用于引入其他模塊或包的定義,使得你可以在當前代碼中使用這些定義。
在 UVM(Universal Verification Methodology)中,include 和 import 也有一些不同的用法和含義。
include 在 UVM 中:
在 UVM 中,include 通常用于包含 UVM 的庫文件、基類和一些通用定義,例如 UVM 中的基類(uvm_object、uvm_component 等)和一些宏定義。
include 在 UVM 中用于將這些共享的定義引入到你的測試環境或測試用例中,以便你可以使用 UVM 提供的功能和方法。
import 在 UVM 中:
在 UVM 中,import 關鍵字用于引入 UVM 命名空間中的類或函數,以便在你的代碼中可以直接使用它們的名稱,而無需使用完整的命名空間路徑。
UVM 使用了一系列的命名空間,例如 uvm_pkg 命名空間。通過 import 可以簡化代碼中對 UVM 類和方法的引用。
` include將文件中所有文本原樣插入包含的文件中。這是一個預處理語句
`include在import之前執行。他的主要作用就是在package中平鋪其他文件,從而在編譯時能夠將多個文件中定義的類置于這個包中,形成一種邏輯上的包含關系。
import不會復制文本內容。但是import可package中內容引入import語句所在的作用域,以幫助編譯器能夠識別被引用的類,并共享數據。在我們的TB中,include通常分為以下幾類:
1)package內的include文件:在package內,前面是import library,比如“import uvm_pkg:😗”,緊接著即使include文件,通常會把本目錄下相關的文件都include進來,比如virtual sequence文件,testcase文件。
2)package外的include文件:這種用法在我們現在的環境中使用不多,目前最常用的是include interface文件,比如,在xxx_env_pkg文件的最開頭,include “xxx_if.sv”
3)為了文件管理方法,將部分code寫到一個單獨的文件中,然后在主文件中直接include進來,相當于將多個文件合并成一個文件。比如,一個subsys要用到很多API,而這些API共有A, B,C三類,分別由3個人完成,則可以寫成api_a.sv, api_b.sv, api_c.sv,在l0_basic_vseq.sv中,將這三個文件include進來。
https://blog.csdn.net/Andy_ICer/article/details/115679314
.sv .svh
.svh后綴的文件即systemverilog include文件,如其名,是為了include到其它文件里面去的文件。
.sv 文件與.svh文件沒有本質區別。通常,需要被include 到package的文件定義為.svh類型, 其他的文件定義為.sv類型。
.svh后綴的文件即systemverilog include文件。
1、package內的類應該用include分隔為單獨的文件。
2、按照編譯順序排列。
3、include中不應該還包含
include。
hdl_top.sv和hvl_top.sv
hdl_top.sv 和 hvl_top.sv 是在硬件設計和硬件驗證中經常使用的兩個文件,分別用于硬件描述語言(HDL)的頂層設計和硬件驗證語言(HVL)的頂層測試環境。
hdl_top.sv:
這個文件通常用于硬件描述語言(如 Verilog、VHDL)中的頂層設計。
在 hdl_top.sv 文件中,你會描述整個硬件系統的結構、功能和連接關系。這可能包括處理器、外設、數據通路等。
該文件會被綜合工具用來生成實際的硬件電路。
hvl_top.sv:
這個文件通常用于硬件驗證語言(如 SystemVerilog)中的頂層測試環境。
在 hvl_top.sv 文件中,你會創建和配置測試環境,生成測試用例,并驅動這些測試用例進行硬件驗證。
這個文件會包括 UVM(Universal Verification Methodology)或其他驗證方法學的相關代碼,以及測試用例生成和管理的邏輯。
在典型的硬件驗證流程中,hdl_top.sv 和 hvl_top.sv 兩者協同工作。hdl_top.sv 描述了你要驗證的硬件設計,而 hvl_top.sv 創建了測試環境,使用測試用例對 hdl_top.sv 中的設計進行驗證。
回顧uvm_config,以及自定義uvm_config
class env_config extends uvm_object
verilog:parameter、defparam與 localparam
在 Verilog 語言中,parameter、defparam 和 localparam 都是用來定義常量的關鍵字,但它們有不同的用途和范圍。下面我會為您解釋它們的區別:
parameter:
parameter 用于在模塊級別定義一個常量,該常量在編譯時被確定,并可以在整個模塊中使用。
它用于指定在模塊實例化時需要傳遞的參數值,這些參數值可以在模塊的內部使用。也可以用于定義宏、宏定義和一些常量值。
在模塊中,parameter 常量可以直接使用,無需使用模塊的實例名稱來引用。
module MyModule #(parameter PARAM_VALUE = 8);// PARAM_VALUE is a parameter with default value 8// You can use PARAM_VALUE within this module
endmodule
defparam:
defparam 用于在模塊實例化之外設置模塊的參數值。
通常在模塊實例化后,使用 defparam 可以修改模塊實例的參數值。這樣做可以避免在模塊定義時傳遞參數,而在實例化時設置參數,從而更靈活地控制模塊行為。
defparam 在一些情況下可能會影響代碼的可讀性,因此在實踐中應該謹慎使用。
module Test;MyModule my_inst(); // Instantiate the module
endmodule// Change the parameter value of my_inst using defparam
defparam my_inst.PARAM_VALUE = 10;
localparam:
localparam 用于在模塊中定義一個局部常量,只能在該模塊內部使用。
localparam 的值在編譯時確定,但是它只在定義它的模塊內部可見,無法在模塊實例化時傳遞或在其他模塊中使用。
module MyModule;localparam LOCAL_PARAM = 5; // A local parameter within the module
endmodule
總結:
parameter 用于定義模塊內部的常量,可以在實例化時傳遞。
defparam 用于在模塊實例化之外修改模塊的參數值。
localparam 用于定義模塊內部的局部常量,只在該模塊內部可見。
1、最好運用模塊在端口的聲明方式,參數覆蓋用參數值模塊例化。
2、不要用defparam去修改在實體內聲明的parameter,因為不可綜合,用帶參數值模塊例化可以。
3、localparam參數可通過parameter賦值進行間接的修改,不能用其他方法修改。
兩種聲明方式混用時,vivado綜合工具會把parameter變成local parameter,其他工具未知。
兩種parameter聲明方式混用的時候,defparam與參數值模塊例化兩種方法vivado均會報錯,因為local parameter不可被直接改變。
單獨使用parameter,無local的警告
https://zhuanlan.zhihu.com/p/420873197
test_base
例化
cm_env env
cm_env_config env_cfg
cm_agent_config agt_cfg
//methods
function void configure_cm_agent
//Standard methods
new
build_phase
set_seqs
function void end_of_elaboration_phase
build_phase
env_cfg
env
cm_agt_cfg
configure_cm_agent(agt_cfg)
get cm_mon_bfm,agt_cfg.mon_bfm
get cm_drv_bfm,agt_cfg.mon_bfm
env_cfg.agent_cfg = cm_agt_cfg
set (this, " * ",“cm_env_config”,env_cfg)
set (this, " * ",“cm_agent_config”,agt_cfg)
end_of_elaboration_phase
//uvm_root::get().set_report_verbosity_level_hier(UVM_HIGH);
//uvm_root::get().set_report_max_quit_count(10);
?11
function void configure_agent
function void configure_cm_agent(agent_config cfg)
配置agt_configure
agt_cfg.active = …;
set_seqs
set_seqs(cm_base_virtual+sequence seq)
seq.cfg = env.cfg
end_of_elaboration_phase
在 UVM(Universal Verification Methodology)中,end_of_elaboration_phase 是一種階段(phase),用于表示仿真環境中的一個特定時間點,通常用于進行一些最終的配置和準備工作,以便在仿真運行開始之前完成環境的設置。
具體來說,end_of_elaboration_phase 位于 UVM 測試基類 uvm_test 中的默認構造函數中,是 UVM 生命周期中的一個重要階段。在這個階段,測試環境的配置和連接已經完成,但還沒有開始進行實際的仿真運行。
在 end_of_elaboration_phase 階段,您可以執行以下操作:
完成環境的配置和連接:在此階段,可以確認環境中的各個組件是否正確連接,并根據需要進行修復或調整。
設置參數和信號:您可以在此階段設置各個組件的參數,包括一些與實際測試相關的參數。
收集信息和報告:您可以在此階段生成一些初始化的報告,以便在仿真運行之前檢查環境的狀態和配置。
進行一些前期準備工作:例如,為測試用例生成隨機種子、設置文件路徑等。
需要注意的是,end_of_elaboration_phase 階段是在 UVM 生命周期的早期階段,僅用于環境的初始化和準備工作。在這之后,會進入 run_phase 階段,開始進行實際的仿真運行。根據您的具體測試需求,您可以在 end_of_elaboration_phase 中執行適當的操作,以確保仿真環境在運行時處于正確的狀態
這段代碼是在 UVM(Universal Verification Methodology)中設置報告的詳細程度和最大退出計數的操作。讓我為您解釋一下這兩個函數的作用:
uvm_root::get().set_report_verbosity_level_hier(UVM_HIGH);:
這行代碼設置了報告的詳細程度(verbosity level)為 UVM_HIGH,這是一種 UVM 預定義的報告詳細程度。
報告詳細程度用于控制報告信息的顯示級別。在高詳細程度下,會顯示更多的報告信息,包括警告和錯誤信息。
uvm_root::get() 返回 UVM 根實例,通過調用 set_report_verbosity_level_hier() 方法,您可以設置整個測試環境中所有組件的報告詳細程度為 UVM_HIGH。
uvm_root::get().set_report_max_quit_count(10);:
這行代碼設置了最大退出計數(max quit count)為 10。這是當發生錯誤時,仿真環境最多允許退出的次數。
如果測試中出現了一些嚴重錯誤,導致測試環境需要退出,但測試尚未結束,系統會嘗試退出一定次數后繼續進行,以便收集更多的錯誤信息。
該函數調用可以用于設置最大退出次數,以控制在錯誤情況下的退出行為。
這些函數調用的目的是在測試環境中配置報告行為和退出行為,以便更好地進行調試和錯誤定位。您可以根據需要選擇不同的報告詳細程度,并設置適當的最大退出計數,以符合您的測試需求。
uvm_comfig_db#()set
set第二個參數可以使用通配符*
get種一般第一個參數為this,則第二個參數可以是“”
env_config
localparam string s_my_config_id = “cm_env_config”
localparam string s_no_config_id =
localparam string s_my_config_type_error_id =
bit has_cm_function_coverage = 0;
bit has_cm_reg_scoreboard = 0;
//bit has_cm_scoreboard = 0;
//配置下屬組件
cm_agent_config cm_agent_cfg
virtual cm_if vif
注冊
extern static function cm_env_config get_config(uvm_component c)
new
do_cm_agent_cfg()
do_cm_agent_cfg()
cm_agent_cfg.name = ,,,;
賦值
function cm_env_config get_config(uvm_component c)
cm_env_config t;
get(c,“”, s_my_config_id ,t)
return t;
cm_defines.svh
//opccode
parameter ADD = 4’d0;
cm_cfg_pkg.svh
cm_ad_random_test
注冊
new
build_phase
task run_phase
run_phase
cm_ad_random_virt_seq random_ad_seq = create
phase.raise_objection(this,"cm_ad_random_test’);
random_ad_seq.start(env.m_vsqr);
#100ns;
phase.drop_objection(this,"cm_ad_random_test’);
hdl_top.sv
`timescale
logic clk
logic rstn
cm_if CM(clk, rstn)
//BFM interfaces
cm_monitor_bfm cm_mon_bfm
cm_driver_bfm cm_drv_bfm
//DUT
cm_math DUT(…
)
initial begin
import uvm_pkg::uvm_config_db;
set cm_mon_bfm
set cm_drv_bfm
end
initial begin
clk
end
initial begin
rstn
repeat(4)
rstn
end
hvl_top
`time
im uvm_pkg:😗 ;
im cm_test_lib_pkg:: *
initial begin
//vcd
end
initial begin
run_test();
end
cm_env.svh
注冊
//data members
cm_env_config m_env_cfg;
cm_agent m_agt;
cm_scoreboard m_scb;
cm_viryual_sequencer m_vsqr;new
build
connect_phase
build
//env_config
get (this, " * ","cm_env_config",m_env_cfg)
//agent_config
get (this, " * ","cm_agent_cfg",m_env_cfg.cm_agent_cfg)
m_agt = cm_agent::creat
if(m_env_cfg.has_cm_scoreboard)begin
m_scb = cm_scoreboard::type_id::creat(
set(this, "m_scb", "m_env_cfg", m_env_cfg);
//vsqr
set(this, "m_vsqr", "m_env_cfg", m_env_cfg); //???
m_vsqr = cm_virtual_sequencer::type_id::creat(
connect_phase
if(m_env_has_complex_scoreboard)begin
magt.m_monitor.scb_ap.connect(m_scb.cm_imp.analysis_export);
end
m_vsqr.sqr = m_agt.m_sequencer
cm_env_pkg.svh
cm_virtual_sequencer
cm_sequencer sqr
cm_env_config cfg
virtual cm_vif vif
new
build
get (this, " * ",“cm_env_config”,cfg)
vif = cfg.vif
cm_agent
cm_gent_cofig m_cfg
m_monitor
m_sequencer
m_driver
m_subscriber
new
build
connect
build
get (this, " * ",“cm_agent_config”,m_cfg)
m_monitor = creat
m_monitor.m_cfg = m_cfg
set m_monitor
m_driver
m_driver.m_cfg = m_cfg
set m_driver
m_sequencer
set m_sequencer
m_subscriber
connect
scb_ap = m_monitor.scb_ap
m_driver.seq_item_port.connect(m_sequencer.seq_item_export)
m_monitor.sub_ap.connect(m_subscriber.analysis_export)
cm_agent_config
localparam string s_my_config_id = “cm_env_config”
localparam string s_no_config_id =
localparam string s_my_config_type_error_id =
virtual cm_monitor_bfm mon_bfm;
virtual cm_driver_bfm drv_bfm;
uvm_active_passive_enum active = UVM_ACTIVE;
bit has_cm_function_coverage = 1;
//bit has_cm_reg_scoreboard = 0;
rand bit has_scoreboard = 1;
好幾個
field
//下面是個方法,set是在test_base.
function cm_agent_config get_config(uvn_component c)
cm_agent_config t;
get(c,“”, s_my_config_id ,t)
return t;
cm_scoreboard
cm_env_config cfg
uvm_tlm_analysis_fifo #(cm_seq_item) cm imp;
cm_reference_model complex_rm;
//data buffers
cm_seq_item tr_observed[ ] ; c m s e q i t e m t r e x p e c t e d [ ]; cm_seq_item tr_expected[ ];cms?eqi?temtre?xpected[];
//cvoreboard var
new
build
new
new
get (this, " * ",“cm_env_config”,cfg)
run
cm_compare()
report_phase
cm _reference_model
//data_buffers
//statistics
//new
function void calculate()
driver
class cm_driver extends uvm_driver#(cm_seq.item,cm_seq_item);
virtual cm_driver_bfm m_bfm;
cm_agent_config m_cfg;
new
run
build
build
`get_config(cm_agent_config, m_cfg, “am_agent_config”)
m_bfm = m_cfg.drv_bfm
run
complex_seq_item req;
complex_seq_item rsp;
int psel_index;
m_bfm.m_cfg = m_cfg;
`get_config
`get_config(cm_agent_config, m_cfg, “am_agent_config”)
這段代碼是使用 UVM(Universal Verification Methodology)中的 uvm_config_db 工具獲取配置信息的示例。讓我為您解釋一下這段代碼的含義:
get_config:這是 uvm_config_db 工具的一個方法,用于獲取配置信息。
cm_agent_config:這是配置信息的目標對象的類型。在這個例子中,cm_agent_config 是一個類或數據結構,它定義了配置信息的格式。
m_cfg:這是一個變量,用于存儲從配置數據庫中獲取的配置信息。根據代碼,它似乎是一個類的實例。
“am_agent_config”:這是一個字符串,表示要獲取的配置信息的名稱。配置信息通常以字符串形式進行標識,以便在數據庫中查找匹配的配置。
在上述代碼中,get_config 方法的目的是從配置數據庫中獲取名為 “am_agent_config” 的配置信息,并將其存儲在 m_cfg 變量中,該變量的類型是 cm_agent_config。
driver 參數
extends uvm_driver#(cm_seq.item, cm_seq_item):通過 extends 關鍵字,cm_driver 類繼承自 uvm_driver 類,并在括號中使用泛型參數指定了序列項類型。具體來說:
uvm_driver#(cm_seq.item, cm_seq_item) 表示 cm_driver 是一個 uvm_driver 類的子類,其中 cm_seq.item 和 cm_seq_item 是泛型參數,分別表示輸入序列項類型和輸出序列項類型。
cm_driver_bfm
interface cm_driver_bfm(
cm_agent_config m_cfg
function ini_sigs
functio drive
)
cm_monitor
virtual cm_driver_bfm m_bfm;
cm_agent_config m_cfg;
uvm_analysis_port#(cm_seq_item) scb_ap;
uvm_analysis_port#(cm_seq_item) sub_ap;
new
run
build
report
build
`get_config(cm_agent_config, m_cfg, “cm_agent_config”)
m_bfm = m_cfg.mon_bfm
m_bfm.mnt = this;
new
new
run
m_bfm.run()
function
void cm_monitor::mnt.notofy_transaction(item);
scb_ap.write(item);
sub_ap.write(item);
cm_monitor_bfm
interface cm_monitor_bfm(
cm_monitor mnt
function ini_sigs
functio drive
task run();
…
mnt.notofy_transaction(item);
)
cm_sequencer
cm_agent_config cfg
new
build
reconfigure(cm_agent_config cfg)
get_cfg(ref cm_agent_config cfg_)
Virtual Sequence & Virtual Sequencer
https://zhuanlan.zhihu.com/p/369681031#%E4%BB%80%E4%B9%88%E6%97%B6%E5%80%99%E9%9C%80%E8%A6%81%E4%B8%80%E4%B8%AAvirtual%20Sequencer%EF%BC%9F
?
1
extern virtual function void configure_complex_agent(complex_agent_config cfg)function void tesr_base::configure_complex_agent(complex_agent_config cfg);
agt_cfg.active = UVM_ACTIVE;
set 與 get 函數的參數
1.寫信
1)第一個和第二個參數聯合起來組成目標路徑,與此路徑符合的目標才能收信。
2)第一個參數必須為uvm_component 的實例的指針。
3)第二個參數是相對于此實例的路徑。
2.收信
1)第一個參數必須為uvm_component 的實例的指針。
2)第二個參數是相對于此實例的路徑。如果第一個設置為 this,第二個可以是空的字符串。
3)第三個參數必須和set中的嚴格一樣。
3.在top_tb 中,set virtual interface 的第一個參數是null。UVM會自動把它替換成uvm_root::get(),即uvm_top。(uvm_root是全局的,get是靜態的)
4.既然是第一個和第二個參數聯合起來的,set 也可以是下面:
5 get也可以這樣,比如driver的build_phase:
https://blog.csdn.net/tingtang13/article/details/46458869