当前位置:   article > 正文

Verilog基础语法——条件语句if-else与case_verilog if else

verilog if else

写在前面

  在Verilog语法中,常用的条件语句有if-else语句case语句,用于判断条件是否为真,并执行判断条件后面的表达式。

一、if-else语句

  if-else语句的基本语法如下:

if(条件1)
    // 表达式1...
else if(条件2)
    // 表达式2...
else // 其他条件
    // 表达式3...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

  if-else语句也可以嵌套使用,其语法如下:

if(条件1)
    if(条件2)
        // 表达式1...
    else
        // 表达式2...
else // 其他条件
    // 表达式3...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

  在使用if-else语句时,若不补全else语句以及后面的表达式,则默认在除了所列出条件以外的其他条件下,保持变量原先的值。而对于组合逻辑而言,变量保持原先的值,电路综合时会综合出锁存器Latch。比如:

// 会产生锁存器Latch(组合逻辑中)
always @(*) begin
    if(条件1)
        // 表达式1
end    
  • 1
  • 2
  • 3
  • 4
  • 5

  而在时序逻辑中,变量保持原先的值,不会产生锁存器Latch,所以对于else语句下变量保持原先的值的情况,可以不补全else语句(建议补全else条件后执行的表达式)。

// 不会产生锁存器Latch(时序逻辑中)
always @(posedge clk) begin
    if(条件1)
        // 表达式1
end    
  • 1
  • 2
  • 3
  • 4
  • 5

  如果在组合逻辑中使用if-else语句,有一种等价写法,用连续赋值语句assign进行替换。比如:

reg     [1:0]    out;

