Altera资料玩转FPGA.docx
《Altera资料玩转FPGA.docx》由会员分享,可在线阅读,更多相关《Altera资料玩转FPGA.docx(62页珍藏版)》请在冰豆网上搜索。
![Altera资料玩转FPGA.docx](https://file1.bdocx.com/fileroot1/2023-2/23/96227a17-aeed-4e1f-b282-fe716ada238f/96227a17-aeed-4e1f-b282-fe716ada238f1.gif)
Altera资料玩转FPGA
玩转FPGA
作者信息:
DylanWang(王欣)istheSeniorApplicationsEngineerfromAlterafocusontheDSPfield.AftergraduatedfromFudanUniversity,hestartedtoworkastheASICdesigner,andgainedseveralyearsofdesignexperience.ThenwenttotheStateUniversityofNewYorkforthefurtherresearchwork,majorbasedontheDSPalgorithmdesignandimplement.
HejoinedAlterain2005,focusedontheDSPfield.Astheapplicationsengineer,providesthetechnicalsupporttothecustomeronweb.Withtheexperienceonbothofalgorithmandimplementation,DylanWangisfamiliarwiththeadvancedDSPdesignsolutiontoimplementthealgorithmintohardware.
原文分为多个部分
1前言
一直以来都想写点什么,关于FPGA设计,因为有点不太服气。
为什么同样是设计,有些人可以好像玩一样的摆弄,photoshop,很时尚,很跩。
有些人可以用所谓的广告创意玩弄人们的智商。
而硬件工程师则一律的被人以为呆板没有创意。
我是说,为什么我们不可以享受设计本身的乐趣,发挥我们自己的创意,为什么就不可以很随心所欲的摆弄我们手里的那些玩具到处炫耀,让美女们看着我们的眼睛都发光?
难道一定就是那些冷冰冰的Datasheet,死板的Schedule,老板的猪肝脸?
所以我写这些东西的目的,就是想让大家可以和我一起起来,玩转FPGA。
所以大家千万别抱着学习的态度来看。
看累了,不如去打打游戏,看烦了,不如自己去试着做几个项目玩玩。
FPGA是可以玩的,而设计FPGA的工具也是很好玩的,为什么?
我们先了解一下我们的玩具。
和所有的玩具一样,这款玩具也有它的适合玩家。
你如果有一些准备,你可以玩得更开心些。
首先是语言,你需要至少知道一样设计方式吧。
Verilog或者VHDL我个人比较喜欢Verilog,不过这并不重要。
不会?
那会画电路图也可以啊。
或者呢,会用Simulink搭个模型什么的也可以。
如果会写一点C,恐怕就更好了。
那么什么是FPGA(已经知道的朋友尽可以跳过去不看)。
想知道学名,去查一下字典,想知道他的历史,去问一下你的教授。
我不说这些,因为我们的目的,就是玩。
你应该知道芯片吧。
对,好像因特尔的CPU,还有AMD。
好像德州仪器的DSP。
还有ASIC,ASSP,反正现在这个世界,没有芯片你恐怕活不下去。
而学电子的,如果不知道芯片,那也不用活了。
还有一样东西,你一定也知道,就是CD-RW,DVD-RW.反复可擦写光盘。
而FPGA就是反复可擦写的芯片。
这样你就知道他能有多好玩了,是否还记得第一次拿到CD-RW的时候那种惊喜的感觉?
想放什么就放什么,想做什么就做什么。
你拿到的这东西就是一片巨大的空白,就看玩家怎么往里面塞东西了。
因为他已经是现成的半成品,完全不需要去等待漫长的流片时间,你就可以看到你的设计在板上实现。
这就是为什么这个玩具,它可以玩,而且因为是数字电路,所以随便你怎么玩,只要你不插错电源,都可以。
不会着火的安全玩具。
下面一个问题是,为什么要玩FPGA。
FPGA一开始是一种附属的玩具,主要的玩具是ASIC。
人们为了验证ASIC设计的功能,往往用FPGA来测试。
因为他不需要漫长的制造时间。
就好像看看这个小孩子长什么样吧,也就知道他长大了大概是什么样子。
但是现在这个小孩子居然也慢慢长大了。
他开始普遍的被用在非常多的产品里面。
首先一个原因是价格。
现在的工艺水平是越来越高,这当然是好事情,但是坏事情是,也变得越来越贵。
可以想象啊,线宽越来越窄,不是需要更厉害一点的放大镜吗?
而这种高工艺导致的高价格是很多产量并不大的ASIC无法承受。
而FPGA作为一个通用的器件呢,它完全可以去追求最新最好的工艺,而让它的买家一起分摊它的成本。
它是目前芯片业拥有利润空间最大的一个分支。
可以想象,如果有一天,FPGA公司把这块利润释放出来,对ASIC,ASSP设计公司的打击是致命的。
第二个原因,就是他可以玩,可以反复擦写。
玩这个,比玩ASIC要快很多,产品可以早点卖出去。
另外如果有一天,你又想出了更好的玩法,你完全可以去把你已经卖给别人的东西换掉,变成更好的东西。
而如果这个时候你面对的是你设计的ASIC,你只好哭吧。
第三个原因,就好像广告里面说的:
方~~~~~便。
再来看看这套玩具里面有些什么.首先是硬件,各种款式的FPGA芯片,各种应用的开发板。
根据各自己不同的玩法,选择,拼接各种不同的产品系列。
如果现成的不够用了,完全可以自己做一块。
然后是工具。
QuartusII,这是一个魔盒,它就好像photoshop一样,可以把你原本看上去有点尴尬的照片,变成美轮美奂的艺术品。
NiosII,嵌入式CPU,是的,你没听错,就是CPU,而且是你想放多少就可以放多少的CPU。
还不过瘾?
那看看DSPbuilder吧(这是我的至爱)。
帮你把Simulink模型算法变成最终硬件的工具。
是的,你完全不需要写一行代码。
好了,不要摩拳擦掌了,开始玩吧。
关于QuartusII的一些事情
QuartusII其实就是一个转换器。
一个把你理解的逻辑语言转换成为器件能理解的语言,然后可以让FPGA按照你的想法去工作。
我们写的那些VHDL啦,Verilog啦什么的,其实都是人类自己定义的语言,对机器来说,就是对牛弹琴了,它没可能知道人类这些傻瓜坐在那里想做什么。
所以为了交流,我们需要让他们理解我们的意图,而你也不至于因此而去学牛说话,所以,我们需要用QuartusII,因为QuartusII就是帮助你进行这种翻译的工具。
我们分两部分来完成这么一件事情,首先把你的逻辑思路转变成用已经有的元件搭建出来的电路。
好比你说我要一个加法,器件没你那么聪敏,他不知道什么叫做加法,加法对他来说是没有意义的。
工具会把加法转换成为一组逻辑,用与,或,与非,或非这些乱七八糟的连在一起,变成和加法结果一样的电路。
这样器件一看就知道了,哦,对了,我有这些的。
当然这个时候你再去看那些东西,可能就蒙了。
这个过程就是综合。
综合结果是一个网表文件(netlist),也就是一堆很无聊的电路。
而这种电路还只是停留在概念上,并没有映射到实物上面。
然后工具会做第二件事情:
fitting。
QuartusII把你选择的器件找出来,对照它拥有的资源来放刚才转成的电路。
FPGA里面的资源都是现成已经做好的,好处是你不需要做,坏处是,你也改不了。
第一步首先是放置,就是把那些逻辑一个个放到器件的相应位置上。
最后,把所有的放置好的点连接起来。
这样,你的思想就在硬件上面完美的体现出来了。
然后我们再回过来看看每个点都在做什么,把这些信息存成一个文件,以后你只需要每次告诉器件这个文件,就可以实现你的设计。
这一切都不需要你来做,工具都可以自动完成,因为对器件世界的理解,工具比你要熟悉的多,所以你可以相信,他一定比你做的好。
但是这样是不是太容易了呢?
当然不会,否则就不好玩了,你需要知道工具去实现,因为很多事情是工具不晓得的,你需要告诉工具你的要求来实现你的设计。
这就是约束。
好像女孩子喜欢漂亮,当然不会随便穿戴,要点缀这里,束缚那里,让自己看上去至少很美。
打扮没有约束,可能顶多就是难看点。
但是翻译过程没有约束,就完全不是一个东西了。
所以,约束很重要,后果很严重。
你要告诉工具很多信息。
比如:
时钟信息,工具不可能聪明到知道你从外面送进来的时钟是多少的。
比如管脚信息,你要告诉他哪些输入,哪些是输出,而这些输入输出分别应该是什么样子的。
这些是最基本的信息,还可以提出一些更苛刻的要求出来。
比如说功耗。
QuartusII在完成编译以后会对编译的结果进行分析,看是不是能满足你的要求。
如果不满足,它可以再试几次。
最后告诉你:
帅哥,按照你的要求,我们完成了工作了,或者说,小子,你的要求是在太过分了,我做不了。
那么可能你得调整一下设计,代码,约束条件,甚至器件。
到此为止,其实QuartusII的工作已经可以说完成了。
但如果只是这样,你一定会很郁闷,因为你并不知道你的设计是不是真的可以工作。
或者说,你会想知道你的设计为什么不工作。
所以必须提供仿真和debug工具。
QuartusII提供一个相对比较简单的仿真工具,让你可以通过画波形图的方式来做仿真。
这种工具非常容易用,但是能力比较有限。
他可以很直白的实现激励和观察输出波形的平台,但是他无法实现很好的交互能力。
好比你需要因为一个信号而发动下一个动作时?
你恐怕很难猜得出来什么时候这个信号就来了吧。
所以很多时候,我们会比较喜欢用第三方工具ModelSim。
这个东西不好的地方就是你需要自己写仿真代码。
你会发现这是一件蛮痛苦的事情,很多时候仿真代码比电路代码本身还要复杂。
但是,真的没有办法,我很同情你,因为只有你才知道你想做什么,没有人能代替你来写仿真。
仿真毕竟只是仿真而已,不是真的,很多时候你会发现电路还是不能工作,虽然仿真看上去完全没问题。
千万不要太自信的以为这一定就是工具的bug,从而很兴高采烈的报告说,我找到你们一个bug。
绝大多数的情况下,要么是因为你的约束有问题,要么是因为你的仿真和真实情况不符合。
所以,QuartusII不得不提供一种途径,让你看到,芯片里面到底发生了一些什么事情,那就是在片上debug工具,signaltapII。
我知道名字不太好听,但是其实真的还蛮有用的。
QuartusII就是这样一个工具,很简单,但要玩得好,还是需要一点功夫的。
后面我会比较细化的聊聊怎么玩这个东西。
我不会很老土的说怎么创建一个工具,然后按这里,按那里。
这些要你自己去玩,去摸索,否则,完全没有乐趣了。
门规
别担心,这里不是黑帮。
我喜欢把寄存器比喻为门。
所谓的电路就是由一堆这样的门包围着的。
每个门都有一个相应的时钟来驱动,在相同间隔后,门将会打开。
一些信号从一个门出来,经过一系列的变化(组合逻辑)变成一个新的信号,走到另一个门口,当门打开的时候,进入。
这就是FPGA里面发生的一切。
或许速度会快一些,或许情况会复杂一些,但是大体就是这么回事而已。
而我们要保证的就是所有的信号都可以高高兴兴来,安安全全回去。
不会迟到,也不会早退,更不会被门夹到,就万事大吉了。
但是事情容易说不容易做,所以需要注意一些细节方面的问题。
如果因为你把逻辑给做错了,那我们就不提了。
而有些事情,即使你感觉一切都做得足够完美了,却还是没有结果。
在这里提一些会有好处。
门规之组合电路篇
虽然我们要讨论的是门,但其实我们更关注的应该是门与门之间发生的一切。
因为门的作用只是把阶段和另一个阶段分割开来,而更多的事情,其实是在这个阶段里面做的。
门与门之间,或者门外面的,就都是这些组合电路了。
组合电路最终影响了你的时钟能够飙到多快。
1.进来的时候,请随手关门
这是一个再简单不过的规则。
在进来的时候,请关一下门。
相信如果你呆在一个有一部分没有被包围在墙和门里面的房子里,一定很没安全感。
尤其是在门外面的东西吧,你会整夜整夜的睡不着觉。
所以进来的时候,最好可以随手关门,把自己包围在一个安全的环境里面。
所以信号也是这样,信号是很敏感很没安全感的东西。
所以,进来的时候最好被时钟打一下。
这在FPGA设计中是非常重要的,尤其是复位信号。
外部信号的触发事件是随机的,连它自己都不晓得什么时候那个reset键就被按了一下,加上进来以后的线路会有一点延迟,恰好在时钟触发的时候,前面一个信号被触发了,后一个信号恰好被门夹到。
就好像指挥抬手的时候,钢琴开始弹奏了,小提琴手还在摆pose。
这样导致的结果就是大家不是同时开始工作。
门分很多种,材质不一样(时钟频率),大小不一样(时钟相位),还有很多属性不同(全局时钟?
)。
所以为了进入不同的区域,你必须关一下相应的门。
这其实很容易理解,你进厨房,关厕所的门,就有点奇怪了。
还是以复位信号为例,对所有你需要用到复位信号的时钟域,最好可以被相应的时钟打一下。
提出这样一点,是因为它经常被忽略,而且发生问题的状况可能变成随机的。
如果你的设计仿真没有问题,而在板子上发生一些随机的事件,那么很有可能是你的异步信号造成的。
2.在门与门之间请不要来回走动
门(寄存器)与门之间是什么?
是组合逻辑电路。
信号的传递就是不断的打开一个门,然后进入另外一个门,这样一级一级的不断传递,你才可以一直从起点走到终点。
在有些时候也许你并没有注意,你在到达另外一个门之前,你转了一个圈又回来了。
虽然这只是一个简单的圈,但是这个动作会被无限循环,因为这个动作没有被时钟限制。
所以导致的后果可想而知了。
举一个最简单的例子:
D=A+B+C;
RegC=D+B;
A和B都是输入,而C是输出,你会发现其实这个C偷偷的回去转了一圈,而结果是使自己又多做了几次循环。
而最终结果是多少要看这段逻辑自身的延迟和你的时钟频率,对不起,谁都不可能预测结果。
而且每次编译的结果都会不同,因为编译导致的电路延迟是随机的。
但是如果我们把D也用门关一下(寄存器),那么结果就会舒服了。
RegD=A+B+C;
RegC=D+B;
不妨在QuartusII里面尝试这两种电路。
工具会报告一个combinationalloop的警告给你。
也可以尝试做一些仿真体会一下。
3.不要为了省钱,用假门(LatchVsRegister)
让我们把这个门再好好的研究一下,首先是定义。
我这里说的门更多是flip-flopregister.作为现成的资源,它遍布于器件的四面八方。
另外有一种叫Latch的东西,我把它叫做假门。
在普通数字电路中,人们会喜欢用到它。
因为它的结构相对简单,所以资源上比较节约。
所以我们需要说说这个假门的问题。
那么首先需要了解一下什么是假门,其实就是一个偷工减料的门。
我们来看一个简单的图:
这确实是一个再简单不过的逻辑了,比flip-flop的那个寄存器要简单许多。
当gate为高的时候,Q变成D,否则,就保持Q的值。
很显然这是一个用电平来保存数据的一个逻辑,但是为什么我们不喜欢它呢?
1.不稳定,和flip-flop做一个比较,register是在开门的时候数据进去的,然后这个门马上就关掉了,所以数据只要在开门的前后保持稳定,那么从输出看都是可以保持一致的。
但是Latch的结构中,当Gate为高的时候,Q的数据会随着D的变化而变化。
所以他无法保持一个稳定的状态。
2.它给工具制造了麻烦。
因为电路是由你设计的,工具并无法知道你的思路,所以他不会知道你想要的到底是什么时候的输入。
因为你现在门是一直那么开着的。
在这过程中,狐狸也来过了,狼也来过了,老鼠也来过了,工具不知道究竟以什么为标准来判断这个电路是不是能符合时序要求。
这样的话,或许你会很幸运的在一颗片子上面完成任务。
但是一旦换一颗,情况就变了。
3.最后,作为一个精打细算的人,我们需要知道他是不是真的就省了那些传说中的资源了。
大家不妨自己做一个Latch出来(QuartusII的megacore中是可以找到LPM_LATCH的)。
然后把它编译一下出来看看。
你会发现事实上你根本找不到这样的一个电路(Resourcepropertyeditor)你只能看到这样一个有点庞大的图:
真是不划算,你发现其实整个查找表都给用上了。
而后面一个简简单单的register可怜巴巴的放在那里用不到。
作为FPGA设计中比较独特的一个原则就是,这个世界不是你创造的,所以你必须去适应它,而不是顽固自己的意图。
换句话说:
坏人也是人,不是说你不能做,但都已经告诉你坏人不好了,你干嘛还要去做呢?
留一个问题给大家去尝试,或者玩一下。
什么状况下,或者说怎么写代码的时候,可以把Latch写出来。
4.除了门,其他的一切过程都只是暂时的
在FPGA中,除了门与门之间的延迟是固定的(时钟频率)外,一切的组合电路的延迟都是不确定的。
你不能依靠一次编译的延迟结果来做你的设计,虽然这样看上去的效率会非常高。
就好像接力跑一样,可以一棒一棒的传下去。
但是电路是需要可以不断重复的一个过程。
相信每次接力跑交棒的时间点都是不同的吧,你再做一次编译以后,你会发现整个世界都变了。
所以在设计中,尽量避免使用这种手段。
延迟链,经常会使用这种手段,比如几级非门来增加延迟。
但是它也是具有不稳定性的,所以在不到万不得已的状况下,不要用它来增加认为的延迟。
延迟链在ASIC中另外一种用途是增加扇出。
而这在FPGA设计中是画蛇添足了。
因为布线资源中已经加入了buffer了。
记住这样一个规律就好了,凡是没有被门关过的信号都是不稳定的,都只是暂时的。
门规之时钟篇
门本身没什么复杂的地方,但是门的种类一多,麻烦就来了。
而好玩的地方也来了。
所以我们对门(主要是时钟)的选择就会有很多讲究。
好像厨房应该配什么门,卧室配什么门?
对于门的属性把握也影响到你知道工具工作的准确性。
如果你给工具的信息本身就不是符合事实的话,那么结果一定是不堪的。
所以,我们需要对门,提醒一些门规。
1.再生门
很多时候我们不得不用一些逻辑的结果作为时钟去驱动一个门,我们且管他叫作再生门吧,这种门所造成的问题是最多不过的,因为有一些先天不足。
所以我们把力气主要多的放在这里。
首先这些门的驱动时钟是由组合电路组成的,还记得之前的规则么?
所有的组合电路都是不可信的。
是的,往往有很多的毛刺啊,或者中间过程啊不可避免的出现,这当然不是我们想要的东西。
所以,在生成新的再生门之前,你最好把这个时钟信号用原来的那种门在关一下。
这样你获得的会是一个干净的,纯粹的时钟信号。
2.门之相关
再生门也可以分成两种,一种是锁相环所产生的时钟驱动的门。
另一种是你用逻辑搭建出来的时钟。
就好像有的门是工厂制作的,有的门是你自己劈木头造出来的,工厂造出来的驱动门会比较准确,效果比较好,可以省掉你很多麻烦,所以很多时候我们还是推荐用这种门。
而且因为是工厂制造,所以工厂对这种驱动的属性,状态会非常清楚,所以在分析的时候,会自动获得很多信息,而不需要你来提供。
但是有的时候,你或许不得不自己造一个门。
那么这个时候你就需要比较细心的呵护一下。
首先就是刚才说的毛刺问题,然后就是相关性问题。
你需要告诉工具你造的这个门和原始的那个门的关系。
好比时钟频率,相位。
工具是很蠢的,它没可能了解高级生物的语言,所以你必须告诉它。
所以再生门与原始门之相关性会非常重要(derivedclock)
3.门锁(gatedclock)
门当然应该可以上锁,就是可以把时钟停掉,那么门就不会被打开了。
而最大的好处是什么?
对了,就是省电。
门不会一直开来关去的,信号也不会频繁的翻上坠下的。
对芯片电力的贡献可是相当大了。
但是同时也带来很多问题,主要是时钟的不稳定性增强了。
最最简单的做法就是把门锁信号和时钟与一下。
但是这样的组合电路通过了查找表以后的驱动能力降低了,导致了时钟从这一点到另一点的传输延迟变长了。
另外你的门锁信号上面可能本身带有毛刺,那么可能反映到时钟上,那结果就不得了了。
你可能不小心就被门夹扁了。
针对新的一些器件,器件本身可以提供一些时钟控制模块,当你需要使用门锁的时候,尽量的使用这些模块,会让你的时钟变得安全(clockcontrolblock)。
或许你会说,我并不是太在乎是不是省电,我只是希望这一块地方不需要因为新的数据而变化,等于是把功能停掉。
那么这样的话,你可以不需要去控制你的时钟,而选择控制你的数据。
让你的门锁来选择进去的是你刚才已经进去的信号,还是新的信号。
想象一下,如果反复进去的都是刚才的信号,那么你的电路大部分情况下是不太会有变化的。
这当然不是绝对的。
但是这可以作为一种方法来避免不安全感。
当然总会有万不得已无奈的时候,好比老板脑袋被门夹到了。
你不得不使用逻辑电路来锁门,而你的器件又没有特定的模块。
那么最好的情况就是,你可以先用那个时钟,把你的门锁信号关一下。
这样的好处就是可以把毛刺信号完全的规避在门外面,使你的时钟更加安全。
好了,好了,先就说这些好了,再说下去恐怕会因为门规太多,很多人要倒戈投降了。
这些是比较容易被忽略的地方而已。
如果还有什么补充,也可以一起交流一下。
你的Q-zone,你做不了主
我的地盘我做主,这其实是一句鬼话。
你很少真的有什么地盘你可以做主的,因为你很难作为规则制造者存在。
你只有更好的依循规则,你才能更好的让事情按照你的想法去做。
所以为了做主你的地盘,你最好依照一些规则,而不是按照自己的喜好来做,好比写代码。
上电初始值
在通常的状况下,所有的门在上电的时候输出为低。
但是这并不是不能改变的。
你可以把上电设置为高,这样综合工具可能会做两种事情,把输出反向,或者使用preset控制(如果存在的话)把初始值放进门里。
当时上电为高的做法,并不是非常必要,因为你其实是可以使用复位信号来获得你想要的初始状态的。
如果你觉得这是必须的,那么有几种方法你可以做:
1.首先是在QuartusII里面你可以针对某个或者某些门设置power-uplevel为高或低。
2.在代码中使用altera_attribute。
3.直接写代码设置初始值:
regq=1'b1;
always@(posedgeclkorposedgeaclr)
begin
if(aclr)
q<=1'b0;
else
q<=d;
end
门的次级管理信号
每个门都有一些次级的管理装置,好比清除信号啊,时钟使能信号啊。
而这些装置当然都有他们自己的操作规律。
如果你在写代码的时候可能适当的使用它们,那么综合的时候很容易就可以使得王八看到绿豆,大家都对上了。
其实实现一个功能是没有问题的,但是如果你把功能按照它的自然规律来实现,从资源消耗还是很划算的。
当然我知道大家现在都很有钱,不太在乎这些的,但是省吃俭用似乎还是硬件设计师德传统美德。
你会发现年资越大的工程师在这方面越是注意,所以,如果你希望在别人眼里看上去比较牛的话,适当的使用这种手段,还是蛮炫的。
我们把这些信号按照优先级排列一下(不知道什么是优先级?
找本字典先)
1.异步清零信号–aclr
2.上电复位信号,-pre
3.异步载入信号–aload
4.使能信号–ena
5.同步清零信号–sclr
6.同步载入信号–sload7.数据输入信号–data
我建议大家可以尝试自己用这些信号来做一个门出来看看,尝试怎么可以使用这些信号。
然后使用quartus来编译验证自己的结果。
这是一种非常有趣的玩法。
首先,它可以使你对器件的结构更加了解,同时也锻炼了你写代码的能力。
一