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

Subversion Repositories ethmac

[/] [ethmac/] [tags/] [rel_4/] [bench/] [verilog/] [tb_ethernet.v] - Blame information for rev 338

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 116 mohor
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  tb_ethernet.v                                               ////
4
////                                                              ////
5
////  This file is part of the Ethernet IP core project           ////
6
////  http://www.opencores.org/projects/ethmac/                   ////
7
////                                                              ////
8
////  Author(s):                                                  ////
9
////      - Igor Mohor (igorM@opencores.org)                      ////
10
////                                                              ////
11
////  All additional information is avaliable in the Readme.txt   ////
12
////  file.                                                       ////
13
////                                                              ////
14
//////////////////////////////////////////////////////////////////////
15
////                                                              ////
16
//// Copyright (C) 2001, 2002 Authors                             ////
17
////                                                              ////
18
//// This source file may be used and distributed without         ////
19
//// restriction provided that this copyright statement is not    ////
20
//// removed from the file and that any derivative work contains  ////
21
//// the original copyright notice and the associated disclaimer. ////
22
////                                                              ////
23
//// This source file is free software; you can redistribute it   ////
24
//// and/or modify it under the terms of the GNU Lesser General   ////
25
//// Public License as published by the Free Software Foundation; ////
26
//// either version 2.1 of the License, or (at your option) any   ////
27
//// later version.                                               ////
28
////                                                              ////
29
//// This source is distributed in the hope that it will be       ////
30
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
31
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
32
//// PURPOSE.  See the GNU Lesser General Public License for more ////
33
//// details.                                                     ////
34
////                                                              ////
35
//// You should have received a copy of the GNU Lesser General    ////
36
//// Public License along with this source; if not, download it   ////
37
//// from http://www.opencores.org/lgpl.shtml                     ////
38
////                                                              ////
39
//////////////////////////////////////////////////////////////////////
40
//
41
// CVS Revision History
42
//
43
// $Log: not supported by cvs2svn $
44 121 mohor
// Revision 1.2  2002/07/19 14:02:47  mohor
45
// Clock mrx_clk set to 2.5 MHz.
46
//
47 117 mohor
// Revision 1.1  2002/07/19 13:57:53  mohor
48
// Testing environment also includes traffic cop, memory interface and host
49
// interface.
50 116 mohor
//
51
//
52
//
53
//
54 117 mohor
//
55 116 mohor
 
56
 
57
 
58
`include "tb_eth_defines.v"
59
`include "eth_defines.v"
60
`include "timescale.v"
61
 
62
module tb_ethernet();
63
 
64
 
65
parameter Tp = 1;
66
 
67
 
68
reg           wb_clk_o;
69
reg           wb_rst_o;
70
 
71
reg           mtx_clk;
72
reg           mrx_clk;
73
 
74
wire   [3:0]  MTxD;
75
wire          MTxEn;
76
wire          MTxErr;
77
 
78
reg    [3:0]  MRxD;     // This goes to PHY
79
reg           MRxDV;    // This goes to PHY
80
reg           MRxErr;   // This goes to PHY
81
reg           MColl;    // This goes to PHY
82
reg           MCrs;     // This goes to PHY
83
 
84
wire          Mdi_I;
85
wire          Mdo_O;
86
wire          Mdo_OE;
87
wire          Mdc_O;
88
 
89
integer tx_log;
90
integer rx_log;
91
 
92
reg StartTB;
93
 
94 121 mohor
`ifdef ETH_XILINX_RAMB4
95
  reg gsr;
96
`endif
97
 
98
 
99 116 mohor
integer packet_ready_cnt, send_packet_cnt;
100
 
101
 
102
// Ethernet Slave Interface signals
103
wire [31:0] eth_sl_wb_adr_i, eth_sl_wb_dat_o, eth_sl_wb_dat_i;
104
wire  [3:0] eth_sl_wb_sel_i;
105
wire        eth_sl_wb_we_i, eth_sl_wb_cyc_i, eth_sl_wb_stb_i, eth_sl_wb_ack_o, eth_sl_wb_err_o;
106
 
107
// Memory Slave Interface signals
108
wire [31:0] mem_sl_wb_adr_i, mem_sl_wb_dat_o, mem_sl_wb_dat_i;
109
wire  [3:0] mem_sl_wb_sel_i;
110
wire        mem_sl_wb_we_i, mem_sl_wb_cyc_i, mem_sl_wb_stb_i, mem_sl_wb_ack_o, mem_sl_wb_err_o;
111
 
112
// Ethernet Master Interface signals
113
wire [31:0] eth_ma_wb_adr_o, eth_ma_wb_dat_i, eth_ma_wb_dat_o;
114
wire  [3:0] eth_ma_wb_sel_o;
115
wire        eth_ma_wb_we_o, eth_ma_wb_cyc_o, eth_ma_wb_stb_o, eth_ma_wb_ack_i, eth_ma_wb_err_i;
116
 
117
// Host Master Interface signals
118
wire [31:0] host_ma_wb_adr_o, host_ma_wb_dat_i, host_ma_wb_dat_o;
119
wire  [3:0] host_ma_wb_sel_o;
120
wire        host_ma_wb_we_o, host_ma_wb_cyc_o, host_ma_wb_stb_o, host_ma_wb_ack_i, host_ma_wb_err_i;
121
 
122
 
123
 
124
eth_cop i_eth_cop
125
(
126
  // WISHBONE common
127
  .wb_clk_i(wb_clk_o), .wb_rst_i(wb_rst_o),
128
 
129
  // WISHBONE MASTER 1  Ethernet Master Interface is connected here
130
  .m1_wb_adr_i(eth_ma_wb_adr_o),  .m1_wb_sel_i(eth_ma_wb_sel_o),  .m1_wb_we_i (eth_ma_wb_we_o),
131
  .m1_wb_dat_o(eth_ma_wb_dat_i),  .m1_wb_dat_i(eth_ma_wb_dat_o),  .m1_wb_cyc_i(eth_ma_wb_cyc_o),
132
  .m1_wb_stb_i(eth_ma_wb_stb_o),  .m1_wb_ack_o(eth_ma_wb_ack_i),  .m1_wb_err_o(eth_ma_wb_err_i),
133
 
134
  // WISHBONE MASTER 2  Host Interface is connected here
135
  .m2_wb_adr_i(host_ma_wb_adr_o), .m2_wb_sel_i(host_ma_wb_sel_o), .m2_wb_we_i (host_ma_wb_we_o),
136
  .m2_wb_dat_o(host_ma_wb_dat_i), .m2_wb_dat_i(host_ma_wb_dat_o), .m2_wb_cyc_i(host_ma_wb_cyc_o),
137
  .m2_wb_stb_i(host_ma_wb_stb_o), .m2_wb_ack_o(host_ma_wb_ack_i), .m2_wb_err_o(host_ma_wb_err_i),
138
 
139
  // WISHBONE slave 1   Ethernet Slave Interface is connected here
140
        .s1_wb_adr_o(eth_sl_wb_adr_i),  .s1_wb_sel_o(eth_sl_wb_sel_i),  .s1_wb_we_o (eth_sl_wb_we_i),
141
        .s1_wb_cyc_o(eth_sl_wb_cyc_i),  .s1_wb_stb_o(eth_sl_wb_stb_i),  .s1_wb_ack_i(eth_sl_wb_ack_o),
142
        .s1_wb_err_i(eth_sl_wb_err_o),  .s1_wb_dat_i(eth_sl_wb_dat_o),  .s1_wb_dat_o(eth_sl_wb_dat_i),
143
 
144
  // WISHBONE slave 2   Memory Interface is connected here
145
        .s2_wb_adr_o(mem_sl_wb_adr_i),  .s2_wb_sel_o(mem_sl_wb_sel_i),  .s2_wb_we_o (mem_sl_wb_we_i),
146
        .s2_wb_cyc_o(mem_sl_wb_cyc_i),  .s2_wb_stb_o(mem_sl_wb_stb_i),  .s2_wb_ack_i(mem_sl_wb_ack_o),
147
        .s2_wb_err_i(mem_sl_wb_err_o),  .s2_wb_dat_i(mem_sl_wb_dat_o),  .s2_wb_dat_o(mem_sl_wb_dat_i)
148
);
149
 
150
 
151
 
152
 
153
// Connecting Ethernet top module
154
eth_top ethtop
155
(
156
  // WISHBONE common
157
  .wb_clk_i(wb_clk_o),              .wb_rst_i(wb_rst_o),
158
 
159
  // WISHBONE slave
160
        .wb_adr_i(eth_sl_wb_adr_i[11:2]), .wb_sel_i(eth_sl_wb_sel_i),   .wb_we_i(eth_sl_wb_we_i),
161
        .wb_cyc_i(eth_sl_wb_cyc_i),       .wb_stb_i(eth_sl_wb_stb_i),   .wb_ack_o(eth_sl_wb_ack_o),
162
        .wb_err_o(eth_sl_wb_err_o),       .wb_dat_i(eth_sl_wb_dat_i),   .wb_dat_o(eth_sl_wb_dat_o),
163
 
164
  // WISHBONE master
165
  .m_wb_adr_o(eth_ma_wb_adr_o),     .m_wb_sel_o(eth_ma_wb_sel_o), .m_wb_we_o(eth_ma_wb_we_o),
166
  .m_wb_dat_i(eth_ma_wb_dat_i),     .m_wb_dat_o(eth_ma_wb_dat_o), .m_wb_cyc_o(eth_ma_wb_cyc_o),
167
  .m_wb_stb_o(eth_ma_wb_stb_o),     .m_wb_ack_i(eth_ma_wb_ack_i), .m_wb_err_i(eth_ma_wb_err_i),
168
 
169
  //TX
170
  .mtx_clk_pad_i(mtx_clk), .mtxd_pad_o(MTxD), .mtxen_pad_o(MTxEn), .mtxerr_pad_o(MTxErr),
171
 
172
  //RX
173
  .mrx_clk_pad_i(mrx_clk), .mrxd_pad_i(MRxD), .mrxdv_pad_i(MRxDV), .mrxerr_pad_i(MRxErr),
174
  .mcoll_pad_i(MColl),    .mcrs_pad_i(MCrs),
175
 
176
  // MIIM
177
  .mdc_pad_o(Mdc_O), .md_pad_i(Mdi_I), .md_pad_o(Mdo_O), .md_padoe_o(Mdo_OE),
178
 
179
  .int_o()
180
);
181
 
182
 
183
 
184
// Connecting Memory Interface Module
185
eth_memory i_eth_memory
186
(
187
  // WISHBONE common
188
        .wb_clk_i(wb_clk_o),         .wb_rst_i(wb_rst_o),
189
 
190
  // WISHBONE slave:   Memory Interface is connected here
191
        .wb_adr_i(mem_sl_wb_adr_i),  .wb_sel_i(mem_sl_wb_sel_i),  .wb_we_i (mem_sl_wb_we_i),
192
        .wb_cyc_i(mem_sl_wb_cyc_i),  .wb_stb_i(mem_sl_wb_stb_i),  .wb_ack_o(mem_sl_wb_ack_o),
193
        .wb_err_o(mem_sl_wb_err_o),  .wb_dat_o(mem_sl_wb_dat_o),  .wb_dat_i(mem_sl_wb_dat_i)
194
);
195
 
196
 
197
// Connecting Host Interface
198
eth_host eth_host
199
(
200
  // WISHBONE common
201
  .wb_clk_i(wb_clk_o),         .wb_rst_i(wb_rst_o),
202
 
203
  // WISHBONE master
204
  .wb_adr_o(host_ma_wb_adr_o), .wb_sel_o(host_ma_wb_sel_o), .wb_we_o (host_ma_wb_we_o),
205
  .wb_dat_i(host_ma_wb_dat_i), .wb_dat_o(host_ma_wb_dat_o), .wb_cyc_o(host_ma_wb_cyc_o),
206
  .wb_stb_o(host_ma_wb_stb_o), .wb_ack_i(host_ma_wb_ack_i), .wb_err_i(host_ma_wb_err_i)
207
);
208
 
209
 
210
 
211
 
212
 
213
// Reset pulse
214
initial
215
begin
216
  MCrs=0;                                     // This should come from PHY
217
  MColl=0;                                    // This should come from PHY
218
  MRxD=0;                                     // This should come from PHY
219
  MRxDV=0;                                    // This should come from PHY
220
  MRxErr=0;                                   // This should come from PHY
221
  packet_ready_cnt = 0;
222
  send_packet_cnt = 0;
223
  tx_log = $fopen("ethernet_tx.log");
224
  rx_log = $fopen("ethernet_rx.log");
225
  wb_rst_o =  1'b1;
226 121 mohor
`ifdef ETH_XILINX_RAMB4
227
  gsr           =  1'b0;
