收藏 分享(赏)

FPGA入门教程.pdf

上传人:HR专家 文档编号:6298055 上传时间:2019-04-05 格式:PDF 页数:37 大小:672.08KB
下载 相关 举报
FPGA入门教程.pdf_第1页
第1页 / 共37页
FPGA入门教程.pdf_第2页
第2页 / 共37页
FPGA入门教程.pdf_第3页
第3页 / 共37页
FPGA入门教程.pdf_第4页
第4页 / 共37页
FPGA入门教程.pdf_第5页
第5页 / 共37页
点击查看更多>>
资源描述

1、 FPGA 入门教程 1数字电路设计入门 2 FPGA 简介 3 FPGA 开发流程 4RTL 设计 5Quartus 设计实例 6. ModelSim 和 Testbench 1.数字电路设计入门 1.1 数字电路设计 数字电路设计的核心是逻辑设计。通常,数字电路的逻辑值只有1 和0 ,表征的是模拟电压或电流的离散值,一般1 代表高电平,0 代表低电平。 高低电平的含义可以理解为,存在一个判决电平,当信号的电压值高于判决电平时,我们就认为该信号表征高电平,即为1 。反之亦然。 当前的数字电路中存在许多种电平标准,比较常见的有 TTL、 CMOS、 LVTTL、 LVCMOS、ECL、 PEC

2、L、 LVDS、 HSTL、 SSTL 等。这些电平的详细指标请见补充教程 1:电平标准。 数字电路设计大致可分为组合逻辑电路和时序逻辑电路。 一般的数字设计的教材中对组合逻辑电路和时序逻辑电路的定义分别为:组合逻辑电路的输出仅与当前的输入有关 ,而时序逻辑电路的输出不但与输入有关,还和系统上一个状态有关。 但是在设计中,我们一般以时钟的存在与否来区分该电路的性质。由时钟沿驱动工作的电路为时序逻辑电路。大家注意,这两种电路并不是独立存在的,他们相互交错存在于整个电路系统的设计中。 1.1.1 组合逻辑电路 组合逻辑电路由任意数目的逻辑门电路组成,一般包括与门、或门、非门、异或门、与非门、或非门

3、等。一般的组合逻辑电路如下图: 其中 A,B,C,D,E,F 为输入,G 为输出。 1.1.2 时序逻辑电路 时序逻辑电路由时钟的上升沿或下降沿驱动工作,其实真正被时钟沿驱动的是电路中的触发器(Register ),也称为寄存器。触发器的工作原理和参数如下图: Register的原理和参数 D Clk Q D Q Clk tc-q tholdTtsu tsu:建立时间 ,在时钟有效沿到来之前触发器数据输入应保持稳定的时间,如果建立时间不够,数据将不能在这个时钟沿被打入触发器。它间接约束了组合逻辑的最大延时。 thold:保持时间 ,在触发器数据输入引脚的数据在系统有效时钟沿到来后,需要保持稳定

4、的时间,如果保持时间不够,数据同样不能被打入触发器。它间接约束了组合逻辑的最小延时. tc-q: 触发器从有效时钟沿到来到输出有效的最大时间。下面是两个简单的时序逻辑电路例子: (1)、时钟分频电路 该时序电路的功能为实现对时钟 clk的 4 分频,其中 clk_2为 2 分频时钟, clk_4为 4分频时钟, enable为该电路的使能信号。其功能仿真波形如下图所示: (2)、序列检测器 该时序电路实现了一个序列检测器,当输入序列datain 中出现101 时,标志位 F 将输出1 ,其他时刻输出0 。电路中clk 为时钟信号, D1, D2, D3为移位寄存器的输出, enable为该电路

5、的使能信号。其功能仿真波形如下图所示: 可见,时序电路设计的核心是时钟和触发器,这两者也是我们设计电路时需重点关注的。 1.2 毛刺的产生与消除 1.2.1 竞争与冒险 当一个逻辑门的输入有两个或两个以上的变量发生改变时,由于这些变量是经过不同路径产生的,使得它们状态改变的时刻有先有后,这种时差引起的现象称为竞争(Race ) 。竞争的结果将很可能导致冒险(Hazard )发生(例如产生毛刺),造成错误的后果,并影响系统的工作。 组合逻辑电路的冒险仅在信号状态改变的时刻出现毛刺,这种冒险是过渡性的,它不会使稳态值偏离正常值,但在时序电路中,冒险是本质的,可导致电路的输出值永远偏离正常值或者发生

