第二章 一個(gè)簡(jiǎn)單的UVM驗(yàn)證平臺(tái)

2.1 驗(yàn)證平臺(tái)的組成

2.2 只有driver的驗(yàn)證平臺(tái)

2.2.1 最簡(jiǎn)單的驗(yàn)證平臺(tái)

class my_driver extends uvm_driver;

? ? function new(string name = "my_driver", uvm_component parent = null);

? ? ? ? super.new(name, parent);

? ? endfunction

? ? extern virtual task main_phase(uvm_phase phase)

endclass

task my driver::main_phase(uvm_phase phase);

? ? ......

? ? ? ? `uvm_info("my_driver", "data is drived", UVM_LOW)

? ? ......

endtask


uvm_driver是一個(gè)派生字uvm_component的類讹躯,每一個(gè)派生自u(píng)vm_component或其派生類的類在其new函數(shù)種要指明兩個(gè)參數(shù):name 和 parent格郁。

uvm_info宏有三個(gè)參數(shù),第一個(gè)參數(shù)是字符串舷蒲,把打印的信息歸類,第二個(gè)參數(shù)是具體要打印的信息友多,第三個(gè)參數(shù)是冗余級(jí)別(UVM_LOW, UVM_MEDIUM, UVM_HIGH)牲平。

get_full_name() 獲取路徑索引。


2.2.1 加入factory機(jī)制

"my_driver.sv"

class my_driver extends uvm_driver;

? ? `uvm_component_utils(my_driver)

? ? ......

endclass


"top_tb.sv"

module top_tb;

initial begin

? ? run_test("my_driver");

end

endmodule


`uvm_component_utils(my_driver) 其功能之一是將my_driver登記在UVM內(nèi)部的一張表中域滥,這張表是factory功能實(shí)現(xiàn)的基礎(chǔ)纵柿。

一個(gè)run_test語(yǔ)句會(huì)創(chuàng)建一個(gè)my_driver的實(shí)例蜈抓,并會(huì)自動(dòng)調(diào)用my_driver的main_phase。只有在類的定義時(shí)聲明了`uvm_component_utils(my_driver)才能使用這個(gè)功能昂儒。所有派生自u(píng)vm_component及其派生類的類都應(yīng)該使用宏注冊(cè)沟使。


2.2.3 加入objection機(jī)制

task my_driver::main_phase(uvm_phase phase);

? ? phase.raise_objection(this);

? ? ......

? ? phase.drop_objection(this);

endtask


raise_objection語(yǔ)句必須在main_phase種第一個(gè)消耗仿真時(shí)間的語(yǔ)句之前,如$display語(yǔ)句可以放在raise_objection之前渊跋。


2.2.4 加入virtual interface

"top_tb.sv"

module top_tb;

initial begin

? ? run_test("my_driver");

end

initial begin

? ? uvm_config_db#(virtual my_if)::set(null, "uvm_test_top", "vif", input);

end

endmodule


"my_driver.sv"

virtual function void build_phase(uvm_phase phase);

? ? ......

