diff --git a/litex/gen/vpi/Makefile b/litex/gen/vpi/Makefile deleted file mode 100644 index 5f4ed341a..000000000 --- a/litex/gen/vpi/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -INSTDIR = $(shell iverilog-vpi --install-dir) - -CFLAGS = -Wall -O2 $(CFLAGS_$@) -VPI_CFLAGS := $(shell iverilog-vpi --cflags) -# Define the below flags for a Windows build. -# Make sure to run iverilog-vpi with -mingw and -ivl options if necessary! -# i.e. iverilog-vpi -mingw=C:\msys64\mingw32 -ivl=C:\msys64\mingw32 -# MINGW_FLAGS=-lWs2_32 - -OBJ=ipc.o main.o - -all: migensim.vpi - -%.o: %.c - $(CC) $(CFLAGS) $(VPI_CFLAGS) -c $(INCDIRS) -o $@ $< - -migensim.vpi: $(OBJ) - iverilog-vpi $(MINGW_FLAGS) --name=migensim $^ - -install: migensim.vpi - install -m755 -t $(INSTDIR) $^ - -clean: - rm -f $(OBJ) - rm -f migensim.vpi - -.PHONY: install clean diff --git a/litex/gen/vpi/ipc.c b/litex/gen/vpi/ipc.c deleted file mode 100644 index a51004165..000000000 --- a/litex/gen/vpi/ipc.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (C) 2012 Vermeer Manufacturing Co. - * License: GPLv3 with additional permissions (see README). - */ - -#ifdef _WIN32 -#define WINVER 0x501 -#endif - -#include -#include -#include -#include -#include -#include - -#ifdef _WIN32 -#include -#include -#else -#include -#include -#endif - - -#include "ipc.h" - -struct ipc_softc { - int socket; - go_handler h_go; - write_handler h_write; - read_handler h_read; - void *user; -}; - -#define MAX_LEN 2048 - -#ifdef _WIN32 -#define HEADER_LEN 2 -#define SOCKET_PORT "50007" - -unsigned char ipc_rxbuffer[2*MAX_LEN]; -int ipc_rxlen; -#else -#define HEADER_LEN 0 -#endif - -struct ipc_softc *ipc_connect(const char *sockaddr, - go_handler h_go, write_handler h_write, read_handler h_read, void *user) -{ - struct ipc_softc *sc; -#ifdef _WIN32 - struct addrinfo hints, *my_addrinfo; - WSADATA wsaData; - ipc_rxlen = 0; -#else - struct sockaddr_un addr; -#endif - - sc = malloc(sizeof(struct ipc_softc)); - if(!sc) return NULL; - - sc->h_go = h_go; - sc->h_write = h_write; - sc->h_read = h_read; - sc->user = user; - -#ifdef _WIN32 - /* Initialize Winsock. */ - if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { - free(sc); - return NULL; - } - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - - if(getaddrinfo(sockaddr, SOCKET_PORT, NULL, &my_addrinfo) != 0) { - free(sc); - return NULL; - } - - sc->socket = socket(AF_INET, SOCK_STREAM, 0); - if(sc->socket < 0) { - free(sc); - return NULL; - } - - if(connect(sc->socket, my_addrinfo->ai_addr, my_addrinfo->ai_addrlen) != 0) { - close(sc->socket); - free(sc); - return NULL; - } -#else - sc->socket = socket(AF_UNIX, SOCK_SEQPACKET, 0); - if(sc->socket < 0) { - free(sc); - return NULL; - } - - addr.sun_family = AF_UNIX; - strcpy(addr.sun_path, sockaddr); - if(connect(sc->socket, (struct sockaddr *)&addr, sizeof(addr)) != 0) { - close(sc->socket); - free(sc); - return NULL; - } -#endif - - return sc; -} - -void ipc_destroy(struct ipc_softc *sc) -{ - close(sc->socket); - free(sc); -#ifdef _WIN32 - WSACleanup(); -#endif -} - -enum { - MESSAGE_TICK = 0, - MESSAGE_GO, - MESSAGE_WRITE, - MESSAGE_READ, - MESSAGE_READ_REPLY -}; - -static int ipc_receive_packet(struct ipc_softc *sc, unsigned char *buffer) { -#ifdef _WIN32 - int len; - int packet_len; - /* ensure we have packet header */ - while(ipc_rxlen < HEADER_LEN) { - len = recv(sc->socket, (char *)&ipc_rxbuffer[ipc_rxlen], MAX_LEN, 0); - if(len) - ipc_rxlen += len; - } - - /* compute packet length and ensure we have the payload */ - packet_len = (ipc_rxbuffer[1] << 8) | ipc_rxbuffer[0]; - while(ipc_rxlen < packet_len) { - len = recv(sc->socket, (char *)&ipc_rxbuffer[ipc_rxlen], MAX_LEN, 0); - if(len) - ipc_rxlen += len; - } - - /* copy packet to buffer */ - memcpy(buffer, ipc_rxbuffer + HEADER_LEN, packet_len - HEADER_LEN); - - /* prepare ipc_rxbuffer for next packet */ - ipc_rxlen = ipc_rxlen - packet_len; - memcpy(ipc_rxbuffer, ipc_rxbuffer + packet_len, ipc_rxlen); - - return packet_len - HEADER_LEN; -#else - return recv(sc->socket, buffer, MAX_LEN, 0); -#endif -} - -/* - * 0 -> error - * 1 -> success - * 2 -> graceful shutdown - */ -int ipc_receive(struct ipc_softc *sc) -{ - unsigned char buffer[MAX_LEN]; - ssize_t l = 0; - int i; - - l = ipc_receive_packet(sc, (unsigned char *)&buffer); - if(l == 0) - return 2; - if((l < 0) || (l >= MAX_LEN)) - return 0; - i = 0; - - switch(buffer[i++]) { - case MESSAGE_GO: - assert((l - i) == 0); - - return sc->h_go(sc->user); - case MESSAGE_WRITE: { - char *name; - int nchunks; - unsigned char *chunks; - unsigned int chunk_index; - - name = (char *)&buffer[i]; - i += strlen(name) + 1; - assert((i+4) < l); - chunk_index = buffer[i] | buffer[i+1] << 8 | buffer[i+2] << 16 | buffer[i+3] << 24; - i += 4; - nchunks = buffer[i++]; - assert(i + nchunks == l); - chunks = (unsigned char *)&buffer[i]; - - return sc->h_write(name, chunk_index, nchunks, chunks, sc->user); - } - case MESSAGE_READ: { - char *name; - unsigned int name_index; - - name = (char *)&buffer[i]; - i += strlen(name) + 1; - assert((i+4) == l); - name_index = buffer[i] | buffer[i+1] << 8 | buffer[i+2] << 16 | buffer[i+3] << 24; - - return sc->h_read(name, name_index, sc->user); - } - default: - return 0; - } -} - -int ipc_tick(struct ipc_softc *sc) -{ - ssize_t l; - char c[HEADER_LEN + 1]; - -#ifdef _WIN32 - c[0] = 3; - c[1] = 0; -#endif - c[HEADER_LEN + 0] = MESSAGE_TICK; - l = send(sc->socket, c, HEADER_LEN + 1, 0); - if(l != (HEADER_LEN + 1)) - return 0; - - return 1; -} - -int ipc_read_reply(struct ipc_softc *sc, int nchunks, const unsigned char *chunks) -{ - int len; - char buffer[MAX_LEN]; - ssize_t l; - - len = nchunks + HEADER_LEN + 2; - assert(len < MAX_LEN); - assert(nchunks < 256); - -#ifdef _WIN32 - buffer[0] = len & 0xFF; - buffer[1] = (0xFF00 & len) >> 8; -#endif - buffer[HEADER_LEN + 0] = MESSAGE_READ_REPLY; - buffer[HEADER_LEN + 1] = nchunks; - memcpy(&buffer[HEADER_LEN + 2], chunks, nchunks); - - l = send(sc->socket, buffer, len, 0); - if(l != len) - return 0; - return 1; -} - diff --git a/litex/gen/vpi/ipc.h b/litex/gen/vpi/ipc.h deleted file mode 100644 index 184858eea..000000000 --- a/litex/gen/vpi/ipc.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2012 Vermeer Manufacturing Co. - * License: GPLv3 with additional permissions (see README). - */ - -#ifndef __IPC_H -#define __IPC_H - -struct ipc_softc; - -typedef int(*go_handler)(void *); -typedef int(*write_handler)(char *, int, int, const unsigned char *, void *); -typedef int(*read_handler)(char *, int, void *); - -struct ipc_softc *ipc_connect(const char *sockaddr, - go_handler h_go, write_handler h_write, read_handler h_read, void *user); -void ipc_destroy(struct ipc_softc *sc); - -int ipc_receive(struct ipc_softc *sc); - -int ipc_tick(struct ipc_softc *sc); -int ipc_read_reply(struct ipc_softc *sc, int nchunks, const unsigned char *value); - -#endif /* __IPC_H */ diff --git a/litex/gen/vpi/main.c b/litex/gen/vpi/main.c deleted file mode 100644 index 74c13fd46..000000000 --- a/litex/gen/vpi/main.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (C) 2012 Vermeer Manufacturing Co. - * License: GPLv3 with additional permissions (see README). - */ - -#include -#include -#include -#include - -#include "ipc.h" - -struct migensim_softc { - struct ipc_softc *ipc; - int has_go; -}; - -static int h_go(void *user) -{ - struct migensim_softc *sc = (struct migensim_softc *)user; - sc->has_go = 1; - return 1; -} - -static s_vpi_time zero_delay = { - .type = vpiSimTime, - .high = 0, - .low = 0 -}; - -static int h_write(char *name, int index, int nchunks, const unsigned char *chunks, void *user) -{ - vpiHandle item; - s_vpi_vecval vector[64]; - int i; - s_vpi_value value; - - item = vpi_handle_by_name(name, NULL); - if(item == NULL) { - fprintf(stderr, "Attempted to write non-existing signal %s\n", name); - return 0; - } - if(vpi_get(vpiType, item) == vpiMemory) - item = vpi_handle_by_index(item, index); - else - assert(index == 0); - - assert(nchunks <= 255); - for(i=0;i<64;i++) { - vector[i].aval = 0; - vector[i].bval = 0; - } - for(i=0;i> 8; - break; - case 2: - chunks[i] = (vals[i/4] & 0xff0000) >> 16; - break; - case 3: - chunks[i] = (vals[i/4] & 0xff000000) >> 24; - break; - } - } - - if(!ipc_read_reply(sc->ipc, nchunks, chunks)) { - perror("ipc_read_reply"); - return 0; - } - - return 1; -} - -static int process_until_go(struct migensim_softc *sc) -{ - int r; - - sc->has_go = 0; - while(!sc->has_go) { - r = ipc_receive(sc->ipc); - if(r != 1) - return r; - } - return 1; -} - -static PLI_INT32 connect_calltf(PLI_BYTE8 *user) -{ - struct migensim_softc *sc = (struct migensim_softc *)user; - vpiHandle sys; - vpiHandle argv; - vpiHandle item; - s_vpi_value value; - - sys = vpi_handle(vpiSysTfCall, 0); - argv = vpi_iterate(vpiArgument, sys); - item = vpi_scan(argv); - value.format = vpiStringVal; - vpi_get_value(item, &value); - - sc->ipc = ipc_connect(value.value.str, h_go, h_write, h_read, sc); - if(sc->ipc == NULL) { - perror("ipc_connect"); - vpi_control(vpiFinish, 1); - return 0; - } - - return 0; -} - -static PLI_INT32 tick_calltf(PLI_BYTE8 *user) -{ - struct migensim_softc *sc = (struct migensim_softc *)user; - int r; - - if(!ipc_tick(sc->ipc)) { - perror("ipc_tick"); - vpi_control(vpiFinish, 1); - ipc_destroy(sc->ipc); - sc->ipc = NULL; - return 0; - } - r = process_until_go(sc); - if(r != 1) { - vpi_control(vpiFinish, r == 2 ? 0 : 1); - ipc_destroy(sc->ipc); - sc->ipc = NULL; - return 0; - } - - return 0; -} - -static struct migensim_softc sc; - -static void simple_register(const char *tfname, PLI_INT32 (*calltf)(PLI_BYTE8 *)) -{ - s_vpi_systf_data tf_data; - - tf_data.type = vpiSysTask; - tf_data.tfname = tfname; - tf_data.calltf = calltf; - tf_data.compiletf = NULL; - tf_data.sizetf = 0; - tf_data.user_data = (void *)≻ - vpi_register_systf(&tf_data); -} - -static void migensim_register() -{ - simple_register("$migensim_connect", connect_calltf); - simple_register("$migensim_tick", tick_calltf); -} - -void (*vlog_startup_routines[])() = { - migensim_register, - 0 -};