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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [testsuite/] [test-code-or1k/] [except-test/] [except-test.c] - Blame information for rev 90

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 90 jeremybenn
/* except-test.c. Test of Or1ksim exception handling
2
 
3
   Copyright (C) 1999-2006 OpenCores
4
   Copyright (C) 2010 Embecosm Limited
5
 
6
   Contributors various OpenCores participants
7
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
8
 
9
   This file is part of OpenRISC 1000 Architectural Simulator.
10
 
11
   This program is free software; you can redistribute it and/or modify it
12
   under the terms of the GNU General Public License as published by the Free
13
   Software Foundation; either version 3 of the License, or (at your option)
14
   any later version.
15
 
16
   This program is distributed in the hope that it will be useful, but WITHOUT
17
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
19
   more details.
20
 
21
   You should have received a copy of the GNU General Public License along
22
   with this program.  If not, see <http:  www.gnu.org/licenses/>.  */
23
 
24
/* ----------------------------------------------------------------------------
25
   This code is commented throughout for use with Doxygen.
26
   --------------------------------------------------------------------------*/
27
 
28
#include "spr-defs.h"
29
#include "support.h"
30
#include "int.h"
31
 
32
/* Define RAM physical location and size
33
   Bottom half will be used for this program, the rest
34
   will be used for testing */
35
#define FLASH_START 0xf0000000
36
#define FLASH_SIZE  0x00200000
37
#define RAM_START   0x00000000
38
#define RAM_SIZE    0x04000000
39
 
40
#define TEST_BASE   0xa5000000
41
 
42
/* MMU page size */
43
#define PAGE_SIZE 8192
44
 
45
/* Number of DTLB sets used (power of 2, max is 256) */
46
#define DTLB_SETS 32
47
 
48
/* Number of DTLB ways (2, 2, 3 etc., max is 4). */
49
#define DTLB_WAYS 1
50
 
51
/* Number of ITLB sets used (power of 2, max is 256) */
52
#define ITLB_SETS 32
53
 
54
/* Number of ITLB ways (1, 2, 3 etc., max is 4). */
55
#define ITLB_WAYS 1
56
 
57
/* TLB mode codes */
58
#define TLB_CODE_ONE_TO_ONE     0x00000000
59
#define TLB_CODE_PLUS_ONE_PAGE  0x10000000
60
#define TLB_CODE_MINUS_ONE_PAGE 0x20000000
61
 
62
#define TLB_TEXT_SET_NB 6
63
#define TLB_DATA_SET_NB 2
64
 
65
#define TLB_CODE_MASK   0xfffff000
66
#define TLB_PR_MASK     0x00000fff
67
#define DTLB_PR_NOLIMIT  ( SPR_DTLBTR_CI   | \
68
                          SPR_DTLBTR_URE  | \
69
                          SPR_DTLBTR_UWE  | \
70
                          SPR_DTLBTR_SRE  | \
71
                          SPR_DTLBTR_SWE  )
72
 
73
#define ITLB_PR_NOLIMIT  ( SPR_ITLBTR_CI   | \
74
                          SPR_ITLBTR_SXE  | \
75
                          SPR_ITLBTR_UXE  )
76
 
77
/* fails if x is false */
78
#define ASSERT(x) ((x)?1: fail (__FUNCTION__, __LINE__))
79
 
80
/* Exception vectors */
81
#define V_RESET       1
82
#define V_BERR        2
83
#define V_DPF         3
84
#define V_IPF         4
85
#define V_TICK        5
86
#define V_ALIGN       6
87
#define V_ILLINSN     7
88
#define V_INT         8
89
#define V_DTLB_MISS   9
90
#define V_ITLB_MISS   10
91
#define V_RANGE       11
92
#define V_SYS         12
93
#define V_TRAP        14
94
 
95
#define debug printf
96
 
97
/* Extern functions */
98
extern void lo_dmmu_en (void);
99
extern void lo_immu_en (void);
100
extern unsigned long call (unsigned long add, unsigned long val);
101
extern unsigned long call_with_int (unsigned long add, unsigned long val);
102
extern void trap (void);
103
extern void b_trap (void);
104
extern void range (void);
105
extern void b_range (void);
106
extern int except_basic (void);
107
extern void (*test)(void);
108
extern int load_acc_32 (unsigned long add);
109
extern int load_acc_16 (unsigned long add);
110
extern int store_acc_32 (unsigned long add);
111
extern int store_acc_16 (unsigned long add);
112
extern int load_b_acc_32 (unsigned long add);
113
extern int int_trigger (void);
114
extern int int_loop (void);
115
extern int jump_back (void);
116
 
117
/* Local functions prototypes */
118
void dmmu_disable (void);
119
void immu_disable (void);
120
 
121
/* DTLB mode status */
122
volatile unsigned long dtlb_val;
123
 
124
/* ITLB mode status */
125
volatile unsigned long itlb_val;
126
 
127
/* Exception counter */
128
volatile int except_count;
129
 
130
/* Exception mask */
131
volatile unsigned long except_mask;
132
 
133
/* Exception efective address */
134
volatile unsigned long except_ea;
135
 
136
/* Eception PC */
137
volatile unsigned long except_pc;
138
 
