文章目录
前言
现在,我们已经通过了流水灯、按键控制led灯、按键控制蜂鸣器、状态机等项目的训练,对Veriolg也有初步的认识,但是我们没有系统的学习Verilog语法。相信你也遗留了很多关于Verilog的诸多问题,不用着急,本文将根据前期课程的实训内容,来学习Verilog语法。一、硬件描述语言
1.1 什么是硬件描述语言
硬件描述语言(Hardware Description Language, HDL)是电子系统硬件行为描述、结构描述、数据流描述的语言。利用这种语言,数字电路系统的设计可以从顶层到底层(从抽象到具体)逐层描述自己的设计思想,用一系列分层次的模块来表示极其复杂的数字系统。然后,利用电子设计自动化(Electronics Design Automation, EDA )工具,逐层进行仿真验证,再把其中需要变为实际电路的模块组合,经过自动综合工具转换到门级电路网表。接下去,再用专用集成电路(Application Specific Integrated Circuit,ASIC)或现场可编程门阵列 FPGA(Field-Programmable Gate Array,FPGA)自动布局布线工具,把网表转换为要实现的具体电路布线结构,VHDL(Very High Speed Integration Circuit,HDL)和 Verilog HDL 语言适应了这种趋势的要求,先后成为 IEEE 标准。
1.2 主要的硬件描述语言
硬件描述语言主要包括:Verilog、VHDL、SystemVerilog。
1.2.1 Verilog HDL
Verilog HDL拥有广泛的设计群体,成熟的资源也比 VHDL 丰富,语言从C编程语言中继承了多种操作符和结构,对于熟悉C语言的同学,学习verilog时上手会很快。
1.2.2 VHDL
超高速集成电路硬件描述语言(Very High Speed Integrated Circuit Hardware Description Language,VHDL)是一种标准化程度较高的硬件描述语言,其语言特点包括:语法严谨、结构规范、移植性强、数据类型丰富。除此之外VHDL支持层次结构设计,独立于器件和设计平台,程序复用性强。
1.2.3 SystemVerilog
SystemVerilog结合了来自 Verilog、VHDL、C++的概念,将硬件描述语言与现代的高层级验证语言结合了起来。所以SystemVerilog有上述两种语言和计算机高级语言的特征。
建议学习Verilog HDL的原因:
- Verilog HDL 推出已经有 20 年了,拥有广泛的设计群体,成熟的资源也比 VHDL 丰富,Verilog HDL未来发展趋势。
- 它非常容易掌握,只要有 C 语言的编程基础,通过比较短的时间,经过一些实际的操作,可以在 2 ~ 3 个月内掌握这种设计技术。
- 在中国很多集成电路设计公司都采用Verilog,一般大型项目采用VHDL。
- SystemVerilog是Verilog的升级,对于“小白”,应该从学习Verilog开始。
二、基础知识
2.1 逻辑值
- 逻辑0:表示低电平,也就对应我们的电路GND。
- 逻辑1:表示高电平,也就对应我们电路的VCC。
- 逻辑X:表示未知,有可能是高电平,也有可能是低电平。
- 逻辑Z:·表示高阻态,外部没有激励信号(输入信号),是一个悬空状态(未接高低电平)。
2.2 进制格式
Verilog数字进制格式包括二进制(binary)、八进制(octal)、十进制(decimal)和十六进制(hexadecimal)。一般常用的为二进制、十进制和十六进制。
- 二进制表示如下:4’b0101表示4位二进制数字0101
- 八进制表示如下:4’o7表示4位八进制数7(二进制0111)
- 十进制表示如下:4’d2表示4位十进制数字2(二进制0010)
- 十六进制表示如下:4’ha表示4位十六进制数字a(二进制1010)
注意:如果数值未表明位宽和进制,则:默认为32位宽的十进制数字(32’d),常见写法:16’b1001_1010_1010_1001=16’h9AA9
2.3 标识符(变量名)
标识符:用于定义模块名、端口名、信号名等(就是起个名字而已)。标识符命名规则:
- 标识符可以是任意一组字母、数字、$和_(下划线)符号的组合。
- 但标识符不允许以数字开头,和c语言类似。
- 标识符严格区分大小写,大小写敏感。
- 不建议大小写混合使用。
- 普通内部信号建议全部小写。
- 命名最好体现信号的含义,简介、清晰、易懂(见名知意)
例子:
- 有意义的标识符:sum
- 用下划线区分词:cpu_addr
- 采用一些前缀或后缀:时钟clk_50或sys_clk
三、数据类型
3.1 概述
在Verilog中,主要数据类型:
1. 寄存器数据类型(register)
2. 线网数据类型(wire)
3. 参数数据类型(parameter)
4. 整型(integer)
注意:真正在数字电路中起作用的数据类型是寄存器数据类型和线网数据类型。
3.2 寄存器类型
寄存器表示一个抽象的数据存储单元,通过赋值语句可以改变寄存器存储的值 ,寄存器数据类型的关键字是reg,reg类型数据的默认初始值为不定值x。
如: reg [9:0] delay_cnt; //双斜杠表示注释,不参与编译
reg key_reg;
reg类型的数据只能在always语句和initial语句中被赋值。如果该过程语句描述的是时序逻辑,即always语句带有时序时钟信号,则该寄存器变为对应为触发器;如果该过程语句描述的是组合逻辑,即always语句不带有时钟信号,则该寄存器变为对应硬件连线。
3.3 线网类型
- 线网数据类型表示结构实体(例如门)之间的物理连线。
- 线网类型的变量不能存储值,它的值是由驱动它的元件所决定。
- 驱动线网型变量的元件有逻辑门、连续赋值语句(assign)等。
- 如果没有驱动元件连接到线网类型的变量上,则该变量就是高阻的,即为Z。
- 线网数据类型包括wire类型和tri类型,其中最常用的就是wire类型。
3.4 参数类型
参数其实就是一个常量,在Verilog HDL中用parameter定义常量。我们可以一次定义多个参数,参数与参数之间需要用逗号(,)隔开。每个参数定义的右边必须是一个常数表达式。
如: parameter H_FRONT = 11’d11; //行显示前沿
parameter H_BACK = 11’d2; //行显示后沿
参数型数据常用于定义状态机的状态、数据位宽和延迟大小等。采用标识符来表示一个常量可以提高程序的可读性和可维护性。在模块调用时,可通过参数传递来改变被调用模块中已定义的参数。
四、运算符
Verilog中的操作符按照功能分为以下几种类型:
- 算数运算符
- 关系运算符
- 逻辑运算符
- 条件运算符
- 位运算符
- 移位运算符
- 拼接运算符
4.1 算数运算符
符号 | 使用方法 | 说明 |
---|---|---|
+ | a + b | a加上b |
- | a - b | a减去b |
* | a * b | a乘以b |
/ | a / b | a除以b |
% | a % b | a模除b |
注:除法运算(/):整数与整数相除的结果为整数
4.2 关系运算符
符号 | 使用方法 | 说明 |
---|---|---|
> | a > b | a大于b |
< | a < b | a小于b |
>= | a >= b | a大于等于b |
<= | a <= b | a小于等于b |
== | a == b | a等于b |
!= | a != b | a不等于b |
4.3 逻辑运算符
符号 | 使用方法 | 说明 |
---|---|---|
! | !a | a的非 如果a为0,那么a的非就是1。 |
&& | a && b | a与上b 如果a和b都为1,a&&b结果才为1,表示真 |
|| | a || b | a或上b 如果a或者b有一个为1,a||b结果为1,表示真 |
&&:左右两边同时为1,则结果为1
||:左右两边同时为0,则结果为0
4.4 条件运算符(三目运算符)
符号 | 使用方法 | 说明 |
---|---|---|
?: | a ? b : c | 如果a为真,就选择b,否则选择c |
如:result = a >= b ? a : b;
4.5 位运算符(二进制运算)
符号 | 使用方法 | 说明 |
---|---|---|
~ | ~a | 将a的每个位进行取反 |
& | a & b | 将a的每个位与b相同的位进行相与 |
| | a | b | 将a的每个位与b相同的位进行相或 |
^ | a ^ b | 将a的每个位与b相同的位进行异或 |
~(取反):0变1,1变0
&(位与):同时为1,则结果为1
|(位或):有1,则1
^(异或):相同为0不同为1
注意:如果位运算左右两边变量的位宽不同,则比较小的位宽高位补0。
4.6 移位运算符
符号 | 使用方法 | 说明 |
---|---|---|
<< | a << b | 将a左移b位 |
>> | a >> b | 将a右移b位 |
注意:两种移位运算符都用0来填补移出的空位。左移时,位宽增加;右移时,位宽不变。
如:4’b1001 << 2 = 6’b100100;
4’b1001 >> 1 = 4’b0100;
4.7 拼接符合
符号 | 使用方法 | 说明 |
---|---|---|
{} | {a,b} | 将a和b位拼接起来,作为一个新信号 |
五、运算符的优先级
运算符 | 优先级 |
---|---|
!、~ | 最高 |
*、/、% | 次高 |
+、- | | |
<<、>> | | |
<、<=、>、>= | | |
==、!=、===、>== | | |
& | | |
^、^~ | | |
| | | |
&& | | ∨ |
|| | 次低 |
? | 最低 |
注意:不清楚直接用小括号提高优先级。
六、常用关键词
关键字 | 含义 |
---|---|
module | 模块开始定义 |
input | 输入端口定义 |
output | 输出端口定义 |
inout | 双向端口定义 |
parameter | 信号的参数定义 |
wire | wire信号定义 |
reg | reg信号定义 |
always | 产生reg信号语句的关键字 |
assign | 产生wire信号语句的关键字 |
begin | 语句起始标志 |
end | 语句结束标志 |
edge/posedge/negedge | 时序电路起始标志 |
case | case语句起始标志 |
default | case语句的默认分支标志 |
endcase | case语句结束标志 |
if | if/else语句标志 |
else | if/else语句标志 |
for | for语句标志 |
endmodule | 模块结束定义 |
总结
以上就是Verilog的基础语法,因为本文只针对前期实验课程内容,而进行基础语法的筛选讲解。在后期的课程中,将会根据实验讲解Verilog中的疑点和难点。敬请期待!