2011年6月11日 星期六

uvm_config_db的使用(三)

uvm_config_db 取代原始的OVM function

在set方面
set_config_int(...) => uvm_config_db#(uvm_bitstream_t)::set(cntxt,...)
set_config_string(...) => uvm_config_db#(string)::set(cntxt,...)
set_config_object(...) => uvm_config_db#(uvm_object)::set(cntxt,...)

在get方面
get_config_int(...) => uvm_config_db#(uvm_bitstream_t)::get(cntxt,...)
get_config_string(...) => uvm_config_db#(string)::get(cntxt,...)
get_config_object(...) => uvm_config_db#(uvm_object)::get(cntxt,...)

uvm_config_db的get/set function的語法
static function bit get(
uvm_component cntxt,


string inst_name,


string field_name,

ref T value )


static function void set( uvm_component cntxt,

string inst_name,

string field_name,

T value )
其它使用的例子
uvm_config_db#(int)::set(this,"*.masters[0]", "master_id", 0);

uvm_config_db#(uvm_object_wrapper)::
set(this, “*.ubus0.masters[0].sequencer.main_phase",
"default_sequence", read_modify_write_seq::type_id::get());

uvm_config_db#(virtual ubus_if)::set(this,"ubus_example_tb0.*","vif",vif);

uvm_config_db的使用(二)

基本使用時機

由於是用來設定verification 的環境變數
基本上我們會放在build_phase()

例子

virtual function void build();
super.build_phase(phase); // Configure before creating the
// subcomponents.
uvm_config_db#(int)::set(this,"ubus0",
"num_masters", 1);
uvm_config_db#(int)::set(this,".ubus0",
"num_slaves", 1);

...



其它的例子如下

— Set the masters[0] agent to be active:
uvm_config_db#(int)::set(this,"ubus0.masters[0]", “is_active",
UVM_ACTIVE);

— Do not collect coverage for masters[0] agent:
uvm_config_db#(int)::set(this, "ubus0.masters[0].monitor",
“coverage_enable", 0);

— Set all slaves (using a wildcard) to be passive:
uvm_config_db#(int)::set(this,"ubus0.slaves*", “is_active", UVM_PASSIVE);

2011年6月10日 星期五

uvm_config_db的使用(一)

先看看文件所述

With Easier UVM, configuration parameters should be accesed by calling uvm_config_db #(T)::get explicitly from the build_phase method and copying their values to local variables:

這是設定verification 的環境之用的


基本使用方法如下

在設定了

`uvm_component_utils_begin(ahb_env)

`uvm_field_int(num_masters, UVM_ALL_ON)

`uvm_component_utils_end

就可以設定

uvm_config_db#(int)::set(this, "*.my_env", "num_masters", 3, this);


因為

All of the functions in uvm_config_db#(T) are static, so they must be called using the :: operator.

就是說必須加上::來用它

電影感想: 三個傻蛋

昨晚看了三個傻蛋的電影
這是講述印度畸形的理工教育
但是台灣其實也差不了多少

考試才是台灣的重點
其它的實作一點都不重要
能從學校快快畢業
然後去大公司或醫院上班領薪水
就是最優秀的學生。
而其他想做些不一樣的人
只能被視為異類,甚至笨蛋

如果你作的事情不是你的興趣,你就不容易全心全意
如果你不能全心全意,你就無法卓越

許多事情會令你無法全心全意
恐懼,害怕,親友的期望...

當你知道你自己是誰,
你就知道該如何去作。

所以先了解你自己的內心呼喊,
然後Just do it .

其實最後電影要講述的是
如果你追求卓越,成功就會不經意的找上門
Just do it, Al Lez Well

uvm phase

基本上UVM phase只是沿用OVM的東東

例如UVM的build_phase 延用OVM的build
UVM的connect延用OVM的connect

只不過在後面加上一個phase的字尾而已

2011年6月9日 星期四

build_phase的使用

當我們一開始UVC時,須先設定UVC內部的變數與環境。
我們會使用build_phase這個function來作

在Agent中
我們會建立monitor, sequencer, driver
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase)
monitor = simple_monitor::type_id::create("monitor",this);
if (is_active == UVM_ACTIVE) begin
// Build the sequencer and driver.
sequencer =
uvm_sequencer#(simple_item)::type_id::create("sequencer",this);
driver = simple_driver::type_id::create("driver",this);
end
endfunction : build_phase

個別的class如drvier內部也會有build_phase
去設定所需的變數,此例使用uvm_config_db
function void build_phase(uvm_phase phase);
super.build_phase(phase);
if(!uvm_config_db#(virtual ubus_if)::get(this, "", "vif", vif))
`uvm_fatal("NOVIF",{"virtual interface must be set for: ",get_full_name(),".vif"});
endfunction: build_phase

