您的位置:首页 > 其它

UVM糖果爱好者教程 - 4.代理

2018-03-19 16:00 841 查看
上一篇文章集中讨论了 jelly-bean系统的transaction和sequence。本文将深入解释验证环境中的验证组件。

interface

在这一部分,将提供接口(jelly_bean_if)的一般解释及其绑定验证组件和jelly-bean(DUT)的作用。
下图显示了jelly_bean_if的内容。实质上,jelly_bean_if已包含从jelly_bean_transaction中的属性转换而来的信号。interface jelly_bean_if(input bit clk);
logic [2:0] flavor;
logic [1:0] color;
logic sugar_free;
logic sour;
logic [1:0] taste;

clocking master_cb @ (posedge clk);
default input #1step output #1ns;
output flavor, color, sugar_free, sour;
input taste;
endclocking: master_cb

clocking slave_cb @ (posedge clk);
default input #1step output #1ns;
input flavor, color, sugar_free, sour;
output taste;
endclocking: slave_cb

modport master_mp(input clk, taste, output flavor, color, sugar_free, sour);
modport slave_mp(input clk, flavor, color, sugar_free, sour, output taste);
modport master_sync_mp(clocking master_cb);
modport slave_sync_mp(clocking slave_cb);
endinterface: jelly_bean_if各个信号的时序由时钟块定义。 master_cb从总线master的角度定义时序,而slave_cb从总线slave的角度定义时序。
该接口还有modport列表,它定义了接口内信号的方向。我们定义了四个modport列表:



DUT使用异步modport列表(master_mp和slave_mp),而testbench使用同步modport列表(master_sync_mp和slave_sync_mp)。
更新(2014年4月2日):我们注意到有些仿真器不支持#1步骤(第9和15行)。如果是这种情况,您可以将其更改为#1ns。

DUT

下面的代码显示了jelly_bean_taster的一个简单结构。第1行指定了我们刚刚定义的jelly_bean_if,以及slave_mp为接口信号选择适当的方向信息。品尝师只会对酸味巧克力口味产生负面影响(即有酸味的巧克力)!module jelly_bean_taster( jelly_bean_if.slave_mp jb_slave_if );
import jelly_bean_pkg::*;
always @ ( posedge jb_slave_if.clk ) begin
if ( jb_slave_if.flavor == jelly_bean_transaction::CHOCOLATE &&
jb_slave_if.sour ) begin
jb_slave_if.taste <= jelly_bean_transaction::YUCKY;
end else begin
jb_slave_if.taste <= jelly_bean_transaction::YUMMY;
end
end
endmodule: jelly_bean_taster或者,您可以在模块实例的端口连接中指定modport列表。module jelly_bean_taster( jelly_bean_if jb_slave_if ); // no modport specified
// ...
endmodule

module top;
reg clk;
jelly_bean_if jb_slave_if( clk );
jelly_bean_taster jb_taster( jb_slave_if.slave_mp ); // modport specified
// ...
endmodule您可以在模块声明和模块实例中指定modport列表,但如果您这样做,它们必须相同。如果完全没有指定modport列表,则接口中的信号被假定为无法访问。

Sequencer

 jelly-bean sequence由sequencer处理。 uvm_sequencer按原样使用,因为 jelly-bean sequencer不涉及任何类型的扩展功能。typedef uvm_sequencer#(jelly_bean_transaction) jelly_bean_sequencer;

Driver

driver通过22行中的seq_item_port接收jelly_bean_transaction,然后驱动interface上的信号。driver使用driver和DUT之间的interface来驱动信号。该interface存储在uvm_resource_db(第12行)中。

