发 帖  
原厂入驻New
[讨论]

FPGA入门教程

2014-6-30 15:45:20  3043
分享
4
FPGA入门教程

1.数字电路设计入门
2FPGA简介
3FPGA开发流程
4RTL设计
5QuartusⅡ设计实例
6. ModelSimTestbench1.
数字电路设计入门
1.1数字电路设计
数字电路设计的核心是逻辑设计。通常,数字电路的逻辑值只有‘1’‘0’,表征的是模拟电压或电流的离散值,一般‘1’代表高电平,‘0’代表低电平。
高低电平的含义可以理解为,存在一个判决电平,当信号的电压值高于判决电平时,我们就认为该信号表征高电平,即为‘1’。反之亦然。
当前的数字电路中存在许多种电平标准,比较常见的有TTLCMOSLVTTLLVCMOSECLPECLLVDSHSTLSSTL等。这些电平的详细指标请见《补充教程1:电平标准》。
数字电路设计大致可分为组合逻辑电路和时序逻辑电路。
一般的数字设计的教材中对组合逻辑电路和时序逻辑电路的定义分别为:组合逻辑电路的输出仅与当前的输入有关,而时序逻辑电路的输出不但与输入有关,还和系统上一个状态有关。
但是在设计中,我们一般以时钟的存在与否来区分该电路的性质。由时钟沿驱动工作的电路为时序逻辑电路。大家注意,这两种电路并不是独立存在的,他们相互交错存在于整个电路系统的设计中。
1.1.1 组合逻辑电路
组合逻辑电路由任意数目的逻辑门电路组成,一般包括与门、或门、非门、异或门、与非门、或非门等。一般的组合逻辑电路如下图:


1

其中A,B,C,D,E,F为输入,G为输出。
1.1.2 时序逻辑电路
时序逻辑电路由时钟的上升沿或下降沿驱动工作,其实真正被时钟沿驱动的是电路中的触发器(Register),也称为寄存器。触发器的工作原理和参数如下图:

2

下面是两个简单的时序逻辑电路例子:
(1)、时钟分频电路

3

该时序电路的功能为实现对时钟clk4分频,其中clk_22分频时钟,clk_44分频时钟,enable为该电路的使能信号。其功能仿真波形如下图所示:

4

(2)、序列检测器

5

该时序电路实现了一个序列检测器,当输入序列‘datain’中出现‘101’时,标志位F将输出‘1’,其他时刻输出‘0’。电路中‘clk’为时钟信号,‘D1’‘D2’‘D3’为移位寄存器的输出,enable为该电路的使能信号。其功能仿真波形如下图所示:

6

可见,时序电路设计的核心是时钟和触发器,这两者也是我们设计电路时需重点关注的。
1.2毛刺的产生与消除
1.2.1竞争与冒险
当一个逻辑门的输入有两个或两个以上的变量发生改变时,由于这些变量是经过不同路径产生的,使得它们状态改变的时刻有先有后,这种时差引起的现象称为竞争(Race)。竞争的结果将很可能导致冒险(Hazard)发生(例如产生毛刺),造成错误的后果,并影响系统的工作。
组合逻辑电路的冒险仅在信号状态改变的时刻出现毛刺,这种冒险是过渡性的,它不会使稳态值偏离正常值,但在时序电路中,冒险是本质的,可导致电路的输出值永远偏离正常值或者发生振荡。
避免冒险的最简单的方法是同一时刻只允许单个输入变量发生变化,或者使用寄存器采样的办法。
1.2.2毛刺的产生与危害
信号在FPGA器件中通过逻辑单元连线时,一定存在延时。延时的大小不仅和连线的长短和逻辑单元的数目有关,而且也和器件的制造工艺、工作环境等有关。因此,信号在器件中传输的时候,所需要的时间是不能精确估计的,当多路信号同时发生跳变的瞬间,就产生了竞争冒险。这时,往往会出现一些不正确的尖峰信号,这些尖峰信号就是毛刺
让我们来具体看一下毛刺是如何产生的。下图是一个与门电路,

