zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Nios II自学笔记一:Nios II软硬件架构介绍

架构笔记 介绍 II 自学 软硬件
2023-09-27 14:20:17 时间

该文章为Nios II学习中的整理的笔记,主要内容来源于锆石科技的教程。

目录

一、QSYS和Nios II

二、Nios II硬件框架结构

1.寄存器文件

1.1 通用寄存器

1.2 控制寄存器

1.3 影子寄存器组

2.算术逻辑单元

3.复位信号

4.中断

4.1内部中断

4.2 外部中断

5.存储器和I/O结构

5.1指令主端口和数据主端口

5.2 指令高速缓存和数据高速缓存

5.3 MMU和MPU

5.4 紧耦合存储器

6 JTAG调试模块

三、Nios II软件框架结构

四、Nios II的用户程序引导装载过程

4.1 Nios II的Boot

4.2Nios II的BootLoader

参考资料​​


 

提示:以下是本篇文章正文内容,下面案例可供参考

一、QSYS和Nios II

Qsys是Altera公司为其FPGA上定制实现的SOPC框架,Qsys系统集成工具知道生成互联逻辑,连接IP核功能和子系统,从而显著节省了时间,减轻了FPGA设计工作量。

Qsys是Quartus II中的一个系统集成工具,它是用来搭建、开发以及维护“系统”的平台,这个系统通常是指以Nios II处理器为核心的嵌入式系统。利用Qsys所搭建的一个基本的嵌入式系统包含系统时钟、Nios II处理器、JTAG接口、ROM和RAM等

Nios II CPU是QSYS系统中最为核心的一个IP核,相比于前一代,nios II从16位升级为32位,因此性能更高,占用FPGA资源更少。Nios II处理器系统包括三种不同等级内核可供用户配置——快速(Nios II/f)、标准(Nios II/s)和经济型(Nios II/e),三种不同等级Nios II处理器的特性如下,所有这些内核共享32位指令集体系,与二进制代码100%兼容。

二、Nios II硬件框架结构

1.寄存器文件

寄存器文件是Nios II处理器内部用来存放数据的一些小型存储区域,这些小型存储区域可以用来暂时存放参数数据与运算结果。Nios II寄存器文件包括32个通用寄存器、32个控制寄存器以及影子寄存器组。

1.1 通用寄存器

通用寄存器用于多种用途,它们可以用来暂存指令、数据和地址。

1.2 控制寄存器

所谓控制寄存器,就是它可以用于控制和确定Nios II处理器的操作模式,以及当前执行任务的特性

1.3 影子寄存器组

用来备份通用寄存器和状态寄存器,影子寄存器组通常会和外部中断控制器联合使用。当外部中断来了,影子寄存器组就会为这个中断制造一个完全属于它自己的一个运行环境,它运行完了之后再回到原来的通用寄存器中继续运行。

2.算术逻辑单元

Nios II中的算术逻辑单元(ALU)支持算术运算、关系运算、逻辑运算和移位运算。对于需要很多逻辑资源的乘法、除法和可控位数的移位操作,在Nios中还可以设置选择硬件算法操作,通过嵌入式乘法器和嵌入式触发器来实现。

3.复位信号

全局硬件复位信号 reset : 外部输入,高电平有效,强制处理器核进入复位

本地复位信号 cpu_resetrequest:高电平有效,只让CPU复位,而NIOS II系统中的其他元件不受这个复位影响

4.中断

Nios II中具有内部中断和外部中断。实际使用时,只能二选一。

4.1内部中断

Nios II体系结构支持32个内部中断,即irq0~irq31,在Qsys为中断分配优先级。内部产生中断的条件:

(1)、Status控制寄存器中断使能位(PIE)置1;

(2)、某个中断请求irqn有效

(3)、在ienable寄存器中,该中断源相应位为1

当内部中断发生之后,Nios II系统相应中断依次执行的工作:

(1)、把status寄存器内容复制到estatus寄存器总,保存当前处理器状态

(2)、清除status寄存器的PIE位为0,并禁止所有中断

(3)、把异常返回地址写入ea寄存器(r29)

(4)、跳转到异常处理地址

4.2 外部中断

