case语句检查给定的表达式是否与列表中的其他表达式之一相匹配,并据此进行分支。它通常用于实现一个多路复用器。

如果要检查的条件很多,if-else结构可能不合适,因为它会综合成一个优先编码器而不是多路复用器。

一个Verilog case语句以case关键字开始,以endcase关键字结束。在括弧内的表达式将被精确地评估一次,并按其编写顺序与备选方案列表进行比较,与给定表达式匹配的备选方案的语句将被执行。一块多条语句必须分组,并在 begin 和 end 范围内。

// Here 'expression' should match one of the items (item 1,2,3 or 4)
case (<expression>)
	case_item1 : 	<single statement>
	case_item2,
	case_item3 : 	<single statement>
	case_item4 : 	begin
	          			<multiple statements>
	default 	 : <statement>
endcase

如果所有的case项都不符合给定的表达式,则执行缺省项内的语句,缺省语句是可选的,在case语句中只能有一条缺省语句。case语句可以嵌套。

如果没有符合表达式的项目,也没有给出缺省语句,执行将不做任何事情就退出case块。

下图所示的设计模块有一个2位选择信号,用于将其他三个3位输入中的一个信号连接到被调用的输出信号。根据sel的值,用case语句将正确的输入分配到输出。由于sel是一个2位信号,它可以有2^2种组合,从0到3。如果sel为3,默认语句有助于将输出设置为0。

module my_mux (input       [2:0] 	a, b, c, 		// Three 3-bit inputs
                           [1:0]	sel, 			  // 2-bit select signal to choose from a, b, c
               output reg  [2:0] 	out); 			// Output 3-bit signal
  // This always block is executed whenever a, b, c or sel changes in value
  always @ (a, b, c, sel) begin
    case(sel)
      2'b00    : out = a; 		// If sel=0, output is a
      2'b01    : out = b; 		// If sel=1, output is b
      2'b10    : out = c; 		// If sel=2, output is c
      default  : out = 0; 		// If sel is anything else, out is always 0
    endcase
endmodule

硬件原理图

通过对rtl代码进行RTL分析,得到一个表示4比1多路复用器的硬件原理图。

请看,当sel为3时,输出为零,sel为其他值时也有对应的输入。

在case语句中,只有当表达式中的每个位都与包括0、1、x和z在内的备选方案之一相匹配时,比较才会成功。在上图所示的例子中,如果sel中的任何位是x或z,默认语句将被执行,因为其他备选方案都不匹配。在这种情况下,输出将全部为0。

我们可以做下简单的仿真:

  reg  [2:0] a, b, c;
  reg  [1:0] sel;
  wire [2:0] out;
  my_mux 	m0 ( .a(a),
                .b(b),
                .c(c),
                .sel(sel),
                .out(out));
  initial begin
    $monitor ("[%0t] a=0x%0h b=0x%0h c=0x%0h sel=0b%b out=0x%0h", $time, a, b, c, sel, out);
    for (int i = 0; i < 10; i = i+1) begin
      a <= $random;
      b <= $random;
      c <= $random;
      sel <= $random;
      #10;
[0] a=0x4 b=0x1 c=0x1 sel=0bxx out=0x0
[10] a=0x3 b=0x5 c=0x5 sel=0bzx out=0x0
[20] a=0x5 b=0x2 c=0x1 sel=0bxx out=0x0
[30] a=0x5 b=0x6 c=0x5 sel=0bzx out=0x0
[40] a=0x5 b=0x4 c=0x1 sel=0bxz out=0x0
[50] a=0x6 b=0x5 c=0x2 sel=0bxz out=0x0
[60] a=0x5 b=0x7 c=0x2 sel=0bzx out=0x0
[70] a=0x7 b=0x2 c=0x6 sel=0bzz out=0x0
[80] a=0x0 b=0x5 c=0x4 sel=0bxx out=0x0
[90] a=0x5 b=0x5 c=0x5 sel=0bxz out=0x0

如果设计中的案例语句中案例项备选有x和z,结果就会大不相同。

module my_mux (input  		[2:0] 	a, b, c,
													[1:0]		sel,
							output reg	[2:0] 	out);
  // Case items have x and z and sel has to match the exact value for
  // output to be assigned with the corresponding input
  always @ (a, b, c, sel) begin
    case(sel)
      2'bxz			:	out = a;
      2'bzx			:	out = b;
      2'bxx			:	out = c;
      default 	:	out = 0;
    endcase