139
unsigned long  excpt_buserr;
140
unsigned long excpt_dpfault;
141
unsigned long excpt_ipfault;
142
unsigned long excpt_tick;
143
unsigned long excpt_align;
144
unsigned long excpt_illinsn;
145
unsigned long excpt_int;
146
unsigned long excpt_dtlbmiss;
147
unsigned long excpt_itlbmiss;
148
unsigned long excpt_range;
149
unsigned long excpt_syscall;
150
unsigned long excpt_break;
151
unsigned long excpt_trap;
152
 
153
 
154
void fail (char *func, int line)
155
{
156
#ifndef __FUNCTION__
157
#define __FUNCTION__ "?"
158
#endif
159
 
160
  immu_disable ();
161
  dmmu_disable ();
162
 
163
  debug("Test failed in %s:%i\n", func, line);
164
  report (0xeeeeeeee);
165
  exit (1);
166
}
167
 
168
void test_dummy (void)
169
{
170
        asm("_test:");
171
        asm("l.addi\t\tr3,r3,1") ;
172
        asm("l.nop" : :);
173
}
174
 
175
void copy_test (unsigned long phy_add)
176
{
177
        memcpy((void *)phy_add, (void *)&test, 8);
178
}
179
 
180
/* Bus error handler */
181
void bus_err_handler (void)
182
{
183
 
184
  except_mask |= 1 << V_BERR;
185
  except_count++;
186
}
187
 
188
/* Illegal insn handler */
189
void ill_insn_handler (void)
190
{
191
  except_mask |= 1 << V_ILLINSN;
192
  except_count++;
193
}
194
 
195
/* Low priority interrupt handler */
196
void tick_handler (void)
197
{
198
 
199
  /* Disable interrupt recognition */
200
  mtspr(SPR_ESR_BASE, mfspr(SPR_ESR_BASE) & ~SPR_SR_TEE);
201
 
202
  except_mask |= 1 << V_TICK;
203
  except_count++;
204
}
205
 
206
/* High priority interrupt handler */
207
void int_handler (void)
208
{
209
 
210
  /* Disable interrupt recognition */
211
  mtspr(SPR_ESR_BASE, mfspr(SPR_ESR_BASE) & ~SPR_SR_IEE);
212
 
213
  except_mask |= 1 << V_INT;
214
  except_count++;
215
}
216
 
217
/* Trap handler */
218
void trap_handler (void)
219
{
220
 
221
  except_mask |= 1 << V_TRAP;
222
  except_count++;
223
}
224
 
225
/* Align handler */
226
void align_handler (void)
227
{
228
 
229
  except_mask |= 1 << V_ALIGN;
230
  except_count++;
231
}
232
 
233
/* Range handler */
234
void range_handler (void)
235
{
236
  /* Disable range exception */
237
  mtspr (SPR_ESR_BASE, mfspr (SPR_ESR_BASE) & ~SPR_SR_OVE);
238
 
239
  except_mask |= 1 << V_RANGE;
240
  except_count++;
241
}
242
 
243
/* DTLB miss exception handler */
244
void dtlb_miss_handler (void)
245
{
246
  unsigned long ea;
247
  int set, way = 0;
248
  int i;
249
 
250
  /* Get EA that cause the exception */
251
  ea = mfspr (SPR_EEAR_BASE);
252
 
253
  /* Find TLB set and LRU way */
254
  set = (ea / PAGE_SIZE) % DTLB_SETS;
255
  for (i = 0; i < DTLB_WAYS; i++) {
256
    if ((mfspr (SPR_DTLBMR_BASE(i) + set) & SPR_DTLBMR_LRU) == 0) {
257
      way = i;
258
      break;
259
    }
260
  }
261
 
262
  mtspr (SPR_DTLBMR_BASE(way) + set, (ea & SPR_DTLBMR_VPN) | SPR_DTLBMR_V);
263
  mtspr (SPR_DTLBTR_BASE(way) + set, (ea & SPR_DTLBTR_PPN) | dtlb_val);
264
 
265
  except_mask |= 1 << V_DTLB_MISS;
266
  except_count++;
267
}
268
 
269
/* ITLB miss exception handler */
270
void itlb_miss_handler (void)
271
{
272
  unsigned long ea;
273
  int set, way = 0;
274
  int i;
275
 
276
  /* Get EA that cause the exception */
277
  ea = mfspr (SPR_EEAR_BASE);
278
 
279
  /* Find TLB set and LRU way */
280
  set = (ea / PAGE_SIZE) % ITLB_SETS;
281
  for (i = 0; i < ITLB_WAYS; i++) {
282
    if ((mfspr (SPR_ITLBMR_BASE(i) + set) & SPR_ITLBMR_LRU) == 0) {
283
      way = i;
284
      break;
285
    }
286
  }
287
 
288
  mtspr (SPR_ITLBMR_BASE(way) + set, (ea & SPR_ITLBMR_VPN) | SPR_ITLBMR_V);
289
  mtspr (SPR_ITLBTR_BASE(way) + set, (ea & SPR_ITLBTR_PPN) | itlb_val);
290
  except_mask |= 1 << V_ITLB_MISS;
291
  except_count++;
292
}
293
 
