1

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 ?

First User
  • 704
  • 5
  • 12
  • 1
    Evaluating inputs with an equality operator to a weak driving 'L' for example will require an 'L' and not a '0'. The equality value comparison is literal. Package std_logic_1164 functions for evaluating filtering 'L' to '0' and 'H' to '1' that can be used. To_X01, To_X01Z and To _UX01 when trying to model binary behavior. We normally evaluate and assign '0' and '1' for code intended to synthesize other than inferring a high impedance drive value. – user16145658 Nov 03 '22 at 19:22
  • `when input = (input'range => 'H')` gives the compiler a vector size to work with. –  Nov 05 '22 at 13:32

2 Answers2

2

As equality operator is defined by VHDL (7.2.2 of IEEE-1076-1993), there is no direct constraint between operands. For instance, if both operands are of the same array type, they may be not the same length (and equality will be always false), if they are of same length, elements are matched in order (whatever the range of array). This gives no strong constraint between operands.

In some contexts, literal array aggregates with others can be determined from context (initializations, assignments, etc.). Valid cases are listed in 7.3.2.2. Equality operator operands is not one of them.

You may still write an aggregate with an explicit range, for instance input = (input'range => 'H').

Nipo
  • 2,617
  • 13
  • 20
  • *You may still write an array literal with an explicit range, for instance input = (input'range => 'H').* That's not a literal, it's an aggregate, an expression that happens to have a locally static range (7.4.1 Locally static primaries). The type of a string literal (a lexical element, here "HHHHHHHH") can be determined from context, both operands of an equality operator are of the same type. The NOTE in 13.6 String literals was misleading and has been corrected in later revisions (-2000), a literal is not the result of concatenation (or aggregation) 7.3.1 Literals. – user16145658 Nov 03 '22 at 20:31
  • Thanks for noting aggregate is not a literal. I edited. – Nipo Nov 04 '22 at 10:05
2

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.

user16145658
  • 695
  • 1
  • 5
  • 10