Jump to content


  • Content Count

  • Joined

  • Last visited

About tymonx

  • Rank

Contact Methods

  • Website URL

Profile Information

  • Gender
  • Location
    Gdansk, Poland
  • Interests
  1. I have added UVM error/warning messages for all .unpack_*(), .is_null() and .un/pack_object() methods.
  2. Thanks @jrefice. Now I see that the .flush() method is called in the packer new() constructor. It was located at the bottom of the uvm_packer.svh header file (line 1188). I have debugged correctly my issue with invalid m_*_iter values. I see that changes were met in another thread because of a singleton default packer nature. In the standard UVM implementation, creating a new packer object each time when packing or unpacking methods are called, it solves the problem In my implementation, the .is_null() method is not used because I never encode object handler. It is based on the use
  3. I have another minor issue but during extending UVM. I thing it will be better for everyone to split interface from implementation. Because currently I have inherited everything, including some unused private variable members. For example uvm_packer class as an empty class and a separate uvm_packer_impl class with implementation details. It will make inheritance more cleaner.
  4. Sure. I will share: https://gitlab.com/tymonx/uvm-extensions Benefits: it does one simple thing but very good. It packs and unpacks data without any additional bits very good for any kind of protocols (sequence items) like networking, encap/decap or streaming interfaces like AXI4-Stream or Avalon-ST new packer class inherited from the UVM packer class and extended. The default UVM packer is replaced with UVM factory and uvm_packer::set_default() method new coreservice class inherited from the default UVM coreservice class and extended. The default UVM coreservice i
  5. I will show a real life scenario, not some academic use case that you can find in many UVM cookbooks or tutorial for dummies (like Candy Lovers) which are detached from reality. Lets assume that we have 2 two different protocols and we want to create a new sequence item that will represent a new protocol with header + encapsulate these two protocols inside a payload. Simple usage: byte bytes[]; protocol_c.pack_bytes(bytes); First try: function void protocol_c::do_pack(uvm_packer packer); uvm_object protocols[] = { protocol_a, protocol_b }; //
  6. After that: I agree with @sas73. We need to open source UVM library using GitHub or even better GitLab with Issue Tracker, proper CI/CD setup and unit testing. Accellera should strongly consider that. After spending some time for internal UVM source code review... Now I have many doubts about quality and architecture design decisions.
  7. Sadly, some of these cons are also present in previous UVM releases (like UVM 1.2 before IEEE standardization).
  8. To summarize my topic: Default pack/unpack methods from UVM object don't pack only user data but also additional magic UVM packer state (8 bytes) at the beginning and extra bits in mid when using packer.pack_object() method The packing API is not self-explained and it is very confusing. API user is expecting simple packing/unpacking solution It is against the "Doing One Thing, Well" philosophy. It requires extra effort to simplify it (extend basic classes). Not opposite! The UVM object pack/unpack methods are not thread-safe on default. They are using a single global pa
  9. Hi Justin, Thanks for your detailed answer. I'm very grateful to read that. But still... I'm not happy with the UVM packer implementation, behavior and pack/unpack methods from UVM object. In my modest opinion, the UVM packer and pack/unpack methods had enormous potential, but it was simply wasted by that. The state retrieval should be moved to separate method and/or encapsulate within class (maybe a separate proxy class). Not exposed to user world with user packed bits. This is against proper software architecture design. Class methods and object itself should do one thing but
  10. In my opinion, the internal m_pack() method from the UVM object should be changed to: if (packer == null) begin packer = uvm_packer::get_default().clone(); end To preserve the global configuration and be truly thread safe (separate state per method call).
  11. Also this code is not thread safe. When packer is null, it gets the uvm_packer::get_default() that is a singleton instance... And call methods that changes internal packer states... Only solution is to create a packer object for every pack/unpack calls.
  12. I have found another issue with the original UVM packer. It doesn't initialize internal m_pack_iter and m_unpack_iter iterators! They have undefined values. Only the .flush() method initialize them. How this even pass a code review? Do you have any unit tests for that?
  13. Hi Guys, Current implementation of the UVM packer store some additional contexts information at the beginning of the bitstream (m_bits). A copy of the m_pack_iter and m_unpack_iter members. Exactly 64 bits (8 bytes). During packing or unpacking (un/pack, un/pack_bits/bytes/ints/intlongs) using an UVM object these fields are exposed. It makes these operations useless from user perspective and experience. To pack bits (example from header into bytes of stream), user needs to allocate additional extra magic 8 bytes (reverse engineering) and store some magic values (2x64, again...) at the beg
  14. You must create all necessary SystemC signals, SystemC modules and make connection between them before you run any test in gtest. This require to create own gtest_main.cc implementation. Naturally in SystemC you must put everything in sc_main() function. For this, I would use registry design pattern. First create registry class (registry + factory + singleton). This class will be responsible for storing registered constructors using dynamic allocation with new and smart pointer in lambda expression (see factory::add class). Create all objects using factory::create() method before run
  • Create New...