294
/* Data page fault exception handler */
295
void dpage_fault_handler (void)
296
{
297
  unsigned long ea;
298
  int set, way = 0;
299
  int i;
300
 
301
  /* Get EA that cause the exception */
302
  ea = mfspr (SPR_EEAR_BASE);
303
 
304
  /* Find TLB set and way */
305
  set = (ea / PAGE_SIZE) % DTLB_SETS;
306
  for (i = 0; i < DTLB_WAYS; i++) {
307
    if ((mfspr (SPR_DTLBMR_BASE(i) + set) & SPR_DTLBMR_VPN) == (ea & SPR_DTLBMR_VPN)) {
308
      way = i;
309
      break;
310
    }
311
  }
312
 
313
  /* Give permission */
314
  mtspr (SPR_DTLBTR_BASE(way) + set, (mfspr (SPR_DTLBTR_BASE(way) + set) & ~DTLB_PR_NOLIMIT) | dtlb_val);
315
 
316
  except_mask |= 1 << V_DPF;
317
  except_count++;
318
}
319
 
320
/* Intstruction page fault exception handler */
321
void ipage_fault_handler (void)
322
{
323
  unsigned long ea;
324
  int set, way = 0;
325
  int i;
326
 
327
  /* Get EA that cause the exception */
328
  ea = mfspr (SPR_EEAR_BASE);
329
 
330
  /* Find TLB set and way */
331
  set = (ea / PAGE_SIZE) % ITLB_SETS;
332
  for (i = 0; i < ITLB_WAYS; i++) {
333
    if ((mfspr (SPR_ITLBMR_BASE(i) + set) & SPR_ITLBMR_VPN) == (ea & SPR_ITLBMR_VPN)) {
334
      way = i;
335
      break;
336
    }
337
  }
338
 
339
  /* Give permission */
340
  mtspr (SPR_ITLBTR_BASE(way) + set, (mfspr (SPR_ITLBTR_BASE(way) + set) & ~ITLB_PR_NOLIMIT) | itlb_val);
341
 
342
  except_mask |= 1 << V_IPF;
343
  except_count++;
344
}
345
 
346
/*Enable DMMU */
347
void dmmu_enable (void)
348
{
349
  /* Enable DMMU */
350
  lo_dmmu_en ();
351
}
352
 
353
/* Disable DMMU */
354
void dmmu_disable (void)
355
{
356
  mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_DME);
357
}
358
 
359
/* Enable IMMU */
360
void immu_enable (void)
361
{
362
  /* Enable IMMU */
363
  lo_immu_en ();
364
}
365
 
366
/* Disable IMMU */
367
void immu_disable (void)
368
{
369
  mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_IME);
370
}
371
 
372
/* Tick timer init */
373
void tick_init (int period, int hp_int)
374
{
375
  /* Disable tick timer exception recognition */
376
  mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_TEE);
377
 
378
  /* Set period of one cycle, restartable mode */
379
  mtspr(SPR_TTMR, SPR_TTMR_IE | SPR_TTMR_RT | (period & SPR_TTMR_PERIOD));
380
 
381
  /* Reset counter */
382
  mtspr(SPR_TTCR, 0);
383
}
384
 
385
/* Interrupt test */
386
int interrupt_test (void)
387
{
388
  unsigned long ret;
389
  int i;
390
 
391
  /* Init tick timer */
392
  tick_init (1, 1);
393
 
394
  /* Reset except counter */
395
  except_count = 0;
396
  except_mask = 0;
397
  except_pc = 0;
398
  except_ea = 0;
399
 
400
  /* Test normal high priority interrupt trigger */
401
  ret = call ((unsigned long)&int_trigger, 0);
402
  ASSERT(except_count == 1);
403
  ASSERT(except_mask == (1 << V_TICK));
404
  ASSERT(ret == 0);
405
  ASSERT(except_pc == (unsigned long)int_trigger + 16);
406
 
407
  /* Reset except counter */
408
  except_count = 0;
409
  except_mask = 0;
410
  except_pc = 0;
411
  except_ea = 0;
412
 
413
  /* Test inetrrupt in delay slot */
414
  tick_init (100, 1);
415
 
416
  /* Hopefully we will have interrupt recognition between branch insn and delay slot */
417
  except_pc = (unsigned long)&int_loop;
418
  for (i = 0; i < 10; i++) {
419
    call_with_int (except_pc, RAM_START);
420
    ASSERT(except_pc == (unsigned long)&int_loop);
421
  }
422
 
423
  return 0;
424
}
425
 
426
/* ITLB miss test */
427
int itlb_test (void)
428
{
429
  int i, j, ret;
430
  unsigned long ea, ta;
431
 
432
  /* Invalidate all entries in ITLB */
433
  for (i = 0; i < ITLB_WAYS; i++) {
434
    for (j = 0; j < ITLB_SETS; j++) {
435
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
436
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
437
    }
438
  }
439
 
440
  /* Set one to one translation for the use of this program */
441
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
442
    ea = FLASH_START + (i*PAGE_SIZE);
443
    ta = FLASH_START + (i*PAGE_SIZE);
444
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
445
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
446
  }
447
 
448
  /* Set dtlb no permisions */
449
  itlb_val = SPR_ITLBTR_CI;
450
 
451
  /* Reset except counter */
452
  except_count = 0;
453
  except_mask = 0;
