Quantcast
Channel: UVM Methodology and BCL Forum RSS Feed
Viewing all 283 articles
Browse latest View live

16-bit uvm_mem in 32-bit map - overlap warning

$
0
0

I am getting a warning when building a uvm_mem_map that contains a mix of 16- and 32-bit wide memories.  It seems the 16-bit memories are taking twice as much address space as they should.  The error message reads:

 

In map 'm_regs.LB_map' memory 'm_regs.mem32bit' overlaps with address range of memory 'm_regs.mem16bit': 'h[e000:fffc]

 

The mem16bit is defined as a 4096 x 16-bit memory and added to the map at address 'hC000.  It should therefore occupy address range 'hC000 - 'hDFFE

 

The mem32bit is defined as a 2048 x 32-bit memory and added to the map at address 'hE000.  It should occupy address range 'hE000 - 'hFFFC (which it does)

 

What am I missing here?  Why does it think there is an overlap?


Interface Monitor implementation

$
0
0

Hi,

 

I have a interface monitor where i am capturing data from the interface.

I need to pass valid data captured from the interface to the scoreboard for comparison.

 

But the behaviour of interface signals and the way they are asserted depends on the register configuration.

Now this config info is not known to the interface or the interface monitor.

So while implementing the monitor, should i define two monitors

1) interface monitor which just samples all the data from the bus.

2) process data got in 1) furthur depending on the register config & then pass it on the scoreboard for comparison.

 

 

Also should this be done using analysis ports?

I think this is the right way but wanted to know if there is anything that UVM recommends in such cases.

 

Thanks in advance.

Parag

UVM_MEM bursting

$
0
0

I am working on a design that supports single, or bursting access to a memory. I would like to keep the abstraction of the register model (ie. MEM.Write(), MEM.bust_write()...).  It appears that the register model breaks up the burst-ed writes into single transactions. 

 

What is the best way to implement a burst_write (Basically one address, and many data items) into a single seq_item for the driver to implement?

bidir TLM ports

$
0
0

I want to create a master model that performs a non-blocking put to a slave.  Later, I expect the slave to do a blocking put back to the master.  So my master should have a uvm_nonblocking_put_port and a uvm_blocking_put_imp.  I'm trying to figure out if one of those bidir port types includes that combination.  It's kind of hard to decipher the TLM code.

 
Anyone know of example code using the bidir ports?
 

Writing register fields

$
0
0
I am confused about register field write() vs register field set() followed by register update().
 
When writing a register field, a warning is echoed on the transcript (with uvm 1.1b and 1.1d):
 
"...[RegModel] Target bus does not support byte enabling, and the field 'test_rm.test_field' is not the only field within the entire bus width. Individual field access will not be available. Accessing complete register instead."
 
While it is correct that my target bus does not support byte enabling, the field is indeed the only field in the register.
 
Single-stepping through uvm_reg_field::write() up to the point where the warning is echoed, shows that a check for side effects is being made before the actual bus write, in this case resulting in a "bad_side_effect" flag being cleared (since there is no fields to conflict with), but instead of just proceeding with the bus write at this point, another checker is called to figure out if the field is individually accessible, and this check fails, even if the field has been configured as such. The checker even concludes there is only one field in the register by setting a bit named "sole_field", still the checker emits the warning and returns failure. This does not look right.
 
So in an attempt to get rid of the warning, I tried set(value) on the field followed by update() on the register. But it seems this isn't the same as write(value) on the field. For example, if the field has W1C access, then set(1) will clear bit 0 of the desired value and if that changed the desired value, a subsequent update will write the desired value to the bus. A write(1) on the field, on the other hand, will do just that. Thus there is a difference both in what value is written on the bus and also whether or not a bus transaction will take place.
 
So how can register fields be written to the dut without flooding the transcript with warnings?  I realize the warnings can be silenced via the log system, but that will disable all warnings from [RegModel], and that is probably not a good idea.
 
 
Erling

