问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

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

创作时间:
作者:
@小白创作中心

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

引用
CSDN
1.
https://blog.csdn.net/qq_42224089/article/details/133690277

Verilog基础语法——条件语句case、if-else

一、if-else语句

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

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

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

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

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

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

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

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

如果在组合逻辑中使用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 

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

wire    [1:0]    out;
assign out = (a == 2'b11) ? 2'b00 : (a == 2'b10) ? 2'b11 : 2'b01;

问题一: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

其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

其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

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

case
1
0
x
z
1
1
0
0
0
0
0
1
0
0
x
0
0
1
0
z
0
0
0
1

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

同样的,将前面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

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

综合后的电路如下图所示,是并行的。

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

2.2 casez语句

casez语句的基本语法如下:

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

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

casez
1
0
x
z
1
1
0
0
1
0
0
1
0
1
x
0
0
1
1
z
1
1
1
1

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

2.3 casex语句

casex语句的基本语法如下:

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

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

casex
1
0
x
z
1
1
0
1
1
0
0
1
1
1
x
1
1
1
1
z
1
1
1
1

总结

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

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号