Compiling a simple 2-input multiplexer with GHDL fails

I started reading "The Designer's Guide to VHDL" by P. J. Ashenden, but I'm already stuck after exercise 9, here is my code:

entity mul2 is
port ( a, b, sel : in bit;
z : out bit );
end entity mul2;

architecture behav of mul2 is
begin

multiplex : process is
begin
if sel then
z <= a;
else
z <= b;
end if;
end process multiplex;

end architecture behav;


When I invoke GHDL with

ghdl -a mul2.vhdl


I get the following error:

mul2.vhdl:11:19: can't match port "sel" with type boolean
mul2.vhdl:2:21: (location of port "sel")


I'm kind of confused, because in the book there is a example that shows a in bit port being used in a if-statement the same way I do in my code - but that example won't compile as well(example 1.2, if you have the book on hand).

I think this is a problem with GHDL not implementing the standard properly. Has anyone an idea what's wrong here?

• IEEE Std 1076-2008 10.8 If statements "For the execution of an if statement, the condition specified after if, and any conditions specified after elsif, are evaluated in succession (treating a final else as elsif TRUE then) until one evaluates to TRUE or all conditions are evaluated and yield FALSE. If one condition evaluates to TRUE, then the corresponding sequence of statements is executed; otherwise, none of the sequences of statements is executed." ghdl --disp-standard | grep -i FALSE -> type boolean is (false, true); They're enumeration values of type boolean. – user8352 Aug 20 '16 at 12:26
• The Designer's Guide to VHDL 2nd Edition. Chapter 1 Exercise 8. "Write an entity declaration and a behavioral architecture body for a two-input multiplexer with input ports a, b and sel and and output port of z. If the sel input is '0' the value of a should be copied to z, otherwise the value of b should be copied to z. Write a test bench for the multiplexer model, and test it using a VHDL simulator." That '0' is an enumeration value for the type of sel, in your case type bit. The answer to exercise 8 isn't in the back of my copy of the book. – user8352 Aug 20 '16 at 12:56
• There are no solutions for level 2, 3, and 4 exercises in the book, only for level 1. But yes, that's the exercise I'm trying to solve, right now I stuck getting a test bench running, but I'm making progress :) – georgjz Aug 20 '16 at 13:43

The problem is in the if statement.

Unlike C, in VHDL you there is no shortcut that would evaluate any non-zero value to true and the rest to false. VHDL is much stricter here.

Here is the fixed code:

entity mul2 is
port ( a, b, sel : in bit;
z : out bit );
end entity mul2;

architecture behav of mul2 is
begin

multiplex : process is
begin
if sel = '1' then  --- see, if you do a proper compare it works
z <= a;
else
z <= b;
end if;
end process multiplex;

end architecture behav;

• Thank you! That did the trick. I wonder why the author did the way if it's illegal in his example - but that's what learning is about. – georgjz Aug 20 '16 at 11:16
• If sel was boolean your code would be correct. Where did you see in the book the illegal example you are mentioning? I have the third edition of his book. – Claudio Avi Chami Aug 20 '16 at 11:38
• I have the third edition as well, it's example 1.2 of chapter 1 on page 9 – georgjz Aug 20 '16 at 12:58
• I found some kind of shorten version by the same author here, in this version he uses the same code but slightly modified to the solution Nils Pipenbrinck suggested. – georgjz Aug 20 '16 at 13:48

This is no provide additional information for TEMLIB's answer without mutilating it. The information won't fit in a comment.

IEEE Std 1076-2008 9.2.9 Condition operator, paragraph 4:

The condition operator implicitly applied, if any, is either the predefined operator for type BIT or an overloaded operator, determined as follows. If, without overload resolution (see 12.5), the expression is of type BOOLEAN defined in package STANDARD, or if, assuming a rule requiring the expression to be of type BOOLEAN defined in package STANDARD, overload resolution can determine at least one interpretation of each constituent of the innermost complete context including the expression, then the condition operator is not applied. Otherwise, the condition operator is implicitly applied, and the type of the expression with the implicit application shall be BOOLEAN defined in package STANDARD.

Type BOOLEAN has the operator implemented in package standard:

ghdl --disp-standard --std=08 | grep \?\?
-- function "??" (<anonymous>: bit) return boolean;

It's also implemented in the -2008 revision of package std_logic_1164:

function "??" (l : STD_ULOGIC) return BOOLEAN;

Which serves for any array types or subtypes defined with STD_ULOGIC elements. (Array types ufixed, sfixed, float, signed, unsigned, std_ulogic_vector and std_logic_vector all use std_ulogic elements and are declared in IEEE packages).

There are no other types with the condition operator predefined in the -2008 revision of the standard.

The -2008 standard also introduces matching relational operators (See 9.2.3 Relational operators.

There is a downside. Just about every VHDL tool has to have -2008 compatibility mode enabled, and all new features aren't supported by all tools (presumptively not yet, it's only been eight years).

Which constructs you should use are generally dictated by your entire tool chain (especially synthesis tools) as well as portability concerns.

You'll find in Xilinx's supported features in User Guide 901 Vivado Design Suite User Guide Synthesis Chapter 5 VHDL-2008 Language Support. Other vendors will generally be forthcoming with feature support.

You could note The Designer's Guide to VHDL, Peter Ashenden, 2d ed., 2002 that the subject exercise the question is taken from precedes the release of the -2008 standard by more than six years.

Chapter 1 Exercise 8, Book page 26:

Write an entity declaration and a behavioral architecture body for a two-input multiplexer with input ports a, b and sel and an output port of z. If the sel input is '0' the value of a should be copied to z, otherwise the value of b should be copied to z. Write a test bench for the multiplexer model, and test it using a VHDL simulator."

I'd suggest putting all the shortcuts into practice immediately:

entity mul2 is
port ( a, b, sel: bit;
z : out bit );
end;

architecture foo of mul2 is
begin
Z <= a when sel else b;
end;


doesn't serve the VHDL learner as well as understanding the syntax, semantics and type system nor understanding the limits of the tool chain he or she is using. If you don't understand VHDL sufficiently working around tool chain shortcomings can be much more difficult.

As well as an implicitly applied condition operator the condition expression could be explicitly applied: ?? sel.

• As with TEMLIB's answer, I suspected such a thing. I know that toolchains often lack behind in terms of implementing new standards (C++11 is coming along fine at last while they're talking about C++17 already, not to forget C++14), so I placed my question here after Google didn't find anything on the subject. – georgjz Aug 21 '16 at 10:55

Directly using std_logic or bit as booleans in IF statements is a novelty introduced in the 2008 edition of VHDL.

As default, GHDL supports the language defined in the 1993 edition of the standard (which is more widely used), you can select the 2008 edition through a command line option :

--std=08

• Thanks, I always had a feeling that this could be the case, but since I'm very new to VHDL, I thought I rather ask. – georgjz Aug 21 '16 at 10:01