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

Reply via email to