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

quickstart/logicvector example (Bounded) #6

Closed
wants to merge 28 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
22b3d72
initial logic vector example
Apr 13, 2020
8cc6d3a
Done u/logic array example: todo use logic_vector
Apr 13, 2020
5aac200
Use std_(u)logic_vectors: ghdl/ghdl/issues/1224
Apr 13, 2020
5ef361f
Move to quickstart
Apr 14, 2020
e1e7e39
Simplify quickstart/logicvectors
Apr 14, 2020
ad9d3f7
Revision 2: 2 vecs, cleaned vhdl, #defined sizes
Apr 15, 2020
b2c8317
Bounded 2D array working
Apr 15, 2020
47cd823
Remove 2D array_C
Apr 15, 2020
35e07dd
Whitespace rules
Apr 16, 2020
6c376bc
Switch getVectorSize()
Apr 17, 2020
cf7c17b
Swap names HDL_LOGIC_STATE/CHAR
Apr 17, 2020
dd8f83e
caux
Apr 17, 2020
e821c8e
Logic Vector documentation
Apr 17, 2020
b67c73e
Merge branch 'master' into logicVectors
radonnachie Apr 17, 2020
a1f29bc
caux.c
Apr 17, 2020
2110723
Add to windows test
radonnachie Apr 17, 2020
386470b
Doc Rev1
radonnachie Apr 17, 2020
b537f2b
Missing 'the'
radonnachie Apr 17, 2020
95a760d
vhpidirect: add 'quickstart/package'
radonnachie Apr 17, 2020
276affa
Merge branch 'master' into logicVectors
radonnachie Apr 18, 2020
effe73d
Update VHDL Boolean parsing In C
radonnachie Apr 18, 2020
c7a3df1
Move to arrays, including documentation
radonnachie Apr 18, 2020
5adf1cc
Doc Rev
radonnachie Apr 18, 2020
60f8e85
Illustrative purposes
radonnachie Apr 18, 2020
54746cc
Doc Rev2
radonnachie Apr 19, 2020
7ddd6fa
Merge branch 'master' into logicVectors
radonnachie Apr 19, 2020
f77ad0d
Fix example details order
radonnachie Apr 19, 2020
316da8d
Merge branch 'logicVectors' of https://github.com/RocketRoss/ghdl-cos…
radonnachie Apr 19, 2020
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
2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ jobs:
vhpidirect/shared/shlib,
vhpidirect/shared/dlopen,
vhpidirect/shared/shghdl,
vhpidirect/arrays/logicvector,
]
runs-on: ubuntu-latest
env:
Expand Down Expand Up @@ -55,6 +56,7 @@ jobs:
vhpidirect/shared/shlib,
#vhpidirect/shared/dlopen, ! dlfcn.h is not available on win
#vhpidirect/shared/shghdl, ! dlfcn.h is not available on win
vhpidirect/arrays/logicvector,
]
runs-on: windows-latest
env:
Expand Down
58 changes: 58 additions & 0 deletions doc/vhpidirect/examples/arrays.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
.. program:: ghdl
.. _COSIM:VHPIDIRECT:Examples:arrays:

Arrays
######

.. _COSIM:VHPIDIRECT:Examples:arrays:logicvectors:

:cosimtree:`logicvector <vhpidirect/arrays/logicvector>`
**************************************************************

Commonly signals in VHDL are of a logic type or a vector thereof (``std_logic`` and ``std_logic_vector``), coming from IEEE's ``std_logic_1164`` package.
These types can hold values other than high and low (``1`` and ``0``) and are enumerated as:

0. 'U'
1. 'X'
2. '0'
3. '1'
4. 'Z'
5. 'W'
6. 'L'
7. 'H'
8. '-'

As mentioned in :ref:`Restrictions_on_foreign_declarations`:
- Because the number of enumeration values is less than 256, logic values are transported in 8 bit words (a ``char`` type in C).

- In this example two declarations make handling logic values in C a bit easier:

- Providing logic values in C as their enumeration numbers is simplified with the use of a matching enumeration, ``HDL_LOGIC_STATES``.
- Printing out a logic value's associated character is also simplified with the ``const char HDL_LOGIC_CHAR[]`` declaration.

- Logic vectors, of a bounded size, can be easily created in C as a ``char[]`` and passed to VHDL to be read as an ``access`` type in VHDL, in this case an access of a subtype of std_logic_vector.


This example builds on the integer vector example (:ref:`COSIM:VHPIDIRECT:Examples:arrays:intvector`), by instead passing an array of logic values. Foreign subprograms are declared that enable receiving the size of two different logic vectors as well as the vectors themselves from C. There is only one subprogram to get the size of both C arrays, and it takes in an integer to determine which array's size gets returned.

.. HINT::
The ``getLogicVecSize`` in VHDL is declared as receiving a ``boolean`` argument. In C the function is declared to receive an ``char`` argument. The VHDL booleans ``false`` and ``true`` are enumerations, and have integer values, ``0`` and ``1`` respectively. As with the logic values, the boolean enumerations use fewer than 8 bits, so the single byte in C's ``char`` variable receives the VHDL enumeration correctly.

umarcor marked this conversation as resolved.
Show resolved Hide resolved
For illustrative purposes, the two vectors are populated with logic values in different ways:

- LogicVectorA's indices are manually filled with enumeration values from HDL_LOGIC_STATES.

- .. code-block:: C

logic_vec_A[0] = HDL_U;

- LogicVectorB's indices are filled with an integer value.

- .. code-block:: C

for(int i = 0; i < SIZE_LOGIC_VEC_B; i++){
logic_vec_B[i] = 8-i;
}

.. ATTENTION::
umarcor marked this conversation as resolved.
Show resolved Hide resolved
The integer values that are given to ``char`` variables in C which are intended to be read as VHDL logic values, must be limited to [0, 8]. This ensures that they represent one of the 9 enumerated logic values.
1 change: 1 addition & 0 deletions doc/vhpidirect/examples/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ Examples
wrapping
linking
shared
arrays
other
52 changes: 52 additions & 0 deletions vhpidirect/arrays/logicvector/caux.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include <stdio.h>
#define SIZE_LOGIC_VEC_A (sizeof(logic_vec_A)/sizeof(char))
#define SIZE_LOGIC_VEC_B (sizeof(logic_vec_B)/sizeof(char))

static const char HDL_LOGIC_CHAR[] = { 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-'};

enum HDL_LOGIC_STATES {
HDL_U = 0,
HDL_X = 1,
HDL_0 = 2,
HDL_1 = 3,
HDL_Z = 4,
HDL_W = 5,
HDL_L = 6,
HDL_H = 7,
HDL_D = 8,
};

char logic_vec_A[3];
char logic_vec_B[6];

int getLogicVecSize(char returnA){
if(returnA)
return SIZE_LOGIC_VEC_A;
else
return SIZE_LOGIC_VEC_B;
}

char* getLogicVecA(){
//The HDL_LOGIC_STATES enum is used
logic_vec_A[0] = HDL_U;
logic_vec_A[1] = HDL_X;
logic_vec_A[2] = HDL_0;

printf("A: 1D Array Logic Values [%ld]:\n", SIZE_LOGIC_VEC_A);
for(int i = 0; i < SIZE_LOGIC_VEC_A; i++){
printf("[%d] = %c\t", i, HDL_LOGIC_CHAR[logic_vec_A[i]]);
}
printf("\n");
return logic_vec_A;
}

char* getLogicVecB(){
//The equivalent value of HDL_LOGIC_STATES is used
printf("B: 1D Array Logic Values [%ld]:\n", SIZE_LOGIC_VEC_B);
for(int i = 0; i < SIZE_LOGIC_VEC_B; i++){
logic_vec_B[i] = 8-i;//The last 'SIZE_LOGIC_VEC_B' HDL_LOGIC values, in reverse order.
printf("[%d] = %c\t", i, HDL_LOGIC_CHAR[logic_vec_B[i]]);
}
printf("\n");
return logic_vec_B;
}
14 changes: 14 additions & 0 deletions vhpidirect/arrays/logicvector/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env sh

cd "$(dirname $0)"

set -e

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

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

echo "Execute tb"
./tb
53 changes: 53 additions & 0 deletions vhpidirect/arrays/logicvector/tb.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
library ieee;
use ieee.std_logic_1164.all;

entity tb is
end;

architecture arch of tb is
begin

process

function getLogicVecSize(returnSizeOfA: boolean) return integer is
begin assert false report "VHPIDIRECT getLogicVecSize" severity failure; end;
attribute foreign of getLogicVecSize : function is "VHPIDIRECT getLogicVecSize";

subtype logic_vec_a_t is std_logic_vector(0 to getLogicVecSize(true)-1);
type logic_vec_a_ptr_t is access logic_vec_a_t;

subtype logic_vec_b_t is std_ulogic_vector(0 to getLogicVecSize(false)-1);
type logic_vec_b_ptr_t is access logic_vec_b_t;

function getLogicVecA return logic_vec_a_ptr_t is
begin assert false report "VHPIDIRECT getLogicVecA" severity failure; end;
attribute foreign of getLogicVecA : function is "VHPIDIRECT getLogicVecA";

function getLogicVecB return logic_vec_b_ptr_t is
begin assert false report "VHPIDIRECT getLogicVecB" severity failure; end;
attribute foreign of getLogicVecB : function is "VHPIDIRECT getLogicVecB";

variable g_logic_vec_a: logic_vec_a_ptr_t := getLogicVecA;
variable g_logic_vec_b: logic_vec_b_ptr_t := getLogicVecB;

constant logicArray: std_logic_vector(0 to 8) := ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-');
umarcor marked this conversation as resolved.
Show resolved Hide resolved

begin

report "g_logic_vec_a'length: " & integer'image(g_logic_vec_a'length) severity note;

for x in g_logic_vec_a'range loop
report "Asserting VecA [" & integer'image(x) & "]: " & std_logic'image(g_logic_vec_a(x)) severity note;
assert g_logic_vec_a(x) = logicArray(x) severity failure;
end loop;

report "g_logic_vec_b'length: " & integer'image(g_logic_vec_b'length) severity note;

for x in g_logic_vec_b'range loop
report "Asserting VecB [" & integer'image(x) & "]: " & std_logic'image(g_logic_vec_b(x)) severity note;
assert g_logic_vec_b(x) = logicArray(8-x) severity failure;
end loop;

wait;
end process;
end;