设计模式在芯片验证中的应用——装饰器

一、装饰器模式

装饰器模式(Decorator)是一种结构化软件设计模式,它提供了一种通过向类对象添加行为来修改类对象的方法,而不会影响同一类的其它对象行为。该模式允许在不修改抽象类的情况下添加类功能。它从本质上允许基类代码对不可预见的修改具有前瞻性。

对于经常需要在最后时刻新增特性的验证工作,装饰器模式的这个特性非常强大。该模式适用于通过向复杂数据项应用额外的约束集来对它们进行建模,或者在原先数据上添加额外数据。与类继承相比,它的主要优点是可以实现向类对象中动态添加或删减行为。在工程中,该技术被广泛用于实现受约束随机激励的生成。

举个例子,如下图,我们在验证环境中打算开发一个Arm指令生成器,原先RTL只支持基本的load和store指令,过段时间可能又支持atomic指令,再过段时间可能又支持SVE指令了,这样就容易造成我们需要对以往的代码不停地修改。更令人崩溃的是,RTL又搞了其它版本,有的版本只支持load/store指令和SVE指令,有的版本只支持atomic和SVE指令,等等。对于这些行为,第一个跳入脑海的想法可能就是扩展它所属的类,在新的类中添加新功能,但这种方式会使代码量迅速膨胀,而且可能会破坏之前写好的代码。

针对以上情况,我们可以考虑使用装饰器模式。要构建装饰器设计模式,需要定义几个主要部分:

  • 被包装对象:它声明了被包装对象的共用接口和基本行为,装饰器会在此基础上添加新的行为。
  • 抽象装饰器:定义了基本的装饰器,它拥有一个指向被被包装对象的引用成员变量,因此会将操作委派给被包装的对象。
  • 具体装饰器:定义了可动态增减到被包装对象的额外行为。具体装饰器会重写装饰基类的方法,并在调用父类方法之前或之后进行额外的行为。

下图使用UML类图提供了上述三者之间的图形化关系:

装饰器设计模式背后的主要思想是,各种具体装饰器可以在仿真过程中处于活动状态,灵活地为被包装对象增加新功能。而且可以指令任意组合的具体装饰器同时处于活动状态,这样就可以在任意给定时刻,向被包装的对象添加任何期望的激励组合。

二、参考代码

指令生成器的装饰器模式参考代码如下:

class common_base;int pe;int scen_weight[string];int weight_mul = 1;virtual function void set_scen_weight(common_base _h);endfunction : set_scen_weightvirtual function void print_msg();foreach ( scen_weight[t_scen] ) begin$display("scen[%s]=%0d is added", t_scen, scen_weight[t_scen]);endendfunction : print_msgendclass : common_baseclass base_decorator extends common_base;common_base  base;virtual function void set_scen_weight(common_base _h);add();base = _h;foreach ( scen_weight[t_scen] ) beginif ( base.scen_weight.exists(t_scen) ) begin`uvm_error("decorator", $psprintf("The scen(%s) has exists", t_scen))end else beginbase.scen_weight[t_scen] = scen_weight[t_scen] * weight_mul;endendprint_msg();endfunction : set_scen_weightvirtual function void add();endfunction : addendclass : base_decoratorclass base_ldst_scen_wei extends base_decorator;virtual function void add();scen_weight["load"]  = 10;scen_weight["store"] = 10;endfunction : addendclass : base_ldst_scen_weiclass atomic_scen_wei extends base_decorator;virtual function void add();scen_weight["atomic_add"] = 5;scen_weight["atomic_sub"] = 5;endfunction : addendclass : atomic_scen_weiclass sve_scen_wei extends base_decorator;virtual function void add();scen_weight["gather"]  = 8;scen_weight["scatter"] = 8;endfunction : addendclass : sve_scen_wei

模拟测试代码如下:

class scen_weight_gen;rand bit base_ldst_scen;rand bit atomic_scen;rand bit sve_scen;function void gen();common_base base = new();common_base common;`uvm_info("", $psprintf("base_ldst_scen:%b, atomic_scen:%b, sve_scen:%b", base_ldst_scen, atomic_scen, sve_scen), UVM_LOW)if ( base_ldst_scen ) begincommon = base_ldst_scen_wei::new();common.set_scen_weight(base);endif ( atomic_scen ) begincommon = atomic_scen_wei::new();common.weight_mul = 3;common.set_scen_weight(base);endif ( sve_scen ) begincommon = sve_scen_wei::new();common.set_scen_weight(base);endendfunction : genendclass : scen_weight_gen

