mea1201 Posted September 9, 2011 Report Share Posted September 9, 2011 I have a transaction class family where the most super class of that hierarchy is essentially an abstract class; all other transaction types are concrete classes derived from this. I have a monitor with an analysis port declared for this abstract base class, and I'm relying on polymorphism to broadcast different transaction types as they are collected to the analysis domain. The question I have is what is the best way to handle this situation? I won't know what transaction type I have until I sample data a couple of clocks in from the start of the transaction. Then, I would like to cast the transaction from the abstract to a specific concrete class based on the type detected. The only solution I can think of is to pre-declare several transactions in the monitor, one for each concrete class plus one declared with the abstract type to hold the start of the transaction until the type can be determined. Quote Link to comment Share on other sites More sharing options...
jeff.schroeder Posted September 9, 2011 Report Share Posted September 9, 2011 I did pretty much what you did. Essentially, you need a factory that creates a specific subtype based on the data that you collect. The way I did it, the base class is the factory: As you unpack into it, it creates the subtype when it has enough information to determine the type. (I build the decoding into the transaction class, so the monitor just puts raw data into the transaction object, and the transaction populates itself from the data.) Quote Link to comment Share on other sites More sharing options...
mea1201 Posted September 9, 2011 Author Report Share Posted September 9, 2011 I did pretty much what you did. Essentially, you need a factory that creates a specific subtype based on the data that you collect. The way I did it, the base class is the factory: As you unpack into it, it creates the subtype when it has enough information to determine the type. (I build the decoding into the transaction class, so the monitor just puts raw data into the transaction object, and the transaction populates itself from the data.) Thanks for the idea, Jeff! That led me to look into the factory method pattern to implement this. So, a contrived and concise example might look something like: // -- Transaction family, or products in the factory method pattern (factory method defined in the abstract base class. typedef class a_trans; typedef class b_trans; virtual class base_trans extends uvm_sequence_item; // -- Usual stuff. static function base_trans make(int kind); case(kind) // Decode transaction type data to determine subclass to create. 0: return a_trans::type_id::create("a_trans"); 1: return b_trans::type_id::create("b_trans"); endcase endfunction : make pure virtual function void show_trans(); endclass : base_trans class a_trans extends base_trans; // -- Usual stuff. int id_number; function void show_trans(); `uvm_info("a_trans", $psprintf("I am transaction number %0d.", id_number), UVM_LOW) endfunction : show_trans endclass : a_trans class b_trans extends base_trans; // -- Usual stuff. string id_name; function void show_trans(); `uvm_info("b_trans", $psprintf("I am a transaction called %0s.", id_name), UVM_LOW) endfunction : show_trans endclass : b_trans // -- Sample usage within a monitor, or the client in the factory method pattern. class my_mon extends uvm_monitor; // -- Usual stuff. virtual interface my_if vif; uvm_analysis_port #(base_trans) ap; task run_phase(uvm_phase phase); base_trans my_trans; forever begin // -- Assume first data determines transaction type for simplicity of example. my_trans = base_trans::make(vif.data); // -- Collect remaining data into my_trans. Call an update method if data is collected raw, to populate other attributes in transaction. ap.write(my_trans); end endtask : run_phase endclass : my_mon 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.