Jump to content


  • Posts

  • Joined

  • Last visited

Everything posted by Robert.g.Liu

  1. I have seen several SV-DPI and pthread related posts in this forum and in stackoverflow. However, it seems no post for SV-DPI and co-routine. I guess the reason is there is NO standard library or C language native support for co-routine ( except C++20). Now I'm trying several C based co-routine libraries mentioned in https://en.wikipedia.org/wiki/Coroutine to support python/javascript type of generator in Systemverilog/UVM testbench. Here is how. 1. One SV thread is working as main thread. A SV function will be working as a co-routine and exported to DPI. 2. The SV thread need to create a co-routine by calling co_create through the DPI. the first argument of the co_create would be a wrapper function to the SV exported function. And co_create will use a dynamically allocated array as standalone stack for the co-routine being created. 3. Then SV thread need to resume the co-routine by calling co_resume through the DPI. Here, stack pointer of the CPU will switch to the new stack of the co-routine and entry point is the wrapper function. And finally, the execution will go to the SV exported function and go back to SV side. 4. In the middle of the SV exported function, co_yield will be called. stack pointer will be switched back to the main thread and program counter will be returned to right after the co_resume. Finally, execution will return back to the SV side of the main thread. 5. Above step 3-4 can be repeated many times until the exported function is finished and co-routine can be destroyed. I don't know how much stack space is needed to run SV functions on it. I just allocated 32KB for each co-routine. That's all. This is completely single threaded with user space cooperative multiple tasking. Again, this is to mimic the python/javascript type of generator for test framework development. Is there any risk ?
  2. Here my code: package pkg; import uvm_pkg::*; `include "uvm_macros.svh" `define rob_field_sarray_int(ARG, FLAG) \ `uvm_field_sarray_int(ARG, FLAG) \ begin \ case (what__) \ UVM_SETINT: \ begin \ __m_uvm_status_container.scope.set_arg(`"ARG`"); \ if(uvm_is_match(str__, __m_uvm_status_container.scope.get())) begin \ if((FLAG)&UVM_READONLY) begin \ uvm_report_warning("RDONLY", $sformatf("Readonly argument match %s is ignored", \ __m_uvm_status_container.get_full_scope_arg()), UVM_NONE); \ end else begin \ ARG = { << $bits(ARG[0]) {$bits(ARG)'(uvm_object::__m_uvm_status_container.bitstream)} }; \ __m_uvm_status_container.status = 1; \ end \ end \ end \ endcase \ end class set_int_local_class extends uvm_pkg::uvm_object; int data[2]; `uvm_object_utils_begin(set_int_local_class) `rob_field_sarray_int(data, UVM_ALL_ON) `uvm_object_utils_end function new(string name = "set_int_local_class"); super.new(name); $display("$bits(data) = %0d", $bits(data)); endfunction: new endclass: set_int_local_class endpackage module test; pkg::set_int_local_classmy_inst = new; initial begin longint unsigned data_val = 'h1234_5678_9abc_def0; my_inst.set_int_local("data", data_val); my_inst.print(); end endmodule The appended UVM_SETINT branch in rob_field_sarray_int macro is what I would like to have.
  3. In a transaction sub-class we have a simple integer array like int my_data[2]; Then we can declare the field automation like `uvm_field_sarray_int(my_data, UVM_ALL_ON). If we call set_int_local("my_data", 'h0123456789abcdef) on that class object, we get nothing into the my_data array. After going through the class reference manual we can't see the expected result of this function call. And checking the body of the `uvm_field_sarray_int macro, I think the UVM_SETINT case branch appears very strange.
  4. Often we are required to just compare part of the transaction items, and which part to compare is different in different context. For example, for a simple bus transaction, we can come up with these contexts: o just compare the control part ( address, direction and other control information) o just compare the data part ( wdata or rdata depending on the direction) o all of them Without a compare kind input like in vmm, I'm looking for a graceful solution for this.
  5. Hi Dave, Sorry for the latency. Speaking of "random stability", I just review the "thread stability and object stability" section of the LRM. Since the static initialization of object in module, interface, program and package is allowed, making use of the initialization seed of the enclosing design element, static creation of "dynamic thread" can follow the same way. In some sense it is another flavor of "initial" and "always*" procedural.
  6. In this following code example, class test; rand bit [7:0] da[]; rand int unsigned len; constraint cst_len { len inside { 2, 4, 8 }; } constraint cst { da.size == len; solve len before da.size; } endclass The issue is from "solve len before da.size". It was working with some simulator. Now it stops working on the uvm platform with all simulators. The intent is clear: find out the len value first and allocate that amount of memory and produce random number for each array element. So the question we have: 1) is it legal sv code? 2) is it really necessary?
  7. One of register test requirements is that the write-only register written with a new value in advance can be read back correctly via the back-door interface anyway. It is to prove the correctness of write to the write-only register via front-door. The uvm_reg doesn't support this because it will do the pre_read check using uvm_reg_write_only_cbs class before the true backdoor operation is done. The read is then returned with UVM_NOT_OK and failed eventually. Suppose the test requirement makes sense here, what could I work-around this? Seem the uvm_reg should be updated to distinguish the backdoor and frontdoor way of read from write-only register.
  8. I'm building up a UVM flow for my team working with the three simulators. The code I showed in this thread is just for describing the issue, not being the real code actually. The code was written on VCS initially and then ported to IUS and Questa. This kind of utility classes were designed to provide waveform dumpping and other service and they always are singleton classes. I hope its user wanting the service just needs to include the file class. When the class is "loaded" at the beginning of simulation a back-ground thread can be spawned. Obviously, there would be no "initial" block there. Currently VCS and IUS support this coding style but Questa( latest 10.1d) doesn't. I think Dave has pointed out the statements in the LRM. To make the code standard complaint I have to add "initial" blocks. But really I think it is handy coding style. And thanks Dave and jadec for supporting this issue.
  9. And it is using deprecated features in uvm_pkg which prevents user from declaring UVM_NO_DEPRECATED macro.
  10. Similar to uvm_reg, I like all the DPI stuff with the uvm_/UVM_ prefix. This includes: Macro RGM_NO_VHPI Filename rgm_set_hdl.c
  11. I found a statement in the LRM-2009, page 138. 8.17 Data hiding and encapsulation A member identified as local is available only to methods inside the class. That way the "static local singleton me = new;" should be illegal per the LRM. However, I think the LRM statement is too restrictive. The invocation of local member should be allowed in the scope of its class, rather than only in the scope of methods inside the class. And constructor function is also a kind of member as well. In addition, this is supported by all simulators, though it appears illegal per the LRM: module top; class singleton; static local bit _dummy = do_something(); static local function bit do_something (); endfunction local function new(); endfunction endclass: singleton endmodule: top
  12. no, actually questa doesn't support this, even I enabled -sv09compat. It said, "Illegal access to local constructor."
  13. Hi Uwe, Actually we can have two kinds of coding style for singleton class: let's call them "starve" and "lazy". If I know the instance of the singleton is a must in a testbench and it doesn't play with other classes, it can use this "starve" coding style, eliminating the get_inst method and its invocation. For example, we can put the waveform dump function call in the constructor with local attribute, use can "include" the class file inside his tb top module and it's done. Not all the simulation can compile the code: static local singleton me = new; since the "new" has a "local" modifier. How does the LRM state this point?
  14. One of the singleton class coding styles is like this: module top; class singleton; static local singleton me = new; local function new (); endfunction endclass: singleton endmodule: top The invocation of "new" constructor is in the class but not in the static function like "get_inst". Simulators don't handle this code uniquely. Please help confirm whether it is allowed by the LRM.
  15. I have simplified my real code into following code example: module top; class test; static bit _dummy = _dummy_func(); static function bit _dummy_func(); fork $display("hello"); join_none _dummy_func = 0; endfunction: _dummy_func endclass: test endmodule: top Since the function _dummy_func including a fork...join_none statement isn't called in any initial or always block, simulators don't handle it uniquely. As a result, my tb on the UVM isn't universal any longer. So, I'm just wondering if it is legal against the LRM.
  16. The main intent is to turn off the real time phases in a simulation so that much less number of "empty" threads will be spawned. We just implement the behavior in the run_phase. Of course, from the current implementation the define_domain has to be overridden in subclasses or the simulation will crash due to null reference deference. However, it's better to have it in the BCL. -Robert
  17. Any reason when creating the uvm_test_top using the factory method in run_test, the parent_inst_path parameter of uvm_factory::create_component_by_name has the argument value "uvm_test_top", resulting in a "uvm_test_top.uvm_test_top" instance path for this component inside the factory method? $cast(uvm_test_top, factory.create_component_by_name(test_name, "uvm_test_top", "uvm_test_top", null)); It seems to make more sense to just make the parent_inst_path argument an empty string when calling the factory method for creating the uvm_test_top component. $cast(uvm_test_top, factory.create_component_by_name(test_name, "", "uvm_test_top", null));
  18. Hi, The code does support the wildcard instance override when the original type name argument contains wildcard metacharacters in the uvm_factory::set_inst_override_by_name method. Nonetheless, the user's guide and class reference manual don't mention this at all. So what's the intention concerning this feature ? Will it be deprecated in the next revision so it is not recommended for use in the new development? Thanks, Robert
  19. Hi uwe, Ok. I will report the issues to vip-tc@lists.accellera.org first to get them discussed first. -Robert
  20. Hi, Any idea that in the uvm_object::copy implementation the do_copy is prior to the __m_uvm_field_automation while in the others, like print, compare, pack and unpack the do_* function calls are following the __m_uvm_field_automation calls? In my opinion putting the do_* after the __m_uvm_field_automation is better than the reversed order of the placement since it gives the derivation of uvm_object all the rights to deal with any kind of exceptions. It also keeps the consistency between the field automation method and do_* methods. Thanks, Robert
  21. Hi, Since I don't find in the class reference the statement that it is illegal that null RHS is used I think it is permitted to do that then. The comparison was successfully done until the get_type_name was called on the rhs without a null reference check before the method invocation, the simulation crashed finally. The issue here is that after the comparer initialization between line 1058 and 1067, the scope depth must be greater than 0 so the else branch between line 1072 and 1078 would never run. So done won't be set when rhs == null. BTW, bit t and static int style are declared but never used. Should these be cleaned up? Thanks, Robert
  22. Hi, In the uvm_config_db source code, the m_rsc lookup table seems to work as a local cache for config settings. Two issues here: * It is never used in the uvm_config_db #(T) :: get ( ... ) interface method. * In the uvm_config_db #(T) :: m_get_resource_match ( ... ) interface method, if the pool for the specified context has been allocated but the lookup = {inst_name, field_name} doesn't exists in the pool, null uvm_resource reference will be returned to uvm_config_db #(T) :: set (...) and anther pool object will be allocated and replaces the previously allocated pool. Then all the resource in the previously allocated pool will be dropped thoroughly. However, the functionality of uvm_config_db will not be impacted at all due to the issue above. Thanks, Robert www.lsi.com
  • Create New...