Nios初体验之——Hello world!


前言

环境:
1、Quartus18.0
2、vscode
3、板子型号:原子哥开拓者2(EP4CE10F17C8)
要求:
通过Nios输出Hello world!


一、系统设计

1、系统模块框图

在这里插入图片描述
在这里插入图片描述

Nios II 处理器通过 Avalon 总线与 ROM 和RAM 连接,其中 Avalon 总线用来传输指令与数据。除此之外,Qsys 系统还提供了一个 JTAG 接口,供用户下载和调试程序。

2、系统涉及到的模块

1、时钟

clk IP 核的全称是 Clock Source,在这里设定我们整个系统的工作时钟频率。

2、nios2_qsys

这是我们之前对Qsys介绍时了解到,这是整个Qsys的控制中心,起着分配中断、管理地址、调度内存等主要的控制作用,相当于大脑的低位吧,通过Avalon与外界进行通信。

3、片内存储(onchip_rom、onchip_ram)

这里我们创建了两个片内存储器,ROM和RAM。这两个片内存储器都是利用FPGA的片上存储资源进行实现,除了用于存储指令和数据外,还是程序的运行空间。需要注意的是ROM的实现,在FPGA内部并没有专用的ROM资源,我们通过对 RAM 赋初值,并始终保持该值,使其变得只读,从而实现片内 ROM(只读存储器)。

4、串行通信(jtag_uart)

JTAG UART IP 核使用 JTAG 接口来实现上位机与 Qsys 系统之间的串行通信。JTAG UART IP 核为用户提供了 Avalon-MM 接口映射,屏蔽了复杂的 JTAG 接口协议。

5、System ID(sysid_qsys)

System ID IP核是一个具有Avalon接口的只读设备,它给每个Nios II系统生成一个唯一的标识符(ID),并将其写入 System ID 核的寄存器中。编译器和用户可以利用该 IP 核来验证编译后的可执行程序与配置到FPGA 中的硬件环境是否匹配。如果可执行程序中的 ID 与 FPGA 中 System ID 核所存储的 ID 不一致,那么程序在运行时可能会出错

二、硬件设计

在开始Qsys系统设计之前我们需要先根据我们的芯片型号创建Quartus 工程,这里前面已经介绍过这里不在赘述。不同的是我们需要多创建一个qsys文件夹,下面新建hardware 和 software 文件夹,分别存放 qsys设计的硬件部分和软件部分。然后我们需要在prj文件夹下新建一个ipcore 文件夹,用于存放 Quartus II 工程 IP 核。

1、创建Qsys

  • 点击tools->platfrom Desiger进入设计界面:
    在这里插入图片描述
  • 修改时钟频率为100M:
    在这里插入图片描述

修改为100MHZ,并点击finish完成,否则修改失败。

  • 添加Nios II IP 核:
    在这里插入图片描述

  • 双击Nios II IP 核进入配置界面:
    在这里插入图片描述

这里我们保持默认选择“Nios II/f‖内核“,报错我们后面再进行解决,点击finish。

  • 添加成功:
    在这里插入图片描述
  • 添加片内存储ROM IP核:
    在这里插入图片描述
  • 同样双击进入配置界面:
    在这里插入图片描述

我们需要将其设置为ROM(只读),大小设置为10240,为10KB,其余默认。

  • 同样的方法,配置RAM:
    在这里插入图片描述

将“Type”选项设置为“RAM(Writable)”,然后将“Total memory size”修改为“20480”,也就是 20KB。其他的选项保持默认设置,最后点击 Finish

  • 添加 JTAG UART IP 核:
    在这里插入图片描述
  • 这里保持默认:
    在这里插入图片描述
  • 添加 System ID IP 核:
    在这里插入图片描述
  • 这里保持默认,点击finish:
    在这里插入图片描述

2、重命名IP核&连线

为了方便我们的理解,以及后面的软件程序中可能会使用到,所以我们尽量重命名为简单易理解的名字。

  • 右击点击rename重命名:
    在这里插入图片描述
  • 修改过后的名称:
    在这里插入图片描述
  • 连线:将IP核进行连接:

连接时,用鼠标点击“Connections‖一栏中相应的结点,连接后各结点处的空心圆会变成实心的点,同时相应的连线由浅灰色变成黑色。

  • 将复位信号与时钟信号接入到各IP核下:
    在这里插入图片描述
  • 数据主端口―data_master‖和指令主端口―instruction_master‖的连线:
    在这里插入图片描述
  • 注意:

这两个端口的连线遵循以下规则:数据主端口与所有的外设 IP 核连接,而指令主端口只连接存储器 IP 核。

  • 连接“jtag_debug_module_reset‖信号:
    在这里插入图片描述
  • 注意:

在连完线后,我们需要在“IRQ”一栏将 jtag_uart IP 核的中断信号与 Nios II 处理器连接起来。在连接中断的时候,Qsys 会自动为中断分配一个优先级。

  • 双击Nios II IP核设置复位地址和异常地址:
    在这里插入图片描述

这个时候finish会报错,我们先设置一下下面的自动分配

  • 设置基地址分配:
    在这里插入图片描述
    设置完了以后,之前的爆红就会消失,然后可以finish,Generate生成Qsys 系统了。
  • 生成过程:
    在这里插入图片描述

