uvm_agent,uvm_scoreboard,reference model

        昨天组会时,老师说研二的同学把工作交接一下开始准备找工作。初听时还是很开心的,至少可以光明正大的看点儿uvm。但是细想,每天还得去公司挂机,也得去费尽心思去搞毕设,但是心理上更能接受而已。不过不管怎么样,还是专注把自己手头的工作做好吧,剩下的一半交给天意。

1.uvm_agent

1.agent 封装了sqr,driver和monitor,并将sqr和driver连接起来;

2.agt有两种模式,active和passive;

3.代码示例

`ifndef _GUARD_HELLO_AGENT_SV_
`define _GUARD_HELLO_AGENT_SV_        //两句连用,防止重复编译(C语言内容)

class hello_agent extends uvm_agent;

    hello_sequencer sqr;
    hello_driver    dri;
    hello_monitor   mon;
                                      //agt内例化 sqr,dri,moni
    extern function new(string name,uvm_component parent);
    extern virtual function void build_phase(uvm_phase phase);
    extern virtual function void connect_phase(uvm_phase phase);  
                                      //agt中需要将dri与sqr连接在一起
    uvm_analysis_port#(hello_transaction) ap;
    
`uvm_component_utils_begin(hello_agent)    //uvm 工厂机制 宏注册
    `uvm_field_object(sqr,UVM_ALL_ON)
    `uvm_field_object(dri,UVM_ALL_ON)
    `uvm_field_object(mon,UVM_ALL_ON)
`uvm_conponent_utils_end

endclass

function hello_agent::new(string name,uvm_component parent)
    super.new(name,parent);
endfunction
//执行uvm_agent的new函数

function void hello_agent::build_phase(uvm_phase phase)
    super.build_phase(phase);
    if(is_active == UVM_ACTIVE) begin
       sqr = hello_sequencer::type_id::create("sqr",this);
       dri = hello_sequencer::type_id::create("sri",this);
       mon = hello_sequencer::type_id::create("mon",this);
    end
    else begin
       mon = hello_sequencer::type_id::create("mon",this);
endfunction

function void hello_agent::connect_phase(uvm_phase phase);
    super.connect_phase(phase);

    if(is_active == UVM_ACTIVE) begin
        dri.seq_item_port.connect(sqr.seq_item_export);
        this.ap = mon.ap;
        end
    else begin
        this.ap = mon.ap
    end
endfunction


2.reference model

 1.模拟DUT的行为,计算相应的输出;继承于component(唯一)

    输入:iagt_monitor        输出:scoreboard

例如在fifo验证中,就不需要reference model

2.代码示例

`ifndef _GUARD_HELLO_MODEL_SV_
`define _GUARD_HELLO_MODEL_SV_        //两句连用,防止重复编译(C语言内容)

class hello_model extends uvm_component
    
    uvm_blocking_get_port#(hello_transaction) port;//从mon取的激励
    uvm_analysis_port    #(hello_transaction) ap;
    
    extern function new(string name,uvm_component parent);
    extern function void build_phase(uvm_phase phase);
    extern task main_phase(uvm_phase phase);

    `uvm_component_utils(hello_model)    //uvm 工厂机制 宏注册
endclass

function hello_sequencer::new(string name,uvm_component parent)
    super.new(name,parent);
endfunction
//执行reference model的new函数

function void hello_model::build_phase(uvm_phase phase)
    super.build_phase(phase);
    port = new("port",this);            //reference model与monitor连接端口
    ap   = new("ap",this);              //reference model与scoreboard连接端口
endfunction

task hello_model::main_phase(uvm_phase phase)
    hello_transaction tr;
    hello_transaction new_tr;
    super.main_phase(phase);
    
    while(1) begin
        port.get(tr);                    //从monitor拿到tr
        new_tr = new("new_tr");          
        new_tr.copy(tr);                 //复制tr到new_tr
        
        new_tr.print();
        ap.write(tr);                    //把new_tr发给scoreboard,本质上还是从vif获取的tr
    end
