Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


pratta last won the day on July 16 2014

pratta had the most liked content!

About pratta

  • Rank
    Junior Member
  1. I wrote series of articles about the difficulties that SV parameters introduce when developing reusable verification components. See the following: http://www.vip-central.org/2012/09/parameterized-interfaces-and-reusable-vip-part-1/ http://www.vip-central.org/2012/09/parameterized-interfaces-and-reusable-vip-part-2/ http://www.vip-central.org/2012/09/parameterized-interfaces-and-reusable-vip-part-3/
  2. If the sequence constraints are set up properly you could also disable the conflicting constraint on the sequence from the testcase. This works best if the constraints are set up to only affect a single property because otherwise you need to recreate the constraints on the rest of the properties (your simple example demonstrates this). For example, this would work: jb_seq = gift_boxed_jelly_beans_sequence::type_id::create(.name("jb_seq"), .contxt(get_full_name())); jb_seq.num_jelly_bean_flavors_con.constraint_mode(0); assert(jb_seq.randomize() with { jb_seq.num_jelly_bean_flavors == 1;});
  3. Brilliant! I am going to bookmark this thread for all of the times that users have given me grief over this just so that I can come back to this and laugh. It is indeed nice that this will be fixed in 1.2. Unfortunately the 1.0 and 1.1 codebase will live on at customer sites for a very long time, and so the confusion will live on as well.
  4. I agree that this is a trickier problem. You're right that simulators cannot pass types in on the command line, but if the variable portion of your design is scalar values such as data vector widths or number of elements then you can still pass those values in on the command line and then use the typedef construct to create your specific type. For example, pass this in on the command line: +define+DATA_VECTOR_WIDTH=<value> Then in your code you define your customized type: typedef bit [`DATA_VECTOR_WIDTH-1:0] data_vector_t; Now in your code you always use the data_vector_t type.
  5. I have just uploaded a package to the contributions section that demonstrate the problems that parameterized interfaces introduce, along with a few solutions that overcome those problems: http://www.uvmworld.org/contribution_download.php?id=208 Hopefully you'll find this useful.
  6. The value used to specialize the SV classes and the modules and interfaces must be consistent, and they must be known at the time of elaboration (so accessor methods won't help). The only way to test multiple values of N that I know of is to pass the value in as a compile-time constant and run all tests with that value. If you need to test multiple values of N then you will need several compile and run passes (luckily that is a highly parallel problem and so each value of N could be run on a separate host in a separate testbench area).
  7. 636 downloads

    Code examples that demonstrate the problems that parameterized interfaces present for reuseable VIP design and ways to overcome these limitations.
  8. I see. I didn't notice that there were two different monitor class instances. You're right that you should be able to pass the two different interface instances to the two different monitor instances.
  9. There is a typo in top testbench. You need to change the third argument of the second uvm_config_db call to "flash_if1".
  10. I think that you will likely run into scoping problems if you implement all of your concrete classes within an interface. How will those classes then be made available outside of that interface? For example, at the system level you may have a need for multiple specializations of this interface that the system level controller would need access to. In general I have been recommending that people avoid parametrized interfaces because of the problems that you are running in to. However, if they cannot be avoided then you can avoid the proliferation of the parameters through your class hierarchy by using a non-parametrized abstract class to provide access to virtual methods that operate on the interface, and then designing the UVM agent to accept that non-parametrized abstract class and doing all interface operations through that. A parametrized concrete class that extends that base class must also be implemented which has a reference to that parametrized interface and which implements all of the virtual methods to actually operate on that interface. The testbench integrator must then declare a specialized version of that extended class and pass it into the agent.
  11. It isn't elegant, but I've overcome situations like this by creating a non-parameterized port handler class to define empty virtual methods to manipulate the interface. Then I create a parameterized extension of that class which implements those virtual methods to actually do stuff with the parameterized interface. The non-parameterized driver and monitor then create the non-parameterized port handler class and access the interface through those virtual methods. Then the port handler class can be replaced using the factory API with a correctly parameterized port handler class.
  12. I had the same confusion about this. See this thread: http://www.uvmworld.org/forums/showthread.php?243-seq_item_port.put_response%28rsp%29 From what I can tell, the seq_item_port.item_done(rsp) call should be done if the execution model is not pipelined. If the sequencer will only ever have a single transaction outstanding at a time this this is the method to use. If you are using a pipelined communication model, then either the seq_item_port.put_response(rsp) or the rsp_port.write() method can be used. If using the response channel on seq_item_port then nothing more needs to be done to connect the sequencer to the driver. If using the rsp_port then in addition to connecting the seq_item_port, the containing agent must also connect the analysis ports. Which method you choose is up to you however - there are no guidelines about which method to use.
  13. Bart - You are correct that item_done() can be used to return the response to the sequence if the response is returned back to the sequence before the original request is completed. This is one way to design the request/response process, but this isn't how the response is normally used from what I've seen. In the User Guide, and in the public examples that are shipping with UVM the response is not returned to the sequence until the request is completed. Granted, the UVM examples that ship with the UVM BCL are very basic, and don't demonstrate pipelined requests. However, the User Guide seems to back this up as well Section 3.5.3 Fetching Consecutive Randomized Items talks about pipelined protocols and suggests that item_done() should be called without providing a response. Waiting until the request is completed before returning the response seems to convey more information as well. For example, sequences can use the get_response() call to synchronize to the completion of the original request if desired. If sequences don't care to synchronize to the end of the request then they can wait for the response in a thread or else just ignore it by calling set_response_queue_depth(-1).
  14. item_done() can be used to return the response if the sequencer/driver communication model is an atomic in-order execution model. However, we cannot return the response in the call to item_done() if we are using a pipelined response or an out of order response. In that case we need to call item_done() without returning a response, and then we need to send the response back only when the request is completed. I think that I have an answer to my original query however. I believe that the put_response() method is currently documented incorrectly and is intended to be a public method. See the following: http://www.eda.org/svdb/view.php?id=3590
  15. There are conflicting recommendations about which method to use to return a pipelined response back to the sequencer. The 1.1 User Guide states that the response can be returned via a call to seq_item_port.put_response() (section 3.5.4), however, the 1.1RC5 code flags that as an internal method: // Function- put_response // // Internal method. virtual function void put_response(uvm_sequence_item response_item); RSP response; if (!$cast(response, response_item)) begin uvm_report_fatal("PUTRSP", "Failure to cast response in put_response", UVM_NONE); end put_base_response(response_item); endfunction Is this an internal method?
  • Create New...