Quantcast
Channel: UVM SystemVerilog Discussions Forum RSS Feed
Viewing all 410 articles
Browse latest View live

Handling protocol extensions

$
0
0

Hi everyone,

 

I'm curious how you handle extensions to a protocol UVC. Let's say we have an APB UVC that implements the AMBA protocol. Let's also say that we have a DUT that, aside from the signals defined in the specification, also implements a few other signals that are related to the generic APB signals (they add support for protected accesses or whatever). On the class side it's pretty easy to handle: just create a new sequence item subclass with extra fields and do type overrides. Where it gets tricky is when working at the signal level. Our UVC already uses an SV interface that only contains the APB signals and it's not possible to extend it in any way. How would we get these extra signals into the UVC to drive and monitor?

 

What we have done up to now is, since we use our own homegrown UVCs, we just pack everything into the base UVC and have it highly configurable. I don't like this approach as I don't feel it's properly encapsulated. It confuses the user with too many extra config parameters and it makes development a lot harder. I'm just wondering if anyone has a nicer solution to this.

 

Thanks and best regards,

Tudor


SystemVerilog connecting a channel

$
0
0

I'm trying to hook up a new channel (channel 2) to an existing one (channel1) like so:

channel channel1;
channel channel2;

extern function new(
channel_type channel2
);

function subenv1::new(
channel channel2
);

this.channel1 = new();

xactor1(
this.channel1
);

xactor2(
this.channel1
);

//channel1 is a connection between both xactors

//hook new channel2 up to channel1
channel2 = this.channel1

This seems to work fine at this level, ie if I do this check, it doesn't cause a fatal:
if (channel2 ==null) `cvm_fatal


However when I go up to the subenv above this 
if (channel2 ==null) `cvm_fatal

Then I get a fatal. What else do I need to ensure that the channel is not fatal at the next level up?

Rnadomize a variable inside a function

$
0
0

Hi,

 

I want to randomize a variable defined in a function. The function is inside a package.

 

I tried declaring a class inside the package and taking the instance of that class in the function.

But that didnt work out as the object needs to be static.

 

I tried randomization() function, but the problem is the variable "k" can only have 2 value ie (5,9).

 

function foo()

 int k;

 void'(randomize(k)) with {k==5;k==9;});  // I am getting randomization failure in this case.

endfunction

 

Let me know how can this be resolved.

 

Thanks.

Using $past in procedural code

$
0
0

Hi everyone,

 

I'm not sure if this is the right place to post this. I have question regarding the usage of $past(...) and the other members of that family inside procedural code. The SV 2012 standard says the following: "The use of these functions is not limited to assertion features; they may be used as expressions in procedural code as well."

 

I've tried using a call to $past(...) with an explicit clocking event inside a class task. One of our simulators complained that this is only allowed in assertions and procedural blocks. The other one we use allows it. The standard is rather vague here. What constitutes procedural code? Hopefully someone from the SV Committee hangs out in this forum.

 

Here's the code I'm trying.

module top;
   bit clk;
   bit some_signal;

   always #1 clk = ~clk;
   

class some_class;
   task some_task();
      bit foo;
       foo = $past(some_signal,,,@(negedge clk));
       $display("some_signal was %b at the last negedge", foo);
    endtask
 endclass
   
   initial begin
      automatic some_class obj = new();
      
      @(posedge clk);
      some_signal <= 1;
      @(negedge clk);
      some_signal <= 0;
      @(posedge clk);
           
      obj.some_task();
      $finish();
   end
endmodule

Randomization in an initial block

$
0
0

I have a module defined as follows...

module dut();

   int i;

   initial begin
      i = $urandom_range(0, 500);
      $display("The value of i is %1d", i);
   end

endmodule // dut

I'm trying to randomize the value assigned to the variable i.  My top level module is

module top_tb;

   dut dut_a();
   dut dut_b();
   dut dut_c();

endmodule

When I simulate this, the output shows the same value for all three instances.

# The value of i is 3
# The value of i is 3
# The value of i is 3

