Skip to content

Instantly share code, notes, and snippets.

@dmitrodem
Created September 23, 2019 06:54
Show Gist options
  • Save dmitrodem/6e1f169e26f95e0d7a91fd63b250b5da to your computer and use it in GitHub Desktop.
Save dmitrodem/6e1f169e26f95e0d7a91fd63b250b5da to your computer and use it in GitHub Desktop.
Verilog VPI example
#include <vpi_user.h>
#include <stdint.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <string.h>
#define CHUNKSIZE 32
int sockfd = 0;
static int compiletf_udp(char *userdata) {
struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
char *s = getenv("SIM_SOCKET");
if (s == NULL) {
vpi_printf("Set environment variable SIM_SOCKET\n");
exit(-1);
}
strncpy(addr.sun_path, s, sizeof(addr.sun_path) - 1);
sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);
if (connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
perror("Failed to connect to SIM_SOCKET");
exit(-1);
}
return 0;
}
static int systf_udp(char *userdata) {
p_vpi_error_info err;
vpiHandle systfref, args_iter, args_handle;
if (sockfd == 0) {
vpi_printf("SIM_SOCKET is not opened\n");
return 0;
}
systfref = vpi_handle(vpiSysTfCall, NULL);
if (systfref == NULL) {
vpi_printf("Failed to get task handle\n");
return 0;
}
args_iter = vpi_iterate(vpiArgument, systfref);
if (args_iter == NULL) {
if (vpi_chk_error(err)) {
vpi_printf("%s\n", err->message);
}
vpi_printf("Failed to get arguments handle\n");
return 0;
}
uint32_t *buf = malloc(sizeof(uint32_t) * CHUNKSIZE);
size_t i = 0;
while((args_handle = vpi_scan(args_iter)) != NULL) {
struct t_vpi_value argval;
argval.format = vpiIntVal;
vpi_get_value(args_handle, &argval);
if ((i > 0) && ((i % CHUNKSIZE) == 0)) {
buf = realloc(buf, sizeof(uint32_t) * i);
}
buf[i] = argval.value.integer;
i++;
}
send(sockfd, buf, sizeof(uint32_t) * i, 0);
free(buf);
return 0;
}
void register_udp() {
s_vpi_systf_data s = {vpiSysTask, vpiSysTask, "$send_udp", systf_udp, compiletf_udp, NULL, NULL};
vpi_register_systf(&s);
}
void (*vlog_startup_routines[])() = {
register_udp,
0
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment