Erling Posted June 29, 2010 Report Share Posted June 29, 2010 I would like to have a component receive different transactions, but that would require the component to overload member functions, for example: function void write(Trans1 t); function void write(Trans2 t); This does not work, though, because the compiler rejects the overload. A single write function taking a superclass of Trans1 and Trans2 does work, but the result is ugly and not OOP like with casting to reveal the type info lost in the call. Another solution is to split the component in two, but it may be valid reasons to receive different transactions in the same context. Is there a better way to deal with this situation? Erling Quote Link to comment Share on other sites More sharing options...
uwes Posted June 30, 2010 Report Share Posted June 30, 2010 hi, you do have 4 options (maybe more). i usually prefer #3: 1. use the *_decl macros //| `uvm_put_imp_decl(_1) //| `uvm_put_imp_decl(_2) //| //| class my_put_imp#(type T=int) extends uvm_component; //| uvm_put_imp_1#(T) put_imp1; //| uvm_put_imp_2#(T) put_imp2; //| ... //| function void put_1 (input T t); //| //puts comming into put_imp1 //| ... //| endfunction //| function void put_2(input T t); //| //puts comming into put_imp2 //| ... //| endfunction //| endclass 2. use inheritance (the way you suggested). but this requires both elements derive at least from ovm_object. 3. use uvm_subscriber to create a container around the port type you want 4. use a base transaction as element. inherit from this base element a custom transaction where each derived type does have a custom member with your private type embedded. this works even when you object do not derive from ovm_object. ala class base_trans extends uvm_object; endclass class my_type1 extends base_trans; my_object t1; endclass class my_type2 extends base_trans; my_object t2; endclass regards /uwe Quote Link to comment Share on other sites More sharing options...
desperado Posted June 30, 2010 Report Share Posted June 30, 2010 Hi Erling, Yes your are right, basically inside an uvm component you can use only one write function. But if you try to use more than one it might mess up. You can have a look at this link given below, basically this show some of the usage to overcome this problem. This basically was used in OVM, so does can be used for UVM as well. http://ovmworld.org/forums/showthread.php?877-Connecting-OVM-Monitor-with-OVM-Scoreboard!!-Wish-would-be-helpfull-for-people-!!&highlight=write+function+inside+scoreboard Kindly let know if you face any issue regarding the same. Thanks, Desperado --> A New Fresh Breath of "UVM" - Nice to feel this united "Air" Quote Link to comment Share on other sites More sharing options...
Erling Posted July 2, 2010 Author Report Share Posted July 2, 2010 hi, you do have 4 options (maybe more). i usually prefer #3: 3. use uvm_subscriber to create a container around the port type you want regards /uwe Thanks to those who replied. About your preferred option #3: I 'm not sure I understand what you mean creating a container around the port. I could add two subscribers each parameterized with different transaction types, but the transactions will then be written to the subscribers and not to the common parent (without further trickery) and this seems to defeat the purpose. I did try option #1 (i.e using the uvm_analysis_imp_decl macro). This works. It is a poorman solution, though, direct language support would have been more elegant, understandable, and maintainable. Oh well. Erling Quote Link to comment Share on other sites More sharing options...
uwes Posted July 5, 2010 Report Share Posted July 5, 2010 hi, using a subscriber or not depends on the situation (and potentially preference). i usually inject more functionality into it (its not just a redeclared port ending in a different function). attached is some (incomplete) code fragment. btw: the native language solution... with an option to overload functions one could obviously solve the "ports of different types" issue. however this does not address the "multiple ports of the same type" issue. to simplify both issues other languages allow anonymous types and/or closures. the subscriber version is the long,long, fully expanded version of that. // @test: // uwes@cadence.com module test7; import uvm_pkg::*; class t71 extends uvm_object; `uvm_object_new_func endclass class t72 extends uvm_object; `uvm_object_new_func endclass class container #(type TRANS=int,TARGET=uvm_component) extends uvm_subscriber#(TRANS); local TARGET target; local int unsigned idx; function new (string name, uvm_component parent,TARGET target,int unsigned idx); super.new(name,parent); this.target=target; endfunction function void write(TRANS t); // FIXME call some function with custom args in target(dest) target.collector(t,idx); endfunction endclass class m7 extends uvm_component; `uvm_component_new_func container#(t71,m7) p0 = new("p0",this,this,0); container#(t72,m7) p1 = new("p0",this,this,1); function void collector(uvm_object o, int unsigned idx); uvm_report_info("TEST7",$psprintf("received %s from port %0d",o.sprint(),idx),UVM_NONE); endfunction endclass endmodule Quote Link to comment Share on other sites More sharing options...
Erling Posted July 6, 2010 Author Report Share Posted July 6, 2010 hi, using a subscriber or not depends on the situation (and potentially preference). i usually inject more functionality into it (its not just a redeclared port ending in a different function). attached is some (incomplete) code fragment. btw: the native language solution... with an option to overload functions one could obviously solve the "ports of different types" issue. however this does not address the "multiple ports of the same type" issue. to simplify both issues other languages allow anonymous types and/or closures. the subscriber version is the long,long, fully expanded version of that. The effect of this solution appears to be a "write" method with an additional parameter identifying the writer. Unless there is a need for more functionality in the closure, a less complicated variant of this pattern could be to embed the index in the transaction itself and have it go to write() directly (or perhaps use the set/get_initiator members of uvm_transaction). Regards, Erling Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.