-
Notifications
You must be signed in to change notification settings - Fork 263
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
VHDL-embedded Python code #986
base: master
Are you sure you want to change the base?
Conversation
Very interesting. This is like cocotb in reverse. 😆 |
@joshrsmith Yes, it is reversed in the sense that the simulation is driven from VHDL rather than from Python. The reason is that we want to use VHDL for what is good for and only use Python when VHDL runs out of steam. Doing pin-wiggling from Python is a bit inefficient and that is not a price I want to pay for getting access to the areas where Python is a good fit. |
Great effort, this certainly opens up a lot of possibilities! I'm still really interested in communication between python and VHDL with messages. |
@javValverde Yes, that will be step 2. I thought I should start with something simpler to find all the different quirks in VHPI, FLI, and the others. I also got FLI working so now the same examples can be run with no modification under Questa. Will do some refactoring before pushing that. |
@LarsAsplund Not sure if you are aware, but Questa also supports VHPI since about two years. |
@cmarqu Yes, I discovered that after I started with FLI. It was a bit hidden. However, very few VHPI functions are supported so currently it is not possible to use it for our purposes. |
c33ee57
to
958b275
Compare
This looks so nice :D |
25dcd0e
to
90056c9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The master branch of NVC now has some very basic support for VHPI foreign sub-programs. There's some examples here:
test/regress/vhpi14.vhd
test/vhpi/vhpi14.c
Although at the moment I don't support Aldec's format for the foreign
attribute.
|
||
for c_file_path in c_file_paths: | ||
args = [ | ||
"gcc", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs -fPIC
too on Linux.
if (vhpi_get_value(parameter_handle, ¶meter)) { | ||
ffi_error_handler("getting VHDL parameter value", true); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this needs a call to vhpi_release_handle(parameter_handle)
here or a it leaks a handle on each invocation.
procedure python_setup; | ||
-- TODO: Looks like Riviera-PRO requires the path to the shared library to be fixed at compile time | ||
-- and that may become a bit limited. VHDL standard allow for expressions. | ||
attribute foreign of python_setup : procedure is "VHPI libraries/python; python_setup"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does "VHPI python python_setup"
work? ("python" here is the libraryName
argument passed to vhpi_register_foreignf()
.) I think passing the path to the native library here and the semicolon separator is an Aldec extension that's not present in the VHDL LRM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The semicolon is something I took from Aldec's examples. However, it works well without it so I will have it removed.
It seems like just python
should be enough to identify the shared library if I put the libraries
directory in the PATH
environment variable. Are you also using that approach to for finding the libraries?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw, what would be the benefits of using VHPI over VHPIDIRECT in this case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like just python should be enough to identify the shared library if I put the libraries directory in the PATH environment variable. Are you also using that approach to for finding the libraries?
No, I'm rely on the user loading the library explicitly with --load
and then the "VHPI libraryName modelName" should match the corresponding libraryName
and modelName
arguments passed to vhpi_register_foreignf()
. I'm actually having a hard time understanding how the LRM intended these to be used. Does Aldec treat the first libraryName
as the path to the shared library?
Btw, what would be the benefits of using VHPI over VHPIDIRECT in this case?
Honestly probably not many benefits. In theory if every simulator implemented the VHPI standard you'd only need one backend here rather than one per simulator.
@LarsAsplund , Thanks for your efforts, this looks like a really powerful addition to the VUnit ecosystem. I look forward to this PR making it into the main branch and a release. I've had a hack at We're quite interested is using something like this to build python based predictors of our signal processing in the Square Kilometre Array Telescope Correlator and Beamformer. |
@willkamp Do you have any details on the hacks you had to do? |
This PR contains work toward enabling embedded Python code within VHDL
For the first iteration I've focused on providing the lowest possible threshold for embedded Python and I found that to be the "eval and exec model" where the user can create any valid Python string and have that evaluated as an expression or executed as code by a Python interpreter.
The main limitation to what can be done is basically that variables passed between Python and VHDL must have a type that can be represented in both domains. For the first set of examples I also limited myself to a small set of scalar and vector/list types. Supporting remaining types is just more of the same and will be added as I move along.
Simplicity also means:
Riviera-PRO and Active-HDL use VHPI but it is important that the user interfaces do not leak VHPI specific stuff. The same API should be possible to use on all simulators regardless of what foreign language interface being used in the background
So far I've only worked on VHPI and on Windows.
Some work has also been done on running the Python code in separate process(es) (as in separate applications). Rather than passing code strings, the VHDL code would communicate with the concurrent Python actors using message passing or simple data queues. This work will be completed in a second iteration and in a separate PR. The goal of that use model is more towards performance.
Feedback on the eval and exec model is appreciated and a good starting point is to review the provided example tests. If you have an Riviera-PRO or Active-HDL license you can run the examples. If not, you should get a good feel for the concepts by just looking at the example code.
I would also appreciate more use case examples. So far I have these (note that some are expected to fail)
For you who don't have any of the currently supported simulators, here is a screenshot of what the user interactions provided by some tests may look like. I use PySimpleGUI which creates these types of interactions from one-liners
Currently tested simulators
Riviera-PRO
Active-HDL
Questa
nvc
GHDL