Условные операторы 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:
module simple_if(); reg latch; wire enable,din; always @ (enable or din) if (enable) begin latch <= din; end endmodule
Пример if else
Verilog Code:
module if_else(); reg dff; wire clk,din,reset; always @ (posedge clk) if (reset) begin dff <= 0; end else begin dff <= din; end endmodule
Пример вложенного if else if
Verilog Code:
module nested_if(); reg [3:0] counter; reg clk,reset,enable, up_en, down_en; always @ (posedge clk) // If reset is asserted if (reset == 1'b0) begin counter <= 4'b0000; // If counter is enable and up count is asserted end else if (enable == 1'b1 && up_en == 1'b1) begin counter <= counter + 1'b1; // If counter is enable and down count is asserted end else if (enable == 1'b1 && down_en == 1'b1) begin counter <= counter - 1'b1; // If counting is disabled end else begin counter <= counter; // Redundant code end // Testbench code initial begin $monitor ("@%0dns reset=%b enable=%b up=%b down=%b count=%b", $time, reset, enable, up_en, down_en,counter); $display("@%0dns Driving all inputs to know state",$time); clk = 0; reset = 0; enable = 0; up_en = 0; down_en = 0; #3 reset = 1; $display("@%0dns De-Asserting reset",$time); #4 enable = 1; $display("@%0dns De-Asserting reset",$time); #4 up_en = 1; $display("@%0dns Putting counter in up count mode",$time); #10 up_en = 0; down_en = 1; $display("@%0dns Putting counter in down count mode",$time); #8 $finish; end always #1 clk = ~clk; endmodule
Вывод симулятора
Code:
@0ns Driving all inputs to know state @0ns reset=0 enable=0 up=0 down=0 count=xxxx @1ns reset=0 enable=0 up=0 down=0 count=0000 @3ns De-Asserting reset @3ns reset=1 enable=0 up=0 down=0 count=0000 @7ns De-Asserting reset @7ns reset=1 enable=1 up=0 down=0 count=0000 @11ns Putting counter in up count mode @11ns reset=1 enable=1 up=1 down=0 count=0001 @13ns reset=1 enable=1 up=1 down=0 count=0010 @15ns reset=1 enable=1 up=1 down=0 count=0011 @17ns reset=1 enable=1 up=1 down=0 count=0100 @19ns reset=1 enable=1 up=1 down=0 count=0101 @21ns Putting counter in down count mode @21ns reset=1 enable=1 up=0 down=1 count=0100 @23ns reset=1 enable=1 up=0 down=1 count=0011 @25ns reset=1 enable=1 up=0 down=1 count=0010 @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:
module parallel_if(); reg [3:0] counter; wire clk,reset,enable, up_en, down_en; always @ (posedge clk) // If reset is asserted if (reset == 1'b0) begin counter <= 4'b0000; end else begin // If counter is enable and up count is mode if (enable == 1'b1 && up_en == 1'b1) begin counter <= counter + 1'b1; end // If counter is enable and down count is mode if (enable == 1'b1 && down_en == 1'b1) begin counter <= counter - 1'b1; end end endmodule