在Verilog语法中有三种判断与分支语句,分别是if语句,case 语句,和问号?语句。它们有相似的地方,也有不同之处,下面就语法定义、使用场景、注意事项以及异同点进行描述,并以实例应用的方式一一介绍。
在Verilog语法中if 语句有如下几种形式:
1.If(…)格式
if (判断条件) begin .... .... .... end
- 格式描述
if 后面跟由()括起来的判断条件,之后是由begin…end关键字括起来的顺序语句块,如果if后只跟一条执行语句,begin和end关键字可以省略。如:
if(a>b) begin c[3:0] = 5; end
可以直接写成:
if(a>b)
c[3:0] = 5;
- if引导的语句块是顺序语句
由if和begin…end 引导的语句是顺序语句,因此if语句只能用在如always,initial,function,task等顺序过程中,不能在连续赋值语句中使用。
if 语句的含义:如果判断条件为真,则执行if之后的语句,否则不执行。
例1:错误位置使用if语句
module selx ( input [1:0] sel, input [3:0] a,b, output [3:0] c ); if(sel) begin //错误,if语句不能直接用在并发过程中 assign c = a; end endmodule
例1中红色部分表示在并发过程中使用if语句是错误的。if语句只能用在顺序语句中,可以将上面的程序改写成例2所示就正确。
- 判断条件
- 判断条件一般为关系表达式、等式表达式或由逻辑符号组成复杂表达式的返回值,一般只有真/假两个值。
例2:
module selx ( input sel, input [3:0] a, b, output reg [3:0] c ); always@(*) if(sel) begin c = a; end endmodule
该程序在sel为1时执行c=a; 否则该语句不被执行,而c将维持原值不变。
注: if(sel)等效为if(sel==1’b1),实际判断条件为等式表达式。
2. 双重选择结构if …else…
如果有双重选择,则需要使用if…else…结构。
例3:
module selx ( input sel, input [3:0] a, b, output reg [3:0] c ); always@(*) if(sel) c = a; else c = b; endmodule
例3中的行为解释如下:如果sel为1,则a赋值给c,否则b赋值给c。
注意在仿真时sel的值为X时,将会按照false进行处理,这一点在Modelsim仿真时可以得到验证,因此if语句将会阻止 ‘X’的传递。下面加上激励程序,观察仿真结果。
例3的仿真程序如下:
module top_sim ( ); reg sel; reg [3:0] a,b; wire [3:0] c; initial begin sel = 0; a = 1; b = 2; #10 sel = 1; #10 sel = 1'bX; end selx selx_dut ( .sel (sel), .a (a), .b (b), .c (c) ); endmodule
从图1中可以看出在判断语句中,如果判断语句的结果为’x’或’Z’,也是判断为假的(false)。
当判断表达式为向量时的情况, 参照例4。
例4:
module selx ( input [1:0] sel, input [3:0] a, b, output reg [3:0] c ); always@(*) if(sel) c = a; else c = b; endmodule
例4的仿真程序如下:
module ( ); reg [1:0] sel; reg [3:0] a,b; wire [3:0] c; initial begin sel = 0; a = 1; b = 2; #10 sel = 2'b01; #10 sel = 2'b10; #10 sel = 2'b11; #10 sel = 2'b0x; #10 sel = 2'b1x; #10 sel = 2'bx0; #10 sel = 2'bx1; #10 sel = 2'bxx; end selx selx_dut ( .sel (sel), .a (a), .b (b), .c (c) ); endmodule
仿真结果如下:
图2
由图2可见,如果表达式的结果为向量,首先将sel按位或运算,即等效为if(|sel),如果sel中含有’X’或’Z’, 先按位或处理 ‘x’或’z’,再判断。
或者也可以这样理解,即向量中各个位的组合有全0值即为假,否则为真。
如”0x”组合为00,01两种,有“00” 组合,因此为假。
同样“x0″的两种组合为”00″,”10″也包含”00″ 组合,因此也为假。
而”1x”的组合为”10″,”11″,因此结果判断为真。请自行分析”x1″,”xx”的情况。
3.多重分支结构If…else if…else if …else…
如果分支多于两个则可以选择多重分支结构。多重分支结构用于判断条件比较多的情况,如果不能罗列所有条件,else将执行所有没有列出的条件。
例5:
module selx ( input [1:0] sel, input [3:0] a, b, m, n, output reg [3:0] c ); always@(*) if(sel==0) c = a; else if(sel==1) c = b; else if(sel==2) c = m; else c = n; endmodule
例5的仿真程序如下:
module tb ( ); reg [1:0] sel; reg [3:0] a,b; wire [3:0] c; initial begin sel = 0; a = 1; b = 2; m = 3; n = 4; #10 sel = 2'b01; #10 sel = 2'b10; #10 sel = 2'b11; #10 sel = 2'b0x; #10 sel = 2'b1x; #10 sel = 2'bx0; #10 sel = 2'bx1; #10 sel = 2'bxx; end selx selx_dut ( .sel (sel), .a (a), .b (b), .m (m), .n (n), .c (c) ); endmodule
例5中,如果sel!=0,1,2三个值,其它的条件都会执行c=n; 如if(sel==2’bxx)等。
- 程序中else是可选的,此时如果不满足if…else if…条件时,不执行任何代码,变量的值也保持不变。
如果将例5改成例6,则在if(sel==2’bxx)成立时,变量c的值将保持不变。
例6:
module selx ( input [1:0] sel, input [3:0] a, b, m, n, output reg [3:0] c ); always@(*) if(sel==0) c = a; else if(sel==1) c = b; else if(sel==2) c = m; endmodule
- if语句是有优先顺序的,也就说在if…else if …的结构中if…的优先级(level of precedence ) 高于else if…,而else if…的优先级又高于之后的else if….或else…。因此if语句更适合描述含有优先级的电路。
例7:利用有优先级功能的if语句描述74LS148 8/3优先编码器
module M74ls148
(
input nst,
input [7:0] nin,
output [2:0] y,
output yex,
output ys
);
always@(*)
begin
if(nst)
begin
y = 3'b111;
yex = 1'b1;
ys = 1'b1;
end
else
begin
if( !nin[7] ) y = 3'b000;
else if (!nin[6]) y = 3'b001;
else if (!nin[5]) y = 3'b010;
else if (!nin[4]) y = 3'b011;
else if (!nin[3]) y = 3'b100;
else if (!nin[2]) y = 3'b101;
else if (!nin[1]) y = 3'b110;
else if (!nin[0]) y = 3'b111;
else y = 3'b111;
if(~nin)
begin
yex = 1'b0;
ys = 1'b1;
end
else
begin
yex = 1'b1;
ys = 1'b0;
end
end
end
endmodule