Skip to content

Commit 98133cc

Browse files
committed
examples/vhdl/external_buffer: add serve.py and adapt Vue.js frontend
1 parent 130a5aa commit 98133cc

8 files changed

Lines changed: 210 additions & 24 deletions

File tree

examples/vhdl/external_buffer/cosim.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
print("A single argument is required and supported!")
1717
exit(1)
1818

19-
with open(join(dirname(__file__), "vunit_out", "cosim", '%s.json' % argv[1])) as json_file:
19+
with open(
20+
join(dirname(__file__), "vunit_out", "cosim", "%s.json" % argv[1])
21+
) as json_file:
2022
args = load(json_file)
2123
if "integer" not in argv[1]:
2224
new_buf = byte_buf
@@ -30,7 +32,7 @@
3032
print("\nREGULAR EXECUTION")
3133
ghdl = dlopen(args[0])
3234
try:
33-
ghdl.main(len(xargs)-1, xargs)
35+
ghdl.main(len(xargs) - 1, xargs)
3436
# FIXME With VHDL 93, the execution is Aborted and Python exits here
3537
except SystemExit as exc:
3638
if exc.code != 0:
@@ -42,17 +44,26 @@
4244

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

47+
# Two pointers/buffers are to be allocated
48+
buf = [[] for c in range(2)]
49+
4550
# Allocate and initialize shared data buffer
46-
buf = new_buf(data + [0 for x in range(2*len(data))])
51+
buf[1] = new_buf(data + [0 for x in range(2 * len(data))])
52+
53+
# Fill 'params' vector
54+
buf[0] = int_buf(
55+
[-(2 ** 31) + 10, -(2 ** 31), 3, 0, len(data)] # clk_step # update # block_length
56+
)
4757

48-
ghdl.set_string_ptr(0, buf)
58+
for x, v in enumerate(buf):
59+
ghdl.set_string_ptr(x, v)
4960

50-
for i, v in enumerate(read_buf(buf)):
61+
for i, v in enumerate(read_buf(buf[1])):
5162
print("py " + str(i) + ": " + str(v))
5263

53-
ghdl.ghdl_main(len(xargs)-1, xargs)
64+
ghdl.ghdl_main(len(xargs) - 1, xargs)
5465

55-
for i, v in enumerate(read_buf(buf)):
66+
for i, v in enumerate(read_buf(buf[1])):
5667
print("py " + str(i) + ": " + str(v))
5768

5869
dlclose(ghdl)
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# This Source Code Form is subject to the terms of the Mozilla Public
2+
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
3+
# You can obtain one at http://mozilla.org/MPL/2.0/.
4+
#
5+
# Copyright (c) 2014-2019, Lars Asplund lars.anders.asplund@gmail.com
6+
7+
import ctypes
8+
from os.path import join, dirname
9+
from vunit import VUnit
10+
from websim import *
11+
12+
13+
root = dirname(__file__)
14+
15+
16+
# Allocate and define shared data buffers
17+
18+
data = [3 * c for c in range(64)]
19+
20+
buf = [[] for c in range(2)]
21+
buf[1] = byte_buf(data + [0 for x in range(2 * len(data))])
22+
23+
buf[0] = int_buf(
24+
[-(2 ** 31) + 1, -(2 ** 31), 0, 1, len(data)] # clk_step, update, block_length
25+
)
26+
27+
28+
# Load args and define simulation callbacks
29+
30+
sim = None
31+
args = [line.rstrip("\n") for line in open(join(root, "args.txt"))]
32+
33+
34+
def load():
35+
g = ctypes.CDLL(args[0])
36+
sim.handler(g)
37+
38+
for idx, val in enumerate(buf):
39+
g.set_string_ptr(idx, val)
40+
41+
xargs = enc_args(args)
42+
return g.ghdl_main(len(xargs) - 1, xargs)
43+
44+
45+
def update_cb():
46+
p = read_int_buf(buf[0])[0:3]
47+
p[0] -= -(2 ** 31)
48+
p[1] -= -(2 ** 31)
49+
return {
50+
"name": "external_buffer",
51+
"params": p,
52+
"data": {"mem": read_byte_buf(buf[1])},
53+
}
54+
55+
56+
def unload():
57+
dlclose(sim.handler())
58+
59+
60+
# Instantiate WebSim and run server
61+
62+
sim = WebSim(
63+
dist=join(root, "..", "vue", "dist"),
64+
load_cb=load,
65+
unload_cb=unload,
66+
update_cb=update_cb,
67+
)
68+
69+
sim.run()

examples/vhdl/external_buffer/src/main.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ or tb_ext_integer_vector.vhd
2121
#include <stdio.h>
2222
#include <stdlib.h>
2323
#include <stdint.h>
24+
#include <limits.h>
2425
#include "vhpidirect_user.h"
2526

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

