当前位置:智城范文网>范文大全 > 征文 > 周期精确的指令集模拟器(ISS)的建模与封装方法

周期精确的指令集模拟器(ISS)的建模与封装方法

时间:2022-03-24 09:04:33 来源:网友投稿

摘要:本文首先介绍了指令集模拟器(ISS)的原理与应用,提出了在ISS的建模过程中所要处理的主要问题。然后以ARM7为例讨论了使用C++语言建立周期精确的指令集模拟器的方法。并使用了SystemC封装的方式来解决ISS同系统中其它模块的信息传递和时钟同步问题。将封装后的ISS同存储器一起挂接在AHB总线上,建立了简单的仿真平台。

关键词:指令集模拟器(ISS);周期精确;ARM;SystemC;封装

中图分类号:TN402 文献标识码:A

1、引言

软硬件协同验证是目前嵌入式系统的系统级设计中一项极具挑战的任务。一个准确的协同验证模型不仅可以对系统进行仿真,而且可以在设计初期给出系统的性能参数。处理器是构成系统的重要模块,所以在嵌入式系统的系统级设计中建立支持软硬件协同验证的处理器模型是系统级模型构建的一项重要工作[1]。SystemC这种语言具有对处理器进行建模的能力[2],但是采用C++建立的处理器模型则具有更加灵活的特性和更广泛的使用空间。因此使用C++建立处理器的指令集模拟器(Instruction set simulator,简称ISS),再将其封装到SystemC的模块中,形成的系统模型中使用的处理器模块,不仅具有C++的各种优良特性而且易于集成到系统中。

2、 ISS的建模

处理器的ISS模型按照它所能够提供的仿真精度的不同通常可分为两种基本类型[3]:指令精确(IA,Instruction Accurate)的ISS模型和周期精确(CA,Cycle Accurate)的ISS模型。IA的ISS本身不能提供指令执行过程中与时间相关的细节。相对于IA的ISS,CA的ISS要复杂的多,但是能够充分体现处理器的时序特性,从而能够提供真实运行时间,区分算法优劣,判断体系结构是否符合预期设想。

2.1 所要解决的主要问题

周期精确的ISS模型在仿真时不仅要保证程序的正确执行,而且需要精确地刻画处理器各部分在每个时钟周期的行为。如果处理器具有并行特性,例如指令流水,那么ISS必须能够在每个周期“并行地”对多个不同的指令进行取指、译码、执行等操作。并且对异常情况例如中断处理的操作也要具有周期的特性。所以构建周期精确的ISS模型在本质上就是让处理器内部并行部件具有逐周期的交互能力。周期精确的ISS处理器模型在接口界面上提供了每个时钟周期内处理器的行为细节,包括了访存通信和流水线运行的效果。周期精确的ISS模型在核心的实现上是:以时钟为周期的无限循环结构。ARM7使用的是三级流水线,ISS的核心函数每周期所需“并行地”操作如图1所示。

图1 ISS的核心函数每周期的“并行”操作

但是在执行多周期指令和访存操作时,流水线就会发生中断变得不太规则。

2.2 ARM7指令集模拟器的结构

从整体结构上主要分为两层:核(Core)和处理器(processor),如图2。在这里均采用类的形式对它们进行设计。其中Core是ISS的核心,完成流水线操作,Processor调用了类Core,实现处理器中其它部分的功能,并提供至封装的接口。

图2 ISS结构图

在功能上可以分为以下部分:ARM7三级流水线的仿真函数;ARM7体系结构中所使用的MMU;指令)Cache)和数据(Cache);异常情况的处理。

2.2.1三级流水线仿真函数的设计

取指操作 取指令就是将存储器中的指令放入指令流水。指令地址有多个来源:指令指针寄存器的自加、来自于寄存器堆的跳转地址、由ALU总线给出的跳转地址。为了保证流水线的正常运行,每执行完一条指令就要有一条新的指令进入流水。所以是否进行取指操作,就要由这一周期的执行操作决定。同时要求在一个周期内只能有一条指令对存储器进行操作,所以在执行存储器读写指令时,前面的指令具有总线的使用权,对于后面指令的取指操作将被推迟。