6、振荡。 避免冒险的最简单的方法是同一时刻只允许单个输入变量发生变化,或者使用寄存器采样的办法。 1.2.2 毛刺的产生与危害 信号在 FPGA 器件中通过逻辑单元连线时,一定存在延时。延时的大小不仅和连线的长短和逻辑单元的数目有关,而且也和器件的制造工艺、工作环境等有关。因此,信号在器件中传输的时候,所需要的时间是不能精确估计的,当多路信号同时发生跳变的瞬间,就产生了“ 竞争冒险” 。这时,往往会出现一些不正确的尖峰信号,这些尖峰信号就是“ 毛刺” 。 让我们来具体看一下毛刺是如何产生的。下图是一个与门电路, 我们期望的设计是,a 和 b 信号同时变化,这样输出 OUT 将一直为 0,但是实际

7、中 OUT产生了毛刺,它的仿真波形如下所示: 可见,即使是在最简单的逻辑运算中,如果出现多路信号同时跳变的情况,在通过内部走线之后,就一定会产生毛刺。而现在数字电路设计中的信号往往是由时钟控制的,如果将带有毛刺的输出信号直接连接到时钟输入端、清零或置位端口的设计,可能会导致严重的后果;此外对于多数据输入的复杂运算系统,每个数据都由相当多的位数组成。这时,每一级的毛刺都会对结果有严重的影响,如果是多级的设计,那么毛刺累加后甚至会影响整个设计的可靠性和精确性。 判断一个逻辑电路在某些输入信号发生变化时是否会产生毛刺,首先要判断信号是否会同时变化,然后判断在信号同时变化的时候,是否会产生毛刺,这可以

8、通过逻辑函数的卡诺图或逻辑函数表达式来进行判断。 1.2.3 毛刺的消除 毛刺是数字电路设计中的棘手问题,它的出现会影响电路工作的稳定性、可靠性,严重时会导致整个数字系统的误动作和逻辑紊乱。 可以通过以下几种方法来消除毛刺: 1、输出加 D 触发器 这是一种比较传统的去除毛刺的方法。原理就是用一个 D 触发器去读带毛刺的信号,利用 D 触发器对输入信号的毛刺不敏感的特点,去除信号中的毛刺。在实际中,对于简单的逻辑电路,尤其是对信号中发生在非时钟跳变沿的毛刺信号,去除效果非常的明显。 但是如果毛刺信号发生在时钟信号的跳变沿, D 触发器的效果就没有那么明显了(加 D触发器以后的输出 q,仍含有毛

9、刺)。另外,D 触发器的使用还会给系统带来一定的延时,特别是在系统级数较多的情况下,延时也将变大,因此在使用 D 触发器去除毛刺的时候,一定要视情况而定,并不是所有的毛刺都可以用 D 触发器来消除。 2、信号同步法 设计数字电路的时候采用同步电路可以大大减少毛刺。由于大多数毛刺都比较短(大概几个纳秒),只要毛刺不出现在时钟跳变沿,毛刺信号就不会对系统造成危害了。因此一般认为,只要在整个系统中使用同一个时钟就可以实现系统同步。但是,时钟信号在 FPGA器件中传递时是有延时的,我们无法预知时钟跳变沿的精确位置。也就是说我们无法保证在某个时钟的跳变沿读取的数据是一个稳定的数据,尤其是在多级设计中,这

10、个问题就更加突出。因此,做到真正的“ 同步“ 就是去除毛刺信号的关键问题。所以同步的关键就是保证在时钟的跳变沿读取的数据是稳定的数据而不是毛刺数据。以下为两种具体的信号同步方法。 (1 )信号延时同步法 信号延时法,它的原理就是在两级信号传递的过程中加一个延时环节,从而保证在下一个模块中读取到的数据是稳定后的数据,即不包含毛刺信号。这里所指的信号延时可以是数据信号的延时,也可以是时钟信号的延时。 ( 2)状态机控制 使用状态机也可以实现信号的同步和消除毛刺的目的。在数据传递比较复杂的多模块系统中,由状态机在特定的时刻分别发出控制特定模块的时钟信号或者模块使能信号,状态机的循环控制就可以使得整个