在更上層的env中,我們可以用此來設定環境變數,
如Master/Slave數目
virtual function void build_phase(phase);
string inst_name;
super.build_phase(phase);
if(!uvm_config_db#(virtual ubus_if)::get(this,””,
"vif",vif))
`uvm_fatal("NOVIF",{"virtual interface must be set for: ",
get_full_name(),".vif"});
masters = new[num_masters];
for(int i = 0; i < num_masters; i++) begin
$sformat(inst_name, "masters[%0d]", i);
masters[i] = ahb_master_agent::type_id::create(inst_name,this);
end
// Build slaves and other components.
endfunction

所有的build_phase,一定不能忘記super.build_phase(phase);
Properties that are registered as UVM fields using the uvm_field_* macros will be automatically updated by the component’s super.build_phase() method. These properties can then be used to determine the build_phase() execution for the component.

當我們需要從Driver回傳資料回去Sequence時

方法一
seq_item_port.item_done(rsp);

方法二
using the put_response() method.
seq_item_port.put_response(rsp);

方法三
or using the built-in analysis port in uvm_driver.
rsp_port.write(rsp);

NOTE—Before providing the response, the response’s sequence and transaction id must be set to correspond to the request transaction using rsp.set_id_info(req).
NOTE—put_response() is a blocking method, so the sequence must do a corresponding
get_response(rsp)-->在Sequence中使用

2011年6月8日 星期三

Sequence 內部流程

從User Guide剪出

a) Call start_item() to create the item via the factory.
b) Optionally call pre_do() or some other functionality.
c) Optionally randomize item.
d) Optionally call mid_do() or some other functionality, if desired.
e) Call finish_item().
f) Optionally call post_do() or some other functionality.
g) Optionally call get_response().

Sequence Item Flow in Pull Mode

從User Guide剪出

方便複習

Sequence 從start_item到finish_item再到post_do

Driver從get_next_item到item_done如有需要再到rsp_port.write

Sequencer只是一個轉接介面而已



2011年6月7日 星期二

Blogger 字元消失

有時候貼上Code時
沒太注意到有些字元會消失
例如連續兩個"<"
一些換行符號
有時也會導致移除一些code
還是要多注意一下
不要貼太快了
而讓一些code亂掉

這裡要參考
http://01mistery.blogspot.com/2009/07/htmlcode.html


http://01mistery.blogspot.com/2007/10/blogger.html

rsp_export及rsp_port

Drivers or monitors can connect to this port to send responses to the sequencer. Alternatively, a driver can send responses via its seq_item_port.

seq_item_port.item_done(response)
seq_item_port.put(response)
rsp_port.write(response) //--- via this export

The rsp_port in the driver and/or monitor must be connected to the rsp_export in this sequencer in order to send responses through the response analysis port.

而rsp_port的class是uvm_analysis_port

所以有一個內含的method是write去 Send specified value to all connected interface

這個connect interface就是rsp_export(sequencer)


2011年6月6日 星期一

item_done的使用

從UVM library剪出

Function: item_done
//
// Indicates that the request is completed to the sequencer. Any
//
// calls made by a sequence for this item will return.
//
// The current item is removed from the sequencer fifo.
//
// If a response item is provided, then it will be sent back to the requesting
// sequence. The response item must have it's sequence ID and transaction ID
// set correctly, using the <uvm_sequence_item::set_id_info> method:
//
//| rsp.set_id_info(req);設定rsp的id與req相同
//
// Before is called, any calls to peek will retrieve the current
// item that was obtained by . After is called, peek
// will cause the sequencer to arbitrate for a new item.

get_next_item的使用

從UVM library剪出來的

// Task: get_next_item
//
// Retrieves the next available item from a sequence. The call will block
// until an item is available. The following steps occur on this call:
//
// 1 - Arbitrate among requesting, unlocked, relevant sequences - choose the
// highest priority sequence based on the current sequencer arbitration
// mode. If no sequence is available, wait for a requesting unlocked
// relevant sequence, then re-arbitrate.
// 2 - The chosen sequence will return from wait_for_grant
// 3 - The chosen sequence is called
// 4 - The chosen sequence item is randomized
// 5 - The chosen sequence is called
// 6 - Return with a reference to the item
//
// Once is called, must be called to indicate the completion of the request to the sequencer. This will remove the request
// item from the sequencer fifo.

2011年6月5日 星期日

Simple Driver/Sequencer interaction

Cadence example

其中
`uvm_update_sequence_lib_and_item
This macro registers all the sequence types that are associated with the current sequencer and indi-cates the sequencer's generated transaction type as a parameter.

