| Login | | Don't have an account yet? You can create one. As a registered user you have some advantages like theme manager, comments configuration and post comments with your name. | |
| Who's Online | There are currently, 47 guest(s) and 0 member(s) that are online.
You are Anonymous user. You can register for free by clicking here | |
 | |
|
Verification Guild: Forums |
|
| View previous topic :: View next topic |
| Author |
Message |
Jignesh Senior


Joined: Jan 08, 2008 Posts: 83 Location: Hyderabad - INDIA
|
Posted: Wed Mar 12, 2008 10:04 am Post subject: Factory pattern - One of the OOPs funda |
|
|
Hi Friends,
When we are implementing TB using VMM we are using factory pattern in our TB.
1 : In my Testbench generator is randomizing the packet_obj ( object of class which contraints all the packet fileds like length, address, size etc.. )
2 : then we are creating copy of this randomized_obj .. by calling copy method of packet_obj class.
3 : Then we are pushing the object , which is retrun by copy method and received by generater in mail box.
So my question is why we are using this factory pattern in the methodolgy .. what is the advatage of this way of generating data(Randomizing data) then creating its copy and then pushing it in mail box??
So what is the advantage(or Application) of using factory pattern fundamental in VMM methodology??
Thanks
---------
Jignesh |
|
| Back to top |
|
 |
Logger Senior


Joined: Jun 15, 2004 Posts: 340 Location: MN
|
Posted: Wed Mar 12, 2008 10:11 am Post subject: |
|
|
You can extend packet_obj, put an object of this extended class into gen.randomized_obj, and now the generator will create objects of the extended type rather than the original. It allows you to change the blueprint used to build the objects.
Thus you don't need to create a new generator for every extension of packet_obj. You should follow this pattern for your own transactors that create objects from objects, so you don't have to create new versions of those transactors when you want them to create a slightly different type of object.
Ryan |
|
| Back to top |
|
 |
vhdlcohen Industry Expert


