0

I am trying to code a 8 bit full adder using just concurrent code in VHDL but I got an error in the syntaxis. In the first instance i did this:

    LIBRARY ieee;
    USE ieee.std_logic_1164.ALL;

    ENTITY concfulladder IS

        PORT(     A: IN std_logic_vector (7 DOWNTO 0);
                  B: IN std_logic_vector (7 DOWNTO 0);
                Cin: IN std_logic_vector (7 DOWNTO 0);
                Sum: OUT std_logic_vector(7 DOWNTO 0);
               Cout: OUT std_logic_vector(7 DOWNTO 0));
         
    END concfulladder;

    ARCHITECTURE cfulladder OF concfulladder IS


    BEGIN

      sum(0) <= '0' WHEN (A(0) XOR B(0) XOR CIN(0)) = '0' ELSE
                '1';
      cout(0) <= '0' WHEN ((A(0) AND B(0)) OR (Cin(0) AND A(0)) OR (Cin(0) AND B(0))) = '0' ELSE
                 '1';
      sum(1) <= '0' WHEN (A(1) XOR B(1) XOR CIN(1)) = '0' ELSE
                 '1';
      cout(1) <= '0' WHEN ((A(1) AND B(1)) OR (Cin(1) AND A(1)) OR (Cin(1) AND B(1))) = '0' ELSE
                 '1';
       sum(2) <= '0' WHEN (A(2) XOR B(2) XOR CIN(2)) = '0' ELSE
                 '1';
      cout(2) <= '0' WHEN ((A(2) AND B(2)) OR (Cin(2) AND A(2)) OR (Cin(2) AND B(2))) = '0' ELSE
                 '1';
       sum(3) <= '0' WHEN (A(3) XOR B(3) XOR CIN(3)) = '0' ELSE
                 '1';
      cout(3) <= '0' WHEN ((A(3) AND B(3)) OR (Cin(3) AND A(3)) OR (Cin(3) AND B(3))) = '0' ELSE
                 '1';
       sum(4) <= '0' WHEN (A(4) XOR B(4) XOR CIN(4)) = '0' ELSE
                 '1';
      cout(4) <= '0' WHEN ((A(4) AND B(4)) OR (Cin(4) AND A(4)) OR (Cin(4) AND B(4))) = '0' ELSE
                 '1';
       sum(5) <= '0' WHEN (A(5) XOR B(5) XOR CIN(5 )) = '0' ELSE
                 '1';
      cout(5) <= '0' WHEN ((A(5) AND B(5)) OR (Cin(5) AND A(5)) OR (Cin(5) AND B(5))) = '0' ELSE
                 '1';
       sum(6) <= '0' WHEN (A(6) XOR B(6) XOR CIN(6)) = '0' ELSE
                 '1';
      cout(6) <= '0' WHEN ((A(6) AND B(6)) OR (Cin(6) AND A(6)) OR (Cin(6) AND B(6))) = '0' ELSE
                 '1';
       sum(7) <= '0' WHEN (A(7) XOR B(7) XOR CIN(7)) = '0' ELSE
                 '1';
      cout(7) <= '0' WHEN ((A(7) AND B(7)) OR (Cin(7) AND A(7)) OR (Cin(7) AND B(7))) = '0' ELSE
                 '1';
             
  END cfulladder;

And all of this is correct I don't get any error. But, if I try to decrease the number of lines using a for loop I got an error:

PROCESS (all) IS

BEGIN

    FOR I IN 0 TO 7 LOOP

        Sum(I) <= '0' WHEN (A(I) XOR B(I) XOR CIN(I)) = '0' ELSE 
                     '1';
                     
        Cout(I) <= '0' WHEN ((A(I) AND B(I)) OR (Cin(I) AND A(I)) OR (Cin(I) AND B(I))) = '0' ELSE 
                      '1';

    END LOOP;

END PROCESS;

The error is: Error near text WHEN; expecting ";". Searching a solution in internet I found that I can't use sequential code and concurrent code in the same program. Is there any solution for this problem?