在使用外部中断时,还需要设置相应的影子寄存器组。针对每一个外部中断,都会给它分配一个相对应的影子寄存器组,用来备份通用寄存器和状态寄存器,一旦外部中断来了之后,CPU就会切换到影子寄存器组中运行。运行完成后,CPU再返回到之前的寄存器中运行,因此能够完成保护现场的工作。只有Nios II/f才支持外部中断。

外部中断的设置:

在Nios II processor里面的[Advaanced Features]标签下的[Interrupt Controller]中进行设置。选择为[External],同时设置影子寄存器数量。

在QSYS中添加外部中断控制器Vectored interrupt Controller IP连接至nios II processor的interrupt_controller_in端口,至此可以在qsys界面的右侧像连接内部中断一样去连接外部中断。

** 使用外部中断的场景**

(1)需要一个或多个中断来减少平均响应时间

(2)中断性能有很强的实时性要求

(3)不可屏蔽的中断

(4)需要处理的中断超过32个

5.存储器和I/O结构

Nios II 处理器属于哈弗结构,支持独立的指令和数据总线,指令和数据总线都遵循Avalon接口规范。数据主端口连接存储器和外设,指令主端口只连接存储器元件

Nios II内核可以使用下面的一种或多种方式访问存储器和IO:

(1)指令主端口:instruction_master ,通过Avalon 系统互联结构访问到指令存储器

(2)数据主端口:data_master ,通过Avalon 系统互联结构连接到数据存储器

(3)指令高速缓存:Nios II内核里面的高速缓存

(4)数据高速缓存:Nios II内核里面的高速缓存

(5)紧耦合指令或数据存储器端口:与Nios II内和外的快速存储器相连

5.1指令主端口和数据主端口

指令主端口:对处理器将要执行的指令进行取指,并且它不执行任何写操作

数据主端口:当处理器执行装载指令时,从存储器或外设中读数据;当处理器执行存储指令时,将数据写入存储器或外设。

注:当存储器能够为系统提供指令,存储器需要连接指令端口和数据端口

5.2 指令高速缓存和数据高速缓存

Nios II结构的指令主端口和数据主端口都支持高速缓存(Cache)。高速缓存使用片内存储资源,能改善使用较慢片存储器的Nios II处理器系统的平均存储访问时间,在软件上几乎透明,不需要我们写任何代码就可以实现。Cache在Qsys中是可选的。

注意,指令cache和数据cache虽然可以改善系统的整体性能,但是它会使程序执行的时间变得不可预测,对实时系统来说,代码执行的确定性——装载和存执指令、数据的时间必须是可预测的

5.3 MMU和MPU

MMU:Memory Manager Unit 即存储器管理单元

实现虚拟地址与物理实际地址的映射管理,用于支持虚拟内存的操作系统

MPU:Memory Protection Unit 即存储器保护单元

限制用户应用程序访问关键的系统资源,Nios Ii中仅提供了存储器保护,不支持内存映射管理,Altera HAL为MPU提供了基本的支持,无须OS

注:Nios II 中MMU与MPU只能二选一

5.4 紧耦合存储器

紧耦合存储器是一种紧挨着内核的快速SRAM,它不仅能改善系统性能,而且保证了装载和存储指令或数据的时间。既能提高处理器的性能,又能获得可预测的实时响应,与cache相比的优点:

     (1)性能类似于高速缓存

     (2)软件能够保证关键性能的代码或数据存放在紧耦合存储器中

     (3)代码执行的确定性——转载和存储指令或数据的时间是可预测的

应用场景:例如,中断频繁的应用能够将异常处理代码放在紧耦合存储器中来降低中断延时。类似的,计算密集的数字信号处理应用能够将紧耦合存储器指定为数据缓存区,实现最快的数据访问。如果应用程序的存储器需求足够小,能够完全在片内实现,可以使用专门针对代码和数据的紧耦合存储器。如果应用程序较大,那么必须仔细选择放入紧耦合存储器中的内容,使得成本和性能能够实现最佳平衡。

紧耦合存储器QSYS使用示例:

在Nios II processor的[Caches and Memory Interfaces]端口选择tightly coupled master port的数量,之后会引出2个端口:tightly_coupled_data_master0和 tightly_coupled_instruction_master0,然后添加两个onchip_memory用于缓存,一个单口onchip_memory用于data master,一个双口onchip_memory的一端接到tightly coupled instruction master port,另一端接到Avalon Data Master Port。

注意:当我们在Qsys上完成连接后还需要将nios的异常相连设置为tightly coupled instruction memory。

