[sv-ec] Multiple Inheritance Proposal

From: Alsop, Thomas R <thomas.r.alsop@intel.com>
Date: Mon Aug 16 2010 - 12:38:21 PDT

Hi Everyone,

I'd like to run this proposal by the committee to get feedback before uploading an official proposal.

Below you will find what Brandon Tipp (Intel colleague) and I are proposing WRT to the concept of a Java Style interface converted into an SV Multiple Inheritance (MI) implementation. We introduce the concept of first a 'pure virtual class' along with a new 'implements' keyword used to specify one or more 'pure virtual classes' which can be inherited. Conceptually the idea is that any typical class extension can, in addition to inheriting the base class from which it is extended, will additionally inherit and 'implement' the methods from the implemented class(es). The example that follows only 'implements' one pure virtual class but this extended to more than one implementation class by adding comma separated 'pure virtual' classes after the 'implement' keyword.

Please take a look at this example before continuing with the restrictions (below) that we believe must be incorporated into LRM in order to apply correct usage.

pure virtual class rw_byte #(int MAX_ADDR = 63); // Note the parameterization
  typedef enum bit {
    SUCCESS = 1'b0,
    FAILURE = 1'b1
  } status_e;
  pure virtual function status_e write_byte(input bit[MAX_ADDR:0] address, byte data);
  pure virtual task read_byte(output byte data, input bit[MAX_ADDR:0] address);
endclass : BFMIntf

class usbBFM #(int MAX_ADDR = 63) extends vendor1BaseBFM implements rw_byte #(MAX_ADDR);
  function status_e write_byte(input bit[MAX_ADDR:0] address, byte data);
    // implement sending a write on USB
  endfunction : write_byte

  task read_byte(output byte data, input bit[MAX_ADDR:0] address);
    // implement sending a read on USB
  endfunction : read_byte
endclass : usbBFM

class PCIeBFM #(MAX_ADDR = 63) extends vendor2BaseBFM implements rw_byte #(MAX_ADDR);
  function status_e write_byte(input bit[MAX_ADDR:0] address, byte data);
    // implement sending a write on PCIe
  endfunction : write_byte

  task read(output btye data, input bit[MAX_ADDR:0] address);
    // implement sending a read on PCIe
  endfunction : read_byte
endclass : PCIeBFM

program test;
  initial
    usbBFM #(31) usb1BFM = new();
    PCIeBFM #(31) pcie1BFM = new();
    rw_byte #(31) bfm_a[];
    bit [31:0] address;
    byte writeData, readData;

    bfm_a = new[2] ({usb1BFM, pcie1BFM});

    // Generate 100 write-read sequences to each BFM
    for (int i = 0; i < 100; i++) begin
      for (int j = 0; j < bfm_a.size(); j++) begin
        assert(std::randomize(address, write_data));
        assert(bfm_a[j].write_byte(address, write_data) == rw_byte::SUCCESS);
        bfm_a[j].read_byte(read_data, address);
        assert(write_data == read_data);
      end
    end
endprogram : test

So we believe there must be limitation or restrictions that come with this type of usage. These are basically the Java-Style limitations you see with interfaces. We do not believe that SV end users need or want the full MI implementation seen in C++ and that this will enable bad/relaxed usage models and complicate the implementation.

Requirements/Restrictions

* A pure virtual class cannot extend any classes or virtual classes. (Reason - Forcing an already defined method back to pure virtual is ugly. 2) what do you do about data members? 3) This also goes against what should be the thought process... if you have a class or virtual class it is a description of a thing (or a generic thing), but a "pure virtual class" is just the way that a thing can communicate. If you tried to force a "pure virtual class" to extend a class or a virtual class, then you are doing something wrong.)

* A class or virtual class can implement 0 or more pure virtual classes while simultaneously extending 0 or 1 class or virtual class.

* A virtual class is not required to but may provide definition(s) for pure virtual method(s) of a pure virtual class that it implements. (Reason - Virtual classes are abstract classes and do not need to implement the methods. This simply will force the extension of the virtual class to provide the definition of the 'implement'd pure virtual base class.)

* A (non-virtual) class must provide definitions for each of the pure virtual methods declared in all of the pure virtual classes that it 'implements' through the class and pure virtual class hierarchy. (Reason - This is the point where definitions must be provided. Error shall be issued if this is violated)

* It shall be an elaboration error if a class implements two pure virtual classes which each contain the same symbol (eg. if pure virtual class A defines "write" as a constant and pure virtual class B defines "write" as a function prototype, no class can implement both A and B)

* Polymorphism applies to pure virtual classes (This item is up for discussion)

o An instance of a class which implements a pure virtual class can be stored in a variable of the pure virtual class type, or a variable of a parent pure virtual class type.

o $cast() may be used to dynamically cast a variable of a pure virtual class type to a class, virtual class or pure virtual class that implements the pure virtual class.

* It shall not be an error if a sub class implicitly or explicitly implements the same pure virtual class as its parent class. [This may be necessary if you have a sub-class which implements a sub-pure virtual class. E.g. pure virtual class A implements pure virtual class B; class X implements B; class Y extends X implements A... Since class Y extends X, it implicitly implements B, but since it implements A, that also means that it implements B, so class Y implicitly implements interface B two different ways. It shouldn't be an error to implicitly implement the same pure virtual class twice. Also, an instance of class Y can be placed into a variable of type X, Y, A or B.]

Thanks, Tom & Brandon

-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
Received on Mon Aug 16 12:38:53 2010

This archive was generated by hypermail 2.1.8 : Mon Aug 16 2010 - 12:38:57 PDT