11、系统协调运作,同时减少毛刺信号。那么只要我们在状态机的触发时间上加以处理,就可以避免竞争冒险,从而抑制毛刺的产生。 3、格雷码计数器 对于一般的二进制或十进制计数器,在计数时,将有多位信号同时跳变。例如一个 3bit二进制计数器,由111 转换为000 时,必将产生毛刺。此时,使用格雷码计数器将避免毛刺的出现,因为格雷码计数器的输出每次只有一位跳变。 其他关于毛刺的详细讨论,请见补充教程 2:关于毛刺问题的探讨。 1.3 同步电路设计 同步电路是指所有电路在同一个公共时钟的上升沿或下降沿的触发下同步地工作。但在实际系统中,往往存在多时钟域的情况,这时同步的概念有所延伸,不再专指整个设计同步于同

12、一时钟沿,而是指设计应该做到局部同步,在每个时钟域内的电路要同步于同一时钟沿。 1.3.1 同步电路设计的优点: 1同步设计能有效地避免毛刺的影响,使得设计更可靠; 2同步设计易于添加异步复位reset,以使整个电路有一个确定的初始状态; 3同步设计可以减小环境对芯片的影响,避免器件受温度,电压,工艺的影响; 4同步设计可以使静态时序分析变得简单和可靠; 5同步设计可以很容易地组织流水线,提高芯片的运行速度。 1.3.2 同步电路的设计准则: 1尽可能在设计中使用同一时钟,时钟走 全局时钟网络。走全局时钟网络的时钟是最简单、最可预测的时钟,它具有很强的驱动能力,可以驱动 FPGA 内部中的所有

13、触发器,并保证 Clock skew 可以小到忽略的地步。 2避免使用混合时钟沿采样数据,即避免在设计中同时使用时钟的上升沿和下降沿。 3尽量少在模块内部使用计数器分频所产生的时钟。计数器分频时钟需完成的逻辑功能完全可由 PLL 锁相环或时钟使能电路替代。计数器分频时钟的缺点是使得系统内时钟不可控,并产生较大的 Clock skew,还使静态时序分析变得复杂。 4避免使用门控时钟。因为经组合逻辑产生的门控时钟极可能产生毛刺,使 D 触发器误动作。 5当整个电路需要多个时钟来实现,则可以将整个电路分成若干局部同步电路(尽量以同一个时钟为一个模块),局部同步电路之间接口当作异步接口考虑,而且每个时

14、钟信号的时钟偏差(T)要严格控制。 6电路的实际最高工作频率不应大于理论最高工作频率,留有设计余量,保证芯片可靠工作。 7电路中所有寄存器、状态机在系统被 reset 复位时应处在一个已知的状态。 关于同步电路设计中的其他问题请详见补充教程 3:华为同步电路设计规范。 1.3.3 关于时钟设计的讨论 目前的工程设计中一般使用同步时序电路来完成整个系统的设计,由上一节可见,时钟在同步电路设计中起着至关重要的作用。那么,我们在设计时首先要完成的是对时钟的设计。 如今在设计中常见的时钟类型包括: 全局时钟、内部逻辑时钟和门控时钟。 1 全局时钟 全局时钟即同步时钟,它通过 FPGA 芯片内的全局时钟

15、布线网络或区域时钟网络来驱动,全局时钟具有高扇出、高精度、低 Jitter 和低 Skew 的特点,它到芯片中的每一个寄存器的延迟最短,且该延迟可被认为是固定值。所以我们推荐在所有的设计中的时钟都使用全局时钟。全局时钟的设计有以下几种方法: (1). 由 PLL 锁相环来产生全局时钟。 (2). 将 FPGA芯片内部逻辑产生的时钟分配至全局时钟布线网络。 (3). 将外部时钟通过专用的全局时钟输入引脚引入 FPGA。 在我们的设计中,一般推荐电路中的所有的时钟都由 PLL 锁相环产生。一方面,PLL锁相环可实现倍频和移相的操作,使我们很方便地获得所需频率和相位的时钟;另一方面,PLL锁相环默认

16、将其驱动的时钟分配至全局时钟网络或区域时钟网络, Jitter和 Skew都很小。 下图取自我们项目中的一个 PLL 锁相环设计,该 PLL 用于驱动 DDR 的接口模块。因为功能所需,DDR 接口需要三个 133MHz的时钟,相位分别是 -90 、 0 、 -180 ,图中所示即为该时钟的产生模块。我们使用 Quartus的 Megawizard 生成 PLL 锁相环的 IP core。其中inclk_66 为 PLL 锁相环的输入时钟,由外部的 66MHz 晶振提供,经过 PLL 倍频和移相后得到所需的三个全局时钟。 o o o2 内部逻辑时钟 内部逻辑时钟即指由芯片内部的组合逻辑或计数器

