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

一、装饰器模式

装饰器模式(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.kler.cn/a/274121.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙开发入门教程—瀑布流的实战案例

给大家分享一下瀑布流的实战案例,和官方文档略有不同,本文数据直接从api接口获取,更接近实战。需要注意的是,要实现瀑布流,接口最好将图片尺寸一起返回。 本文效果图: 首先要实现IDataSource接口的对象&am…

c语言(数据在内存中的存储)

1. 整数在内存中的存储 整数的2进制表⽰⽅法有三种,即原码、反码和补码 三种表⽰⽅法均有符号位和数值位两部分,符号位都是⽤0表⽰“正”,⽤1表⽰“负”,⽽数值位最 ⾼位的⼀位是被当做符号位,剩余的都是数值位。 正整…

EI期刊复现:面向配电网韧性提升的移动储能预布局与动态调度策略程序代码!

适用平台:MatlabYalmipCplex/Gurobi/Mosek 程序提出一种多源协同的两阶段配电网韧性提升策略。在灾前考虑光伏出力不确定性与网络重构,以移动储能配置成本与负荷削减风险成本最小为目标对储能的配置数量与位置进行预布局;在灾后通过多源协同…

Javascript抓取京东、淘宝商品数据(商品采集商品详情图片抓取)

之前用的方法: let temp []var lists $(#J_goodsList li.gl-item)$.each(lists,function(idx,item){ temp.push({ id:$(item).data(sku), goods_img:$(item).find(img).attr(src), goods_name:$(item).find(.p-name em).text(), market_price:$(item).fi…

AI检测识别技术,为智能化视频生产赋能

在科技飞速发展的今天,智能化生产已经成为企业提高效率、降低成本、增强竞争力的关键所在。美摄科技,作为一家在音视频处理技术领域保持领先的创新型企业,不仅致力于提供卓越的音视频处理技术,更在AI检测识别领域积累了深厚的实力…

数据分析-Pandas序列滑动窗口配置参数

数据分析-Pandas序列滑动窗口配置参数 数据分析和处理中,难免会遇到各种数据,那么数据呈现怎样的规律呢?不管金融数据,风控数据,营销数据等等,莫不如此。如何通过图示展示数据的规律? 数据表&…

Flutter Widget:StatefulWidget StatelessWidget

Widget 概念 Widget 将是构建Flutter应用的基石,在Flutter开发中几乎所有的对象都是一个 Widget 。 在Flutter中的widget 不仅表示UI元素,也表示一些功能性的组件,如:手势 、主题Theme 等。而原生开发中的控件通常只是指UI元素。…

C++作业day6

编程1: 封装一个动物的基类,类中有私有成员:姓名,颜色,指针成员年纪 再封装一个狗这样类,共有继承于动物类,自己拓展的私有成员有:指针成员:腿的个数(整型 …

nodeJs 学习

常用快捷键 二、fs模块 回调函数为空,则表示写入成功! 练习 const fs require(fs); fs.readFile(../files/成绩.txt, utf-8, (err, dataStr) > {if (err) {console.log(读取失败);return err;}console.log(读取成功);const arr dataStr.split( )co…

C++_day6:2024/3/18

作业1:编程题: 以下是一个简单的比喻,将多态概念与生活中的实际情况相联系: 比喻:动物园的讲解员和动物表演 想象一下你去了一家动物园,看到了许多不同种类的动物,如狮子、大象、猴子等。现在…

一般做策划的的,上哪儿找策划方案借鉴?

许多策划人担忧,借鉴他人的经验和方案会会削弱自己的创新能力和独立思考。 但是,实际上,借鉴他人的经验和方案可以为自己提供更多的灵感和创意,同时也可以提高策划的成功率。 这里推荐策划人必备的宝藏网站(专治不会…

Echarts横向柱形图

项目原型图如下: 实际上就是设置两个y轴,第一个显示底色柱子,另一个只显示真实数据的柱子,在这里只显示y轴,x轴不显示.. this.middleLeftOption {tooltip: {trigger: axis,axisPointer: {}},legend: {data: [回退次数],y: bottom},grid: {left: 3%,righ…

微信小程序注册流程

1. 微信小程序注册流程 1.1. 材料 新开通小程序则需要提供未注册过微信、从未绑定过微信公众号的邮箱号;法人的微信号(必须已绑定银行卡);法人的身份证号码、身份证正反面照片;管理员手机号和微信绑定的;公…

Docker基本配置及使用

Docker基本配置及使用 使用步骤 1.卸载旧版 代码如下:首先如果系统中已经存在旧的Docker,则先卸载 yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engin…

嵌入式DSP教学实验箱操作教程:2-20 数模转换实验(模拟SPI总线输出电压值)

一、实验目的 掌握GPIO模拟SPI总线的使用,了解AD5724的芯片特性和使用,并实现基于AD5724输出电压值。 二、实验原理 StarterWare StarterWare是一个免费的软件开发包,它包含了示例应用程序。StarterWare提供了一套完整的GPIO寄存器配置接…

数据库系统概论-练手题集合【期末复习|考研复习】

前言 总结整理不易,希望大家点赞收藏。 给大家整理了一下数据库系统概论中的练手题,以供大家期末复习和考研复习的时候使用。 数据库系统概论系列文章传送门: 第一章 绪论 第二/三章 关系数据库和标准语言SQL 第四/五章 数据库安全性和完整性…

蓝桥杯之冲刺

文章目录 动态规划01背包小练一下 网格图上的DP 动态规划 01背包 由于不能拆开,那就是DP 问题,如果能拆开,那就是贪心问题 小练一下 import os import sys# 请在此输入您的代码N,V map(int,input().split())w [] v [] w.append(0) v.appen…

数据结构(三)复杂度的深层次剖析

之前发布了数据结构(一),很多同学反响不够清晰,那今天就发一篇对复杂度专题的博客,希望对大家理解复杂度提供一些帮助。 时间复杂度 我们先来一个理解一个复杂度,二分查找的复杂度(之前写过二…

基于tcp协议的网络通信(基础echo版.多进程版,多线程版,线程池版),telnet命令

目录 基础版 思路 辅助函数 服务端 代码 运行情况 -- telnet ip 端口号 传输的数据为什么没有转换格式 客户端 思路 代码 多进程版 引入 问题 解决 注意点 服务端 代码 运行情况 进程池版(简单介绍) 多线程版 引入 问题解决 注意点 服务端 代码 …

携程Kar98k/hotelUuidKey算法分析

声明 本文以教学为基准、本文提供的可操作性不得用于任何商业用途和违法违规场景。 本人对任何原因在使用本人中提供的代码和策略时可能对用户自己或他人造成的任何形式的损失和伤害不承担责任。 如有侵权,请联系我进行删除。 这里只是我分析的分析过程,以及一些重要点的记录…
最新文章