VHDL-2019

The VHDL Analysis and Standardization Group (VASG), has been working for quite some time on finishing the draft for the upcoming VHDL-2019 revision of the language. The ballot has been held, and a list of approved changes has emerged.

What’s left before this becomes the latest revision of the VHDL language is for the draft to be reviewed by the IEEE Standards Review Committee. With their approval, IEEE 1076-2019 will become the official standard.e

Unfortunately, work on the draft has been delayed*.

* Update (Feb 10th, 2020): The new VHDL standard was approved on Sept 5, 2019.
    Purchase the 1076-2019 Language Reference Manual from IEEE.

VHDL-2017? VHDL-2018? VHDL-2019?

Due to the delay, what started off as VHDL-2017 is now VHDL-2018, and is likely to become VHDL-2019 before the standard is approved. This has led to a slight confusion about the name of the revision. Some websites refer to it as VHDL-2017, others VHDL-2018, while VHDL-2019 might be the one that prevails.

VHDLwhiz has been in touch with Jim Lewis, chair of VASG, who is responsible for maintaining the VHDL standard. Work on the revision has been delayed due to problems finding a person to edit using Adobe Framemaker. Mr. Lewis says: «at this point it will be 1076-2019».

Highlights

Vendors who aim to support the bleeding edge of VHDL revisions must incorporate a long list of new features and changes into their tools. So how can VHDL-2019 make your life better?

Here are some highlights of the upcoming VHDL-2019 revision:

For a more detailed description of the changes and new features, continue reading the rest of this post.

Approved changes

Each of the proposed changes can be identified by a Language Change Specification (LCS) number on the format LCS-2016-NNN. The details can be viewed on the EDA wiki, but the rest of this section will explain the implications of each LCS using straightforward examples and uncomplicated language.

Partially connected vectors in port maps

LCS-2016-001

This is a very welcome change which will serve to make module instantiation less annoying. Currently, whenever you assign an interface array of mode out to a signal, you have to assign every bit of the array. In VHDL-2019 you will be allowed to declare the subelements as unconnected by using the open keyword:

i_MyModule : entity work.MyModule(rtl)
port map(
    Port8(7 downto 4) => SlvNibble,
    Port8(3 downto 0) => open
);

Similarly, you will be allowed to connect only selected bits of ports with mode in or generic ports. Of course, there will still have to be a default value set in the port declaration.

This change isn’t functionally important, but it fixes something that has been irritating. You’ve had to declare an intermediate signal to assign to a long port, only to leave half of the bits unused. Now we can assign the shorter signal directly to the port, and leave the unused bits disconnected. Overall, it’s a change that makes VHDL feel a bit more flexible.

Access, file, and protected types are now allowed as subprogram parameters in protected types

LCS-2016-002, LCS-2016-004

This change affects functions and procedures declared in protected types. They can now have parameters that are access, file, and protected types.

Extensions to the file type

LCS-2016-006a

New subprograms for manipulating files have been added to the TEXTIO package.

New procedures:

  • FILE_REWIND: Move the position to the start of the file
  • FILE_SEEK: Move the position back or forth
  • FILE_TRUNCATE: Set the size of a file. Can be used for shrinking or growing files

New function:

  • FILE_STATE: Returns the state of a file, open or closed
  • FILE_MODE: Returns the mode of a file, read, write, etc.
  • FILE_POSITION: Returns the position of the file
  • FILE_SIZE: Returns the size of a file
  • FILE_CANSEEK: Returns true if seek is supported

Added read/write mode to file types. Previously, a file had to be opened either for reading or writing. Now, you can get both.

New Directory API

LCS-2016-006c

New functions, procedures, and types for handling directories have been added to the ENV package. The standard environmental package (ENV), which was introduced in VHDL-2008, has been extended with subprograms for reading and writing in directories on the native filesystem.

New subprograms include:

  1. DIR_OPEN: Open dir and return a record containing the directory items
  2. DIR_CLOSE: Deallocate directory object.
  3. DIR_ITEMEXISTS: Check if file or dir exists
  4. DIR_ITEMISDIR: Check if the dir exists
  5. DIR_ITEMISFILE: Check if the file exists
  6. DIR_WORKINGDIR: Sets the working dir
  7. DIR_CREATEDIR: Create a new dir
  8. DIR_DELETEDIR: Deletes an empty dir
  9. DIR_DELETEFILE: Delete a file

