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

Subversion Repositories diogenes

[/] [diogenes/] [trunk/] [sim/] [sim.c] - Blame information for rev 236

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 208 fellnhofer
 
2
#include<stdio.h>
3
#include<stdlib.h>
4
#include<stdarg.h>
5
 
6
unsigned int R[16] = {0};
7
unsigned int PC = 0;
8
unsigned int DMEM[1024];
9
unsigned short PMEM[1024];
10
 
11
int RA=0, RB=0, RD=0, SIMM6;
12
unsigned int IMM8=0;
13
 
14
unsigned int load_io[2], load_reg[2], load_address[2], is_load[2]  = {0};
15
 
16
 
17
//#define USE_DEBUG
18
 
19
#define VRAM_X 128
20
#define VRAM_Y 64
21
#define VRAM_SIZE (VRAM_X * VRAM_Y)
22
 
23
typedef union{
24
  unsigned char linear[VRAM_SIZE];
25
  unsigned char matrix[VRAM_X][VRAM_Y];
26
} vram_union;
27
 
28
vram_union global_vram;
29
 
30
#define VRAM global_vram.matrix
31
#define VMEM global_vram.linear
32
 
33
 
34
void usage()
35
{
36
  printf("USAGE:\n  sim <filename>\n\n");
37
  exit(1);
38
}
39
 
40
 
41
void bail_out(int err, const char *fmt, ...)
42
{
43
  va_list ap;
44
  va_start(ap, fmt);
45
  printf(fmt, ap);
46
  va_end(ap);
47
  exit(err);
48
}
49
 
50
 
51
int bit_is_0(int pos, int val)
52
{
53
  return !(val & (1<<pos));
54
}
55
 
56
void regdump()
57
{
58
  int i,j;
59
#ifdef USE_DEBUG
60
 
61
  for(i=0;i<4;i++) {
62
    fprintf(stderr, "                    ");
63
    for(j=0;j<4;j++)
64
      fprintf(stderr, "%08x  ", R[i*4+j]);
65
    fprintf(stderr, "\n");
66
  }
67
#endif
68
}
69
 
70
 
71
void mem_dump ( unsigned int addr, unsigned int size )
72
{
73
  int i, j;
74
  char c;
75
  char *mem = (char*) DMEM;
76
#ifdef USE_DEBUG
77
  for ( i=0; i<(int)( size/32 ); i++ )
78
  {
79
    fprintf(stderr,"%06x:   ", ( unsigned int ) ( addr + i*32 ) );
80
 
81
    for ( j=0; j<32; j+=4 ) {
82
      fprintf(stderr,"%08x ",  * ( ( unsigned int * ) ( mem + addr + i*32 + j ) ) );
83
    }
84
 
85
    fprintf (stderr,"   ");
86
 
87
    for ( j=0; j<32; j++ ) {
88
      c = ( * ( ( char * ) ( mem + addr + i*32 + j ) ) );
89
      fprintf(stderr,"%c",  c<30?'.':c );
90
    }
91
 
92
    fprintf(stderr,"\n" );
93
  }
94
#endif
95
}
96
 
97
 
98
unsigned int load (unsigned int io, unsigned int addr) {
99
  if(!io)
100
    return DMEM[addr];
101
 
102
  int temp = -1;
103
 
104
  if(addr & 0x80) { // read from UART
105
    if((addr&0x0f) == 1){
106
      while(temp == -1)
107
        temp = getchar();
108
        printf("read from UART %2X\n", (unsigned char) temp);
109
      return temp;
110
    }
111
 
112
    if((addr&0x0f) == 0)
113
      return 0x03; // send+recv is ready FIXME?
114
  }
115
 
116
  return 0; // default when read from unknown address
117
}
118
 
119
int loaded = 0;
120
 
