作者前言:我学习FPGA是因为公司需要,同时自己也想接触这方面的知识,在大规模、高速信号领域还是有一定的优势,总而言之出于共赢的想法吧。自学的话,因为我是会跟着项目学习的,所以就是用到哪部分再去补充哪部分的知识。我的思路是先把基础的语法熟悉,数电和信号处理的知识再扎实一下,同时了解下FPGA代码的规范写法,至于开发工具的话就先大体了解下流程操作,应用的时候再逐渐熟悉。然后在实践中提高实际设计的能力。
可能有些是在校自学的,那么我觉得手头宽裕的可以买块开发板来练习效果会更直观,不宽裕的话找学校从事这方面的老师去当个助理,或者在外实习,都是可行的步骤。另外就是坚持(自古以来说的容易做的难)。
从零开始大战FPGA——第一天(盲人摸象)
之前一直接触ARM,单片机多一些,大多是裸机开发,由于公司需要FPGA这块的工作,只好硬着头皮去学。哎,真是什么都是被逼出来的,我的兴趣本来是想走偏软一点的方向的,现在看来,又远了一步啦,只好有时间了再慢慢学习。打算把每天学习的内容记下来,希望一方面能鞭策自己,另一方面也是将来可以回顾下当初走的路。
由于是个人学习记录,难免有错误之处,望各位看到的亲们可以指正、共勉!
FPGA第一天:
首先,知道了什么叫FPGA(不要鄙视我,虽然我本科时也有集电路和cpld这些课,但纯粹是混过来的,老师名字都不知道-。-),FPGA就是现场可编程门阵列,在我的理解看来就是FPGA里面有非常多的逻辑单元,几十几百万门,然后以编程的手段让这些逻辑单元组成各种各样的电路,实现指定的功能。
了解了FPGA的基本概念后就开始看 Verilog了,(Verilog跟C语言有点像,看起来比较容易,在亚洲用的比较多,也比较灵活。VHDL语法更严谨,美国军方开发的,不好入门,但是可以自定义类型等等,不是很熟悉,在欧洲美洲用的多些?不太确定)公司是做军品的,后期可能需要学习VHDL想想头都大的一B=。=
抱着书,看了一整天,看完了语法部分,了解了基本数据类型,运算符,语法等等。有以下几点感触:
Verilog本质还是硬件操作。C语言是顺序进行的,Verilog是并行的,这点很重要!
Verilog的精髓感觉是模块化思想(废话,其实所有语言都是模块化...)
wire型变量和reg变量这两个区分比较蛋疼,现在是记住了,但是并没有理解透(太理论了,需要在实践中区分啊,妈蛋)
initial,assign,always,这几个也有点绕哈哈。
然后看了ISE这个软件的使用(用的片子是Xilinx的多些),一句话,比较繁琐,功能强劲。。。
说说这个软件的流程吧,看了好久才理解的,首先设计大体框架,然后代码编写,然后代码编仿真,然后仿真,仿真完以后把编好的代码整成一张网表,然后用这张网表映射到FPGA的电路上去,然会就会神奇的由代码变成了硬件电路(好伟大啊是吧),然后就是各种约束规则,布线布局。再然后就是再仿真,这个仿真是真实反映实际电路的,再再然后就可以把代码下载到片子啦。
这是我自己的理解和总结,人家官方给每个步骤起了个好听的名字:什么设计文档、仿真、综合、实现、布局布线、仿真、下载,很绕口,反正了解这个软件怎么用就行了,我这只是刚刚接触,根本没有仔细了解其功能,待日后发掘之!
好吧,今天的FPGA就看了这么多,效率不是很高,关键是手头还有其他任务,是关于IC卡的,13.56Mhz的数据收发,头疼,芯片手册看半天也没看懂,明天继续,欢迎大牛们提出宝贵的学习建议,欢迎小牛们指正错误之处,欢迎渣渣们共勉哈哈!
从零开始大战FPGA——第二天(朝花夕拾)
夜深人静的时候最适合总结和学习新东西了有木有啊,嘿嘿。FPGA之旅的第二天,走你! 今天看的东西不是特别多,主要是公司还有其他活要干(说点小感悟:公司是给你钱让你产生效益的,而学校是你花钱买教育的,这是我看来本质的区别,后来者一定要转变好心态和思维),但是学习还得继续。废话结束!
回顾:昨天主要看了一些基本的语法(我是以夏宇闻的书为参考书,其他的用到时再去拓展),首先复习吧(年纪大了一下就忘了)。
wire和reg的区别(自己的理解,望大牛批评指正):从仿真角度看,wire对应的连续的赋值,比如assign;reg对应过程赋值,比如always、initial;从综合的角度来看,要对应实际的电路,wire综合出来的结果就是一根导线,就起连接作用。reg比如在always中综合的结果就是逻辑电路,比如or、and这些门电路,没有时钟的边沿。另一个结果是带有时钟边沿的,综合出来就是带时序的逻辑,比如触发器这种。
还有,一个模块在输入的时候,我应该不知道上级的输出是什么,那么对本模块来说,他就是一根导线,也就是wire型,输出则由我决定是wire还是 reg。一般而言,整个设计的外部模块输出,也就是最顶层,要求是寄存器输出,reg,较稳定,扇出能力也好(这句话不理解妈蛋)。
例子来啦:
一:
reg a,b;
wire and_result;
...
assign and_result =a&&b;
你可以试试把wire定义成reg。综合器会报错。
二:
wire按照国外的教材上面的定义:
wire为无逻辑连线。只做连线,wire本身是不带逻辑性的,所以输入什么输出就是什么。所以你尝试着用always语句对wire变量赋值。综合器就会报错。
那么你可能会问。assign and_result =a&&b不是就是对wire的赋值吗?
其实并非如此。综合器综合时将a&&b综合成ab经过一个与门。而and_result只是连接到与门输出的线。正真综合出与门的是&&。而不是result,是不是有点神奇啊哈哈。
好了,复习到此结束。
今天主要看的还是Verilog的基本知识:Task和Function的基本知识,一个是任务,一个是函数,跟C语言有点像。需要注意的是,函数和主模块共用仿真单位时间,任务可以自定义仿真时间单位;函数要有返回值,任务木有,而是通过输出端口输出(有点绕,不过一看书上的例子就懂了)
接着看了一下有限状态机,格雷码、独热码的概念,对着书上的例子,看了下计数器、移位寄存器、触发器等等的Verilog代码,感觉代码还是挺好看懂的,但是自己动手写起来有点困难,所以还是多动手,最最简单的例子自己写起来感觉到处是问题(用我们那的方言就是:眼眼巧,手手拙)哈哈。
由于是个学渣,当初的数电也是皮毛,连基本的触发器,状态机,卡诺图都忘得一干二净,所以又回头看了半天数电(突出一个囧),感觉这些基本电路设计的代码倒是好看,但是对电路硬件本身不是很熟悉的话,心里特不踏实。一句话,用到啥看啥,没必要从头翻,毕竟时间有限啊。
今天就看了这么点知识,然后跑了简单的例子(不得不说,FPGA综合和布线咋就这么慢呢?听同事说大点的项目光是逻辑综合、布局布线都要花十几个小时,我在心里默念,I am too young too simple)。
为什么叫朝花夕拾呢?因为当初丢掉的数电知识需要拾起来呀。
现在主要在想,FPGA内部没有像单片机,arm 那些逻辑处理单元,和运算的东西,怎么去实现一个比如像串口啊、IIC、USB、AD、网络这些功能呢,抱着这些疑问,先去休息了哈哈。明天打算直接看实例项目代码——AD采集卡,看看怎么实现的。到时候再写点总结(希望能看懂),当然代码是不会贴出来的(保密嘛,职业操守还是要有的嘿嘿)。
从零开始大战FPGA——第三天(管中窥豹)
上周搬家,家里的网络刚刚修好,更新耽搁了很久啊,接下来继续FPGA从零前进,走你。
上次说要看FPGA的AD采集卡实例。
在看了Verilog的基本语法后,就开始迫不及待的想看看实例怎么应用的。打开工程后傻眼了,这个project是用VHDL编写的而不是我前段时间看的Verilog啊。。。无奈,只好找了一本VHDL的电子书看一看,这次我是直接看的代码,遇到不认识的标识符,语法等等,就回去看电子书。所以效率非常低,这就是所谓的空中楼阁啊。(还是不建议像我一样的初学者刚开始就看两种语言,大牛除外,先把基本的设计思想,代码是怎么跑的这些搞懂,语言的话只是工具,当你了解了FPGA具体在干什么的时候,再来挑选所需语言)
在了解了每一行的代码的意思后,又回过头来看这个工程,还是看不懂(不能用学单片机、ARM的思维去学FPGA),以前跑AD在单片机或者ARM上调用一下库函数就OK,根本不理会什么时序的东西,现在发现走不通。
调整了下思维,FPGA的设计是非常模块化的感觉,那就先搞懂每个模块的用途。
这个AD片子是个50MSPS,14位8通道的一个小东西。然后大体看了下datasheet的时序图和引脚定义。大体包含了模拟输入,数字输出,时钟(由FPGA提供),数据输出时钟(用来读取采样的数据),帧数据输出时钟(也就是输出1帧1帧的数据,也就是14位),串行时钟和数据。
这时候就有点了解了,工程里先进行最顶层模块的的设计(VHDL用实体entity这么个关键词,我表示快混淆概念了啊-。-),主要是端口的说明,也就是与AD片子的接口,时钟(各种时钟)、8路数据输入等等,反正这个就对应了与AD的接口关系。
可以把实体这部分看做一个系统的大方框,主要用来定义方框与外设的接口,相当于main函数。(都是个人理解,仅供参考,欢迎指正)
接下来是结构体的定义(用来说明实体这个大方框中的东西具体怎么工作的)。
包含这么几部分:
1:信号说明
2:元器件定义
3:进程(逻辑关系说明)
4:元器件例化(感觉元器件就像定义了有个水果,这个例化具体说明这个水果是叫什么名字,苹果、桃子等等)
over,整体框架就出来了,主要是FPGA和AD的接口对应关系,还有顶层的逻辑关系(选择读取哪个通道的数据)
然后就纳闷了,这就能控制AD读取数据了?什么时候读取AD采样的值?什么时候把每一帧数据读过来?当然不够。
所以,就有了下面的步骤:
再单独写一个文件,把每个通道看做一个单独的AD元件,再写一个小框架,并把每个小框架的端口对应到大框架中的那个元件的端口。
然后再这个小框架中就可以定义逻辑电路了,对着AD时序图,比如在数据时钟上升沿采集数据等等。
从大到小,一步一步定义模块。
最后编写一个约束文件,把定义的端口,映射到FPGA管脚上。
总结下:
就像C程序中的多文件一样,main函数调用子函数,一级一级编写。
困惑:
1:类属性generic是嘛玩意,没有这个会有什么影响?
AD这个暂时看到这,主要是想了解下FPGA的工程是怎么实现具体应用的,准备回归夏宇闻的书本,和ISE的使用阶段。
最后一点,资料不要下了一大堆不看,抓住一个合适的再延伸(后来者引以为戒阿,不过有时还是控制不住,下载一大堆在那蒙灰...)