endtask
    

3.uvm_scoreboard

1.scoreboard用于比较DUT的输出与reference model是否一致。只有一个构析函数,在component的基础上没有额外增加任何东西

2.代码分析

`ifndef _GUARD_HELLO_SCOREBOARD_SV_
`define _GUARD_HELLO_SCOREBOARD_SV_        //两句连用,防止重复编译(C语言内容)

class hello_scoreboard extends uvm_scoreboard 
    hello_transaction expect_queue[$];
    
    uvm_blocking_get_port #(hello_transaction) exp_port;
    uvm_blocking_get_port #(hello_transaction) act_port;

    `uvm_component_utils(hello_scoreboard)    //uvm 工厂机制 宏注册

    extern function new(string name,uvm_component parent);
    extern virtual function void build_phase(uvm_phase phase);
    extern virtual task main_phase(uvm_phase phase);

    //new、build_phase、main_phase是一个component必须的    
    
    extern task xxx
    //不同的component里面有各自完成独特功能的函数,属于用户自定义

endclass

function hello_monitor::new(string name,uvm_component parent)
    super.new(name,parent);
endfunction
//执行uvm_scoreboard的new函数

function void hello_scoreboard::build_phase(uvm_phase phase)
    super.build_phase(phase);
        exp_port = new("exp_port",this);
        act_port = new("act_port",this);
endfunction

task hello_scoreboard::main_phase(uvm_phase phase);
    hello_transaction get_export,get_actual,tmp_tran;
    bit result;
    super.main_phase(phase);

    fork
        while(1) begin
            exp_port.get(get_export);
            expect_queue.push_back(get_export);
        end

        while(1) begin
            act_port.get(get_actual);

            if(expect_queue.size()>0) begin
                tmp_tran = expect_queue.pop_front();
                result = get_actual.compare(tmp_tran);
                
                if(result) begin
                    tmp_tran.print();
                end

                else begin
                    `uvm_error("my_scoreboard","compare FAILED");
                end
             end
    join
endtask

4.总结

1.agent的作用是什么?为什么需要agent这个组件?

        相较于sv来说,uvm的存在就是为了提高代码的复用性和可维护。agent作为一个uvm_component类,是为了验证环境的复用而存在的。agt只是将dri、mon、sqr封装在一起,在它内部没有其他特殊的函数。封装成mon之后,在env中只需要例化agt而不需要例化dri和moni。dri和mon的代码是高度重复的,因为他们处理的是同一种协议,区别在于方向。把他们封装在一起,不同的agt就代表了不同的协议。

2.is_active的实现有什么好处?若用new创建drv,mon,sqr会怎么样?

        is_active的存在是为了模块级的环境复用到更高级别的环境中。在build_phase中,根据is_active变量的值来决定sqr和dri是否要实例化。通常对于slave_agt,只需要监测信号时,可以设为passive,减少代码的冗余。另一方面,在模块级验证中,当模块验证环境被集成到一个更大的模块时,有真正的master模块设计连接着APB总线,,也有slave模块通过APB总线做响应。那这个时候,我就不需要你APB VIP里面的master agent 里面的 driver 和 sequencer 来模拟master去发送激励了,但这个时候,我们仍然想监测APB总线上数据的来来回回,但又不需要发送激励,这时候我们就可以通过对APB VIP的 master agent 和 slave agent 配置UVM_PASSIVE,也就是不例化 driver 和 sequencer ,只例化monitor,实现了模块级环境复用到更高级别的环境中。
        UVM推荐使用内置方法 :: type_id :: create() ,而不是直接调用构造函数new()创建组件或事务对象。create方法在内部调用factory机制以查找所请求创建的类型,然后调用构造函数new()以实际创建一个对象而 无需更改任何代码 

3.组件之间使用fifo连接和直接用port端口连接该怎么选择?

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值