Визуальная электроника

Оператор выбора case

Этот оператор последовательно проверяет выражение на совпадение значений и выполняет инструкции в соответствующих ветвях.

  • case работает с одиночными инструкциями и группами инструкций.
  • В групповых инструкциях используют блоки begin ­ end.

Синтаксис оператора case показан ниже:

case ()
    < case1 > : < инструкции >
    < case2 > : < инструкции >
    ..... default : < инструкции >
endcase

Пример case

Verilog Code:
  1. module mux (a,b,c,d,sel,y);
  2. input a, b, c, d;
  3. input [1:0] sel;
  4. output y;
  5.  
  6. reg y;
  7.  
  8. always @ (a or b or c or d or sel)
  9. case (sel)
  10. 0 : y = a;
  11. 1 : y = b;
  12. 2 : y = c;
  13. 3 : y = d;
  14. default : $display("Error in SEL");
  15. endcase
  16.  
  17. endmodule

Пример ­ case без default

Verilog Code:
  1. module mux_without_default (a,b,c,d,sel,y);
  2. input a, b, c, d;
  3. input [1:0] sel;
  4. output y;
  5.  
  6. reg y;
  7.  
  8. always @ (a or b or c or d or sel)
  9. case (sel)
  10. 0 : y = a;
  11. 1 : y = b;
  12. 2 : y = c;
  13. 3 : y = d;
  14. 2'bxx,2'bx0,2'bx1,2'b0x,2'b1x,
  15. 2'bzz,2'bz0,2'bz1,2'b0z,2'b1z : $display("Error in SEL");
  16. endcase
  17.  
  18. endmodule

Пример выше показывает, как указать несколько ветвлений в одном операторе выбора.

В Verilog оператор case выполняет сравнение с идентификацией (подобно оператору === ), можно использовать case для проверки логики значений x и z как показано в примере ниже.

Операторы casez и casex

Особые случаи case позволяют использовать логические значения x и z как "безразличные":

  • casez : Игнорирует значение z
  • casex : Игнорирует значения x и z

Пример ­ casez

Verilog Code:
  1. module casez_example();
  2. reg [3:0] opcode;
  3. reg [1:0] a,b,c;
  4. reg [1:0] out;
  5.  
  6. always @ (opcode or a or b or c)
  7. casez(opcode)
  8. 4'b1zzx : begin // Don't care about lower 2:1 bit, bit 0 match with x
  9. out = a;
  10. $display("@%0dns 4'b1zzx is selected, opcode %b",$time,opcode);
  11. end
  12. 4'b01?? : begin
  13. out = b; // bit 1:0 is don't care
  14. $display("@%0dns 4'b01?? is selected, opcode %b",$time,opcode);
  15. end
  16. 4'b001? : begin // bit 0 is don't care
  17. out = c;
  18. $display("@%0dns 4'b001? is selected, opcode %b",$time,opcode);
  19. end
  20. default : begin
  21. $display("@%0dns default is selected, opcode %b",$time,opcode);
  22. end
  23. endcase
  24.  
  25. // Testbench code goes here
  26. always #2 a = $random;
  27. always #2 b = $random;
  28. always #2 c = $random;
  29.  
  30. initial begin
  31. opcode = 0;
  32. #2 opcode = 4'b101x;
  33. #2 opcode = 4'b0101;
  34. #2 opcode = 4'b0010;
  35. #2 opcode = 4'b0000;
  36. #2 $finish;
  37. end
  38.  
  39. endmodule

Вывод симулятора

Code:
  1. @0ns default is selected, opcode 0000
  2. @2ns 4'b1zzx is selected, opcode 101x
  3. @4ns 4'b01?? is selected, opcode 0101
  4. @6ns 4'b001? is selected, opcode 0010
  5. @8ns default is selected, opcode 0000

Пример ­ casex