7

我们期望的设计是,ab信号同时变化,这样输出OUT将一直为0,但是实际中OUT产生了毛刺,它的仿真波形如下所示:

8

可见,即使是在最简单的逻辑运算中,如果出现多路信号同时跳变的情况,在通过内部走线之后,就一定会产生毛刺。而现在数字电路设计中的信号往往是由时钟控制的,如果将带有毛刺的输出信号直接连接到时钟输入端、清零或置位端口的设计,可能会导致严重的后果;此外对于多数据输入的复杂运算系统,每个数据都由相当多的位数组成。这时,每一级的毛刺都会对结果有严重的影响,如果是多级的设计,那么毛刺累加后甚至会影响整个设计的可靠性和精确性。 判断一个逻辑电路在某些输入信号发生变化时是否会产生毛刺,首先要判断信号是否会同时变化,然后判断在信号同时变化的时候,是否会产生毛刺,这可以通过逻辑函数的卡诺图或逻辑函数表达式来进行判断。
1.2.3毛刺的消除
毛刺是数字电路设计中的棘手问题,它的出现会影响电路工作的稳定性、可靠性,严重时会导致整个数字系统的误动作和逻辑紊乱。
可以通过以下几种方法来消除毛刺: 1、输出加D触发器 这是一种比较传统的去除毛刺的方法。原理就是用一个D触发器去读带毛刺的信号,利用D触发器对输入信号的毛刺不敏感的特点,去除信号中的毛刺。在实际中,对于简单的逻辑电路,尤其是对信号中发生在非时钟跳变沿的毛刺信号,去除效果非常的明显。 但是如果毛刺信号发生在时钟信号的跳变沿,D触发器的效果就没有那么明显了(加D触发器以后的输出q,仍含有毛刺)。另外,D触发器的使用还会给系统带来一定的延时,特别是在系统级数较多的情况下,延时也将变大,因此在使用D触发器去除毛刺的时候,一定要视情况而定,并不是所有的毛刺都可以用D触发器来消除。 2、信号同步法 计数字电路的时候采用同步电路可以大大减少毛刺。由于大多数毛刺都比较短(大概几个纳秒),只要毛刺不出现在时钟跳变沿,毛刺信号就不会对系统造成危害了。因此一般认为,只要在整个系统中使用同一个时钟就可以实现系统同步。但是,时钟信号在FPGA器件中传递时是有延时的,我们无法预知时钟跳变沿的精确位置。也就是说我们无法保证在某个时钟的跳变沿读取的数据是一个稳定的数据,尤其是在多级设计中,这个问题就更加突出。因此,做到真正的"同步"就是去除毛刺信号的关键问题。所以同步的关键就是保证在时钟的跳变沿读取的数据是稳定的数据而不是毛刺数据。以下为两种具体的信号同步方法。 1)信号延时同步法 信号延时法,它的原理就是在两级信号传递的过程中加一个延时环节,从而保证在下一个模块中读取到的数据是稳定后的数据,即不包含毛刺信号。这里所指的信号延时可以是数据信号的延时,也可以是时钟信号的延时。 2)状态机控制 使用状态机也可以实现信号的同步和消除毛刺的目的。在数据传递比较复杂的多模块系统中,由状态机在特定的时刻分别发出控制特定模块的时钟信号或者模块使能信号,状态机的循环控制就可以使得整个系统协调运作,同时减少毛刺信号。那么只要我们在状态机的触发时间上加以处理,就可以避免竞争冒险,从而抑制毛刺的产生。
3、格雷码计数器
对于一般的二进制或十进制计数器,在计数时,将有多位信号同时跳变。例如一个3bit二进制计数器,由’111’转换为’000’时,必将产生毛刺。此时,使用格雷码计数器将避免毛
刺的出现,因为格雷码计数器的输出每次只有一位跳变。
其他关于毛刺的详细讨论,请见补充教程2:关于毛刺问题的探讨。
1.3同步电路设计
同步电路是指所有电路在同一个公共时钟的上升沿或下降沿的触发下同步地工作。但在实际系统中,往往存在多时钟域的情况,这时同步的概念有所延伸,不再专指整个设计同步于同一时钟沿,而是指设计应该做到局部同步,在每个时钟域内的电路要同步于同一时钟沿。
1.3.1 同步电路设计的优点:
1.同步设计能有效地避免毛刺的影响,使得设计更可靠;
2.同步设计易于添加异步复位reset,以使整个电路有一个确定的初始状态;
3.同步设计可以减小环境对芯片的影响,避免器件受温度,电压,工艺的影响;
4.同步设计可以使静态时序分析变得简单和可靠;
5.同步设计可以很容易地组织流水线,提高芯片的运行速度。
1.3.2同步电路的设计准则:
1.尽可能在设计中使用同一时钟,时钟走全局时钟网络。走全局时钟网络的时钟是最简单、最可预测的时钟,它具有很强的驱动能力,可以驱动FPGA内部中的所有触发器,并保证clock skew可以小到忽略的地步。
2.避免使用混合时钟沿采样数据,即避免在设计中中同时使用时钟的上升沿和下降沿。
3.尽量少在模块内部使用计数器分频所产生的时钟。计数器分频时钟需完成的逻辑功能完全可由PLL锁相环或时钟使能电路替代。计数器分频时钟的缺点是使得系统内时钟不可控,并产生较大的Clock skew,还使静态时序分析变得复杂。
4.避免使用门控时钟。因为经组合逻辑产生的门控时钟极可能产生毛刺,使D触发器误动作。
5.当整个电路需要多个时钟来实现,则可以将整个电路分成若干局部同步电路(尽量以同一个时钟为一个模块),局部同步电路之间接口当作异步接口考虑,而且每个时钟信号的时钟偏差(△T)要严格控制。
6.电路的实际最高工作频率不应大于理论最高工作频率,留有设计余量,保证芯片可靠工作。
7.电路中所有寄存器、状态机在系统被reset复位时应处在一个已知的状态。
关于同步电路设计中的其他问题请详见补充教程3:华为同步电路设计规范。
1.3.3关于时钟设计的讨论
目前的工程设计中一般使用同步时序电路来完成整个系统的设计,由上一节可见,时钟在同步电路设计中起着至关重要的作用。那么,我们在设计时首先要完成的是对时钟的设计。
如今在设计中常见的时钟类型包括: 全局时钟、内部逻辑时钟和门控时钟。
1 全局时钟
全局时钟即同步时钟,它通过FPGA芯片内的全局时钟布线网络或区域时钟网络来驱动,全局时钟具有高扇出、高精度、低Jitter和低Skew的特点,它到芯片中的每一个寄存器的延迟最短,且该延迟可被认为是固定值。所以我们推荐在所有的设计中的时钟都使用全局时钟。全局时钟的设计有以下几种方法:

