Skip to content

Proposal for a more comprehensive approach to VUnit co-simulation #603

Open
@bradleyharden

Description

@bradleyharden

@LarsAsplund, @kraiger and @umarcor,

I would like to propose a broad strategy for co-simulation with VUnit. I really like what @umarcor has been working on, but I think his approach leaves most of the implementation to users. If I understand #568 correctly, users have to manually synchronize between VHDL and C/Python using clock signals run through a string_ptr. That approach is extremely powerful and flexible, but to me, it doesn't seem very easy to use or approachable for new users.

So far, I've found VUnit to be extremely easy to learn and use, because the VHDL libraries abstract away many of the low-level details. I never even knew string_ptr_pkg existed until I started reading the VUnit codebase out of interest. However, even with simple, easy-to-use libraries, I have struggled to convince my co-workers to learn and use VUnit. I fear it will be even harder to convince them to use VUnit for co-simulation if they have to implement most of the low-level details.

Based on the work I've already done for #521 and #522, and the discussion in #583, I would like to propose a more comprehensive approach to co-simulation. Essentially, I would like to communicate with C/Python code in the same way that I currently communicate with concurrent actors in VHDL, using messages and queues. I think this approach will require more work than what @umarcor has proposed, but I think the end result will be much more user-friendly. Furthermore, there is a lot of overlap between this proposal and my work on #521 and #522.

To support my proposal, I spent some time this past week prototyping various pieces. Here is an overview of a roadmap, as I see it:

  1. Implement ext_ptr.c and ext_ptr_pkg - Mostly complete

This library is essentially a port of string_ptr_pkg and integer_vector_ptr_pkg to C. It serves the same purpose in C as those packages do in VHDL. It is only responsible for providing shared memory among concurrent actors. It is not used for synchronizing between actors. I already have a complete, working implementation, with tests, here.

  1. Modify string_ptr_pkg and integer_vector_ptr_pkg to cast to and from ext_ptr_t - Trivial

This change would make it possible to create instances of string_ptr and integer_vector_ptr in VHDL that are stored externally. This is the infrastructure for implementing external queues. Because ext_ptr_pkg and ext_ptr.c mimic the structure of the two VHDL ptr packages, adding this would be trivial.

  1. Update queue_pkg to push and pop instances of string_ptr rather than character, so that you can push and pop whole items - Complete

This approach is faster than the current implementation, and it is more useful, because the queue length now tells you how many items are left in the queue. #522 is a working and tested implementation. Performance comparisons are available in #521.

  1. Add external queues - Straight forward

Modify queue_pkg to accept an external option. For a given queue, if external is true, the queue would create external rather than internal instances of string_ptr, and it would push and pop using a C library, ext_queue.c.

  1. Modify the codec libraries to encode all VHDL types in a binary compatible manner - Mostly complete

With this change, any VHDL type encoded into an external string_ptr could be read directly by C code, without any decoding step. I have already done this while working on my changes for #521. I can make this code available, if you would like to see what I've done.

  1. Generalize the VUnit type system to make it modular and extensible - Mostly complete

This has two benefits. For co-simulation, it will set the stage for pushing and poping any VHDL type from external queues. More generally, it will allow us to create new VUnit data structures, like list_t. It will also make it easy to extend the existing dict_t to all types. The latter were my initial objectives in #521. As above, I have already implemented most of this. I just haven't made it public yet.

  1. Extend the type definitions from VHDL to C. - No progress yet

As stated above, a generic type system can be easily extended to C, which will allow users to easily read and write VHDL types encoded by VUnit. This is the last step needed for a full implementation of external queues.

  1. Extend the com library from VHDL to C - Prototyping complete

This is the final piece that brings the whole proposal together. With this change, we can treat external actors like any other VUnit actor. All synchronization between VHDL and C/Python can be handled with messages. I have already prototyped the actor_t, actor_item_t, msg_t, envelope_t and mailbox_t data structures in C. With them, I demonstrated that you can add external actors, find them in VHDL, and push/pop messages (see here).

To send a message to an external actor, you simply have to create an external message that uses an external queue to store its data. The actual synchronization happens when calling the com function notify. When this function is called, it would call an ext_com.c function that would run a list of C functions specified by users. These C functions would essentially act as concurrent processes do in VHDL. When run, they would check for new messages and act accordingly.

What do you think? Do you agree that this approach would be easier for users? I'm eager to work on this, but I don't want to devote more effort without buy-in from you three.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions