SystemVerilog Interface Class的妙用

前言

Interface Class是在SystemVerilog 2012版本中引入的,但目前在验证中几乎很少采用,大多数验证工程师要么不知道它,要么没有看到使用它的任何好处,这使得Interface Class成为一个未被充分使用和不被重视的特性。本文将举两个Interface Class的使用例子,在这些例子中,Interface Class提高了验证环境的灵活性和质量,同时进一步提高了其可维护性和可调试性。

示例1:观察者设计模式

Interface Class用于观察者设计模式(Observer Design pattern)。观察者模式允许你定义一种订阅机制, 可在对象事件发生时通知多个 “观察” 该对象的其他对象。例如验证环境中monitor需要采集interface上的信息,将其组合成某种transaction数据结构,并将其发送给感兴趣的各方组件,例如scoreboard和checker。在这里,monitor也称作publisher,scoreboard和checker称作subscriber或listener。如下图所示。

图1 观察者设计模式

UVM方法学通过TLM analysis port开发了观察者模式,提供了在publisher和subscriber之间创建连接的方法,实现一对多的连接。这种方式在现在验证环境中大量使用了,但也有许多限制:

  • 限制一:这种方式的组件连接是静态的,它们通常在connect_phase就确定了,并且只有uvm_component可以参与连接。
  • 限制二:这种通信方式仅限于一种类型的单个事务传输。
  • 限制三:subscriber需要多个analysis port时需要求助于UVM宏,或者创建子层次结构来监听transaction。

使用Interface Class实现的观察者模式完美解决了所有这三个问题。下图提供与UVM analysis port非常相似功能的实例。