3
  • A conditional signal assignment is only a concurrent statement in revisions of the VHDL standard prior to -2008. Your options are to use -2008, use an equivalent if statement or describe dataflow in the assignment, e.g. Sum(I) <= A(I) XOR B(I) XOR CIN(I); and Cout(I) <= (A(I) AND B(I)) OR (Cin(I) AND A(I)) OR (Cin(I) AND B(I)); which provides the same values using overload operators defined in IEEE package std_logic_1164. Commented Oct 4, 2020 at 17:58
  • There's also the use of a for generate statement. See Bill Lynch's answer which is also useful in generic sized adders. Here a generate statement has a block statement equivalent for each iteration each containing concurrent signal assignment statements. Commented Oct 4, 2020 at 18:06
  • From your use of the reserved word all in the process sensitivity list you appear to be using -2008. Sequential conditional signal assignment statements may not be implemented in your particular tool environment. Likewise you may have missed passing the -2008 flag to the tool analyzer (compiler). Substituting the above process statement for the concurrent statements found in the architecture will successfully analyze (e.g. ghdl -a --std=08 concfulladder.vhdl, a recent ghdl commit 1.0-dev v0.37.0-773-gd85a1a9). Commented Oct 4, 2020 at 19:43

2 Answers 2

1

when..else is allowed inside a process only when using VHDL 2008 or later revisions. For previous versions, you'll need to use the when..else statements outside a process.

Sign up to request clarification or add additional context in comments.

6 Comments

That is incorrect. See 11.6 Concurrent signal assignment statements, the BNF target *conditional_waveforms * which is defined in 10.5.3 Conditional signal assignments. 11.6 Concurrent signal assignment statements "A concurrent signal assignment statement represents an equivalent process statement that assigns values to signals." See 11.3 Process statement. The process statement part contains a sequence of zero or more sequential statements, here a conditional signal assignment statement (10.5.3).
@user1155120 Which part are you claiming to be incorrect? That in VHDL-2008 conditional assignment is now allowed in a process, or that prior to VHDL-2008 conditional assignment was not allowed in a process?
This is incorrect: when..else is only allowed inside a process when using VHDL 2008. A concurrent signal assignment statement (11.6) can be a concurrent_conditional_signal_assignment where the intermediary target conditional_waveforms is defined in 10.5.3 and contains the reserved words when and else. Conditional waveforms are allowed in both sequential and concurrent signal assignments. Concurrent statements don't occur in process statements.
@user1155120 Clause 10 is sequential statements. Clause 10.5.3 details conditional signal assignments (sequential ones in a process). Hence, In VHDL-2008, "when else" became conditional assignment and is indeed allowed inside a process and Tricky is correct - unless you are just mincing words, but at that point you are confusing the community. You may also enjoy 10.6.3 Conditional variable assignments.
@jim Here's an example demonstrating when...else is not only allowed inside a process when using VHDL 2008. 'only' should be eliminated, simply moving it would be ambiguous with respect to the approved current revision. Standard syntax is permissive while semantic limits are restrictive. It eliminates tautological ambiguity.
|
1

There is no need for conditional assignments here. Instead try:

PROCESS (all) IS
BEGIN

    FOR I IN 0 TO 7 LOOP
        Sum(I) <= A(I) XOR B(I) XOR CIN(I);
                     
        Cout(I) <= (A(I) AND B(I)) OR (Cin(I) AND A(I)) OR (Cin(I) AND B(I));
    END LOOP;
END PROCESS;

Alternately, all of VHDL logic operators are bitwise, so you should also be able to write this as (but make sure to verify this in simulation):

Sum <= A XOR B XOR CIN;
Cout <= (A AND B) OR (Cin AND A) OR (Cin AND B);

Historically, we needed "when" "else" when making decisions based on arrays and deriving a scalar value. For example:

Decode1 <= '1' when BlockSelect = '1' and Addr = X"A5" else '0';

With VHDL-2008 even this usage will go away as we can re-express this using the ?= without using the conditional" assignment.

Decode1 <= BlockSelect and Addr ?= X"A5";

As with any VHDL-2008 code, your synthesis vendor may not support it just yet. If they don't (and you had turned on VHDL-2008 in their tools), please be sure to submit a bug report against their implementation.

1 Comment

The delimiter ?= used as an operator implements matching equality (-2008 9.2.3 Relational operators) and is predefined for any single dimensional array type with an element type of BIT or STD_ULOGIC returning a value of the element type. With "Hopefully" Jim signals universal implementation adoption allowing VHDL design description portability. There are no VHDL implementations that completely implement the -2008 standard revision. This successfully analyzes in a current ghdl commit. Is it portable today?

Your Answer

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.