RE: [vhdl-200x] Updated Enum Attributes twiki page

From: <ryan.w.hinton@L-3com.com>
Date: Mon Jun 29 2015 - 11:38:03 PDT
Lars's last statement is yet another example of "something available to all types" or even better, "something available to all types that fit criterion X."  This seems to be a recurring theme.  The first example that comes to mind is my suggestion to define 'value and 'image for record types (http://www.eda-twiki.org/cgi-bin/view.cgi/P1076/CompositeValueString).  In VHDL there is no way to define something implicitly for all types like e.g. "maximum" and "minimum".  These kinds of features require language changes -- and I suggest the lack of facility for this level of generic programming motivates many of the current and past language change proposals.  I would love to see text removed from the LRM and replaced by attributes and functions added to package STANDARD.

But my wish is just a wish: I don't have any concrete suggestions at the moment.  (For example, how do you specify that an attribute should apply to all scalar types, or all discrete types, or all one-dimensional array types?)  I'm usually against invasive, sweeping changes to the language.  But I also like Brian Drummond's pattern for the language to provide facilities while (library) designers provide functionality.

- Ryan

From: owner-vhdl-200x@eda.org [mailto:owner-vhdl-200x@eda.org] On Behalf Of Lars Asplund
Sent: Friday, June 26, 2015 10:25 AM
To: vhdl-200x@eda.org
Subject: Re: [vhdl-200x] Updated Enum Attributes twiki page

Hello,

Serialization/deserialization is really useful for any type. We've implemented a message passing mechanism for VHDL (https://github.com/LarsAsplund/vunit/blob/master/vhdl/com/user_guide.md) and we use encode/decode functions to serialize/deserialize messages to/from string. This enables us to reuse the same string-based message passing functionality regardless of the message type used. Functions for standard types are easily provided by a package (https://github.com/LarsAsplund/vunit/blob/master/vhdl/com/src/com_codec.vhd) but user messages are often of a custom type, typically a record. You can build your own encode/decode functions from the standard functions but this is a rather time consuming task. To make this convenient we had to write a code generator that creates these functions from the type definitions. If VHDL had support for serialization/deserialization of standard as well as custom types we would be able to do this entirely within the language itself.

Best Regards,

Lars Asplund

On 26 June 2015 at 16:48, Lehmann, Patrick <patrick.lehmann@tu-dresden.de<mailto:patrick.lehmann@tu-dresden.de>> wrote:
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<http://www.mailscanner.info/>, and is
believed to be clean.


--
This message has been scanned for viruses and
dangerous content by MailScanner<http://www.mailscanner.info/>, and is
believed to be clean.

-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
Received on Mon Jun 29 11:38:18 2015

This archive was generated by hypermail 2.1.8 : Mon Jun 29 2015 - 11:38:31 PDT