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

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

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

寄存器模型Register Model學(xué)習(xí)筆記

數(shù)字芯片實(shí)驗(yàn)室 ? 來源:數(shù)字芯片實(shí)驗(yàn)室 ? 2023-07-11 09:20 ? 次閱讀

1.寄存器模型( Register model )簡介

UVM的寄存器模型是一組高級(jí)抽象的類,用來對(duì)DUT中具有地址映射的寄存器和存儲(chǔ)器進(jìn)行建模。它非常貼切地反映DUT中寄存器的各種特性,可以產(chǎn)生激勵(lì)作用于DUT并進(jìn)行寄存器功能檢查。

通過UVM的寄存器模型,可以簡單高效地實(shí)現(xiàn)對(duì)DUT的寄存器進(jìn)行前門或后門操作。它本身也提供了一些寄存器測試的sequence,方便用戶直接使用。

UVM的寄存器模型是高度抽象化的,不依賴具體DUT而獨(dú)立存在的。

用戶必須創(chuàng)建一個(gè)繼承自u(píng)vm_reg_adapter的類,實(shí)現(xiàn)uvm_reg_bus_op與真正作用到具體dut上的transaction的互相轉(zhuǎn)換。

UVM寄存器模型基本結(jié)構(gòu)如下圖所示。uvm_reg_block是UVM register layer的類。uvm_reg_adapter是必不可少的,它實(shí)現(xiàn)了bus driver需要的transaction和中間變量uvm_reg_bus_op之間的相互轉(zhuǎn)換。寄存器前門訪問是依靠寄存器模型自動(dòng)產(chǎn)生sequence,并發(fā)送給bus driver來完成的。

be63660a-1f2c-11ee-962d-dac502259ad0.png

2.UVM 寄存器模型的層次結(jié)構(gòu)

uvm_reg_field是寄存器模型的最小單位,和DUT的每個(gè)register里的bit filed對(duì)應(yīng)。

uvm_reg 和dut中每個(gè)register對(duì)應(yīng),其寬度一般和總線位寬一致,里面可以包含多個(gè)uvm_reg_field。

uvm_reg_block里包含uvm_reg,一般一個(gè)最底層模塊級(jí)的DUT的所有寄存器具有相同的基地址,會(huì)放在一個(gè)reg_block中。uvm_reg_block內(nèi)也可包含其他低層次的reg_block。

reg_block里有含有uvm_reg_map類的對(duì)象default_map,進(jìn)行地址映射,以及用來完成寄存器前后門訪問操作。

一個(gè)寄存器模型必須包含一個(gè)reg_block。一個(gè)reg_block可以包含多個(gè)reg_map, 從而實(shí)現(xiàn)一個(gè)reg_block應(yīng)用到不同總線,或不同地址段上。

uvm_mem是對(duì)dut中memory進(jìn)行建模使用的。

這些類均是繼承自u(píng)vm_object類。一個(gè)完整的register model由這些層次化的register元素構(gòu)成,放到頂層的reg block中。一個(gè)reg block可以包含子block,register,register file和memories,如下圖所示。

bec859ca-1f2c-11ee-962d-dac502259ad0.png

需要說明的是,因?yàn)橐粋€(gè)項(xiàng)目中存在大量的寄存器,用人工來維護(hù)RAL不僅耗時(shí)耗力,更容易出現(xiàn)錯(cuò)誤,所以正常情況下應(yīng)該使用工具產(chǎn)生和維護(hù)UVM寄存器模型:

Synopsy VCS中自帶的ralgen工具可以產(chǎn)生uvm 寄存器模型,具體使用方法可參考