17、分频产生的时钟。 对于组合逻辑时钟,特别是由多级组合逻辑产生的时钟,是要被严格禁止使用的,因为一方面组合逻辑极容易产生毛刺,特别是对多级组合逻辑;另一方面组合逻辑电路的 Jitter和 Skew 比较大,这将恶化时钟的质量。所以,一般组合逻辑产生的内部时钟仅仅适用于时钟频率较低、时钟精度要求不高的情况。 对于计数器分频产生的时钟,也应该尽量少地使用,因为这种时钟会带来比较大的延迟,降低设计的可靠性,也使得静态时序分析变得复杂。计数器分频时钟需完成的逻辑功能完全可由 PLL 锁相环或时钟使能电路替代。 还有一种由触发器产生的时钟行波时钟,即一个触发器的输出用作另一个触发器的时钟输入。文中 1.1

18、.2 节描述的时钟分频电路就是一种行波时钟。因为各触发器的时钟之间产生较大的时间偏移,很容易就会违反建立时间、保持时间的要求,导致亚稳态的发生。所以,这种行波时钟要被严格禁止使用。 3 门控时钟 一般情况下,应该避免使用门控时钟。因为经组合逻辑产生的门控时钟极可能产生毛刺,对系统造成很大危害。但对于某些功耗很大的系统而言,需要使用门控时钟来降低功耗。 我们推荐使用右图中描述的门控时钟的设计,该设计一般不会产生毛刺和亚稳态的问题。因为触发器避免了毛刺的产生,而亚稳态只可能出现在源时钟的下降沿,但是随后它与源时钟低相位相与,最后不会产生影响。 Dsource_clkclk_engated_clkq

19、outsource_clkclk_enqoutgated_clk门控时钟最好只在顶层模块中出现, 并将其分离到一个在顶层的独立模块中。 这同时保证了底层的每个模块有单一的时钟,且在本模块中的时钟不进行门控。 在补充教程 4 和补充教 程 5 中,我 们对时钟和时序的设计进行了更详细的讨论。 1.3.4 亚稳态 在同步电路或异步电路中,如果触发器的 setup 时间或 hold 时间不能得到满足,就可能产生亚稳态,此时触发器输出端 Q 在有效时钟沿之后比较长的一段时间处于不确定的状态,在这段时间里 Q 端将会产生毛刺并不断振荡、最终固定在某一电压值上,此电压值并不一定等于原来数据输入端 D的值。

20、这段时间称为决断时间(resolution time ) 。经过决断时间之后, Q 端将稳定到 0 或1 上,但是究竟是 0 还是 1,这是随机的,与输入没有必然的关系。 亚稳态的危害主要体现在破坏系统得稳定性上,由于输出在稳定下来之前可能是毛刺、振荡、固定的某一电压值,因此亚稳态除了导致逻辑误判之外,严重情况下输出 01 之间的中间电压值还会使下一级产生亚稳态(即导致亚稳态的传播) 。 逻辑误判将导致功能性错误,而亚稳态的传播则扩大了故障面,严重时将导致系统崩溃。 在异步时序电路中更容易发生亚稳态,因为异步电路一般具有多个时钟域,数据在两个时钟域间传递时,非常容易导致 setup 时间或 h

21、old 时间不满足而发生亚稳态。在同步时序电路中,当两个触发器间的组合逻辑延迟过大时,会导致 setup 时间不满足而发生亚稳态。 1.3.5 对跨时钟域数据的处理 对跨时钟域数据的处理的核心就是要保证下级时钟对上级数据采样的 setup 时间或hold 时间满足要求,即尽量避免亚稳态的发生和传播。但是,我们知道,只要系统中有异步元件,亚稳态就是无法避免的,因此设计的电路首先要减少亚稳态导致错误的发生,其次要使系统对产生的错误不敏感。我们推荐使用以下方法来解决异步时钟域数据同步问题。 1 用触发器打两拍 如下图,左边为异步输入端,经过两级触发器同步,在右边的输出将是同步的,而且该输出基本不存在

