本文內(nèi)容整理自CSDN博主:Starry、 ,UVM實戰(zhàn)卷1—張強(qiáng)—機(jī)械工業(yè)出版社
一、寄存器模型的基本概念
寄存器是硬件模塊之間互相交談的窗口,在驗證的過程中,我們需要對寄存器的配置和功能也進(jìn)行驗證。
硬件設(shè)計中,一定會用到寄存器對功能進(jìn)行配置,而我們在進(jìn)行驗證功能模塊的時候,需要讀出此時寄存器的配置或狀態(tài)。常規(guī)的想法是通過總線直接進(jìn)入DUT中進(jìn)行讀寫,但這樣有許多缺點,比如訪問速度,占用資源等缺點,UVM提供的寄存器模型,顧名思義,就是可以在驗證模塊搭建中,搭建寄存器模型,并且這個模型具有自動預(yù)測,更新硬件值等功能。

1.1 寄存器模型組成
uvm_reg_field :寄存器模型中的最小單位;
uvm_reg:比uvm_reg_field高一個級別,但仍然是比較小的一個單位;
uvm_reg_block:顧名思義,uvm_reg的塊,可以擁有許多的uvm_reg,也可以加入其他的uvm_reg_block;
uvm_reg_map:每個寄存器在加入寄存器模型時,都必須要有其地址,uvm_reg_map就是儲存這些地址并可以轉(zhuǎn)換其真實物理地址的一個成員。每個uvm_reg_block內(nèi)部都自帶一個默認(rèn)的uvm_reg_map——default_map
1.2 構(gòu)建寄存器模型的步驟
uvm_reg:
首先,需要從uvm_reg中派生一個類:class reg_invert extends uvm_reg;
????在類中,聲明uvm_reg_field的成員變量:rand uvm_reg_field reg_data;
????在這個類中的build()方法中,創(chuàng)建field:reg_data = uvm_reg_field::type_id::create("reg_data");
? ??配置你的域:reg_data.configure(this, 1, 0, "RW", 1, 0, 1, 1, 0);
最后在new()方法中,使用super.new(name, 16, UVM_NO_COVERAGE);

build()方法:?
主要用于域的例化和configure
configure()方法:
主要用于對寄存器域進(jìn)行配置,各輸入變量含義如下
● uvm_reg parent:所屬寄存器的句柄
● int unsigned size:域?qū)?/p>
● int unsigned lsb_pos:該域的最低bit在寄存器中的下標(biāo)bit號。
● string access:該域的存取方式,包括"RO", “RC”, “RS”, “WC”, "WS"等
● bit volatile:是否易失,一般為0
● uvm_reg_data_t reset:復(fù)位時的默認(rèn)值
● bit has_reset:是否有復(fù)位,一般為1
● bit is_rand:是否為隨機(jī)的
● bit individually_accessible:是否可單獨存取
new()方法:
● string name="":名字
● int unsigned n_bits:寄存器總長度,單位bit
● int has_coverage:是否加入覆蓋率
uvm_reg_block:
由uvm_reg_block派生的類就是用戶使用的寄存器模型塊了,它可包含多個寄存器reg,且必須包含一個寄存器地址map。
首先聲明繼承自uvm_reg_block:reg_model extends uvm_reg_block;
聲明uvm_reg:rand reg_invert invert;
在build()里需要創(chuàng)建uvm_reg和uvm_reg_map:
????default_map = create_map("default_map", 0, 2, UVM_BIG_ENDIAN, 0);
????invert = reg_invert::type_id::create("invert", , get_full_name());
然后配置configure()、build()(注意此處的build是嵌套u(yù)vm_reg內(nèi)的build函數(shù)):
? ? invert. configure(this. null, "");
? ? invert.build();
最后還需要在map里添加這個reg;
? ? default_map.add_reg(invert, `h9, "RW");

default_map與create_map():
default_map是uvm_reg_block中的成員,是系統(tǒng)已經(jīng)默認(rèn)聲明好的default_map,所以寄存器組類定義中不用再創(chuàng)建新的uvm_reg_map成員了,只需要在build中將其例化。
lock_model():
一般在寄存器block定義完之后,要進(jìn)行鎖定,reg_model中就不能再添加新的寄存器了。
1.3 總線適配器 adapter
有了寄存器塊reg_block類還不夠,還要寫一個適配器adapter類。
因為對寄存器模型操作的transaction是uvm_reg_bus_op類的
該類與driver驅(qū)動dut的總線bus_trans不一樣,uvm_reg_bus_op具有更高的可讀性,所以需要一個adapter來作trans類型轉(zhuǎn)換。
uvm_reg_adapter::reg2bus() 與 uvm_reg_adapter::bus2reg():
在通信過程中,無論讀或?qū)?,寄存器模型都會通過sequence產(chǎn)生一個uvm_reg_bus_op的變量,此變量中存儲著操作類型和操作的地址。此變量中的信息要經(jīng)過一個轉(zhuǎn)換器(adapter)轉(zhuǎn)換后,交給bus_sequencer,隨后交給bus_driver,由bus_driver實現(xiàn)最終的前門訪問讀寫操作。