454
  except_pc = 0;
455
  except_ea = 0;
456
 
457
  /* Enable IMMU */
458
  immu_enable ();
459
 
460
  /* Copy jump instruction to last location of a page */
461
  ea = RAM_START + (RAM_SIZE/2) + ((TLB_TEXT_SET_NB + 1)*PAGE_SIZE) - 8;
462
  memcpy((void *)ea, (void *)&jump_back, 12);
463
 
464
  /* Check if there was ITLB miss exception */
465
  ret = call (ea, 0);
466
  ASSERT(except_count == 1);
467
  ASSERT(except_mask == (1 << V_ITLB_MISS));
468
  ASSERT(except_pc == ea);
469
  ASSERT(ret == 0);
470
 
471
  /* Set dtlb no permisions */
472
  itlb_val = SPR_ITLBTR_CI | SPR_ITLBTR_SXE;
473
 
474
  /* Reset except counter */
475
  except_count = 0;
476
  except_mask = 0;
477
  except_pc = 0;
478
  except_ea = 0;
479
 
480
  /* Check if there was IPF miss exception */
481
  ret = call (ea, 0);
482
  ASSERT(except_count == 1);
483
  ASSERT(except_mask == (1 << V_IPF));
484
  ASSERT(except_pc == ea);
485
  ASSERT(ret == 0);
486
 
487
  /* Set dtlb no permisions */
488
  itlb_val = SPR_ITLBTR_CI;
489
 
490
  /* Reset except counter */
491
  except_count = 0;
492
  except_mask = 0;
493
  except_pc = 0;
494
  except_ea = 0;
495
 
496
  /* Check if there was ITLB miss exception */
497
  ret = call (ea, 0);
498
  ASSERT(except_count == 1);
499
  ASSERT(except_mask == (1 << V_ITLB_MISS));
500
  ASSERT(except_pc == ea + 4);
501
  ASSERT(ret == 0);
502
 
503
  /* Set dtlb no permisions */
504
  itlb_val = SPR_ITLBTR_CI | SPR_ITLBTR_SXE;
505
 
506
  /* Reset except counter */
507
  except_count = 0;
508
  except_mask = 0;
509
  except_pc = 0;
510
  except_ea = 0;
511
 
512
  /* Check if there was IPF exception */
513
  ret = call (ea, 0);
514
  ASSERT(except_count == 1);
515
  ASSERT(except_mask == (1 << V_IPF));
516
  ASSERT(except_pc == ea + 4);
517
  ASSERT(ret == 0);
518
 
519
  /* Reset except counter */
520
  except_count = 0;
521
  except_mask = 0;
522
  except_pc = 0;
523
  except_ea = 0;
524
 
525
  ret = call (ea, 0);
526
  ASSERT(except_count == 0);
527
  ASSERT(ret == 1);
528
 
529
  /* Disable IMMU */
530
  immu_disable ();
531
 
532
  return 0;
533
}
534
 
535
/* DTLB miss test */
536
int dtlb_test (void)
537
{
538
  int i, j, ret;
539
  unsigned long ea, ta;
540
 
541
  /* Invalidate all entries in DTLB */
542
  for (i = 0; i < DTLB_WAYS; i++) {
543
    for (j = 0; j < DTLB_SETS; j++) {
544
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
545
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
546
    }
547
  }
548
 
549
  /* Set one to one translation for the use of this program */
550
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
551
    ea = RAM_START + (i*PAGE_SIZE);
552
    ta = RAM_START + (i*PAGE_SIZE);
553
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
554
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
555
  }
556
 
557
  /* Set dtlb no permisions */
558
  dtlb_val = SPR_DTLBTR_CI;
559
 
560
  /* Reset except counter */
561
  except_count = 0;
562
  except_mask = 0;
563
  except_pc = 0;
564
  except_ea = 0;
565
 
566
  /* Set pattern */
567
  ea = RAM_START + (RAM_SIZE/2) + ((TLB_DATA_SET_NB)*PAGE_SIZE);
568
  REG32(ea) = 0x87654321;
569
 
570
  /* Enable DMMU */
571
  dmmu_enable ();
572
 
573
  /* Check if there was DTLB miss exception */
574
  ret = call ((unsigned long)&load_b_acc_32, ea);
575
  ASSERT(except_count == 1);
576
  ASSERT(except_mask == (1 << V_DTLB_MISS));
577
  ASSERT(except_pc == (unsigned long)load_b_acc_32 + 8);
578
  ASSERT(except_ea == ea);
579
  ASSERT(ret == 0x12345678);
580
 
581
  /* Set dtlb no permisions */
582
  dtlb_val = SPR_DTLBTR_CI | SPR_DTLBTR_SRE;
583
 
584
  /* Reset except counter */
585
  except_count = 0;
586
  except_mask = 0;
587
  except_pc = 0;
588
  except_ea = 0;
589
 
590
  /* Check if there was DPF miss exception */
591
  ret = call ((unsigned long)&load_b_acc_32, ea);
592
  ASSERT(except_count == 1);
593
  ASSERT(except_mask == (1 << V_DPF));
594
  ASSERT(except_pc == (unsigned long)load_b_acc_32 + 8);
595
  ASSERT(except_ea == ea);
