长期以来,在设计芯片时常常碰着这样的困惑,采取传统流程设计某种类型的芯片时周期很长,某些模块的特点至少等到进行FPGA验证阶段才能剖析其性能,如果不得当,还须要推翻原来的架构重新设计,给设计流程和设计繁芜度带来很大的困扰。为了在芯片真正开始写代码设计之前就把上述问题办理掉,芯片仿照器的思想应运而生了。
gem5与打算机架构仿真器

GEM5是一款模块化的离散事宜驱动全部系仿照器,它结合了M5(多处理器仿照器)和GEMS(存储层次仿照器)中最精良的部分,是一款高度可配置、集成多种ISA和多种CPU模型的体系构造仿照器。GEM5已经能够支持多种商用ISA,包括X86、ARM、ALPHA、MIPS、Power、SPARC等,并且能够在X86、ARM、ALPHA上加载LINUX操作系统。是一种名副实在的全部系打算机架构仿真工具。

笔者所在课题组也曾经研究过一段韶光gem5,在上面跑起来了linux操作系统。只是速率比真实芯片上跑起来的有点慢而已。 网上有很多干系的学习条记,比如:一个从刚入大学就励志做CPU设计到毕业后如愿以偿的故事!
让我们看一下gem5先容框图。
事实上,打算机架构仿真器有很多种,有些不是完全的系统仿真器。全部系仿真器包括 Simics, Simflex, GEM5, Bochs, MARSSX86, PTLsim。 (QEMU, GEMS以及其它项目)。个中最具代表性的有Simflex, GEM5, Bochs, MARSSX86等。
更加全面系统先容打算机架构仿真器的页面请访问:
http://pages.cs.wisc.edu/~arch/www/tools.html。
这里有各种仿真器官网的链接及相应的工具下载链接。可惜很少看到有中国人开拓的仿真器。
Tensilica公司与ASIP
个人认为,Tensilica公司是一家真正将打算机架构仿真器商用化的公司。或许很多同学没有听说过这个公司。实在,这家公司紧张做定制指令集处理器(ASIP)的一家公司。ASIP的理念是:专业的事情该当由专业的指令集来完成!
举个例子,通用ARM处理器功能险些无所不能,可以播放视频,可以处理网络数据包等业务,但什么都能做的反面就意味着可能什么都做的不是最好的!
Tensilica的思路是,剖析通用途理器在实行某些详细任务如播放视频的指令实行情形,从个中选出最常常被用到的几十条或者几百条通用指令集的组合,将这些最常常被用到的指令集组合实现的功能采取专门的一条新指令来更换掉!
当然,这条新的指令就意味着处理器本身必须在硬件上去支持这一条指令去完成的所有功能。有了新的指令,当然处理器在进行视频播放时效率就会有非常显著的提升。这个新的被优化过的指令集便是播放视频而定制的专用指令集,这便是ASIP的思想。
在这个理念下,DSP便是一种被优化了数值打算功能的ASIP,GPU也是一种被优化了视频或图像处理的ASIP,而寒武纪的AI处理器也是一种被优化了机器学习功能的ASIP,而所有的网络处理器也是被优化了网络数据包处理功能的ASIP......
笔者曾在研究生阶段申请了Tensilica公司大学操持的LICENSE,也曾考试测验过在这个新的架构仿真器平台下对JPEG等编解码功能的指令集优化,据先容,可以在这个平台下一个小时之内就能定制一款ASIP的处理器。并且,在新的指令集下可以直接运行嵌入式的各种操作系统,综合验证软硬件是否能协同事情。这种理念在十几年前曾引起了不小的轰动,被认为是一种能击倒ARM处理器的一种前辈的SoC设计理念,可惜,当时的Xtensa等处理器由于价格昂贵等成分,没有能迅速的推广开。以至于到2013年的时候,被Cadence公司以3.8亿美金收购。
有人认为,被收购的缘故原由是大势所趋。由于一组数据的比拟,大约2003年,网络电信专用设备硬件和软件的投资比80:20的样子,而2008年基本就已经逆转成20:80的样子。添加指令,是捐躯软件的兼容性来增加硬件性能。因此当软硬件投资比例发生逆转的时候,过去的一些好技能,就不再有市场。这阐明了intel干倒了一堆高性能的CPU,也阐明了ARM的崛起,也阐明了Tesillica不能独立运营,只能被收购。
还有人认为被收购的缘故原由是太过于对工具的依赖。针对某一类运用设计一套指令集,相对应的是一种处理器体系构造。但是要想真正从某一类运用出发设计出一个处理器,那困难大了去了,你先得抽象出一样平常共性的指令集,然后选择得当的体系构造,根据指令集去调度优化这个构造,末了指令集和体系构造逐步收敛。期间还要考虑一整套处理器工具链的设计和实现。就像海内龙芯和最近呼声很高的RISCV处理器一样,末了创造,最主要的不是芯片的设计,而是针对芯片的编译器的设计。从事CPU芯片设计的同学们都知道那本经典的《打算机体系架构:量化剖析方法》书本,此书可以说是打算机界的奇书,没有之一,三十年来出了四版。两位作者都是大仙,一个是斯坦福大学校长,另一个是是RISC的发明人,看这本书,让人清楚的感想熏染到处理器设计的门槛之高,涉及技能领域之广。而Tensilica公司的Xtensa处理器涌现后,一下子把处理器的设计门槛降落了!
你可以针对你的目标运用,对这个处理器原型进行修修补补,尤其是他们供应了一个强大的软件工具,你只须要用一种高等措辞描述你的处理器,就会自动产生处理器干系的工具链和终极的RTL代码/网表。全体过程比重新开始一个新指令集/体系构造要随意马虎的多。也有人认为这里面蕴含着一种设计哲学:要想从用户需求侧设计一种繁芜的系统,相对大略的思路是选择一种熟习的、通用的系统原型,进行修修补补,迭代收敛完成终极的设计。
有关Tensilica的更详细的技能细节,可以参考chris rowen博士的《繁芜SoC设计》一书。
离散事宜模型
言归正传。接下来先容一种上面牛叉的各种芯片仿照器平台的原始设计思想:离散事宜模型!
几年前,由于笔者所在的团队常做各种定制的网络与交流的FPGA和芯片,以是就想着,是否能够像设计CPU那样开拓出一套网络与交流专用的仿照器。当然,网络剖析的仿照器也有很多常用的工具,比如OPNET、NS3等工具,但这些太偏系统,无法仿照出一款专用的交流芯片内部模块的功能,最主要的是,这是别人做的工具,用起来实在不顺手。大学的义务便是做研究,研究这些仿照器的核心思想到底是什么,我们能否开拓出自己的芯片仿照器?这才是我们作为一个高校科研事情者的义务和担当。于是才有了上面那些资料的查找和理解过程。
我们的目标是,通过仿照器可以对各种交流功能进行裁剪和定制,知足各种接口个数和接口速率(从百兆千兆万兆到25G、40G到100G和400G)的需求,并且,通过仿照器还可以判断逻辑资源和存储资源的需求,从而确定FPGA的选型,还可以给出数据包的时延、抖动以及在各种网络数据源模型下的性能剖析......
硬件上实现一个繁芜的交流单元的设计方案,所须要的开拓本钱十分高昂,实现周期长。而且硬件实现的结果如果不符合交流单元的需求,那么又须要修正硬件实现方案,又须要经由漫长的韶光,这样大大增加了交流单元的开拓韶光。如果能够在硬件实现之前,能够确保设计方案的性能知足需求,则能减少硬件修正的次数,从而缩短开拓周期。而软件仿真能够衡量设计方案的性能好坏,在创造设计方案问题的时候可以及时对设计方案进行修正,然后连续进行仿真测试性能,这样为硬件实现供应了良好的方案,避免重复繁琐的硬件修正过程。
仿真平台能够把一些比较成熟的仿真实现方法接口化和模块化,让软件仿真开拓者可以直接调用已有的,减少了不必要的重复繁琐的仿真设计事情,这样有助于缩短软件仿真开拓周期,从而降落了实现一款交流单元的韶光本钱。这样的仿真平台能让平台的开拓者更关注于平台底层功能的开拓,而平台利用者即仿真开拓者更看重详细交流单元的仿真方案的设计和实现。
交流单元软件仿真平台的开拓职员紧张设计和实现仿真平台底层,并且设计各种API函数和模块供给用者调用。平台的利用者则针对详细交流单元的设计方案,设计仿真方案,然后调用平台接口实现自己的功能逻辑,而平台底层卖力运行逻辑。
好了,不啰嗦了。下面看一个图。
上图便是一个最范例的离散韶光模型的实现办法,二维事宜链表。用事宜行列步队来表示所发生各种事宜的先后顺序,以及在不同的事宜发生后会触发新的事宜的发生,通过入队和出队操作来仿照事宜的发生和结束。全体模型采取事宜触发的机制。当然,描述芯片内部行为,还须要掩护一个韶光轴,所有的事宜都有专属的实行韶光的观点。在这个大略模型下,一个数据帧的到达可以用数个事宜来描述(帧长、耗费的韶光等)。实在,大家该当都做过类似的程序设计,比如经典的银行窗口做事系统等便是最大略的一个离散事宜。
实在,离散事宜模型不仅仅可以用来搭建芯片的仿真器(变时钟驱动为事宜驱动),还可以做各种通信协议的仿真平台,乃至是其它所有你可以抽象为离散事宜的场景。
事宜驱动仿真器关键技能
以下内容是课题组学生总结的一些体会和心得,通过这些总结就能够看出初次写一个仿照器须要把稳的内容。
1、什么是事宜
事宜是什么,事宜是一种软件层面的抽象,一定要理解软件中的抽象。事宜是对将要实行的动作的一种抽象描述,一个事宜最紧张的便是啥事、啥时候、谁啊、干啥啊。在实际的硬件中,大多数的动作都是中断触发的,包括定时器中断,我们都可以说有个事宜要实行。在MFC框架中,也有事宜的观点,一条、什么时候的、给谁的、怎么处理这个。总之当我们将上述元素组合在一起时,将能够精确地描述一个实际操作。例如,我要发送数据包,我在时候发送,我这么这么发送。再例如,我要方案信道,我在时候方案,我这么这么方案。原来上面说的一大堆模块都可以抽象成为事宜的观点,在不同的时候实行不同的例如,天生数据、发送数据、吸收数据的操作。我不敢说所有软件都是基于事宜的,但我们的仿真框架便是基于事宜的。
2、须要调度器吗
事宜有了,然后呢?怎么安排这些事宜在不同的时候去实行呢?我的第一个思路,把这些事宜写成数组,一个挨着一个实行,由于我们的协议是TDD的嘛,有韶光轴。这个方法貌似可行。。。不对有问题,同一时候有多个事宜怎么办?这个数组不足大怎么办?随着事宜的实行,很多空间变得不再须要怎么办?我可能要添加新的事宜怎么办?我脑残添加错了想删除事宜怎么办?好了好了别问了,我用链表不就行了。。。(实现的可能万万万)
经由努力,现在所有的事宜以一种合理的办法存储着,而且你可以随时添加新的事宜,在创造自己2B往后可以删除事宜。我们貌似有了一张动态的表格,随着韶光的推移已经实行的事宜在表格中擦除了,但是同时也会有新的须要实行的事宜写入了这张表格。
而调度器的事情便是每次提取第一个将要实行的事宜并实行干系处理(FIFO,最大略的调度器,也最符合仿真场景)。Windows怎么做的?GetMessage、TranslateMessage、DispatchMessage大循环。NS2怎么做的deque_event、dispatch_event大循环。
这里由于windows是实际系统,以是他不知道有什么message,这个message是由于用户交互操作产生的,是不可知的,而且系统的时钟是连续流逝的。NS2中,在一定程度上事宜是提前可知的,而且系统的时钟可以不连续的流逝。下面我们就说说韶光轴和离散的问题,来完善这个调度器的解释。
3、韶光轴和离散事宜驱动
我们在丈量协议性能的时候,有一个性能指标叫做时延,数据包从到达系统,然后离开系统所经由的韶光。实际硬件中,系统该当会掩护一个时钟,这样对每个包在出队入队时分别读取这个韶光就可以知道包的时延。那么在仿真中如何做到?
没错我们也须要一个韶光轴,在数据包入队事宜中为每个包打上标记,在数据包发送并吸收事宜处理时读取韶光轴韶光,以得到包的时延。问题是我们怎么样供应一个韶光轴?
Windows下可以获取系统韶光,能拿这个当做我们仿真的韶光轴对吗?You are wrong!
记得我们说过的仿真可以屏蔽硬件特性吗?如果我们这样做会有什么样的结果呢?我有一台i7-4770k处理器的台式机,一个数据包从入队到出队历时2.5ms;你有一台奔驰III处理器的台式机,同样的操作历时5ms。哇,你又引入了硬件特性,更何况windows能供应的韶光精度是什么样的我们都不知道。
我们该怎么办?别给我说windows都做不到,臣妾也做不到啊~~~~面包会有,办法也会有的。办法便是我们自己供应一个韶光轴,韶光的流逝由我们自己掌握,流逝的精度任意设定,这样就完备屏蔽了不同硬件带来的不同结果。
我以为我又说了个废话,方法详细是啥呢?第一个思路,设计韶光流逝精度是1us,现在时候now_time,我查看事宜表格里的第一个事宜的时候是不是即是now_time,若是则实行;若不是则now_time+1,韶光流逝1us。这里为了屏蔽硬件特性,在这个操作没有实行结束时时间轴是不会向前移动的,由于实际硬件中高速率cpu可能0.5us就实行完毕,而低速率cpu可能须要2us。这里无论这个操作在实际硬件中须要多久,我们都假设他在1us内实行结束就屏蔽了硬件。
然后,我又创造了问题,这样做确实可行,但是我须要轮训查询,轮训效率是相对较低的。而且,若1us有个事宜,1000us有个事宜,我须要查询1000次,而且全是无用功,怎么办?离散事宜驱动来帮助你。。。
每次取出一个事宜,事宜中标记此事宜的发生韶光,我们只须要将事宜的发生时候赋值给now_time,就可以仿照韶光流逝到这个事宜的发生时候。还是上述例子,now_time为1,取出一个事宜,创造其发生时候为1000,则设定now_time为1000,并实行干系操作。没有了查询,而且跳过了没有任何事宜的1000个韶光单位,效率大大提升。这里韶光轴没有一个一个韶光单元的流逝,而是根据事宜的发生时候,从1跳到1000,再跳到1002.。。。。韶光点是离散的,事宜也没有在韶光轴上均匀分布,这就叫离散事宜驱动,基于此事理的调度器便是离散事宜调度器,也便是我们仿真框架利用的模型。
4、事宜单元
至此,我们该当对框架有个大概的认识:事宜便是协议中的各种操作,他们被事先安排在一个合理的构造中,调度器每次从这个构造中取出第一个待实行的事宜实行,完毕后重复上述步骤,完成deque_event、dispatch_event循环。这里,大循环不是问题,问题是第一事宜该当有哪些元素,第二这个所谓存储事宜的构造是啥样的,我们一个个回答。
事宜应由哪些元素组成呢?回忆一下windows程序中的,它包括所属的窗口(谁的),标识符(的名字或者类型),投递韶光(消逝的产生韶光),的附加信息。转头想想之前说的事宜中的元素,现在已经拥有了谁啊(所属)、啥事儿(标识符)、啥时候(投递韶光),但是没有看到干啥啊,windows里的构造不完全啊,这是个bug吧。再翻开孙鑫的书,每个有指定所属的窗口,每个窗口构造有一个函数指针,指向此窗口对所有的处理函数,函数中根据的类型不同,利用switch进行语句分支,达到处理不同的目的。
貌似问题办理了,我们可以为每个模块设定类似上述构造(事宜类型、事宜实行者、事宜发生韶光),然后每个模块根据剖断事宜类型的不同选择不同的程序分支进行处理。详细些,调度器调出一个事宜,首先剖断事宜实行者,程序调转到干系实行者代码段,再剖断事宜类型,程序跳转至相应代码段,所有操作实行结束,返回调度器,重复上述。思路没有大的问题,程序会有两个switch,一个剖断实行者,一个剖断事宜类型。但是我们可以想象随着模块的增多、事宜类型的增多,这两个switch会不断增大,甚至后来我们自己徜徉在我们的代码里却找不到北。
巨硬搞错了吧,设计这么糟糕的框架。别忘了巨硬还有个框架叫MFC,它里面利用了其余一套机制来办理代码越来越长的问题---映射机制,光从这个名字就知道这是啥技能。一条对应一个处理函数,而不像原来所有对应到一个入口函数,在内部实现的不同处理。这样第一我们能迅速的找到处理此的代码,第二我们程序猿不用为了知足产品狗不断的需求,而让那唯一的函数变得越来越大、越来越长~~~~(这里微软是怎么映射的我们就不磋商了,那是详细实现的问题了)
说了这么一大堆windows的东西,和我们有何关系呢?如前所述,我们的事宜就类似windows中的,有差不多相同的元素,再加上事宜到事宜处理函数的映射关系,我们的框架貌似就要完成了。不过先别急,我们再看看NS2的代码。
NS2更
好吧,齐活。事宜包括事宜类型和名称(名称大概只有调试的时候有用),事宜实行者ID(协议仿真中总要分不同的结点),事宜发生韶光(别忘了我们还有张事宜表格,事宜在表格中是有先后顺序的),事宜实行函数指针(瞬间我就找到了处理我的代码,真是极好的)。
哎呀师兄,这个函数指针我理解不了。要举一反三。再看看孙鑫的书,看看windows窗口程序的函数指针,它有四个参数,前两个参数--窗口句柄、类型,为了之前所说的两个switch用的,看来我们的构造是用不上了,由于我们不须要映射。后两个参数--带来的两个参数,这是干嘛的。废话啊,程序是完成交互处理的,当然要有参数了,不然函数不就不能完成多样性的输出了嘛。
对啊,我们的事宜实行函数指针总要有个类型吧,指明这类函数要怎么样的输入参数,输出怎么样的值。说得对,但问题是实行函数千奇百怪,参数个数不尽相同,怎么可能设计出适宜所有函数的指针呢?
哎呀呀,要你这么说linux中的驱动程序那么高等的抽象是怎么做出来的。办法有,而且很大略,利用void指针作为函数的输入参数(void fun(void pdata))。当我们须要一个输入参数时,一个viod指针就够了;两个参数怎么办,传输形参前先将他们封装到一个构造体内,在函数内部再取出各个域。这个办法,你有一百个参数都能传进去。
方法很好,不过我们能不能简化一下处理呢?一个函数完成一个功能,须要处理输入得到输出,那么这个函数类型可以简化为void fun(void src_data,void des_data),这样如果函数的参数不是很多的话,我们就不用设计那些封装参数的构造体了。送佛送到西,再来一个void fun(void src_data,void des_data, void add_data),我们的函数都采取这样的形式吧,源参数、目的参数和附加参数,源参数紧张承载函数获取数据的来源,目的参数卖力指明结果写到哪里,附加参数你就发挥想象吧,什么都可以。
哇,问题彷佛是得到理解决,事宜包括上述的那些元素,个中包括一个这样一个函数指针---void (pfun)(voidsrc_data, void des_data, void add_data)。事宜处理循环中,取出事宜,然后实行这个指针指向的函数。
代码写着写着创造问题了,实行这个指针指向的函数,他须要参数啊,而且虽说所有事宜实行函数的参数个数同等,但是参数的名字不一致啊,怎么可能写出一条语句去实行所有的事宜实行函数呢?看看NS2咋搞的,很遗憾NS2没有利用我们设计的这套机制,难道我们要推倒重修?Nononono。。。。
再看一下NS2的事宜实行循环函数:
把稳赤色划线部分,先取出一个事宜p,然后将p通报给dispatch函数,然后在dispatch内部:
调用事宜p的实行函数指针,并将事宜p本身作为参数通报给事宜实行函数。
原来是这样啊,我们可以将所有的参数封装进事宜,作为事宜元素的一部分,然后对付事宜实行函数我们设计void (pfun)(Event e)的指针,每次将事宜本身通报给实行函数,并在函数内部解析出须要的各种参数。
真是个浩大的工程,用了三分之一的篇幅终于将事宜的所有主要元素搞出来了。事宜包括:事宜的发生韶光、事宜的类型、事宜的所属工具、事宜的实行函数指针、事宜实行函数的源参数指针、事宜实行函数的目的参数指针、事宜实行函数的附加参数指针(针对不同事宜,不是所有的域都要利用)。
那么当我们实例化一个事宜时,这个构培养叫做一个事宜单元,代表着一个将要实行的动作的所有要素。
5、事宜存储单元
有了事宜单元后,存进一个怎么样的构培养是个问题。这里仅仅讲解存储的思路,实现不做详细剖析。我们有两个问题,第一同一韶光点的事宜如何放置,第二不同韶光点的事宜如何放置。
第一个问题,最大略的方法便是行列步队,同一时候的事宜按照事宜的先后顺序(也有可能事宜间没有先后顺序,但总要有个行列步队)。
第二个问题,不同的时候也要能够很大略的索引到,由于当插入新事宜时,一定是向当前时候之后的某个时候插入。这里我们可以再次利用链表,或者hash表,这都是实现的问题了。
至此,我们设计出了一个事宜单元的构造,以及为了方便索引至任意时候的任意事宜单元的存储构造。而且,通过每次提取这个存储构造中的第一个事宜并实行,我们的框架中最紧张的部分就完成了,剩下的事情便是设计不同的事宜及其干系操作函数。
EDA干系与芯片仿真器
长期以来,海内的EDA干系工具都严重依赖于国外。正是由于海内从事EDA工具开拓的公司在Synopsys、Cadence、Mentor面前实力过于悬殊,海内IC设计公司险些100%采取国外EDA工具。而且在相称长的一段韶光里,看不到缩小和Synopsys、Cadence、Mentor技能差距的可能性。但笔者本日所说的内容,不属于常见的芯片设计EDA工具范畴,但却关乎国产芯片能否做大做强的关键。今年9月,一家国产eda公司得到国家集成电路家当投资基金投资,从2017年底至今,该公司已得到累计数亿元投资,这将有助于该公司提升自身技能水平,补充中国EDA工具上的空缺。不过,由于中国在EDA工具上与国外三大厂差距过大,追赶之路任重道远。
我们也希望海内也能够涌现类似于Cadence和Synopsys 这样的巨无霸,不是只供应芯片设计专用的EDA工具,也能够出售各种成熟的IP和仿真器平台。
全文完。







