Jump to content


  • Posts

  • Joined

  • Last visited

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

Robert.g.Liu's Achievements


Member (1/2)



  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?
  • Create New...