gem5中有一个 hello的例子,不是hello world那个,在src/learning-gem5/part2里面,这是虽然是个简单的例子但包含的要素挺多挺全。

整个结构是src下面有一个hello_object和goodbye_object这两个源码,前者会调用后者,同时还有有相应的python文件,这些是一一对应的。每个C++都对应一个PY文件。

PY文件可以理解对C++这个类的描述,例子中把hello_object goodbye_object两个C++写到一个PY里去了,这样也行,同样的目录下还有scons这个文件,这是编译时通过他去找哪些需要编译,里面就是把写的前面的文件加进去其实。

另外在config里面就是仿真启动,相当于是主程序的入口。也是py文件。

下面是C++配套的PY文件代码

  1. 1 from m5.params import *
  2. 2 from m5.SimObject import SimObject
  3. 3
  4. 4 class HelloObject(SimObject):
  5. 5 type = 'HelloObject'
  6. 6 cxx_header = "learning_gem5/part2/hello_object.hh"
  7. 7 cxx_class = 'gem5::HelloObject'
  8. 8
  9. 9 time_to_wait = Param.Latency("Time before firing the event")
  10. 10 number_of_fires = Param.Int(1, "Number of times to fire the event before "
  11. 11 "goodbye")
  12. 12
  13. 13 goodbye_object = Param.GoodbyeObject("A goodbye object")
  14. 14
  15. 15 class GoodbyeObject(SimObject):
  16. 16 type = 'GoodbyeObject'
  17. 17 cxx_header = "learning_gem5/part2/goodbye_object.hh"
  18. 18 cxx_class = 'gem5::GoodbyeObject'
  19. 19
  20. 20 buffer_size = Param.MemorySize('1kB',
  21. 21 "Size of buffer to fill with goodbye")
  22. 22 write_bandwidth = Param.MemoryBandwidth('100MB/s', "Bandwidth to fill "
  23. 23 "the buffer")

来理解一下这些代码,gem5有很多现有的类我们会用到, gem5所有的类都要继承自simobject这是固定的,而每个simobject都有一个params 的参数,所以开始把params和simobject导入进来。

然后是声明hello的类,继承simobject,里面是类的说明,名字,路径之类的,然后是参数第9行开始,左边是C++中的参数名字右边是他的类型,这些类型是来自第一行导入的params这些文件中已经定义好的了,比如去把parama找到打开能找到对于Latency的定义。

13行是我们要调用的子类,大型设计会有很多小类,最后在顶层把它们整合起来,这里的HELLO相当于顶层,GOODBYE相当于子功能模块,我们要把他加到主模块里来。

后面是对GOODBYE这个类的描述都差不多。

然后再理解下C++文件,

  1. 1 HelloObject::HelloObject(const HelloObjectParams &params) :
  2. 2 SimObject(params),
  3. 3 // This is a C++ lambda. When the event is triggered, it will call the
  4. 4 // processEvent() function. (this must be captured)
  5. 5 event([this]{ processEvent(); }, name() + ".event"),
  6. 6 goodbye(params.goodbye_object),
  7. 7 // Note: This is not needed as you can *always* reference this->name()
  8. 8 myName(params.name),
  9. 9 latency(params.time_to_wait),
  10. 10 timesLeft(params.number_of_fires)
  11. 11 {
  12. 12 DPRINTF(HelloExample, "Created the hello object\n");
  13. 13 panic_if(!goodbye, "HelloObject must have a non-null GoodbyeObject");
  14. 14 }

