OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [branches/] [stable_0_2_x/] [or1ksim/] [peripheral/] [memory.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1486 nogj
/* memory.c -- Generic memory model
2
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
3
   Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
4
 
5
This file is part of OpenRISC 1000 Architectural Simulator.
6
 
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or
10
(at your option) any later version.
11
 
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
 
21
#include <stdio.h>
22
#include <time.h>
23
#include <string.h>
24
 
25
#include "config.h"
26
 
27
#ifdef HAVE_INTTYPES_H
28
#include <inttypes.h>
29
#endif
30
 
31
#include "port.h"
32
#include "arch.h"
33
#include "abstract.h"
34
#include "sim-config.h"
35
 
36
struct mem_config {
37
  int ce;                         /* Which ce this memory is associated with */
38
  int mc;                         /* Which mc this memory is connected to */
39
  oraddr_t baseaddr;              /* Start address of the memory */
40
  unsigned int size;              /* Memory size */
41
  char *name;                     /* Memory type string */
42
  char *log;                      /* Memory log filename */
43
  int delayr;                     /* Read cycles */
44
  int delayw;                     /* Write cycles */
45
 
46
  void *mem;                      /* malloced memory for this memory */
47
 
48
  int pattern;                    /* A user specified memory initialization
49
                                   * pattern */
50
  int random_seed;                /* Initialize the memory with random values,
51
                                   * starting with seed */
52
  enum {
53
    MT_UNKNOWN,
54
    MT_PATTERN,
55
    MT_RANDOM
56
  } type;
57
};
58
 
59
uint32_t simmem_read32(oraddr_t addr, void *dat)
60
{
61
  return *(uint32_t *)(dat + addr);
62
}
63
 
64
uint16_t simmem_read16(oraddr_t addr, void *dat)
65
{
66 1586 nogj
#ifdef WORDS_BIGENDIAN
67
  return *(uint16_t *)(dat + addr);
68
#else
69 1486 nogj
  return *(uint16_t *)(dat + (addr ^ 2));
70 1586 nogj
#endif
71 1486 nogj
}
72
 
73
uint8_t simmem_read8(oraddr_t addr, void *dat)
74
{
75 1586 nogj
#ifdef WORDS_BIGENDIAN
76
  return *(uint8_t *)(dat + addr);
77
#else
78 1557 nogj
  return *(uint8_t *)(dat + ((addr & ~ADDR_C(3)) | (3 - (addr & 3))));
79 1586 nogj
#endif
80 1486 nogj
}
81
 
82
void simmem_write32(oraddr_t addr, uint32_t value, void *dat)
83
{
84
  *(uint32_t *)(dat + addr) = value;
85
}
86
 
87
void simmem_write16(oraddr_t addr, uint16_t value, void *dat)
88
{
89 1586 nogj
#ifdef WORDS_BIGENDIAN
90
  *(uint16_t *)(dat + addr) = value;
91
#else
92 1486 nogj
  *(uint16_t *)(dat + (addr ^ 2)) = value;
93 1586 nogj
#endif
94 1486 nogj
}
95
 
96
void simmem_write8(oraddr_t addr, uint8_t value, void *dat)
97
{
98 1586 nogj
#ifdef WORDS_BIGENDIAN
99
  *(uint8_t *)(dat + addr) = value;
100
#else
101 1557 nogj
  *(uint8_t *)(dat + ((addr & ~ADDR_C(3)) | (3 - (addr & 3)))) = value;
102 1586 nogj
#endif
103 1486 nogj
}
104
 
105
uint32_t simmem_read_zero32(oraddr_t addr, void *dat)
106
{
107
  if (config.sim.verbose)
108
    fprintf (stderr, "WARNING: 32-bit memory read from non-read memory area 0x%"
109
                     PRIxADDR".\n", addr);
110
  return 0;
111
}
112
 
113
uint16_t simmem_read_zero16(oraddr_t addr, void *dat)
114
{
115
  if (config.sim.verbose)
116
    fprintf (stderr, "WARNING: 16-bit memory read from non-read memory area 0x%"
117
                     PRIxADDR".\n", addr);
118
  return 0;
119
}
120
 
121
uint8_t simmem_read_zero8(oraddr_t addr, void *dat)
122
{
123
  if (config.sim.verbose)
124
    fprintf (stderr, "WARNING: 8-bit memory read from non-read memory area 0x%"
125
                     PRIxADDR".\n", addr);
126
  return 0;
127
}
128
 
