Skip to content

Commit

Permalink
feat(examples/vhdl/array_axis_vcs): use helper functions instead of d…
Browse files Browse the repository at this point in the history
…eclaring arrays and access types
  • Loading branch information
umarcor committed Apr 9, 2019
1 parent 35a7940 commit a241e7d
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 39 deletions.
21 changes: 12 additions & 9 deletions examples/vhdl/array_axis_vcs/src/test/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

extern int ghdl_main (int argc, char **argv);

int32_t *V[2];
uint8_t *V[2];
uint32_t length = 100;

// get_param is used by GHDL to retrieve parameter values (integers).
Expand All @@ -25,14 +25,16 @@ uint32_t get_param(uint32_t w) {
return o;
}

// get_addr is used by GHDL to retrieve pointers to the base addresses of the buffers.
uintptr_t get_addr(uint32_t w) {
//printf("get_addr(%d): %p\n", w, (void *)V[w]o);
return (uintptr_t)V[w];
void write_byte ( uint8_t id, uint32_t i, uint8_t v ) {
V[id][i] = v;
}

uint8_t read_byte ( uint8_t id, uint32_t i ) {
return V[id][i];
}

// check evaluates if the result produced by the UUT is equivalent to some other softwre procedure.
int check(int32_t *I, int32_t *O, uint32_t l) {
int check(uint8_t *I, uint8_t *O, uint32_t l) {
int i;
for ( i=0 ; i<l ; i++ ) {
if ( I[i] != O[i] ) {
Expand All @@ -54,7 +56,7 @@ int main(int argc, char **argv) {
// Allocate the memory buffers that are to be shared between the software and the simulation.
int i;
for (i=0 ; i<2 ; i++) {
V[i] = (int32_t *) malloc(length*sizeof(uint32_t));
V[i] = (uint8_t *) malloc(length*sizeof(uint32_t));
if ( V[i] == NULL ) {
perror("execution of malloc() failed!\n");
return -1;
Expand All @@ -63,15 +65,16 @@ int main(int argc, char **argv) {

// Initialize one of the buffers with random data.
for (i=0 ; i<length ; i++) {
V[0][i]=i*100+rand()/(RAND_MAX/100);
((int32_t*)V[0])[i] = i*100+rand()/(RAND_MAX/100);
printf("V[%d]: %d\n", i, ((int32_t*)V[0])[i]);
}

// Execute the simulation to let the UUT copy the data from one buffer to another.
ghdl_main(gargc, gargv);

// Check that the UUT did what it was expected to do.
printf("> Call 'check'\n");
if ( check(V[0], V[1], length) != 0 ) {
if ( check((int32_t*)V[0], (int32_t*)V[1], length) != 0 ) {
printf("check failed!\n");
return -1;
}
Expand Down
61 changes: 42 additions & 19 deletions examples/vhdl/array_axis_vcs/src/test/pkg_c.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -4,55 +4,78 @@
--
-- Copyright (c) 2014-2019, Lars Asplund lars.anders.asplund@gmail.com

library ieee;
context ieee.ieee_std_context;

package pkg_c is

function get_param(f: integer) return integer;
attribute foreign of get_param :
function is "VHPIDIRECT get_param";
attribute foreign of get_param : function is "VHPIDIRECT get_param";

--integer'high is 2147483647, but the limit here seems to be 128 times less. Otherwise, it fails.
constant max_length: integer:= 16777215;
type buffer_t is array(integer range 0 to max_length) of integer;
type buffer_p is access buffer_t;
procedure write_byte ( id, i, v: integer ) ;
attribute foreign of write_byte : procedure is "VHPIDIRECT write_byte";

impure function get_addr(f: integer) return buffer_p;
attribute foreign of get_addr :
function is "VHPIDIRECT get_addr";
impure function read_byte ( id, i: integer ) return integer;
attribute foreign of read_byte : function is "VHPIDIRECT read_byte";

type memory_t is record
-- Private
p_id: integer;
end record;

impure function new_memory(id: integer := -1) return memory_t;
procedure write_word ( memory: memory_t; i, v: integer );
impure function read_word ( memory: memory_t; i: integer ) return integer;
procedure write_word ( memory: memory_t; i: natural; w: std_logic_vector );
impure function read_word ( memory: memory_t; i, bytes_per_word: integer ) return std_logic_vector;

procedure write_byte ( memory: memory_t; i: integer; v: std_logic_vector(7 downto 0) );
impure function read_byte ( memory: memory_t; i: integer ) return std_logic_vector;

end pkg_c;

package body pkg_c is

-- VHPI

function get_param(f: integer) return integer is begin
assert false report "VHPI" severity failure;
end function;

impure function get_addr(f: integer) return buffer_p is begin
procedure write_byte ( id, i, v: integer ) is begin
assert false report "VHPI" severity failure;
end procedure;

impure function read_byte ( id, i: integer ) return integer is begin
assert false report "VHPI" severity failure;
end function;

-- VHDL

procedure write_byte ( memory: memory_t; i: integer; v: std_logic_vector(7 downto 0) ) is
begin
write_byte(memory.p_id, i, to_integer(unsigned(v)));
end procedure;

impure function read_byte ( memory: memory_t; i: integer ) return std_logic_vector is begin
return std_logic_vector(to_unsigned(read_byte(memory.p_id, i), 8));
end function;

impure function new_memory(id: integer := -1) return memory_t is begin
return (p_id => id);
end;

procedure write_word ( memory: memory_t; i, v: integer ) is
variable buf: buffer_p := get_addr(memory.p_id);
begin
buf(i) := v;
procedure write_word ( memory: memory_t; i: natural; w: std_logic_vector ) is begin
for idx in 0 to w'length/8-1 loop
write_byte(memory, i + idx, w(8*idx+7 downto 8*idx));
end loop;
end procedure;

impure function read_word ( memory: memory_t; i: integer ) return integer is
variable buf: buffer_p := get_addr(memory.p_id);
impure function read_word ( memory: memory_t; i, bytes_per_word: integer ) return std_logic_vector is
variable tmp: std_logic_vector(31 downto 0);
begin
return buf(i);
for idx in 0 to bytes_per_word-1 loop
tmp(8*idx+7 downto 8*idx) := read_byte(memory, i + idx);
end loop;
return tmp;
end function;

end pkg_c;
15 changes: 6 additions & 9 deletions examples/vhdl/array_axis_vcs/src/test/stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@
#include <stdlib.h>
#include <stdint.h>

// get_param is used by GHDL to retrieve parameter values (integers).
uint32_t get_param(uint32_t w) {
printf("ERROR get_param: THIS IS A STUB\n");
void write_byte ( uint8_t id, uint32_t i, uint8_t v ) {
printf("ERROR write_byte: THIS IS A STUB\n");
exit(1);
return 0;
}

// get_param is used by GHDL to retrieve pointers to the base addresses of the buffers.
uintptr_t get_addr(uint32_t w) {
printf("ERROR get_addr: THIS IS A STUB\n");
uint8_t read_byte ( uint8_t id, uint32_t i ) {
printf("ERROR read_byte: THIS IS A STUB\n");
exit(1);
return (uintptr_t)NULL;
}
return 0;
}
4 changes: 2 additions & 2 deletions examples/vhdl/array_axis_vcs/src/test/tb_c_axis_loop.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ begin

for y in 0 to stream_length-1 loop
wait until rising_edge(clk);
push_axi_stream(net, m_axis, std_logic_vector(to_signed(pkg_c.read_word(ibuffer, y), data_width)) , tlast => '0');
push_axi_stream(net, m_axis, pkg_c.read_word(ibuffer, 4*y, 4) , tlast => '0');
end loop;

info("m_I sent!");
Expand All @@ -106,7 +106,7 @@ begin

for y in 0 to stream_length-1 loop
pop_axi_stream(net, s_axis, tdata => o, tlast => last);
pkg_c.write_word(obuffer, y, to_integer(signed(o)));
pkg_c.write_word(obuffer, 4*y, o);
end loop;

info("m_O read!");
Expand Down

0 comments on commit a241e7d

Please sign in to comment.