596
  ASSERT(ret == 0x12345678);
597
 
598
  /* Reset except counter */
599
  except_count = 0;
600
  except_mask = 0;
601
  except_pc = 0;
602
  except_ea = 0;
603
 
604
  ret = call ((unsigned long)&load_b_acc_32, ea);
605
  ASSERT(except_count == 0);
606
  ASSERT(ret == 0x87654321);
607
 
608
  /* Disable DMMU */
609
  dmmu_disable ();
610
 
611
  return 0;
612
}
613
 
614
/* Bus error test */
615
int buserr_test (void)
616
{
617
  int i, j, ret;
618
  unsigned long ea, ta;
619
 
620
  /* Invalidate all entries in ITLB */
621
  for (i = 0; i < ITLB_WAYS; i++) {
622
    for (j = 0; j < ITLB_SETS; j++) {
623
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
624
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
625
    }
626
  }
627
 
628
  /* Set one to one translation for the use of this program */
629
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
630
    ea = FLASH_START + (i*PAGE_SIZE);
631
    ta = FLASH_START + (i*PAGE_SIZE);
632
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
633
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
634
  }
635
 
636
  /* Invalidate all entries in DTLB */
637
  for (i = 0; i < DTLB_WAYS; i++) {
638
    for (j = 0; j < DTLB_SETS; j++) {
639
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
640
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
641
    }
642
  }
643
 
644
  /* Set one to one translation for the use of this program */
645
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
646
    ea = RAM_START + (i*PAGE_SIZE);
647
    ta = RAM_START + (i*PAGE_SIZE);
648
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
649
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
650
  }
651
 
652
  /* Reset except counter */
653
  except_count = 0;
654
  except_mask = 0;
655
  except_pc = 0;
656
  except_ea = 0;
657
 
658
  /* Set IMMU translation */
659
  ea = RAM_START + (RAM_SIZE) + ((TLB_TEXT_SET_NB)*PAGE_SIZE);
660
  itlb_val = SPR_ITLBTR_CI | SPR_ITLBTR_SXE;
661
  mtspr (SPR_ITLBMR_BASE(0) + TLB_TEXT_SET_NB, (ea & SPR_ITLBMR_VPN) | SPR_ITLBMR_V);
662
  mtspr (SPR_ITLBTR_BASE(0) + TLB_TEXT_SET_NB, ((ea + PAGE_SIZE) & SPR_ITLBTR_PPN) | itlb_val);
663
 
664
  /* Enable IMMU */
665
  immu_enable ();
666
 
667
  /* Check if there was bus error exception */
668
  ret = call (ea, 0);
669
  ASSERT(except_count == 1);
670
  ASSERT(except_mask == (1 << V_BERR));
671
  ASSERT(except_pc == ea);
672
  ASSERT(except_ea == ea);
673
 
674
  /* Disable IMMU */
675
  immu_disable ();
676
 
677
  /* Reset except counter */
678
  except_count = 0;
679
  except_mask = 0;
680
  except_pc = 0;
681
  except_ea = 0;
682
 
683
  /* Copy jump instruction to last location of RAM */
684
  ea = RAM_START + RAM_SIZE - 8;
685
  memcpy((void *)ea, (void *)&jump_back, 8);
686
 
687
  /* Check if there was bus error exception */
688
  ret = call (ea, 0);
689
  ASSERT(except_count == 1);
690
  ASSERT(except_mask == (1 << V_BERR));
691
  ASSERT(except_pc == ea + 4);
692
  ASSERT(except_ea == ea + 8);
693
 
694
  /* Reset except counter */
695
  except_count = 0;
696
  except_mask = 0;
697
  except_pc = 0;
698
  except_ea = 0;
699
 
700
  /* Set DMMU translation */
701
  ea = RAM_START + (RAM_SIZE) + ((TLB_DATA_SET_NB)*PAGE_SIZE);
702
  dtlb_val = SPR_DTLBTR_CI | SPR_DTLBTR_SRE;
703
  mtspr (SPR_DTLBMR_BASE(0) + TLB_DATA_SET_NB, (ea & SPR_DTLBMR_VPN) | SPR_DTLBMR_V);
704
  mtspr (SPR_DTLBTR_BASE(0) + TLB_DATA_SET_NB, ((ea + PAGE_SIZE) & SPR_DTLBTR_PPN) | dtlb_val);
705
 
706
  /* Enable DMMU */
707
  dmmu_enable ();
708
 
709
  /* Check if there was bus error exception */
710
  ret = call ((unsigned long)&load_acc_32, ea );
711
  ASSERT(except_count == 1);
712
  ASSERT(except_mask == (1 << V_BERR));
713
  ASSERT(except_pc == (unsigned long)load_acc_32 + 8);
714
  ASSERT(except_ea == ea);
715
  ASSERT(ret == 0x12345678);
716
 
717
  /* Disable DMMU */
718
  dmmu_disable ();
719
 
720
  /* Reset except counter */
721
  except_count = 0;
722
  except_mask = 0;
723
  except_pc = 0;
724
  except_ea = 0;
725
 
726
  /* Check if there was bus error exception */
727
  ret = call ((unsigned long)&load_acc_32, ea );
728
  ASSERT(except_count == 1);
729
  ASSERT(except_mask == (1 << V_BERR));