这个是HELLO的构造函数,他有一个params的参数需要传进来,来源于上面的文字有说过,然后传给simobject,5行是事件的加入,这个是GEM5的机制,因为我们要模拟数字电路的工作方式,这里相当于是把要做的事加到event里面,然后拿去在某个时间执行一次,再间隔时间再执行一次这样就相当于时钟一样, 后面是GOODBYE的传参,MYname后面直接用了name这个变量,但是没有声明或者传递啥的,研究了下,是因为前面有个name()这个函数是返回例化名字的,前面用了这个函数会返回一个name变量,所以后面可以直接用,如果前面也直接用name的话就会报错。再后面是参数传递,花括号里面是构造函数要做的事情。

  1. 1 void
  2. 2 HelloObject::startup()
  3. 3 {
  4. 5 // Before simulation starts, we need to schedule the event
  5. 6 schedule(event, latency);
  6. 7 }
  7. 8
  8. 9 void
  9. 10 HelloObject::processEvent()
  10. 11 {
  11. 13 timesLeft--;
  12. 14 DPRINTF(HelloExample, "Hello world! Processing the event! %d left\n",
  13. 15 timesLeft);
  14. 16
  15. 17 if (timesLeft <= 0) {
  16. 18 DPRINTF(HelloExample, "Done firing!\n");
  17. 19 goodbye->sayGoodbye(myName);
  18. 20 } else {
  19. 21 schedule(event, curTick() + latency);
  20. 22 }
  21. 23 }

上面第一个函数是startup可以看到没有其他哪里在调用它,这好像也是gem5本身的在开始仿真前会自动调用的一个函数,暂时不研究怎么调的了,里面的内容是一个安排事件的函数,这个函数也是gem5里面的实现时钟模拟的函数,之前event是把事件封起来,这里就是真正决定他好久执行了,第二个参数就是等这么久之后就执行event,而event里面又包了我们的普通函数process,这样整个类就运行起来了。

每二个函数就是普通的函数,他被封在了event里面,同时里面也有调用子类GOODBYE的功能,也有再次安排事件的调用。这样就可以实现时钟工作模式。

下面是config/learning/part2里面的。

  1. 1 # set up the root SimObject and start the simulation
  2. 2 root = Root(full_system = False)
  3. 3
  4. 4 # Create an instantiation of the simobject you created
  5. 5 root.hello = HelloObject(time_to_wait = '2us', number_of_fires = 5)
  6. 6 root.hello.goodbye_object = GoodbyeObject(buffer_size='100B')
  7. 7
  8. 8 # instantiate all of the objects we've created above
  9. 9 m5.instantiate()
  10. 10
  11. 11 print("Beginning simulation!")
  12. 12 exit_event = m5.simulate()
  13. 13 print('Exiting @ tick %i because %s' % (m5.curTick(), exit_event.getCause()))

这其实就是主程序的入口相当于,第2行是格式要求吧理解为,每个仿真都有个最顶层的类就是root,后面参数是表示是不是全系统模拟,我们这当然不是。第5行是在root下再例化一个之前我们写的类,并把我们想要的参数传进去。这样程序就真正的完整了,可以用了,第9行是初始化上面的东西,再后面就是开始跑起来了,都是较固定。不再细说。