Verilog Code:
  1. module casex_example();
  2. reg [3:0] opcode;
  3. reg [1:0] a,b,c;
  4. reg [1:0] out;
  5.  
  6. always @ (opcode or a or b or c)
  7. casex(opcode)
  8. 4'b1zzx : begin // Don't care 2:0 bits
  9. out = a;
  10. $display("@%0dns 4'b1zzx is selected, opcode %b",$time,opcode);
  11. end
  12. 4'b01?? : begin // bit 1:0 is don't care
  13. out = b;
  14. $display("@%0dns 4'b01?? is selected, opcode %b",$time,opcode);
  15. end
  16. 4'b001? : begin // bit 0 is don't care
  17. out = c;
  18. $display("@%0dns 4'b001? is selected, opcode %b",$time,opcode);
  19. end
  20. default : begin
  21. $display("@%0dns default is selected, opcode %b",$time,opcode);
  22. end
  23. endcase
  24.  
  25. // Testbench code goes here
  26. always #2 a = $random;
  27. always #2 b = $random;
  28. always #2 c = $random;
  29.  
  30. initial begin
  31. opcode = 0;
  32. #2 opcode = 4'b101x;
  33. #2 opcode = 4'b0101;
  34. #2 opcode = 4'b0010;
  35. #2 opcode = 4'b0000;
  36. #2 $finish;
  37. end
  38.  
  39. endmodule

Вывод симулятора

Code:
  1. @0ns default is selected, opcode 0000
  2. @2ns 4'b1zzx is selected, opcode 101x
  3. @4ns 4'b01?? is selected, opcode 0101
  4. @6ns 4'b001? is selected, opcode 0010
  5. @8ns default is selected, opcode 0000

Пример сравнения case, casex и casez

Verilog Code:
  1. module case_compare;
  2.  
  3. reg sel;
  4.  
  5. initial begin
  6. #1 $display ("\n Driving 0");
  7. sel = 0;
  8. #1 $display ("\n Driving 1");
  9. sel = 1;
  10. #1 $display ("\n Driving x");
  11. sel = 1'bx;
  12. #1 $display ("\n Driving z");
  13. sel = 1'bz;
  14. #1 $finish;
  15. end
  16.  
  17. always @ (sel)
  18. case (sel)
  19. 1'b0 : $display("Normal : Logic 0 on sel");
  20. 1'b1 : $display("Normal : Logic 1 on sel");
  21. 1'bx : $display("Normal : Logic x on sel");
  22. 1'bz : $display("Normal : Logic z on sel");
  23. endcase
  24.  
  25. always @ (sel)
  26. casex (sel)
  27. 1'b0 : $display("CASEX : Logic 0 on sel");
  28. 1'b1 : $display("CASEX : Logic 1 on sel");
  29. 1'bx : $display("CASEX : Logic x on sel");
  30. 1'bz : $display("CASEX : Logic z on sel");
  31. endcase
  32.  
  33. always @ (sel)
  34. casez (sel)
  35. 1'b0 : $display("CASEZ : Logic 0 on sel");
  36. 1'b1 : $display("CASEZ : Logic 1 on sel");
  37. 1'bx : $display("CASEZ : Logic x on sel");
  38. 1'bz : $display("CASEZ : Logic z on sel");
  39. endcase
  40.  
  41. endmodule

Вывод симулятора

Code:
  1. Driving 0
  2. Normal : Logic 0 on sel
  3. CASEX : Logic 0 on sel
  4. CASEZ : Logic 0 on sel
  5.  
  6. Driving 1
  7. Normal : Logic 1 on sel
  8. CASEX : Logic 1 on sel
  9. CASEZ : Logic 1 on sel
  10.  
  11. Driving x
  12. Normal : Logic x on sel
  13. CASEX : Logic 0 on sel
  14. CASEZ : Logic x on sel
  15.  
  16. Driving z
  17. Normal : Logic z on sel
  18. CASEX : Logic 0 on sel
  19. CASEZ : Logic 0 on sel