12 #include "sim_vhpi_c.h"
16 #define ALIGN_UP(VAL, SIZE) (((VAL) + ((SIZE)-1)) & ~((SIZE)-1))
18 #define MAX_REGIONS 128
20 struct ram_behavioural
{
26 static struct ram_behavioural behavioural_regions
[MAX_REGIONS
];
27 static unsigned long region_nr
;
29 unsigned long behavioural_initialize(void *__f
, unsigned long size
)
31 struct ram_behavioural
*r
;
34 unsigned long tmp_size
;
37 if (region_nr
== MAX_REGIONS
) {
38 fprintf(stderr
, "%s: too many regions, bump MAX_REGIONS\n", __func__
);
42 r
= &behavioural_regions
[region_nr
];
44 r
->filename
= from_string(__f
);
45 r
->size
= ALIGN_UP(size
, getpagesize());
47 fd
= open(r
->filename
, O_RDWR
);
49 fprintf(stderr
, "%s: could not open %s\n", __func__
,
54 if (fstat(fd
, &buf
)) {
59 /* XXX Do we need to truncate the underlying file? */
60 tmp_size
= ALIGN_UP(buf
.st_size
, getpagesize());
62 if (r
->size
> tmp_size
) {
66 * We have to pad the file. Allocate the total size, then
67 * create a space for the file.
69 mem
= mmap(NULL
, r
->size
, PROT_READ
|PROT_WRITE
,
70 MAP_PRIVATE
|MAP_ANONYMOUS
, -1, 0);
71 if (mem
== MAP_FAILED
) {
77 munmap(mem
, tmp_size
);
79 m
= mmap(mem
, tmp_size
, PROT_READ
|PROT_WRITE
,
80 MAP_PRIVATE
|MAP_FIXED
, fd
, 0);
81 if (m
== MAP_FAILED
) {
86 fprintf(stderr
, "%s: mmap(MAP_FIXED) failed\n",
92 mem
= mmap(NULL
, tmp_size
, PROT_READ
|PROT_WRITE
, MAP_PRIVATE
,
94 if (mem
== MAP_FAILED
) {
100 behavioural_regions
[region_nr
].m
= mem
;
104 void behavioural_read(unsigned char *__val
, unsigned char *__addr
,
105 unsigned long sel
, int identifier
)
107 struct ram_behavioural
*r
;
108 unsigned long val
= 0;
109 unsigned long addr
= from_std_logic_vector(__addr
, 64);
112 if (identifier
> region_nr
) {
113 fprintf(stderr
, "%s: bad index %d\n", __func__
, identifier
);
117 r
= &behavioural_regions
[identifier
];
119 for (unsigned long i
= 0; i
< 8; i
++) {
121 /* sel only used on writes */
122 if (!(sel
& (1UL << i
)))
126 if ((addr
+ i
) > r
->size
) {
127 fprintf(stderr
, "%s: bad memory access %lx %lx\n", __func__
,
132 p
= (unsigned char *)(((unsigned long)r
->m
) + addr
+ i
);
133 val
|= (((unsigned long)*p
) << (i
*8));
137 printf("MEM behave %d read %016lx addr %016lx sel %02lx\n", identifier
, val
,
141 to_std_logic_vector(val
, __val
, 64);
144 void behavioural_write(unsigned char *__val
, unsigned char *__addr
,
145 unsigned int sel
, int identifier
)
147 struct ram_behavioural
*r
;
148 unsigned long val
= from_std_logic_vector(__val
, 64);
149 unsigned long addr
= from_std_logic_vector(__addr
, 64);
152 if (identifier
> region_nr
) {
153 fprintf(stderr
, "%s: bad index %d\n", __func__
, identifier
);
157 r
= &behavioural_regions
[identifier
];
159 p
= (unsigned char *)(((unsigned long)r
->m
) + addr
);
162 printf("MEM behave %d write %016lx addr %016lx sel %02x\n", identifier
, val
,
166 for (unsigned long i
= 0; i
< 8; i
++) {
167 if (!(sel
& (1UL << i
)))
170 if ((addr
+ i
) > r
->size
) {
171 fprintf(stderr
, "%s: bad memory access %lx %lx\n", __func__
,
176 p
= (unsigned char *)(((unsigned long)r
->m
) + addr
+ i
);
177 *p
= (val
>> (i
*8)) & 0xff;