228
  #100 gsr      =  1'b1;
229
  #100 gsr      =  1'b0;
230
`endif
231 116 mohor
  #100 wb_rst_o =  1'b0;
232
  #100 StartTB  =  1'b1;
233
end
234
 
235 121 mohor
`ifdef ETH_XILINX_RAMB4
236
  assign glbl.GSR = gsr;
237
`endif
238 116 mohor
 
239
 
240 121 mohor
 
241 116 mohor
// Generating wb_clk_o clock
242
initial
243
begin
244
  wb_clk_o=0;
245
//  forever #2.5 wb_clk_o = ~wb_clk_o;  // 2*2.5 ns -> 200.0 MHz    
246
//  forever #5 wb_clk_o = ~wb_clk_o;  // 2*5 ns -> 100.0 MHz    
247
//  forever #10 wb_clk_o = ~wb_clk_o;  // 2*10 ns -> 50.0 MHz    
248 117 mohor
  forever #12.5 wb_clk_o = ~wb_clk_o;  // 2*12.5 ns -> 40 MHz    
249 116 mohor
//  forever #15 wb_clk_o = ~wb_clk_o;  // 2*10 ns -> 33.3 MHz    
250 117 mohor
//  forever #20 wb_clk_o = ~wb_clk_o;  // 2*20 ns -> 25 MHz    
251 116 mohor
//  forever #25 wb_clk_o = ~wb_clk_o;  // 2*25 ns -> 20.0 MHz
252
//  forever #31.25 wb_clk_o = ~wb_clk_o;  // 2*31.25 ns -> 16.0 MHz    
253
//  forever #50 wb_clk_o = ~wb_clk_o;  // 2*50 ns -> 10.0 MHz
254
//  forever #55 wb_clk_o = ~wb_clk_o;  // 2*55 ns ->  9.1 MHz    
255
end
256
 
257
// Generating mtx_clk clock
258
initial
259
begin
260
  mtx_clk=0;
261
//  #3 forever #20 mtx_clk = ~mtx_clk;   // 2*20 ns -> 25 MHz
262
  #3 forever #200 mtx_clk = ~mtx_clk;   // 2*200 ns -> 2.5 MHz
263
end
264
 
265
// Generating mrx_clk clock
266
initial
267
begin
268
  mrx_clk=0;
269 117 mohor
//  #16 forever #20 mrx_clk = ~mrx_clk;   // 2*20 ns -> 25 MHz
270
  #16 forever #200 mrx_clk = ~mrx_clk;   // 2*200 ns -> 2.5 MHz
271 116 mohor
end
272
 
273
reg [31:0] tmp;
274
initial
275
begin
276
  wait(StartTB);  // Start of testbench
277
 
278
 
279
  eth_host.wb_write(`ETH_MODER, 4'hf, 32'h0); // Reset OFF
