Jump to content


  • Content count

  • Joined

  • Last visited

  • Days Won


karandeep963 last won the day on May 21 2016

karandeep963 had the most liked content!

About karandeep963

  • Rank
    Advanced Member

Profile Information

  • Gender
  • Location
    New Delhi

Recent Profile Visitors

550 profile views
  1. karandeep963


    Great many thanks Tudor , I overlooked it . Also can you please also provide your expertise feedback on : Question 2: when we execute `uvm_do_on(eseq_inst[va],...) , so it creates an object and registers with factory. Does for every iteration it registers with factory the same name eseq_inst[va] instead of value eseq_inst[0]/eseq_inst[1]/eseq_inst[3]. as per UVM library : `uvm_do_on_with implicity calls `uvm_create which further calls create_item() as : { \ uvm_object_wrapper w_; \ w_ = SEQ_OR_ITEM.get_type(); \ $cast(SEQ_OR_ITEM , create_item(w_, SEQR, #SEQ_OR_ITEM));\ } Definition at line 146 of file uvm_sequence_defines.svh. while create_item has been defined as: protected function uvm_sequence_item create_item( uvm_object_wrapper type_var, uvm_sequencer_base l_sequencer, string name )
  2. class my_virtual_sequence extends uvm_sequence; `uvm_sequence_utils(my_virtual sequence,my_v_sequencer) exec_sequence eseq_inst[100]; ... virtual task body(); for(int i = 0 ; i <100 ; i++)begin fork automatic int var = i; // this is not allowed , getting compilation error `uvm_do_on(eseq_inst[var], p_sequencer.master_sequencer[var]) join_none end ..... some other piece of code ..... endtask: body endclass: my_virtual_sequence Hi , As per the above code, I wanted to parallely fire 100 transactions on 100 different masters_sequncers. Question 1: But it is not allowing to declare automatic variable before fork. what is alternative to this ? Also Question 2: when we execute `uvm_do_on(eseq_inst[var],...) , so it creates an object and registers with factory. Does for every iteration it registers with factory the same name eseq_inst[var] instead of value eseq_inst[0]/eseq_inst[1]/eseq_inst[3]. Since I checked UVM library and found `uvm_do_on_with implicity calls `uvm_create which further calls create_item() as : { \ uvm_object_wrapper w_; \ w_ = SEQ_OR_ITEM.get_type(); \ $cast(SEQ_OR_ITEM , create_item(w_, SEQR, #SEQ_OR_ITEM));\ } Definition at line 146 of file uvm_sequence_defines.svh. while create_item has been defined as: protected function uvm_sequence_item create_item( uvm_object_wrapper type_var, uvm_sequencer_base l_sequencer, string name ) So what is the work around to this if one wants to execute it with `uvm_do_* . May be using seq.start(sequncer) can be solution , but wandering if I can do it `uvm_do. Thanks
  3. karandeep963

    UVM Override V/s Simulator Compile/Elab

    Yes it should work. It skipped from my mind. Thanks a lot :)
  4. Hi Folks, Interestingly today making some tweaks I faced a scenario with overrides. Suppose I add some variables in the extended class which are not present in the base class. Then I called the uvm_set_type_override from my top test. Interestingly I wanted to access those newly added variables in final_phase of some component , but during the simulator compile/elaboration phase it fails since the overrides are active during Simulation run-UVM_BUILD_PHASE. So my question is , if someone using some legacy code and wanted to update the stuff without re-writing again/or major changes , extended from base, then only overrides possible are those that will be active during simulation run , for an example , setting default sequence to driver with override. So there is no way we could leverage it. I am wandering , if TLM-GP extensions implementation may provide my some idea to do this. Any suggestions ??? If needed a code to see I saved the stuff http://www.edaplayground.com/x/2Ltr Line 156 is point of interest
  5. Hi , I have a case in which my DUT only toggles the valid bits of data output and doesn't change the rest of the bits. At the receiever side its state machine decides what all are the valid bits. DUT is purely based on couple of state machines. I have a C model for the same which does not have that state machines though it every time toggless all the data fields. For an example , lets say DUT transmits 0101 at N cycles and has to transmit only 0x04 at N+1th cycle so it again transmits 0101. since the LSB is not valid in this case. In case of model , it tries to follow the DUT and generated 0101 for Nth cycle and 0100 for N+1th cycles unlike DUT. There is SV-UVM scoreboard which compares both the transactions and creeps for this case. Now , I have few ideas in my mind. 1: I need to sit with designer and get to know the inside indepth working and re-write the stuff in scoreboard. 2: Other thing is I can do bitwise AND of DUT with MODEL output and compare with MODEL in scoreboard , but this will fail for the case in which DUT always respond with 0xFFFF. Any idea what can be the better approach in this case. Thanks, Karandeep
  6. One other way could be: Since binding of port can be possible with the components(which are supposed to be hierarchical members unlike sequence which associated during run-time). So you can create one port in your env and connect it to block_cfg_mngr import. Now in the sequence you might be already having the env pointer through config_db (if not set the port from env in the config_db) , get the pointer of env,port in your sequence and start accessing it. ///// Env Classs ///// class my_env extends uvm_env; uvm_tlm_b_initiator_socket #(uvm_tlm_gp) config_socket; function my_env::new(string name = "my_env", uvm_component parent = null); super.new(name, parent); // CONFIG config_socket = new ("config_socket",this); endfunction // build_phase: uvm_config_db #(uvm_tlm_b_initiator_socket)::set(this, "", "config", config_socket); //// Sequence Class /// class my_seq extends uvm_sequence(uvm_sequence_item) // CONFIG tlm block socket for configuration uvm_tlm_b_initiator_socket #(uvm_tlm_gp) bsocket; task body; // CONFIG GEtting Handle from env for config socket if(!uvm_config_db #(uvm_tlm_b_initiator_socket)::get(null,"uvm_test_top.m_env", "config", bsocket)) begin `uvm_error("CONFIG_DB_ERROR", "Could not find config") end // Use it the way you want bsocket.write(uvm_tlm_gp); endtask: body
  7. I think UNIQUE KEYWORD does well , I have used it with Synopsys VCS, a quick example ::-> http://www.edaplayground.com/x/6AHE Not sure about cadence incisive, sometime back raised CCR for enhancement for this feature , not sure whether it is available. But yes, this unique keyword does much beautification to my code.
  8. karandeep963

    RAL mapping reg_field to another reg_field

    It can be done in two ways: 1. Use reg callbacks pre_predict/post_predict to update the values. http://forums.accellera.org/topic/5107-uvm-register-implimentation-for-same-register-with-different-instances/ will be help you in a better way. Thanks to Tudor Timi for his kind help !! 2. The other way would be overload your predictor to do this stuff.
  9. As far as I understand Chip Select(CSbar) is active low in nature , so its the masters responsibility to control/enable/disable it while the slave has to respond to the command input. Slave must not drive CSbar. Slave must be active on CSbar low and process the input command and do the needful.
  10. karandeep963

    saving previous transaction values

    Though its late to answer I guess, here is one solution: Create two packets in your monitor as follow; class any_monitor extends uvm_monitor; // rest things task run_phase (uvm_phase phase); my_packet previous_packet = my_packet::type_id::create("previous_packet"); my_packet current_packet = my_packet::type_id::create("current_packet "); // Processing the transaction // Do the needful and before sending the packet through monitor analysis port make a local copy for it as // since we send the packet through analysis port in the end where we are all done with our processing , so upto here you have previous packet available $cast(previous_packet,current_packet ); analysis_port.write(current_packet ); // In this way you can make for more copies , even put these copies in fifo , do whatever flavor your want to implement endtask In the above way you can make for more copies , even put these copies in fifo , do whatever flavor your want to implement. Hope it will meet your requirements. Regards, Karandeep
  11. Let me try to understand the problem before proposing any solution. You wanted to access the 32bit and 64bit data-width registers via program bus whose datawidth 64 bits. In hardware we mimic such scenarios using byte_enable that decides the valid bytes in data_width and registers those are only 32bits valid fields implemented marked the rest with reserved bits. Same is done in the RAL as well , we only implement the valid fields for the register while non-implemented space treated as reserved. So while accessing the registers the respective values are updated. Let me take another example , Your RAL registers will be updated with what the data you received from monitor (in case of read)on the program bus, since the monitor mimics the program bus protocol so it will create a valid values in data-width using byte_enables. Now the transaction created by monitor would be passed to your RAL registers via reg_adapter(adheres two api's reg2bus and bus2reg) which further updates the desired/mirrored values as per the call. I might not be getting the right understanding to your question, in that case let me share my views about tlm extensions, that might connect you in better way. TLM extensions as far as I understand come with tlm_gp (TLM_GENERIC_PAYLOAD). TLM_GP in itself is enough to carry the required contents for valid memory mapped transactions as it contains : m_address m_data m_command m_streaming_width m_byte_enable_length extensions are optional part that is associated with your payload , by the word "Optional" I wanted to say that apart from above if you need some other information to be passed that can be send in extensions. The beauty is that if at the receiver/driver is looking for that extra information it will use it and if not that will be ignored simply, thus providing you the interoperability between those two driver using the same payload. I tried with my assumption, let me know your views. Regards, Karandeep
  12. Great Many Thanks Tudor !!! I will try implementing this way.
  13. Agreed !! But the problem is that there isn't any post_predict(...) hook defined for uvm_reg, do need to make n number of callbacks for n/4 registers. Scarifying the vertical reuse for sake of using single callback for n registers. Indeed at deep of my heart I was feeling it not a good way, Thanks for pointing. Now I will for sure try to find some other way out. Implementing this behavior in predictor will help ??? I will try to check this implementing at predictor level. Thanks for your valuable feedback.
  14. Thanks Tudor for sharing your thoughts, it really helps. Posting here the implementation, might be helpful of someone someday (provided better ways would always be there ) --------------------// CALLBACK IMPLEMENTATION //--------------------------- class my_cb extends uvm_reg_cbs; `uvm_object_utils(my_cb) virtual task post_write( uvm_reg_item rw); uvm_reg my_reg; uvm_reg rg; int unsigned offset_addr; if (!$cast(my_reg ,(rw.element))) begin //TODO: remove this once able to use get_offset() api with rw.element `uvm_error("WRONG_TYPE","Provided casting failed") return; end offset_addr = (my_reg.get_offset() & 'hFFF0); for(int i = offset_addr; i <= (offset_addr+'hC); i= i+4)begin rg = rw.map.get_reg_by_offset('h0000+i, (rw.kind == UVM_READ)); if (rg == null) begin `uvm_fatal("REG_NULL",$sformatf("Unable to reg by offset = 0x%8x : called from %s",('h0000+i), get_type_name() )) end rg.predict(my_reg.get_mirrored_value()); // Updating the mirror values for all the four reg end endtask:post_write endclass:my_cb ----------------------// IN REG BLOCK //--------------------- virtual function void build(); my_cb cb_reg = new(); // Now create all registers REG1 = REG_1::type_id::create("REG_1", , get_full_name()); REG_1.configure(this, null, ""); REG_1.build(); // Similar for REG_2/REG_3/REG_4 uvm_reg_cb::add(REG_1, cb_reg); uvm_reg_cb::add(REG_2, cb_reg); uvm_reg_cb::add(REG_3, cb_reg); uvm_reg_cb::add(REG_4, cb_reg);
  15. Thanks Tudor !! You exactly hit the right place. Indeed registered callback to reg only. I think what I wanted to acheive would have to be done in other way. I wanted to implement "SHARED VALUE" registers which are at different address space in same map. Lets say I have 0x0 REG 1 --> Type RW 0x4 REG 2 --> Type W1S 0x8 REG 3 --> Type W1T 0xC REG 4 --> Type W1C Now any change(write) to any register should be reflected(read) same in all the four. For this reason I planned to make a callback, register that with all the four reg, any writeaccess to an anyone will trigger the same callback in which post_predict will update the desired value of all the four with the current updated(desired) value of accessed register. Can you please share thoughts what wud be the better way for this type of implementation. Thanks once again. Karandeep.