Verilog HDL程序由模块组成
一个完整的模块由模块端口定义和模块内容组成
模块内容包括I/O声明,信号类型声明和功能表述
基本结构
module 模块名(端口定义);
I/O声明; //代码
功能描述; //代码
endmodule
语法:
模块端口定义用来声明设计模块的输入/输出端口
格式:module 模块名 (端口1,端口2,端口3,···) ;
模块的端口是设计实体的对外引脚,是使用时外界可以看到的部分,多个端口之间用逗号
模块内容用于对信号的I/O状态及信号类型进行声明,并描述模块的功能
模块的I/O声明用来声明各端口信号流动方向,包括输入,输出,双向
格式:
输入声明
信号位宽为1位,声明格式:input 端口1,端口2,端口3,.....
信号位宽大于1位,声明格式:input[msb:lsb] 端口1,端口2,端口3,....
输出声明
信号位宽为1位,声明格式:output 端口1,端口2,端口3,....
信号位宽大于1位,声明格式: output[msb,lsb] 端口1,端口2,端口3,....
输入/输出声明
inout
信号类型声明用来说明电路的功能描述中所用信号的数据类型
常用的信号类型有wire(连线型)
,reg(寄存器型)
,整型(integer)
,实型(real)
,时间型(time)
功能描述是Verilog HDL程序的主要部分,在电路上相当于器件的内部结构
元件名 实例化后元件名(输入/输出端)
Verilog HDL中共有19种数据类型
程序运行过程中,值不能改变的量称为常量,分为三种:整型,实型,字符串型
整型常量格式为:<位宽>'<进制><数值>
位宽:为对应的二进制宽度
进制:二进制,十进制,八进制,十六进制
数值:
x表示未知,z表示高阻
实型数可以用十进制计数法和科学计数法表示
科学计数法标志为e/E,例如6E-2表示0.06
字符串是用双引号括起来的字符序列,它必须写在同一行
字符串中的每个字符都是以ASCII码的进行存放的
用parameter定义常量,即定义一个标识符代表一个常量,称为参数常量或符号常量
格式:parameter 标识符 = 表达式/常量
程序运行过程中,其值可以改变的量称为变量
wire是网络数据类型之一,表示结构实体之间的物理连接
网络类型变量不能储存值,而且必须受到驱动器驱动,没有驱动器连接到变量上时其值为高阻值
输入/输出信号默认自动定义为wire型
定义格式:wire[msb:lsb] 变量1,变量2,变量3,.....
wire为定义符,msb与lsb表示变量的最高位和最低位的编号,位宽由其决定
如果不指定位宽,则位宽默认为1
定义多个变量时,用逗号隔开
reg型为寄存器型,是数据存储单元的抽象,对应的是具有状态保持功能的电路元件
reg型变量只能在在always
和initial
块中被赋值
若reg型变量未被初始化,则其值为未知x
reg型与wire型变量的区别是:wire型需要持续驱动,而reg型保持保持最后一次赋值
定义格式:reg[msb:lsb] 变量1,变量2,变量3,....
memory型为存储器型,通过建立reg型数组描述
定义格式:reg[msb:lsb] 存储单元 [n:m]...
[n:m]表示存储单元的编号范围
integer型是32位带符号整型变量,用于对循环控制变量的说明,不可综合,不与任何物理电路相对应
定义格式:integer 变量.....
time型用于存储和处理时间,是64位无符号数
定义格式:time 变量....
real型是64位符号实型变量,用于存储和处理实型数据
定义格式:real 变量.....
+
加法运算符或正值运算符-
减法运算符或负值运算符*
乘法运算符/
除法运算符%
取模运算符&&
逻辑与||
逻辑或!
逻辑非逻辑运算符操作的结果为0或1
>
,>=
,<
,<=
==
逻辑相等!=
逻辑不等===
逻辑全等!==
非全等操作数中某些位可能是x或z,这样用==
比较的结果就是x
===
运算符按位进行比较,每一位都相等才会判断为相等
位运算符即对两个数按位进行逻辑运算
位数不同时,在位数少的数的高位自动补0
赋值语句分为两种:连续赋值语句和过程赋值语句
连续赋值语句用来驱动wire型变量,且变量必须事先定义
只要输入端操作数发生变化,该语句就重新计算并刷新赋值结果
用来描述组合逻辑
连续赋值语句格式:`assign #(延时量)wire 型变量名 = 赋值表达式
含义:只要右边赋值表达式中有变量发生变化,就重新计算表达式的值,新结果在指定的延时时间单位以后赋值给wire型变量,不指定延时量则默认为0
过程赋值语句在initial
或always
语句块内赋值
对于reg,memory integer,time,real型变量赋值
这些变量将在下一次赋值之前保持原来的值
分为两类:阻塞赋值和非阻塞赋值
阻塞赋值
赋值符:“=”,在语句结束时完成赋值操作
格式:变量 = 赋值表达式
非阻塞赋值
赋值符:“<=”,在块结束时才完成赋值操作
格式:变量 <= 赋值表达式
区别:非阻塞语句的赋值时并行执行的
阻塞赋值与非阻塞赋值区别如下
code1:
r1 = 1;
r2 = 2;
r3 = 3;
r2 = r1;
r3 = r2;
//该段程序执行结果为:r1 = 1,r2 = 1,r3 = 1
code2:
r1 = 1;
r2 = 2;
r3 = 3;
r1 <= r3
r2 <= r1
r3 <= r2
//该段程序执行结果为:r1 = 3, r2 = 1 , r3 = 2
Verilog HDL提供了3种形式的if语句
第一种:
if(表达式)
语句
第二种:
if(表达式)
语句1
else
语句2
第三种
if(表达式1)
语句1
else if (表达式2)
语句2
else if (表达是3)
语句3
....
else
语句 n
case语句是一种多分支语句
格式:
case (控制表达式)
分支项表达式 1:语句1
....
default:语句n
endcase
Verilog HDL中有四类循环语句,分别为
forever循环语句用于连续执行过程,不能独立写在程序中,必须写在initial
块中
格式:forever 语句
常用于产生周期性的波形
repeat循环语句是用于执行指定循环次数的过程语句
格式:repeat(表达式) 语句
repeat表达式通常为常量表达式,表示循环次数
如果循环计数表达式的值不确定,即为X或Z时,循环次数为0
循环执行直到指定条件为假,与C语言中while语句类似
格式:while 语句
**如果条件为X或Z,则按假处理
与C语言中for循环语句类似
格式:for(初值表达式; 条件; 循环变量增值) 语句
Verilog HDL中任何过程模块都从属于四种结构说明语句
initial,always,task,function
initial语句常用于对各变量的初始化
一个程序模块中可以有多个initial语句
所有initial语句在程序&一开始时同时执行,并且只执行一次
格式:initial 语句
一个程序可以有多个always语句,在程序一开始执行,当敏感事件列表有条件满足时,运行一次语句
格式:always @(敏感事件列表) 语句
敏感事件列表:作用是激活always语句,可以是电平触发,边沿触发,可以是单个事件或是多个事件
多个事件用or连接
如果敏感事件是电平信号则直接给出信号名
如果敏感事件是边沿信号,则分为上升沿和下降沿
上升沿触发的信号前加关键字posedge,下降沿触发信号前加关键字negedge
task说明语句定义任务,类似高级语言中的字程序,用来单独完成某项任务,并被其他模块或其他任务调用
任务定义语句:
task 任务名
端口声明语句
类型声明语句
语句
endtask
任务调用语句:
任务名 (端口名列表)
注意:
function说明语句用来定义函数。函数类似高级语言中的函数,用来单独完成某项具体的操作。
函数可以作为一个表达式中的一个操作数,也可以被模块,任务或其他函数调用
函数调用有一个返回值
函数语句定义:
function(返回值的类型或范围) 函数名
端口声明语句;
类型声明语句;
语句
endfunction
//返回值的类型或范围是可选项,若缺省,则返回值为一位寄存器类型的数据
函数的调用:
函数名(端口名列表)
函数与任务的区别:
返回值
函数只能有一个返回值,任务可以有多个或没有返回值
函数的返回值是通过函数名返回的,任务的返回值是通过输出端口传递的
输入变量
函数至少有一个输入变量,任务可以多个任何类型的变量或没有
仿真时间
调用