今天给大侠带来今天带来FPGA 之 SOPC 系列第三篇,Nios II 体系结构,希望对各位大侠的学习有参考价值,话不多说,上货。
本篇的目的是让大侠建立一个Nios II处理器的概念,了解一些Nios II处理器的工作细节,这对开发出高效率、相对完善的程序是非常有好处的。
体系结构(Architecture)主要用来描述面向程序员的CPU抽象,而不是其具体实现。本篇先介绍Nios II处理器构架,接着介绍NiosII的寄存器文件(Register File),然后介绍NiosII的异常处理,最后介绍NiosII的储存器结构并分析三种NiosII处理器的性能特点。
以下为本篇的目录简介:
3.1 Nios II处理器结构
3.2 Nios II的寄存器文件
3.3 算数逻辑单元(ALU)
3.4 复位信号
3.5 Nios II处理器运行模式
3.6 异常和中断控制器
3.7 Nios II的异常处理
3.8 存储器及I/O结构
3.9 存储器和外设访问
3.10 Nios II处理器性能
本篇的目的是让大侠建立一个Nios II处理器的概念,了解一些Nios II处理器的工作细节,这对开发出高效率、健壮的程序是非常有好处的。
体系结构(Architecture)主要用来描述面向程序员的CPU抽象,而不是其具体实现。本篇先介绍Nios II 处理器构架,接着介绍Nios II 的寄存器文件(Register File),然后介绍Nios II 的异常处理,最后介绍 Nios II 的储存器结构并分析三种 Nios II 处理器的性能特点。
3.1 Nios II处理器结构
Nios II 是一种软核(Soft-Core)处理器。
所谓软核,是指未被固化在硅片上,使用时需要借助EDA软件对其进行配置并下载到可编程芯片(比如FPGA)中的IP核。软核最大的特点就是可由用户按需要进行配置。
1) NIOSⅡ处理器采用流水线技术、单指令流的32位通用RISC处理器
2) 提供全32位的指令集、数据总线和地址总线
3) 提供32个通用寄存器
4) 提供32个外部中断源
5) 提供结果为32位的单指令32X32乘除法
6) 提供专用指令计算结果为64位和128位的乘法
7) 可以定制单精度浮点计算指令
8) 单指令桶形移位寄存器
9) 对各种片内外设的访问及与片外外设和存储器的接口
10) 硬件辅助的调试模块,在IDE环境下,可完成开始、停止、断点、单步执行、指令跟踪等基 本调试和高级调试功能
11) 基于GNU C/C 工具集和Eclipse IDE的软件开发环境
12) ALTERA公司的SignalTapⅡ逻辑分析仪,实现对指令、数据、FPGA设计中的逻辑信号进行实 时分析
13) 所有NISOⅡ处理器均兼容的指令系统
14) 高达218DMIPS的性能
Nios II软核处理器简介:
Nios II 处理器系列包括三种内核,如下图:
数据总线:提高系统性能:NIOSⅡ采用哈佛结构:指令总线、数据总线分开;
紧耦合指令存储器:提高系统性能:集成指令Cache、数据Cache、紧耦合存储器(TCM)接口;
紧耦合数据存储器:提高系统性能:集成了指令Cache、数据Cache、紧耦合存储器(TCM)接口;
数据Cache:支持用户定制指令,方便指令扩展,提升系统性能;
指令Cache:支持用户定制指令,方便指令扩展,提升系统性能;
用户定制指令逻辑:提高系统性能:支持用户定制指令,方便指令集扩展;
寄存器文件:寄存器文件包括32个通用寄存器和6个控制寄存器,允许添加浮点寄存器;
异常控制器:异常控制器处理内核异常事件;
中断控制器:中断控制器处理外部硬件中断事件;
JTAG调试模块:方便用户调试,集成了JTAG调试模块;
NiosII 处理器核:
NIOSⅡ处理器核采用硬件实现,实现指令集并支持各功能模块的工作,处理器核不包含外设和接口逻辑;
NIOSⅡ体系结构定义了指令集,但并不是特定的硬件实现,体系结构中的各功能模块可由硬件实现、软件实现、也可省去;
一个NIOSⅡ实现是根据设计要求得到的一个特定的NIOSⅡ处理器核,实现方案体现了NIOSⅡ软核的可配置性。
或多或少:如增加或减小缓存的大小;
要或不要:如选择不采用JTAG调试模块;
硬件实现或软件模拟:如硬件乘法器的取舍。
NIOSⅡ处理器的算术逻辑单元(ALU)对通用寄存器的数据进行操作,ALU从寄存器中取出操作数,运算结果放回寄存器中。
3.2 Nios II的寄存器文件
Nios II 的通用寄存器:
尽管硬件对寄存器的用法几乎没有规定,但是它们在实际使用过程中还是遵循一些约定俗成的惯例。如果想使用他人的子程序,编译器或操作系统,最好还是遵守这些惯例。
我们通过下面的通用寄存器一览表来了解Nios II的32个通用寄存器。
r0或zero:
总是存放0值,对它读写无效。Nios II没有专门的清零指令,所以常用它来对寄存器清零。
r1或at:
这个寄存器在汇编程序中常用作临时变量。
r2,r3:
用来传递4个非浮点参数给一个子程序。r3存放返回值的高32位。如果这两个寄存器不够存放需要返回的值,编译器将通过堆栈来传递。
r4~r7:
用来传递4个非浮点参数给一个子程序。r4传递第一个参数,r5传递第二个参数,以此类推。如果这四个寄存器不够传递参数,编译器将通过堆栈来传递。
r8~r15:
习惯上,子程序可以使用其中的值而不用保存它们。但使用者必须记住,这些寄存器里面的值可能被一次子程序调用改变,所以调用有责任保护它们。
r16~r23:
习惯上,子程序必须保证这些寄存器中的值在调用前后保持不变,即要么在子程序执行时不使用它们,要么使用前把它们保存在堆栈中并在退出时恢复。
r24或et:
在异常处理时使用。使用时,可以不恢复原来的值。该寄存器很少作用其它用途。
r25或bt:
在程序断点处理时使用。使用时,可以不恢复原来的值。该寄存器很少作其它用途。
r26或gp:
它指向静态数据区中的一个运行时临时决定的地址。这意味着在存取位于gp值上下32KB范围内的数据时,只需要一条以gp作为基指针的指令即可完成。
r27或sp:
堆栈指针。Nios II没有专门的出栈(POP)入栈(PUSH)指令,在子程序入口处,sp被调整指向栈底部,然后以sp为基址,用寄存器基址+偏移地址的方式来访问栈中的数据。
r28或fp:
帧指针,习惯上用于跟踪栈的变化和维护运行时环境。
r29或ea:
保存异常返回地址。
r30或ba:
保存断点返回地址。
r31或ra:
保存函数返回地址。
Nios II的控制寄存器
Nios II的控制寄存器共有6个,它们的读/写访问只能在超级用户态(Supervisor Model)由专用的控制寄存器读/写指令(rdctl和wrctl)实现。
通过控制寄存器一览表,来了解控制寄存器各位的意义。
status—状态寄存器:
只有第1位和第0位有意义。
第0位PIE—外设中断允许位:
- 1表示允许外设中断;
- 0表示禁止外设中断。
第1位U—反映计算机当前状态:
- 1表示处于用户态(User-mode);
- 0表示处于超级用户态(Supervisor Mode)。
estatus、bstatus—都是status寄存器的影子寄存器:
- 发生断点或者异常时:保存status寄存器的值;
- 断点或异常处理返回时:恢复status寄存器的值。
cpuid—此寄存器中装载着处理器的id号:
该id号在生成Nios II系统时产生。Id号在多处理器系统中可以作为分辨CPU的标识。
ipending—中断发生标志位:
每一位反映一个中断发生。例如:
- 第0位为1:表示第0号中断发生;
- 第0位为0:表示第0号中断未发生;
ienable—中断允许寄存器:
每一位控制一个中断通道。例如:
- 第0位为1:表示允许第0号中断发生;
- 第0位为0:表示禁止第0号中断发生;
3.3 算数逻辑单元(ALU)
Nios II ALU支持的操作:
未实现指令:
NIOSⅡ处理器核未提供硬件乘除法器的实现。
当处理器遇到未实现指令时,处理器会产生一个异常,异常管理器 会调用相应程序用软件模拟未实现指令的操作。NIOSⅡ处理器对未 实现指令的处理对程序员是透明的。
用户定制指令:
NIOSⅡ处理器的ALU直接与用户定制指令逻辑相连,对用户定制指 令的访问等同于系统指令集的指令。
浮点指令:
NIOSⅡ支持符合IEEE STD754-1985规范的单精度浮点指令,浮点指 令以用户定制指令的方式实现。
3.4 复位信号
Nios II处理器支持两个复位信号:reset和cpu_resetrequest
- reset:是一个强制处理器核立即进入复位状态的全局硬件复位信号。
- cpu_resetrequest:是一个可以让CPU复位但不影响Nios II系统其它外设的局部复位信号。
Nios II处理器结构框图
CPU复位后,Nios II处理器将执行下列操作:
- 清除状态寄存器status,使之为0x0;是为了使处理器进入超级用户模式并禁止硬件中断。
- 指令Cache与程序存储器的关联被置为无效,处理器从固态程序存储器(比如Flash)中的reset地址处取得第一条指令;使当前Cache队列无效:是为了保证取指是从复位地址所在的非Cache存储区,而不是当前指令Cache。
- 从复位地址处开始执行程序,复位地址在系统生成时指定。
以下部件的状态在复位后是不确定的:
- 通用寄存器(除zero(r0):总是存放0值);
- 控制寄存器(除status(ct10),被置为0x0);
- 指令和数据存储器。
- Cache(除与复位地址关联的指令Cache);
- 与CPU相连的各外设,各外设复位后的状态要具体参考各外设的手册;
- 用户指令逻辑在复位后的状态要参看用户指令逻辑的手册或说明。
3.5 Nios II处理器运行模式
Nios II处理器有3种运行模式:
- 用户模式(User Mode);
- 超级用户模式(Supervisor Mode) ;
- 调试模式(Debug Mode) 。
用户模式:
是超级用户模式功能访问的一个子集,它不能访问控制寄存器和一些通用寄存器。
超级用户模式:
除了不能访问与调试有关的寄存器(bt、ba和bstatus)外,无其它访问限制;
调试模式:
拥有最大的访问权限,可以无限制地访问所有的功能模块。
通常系统程序代码运行在超级用户模式。在V6.0版本以前的Nios II 处理器都不支持用户模式,永远都运行在超级用户模式。
Nios II 处理器3种运行模式切换
Nios II处理器3种运行模式
3.6 异常和中断控制器
异常控制器:
Nios II体系结构提供一个简单的非向量异常控制器来处理所有类型的异常。
中断控制器:
Nios II体系结构支持32个外部硬件中断,即irq0~irq31。每个中断对应一个独立的中断通道。
3.7 Nios II的异常处理
异常类型:
异常硬件处理流程:
当异常发生后,处理器会依次完成以下工作:
异常判别及优先级:
异常的嵌套:
当执行异常返回指令(eret)后,处理器会把estatus寄存器(ctl1)内容复制到status寄存器(ctl0),恢复异常前的处理器状态,然后把异常返回地址从ea寄存器(r29)写入程序计数器。
异常发生时,ea寄存器(r29)保存了异常发生处下一条指令所在的地址。当异常从软件陷阱异常 或未定义指令异常返回时,程序必须从软件陷阱指令trap或未定义指令后继续执行,因此ea寄存器(r29)就是正确的异常返回地址。
异常返回:
如果是硬件中断异常,程序必须从硬件中断异常发生处继续执行,因此必须将ea寄存器(r29)中的地址减去(ea-4)作为异常返回地址。
异常响应时间:
Nios II的非向量仲裁策略,导致了Nios II的异常处理延时会比较大,它是靠提高Nios II处理器的执行速度来弥补这一缺点的。见下表:
Nios II 异常处理性能表
3.8 存储器及I/O结构
NIOSⅡ处理器的存储器和I/O结构:
1、指令主端口
Nios II指令总线作为32位Avalon主端口来实现。指令主端口只执行一个功能:对处理器将要执行的指令进行取指。
指令主端口是具有流水线属性的Avalon主端口。
指令主端口依赖Avalon交换结构中的动态总线对齐逻辑始终能接收32位数据。
Nios II结构支持片内高速缓存。
Nios II结构还支持紧耦合存储器,对紧耦合存储器的访问能实现低延迟。
说明:
1)、指令主端口不执行任何写操作。
2)、动态总线对齐逻辑不管目标存储器的宽度如何,每次取指都会返回一个完整的指令字,因而程序不需要 知道Nios II处理器系统中的存储器宽度。
3)、片内高速缓存,用于改善访问较慢存储器时的平均指令取指性能。
2、指令高速缓存
3、数据主端口
Nios II数据总线作为32位Avalon主端口来实现。数据主端口执行两个功能:
- 当处理器执行装载指令时,从存储器或外设中读数据。
- 当处理器执行存储指令时,将数据写入存储器或外设。
数据主端口不支持Avalon流水线传输。
同指令主端口一样Nios II结构支持片内高速缓存,改善平均数据传输性能。
Nios II结构也支持紧耦合存储器以实现低延迟。
4、数据高速缓存
高速缓存(Cache):
Nios II结构的指令主端口和数据主端口都支持高速缓存。
作为NiosII处理器组成部分的高速缓存在SOPC Builder中是可选的,这取决于用户对系统存储性能以及FPGA资源的使用要求。包含高速缓存不会影响程序的功能,但会影响处理器取指和读/写数据时的速度。
高速缓存改善性能的功效是基于以下前提的:
- 常规存储器位于片外,访问时间比片内存储器要长。
- 循环执行的、最大的,关键性能的指令序列长度小于指令高速缓存。
- 关键性能数据的最大模块小于数据高速缓存。
例如在以下的情况下高速缓存将无法改善执行速度:
Nios II处理器系统只含有快速的片内存储器(即从不访问较慢的片外存储器)。
程序的关键循环是2KB,而指令高速缓存的大小为1KB。
由于性能上的原因,应用程序始终要求某些数据或部分代码存放在高速缓存中,那么紧耦合存储器可能会提供一个更合适的解决方案。
紧耦合存储器(TCM):
与高速缓存相比具有的优点:
1.性能类似于高速缓存;
2.软件能够保证将关键性能的代码或数据存放在紧耦合存储器中;
3.代码执行的确定性——装载和存储指令或数据的时间是可预测的。
紧耦合存储器介绍:
实际上,紧耦合存储器是Nios II处理器内核上的一个独立的主端口,与指令或数据主端口类似。Nios II结构指令和数据访问都支持紧耦合存储器。Nios II内核可以不包含紧耦合存储器,也可以包含一个或多个紧耦合存储器。每个紧耦合存储器端口直接与具有固定的低延迟的存储器相连,该存储器在Nios II内核的外部,通常使用FPGA片内存储器。
紧耦合存储器与其它通过Avalon交换结构连接的存储器件一样,占据标准的地址空间。它的地址范围在生成系统时确定。
系统在访问指定的代码或数据时,能够使用紧耦合存储器来获得最高性能。例如,中断频繁的应用能够将异常处理代码放在紧耦合存储器中来降低中断延迟。类似的,计算密集型的数字信号处理(DSP)应用能够将紧耦合存储器指定为数据缓存区,实现最快的数据访问。
- IOSⅡ体系结构采用哈佛结构:指令总线和数据总线分开
- 指令总线和数据总线均为遵循Avalon主端口规范的主端口
- 数据主端口可连接存储器和外设
- 指令主端口只连接存储器
存储器与外设的访问:
NiosⅡ体系结构提供映射为存储器的I/O访问。
数据存储器和外设都被映射到数据主端口的地址空间。
NIOSⅡ体系结构采用小端方式,高字节放高地址,低字节放低地址。
3.9 存储器和外设访问
Nios II地址是32位的,允许对4GB地址空间进行访问,但现有的Nios II内核都将地址限制在31位,即2GB地址空间。处理器的数据总线为32位宽度。指令集提供字节,半字(16bit)或字(32位)的读写指令。Nios II结构采用小端模式,对于保存在存储器中的大于8位的数据,最高有效位在高地址。
寻址方式
Nios II结构支持以下寻址方式有:
- 寄存器寻址:所有的操作数都是寄存器,结果保存在寄存器中
- 移位寻址:寄存器和带符号的16位立即数相加的结果作为地址
- 立即数寻址:操作数是指令中的常量
- 寄存器间接寻址:使用了移位寻址,只是移位值是常量0
- 绝对寻址:范围有限制的绝对寻址使用带有寄存器r0(它的值始终是0x00)的移位寻址来实现。
高速缓存访问
Nios II结构和指令集可以管理数据高速缓存和指令高速缓存。高速缓存管理使用高速缓存指令在软件中实现。指令集可对高速缓存实现初始化、刷新及旁路数据高速缓存的指令操作。
有些Nios II处理器内核支持一种称作31位高速缓存旁路的机制,它根据地址的最高有效位的值来旁路高速缓存。处理器实现的地址空间为2GB,地址的高位控制数据存储器访问的缓存操作。
写入到具有高速缓存的处理器内核的代码可以在没有高速缓存存储器的处理器内核上正确地执行,反过来则不行。在没有高速缓存的系统中,高速缓存管理指令不执行任何操作。
3.10 Nios II处理器性能
Nios II 处理器有以下三种类型:
注:关于各处理器的更详细内容请阅读Altera公司的《Nios II Processor Reference Handbook》的Nios II Core Implementation Details部分。
Nios II 处理器内核性能表如下:
FPGA 之 SOPC 系列第三篇就到这里结束,第四篇将带来NIOS II 外围设备——标准系统搭建相关内容,敬请期待。各位大侠,有缘再见!
END
后续会持续更新,带来Vivado、 ISE、Quartus II 、candence等安装相关设计教程,学习资源、项目资源、好文推荐等,希望大侠持续关注。
大侠们,江湖偌大,继续闯荡,愿一切安好,有缘再见!