Modifycation of uvm_object internals

$
0
0

Hi,
I would like to ask UVM familiar users/professionals to get an opinion on the following issue:

I am trying to modify uvm_object's internal fields during a run_phase of my testcase (or it could be
end_of_elaboration_phase or start_of_simulation_phase, important - environment is already built up).
Would you consider it like "this is something that should be working"?

- let's assume the object "ga_config" is agent configuration

- for simplicity there is only 1 data field "monitor_enable" in it

class ga_config extends uvm_object;

  // Variable: monitor_enable
  uvm_active_passive_enum monitor_enable = UVM_PASSIVE;

  function new (string name = "unnamed-ga_cfg");
    super.new(name);
    this.name = name;
  endfunction

  `uvm_object_utils_begin(ga_config)
    `uvm_field_enum  (uvm_active_passive_enum, monitor_enable, UVM_DEFAULT)
  `uvm_object_utils_end

endclass : ga_config

- "ga_cfg" is a name registered into uvm database in TB environment (in build phase)

  ga_cfg = ga_config::type_id::create("ga_cfg");
  uvm_config_db#(ga_config)::set(this, "ga_env0*", "ga_cfg", ga_cfg);


- "ga_cfg" is sourced from uvm database in agent monitor (in build phase)
 

class ga_monitor extends uvm_monitor;

  ga_config cfg;

...

  function void build_phase (uvm_phase phase);

   ...

  uvm_config_db#(ga_config)::get(this, "", "ga_cfg", cfg);

   ...

  endfunction

  …

endclass

 

  i.e I am expecting here to create a pointer to object "ga_cfg"


- NOW in testcase for example end_of_elaboration_phase I WANT TO MODIFY "monitor_enable" field
 

class my_testcase extends uvm_test;

...

  function void end_of_elaboration_phase (uvm_phase phase);

  uvm_config_db#(uvm_active_passive_enum)::set(this, "tb_env0.ga_env0.ga2.monitor.cfg", "monitor_enable", UVM_ACTIVE);

  endfunction

  …

endclass

 

  Note: assume the path "tb_env0.ga_env0.ga2.monitor.cfg" is something you can extract from
  hierarchy report (print_topology).


Unfortunately this latest command doesn't have desired effect. I’d expect to see monitor_enable value set to UVM_ACTIVE,

but I still see UVM_PASSIVE. Can anybody explain why?

 

I have seen some comments regarding issues w/ uvm_object hierarchy and UVM 1.1. Is it related to what I am trying to describe here?

Thanks Josef

Why is there no uvm_reg_block::write_field_by_name()?

$
0
0
There is a function uvm_reg_block::write_reg_by_name() which will write to a register using it's simple name instead of the full hierarchical path. Why is there no equivalent function for writing directly to a field? I can do the two step process of uvm_reg_block::get_field_by_name() followed by uvm_reg_field::write(), which is basically what happens under the hood of uvm_reg_block::write_reg_by_name(), but why isn't this already built into UVM? Or is there a way to do this that I missed?

Thanks

Hierarchical register maps

$
0
0

I've written the register abstraction for my DUT in a hierarchical manner, i.e. a reg_block containing sub reg_blocks. Each of the sub blocks has a register map with a specified base address and the offsets for the registers it contains. The top level reg_block also has a register map with a base address and offsets for it's sub reg_blocks.

 

Q. What is the methodology for passing the sub block offsets from the top level address map to be the base address of the address maps for the sub blocks?
This must involve passing to each of the sub blocks address maps during build the base address of the top level address map + the offset in the top level address map for that particular block?

 

Should I be using add_submap?

 

Thanks.


Implementing register burst read

$
0
0
I am using the extension parameter of reg read()/write() to implement burst transfers. This is relatively straight forward for writes since it is easy to get hold of the extension in adapter::reg2bus, but read is more problematic because the reg item is null for adapter::bus2reg, and thus the extension isn't available when the data arrives from the dut. Is this a bug or a feature? What would be a good workaround? I am considering a resource instead of the extension parameter. Better ideas? How do you deal with burst transfers?
 
 
Erling

sequencer and sequence driver

$
0
0

May I know what is the difference between a sequencer and sequence driver, are they the same or sequence driver is simply the UVM driver?

 

Unused bits in a uvm_reg

$
0
0
Is it a requirement that unused bits are to be modeled for uvm reg to work? For example, if there is a 24 bit field in a 32 bit reg, can the 8 unused bits be left out of the model or is it necessary to add fields to cover the unused 8 bits in the register?
 
 
Erling

creating sequence library of virtual sequences

$
0
0

Hi,

 

I wonder if we can create sequence library of virtual sequences? I know uvm supports uvm_sequence_library class where we can create library of uvm_sequence.

can we do same for virtual sequences?

 

If yes can anyone give me example?

 

Thanks,

Akshay

System level uvm_reg_map::get_n_bytes() returns 0?

$
0
0

Why does uvm_reg_map::get_n_bytes() return 0 if you call it on a system level map?  That is completely useless and tells me nothing about the system.

 

If on the other hand, I call uvm_reg_map::get_n_bytes() from a lower level map in my register model, then I get the narrowest bus width in the map hierarchy.  That makes sense.  It seems I should get that same value when calling get_n_bytes() on the system level map.  Returning 0 is not useful under any circumstance.

 

different between run_phase and other 12 runtime phase

$
0
0

Hi, all

 

     i confused about the different between run_phase and other 12 runtime phase at bellow two case:

 

First Case:

 

task monitor::run_phase(uvm_phase pahse);

super.run_phase(phase);

#50;

`uvm_info("RUN_PHASE", "Monitor Run_phase Starting", UVM_NONE)