This is a simple example.  I've tried other approaches, including placing the random variable inside a class, declaring a new object of that class inside the initial block and then randomizing the object.  That yields the same result, all the values are the same in the different instances.  I've added time before the randomization via a #10 statement.  Same result.

 

It seems to be related to the initial block.  So how does the SystemVerilog random functions work in regards to an initial block and non-initial blocks?  There some part of how those functions work that I'm not understanding.  How could I set a different random value inside each dut instance within the initial block?

 

gb

how to drive a clocking block output asynchronously

$
0
0

Our uvm_driver derivatives push values into the RTL via clocking blocks in interfaces.  This updates the signals synchronously as we typically want, but is there a recommended way to add an asynchronous update of the signal to model a change that could occur when asynchronous reset is applied?  We see that if we just assign to the signal at the interface level (not the clocking block level), we get a conflict between both assignments.  

assert(std::randomize(variable)) when assertions are turned off

$
0
0

What systemverilog standard defines when we use

assert(std::randomize(variable))

when assertions are turned off

 

I am using it but bit confuse what should simulators do ?

will it still randomize variable

or keep previous value

or it is going to be 0 (variable is int)

 

 

Thanks

Accessing Memory model from various sequences

$
0
0

I need to use a common memory for 2 sequences. I have a memory defined as uvm_component and all the logic needed to build a memory and its parameterizable. This memory is placed in the sequencer so that the sequences can read/write to it and then drive request from the driver. This all works very well if I wanted to use memory per agent/sequence.

 

I want to now merge 2 sequences driving 2 different interfaces to use the same memory. I have tried the following ways

1) create the memory in TB, so sequences can write/read into. This is not possible as hierarchy is built in test, but when sequences are compiled it cannot find this hierarchy.

2) Cannot do uvm_config_db , as I cannot replace 2 memories from individual sequences to a common place in TB.

3) tried virtual sequence, but had to have 2 sequencers there to pass handles to these 2 lower sequencers. This would still mean 2 memories.

4) Made the sequences run on a single virtual sequencer, but that would not run as the driver widths are different so I would get error either on $cast as below.

 

 

Please let me know how to use single memory model across various sequences.

.

When I tried to run the lower sequences on same sequencer (just for using same memory). Here is the error I get. One sequencer data width is 128 and the other is 64. I have used $cast to cast one type of sequencer to the other and then run the sequence on the sequencer.

 

slave_memory_seq.start(kpEnv.sysSequencer.axi4_slave_sequencer, null); //128 bit sequence
//slave_memory_sram_seq.start(kpEnv.axi4_slave_agent_sram.m_sequencer, null);
slave_memory_sram_seq.start($cast (kpEnv.sysSequencer.axi4_slave_sram_sequencer, kpEnv.sysSequencer.axi4_slave_sequencer), null); //64 bit sequence.

 

Trying to use 1 sequencer (kpEnv.sysSequencer.axi4_slave_sequencer) which has the same memory so both sequences can share.

 

I get the following error
slave_memory_sram_seq.start($cast (kpEnv.sysSequencer.axi4_slave_sram_sequencer, kpEnv.sysSequencer.axi4_slave_sequencer), null);
|
ncelab: *E,TYCMPAT (./tb/tests/kp_base_test.sv,484|33): formal and actual do not have assignment compatible data types (expecting datatype compatible with 'class uvm_pkg::uvm_sequencer_base' but found 'integer' instead).

 

Is there any other way I could run 2 sequences on same sequencer (only purpose being to use the memory).

 

 

Thanks in advance!


Difference between RAL and RGM?

$
0
0

Hi,
I have a doubt related to UVM 's RAL with compared to OVM's RGM. The OVM's RGM seems to have only two sets of registers i.e., the actual ones belonging to DUT and the other belonging to the register model(testbench side regs to mimic duts regs). But the UVM's RAL has three sets namely 1) DUT's regs as usual and 2)Mirror registers 3)Desired value registers, the 2) and 3) are part of the testbench i.e., register model side. Why is this kind of implementation has been adopted in UVM RAL where as we could accomplish our tasks with the 2 sets as is in RGM. Can any one please enlighten me regarding the advantages or usecases related to this?
Thanks In advance.

