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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [sim/] [common/] [cgen-par.c] - Blame information for rev 578

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

Line No. Rev Author Line
1 578 markom
/* Simulator parallel routines for CGEN simulators (and maybe others).
2
   Copyright (C) 1999, 2000 Free Software Foundation, Inc.
3
   Contributed by Cygnus Solutions.
4
 
5
This file is part of the GNU instruction set 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, or (at your option)
10
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 along
18
with this program; if not, write to the Free Software Foundation, Inc.,
19
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
 
21
#include "sim-main.h"
22
#include "cgen-mem.h"
23
#include "cgen-par.h"
24
 
25
/* Functions required by the cgen interface.  These functions add various
26
   kinds of writes to the write queue.  */
27
void sim_queue_bi_write (SIM_CPU *cpu, BI *target, BI value)
28
{
29
  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
30
  CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
31
  element->kind = CGEN_BI_WRITE;
32
  element->insn_address = CPU_PC_GET (cpu);
33
  element->kinds.bi_write.target = target;
34
  element->kinds.bi_write.value  = value;
35
}
36
 
37
void sim_queue_qi_write (SIM_CPU *cpu, UQI *target, UQI value)
38
{
39
  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
40
  CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
41
  element->kind = CGEN_QI_WRITE;
42
  element->insn_address = CPU_PC_GET (cpu);
43
  element->kinds.qi_write.target = target;
44
  element->kinds.qi_write.value  = value;
45
}
46
 
47
void sim_queue_si_write (SIM_CPU *cpu, SI *target, SI value)
48
{
49
  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
50
  CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
51
  element->kind = CGEN_SI_WRITE;
52
  element->insn_address = CPU_PC_GET (cpu);
53
  element->kinds.si_write.target = target;
54
  element->kinds.si_write.value  = value;
55
}
56
 
57
void sim_queue_sf_write (SIM_CPU *cpu, SI *target, SF value)
58
{
59
  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
60
  CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
61
  element->kind = CGEN_SF_WRITE;
62
  element->insn_address = CPU_PC_GET (cpu);
63
  element->kinds.sf_write.target = target;
64
  element->kinds.sf_write.value  = value;
65
}
66
 
67
void sim_queue_pc_write (SIM_CPU *cpu, USI value)
68
{
69
  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
70
  CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
71
  element->kind = CGEN_PC_WRITE;
72
  element->insn_address = CPU_PC_GET (cpu);
73
  element->kinds.pc_write.value = value;
74
}
75
 
76
void sim_queue_fn_hi_write (
77
  SIM_CPU *cpu,
78
  void (*write_function)(SIM_CPU *cpu, UINT, UHI),
79
  UINT regno,
80
  UHI value
81
)
82
{
83
  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
84
  CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
85
  element->kind = CGEN_FN_HI_WRITE;
86
  element->insn_address = CPU_PC_GET (cpu);
87
  element->kinds.fn_hi_write.function = write_function;
88
  element->kinds.fn_hi_write.regno = regno;
89
  element->kinds.fn_hi_write.value = value;
90
}
91
 
92
void sim_queue_fn_si_write (
93
  SIM_CPU *cpu,
94
  void (*write_function)(SIM_CPU *cpu, UINT, USI),
95
  UINT regno,
96
  USI value
97
)
98
{
99
  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
100
  CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
101
  element->kind = CGEN_FN_SI_WRITE;
102
  element->insn_address = CPU_PC_GET (cpu);
103
  element->kinds.fn_si_write.function = write_function;
104
  element->kinds.fn_si_write.regno = regno;
105
  element->kinds.fn_si_write.value = value;
106
}
107
 
108
void sim_queue_fn_sf_write (
109
  SIM_CPU *cpu,
110
  void (*write_function)(SIM_CPU *cpu, UINT, SF),
111
  UINT regno,
112
  SF value
113
)
114
{
115
  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
116
  CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
117
  element->kind = CGEN_FN_SF_WRITE;
118
  element->insn_address = CPU_PC_GET (cpu);
119
  element->kinds.fn_sf_write.function = write_function;
120
  element->kinds.fn_sf_write.regno = regno;
121
  element->kinds.fn_sf_write.value = value;
122
}
123
 
