Search code examples
if-statementvhdlsynthesis

Are multiple non-nested if statements inside a VHDL process a bad practice?


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?


Solution

  • 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.