3
\$\begingroup\$

In VHDL, if I take create a type like this

type example is (
    ex_0,
    ex_1,
    ex_2,
    ex_3
);
signal example_signal : example

Then ex_0 would synthesize to something like '00', ex_1 to '01' , ex_2 to '10', and ex_3 to '11'. Maybe it'd be gray code but I don't know.

Is there a way to assign each of those to a specific value? For example it would look something like

type example is (
    ex_0 := '11',
    ex_1 := '10',
    ex_2 := '01',
    ex_3 := '00'
);
signal example_signal : example
\$\endgroup\$
4
  • 1
    \$\begingroup\$ intel.com/content/www/us/en/programmable/quartushelp/17.0/hdl/… ... may be vendor-specific \$\endgroup\$
    – user16324
    Commented Oct 6, 2022 at 18:34
  • 1
    \$\begingroup\$ An enumeration value is scalar and ordered representing positional value from 0. The enum_encoding user defined attribute mentioned in the Intel link above is found in IEEE Std 1076.6-2004 (RTL Synthesis, 7.1 Attributes, withdrawn for lack of vendor participation). The mentioned encoding style is controlled by user defined attribute fsm_state. Without standardization support isn't guaranteed but is likely. \$\endgroup\$ Commented Oct 6, 2022 at 19:51
  • 1
    \$\begingroup\$ Without an attribute, synthesis tools typically represent enumerated types with one-hot encoding ("1000", "0100", "0010", "0001") and optimize from there, especially for state machines this usually gives a fairly efficient representation. A more compact encoding needs to generate comparators in every place the value is used. \$\endgroup\$ Commented Oct 7, 2022 at 11:26
  • 1
    \$\begingroup\$ There is no builtin conversion between an enumerated type and a std_logic_vector, I'd use a function with a case mapping. \$\endgroup\$ Commented Oct 7, 2022 at 11:28

2 Answers 2

2
\$\begingroup\$

The VHDL-2008 standard defines in chapter 5.2.2 enumeration types and says this:

Each enumeration literal yields a different enumeration value. The predefined order relations between enumeration values follow the order of corresponding position numbers. The position number of the value of the first listed enumeration literal is zero; the position number for each additional enumeration literal is one more than that of its predecessor in the list.

However, it specifies no way to assign deliberate values.

\$\endgroup\$
1
  • \$\begingroup\$ See IEEE Std 1076.6-2004 (withdrawn), 7.1.8 Enumeration encoding attribute as pointed out in the comment to the question. Redefining values for an enumeration would be done in synthesis. \$\endgroup\$ Commented Oct 7, 2022 at 9:44
2
\$\begingroup\$

If you don't mind not using the enumeration, it looks like this:

constant ST0: std_logic_vector(3 downto 0) := "1000";
constant ST1: std_logic_vector(3 downto 0) := "0100";
constant ST2: std_logic_vector(3 downto 0) := "0010";
constant ST3: std_logic_vector(3 downto 0) := "0001";
signal PS, NS : std_logic_vector(3 downto 0);

But with enumeration, it looks even uglier (IMO):

type state_type is (ST0, ST1, ST2, ST3);
attribute ENUM_ENCODING : STRING;
attribute ENUM_ENCODING of state_type: type is "1000 0100 0010 0001";
signal PS, NS : state_type;

Which works in every synthesis tool I've used. For FSMs, at least, I've seen very good optimizations from Vivado (to the point of eliminating a DFF from a "One Hot Encoding" state).

\$\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.