doituvm Posted September 5, 2011 Report Share Posted September 5, 2011 Hello, We are a small start-up using UVM with IUS. We use UVM-Reg and all the good old OVM stuff in UVM. One of the things that our lead strongly believes is that the new task-based phasing (a la VMM_env) is a must to use. But given the slew of changes, conf-calls going on in UVM development @Accellera we are nervous about the same. Any real user experience - should we attempt to use the new, task based UVM phases right away? Or should we stick to OVM-like run() alone being task and handle synchronizations painfully? Thanks Quote Link to comment Share on other sites More sharing options...
uwes Posted September 6, 2011 Report Share Posted September 6, 2011 hi, depends what you want to do with the phases? - you want the fully thing with domains, phases, phase jumps forward/backward, user defined phases mixed with other things such as sequences then probably it will be a bumpy ride. - you only want to subdivide you stimulus into slices then you are probably ok (althrough you could also use virtual sequences for this) basically you need to answer the questions: - when should an activity start - when should it end - can the activity be ended (killed) - can the activity stop a phase from progression - what happens upon exceptions such as reset regards 7uwe Quote Link to comment Share on other sites More sharing options...
doituvm Posted September 6, 2011 Author Report Share Posted September 6, 2011 Thanks Uwes for response. We are looking at second part of your statement, i.e.: >> - you only want to subdivide you stimulus into slices then you are probably ok Is there a recommended IUS version and UVM version for this basic usage? We use IUS 10.20* and I believe UVM 1.1 (BTW, is there a get_uvm_version API as in VMM?) Also do you have a running example for this in $IUS_HOME or somewhere? My search didn't show it (I am offline from server, can't check it during travel). My simple use model is to allow reset, config-dut, then run and finally check/cleanup - all to be time-consuming. No additional domains, user defined phase etc. Thanks again! Any other user experience on this please? Quote Link to comment Share on other sites More sharing options...
uwes Posted September 8, 2011 Report Share Posted September 8, 2011 hi, >Is there a recommended IUS version and UVM version for this basic usage? We use IUS 10.20* and I believe UVM 1.1 (BTW, is there a get_uvm_version API as in VMM?) i would always recommend "latest" IUS which comes with latest released UVM and contains fixes to already known issues. there is no "get_uvm_version" althrough there are some defines in src/macros/uvm_version_defines.svh if required. there are examples in the examples directory of uvm. >My simple use model is to allow reset, config-dut, then run and finally check/cleanup - as said everything is fine APART from a right reset support. that is currently a hot topic how that should be modelled. i need to check if my reset_aware_component and reset_watcher classes are upto date to post. /uwe Quote Link to comment Share on other sites More sharing options...
uwes Posted September 14, 2011 Report Share Posted September 14, 2011 hi, here is something i used to build reset aware components using some base classes with the current phasing. please note that there are some assumptions used, it requires latest UVM code from the UVM_1_1_BUGFIX branch, it also handles some issues/bugs/quirks in the current UVM,starts activities in the post_reset phase etc... - anyway here is the code: // assumptions: // reset jump to pre_reset // ALL jumps backward are considered similar to a reset virtual class reset_aware_component#(type C=uvm_component) extends C; local process driver_p; local uvm_phase last_ended_phase; // derived types should implement reset_phase and block phase progress upon reset // should assign reset signals // need to update driver_p virtual task span_phases(uvm_phase phase); endtask virtual function void phase_ended(uvm_phase phase); uvm_phase next_phase = phase.get_jump_target(); super.phase_ended(phase); // 1. kill the driver_p // 2. call cleanup_upon_phase_jump if(next_phase != null) begin `uvm_info("RESET", "BACKWARD JUMP - kill spawned-thread & cleanup via hook",UVM_MEDIUM) if(driver_p) driver_p.kill(); cleanup_upon_phase_jump(); // put "reg_model" property on a reset_aware_component will clean semaphore of regs begin uvm_reg_block b; uvm_reg r[$]; if(uvm_config_db#(uvm_reg_block)::get(this,"","reg_model",) begin `uvm_info("RESET",$sformatf("found reset aware register block %s, resetting handshakes",b.get_full_name()),UVM_NONE) b.get_registers(r); foreach(r[idx]) fork automatic uvm_reg i=r[idx]; begin $display("unlocking ",i.get_full_name()); i.XatomicX(0); end join_none end end end endfunction virtual function void phase_started(uvm_phase phase); super.phase_started(phase); if(phase.get_name() == "post_reset") begin fork begin driver_p = process::self(); span_phases(phase); end join_none end endfunction virtual function void cleanup_upon_phase_jump(); endfunction function new(input string name, input uvm_component parent); super.new(name,parent); endfunction endclass virtual class any_reset_watcher extends uvm_component; function new(input string name, input uvm_component parent); super.new(name,parent); endfunction pure virtual task wait_to_start_of_reset(); pure virtual task wait_to_end_of_reset(); virtual task reset_phase(uvm_phase phase); super.reset_phase(phase); `uvm_info(get_type_name(),"reset active, driving reset values ...",UVM_MEDIUM) phase.raise_objection(this); wait_to_end_of_reset(); `uvm_info(get_type_name(),"reset ended, could progress now ",UVM_MEDIUM) phase.drop_objection(this); endtask virtual task run_phase(uvm_phase phase); super.phase_started(phase); `uvm_warning("RESET-WATCHER", {"STARTING ",phase.get_full_name()}) // NOTE assumption is to go through an initial RESET // as also all phases progress through RESET forever begin wait_to_start_of_reset(); begin uvm_domain my_domain = get_domain(); uvm_phase p = my_domain.find_by_name("pre_reset"); my_domain.jump_all(p); end `uvm_warning("JUMP", "DOMAIN JUMP ANNOUNCED") end endtask endclass so the component sensitive to reset could be like this class amba_domain_reset_watcher extends any_reset_watcher; `uvm_component_utils(amba_domain_reset_watcher) virtual amba_bus_if.monitor_mp xi; function new(input string name, input uvm_component parent); super.new(name,parent); endfunction virtual function void connect_phase(uvm_phase phase); virtual amba_bus_if vif; super.connect_phase(phase); begin if(!uvm_config_db#(virtual amba_bus_if)::get(this,"","xi",vif)) `uvm_error("NOVIF","no vif found"); xi=vif; end endfunction virtual task wait_to_start_of_reset(); @(negedge xi.hresetn); endtask virtual task wait_to_end_of_reset(); @(posedge xi.hresetn); endtask endclass a driver could be like this: class amba_master_driver extends reset_aware_component#(uvm_driver#(amba_master_burst_c)); virtual task span_phases(uvm_phase phase); amba_master_burst_c this_item; forever begin `uvm_info("AHB","fetching next burst",UVM_HIGH) seq_item_port.get_next_item(this_item); have_handshake=1; this_item.set_initiator(this); //response.set_id_info(this_item); drive_burst(this_item); seq_item_port.item_done(); have_handshake=0; end endtask // NOTE manual cleanup of sequencer-driver handshake virtual function void cleanup_upon_phase_jump(); super.cleanup_upon_phase_jump(); if(have_handshake) seq_item_port.item_done(); have_handshake=0; endfunction virtual task reset_phase(uvm_phase phase); super.reset_phase(phase); xi.hbusreq <= 0; xi.htrans <= IDLE; endtask // rest of code endclass an agent could look like this (to stop the sequences upon a jump): class amba_master_agent extends reset_aware_component#(uvm_agent); virtual function void cleanup_upon_phase_jump(); if(is_active==1) sequencer.stop_sequences(); endfunction // rest of code endclass a monitor could look like this: class amba_master_monitor extends reset_aware_component; virtual task span_phases(uvm_phase phase); amba_master_burst_c the_burst; amba_master_transfer_c the_beat; int unsigned beats_to_go; bit the_burst_has_ended; forever begin // granted @(xi.monitor_cb iff xi.monitor_cb.hready && xi.monitor_cb.hgrant); fork begin // end of addr phase @(xi.monitor_cb iff xi.monitor_cb.hready); monitor_addr_phase(the_burst,beats_to_go,$time); // checkif the burst has ended if(the_burst.burst_kind!=INCR) the_burst_has_ended = (beats_to_go==0); else the_burst_has_ended = 0; if(xi.monitor_cb.htrans inside {SEQ,NONSEQ}) monitor_data_phase(the_burst,the_burst.direction,the_burst.data[the_burst.data.size()-1],the_burst_has_ended); else @(xi.monitor_cb iff xi.monitor_cb.hready); end join_none end endtask // monitor // rest of code endclass 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.