Nios II 处理器与 SOPC Builder 设计

Altera FPGA 培训讲义第三章,共 148 页。系统讲解 Nios II 软核处理器的硬件架构、软件开发流程、Avalon 互联总线、自定义外设与指令、DMA 等核心内容。

一、课程议程

  1. Nios II 硬件开发 — 处理器架构、系统组成、配置选项
  2. Nios II 软件开发 — IDE、工程结构、HAL 库、外设驱动
  3. Nios II 软件调试 — JTAG 调试、断点、监视
  4. RTL 仿真 — ModelSim 仿真流程
  5. Avalon 互联总线 — 总线架构、传输时序、桥接
  6. 自定义外设 — Avalon Slave 接口设计
  7. 自定义指令 — 扩展 CPU 指令集
  8. 多主设备与 DMA — 多主仲裁、DMA 传输
  9. 配置开发板 — 下载与调试流程

二、Nios II 硬件开发

2.1 什么是 Nios II

  • Altera 第二代 32 位软核 RISC 处理器
  • Nios II 与所有外设都用 HDL 设计,可在所有 Altera FPGA 中使用
  • 使用 Quartus II 内置综合器

核心价值:用可编程逻辑器件替代外部分立器件(CPU、DSP、Flash、SDRAM 等),降低系统成本、复杂度和功耗。

2.2 标准 Nios II 系统结构

Nios II CPU
  ├── On-Chip Debug Core
  └── Off-Chip Software Trace Memory
        │
        ▼
Avalon Interconnect Fabric(互联总线)
  ├── Address Decoder        地址译码
  ├── Interrupt Controller   中断控制器
  ├── Wait State Generation  等待状态生成
  ├── Data in Multiplexer    数据多路选择
  ├── Master Arbitration     主设备仲裁
  ├── Clock Domain Crossing  时钟域交叉
  └── Dynamic Bus Sizing     动态总线位宽
        │
        ▼
外设集合:UART / Timer / SPI / GPIO / DMA / Memory Interface / User-Defined Interface

2.3 Nios II 三种配置版本

版本特点乘法器性能(32×32→32 时钟周期)
Economy(经济型)无硬件乘法器,用 GNU 数学库模拟250 周期
Standard(标准型)全硬件乘法器3 周期
Fast(快速型)全硬件乘法器1 周期

2.4 Control Plane 与 Data Path 分离架构

  • Control Plane(控制平面):CPU + Ethernet 等主设备通过 Avalon 总线控制 Memory / UART / GPIO / Timer / SPI 等从设备
  • Data Path(数据路径):FIR 等 DSP 模块通过 Avalon-ST(流式接口)直接处理数据流,旁路 CPU
  • 控制流和数据流分离,避免 CPU 成为数据吞吐瓶颈

2.5 复位与异常地址

  • 复位地址应设在非易失存储器中(如 Flash)
  • 异常地址由 HAL 库提供异常处理代码
  • 支持多种异常类型:软件异常、硬件异常

2.6 紧耦合主控制器(TCM)

  • 紧耦合指令主设备 + 紧耦合数据主设备
  • 连接到片上真双口 RAM(Tightly Coupled Memory)
  • 绕过 Avalon 互联,单周期访问,用于关键代码/数据的低延迟
  • 普通 Avalon 主设备仍可通过第二端口访问 TCM

2.7 硬件开发流程

  1. SOPC Builder 中配置 Nios II CPU 及外设
  2. 生成系统 HDL 代码
  3. 在顶层 Verilog/VHDL 文件中实例化 SOPC 系统模块
  4. 连接顶层端口与 SOPC 系统端口
  5. Quartus II 综合、布局布线、生成配置文件

2.8 常用外设

JTAG UART:单一 JTAG 链接实现多种功能

  • 器件配置、Flash 编程、程序下载、调试、STDIO(标准输入输出)

System ID 外设:保证硬件/软件版本同步

  • 两个只读寄存器:寄存器 1 存随机数,寄存器 2 存系统生成时间日期
  • 运行时检查,确认软件与当前硬件匹配

三速 Ethernet Megacore(TSE)

  • 集成 10/100/1000 Ethernet MAC
  • 通过 MegaWizard 配置,自动生成 ModelSim Testbench
  • 架构:MAC → 1000BASE-X/SGMII PCS → GX Serial Transceiver PMA

Avalon-ST 组件(用于数据流处理)

  • Bridges and Adapters:Channel Adapter / Data Format Adapter / Demultiplexer / Multiplexer / Timing Adapter
  • Peripherals:Avalon-ST Sink / Source / Performance Counter Unit / System ID

三、Nios II 软件开发

3.1 Nios II IDE

  • 基于 Eclipse 框架的集成开发环境
  • 欢迎页提供:Overview(概述)、Tutorials(教程)、What’s New(新特性)、Workbench(工作台)

3.2 两类工程

应用程序工程:建立可执行程序(.elf)

系统程序库工程(syslib):包含与硬件的接口

  • Nios II 设备驱动程序(硬件抽象层 HAL)
  • 可选 RTOS:MicroC/OS-II
  • 可选软件构件:轻量 TCP/IP 协议栈、只读 Zip 文件系统等

3.3 目录结构

hello_world/                    # 应用工程
├── Debug/                      # 编译输出
│   ├── hello_world.elf         # 可执行文件
│   ├── ext_flash.flash         # Flash 镜像
│   └── makefile
├── hello_world.c               # 源码
├── application.stf
└── readme.txt