(1). PLL锁相环来产生全局时钟。
(2). FPGA芯片内部逻辑产生的时钟分配至全局时钟布线网络。
(3). 将外部时钟通过专用的全局时钟输入引脚引入FPGA
在我们的设计中,一般推荐电路中的所有的时钟都由PLL锁相环产生。一方面,PLL锁相环可实现倍频和移相的操作,使我们很方便地获得所需频率和相位的时钟;另一方面,PLL锁相环默认将其驱动的时钟分配至全局时钟网络或区域时钟网络,JitterSkew都很小。
下图取自我们项目中的一个PLL锁相环设计,该PLL用于驱动DDR的接口模块。因为功能所需,DDR接口需要三个133MHz的时钟,相位分别是-900-180,图中所示即为该时钟的产生模块。我们使用QuartusⅡ的Megawizard生成PLL锁相环的IP core。其中‘inclk_66’PLL锁相环的输入时钟,由外部的66MHz晶振提供,经过PLL倍频和移相后得到所需的三个全局时钟。 ooo

2. 内部逻辑时钟
内部逻辑时钟即指由芯片内部的组合逻辑或计数器分频产生的时钟。
对于组合逻辑时钟,特别是由多级组合逻辑产生的时钟,是要被严格禁止使用的,因为一方面组合逻辑极容易产生毛刺,特别是对多级组合逻辑;另一方面组合逻辑电路的JitterSkew比较大,这将恶化时钟的质量。所以,一般组合逻辑产生的内部时钟仅仅适用于时钟频率较低、时钟精度要求不高的情况。
对于计数器分频产生的时钟,也应该尽量少地使用,因为这种时钟会带来比较大的延迟,降低设计的可靠性,也使得静态时序分析变得复杂。计数器分频时钟需完成的逻辑功能完全可由PLL锁相环或时钟使能电路替代。
还有一种由触发器产生的时钟行波时钟,即一个触发器的输出用作另一个触发器的时钟输入。文中1.1.2节描述的时钟分频电路就是一种行波时钟。因为各触发器的时钟之间产生较大的时间偏移,很容易就会违反建立时间、保持时间的要求,导致亚稳态的发生。所以,这种行波时钟要被严格禁止使用。
3 门控时钟
一般情况下,应该避免使用门控时钟。因为经组合逻辑产生的门控时钟极可能产生毛刺,对系统造成很大危害。但对于某些功耗很大的系统而言,需要使用门控时钟来降低功耗。
我们推荐使用右图中描述的门控时钟的设计,该设计一般不会产生毛刺和亚稳态的问题。因为触发器避免了毛刺的产生,而亚稳态只可能出现在源时钟的下降沿,但是随后它与源时钟低相位相与,最后不会产生影响。
门控时钟最好只在顶层模块中出现,并将其分离到一个在顶层的独立模块中。这同时保证了底层的每个模块有单一的时钟,且在本模块中的时钟不进行门控。
在补充教程4和补充教程5中,我们对时钟和时序的设计进行了更详细的讨论。 Dsource_clkclk_engated_clkqoutsource_clkclk_enqoutgated_clk
1.3.4 亚稳态在同步电路或异步电路中,如果触发器的setup 时间或hold 时间不能得到满足,就可能产生亚稳态,此时触发器输出端Q在有效时钟沿之后比较长的一段时间处于不确定的状态,在这段时间里Q端将会产生毛刺并不断振荡、最终固定在某一电压值上,此电压值并不一定等于原来数据输入端D的值。这段时间称为决断时间(resolution time)。经过决断时间之后,Q端将稳定到01上,但是究竟是0还是1,这是随机的,与输入没有必然的关系。
亚稳态的危害主要体现在破坏系统得稳定性上,由于输出在稳定下来之前可能是毛刺、振荡、固定的某一电压值,因此亚稳态除了导致逻辑误判之外,严重情况下输出01之间的中间电压值还会使下一级产生亚稳态(即导致亚稳态的传播)。逻辑误判将导致功能性错误,而亚稳态的传播则扩大了故障面,严重时将导致系统崩溃。
在异步时序电路中更容易发生亚稳态,因为异步电路一般具有多个时钟域,数据在两个时钟域间传递时,非常容易导致setup 时间或hold 时间不满足而发生亚稳态。在同步时序电路中,当两个触发器间的组合逻辑延迟过大时,会导致setup 时间不满足而发生亚稳态。
1.3.5 对跨时钟域数据的处理
对跨时钟域数据的处理的核心就是要保证下级时钟对上级数据采样的setup 时间或hold 时间满足要求,即尽量避免亚稳态的发生和传播。但是,我们知道,只要系统中有异步元件,亚稳态就是无法避免的,因此设计的电路首先要减少亚稳态导致错误的发生,其次要使系统对产生的错误不敏感。我们推荐使用以下方法来解决异步时钟域数据同步问题。
1 用触发器打两拍
如下图,左边为异步输入端,经过两级触发器同步,在右边的输出将是同步的,而且该输出基本不存在亚稳态。其原理是即使第一个触发器的输出端存在亚稳态,经过一个CLK周期后,第二个触发器D端的电平仍未稳定的概率非常小,因此第二个触发器Q端基本不会产生亚稳态。然而,亚稳态是无法被根除的,一旦亚稳态发生,后果的严重程度依赖于你