? ? if(!uvm_config_db#(virtual my_if)::get(this, " ", "vif", vif)

? ? ......

endfunction

UVM通過(guò)run_test語(yǔ)句實(shí)例化了一個(gè)脫離了top_tb層次結(jié)構(gòu)的實(shí)例腊嗡,建立了一個(gè)新的層次結(jié)構(gòu)。

對(duì)于這種脫離了top_tb層次結(jié)構(gòu)刹枉,同時(shí)又期望在top_tb中對(duì)其進(jìn)行某些操作的實(shí)例叽唱,UVM引進(jìn)了config_db機(jī)制。

在build_phase中主要通過(guò)config_db的 set 和 get 操作來(lái)傳遞一些數(shù)據(jù)微宝,以及實(shí)例化成員變量等棺亭。build_phase是一個(gè)函數(shù)phase,不消耗仿真時(shí)間蟋软,總是在仿真時(shí)間為0時(shí)執(zhí)行镶摘,而main_phase是一個(gè)任務(wù)phase。

config_db的 set 和 get 函數(shù)都有四個(gè)參數(shù)岳守,這兩個(gè)函數(shù)的第三個(gè)參數(shù)必須完全一致凄敢。set函數(shù)的第四個(gè)參數(shù)表示要將哪個(gè)interface通過(guò)config_db傳遞給my_driver,get函數(shù)的第四個(gè)參數(shù)表示把得到的interface傳遞給哪個(gè)my_driver的成員變量湿痢。set函數(shù)的第二個(gè)參數(shù)表示的是路徑索引涝缝,無(wú)論傳遞給run_test的參數(shù)是什么,創(chuàng)建的實(shí)例的名字都為uvm_test_top譬重,因?yàn)閟et操作的目標(biāo)是my_driver拒逮,所以set函數(shù)的第二個(gè)參數(shù)就是uvm_test_top。


2.3 為驗(yàn)證平臺(tái)加入各個(gè)組件

2.3.1 加入transaction

驗(yàn)證平臺(tái)的組件之間臀规,信息的傳遞是基于transaction的滩援。


class my_transaction extends uvm_sequence_item;

? ? rand bit [47:0] dmac;

? ? ......

? ? constraint ...{}

? ? function bit [31:0] calc_crc();

? ? ? ? return 32'h0;

? ? endfunction

? ? `uvm_object_utils(my_transaction)

? ? function new(...);

? ? ......

endclass

在UVM中,所有transaction都要從uvm_sequence_item派生塔嬉。

my_transaction有生命周期玩徊,這種類都是派生自u(píng)vm_object或者uvm_object的派生類,uvm_sequence_item的祖先就是uvm_object谨究,UVM中具有這種特征的類都要使用uvm_object_utils宏來(lái)實(shí)現(xiàn)恩袱。


2.3.2 加入env

run_test只能實(shí)例化一個(gè)實(shí)例。引入一個(gè)容器類胶哲,在這個(gè)容器類中實(shí)例化driver, monitor, reference model 和 scoreboard等憎蛤,在調(diào)用run_test時(shí),傳遞參數(shù)是這個(gè)容器類,uvm_env俩檬。

class my_env extends uvm_env;

? ? my_driver drv;

? ? ......

? ? virtual function void build_phase(uvm_phase phase);

? ? ? ? super.build_phase(phase);

? ? ? ? drv = my_driver::type_id::create("drv", this);

? ? endfunction

? ? `uvm_component_utils(my_env)

endclass


factory機(jī)制注冊(cè)過(guò)的類的實(shí)例化: type_name::type_id::create()萎胰。


2.3.3 加入monitor

class my_monitor extends uvm_monitor;

? ? virtual my_if vif;

? ? `uvm_component_utils(my_monitor)

? ? function new(...)

? ? ......

? ? virtual function void build_phase(uvm_phase phase);

? ? ......

endclass


2.3.4 封裝成agent

driver和monitor二者處理的是同一種協(xié)議,agent將driver和monitor封裝在一起棚辽,不同agent代表了不同的協(xié)議技竟。

class my_agent extends uvm_agent;

? ? my_driver?????drv;

? ? my_monitor? mon;

? ? ......

? ? `uvm_component_utils(my_agent)

endclass

function void my_agent::build_phase(uvm_phase phase);

? ? super.build_phase(phase);

? ? if(is.active == UVM_ACTIVE) ?? begin

? ? ? ? drv = my_driver::type_id::create("drv", this);

? ? end

? ? mon = my_monitor::type_id::create("mon", this);

endfunction

function void my_agent::connect_phase(uvm_phase phase);

? ? super.connect_phase(phase);

endfunction


is_avtive 是uvm_agent的一個(gè)成員變量:

? ? uvm_active_passive_enum is_active = UVM_ACTIVE;

