Verilog语法简易教程

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

电子设计大赛——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:高阻态。•整数常量:基本表达格式为:长度‘进制数值•如:6’b96位二进制数•5‘o55位八进制数•9’d69位十进制数•8‘h1f8位十六进制数•而没有“长度进制”声明时,默认为32位十进制数。如:40,-50。•参数:参数是特殊的常量,其语法结构是:•parameterpara1=const1,para2=const2……paraN=constN;如:parameterBIT=1,BYTE=8;语法--变量定义•数据类型:数据类型用来表示数字电路硬件中的数据存储和传送元素,可以理解成变量。Verilog中总共有两大类数据类型:线网类型和寄存器类型。•数据类型的总种类很多,这里只介绍两种最常用且可综合的类型:wire与reg。有兴趣的同学可以自行学习其他类型。•wire是线网类型,可以理解成电路中的一根导线,在实际综合中一般也是生成连接线。•reg是寄存器类型,就是电路中的寄存器、触发器或选择器。语法--变量声明•命名规则:wire与reg变量的通用命名规则:wire/reg[msb:lsb]Varia1,Varia2;•例如:reg[3:0]Sat;//Sat为4位寄存器wire[7:0]Line;//Line为8位线网•如果没有位宽声明,则默认为1位位宽。•注意:reg和wire声明的都是无符号变量,若要声明有符号变量,可以在reg和wire后加上关键字signed。如:regsigned[7:0]Sat;语法--变量赋值•在Verilog中,变量是不能随意赋值的,必须使用赋值运算符才可以进行赋值。其中assign称为连续赋值,对应于线网类型变量wire;initial或always称为过程赋值,对应于寄存器类型变量reg。下面作具体讲解语法--assign与wire•首先列个例子:wirea;assigna=1’b1;•可以看出,语法格式就是这么简单,如下:assign线网型变量名=赋值表达式;•需要理解的是,assign称为连续赋值的意思是,等号右端赋值表达式的值会持续对被赋值变量产生连续驱动,而且只要等号右端赋值表达式的值改变,左端被赋值变量的值就会立即改变。对应到电路中去,就是导线。语法--assign与wire•下面列举一些实际中常用的用法:(1)wirea,b;assigna=b;(2)wire[7:0]a,b;assigna=b;(3)wire[7:0]a,b;assigna[3]=b[1];(4)wire[7:0]a,b;assigna[3:0]=b[3:0];(5)wirea,b;wire[1:0]c;assignc={a,b};语法--initial/always与reg•首先列举两个例子说明initial与always的区别rega,c;initialbeginc=1'b0;endrega,c;always@(a)beginc=c+a;end•initial只会执行一次,即只执行一次把C赋零的行为;而always会不断执行,即每一次a的值改变时,c都会被重新赋值。•这两个例子也非常清楚的说明了initial/always与reg如何配合使用。要注意的是,其中beginend是必须加入的,而@也必须和always一起使用。具体在后面进行讲解。语法—阻塞与非阻塞•于连续赋值assign不同的是,过程赋值中的赋值操作符分为两种,分别是:“=”,称为阻塞赋值,指的在当前的赋值完成前阻塞其他类型的赋值任务;“=”,称为非阻塞赋值,指的从估计右端开始并不阻碍执行其他的赋值操作。•阻塞与非阻塞赋值的区别是Verilog中较为重要的一部分,将在后面进行详尽的讲解。语法--算数运算符•算数运算符有5种:+,-,*,/,%,用于整型数据的数学运算。随着技术的发展,上述5种算术运算符都是可以直接综合的。需要注意的是,在进行加法和乘法运算时,要注意防止数据溢出造成运算错误。语法--逻辑运算符与关系运算符•Verilog中的逻辑运算符与关系运算符同C语言中的用法相似,可以参考。•逻辑运算符分为3种:逻辑与“&&”;逻辑或“||”;逻辑非“!”。•关系运算符分为6种:大于“”;大于等于=;小于;小于等于=;逻辑相等==;逻辑不等!=。如果操作数直接的关系成立,则返回值为1;关系不成立,则返回值为0。语法--条件运算符•条件运算符为“?:”,基本表达式为:y=x?a:b;与C语言一样,x为真时返回前一个操作数a,否则返回操作数b。语法--位运算符•Verilog用位运算符来描述硬件电路中的逻辑门,共有5种:(1)~:非;(2)&:与;(3)|:或;(4)^:异或;(5)^~:同或。•与逻辑运算符不同,位运算符是逐位操作。而逻辑运算符是对整体进行操作:101&100=100;101&&100=1;拼接运算符与重复操作符•拼接运算符是将两个或多个信号的某些位拼接起来成为一个整体数据的运算操作,其格式为:{s1,s2,…,sn};举例如下:z[3:0]={a,b,c,d};shr[15:0]={shr[14:1],b,c};•重复操作符为{{}},即双重花括号,提供复制一个常量或变量的简便记法,如:{3{2'b01}}=6'b010101;语法--移位运算符•移位运算符只有两种:(左移),(右移),其使用格式为:s1N;s1N,N为常数。•某些情况下移位运算符的效果也可以通过拼接运算符实现,这个看个人喜好与具体电路要求。语法--一元约简运算符•一元约简运算符是一种特殊的位运算符,它对单个操作数进行运算,最后返回一位数,具体运算过程为:首先将操作数的第一位和第二位进行位运算,然后将结果与第三位进行位运算,依次类推到最后一位,输出运算结果。示例如下:out1=&a;out2=|a;out3=~&a;out4=~|a;out5=^a;out6=~^a;•一元约简运算符主要用于特殊操作中,如与约简可检测数据中是否包含位1,或约简课检测数据是否包含0。语法--begin…end•前面已经提到过begin…end了。begin…end在Verilog中是非常基础但是十分重要的东西。那么什么是begin…end?这里可以借助C来理解:“begin…end就是C语言中的花括号‘{}’,只不过‘{}’在Verilog中有了别的用处了,所以用begin…end来表示。”语法--触发,“@”•前面讲到了在过程赋值always中,必须加上@。为什么?过程赋值是什么?就是如果发生了什么行为,才给你赋值。那发生的行为就要用“@(行为)”来描述,我们称之为触发,完整格式为always@(触发事件)begin……end语法--触发事件•触发事件有两种,这是由硬件电路决定的,在数电中已经学过:电平触发,边沿触发。•电平触发的格式为•always@(a)•begin……•end•只要a的电平一改变,内部的过程赋值就进行一次。•电平触发不能直接选择触发的电平是高还是低,如果非要选择,可以在内部加入if语句进行判断:always@(a)beginif(a==1‘b0)begin……endend•与电平触发不同,边沿触发可以直接选择触发的边沿:posedge表示上升沿触发,negedge表示下降沿触发。如:•always@(posedgeclk)begin……end•需要注意的是,边沿触发不可以选用某个信号的两个沿,即不能@(posedgeclkornegedgeclk)•注意事项!•同一个always模块中只能使用一种触发方式,不可以边沿触发与电平触发混合使用。•不同的触发事件中间用“or”隔开,也可以用“,”隔开。语法--条件语句if•Verilog中的if语句与C语言中十分相似,可以直接进行参考。需要注意的是,if…else中,即使用不到else分支,语句中else分支也最好加上,否则电路有可能生成不稳定的电路,造成结果的错误。•if(a==1b'1)•c=1'b0;•应写成•if(a==1'b1)•c=1'b0;•else•c=c;语法--条件语句case•case与C语言中的switch比较类似,但是具体又有区别。其语法格式如下:•case(条件表达式)•分支1:语句块1;•分支2:语句块2;•……•default:语句块n;•endcasereg[2:0]cnt;case(cnt)3'b000:q=q+1;3'b001:q=q+2;default:q=q;endcase语法--条件语句case当几个分支对应的操作相同时,可以将这些分支放在一起,如:reg[2:0]cnt;case(cnt)3'b000,3'b001,3'b010:q=q+1;3'b011,3'b100: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中最基本的概念,也是最常用的基本单元。一个mo

1 / 61
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功