HDL & FPGA 学习 - Quartus II 工程搭建,ModelSim 仿真,时序分析,IP 核使用,Nios II 软核使用,更多技巧和规范总结

目录

工程搭建、仿真与时钟约束

一点技巧

[ModelSim 仿真](#ModelSim 仿真)

[Timing Analyzer 时钟信号约束](#Timing Analyzer 时钟信号约束)

[SignalTap II 使用](#SignalTap II 使用)

[In-System Memory Content Editor 使用](#In-System Memory Content Editor 使用)

[记录 QII 的 IP 核使用](#记录 QII 的 IP 核使用)

[记录 Qsys/Nios II 相关](#记录 Qsys/Nios II 相关)

[记录 Qsys 的 IP 核使用](#记录 Qsys 的 IP 核使用)

[封装 Avalon IP](#封装 Avalon IP)

更多小技巧教程文章

更多好设计规范总结


编辑整理 by Staok,始于 2021.2 且无终稿。转载请注明作者及出处。整理不易,请多支持。

本文件是"瞰百易"计划的一部分,尽量遵循"二项玻"定则,致力于与网络上碎片化严重的现象泾渭分明!

本文系广泛撷取、借鉴和整理,适合刚入门的人阅读和遵守,已经有较多经验的人看一看图个乐,如有错误恭谢指出!本文已经是长期积累和堆叠而形成一定规模,不必按照从前到后的顺序去看,可以挑感兴趣的章节去看。

本文为简述风格,本意即记录要点和便于快速拾起。

本文对应的 Github/Gitee 仓库地址,本文最新的原文 和 一些源码、备查手册等等 均放在里面。


工程搭建、仿真与时钟约束
一点技巧
  • 安装 Quartus II 软件时候关闭杀毒软件。
  • 工程路径不能包含中文和空格!
  • 自动补全代码的功能 ,在 [Tools] -> [Options] -> [Text Editor] -> Autocomplete Text 里面选择启用。
  • 对于 Pin Planner,引脚的某一个属性可以复制,然后多选其他 I/O 对应属性的位置,再粘贴实现批量配置。
  • 针对硬件引脚固定的项目,先在 Pin Planner 写好所有引脚定义,然后导出,在 Pin Planner 界面里面点 左上角的 File 然后 Export 即可。以后在相同硬件平台创建新工程时可以直接导入这个引脚配置,在 Assignments 里面的 Import Assignments... 导入即可 。
  • 综合、布局布线后会生成"报告" ,里面一般会有 Warnings 和 Errors。这些报告信息会辅助你修改你设计中的 bug。
  • 三种优化模式(IDE 软件里可选):针对速度的优化;针对面积的优化;针对功耗的优化。
  • 检查 Quartus II 软件对于未使用引脚的处理。步骤:打开 Device -> Device and Pin Options,新打开窗口中找到 Unused Pins,只能选两个比较安全的选项:As input tr-stated with week pull-up 或者 As input tri-stated。在 Dual-Purpose Pins 里面,可以设置所有的 配置相关的 PIN 为 Regular I/O。
  • 逻辑固化需要 sof 转 jic,然后将 jic 下载,教程 Intel(Altera)FPGA的SOF转JIC文件和下载详细教程_rui22的博客-CSDN博客_sof转jic
ModelSim 仿真
  1. 确保 Quartus II 软件中 modelsim 的路径设置正确。步骤:Tools -> Options -> EDA Tool Options 里面,ModelSim-Altera 里面 设置正确路径 [盘符]:\intelFPGA\18.0\modelsim_ase\win32aloem

  2. 先对工程做一次全编译。然后手动操作 IDE 软件产生 仿真文件 testbench(相比于手写 testbench,当引脚很多时节省手写时间)。步骤: Quartus II 软件里面 Processing->Start->Start Test Bench Template Writer,生成 .vt 格式的 testbench 文件后,修改这个文件名与里面顶层模块名一致,可以将文件扩展名改为 .v。

  3. 添加仿真文件到 Setting 里的 Simulation 里面(这一步新人可看教程),并设置 testbench 文件 为工程顶层文件。

  4. 然后按照下面的样式修改仿真文件。

    一般仿真文件结构:

    `timescale 1 ns/ 100 ps /* 仿真时间单位和精度 */
    
    /* 设定时钟周期,这里为 20ns,即 50Mhz */
    `define clock_period 20
    
    /* 仿真文件的顶层模块 */
    module xxx_vlg_tst();
    
    // constants  
    // general purpose registers
    reg eachvec; /* 这个必须有。。。否则仿真不显示时序图 */
    
    // test vector input registers
    /* 这里定义模块内各种 wire 和 net */
    /* 把要仿真展示的信号的定义都放在这里 */
    
    // assign statements (if any)                          
    /* 这里例化被仿真模块,例子:
    pingPong_ram_module i1 (
    // port map - connection between master ports and signals/registers   
    	.rst_n_in(rst_n_in),
    
    	.clk_w(clk_w),
    	.data_w(data_w),
    
    	.clk_r(clk_r),
    	.addr_r(addr_r),
    	.data_r(data_r),
    
    	.read_valid(read_valid)
    ); */
    
    /* 产生时钟 */
    always #(`clock_period/2) clk_in = ~clk_in;
    
    initial
        begin
            $display("Running testbench");
    
            /* 在这里 复位/初始化 信号/寄存器 */
            clk_in = 0; /* 时钟信号初始值 */
            rst_n_in = 0;
    
            /* 或者用此产生激励源:
             forever #10 CLK_in = ~CLK_in;    重复运行语句直到仿真结束
             repeat(100) #5 CLK_in = ~CLK_in; 重复运行语句 100 次
            */
    
            rst_n_in = 0; #100 rst_n_in = 1;	/* 复位信号*/
    
            #1000;
    
            rst_n_in = 0; #100 rst_n_in = 1;	/* 复位信号*/
    
            $display("Stop testbench");
            $stop; /* 停止仿真 */
        end
    
    always
    	begin
         @eachvec; /* 这个必须有。。。 */
    	end
    endmodule
    

    打印调试信息:

    $display("%d",value);    // 与 printf 类似,但这个会自动换行
    $wirte("%d\r\n",value);  // 与 printf 一样
    // %od,%oh :以最少位输出,自适应
    // $time 为执行到当前位置的以 `timescale 为单位的时间计数整数;
    // $realtime 为以小数显示的执行到当前位置的以 timescale 为单位的时间。
    

    注意:设计仿真文件 testbench 的激励源的时候,对于边沿触发的信号其激励源要设计带有沿变化,否则不会生效。

  5. 确保把 testbench 仿真文件 设为 工程顶层文件后,再点 Analysis & Elaboration(分析 仿真文件),编译没问题后可以开始仿真了,Tools -> Run Simulation Tool,里面有 RTL 级别仿真(前仿真)和 门级仿真(后仿真)。

  6. ModelSim 软件自动打开和仿真并结束后,右边可以查看信号逻辑时序图,通过 "+" 或 "-" 按钮进行放大和缩小视图,左边可以手动增减信号,增减信号后需要 重新开始仿真 来更新。

  7. 在 ModelSim 里面重新仿真,先点 Restart,再在菜单栏找到 Run -All 则重新仿真。

Timing Analyzer 时钟信号约束

对于时钟信号的约束,必须要做,最基本要做的是使用 "TimeQuest timing Analyzer" 把设计内的所有时钟信号(包括晶振输入的时钟和 PLL 时钟)都约束一下。以下是具体步骤。

关于其他输入、输出引脚的约束以及外接器件的 Timing 约束比较深奥(内容多,但不难理解),更多内容可详看 "O.0 值得跟着的学习网站" 一节 中的 "时序分析 和 时序约束" 部分。

  1. 先对 Quartus II 工程 进行 全编译 一遍。
  2. 打开 Timing Analyzer。
  3. 选择菜单栏 Netlist -> Create Timing Netlist,弹出对话框保持默认(保持选择 Post-fit),确认。
  4. 添加要约束的时钟,在标题栏选择 Constrains 里面选择 Creat Clock 打开对话框,Targets 选择 Quartus II 工程里面的 一个时钟信号(搜索信号名字的时候可以这样写 *<信号名的一部分>*,两边通配符更好找),然后填入 Clock name(随意,可与 工程内时钟信号名保持一致),Period 为该时钟的周期,如实填写,上升和下降的时刻 分别写上 0 和 Period 的一半即可,再点 Run。关闭对话框。
  5. 左边 Task 栏里面 依次双击 Update Timing Netlist 和 Write SDC File,第二个是保存 sdc 文件,选择一个合适的文件名和位置。然后可以关闭 Timing Analyzer。根据设置生成 sdc 约束文件,里面是约束的命令语句。
  6. 在 Quartus II 工程中添加自己生成的 sdc 文件,点击 Assignments -> Settings 里面的 Timing Analyzer,添加上面生成的 sdc 文件,关闭。可以看到 Quartus II 工程中 File 多了该 sdc 文件。然后对 Quartus II 工程 全编译。
  7. 再进入 Timing Analyzer,左边 Task 栏下面 先双击 Read SDC File,再找到左边 Task 栏下面 Macros 里面的 Report All Core Timing,双击打开,可以在右边栏看到 综合布线后各个信号线的传递裕量(Slack),为从小到大配列,该值为正的即可,越大越好。左边的其他栏目可以看到建立时间、保持时间的裕量等更多信息。

教程参考:quartus II关于时钟约束_ a346544987的博客-CSDN博客 _quartus时钟约束

用 cdc 文件对 时钟进行时序约束非常重要,在对 逻辑工程 进行全编译后 若 timing analysis 中 显示 有时钟信号未被约束(红色),那么此时综合出来的逻辑肯定是有问题的,必须对 提示的 未约束的 信号 相关的 时钟信号 设置 始终约束 一下,经验:可以按照可能用到的最高时钟频率进行约束,始终约束的频率设置的高,达到 MHz 级别 才更能成功约束住,如果很低反而处理不了。

如果 FPGA 的逻辑资源的使用率达到 90% 以上后有可能就无论如何也无法约束了,不会把逻辑资源用满,留多一些逻辑资源裕量,方便综合器布线和约束。

SignalTap II 使用

SignalTap II 捕获和显示 FPGA 内部的 实时信号。其占用 FPGA 内部部分逻辑和 RAM 资源,进行存储,并通过 JTAG 发送到 PC 上的 SignalTap II 软件来观察时序图,其采样深度会受 FPGA 内部 RAM 限制,一般够用。

  1. 先不用修改 Verilog HDL 源文件。在 Quartus II 主界面选择菜单栏的 Tools->SignalTap II Logic Analyzer,打开 SigalTap II 软件,如下图所示(图源自正点原子的《开拓者FPGA 开发指南》),双击 节点列表和触发条件 栏 的空白区域来添加要监测的信号,在打开的窗口里面 首先将 Filer 设置为 SignalTap II:pre-synthesis(与 Verilog 设计中存在的信号最为贴近,方便寻找信号),再点击 List,完成信号添加点 OK 即可。添加进来的信号,在 Trigger Cond 一列 可以在某个信号上 右击 选择一种触发方式。

  2. 如果我们发现添加的信号变成了红色,或者有些 reg 与 wire 定义的信号可以观察,有些不可以,这是因为 reg 与 wire 被 Quartus 软件优化掉了,导致无法使用 SignalTap 观察。一种简便的方法是 对 这些信号添加 不要优化掉的注释来标记,如下所示,注意注释是加在 分号 前面。然后再在 SignalTap 软件里面添加试试。

    wire [23:0] counter/*synthesis keep*/;
    reg  [23:0] counter/*synthesis noprune*/;
    
  3. 在 SignalTap 右边的 Signal Configuration 栏里面设置采样时钟、采样深度、采样方式、触发方式、触发条件等。必须设置的是 采样时钟 Clock 和 采样深度 Sample depth,采样深度可以设置为 2K。如果不需要设置 采样方式和触发等,其它选项保持默认即可。

  4. 在 SignalTap 软件左上角保存 软件设置文件 .stp,接下来会弹出是否将分析文件添加至工程的页面,点 Yes 即可,可以在 Quartus 软件左边的工程文件栏看到 刚刚添加 的 SignalTap 文件 .stp,也可以在 Assignments -> Settings 里面的 Signal Tap Logic Analyzer 里面 看到 Enable Signal Tap Logic Analyzer 选项 被打勾,并且 SignalTap 文件 .stp 被添加了进来。

  5. Quartus 软件里面 对工程进行 全编译。

  6. 给板子上电,连接好 Blaster,回到 SignalTap 软件界面,在软件右上角 的 JTAG 设置区 点 Setup 找到 并选择 USB-Blaster[USB-0],点 OK,再在 JTAG 设置区 点 Scan Chain 来扫描到 FPGA 芯片,然后在 SOF Manager 的右边 添加 刚刚全编译好的 .sof 工程文件,然后点 下载标志的按钮来下载。

  7. 下载完后,点击 SignalTap 软件 工具栏 中的开始分析图标(Instance Manager 右边的第一个按钮),即采样一次(以设置的采样深度来采集一次),从左到右三个按钮分别为 采样一次、循环采样 和 停止。

  8. 节点列表和触发条件 栏的 下面 切换到 Data 页面,即可看到信号的采样的时序图,鼠标左键单击放大、右击缩小。信号的名字上右击 选择 Display Format 可以切换 显示 16 进制或 其它进制。

  9. 切换信号的触发方式,在 SignalTap 信号列表 Setup 一栏中,右击 信号的 Trigger Conditions 方框内的图标,其中:Don't Care 表示不关心,即不设置触发方式;Low 表示低电平触发;Falling Edge 表示下降沿触发;Rising Edge 表示上升沿触发;High 表示高电平触发;Either Edge 表示双沿触发,在此栏的最上边可以选择 这些信号的触发条件的 与或非 组合 来启动触发。然后再点 开始分析按钮 的 采样一次按钮,这是采样会等到 信号的 触发事件发生后再开始采集。因此触发可以给 外部按键信号 或 关键的信号 来触发开始采样。对于多位的寄存器可以设置某个 计数值 来触发采样。

推荐教程:

In-System Memory Content Editor 使用

Quartusii 调试工具中的 In-System Memory Content Editor,其主要功能就是能实时更改 RAM,ROM 中的数值,同时也可以修改 FPGA 内部定义的常数值。

实时查看 FPGA 内建 RAM 的值,很方便的工具。还可以导出数据,格式有 hex 和 mif。

推荐教程:

记录 QII 的 IP 核使用

官网文档查询

这里是最全、最准确的 原理和用法的详细介绍,用新外设好好看这里就能快速上手!

  • 《Introduction to Intel® FPGA IP Cores》以及 各个 IP 的手册。在官网可以下载到。
  • 本仓库的 Quartus II + Nios II 的 IP核手册 文件夹里面。本文对应的 Github/Gitee 仓库地址,本文最新的原文 和 一些源码、备查手册等等 均放在里面。

已经添加的 IP 核 是可以再编辑参数的,在 QII 软件左上角 的 Project Navigator 右边下拉框选择 IP components 里面可以看到所有添加的 IP,双击可以再编辑参数,若不能,则重新打开 QII 工程一下再试试。

PIO

提醒一点,使用 IO 中断时候,要确保 IO 接到一个确定的电平,不要空接,否则循环进入中断导致 NIOS II 看起来不运行。

NCO 正弦波合成

ALTDDIO_IN

ALTPLL

使用 FPGA 内 PLL 资源做 预先自定义的频率、相位的时钟信号,一个 PLL 最多输出 五路。

  • 可选的 带有 复位端(areset) 和 锁相成功指示端(locked) 等。

  • 一个 实例化 例子如下。

    pll pll_inst
    (
        .areset ( !rst_n_in ),      /* 高电平输入复位 PLL,rst_n_in 可以是全局复位信号 */
        .inclk0 ( CLK_50M_in ),
        .c0 ( pll_10k_out ),
        .c1 ( pll_1M_out ),
        .c2 ( pll_100M_out ),
        .locked ( pll_locked_out )  /* 高电平输出表明 PLL 开始正常工作,
                                      pll_locked_out 可以是使用这个 PLL 时钟输出的模块的使能信号/复位信号等 */
    );
    
记录 Qsys/Nios II 相关
  • Nios II自学笔记一:Nios II软硬件架构介绍_搬砖的MATTI的博客-CSDN博客_nios

  • nios自学笔记二:一个简易的Qsys系统的开发流程_搬砖的MATTI的博客-CSDN博客_qsys

  • NIOS II使用经验_shimmy_lee的博客-CSDN博客_nios

  • 关于 SOPC,Nios II Eclipse 里面的 BSP 包里的 drives 文件夹里面的 _reg 后缀 的 .h 文件里面为自加的 Nios II 外设的可调用的 API。

  • Nios II 默认禁止中断嵌套。

  • 关于 SOPC 中的 NIOS II 的 复位、异常向量 存放 (即程序存储 和 运行)位置 的几种方案:

    1. 复位、异常都在 内建ram里;
    2. 复位在 flash 里,异常在 内建ram里;
    3. 复位在 flash 里,异常在 ddr(sdram 或 lpddr2 等 控制器 IP) 里。

    以上每一种情况都可以 下载到 ram 调试 和 进行固化(两种方法)。具体见下面 "程序调试" 和 "程序固化" 几段话。

  • 关于 Nios II software build tool for eclipse 这个 IDE 的设置:

    • file->new->Nios II ...Template 从 .sopcinfo 文件获取信息新建 hello world 模板项目,工程名暂定为 Temp。

    • 主工程目录可以 在源工程目录里面去操作 创建和整理,也可以在 eclipse IDE 里面设置。

      • 在源工程目录里面操作:把 需要 include 并且要放入编译路径的其他程序文件分好文件夹,都放入 工程文件夹 Temp 里面,并把含有主函数 main() 的 .c 文件替换默认生成的 Hello World.c 文件。添加好工程文件之后,在 Eclipse 的主工程文件夹 Temp 上面 右击 选择 refresh 一下,即可更新好工程目录。
      • 在 IDE 里面操作:在 IDE 中,右击工程名 Temp,选 New->Source Folder,把同上一步的文件夹添加进来;然后右击工程名 Temp,选 Refresh。
      • 若源程序文件 不是 GBK 编码的,则 打开一个文件之后,在 Edit->Set Encoding 里面选择 相应的编码即可。或者统一设置:在 IDE 中,右击工程名 Temp,选 Properties,在 Resource 里面 改成 utf-8。
    • 添加工程里面所有头文件:在 IDE 中,右击工程名 Temp,选 Properties,在 Nios II App.. Path 里面的 App include directories 里面添加需要 include 的其他程序文件夹。

    • 关于 BSP 包设置:在 IDE 中,右击工程名 Temp,Nios II->BSP Editor,选择里面 enable_reduced... 和 enable_small_c 这两个选项,再到 linker Script 栏 里面点击 Retore Defaults,这会自动根据 sopc 中 nios ii 中 复位、异常向量存储位置的设置 来分配 软件程序 各个段 的分配,最后再点右下角的 Generate,等待完成后再关闭。

    • 每次使用 Qsys 生成 SOPC 之后都要在 Quartus II 里面进行全编译一次,再下载最新的 .sof;每次在 Quartus II 里面全编译 之后,在 NIOS II 的 eclipse 里面都要重新生成 Generate BSP 一次,才能进行 NIOS II 的 软件程序的编译。

    • 关于编译:在 IDE 中,菜单栏 Project 里面 选择 Build All,会同时编译 程序工程 和 BSP 工程。也有这样的:在 IDE 中,右击工程名 Temp,选 Build Project。把杀毒软件关掉会大大加快编译速度。。。

    • 关于下载:工程全编译之后会生成 .elf 文件;这时应该确保在 Quartus II 里面对 逻辑部分 进行了全编译并且下载到 fpga 里面了,并保持其运行,此时在 eclipse 里面 右击 Temp 选择 Run As 里面的 ...Hardware 选项 进入下载页面,找到 Target Connection 栏 点 Refresh Connection 可以看到有 Processor 的识别,可以把下面的 system id check 里面的两个 ignore 打勾,然后点击 run 即可下载软件程序的 .elf 到 fpga 里面运行,点击 run 之后会回到 eclipse 界面,注意右下角的进度,进度完成之后 nios ii 软件程序就开始运行了。再编辑程序然后 Build All 之后,再 右击 Temp 选择 Run As 里面的 ...Hardware 可以直接下载程序而没有选择框,或者在 菜单栏 选择 Run->Run As->...Hardware 或者 选择 Run->Run 同样。

    • 一定要确保,在 Quartus II 里面对逻辑进行全编译然后下载到板子里面,然后 eclipse 里面 点击 generate BSP 之后再 编译软件程序,再通过 Run Config.. 里面确认识别到 板子里的 sopc 系统 再 下载 nios ii 软件程序 跑在 对应的 sopc 上面。如果 fpga 有固化 sopc 系统,那么在 下载最新逻辑 .sof 之后,如果点了 复位 或者 fpga 重新上电了,那么这时 fpga 里面就不是最新的 逻辑了而是 可能之前固化的 旧逻辑,这时候下载 nios ii 程序 进去 也许能运行 但不会运行正确了。因此要保证 fpga 里面的逻辑 与 要下载 的 nios ii 程序都是最新的 或 是一一对应的。

    • 关于程序没有语法错误但是编译报错:关于NiosII的报错make: *** XXX.elf Error 1_万世奋飞的博客-CSDN博客

      一般有:

      1、右击BSP工程--NiosII--Generate BSP。

      2、Qsys硬件存储大小不够。

      3、BSPEditor--enable_small_c_library和enable_reduced_device_drivers。

      4、针对QuartusII13.0sp1的Qsys,在设计带有Timer的硬件,比如ucosII系统等有此要求。

      • 若在 IDE 里面 Run 或者 Debug 时候显示 "make:[../..._bsp-recurs-make-lib] Error 2" 错误,则在 IDE 中,右击工程名 Temp,Nios II->BSP Editor,再点一下右下角的 Generate,并关闭重新编译,Run,试一试。

        或者就是由于 分给 存储程序的 ram/rom 小于编译后需求的大小。

      • 主程序c文件中,编译时报错symbol xx could not be resolved.原因是该头文件未被更新。可选中软件工程及其bsp文件夹,右键->index->fresh all files更新所有文件,报错一般会消除。

      • 如果 NIOS II 程序调试好了,关闭全部软件下次再打开和下载又不好使了,那么就全部重编译、下载一遍:Quartus II 里面对 所有逻辑(包括Qsys)全编译一次(此过程也会重新生成Qsys 的 SOPC 系统 而不必去 Qsys 里面去重新生成 SOPC 系统),再下载逻辑,再到 eclipse 里面 重新 generate BSP,然后编译 nios ii 软件程序 然后下载(Run)即可。

      • NIOS II EDS中出现TYPE 'XXXX_BASE' COULD NOT BE RESOLVED的解决方法_lpwin81的博客-CSDN博客

  • 程序调试(下载到 ram 中运行,逻辑只全编译一次生成 .sof 并下载,然后去下载 nios ii 软件编译后的 .elf,每次调试只下载 nios ii 程序):

    程序调试 见上面 "关于下载:" 一段话。

  • 程序固化(下载到 flash 中运行,每次下载 都需要全编译 逻辑 和 nios ii 程序),两种方法:

    1、nios ii 复位向量在 flash 的方法:网友教程,这个方法要 sopc 的 nios ii 的复位向量在 flash,niosii 把程序固化到epcs中的步骤_mail-mail的博客-CSDN博客_nios固化。然后在 eclipse 里面编译 nios ii 软件程序 然后 Nios II->Flash Programmer 里面添加 最新逻辑全编译文件 .sof 和 最新 nios ii 程序编译文件 .elf 然后下载到 flash 里面。推荐这种方法。

    2、nios ii 复位、异常向量均在 ram 的方法:这个方法是不用 sopc 的 nios ii 的复位向量在 flash 里面,即 这个方法 适用于 nios 的复位、异常向量均在 内建 ram 或 外部 sdram/ddr 里面。1、开始编译,在 IDE 中,右击工程名 Temp,选 Build Project(或者用 菜单栏 Project 里面 选择 Build All),成功后再 Make Targets->Build,里面选 mem_init_generate ,再点 Build。2、然后再把 Temp 文件夹里面的 mem_init 文件夹里面的 meminit.qip 文件加到 Quartus 工程中,再全编译产生一个 .sof 文件,进而转 .jic 文件进行固化。

    两种方法都说到的在这里面有:NIOS II 软件程序固化的相关知识 - 走看看 (zoukankan.com),这里面第一个就是这里的 nios ii 复位、异常向量均在 ram 的方法 方法。

    批量量产的方法:nios自学笔记四:将sof和elf合并为JIC文件_搬砖的MATTI的博客-CSDN博客_sof和elf怎么一起转化成jic文件

记录 Qsys 的 IP 核使用

官方文档查询

多看 官方文档。

  • Nios II 的 IP核 使用参考手册 《Embedded Peripherals IP User Guide》。
  • Nios II 的 部分 IP核 的软件编程手册 《Nios® II Software Developer Handbook》。
  • 上面两个手册均离线在 本仓库的 Quartus II + Nios II 的 IP核手册 文件夹里面。本文对应的 Github/Gitee 仓库地址,本文最新的原文 和 一些源码、备查手册等等 均放在里面。

一个 基本 SOPC 系统搭建要添加的 外设 IP 列举

  • Clock Source 外设 clk_0。要设置为 真实输入的时钟的频率,并对 clk frq known 打勾(后面的其它外设的频率相关的设置都与这个直接相关)

  • Nios II Processor。

  • On-Chip Memory (RAM or ROM) Intel FPGA IP,需要连接 NIOS 的 数据总线 和 指令总线。fpga 内建 ram 当作 nios ii 处理器的 内存(用来 存放、设置为 异常向量、复位向量)。

    也可以将 DDR(比如 SDRAM、LPDDR2 等) 设置为 异常向量、复位向量 存放的地方,而不用内建 ram 了就。当删除 SDRAM/DDR IP 的时候,应该 在 NIOS IP 参数里面 将 异常 地址选择那里选择其它 存储器(需要手动改,软件不会自动改)。

  • Legacy EPCS/EPCQx1 Flash Controller Intel FPGA IP。或者加一个 epcs/epcq 控制器 ip,然后 nios ii 的复位向量选择 这个。使用 EPCQ256 之类的 可以用 Flash Serial controller II IP,在里面选择 FLASH 型号。

  • sysid。

  • UART (RS-232 Serial Port) Intel FPGA IP。

  • Interval Timer Intel FPGA IP。

  • PIO (Parallel I/O) Intel FPGA IP。

SOPC 的 Nios 2 处理器构建时(Qsys 或 SOPC Builder里面)可以只加 RAM 或 DDR(不用 ROM)(RAM 大小:经验值至少大于10KB)(这里的 RAM 是 FPGA 里面的 M9K 存储器,不是外接 RAM 芯片的)来运行程序。当外设较多时,NIOS II 的底层驱动 HAL 库非常大,对于储存空间紧张的 FPGA 用 RAM + ROM 会资源不够,所以只用 RAM 且设置足够大。NIOS II processer 设置复位和中断向量均在 RAM 里面。

SOPC系统构建(Qsys 或 SOPC Builder里面)还是得尽量添加 EPCS 存储器件 (如果板子只有一个 EPCS Flash(一般都是一个),那就是与 FPGA 存放逻辑共用的那个存储器件 )控制器和 SRAM (或 SDRAM)控制器(板子上要有至少一个 RAM 芯片),否则只靠 FPGA 的片上存储空间写 Nios II 程序,那么能写的程序太少了(HAL 库就占了非常多容量),非常受限。

一个例子:DMA测试能用,各个连接都对之后再截图放这里

PIO

SDRAM

软核中的使用例程如下(默认16位数据位)。

cpp 复制代码
 /* 写 *(ram_base) = i;  读 *(ram_base)*/
unsigned short * ram_base = (unsigned short *)(SDRAM_0_BASE+0x10000);

其它 带有 HMC(硬件内存控制器,支持如 LPDDR2、DDR3 等)的 FPGA,可以在 Qsys 里面直接添加这个 外设 IP,然后在 NIOS II 编程时候 如上一样,通过指针指针直接访问。

EPCS

SPI

DMA

NIOS II 软件程序自整理模板

直接看 NIOS II 软件编程一个自己整理的模板,里面对实用 Qsys IP 的使用和寄存器说明等,如 PIO、TIMER、UART、SPI、DMA、EPCS 等等,做了详细注释,和程序例子可以直接用。

见 Github/Gitee 仓库:本文对应的 Github/Gitee 仓库地址,本文最新的原文 和 一些源码、备查手册等等 均放在里面。

封装 Avalon IP
  • 每一个外设尽量封装成 Avalon 接口的 IP 核,加入到 Nios II 的外设中;IP 核的设计分为三个层次,Avalon 接口层,寄存器层和逻辑层(输出层),Nios II 软件只需操作/读写 IP 核的寄存器组即可控制该 IP 核所有功能。
  • 创建自定义 IP 核一个详细教程 Quartus创建自定义IP核 - LED控制IP核_欢迎光临-CSDN博客

更多小技巧教程文章

更多好设计规范总结


相关推荐
IM_DALLA8 小时前
【Verilog学习日常】—牛客网刷题—Verilog进阶挑战—VL25
学习·fpga开发·verilog学习
辣个蓝人QEX9 小时前
【FPGA开发】Modelsim如何给信号分组
fpga开发·modelsim·zynq
li星野12 小时前
ZYNQ:点亮LED灯
fpga开发·zynq·7010
9527华安12 小时前
FPGA实现PCIE视频采集转HDMI输出,基于XDMA中断架构,提供3套工程源码和技术支持
fpga开发·音视频·pcie·xdma·ov5640·hdmi
乌恩大侠13 小时前
【Xcode Command Line Tools】安装指南
macos·fpga开发·c
apple_ttt14 小时前
从零开始讲PCIe(9)——PCIe总线体系结构
fpga开发·fpga·pcie
Little Tian17 小时前
信号用wire类型还是reg类型定义
fpga开发
XiaoChaoZhiNeng1 天前
基于Zynq SDIO WiFi移植二(支持2.4/5G)
5g·fpga·zynq·sdio
apple_ttt1 天前
从零开始讲PCIe(6)——PCI-X概述
fpga开发·fpga·pcie
水饺编程2 天前
【英特尔IA-32架构软件开发者开发手册第3卷:系统编程指南】2001年版翻译,1-2
linux·嵌入式硬件·fpga开发