? ? typedef enum bit {UVM_PASSIVE=0, UVM_ACTIVE=1} uvm_active_passive_enum;


2.3.5 加入reference model

class my_model extends uvm_component;

? ? uvm_blocking_get_port?????#(my_transaction) ? ? port;

? ? uvm_analysis_port ?? #(my_transaction) ?? ap;

在UVM中,通常使用TLM(Transaction Level Modeling)實(shí)現(xiàn)compone之間transaction級(jí)別的通信屈藐。

數(shù)據(jù)的一種發(fā)送方式:uvm_analysis_port

數(shù)據(jù)的一種接收方式:uvm_blocking_get_port


my_monitor在main_phase收集完一個(gè)transaction榔组,將其寫入ap中:

????????????task my_monitor::main_phase(uvm_phase phase);

??????????????? ......

????????????????ap.write(tr);

my_env中使用fifo將 ap 和 port 端口聯(lián)系在一起:

????????????uvm_tlm_analysis_fifo ?? #(my_transaction) ?? agt_mdl_fifo;

????????????......

????????????agt_mdl_fifo = new("agt_mdl_fifo", this);

my_env在connect_phase中將fifo分別與my_monitor中的analysis_port和my_model中的blocking_get_port相連:

? ? ? ? ? ? function void my_env::connect_phase(uvm_phase phase);

? ? ? ? ? ? ? ? super.connect_phase(phase);

? ? ? ? ? ? ? ? i_agt.ap.connect(agt_mdl_fifo.analysis_export);

? ? ? ? ? ? ? ? mdl.port.connect(agt_mdl_fifo.blocking_get_export);

? ? ? ? ? ? endfunction

my_agent在connect_phase中:ap = mon.ap。


2.3.6 加入scoreboard

class my_scoreboard extends uvm_scoreboard;


2.3.7 加入field_automation機(jī)制

class my_transaction extends uvm_sequence_item;

? ? rand bit[47:0] dmac;

? ? rand byte ? ? ? pload[];

? ? ......

? ? `uvm_object_utils_begin(my_transaction)

? ? ? ? `uvm_field_int(dmac, UVM_ALL_ON)

? ? ? ? `uvm_field_array_int(pload, UVM_ALL_ON)

? ? `uvm_object_utils_end

endclass


使用uvm_object_utils_begin和uvm_object_utils_end來(lái)實(shí)現(xiàn)my_factory的factory注冊(cè)联逻,在這兩個(gè)宏中間搓扯,使用uvm_field宏注冊(cè)所有字段,就可以直接調(diào)用copy, compare, print等函數(shù)包归。


data_size = tr.pack_bytes(data_q)/8

? ? ? ? ? ? pack_bytes將 tr 中的所有字段變成byte流放入data_q中锨推,字段按照uvm_field系列宏書寫的順序排列。


data_size = tr.unpack_bytes(data_array)/8

? ? ? ? ? ? unpack_bytes將data_q中的byte流轉(zhuǎn)換成 tr 中的各個(gè)字段公壤,其輸入?yún)?shù)必須是一個(gè)動(dòng)態(tài)數(shù)組换可。



2.4 UVM的終極大作:Sequence

2.4.1 在驗(yàn)證平臺(tái)中加入sequencer

在規(guī)范化的UVM驗(yàn)證平臺(tái)中,driver只負(fù)責(zé)驅(qū)動(dòng)transaction厦幅,而不負(fù)責(zé)產(chǎn)生transaction沾鳄。

class my_sequencer extends uvm_sequencer #(my_transaction);

? ? function new(string name, uvm_component parent);

? ? ? ? super.new(name, parent);

? ? endfunction

? ? `uvm_component_utils(my_sequencer)

endclass


class my_driver extends uvm_driver #(my_transaction);


2.4.2 sequence機(jī)制

class my_sequence extends uvm_sequence #(my_transaction);

? ? my_transaction m_trans;

? ? function new(string name = "my_sequence");

? ? ? ? super.new(name);

? ? endfunction

? ? virtual task body();

? ? ? ? repeat (10) begin

? ? ? ? ? ? `uvm_do(m_trans)

