Chapter 10. What’s Next

In this final chapter, we look into the near future and give a preview of some features that are being developed by the Accellera VHDL Technical Committee (the VHDL-TC). The focus of the new features is verification and system-level modeling. From a language perspective, VHDL already provides some support for these modeling tasks, in the form of records, access types (pointers), and protected types (shared variables). The new features being developed include class types, verification data structures, randomization, and functional coverage. As much as possible, the new features will build on existing features in the language. Where no existing features meet a need, the new features added will be designed to integrate with the syntax and semantics of other existing features.

The language features described in this chapter are currently being actively worked on in committee. There is a great deal more to each of the proposals than is presented here. However, since the details are still subject to revision, it is too early to publish them. We present an overview to whet the appetite and encourage participation in the development process. The long-term plan is to evolve VHDL from a Hardware Description Language to a Verification and Hardware Description Language.

Object-Oriented Class Types

Class types are a foundation feature for both data structures and randomization. Briefly, a class type encapsulates data and provides operations, called methods, to access and update the data. An object is an instance of a class type. A subclass can inherit data and operations from a superclass, and in doing so, can override the implementation of inherited operations. References to objects can be polymorphic, meaning that they can refer to an object of a nominated class or of any subclass. When a method is invoked via a polymorphic reference, the overriding method of the referenced object’s specific class is executed. This is referred to as dynamic dispatch.

The object-oriented features under development involve basing class type on protected types, since the latter already provide encapsulation of data and methods. We can view a protected type as a class type without inheritance or dynamic dispatch. A side benefit of this approach is that it simplifies the prototyping of data structures and communication protocols using the existing language. For example, if we are to use object-oriented features for verification, we need to implement a number of data structures, including lists, FIFOs, mailboxes, transaction interfaces, scoreboards, and memories. We can already build many of these data structures using protected types. However, the class extension increases their parameterizability, and hence, reusability.

Example 10.1. Using protected class types for FIFO communication

A protected class type definition for a simple bounded FIFO is similar to a protected type as currently provided in VHDL, requiring a declaration and a body:

type BoundedFIFO  is protected class
  procedure put ( e : in  element_type );  --  methods
  procedure get ( e : out element_type );
end protected class BoundedFIFO;

type BoundedFIFO is protected class body

  constant size : positive := 20;
  type element_array is array (0 to size-1) of element_type;

  variable elements : element_array;
  variable head, tail : natural range 0 to size-1 := 0;
  variable count : natural range 0 to size := 0;

  procedure put ( e : in element_type ) is
  begin

     if count = size then wait until count > size; end if ;
     elements(head) := e;
     head := (head + 1) mod size; count := count + 1;
  end procedure put;

  procedure get ( e : out element_type ) is . . .

end protected class body BoundedFIFO;

The class declaration contains the publicly visible data members and methods, in this case, just the methods put and get. The body contains the private data members and the implementations of the methods. The implementation of the put method in this example illustrates a new form of conditional wait that allows a method to suspend until a condition becomes true. This is an enhanced form of concurrency control included in the proposal.

Among the other features included in the class proposal, beyond the basic object-oriented features, is provision for objects of class types to be included as subprogram parameters and ports of components and entities. Moreover, the proposal adopts Java-like interface definitions and multiple inheritance. An interface (as in the Java sense) specifies methods that a class must implement. A given class may implement more than one interface, as well as inheriting from a superclass. The interface feature provides a very powerful abstraction mechanism, as the following example illustrates.

Example 10.2. Communication interfaces

A modular design involves a number of components that communicate with one another. Communication involves a producer putting data into a communications data structure and a consumer getting data from the data structure. We can express the notions of putting and getting as two distinct interfaces that can be implemented by a wide variety of different data structures. The details of an implementation are not relevant to a producer or consumer, only the signature of each interface. Thus, we define two interfaces as follows:

type putable is interface
  procedure put (e : in element_type) ;
  procedure try_put (e : in element_type; ok : out boolean);
end interface putable;

type getable is interface
  procedure get (e : out element_type);
  procedure try_get (e : out element_type; ok : out boolean);
end interface getable;

A mailbox class might implement the putable and getable interfaces as follows:

type mailboxPCType is protected class implements putable, getable
   impure function flag_up return boolean;
   procedure put(e : in element_type);
   procedure try_put (e : in element_type; ok : out boolean);
   procedure get     (e : out element_type);
   procedure try_get (e : out element_type; ok : out boolean);
end protected class mailboxPCType;

The class body would include implementations of the flag_up function and the four procedures.

