E (verification language)

Last updated
e
Paradigm Aspect-oriented
Designed by Yoav Hollander
First appeared1992 (1992)
Stable release
IEEE 1647-2019 / June 13, 2019;4 years ago (2019-06-13)
Filename extensions .e
Website TWiki @ eda.org

e is a hardware verification language (HVL) which is tailored to implementing highly flexible and reusable verification testbenches.

Contents

History

e was first developed in 1992 in Israel by Yoav Hollander for his Specman software. In 1995 he founded a company, InSpec (later renamed Verisity), to commercialize the software. The product was introduced at the 1996 Design Automation Conference. [1] Verisity has since been acquired by Cadence Design Systems.

Features

Main features of e are:

Language Features

The e language uses an aspect-oriented programming (AOP) approach, which is an extension of the object-oriented programming approach to specifically address the needs required in functional verification. AOP is a key feature in allowing for users to easily bolt on additional functionality to existing code in a non-invasive manner. This permits easy reuse and code maintenance which is a huge benefit in the hardware world, where designs are continually being tweaked to meet market demands throughout the project lifecycle. AOP also addresses cross cutting concerns (features that cut across various sections of the code) easily by allowing users to extend either specific or all instances of a particular struct to add functionality. Users can extend several structs to add functionality related to a particular feature and bundle the extensions into a single file if desired, providing for more organized file partitioning.

Comments

Executable e code is enclosed within code-segment markers <' and '>:

Example

Anything outside the markers is a comment <' extend sys {   // This is a comment Verilog style   -- This is a comment in VHDL style   post_generate() is also {     out("... and everything else within the markers is executable code.");   }; }; '> 

Classes

e also has two kinds of classes:

A class may contain fields, methods, ports and constraints. Fields can be of type integer, real, enum, string and even complex objects. The code segment shows a unit called 'environment_u' being instantiated within the e root 'sys'. This environment_u class contains a list of 5 packet_s objects and this packet_s class contains two fields and a method.

Example

<' // This is a dynamic class with two fields struct packet_s {   field0: uint (bits: 32);   // This field is called 'field0' and is a                              // 32 bit wide unsigned integer.   field1: byte;             // This field is called 'field1' and is a byte.      // This method is called once a packet_s object has been generated   post_generate() is also {      out(field0);            // Printing the value of 'field0'   }; };  // This is a static class with a list of five packet struct unit environment_u {   my_pkt[5]: list of packet_s; };  // sys is the root for every e environment and instantiates the 'test_env' object extend sys {   test_env: environment_u is instance; }; '> 

Randomization

In e each field is randomized by default. Field randomization can be controlled by hard constraints, soft constraints or even be turned off completely. Soft constraints are used as the default constraints, and may be automatically overridden by the test layer if a conflict occurs. Otherwise it behaves like a regular constraint.

Example

<' struct my_pkt_s {   destination_address: uint (bits: 48);   // this field is randomized and is not constrained.   data_payload       : list of byte;        !parity_field      : uint (bits: 32);   // '!' prevents the parity_field from being randomized.      keep soft data_payload.size() in [64..1500];  // a soft constraint, used to provide a default randomization   keep data_payload.size() not in [128..256];   // this is a hard constraint }; '> 

Assertions

e supports assertions with temporal expressions. A temporal expression is used at the same syntactic level as fields and methods and is thereby declarative by nature. A temporal expression describes timed behavior.

Example

<' unit temporal_example_u {   event a;   // declaring an event 'a'   event b;   // declaring an event 'b'   event c;   // declaring an event 'c'      // This assertion expects that the next cycle after event a   // has been detected that event b followed by event c occurs.   expect @a => {@b;@c} }; '> 

Coverage

e supports coverage that are grouped according to their sampled event and those groups are internally structured with items. Items can be simple items or complex items such as crossed items or transitional items.

Example

unit coverage_example_u {   event cov_event_e;   // collecting coverage will be tied to this event    cover cov_event_e is {     item  a: uint (bits: 4);   // this item has 16 buckets from 0 to 15     item  b: bool;            // this item has two buckets: TRUE and FALSE     cross a, b;               // this item contains a cross multiplication matrix of a and b     trans b;                  // this item is derived of item b and has four buckets                               // transitioning each TRUE - FALSE combination   }; }; 

Messaging & Reporting

Messaging within e can be done with various methods.

Example

unit message_example_u {   example_message_method() is {     out("This is an unconditional, unformatted output message.");     outf("This is an unconditional, formatted output message displaying in HEX %x",15);     print "This is an unconditional message.";     message( LOW, "This is a conditional message, usually tied to a message logger. ",                   "You can also concatenate strings like this and even add objects like ",me,                   " in this output." );     messagef( LOW, "This conditional output is formatted %x.",15 );   }; }; 

Interfacing With Other Languages

An e testbench is likely to be run with RTL or higher-level models. Bearing this in mind, e is capable of interfacing with VHDL, Verilog, C, C++ and SystemVerilog.

Example of an e <-> Verilog Hookup

// This code is in a Verilog file tb_top.vmoduletestbench_top;rega_clk;always#5a_clk=~a_clk;initialbegina_clk=0;endendmodule
This code is in a signal_map.e file <' unit signal_map_u {   // Define a port named 'a_clk_p'   a_clk_p: in simple_port of bit is instance;   // Set the port's hdl_path property to point to the 'a_clk' signal in the top-level testbench   keep a_clk_p.hdl_path() == "~/testbench_top/a_clk"; }; '> 

