Skip to content
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

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@
*.lst
*.o
*.so
*.vpi
ent
tb
bellaz89 marked this conversation as resolved.
Show resolved Hide resolved
3 changes: 2 additions & 1 deletion doc/vpi/examples/index.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Examples
########

TBC
See :cosimtree:`VPI examples <vpi>` directory
Copy link
Member

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.

Copy link
Author

@bellaz89 bellaz89 Apr 30, 2020

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

Copy link
Member

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:

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.

Copy link
Author

@bellaz89 bellaz89 Apr 30, 2020

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......

Copy link
Member

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...


14 changes: 14 additions & 0 deletions vpi/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
## VPI examples
Copy link
Member

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.

Copy link
Author

@bellaz89 bellaz89 Apr 30, 2020

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

Copy link
Member

@umarcor umarcor Apr 30, 2020

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 and vpi/list/README.md)? Or all of them?


The directory contains some VPI usage examples:

1. [helloworld](./helloworld/) minimal VPI code example that runs a simulation, prints a message and exits.
Copy link
Member

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.

Copy link
Author

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

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2. [access](./access/) signal read/write example on an adder component using `vpi_put_value` and `vpi_get_value`.
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
Copy link
Member

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.

Copy link
Member

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)).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now included in #21.

```bash
sh run.sh
```

24 changes: 24 additions & 0 deletions vpi/access/ent.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

-- ent is a 4 bit adder

