0
\$\begingroup\$

Is this expression allowed inside Xilinx ISE: generic map (record1.field1'length) ??

Previously I have defined record:

type test_record is record
  field1 : std_logic_vector(31 downto 0);
  field2 : std_logic_vector(31 downto 0);
end record;

constant record1 : test_record := ((others => '0'),(others => '0'));

I get this error message:

The actual value (Attribute name) associated with a generic must be a globally static expression

\$\endgroup\$
2

1 Answer 1

1
\$\begingroup\$

Assuming the record type and constant are declared prior to the use in a component instantiation record1.field1'length is globally static.

A Minimal, Complete and Verifiable Example:

library ieee;
use ieee.std_logic_1164.all;

entity foo is
    generic (constant fie: natural);
    port (foe:  in  std_logic);
end entity;

architecture foo of foo is
begin
    process (foe)
    begin
        report "fie = " & integer'image(fie);
    end process;
end architecture;


library ieee;
use ieee.std_logic_1164.all;

entity zoki is
end entity;

architecture fum of zoki is

    type test_record is record
      field1 : std_logic_vector(31 downto 0);
      field2 : std_logic_vector(31 downto 0);
    end record;

    constant record1 : test_record := ((others => '0'),(others => '0'));

    component foo is
        generic (constant fie: natural);
        port (foe:  in  std_logic);
    end component;

    signal foe: std_logic;

begin
FIE:
    foo 
        generic map (record1.field1'length)
        port map (foe);        
end architecture;

Which analyzes, elaborates and simulates, reporting the value of the generic:

ghdl -a zoki.vhdl
ghdl -e zoki
ghdl -r zoki
zoki.vhdl:13:9:@0ms:(report note): fie = 32

The reason why the value of the generic is globally static is found in the LRM.

IEEE Std 1076-2008
9.4.3 Globally static primaries para 1:

An expression is said to be globally static if and only if every operator in the expression denotes a pure function and every primary in the expression is a globally static primary, where a globally static primary is a primary that, if it denotes an object or a function, does not denote a dynamically elaborated named entity (see 14.6) and is one of the following:
...

l) A predefined attribute that is a function, other than the predefined attributes 'EVENT, 'ACTIVE, 'LAST_EVENT, 'LAST_ACTIVE, 'LAST_VALUE, 'DRIVING, and 'DRIVING_VALUE, whose prefix is appropriate for a globally static attribute, and whose actual parameter (if any) is a globally static expression ...

So 'LENGTH is not proscribed, it is a function (16.2.3 Predefined attributes of arrays). It denotes an array type whose index ranges are defined by a constraint (record1.field1`, an index constraint (5.3.2 Array types)).

Is the prefix record1.field1 a globally static expression?

9.4.3 Globally static primaries para 1:

An expression is said to be globally static if and only if every operator in the expression denotes a pure function and every primary in the expression is a globally static primary, where a globally static primary is a primary that, if it denotes an object or a function, does not denote a dynamically elaborated named entity (see 14.6) and is one of the following:
...

e) A constant (including a deferred constant) explicitly declared by a constant declaration with a globally static subtype or with an unconstrained or partially constrained composite subtype for which the applicable constraints are globally static

Further, para 2:

A prefix is appropriate for a globally static attribute if it denotes a signal, a constant, a type or subtype, a globally static function call, a variable that is not of an access type, or a variable of an access type whose designated subtype is fully constrained.

And record1 is a constant, actually locally static (a 'locally static expression is also globally static unless the expression appears in a dynamically elaborated context' (9.4.1 via Annex I Glossary item globally static expression), dynamically elaborated means subprogram calls or loop statement parameter specification, see 14.6 Dynamic elaboration).

Further in 9.4.2 Locally static primaries:

An expression is said to be locally static if and only if every operator in the expression denotes an implicitly defined operator or an operator defined in one of the packages STD_LOGIC_1164, NUMERIC_BIT, NUMERIC_STD, NUMERIC_BIT_UNSIGNED, or NUMERIC_STD_UNSIGNED in library IEEE, and if every primary in the expression is a locally static primary, where a locally static primary is defined to be one of the following:
...

b) A constant (other than a deferred constant) explicitly declared by a constant declaration with a locally static subtype or with an unconstrained or partially constrained composite subtype for which the applicable constraints are locally static, and initialized with a locally static expression
...
p) A selected name whose prefix is a locally static primary

The selected name record1.field1 is locally static and hence globally.

The entire expression record1.field1'length is locally static:

g) A predefined attribute that is a function, other than the predefined attribute 'VALUE with a prefix whose base type is the predefined type TIME, and other than the predefined attributes 'EVENT, 'ACTIVE, 'LAST_EVENT, 'LAST_ACTIVE, 'LAST_VALUE, 'DRIVING, and 'DRIVING_VALUE, whose prefix is either a locally static subtype or is an object that is of a locally static subtype, and whose actual parameter (if any) is a locally static expression

And hence globally static. (This should all hold true for IEEE Std 1076-1993 as well).

Because you haven't supplied an MCVE there are two possibilities. Your code doesn't conform to the example in this answer or there's a bug in the semantic error checking in ISE's HDL Parser.

It should be possible to overcome the latter by declaring a constant with the length of the field (derived from the length attribute). Another possibility would be to derive field1 and field2 left index constraints from a constant and pass that to the generic.

From Stevanovic's Xilinx forum topic, the first indication is that Xilinx would suggest you try the new parser in Vivado, failing that provide complete code.

No success in finding the same issue with globally static attributes as generics historically. It's amazing the same issue can come up twice in one day. Have you considered contacting Xilinx? Two such occurrences just may spark a useful response.

It turns out the new parser is available in ISE 14.7 and it cures the problem. Stevanovic's thread in the Xilinx forum shows he ponied up an MCVE and setting the command line options to include -use_new_parser yes cures the problem for some older device families.

There are directions on how to do that in Gabor's answer there.

So this falls under the heading of a Xilinx discrepancy not supporting globally static expression semantics completely.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.