本书使用Altera公司的Cyclone Ⅳ FPGA器件,由浅入深地引领读者从板级设计、基础入门实例、FPG内资源应用实例和综合进阶实例等方面,玩转FPGA逻辑设计。本书基于特定的FPGA实验平台,既有足够的理论知识深度作支撑,也有丰富的例程供实践学习,并且穿插了笔者在多年FPGA学习和开发过程中所积累的经验和技巧。 无论对于希望快速掌握Verilog语言进行FPGA开发的初学者,还是希望快速掌握基于Altera Cyclone Ⅳ FPGA进行开发的设计者,本书都是很好的选择。
(1)本书由《深入浅出玩转FPGA》一书的作者吴厚航(网名:特权同学)倾心打造。(2)供FPGA板级设计说明、工具安装说明、入门实例、片内资源应用实例和综合实例,由浅入深地掌握FPGA的开发设计。(3)使用Altera公司的Cyclone Ⅳ FPGA器件既有足够的理论知识深度作支撑,也有丰富的例程进行实践学习,并且穿插着笔者多年FPGA学习和开发过程中的各种经验和技巧。
作者简介吴厚航[网名:特权同学] 有近10年的FPGA工程实践经历,擅长记录、分析并总结FPGA开发中的经验与技巧,也非常乐于分享。活跃于各大电子技术网站的FPGA社区或版块,多年来笔耕不辍、风雨无阻,不断地发表FPGA相关文章,其总点击量超过300万。著有多本FPGA技术相关图书,其诙谐的文字、贴近读者实际需求的知识点与经验技巧分享,赢得了广大读者的一致认可。
目录
Contents
第1章FPGA开发入门
1.1FPGA基础入门
1.2FPGA的优势在哪里
1.3FPGA应用领域
1.4FPGA开发流程
第2章实验平台“勇敢的芯”板级电路详解
2.1板级电路整体架构
2.2电源电路
2.3复位与时钟电路
2.3.1关于FPGA器件的时钟
2.3.2关于FPGA器件的复位
2.3.3实验平台电路解析
2.4FPGA下载配置电路
2.5SRAM接口电路
2.6ADC/DAC芯片电路
2.7UART接口电路
2.8RTC接口电路
2.94×4矩阵按键电路
2.10VGA显示接口电路
2.11蜂鸣器、流水灯、数码管、拨码开关电路
2.12超声波接口、外扩LCD接口电路
第3章逻辑设计基
3.10和1——精彩世界由此开始
3.2表面现象揭秘——逻辑关系
3.3内里本质探索——器件结构
第4章软件安装与配置
4.1软件下载和license申请
4.2Quartus Ⅱ与ModelSimAltera的安装
4.3文本编辑器Notepad 安装
4.4QuartusⅡ中使用Notepad 的关联设置
4.5USBBlaster的驱动安装
4.5.1Windows XP系统USBBlaster安装
4.5.2在Windows 7系统安装USBBlaster
4.5.3在Windows 8系统安装USBBlaster
4.6串口芯片驱动安装
4.6.1驱动安装
4.6.2设备识别
第5章Verilog语法概述
5.1语法学习的经验之谈
5.2可综合的语法子集
5.3代码风格与书写规范
勇敢的芯伴你玩转Altera FPGA
第6章基于仿真的及时个工程实例
6.1新建工程
6.2Verilog源码文件创建与编辑
6.2.1Verilog源码文件创建
6.2.2Verilog源码文件编辑
6.3Verilog语法检查
6.4ModelSim仿真验证
6.4.1Quartus Ⅱ基本设置
6.4.2测试脚本创建与编辑
6.4.3测试脚本关联设置
6.4.4调用ModelSim仿真
第7章基于板级调试的第二个工程实例
7.1PWM蜂鸣器驱动——功能概述
7.2PWM蜂鸣器驱动——引脚分配
7.3PWM蜂鸣器驱动——综合、映射与配置文件产生
7.4Altera FPGA配置方式
7.4.1概述
7.4.2配置方式
7.5PWM蜂鸣器驱动——FPGA在线下载配置
7.6PWM蜂鸣器驱动——FPGA配置芯片固化
7.7PWM蜂鸣器驱动——复位与FPGA重配置功能
第8章基础入门实例
8.1蜂鸣器开关实例
8.1.1功能简介
8.1.2代码解析
8.1.3打开工程
8.1.4下载配置操作
8.2流水灯实例
8.2.1功能简介
8.2.2代码解析
8.2.3下载配置
8.338译码器实例
8.3.1功能简介
8.3.2代码解析
8.3.3板级调试
8.4按键消抖与LED开关实例
8.4.1按键消抖原理
8.4.2功能简介
8.4.3代码解析
8.4.5板级调试
8.5经典模式流水灯实例
8.5.1功能简介
8.5.2代码解析
8.5.3板级调试
8.6基于PLL分频计数的LED闪烁实例
8.6.1PLL概述
8.6.2功能简介
8.6.3新建IP核文件
8.6.4PLL配置
8.6.5模块化设计概述
8.6.6模块化设计实践
8.6.7代码解析
8.6.8板级调试
8.7数码管驱动实例
8.7.1数码管驱动原理
8.7.2功能概述
8.7.3代码解析
8.7.4板级调试
8.8SRAM读写测试实例
8.8.1SRAM读写时序解读
8.8.2功能简介
8.8.3代码解析
8.8.4仿真设置
8.8.5功能仿真
8.8.6FPGA在线配置
8.8.7触发采样波形
8.9UART loopback测试
8.9.1功能概述
8.9.2代码解析
8.9.3板级调试
8.10VGA驱动ColorBar显示实例
8.10.1VGA概述
8.10.2功能简介
8.10.3代码解析
8.10.4板级调试
8.11LCD基本驱动实例
8.11.1LCD驱动时序
8.11.2功能简介
8.11.3代码解析
8.11.4装配
8.11.5板级调试
8.12LCD字符显示驱动实例
8.12.1字符取模
8.12.2ROM初始化文档创建
8.12.3新建源文件
8.12.4ROM配置
8.12.5功能简介
8.12.6代码解析
8.12.7板级调试
8.13矩阵按键扫描检测实例
8.13.1键盘概述
8.13.2矩阵按键工作原理
8.13.3功能概述
8.13.4代码解析
8.13.5RTL Viewer
8.13.6State Machine Viewer
8.13.7Technology Map Viewer
8.13.8板级调试
第9章FPG内资源应用实例
9.1基于SignalTap Ⅱ的超声波测距调试实例
9.1.1超声波测距原理
9.1.2功能简介
9.1.3代码解析
9.1.4硬件装配
9.1.5SignalTap Ⅱ源文件创建
9.1.6SignalTap Ⅱ配置
9.1.7SignalTap Ⅱ调试
9.2FPG内ROM实例
9.2.1功能概述
9.2.2代码解析
9.2.3ROM初始化文档创建
9.2.4新建IP核源文件
9.2.5ROM配置
9.2.6功能仿真
9.2.7FPGA在线调试
9.3FPG内RAM实例
9.3.1功能概述
9.3.2代码解析
9.3.3新建IP核源文件
9.3.4RAM配置
9.3.5功能仿真
9.3.6FPGA在线调试
9.4FPG内FIFO实例
9.4.1功能概述
9.4.2代码解析
9.4.3新建IP核源文件
9.4.4FIFO配置
9.4.5功能仿真
9.4.6FPGA在线调试
9.5FPG内异步FIFO实例
9.5.1功能概述
9.5.2代码解析
9.5.3新建IP核源文件
9.5.4FIFO配置
9.5.5功能仿真
9.5.6FPGA在线调试
9.6FPG内ROM、FIFO、RAM联合实例
9.6.1功能概述
9.6.2代码解析
9.6.3功能仿真
9.6.4FPGA在线调试
第10章综合进阶实例
10.1基于数码管显示的超声波测距回响脉宽计数实例
10.1.1功能简介
10.1.2代码解析
10.1.3板级调试
10.2基于均值滤波处理的超声波测距回响脉宽计数实例
10.2.1功能简介
10.2.2滤波算法与实现
10.2.3代码解析
10.2.4板级调试
10.3基于进制换算的超声波测距结果显示实例
10.3.1功能简介
10.3.2距离计算公式实现
10.3.3进制换算实现
10.3.4代码解析
10.3.5乘法器IP核创建、配置与例化
10.3.6除法器IP核创建、配置与例化
10.3.7板级调试
10.4倒车雷达实例
10.4.1应用背景
10.4.2功能简介
10.4.3代码解析
10.4.4板级调试
10.5基于SRAM批量读写的UART bulk测试实例
10.5.1功能概述
10.5.2代码解析
10.5.3板级调试
10.6基于数码管显示的RTC读取实例
10.6.1RTC芯片解析
10.6.2功能简介
10.6.3代码解析
10.6.4板级调试
10.7基于UART发送的RTC读取实例
10.7.1功能简介
10.7.2代码解析
10.7.3板级调试
10.8基于UART收发的RTC读写实例
10.8.1功能简介
10.8.2代码解析
10.8.3板级调试
10.9基于UART控制的VGA多模式显示实例
10.9.1功能简介
10.9.2代码解析
10.9.3板级调试
10.10基于LED显示的D/A输出驱动实例
10.10.1D/A芯片概述
10.10.2功能简介
10.10.3代码解析
10.10.4板级调试
10.11基于按键调整和数码管显示的D/A输出实例
10.11.1功能简介
10.11.2代码解析
10.11.3板级调试
10.12波形发生器实例
10.12.1功能简介
10.12.2代码解析
10.12.3IP核CORDIC配置与例化
10.12.4板级调试
10.13基于数码管显示的A/D采集实例
10.13.1A/D芯片接口概述
10.13.2功能简介
10.13.3代码解析
10.13.4板级调试
10.14A/D和D/A联合测试实例
10.14.1功能简介
10.14.2代码解析
10.14.3板级调试
10.15RTC时间的LCD显示和UART设置实例
10.15.1功能简介
10.15.2代码解析
10.15.3板级调试
参考文献
第5章Verilog语法概述
本章导读本章介绍学习Verilog语言的一些经验和Verilog语言可综合的基本语法,以及常见逻辑功能的代码风格与书写规范。5.1语法学习的经验之谈FPGA器件的设计输入有多种方式,如绘制原理图、编写代码或是调用IP核。早期的工程师对原理图的设计方式情有独钟,这种输入方式应付简单的逻辑电路还凑合,应该算得上简单实用,但随着逻辑规模的不断攀升,这种落后的设计方式已显得力不从心。取而代之的是代码输入的方式,今天的绝大多数设计都是采用代码来完成的。FPGA开发所使用的代码,通常称为硬件描述语言(Hardware Description Language),目前最主流的是VHDL和Verilog。VHDL发展较早,语法严谨; Verilog类似C语言,语法风格比较自由。IP核调用通常也是基于代码设计输入的基础之上,现在很多EDA工具的供应商都在打FPGA的如意算盘,FPGA的设计也在朝着软件化、平台化的方向发展。也许在不久的将来,越来越多的工程只需要设计者从一个类似苹果商店的IP核库中索取组件进行配置,像搭积木一样完成一个项目,或者整个设计都不需要见到一句代码。当然,未来什么情况都有可能发生,但是底层的代码逻辑编写方式无论如何还是有其生存空间的,毕竟一个个IP核组件都是从代码开始的,所以对于初入这个行业的新手而言,掌握基本代码设计的技能是必需的。
这里不过多谈论VHDL和Verilog语言孰优孰劣,总之这两种语言是当前业内绝大多数开发设计者所使用的语言,从二者对电路的描述和实现上看,有许多相通之处。无论是VHDL还是Verilog,建议初学者先掌握其中一门,至于到底先下手哪一门,则需要读者根据自身的情况做考量。对于没有什么外部情况限制的朋友,若之前有一定的C语言基础,不妨先学Verilog,这有助于加快对语法本身的理解。在将其中一门语言学精、用熟之后,好也能够着手掌握另一门语言。虽然在单个项目中,很少需要“双语齐下”,但在实际工作中,还是很有可能需要去接触另一门语法所写的工程。网络上有很多很好的开源实例,若只会Verilog,而参考实例却是VHDL的,那么就很尴尬了; 忽然有24小时A同事离职,老板把他写了一半的Verilog工程扔给只会VHDL的你来维护,那可就被动难堪了……所以,对于VHDL和Verilog的取舍问题,建议先学精一门,也别忘了兼顾另一门,无论哪一种语言,至少需要具备看懂别人设计的基本能力。
HDL虽然和软件语言有许多相似之处,但由于其实现对象是硬件电路,所以它们之间的设计思维存在较大差异。尤其是那些做过软件编程的朋友,很喜欢用软件的顺序思维来驾驱HDL,岂不知HDL实现的硬件电路大都是并行处理的。也许就是这个大弯转不过来,所以很多朋友在研究HDL所实现的功能时常常百思不得其解。对于初学者,尤其是软件转行过来的初学者,笔者的建议是不要抛开实际电路而研究语法,在一段代码过后,多花些精力对比实际逻辑电路,必要时做一下仿真,好能再找一些直观的外设在实验板上看看结果。长此以往,若能达到代码和电路都心中有数,那才证明是真真正正掌握HDL的精髓了。HDL的语法条目虽多,但并非所有的HDL语法都能够实现最终的硬件电路。由此进行划分,可实现为硬件电路的语法常称为可综合的语法; 而不能够实现到硬件电路中,却常常可作为仿真验证的高层次语法则称为行为级语法。很多朋友在初学语法时,抱着一本语法书晕头转向地看,实战的时候却常常碰到这种语法不能用、那种语法不支持的报错信息,从而更加抱怨HDL不是好东西,学起来真困难。其实不然,可综合的语法是一个很小的子集,对于初学者,建议先重点掌握好这个子集,实际设计中或许靠着十来条基本语法就可以打天下了。怎么样?HDL一下变简单了吧。这么说一点也不夸张,本书的重点就是要通过各种可实现到板级的例程让读者快速地掌握如何使用可综合的语法子集完成一个设计。5.2节中会将常用的可综合语法子集逐一罗列并简单介绍。对于已入门的读者,也不是说掌握了可综合的语法子集就“万事大吉”了。
行为级语法也非一无是处,都说“存在即是合理”,行为级语法也大有用处。一个稍微复杂的设计,若是在板级调试前不经过几次三番的仿真测试,一次性成功的概率几乎为零。而仿真验证也有自己的一套高效便捷的语法,如果再像底层硬件电路一样搭仿真平台,恐怕就太浪费时间了。行为级语法最终的实现对象不是FPGA器件,而是手中的计算机,动辄上G甚至双核、四核的CPU可不愿做“老牛拉破车”的活,所以行为级语法帮助设计者在仿真过程中利用好手中的资源,能够快速、高效地完成设计的初期验证平台搭建。因此,掌握行为级语法,可以服务于设计的仿真验证阶段的工作。
对于HDL的学习,笔者根据自身的经验,提几点建议。首先,手中需要准备一本比较完整的语法书籍。这类书市场上已经是满天飞了,内容相差无几,初学者好能在开始FPGA的学习前花一些时间认真地看过一遍语法,尽可能地理解每条语法的基本功能和用法。当然,只需要认真看过、理解过,做到相关语法心中有数就行,这也不是为了应付考试,也没必要去“死记硬背”任何东西。语法的理论学习是必需的,能够为后面的实践打下坚实的基础。有些实在不好理解的语法,也不要强求,今后在实例中遇到类似语法的参考用法时再掌握也不迟。其次,参考一些简单的例程,并且自己动手写代码实现相同或相近的电路功能。这个过程中,可能需要结合实际的FPGA开发工具和入门级学习套件。FPGA的开发工具前面章节已经有所介绍,主要是掌握Quartus Ⅱ(Altera公司的器件使用)或ISE(Xilinx公司的器件使用)的使用,学会使用这些工具新建一个工程、编写代码、分配引脚、进行编译、下载配置文件到目标电路板中。入门级的学习套件,简单地说,就是一块板载FPGA器件的电路板。这块电路板不需要有很多高级的外设,一些简单的常见外设即可(如蜂鸣器、流水灯、数码管、UART、IIC等)。通过开发工具可以进行工程的建立和管理; 而通过学习套件,就可以直观地验证工程是否实现了既定的功能。在实践的过程中,一定要注意自己的代码风格,当然,这在很大程度上取决于参考例程的代码风格。至于什么样的学习套件配套的参考例程是规范的,倒也没有定论,建议在选择口碑较好的学习套件的同时,推荐读者多去读读FPGA原厂Altera(qts_qii5v1.pdf)或Xilinx(xst.pdf)公司的官方文档,在它们的一些文档手册中有各种常见电路的实现代码风格和参考实例。在练习的过程中,也要学会使用开发工具生成的各种视图,尤其是RTL视图。RTL视图是用户输入代码进行综合后的逻辑功能视图。这个视图很好地将用户的代码用逻辑门的方式诠释出来,初学者可以通过查看RTL视图的方式来看看自己编写的代码所能实现的逻辑电路,以加深对语法的理解; 反之,也可以通过RTL视图来检验当前所写的代码是否实现了期望的功能。