译码操作 指令译码是为下一个周期准备数据通道的控制信号。在这一级指令占有译码逻辑不占用数据通道。对于多周期指令它的执行需要多个时钟周期,这时译码逻辑就要被一条指令占用多个周期,后面指令的译码被推迟。

全局译码函数为Decode( )。ARM采用的是32位定长指令,指令主要分为数据处理、转移及链接、存储器读写、协处理器指令、软件中断、交换指令等六类[4]。每一类的ARM指令都具有自身的特点,可以采用掩码模板的方法,先将指令分成不同的类型,再调用相应的译码子函数将指令分成不同的域并产生相应的控制信号。这样可以提高译码速度,而且实现起来更灵活。例如在ARM的指令集中转移及链接指令的25-27位为101,使掩码BRANCH_MASK的值为0x0E000000,同指令相与如果等于BRANCH_SIG=0x0A000000就说明此为转移及链接指令。

if((instruction&BRANCH_MASK)==BRANCH_SIG)

DecodeBranch( );

对于有多种编码格式的指令类型,要根据hash和tag信息来进行区分。例如数据处理指令根据第二个操作数的来源和是否进行移位可以分为三类,在对其解码的时候采用以下方式:

if (i.dpi1.hash == 1){ }

else if (i.dpi2.pad2 = 0)){ }

else{ }

执行操作 Exec( )根据译码逻辑提供的控制信号读取寄存器堆、将操作数移位、ALU产生结果并写入指定的寄存器、更新CPSR和SPSR、占用A,B总线,ALU总线等数据通道。

Exec( )

{a_bus = ctrl->rn;//更新A总线数据

switch (ctrl->b){ }//更新B总线数据

if(ctrl->shift_reg){ }//是否进行移位

switch(ctrl->ai){ }//更新ALU_A总线数据

switch(ctrl->bi){ }//更新ALU_B总线数据

res_bus=(ctrl->opcode,alu_a,alu_b,Flags);

//计算结果

if (ctrl->updates & UPDATE_XX){ }

//更新状态寄存器

m_regsUser[ctrl->rd] = res_bus;//回写

……}

由于C++语言本身是顺序执行的,并不具备并行机制,所以在这里要采取一定的方法来模拟出取指、译码、执行等并行操作。首先要定义全局变,量保存各指令各流水段执行的状态信息,以便在下一个周期可以正确的完成流水的下一步工作。其次就是要将各种不同情况下,一个周期内所要完成的任务顺序的进行描述。这里的重点在于描述的先后顺序和各段执行的条件。这样在每个周期可以根据状态信息有条件的选择所需要的语段运行。比如,当执行访存操作时,将会占用总线,造成的流水线阻塞,导致取指操作的推迟。在流水线的仿真上按照ARM的定义设置标志位,通过对标志位的检查来确定哪部分应该是活动的。这样就可以使每个周期的取指、译码、执行操作在不发生冲突的时候执行。

2.2.2 MMU和缓存(Cache)仿真的实现

ARM7体系结构中所使用的MMU的主要功能是完成虚拟地址到物理地址的转换以及控制存储器的访问。在ISS中地址转换功能是通过地址转换函数实现的。在控制存储器的访问和对缓存的管理上则要通过状态机来实现。对于这种寄存器、缓存和存储器的访问方式如图3。

图3 存储器访问方式

Core给出地址提出读要求,MMU查看Cache是否命中,命中则直接从Cache读入。若Cache没有命中则Core进行NOOP,等待MMU从存储器中读取指令数据,送入Core并写入Cache(如果是可Cache的),Core继续工作。实现这种读写控制的状态机如图4。

图4 读写控制状态机的状态转换图

2.2.3 异常情况的处理

如果处理器在执行程序时发生了意外事件,则应该采取相应的处理机制来进行处理。

对于未定义指令引起异常的处理方法:进入相应的处理模式;将引起异常指令的下一条指令的地址保存到新模式的R14;将CPSR保存到新模式的SPSR中;禁止中断;将跳转指令的地址赋给PC,实现跳转。

