DSP指令集仿真器的设计与实现

2012-01-15 06:02史彦芳
电子设计工程 2012年15期
关键词:指令集存储单元仿真器

刘 静,史彦芳,孔 黎

(西北工业大学 电子信息学院,陕西 西安 710072)

在构建一个新系统时,为了有效地测试和验证新系统的行为和正确性,通常需要对此新系统进行仿真。系统仿真包括软硬件结合仿真和软件仿真,其中,软件仿真由于其具有脱离具体的硬件,便于调试的优点,而得到广泛的应用。

所谓软件仿真是指通过软件的执行来模拟硬件行为的一种方法。软件仿真器是在宿主机上运行并能模拟目标机器行为的一种软件系统。

利用软件仿真器,硬件生产厂商可以在构建系统之前就对其正确性及性能进行验证,从而使得软件开发商可以在硬件生产出来之前进行软件开发使得软硬件可以同时面世,从而大大降低了开发时间。

与此同时,软件仿真器具有执行速度低的缺点,因此如何提高指令集仿真器的执行速度成为指令集仿真器的一个研究课题。文中首先介绍了指令集仿真的实现策略,并对基于ZWFcore的DSP指令集仿真器具体设计与实现做了阐述。

1 指令集仿真策略

指令集仿真器是最基本的软件仿真器。目前最流行的指令集仿真器实现策略[1]有3种:基于解释的指令集仿真策略、基于编译的指令集仿真策略和混合指令集仿真策略。

1.1 解释型指令集仿真器

解释型指令集仿真器是基于解释的指令集仿真策略来实现的仿真器。它通过在内存中建立一个数据结构来模拟目标处理器的状态,然后进入一个循环,循环体包括取值、译码、路由、执行4个基本的步骤。如图1所示。

图1 解释型指令集仿真Fig.1 Interpreted instruction set simulator

其中取值是从内存中将一条指令字取出,译码是通过相应的掩码取出指令字中的操作数和操作码,然后通过路由根据操作码选择到相应的执行函数,再有对应的执行函数完成对操作数的操作。从而完成对一条指令的的仿真。其优点是,设计简单且灵活性好,但完成一个周期的时间较长。

1.2 编译型指令集仿真器

编译型指令集仿真器[2-4]是基于编译型指令集仿真策略来实现的仿真器。它在程序执行之前,首先对程序进行编译处理,把每一条目标机指令转译成一组宿主机指令,在实际运行时直接使用那一组宿主机的指令代替那条目标机的指令来完成处理器状态的修改,如图2所示。编译型指令集仿真器具有较高的模拟速度,但它对宿主机过分依赖使得其通常只用于宿主机和目标机体系结构相近的模拟器中。

图2 编译型指令集仿真Fig.2 Compiled instruction set simulator

解释型指令集仿真器能够精确地模拟指令执行过程中各个部件的状态,具有良好的扩展性,因此可以方便地在模拟器外部扩充调试其和程序分析器。另外,由于指令解释部分采用高级语言的函数来实现,使得模拟器便于向其他宿主机移植,故本文采用解释型指令仿真策略来模拟指令的读取、译码和执行过程。

2 仿真器的总体设计与实现

2.1 主要功能

ZWFcore是一款高性能通用DSP核,支持多种片上系统(SOC)。其主要应用于通信、图像处理及视频处理领域。DSP指令集仿真器(ZWISS)是运行在ZWFcore平台之上,基于解释型指令集仿真策略对ZWFcore指令集进行仿真的仿真器。其首先在内存中建立一个数据结构来代表目标处理器的状态,并将可执行的指令加载到内存开辟的存储结构中,然后进入一个处理循环。它有效地对ZWFcore的存储器、及存储器的访问、指令集流水线及中央处理单元进行了模拟,并通过设计server模块,在server上完成了对ZWFcore上的开发程序的调试。

2.2 总体设计与实现

为实现上述功能,基于ZWFcore的DSP指令集仿真器[5](ZWISS)主要可以分为7个模块,分别为:初始化模块、加载模块、译码模块、路由模块、中央处理单元模块、多级存储器模块、MMU模块、MPS模块、PMA模块和调试代理rsp_server模块。其中MMU模块、MPS模块和PMA模块是可选的模块。根据硬件的设计需求来决定是否启用相应的模块。

2.2.1 初始化模块

在启动zwiss时,需要对多级存储单元模块的类中生成对象按照硬件启动时应该具有的状态进行初始化设置,并且对其他各模块进行初始化,因此需要初始化模块完成这个功能。

具体地,初始化模块主要完成以下几项任务:

1)对多级存储单元的初始化:多级存储单元的初始化包括对寄存器的初始化和内存的初始化,其可以通过通过加载模块对elf头文件中的信息进行解析,获得相应的系统初始化的参数后,对多级存储单元中的特殊寄存器和内存的值分别进行相应的初始化,其他寄存器可以赋为0。

2)对译码模块的初始化:主要是将配置文件中的信息存储到向量表中,这样可以使代码的重用性大大提高。

3)对路由模块的初始化就是对函数指针数组的初始化,由函数functionmap()来完成。

