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

Add packageless intvector examples (#5 a + c) #11

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions vhpidirect/quickstart/intvector/caux.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include <stdio.h>
#define SIZE_ARRAY (sizeof(intArray)/sizeof(int))

int intArray[6];
umarcor marked this conversation as resolved.
Show resolved Hide resolved

int getIntArrSize(){//function acts like a constructor so initialise the variable
umarcor marked this conversation as resolved.
Show resolved Hide resolved
return SIZE_ARRAY;
}

int* getIntArr_ptr(){//function acts like a constructor so initialise the variable
for (int i = 0; i < SIZE_ARRAY; i++)
Copy link
Owner

Choose a reason for hiding this comment

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

I would limit getIntArr_ptr to retrieving the pointer.

Optionally, you can add a main.c where this caux.c is imported and the content of intArray is redefined before calling ghdl_main. This would not replace the caux.c only example. It'd be two subexamples of the same. This would be interesting, because it would be the example where to show why having caux.c, caux.h and main.c makes sense, and how to use them separated or together.

Don't take me wrong: I like the concept of a get function that acts as a generator, because that's the essence of VUnit/vunit#603, and we are kind of blocked. However, I believe that it fits later, not in this example.

Copy link
Author

@radonnachie radonnachie Apr 18, 2020

Choose a reason for hiding this comment

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

So, I didn't stick to such a simple main.c+caux subexample, but I think you may like what I posted. I have not run through the many ways to compile and run the executable, as it is an early example, and we have a dedicated section for that, and the executable asks for user input.

The subexample prompts the user for the array's length, fills the array, and calls ghdl_main. Only thing I don't like is trusting the user to enter a reasonable number, but I cannot seem to break the executable with outrageous values so I think it is safe. Only thing is getting the test to provide runtime stdin input...

Copy link
Owner

Choose a reason for hiding this comment

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

I have not run through the many ways to compile and run the executable, as it is an early example, and we have a dedicated section for that, and the executable asks for user input.

My point was not about different ways to compile and run the executable, but about different requirements dependending on the number of C files.

  • -Wl,main.c or -Wl,caux.c only. Already covered.
  • -Wl,caux.c -Wl,main.c. Not used yet. Questions that users might have:
    • Is it -I./ required?
    • Does caux.h need to exist?

Of course, this can be explained in a different example instead of here.

The subexample prompts the user for the array's length, fills the array, and calls ghdl_main.

I think it would be better to use/parse argv[1]. Three options:

  • If argc == 1, use argv[1] as an integer (atoi).
  • Pase argv and look for --size= or -s. Then use atoi as in the previous point.
  • Search for -- in argv and consider all previous args to be "custom args for C". Then search for --size or -s as in the previous point. Pass args after -- to GHDL. Open question would be: what to do when -- is not found? Are all args for C or for ghdl_main?

Either of these would be interesting because they'd show how to add custom args (that need to be removed from the argv passed to GHDL). I would not use any lib such as optargs, tho. We want to support a single custom argument.

Only thing I don't like is trusting the user to enter a reasonable number, but I cannot seem to break the executable with outrageous values so I think it is safe.

Even if they try to, it's ok. See ghdl/ghdl#822.

Only thing is getting the test to provide runtime stdin input...

I think it is better to pass argv, which allows ./tb 26 or ./tb -s 26 or ./tb --size=26 or ./tb --size 26 -- --wave=mywave.ghw.

{
intArray[i] = 11*(i+1);
}
return intArray;
}
umarcor marked this conversation as resolved.
Show resolved Hide resolved
26 changes: 26 additions & 0 deletions vhpidirect/quickstart/intvector/pkg.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package pkg is
umarcor marked this conversation as resolved.
Show resolved Hide resolved
function c_intArrSize return integer; -- represented C-side with int*
attribute foreign of c_intArrSize : function is "VHPIDIRECT getIntArrSize"; -- getIntArrSize is the C-side function name

type int_arr is array(0 to c_intArrSize-1) of integer;
type int_arr_ptr is access int_arr; -- represented C-side with int*


function c_intArr_ptr return int_arr_ptr;
attribute foreign of c_intArr_ptr : function is "VHPIDIRECT getIntArr_ptr";

shared variable c_intArr : int_arr_ptr := c_intArr_ptr;
end package pkg;

package body pkg is

function c_intArrSize return integer is
begin
assert false report "c_intArrSize VHPI" severity failure;
end c_intArrSize;

function c_intArr_ptr return int_arr_ptr is
begin
assert false report "c_intArr_ptr VHPI" severity failure;
end c_intArr_ptr;
end package body pkg;
14 changes: 14 additions & 0 deletions vhpidirect/quickstart/intvector/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env sh

set -e

cd $(dirname "$0")

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

echo "Build tb (with caux.c) [GHDL]"
ghdl -e -Wl,caux.c tb

echo "Execute tb"
./tb
umarcor marked this conversation as resolved.
Show resolved Hide resolved
38 changes: 38 additions & 0 deletions vhpidirect/quickstart/intvector/tb.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
entity tb is
end entity tb;

architecture RTL of tb is

begin

process
function c_intArrSize return integer is-- represented C-side with int
begin
assert false report "c_intArrSize VHPI" severity failure;
end;
attribute foreign of c_intArrSize : function is "VHPIDIRECT getIntArrSize"; -- getIntArrSize is the C-side function name

type int_arr is array(0 to c_intArrSize-1) of integer;
type int_arr_ptr is access int_arr; -- represented C-side with int*

umarcor marked this conversation as resolved.
Show resolved Hide resolved

function c_intArr_ptr return int_arr_ptr is
begin
assert false report "c_intArr_ptr VHPI" severity failure;
end;
attribute foreign of c_intArr_ptr : function is "VHPIDIRECT getIntArr_ptr";

variable c_intArr : int_arr_ptr := c_intArr_ptr;

begin
report "Array length: " & integer'image(c_intArr.all'length);

for i in 0 to c_intArr.all'right loop
report "c_intArr[" & integer'image(i) &"] = " & integer'image(c_intArr.all(i)) & ". Set to: " & integer'image(-2*c_intArr.all(i));
c_intArr.all(i) := -2*c_intArr.all(i);
end loop;

wait;
end process;

end architecture RTL;