日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁(yè) > > 處芯積律

問(wèn)題引入

UVM中,phase機(jī)制是一個(gè)基本而又非常核心的特性之一,uvm phase將驗(yàn)證環(huán)境的運(yùn)行劃分為不同的階段,如build, configue, reset, main等。每個(gè)phase階段可對(duì)應(yīng)著環(huán)境或者DUT的初始化或者處理過(guò)程。

phase的執(zhí)行機(jī)制遵循UVM的"樹(shù)"結(jié)構(gòu),從top-down角度看,有自上而下和自下而上的phase區(qū)別。也有function phase 和 task phase之分,區(qū)別在于是否消耗仿真時(shí)間。uvm中定義的phase如下所示:

UVM已有的phase機(jī)制已經(jīng)可以解決大家絕大部分的場(chǎng)景需求。

近期項(xiàng)目驗(yàn)證架構(gòu)調(diào)整,遇到這樣的需求。簡(jiǎn)化來(lái)說(shuō),SoC驗(yàn)證環(huán)境中會(huì)集成數(shù)十個(gè)子系統(tǒng)的驗(yàn)證UVC(有uvm_test, uvm_env,agent), 其中env A 和env B的初始化build有約束,需要保證env B的build phase內(nèi)容在env A之前完成。

解決方案:

根據(jù)這個(gè)需求,其實(shí)有這樣幾個(gè)解決辦法。

  1. 將env A和env B build_phase中有約束的部分上移,將需要協(xié)調(diào)同步的內(nèi)容放到uvm_test中的build_phase中實(shí)現(xiàn)。這樣就需要Block level和SoC level在集成時(shí)進(jìn)行區(qū)別處理。

  2. 將uvm_env的實(shí)例名按字典排序。在uvm_phase或者樹(shù)的遍歷中,按照字典序進(jìn)行,因此可以將env B和env A的實(shí)例名按字典序命名。

  3. 如果是類似隨機(jī)的過(guò)程的代碼,可以嘗試將env B的該部分代碼放到new函數(shù)中。new函數(shù)會(huì)在build_phase前執(zhí)行。

  4. 給env B建立一個(gè)自定義phase, 該phase在build_phase之前執(zhí)行,完成同步。

因此就對(duì)自定義phase的實(shí)現(xiàn)進(jìn)行了小小的嘗試和solution的package設(shè)計(jì),有幾種方路線可選:

  1. UVM推薦的經(jīng)典實(shí)現(xiàn)
  2. 基于UVM預(yù)先埋入的回調(diào)函數(shù)實(shí)現(xiàn)
  3. 基于interface class的插件式方法
  4. 基于AOP(Aspect Oriented Programming)實(shí)現(xiàn)

先介紹第一種的經(jīng)典做法。

自定義phase實(shí)現(xiàn)之: UVM經(jīng)典推薦

自定義phase的實(shí)現(xiàn),也能找到一些開(kāi)源的代碼,主要步驟:

  1. 根據(jù)所需,選擇function phase還是task phase。并實(shí)現(xiàn)對(duì)應(yīng)的exec_function或者exec_task。

  2. 獲取uvm_domain句柄。function phase對(duì)應(yīng)uvm_domain::get_common_domain()。task phase使用uvm_domain::get_uvm_domain()。

  3. 獲取domain中需要插入phase的位置

  4. 調(diào)用uvm_domain的add函數(shù),將自定義的phase插入到指定位置。

  5. 擴(kuò)展包含新的phase的uvm組件

下面以建立一個(gè)pre_build_phase為例,相關(guān)代碼如下。

user_pre_build_test

先新建一個(gè)包含pre_build_phase的base component, 根據(jù)需求繼承uvm_test或者uvm_env。然后用戶的component均此component擴(kuò)展。

class?user_pre_build_test?extends?uvm_test;
? ??`uvm_component_utils(pre_build_test)
? ??
? ??functionnew?(string?name="pre_build_test",uvm_component parent=null);
? ? ? ??super.new(name,parent);
? ??endfunction

? ??virtualfunctionvoid?pre_build_phase(uvm_phase phase);
? ??endfunction

endclass

class?user_test?extends?user_pre_build_test;
? ??`uvm_component_utils(user_test)

? ??functionnew?(string?name="pre_build_test",uvm_component parent=null);
? ? ? ??super.new(name,parent);
? ??endfunction

? ??virtualfunctionvoid?build_phase(uvm_phase phase);
? ? ? ??super.build_phase(phase);
? ? ? ??`uvm_info(get_type_name, "Here is build_phase", UVM_NONE)
? ??endfunction

? ??virtualfunctionvoid?pre_build_phase(uvm_phase phase);
? ? ? ??`uvm_info(get_type_name, "Here is pre_build_phase", UVM_NONE)
? ??endfunction
endclass

user_pre_build_phase

實(shí)現(xiàn)pre_build_phase的class, 可以參考uvm_build_phase的實(shí)現(xiàn)。如果是task類選的phase,需要繼承uvm_task_phase, 實(shí)現(xiàn)exec_task, 可以參考uvm_main_phase的實(shí)現(xiàn)。

class?user_pre_build_phase?extends?uvm_topdown_phase;
? ??localstatic?user_pre_build_phase m_inst;

? ??staticconststring?type_name =?"user_pre_build_phase";

? ??protectedfunctionnew(string?name="user_pre_build_phase");
? ??endfunction

? ??staticfunction?user_pre_build_phase get();
? ? ? ??if(m_inst ==?null) m_inst =?new();
? ? ? ??return?m_inst;
? ??endfunction

? ??virtualfunctionstring?get_type_name();
? ? ? ??return?type_name;
? ??endfunction

? ??virtualfunctionvoid?exec_func(uvm_component comp, uvm_phase phase);
? ? ? ? user_pre_build_test t;
? ? ? ??if($cast(t,comp) )?begin
? ? ? ? ? ? t.pre_build_phase(phase);
? ? ? ??end
? ??endfunction
endclass

uvm_domain.add(...)

最后在TB的initial里將user_pre_build_phase插入到build_phase之前即可。

module?tb;
? ??import?uvm_pkg::*;
? ??initialbegin
? ? ? ? uvm_domain sim_common_domain;
? ? ? ? uvm_phase ?target_phase;
? ? ? ? sim_common_domain = uvm_domain::get_common_domain();
? ? ? ? target_phase = sim_common_domain.find(uvm_build_phase::get() );
? ? ? ? sim_common_domain.add(
? ? ? ? ? ??.phase(user_pre_build_phase::get() ),
? ? ? ? ? ??.with_phase(null?),
? ? ? ? ? ??.after_phase(null?),
? ? ? ? ? ??.before_phase(target_phase )
? ? ? ? );
? ??end

? ??initialbegin
? ? ? ? run_test();
? ??end
endmodule

根據(jù)上面的代碼可以逐步實(shí)現(xiàn)所需要的phase實(shí)現(xiàn),可以看到期望的輸出,也是比較基礎(chǔ)和經(jīng)典的代碼。后幾種方法可以進(jìn)一步提升自定義phase的易用性和集成性。因?yàn)樽罱也坏娇捎玫腣CS平臺(tái)了,其他的方法后續(xù)再更新。




本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
關(guān)閉