4344
expected = (i+1)*11 + k;
44-
got = ((TYPE*)D[0])[z];
45+
got = ((TYPE*)D[1])[z];
4546
if (expected != got) {
4647
printf("check error %d: %d %d\n", z, expected, got);
4748
exit(1);
@@ -50,26 +51,41 @@ static void exit_handler(void) {
5051
}
5152
}
5253
free(D[0]);
54+
free(D[1]);
5355
}
5456

5557
// Main entrypoint of the application
5658
int main(int argc, char **argv) {
5759
// Allocate a buffer which is three times the number of values
5860
// that we want to copy/modify
59-
D[0] = (uint8_t *) malloc(3*length*sizeof(TYPE));
61+
D[0] = (uint8_t *) malloc(5*sizeof(int32_t));
6062
if ( D[0] == NULL ) {
6163
perror("execution of malloc() failed!\n");
6264
return -1;
6365
}
66+
67+
// Initialize 'params' array
68+
int32_t *P = (int32_t*)D[0];
69+
P[0] = INT_MIN+10;
70+
P[1] = INT_MIN;
71+
P[2] = 3; // clk_step
72+
P[3] = 0; // update
73+
P[4] = length; // block_length
74+
6475
// Initialize the first 1/3 of the buffer
76+
D[1] = (uint8_t *) malloc(3*length*sizeof(TYPE));
77+
if ( D[1] == NULL ) {
78+
perror("execution of malloc() failed!\n");
79+
return -1;
80+
}
6581
int i;
6682
for(i=0; i<length; i++) {
67-
((TYPE*)D[0])[i] = (i+1)*11;
83+
((TYPE*)D[1])[i] = (i+1)*11;
6884
}
6985
// Print all the buffer
7086
printf("sizeof: %lu\n", sizeof(TYPE));
7187
for(i=0; i<3*length; i++) {
72-
printf("%d: %d\n", i, ((TYPE*)D[0])[i]);
88+
printf("%d: %d\n", i, ((TYPE*)D[1])[i]);
7389
}
7490

7591
// Register a function to be called when GHDL exits

examples/vhdl/external_buffer/src/tb_ext_byte_vector.vhd

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,44 +11,84 @@
1111
--library vunit_lib;
1212
--context vunit_lib.vunit_context;
1313

14+
library ieee;
15+
use ieee.std_logic_1164.all;
16+
use ieee.numeric_std.all;
17+
1418
library vunit_lib;
1519
use vunit_lib.run_pkg.all;
1620
use vunit_lib.logger_pkg.all;
1721
use vunit_lib.types_pkg.all;
1822
use vunit_lib.byte_vector_ptr_pkg.all;
23+
use vunit_lib.integer_vector_ptr_pkg.all;
24+
use vunit_lib.clk_pkg.all;
1925

2026
entity tb_external_byte_vector is
2127
generic ( runner_cfg : string );
2228
end entity;
2329

2430
architecture tb of tb_external_byte_vector is
2531

26-
constant block_len : natural := 5;
32+
constant params: integer_vector_ptr_t := new_integer_vector_ptr(6, extacc, 0);
33+
34+
constant clk_step : natural := get(params, 2);
35+
constant block_len : integer := get(params, 4);
2736

28-
constant ebuf: byte_vector_ptr_t := new_byte_vector_ptr( 3*block_len, extfnc, 0); -- external through VHPIDIRECT functions 'read_char' and 'write_char'
29-
constant abuf: byte_vector_ptr_t := new_byte_vector_ptr( 3*block_len, extacc, 0); -- external through access (requires VHPIDIRECT function 'get_string_ptr')
37+
constant ebuf: byte_vector_ptr_t := new_byte_vector_ptr( 3*block_len, extfnc, 1); -- external through VHPIDIRECT functions 'read_char' and 'write_char'
38+
constant abuf: byte_vector_ptr_t := new_byte_vector_ptr( 3*block_len, extacc, 1); -- external through access (requires VHPIDIRECT function 'get_string_ptr')
39+
40+
signal clk, rst, rstn : std_logic := '0';
41+
signal done, tg, start : boolean := false;
3042

3143
begin
3244

33-
main: process
45+
rstn <= not rst;
46+
47+
clk_gen: entity vunit_lib.clk_handler generic map ( params ) port map ( rst, clk, tg );
48+
49+
run: process(tg) begin if rising_edge(tg) then
50+
info("UPDATE READY");
51+
set(params, 3, 1);
52+
end if; end process;
53+
54+
main: process begin
55+
test_runner_setup(runner, runner_cfg);
56+
rst <= '1';
57+
info("Init test: " & to_string(block_len));
58+
wait for 100 ns;
59+
rst <= '0';
60+
info("wait_load");
61+
wait_load(params);
62+
info("start");
63+
start <= true;
64+
info("wait_sync");
65+
wait_sync(params, done, tg);
66+
info("Test done");
67+
test_runner_cleanup(runner);
68+
wait;
69+
end process;
70+
71+
stimuli: process
3472
variable val, ind: integer;
3573
begin
36-
test_runner_setup(runner, runner_cfg);
37-
info("Init test");
74+
wait until start;
75+
wait_for(clk, 1);
3876
for x in 0 to block_len-1 loop
3977
val := get(ebuf, x) + 1;
4078
ind := block_len+x;
4179
set(ebuf, ind, val);
4280
info("SET " & to_string(ind) & ": " & to_string(val));
81+
wait_for(clk, 1);
4382
end loop;
4483
for x in block_len to 2*block_len-1 loop
4584
val := get(abuf, x) + 2;
4685
ind := block_len+x;
4786
set(abuf, ind, val);
4887
info("SET " & to_string(ind) & ": " & to_string(val));
88+
wait_for(clk, 1);
4989
end loop;
50-
info("End test");
51-
test_runner_cleanup(runner);
90+
info("done");
91+
done <= true;
5292
wait;
5393
end process;
5494

examples/vhdl/external_buffer/src/tb_ext_integer_vector.vhd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ architecture tb of tb_external_integer_vector is
2525

2626
constant block_len : natural := 5;
2727

28-
constant ebuf: integer_vector_ptr_t := new_integer_vector_ptr( 3*block_len, extfnc, 0); -- external through VHPIDIRECT functions 'read_char' and 'write_char'
29-
constant abuf: integer_vector_ptr_t := new_integer_vector_ptr( 3*block_len, extacc, 0); -- external through access (requires VHPIDIRECT function 'get_string_ptr')
28+
constant ebuf: integer_vector_ptr_t := new_integer_vector_ptr( 3*block_len, extfnc, 1); -- external through VHPIDIRECT functions 'read_char' and 'write_char'
29+
constant abuf: integer_vector_ptr_t := new_integer_vector_ptr( 3*block_len, extacc, 1); -- external through access (requires VHPIDIRECT function 'get_string_ptr')
3030

3131
begin
3232

examples/vhdl/external_buffer/src/tb_ext_string.vhd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ architecture tb of tb_external_string is
2525

2626
constant block_len : natural := 5;
2727

28-
constant ebuf: string_ptr_t := new_string_ptr( 3*block_len, extfnc, 0); -- external through VHPIDIRECT functions 'read_char' and 'write_char'
29-
constant abuf: string_ptr_t := new_string_ptr( 3*block_len, extacc, 0); -- external through access (requires VHPIDIRECT function 'get_string_ptr')
28+
constant ebuf: string_ptr_t := new_string_ptr( 3*block_len, extfnc, 1); -- external through VHPIDIRECT functions 'read_char' and 'write_char'
29+
constant abuf: string_ptr_t := new_string_ptr( 3*block_len, extacc, 1); -- external through access (requires VHPIDIRECT function 'get_string_ptr')
3030

3131
begin
3232

examples/vhdl/vue/src/App.vue

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121
</div>
2222
</div>
2323
</section>
24+
25+
<external_buffer
26+
v-if="loaded && (name=='external_buffer')"
27+
:data.sync="data"/>
2428
</div>
2529
</template>
2630

@@ -38,10 +42,13 @@ Vue.use(Buefy);
3842
3943
import NavBar from "@/components/NavBar.vue";
4044
45+
import external_buffer from "@/cases/external_buffer.vue";
46+
4147
export default {
4248
name: 'app',
4349
components: {
44-
NavBar
50+
NavBar,
51+
external_buffer
4552
},
4653
data() {
4754
return {
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<template>
2+
<div class="container">
3+
<Memory
4+
name="buffer"
5+
:buf="content.mem"/>
6+
</div>
7+
</template>
8+
9+
<script>
10+
import Memory from "@/components/Memory.vue";
11+
12+
function isEmpty(obj) {
13+
for(var key in obj) {
14+
if(obj.hasOwnProperty(key))
15+
return false;
16+
}
17+
return true;
18+
}
19+
20+
export default {
21+
name: 'external_buffer',
22+
components: {
23+
Memory
24+
},
25+
props: {
26+
data: Object
27+
},
28+
computed: {
29+
content() {
30+
return (isEmpty(this.data)) ? {
31+
mem: [],
32+
} : {
33+
mem: this.data.mem,
34+
};
35+
}
36+
},
37+
methods: {
38+
isEmpty(d) {
39+
return isEmpty(d);
40+
}
41+
}
42+
}
43+
</script>

0 commit comments

Comments
 (0)