在学习Verilog HDL基本语法之前,本节先以两个简单的实例引领大家进入Verilog HDL的世界,进而对Verilog HDL有一个基本的认识。
【 例 2.1】设计一个一位半加器。
例 2.1 定义了一个名为half_adder的模块,它有a、b、so、co 4 个端口,其中a、b为输入端口,so、co为输出端口。assign so = a^b和assign co = a&b是逻辑功能的描述,表示本位和进位的表达式。其仿真波形如图 2.1 所示。
图 2.1 一位半加器仿真波形
例 2.1 的另一种描述方法如例 2.2 所示。
【 例 2.2】一位半加器的另一种描述方法。
以上两个例子只是写法不同,其描述的功能是一样的,推荐第二种描述方法。下面再介绍一个时序逻辑电路的实例。
【 例 2.3】设计一个二分频时钟电路。
例 2.3 描述了一个二分频电路模块,即每出现一个sysclk的上升沿,c_out的状态翻转一次,也就是说c_out由 0 变 1,要经历两个sysclk周期。其中c_out是中间变量,由于它在always块内被赋值,故被定义为reg类型的变量,其他变量没有单独声明,默认为wire类型。有关变量类型 2.4 节中有详细介绍。二分频模块的仿真波形如图 2.2 所示。
图 2.2 二分频电路仿真波形
(1)module的组成
从 2.3.1 节的两个例子可以看出,模块(module)是Verilog HDL结构的核心,每个模块对应电路中的逻辑实体。模块module由下面几部分组成。
1)模块声明
格式:
例如:
2)输入/输出端口声明
格式:
例如:
3)信号类型声明
对信号的数据类型进行声明。
格式:
例如:
4)逻辑功能描述
逻辑功能描述是模块module的核心,有以下几种常用的描述逻辑功能的方法:
数据流描述、结构描述、行为描述、混合描述。
有关以上 4 种描述方法举例见 2.7 节。
①Verilog HDL程序是由模块构成的。每个模块嵌套在module和endmodule之间,模块可以进行层次嵌套。
②每个Verilog HDL源文件中只有一个顶层模块,其他为子模块。
③每个模块要进行端口定义,并说明输入/输出端口,然后对模块的功能进行逻辑描述。
④模块中的时序逻辑部分在always块的内部,在always块内只能对reg型变量赋值。
⑤模块中对wire型变量的赋值必须在always块外使用assign语句,其作用是将寄存器的值传递出去。
⑥程序书写格式自由,一行可以写几条语句,一条语句也可以分多行书写。
⑦除endmodule、begin…end和fork…join语句外,每条语句和数据定义的末尾必须有分号。
⑧可用/∗……∗/或//对程序的任何部分作注释,以增强程序的可读性和可维护性。
需要注意的是,模块的名称不能使用关键字,因为这样会使Vivado等FPGA开发软件无法分析语法进行综合。