Search code examples
vhdlaggregatesghdl

vhdl: Why is aggregate assignment not allowed in this context?


I am trying to use aggregate assignments within a conditional assignment statement in the lines labelled "PROBLEMATIC LINE" in the following code implementation for a priority encoder module.

library ieee;
use ieee.std_logic_1164.all;

entity SN74LS148 is -- 8 to 3 line priority encoder module 
    port(EI      : in   std_logic;                     -- input enable      
         input   : in   std_logic_vector(0 to 7);      -- 8 bit input bus
         A       : out  std_logic_vector(2 downto 0);  -- 3 output bits
         GS, EO  : out  std_logic                      -- valid bit, enable output
    );  
end SN74LS148;

architecture behavioral of SN74LS148 is
    signal truth_table : std_logic_vector(2 downto 0);
begin
    truth_table <= "HHH" when input = (others => 'H') else   -- PROBLEMATIC LINE
                   "LLL" when input(7) = 'L' else
                   "LLH" when input(6) = 'L' else
                   "LHL" when input(5) = 'L' else
                   "LHH" when input(4) = 'L' else
                   "HLL" when input(3) = 'L' else
                   "HLH" when input(2) = 'L' else
                   "HHL" when input(1) = 'L' else
                   "HHH" when input(0) = 'L' else
                   "XXX";
    A <= truth_table    when EI = 'L' else  -- device enabled (active low)
         "HHH"          when EI = 'H' else  -- device disabled (all outputs inactive)
         "XXX";
    GS <= 'H' when EI = 'H'                         -- invalid when device disabled
                   or input = (others => 'H') else  -- or none of the lines asserted (PROBLEMATIC LINE)
          'L';
    EO <= 'L' when EI = 'L' and input = (others => 'H') else -- PROBLEMATIC LINE
          'H';
end behavioral;

I am using the GHDL compiler. The error that I am getting is

encoder8x3.vhd:28:43: 'others' choice not allowed for an aggregate in this context
        truth_table <= "HHH" when input = (others => 'H') else
                                          ^
encoder8x3.vhd:46:47: 'others' choice not allowed for an aggregate in this context
                                   or input = (others => 'H') else      -- or none of the lines asserted
                                              ^
encoder8x3.vhd:50:45: 'others' choice not allowed for an aggregate in this context
        EO <= 'L' when EI = 'L' and input = (others => 'H') else
                                            ^

I guess I can fix this easily by hardcoding the inputs but what I want to know is why I am getting this error when the size of input has been specified in the port. This is not an ambiguity issue right ?


Solution

  • No, it is an ambiguity issue.

    See IEEE Std 1076-1993 7.3.2.2 Array aggregates

    The subtype of an array aggregate that has an others choice must be determinable from the context. That is, an array aggregate with an others choice may only appear

    a. As an actual associated with a formal parameter or formal generic declared to be of a constrained array subtype (or subelement thereof)
    ...

    Here the actual is your array aggregate associated with a parameter of the subprogram parameter for the overloaded equality operator, which is unconstrained. The type mark of that parameter would be the type std_logic_vector, while this would become a subtype in -2008 to allow subtype resolution specification it'd be unconstrained and the language of -2008 9.3.3.3 Array aggregates has been changed:

    The index range of an array aggregate that has an others choice shall be determinable from the context.

    That actually implies what's important here, the length of the aggregate array value. See 7.2.2 Relational operators:

    Two scalar values of the same type are equal if and only if the values are the same. Two composite values of the same type are equal if and only if for each element of the left operand there is a matching element of the right operand and vice versa, and the values of matching elements are equal, as given by the predefined equality operator for the element type.

    These rules also tell us the std_logic weak driving 'H' or 'L' enumeration values either as a scalar or an element of a composite value are not equal to the strong driving '1' and '0' values respectively.