15 Sequence-Driver-Sequencer communication in UVM

news2025/1/12 17:42:58

我们分别讨论了sequece_item、sequence、sequencer和driver。在本节中,我们将讨论他们如何相互talk,sequencer如何给driver提供从sequence里的sequence item。在开始阅读本节之前,请确保您了解sequencer和driver中使用的所有方法。(参考:UVM seqeuencer和UVM driver ). 

1 Sequencer-Driver Connections

sequencer和driver使用双向TLM接口相互通信,以传输REQ和RSP序列项。

driver的uvm_seq_iem_pull _port和相应的sequencer的uvm_seq_item_pull_export连接。这个TLM接口提供了一个工具,可以使用实现的API检索REQ item并返回RSP项。
注:

  1. uvm_seq_item_pull_port和uvm_secq_itemp_pull_export都是带有REQ和RSP sequence item的参数化类。
  2. driver和sequencer之间的TLM连接是一对一的。这意味着没有多个sequencer连接到单个driver,也没有多个driver连接到单个sequencer。

connections:driver和sequence在UVM agent的connect_phase中连接。

<driver_inst>.seq_item_port.connect(<sequencer_inst>.seq_item_export);

seq_item_port和seq_iem_export分别是uvm_seq_itemp_pull_port和uvm_sseq_tem_pull_export的实例句柄(instance handle)。 

2 Sequence-Driver-Sequencer communication Approaches

基于sequence和driver可用的各种方法,进一步解释所有组合。

方法A:Using get_next_item and item_done methods in the driver

方法B:Using get and put methods in driver

2.1 A. Using get_next_item and item_done methods in the driver

2.1.1 Without RSP packet

  1. 创建一个sequence item,并使用create_item函数在工厂中注册。
  2. wait_for_grant向sequencer发出请求,并等待sequencer的授权。当sequencer授予sequence时返回。
  3. 对sequence item进行随机化,并使用send_request将其发送到sequencer。wait_for_grant和send_request方法之间不能有任何仿真时间延迟。sequencer在REQ FIFO的帮助下将sequence item转发给driver。这将取消阻止get_next_item()调用,driver将接收序列sequence item。
  4. 来自sequence的wait_for_item_done()调用被阻止,直到driver响应。
  5. 同时,driver使用virtual interface句柄将sequence item驱动到DUT。完成后,将调用item_done方法。这将从sequence中取消阻止wait_for_item_done方法。
  6. 如果必须从driver向sequence发送响应,则使用RSP项作为参数调用item_done(RSP)。RSP项目通过sequencer在RSP FIFO的帮助下与sequence通信。调用get_response方法以获取响应很重要。如果DUT没有发送RSP项目,则此步骤是可选的,不是必需的。 
// Driver Code
class driver extends uvm_driver#(seq_item);
  `uvm_component_utils(driver)
  
  function new(string name = "driver", uvm_component parent = null);
    super.new(name, parent);
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
  endfunction
  
  task run_phase (uvm_phase phase);
    forever begin
      seq_item_port.get_next_item(req);
      `uvm_info(get_type_name(), "After get_next_item call", UVM_LOW);
      #50; // Driving delay. Assuming time taken to drive RTL signals
      seq_item_port.item_done();
      `uvm_info(get_type_name(), "After item_done call", UVM_LOW);
    end
  endtask
endclass

// Sequence Code
class base_seq extends uvm_sequence #(seq_item);
  seq_item req;
  `uvm_object_utils(base_seq)
  
  function new (string name = "base_seq");
    super.new(name);
  endfunction

  task body();
    `uvm_info(get_type_name(), "Base seq: Inside Body", UVM_LOW);
    //req = seq_item::type_id::create("req");
    // or
    $cast(req, create_item(seq_item::get_type(), m_sequencer, "req"));
    wait_for_grant();
    assert(req.randomize());
    send_request(req);
    `uvm_info(get_type_name(), "Before wait_for_item_done", UVM_LOW);
    wait_for_item_done();
    `uvm_info(get_type_name(), "After wait_for_item_done", UVM_LOW);
  endtask
endclass

Output:

UVM_INFO testbench.sv(21) @ 0: uvm_test_top.env_o.agt.seqr@@bseq [base_seq] Base seq: Inside Body
UVM_INFO testbench.sv(28) @ 0: uvm_test_top.env_o.agt.seqr@@bseq [base_seq] Before wait_for_item_done
UVM_INFO driver.sv(15) @ 0: uvm_test_top.env_o.agt.drv [driver] After get_next_item call
UVM_INFO driver.sv(19) @ 50: uvm_test_top.env_o.agt.drv [driver] After item_done call
UVM_INFO testbench.sv(30) @ 50: uvm_test_top.env_o.agt.seqr@@bseq [base_seq] After wait_for_item_done
2.1.2 With RSP packet

// Driver Code
class driver extends uvm_driver#(seq_item);
  `uvm_component_utils(driver)
  
  function new(string name = "driver", uvm_component parent = null);
    super.new(name, parent);
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
  endfunction
  
  task run_phase (uvm_phase phase);
    forever begin
      seq_item_port.get_next_item(req);
      `uvm_info(get_type_name(), "After get_next_item call", UVM_LOW);
      #50; // Driving delay. Assuming time taken to drive RTL signals
      req.rsp_b = 1;
      seq_item_port.item_done(req);
      `uvm_info(get_type_name(), "After item_done call", UVM_LOW);
    end
  endtask