22、亚稳态。其原理是即使第一个触发器的输出端存在亚稳态,经过一个 CLK周期后,第二个触发器 D 端的电平仍未稳定的概率非常小,因此第二个触发器 Q 端基本不会产生亚稳态。然而,亚稳态是无法被根除的,一旦亚稳态发生,后果的严重程度依赖于你设计系统对产生的错误是否敏感。 2 异步 FIFO 或 DPRAM 因为异步 FIFO 或 DPRAM 使用格雷码计数器设计读写地址的指针,所以它可以很好地避免亚稳态的发生。使用方法如下,将上级芯片提供的数据随路时钟作为写信号,将数据写入异步 FIFO 或 DPRAM,然后使用本级的采样时钟将数据读出即可。唯一需要注意的是,当两级时钟频率不同时,需要设计好缓冲区,

23、并通过监控 full、 half、 empty、 useword3 调整时钟相位 信号,保证数据不会溢出,也不会被读空。 而且适用面有限。首先需对跨时钟域数据的路径进行详细的静态时序分析,然后将违反 setup 时间和 hold 时间的情况一一列出,在不影响其它设计性能的前提下,综合考虑调整两级时钟的相位关系,最终使其 setup 时间和 hold 时间满足要求。 这种方法的设计难度较大,2.FPGA 简介 2.1 什么是 FPGA mable Gate Array 的缩写, 即现场可编程门阵列, 是一种可编程的 IC以下是目前项目中使用的几种 FPGA 芯片: FPGA是 Field Pro

24、gram芯片(集成电路芯片),2.2 FPGA 的结构与组成的可编程逻辑单元构成阵列,又由可编程 I/O 单元围绕阵排成阵列的逻辑单元由布线通道中的可编程内连线连接起来实现一定的逻辑功能。 FPGA 的可编程逻辑单元一般由查找表和触发器构成。下图所示即为 Cyclone 系列 FPGA 芯 LE)组成。 图左边所示的电路,查找表是这样实现的:首先 FPGA 开发软件会自动计算逻辑电路的所有等于输入一个地址进行查表,找出地址对应的内容后输出,即实现了该逻辑功能。 通常 FPGA 由布线资源分隔列构成整个芯片,目前我们使用的片的逻辑单元(查找表(Look-Up-Table)简称为 LUT,其本质上

25、就是一个静态存储器 SRAM。 对于下可能的结果,然后把结果事先写入查找表中,FPGA 工作时,输入信号所进行的逻辑运算就实际逻辑电路 LUT 的实现方式 a,b,c,d 输入 逻辑输出 地址 RAM中存储的内容 0000 0 0000 0 0001 0 0001 0 0 . 0 1111 1 1111 1 如果所设计的是时序电路,需要触发器,则 FPGA 开发软件会自动将触发器配置在查找表的后面,实现组合逻辑时就将触发器旁路掉。 当然,对于复杂的设计,一个 LUT 是无法完成的,FPGA 可以通过进位逻辑将多个 LUT相连起来,实现 n 输入的查找表,实现设计要求。 表、触发器和布线资源组成

26、。下图内部结构,其中一对查找表和触发器构成逻辑单元LE, LE 组各种布线资源,就是一个 FPGA详细的介绍请见:补充教程2.3 FPGA 与 ASIC 设计的区别ASIC 和 FPGA个发展方向,两者唯一的区别在于, ASIC 的逻FPGA。 设计的代码风格有明显差异,特别是在功耗、速度、时序等要求上。例如意识地采用某些组合逻辑、门控时钟等,以降低功耗或提高速度。 通俗地说,FPGA 就是由查找是一个 Cyclone系列 FPGA芯片的若干个成逻辑阵列块 LAB,最后再配上芯片了。 6 FPGA PLD 结构与原理。 ASIC 是 Application Specific Integrate

27、d Circuit 的缩写,即专用集成电路。属于 SOC(System on a chip 片上系统)的两辑电路是固化在其芯片中的,我们可以将 ASIC 理解为不可编程的由于 FPGA 设计是基于固有的硬件结构(如逻辑单元、块 RAM、 PLL/DLL、时钟资源等)的;而 ASIC 设计结构灵活,目标多样,所以 ASIC 设计的代码风格和 FPGAASIC 设计中根据要求会有3. FPGA 开发流程 HDL(Hardware Design Language )和原理图是两种最常用的数字硬件电路描述方法,HDL 设计法具有更好的可移植性、通用性和模块划分与重用性的特点,在目前的工程设计开发流程是

28、基于 HDL 的。 中被广泛使用。所以,我们在使用 FPGA 设计数字电路时,其需求定义( 功能定义) pec Design S ificationRTL 级 HDL 描述 RTL Design Entry 功能仿真( 前仿真) RTL Simulation 管脚分配与设计约束Assign Pins 地址为 07,每个存储单元都是 4bit; 3由于硬件是并行工作的,在 Verilog 语言的 module 中,所有描述语句(包括连续赋值语句 assign、行为语句块 ways 和 initial 语句块以及模块实例化)都是并发执行的。 4使用完备的 ifelse 语句,使用条件完备的 cas

29、e 语句并设置 default 操作,以防止产生锁存器 latch,因为锁存器对毛刺敏5严禁设计组合逻辑反馈环路,它最容易引起振荡、毛刺、时序违规等问题。 6不要在两个或两个以上的语句块(always 或 initial)中对同一个信号赋值。 使用 verilog 进行 R1、数据流描述:采用 assign 连续赋值语句 算言的方式去:0al感。 4.1.3 阻塞赋值与非阻塞赋值 在 中,有两种过程性赋值方式,即阻塞赋值 (Verilog HDL blocking assignment)和非阻塞 (non-blocking assignment )。这两种赋值方式有着根本的区别,如果使用不当,

30、赋值综合出来的结果会和设计的期望结果相去甚远。 1阻塞 赋值的操作符为 “ = ” 。它的含义是在计算等式右侧表达式值及完成其赋值时不会被其他的 verilog 语句打断,就是说,在当前赋值没有完成之前,它阻塞了其他 verilog语句的执行。 例如:begin end 语句 2 的,它“ 阻塞“ 语句 2 的执行。这里说的“ 执行完“ 指的是在本时刻计算完 y+c 的值,并赋给 y=5(旧值) ,c=4,a=3,b=1 ,则 x=9,y=4。 的两个 always 语句块。 过程 2: always (posedge clk or negedge rst_n) always (posedge

31、 clk or negedge rst_n) begiif ( rst_n = 1b0) y = 1b0; x = 1b1; end end ,则在复位完后,x、y 1;如果先执行过程 1,则 x、 0。 的标准,上例中两个 always 块是并行执行的,与书写的前后顺序无关,但是,verilog 标准没有规定在这种特殊情况下的执行顺序。所以,这需要我们在编程时避免这样的代码。 B)?C:D 这样的运算一定可以综合。 实仅符合语法的 HDL 代码。 1 哪些是不可综合的代码 我们不可能将所有不可综合的代码都一一列出1.对于一些抽象的行为描述代码是不可综合的。比如我们常见初始化语句 initia