280
  eth_host.wb_read(`ETH_MODER, 4'hf, tmp);
281
 
282
  eth_host.wb_write(32'hd0000000, 4'hf, `ETH_MODER_RXEN  | `ETH_MODER_TXEN | `ETH_MODER_PRO |
283
                                        `ETH_MODER_CRCEN | `ETH_MODER_PAD); // Set MODER register
284
  eth_host.wb_read(32'hd0000000, 4'hf, tmp);
285
 
286
 
287
  initialize_txbd(3);
288
  initialize_rxbd(6);
289
 
290
  set_packet(16'h34, 8'h1);
291
  set_packet(16'h34, 8'h11);
292
  send_packet;
293
  set_packet(16'h34, 8'h21);
294
  set_packet(16'h34, 8'h31);
295
  send_packet;
296
 
297
  GetDataOnMRxD(100, `BROADCAST_XFR); // LengthRx bytes is comming on MRxD[3:0] signals
298
 
299
  repeat (100) @(posedge mrx_clk);   // Waiting for TxEthMac to finish transmit
300
 
301
 
302
  GetDataOnMRxD(70, `BROADCAST_XFR); // LengthRx bytes is comming on MRxD[3:0] signals
303
 
304
 
305
  repeat (10000) @(posedge wb_clk_o);   // Waiting for TxEthMac to finish transmit
