1、Verilog HDL基本程序结构
所有的程序都置于模块(module)框架结构内,以模块集合的形式来描述数字电路系统。
2、Verilog HDL词法构成
空白符和注释符:
空白符的功能:
分隔其他词法标识符,增强源文件的可读性。包括空格符、制表符、换行符以及换页符等。
注释符的功能:
用于解释程序段的作用、标记程序段的相关信息,增强程序的通用性。
单行注释符 “// ”,表明自“//”开始,到该行结束,都是注释。
多行段注释以“ /* ”起始,到“ */ ”结束,在段注释中不允许嵌套。
操作符:
功能描述
(1) 算术操作符—— 双目操作符,即有2个操作数。
(2) 比较操作符
—— 双目操作符,如果操作数之间的比较关系成立,则返回值为1;不成立,则返回值为0。
—— 若某个操作数的值不定,则关系是模糊的,返回值为不定值X。
(3) 逻辑操作符
(4) 位操作符—— 将操作数按位进行逻辑运算,操作数按右端对齐,位数少的操作数在高位补0。
(5) 归约操作符—— 单目操作符, 对操作数各位的值进行运算,返回1位结果值。
(6) 移位操作符
—— 双目操作符,对左侧操作数进行移位操作,移动的位数由右侧操作数指定,空位用0补全。
(7) 条件操作符—— 三目操作符
a? b: c
—— 若操作数a的逻辑值为1,则将b的值做为返回值;反之,将c的值做为返回值。
(8) 连接和复制操作符
{ 表达式1,表达式2,… }
—— 将2个或2个以上用逗号分隔的表达式按位拼接在一起;可以用常数来指定重复的次数。
数值常量:
(1) 整型数值常量—— 按进制划分的整数
——无位宽的十进制表示法,用0~9的数字序列表示,例如 – 132。
—— 定义位宽和进制的表示法
书写格式:<位长度><' 进制符号><数字>
(2) 实型数值常量
—— 浮点数,可以用十进制和科学计数法两种形式书写。
字符串:—— 双引号“ ”括起来的字符序列,必须包含在一行中,不能多行书写。例如: “abcd”
标识符:—— 赋给对象的唯一名称,可以是字母、数字、$符、下划线“_”字符的任意组合序列,必须以字母或下划线“_”开头。在Verilog HDL中,标识符区分大小写。
3、Verilog HDL行为语句
过程语句always:
功能:—— 循环执行语句,在always后面跟了一个时间控制语句,时间控制通过事件表达式(关键词“@”)实现。
语法结构:always @(敏感变量列表)
always @( a or b or s)
if (!s) y = a;
else y = b;
只要任意敏感信号发生变化,过程块将重复连续执行,持续整个过程。
串行块语句begin-end:
功能:—— 通常用来将多条语句组合在一起,使其在格式上更象一条语句。
语法结构:
begin
顺序语句1;…;顺序语句n;
end
例如:
begin
if(sel==2'b00) out=in0;
else if(sel==2'b01) out=in1;
else if(sel==2'b10) out=in2;
else if(sel==2'b11) out=in3;
else out=1'bx;
end
连续赋值语句assign:
功能:—— 给网表变量赋值,模拟组合逻辑电路。
语法结构:assign 赋值语句;
例如:
assign y = a | b;只要等号右边的表达式值发生变化,赋值行为立即执行。
条件控制语句if-else:
功能:—— 顺序执行语句,只出现在always语句中
语法结构:
if (表达式) 语句1;
else 语句2;
如果表达式值为1,则执行语句1,否则执行语句2。
分支条件控制语句case-endcase:
语法结构:
case (表达式)
选项值1: 语句1;
选项值2: 语句2;
…
default : 缺省语句;
endcase
计算表达式的值,寻找匹配的选择项,执行对应语句。如果没有匹配的选择项,则执行缺省语句。缺省语句是可选而不是必需的,不允许有多条缺省语句。
4、 Verilog HDL进程、任务和函数
进程:
在Verilog中,数字系统的行为特征可以描述为多个进程的集合。
主要特点:
(1) 进程只有两种状态,即执行状态和等待状态。
(2) 进程一般由敏感信号的变化来启动。
(3) 各个进程之间通过信号线进行通信。
多个进程之间是并发执行的,即多个always过程块、assign连续赋值语句、实例元件调用等操作都是同步执行的,与语句的编写顺序无关。
任务(task):
功能:—— 程序的模块化设计。
定义格式:
task <任务名>; // 注意无端口列表
端口及数据类型声明语句;
其他语句;
endtask
例:
task test; // 定义任务名
input in1,in2; // 定义输入端口
output out1,out2; // 定义输出端口
#1 out1=in1 & in2;
#1 out2=in1 | in2;
endtask
调用格式:
<任务名> (端口1, 端口2, …… );
函数(function)
功能:—— 程序的模块化设计,使程序结构清晰 明了,利于软件调试。
定义格式:
[例] 定义函数get0
调用格式:<函数名> (<表达式><表达式>);
[例]使用连续赋值语句调用函数get0
assign out = is_legal ? get0 (in): 1b0;
调用函数get0时,先将变量in的值赋给x,get0的返回值是in中“0”的个数。
注意:函数不能启动任务,在函数中不能包含有任何的时间控制语句,同时定义函数时至少要有一个输入参量。
5、Verilog HDL模块的描述方式
行为型描述:
—— 只描述行为特征,不涉及逻辑电路的实现, 是一种高级语言描述方式,具有很强的通用 性和有效性。
结构型描述:
—— 将硬件电路描述成分级子模块相互连接的结构,通过对各子模块间相互连接关系的描述,来说明电路的组成(实例化)。描述实体连接的结构方式,实体一般指用Verilog语言定义的基本单元(基元)。在Verilog HDL中有26个内置基元。
数据流型描述:
—— 通过 assign 连续赋值实现组合逻辑功能的描述方式。 assign能够给网表变量赋值,只要右边表达式中的操作数发生变化,都会引发重新计算,并将新计算值赋予左边的网表变量,即赋值行为会立刻发生。