32、l 以及等待语句 wait 都是不可综合的可实现的。 2.对于一些抽象的运算代码也是不可综合的always (posedge clk) 试想一下,如果我们自己用笔算除法是怎么做的?从高位到低位逐次试个时钟延上一句简单的 C=A/B 同所有这些相比显得太抽象,对于只能接受 RTL 或更低层软件来说确实太难实现。for (i=0; iwordlength ; i=i+1) parity = parity xor datai; 当 wordlength 为变量时,任何 EDA 软件都不能综合这个代码。这是因为硬件规模必须然后再综合成电路。若 wordlength若它是变量时,展开的语句数不确定,4.

33、2.2 如何判断自己写的代码是可综合的 如果你不能想象出一个较直观的硬件实现方法,多路选择器是大家都很熟悉的电路而除法、开根、对数等等较复杂的运算,必须通过一定的算法实现,没有直观简单的现方法,则可以判断那些计算式是不能综合的,必须按它们的算法写出更具体的代码才能实现。此外,硬件无法支持的抽象行为描述,当然也不能被综合。 不过,这样的判断标准非常主观模糊,时延较大的组合逻辑 a_reg a_pipe a_int z_rega_reg a_pipe a_int z_reg HDL 描述的结构遇到具体情况还得按设计人员自己的经验来判断。如果以及他们的有限次组合,基本上是可综合的,否则就有无法综合的

34、可能性。当然,这样的标准仍4.3 RTL 代码的优化 求一个设计同时具备 要求和最高频率要求的前提下,占用最小的芯片面积,或者在所规定的面积下,使设计的时序余量更大,频率Pipelining,即流水线时序优化方法,其本质是调整一个较大的组合逻辑路径中的寄存Clock-To-Output 和 Setup 等时间参数的要求,达到提高设计频率的目的。 的组合逻辑,在它旁边加上若干个需优化的要一个相对客观的标准,一般来说:在 RTL 级的描述中,所有逻辑运算和加减法运算、然有缺陷,所以,正确的判断仍然要靠实践来积累经验。当你可以较准确判断代码的可综合性的时候,你对 HDL 的掌握就算完全入门了。 优化