For a parameter of a subprogram or a port of a component or entity, we can specify an interface as the type rather than a specific concrete class type, as shown in the components declared in the following model:

entity tlm  is
end entity tlm;

architecture structural of tlm is

  component producer is
     port ( shared variable data_source : inout putable );
  end component producer;
  component consumer is
     port ( shared variable data_sink : inout getable );
  end component consumer;

  shared variable MailBox : mailboxPCType;

begin

  u_producer : producer port map ( data_source => MailBox );
  u_consumer : consumer port map ( data_sink   => MailBox );

end architecture tlm;

For the producer and consumer components, we could bind any entities that communicate through the putable and getable interfaces, respectively. Moreover, we could use any concrete class that implements the interfaces, such as the mailboxPC-Type class, to connect the components.

Standard Components Library

Object-oriented language features allow factoring of common code into abstract super-classes, with the inheriting subclasses refining behavior by adding data members and overriding methods. These aspects are put to good use in other object-oriented languages to provide suites of reusable data structures. Examples are the Standard Template Library in C++, the Java collections library, and the Booch Components in Ada.

The VHDL-TC is planning to develop a standard components library along a similar vein. It will include packages defining class types for data structures, using formal generic types for the contained elements. The library will also include packages defining reusable verification components, such as communication interfaces and classes and support for stimulus generators and checkers. The plan is, ultimately, to provide components similar in nature to those that support the Advanced Verification Methodology (AVM) and the Verification Methodology Manual (VMM).

Randomization

One problem in verifying a design with a large verification space and numerous configurable features is how to write enough test cases to adequately test all of the features. For some designs, using the algorithmic features of the VHDL is sufficient to generate the test cases. For other designs, randomization is more appropriate. The randomization proposal under consideration by the VHDL-TC introduces three forms of randomization: basic randomization, class-based randomization, and procedural randomization. These features are similar to those of SystemVerilog; however, their syntax is consistent with other VHDL constructs.

The intent of basic randomization is to provide individual random values. Basic randomization is implemented in a predefined class providing function methods RandReal, Randlnt, RandSlv, RandUnsigned, and RandSigned. Since these functions are encapsulated in a class, the seed is also stored in the class and does not need to be passed as a parameter in a procedure call. Each of the functions has parameters that allow the result to be scaled to a particular range of values.

In class-based randomization, related objects are included as data members of a class. Within the class, relationships are written between the class members. During randomization (using a built-in method), class members are randomized taking these relationships into account. In this manner, meaningful values can be generated to specify a transaction or a sequence of transactions.

Example 10.3. Randomized bus traffic

A class to generate random bursts of traffic on a bus is shown below. In this class, BurstLen specifies the number of values to generate, and BurstDelay specifies the number of cycles to insert between bursts. BurstLen is randomized with values between 1 and 10, inclusive, and BurstDelay is randomized as a function of Burst-Len. If BurstLen is less than 3, BurstDelay has a value between 1 and 6, inclusive; otherwise, BurstDelay has a value between 3 and 10, inclusive.

type TxPacketCType is class

  rand variable BurstLen   : integer;  -- Public Variables
  rand variable BurstDelay : integer;

  constraint BurstPkt is (
     BurstLen in (1 to 10);
     BurstDelay in (1 to 6) when BurstLen <= 3 else
     BurstDelay in (3 to 10);
  );
end class TxPacketCType;

A combination of basic and class-based randomization is shown below. The call to randomize generates a random value for both BurstLen and BurstDelay. Since these objects are public class members, their value can be accessed directly using the same "." notation that is used for records.

TxProc : process
  variable TxPacket : TxPacketCTType;
  variable RV : Randclass;
