1. 环境准备与工程创建第一次接触FPGA软核开发的朋友建议先准备好以下环境。我用的Quartus II 18.1标准版搭配Cyclone IV E系列FPGA开发板。安装时记得勾选Nios II EDS组件这个后面调试会用到。实测发现如果漏装这个组件后期会遇到找不到Nios II命令行的尴尬情况。新建工程时有个容易踩坑的点在Device and Pin Options里一定要把Unused Pins设置为As input tri-stated。我去年带实习生时就遇到过有个小伙子的板子烧录后莫名发热排查半天才发现是这个选项没配置导致未使用引脚悬空引发短路。具体操作路径新建工程向导的第三步找到这个选项卡勾选即可。工程命名建议用英文下划线的形式比如nios2_mini_system。别用中文路径去年有个学员在Windows系统下用了中文目录Platform Designer生成文件时各种报错最后重装系统才解决。存储路径最好直接放在磁盘根目录比如D:/nios_project/避免多层嵌套。2. Platform Designer基础配置2.1 创建Nios II系统在Quartus菜单栏选择Tools - Platform Designer老版本叫Qsys这个工具相当于FPGA版的乐高积木。第一次打开时界面可能有点懵我教大家个记忆方法左边是零件库IP Catalog中间是组装台System Contents右边是接线图Connections。重点来了点击File - Save As命名为nios2_small。这里有个隐藏技巧名称不要带空格和特殊字符否则后续生成HDL文件时会报错。保存后立即在IP Catalog里搜索Nios II Processor双击后会弹出配置窗口。选择经济型Nios II/e内核时要注意这个型号只支持Level 1调试模块。去年我用Nios II/f内核时不小心选了Level 4调试模块结果占用了大量逻辑资源。对于简单应用经济型内核完全够用实测跑RT-Thread Nano都没问题。2.2 时钟与存储器配置找到clk_0右键重命名为clk_50对应开发板上的50MHz晶振。这里有个细节双击时钟源组件把Reset synchronous edges都选上这样能确保所有IP核同步复位。添加On-Chip Memory时建议初始设为40KB输入40960。这个大小足够运行小型RTOS了。我测试过放一个裸机程序大概占8KB加上RT-Thread Nano内核约20KB留点余量比较稳妥。命名建议改为onchip_mem后续写链接脚本时变量名更直观。3. 外设集成与系统连接3.1 JTAG UART添加在IP Catalog搜索JTAG UART直接双击添加默认配置。这个组件相当于系统的控制台后续调试打印都靠它。有个实用技巧在参数设置里把Write FIFO调到8字节Read FIFO调到64字节这样既能节省资源又保证通信流畅。连接信号线时要注意数据端口和指令端口都要连到CPU的data_master。有个常见误区是只连data_master结果程序能下载但无法运行。具体操作先点击CPU的instruction_master再点击onchip_mem的s1端口最后点击自动生成的connect按钮。3.2 地址与中断配置点击System - Assign Base Addresses自动分配地址。这里有个坑有时自动分配的地址不连续建议手动检查一下。正常情况应该是0x00000000开始分配每个外设占用2的N次方位宽。中断配置最关键一步在IRQ标签页下把jtag_uart的irq连接到CPU的irq0。我见过最奇葩的bug是有人把中断号设成了31结果调试时死活进不了中断服务程序。对于新手记住中断号从0开始按顺序用就对了。4. 系统生成与集成4.1 生成HDL文件点击Generate - Generate HDL这个过程大概需要1-3分钟。如果遇到Generation failed错误八成是时钟没连好。我常用的检查顺序先看CPU的clk接线再看reset信号最后检查各外设的时钟域。生成完成后别急着关闭先查看Generation Report重点检查两个地方Address Map和Interrupt Assignments。去年有个项目就是在这里发现UART地址和软件定义的不一致避免了后续的硬件调试悲剧。4.2 顶层原理图集成回到Quartus主界面新建Block Diagram文件。双击空白处在Project下找到nios2_small符号。这里有个隐藏功能按住Ctrl键拖动符号可以快速复制。添加qip文件时建议用绝对路径方式引入相对路径有时在团队协作时会出问题。最后编译前记得做三件事检查引脚分配我一般先用Pin Planner查看关键时钟引脚设置编译选项为Fast Compile快速验证开启Smart Compilation减少后续编译时间第一次编译可能会报时序错误别慌先把时钟约束加上。对于50MHz时钟简单加个create_clock -period 20.000 [get_ports {clk}]就能解决大部分问题。