124
void sim_queue_fn_di_write (
125
  SIM_CPU *cpu,
126
  void (*write_function)(SIM_CPU *cpu, UINT, DI),
127
  UINT regno,
128
  DI value
129
)
130
{
131
  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
132
  CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
133
  element->kind = CGEN_FN_DI_WRITE;
134
  element->insn_address = CPU_PC_GET (cpu);
135
  element->kinds.fn_di_write.function = write_function;
136
  element->kinds.fn_di_write.regno = regno;
137
  element->kinds.fn_di_write.value = value;
138
}
139
 
140
void sim_queue_fn_xi_write (
141
  SIM_CPU *cpu,
142
  void (*write_function)(SIM_CPU *cpu, UINT, SI *),
143
  UINT regno,
144
  SI *value
145
)
146
{
147
  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
148
  CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
149
  element->kind = CGEN_FN_XI_WRITE;
150
  element->insn_address = CPU_PC_GET (cpu);
151
  element->kinds.fn_xi_write.function = write_function;
152
  element->kinds.fn_xi_write.regno = regno;
153
  element->kinds.fn_xi_write.value[0] = value[0];
154
  element->kinds.fn_xi_write.value[1] = value[1];
155
  element->kinds.fn_xi_write.value[2] = value[2];
156
  element->kinds.fn_xi_write.value[3] = value[3];
157
}
158
 
159
void sim_queue_fn_df_write (
160
  SIM_CPU *cpu,
161
  void (*write_function)(SIM_CPU *cpu, UINT, DF),
162
  UINT regno,
163
  DF value
164
)
165
{
166
  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
167
  CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
168
  element->kind = CGEN_FN_DF_WRITE;
169
  element->insn_address = CPU_PC_GET (cpu);
170
  element->kinds.fn_df_write.function = write_function;
171
  element->kinds.fn_df_write.regno = regno;
172
  element->kinds.fn_df_write.value = value;
173
}
174
 
175
void sim_queue_fn_pc_write (
176
  SIM_CPU *cpu,
177
  void (*write_function)(SIM_CPU *cpu, USI),
178
  USI value
179
)
180
{
181
  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
182
  CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
183
  element->kind = CGEN_FN_PC_WRITE;
184
  element->insn_address = CPU_PC_GET (cpu);
185
  element->kinds.fn_pc_write.function = write_function;
186
  element->kinds.fn_pc_write.value = value;
187
}
188
 
189
void sim_queue_mem_qi_write (SIM_CPU *cpu, SI address, QI value)
190
{
191
  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
192
  CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
193
  element->kind = CGEN_MEM_QI_WRITE;
194
  element->insn_address = CPU_PC_GET (cpu);
195
  element->kinds.mem_qi_write.address = address;
196
  element->kinds.mem_qi_write.value   = value;
197
}
198
 
199
void sim_queue_mem_hi_write (SIM_CPU *cpu, SI address, HI value)
200
{
201
  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
202
  CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
203
  element->kind = CGEN_MEM_HI_WRITE;
204
  element->insn_address = CPU_PC_GET (cpu);
205
  element->kinds.mem_hi_write.address = address;
206
  element->kinds.mem_hi_write.value   = value;
207
}
208
 
209
void sim_queue_mem_si_write (SIM_CPU *cpu, SI address, SI value)
210
{
211
  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
212
  CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
213
  element->kind = CGEN_MEM_SI_WRITE;
214
  element->insn_address = CPU_PC_GET (cpu);
215
  element->kinds.mem_si_write.address = address;
216
  element->kinds.mem_si_write.value   = value;
217
}
218
 
219
void sim_queue_mem_di_write (SIM_CPU *cpu, SI address, DI value)
220
{
221
  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
222
  CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
223
  element->kind = CGEN_MEM_DI_WRITE;
224
  element->insn_address = CPU_PC_GET (cpu);
225
  element->kinds.mem_di_write.address = address;
226
  element->kinds.mem_di_write.value   = value;
227
}
228
 
