从零开始学FPGA--Verilog基础语法

一、Verilog简介

Verilog HDL(Hardware Description Language)是在用途最广泛的C语言的基础上发展起来的一种硬件描述语言,具有灵活性高、易学易用等特点。Verilog容易掌握,只要有C语言的编程基础,通过比较短的时间,经过一些实际的操作,可以在1个月左右掌握这种语言。

Verilog和C的区别

Verilog是硬件描述语言,在编译下载到FPGA之后,会生成电路,所以Verilog全部是并行处理与运行的;C语言是软件语言,编译下载到单片机/CPU之后,还是软件指令,而不会根据你的代码生成相应的硬件电路,而单片机/CPU处理软件指令需要取址、译码、执行,是串行执行的。
Verilog和C的区别也是FPGA和单片机/CPU的区别,由于FPGA全部并行处理,所以处理速度非常快,这个是FPGA的最大优势,这一点是单片机/CPU替代不了的。

二、Verilog基础知识

Verilog的逻辑值

我们先看下逻辑电路中有四种值,即四种状态:
逻辑 0:表示低电平,也就是对应我们电路的GND;
逻辑 1:表示高电平,也就是对应我们电路的VCC;
逻辑 X:表示未知,有可能是高电平,也有可能是低电平;
逻辑 Z:表示高阻态,外部没有激励信号是一个悬空状态。
在这里插入图片描述

数字进制格式

Verilog数字进制包括二进制(b)、八进制(o)、十进制(d)和十六进制(h)。
例如:
二进制:4’b0101 表示4位二进制数字0101
十进制:4’d2 表示4位二进制数字2 (用二进制表示为0010)
十六进制:4’ha 表示4位十六进制数字a(用二进制表示为1010)

标识符

标识符(identifier)用于定义模块名、端口名和信号名等。Verilog的标识符可以是任意一组字母、数字、$和_(下划线)符号的组合,但标识符的第一个字符必须是字母或者下划线。另外,标识符是区分大小写的。(可以看出与C语言一致)

不建议大小写混合使用,普通内部信号建议全部小写,参数定义建议大写,另外信号命名最好体现信号的含义(比如计数器count,数字和sum等等)。

规范建议
以下是一些书写规范的要求:
1、用有意义的有效的名字如sum、cpu_addr等。
2、用下划线区分词语组合,如cpu_addr。
3、采用一些前缀或后缀,比如:时钟采用clk前缀:clk_50m(可以清楚的知道此处代表50M HZ的时钟),clk_cpu;低电平采用_n后缀:enable_n;
4、统一缩写,如全局复位信号rst。
5、同一信号在不同层次保持一致性,如同一时钟信号必须在各模块保持一致。
6、自定义的标识符不能与保留字(关键词)同名。
7、参数统一采用大写,如定义参数使用SIZE

Verilog的数据类型

寄存器类型

寄存器类型表示一个抽象的数据存储单元,它只能在always语句和initial语句中被赋值,并且它的值从一个赋值到另一个赋值过程中被保存下来。如果该过程语句描述的是时序逻辑,即always语句带有时钟信号,则该寄存器变量对应为寄存器;如果该过程语句描述的是组合逻辑,即always语句不带有时钟信号,则该寄存器变量对应为硬件连线;寄存器类型的缺省值是x(未知状态).
寄存器数据类型有很多种,如reg、integer、real等,其中最常用的就是reg类型,它的使用方法如下:
在这里插入图片描述
reg [31:0] 中 [31:0] 表示定义了32位的一个寄存器,注意高位在前,即31:0
而reg未定义位宽则默认为1位长度

线网类型
线网表示Verilog结构实体(例如门)的物理连线。线网类型的变量不能储存值,它的值由驱动元件的值决定,例如连续赋值或门的输出。驱动线网类型变量的元件有门、连续赋值语句、assign等。如果没有驱动元件连接到线网,线网的缺省值为z(高阻态)。线网类型同寄存器类型一样也是有很多种,如tri和wire等,其中最常用的就是wire类型,它的使用方法如下:
在这里插入图片描述
参数类型
我们再来看下参数类型,参数其实就是一个常量,常被用于定义状态机的状态、数据位宽和延迟大小等,由于它可以在编译时修改参数的值,因此它又常被用于一些参数可调的模块中,使用户在实例化模块时,可以根据需要配置参数。在定义参数时,我们可以一次定义多个参数,参数与参数之间需要用逗号隔开,每个参数定义的右边必须是一个常数表达式。这里我们需要注意的是参数的定义是局部的,只在当前模块中有效。它的使用方法如下:
在这里插入图片描述
注意:合理使用参数定义可以增加可读性与可维护性,例如上述例子,如果我们使用别的尺寸LCD,只需要修改上述一些参数的值,而不需要进入代码内部进行维护更改,会大幅节约时间。

Verilog的运算符

Verilog中的运算符按照功能可以分为下述类型:1、算术运算符、 2、关系运算符、3、逻辑运算符、 4、条件运算符、 5、位运算符、 6、移位运算符、 7、拼接运算符。(大多数与C语言一致)

扫描二维码关注公众号,回复: 11300421 查看本文章

算术运算符
在这里插入图片描述
Verilog实现乘除比较浪费组合逻辑资源,尤其是除法。一般2的指数次幂的乘除法使用移位运算来完成运算(学过8086、51单片机的应该都清楚这个)。 其中 “/” 除法只能实现整除,小数部分会被省略。

关系运算符
在这里插入图片描述
在这里插入图片描述
逻辑运算符
逻辑运算符是连接多个关系表达式用的,可实现更加复杂的判断,一般不单独使用,都需要配合具体语句来实现完整的意思(注意逻辑运算符与位运算符的区别,很多初学者都会弄混。两者主要区别是逻辑运算符只输出0或1,而位运算符是按位进行相应运算,输出的位数与原来的位数相同)
在这里插入图片描述
条件运算符

条件操作符一般来构建从两个输入中选择一个作为输出的条件选择结构,功能等同于 always中的if-else语句
在这里插入图片描述
例如:result = (a>=b)?a:b;
上面表示如果a>=b,则result=a;如果a<b,则result=b。即取a、b的最大值。

位运算符
在这里插入图片描述
如果a与b位宽不一致,则位宽小的数据前面会补0,补到相同的位宽再进行运算。

移位运算符

移位运算符包括左移位运算符和右移位运算符,这两种移位运算符都用0来填补移出的空位。注意左移时,位宽增加;右移时,位宽不变
在这里插入图片描述
例如:
4’b1001<<2 = 6’b100100;
4’b1001>>1 = 4’b0100;

拼接运算符

Verilog中有一个特殊的运算符是C语言中没有的,就是位拼接运算符。用这个运算符可以把两个或多个信号的某些位拼接起来进行运算操作。
在这里插入图片描述
c = { a, b[3:0] }; 将a与b的低四位拼接起来。

运算符的优先级
在这里插入图片描述
注:如果没有自信,最好多用括号,这样也会让程序尽量按自己的逻辑来,毕竟括号的优先级最高,可以避免自己的想法与程序运行时不一致。

参考:正点原子FPGA开发指南


2019年3月28日 西安市沙坡村职业技术学院

猜你喜欢

转载自blog.csdn.net/YDC123458/article/details/88867611