更新(2014年4月2日):在本教程中,我们使用uvm_resource_db来检索jelly_bean_if(第12和13行)。 UVM建议使用uvm_config_db而不是uvm_resource_db,因为前者更健壮。您可以用下列内容替换第12行和第13行:assert( uvm_config_db#( virtual jelly_bean_if )::
get( .cntxt( this ), .inst_name( "" ), .field_name( "jelly_bean_if" ), .value( jb_vi ) ) );
class jelly_bean_driver extends uvm_driver#(jelly_bean_transaction);
`uvm_component_utils(jelly_bean_driver)

virtual jelly_bean_if jb_vi;

function new(string name, uvm_component parent);
super.new(name, parent);
endfunction: new

function void build_phase(uvm_phase phase);
super.build_phase(phase);
void'(uvm_resource_db#(virtual jelly_bean_if)::read_by_name
(.scope("ifs"), .name("jelly_bean_if"), .val(jb_vi)));
endfunction: build_phase

task run_phase(uvm_phase phase);
jelly_bean_transaction jb_tx;

forever begin
@jb_vi.master_cb;
jb_vi.master_cb.flavor <= jelly_bean_transaction::NO_FLAVOR;
seq_item_port.get_next_item(jb_tx);
@jb_vi.master_cb;
jb_vi.master_cb.flavor     <= jb_tx.flavor;
jb_vi.master_cb.color      <= jb_tx.color;
jb_vi.master_cb.sugar_free <= jb_tx.sugar_free;
jb_vi.master_cb.sour       <= jb_tx.sour;
seq_item_port.item_done();
end
endtask: run_phase
endclass: jelly_bean_driver
第20和23是所谓的时钟块事件。它们相当于@(posedge jb_vi.clk)

Monitor

monitor中的数据流向与driver中相反,但与驱动程序类似。 DUT的interface(jelly_bean_if)位于uvm_resource_db(第14行)。monitor密切监视jelly_bean_if,并获取信号的值。我们的monitor监视一个非NO_FLAVOR果冻豆(第23行)并创建一个jelly_bean_transaction(第24行)。创建的transaction通过analysis port发送给31行的用户。
更新(2014年4月2日):我们使用uvm_resource_db来检索jelly_bean_if(第14行和第15行)。有关如何使用uvm_config_db而不是uvm_resource_db,请参阅上一节。
class jelly_bean_monitor extends uvm_monitor;
`uvm_component_utils(jelly_bean_monitor)

uvm_analysis_port#(jelly_bean_transaction) jb_ap;

virtual jelly_bean_if jb_vi;

function new(string name, uvm_component parent);
super.new(name, parent);
endfunction: new

function void build_phase(uvm_phase phase);
super.build_phase(phase);
void'(uvm_resource_db#(virtual jelly_bean_if)::read_by_name
(.scope("ifs"), .name("jelly_bean_if"), .val(jb_vi)));
jb_ap = new(.name("jb_ap"), .parent(this));
en
4000
dfunction: build_phase

task run_phase(uvm_phase phase);
forever begin
jelly_bean_transaction jb_tx;
@jb_vi.slave_cb;
if (jb_vi.slave_cb.flavor != jelly_bean_transaction::NO_FLAVOR) begin
jb_tx = jelly_bean_transaction::type_id::create(.name("jb_tx"), .contxt(get_full_name()));
jb_tx.flavor = jelly_bean_transaction::flavor_e'(jb_vi.slave_cb.flavor);
jb_tx.color = jelly_bean_transaction::color_e'(jb_vi.slave_cb.color);
jb_tx.sugar_free = jb_vi.slave_cb.sugar_free;
jb_tx.sour = jb_vi.slave_cb.sour;
@jb_vi.master_cb;
jb_tx.taste = jelly_bean_transaction::taste_e'(jb_vi.master_cb.taste);
jb_ap.write(jb_tx);
end
end
endtask: run_phase
endclass: jelly_bean_monitor

Agent

sequencer,driver,monitor - 全部例化在在agent中。这些组件在build_phase中创建,创建的组件在connect_phase中连接。由于subscriber没有例化在agent,但是monitor要向subscriber发送trans,所以创建analysis port以与subscriber进行通信。agent和monitor中的analysis port在26行相互连接。然后,agent中的analysis port又和subscriber中的analysis imp在env中连接。
class jelly_bean_agent extends uvm_agent;
`uvm_component_utils(jelly_bean_agent)

uvm_analysis_port#(jelly_bean_transaction) jb_ap;

jelly_bean_sequencer jb_seqr;
jelly_bean_driver jb_drvr;
jelly_bean_monitor jb_mon;

function new(string name, uvm_component parent);
super.new(name, parent);
endfunction: new

function void build_phase(uvm_phase phase);
super.build_phase(phase);

jb_ap = new(.name("jb_ap"), .parent(this));
jb_seqr = jelly_bean_sequencer::type_id::create(.name("jb_seqr"), .parent(this));
jb_drvr = jelly_bean_driver::type_id::create(.name("jb_drvr"), .parent(this));
jb_mon = jelly_bean_monitor::type_id::create(.name("jb_mon"), .parent(this));
endfunction: build_phase

function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
jb_drvr.seq_item_port.connect(jb_seqr.seq_item_export);
jb_mon.jb_ap.connect(jb_ap);
endfunction: connect_phase
endclass: jelly_bean_agent虽然这篇文章到这里就结束,但下一篇将继续介绍其他验证组件。


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  uvm systemverilog