Next: , Previous: Installation Directory, Up: Invoking GHDL


3.11 IEEE library pitfalls

When you use options --ieee=synopsys or --ieee=mentor, the IEEE library contains non standard packages such as ‘std_logic_arith’.

These packages are not standard because there are not described by an IEEE standard, even if they have been put in the IEEE library. Furthermore, they are not really de-facto standard, because there are slight differences between the packages of Mentor and those of Synopsys.

Furthermore, since they are not well-thought, their use has pitfalls. For example, this description has error during compilation:

     library ieee;
     use ieee.std_logic_1164.all;
     
     --  A counter from 0 to 10.
     entity counter is
        port (val : out std_logic_vector (3 downto 0);
              ck : std_logic;
              rst : std_logic);
     end counter;
     
     library ieee;
     use ieee.std_logic_unsigned.all;
     
     architecture bad of counter
     is
        signal v : std_logic_vector (3 downto 0);
     begin
        process (ck, rst)
        begin
          if rst = '1' then
             v <= x"0";
          elsif rising_edge (ck) then
             if v = "1010" then -- Error
                v <= x"0";
             else
                v <= v + 1;
             end if;
          end if;
        end process;
     
        val <= v;
     end bad;

When you analyze this design, GHDL does not accept it (too long lines have been split for readability):

     $ ghdl -a --ieee=synopsys bad_counter.vhdl
     bad_counter.vhdl:13:14: operator "=" is overloaded
     bad_counter.vhdl:13:14: possible interpretations are:
     ../../libraries/ieee/std_logic_1164.v93:69:5: implicit function "="
         [std_logic_vector, std_logic_vector return boolean]
     ../../libraries/synopsys/std_logic_unsigned.vhdl:64:5: function "="
         [std_logic_vector, std_logic_vector return boolean]
     ../translate/ghdldrv/ghdl: compilation error

Indeed, the "=" operator is defined in both packages, and both are visible at the place it is used. The first declaration is an implicit one, which occurs when the std_logic_vector type is declared and is an element to element comparison, the second one is an explicit declared function, with the semantic of an unsigned comparison.

With some analyser, the explicit declaration has priority over the implicit declaration, and this design can be analyzed without error. However, this is not the rule given by the VHDL LRM, and since GHDL follows these rules, it emits an error.

You can force GHDL to use this rule with the -fexplicit option. See GHDL options, for more details.

However it is easy to fix this error, by using a selected name:

     library ieee;
     use ieee.std_logic_unsigned.all;
     
     architecture fixed_bad of counter
     is
        signal v : std_logic_vector (3 downto 0);
     begin
        process (ck, rst)
        begin
          if rst = '1' then
             v <= x"0";
          elsif rising_edge (ck) then
             if ieee.std_logic_unsigned."=" (v, "1010") then
                v <= x"0";
             else
                v <= v + 1;
             end if;
          end if;
        end process;
     
        val <= v;
     end fixed_bad;

It is better to only use the standard packages defined by IEEE, which provides the same functionalities:

     library ieee;
     use ieee.numeric_std.all;
     
     architecture good of counter
     is
        signal v : unsigned (3 downto 0);
     begin
        process (ck, rst)
        begin
          if rst = '1' then
             v <= x"0";
          elsif rising_edge (ck) then
             if v = "1010" then
                v <= x"0";
             else
                v <= v + 1;
             end if;
          end if;
        end process;
     
        val <= std_logic_vector (v);
     end good;