129
void simmem_write_null32(oraddr_t addr, uint32_t value, void *dat)
130
{
131
  if (config.sim.verbose)
132
    fprintf (stderr, "WARNING: 32-bit memory write to 0x%"PRIxADDR", non-write "
133
                     "memory area (value 0x%08"PRIx32").\n", addr, value);
134
}
135
 
136
void simmem_write_null16(oraddr_t addr, uint16_t value, void *dat)
137
{
138
  if (config.sim.verbose)
139
    fprintf (stderr, "WARNING: 16-bit memory write to 0x%"PRIxADDR", non-write "
140
                     "memory area (value 0x%08"PRIx32").\n", addr, value);
141
}
142
 
143
void simmem_write_null8(oraddr_t addr, uint8_t value, void *dat)
144
{
145
  if (config.sim.verbose)
146
    fprintf (stderr, "WARNING: 8-bit memory write to 0x%"PRIxADDR", non-write "
147
                     "memory area (value 0x%08"PRIx32").\n", addr, value);
148
}
149
 
150
void mem_reset(void *dat)
151
{
152
  struct mem_config *mem = dat;
153
  int seed;
154
  int i;
155
  uint8_t *mem_area = mem->mem;
156
 
157
  /* Initialize memory */
158
  switch(mem->type) {
159
  case MT_RANDOM:
160
    if (mem->random_seed == -1) {
161
      seed = time(NULL);
162
      /* Print out the seed just in case we ever need to debug */
163
      PRINTF("Seeding random generator with value %d\n", seed);
164
    } else
165
      seed = mem->random_seed;
166
    srandom(seed);
167
 
168
    for(i = 0; i < mem->size; i++, mem_area++)
169
      *mem_area = random() & 0xFF;
170
    break;
171
  case MT_PATTERN:
172
    for(i = 0; i < mem->size; i++, mem_area++)
173
      *mem_area = mem->pattern;
174
    break;
175
  case MT_UNKNOWN:
176
    break;
177
  default:
178
    fprintf(stderr, "Invalid memory configuration type.\n");
179
    exit(1);
180
  }
181
}
182
 
183
/*-------------------------------------------------[ Memory configuration ]---*/
184
void memory_random_seed(union param_val val, void *dat)
185
{
186
  struct mem_config *mem = dat;
187
  mem->random_seed = val.int_val;
188
}
189
 
190
void memory_pattern(union param_val val, void *dat)
191
{
192
  struct mem_config *mem = dat;
193
  mem->pattern = val.int_val;
194
}
195
 
196
void memory_type(union param_val val, void *dat)
197
{
198
  struct mem_config *mem = dat;
199
  if(!strcmp(val.str_val, "unknown"))
200
    mem->type = MT_UNKNOWN;
201
  else if(!strcmp (val.str_val, "random"))
202
    mem->type = MT_RANDOM;
203
  else if(!strcmp (val.str_val, "pattern"))
204
    mem->type = MT_PATTERN;
205
  else if(!strcmp (val.str_val, "zero")) {
206
    mem->type = MT_PATTERN;
207
    mem->pattern = 0;
208
  } else {
209
    char tmp[200];
210
    sprintf (tmp, "invalid memory type '%s'.\n", val.str_val);
211
    CONFIG_ERROR(tmp);
212
  }
213
}
214
 
215
void memory_ce(union param_val val, void *dat)
216
{
217
  struct mem_config *mem = dat;
218
  mem->ce = val.int_val;
219
}
220
 
221
void memory_mc(union param_val val, void *dat)
222
{
223
  struct mem_config *mem = dat;
224
  mem->mc = val.int_val;
225
}
226
 
227
void memory_baseaddr(union param_val val, void *dat)
228
{
229
  struct mem_config *mem = dat;
230
  mem->baseaddr = val.addr_val;
231
}
232
 
233
void memory_size(union param_val val, void *dat)
234
{
235
  struct mem_config *mem = dat;
236
  mem->size = val.int_val;
237
}
238
 
239
/* FIXME: Check use */
240
void memory_name(union param_val val, void *dat)
241
{
242
  struct mem_config *mem = dat;
243
  mem->name = strdup(val.str_val);
244
}
245
 
246
void memory_log(union param_val val, void *dat)
247
{
248
  struct mem_config *mem = dat;
249
  mem->log = strdup(val.str_val);
250
}
251
 
252
void memory_delayr(union param_val val, void *dat)
253
{
254
  struct mem_config *mem = dat;
255
  mem->delayr = val.int_val;
256
}
257
 
