文章目录
1、case的用法
case语句是一种多路选择结构语句,根据表达式(expression)中的值,对选项(case_item)从上到下一一进行匹配。若有选项与表达式对应,则执行该选项的表达语句(statement),并从case语句退出。若所有选项均无法匹配表达式,则执行default语句中的语句;若无default语句且所有选项均不匹配表达式,则什么也不执行。
case语句的一般结构如下:
需要注意的是:default语句虽然是可选选项(非强制性),但是在一般的开发过程中,为了避免产生锁存器LATCH,通常都会要求加上default语句。
下面是一个使用case语句的典型例子:
举例:电路会根据寄存器rega的值对下列选项进行匹配。
- 如果rega = 16'd0,则执行改选项后的执行语句----result = 10'b0111111111;然后退出case语句。
- 如果rega 不等于 16'd0,则继续搜寻下一条选项是否匹配,直到某个选项匹配表达式,然后执行该选项的执行语句后,退出case语句。
- 如果rega的值不等于这些选项中的任意一个,则执行default语句中的执行语句----result = 'bx;
虽然case语句是从第一句开始匹配直到default语句,但通常由于所有选项的互异性,所以造成了case语句成了事实上的并行语句,而不存在优先级。
此外,我们知道Verilog HDL 有四种基本的值来表示硬件电路中的电平逻辑:
- 0:逻辑 0 或 "假"
- 1:逻辑 1 或 "真"
- x 或 X:未知
- z 或 Z:高阻
那么case语句对x/z的支持如何?答案是,在case语句中x就是x,而z就是z(听起来很奇怪,需要结合后面casex/casez来理解)。
下面是一个在选项中有x、z的例子:
选项2'b0x、2'b0z、2'bx0和2'bz0均需要完全匹配才会执行对应的执行语句。比如select[1:2] = 2'b0x且flaga = 0,则result = 0。
2、casez/casex的用法
casez语句和case语句的用法非常相似,其唯一的区别在于,状态z在casez语句中不会被视为正常的z状态,而是将表达式中,标记为z的那个(或那些)bit视为不在乎(dont care)。
比如下面的例子:
选项8'b1??????? 意味着 后面7bit均不用在乎,随便是什么值都可以,只要最高位是1即可完成匹配,从而执行后面的执行语句----instruction1(ir);
casex语句和casez语句的用法非常相似,其唯一的区别在于,casex可以同时将状态x和状态z均视为不在乎(dont care)。
3、case语句的常数表达式
case表达式中的值除了是某个变量或其组合外,也可以是一个常数。
比如下面这种写法:
把表达式的值固定为了常数1即真,所以只需判断encode[2]是否为真,为真则执行$display("Select Line 2") ;为假则判断 encode[1],直到default。
写个简单的testbench验证一下,顺便看看再表达选项不为互异的情况下,case语句如何进行判断。
`timescale 1ns / 1ps //时间单位/精度
module tb_test();
reg [2:0] encode ;
initial begin
encode = 3'b0;
$display("sim start!"); //仿真开始
#100
#10 encode = 3'b100;
#10 encode = 3'b010;
#10 encode = 3'b001;
#10 encode = 3'b111; //此时三个选项均满足,观察如何执行
#10 encode = 3'b011; //此时后两个选项均满足,观察如何执行
#20 $display("sim finish!");//仿真结束
$finish;
end
always@(*)begin
case (1)
encode[2] : $display("Select Line 2") ;
encode[1] : $display("Select Line 1") ;
encode[0] : $display("Select Line 0") ;
default $display("Error: One of the bits expected ON");
endcase
end
endmodule
Vivado终端窗口打印的结果如下:
- 此时对encode赋值初值encode = 3'b0; 不满足任何一条选项,执行default语句中的执行语句,显示Error: One of the bits expected ON
- 此时对encode赋值 encode = 3'b100; 满足encode[2],执行打印语句Select Line 2
- 此时对encode赋值 encode = 3'b010; 满足encode[1],执行打印语句Select Line 1
- 此时对encode赋值 encode = 3'b001; 满足encode[0],执行打印语句Select Line 0
- 此时对encode赋值 encode = 3'b111; 满足encode[2]、encode[1]和encode[0],但由于encode[2]在最上面,所以会被先匹配到,然后执行打印语句Select Line 2(说明case还是有优先级的)
- 此时对encode赋值 encode = 3'b011; 满足encode[1]和encode[0],但由于encode[1]在encode[0]上面,所以会被先匹配到,然后执行打印语句Select Line 1(同样说明case是有优先级的)