Read environment variables

LCS2016_006e

Finally, this much-wanted feature will be implemented in VHDL. The ability to read environment variables will be ensured by two new functions in the ENV package.

impure function GETENV(Name : STRING) return STRING;
impure function GETENV(Name : STRING) return LINE;

Standard environment awareness

LCS2016_006f

These additions to the ENV package will reveal things like VHDL version, tool type, and vendor. Definitely useful functions to have when you are developing code that needs to be aware of such specifics.

impure function VHDL_VERSION return string ;
function TOOL_TYPE return string ;
function TOOL_VENDOR return string ;
function TOOL_NAME return string ;
function TOOL_EDITION return string ;
function TOOL_VERSION return string ;

Sequential block statement

LCS2016_007, LCS2016_007a

The block statement is an old feature in VHDL. It is used for separating logic within an architecture, limiting the scope of signals to within the block. What is new in VHDL-2019 is that the block statement can be used in sequential logic, within a process or subprogram.

A trivial example to illustrate such usage:

process is
  variable MyVar : integer;
begin
  
  InnerBlock : block
    variable InnerVar : integer;
  begin
   
    -- InnerVar is only visible in here
   
  end block ;
   
  wait;
end process;

Date and time

LCS2016_011

A set of new types and functions in the ENV package will give access to the local date and time.

New types are:

type DAYOFWEEK is (
  SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY,
  FRIDAY, SATURDAY
);
 
--
type TIME_RECORD is record
  microsecond : INTEGER range 0 to 999_999
  second      : INTEGER range 0 to 61;
  minute      : INTEGER range 0 to 59;
  hour        : INTEGER range 0 to 23;
  day         : INTEGER range 1 to 31;
  month       : INTEGER range 0 to 11;
  year        : INTEGER range 1 to 4095;
  weekday     : DAYOFWEEK;
  dayofyear   : INTEGER range 0 to 365;
end record TIME_RECORD;

New subprograms include:

  • LOCALTIME: Local time
  • GMTIME: UTC time
  • EPOCH: Epoch time
  • TIME_TO_SECONDS: Convert to seconds in real
  • SECONDS_TO_TIME: Opposite conversion

Additionally, there are TO_STRING functions which will come in handy for logging purposes. They generate string timestamps on the format “YYYY-MM-DDTHH:mm:ss”.

Even better, there exists overloaded + and - operators for incrementing or decrementing the TIME_RECORD.

String representation of composite types

LCS2016_012

Through the T'image(X) attribute you will be able to get a string representation of composite types. Records will convert into comma-separated strings within parentheses, such as ("1001000", '0', 0, 3.14).

Similarly, the T.value(X) attribute can be used to fill records with values stored in the string format. In this case, extra spaces will be ignored.

Composites of protected types

LCS2016_014

This change will allow the class-like objects of protected types to be stored in composite types. In other words, you can create arrays with them, or they can be members of a record.

When passing a protected type as a parameter to a function, it shall be passed by reference. This means that you can enjoy bouncing the class-like objects back and forth, just like you would do in any other object-oriented programming language.

Access types to protected types

LCS2016_014a

With this change, the designated type of an access types can be a protected type. Access types in VHDL are pointers to an object, and protected types are class-like constructs which you can create objects of. In more regular programming language terms, VHDL already had both pointers and classes.

In VHDL-2019 you will be allowed to create pointers to objects of protected types. You will also be able to create pointers to file types, as well as objects and file types that are composites of protected types.

Get calling path and stack info

LCS2016_015

This is an addition to the standard ENV package which lets you get call path information for the current stack frame. By calling the GET_CALL_PATH function from the ENV package, a pointer to a vector of records will be returned. The leftmost element in the record will be the current stack frame, while the rightmost element is the root of the call stack.

The vector contains a record of the following type:

type CALL_PATH_ELEMENT is record
  name             : LINE;
  file_name        : LINE;
  file_path        : LINE;
  file_line        : POSITIVE;
end record;

The name element refers to the name of the current subprogram or construct. The other elements in the record contain information about the calling position in the VHDL file.

Get current line and file

