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 1557

Go to most recent revision | 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
  return *(uint16_t *)(dat + (addr ^ 2));
67
}
68
 
69
uint8_t simmem_read8(oraddr_t addr, void *dat)
70
{
71 1557 nogj
  return *(uint8_t *)(dat + ((addr & ~ADDR_C(3)) | (3 - (addr & 3))));
72 1486 nogj
}
73
 
74
void simmem_write32(oraddr_t addr, uint32_t value, void *dat)
75
{
76
  *(uint32_t *)(dat + addr) = value;
77
}
78
 
79
void simmem_write16(oraddr_t addr, uint16_t value, void *dat)
80
{
81
  *(uint16_t *)(dat + (addr ^ 2)) = value;
82
}
83
 
84
void simmem_write8(oraddr_t addr, uint8_t value, void *dat)
85
{
86 1557 nogj
  *(uint8_t *)(dat + ((addr & ~ADDR_C(3)) | (3 - (addr & 3)))) = value;
87 1486 nogj
}
88
 
89
uint32_t simmem_read_zero32(oraddr_t addr, void *dat)
90
{
91
  if (config.sim.verbose)
92
    fprintf (stderr, "WARNING: 32-bit memory read from non-read memory area 0x%"
93
                     PRIxADDR".\n", addr);
94
  return 0;
95
}
96
 
97
uint16_t simmem_read_zero16(oraddr_t addr, void *dat)
98
{
99
  if (config.sim.verbose)
100
    fprintf (stderr, "WARNING: 16-bit memory read from non-read memory area 0x%"
101
                     PRIxADDR".\n", addr);
102
  return 0;
103
}
104
 
105
uint8_t simmem_read_zero8(oraddr_t addr, void *dat)
106
{
107
  if (config.sim.verbose)
108
    fprintf (stderr, "WARNING: 8-bit memory read from non-read memory area 0x%"
109
                     PRIxADDR".\n", addr);
110
  return 0;
111
}
112
 
113
void simmem_write_null32(oraddr_t addr, uint32_t value, void *dat)
114
{
115
  if (config.sim.verbose)
116
    fprintf (stderr, "WARNING: 32-bit memory write to 0x%"PRIxADDR", non-write "
117
                     "memory area (value 0x%08"PRIx32").\n", addr, value);
118
}
119
 
120
void simmem_write_null16(oraddr_t addr, uint16_t value, void *dat)
121
{
122
  if (config.sim.verbose)
123
    fprintf (stderr, "WARNING: 16-bit memory write to 0x%"PRIxADDR", non-write "
124
                     "memory area (value 0x%08"PRIx32").\n", addr, value);
125
}
126
 
127
void simmem_write_null8(oraddr_t addr, uint8_t value, void *dat)
128
{
129
  if (config.sim.verbose)
130
    fprintf (stderr, "WARNING: 8-bit memory write to 0x%"PRIxADDR", non-write "
131
                     "memory area (value 0x%08"PRIx32").\n", addr, value);
132
}
133
 
134
void mem_reset(void *dat)
135
{
136
  struct mem_config *mem = dat;
137
  int seed;
138
  int i;
139
  uint8_t *mem_area = mem->mem;
140
 
141
  /* Initialize memory */
142
  switch(mem->type) {
143
  case MT_RANDOM:
144
    if (mem->random_seed == -1) {
145
      seed = time(NULL);
146
      /* Print out the seed just in case we ever need to debug */
147
      PRINTF("Seeding random generator with value %d\n", seed);
148
    } else
149
      seed = mem->random_seed;
150
    srandom(seed);
151
 
152
    for(i = 0; i < mem->size; i++, mem_area++)
153
      *mem_area = random() & 0xFF;
154
    break;
155
  case MT_PATTERN:
156
    for(i = 0; i < mem->size; i++, mem_area++)
157
      *mem_area = mem->pattern;
158
    break;
159
  case MT_UNKNOWN:
160
    break;
161
  default:
162
    fprintf(stderr, "Invalid memory configuration type.\n");
163
    exit(1);
164
  }
165
}
166
 
167
/*-------------------------------------------------[ Memory configuration ]---*/
168
void memory_random_seed(union param_val val, void *dat)
169
{
170
  struct mem_config *mem = dat;
171
  mem->random_seed = val.int_val;
172
}
173
 
174
void memory_pattern(union param_val val, void *dat)
175
{
176
  struct mem_config *mem = dat;
177
  mem->pattern = val.int_val;
178
}
179
 
180
void memory_type(union param_val val, void *dat)
181
{
182
  struct mem_config *mem = dat;
183
  if(!strcmp(val.str_val, "unknown"))
184
    mem->type = MT_UNKNOWN;
185
  else if(!strcmp (val.str_val, "random"))
186
    mem->type = MT_RANDOM;
187
  else if(!strcmp (val.str_val, "pattern"))
188
    mem->type = MT_PATTERN;
189
  else if(!strcmp (val.str_val, "zero")) {
190
    mem->type = MT_PATTERN;
191
    mem->pattern = 0;
192
  } else {
193
    char tmp[200];
194
    sprintf (tmp, "invalid memory type '%s'.\n", val.str_val);
195
    CONFIG_ERROR(tmp);
196
  }
197
}
198
 
199
void memory_ce(union param_val val, void *dat)
200
{
201
  struct mem_config *mem = dat;
202
  mem->ce = val.int_val;
203
}
204
 
205
void memory_mc(union param_val val, void *dat)
206
{
207
  struct mem_config *mem = dat;
208
  mem->mc = val.int_val;
209
}
210
 
