当前位置: 首页 > news >正文

creating and using sequence

序列由多个数据项组成,这些数据项可能构成有趣的测试场景。例如,您可以创建对设计内所有寄存器执行读写操作的序列、执行复位的序列,或向被测设备施加激励的另一个序列。最终您会拥有多个执行不同任务的序列,用于验证设计的各个方面。请注意:序列项指代数据包,而序列只是数据项/子序列排列的容器。

现在,你有几个选择:

使用现有序列单独驱动DUT的激励;
组合现有序列创建新序列——例如先执行复位序列,再进行寄存器读写序列,最后执行FSM状态转换序列;
从序列库中随机抽取序列并在DUT上执行;

序列可以对序列项执行操作,或启动新的子序列:

通过序列的start()方法或uvm_do宏来执行;
通过start_item/finish_itemuvm_do宏来执行序列项;
uvm_do宏会判断参数是序列还是序列项,并相应调用start()start_item()方法;

在本页面中,我们将尝试通过start_item/finish_item任务来执行一个序列项。要创建用户自定义序列:

从指定数据对象类型的uvm_sequence基类派生;
使用uvm_object_utils向工厂注册该序列;
设置应执行此序列的默认sequencer;
在body()任务中编写主要激励代码;

Let's look at an example next.

class base_sequence extends uvm_sequence #(my_data);`uvm_object_utils (base_sequence)`uvm_declare_p_sequencer (my_sequencer)my_data  data_obj;int unsigned      n_times = 1;function new (string name = "base_sequence");super.new (name);endfunctionvirtual task pre_body ();`uvm_info ("BASE_SEQ", $sformatf ("Optional code can be placed here in pre_body()"), UVM_MEDIUM)if (starting_phase != null)starting_phase.raise_objection (this);endtaskvirtual task body ();`uvm_info ("BASE_SEQ", $sformatf ("Starting body of %s", this.get_name()), UVM_MEDIUM)data_obj = my_data::type_id::create ("data_obj");repeat (n_times) beginstart_item (data_obj);assert (data_obj.randomize ());finish_item (data_obj);end`uvm_info (get_type_name (), $sformatf ("Sequence %s is over", this.get_name()), UVM_MEDIUM)endtaskvirtual task post_body ();`uvm_info ("BASE_SEQ", $sformatf ("Optional code can be placed here in post_body()"), UVM_MEDIUM)if (starting_phase != null)starting_phase.drop_objection (this);endtask
endclass

