-
Notifications
You must be signed in to change notification settings - Fork 9
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
Various VPI examples #19
base: master
Are you sure you want to change the base?
Conversation
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.
Overall, I think that 6 examples can be extracted from this content, instead of 4. I would propose the following structure:
- quickstart
- hello
- helloworld
- access
- access_hierarchy
- timestep
- list
Please, add these additional examples/tests to CI. To do so, edit .github/workflows/test.yml
and add new items to the task
lists in lines 19 and 66.
See further comments below.
doc/vpi/examples/index.rst
Outdated
@@ -1,4 +1,5 @@ | |||
Examples | |||
######## | |||
|
|||
TBC | |||
See :cosimtree:`VPI examples <vpi>` directory |
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.
As commented in #1, TBC
at the end of doc/index.rst
should be replaced with one or a few notes/tips/hints about minimum knowledge to use VPI. Optionally, that content might be written in doc/vpi/index.rst
and included in the toctree.
Anyway, this file should contain a toctree
(as done in doc/vhpidirect/examples/index.rst
), so that a nice TOC is shown in the sidebar.
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 agree that proper documentation in RST format is necessary. For now, what I can do, is to add a list of examples in rst format. The rest will come later :P
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 wrote a couple of paragraphs in #1 (comment), which you can copy and paste at the end of doc/index.rst
.
The examples cannot be a list. There are two options:
- Each of them can be written in a separte RST file with a header.
- All of them can be written in the same file, using different headers for each of them. See https://raw.githubusercontent.com/ghdl/ghdl-cosim/master/doc/vhpidirect/examples/quickstart.rst.
As long as all the files (one or multiple) are added to the toctree, the TOC in the sidebar will have the same structure regardless of the number of files.
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.
Please see the changes I did yesterday......
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 is really annoying when GitHub shows a subset of changes or an outdated set of changes...
@@ -0,0 +1,14 @@ | |||
## VPI examples |
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 file should be written in RST and located in subdir doc
. The motivation to use RST is that we might want to add labels for cross-referencing these examples. The location is because we are keeping docs separate from code sources.
Moreover, each example should have a header of the appropriate level. This is necessary for the TOC.
In VHPIDIRECT, examples are grouped (Quick start, Arrays, Other projects...). You might want to add all your examples to a section named "Quick Start", to use/create some other section, or to not create any section yet.
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 am ok with this. However, I just did a similar thing as in ./systemc/README.md
. If you think it is unnecessary I will remove that, but having a small overview of the folder is helpful for people that just want to explore the repo without directly using the documentation. See https://github.com/bellaz89/ghdl-cosim/tree/master/vpi
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.
Oh, the existence of ./systemc/README.md
is a kind of "artifact". Repo https://github.com/ghdl/ghdl-systemc-fosdem15 was created some weeks ago, due to a user's demand. The name was not correct, and it was renamed to https://github.com/ghdl/ghdl-systemc-fosdem16 a few days later. Then, we discussed about widening the scope to "co-simulation", and this repo was forked from there. We considered to rename the other once again, but we thought it would be too much trouble. Nonetheless, the content of the "old" repo was moved to subdir ./systemc
and the README remains. The plan is to add it to the docs (as other examples), once we guess how to make it fit.
If you think it is unnecessary I will remove that, but having a small overview of the folder is helpful for people that just want to explore the repo without directly using the documentation.
Honestly, I had not thought about it, but it sounds as a good idea! From this point of view:
The docs need not to link this file, but headers should link to the corresponding subdirs.- This file should contain one or multiple links to the docs, where these very brief descriptions are extended.
- Do we want a single
vpi/README.md
? Two (vpi/quickstart/README.md
andvpi/list/README.md
)? Or all of them?
vpi/README.md
Outdated
|
||
The directory contains some VPI usage examples: | ||
|
||
1. [helloworld](./helloworld/) minimal VPI code example that runs a simulation, prints a message and exits. |
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.
Explanations need to be a little more verbose. As a rule of thumb, the first paragraph in each example explains why the example is relevant (why we decided to add it). Second and further paragraphs explain what is implemented in the example and which files/functions/features are used.
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.
See above: this is repository documentation. The full documentation in rst format will come with successive PRs
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.
Ref #19 (comment).
3. [list](./list/) example on signal hierarchy iteration using `vpi_iterate`and `vpi_scan`. | ||
4. [timestep](./timestep/) shows how to run a simulation for an arbitrary number of timesteps. | ||
|
||
to run a test, just go in the directory and execute |
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 comment applies to all the examples in this repo. It would better fit either as an admonition in the main page, or in the README.
It can be a separate PR.
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 should go in the main README, along with an explanation about "groups of examples" (see #19 (comment)).
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.
Now included in #21.
vpi/access/vpi.c
Outdated
|
||
val.format = vpiBinStrVal; | ||
val.value.str = "0101"; | ||
printf("set %s in tb.nibble1 \n", val.value.str); |
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 that there are two main differences between the vpi.c
sources of helloworld
and access
:
- In
access
the values of some signals are written/read. - In
access
the signals are not in the top-level entity, but in an instance.
Hence, I think that two access
examples should exist. Each showing one of the new features. Of course, both can share sources. It seems that #define hdl_prefix tb.
can be added and overwritten when calling GHDL/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.
I am ok in splitting the tests, or if you prefer, I can just make a simple tb.vhd that do not use ent.vhd to just demonstrate how to read/write signals. Or are you referring to the top module ports??
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.
See #19 (comment).
Or are you referring to the top module ports??
I mean that the same C source can be used to first inspect ent
directly (no testbench, no hierarchy) and then inspect tb/ent
(with testbench, with hierarchy).
- In the first case,
ent.vhd
andvpi_access.c
are required, and-Dhdl_prefix="ent"
. - For the second case,
ent.vhd
,tb.vhd
andvpi_access.c
are required, and-Dhdl_prefix="tb.ent"
.
The purpose of this pair of examples is to show that the access logic is the same, regardless of using hierarchical names or not.
@@ -0,0 +1,20 @@ | |||
#!/usr/bin/env sh |
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.
See comment about duplicated files above.
@@ -0,0 +1,39 @@ | |||
library ieee; |
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.
See comment about duplicated files above.
@@ -0,0 +1,71 @@ | |||
#include <vpi_user.h> |
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 that all VHDL sources are the same for all the examples. Do you think that it can be a common pattern for all VPI examples? Or do you expect other features to require different VHDL sources?
I ask it because it seems that the 4-7 examples that are part of this PR differ on the vpi.c
file and the compilation commands only.
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 thing is that to demonstrate very basic usage of VPI, the VHDL component under test do not matter so much. So, for helloworld I can, for example, just put a complete void top module without any signals, because at the end the VPI code is interacting with the simulator but not with the simulation. If you think it is better, I can try to make the ent.vhd and tb.vhd even more concise in each test.
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. In VHPIDIRECT examples, many C sources are common but VHDL sources need to be different. Here, as you said, VHDL sources are almost irrelevant (as long as they contain the minimum features that we want to test). Hence, instead of making ent.vhd
and tb.vhd
more concise in each test, I would suggest to make them general enough so that they can used in any VPI example (last structure in #19 (comment)). If some example in the future requires some weird feature in VHDL, we will consider adding different VHDL sources to the corresponding subdir. But, for now, it seems unnecessary.
@umarcor In the meanwhile, I tried to implement a part of your suggestions. |
I don't understand why I cannot reply to some of the previous (outdated) comments, but I can reply to some other. Hence, I think that the review and this comment might be a little messy. Hope we can understand each other...
The structure that we are following is that each new file that is added to the repo, is required for a reason. If two examples use a source which is almost the same except for a line or a few lines, we consider whether it can be shared by adding some parameter. Should doing so involve too much complexity, it is ok to duplicate very similar files.
We need to balance complexity and verbosity. On the one hand, we want intermediate and advanced users to pick any isolated example and run/use it directly. On the other hand, we want unexperienced users which are reading the docs in order (as a tutorial), not to be continuously diffing many files that look similar and which might or might not be the same. We are currently handling this as subsections (groups of examples). So, in this PR the "atomic unit" is |
PLI_INT32 reason, | ||
int64_t cycles){ | ||
|
||
s_cb_data cbData; |
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 that this deserves a reference/cite, either here or in the docs. Where should users search for the definition of s_cb_data
? In vpi_user.h
? The standard? Some book?
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.
Now explained in #21.
|
||
begin | ||
|
||
ent_0: entity work.ent |
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 feels not to be valid VHDL. Is it on purpose?
Anyway, correct or purposely incorrect, I'd suggest to use a for generate
instead:
i_ent: for I in 0 to 3 generate
w_ent: entity work.ent
port map (nibble1 => nibble1,
nibble2 => nibble2,
sum => sum,
carry_out => carry_out);
end generate;
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 script is running, the CI completes without any error, and GHDL doesn't pop out even a Warning. Therefore I think it is valid VHDL.
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.
Surprising... I would expect sum
and carry_out
to collide, since four different drivers are connected to the same signal. I simulated it and, when one of the instances drives a different value, sum
and/or carry_out
are X
. @tgingold, should this produce a warning?
Anyway, I think we should build a proper adder chain to sum two 4*4=16bit numbers.
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.
Ok, now I see that you were talking about a multiple-driving issue. I agree that it is strange that GHDL doesn't catch it and I will fix that. Please could you be a bit more descriptive and giving the code lines where the problem is next time?
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.
Please could you be a bit more descriptive and giving the code lines where the problem is next time?
Sure! Sorry about it. I was convinced that you had done it on purpose, because you only wanted to explore the hierarchy without caring about the content.
I will take care of fixing this source if you want; so you can focus on VPI-specific issues which I'm less comfortable with.
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.
Equivalent source included in #21.
cbData.user_data = 0; | ||
cbData.value = 0; | ||
|
||
// the callback is executed after a delay of 0 |
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.
From my ignorance, it seems that these lines (35-37) are optional. That is, the first example would also work with cbData.time = NULL
(as per the common header above). However, I'm afraid that cbData.time = NULL
and cbData.reason = cbAfterDelay
might produce either a crash or weird behaviour.
Hence, I think that we should have three "hello" examples:
begin
/hello
: same asbegin_end
but withoutcommon_vpi.h
, or same ashelloworld
but withoutsimuTime
.helloworld
begin_end
Anyway, we can move forward and I will take care of adding begin
/hello
after this PR is merged.
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.
Example hello
is now included in #21.
* VPI. This is accomplished registering a chain of callbacks. | ||
*/ | ||
|
||
// register a cbAfterDelay callback that executes delay_ro_cb after 1 timestep |
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 that some discussion/explanation is required about why four different callbacks are used. Why do we need to register cbReadOnlySynch
if cbReadWriteSynch
is going to be executed in the same chain anyway?
Hi, I think that I won't work anymore on this PR. Either because I don't believe that, given the scope of the PR, implementing more changes will lead to any quality improvement, and (more important) because I don't have more time to spend on this. So, take it as it is and do what you want with the PR. You can merge it and do the changes you prefer later, you can reject it or you can make it as a pending PR indefinitely. I am fine with whatever decision you will take. |
In this PR four VPI usage examples are added.
VPI examples
The directory contains some VPI usage examples:
vpi_put_value
andvpi_get_value
.vpi_iterate
andvpi_scan
.to run a test, just go in an example directory and execute