123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- #include <stdio.h>
- #include <stdbool.h>
- #include <stdint.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/mman.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include "sim_vhpi_c.h"
- #undef DEBUG
- #define ALIGN_UP(VAL, SIZE) (((VAL) + ((SIZE)-1)) & ~((SIZE)-1))
- #define MAX_REGIONS 128
- struct ram_behavioural {
- char *filename;
- unsigned long size;
- void *m;
- };
- static struct ram_behavioural behavioural_regions[MAX_REGIONS];
- static unsigned long region_nr;
- unsigned long behavioural_initialize(void *__f, unsigned long size)
- {
- struct ram_behavioural *r;
- int fd;
- struct stat buf;
- unsigned long tmp_size;
- void *mem;
- if (region_nr == MAX_REGIONS) {
- fprintf(stderr, "%s: too many regions, bump MAX_REGIONS\n", __func__);
- exit(1);
- }
- r = &behavioural_regions[region_nr];
- r->filename = from_string(__f);
- r->size = ALIGN_UP(size, getpagesize());
- fd = open(r->filename, O_RDWR);
- if (fd == -1) {
- fprintf(stderr, "%s: could not open %s\n", __func__,
- r->filename);
- exit(1);
- }
- if (fstat(fd, &buf)) {
- perror("fstat");
- exit(1);
- }
- /* XXX Do we need to truncate the underlying file? */
- tmp_size = ALIGN_UP(buf.st_size, getpagesize());
- if (r->size > tmp_size) {
- void *m;
- /*
- * We have to pad the file. Allocate the total size, then
- * create a space for the file.
- */
- mem = mmap(NULL, r->size, PROT_READ|PROT_WRITE,
- MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
- if (mem == MAP_FAILED) {
- perror("mmap");
- exit(1);
- }
- if (tmp_size) {
- munmap(mem, tmp_size);
- m = mmap(mem, tmp_size, PROT_READ|PROT_WRITE,
- MAP_PRIVATE|MAP_FIXED, fd, 0);
- if (m == MAP_FAILED) {
- perror("mmap");
- exit(1);
- }
- if (m != mem) {
- fprintf(stderr, "%s: mmap(MAP_FIXED) failed\n",
- __func__);
- exit(1);
- }
- }
- } else {
- mem = mmap(NULL, tmp_size, PROT_READ|PROT_WRITE, MAP_PRIVATE,
- fd, 0);
- if (mem == MAP_FAILED) {
- perror("mmap");
- exit(1);
- }
- }
- behavioural_regions[region_nr].m = mem;
- return region_nr++;
- }
- void behavioural_read(unsigned char *__val, unsigned char *__addr,
- unsigned long sel, int identifier)
- {
- struct ram_behavioural *r;
- unsigned long val = 0;
- unsigned long addr = from_std_logic_vector(__addr, 64);
- unsigned char *p;
- if (identifier > region_nr) {
- fprintf(stderr, "%s: bad index %d\n", __func__, identifier);
- exit(1);
- }
- r = &behavioural_regions[identifier];
- for (unsigned long i = 0; i < 8; i++) {
- #if 0
- /* sel only used on writes */
- if (!(sel & (1UL << i)))
- continue;
- #endif
- if ((addr + i) > r->size) {
- fprintf(stderr, "%s: bad memory access %lx %lx\n", __func__,
- addr+i, r->size);
- exit(1);
- }
- p = (unsigned char *)(((unsigned long)r->m) + addr + i);
- val |= (((unsigned long)*p) << (i*8));
- }
- #ifdef DEBUG
- printf("MEM behave %d read %016lx addr %016lx sel %02lx\n", identifier, val,
- addr, sel);
- #endif
- to_std_logic_vector(val, __val, 64);
- }
- void behavioural_write(unsigned char *__val, unsigned char *__addr,
- unsigned int sel, int identifier)
- {
- struct ram_behavioural *r;
- unsigned long val = from_std_logic_vector(__val, 64);
- unsigned long addr = from_std_logic_vector(__addr, 64);
- unsigned char *p;
- if (identifier > region_nr) {
- fprintf(stderr, "%s: bad index %d\n", __func__, identifier);
- exit(1);
- }
- r = &behavioural_regions[identifier];
- p = (unsigned char *)(((unsigned long)r->m) + addr);
- #ifdef DEBUG
- printf("MEM behave %d write %016lx addr %016lx sel %02x\n", identifier, val,
- addr, sel);
- #endif
- for (unsigned long i = 0; i < 8; i++) {
- if (!(sel & (1UL << i)))
- continue;
- if ((addr + i) > r->size) {
- fprintf(stderr, "%s: bad memory access %lx %lx\n", __func__,
- addr+i, r->size);
- exit(1);
- }
- p = (unsigned char *)(((unsigned long)r->m) + addr + i);
- *p = (val >> (i*8)) & 0xff;
- }
- }
|