? ? ? ? end

? ? ? ? #1000;

? ? endtask

? ? `uvm_object_utils(my_sequence)

endclass


當(dāng)一個(gè)sequence啟動(dòng)之后,會(huì)自動(dòng)執(zhí)行body中的代碼确憨。

`uvm_do: (1)創(chuàng)建一個(gè)my_transaction的實(shí)例m_trans; (2)將其隨機(jī)化; (3)最終將其送給sequencer译荞。


uvm_driver中有成員變量seq_item_port,uvm_sequencer中有成員變量seq_item_export休弃,這兩者之間可以建立一個(gè)通道吞歼,通道中傳遞transaction。在my_agent中玫芦,使用connect函數(shù)將兩者聯(lián)系在一起:

drv.seq_item_port.connect(sqr.seq_item_export);


2.4.3 default_sequence的使用

"my_env.sv"

virtual function void build_phase(uvm_phase phase);

? ? super.build_phase(phase);

? ? ......

? ? uvm_config_db#(uvm_object_wrapper)::set(this, "i_agt.sqr.main_phase", "default_sequence", my_sequence::type_id::get());


2.5 建造測(cè)試用例

2.5.1 加入base_test

class base_test extends uvm_test;

? ? my_env ?? env;

? ? function new(...)

? ? extern virtual function void build_phase(uvm_phase phase);

? ? extern virtual function void report_phase(uvm_phase phase);

? ? `uvm_component_utils(base_test)

endclass


2.5.2 UVM中測(cè)試用例的啟動(dòng)

class case0_sequence extends uvm_sequence #(my_transaction);

......

endclass

class my_case0 extends base_test

? ? ......

? ? uvm_config_db#(uvm_object_wrapper)::set(this, "env.i_agt.sqr.main_phase", "default_sequence", case0_sequence::type_id::get());


class case1_sequence extends uvm_sequence #(my_transaction);

......

endclass

class my_case1 extends base_test

......

endclass


????????????????

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市本辐,隨后出現(xiàn)的幾起案子桥帆,更是在濱河造成了極大的恐慌,老刑警劉巖慎皱,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件老虫,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡茫多,警方通過(guò)查閱死者的電腦和手機(jī)祈匙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人夺欲,你說(shuō)我怎么就攤上這事跪帝。” “怎么了些阅?”我有些...
    開封第一講書人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵伞剑,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我市埋,道長(zhǎng)黎泣,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任缤谎,我火速辦了婚禮抒倚,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘坷澡。我一直安慰自己托呕,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開白布洋访。 她就那樣靜靜地躺著镣陕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪姻政。 梳的紋絲不亂的頭發(fā)上呆抑,一...
    開封第一講書人閱讀 52,475評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音汁展,去河邊找鬼鹊碍。 笑死,一個(gè)胖子當(dāng)著我的面吹牛食绿,可吹牛的內(nèi)容都是我干的侈咕。 我是一名探鬼主播,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼器紧,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼耀销!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起铲汪,我...
    開封第一講書人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤熊尉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后掌腰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體狰住,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年齿梁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了催植。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肮蛹。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖创南,靈堂內(nèi)的尸體忽然破棺而出伦忠,到底是詐尸還是另有隱情,我是刑警寧澤扰藕,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布缓苛,位于F島的核電站,受9級(jí)特大地震影響邓深,放射性物質(zhì)發(fā)生泄漏未桥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一芥备、第九天 我趴在偏房一處隱蔽的房頂上張望冬耿。 院中可真熱鬧,春花似錦萌壳、人聲如沸亦镶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)缤骨。三九已至,卻和暖如春尺借,著一層夾襖步出監(jiān)牢的瞬間绊起,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工燎斩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留虱歪,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓栅表,卻偏偏與公主長(zhǎng)得像笋鄙,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子怪瓶,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容