
本书是针对FPGA初学者编著的入门级图书,以高云公司的FPGA和Verilog HDL为开发平台,详细阐述FPGA设计所需的基础知识、基本语法、设计流程、设计技巧,全面、细致、深刻地剖析了Verilog HDL与C语言等传统顺序语言的本质区别,使读者通过简单的实例逐步理解FPGA的硬件设计思想,实现快速掌握FPGA设计方法的目的。本书思路清晰、语言流畅、分析透彻,在简明阐述设计方法的基础上,重点辨析读者易于与常规顺序语言混淆的概念,力求使读者在较短的时间内理解硬件编程思想,掌握FPGA设计方法。
前言 为什么要写这本书 时光如水,流逝悄无声息,从初次接触FPGA开始,不知不觉已二十余年。十余年前,我开始写FPGA方面的著作,第一本《FPGA/VHDL设计入门与进阶》本是希望为菜鸟写本入门书籍,现在翻看当时的文字,感觉自己当时也不过是有些自以为是的超级菜鸟而已。后来写通信技术FPGA设计方面的书籍,本意不过是将自己在设计过程中颇有心得的设计经验公之于众,为在通信技术FPGA设计领域的工程师提供有益的参考,所幸确实帮助到不少工程师和同学,与读者交流的邮件让我备感欣慰。 自2011年开始编写《数字滤波器的MATLAB与FPGA实现》(“数字通信技术的FPGA实现系列”图书的第一本)后,我先后完成《数字滤波器的MATLAB与FPGA实现》《数字通信同步技术的MATLAB与FPGA实现》《数字调制解调技术的MATLAB与FPGA实现》三本图书的编写。这三本图书(简称Xilinx/VHDL版)是基于AMD公司的FPGA器件和VHDL语言编写的,后来又基于Intel公司的FPGA和Verilog HDL语言改写了上面三本图书(简称Altera/Verilog版)。由于载波锁相环技术难度大且应用较为广泛,我又专门针对这个专题编写了《锁相环技术原理及FPGA实现》一书。由于“数字通信技术的FPGA实现系列”图书专业性较强,要同时理解一大堆繁杂的公式和FPGA设计知识,无疑是一件极具挑战的事。为此,我又先后出版关于数字信号处理技术更为基础的著作《Xilinx FPGA数字信号处理设计——基础版》《Intel FPGA数字信号处理设计——基础版》。 数字信号处理技术理论性强,FPGA技术入门难,要将两者有机结合完成FPGA数字信号处理设计,对工程师的要求很高。在收到的读者交流邮件中,有很大一部分读者其实在咨询FPGA设计的基础知识。九层之台,起于累土,学习不可操之过急。先打好基础,掌握FPGA的基本设计方法,熟悉FPGA设计流程,透彻理解FPGA设计所需的硬件思想,再加上数字信号处理的专业知识,才可以自由地完成数字信号处理的FPGA设计。 虽然市面上关于 FPGA 入门的书籍多如繁星,但具有原创性和鲜明特性的书籍还比较少。 何必又要写入门级别的书籍?无它,只是想将自己对FPGA设计的一些独特的理解和心得公之于众,为读者提供有益参考。既然是心得,那么书中的实例和书中对FPGA设计方法的理解都有很强的原创性,读者不用担心会看到过多与其他图书明显雷同的内容。 所谓集腋成裘,聚沙成塔。任何技能或技术都不是一蹴而就的,掌握它都需要读者长期的练习和思考,如江湖油翁,神箭穿杨。 如果有一本好书,能够讲解透彻、思路清晰、语言流畅,作者刚好又是讲授相关课程的老师,且是在行业混迹多年的工程师,相信会加快初学者成裘成塔的速度。 本书的内容安排 本书分为基础篇、初识篇、入门篇和提高篇,共16章。 基础篇包括必备的数字逻辑电路知识、可编程逻辑器件基础及开发环境的安装方法,主要对FPGA设计所需要了解的数字电路、模拟电路知识进行简单介绍,读者不用再翻阅《数字电路技术》《模拟电路技术》等书籍。 初识篇正式开启FPGA程序设计的学习之旅。首先详细介绍经典的“流水灯”实例,手把手讲解FPGA的全设计流程。接着从组合逻辑电路讲起,感受Verilog HDL“绘制”电路的设计思想。正如所有纷繁复杂的数字产品本质上都是由“0”和“1”组成的数字游戏,掌握FPGA的灵魂和精华,就打开了绚烂至极的FPGA设计技术之门。D触发器就是FPGA的灵魂,计数器就是FPGA的精华。几乎所有的FPGA语法结构都可以套用描述D触发器的语法结构,几乎所有的FPGA时序电路都可以分解为功能单一的计数器。D触发器虽然简单,计数器仅需三五行代码即可描述,但FPGA工程师的价值正是利用这些简单的基本部件,融合设计者的思想,形成满足用户需求的功能电路。理解硬件编程的思想,需要从透彻理解D触发器和计数器开始。在初识篇里,除了理解D触发器和计数器,还需要掌握Verilog HDL“并行语句”的概念,从而悟透Verilog HDL与C语言的本质区别。 入门篇包括对秒表电路、密码锁电路、电子琴电路、串口通信电路及状态机的讨论。这些电路模块看似功能简单,如何能够采用简洁、规范、高效的Verilog HDL语言完成电路的设计,需要设计者熟知FPGA的设计规则。从网络上找到类似功能电路的Verilog HDL代码很容易。由于这些电路一般不需要用到IP核,全是用Verilog HDL实现的,很容易实现代码移植,只需约束相应的引脚,了解电路顶层接口的信号功能,即可将编译后的代码下载到开发板上验证。能够在开发板上成功验证功能电路,实现正确的秒表、密码锁、电子琴、串口通信功能无疑会让人感到非常高兴。但对于FPGA初学者来讲,验证电路功能并不是最重要的,重要的是理解代码的设计思想。要在不参考任何代码的情况下,从头开始,在头脑中形成具体的电路模型,指间随心流淌Verilog HDL代码,最终完成正确的功能电路设计却需要艰苦卓绝的努力。唯有经过如此的练习,才能真正理解这些功能电路的设计方法。如果能够达到这样的状态,说明你已跨进FPGA设计的大门了。状态机一直是数字电路技术课程中的重要内容之一,虽然状态机也是一种比较常用的FPGA设计方式,但是作者仍然不推荐采用状态机的方式描述电路。第12章阐述了状态机的设计方法,并对状态机描述电路的利弊进行了分析。 提高篇包括时序约束、IP核设计、在线逻辑分析仪调试和常用的FPGA设计技巧等内容。当FPGA电路系统工作频率较高时,时序约束的重要性就凸显出来,设计出满足时序要求的Verilog HDL程序,首先要深刻理解FPGA程序运行速度的极限。IP核是经过验证的成熟设计模块,是一种提高设计效率的极佳设计方式,何况FPGA开发环境提供了很多免费的IP核。要解决FPGA工程师和硬件制版工程师之间的争端,弄清到底是FPGA程序的问题还是硬件电路板的问题,通常需要对FPGA程序进行在线调试。将FPGA程序下载到目标器件上观察电路的运行情况,在线逻辑分析仪提供了很好的调试手段。本书最后介绍了一些常用的FPGA设计技巧,如默认引脚状态设置、复位信号处理方法、时钟使能信号使用方法等,并以浮点乘法器为例讨论了FPGA电路的设计技巧,希望给读者更多有益的参考。 关于FPGA开发平台的说明 众所周知,目前AMD公司(2022年收购了Xilinx公司)和Intel公司(2015年收购了Altera公司)的FPGA产品占据全球90%以上的FPGA市场。可以说,在一定程度上正是由于两家公司的相互竞争,才有力地推动了FPGA技术的不断发展。 但是,近年来国际上的芯片产业呈现出异乎寻常的竞争发展态势,尤其国际上FPGA主要生产厂商的芯片在国内的售价持续上涨,且供货渠道不畅,很大程度上影响了本书对开发平台的选择。本书定位于FPGA初学者,在选用开发平台时主要考虑开发板的成本及开发软件的易用性。近年来,国产FPGA的发展势头十分迅猛,综合考虑后,本书选用了高云FPGA作为本书的开发平台。 虽然硬件描述语言(HDL)的编译及综合环境可以采用第三方公司开发的产品,如ModelSim、Synplify等,但FPGA的物理实现必须采用各自公司开发的软件平台,无法通用。例如,AMD公司的FPGA使用Vivado和ISE系列开发工具,Intel公司的FPGA使用Quartus系列开发工具,高云公司的FPGA使用云源软件。与FPGA的开发工具类似,HDL也存在两种难以取舍的选择:VHDL和Verilog HDL。 学习FPGA开发技术的难点之一在于开发工具的使用,AMD公司、Intel公司,以及各家国产FPGA公司,为了适应不断更新的开发需求,主要是适应不断推出的新型FPGA器件,开发工具的版本更新速度很快。开发工具的更新除了对开发环境本身进行完善,还需要不断加强对新上市的FPGA器件的支持。本书所有实例均采用云源软件进行编写。相对于Quartus、ISE、Vivado而言,云源软件的功能和界面都更为简洁,更适于初学者学习。 应当如何选择HDL呢?其实,对于有志于从事FPGA开发的技术人员,选择哪种HDL并不重要,因为两种HDL具有很多相似之处,精通一种HDL后,再学习另一种HDL也不是一件困难的事。通常来讲,可以根据周围同事、朋友、同学或公司的使用情况来选择HDL,这样在学习过程中,可以很方便地找到能够给你指点迷津的专业人士,从而加快学习进度。 本书采用高云公司的FPGA作为开发平台,采用Gowin_v1.9.8.07作为开发工具,采用Verilog HDL作为设计语言,使用ModelSim进行仿真测试。由于Verilog HDL并不依赖于具体的FPGA器件,因此本书中的Verilog HDL程序可以很方便地移植到AMD或Intel公司的FPGA上。如果Verilog HDL程序中使用了IP核,由于不同公司的IP核不能通用,因此需要根据IP核的参数,在另外一个平台上重新生成IP核,或重新编写Verilog HDL程序。 有人曾经说过,技术只是一个工具,关键在于思想。将这句话套用过来,对于本书来讲,具体的开发平台和HDL只是实现技术的工具,关键在于设计的思路和方法。读者完全没有必要过于在意开发平台的差别,只要掌握了设计思路和方法,加上读者已经具备的FPGA开发经验,采用任何一种FPGA都可以很快地设计出满足用户需求的产品。 如何使用本书 本书是专为FPGA初学者编写的入门级图书。一般来讲,FPGA设计者同时需要熟悉Verilog HDL语法,熟悉FPGA开发环境(如 Quartus II、ISE、Vivado、云源软件),熟悉数字电路基础知识。由于FPGA需要综合应用这些知识,加之Verilog HDL与C语言(工科学生一般首先接触到C语言,先入为主地形成了顺序编程思维)又存在本质的区别,因此初学者总是感觉FPGA设计入门比较难。本书的基础篇对FPGA设计所需的基础知识进行了简要介绍,后面介绍FPGA设计时,采用实例设计的方法,将云源软件 和Verilog HDL语法融合在一起进行讨论,并在实例过程中,详细、深刻、反复、多角度地讨论一些较难理解的FPGA设计概念,读者要细心体会这些简单的实例,理解FPGA设计的本质是设计电路,理解FPGA并行语句的概念,理解硬件编程思想。 为便于读者学习,本书的绝大多数实例均可以在CGD100开发板上进行验证。由于本书的实例并不复杂,大多数实例没有用到IP核,因此读者可以很容易地将本书的实例移植到其他开发板上进行验证,只需修改FPGA工程的目标FPGA型号,修改顶层文件信号端口对应的引脚约束即可。 致谢 有人说,每个人都有他存在的使命,如果迷失了使命,就失去了存在的价值。不只是每个人,每件物品也都有其存在的使命。对于一本图书来讲,其存在的使命就是被阅读,并给读者带来收获。如果本书能对读者的工作和学习有所帮助,将给作者莫大的欣慰。 在本书的编写过程中,作者得到了高云半导体公司的大力支持和帮助,在此表示衷心的感谢。该书配套的FPGA教学开发板由武汉易思达科技有限公司和米恩工作室联合研制,在此一并表示感谢。作者查阅了大量的资料,在此对资料的作者及提供者表示衷心的感谢。 FPGA技术博大精深,本书远没有讨论完FPGA设计的全部内容,仅针对FPGA初学者需要掌握的知识展开了详细的讨论。学习的过程充满艰辛、彷徨、痛苦和快乐,深入理解基本概念,透彻理解硬件设计思想,不急不躁,一定可以体会到FPGA设计的美妙。 由于作者水平有限,书中难免会存在不足和疏漏之处,敬请广大读者批评指正。欢迎读者就相关技术问题与作者进行交流,或对本书提出改进意见及建议。本书的配套资源包含完整的Verilog HDL实例工程代码。读者可以关注作者的公众号“杜勇FPGA”免费下载程序资料及开发环境,关注B站UP主“杜勇FPGA”免费观看配套教学视频。如果需要本书配套的CGD100开发板,请到官方网店购买:https://shop574143230.taobao.com/。 杜 勇 2022年11月
目录 第一篇 基础篇 第1章 必备的数字逻辑电路知识 3 1.1 数字逻辑和逻辑电平 3 1.1.1 模拟器件构成的数字电路 3 1.1.2 TTL反相器电路 4 1.1.3 现实中的数字信号波形 5 1.1.4 了解常用的逻辑电平 6 1.2 布尔代数 7 1.2.1 布尔和几个基本运算规则 7 1.2.2 常用的布尔代数法则 8 1.3 组合逻辑电路基础 9 1.3.1 组合逻辑电路的表示方法 9 1.3.2 为什么会产生竞争冒险 10 1.4 时序逻辑电路基础 11 1.4.1 时序逻辑电路的结构 11 1.4.2 D触发器的工作波形 12 1.4.3 计数器与寄存器电路 13 1.5 小结 16 第2章 可编程逻辑器件基础 17 2.1 可编程逻辑器件的历史 17 2.1.1 PROM是可编程逻辑器件 17 2.1.2 从PROM到GAL 19 2.1.3 从SPLD到CPLD 21 2.1.4 FPGA的时代 22 2.2 FPGA的发展趋势 24 2.3 FPGA的结构 26 2.4 FPGA与其他处理平台的比较 28 2.4.1 ASIC、DSP、ARM的特点 29 2.4.2 FPGA的特点及优势 30 2.4.3 FPGA与CPLD的区别 31 2.5 工程中如何选择FPGA器件 31 2.6 小结 32 第3章 准备好开发环境 33 3.1 安装FPGA开发环境 33 3.1.1 安装高云云源软件 33 3.1.2 安装ModelSim软件 35 3.2 开发平台CGD100简介 38 3.3 Verilog HDL基本语法 39 3.3.1 Verilog HDL的程序结构 39 3.3.2 数据类型及基本运算符 42 3.3.3 运算符优先级及关键词 44 3.3.4 赋值语句与块语句 44 3.3.5 条件语句和分支语句 47 3.4 小结 48 第二篇 初识篇 第4章 FPGA设计流程—LED流水灯电路 51 4.1 FPGA设计流程 51 4.2 流水灯设计实例要求 54 4.3 读懂电路原理图 55 4.4 流水灯的设计输入 57 4.4.1 建立FPGA工程 57 4.4.2 Verilog HDL程序输入 59 4.5 程序文件下载 62 4.6 小结 64 第5章 从组合逻辑电路学起 65 5.1 从最简单的与非门电路开始 65 5.1.1 调用门级结构描述与非门 65 5.1.2 二合一的命名原则 66 5.1.3 用门级电路搭建一个投票电路 67 5.2 设计复杂一点的投票电路 68 5.2.1 门电路设计方法的短板 68 5.2.2 利用assign语句完成门电路功能 69 5.2.3 常用的if…else语句 71 5.2.4 reg与wire的用法区别 73 5.2.5 记住“<=”与“=”赋值的规则 74 5.2.6 非常重要的概念—信号位宽 75 5.2.7 行为级建模的5人投票电路 75 5.3 ModelSim仿真电路功能 76 5.3.1 4线-2线编码器设计 77 5.3.2 建立ModelSim工程 78 5.3.3 设计测试激励文件 79 5.3.4 查看ModelSim仿真波形 82 5.4 典型组合逻辑电路Verilog HDL设计 84 5.4.1 8421BCD编码器电路 85 5.4.2 8线-3线优先编码器电路 86 5.4.3 74LS138译码器电路 88 5.4.4 与if…else语句齐名的case语句 90 5.4.5 数据分配器与数据选择器电路 91 5.5 数码管静态显示电路设计 93 5.5.1 数码管的基本工作原理 93 5.5.2 实例需求及电路原理分析 94 5.5.3 数码管显示电路Verilog HDL设计 95 5.5.4 板载测试 97 5.6 小结 98 第6章 时序逻辑电路的灵魂—D触发器 101 6.1 深入理解D触发器 101 6.1.1 D触发器产生一个时钟周期的延时 101 6.1.2 D触发器能工作的最高时钟频率分析 102 6.2 D触发器的描述方法 104 6.2.1 单个D触发器的Verilog HDL设计 104 6.2.2 异步复位的D触发器 106 6.2.3 同步复位的D触发器 108 6.2.4 时钟使能的D触发器 109 6.2.5 D触发器的ModelSim仿真 111 6.2.6 其他形式的D触发器 112 6.3 初试牛刀—边沿检测电路设计 113 6.3.1 边沿检测电路的功能描述 113 6.3.2 边沿检测电路的Verilog HDL设计 114 6.3.3 改进的边沿检测电路 115 6.4 连续序列检测电路—边沿检测电路的升级 116 6.4.1 连续序列检测电路设计 116 6.4.2 分析Verilog HDL并行语句 118 6.4.3 再论“<=”与“=”赋值 119 6.4.4 序列检测电路的ModelSim仿真 121 6.5 任意序列检测器—感受D触发器的强大 124 6.5.1 完成饮料质量检测电路功能设计 124 6.5.2 优化检测电路的设计代码 128 6.6 小结 129 第7章 时序逻辑电路的精华—计数器 131 7.1 简单的十六进制计数器 131 7.1.1 计数器设计 131 7.1.2 计数器就是加法器和触发器 133 7.2 十进制计数器 134 7.2.1 具有复位及时钟使能功能的计数器 134 7.2.2 讨论计数器的进制 135 7.2.3 计数器代码的花式写法 136 7.3 计数器是流水灯的核心 137 7.3.1 设计一个秒信号 137 7.3.2 流水灯电路的设计方案 139 7.3.3 闪烁频率可控制的流水灯 140 7.3.4 采用移位运算设计流水灯电路 142 7.4 Verilog的本质是并行语言 142 7.4.1 典型的Verilog错误用法—同一信号重复赋值 142 7.4.2 并行语言与顺序语言 144 7.4.3 采用并行思维分析信号重复赋值问题 145 7.5 呼吸灯电路设计 146 7.5.1 呼吸灯的工作原理 146 7.5.2 设计思路分析 147 7.5.3 亮度实现模块Verilog HDL设计 147 7.5.4 亮度控制模块Verilog HDL设计 148 7.5.5 顶层模块Verilog HDL设计 150 7.6 小结 151 第三篇 入门篇 第8章 设计简洁美观的秒表电路 155 8.1 设定一个目标—4位秒表电路 155 8.1.1 明确功能需求 155 8.1.2 形成设计方案 156 8.2 顶层文件的Verilog HDL设计 157 8.3 设计一个完善的数码管显示模块 158 8.4 秒表计数模块的Verilog HDL设计 160 8.4.1 秒表计数电路设计 160 8.4.2 秒表计数电路的ModelSim仿真 162 8.4.3 简洁美观的秒表计数器设计 163 8.4.4 实现秒表的启停功能 166 8.5 按键消抖模块的Verilog HDL设计 166 8.5.1 按键消抖产生的原理 166 8.5.2 按键消抖模块Verilog HDL设计 167 8.5.3 将按键消抖模块集成到秒表电路中 169 8.6 小结 169 第9章 数字密码锁电路设计 171 9.1 数字密码锁的功能描述 171 9.2 规划好数字密码锁的功能模块 172 9.2.1 数字密码锁总体结构框图 172 9.2.2 数字密码锁的顶层模块设计 172 9.3 数字密码锁功能子模块设计 174 9.3.1 按键消抖模块Verilog HDL设计 174 9.3.2 计数模块Verilog HDL设计 175 9.3.3 密码设置模块才是核心模块 176 9.4 小结 178 第10章 简易电子琴电路设计 179 10.1 音符产生原理 179 10.2 琴键功能电路设计 180 10.2.1 顶层模块设计 180 10.2.2 琴键模块设计 182 10.2.3 音符产生模块设计 183 10.3 自动演奏乐曲《梁祝》 185 10.3.1 自动演奏乐曲的原理 185 10.3.2 自动演奏乐曲《梁祝》片段 186 10.4 完整的电子琴电路设计 189 10.5 小结 190 第11章 应用广泛的串口通信电路 191 11.1 RS-232串口通信的概念 191 11.2 串口硬件电路原理分析 192 11.3 串口通信电路Verilog HDL设计 193 11.3.1 顶层文件的Verilog HDL设计 193 11.3.2 时钟模块的Verilog HDL设计 195 11.3.3 接收模块的Verilog HDL设计 196 11.3.4 发送模块的Verilog HDL设计 198 11.3.5 FPGA实现及板载测试 199 11.4 采用串口控制秒表电路 201 11.4.1 设计需求分析 201 11.4.2 顶层文件的Verilog HDL设计 202 11.4.3 秒表时间获取模块Verilog HDL设计 204 11.4.4 完善秒表电路顶层模块Verilog HDL代码 205 11.4.5 完善秒表计数模块Verilog HDL代码 207 11.4.6 FPGA实现及板载测试 210 11.5 小结 210 第12章 对状态机的讨论 211 12.1 有限状态机的概念 211 12.2 状态机的Verilog设计方法 212 12.2.1 一段式状态机Verilog代码 212 12.2.2 二段式状态机Verilog代码 213 12.2.3 三段式状态机Verilog HDL代码 215 12.3 计数器电路的状态机描述方法 216 12.4 序列检测器的状态机描述方法 218 12.5 小结 221 第四篇 提高篇 第13章 基本的时序约束方法 225 13.1 电路的速度极限 225 13.2 时序约束方法 227 13.2.1 查看计数器的逻辑电路结构 227 13.2.2 计数器电路添加时钟周期约束 229 13.3 速度与面积的取舍 231 13.3.1 多路加法器电路的结构分析 231 13.3.2 流水线操作的本质—讨论多路加法器的运行速度 233 13.3.3 用一个加法器完成4路加法 235 13.3.4 串行加法器时序分析 238 13.4 小结 238 第14章 采用IP核设计 241 14.1 FPGA设计中的“拿来主义”—使用IP核 241 14.1.1 IP核的一般概念 241 14.1.2 FPGA设计中的IP核类型 242 14.2 时钟IP核 244 14.2.1 全局时钟资源 244 14.2.2 采用时钟IP核生成多路时钟信号 244 14.3 乘法器IP核 248 14.3.1 乘法器IP核参数的设置 248 14.3.2 乘法器IP核的功能仿真 250 14.4 存储器IP核 251 14.4.1 ROM核 251 14.4.2 RAM核 255 14.5 小结 260 第15章 采用在线逻辑分析仪调试程序 261 15.1 在线逻辑分析仪的优势 261 15.2 GAO的使用流程 262 15.3 采用GAO调试串口通信程序 263 15.3.1 调试目的 263 15.3.2 添加GAO到项目中 263 15.3.3 设置触发信号及触发条件 264 15.3.4 设置捕获信号参数 265 15.3.5 观察串口收发信号波形 267 15.4 小结 268 第16章 常用的FPGA设计技巧 269 16.1 默认引脚状态设置 269 16.2 复位信号的处理方法 271 16.3 合理利用时钟使能信号设计 272 16.4 利用移位相加实现乘法运算 273 16.5 根据芯片结构制定设计方案 274 16.6 浮点乘法器设计 275 16.6.1 单精度浮点数据格式 275 16.6.2 单精度浮点数乘法运算分析 276 16.6.3 自定义浮点数据格式 276 16.6.4 自定义浮点数据乘法算法设计 277 16.6.5 算法Verilog HDL实现 278 16.7 小结 284 参考文献 287