UVM Register Abstraction Layer Generator User Guide(uvm_ralgen_ug.pdf

3. 創(chuàng)建和使用寄存器模型

Step1: 對(duì)每個(gè)寄存器進(jìn)行定義

class cfs_dut_reg_ctrl extends uvm_reg;


   rand uvm_reg_field reserved;  //reserved
   rand uvm_reg_field enable; //control for enabling the DUT
   `uvm_object_utils(cfs_dut_reg_config)
    function new(string name = "cfs_dut_reg_config");
      //specify the name of the register, its width in bits and if it has coverage
       super.new(name, 32, 1);
    endfunction


    virtual function void build();
      reserved = uvm_reg_field::create("reserved");
      //specify parent, width, lsb position, rights, volatility,
      //reset value, has reset, is_rand, individually_accessible
reserved.configure(this,31,1,"RO",0,0,1,1,1);
      enable = uvm_reg_field::create("enable");
      enable.configure(this, 1, 0, "RW", 0, 0, 1, 1, 1);
   endfunction
endclass

在uvm_reg的new中,要將寄存器的寬度傳入super.new()的第二個(gè)參數(shù),super.new()的第三個(gè)參數(shù)是uvm_coverage_model_e類型,用以設(shè)置寄存器是否參與加入覆蓋率:

bef9854a-1f2c-11ee-962d-dac502259ad0.png

uvm_reg類有一個(gè)build函數(shù),這個(gè)build和UVM_component的bulid_phase并不一樣,并不會(huì)自動(dòng)執(zhí)行,需要手動(dòng)調(diào)用。

要使用uvm_field的configure函數(shù)對(duì)各個(gè)field進(jìn)行詳細(xì)配置,它有9個(gè)參數(shù):

enable.configure( .parent              ( this ),
.size                   ( 3    ),
.lsb_pos                ( 0    ),
.access                 ( "RW" ),
.volatile               ( 0    ),
.reset                  ( 0    ),
.has_reset              ( 1    ),
.is_rand                ( 1    ),
.individually_accessible( 0    ) );




 參數(shù)一是此域的父輩,也就是此域位于哪個(gè)寄存器中,即是this;
 參數(shù)二是此域的寬度;
 參數(shù)三是此域的最低位在整個(gè)寄存器的位置,從0開始計(jì)數(shù);
 參數(shù)四表示此字段的存取方式;
 參數(shù)五表示是否是易失的(volatile),這個(gè)參數(shù)一般不會(huì)使用;
 參數(shù)六表示此域上電復(fù)位后的默認(rèn)值;
 參數(shù)七表示此域時(shí)都有復(fù)位;
 參數(shù)八表示這個(gè)域是否可以隨機(jī)化;
 參數(shù)九表示這個(gè)域是否可以單獨(dú)存取。

Step2: 將寄存器放入register block容器中,并加入到對(duì)應(yīng)的Address Map

class cfs_dut_reg_block extends uvm_reg_block;
   `uvm_object_utils(cfs_dut_reg_block)
//Control register
   rand cfs_dut_reg_ctrl ctrl;
//Status register
   rand cfs_dut_reg_status status;


function new(string name = "cfs_dut_reg_block");
    super.new(name, UVM_CVR_ALL);
      ctrl = cfs_dut_reg_ctrl::create("ctrl");
      status = cfs_dut_reg_status::create("status");
endfunction




   virtual function void build();
default_map=create_map(“default_map”,0,4,UVM_BIG_ENDINA,0);
      ctrl.configure(this, null, "");
      ctrl.build();
default_map.add_reg(ctrl,`h10,"RW")


      status.configure(this, null, "");
      status.build();
      default_map.add_reg(status,`h14,"RO")




   endfunction
endclass

reg block中也有build函數(shù),在其中要做如下事情:

調(diào)用create_map函數(shù)完成default_map的實(shí)例化,

default_map = create_map(“default_map”,0,2,UVM_BIG_ENDINA,0);

create_map的第一個(gè)參數(shù)是名字,第二個(gè)參數(shù)是該reg block的基地址,第三個(gè)參數(shù)是寄存器所映射到的總線的寬度(單位是byte,不是bit),第四個(gè)參數(shù)是大小端,第五個(gè)參數(shù)表示該寄存器能否按byte尋址。

完成每個(gè)寄存器的build及configure操作

uvm_reg的configure函數(shù)原型:

function void configure ( uvm_reg_block blk_parent, uvm_reg_file regfile_parent = null, string hdl_path = "" )

其第一個(gè)參數(shù)是所在reg block的指針,第二個(gè)參數(shù)是reg_file指針,第三個(gè)是寄存器后面訪問路徑—string類型。

把每個(gè)寄存器加入到default_map中。uvm_reg_map存有各個(gè)寄存器的地址信息。

default_map.add_reg(ctrl, `h10,"RW")

第一個(gè)參數(shù)是要添加的寄存器名,第二個(gè)是地址,第三個(gè)是寄存器的讀寫屬性。如果一個(gè)寄存器可以通過兩個(gè)物理總線訪問,則需要將其添加到多個(gè)address map中。

Step3: 創(chuàng)建Register Adapter

寄存器模型的前門操作都會(huì)通過sequence產(chǎn)生一個(gè)uvm_reg_bus_op類型的變量,他不能直接被bus sequencer和driver接受。需要定義一個(gè)繼承自uvm_reg_adpater的adapter,來完成與bus transaction之間的轉(zhuǎn)換,之后才能交給交給bus_sequencer和bus_driver,實(shí)現(xiàn)前門訪問。而從bus_driver返回的rsp,也需要由adapter轉(zhuǎn)換成uvm_reg_bus_op類型變量,返回給寄存器模型,用來更新內(nèi)部值。在adapter中,要實(shí)現(xiàn):

1. reg2bus: 其作用是將uvm_reg_bus_op類型變量轉(zhuǎn)換成bus_sequencer能夠接受的transaction。

virtual function uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw);

2. bus2reg: 其將收集到的transaction轉(zhuǎn)換成寄存器模型使用的uvm_reg_bus_op類型變量,用以更新寄存器模型中相應(yīng)寄存器的值。

virtual function void bus2reg(uvm_sequence_item bus_item, ref uvm_reg_bus_op rw);

class cfs_dut_reg_adapter extends uvm_reg_adapter;
   `uvm_object_utils(cfs_dut_reg_adapter)




   function new(string name = "cfs_dut_reg_adapter");
      super.new(name);
   endfunction
        
   virtual function uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw);
      acme_apb_drv_transfer transfer = acme_apb_drv_transfer::create("transfer");


      if(rw.kind == UVM_WRITE) begin
         transfer.direction = APB_WRITE;
      end
      else begin
         transfer.direction = APB_READ;
      end 
            
      transfer.data = rw.data;
      transfer.address = rw.addr;
      
      return transfer;
   endfunction
        
   virtual function void bus2reg(uvm_sequence_item bus_item, ref uvm_reg_bus_op rw);
      acme_apb_mon_transfer transfer;
            
      if($cast(transfer, bus_item)) begin
         if(transfer.direction == APB_WRITE) begin
            rw.kind = UVM_WRITE;
         end
         else begin
            rw.kind = UVM_READ;
         end


         rw.addr = transfer.address;
         rw.data = transfer.data;
         rw.status = UVM_IS_OK;
      end
      else begin
         `uvm_fatal(get_name(), $sformatf("Could not cast to acme_apb_mon_transfer: %s", 
            bus_item.get_type_name()))
      end
   endfunction
endclass

Step4: 頂層reg block對(duì)象的創(chuàng)建及使用

整個(gè)仿真平臺(tái)只創(chuàng)建一個(gè)reg model對(duì)象,在其他地方使用指針調(diào)用。一般在test中創(chuàng)建頂層reg_block,及adapt和predictor。

// in  base test class
   ...
   virtual function void build_phase(uvm_phase phase);
      super.build_phase(phase);
      
      //create all the elements of the environment
      reg_block = cfs_dut_reg_block::create("reg_block",this);
      apb_agent = acme_apb_agent::create("apb_agent", this);
      adapter = cfs_dut_reg_adapter::create("adapter");
      predictor = uvm_reg_predictor#(acme_apb_mon_transfer)::create("predictor", this);
      reg_block.configure(null,"");
      reg_block.build();
      reg_block.lock_model();
      reg_block.reset("HARD");
   endfunction
   ...

reg_block傳完要調(diào)用其configure函數(shù),配置后門訪問路徑。

Step5: 將Address Map連接到Bus sequencer和Adapter

在test或env的connect phase中,調(diào)用default_map或其他用戶自定義的address map對(duì)象中的set_sequencer方法, 并把前門操作的bus sequencer及adaptor作為參數(shù)傳入。

virtual function void connect_phase(uvm_phase phase);
      super.connect_phase(phase);
      
      //required to start physical register accesses using the registers
      reg_block.default_map.set_sequencer(apb_agent.sequencer, adapter);
      
      predictor.map = reg_block.default_map;
      predictor.adapter = adapter;
      apb_agent.monitor.output_port.connect(predictor.bus_in);
   endfunction

Step6: 在sequence或其他component中使用寄存器模型

在sequence中使用要先在對(duì)應(yīng)的sequencer中定義一個(gè)頂層reg_block的指針,并指向base_test的reg_block對(duì)應(yīng),之后再sequence中調(diào)用p_sequencer訪問,如:

p_sequencer.p_reg_block.enable.wirte(status,1,UVM_FRONTDOOR); // 前門訪問 front-door
p_sequencer.p_reg_block.enable.re'a'd(status,value,UVM_BACKDOOR);// 后門訪問 back-door

3、寄存器訪問方法

前門訪問和后面訪問的區(qū)別

前門訪問是通過物理總線向dut發(fā)起寄存器訪問操作,消耗仿真時(shí)間

后面操作不通過物理總線,不消耗仿真時(shí)間

前門訪問過程以write為例:

當(dāng)調(diào)用寄存器的write()任務(wù)后,產(chǎn)生uvm_reg_item類型的transaction:rw,之后調(diào)用uvm_reg::do_write()。

在uvm_reg_map中,調(diào)用reg_adapter.reg2bus將rw轉(zhuǎn)換成bus driver對(duì)應(yīng)的transaction。

把transaction交給sequencer,最終由bus driver驅(qū)動(dòng)到對(duì)應(yīng)的bus interface上。

bus monitor在bus interface上檢測到bus transaction 。

reg_predictor會(huì)調(diào)用reg_adapter.bus2reg將該bus transaction轉(zhuǎn)換成uvm_reg_item。

從driver中返回的req會(huì)轉(zhuǎn)換成uvm_reg_item類型,如防止sequencer的response隊(duì)列溢出,需要在adapter中設(shè)置provides_reponses.

寄存器模型根據(jù)返回的uvm_reg_item來更新寄存器的value,m_mirrored和m_desired三個(gè)值

bf219a44-1f2c-11ee-962d-dac502259ad0.png

原文鏈接:https://blog.csdn.net/wonder_coole/article/details/91879378






審核編輯:劉清

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

    關(guān)注

    31

    文章

    5294

    瀏覽量

    119814
  • 存儲(chǔ)器
    +關(guān)注

    關(guān)注

    38

    文章

    7430

    瀏覽量

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

    關(guān)注

    0

    文章

    181

    瀏覽量

    19121
  • VCS
    VCS
    +關(guān)注

    關(guān)注

    0

    文章

    78

    瀏覽量

    9581
  • DUT
    DUT
    +關(guān)注

    關(guān)注

    0

    文章

    189

    瀏覽量

    12309

原文標(biāo)題:UVM學(xué)習(xí)筆記--寄存器模型 Register Model

文章出處:【微信號(hào):數(shù)字芯片實(shí)驗(yàn)室,微信公眾號(hào):數(shù)字芯片實(shí)驗(yàn)室】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    UVM寄存器模型的常規(guī)方法有哪些呢?

    在應(yīng)用寄存器模型時(shí), 除了利用它的寄存器信息, 還可以利用它來跟蹤寄存器的值。
    的頭像 發(fā)表于 11-25 09:27 ?1675次閱讀
    UVM<b class='flag-5'>寄存器</b><b class='flag-5'>模型</b>的常規(guī)方法有哪些呢?

    STM32學(xué)習(xí)筆記(寄存器版本)

    STM32學(xué)習(xí)筆記(寄存器版本)
    發(fā)表于 08-22 10:45

    如何構(gòu)建UVM寄存器模型并將寄存器模型集成到驗(yàn)證環(huán)境中

    寄存器register)是數(shù)字系統(tǒng)中非常重要的部件,它常被用于數(shù)字系統(tǒng)的功能控制(control)和狀態(tài)(status)顯示。RAL(Register Abstract Layer,寄存器
    發(fā)表于 09-23 14:29

    什么是Register Renaming(寄存器重命名)/R

    什么是Register Renaming(寄存器重命名)/Resource contention(資源沖突)  Register Renaming: (寄存器重命名)把一個(gè)
    發(fā)表于 02-04 10:35 ?2371次閱讀

    什么是Register Pressure(寄存器不足) /

    什么是Register Pressure(寄存器不足) / Register Renaming(寄存器重命名)?   Register P
    發(fā)表于 02-04 11:02 ?1333次閱讀

    ARM寄存器學(xué)習(xí)總結(jié)

    ARM寄存器學(xué)習(xí)總結(jié)
    發(fā)表于 01-04 15:10 ?0次下載

    寄存器變量

    C語言中使用關(guān)鍵字register來聲明局部變量為寄存器變量。寄存器變量的值會(huì)被存放在CPU的寄存器中,每當(dāng)需要使用它們時(shí),CPU就可以直接使用,而無須再通過控制
    發(fā)表于 06-03 10:13 ?2319次閱讀

    學(xué)習(xí)筆記】51單片機(jī)常用寄存器

    SCON控制寄存器SCON(Serial Control Register)串行口控制寄存器,用于控制串行通信的方式選擇、接收和發(fā)送,指示串口的狀態(tài)。SCON既可以字節(jié)尋址,也可以位尋址,其字節(jié)地址
    發(fā)表于 11-14 16:21 ?9次下載
    【<b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b>】51單片機(jī)常用<b class='flag-5'>寄存器</b>

    STM32學(xué)習(xí)筆記(2)——寄存器

    STM32 第二天寄存器寄存器功能:寄存器的功能是存儲(chǔ)二進(jìn)制代碼,它是由具有存儲(chǔ)功能的觸發(fā)組合起來構(gòu)成的。一個(gè)觸發(fā)可以存儲(chǔ)1位二進(jìn)制代碼
    發(fā)表于 12-08 17:36 ?18次下載
    STM32<b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b>(2)——<b class='flag-5'>寄存器</b>

    什么是寄存器

    有一個(gè)很無語的問題,什么是register?天天在配寄存器,但是不知道寄存器是什么。寄存器的地址偏移有的是1,有的是4。這個(gè)偏移量為什么偏移不是3?偏移量和
    的頭像 發(fā)表于 01-30 16:36 ?3266次閱讀
    什么是<b class='flag-5'>寄存器</b>

    四種類型的 JTAG 數(shù)據(jù)寄存器介紹

    本文將介紹四種類型的 JTAG 數(shù)據(jù)寄存器,分別是: Boundary Scan Register (BSR) 邊界掃描寄存器 Bypass Register (BR) 旁路
    發(fā)表于 02-07 10:01 ?3390次閱讀

    簡述RAL寄存器模型基礎(chǔ)

    RAL(Register Abstract Layer,寄存器抽象層),通常也叫寄存器模型,顧名思義就是對(duì)寄存器這個(gè)部件的建模。本文要介紹的
    的頭像 發(fā)表于 02-14 16:55 ?2649次閱讀
    簡述RAL<b class='flag-5'>寄存器</b><b class='flag-5'>模型</b>基礎(chǔ)

    RAL寄存器模型操作圖鑒

    寄存器模型操作,指的是通過寄存器模型對(duì)RTL中寄存器進(jìn)行讀寫訪問,或者同步寄存器
    的頭像 發(fā)表于 05-17 09:01 ?883次閱讀
    RAL<b class='flag-5'>寄存器</b><b class='flag-5'>模型</b>操作圖鑒

    RAL寄存器模型操作指南

    寄存器模型操作,指的是通過寄存器模型對(duì)RTL中寄存器進(jìn)行讀寫訪問,或者同步寄存器
    的頭像 發(fā)表于 07-12 09:37 ?1006次閱讀
    RAL<b class='flag-5'>寄存器</b><b class='flag-5'>模型</b>操作指南

    詳解寄存器模型鏡像值

    DUT的配置寄存器的值是實(shí)際值,reg_model有鏡像值、期望值的概念。
    的頭像 發(fā)表于 10-23 09:43 ?153次閱讀
    詳解<b class='flag-5'>寄存器</b><b class='flag-5'>模型</b>鏡像值