LCS2016_015a

Another addition to the ENV package. Six new functions that will get the name and path of the current VHDL file, as well as the line number which is executing:

impure function FILE_NAME return LINE ;
impure function FILE_NAME return STRING ;
impure function FILE_PATH return LINE ;
impure function FILE_PATH return STRING ;
impure function FILE_LINE return POSITIVE ;
impure function FILE_LINE return STRING ;

Anonymous types in interface lists

LCS2016_016

This change allows anonymous types in interface list declarations, like ports or subprogram’s parameter lists. Instead of specifying std_logic_vector or bit_vector, you will be able to write <>, which covers all scalar types. The possible type categories are private, scalar, discrete, integer, physical, and floating.

Example usage of this feature:

Architecture A of E is
  signal SigA : std_logic_vector(7 downto 0) ;
  signal SigB : std_logic ;
  component E is
    port (
      A : type is private ; -- any type
      B : type is <>        -- a scalar type
    ) ;
  end component E ;
   
begin
  E1 :  E
  port map (
    A => SigA  ;
    B => SigB
  ) ;
...

Attributes for Enumerated Types

LCS2016_018, LCS2016_018a, LCS2016_018d

A number of new attributes have been defined for enumerated types:

  • ‘LENGTH
  • ‘RANGE
  • ‘REVERSE_RANGE
  • ‘IMAGE
  • ‘POS
  • ‘SUCC
  • ‘PRED
  • ‘LEFTOF
  • ‘RIGHTOF
  • ‘INDEX[(N)]
  • ‘DESIGNATED_SUBTYPE

Most of these attributes should be known to you already, as they have existed for scalar types before. Now you can use them for enumerated types as well.

Infer signal and variable subtype constraints from initial value

LCS-2016-019

When dealing with ports of unconstrained types, defining signals and variables with derived types has been cumbersome. This change is perhaps better explained with the example taken from here.

Currently, you must do this:

entity
port (
a_port : sfixed;
b_port : sfixed;
...
 
-- don't care about actual value, just subtype
constant prod_proto : sfixed := a_port * b_port;
 
-- use constant just to get the appropriate subtype
variable prod       : prod_proto'subtype;
...
 
prod := a_port * b_port;

In VHDL-2019, you will be allowed to do this:

entity
port (
a_port : sfixed;
b_port : sfixed;
...
 
-- NO DUMMY CONSTANT NEEDED
variable prod       : sfixed := a_port * b_port;
-- the initial value may not be meaningful, but the subtype of the
-- result is used to constrain the variable type.
 
...
 
prod := a_port * b_port;

Allow configuration and entity libraries to differ

LCS-2016-023

Currently, entities must be defined in the same library as their configurations. This requirement has now been relaxed.

Long integers

LCS-2016-026c

Finally, VHDL number types are catching up with the 21st century. The INTEGER type has been increased from 32 to 64 bits.

Access external types through the library path

LCS-2016-028

This added language feature allows you to hierarchically reference a type or subtype. Hierarchical signal access has been available since VHDL-2008 through the use of the << library_path >> construct. Now, you can also reference types and subtypes by using the following syntax:

architecture_path_name ::= entity_simple_name ( architecture_simple_name)

This is useful in verification scenarios where the testbench needs to have access to a type that is declared in the module. Usually, this is solved by declaring the type in a package common both the testbench and the RTL module. Another way to solve this has been to redefine the type in the testbench.

With this change, it can be accomplished in the testbench by hierarchically referencing the type in the module where it is declared:

alias extStateType is work.EntityName(ArchitectureName).StateType;

Garbage collection

LCS-2016-030

In the code below, there is a potential memory leak. In VHDL-2019, you won’t have to worry about that because it has automatic garbage collection. As soon as the last reference to an object is lost, it shall be deallocated.

function to_string (
  value      : in integer_vector
) return string is
  variable L : line;
  begin
  write(L, value) ;
  return  L.all ;
end function to_string ;

More explicit ‘PATH_NAME and ‘INSTANCE_NAME paths

LCS-2016-032

There are changes to the attributes for getting the hierarchy path of an object. They have been changed to include the full package name and instance path, even when the object resides within a protected type.

This is useful, especially for algorithms that rely on having a unique string descriptor for an object. For example RandomPck’s InitSeed procedure.

Public variable declaration in protected types and the PRIVATE keyword

LCS-2016-033

The word private has been added to the list of reserved words in VHDL.

Currently, the declarative region of protected types cannot include variable declaration. This is usually solved by using getter and setter subprograms. Now, you can simply add the variable declarations to the protected type declaration to make them public.

Furthermore, you can make a variable private by using the new private keyword. Then, you can expose a member of the private variable by creating an alias for it:

package MyPkg... is
  type MyPkg is protected
  private shared variable Name : MyType;
  alias SetMessage is Name.SetMessage [String];
  alias WriteMessage is Name.WriteMessage;

Generics on protected types

LCS-2016-034

This change allows generics to be mapped to an object of protected type when a variable is created of it. Kind of like the function template in C++, types can now be specified when creating the object. You can avoid hard-coding types within the protected type, making them more versatile.

An example shared variable declaration using generics:

shared variable MyVar : MyType generic map (
  InternalType => integer
);

Conditional assignment of initial values

LCS-2016-036a

Conditional assignments have previously been allowed for signals in the architecture of the VHDL file. Now, you can use the same shorthand format within the declarative region as well.

It will be allowed to assign to constants conditionally like this:

constant T : time := 1 ns when GenericBoolean else 10 ns;

New ‘reflect attribute

LCS-2016-41

This change introduces a new 'reflect attribute to VHDL. Calling this attribute function will return a new object of protected type, which has a copy of the current state of the object. The name of the new protected type is VALUE_MIRROR.

Example code from the LCS:

-- The following complex data type shall be converted to a string:
 
process
  type Rec is record
    I : INTEGER_VECTOR(0 to 3);
    R : REAL;
    T : TIME;
  end record;
  
  constant test : Rec := (
    I => (1, 3, 7, 9),
    R => 3.14,
    T => 25 ns
  );
 
  variable mirror : VALUE_MIRROR := test'reflect;
begin
  report to_string(mirror);
  wait;
end process;
 
-- result:
-- (I => (1, 3, 7, 9), R => 3.14, T => 25 ns)

New PSL attributes and functions

LCS-2016-43

The following functions have been added to the ENV package to make Property Specification Language (PSL) more usable with VHDL:

-- PSL Assert Failed
impure function PslAssertFailed return boolean ;
 
-- PSL Is Covered
impure function PslIsCovered return boolean ;
 
-- Psl Cover Asserts
procedure SetPslCoverAssert( Enable : boolean := TRUE) ; 
impure function GetPslCoverAssert return boolean ;
 
-- Psl Is AssertCovered
impure function PslIsAssertCovered return boolean ; 
 
-- Clear PSL State (Assert and Cover)
procedure ClearPslState ;

Additional 'signal and 'event attributes have been added to PSL objects.

Separate modes for composite type members

LCS-2016-45a, LCS-2016-45b, LCS-2016-45c

Previously, we have been forced to give composite types in port declarations the same mode (in, out e.g.) for all of its data members. Now, we can give modes to each individual member of records or arrays. Thus, you can implement an interface using records without resorting to using the inout mode on every entity where it’s used.

Two new mode keywords have been introduced in VHDL; view and null. The view mode enables individual mode control of the composite type members. Example taken from the EDA wiki:


port(
  rst_i       : in     std_logic;
  clk_i       : in     std_logic;
  cpu_bus_rif : view   cpu_bus_r(
    element(
      arbiter_al : view arbiter_a(
      element(
        others : view   arbiter_r;
        element(
          master_rl   : in     master_r;
          bus_req_l   : in     std_logic;
          bus_grnt_l  : buffer std_logic

The null mode can be used to denote unconnected interface objects:

port configuration SLAVE_pcfg is
generic(
  SEL_jg : SEL_jst
  );
port(
  MASTER_rl : in;
  SLAVE_al  : composite(
  SEL_jg    : buffer;
  others    : null
  )
);
end port configuration SLAVE_pcfg;

Shared variables on entities

LCS-2016-47

You will finally be allowed to send shared variables of protected type through entity ports. With this change, you should be able to write some creative testing strategies, for instance, by passing scoreboards passed between verification components.

Generics on subprograms

LCS-2016-49

Subprograms can now* have generics in addition to the normal parameter list. The advantage of this is that you can pass types through the generic parameters, eliminating the need for an overloaded version of the subprogram for each data type.

* Update (Feb 18th, 2021): Actually, generics on subprograms have existed since VHDL-2008. But VHDL-2019 brought some refinements to the specification. See LCS-2016-49 in the EDA wiki.

Thanks to Richard from the comment section for the clarification!

Example taken from EDA wiki:

function Mux4
    generic ( type DataType ) 
    parameter (
      MuxSel :   in std_logic_vector(1 downto 0) ; 
      A, B, C, D :  in DataType
   ) return DataType is
   . . . 
end function Mux4; 

New assert API utility subprograms

LCS-2016-50

The following new subprograms have been added to the ENV package to help with assertion-based verification in VHDL:

-- VHDL Assert Failed
impure function IsVhdlAssertFailed return boolean ; 
impure function IsVhdlAssertFailed (Level : SEVERITY_LEVEL ) return boolean ; 
 
-- VHDL Assert Count
impure function GetVhdlAssertCount return natural ; 
impure function GetVhdlAssertCount (Level : SEVERITY_LEVEL ) return natural ; 
 
--  Clear VHDL Assert Errors
procedure ClearVhdlAssert; 
 
-- Assert Enable, Disable/Ignore Asserts 
procedure SetVhdlAssertEnable(Enable : boolean := TRUE) ;
procedure SetVhdlAssertEnable(Level : SEVERITY_LEVEL := NOTE; Enable : boolean := TRUE) ; 
impure function GetVhdlAssertEnable(Level : SEVERITY_LEVEL := NOTE) return boolean ; 
 
--  Assert statement formatting
procedure SetVhdlAssertFormat(Level : SEVERITY_LEVEL; format: string) ;
procedure SetVhdlAssertFormat(Level : SEVERITY_LEVEL; format: string; Valid : out boolean) ;
impure function GetVhdlAssertFormat(Level : SEVERITY_LEVEL) return string ; 
 
--  VHDL Read Severity
procedure SetVhdlReadSeverity(Level: SEVERITY_LEVEL := FAILURE) ; 
impure function GetVhdlReadSeverity return SEVERITY_LEVEL ;

Relax component end syntax

LCS-2016-55a

This change makes the end component; optional. Now, you can write just end;. The syntax has previously been a bit inconsistent with the “entity” in end entity; being optional, while “component” was mandatory in end component;.

Type class insurance for generic types

LCS-2016-59

This change allows arrays of generic types to be constructed of a preceding type on the same generic port. Previously, types passed through a generic port could not be used as part of a subprogram or array in the same generic port. Now, the type class (scalar, array, e.g.) will be determined before elaboration time. Thus, attributes like 'length or 'range can also be used.

Example taken from the EDA wiki

entity mux
  generic (
    type ELEM;
    type ARR is array (integer) of ELEM);
  port (
    inputs : in  ARR;
    select : in  integer;
    muxed  : out ELEM);
end entity;

Use relational operators with arrays of scalar types as operands

LCS-2016-59a

In VHDL-2019, you will be allowed to use relational operators like = or < to compare arrays of scalar types, for example integer.

Conditional analysis

LCS-2016-61

Much like the beloved C preprocessor, VHDL-2019 has the ability to include or exclude blocks of code based on the value of a constant. Tools are required to support a syntax on the form:

`if G_MY_GENERIC then
    attribute my_attribute_typ : string;
    attribute an_attribute of my_attribute_typ: signal is "value";
`else
    --nothing is created
`end if

The possibilities are endless. You could set the constant in the VHDL code where the module is instantiated, or it could be set from the TCL script, which starts the compilation or synthesis. Either way, it enables you to drastically change the function of the module, making it more versatile.

Note that the “`” character is mandatory in front of all tool instructions. See Mr. Lehmann’s comment in the comment section.

Optional trailing semicolon in interface lists

LCS-2016-71a

This is an unimportant change, but it is one that will save you a lot of time in the long run!

You know, when you make some changes to the entity of a module, perhaps you remove the last signal from the interface list. Then, when you try to compile, you get the annoying near “)”: (vcom-1576) expecting IDENTIFIER.” error because you forgot to remove the trailing semicolon from the second last signal.

Now, a trailing semicolon after the last signal on the interface list has been made optional. You can do this:

entity someEntity is
port
(
    a : std_logic;
    b : integer; -- This trailing semicolon is optional
);
end entity;

Functions will have knowledge of the array bounds of the receiver of the return value

LCS-2016-72b

This change allows functions to access attributes belonging to the receiver of its return value. An annoying side effect of not knowing anything about the signal that its return value is to be assigned to is evident in the to_unsigned function:

x <= to_unsigned(i, x'length);

You have to include the array length of the receiver of the return value as a parameter because the function has no way of knowing it. Now, you can simply do this:

x <= to_unsigned(i);

This is possible because the receiving signal can optionally be referenced from within the function.

It is not only limited to standard functions like to_unsigned. You can use this in your own custom functions as well. The function specification has changed, the new optional handle of the receiver of the return value is denoted in red:

function_specification ::=
  [ pure | impure ] function designator
  subprogram_header
  [ [ parameter ] ( param_list) ] return [ return_identifier of ] type_mark

LCS-2016-75

An automatic cast from one record type to another if each element of the source record can be implicitly converted to a matching element in the destination record.

An example of two closely related record types:

type SourceRec is record
  a : natural;
  b : real;
  c : boolean;
end record;
 
type DestRec is record
  d : integer;
  e : real;
  f : boolean;
end record;

Allow empty records

LCS-2016-82

Records with no data members will be allowed. Now you can kick off your design by specifying interfaces as empty records before completing them at a later stage.

An empty record:

type MyRecord is record
end record;

Use interface objects later in the same interface list

LCS-2016-86

This allows you to use an object listed in an interface list, later in the same interface list to provide an initial value or to access an attribute.

An example taken from the LCS:

entity E is
  generic (G1: INTEGER; G2: INTEGER := G1; G3, G4, G5, G6: INTEGER);
  port (P1: STRING(G3 to G4); P2: STRING(P1'RANGE); P3: P1'SUBTYPE);
  procedure X (Y1, Y2: INTEGER; Y3: INTEGER range Y1 to Y2; Y4: Y1'SUBTYPE);
end E;

Conditional return statement

LCS-2016-94a

In VHDL-2019 you will be able to write return statements on the When-Else form instead of wrapping them in If-Then-Elseif-Else statements. This is the new accepted format:

return (<expression 1>) when <condition 1> else
       (<expression 2>) when <condition 2> else
       (<expression N>);

Return statements are still mandatory in functions.

Range record

LCS-2016-99

Two new attributes have been defined, which can be applied to ranges. The first one is R'RECORD which will get the range record type on the format:

type <unnamed_range_record> is record
  Left      : <scalar_type>;
  Right     : <scalar_type>;
  Direction : DIRECTION;
end record;

The second attribute is R'VALUE which will retrieve the values for the given range. This feature will come in handy for anyone who wishes to perform calculations on ranges of scalar types.

When can I start using VHDL-2019?

Even though VHDL-2008 has been around for quite a few years, not all tools support it yet. Most of the new functionality and changes are not intended to be synthesizable. They are testbench features. Therefore, the best we can hope for is that the simulator vendors will adopt VHDL-2019 before the end of the decade.

The only simulator that claims to support VHDL-2019 is Aldec Riviera-PRO. Aldec refers to the standard as “VHDL 2018”.

Update (Feb 10th, 2020): The new VHDL standard was approved on Sept 5, 2019.
    Purchase the 1076-2019 Language Reference Manual from IEEE.

Similar Posts

20 Comments

  1. The statements of “CONDITIONAL COMPILATION” are not correct.

    At first, it’s called “conditional analysis” see LRM 24.2 Conditional analysis tool directives.
    At second, your code example misses the “`” characters in front of all tool instructions.
    At third, there is no “;” after “`end if” (see LRM 24.2.1).

    `if G_MY_GENERIC then
        attribute my_attribute_typ : string;
        attribute an_attribute of my_attribute_typ: signal is "value";
    `else
        --nothing is created
    `end if
    

    The feature “BIDIRECTIONAL CONCURRENT ASSOCIATIONS” was skipped last minute and is not part of VHDL-2019.

    1. Hi Patrick,

      I have updated the blog post with your corrections. I’ve also added a link to the finished VHDL Language Reference Manual in the IEEE webshop.

      Thank you for making this article better and for your work in the VHDL standardization working group.

  2. Hi Jonas,
    You realize that creating a great list like this automatically volunteers you to participate in the next revision of the standard. 🙂
    Best Regards,
    Jim Lewis
    VHDL 1076 WG Chair

    1. Thanks, Jim.

      I feel honored to hear that from you. It’s just that I’m a bit overworked with my current projects, and I don’t like doing things halfway good. Let me take a good look at my options once again.

      Jonas

  3. This is the best VHDL2019 site I have found so far, many thanks for creating it! For the VHDL users reading this, if you pay thousands of euros/dollars/pounds/etc for you simulator maintenance you are entitled to ask them to implement this standard. However, don’t just ask for the whole standard, tell them which feature you like and why you would use them. R&D is expensive and EDA companies rather spend their R&D budget on SV as they mistakenly believe it is a better investment. I have asked for the pre-processor as I already use VPP in my projects. It was rejected which was very disappointing as this is probably one of the easiest VHDL2019 feature to add.

    1. Hello Richard, and thanks for the kind words! I think so too. Eventually, the EDA companies will implement what they think sells. If the customers make it clear that they want VHDL features fully supported, I’m sure the tools will follow. Perhaps I should advocate this more 🙂

  4. Great article.

    Could you please provide an example of how to use the new optional handle of the receiver of the return value in custom functions?

    i.e.:

    "return_identifier of" 
    
    1. I’ve figured it out now. Here’s an example:

      function ConvertToSlv(constant i: in integer) return TResult of std_logic_vector is
          variable result: TResult;
      begin
          result := std_logic_vector(to_signed(i, result'length));
          return result;
      end function;
      
      signal int: integer := 8;
      signal sig: std_logic_vector(7 downto 0);
      ...
      sig <= ConvertToSlv(int);
      

      I was thrown by the misnomer and bad grammar of “return_identifier of” in the LRM. It’s actually the ‘type of the return identifier’ rather than the ‘return identifier’ itself.

        1. Thanks. Afterwards, I realised that there is no need for the intermediate variable, so the example reduces to:

          function ConvertToSlv(constant i: in integer) return TResult of std_logic_vector is
          begin
              return std_logic_vector(to_signed(i, TResult'length));
          end function;
          

          Perhaps this has what has given rise to the misnomer of “return_indentifier” because ostensibly you could replace “TResult” with “my_actual_variable” and you would be none the wiser in this simple example. I discovered the difference when I experimented with a more complex example trying to use “return_indentifier” as an actual variable and the compiler gave an error.

          However, the intermediate variable could be useful for cumulative operations in a more complex custom function.

          Try it here on EDA Playground where I’ve included some conversion procedures as well:
          https://www.edaplayground.com/x/qJLb

  5. “Generics on subprograms”

    This is not a VHDL 2019 feature. It has been available since VHDL 2008. In addition the example starts as a function but ends as a procedure.

  6. “Access and protected types as subprogram parameters”

    Access types have been allowed as subprogram parameters since VHDL 87 (read/write(line, var) being a perfect example), but not on protected types

    Protected types have been allowed as subprogram parameters since protected types were added VHDL 2002. Again, not on protected types.

    I think you need to clarify this section as “Access, file and protected types are now allowed as subprogram parameters in protected types”

  7. “Anonymous types in port declarations”

    From reading the wiki, this doesnt apply only to port specifications, but any interface list (like functions, procedures etc).

  8. First of all, thank you for the awesome and comprehensive overview!
    I appreciate the new option of trailing semicolons in interface lists (3.35). However, what about generic and port maps, or aggregates in general? are there trailing commas allowed?

    1. No, it’s only the trailing semicolon in interface lists that is allowed according to the VHDL-2019 Language Reference Manual:

      interface_list ::=
         interface_element { ; interface_element } [ ; ]

      The BNFs for associations and the like don’t have any optional trailing commas:

      association_list ::=
         association_element { , association_element }
      record_element_list ::=
         record_element_simple_name { , record_element_simple_name }

Leave a Reply

Your email address will not be published. Required fields are marked *