Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 3 additions & 0 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
sphinx
sphinx-argparse
ablog
19 changes: 18 additions & 1 deletion examples/vhdl/axi_dma/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,34 @@
via AXI-lite.
"""

from os import popen
from os.path import join, dirname
from vunit import VUnit
import inspect

vu = VUnit.from_argv()
vu = VUnit.from_argv(external={'string': True, 'integer': False})
vu.add_osvvm()
vu.add_verification_components()

src_path = join(dirname(__file__), "src")
ext_srcs = join(dirname(inspect.getfile(VUnit)), 'vhdl', 'data_types', 'src', 'external')

vu.add_library("axi_dma_lib").add_source_files(
[join(src_path, "*.vhd"), join(src_path, "test", "*.vhd")]
)

c_obj = join(src_path, 'test', 'main.o')

print(popen(' '.join([
'gcc -fPIC -rdynamic',
'-I', ext_srcs,
'-c', join(src_path, '**', 'main.c'),
'-o', c_obj
])).read())

vu.set_sim_option("ghdl.elab_flags", [
'-Wl,' + c_obj,
'-Wl,-Wl,--version-script=' + join(ext_srcs, 'grt.ver')
])

vu.main()
18 changes: 18 additions & 0 deletions examples/vhdl/axi_dma/src/test/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "vhpidirect_user.h"

static void exit_handler(void) {
atexit(exit_handler);
free(D[0]);
}

int main(int argc, char **argv) {
D[0] = (uint8_t *) malloc(2097152 * sizeof(uint8_t));
if ( D[0] == NULL ) {
perror("execution of malloc() failed!\n");
return -1;
}
return ghdl_main(argc, argv);
}
2 changes: 1 addition & 1 deletion examples/vhdl/axi_dma/src/test/tb_axi_dma.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ architecture tb of tb_axi_dma is
address_length => 32,
logger => get_logger("axil_bus"));

constant memory : memory_t := new_memory;
constant memory : memory_t := new_memory(2097152, extfnc);
constant axi_rd_slave : axi_slave_t := new_axi_slave(memory => memory,
logger => get_logger("axi_rd_slave"));

Expand Down
69 changes: 69 additions & 0 deletions examples/vhdl/external_buffer/cosim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
#
# Copyright (c) 2014-2019, Lars Asplund lars.anders.asplund@gmail.com


from vunit.cosim import *
import ctypes
from os.path import join, dirname, isfile
from sys import argv
from json import load


if len(argv) != 2:
print("A single argument is required and supported!")
exit(1)

with open(
join(dirname(__file__), "vunit_out", "cosim", "%s.json" % argv[1])
) as json_file:
args = load(json_file)
if "integer" not in argv[1]:
new_buf = byte_buf
read_buf = read_byte_buf
else:
new_buf = int_buf
read_buf = read_int_buf

xargs = enc_args(args)

print("\nREGULAR EXECUTION")
ghdl = dlopen(args[0])
try:
ghdl.main(len(xargs) - 1, xargs)
# FIXME With VHDL 93, the execution is Aborted and Python exits here
except SystemExit as exc:
if exc.code != 0:
exit(exc.code)
dlclose(ghdl)

print("\nPYTHON ALLOCATION")
ghdl = dlopen(args[0])

data = [111, 122, 133, 144, 155]

# Two pointers/buffers are to be allocated
buf = [[] for c in range(2)]

# Allocate and initialize shared data buffer
buf[1] = new_buf(data + [0 for x in range(2 * len(data))])

# Fill 'params' vector
buf[0] = int_buf(
[-(2 ** 31) + 10, -(2 ** 31), 3, 0, len(data)] # clk_step # update # block_length
)

for x, v in enumerate(buf):
ghdl.set_string_ptr(x, v)

for i, v in enumerate(read_buf(buf[1])):
print("py " + str(i) + ": " + str(v))

ghdl.ghdl_main(len(xargs) - 1, xargs)

for i, v in enumerate(read_buf(buf[1])):
print("py " + str(i) + ": " + str(v))

dlclose(ghdl)
36 changes: 33 additions & 3 deletions examples/vhdl/external_buffer/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,21 @@
"""

from vunit import VUnit, ROOT
from os import popen
from sys import argv
from os import popen, makedirs
from os.path import join, dirname
from shutil import copyfile
import re


src_path = join(dirname(__file__), "src")
ext_srcs = join(ROOT, "vunit", "vhdl", "data_types", "src", "external", "ghdl")
build_only = False
if "--build" in argv:
argv.remove("--build")
build_only = True

# Compile C applications to an objects
# Compile C applications to objects
c_iobj = join(src_path, "imain.o")
c_bobj = join(src_path, "bmain.o")

Expand Down Expand Up @@ -76,4 +84,26 @@
overwrite=True,
)

vu.main()
if build_only:
vu.set_sim_option("ghdl.elab_e", True)
vu._args.elaborate = True

