Wednesday, November 07, 2012

Developing OVM based testbench environment: Lessons learnt

On experience front, I only started about couple months back and I'm sure there is lots more for me to learn further. Why I wanted to write this blog is that about 4 years ago I had done specman e, though for a very short period, I was quite thorough with all the basics, later moved on to work on System Verilog (SV) and ever since its all about only SV at work. Worst thing was that I had completely forgotten whats and hows of 'e' and this time don't want that to happen!
Read through a lot of blogs, websites like testbench.in, verification academy, some eetimes posts etc (all of those sites that come up as the first few google results for methodology search). After some enough learning of basics, started creating a fresh TB env and following are some of the important observations that I thought:

1. Going by the traditional Layered architecture method, I had pulled up an analysis port from driver, just after calling get_next_item, that which my scoreboard will refer and does the comparison against the analysis port from the output monitor. 
  - What I should have actually done is to use an input monitor and the analysis port declaration in here for the scoreboard to pick the input packet. On a large scale, this layer is critical given that all we are targeting via any methodology is reusability. And by not doing this, I limit my scoreboard to be used just as a plug and play item at SoC level (say what I developed is at sub-system level) and now when I try to get this scoreboard to SoC level, it might need multiple modifications to suit the SoC level drivers and I'm only complicating the env instead of easing it.

2. $cast: I was, not a lil, but a lot confused and I'm not sure if I'm still all that clear with this. Firstly, when do I use this: for ex in my env, I use get_next_item and get the first sequence item. I $cast it to the configuration packet object and drive this one on the input interface to the DUT. 
For a long time, I was thinking, $cast is about the simple System Verilog dynamic casting where we try to cast an item of one datatype onto the one of different datatype. And in my env, because I always $cast a sequence item which is the only OVM object on to the configuration packet which is a OVM component, I was convinced probably casting an object to a component needs something more than just what a copy system call can do. 
Now in a discussion, some senior tells me it is not just that (read not that) and there is something more. It acts more like a deep copy. And the concept of relating SV dynamic casting to casting an ovm object onto a component sounds kinda stupid! 
That said, the question next is whats the difference between a deep copy and $cast. I brainstorm and find out, in OVM it's about copying a parent object to child object or copying a derived object onto another inherited object that share the same parent (meaning - 1. it's always from parent to child 2. of which the object that gets copied can have (generally has) more properties/methods defined). I'm only sticking on to this explanation now.

3. set_config_object and assign_vi
 These two constructs were great to know concept wise and there were no confusions until I got here: http://www.eetindia.co.in/STATIC/PDF/201004/EEIOL_2010APR28_EDA_TA_01.pdf?SOURCES=DOWNLOAD.
This document in specific compared assign_vi and set_config_object.
Basically, both these constructs have something to do with interfaces. But going through this article kinda added to confusions and I probably went around doing a research for almost about a day but I'm not convinced yet. Anyway, the simplest understanding is that set_config_object is complete only with a get_config_object and it is a one time declaration. while assign_vi is actually a task and whenever you want to call it, the task definition in that particular class adds additional code. 

4. ovm_report_object
 This is an interesting find for me. And only when I went about coding on my own, I hit this compile time error - Going back to the beginner level of verilog, every interview you give, you have this question the difference between task and function. So you can call ovm_report_object only from a function. That leaves you with this construct not being called from run task and okay with the other phases.

 5. There were couple of other scenarios that we were brainstorming about, may be trying to think out of the box ;) so 1. what happens if we have an empty ovm component defined in the environment - I think it would probably just throw a warning and would occupy some memory in the factory list of components. But the real time output - need to try out yet.  2. the incremental compilation stuff using factory. I kinda remember this existed in System verilog I mean the incremental compilation, not factory, but not sure though. Specman had this aeons ago needless to say. Also that, we have the verdi doing incremental compilation of the design to load the trace and waveforms after there are changes made to TB - got lots to explore huh!
 

0 comments: