0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

UVM中的可重用序列

星星科技指導(dǎo)員 ? 來源:synopsys ? 作者:Hari Balisetty,Broa ? 2023-05-29 09:50 ? 次閱讀

在這篇博客中,我描述了在編寫序列時(shí)必須采取的必要步驟,以確保它可以重用。就我個(gè)人而言,我覺得編寫序列是驗(yàn)證任何IP最具挑戰(zhàn)性的部分。編寫序列需要仔細(xì)規(guī)劃,否則我們最終會(huì)從頭開始為每個(gè)場(chǎng)景編寫一個(gè)序列。這使得序列難以維護(hù)和調(diào)試。

眾所周知,序列由幾個(gè)數(shù)據(jù)項(xiàng)組成,它們共同構(gòu)成了一個(gè)有趣的場(chǎng)景。序列可以是分層的,從而創(chuàng)建更復(fù)雜的方案。在最簡單的形式中,序列應(yīng)該是 uvm_sequence 基類的派生,方法是指定請(qǐng)求和響應(yīng)項(xiàng)類型參數(shù),并使用要執(zhí)行的特定方案實(shí)現(xiàn) body 任務(wù)。

usb_simple_sequence 擴(kuò)展uvm_sequence #(usb_transfer);

    rand int unsigned sequence_length;
    constraint reasonable_seq_len { sequence_length < 10 };

    //Constructor
    function new(string name=”usb_simple_bulk_sequence”);
        super.new(name);
    endfunction

   //Register with factory
   `uvm_object_utils(usb_simple_bulk_sequence)

   //the body() task is the actual logic of the sequence
   virtual task body();
      repeat(sequence_length)
      `uvm_do_with(req,  {
      //Setting the device_id to 2
          req.device_id == 8’d2;
          //Setting transfer type to BULK
          req.type == usb_transfer::BULK_TRANSFER;
       })
   endtask : body
endclass

在上面的順序中,我們嘗試將 USB 批量傳輸發(fā)送到 id 為 2 的設(shè)備。測(cè)試編寫者可以通過將此序列分配給頂級(jí)測(cè)試中序列器的默認(rèn)序列來調(diào)用此序列。

類usb_simple_bulk_test擴(kuò)展uvm_test;

…
    virtual function void build_phase(uvm_phase phase );
        …
        uvm_config_db#(uvm_object_wrapper)::set(this, "sequencer_obj.
        main_phase","default_sequence", usb_simple_sequence::type_id::get());
        …
    endfunction : build_phase
endclass

到目前為止,事情看起來簡單明了。為了確保序列可重用于更復(fù)雜的場(chǎng)景,我們必須遵循更多準(zhǔn)則。

首先,通過在序列類中pre_start和post_start任務(wù)中提出和放棄異議來管理測(cè)試結(jié)束非常重要。這樣,我們只在最上面的序列中提出和放棄異議,而不是對(duì)所有子序列都這樣做。

t問 pre_start()

    if(starting_phase != null)
    starting_phase.raise_objection(this);
endtask : pre_start

t問 post_start()

    if(starting_phase != null)
    starting_phase.drop_objection(this);
endtask : post_start

請(qǐng)注意,starting_phase僅為作為特定階段的默認(rèn)序列啟動(dòng)的序列定義。如果已通過調(diào)用序列的 start 方法顯式啟動(dòng)它,則用戶負(fù)責(zé)設(shè)置starting_phase。

類usb_simple_bulk_test擴(kuò)展uvm_test;

    usb_simple_sequence seq;
    …
    virtual function void main_phase(uvm_phase phase );
        …
        //User need to set the starting_phase as sequence start method
        is explicitly called to invoke the sequence
        seq.starting_phase = phase;
        seq.start();
        …
    endfunction : main_phase

結(jié)束類

使用 UVM 配置從頂級(jí)測(cè)試中獲取值。在上面的示例中,沒有為測(cè)試編寫者提供可控性,因?yàn)樾蛄胁皇褂门渲脧捻敿?jí)測(cè)試或序列中獲取值(將使用此序列來構(gòu)建復(fù)雜場(chǎng)景)。修改序列以更好地控制使用此簡單序列的頂級(jí)測(cè)試或序列。