730
  ASSERT(except_pc == (unsigned long)load_acc_32 + 8);
731
  ASSERT(except_ea == ea);
732
  ASSERT(ret == 0x12345678);
733
 
734
  return 0;
735
}
736
 
737
/* Illegal instruction test */
738
int illegal_insn_test (void)
739
{
740
  int ret;
741
 
742
  /* Reset except counter */
743
  except_count = 0;
744
  except_mask = 0;
745
  except_pc = 0;
746
  except_ea = 0;
747
 
748
  /* Set illegal insn code.
749
 
750
     Original code had two bugs. First it jumped to the illegal instruction,
751
     rather than the immediately preceding l.jr r9 (allowing us to
752
     recover). Secondly it used 0xffffffff as an illegal instruction. Except
753
     it isn't - it's l.cust8 0x3ffffff.
754
 
755
     Fixed by a) jumping to the correct location and b) really using an
756
     illegal instruction. */
757
  REG32(RAM_START + (RAM_SIZE/2)) = REG32((unsigned long)jump_back + 4);
758
  REG32(RAM_START + (RAM_SIZE/2) + 4) = 0xe5dfffff;
759
 
760
  /* Check if there was illegal insn exception. Note that if an illegal
761
     instruction occurs in a delay slot (like this one), then the exception
762
     PC is the address of the hump instruction. */
763
  ret = call (RAM_START + (RAM_SIZE/2), 0 );     /* JPB */
764
 
765
  ASSERT(except_count == 1);
766
  ASSERT(except_mask == (1 << V_ILLINSN));
767
  ASSERT(except_pc == (RAM_START + (RAM_SIZE/2)));
768
 
769
  return 0;
770
}
771
 
772
/* Align test */
773
int align_test (void)
774
{
775
  int ret;
776
 
777
  /* Reset except counter */
778
  except_count = 0;
779
  except_mask = 0;
780
  except_pc = 0;
781
  except_ea = 0;
782
 
783
  /* Check if there was alignment exception on read insn */
784
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
785
  ASSERT(except_count == 1);
786
  ASSERT(except_mask == (1 << V_ALIGN));
787
  ASSERT(ret == 0x12345678);
788
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
789
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
790
 
791
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 2);
792
  ASSERT(except_count == 2);
793
  ASSERT(except_mask == (1 << V_ALIGN));
794
  ASSERT(ret == 0x12345678);
795
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
796
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 2)));
797
 
798
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 3);
799
  ASSERT(except_count == 3);
800
  ASSERT(except_mask == (1 << V_ALIGN));
801
  ASSERT(ret == 0x12345678);
802
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
803
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 3)));
804
 
805
  ret = call ((unsigned long)&load_acc_16, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
806
  ASSERT(except_count == 4);
807
  ASSERT(except_mask == (1 << V_ALIGN));
808
  ASSERT(ret == 0x12345678);
809
  ASSERT(except_pc == ((unsigned long)(load_acc_16) + 8));
810
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
811
 
812
  /* Check alignment exception on write  insn */
813
  call ((unsigned long)&store_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
814
  ASSERT(except_count == 5);
815
  ASSERT(except_mask == (1 << V_ALIGN));
816
  ASSERT(except_pc == ((unsigned long)(store_acc_32) + 8));
817
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
818
 
819
  call ((unsigned long)&store_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 2);
820
  ASSERT(except_count == 6);
821
  ASSERT(except_mask == (1 << V_ALIGN));
822
  ASSERT(except_pc == ((unsigned long)(store_acc_32) + 8));
823
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 2)));
824
 
825
  call ((unsigned long)&store_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 3);
826
  ASSERT(except_count == 7);
827
  ASSERT(except_mask == (1 << V_ALIGN));
828
  ASSERT(except_pc == ((unsigned long)(store_acc_32) + 8));
829
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 3)));
830
 
