什么是SOPC: SOPC是英文System On a Programmable Chip的缩写,称为片上可编程系统。SOPC将传统的EDA技术、计算机系统、嵌入式系统、数字信号处理等融为一体,综合了各自的优势,且在结构上形成一块芯片。 为什么用SOPC:SOPC是现代电子技术和电子系统设计的发展趋势,建立了电子系统设计的新模式。用户利用SOPC开发平台,自行设计高速、高性能的DSP处理器、特定功能的CPU及其外围接口电路,创建结构最为简洁的电子系统。 本章内容:以Altera公司的Nios软核RISC处理器为例,简要介绍SOPC系统设计流程、硬件设计和软件开发等相关内容。
第8章 SOPC设计应用 8.1 SOPC技术概述 8.2 SOPC系统设计实例
8.1 SOPC技术概述 8.1.1 SOC技术 8.1.2 SOPC技术 8.1.3 Nios Ⅱ处理器
8.1.1 SOC技术 什么是SOC: SOC是英文System On a Chip的缩写,称为片上系统。随着微电子技术和计算机技术的发展,可编程逻辑器件的复杂度已经能够在单个可编程逻辑器件上实现整个系统,或者说将一个完整产品的功能集成在一个芯片或芯片组上,这就是片上系统SOC。 SOC中包含什么:包括微处理器CPU、数字信号处理器DSP、存储器ROM、RAM、FLASH等、总线和总线控制器、外围设备接口等,还有其他必要的数模混合电路,甚至传感器等。
SOC技术特点:可以将硬件系统,包括微处理器,存储器,外设以及用户逻辑电路等和软件设计放在一个芯片中,以达到系统IC设计。SOC设计的周期长,设计成本高,中小企业和研究院所、大专院校难以研究和使用这种系统。 SOC技术发展:由于FPGA技术的不断发展,基于FPGA的可重构SOC系统解决方案不断成熟,从而出现SOPC技术。SOPC设计方式,具有开发周期短以及系统可修改等优点。
SOPC技术优势:是可编程逻辑器件和基于ASIC的SOC技术融合的成果,SOPC结合了两者各自的优点。 第一款SOPC产品:2000年Altera公司发布了Nios软核RISC处理器, 这是一款32位的RISC处理器,成为业界第一款为可编程逻辑优化的可配置处理器。将可编程逻辑器件的固有优势集成到嵌入处理器的开发流程中,在定义了处理器之后,设计者就“拥有”了体系结构,形成了片上可编程系统。
SOPC具备以下基本特点: (1)至少包含一个嵌入式处理器内核; (2)具有小容量片内高速RAM 资源; (3)丰富的IP Core资源可供选择; (4)足够的片上可编程逻辑资源; (5)处理器调试接口和FPGA 编程接口; (6)可能包含部分可编程模拟电路; (7)单芯片、低功耗、微封装。
Nios II处理器:是Altera公司的产品,是目前使用较多的一款嵌入式软核处理器,具有可配置性、成本低、灵活性高的优势。 SOPC的核心:是嵌入式处理器内核。SOPC系统中的嵌入式内核可以使用任意一款软核处理器或硬核处理器,该处理器可以非常复杂而且功能强大,也可以非常简单。所以人们选择处理器时,一般都会考虑相应的硬件和软件开发工具以及该处理器与可编程逻辑器件、外部设备的接口能力。 Nios II处理器:是Altera公司的产品,是目前使用较多的一款嵌入式软核处理器,具有可配置性、成本低、灵活性高的优势。
Nios II处理器特性: (1)32位指令集; (2)32位数据总线宽度和32位地址空间; (3)32个通用寄存器和32个外部中断源; (4)32×32乘法器和除法器; (5)可以计算64位和128位乘法的专用指令; (6)单精度浮点运算指令; (7)基于边界扫描测试JTAG的调试逻辑,支持硬件断点、数据触发以及片内和片外调试跟踪; (8)最多支持256个用户自定义指令逻辑; (9)最高250DMIPS(25000万条指令每秒)的性能。
Nios II处理器的使用:根据实际需要选择外设、存储器和接口,可以在同一个FPGA芯片中定制多个处理器并行协同工作,可以使用自定义指令为处理器集成自己的专有功能。Nios II 处理器支持自定义指令逻辑,支持多种用户定制指令的实现方式,自定义指令逻辑可以使用内部寄存器在指令逻辑与CPU之间直接进行数据交互,提高自定义指令逻辑的处理能力。
8.2 SOPC设计应用 SOPC系统设计包括哪些内容:软件设计和硬件设计两个部分,既有软硬件的独立设计,又有软硬件协同设计以及系统调试技术。 8.2.1 SOPC系统设计流程 8.2.2 SOPC系统硬件设计 8.2.3 SOPC系统软件开发 8.2.4 NiosⅡ自定义指令逻辑
8.2.1 SOPC系统设计流程 SOPC系统设计流程:如图所示,可分为系统分析、硬件设计、软件设计、协同验证和调试。
1. 系统分析 依据任务要求,确定系统所要完成的功能及复杂程度,确定系统实现时的软件和硬件的分工,进行系统设计和方案论证。
2. 硬件设计 首先:利用SOPC Builder定制CPU内核系统。首先利用基本CPU类库以及自己实现的自定义逻辑完成CPU的配置,然后添加必要的外设接口等模块,利用SOPC Builder将各个模块利用总线进行正确连接后生成硬件。 接着:开发所需要的HDL文件以及软件开发需要的C程序文件。 最后:得到有关CPU内核描述的HDL文档,回到QuartusII工程中进行必要的配置,添加其他逻辑功能,进行仿真、综合,最终实现硬件配置文件。
3. 软件设计 首先完成与硬件平台无关部分的C/C++代码;得到硬件平台相关的系统支撑库文件后,再进行目标平台代码的编写和软件调试。
4. 协同验证与调试 软件工程师和硬件工程师完成各自的工作后将进行联合调试。这时候软件和硬件都将下载到实际的FPGA芯片中进行实际运行测试,一般会用到片上调试技术。通过片上调试和验证,确定系统是否符合要求,根据需要修改前几部份的设计,重新回到进入设计流程,直至最后系统通过测试。
8.2.2 SOPC系统硬件设计 举例:利用Nios II处理器控制外围LED的显示系统设计 SOPC系统硬件设计包括:QuartusII开发环境下的硬件设计、SOPC Builder开发环境下构建Nios II嵌入式处理器系统。 硬件设计主要完成的工作:Nios II处理器的构建和外围设备接口的设计,在Quartus II中完成引脚分配、电路综合及下载。 目的:熟悉SOPC系统的硬件设计流程和方法。
1.建立工程及顶层设计文件 启动Quartus II软件,用File\New Project Wizard…菜单在Quartus II中新建一个工程Nios-First。工程建立向导完成后,为工程选择使用的器件。然后建立顶层文件。 这里使用原理图设计文件Nios-First.bdf。
2.启动SOPC Builder建立SOPC硬件系统 单击工具按钮或者Tools\SOPC Builder菜单启动SOPC Builder。如图所示,输入系统名称为NIOSIIsys,点击OK按钮,进入SOPC Builder主界面。 注意:系统名称中不能出现空格,不使用中文名称。
SOPC Builder主界面:包括两个向导页,当前是Contents页面,如图所示。 图中左侧:有效组件列表,包括Nios II CPU、PCI等总线以及USB等,罗列了用户可以使用的有效组件,这些组件一般以IP核的方式提供,并且允许用户创建新的组件。 图中右侧:当前系统使用的组件及其互连结构,在这个区域可以修改组件名称。 图中下方:SOPC Builder的信息提示窗口,提示系统构建过程中存在的问题。 目标板信息选择的器件系列应该与Quartus II工程建立时的选择一致。时钟设置表中显示当前SOPC系统中设置的时钟,用户可以根据需要,添加使用的PLL。
配置向导 时钟设置表 目标板信息 有效组件列表 系统组件列表区 提示信息
3. 添加Nios II 处理器 在SOPC Builder主界面的左侧有效组件列表中选择Nios II Processor,按鼠标右键,在弹出菜单中选择Add Nios II Processor[8.0],或者直接点击Add按钮,将会弹出如图所示的Nios II处理器配置界面。本设计选择Nios II/s处理器,占用约1200-1400个逻辑,最好性能可达到25DMPS,与Nios II/e相比增加了指令缓存、分支预测、硬件乘法器等。
Nios II处理器配置向导的第二页缓存设置:如图所示,对指令缓存和数据缓存进行设置,标准型CPU只支持指令缓存,不支持数据缓存。这里使用缺省设置即可。点击Next按钮,进入配置向导下一页。 进入配置向导第四页JTAG调试模块设置:JTAG调试模块占有系统额外的逻辑资源,所以一般在系统设计阶段根据需要添加调试功能,在系统正确完成调试后修改设计去掉调试模块,节省系统资源。
配置向导第四页JTAG调试模块设置: JTAG调试模块有四个级别,最低级别仅能完成JTAG设备连接、软件下载及简单的软件中断,使用这些功能可以将调试信息输出到Nios II IDE环境中。更高级别的调试模块支持硬件中断、数据触发器、指令跟踪、数据跟踪等功能。如图所示,选择了缺省的第一级别设置。
CPU的其他设置:都采用缺省设置,点击Finish按钮结束处理器的设置,回到SOPC Builder主界面后可以对CPU进行重命名,然后进行其他器件的添加和配置。
4.添加存储器 在SOPC Builder主界面左侧的组件列表中选择Memory下On-Chip Memory(RAM or ROM),在鼠标右键弹出菜单中选择Add New On-Chip Memory(RAM or ROM),在如图所示界面上进行存储器配置。设置存储类型:RAM,数据宽度:32位,内存大小:40K字节。设置完成后点击Finish按钮,退出设置界面。
5.添加JTAG UART JTAG UART组件在SOPC Builder组件列表的Communication组中,双击后弹出如图所示配置界面。按照默认设置,配置不做改变,单击Finish按钮完成JTAT UART的设置。
6. 添加PIO控制LED 在SOPC Builder的组件列表中,查找外设PIO,添加并行IO口进行LED显示控制。 PIO配置页面如图所示,设置宽度:8位,方向:输出。点击Finish回到SOPC Builder主界面进行其他设置。
7. Nios II处理器其他设置 添加完所用组件后,系统还需要进行其他的设置。地址设置如图所示,通过单击组件的Base列(基地址)对该组件的基地址进行锁定或解锁,通过system\auto-assign base address菜单对系统组件的基地址进行重新分配。
处理器其他地址设置:如图所示,设置系统复位地址和异常处理地址。
8.生成系统 在SOPC Builder主界面,点击Next按钮,进入系统生成页面,按Generate按钮开始生成Nios II系统。系统生成过程中,屏幕上会显示各种提示信息。 系统生成后,退出SOPC Builder,返回QuartusII,或者不退出,直接切换到Quartus II,进行后续的硬件设计工作。
9.例化Nios II 处理器 在Quartus II软件环境下,左键双击Nios-First.bdf的空白处,弹出Symbol选择对话框,可以在Project组中找到刚刚在SOPC Builder中生成的Nios II系统,如图所示。选中NIOSIIsys,单击OK按钮,在Nios-First.bdf 中放置该模块,实现对Nios II处理器的例化。
10. 编译并下载设计 接下来,按照前面介绍的FPGA设计流程,在QuartusII软件环境下,对设计方案进行分配引脚、完成系统的编译、下载和测试。
SOPC系统软件开发:指的是在Nios II系统上进行软件编程,软件编程的工作是在Nios II IDE下完成。 SOPC系统软件开发举例:要求在Nios II IDE中编写一段程序,驱动LED依次显示0~255的二进制数据。 注意:8.2.2SOPC硬件系统设计举例中已经将Nios II处理器与外围8个LED端口进行了连接。 SOPC的软件开发举例是在此基础上进行的。
1. 启动Nios II IDE 通过SOPC Builder的System Generation页面启动Nios II IDE。也可以通过操作系统开始菜单,单独启动。如图所示是Nios II IDE的欢迎界面,如果对Nios II IDE的操作有疑问的话,单击教程链接tutorials,可以进行Nios II IDE的学习。
2. 建立新工程 进入Nios II IDE后,通过File\New\Nios II C/C++ Application进入新工程配置界面,如图所示。 利用“Hello World”工程模板建立新工程,工程名修改为hello_led或其他名字,注意工程名中不要出现空格。
Nios II IDE进行的程序设计都是针对某个目标硬件进行的,在Select Target Hardware中单击Browse按钮,选择NIOSIIsys作为SOPC Builder system。点击Next按钮,进入系统库选择界面,选择Creat a new system library named选项,如图所示。
Nios II IDE程序设计界面:如图所示。图左侧:是工程列表,列出当前可以使用的工程;图中间:是程序编辑窗口,可以查看和编辑程序;图右侧:是大纲视图,主要显示当前源程序中包含的函数、头文件、宏定义等。图下方:是终端窗口,显式编译信息、调试信息等。 程序编辑窗口 大纲视图 工程列表 终端窗口
3. 修改系统属性 新建工程包括用户工程和系统库工程,后者一般以“_syslib”做后缀与用户工程区分。系统工程是Nios II IDE 根据SOPC Builder生成的Nios II内核进行编译自动生成的系统库。选择用户工程点击鼠标右键,弹出菜单,如图所示。在菜单中选择System Library Properties,修改系统属性,取消Support C++项,选中Small C library项。
4. 编译系统库 在编写用户程序之前,首先需要了解系统库文件的内容,再编译系统库文件。 在Nios II IDE中选择系统库工程,单击鼠标右键,在菜单中选择“compile”。编译成功后,展开该工程文件夹, 在debug目录中可以看到system.h文件,这是Nios II IDE对NiosII处理器系统中各种外设的配置信息。对照SOPC Builder中的设置,我们可以看出,system.h中以宏定义描述了各种设备的基本信息,包括名称、类型和基地址等。
6. 编辑代码 完成的系统功能:通过一个循环,驱动8位LED灯以二进制编码形式显示0~255。 程序代码如下: #include "system.h" #include "alt_types.h" int main() { char i; for (i=0; i<256; i++) usleep(1000); //延时 printf("Hello from Nios II %d !\n", i); //打印信息将输出到标准输出 IOWR(LEDPIO_BASE, 0, i); // LEDPIO的基地址偏移0字节是数据写入寄存器, //通过直接对PIO该寄存器的数据写入,可以将数据输出到LED端口 } return 0; 说明:因为标准输出定义为JTAG UART,所以printf函数的运行结果会在Nios II IDE的终端窗口显示。IOWR函数将i值输出到LEDPIO的基地址第0字处,点亮相应的LED。
7. 编译并运行工程 编译:完成代码编写后,需要对该工程进行编译。 硬件连接:编译正确后,检查硬件设备与电脑的连接情况。 程序下载:在Nios II IDE中选择用户工程,从菜单Run\Run as下选择Nios II Hardware,将程序下载到FPGA芯片上 运行工程:程序运行可以看到控制窗口依次显示“Hello from Nios II”,同时LED灯以二进制形式顺序显示0~255。 需要注意的是:自定义指令是不能进行软件仿真的。
8.2.4 Nios II自定义指令逻辑 为什么使用自定义指令逻辑:可以灵活扩展CPU的指令集,可以将复杂的软件运算过程用硬件逻辑代替,充分利用FPGA的快速高效的性能。 举例:为前面设计的Nios应用系统添加一条与非逻辑指令。 步骤:首先使用VHDL语言编写与非逻辑;然后在SOPC Builder中将其添加到CPU中;最后在Nios II IDE中调用并验证自定义指令。 通过前面的学习,我们已经初步了解了以Nios II为核心的SOPC系统设计开发流程,下面主要介绍如何在Nios CPU中添加自定义指令逻辑的方法步骤。
1. 编写自定义指令逻辑 自定义指令逻辑可以使用原理图方式或者硬件描述语言的方式实现,在QuartusII中检验无误后,再添加到Nios II CPU。 例 8. 3:与非逻辑的VHDL描述 library ieee; use ieee.std_logic_1164.all; entity cinand is port( signal dataa: in std_logic_vector(31 downto 0); -- Operand A signal datab: in std_logic_vector(31 downto 0); -- Operand B signal result: out std_logic_vector(31 downto 0) -- result ); end entity cinand; architecture a_custominstruction of cinand is begin result <= not (dataa and datab); end architecture a_custominstruction;
2. 为Nios II CPU导入并添加自定义指令逻辑 启动Quartus II,打开上一节使用的工程,然后启动SOPC Builder,在SOPC Builder主界面双击CPU,启动Nios II CPU配置向导,点击Next进入向导的Custom Instructions页面,如图所示。左侧窗口显示了SOPC Builder当前集成的可用自定义指令,右侧显示当前CPU已经添加的指令。点击Import按钮可以进入导入指令的组件编辑向导。 当前集成的可用自定义指令 集成到当前CPU的指令
如图所示的是组件编辑向导中的HDL Files页面,点击Add按钮,选择自定义指令的描述文件,SOPC Builder会对选定文件进行检查,检查无误后添加在文件列表,这里选择的是例8.3所示的cinand.vhd。
点击Next进入Signal向导页:可以对现有信号进行检查和调整,由于HDL文件严格按照自定义指令要求的端口名称进行定义,所以已经自动识别映射,如图所示。否则需要自己选择每个端口的信号类型(Signal Type)。
退出组件编辑窗口:检查无误后点击Finish,退出组件编辑窗口,回到CPU的配置向导页,此时指令已经出现在左侧指令列表中,如图所示。 添加指令:选定该指令,然后点击Add,指令出现在左侧,这就表示已经为Nios II CPU添加了一条自定义指令。 重新生成SOPC系统:点击Finish按钮,结束Nios II处理器的修改,回到SOPC Builder,点击Generation,重新生成SOPC系统。 重新生成新的硬件配置文件:回到Quartus II软件,更新SOPC系统组件,重新对工程进行编译,生成新的硬件配置文件。
3. 编写程序使用自定义指令 打开Nios II IDE,对系统库工程进行重新编译,查看system.h文件,可以看到该文件内容发生了变化。增加的程序代码如例8.4所示。 例 8.4 自定义指令的宏定义 /* * custom instruction macros * */ #define ALT_CI_CINAND_N 0x00000000 #define ALT_CI_CINAND(A,B) __builtin_custom_inii(ALT_CI_CINAND_N,(A),(B)) 上述代码就是自定义指令的C语言接口。可以看出,ALT_CI_CINAND是一个宏定义,命名方式是ALT_CI_前缀加指令名,ALT_CI_CINAND_N是定义了自定义指令的序号,Nios II最多支持256条自定义指令。在用户程序中,可以使用该接口函数完成对自定义指令的调用。
例8.5 调用自定义指令 unsigned int x, y, z; x = 0x12345678; y = 0x9abcdef0; z = ALT_CI_CINAND(x, y); // 调用自定义指令进行运算 printf("%x NAND %x = %x\n",x, y, z); // 打印输出 说明:自定义指令无法利用软件仿真。完成编译后,首先确认硬件配置无误,然后选择Run\Run as\ Run as Hardware菜单在硬件上运行程序,可以在控制台看到printf语句输出的正确结果。