文章目录
- 概述
- 一、建立工程
- 二、设计输入
- 三、分析和综合
- 四、功能仿真
- 五、综合与布局布线
- 六、时序仿真
- 七、IO 分配以及生成配置文件
- 八、配置 FPGA 下载
- 九、固化程序到FLASH中
- 9.1、FPGA 固件存储方案介绍
- 9.2、Cyclone IV E FPGA 固件烧写方案
- 9.3、烧写文件 JIC 的产生
概述
科学合理的 FPGA 设计流程是为了更加直观地展示一个完整的设计流程,本节以一个基础的实验——二选一选择器,来介绍完整的 FPGA 设计开发流程。
良好的文件夹设置以及工程管理是学好 FPGA 设计的基础,在学习之初就应建立良好的习惯。因此首先在新建的工程文件夹下面,分别建立如下图所示的子文件夹。
各级目录作用释义如下:
- prj 为工程文件存放目录
- prj 文件夹下还建立了子文件夹 ip,用于存放 Quartus Prime 中生成的 IP 核文件
- rtl 为 verilog 可综合代码存放目录
- testbench 为测试文件存放目录
- img 为设计相关图片存放目录
- doc 为设计相关文档存放目录
一、建立工程
每个开发过程开始时都应建立一个 Quartus Prime 工程, Quartus II 以工程的方式对设计过程进行管理, Quartus II 工程包括创建 FPGA 配置文件需要的所有设置和设计文件。
打开安装好的 Quartus Prime 17.1 软件,软件启动界面及启动后的主界面如下图所示:
STEP #1
第一步, 单击 New Project Wizard 来启动一个工程向导。 会显示如下图所示的工程向导介绍,此处直接单击 Next 即可。
STEP #2
第二步,选择新建工程所在路径、设置工程命名以及「顶层设计实体名称」。在输入顶层设计实体时默认与工程名称一致,此处可根据具体情况来自行修改,这里我就直接使用默认设置了,如下图所示。
选择工程类型时可以选择一个全空的工程,也可以基于现有的工程模版来实现。此处选择新建一个空的工程,如下图所示。
STEP #3
第三步,添加已有设计文件。如没有, 可直接点击 Next,本次单击 Next, 如下图所示。
STEP #4
第四步,选择器件。在这里选择 Cyclone IV E 系列的 EP4CE10F17C8
,如下图所示。 这里可在右面红色框内可通过添加限定条件来减少需要翻看器件的目录。
❝小梅哥的AC501使用的是:Cyclone V 系列的
❞5CSEBA2U19I7
STEP #5
第五步, EDA 工具的选择。从上至下依次是综合工具、仿真工具以及板级工具, 可根据实际情况自行选择。在这里根据自己安装情况将仿真工具设置为 Modelsim-Altera,语言选择 Verilog HDL,其他选项可暂时不做处理, 如下图所示。
❝若「后期需要设置或更改 EDA 工具相关路径时」, 依次点击
❞[Tools] -> [Options] -> [General] -> [EDA Tool Options] -> ModelSim-Altera
STEP #6
第六步,出现设置信息概览页面,直接单击 Finish 完成工程的建立。
二、设计输入
工程建立完成后,需要为工程添加新的设计文件,单击 [File] -> [New] -> Verilog HDL File
,或者工具栏中的 New,弹出如下图所示的选择框,此处选择 Design Files 中的 Verilog HDL File,然后点击OK。
新的文件建立完成后,输入下述二选一多路器代码,并以 led.v
命名保存到工程对应的 rtl
文件夹下。
module led(a,b,key_in,led_out); input a;//输入端口 A input b;//输入端口 B input key_in; //按键输入,实现输入通道的选择 output led_out; //led 控制端口 默认是wire类型 //当 key_in == 0 : led_out = a assign led_out = (key_in == 0)? a : b;endmodule
简单解释代码,当 key_in 为低时,输出 led_out 和 a 相同,否之 led_out 和 b 相同。
❝默认勾选
❞Add file to current project
三、分析和综合
单击工具栏中的 Start Analysis & Synthesis
来进行分析和综合, 如下图所示。如在设计过程有错误的地方,在分析和综合后会提示 Error 或者 Warning,需针对不同情况进行修改。
❝常见的问题以及解决方式,可参见 www.corecourse.cn 网站上相关文章针对性解决。
❞
Quartus的右下角会显示进度和所用时间,如下图所示。
分析和综合没有问题后,依次点击[Tools] -> [Netlist Viewers] -> RTL Viewer
,可以看到如下图所示的硬件逻辑电路,即一个二选一选择器,符合设计预期。
四、功能仿真
STEP #1 编写测试激励文件
为了验证以上逻辑设计是否成功, 「在直接下载到开发板观察现象之前需要进行功能仿真(又称为行为级仿真或者前仿真)」,功能仿真首先需要编写激励文件,此处再新建一个 led_tb.v
文件并输入如下代码,保存到工程对应的 testbench
文件夹下, 并再次进行「分析和综合」查看是否存在语法设计错误。
`timescale 1ns/1psmodule led_tb; //激励信号定义,对应连接到待测试模块的输入端口 reg signal_a; reg signal_b; reg signal_c; //待检测信号定义,对应连接到待测试模块的输出端口 wire led; //例化待测试模块 led led0( .a(signal_a), .b(signal_b), .key_in(signal_c), .led_out(led) ); //产生激励 initial begin signal_a = 0;signal_b = 0;signal_c = 0; #100;//延时 100ns signal_a = 0;signal_b = 0;signal_c = 1; #100; signal_a = 0;signal_b = 1;signal_c = 0; #100; signal_a = 0;signal_b = 1;signal_c = 1; #100; signal_a = 1;signal_b = 0;signal_c = 0; #100; signal_a = 1;signal_b = 0;signal_c = 1; #100; signal_a = 1;signal_b = 1;signal_c = 0; #100; signal_a = 1;signal_b = 1;signal_c = 1; #200; $stop; endendmodule
简单解释下程序,timescale 指定程序的延时单位和精度。#200 的意思就是延时200ns,#200.123的意思就是延时200.123ns,即演示精度最多为ps级别,200123ps。提醒一点,需要注意下例化的对应关系。
STEP #2 设置仿真脚本
单击标题栏的 [Assignments] -> [Settings] -> Simulation
,「查看仿真工具以及语言是否与之前的设置一致」, 否则根据实际使用情况进行相应的修改,如下图所示。
选中上述界面下方的 Compile test bench 选项,然后单击其后的 Test Benches,可以看到如下图所示界面。
点击 New, 弹出如下图所示的 Test Bench 设置文件对话框,在 Test bench name 中填写对应的激励名称led_tb
(Top level module in test bench
会自动设置与其一样),接着找到已经编写好的激励文件,单击 Add,最后点击 OK 后回到主界面。
❝手动设置仿真时间为
❞10us
,方式如下图所示:
STEP #3 启动仿真
单击 [Tools] -> [Run Simulation Tool] -> RTL Simulation
来进行「前仿真」也就是常说的「功能仿真」,如下图所示。
❝[Tools] -> [Options] -> EDA ToolOptions 可以设置对应的仿真软件的路径
❞
STEP #4 仿真结果分析
至此, 即可在仿真软件 modelsim 中看到如下图所示的波形文件,可以看出符合设计预期, 当 key_in 等于 0 时 led_out 等于 a,当 key_in 等于 1 时 led_out 等于 b,即功能仿真通过。
五、综合与布局布线
点击 Quartus Prime 主界面的 Start Compilation,进行综合&布局布线, 如下图所示。布局布线过程中如遇出错, 应根据编译错误信息具体修改。
六、时序仿真
❝时序仿真又称为后仿真,后仿真之前需要把已打开的
❞Modelsim
关闭!
点击 [Tools] -> [Run Simulation Tool] -> Gate Leval Simulation
或者在工具栏点击 Gate LevalSimulation
进行后仿真, 也就是门级仿真,如下图所示。
弹出选择时序模型对话框,可针对相应情况具体选择。此时可选择第一个时序模型: 慢速工作、环境温度为 85℃、 内核供电 1.2V 的情况进行仿真, 如下图所示。
时序仿真完成后, 可以在 Modelsim 的波形窗口中看到图 2.2-23 的时序仿真波形。从波形中发现与之前的功能仿真相比有了一些差异,如: 「存在不希望存在的脉冲、 且在 200ns 时,led 相对输入信号有一定时间的逻辑延时」。
七、IO 分配以及生成配置文件
IO 分配其方法不唯一,常用的有三种。 在标题栏中 Assignments—Pin Planner 或者直接单击工具栏的 Pin Planner 进行 IO 分配, 如下所示。同时也可通过编写 Tcl 文件的方式来实现引脚分配,此处需针对不同板卡进行不同的设置。
以芯路恒 AC620 开发板为例, 最终的引脚分配如下图所示:
此处需注意, 在分配好引脚后,仍需再进行一次「全编译才能使引脚分配生效」。
八、配置 FPGA 下载
单击工具栏中的 Programmer, 如下图所示,弹出以下对话框。确认连接好下载器并在 Hardware Setup 中选中 USB-Blaster 以及被下载的.sof
文件后, 单击 Start 即可将设计好的逻辑电路下载到开发板中。
❝❞
sof
文件是下载到FPGA,掉电即丢失;jic
文件是固化到FLASH中,掉电仍存在!
通过按键以及两根杜邦线控制 P2 插接件下方的 GPIO0 (R1)以及 GPIO1(P2)接入不同的电平值, 可以观测到 led 灯(LED0)具有不同的亮灭效果。
九、固化程序到FLASH中
9.1、FPGA 固件存储方案介绍
Intel 或 Xilinx 的 FPGA 芯片,使用的是「基于 SRAM
结构的查找表」,而 「SRAM 的一大特性就是掉电数据会丢失」,当使用 JTAG 将 SRAM 配置文件(.sof
)配置到 FPGA 芯片中后,这些数据是「直接存储」在 SRAM 结构的「查找表」中的,因此,一旦芯片掉电,则 SRAM 中的数据将丢失,再次上电后, SRAM 中将不再有有效的数据。 而「普通的 MCU 内部集成了片上程序存储器 ROM,即使掉电后也能保存程序」。 这也就是常见的,使用 JTAG 下载 SOF 固件到FPGA 中后,板子重新上电,则之前下载的固件又不在了的原因。
当系统设计完成并验证结束后, 准备量产时,希望 FPGA 能够永久保持电路固件,即让FPGA 上电后其查找表中就被写入有效的数据。但是又不能总是每次系统上电后就用 JTAG去下载一次程序固件。因此, FPGA 支持另外一种配置方式:「主动串行配置」(AS)。
所谓主动串行配置,就是在 FPGA 芯片外部放置一片「能够掉电数据不丢失的存储器」,例如最常见的 EPCS、 QFLASH、并口 FLASH
,来存储设计好的电路固件。而 FPGA 芯片内部,则设计了一个专用的硬件电路,在芯片刚上电时就主动去读取存储器中的固件,并配置到FPGA 芯片的每一个 SRAM 中去。通过这样一种方式,可在不改变 FPGA 芯片 SRAM 工艺的查找表结构前提下, 使得芯片每次上电后,都能获得有效的配置数据。外部存储电路配置信息的芯片称之为「配置芯片」。
早前, 原 Altera 公司规定只能使用其自己发售的 EPCS 芯片作为外部配置器件,该 「EPCS 芯片实质就是一个 SPI 接口的串行 FLASH 芯片」, 只不过是经过了 Altera 的严格测试,性能优异。而近些年,随着芯片生产工艺的不断发展,很多其他厂家生产的 SPI 接口的 FLASH 芯片也能够达到 EPCS 的技术标准,因此 Altera 就放开了该限制,并指出可以使用其他芯片厂家生产的 SPI 接口的 FLASH 芯片代替 EPCS。在芯路恒的 AC620上就使用了一片「华邦公司生产的 16Mbit 的串行 FLASH 芯片 W25Q16 来作为配置芯片」。该芯片性能优异,性价比较高,完全能够达到 EPCS 的性能标准。
9.2、Cyclone IV E FPGA 固件烧写方案
当需要将设计好的配置固件固化到该器件中时,有两种方式。
- 第一种方式,也就是传统的方式,是使用「专用 AS 接口」(与 JTAG 10 针接口独立)来直接烧写该配置芯片,该种方式需要在电路板上设置一个独立的 AS 接口,占用 PCB 板面积较大,使用起来不方便。
- 第二种方式,也是现在流行的方式则是「通过 JTAG 接口」,经 FPGA 芯片间接烧写配置芯片,其电路如下图所示。 AC620 开发板没有设计独立的 AS 接口,因此只支持第二种烧写方式。
9.3、烧写文件 JIC 的产生
STEP #1
打开希望固化的 FPGA 设计工程, 此处以本节的工程为例。
STEP #2
在 Quartus Prime 软件中点击 File—>Convert Programming Files,如下图所示:
STEP #3
在弹出的窗口中, Programming file type 选择 JTAG Indirect Configuration File(.jic), Mode选择 Active Serial, Configuration device 选择 EPCS16, File name 默认是 output_file.jic,这里,我们养成良好的习惯,将其改成工程名字: led_test.jic, 如图 2.3-3 所示。
STEP #4
在 Input files to convert 一栏中,点击 Flash Loader 一项,在右侧点击 Add Device 选项,如下图所示:
STEP #5
在上一步弹出的选项卡中,选择 Cyclone IV E 下的 EP4CE10(AC620 开发板上的芯片为 EP4CE10F17C8,可根据实际情况进行选择),然后点击 OK,如下图所示:
STEP #6
点击 OK 后会回到先前的配置页面,此时鼠标再次点击 SOF Data,再点击右侧的 AddFile,如下图所示:
STEP #7
在弹出的窗口中,在工程生成的output files文件夹下找到“key_filter.sof”文件,点击Open,即可添加进来,如下图所示:
STEP #8
点击 Open 后,回到配置页面,点击 Generate 按钮,如下图所示:
STEP #9
点击 Generate 按钮后,软件开始转换文件,转换成功后弹出成功提示窗口,如下图所示:
STEP #10
点击 OK 即可,然后 close 窗口。
STEP #11
打开 Quartus Pime 中的下载工具 Programmer,「将原有的 sof 文件移除」, 点击 Add Files重新添加 Output Files 文件夹下的 led_test.jic 文件进来,勾选 Programming/Configuration,如下图所示:
STEP #12
设置完成后,点击 Start(确保此时下载器与开发板已经正确连接),则软件开始烧录固件,整个烧录时间大约花费 20 秒钟左右。
烧录完成后,此时固件已经保存在了配置芯片中,「但是此刻 FPGA 还不能运行该固件,因为当前的固件是存储在配置芯片中的,并没有被配置到 FPGA 中,因此需要让 FPGA 主动执行一次从配置芯片中配置固件的过程」,方法很简单, 「只需开发板断电后重新上电即可」。
此时, 使用杜邦线分别接触不同的电平值,就可以看到 LED 的状态发生变化。断电再上电,固件依旧保持,整个程序固化工作完成。