2.2.2 加载模块

加载模块[6]是在ZWFcore指令集仿真器初始化模块运行后,在译码模块运行之前运行的模块。加载模块用于解析elf文件,提取相关信息包括其头信息和此文件涉及的指令,将提取的信息存储到多级存储单元中。加载模块是中微一号指令集仿真器运行的基础,是后面译码、路由、执行函数的先决条件,只有加载了信息后,中微一号指令集仿真器的运行才有意义,才能够验证指令仿真的正确性。

设计加载模块前,首先要区分文件是否为ELF文件,根据文件的格式,提取指令信息。从ELF文件信息中分析出需要将指令信息加载到代码区或者数据区的具体问题,然后将提取出的信息加载到代码区或者数据区中。

2.2.3 译码模块

译码模块实现对指令中操作码和操作数的提取。从多级存储单元中提取指令,然后经过译码模块的解释,将操作数和操作码提取出来,根据操作码定位到对应的指令序号,将操作数和指令序号存入到操作数结构体中,为后面的指令的运行提供了保证。

译码模块主要完成以下工作:

1)将指令和指令掩码按照顺序依次进行掩码操作,判断出指令的类别,然后根据指令的类别,和特征码进行匹配,如果特征码相同,即完成了操作码的定位,将其定位到特定的指令序号。

2)由于前面初始化的过程中已经建立了操作数的初始化列表,并且定位了指令中具体的比特位的是第几个操作数的比特位,所以可以根据这些定位从指令中提取出操作数,并将操作数按照顺序存放到定义的vector中。

译码模块将操作数存在vector中,故定义如下的结构体:

struct operand_struct

{

int instruction_index;//指令序号

vectoroperands_list;//操作数列表

};

该结构体包括指令序号和操作数列表信息。其中操作数列表中包含了从指令中提取的操作数的信息。

同时译码模块定义了opcoder类,其流程图如图3所示。

图3 译码流程图Fig.3 Flow chart the decoder design

文中采用了基于决策森林的二进制指令译码算法,其思想是先构建一决策森林,当一条待译码指令字进入译码入口后,按照决策森林中的第一棵决策树对应的指令掩码计算出其可能的指令决策码,在决策树中寻找,找到则识别完毕,译码成功退出,否则依次遍历所有的决策树,直至译码成功退出,若还未匹配则说明该指令字不合法,译码失败退出。

2.2.4 路由模块

路由模块是紧跟译码模块之后的模块,主要根据译码所得的指令序号,路由到中央处理单元的相应处理函数来处理。

路由模块的实现是通过定义一个函数指针数组,此数组的结构如下:

Int(*function_map[765])(struct operand_struct&);

其中*function_map为定义的指针数组,765为指令的个数,struct_operand_struct代表的是操作数结构体。

2.2.5 中央处理单元模块

中央处理单元模块是整个仿真器的核心部分,其本质是一个函数集,主要完成的是将ZWFcore所有的指令用C++语言的函数来实现,每条指令根据指令集中给出的定义对相应的多级存储器进行访问或修改。

为了方便整个系统的调用,中央处理单元针对每条向外部提供了接口,这些接口的命名如下:

int ins0(struct operand_struct operand&);

int ins1(struct operand_struct operand&);

……

由于这些函数采用了统一的参数,即由译码模块提供的指令操作数,故使代码的编写更加规范,同时降低了出错概率。

2.2.6 内存管理单元模块

内存管理单元(MMU)模块是可选的模块,其实现的是虚拟地址与物理地址的转换功能(详见图4)。从而避免不同的指令执行过程中访问同一物理地址。

MMU的实现主要是将虚拟页表映射到物理页表。通过查找TLBs来实现这种转换。而TLBs是由操作系统填充的,用户不能随意更改。

2.2.7 存储保护系统模块

通过定义一对存储器,用来存放可以读写的内存的上下界的地址,从而来限定用户访问的内存范围。它是一种基于地址的保护,保障了系统的安全性。

图4 虚拟地址转换Fig.4 Virtual addressing translation

2.2.8 物理内存属性模块

物理内存属性模块(MPS),其主要功能是对内存中的各个段进行划分,规定其特殊的属性,包括外设属性(Privileged Peripheral(P)),可缓存(Cacheable (C))

投机性(Speculative (S)),代码可读(Code Fetch (F)),数据可访问(Data Access(D))。这是一种基于段的保护,防止对一些地址的非法访问。

2.2.9 多级存储器模块

多级存储单元模块主要完成的是对ZWFcore的寄存器组、主存和cache进行管理。在指令仿真执行的过程中通过调用该模块完成对寄存器以及主存的修改与读取。这里我们将其寄存器组合主存抽象成一个类,故对主存和寄存器的修改和读取可以看作是对该类对象的相应的操作。

在多级存储器模块中,ZWISS采用了虚拟页表来仿真ZWFcore的主存,每个页64 kB。由于ZWFcore的地址是32位,故我们将其告16位作为其页地址,低16位为其页内地址。这种方式与单纯使用“地址-值”的方式相比,具有查找次数少,用时短的优点。

