实际问题中常常需要用到多分支选择,使用if语句导致内容繁琐;更明智的做法是使用case语句,case语句是一种多分支选择语句,可以方便的处理多分支选择。本文通过实际例子,讲解case语句的使用,以及case语句的变体casez和casex的使用:
目录
一、case的用法
形式:
功能:
注意:
测试:
二、casez与casex的用法
三、参考文献
一、case的用法
形式:
case(控制表达式/值)
分支表达式:执行语句
default:执行语句
endcase
功能:
自上而下,按照顺序逐个对分支表达式进行判断,如果这一分支表达式等于控制表达式的值,就执行其对应操作;均不相等时,执行default操作;
注意:
分支表达式不能重复,否则会出现冲突;
执行完某一操作后,跳出case语句;
控制表达式与多个分支表达式匹配,只执行从上至下首个匹配项(判断顺序进行,执行一次后就跳出case语句了);
测试:
设计一个四选一器件,验证case语句功能:
实现代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | `timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: guoliang CLL // // Create Date: 2020/03/02 16:51:44 // Design Name: // Module Name: case_test // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module case_test( input [1:0]sel, output reg [3:0]dout ); always@(*) begin case(sel) 2'b00:begin dout = 4'b0000; end 2'b01:begin dout = 4'b0001; end 2'b10:begin dout = 4'b0011; end 2'b11:begin dout = 4'b0111; end default:begin dout = 4'b1111; end endcase end endmodule |
测试文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | `timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: guoliang CLL // // Create Date: 2020/03/02 16:56:45 // Design Name: // Module Name: case_tsb // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module case_tsb( ); reg [1:0]sel; wire [3:0]dout; initial begin sel = 2'b00; #10 sel = 2'b10; #10 sel = 2'b11; #10 sel = 2'b01; end case_test inst1(.sel(sel),.dout(dout)); endmodule |
仿真结果如下:
对应RTL电路如下:
二、casez与casex的用法
casez进行控制表达式与分支表达式的比较时,不关注高阻态位(不管是控制表达式还是条件表达式,这些位均默认为匹配);
casex进行控制表达式与分支表达式的比较时,不关注高阻态,以及不定位(不管是控制表达式还是条件表达式,这些位均默认为匹配);
示例1:
对于case语句:
1 2 3 4 5 6 7 8 9 | case (sel) 2'b00: y = a; 2'b01: y = b; 2'bx0: y = c; 2'b1x: y = d; 2'bz0: y = e; 2'b1?: y = f; default : y = g; endcase |
对应的结果为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Result: sel y case item 00 a 00 11 g default xx g default x0 c x0 1z f 1? z1 g default |
可以看出,case可以识别出1/0/x/z,必须完全匹配才能执行对应的执行语句;反之就匹配default;
对于casez语句:
1 2 3 4 5 6 7 8 9 | casez (sel) 2'b00: y = a; 2'b01: y = b; 2'bx0: y = c; 2'b1x: y = d; 2'bz0: y = e; 2'b1?: y = f; default: y = g; endcase |
对应的结果为:
1 2 3 4 5 6 7 8 | Result: sel y case item 00 a 00 11 f 1? xx g default x0 c x0 (would have matched with z0(item 5) if item 3 is not present.) 1z d 1x (would have matched with z0(item 5) & 1?(item 6) also.) z1 b 01 (would have matched with 1?(item 6) also.) |
可以看出,casez会把z/?匹配成任意,也会把任意匹配成z/?的;
对于casex语句:
1 2 3 4 5 6 7 8 9 | casex (sel) 2'b00 : y = a; 2'b01 : y = b; 2'bx0 : y = c; 2'b1x : y = d; 2'bz0 : y = e; 2'b1? : y = f; default : y = g; endcase |
对应的结果为:
1 2 3 4 5 6 7 8 | Result: sel y case item 00 a 00 11 d 1x (would have matched with 1? also) xx a 00 (would have matched with all items) x0 a 00 (would have matched with all items except 01) 1z c x0 (would have matched with all items except 00,01) z1 b 01 (would have matched with 1x, 1? also) |
可以看出,casex会把x和z/?匹配成任意,也会把任意匹配成x和z/?的;
三、参考文献
https://www.cnblogs.com/poiu-elab/archive/2012/11/02/2751323.html