211
void memory_baseaddr(union param_val val, void *dat)
212
{
213
  struct mem_config *mem = dat;
214
  mem->baseaddr = val.addr_val;
215
}
216
 
217
void memory_size(union param_val val, void *dat)
218
{
219
  struct mem_config *mem = dat;
220
  mem->size = val.int_val;
221
}
222
 
223
/* FIXME: Check use */
224
void memory_name(union param_val val, void *dat)
225
{
226
  struct mem_config *mem = dat;
227
  mem->name = strdup(val.str_val);
228
}
229
 
230
void memory_log(union param_val val, void *dat)
231
{
232
  struct mem_config *mem = dat;
233
  mem->log = strdup(val.str_val);
234
}
235
 
236
void memory_delayr(union param_val val, void *dat)
237
{
238
  struct mem_config *mem = dat;
239
  mem->delayr = val.int_val;
240
}
241
 
242
void memory_delayw(union param_val val, void *dat)
243
{
244
  struct mem_config *mem = dat;
245
  mem->delayw = val.int_val;
246
}
247
 
248
void *memory_sec_start(void)
249
{
250
  struct mem_config *mem = malloc(sizeof(struct mem_config));
251
 
252
  if(!mem) {
253
    fprintf(stderr, "Memory Peripheral: Run out of memory\n");
254
    exit(-1);
255
  }
256
  mem->size = 0;
257
  mem->log = NULL;
258
  mem->name = NULL;
259
  mem->delayr = 1;
260
  mem->delayw = 1;
261
  mem->random_seed = -1;
262
  mem->ce = -1;
263
  mem->mc = 0;
264
 
265
  return mem;
266
}
267
 
268
void memory_sec_end(void *dat)
269
{
270
  struct mem_config *mem = dat;
271
  struct dev_memarea *mema;
272
 
273
  struct mem_ops ops;
274
 
275
  if(!mem->size) {
276
    free(dat);
277
    return;
278
  }
279
 
280
  /* Round up to the next 32-bit boundry */
281
  if(mem->size & 3) {
282
    mem->size &= ~3;
283
    mem->size += 4;
284
  }
285
 
286
  if(!(mem->mem = malloc(mem->size))) {
287
    fprintf(stderr, "Unable to allocate memory at %"PRIxADDR", length %i\n",
288
            mem->baseaddr, mem->size);
289
    exit(-1);
290
  }
291
 
292
  if(mem->delayr > 0) {
293
    ops.readfunc32 = simmem_read32;
294
    ops.readfunc16 = simmem_read16;
295
    ops.readfunc8 = simmem_read8;
296
  } else {
297
    ops.readfunc32 = simmem_read_zero32;
298
    ops.readfunc16 = simmem_read_zero16;
299
    ops.readfunc8 = simmem_read_zero8;
300
  }
301
 
302
  if(mem->delayw > 0) {
303
    ops.writefunc32 = simmem_write32;
304
    ops.writefunc16 = simmem_write16;
305
    ops.writefunc8 = simmem_write8;
306
  } else {
307
    ops.writefunc32 = simmem_write_null32;
308
    ops.writefunc16 = simmem_write_null16;
309
    ops.writefunc8 = simmem_write_null8;
310
  }
311
 
312 1556 nogj
  ops.writeprog8 = simmem_write8;
313
  ops.writeprog32 = simmem_write32;
314
  ops.writeprog8_dat = mem->mem;
315
  ops.writeprog32_dat = mem->mem;
316 1486 nogj
 
317
  ops.read_dat32 = mem->mem;
318
  ops.read_dat16 = mem->mem;
319
  ops.read_dat8 = mem->mem;
320
 
321
  ops.write_dat32 = mem->mem;
322
  ops.write_dat16 = mem->mem;
323
  ops.write_dat8 = mem->mem;
324
 
325
  ops.delayr = mem->delayr;
326
  ops.delayw = mem->delayw;
327
 
328
  ops.log = mem->log;
329
 
330
  mema = reg_mem_area(mem->baseaddr, mem->size, 0, &ops);
331
 
332
  /* Set valid */
333
  /* FIXME: Should this be done during reset? */
334
  set_mem_valid(mema, 1);
335
 
336
  if(mem->ce >= 0)
337
    mc_reg_mem_area(mema, mem->ce, mem->mc);
338
 
339
  reg_sim_reset(mem_reset, dat);
340
}
341
 
342
void reg_memory_sec(void)
343
{
344
  struct config_section *sec = reg_config_sec("memory", memory_sec_start,
345
                                              memory_sec_end);
346
 
347
  reg_config_param(sec, "random_seed", paramt_int, memory_random_seed);
348
  reg_config_param(sec, "pattern", paramt_int, memory_pattern);
349
  reg_config_param(sec, "type", paramt_word, memory_type);
350
  reg_config_param(sec, "ce", paramt_int, memory_ce);
351
  reg_config_param(sec, "mc", paramt_int, memory_mc);
352
  reg_config_param(sec, "baseaddr", paramt_addr, memory_baseaddr);
353
  reg_config_param(sec, "size", paramt_int, memory_size);
354
  reg_config_param(sec, "name", paramt_str, memory_name);
355
  reg_config_param(sec, "log", paramt_str, memory_log);
356
  reg_config_param(sec, "delayr", paramt_int, memory_delayr);
357
  reg_config_param(sec, "delayw", paramt_int, memory_delayw);
358
}
359
 

powered by: WebSVN 2.1.0

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