14 #define ALIGN_UP(VAL, SIZE) (((VAL) + ((SIZE)-1)) & ~((SIZE)-1))
16 #define vhpi0 2 /* forcing 0 */
17 #define vhpi1 3 /* forcing 1 */
30 struct int_bounds
*bounds
;
33 static char *from_string(void *__p
)
35 struct fat_pointer
*p
= __p
;
36 unsigned long len
= p
->bounds
->len
;
45 memcpy(m
, p
->base
, len
);
51 static uint64_t from_std_logic_vector(unsigned char *p
, unsigned long len
)
53 unsigned long ret
= 0;
56 fprintf(stderr
, "%s: invalid length %lu\n", __func__
, len
);
60 for (unsigned long i
= 0; i
< len
; i
++) {
65 } else if (*p
== vhpi1
) {
68 fprintf(stderr
, "%s: bad bit %d\n", __func__
, *p
);
72 ret
= (ret
<< 1) | bit
;
79 static void to_std_logic_vector(unsigned long val
, unsigned char *p
,
83 fprintf(stderr
, "%s: invalid length %lu\n", __func__
, len
);
87 for (unsigned long i
= 0; i
< len
; i
++) {
88 if ((val
>> (len
-1-i
) & 1))
97 #define MAX_REGIONS 128
99 struct ram_behavioural
{
105 static struct ram_behavioural behavioural_regions
[MAX_REGIONS
];
106 static unsigned long region_nr
;
108 unsigned long behavioural_initialize(void *__f
, unsigned long size
)
110 struct ram_behavioural
*r
;
113 unsigned long tmp_size
;
116 if (region_nr
== MAX_REGIONS
) {
117 fprintf(stderr
, "%s: too many regions, bump MAX_REGIONS\n", __func__
);
121 r
= &behavioural_regions
[region_nr
];
123 r
->filename
= from_string(__f
);
124 r
->size
= ALIGN_UP(size
, getpagesize());
126 fd
= open(r
->filename
, O_RDWR
);
128 fprintf(stderr
, "%s: could not open %s\n", __func__
,
133 if (fstat(fd
, &buf
)) {
138 /* XXX Do we need to truncate the underlying file? */
139 tmp_size
= ALIGN_UP(buf
.st_size
, getpagesize());
141 if (r
->size
> tmp_size
) {
145 * We have to pad the file. Allocate the total size, then
146 * create a space for the file.
148 mem
= mmap(NULL
, r
->size
, PROT_READ
|PROT_WRITE
,
149 MAP_PRIVATE
|MAP_ANONYMOUS
, -1, 0);
150 if (mem
== MAP_FAILED
) {
156 munmap(mem
, tmp_size
);
158 m
= mmap(mem
, tmp_size
, PROT_READ
|PROT_WRITE
,
159 MAP_PRIVATE
|MAP_FIXED
, fd
, 0);
160 if (m
== MAP_FAILED
) {
165 fprintf(stderr
, "%s: mmap(MAP_FIXED) failed\n",
171 mem
= mmap(NULL
, tmp_size
, PROT_READ
|PROT_WRITE
, MAP_PRIVATE
,
173 if (mem
== MAP_FAILED
) {
179 behavioural_regions
[region_nr
].m
= mem
;
183 void behavioural_read(unsigned char *__val
, unsigned char *__addr
,
184 unsigned long sel
, int identifier
)
186 struct ram_behavioural
*r
;
187 unsigned long val
= 0;
188 unsigned long addr
= from_std_logic_vector(__addr
, 64);
191 if (identifier
> region_nr
) {
192 fprintf(stderr
, "%s: bad index %d\n", __func__
, identifier
);
196 r
= &behavioural_regions
[identifier
];
198 for (unsigned long i
= 0; i
< 8; i
++) {
200 /* sel only used on writes */
201 if (!(sel
& (1UL << i
)))
205 if ((addr
+ i
) > r
->size
) {
206 fprintf(stderr
, "%s: bad memory access %lx %lx\n", __func__
,
211 p
= (unsigned char *)(((unsigned long)r
->m
) + addr
+ i
);
212 val
|= (((unsigned long)*p
) << (i
*8));
216 printf("MEM behave %d read %016lx addr %016lx sel %02lx\n", identifier
, val
,
220 to_std_logic_vector(val
, __val
, 64);
223 void behavioural_write(unsigned char *__val
, unsigned char *__addr
,
224 unsigned int sel
, int identifier
)
226 struct ram_behavioural
*r
;
227 unsigned long val
= from_std_logic_vector(__val
, 64);
228 unsigned long addr
= from_std_logic_vector(__addr
, 64);
231 if (identifier
> region_nr
) {
232 fprintf(stderr
, "%s: bad index %d\n", __func__
, identifier
);
236 r
= &behavioural_regions
[identifier
];
238 p
= (unsigned char *)(((unsigned long)r
->m
) + addr
);
241 printf("MEM behave %d write %016lx addr %016lx sel %02x\n", identifier
, val
,
245 for (unsigned long i
= 0; i
< 8; i
++) {
246 if (!(sel
& (1UL << i
)))
249 if ((addr
+ i
) > r
->size
) {
250 fprintf(stderr
, "%s: bad memory access %lx %lx\n", __func__
,
255 p
= (unsigned char *)(((unsigned long)r
->m
) + addr
+ i
);
256 *p
= (val
>> (i
*8)) & 0xff;