always @(*) begin
    if(a == 2'b11)
        out = 2'b00;
    else if(a == 2'b10)
        out = 2'b11;
    else
        out = 2'b01;
end 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

  可以使用三目运算符“ ?: ”进行替换,如下。需要注意的是连续赋值语句assign赋值的变量是wire型变量,而在always语句中赋值的变量是reg型变量。

wire    [1:0]    out;

assign out = (a == 2'b11) ? 2'b00 : (a == 2'b10) ? 2'b11 : 2'b01;
  • 1
  • 2
  • 3

问题一:if-else语句中各个条件是否具有优先级?各个条件的判断是串行的还是并行的?条件互斥是否存在影响?

  以下面这段代码为例,if-else语句中各个条件互斥。

// if-else(条件互斥)
module top(
    input    wire    [1:0]    din  ,
    input    wire    [3:0]    din_a,
    input    wire    [3:0]    din_b,
    input    wire    [3:0]    din_c,
    input    wire    [3:0]    din_d,
    output   reg     [3:0]    dout 
);

always @(*) begin
    if(din == 2'b00)
        dout = din_a;
    else if(din == 2'b01)
        dout = din_b;
    else if(din == 2'b10)
        dout = din_c;
    else if(din == 2'b11)
        dout = din_d;
    else
        dout = 4'b0000;
end   

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

  上述代码对应的真值表如下所示:

在这里插入图片描述

  其RTL Schematic如下图所示,可以看出这里5个条件所对应的4个MUX是串行的,存在优先级关系,其中优先级顺序为:第一级>第二级>第三级>第四级。

在这里插入图片描述

  而在FPGA内部,MUX是由LUT构成的,综合后的电路是否存在优先级关系?下图为综合后的Schematic,可以看到综合后的实际电路是并行的。

在这里插入图片描述
  这里if-else语句条件是互斥的,互斥是否会存在影响?对上述代码稍加修改(各个条件不互斥),如下:

// if-else(条件不互斥)
module top(
    input    wire    [1:0]    din  ,
    input    wire    [3:0]    din_a,
    input    wire    [3:0]    din_b,
    input    wire    [3:0]    din_c,
    output   reg     [3:0]    dout 
);

always @(*) begin
    if(din[0] == 1'b1)
        dout = din_a;
    else if(din[1] == 1'b1)
        dout = din_b;
    else
        dout = din_c;
end   

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

  上述代码对应的真值表如下所示:

在这里插入图片描述

  其RTL Schematic如下图所示,可以看出这里3个条件所对应的2个MUX同样是串行的,存在优先级关系,其中优先级顺序为:第一级>第二级。

在这里插入图片描述

  再对上述代码进行综合,综合后的电路如下。可以看出综合后的电路是并行的,不存在优先级关系。

在这里插入图片描述

  综上所述,在FPGA设计中,if-else语句综合后的电路无优先级关系,是并行执行的,与判断条件是否互斥无关。

二、case语句

  if-else语句常用于判断条件较少的情况。对于判断条件较多的情况下,使用if-else语句会显得繁琐,使用case语句会更加简洁直观。本节介绍case语句、casez语句和casex语句三者的用法。

2.1 case语句

  case语句的基本语法如下:

case(判断条件)
    条件值1: 表达式1;
    条件值2: 表达式2;
    条件值3: 表达式3;
    default: 表达式4; // 其他条件
endcase
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

  case语句中只有当判断条件与条件值完全相等时,才为真值(True),执行条件值对应的表达式。case语句的真值表如下所示:

case10xz
11000
00100
x0010
z0001

  case语句中有两点需要注意:(1)case语句没有补全default,则对于未声明的情况,变量保持原先的值。在组合逻辑中,若未声明所有情况,则对于未声明的情况,变量保持原先的值,综合时会产生锁存器Latch。而在时序逻辑中,对于未声明的情况,变量保持原先的值,综合出来的是寄存器;(2)case语句中各个状态之间需要互斥,若各个状态不互斥,则比较电路的输出结果可能是不定态x。

问题: case语句是否具有优先级?是串行还是并行?

  同样的,将前面if-else示例中的if-else语句替换为case语句,如下:

// case(条件互斥)
module top(
    input    wire    [1:0]    din  ,
    input    wire    [3:0]    din_a,
    input    wire    [3:0]    din_b,
    input    wire    [3:0]    din_c,
    input    wire    [3:0]    din_d,
    output   reg     [3:0]    dout 
);

always @(*) begin
    case(din)
        2'b00: dout = din_a;
        2'b01: dout = din_b;
        2'b10: dout = din_c;
        2'b11: dout = din_d;
        default : dout = 4'b0000;
    endcase
end   

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

  其RTL Schematic如下图所示,可以看到case对应的各个条件之间无优先级关系,是并行的。

在这里插入图片描述
  综合后的电路如下图所示,是并行的。
在这里插入图片描述

  综上所述,case语句的各个条件之间无优先级关系,是并行的。

2.2 casez语句

  casez语句的基本语法如下:

casez(判断条件)
    条件1: 表达式1;
    条件2: 表达式2;
    条件3: 表达式3;
    default: 表达式4; // 其他条件
endcase
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

  casez语句的语法与case语句一致,但是其真值表不一致,如下表所示。

casez10xz
11001
00101
x0011
z1111

  在casez语句中,将高阻态z视为不关心的状态,即在进行比较时,高阻态z与任意状态的比较结果(==)均为真值1(True)。

2.3 casex语句

  casex语句的基本语法如下:

casex(判断条件)
    条件1: 表达式1;
    条件2: 表达式2;
    条件3: 表达式3;
    default: 表达式4; // 其他条件
endcase
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

  casex语句的真值表,如下表所示。在casex语句中将高阻态z和不定态x都视为不关心的状态,即在进行比较时,高阻态z、不定态x与任意状态的比较结果(==)均为真值1(True)。

casex10xz
11011
00111
x1111
z1111

写在后面

  在本文中,我们学习了if-else语句和case语句(case/casez/casex)的基本用法以及两者之间的区别。通过实验对比if-else语句与case语句综合后的电路,结果表明,两种条件语句中的各个条件不存在优先级关系,综合后的电路是并行的。


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/648990
推荐阅读
相关标签