第一篇:用verilog 进行FPGA设计阶段总结
用verilog 进行FPGA设计第一阶段总结
2007-08-23 21:34
实习期间,老师叫我们做他的大课题中的一个小部分。这个部分主要是将A/D采集的数字信号利用一个函数进行插值恢复,以便后面的作图中使用。要求在每两个点中间均匀插入九个点,每个点与其前后80个点有关,用verilog语言描述,在xilinx公司的开发环境ISE下完成。
对于verilog我们没有接触过,以前的课程设计都用的是VHDL,ISE也没用过,以前用的是Maxplus2开发环境,于是我们就从网上下载了一些教程开始学习。在熟悉了verilog的语法和ISE之后,我们开始了设计。思路是这样的:将要处理的数据先存在一个存储器中,然后每进来一个新的数据,所有的数据向前移动一个寄存器,在主时钟十分频之后的每个上升沿读取新的数据进来,然后计算插值,然后在每个主时钟的上升沿处输出插值后的数据,这样就能实现插值的过程了。
在具体的编写程序的时候,我们先用与每个插值点前后4个点有关进行设计,设计好之后再进行扩展。对于插值的计算我们先不考虑,将其全部设置成常量,主要考虑看能否在两个点之间插值成功,这样的程序就简单多了。很快我们的程序就写好了,编译仿真之后能实现插值。接下来就是主要考虑插值的计算问题了,在这个部分我们走了一些弯路。
首先是乘法问题,这个课题相当于是一个FIR滤波器,其中要进行约720次的相乘累加,我们看资料书和一些发表的论文,上面好多都考虑用分布式算法DA来实现,但是要是考虑的点多了,这种方法就不可行了,因为那个表会造的很大。在书上,我也没有看到直接用乘号来进行乘法运算的,大部分都是进行移位相加的,为此还认真的研究了一下乘法的原理。到最后,老师说你可以直接用乘号的,不要管那些移位什么的,这些是综合器做的事情。
其次是verilog中有符号数的计算问题。因为是新接触,不知道怎么做。为了实现2*(-3)=-6,搞到了半夜两点。我记得计算机组织与结构里面有一章是关于乘法的,里面讲的是用布斯算法,看了半天,觉得在程序中这样实现太麻烦,肯定有更简单的方法。最后在百度里知道只要在声明的时候加个signed就行了。
再次是数据宽度问题,两个8位的数据相乘后应给16位宽度,在加8位的宽度就可以进行256次相乘累加。在原码表示中,数据从低的宽度到高的宽度时,符号为移到最左边,其余空位用0来填充;在补码表示时则是符号位移到最左边,其余各位用相应的符号位填充。
庆幸的是,我们利用简单的C语言程序就将复杂的权值计算出来了,省了好多的时间,深切的体会到了计算机的好处。
这些都做好之后,我们在一次仿真,结果令我们高兴,但又令我们苦恼。因为出来的结果有一半是正确的,与我们用C语言插值的结果一样,另一半却是
随后两个点插值的一半。能计算出一半,就证明程序计算部分没有错,我们给的权值也正确,那是哪里错了呢?分析了半天之后,我们找出了这个规律,觉得是计算花的时间太长,导致还没计算完9个插值就有新的数据进来参与了随后的计算,其实是由于计算和输出是并行的,计算出来的结果没有经过缓冲就直接输出,这样由于计算第一个插值和输出第一个插值不同步,这样使得在还没有输出结束时,新的插值覆盖了原来的插值,最后我们在计算和输出之间加了个缓冲器就好了。
老师看了结果后比较满意,接下来就要下载到具体的芯片上进行调试,看是否正确。我们到这一步还只是行为级的仿真,接下来的综合和下载到器件上调试将会遇到更多的困难。相信通过我们的努力,这些困难将会成为我们以后成功路上的垫脚石。
用verilog 进行FPGA设计第二阶段总结
2007-08-31 17:37
第一阶段的行为仿真完成之后,我们开始进行第二阶段的综合和实现。在双击综合按钮之后,我感觉出问题了,这么个小程序,综合了十来分钟还没完成,出现了“no possible choice”字样,再看看用到的硬件资源,16*8的乘法器326个,锁存器891个,很吓人的,并且出现了加权值寄存器没有初值的警告。我想这种方法是行不通的,肯定得找更好的办法。
因为放加权值的寄存器的值是不变的,所以可以用一个rom来实现。然后就立即找有关rom使用的资料,很快就学会了调用ISE自带的rom,并且也赋79了正确的初值给rom,我们把rom模块放在程序中进行综合的时候,令我们惊喜的事情发生了,乘法器一下子成了79个,锁存器也减少到了361个。但是我们进行功能仿真的结果却不正确,始终都是同一个值,似乎修改程序对输出的结果都没有影响。问题出在什么地方呢?我们开始排除错误,算法是正确的,因为在前一阶段用寄存器的时候仿真已经是正确的了,是rom的原因吗,好像也不是,因为我编写小程序测试的时候用我的方法是可以读出rom的值的,那到底是错在哪里?出来的结果不是我们预料的,这个问题我想了好几天,寄存器的方法是不能用的,必须用rom,但rom的问题在什么地方呢,试着修改程序,然后调试,但是就是没有结果出来,有时候都有种崩溃的感觉,但是我坚信,rom是可行的,并且有解决的办法,我们离成功只有一步。
我把rom的测试程序改的稍微复杂点,带个for循环,然后让它输出。问题暴露出来了,for循环的结果老是我给的最后一个地址的值,不论我用时钟触发或者不用。我开始以为是for循环中的变量不能读出rom,后来终于明白是由于for循环太快,每次都会将前一个读出来的值覆盖掉,所以最后出来的值老是最后一个。但是,不用for循环的话,那我们的程序该怎样设计呢?80个相乘累加要进行9次,如果一个一个搞,岂不累死人,写出来的程序肯定不行。还是得用for循环,这样在寻找for循环中使用rom的过程中,两天又过去了,而且没有什么结果,因为我能求助的人基本上都对这个不熟悉。
黄天不负有心人,我终于找到了解决的办法,在一本教材上面。用if语句在时钟的触发下来实现for循环,这样就可以了。不到半天的时间我们的程
序就可以仿真出来结果了,并且综合也通过,不会出现“no possible choice”消息,乘法器也没有了,用的资源很少,综合的时候30秒就可以完成,如果机器好的话。现在出来的结果跟我们先前的结果是一样的,真的很令人激动。在一个多星期的时间里,我们主要就解决了在怎样让rom循环的问题。俗话说:靠天靠地不如靠自己,我部分认同这个观点,当所有可以获得帮助的途径都没有用的时候,我们选择了自立更生。虽然最后也取得了效果,得到的知识也很深刻,但是我感觉付出的代价是在是大了点,好几天的功夫就面对这样一个问题,而这个问题属于经验性质的,用过之后以后就知道了,要是有个高手在旁边说一句话的话,估计半天就能解决问题了。
可能这就是生活,什么事情只有自己体会了才知道。
第二篇:本科毕业设计阶段总结
本科毕业设计阶段总结
毕业设计从开题至今,已经近两个月了。在这段时间里,通过跟随老师一起做实验,和同学、老师一起讨论课题,自己不仅学到了许多关于实验本身的知识,更受到了老师思考问题、解决问题等思维方式的影响,收获很多。现在我就毕业设计开题以来的实验(工作)进行一些总结,在总结实验的同时,也能思考过程中出现的问题,进行一些方案的修正,以保证毕业设计更加顺利的进行。总结主要从配方设计、实验过程、两个方面进行:
1、配方设计过程中,确定用溶胶-凝胶法制备含有光敏基(丙烯酰氧基)的液态紫外光固化氟硅树脂。溶胶-凝胶法就是用含高化学活性组分的化合物作前驱体,在液相下将这些原料均匀混合,并进行水解、缩合化学反应,在溶液中形成稳定的透明溶胶体系,溶胶经陈化胶粒间缓慢聚合,形成三维空间网络结构的凝胶,凝胶网络间充满了失去流动性的溶剂,形成凝胶。凝胶经过干燥、烧结固化制备出分子乃至纳米亚结构的材料。这样可以在不改变有机硅材料原有优异性能的基础上,引入含氟基团使得氟改性有机硅材料具有较强的疏水性和较低的表面张力,改善材料的耐油、耐溶剂、防污等性能,拓宽有机硅材料的应用领域。而通过改变含氟单体的量,可以找出最好性能比下的氟硅树脂。
2、实验过程。在实验的过程中发现采用NaOH做中和剂不会控制pH值到7,然后采用NaHCO3来作为中和剂,可以温和的达到7的pH值。在采用无水硫酸钠做干燥剂的时候,因为它为颗粒状,干燥的效果不好很好,然后商讨决定采用无水硫酸镁来做为干燥剂,因为它是粉末状的,可以更充分的接触吸收水分。这些问题都是要在实验之中才可以发现,然后再加以改进的,所以在实验中也可以学到很多东西以及经验。
以上就是这段时间以来相关实验工作的小结,而接下来的时间,就是要对产品进行各项的性能测试,然后工作的重心将放在进一步地掌握相关测试技术的原理,从而去分析实验数据,并掇写毕业论文,准备答辩。
吴毓
二〇一二年二月二十三日
第三篇:学习verilog后的总结
关于这个学期学习verilog hdl语言后的小结
在完成本次verilog大作业的过程中,我不仅学到了很多只靠看书本学不到的知识,而且体会到了团队协作的力量,在团队成员的合作下,经历了不少困难,终于完成了verilog的大作业,虽然过程并不是和想象中的一样,而且作业也与老师要求的有点差距,但是从中学习到了许多关于verilog的使用与仿真的基础知识,也对课上学到的语句有了更深的理解,并将其应用到了实际工程中,使自己的运用能力得到了很好的锻炼,对基本操作已经较熟练的掌握,对其中一些细节问题,如仿真时间的选取等也有了自己的理解。实践出真知,通过在软件上反复改程序、跑程序我也学会了很多只看书本发现不了的问题,锻炼了自己的解决问题能力。这对于今后的学习是有很大的帮助的。以下做一下简要总结:
这次的大作业是通过我们小组四个同学共同努力下完成的,其中有很多收获也有很多感受。这次的大作业给了我们一次很好的锻炼机会,通过这次大作业,我开始熟悉用verilog设计的最基本的方法和流程,课堂上学到的东西只有自己通过应用才能加深自己的理解,课堂上学到的并不是全部,要想真正的学好这门课,只有在实践中运用才能真正的体会到这门课的精髓,这次的大作业很好的验证了。
有一个外因也是给了我们的帮助,那就是网络的强大,在这个信息的时代,互联网的作用显而易见,如果能够充分得利用网络上海量的信息,掌握一定的检索技巧,就可以获得很多有价值的东西,比如参考别人的算法和程序段,观看关于Quartus II软件的使用教程视频。这比起关起门来自己钻研要强上不少。对于如何使用verilog hdl写出可综合的代码真的是一件不容易的事情,而真正的可以写出可综合的代码确实还需要经过很长时间的锻炼。而对Quartus II的使用,感觉也只会得不多,还有很多功能诸如时序分析,逻辑分析,引脚分配等都不会使用。
在完成这次大作业的过程中充分感受到自己知识的不足以及学以致用的重要性,有很多不懂的地方,要通过不断的学习来提高自己,这正验证了学海无涯这句古话。这次的大作业是一次很好的实践。通过大家一起设计,大家都很有收获,不仅完成了作业,而且学到了知识,关键的是自己的自学能力有所提高,所以希望以后还有更多实践的机会,这对于我们的提高大有好处。
最后,我还得感谢我的队友们,这次作业的完成是我们共同努力的结果,我真正感受到了团队的力量,也体会到了老师为什么一定要求必须绝对完成的良苦用心。
11光电A1 朱
2014.01.01
第四篇:FPGA高手总结
一个FPGA高手的总结
很早之前就想对这几个月工作经历写的东西,一是作为自己的总结,二是自己也很想将自己这段时间的一些经历和大家分享一下,希望对初学者而言能使得他们能少走一些弯路。只是公司里的事情很多,最近经常加班,所以一直拖到现在。
能来到这家公司应该是一种缘份--缘起NIOS。当初三月份altera来我们学校建立SOPC实验室的时候自己还不知道NIOS是什么东西,只是想在altera的FAE讲完NIOS后多问他几个时序约束的问题,然后拷一份PPT回去。但是想不到因为那一份NIOS的培训资料,我认识了edacn上的cawan,他给我讲了很多NIOS的东西,之后是丁哥在SOC版帖了位NIOS大赛的通知,然后我和队友就去报了名,并去川大参加了NIOS的培训,认识了峻龙的FAE----也是我现在的boss。在这里要谢谢cawan、丁哥、和我一起参加NIOS竞赛的队友刘科以及我的BOSS,是他们让我有了这一段的经历。在公司里的几个月,做的项目其实不多,但是收获还是有一些,我觉得收获最大的是设计理念的改变,这也是我这段时间最想总结的,我会在后面逐渐阐述。
时序是设计出来的我的boss有在华为及峻龙工作的背景,自然就给我们讲了一些华为及altera做逻辑的一些东西,而我们的项目规范,也基本上是按华为的那一套去做。在工作这几个月中,给我感触最深的是华为的那句话:时序是设计出来的,不是仿出来的,更不是湊出来的。在我们公司,每一个项目都有很严格的评审,只有评审通过了,才能做下一步的工作。以做逻辑为例,并不是一上来就开始写代码,而是要先写总体设计方案和逻辑详细设计方案,要等这些方案评审通过,认为可行了,才能进行编码,一般来说这部分工作所占的时间要远大于编码的时间。总体方案主要是涉及模块划分,一级模块和二级模块的接口信号和时序(我们要求把接口信号的时序波形描述出来)以及将来如何测试设计。在这一级方案中,要保证在今后的设计中时序要收敛到一级模块(最后是在二级模块中)。什么意思呢?我们在做详细设计的时候,对于一些信号的时序肯定会做一些调整的,但是这种时序的调整最多只能波及到本一级模块,而不能影响到整个设计。记得以前在学校做设计的时候,由于不懂得设计时序,经常因为有一处信号的时序不满足,结果不得不将其它模块信号的时序也改一下,搞得人很郁闷。在逻辑详细设计方案这一级的时候,我们已经将各级模块的接口时序都设计出来了,各级模块内部是怎么实现的也基本上确定下来了。由于做到这一点,在编码的时候自然就很快了,最重要的是这样做后可以让设计会一直处于可控的状态,不会因为某一处的错误引起整个设计从头进行。做逻辑的难点在于系统结构设计和仿真验证刚去公司的时候BOSS就和我讲,做逻辑的难点不在于RTL级代码的设计,而在于系统结构设计和仿真验证方面。目前国内对可综合的设计强调的比较多,而对系统结构设计和仿真验证方面似乎还没有什么资料,这或许也从一个侧面反映了国内目前的设计水平还比较低下吧。
以前在学校的时候,总是觉得将RTL级代码做好就行了,仿真验证只是形式而已,所以对HDL的行为描述方面的语法不屑一顾,对testbench也一直不愿意去学--因为觉得画波形图方便;对于系统结构设计更是一点都不懂了。到了公司接触了些东西才发现完全不是这样。其实在国外,花在仿真验证上的时间和人力大概是花在RTL级代码上的两倍,现在仿真验证才是百万门级芯片设计的关键路径。仿真验证的难点主要在于怎么建模才能完全和准确地去验证设计的正确性(主要是提高代码覆盖),在这过程中,验证速度也是很重要的。验证说白了也就是怎么产生足够覆盖率的激励源,然后怎么去检测错误。我个人认为,在仿真验证中,最基本就是要做到验证的自动化。这也是为什么我们要写testbench的原因。在我现在的一个设计中,每次跑仿真都要一个小时左右(这其实算小设计)。由于画波形图无法做到验证自动化,如果用通过画波形图来仿真的话,一是画波形会画死(特别是对于算法
复杂的、输入呈统计分布的设计),二是看波形图要看死,三是检错率几乎为零。
那么怎么做到自动化呢?我个人的水平还很有限,只能简单地谈下BFM(bus function model,总线功能模型)。以做一个MAC的core为例(背板是PCI总线),那么我们需要一个MAC_BFM和PCI_BFM及PCI_BM(PCI behavior.model)。MAC_BFM的主要功能是产生以太网帧(激励源),随机的长度和帧头,内容也是随机的,在发送的同时也将其复制一份到PCI_BM中;PCI_BFM的功能则是仿PCI总线的行为,比如被测收到了一个正确帧后会向PCI总线发送一个请求,PCI_BFM则会去响应它,并将数据收进来;PCI_BM的主要功能是将MAC_BFM发送出来的东西与PCI_BFM接收到的东西做比较,由于它具有了MAC_BFM的发送信息和PCI_BFM的接收信息,只要设计合理,它总是可以自动地、完全地去测试被测是否工作正常,从而实现自动检测。华为在仿真验证方面估计在国内来说是做的比较好的,他们已建立起了比较好的验证平台,大部分与通信有关的BFM都做好了,听我朋友说,现在他们只需要将被测放在测试平台中,并配置好参数,就可以自动地检测被测功能的正确与否。在功能仿真做完后,由于我们做在是FPGA的设计,在设计时已经基本保证RTL级代码在综合结果和功能仿真结果的一致性,只要综合布局布线后的静态时序报告没有违反时序约束的警告,就可以下到板子上去调试了。事实上,在华为中兴,他们做FPGA的设计时也是不做时序仿真的,因为做时序仿真很花时间,且效果也不见得比看静态时序分析报告好。当然了,如果是ASIC的设计话,它们的仿真验证的工作量要大一些,在涉及到多时钟域的设计时,一般还是做后仿的。不过在做后仿之前,也一般会先用形式验证工具和通过静态时序分序报告去查看有没有违反设计要求的地方,这样做了之后,后仿的工作量可以小很多。
在HDL语言方面,国内语言很多人都在争论VHDL和verilog哪个好,其实我个人认为这并没有多大的意义,外面的大公司基本上都是用verilog在做RTL级的代码,所以还是建议大家尽量学verilog。在仿真方面,由于VHDL在行为级建模方面弱于verilog,用VHDL做仿真模型的很少,当然也不是说verilog就好,其实verilog在复杂的行为级建模方面的能力也是有限的,比如目前它还不支持数组。在一些复杂的算法设计中,需要高级语言做抽象才能描述出行为级模型。在国外,仿真建模很多都是用System C和E语言,用verilog的都算是很落后的了,国内华为的验证平台好像是用System C写。
在系统结构设计方面,由于我做的设计还不够大,还谈不上什么经验,只是觉得必须要具备一些计算机系统结构的知识才行。划分的首要依据是功能,之后是选择合适的总线结构、存储结构和处理器架构,通过系统结构划分要使各部分功能模块清晰,易于实现。这一部分我想过段时间有一点体会了再和大家分享,就先不误导大家了。
规范很重要
工作过的朋友肯定知道,公司里是很强调规范的,特别是对于大的设计(无论软件还是硬件),不按照规范走几乎是不可实现的。逻辑设计也是这样:如果不按规范做的话,过一个月后调试时发现有错,回头再看自己写的代码,估计很多信号功能都忘了,更不要说检错了;如果一个项目做了一半一个人走了,接班的估计得从头开始设计;如果需要在原来的版本基础上增加新功能,很可能也得从头来过,很难做到设计的可重用性。
在逻辑方面,我觉得比较重要的规范有这些:
1.设计必须文档化。要将设计思路,详细实现等写入文档,然后经过严格评审通过后才能进行下一步的工作。这样做乍看起来很花时间,但是从整个项目过程来看,绝对要比一上来就写代码要节约时间,且这种做法可以使项目处于可控、可实现的状态。
2.代码规范。
a.设计要参数化。比如一开始的设计时钟周期是30ns,复位周期是5个时钟周期,我们可以这么写:
重
parameter CLK_PERIOD = 30;parameter RST_MUL_TIME = 5;parameter RST_TIME = RST_MUL_TIME * CLK_PERIOD;...rst_n = 1'b0;# RST_TIME rst_n = 1'b1;...# CLK_PERIOD/2 clk <= ~clk;如果在另一个设计中的时钟是40ns,复位周期不变,我们只需对CLK_PERIOD进行新例化就行了,从而使得代码更加易于重用。b.信号命名要规范化。1)信号名一律小写,参数用大写。2)对于低电平有效的信号结尾要用_n标记,如rst_n。3)端口
第五篇:FPGA程序总结
1流水灯程序
module ww(clk,led,rst);
input clk,rst;
output [3:0]led;
reg [3:0]led;
reg [24:0] cnt;
always@(posedge clk or negedge rst)
begin
if(!rst)cnt<=25'd0;
else
begin
if(cnt==25'd24999999)cnt<=25'd0;
else cnt<=cnt+25'd1;
end
end
通过cnt对时钟的计数实现0.5s定时。设输入时钟是50M always@(posedge clk or negedge rst)
begin
if(!rst)led<=4'b1111;
else
begin
if(cnt==25'd24999999)
begin
led<=led<<1;
if(led==4'b0000)led<=4'b1111;
end
else led<=led;
end
end endmodule
学会计数判断实现定时,和移位的使用
将第二个always改为下面的,就是跑马灯了。(相当向左循环移位)always@(posedge clk or negedge rst)
begin
if(!rst)led<=4'b0101;
else
begin
if(cnt==25'd24999999)
led<={led[2:0],led[3]};
else led<=led;
end
end
2共阴数码管
3FH,06H,5BH,4FH,66H,6DH,7DH,07H[0-7]7FH,6FH ,77H,7CH,39H,5EH,79H,71H[8-F]注意:easyfpga板独立的2个数码管是共阴的,断码8位顺序:dp,g,f,e,d,c,b,a//dp在高位 0—F显示 输入时钟50M
module ww(clk,seg,wei,rst);
input clk,rst;
output [7:0]seg;
output [1:0]wei;
reg [7:0]seg;
reg [3:0]dat;reg [25:0] cnt;
always@(posedge clk or negedge rst)//1秒定时 begin
if(!rst)cnt<=26'd0;
else
begin
if(cnt==26'd49999999)cnt<=26'd0;else cnt<=cnt+26'd1;
end
end
always@(posedge clk or negedge rst)begin
if(!rst)dat<=4'b0000;
else
begin
if(cnt==26'd49999999)begin
dat<=dat+1'b1;
if(dat==4'hf)dat<=0;end
end
always@(dat)
begin
case(dat)
4'h0:seg=8'h3f;
4'h1:seg=8'h06;
4'h2:seg=8'h5b;else dat<=dat;end
4'h3:seg=8'h4f;4'h4:seg=8'h66;4'h5:seg=8'h6d;4'h6:seg=8'h7d;4'h7:seg=8'h07;4'h8:seg=8'h7f;4'h9:seg=8'h6f;4'ha:seg=8'h77;4'hb:seg=8'h7c;4'hc:seg=8'h39;4'hd:seg=8'h5e;4'he:seg=8'h79;4'hf:seg=8'h71;endcase end
assign wei=2'b00;endmodule