Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by jadec

  1. I'd call it from the sequencer once and store the value to be retrieved whenever a sequence wants it. That does assume that you're setting some global parameter and not something that's applied to particular sequence instances.
  2. I was able to compile your code (with some minor additions). The message is very strange because the "formal type" is exactly what the "actual type" is extended from, so I don't see why this would fail. You should probably consult your simulator vendor.
  3. Nash, you're probably better off creating your own question thread. But you should be able to register your own objection callback for this without modifying the component.
  4. The answer to the question is a question "How does your hardware determine the packet length?" Once you know that, you can implement the same logic in your monitor. It will be either so interface signaling the start and end of packet. Or some common header format. If it's the latter, you'll need a base class for your packet that can decode the common header (both for the length and to determine the actual packet type).
  5. uvm_config_db#()::get() is a rather expensive operation. You'll want to be careful about calling it frequently. For sequences, I generally recommend doing the get in the sequencer and just using "p_sequencer." to access it from your sequence.
  6. Take a look at Figure 1 in the UVM user guide. You should have 2 agents for your DUT. One for the input side (what you're calling your "driver") and one for the output side (which I think you're calling your "monitor"). Each of these agents contains a monitor. The input monitor should communicate to your scoreboard as will the output monitor. This allows you to check the functionality of the DUT (comparing what it saw on the inputs to what it generated on the outputs). If you want to check the functionality of the driver, you'll need to compare the input transactions in the driver against those observed by the input monitor (this is not generally automated).
  7. Since indexes to interface array need to be elab-time constants, you can do: duv_sigif fifo_vif[`PORTS_NUM] (clk, rst); // SystemVerilog Interface ... // outside of procedural block generate for (genvar i = 0; i < `PORTS_NUM; i++) begin initial uvm_config_db#(duv_vif)::set(uvm_root::get(), $sformatf("*.env.subenv[%0d].*", i), "tb_vif", fifo_vif); end endgenerate
  8. Generally, you wouldn't use uvm_resource_db directly. Instead you'd use uvm_config_db. You would identify the different instances by their instance path: uvm_config_db#(...)::set( this, "path.to.bfm1", "INTF", INTF1 ); uvm_config_db#(...)::set( this, "path.to.bfm2", "INTF", INTF2 ); Then in the "bfm" component: uvm_config_db#(...)::get( this, "", "INTF", my_intf ); Because each "bfm" will have a different fullname, the "this" will select the right interface.
  9. The uvm_queue::get_global_queue() function returns a shared queue of a particular type. You can create separate queues by using the uvm_queue::type_id::create(...) function. If your intention is to communicate data between 2 components, it's probably better to use tlm ports.
  10. These base classes are not intended to be directly instantiated.
  11. 1. You may set a default sequence for each run-time phase. This message is generated for each phase that didn't find one. 2. No, the message is an info only (you've probably set UVM_VERBOSITY too high for normal usage). 3. It is similar but there are some differences. For example, the sequencer sets "starting_phase" variable in the sequence if it starts it as a default_sequence.
  12. Perhaps you can post the code you are using to set and get the configuration (along with the context)? SystemVerilog tasks are not objects so they can't be passed directly via config. Normally, I'd expect the "wait for IRQ" function to be implemented in a component and for a handle to that component to be given to the virtual sequencer during the connect_phase (where the sequence can later access it). Config is generally not used for such connections.
  13. uvm_analysis_imp requires that the implementation be a component, but uvm_analysis_port can be instantiated outside of a component: uvm_analysis_port #( my_obj ) myport = new( "myport", null ); It might make debugging more difficult, but the port functionality doesn't require it.
  14. Where did you see this information? I don't find any reference to UVM_MUTE in the UVM 1.1c release at all.
  15. You should be able to safely modify the global report server before calling run_test(). That should handle anything that happens within the UVM phasing (it's still possible for static initializers to run before that, but there's never going to be a way to control the order of that). It seems to me that any extension of uvm_root would suffer from the same timing problem you have now with extending the report server.
  16. Your example is correct. I think you're confusing the component's own "create" method with the factory "create_object_by_type" method. The "create" method of a component is defined by `uvm_component_utils and uses the factory "create_component_by_type" method like it is supposed to.
  17. You should read the uvm_sequence_base section of the reference guide that gives a detailed list of all the sequence methods called.
  18. A virtual interface is a variable that holds a reference to an interface instance. You can assign an interface instance to a virtual interface variable, you can't assign to an non-virtual interface. So the uvm_config_db::set() in file3 is correct in its use of virtual interface type. Both the type parameter and the string name in set() must match the get(). You could use the "chpp_vif" typedef in place of the type "virtual chpp_sigif", but generally it's better to use the same text in both places so that it is obvious that they are the same. You were right that your original problem was that the string names didn't match. The types were not the issue.
  19. You used a typedef for the virtual interface type parameter in your set: typedef virtual chpp_sigif chpp_vif; This is an exact match to the virtual interface type parameter in the get.
  20. For dynamic arrays that you wish to access normally, you'll need to first use "new[len]" to set the size of the array. int arr[]; arr = new[10]; foreach( arr[ndx] ) arr[ndx] = ndx; Inside of randomize call, the simulator will automatically do this for resized arrays. int arr[]; constraint c { arr.size() == 10; } ... void'(randomize()); For arrays of objects the default value is "null". If you want contents in your objects, you'll need to allocate an object for each entry. obj arr[]; arr = len[10]; foreach( arr[ndx] ) begin arr[ndx] = new(); arr[ndx].val = ndx; end Inside of randomize call, the simulator will NOT automatically do this. Thus it is necessary to pre-allocate the objects you might use in randomize. rand obj arr[]; constraint c { arr.size() == 10; } ... arr = len[MAX]; foreach( arr[ndx] ) arr[ndx] = new(); void'(randomize()); NOTE: randomize will size the object array automatically, but if new elements are added they will be null.
  21. The only time you need to pre-allocate the array is if it's an object array (because randomize doesn't call constructors for new objects). If that's the case, you'll probably want to create your sequence, then call a sequence function to initialize the array size to what you need before calling randomize on it. (If you're using `uvm_do, you can use `uvm_create and `uvm_rand_send instead and call your initialize function in between.)
  22. IEEE 1800-2009 18.14.1 (On random stability): "When a class object is created by a static declaration initializer, there is no active thread..." I'm not sure that implies you can't do a fork though this section has no reference to it. I'm curious which simulators have you tried. One thing I see is you've got your class declared in a module. That could create a separate class definition for each instance of the module.
  23. I agree this is a bug in the library. In fact, since you passed the exact size to the macro, there's no reason not to declare the data of the appropriate size. uvm_pack_intN is a utility macro, you can just copy that code into your own implementation and fix the size issue.
  24. You have to change the whole thing. There's no way to interoperate OVM and UVM. On the other hand, the conversion is generally an automated process, you have more flexibility in incrementally removing the deprecated OVM features.
  • Create New...