Hallo,
In my last email I ask about the possiblity to make some trigger events
to GHDL. I want change vhdl signals from outside.
I get only some short information. But no correct way.
I had tried this for long time and stopped this. Now some year later I
had found no solution and ask.
I check out some old files and reduced the code for this problem.
First the testbench starts a connection.
Now the question:
how can a c-function change a vhdl signal?
For instance make Reset high for 80ns if the socket bind.
Best regards
René Doß
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <signal.h>
#include <netdb.h>
#include <pthread.h>
#define GDBSTUB_EXECUTION_BREAKPOINT (0xac1)
#define GDBSTUB_TRACE (0xac2)
#define GDBSTUB_USER_BREAK (0xac3)
static int listen_socket_fd;
static int socket_fd;
static int hex(char ch)
{
if ((ch >= 'a') && (ch <= 'f')) return(ch - 'a' + 10);
if ((ch >= '0') && (ch <= '9')) return(ch - '0');
if ((ch >= 'A') && (ch <= 'F')) return(ch - 'A' + 10);
return(-1);
}
static void put_debug_char(char ch)
{
send(socket_fd, &ch, 1, 0);
}
static char get_debug_char(void)
{
char ch;
recv(socket_fd, &ch, 1, 0);
return(ch);
}
static const char hexchars[]="0123456789abcdef";
static void put_reply(char* buffer)
{
unsigned char csum;
int i;
do
{
put_debug_char('$');
csum = 0;
i = 0;
while (buffer[i] != 0)
{
put_debug_char(buffer[i]);
csum = csum + buffer[i];
i++;
}
put_debug_char('#');
put_debug_char(hexchars[csum >> 4]);
put_debug_char(hexchars[csum % 16]);
} while (get_debug_char() != '+');
}
static void get_command(char* buffer)
{
unsigned char checksum;
unsigned char xmitcsum;
char ch;
unsigned int count;
unsigned int i;
do
{
while ((ch = get_debug_char()) != '$');
checksum = 0;
xmitcsum = 0;
count = 0;
while (1)
{
ch = get_debug_char();
if (ch == '#') break;
checksum = checksum + ch;
buffer[count] = ch;
count++;
}
buffer[count] = 0;
if (ch == '#')
{
xmitcsum = hex(get_debug_char()) << 4;
xmitcsum += hex(get_debug_char());
if (checksum != xmitcsum)
{
// BX_INFO (("Bad checksum"));
}
}
if (checksum != xmitcsum)
{
put_debug_char('-');
}
else
{
put_debug_char('+');
if (buffer[2] == ':')
{
put_debug_char(buffer[0]);
put_debug_char(buffer[1]);
count = strlen(buffer);
for (i = 3; i <= count; i++)
{
buffer[i - 3] = buffer[i];
}
}
}
} while (checksum != xmitcsum);
}
void hex2mem(char* buf, unsigned char* mem, int count)
{
int i;
unsigned char ch;
for (i = 0; i<count; i++)
{
ch = hex(*buf++) << 4;
ch = ch + hex(*buf++);
*mem = ch;
mem++;
}
}
char* mem2hex(char* mem, char* buf, int count)
{
int i;
unsigned char ch;
for (i = 0; i<count; i++)
{
ch = *mem;
mem++;
*buf = hexchars[ch >> 4];
buf++;
*buf = hexchars[ch % 16];
buf++;
}
*buf = 0;
return(buf);
}
static int continue_thread = -1;
static int other_thread = 0;
#define NUMREGS (18)
#define NUMREGSBYTES (NUMREGS * 4)
static int registers[NUMREGS];
#define MAX_BREAKPOINTS (255)
static int breakpoints[MAX_BREAKPOINTS] = {0,};
static int nr_breakpoints = 0;
static int stub_trace_flag = 0;
static int instr_count = 0;
static int saved_eip = 0;
static void server_connect(int portn)
{
struct sockaddr_in sockaddr;
socklen_t sockaddr_len;
struct protoent *protoent;
int r;
int opt;
listen_socket_fd = socket(PF_INET, SOCK_STREAM, 0);
if (listen_socket_fd == -1)
{
printf(("Failed to create socket\n"));
exit(1);
}
/* Allow rapid reuse of this port */
opt = 1;
r = setsockopt(listen_socket_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
if (r == -1)
{
// BX_INFO (("setsockopt(SO_REUSEADDR) failed\n"));
}
memset (&sockaddr, '\000', sizeof sockaddr);
#if BX_HAVE_SOCKADDR_IN_SIN_LEN
// if you don't have sin_len change that to #if 0. This is the subject of
// bug [ 626840 ] no 'sin_len' in 'struct sockaddr_in'.
sockaddr.sin_len = sizeof sockaddr;
#endif
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons(portn);
sockaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
r = bind(listen_socket_fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
if (r == -1)
{
printf (("Failed to bind socket\n"));
}
r = listen(listen_socket_fd, 0);
if (r == -1)
{
printf(("Failed to listen on socket\n"));
}
sockaddr_len = sizeof sockaddr;
socket_fd = accept(listen_socket_fd, (struct sockaddr *)&sockaddr, &sockaddr_len);
if (socket_fd == -1)
{
printf (("Failed to accept on socket\n"));
}
close(listen_socket_fd);
protoent = getprotobyname ("tcp");
if (!protoent)
{
printf (("getprotobyname (\"tcp\") failed\n"));
return ;
}
/* Disable Nagle - allow small packets to be sent without delay. */
opt = 1;
r = setsockopt (socket_fd, protoent->p_proto, TCP_NODELAY, &opt, sizeof(opt));
if (r == -1)
{
printf (("setsockopt(TCP_NODELAY) failed\n"));
}
}
//static
int wait_for_connect(int portn)
{
//http://www.risc.jku.at/people/schreine/papers/rt++-linuxmag1/main.html
printf ("wait for connect\n");
pthread_t thread1;
server_connect(portn);
// server_connect(2013);
printf("start debug loop\n");
/* Do debugger command loop */
// pthread_create(&thread1, NULL, &debug_loop, NULL);
// debug_loop();
return 1;
}
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package gdb_pack is
function wait_for_connect (portn :integer) return integer;
attribute foreign of wait_for_connect :
function is "VHPIDIRECT wait_for_connect";
end;
package body gdb_pack is
function wait_for_connect (portn :integer) return integer is
begin
assert false report "VHPI" severity failure;
end wait_for_connect;
end gdb_pack;
all:
gcc -c -fPIC gdb_sim.c
rm -rf work
mkdir work
ghdl -a --work=work --workdir=work gdb_sim_pkg.vhd
ghdl -a --work=work --workdir=work tb_MAIS.vhd
# ghdl -e -Wa,--32 -Wl,-m32 --ieee=synopsys -fexplicit --workdir=work
-Pwork tb_lm_cpu
# ghdl -e -Wa,--32 -Wl,-m32 -Wl,emulator_src.o -Wl,gdb_sim.o
-Wl,-lpthread --ieee=synopsys --workdir=work -Pwork tb_lm_cpu
ghdl -e -Wl,gdb_sim.o -Wl,-lpthread --ieee=synopsys --workdir=work
-Pwork tb_lm_cpu
ghdl -r tb_lm_cpu --wave=tbench.ghw --stop-time=50us
# ghdl -r tbench --disp-tree=inst --wave=tbench.ghw
view:
gtkwave tbench.ghw a.sav
--------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 21:08:31 05/17/2011
-- Design Name:
-- Autor : R.Doss
-- Target Device:
-- Tool versions:
-- Description:
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.gdb_pack.all;
entity tb_lm_cpu is
end tb_lm_cpu;
architecture behavior of tb_lm_cpu is
--Inputs
signal board_clk : std_logic := '0';
signal reset : std_logic := '0';
signal HW_INT : std_logic := '0';
--Outputs
-- Clock period definitions
constant board_clk_period : time := 12.5 ns;
begin
-- Clock process definitions
board_clk_process : process
begin
board_clk <= '0';
wait for board_clk_period/2;
board_clk <= '1';
wait for board_clk_period/2;
end process;
-- intb : process
-- begin
-- wait for 10 ns;
-- reset<='1';
-- wait for 800 ns;
-- reset <= '0';
-- insert stimulus here
-- end process;
gdb_init : process
variable i: integer ;
begin
i:=wait_for_connect(2020);
wait;
end process;
end;
_______________________________________________
Ghdl-discuss mailing list
[email protected]
https://mail.gna.org/listinfo/ghdl-discuss