258
void memory_delayw(union param_val val, void *dat)
259
{
260
  struct mem_config *mem = dat;
261
  mem->delayw = val.int_val;
262
}
263
 
264
void *memory_sec_start(void)
265
{
266
  struct mem_config *mem = malloc(sizeof(struct mem_config));
267
 
268
  if(!mem) {
269
    fprintf(stderr, "Memory Peripheral: Run out of memory\n");
270
    exit(-1);
271
  }
272
  mem->size = 0;
273
  mem->log = NULL;
274
  mem->name = NULL;
275
  mem->delayr = 1;
276
  mem->delayw = 1;
277
  mem->random_seed = -1;
278
  mem->ce = -1;
279
  mem->mc = 0;
280
 
281
  return mem;
282
}
283
 
284
void memory_sec_end(void *dat)
285
{
286
  struct mem_config *mem = dat;
287
  struct dev_memarea *mema;
288
 
289
  struct mem_ops ops;
290
 
291
  if(!mem->size) {
292
    free(dat);
293
    return;
294
  }
295
 
296
  /* Round up to the next 32-bit boundry */
297
  if(mem->size & 3) {
298
    mem->size &= ~3;
299
    mem->size += 4;
300
  }
301
 
302
  if(!(mem->mem = malloc(mem->size))) {
303
    fprintf(stderr, "Unable to allocate memory at %"PRIxADDR", length %i\n",
304
            mem->baseaddr, mem->size);
305
    exit(-1);
306
  }
307
 
308
  if(mem->delayr > 0) {
309
    ops.readfunc32 = simmem_read32;
310
    ops.readfunc16 = simmem_read16;
311
    ops.readfunc8 = simmem_read8;
312
  } else {
313
    ops.readfunc32 = simmem_read_zero32;
314
    ops.readfunc16 = simmem_read_zero16;
315
    ops.readfunc8 = simmem_read_zero8;
316
  }
317
 
318
  if(mem->delayw > 0) {
319
    ops.writefunc32 = simmem_write32;
320
    ops.writefunc16 = simmem_write16;
321
    ops.writefunc8 = simmem_write8;
322
  } else {
323
    ops.writefunc32 = simmem_write_null32;
324
    ops.writefunc16 = simmem_write_null16;
325
    ops.writefunc8 = simmem_write_null8;
326
  }
327
 
328 1556 nogj
  ops.writeprog8 = simmem_write8;
329
  ops.writeprog32 = simmem_write32;
330
  ops.writeprog8_dat = mem->mem;
331
  ops.writeprog32_dat = mem->mem;
332 1486 nogj
 
333
  ops.read_dat32 = mem->mem;
334
  ops.read_dat16 = mem->mem;
335
  ops.read_dat8 = mem->mem;
336
 
337
  ops.write_dat32 = mem->mem;
338
  ops.write_dat16 = mem->mem;
339
  ops.write_dat8 = mem->mem;
340
 
341
  ops.delayr = mem->delayr;
342
  ops.delayw = mem->delayw;
343
 
344
  ops.log = mem->log;
345
 
346
  mema = reg_mem_area(mem->baseaddr, mem->size, 0, &ops);
347
 
348
  /* Set valid */
349
  /* FIXME: Should this be done during reset? */
350
  set_mem_valid(mema, 1);
351
 
352
  if(mem->ce >= 0)
353
    mc_reg_mem_area(mema, mem->ce, mem->mc);
354
 
355
  reg_sim_reset(mem_reset, dat);
356
}
357
 
358
void reg_memory_sec(void)
359
{
360
  struct config_section *sec = reg_config_sec("memory", memory_sec_start,
361
                                              memory_sec_end);
362
 
363
  reg_config_param(sec, "random_seed", paramt_int, memory_random_seed);
364
  reg_config_param(sec, "pattern", paramt_int, memory_pattern);
365
  reg_config_param(sec, "type", paramt_word, memory_type);
366
  reg_config_param(sec, "ce", paramt_int, memory_ce);
367
  reg_config_param(sec, "mc", paramt_int, memory_mc);
368
  reg_config_param(sec, "baseaddr", paramt_addr, memory_baseaddr);
369
  reg_config_param(sec, "size", paramt_int, memory_size);
370
  reg_config_param(sec, "name", paramt_str, memory_name);
371
  reg_config_param(sec, "log", paramt_str, memory_log);
372
  reg_config_param(sec, "delayr", paramt_int, memory_delayr);
373
  reg_config_param(sec, "delayw", paramt_int, memory_delayw);
374
}
375
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.