Оператор выбора case
Этот оператор последовательно проверяет выражение на совпадение значений и выполняет инструкции в соответствующих ветвях.
- case работает с одиночными инструкциями и группами инструкций.
- В групповых инструкциях используют блоки begin end.
Синтаксис оператора case показан ниже:
case ()
< case1 > : < инструкции >
< case2 > : < инструкции >
..... default : < инструкции >
endcase
Пример case
Verilog Code:
module mux (a,b,c,d,sel,y); input a, b, c, d; input [1:0] sel; output y; reg y; always @ (a or b or c or d or sel) case (sel) 0 : y = a; 1 : y = b; 2 : y = c; 3 : y = d; default : $display("Error in SEL"); endcase endmodule
Пример case без default
Verilog Code:
module mux_without_default (a,b,c,d,sel,y); input a, b, c, d; input [1:0] sel; output y; reg y; always @ (a or b or c or d or sel) case (sel) 0 : y = a; 1 : y = b; 2 : y = c; 3 : y = d; 2'bxx,2'bx0,2'bx1,2'b0x,2'b1x, 2'bzz,2'bz0,2'bz1,2'b0z,2'b1z : $display("Error in SEL"); endcase endmodule
Пример выше показывает, как указать несколько ветвлений в одном операторе выбора.
В Verilog оператор case выполняет сравнение с идентификацией (подобно оператору === ), можно использовать case для проверки логики значений x и z как показано в примере ниже.
Операторы casez и casex
Особые случаи case позволяют использовать логические значения x и z как "безразличные":
- casez : Игнорирует значение z
- casex : Игнорирует значения x и z
Пример casez
Verilog Code:
module casez_example(); reg [3:0] opcode; reg [1:0] a,b,c; reg [1:0] out; always @ (opcode or a or b or c) casez(opcode) 4'b1zzx : begin // Don't care about lower 2:1 bit, bit 0 match with x out = a; $display("@%0dns 4'b1zzx is selected, opcode %b",$time,opcode); end 4'b01?? : begin out = b; // bit 1:0 is don't care $display("@%0dns 4'b01?? is selected, opcode %b",$time,opcode); end 4'b001? : begin // bit 0 is don't care out = c; $display("@%0dns 4'b001? is selected, opcode %b",$time,opcode); end default : begin $display("@%0dns default is selected, opcode %b",$time,opcode); end endcase // Testbench code goes here always #2 a = $random; always #2 b = $random; always #2 c = $random; initial begin opcode = 0; #2 opcode = 4'b101x; #2 opcode = 4'b0101; #2 opcode = 4'b0010; #2 opcode = 4'b0000; #2 $finish; end endmodule
Вывод симулятора
Code:
@0ns default is selected, opcode 0000 @2ns 4'b1zzx is selected, opcode 101x @4ns 4'b01?? is selected, opcode 0101 @6ns 4'b001? is selected, opcode 0010 @8ns default is selected, opcode 0000
Пример casex
Verilog Code:
module casex_example(); reg [3:0] opcode; reg [1:0] a,b,c; reg [1:0] out; always @ (opcode or a or b or c) casex(opcode) 4'b1zzx : begin // Don't care 2:0 bits out = a; $display("@%0dns 4'b1zzx is selected, opcode %b",$time,opcode); end 4'b01?? : begin // bit 1:0 is don't care out = b; $display("@%0dns 4'b01?? is selected, opcode %b",$time,opcode); end 4'b001? : begin // bit 0 is don't care out = c; $display("@%0dns 4'b001? is selected, opcode %b",$time,opcode); end default : begin $display("@%0dns default is selected, opcode %b",$time,opcode); end endcase // Testbench code goes here always #2 a = $random; always #2 b = $random; always #2 c = $random; initial begin opcode = 0; #2 opcode = 4'b101x; #2 opcode = 4'b0101; #2 opcode = 4'b0010; #2 opcode = 4'b0000; #2 $finish; end endmodule
Вывод симулятора
Code:
@0ns default is selected, opcode 0000 @2ns 4'b1zzx is selected, opcode 101x @4ns 4'b01?? is selected, opcode 0101 @6ns 4'b001? is selected, opcode 0010 @8ns default is selected, opcode 0000
Пример сравнения case, casex и casez
Verilog Code:
module case_compare; reg sel; initial begin #1 $display ("\n Driving 0"); sel = 0; #1 $display ("\n Driving 1"); sel = 1; #1 $display ("\n Driving x"); sel = 1'bx; #1 $display ("\n Driving z"); sel = 1'bz; #1 $finish; end always @ (sel) case (sel) 1'b0 : $display("Normal : Logic 0 on sel"); 1'b1 : $display("Normal : Logic 1 on sel"); 1'bx : $display("Normal : Logic x on sel"); 1'bz : $display("Normal : Logic z on sel"); endcase always @ (sel) casex (sel) 1'b0 : $display("CASEX : Logic 0 on sel"); 1'b1 : $display("CASEX : Logic 1 on sel"); 1'bx : $display("CASEX : Logic x on sel"); 1'bz : $display("CASEX : Logic z on sel"); endcase always @ (sel) casez (sel) 1'b0 : $display("CASEZ : Logic 0 on sel"); 1'b1 : $display("CASEZ : Logic 1 on sel"); 1'bx : $display("CASEZ : Logic x on sel"); 1'bz : $display("CASEZ : Logic z on sel"); endcase endmodule
Вывод симулятора
Code:
Driving 0 Normal : Logic 0 on sel CASEX : Logic 0 on sel CASEZ : Logic 0 on sel Driving 1 Normal : Logic 1 on sel CASEX : Logic 1 on sel CASEZ : Logic 1 on sel Driving x Normal : Logic x on sel CASEX : Logic 0 on sel CASEZ : Logic x on sel Driving z Normal : Logic z on sel CASEX : Logic 0 on sel CASEZ : Logic 0 on sel