Running testcase in Questasim

$
0
0
Hi all,
    I tried to run a testcase ( test_write_sequence) using command line in Questasim... 
I had coded a AHB UVC and wanna to perform a simple write transaction.. 
But the tool called $finish in the uvm_root.svh file... Can anyone tell me how to fix this..
 
 
Log:
 
 
# --- UVM Report Summary ---
# ** Report counts by severity
# UVM_INFO :    2
# UVM_WARNING :    2
# UVM_ERROR :    0
# UVM_FATAL :    0
# ** Report counts by id
# [RNTST]     1
# [TPRGED]     2
# [ahb_scoreboard]     1
# ** Note: $finish    : C:/questasim_10.0b/win32/../verilog_src/uvm-1.0p1/src/base/uvm_root.svh(392)
#    Time: 0 ns  Iteration: 196  Instance: /ahb_top
# 1
# Break in Task uvm_pkg/uvm_root::run_test at C:/questasim_10.0b/win32/../verilog_src/uvm-1.0p1/src/base/uvm_root.svh line 392
 

 

run time issue questa sim

$
0
0

I ran a testcase using questa sim,i am getting following output.

 

 

** Error: (vsim-3601) Iteration limit reached at time 0 ps

 

 

testcase run phase look like this. it printed info messages from below code then gave above mentioned error.

 

  task run_phase(uvm_phase phase);

    phase.raise_objection(this);
 
    `uvm_info(get_type_name(), "Starting test",UVM_NONE)
 
    // generate register settings
    assert (m_cfg_gen.randomize()) else
    `uvm_fatal(get_name(),"m_cfg_gen randomization failed");
 
    `uvm_info(get_type_name(), $psprintf("Using this configuration:\n%s",m_cfg_gen.sprint()),UVM_MEDIUM)
    
 
    #20000ns;
    phase.drop_objection(this);
    `uvm_info(get_type_name(), "Stopping test...", UVM_LOW );
 
    endtask : run_phase
 
Please help me in resolving this

how to Constraint dynamic array

$
0
0

hi,

   I will be ready to build one layer protocol testbench,  top level sequence item is transmit to lower level sequencer with large payload of data packet. assuption that

        1)  trans_item  is toper level sequence item(transaction layer item);

       

        2)  link_item  is lower level sequence item(ie,link layer item);

 

      patial  code as follows:

   

      class  trans_item  extends uvm_sequence_item;

          rand  bit [31:0]  mess_data[];

          rand  bit [15:0]  mess_len;

          constraint  C_mess{

            soft  mess_data.size()==mess_len;

            slove  mess_len before  mess_data;

         } 

             ................

    

      class  link_item  extends uvm_sequence_item;

          rand  bit [31:0]  mess_data[];

          rand  bit [15:0]  mess_len;

          constraint  C_mess{

             soft  mess_data.size()==mess_len;

             slove  mess_len before  mess_data;

         } 

             ................

 

     class  top_sequence  extends uvm_sequence #(trans_item);

 

              rand  bit [31:0]  trans_data[];

              rand  bit [15:0]  trans_len ;

                 constraint C_len{

                      trans_len==40;

                      trans_data.size()==trans_len;

                      slove  trans_len before  trans_data;

                 }

                      ....

              virtual  task  body()

                    `uvm_do_with(req,{req.mess_len==local::trans_len;

                                                    ........................

                                                  foreach(local::trans_data[i])

                                                       req.mess_data[i]==local::trans_data[i];})

              endtask

 

    endclass

 

    class  trans_to_link_seq  extends uvm_sequence  #(link_item);

             

                uvm_sequencer   trans_sequencer;

                trans_item   trans_req;

                link_item     link_req;

                        ......

                virtual  task body();

                      forever

                        trans_sequencer.get_next_item(trans_req);

                         ........

                        `uvm_do_with(link_req,{link_req.mess_len==trans_req.mess_len;

                                                               ..................

                                                              foreach(trans_req.mess_data[i])                                                                                                                                                     link_req.mess_data[i]==trans_req.mess_len;})

               .............

   endclass

 

                    

  next, supposing that   trans_sequencer  has connected to link_sequencer by uvm_seq_item_pull_port ,seq_item_export

 

   then , In test start  top_sequence and trans_to_link_seq in fork jion statement;

   

     class  trans_test  extends  uvm_test;

     

              virtual  task  main_phase (uvm_phase phase);

 

                    phase.raise_objection(this,"");

                    fork

                           top_sequence.start(env.agent.trans_sequencer);

                           trans_to_link_seq.start(env.agent.link_sequencer);

                    join_any

 

     During the  simulation,printing mess_len is not 40, questasim10.2c simulator has not  reported assertion failed,in practual constraint is failed,

 

     how  dynamic array and  x_len is constrainted,how to send large payload of data packet to lower sequence or lower driver?