endtask

 

task driver::main_phase(uvm_phase pahse);

super.main_phase(phase);

phase.raise_objection(this);

#100;

`uvm_info("MAIN_PHASE", "Driver Main_phase Starting", UVM_NONE)

phase.drop_objection(this);

endtask

 

In the case, raise objection in driver‘s main_phase task, does not raise objection in the monitor's run_phase task

the run_phase and main_phase work as expected!

 

 

Second Case:

 

task monitor::run_phase(uvm_phase pahse);

super.run_phase(phase);

phase.raise_objection(this);

#100;

`uvm_info("RUN_PHASE", "Monitor Run_phase Starting", UVM_NONE)

phase.drop_objection(this);

endtask

 

 

task driver::main_phase(uvm_phase pahse);

super.main_phase(phase);

#50;

`uvm_info("MAIN_PHASE", "Driver Main_phase Starting", UVM_NONE)

endtask

 

In the case, raise objection in the monitor's run_phase task, does not raise objection in the driver’s main_phase task

The run_phase work expected, but the main_phase task in driver does not output any information, in other words, it seems like the main_phase task is not scheduled!

 

Who know the reason?

 

BR

 

QIN

uvm_reg_field::do_predict() does not call cb.post_predict for UVM_PREDICT_DIRECT

$
0
0

Is there a reason the uvm_reg_field::do_predict() function does not call the cb.post_predict()?

 

I created a callback that triggers an event using post_predict, but the post_predict never gets called for the UVM_PREDICT_DIRECT case.

 


How to determine if a UVM_REG is initialized

$
0
0

Is there a way to determine if a uvm_reg has been initialized?

 

For example, a register that is located in EDAC protected block ram will power-up uninitialized. If the register is read before it is written to (or before the DUT has updated it internally) an error will occur.

 

I would like a way to tell if the register has been initialized in order to predict this error case.

 

 

what is the intend of uvm_wait_for_nba_region?

$
0
0

Hi, All

 

there is a task as follow in uvm_globals.sv file.

 

 

//----------------------------------------------------------------------------
//
// Task: uvm_wait_for_nba_region
//
// Callers of this task will not return until the NBA region, thus allowing
// other processes any number of delta cycles (#0) to settle out before
// continuing. See <uvm_sequencer_base::wait_for_sequences> for example usage.
//
//----------------------------------------------------------------------------

task uvm_wait_for_nba_region;

  string s;

  int nba;
  int next_nba;

  //If `included directly in a program block, can't use a non-blocking assign,
  //but it isn't needed since program blocks are in a seperate region.
