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

本文转载自https://blog.csdn.net/zhajio/article/details/79612388,感谢原作者。

 

上一篇文章集中讨论了 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。


PS:为避免竞争冒险,testbench需要使用同步后的信号,clocking时钟块即实现的同步功能,DUT不需要同步。


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列表,则接口中的信号被假定为无法访问。


PS:实际使用中,一般不这么用,dut不会使用interface,老老实实的在top中使用intf.xxx连接dut。

调用class中的成员:jelly_bean_transaction::YUCKY,YUCKY是class中定义的enum变量。::类似于使用extern 方法时的操作。


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_config_db数据库中

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);
      assert( uvm_config_db#( virtual jelly_bean_if )::get( this,"","jelly_bean_if",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)


PS:interface相当于硬件,静态的,一直存在,class是动态的,class中是不能直接例化interface的,所以使用virtual,相当于取了interface的句柄。也可以直接使用top.intf_inst,但移植性会差些。

drv驱动的信号flavor--sour都是用的master_cb中的信号,为output型!主动产生激励的才是master,dut接受激励,为slave。


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行的用户。

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);
      assert(uvm_config_db#(virtual jelly_bean_if)::get(this,"","jelly_bean_if",jb_vi));
      jb_ap = new(.name("jb_ap"), .parent(this));
   endfunction: 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()));
            //ATTENTION
            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

PS: 注意类型转换的操作,将flavor转换为枚举型值:jelly_bean_transaction::flavor_e'(jb_vi.slave_cb.flavor)。

注意mon中,采样的值flavor、color、sugar_free、sour用的是slave_cb中的信号,input型。taste则是用的master_cb中的信号,也是input型,平台不能对intf中的output型采样,因为这些值刚赋值完就采样,会引起竞争冒险


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

PS:drv需要和sqr通过端口进行连接,虽然seq_item_port和seq_item_export是内建的。 


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SystemVerilog的听课学习笔记,包括讲义截取、知识点记录、注意事项等细节的标注。 目录如下: 第一章 SV环境构建常识 1 1.1 数据类型 1 四、二值逻辑 4 定宽数组 9 foreach 13 动态数组 16 队列 19 关联数组 21 枚举类型 23 字符串 25 1.2 过程块和方法 27 initial和always 30 function逻辑电路 33 task时序电路 35 动态 静态变量 39 1.3 设计例化和连接 45 第二章 验证的方法 393 动态仿真 395 静态检查 397 虚拟模型 403 硬件加速 405 效能验证 408 性能验证 410 第三章 SV组件实现 99 3.1 接口 100 什么是interface 101 接口的优势 108 3.2 采样和数据驱动 112 竞争问题 113 接口中的时序块clocking 123 利于clocking的驱动 133 3.3 测试的开始和结束 136 仿真开始 139 program隐式结束 143 program显式结束 145 软件域program 147 3.4 调试方法 150 第四章 验证的计划 166 4.1 计划概述 166 4.2 计划的内容 173 4.3 计划的实现 185 4.4 计划的进程评估 194 第五章 验证的管理 277 6.1 验证的周期检查 277 6.2 管理三要素 291 6.3 验证的收敛 303 6.4 问题追踪 314 6.5 团队建设 321 6.6 验证的专业化 330 第六章 验证平台的结构 48 2.1 测试平台 49 2.2 硬件设计描述 55 MCDF接口描述 58 MCDF接口时序 62 MCDF寄存器描述 65 2.3 激励发生器 67 channel initiator 72 register initiator 73 2.4 监测器 74 2.5 比较器 81 2.6 验证结构 95 第七章 激励发生封装:类 209 5.1 概述 209 5.2 类的成员 233 5.3 类的继承 245 三种类型权限 protected/local/public 247 this super 253 成员覆盖 257 5.4 句柄的使用 263 5.5 包的使用 269 第八章 激励发生的随机化 340 7.1 随机约束和分布 340 权重分布 353 条件约束 355 7.2 约束块控制 358 7.3 随机函数 366 7.4 数组约束 373 7.5 随机控制 388 第九章 线程与通信 432 9.1 线程的使用 432 9.2 线程的控制 441 三个fork...join 443 等待衍生线程 451 停止线程disable 451 9.3 线程的通信 458 第十章 进程评估:覆盖率 495 10.1 覆盖率类型 495 10.2 功能覆盖策略 510 10.3 覆盖组 516 10.4 数据采样 524 10.5 覆盖选项 544 10.6 数据分析 550 第十一章 SV语言核心进阶 552 11.1 类型转换 552 11.2 虚方法 564 11.3 对象拷贝 575 11.4 回调函数 584 11.5 参数化的类 590 第十二章 UVM简介 392 8.2 UVM简介 414 8.3 UVM组件 420 8.4 UVM环境 425
### 回答1: uvm-1.1a.tar.gz是一个库文件,它是Universal Verification Methodology(UVM)的开源版本,旨在帮助硬件验证工程师实现更高效、更准确的系统级验证工作。该版本的发布包括完整的UVM框架和示例代码,它们可以被应用于各种验证环境中。其中包含了基于SystemVerilog的类库、通用模型、事务级建模器和随机验证,同时也包括了DPI、OVM等不同验证中间件框架的支持。该版本提供了更多的互操作性和可扩展性,让用户能够快速开发和部署大规模验证工作。UVM已经成为ASIC和FPGA验证领域的事实标准,可以在不同的平台和工具上进行移植。因为它的开源特性和流行度,UVM支持社区持续创新和最佳实践的分享,不断提高Verilog验证技术的水平和效率。 ### 回答2: uvm-1.1a.tar.gz是一种开源的验证方法学框架,为现代芯片验证提供了一种完整而灵活的解决方案。它提供了一套可重用的Class Library,包括了各种验证组件,如监控,分析器,交通形成器和交通收集器,并提供了一种现代的验证方法学,包括创建可重用的测试用例和环境。UVM框架是基于SystemVerilog语言的,是目前工业界最常用的验证环境之一。该框架可以帮助芯片设计者和验证工程师更有效地制定验证计划和执行测试,缩短开发周期,提高产品质量和可重复性。同时,UVM也在学术界和研究机构中广泛应用,为芯片验证方法学的研究和发展提供了有力的支持和平台。总之,uvm-1.1a.tar.gz是一个非常有用的开源验证方法学框架,为芯片验证提供了强大的支持和帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值