Passing Transaction from Callback

$
0
0

Hi,

 

I have a transaction in the callback and want to pass it on to the scoreboard.

 

Since the callback are not uvm_components it is not possible to use the analysis ports. 

 

Thanks,

Kans

Type parametrization of uvm_analysis_imp

$
0
0

I have a sequencer: 

class l3_ack_sequencer #(type REQ  = uvm_sequence_item) extends uvm_sequencer #(REQ);

    `uvm_component_utils_begin(l3_ack_sequencer#(REQ))
    `uvm_component_utils_end

    uvm_analysis_imp #(REQ, l3_ack_sequencer) generate_res;

    function new (string name, uvm_component parent);
        super.new(name, parent);
        generate_res = new("generate_ack", this);
    endfunction


    virtual function void build_phase(uvm_phase phase);
        super.build_phase(phase);
    endfunction
    
    virtual function void connect_phase(uvm_phase phase);
        super.connect_phase(phase);
    endfunction

    // Generate ack
    virtual function void write(REQ item);
    endfunction   
endclass

Then I declare a handle somewhere:


l3_ack_sequencer  #(core_l3q_ireq_tran) l3r_ireq;

Using Synopsys VCS I have an error:

 

Error-[ICTTFC] Incompatible complex type usage
.../l3_ack_sequencer.sv, 33
  Incompatible complex type usage in task or function call.
  The following expression is incompatible with the formal parameter of the 
  function. The type of the actual is 'class $unit::l3_ack_sequencer#(class 
  $unit::core_l3q_ireq_tran)', while the type of the formal is 'class 
  $unit::l3_ack_sequencer#(class uvm_pkg::uvm_sequence_item)'. Expression: 
  this
  Source info: uvm_analysis_imp_8::new("generate_ack", this)

 

Can anyone help me to solve this problem or explain why it cant be solved?

how to pass value to a variable that is a derivation of uvm_object and not uvm_component

$
0
0

Hi,

problem statement: I wanted to set a value to a variable that is derived of a uvm_object. I wanted to use the get/.set method

 

prvious code snippet:

 

function new(int len = 0)

  if(len > 0)

    this.length = len;

  else

    ERROR

endfunction

 

Given that now the UVM constructor has to be like 

function new(string name ="");

  super.new(name);

endfunction

 

I wanted to set the len, variable using the set method.

1) however the set/get method requires a logical hierarchy, given that this object is instantiated in a sequence object, I don't know what which way can you pass the sequence_item hierarchy. 

2) Also given that the ojbect does not have phasing involved unless I pass the value in some function and call the function explicitly it doesn't seem like it will work.

 

I wanted to know if there is an elegant way to do so?

 

Thanks,

Ankur

 

 

 


UVM_REG : override some addresses of old register model with another register model.

$
0
0

Hi ,

   I have a  top register model. in that some address part is defined as memory. ( ex :- 0x0,4,8 ,c registers address then 0x10 memory then 0x20,0x24,0x28 ... registers) 

 

I have another register model , which has all the registers which fit the space defined as memory  in top register model. (ex: 0x10,0x14,0x18,0x1c as registers)

 

could you please suggest me how to map them .

 

Regards,

Pavan.

Generic Payload Vs PROTOCOL specific packets/seq_items in UVM env

$
0
0

Hello All,

 

