欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Verilog初级教程(17)Verilog中的case语句

程序员文章站 2022-07-14 22:38:49
...

前言

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>
	        			end
	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
  end
endmodule

硬件原理图

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

Verilog初级教程(17)Verilog中的case语句

请看,当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;
    end
  end
[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
  end
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

交个朋友