在Verilog语法中有三种判断与分支语句,分别是if语句,case 语句,和问号?语句。它们有相似的地方,也有不同之处,下面就语法定义、使用场景、注意事项以及异同点进行描述,并以实例应用的方式一一介绍。
在Verilog语法中if 语句有如下几种形式:
1.If(…)格式
|
1 2 3 4 5 6 7 8 |
<span style="color: #993366;">if</span> (判断条件) <span style="color: #993366;">begin</span> .... .... .... <span style="color: #993366;">end </span> |
- 格式描述
if 后面跟由()括起来的判断条件,之后是由begin…end关键字括起来的顺序语句块,如果if后只跟一条执行语句,begin和end关键字可以省略。如:
|
1 2 3 4 |
<span style="color: #993366;">if</span>(a > b) <span style="color: #993366;">begin</span> c[3:0] = 5; <span style="color: #993366;">end</span> |
可以直接写成:
|
1 2 |
<span style="color: #993366;">if</span>(a > b) c[3:0] = 5; |
- if引导的语句块是顺序语句
由if和begin…end 引导的语句是顺序语句,因此if语句只能用在如always,initial,function,task等顺序过程中,不能在连续赋值语句中使用。
if 语句的含义:如果判断条件为真,则执行if之后的语句,否则不执行。
例1:错误位置使用if语句
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<span style="color: #800080;">module</span> selx ( <span style="color: #800080;"> input</span> [1:0] sel, <span style="color: #800080;"> input</span> [3:0] a,b, <span style="color: #800080;"> output</span> [3:0] c ); <span style="color: #ff0000;">if(sel) begin //错误,if语句不能直接用在并发过程中</span> <span style="color: #ff0000;"> assign c = a;</span> <span style="color: #ff0000;">end</span> <span style="color: #993366;">endmodule</span> |
例1中红色部分表示在并发过程中使用if语句是错误的。if语句只能用在顺序语句中,可以将上面的程序改写成例2所示就正确。
- 判断条件
- 判断条件一般为关系表达式、等式表达式或由逻辑符号组成复杂表达式的返回值,一般只有真/假两个值。
例2:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
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:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
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的仿真程序如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
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:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
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的仿真程序如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
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:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
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的仿真程序如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
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:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
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优先编码器
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
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 |
对应视频:

