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

news2024/10/7 8:30:43

一、装饰器模式

装饰器模式(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_weight

    virtual function void print_msg();
        foreach ( scen_weight[t_scen] ) begin
            $display("scen[%s]=%0d is added", t_scen, scen_weight[t_scen]);
        end
    endfunction : print_msg

endclass : common_base


class 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] ) begin
            if ( base.scen_weight.exists(t_scen) ) begin
                `uvm_error("decorator", $psprintf("The scen(%s) has exists", t_scen))
            end else begin
                base.scen_weight[t_scen] = scen_weight[t_scen] * weight_mul;
            end
        end
        print_msg();
    endfunction : set_scen_weight

    virtual function void add();
    endfunction : add

endclass : base_decorator


class base_ldst_scen_wei extends base_decorator;

    virtual function void add();
        scen_weight["load"]  = 10;
        scen_weight["store"] = 10;
    endfunction : add

endclass : base_ldst_scen_wei


class atomic_scen_wei extends base_decorator;

    virtual function void add();
        scen_weight["atomic_add"] = 5;
        scen_weight["atomic_sub"] = 5;
    endfunction : add

endclass : atomic_scen_wei

class sve_scen_wei extends base_decorator;

    virtual function void add();
        scen_weight["gather"]  = 8;
        scen_weight["scatter"] = 8;
    endfunction : add

endclass : 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 ) begin
            common = base_ldst_scen_wei::new();
            common.set_scen_weight(base);
        end
        if ( atomic_scen ) begin
            common = atomic_scen_wei::new();
            common.weight_mul = 3;
            common.set_scen_weight(base);
        end
        if ( sve_scen ) begin
            common = sve_scen_wei::new();
            common.set_scen_weight(base);
        end
    endfunction : gen

endclass : 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.coloradmin.cn/o/1523091.html

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

相关文章

【Vue】Request模块 - axios 封装Vuex的持久化存储

📝个人主页:五敷有你 🔥系列专栏:Vue ⛺️稳中求进,晒太阳 Request模块 - axios 封装 使用axios来请求后端接口,一般会对axios进行一些配置(比如配置基础地址,请求响应拦截器…

26-Java访问者模式 ( Visitor Pattern )

Java访问者模式 摘要实现范例 访问者模式(Visitor Pattern)使用了一个访问者类,它改变了元素类的执行算法,通过这种方式,元素的执行算法可以随着访问者改变而改变访问者模式中,元素对象已接受访问者对象&a…

【零基础学习06】嵌入式linux驱动中PWM驱动基本实现

大家好,今天给大家分享一下,如何利用PWM外设来实现LCD背光调节,本次实验使用Linux系统中PWM控制器以及PWM子系统来控制对应的功能。 第一:设备树下PWM控制节点 PWM对应的节点信息如下: pwm3: pwm@02088000 {compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm…

c语言商品库存管理系统

定制魏:QTWZPW,获取更多源码等 目录 题目 功能概述 数据结构 用户界面 ​编辑 主要函数 数据存储 完整代码 总结 题目 实现一个商品库存管理系统,可以对商品进行入库、出库、删除、修改、查询以及显示所有商品信息的操作。 功能概述 系统包含以下主要功能: 商品…

JS函数知识点(复习)

在 JavaScript(JS)中使用函数有多种原因,这些原因不仅涉及到代码的组织和可读性,还涉及到代码的可维护性、复用性以及程序的模块化等方面。以下是一些关键的理由: 代码重用:函数允许你将一段代码块封装起来…

探索设计模式的魅力:探索发布-订阅模式的深度奥秘-实现高效、解耦的系统通信

​🌈 个人主页:danci_ 🔥 系列专栏:《设计模式》 💪🏻 制定明确可量化的目标,并坚持默默的做事。 探索发布-订阅模式的深度奥秘:实现高效、解耦的系统通信 文章目录 一、案例场景&am…

UE5数字孪生系列笔记(二)

智慧城市数字孪生系统 制作流云动画效果 首先添加一个图像在需要添加流云效果的位置 添加动画效果让其旋转 这个动画效果是程序开始就要进行的,所以要在EventConstruct中就可以启动这个动画效果 添加一个一样的图像在这里,效果是从此处进行放大消散 添…

python之自动化(django)

1、安装 我用的是pip install Django 在命令行中安装 然后django-admin startproject autotext(在命令行中) 这句话是创建一个django 项目 然后切换到你所创建项目的目录下 输入: python manage.py runserver 当你出现以下错误时 You…

高光谱数据应用于植被监测与分析与数据获

1. 常用高光谱数据 (1) 航空成像光谱仪系统 国内系统:MAIS、OMIS-1、OMIS-2、PHI、WHI、LASIS 国外系统:AIS、AVIRIS、TRWIS、GERIS、HYDICEAISA、DAIS、CASI、HYMAP (2) 航天成像光谱仪 Hyperion/EO-1 环境与减灾小卫星星座(HJ-1B&…

【jeecgboot】微服务实战LISM

目录 一、服务解决方案-Spring Cloud Alibaba1.1选用原因(基于Spring Cloud Alibaba的试用场景)1.2 核心组件使用前期规划 部署 nacos部署 mino使用JavaFreemarker模板引擎,根据XML模板文件生成Word文档使用JavaFlowable 工作流引擎前端 -vue…

【Flink SQL】Flink SQL 基础概念(三):SQL 动态表 连续查询

《Flink SQL 基础概念》系列,共包含以下 5 篇文章: Flink SQL 基础概念(一):SQL & Table 运行环境、基本概念及常用 APIFlink SQL 基础概念(二):数据类型Flink SQL 基础概念&am…

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

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

代码随想录算法训练营三刷day25 | 回溯 之 216.组合总和III 17.电话号码的字母组合

三刷day25 216.组合总和III剪枝 17.电话号码的字母组合 216.组合总和III 题目链接 解题思路: 选取过程如图: 图中,可以看出,只有最后取到集合(1,3)和为4 符合条件。 递归三部曲 确定递归函数参…

【C++】类和对象终章

🔥博客主页: 小羊失眠啦. 🎥系列专栏:《C语言》 《数据结构》 《C》 《Linux》 《Cpolar》 ❤️感谢大家点赞👍收藏⭐评论✍️ 文章目录 一、初始化列表1.1 初始化列表的形式1.2 初始化列表的注意事项 二、explicit关键…

【STM32定时器(一)内部时钟定时与外部时钟 TIM小总结】

STM32 TIM详解 TIM介绍定时器类型基本定时器通用定时器高级定时器常用名词时序图预分频时序计数器时序图 定时器中断配置图定时器定时 代码调试代码案例1代码案例2 TIM介绍 定时器(Timer)是微控制器中的一个重要模块,用于生成定时和延时信号…

Linux/Ubuntu/Debian从控制台启动程序隐藏终端窗口

如果你想从终端运行应用程序但隐藏终端窗口. 你可以这样做: 在后台运行: 你只需在命令末尾添加一个与号 (&) 即可在后台运行它。 例如: your_command &将 your_command 替换为你要运行的命令。 这将在后台启动该命令&#xff0c…

THM学习笔记—Simple CTF

nmap扫描,发现2222端口很奇怪啊,重新换一种方式扫描2222端口 发现是ssh 先用ftp试试,尝试匿名登录 下载所有文件 发现只有一个ForMitch.txt,告诉我们其账号密码为弱密码,我们猜测Mitch为其用户名,尝试暴力…

python 爬取人民新闻

基础信息获取: 要闻url:https://www.gov.cn/yaowen/liebiao/home.htm 下一页的url:https://www.gov.cn/yaowen/liebiao/home_1.htm 基础代码: import re import openpyxl import requests from lxml import etree import osdef …

【Java】图书管理系统,完整版+源代码!!!

1. 图书管理系统菜单 1.1 管理员菜单 查找图书新增图书删除图书显示图书退出系统 1.2普通用户菜单 查找图书借阅图书归还图书退出系统 2.基本框架的实现 首先我们要建立一个新的文件,在文件内建立三个包,分别命名为user(用户)、book(图书&#xff…

基于FPGA的图像锐化算法(USM)设计

免费获取源码请关注微信号《FPGA学习笔记册》! 1.图像锐化算法说明 图像锐化算法在实际的图像处理应用很广泛,例如:医学成像、工业检测和军事领域等;它的作用就是将模糊的图像变的更加清晰。常用的图像锐化算法有拉普拉斯算子、s…