begin
  . . .
  TxOuterLoop: loop

    TxPacket.randomize;

    for i in 1 to TxPacket.BurstLen loop
       DataSent := RV.RandSlv(0, 255, DataSent'length);
       Scoreboard.PutExpectedData(DataSent);
       WriteToFifo(DataSent);
    end loop ;

    wait for TxPacket.BurstDelay * tperiod_Clk - tpd;
    wait until Clk = '1';

  end loop TxOuterLoop;
  . . .
end process TxProc;

Procedural randomization is a proposed enhancement to VHDL’s sequential constructs. A RandCase feature provides random choice among statements, and a sequence feature allows randomly or deterministically ordered sequences of statements to be executed.

Example 10.4. Random permutation

We can use the RandCase feature to choose a random permutation of statements to execute. The code below loops three times, randomly selecting a statement to execute in each iteration. The RandCase feature uses weights to express relative frequencies of choice among the alternatives. After a statement has been executed, the weight for that alternative is set to 0, preventing the alternative from being executed a second time.

I0  := 1; I1 := 1; I2 := 1;
for i in 1 to 3 loop

  randcase is
     with I0 =>
        CpuWrite(CpuRec, DMA_WORD_COUNT, DmaWcIn);
        I0 := 0; -- modify weight

     with I1  =>
        CpuWrite(CpuRec, DMA_ADDR_HI, DmaAddrHiIn);
        I1 := 0; --  modify weight

     with I2   =>
        CpuWrite(CpuRec, DMA_ADDR_LO,  DmaAddrLoIn);
        I2 := 0; -- modify weight

  end randcase ;

end loop;
CpuWrite(CpuRec, DMA_CTRL, START_DMA  or DmaCycle);

Functional Coverage

Functional coverage is intended to supplement other forms of coverage. Tool based code coverage provides information about what parts of a design are exercised during a simulation. However, it cannot test whether an aspect of the specification for the design is actually implemented. Functional coverage features, on the other hand, allow us to measure the occurrence of difference categories of data values during a simulation. We can thus determine whether processing of categories of interest has been exercised. To measure functional coverage, we specify a bin (a value or range of values) for each category of a data object. During simulation, for each bin, the tool records the number of transactions that produce values in the bin. We can analyze the result to identify bins for which no transactions occurred, and adjust our stimulus generation or randomization constraints accordingly.

The VHDL-TC plans to incorporate functional coverage features into a future extension of VHDL. The details of language features are yet to be determined.

Alternatives

One question that comes up frequently is, why update VHDL? Instead, why not adopt SystemVerilog as the verification language? The answer is much simpler than one would expect. From a language perspective, VHDL already includes many system-level modeling features, such as records, access types (pointers), and protected types. Many of these features can be enhanced with relatively little impact on the language, and new features can be added in a way that integrates cleanly with existing features. From a project perspective, organizations using VHDL already have significant experience using the language. If a verification engineer is needed for a project, the organization has a pool of people familiar with VHDL. A person from that pool can build on their existing knowledge of VHDL, provided the language includes the necessary verification features. If they were to adopt SystemVerilog, they would not only have to learn a language that is quite idiomatically different, but they would also have to manage a multilingual design/verification environment. Both of these issues would adversely affect their productivity.

Getting Involved

Standards development is a volunteer-run effort, and depends on your participation. As you become an experienced VHDL design and/or verification engineer, it is both your right and responsibility to participate. You can participate by submitting enhancement requests, participating in the standards groups, helping with funding, and helping with vendor support.

One person can make a difference. No matter how hard the VHDL-TC works, without your ideas, the group may overlook the changes you desire. You can submit your enhancement requests using the web page at http://www.eda.org/vasg.

VHDL standards are co-developed by IEEE and Accellera. Currently most of the new technical development is done by the Accellera VHDL-TC. The IEEE VHDL Analysis and Standardization Group (VASG) resolves issues with the current IEEE VHDL standard and conducts balloting for new IEEE versions of the standard. For more information about the Accellera VHDL-TC, see http://www.accellera.org/vhdl, and for more information about the IEEE VASG, see http://www.eda.org/vasg.

Volunteers run these standards groups, and members tend to work on what interests them personally. For a request to become a proposal and then a language feature, someone has to champion it. The best way to make this happen is to participate. Participation is open to anyone who has the background and is willing to invest the time. You can join the technical subcommittees, participate in email reflectors, attend teleconferences, attend in-person meetings, and actively participate in all discussions. Most technical decisions are held at a level where everyone can contribute. When decisions have conflicting choices, the issue is put to a member vote. To have a member vote in the Accellera VHDL-TC, your company must join Accellera. To have a member vote in the IEEE VASG, you need to join the parent group, IEEE Design Automation Standards Committee (DASC, see http://www.dasc.org) and maintain an active history of voting participation.

While much of the work is volunteer based, the task of integrating the language change proposals and editing the standard is a time-intensive task and is undertaken by a paid technical editor. This person is a VHDL expert with deep language design knowledge. Currently, this position is funded through Accellera. If your company is able, please encourage them to become an Accellera member and help fund future revisions of the VHDL standard.

Finally, ongoing evolution of VHDL requires vendor support. Part of achieving this is to understand why vendors implement standards. For an EDA vendor, supporting a standard is a business decision. In general, this means they support the features their customers request. Hence, you can influence the process by learning the new features and making the vendors aware of the ones that are important to you. The person with the most power is the person who funds your tool licenses. Make sure they are aware of what you need and make sure to forward your requests through them.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.188.168.28