121
void store (unsigned int io, unsigned int addr, unsigned int val) {
122
  unsigned int i;
123
 
124
  if(!io) {
125
    DMEM[addr] = val;
126
  } else {
127
    fprintf(stdout, "                      storeio: 0x%02x->[0x%02x]\n", val, addr);
128
    if(addr & 0x8000) {
129
      if(!(addr & 0x4000)) {// write to programm memory       
130
        printf("->PROGRAM-MEM address: 0x%04x (full 0x%08x) data: 0x%04x  (full: 0x%08x)\n ", addr&0x3ff, addr, val&0xffff, val);
131
        PMEM[addr&0x3ff] = val & 0xffff;
132
        loaded = loaded > (addr&0x3ff)? loaded: addr&0x3ff;
133
      }
134
      else{
135
        VRAM[addr & 0x7f][(addr & 0x1f80) >> 7] = val & 0xff;
136
 
137
        printf("Speicher:  %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x \n", DMEM[0], DMEM[1], DMEM[2], DMEM[3], DMEM[4], DMEM[5], DMEM[6], DMEM[7], DMEM[8], DMEM[9], DMEM[10], DMEM[11], DMEM[12], DMEM[13]);
138
 
139
      }
140
    }else{
141
      if((addr & 0xc0) == 0x80){        // write to UART
142
        printf("                           UART ad(%x): ", addr & 0x0f);
143
      }else if((addr & 0xc0) == 0x00) {                 // wirte to LEDs        
144
        for(i = 0x80; i; i>>= 1) {
145
          putchar(i&val?'#':'-');
146
        }
147
        printf("LED: ");
148
      }
149
      //printf("%03d  0x%02x (%c)\n",val, val,val<30?'.':val); fflush(stdout);     
150
    }
151
  }
152
}
153
 
154
void decode(unsigned int instruction)
155
{
156
  RB = instruction & 0xf;
157
  RA = (instruction & 0xf0) >> 4;
158
  RD = (instruction & 0xf00) >> 8;
159
  IMM8 = instruction & 0xff;
160
  SIMM6 = (((int)instruction & 0x3f) << (32-6)) >> (32-6);
161
}
162
 
163
void arith(unsigned int instruction)
164
{
165
  int subc = (instruction & 0x7000) >> 12;
166
#ifdef USE_DEBUG
167
  fprintf(stderr, "arith: ");
168
#endif
169
  switch (subc)
170
  {
171
    case 0: R[RD] = R[RA] + R[RB];
172
#ifdef USE_DEBUG 
173
    fprintf(stderr, "add ");
174
#endif
175
    break;
176
    case 1: R[RD] = R[RA] - R[RB];
177
#ifdef USE_DEBUG 
178
    fprintf(stderr, "sub ");
179
#endif
180
    break;
181
 
182
    case 2: R[RD] = R[RA] & R[RB];
183
#ifdef USE_DEBUG 
184
    fprintf(stderr, "and ");
185
#endif
186
    break;
187
 
188
    case 3: R[RD] = R[RA] | R[RB];
189
#ifdef USE_DEBUG 
190
    fprintf(stderr, "or  ");
191
#endif
192
    break;
193
 
194
    case 4: R[RD] = R[RA] ^ R[RB];
195
#ifdef USE_DEBUG 
196
    fprintf(stderr, "xor ");
197
#endif
198
    break;
199
 
200
    case 5: R[RD] = R[RA] << ((int) R[RB]);
201
#ifdef USE_DEBUG 
202
    fprintf(stderr, "sh  ");
203
#endif
204
    break;
205
 
206
    case 6: R[RD] = IMM8;
207
#ifdef USE_DEBUG
208
    fprintf(stderr, "ldi ");
209
#endif
210
    break;
211
 
212
    case 7: R[RD] = (R[RD] << 8) | IMM8;
213
#ifdef USE_DEBUG  
214
    fprintf(stderr, "lsi ");
215
#endif
216
    break;
217
  }
218
#ifdef USE_DEBUG
219
  fprintf(stderr, "%d = %d . %d\n", RD, RA, RB);
220
#endif
221
}
222
 
223
 
224
void compare(unsigned int instruction)
225
{
226
  int gt = instruction & 0x2000;
227
  int sign = instruction & 0x1000;
228
 
229
  if(gt) {
230
    //if(sign) R[RD] = ((int)R[RA])>((int)R[RB]);
231
    //else R[RD] = R[RA]>R[RB];
232
    printf("UNKNOWN INSTRUCTIION (former compare greater)\n");
233
  } else {
234
    if(sign) R[RD] = ((int)R[RA])<((int)R[RB]);
235
    else R[RD] = R[RA]<R[RB];
236
  }
237
}
238
 
239
 
240
 