Use `uvm_sequencer_utils and `uvm_update_sequence_lib_and_item to indicate
the generated data item type and field desired automation.
這兩個Marco看起來功能是一樣的,看不出有何差異

但有些時候會有用到`uvm_component_utils
The `uvm_component_utils macro should not be used here(sequencer) because its functionality is embed-ded in `uvm_sequencer_utils. Instead of using the `uvm_component_utils, use `uvm_sequencer_utils, as well as the regular general automation this macro provides sequencer-specific infrastructure.

driver才用`uvm_component_utils

`include "uvm_pkg.sv"
module test;
import uvm_pkg::*;
`include "uvm_macros.svh"

// Simple request item that contains one field, question
class simple_transfer extends uvm_sequence_item;
rand int question;
int answer;
`uvm_object_utils_begin(simple_transfer)
`uvm_field_int(question, UVM_DEFAULT)
`uvm_field_int(answer, UVM_DEFAULT)
`uvm_object_utils_end
function new (string name="simple_transfer");
super.new(name);
endfunction : new
endclass : simple_transfer

class simple_sequencer extends uvm_sequencer #(simple_transfer);
`uvm_sequencer_utils(simple_sequencer)
function new (string name, uvm_component parent);
super.new(name, parent);
`uvm_update_sequence_lib_and_item(simple_transfer)
endfunction : new
endclass

class simple_driver extends uvm_driver #(simple_transfer);
function new (string name, uvm_component parent);
super.new(name, parent);
endfunction : new
`uvm_component_utils(simple_driver)

task run();
get_and_drive();
endtask : run

task get_and_drive();
while (1) begin
seq_item_port.get_next_item(req);
send_to_dut(req);
seq_item_port.item_done();
end
endtask

task send_to_dut(simple_transfer trans);
// Logic to handle sending multiple data items in flight
trans.answer = trans.question + 1;
trans.print();
endtask : send_to_dut

endclass

simple_sequencer s_sequencer0;
simple_driver s_driver0;

initial begin
`uvm_info("TOP", "Beginning test...", UVM_LOW)
//set_config_string("s_sequencer0", "default_sequence", "pipeline_seq");
s_sequencer0 = new("s_sequencer0", null); s_sequencer0.build();
s_driver0 = new("s_driver0", null); s_driver0.build();
s_driver0.seq_item_port.connect(s_sequencer0.seq_item_export);
s_driver0.rsp_port.connect(s_sequencer0.rsp_export);
s_sequencer0.print();
s_driver0.print();
run_test();
end

initial begin
#10000;
global_stop_request();
end

endmodule

Driver與Sequencer的連結方法

在OVM/UVM中最基本的連結方法

Sequencer使用 seq_item_export 連結到
Driver的 seq_item_port(另一個名稱為seq_item_prod_if)

Sequencer的port_base就是
uvm_seq_item_pull_imp

Driver的port_base就是
uvm_seq_item_pull_port

基本的連接設定,基本上是放在agent
// connect_phase
function void connect_phase(uvm_phase phase);
if(get_is_active() == UVM_ACTIVE) begin
driver.seq_item_port.connect(sequencer.seq_item_export);
end
endfunction : connect_phase

另外還有一個rsp_port在driver及rsp_export在sequencer