entity ent is
port(nibble1, nibble2 : in unsigned(3 downto 0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, make it parametric (add a generic to define the word-length).

Copy link
Author

@bellaz89 bellaz89 Apr 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, but is this really helpful to make the example easy to understand from people with basic knowledge? I can change it but adding a generic just adds unnecessary information and details for the purpose of the example.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As commented in #1 (comment), we target people with basic knowledge about using GHDL and VPI at the same time. But we expect users to know VHDL and VPI, or we provide them the references to go and learn.

Apart from that, the purpose of this examples is to learn. An important part of learning a new technology is being able to play with it. Hence, we are ok with using features which add very little complexity from VHDL's perspective, and which make it easier for users to play with this, our toy. Think e.g. of a user that wants to test what would happen with signals which are larger than 32 or 64 bits.
The question might or might not make sense, but in any case we don't want him/her to stop doing it because of how cumbersome it is to find and change hardcoded values.

From this point of view, a generic or a constant can be used, but it is general bad practice (in any language) to hardcode sizes. Of course, I don't mean to criticize your coding; just to draw the limit for oversimplification.

sum : out unsigned(3 downto 0);
carry_out : out std_logic);

end entity ent;

architecture behavioral of ent is

signal temp : unsigned(4 downto 0);

begin

temp <= ("0" & nibble1) + nibble2;
sum <= temp(3 downto 0);
carry_out <= temp(4);

end architecture behavioral;
20 changes: 20 additions & 0 deletions vpi/access/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env sh

set -e

cd "$(dirname $0)"

echo "Analyze ent.vhd and tb.vhd"
ghdl -a ent.vhd tb.vhd

echo "Elaborate tb"
ghdl -e tb

echo "Compile vpi.c"
ghdl --vpi-compile gcc -c vpi.c -I./../common/ -o vpi.o

echo "Link vpi.o"
ghdl --vpi-link gcc vpi.o -o vpi.vpi

echo "Execute tb"
ghdl -r tb --vpi=./vpi.vpi
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to pass multiple *.vpi arguments? Or do all VPI features need to be built into a single module?

Copy link
Author

@bellaz89 bellaz89 Apr 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The answer is I don't know. Probably @tgingold or @eine knows XD.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will ask.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently you can pass only one --vpi= option. Well, only the last one is kept. But handling more than one shouldn't be a difficult change.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

39 changes: 39 additions & 0 deletions vpi/access/tb.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity tb is
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, make the testbench parametric or define the word-length as a constant.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above.

end tb;

architecture behavioral of tb is
component ent
port(nibble1, nibble2 : in unsigned(3 downto 0);
sum : out unsigned(3 downto 0);
carry_out : out std_logic);

end component ent;

for ent_0: ent use entity work.ent;

signal nibble1, nibble2, sum : unsigned(3 downto 0);
signal carry_out : std_logic;

begin

ent_0: ent port map (nibble1 => nibble1,
bellaz89 marked this conversation as resolved.
Show resolved Hide resolved
nibble2 => nibble2,
sum => sum,
carry_out => carry_out);

process

begin

wait for 10 ns;
wait;

end process;

end architecture behavioral;


47 changes: 47 additions & 0 deletions vpi/access/vpi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include <vpi_user.h>
#include <stdio.h>
#include "common_vpi.h"

PLI_INT32 start_cb(p_cb_data data){
(void) data;
s_vpi_value val;

printf("Start of simulation \n");

val.format = vpiBinStrVal;
val.value.str = "0101";
printf("set %s in tb.nibble1 \n", val.value.str);
Copy link
Member

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.

Copy link
Author

@bellaz89 bellaz89 Apr 30, 2020

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??

Copy link
Member

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 and vpi_access.c are required, and -Dhdl_prefix="ent".
  • For the second case, ent.vhd, tb.vhd and vpi_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.

vpiHandle nibble1 = vpi_handle_by_name("tb.nibble1", NULL);
vpi_put_value(nibble1, &val, NULL, vpiNoDelay);

val.value.str = "0011";
printf("set %s in tb.nibble2 \n", val.value.str);
vpiHandle nibble2 = vpi_handle_by_name("tb.nibble2", NULL);
vpi_put_value(nibble2, &val, NULL, vpiNoDelay);

return 0;
}

PLI_INT32 end_cb(p_cb_data data){
(void) data;
s_vpi_value val;

val.format = vpiBinStrVal;
vpiHandle sum = vpi_handle_by_name("tb.sum", NULL);
vpi_get_value(sum, &val);
printf("get %s from tb.sum \n", val.value.str);

printf("End of simulation \n");

return 0;
}

void entry_point_cb() {
register_cb(start_cb, cbStartOfSimulation, -1);
register_cb(end_cb, cbEndOfSimulation, -1);
}

void (*vlog_startup_routines[]) () = {
entry_point_cb,
0
};
27 changes: 27 additions & 0 deletions vpi/common/common_vpi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#pragma once
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is the only common file for now, I think that subdir common is not required. I'd move it to vpi/common.h. How common is it? Is it expected to be used by examples other than yours? Would it make sense to have it upstreamed to vpi_user.h (or added to GHDL codebase)?

Anyway, please name it *.c and add a matching ^.h.

Copy link
Author

@bellaz89 bellaz89 Apr 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

common_vpi.h contains a single function that helps the user to register VPI callbacks and it is used in all the VPI examples. I separated it so the VPI plugin sources are not bloated with callback registering code.

I can put it out of common. I don't think that it can be added to vpi_user.h since vpi_user.h should contain only VPI calls/definitions that are defined by the IEEE PLI 2.0 standard. I don't know what is the GHDL policy about including such kind of code. So I cannot give any opinion on that :P Sorry.

It can be put in a different compilation unit, but since it contains only a very simple function, I do not see any benefit in doing it from a clarity point of view.
Moreover, since this repo uses shell scripts and not makefiles to generate and execute the examples, the function gets recompiled anyways in each example.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's keep it as vpi/common.c and vpi/common.h for now, and I'll ask Tristan about providing a vpi_user_ghdl.h.

#include <inttypes.h>
#include <vpi_user.h>

void register_cb(PLI_INT32(*f)(p_cb_data),
PLI_INT32 reason,
int64_t cycles){

s_cb_data cbData;
s_vpi_time simuTime;
if (cycles < 0){
cbData.time = NULL;
} else {
cbData.time = &simuTime;
simuTime.type = vpiSimTime;
simuTime.high = (PLI_INT32) (cycles >> 32);
simuTime.low = (PLI_INT32) (cycles & 0xFFFFFFFF);
}

cbData.reason = reason;
cbData.cb_rtn = f;
cbData.user_data = 0;
cbData.value = 0;

vpi_register_cb(&cbData);
}

24 changes: 24 additions & 0 deletions vpi/helloworld/ent.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

-- ent is a 4 bit adder

entity ent is
port(nibble1, nibble2 : in unsigned(3 downto 0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this source is exactly the same as vpi/access/ent.vhd, do not add both of them. Make access be a case of helloworld and reuse all the common sources.

Copy link
Author

@bellaz89 bellaz89 Apr 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, do you suggest to put every common vhd file in the same directory?
Even if some examples contain similar or same code, I would not recommend moving them out of the particular example folder to limit the necessity to look around to the minimum (and IMHO it is very important in a documentation project). I know that common_vpi.h in this sense is an (the only) exception. We can discuss that :) .

I didn't get what you say when you write

Make access be a case of helloworld

Since they are two distinct examples I wouldn't recommend mixing them together.

BTW now VHDL sources are a bit different from example to example, so the need to put everything in the same places doesn't apply so much anymore.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both are subexamples of "quickstart":

  • vpi/quickstart/
    • ent.vhd
    • tb.vhd
    • vpi_hello.c
    • vpi_helloworld.c
    • vpi_access.c
    • vpi_access_hierarchy.c
    • vpi_timestep.c

Or, to make the distinction more clear:

  • vpi/quickstart/
    • ent.vhd
    • vpi_hello.c
    • vpi_helloworld.c
    • vpi_timestep.c
    • access/
      • tb.vhd
      • vpi_access.c
      • vpi_access_hierarchy.c

Moreover, if the entity and testbench will be shared with other examples:

  • vpi/
    • ent.vhd
    • tb.vhd
    • quickstart/
      • vpi_hello.c
      • vpi_helloworld.c
      • vpi_timestep.c
      • access/
        • vpi_access.c
        • vpi_access_hierarchy.c

The point is that 5 examples exist in the docs, independently of which of these structures is used for the sources.

It is easier to understand for new users that they need to focus on different *.c files only, because the "already know" the content of others. Intermediate/advanced users can quickly cherry-pick the subset of files they need. They are not going to reuse the provided run.sh anyway.

sum : out unsigned(3 downto 0);
carry_out : out std_logic);

end entity ent;

architecture behavioral of ent is

signal temp : unsigned(4 downto 0);

begin

temp <= ("0" & nibble1) + nibble2;
sum <= temp(3 downto 0);
carry_out <= temp(4);

end architecture behavioral;
20 changes: 20 additions & 0 deletions vpi/helloworld/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env sh

set -e
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If multiple examples share most of the sources and some steps in this script can be shared, please build and execute all the examples in the same script.

Copy link
Author

@bellaz89 bellaz89 Apr 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, give an example to do this in a proper way.
Also, in this way the user loses the ability to compile/run a single test, so I discourage this solution. For code examples IMHO it is more important self-containment rather than code reuse.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See, for example, https://github.com/ghdl/ghdl-cosim/tree/master/vhpidirect/quickstart/sharedvar or https://github.com/ghdl/ghdl-cosim/tree/master/vhpidirect/arrays/intvector.

Overall, the docs define which examples exist and how they are named. Sources might or might not match the structure.

Copy link
Member

@umarcor umarcor Apr 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, in this way the user loses the ability to compile/run a single test, so I discourage this solution.

In the future, we would like to use some other mechanism to allow running single tests, while keeping shared steps in a common source (not duplicated). For now, we prioritize avoiding duplication over execution granularity.

Some options to handle testing better are makefiles or VUnit, but we have not given a thought to it yet. Whatever solution we use, we should be able to export nice and short bash scripts, so that users don't need to understand the complexity of the test runner.


cd "$(dirname $0)"

echo "Analyze ent.vhd"
ghdl -a ent.vhd

echo "Elaborate tb"
ghdl -e ent

echo "Compile vpi.c"
ghdl --vpi-compile gcc -c vpi.c -I./../common/ -o vpi.o

echo "Link vpi.o"
ghdl --vpi-link gcc vpi.o -o vpi.vpi

echo "Execute ent"
ghdl -r ent --vpi=./vpi.vpi
34 changes: 34 additions & 0 deletions vpi/helloworld/vpi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include <vpi_user.h>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that this example fits as "how to do nothing other than building and running a simulation with an VPI module" (#1 (comment)). Thanks a lot for adding it!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are welcome :D

#include <stdio.h>
#include "common_vpi.h"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, this very first example would not require any header other than vpi_user.h. Is it possible to add a simpler version of register_cb here?

Copy link
Author

@bellaz89 bellaz89 Apr 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep! Are you fine if I just register the cbAfterDelay callback?

Copy link
Member

@umarcor umarcor May 1, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's up to you. I feel that registering a printf at start or finish is easier to understand as the very first contact than AfterDelay. From my ignorance, I would ask myself "a delay after what?", which would deviate me from the purpose of the example. However, if the explanation/introduction of the example clarifies it. For example:

VPI allows to register callbacks at multiple events. In this example, a callback is set with a delay of N cycles/ms after whatever, but the same procedure can be applied to cbStartOfSimulation or cbEndOfSimulation. See REFERENCE for a complete list of available callback names/identifiers.


  • Is there anything that makes delay_ro_cb signifficantly different from start_cb?
  • Is the last argument to register_cb required only to pass the delay?


PLI_INT32 start_cb(p_cb_data data){
(void) data;
printf("Start of simulation \n");
return 0;
}

PLI_INT32 delay_ro_cb(p_cb_data data){
(void) data;
printf("Hello world! \n");
vpi_control(vpiFinish, 0);
return 0;
}

PLI_INT32 end_cb(p_cb_data data){
(void) data;
printf("End of simulation \n");
return 0;
}


void entry_point_cb() {
register_cb(start_cb, cbStartOfSimulation, -1);
register_cb(end_cb, cbEndOfSimulation, -1);
register_cb(delay_ro_cb, cbAfterDelay, 0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this callback, which seems to be the one that requires a non-trivial register_cb, should not be part of the very first example. Hence, I believe that helloworld can be split in two: hello and helloworld.

Copy link
Author

@bellaz89 bellaz89 Apr 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I changed helloworld and added the example beginend which should be equivalent to what you said and shows how to register callbacks that runs at the beginning/end of a simulation.

}

void (*vlog_startup_routines[]) () = {
entry_point_cb,
0
};
24 changes: 24 additions & 0 deletions vpi/list/ent.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
library ieee;
Copy link
Member

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.

use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

-- ent is a 4 bit adder

entity ent is
port(nibble1, nibble2 : in unsigned(3 downto 0);
sum : out unsigned(3 downto 0);
carry_out : out std_logic);

end entity ent;

architecture behavioral of ent is

signal temp : unsigned(4 downto 0);

begin

temp <= ("0" & nibble1) + nibble2;
sum <= temp(3 downto 0);
carry_out <= temp(4);

end architecture behavioral;
20 changes: 20 additions & 0 deletions vpi/list/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env sh
Copy link
Member

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.


set -e

cd "$(dirname $0)"

echo "Analyze ent.vhd and tb.vhd"
ghdl -a ent.vhd tb.vhd

echo "Elaborate tb"
ghdl -e tb

echo "Compile vpi.c"
ghdl --vpi-compile gcc -c vpi.c -I./../common/ -o vpi.o

echo "Link vpi.o"
ghdl --vpi-link gcc vpi.o -o vpi.vpi

echo "Execute tb"
ghdl -r tb --vpi=./vpi.vpi
39 changes: 39 additions & 0 deletions vpi/list/tb.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
library ieee;
Copy link
Member

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.

use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity tb is
end tb;

architecture behavioral of tb is
component ent
port(nibble1, nibble2 : in unsigned(3 downto 0);
sum : out unsigned(3 downto 0);
carry_out : out std_logic);

end component ent;

for ent_0: ent use entity work.ent;

signal nibble1, nibble2, sum : unsigned(3 downto 0);
signal carry_out : std_logic;

begin

ent_0: ent port map (nibble1 => nibble1,
nibble2 => nibble2,
sum => sum,
carry_out => carry_out);

process

begin

wait for 10 ns;
wait;

end process;

end architecture behavioral;


Loading