0
votes

I use VHDL for a few months and I sometimes build that kind of process with non-nested if statements when I want some conditions to be evaluated sequentially :

    process(clk)
    begin
        if rising_edge(clk) then
            if CONDITION1 then
                (some instructions)
            end if;

            if CONDITION2 then
                (some instructions)
            end if;
        end if;
    end process;

It seems to work well in both simulation and synthesis, but I hardly ever see that kind of structure when looking for examples on the web. I had doubts about the sequential execution of those statements but the IEEE Standard VHDL Language Reference Manual Std 1076-2008 states :

Sequential statements are used to define algorithms for the execution of a subprogram or process; they execute in the order in which they appear.

And the if statement is in the list of sequential statements.

Why can't I find more examples of this? Is this a bad practice?

1
I would recommend not doing it. You can always replace the second if with either an elsif or an else. Why do I recommend not doing it? Because there is a chance that your synthesiser thinks that there are circumstances where neither CONDITION1 or CONDITION2 is true so it puts latches in, even if they are not necessary. (And if you end up with anelsif, to avoid latches, don't you also need an else or a default assignment.) - Matthew Taylor
@MatthewTaylor Its a clocked process, so latches shouldnt be possible. I use the double if all the time with no issues because of my answer below. CONDITION1 could be sync enable and CONDITION2 sync reset, and it allows you to chose which signals have enable and reset separately. if..else forces all signals to be connected to both. - Tricky
@Tricky Oh. Yes. It's a clocked process. No latches then. - Matthew Taylor
CORRECTION: I would recommend not doing it in a combinational process for all the reasons I said. - Matthew Taylor

1 Answers

3
votes

Yes, it is legal, and yes, assignments are sequiential. Remember that signal assignemnts are given the last value given to them, so the final if "wins". So the following two codes are functionally identical.

process(clk)
begin
  if rising_edge(clk) then
    if cond1 then
      --do something 
    end if;

    if cond2 then
      -- do something else
    end if;
  end if;
end process;

-- same as this:

process(clk)
begin
  if rising_edge(clk) then
    if cond2 then 
      -- do soemthing else
    elsif cond1 then
      -- do something
    end if;
  end if;
end process;

There is a practical use for this. The traditional process template has a reset as an if..else setup:

-- sync process
if srst then
  a <= '0';
  b <= '0';
else
  --do something with a and b
end if;

This is fine, but you are forcing a and b to always have a link to srst. If you forget to put b in the srst branch, you'll connect srst to the enable pin of b, because you're saying in the code that the b register cannot be latched when srst is active. This forces you to put all register in the reset branch, which you may not want. So, to allow reset and non-reset signals in the same process without creating the enable link, you can use the double if:

--sync process
--do some logic with A and B here

if srst then  -- reset wins
  a <= '0'; 
  -- B has no link to reset 
end if;

This is not a style you find commonly on the internet (probably because of old tutorials always teaching the if..else style). But it is very common to find accidental timing links between srst and enable pins in development code using the "traditional" approach.