本文从微信公众号--数字IC小站,​转载,欢迎关注,微信公众号更新更多更快

SystemVerilog中的callback(回调)​mp.weixin.qq.com

在第二次systemverilog实验中,我看到有同学用到了callback函数,今天就是简单讲讲这个方法。

1、什么是callback

callback是SystemVerilog学习者的主要困惑点之一。许多人在许多论坛上都提出了相同的问题,但答案似乎并不能尽如人意。

我们可以将数据成员传递给任何函数。现在考虑一种情况,将一个函数(例如func1)作为数据成员传递给另一个函数(例如func2),并且得到所谓的callback。之所以称为callback,是因为函数func2现在可以在其代码函数func1中的任何地方调用。

如下图所示:

这个是一个基类,其中:

  • temp是一个方法
  • 方法temp中的一些语句还调用了方法callback_1和callback_2,在这其中的两个方法都是虚方法,并不含有任何逻辑。
  • 用户可以在派生类中将所需逻辑添加到方法callback_1和callback_2,不需要更改方法temp。

例如,“randomize”是systemverilog中的一个带有callback的内建方法。randomize方法通过在randomize()前后分别调用pre_randomize()和post_randomize()去实现callback。

方法将按照下面提到的顺序执行,

  • pre_randomize();
  • randomize();
  • pre_randomize();

2、如何实现callback

实现systemverilog中callback的一种方式如下:

  • 编写一个方法,并且其中调用了其他的虚方法
  • 编写被调用的虚方法,此方法中一般不含有任何逻辑

3、如何使用callback

方法如下:

  • 派生类并且实现callback方法,重写虚方法的内容
  • 通过派生类覆盖基类

4、使用范例

class abc_transactor;
virtual task pre_send(); endtask
virtual task post_send(); endtasktask xyz();// Some code herethis.pre_send();// Some more code herethis.post_send();// And some more code here
endtask : xyz
endclass : abc_transactorclass my_abc_transactor extend abc_transactor;
virtual task pre_send();...     // This function is implemented here
endtaskvirtual task post_send();...     // This function is implemented here
endtaskendclass : my_abc_transactor

上述代码中,基类含有3个task,其中2个task声明为virtual并且没有任何逻辑,但是这2个task都被另外的task xyz()调用,而xyz()是已经有逻辑代码了的,在这其中,这2个virtual task就被称为callback class。

my_abc_transactor派生自abc_transactor类,并且实现了基类中没有添加任何逻辑的task,这样我们可以直接把需要执行的代码添加到virtual task中而不需要对其进行修改。

还是不懂?那么看个实例:

上图实现的是一个slaver driver,用来对master进行反馈。

其中包括以下组件:

  • slave_driver - Normal driver to drive response

    • 响应类型为 OKAY, EXOKAY, SLVERR, DECERR
    • slave_driver 被限制为始终发送OKAY响应以查看回调用法差异
  • slave_env -在其中创建了slave_driver的环境
  • basic_test - 发送正常响应
  • error_test - 具有回调方法的测试用例,用于生成错误响应
  • err_inject - 扩展的驱动程序类,用于实现回调方法

首先,编写slave_driver,并在其中添加空方法,放置挂钩以进行回调,在此示例中,由于需要在响应生成后立即对其进行更改,因此最好在调用randomize方法之后放置回调挂钩:

typedef enum {OKAY, EXOKAY, SLVERR, DECERR} resp_type;class slave_driver;resp_type resp;//callback hookvirtual task update_resp; endtask//send response tasktask send_response;std::randomize(resp) with { resp == OKAY;};update_resp();//hookendtask
endclass

实现callback,首先派生类,完善virtual task:

class err_inject extends slave_driver;virtual task update_resp;$display("Injecting SLVERR");resp = SLVERR;endtask
endclass

使用callback,生成error_test:

program error_test;slave_env  env;err_inject err_driver;initial begin//Create envenv = new();err_driver = new();//Overriding slave_driver by error_driverenv.slv_driver = err_driver;//Calling run of envenv.run();end
endprogram

其中slave_env如下:

class slave_env;slave_driver slv_driver;function new();slv_driver = new();endfunction//run task to call driver logictask run;repeat(2) begin //{slv_driver.send_response();$display("Slave generated response is %s",slv_driver.resp.name());end //}endtaskendclass

此外,还添加basic_test如下,以便进行比对:

program basic_test;slave_env env;initial begin//Create envenv = new();//Calling run of envenv.run();end
endprogram 

在Synopsys VCS 2019.06下进行仿真

  • 当执行basic_test时,输出如下:

