Cadence.com will be under maintenance from Friday, Oct. 3rd at 6pm (PST) thru Sunday, Oct 5th at 11pm (PST).
Cadence.com login, registration, community posting and commenting functionalities will be disabled.
Home > Community > Blogs > Functional Verification > when less is more part 2 is e code really up to 3x more compact than systemverilog
 
Login with a Cadence account.
Not a member yet?
Create a permanent login account to make interactions with Cadence more convenient.

Register | Membership benefits
Get email delivery of the Functional Verification blog (individual posts).
 

Email

* Required Fields

Recipients email * (separate multiple addresses with commas)

Your name *

Your email *

Message *

Contact Us

* Required Fields
First Name *

Last Name *

Email *

Company / Institution *

Comments: *

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

Comments(1)Filed under: Functional Verification, OVM, CDV, SystemVerilog, coverage driven verification (CDV), e, IEEE 1647, OVM e, Aspect Oriented Programming, AOP, OVM SV, IES-XL

In my last post I wrote some packet generation code to validate the claim that e code can be up to 3 times more compact vs. the equivalent functionality in SystemVerilog.  The result was actually an e description that was more than 3x less than the SystemVerilog equivalent.  In this post, let’s see if these lopsided ratios carry forward to coverage as well.

If a user wanted to add coverage to the generation example given in the last post, in e one could extend the packet_s struct and add coverage via an extension to the base struct.  (Even better: you could put this code in a completely separate file, leaving the base code intact.  This allows the user flexibility to maintain a separate set of files just pertaining to coverage, which increases modularity of the environment and permits engineers to work in parallel teams -- one team focused on adding new functionality, another team working on coverage; where the teams’ relative independence acting as a built-in safety measure.  But I digress …)

For example, consider this e coverage code that covers the fields of the previously defined packet_s struct, implemented in a file called test2.e:

     <'
    import test1;  //Needed to obtain the packet definition

    extend packet_s {
       event cover_me;
       cover cover_me is {
          item size using ranges = {range([0..1500],"",1);};
          item type;
       };
       post_generate() is also {
          emit cover_me;
       };
    };
    '>

The above totals 13 lines of code.  The test1.e file was created in my previous post.

Now, to add coverage in SystemVerilog to a pre-existing structure users have two options:

  1. Edit the base class code
  2. Create a new class that inherits from the base class and add the coverage there. 

Option (1) would result in a relatively compact description; however, it also means that the user would be modifying code that could potentially be used by multiple objects in the environment, and even multiple teams within the company, which is not desirable as other teams may not require or desire to have this extra functionality added.  Hence, a true apples-to-apples comparison that would give the SystemVerilog user the same modularity as the e code would be option (2).  Thus, consider the following code that’s written to match to all the same specs, in a file called test2.sv:

     class packet_cov extends packet_c;
       `ovm_object_utils_begin(packet_cov)
       `ovm_object_utils_end
       event cover_me;

       covergroup cg_cover_me @(cover_me);
          coverpoint size {option.auto_bin_max = 1500;}
          coverpoint p_type;
       endgroup

       function new (string name="packet_cov");
          super.new(name);
          cg_cover_me = new;
       endfunction: new

       function void post_randomize();
         cg_cover_me.sample();
       endfunction
    endclass : packet_cov

    class test2 extends test1;

        function void build();
          set_type_override_by_type(packet_c::get_type(), packet_cov::get_type());
        endfunction
        `ovm_component_utils(test2)

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

The above 25 lines of code would represent the best case situation as it assumes that the user would like the exact same functionality in test2 as they did in test1 (hence we can inherit directly from it), which might not necessarily be the case. 

Of course in any verification project, you almost always need to add to or refine pre-existing coverage items. In e, this can be done using the Lego-like, Aspect Oriented Programming (“AOP”) capabilities that are built into the language (recall my colleague Brett Lammers' prior post on AOP). Consider the following code, which appends an extra condition onto the coverage item "size" that checks to ensure that the size is legal. Note that the previous ranges option is still in place. .

     <’
    extend packet_s {
       cover cover_me is also {
          item size using also illegal = (size > 1000); // will fire an error if size is ever greater than 1000 bytes
       };
    };
    ‘>

How would this be done in SystemVerilog?  It’s a trick question: there is no exact equivalent in SystemVerilog to perform the functionality of the above 7 lines of code.  Instead, the user would have to perform all the steps in the previous example over again, introducing another 25 lines of code.


So what’s the bottom-line?  The grand total of e vs. SystemVerilog line count shown so far in this series is:

    e: 12+13+7 = 31

    SystemVerilog: 37+25+25 = 87 lines

For a ratio of 2.8 more lines of SystemVerilog vs. the e version.

In the next post I’ll elaborate more on how e's AOP capability itself can enable you to write substantially more compact, flexible code than with any other IEEE language. able you to write substantially more compact, flexibly code than with any other IEEE language.  In the mean time, I invite you to challenge your OVM SystemVerilog friends to see if they can write more compact SystemVerilog examples than the ones I show above.
 
Happy coding!

Corey Goss
Staff Solutions Engineer
Team Specman

 

Comments(1)

By Paul on April 7, 2010
One usually does not put coverage objects in transactions. It's better to put the coverage in the transactors. Fortunately OVM with its analysis ports allows coverage to be added easily.
I do agree, though, that covergroups in SystemVerilog are next to useless in a language which supports OOP as they are not extensible nor inheritable. I believe this missing feature was one of the top enhancements suggested at the recent SystemVerilog working group meeting help just after DVCon.
Paul.

Leave a Comment


Name
E-mail (will not be published)
Comment
 I have read and agree to the Terms of use and Community Guidelines.
Community Guidelines
The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.