该模块对外提供了很多接口,主要是完成其他模块对寄存器和内存的访问和修改。

这些接口的设计须满足通用性、高效性、高内聚和低耦合,并且应在实现相应功能基础上,具有较好的扩展性。

该类的设计表示如下所示:class MLSS

{

public:

//程序状态字寄存器

unsigned int PSW;

//程序计数器

unsigned int PC;

private:

//资料寄存器

union reg data_reg;

//地址寄存器

union reg addr_reg;

//代码区

std::mapdata_men[16];

//数据区

std::mapcode_men[16];

public:

int get_reg32bit (int reg_type, int reg_ID, unsigned int&val);//读 32 位

int set_reg32bit (unsigned int val, int reg_type, int reg_ID);//写 32 位

……

}

其中,在读写内存时,根据MMU、MPS、以及PMA的存在与否,来进行对将要操作的地址进行判断,看其是否允许被操作,在进行相应的操作。其具体的操作如图5所示。

图5 地址的翻译过程Fig.5 Progress of the addressing translation

2.2.10 调试代理模块

调试代理模块即server模块,相当于ZWISS仿真器与调试器GDB的接口。其用于解析调试器GDB发出的调试命令并调用仿真器进行相应的处理,同时将结果返回给调试器GDB。

Server模块通过RSP协议与GDB进行通信,针对RSP协议中的指令,在server模块中设计了ZWDPI(中微一号调试编程接口)。在ZWDPI中提供最精简的调试编程方法,包括设置断点,移除断点,读/写全部寄存器,连接主机等。这些方法函数保证了server模块通过方法的组合执行GDB发出的所有命令。

2.2.11 陷阱模块

陷阱模块提供了各种陷阱的接口。其实现是通过定义一个类,在程序执行过程中,当发生陷阱时可以调用此模块中的类成员函数来实现相应的处理。

3 部分模块的性能分析

模拟器的好坏直接由各个模块的性能决定,因此对各个模块性能分析成为设计的一个主要部分,现对主要模块的性能分析如下。

3.1 路由模块的性能

路由模块主要是利用函数指针指向对应的中央处理单元的执行函数,因此其具有较高的性能,时间复杂度仅为O(1)。

3.2 中央处理单元的性能

中央处理单元是整个模拟器的核心单元,其性能的好坏直接影响模拟器的正确性和执行速度,故其是否能准确的解释指令,并且用最短的时间来实现指令,成为我们关注的核心。在用C语言实现中央处理单元时,要尽可能使用执行速度高的编码,如:尽量使用比较简单的移位操作而避免使用与或操作。这样大大提高此单元的执行速度和可靠性。

3.3 多级存储单元的性能

多级存储单元在实现上,采用了动态申请空间的方式而不是一次性申请所需的模拟大小的内存空间,这使得多级存储单元的空间复杂度大大降低,同时,在对寄存器和内存进行读写操作时,使用较少的循环操作,提高了多级存储单元的时间复杂度。

4 结 论

文中实现对ZWFcore的仿真,在对其进行指令集仿真的基础上,通过对其体系结构的升入分析,对其特殊模块如MMU、MPS、PMA单元进行了仿真,实现了对内存的保护和更加真实的模拟了硬件的实现情况。同时,增加了调试代理模块为仿真器的调试提供了接口,便于挂接其他的调试模块。

[1]俞甲子,石凡,潘爱民,等.程序员的自我修养[M].北京:电子工业出版社,2009.

[2]谭华.嵌入式系统软件仿真器的研究与实现 [D].成都:电子科技大学,2005.

[3]Reshadi M,Mishra P,Dutt N.Instruction Set Compiled Simulation:A Technique for Fast and Flexible Instruction Set Simulation [C]//Design Automation Conference,2003:758-763.

[4]A Nohl et al.A Universal Technique for fast and Flexible Instruction-Set Architecture Simulation[J].IEEE Transaction on Computer-Aided Design ofIntegrated Circuitsand Systems,2002,123(12):1625-1639.

[5]S Pees et al.Using Static Scheduling Techniques for the Retargeting ofHigh Speed, Compiled Simulators for Embedded Processors from an Abstract Machine Description[C]//The 14th International Symposium on System Synthesis,2001:57-62.

[6]陶峰峰,付宇卓.DSP指令集仿真器的设与实现[J].计算机仿真,2005,22(9):225-228.TAO Feng-feng,FU Yu-zhuo.Design and implementation of DSP instruction simulator[J].Computer Simulation,2005,22(9):225-228.

猜你喜欢
指令集存储单元仿真器
基于Kubernetes的RISC-V异构集群云任务调度系统①
一种28 nm工艺下抗单粒子翻转SRAM的12T存储单元设计
3DNow指令集被Linux淘汰
一种新型密集堆垛式仓储系统设计
AI仿真器将大大提高科学领域的仿真模拟速度
浮点类型有效位数计算与应用分析
数据在计算机内存中的存储形式及实验验证
基于多用户无线仿真器系统的研究
实时微测量系统指令集及解析算法
分析利用仿真器(RTDS)测试小电流接地选线装置的可行性