0
\$\begingroup\$

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?

Thanks in advance.

asked Jan 12, 2015 at 21:38
\$\endgroup\$
3
  • 3
    \$\begingroup\$ 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 :) \$\endgroup\$ Commented Jan 12, 2015 at 22:14
  • \$\begingroup\$ 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. \$\endgroup\$ Commented Jan 13, 2015 at 9:30
  • \$\begingroup\$ Nitpick: conditional assignment is not exactly a "ternary operator", though it functions like one in this case. \$\endgroup\$ Commented Jan 14, 2015 at 14:02

2 Answers 2

1
\$\begingroup\$

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.

answered Jan 13, 2015 at 13:49
\$\endgroup\$
1
\$\begingroup\$

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

answered Aug 22, 2018 at 13:54
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.