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

Условные операторы if ­ else

if − else являются инструкциями, управляющими выполнением других инструкций. В языках программирования, подобных C, if − else управляет ходом выполнения программ. В Verilog, если требуется применить условную ветвь к более чем одной инструкции, дополнительно используйте блоки begin ­ end.

Синтаксис if
if (условие)
    инструкции;

Синтаксис if−else
if (условие)
    инструкции;
else
    инструкции;

Синтаксис вложенный if−else−if
if (условие)
    инструкции;
else if (условие)
    инструкции;
    ................
    ................
else
    инструкции;

Пример простой if

Verilog Code:
  1. module simple_if();
  2.  
  3. reg latch;
  4. wire enable,din;
  5.  
  6. always @ (enable or din)
  7. if (enable) begin
  8. latch <= din;
  9. end
  10.  
  11. endmodule

Пример if ­ else

Verilog Code:
  1. module if_else();
  2.  
  3. reg dff;
  4. wire clk,din,reset;
  5.  
  6. always @ (posedge clk)
  7. if (reset) begin
  8. dff <= 0;
  9. end else begin
  10. dff <= din;
  11. end
  12.  
  13. endmodule

Пример вложенного if ­ else ­ if

Verilog Code:
  1. module nested_if();
  2.  
  3. reg [3:0] counter;
  4. reg clk,reset,enable, up_en, down_en;
  5.  
  6. always @ (posedge clk)
  7. // If reset is asserted
  8. if (reset == 1'b0) begin
  9. counter <= 4'b0000;
  10. // If counter is enable and up count is asserted
  11. end else if (enable == 1'b1 && up_en == 1'b1) begin
  12. counter <= counter + 1'b1;
  13. // If counter is enable and down count is asserted
  14. end else if (enable == 1'b1 && down_en == 1'b1) begin
  15. counter <= counter - 1'b1;
  16. // If counting is disabled
  17. end else begin
  18. counter <= counter; // Redundant code
  19. end
  20.  
  21. // Testbench code
  22. initial begin
  23. $monitor ("@%0dns reset=%b enable=%b up=%b down=%b count=%b",
  24. $time, reset, enable, up_en, down_en,counter);
  25. $display("@%0dns Driving all inputs to know state",$time);
  26. clk = 0;
  27. reset = 0;
  28. enable = 0;
  29. up_en = 0;
  30. down_en = 0;
  31. #3 reset = 1;
  32. $display("@%0dns De-Asserting reset",$time);
  33. #4 enable = 1;
  34. $display("@%0dns De-Asserting reset",$time);
  35. #4 up_en = 1;
  36. $display("@%0dns Putting counter in up count mode",$time);
  37. #10 up_en = 0;
  38. down_en = 1;
  39. $display("@%0dns Putting counter in down count mode",$time);
  40. #8 $finish;
  41. end
  42.  
  43. always #1 clk = ~clk;
  44.  
  45. endmodule

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

Code:
  1. @0ns Driving all inputs to know state
  2. @0ns reset=0 enable=0 up=0 down=0 count=xxxx
  3. @1ns reset=0 enable=0 up=0 down=0 count=0000
  4. @3ns De-Asserting reset
  5. @3ns reset=1 enable=0 up=0 down=0 count=0000
  6. @7ns De-Asserting reset
  7. @7ns reset=1 enable=1 up=0 down=0 count=0000
  8. @11ns Putting counter in up count mode
  9. @11ns reset=1 enable=1 up=1 down=0 count=0001
  10. @13ns reset=1 enable=1 up=1 down=0 count=0010
  11. @15ns reset=1 enable=1 up=1 down=0 count=0011
  12. @17ns reset=1 enable=1 up=1 down=0 count=0100
  13. @19ns reset=1 enable=1 up=1 down=0 count=0101
  14. @21ns Putting counter in down count mode
  15. @21ns reset=1 enable=1 up=0 down=1 count=0100
  16. @23ns reset=1 enable=1 up=0 down=1 count=0011
  17. @25ns reset=1 enable=1 up=0 down=1 count=0010
  18. @27ns reset=1 enable=1 up=0 down=1 count=0001

Параллельный if ­ else

В примере выше, условие (enable == 1'b1 && up_en == 1'b1) имеет высший приоритет, а условие (enable == 1'b1 && down_en == 1'b1) ­ низший. Обычно проверка сброса не включается в приоритет, так как не входит в комбинационую часть логики триггера, показанного на рисунке ниже.

Когда требуется логика с приоритетами, используются вложенные if−else инструкции. С другой стороны, если мы не хотим использовать логику с приоритетами, зная, что только один вход будет активен в любой момент времени, мы можем использовать код, приводимый ниже.

Известно, что использование приоритетов требует больше логики, чем в случае параллельных вычислений. Так что, если известно, что входы взаимно исключают друг друга, то можно писать код с параллельными условиями if.

Verilog Code:
  1. module parallel_if();
  2.  
  3. reg [3:0] counter;
  4. wire clk,reset,enable, up_en, down_en;
  5.  
  6. always @ (posedge clk)
  7. // If reset is asserted
  8. if (reset == 1'b0) begin
  9. counter <= 4'b0000;
  10. end else begin
  11. // If counter is enable and up count is mode
  12. if (enable == 1'b1 && up_en == 1'b1) begin
  13. counter <= counter + 1'b1;
  14. end
  15. // If counter is enable and down count is mode
  16. if (enable == 1'b1 && down_en == 1'b1) begin
  17. counter <= counter - 1'b1;
  18. end
  19. end
  20.  
  21. endmodule