endmodule
[0] a=0x4 b=0x1 c=0x1 sel=0bxx out=0x1
[10] a=0x3 b=0x5 c=0x5 sel=0bzx out=0x5
[20] a=0x5 b=0x2 c=0x1 sel=0bxx out=0x1
[30] a=0x5 b=0x6 c=0x5 sel=0bzx out=0x6
[40] a=0x5 b=0x4 c=0x1 sel=0bxz out=0x5
[50] a=0x6 b=0x5 c=0x2 sel=0bxz out=0x6
[60] a=0x5 b=0x7 c=0x2 sel=0bzx out=0x7
[70] a=0x7 b=0x2 c=0x6 sel=0bzz out=0x0
[80] a=0x0 b=0x5 c=0x4 sel=0bxx out=0x4
[90] a=0x5 b=0x5 c=0x5 sel=0bxz out=0x5

有关更多case的讨论,例如casex/casez等,跳转链接:【 Verilog HDL 】case, casez, casex 之干货总结

case与if-else有什么不同?

case语句与if-else-if有两点不同。

  • 在if-else块中给出的表达式比较笼统 而在case块中,一个表达式要与多个项目相匹配。
  • 当一个表达式中存在X和Z值时,case将提供一个明确的结果。

Verilog初级教程(16)Verilog中的控制块

Verilog初级教程(15)Verilog中的阻塞与非阻塞语句

Verilog初级教程(14)Verilog中的赋值语句

Verilog初级教程(13)Verilog中的块语句

Verilog初级教程(12)Verilog中的generate块

Verilog初级教程(11)Verilog中的initial块

Verilog初级教程(10)Verilog的always块

Verilog初级教程(9)Verilog的运算符

Verilog初级教程(8)Verilog中的assign语句

Verilog初级教程(7)Verilog模块例化以及悬空端口的处理

Verilog初级教程(6)Verilog模块与端口

Verilog初级教程(5)Verilog中的多维数组和存储器

Verilog初级教程(4)Verilog中的标量与向量

Verilog初级教程(3)Verilog 数据类型

Verilog初级教程(2)Verilog HDL的初级语法

Verilog初级教程(1)认识 Verilog HDL

芯片设计抽象层及其设计风格

Verilog以及VHDL所倡导的的代码准则

FPGA/ASIC初学者应该学习Verilog还是VHDL?

参考资料及推荐关注

verilog-case-statement

simulator

个人微信公众号: FPGA LAB

在线性搜索过程,如果其一个case项表达式与括号给出的case表达式相匹配,则应执行与该case项相关的语句,并终止线性搜索。如果没有给出default项语句,且所有case项的比较都失败,则不会执行任何case语句。的比较过程case表达式任何位的"忽略"值(casez的z值,casex的 z 和 x 值)都将被视为 "忽略不计"条件,该位的值将不予考虑。verilog提供可处理x和z值的case表达式比较的原因在于它提供了一种检测此类值的机制,并减少了因其存在而产生的不确定性。 欢迎FPGA工程师加入官方微信技术群模块的结构、数据类型、变量和基本运算符号3.1.模块的结构Verilog的基本设计单元是“模块”(block)。一个模块是由两部分组成的,一部分描述接口,另一部分描述逻辑功能,即定义输入是如何影响输出的。下面举例说明:图1 模块示例m请看上面的例子: 程序模块旁边有一个电路图的符号。在许多方面,程序模块和电路图符号是一致的,这是因为电路图符号的引脚也就... case语句的功能是:在某个信号(本例的sel)取不同的值时,给另一个信号(本例的q)赋不同的值。在括弧内的表达式将被精确地评估一次,并按其编写顺序与备选方案列表进行比较,与给定表达式匹配的备选方案的语句将被执行。Verilog HDL针对电路的特性提供了case语句的其它两种形式用来处理case语句比较过程的不必考虑的情况( don’t care condition )。如果所有的case项都不符合给定的表达式,则执行缺省项内的语句,缺省语句是可选的,在case语句只能有一条缺省语句Verilogcase语句是多路决策语句,用于检查一个表达式的值是否与其他多个表达式的值相等,如果发现匹配,则进行分支跳转,执行相应语句。就像是C语言的switch语句一样,但Verilogcase语句还有以下特性:1.除了case,还支持casez和casex变种。2.case_expression和case_item可以是各种数据类型的组合:变量/常量、常量/变量、变量/变量。3.既可以实现平行结构(parallel),也可以实现优先级结构(priority)。 case (case_expression) case_item1 : case_item_statement1; case_item2 : case_item_statement2; case_item3 : case_item_statement3; case_item4 : case_item_statement4; default : case 包含在case和endcase之间的代码(也包括casex和casez)..endcasecasez语句case语句的一个变种。casez语句允许“z”和“?”值在比较时被当作不关心的值。如果“z”和“?”在case_expression和case_item,那么就不关心对应的位。“z”和“?”的等价的。注意:当编写可综合的代码时,要小心使用casez;使用casez时,最好使用?表示不关心。casex语句case语句的一个变种。casex语句允许“x。