输出仿真日志如下:

base_ldst_scen:1, atomic_scen:1, sve_scen:0| # scen[load]=10 is added| # scen[store]=10 is added| # scen[atomic_add]=5 is added| # scen[atomic_sub]=5 is added

从仿真结果可以看出,scen_weight_gen类随机后,base_ldst_scen为1,atomic_scen为1,sve_scen为0,因此只有load/store指令和atomic指令功能被添加到指令生成器中。

好了,今天就写到这里了。下次给大家分享下设计模式中策略模式(Strategy)在芯片验证中的应用。它和装饰器模式很类似,区别是装饰器模式可让你更改对象的外表,但策略模式则让你能够更改其本质。

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

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

相关文章

SQLiteC/C++接口详细介绍之sqlite3类(十二)

返回目录:SQLite—免费开源数据库系列文章目录 上一篇:SQLiteC/C接口详细介绍之sqlite3类(十一) 下一篇:SQLiteC/C接口详细介绍之sqlite3类(十三) ​37.sqlite3_load_extension 用于在SQLit…

硅电容的工作原理,结构特点,工艺流程,选型参数及设计注意事项总结

🏡《总目录》 目录 1,概述2,工作原理3,结构特点3.1,集成度高3.2,制造工艺成熟3.3,稳定性好3.4,高可靠性4,工艺流程4.1,材料准备4.2,硅片处理4.3,电容结构制作4.4,电极制作4.5,封装与测试<

Iframe 嵌入: 页面嵌入并保持自适应页面的宽高并铺满整个屏幕

文章目录 问题分析1. 嵌入 Iframe2. 样式3. 源码 问题 当我们使用 Iframe 嵌入页面后&#xff0c;会看到它只在小小的一部分进行展示&#xff0c;如何让它铺满整个屏幕 分析 1. 嵌入 Iframe <template><div><iframe :src"embeddedPageUrl" width…

R语言中的常用基础绘图函数 直方图,箱线图,条形图,散点图

目录 R语言中的绘图参数 绘图函数 1.plot函数绘制散点图 2.hist函数绘制直方图 如何修饰直方图? 如何在直方图上标注各组频数&#xff1f; 使用text函数把某些信息标注在直方图上 如何在直方图上添加概率密度曲线&#xff1f; 3.boxplot函数绘制箱线图 4.barplot函数…

【强化学习笔记一】初识强化学习(定义、应用、分类、性能指标、小车上山案例及代码)

文章目录 第1章 初识强化学习1.1 强化学习及其关键元素1.2 强化学习的应用1.3 强化学习的分类1.3.1 按任务分类1.3.2 按算法分类 1.4 强化学习算法的性能指标1.5 案例&#xff1a;基于Gym库的智能体/环境接口1.5.1 安装Gym库1.5.2 使用Gym库1.5.3 小车上山1.5.3.1 有限动作空间…

灯塔:CSS笔记(4)

伪类选择器&#xff1a; 1.作用与优势&#xff1a; 1.作用&#xff1a;根据元素在HTML中的结构关系查找元素 2.优势&#xff1a;减少对于HTML中类的依赖&#xff0c;有利于保持代码的整洁 3.场景&#xff1a;常用于查找某父级选择器中的子元素 2.选择器 选择器说明E:first-c…

蓝桥杯2023年省A(一波三折的)【买瓜】折半搜索+剪枝+排序

题目&#xff1a;洛谷 P9234 [蓝桥杯 2023 省 A] 买瓜 折半搜索 一开始觉得像dp&#xff0c;试着写了&#xff0c;显然过不了&#xff0c;但我实在觉得搜索也过不了啊&#xff0c;去看题解&#xff0c;发现使用了折半搜索&#xff08;每天都觉得啥都不会捏 折半搜索就是先搜一…

wayland(xdg_wm_base) + egl + opengles 渲染使用纹理贴图的旋转 3D 立方体实例(十三)

文章目录 前言一、使用 stb_image 库加载纹理图片1. 获取 stb_image.h 头文件2. 使用 stb_image.h 中的相关接口加载纹理图片3. 纹理图片——cordeBouee4.jpg二、渲染使用纹理贴图的旋转 3D 立方体1. egl_wayland_texture_cube.c2. Matrix.h 和 Matrix.c3. xdg-shell-client-pr…

