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

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

UVM中的可重用序列

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

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

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

usb_simple_sequence 擴展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 的設備。測試編寫者可以通過將此序列分配給頂級測試中序列器的默認序列來調用此序列。

類usb_simple_bulk_test擴展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

到目前為止,事情看起來簡單明了。為了確保序列可重用于更復雜的場景,我們必須遵循更多準則。

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

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

請注意,starting_phase僅為作為特定階段的默認序列啟動的序列定義。如果已通過調用序列的 start 方法顯式啟動它,則用戶負責設置starting_phase。

類usb_simple_bulk_test擴展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

結束類

使用 UVM 配置從頂級測試中獲取值。在上面的示例中,沒有為測試編寫者提供可控性,因為序列不使用配置從頂級測試或序列中獲取值(將使用此序列來構建復雜場景)。修改序列以更好地控制使用此簡單序列的頂級測試或序列。

類 usb_simple_sequence 擴展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

結束類

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

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

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

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

虛擬任務正文();

    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)

結束任務:正文

使用'uvm_do_with時總是要小心的,因為它會在較低級別的序列或序列項中的任何現有約束之上添加約束。

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

虛擬任務正文();

    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)

結束任務:正文

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

類 usb_complex_sequence 擴展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

結束類

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

審核編輯:郭婷


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯系本站處理。 舉報投訴
  • usb
    usb
    +關注

    關注

    60

    文章

    7773

    瀏覽量

    262379
  • IP
    IP
    +關注

    關注

    5

    文章

    1541

    瀏覽量

    148919
  • UVM
    UVM
    +關注

    關注

    0

    文章

    181

    瀏覽量

    19087
收藏 人收藏

    評論

    相關推薦

    UVM序列的創(chuàng)建和運行及中斷服務程序實現方案

    SystemVerilog通用驗證方法(UVM)是一種生成測試和檢查結果以進行功能驗證的有效方法,最適合用于塊級IC或FPGA或其他“小型”系統。在UVM測試臺中,大多數活動是通過編寫序列來生
    的頭像 發(fā)表于 04-09 16:09 ?4024次閱讀
    <b class='flag-5'>UVM</b><b class='flag-5'>序列</b>的創(chuàng)建和運行及中斷服務程序實現方案

    重用機床編碼技術及重構算法研究

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

    IC驗證"為什么要學習UVM呢"

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

    數字IC驗證之“什么是UVM”“UVM的特點”“UVM提供哪些資源”(2)連載...

    會在一定范圍內產生,減少無用的激勵,提高效率。支持覆蓋率驅動模式,根據當前覆蓋率的情況,驗證工程師可以決定下一步的驗證內容,當覆蓋率達到了一定的要求時,就可以宣告驗證工作的完成。uvm驗證平臺,它具有很高的重用
    發(fā)表于 01-21 16:00

    數字IC驗證之“典型的UVM平臺結構”(3)連載...

    應用的過程,將uvm的組件封裝起來,可以將這些封裝的組件呢作為一個整體進行重用,在進行芯片級或者是系統級驗證的時候,往往會出現多個模塊的驗證。  此時,測試平臺的結構會發(fā)生變化,圖中的測試平臺實現了
    發(fā)表于 01-22 15:32

    談談UVMuvm_info打印

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

    重用機床編碼技術及重構算法研究

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

    UVM驗證平臺執(zhí)行硬件加速

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

    ASIC芯片設計之UVM驗證

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

    什么是UVM environment?

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

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

    大多數UVM測試平臺由重復使用的驗證組件組成,除非我們正在對像MIPI-CSI這樣的簡單協議進行塊級驗證。考慮驗證簡單協議的場景;在這種情況下,我們可以忍受只有一個音序器將刺激發(fā)送給驅動器。頂級
    的頭像 發(fā)表于 05-29 09:46 ?674次閱讀

    介紹從一組重用的驗證組件構建測試平臺所需的步驟

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

    重用的驗證組件構建測試平臺的步驟

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

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

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

    UVMuvm_config_db機制背后的大功臣

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