
2.3 i f-else 与case 语句实战演练
在Verilog HDL 语言中存在如下两种分支语句。
● if-else:条件分支语句。
● case:分支控制语句。
看到它们两个,小芯总能想起一个成语:欢喜冤家。很多人问我:“在编写代码时,if-else语句和case 语句,哪个更好用呢?” 同样的逻辑,既可以通过if-else 语句实现,也可以通过case 语句实现。从这个角度来看,它们的功能好像是重复的,是 “职业竞争” 的关系,但是在很多场合,case 语句和if-else 语句总是同时出现,互相嵌套,密切配合。
2.3.1 if-else 条件分支语句
if-else 条件分支语句的作用是根据指定的判断条件是否满足来确定下一步要执行的操作。它在使用时可以采用如下三种形式。
1.第一种形式
if-else 条件分支语句的第一种形式如下:

在这种形式中没有出现else 语句,此时,if-else 条件分支语句的执行过程如下。
● 如果指定的<条件表达式>成立(也就是这个条件表达式的逻辑值为1),则执行if-else 条件分支语句内的 “语句或语句块”,并退出if-else 条件分支语句。
● 如果<条件表达式>不成立(也就是条件表达式的逻辑值为0),则不执行if-else 条件分支语句内的 “语句或语句块”,直接退出if-else 条件分支语句。
例如,编写程序1,代码如下。


得到的仿真波形如图2.3 所示。

图2.3
在执行程序1 中的代码时,会根据条件表达式 “sel==1” 是否成立来决定是否执行赋值语句 “out=a;”:如果 “sel==1” 成立,则执行赋值语句 “out=a;”,即输出信号out 得到a 的值;如果“sel==1”不成立,则不执行赋值语句 “out=a;”,即输出信号out 保持原有值不变。
2.第二种形式
if-else 条件分支语句的第二种形式如下:

第二种形式的if-else 条件分支语句将以如下方式执行。
● 如果指定的<条件表达式>成立(条件表达式的逻辑值为1),则执行if-else 条件分支语句内的 “语句或语句块1”,并退出if-else 条件分支语句。
● 如果指定的<条件表达式>不成立(条件表达式的逻辑值为0),则执行if-else 条件分支语句内的 “语句或语句块2”,并退出if-else 条件分支语句。
例如,编写程序2,代码如下。

得到的仿真波形如图2.4 所示。

图2.4
在执行程序2 中的代码时,会根据条件表达式 “sel==1” 是否成立来决定执行哪条赋值语句。
● 如果 “sel==1” 成立,则执行赋值语句 “out=a;”,将a 的值赋给输出信号out。
● 如果 “sel==1” 不成立,则执行赋值语句 “out=b;”,将b 的值赋给输出信号out。
3.第三种形式
if-else 条件分支语句的第三种形式如下:

在执行这种形式的if-else 条件分支语句时,将按照各分支语句的排列顺序对各个条件表达式是否成立做出判断,当遇到某一项的条件表达式成立时,则执行这一项所指定的语句或语句块;如果所有的条件表达式都不成立,则执行else 后的语句或语句块n。
第三种形式的if-else 条件分支语句实现了多路分支的选择、控制功能。例如,编写程序3,代码如下。


得到的仿真波形如图2.5 所示。

图2.5
如果 “sel1==1” 成立,则第一个分支项的条件表达式成立,执行 “out=a; ”语句,即将将a 的值赋给输出信号out;如果 “sel1==1” 不成立,“sel2==1” 成立,则第二个分支项的条件表达式成立,执行 “out=b;” 语句,即将b 的值赋给输出信号out;如果 “sel1==1” 不成立,“sel2==1” 也不成立,则执行 “out=c;” 语句,即将c 的值赋给输出信号out。
4.if-else 条件分支语句的嵌套使用
if-else 条件分支语句的嵌套使用方法如下:

2.3.2 case 分支控制语句
case 分支控制语句是一种用来实现多路分支控制的语句。与使用if-else 条件分支语句相比,通过case 分支控制语句实现多路分支控制显得更加方便和直观。
case 分支控制语句通常用于对微处理器指令译码功能的描述,以及对有限状态机的描述。
case 分支控制语句的示意代码如下:

控制表达式是对程序流向进行控制的信号;分支语句用于控制表达式的具体取值,在实际使用中,分支语句通常是一些常量表达式;语句块是在各个分支语句下所要执行的操作,可由单条语句构成;以关键词default 开头的语句块被称为default 分支项,是可以省略的。
Case 分支控制语句的执行过程如下:
● 若控制表达式的值等于分支语句1,则执行语句块1。
● 若控制表达式的值等于分支语句2,则执行语句块2。
● ……
● 若控制表达式的值等于分支语句n,则执行语句块n。
● 若控制表达式的值不等于任何分支语句,则执行语句块n+1。
小芯温馨提示
在执行了某一分支语句后,将会退出case 分支控制语句,终止case 分支控制语句的执行。case 分支控制语句中的各个分支语句的值必须互不相同,否则就会出现矛盾现象。
例如,编写程序4,代码如下。


得到的仿真波形如图2.6 所示。

图2.6
在执行case 分支控制语句时,控制表达式的值和分支语句之间的比较是一种 “全等比较”,也就是说,只有在分支语句和控制表达式的值完全相同(对应的每一位完全相同)的情况下,才能认为分支语句和控制表达式的值相等,对应的语句块才会被执行。
小芯温馨提示
在执行if-else 条件分支语句时,会按照优先级的顺序执行语句;在执行case 分支控制语句时,各分支语句之间无优先级之分,只要控制表达式的值和分支语句相等,就能执行对应的语句块。