硬件描述语言(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 标准。
硬件描述语言主要包括:Verilog、VHDL、SystemVerilog。
Verilog HDL拥有广泛的设计群体,成熟的资源也比 VHDL 丰富,语言从C编程语言中继承了多种操作符和结构,对于熟悉C语言的同学,学习verilog时上手会很快。
超高速集成电路硬件描述语言(Very High Speed Integrated Circuit Hardware Description Language,VHDL)是一种标准化程度较高的硬件描述语言,其语言特点包括:语法严谨、结构规范、移植性强、数据类型丰富。除此之外VHDL支持层次结构设计,独立于器件和设计平台,程序复用性强。
SystemVerilog结合了来自 Verilog、VHDL、C++的概念,将硬件描述语言与现代的高层级验证语言结合了起来。所以SystemVerilog有上述两种语言和计算机高级语言的特征。
建议学习Verilog HDL的原因:
Verilog数字进制格式包括二进制(binary)、八进制(octal)、十进制(decimal)和十六进制(hexadecimal)。一般常用的为二进制、十进制和十六进制。
注意:如果数值未表明位宽和进制,则:默认为32位宽的十进制数字(32’d),常见写法:16’b1001_1010_1010_1001=16’h9AA9
标识符:用于定义模块名、端口名、信号名等(就是起个名字而已)。标识符命名规则:
例子:
在Verilog中,主要数据类型:
1. 寄存器数据类型(register)
2. 线网数据类型(wire)
3. 参数数据类型(parameter)
4. 整型(integer)
注意:真正在数字电路中起作用的数据类型是寄存器数据类型和线网数据类型。
寄存器表示一个抽象的数据存储单元,通过赋值语句可以改变寄存器存储的值 ,寄存器数据类型的关键字是reg,reg类型数据的默认初始值为不定值x。
如: reg [9:0] delay_cnt; //双斜杠表示注释,不参与编译
reg key_reg;
reg类型的数据只能在always语句和initial语句中被赋值。如果该过程语句描述的是时序逻辑,即always语句带有时序时钟信号,则该寄存器变为对应为触发器;如果该过程语句描述的是组合逻辑,即always语句不带有时钟信号,则该寄存器变为对应硬件连线。
参数其实就是一个常量,在Verilog HDL中用parameter定义常量。我们可以一次定义多个参数,参数与参数之间需要用逗号(,)隔开。每个参数定义的右边必须是一个常数表达式。
如: parameter H_FRONT = 11’d11; //行显示前沿
parameter H_BACK = 11’d2; //行显示后沿
参数型数据常用于定义状态机的状态、数据位宽和延迟大小等。采用标识符来表示一个常量可以提高程序的可读性和可维护性。在模块调用时,可通过参数传递来改变被调用模块中已定义的参数。
Verilog中的操作符按照功能分为以下几种类型:
符号 | 使用方法 | 说明 |
---|---|---|
+ | a + b | a加上b |
- | a - b | a减去b |
* | a * b | a乘以b |
/ | a / b | a除以b |
% | a % b | a模除b |
注:除法运算(/):整数与整数相除的结果为整数
符号 | 使用方法 | 说明 |
---|---|---|
> | a > b | a大于b |
< | a < b | a小于b |
>= | a >= b | a大于等于b |
<= | a <= b | a小于等于b |
== | a == b | a等于b |
!= | a != b | a不等于b |
符号 | 使用方法 | 说明 |
---|---|---|
! | !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
符号 | 使用方法 | 说明 |
---|---|---|
?: | a ? b : c | 如果a为真,就选择b,否则选择c |
如:result = a >= b ? a : b;
符号 | 使用方法 | 说明 |
---|---|---|
~ | ~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。
符号 | 使用方法 | 说明 |
---|---|---|
<< | a << b | 将a左移b位 |
>> | a >> b | 将a右移b位 |
注意:两种移位运算符都用0来填补移出的空位。左移时,位宽增加;右移时,位宽不变。
如:4’b1001 << 2 = 6’b100100;
4’b1001 >> 1 = 4’b0100;
符号 | 使用方法 | 说明 |
---|---|---|
{} | {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中的疑点和难点。敬请期待!