831
  call ((unsigned long)&store_acc_16, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
832
  ASSERT(except_count == 8);
833
  ASSERT(except_mask == (1 << V_ALIGN));
834
  ASSERT(except_pc == ((unsigned long)(store_acc_16) + 8));
835
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
836
 
837
 
838
  ret = call ((unsigned long)&load_b_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
839
  ASSERT(except_count == 9);
840
  ASSERT(except_mask == (1 << V_ALIGN));
841
  ASSERT(ret == 0x12345678);
842
  ASSERT(except_pc == ((unsigned long)(load_b_acc_32) + 8));
843
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
844
 
845
 
846
  return 0;
847
}
848
 
849
/* Trap test */
850
int trap_test (void)
851
{
852
  /* Reset except counter */
853
  except_count = 0;
854
  except_mask = 0;
855
  except_pc = 0;
856
  except_ea = 0;
857
 
858
  /* Check if there was trap exception */
859
  call ((unsigned long)&trap, 0);
860
  ASSERT(except_count == 1);
861
  ASSERT(except_mask == (1 << V_TRAP));
862
  ASSERT(except_pc == (unsigned long)(trap));
863
 
864
  /* Check if there was trap exception */
865
  call ((unsigned long)&b_trap, 0);
866
  ASSERT(except_count == 2);
867
  ASSERT(except_mask == (1 << V_TRAP));
868
  ASSERT(except_pc == (unsigned long)(b_trap));
869
 
870
  return 0;
871
}
872
 
873
/* Range test */
874
int range_test (void)
875
{
876
  /* Reset except counter */
877
  except_count = 0;
878
  except_mask = 0;
879
  except_pc = 0;
880
  except_ea = 0;
881
 
882
  /* Check if there was range exception */
883
  mtspr (SPR_SR, mfspr (SPR_SR) | SPR_SR_OVE);
884
  call ((unsigned long)&range, 0);
885
  ASSERT(except_count == 1);
886
  ASSERT(except_mask == (1 << V_RANGE));
887
  ASSERT(except_pc == (unsigned long)(range));
888
  ASSERT(except_ea == 0);
889
 
890
  /* Check if there was range exception */
891
  mtspr (SPR_SR, mfspr (SPR_SR) | SPR_SR_OVE);
892
  call ((unsigned long)&b_range, 0);
893
  ASSERT(except_count == 2);
894
  ASSERT(except_mask == (1 << V_RANGE));
895
  ASSERT(except_pc == (unsigned long)(b_range));
896
 
897
  return 0;
898
}
899
 
900
/* Exception priority test */
901
void except_priority_test (void)
902
{
903
  int i, j;
904
  unsigned long ea, ta, ret;
905
 
906
  /* Invalidate all entries in ITLB */
907
  for (i = 0; i < ITLB_WAYS; i++) {
908
    for (j = 0; j < ITLB_SETS; j++) {
909
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
910
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
911
    }
912
  }
913
 
914
  /* Set one to one translation for the use of this program */
915
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
916
    ea = FLASH_START + (i*PAGE_SIZE);
917
    ta = FLASH_START + (i*PAGE_SIZE);
918
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
919
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
920
  }
921
 
922
  /* Set dtlb no permisions */
923
  itlb_val = SPR_ITLBTR_CI;
924
 
925
  /* Invalidate all entries in DTLB */
926
  for (i = 0; i < DTLB_WAYS; i++) {
927
    for (j = 0; j < DTLB_SETS; j++) {
928
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
929
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
930
    }
931
  }
932
 
933
  /* Set one to one translation for the use of this program */
934
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
935
    ea = RAM_START + (i*PAGE_SIZE);
936
    ta = RAM_START + (i*PAGE_SIZE);
937
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
938
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
939
  }
940
 
941
  /* Init tick timer */
942
  tick_init (1, 1);
943
 
944
  /* Set dtlb no permisions */
945
  dtlb_val = SPR_DTLBTR_CI;
946
 
947
  /* Reset except counter */
948
  except_count = 0;
949
  except_mask = 0;
950
  except_pc = 0;
951
  except_ea = 0;
952
 
953
  /* Enable IMMU */
954
  immu_enable ();
955
 
956
  /* Check if there was INT exception */
957
  call_with_int (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE), 0);
958
  ASSERT(except_count == 1);
959
  ASSERT(except_mask == (1 << V_TICK));
960
  ASSERT(except_pc == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
961
 
962
  /* Reset except counter */
963
  except_count = 0;
964
  except_mask = 0;
965
  except_pc = 0;
966
  except_ea = 0;
967
 
968
  /* Check if there was ITLB exception */
969
  call (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE), 0);
970
  ASSERT(except_count == 1);
971
  ASSERT(except_mask == (1 << V_ITLB_MISS));
972
  ASSERT(except_pc == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
973
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
974
 
975
  /* Set dtlb permisions */
976
  itlb_val |= SPR_ITLBTR_SXE;
977
 
978
  /* Reset except counter */
979
  except_count = 0;
980
  except_mask = 0;
981
  except_pc = 0;
982
  except_ea = 0;
983
 
984
  /* Check if there was IPF exception */
985
  call (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE), 0);
986
  ASSERT(except_count == 1);
987
  ASSERT(except_mask == (1 << V_IPF));
988
  ASSERT(except_pc == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
989
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
990
 
991
  /* Reset except counter */
992
  except_count = 0;
993
  except_mask = 0;
994
  except_pc = 0;
995
  except_ea = 0;
996
 
997
  /* Check if there was bus error exception */
998
  call (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE), 0);
999
  ASSERT(except_count == 1);
1000
  ASSERT(except_mask == (1 << V_BERR));
1001
  ASSERT(except_pc == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
1002
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
1003
 
1004
  /* Reset except counter */
1005
  except_count = 0;
1006
  except_mask = 0;
1007
  except_pc = 0;
1008
  except_ea = 0;
1009
 
1010
  /* Disable MMU */
1011
  immu_disable ();
1012
 
1013
  /* Set illegal instruction. JPB. Use a really illegal instruction, not
1014
     l.cust8 0x3ffffff. */
1015
  REG32(RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 0) = 0x00000000;
1016
  REG32(RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 4) = 0xe5dfffff;
1017
  REG32(RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 8) = 0x00000000;
1018
 
1019
  /* Check if there was illegal insn exception */
1020
  call (RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 4, 0);
1021
  ASSERT(except_count == 1);
1022
  ASSERT(except_mask == (1 << V_ILLINSN));
1023
  ASSERT(except_pc == (RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 4));
1024
  ASSERT(except_ea == (RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 4 ));
1025
 
1026
  /* Reset except counter */
1027
  except_count = 0;
1028
  except_mask = 0;
1029
  except_pc = 0;
1030
  except_ea = 0;
1031
 
1032
  /* Enable DMMU */
1033
  dmmu_enable ();
1034
 
1035
  /* Check if there was alignment exception on read insn */
1036
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
1037
  ASSERT(except_count == 1);
1038
  ASSERT(except_mask == (1 << V_ALIGN));
1039
  ASSERT(ret == 0x12345678);
1040
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
1041
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
1042
 
1043
  /* Reset except counter */
1044
  except_count = 0;
1045
  except_mask = 0;
1046
  except_pc = 0;
1047
  except_ea = 0;
1048
 
1049
  /* Check if there was DTLB exception */
1050
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE));
1051
  ASSERT(except_count == 1);