35、 RTL 代码追求的最终目标是面积或者速度,或者是两者的平衡。面积和速度是FPGA 设计的两个基本标准。“面积”是指一个设计所消耗 FPGA 的逻辑资源数量,“速度”指设计在芯片上稳定运行所能够达到的最高频率。两者是对立统一的,即要面积最小、速度最高时不现实的。我们的设计目标应该是在满足设计时序更高。 4.3.1 Pipelining 技术 器位置,用寄存器合理分割该组合逻辑路径,从而降低路径具体实现可通过下图的方法,首先对时延较大寄存器,然后运用优化工具自动将大组合逻辑拆分为几个小的组合逻辑,同时将寄存器放在小组合逻辑在中间。 工具自动优化之后的结构 4.3.2 模块复用与资源共享 模块复

36、FPGA 的逻辑资源,即节约面积。我们通过下面如果需要实现一个补码平方器,输入是 8bit 补码,求其平方和。因为输入是补码,所示原值是正数,直接求平方。下面是两种 RTL 设计实现方式: 第一种 RTL 设计实现: module resource_share1 (data_in,square); data_in; /输入是补码 output 15:0 square; assign data_bar = data_in + 1; 第二种 RTL 设计实现: module resource_share2 (data_in,square); are; wire 7:0 data_tmp; assi

37、gn data_tmp = (data_in7)? (data_in + 1) : data_in; assign square = data_tmp * data_tmp; endmodule 可以发现,第一种 RTL 设计需要两个 16bit 乘法器,同时平方;而第二种 RTL 设计只用了一个乘法器。我们使用 Synplify Pro 对两个 RTL 设计分别进行综合,结果第一种 RTL计所占用的逻辑资源为 140 个 LUTs,第二种 RTL 设计为 75 个 LUTs。下图是两个设计的现结果: 第一种 RTL 设计,占用 140 个 LUTs 用与资源共享的目的在于节约这个例子来说明这

38、个优化方法。 以当最高位是 1 时,表示原值是负数,需要按位取反,加 1 后再平方;当最高位是 0 时,表input 7:0 wire 7:0 data_bar; assign square=(data_in7)? (data_bar*data_bar) : (data_in*data_in); endmodule input 7:0 data_in; /输入是补码 output 15:0 squ使设实第 计,占用 75 个 LUTs 逻辑复 而改善时序条件的优化手段。逻辑复制最常使用的场合是调整信号的 buffer 来满足信号的驱动能力的要求,在复制了一条路径后,就可减轻这条路径的驱动能力,

39、同时路径的延时也同时减小了。 二种 RTL 设4.3.3 逻辑复制 制是一种通过增加面积扇出。如下图, FPGA 一般通过插入4.4 状态机的设计 我们推荐在状态机的设计中采用两段式写法(2 个 always 模块)或三段式写法(3 个always 模块)。 两段式写法的核心思想是,一个 always 模块采用同步时序描述状态转移;另一个 always模块采用组合逻辑方式判断状态转移条件,描述状态转移规律。其结构如下图: 状态转移 条件判断 组合逻辑 当前状态时序逻辑组合逻辑输出 ,若时序允许 ,尽量插入寄存器输出输入 下一状态状态 时钟 状态 输出 组合逻辑 时序逻辑 组合逻辑三段式写法的

40、核心思想是,一个 always 模块采用同步时序的方式描述状态转移,一个时序电路描述每个状态的输出。其结构如下图:我们归纳出状态机设计的其它技巧和准则: 1 状态机的编码最好使用 one-hot(独热码)。2 一个完备的状态机应该具备初始化状态和默认状态。 4 时序逻辑 always 模块使用非阻塞赋值“ = “,组合逻辑模块使用阻塞赋值“ = ” 。 minpinpoutput o1,o2,err; parameter 2:0 /one hot with zero idle IDLE = 3b000, S1 = 3b001, S2 = 3b010, ERROR = 3b100; 采用组合逻辑

41、的方式判断状态转移条件,描述状态转移规律,第三个 always 模块使用同步3状态机的编码可以用 parameter 定义,不推荐使用 define 宏定义。 5 使用完备的 ifelse 语句和 case 语句。 6 case 语句需具备 full_case 和 parallel_case 属性。full_case 定义了所有可能的输入模式,parallel_case 定义了 case 项是不重复的。 下面是一个状态机的例子,它采用了三段式写法,one-hot 编码,并且符合其它状态机的设计准则。 odule state ( nrst,clk, i1,i2,o1,o2,err); ut nr

