forked from ghdl/ghdl-cosim
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
354 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
#include <stdlib.h> | ||
#include <stdint.h> | ||
#include <stdio.h> | ||
#include <stdbool.h> | ||
#include <assert.h> | ||
#include <string.h> | ||
|
||
#include <ghdl-intro.h> | ||
|
||
char* vec; | ||
bounds_t* vec_bounds; | ||
char* mat; | ||
bounds_t* mat_bounds; | ||
int* len; | ||
int* len2; | ||
|
||
int getFlatArrayIndex(int* dimIndex, int* lens, int dims){ | ||
if(dims == 1){ | ||
return dimIndex[0]; | ||
} | ||
else{ | ||
return dimIndex[dims-1] + (lens[dims-1]*getFlatArrayIndex(dimIndex, lens, dims-1)); | ||
} | ||
} | ||
|
||
void testCinterface( | ||
ghdl_NaturalDimArr_t* v_vec_logic, | ||
ghdl_NaturalDimArr_t* v_mat_ulogic | ||
) { | ||
|
||
//VECTOR 1D//////////////////////////////////////// | ||
printf("\nvector\n"); | ||
printUnconstrained(v_vec_logic, 1); | ||
len = malloc(1 * sizeof(int)); | ||
|
||
char* vec; | ||
ghdlToArray(v_vec_logic, (void**)&vec, len, 1); | ||
for (int i = 0; i < len[0]; i++) | ||
{ | ||
printf("C vec_logic[%d] = %c\n", i, HDL_LOGIC_CHAR[vec[i]]); | ||
} | ||
printf("v_vec_logic : %p [%d]\n\n", vec, len[0]); | ||
|
||
//MATRIX 2D//////////////////////////////////////// | ||
printf("\nmatrix\n"); | ||
printUnconstrained(v_mat_ulogic, 2); | ||
len2 = malloc(2 * sizeof(int)); | ||
|
||
char* mat_ulogic; | ||
ghdlToArray(v_mat_ulogic, (void**)&mat_ulogic, len2, 2); | ||
for (int i = 0; i < len2[0]; i++) | ||
{ | ||
for (int j = 0; j < len2[1]; j++) | ||
{ | ||
int ind[] = {i, j}; | ||
int flatIndex = getFlatArrayIndex(ind, len2, 2); | ||
printf("[%d][%d] = %c (%d)\t", i, j, HDL_LOGIC_CHAR[mat_ulogic[flatIndex]], flatIndex); | ||
} | ||
printf("\n"); | ||
} | ||
printf("v_mat_ulogic : %p [%d,%d]\n\n", mat_ulogic, len2[0], len2[1]); | ||
|
||
printf("end testCinterface\n\n"); | ||
} | ||
|
||
void freePointers(){ | ||
free(vec); | ||
free(vec_bounds); | ||
free(mat); | ||
free(mat_bounds); | ||
free(len); | ||
free(len2); | ||
} | ||
|
||
void getLogicVec(ghdl_NaturalDimArr_t* ptr){ | ||
char vecArr[9]; | ||
int32_t len[1] = {9}; | ||
for(int i = 0; i < len[0]; i++){ | ||
vecArr[i] = i; | ||
} | ||
printf("\n"); | ||
|
||
*ptr = ghdlFromArray((void *)vecArr, len, 1, sizeof(char)); | ||
vec_bounds = ptr->bounds; | ||
vec = ptr->array; | ||
printf("1D Array Logic Values [%d]:\n", len[0]); | ||
for(int x = 0; x < len[0]; x++){ | ||
printf("[%d] = %c\t", x, HDL_LOGIC_CHAR[x]); | ||
assert(((char*)ptr->array)[x] == vecArr[x]); | ||
//ghdlFromArray creates a deep-copy of the information, so this change is not reflected in VHDL | ||
vecArr[x] = 0; | ||
} | ||
|
||
} | ||
|
||
void getULogicMat(ghdl_NaturalDimArr_t* ptr){ | ||
mat = malloc(3*3*sizeof(int32_t)); | ||
int32_t len[2] = {3, 3}; | ||
int x, y, ind[2]; | ||
for ( x=0 ; x<len[0] ; x++ ) { | ||
ind[0] = x; | ||
for ( y=0 ; y<len[1] ; y++ ) { | ||
ind[1] = y; | ||
int flatIndex = getFlatArrayIndex(ind, len, 2); | ||
mat[flatIndex] = flatIndex%9; | ||
} | ||
} | ||
//ghdl_NaturalDimArr_t* ptr = malloc(sizeof(ghdl_NaturalDimArr_t)); | ||
*ptr = ghdlFromPointer((void *)mat, len, 2); | ||
mat_bounds = ptr->bounds; | ||
assert(mat == ptr->array); | ||
printf("\n2D Array values [%d,%d]:\n", len[0], len[1]); | ||
for ( x=0 ; x<len[0] ; x++ ) { | ||
ind[0] = x; | ||
for ( y=0 ; y<len[1] ; y++ ) { | ||
ind[1] = y; | ||
int flatIndex = getFlatArrayIndex(ind, len, 2); | ||
printf("mat[%d][%d] = %c\t", x, y, HDL_LOGIC_CHAR[mat[flatIndex]]); | ||
assert(((char*)ptr->array)[flatIndex] == mat[flatIndex]); | ||
} | ||
printf("\n"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
#ifndef GHDL_TYPES_INTRO_H | ||
#define GHDL_TYPES_INTRO_H | ||
|
||
#include <stdlib.h> | ||
#include <stdint.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
|
||
// Range/bounds of a dimension of an unconstrained array with dimensions of type 'natural' | ||
typedef struct { | ||
int32_t left; | ||
int32_t right; | ||
int32_t dir; | ||
int32_t len; | ||
} bounds_t; | ||
|
||
// Unconstrained array with dimensions of type 'natural' | ||
typedef struct { | ||
void* array; | ||
bounds_t* bounds; | ||
} ghdl_NaturalDimArr_t; | ||
|
||
/* | ||
* Print custom types | ||
*/ | ||
|
||
void printUnconstrained(ghdl_NaturalDimArr_t* ptr, int dims) { | ||
printf("array: %p\n", ptr->array); | ||
printf("bounds: %p\n", ptr->bounds); | ||
int i; | ||
for(i = 0; i < dims; i++){ | ||
printf("bounds%d.left: %d\n", i, ptr->bounds[i].left); | ||
printf("bounds%d.right: %d\n", i, ptr->bounds[i].right); | ||
printf("bounds%d.dir: %d\n", i, ptr->bounds[i].dir); | ||
printf("bounds%d.len: %d\n", i, ptr->bounds[i].len); | ||
} | ||
} | ||
|
||
/* | ||
* Convert a fat pointer of an uncontrained array with (up to 3) dimensions of type 'natural', to C types | ||
*/ | ||
|
||
void ghdlToArray(ghdl_NaturalDimArr_t* ptr, void** vec, int* len, int num) { | ||
assert(ptr != NULL); | ||
assert(ptr->bounds != NULL); | ||
*vec = ptr->array; | ||
|
||
for (int i = 0; i < num; i++) | ||
{ | ||
len[i] = ptr->bounds[i].len; | ||
} | ||
} | ||
|
||
/* | ||
* Helper to setup the bounds_t for ghdlFromArray | ||
*/ | ||
|
||
void ghdlSetRange(bounds_t* r, int len, bool reversed){ | ||
if(!reversed){//to | ||
r->left = 0; | ||
r->right = len-1; | ||
r->dir = 0; | ||
r->len = len; | ||
} | ||
else{//downto | ||
r->left = len-1; | ||
r->right = 0; | ||
r->dir = 1; | ||
r->len = len; | ||
} | ||
} | ||
|
||
/* | ||
* Convert C types representing an unconstrained array with a dimension of type 'natural', to a fat pointer | ||
*/ | ||
|
||
|
||
ghdl_NaturalDimArr_t ghdlFromPointer(void* vec, int* len, int dims) { | ||
bounds_t* b = malloc(sizeof(bounds_t)*dims); | ||
assert(b != NULL); | ||
|
||
for (int i = 0; i < dims; i++) | ||
{ | ||
ghdlSetRange(b+i, len[i], false); | ||
} | ||
|
||
void *a = vec; | ||
return (ghdl_NaturalDimArr_t){.array= a, .bounds=b}; | ||
} | ||
|
||
ghdl_NaturalDimArr_t ghdlFromArray(void* vec, int* len, int dims, int sizeOfDataType) { | ||
bounds_t* b = malloc(sizeof(bounds_t)*dims); | ||
int totalSize = 1; | ||
for (int i = 0; i < dims; i++) | ||
{ | ||
totalSize *= len[i]; | ||
ghdlSetRange(b+i, len[i], false); | ||
} | ||
|
||
void *a = malloc(sizeOfDataType * totalSize); | ||
memcpy(a, vec, sizeOfDataType * totalSize); | ||
|
||
return (ghdl_NaturalDimArr_t){.array= a, .bounds=b}; | ||
} | ||
|
||
/* | ||
* Handle C char for the appropriate values in std_ulogic and std_logic. | ||
*/ | ||
|
||
// @RocketRoss | ||
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, | ||
}; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#!/usr/bin/env sh | ||
|
||
cd "$(dirname $0)" | ||
|
||
set -e | ||
|
||
ghdl -a --std=08 -O0 -g tb.vhd | ||
ghdl -e --std=08 -O0 -g -Wl,-ggdb3 -Wl,-I./ -Wl,caux.c tb && | ||
./tb | ||
#valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=valgrind-out.txt ./tb && | ||
#cat valgrind-out.txt | grep -A 4 "LEAK SUMMARY" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
use std.textio.line; | ||
|
||
library ieee; | ||
use ieee.std_logic_1164.all; | ||
|
||
entity tb is | ||
end; | ||
|
||
architecture arch of tb is | ||
|
||
type ulogic_mat_t is array(natural range <>, natural range <>) of std_ulogic; | ||
|
||
begin | ||
process | ||
|
||
procedure testCinterface( | ||
v_1D_logic : std_logic_vector; | ||
v_1D_ulogic : ulogic_mat_t | ||
) is | ||
begin assert false report "VHPIDIRECT testCinterface" severity failure; end; | ||
attribute foreign of testCinterface : procedure is "VHPIDIRECT testCinterface"; | ||
|
||
function getLogicVec return std_logic_vector is | ||
begin assert false report "VHPIDIRECT getLogicVec" severity failure; end; | ||
attribute foreign of getLogicVec : function is "VHPIDIRECT getLogicVec"; | ||
|
||
function getULogicMat return ulogic_mat_t is | ||
begin assert false report "VHPIDIRECT getULogicMat" severity failure; end; | ||
attribute foreign of getULogicMat : function is "VHPIDIRECT getULogicMat"; | ||
|
||
|
||
procedure freeCPointers is | ||
begin assert false report "VHPIDIRECT freeCPointers" severity failure; end; | ||
attribute foreign of freeCPointers : procedure is "VHPIDIRECT freePointers"; | ||
|
||
constant g_logic_vec: std_logic_vector := getLogicVec; | ||
constant g_ulogic_mat: ulogic_mat_t := getULogicMat; | ||
|
||
constant logicArray: std_logic_vector(0 to 8) := ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-'); | ||
|
||
variable spareInt: integer; | ||
begin | ||
|
||
testCinterface( | ||
v_1D_logic => ('1', 'H', 'X'), | ||
v_1D_ulogic => (('1', 'H', 'X'), ('1', 'H', 'X')) | ||
); | ||
|
||
report "g_logic_vec'length: " & integer'image(g_logic_vec'length) severity note; | ||
|
||
for x in g_logic_vec'range loop | ||
report "Asserting Vec [" & integer'image(x) & "]: " & std_logic'image(g_logic_vec(x)) severity note; | ||
assert g_logic_vec(x) = logicArray(x) severity failure; | ||
end loop; | ||
|
||
spareInt := 0; | ||
report "g_ulogic_mat'length: " & integer'image(g_ulogic_mat'length) severity note; | ||
for i in g_ulogic_mat'range loop | ||
for j in g_ulogic_mat'range(1) loop | ||
report "Asserting Mat [" & integer'image(i) & "," & integer'image(j) & "]: " & std_logic'image(g_ulogic_mat(i,j)) severity note; | ||
assert g_ulogic_mat(i,j) = logicArray(spareInt) severity failure; | ||
spareInt := spareInt + 1; | ||
end loop ; | ||
end loop ; | ||
|
||
freeCPointers; | ||
wait; | ||
end process; | ||
end; |