Thursday, March 26, 2015

How to find reason for randomize failure in questasim?

Many times our randomize() method call fails and the simulator ejects the failure message. But it is hard time finding the reason for the failure. Questasim has a switch for vsim, which will very clearly display the reason for the failure.   

vsim –solvefaildebug

Wednesday, March 11, 2015

UVM Verbosity management for ModelSim Questa

Generally the following code is used in the test case.

function void end_of_elaboration();
set_report_verbosity_level_hier(m_config.m_wb_wb_verbosity);
endfunction

The above is difficult option since for each change we need to put this and recompile. & simulate.

Easy method is +UVM_VERBOSITY=UVM_*
Where UVM_* can be UVM_FULL, UVM_DEBUG etc.

The funny thing is that the order of this command line argument is very important. It has to be put immediately after the test bench module name as below:
 vsim top_tb +UVM_VERBOSITY=UVM_*.

If we use them after other arguments, there is no effect !!! This is true only for Modelsim Questa.

Tuesday, March 10, 2015

Randomize uvm_driver

Many times we override the uvm_driver to generate error cases or to model delays to the driver. This happens in the build phase of the test case. The drawback here is that we need to have a separate test case for this. If it is an error test, then it makes sense to have a dedicated test case so that it can be regressed and debugged separately.

But when a delay model has to be implemented, it is better to have all kinds of delays in one random test. To cover all kinds of delays, I have used the following method.

Take the example of the driver which drives a message, which has header and couple of DWs of data. Now two kinds of delays are possible: inter-message-delay and inter-dw-delay. If we extend the driver to have separate constraints, we need separate tests for those.

But if we declare one more variable delay_model in the driver, we can randomize this in the test case itself. This saves number of tests.

driver.sv:

  rand int inter_dw_delay; 
  rand int inter_msg_delay;
  rand bit [1:0] delay_model; //
                              //00 - inter_dw_delay=0  & inter_msg_delay=0
                              //01 - inter_dw_delay=0  & inter_msg_delay=random 
                              //10 - inter_dw_delay=random  & inter_msg_delay=0 
                              //11 - inter_dw_delay=random  & inter_msg_delay=random
   

  constraint delay_order { 
    solve delay_model before inter_dw_delay;
    solve delay_model before inter_msg_delay;
  }
  constraint delay_c {
    if(delay_model==0) {
      inter_dw_delay ==0;
      inter_msg_delay ==0;
    }
    else if(delay_model==1) {
      inter_dw_delay ==0;
      inter_msg_delay dist {0:=30, [1:20]:=55, [21:100]:=10, [101:1000]:=5};
    }
    else if(delay_model==2) {
      inter_dw_delay dist {0:=60, [1:20]:=40};
      inter_msg_delay ==0;
    }
    else {
      inter_dw_delay dist {0:=60, [1:20]:=40};
      inter_msg_delay dist {0:=30, [1:20]:=55, [21:100]:=10, [101:1000]:=5};
    }
  }

In the above code, I have all the constraints in the driver. And in the test case, just randomize this driver, only for the delay_model. Other delays can be randomized in the driver run-time only. This covers all combinations of the delay in one single test case !

test.sv:

        if(!env.agnt.driver.randomize(delay_model))begin 
          `uvm_error(get_name(), $sformatf("env.agnt.driver.randomize failed"));
        end
        else begin
          `uvm_info(get_name(), $sformatf("driver.delay_model %2b", env.agnt.driver.delay_model), UVM_MEDIUM);
        end