本文內(nèi)容整理自CSDN博主:Starry栏赴、 蘑斧,UVM實(shí)戰(zhàn)卷1—張強(qiáng)—機(jī)械工業(yè)出版社
一、寄存器模型的基本概念
寄存器是硬件模塊之間互相交談的窗口须眷,在驗(yàn)證的過程中竖瘾,我們需要對(duì)寄存器的配置和功能也進(jìn)行驗(yàn)證。
硬件設(shè)計(jì)中花颗,一定會(huì)用到寄存器對(duì)功能進(jìn)行配置捕传,而我們?cè)谶M(jìn)行驗(yàn)證功能模塊的時(shí)候,需要讀出此時(shí)寄存器的配置或狀態(tài)扩劝。常規(guī)的想法是通過總線直接進(jìn)入DUT中進(jìn)行讀寫庸论,但這樣有許多缺點(diǎn)职辅,比如訪問速度,占用資源等缺點(diǎn)聂示,UVM提供的寄存器模型域携,顧名思義,就是可以在驗(yàn)證模塊搭建中鱼喉,搭建寄存器模型秀鞭,并且這個(gè)模型具有自動(dòng)預(yù)測,更新硬件值等功能扛禽。
1.1 寄存器模型組成
uvm_reg_field :寄存器模型中的最小單位气筋;
uvm_reg:比uvm_reg_field高一個(gè)級(jí)別,但仍然是比較小的一個(gè)單位旋圆;
uvm_reg_block:顧名思義宠默,uvm_reg的塊,可以擁有許多的uvm_reg灵巧,也可以加入其他的uvm_reg_block搀矫;
uvm_reg_map:每個(gè)寄存器在加入寄存器模型時(shí),都必須要有其地址刻肄,uvm_reg_map就是儲(chǔ)存這些地址并可以轉(zhuǎn)換其真實(shí)物理地址的一個(gè)成員瓤球。每個(gè)uvm_reg_block內(nèi)部都自帶一個(gè)默認(rèn)的uvm_reg_map——default_map
1.2 構(gòu)建寄存器模型的步驟
uvm_reg:
首先,需要從uvm_reg中派生一個(gè)類:class reg_invert extends uvm_reg敏弃;
????在類中卦羡,聲明uvm_reg_field的成員變量:rand uvm_reg_field reg_data;
????在這個(gè)類中的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()方法:
主要用于對(duì)寄存器域進(jìn)行配置瓶颠,各輸入變量含義如下
● uvm_reg parent:所屬寄存器的句柄
● int unsigned size:域?qū)?/p>
● int unsigned lsb_pos:該域的最低bit在寄存器中的下標(biāo)bit號(hào)拟赊。
● string access:該域的存取方式,包括"RO", “RC”, “RS”, “WC”, "WS"等
● bit volatile:是否易失粹淋,一般為0
● uvm_reg_data_t reset:復(fù)位時(shí)的默認(rèn)值
● bit has_reset:是否有復(fù)位吸祟,一般為1
● bit is_rand:是否為隨機(jī)的
● bit individually_accessible:是否可單獨(dú)存取
new()方法:
● string name="":名字
● int unsigned n_bits:寄存器總長度,單位bit
● int has_coverage:是否加入覆蓋率
uvm_reg_block:
由uvm_reg_block派生的類就是用戶使用的寄存器模型塊了桃移,它可包含多個(gè)寄存器reg屋匕,且必須包含一個(gè)寄存器地址map。
首先聲明繼承自u(píng)vm_reg_block:reg_model extends uvm_reg_block;
聲明uvm_reg:rand reg_invert invert借杰;
在build()里需要?jiǎng)?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里添加這個(gè)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類還不夠专缠,還要寫一個(gè)適配器adapter類雷酪。
因?yàn)閷?duì)寄存器模型操作的transaction是uvm_reg_bus_op類的
該類與driver驅(qū)動(dòng)dut的總線bus_trans不一樣,uvm_reg_bus_op具有更高的可讀性涝婉,所以需要一個(gè)adapter來作trans類型轉(zhuǎn)換哥力。
uvm_reg_adapter::reg2bus() 與 uvm_reg_adapter::bus2reg():
在通信過程中,無論讀或?qū)懚胀洌拇嫫髂P投紩?huì)通過sequence產(chǎn)生一個(gè)uvm_reg_bus_op的變量吩跋,此變量中存儲(chǔ)著操作類型和操作的地址。此變量中的信息要經(jīng)過一個(gè)轉(zhuǎn)換器(adapter)轉(zhuǎn)換后渔工,交給bus_sequencer锌钮,隨后交給bus_driver,由bus_driver實(shí)現(xiàn)最終的前門訪問讀寫操作引矩。