hello_world_syslib/             # 系统库工程
├── Debug/
│   ├── system_description/     # 系统描述(system.h 等)
│   └── libhello_world_syslib.a # 静态库
├── Device Drivers/             # 各外设驱动
│   ├── altera_avalon_uart/
│   ├── altera_avalon_timer/
│   └── ...
├── Newlib C Library
└── system.stf

3.4 外设头文件与寄存器访问

每个外设都有对应的寄存器读写宏,命名规则:

// 读宏:IORD_<外设名>_<寄存器名>(base)
// 写宏:IOWR_<外设名>_<寄存器名>(base, data)
 
// 例如 UART 外设(altera_avalon_uart_regs.h):
#define IORD_ALTERA_AVALON_UART_RXDATA(base)   IORD(base, 0)
#define IOWR_ALTERA_AVALON_UART_TXDATA(base, d) IOWR(base, 1, d)
#define IORD_ALTERA_AVALON_UART_STATUS(base)   IORD(base, 2)
  • 宏的底层调用通用 IORD / IOWR 函数,传入外设基地址和寄存器偏移
  • 头文件位于系统库工程的 Device Drivers/<外设名>/inc/ 目录

3.5 运行与调试

  • 代码下载到目标板后通过 JTAG UART 输出到 Nios II 控制台
  • nios2-terminal 工具连接硬件目标的 JTAG UART
  • 支持标准 printf/scanf(通过 JTAG UART 实现 STDIO)

四、Avalon 互联总线

4.1 Avalon-MM 方框图

  • Avalon Interconnect Fabric:主从设备之间的点对点连接结构
  • 主设备:Processor(指令+数据)、DMA Controller(控制+读+写)
  • 从设备:Instruction Memory、Data Memory、SDRAM Controller、Tri-State Bridge、Ethernet MAC、Flash
  • 内部组件:MUX(多路器)、Arbitrator(仲裁器)
  • 信号类型:写数据与控制信号、读数据、片外设备接口

4.2 Avalon-MM 从动写传输

典型配置:0 建立周期 + 0 等待周期 + 0 保持周期

关键信号:

  • clk — 时钟
  • address, be_n — 地址 + 字节使能
  • writedata — 写数据
  • writen — 写使能
  • chipselect — 片选

4.3 Avalon-MM 时钟交叉桥接

适用于高吞吐量跨时钟域场景:

  • 连接不同时钟域的主设备和从设备
  • 可配置数据位宽
  • 支持流水线数据流的读写缓冲
  • 支持跨时钟域突发传输

典型用法:CPU(sys_clk 域)→ 时钟交叉桥 → 外设(test_clk 域)

4.4 已注册 Avalon Slave 实例(自定义外设结构)

Component Hardware
├── Application-Specific Interface Signals   应用特定接口
├── Task Logic                               任务逻辑(核心功能)
├── Register File                            寄存器文件
│   ├── Status Register     ←  任务逻辑写入状态
│   ├── Control Register 1  →  控制任务逻辑
│   ├── Control Register 2  →
│   ├── Data Register 1     ↔  数据双向传输
│   ├── Data Register 2     ↔
│   ├── Data Register 3     ↔
│   └── Other Registers
└── Avalon Slave Interface                   Avalon 从接口
    └── Avalon Slave Port Signals            对外总线端口

核心思想:总线访问全部通过寄存器文件中转,任务逻辑通过寄存器与总线交互。


五、自定义外设

5.1 参数化外设设计(Verilog)

  • 使用 parameter 定义可配置参数(如位宽、默认值)
  • 通过 SOPC Builder 的 Component Wizard 的 Parameters 面板暴露参数
  • 用户在添加外设时可通过 GUI 修改参数值
module my_peripheral #(
    parameter test_sig1 = 1,   // 默认值,可通过 Wizard 修改
    parameter test_sig2 = 2
) (
    clk, wr_data, cs, wr_n, addr, clr_n,
    rd_data, pwm_out, test_out1, test_out2
);

Component Wizard 配置表格含:Name、Default Value、Editable、Type、Tooltip。


六、自定义指令

6.1 概述

  • 完全集成到 Nios II 开发工具链
  • SOPC Builder 处理指令定制的设计工具
  • 自动生成 C 和汇编语言宏定义
  • 最多支持 256 种不同的自定义指令
  • 多周期指令可配置不同周期数
  • 支持指令参数化

6.2 内部寄存器文件 CI 端口

信号方向必需功能
readraInputNo为高时 dataa/datab 由 CPU 提供;为低时从内部寄存器文件按 a[4..0] 索引读取
readrbInputNo同上,对应 B 端口
writercInputNo写入结果到内部寄存器文件 c[4..0] 索引
a[4..0]InputNo内部寄存器文件索引 A
b[4..0]InputNo内部寄存器文件索引 B
c[4..0]InputNo内部寄存器文件索引 C

七、知识体系关联

相关 FPGA 培训笔记

延伸关联

要点速记

  1. Nios II 三种配置:Economy(无硬件乘)/ Standard(3周期乘)/ Fast(1周期乘)
  2. Avalon 总线核心:点对点互联、主从架构、动态位宽、时钟域交叉、多主仲裁
  3. 自定义外设模板:Avalon Slave 接口 + 寄存器文件 + 任务逻辑三层结构
  4. 自定义指令上限:256 条,支持多周期、参数化、内部寄存器文件
  5. 软硬件协同:SOPC Builder 生成硬件 → 自动生成 HAL 驱动 → Nios II IDE 编写应用 → JTAG 下载调试
  6. Control Plane + Data Path 分离:控制走 CPU + Avalon-MM,数据流走 Avalon-ST + DSP 模块