精华内容
下载资源
问答
  • AMBA_UVM验证DEMO

    2019-01-29 15:25:06
    AMBA_UVM验证,可以在VCS等仿真工具中进行运行,可以帮助你更好的理解UVM验证平台
  • UVM验证示例代码

    2018-07-03 15:05:30
    一组UVM验证平台的示例代码,可以在Modelsim10.4 + UVM-1.1d环境下运行
  • apb的uvm验证vip

    2020-04-11 12:21:22
    APB的UVM验证VIP,非常实用。 初学UVM的可以作为模板参考学习,也可以直接用到项目中作为验证的环境!
  • 寄存器模型生成工具,可将excel表格直接生成uvm验证使用的寄存器模型
  • perl脚本自动生成UVM验证框架
  • 一个基本的 uvm 验证环境结构如下图所示,包含两个 agent,其中 in_agent 用于驱动 DUT ,同时将驱动数据同时传递给 reference model, out_agent 用于按照协议采集 DUT 的输出数据,并将数据传递给 scoreboard,在 ...

    一个基本的 uvm 验证环境结构如下图所示,包含两个 agent,其中 in_agent 用于驱动 DUT ,同时将驱动数据同时传递给 reference model, out_agent 用于按照协议采集 DUT 的输出数据,并将数据传递给 scoreboard,在 scoreboard 收集到 reference model 的运算结果后,再进行比对验证。

    要想实现 monitor 和 reference model 进行通信,大致可以有以下几种方式,第一种,通过全局变量;第二种,通过 定义一个参数类来进行信息传递;第三种:通过前面刚谈到的 uvm_config 来进行传递信息。似乎这些东西都可以实现我们定义的任务,但是有个很重要的点还没有提到,如果我们需要一种 阻塞的场景,即有数据时就取数据,没有数据时就等待。这在验证中是一种比较常见的场景。为了解决这个问题 uvm 提炼出了一种具有阻塞和非阻塞功能的类型,取名为TML。

    通俗意义上讲,TLM就是一些带阻塞和非阻塞 port 端口, 为了满足缓存需要,其中也有一些能缓存能力的 port。TLM 端口的使用有点像我们看电视时用插头插插座,插看好后电网的电量就源源不断的通过接口输入进电视机,结合我们的验证环境来说 driver 和 reference model 中包含一对匹配的结构,一个用于发送数据,一个用于接收数据。

    1.端口连接

    在 UVM 中 port 可以分为三种:

    a.port : 优先级最高,可以作为数据链路的端口的起点或者端口中间节点 ;

    b.export :优先级最中,可以作为数据链路的或者起点端口中间节点 ;

    c.import :优先级最低,只能作为数据链路的重点 。

    连接形式可以为

    a.port -> import; port -> export -> import; port -> port -> import; port -> export -> export -> import ;

    b.export -> import; export -> export -> import;

    注意 -> 表示连接关系,A port -> B import,表示为 A.connect(B) ,其中 A 的优先级需要比 B 的优先级高。

    2.端口操作

    如下图所示,在 UVM 中 port 常见的两种操作就是:

    a. put 操作 :通信的发起者 A 把一个 transaction 发送给接受者 B ;

    b. get 操作 :通信的发起者 A 向 接受者 B 请求一个 transaction ;

    c. transport操作,transport操作相当于一次 put 操作加一次 get 操作 。

    uvm 包含了很多类型的 port/export/import,如 uvm_blocking_put_port/export/import、uvm_blocking_peek_port/export/import 和 uvm_blocking_transport_port/export/import 等,但除了这些,uvm 还包含了两种特殊的端口 analysis_port 和 analysis_export, 这两种端口和 put/peek/get 等系列端口类似,但是包含一些重要区别:

    默认情况下,一个 analysis_port(analysis_export)可以连接多个 analysis_import,即 analysis_port(analysis_export)与 analysis_import 之间是一对多通信;而 put/peek/get 等系列端口只能进行一对一通信。analysis_port(analysis_export)的通信方式像一个广播。

    put/peek/get 等系列端口都具有阻塞和非阻塞之分,但对于 analysis_port(analysis_export)来说,没有阻塞和非阻塞的概念。

    不同于put/peek/get 等系列端口,对于analysis_port(analysis_export)两种端口仅包含 write 操作,与之相连的 analysis_imp 所在的 component 必须定义一个名为 write 的函数。

    3.端口实例1 - uvm_analysis_port

    在 uvm 环境中,常用 TML 通信的组件有 monitor、scoreboard和reference model 三者之间的通信,下面以 monitor 和 scoreboard 通信为例,monitor端 uvm_analysis_port的代码为:

    my_monitor

    class my_monitor extends uvm_monitor;

    `uvm_component_utils(my_monitor)

    uvm_analysis_port(my_transaction) A_port;

    ...

    endclass

    ...

    virtual function void my_monitor::build_phase(uvm_phase phase);

    super.build_phase(phase);

    A_port=new("A_port",this);

    ...

    endfuction

    virtual function void my_monitor::main_phase(uvm_phase phase);

    my_transaction tr;

    forever begin

    assert(tr.randomize());

    A_port.write(tr);

    end

    endfuction

    scoreboard 端 uvm_analysis_port 的代码为:

    scoreboard

    class my_scoreboard extends uvm_scoreboard;

    `uvm_component_utils(my_scoreboard)

    uvm_analysis_import(my_transaction,my_scoreboard) A_import;

    ...

    endclass

    ...

    virtual function void my_scoreboard::build_phase(uvm_phase phase);

    super.build_phase(phase);

    A_import=new("A_import",this);

    ...

    endfuction

    virtual function void my_scoreboard::write(my_transaction tr);

    deal_with(tr);

    endfuction

    顶层 env 连接代码:

    my_env

    class my_env extends uvm_env;

    ...

    endclass

    ...

    virtual function void my_scoreboard::connect_phase(uvm_phase phase);

    super.connect_phase(phase);

    agt.monitor.A_port.connect(scb.A_import)

    ...

    endfuction

    实例中,在 monitor 中定义了 analysis_port;socreboard 中定义了 analysis_import;在 env 的 connect_phase 中对 analysis_port 和 analysis_import 进行连接。数据在 monitor 产生后,数据的流通过程如下图所示, 数据首先通过 analysis_port 的系统函数 write 调用 analysis_import 的系统函数 write,再由 analysis_import 的系统函数 write 触发 my_scoreboard 中用户自定义的 write 函数,这也为什么在定义 scoreboard 的 impport时,需要通过 uvm_analysis_port(my_transaction,my_scoreboard) A_import; 将 my_scoreboard 和 A_import 绑定的原因,就是为了 能顺利触发 自定义的 write 函数。而且这种触发是没有延迟的触发机制,可以通过这种 write 方式来满足一些特定时序要求。

    在了解了上述内容后,在来看看 uvm_analysis_port 的最重要的特性,一对多通信是怎么实现的,现在考虑一种场景,scoreboard 需要收集 monitor 和 reference model 两个组件传输过来的数据,但是我们定义write 函数的时候只有一个名字,那么 monitor 和 reference model 中的 analysis_import 的系统函数 write 怎么触发 my_scoreboard 中用户自定义的 write 函数呢?

    为了解决上述问题 uvm 定了一宏 uvm_analysis_imp_decl 来解决上述问题,现在我们来看看这个宏怎么用,更新后的 my_scoreboard 代码如下:

    scoreboard

    `uvm_analysis_imp_decl(_monitor)

    `uvm_analysis_imp_decl(_model)

    class my_scoreboard extends uvm_scoreboard;

    my_transaction inpect_queue[$]

    my_transaction expect_queue[$]

    uvm_analysis_imp_monitor(my_transaction,my_scoreboard) mon_import;

    uvm_analysis_imp_model(my_transaction,my_scoreboard) model_import;

    ...

    extern function void write_monitor(my_transaction tr);

    extern function void write_model(my_transaction tr);

    ...

    endclass

    ...

    virtual function void my_scoreboard::write_monitor(my_transaction tr);

    inpect_queue.push_back(tr);

    ...

    endfuction

    virtual function void my_scoreboard::write_model(my_transaction tr);

    expect_queue.push_back(tr);

    ...

    endfuction

    上述代码通过宏 uvm_analysis_imp_decl 声明了两个后缀 _monitor 和 _model 。UVM 会根据这两个后缀定义两个新的 import 类:uvm_analysis_imp_monitor 和 uvm_analysis_imp_model ,并在 my_scoreboard 中分别实例化这两个类:monitor_imp 和 model_imp。当与 monitor_imp 相连接的 analysis_port 执行 write 函数时,会自动调用 write_monitor 函数,而与 model_imp 相连接的 analysis_port 执行 write 函数时,会自动调用 write_model 函数。所以,只要完成后缀的声明,并在write后面添加上相应的后缀就可以正常工作了。

    3.端口实例2 - uvm_tlm_analysis_fifo

    另外一种带缓存能力的 analysis port ,叫做 uvm_tlm_analysis_fifo,其本质为 一块 FIFO 加一组端口,如下图所示,共有 3 类,12 import 为一类,包含 一族 *_put_export 、一族 *_get_export 和一族 *_peek_export ,似乎上述都是 export,其实这只是取名为 export 而已,它们本质上还是 import 。

    *_put_export 族:调用时,导致 uvm_tlm_analysis_fifo 中的缓存单元(**本质为 mailbox ),元素个数加 1;

    *_get_export 族:调用时,导致 uvm_tlm_analysis_fifo 中的缓存单元(本质为 mailbox ),元素个数减 1;

    *_peek_export 族:调用时,导致 uvm_tlm_analysis_fifo 中的缓存单元(本质为 mailbox **),元素个数不变,同时把 transaction 复制一份发送出去。

    现在来说说图中的另外两个端口 - put_ap 和 get_ap, 这两组的 端口的源码如下

    scoreboard

    virtual task void put(int T t);

    m.put(t);

    put_ap.write(t);

    endtask

    virtual task void get(int T t);

    m_pending_blocked_gets++;

    m.get( t );

    m_pending_blocked_gets--;

    get_ap.write( t );

    endtask

    当 uvm_tlm_analysis_fifo 上 的 _put_export 族端口被连接到 一个 put 端口时,且调用 put 函数时,put 函数会把传递过来的 transactoin 放在 uvm_tlm_analysis_fifo 的缓存单元 m (mailbox)中,同时把这个 transaction 通过 put_ap 端口的 write 函数发送给与之相连的端口;当 uvm_tlm_analysis_fifo 上 的_get_export 族 被连接到一个 get 端口,且调用 get 函数时,过程类似。我们常用的是 analysis_export 端口。带 FIFO 缓存的端口类型除了 uvm_tlm_analysis_fifo,还有一种是 uvm_tlm_fifo, 区别在于前者有一个 analysis_export 端口和一个 write 函数。

    现在以 monitor 与 reference model 的通信为例,其 monitor 端代码如下

    monitor

    class my_monitor extends uvm_monitor;

    `uvm_component_utils(my_monitor)

    uvm_analysis_port(my_transaction) A_port;

    ...

    endclass

    ...

    virtual function void my_monitor::build_phase(uvm_phase phase);

    super.build_phase(phase);

    A_port=new("A_port",this);

    ...

    endfuction

    virtual function void my_monitor::main_phase(uvm_phase phase);

    my_transaction tr;

    forever begin

    assert(tr.randomize());

    A_port.write(tr);

    end

    endfuction

    其 reference model 端代码如下

    reference model

    class my_reference extends uvm_component;

    `uvm_component_utils(my_reference )

    uvm_tlm_analysis_fifo(my_transaction) A_fifo_port;

    ...

    endclass

    ...

    virtual function void my_reference ::build_phase(uvm_phase phase);

    super.build_phase(phase);

    A_fifo_port=new("A_fifo_port",this);

    ...

    endfuction

    virtual function void my_reference ::main_phase(uvm_phase phase);

    my_transaction tr = null;

    forever begin

    A_fifo_port.get(tr);

    ...

    end

    endfuction

    顶层 env 连接代码:

    my_env

    class my_env extends uvm_env;

    ...

    endclass

    ...

    virtual function void my_scoreboard::connect_phase(uvm_phase phase);

    super.connect_phase(phase);

    agt.monitor.A_port.connect(ref.A_fifo_port.analysis_export)

    ...

    endfuction

    其中 monitor 通过 uvm_analysis_port A_port 调用 write 函数将 my_transaction 存入 uvm_tlm_analysis_fifo 的缓存单元中,在 reference model 中通过 get 函数将 tranansction 取出进行后续处理。

    3.端口特例

    这组特例 port 就是 uvm_seq_item_pull_port 和 uvm_seq_item_pull_imp ,通过名字可以知道,这组端口通常是在 sequencer 和 driver 中使用的,用于它们之间的数据传递。uvm library 中 原型代码如下所示:

    uvm_seq_item_pull_port

    class uvm_driver #(type REQ=uvm_sequence_item,type RSP=REQ) extends uvm_component;

    uvm_seq_item_pull_port #(REQ,RSP) seq_item_port;

    ...

    endclass

    class uvm_sequencer #(type REQ=uvm_sequence_item,type RSP=REQ) extends uvm_sequencer_para_base #(REQ,RSP);

    uvm_seq_item_pull_imp #(REQ,RSP) seq_item_export;

    ...

    endclass

    在使用时,因为 sequencer 中的操作被隐藏,所以使用时很简单,实例如所示:

    uvm_seq_item_pull_port 实例

    class my_sequence extends uvm_sequence #(my_transaction);

    `uvm_object_utils(my_sequence);

    virtual task body(uvm_phase phase);

    `uvm_do(req);

    get_response(rsp);

    endtask

    endclass

    class my_sequencer extends uvm_sequencer #(my_transaction);

    `uvm_component_utils(my_sequencer);

    function new(string name, uvm_component phase);

    super.new(name,parent);

    endfunction

    function void build_phase(uvm_phase phase);

    super.build_phase(phase);

    endfunction

    endclass

    class my_driver extends uvm_driver #(my_transaction);

    `uvm_component_utils(my_driver );

    ...

    virtual task run_phase(uvm_phase phase);

    my_transaction tr;

    while(1)begin

    seq_item_port.get_next_item(req);

    send(tr);

    se_item_port.item_done();

    seq_item_port.put_response(rsp);

    end

    endtask

    endclass

    sequence 发送数据,driver 接受数据,具体细节将在第 5 节中讲述。

    展开全文
  • UVM(一)——UVM验证平台UVM验证平台组成driver组件factory机制objection机制virtual interfaceconfig_db机制transaction UVM验证平台组成 之前一直在忙比赛的事情,时隔一个月终于又能开始继续学习验证了! 这次刚...

    UVM验证平台组成

    之前一直在忙比赛的事情,时隔一个月终于又能开始继续学习验证了!
    这次刚看完UVM白皮书第二章的内容,大致了解了一下UVM的框架,做个简单的总结。

    了解UVM后觉得其本质是一个框架,就像pytorch对于深度学习,以及其他高级语言在特定需求下的一种框架。UVM就是SV在IC验证中的一种框架。不用UVM也能完成验证功能,只是复用性和便捷性不如用UVM的情况。

    • 对于UVM来说其强大的复用性决定它必定是面向对象的所以它的封装都很规范。
    • 一个验证平台大致分为sequencer、driver、monitor、reference model、scoreboard。
    • 又会将不同协议的driver和monitor封装成一个agent。再把各个验证组件封装成一个env。大致结构如下图所示。

    在这里插入图片描述

    • UVM是树形结构的,会在build_phase中构建整个树,而后安装树的结构运行程序。

    在这里插入图片描述

    driver组件

    UVM的第一条原则就是:验证平台中所有的组件应该派生自UVM中的类

    driver就应该派生自uvm_driver,这个派生类的new函数有两个参数,第一个是字符串类型,表示派生类的name,第二个则是其父节点的名字。如

    function new(string name="my_driver",uvm_component parent=null);
    

    第二点便是UVM中都是由phase来管理平台运行的。(暂时还缺乏都phase的深入理解)

    factory机制

    factory是UVM中一个非常重要的机制,暂时明白的功能就是run_test();就可以直接创建一个类的实例并调用其函数。但是用factory机制前需要通过uvm_component_utils宏进行注册,例如:

    `uvm_component_utils(my_driver);
    

    并且可以直接运行my_driver的main_phase,但是仅仅这样不会运行其main_phase中的事务。

    objection机制

    这时候就需要objection机制登场啦。
    在UVM中每个phase会检查是否有objection被raise,如果有等这个objection被drop后才停止。例如将下列两行代码加在main_phase的开头和结尾,事务就能正常运行。

    phase.raise_objection(this);
    phase.drop_objection(this);
    

    这里的this就像C++的this指针一样,指的是当前类。(raise要加在所有耗时语句之前

    virtual interface

    在SV中会使用interface来简化接口的描述,但是UVM中interface是不能在类中例化的,所以就引入了virtual interface的概念。在类中如下描述:

    virtual my_if vif;
    

    声明过这个virtual interface后就可以在main_phase中使用这个接口了。
    这样就剩下最后一个问题了,怎么将顶层的input_if和driver的if连接起来。最简单的就是赋值了,但是由于UVM的run_test的实例化其实在顶层之上建立了一个新的层次:uvm_test_top,所以无法使用top.driver…。

    • 这时候就需要config_db机制了

    config_db机制

    • 在我的理解中config_db机制就是为了给不同层次的类进行赋值的,用set表示发送,get表示接受。
    uvm_config_db# (virtual my_if)::set(null,"uvm_test_top","vif",input_if);
    uvm_config_db# (virtual my_if)::get(this,"","vif",vif);
    

    但是不同的是get要放在build_phase中,build_phase通常是在整个UVM结构树形成前进行操作的。(在new函数后,main_phase之前)

    • set和get函数的第三个参数必须一致,表示目标virtual interface,第二个参数表示路径索引。
    • set的第四个参数表示要传递哪个interface,get第四个参数表示要把接受到的interface给哪个成员变量。
      #后面括号的内容就是要传递数据的类型。(也可以为int,logic等等)

    transaction

    在uvm中所有的数据都抽象成transaction,而transaction都由uvm_sequence_item派生出来。

    详细内容等后续看完继续补充

    env

    env就是一个容器,在其中来进行driver、monitor、reference model和scoreboard的实例化。env就成为了根节点。

    monitor

    monitor组件的功能是检测DUT输入输出的端口数据并转换成transaction并交给后续比对。monitor的类应该全部派生自uvm_monitor类,其内也需要virtual interface

    • uvm_monitor也是一个component所以也需要注册
    `uvm_component_utils(my_monitor);
    

    agent

    有了driver和monitor后可以将他们封装成一个agent,在UVM中不同的agent代表不同的协议。而agent类都要派生自uvm_agent类,也需要注册。

    • 如果端口不需要driver只需要monitor那么agent的build_phase的is_active的值可以赋为uvm_passive,那么driver就不会被例化出来。加入agent后UVM树的层次就再次改变了,driver和monitor的根节点就是agent了不是uvm_top_test。

    reference model

    reference model功能就是以软件的形式完成DUT的功能验证,并将结果给后续的scoreboard比对。

    • 除了其中的功能实现外,其另一个重点是,transaction的传递方式。
    • 在uvm的transaction级别的通信中可以使用uvm_analysis_port。

    可以在monitor中参数化定义一个uvm_analysis_port,然后在build_phase中实例化,在main_phase中用内建函数write将transaction写入。
    之后可以在env中定义fifo,两端分别连接monitor的analysis_port和model的blocking_get_port。

    此处为什么要用fifo呢,因为analysis_port是非阻塞的,如果blocking_get_port正在忙无法接受monitor的数据,那么没有fifo就会使数据丢失,所以此处需要一个fifo。

    scoreboard

    开启两个进程,一个处理model出来的数据,放在队列里,一个存DUT出来的数据,用内建函数compare比较两个数据。通常model是高级语言处理,数据产生的比DUT快。
    接口机制和上述的monitor和model类似。

    field_automation

    对变量用uvm_objection_utils进行宏注册,可以让变量使用uvm内置的许多函数,如compare(),copy()等。需要在变量前后加上如下语句

    `uvm_objection_utils_begin(my_transaction)
    `uvm_objection_utils_end
    

    sequence

    最后的也是最重要的sequence机制,sequence机制有两部分组成,一是sequence,二是sequencer。
    sequence不属于验证平台中,但是在它的帮助下,sequencer才能正常工作。

    • 从本质上来说,sequencer是一个uvm_component;而sequence是一个uvm_object。
    • 每一个sequence都应该派生自uvm_sequence,用·uvm_do这个这个宏产生transaction,这个宏的功能是
    • 1.创建一个实例。2.将其随机化。3.最终给sequencer。

    但是一个sequence在向sequencer发送transaction之前,要先做两件事,一是发送一个请求,二是检测driver是否发出申请了。通过这种握手机制后,driver才可以通过get_next_item向sequencer申请transaction。

    • 申请下一transaction可以用get_next_item还有try_next_item前者是阻塞的,后者是非阻塞的。
    展开全文
  • 基于UVM验证平台Makefile,支持通用,需提供独特dut.f tb.f这两个filelist
  • 基于简单的加法器设计的完整UVM验证平台,包含功能覆盖率和UVM各组件,适合UVM入门学习,代码在vcs环境下仿真使用。
  • UVM验证方法学

    热门讨论 2013-09-04 16:35:05
    UVM验证方法学,讲的非常细。个人认为很好!按照各种实例教你如何使用UVM搭建Testbenchf The Test Bench Module
  • UVM验证之UVM_INFO的用法 其实关于uvm_info的用法网上的资料有很多,大多都是你抄抄我抄抄。 把简单的问题搞复杂,最后浪费大家的时间。 今天我说一些,如何用uvm_info来调试我们的代码。 `uvm_info(TAG, “SETUP ...

    UVM验证之UVM_INFO的用法

    其实关于uvm_info的用法网上的资料有很多,大多都是你抄抄我抄抄。

    把简单的问题搞复杂,最后浪费大家的时间。

    今天我说一些,如何用uvm_info来调试我们的代码。

    `uvm_info(TAG, “SETUP SIMULATION DEBUG1”, UVM_NONE)

    `uvm_info(TAG, “SETUP SIMULATION DEBUG2”, UVM_NONE)

    以此类推,这就是最直接的用法!
    上面的代码有三个参数!第一参数:就是自己定义的字符串!第二个参数:就是我们想要打印的信息!第三个参数:冗余级别,通常设置成UVM_NONE。当然也可以设置成别的级别!你只要记住一点,UVM_NONE(always打印)。

    很显然,这样写是存在问题的,一个小小的问题!希望可以发现!
    `uvm_info(“TAG”, “SETUP SIMULATION DEBUG2”, UVM_NONE)
    TAG需要加双引号,毕竟它是字符串!为了方便期间,第一个参数尽可能不要一致!

    展开全文
  • 一个简单的UVM验证平台1:面向对象的编程语言的特性:封装(变量和methods在一个类里),继承(派生,子类拥有父类所有特性)和多态(调用同一个函数但最终状态不一样(必须是virtual methods))。2:UVM是一个库,在这个库...

    一个简单的UVM验证平台

    1:面向对象的编程语言的特性:封装(变量和methods在一个类里),继承(派生,子类拥有父类所有特性)和多态(调用同一个函数但最终状态不一样(必须是virtual methods))。

    2:UVM是一个库,在这个库中,几乎所有的东西都是由类(class)来实现的。

    3:当实现一个功能时,首先要想到的是从UVM的某个类派生出一个新的类,在这个新的类中实现所期望的功能。所以使用UVM的第一条原则是:验证平台的所有的组件应该派生自UVM中的类。

    4:factory机制会自动实例化并按照顺序执行所有phase。所以所有派生自uvm_component及其派生的类都应该使用uvm_component_utils宏注册。

    5:UVM中通过objection机制来控制验证平台的关闭。在每个phase中,UVM会检查是否有objection被提起(raise_objection),如果有,那么就待这个objection被撤销(drop_objection)后停止仿真,如果没有,则马上结束当前phase。

    6:raise_objection语句必须在main_phase中第一个消耗仿真时间的语句之前。

    7:绝对路径的使用大大减弱了验证平台的可移植性,因此,从根本上来说,应该尽量杜绝在验证平台中使用绝对路径,避免使用绝对路径有两种方法,一,使用宏(不推荐),二,使用interface(推荐)。

    8:在类中使用的是virtual interface。但是UVM通过run_test语句实例化了一个脱离了top_tb层次结构的实例(uvm_test_top),建立了一个新的层次结构,所以UVM引进了config_db机制,用于interface和class之间的通信。

    9:super.build_phase语句用于执行父类的build_phase中的一些必要操作。所以必须显式的调用它。

    10:build_phase和main_phase不同的一点在于,build_phase是一个函数phase,而main_phase是一个任务phase,build_phase不消耗仿真时间,build_phase总在仿真时间为0时执行。

    11:config_db的set和get都有四个参数,前两个参数表示寄信收信的地址,第三个参数用于确认身份,即寄信和收信的第三个参数必须完全相同,第四个参数表示寄信或收信的实体。

    12:无论传递给run_test的参数是什么,创建实例的名字都为uvm_test_top。

    13:使用双冒号访问的函数都是静态函数。

    14:验证平台各个组件之间,传递的信息都是基于transaction的。这是一个抽象的概念,可以简单理解成包。

    15:transaction的基类是uvm_sequence_item,在UVM中所有的transaction都要从它这里派生,也只有从uvm_sequence_item中派生的transaction才可以使用sequence机制。

    16:uvm_env 是一个容器类,在这个容器类中实例化driver,monitor,reference model和scoreboard等。

    17:实例化一个class有两种方式,一种是直接调用new函数,一种是使用factory提供的实例化方式type_name::type_id::create(name,parent)的方式,验证平台中的组件都应该使用第二种方式实例化。

    18:build_phase的执行顺序是由树根到树叶,因为build_phase主要完成各个组件的实例化,实例化的时候要指定parent参数,如果从树叶到树根执行会导致parent参数无法指定。

    19:除build_phase以外的phase都是由树叶到树根的顺序执行,像connect_phase,如果从树根到树叶的顺序执行(端口的实体有时在monitor或者driver上,agent上通常只是一个指针),这时在model连接agent端口的时候就会报空指针错误。

    20:验证平台中实现监测DUT行为的组件是monitor。

    21:driver和monitor的代码很相似,其本质是因为二者处理的是同一种协议,所以UVM通常将二者封装在一起,成为一个agent。因此,不同的agent就代表了不同的协议。

    22:只有uvm_component才能作为树的结点,像transaction这种使用uvm_object_utils宏实现的类是不能作为UVM树结点的。

    23:UVM数最晚在build_phase时段完成,但约定成俗仅在build_phase中完成实例化。

    24:reference model用于完成和DUT相同的功能(一般用高级语言处理)。

    25:将transaction通过端口发送出去使用write函数,这是一个uvm_analyse_port的内建函数。

    26:connect_phase用于各组件之间的连接,在build_phase执行完后马上执行。

    27:field_automation机制可以简化验证平台的的搭建,提高效率。transaction中的成员变量使用uvm_field注册后,可以直接使用copy,compare,print等函数,无需自己定义。

    28:pack_bytes()和unpack_bytes()函数用于打包byte流和解包byte流,但函数的参数必须是一个动态数组,解包时要指定其大小才能正常工作。

    29:sequence机制用于产生激励,它是UVM中最重要的机制之一。

    30:在使用sequence时要引入sequencer。sequence就像是一个弹夹,里面的子弹是transaction,而sequencer是一把枪,弹夹只有放入枪中才有意义,枪只有在放入弹夹后才能发挥威力。

    31:每一个sequence都应该派生自uvm_sequence,并且在定义时指定要产生的transaction类型。每一个sequence都有一个body任务,当一个sequence启动之后被自动执行body的代码。

    32:uvm_do宏是UVM中最常用的宏之一,它用于创建transaction的实例化并将其随机化,最终将其送给sequencer。

    33:sequencer主要做两件事情,一,检测仲裁队列中是否有某个sequence发送来的transaction的请求。二,检测driver是否申请transaction。这样就会出现有sequence发送但没有driver申请transaction,有driver申请但没有sequence发送transaction和刚好sequence发送刚好driver请求transaction的三种情况。

    34:sequencer和driver通过内建的端口连接,driver通过get_next_item任务向sequencer申请transaction。

    35:uvm_do产生一个transaction并交给sequencer后不会立即执行下一次uvm_do宏,而是等待在那里,直到driver返回item_done信号,此时,uvm_do宏才算执行完毕,返回后开始执行下一个uvm_do,并产生新的transaction。

    36:sequence可以使用start任务手动启动,seq.start(i_agt.sqr);start任务的参数是sequencer指针,如果不指明此指针,则sequence不知道将产生的transaction交给哪个sequencer。在UVM中,objection一般伴随着sequence,通常只在sequence出现的地方才会提起和撤销objection。

    37:sequence大多数情况是使用default_sequence的形式启动,uvm_sequence的基类中有一个变量名为start_phase,类型为uvm_phase的变量。在sequencer启动default_sequence时会自动将phase赋给starting_phase,因此,可以在sequence中使用starting_phase进行提起和撤销objection,从而,objection完全与sequence关联在了一起,在其他任何地方都不必再设置objection。

    38:真正的测试用例都是基于base_test派生的一个类。在base_test里一般完成实例化env,log的打印,设置超时退出等等。

    39:UVM中的测试用例的启动可以使用run_test(“test_case_name”);的方式启动(很少用),也可以使用run_test() 即不指定具体的test case然后再仿真命令行使用+UVM_TESTNAME=my_case_name的方式来启动测试用例(比较常用);

    40:通常UVM启动和执行的流程为:

    module top_tb ->全局的run_test() ->启动验证平台->根据UVM_TESTNAME产生具体的test case的实例 ->依次执行build_phase 形成UVM树 ->顺序执行UVM树各结点的connect_phase,main_phase等-> 所有phase执行完毕,结束仿真。UVM 树

    展开全文
  • 本发明涉及数字芯片的功能验证和验证方法学领域,尤其是一种基于UVM验证方法学的SPI验证方法,通过验证平台的搭建,随机化激励的生成,功能覆盖率的收集,响应结果的自检等操作完成对SPI的功能验证。背景技术:近年...
  •   uvm_objection 和 uvm_component 是 uvm 中两大基础类,刚开始学习的时候,对两个东西认识不深,以为它们俩差不多,谁知道它两是一个是“爷爷”,一个是孙子的关系,两者贯穿整个 uvm 验证方法学。至于为什么要...
  • 技术领域本发明涉及芯片设计验证领域,具体地说是一种实用性强、连接UVM验证平台的搭建方法。背景技术:伴随着芯片集成度增加,各种通信与信号处理算法被集成到系统芯片中,这些算法通常需要先利用Matlab或Simulink...
  • 基于APB的UART IP核设计与UVM验证 - 基于APB的UART IP核设计与UVM验证 - 副本
  • 基于SystemVerilog语言的 UVM 验证方法学可以有效提高验证效率,缩短验证周期。采用高层次的抽象模型C_Model作为参考模型接入UVM平台,对数字基带处理单元中标签发送链路的编码模块进行验证,设计随机和非随机的...
  • 搭建UVM验证环境历程
  •   一个基本的 uvm 验证环境结构如下图所示,包含两个 agent,其中 in_agent 用于驱动 DUT ,同时将驱动数据同时传递给 reference model, out_agent 用于按照协议采集 DUT 的输出数据,并将数据传递给 scoreboard,...
  • UVM验证方法学之一验证平台

    千次阅读 2020-03-20 23:29:48
    UVM验证方法学之一验证平台 在现代IC设计流程中,当设计人员根据设计规格说明书完成RTL代码之后,验证人员开始验证这些代码(通常称其为DUT,Design Under Test)。验证工作主要保证从设计规格说明书到RTL转变的正确...
  • Sunburst OVM/UVM 验证培训由Cliff Cummings(SV的顶级专家)提供。让我们轻松学习OVM、UVM
  • UART UVM验证平台平台搭建总结 tb_top是整个UVM验证平台的最顶层;tb_top中例化dut,提供时钟和复位信号,定义接口以及设置driver和monitor的virual interface,在intial中调用run_test() UVM入口函数。在基于uvm_...
  • uvm_sin_cos_table:包含用于使用UVM验证sincos表的源代​​码
  • 可重用的UVM验证平台

    2020-10-24 17:39:27
    开发一个可重用的UVM验证平台,一般按照如下顺序进行: 对数据元素进行建模 开发事务级组件 开发driver 开发sequencer 连接driver和sequencer 开发monitor 例化上述组件 开发agent 开发env 启动场景创建 控制仿真...
  • 加入factory机制 上一节《IC验证"一个简单的UVM验证平台"是如何搭建的(五)》给出了一个只有driver、使用UVM搭建的验证平台。严格来说这根本就不算是UVM验证平台,因为UVM的特性几乎一 点都没有用到。像上节中my_...
  • 对于uvm验证的总结

    2019-11-27 19:42:33
    对于刚刚步入uvm验证的来说,如何逐步学习这个复杂的环境无疑有点困难,没有任何经验的去做往往事半功倍,在这里列出几点学习建议: 第一点: 不必去关注源代码的含义,只需搞懂源代码的格式和怎么写的就可以,没...
  • APB协议UVM验证环境的搭建 一、编译文件 只需编译这两个文件即可 apb_pkg.sv 里面包含了"apb.svh",即编译apb_pkg.sv这个文件的同时,也会编译所需要的所有的头文件。 `ifndef APB_PKG_SV `define APB_PKG_SV ...
  • 关于UVM验证平台的简单介绍和入门知识,这位老师讲解的相当不错,仅作为入门了解视频: https://v.qq.com/x/page/k07663evpjl.html
  • 一个加法器的UVM验证平台设计

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 824
精华内容 329
关键字:

uvm验证