请注意上述示例中的要点:

  1. base_sequence 继承自 uvm_sequence,其数据对象类型为 my_data
  2. 该序列通过宏 uvm_declare_p_sequencer 指定使用 my_sequencer 执行(类似sequence 不绑定sequencer ,使用config_db#()::set  default sequence 实现 ??? )
  3. 主要任务 body() 包含向驱动器发送激励的代码
  4. 可包含(非必须)两个额外任务 pre_body() 和 post_body(),分别在执行 body() 前后执行特定操作
  5. 序列启动时务必置位标志位/提出异议(objection),通知测试平台其仍在运行。该标志位应在序列结束时清除,以便测试平台能优雅结束仿真。若未置位标志,可能导致测试平台其他组件调用仿真退出,致使序列异常终止。该操作也可置于 body() 任务中
  6. 数据对象将通过随机化后,经由 start_item 和 finish_item 发送至驱动器

让我们创建一个简单的序列器来执行上述序列。

class my_sequencer extends uvm_sequencer #(my_data);`uvm_component_utils (my_sequencer)function new (string name, uvm_component parent);super.new (name, parent);endfunctionendclass

记得将默认序列设为基础序列。

class base_test extends uvm_test;...function void start_of_simulation_phase (uvm_phase phase);super.start_of_simulation_phase (phase);uvm_config_db#(uvm_object_wrapper)::set(this,"m_top_env.m_seqr0.main_phase","default_sequence", base_sequence::type_id::get());endfunction...
endclass

Alternatives

Use uvm_sequencer

如果您不想创建一个新的sequencer类,而更倾向于使用uvm_sequencer,您可以通过替换相应的代码行来实现。这样将创建一个类型为uvm_sequencer的sequencer,它可以操作my_data类型的数据,而不是上面示例中用户定义的自定义sequencer。

class base_sequence extends uvm_sequence #(my_data);...`uvm_declare_p_sequencer (uvm_sequencer #(my_data))...
endclassclass my_env extends uvm_env;...uvm_sequencer #(my_data) m_seqr0;...virtual function void build_phase (uvm_phase phase);...m_seqr0 = uvm_sequencer#(my_data)::type_id::create ("m_seqr0", this);endfunction
endclass

Use uvm_sequence_utils

另一种实现相同任务的方法是:在向工厂注册时,对序列使用宏uvm_sequence_utils,对序列器使用宏uvm_sequencer_utils。记得调用uvm_update_sequence_lib_and_item宏来更新数据库。该宏未来可能会被弃用

class my_sequencer extends uvm_sequencer #(my_data);function new (string name, uvm_component parent);super.new (name, parent);`uvm_update_sequence_lib_and_item (my_data)endfunction`uvm_sequencer_utils (my_sequencer)
endclassclass base_sequence extends uvm_sequence #(my_data);`uvm_sequence_utils (base_sequence, my_sequencer)...
endclass

 Simulation Log

----------------------------------------------------------------
CDNS-UVM-1.1d (14.10-s013)
(C) 2007-2013 Mentor Graphics Corporation
(C) 2007-2013 Cadence Design Systems, Inc.
(C) 2006-2013 Synopsys, Inc.
(C) 2011-2013 Cypress Semiconductor Corp.
----------------------------------------------------------------
UVM_INFO @ 0: reporter [RNTST] Running test base_test...
UVM_INFO @ 0: reporter [UVMTOP] UVM testbench topology:
------------------------------------------------------------
Name                     Type                    Size  Value
------------------------------------------------------------
uvm_test_top             base_test               -     @2631m_top_env              my_env                  -     @208m_drv0               my_driver               -     @202rsp_port           uvm_analysis_port       -     @2830seq_item_port      uvm_seq_item_pull_port  -     @2779m_seqr0              my_sequencer            -     @2730rsp_export         uvm_analysis_export     -     @2920seq_item_export    uvm_seq_item_pull_imp   -     @3468arbitration_queue  array                   0     -lock_queue         array                   0     -num_last_reqs      integral                32    'd1num_last_rsps      integral                32    'd1
------------------------------------------------------------UVM_INFO ./tb/my_pkg.sv(98) @ 0: uvm_test_top.m_top_env.m_drv0 [my_driver] Applying initial reset
UVM_INFO ./tb/my_pkg.sv(102) @ 390000: uvm_test_top.m_top_env.m_drv0 [my_driver] DUT is now out of reset
UVM_INFO ./tb/my_pkg.sv(109) @ 390000: uvm_test_top.m_top_env.m_drv0 [my_driver] Waiting for data from sequencer
UVM_INFO ./tb/my_pkg.sv(149) @ 390000: uvm_test_top.m_top_env.m_seqr0@@base_sequence [BASE_SEQ] Optional code can be placed here in pre_body()
UVM_INFO ./tb/my_pkg.sv(155) @ 390000: uvm_test_top.m_top_env.m_seqr0@@base_sequence [BASE_SEQ] Starting body of base_sequence
UVM_INFO ./tb/my_pkg.sv(122) @ 410000: uvm_test_top.m_top_env.m_drv0 [DRV] Driving data item across DUT interface
data_obj: (my_data@3581) {data: 'hedaddr: 'h5begin_time: 390000depth: 'd2parent sequence (name): base_sequenceparent sequence (full name): uvm_test_top.m_top_env.m_seqr0.base_sequencesequencer: uvm_test_top.m_top_env.m_seqr0
}
UVM_INFO ./tb/my_pkg.sv(109) @ 410000: uvm_test_top.m_top_env.m_drv0 [my_driver] Waiting for data from sequencer
UVM_INFO ./tb/my_pkg.sv(163) @ 410000: uvm_test_top.m_top_env.m_seqr0@@base_sequence [base_sequence] Sequence base_sequence is over
UVM_INFO ./tb/my_pkg.sv(168) @ 410000: uvm_test_top.m_top_env.m_seqr0@@base_sequence [BASE_SEQ] Optional code can be placed here in post_body()
UVM_INFO ./tb/my_pkg.sv(128) @ 410000: uvm_test_top.m_top_env.m_drv0 [my_driver] Finished DUT simulation--- UVM Report catcher Summary ---

summary: 

        seuqnece 是弹夹,可以在body内使用uvm_do marco,也可以使用start_item,randomize,finish_item  2 种方式发送数据;

        sequence 和sequencer的绑定,使用start ().  或者使用default sequence;

        uvm_do_on支持item、sequence和 sequencer的绑定,至少需要raise objection 一次;

http://www.xdnf.cn/news/1205155.html

相关文章:

  • AI论文阅读方法+arixiv
  • Redis未授权访问的利用的几种方法原理以及条件
  • yolo 目标检测600类目标
  • STM32中集成USB驱动
  • STM32 USB HOST 驱动FT232 USB转串
  • Android 解析 TrafficDescriptor 的 OSAPP 信息
  • OpenLayers 综合案例-区域掩膜
  • [机缘参悟-237]:AI人工神经网络与人类的神经网络工作原理的相似性
  • SpringBoot数学实例:高等数学实战
  • 7.项目起步(1)
  • Baumer工业相机堡盟工业相机如何通过YoloV8深度学习模型实现面部口罩的检测识别(C#代码,UI界面版)
  • 数据结构(动态数组)
  • HTML应用指南:利用GET请求获取全国小米之家门店位置信息
  • 第4章唯一ID生成器——4.2 单调递增的唯一ID
  • 【Zustand】从复杂到简洁:Zustand 状态管理简化实战指南
  • 绿算技术携手昇腾发布高性能全闪硬盘缓存设备,推动AI大模型降本增效
  • Laravel 分页方案整理
  • 安宝特新闻丨Vuzix与Wyr.Ai合作推出基于M400眼镜的全新一代质检平台
  • springboot校园外卖配送系统
  • 【设计模式】状态模式 (状态对象(Objects for States))
  • Linux应用程序架构与软件包管理
  • Redis实战(3)-- 高级数据结构zset
  • MySQL5.7主从延迟高排查优化思路
  • Qt:盒子模型的理解
  • 电流变送器电路的分析与计算
  • TCPIP之常用协议
  • LeetCode--50.Pow(x,n)
  • RCLAMP2574N.TCT Semtech:超低钳位TVS二极管 0.5pF超低电容+±30kV超强防护
  • FastGPT本地构建工作流高级编排(最新4.11.0)
  • 【云馨AI-大模型】2025世界人工智能大会引爆全球AI热潮,技术突破与政策布局引领产业新未来