|
||||
|
||||
摘要
NiosII
是一个建立在
FPGA
上的嵌入式软核处理器,灵活性很强。作为体现
NiosII
灵活性精髓的两个最主要方面,自定义外设和自定义指令的性能开始受到越来越多开发者的关注。本文在对
NiosII
自定义外设和自定义指令进行深入研究后,采用实验的方法,通过实例
CRC32
对比了在实现相同功能的情况下,自定义外设和自定义指令的性能差异,并从自定义外设和自定义指令的实现机理上给予说明。分析结果表明:
在
SOPC
系统中,如果系统的实时性要求非常高,那么采取自定义外设来实现系统中关键处理模块无疑是最佳选择。
关键词
自定义外设
自定义指令
CRC
校验
性能分析
SOPC
引言
NiosII
是一个嵌入式软核处理器,除了可以根据需要任意添加已经提供的各种外设以外,用户还可以通过定制自定义外设和自定义指令的方式来满足各种应用需求。定制用户外设和用户指令是使用
NiosII
嵌入式软核处理器的重要特征。定制的用户外设能够以
“
硬件加速器
”
的形式实现各种各样用户要求的功能;同时定制的用户指令,可以把一个复杂的标准指令序列简化为一条用硬件实现的单个指令,以增强对实时软件算法的处理能力。近来,随着国内
SOPC
开发的逐步深入,这两者的性能开始成为一个关注的焦点。本文通过
CRC32
对
SOPC
系统中的自定义外设和自定义指令的实现以及对性能差异所作的详细分析,给广大
SOPC
开发人员提供参考。
1 CRC
自定义外设的实现
1.1 SOPC
系统中自定义外设的组成和结构
自定义外设作为
NiosII
软核处理器超强灵活性的体现,其开发遵循一定的规律。一个用户自定义外设必须进行硬件设计,也就是说,必须用硬件描述语言来描述出硬件的逻辑组成。一般来说,一个自定义外设主要由下列部分组成:
①
描述自定义外设逻辑的硬件描述文件部分(主要是
HDL
程序)。
② 软件文件,一个用来定义外设寄存器的 C 语言头文件,以及让程序员控制这个元件的软件驱动程序。 ③ 元件的描述文件( class.ptf )。该文件定义了元件的架构,提供了 SOPC Builder 将该元件集成到一个系统的各种信息。该文件由元件编辑器根据用户提供的硬件和软件文件以及在图形用户界面中设置的各个选项和参数自动生成。图 1 给出了带 Avalon 从端口的自定义外设组成框图。 图 1 带 Avalon 从端口的自定义外设组成框图
从图中可以看出,一个典型的自定义外设主要由下列功能模块组成:
①
任务逻辑。任务逻辑实现外设的基本功能,是必不可少的组成部分。
② 寄存器文件。寄存器文件部分提供任务逻辑和外界交换信息的桥梁。有了寄存器文件,用户就可以通过 Avalon 接口采用 “ 基地址 + 地址偏移量 ” 的方法来访问外设内部的各个寄存器。 ③ Avalon 接口。 Avalon 接口为寄存器文件提供了一个标准的 Avalon 前端。该模块使用 Avalon 规定的信号来访问寄存器文件,并且支持任务逻辑的传输类型。
1.2 CRC32
自定义外设的实现
CRC32
校验可以由软件或硬件来实现。现多采用超大规模集成电路芯片以硬件方式实现。例如:
其硬件实现原理如图
2
所示。
图 2 CRC 硬件实现原理
编码运算过程如下:
开关关闭,
k
位数据移入寄存器,同时送到外部。当
k
位信息全部送到外部时,除法运算也正好进行完毕,寄存器中的
r
位数据就构成了余项的系数序列,即形成了校验码。然后切断除法反馈电路,将移位寄存器的每一位逐次输出到信道中。这些校验码与原来的数据位一起构成了完整的码字。
采用
HDL
语言来描述出
CRC32
的硬件实现,命名为
crc.v
。在
SOPC Builder
元件编辑器中加入该元件
,
其中自定义外设的接口信号和
Avalon
信号类型的一一对应关系如表
1
所列。
表
1 CRC
接口信号和
Avalon
信号类型的对应关系
当把自定义外设加入到
SOPC
系统中时,系统自动生成一个
system.h
文件。在
system.h
中生成的
CRC
自定义外设的相关信息如下:
#defineCRC_NAME "/dev/crc"
#defineCRC_TYPE "avalon_crc" #defineCRC_BASE 0x06210880
根据
system.h
中的信息,可以建立名称为
altera_avalon_crc_regs.h
的寄存器头文件。在这个
C
头文件中,用清晰的宏符号描述出设备的寄存器集合,并且给出其访问方法。
#ifndef __ALTERA_AVALON_CRC_REGS_H__
#define __ALTERA_AVALON_CRC_REGS_H__ #include #defineCRC_WRITE_REG4 #defineCRC_READ_REG016 #defineCRC_READ_REG120 #defineCRC_READ_REG224 #defineCRC_READ_REG328 #defineCRC_INITIALIZATION(base) IOWR_32DIRECT(base, CRC_INIT_REG, 0) #defineCRC_WRITEDATA_8(base,data) IOWR_8DIRECT(base, CRC_WRITE_REG, data) #defineCRC_WRITEDATA_16(base,data) IOWR_16DIRECT(base, CRC_WRITE_REG, data) #defineCRC_WRITEDATA_32(base,data) IOWR_32DIRECT(base, CRC_WRITE_REG, data) #defineCRC_READRESULT_32(base) IORD_32DIRECT(base, CRC_READ_REG0) #defineCRC_READRESULT_64(base) IORD_32DIRECT(base, CRC_READ_REG1) #defineCRC_READRESULT_96(base) IORD_32DIRECT(base, CRC_READ_REG2) #defineCRC_READRESULT_128(base) IORD_32DIRECT(base, CRC_READ_REG3) #endif //__ALTERA_AVALON_CRC_REGS_H__
该头文件定义了
CRC IP
核的寄存器访问宏。用户可以通过
Avalon
接口采用
“
基地址
+
地址偏移量
”
的方法来访问外设内部的各个寄存器,以实现
NiosII CPU
对
CRC IP
核的控制。
2 CRC32
自定义指令的实现
2.1
自定义指令的原理和开发
自定义指令是基于
NiosII
处理器的
SOPC
系统的一个重要特征。
NiosII
处理器自定义指令不仅扩展了
CPU
的指令集,还能提高对时间要求严格的软件运行速度,因此提高了系统的整体性能。采用自定义指令,用户可以实现传统处理器无法达到的最佳性能。在对数据处理速度要求比较高的场合,把由标准指令序列实现的核心功能变成由一条用户定制的指令来实现,这样可以明显提高软件的执行效率。基于硬件处理模块的自定义指令可通过单个时钟周期或多个时钟周期的硬件算法操作完成原本十分复杂的处理任务。
NiosII
处理器最多支持
256
条定制指令,加速通常由软件实现的复杂数学运算。
自定义用户指令实质上就是让软核处理器实现由硬件逻辑实现的某种功能,这个硬件逻辑连接到
NiosII
处理器的算术逻辑单元上。对于
NiosII
的标准指令,
NiosII
使用
ALU
来完成相应的算术逻辑操作;对于自定义指令,则采用用户自己建立的硬件逻辑来完成运算。
2.2 CRC32
定制指令的实现
在前面开发的
CRC
自定义外设的基础上,按照定制指令所要求的设计方式,把前面开发的自定义外设改写成一条指令。本设计中
,CRC
自定义指令是作为多周期指令来实现的,在多周期指令要求中必须包括信号
clk
、
clk_en
、
reset
,其他的信号不是必需的。
由于在
SOPC
系统中自定义外设的接口类型与自定义指令的接口类型要求不一样,因此要求在自定义外设的基础上必须加上一个接口文件。这个接口文件的作用是为了与多周期指令的端口信号类型对应。接口文件端口信号和自定义外设端口的对应关系如表
2
所列。
表
2
自定义指令与自定义外设端口对应关系
开发完成后,把自定义指令加到
NiosII CPU
中。生成系统后,在生成的
system.h
文件中,关于
CRC
自定义指令的宏如下:
#define ALT_CI_CRC_CUSTOM_INSTRUCTION_N 0x00000000
#define ALT_CI_CRC_CUSTOM_INSTRUCTION(A,B)__ builtin_custom_inii (ALT_CI_CRC_CUSTOM_INSTRUCTION_N,(A),(B))
其中,
“ALT_”
是宏定义的前缀,表示为
Altera
公司;
CI
是用户定制指令的意思;
CI_CRC_CUSTOM_INSTRUCTION
是用户指令的逻辑模块名称;
N
表示指令操作码。
3
自定义外设和自定义指令在
SOPC
系统中的运行和验证
前面已经分别用自定义外设和自定义指令的方式实现了
CRC32
。那么自定义外设和自定义指令执行性能如何?在实现相同功能的情况下,何种方式在执行过程中更有优势?它们之间的差异有多大?在这一部分将通过测试给予充足的验证。
3.1
验证平台的硬件系统
采用以
CycloneII
系列
EP2C35
为核心芯片的
SOPC
开发系统,来搭建实验所需要的硬件平台。在这个硬件平台中,需要添加系统工作需要的外设,包括
NiosII CPU
、
Timer
、
Avalon
三态桥,外部
RAM
接口和
Flash
等。在该硬件系统中,首先要加入自己定制的外设逻辑,同时在
NiosII CPU
中加入开发的自定义指令。在同一系统中同时加入实现相同功能的自定义外设和自定义指令是为了得到对比结果。系统时钟设置在
50 MHz
。在本设计中,有大量的数据从
SSRAM
传输到
CRC
处理模块中,这些数据在传输过程中不需要进行算术逻辑运算,如果通过
CPU
来操作,会消耗大量的
CPU
时间。为了提高
CPU
的工作效率,采用
DMA(
直接存储器访问
)
来完成。利用
DMA
控制器方式,在
CRC
自定义外设和
SSRAM
存储器之间建立一条
DMA
传输通道,让硬件自动读取数据信息。在
DMA
传输过程中,首先通过中断由
CPU
对
DMA
进行初始化设置,打开
DMA
传输通道,使
DMA
在没有
CPU
干预的情况下进行传输。然后
DMA
直接将
SSRAM
存储器中的数据传输到
CRC
处理模块中,直到数据传输完成。所添加的
DMA
通道,读端口通过
Avalon
三态桥连接到了
SSRAM
,写端口连接到了自定义外设
CRC
,如图
3
所示。
图 3 CRC 验证硬件平台
特别注意的是,在该硬件平台中,要加入一个时间标记服务定时器
high_res_timer
(也就是经常说的
“
时间戳
”
)。该服务可以帮助设计人员查找出耗时最长的功能函数,定位优化目标,检测某个功能部件的运行情况。在这里,主要是利用该
“
时间戳
”
来测量
CRC32
不同方式的执行时间,为分析各种方式的性能差异奠定基础。
3.2
软件开发
在
NiosII IDE
开发环境中,分别使用自定义外设、自定义指令和软件的方式来实现
CRC32
。
①
软件实现方式:数据的读取、处理、保存等全部由软件来实现。
② 用户自定义指令方式:处理过程使用 CRC32 自定义指令来完成。 ③ 用户自定义外设方式:使用 DMA 通道完成数据的读取、保存, NiosII 处理器控制外设完成 CRC32 的处理。
完成上面的工作后,编译工程,下载到
SOPC
开发板中。从
NiosII
控制台中,可以看到如下输出信息,如图
4
所示。
图 4 NiosII IDE 控制台输出信息
4
性能对比和分析
在
NiosII IDE
上面可以观察到用软件、自定义指令、自定义外设实现
CRC32
的各种情况。这几种方式的运行结果是相同的,但用软件实现的时间是
12 381.33 ms
,采用优化的软件设计时间是
8 393.02 ms
,采用自定义指令的时间是
164.69 ms
,而采用自定义外部设备时则用了
12.08 ms
。从结果可以分析出,纯用软件来执行,运行速度最低;如果把标准指令序列实现的核心功能由一条用户自定义指令来实现,可以明显提高系统的执行效率;如果采用自定义外设,即将软件实现的功能全部由硬件来实现,则速度又大大提高。从图
5
中可以更清楚地看到这种对比:
从左到右依次是软件方式、改进软件方式、自定义指令方式、自定义外设方式。由此可知,自定义外设执行效率最高,其次是自定义指令。
图 5 各种方式执行时间和效率对比图
从实现机理上来讲,自定义外设可以看作是和
NiosII
并行运行的一个硬件加速逻辑,中间
CPU
参与过程很少,这就为系统
“
全面加速
”
提供了坚实的基础;而自定义指令由于硬件逻辑连接到
NiosII
处理器的算术逻辑单元上,只能实现
“
局部
”
加速。从实现结果来说,实现同样的功能,自定义外设的执行效率是自定义指令的十几倍以上;而随着系统频率的升高,这个差距会越来越大。如果系统在
120 MHz
,差距会在
50
倍左右。
结语
本文对
SOPC
系统中自定义外设和自定义指令的性能进行了详细对比,并且给出了对比的详细参数。在
SOPC
系统中,如果实时性要求非常高,那么采取自定义外设加
DMA
来完成系统中的关键处理模块无疑是最佳选择。
参考文献
[1] Altera Corporation. Nios II Software Developer's Handbook,2006.
[2] Altera Corporation. QuartusII Verision 6.0 Handbook,2006. [3] 潘松,黄继业 . SOPC 技术实用教材 [M]. 北京:清华大学出版社, 2005. [4] 彭澄廉 , 等 . 挑战 SOC—— 基于 Nios 的 SOPC 设计与实现 [M]. 北京:清华大学出版社, 2004.
王玉峰(硕士)、郭春凤(教师),主要研究方向为基于
FPGA/SOPC
的嵌入式系统。
(收稿日期:
2007-06-15
)
|