平码五不中公式规律
  • / 21
  • 下载费用:30 金币  

基于片上网络互连的多核存储系统仿真器.pdf

关 键 ?#21097;?/dt>
基于 网络 互连 多核 存储系统 仿真器
  专利查询网所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
摘要
申请专利号:

CN201410148038.3

申请日:

2014.04.14

公开号:

CN103914333A

公开日:

2014.07.09

当前法律状态:

授权

有效性:

有权

法?#19978;?#24773;: 授权|||实质审查的生效IPC(主分类):G06F 9/455申请日:20140414|||公开
IPC分类号: G06F9/455 主分类号: G06F9/455
申请人: 中国科学技术大学苏州研究院
发明人: 吴俊敏; 崔贤芬; 赵小雨
地址: 215123 江苏省苏州市工业园区独墅湖高教区仁爱路166号
优?#28909;ǎ?/td>
专利代理机构: 苏州创元专利商标事务所有限公司 32103 代理人: 范晴;夏振
PDF完整版下载: PDF下载
法律状态
申请(专利)号:

CN201410148038.3

授权公告号:

||||||

法律状态公告日:

2017.12.01|||2014.08.06|||2014.07.09

法律状态类型:

授权|||实质审查的生效|||公开

摘要

本发明公开了一种基于片上网络互连的多核存储系统仿真器,其特征在于所述仿真器以SystemC的内核作为整个仿真器的驱动内核,包括用于仿真各个处理器核心的一级高速缓存的缓存模块、用于仿真各个处理器核心的二级高速缓存的路由模块和用于提供功能仿真的QEMU模块;若干个路由模块互连仿真处理器核心共享的二级高速缓存形成的片上网络,每个路由模块设置有一组与缓存模块连接的信号线;所述路由模块将缓存模块或者路由模块传递的pkt消息?#22336;?#21040;另一缓存模块或者另一路由模块。该仿真器能够用来进?#24515;?#26631;系统的系统软件开发,使得软?#24067;?#24320;发可以同时进行,加快系统开发速度。

权利要求书

权利要求书
1.   一种基于片上网络互连的多核存储系统仿真器,其特征在于所述仿真器以SystemC的内核作为整个仿真器的驱动内核,包括用于仿真各个处理器核心的一级高速缓存的缓存模块、用于仿真各个处理器核心的二级高速缓存的路由模块和用于提供功能仿真的QEMU模块;若干个路由模块互连仿真处理器核心共享的二级高速缓存形成的片上网络,每个路由模块设置有一组与缓存模块连接的信号线;所述路由模块将缓存模块或者路由模块传递的pkt消息?#22336;?#21040;另一缓存模块或者另一路由模块。

2.   根据权利要求1所述的基于片上网络互连的多核存储系统仿真器,其特征在于所述pkt消息包括data字段、id字段、dest数组字段、addr字段、cur_addr字段、change_data字段、index字段;其中data字段用于存储消息中的数据;id字段用于表示路由模块的编号;dest数组字段用于表示pkt信息需要发送的目的地;addr字段表示缓存行的地址;cur_addr字段表示缓存行的起始地址;change_data字段表示写操作的数据;index字段为标记字段。

3.   根据权利要求2所述的基于片上网络互连的多核存储系统仿真器,其特征在于所述pkt消息中index字段为0时,表示没有特殊功能;index字段为1时,从二级缓存或DRAM中取块并返回给发送者;index字段为2时,修改二级缓存及DRAM中相应块的内容,同时发?#36879;?#38500;自己之外的一级缓存,表示对某个地址执行了写操作;index字段为3时,从二级缓存发给DRAM要求其刷新相应的缓存块;index字段为4时,修改二级缓存及DRAM中的字,并将该字对应的块传?#36879;?#21457;?#36879;?#28040;息的源一级缓存;index字段为5时,表示一级缓存未?#19994;?#26576;行数据,需要从其它一级缓存中查看是否有该数据。

4.   根据权利要求1所述的基于片上网络互连的多核存储系统仿真器,其特征在于每个路由模块中设置有路由表,所述路由表中存储路由模块输出时的路由选择路径。

5.   根据权利要求1所述的基于片上网络互连的多核存储系统仿真器,其特征在于每个路由模块维护一个消息队列,每次路由模块采用轮询的方式将输入信号线中的pkt消息存入消息队列中。

6.   根据权利要求1所述的基于片上网络互连的多核存储系统仿真器,其特征在于所述缓存模块采用组相联?#25104;?#31574;?#38498;?#20889;回方法,替换时随机选择某一缓存行,在缓存块中设置若干指向实际存储信息的缓存行的指针,每个缓存行包含Valid字段、data字段、tag字段和dirty字段;其中Valid字段用于表示该缓存行是否有效;data字段指向存储“字块”的单元;tag字段为标记位,当接收到某个地址之后,比较标记位确认是否与此缓存行匹配;dirty字段判断是否为脏数据,该行数据有没有被写过。

7.   根据权利要求1所述的基于片上网络互连的多核存储系统仿真器,其特征在于所述仿真器还包括驱动模块,驱动模块向缓存模块发起读或写操作,并传输其它相关信号。

8.   根据权利要求7所述的基于片上网络互连的多核存储系统仿真器,其特征在所述驱动模块和缓存模块?#21152;?#26102;钟发生器控制,驱动模块和缓存模块之间通过5根信号线连接进行信号传输,包括Func信号线、Data_in信号线、Addr信号线、Data_out信号线和Done_sig信号线;其中Func信号线用以通知缓存模块执行操作;Data_in信号线是提供驱动模块向缓存模块中的某个单元传送写入的数据;Addr信号线用于表示驱动模块想要读/写的地址;Data_out信号线用于驱动模块发送读操作,通过Data_out信号线返回所读单元的数据;Done_sig信号线用于结束一次执行过程。

说明书