229
void sim_queue_mem_df_write (SIM_CPU *cpu, SI address, DF value)
230
{
231
  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
232
  CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
233
  element->kind = CGEN_MEM_DF_WRITE;
234
  element->insn_address = CPU_PC_GET (cpu);
235
  element->kinds.mem_df_write.address = address;
236
  element->kinds.mem_df_write.value   = value;
237
}
238
 
239
void sim_queue_mem_xi_write (SIM_CPU *cpu, SI address, SI *value)
240
{
241
  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
242
  CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
243
  element->kind = CGEN_MEM_XI_WRITE;
244
  element->insn_address = CPU_PC_GET (cpu);
245
  element->kinds.mem_xi_write.address = address;
246
  element->kinds.mem_xi_write.value[0] = value[0];
247
  element->kinds.mem_xi_write.value[1] = value[1];
248
  element->kinds.mem_xi_write.value[2] = value[2];
249
  element->kinds.mem_xi_write.value[3] = value[3];
250
}
251
 
252
void sim_queue_fn_mem_qi_write (
253
  SIM_CPU *cpu,
254
  void (*write_function)(SIM_CPU *cpu, IADDR, SI, QI),
255
  SI address,
256
  QI value
257
)
258
{
259
  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
260
  CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
261
  element->kind = CGEN_FN_MEM_QI_WRITE;
262
  element->insn_address = CPU_PC_GET (cpu);
263
  element->kinds.fn_mem_qi_write.function = write_function;
264
  element->kinds.fn_mem_qi_write.address = address;
265
  element->kinds.fn_mem_qi_write.value   = value;
266
}
267
 
268
void sim_queue_fn_mem_hi_write (
269
  SIM_CPU *cpu,
270
  void (*write_function)(SIM_CPU *cpu, IADDR, SI, HI),
271
  SI address,
272
  HI value
273
)
274
{
275
  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
276
  CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
277
  element->kind = CGEN_FN_MEM_HI_WRITE;
278
  element->insn_address = CPU_PC_GET (cpu);
279
  element->kinds.fn_mem_hi_write.function = write_function;
280
  element->kinds.fn_mem_hi_write.address = address;
281
  element->kinds.fn_mem_hi_write.value   = value;
282
}
283
 
284
void sim_queue_fn_mem_si_write (
285
  SIM_CPU *cpu,
286
  void (*write_function)(SIM_CPU *cpu, IADDR, SI, SI),
287
  SI address,
288
  SI value
289
)
290
{
291
  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
292
  CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
293
  element->kind = CGEN_FN_MEM_SI_WRITE;
294
  element->insn_address = CPU_PC_GET (cpu);
295
  element->kinds.fn_mem_si_write.function = write_function;
296
  element->kinds.fn_mem_si_write.address = address;
297
  element->kinds.fn_mem_si_write.value   = value;
298
}
299
 
300
void sim_queue_fn_mem_di_write (
301
  SIM_CPU *cpu,
302
  void (*write_function)(SIM_CPU *cpu, IADDR, SI, DI),
303
  SI address,
304
  DI value
305
)
306
{
307
  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
308
  CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
309
  element->kind = CGEN_FN_MEM_DI_WRITE;
310
  element->insn_address = CPU_PC_GET (cpu);
311
  element->kinds.fn_mem_di_write.function = write_function;
312
  element->kinds.fn_mem_di_write.address = address;
313
  element->kinds.fn_mem_di_write.value   = value;
314
}
315
 
316
void sim_queue_fn_mem_df_write (
317
  SIM_CPU *cpu,
318
  void (*write_function)(SIM_CPU *cpu, IADDR, SI, DF),
319
  SI address,
320
  DF value
321
)
322
{
323
  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
324
  CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
325
  element->kind = CGEN_FN_MEM_DF_WRITE;
326
  element->insn_address = CPU_PC_GET (cpu);
327
  element->kinds.fn_mem_df_write.function = write_function;
328
  element->kinds.fn_mem_df_write.address = address;
329
  element->kinds.fn_mem_df_write.value   = value;
330
}
331
 