当执行error_test时,输出如下:

可见,我们通过调用改变派生类中的virtual task中的内容,可以实现我们特定的内容。可以在不改变现有环境的情况下就实现错误的注入,因此好处如下:

  • 易于向现有逻辑添加其他功能
  • 使组件可重用,扩展类的功能

bmklocationmanager方法没有回调_SystemVerilog中的callback(回调)相关推荐

  1. java中接口回调_Java中的接口回调实例

    定义: /** * @author Administrator * @project: TestOne * @package: PACKAGE_NAME * @date: 2018/11/30 003 ...

  2. [转]在C#中使用API回调函数的方法

    在C#中使用API回调函数的方法 就以EnumChildWindows和EnumChildProc为例子: 首先要声明EnumChildProc 为一个回调函数 public delegate boo ...

  3. js中this和回调方法循环-我们到底能走多远系列(35)

    我们到底能走多远系列(35) 扯淡: 13年最后一个月了,你们在13年初的计划实现了吗?还来得及吗? 请加油~ 主题: 最近一直在写js,遇到了几个问题,可能初入门的时候都会遇到吧,总结下. 例子: ...

  4. alert 回调_JavaScript中到底什么时候回调函数Callback

    什么是回调函数Callback 简单的理解:回调函数是在另一个函数执行完毕后执行的函数 - 因此名称为'call back'. 复杂的理解:在JavaScript中,函数是对象.因此,函数可以将函数作 ...

  5. 安卓开发——JNI——回调java中的方法

    JNI开发中 在C代码中回调java中的方法 package com.example.jnitest2;import android.app.Activity; import android.cont ...

  6. python线程池回调函数_python回调函数中使用多线程的方法

    下面的demo是根据需求写的简单测试脚本 #!/usr/bin/env python # coding: utf-8 # 第一个列表为依赖组件和版本号,后面紧跟负责人名称 # 接着出现第二个以来组建列 ...

  7. 函数指针--Nginx和Redis中两种回调函数写法

    1.Nginx和Redis中两种回调函数写法 #include <stdio.h>//仿Nginx风格 //结构外声明函数指针类型 typedef void (*ngx_connectio ...

  8. java web自定义监听器_Android自定义监听器Listener(自定义Java Callback回调事件)

    Callback回调事件介绍 Java或Android中创建异步回调最普遍的做法就是使用listener监听器或者observer观察者模式来解决,listener回调事件通常用于实现一个代码去监听另 ...

  9. 深度解析ASP.NET2.0中的Callback机制

    callback的一般使用方法还算简单,直接参照msdn的帮助和范例就足够了.但是想要真正用好.用精,或者想开发一些基于callback机制的WEB组件,那么,就要先深入了解callback的实现机制 ...

最新文章

  1. mysql和mariadb可以同时使用吗,MariaDB与MySQL在一台服务器同时运行
  2. python bound unbound method
  3. Python中time模块详解
  4. 什么地方容易刷出ak_男人会用什么理由拒绝表白?
  5. SpringMVC教程--图片上传
  6. Form表单基础知识和常用兼容方法笔记(二)
  7. es6 Promise 的应用
  8. throw与throws
  9. 优步杭州推出顺路接单功能,不久将向全国开放!
  10. Java 延迟队列 DelayQueue 的原理
  11. 空间换时间和时间换空间
  12. xs2鸿蒙系统,华为Mate XS2来了,搭载麒麟9000,依旧安卓10版本
  13. cluster-proportional-autoscaler源码分析及如何解决KubeDNS性能瓶颈
  14. 理解常用的无理数:自然常数(e)、圆周率(π)、黄金比例(φ)
  15. 电路设计_物联网芯片资讯——GPRS
  16. 06-作业练习盒子模型
  17. 用字节数组存放二维地图数据
  18. cobbler(一) cobbler实现系统自动安装
  19. .hex 文件详解 stm32
  20. 毛桃pe系统 linux,老毛桃U盘PE重装教程

热门文章

  1. 如何判断Linux服务器是否被入侵?
  2. vim:复制复制字符到vim的命令行窗口的4种方法
  3. vbs 一些学习资料
  4. Android深度探索第五章总结
  5. [翻译] TGLStackedViewController
  6. 【语言处理与Python】4.7算法设计
  7. HDU1249_三角形切割平面
  8. ASP.NET AJAX入门系列(8):自定义异常处理
  9. 移动端点击a链接出现蓝色背景问题解决
  10. 利用Redis锁解决高并发问题