interface class resolve_listener;pure virtual function void new_resolve(txn_resolve resolve);
endclass : resolve_listenerclass monitor extends uvm_component;local resolve_listener m_resolve_listeners[$];function void add_listener(resolve_listener listener);m_resolve_listener.push_back(listener);endfunctionvirtual task run_phase(uvm_phase phase);forever begintxn_resolve resolve = get_next_resolve();foreach(m_resolve_listeners[i])m_resolve_listeners[i].new_resolve(resolve);endendtaskendclass : monitorclass resolve_checker extends uvm_component implements resolve_listener;virtual function void connect_phase(uvm_phase phase);super.connect_phase(phase);m_config.monitor.add_listener(this);endfunctionvirtual function void new_resolve(txn_resolve resolve);if (resolve.is_abort())`uvm_fatal(get_name(), "Aborts are not expected")endfunctionendclass : resolve_checker

图2 使用Interface Class实现通信

首先这个实例使用了动态连接,subscribers可以在仿真过程中的任何时间点向publisher注册自己(并不限制于connect_phase阶段),并开始订阅transactions。另外,这个实例也允许UVM sequence等非uvm_component直接订阅monitor、BFM和checker等的transactions。下面为reactive sequence直接利用monitor监控到的接口行为产生其它动作的例子,这样的写法使得reactive sequence更容易编写。维护和理解,而不需要借助于sequencer和sequence之间错综复杂的通信通道。

task run_sequence();m_done = 0;m_config.monitor_l1l2.add_listener(this);wait(m_done);m_config.monitor_l1l2.remove_listener(this);
endtaskvirtual function void new_l1l2_request(txn_l1l2 req);// Wait until a request to upgrade line from shared to exclusive is seen and// send a snoop request to steal the line awayif (!m_done && l1l2.req_type() == READ_UNIQUE_HIT_SHARED) beginsend_snoop(SNOOP_INVALIDATE, l1l2.req_address());m_done = 1;end
endfunction

图3 使用观察者模式直接订阅monitor的事件

第二个是subscriber和publisher之间的接口并不局限于单个transaction传输。接口函数new_resolve(…)可以传递任何可能对subscriber有用的附加信息,如下面new_resolve新的函数参数。

pure virtual function void new_resolve(txn_uop uop, txn_resolve resolve);

图4 new_resolve新定义

最后,subscriber可以订阅多个publisher的消息,因为Interface Class允许多继承,下图的例子是order检查器一方面订阅正在进行的微操作(micro operation),另一方面订阅了ACE协议口发出的请求,并检查它们是否是以正确的顺序进行。这样生成的代码比使用UVM analysis port更干净和直接得多,那个函数做什么很清楚。

class ordering_checker extends checker implements uop_listener, ace_listener;local txn_uop m_ordered_uops[$];// Register ourselves with micro-op and ACE agentsvirtual function void connect_phase(uvm_phase phase);super.connect_phase(phase);m_config.uop_agent.add_listener(this);m_config.ace_agent.add_listener(this);endfunction// On commits, record micro-ops that need to be orderedvirtual function void new_commit(txn_uop uop, txn_commit commit);if (commit.is_clean() && uop.is_ordered())m_ordered_uops.push_back(uop);endfunction// On ACE requests, compare address and sizevirtual function void new_ace_req(ace_req ace_request);txn_uop uop;if (!ace_request.needs_to_be_ordered())return;uop = m_ordered_uops.pop_front();check(ace_request.addr().equals(uop.addr()) && (ace_request.size() == uop.size()),{"ACE request seen doesn¿t match the oldest micro-op: ", uop.covert2string()});endfunctionendclass : ordering_checker

图5 checker订阅两个不同的monitor的事件

在某些情况下,用于复杂checker的subscriber的Interface Class定义了许多函数,但并非所有函数都在每个subscriber中用到。一种解决方案是将Interface Class分解为更小的类,但这需要向订阅所有events的subscriber添加额外代码。可以使用一个优雅的解决方案,也就是引入中间层类,中间层类为Interface Class的所有函数提供了空的实现,允许子类只覆盖它需要的函数,如下图所示。

class uop_listener_mixin(type T = uvm_component) extends T implements uop_listener;virtual function void new_resolve(txn_uop uop, txn_resolve resolve);endfunctionvirtual function void new_commit(txn_uop uop, txn_commit commit);endfunctionvirtual function void new_issue(txn_uop uop);endfunctionvirtual function void uop_flush(txn_uop uop, flush_cause_e cause);endfunctionendclass : uop_listener_mixinclass uop_checker extends uop_listener_mixin#(checker);virtual function void new_issue(txn_uop uop);check_uop(uop);endfunctionendclass : uop_checker

图6 在Interface Class中使用中间层

这种方式的一大优点是,仍然允许中间层继承多个Interface Class,进而订阅多个接口的transactions。order检查器的声明可以写成如下图所示。

class strongly_ordered_checker extends uop_listener_mixin#(l1l2_listener_mixin #(checker));

图7 中间层的嵌套使用

示例2:多继承

在SystemVerilog中缺乏真正的多继承,我们可以使用Interface Class来绕过这个限制,我们以Arm指令类为例。下图左边为带地址的指令,比如load和store指令,右边为不带地址的操作,比如data barrier指令中的DMB和DSB等。但如果引入了Load-Acquire(LDAR)和Store-Release(STLR)指令呢(LDAR和STLR指令的行为就像是二合一指令,它们即是load/store,也是barrier)?那么它们在下图中该处于什么位置呢?

图8 CPU指令集的典型类层次划分

如果支持类多继承的话,LDAR可以从load和data barrier类继承。但缺乏类多继承的情况下,大多数类层次结构只允许LDAR继承自load,并且要么将所有特定于barrier的函数放在共同基本类中,要么在任何地方编写特殊代码来处理此问题,这样会导致代码更难以维护。

然而,有了Interface Class一切就好办了,它允许我们做一些类似于多继承的实现。我们可以定义一个Barrier Interface Class,它声明描述Barrier行为的函数,然后让Dat啊Barrier、LDAR和STLR类实现它。现在,判断一个指令是否是Barrier只需要做一次$cast检查就好了。

interface class barrier;// Return 1 if this barrier affects the given uop in a given directionpure virtual function bit affects_uop(txn_uop uop, dir_e direction);// Perform age comparison between a barrier and a uoppure virtual function bit is_barrier_older(txn_uop uop);//...
endclass : barrierclass barrier_checker;function void check_out_of_order_resolve(txn_uop first, txn_uop second);barrier bar;if ($cast(bar, second) && bar.affects_uop(first, YOUNGER))`uvm_fatal(get_name(), "Uop bypassed a barrier it isn¿t allowed to.")endfunction
endclass :barrier_checker

