# VHDL process causes errors

I'm new to VHDL so I just have a question to ask about why this produces an error. I have an ALU defined in VHDL:

c <=        a + b       WHEN opc="0111"
ELSE        a - b       WHEN opc="1000"
ELSE        -a          WHEN opc="1011"
ELSE        -b          WHEN opc="0001"
ELSE        ABS(a)      WHEN opc="1110"
ELSE        ABS (b)     WHEN opc="1010"
ELSE        NOT a       WHEN opc="0010"
ELSE        NOT b       WHEN opc="1100"
ELSE        a AND b     WHEN opc="0100"
ELSE        a OR b      WHEN opc="0110"
ELSE        a XOR b     WHEN opc="0101"


(this is the architecture)

But then I want to make it synchronous,

PROCESS (clock)
BEGIN
IF(rising_edge(clock)) THEN
c <=        a + b       WHEN opc="0101"
ELSE        a - b       WHEN opc="1000"
ELSE        -a          WHEN opc="1011"
ELSE        -b          WHEN opc="0001"
ELSE        ABS(a)      WHEN opc="1110"
ELSE        ABS (b)     WHEN opc="1010"
ELSE        NOT a       WHEN opc="0010"
ELSE        NOT b       WHEN opc="1100"
ELSE        a AND b     WHEN opc="0100"
ELSE        a OR b      WHEN opc="0110"
ELSE        a XOR b     WHEN opc="0111"
END IF
END PROCESS;


This doesn't work, it comes up with various errors like:

';' expected.
Keyword "end" expected.


So I have now changed my code to:

PROCESS (clock)
BEGIN
IF(rising_edge(clock)) THEN
CASE opc IS
WHEN "0101" => c <= a+b;
WHEN "1000" => c <= a-b;
WHEN "1011" => c <= -a;
WHEN "0001" => c <= -b;
WHEN "1110" => c <= ABS(a);
WHEN "1010" => c <= ABS(b);
WHEN "0010" => c <= NOT a;
WHEN "1100" => c <= NOT b;
WHEN "0100" => c <= a AND b;
WHEN "0110" => c <= a OR b;
WHEN "0111" => c <= a XOR b;
END CASE;
END IF;
END PROCESS;


And this doesn't produce any errors. But why does the original code which worked when put in a process not work unless I use the case statement?

• The ternary operator c <= a when condition else b; is not allowed inside of process statements prior to VHDL-2008. SO you can enable VHDL-2008 support if your tool supports this or you use your later code example, which is much nicer :) – Paebbels Jan 12 '15 at 22:14
• Paebbels is correct, and I have to add that if you are designing for ASIC or FPGA (specially) you should avoid nested If-Then-Elest statement. Also, at the end of your process add the "others" to make sure all the cases are covered with that statement. – FarhadA Jan 13 '15 at 9:30
• Nitpick: conditional assignment is not exactly a "ternary operator", though it functions like one in this case. – fru1tbat Jan 14 '15 at 14:02

In order of effort:

• If you have access to VHDL 2008 in your tools, enable it. If not, bug the vendor to support it!
• add an extra signal calling c_sync and then add a line:

c_sync <= c when rising_edge(clk);

• Change your code to a set of if then statements.

Your first try to make it synchronous didn't work because:

• You haven't enabled VHDL 2008 (as stated in the other answers/comments)
• the end of the conditional assignment is missing a ;
• your END IF is missing a ;

Your second try works, because it doesn't require VHDL 2008:

The case-statement has been supported in processes since the first VHDL version, while the conditional assignment was previously forbidden inside processes (which has been changed with VHDL 2008).