• Skip to main content
  • Skip to search
  • Skip to footer
Cadence Home
  • This search text may be transcribed, used, stored, or accessed by our third-party service providers per our Cookie Policy and Privacy Policy.

  1. Blogs
  2. Verification
  3. When Less Is More, Part 1: Is e Really Up to 3x More Compact…
teamspecman
teamspecman

Community Member

Blog Activity
Options
  • Subscribe by email
  • More
  • Cancel
IEEE 1647
SystemVerilog
Object Oriented Programming
Functional Verification
OVM
OVM e
OVM SV
e
OOP
ClubT
Aspect Oriented Programming
AOP
IES-XL

When Less Is More, Part 1: Is e Really Up to 3x More Compact Than SystemVerilog?

30 Mar 2010 • 3 minute read
A famous expression in the software world is that “you can only expect 10 good lines of production code per day”.  Web search for this phrase and you will see there is ongoing debate whether this figure is still only 10 lines, or it’s improved to 20, or 100, or more.  One thing that’s not in dispute is that the more lines of code you need to support given task, the more difficult it is for others to comprehend, maintain, and reuse.

Hence, imagine the surprise of the attendees of the “ClubT” in Herzliya Israel last November where an IES-XL end user shared a case study where they had implemented a UVC in both OVM SystemVerilog and OVM e; and the OVM e version was literally half the number of lines of code.  Intrigued by this result, I’ve set out to demonstrate this code reduction for some common testbench tasks.  First, let’s consider stimulus generation.

Let's say we wanted to declare, and generate a simple list of packets to check their contents.  In e, we could do the following in a file called test1.e:


    <'
  type packet_type_t: [TYPE_A, TYPE_B];
  struct packet_s {
    size: uint;
    payload[size]: list of byte;
    keep size in [0..1500];
    type: packet_type_t;
  };
  extend sys {
    packets: list of packet_s;
  };
  '>


The above 12 lines of code would be all that is needed to declare, and generate a randomly sized list of packets.  Each packet in the list will contain random values for size, payload and type.  The construction, allocation and randomization is done during the generation phase automatically in e. 

Now, let's implement, as closely as possible, the same in OVM SystemVerilog in a file called test1.sv:

     import ovm_pkg::*;
   `include "ovm_macros.svh"

    typedef enum {TYPE_A, TYPE_B} my_type_t;

   class packet_c extends ovm_object;
      rand int unsigned size;
      rand byte unsigned payload[];
      rand my_type_t p_type;
      constraint c_size { payload.size() == size;
                                      size inside {[0:1500]};}

      `ovm_object_utils_begin(packet_c)
         `ovm_field_int(size, OVM_ALL_ON)
         `ovm_field_array_int(payload, OVM_ALL_ON)
         `ovm_field_enum(my_type_t, p_type, OVM_ALL_ON)
      `ovm_object_utils_end

      function new (string name="packet_c");
         super.new(name);
      endfunction: new
    endclass : packet_c

   class test1 extends ovm_test;
      packet_c pkt_array[$], cur_pkt;
      task run;
        for (int i=0; i<10; i++) begin
           cur_pkt = packet_c::type_id::create($psprintf("cur_pkt%0d",i));
           if (!cur_pkt.randomize())
              ovm_report_fatal("RANDFAIL", "Randomization Failure of Packet");
             pkt_array.push_front(cur_pkt);
        end
        global_stop_request();
      endtask
       `ovm_component_utils(test1)

       function new(string name, ovm_component parent);
           super.new(name, parent);
       endfunction
   endclass

   module top;
     initial run_test();
   endmodule

The above OVM SystemVerilog code is 37 lines long, which is more than 3 times the number of lines than in the e version.  What you may also notice in the above code is that it requires quite a bit of overhead (ovm base class inheritance, `ovm_* macros, new(), build(), run(), etc).  There are many operations verification users perform on objects such streaming them into bits, copying, randomizing and setting certain fields from testcases. While the SystemVerilog language does have some of these features built-in, it does not have all of them.  Class libraries such as OVM help to address this concern, making it much easier for the SystemVerilog user to perform common verification tasks, hence increasing productivity over SystemVerilog usage alone.  The extra overhead is merely the tradeoff. 

In contrast, the extra overhead is not needed in the e language since e natively supports the concept of "introspection".  This means that all e structs and units are inherently aware of what variables they contain.  Consequently, when performing common verification tasks, such as those mentioned above, all variables are automatically considered.

In the next post I’ll try out this exercise with a coverage description example.  In the mean time, I invite you to challenge your OVM SystemVerilog-using friends to see if they can write a more compact SystemVerilog example then the one I show above.

Happy coding!

Corey Goss
Staff Solutions Engineer
Team Specman

 

© 2025 Cadence Design Systems, Inc. All Rights Reserved.

  • Terms of Use
  • Privacy
  • Cookie Policy
  • US Trademarks
  • Do Not Sell or Share My Personal Information