42、st,clk; ut i1,i2; reg o1,o2,err; reg 2:0 NS,CS; 状态转移 条件判断 组合逻辑 组合逻辑 当前状态时序逻辑时序逻辑状态转移条件判断组合逻辑组合逻辑当前状态时序逻辑 时序逻辑 输入 状态 当前状态时钟 下一状态 下一状态下一状态 输出 输出always (posedge clk or negedge nrst) /1st always block, sequential state transition if (!nrst) CS = IDLE; else CS =NS; always (nrst or CS or i1 or i2) /2nd al

43、ways block, combinational condition judgment begin NS = 3bx; case (CS) IDLE: begin if (i1) NS = IDLE; if (i1 i2) NS = ERROR; end ; if (i2 S2: begin NS = S2; if (i2 if (i1) NS = ERROR; if (i1) NS = IDLE; ult: begin NS = IDLE; end gedge nrst) /3rd always block, the sequential FSM output 0; begin 3b000

44、; 3b100; if (i1 end if (i2) if (i2 end ERROR: begin enddefaendcase end always (posedge clk or neif (!nrst) o1,o2,err = 3b00else o1,o2,err = 3b000; case (NS) IDLE: o1,o2,err=S1: o1,o2,err=S2: o1,o2,err=3b010; ERROR: o1,o2,err=3b111; plify Pro 分析该状态机,可以使用专用的 FSM 观察器(FSM 息显示选项卡。左endcase end endmodule 我

45、们推荐使用工具 SynViewer)进行分析。下图为在 FSM Viewer 中得到的状态转移图和 FSM 信图中被选中的状态和转移路径,将在右图中同时被标示出。 5Quartus 设计实例 该实例设计实现一个简单的DDS 正模块,地址产生模块,ROM40MHz的时钟到FPGA 内部,进入时定精确的 120MHz的系统时钟。然后,累加寄存器输出的数据进行累加,ROM查找表模块在每个系统时钟的上升沿,点数据并输出,该数据就是最终的DDS信号。那么下面我们就来开始设计这个DDS正弦波发生器。 5.1 新建 project 首先,建立一个 Quartus工程,点击 file 在弹出的对话 框中输入工

46、程目录和工程名,然后在器件选择框中选择 FPGA 芯片的型号。我们在这里假定使用 cyclone 系列的 EP1C6Q240C8。 5.2 设计输入 下面我们将通过一个 Quartus设计实例来向大家介绍如何进行实际的 FPGA 设计开发。 弦波发生器。它 可分解为 3 个部分来设计:时钟产生查找表模块。整个系统实现的思路是:首先,由外部晶振引入钟产生模块,对时钟进行处理并 3 倍频后,得到一个稳地址产生模块在系统时钟的激励下,将频率控制字与然后把累加结果作为地址输出给ROM 查找表模块。最后,按照地址来读取ROM 查找表中相应的波形采样40MHz时钟时钟产生模块 120MHz 时钟地址产生模

47、块ROM 查找表 DDS 波形信号address频率控制字 设计 输入的第一步,是建立顶层设计文件:点击 fileNEW 这样就点击 tools建立一个新的原理图文件,我们将这个原理图文件作为顶层文件。 对于时钟产生模块, 我们打算用PLL锁相环来实现,所以可以使用 Quartus自带的 IP core调用工具 Megafunction 来产生 PLL 锁相环的。 或者右键选择 new InsertSymbol;选择 create a custom megafunction variation ,然后选择下的 ,接着按照要求配置PLL 模块。 实现地址产生模块,点击 fileNEW各项参数,最

48、后得到下一步是 建立一个新的verilog文件,然后输入 RTL 代码: timescale 1nsmodule address_gen ble; input 5:0control_word; output 11:0 address; always (posedge clk or negedge reset) else gin address = address; /10ps (clk, reset,enable,control_word,address); input clk,reset,enareg 11:0address; begin if (reset = 1b0) begin address = 12h000; end else if (enable = 1b1) begin address = address + 6b0,control_word; end beend end endmodule 接着我们将这些 RTL 代码生成为一个子模块 ,以方便将Update其加入到顶层文件中。点击 file Create/即生成了该模块,右键选择 InsertSymbol,引用该模块至原理图中然后点击。 最后一步,是实现 ROM 查找表模块。我们同样可以调用 Quartus的 IP core 来实现,tools因为在 Megafunc

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 实用文档 > 简明教程

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报