gem5 使用记录,对例子中helloobject的理解的更多相关文章

  1. [Spark][Python]DataFrame中取出有限个记录的例子

    [Spark][Python]DataFrame中取出有限个记录的例子: sqlContext = HiveContext(sc) peopleDF = sqlContext.read.json(&q ...

  2. 记录Python学习中的几个小问题

    记录Python学习中的几个小问题,和C#\JAVA的习惯都不太一样. 1.Django模板中比较两个值是否相等 错误的做法 <option value="{{group.id}}&q ...

  3. 也用 Log4Net 之将自定义属性记录到文件中 (三)

    也用 Log4Net  之将自定义属性记录到文件中 (三)  即解决了将自定义属性记录到数据库之后.一个新的想法冒了出来,自定义属性同样也能记录到文件中吗?答案是肯定的,因为Log4Net既然已经考虑 ...

  4. 记录下项目中常用到的JavaScript/JQuery代码二(大量实例)

    记录下项目中常用到的JavaScript/JQuery代码一(大量实例) 1.input输入框监听变化 <input type="text" style="widt ...

  5. (4.7)怎么捕获和记录SQL Server中发生的死锁?

    转自:https://blog.csdn.net/c_enhui/article/details/19498327 怎么捕获和记录SQL Server中发生的死锁? 关键词:死锁记录,死锁捕获 sql ...

  6. 微信小程序开发入门教程(二)---分析官方云开发例子中的一些功能

    接上一篇文章:https://www.cnblogs.com/pu369/p/11326538.html 1.官方云开发的例子中,点击获取 openid,对应代码在E:\wxDEV\helloyun\ ...

  7. Log4Net 之将自定义属性记录到文件中 (三)

    原文:Log4Net 之将自定义属性记录到文件中 (三) 即解决了将自定义属性记录到数据库之后.一个新的想法冒了出来,自定义属性同样也能记录到文件中吗?答案是肯定的,因为Log4Net既然已经考虑到了 ...

  8. 怎么启用apache的mod_log_sql模块将所有的访问信息直接记录在mysql中

    怎么启用apache的mod_log_sql模块将所有的访问信息直接记录在mysql中

  9. 记录对依赖注入的小小理解和autofac的简单封装

    首先,我不是一个开发者,只是业余学习者.其次我的文化水平很低,写这个主要是记录一下当前对于这块的理解,因为对于一个低水平 的业余学习者来说,忘记是很平常的事,因为接触.应用的少,现在理解,可能过段时间 ...

随机推荐

  1. 期末人福音——用Python写个自动批改作业系统

    一.亮出效果 最近一些软件的搜题.智能批改类的功能要下线. 退1024步讲,要不要自己做一个自动批改的功能啊?万一哪天孩子要用呢! 昨晚我做了一个梦,梦见我实现了这个功能,如下图所示:功能简介:作对了 ...

  2. Redis主从复制+Keepalived+VIP漂移实现HA高可用技术之详细教程

    1.大家可以先看我的单台Redis安装教程,链接在此点击Redis在CentOS for LInux上安装详细教程 2.第一台redis配置,是正常配置.作为MASTER主服务器,第二台redis的配 ...

  3. Android高仿网易云音乐-启动界面实现和动态权限处理

    效果 实现分析 基本上没有什么难点,就是布局,然后显示用户协议对话框,动态处理权限,判断是否显示引导界面,是否显示广告界面等. 布局 <?xml version="1.0" ...

  4. 数据结构-二叉树(Binary Tree)

    1.二叉树(Binary Tree) 是n(n>=0)个结点的有限集合,该集合或者为空集(空二叉树),或者由一个根节点和两棵互不相交的,分别称为根节点的左子树和右子树的二叉树组成.  2.特数二 ...

  5. get前言之版本控制-get和SVN的区别

    版本控制什么是版本控制版本控制(Revision control)是一种在开发的过程中用于管理我们对文件.目录或工程等内容的修改历史,方便查看更改历史记录,备份以便恢复以前的版本的软件工程技术. ~实 ...

  6. 关于C标准库stdarg.h

    看<数据结构(C语言版)>(严蔚敏)时看到p94上面va_list啥的,看不懂了,于是整理一下这一部分的知识. 1/当无法列出传递函数的所有实参的类型和数目时,可以用省略号指定参数表. i ...

  7. 渗透测试(PenTest)基础指南

    什么是渗透测试? 渗透测试(Penetration Test,简称为 PenTest),是指通过尝试利用漏洞攻击来评估IT基础设施的安全性.这些漏洞可能存在于操作系统.服务和应用程序的缺陷.不当配置或 ...

  8. MySQL--用通配符进行过滤(LIKE操作符)

    1.LIKE操作符 怎样搜索产品名中包含文本anvil的所有产品?用简单的比较操作符肯定不行,必须使用通配符.利用通配符可创建比较特定数据的搜索模式.在这个例子中,如果你想找出名称包含anvil的所有 ...

  9. grafana监控配置

    一.配置开启smtp服务 1.编辑grafana配置文件grafana.ini [smtp] enabled = true host = smtp.163.com:25 user = 157xxxx3 ...

  10. 《Python编程:从入门到实践》第十八章笔记:Django最基本用法笔记

    最近在看Python编程:从入门到实践,这是这本书"项目3 Web应用程序"第18章的笔记.记录了django最基本的一些日常用法,以便自己查阅. 可能是我的这本书版本比较老,书上 ...