306
 
307
  $display("\n\n End of simulation");
308
  $stop;
309
 
310
 
311
 
312
end
313
 
314
 
315
 
316
task initialize_txbd;
317
  input [6:0] txbd_num;
318
 
319
  integer i;
320
  integer bd_status_addr, buf_addr, bd_ptr_addr;
321
 
322
  for(i=0; i<txbd_num; i=i+1) begin
323
    buf_addr = `TX_BUF_BASE + i * 32'h600;
324
    bd_status_addr = `TX_BD_BASE + i * 8;
325
    bd_ptr_addr = bd_status_addr + 4;
326
 
327
    // Initializing BD - status
328
    if(i==txbd_num-1)
329
      eth_host.wb_write(bd_status_addr, 4'hf, 32'h00007800);    // last BD: + WRAP
330
    else
331
      eth_host.wb_write(bd_status_addr, 4'hf, 32'h00005800);    // IRQ + PAD + CRC
332
 
333
    eth_host.wb_write(bd_ptr_addr, 4'hf, buf_addr);             // Initializing BD - pointer
334
  end
335
endtask // initialize_txbd
336
 
337
 
338
task initialize_rxbd;
339
  input [6:0] rxbd_num;
340
 
341
  integer i;
342
  integer bd_status_addr, buf_addr, bd_ptr_addr;
343
 
344
  for(i=0; i<rxbd_num; i=i+1) begin
345
    buf_addr = `RX_BUF_BASE + i * 32'h600;
346
    bd_status_addr = `RX_BD_BASE + i * 8;
347
    bd_ptr_addr = bd_status_addr + 4;
348
 
349
    // Initializing BD - status
350
    if(i==rxbd_num-1)
351
      eth_host.wb_write(bd_status_addr, 4'hf, 32'h0000e000);    // last BD: + WRAP
352
    else
353
      eth_host.wb_write(bd_status_addr, 4'hf, 32'h0000c000);    // IRQ + PAD + CRC
354
 
355
    eth_host.wb_write(bd_ptr_addr, 4'hf, buf_addr);             // Initializing BD - pointer
356
  end
357
endtask // initialize_rxbd
358
 
359
 
360
task set_packet;
361
  input  [15:0] len;
362
  input   [7:0] start_data;
363
 
364
  integer i, sd;
365
  integer bd_status_addr, bd_ptr_addr, buffer, bd;
366
 
367
  begin
368
    sd = start_data;
369
    bd_status_addr = `TX_BD_BASE + packet_ready_cnt * 8;
370
    bd_ptr_addr = bd_status_addr + 4;
371
 
372
    // Reading BD + buffer pointer
373
    eth_host.wb_read(bd_status_addr, 4'hf, bd);
374
    eth_host.wb_read(bd_ptr_addr, 4'hf, buffer);
375
 
376
    while(bd & `ETH_TX_BD_READY) begin  // Buffer is ready. Don't touch !!!
377
      repeat(100) @(posedge wb_clk_o);
378
      i=i+1;
379
      eth_host.wb_read(bd_status_addr, 4'hf, bd);
380
      if(i>1000)  begin
381
        $display("(%0t)(%m)Waiting for TxBD ready to clear timeout", $time);
382
        $stop;
383
      end
384
    end
385
 
386
    // First write might not be word allign.
387
    if(buffer[1:0]==1)  begin
388
      eth_host.wb_write(buffer-1, 4'h7, {8'h0, sd[7:0], sd[7:0]+3'h1, sd[7:0]+3'h2});
389
      sd=sd+3;
390
      i=3;
391
    end
392
    else if(buffer[1:0]==2)  begin
393
      eth_host.wb_write(buffer-2, 4'h3, {16'h0, sd[7:0], sd[7:0]+3'h1});
394
      sd=sd+2;
395
      i=2;
396
    end
397
    else if(buffer[1:0]==3)  begin
398
      eth_host.wb_write(buffer-3, 4'h1, {24'h0, sd[7:0]});
399
      sd=sd+1;
400
      i=1;
401
    end
402
    else
403
      i=0;
404
 
405
 
406
    for(i=i; i<len-4; i=i+4) begin   // Last 0-3 bytes are not written
407
      eth_host.wb_write(buffer+i, 4'hf, {sd[7:0], sd[7:0]+3'h1, sd[7:0]+3'h2, sd[7:0]+3'h3});
