kaushalmodi Posted October 1, 2016 Report Share Posted October 1, 2016 Hello, We have a test bench environment where we have 2 objects of the same SPI env class. The SPI env sets the sequencer for the RAL model as follows: reg_model.default_map.set_sequencer(spi_master_agt.mem_sqr, reg2spi_adapter); The transaction type handled by the spi_master_agt.mem_sqr is spi_mem_tr. Now I need to extend the spi_mem_tr to spi_mem_tr_1 and spi_mem_tr_2, and then override spi_mem_tr with those separately for the 2 objects of the SPI env class. // Below does not work set_inst_override_by_type ( .relative_inst_path("env.spi_m[0].*"), // Here spi_m[0] is the first instance of the SPI env .original_type(spi_mem_tr::get_type()), .override_type(spi_mem_tr_1::get_type())); set_inst_override_by_type ( .relative_inst_path("env.spi_m[1].*"), // Here spi_m[1] is the second instance of the SPI env .original_type(spi_mem_tr::get_type()), .override_type(spi_mem_tr_2::get_type())); // This does not work too! set_inst_override_by_type ( .relative_inst_path("env.*"), .original_type(spi_mem_tr::get_type()), .override_type(spi_mem_tr_1::get_type())); // Even this does not work! // So looks like "inst" override by type does not work for tr objects in RAL // connecting agents? set_inst_override_by_type ( .relative_inst_path("*"), .original_type(spi_mem_tr::get_type()), .override_type(spi_mem_tr_1::get_type())); // Other the other hand, below works, BUT that overrides the tr in both SPI env objects // That is not what I want; I need to override using different types for the // two SPI env objects spi_mem_tr::type_id::set_type_override(spi_mem_tr_1::get_type()); Questions: Is it possible to do instance specific overrides over transaction class inside the SPI agent connecting to my RAL model? If so, what is the correct way to set the relative_inst_path? If not, are there any hacks to achieve the same? The fact that the global type override does work gives me some hope. Quote Link to comment Share on other sites More sharing options...
tudor.timi Posted October 1, 2016 Report Share Posted October 1, 2016 When using RAL like this, items aren't created by your agents, but by the adapters interfacing with those agents. If you set up the contexts properly when creating items inside your adapters, it's going to be possible to do instance-based overrides: class spi_adapter extends uvm_reg_adapter; function uvm_sequence_item reg2bus(...); // notice the 'get_full_name()' here spi_item bus_item = spi_item::type_id::create("bus_item", null, get_full_name()); // ... endfunction endclass The extra argument to create(...) sets the context for items create under the adapter as being "<adapter_name>.*". In your environment code, you can set instance overrides like this: class some_tb_env; spi_adapter adapter0; spi_adapter adapter1; function void end_of_elaboration_phase(...); spi_mem_tr::type_id::set_inst_override(spi_mem_tr_0::get_type(), null, "adapter0.*"); spi_mem_tr::type_id::set_inst_override(spi_mem_tr_1::get_type(), null, "adapter1.*"); endfunction endclass Your adapters need to have different names otherwise you won't be able to differentiate between items create by one and ones created by the other. Note: Don't confuse the context passed into create(...) with instance paths of uvm_components. The two are closely related, but aren't the same thing. Quote Link to comment Share on other sites More sharing options...
kaushalmodi Posted October 3, 2016 Author Report Share Posted October 3, 2016 Hi Tudor, Thanks for the reply. I have tried something similar. But that doesn't work. Here's is some code to show what I tried. In the adapter class where I create the transaction objects: mem_tr = spi_mem_tr::type_id::create(.name("mem_tr"), .contxt(get_full_name())); In the base test where I do the overrides: spi_mem_tr::type_id::set_inst_override(.override_type(spi_mem_ext_tr::get_type()) , .inst_path("env.spi_m[0].reg2spi_adapter.*") , .parent(null)); spi_mem_tr::type_id::set_inst_override(.override_type(spi2_mem_ext_tr::get_type()) , .inst_path("env.spi_m[1].reg2spi_adapter.*") , .parent(null)); Note that I have fixed the order of the arguments to set_inst_override; the parent argument is the last argument. To avoid confusion, I am using named argument association. The difference here is that we have a VIP that wraps the SPI adapter, and I have 2 instances spi_m[0] and spi_m[1] of the same VIP class. the mem_tr objects are created inside the reg2spi_adapter. Even then, the overrides do not work at all. Quote Link to comment Share on other sites More sharing options...
tudor.timi Posted October 4, 2016 Report Share Posted October 4, 2016 The "env.spi_m[0].reg2spi_adapter.*" won't work in there, because the adapter doesn't know under which env it was instantiated. You can check this by calling get_full_name() from the adapter. That's what you need to pass as a context. Quote Link to comment Share on other sites More sharing options...
kaushalmodi Posted October 5, 2016 Author Report Share Posted October 5, 2016 Thank you. It now makes sense why that full path of "env..." did not work. So I thought that the below would fix that. But it is not.. Below code is in the "SPI env" component whose objects are "spi_m[0]" and "spi_m[1]". reg2spi_adapter = spi_master_reg_adapter::type_id::create(.name("reg2spi_adapter"), .contxt(get_full_name())); `uvm_info("DEBUG_FULL_NAME", $sformatf("Full name of this spi_env obj is %s", this.get_full_name()), UVM_MEDIUM) `uvm_info("DEBUG_FULL_NAME", $sformatf("Full name of the new reg2spi_adapter obj is %s", reg2spi_adapter.get_full_name()), UVM_MEDIUM) Inside the "new" function of the "spi_master_reg_adapter" class, I have: `uvm_info("DEBUG_FULL_NAME", $sformatf("Full name of this adapter obj is %s", this.get_full_name()), UVM_MEDIUM) But still, this is what gets printed (formatting changed from default using a custom report server): UVM_INFO @ 0ns Full name of this adapter obj is reg2spi_adapter :DEBUG_FULL_NAME UVM_INFO @ 0ns Full name of this spi_env obj is uvm_test_top.env.spi_m[0] :DEBUG_FULL_NAME UVM_INFO @ 0ns Full name of the new reg2spi_adapter obj is reg2spi_adapter :DEBUG_FULL_NAME UVM_INFO @ 0ns Full name of this adapter obj is reg2spi_adapter :DEBUG_FULL_NAME UVM_INFO @ 0ns Full name of this spi_env obj is uvm_test_top.env.spi_m[1] :DEBUG_FULL_NAME UVM_INFO @ 0ns Full name of the new reg2spi_adapter obj is reg2spi_adapter :DEBUG_FULL_NAME I am curious why the below does not work; I am specifying the env's "get_full_name()" as the context: reg2spi_adapter = spi_master_reg_adapter::type_id::create(.name("reg2spi_adapter"), .contxt(get_full_name())); Quote Link to comment Share on other sites More sharing options...
kaushalmodi Posted October 5, 2016 Author Report Share Posted October 5, 2016 Hi Tudor, Thanks for your immense help. I was finally able to get the overrides work with these changes: (1) Append the full name to the transaction objects generated in the adapter: mem_tr = spi_mem_tr::type_id::create({get_full_name(), ".mem_tr"}); (2) Append the full name even to the adapter object generated in the SPI env: reg2spi_adapter = spi_master_reg_adapter::type_id::create({get_full_name(), ".reg2spi_adapter"}); (3) Finally set the instance overrides as usual in the base test: set_inst_override_by_type ( .relative_inst_path("env.spi_m[0].*"), .original_type(spi_mem_tr::get_type()), .override_type(spi_mem_ext_tr::get_type())); set_inst_override_by_type ( .relative_inst_path("env.spi_m[1].*"), .original_type(spi_mem_tr::get_type()), .override_type(spi2_mem_ext_tr::get_type())); Once again, I really appreciate the help you provided. Thanks! Quote Link to comment Share on other sites More sharing options...
kaushalmodi Posted October 5, 2016 Author Report Share Posted October 5, 2016 Here's a minor update with respect to point (1) in my above summary. I had to do: mem_tr = spi_mem_tr::type_id::create(.name("mem_tr"), .contxt(get_full_name())); instead of mem_tr = spi_mem_tr::type_id::create({get_full_name(), ".mem_tr"}); With the latter, I get an SDI/Verilog warning saying: Message! [SDI/Verilog] In sdiT::transactionTypeT ctor, the transaction name had illegal characters. Those characters have been replaced. Here's the new name: 'uvm_test_top_env_spi_m[0]_reg2spi_adapter_mem_tr' ... Message! [SDI/Verilog] In sdiT::transactionTypeT ctor, the transaction name had illegal characters. Those characters have been replaced. Here's the new name: 'uvm_test_top_env_spi_m[1]_reg2spi_adapter_mem_tr' But the overrides still worked. Now with that fixed (by not using get_full_name() or "." in the "name" argument, mem_tr.get_full_name() now prints just "mem_tr". But the overrides still work!! This is very confusing. Quote Link to comment Share on other sites More sharing options...
uwes Posted January 4, 2017 Report Share Posted January 4, 2017 hi the difference is that with version one you create an object named "mem_tr" in the context of get_full_name() while with the second one you create an object named (long name with alot of dots) {get_full_name(), ".mem_tr"} in the uvm_root: context. Here it depends for which instances you set the factory override. for various reasons it is not a good habit to have object names involving dots or other non a-Z0-9_ characters. just think of print out of a.b.c.e.f and you allow "." in names then it could be "a" . "a.c.d.e.f" or "a.b" . "c.e.f" or any weird combination. with that you should avoid any get_full_name() in the name argument of the ctor. for the particular SDI warning the name should have no "." since this is considered a hierarchical delimiter (which for you isnt true). 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.