Joined: Jan 05, 2004 Posts: 1237 Location: Los Angeles, CA
|
Posted: Wed Mar 12, 2008 12:41 pm Post subject: Re: Factory pattern - One of the OOPs funda |
|
|
| Jignesh wrote: | ...So my question is why we are using this factory pattern in the methodolgy .. what is the advatage of this way of generating data(Randomizing data) then creating its copy and then pushing it in mail box??
So what is the advantage(or Application) of using factory pattern fundamental in VMM methodology?? | From our book A Pragmatic Approach to VMM Adoption "VMM flow control and the factory pattern used by the atomic generator are designed such that it allows you to make the testcase redefinition in the program block without modifying the environment." Code application example from our book: | Code: | class Fifo_xactn_no_pop extends Fifo_xactn;
constraint cst_xact_kind {
kind dist {
PUSH := 25,
POP := 0,
PUSH_POP :=0,
IDLE := 3,
RESET := 1
};
} // cst_xact_kind
extern virtual function vmm_data copy(vmm_data to=null);
endclass : Fifo_xactn_no_pop
class Fifo_env extends vmm_env;
Fifo_xactn_atomic_gen fifo_xactn_gen_0; // atomic generator declaration
..
function void Fifo_env::build();
..
// Instantiation of transaction generator
this.fifo_xactn_gen_0 = new ("fifo_gen", 0, fifo_channel_0);
…
endfunction : build
... endclass : Fifo_env
// The Environment Remains Unchanged Redefinition Performed
// at program Level
program automatic fifo_test_pgm ();
//include files + log + fifo_env_0 instantiation
`include "test.svh"
initial :test
begin
// Build all components of an environment - testbench
// Do the build first
fifo_env_0.build();
// modify the default environment for the fifo_env_0.randomized_obj
begin : setting_up_the_factory_for_the_generator
// Declare an instance and instantiate desired transaction with constraints
Fifo_xactn_no_pop fifo_xactn; // No pop constraint
fifo_xactn=new();
`vmm_trace(log,
"Modifying reference of randomized_obj to NO POP");
fifo_env_0.fifo_xactn_gen_0.randomized_obj= fifo_xactn;
end : setting_up_the_factory_for_the_generator
// now run the environment.
// Since the build was exercised already, it will not be repeated in the run
fifo_env_0.run();
`vmm_note(log, "End of Test");
end :test
endprogram : fifo_test_pgm
|
_________________ Ben Cohen http://www.systemverilog.us/
* SystemVerilog Assertions Handbook, 3rd Edition, 2013
* A Pragmatic Approach to VMM Adoption
* Using PSL/SUGAR ... 2nd Edition
* Real Chip Design and Verification
* Cmpt Design by Example
* VHDL books |
|
| Back to top |
|
 |
Jignesh Senior


Joined: Jan 08, 2008 Posts: 83 Location: Hyderabad - INDIA
|
Posted: Thu Mar 13, 2008 3:44 am Post subject: |
|
|
I understand your all comments ..
But I have one another doubt..
Please reveiw the generator code shown below.
Two methods are written below , in both the methods we are creating copy of randomized_obj and then we are pusing copied object in mail box.
I have heard that method 2 is better. Can you tell me why method 2 is better??
And what is the advantage of method 2..
Code :
Method 1:
--------
packet packet_obj = new() ;
randomized_obj.randomize() ;
packet_obj = randomized_obj ; // Creating copy of randomized object
mailbox.put(packet_opj) ;
// Pushing the copied object in mail box instead of randomized_obj
-------------------------
Method 2 :
-------------
packet packet_obj = new();
randomized_obj.randomize() ;
//Copy is method of packet class which retruns the object of packet class itself
$cast(packet_obj,randomized_obj.copy()) ;
// Creating copy of randomized object via copy method of packet class
mailbox.put(packet_opj) ;
--------------------------------
Thanks
Jignesh Thakkar |
|
| Back to top |
|
 |
Dhaval Senior


Joined: Feb 16, 2006 Posts: 94
|
Posted: Thu Mar 13, 2008 6:00 am Post subject: |
|
|
| Code: | | packet_obj = randomized_obj ; // Creating copy of randomized object |
Its called shallow copy, if above instance has another instance inside then both packet_obj and randomized_obj points to the same location where as in second method such is not the case. If you implement copy method in your transaction then you would know it more profoundly. |
|
| Back to top |
|
 |
Janick Site Admin


Joined: Nov 29, 2003 Posts: 1382 Location: Ottawa, ON Canada
|
Posted: Thu Mar 13, 2008 9:21 am Post subject: |
|
|
Example #1 is not even creating a copy! It is creating another reference to the randomized object. You'll end up with N references to the same object, all having the same value. It is a common mistake.
A shallow copy would be:
| Code: | | packet_obj = new randomized_obj; |
but that is risky as explained above. |
|
| Back to top |
|
 |
Jignesh Senior


Joined: Jan 08, 2008 Posts: 83 Location: Hyderabad - INDIA
|
Posted: Thu Mar 13, 2008 10:27 am Post subject: |
|
|
Thanks
Dhaval & Janick |
|
| Back to top |
|
 |
heritageorchard Senior


Joined: Feb 22, 2005 Posts: 123 Location: Boston, Ma
|
Posted: Thu Mar 13, 2008 2:34 pm Post subject: |
|
|
Hi Jignesh,
I agree with your comments and concerns. The factory method is just an overly complicated way to define a standard generator pattern. Complex generators are, well, more complex than just a blueprint. Simple generators are, well simple and we do not need standard code for that. Remember that in the patterns book, they state clearly that patterns are a meta level idea, not actual code.
Method #2 is not better. Method #1 that is a perfectly fine way of putting something in to a queue. As long as you know it's a pointer, you are fine. I find it very hard to believe the argument that verification people get confused. Even if you accept that we get confused, it's a simple junior mistake and made only once. We have complex chips to verify; repeatedly making this simple mistake speaks badly for one's career in verification. Also, adding a copy based, common base class methodology does not make the problem any simpler and in my belief, creates more complex problems than a basic understanding of pointers.
What I tend to do is separate the concerns of generation (i.e. the constraints or knobs) from the sending the generated "transaction" to a driver/checker, etc. So my generators have knobs/parameters that may or may not be controlled by constraints, followed by a pure virtual function generate_done_(). This method is implemented in a base class and often is nothing more than a two line create a structure and put it into a channel. That way my generator can be used in different projects, usually each with their favorite methodologies.
So, a blueprint is an acceptable pattern (idea not code), but the assumptions of copying, common base class, and even the channel confuse and complicate the idea of simple generation. I would consider each assumption individually and come up with a solution that fits your team/company. _________________ Mike Mintz
www.trusster.com
"Teal and Truss" A multi-vendor, multi-language, open source verification framework
co-author "Hardware Verification with C++", and "Hardware Verification with SystemVerilog" |
|
| Back to top |
|
 |
Dhaval Senior


Joined: Feb 16, 2006 Posts: 94
|
Posted: Thu Mar 13, 2008 10:55 pm Post subject: |
|
|
| To understand ur concers more deeply I would suggest a book "SystemVerilog for verification" by Chris Spear. |
|
| Back to top |
|
 |
heritageorchard Senior


Joined: Feb 22, 2005 Posts: 123 Location: Boston, Ma
|
Posted: Fri Mar 14, 2008 8:59 am Post subject: |
|
|
Dhaval,
I disagree. I really like Chris' book (and was a reviewer), yet it doesn't delve into the choices needed to be made when creating a reasonable verification environment.
To understand architecture trade-offs, it's a good idea to study the "lessons learned" from the software industry. Consider "Software Engineering: A Practitioner's Approach", by Roger S. Pressman for a good overview. Also consider "The C++ Programming Language, section 24.3.1: What do classes represent?” by Bjarne Stroustrup.
Finally, to help you think about how to construct a system with abstraction levels that are logically consistent, a great book is “The Design of Everyday Things”, by Donald A. Norman. Though it does not deal with code or high-tech, it is great for thinking about how someone else might develop a mental model of using your code. _________________ Mike Mintz
www.trusster.com
"Teal and Truss" A multi-vendor, multi-language, open source verification framework
co-author "Hardware Verification with C++", and "Hardware Verification with SystemVerilog" |
|
| Back to top |
|
 |
Jignesh Senior


Joined: Jan 08, 2008 Posts: 83 Location: Hyderabad - INDIA
|
Posted: Fri Mar 14, 2008 10:20 am Post subject: |
|
|
Hi Heritageorchard,
| Quote: | | Method #2 is not better. Method #1 that is a perfectly fine way of putting something in to a queue. |
As you said Method 2 is not better but to create the copy of randomization class we have to use method 2 only because througth method 1 we are creating shadow copy ..
And so we will have a two handle of same object, which is of no meaning..
So if we want to create local copy of randomization_obj then we must have to use method 2 only..
Can you please expaling me that with out method 2 how can we create local copy..
Thanks
Jignesh Thakkar |
|
| Back to top |
|
 |
Logger Senior


Joined: Jun 15, 2004 Posts: 340 Location: MN
|
Posted: Fri Mar 14, 2008 11:31 am Post subject: |
|
|
| Jignesh wrote: | | Can you please expaling me that with out method 2 how can we create local copy.. |
You would need to not use the factory pattern.
| Code: | Packet packet_obj;
while(1) begin
packet_obj = new();
packet_obj.randomize();
mailbox.put(packet_obj);
end |
You would then of course lose the flexibility that the factory pattern provides. Which means you would need to replace this code anytime you wanted this loop to create an object of a type other than Packet.
Once you learn it, the factory pattern only adds a minute amount of complexity. And although you may not forsee the need to generate anything other than Packet objects when you write the code. It is a minimal effort, which future proofs your code, so you don't have to change it to generate ConstrainedPacket type objects in the future. I think this is more important for randomized objects (as shown in this example), because it is highly likely you will want to alter the constraints.
Ryan |
|
| Back to top |
|
 |
heritageorchard Senior


Joined: Feb 22, 2005 Posts: 123 Location: Boston, Ma
|
Posted: Fri Mar 14, 2008 11:35 am Post subject: Method #2 |
|
|
Hi Jignesh,
As it stands, your implementation is fine, with the exception that the "packet_obj = randomized_obj " line is not making a copy of the object.
| Quote: | packet packet_obj = new() ;
randomized_obj.randomize() ;
packet_obj = randomized_obj ; // Creating copy of randomized object
mailbox.put(packet_opj) ;
// Pushing the copied object in mail box instead of randomized_obj
|
So the code is effectively:
| Quote: | packet packet_obj = new() ;
randomized_obj.randomize() ;
mailbox.put(randomized_obj) ;
|
Why do you need a copy to be put in the channel? Assuming you pack this code into a method, perhaps called send_one(), you are all set. _________________ Mike Mintz
www.trusster.com
"Teal and Truss" A multi-vendor, multi-language, open source verification framework
co-author "Hardware Verification with C++", and "Hardware Verification with SystemVerilog" |
|
| Back to top |
|
 |
vhdlcohen Industry Expert


Joined: Jan 05, 2004 Posts: 1237 Location: Los Angeles, CA
|
Posted: Fri Mar 14, 2008 11:57 am Post subject: Re: Method #2 |
|
|
| heritageorchard wrote: | As it stands, your implementation is fine, with the exception that the "packet_obj = randomized_obj " line is not making a copy of the object. | Quote: | packet packet_obj = new() ;
randomized_obj.randomize() ;
packet_obj = randomized_obj ; // Creating copy of randomized object
mailbox.put(packet_opj) ;
// Pushing the copied object in mail box instead of randomized_obj
| So the code is effectively:
| Quote: | packet packet_obj = new() ;
randomized_obj.randomize() ;
mailbox.put(randomized_obj) ;
| Why do you need a copy to be put in the channel? Assuming you pack this code into a method, perhaps called send_one(), you are all set. |
By creating a complete copy, you maintain a pristine original of the transaction, thus isolating the producer of the randomized packets (i.e., the generator) from the consumer of the transaction (i.e., the consumer transactor). This insures that the generated transaction sequences is in accordance to the original intent, rather than one that is modified in an uncontrolled manner. This is important when the next generated transaction is a function of the current transaction. The consumer transactor may modify that copy (e.g., add results from DUT), as it may use that modified copy to pass it onto another channel or thru a notification to pass results to a monitor or some other transactor. Another consideration is that the copy may have a life of its own, freed from the original that may be consumed (i.e., link is nulled). This is what we show in our VMM Adoption book in the chapter of custom generator | Code: | task Fifo_custom_gen::gen();
...repeat(100) begin : for_random_tests
randomized_obj.randomize();
this.put_in_channel(randomized_obj);
end : for_random_tests
...endtask : gen
...
task Fifo_custom_gen::put_in_channel(Fifo_xactn obj);
Fifo_xactn fifo_inst;
obj.data_id++; // ID maintenance is custom
$cast(fifo_inst, obj.copy(obj));
this.out_chan.put(fifo_inst);
endtask : put_in_channel
|
_________________ Ben Cohen http://www.systemverilog.us/
* SystemVerilog Assertions Handbook, 3rd Edition, 2013
* A Pragmatic Approach to VMM Adoption
* Using PSL/SUGAR ... 2nd Edition
* Real Chip Design and Verification
* Cmpt Design by Example
* VHDL books |
|
| Back to top |
|
 |
Logger Senior


Joined: Jun 15, 2004 Posts: 340 Location: MN
|
Posted: Fri Mar 14, 2008 1:10 pm Post subject: Re: Method #2 |
|
|
| heritageorchard wrote: | | Why do you need a copy to be put in the channel? Assuming you pack this code into a method, perhaps called send_one(), you are all set. |
As oppose to the copy used to implement the factory pattern:
| Code: | // In new()
Packet packet_obj = new;
// in main()
while(1) begin
packet_obj.randomize();
mailbox.put(packet_obj.copy());
end |
Maybe the $cast in Jignesh's original code was confusing the conversation? In VMM, copy() returns vmm_data type object, so the cast is needed to get it back to Packet type. But in non-VMM environments your copy() might return Packet type objects, or your channel might accept the base class object. In which case the cast is not necessary.
Ryan |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
| |
|
|