類 usb_simple_sequence 擴(kuò)展uvm_sequence #(usb_transfer);

    rand int unsigned sequence_length;
    constraint reasonable_seq_len { sequence_length < 10 };
    …
    virtual task body();
        usb_transfer::type_enum local_type;
        bit[7:0] local_device_id;
        //Get the values for the variables in case toplevel
         //test/sequence sets it.
        uvm_config_db#(int unsigned)::get(null, get_full_name(),
            “sequence_length”, sequence_length);
        uvm_config_db#(usb_transfer::type_enum)::get(null,
            get_full_name(), “l(fā)ocal_type”, local_type);
        uvm_config_db#(bit[7:0])::get(null, get_full_name(),?
            “l(fā)ocal_device_id”, local_device_id);
        repeat(sequence_length)
        `uvm_do_with(req, {
            req.device_id == local_device_id;
            req.type == local_type;
        })
    endtask : body

結(jié)束類

通過上述修改,我們已經(jīng)控制了頂級(jí)測(cè)試或序列來修改device_id、sequence_length和類型。這里需要注意的幾點(diǎn):uvm_config_db#()::set 中使用的參數(shù)類型和字符串(第三個(gè)參數(shù))應(yīng)該與 uvm_config_db#()::get 中使用的類型匹配。確保使用確切的數(shù)據(jù)類型“設(shè)置”和“獲取”。否則,值將無法正確設(shè)置,調(diào)試將成為一場(chǎng)噩夢(mèng)。

上述序列的一個(gè)問題是:如果 usb_transfer 類中對(duì)device_id或類型有任何約束,那么這將限制頂級(jí)測(cè)試或序列以確保它在約束范圍內(nèi)。

例如,如果usb_transfer類中的device_id存在約束,將其約束為低于 10,則頂級(jí)測(cè)試或序列應(yīng)在此范圍內(nèi)約束它。如果頂級(jí)測(cè)試或序列將其設(shè)置為類似 15 的值(超過 10),則在運(yùn)行時(shí)將看到約束失敗。

有時(shí),頂級(jí)測(cè)試或序列可能需要完全控制,并且可能不希望啟用在較低級(jí)別的序列或數(shù)據(jù)項(xiàng)中定義的約束。需要這樣做的一個(gè)示例是陰性測(cè)試:- 主機(jī)希望確保設(shè)備不會(huì)響應(yīng)device_id大于 10 的傳輸,因此希望發(fā)送device_id 15 的傳輸。因此,為了完全控制頂級(jí)測(cè)試或序列,我們可以修改正文任務(wù),如下所示:

虛擬任務(wù)正文();

    usb_transfer::type_enum local_type;
    bit[7:0] local_device_id;
    int status_seq_len = 0;
    int status_type = 0;
    int status_device_id = 0;
    status_seq_len = uvm_config_db#(int unsigned)::get(null,
        get_full_name(), “sequence_length”, sequence_length);
    status_type = uvm_config_db#(usb_transfer::type_enum)::get(null,
        get_full_name(),“l(fā)ocal_type”,local_type);
    status_device_id = uvm_config_db#(bit[7:0])::get(null,
        get_full_name(), “l(fā)ocal_device_id”,local_device_id);
    //If status of uvm_config_db::get is true then try to use the values
        // set by toplevel test or sequence instead of the random value.
    if(status_device_id || status_type)
    begin
        `uvm_create(req)
        req.randomize();
        if(status_type)
        begin
        //Using the value set by top level test or sequence
        //instead of the random value.
            req.type = local_type;
        end
        if(status_device_id)
        begin
            //Using the value set by top level test or sequence
        //instead of the random value.
            req.device_id = local_device_id;
        end
    end
    repeat(sequence_length)
        `uvm_send(req)

結(jié)束任務(wù):正文

使用'uvm_do_with時(shí)總是要小心的,因?yàn)樗鼤?huì)在較低級(jí)別的序列或序列項(xiàng)中的任何現(xiàn)有約束之上添加約束。

另請(qǐng)注意,如果您有更多變量要“設(shè)置”和“獲取”,那么我建議您創(chuàng)建對(duì)象并在創(chuàng)建的對(duì)象中設(shè)置值,然后使用頂級(jí)測(cè)試/序列中的uvm_config_db設(shè)置此對(duì)象(而不是顯式設(shè)置此對(duì)象中的每個(gè)變量)。這樣,我們可以通過不搜索每個(gè)變量(當(dāng)我們執(zhí)行 uvm_config_db::get 時(shí))來提高運(yùn)行時(shí)性能,而是使用該對(duì)象一次性獲取所有變量。

虛擬任務(wù)正文();

    usb_transfer::type_enum local_type;
    bit[7:0] local_device_id;
    int status_seq_len = 0;
    int status_type = 0;
    int status_device_id = 0;
    status_seq_len = uvm_config_db#(int unsigned)::get(null,
        get_full_name(), “sequence_length”, sequence_length);
    status_type = uvm_config_db#(usb_transfer::type_enum)::get(null,
        get_full_name(),“l(fā)ocal_type”,local_type);
    status_device_id = uvm_config_db#(bit[7:0])::get(null,
        get_full_name(), “l(fā)ocal_device_id”,local_device_id);
    //If status of uvm_config_db::get is true then try to use the values
        // set by toplevel test or sequence instead of the random value.
    if(status_device_id || status_type)
    begin
        `uvm_create(req)
        req.randomize();
        if(status_type)
        begin
        //Using the value set by top level test or sequence
        //instead of the random value.
            req.type = local_type;
        end
        if(status_device_id)
        begin
            //Using the value set by top level test or sequence
        //instead of the random value.
            req.device_id = local_device_id;
        end
    end
    repeat(sequence_length)
        `uvm_send(req)

結(jié)束任務(wù):正文

始終嘗試通過為復(fù)雜方案創(chuàng)建頂級(jí)序列來重用簡單序列。例如,在下面的順序中,我嘗試發(fā)送批量傳輸,然后向 2 個(gè)不同的設(shè)備發(fā)送中斷傳輸。對(duì)于此場(chǎng)景,我將使用我們的usb_simple_sequence如下所示:

類 usb_complex_sequence 擴(kuò)展uvm_sequence #(usb_transfer);

    //Object of simple sequence used for sending bulk transfer
    usb_simple_sequence simp_seq_bulk;
    //Object of simple sequence used for sending interrupt transfer
    usb_simple_sequence simp_seq_int;
    …
    virtual task body();
        //Variable for getting device_id for bulk transfer
        bit[7:0] local_device_id_bulk;
        //Variable for getting device_id for interrupt transfer
        bit[7:0] local_device_id_int;
        //Variable for getting sequence length for bulk
        int unsigned local_seq_len_bulk;
        //Variable for getting sequence length for interrupt
        int unsigned local_seq_len_int;
        //Get the values for the variables in case top level
        //test/sequence sets it.
        uvm_config_db#(int unsigned)::get(null, get_full_name(),
        “l(fā)ocal_seq_len_bulk”,local_seq_len_bulk);
        uvm_config_db#(int unsigned)::get(null, get_full_name(),
        “l(fā)ocal_seq_len_int”,local_seq_len_int);
        uvm_config_db#(bit[7:0])::get(null, get_full_name(),
        “l(fā)ocal_device_id_bulk”,local_device_id_bulk);
        uvm_config_db#(bit[7:0])::get(null, get_full_name(),
        “l(fā)ocal_device_id_int”,local_device_id_int);
        //Set the values for the variables to the lowerlevel
        //sequence/sequence item, which we got from
        //above uvm_config_db::get.
        //Setting the values for bulk sequence
        uvm_config_db#(int unsigned)::set(null, {get_full_name(),”.”,
        ”simp_seq_bulk”}, “sequence_length”,local_seq_len_bulk);
        uvm_config_db#(usb_transfer::type_enum)::set(null, {get_full_name(),
        “.”,“simp_seq_bulk”} , “l(fā)ocal_type”,usb_transfer::BULK_TRANSFER);
        uvm_config_db#(bit[7:0])::set(null, {get_full_name(),“.”,
        ”simp_seq_bulk”}, “l(fā)ocal_device_id”,local_device_id_bulk);
        //Setting the values for interrupt sequence
        uvm_config_db#(int unsigned)::set(null, {get_full_name(),”.”,
        ”simp_seq_int”}, “sequence_length”,local_ seq_len_int);
        uvm_config_db#(usb_transfer::type_enum)::set(null, {get_full_name(),
        “.”,“simp_seq_int”} , “l(fā)ocal_type”,usb_transfer::INT_TRANSFER);
        uvm_config_db#(bit[7:0])::set(null,{get_full_name(),“.”,
        ”simp_seq_bulk”},“l(fā)ocal_device_id”,local_device_id_int);
        `uvm_do(simp_seq_bulk)
        simp_seq_bulk.get_response();
        `uvm_send(simp_seq_int)
        simp_seq_int.get_response();
    endtask : body

結(jié)束類

請(qǐng)注意,在上面的序列中,我們使用 uvm_config_db::get 從頂級(jí)測(cè)試或序列中獲取值,然后使用 uvm_config_db::set 再次將其設(shè)置為較低級(jí)別的序列。如果我們嘗試使用 'uvm_do_with 并將值傳遞到約束塊內(nèi),那么這將作為附加約束應(yīng)用而不是設(shè)置這些值,這很重要。

審核編輯:郭婷


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • usb
    usb
    +關(guān)注

    關(guān)注

    60

    文章

    7846

    瀏覽量

    263304
  • IP
    IP
    +關(guān)注

    關(guān)注

    5

    文章

    1579

    瀏覽量

    149141
  • UVM
    UVM
    +關(guān)注

    關(guān)注

    0

    文章

    181

    瀏覽量

    19111
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    UVM序列的創(chuàng)建和運(yùn)行及中斷服務(wù)程序?qū)崿F(xiàn)方案

    SystemVerilog通用驗(yàn)證方法(UVM)是一種生成測(cè)試和檢查結(jié)果以進(jìn)行功能驗(yàn)證的有效方法,最適合用于塊級(jí)IC或FPGA或其他“小型”系統(tǒng)。在UVM測(cè)試臺(tái)中,大多數(shù)活動(dòng)是通過編寫序列來生
    的頭像 發(fā)表于 04-09 16:09 ?4118次閱讀
    <b class='flag-5'>UVM</b><b class='flag-5'>序列</b>的創(chuàng)建和運(yùn)行及中斷服務(wù)程序?qū)崿F(xiàn)方案

    重用機(jī)床編碼技術(shù)及重構(gòu)算法研究

    重用機(jī)床編碼技術(shù)及重構(gòu)算法研究摘要:在產(chǎn)品開發(fā)過程80%的設(shè)計(jì)工作是在重用的基礎(chǔ)上進(jìn)行的。設(shè)計(jì)重用能夠縮短產(chǎn)品開發(fā)周期、降低設(shè)計(jì)成本和避
    發(fā)表于 05-17 11:58

    IC驗(yàn)證"為什么要學(xué)習(xí)UVM呢"

    驗(yàn)證的基本常識(shí),將會(huì)散落在各個(gè)章節(jié)之間。UVM的一些高級(jí)功能,如何靈活地使用sequence機(jī)制、factory機(jī)制等。如何編寫代碼才能保證重用性。
    發(fā)表于 12-01 15:09

    數(shù)字IC驗(yàn)證之“什么是UVM”“UVM的特點(diǎn)”“UVM提供哪些資源”(2)連載...

    會(huì)在一定范圍內(nèi)產(chǎn)生,減少無用的激勵(lì),提高效率。支持覆蓋率驅(qū)動(dòng)模式,根據(jù)當(dāng)前覆蓋率的情況,驗(yàn)證工程師可以決定下一步的驗(yàn)證內(nèi)容,當(dāng)覆蓋率達(dá)到了一定的要求時(shí),就可以宣告驗(yàn)證工作的完成。uvm驗(yàn)證平臺(tái),它具有很高的重用
    發(fā)表于 01-21 16:00

    數(shù)字IC驗(yàn)證之“典型的UVM平臺(tái)結(jié)構(gòu)”(3)連載...

    應(yīng)用的過程,將uvm的組件封裝起來,可以將這些封裝的組件呢作為一個(gè)整體進(jìn)行重用,在進(jìn)行芯片級(jí)或者是系統(tǒng)級(jí)驗(yàn)證的時(shí)候,往往會(huì)出現(xiàn)多個(gè)模塊的驗(yàn)證?! 〈藭r(shí),測(cè)試平臺(tái)的結(jié)構(gòu)會(huì)發(fā)生變化,圖中的測(cè)試平臺(tái)實(shí)現(xiàn)了
    發(fā)表于 01-22 15:32

    談?wù)?b class='flag-5'>UVMuvm_info打印

    uvm_report_enabled(xxx),會(huì)分析傳過來的severity和id的配置verbosity要大于傳過來的verbosity,(get_report_verbosity_level(severity, id
    發(fā)表于 03-17 16:41

    重用機(jī)床編碼技術(shù)及重構(gòu)算法研究

    重用機(jī)床編碼技術(shù)及重構(gòu)算法研究:摘要:在產(chǎn)品開發(fā)過程80%的設(shè)計(jì)工作是在重用的基礎(chǔ)上進(jìn)行的。設(shè)計(jì)重用能夠縮短產(chǎn)品開發(fā)周期、降低設(shè)計(jì)成本和
    發(fā)表于 05-16 15:31 ?14次下載

    UVM驗(yàn)證平臺(tái)執(zhí)行硬件加速

    UVM已經(jīng)成為了一種高效率的、從模塊級(jí)到系統(tǒng)級(jí)完整驗(yàn)證環(huán)境開發(fā)標(biāo)準(zhǔn),其中一個(gè)關(guān)鍵的原則是UVM可以開發(fā)出重用的驗(yàn)證組件。獲得重用動(dòng)力的一個(gè)
    發(fā)表于 09-15 17:08 ?14次下載
    <b class='flag-5'>UVM</b>驗(yàn)證平臺(tái)執(zhí)行硬件加速

    ASIC芯片設(shè)計(jì)之UVM驗(yàn)證

    百度百科對(duì)UVM的釋義如下:通用驗(yàn)證方法學(xué)(Universal Verification Methodology, UVM)是一個(gè)以SystemVerilog類庫為主體的驗(yàn)證平臺(tái)開發(fā)框架,驗(yàn)證工程師可以利用其
    發(fā)表于 11-30 12:47 ?1417次閱讀

    什么是UVM environment?

    UVM environment**包含多個(gè)重用的驗(yàn)證組件,并根據(jù)test case的需求進(jìn)行相應(yīng)的配置。例如,UVM environment可能具有多個(gè)agent(對(duì)應(yīng)不同的inte
    的頭像 發(fā)表于 03-21 11:35 ?1016次閱讀
    什么是<b class='flag-5'>UVM</b> environment?

    UVM的虛擬序列:為什么,如何?

    大多數(shù)UVM測(cè)試平臺(tái)由重復(fù)使用的驗(yàn)證組件組成,除非我們正在對(duì)像MIPI-CSI這樣的簡單協(xié)議進(jìn)行塊級(jí)驗(yàn)證??紤]驗(yàn)證簡單協(xié)議的場(chǎng)景;在這種情況下,我們可以忍受只有一個(gè)音序器將刺激發(fā)送給驅(qū)動(dòng)器。頂級(jí)
    的頭像 發(fā)表于 05-29 09:46 ?736次閱讀

    介紹從一組重用的驗(yàn)證組件構(gòu)建測(cè)試平臺(tái)所需的步驟

    本文介紹了從一組重用的驗(yàn)證組件構(gòu)建測(cè)試平臺(tái)所需的步驟。UVM促進(jìn)了重用,加速了測(cè)試平臺(tái)構(gòu)建的過程。
    的頭像 發(fā)表于 06-13 09:11 ?433次閱讀
    介紹從一組<b class='flag-5'>可</b><b class='flag-5'>重用</b>的驗(yàn)證組件<b class='flag-5'>中</b>構(gòu)建測(cè)試平臺(tái)所需的步驟

    重用的驗(yàn)證組件構(gòu)建測(cè)試平臺(tái)的步驟

    本文介紹了從一組重用的驗(yàn)證組件構(gòu)建測(cè)試平臺(tái)所需的步驟。UVM促進(jìn)了重用,加速了測(cè)試平臺(tái)構(gòu)建的過程。 首先對(duì) 測(cè)試平臺(tái)集成者(testbe
    的頭像 發(fā)表于 06-13 09:14 ?539次閱讀
    <b class='flag-5'>可</b><b class='flag-5'>重用</b>的驗(yàn)證組件<b class='flag-5'>中</b>構(gòu)建測(cè)試平臺(tái)的步驟

    創(chuàng)建UVM Testcase的步驟

    UVM,Testcase是一個(gè)類,它封裝了測(cè)試用例開發(fā)者編寫的特定激勵(lì)序列。
    的頭像 發(fā)表于 06-15 09:41 ?1438次閱讀
    創(chuàng)建<b class='flag-5'>UVM</b> Testcase的步驟

    UVMuvm_config_db機(jī)制背后的大功臣

    本次講一下UVMuvm_config_db,在UVM中提供了一個(gè)內(nèi)部數(shù)據(jù)庫,可以在其中存儲(chǔ)給定名稱下的值,之后可以由其它TB組件去檢索。
    的頭像 發(fā)表于 06-20 17:28 ?1254次閱讀