I am wondering for the use of generic payload instead of PROTOCOL specific packets/seq_items in UVM agents.

 

Why : 

1. This will help to verify the SC-TLM models(used as golden ref models) with the same testenv.
2. Generic Payload is standard.
3. GP has better interoperability options, less changes in scoreboards etc for new UVC's connections.

 

How: 
1. All the UVC's work on the Generic Payload.
2. Only Driver needs the extra functionality for GP-Protocol toggling conversion.
3. Monitor need to pack the protocol toggling to GP.

 

Threats:
1. Functional Coverage would be somehow difficult to calculate.

 

Please let me know am I moving in right direction or there may be some serious problems using it.

 

Thanks,
Karandeep

How to using package rightly in UVM?

$
0
0

Hi!

 

 

often,in uvm test, host controller write or read registers through  addresses,so, I define some parameter in a package using `define in replace of register address.

   then , import the package into my test lib package,

compile in order , test lib package is compiled lastly,

but when compling code ,report macro address can't find?

How to using package rightly in UVM?

 

Large projects may have many packages with complex interdependencies,How to using it rightly ?

 

 

 

 

thanks.

 

/wszhong

 

can we use callback in other class than driver class or monitor or scorboard

$
0
0

1.can we use callback in other class than driver class or monitor or scorboard

2. in which class or module we can delete the callback

extending uvm_cmdline_processor - problem

$
0
0

I am trying to extend uvm_cmdline_processor as follows, but my extended version, ivm_cmdline_processor is not working.  It seems like the *ref values* might not be getting passed correctly.  There is no error message.  The get_arg_values that is called with iclp is seen I know, because I receive a simulator warning about not using a void'() with the function.  (This warning occurs for both the uclp and iclp usages, as expected.)  I am not sure about my duplication of the get_inst function to create and return a singleton, but have tried versions of this code w/ and w/o it.

`include "ivm_cmdline_processor.svh"
module top;
   import uvm_pkg::*;

   ivm_cmdline_processor iclp;
   uvm_cmdline_processor uclp;

   string values[$];

   initial begin
      $display(">>>> START TEST.");

      iclp=ivm_cmdline_processor::get_inst();
      uclp=uvm_cmdline_processor::get_inst();

      iclp.get_arg_values("+",values);
      foreach (values[iii]) begin
        $display("iclp>>>%0d: %0s", iii, values[iii]);
      end

      uclp.get_arg_values("+",values);
      foreach (values[iii]) begin
        $display("uclp>>>%0d: %0s", iii, values[iii]);
      end

      $display(">>>> END TEST.");
   end
endmodule : top
import uvm_pkg::*;
class ivm_cmdline_processor extends uvm_cmdline_processor;

   static local ivm_cmdline_processor m_inst;

   static function ivm_cmdline_processor get_inst();
      if(m_inst == null) 
        m_inst = new("ivm_cmdline_proc");
      return m_inst;
   endfunction

   function new(string name = "");
      super.new(.name(name));
   endfunction : new

endclass : ivm_cmdline_processor
Reason for attempt:
I would like to add features to the uvm_cmdline_processor.  To start, I'd like to enhance +arg checking by checking that the +args supplied are from a list of valid +args.
 
Typos are too common from my fingers and without this functionality, typos go unnoticed.  (Once I even was in a different sim environment than I thought and was happily running a test with plusargs for a completely different testbench, wondering why things weren't working as I expected.)
 
I realize that I might create an object or 'shell', around uvm_cmdline_processor and do my checking in this 'shell'.  I have a version of this now, but I'd like to make it generic so that it may be used across 'all' testbenches.  Rather than polishing my shell, I am first trying to extend uvm_cmdline_processor and running into these problems.
 
Any ideas about this?
 
(I just discovered this next post from about 30min ago.  Thanks, Srini.  I think my problem is the same, but am not sure as I am not trying to 'mix' which handle (parent or child) points to my extended version of uvm_cmdline_processor.  Yes, I am confused about this.   re: http://forums.accellera.org/topic/1937-uvm-cmdline-processor-why-its-methods-are-non-virtual/ )
Viewing all 410 articles
Browse latest View live