def post_func(results):
"""
Copy runtime args for each test/executable to output dir 'cosim'
"""
report = results.get_report()
cosim_args_dir = join(report.output_path, "cosim")
try:
makedirs(cosim_args_dir)
except FileExistsError:
pass
for key, val in report.tests.items():
copyfile(
join(val.path, "ghdl", "args.json"),
join(cosim_args_dir, "%s.json" % re.search("lib\.(.+)\.all", key)[1]),
)

vu.main(post_run=post_func)
else:
vu.main()
73 changes: 73 additions & 0 deletions examples/vhdl/external_buffer/serve.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
#
# Copyright (c) 2014-2019, Lars Asplund lars.anders.asplund@gmail.com

import ctypes
from os.path import join, dirname
from vunit import VUnit
from websim import *


root = dirname(__file__)


# Allocate and define shared data buffers

data = [3 * c for c in range(64)]

buf = [[] for c in range(2)]
buf[1] = byte_buf(data + [0 for x in range(2 * len(data))])

buf[0] = int_buf([
-(2 ** 31) + 1,
-(2 ** 31),
0, # clk_step
1, # update
len(data) # block_length
])


# Load args and define simulation callbacks

sim = None
args = [line.rstrip("\n") for line in open(join(root, "args.txt"))]


def load():
g = ctypes.CDLL(args[0])
sim.handler(g)

for idx, val in enumerate(buf):
g.set_string_ptr(idx, val)

xargs = enc_args(args)
return g.ghdl_main(len(xargs) - 1, xargs)


def update_cb():
p = read_int_buf(buf[0])[0:3]
p[0] -= -(2 ** 31)
p[1] -= -(2 ** 31)
return {
"name": "external_buffer",
"params": p,
"data": {"mem": read_byte_buf(buf[1])},
}


def unload():
dlclose(sim.handler())


# Instantiate WebSim and run server

sim = WebSim(
dist=join(root, "..", "vue", "dist"),
load_cb=load,
unload_cb=unload,
update_cb=update_cb,
)

sim.run()
26 changes: 26 additions & 0 deletions examples/vhdl/external_buffer/sigabrt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
When VHDL 1993 is used, the simulation is terminated with an `abort`, which prevents the user from running post-checks.
These are some snippets to test it. See https://github.com/VUnit/vunit/pull/469#issuecomment-485723516.

``` python
https://bugs.python.org/issue12423
def handler(signum, frame):
print('Signal handler called with signal', signum)
import signal
signal.signal(signal.SIGABRT, handler)
import os
os.abort()
```

``` c
#include <signal.h>

void sigabrtHandler(int sig_num)
{
// Reset handler to catch SIGINT next time. Refer http://en.cppreference.com/w/c/program/signal
signal(SIGABRT, sigabrtHandler);
printf("\nSIGABRT caught!\n");
fflush(stdout);
}

signal(SIGABRT, sigabrtHandler);
```
24 changes: 20 additions & 4 deletions examples/vhdl/external_buffer/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ or tb_ext_integer_vector.vhd
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <limits.h>
#include "vhpidirect_user.h"

const uint32_t length = 5;
Expand All @@ -41,7 +42,7 @@ static void exit_handler(void) {
z = (length*j)+i;

expected = (i+1)*11 + k;
got = ((TYPE*)D[0])[z];
got = ((TYPE*)D[1])[z];
if (expected != got) {
printf("check error %d: %d %d\n", z, expected, got);
exit(1);
Expand All @@ -50,26 +51,41 @@ static void exit_handler(void) {
}
}
free(D[0]);
free(D[1]);
}

// Main entrypoint of the application
int main(int argc, char **argv) {
// Allocate a buffer which is three times the number of values
// that we want to copy/modify
D[0] = (uint8_t *) malloc(3*length*sizeof(TYPE));
D[0] = (uint8_t *) malloc(5*sizeof(int32_t));
if ( D[0] == NULL ) {
perror("execution of malloc() failed!\n");
return -1;
}

// Initialize 'params' array
int32_t *P = (int32_t*)D[0];
P[0] = INT_MIN+10;
P[1] = INT_MIN;
P[2] = 3; // clk_step
P[3] = 0; // update
P[4] = length; // block_length

// Initialize the first 1/3 of the buffer
D[1] = (uint8_t *) malloc(3*length*sizeof(TYPE));
if ( D[1] == NULL ) {
perror("execution of malloc() failed!\n");
return -1;
}
int i;
for(i=0; i<length; i++) {
((TYPE*)D[0])[i] = (i+1)*11;
((TYPE*)D[1])[i] = (i+1)*11;
}
// Print all the buffer
printf("sizeof: %lu\n", sizeof(TYPE));
for(i=0; i<3*length; i++) {
printf("%d: %d\n", i, ((TYPE*)D[0])[i]);
printf("%d: %d\n", i, ((TYPE*)D[1])[i]);
}

// Register a function to be called when GHDL exits
Expand Down
Loading