6 JTAG调试模块

Nios II结构中包含可定制的JTAG调试模块,分4个等级,不同等级对应不同的功能和逻辑资源消耗。

三、Nios II软件框架结构

Application Project是我们的软件工程,Hardware System是我们的硬件系统,连接软硬件的这座桥梁脚HAL BSP Project,也就是我们所说的硬件抽象层(HAL)系统库或者是板级支持包(BSP)。

HAL系统库为用户提供以下支持:

  1. 集成了ANSI C标准函数库,允许调用类似C标准库函数;
  2. 提供访问Nios II系统每个设备的驱动程序;
  3. 提供HAL API,用于标准的函数接口如设备访问、中断处理以及ALARM等;
  4. 提供系统初始化函数,为main()函数和C库函数建立运行时环境。由于这里包含了Bootload以及程序重新定位工作,所以Nios II开发中没有像ARM系统开发设计Bootload等问题;
  5. 提供设备初始化函数,在main()函数前,分配设备空间并初始化所有的外围设备。

四、Nios II的用户程序引导装载过程

4.1 Nios II的Boot

Nios II的启动过程要经历两个过程:

  1. FPGA器件本身的配置过程。FPGA器件在外部配置控制器或自身携带的配置控制寄存器(EPCS)的控制下配置FPGA的内部逻辑。如果内部逻辑中使用了Nios II,则配置完成的FPGA中包含有Nios II软核CPU。
  2. Nios II本身的引导过程。一旦FPGA配置成功之后,Nios II就被逻辑中的复位电路复位,然后开始执行Bootloader。

4.2Nios II的BootLoader

几个地址断概念:

(1).bss(未初始化变量数据段):未初始化变量,如全局变量定义后,但未初始化的都放在这里;

(2).entry(复位地址):最终软件代码存放区,程序从此处开始启动;

(3).exception(异常处理地址):系统异常处理代码存放的地方;

(4).heap(堆):动态分配内存的存储区,从小地址向大地址方向增长;

(5).rodata(只读数据段):用于存放程序中的静态全局变量,所有赋予了初值的全局变量都被放在这里;

(6).rwdata(可读写数据段):用于存放程序中可读写变量和指针变量;

(7).stack(栈):函数调用变量与临时数据存储区(如返回地址,现场信息),从大地址向小地址方向增长;

(8).text(正文段,只读):代码执行区,也就是Nios II程序最终运行的地方;一个程序只有一个副本;只读,防止程序由于意外事故而修改自身指令;

Bootloader作为“代码搬运工”,是系统加电之后运行的第一行代码,Bootloader能根据用户设置的用户程序文件(.elf)连接地址来重新装载程序,然后跳过.elf文件的连接地址来执行程序。Bootloader的执行过程如下:

  1. 完成复位子程序功能。在从复位地址开始的32字节(指令缓存行的尺寸)空间内完成复位的软件相应。
  2. 加载应用项目程序映像中的代码和数据段(从装载地址reset address加载到程序运行地址.text)。
  3. 跳转到程序入口(通常是_start)。

当Bootloader跳转到应用程序入口后,便会用到Nios II架构准备的启动代码,分别是crt0.s和alt_main.c。

crt0.s主要完成以下功能:

  1. 初始化指令Cache,初始化数据Cache;
  2. 设置堆栈指针(Stack Pointer)寄存器;
  3. 全局指针(Global Pointer)寄存器;
  4. 初始化bss段;
  5. 如果系统中没有BootLoader,则把.rwdata,rodata和异常向量装入RAM中;
  6. 调用alt_main()函数,也就是执行alt_main.c文件中的内容。

alt_main.c主要完成以下功能:

  1. 调用alt_irq_init()初始化中断控制器;
  2. 调用ALT_OS_INIT()初始化OS;
  3. 如果使用了操作系统,那么初始化用于控制访问文件描述器列表的信号量。
  4. 使能中断;
  5. 调用alt_sys_init()初始化添加的IP核的设备驱动;
  6. 把标准输入输出设备(stdin,stdout,stderr)映射到合适的设备上;
  7. 调用C++的构造器;
  8. 调用main()函数;
  9. 调用exit()函数。

参考资料

1.《Hello FPGA》——软核演练篇

2.博客https://blog.csdn.net/wuyanbei24/article/details/111402033