时间:2025-06-20 来源:网络收集 关于我们 0
易于维护,方便移植、升级或扩展
满足实时处理的要求
可将各种端接匹配元件整合到器件内部,
降低NRE成本,加速产品上市时间
有效降低BOM成本
支持丰富的外设接口,可根据需求配置
单片解决方案,可以替代很多数字芯片
减少板级走线,有效降低布局布线难度
FPGA技术的局限性
绝对性能受限:在某些性能上,FPGA可能比不上专用芯片;或者至少在稳定性方面,FPGA可能要逊色一些。灵活性是否适用:如果设计不需要太多的灵活性,FPGA的灵活性反而是一种浪费,会潜在的增加产品的成本。功耗相对较高:相比特定功能、应用集中的ASIC,使用FPGA实现相同功能可能产生更高的功耗(相比GPU,则单位性能功耗要低很多)。设计复杂性高:在FPGA中除了实现ASIC所具有的复杂功能,还得添加一些额外的功能,实属一大挑战。FPGA的设计复杂性和难度可能会给产品的开发带来一场噩梦。
所以,基于上述FPGA的优缺点,在开发目标产品时,是否需要使用FPGA就需要考虑以下几点:
1.1.6 FPGA的应用
FPGA的应用领域非常广泛,下面举几个例子。
- 逻辑粘合
如一些嵌入式处理常常需要地址或外设扩展,CPLD器件尤其适合。在FPGA被发明的早期,使用FPGA做的很大一部分工作就是逻辑粘合。今天已经少有项目会选择一颗FPGA器件专门用于逻辑粘合的应用,但是在使用FPGA做一些大规模处理的同时,顺便做些逻辑粘合的工作倒是非常普遍。
图1-3 逻辑粘合示意图
如上图中,左侧是一颗DSP,由于EMIF接口数量不够,可能需要拓展,就使用FPGA接了三个双口RAM。
- 实时控制
如液晶屏或电机等设备的驱动控制,此类应用都具有很强的实时性但相对简单,所以主要使用CPLD或低端FPGA。
- 高速信号采集和处理
如高速AD前端或图像前端的采集和预处理,近年来持续升温的机器视觉应用也几乎是无一例外的都使用了FPGA器件。
图1-4 高速采集处理应用示意图
如今很多机器视觉的应用也采用了类似的方式,只不过前端的AD会被替换成Math 。
- 协议实现
如更新较快的各种有线和无线通信标准、广播视频及其编解码算法、各种加密算法等,诸如此类小批量、定制化、更新换代频繁的应用使用,FPGA比ASIC更有竞争力。如下图所示的“SD/HD/3G SDI的协议”或者无线通信基站之间的协议实现。
图1-5 SD/HD/3G SDI的协议实现
- 各种原型系统验证
FPGA支持丰富的接口协议标准,可定制性强,芯片原厂使用FPGA搭建芯片的验证系统。
- 并行计算(算法实现)
传统的CPU计算受限于其串行顺序处理的架构,已经很难适应今天的云计算和数据中心对大数据运算的需求。而FPGA与生俱来的并行性与灵活可编程特性是其进入高速运算领域的一大优势。GPU虽然一直是并行处理的主流方案,但也受限于极高的成本和功耗代价。相比之下,单位功耗性能是GPU的3~4倍的FPGA则大有取而代之的趋势。
- 片上系统SoC
目前在一些单芯片SoC产品,既有成熟的ARM硬核处理器,又有丰富的FPGA资源(IO资源、RAM资源、乘法器资源等)。这种SoC集成度高,布板面积可以做到最小化,并且内部灵活和高吞吐量的高速互联。如Intel-公司的Soc FPGA和AMD-公司的ZYNQ。
- 从行业看FPGA的应用
最后总结一下,FPGA在通信领域、数字信号处理领域、视频图像处理领域、高速接口设计领域、人工智能领域、IC验证领域以及各种定制设计中都有涉猎。
FPGA所诞生并发展的时代是一个好时代,与生俱来的一些特性也注定了它将会在这个时代的大舞台上大放光彩。
1.1.7 FPGA的学习之路
FPGA设计是一种整合的技术,要求从不同的设计领域融合多种设计技能。要想成为一名资深的FPGA开发工程师,开发一些复杂的FPGA应用,极可能涉及到多种交叉的设计技能,需要掌握交叉学科知识、拥有丰富的技能,可能还需要来自系统、软件和硬件工程的设计技能。
图1-6 FPGA开发可能会使用的知识领域
表1-3 FPGA开发可能需要掌握的技能
领域硬件/DSP设计软件(HDL)设计软件/DSP设计系统设计
所
需
技
能
板级硬件与接口设计
HDL语言的设计输入
处理器代码模块的定义
处理器需求分析
DSP算法的硬件实现
脚本实现自动化处理
代码的编写和测试
设计数据流的定义
逻辑电路设计
设计测试平台的开发
DSP算法的软件实现
处理器架构的选择
功耗与去耦设计
HDL流程设计的配置管理
常规的代码调试和验证
硬件/软件实现的权衡
硬件仿真
设计约束
在处理器上运行操作系统
系统级设计的层次结构定义
板级引脚分配
支持设计复用
代码的配置管理
功能划分和模块化设计
硬件模块调试
系统模块的集成与接口测试
I/O特性的定义
系统级测试,调试和验证
设计布局
设计优化权衡
信号完整性和终端匹配
FPGA器件和封装选择
当然,上述技能虽多,但不用害怕,没有人天生就懂软件/硬件开发,所有大佬都是从“Hello World”/点灯开始的。下面就是特权同学总结的FPGA三阶段:
1. 入门阶段
从无到有的阶段,初识FPGA,是不折不扣的“菜鸟”。
要初步了解FPGA是什么、能做什么等基本的理论。
要学会HDL语言,能够使用EDA工具完成FPGA的代码设计、仿真验证、时序设计、综合和映射。
能够在开发板上下载并跑例程,进行初步的板级调试。
这一阶段的目标是"熟练"。
2. 精通阶段
提高自己的设计和调试能力。
掌握如何用合适的HDL语法风格设计出最优化的电路;让EDA工具的不同设置功能服务于具体的设计优化。
掌握不同的板级调试手段并能熟练应用。
这一阶段的目标是“精通"。
3. 从业阶段
以FPGA产品开发作为自己的职业。
让FPGA技术以最优的方式服务于产品。
有挑战也有成就,最长、最难的阶段。
这一阶段的目标是“专业”。
1.2 FPGA开发流程 1.2.1 一般性的FPGA开发流程
图1-7 一般性FPGA开发流程
设计输入:创建FPGA工程,添加设计源文件,比如HDL文件、EDIF或NGC网表文件、原理图、IP核模块、嵌入式处> 理器以及数字信号处理器模块等。设计综合: FPGA开发工具的综合引擎将编译整个设计,并将HDL源文件转译为特定结构的设计网表约束输入:指定时序、布局布线或者其它的设计要求。如时序约束、I/O弓|脚约束和布局布线约束等设计仿真:使用仿真I具对FPGA工程进行功能或时序验证。设计实现:将逻辑设计进一步转译为可以被下载烧录到目标FPGA器件中的特定物理文件格式。分析实现结果:对设计约束、器件资源占用率、实现结果以及功耗等设计性能进行分析设计优化:分析当前设计结果,对设计源文件、编译属性或设计约束进行修改,然后重新综合、实现以达到设计最优化。FPGA的设计有很多迭代的过程。板级调试:生成比特流并下载到开发板上,对FPGA器件进行板级的调试。FPGA有非常丰富的板级调试手段,比如在线逻辑分析仪可以直接查看FPGA内部引脚、接口、走线的信号变化,可以有效提升板级调试效率。
图1-8 简化的FPGA开发流程
概念阶段:或称架构阶段,完成项目前期的立项准备,如需求的定义和分析、各个设计模块的划分。设计实现阶段:或称详细设计阶段,包括编写RTL代码、并对其进行初步的功能验证、逻辑综合和布局布线、时序验证。FPGA器件实现阶段:除了器件烧录和板级调试外,也应该包括设计实现阶段的布局布线和时序验证,因为这两个步骤也都是和FPGA器件紧密相关的。 1.2.2 利用开发FPGA
就是用来进行FPGA开发的一个工具,可以编译硬件代码,完成上面所说的整个FPGA开发流程。市面上主流的FPGA开发工具只有两款,一个是芯片(被AMD收购)专用的 ,另一款则是芯片(被Intel收购)专用的 ,两者原理相同,但建议先熟练掌握一个工具而不是混着学。本教程选用正点原子达芬奇PRO开发板,搭载了的芯片,所以本教程都是用进行开发。
另外,集成了 HLS( High Level ) 工具,可以实现直接使用C、C++以及 C语言对的FPGA器件进行编程。用户无需手动创建RTL,通过高层次综合生成HDL级的IP核,从而加速IP创建。在某些使用语言描述异常复杂的场景中(如卷积神经网络),使用HLS将高级语言转化为对应的HDL级的IP核,就会非常方便。这种功能会在ZYNQ系列芯片的学习过程中进行介绍,本教程不涉及。
下面是左侧的导航窗格,上一节所述的FPGA开发流程都在这里完成:
图1-9 左侧导航窗格
图1-10 基于的FPGA开发流程
创建源文件:用户有两种方式可以创建源文件,以描述电路结构与功能,分别是编写“HDL代码”、创建BD(框图,Block )。RTL分析:将上述源文件转换为逻辑门电路。 综合:将经过“RTL分析”后的门电路映射为FPGA器件内部的物理结构。所以“综合”电路中看不到任何的“门”。“综合”的结果是所使用的特定FPGA器件中实际存在着的物理结构,如“输入缓冲”、“查找表”、“触发器”和“输出缓冲”等。 布局布线:需要用户指定时序、布局布线或者其它的设计要求,如时序约束、I/O引脚约束和布局布线约束等。会自动根据这些约束,将“综合”给出HDL代码与实际FPGA器件进行映射,物理视图与具体的芯片一致。 生成比特流、下载到板材上。
注:使用进行后续操作时,会自动检查前面的步骤是否已经完成,比如直接“综合”会自动先进行“RTL分析”、直接“生成比特流”则会自动进行整个过程,若有那个环节有错,会自动停止并给出提示。
在整个开发过程中,为了验证电路的正确性,还会进行仿真。从上面的示意图可以看到一共有5种仿真类型。主要分为行为仿真/功能仿真( / )、时序仿真( )两大类:
功能仿真也称为行为仿真,主旨在于验证电路的功能是否符合设计要求,其特点是不考虑电路门延迟与线延迟,主要是验证电路与理想情况是否一致。时序仿真也称为布局布线后仿真,是指电路已经映射到特定的工艺环境以后,综合考虑电路的路径延迟与门延迟的影响,验证电路能否在一定时序条件下满足设计构想的过程,能较好地反映芯片的实际工作情况。但仿真耗时很长。
仿真是FPGA在板级调试前非常重要的验证手段。 仿真可以在RTL分析前进行,但是为了提高仿真的有效性,需要先进行RTL分析、综合。另外,布局布线后也可以进行更精确的仿真,但是一般不做。在对时序要求不高的场景中,可以认为时钟的轻微延迟对电路基本没有影响,所以为了提高开发效率,一般只进行行为仿真( )。后续还有bug会使用ILA或VIO看波形异常,实在是找不出来问题,才会进行布局布线后时序仿真。
下面给出一个简单的开发实例:假如现在我们要开发一个电路,有三个输入信号A/B/C,输出为 AB+C,下面给出其真值表:
创建源文件,编写以下代码描述上述真值表所给出的逻辑功能。
module design_1( clk,rst_p, cina,cinb,cinc, cout ); //定义输入输出接口 input clk, rst_p; //时钟及复位信号 input cina, cinb, cinc; //输入的三个数据信号 output reg cout; //输出数据信号 //实现功能 always@(posedge clk or posedge rst_p) if(rst_p) cout <= 1'b0; else cout <= (cina & cinb) | cinc; endmodule
进行RTL分析(Run ),点击“Open ” → “”,即可看到RTL门级电路:
图1-11 【例】RTL门级电路
进行综合(Run ),将上面的门电路映射为FPGA芯片上实际的硬件电路,点击“Open ” → “”查看:
图1-12 【例】实际的硬件电路
添加硬件约束(也就是引脚分配),通过查看PYNQ-Z2原理图可以发现系统时钟引脚为H16;四个按下为高电平的按键开关BTN3~BTN0的硬件端口依次为L19、L20、D20、D19;LED0端口为R14。设置BTN3为复位按键,BTN0~BTN2分别为cina/cinb/cinc,LED0为输出,于是分配硬件端口:
图1-13 【例】引脚约束
生成比特流,下载到开发板,就可以看到相应的实验现象了。 1.2.3 硬件调试与仿真(ILA核/VIO核)
那硬件开发的过程中,肯定也会出现各种各样的bug(实验现象与预期不符),在FPGA开发过程中,最主要的调试方式就是看各个主要信号的波形。本小小节就来介绍使用进行FPGA程序调试的思路。
1) 硬件异常检测
在进行程序调试前,首先要确定硬件本身没有问题。可以按照以下步骤进行:
下载一个验证好的例程,测试硬件是否能正常工作。假如例程无法运行,排查接口连接、管脚分配。比如按照从电源到各个模块的顺序,测量各个模块的电压是否正常。如果例程还是无法正常运行,交给硬件工程师/开发板卖家。
2) 行为仿真
确认硬件没有问题后,那么程序现象出问题就显然是软件程序的问题了。为了简单快捷,首先可以快速排查几个常见的错误:
检查 时钟、复位 是否接好。检查每一个模块的接口是否正确。比如涉及到通信的问题,检查主控制和从控制器Slave是否建立的联系(两者之间的valid、ready信号)。查看状态机的状态是否正常、查看数据是否有问题、查看触发条件是否有问题。(“状态机”后续会进行介绍)
注:任意查看“RTL分析”、“综合”、“布局布线”后的三种原理图,可以快速的查看电路连接状态。
小技巧:
若此时还是没有发现问题,就需要编写仿真文件,来产生设计好的激励以驱动可能有问题的模块,这些激励包括时钟、复位、控制信号,另外也可以设计一些具有规律性的假数据来进行测试。仿真文件编写完毕后,再点击“运行”,就可以看到目标信号的仿真波形了。
3) ILA核与VIO核
一般通过上述“行为仿真”就能找出相应的bug了。但有些实验涉及到与外部芯片进行通信,导致不是所有的信号都是由FPGA内部控制,比如I2C通信读写、DDR3读写实验等。比较幸运时,可以找到该芯片对应的仿真代码,比如就有对应的仿真代码,可以直接在行为仿真中完全模拟出芯片信号的变化。但有些芯片可能没有对应的仿真代码;或者说有对应的仿真代码但实在是过于复杂,进行一次有效的行为仿真需要几十分钟,那这个时候就需要硬件电路的帮忙。换句话说,我想直接在有问题的硬件电路上,直接抓取信号看波形。
要想实现上面这个目的,首先想到的是使用示波器,但是示波器只能看到物理存在的接口。那想查看芯片内部信号的波形该怎么办呢?就需要使用内置的IP核:ILA核( Logic )、VIO核( Input/)。下面依次介绍。
图1-14 ILA/VIO 示意图
的LIA/VIO通过将Probe与相应的IP核相连,来监控逻辑内部信号和端口信号,最终将数据通过下载器(JTAG接口)传输到PC。简单来说,就是将数据发送到PC端(软件)进行显示。此外,VIO还可以接收电脑数据,用来驱动内部逻辑信号或提供触发信号。
图1-15 添加ILA/VIO的方法
上图给出了添加ILA/VIO的方法:
HDL【常用】:生成ILA的IP核,然后在代码中进行例化。优点是方便,缺点是要修改代码。信号列表()或原理图():对代码综合之后才能添加。优点是不用修改原代码,缺点是综合可能会优化掉待测信号(添加属性可以解决)。IP (IP集成器):在IP 中添加信号,但是只有在添加硬核或软核才会用到。
注:添加成功后,下载比特流后会在软件窗口界面显示波形等设置。
总结:
ILA核:监控信号。可以将波形存储在ROM之中,但会消耗FPGA内部的逻辑资源和存储资源。VIO核:监控和驱动信号。只能显示实时波形,但还可以通过电脑端手动更改程序的某些触发信号。 1.3 FPGA芯片介绍
本小节来点轻松的,介绍一下FPGA的发展历史以及内部结构。内部结构可能看起来有点难,但是先有个印象就行。
1.3.1 FPGA的发展史
图1-16 FPGA发明人-Ross
图1-17 曾经的可编程逻辑器件
FPGA的发展史其实也就是近几十年的事情:
在FPGA刚发明的时,常以有多少“门”(与门、或门、非门等逻辑资源)来衡量一个FPGA。而现在“门”的概念已经逐渐被淡化,FPGA不仅强调其逻辑资源,还包括其他丰富的资源,如可编程IO单元、丰富的布线资源、灵活的时钟管理单元、嵌入式块RAM以及各种通用的内嵌功能单元(如内嵌乘法器、内嵌硬核IP等),很多器件还顺应市场需求内嵌专用的硬件模块。
注:FPGA从高到低分为好几个级别:系统级、算法级、寄存器级(RTL级、行为级)、门级(布局布线后,有延迟)、开关级。
图1-18 野心十足的ARM+FPGA架构
近些年来,可编程器件的龙头老大和更是相继推出了硬核CPU+FPGA的产品,此举大有单芯片横扫千军的架势。比如上图所示的蓝色PS部分就是CPU硬核(ARM架构),剩下的黄色部分就是FPGA,这样的产品包括的ZYNQ系列和的SoC FPGA。
1.3.2 FPGA厂商及型号
图1-19 国内外FPGA市场占有率
国际上,FPGA的主要生产厂商有:
注:正所谓集群效应,主流的FPGA供应商几乎都来自美国加利福尼亚。
那我这一顿库库介绍FPGA,其他的啥也没说。但是很多初学者(比如我)在刚学FPGA找资料的时候,总是会看到什么FPGA、ZYNQ、PYNQ啥的,被这些不同的芯片型号整的晕头转向,那现在就来捋一捋他们的关系:
图1-20 芯片型号的发展顺序
那官网上着重介绍了自家的 FPGA芯片 和 ZYNQ系列芯片,咱们就大概看看它的产品线(那边也差不多,就不多说了),如下图所示:
图1-21 的FPGA、SoC产品
从上图可以看到主要有FPGA芯片、SoC( on Chip, 片上系统)两大类。这两个大类各自包含四个子系列,每个子系列又细分为多种产品线,而每一个产品线都有很多型号(图中未给出具体型号)。可以大致认为,该产品树从上到下分别对应了片上资源从少到多。
目前市面上最常见的初学者开发板,就是FPGA系列中的Atrix-7系列(/)、以及Zynq-7000系列(7000/7020)。
1.3.3 FPGA硬件结构
本小小节介绍FPGA内部的硬件结构,对于初学者来说,里面的很多图一看就非常复杂,想搞懂很困难。但是不要放弃,本篇文章只是用做科普,一些看似很难的图只需要有一个大概的印象即可,后续做实验时,涉及到相应的模块则会继续讲解。另外在基础的开发实验中,只需要了解各模块的接口,能把接口接对即可,可以暂时不用对内部结构有特别深入的理解。
1.3.3.1 数字电路基本结构
下面给出了在设计数字电路的过程中,经常用到的一些基本结构。下面可能只给出一些基本的示意图,关于更详细的基本电路介绍可以在任意一门《数字电子技术基础》课程上讲到,可以在 B站/ 搜索相应关键词。
1) MOS管
所有门电路的功能都可以由PMOS管和NMOS管(统称“晶体管”) 来实现的。下面给出了其物理结构和基本的电路符号。当然,这里仅是简单的示意图,实际上还有结型场效应管、绝缘栅型场效应管(又细分为增强型和耗尽型),具体细节可以查看任意一本《模拟电子技术基础》课本(推荐清华大学出版社 童诗白主编)。
图1-22 NMOS和PMOS示意图
2) 基本逻辑门电路
图1-23 基本逻辑门电路
上图给出数字电路中最常见的基本逻辑门电路。上图所示的每一个门电路都是由最基本的 电阻、二极管、三极管 组成的。比如:
注:具体结构可以查看《数字电子技术基础》。
3) 触发器
通过将门电路进行组合,就可以得到更加复杂的“触发器”。触发器一般都需要时钟输入,作用一般是锁存数据,或者多个触发器和外围电路配合形成计数器。而多个计数器级联,就可以产生任意周期的脉冲信号。触发器的种类多种多样,比如RS触发器、D触发器、JK触发器、T触发器、T’触发器等,下图以D触发器为例。
图1-24 D触发器电路结构及逻辑符号
可以看到D触发器由基本的非门、与非门构成。比如 Rˉd\bar{R}_dRˉd、Sˉd\bar{S}_dSˉd 均设置为高电平时,输出Q就会在 时钟 高电平时同步更新为 输入DDD。
4) 组合逻辑和时序逻辑
那有了上面的门电路、触发器等数字电路的基本元器件,就可以搭建各种各样的数字电路了。但是注意数字电路根据是否需要时钟又分成 组合逻辑 和 时序逻辑。下面是其示意图:
图1-25 组合逻辑和时序逻辑示意图
组合逻辑的输出只与当前输入有关,时序逻辑的输出与当前输出和过去的状态都有关。组合逻辑立即反应当前输入状态,时序逻辑还必须在时钟边沿触发后输出新值。组合逻辑容易出现竞争、冒险现象,时序逻辑一般不会出现竞争、冒险现象。组合逻辑的时序较难保证,时序逻辑更容易达到时序收敛,时序逻辑更可控。组合逻辑只适合简单的电路,时序逻辑能够胜任大规模的逻辑电路。
简单一句话:组合逻辑立即变化,时序逻辑随着时钟变化。
那下面就来一步步介绍FPGA内部是如何实现上述这些数字电路的基本结构的。
1.3.3.2 LUT查找表
实际上,FPGA通过 LUT(Look-up table,查找表)结构 来实现可编程电路。LUT就是一张已经设计好的结果已知的查找表,这个表存储着不同的输入对应的所有可能的结果,这些结果对应LUT中一个唯一的地址。而组成LUT的RAM本质上也由晶体管组成,所以 LUT本质上也是晶体管的组合。
【例】2输入LUT实现的与非门电路,可以用4个预存储的数据实现既定功能。输入x和y的4种不同组合可以看出是0~3的4个不同地址,每个地址都对应一个输出结果。
图1-26 2输入LUT实现与非门
当然实际的FPGA当中,使用的并不是这么简单的2输入查找表。具体到 系列FPGA器件,它使用的是 6输入LUT结构。这6个独立的输入(称为A1~A6)可以配置为单输出(O6)模式和双输出(O5和O6)模式。
图1-27 LUT实现多输入可编程电路
实际上,通过配置,上图不仅可以实现“多输入与门”电路结构,同样可以实现“多输入或门”,以至于任意多输入的组合,都可以实现。
1.3.3.3 可配置逻辑块CLB
图1-28 可配置逻辑块CLB
以主流的7系列为例,一颗FPGA内部通常都会有数千到数十万不等的 可配置逻辑块( Logic Block,简称CLB)。呈矩阵排布的CLB就构成了最基本的FPGA逻辑资源的架构,CLB块之间有很丰富的布线池。系列的可配置逻辑块可以有效的支持以下特性:
从微观角度看,CLB内部主要由2个更小的单位Slice所组成。两个Slice之间有连线,且每个Slice都有独立的高速进位链以及独立的布线通道连接到矩阵开关,通过矩阵开关可以实现Slice与FPGA大布线池之间的灵活编程。每个slice单元则包含了以下更小的功能块:
围绕在CLB周围丰富的行、列走线称为 布线池,它用于衔接FPGA的各个CLB以及其它相关的资源。在FPGA芯片四周的小矩形以及延伸出去的短线,则表示FPGA和外部芯片接口的 IO块。
1.3.3.4 其他丰富的FPGA资源
图1-29 主流的FPGA架构
从整个FPGA的配置来看,不仅包含了很多CLB资源,还包括以下丰富的资源:
以成块出现的FPGA内嵌存储器(块RAM)。用于产生不同时钟频率的锁相环( PLL时钟发生器)以及相应的时钟布线资源。高速串行收发器。外部存储器控制器(硬核IP)。用于实现数字信号处理的乘累加模块(DSP Slice)。模拟数字转换模块( FPGA器件特有的ADC,简称XADC):支持最多16个可复用通道,对于一些工业应用领域(如电压监控、小信号采集)来说,非常实用。
1) 块RAM
图1-30 BRAM接口框图
块RAM就是以成块出现的FPGA内嵌存储器。因为在一些高速的数据处理、缓存、算法实现、信号处理等场合,需要内部的一个紧耦合的RAM来实现对数据的高速的缓存和读写,所以块RAM应运而生。从上图所示的FPGA内部的块RAM接口框图来看,块RAM本质上都是36kb大小的双输入双输出:左侧有DIA和DIB两个独立的数据输入,右侧也分别是DOA和DOB两个独立的输出,上下则是用于级联的接口。但当然也可以根据需求,配置成简单的单输入单输出,这个后续在学习“RAM IP核”时再具体介绍。
实际上,FPGA内嵌的存储器单元包括块RAM(BRAM) 和 分布式RAM。BRAM 就是上一段介绍的结构,分布式RAM 则是基于CLB的查找表。这些存储器单元都可以配置为随机存取存储器(RAM)、只读存储器(ROM)、FIFO或移位寄存器,非常灵活。
2) 时钟资源(PLL时钟发生器)
1) 块RAM
图1-31 FPGA时钟资源类比
FPGA内部充斥着各种各样的连线,如果我们把这些逻辑间的互连线比喻为大城市里面密密麻麻的街道和马路,那么专为快速布线而定制的 时钟布线资源 则是城市里的快速路。FPGA内部的 时钟布线池 也是横平竖直的矩阵式排布,意图让每一条“小路”能够尽快地找到可以就近“上高速”的“匝道”。换回到FPGA内部电路来说,就是希望时钟源产生的时钟信号,可以通过尽可能小的延迟,快速地、同步地 达到各个资源,以驱动电路各模块正常协调工作。注意时钟信号的最大延迟,限制了FPGA的时钟频率。
FPGA内部会将时钟布线资源划分到不同的“时钟区”中,每个时钟区对应一定数量的IO口数量、逻辑资源、存储器资源或DSP slice资源,同时也会有一个CMT(Clock tiles)相对应。于是,由 PLL时钟发生器 产生的不同时钟频率的锁相环以及相应的时钟布线资源,就可以被输送到不同的“时钟区”。
3) 数字信号处理块
图1-32 DSP示意图
数字信号处理( ,简称DSP)块是 FPGA内部最复杂的运算单元。DSP块是内嵌到FPGA中的算术逻辑单元(ALU),它由3个不同的链路块组成:DSP块的算术链路由一个加减器连接到乘法器,再连接到一个乘累加器所组成。DSP用于实现数字信号处理的乘累加模块(DSP Slice)。可用于一些算法实现和运算功能。
当然在一些简单的应用中,无需对DSP内部的结构做如此深入的理解,只要会用即可。
4) 高速串行收发器
图1-33 GTP 资源
FPGA支持各种高速差分对,从几百MHz的普通LVDS接口到上GHz或数十GHz的Gbit串行收发器,可以满足各种高速数据传输的需求。通常在FPGA器件内部提供高速的串化器和解串器,以及低时延、高速率的时钟处理单元。普通的LVDS接口,小规模的FPGA器件中也能够提供多达几十对的差分接口,通常既可以作为LVDS接口,也可以复用为一般的IO引脚使用。在系列FPGA器件中达到6.6Gb/s的GTP 有2到16个不等,能够满足一般性的应用。
注:
5) 外部存储器控制器
图1-34 MIG IP核 可综合示例
外部存储器控制器( )通常是硬核IP。在进行高速数据采集、缓存、处理等场合,可以大大方便FPGA和高速之间的交互。由于FPGA的片内存储器(如BRAM)容量受限,所以对DDR3/DDR4等外部高速存储器的支持也成为了中高端FPGA器件必备的资源。FPGA器件内部往往内嵌了一个或多个DDR3/DDR4控制器硬核IP,包括用户接口(User )模块、存储器控制器( )模块、初始化和校准(/)模块、物理层模块等。
这部分的原理非常重要,基本上能够独立完成“DDR读写实验”,就算是从“FPGA一窍不通”进阶成“FPGA熟练掌握”了,属于是大多数人学习FPGA的分水岭,这部分的实验后续会详细介绍。
6) 模拟数字转换模块
图1-35 XADC内部功能框图
FPGA器件特有的ADC,简称XADC,将模拟信号处理混合到FPGA器件。XADC包括:
1.4 基础语法 1.4.1 基础知识
1) 关于逻辑值
建议初学者将所有的信号值都规定好,也就是只使用前两个逻辑值。
2) 关于数字的表示
数字进制格式包括二进制('b)、八进制('o)、十进制('d)和十六进制('h)。
一般常用的二进制、十进制和十六进制。记得一定要规定数字的位宽(这个位宽是二进制的位宽),有时候可能不规定(默认32位)也能正常运行,但不要自己埋雷。
举个例子,现在要表示十进制数255:
二进制 表示为:8’。
十进制 表示为:8’d255。
十六进制表示为:8’hff。
注:数字分隔符(也就是下划线)可以随便加,自己看得舒服就行。
小技巧:使用自带的计算器,打开程序员模式,就可以同时看到一个数字的四种进制的表示。对于FPGA开发来说,这个工具比较方便。
3) 关于命名
标识符()就是模块名、端口名、信号名等,可以类比为软件语言中各个变量、函数的名称。对命名标识符的过程做出了如下规定(必须遵守):
1.标识符可以是任意一组字母、数字、$(符号)和_(下划线)符号的组合。
2.标识符的第一个字符必须是字母或者下划线。
3.标识符是区分大小写的。
除此之外,广大开发者还有一些约定成俗的建议:
1.不建议大小写混合使用,也就是全部大写或全部小写。
2.模块名、普通内部信号建议全部小写,常量建议全部大写。
3.信号命名最好体现信号的含义,简洁、清晰、易懂;
以下是一些推荐的写法:
1.用有意义的有效的名字如 、 等。
2.用下划线区分词,如。
3.采用一些前缀或后缀,比如时钟采用clk前缀:,。
1.4.2 数据类型
在 语言中,常用的主要有三大数据类型:寄存器数据类型、线网数据类型和参数数据类型。顾名思义,寄存器数据类型(reg)描述的是一个可以存储数据的单元,而线网数据类型(wire)则是描述一个物理连线,参数数据类型()就是常量。下面依次介绍。
综上所述,每个信号的控制逻辑如下图所示。一直没有提到的是,时序逻辑信号会等待时钟边沿再进行变化;组合逻辑信号会立即变化。为了保证FPGA具有良好的时序性,一般的信号都使用时序逻辑,只有一些控制信号、状态信号、模块之间的连接信号才使用组合逻辑,当然还需要开发者的综合考量。
图1-36 中的数据类型
注:与软件语言中直接使用等号进行赋值不同,中,时序逻辑信号一般使用非阻塞赋值
a > b
a大于b
a >= b
a大于等于b
算术右移,a右移b位,高位补符号位(最高位)
注:
逻辑移位是针对无符号数使用;算术移位是针对有符号整数使用,可以快速满足有符号数的乘以/除以2的整数次幂运算。左移位宽增加,右移位宽不变。
拼接运算符:
符号使用方法说明
{ }
{a , b}
将a、b拼接起来,作为一个新的信号
注:这个符号使用的非常广泛,比如一个有意思的用法就是实现 循环移位:假如有一个4位的流水灯信号reg [3:0] led,每个时钟沿都希望得到其循环移位的结果,于是有led