241
void execute();
242
 
243
 
244
void branch(unsigned int instruction)
245
{
246
  int offset = (((int) instruction & 0x0ff0) << (32-12)) >> (32-8);
247
  if(!!R[RB] == !!(instruction&0x1000)) {
248
#ifdef USE_DEBUG
249
    fprintf(stderr, "branch taken: %d == %d\n", R[RB], !!(instruction&0x1000));
250
#endif
251
    PC++;
252
    execute();
253
    PC += offset - 3;
254
  } else {
255
#ifdef USE_DEBUG
256
    fprintf(stderr, "branch NOT taken: %d == %d\n", R[RB], !!(instruction&0x1000));
257
#endif
258
  }
259
}
260
 
261
void addshift(unsigned int instruction)
262
{
263
  int ra = RD ^ ((instruction&0x80)>>4);
264
  if(!(instruction&0x40)) {   // add
265
    R[RD] = R[ra] + SIMM6;
266
  } else {
267
#ifdef USE_DEBUG
268
    fprintf(stderr, "shift imm %d\n", SIMM6);
269
#endif
270
    if(SIMM6<0) R[RD] = R[ra] >> (-SIMM6);
271
    else R[RD] = R[ra] << SIMM6;
272
  }
273
}
274
 
275
void special(unsigned int instruction)
276
{
277
  unsigned int rra = R[RA];
278
  int io_t = !!(instruction & 0x8);
279
  int rb = RA^(io_t<<3);
280
  int sh_off = ((instruction & 0xc0) >> 6) * 8;
281
  int imm_mask = (instruction & 0x20)?0xffff:0xff;
282
 
283
  switch (instruction & 0x7)
284
  {
285
    case 0:  // calll
286
#ifdef USE_DEBUG
287
      fprintf(stderr, "call/jump delay slot\n");
288
#endif
289
      if(io_t) R[RD] = PC+2;
290
      PC++;
291
      execute();
292
      PC = rra-1;
293
      break;
294
    case 1:
295
      R[RD] = R[RA];
296
      break;
297
    case 2:
298
      is_load[0] = 1;
299
      load_io[0] = io_t;
300
      load_reg[0] = RD;
301
      load_address[0] = R[RA];
302
      //if(io_t) R[RD] = getchar();
303
      //else R[RD] = DMEM[R[RA]];
304
      break;
305
    case 3:
306
      //fprintf(stderr, "store io:%d %d->[%d]\n", !!io_t, R[RD], R[RA]);
307
      //if(io_t) { printf(" %02x",R[RD],R[RD]); fflush(stdout); }
308
      //else DMEM[R[RA]] = R[RD];
309
 
310
      store(io_t, R[RA], R[RD]);
311
 
312
 
313
      break;
314
    case 4:
315
      R[RD] = (R[RB] >> (8*(R[RA]&0x3))) & 0xffff;
316
      break;
317
    case 5:
318
      R[RD] = (R[RB] >> (8*(R[RA]&0x3))) & 0xff;
319
      break;
320
    case 6:
321
      R[RD] = (R[RD^((instruction&0x8)?8:0)] >> sh_off) & imm_mask;
322
      if(instruction&0x40) {
323
        if(imm_mask == 0xffff) R[RD] = (R[RD] << 16) >> 16;
324
        else R[RD] = (R[RD] << 24) >> 24;
325
      }
326
      break;
327
    default:
328
      bail_out(1, "Unknown Operation");
329
      break;
330
  }
331
}
332
 