`ifndef UVM_NO_WAIT_FOR_NBA
  next_nba++;
  nba <= next_nba;
  @(nba);
`else
  repeat(`UVM_POUND_ZERO_COUNT) #0;
`endif


endtask
 

For example, it is used in the task wait_for_sequences in uvm_sequencer_base.sv file

 

Who would like to explain the function of the uvm_wait_for_nba_region in details?

 

Best Regards

 

QIN

 

 

 

Simple change to add support for (concurrent) posted reads in Register Layer

$
0
0

A Register Layer read (using the built-in frontdoor) proceeds as follows:

 

  uvm_reg::read -> uvm_reg::XreadX -> uvm_reg::do_read -> uvm_reg_map::do_read -> uvm_reg_map::do_bus_read

 

If a read request (bus_req) is expected to be completed by a completely separate read reponse (bus_rsp), the following code is executed within uvm_reg_map::do_bus_read:

 

      if (adapter.provides_responses) begin

        uvm_sequence_item bus_rsp;

        …

        rw.parent.get_base_response(bus_rsp);

        adapter.bus2reg(bus_rsp,rw_access);

      end

 

The problem is that since transaction_id is not being provided to uvm_sequence_base ::get_base_response:

 

  virtual task get_base_response(output uvm_sequence_item response, input int transaction_id = -1);

   …

    if (response_queue.size() == 0)

      wait (response_queue.size() != 0);

 

    if (transaction_id == -1) begin

      response = response_queue.pop_front();

      return;

    end

 

    forever begin

      queue_size = response_queue.size();

      for (i = 0; i < queue_size; i++) begin

        if (response_queue[i].get_transaction_id() == transaction_id)

          begin

            $cast(response,response_queue[i]);

            response_queue.delete(i);

            return;

          end

      end

      wait (response_queue.size() != queue_size);

    end

  endtask

 

the next response provided to the sequencer will unblock get_base_response and be provided to ALL reads that have posted their requests and are waiting for a response.  When that happens the first read to unblock will get the transaction (possibly not the correct one), and then the others will get null responses, and incur in Null-access runtime errors.

 

By simply adding the transaction_id as follows:

 

          rw.parent.get_base_response(bus_rsp, bus_req.get_transaction_id());
 

we force get_base_response to return only after the correct response matching the request is received by the sequencer.

 

The change will enable support for bus protocols where reads are posted and their responses may be returned out-of-order; and it should not affect simpler protocols  where the read requests/responses are not interleaved.

 

Without the (simple) change the only solutions are to:

 

  1.  Create a user-defined frontdoor; which adds significant complexity, since not all automated register model generators have to hooks register them automatically

 

  2.  Extend uvm_reg_map, override do_bus_read, and factory replace

 

 

We are using solution #2.

 

Before reporting this to the UVM Mantis I wanted to open the topic for discussion.

 

Regards,

 

Devaloy Muniz

 

when is the value of the lock_list.size() greater than one?

$
0
0

Hi, all

 

     when is the size of the queue lock_list greater than one in uvm_sequencer_base.sv file?

 

     Could you like to give us some examples?

 

     Thanks in advanced!

 

BR

 

QIN

constraint on sub sequence

$
0
0
`uvm_do_with(m_top_seq, {m_sub_seq.num_of_trans == 0;})

The above example results in a runtime null object failure for m_sub_seq

Is there a way to overcome this without copying all m_sub_seq random variables to m_top_seq ?

Viewing all 283 articles
Browse latest View live