图9 Barrier Interface Class的使用示例

这种方式可以用于指令类层次结构中的其它指令,比如exclusive指令、atomic指令等等。

总结

本文两个Interface Class用例都会使得验证环境开发更加容易,观察者模式使得transaction传递更加清晰和灵活,这对激励质量有特别积极的影响,sequence可以直接根据monitor中的事件自适应调整激励。多继承模式简化了类的层次结构,使每个类的职责有更清晰的划分。

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

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

相关文章

docker镜像深入理解

大家好,本篇文章和大家聊下docker相关的话题~~ 工作中经常有关于docker镜像的问题,让人百思不解 docker镜像加载到系统中到哪里去了?docker load 加载镜像的流程是怎样的?为什么容器修改内容后,删除容器后再次开启容…

阿里云 MQTT 服务器搭建与测试(上传和下发数据finish)

一、 MQTT 概念 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的"轻量级"通讯协议,该协议构建于 TCP/IP协议上,由 IBM 在 1999 年发布。MQTT 最大优点在于,可以以极少的代码和有限的带宽,…

c++之旅第十弹——IO流

大家好啊,这里是c之旅第十弹,跟随我的步伐来开始这一篇的学习吧! 如果有知识性错误,欢迎各位指正!!一起加油!! 创作不易,希望大家多多支持哦! 一.流的概念&…

kNN算法-概述

所谓kNN算法就是K-nearest neigbor algorithm。这是似乎是最简单的监督机器学习算法。在训练阶段,kNN算法存储了标签训练样本数据。简单地说,就是调用训练方法时传递给它的标签训练样本会被它存储起来。 kNN算法也叫lazy learning algorithm懒惰学习算法…

计算机网络 期末复习(谢希仁版本)第8章

元文件就是一种非常小的文件,它描述或指明其他文件的一些重要信息。这里的元文件保存了有关这个音频/视频文件的信息。 10. 流式:TCP;流式实况:UDP。

Huawei 大型 WLAN 组网 AC 间漫游

AC1配置命令 <AC6005>display current-configuration # vlan batch 100 # interface Vlanif100description to_S3_CAPWAPip address 10.0.100.254 255.255.255.0 # interface GigabitEthernet0/0/1port link-type trunkport trunk allow-pass vlan 100# ip route-stati…

Chrome浏览器书签同步不及时怎么办?两种方法帮你解决!

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;CSDN博客专家   &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01…

7种方法教你如何解决msvcp140_1.dll丢失问题,一键修复dll丢失问题

msvcp140_1.dll 是 Microsoft Visual C 2015 Redistributable 的一部分&#xff0c;它提供了运行时所需的 C 标准库的实现。这个 DLL 文件对于依赖 Visual C 2015 编译的应用程序至关重要&#xff0c;因为它包含了程序运行时所必需的函数和资源。 作用 运行时支持&#xff1a…

28-LINUX--I/O复用-epoll

一.epoll概述 epoll 是 Linux 特有的 I/O 复用函数。它在实现和使用上与 select、poll 有很大差异。首 先&#xff0c;epoll 使用一组函数来完成任务&#xff0c;而不是单个函数。其次&#xff0c;epoll 把用户关心的文件描述 符上的事件放在内核里的一个事件表中。从而无需像…

mysql (事物)

一.什么是事物 事物是一组操作的集合&#xff0c;不可分割的工作单位&#xff0c;事物会把所有的操作当作一个整体一起向系统提交或撤销操作请求&#xff0c;就是这些操作要么一起成功要么一起失败。 二.事物操作 &#xff08;这个就是一个理解&#xff09; 1.事务特性 原子性…