Aspect-Oriented Programming Support in e

The process of functional verification requires to raise the level of abstraction of any Design Under Test (DUT) beyond the RTL level. This necessity calls for a language that is capable of encapsulating data and models, which is readily available in object-oriented languages. To address this need has been designed to be e an object-oriented language and on top of that has been augmented with aspect-oriented mechanisms that facilitate not only writing highly flexible and reusable testbenches, but also helps verification engineers by enabling to patch discovered RTL bugs without having to rewrite or touch any of the already existing code base.
Aspect-oriented programming in e allows verification engineers to structure their testbench in aspects. An object is therefore the sum of all its aspects, which may be distributed over multiple files. The following sections illustrate basic aspect-oriented mechanisms in e.

Subtyping Mechanism

Subtyping is the prime example of what object-oriented languages without aspect-oriented features can not accomplish. Subtyping allows a verification engineer to add functionality to an already defined/implemented class without having to derive from a base class. The following code shows the original implementation of a base-class and how it is extended. Once the extension took place, all base-class objects contain the extensions as well. The constraints given in the two different subtypes would usually cause a contradiction, however both subtypes are handled separately and thus each subtype yields a different constraint calculation.

Subtyping Mechanism Example

subtyping_example.e <' // This enum type definition is used to declare the subtypes ODD and EVEN type ctrl_field_type_t: [ODD, EVEN]; unit base_ex_u {   // The subtype_field is the determinant field which calculation is being applied   subtype_field: ctrl_field_type_t;   data_word    : uint (bits: 32);   parity_bit   : bit;      // Subtyping the ODD type   when ODD'subtype_field base_ex_u {     // This is a simple constraint that XORs the index bit 0 of data_word and increments that value     keep parity_bit == (data_word[0:0] ^ data_word[0:0] + 1);   };    // Subtyping the EVEN type   when EVEN'subtype_field base_ex_u {     // This constraint is the same as above, however the increment is not done     keep parity_bit == (data_word[0:0] ^ data_word[0:0]);   }; }; '> 

Extending Methods

The original unit definition is given in file1.e. The aspect-oriented mechanism used in this example shows how to execute code before and after an already implemented method.

Method Extension Example

This code is in file1.e <' unit aop_example_u {   meth_ext() is {     out("This is the original method implementation.");   }; }; '> 
This code is in file2.e <' extend aop_example_u {   meth_ext() is first {     out("This method extension is executed before the original method implementation.");   };    meth_ext() is also {     out("This method extension is executed after the original method implementation.");   }; }; '> 

Related Research Articles

<span class="mw-page-title-main">VHDL</span> Hardware description language

VHDL is a hardware description language that can model the behavior and structure of digital systems at multiple levels of abstraction, ranging from the system level down to that of logic gates, for design entry, documentation, and verification purposes. The language was developed for the US military VHSIC program in the 1980s, and has been standardized by the Institute of Electrical and Electronics Engineers (IEEE) as IEEE Std 1076; the latest version of which is IEEE Std 1076-2019. To model analog and mixed-signal systems, an IEEE-standardized HDL based on VHDL called VHDL-AMS has been developed.

Verilog, standardized as IEEE 1364, is a hardware description language (HDL) used to model electronic systems. It is most commonly used in the design and verification of digital circuits at the register-transfer level of abstraction. It is also used in the verification of analog circuits and mixed-signal circuits, as well as in the design of genetic circuits. In 2009, the Verilog standard was merged into the SystemVerilog standard, creating IEEE Standard 1800-2009. Since then, Verilog has been officially part of the SystemVerilog language. The current version is IEEE standard 1800-2023.

In computer engineering, a hardware description language (HDL) is a specialized computer language used to describe the structure and behavior of electronic circuits, most commonly to design ASICs and program FPGAs.

In computing, aspect-oriented programming (AOP) is a programming paradigm that aims to increase modularity by allowing the separation of cross-cutting concerns. It does so by adding behavior to existing code without modifying the code, instead separately specifying which code is modified via a "pointcut" specification, such as "log all function calls when the function's name begins with 'set'". This allows behaviors that are not central to the business logic to be added to a program without cluttering the code of core functions.

In programming language theory, subtyping is a form of type polymorphism. A subtype is a datatype that is related to another datatype by some notion of substitutability, meaning that program elements, written to operate on elements of the supertype, can also operate on elements of the subtype.

In software systems, encapsulation refers to the bundling of data with the mechanisms or methods that operate on the data. It may also refer to the limiting of direct access to some of that data, such as an object's components. Essentially, encapsulation prevents external code from being concerned with the internal workings of an object.

<span class="mw-page-title-main">F Sharp (programming language)</span> Microsoft programming language

F# is a general-purpose, strongly typed, multi-paradigm programming language that encompasses functional, imperative, and object-oriented programming methods. It is most often used as a cross-platform Common Language Infrastructure (CLI) language on .NET, but can also generate JavaScript and graphics processing unit (GPU) code.

In object-oriented programming languages, a mixin is a class that contains methods for use by other classes without having to be the parent class of those other classes. How those other classes gain access to the mixin's methods depends on the language. Mixins are sometimes described as being "included" rather than "inherited".

In computer science, object composition and object aggregation are closely related ways to combine objects or data types into more complex ones. In conversation the distinction between composition and aggregation is often ignored. Common kinds of compositions are objects used in object-oriented programming, tagged unions, sets, sequences, and various graph structures. Object compositions relate to, but are not the same as, data structures.

<span class="mw-page-title-main">SystemVerilog</span> Hardware description and hardware verification language

SystemVerilog, standardized as IEEE 1800, is a hardware description and hardware verification language used to model, design, simulate, test and implement electronic systems. SystemVerilog is based on Verilog and some extensions, and since 2008, Verilog is now part of the same IEEE standard. It is commonly used in the semiconductor and electronic design industry as an evolution of Verilog.

In object-oriented programming, inheritance is the mechanism of basing an object or class upon another object or class, retaining similar implementation. Also defined as deriving new classes from existing ones such as super class or base class and then forming them into a hierarchy of classes. In most class-based object-oriented languages like C++, an object created through inheritance, a "child object", acquires all the properties and behaviors of the "parent object", with the exception of: constructors, destructors, overloaded operators and friend functions of the base class. Inheritance allows programmers to create classes that are built upon existing classes, to specify a new implementation while maintaining the same behaviors, to reuse code and to independently extend original software via public classes and interfaces. The relationships of objects or classes through inheritance give rise to a directed acyclic graph.

In computer programming, the term hooking covers a range of techniques used to alter or augment the behaviour of an operating system, of applications, or of other software components by intercepting function calls or messages or events passed between software components. Code that handles such intercepted function calls, events or messages is called a hook.

Verilog-AMS is a derivative of the Verilog hardware description language that includes Analog and Mixed-Signal extensions (AMS) in order to define the behavior of analog and mixed-signal systems. It extends the event-based simulator loops of Verilog/SystemVerilog/VHDL, by a continuous-time simulator, which solves the differential equations in analog-domain. Both domains are coupled: analog events can trigger digital actions and vice versa.

In computer science, a type punning is any programming technique that subverts or circumvents the type system of a programming language in order to achieve an effect that would be difficult or impossible to achieve within the bounds of the formal language.

Semulation is a computer science-related portmanteau of simulation and emulation, signifying the process of controlling an emulation through a simulator.

Intelligent Verification, including intelligent testbench automation, is a form of functional verification of electronic hardware designs used to verify that a design conforms to specification before device fabrication. Intelligent verification uses information derived from the design and specification(s) to expose bugs in and between hardware IPs. Intelligent verification tools require considerably less engineering effort and user guidance to achieve verification results that meet or exceed the standard approach of writing a testbench program.

<span class="mw-page-title-main">Object-oriented programming</span> Programming paradigm based on the concept of objects

Object-oriented programming (OOP) is a programming paradigm based on the concept of objects, which can contain data and code: data in the form of fields, and code in the form of procedures. In OOP, computer programs are designed by making them out of objects that interact with one another.

The e Reuse Methodology (eRM) was the first reuse methodology to emerge in the Hardware Verification Language space and was used in conjunction with the e Hardware Verification Language. It was invented in 2001 by Verisity Design and released in 2002. The methodology was composed of guidelines for topics such as:

Chisel is an open-source hardware description language (HDL) used to describe digital electronics and circuits at the register-transfer level.

References

  1. Samir Palnitkar: Design verification with e, Prentice Hall PTR. October 5, 2003. ISBN   978-0-13-141309-2

Sources