设计系统对产生的错误是否敏感。
2 异步FIFODPRAM
因为异步FIFODPRAM使用格雷码计数器设计读写地址的指针,所以它可以很好地避免亚稳态的发生。使用方法如下,将上级芯片提供的数据随路时钟作为写信号,将数据写入异步FIFODPRAM,然后使用本级的采样时钟将数据读出即可。唯一需要注意的是,当两级时钟频率不同时,需要设计好缓冲区,并通过监控fullhalfemptyuseword

是,当两级时钟频率不同时,需要设计好缓冲区,并通过监控fullhalfemptyuseword3 调整时钟相位
这种方法的设计难度较大,

FPGAField Program芯片(集成电路芯片),
通常FPGA由布线资源分隔
列构成整个芯片,目前我们使用的
片的逻辑单元(
可能的结果,然后把结果事先写入查找表中,FPGA工作时,输入信号所进行的逻辑运算就查找表(Look-Up-Table)简称为LUT,其本质上就是一个静态存储器SRAM 对于下
实际逻辑电路 LUT的实现方式 ....
0
...
0
1111
1
1111
1
9
3.1 需求定义(功能定义) 设计和实现一个系统的第一步,是明确整个系统的性能指标,然后进一步将系统功能划 分为可实现的具体功能模块,同时明确各模块的功能与基本时序,还可大致确定模块间的接 口,如时钟、读写信号、数据流和控制信号等。 3.2 RTL HDL 描述 RTL 级(寄存器传输级)指不关注寄存器和组合逻辑的细节(如使用了多少逻辑门、逻 辑门的连接拓扑结构等),通过描述寄存器到寄存器之间的逻辑功能的 HDL 设计方法。RTL 级比门级更抽象,同时也更简单和高效。RTL 级的最大特点是可以直接用综合工具将其综 合为门级网表。RTL 级设计直接决定着系统的功能和效率。我们使用的 HDL 语言是 verilog 3.3 功能仿真(前仿真) 功能仿真也称综合前仿真,其目的是验证 RTL 级描述是否与设计意图一致。为了提高效 率,功能仿真需要建立 testbench,其测试激励一般使用行为级 HDL 语言描述。 3.4 管脚分配与设计约束 无论是 RTL 级还是门级的 HDL 设计方法,在实现该逻辑时都需要与实际的 FPGA 芯片 相匹配。管脚分配是指将设计文件的输入输出信号指定到器件的某个管脚,设置此管脚的电 平标准、电流强度等。设计约束指对设计的时序约束和在综合、布局布线阶段附加的约束等。 3.5 综合 RTL HDL 语言翻译成由与、或、非门等基本逻辑单元组成的门级连接(网表),并 根据设计目标与要求(约束条件)优化所生成的逻辑连接,输出门级网表文件。 3.6 门级仿真(综合后仿真) 在综合后通过后仿真来检查综合结果是否与原设计一致。一般,综合后仿真和功能仿真 的测试激励相同。由于综合工具日益完善,在目前的 FPGA 设计中,这一步骤被省略掉。 3.7 布局布线 配。也可以简单地将布局布线理解为对 FPGA 内部查找表和寄存器资源的合理配置,那么 布局布线就是使用综合后的网表文件,将工程的逻辑与时序要求与器件的可用资源相匹
可以被理解挑选可实现设计
资源以最优方式连接起来。 3.8时序/时延分析布线延时。时序/时延分析的时序仿真是最准确的,能较好地反映芯片的实际工作情况,同
时发现时序违规(Timing Vio
时间、保持时间)的情况。3.9配置与下载
通过编程器programmer)将布
程。文件格JTAG
4.2. ,我们举几个例子来说明这个问题: 的延迟语句(如:#delay)、 ,他们所描述的功能对硬件而言是不 。比如,实现两个变量相除运算的代码: c<=A/B; 我们将发现这句代码只能在前仿真中正确执行,在 QuartusⅡ和其他 EDA 软件中都不 能将其综合成硬件。 除、求余、移位。试除和求余需要减法器,商数和余数的中间结果必须有寄存器存储;而这 些运算显然不能在一 完成,它需要一个状态机来控制时序,经过多个时钟周期 能得出结果。 次描述的 EDA (注:有些 FPGA 的配套软件提供乘除法的运算模块, 但也只能支持直接调用,不支持把形如 C=A/B 的语句综合成除法模块) 3.对于不定次数的循环运算是不可综合的,比如对于如下的代码段: 是有限的、固定的。当综合软件遇到循环语句时,总是将其展开成若干条顺序执行的语句, 是常数,则展开的语句数是确定的,具有可综合性;而 对应的硬件电路数量也不能确定,无法被综合。这样 的语句还包括 whilerepeatforever 等,他们都不可综合。 通常 EDA 软件对 HDL 代码的综合能力总是比人的思维差。也就是说,对于一段代码, EDA 软件肯定也不行。比如说,加法器、 ,所以类似 A+B-C(A>B)?C:D 这样的运算一定可以综 合。 仅符合语法的HDL代码。
1哪些是不可综合的代码
我们不可能将所有不可综合的代码都一一列出
1.对于一些抽象的行为描述代码是不可综合的。比如我们常见
初始化语句initial以及等待语句wait都是不可综合的
可实现的。
2.对于一些抽象的运算代码也是不可综合的
always @(posedge clk)
试想一下,如果我们自己用笔算除法是怎么做的?从高位到低位逐次试
个时钟延上
一句简单的C=A/B同所有这些相比显得太抽象,对于只能接受RTL或更低层
软件来说确实太难实现。
for (i=0; i<wordlength ; i=i+1)
parity = parity xor data;
wordlength为变量时,任何EDA软件都不能综合这个代码。这是因为硬件规模必须
然后再综合成电路。若wordlength
若它是变量时,展开的语句数不确定,4.2.2如何判断自己写的代码是可综合的如果你不能想象出一个较直观的硬件实现方法,多路选择器是大家都很熟悉的电路
而除法、开根、对数等等较复杂的运算,必须通过一定的算法实现,没有直观简单的现方法,则可以判断那些计算式是不能综合的,必须按它们的算法写出更具体的代码才能实现。此外,硬件无法支持的抽象行为描述,当然也不能被综合。不过,这样的判断标准非常主观模糊,
要一个相对客观的标准,一般来说:在RTL级的描述中,所有逻辑运算和加减法运算、
然有缺陷,所以,正确的判断仍然要靠实践来积累经验。当你可以较准确判断代码的可综合性的时候,你对HDL的掌握就算完全入门了。优化RTL代码追求的最终目标是面积或者速度,或者是两者的平衡。面积和速度是FPGA设计的两个基本标准。面积是指一个设计所消耗FPGA的逻辑资源数量,速度指设计在芯片上稳定运行所能够达到的最高频率。两者是对立统一的,即要
面积最小、速度最高时不现实的。我们的设计目标应该是在满足设计时序
更高。4.3.1 Pipelining技术器位置,用寄存器合理分割该组合逻辑路径,从而降低路径
具体实现可通过下图的方法,首先对时延较大
时延较大的组合逻辑a_rega_pipe a_int a_reg a_pipe a_int z_reg HDL描述的结构寄存器,然后运用优化工具自动将大组合逻辑拆分为几个小的组合逻辑,同时将寄存器放在小组合逻辑在中间。



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
不是一个风骚女 2014-6-30 15:56:21
没想到鹰哥还会FPGA啊!!期待分享连载项目!!!
回复

举报

张奇 2014-7-4 18:40:40
没有可以下载的附件吗
回复

举报

只有小组成员才能发言,加入小组>>

82个成员聚集在这个小组

加入小组

创建小组步骤

关闭

站长推荐 上一条 /8 下一条

快速回复 返回顶部 返回列表