在处理器模型中使用create_vector( )函数来生成一系列的控制信号完成异常情况下指令的跳转。

ARM7拥有7种不同的模式,分别使用不同的寄存器组,共有37个寄存器。为此在ISS中建立多个数组作为寄存器组,不同模式所使用的寄存器对应不同的数组。使用函数return(m_regsPBank[m_mode & 0xf][reg]);来读取相应的寄存器。

3、ISS模型的封装

将ISS集成到系统中时可以使用进程间通信(interprocess communication,简称IPC)机制和总线封装方式。但前者在总线操作增多的情况下,阻塞增加,仿真速度将会下降。而使用SystemC封装的ISS模型,在SystemC仿真器下能够直接和总线上其它模块进行通信[2]。

SystemC的基本特性:SystemC提供了完善的时间机制和并行机制,可以描述复杂系统的交互行为。SystemC提供了两种用于描述功能的进程:SC_METHOD和SC_THREAD。SC_METHOD进程在运行完成后退出运行,并将控制权返还给仿真器内核。因此这种进程不能挂起,也不能含有无限循环。SC_THREAD进程可以使用wait( )方法将进程挂起,根据延时或敏感条件的发生来恢复执行。

将ISS封装到SystemC模块中要处理ISS同系统中其余硬件模型之间的通信和同步的问题,因为封装模块的一边是ISS的C++数据类型而另一边是硬件描述中的数据类型。封装模块还要将ISS核心函数运行的结果转化为精确至周期的SystemC事件。封装后的ISS包含一个由时钟触发的进程,每次触发使ISS的核心函数运行一次,执行相应的操作,由此实现ISS同时钟的同步。

SC_MODULE(armsystem)

{CArmProc* pArm;

sc_in_clk clock;

//ISS的输入输出信号

void startsimul( );//由时钟触发

SC_CTOR(armsystem){

pArm = new CArmProc(name( ));//例化

SC_CTHREAD(startsimul, clock.pos( ));

}

};

void armsystem::startsimul( )

{……

pArm->Cycle(&pinout, intforw);

if (pinout.benable == 1)

{……}//总线上的数据传输

……}

4、 仿真

将封装后的ISS模型挂接在AMBA AHB[7,8]总线上,加上RAM存储器模型建立仿真平台,如图5所示。使用交叉编译工具生成测试程序的目标代码,将其加载到存储器中由ISS执行。使用矩阵排序作为测试程序,总线读写操作波形如图6所示。排序前后矩阵的内容如表1。从图6中我们可以看出,由于排序程序使用的是相同子函数重复调用的方法而且程序又很小,可以完全存储于缓存之中,这样只有在对第一个数进行排序时需要访问存储器,节省了很多时间。并且随着排序的进行,未被排序数的减少,每个数字的排序时间依次减小。

表1 排序前后矩阵的内容

图5 由ISS,存储器和总线构成的仿真平台

图6 总线的读写操作

5、 结束语

使用C++语言对指令集模拟器进行建模的主要难点在于周期精确的流水线的设计和对于指令集的理解。由于C语言广泛的应用以及高效的表达方式使得软件的开发以及软硬件的协同验证变得方便。在软件验证阶段,可以通过减少Log信息的输出来减少仿真时间。

参考文献

[1] Luca Formaggio, Franco Fummi, Graziano Pravadelli. A timing-accurate HW/SW cosimulation of an ISS with SystemC [J].CODES+ISSSW. 2004,September:152-157.

[2] Open SystemC Initiative. SystemC v2.0.1 Language Reference Manual[EB/OL]. ,2000.

[7] 刘军,郭立,段勃,等. AMBA 2.0总线IP核的设计与实现[J]. 微电子学与计算机, 2005,22(6): 145-148

[8] ARM Limited, AHB CPU Wrappers Technical Reference Manual [EB/OL]. ,2001.

推荐访问: 模拟器 建模 封装 精确 周期

版权所有:智城范文网 2010-2025 未经授权禁止复制或建立镜像[智城范文网]所有资源完全免费共享

Powered by 智城范文网 © All Rights Reserved.。粤ICP备20058421号