Jump to content

UVM phases - how stable is the new phasing?


Recommended Posts

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...