




已阅读5页,还剩56页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
电子设计大赛Verilog与FPGA,什么是VerilogHDL?,Verilog是一种用于数字逻辑设计的硬件描述语言。在设计中常用于硬件电路的行为级描述就是告诉电路,你应该做什么,做什么,再做什么!,Verilog与C语言,Verilog的某些语法是与C相似的。但只是形似,神是不同的!Verilog只是Verilog而已,你可以参考C,但不能当做C!你必须了解Verilog的本质。,记住!,你编写的Verilog代码,是会生成实际硬件电路的。而电路,一般都不是串行执行的,很多时候都是并行工作的。所以在Verilog中,你一定要对电路的时序图与数据量图有深刻的认识!,不是所有的Verilog代码都能够转换成实际电路的,学习语法时要分辨清楚。那些可以转换成实际电路的,我们称为“可综合”!另外,即使你使用的可综合的代码去编写,如果你描述的电路实际上无法实现,也是无法综合的!,也许在C语言中,代码越简洁越好。但是在Verilog中绝不是这样!衡量Verilog代码的唯一标准,就是在代码正确与清晰的前提下,可以生成结构尽可能简单、功能却非常强大的电路!,也许有用的Tips,多使用编译器附带RTLViewr看看RTL级原理图,看清楚你写的代码到底生成了什么样的电路。多使用SignalTapIILogicalAnalyzer,看看你写的模块的时序图,看看你写的模块输出的数据的值,尽量忘记C吧,C可以帮助你记住Verilog里面的关键字,但是请不要用C的思想来编写Verilog。要使用Verilog的思想来编写Verilog,多写多练吧,无论学习什么练习都是王道。当你初步掌握了Verilog之后,推荐你看看Verilog那些事儿进行进一步的学习。什么是Verilog的思想?也许你可要在那里找到答案。,语法-符号,标识符:赋给对象的唯一名称,可以是字母、数字、下划线和符号“$”的组合,且首字符只能是字母或者下划线。区分大小写,如“if”为关键字,而“IF”不是关键字。注释:注释有两种:1,以“/*”开头,以“*/”结束。2,以“/”开头到本行结束。这些和C语言差不多。,语法-数字量,逻辑数值:(1)0:逻辑0;(2)1:逻辑1;(3)x:未知,不定;(4)z:高阻态。,整数常量:基本表达格式为:长度进制数值如:6b96位二进制数5o55位八进制数9d69位十进制数8h1f8位十六进制数而没有“长度进制”声明时,默认为32位十进制数。如:40,-50。,参数:参数是特殊的常量,其语法结构是:parameterpara1=const1,para2=const2paraN=constN;如:parameterBIT=1,BYTE=8;,语法-变量定义,数据类型:数据类型用来表示数字电路硬件中的数据存储和传送元素,可以理解成变量。Verilog中总共有两大类数据类型:线网类型和寄存器类型。数据类型的总种类很多,这里只介绍两种最常用且可综合的类型:wire与reg。有兴趣的同学可以自行学习其他类型。wire是线网类型,可以理解成电路中的一根导线,在实际综合中一般也是生成连接线。reg是寄存器类型,就是电路中的寄存器、触发器或选择器。,语法-变量声明,命名规则:wire与reg变量的通用命名规则:wire/regmsb:lsbVaria1,Varia2;例如:reg3:0Sat;/Sat为4位寄存器wire7:0Line;/Line为8位线网如果没有位宽声明,则默认为1位位宽。注意:reg和wire声明的都是无符号变量,若要声明有符号变量,可以在reg和wire后加上关键字signed。如:regsigned7:0Sat;,语法-变量赋值,在Verilog中,变量是不能随意赋值的,必须使用赋值运算符才可以进行赋值。其中assign称为连续赋值,对应于线网类型变量wire;initial或always称为过程赋值,对应于寄存器类型变量reg。下面作具体讲解,语法-assign与wire,首先列个例子:wirea;assigna=1b1;可以看出,语法格式就是这么简单,如下:assign线网型变量名=赋值表达式;需要理解的是,assign称为连续赋值的意思是,等号右端赋值表达式的值会持续对被赋值变量产生连续驱动,而且只要等号右端赋值表达式的值改变,左端被赋值变量的值就会立即改变。对应到电路中去,就是导线。,语法-assign与wire,下面列举一些实际中常用的用法:(1)wirea,b;assigna=b;(2)wire7:0a,b;assigna=b;(3)wire7:0a,b;assigna3=b1;(4)wire7:0a,b;assigna3:0=b3:0;(5)wirea,b;wire1:0c;assignc=a,b;,语法-initial/always与reg,首先列举两个例子说明initial与always的区别,rega,c;initialbeginc=1b0;end,rega,c;always(a)beginc=c+a;end,initial只会执行一次,即只执行一次把C赋零的行为;而always会不断执行,即每一次a的值改变时,c都会被重新赋值。,这两个例子也非常清楚的说明了initial/always与reg如何配合使用。要注意的是,其中beginend是必须加入的,而也必须和always一起使用。具体在后面进行讲解。,语法阻塞与非阻塞,于连续赋值assign不同的是,过程赋值中的赋值操作符分为两种,分别是:“=”,称为阻塞赋值,指的在当前的赋值完成前阻塞其他类型的赋值任务;“(右移),其使用格式为:s1N,N为常数。某些情况下移位运算符的效果也可以通过拼接运算符实现,这个看个人喜好与具体电路要求。,语法-一元约简运算符,一元约简运算符是一种特殊的位运算符,它对单个操作数进行运算,最后返回一位数,具体运算过程为:首先将操作数的第一位和第二位进行位运算,然后将结果与第三位进行位运算,依次类推到最后一位,输出运算结果。示例如下:out1=一元约简运算符主要用于特殊操作中,如与约简可检测数据中是否包含位1,或约简课检测数据是否包含0。,语法-beginend,前面已经提到过beginend了。beginend在Verilog中是非常基础但是十分重要的东西。那么什么是beginend?这里可以借助C来理解:“beginend就是C语言中的花括号,只不过在Verilog中有了别的用处了,所以用beginend来表示。”,语法-触发,“”,前面讲到了在过程赋值always中,必须加上。为什么?过程赋值是什么?就是如果发生了什么行为,才给你赋值。那发生的行为就要用“(行为)”来描述,我们称之为触发,完整格式为always(触发事件)beginend,语法-触发事件,触发事件有两种,这是由硬件电路决定的,在数电中已经学过:电平触发,边沿触发。,电平触发的格式为always(a)beginend只要a的电平一改变,内部的过程赋值就进行一次。电平触发不能直接选择触发的电平是高还是低,如果非要选择,可以在内部加入if语句进行判断:always(a)beginif(a=1b0)beginendend,与电平触发不同,边沿触发可以直接选择触发的边沿:posedge表示上升沿触发,negedge表示下降沿触发。如:always(posedgeclk)beginend需要注意的是,边沿触发不可以选用某个信号的两个沿,即不能(posedgeclkornegedgeclk),注意事项!同一个always模块中只能使用一种触发方式,不可以边沿触发与电平触发混合使用。不同的触发事件中间用“or”隔开,也可以用“,”隔开。,语法-条件语句if,Verilog中的if语句与C语言中十分相似,可以直接进行参考。需要注意的是,ifelse中,即使用不到else分支,语句中else分支也最好加上,否则电路有可能生成不稳定的电路,造成结果的错误。,if(a=1b1)c=1b0;应写成,if(a=1b1)c=1b0;elsec=c;,语法-条件语句case,case与C语言中的switch比较类似,但是具体又有区别。其语法格式如下:,case(条件表达式)分支1:语句块1;分支2:语句块2;default:语句块n;endcase,reg2:0cnt;case(cnt)3b000:q=q+1;3b001:q=q+2;default:q=q;endcase,语法-条件语句case,当几个分支对应的操作相同时,可以将这些分支放在一起,如:reg2:0cnt;case(cnt)3b000,3b001,3b010:q=q+1;3b011,3b100:q=q+2;default:q=q;endcase,另外,同else一样,default一般不要缺省。,语法-条件语句if与case的区别,最大的区别是,if生成的电路是串行,是有优先级的编码逻辑;而case生成的电路是并行的,各种判定情况的优先级相同。因此,if生成的电路延时较大,占用硬件资源少;case生成的电路延时短,但占用硬件资源多。,语法-循环语句,Verilog中也是有循环语句的,但是不推荐初学者使用。与C不同,Verilog的循环语句是依靠电路的重复生成实现的,而且并不是所有的循环语句都可以综合。感兴趣的同学可以在深入了解Verilog后自学循环语句。,语法-任务和函数,Verilog中还有两种特殊的语句:任务(task)和函数(function)。这两种语句一般用于组合电路的设计中,可以简化代码结构,但在时序电路的设计中无法使用。感兴趣的同学可以在深入了解Verilog后自行学习。,语法-模块的概念,模块(module)是Verilog中最基本的概念,也是最常用的基本单元。一个module就是一整块电路实体,一个系统就是由许多个module组成的。需要注意的是,在Quartus中,一个VerilogHDL文件(*.v)中只能编写一个module,而且文件名必须与module的名字相同。,语法-module的结构,module的基本结构如下:module模块名(端口列表)端口声明其他声明模块条目endmodule,端口声明有3钟:(1)input:输入端口,可以理解为输入脚;(2)output:输出端口,可以理解成输出脚;(3)inout:输入输出端口,可以理解成双向管脚。,语法-module实例:3-8译码器,moduledecoder3to8(din,dout);input2:0din;output7:0dout;reg7:0dout;always(din)begincase(din)3b000:dout=8b0000_0001;3b001:dout=8b0000_0010;3b111:dout=8b1000_0000;endcaseendendmodule,语法*-阻塞与非阻塞的深入理解,前面说过,过程赋值有两种:阻塞赋值“=”和非阻塞赋值“=”。那么它们有什么区别呢?说的最简单的话,阻塞式赋值左边的变量在被赋予新值前,之后用到该变量的阻塞赋值式都无法执行,而非阻塞赋值则不会。在组合逻辑和时序逻辑电路中都可以这样理解。,语法*-阻塞与非阻塞的深入理解,首先看组合逻辑中的区别,看下面两个例子,always(a,b,c,d)begint1=aend,always(a,b,c,d)begint1=aend,当a,b,c,d都从0变为1时,左边out输出1,右边out仍为0。因为t1的值由a,b决定,t2的值有c,d决定,在左边,由于阻塞,t1、t2被赋新值前不能给out赋值,out使用的t1,t2存储的是新的数值1;而在右边,由于非阻塞,out赋值式立刻执行,out使用的t1,t2存储的是旧的数值0。,语法*-阻塞与非阻塞的深入理解,再来看时序逻辑中的区别,看下面两个例子,always(posedgeclk)q1=d;q2=q1;q3=q2;end,always(posedgeclk)q1=d;q2=q1;q3temp2)?1:0;endmodule这样就实现了模块的调用,最终实现了将输入数据相乘后比较大小的结果输出。,语法*-模块调用,根据上面例子,可以给出模块调用的语法格式:模块名例化后名(.端口1名(连接端口1信号名),.端口2名(连接端口2信号名),.端口3名(连接端口3信号名),);其中,掉用时端口的顺便可以改变,只要名字正确即可;例化后名不能为元模块名或关键字。,语法*-状态机,状态机并不是属于Verilog的范畴,但是通过Verilog实现状态机可以帮助我们简化很多设计,所以状态机一定要掌握!状态机可分为两种:Mealy型和Moore型状态机。Mealy型状态机的输出同时依赖于当前状态和输入信号,输出可以在输入发生改变之后立刻改变,而与时钟信号无关,因此Mealy型状态机具有异步输出;Moore型状态机的输出仅仅依赖于当前状态,输出是通过组合逻辑块计算得到的,本质上是当前状态的函数。,语法*-状态机,Mealy型,Mealy型,语法*-状态机,状态机设计原则:1,给事件划分步骤,弄清楚先做什么,再做什么,做了这一步下一步应该怎么样做。2,状态化简与状态分配。检查下是否有冗余,重复的步骤。当状态划分到最简后,给每个状态进行编码分配。3,通过Verilog实现。这里有很多模板,后面进行讲解。4,观察编译结果的状态流程图,检查状态机功能是否正确。,语法*-状态机,编码分配原则:状态的编码形式一般有三种,普通的二进制编码,格雷码编码,OneHot码编码(OneHot码对应关系:0,0000;1,0001;2,0010;3,0100;4,1000)。二进制码占用的数据位宽比较简单,但容易产生毛刺;格雷码一定程度减少了毛刺的产生;OneHot码不会产生毛刺,可以使状态机达到较高的工作频率,但是会增加触发器的占用。具体选用什么码根据实际需求,一般普通二进制编码即可。,语法*-状态机,“一段式”状态机Verilog模板:always(posedgeclk)beginif(!rst_n)beginstate=out=endelsebegincase(state)s0:beginstate=out=end,s1:beginstate=out=endendcaseendend这种形式输出向量不会产生毛刺,但是不能实现异步Mealy有限状态机。,语法*-状态机,“二段式”状态机Verilog模板:/状态调转always(posedgeclk)beginif(!rst_n)state=idle;elsestate=next_state;end/下一状态的计算以及输出逻辑always(state)begincase(state)s0:beginnext_state=out=,ends1:beginnext_state=out=endendcaseend这种形式具有最优的面积和时序性能,但输出组合逻辑,有可能产生毛刺。,语法*-状态机,飞“三段式”状态机Verilog模板:/状态调转always(posedgeclk)beginif(!rst_n)state=idle;elsestate=next_state;end/下一状态的计算always(posedgeclk)begincase(state)s0:next_state=s1:next_state=endcase,end/输出的逻辑处理always(posedgeclk)begincase(state)s0:out=s1:put=endcaseend这种形式的输出同样无毛刺,是一些参考书上的推荐写法。,写在Verilog的最后,下面是一些我推荐的代码风格,同学们可以参考一下,希望对同学们学习Verilog有帮助;模块声明:module(/inputa,b,/outputc,d);在声明时就用注释将输入输出脚区别出来。,写在Verilog的最后,异步复位的always:always(posedgeclk,negedgerst_n)beginif(!rst_n)begin/一堆复位的行为endelsebeginendend模块带有异步复位的功能推荐都这样写,FPGA的概述,Filedprogrammablegatearray,现场可编程门阵列。FPGA的引脚分为电源脚,I/O脚,特殊功能脚。能给外设使用的只有I/O脚。FPGA的逻辑实现是通过查找表的方式实现的,就是通过RAM来实现逻辑函数。所以,FPGA内部没有真正的逻辑门。,FPGA使用注意,FPGA内部是RAM,RAM掉电丢失数据,所以与CPLD不同,FPGA普通下载的程序在掉电后是没有了的。FPGA内部没有真正的逻辑门,所以不要在内部使用带高阻态的输出相连,编译器不会报错,但是电路功能是无法实现的。如果非要把两个输出连一起,可以使用“:?”进行二选一。FPGA的I/O引脚电路是支持双向高阻态的。,FPGA内部硬件,1.锁相环(PLL):可以将输入的晶振时钟信号分频或者倍频。注意:FPGA内部对时序有着严格的要求,而PLL的输入输出都是使用的特殊设计的时钟信号线。因此当工作在高频时,你们自己编写的FPGA模块一般都必须采用PLL的输出作为时钟信号。,FPGA内部硬件,基本逻辑单元:不同FPGA的基本逻辑单元的
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 计算机组成原理 课件 8 输入输出系统
- XXXX年选人用人专项整治党性分析报告范文
- 巡察组写巡察报告课件
- 输电线路运行培训课件
- 尾矿作业安全培训教程课件
- 国际知识产权贸易合同创新成果转化与许可使用
- 生态旅游区土石方运输与景观建设合同
- 风力发电场工程项目建议书编制与环境影响评价规范
- 专项项目出差人员管理服务合同
- 离婚子女抚养权争夺人民法院协议调解合同
- 中国昆曲课件
- 大学健身房管理细则
- 2025中国临床肿瘤学会CSCO肿瘤厌食-恶病质综合征诊疗指南解读课件
- 中药材生产与加工专业教学标准(高等职业教育专科)2025修订
- 公司内部电子发票管理制度
- 2025至2030中国乳清粉行业发展分析及前景趋势与投资报告
- 乡村医生招聘面试题及答案详解
- 傅里叶级数习题课
- 医疗质量与医疗安全十八项核心制度
- DB31T 329.24-2019 重点单位重要部位安全技术防范系统要求 第24部分:高校
- 某某医疗机构纳入定点后使用医疗保障基金的预测性分析报告
评论
0/150
提交评论