3、集成 Qsys 系统

  • 将Qsys生成的.qip文件添加到工程:
    在这里插入图片描述
  • 配置Pll锁相环:
    这里因为我们前面设计Qsys系统时,配置的是100Mhz,所以这里我们需要创建一个PLL IP 核实现二倍频,这里由于前面文章已经介绍过,就不在赘述。
    IP核简介及PLL_IP核的调用

4、顶层文件实例化:

  • 打开我们的Qsys设计界面,在Qsys文件夹找到qsys文件打开:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 自动生成Qsys系统例化代码:
    在这里插入图片描述

但是这里不知道咋的不能生成,那没事我们自己例化顶层模块,例化完放到rtl文件夹中,并添加到工程里设置为顶层文件。

module qsys_hello_world(
 input sys_clk, //晶振时钟,50Mhz
 input sys_rst_n //按键复位,低电平有效
 );
 
 //wire define
 wire clk_100m; //Qsys 系统时钟,100Mhz
 
 //例化 pll IP 核
 pll u_pll(
 .inclk0 (sys_clk),
 .c0 (clk_100m)
 );

 //例化 Qsys 系统
 hello u_qsys(
 .clk_clk (clk_100m),
 .reset_reset_n (sys_rst_n)
 );

 endmodule

5、编译下载操作:

  • Assignment→Device:
    在这里插入图片描述

  • 将未使用的引脚设置为高阻输入:
    在这里插入图片描述

  • 将“Value‖一栏全部设置为 ―Use as regular I/O”:
    在这里插入图片描述

  • 下面就是分析综合然后分配引脚全编译:
    在这里插入图片描述
    在这里插入图片描述

编译通过,下一部分是软件的设计阶段。

三、软件设计

  • 点击Toos下的Nios II SBT for Eclipse:
    在这里插入图片描述

  • 修改工作空间到 software 文件夹:
    在这里插入图片描述

  • 点击ok进入后选择file→New→Nios II Application and BSP from Template用于新建Nios II工程:
    在这里插入图片描述

  • 设置Nios II工程:
    在这里插入图片描述

  • 系统默认帮我们创建一个BSP(板级支持包)、保持默认、点击finish:
    在这里插入图片描述

  • 点击finish完成过后,我们会发现左边增加了两个文件:在这里插入图片描述

  • 点击c/c++的点c文件,修改输出内容并保存:
    在这里插入图片描述

  • 右击hello_world选择Build Project进行编译:

报错:
在这里插入图片描述
解决:
选中hello_world_bsp,右击,进行下面操作:
在这里插入图片描述

  • 添加勾选:
    在这里插入图片描述

enable_reduced_device_drivers
BSP 为处理器的外设提供了两个版本的驱动库:一种是执行速度快,但代码量比较大的版本;另一种是封装小的版本。默认使用的是代码量大的版本, 这里通过
enable_reduced_device_drivers: 选项来选择封装小的版本,从而减少代码量。enalbe_small_c_library:完整的 ANSI C 标准库通常不适用于嵌入式系统,BSP 提供了一系列经过裁剪的 ANSI C 标准库,占用资源比较少,我们可以通过【enalbe_small_c_library】选项来选择精简的 ANSI C 标准库。

  • 取消勾选:
    在这里插入图片描述

enable_c_plus_plus: 我们使用 C 语言来编写软件程序,因此不需要使能 C++。
enable_clean_exit: 当选中该选项时,系统库在主函数 main()返回时会调用 exit()。调用 exit()时,首先会清理 I/O 的缓冲区,然后再调用_exit()。当不选中该选项时,系统库会只调用_exit(),这样将会节省程序空间。对于嵌入式系统程序来说,一般都不会从 main()返回,所以可以不勾选该选项。

然后我们先点击Generate,再exit。

  • 编译整个工程:
    在这里插入图片描述
  • 编译成功:
    在这里插入图片描述

四、下载验证

这里我们需要下载两个文件,先下载sof,再下载elf。这里我们只介绍elf文件的下载。

  • 右击我们的工程名—>run as—>Nios II Hardware:

如果一步成功,那么你的控制台就会打印成功,否则跳出下面弹窗。

提示我们找不到与Nios II硬件系统的连接
在这里插入图片描述

如果你这一步成功,那么你的控制台就会打印成功,否则跳出下面弹窗。

在这里插入图片描述

上面这个问题博主寻找了许久也没有发现问题,或者解决方法,丢弃了几天,在周末打开时他又行了,真是玄学,如果有友友了解的可以在评论区发表一下想法,一起学习。

  • 在下载完成之后,控制台会输出相应信息:
    在这里插入图片描述

五、总结

总结的话就一句话,杀猪焉用牛刀哈,这里我们在实现简单输出时发现我们的步骤稍显复杂,这里的话为了方便我们后续的查看步骤,博主这里写的较为详细。在后面大的一些工程的话就能体会到Nios的魅力了。大家在配置的时候要细心,尤其连线那里,加油!最近在搞DHT11的温湿度读取和基于openvino的车牌识别,敬请期待。

六、参考资料

以上资料均来自正点原子的教学视频或开拓者2开发教程:原子官方
源码:https://github.com/no1jiangjiang/Nios_hello

猜你喜欢

转载自blog.csdn.net/qq_52215423/article/details/132016851