说明书基于片上网络互连的多核存储系统仿真器
技术领域
本发明属于存储系统仿真领域,具体涉及一种基于片上网络互连的多核存储系统仿真器。
背景技术
早期的单核计算机系统通过提升芯片频率达?#25945;?#39640;计算机性能的目的,但是随之而来的是产生过多的热量且不能得到相应的性能提升,于是产生了多核。为了对多核处理器及其片上网络进行研究,可使用体系结构仿真技术进?#24515;?#25311;,并运行程序进行测?#38498;?#39564;证。当前主流的系统仿真器?#28909;鏢implescalar、M5主要是模拟处理器,每个仿真器都有各自的关注点。?#28909;?#21069;者主要是模拟处理器的执行过程,后者主要是仿真网络主机,很少有仿真器把重点放在存储系统上。现有的仿真器大都使用高级语言编写,而仿真过程模拟的是?#24067;?#30340;功能,传统的方法是使用高级语言编写代码后,再转化为?#24067;?#35821;言描述,整个实现的过程周期长、效?#23454;汀?
发明内容
本发明目的在于提供一种基于片上网络互连的多核存储系统仿真器,解决了多核下存储系统互连问题。存储系统的执行过程可以细化到时钟级,与真实系统的执行过程类似,采用SystemC语言描述的系统更接近真实系统的工作过程。多核下的互连采用片上网络结构,片上网络的优点是易于扩展,如若需要往整个系统中再添?#26377;?#30340;核心,只需在片上网络中再添加一路由器并连接一处理器,整个系统可以照常运?#23567;?
为解决现有方法中的问题,本发明提供的技术方案是:
一种基于片上网络互连的多核存储系统仿真器,其特征在于所述仿真器以SystemC的内核作为整个仿真器的驱动内核,包括用于仿真各个处理器核心的一级高速缓存的缓存模块、用于仿真各个处理器核心的二级高速缓存的路由模块和用于提供功能仿真的QEMU模块;若干个路由模块互连仿真处理器核心共享的二级高速缓存形成的片上网络,每个路由模块设置有一组与缓存模块连接的信号线;所述路由模块将缓存模块或者路由模块传递的 pkt消息?#22336;?#21040;另一缓存模块或者另一路由模块。
优选的技术方案中?#26680;?#36848;pkt消息包括data字段、id字段、dest数组字段、addr字段、cur_addr字段、change_data字段、index字段;其中data字段用于存储消息中的数据;id字段用于表示路由模块的编号;dest数组字段用于表示pkt信息需要发送的目的地;addr字段表示缓存行的地址;cur_addr字段表示缓存行的起始地址;change_data字段表示写操作的数据;index字段为标记字段。
优选的技术方案中?#26680;?#36848;pkt消息中index字段为0时,表示没有特殊功能;index字段为1时,从二级缓存或DRAM中取块并返回给发送者;index字段为2时,修改二级缓存及DRAM中相应块的内容,同时发?#36879;?#38500;自己之外的一级缓存,表示对某个地址执行了写操作;index字段为3时,从二级缓存发给DRAM要求其刷新相应的缓存块;index字段为4时,修改二级缓存及DRAM中的字,并将该字对应的块传?#36879;?#21457;?#36879;?#28040;息的源一级缓存;index字段为5时,表示一级缓存未?#19994;?#26576;行数据,需要从其它一级缓存中查看是否有该数据。
优选的技术方案中:每个路由模块中设置有路由表,所述路由表中存储路由模块输出时的路由选择路径。
优选的技术方案中:每个路由模块维护一个消息队列,每次路由模块采用轮询的方式将输入信号线中的pkt消息存入消息队列中。
优选的技术方案中?#26680;?#36848;缓存模块采用组相联?#25104;?#31574;?#38498;?#20889;回方法,替换时随机选择某一缓存行,在缓存块中设置若干指向实际存储信息的缓存行的指针,每个缓存行包含Valid字段、data字段、tag字段和dirty字段;其中Valid字段用于表示该缓存行是否有效;data字段指向存储“字块”的单元;tag字段为标记位,当接收到某个地址之后,比较标记位确认是否与此缓存行匹配;dirty字段判断是否为脏数据,该行数据有没有被写过。
优选的技术方案中?#26680;?#36848;仿真器还包括驱动模块,驱动模块向缓存模块发起读或写操作,并传输其它相关信号。
优选的技术方案中?#26680;?#36848;驱动模块和缓存模块?#21152;?#26102;钟发生器控制,驱动模块和缓存模块之间通过5根信号线连接进行信号传输,包括Func信号线、Data_in信号线、Addr信号线、Data_out信号线和Done_sig信号线; 其中Func信号线用以通知缓存模块执行操作;Data_in信号线是提供驱动模块向缓存模块中的某个单元传送写入的数据;Addr信号线用于表示驱动模块想要读/写的地址;Data_out信号线用于驱动模块发送读操作,通过Data_out信号线返回所读单元的数据;Done_sig信号线用于结束一次执行过程。
本发明利用SystemC的内容今昔跟仿真,SystemC这种编程语言既能描述?#24067;?#34892;为,也可以实现软件,SystemC是C++的宏和库,C++语言是面向对象的,而且现存有许多功能完善的执行代码工具。该仿真器使用QEMU模块进行功能仿真,QEMU仿真器具有高效、支持多种体系结构、动态二进?#21697;?#35793;等特点。最终实现的存储系统分为二级结构,一级缓存为处理器私有,二级缓存为共享。存储系统将通过片上网络与QEMU模块互连形成一个完整的多核计算机系统。QEMU是功能仿真器,用于模拟处理器模块的功能。可以通过在SystemC模块中预留接口,并且在QEMU模块中将部分功能使用SystemC细化,从而将两模块之间共有的SystemC部分连接通信。
由于QEMU是功能仿真器,本发明将QEMU仿真器中剥离其中的处理器功能模块,添加到该存储系统仿真器中可以形成一个完整的多核计算机系统。该存储系统仿真器具体包括三个模块:缓存模块、路由模块和QEMU模块。
首先由sc_start()语句启动SystemC的内核作为整个仿真器的驱动内核。?#32531;驫EMU模块启动进程,该进程会对底层的存储系统发起读/写某地址中的数据操作。程序运行之时,存储系统会调用各自的构造函数为存储器分配存储空间。当整个系统运行时,模块内部会执行相应的操作,QEMU中的进程执行的操作会通过屏幕显示出来结果,由结果可以看出是否得到所需地址的值。
相对于现有技术中的方案,本发明的优点是:
本发明的仿真器能够用来进?#24515;?#26631;系统的系统软件开发,使得软?#24067;?#24320;发可以同时进行,加快系统开发速度。多个核心之间的片上网络互连能够缩短核间的互连线,?#26723;?#26680;间通信?#26144;伲?#25552;高通信效率和数据传输带宽。使用片上网络互连有利于系统的扩展。
附图说明
下面结合附?#25216;?#23454;施例对本发明作进一步描述:
图1是本发明基于片上网络互连的多核存储系统仿真器的互连图
图2是本发明片上网络互连结构图;
图3是本发明路由模块的简要示意图;
图4是缓存模块的结构示意图;
图5是本发明基于片上网络互连的多核存储系统仿真器qemu模块的通信架构图;
图6是本发明驱动模块与缓存模块的通信示意图。
具体实施方式
以下结合具体实施例对上述方案做进一步说明。应理解,这些实施例是用于说明本发明而不限于限制本发明的范围。实施例中采用的实施条件可以根据具体厂家的条件做进一步调整,未注明的实施条件通常为常规实验中的条件。
实施例
本实施例采用一?#20013;?#30340;互连方式:片上网络互连方式。多核下的缓存采用分级结构,采用二级缓存结构,一级缓存为各个核心所私有,二级缓存为各个核心所共享;由于一级缓存为多个核所私有,各个核会对同一缓存块中的数据执行不同的操作,所以容易造成数据不一致。
一、缓存模块
缓存模块是按照其定义来实现的,采用组相联?#25104;?#31574;略、写回方法、替换时随机选择某一缓存?#23567;?#39318;?#20161;?#29992;一个指针指向Cache Block,这些缓存块中存有许多指针,这些指针指向实际存储信息的单元,该单元被称为缓存行(cache line)。不论是私有缓存还是共享缓存都使用缓存行的方式,只是一级缓存需要考虑一致性问题。
(1)私有缓存
在多核下缓存的一致性问题存在于私有的一级缓存中。采用MSI(三态写回无效)协议解决该问题,由该协议可知,该协议采用写回高速缓存,减少了传输次数;写无效是指本地高速缓存中的数据被更新后,使其它高速缓 存中的相应拷?#27425;?#25928;,下一次由该缓存发起对相同块的写操作?#25442;?#20877;对其它一级缓存模块发出通知。该协议将Cache的状态设置为三种:修改过、共享和无效状态。因此在缓存行中需要2位用于表示这三种状态。在多核下,采用消息传输,一级缓存只需两根信号线(输入/输出信号线)直接连接到路由模块,消息的转发在路由模块内部实现。
SystemC使用SC_CTOR()表示构造函数,在构造函数内?#21487;?#26126;进程,可以初始化进程的敏感表,敏感表是用来指定对进程敏感的信号和端口集。所有需要在模块内部执行的操作都会在进程中实现。
私有缓存模块的构造函数首?#20161;?#36827;行存储空间的分配。在构造函数的参数中可以设定参数用于指定缓存的容?#20426;?#32452;相联的路数,?#32531;?#20998;配所需的空间。接下来就是定义进程实现模块的功能。在构造函数中包含两个函数:①do_operation(),该函数对时钟的下降沿敏感,该函数的作用就是接收驱动模块发送的命令,并对缓存执行一系列的操作,主要是控制本地操作;②do_cycle(),该函数对模块的输入信号敏感,当输入信号来临时,表明远程处理器执行了某操作,需要查看本地缓存并根据情况修改其相应的状态位,主要是控制远程操作。远程操作分为如?#28388;?#31181;:①本地读;②本地写;③远程读;④远程写。
1.无效I状态
①本地读操作时,发送消息给其它一级缓存中查看有没有此行数据。若没有,直接从下面的存储器中返回,并将状态由I->S;如果其它核心中的一级缓存中含有这行数据且状态为修改过M,则首先要写回主存,?#32531;?#23558;状态改为共享S,本Cache将数据从内存中取出,本地缓存行状态由I->S;若其它缓存中有该数据且状态为S,则直接从下层存储空间取数据,本地缓存行状态由I->S。
②本地写操作时,从内存中取数据,在Cache中修?#27169;?#29366;态由I->M。如果核心的一级缓存中有这份数据的拷贝且状态为修改过M,则要先将数据写回内存。如果其它Cache中有这份数据,则其它Cache的cache line状态变为I。
③远程读和远程写时,因为本来就是无效状态,所以无影响,从而状态不变。2.共享S状态
①本地读操作就直接从Cache中提取数据,状态不变。
②本地写时,修改Cache中的数据,状态变为M。其它缓存中若有该cache
line,则cache line变为I。
③远程读时,状态不变。
④远程写时,由于数据被修?#27169;?#26412;cache line含有旧数据,状态变成I。
3.修改M状态
①本地读时,直接从Cache中取数据,状态不变。
②本地写时,修改cache line中的数据,状态不变。
③远程读时,该行数据需要写回内存,其它核心从内存中取得最新数据,状态变为共享S。
④远程写时,本核心中的数据先写回内存,因为其它核会改变这行数据,所以状态变为无效。
当某个缓存接收到驱动模块发送的信号后,查?#19968;?#23384;块中是否包含所求地址的块,如果?#19994;?#19988;不为无效,直接返回就可以了。如果是无效,则需要发送消息到其它一级缓存模块。如果是远程发送过来的消息,首先查看消息中的地址所在的缓存块是否在该缓存中。如果不在,则不予处理;如果在,则根据外界操作的类型来修改缓存行的状态,修改的方法就是按照前面所述的状态转换过程。同时,如果伴有将数据块送入下层存储系统的操作,不仅需要修改状态,还要将缓存块打包在消息中,传送到下层的存储系统中。
在缓存模块中,不仅需要定义与驱动模块连接的信号线,而且需要为其缓存行的存储分配空间。