408
      sd=sd+4;
409
    end
410
 
411
 
412
    // Last word
413
    if(len-i==3)
414
      eth_host.wb_write(buffer+i, 4'he, {sd[7:0], sd[7:0]+3'h1, sd[7:0]+3'h2, 8'h0});
415
    else if(len-i==2)
416
      eth_host.wb_write(buffer+i, 4'hc, {sd[7:0], sd[7:0]+3'h1, 16'h0});
417
    else if(len-i==1)
418
      eth_host.wb_write(buffer+i, 4'h8, {sd[7:0], 24'h0});
419
    else if(len-i==4)
420
      eth_host.wb_write(buffer+i, 4'hf, {sd[7:0], sd[7:0]+3'h1, sd[7:0]+3'h2, sd[7:0]+3'h3});
421
    else
422
      $display("(%0t)(%m) ERROR", $time);
423
 
424
 
425
    // Checking WRAP bit
426
    if(bd & `ETH_TX_BD_WRAP)
427
      packet_ready_cnt = 0;
428
    else
429
      packet_ready_cnt = packet_ready_cnt+1;
430
 
431
    // Writing len to bd
432
    bd = bd | (len<<16);
433
    eth_host.wb_write(bd_status_addr, 4'hf, bd);
434
 
435
  end
436
endtask // set_packet
437
 
438
 
439
task send_packet;
440
 
441
  integer bd_status_addr, bd_ptr_addr, buffer, bd;
442
 
443
  begin
444
    bd_status_addr = `TX_BD_BASE + send_packet_cnt * 8;
445
    bd_ptr_addr = bd_status_addr + 4;
446
 
447
    // Reading BD + buffer pointer
448
    eth_host.wb_read(bd_status_addr, 4'hf, bd);
449
    eth_host.wb_read(bd_ptr_addr, 4'hf, buffer);
450
 
451
    if(bd & `ETH_TX_BD_WRAP)
452
      send_packet_cnt=0;
453
    else
454
      send_packet_cnt=send_packet_cnt+1;
455
 
456
    // Setting ETH_TX_BD_READY bit
457
    bd = bd | `ETH_TX_BD_READY;
458
    eth_host.wb_write(bd_status_addr, 4'hf, bd);
459
  end
460
 
461
 
462
endtask // send_packet
463
 
464
 
465
task GetDataOnMRxD;
466
  input [15:0] Len;
467
  input [31:0] TransferType;
468
  integer tt;
469
 
470
  begin
471
    @ (posedge mrx_clk);
472
    #1MRxDV=1'b1;
473
 
474
    for(tt=0; tt<15; tt=tt+1)
475
      begin
476
        MRxD=4'h5;              // preamble
477
        @ (posedge mrx_clk);
478
        #1;
479
      end
480
 
481
    MRxD=4'hd;                // SFD
482
 
483
    for(tt=1; tt<(Len+1); tt=tt+1)
484
      begin
485
        @ (posedge mrx_clk);
486
        #1;
487
            if(TransferType == `UNICAST_XFR && tt == 1)
488
                MRxD= 4'h0;   // Unicast transfer
489
              else if(TransferType == `BROADCAST_XFR && tt < 7)
490
                MRxD = 4'hf;
491
              else
492
          MRxD=tt[3:0]; // Multicast transfer
493
 
494
        @ (posedge mrx_clk);
495
              #1;
496
              if(TransferType == `BROADCAST_XFR && tt < 7)
497
                MRxD = 4'hf;
498
              else
499
          MRxD=tt[7:4];
500
      end
501
 
502
    @ (posedge mrx_clk);
503
    #1;
504
    MRxDV=1'b0;
505
  end
506
endtask // GetDataOnMRxD
507
 
508
 
509
endmodule

powered by: WebSVN 2.1.0

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