超详解——python数字和运算——小白篇

目录 1.位运算 2. 常用内置函数/模块 math模块&#xff1a; random模块&#xff1a; decimal模块&#xff1a; 3.内置函数&#xff1a; 总结&#xff1a; 1.位运算 位运算是对整数在内存中的二进制表示进行操作。Python支持以下常见的位运算符&#xff1a; 按位与&…

C语言王国——数据的内存管理

目录 一、引言 二、整形在内存中的存储 2.1 进制之间的转换 2.1.1 整形的二进制 2.1.2 十进制和二进制 2.1.3 十进制和八进制的转换 2.1.4 十六进制和十进制的转换 2.2 原码&#xff0c;反码&#xff0c;和补码 三、大、小端字节序 3.1 大小端的定义 3.2 为什么会有大…

pxe批量部署linux介绍

1、PXE批量部署的作用及必要性&#xff1a; 1&#xff09;智能实现操作系统的批量安装&#xff08;无人值守安装&#xff09;2&#xff09;减少管理员工作&#xff0c;提高工作效率3&#xff09;可以定制操作系统的安装流程a.标准流程定制(ks.cfg)b.自定义流程定制(ks.cfg(%pos…

LLVM Cpu0 新后端8 尾调用优化 Stack Overflow Exception异常

想好好熟悉一下llvm开发一个新后端都要干什么&#xff0c;于是参考了老师的系列文章&#xff1a; LLVM 后端实践笔记 代码在这里&#xff08;还没来得及准备&#xff0c;先用网盘暂存一下&#xff09;&#xff1a; 链接: https://pan.baidu.com/s/1V_tZkt9uvxo5bnUufhMQ_Q?…

【iOS】JSONModel源码阅读笔记

文章目录 前言一、JSONModel使用二、JSONModel其他方法转换属性名称 三、源码分析- (instancetype)initWithDictionary:(NSDictionary*)dict error:(NSError **)err[self init]__setup____inspectProperties - (BOOL)__doesDictionary:(NSDictionary*)dict matchModelWithKeyMa…

android集成百度文心一言实现对话功能,实战项目讲解,人人都能拥有一款ai应用

大家好&#xff0c;今天给大家讲解下如何实现一个基于百度文心一言的app功能&#xff0c;app内部同时集成了讯飞的语音识别。本文适用于有android基础的小伙伴阅读&#xff0c;文章末尾放上本项目用到的全部实例代码&#xff0c;在使用前请务必看完本文章。 先来给大家看看效果…

微信小程序毕业设计-医院挂号系统项目开发实战(附源码+论文)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;微信小程序毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计…

Linux 36.3 + JetPack v6.0@jetson-inference之图像分类

Linux 36.3 JetPack v6.0jetson-inference之图像分类 1. 源由2. imagenet2.1 命令选项2.2 下载模型2.3 操作示例2.3.1 单张照片2.3.2 视频 3. 代码3.1 Python3.2 C 4. 参考资料5. 补充5.1 第一次运行模型本地适应初始化5.2 samba软连接 1. 源由 从应用角度来说&#xff0c;图…

CAN协议简介

协议简介 can协议是一种用于控制网络的通信协议。它是一种基于广播的多主机总线网络协议&#xff0c;常用于工业自动化和控制领域。can协议具有高可靠性、实时性强和抗干扰能力强的特点&#xff0c;被广泛应用于汽车、机械、航空等领域。 can协议采用了先进的冲突检测和错误检测…

Application Load Balancer-ALB

Application Load Balancer-ALB 什么是ALB开通ALB服务实现IPv4服务的负载均衡创建ALB实例创建服务器组添加后端服务器配置监听设置域名解析&#xff08;可选&#xff09;释放ALB实例 什么是ALB 在介绍ALB之前首先介绍一下负载均衡SLB&#xff0c;可以说SLB是负载均衡家族之首 …