333
void execute()
334
{
335
  unsigned int temp;
336
  unsigned int instruction = PMEM[PC];
337
#ifdef USE_DEBUG
338
  fprintf(stderr, "PC: 0x%04x = 0x%04x\n", PC, PMEM[PC]);
339
#endif
340
 
341
 
342
  is_load[1] = is_load[0];
343
  load_reg[1] = load_reg[0];
344
  load_address[1] = load_address[0];
345
  load_io[1] = load_io[0];
346
 
347
 
348
  // wenn im "delayslot" von einer Load Instruktion
349
  // das Register, in das geladen wird, geschrieben wird (zB auch nop: l0 = l0 | l0)
350
  // ist der Wert zwar kurz ins registerfile geschrieben, ist aber nie sichtbar
351
 
352
  is_load[0] = 0;
353
  decode(instruction);
354
  if (bit_is_0(15, instruction)) arith(instruction);
355
  else if (bit_is_0(14, instruction)) compare(instruction);
356
  else if (bit_is_0(13, instruction)) branch(instruction);
357
  else if (bit_is_0(12, instruction)) addshift(instruction);
358
  else special(instruction);
359
  PC++;
360
 
361
  if(is_load[1])
362
  {
363
    temp = load(load_io[1], load_address[1]);
364
 
365
    if( RD != load_reg[1]) // simuliert das problem (aber nicht haargenau, weil branch etc. nicht wirklich auf RD schreiben) 
366
      R[load_reg[1]] = temp;
367
  }
368
}
369
/**********************
370
 * graphic simulation *
371
 **********************/
372
 
373
unsigned char header[0x2A] = {
374
           0x00,0x01,0x01,0x00,0x00,0x08,0x00,0x18,
375
           0x00,0x00,0x00,0x00,0x80,0x02,0xE0,0x01,
376
           0x08,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,
377
           0x00,0xFF,0x00,0x00,0xFF,0xFF,0xC2,0x79,
378
           0x02,0xC2,0x5D,0xFC,0xFF,0xE8,0xA3,0xFF,
379
           0xFF,0xFF};
380
 
381
unsigned char pcolor(int x, int y) {
382
  unsigned char addr;
383
 
384
  addr = VRAM[x>>3][y>>3];
385
 
386
  addr = VRAM[(1<<6) + ((addr & 0x0F) << 2) + ((x&0x6) >> 1)][((addr & 0x70) >> 1) + ((y & 0x07))];
387
 
388
 
389
  if(x & 0x01)
390
    return (addr & 0x07);
391
  else
392
    return (addr & 0x70) >> 4;
393
}
394
 
395
 
396
 
397
void sim_graphic(int num) {
398
  int i; int x; int y;
399
  char str[256];
400
 
401
  FILE *tgaout = 0;
402
 
403
  sprintf(str, "pic%04d.tga", num);
404
  tgaout = fopen(str, "w+");
405
 
406
  if(!tgaout){
407
    printf("picture output file");
408
  }
409
  else {
410
    for(i = 0; i < 0x2A; i++) {
411
      fputc(header[i],tgaout);
412
    }
413
 
414
    for(y = 479; y >= 0; y --)
415
      for(x = 0; x < 640; x++)
416
        fputc(pcolor(x,y), tgaout);
417
 
418
    /*
419
    for(y = 0; y < VRAM_Y; y++)
420
      for(x = 0; x < VRAM_X; x++)
421
        fputc(VRAM[x][y], tgaout);
422
    */
423
 
424
    fclose(tgaout);
425
  }
426
 
427
}
428
 
429
 
430
 
431
 
432
 
433
int main(int argc, char **argv)
434
{
435
  FILE *bin;
436
  int running = 1;
437
  int x,y;
438
  long cycle = 0;
439
 
440
  if(argc<2) usage();
441
 
442
  bin = fopen(argv[1], "r");
443
  if(!bin) bail_out(1, "Binary File '%s' not found\n");
444
 
445
  // load programm memory
446
  loaded = fread(PMEM+0x40, sizeof(short), sizeof(PMEM)/sizeof(short), bin) + 0x40;
447
  PC = 0x40;
448
 
449
  // load video memory
450
  FILE *vram_dump = fopen("video.ram", "r");
451
 
452
  if(!vram_dump) {
453
    printf("cannot open video ram file video.ram (VIDEO RAM unititialized!)\n");
454
  } else {
455
    for(y = 0; y < VRAM_Y; y++)
456
      for(x = 0; x < VRAM_X; x++)
457
        VRAM[x][y] = fgetc(vram_dump);
458
    fclose(vram_dump);
459
  }
460
 
461
  while(running) {
462
    execute();
463
    regdump();
464
    if(PC>=loaded) running = 0;
465
 
466
 
467
 
468
    if((cycle % 400000) == 0)
469
      sim_graphic(cycle/400000);
470
    cycle++;
471
 
472
  }
473
  mem_dump ( 0, 2058);
474
 
475
  return 0;
476
}

powered by: WebSVN 2.1.0

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