1052
  ASSERT(except_mask == (1 << V_DTLB_MISS));
1053
  ASSERT(ret == 0x12345678);
1054
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
1055
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE)));
1056
 
1057
  /* Reset except counter */
1058
  except_count = 0;
1059
  except_mask = 0;
1060
  except_pc = 0;
1061
  except_ea = 0;
1062
 
1063
  /* Set dtlb permisions */
1064
  dtlb_val |= SPR_DTLBTR_SRE;
1065
 
1066
  /* Check if there was DPF exception */
1067
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE));
1068
  ASSERT(except_count == 1);
1069
  ASSERT(except_mask == (1 << V_DPF));
1070
  ASSERT(ret == 0x12345678);
1071
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
1072
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE)));
1073
 
1074
  /* Reset except counter */
1075
  except_count = 0;
1076
  except_mask = 0;
1077
  except_pc = 0;
1078
  except_ea = 0;
1079
 
1080
  /* Check if there was bus error exception */
1081
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE));
1082
  ASSERT(except_count == 1);
1083
  ASSERT(except_mask == (1 << V_BERR));
1084
  ASSERT(ret == 0x12345678);
1085
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
1086
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE)));
1087
 
1088
  /* Reset except counter */
1089
  except_count = 0;
1090
  except_mask = 0;
1091
  except_pc = 0;
1092
  except_ea = 0;
1093
 
1094
  /* Check if there was trap exception */
1095
  call ((unsigned long)&trap, 0);
1096
  ASSERT(except_count == 1);
1097
  ASSERT(except_mask == (1 << V_TRAP));
1098
  ASSERT(except_pc == (unsigned long)(trap));
1099
 
1100
}
1101
 
1102
int main (void)
1103
{
1104
  int ret;
1105
 
1106
  printf("except_test\n");
1107
 
1108
  /* Register bus error handler */
1109
  excpt_buserr = (unsigned long)bus_err_handler;
1110
 
1111
  /* Register illegal insn handler */
1112
  excpt_illinsn = (unsigned long)ill_insn_handler;
1113
 
1114
  /* Register tick timer exception handler */
1115
  excpt_tick = (unsigned long)tick_handler;
1116
 
1117
  /* Register external interrupt handler */
1118
  excpt_int = (unsigned long)int_handler;
1119
 
1120
  /* Register ITLB miss handler */
1121
  excpt_itlbmiss = (unsigned long)itlb_miss_handler;
1122
 
1123
  /* Register instruction page fault handler */
1124
  excpt_ipfault = (unsigned long)ipage_fault_handler;
1125
 
1126
  /* Register DTLB miss handler */
1127
  excpt_dtlbmiss = (unsigned long)dtlb_miss_handler;
1128
 
1129
  /* Register data page fault handler */
1130
  excpt_dpfault = (unsigned long)dpage_fault_handler;
1131
 
1132
  /* Register trap handler */
1133
  excpt_trap = (unsigned long)trap_handler;
1134
 
1135
  /* Register align handler */
1136
  excpt_align = (unsigned long)align_handler;
1137
 
1138
  /* Register range handler */
1139
  excpt_range = (unsigned long)range_handler;
1140
 
1141
  /* Exception basic test */
1142
  ret = except_basic ();
1143
  ASSERT(ret == 0);
1144
 
1145
  /* Interrupt exception test */
1146
  interrupt_test ();
1147
 
1148
  /* ITLB exception test */
1149
  itlb_test ();
1150
 
1151
printf("dtlb_test\n");
1152
  /* DTLB exception test */
1153
  dtlb_test ();
1154
 
1155
printf("buserr_test\n");
1156
  /* Bus error exception test */
1157
  buserr_test ();
1158
 
1159
printf("illegal_insn_test\n");
1160
  /* Bus error exception test */
1161
  /* Illegal insn test */
1162
  illegal_insn_test ();
1163
 
1164
printf("align_test\n");
1165
  /* Alignment test */
1166
  align_test ();
1167
 
1168
printf("trap_test\n");
1169
  /* Trap test */
1170
  trap_test ();
1171
 
1172
printf("except_priority_test\n");
1173
  /* Range test */
1174
//  range_test ();
1175
 
1176
  /* Exception priority test */
1177
  except_priority_test ();
1178
 
1179
  report (0xdeaddead);
1180
  exit (0);
1181
 
1182
  return 0;
1183
}
1184
 

powered by: WebSVN 2.1.0

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