endclass

// Sequence Code
class base_seq extends uvm_sequence #(seq_item);
  seq_item req;
  `uvm_object_utils(base_seq)
  
  function new (string name = "base_seq");
    super.new(name);
  endfunction

  task body();
    `uvm_info(get_type_name(), "Base seq: Inside Body", UVM_LOW);
    //req = seq_item::type_id::create("req");
    // or
    $cast(req, create_item(seq_item::get_type(), m_sequencer, "req"));
    wait_for_grant();
    assert(req.randomize());
    send_request(req);
    `uvm_info(get_type_name(), "Before wait_for_item_done", UVM_LOW);
    wait_for_item_done();
    `uvm_info(get_type_name(), "After wait_for_item_done", UVM_LOW);
    get_response(req);
    `uvm_info(get_type_name(), $sformatf("After get_response: rsp_b = %0d", req.rsp_b), UVM_LOW);
  endtask
endclass

 Output:

UVM_INFO testbench.sv(21) @ 0: uvm_test_top.env_o.agt.seqr@@bseq [base_seq] Base seq: Inside Body
UVM_INFO testbench.sv(28) @ 0: uvm_test_top.env_o.agt.seqr@@bseq [base_seq] Before wait_for_item_done
UVM_INFO driver.sv(15) @ 0: uvm_test_top.env_o.agt.drv [driver] After get_next_item call
UVM_INFO driver.sv(20) @ 50: uvm_test_top.env_o.agt.drv [driver] After item_done call
UVM_INFO testbench.sv(30) @ 50: uvm_test_top.env_o.agt.seqr@@bseq [base_seq] After wait_for_item_done
UVM_INFO testbench.sv(32) @ 50: uvm_test_top.env_o.agt.seqr@@bseq [base_seq] After get_response: rsp_b = 1

2.2 B. Using get and put methods in driver

  1. Create a sequence item and register in the factory using the create_item function call.
  2. The wait_for_grant issues the request to the sequencer and wait for the grant from the sequencer. It returns when the sequencer has granted the sequence.
  3. Randomize the sequence item and send it to the sequencer using send_request call. There should not be any simulation time delay between wait_for_grant and send_request method call. The sequencer forwards the sequence item to the driver with the help of REQ FIFO. This unblocks the get() call and the driver receives the sequence item.
  4. The wait_for_item_done() call from the sequence gets blocked until the driver calls the get method.
  5. Once the get method is called, the wait_for_item_done() call from sequence gets unblocked immediately without caring about driving the virtual interface.
  6. The get_response call is necessary to call that completes the communication. The get_response method is blocked until the driver calls put(RSP).
  7. In the meantime, the driver drives the sequence item to the DUT using a virtual interface handle. Once it is completed, the put(RSP) method is called. This unblocks the get_response method from the sequence. The RSP item is communicated to the sequence by a sequencer with help of RSP FIFO. 
// Driver Code
class driver extends uvm_driver#(seq_item);
  `uvm_component_utils(driver)
  
  function new(string name = "driver", uvm_component parent = null);
    super.new(name, parent);
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
  endfunction
  
  task run_phase (uvm_phase phase);
    forever begin
      seq_item_port.get(req);
      `uvm_info(get_type_name(), "After get call", UVM_LOW);
      #50; // Driving delay. Assuming time taken to drive RTL signals
      req.rsp_b = 1;
      seq_item_port.put(req);
      `uvm_info(get_type_name(), "After put call", UVM_LOW);
    end
  endtask
endclass

