[vhdl-200x] Updated Enum Attributes twiki page

From: Lehmann, Patrick <patrick.lehmann@tu-dresden.de>
Date: Fri Jun 26 2015 - 07:48:25 PDT
Hello,



after my question: “VHDL: Why is ‘length not defined for enums” on stackoverflow, Jim Lewis encouraged

me to update the proposal on addition attributes for enum types.



http://stackoverflow.com/questions/31032446/vhdl-why-is-length-not-defined-for-enums


http://www.eda-twiki.org/cgi-bin/view.cgi/P1076/EnumAttributes




Here are some additional thoughts to the updated twiki page. This email is also indented to be the basis

for a discussion, regarding my twiki extensions. The following sections are numbered for better reference.



1)

The ‘old’ proposal requested an additional attribute named ‘LENGTH.

I added ‘COUNT as an alternative name for ‘LENGTH, because LENGTH is currently used to get the number

of elements in an array. So maybe it’s better to use ‘COUNT to get the number of enum members.



2)

I added two use cases on the twiki page section ‘Use Model’. Both examples perform some sort of serialization

task, which need ‘COUNT as an integral part of the algorithm.





Insertion: Why do we need serialization?

==============================

Serializing and de-serializing enumerated types to binary representations is a common use case in simulation and

synthesis code. While VHDL does not support type generics to describe generic RAMs, FIFOs or cross-clock

synchronizers, a 'serialization' functionality is needed to convert enum values into a common binary representation.

These converted values (e.g. of type STD_LOGIC_VECTOR) can be passed to a FIFO. It's also possible to convert

these STD_LOGIC_VECTOR values back to a enum value.



Example 1 - Serializing enum values to std_logic_vector and vice versa for using with generic VHDL components:
type T_STATUS is (
  STATUS_IDLE,
  STATUS_TRANSMITTING,
  STATUS_COMPLETE,
  STATUS_ERROR
);

function log2(value : NATURAL) return POSITIVE;     -- returns log2 of value
function str_len(value : STRING) return NATURAL;    -- returns the length of a NUL terminated string
function str_trim(value : STRING) return STRING;    -- returns a trimmed string without trailing NUL characters

function serializeStatus(value : T_STATUS) return STD_LOGIC_VECTOR is
begin
  return std_logic_vector(to_unsigned(T_STATUS'pos(value), log2(T_STATUS'pos(T_STATUS'high) + 1)));
end function;

function deserializeStatus(slv : STD_LOGIC_VECTOR) return T_STATUS is
begin
  if (to_integer(unsigned(slv)) <= T_STATUS'pos(T_STATUS'high)) then
    return T_STATUS'val(to_integer(unsigned(slv)));
  else
    return STATUS_ERROR;
  end if;
end function;

This could be shortened to this, if enum types support 'COUNT:

function serializeStatus(value : T_STATUS) return STD_LOGIC_VECTOR is
begin
  return std_logic_vector(to_unsigned(T_STATUS'pos(value), log2(T_STATUS'count)));
end function;

function deserializeStatus(slv : STD_LOGIC_VECTOR) return T_STATUS is
begin
  if (to_integer(unsigned(slv)) < T_STATUS'count) then
    return T_STATUS'val(to_integer(unsigned(slv)));
  else
    return STATUS_ERROR;
  end if;
end function;

It’s also possible to use the serialization function to connect signals based on enumerated types to

Integrated logic analyzers like ChipScope.

signal Status        : T_STATUS;
signal Debugger_Data : STD_LOGIC_VECTOR(15 downto 0);

Debugger_Data(1 downto 0) <= serializeStatus(Status)

Example 2 - Exporting/writing enum values and member names into files for external tools



Some simulation and synthesis tools support I/O functions to read and write files from the host's file

system. While this feature is massively used in simulation environments it's rarely used in synthesis

environments. Synthesis tools generate large reports, which include state encodings for enum based

FSMs. But it's not common to report other encodings for e.g. enum based signals.

These string representations can be read back by external tools like waveform viewers or debuggers

to show captured signals with it's member name instead of it's binary representation.



A simple export format could be:

-          one member per line

-          separated by semi-colons



Example of a simple format:

STATUS_IDLE;STATUS_TRANSMITTING;STATUS_COMPLETE;STATUS_ERROR;



procedure str_append(StringBuffer : inout STRING; value : STRING) is

  constant BufferEnd : POSITIVE := str_len(StringBuffer);

begin

  StringBuffer(BufferEnd + 1 to BufferEnd + str_len(value))      := value;

end procedure;



function encodeStatus return string is

  variable StringBuffer : STRING(1 to (64 * T_STATUS'count))     := (others => NUL);

begin

  for member in T_STATUS loop

    str_append(StringBuffer, (T_STATUS'image(member) & ';');

  end loop;

  return  str_trim(StringBuffer);

end function;



A external script can transform this enum member list into other file formats like ChipScope's token files (*.tok)

or GTKwaves data format filter files. It's even possible to export these file formats directly. An advantage is to

generate up-to-date encoding files for external tools without complex synthesis report parsing.



3)

I introduced two new attributes ‘SERIALIZE and ‘DESERIALZIE, which serialize enum values to a common

binary representation and vice versa. This would reduce the amount of user written code, because the current

approach needs one conversion function per type and direction. It should be possible to define such attributes

and the underlying conversion function by the language itself like it’s done for operators or ‘IMAGE.



These new attributes allow a much shorter usage like this:
Debugger_Data(1 downto 0) <= T_STATUS'serialize(Status);



Open questions:

4)

What type should be used as a common binary representation?

-          BIT_VECTOR

-          STD_LOGIC_VECTOR

-          …



5)

Which encoding should be used for the binary representation?

-          positive binary numbers

-          gray encoding

-          one-hot / one-cold encoding

-          …



My current example uses to_unsigned as a encoding function to convert the enum member position into

a binary representation. While this is a good choise in many use cases, it could be necessary to choose another

encoding schema to reduce logic or increase timing. So should it be possible to pass an encoding parameter to

‘SERIALIZE?



Example:

type T_ENCODING is (BINCODE, GRAYCODE, ONEHOTCODE);



Debugger_Data(3 downto 0) <= T_STATUS'serialize(Status, ONEHOTCODE);





6)

Regarding some comments on stackoverflow, there are also interests for

-          type generics

-          record serialization / de-serialization



7)

Please, feel free to correct the twiki page for any misspelling or other language fault ☺.







Regards

    Patrick




-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
Received on Fri Jun 26 07:48:39 2015

This archive was generated by hypermail 2.1.8 : Fri Jun 26 2015 - 07:48:42 PDT