VHDL If, Else If, or Else Statement
Quick Syntax
PROC_IF_ELSIF_ELSE : process (clk)
begin
if rising_edge(clk) then
if input_sel = "00" then
output <= input(0);
elsif input_sel = "01" then
output <= input(1);
else
output <= '0';
end if;
end if;
end process;
Purpose
The if statement is one of the most commonly used things in VHDL. Typically, you'll have at least one if statement in a process to make it clocked on a rising or falling edge. Then you can have multiple layers of if statements to implement the logic that you need inside that first clocked statement.
Although not required, you can also use the else if (elsif in VHDL) and/or the else. It's proper design practice to always have an else (other than the clocked if statement of course) so that you cover all logic states in your design.
Also, the word latch is a bit of a dirty word in FPGA design these days. A latch is usually created when you use an if statement that is not clocked and that is based on an input signal to drive an output. Here's an example:
PROC_LATCH : process (input_sel,input)
begin
if input_sel = "00" then
output <= input(0);
end if;
end process;
This latch inference is a big no no in digital design. If you add a clocked if statement right before, then instead it's considered a register and should be fine. Ideally though, you can prevent latches by either making it clocked, or adding an else to the statement so that all cases are covered all of the time.
Here's the proper way to prevent a latch:
PROC_NOT_A_LATCH : process (input_sel,input)
begin
if input_sel = "00" then
output <= input(0);
else
output <= '0';
end if;
end process;
OR using a clock alone will prevent it, but let's throw in an else for good design practice as well:
PROC_NOT_A_LATCH : process (clk)
begin
if rising_edge(clk) then
if input_sel = "00" then
output <= input(0);
else
output <= '0';
end if;
end if;
end process;
Examples
Here's an example of a counter that goes from 0 to 127 and then rolls back over to 0, and we need the output to be high several clocks long at the end of the counter's range:
PROC_COUNTER : process (clk)
begin
if rising_edge(clk) then
if reset = '1' then
output <= '0';
count <= 0;
else
if count = 120 then
output <= '1';
count <= count + 1;
elsif count = 127 then
output <= '0';
count <= 0;
else
count <= count + 1;
end if;
end if;
end if;
end process;
Best Practices
1. If statements are your bread and butter, use them well.
2. Multiple layers of if statements are allowed and commonly used.
3. Don't let your if statement get too crazy big. Consider using case instead for bigger needs, as they are easier to code.
4. Try to design your if statements where you always use an else to catch all other situations. It's good design and is a must if your if statement is not clocked to prevent a latch.