fpga学习心得.docx
《fpga学习心得.docx》由会员分享,可在线阅读,更多相关《fpga学习心得.docx(9页珍藏版)》请在冰豆网上搜索。
![fpga学习心得.docx](https://file1.bdocx.com/fileroot1/2023-1/1/98d4d432-1c6a-496e-8c1f-019c65747fdf/98d4d432-1c6a-496e-8c1f-019c65747fdf1.gif)
fpga学习心得
FPGA学习心得
学习fpga一个多月以来,完全从零开始学习,感觉自己学到的东西真不少,虽然还不是很熟练,不过也对fpga有了很好的了解。
以前一直没有想过要来总结些什么,是感觉自己对于fpga根本就像是一无所知一样,虽然天天在学,不过确实没有一个总体观念,学的东西太混乱也没有一个总体的框架。
到了今天终于觉得自己的学习已经小有成就了,虽然还是没有能够独立设计的自信。
在最初学习的时候最主要就是对于fpga结构的一个基本认识和对硬件描述语言verilogHDL语言的学习。
之所以选择学习fpga是因为在这一学期找工作中发现,现在很多公司都需要会一点fpga方面的知识,在笔试的时候也会偶尔遇到一些用HDL语言编程的试题。
现在很多硬件工程师已经不再是单纯的用传统的方法进行电路的设计,至少现在很多招聘的岗位当中不再是单纯的电路的设计了,很多都涉及到嵌入式和HDL语言。
Fpga现在正在以异常的速度发展,在08年全球金融危机的时候大多数行业都呈现在下滑的趋势,而fpga的厂商如xilinx和altera等公司的收入却呈现出增长的态势。
在我看来fpga必将是将来硬件工程师不可缺少的一项本领,这也就是我学习fpga的原因之一。
一、硬件描述语言:
对于硬件描述语言(HDL)语言我选择的是和C语言类似的verilogHDL语言,虽然VHDL语言在很多方面优于verilogHDL语言,但是作为初学,还是先学习一个简单一点的语言,尽量先将所需要学习的东西过一遍,将来等时间允许的时候再去学习VHDL语言,在网上有看到现在出来了一个叫systemverilog的语言,据说融合了verilog和VHDL语言各自的优点,可能将来会成为行业统一的语言吧。
verilogHDL现阶段主要接触的就是对组合逻辑电路和时序电路的描述了。
所接触的程序中以always@(*)模块居多,几乎是所见过模块的核心部分了,其实在学习这个语言上面也没有花太多的时间,因为有对C语言的学习,所以就先入为主了。
当了解了其基本语法过后就开始了实例的分析,在此过程中也有了解fpga的结构,不过感觉没有真正使用过fpga所以对于那些什么pll、sram、sdram、norflash等都没有什么直观的感觉,所以对于程序也根本不知道这样些的原因和到底能实现什么功能,这也成为了我学习verilogHDL语言的一个障碍。
二、fpga的基本结构:
在这里还是得认识清楚fpga的结构,记得有一个在外面去面试的时候,别人就问了我一个问题——fpga和mcu的联系与区别?
当时我根本都还没有接触过fpga,只知道fpga是属于硬件方面的开发板。
后来通过自己对fpga的接触和网上的相关说明终于有了一个初步的认识。
接下来就具体说明一下:
MCU又称为单片机,它为8位的微控制器,主要用在工业控制,FPGA则为可编程逻辑器件的一种,拥有丰富的硬件资源,可实现强大的逻辑功能,由于其硬件重构的特性,适合各种领域的应用;MCU的编程语言主要为C语言,以软逻辑实现,它通过顺序执行指令来实现特定功能,避免不了低速的缺点,相比之下,FPGA它以Verilog或VHDL等硬件描述语言为编程语言,由于直接由硬件实现逻辑,所以它并行执行,从而使速度大大提高;MCU的这种同一时间只能处理一条指令的特点也影响了它的应用,它只能用于一些算法的设计及简单的控制,而FPGA由于并行执行的特性,大量应用于复杂逻辑控制以及大量的数据运算和处理。
FPGA是在PAL、GAL、CPLD等可编程器件的基础上一步一步发展起来的。
PAL是与阵列可编程或阵列固定,它的缺点是:
采用熔丝工艺,只能一次编程,并且它的输出是固定的,不能编程;也就是说芯片一旦选定,输出结构将不可改变。
GAL是在PAL的基础上发展起来的,可以重复编程。
与PAL的最大区别是:
输出结构可以由用户自己定义。
但它结构简单,I/O数目有限。
CPLD是在GAL的基础上发展起来的。
它主要由输入输出控制单元、宏单元和互连矩阵等组成。
随着电子市场对功能要求的不断提高,CPLD越来越不能满足市场的需求。
它最大只有512个宏单元,大部分是组合逻辑,难以实现复杂的时序逻辑设计,并且功耗很大。
随着工艺的发展,FPGA登上了历史舞台并成为主角,它内部资源丰富,不管是时序逻辑还是组合逻辑都很多。
它是作为专用集成电路领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器件门电路数有限的缺点。
三、altera公司的软件使用:
其实真正对fpga有一个整体了解是在其软件的使用过程中。
我在实验室里使用的是altera公司的sycloneII系列的EP2C35F484C8,所以使用的软件就是altera公司提供的quartusII和niosEDS。
在quartus的使用中其他的没什么说的,只是有几点需要注意:
一就是顶层文件名一定要和工程名一致;二就是工程一定不能放在含中文的目录下,否者编译会出错。
在最初使用quartus的时候就涉及到仿真和引脚分配的问题。
关于引脚分配,最开始没人提示所以我以为只要弄上去不报错就行了,后来在下载到实验板上的时候,发觉根本就达不到预期的效果,于是在网上找了很多相关的技巧,也尝试过通过tcl脚本配置,网上还特推荐这种方法。
后来在handbook里面终于找到了相应的治疗,发觉还是我一个一个的敲进去方彪。
然后就是仿真了,在最初使用的quartusII9.0版本中还自带仿真工具,所以就没有借用第三方的modelsim,因为感觉编写testbench也是一个很麻烦的事情,但是自从quartusII10版本以后altera公司就取消了仿真工具,而推荐大家使用第三方的modersim,哎没办法只有再去研究一下modersim破解了方法和testbench的书写了。
其实quartusII里面还有很多实用的工具,比如说像signaltapII、timeQuest、sopcbuilder等。
现在我还欠缺的就是使用timeQuest进行时序收敛,这个在特权同学的视频教程中有,还需要好好去学习,而对于signaltapII和sopcbuilder已经有了一定的了解。
其实sopcbuilder就是以前的nios和niosII的一个后继者,它主要就是调用别人已经写好了的一些程序来控制fpga的各个组件,当然也可以根据自己的需要进行自定义组件以达到自己的设计要求。
在配置sopc的时候一定要根据自己所使用的fpga型号就行参数的设置,所以阅读开发板使用手册就显得至关重要了。
而我在配置sopc的过程中也遇到过很多的问题,现在也还有很多技巧没有学会,我在这个方面花费的时间也是特别的多的,几乎用去了我2/3的时间。
刚开始配置的时候还是感觉自己学到了很多东西,也作出了很多实际的效果,给自己带来了不少的信心,可是到后面发觉自己好像只是在做一个简单的模仿的工作,于是越来越觉得自己偏离了学习的重心,而且在这个过程中也遇到了很多没有解决的问题,于是学习就有点停滞不前了。
很多器件为什么需要,为什么不需要?
成了困扰我的主要问题,而《Nios_II_嵌入式软核SOPC设计原理及应用》、《NiosII的那些事儿》以及用户手册和网友博客给了我很大的帮助,也补充了自己在这方面的理论知识。
在学习sopc过程中到现在也还有很多难题没有得到解决,当然不一定就是sopc的问题,也有HDL语言的问题:
第1、在配置锁相环的时候遇到一个很奇怪的问题。
首先来说说锁相环的功能,锁相环主要的功能是能够进行倍频和分频并且能够产生相移。
而一般的niosII软核能够工作在100MHz的频率下,而sycloneII系列的晶振时钟是50MHz,所以一般在配置sopc的时候都需要用到锁相环,当然也可以不用。
然而如果要用到SDRAM组件的时候就一定要用PLL了,因为SDRAM的时钟和系统时钟之间有一个相移,必须通过PLL来实现相移。
而PLL的使用有两种方法,一种就是在quartusII里面添加,一种就是在sopc里面添加PLLcontrol来生成。
第一种没有多少好说的,这里主要就是说一下第二种方法,因为我在第二种配置下没有成功过。
当时一直不知道原因所在,也在网上看了很多想过质料,依旧没有找到权威的解释,终于在特权同学的博客上面得到了解答:
我发觉自己很多知识都是通过特权同学的博客、书籍和视频而得到,看到很多网友推荐购买特权同学的书籍学习看来真是对的。
第2、在观看了特权同学的视频后,试着将那些繁琐的程序分模块来进行书写。
但是对于顶层例化模块的书写一直还没来得及仔细去学习。
大多时候都是通过生成板块图在bdf文件里面用连线的方式来代替例化,对于我现阶段这种小工程来说这样还并没有多大的影响,也和同学讨论过例化。
他们的观点是这个东西可以通过连线的方式来完成,所以没必要再去做那个“麻烦而看似作用不大”的例化了。
其实例化模块的存在是有很大的意义的,或许在我们现阶段的这种小系统中还体现不出它的作用。
我们这样设想一下,假如在公司里面要做某个工程,这个工程由1000个模块组成,分给不同的小组完成,每个小组负责一个模块,最后由总工程师将各个模块整合,如果没有例化文件那么总工程师就用对这1000个模块图进行连接,而通过例化模块对管脚进行分配后就只有一个模块图了,差别可想而知了吧。
当然学习编写例化模块还有一个好处就是能够让自己对所编写的程序有一个总体概念,增强自己对于程序的理解能力,这样能提高自己的编程能力。
第3、就是涉及到一个自定义组件的问题了,其实任何组件都可以通过PIO端口进行外加,但是这个和模块例化也有一样的问题。
既然能够使模块的数量减少又何乐而不为呢?
第4、就是时序收敛了,这个真的还没有仔细去研究过,只是观看了特权同学的教学视频,感觉太繁琐了,还是等以后又充足的时间的时候再去学习了。
第5、而在我的毕业设计当中需要用到vga显示,这成了我这段时间的主要难题,刚开始的时候自己走进了一个误区,总以为vga的各种显示都是通过HDL语言来控制的,而我就在想怎么才能做到动态的显示。
于是遍历互联网终不得其解,也许是我自己没能找到,但是就算我找到了,我想那个难度也足以让我反胃一周了。
通过在网上看相关的论坛也博客最终不得不放弃纯硬件的方法。
我在想可以通过写vga的驱动,然后通过EDS软件编程来实现,当然现在还只是一个想法。
在这里我也找到了一个vga的驱动程序:
1.二分频电路
二分频把50MHz时钟频率分成25MHz并提供给其它模块作为时钟。
显示器的像素分辨率是640×480,像素时钟25Mhz,刷新频率60Hz±1。
开发板提供的系统时钟50MHz,所以要对板载时钟进行分频后才能使用。
分频电路的设计部分程序如下:
moduleclkdiv(
inputwiremclk,
inputwireclr,
outputwireclk25
);
reg[24:
0]q;
//25-bitcounter
always@(posedgemclkorposedgeclr)
begin
if(clr==1)
q<=0;
else
q<=q+1;
end
assignclk25=q[0];//25mhz
endmodule
2.时序控制模块
VGA时序控制模块用于产生640*480显示范围,并控制显示范围和消隐范围以及产生水平同步时序信号hs和垂直同步时序信号vs的值。
一般来说,时钟计数器通过像素时钟来控制水平时序信号。
译码计数器的值产生HS信号。
在指定的行,计数器产生当前像素显示的位置。
一个独立的计数器产生垂直时序信号。
垂直同步计数器在每个HS脉冲信号来临时自动加1,译码值产生VS信号。
计数器产生当前显示行。
这两个计数器从地址到显示缓冲器连续计数。
开发板的DDRSDRAM提供了一个足够的显示缓冲区。
在HS脉冲的开始和VS脉冲的开始没有具体规定相对的时序关系。
因此,计数器被分配到简单格式的视频RAM地址,或分配到同步脉冲产生器的最小译码逻辑。
设计对时序控制部分的部分代码如下:
modulevga640480(
inputwireclk,
inputwireclr,
outputreghsync,
outputregvsync,
outputreg[9:
0]hc,
outputreg[9:
0]vc,
outputregvidon
);
parameterhpixels=10'b1100100000;
//行像素点=800
parametervlines=10'b1000001001;
//行数=521
parameterhbp=10'b0010010000;
//行显示后沿=144(128+16)
parameterhfp=10'b1100010000;
//行显示前沿=784(128+16+640)
parametervbp=10'b0000011111;
//场显示后沿=31(2+29)
parametervfp=10'b0111111111;
//场显示前沿=511(2+29+480)
regvsenable;//EnbalefortheVerticalcounter
//行同步信号计数器
always@(posedgeclkorposedgeclr)
begin
if(clr==1)
hc<=0;
else
begin
if(hc==hpixels-1)
begin
//Thecounterhasreachedtheendofpixelcount
hc<=0;//计数器复位
vsenable<=1;
//Enabletheverticalcountertoincrement
end
else
begin
hc<=hc+1;//Incrementthehorizontalcounter
vsenable<=0;//Leavethevsenableoff
end
end
end
//产生hsync脉冲
//当hc为0~127时,行同步脉冲为低电平
always@(*)
begin
if(hc<128)
hsync=0;
else
hsync=1;
end
//场同步信号计数器
always@(posedgeclkorposedgeclr)
begin
if(clr==1)
vc<=0;
else
if(vsenable==1)
begin
if(vc==vlines-1)
//Resetwhenthenumberoflinesisreached
vc<=0;
else
vc<=vc+1;
//场计数器加1
end
end
//产生vsync脉冲
//当hc为0或1时,场同步脉冲为低电平
always@(*)
begin
if(vc<2)
vsync=0;
else
vsync=1;
end
//Enablevideooutwhenwithintheporches
always@(*)
begin
if((hchbp)&&(vcvbp))
vidon=1;
else
vidon=0;
end
endmodule
当然不同的fpga型号应该做相应的修改。
第6、接下来一个就是鼠标的控制了,这个相对没有vga那么麻烦,在开发板资料上面也有相应的实例,相信用不了什么时间就能够吃透。
以上就是我这段时间的学习,主要是对于硬件部分的学习,而我感觉真正困难的还在后面,软件的编程控制、matlab和dspbuilder的学习都将是一个不小的挑战。