// Sequence Code
class base_seq extends uvm_sequence #(seq_item);
  seq_item req;
  `uvm_object_utils(base_seq)
  
  function new (string name = "base_seq");
    super.new(name);
  endfunction

  task body();
    `uvm_info(get_type_name(), "Base seq: Inside Body", UVM_LOW);
    //req = seq_item::type_id::create("req");
    // or
    $cast(req, create_item(seq_item::get_type(), m_sequencer, "req"));
    wait_for_grant();
    assert(req.randomize());
    send_request(req);
    `uvm_info(get_type_name(), "Before wait_for_item_done call", UVM_LOW);
    wait_for_item_done();
    `uvm_info(get_type_name(), "After wait_for_item_done call", UVM_LOW);
    get_response(req);
    `uvm_info(get_type_name(), $sformatf("After get_response: rsp_b = %0d", req.rsp_b), UVM_LOW);
  endtask
endclass

Output:

UVM_INFO testbench.sv(21) @ 0: uvm_test_top.env_o.agt.seqr@@bseq [base_seq] Base seq: Inside Body
UVM_INFO testbench.sv(28) @ 0: uvm_test_top.env_o.agt.seqr@@bseq [base_seq] Before wait_for_item_done call
UVM_INFO driver.sv(15) @ 0: uvm_test_top.env_o.agt.drv [driver] After get call
UVM_INFO testbench.sv(30) @ 0: uvm_test_top.env_o.agt.seqr@@bseq [base_seq] After wait_for_item_done call
UVM_INFO driver.sv(20) @ 50: uvm_test_top.env_o.agt.drv [driver] After put call
UVM_INFO testbench.sv(32) @ 50: uvm_test_top.env_o.agt.seqr@@bseq [base_seq] After get_response: rsp_b = 1

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1341021.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

idea Spring Boot项目使用JPA创建与数据库链接

1.pom.xml文件中添加依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>com.mysql</groupId><artifactId>…

Python+OpenCV 零基础学习笔记(4-5):计算机图形基础+Python相对文件路径+OpenCV图像+OpenCV视频

文章目录 相关链接运行环境前言计算机图形OpenCV简单使用图形读取文件读取可能会出现的问题&#xff1a;路径不对解决方案其它路径问题解决方案 图像显示保存OpenCV视频视频素材如何获取&#xff1f;简单视频读取 相关链接 【2022B站最好的OpenCV课程推荐】OpenCV从入门到实战 …

Jackson通过自定义序列化器给URL拼接访问域名

1、需求 在存储文件访问路径时&#xff0c;一般不会存储域名地址&#xff0c;若文件服务域名和当前应用域名不一致时&#xff0c;就需要在返回数据库的图片路径给前端时&#xff0c;拼接文件服务的域名。 2、处理方式 因为Spring Boot默认使用的是Jackson作为序列化工具&…

redis的搭建及应用(二)-redis的持久化策略

Redis的持久化策略 RDB RDB持久化是指在指定的时间间隔内将redis内存中的数据集快照写入磁盘&#xff0c;实现原理是redis服务在指定的时间间隔内先fork一个子进程&#xff0c;由子进程将数据集写入临时文件&#xff0c;写入成功后&#xff0c;再替换之前的文件&#xff0c;用二…

【力扣】20.有效的括号

家人们&#xff0c;看这排序&#xff0c;一看就很简单&#xff0c;对吧&#xff1f;不对&#xff0c;我觉得还挺不是很容易的&#xff0c;哈哈哈。 题解&#xff1a; 在看题目的时候&#xff0c;我一开始的解题思路就挺复杂的。题目说了”左括号必须以正确的顺序闭合“&#x…

76 Python开发-内外网收集Socket子域名DNS

目录 Python开发相关知识点本篇文章涉及知识点演示案例:IP&Whois&系统指纹获取代码段-外网CDN&子域名&端口扫描&交互代码段-外网IP&计算机名&存活主机&端口扫描代码段-内网Py格式解析环境与可执行程序格式转换-Pyinstaller 涉及资源&#xff1…

我的NPI项目之行业黑话 -- 电子/机构/软件/认证

因为最近的NPI项目&#xff0c;参加了很多项目的会议&#xff0c;有电子/机构/软件/认证相关的各方面的专业词汇就出现了。这里我将之称为黑话&#xff0c;就是对我&#xff08;纯软件) 来说是黑盒的话。这里简单记录并用于理解。 EE有关&#xff1a; Layout&#xff0c;一直…

详解全志R128 RTOS安全方案功能

介绍 R128 下安全方案的功能。安全完整的方案基于标准方案扩展&#xff0c;覆盖硬件安全、硬件加解密引擎、安全启动、安全系统、安全存储等方面。 配置文件相关 本文涉及到一些配置文件&#xff0c;在此进行说明。 env*.cfg配置文件路径&#xff1a; board/<chip>/&…

树莓派界面改成中文

安装完树莓派系统(Raspberry Pi OS with Desktop)&#xff0c;第一次启动时&#xff0c;时会有如下面二个图所示&#xff0c;让你选择区域时区和语言。 树莓派默认的语言为英文&#xff0c;如果你在安装时没有选择的话&#xff0c;默认的区域为英国&#xff0c;语言为英国英文&…

Translation翻译插件

Translation插件是为IntelliJ IDEA开发的&#xff0c;因此只能在IntelliJ IDEA中使用。但是&#xff0c;如果你需要在其他软件中进行翻译&#xff0c;可以考虑使用其他的翻译工具或服务。例如&#xff0c;一些在线翻译网站&#xff08;如Google翻译、百度翻译等&#xff09;提供…

hosts文件、DNS、删除浏览器域名安全策略、浏览器代理

文章目录 1. hosts文件2. DNS3. 删除浏览器域名安全策略4. 浏览器代理服务器 1. hosts文件 位置 C:\Windows\System32\drivers\etc\hosts 没有后缀名 内容 ip 一个空格 域名 定义 hosts就是系统的一个配置文件&#xff0c;主要配置ip和域名的映射关系&#xff0c;相当于是本地…

低信噪比环境下的语音端点检测

端点检测技术 是 语音信号处理 的关键技术之一为提高低信噪比环境下端点检测的准确率和稳健性&#xff0c;提出了一种非平稳噪声抑制和调制域谱减结合功率 归一化 倒谱距离的端点检测算法 1 端点检测 1-1 定义 定义&#xff1a;在 存在背景噪声 的情况下检测出 语音的起始点和…

记录 Docker 中安装 ROS2

目录 1 安装 Docker 2 安装 ROS2 3 启动 Docker 4 测试 ROS2 环境 1 安装 Docker 1. 更新软件包sudo apt updatesudo apt upgrade2. 安装 docker 依赖sudo apt-get install ca-certificates curl gnupg lsb-release3. 添加 docker 官方 GPG 密钥curl -fsSL http://mirror…

小米路由器2(R2D) 安装 MIXBOX

1. 先刷开发版 ROM http://www1.miwifi.com/miwifi_download.html 进入上述网页&#xff0c;找到 R2D 点击下载 开发版 ROM 教程 看 下载按钮上边的 “刷机教程” 刷机教程 2. 开启SSH工具 登录自己的小米账号后&#xff0c;里面会显示出 自己的 root密码&#xff1b; 默认…

9_js_dom编程进阶3

Dom节点删除和复制操作事件加强讲解 1. 节点操作 1.1 删除节点 Node.removeChild() 方法从 DOM 中删除一个子节点。返回删除的节点。 child 是要移除的那个子节点。 node 是child的父节点。 PS&#xff1a;只能由父节点删除子节点 课堂案例&#xff1a;1.节点操作之删除节…

酷我音乐逆向 请求头 参数解密(js逆向)

免责声明&#xff1a;     本篇博文的初衷是分享自己学习逆向分析时的个人感悟&#xff0c;所涉及的内容仅供学习、交流&#xff0c;请勿将其用于非法用途&#xff01;&#xff01;&#xff01;任何由此引发的法律纠纷均与作者本人无关&#xff0c;请自行负责&#xff01;&…

使用Rust发送邮件

SMTP协议与MIME协议 SMTP&#xff08;简单邮件传输协议,Simple Mail Transfer Protocol&#xff09;是一种用于发送和接收电子邮件的互联网标准通信协议。它定义了电子邮件服务器如何相互发送、接收和中继邮件。SMTP 通常用于发送邮件&#xff0c;而邮件的接收通常由 POP&#…

通过C++程序实现光驱的自动化刻录和读取

文章目录 ISO文件格式光盘的基本概念光盘种类特点DVDR光盘使用windows调用Linux调用Linux平台下用到的C库:读取设备驱动列表向光驱中写文件 数字存储媒体快速发展的今天&#xff0c;光驱的使用已经不像以前那样普及了。但是在数据备份、安装软件和操作系统、旧设备兼容等领域还…

redis的搭建及应用(三)-Redis主从配置

Redis主从配置 为提升Redis的高可用性&#xff0c;需要搭建多个Redis集群以保证高可用性。常见搭建方式有&#xff1a;主从&#xff0c;哨兵集群等&#xff0c;本节我们搭建一主二从的多Redis架构。 redis主从安装1主2从的方式配置&#xff0c;以端口号为redis的主从文件夹。 主…

Elasticsearch8.x结合OpenAI CLIP模型实现图搜图及文搜图功能

前言 在当今大数据时代&#xff0c;搜索引擎已经是许多应用的核心组件之一&#xff0c;近年随着大模型以及AI技术&#xff08;如&#xff1a;自然语言处理NLP&#xff09;的流行&#xff0c;这些技术的结合将会创造出更多的应用场景&#xff0c;比如&#xff1a;电商商品搜索、…