日期与时间(Java)

文章目录 日期与时间&#xff08;Java&#xff09;一、JDK8之前的1.1 Date1.2 SimpleDateFormat1.3 Calendar 二、 JDK8之后的2.1 LocalDate、LocalTime和LocalDateTime2.2 ZoneId和ZonedDateTime2.3 Instant2.4 DateTimeFormatter2.4 Period和 Duration &#x1f389;写在最后…

Java项目利用Redisson实现真正生产可用高并发秒杀功能 支持分布式高并发秒杀

Java中的高并发秒杀场景下我们可以使用redisson来实现高并发秒杀功能, 以下就是一个可用于生产环境的高并发秒杀示例代码: pom依赖 <!-- https://mavenlibs.com/maven/dependency/org.redisson/redisson --><dependency><groupId>org.redisson</groupId&…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:Web)下篇

onRequestSelected onRequestSelected(callback: () > void) 当Web组件获得焦点时触发该回调。 示例&#xff1a; // xxx.ets import web_webview from ohos.web.webviewEntry Component struct WebComponent {controller: web_webview.WebviewController new web_webv…

Github Copilot 工具,无需账号,一键激活

① 无需账号&#xff0c;100%认证成功&#xff01;0风险&#xff0c;可联网可更新&#xff0c;&#xff0c;支持copilot版本升级&#xff0c;支持chat ② 支持windows、mac、linux系统等设备 ③一号通用&#xff0c;支持所有IDE(AppCode,CLion,DataGrip,GoLand,IntelliJ IDEA …

线程的 run()和 start()有什么区别?调用start()方法时,线程状态的变化是怎么样的?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 线程的 run()和 start()有什么区别 run()方法 run()方法是Thread类中的一个普通方法,用来定义线程的执行逻辑。当一个类继承自Thread类并且重写了run()方法…

LeetCode题练习与总结:解数独

一、题目 编写一个程序&#xff0c;通过填充空格来解决数独问题。 数独的解法需 遵循如下规则&#xff1a; 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。&#xff08;请参考示例图&#xff09; …

Linux 基础-查看和设置环境变量

一&#xff0c;查看环境变量 在 Linux中&#xff0c;环境变量是一个很重要的概念。环境变量可以由系统、用户、Shell 以及其他程序来设定&#xff0c;其是保存在变量 PATH 中。环境变量是一个可以被赋值的字符串&#xff0c;赋值范围包括数字、文本、文件名、设备以及其他类型…

前端跨平台开发框架:简化多端开发的利器

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

OpenCV系列文章目录(持续更新中......)

引言&#xff1a; OpenCV是一个开源的计算机视觉库&#xff0c;由英特尔公司开发并开源的一组跨平台的C函数和少量的C函数组成&#xff0c;用于实时图像处理、计算机视觉和机器学习等应用领域。OpenCV可以在包括Windows、Linux、macOS等各种操作系统平台上使用&#xff0c;具…

数据结构--七大排序算法(更新ing)

下面算法编写的均是按照由小到大排序版本 选择排序 思想&#xff1a; 每次遍历待排序元素的最大下标&#xff0c;与待排序元素中最后一个元素交换位置&#xff08;此时需要设置一个临时变量来存放下标&#xff09; 时间复杂度--O(n^2) 空间复杂度--O(1) 稳定性--不稳定 代码实…

解析服务器下载速度:上行、下行与带宽之谜

在日常使用中&#xff0c;我们经常会遇到从服务器下载内容速度忽快忽慢的情况&#xff0c;即便服务器的硬件配置如4核CPU、8GB内存和12Mbps的带宽看似足够。为何会出现这种现象&#xff1f;这背后涉及到网络中的上行、下行以及带宽等关键概念。本文旨在揭开这些术语背后的含义&…

用Origin快速拟合荧光寿命、PL Decay (TRPL)数据分析处理

需要准备材料&#xff1a;Origin、PL Decay数据txt文件 首先打开Origin画图软件 导入数据&#xff0c;按照下图箭头操作直接导入 双击你要导入的PL Decay的txt数据文件&#xff0c;然后点OK 继续点OK 数据导入后首先删除最大光子数之前的无效数据&#xff0c;分析的时候用…