在结构体cache_block中,address表示某个缓存行的起始地址;valid表示这行数据是否有效,在默认情况下是无效的;tag表示这个缓存行的标记,这一个字段是从address中的前几位中分离出来的;data指向缓存行所拥有的块中的数据;dirty用于判断这个缓存行中的数据是否是脏数据。
缓存模块内部,需要定义5个信号线,这5个信号线的输入/输出方向与驱动模块是相反的,因为这是针对缓存模块的。
缓存模块的构造函数含有如下参数。
Cache(sc_module_name name_,unsigned int_index_bit,unsigned int_offset_bit,unsigned int_way_num,unsigned int unique_priority);
在Cache的构造函数中声明这些变量,其中包括模块名、index bit、偏移量offset bit以及组相联的组数?#21462;?#22312;构造函数中,定义各种数据结构,如图4所示,并为各个指针分配所需的存储空间;对某些变量,例如valid、dirty进行初始化。当所有这些工作完成之后,声明一个过程函数do_operation()。该函数对某一信号敏感,?#22791;?#25935;感信号被激活时,就自动调用过程函数,启动模块运?#23567;?#25152;以,这整个模块的所有工作都将由该函数完成。函数应该声明为一个SC_THREAD方法,该方法的特点是内部存在一个无限循环,只有遇到wait()语句时才会挂起直到下一次敏感信号被激活。
该模块中含有一个端口Cache_port,这个端口用于实现与总线中的接口互连。该端口只需指定与总线中的Bus_if相对应,就可以通过该端口调用总线中的接口方法。缓存与主存之间信息传输的单位是块,所以需要用到阻塞读/写方法,即将一个块中的所有数据?#32423;?#23436;之后,才算是一个完整的事务。
任何SystemC模块都必须有模块名,因?#35828;?#19968;个参数就是指定模块名,实质上它是一个常量?#22336;?#20018;;当用户确定了一个缓存块和内存的大小、以及组相联的路数时,_index_bit和_offset_bit的位数也就确定下来了,这两个变量在后面的实现中经常需要用到;_way_num就是组相联?#25104;?#26102;的路数,即一个缓存块中含有多少个缓存?#23567;?
构造函数首先需要做的就是为缓存分配存储空间,包括cache_block和data指针指向的空间,分配这些空间的时候就需要用到构造函数中的参数。 最后将全部的valid以及dirty初始化为0。构造函数中有个函数do_operation(),当时钟的下降沿到来时,就会调用这个函数。前面介绍的函数都是SC_METHOD,而这个函数是SC_THREAD,这种类型的函数内部会有一个无限循环。下面着重介绍do_operation()函数。
do_operation()函数由一个全局的while循环构成。这个循环是死循环,通过在函数内部调用wait()方法可以挂起这个进程,使得wait()后面的语句无法执行,直到某个等待条件出现的时候才会重新执?#23567;?#22312;这个函数中,首?#20161;?#35201;读取信号线Func上的信号判断是FUNC_READ、FUNC_WIRTE还是FUNC_NONE。
若为FUNC_NONE,则调用wait();说明此次过程不需要执行任何操作;待到下一时钟周期的下降沿到来时,再去读取,直到信号线上出?#20013;?#21495;为止。
若有信号,则将读到的值存入变量m_cur_Func中,地址存入m_cur_Addr中,在while循环中,需要分情况?#33268;邸?
当为FUNC_READ时,通过移位的方式将地址分割成三部分:标记tag,index,偏移量offset。首先根据index定位在缓存块cache_block中的哪一组中。由于一组中含有多个缓存块(组相联?#25104;?#26041;式),所?#22253;?#20010;比较这一缓存组中的每一个缓存行中的tag域,直到?#19994;?#19968;个缓存行,它的tag与地址分割出的tag相等并?#19968;?#23384;行的有效位valid为1。此时表明缓存命中。根据偏移量offset定位所要求的字在data指针所指区域中的位置,并将这个值写入到信号线data_out中,返回到请求这个数据字的驱动模块。将信号线Done_sig设置为READ_FIN,并调用wait()语句挂起?#31169;?#31243;;因为此次过程传输已结束,等待下一个时钟的下降沿来临激活该进程,执行wait()后面的语句。在这里需要提一下如何通过一个地址获得其?#21046;?#22987;地址和块起始地址。以4个?#32440;?#20316;为一个字,因此一个字可以通过2位来表示。将信号线上得到的地址先向右移动2位,?#32531;?#21521;左移动2位,得到的就是?#21046;?#22987;地址;将信号线上得到的地址先向右移动offset位?#32531;?#21521;左移动offset位得到的就是块起始地址。
否则的话,缓存没有命中,数据不在缓存中,就需要从DRAM中取得数据所在的块,存储于缓存行中并返回给驱动模块。首先要确定这个数据所在的缓存块从DRAM中取来之后,放在缓存中cache_block的哪个组中,这 是由index变量决定的。?#32531;?#20174;这一组中选择一路(因为有多路)。如果有某一个缓存行中的valid=0,说明这?#24418;?#26377;效数据,可用;否则的话,表明每行数据都有效,通过调用随机函数选择一路。如果该路中的dirty变量为1,说明该缓存行中的数据与主存中的数据不一致,在替换之前,需要将该行数据重新写入内存之后,才能被替换。首先将该缓存中的数据存入一个临时变量中,通过缓存模块的端口cache_port调用总线接口bus_if中的阻塞写方法,目的就是将这行dirty=1的数据写回内存中。?#32531;?#36890;过缓存模块的端口cache_port调用总线接口bus_if中的阻塞读方法,读取m_cur_Addr所指单元所在的数据块的所有数据,读取完毕后,将所读地址中的数据块存入缓存行中,该块就是存入刚才在上一步骤中选取的缓存?#23567;?#19981;仅如此,还需要将该行中的valid置1、dirty置0、将该缓存行的tag位赋为由刚才的地址分割出的tag。至此该未命中过程就结束了。剩下的操作同前面相同,将信号线Done_sig设置一下,此处不再重述。
当为FUNC_WRITE时,首先需要检查所写入的这个地址单元所在的块是不是已经存入缓存行中,定位的方法与读操作时定位的方式相同。如果缓存命中,则将输入信号线data_in中的数据存入缓存行中data指针所指向区域中的某个单元,这个单元是通过偏移量offset来确定的。同时,需要将缓存行中的dirty置1。操作结束后,设置信号线Done_sig为WRITE_FIN,并调用wait()方法挂起该进程。
若未命中,根据信号线Addr中的地址确定缓存块的位置,在缓存块中找寻valid为0的缓存块。如果该块中的所有缓存行所存数据都有效,则随机选择一路缓存。若该缓存行的dirty为1,必须先将该行数据刷新到主存中,?#32531;?#20877;替换。接下来所做的就是“行填充”。根据地址Addr确定该地址所在的块的首地址,?#32531;?#36890;过缓存端口调用总线接口中的阻塞读方法,取得这整块数据放入缓存行中,?#32531;?#35774;置缓存行中的其它字段,例如:valid、tag、dirty。此过程结束之后,设置信号线Done_sig的值为WRITE_FIN。
整个缓存与其它各个模块之间的交互过程就是这样的。缓存中的替换方法采用最直接的随机挑选策略,只需调用一个随机函数取模组相联中的路数即可;不一致问题采用写回方法来解决。
私有缓存模块与驱动模块之间连接的方式与单核下的相同,都是通过5 根信号线连接。由于现在有多个核心分别与各自的一级缓存相连,因此每个一级缓存需要一个cache_id来标识其挂接在哪个编号的路由器上。该模块还有一个输入信号和输出信号与路由器连接,路由器通过这两根信号线与一级缓存?#25442;?#20449;息。在缓存的存储块L1_cache_block中用两个位字段sc_uint<2>表示缓存行的状态(共3个状态)。私有缓存模块的构造函数内部的内容与单核下相似,主要就是为其分配存储空间,以及进行必要的初始化,所不同的就是执行操作的函数内部实现。在构造函数中包含两个函数:①do_operation(),该函数对时钟的下降沿敏感,该函数的作用就是接收驱动模块发送的命令,并对缓存执行一系列的操作,主要是控制本地操作;②do_cycle(),该函数对模块的输入信号敏感,当输入信号来临时,表明远程处理器执行了某操作,需要查看本地缓存并根据情况修改其相应的状态位,主要是控制远程操作。
do_operation()中,接收消息的方式与单核下相同。首?#20161;?#23545;地址进行分割,得到tag、index、offset域。若是读操作消息,则根据index域选择该地址所对应的缓存块,与该块每一路中的比较tag且为无效状态。如果?#19994;?#35813;缓存行,则直接返回所需字,并设置Done_sig信号为READ_FIN。否则未命中,先从缓存行中寻找一路用于存储后续获得的块,如果没有无效行,则通过调用随机函数得到某一缓存?#23567;?#33509;该行的状态为修改过M状态,表明这行数据在替换之前需要先写回主存中,因此打包一个数据包并发送到二级缓存模块修改数据。并且需要给其它的一级缓存模块(除自?#21644;猓?#21457;送一个消息,查看是否有该缓存行数据。所?#28304;?#26102;需要打包一个消息其index=2,dest[]数组中除自己之外其它一级缓存都需要设为1,并将相应的数据和地址都写入消息后发?#32479;?#21435;,等待输入信号,挂起这个进程。如果其它缓存模块含有这个缓存块的有效数据,就直接发送请求给其它缓存,否则需要发送消息到下层存储单元请求数据。
若驱动模块发?#36879;?#19968;级缓存模块的是写操作消息,首先还是?#19994;?#20854;所在的cache_block。若命中,则查看其状态,当为无效或共享状态时,首先打包消息发送到其它的一级缓存查看是否有该地址对应的缓存行,如果有,则将其状态改为无效状态,操作完成后,直?#26377;?#20837;数据,状态更改为修改过M状态;若为修改过状态,只要直?#26377;?#20837;状态无需改变。若未命中,则需要根 据index域选择在哪一组中,?#32531;?#20174;中选择一个无效的缓存行,若所有的缓存行都不是无效状态,则随机选择一行,查看其状态为共享还是修改过。如果是修改过M状态,则需要打包一个消息传送到下层的存储空间,将该数据写回,同时从下层存储空间返回需要写入的数据所在的块给一级缓存,存入一级缓存之后,该一级缓存模块就将新数据写入,该缓存行的状态为修改过状态,同时需要发送消息到其它的一级缓存模块查看是否有这行数据,如果有,就将其状态置为无效。写操作结束之后,信号线Done_sig将被置为WRITE_FIN。驱动模块就会在屏幕上打印输出信息。
do_cycle()函数对模块的输入信号敏感,若远程发生读/写操作,可能需要查看当前模块是否有缓存行,该函数就是用于修改缓存行的状态。函数的内部实现比较简单。函数被输入信号线激活时,根据消息中的地址查?#19968;?#23384;块,在块中查找是否有匹配的缓存行,若?#19994;劍?#21017;根据远程操作的类型修改其状态,修改完成后,返回一个消息通知发送者处理完成。
(2)共享缓存
二级缓存作为各个核的共享缓存,更接近主存,容量更大,因此速度更慢。二级缓存就是一级缓存的缓冲区域。在二级缓存的实?#22336;?#26696;中,采用的是两个状态:有效和无效。该缓存存在的目的就是将部分最近使用的数据存储于其中,但是一级缓存容量不够又装不下,减少传输的层次。缓存的实?#22336;?#24335;也是在构造函数中定义进程实现模块的功能。首?#20161;?#36827;行存储空间的分配,?#32531;?#23450;义进程的功能实现模块的功能。
在二级缓存的实?#22336;?#26696;中,采用的是两个状态:有效和无效。采用这?#22336;?#26696;之后,该缓存的设计和实?#22336;?#27861;与单核下的缓存模块十分相似。只是接收到的消息类型不同。此时的共享缓存接收到的是外界发送来的消息包,包中含有所有想要的信息。之所以使用这?#22336;?#24335;是为了削弱实现的难度。该缓存存在的目的就是将部分最近使用的数据存储于其中,但是一级缓存容量不够又装不下,减少传输的层次。
二级缓存通过输入/输出端口连接到路由器。二级缓存中的存储空间设计与单核下的缓存基本相同。二级缓存担负着减轻一级缓存容量压力的责任。它直接通过输入/输出端口与DRAM模块连接,两个模块之间只需要实现请求的传输,具体的操作在消息内都有指定,收到消息的模块只需按照请 求中的要求执行函数过程。
二、驱动模块
由前图6可知,驱动模块通过5根信号线与缓存模块连接。每根信号线都是必需的。其中,信号线FUNC用来向缓存发送命令,控制读/写操作;data_in用?#21019;?#36755;将要写入缓存中的数据;data_out表示从缓存中返回的数据;addr是所需读/写数据的地址;Done_sig表?#23616;?#21069;的操作是否完成的信号。驱动模块还有一个时钟发生器,由于驱动模块中的函数受到时钟的控制,因些需要一个时?#26377;?#21495;。
在驱动模块中包含2个方法。①execCycle(),该方法用于控制整个循环过程,所需执行的读/写操作都定义在这个函数里。该函数中有个全局静态变量用于控制每次执?#24515;?#20010;操作。每执行一次这个函数,该静态变量的值就会加1。函数体内部是一个个语句块,每个语句块的前面都有一个判断语句,该判断语句的作用就是比较静态变量是否增1,若判断比较相同,则会对各个信号线?#25345;怠?#35813;函数在时钟的上升沿到来时,会被调用执行;②memDone(),该方法用于输出显示一些信息,对信号Done_sig敏?#23567;?#24403;缓存模块中的读/写操作完成后,缓存模块会对Done_sig信号?#25345;担?#27492;时信号值发生变化,函数会被激活,DRAM模块会调用memDone()函数。
该模块中有一个非常重要的控制变量bool m_wait_Mem。在驱动模块的构造函数中将m_wait_Mem初始化为false。?#22791;?#21464;量为true时,若时钟的上升沿到来,函数execCycle()只会返回空语句,什么也不做;若为false,则执行execCycle中的语句块,在这个函数中,通过给信号线赋不同的值,可以执?#24515;?#24819;要的操作。由上可见,驱动模块就是操作的发起者,并在得到数据后,将其显示在屏幕上,用以测试结果正确与否。
三、路由模块
路由模块的功能就是实现消息包的传输。在路由模块内部含有一个队列,用于存储接收到的消息。一级缓存与路由之间通信的消息类型是一个pkt,这个消息类型中含有许多信息,包括存储缓存块的单元、标识发起这个消息模块的id、地址信息、以及一个控制变量表示该消息的作用?#21462;?
为了实现路由,在每个路由模块内部定义一个初始路由表。在路由模块实现了两个函数,一个函数的功能是根据方向选择输出链路,另一个则根据 链路选择输出方向。在路由模块内部定义的路由表,在构造函数初始化阶段进行初始化,给出不同id的路由的不同传输方向。由于整个路由规模比较小,因此初始化比较简单方便。路由策略是采用xy路由。当有多个核心时,就使用多个路由模块,各个路由模块按照xy方向排列成二维坐标方式,并在东西南北方向与其它路由模块相连接。每个路由模块?#24049;?#26377;一个标识id,通过这个id号通过调用函数能够得到路由模块的坐标,该坐标用于在xy判定策略中判断传输的方向。
一级缓存模块在时钟下降沿执行内部函数,执行读/写操作时,会向其它模块发送消息,于是就在模块内部将消息打包,并在同一时刻向路由模块发送过去,路由器于是将消息按照发送模块的优先级进行先后接收并放入队列中。当接收完毕后,路由模块从队头取出第一个消息进行处理,根据消息中的控制变量确定所需执行的操作是何种类型,并将该消息发送到指定的目地的。
如何判断一个消息已经发送到目地的?#30475;?#26102;,需要用到SystemC中的事件event机制。在一般的SC_METHOD函数中,就是通过事件机制挂起进程,?#24065;?#20010;事件发生时,它总是通过notify()函数通知所有等待该事件的所有进程。当某一事件被触发时,就从队列的队头取出消息转发给指定路由或其它模块。路由与各个核心之间的连接就是通过输入/输出信号线,信号线上可?#28304;?#36755;的数据类型就是消息。
路由模块的内部有一个fifo,用于接收其它模块传送过来的pkt。每个路由模块都有一个(x,y)坐标,当使用xy路由策略判断走向时,需要用到这个坐标信息。


由该函数可知,xy路由策略的判定方法就是通过比?#22799;?#22320;的的x、y坐标与当前发送者的x、y坐标值,根据判断结果得出传输的方向。
片上网络是通过路由器来实现的,在路由模块中含有多个信号线,每组信号线分别含有输入和输出两路,各组信号线连接着一个一级缓存模块。路由模块需要一个fifo,存储?#26377;?#21495;线中接收的消息。路由模块通过pkt消息与其它模块传递信息。pkt消息的定义如?#28388;?#31034;:

该结构体中的data用于存储消息中的数据,因为一个块中含有8个字,每个字有4个?#32440;冢?#22240;此数组中含有8个元素;id字段用于表示路由器的编号,在片上网络中,每个路由器都根据其位置给它一个编号,由id字段就可以确定消息是从哪个路由器发过来的;dest数组字段用于表示该信息需要发向哪些目地的,采用四核模拟的,且二级缓存中挂接到其中一个路由器上 的,所以该数组中含有5个元素;addr字段表示缓存行的地址;cur_addr表示缓存行的起始地址;change_data表示写操作的数据;index字段是个标记字段,其不同的取值含义如下:为0时,表示没有特殊功能;为1时,从二级缓存或DRAM中取块并返回给发送者;为2时,修改二级缓存及DRAM中相应块的内容,同时发?#36879;?#38500;自己之外的一级缓存,表示对某个地址执行了写操作;为3时,从二级缓存发给DRAM要求其刷新相应的缓存块;为4时,修改二级缓存及DRAM中的字,并将该字对应的块传?#36879;?#21457;?#36879;?#28040;息的源一级缓存;为5时,表示一级缓存未?#19994;?#26576;行数据,需要从其它一级缓存中查看是否有该数据。
在每个路由器模块的构造函数内部不仅需要定义各种必须的信号线,还需要给定一个默认的路由表,路由表中给出发往其它标号的路由模块时,应该选择哪个方向的链路传输过去,至于如何选择,就是xy路由策略的问题了。由于该路由模块由4个路?#19978;?#32852;,所以路由表会比较简单。
由于连接到同一路由模块存在很大的局限性,所以进一步扩展成由4个路由器相互连接通信的方式。在一个路由器的情况下,路由器模块定义一个struct fifo router_fifo,用来存储从其它模块发送过来的消息。该结构体的定义如?#28388;?#31034;:


fifo中需要定义pkt_in()和pkt_out()函数;由于有多个一级缓存与路由器相连,所以当它们向路由发送消息时,如?#26410;?#29702;这些消息成为问题的关键。为?#31169;?#20915;这个问题,采用事件sc_event机制维护同步,每个需要与路由通信的模块?#32423;?#24212;一个事件。与路由模块互连的多个一级缓存模块分别被给予优先级,连?#26377;?#21495;线上都标有数字。数?#20013;?#30340;模块优先级更高。每次路由模块都是采用轮询的方式将输入信号线中的消息存入队列中。
路由模块的构造函数中定义了信号线、事件、队列以及方法Process()和Process4()。第一个方法对4个一级缓存的输入信号以及时钟的下降沿敏感,当其中?#25105;?#20449;号发生变化时,都会激活这个函数的执?#23567;?#35813;函数定义成SC_THREAD(),内部含有无限循环。函数首先采用轮询的方式从in0~in3这4个输入端口中查看是否有事件发生,如果有输入信号,则将这些信号消息存入router_fifo中。当查完4根输入信号线后,若router_fifo不为空,则取出第一个消息进行处理,根据其index域判断消息是用于何种操作的。若index=1且dest[4]=1,表示该消息是要从二级缓存中取某行数据,将该消息写入out4中,送到二级缓存模块,并调用wait(event4)语句等待下级存储器返回取得的数据,当二级缓存接收到此消息后,对其中的地址进行分割,并判断所需数据是否在缓存中,如果命中,则将数据块存入pkt中的data域,并返回给路由模块;若未命中,则需要二级缓存发送消息到主存中取得块,?#32531;?#36820;回。若index=2,说明此消息只是告知下层的存储单元需要修改相应块的内容,则根据消息的dest[]域确定将消息发往哪个输出端口;index=3只是在二级缓存与主存模块之间用到,而路由模块不需要用到这个特征值;若index=4且dest[4]=1,表示某一级缓存请求某个地址中的数据,并且将该请求发?#36879;?#20854;它的一级缓存模块,查看该地址中的缓存行是否处于修改过状态,若是这样情况,就需要修改二级缓存及主存中的字,并将该字对应的块发?#36879;?#21457;出请求的一级缓存,所以直?#26377;?#21040;输出端口out4中。
Process4()对二级缓存模块的输入信号in4敏感,当输入信号发生变化时,就会执行这个函数。从in4中读取的消息中的index=1或者=4,则根据消息中的id域发往相应的输出端口。如果index=3,表示信息是发给DRAM 的,所以什么都不需要做。函数的最后会有一个事件通知,event4.notify(),所有等待该事件的进程将继续执?#23567;rocess()函数中就有wait(event4),此时,这个函数就会被激活,执行其后的语句。
当采用多个路由互连的方式进行通信时,问题将变得复?#21360;?#27599;个路由器都有一个编号id,该id需要实现与坐标之间的转换,转?#32531;?#25968;如?#28388;?#31034;:

尽管路由模块规模扩大了,但是可以将多个路由看成是一个整体。图2为多个路由互连结构图,四个路由器分别连接一个一级缓存,相互之间也是通过各?#20013;?#21495;线连接,每个路由模块内部都会定义一个变量router_id表示其标号。可以将所有的路由模块看成是一个整体的Top模块,在Top模块与前面的一个路由连接多个一级缓存非常相似,都是向外提供输入/输出信号线。因此,在这种互连结构下,可以采取与前面相似的方法?#21019;?#29702;信号的传输。只不过消息在Top模块内部会按xy路由方向转发。
在Top模块内部的某一路由接收到消息后,根据消息中的id域和dest[]数组中值为1的下标(确定目地的标号,并解析成坐标值),由xy路由策略判定传输方向。xy路由的判定方法是:如果目地的x方向坐标值更大,则向东边转发,否则,向西边转发;如果目地的y方向坐标值更大,则向南边转发,否则向北边转发。当某一路由模块接收到消息后,判定当前接收到消息的目地的是否与接收消息的路由router_id相匹配。如果相同,则根据消 息中的index域确定是传给其它的路由还是直接发?#36879;?#32531;存模块(包括一级和二级)。由上面的分析可知,路由器的作用只是将消息pkt?#22336;?#21040;各个不同的模块中,具体如?#26410;?#29702;由收到这些消息的模块完成。
私有cache和共享cache的实现
私有Cache为单个核所独?#23567;?#35813;Cache的存储实?#22336;?#24335;与单核下的Cache基本相同。驱动模块也是通过5根信号线实现与Cache的通信。不同之处在于,之前的单核下的缓存与总线的通信是通过端口连接到总线的接口,调用总线中实现的方法;在多核下,采用消息传输,一级缓存只需两根信号线直接连接到路由模块,消息的转发在路由模块内部实现。
一级缓存内部的存储结构较之前发生了变化,主要是缓存行状态的改变。单核下的高速缓存中的有效位只存在两种状态:有效或无效。而当前的一级缓存有3种状态,因此需要用2位来表示这三种状态:被修改、共享和无效。而且逻辑判断的过程较之前也有变化。在单核下只需要一个激励响应函数,只在时钟的下降沿被激活,而此时多核情况下,则需要额外增加一个对外来输入信号敏感的函数,该函数用?#21019;?#29702;从路由模块发送过来的信号。在单核下只有一个核会发起操作,而此时,如果远程其它的核有读/写操作时,也需要检查自己的一级缓存模块中的缓存行,如果有该缓存行,则需要根据远程操作的类型对本地缓存行进行状态转换或者是将缓存行中的数据写回主存中。
四、QEMU模块
CPU仿真器子系统是整个QEMU的核心,到目前为止它支持ARM、MIPS、PPC等多达15个体系结构。QEMU主要是处理APIC寄存器的?#21015;?#25805;作和处理器模块对于处理器间消息的处理。当发送信号STARTUP或INIT时,程序部?#21482;?#21521;某个地址处的寄存器写一个值,用于控制该寄存器的行为以发送信号,此时在QEMU中表现为以下步骤:
①TB块的执行函数中,解释器检测到指令INDEX_op_qemu_st32,包括三个参数t0、taddr和t2,它的含义是向taddr处写入值t0,其中使用MMU是t2。使用以上参数调用helper_stl_mmu函数。
②经过层层调用,会到达函数apic_deliver。该函数先根据dest_shorthand确定掩码(掩码用于屏蔽不该接收此消息的目标,也就?#20174;?了应该接收的目标),接着会根据递交模式判断应当发送哪一种消息,若递交模式是“STARTUP?#20445;?#21017;逐一调用apic_startup向未被屏蔽的目标发送消息;若递交模式是“INIT?#20445;?#21017;将环境结构的仲裁标识arb_id置为APIC的ID以便下一步的初始化。
处理器间消息发送之后,QEMU中该消息目的CPU进行执行时,才会对该消息进行处理。执?#24515;?#22359;会在每次准备执?#24515;?#20010;TB前期,会检测是否存在中断,并进行处理。若BSP向某个CPU发送消息STARTUP,则中断检测时应检测到中断CPU_INTERRUPT_SIPI,此时会调用do_cpu_sipi用于后续行为的仿真。它将进行以下工作:
①清理中断位CPU_INTERRUPT_SIPI。
②如果wait_for_sipi标记为假,说明CPU还没有执行INIT操作,退出执行;否则进入③执?#23567;?
③调用cpu_x86_load_seg_cache_sipi进行CPU各种寄存器的设置。其中最重要的是以接收消息中向量的来决定该CPU启动后第一条代码的地址。
若检测到的中断为CPU_INTERRUPT_INIT,QEMU会进行CPU的一些重置工作,用于?#25351;碈PU的初始状态。
QEMU模拟的处理器模块与存储系统模块之间的通信系统主要包括三个部分:QEMU消息源,通信信道和互连模块。QEMU中消息源是产生通信的源头,它可以分为两大类。一类是处理器节点,另一类是外部设备。不同的消息源使用不同的通道发送消息。消息源的不同体现记录在消息结构的某个字段中。通信信道是连接QEMU和SystemC两个子系统的纽带。由于QEMU和SystemC分别通过一个进程来实现,应当使用进程间进行连接。互连模块是仿真器中较为重要的模块。互连模块起到信息传递的,它是用SystemC来实现的。在本系统的实现中,使用SystemC实现了一个简单互连模块。
五、仿真试验结果
本实验环境采用ubuntu12.04,使用SystemC作为编程语言,其内核作为整个系统的仿真内核,vim作为编辑器,gcc作为编译器,文件中含有多个.h和.cpp文件,所以编写Makefile文件简化编译过程。编译程序的时候需要 包含SystemC?#28304;?#30340;include文件和lib-linux,目的是告诉编译器去include下寻找所需要的头文件,即systemc.h;以及告诉连接器去lib-linux下寻找所需的库文件声明。
在多核下,为主存分配1MB的存储空间,为二级缓存分配1KB的存储空间,共有16个缓存块;为一级缓存分配256B的存储空间,共有4个缓存块;一级缓存与二级缓存都是采用二路组相联结构。
在多核下,四个驱动模块执行的操作分别为:读地址4,读地址4,读地址8,读地址12;第二组操作为:写地址1536(写入的数据为1537),读地址1536,写地址12(写入的数据为13),读地址12。
第一组操作之后,所有已存在的缓存行的状态?#21152;蒊->S。第二组操作中,对于地址1536所在的块,会被存入第一个缓存块的第二路中,写过之后其状态为M。随后,标号为1的一级缓存读取该地址的数据,这两个缓存中的状态都将变为S。2号一级缓存在对已存在的缓存行中的某个?#32440;?#34892;写操作,写过之后,其状态变为M,而其它一级缓存中的数据变“脏?#20445;?#38656;要将状态由S->I。?#32531;?号缓存再读地址12时,状态为I,就发送消息到其它模块查看是否有数据,发现2号一级缓存中有修改过状态的缓存行,?#32531;?号就将数据写回主存,主存返回一份数据块给3号缓存,?#32531;?#20854;读取所需要的字。
时间分析:多核下传送数据的时间明显比单核下快,采用路由器作为互连,一级缓存模块是在时钟的下降沿被激活,而其它模块都是通过信号线激活,信号线的触发机制是:一旦有信号发生变化激活函数就会被执?#23567;?#36825;个过程可以在一个很小的时间?#26144;?#20869;完成(即delta时间)。而单核下的互连需要考虑总线的阻塞传输,阻塞传输一个块时,每次总线操作只负责一个字,所以需要总线等待多次之后,一次块的传输过程才结束。
上述实例只为说明本发明的技术构?#25216;?#29305;点,其目的在于让熟悉此项技术的人是能够?#31169;?#26412;发明的内容并据以实施,并不能?#28304;?#38480;制本发明的保护范围。凡根据本发明精神实质所做的等效变换或修饰,?#21152;?#28085;盖在本发明的保护范围之内。

关于本文
本文标题:基于片上网络互连的多核存储系统仿真器.pdf
链接地址:http://www.pqiex.tw/p-6115949.html
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网?#31350;头?/a> - 联系我们

[email protected] 2017-2018 zhuanlichaxun.net网站版权所有
经营许可证编号:粤ICP备17046363号-1 
 


收起
展开
平码五不中公式规律 四维图新股票行情 福彩开奖直播 123期大乐透开奖历史记录 河北快乐扑克3走势图 股票推荐公众号 宁夏十一选五 贵州十一选五前三直走势图 开元棋牌app在哪下载 大乐透139期历史汇总 重庆幸运农场推荐