332
void sim_queue_fn_mem_xi_write (
333
  SIM_CPU *cpu,
334
  void (*write_function)(SIM_CPU *cpu, IADDR, SI, SI *),
335
  SI address,
336
  SI *value
337
)
338
{
339
  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
340
  CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
341
  element->kind = CGEN_FN_MEM_XI_WRITE;
342
  element->insn_address = CPU_PC_GET (cpu);
343
  element->kinds.fn_mem_xi_write.function = write_function;
344
  element->kinds.fn_mem_xi_write.address = address;
345
  element->kinds.fn_mem_xi_write.value[0] = value[0];
346
  element->kinds.fn_mem_xi_write.value[1] = value[1];
347
  element->kinds.fn_mem_xi_write.value[2] = value[2];
348
  element->kinds.fn_mem_xi_write.value[3] = value[3];
349
}
350
 
351
/* Execute a write stored on the write queue.  */
352
void
353
cgen_write_queue_element_execute (SIM_CPU *cpu, CGEN_WRITE_QUEUE_ELEMENT *item)
354
{
355
  IADDR pc;
356
  switch (CGEN_WRITE_QUEUE_ELEMENT_KIND (item))
357
    {
358
    case CGEN_BI_WRITE:
359
      *item->kinds.bi_write.target = item->kinds.bi_write.value;
360
      break;
361
    case CGEN_QI_WRITE:
362
      *item->kinds.qi_write.target = item->kinds.qi_write.value;
363
      break;
364
    case CGEN_SI_WRITE:
365
      *item->kinds.si_write.target = item->kinds.si_write.value;
366
      break;
367
    case CGEN_SF_WRITE:
368
      *item->kinds.sf_write.target = item->kinds.sf_write.value;
369
      break;
370
    case CGEN_PC_WRITE:
371
      CPU_PC_SET (cpu, item->kinds.pc_write.value);
372
      break;
373
    case CGEN_FN_HI_WRITE:
374
      item->kinds.fn_hi_write.function (cpu,
375
                                        item->kinds.fn_hi_write.regno,
376
                                        item->kinds.fn_hi_write.value);
377
      break;
378
    case CGEN_FN_SI_WRITE:
379
      item->kinds.fn_si_write.function (cpu,
380
                                        item->kinds.fn_si_write.regno,
381
                                        item->kinds.fn_si_write.value);
382
      break;
383
    case CGEN_FN_SF_WRITE:
384
      item->kinds.fn_sf_write.function (cpu,
385
                                        item->kinds.fn_sf_write.regno,
386
                                        item->kinds.fn_sf_write.value);
387
      break;
388
    case CGEN_FN_DI_WRITE:
389
      item->kinds.fn_di_write.function (cpu,
390
                                        item->kinds.fn_di_write.regno,
391
                                        item->kinds.fn_di_write.value);
392
      break;
393
    case CGEN_FN_DF_WRITE:
394
      item->kinds.fn_df_write.function (cpu,
395
                                        item->kinds.fn_df_write.regno,
396
                                        item->kinds.fn_df_write.value);
397
      break;
398
    case CGEN_FN_XI_WRITE:
399
      item->kinds.fn_xi_write.function (cpu,
400
                                        item->kinds.fn_xi_write.regno,
401
                                        item->kinds.fn_xi_write.value);
402
      break;
403
    case CGEN_FN_PC_WRITE:
404
      item->kinds.fn_pc_write.function (cpu, item->kinds.fn_pc_write.value);
405
      break;
406
    case CGEN_MEM_QI_WRITE:
407
      pc = item->insn_address;
408
      SETMEMQI (cpu, pc, item->kinds.mem_qi_write.address,
409
                item->kinds.mem_qi_write.value);
410
      break;
411
    case CGEN_MEM_HI_WRITE:
412
      pc = item->insn_address;
413
      SETMEMHI (cpu, pc, item->kinds.mem_hi_write.address,
414
                item->kinds.mem_hi_write.value);
415
      break;
416
    case CGEN_MEM_SI_WRITE:
417
      pc = item->insn_address;
418
      SETMEMSI (cpu, pc, item->kinds.mem_si_write.address,
419
                item->kinds.mem_si_write.value);
420
      break;
421
    case CGEN_MEM_DI_WRITE:
422
      pc = item->insn_address;
423
      SETMEMDI (cpu, pc, item->kinds.mem_di_write.address,
424
                item->kinds.mem_di_write.value);
425
      break;
426
    case CGEN_MEM_DF_WRITE:
427
      pc = item->insn_address;
428
      SETMEMDF (cpu, pc, item->kinds.mem_df_write.address,
429
                item->kinds.mem_df_write.value);
430
      break;
431
    case CGEN_MEM_XI_WRITE:
432
      pc = item->insn_address;
433
      SETMEMSI (cpu, pc, item->kinds.mem_xi_write.address,
434
                item->kinds.mem_xi_write.value[0]);
435
      SETMEMSI (cpu, pc, item->kinds.mem_xi_write.address + 4,
436
                item->kinds.mem_xi_write.value[1]);
437
      SETMEMSI (cpu, pc, item->kinds.mem_xi_write.address + 8,
438
                item->kinds.mem_xi_write.value[2]);
439
      SETMEMSI (cpu, pc, item->kinds.mem_xi_write.address + 12,
440
                item->kinds.mem_xi_write.value[3]);
441
      break;
442
    case CGEN_FN_MEM_QI_WRITE:
443
      pc = item->insn_address;
444
      item->kinds.fn_mem_qi_write.function (cpu, pc,
445
                                            item->kinds.fn_mem_qi_write.address,
446
                                            item->kinds.fn_mem_qi_write.value);
447
      break;
448
    case CGEN_FN_MEM_HI_WRITE:
449
      pc = item->insn_address;
450
      item->kinds.fn_mem_hi_write.function (cpu, pc,
451
                                            item->kinds.fn_mem_hi_write.address,
452
                                            item->kinds.fn_mem_hi_write.value);
453
      break;
454
    case CGEN_FN_MEM_SI_WRITE:
455
      pc = item->insn_address;
456
      item->kinds.fn_mem_si_write.function (cpu, pc,
457
                                            item->kinds.fn_mem_si_write.address,
458
                                            item->kinds.fn_mem_si_write.value);
459
      break;
460
    case CGEN_FN_MEM_DI_WRITE:
461
      pc = item->insn_address;
462
      item->kinds.fn_mem_di_write.function (cpu, pc,
463
                                            item->kinds.fn_mem_di_write.address,
464
                                            item->kinds.fn_mem_di_write.value);
465
      break;
466
    case CGEN_FN_MEM_DF_WRITE:
467
      pc = item->insn_address;
468
      item->kinds.fn_mem_df_write.function (cpu, pc,
469
                                            item->kinds.fn_mem_df_write.address,
470
                                            item->kinds.fn_mem_df_write.value);
471
      break;
472
    case CGEN_FN_MEM_XI_WRITE:
473
      pc = item->insn_address;
474
      item->kinds.fn_mem_xi_write.function (cpu, pc,
475
                                            item->kinds.fn_mem_xi_write.address,
476
                                            item->kinds.fn_mem_xi_write.value);
477
      break;
478
    default:
479
      abort ();
480
      break; /* FIXME: for now....print message later.  */
481
    }
482
}
483
 
484
/* Utilities for the write queue.  */
485
CGEN_WRITE_QUEUE_ELEMENT *
486
cgen_write_queue_overflow (CGEN_WRITE_QUEUE *q)
487
{
488
  abort (); /* FIXME: for now....print message later.  */
489
  return 0;
490
}

powered by: WebSVN 2.1.0

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