0
1
0
0
1
1
0
0
表2:逻辑运算符真值表
逻辑运算符中“&&”和“||”的优先级别低于关系运算符,“!”高于算术运算符。逻辑运算符与其它高级语言的用法基本相似,在此不再举例说明。
1.5.5 位逻辑运算符
在Verilog语言中有7种位逻辑运算符:
1 ~ (非)
2 & (与)
3 | (或)
4 ^ (异或)
5 ^~ (同或)
6 ~& (与非)
7 ~| (或非)
位逻辑运算符对其自变量的每一位进行操作,例如,表达式A & B的结果是A和B的对应位相与的值。对具有不定值的位进行操作,视情况而定会得到不同的结果。例如:x和FALSE相与得结果x,x和TRUE相或得结果TURE。如果操作数的长度不相等,较短的操作数将用0来补位,逐位运算将返回一个与两个操作数中位宽较大的一个等宽的值。
在此需要注意的是,不要将逻辑运算符和位运算符相混淆,比如,!是逻辑非,而~是位操作的非,即按位取反,例如:对于前者!(5 = = 6)结果是TRUE,后者对位进行操作,~{1,0,1,1} = 0100。
1.5.6 一元约简运算符
约简运算符是单目运算符,也有与、或、非运算。其与、或、非运算规则类似于位运算符的与、或、非运算规则,但其运算过程不同。位运算是对操作数的相应位进行与、或、非运算,操作数是几位数则运算结果也是几位数。而约简运算则不同,约简运算是对单个操作数进行与、或、非递推运算,最后的运算结果是1位的二进制数。约简运算的具体运算过程是:1°先将操作数的第1位与第2位进行与、或、非运算;2°将运算结果与第3位进行与、或、非运算,依次类推,直至最后一位。
例如:
reg [3:0] B;
reg C;
C = &B;
相当于:
C = ( (B[0]&B[1]) & B[2] ) & B[3];
一完整的模块举例如下:
module reduction(a, out1, out2, out3, out4, out5, out6);
input [3:0] a;
output out1, out2, out3, out4, out5, out6;
reg out1, out2, out3, out4, out5, out6;
always @ (a)
begin
out1 = & a; //与约简运算
out2 = | a; //或约简运算
out3 = ~& a; //与非约简运算
out4 = ~| a; //或非约简运算
out5 = ^ a; //异或约简运算
out6 = ~^ a; //同或约简运算
end
endmodule
1.5.7 其它运算符
1 移位运算符
在Verilog HDL语言中有两种移位运算符:“<<”(左移位运算符)和“>>”(右移位运算符),方法是将第一个操作数向左(右)移,所移动的位数由第二个操作数来决定。这两种移位运算都用0来填补移出的空位。举例如下:
module shift;
reg[3:0] a, b;
initial
begin
a = 1; //a设为0001
b = (a<<2); //移位后,a的值为0100,赋给b
end
endmodule
从此例可以看出,b在移过两位后,用0来填补空出的位。
进行移位运算时应注意移位前后变量的位数,下面给出几个例子:
4’b1001<<1 = 5’b10010; 4’b1001<<2 = 6’b100100;
1<<6 = 32’b1000000; 4’b1001>> 1= 4’b0100; 4’b1001>>4 = 4’b0000;
2 条件运算符
条件运算符(:?)有三个操作数,第一个操作数是TRUE,算子返回第二个操作数,否则返回第三个操作数,条件算子可以用来实现一个选择器,例如:
module conditional(time, y);
input [2:0] time;
output [2:0] y;
reg [2:0] y;
parameter zero = 3’b000;
parameter timeout = 3’b111;
always @(time)
y = (time != timeout) ? time +1 : zero;
endmodule
嵌套的条件算子可用来实现多路选择。如:
wire [1:0] absval;
assign absval = (a>0) ? 1 : (a<0) ? 2 : 0;
3 并接运算符
Verilog HDL语言中有一个特殊的运算符:并接运算符{}。这一运算符可以将两个或更多个信号的某些位并接起来进行运算操作。其使用方法是把某些信号的某些位详细地列出来,中间用逗号分开,最后用大括号括起来表示一个整体信号,即:
{信号1的某几位,信号2的某几位,……,信号n的某几位}
例如,{a[3],b,c[2:0],4’b0100},{2'b1x,4'h7} = = = 6'b1x0111。
此外,在Verilog语言中还有一种重复操作符{{}},即将一个表达式放入双重花括号中,复制因子放在第一层括号中。它为复制一个常量或变量提供一种简便记法。例如,{3{2'b01}} === 6'b010101。
1.5.8 运算符优先级排序
运算符优先级顺序如下所示:
* / % 最高优先级
<< >>
>= < <=
= = ! = = = = ! = =
&
^ ^~
|
&& 最低优先级
将操作数和算子通过正常的优先级规则组合起来便生成表达式,该结构将会产生一个结果,这一结果是操作数的值和算子的语法含义的函数。一个合法的操作数不加任何运算符也可以被认为是一个表达式,例如一个线型的位选操作数。表达式用来计算数值,但不仅仅单独用来求值,而是构成语句或其它结构的一部分。表达式中的操作数可以是变量名(a),变量的某一位(a[i]),变量的连续数位(a[3:0]),或者是功能块调用。
1.6 控制结构
Verilog HDL语言含有丰富的控制语句,可以选择不同的控制语句生成程序代码的过程块,比如在initial和always结构块中。大部分控制语句与传统的编程语言,如C语言相似。Verilog HDL语言与C语言之间最大的区别在于,C语言中的括弧{},在Verilog中用begin和end代替,而在Verilog中括弧{}用来完成字符的位并接功能。由于大部分使用者对C语言都很熟悉,接下来的各小结对每一种结构进行举例介绍。
1.6.1 选择结构
选择结构包括if和case语句
1 if语句
Verilog HDL语言中的if语句与C语言的十分相似,使用起来也很简单。通过下例进行说明:
if (a < 0 )
begin
b = 1;
end
else
begin
b = 0;
end
2 case语句
与C语言的case语句不同,Verilog语言中,选择第一个与<表达式>的值相匹配的<数值>,并执行相关的语句,然后控制指针将转移到endcase语句之后,也就是说,与C语言不同的是,它不需要break语句。其形式如下:
case (<表达式>)
<数值>:<语句>
<数值>:<语句>
default:<语句>
endcase
下面的例子检查了1位信号的值。
case (sig)
1’bz:$display(“Signal is floating”);
1’bx:$display(“Signal is unknown”);
default:$display(“Signal is %b”, sig);
endcase
另举例如下:
module case_statement;
integer i;
initial i = 0;
always begin
$display (″i = %0d″, i );
case (i)
0: i = i + 2;
1: i = i + 7;
2: i = i - 1;
default : $stop;
endcase
end
endmodule
该模块的运行结果如下:
i = 0
i = 2
i = 1
i = 8
选择表达式要与case表达式逐位相对照,若没有事件相匹配则执行default事件,若default事件不存在,便执行case语句后的下一条语句。
1.6.2 重复结构
重复结构包括for循环语句、while循环语句、repeat重复语句和forever循环语句。
1 for 循环结构
for循环语句与C语言的for循环语句非常相似,只是Verilog中没有增1++和减1--运算符,因此,要使用i = i + 1的形式。
如下所示为for_loop的应用的简单例子:
module for_loop;
integer i;
initial
for (i = 0; i < 4; i = i + 1) begin
$display (″i = %0d (%b binary) ″, i, i);
end
endmodule
执行结果如下:
i = 0 (0 binary)
i = 1 (1 binary)
i = 2 (10 binary)
i = 3 (11 binary)
2 while循环结构
用while语句同样可以实现上例的功能,得到相同的执行结果。
module while_loop;
integer i;
initial begin
i = 0;
while (i < 4) begin
$display (″i = %d (%b binary) ″, i, i); );
i = i + 1;
end
end
endmodule
3 repeat(重复)循环结构
Verilog有两个其它编程语言中不常用的结构;repeat和下面要介绍的forever结构,下面描述的是一个等待5个时钟周期然后停止仿真的repeat循环。
module repeat_loop (clock);
input clock;
initial&n

