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

Subversion Repositories ethmac

[/] [ethmac/] [trunk/] [bench/] [verilog/] [tb_ethernet.v] - Blame information for rev 178

Go to most recent revision | 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 169 mohor
////      - Tadej Markovic, tadej@opencores.org                   ////
10 170 mohor
////      - Igor Mohor,     igormM@opencores.org                  ////
11 116 mohor
////                                                              ////
12 169 mohor
////  All additional information is available in the Readme.txt   ////
13 116 mohor
////  file.                                                       ////
14
////                                                              ////
15
//////////////////////////////////////////////////////////////////////
16
////                                                              ////
17
//// Copyright (C) 2001, 2002 Authors                             ////
18
////                                                              ////
19
//// This source file may be used and distributed without         ////
20
//// restriction provided that this copyright statement is not    ////
21
//// removed from the file and that any derivative work contains  ////
22
//// the original copyright notice and the associated disclaimer. ////
23
////                                                              ////
24
//// This source file is free software; you can redistribute it   ////
25
//// and/or modify it under the terms of the GNU Lesser General   ////
26
//// Public License as published by the Free Software Foundation; ////
27
//// either version 2.1 of the License, or (at your option) any   ////
28
//// later version.                                               ////
29
////                                                              ////
30
//// This source is distributed in the hope that it will be       ////
31
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
32
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
33
//// PURPOSE.  See the GNU Lesser General Public License for more ////
34
//// details.                                                     ////
35
////                                                              ////
36
//// You should have received a copy of the GNU Lesser General    ////
37
//// Public License along with this source; if not, download it   ////
38
//// from http://www.opencores.org/lgpl.shtml                     ////
39
////                                                              ////
40
//////////////////////////////////////////////////////////////////////
41
//
42
// CVS Revision History
43
//
44
// $Log: not supported by cvs2svn $
45 178 mohor
// Revision 1.8  2002/09/13 14:50:15  mohor
46
// Bug in MIIM fixed.
47
//
48 177 mohor
// Revision 1.7  2002/09/13 12:29:14  mohor
49
// Headers changed.
50
//
51 170 mohor
// Revision 1.6  2002/09/13 11:57:20  mohor
52
// New testbench. Thanks to Tadej M - "The Spammer".
53
//
54 121 mohor
// Revision 1.2  2002/07/19 14:02:47  mohor
55
// Clock mrx_clk set to 2.5 MHz.
56
//
57 117 mohor
// Revision 1.1  2002/07/19 13:57:53  mohor
58
// Testing environment also includes traffic cop, memory interface and host
59
// interface.
60 116 mohor
//
61
//
62
//
63
//
64 117 mohor
//
65 116 mohor
 
66
 
67 169 mohor
`include "eth_phy_defines.v"
68
`include "wb_model_defines.v"
69 116 mohor
`include "tb_eth_defines.v"
70
`include "eth_defines.v"
71
`include "timescale.v"
72
 
73
module tb_ethernet();
74
 
75
 
76 169 mohor
reg           wb_clk;
77
reg           wb_rst;
78
wire          wb_int;
79 116 mohor
 
80 169 mohor
wire          mtx_clk;  // This goes to PHY
81
wire          mrx_clk;  // This goes to PHY
82 116 mohor
 
83
wire   [3:0]  MTxD;
84
wire          MTxEn;
85
wire          MTxErr;
86
 
87 169 mohor
wire   [3:0]  MRxD;     // This goes to PHY
88
wire          MRxDV;    // This goes to PHY
89
wire          MRxErr;   // This goes to PHY
90
wire          MColl;    // This goes to PHY
91
wire          MCrs;     // This goes to PHY
92 116 mohor
 
93
wire          Mdi_I;
94
wire          Mdo_O;
95
wire          Mdo_OE;
96 169 mohor
tri           Mdio_IO;
97 116 mohor
wire          Mdc_O;
98
 
99
 
100 169 mohor
parameter Tp = 1;
101 116 mohor
 
102 121 mohor
 
103 116 mohor
// Ethernet Slave Interface signals
104 169 mohor
wire [31:0] eth_sl_wb_adr;
105 116 mohor
wire [31:0] eth_sl_wb_adr_i, eth_sl_wb_dat_o, eth_sl_wb_dat_i;
106
wire  [3:0] eth_sl_wb_sel_i;
107
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;
108
 
109
// Ethernet Master Interface signals
110
wire [31:0] eth_ma_wb_adr_o, eth_ma_wb_dat_i, eth_ma_wb_dat_o;
111
wire  [3:0] eth_ma_wb_sel_o;
112
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;
113
 
114
 
115
 
116
 
117
// Connecting Ethernet top module
118 169 mohor
eth_top eth_top
119 116 mohor
(
120
  // WISHBONE common
121 169 mohor
  .wb_clk_i(wb_clk),              .wb_rst_i(wb_rst),
122 116 mohor
 
123
  // WISHBONE slave
124 169 mohor
  .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),
125
  .wb_cyc_i(eth_sl_wb_cyc_i),       .wb_stb_i(eth_sl_wb_stb_i),   .wb_ack_o(eth_sl_wb_ack_o),
126
  .wb_err_o(eth_sl_wb_err_o),       .wb_dat_i(eth_sl_wb_dat_i),   .wb_dat_o(eth_sl_wb_dat_o),
127 116 mohor
 
128
  // WISHBONE master
129
  .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),
130
  .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),
131
  .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),
132
 
133
  //TX
134
  .mtx_clk_pad_i(mtx_clk), .mtxd_pad_o(MTxD), .mtxen_pad_o(MTxEn), .mtxerr_pad_o(MTxErr),
135
 
136
  //RX
137
  .mrx_clk_pad_i(mrx_clk), .mrxd_pad_i(MRxD), .mrxdv_pad_i(MRxDV), .mrxerr_pad_i(MRxErr),
138
  .mcoll_pad_i(MColl),    .mcrs_pad_i(MCrs),
139
 
140
  // MIIM
141
  .mdc_pad_o(Mdc_O), .md_pad_i(Mdi_I), .md_pad_o(Mdo_O), .md_padoe_o(Mdo_OE),
142
 
143 169 mohor
  .int_o(wb_int)
144 116 mohor
);
145
 
146
 
147
 
148 169 mohor
// Connecting Ethernet PHY Module
149
assign Mdio_IO = Mdo_OE ? Mdo_O : 1'bz ;
150
assign Mdi_I   = Mdio_IO;
151
integer phy_log_file_desc;
152
 
153
eth_phy eth_phy
154 116 mohor
(
155 169 mohor
  // WISHBONE reset
156
  .m_rst_n_i(!wb_rst),
157 116 mohor
 
158 169 mohor
  // MAC TX
159
  .mtx_clk_o(mtx_clk),    .mtxd_i(MTxD),    .mtxen_i(MTxEn),    .mtxerr_i(MTxErr),
160
 
161
  // MAC RX
162
  .mrx_clk_o(mrx_clk),    .mrxd_o(MRxD),    .mrxdv_o(MRxDV),    .mrxerr_o(MRxErr),
163
  .mcoll_o(MColl),        .mcrs_o(MCrs),
164
 
165
  // MIIM
166
  .mdc_i(Mdc_O),          .md_io(Mdio_IO),
167
 
168
  // SYSTEM
169
  .phy_log(phy_log_file_desc)
170 116 mohor
);
171
 
172
 
173 169 mohor
 
174
// Connecting WB Master as Host Interface
175
integer host_log_file_desc;
176
 
177
WB_MASTER_BEHAVIORAL wb_master
178 116 mohor
(
179 169 mohor
    .CLK_I(wb_clk),
180
    .RST_I(wb_rst),
181
    .TAG_I({`WB_TAG_WIDTH{1'b0}}),
182
    .TAG_O(),
183
    .ACK_I(eth_sl_wb_ack_o),
184
    .ADR_O(eth_sl_wb_adr), // only eth_sl_wb_adr_i[11:2] used
185
    .CYC_O(eth_sl_wb_cyc_i),
186
    .DAT_I(eth_sl_wb_dat_o),
187
    .DAT_O(eth_sl_wb_dat_i),
188
    .ERR_I(eth_sl_wb_err_o),
189
    .RTY_I(1'b0),  // inactive (1'b0)
190
    .SEL_O(eth_sl_wb_sel_i),
191
    .STB_O(eth_sl_wb_stb_i),
192
    .WE_O (eth_sl_wb_we_i),
193
    .CAB_O()       // NOT USED for now!
194
);
195
 
196
assign eth_sl_wb_adr_i = {20'h0, eth_sl_wb_adr[11:2], 2'h0};
197
 
198
 
199
 
200
// Connecting WB Slave as Memory Interface Module
201
integer memory_log_file_desc;
202
 
203
WB_SLAVE_BEHAVIORAL wb_slave
204
(
205
    .CLK_I(wb_clk),
206
    .RST_I(wb_rst),
207
    .ACK_O(eth_ma_wb_ack_i),
208
    .ADR_I(eth_ma_wb_adr_o),
209
    .CYC_I(eth_ma_wb_cyc_o),
210
    .DAT_O(eth_ma_wb_dat_i),
211
    .DAT_I(eth_ma_wb_dat_o),
212
    .ERR_O(eth_ma_wb_err_i),
213
    .RTY_O(),      // NOT USED for now!
214
    .SEL_I(eth_ma_wb_sel_o),
215
    .STB_I(eth_ma_wb_stb_o),
216
    .WE_I (eth_ma_wb_we_o),
217
    .CAB_I(1'b0)   // inactive (1'b0)
218
);
219
 
220
 
221
 
222
// Connecting WISHBONE Bus Monitors to ethernet master and slave interfaces
223
integer wb_s_mon_log_file_desc ;
224
integer wb_m_mon_log_file_desc ;
225
 
226
WB_BUS_MON wb_eth_slave_bus_mon
227
(
228 116 mohor
  // WISHBONE common
229 169 mohor
  .CLK_I(wb_clk),
230
  .RST_I(wb_rst),
231 116 mohor
 
232 169 mohor
  // WISHBONE slave
233
  .ACK_I(eth_sl_wb_ack_o),
234
  .ADDR_O({20'h0, eth_sl_wb_adr_i[11:2], 2'b0}),
235
  .CYC_O(eth_sl_wb_cyc_i),
236
  .DAT_I(eth_sl_wb_dat_o),
237
  .DAT_O(eth_sl_wb_dat_i),
238
  .ERR_I(eth_sl_wb_err_o),
239
  .RTY_I(1'b0),
240
  .SEL_O(eth_sl_wb_sel_i),
241
  .STB_O(eth_sl_wb_stb_i),
242
  .WE_O (eth_sl_wb_we_i),
243
  .TAG_I({`WB_TAG_WIDTH{1'b0}}),
244
  .TAG_O(),
245
  .CAB_O(1'b0),
246
  .log_file_desc (wb_s_mon_log_file_desc)
247
);
248
 
249
WB_BUS_MON wb_eth_master_bus_mon
250
(
251
  // WISHBONE common
252
  .CLK_I(wb_clk),
253
  .RST_I(wb_rst),
254
 
255 116 mohor
  // WISHBONE master
256 169 mohor
  .ACK_I(eth_ma_wb_ack_i),
257
  .ADDR_O(eth_ma_wb_adr_o),
258
  .CYC_O(eth_ma_wb_cyc_o),
259
  .DAT_I(eth_ma_wb_dat_i),
260
  .DAT_O(eth_ma_wb_dat_o),
261
  .ERR_I(eth_ma_wb_err_i),
262
  .RTY_I(1'b0),
263
  .SEL_O(eth_ma_wb_sel_o),
264
  .STB_O(eth_ma_wb_stb_o),
265
  .WE_O (eth_ma_wb_we_o),
266
  .TAG_I({`WB_TAG_WIDTH{1'b0}}),
267
  .TAG_O(),
268
  .CAB_O(1'b0),
269
  .log_file_desc(wb_m_mon_log_file_desc)
270 116 mohor
);
271
 
272
 
273
 
274 169 mohor
reg         StartTB;
275
integer     tb_log_file;
276 116 mohor
 
277 169 mohor
initial
278
begin
279
  tb_log_file = $fopen("../log/eth_tb.log");
280
  if (tb_log_file < 2)
281
  begin
282
    $display("*E Could not open/create testbench log file in ../log/ directory!");
283
    $finish;
284
  end
285
  $fdisplay(tb_log_file, "========================== ETHERNET IP Core Testbench results ===========================");
286
  $fdisplay(tb_log_file, " ");
287 116 mohor
 
288 169 mohor
  phy_log_file_desc = $fopen("../log/eth_tb_phy.log");
289
  if (phy_log_file_desc < 2)
290
  begin
291
    $fdisplay(tb_log_file, "*E Could not open/create eth_tb_phy.log file in ../log/ directory!");
292
    $finish;
293
  end
294
  $fdisplay(phy_log_file_desc, "================ PHY Module  Testbench access log ================");
295
  $fdisplay(phy_log_file_desc, " ");
296
 
297
  memory_log_file_desc = $fopen("../log/eth_tb_memory.log");
298
  if (memory_log_file_desc < 2)
299
  begin
300
    $fdisplay(tb_log_file, "*E Could not open/create eth_tb_memory.log file in ../log/ directory!");
301
    $finish;
302
  end
303
  $fdisplay(memory_log_file_desc, "=============== MEMORY Module Testbench access log ===============");
304
  $fdisplay(memory_log_file_desc, " ");
305
 
306
  host_log_file_desc = $fopen("../log/eth_tb_host.log");
307
  if (host_log_file_desc < 2)
308
  begin
309
    $fdisplay(tb_log_file, "*E Could not open/create eth_tb_host.log file in ../log/ directory!");
310
    $finish;
311
  end
312
  $fdisplay(host_log_file_desc, "================ HOST Module Testbench access log ================");
313
  $fdisplay(host_log_file_desc, " ");
314
 
315
  wb_s_mon_log_file_desc = $fopen("../log/eth_tb_wb_s_mon.log");
316
  if (wb_s_mon_log_file_desc < 2)
317
  begin
318
    $fdisplay(tb_log_file, "*E Could not open/create eth_tb_wb_s_mon.log file in ../log/ directory!");
319
    $finish;
320
  end
321
  $fdisplay(wb_s_mon_log_file_desc, "============== WISHBONE Slave Bus Monitor error log ==============");
322
  $fdisplay(wb_s_mon_log_file_desc, " ");
323
  $fdisplay(wb_s_mon_log_file_desc, "   Only ERRONEOUS conditions are logged !");
324
  $fdisplay(wb_s_mon_log_file_desc, " ");
325
 
326
  wb_m_mon_log_file_desc = $fopen("../log/eth_tb_wb_m_mon.log");
327
  if (wb_m_mon_log_file_desc < 2)
328
  begin
329
    $fdisplay(tb_log_file, "*E Could not open/create eth_tb_wb_m_mon.log file in ../log/ directory!");
330
    $finish;
331
  end
332
  $fdisplay(wb_m_mon_log_file_desc, "============= WISHBONE Master Bus Monitor  error log =============");
333
  $fdisplay(wb_m_mon_log_file_desc, " ");
334
  $fdisplay(wb_m_mon_log_file_desc, "   Only ERRONEOUS conditions are logged !");
335
  $fdisplay(wb_m_mon_log_file_desc, " ");
336
 
337
  // Clear memories
338
  clear_memories;
339
 
340
  // Reset pulse
341
  wb_rst =  1'b1;
342
  #423 wb_rst =  1'b0;
343
  #423 StartTB  =  1'b1;
344
end
345
 
346
 
347
 
348
// Generating wb_clk clock
349 116 mohor
initial
350
begin
351 169 mohor
  wb_clk=0;
352
//  forever #2.5 wb_clk = ~wb_clk;  // 2*2.5 ns -> 200.0 MHz    
353
//  forever #5 wb_clk = ~wb_clk;  // 2*5 ns -> 100.0 MHz    
354
//  forever #10 wb_clk = ~wb_clk;  // 2*10 ns -> 50.0 MHz    
355
//  forever #12.5 wb_clk = ~wb_clk;  // 2*12.5 ns -> 40 MHz    
356
//  forever #15 wb_clk = ~wb_clk;  // 2*10 ns -> 33.3 MHz    
357
  forever #20 wb_clk = ~wb_clk;  // 2*20 ns -> 25 MHz    
358
//  forever #25 wb_clk = ~wb_clk;  // 2*25 ns -> 20.0 MHz
359
//  forever #31.25 wb_clk = ~wb_clk;  // 2*31.25 ns -> 16.0 MHz    
360
//  forever #50 wb_clk = ~wb_clk;  // 2*50 ns -> 10.0 MHz
361
//  forever #55 wb_clk = ~wb_clk;  // 2*55 ns ->  9.1 MHz    
362 116 mohor
end
363
 
364
 
365
 
366 169 mohor
integer      tests_successfull;
367
integer      tests_failed;
368
reg [799:0]  test_name; // used for tb_log_file
369 121 mohor
 
370 169 mohor
reg   [3:0]  wbm_init_waits; // initial wait cycles between CYC_O and STB_O of WB Master
371
reg   [3:0]  wbm_subseq_waits; // subsequent wait cycles between STB_Os of WB Master
372
reg   [2:0]  wbs_waits; // wait cycles befor WB Slave responds
373
reg   [7:0]  wbs_retries; // if RTY response, then this is the number of retries before ACK
374
 
375 116 mohor
initial
376
begin
377 169 mohor
  wait(StartTB);  // Start of testbench
378
 
379
  // Initial global values
380
  tests_successfull = 0;
381
  tests_failed = 0;
382
 
383
  wbm_init_waits = 4'h1;
384
  wbm_subseq_waits = 4'h3;
385
  wbs_waits = 4'h1;
386
  wbs_retries = 8'h2;
387
  wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
388
 
389
 
390
  //  Call tests
391
  //  ----------
392 178 mohor
    test_access_to_mac_reg(0, 3);          // 0 - 3
393 177 mohor
//    test_mii(0, 17);                        // 0 - 17
394
    test_mii(0, 1);                        // 0 - 17
395 169 mohor
  test_note("PHY generates ideal Carrier sense and Collision signals for following tests");
396
  eth_phy.carrier_sense_real_delay(0);
397
    test_mac_full_duplex_transmit(0, 3);   // 0 - (3)
398
 
399
  test_note("PHY generates 'real' Carrier sense and Collision signals for following tests");
400
  eth_phy.carrier_sense_real_delay(1);
401
 
402
 
403
  // Finish test's logs
404
  test_summary;
405
  $display("\n\n END of SIMULATION");
406
  $fclose(tb_log_file | phy_log_file_desc | memory_log_file_desc | host_log_file_desc);
407
  $fclose(wb_s_mon_log_file_desc | wb_m_mon_log_file_desc);
408
 
409
  $stop;
410 116 mohor
end
411 169 mohor
 
412 116 mohor
 
413 169 mohor
 
414
//////////////////////////////////////////////////////////////
415
// Test tasks
416
//////////////////////////////////////////////////////////////
417
 
418
task test_access_to_mac_reg;
419
  input  [31:0]  start_task;
420
  input  [31:0]  end_task;
421
  integer        bit_start_1;
422
  integer        bit_end_1;
423
  integer        bit_start_2;
424
  integer        bit_end_2;
425
  integer        num_of_reg;
426
  integer        i_addr;
427
  integer        i_data;
428
  integer        i_length;
429
  integer        tmp_data;
430
  reg    [31:0]  tx_bd_num;
431
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_data;
432
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_tmp_data;
433
  integer        i;
434
  integer        i1;
435
  integer        i2;
436
  integer        i3;
437
  integer        fail;
438 178 mohor
  integer        test_num;
439 169 mohor
  reg    [31:0]  addr;
440
  reg    [31:0]  data;
441
  reg    [31:0]  data_max;
442 116 mohor
begin
443 169 mohor
// ACCESS TO MAC REGISTERS TEST
444
test_heading("ACCESS TO MAC REGISTERS TEST");
445
$display(" ");
446
$display("ACCESS TO MAC REGISTERS TEST");
447
fail = 0;
448
 
449
 
450 178 mohor
//////////////////////////////////////////////////////////////////////
451
////                                                              ////
452
////  test_access_to_mac_reg:                                     ////
453
////                                                              ////
454
////  0: Walking 1 with single cycles across MAC regs.            ////
455
////  1: Walking 1 with single cycles across MAC buffer descript. ////
456
////  2: Test max reg. values and reg. values after writing       ////
457
////     inverse reset values and hard reset of the MAC           ////
458
////  3: Test buffer desc. RAM preserving values after hard reset ////
459
////     of the MAC and resetting the logic                       ////
460
////                                                              ////
461
//////////////////////////////////////////////////////////////////////
462
for (test_num=start_task; test_num <= end_task; test_num=test_num+1)
463 169 mohor
begin
464
 
465 178 mohor
  ////////////////////////////////////////////////////////////////////
466
  ////                                                            ////
467
  ////  Walking 1 with single cycles across MAC regs.             ////
468
  ////                                                            ////
469
  ////////////////////////////////////////////////////////////////////
470
  if (test_num == 0) // Walking 1 with single cycles across MAC regs.
471
    begin
472
      // TEST 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )
473
      test_name   = "TEST 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )";
474
      `TIME; $display("  TEST 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )");
475
 
476
      data = 0;
477
      for (i = 0; i <= 4; i = i + 1) // for initial wait cycles on WB bus
478
        begin
479
          wbm_init_waits = i;
480
          wbm_subseq_waits = {$random} % 5; // it is not important for single accesses
481
          for (i_addr = 0; i_addr <= 32'h4C; i_addr = i_addr + 4) // register address
482
            begin
483
              addr = `ETH_BASE + i_addr;
484
              // set ranges of R/W bits
485
              case (addr)
486
                `ETH_MODER:
487
                  begin
488
                    bit_start_1 = 0;
489
                    bit_end_1   = 16;
490
                    bit_start_2 = 32; // not used
491
                    bit_end_2   = 32; // not used
492
                  end
493
                `ETH_INT: // READONLY - tested within INT test
494
                  begin
495
                    bit_start_1 = 32; // not used
496
                    bit_end_1   = 32; // not used
497
                    bit_start_2 = 32; // not used
498
                    bit_end_2   = 32; // not used
499
                  end
500
                `ETH_INT_MASK:
501
                  begin
502
                    bit_start_1 = 0;
503
                    bit_end_1   = 6;
504
                    bit_start_2 = 32; // not used
505
                    bit_end_2   = 32; // not used
506
                  end
507
                `ETH_IPGT:
508
                  begin
509
                    bit_start_1 = 0;
510
                    bit_end_1   = 6;
511
                    bit_start_2 = 32; // not used
512
                    bit_end_2   = 32; // not used
513
                  end
514
                `ETH_IPGR1:
515
                  begin
516
                    bit_start_1 = 0;
517
                    bit_end_1   = 6;
518
                    bit_start_2 = 32; // not used
519
                    bit_end_2   = 32; // not used
520
                  end
521
                `ETH_IPGR2:
522
                  begin
523
                    bit_start_1 = 0;
524
                    bit_end_1   = 6;
525
                    bit_start_2 = 32; // not used
526
                    bit_end_2   = 32; // not used
527
                  end
528
                `ETH_PACKETLEN:
529
                  begin
530
                    bit_start_1 = 0;
531
                    bit_end_1   = 31;
532
                    bit_start_2 = 32; // not used
533
                    bit_end_2   = 32; // not used
534
                  end
535
                `ETH_COLLCONF:
536
                  begin
537
                    bit_start_1 = 0;
538
                    bit_end_1   = 5;
539
                    bit_start_2 = 16;
540
                    bit_end_2   = 19;
541
                  end
542
                `ETH_TX_BD_NUM:
543
                  begin
544
                    bit_start_1 = 0;
545
                    bit_end_1   = 7;
546
                    bit_start_2 = 32; // not used
547
                    bit_end_2   = 32; // not used
548
                  end
549
                `ETH_CTRLMODER:
550
                  begin
551
                    bit_start_1 = 0;
552
                    bit_end_1   = 2;
553
                    bit_start_2 = 32; // not used
554
                    bit_end_2   = 32; // not used
555
                  end
556
                `ETH_MIIMODER:
557
                  begin
558
                    bit_start_1 = 0;
559
                    bit_end_1   = 9;
560
                    bit_start_2 = 32; // not used
561
                    bit_end_2   = 32; // not used
562
                  end
563
                `ETH_MIICOMMAND: // "WRITEONLY" - tested within MIIM test - 3 LSBits are not written here!!!
564
                  begin
565
                    bit_start_1 = 32; // not used
566
                    bit_end_1   = 32; // not used
567
                    bit_start_2 = 32; // not used
568
                    bit_end_2   = 32; // not used
569
                  end
570
                `ETH_MIIADDRESS:
571
                  begin
572
                    bit_start_1 = 0;
573
                    bit_end_1   = 4;
574
                    bit_start_2 = 8;
575
                    bit_end_2   = 12;
576
                  end
577
                `ETH_MIITX_DATA:
578
                  begin
579
                    bit_start_1 = 0;
580
                    bit_end_1   = 15;
581
                    bit_start_2 = 32; // not used
582
                    bit_end_2   = 32; // not used
583
                  end
584
                `ETH_MIIRX_DATA: // READONLY - tested within MIIM test
585
                  begin
586
                    bit_start_1 = 32; // not used
587
                    bit_end_1   = 32; // not used
588
                    bit_start_2 = 32; // not used
589
                    bit_end_2   = 32; // not used
590
                  end
591
                `ETH_MIISTATUS: // READONLY - tested within MIIM test
592
                  begin
593
                    bit_start_1 = 32; // not used
594
                    bit_end_1   = 32; // not used
595
                    bit_start_2 = 32; // not used
596
                    bit_end_2   = 32; // not used
597
                  end
598
                `ETH_MAC_ADDR0:
599
                  begin
600
                    bit_start_1 = 0;
601
                    bit_end_1   = 31;
602
                    bit_start_2 = 32; // not used
603
                    bit_end_2   = 32; // not used
604
                    end
605
                `ETH_MAC_ADDR1:
606
                  begin
607
                    bit_start_1 = 0;
608
                    bit_end_1   = 15;
609
                    bit_start_2 = 32; // not used
610
                    bit_end_2   = 32; // not used
611
                  end
612
                `ETH_HASH_ADDR0:
613
                  begin
614
                    bit_start_1 = 0;
615
                    bit_end_1   = 31;
616
                    bit_start_2 = 32; // not used
617
                    bit_end_2   = 32; // not used
618
                  end
619
                default: // `ETH_HASH_ADDR1:
620
                  begin
621
                    bit_start_1 = 0;
622
                    bit_end_1   = 31;
623
                    bit_start_2 = 32; // not used
624
                    bit_end_2   = 32; // not used
625
                  end
626
              endcase
627
 
628
              for (i_data = 0; i_data <= 31; i_data = i_data + 1) // the position of walking one
629
                begin
630
                  data = 1'b1 << i_data;
631
                  if ( (addr == `ETH_MIICOMMAND) && (i_data <= 2) ) // DO NOT WRITE to 3 LSBits of MIICOMMAND !!!
632
                    ;
633
                  else
634
                    begin
635
                      wbm_write(addr, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
636
                      wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
637
                      if ( ((i_data >= bit_start_1) && (i_data <= bit_end_1)) ||
638
                           ((i_data >= bit_start_2) && (i_data <= bit_end_2)) ) // data should be equal to tmp_data
639
                        begin
640
                          if (tmp_data !== data)
641
                          begin
642
                            fail = fail + 1;
643
                            test_fail("RW bit of the MAC register was not written or not read");
644
                            `TIME;
645
                            $display("wbm_init_waits %d, addr %h, data %h, tmp_data %h",
646
                                      wbm_init_waits, addr, data, tmp_data);
647
                          end
648
                        end
649
                      else // data should not be equal to tmp_data
650
                        begin
651
                          if (tmp_data === data)
652
                            begin
653
                              fail = fail + 1;
654
                              test_fail("NON RW bit of the MAC register was written, but it shouldn't be");
655
                              `TIME;
656
                              $display("wbm_init_waits %d, addr %h, data %h, tmp_data %h",
657
                                        wbm_init_waits, addr, data, tmp_data);
658
                            end
659
                        end
660
                    end
661
                end
662
            end
663
        end
664
 
665
      if(fail == 0)
666
        test_ok;
667
      else
668
        fail = 0;    // Errors were reported previously
669
    end
670
 
671
 
672
 
673
  ////////////////////////////////////////////////////////////////////
674
  ////                                                            ////
675
  ////  Walking 1 with single cycles across MAC buffer descript.  ////
676
  ////                                                            ////
677
  ////////////////////////////////////////////////////////////////////
678
  if (test_num == 1) // Start Walking 1 with single cycles across MAC buffer descript.
679 169 mohor
  begin
680 178 mohor
    // TEST 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC BUFFER DESC. ( VARIOUS BUS DELAYS )
681
    test_name   = "TEST 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC BUFFER DESC. ( VARIOUS BUS DELAYS )";
682
    `TIME; $display("  TEST 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC BUFFER DESC. ( VARIOUS BUS DELAYS )");
683
 
684
    data = 0;
685
    // set TX and RX buffer descriptors
686
    tx_bd_num = 32'h40;
687
    wbm_write(`ETH_TX_BD_NUM, tx_bd_num, 4'hF, 1, 0, 0);
688
    for (i = 0; i <= 4; i = i + 1) // for initial wait cycles on WB bus
689
    begin
690 169 mohor
      wbm_init_waits = i;
691
      wbm_subseq_waits = {$random} % 5; // it is not important for single accesses
692 178 mohor
      for (i_addr = 32'h400; i_addr <= 32'h7FC; i_addr = i_addr + 4) // buffer descriptor address
693 169 mohor
      begin
694
        addr = `ETH_BASE + i_addr;
695 178 mohor
        if (i_addr < (32'h400 + (tx_bd_num << 3))) // TX buffer descriptors
696
        begin
697
          // set ranges of R/W bits
698
          case (addr[3])
699
            1'b0: // buffer control bits
700
            begin
701
              bit_start_1 = 0;
702
              bit_end_1   = 31; // 8;
703
              bit_start_2 = 11;
704
              bit_end_2   = 31;
705
            end
706
            default: // 1'b1: // buffer pointer
707
            begin
708
              bit_start_1 = 0;
709
              bit_end_1   = 31;
710
              bit_start_2 = 32; // not used
711
              bit_end_2   = 32; // not used
712
            end
713
          endcase
714
        end
715
        else // RX buffer descriptors
716
        begin
717
          // set ranges of R/W bits
718
          case (addr[3])
719
            1'b0: // buffer control bits
720
            begin
721
              bit_start_1 = 0;
722
              bit_end_1   = 31; // 7;
723
              bit_start_2 = 13;
724
              bit_end_2   = 31;
725
            end
726
            default: // 1'b1: // buffer pointer
727
            begin
728
              bit_start_1 = 0;
729
              bit_end_1   = 31;
730
              bit_start_2 = 32; // not used
731
              bit_end_2   = 32; // not used
732
            end
733
          endcase
734
        end
735
 
736 169 mohor
        for (i_data = 0; i_data <= 31; i_data = i_data + 1) // the position of walking one
737
        begin
738
          data = 1'b1 << i_data;
739 178 mohor
          if ( (addr[3] == 0) && (i_data == 15) ) // DO NOT WRITE to this bit !!!
740
            ;
741 169 mohor
          else
742
          begin
743
            wbm_write(addr, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
744
            wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
745
            if ( ((i_data >= bit_start_1) && (i_data <= bit_end_1)) ||
746
                 ((i_data >= bit_start_2) && (i_data <= bit_end_2)) ) // data should be equal to tmp_data
747
            begin
748
              if (tmp_data !== data)
749
              begin
750
                fail = fail + 1;
751 178 mohor
                test_fail("RW bit of the MAC buffer descriptors was not written or not read");
752 169 mohor
                `TIME;
753
                $display("wbm_init_waits %d, addr %h, data %h, tmp_data %h",
754
                          wbm_init_waits, addr, data, tmp_data);
755
              end
756
            end
757
            else // data should not be equal to tmp_data
758
            begin
759
              if (tmp_data === data)
760
              begin
761
                fail = fail + 1;
762 178 mohor
                test_fail("NON RW bit of the MAC buffer descriptors was written, but it shouldn't be");
763 169 mohor
                `TIME;
764
                $display("wbm_init_waits %d, addr %h, data %h, tmp_data %h",
765
                          wbm_init_waits, addr, data, tmp_data);
766
              end
767
            end
768
          end
769
        end
770
      end
771 178 mohor
      // INTERMEDIATE DISPLAYS
772
      case (i)
773
        0:       $display("    buffer descriptors tested with 0 bus delay");
774
        1:       $display("    buffer descriptors tested with 1 bus delay cycle");
775
        2:       $display("    buffer descriptors tested with 2 bus delay cycles");
776
        3:       $display("    buffer descriptors tested with 3 bus delay cycles");
777
        default: $display("    buffer descriptors tested with 4 bus delay cycles");
778
      endcase
779
    end
780
    if(fail == 0)
781
      test_ok;
782
    else
783
      fail = 0;
784 169 mohor
  end
785 178 mohor
 
786
 
787
  ////////////////////////////////////////////////////////////////////
788
  ////                                                            ////
789
  ////  Test max reg. values and reg. values after writing        ////
790
  ////  inverse reset values and hard reset of the MAC            ////
791
  ////                                                            ////
792
  ////////////////////////////////////////////////////////////////////
793
  if (test_num == 2) // Start this task
794 169 mohor
  begin
795 178 mohor
    // TEST MAX REG. VALUES AND REG. VALUES AFTER WRITING INVERSE RESET VALUES AND HARD RESET OF THE MAC
796
    test_name   =
797
      "TEST MAX REG. VALUES AND REG. VALUES AFTER WRITING INVERSE RESET VALUES AND HARD RESET OF THE MAC";
798
    `TIME; $display(
799
      "  TEST MAX REG. VALUES AND REG. VALUES AFTER WRITING INVERSE RESET VALUES AND HARD RESET OF THE MAC");
800
 
801
    // reset MAC registers
802
    hard_reset;
803
    for (i = 0; i <= 4; i = i + 1) // 0, 2 - WRITE; 1, 3, 4 - READ
804 169 mohor
    begin
805 178 mohor
      for (i_addr = 0; i_addr <= 32'h4C; i_addr = i_addr + 4) // register address
806 169 mohor
      begin
807 178 mohor
        addr = `ETH_BASE + i_addr;
808
        // set ranges of R/W bits
809
        case (addr)
810
          `ETH_MODER:
811 169 mohor
          begin
812 178 mohor
            data = 32'h0000_A800;
813
            data_max = 32'h0001_FFFF;
814 169 mohor
          end
815 178 mohor
          `ETH_INT: // READONLY - tested within INT test
816 169 mohor
          begin
817 178 mohor
            data = 32'h0000_0000;
818
            data_max = 32'h0000_0000;
819 169 mohor
          end
820
          `ETH_INT_MASK:
821 178 mohor
          begin
822
            data = 32'h0000_0000;
823
            data_max = 32'h0000_007F;
824
          end
825 169 mohor
          `ETH_IPGT:
826 178 mohor
          begin
827
            data = 32'h0000_0012;
828
            data_max = 32'h0000_007F;
829
          end
830 169 mohor
          `ETH_IPGR1:
831 178 mohor
          begin
832
            data = 32'h0000_000C;
833
            data_max = 32'h0000_007F;
834
          end
835 169 mohor
          `ETH_IPGR2:
836 178 mohor
          begin
837
            data = 32'h0000_0012;
838
            data_max = 32'h0000_007F;
839
          end
840 169 mohor
          `ETH_PACKETLEN:
841 178 mohor
          begin
842
            data = 32'h0040_0600;
843
            data_max = 32'hFFFF_FFFF;
844
          end
845 169 mohor
          `ETH_COLLCONF:
846 178 mohor
          begin
847
            data = 32'h000F_003F;
848
            data_max = 32'h000F_003F;
849
          end
850 169 mohor
          `ETH_TX_BD_NUM:
851 178 mohor
          begin
852
            data = 32'h0000_0040;
853
            data_max = 32'h0000_0080;
854
          end
855 169 mohor
          `ETH_CTRLMODER:
856 178 mohor
          begin
857
            data = 32'h0000_0000;
858
            data_max = 32'h0000_0007;
859
          end
860 169 mohor
          `ETH_MIIMODER:
861 178 mohor
          begin
862
            data = 32'h0000_0064;
863
            data_max = 32'h0000_03FF;
864
          end
865 169 mohor
          `ETH_MIICOMMAND: // "WRITEONLY" - tested within MIIM test - 3 LSBits are not written here!!!
866 178 mohor
          begin
867
            data = 32'h0000_0000;
868
            data_max = 32'h0000_0007;
869
          end
870 169 mohor
          `ETH_MIIADDRESS:
871 178 mohor
          begin
872
            data = 32'h0000_0000;
873
            data_max = 32'h0000_1F1F;
874
          end
875 169 mohor
          `ETH_MIITX_DATA:
876 178 mohor
          begin
877
            data = 32'h0000_0000;
878
            data_max = 32'h0000_FFFF;
879
          end
880 169 mohor
          `ETH_MIIRX_DATA: // READONLY - tested within MIIM test
881
          begin
882 178 mohor
            data = 32'h0000_0000;
883
            data_max = 32'h0000_0000;
884 169 mohor
          end
885 178 mohor
          `ETH_MIISTATUS: // READONLY - tested within MIIM test
886 169 mohor
          begin
887 178 mohor
            data = 32'h0000_0000;
888
            data_max = 32'h0000_0000;
889 169 mohor
          end
890 178 mohor
          `ETH_MAC_ADDR0:
891 169 mohor
          begin
892 178 mohor
            data = 32'h0000_0000;
893
            data_max = 32'hFFFF_FFFF;
894 169 mohor
          end
895 178 mohor
          `ETH_MAC_ADDR1:
896 169 mohor
          begin
897 178 mohor
            data = 32'h0000_0000;
898
            data_max = 32'h0000_FFFF;
899 169 mohor
          end
900 178 mohor
          `ETH_HASH_ADDR0:
901 169 mohor
          begin
902 178 mohor
            data = 32'h0000_0000;
903
            data_max = 32'hFFFF_FFFF;
904 169 mohor
          end
905 178 mohor
          default: // `ETH_HASH_ADDR1:
906 169 mohor
          begin
907 178 mohor
            data = 32'h0000_0000;
908
            data_max = 32'hFFFF_FFFF;
909 169 mohor
          end
910
        endcase
911 178 mohor
 
912
        wbm_init_waits = {$random} % 3;
913
        wbm_subseq_waits = {$random} % 5; // it is not important for single accesses
914
        if (i == 0)
915
          wbm_write(addr, ~data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
916
        else if (i == 2)
917
          wbm_write(addr, 32'hFFFFFFFF, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
918
        else if ((i == 1) || (i == 4))
919 169 mohor
        begin
920 178 mohor
          wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
921
          if (tmp_data !== data)
922
          begin
923
            fail = fail + 1;
924
            test_fail("RESET value of the MAC register is not correct");
925
            `TIME;
926
            $display("  addr %h, data %h, tmp_data %h", addr, data, tmp_data);
927
          end
928 169 mohor
        end
929 178 mohor
        else // check maximum values
930 169 mohor
        begin
931
          wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
932 178 mohor
          if (addr == `ETH_TX_BD_NUM) // previous data should remain in this register
933 169 mohor
          begin
934
            if (tmp_data !== data)
935
            begin
936
              fail = fail + 1;
937 178 mohor
              test_fail("Previous value of the TX_BD_NUM register did not remain");
938 169 mohor
              `TIME;
939 178 mohor
              $display("  addr %h, data_max %h, tmp_data %h", addr, data_max, tmp_data);
940 169 mohor
            end
941 178 mohor
            // try maximum (80)
942
            wbm_write(addr, data_max, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
943
            wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
944
            if (tmp_data !== data_max)
945
            begin
946
              fail = fail + 1;
947
              test_fail("MAX value of the TX_BD_NUM register is not correct");
948
              `TIME;
949
              $display("  addr %h, data_max %h, tmp_data %h", addr, data_max, tmp_data);
950
            end
951
            // try one less than maximum (80)
952
            wbm_write(addr, (data_max - 1), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
953
            wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
954
            if (tmp_data !== (data_max - 1))
955
            begin
956
              fail = fail + 1;
957
              test_fail("ONE less than MAX value of the TX_BD_NUM register is not correct");
958
              `TIME;
959
              $display("  addr %h, data_max %h, tmp_data %h", addr, data_max, tmp_data);
960
            end
961
            // try one more than maximum (80)
962
            wbm_write(addr, (data_max + 1), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
963
            wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
964
            if (tmp_data !== (data_max - 1)) // previous data should remain in this register
965
            begin
966
              fail = fail + 1;
967
              test_fail("Previous value of the TX_BD_NUM register did not remain");
968
              `TIME;
969
              $display("  addr %h, data_max %h, tmp_data %h", addr, data_max, tmp_data);
970
            end
971 169 mohor
          end
972 178 mohor
          else
973 169 mohor
          begin
974 178 mohor
            if (tmp_data !== data_max)
975 169 mohor
            begin
976
              fail = fail + 1;
977 178 mohor
              test_fail("MAX value of the MAC register is not correct");
978 169 mohor
              `TIME;
979 178 mohor
              $display("  addr %h, data_max %h, tmp_data %h", addr, data_max, tmp_data);
980 169 mohor
            end
981
          end
982
        end
983
      end
984 178 mohor
      // reset MAC registers
985
      if ((i == 0) || (i == 3))
986
        hard_reset;
987 169 mohor
    end
988 178 mohor
    if(fail == 0)
989
      test_ok;
990
    else
991
      fail = 0;
992 169 mohor
  end
993 116 mohor
 
994 156 mohor
 
995 178 mohor
  if (test_num == 3) // Start this task
996 169 mohor
  begin
997 178 mohor
    // TEST BUFFER DESC. RAM PRESERVING VALUES AFTER HARD RESET OF THE MAC AND RESETING THE LOGIC
998
    test_name   = "TEST BUFFER DESC. RAM PRESERVING VALUES AFTER HARD RESET OF THE MAC AND RESETING THE LOGIC";
999
    `TIME;
1000
    $display("  TEST BUFFER DESC. RAM PRESERVING VALUES AFTER HARD RESET OF THE MAC AND RESETING THE LOGIC");
1001
 
1002
    // reset MAC registers
1003
    hard_reset;
1004
    // reset LOGIC with soft reset
1005
    reset_mac;
1006
    reset_mii;
1007
    for (i = 0; i <= 3; i = i + 1) // 0, 2 - WRITE; 1, 3 - READ
1008 169 mohor
    begin
1009 178 mohor
      for (i_addr = 32'h400; i_addr <= 32'h7FC; i_addr = i_addr + 4) // buffer descriptor address
1010 169 mohor
      begin
1011 178 mohor
        addr = `ETH_BASE + i_addr;
1012
 
1013
        wbm_init_waits = {$random} % 3;
1014
        wbm_subseq_waits = {$random} % 5; // it is not important for single accesses
1015
        if (i == 0)
1016 169 mohor
        begin
1017 178 mohor
          data = 32'hFFFFFFFF;
1018
          wbm_write(addr, 32'hFFFFFFFF, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1019 169 mohor
        end
1020 178 mohor
        else if (i == 2)
1021 169 mohor
        begin
1022 178 mohor
          data = 32'h00000000;
1023
          wbm_write(addr, 32'h00000000, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1024 169 mohor
        end
1025
        else
1026
        begin
1027 178 mohor
          wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1028
          if (tmp_data !== data)
1029 169 mohor
          begin
1030
            fail = fail + 1;
1031 178 mohor
            test_fail("PRESERVED value of the MAC buffer descriptors is not correct");
1032 169 mohor
            `TIME;
1033 178 mohor
            $display("  addr %h, data %h, tmp_data %h", addr, data, tmp_data);
1034 169 mohor
          end
1035
        end
1036
      end
1037 178 mohor
      if ((i == 0) || (i == 2))
1038
      begin
1039
        // reset MAC registers
1040
        hard_reset;
1041
        // reset LOGIC with soft reset
1042
        reset_mac;
1043
        reset_mii;
1044
      end
1045 169 mohor
    end
1046 178 mohor
    if(fail == 0)
1047
      test_ok;
1048
    else
1049
    fail = 0;
1050 169 mohor
  end
1051 116 mohor
 
1052
 
1053 178 mohor
  if (test_num == 4) // Start this task
1054 169 mohor
  begin
1055 178 mohor
        /*  // TEST 'WALKING ONE' WITH BURST CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )
1056
          test_name   = "TEST 'WALKING ONE' WITH BURST CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )";
1057
          `TIME; $display("  TEST 'WALKING ONE' WITH BURST CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )");
1058
 
1059
          data = 0;
1060
          burst_data = 0;
1061
          burst_tmp_data = 0;
1062
          i_length = 10; // two bursts for length 20
1063
          for (i = 0; i <= 4; i = i + 1) // for initial wait cycles on WB bus
1064
          begin
1065
            for (i1 = 0; i1 <= 4; i1 = i1 + 1) // for initial wait cycles on WB bus
1066
            begin
1067
              wbm_init_waits = i;
1068
              wbm_subseq_waits = i1;
1069
              #1;
1070
              for (i_data = 0; i_data <= 31; i_data = i_data + 1) // the position of walking one
1071
              begin
1072
                data = 1'b1 << i_data;
1073
                #1;
1074
                for (i2 = 32'h4C; i2 >= 0; i2 = i2 - 4)
1075
                begin
1076
                  burst_data = burst_data << 32;
1077
                  // DO NOT WRITE to 3 LSBits of MIICOMMAND !!!
1078
                  if ( ((`ETH_BASE + i2) == `ETH_MIICOMMAND) && (i_data <= 2) )
1079
                  begin
1080
                    #1 burst_data[31:0] = 0;
1081
                  end
1082
                  else
1083
                  begin
1084
                    #1 burst_data[31:0] = data;
1085
                  end
1086
                end
1087
                #1;
1088
                // 2 burst writes
1089
                addr = `ETH_BASE; // address of a first burst
1090
                wbm_write(addr, burst_data[(32 * 10 - 1):0], 4'hF, i_length, wbm_init_waits, wbm_subseq_waits);
1091
                burst_tmp_data = burst_data >> (32 * i_length);
1092
                addr = addr + 32'h28; // address of a second burst
1093
                wbm_write(addr, burst_tmp_data[(32 * 10 - 1):0], 4'hF, i_length, wbm_init_waits, wbm_subseq_waits);
1094
                #1;
1095
                // 2 burst reads
1096
                addr = `ETH_BASE; // address of a first burst
1097
                wbm_read(addr, burst_tmp_data[(32 * 10 - 1):0], 4'hF, i_length,
1098
                         wbm_init_waits, wbm_subseq_waits); // first burst
1099
                burst_tmp_data = burst_tmp_data << (32 * i_length);
1100
                addr = addr + 32'h28; // address of a second burst
1101
                wbm_read(addr, burst_tmp_data[(32 * 10 - 1):0], 4'hF, i_length,
1102
                         wbm_init_waits, wbm_subseq_waits); // second burst
1103
                #1;
1104
                for (i2 = 0; i2 <= 32'h4C; i2 = i2 + 4)
1105
                begin
1106
                  // set ranges of R/W bits
1107
                  case (`ETH_BASE + i2)
1108
                  `ETH_MODER:
1109
                    begin
1110
                      bit_start_1 = 0;
1111
                      bit_end_1   = 16;
1112
                      bit_start_2 = 32; // not used
1113
                      bit_end_2   = 32; // not used
1114
                    end
1115
                  `ETH_INT: // READONLY - tested within INT test
1116
                    begin
1117
                      bit_start_1 = 32; // not used
1118
                      bit_end_1   = 32; // not used
1119
                      bit_start_2 = 32; // not used
1120
                      bit_end_2   = 32; // not used
1121
                    end
1122
                  `ETH_INT_MASK:
1123
                    begin
1124
                      bit_start_1 = 0;
1125
                      bit_end_1   = 6;
1126
                      bit_start_2 = 32; // not used
1127
                      bit_end_2   = 32; // not used
1128
                    end
1129
                  `ETH_IPGT:
1130
                    begin
1131
                      bit_start_1 = 0;
1132
                      bit_end_1   = 6;
1133
                      bit_start_2 = 32; // not used
1134
                      bit_end_2   = 32; // not used
1135
                    end
1136
                  `ETH_IPGR1:
1137
                    begin
1138
                      bit_start_1 = 0;
1139
                      bit_end_1   = 6;
1140
                      bit_start_2 = 32; // not used
1141
                      bit_end_2   = 32; // not used
1142
                    end
1143
                  `ETH_IPGR2:
1144
                    begin
1145
                      bit_start_1 = 0;
1146
                      bit_end_1   = 6;
1147
                      bit_start_2 = 32; // not used
1148
                      bit_end_2   = 32; // not used
1149
                    end
1150
                  `ETH_PACKETLEN:
1151
                    begin
1152
                      bit_start_1 = 0;
1153
                      bit_end_1   = 31;
1154
                      bit_start_2 = 32; // not used
1155
                      bit_end_2   = 32; // not used
1156
                    end
1157
                  `ETH_COLLCONF:
1158
                    begin
1159
                      bit_start_1 = 0;
1160
                      bit_end_1   = 5;
1161
                      bit_start_2 = 16;
1162
                      bit_end_2   = 19;
1163
                    end
1164
                  `ETH_TX_BD_NUM:
1165
                    begin
1166
                      bit_start_1 = 0;
1167
                      bit_end_1   = 7;
1168
                      bit_start_2 = 32; // not used
1169
                      bit_end_2   = 32; // not used
1170
                    end
1171
                  `ETH_CTRLMODER:
1172
                    begin
1173
                      bit_start_1 = 0;
1174
                      bit_end_1   = 2;
1175
                      bit_start_2 = 32; // not used
1176
                      bit_end_2   = 32; // not used
1177
                    end
1178
                  `ETH_MIIMODER:
1179
                    begin
1180
                      bit_start_1 = 0;
1181
                      bit_end_1   = 9;
1182
                      bit_start_2 = 32; // not used
1183
                      bit_end_2   = 32; // not used
1184
                    end
1185
                  `ETH_MIICOMMAND: // "WRITEONLY" - tested within MIIM test - 3 LSBits are not written here!!!
1186
                    begin
1187
                      bit_start_1 = 32; // not used
1188
                      bit_end_1   = 32; // not used
1189
                      bit_start_2 = 32; // not used
1190
                      bit_end_2   = 32; // not used
1191
                    end
1192
                  `ETH_MIIADDRESS:
1193
                    begin
1194
                      bit_start_1 = 0;
1195
                      bit_end_1   = 4;
1196
                      bit_start_2 = 8;
1197
                      bit_end_2   = 12;
1198
                    end
1199
                  `ETH_MIITX_DATA:
1200
                    begin
1201
                      bit_start_1 = 0;
1202
                      bit_end_1   = 15;
1203
                      bit_start_2 = 32; // not used
1204
                      bit_end_2   = 32; // not used
1205
                    end
1206
                  `ETH_MIIRX_DATA: // READONLY - tested within MIIM test
1207
                    begin
1208
                      bit_start_1 = 32; // not used
1209
                      bit_end_1   = 32; // not used
1210
                      bit_start_2 = 32; // not used
1211
                      bit_end_2   = 32; // not used
1212
                    end
1213
                  `ETH_MIISTATUS: // READONLY - tested within MIIM test
1214
                    begin
1215
                      bit_start_1 = 32; // not used
1216
                      bit_end_1   = 32; // not used
1217
                      bit_start_2 = 32; // not used
1218
                      bit_end_2   = 32; // not used
1219
                    end
1220
                  `ETH_MAC_ADDR0:
1221
                    begin
1222
                      bit_start_1 = 0;
1223
                      bit_end_1   = 31;
1224
                      bit_start_2 = 32; // not used
1225
                      bit_end_2   = 32; // not used
1226
                    end
1227
                  `ETH_MAC_ADDR1:
1228
                    begin
1229
                      bit_start_1 = 0;
1230
                      bit_end_1   = 15;
1231
                      bit_start_2 = 32; // not used
1232
                      bit_end_2   = 32; // not used
1233
                    end
1234
                  `ETH_HASH_ADDR0:
1235
                    begin
1236
                      bit_start_1 = 0;
1237
                      bit_end_1   = 31;
1238
                      bit_start_2 = 32; // not used
1239
                      bit_end_2   = 32; // not used
1240
                    end
1241
                  default: // `ETH_HASH_ADDR1:
1242
                    begin
1243
                      bit_start_1 = 0;
1244
                      bit_end_1   = 31;
1245
                      bit_start_2 = 32; // not used
1246
                      bit_end_2   = 32; // not used
1247
                    end
1248
                  endcase
1249
                  #1;
1250
                  // 3 LSBits of MIICOMMAND are NOT written !!!
1251
                  if ( ((`ETH_BASE + i2) == `ETH_MIICOMMAND) && (i_data <= 2) )
1252
                  begin
1253
                    if (burst_tmp_data[31:0] !== burst_data[31:0])
1254
                    begin
1255
                      fail = fail + 1;
1256
                      test_fail("NON WR bit of the MAC MIICOMMAND register was wrong written or read");
1257
                      `TIME;
1258
                      $display("wbm_init_waits %d, wbm_subseq_waits %d, addr %h, data %h, tmp_data %h",
1259
                                wbm_init_waits, wbm_subseq_waits, i2, burst_data[31:0], burst_tmp_data[31:0]);
1260
                    end
1261
                  end
1262
                  else
1263
                  begin
1264
                    if ( ((i_data >= bit_start_1) && (i_data <= bit_end_1)) ||
1265
                         ((i_data >= bit_start_2) && (i_data <= bit_end_2)) ) // data should be equal to tmp_data
1266
                    begin
1267
                      if (burst_tmp_data[31:0] !== burst_data[31:0])
1268
                      begin
1269
                        fail = fail + 1;
1270
                        test_fail("RW bit of the MAC register was not written or not read");
1271
                        `TIME;
1272
                        $display("wbm_init_waits %d, wbm_subseq_waits %d, addr %h, data %h, tmp_data %h",
1273
                                  wbm_init_waits, wbm_subseq_waits, i2, burst_data[31:0], burst_tmp_data[31:0]);
1274
                      end
1275
                    end
1276
                    else // data should not be equal to tmp_data
1277
                    begin
1278
                      if (burst_tmp_data[31:0] === burst_data[31:0])
1279
                      begin
1280
                        fail = fail + 1;
1281
                        test_fail("NON RW bit of the MAC register was written, but it shouldn't be");
1282
                        `TIME;
1283
                        $display("wbm_init_waits %d, wbm_subseq_waits %d, addr %h, data %h, tmp_data %h",
1284
                                  wbm_init_waits, wbm_subseq_waits, i2, burst_data[31:0], burst_tmp_data[31:0]);
1285
                      end
1286
                    end
1287
                  end
1288
                  burst_tmp_data = burst_tmp_data >> 32;
1289
                  burst_data = burst_data >> 32;
1290
                end
1291
              end
1292
            end
1293
          end
1294
          if(fail == 0)
1295
            test_ok;
1296
          else
1297
            fail = 0;*/
1298
  end
1299 116 mohor
 
1300 169 mohor
end
1301 156 mohor
 
1302 169 mohor
end
1303
endtask // test_access_to_mac_reg
1304 156 mohor
 
1305
 
1306 169 mohor
task test_mii;
1307
  input  [31:0]  start_task;
1308
  input  [31:0]  end_task;
1309
  integer        i;
1310
  integer        i1;
1311
  integer        i2;
1312
  integer        i3;
1313
  integer        cnt;
1314
  integer        fail;
1315
  reg     [8:0]  clk_div; // only 8 bits are valid!
1316
  reg     [4:0]  phy_addr;
1317
  reg     [4:0]  reg_addr;
1318
  reg     [15:0] phy_data;
1319
  reg     [15:0] tmp_data;
1320
begin
1321
// MIIM MODULE TEST
1322
test_heading("MIIM MODULE TEST");
1323
$display(" ");
1324
$display("MIIM MODULE TEST");
1325
fail = 0;
1326 156 mohor
 
1327 169 mohor
// reset MIIM LOGIC with soft reset
1328
reset_mii;
1329 116 mohor
 
1330
 
1331 169 mohor
if ((start_task <= 0) && (end_task >= 0))
1332
begin
1333
  // TEST CLOCK DIVIDER OF MII MANAGEMENT MODULE WITH ALL POSSIBLE FREQUENCES
1334
  test_name   = "TEST CLOCK DIVIDER OF MII MANAGEMENT MODULE WITH ALL POSSIBLE FREQUENCES";
1335
  `TIME; $display("  TEST CLOCK DIVIDER OF MII MANAGEMENT MODULE WITH ALL POSSIBLE FREQUENCES");
1336 116 mohor
 
1337 169 mohor
  wait(Mdc_O); // wait for MII clock to be 1
1338
  for(clk_div = 0; clk_div <= 255; clk_div = clk_div + 1)
1339
  begin
1340
    i1 = 0;
1341
    i2 = 0;
1342
    #Tp mii_set_clk_div(clk_div[7:0]);
1343
    @(posedge Mdc_O);
1344
    #Tp;
1345
    fork
1346
      begin
1347
        @(posedge Mdc_O);
1348
        #Tp;
1349
        disable count_i1;
1350
        disable count_i2;
1351
      end
1352
      begin: count_i1
1353
        forever
1354
        begin
1355
          @(posedge wb_clk);
1356
          i1 = i1 + 1;
1357
          #Tp;
1358
        end
1359
      end
1360
      begin: count_i2
1361
        forever
1362
        begin
1363
          @(negedge wb_clk);
1364
          i2 = i2 + 1;
1365
          #Tp;
1366
        end
1367
      end
1368
    join
1369
    if((clk_div[7:0] == 0) || (clk_div[7:0] == 1) || (clk_div[7:0] == 2) || (clk_div[7:0] == 3))
1370
    begin
1371
      if((i1 == i2) && (i1 == 2))
1372
      begin
1373
      end
1374
      else
1375
      begin
1376
        fail = fail + 1;
1377
        test_fail("Clock divider of MII module did'nt divide frequency corectly (it should divid with 2)");
1378
      end
1379
    end
1380
    else
1381
    begin
1382
      if((i1 == i2) && (i1 == {clk_div[7:1], 1'b0}))
1383
      begin
1384
      end
1385
      else
1386
      begin
1387
        fail = fail + 1;
1388
        test_fail("Clock divider of MII module did'nt divide frequency corectly");
1389
      end
1390
    end
1391
  end
1392
  if(fail == 0)
1393
    test_ok;
1394
  else
1395
    fail = 0;
1396 116 mohor
end
1397
 
1398
 
1399 169 mohor
if ((start_task <= 1) && (end_task >= 1))
1400
begin
1401
  // TEST VARIOUS READINGS FROM 'REAL' PHY REGISTERS
1402
  test_name   = "TEST VARIOUS READINGS FROM 'REAL' PHY REGISTERS";
1403
  `TIME; $display("  TEST VARIOUS READINGS FROM 'REAL' PHY REGISTERS");
1404
 
1405
  // set the fastest possible MII
1406
  clk_div = 0;
1407
  mii_set_clk_div(clk_div[7:0]);
1408
  // set address
1409
  reg_addr = 5'h1F;
1410
  phy_addr = 5'h1;
1411
  while(reg_addr >= 5'h4)
1412
  begin
1413
    // read request
1414
    #Tp mii_read_req(phy_addr, reg_addr);
1415
    check_mii_busy; // wait for read to finish
1416
    // read data
1417
    #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1418
    if (phy_data !== 16'hDEAD)
1419
    begin
1420
      test_fail("Wrong data was read from PHY from 'not used' address space");
1421
      fail = fail + 1;
1422
    end
1423
    if (reg_addr == 5'h4) // go out of for loop
1424
      reg_addr = 5'h3;
1425 116 mohor
    else
1426 169 mohor
      reg_addr = reg_addr - 5'h9;
1427
  end
1428 116 mohor
 
1429 169 mohor
  // set address
1430
  reg_addr = 5'h3;
1431
  // read request
1432
  #Tp mii_read_req(phy_addr, reg_addr);
1433
  check_mii_busy; // wait for read to finish
1434
  // read data
1435
  #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1436
  if (phy_data !== {`PHY_ID2, `MAN_MODEL_NUM, `MAN_REVISION_NUM})
1437
  begin
1438
    test_fail("Wrong data was read from PHY from ID register 2");
1439
    fail = fail + 1;
1440 116 mohor
  end
1441 169 mohor
  if(fail == 0)
1442
    test_ok;
1443
  else
1444
    fail = 0;
1445
end
1446 116 mohor
 
1447
 
1448 169 mohor
if ((start_task <= 2) && (end_task >= 2))
1449
begin
1450
  // TEST VARIOUS WRITINGS TO 'REAL' PHY REGISTERS ( CONTROL AND NON WRITABLE REGISTERS )
1451
  test_name   = "TEST VARIOUS WRITINGS TO 'REAL' PHY REGISTERS ( CONTROL AND NON WRITABLE REGISTERS )";
1452
  `TIME; $display("  TEST VARIOUS WRITINGS TO 'REAL' PHY REGISTERS ( CONTROL AND NON WRITABLE REGISTERS )");
1453
 
1454
  // negate data and try to write into unwritable register
1455
  tmp_data = ~phy_data;
1456
  // write request
1457
  #Tp mii_write_req(phy_addr, reg_addr, tmp_data);
1458
  check_mii_busy; // wait for write to finish
1459
  // read request
1460
  #Tp mii_read_req(phy_addr, reg_addr);
1461
  check_mii_busy; // wait for read to finish
1462
  // read data
1463
  #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1464
  if (tmp_data !== phy_data)
1465
  begin
1466
    test_fail("Data was written into unwritable PHY register - ID register 2");
1467
    fail = fail + 1;
1468
  end
1469
 
1470
  // set address
1471
  reg_addr = 5'h0; // control register
1472
  // read request
1473
  #Tp mii_read_req(phy_addr, reg_addr);
1474
  check_mii_busy; // wait for read to finish
1475
  // read data
1476
  #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1477
  // write request
1478
  phy_data = 16'h7DFF; // bit 15 (RESET bit) and bit 9 are self clearing bits
1479
  #Tp mii_write_req(phy_addr, reg_addr, phy_data);
1480
  check_mii_busy; // wait for write to finish
1481
  // read request
1482
  #Tp mii_read_req(phy_addr, reg_addr);
1483
  check_mii_busy; // wait for read to finish
1484
  // read data
1485
  #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1486
  if (phy_data !== 16'h7DFF)
1487
  begin
1488
    test_fail("Data was not correctly written into OR read from writable PHY register - control register");
1489
    fail = fail + 1;
1490
  end
1491
  // write request
1492
  #Tp mii_write_req(phy_addr, reg_addr, tmp_data);
1493
  check_mii_busy; // wait for write to finish
1494
  // read request
1495
  #Tp mii_read_req(phy_addr, reg_addr);
1496
  check_mii_busy; // wait for read to finish
1497
  // read data
1498
  #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1499
  if (phy_data !== tmp_data)
1500
  begin
1501
    test_fail("Data was not correctly written into OR read from writable PHY register - control register");
1502
    fail = fail + 1;
1503
  end
1504
  if(fail == 0)
1505
    test_ok;
1506
  else
1507
    fail = 0;
1508
end
1509
 
1510
 
1511
if ((start_task <= 3) && (end_task >= 3))
1512
begin
1513
  // TEST RESET PHY THROUGH MII MANAGEMENT MODULE
1514
  test_name   = "TEST RESET PHY THROUGH MII MANAGEMENT MODULE";
1515
  `TIME; $display("  TEST RESET PHY THROUGH MII MANAGEMENT MODULE");
1516
 
1517
  // set address
1518
  reg_addr = 5'h0; // control register
1519
  // write request
1520
  phy_data = 16'h7DFF; // bit 15 (RESET bit) and bit 9 are self clearing bits
1521
  #Tp mii_write_req(phy_addr, reg_addr, phy_data);
1522
  check_mii_busy; // wait for write to finish
1523
  // read request
1524
  #Tp mii_read_req(phy_addr, reg_addr);
1525
  check_mii_busy; // wait for read to finish
1526
  // read data
1527
  #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1528
  if (phy_data !== tmp_data)
1529
  begin
1530
    test_fail("Data was not correctly written into OR read from writable PHY register - control register");
1531
    fail = fail + 1;
1532
  end
1533
  // set reset bit - selfclearing bit in PHY
1534
  phy_data = phy_data | 16'h8000;
1535
  // write request
1536
  #Tp mii_write_req(phy_addr, reg_addr, phy_data);
1537
  check_mii_busy; // wait for write to finish
1538
  // read request
1539
  #Tp mii_read_req(phy_addr, reg_addr);
1540
  check_mii_busy; // wait for read to finish
1541
  // read data
1542
  #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1543
  // check self clearing of reset bit
1544
  if (tmp_data[15] !== 1'b0)
1545
  begin
1546
    test_fail("Reset bit should be self cleared - control register");
1547
    fail = fail + 1;
1548
  end
1549
  // check reset value of control register
1550
  if (tmp_data !== {2'h0, (`LED_CFG1 || `LED_CFG2), `LED_CFG1, 3'h0, `LED_CFG3, 8'h0})
1551
  begin
1552
    test_fail("PHY was not reset correctly AND/OR reset bit not self cleared");
1553
    fail = fail + 1;
1554
  end
1555
  if(fail == 0)
1556
    test_ok;
1557
  else
1558
    fail = 0;
1559
end
1560
 
1561
 
1562
if ((start_task <= 4) && (end_task >= 4))
1563
begin
1564
  // TEST 'WALKING ONE' ACROSS PHY ADDRESS ( WITH AND WITHOUT PREAMBLE )
1565
  test_name   = "TEST 'WALKING ONE' ACROSS PHY ADDRESS ( WITH AND WITHOUT PREAMBLE )";
1566
  `TIME; $display("  TEST 'WALKING ONE' ACROSS PHY ADDRESS ( WITH AND WITHOUT PREAMBLE )");
1567
 
1568
  // set PHY to test mode
1569
  #Tp eth_phy.test_regs(1); // set test registers (wholy writable registers) and respond to all PHY addresses
1570
  for (i = 0; i <= 1; i = i + 1)
1571
  begin
1572
    #Tp eth_phy.preamble_suppresed(i);
1573
    #Tp eth_phy.clear_test_regs;
1574
    // MII mode register
1575
    wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}), 4'hF, 1, wbm_init_waits,
1576
              wbm_subseq_waits);
1577
    // walk one across phy address
1578
    for (phy_addr = 5'h1; phy_addr > 5'h0; phy_addr = phy_addr << 1)
1579
    begin
1580
      reg_addr = $random;
1581
      tmp_data = $random;
1582
      // write request
1583
      #Tp mii_write_req(phy_addr, reg_addr, tmp_data);
1584
      check_mii_busy; // wait for write to finish
1585
      // read request
1586
      #Tp mii_read_req(phy_addr, reg_addr);
1587
      check_mii_busy; // wait for read to finish
1588
      // read data
1589
      #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1590
      #Tp;
1591
      if (phy_data !== tmp_data)
1592
      begin
1593
        if (i)
1594
          test_fail("Data was not correctly written into OR read from test registers (without preamble)");
1595
        else
1596
          test_fail("Data was not correctly written into OR read from test registers (with preamble)");
1597
        fail = fail + 1;
1598
      end
1599
      @(posedge wb_clk);
1600
      #Tp;
1601
    end
1602
  end
1603
  // set PHY to normal mode
1604
  #Tp eth_phy.test_regs(0);
1605
  #Tp eth_phy.preamble_suppresed(0);
1606
  // MII mode register
1607
  wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1608
  if(fail == 0)
1609
    test_ok;
1610
  else
1611
    fail = 0;
1612
end
1613
 
1614
 
1615
if ((start_task <= 5) && (end_task >= 5))
1616
begin
1617
  // TEST 'WALKING ONE' ACROSS PHY'S REGISTER ADDRESS ( WITH AND WITHOUT PREAMBLE )
1618
  test_name   = "TEST 'WALKING ONE' ACROSS PHY'S REGISTER ADDRESS ( WITH AND WITHOUT PREAMBLE )";
1619
  `TIME; $display("  TEST 'WALKING ONE' ACROSS PHY'S REGISTER ADDRESS ( WITH AND WITHOUT PREAMBLE )");
1620
 
1621
  // set PHY to test mode
1622
  #Tp eth_phy.test_regs(1); // set test registers (wholy writable registers) and respond to all PHY addresses
1623
  for (i = 0; i <= 1; i = i + 1)
1624
  begin
1625
    #Tp eth_phy.preamble_suppresed(i);
1626
    #Tp eth_phy.clear_test_regs;
1627
    // MII mode register
1628
    wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}), 4'hF, 1, wbm_init_waits,
1629
              wbm_subseq_waits);
1630
    // walk one across reg address
1631
    for (reg_addr = 5'h1; reg_addr > 5'h0; reg_addr = reg_addr << 1)
1632
    begin
1633
      phy_addr = $random;
1634
      tmp_data = $random;
1635
      // write request
1636
      #Tp mii_write_req(phy_addr, reg_addr, tmp_data);
1637
      check_mii_busy; // wait for write to finish
1638
      // read request
1639
      #Tp mii_read_req(phy_addr, reg_addr);
1640
      check_mii_busy; // wait for read to finish
1641
      // read data
1642
      #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1643
      #Tp;
1644
      if (phy_data !== tmp_data)
1645
      begin
1646
        if (i)
1647
          test_fail("Data was not correctly written into OR read from test registers (without preamble)");
1648
        else
1649
          test_fail("Data was not correctly written into OR read from test registers (with preamble)");
1650
        fail = fail + 1;
1651
      end
1652
      @(posedge wb_clk);
1653
      #Tp;
1654
    end
1655
  end
1656
  // set PHY to normal mode
1657
  #Tp eth_phy.test_regs(0);
1658
  #Tp eth_phy.preamble_suppresed(0);
1659
  // MII mode register
1660
  wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1661
  if(fail == 0)
1662
    test_ok;
1663
  else
1664
    fail = 0;
1665
end
1666
 
1667
 
1668
if ((start_task <= 6) && (end_task >= 6))
1669
begin
1670
  // TEST 'WALKING ONE' ACROSS PHY'S DATA ( WITH AND WITHOUT PREAMBLE )
1671
  test_name   = "TEST 'WALKING ONE' ACROSS PHY'S DATA ( WITH AND WITHOUT PREAMBLE )";
1672
  `TIME; $display("  TEST 'WALKING ONE' ACROSS PHY'S DATA ( WITH AND WITHOUT PREAMBLE )");
1673
 
1674
  // set PHY to test mode
1675
  #Tp eth_phy.test_regs(1); // set test registers (wholy writable registers) and respond to all PHY addresses
1676
  for (i = 0; i <= 1; i = i + 1)
1677
  begin
1678
    #Tp eth_phy.preamble_suppresed(i);
1679
    #Tp eth_phy.clear_test_regs;
1680
    // MII mode register
1681
    wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}), 4'hF, 1, wbm_init_waits,
1682
              wbm_subseq_waits);
1683
    // walk one across data
1684
    for (tmp_data = 16'h1; tmp_data > 16'h0; tmp_data = tmp_data << 1)
1685
    begin
1686
      phy_addr = $random;
1687
      reg_addr = $random;
1688
      // write request
1689
      #Tp mii_write_req(phy_addr, reg_addr, tmp_data);
1690
      check_mii_busy; // wait for write to finish
1691
      // read request
1692
      #Tp mii_read_req(phy_addr, reg_addr);
1693
      check_mii_busy; // wait for read to finish
1694
      // read data
1695
      #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1696
      #Tp;
1697
      if (phy_data !== tmp_data)
1698
      begin
1699
        if (i)
1700
          test_fail("Data was not correctly written into OR read from test registers (without preamble)");
1701
        else
1702
          test_fail("Data was not correctly written into OR read from test registers (with preamble)");
1703
        fail = fail + 1;
1704
      end
1705
      @(posedge wb_clk);
1706
      #Tp;
1707
    end
1708
  end
1709
  // set PHY to normal mode
1710
  #Tp eth_phy.test_regs(0);
1711
  #Tp eth_phy.preamble_suppresed(0);
1712
  // MII mode register
1713
  wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1714
  if(fail == 0)
1715
    test_ok;
1716
  else
1717
    fail = 0;
1718
end
1719
 
1720
 
1721
if ((start_task <= 7) && (end_task >= 7))
1722
begin
1723
  // TEST READING FROM PHY WITH WRONG PHY ADDRESS ( HOST READING HIGH 'Z' DATA )
1724
  test_name   = "TEST READING FROM PHY WITH WRONG PHY ADDRESS ( HOST READING HIGH 'Z' DATA )";
1725
  `TIME; $display("  TEST READING FROM PHY WITH WRONG PHY ADDRESS ( HOST READING HIGH 'Z' DATA )");
1726
 
1727
  phy_addr = 5'h2; // wrong PHY address
1728
  // read request
1729
  #Tp mii_read_req(phy_addr, reg_addr);
1730
  check_mii_busy; // wait for read to finish
1731
  // read data
1732
  $display("  => Two errors will be displayed from WB Bus Monitor, because correct HIGH Z data was read");
1733
  #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1734
  if (tmp_data !== 16'hzzzz)
1735
  begin
1736
    test_fail("Data was read from PHY register with wrong PHY address - control register");
1737
    fail = fail + 1;
1738
  end
1739
  if(fail == 0)
1740
    test_ok;
1741
  else
1742
    fail = 0;
1743
end
1744
 
1745
 
1746
if ((start_task <= 8) && (end_task >= 8))
1747
begin
1748
  // TEST WRITING TO PHY WITH WRONG PHY ADDRESS AND READING FROM CORRECT ONE
1749
  test_name   = "TEST WRITING TO PHY WITH WRONG PHY ADDRESS AND READING FROM CORRECT ONE";
1750
  `TIME; $display("  TEST WRITING TO PHY WITH WRONG PHY ADDRESS AND READING FROM CORRECT ONE");
1751
 
1752
  // set address
1753
  reg_addr = 5'h0; // control register
1754
  phy_addr = 5'h2; // wrong PHY address
1755
  // write request
1756
  phy_data = 16'h7DFF; // bit 15 (RESET bit) and bit 9 are self clearing bits
1757
  #Tp mii_write_req(phy_addr, reg_addr, phy_data);
1758
  check_mii_busy; // wait for write to finish
1759
 
1760
  phy_addr = 5'h1; // correct PHY address
1761
  // read request
1762
  #Tp mii_read_req(phy_addr, reg_addr);
1763
  check_mii_busy; // wait for read to finish
1764
  // read data
1765
  #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1766
  if (phy_data === tmp_data)
1767
  begin
1768
    test_fail("Data was written into PHY register with wrong PHY address - control register");
1769
    fail = fail + 1;
1770
  end
1771
  if(fail == 0)
1772
    test_ok;
1773
  else
1774
    fail = 0;
1775
end
1776
 
1777
 
1778
if ((start_task <= 9) && (end_task >= 9))
1779
begin
1780
  // TEST SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER READ REQUEST ( WITH AND WITHOUT PREAMBLE )
1781
  test_name = "TEST SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER READ REQUEST ( WITH AND WITHOUT PREAMBLE )";
1782
  `TIME;
1783
  $display("  TEST SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER READ REQUEST ( WITH AND WITHOUT PREAMBLE )");
1784
 
1785
  for (i2 = 0; i2 <= 1; i2 = i2 + 1) // choose preamble or not
1786
  begin
1787
    #Tp eth_phy.preamble_suppresed(i2);
1788
    // MII mode register
1789
    wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i2, 8'h0}), 4'hF, 1, wbm_init_waits,
1790
             wbm_subseq_waits);
1791
    i = 0;
1792
    cnt = 0;
1793
    while (i < 80) // delay for sliding of writing a STOP SCAN command
1794
    begin
1795
      for (i3 = 0; i3 <= 1; i3 = i3 + 1) // choose read or write after read will be finished
1796
      begin
1797
        // set address
1798
        reg_addr = 5'h0; // control register
1799
        phy_addr = 5'h1; // correct PHY address
1800
        cnt = 0;
1801
        // read request
1802
        #Tp mii_read_req(phy_addr, reg_addr);
1803
        fork
1804
          begin
1805
            repeat(i) @(posedge Mdc_O);
1806
            // write command 0x0 into MII command register
1807
            // MII command written while read in progress
1808
            wbm_write(`ETH_MIICOMMAND, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1809
            @(posedge wb_clk);
1810
            #Tp check_mii_busy; // wait for read to finish
1811
          end
1812
          begin
1813
            // wait for serial bus to become active
1814
            wait(Mdio_IO !== 1'bz);
1815
            // count transfer length
1816
            while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
1817
            begin
1818
              @(posedge Mdc_O);
1819
              #Tp cnt = cnt + 1;
1820
            end
1821
          end
1822
        join
1823
        // check transfer length
1824
        if (i2) // without preamble
1825
        begin
1826
          if (cnt != 33) // at this value Mdio_IO is HIGH Z
1827
          begin
1828
            test_fail("Read request did not proceed correctly, while SCAN STOP command was written");
1829
            fail = fail + 1;
1830
          end
1831
        end
1832
        else // with preamble
1833
        begin
1834
          if (cnt != 65) // at this value Mdio_IO is HIGH Z
1835
          begin
1836
            test_fail("Read request did not proceed correctly, while SCAN STOP command was written");
1837
            fail = fail + 1;
1838
          end
1839
        end
1840
        // check the BUSY signal to see if the bus is still IDLE
1841
        for (i1 = 0; i1 < 8; i1 = i1 + 1)
1842
          check_mii_busy; // wait for bus to become idle
1843 116 mohor
 
1844 169 mohor
        // try normal write or read after read was finished
1845
        #Tp phy_data = {8'h7D, (i[7:0] + 1)};
1846
        #Tp cnt = 0;
1847
        if (i3 == 0) // write after read
1848
        begin
1849
          // write request
1850
          #Tp mii_write_req(phy_addr, reg_addr, phy_data);
1851
          // wait for serial bus to become active
1852
          wait(Mdio_IO !== 1'bz);
1853
          // count transfer length
1854
          while(Mdio_IO !== 1'bz)
1855
          begin
1856
            @(posedge Mdc_O);
1857
            #Tp cnt = cnt + 1;
1858
          end
1859
          @(posedge Mdc_O);
1860
          // read request
1861
          #Tp mii_read_req(phy_addr, reg_addr);
1862
          check_mii_busy; // wait for read to finish
1863
          // read and check data
1864
          #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1865
          if (phy_data !== tmp_data)
1866
          begin
1867
            test_fail("Data was not correctly written into OR read from PHY register - control register");
1868
            fail = fail + 1;
1869
          end
1870
        end
1871
        else // read after read
1872
        begin
1873
          // read request
1874
          #Tp mii_read_req(phy_addr, reg_addr);
1875
          // wait for serial bus to become active
1876
          wait(Mdio_IO !== 1'bz);
1877
          // count transfer length
1878
          while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
1879
          begin
1880
            @(posedge Mdc_O);
1881
            #Tp cnt = cnt + 1;
1882
          end
1883
          @(posedge Mdc_O);
1884
          check_mii_busy; // wait for read to finish
1885
          // read and check data
1886
          #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1887
          if (phy_data !== tmp_data)
1888
          begin
1889
            test_fail("Data was not correctly written into OR read from PHY register - control register");
1890
            fail = fail + 1;
1891
          end
1892
        end
1893
        // check if transfer was a proper length
1894
        if (i2) // without preamble
1895
        begin
1896
          if (cnt != 33) // at this value Mdio_IO is HIGH Z
1897
          begin
1898
            test_fail("New request did not proceed correctly, after read request");
1899
            fail = fail + 1;
1900
          end
1901
        end
1902
        else // with preamble
1903
        begin
1904
          if (cnt != 65) // at this value Mdio_IO is HIGH Z
1905
          begin
1906
            test_fail("New request did not proceed correctly, after read request");
1907
            fail = fail + 1;
1908
          end
1909
        end
1910
      end
1911
      #Tp;
1912
      // set delay of writing the command
1913
      if (i2) // without preamble
1914
      begin
1915
        case(i)
1916
          0, 1:               i = i + 1;
1917
          18, 19, 20, 21, 22,
1918
          23, 24, 25, 26, 27,
1919
          28, 29, 30, 31, 32,
1920
          33, 34, 35:         i = i + 1;
1921
          36:                 i = 80;
1922
          default:            i = 18;
1923
        endcase
1924
      end
1925
      else // with preamble
1926
      begin
1927
        case(i)
1928
          0, 1:               i = i + 1;
1929
          50, 51, 52, 53, 54,
1930
          55, 56, 57, 58, 59,
1931
          60, 61, 62, 63, 64,
1932
          65, 66, 67:         i = i + 1;
1933
          68:                 i = 80;
1934
          default:            i = 50;
1935
        endcase
1936
      end
1937
      @(posedge wb_clk);
1938
    end
1939
  end
1940
  // set PHY to normal mode
1941
  #Tp eth_phy.preamble_suppresed(0);
1942
  // MII mode register
1943
  wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1944
  if(fail == 0)
1945
    test_ok;
1946
  else
1947
    fail = 0;
1948
end
1949
 
1950
 
1951
if ((start_task <= 10) && (end_task >= 10))
1952
begin
1953
  // TEST SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER WRITE REQUEST ( WITH AND WITHOUT PREAMBLE )
1954
  test_name = "TEST SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER WRITE REQUEST ( WITH AND WITHOUT PREAMBLE )";
1955
  `TIME;
1956
  $display("  TEST SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER WRITE REQUEST ( WITH AND WITHOUT PREAMBLE )");
1957
 
1958
  for (i2 = 0; i2 <= 1; i2 = i2 + 1) // choose preamble or not
1959
  begin
1960
    #Tp eth_phy.preamble_suppresed(i2);
1961
    // MII mode register
1962
    wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i2, 8'h0}), 4'hF, 1, wbm_init_waits,
1963
              wbm_subseq_waits);
1964
    i = 0;
1965
    cnt = 0;
1966
    while (i < 80) // delay for sliding of writing a STOP SCAN command
1967
    begin
1968
      for (i3 = 0; i3 <= 1; i3 = i3 + 1) // choose read or write after write will be finished
1969
      begin
1970
        // set address
1971
        reg_addr = 5'h0; // control register
1972
        phy_addr = 5'h1; // correct PHY address
1973
        cnt = 0;
1974
        // write request
1975
        phy_data = {8'h75, (i[7:0] + 1)};
1976
        #Tp mii_write_req(phy_addr, reg_addr, phy_data);
1977
        fork
1978
          begin
1979
            repeat(i) @(posedge Mdc_O);
1980
            // write command 0x0 into MII command register
1981
            // MII command written while read in progress
1982
            wbm_write(`ETH_MIICOMMAND, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1983
            @(posedge wb_clk);
1984
            #Tp check_mii_busy; // wait for write to finish
1985
          end
1986
          begin
1987
            // wait for serial bus to become active
1988
            wait(Mdio_IO !== 1'bz);
1989
            // count transfer length
1990
            while(Mdio_IO !== 1'bz)
1991
            begin
1992
              @(posedge Mdc_O);
1993
              #Tp cnt = cnt + 1;
1994
            end
1995
          end
1996
        join
1997
        // check transfer length
1998
        if (i2) // without preamble
1999
        begin
2000
          if (cnt != 33) // at this value Mdio_IO is HIGH Z
2001
          begin
2002
            test_fail("Write request did not proceed correctly, while SCAN STOP command was written");
2003
            fail = fail + 1;
2004
          end
2005
        end
2006
        else // with preamble
2007
        begin
2008
          if (cnt != 65) // at this value Mdio_IO is HIGH Z
2009
          begin
2010
            test_fail("Write request did not proceed correctly, while SCAN STOP command was written");
2011
            fail = fail + 1;
2012
          end
2013
        end
2014
        // check the BUSY signal to see if the bus is still IDLE
2015
        for (i1 = 0; i1 < 8; i1 = i1 + 1)
2016
          check_mii_busy; // wait for bus to become idle
2017 116 mohor
 
2018 169 mohor
        // try normal write or read after write was finished
2019
        #Tp cnt = 0;
2020
        if (i3 == 0) // write after write
2021
        begin
2022
          phy_data = {8'h7A, (i[7:0] + 1)};
2023
          // write request
2024
          #Tp mii_write_req(phy_addr, reg_addr, phy_data);
2025
          // wait for serial bus to become active
2026
          wait(Mdio_IO !== 1'bz);
2027
          // count transfer length
2028
          while(Mdio_IO !== 1'bz)
2029
          begin
2030
            @(posedge Mdc_O);
2031
            #Tp cnt = cnt + 1;
2032
          end
2033
          @(posedge Mdc_O);
2034
          // read request
2035
          #Tp mii_read_req(phy_addr, reg_addr);
2036
          check_mii_busy; // wait for read to finish
2037
          // read and check data
2038
          #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data , 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2039
          if (phy_data !== tmp_data)
2040
          begin
2041
            test_fail("Data was not correctly written into OR read from PHY register - control register");
2042
            fail = fail + 1;
2043
          end
2044
        end
2045
        else // read after write
2046
        begin
2047
          // read request
2048
          #Tp mii_read_req(phy_addr, reg_addr);
2049
          // wait for serial bus to become active
2050
          wait(Mdio_IO !== 1'bz);
2051
          // count transfer length
2052
          while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
2053
          begin
2054
            @(posedge Mdc_O);
2055
            #Tp cnt = cnt + 1;
2056
          end
2057
          @(posedge Mdc_O);
2058
          check_mii_busy; // wait for read to finish
2059
          // read and check data
2060
          #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data , 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2061
          if (phy_data !== tmp_data)
2062
          begin
2063
            test_fail("Data was not correctly written into OR read from PHY register - control register");
2064
            fail = fail + 1;
2065
          end
2066
        end
2067
        // check if transfer was a proper length
2068
        if (i2) // without preamble
2069
        begin
2070
          if (cnt != 33) // at this value Mdio_IO is HIGH Z
2071
          begin
2072
            test_fail("New request did not proceed correctly, after write request");
2073
            fail = fail + 1;
2074
          end
2075
        end
2076
        else // with preamble
2077
        begin
2078
          if (cnt != 65) // at this value Mdio_IO is HIGH Z
2079
          begin
2080
            test_fail("New request did not proceed correctly, after write request");
2081
            fail = fail + 1;
2082
          end
2083
        end
2084
      end
2085
      #Tp;
2086
      // set delay of writing the command
2087
      if (i2) // without preamble
2088
      begin
2089
        case(i)
2090
          0, 1:               i = i + 1;
2091
          18, 19, 20, 21, 22,
2092
          23, 24, 25, 26, 27,
2093
          28, 29, 30, 31, 32,
2094
          33, 34, 35:         i = i + 1;
2095
          36:                 i = 80;
2096
          default:            i = 18;
2097
        endcase
2098
      end
2099
      else // with preamble
2100
      begin
2101
        case(i)
2102
          0, 1:               i = i + 1;
2103
          50, 51, 52, 53, 54,
2104
          55, 56, 57, 58, 59,
2105
          60, 61, 62, 63, 64,
2106
          65, 66, 67:         i = i + 1;
2107
          68:                 i = 80;
2108
          default:            i = 50;
2109
        endcase
2110
      end
2111
      @(posedge wb_clk);
2112
    end
2113
  end
2114
  // set PHY to normal mode
2115
  #Tp eth_phy.preamble_suppresed(0);
2116
  // MII mode register
2117
  wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2118
  if(fail == 0)
2119
    test_ok;
2120
  else
2121
    fail = 0;
2122
end
2123
 
2124
 
2125
if ((start_task <= 11) && (end_task >= 11))
2126
begin
2127
  // TEST BUSY AND NVALID STATUS DURATIONS DURING WRITE ( WITH AND WITHOUT PREAMBLE )
2128
  test_name   = "TEST BUSY AND NVALID STATUS DURATIONS DURING WRITE ( WITH AND WITHOUT PREAMBLE )";
2129
  `TIME; $display("  TEST BUSY AND NVALID STATUS DURATIONS DURING WRITE ( WITH AND WITHOUT PREAMBLE )");
2130
 
2131
  reset_mii; // reset MII
2132
  // set link up, if it wasn't due to previous tests, since there weren't PHY registers
2133
  #Tp eth_phy.link_up_down(1);
2134
  // set the MII
2135
  clk_div = 64;
2136
  mii_set_clk_div(clk_div[7:0]);
2137
  // set address
2138
  reg_addr = 5'h1; // status register
2139
  phy_addr = 5'h1; // correct PHY address
2140
 
2141
  for (i = 0; i <= 1; i = i + 1)
2142
  begin
2143
    #Tp eth_phy.preamble_suppresed(i);
2144
    // MII mode register
2145
    wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}) | (`ETH_MIIMODER_CLKDIV & clk_div),
2146
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2147
    @(posedge Mdc_O);
2148
    // write request
2149
    #Tp mii_write_req(phy_addr, reg_addr, 16'h5A5A);
2150
    // read data from MII status register - Busy and Nvalid bits
2151
    #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2152
 
2153
    // check MII IO signal and Busy and Nvalid bits
2154
    if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
2155
    begin
2156
      test_fail("Testbench error - read was to late, Mdio_IO is not HIGH Z - set higher clock divider");
2157
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2158
      begin
2159
        test_fail("Busy signal was not set while MII IO signal is not HIGH Z anymore - 1. read");
2160
        fail = fail + 1;
2161
      end
2162
      if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2163
      begin
2164
        test_fail("Nvalid signal was set during write");
2165
        fail = fail + 1;
2166
      end
2167
    end
2168
    else // Busy bit should already be set to '1', due to reads from MII status register
2169
    begin
2170
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2171
      begin
2172
        test_fail("Busy signal should be set after write, due to reads from MII status register");
2173
        fail = fail + 1;
2174
      end
2175
      if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2176
      begin
2177
        test_fail("Nvalid signal was set during write");
2178
        fail = fail + 1;
2179
      end
2180
    end
2181
 
2182
    // wait for serial bus to become active
2183
    wait(Mdio_IO !== 1'bz);
2184
    // count transfer bits
2185
    if (i)
2186
    begin
2187
      repeat(32) @(posedge Mdc_O);
2188
    end
2189 116 mohor
    else
2190 169 mohor
    begin
2191
      repeat(64) @(posedge Mdc_O);
2192
    end
2193
    // read data from MII status register - Busy and Nvalid bits
2194
    #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2195 116 mohor
 
2196 169 mohor
    // check MII IO signal and Busy and Nvalid bits
2197
    if (Mdio_IO === 1'bz) // Mdio_IO should not be HIGH Z here - testbench selfcheck
2198
    begin
2199
      test_fail("Testbench error - read was to late, Mdio_IO is HIGH Z - set higher clock divider");
2200
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2201
      begin
2202
        test_fail("Busy signal should be set while MII IO signal is not active anymore");
2203
        fail = fail + 1;
2204
      end
2205
      if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2206
      begin
2207
        test_fail("Nvalid signal was set during write");
2208
        fail = fail + 1;
2209
      end
2210
    end
2211
    else // Busy bit should still be set to '1'
2212
    begin
2213
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2214
      begin
2215
        test_fail("Busy signal should be set while MII IO signal not HIGH Z");
2216
        fail = fail + 1;
2217
      end
2218
      if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2219
      begin
2220
        test_fail("Nvalid signal was set during write");
2221
        fail = fail + 1;
2222
      end
2223
    end
2224
 
2225
    // wait for next negative clock edge
2226
    @(negedge Mdc_O);
2227
    // read data from MII status register - Busy and Nvalid bits
2228
    #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2229
 
2230
    // check MII IO signal and Busy and Nvalid bits
2231
    if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
2232
    begin
2233
      test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider");
2234
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2235
      begin
2236
        test_fail("Busy signal was not set while MII IO signal is not HIGH Z");
2237
        fail = fail + 1;
2238
      end
2239
      if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2240
      begin
2241
        test_fail("Nvalid signal was set during write");
2242
        fail = fail + 1;
2243
      end
2244
    end
2245
    else // Busy bit should still be set to '1'
2246
    begin
2247
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2248
      begin
2249
        test_fail("Busy signal should be set after MII IO signal become HIGH Z");
2250
        fail = fail + 1;
2251
      end
2252
      if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2253
      begin
2254
        test_fail("Nvalid signal was set during write");
2255
        fail = fail + 1;
2256
      end
2257
    end
2258
 
2259
    // wait for Busy to become inactive
2260
    i1 = 0;
2261
    while (i1 <= 2)
2262
    begin
2263
      // wait for next positive clock edge
2264
      @(posedge Mdc_O);
2265
      // read data from MII status register - Busy and Nvalid bits
2266
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2267
 
2268
      // check MII IO signal and Busy and Nvalid bits
2269
      if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
2270
      begin
2271
        test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider");
2272
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2273
        begin
2274
          test_fail("Busy signal was not set while MII IO signal is not HIGH Z");
2275
          fail = fail + 1;
2276
        end
2277
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2278
        begin
2279
          test_fail("Nvalid signal was set during write");
2280
          fail = fail + 1;
2281
        end
2282
      end
2283
      else // wait for Busy bit to be set to '0'
2284
      begin
2285
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2286
        begin
2287
          i1 = 3; // end of Busy checking
2288
        end
2289
        else
2290
        begin
2291
          if (i1 == 2)
2292
          begin
2293
            test_fail("Busy signal should be cleared after 2 periods after MII IO signal become HIGH Z");
2294
            fail = fail + 1;
2295
          end
2296
          #Tp i1 = i1 + 1;
2297
        end
2298
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2299
        begin
2300
          test_fail("Nvalid signal was set after write");
2301
          fail = fail + 1;
2302
        end
2303
      end
2304
    end
2305 116 mohor
  end
2306 169 mohor
  // set PHY to normal mode
2307
  #Tp eth_phy.preamble_suppresed(0);
2308
  // MII mode register
2309
  wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2310
  if(fail == 0)
2311
    test_ok;
2312
  else
2313
    fail = 0;
2314
end
2315 116 mohor
 
2316
 
2317 169 mohor
if ((start_task <= 12) && (end_task >= 12))
2318
begin
2319
  // TEST BUSY AND NVALID STATUS DURATIONS DURING READ ( WITH AND WITHOUT PREAMBLE )
2320
  test_name   = "TEST BUSY AND NVALID STATUS DURATIONS DURING READ ( WITH AND WITHOUT PREAMBLE )";
2321
  `TIME; $display("  TEST BUSY AND NVALID STATUS DURATIONS DURING READ ( WITH AND WITHOUT PREAMBLE )");
2322 116 mohor
 
2323 169 mohor
  reset_mii; // reset MII
2324
  // set link up, if it wasn't due to previous tests, since there weren't PHY registers
2325
  #Tp eth_phy.link_up_down(1);
2326
  // set the MII
2327
  clk_div = 64;
2328
  mii_set_clk_div(clk_div[7:0]);
2329
  // set address
2330
  reg_addr = 5'h1; // status register
2331
  phy_addr = 5'h1; // correct PHY address
2332
 
2333
  for (i = 0; i <= 1; i = i + 1)
2334
  begin
2335
    #Tp eth_phy.preamble_suppresed(i);
2336
    // MII mode register
2337
    wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}) | (`ETH_MIIMODER_CLKDIV & clk_div),
2338
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2339
    @(posedge Mdc_O);
2340
    // read request
2341
    #Tp mii_read_req(phy_addr, reg_addr);
2342
    // read data from MII status register - Busy and Nvalid bits
2343
    #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2344
 
2345
    // check MII IO signal and Busy and Nvalid bits
2346
    if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
2347
    begin
2348
      test_fail("Testbench error - read was to late, Mdio_IO is not HIGH Z - set higher clock divider");
2349
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2350
      begin
2351
        test_fail("Busy signal was not set while MII IO signal is not HIGH Z anymore - 1. read");
2352
        fail = fail + 1;
2353
      end
2354
      if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2355
      begin
2356
        test_fail("Nvalid signal was set during read");
2357
        fail = fail + 1;
2358
      end
2359
    end
2360
    else // Busy bit should already be set to '1', due to reads from MII status register
2361
    begin
2362
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2363
      begin
2364
        test_fail("Busy signal should be set after read, due to reads from MII status register");
2365
        fail = fail + 1;
2366
      end
2367
      if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2368
      begin
2369
        test_fail("Nvalid signal was set during read");
2370
        fail = fail + 1;
2371
      end
2372
    end
2373
 
2374
    // wait for serial bus to become active
2375
    wait(Mdio_IO !== 1'bz);
2376
    // count transfer bits
2377
    if (i)
2378
    begin
2379
      repeat(31) @(posedge Mdc_O);
2380
    end
2381
    else
2382
    begin
2383
      repeat(63) @(posedge Mdc_O);
2384
    end
2385
    // wait for next negative clock edge
2386
    @(negedge Mdc_O);
2387
    // read data from MII status register - Busy and Nvalid bits
2388
    #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2389
 
2390
    // check MII IO signal and Busy and Nvalid bits
2391
    if (Mdio_IO === 1'bz) // Mdio_IO should not be HIGH Z here - testbench selfcheck
2392
    begin
2393
      test_fail("Testbench error - read was to late, Mdio_IO is HIGH Z - set higher clock divider");
2394
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2395
      begin
2396
        test_fail("Busy signal should be set while MII IO signal is not active anymore");
2397
        fail = fail + 1;
2398
      end
2399
      if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2400
      begin
2401
        test_fail("Nvalid signal was set during read");
2402
        fail = fail + 1;
2403
      end
2404
    end
2405
    else // Busy bit should still be set to '1'
2406
    begin
2407
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2408
      begin
2409
        test_fail("Busy signal should be set while MII IO signal not HIGH Z");
2410
        fail = fail + 1;
2411
      end
2412
      if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2413
      begin
2414
        test_fail("Nvalid signal was set during read");
2415
        fail = fail + 1;
2416
      end
2417
    end
2418
 
2419
    // wait for next positive clock edge
2420
    @(posedge Mdc_O);
2421
    // read data from MII status register - Busy and Nvalid bits
2422
    #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2423
 
2424
    // check MII IO signal and Busy and Nvalid bits
2425
    if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
2426
    begin
2427
      test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider");
2428
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2429
      begin
2430
        test_fail("Busy signal was not set while MII IO signal is not HIGH Z");
2431
        fail = fail + 1;
2432
      end
2433
      if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2434
      begin
2435
        test_fail("Nvalid signal was set during read");
2436
        fail = fail + 1;
2437
      end
2438
    end
2439
    else // Busy bit should still be set to '1'
2440
    begin
2441
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2442
      begin
2443
        test_fail("Busy signal should be set after MII IO signal become HIGH Z");
2444
        fail = fail + 1;
2445
      end
2446
      if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2447
      begin
2448
        test_fail("Nvalid signal was set during read");
2449
        fail = fail + 1;
2450
      end
2451
    end
2452
 
2453
    // wait for Busy to become inactive
2454
    i1 = 0;
2455
    while (i1 <= 2)
2456
    begin
2457
      // wait for next positive clock edge
2458
      @(posedge Mdc_O);
2459
      // read data from MII status register - Busy and Nvalid bits
2460
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2461
 
2462
      // check MII IO signal and Busy and Nvalid bits
2463
      if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
2464
      begin
2465
        test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider");
2466
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2467
        begin
2468
          test_fail("Busy signal was not set while MII IO signal is not HIGH Z");
2469
          fail = fail + 1;
2470
        end
2471
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2472
        begin
2473
          test_fail("Nvalid signal was set during read");
2474
          fail = fail + 1;
2475
        end
2476
      end
2477
      else // wait for Busy bit to be set to '0'
2478
      begin
2479
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2480
        begin
2481
          i1 = 3; // end of Busy checking
2482
        end
2483
        else
2484
        begin
2485
          if (i1 == 2)
2486
          begin
2487
            test_fail("Busy signal should be cleared after 2 periods after MII IO signal become HIGH Z");
2488
            fail = fail + 1;
2489
          end
2490
          #Tp i1 = i1 + 1;
2491
        end
2492
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2493
        begin
2494
          test_fail("Nvalid signal was set after read");
2495
          fail = fail + 1;
2496
        end
2497
      end
2498
    end
2499
  end
2500
  // set PHY to normal mode
2501
  #Tp eth_phy.preamble_suppresed(0);
2502
  // MII mode register
2503
  wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2504
  if(fail == 0)
2505
    test_ok;
2506
  else
2507
    fail = 0;
2508
end
2509
 
2510
 
2511
if ((start_task <= 13) && (end_task >= 13))
2512
begin
2513
  // TEST BUSY AND NVALID STATUS DURATIONS DURING SCAN ( WITH AND WITHOUT PREAMBLE )
2514
  test_name   = "TEST BUSY AND NVALID STATUS DURATIONS DURING SCAN ( WITH AND WITHOUT PREAMBLE )";
2515
  `TIME; $display("  TEST BUSY AND NVALID STATUS DURATIONS DURING SCAN ( WITH AND WITHOUT PREAMBLE )");
2516
 
2517
  reset_mii; // reset MII
2518
  // set link up, if it wasn't due to previous tests, since there weren't PHY registers
2519
  #Tp eth_phy.link_up_down(1);
2520
  // set the MII
2521
  clk_div = 64;
2522
  mii_set_clk_div(clk_div[7:0]);
2523
  // set address
2524
  reg_addr = 5'h1; // status register
2525
  phy_addr = 5'h1; // correct PHY address
2526
 
2527
  for (i = 0; i <= 1; i = i + 1)
2528
  begin
2529
    #Tp eth_phy.preamble_suppresed(i);
2530
    // MII mode register
2531
    wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}) | (`ETH_MIIMODER_CLKDIV & clk_div),
2532
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2533
    @(posedge Mdc_O);
2534
    // scan request
2535
    #Tp mii_scan_req(phy_addr, reg_addr);
2536
    // read data from MII status register - Busy and Nvalid bits
2537
    #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2538
 
2539
    // check MII IO signal and Busy and Nvalid bits
2540
    if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
2541
    begin
2542
      test_fail("Testbench error - read was to late, Mdio_IO is not HIGH Z - set higher clock divider");
2543
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2544
      begin
2545
        test_fail("Busy signal was not set while MII IO signal is not HIGH Z anymore - 1. read");
2546
        fail = fail + 1;
2547
      end
2548
      if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
2549
      begin
2550
        test_fail("Nvalid signal was not set while MII IO signal is not HIGH Z anymore - 1. read");
2551
        fail = fail + 1;
2552
      end
2553
    end
2554
    else // Busy bit should already be set to '1', due to reads from MII status register
2555
    begin
2556
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2557
      begin
2558
        test_fail("Busy signal should be set after scan, due to reads from MII status register");
2559
        fail = fail + 1;
2560
      end
2561
      if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
2562
      begin
2563
        test_fail("Nvalid signal should be set after scan, due to reads from MII status register");
2564
        fail = fail + 1;
2565
      end
2566
    end
2567
 
2568
    // wait for serial bus to become active
2569
    wait(Mdio_IO !== 1'bz);
2570
    // count transfer bits
2571
    if (i)
2572
    begin
2573
      repeat(21) @(posedge Mdc_O);
2574
    end
2575
    else
2576
    begin
2577
      repeat(53) @(posedge Mdc_O);
2578
    end
2579
    // stop scan
2580
    #Tp mii_scan_finish; // finish scan operation
2581
 
2582
    // wait for next positive clock edge
2583
    repeat(10) @(posedge Mdc_O);
2584
    // read data from MII status register - Busy and Nvalid bits
2585
    #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2586
 
2587
    // check MII IO signal and Busy and Nvalid bits
2588
    if (Mdio_IO === 1'bz) // Mdio_IO should not be HIGH Z here - testbench selfcheck
2589
    begin
2590
      test_fail("Testbench error - read was to late, Mdio_IO is HIGH Z - set higher clock divider");
2591
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2592
      begin
2593
        test_fail("Busy signal should be set while MII IO signal is not active anymore");
2594
        fail = fail + 1;
2595
      end
2596
      // Nvalid signal can be cleared here - it is still Testbench error
2597
    end
2598
    else // Busy bit should still be set to '1', Nvalid bit should still be set to '1'
2599
    begin
2600
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2601
      begin
2602
        test_fail("Busy signal should be set while MII IO signal not HIGH Z");
2603
        fail = fail + 1;
2604
      end
2605
      if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
2606
      begin
2607
        test_fail("Nvalid signal should be set while MII IO signal not HIGH Z");
2608
        fail = fail + 1;
2609
      end
2610
    end
2611
 
2612
    // wait for next negative clock edge
2613
    @(negedge Mdc_O);
2614
    // read data from MII status register - Busy and Nvalid bits
2615
    #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2616
 
2617
    // check MII IO signal and Busy and Nvalid bits
2618
    if (Mdio_IO === 1'bz) // Mdio_IO should not be HIGH Z here - testbench selfcheck
2619
    begin
2620
      test_fail("Testbench error - read was to late, Mdio_IO is HIGH Z - set higher clock divider");
2621
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2622
      begin
2623
        test_fail("Busy signal should be set while MII IO signal is not active anymore");
2624
        fail = fail + 1;
2625
      end
2626
      // Nvalid signal can be cleared here - it is still Testbench error
2627
    end
2628
    else // Busy bit should still be set to '1', Nvalid bit should still be set to '1'
2629
    begin
2630
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2631
      begin
2632
        test_fail("Busy signal should be set while MII IO signal not HIGH Z");
2633
        fail = fail + 1;
2634
      end
2635
      if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
2636
      begin
2637
        test_fail("Nvalid signal should be set while MII IO signal not HIGH Z");
2638
        fail = fail + 1;
2639
      end
2640
    end
2641
 
2642
    // wait for next negative clock edge
2643
    @(posedge Mdc_O);
2644
    // read data from MII status register - Busy and Nvalid bits
2645
    #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2646
 
2647
    // check MII IO signal and Busy and Nvalid bits
2648
    if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
2649
    begin
2650
      test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider");
2651
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2652
      begin
2653
        test_fail("Busy signal was not set while MII IO signal is not HIGH Z");
2654
        fail = fail + 1;
2655
      end
2656
      if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
2657
      begin
2658
        test_fail("Nvalid signal was not set while MII IO signal is not HIGH Z");
2659
        fail = fail + 1;
2660
      end
2661
    end
2662
    else // Busy bit should still be set to '1', Nvalid bit can be set to '0'
2663
    begin
2664
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2665
      begin
2666
        test_fail("Busy signal should be set after MII IO signal become HIGH Z");
2667
        fail = fail + 1;
2668
      end
2669
      if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
2670
      begin
2671
        i2 = 1; // check finished
2672
      end
2673
      else
2674
      begin
2675
        i2 = 0; // check must continue
2676
      end
2677
    end
2678
 
2679
    // wait for Busy to become inactive
2680
    i1 = 0;
2681
    while ((i1 <= 2) || (i2 == 0))
2682
    begin
2683
      // wait for next positive clock edge
2684
      @(posedge Mdc_O);
2685
      // read data from MII status register - Busy and Nvalid bits
2686
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2687
 
2688
      // check MII IO signal and Busy and Nvalid bits
2689
      if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
2690
      begin
2691
        test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider");
2692
        if (i1 <= 2)
2693
        begin
2694
          if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2695
          begin
2696
            test_fail("Busy signal was not set while MII IO signal is not HIGH Z");
2697
            fail = fail + 1;
2698
          end
2699
        end
2700
        if (i2 == 0)
2701
        begin
2702
          if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
2703
          begin
2704
            test_fail("Nvalid signal was not set while MII IO signal is not HIGH Z");
2705
            fail = fail + 1;
2706
          end
2707
        end
2708
      end
2709
      else // wait for Busy bit to be set to '0'
2710
      begin
2711
        if (i1 <= 2)
2712
        begin
2713
          if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2714
          begin
2715
            i1 = 3; // end of Busy checking
2716
          end
2717
          else
2718
          begin
2719
            if (i1 == 2)
2720
            begin
2721
              test_fail("Busy signal should be cleared after 2 periods after MII IO signal become HIGH Z");
2722
              fail = fail + 1;
2723
            end
2724
            #Tp i1 = i1 + 1;
2725
          end
2726
        end
2727
        if (i2 == 0)
2728
        begin
2729
          if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
2730
          begin
2731
            i2 = 1;
2732
          end
2733
          else
2734
          begin
2735
            test_fail("Nvalid signal should be cleared after MII IO signal become HIGH Z");
2736
            fail = fail + 1;
2737
          end
2738
        end
2739
      end
2740
    end
2741
  end
2742
  // set PHY to normal mode
2743
  #Tp eth_phy.preamble_suppresed(0);
2744
  // MII mode register
2745
  wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2746
  if(fail == 0)
2747
    test_ok;
2748
  else
2749
    fail = 0;
2750
end
2751
 
2752
 
2753
if ((start_task <= 14) && (end_task >= 14))
2754
begin
2755
  // TEST SCAN STATUS FROM PHY WITH DETECTING LINK-FAIL BIT ( WITH AND WITHOUT PREAMBLE )
2756
  test_name   = "TEST SCAN STATUS FROM PHY WITH DETECTING LINK-FAIL BIT ( WITH AND WITHOUT PREAMBLE )";
2757
  `TIME; $display("  TEST SCAN STATUS FROM PHY WITH DETECTING LINK-FAIL BIT ( WITH AND WITHOUT PREAMBLE )");
2758
 
2759
  reset_mii; // reset MII
2760
  // set link up, if it wasn't due to previous tests, since there weren't PHY registers
2761
  #Tp eth_phy.link_up_down(1);
2762
  // set MII speed
2763
  clk_div = 6;
2764
  mii_set_clk_div(clk_div[7:0]);
2765
  // set address
2766
  reg_addr = 5'h1; // status register
2767
  phy_addr = 5'h1; // correct PHY address
2768
 
2769
  // read request
2770
  #Tp mii_read_req(phy_addr, reg_addr);
2771
  check_mii_busy; // wait for read to finish
2772
  // read data from PHY status register - remember LINK-UP status
2773
  #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2774
 
2775
  for (i = 0; i <= 1; i = i + 1)
2776
  begin
2777
    #Tp eth_phy.preamble_suppresed(i);
2778
    // MII mode register
2779
    wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}) | (`ETH_MIIMODER_CLKDIV & clk_div),
2780
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2781
    if (i)
2782
    begin
2783
      // change saved data when preamble is suppressed
2784
      #Tp tmp_data = tmp_data | 16'h0040; // put bit 6 to ONE
2785
    end
2786
 
2787
    // scan request
2788
    #Tp mii_scan_req(phy_addr, reg_addr);
2789
    check_mii_scan_valid; // wait for scan to make first data valid
2790
 
2791
    fork
2792
    begin
2793
      repeat(2) @(posedge Mdc_O);
2794
      // read data from PHY status register
2795
      #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2796
      if (phy_data !== tmp_data)
2797
      begin
2798
        test_fail("Data was not correctly scaned from status register");
2799
        fail = fail + 1;
2800
      end
2801
      // read data from MII status register
2802
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2803
      if (phy_data[0] !== 1'b0)
2804
      begin
2805
        test_fail("Link FAIL bit was set in the MII status register");
2806
        fail = fail + 1;
2807
      end
2808
    end
2809
    begin
2810
    // Completely check second scan
2811
      #Tp cnt = 0;
2812
      // wait for serial bus to become active - second scan
2813
      wait(Mdio_IO !== 1'bz);
2814
      // count transfer length
2815
      while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i == 0)) || ((cnt == 15) && (i == 1)) )
2816
      begin
2817
        @(posedge Mdc_O);
2818
        #Tp cnt = cnt + 1;
2819
      end
2820
      // check transfer length
2821
      if (i) // without preamble
2822
      begin
2823
        if (cnt != 33) // at this value Mdio_IO is HIGH Z
2824
        begin
2825
          test_fail("Second scan request did not proceed correctly");
2826
          fail = fail + 1;
2827
        end
2828
      end
2829
      else // with preamble
2830
      begin
2831
        if (cnt != 65) // at this value Mdio_IO is HIGH Z
2832
        begin
2833
          test_fail("Second scan request did not proceed correctly");
2834
          fail = fail + 1;
2835
        end
2836
      end
2837
    end
2838
    join
2839
    // check third to fifth scans
2840
    for (i3 = 0; i3 <= 2; i3 = i3 + 1)
2841
    begin
2842
      fork
2843
      begin
2844
        repeat(2) @(posedge Mdc_O);
2845
        // read data from PHY status register
2846
        #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2847
        if (phy_data !== tmp_data)
2848
        begin
2849
          test_fail("Data was not correctly scaned from status register");
2850
          fail = fail + 1;
2851
        end
2852
        // read data from MII status register
2853
        #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2854
        if (phy_data[0] !== 1'b0)
2855
        begin
2856
          test_fail("Link FAIL bit was set in the MII status register");
2857
          fail = fail + 1;
2858
        end
2859
        if (i3 == 2) // after fourth scan read
2860
        begin
2861
          @(posedge Mdc_O);
2862
          // change saved data
2863
          #Tp tmp_data = tmp_data & 16'hFFFB; // put bit 3 to ZERO
2864
          // set link down
2865
          #Tp eth_phy.link_up_down(0);
2866
        end
2867
      end
2868
      begin
2869
      // Completely check scans
2870
        #Tp cnt = 0;
2871
        // wait for serial bus to become active - second scan
2872
        wait(Mdio_IO !== 1'bz);
2873
        // count transfer length
2874
        while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i == 0)) || ((cnt == 15) && (i == 1)) )
2875
        begin
2876
          @(posedge Mdc_O);
2877
          #Tp cnt = cnt + 1;
2878
        end
2879
        // check transfer length
2880
        if (i) // without preamble
2881
        begin
2882
          if (cnt != 33) // at this value Mdio_IO is HIGH Z
2883
          begin
2884
            test_fail("Fifth scan request did not proceed correctly");
2885
            fail = fail + 1;
2886
          end
2887
        end
2888
        else // with preamble
2889
        begin
2890
          if (cnt != 65) // at this value Mdio_IO is HIGH Z
2891
          begin
2892
            test_fail("Fifth scan request did not proceed correctly");
2893
            fail = fail + 1;
2894
          end
2895
        end
2896
      end
2897
      join
2898
    end
2899
 
2900
    fork
2901
    begin
2902
      repeat(2) @(posedge Mdc_O);
2903
      // read data from PHY status register
2904
      #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2905
      if (phy_data !== tmp_data)
2906
      begin
2907
        test_fail("Data was not correctly scaned from status register");
2908
        fail = fail + 1;
2909
      end
2910
      // read data from MII status register
2911
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2912
      if (phy_data[0] === 1'b0)
2913
      begin
2914
        test_fail("Link FAIL bit was not set in the MII status register");
2915
        fail = fail + 1;
2916
      end
2917
      // wait to see if data stayed latched
2918
      repeat(4) @(posedge Mdc_O);
2919
      // read data from PHY status register
2920
      #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2921
      if (phy_data !== tmp_data)
2922
      begin
2923
        test_fail("Data was not latched correctly in status register");
2924
        fail = fail + 1;
2925
      end
2926
      // read data from MII status register
2927
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2928
      if (phy_data[0] === 1'b0)
2929
      begin
2930
        test_fail("Link FAIL bit was not set in the MII status register");
2931
        fail = fail + 1;
2932
      end
2933
      // change saved data
2934
      #Tp tmp_data = tmp_data | 16'h0004; // put bit 2 to ONE
2935
      // set link up
2936
      #Tp eth_phy.link_up_down(1);
2937
    end
2938
    begin
2939
    // Wait for sixth scan
2940
      // wait for serial bus to become active - sixth scan
2941
      wait(Mdio_IO !== 1'bz);
2942
      // wait for serial bus to become inactive - turn-around cycle in sixth scan
2943
      wait(Mdio_IO === 1'bz);
2944
      // wait for serial bus to become active - end of turn-around cycle in sixth scan
2945
      wait(Mdio_IO !== 1'bz);
2946
      // wait for serial bus to become inactive - end of sixth scan
2947
      wait(Mdio_IO === 1'bz);
2948
    end
2949
    join
2950
 
2951
    @(posedge Mdc_O);
2952
    // read data from PHY status register
2953
    #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2954
    if (phy_data !== tmp_data)
2955
    begin
2956
      test_fail("Data was not correctly scaned from status register");
2957
      fail = fail + 1;
2958
    end
2959
    // read data from MII status register
2960
    #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2961
    if (phy_data[0] !== 1'b0)
2962
    begin
2963
      test_fail("Link FAIL bit was set in the MII status register");
2964
      fail = fail + 1;
2965
    end
2966
    // wait to see if data stayed latched
2967
    repeat(4) @(posedge Mdc_O);
2968
    // read data from PHY status register
2969
    #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2970
    if (phy_data !== tmp_data)
2971
    begin
2972
      test_fail("Data was not correctly scaned from status register");
2973
      fail = fail + 1;
2974
    end
2975
    // read data from MII status register
2976
    #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2977
    if (phy_data[0] !== 1'b0)
2978
    begin
2979
      test_fail("Link FAIL bit was set in the MII status register");
2980
      fail = fail + 1;
2981
    end
2982
 
2983
    // STOP SCAN
2984
    #Tp mii_scan_finish; // finish scan operation
2985
    #Tp check_mii_busy; // wait for scan to finish
2986
  end
2987
  // set PHY to normal mode
2988
  #Tp eth_phy.preamble_suppresed(0);
2989
  // MII mode register
2990
  wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2991
  if(fail == 0)
2992
    test_ok;
2993
  else
2994
    fail = 0;
2995
end
2996
 
2997
 
2998
if ((start_task <= 15) && (end_task >= 15))
2999
begin
3000
  // TEST SCAN STATUS FROM PHY WITH SLIDING LINK-FAIL BIT ( WITH AND WITHOUT PREAMBLE )
3001
  test_name   = "TEST SCAN STATUS FROM PHY WITH SLIDING LINK-FAIL BIT ( WITH AND WITHOUT PREAMBLE )";
3002
  `TIME; $display("  TEST SCAN STATUS FROM PHY WITH SLIDING LINK-FAIL BIT ( WITH AND WITHOUT PREAMBLE )");
3003
 
3004
  // set address
3005
  reg_addr = 5'h1; // status register
3006
  phy_addr = 5'h1; // correct PHY address
3007
 
3008
  // read request
3009
  #Tp mii_read_req(phy_addr, reg_addr);
3010
  check_mii_busy; // wait for read to finish
3011
  // read data from PHY status register - remember LINK-UP status
3012
  #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3013
 
3014
  for (i2 = 0; i2 <= 1; i2 = i2 + 1) // choose preamble or not
3015
  begin
3016
    #Tp eth_phy.preamble_suppresed(i2);
3017
    // MII mode register
3018
    #Tp wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i2, 8'h0}), 4'hF, 1, wbm_init_waits,
3019
                  wbm_subseq_waits);
3020
    if (i2)
3021
    begin
3022
      // change saved data when preamble is suppressed
3023
      #Tp tmp_data = tmp_data | 16'h0040; // put bit 6 to ONE
3024
    end
3025
 
3026
    i = 0;
3027
    while (i < 80) // delay for sliding of LinkFail bit
3028
    begin
3029
      // first there are two scans
3030
      #Tp cnt = 0;
3031
      // scan request
3032
      #Tp mii_scan_req(phy_addr, reg_addr);
3033
      #Tp check_mii_scan_valid; // wait for scan to make first data valid
3034
 
3035
      // check second scan
3036
      fork
3037
      begin
3038
        repeat(4) @(posedge Mdc_O);
3039
        // read data from PHY status register
3040
        #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3041
        if (phy_data !== tmp_data)
3042
        begin
3043
          test_fail("Second data was not correctly scaned from status register");
3044
          fail = fail + 1;
3045
        end
3046
        // read data from MII status register
3047
        #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3048
        if (phy_data[0] !== 1'b0)
3049
        begin
3050
          test_fail("Link FAIL bit was set in the MII status register");
3051
          fail = fail + 1;
3052
        end
3053
      end
3054
      begin
3055
      // Completely check scan
3056
        #Tp cnt = 0;
3057
        // wait for serial bus to become active - second scan
3058
        wait(Mdio_IO !== 1'bz);
3059
        // count transfer length
3060
        while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3061
        begin
3062
          @(posedge Mdc_O);
3063
          #Tp cnt = cnt + 1;
3064
        end
3065
        // check transfer length
3066
        if (i2) // without preamble
3067
        begin
3068
          if (cnt != 33) // at this value Mdio_IO is HIGH Z
3069
          begin
3070
            test_fail("Second scan request did not proceed correctly");
3071
            fail = fail + 1;
3072
          end
3073
        end
3074
        else // with preamble
3075
        begin
3076
          if (cnt != 65) // at this value Mdio_IO is HIGH Z
3077
          begin
3078
            test_fail("Second scan request did not proceed correctly");
3079
            fail = fail + 1;
3080
          end
3081
        end
3082
      end
3083
      join
3084
      // reset counter 
3085
      #Tp cnt = 0;
3086
      // SLIDING LINK DOWN and CHECK
3087
      fork
3088
        begin
3089
        // set link down
3090
          repeat(i) @(posedge Mdc_O);
3091
          // set link down
3092
          #Tp eth_phy.link_up_down(0);
3093
        end
3094
        begin
3095
        // check data in MII registers after each scan in this fork statement
3096
          if (i2) // without preamble
3097
            wait (cnt == 32);
3098
          else // with preamble
3099
            wait (cnt == 64);
3100
          repeat(3) @(posedge Mdc_O);
3101
          // read data from PHY status register
3102
          #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3103
          if ( ((i < 49) && !i2) || ((i < 17) && i2) )
3104
          begin
3105
            if (phy_data !== (tmp_data & 16'hFFFB)) // bit 3 is ZERO
3106
            begin
3107
              test_fail("Third data was not correctly scaned from status register");
3108
              fail = fail + 1;
3109
            end
3110
          end
3111
          else
3112
          begin
3113
            if (phy_data !== tmp_data)
3114
            begin
3115
              test_fail("Third data was not correctly scaned from status register");
3116
              fail = fail + 1;
3117
            end
3118
          end
3119
          // read data from MII status register
3120
          #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3121
          if ( ((i < 49) && !i2) || ((i < 17) && i2) )
3122
          begin
3123
            if (phy_data[0] === 1'b0)
3124
            begin
3125
              test_fail("Link FAIL bit was not set in the MII status register");
3126
              fail = fail + 1;
3127
            end
3128
          end
3129
          else
3130
          begin
3131
            if (phy_data[0] !== 1'b0)
3132
            begin
3133
              test_fail("Link FAIL bit was set in the MII status register");
3134
              fail = fail + 1;
3135
            end
3136
          end
3137
        end
3138
        begin
3139
        // check length
3140
          for (i3 = 0; i3 <= 1; i3 = i3 + 1) // two scans
3141
          begin
3142
            #Tp cnt = 0;
3143
            // wait for serial bus to become active if there is more than one scan
3144
            wait(Mdio_IO !== 1'bz);
3145
            // count transfer length
3146
            while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3147
            begin
3148
              @(posedge Mdc_O);
3149
              #Tp cnt = cnt + 1;
3150
            end
3151
            // check transfer length
3152
            if (i2) // without preamble
3153
            begin
3154
              if (cnt != 33) // at this value Mdio_IO is HIGH Z
3155
              begin
3156
                test_fail("3. or 4. scan request did not proceed correctly, while SCAN STOP was written");
3157
                fail = fail + 1;
3158
              end
3159
            end
3160
            else // with preamble
3161
            begin
3162
              if (cnt != 65) // at this value Mdio_IO is HIGH Z
3163
              begin
3164
                test_fail("3. or 4. scan request did not proceed correctly, while SCAN STOP was written");
3165
                fail = fail + 1;
3166
              end
3167
            end
3168
          end
3169
        end
3170
      join
3171
      // reset counter
3172
      #Tp cnt = 0;
3173
      // check fifth scan and data from fourth scan
3174
      fork
3175
      begin
3176
        repeat(2) @(posedge Mdc_O);
3177
        // read data from PHY status register
3178
        #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3179
        if (phy_data !== (tmp_data & 16'hFFFB)) // bit 3 is ZERO
3180
        begin
3181
          test_fail("4. data was not correctly scaned from status register");
3182
          fail = fail + 1;
3183
        end
3184
        // read data from MII status register
3185
        #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3186
        if (phy_data[0] === 1'b0)
3187
        begin
3188
          test_fail("Link FAIL bit was not set in the MII status register");
3189
          fail = fail + 1;
3190
        end
3191
      end
3192
      begin
3193
      // Completely check intermediate scan
3194
        #Tp cnt = 0;
3195
        // wait for serial bus to become active - second scan
3196
        wait(Mdio_IO !== 1'bz);
3197
        // count transfer length
3198
        while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3199
        begin
3200
          @(posedge Mdc_O);
3201
          #Tp cnt = cnt + 1;
3202
        end
3203
        // check transfer length
3204
        if (i2) // without preamble
3205
        begin
3206
          if (cnt != 33) // at this value Mdio_IO is HIGH Z
3207
          begin
3208
            test_fail("Fifth scan request did not proceed correctly");
3209
            fail = fail + 1;
3210
          end
3211
        end
3212
        else // with preamble
3213
        begin
3214
          if (cnt != 65) // at this value Mdio_IO is HIGH Z
3215
          begin
3216
            test_fail("Fifth scan request did not proceed correctly");
3217
            fail = fail + 1;
3218
          end
3219
        end
3220
      end
3221
      join
3222
      // reset counter 
3223
      #Tp cnt = 0;
3224
      // SLIDING LINK UP and CHECK
3225
      fork
3226
        begin
3227
        // set link up
3228
          repeat(i) @(posedge Mdc_O);
3229
          // set link up
3230
          #Tp eth_phy.link_up_down(1);
3231
        end
3232
        begin
3233
        // check data in MII registers after each scan in this fork statement
3234
          repeat(2) @(posedge Mdc_O);
3235
          if (i2) // without preamble
3236
            wait (cnt == 32);
3237
          else // with preamble
3238
            wait (cnt == 64);
3239
          repeat(3) @(posedge Mdc_O);
3240
          // read data from PHY status register
3241
          #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3242
          if ( ((i < 49) && !i2) || ((i < 17) && i2) )
3243
          begin
3244
            if (phy_data !== tmp_data)
3245
            begin
3246
              test_fail("6. data was not correctly scaned from status register");
3247
              fail = fail + 1;
3248
            end
3249
          end
3250
          else
3251
          begin
3252
            if (phy_data !== (tmp_data & 16'hFFFB)) // bit 3 is ZERO
3253
            begin
3254
              test_fail("6. data was not correctly scaned from status register");
3255
              fail = fail + 1;
3256
            end
3257
          end
3258
          // read data from MII status register
3259
          #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3260
          if ( ((i < 49) && !i2) || ((i < 17) && i2) )
3261
          begin
3262
            if (phy_data[0] !== 1'b0)
3263
            begin
3264
              test_fail("Link FAIL bit was set in the MII status register");
3265
              fail = fail + 1;
3266
            end
3267
          end
3268
          else
3269
          begin
3270
            if (phy_data[0] === 1'b0)
3271
            begin
3272
              test_fail("Link FAIL bit was not set in the MII status register");
3273
              fail = fail + 1;
3274
            end
3275
          end
3276
        end
3277
        begin
3278
        // check length
3279
          for (i3 = 0; i3 <= 1; i3 = i3 + 1) // two scans
3280
          begin
3281
            #Tp cnt = 0;
3282
            // wait for serial bus to become active if there is more than one scan
3283
            wait(Mdio_IO !== 1'bz);
3284
            // count transfer length
3285
            while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3286
            begin
3287
              @(posedge Mdc_O);
3288
              #Tp cnt = cnt + 1;
3289
            end
3290
            // check transfer length
3291
            if (i2) // without preamble
3292
            begin
3293
              if (cnt != 33) // at this value Mdio_IO is HIGH Z
3294
              begin
3295
                test_fail("Scan request did not proceed correctly, while SCAN STOP was written");
3296
                fail = fail + 1;
3297
              end
3298
            end
3299
            else // with preamble
3300
            begin
3301
              if (cnt != 65) // at this value Mdio_IO is HIGH Z
3302
              begin
3303
                test_fail("Scan request did not proceed correctly, while SCAN STOP was written");
3304
                fail = fail + 1;
3305
              end
3306
            end
3307
          end
3308
        end
3309
      join
3310
      // check last scan 
3311
      repeat(4) @(posedge Mdc_O);
3312
      // read data from PHY status register
3313
      #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3314
      if (phy_data !== tmp_data)
3315
      begin
3316
        test_fail("7. data was not correctly scaned from status register");
3317
        fail = fail + 1;
3318
      end
3319
      // read data from MII status register
3320
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3321
      if (phy_data[0] !== 1'b0)
3322
      begin
3323
        test_fail("Link FAIL bit was set in the MII status register");
3324
        fail = fail + 1;
3325
      end
3326
 
3327
      #Tp mii_scan_finish; // finish scan operation
3328
      #Tp check_mii_busy; // wait for scan to finish
3329
      #Tp;
3330
      // set delay of writing the command
3331
      if (i2) // without preamble
3332
      begin
3333
        case(i)
3334
          0,  1,  2,  3,  4:  i = i + 1;
3335
          13, 14, 15, 16, 17,
3336
          18, 19, 20, 21, 22,
3337
          23, 24, 25, 26, 27,
3338
          28, 29, 30, 31, 32,
3339
          33, 34, 35:         i = i + 1;
3340
          36:                 i = 80;
3341
          default:            i = 13;
3342
        endcase
3343
      end
3344
      else // with preamble
3345
      begin
3346
        case(i)
3347
          0,  1,  2,  3,  4:  i = i + 1;
3348
          45, 46, 47, 48, 49,
3349
          50, 51, 52, 53, 54,
3350
          55, 56, 57, 58, 59,
3351
          60, 61, 62, 63, 64,
3352
          65, 66, 67:         i = i + 1;
3353
          68:                 i = 80;
3354
          default:            i = 45;
3355
        endcase
3356
      end
3357
      @(posedge wb_clk);
3358
      #Tp;
3359
    end
3360
  end
3361
  // set PHY to normal mode
3362
  #Tp eth_phy.preamble_suppresed(0);
3363
  // MII mode register
3364
  wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3365
  if(fail == 0)
3366
    test_ok;
3367
  else
3368
    fail = 0;
3369
end
3370
 
3371
 
3372
if ((start_task <= 16) && (end_task >= 16))
3373
begin
3374
  // TEST SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER SCAN REQUEST ( WITH AND WITHOUT PREAMBLE )
3375
  test_name = "TEST SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER SCAN REQUEST ( WITH AND WITHOUT PREAMBLE )";
3376
  `TIME;
3377
  $display("  TEST SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER SCAN REQUEST ( WITH AND WITHOUT PREAMBLE )");
3378
 
3379
  for (i2 = 0; i2 <= 1; i2 = i2 + 1) // choose preamble or not
3380
  begin
3381
    #Tp eth_phy.preamble_suppresed(i2);
3382
    // MII mode register
3383
    wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i2, 8'h0}), 4'hF, 1, wbm_init_waits,
3384
              wbm_subseq_waits);
3385
    i = 0;
3386
    cnt = 0;
3387
    while (i < 80) // delay for sliding of writing a STOP SCAN command
3388
    begin
3389
      for (i3 = 0; i3 <= 1; i3 = i3 + 1) // choose read or write after scan will be finished
3390
      begin
3391
        // set address
3392
        reg_addr = 5'h0; // control register
3393
        phy_addr = 5'h1; // correct PHY address
3394
        cnt = 0;
3395
        // scan request
3396
        #Tp mii_scan_req(phy_addr, reg_addr);
3397
        fork
3398
          begin
3399
            repeat(i) @(posedge Mdc_O);
3400
            // write command 0x0 into MII command register
3401
            // MII command written while scan in progress
3402
            wbm_write(`ETH_MIICOMMAND, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3403
            @(posedge wb_clk);
3404
            #Tp check_mii_busy; // wait for scan to finish
3405
            @(posedge wb_clk);
3406
            disable check;
3407
          end
3408
          begin: check
3409
            // wait for serial bus to become active
3410
            wait(Mdio_IO !== 1'bz);
3411
            // count transfer length
3412
            while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3413
            begin
3414
              @(posedge Mdc_O);
3415
              #Tp cnt = cnt + 1;
3416
            end
3417
            // check transfer length
3418
            if (i2) // without preamble
3419
            begin
3420
              if (cnt != 33) // at this value Mdio_IO is HIGH Z
3421
              begin
3422
                test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3423
                fail = fail + 1;
3424
              end
3425
            end
3426
            else // with preamble
3427
            begin
3428
              if (cnt != 65) // at this value Mdio_IO is HIGH Z
3429
              begin
3430
                test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3431
                fail = fail + 1;
3432
              end
3433
            end
3434
            cnt = 0;
3435
            // wait for serial bus to become active if there is more than one scan
3436
            wait(Mdio_IO !== 1'bz);
3437
            // count transfer length
3438
            while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3439
            begin
3440
              @(posedge Mdc_O);
3441
              #Tp cnt = cnt + 1;
3442
            end
3443
            // check transfer length
3444
            if (i2) // without preamble
3445
            begin
3446
              if (cnt != 33) // at this value Mdio_IO is HIGH Z
3447
              begin
3448
                test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3449
                fail = fail + 1;
3450
              end
3451
            end
3452
            else // with preamble
3453
            begin
3454
              if (cnt != 65) // at this value Mdio_IO is HIGH Z
3455
              begin
3456
                test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3457
                fail = fail + 1;
3458
              end
3459
            end
3460
          end
3461
        join
3462
        // check the BUSY signal to see if the bus is still IDLE
3463
        for (i1 = 0; i1 < 8; i1 = i1 + 1)
3464
          check_mii_busy; // wait for bus to become idle
3465 116 mohor
 
3466 169 mohor
        // try normal write or read after scan was finished
3467
        phy_data = {8'h7D, (i[7:0] + 1)};
3468
        cnt = 0;
3469
        if (i3 == 0) // write after scan
3470
        begin
3471
          // write request
3472
          #Tp mii_write_req(phy_addr, reg_addr, phy_data);
3473
          // wait for serial bus to become active
3474
          wait(Mdio_IO !== 1'bz);
3475
          // count transfer length
3476
          while(Mdio_IO !== 1'bz)
3477
          begin
3478
            @(posedge Mdc_O);
3479
            #Tp cnt = cnt + 1;
3480
          end
3481
          @(posedge Mdc_O);
3482
          // read request
3483
          #Tp mii_read_req(phy_addr, reg_addr);
3484
          check_mii_busy; // wait for read to finish
3485
          // read and check data
3486
          #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3487
          if (phy_data !== tmp_data)
3488
          begin
3489
            test_fail("Data was not correctly written into OR read from PHY register - control register");
3490
            fail = fail + 1;
3491
          end
3492
        end
3493
        else // read after scan
3494
        begin
3495
          // read request
3496
          #Tp mii_read_req(phy_addr, reg_addr);
3497
          // wait for serial bus to become active
3498
          wait(Mdio_IO !== 1'bz);
3499
          // count transfer length
3500
          while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3501
          begin
3502
            @(posedge Mdc_O);
3503
            #Tp cnt = cnt + 1;
3504
          end
3505
          @(posedge Mdc_O);
3506
          check_mii_busy; // wait for read to finish
3507
          // read and check data
3508
          #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3509
          if (phy_data !== tmp_data)
3510
          begin
3511
            test_fail("Data was not correctly written into OR read from PHY register - control register");
3512
            fail = fail + 1;
3513
          end
3514
        end
3515
        // check if transfer was a proper length
3516
        if (i2) // without preamble
3517
        begin
3518
          if (cnt != 33) // at this value Mdio_IO is HIGH Z
3519
          begin
3520
            test_fail("New request did not proceed correctly, after scan request");
3521
            fail = fail + 1;
3522
          end
3523
        end
3524
        else // with preamble
3525
        begin
3526
          if (cnt != 65) // at this value Mdio_IO is HIGH Z
3527
          begin
3528
            test_fail("New request did not proceed correctly, after scan request");
3529
            fail = fail + 1;
3530
          end
3531
        end
3532
      end
3533
      #Tp;
3534
      // set delay of writing the command
3535
      if (i2) // without preamble
3536
      begin
3537
        case(i)
3538
          0, 1:               i = i + 1;
3539
          18, 19, 20, 21, 22,
3540
          23, 24, 25, 26, 27,
3541
          28, 29, 30, 31, 32,
3542
          33, 34, 35:         i = i + 1;
3543
          36:                 i = 80;
3544
          default:            i = 18;
3545
        endcase
3546
      end
3547
      else // with preamble
3548
      begin
3549
        case(i)
3550
          0, 1:               i = i + 1;
3551
          50, 51, 52, 53, 54,
3552
          55, 56, 57, 58, 59,
3553
          60, 61, 62, 63, 64,
3554
          65, 66, 67:         i = i + 1;
3555
          68:                 i = 80;
3556
          default:            i = 50;
3557
        endcase
3558
      end
3559
      @(posedge wb_clk);
3560
    end
3561
  end
3562
  // set PHY to normal mode
3563
  #Tp eth_phy.preamble_suppresed(0);
3564
  // MII mode register
3565
  wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3566
  if(fail == 0)
3567
    test_ok;
3568
  else
3569
    fail = 0;
3570
end
3571
 
3572
 
3573
if ((start_task <= 17) && (end_task >= 17))
3574
begin
3575
  // TEST SLIDING STOP SCAN COMMAND AFTER 2. SCAN ( WITH AND WITHOUT PREAMBLE )
3576
  test_name = "TEST SLIDING STOP SCAN COMMAND AFTER 2. SCAN ( WITH AND WITHOUT PREAMBLE )";
3577
  `TIME; $display("  TEST SLIDING STOP SCAN COMMAND AFTER 2. SCAN ( WITH AND WITHOUT PREAMBLE )");
3578
 
3579
  for (i2 = 0; i2 <= 1; i2 = i2 + 1) // choose preamble or not
3580 116 mohor
  begin
3581 169 mohor
    #Tp eth_phy.preamble_suppresed(i2);
3582
    // MII mode register
3583
    wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i2, 8'h0}), 4'hF, 1, wbm_init_waits,
3584
              wbm_subseq_waits);
3585 116 mohor
 
3586 169 mohor
    i = 0;
3587
    cnt = 0;
3588
    while (i < 80) // delay for sliding of writing a STOP SCAN command
3589
    begin
3590
      for (i3 = 0; i3 <= 1; i3 = i3 + 1) // choose read or write after scan will be finished
3591
      begin
3592
        // first there are two scans
3593
        // set address
3594
        reg_addr = 5'h0; // control register
3595
        phy_addr = 5'h1; // correct PHY address
3596
        cnt = 0;
3597
        // scan request
3598
        #Tp mii_scan_req(phy_addr, reg_addr);
3599
        // wait and check first 2 scans
3600
        begin
3601
          // wait for serial bus to become active
3602
          wait(Mdio_IO !== 1'bz);
3603
          // count transfer length
3604
          while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3605
          begin
3606
            @(posedge Mdc_O);
3607
            #Tp cnt = cnt + 1;
3608
          end
3609
          // check transfer length
3610
          if (i2) // without preamble
3611
          begin
3612
            if (cnt != 33) // at this value Mdio_IO is HIGH Z
3613
            begin
3614
              test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3615
              fail = fail + 1;
3616
            end
3617
          end
3618
          else // with preamble
3619
          begin
3620
            if (cnt != 65) // at this value Mdio_IO is HIGH Z
3621
            begin
3622
              test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3623
              fail = fail + 1;
3624
            end
3625
          end
3626
          cnt = 0;
3627
          // wait for serial bus to become active if there is more than one scan
3628
          wait(Mdio_IO !== 1'bz);
3629
          // count transfer length
3630
          while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3631
          begin
3632
            @(posedge Mdc_O);
3633
            #Tp cnt = cnt + 1;
3634
          end
3635
          // check transfer length
3636
          if (i2) // without preamble
3637
          begin
3638
            if (cnt != 33) // at this value Mdio_IO is HIGH Z
3639
            begin
3640
              test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3641
              fail = fail + 1;
3642
            end
3643
          end
3644
          else // with preamble
3645
          begin
3646
            if (cnt != 65) // at this value Mdio_IO is HIGH Z
3647
            begin
3648
              test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3649
              fail = fail + 1;
3650
            end
3651
          end
3652
        end
3653
 
3654
        // reset counter 
3655
        cnt = 0;
3656
        fork
3657
          begin
3658
            repeat(i) @(posedge Mdc_O);
3659
            // write command 0x0 into MII command register
3660
            // MII command written while scan in progress
3661
            wbm_write(`ETH_MIICOMMAND, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3662
            @(posedge wb_clk);
3663
            #Tp check_mii_busy; // wait for scan to finish
3664
            @(posedge wb_clk);
3665
            disable check_3;
3666
          end
3667
          begin: check_3
3668
            // wait for serial bus to become active
3669
            wait(Mdio_IO !== 1'bz);
3670
            // count transfer length
3671
            while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3672
            begin
3673
              @(posedge Mdc_O);
3674
              #Tp cnt = cnt + 1;
3675
            end
3676
            // check transfer length
3677
            if (i2) // without preamble
3678
            begin
3679
              if (cnt != 33) // at this value Mdio_IO is HIGH Z
3680
              begin
3681
                test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3682
                fail = fail + 1;
3683
              end
3684
            end
3685
            else // with preamble
3686
            begin
3687
              if (cnt != 65) // at this value Mdio_IO is HIGH Z
3688
              begin
3689
                test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3690
                fail = fail + 1;
3691
              end
3692
            end
3693
            cnt = 0;
3694
            // wait for serial bus to become active if there is more than one scan
3695
            wait(Mdio_IO !== 1'bz);
3696
            // count transfer length
3697
            while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3698
            begin
3699
              @(posedge Mdc_O);
3700
              #Tp cnt = cnt + 1;
3701
            end
3702
            // check transfer length
3703
            if (i2) // without preamble
3704
            begin
3705
              if (cnt != 33) // at this value Mdio_IO is HIGH Z
3706
              begin
3707
                test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3708
                fail = fail + 1;
3709
              end
3710
            end
3711
            else // with preamble
3712
            begin
3713
              if (cnt != 65) // at this value Mdio_IO is HIGH Z
3714
              begin
3715
                test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3716
                fail = fail + 1;
3717
              end
3718
            end
3719
          end
3720
        join
3721
        // check the BUSY signal to see if the bus is still IDLE
3722
        for (i1 = 0; i1 < 8; i1 = i1 + 1)
3723
          check_mii_busy; // wait for bus to become idle
3724
 
3725
        // try normal write or read after scan was finished
3726
        phy_data = {8'h7D, (i[7:0] + 1)};
3727
        cnt = 0;
3728
        if (i3 == 0) // write after scan
3729
        begin
3730
          // write request
3731
          #Tp mii_write_req(phy_addr, reg_addr, phy_data);
3732
          // wait for serial bus to become active
3733
          wait(Mdio_IO !== 1'bz);
3734
          // count transfer length
3735
          while(Mdio_IO !== 1'bz)
3736
          begin
3737
            @(posedge Mdc_O);
3738
            #Tp cnt = cnt + 1;
3739
          end
3740
          @(posedge Mdc_O);
3741
          // read request
3742
          #Tp mii_read_req(phy_addr, reg_addr);
3743
          check_mii_busy; // wait for read to finish
3744
          // read and check data
3745
          #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3746
          if (phy_data !== tmp_data)
3747
          begin
3748
            test_fail("Data was not correctly written into OR read from PHY register - control register");
3749
            fail = fail + 1;
3750
          end
3751
        end
3752
        else // read after scan
3753
        begin
3754
          // read request
3755
          #Tp mii_read_req(phy_addr, reg_addr);
3756
          // wait for serial bus to become active
3757
          wait(Mdio_IO !== 1'bz);
3758
          // count transfer length
3759
          while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3760
          begin
3761
            @(posedge Mdc_O);
3762
            #Tp cnt = cnt + 1;
3763
          end
3764
          @(posedge Mdc_O);
3765
          check_mii_busy; // wait for read to finish
3766
          // read and check data
3767
          #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3768
          if (phy_data !== tmp_data)
3769
          begin
3770
            test_fail("Data was not correctly written into OR read from PHY register - control register");
3771
            fail = fail + 1;
3772
          end
3773
        end
3774
        // check if transfer was a proper length
3775
        if (i2) // without preamble
3776
        begin
3777
          if (cnt != 33) // at this value Mdio_IO is HIGH Z
3778
          begin
3779
            test_fail("New request did not proceed correctly, after scan request");
3780
            fail = fail + 1;
3781
          end
3782
        end
3783
        else // with preamble
3784
        begin
3785
          if (cnt != 65) // at this value Mdio_IO is HIGH Z
3786
          begin
3787
            test_fail("New request did not proceed correctly, after scan request");
3788
            fail = fail + 1;
3789
          end
3790
        end
3791 116 mohor
      end
3792 169 mohor
      #Tp;
3793
      // set delay of writing the command
3794
      if (i2) // without preamble
3795
      begin
3796
        case(i)
3797
          0, 1:               i = i + 1;
3798
          18, 19, 20, 21, 22,
3799
          23, 24, 25, 26, 27,
3800
          28, 29, 30, 31, 32,
3801
          33, 34, 35:         i = i + 1;
3802
          36:                 i = 80;
3803
          default:            i = 18;
3804
        endcase
3805
      end
3806
      else // with preamble
3807
      begin
3808
        case(i)
3809
          0, 1:               i = i + 1;
3810
          50, 51, 52, 53, 54,
3811
          55, 56, 57, 58, 59,
3812
          60, 61, 62, 63, 64,
3813
          65, 66, 67:         i = i + 1;
3814
          68:                 i = 80;
3815
          default:            i = 50;
3816
        endcase
3817
      end
3818
      @(posedge wb_clk);
3819 116 mohor
    end
3820 169 mohor
  end
3821
  // set PHY to normal mode
3822
  #Tp eth_phy.preamble_suppresed(0);
3823
  // MII mode register
3824
  wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3825
  if(fail == 0)
3826
    test_ok;
3827
  else
3828
    fail = 0;
3829
end
3830 116 mohor
 
3831 169 mohor
end
3832
endtask // test_mii
3833
 
3834
 
3835
task test_mac_full_duplex_transmit;
3836
  input  [31:0]  start_task;
3837
  input  [31:0]  end_task;
3838
  integer        bit_start_1;
3839
  integer        bit_end_1;
3840
  integer        bit_start_2;
3841
  integer        bit_end_2;
3842
  integer        num_of_reg;
3843
  integer        i_addr;
3844
  integer        i_data;
3845
  integer        i_length;
3846
  integer        tmp_data;
3847
  reg    [31:0]  tx_bd_num;
3848
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_data;
3849
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_tmp_data;
3850
  integer        i;
3851
  integer        i1;
3852
  integer        i2;
3853
  integer        i3;
3854
  integer        fail;
3855
  integer        speed;
3856
  reg    [31:0]  addr;
3857
  reg    [31:0]  data;
3858
  reg    [31:0]  tmp;
3859
  reg    [ 7:0]  st_data;
3860
  reg    [15:0]  max_tmp;
3861
  reg    [15:0]  min_tmp;
3862
begin
3863
// MAC FULL DUPLEX TRANSMIT TEST
3864
test_heading("MAC FULL DUPLEX TRANSMIT TEST");
3865
$display(" ");
3866
$display("MAC FULL DUPLEX TRANSMIT TEST");
3867
fail = 0;
3868
 
3869
// reset MAC registers
3870
hard_reset;
3871
// reset MAC and MII LOGIC with soft reset
3872
reset_mac;
3873
reset_mii;
3874
// set wb slave response
3875
wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
3876
 
3877
  /*
3878
  TASKS for set and control TX buffer descriptors (also send packet - set_tx_bd_ready):
3879
  -------------------------------------------------------------------------------------
3880
  set_tx_bd
3881
    (tx_bd_num_start[6:0], tx_bd_num_end[6:0], len[15:0], irq, pad, crc, txpnt[31:0]);
3882
  set_tx_bd_wrap
3883
    (tx_bd_num_end[6:0]);
3884
  set_tx_bd_ready
3885
    (tx_bd_num_start[6:0], tx_bd_num_end[6:0]);
3886
  check_tx_bd
3887
    (tx_bd_num_start[6:0], tx_bd_status[31:0]);
3888
  clear_tx_bd
3889
    (tx_bd_num_start[6:0], tx_bd_num_end[6:0]);
3890
 
3891
  TASKS for set and control RX buffer descriptors:
3892
  ------------------------------------------------
3893
  set_rx_bd
3894
    (rx_bd_num_strat[6:0], rx_bd_num_end[6:0], irq, rxpnt[31:0]);
3895
  set_rx_bd_wrap
3896
    (rx_bd_num_end[6:0]);
3897
  set_rx_bd_empty
3898
    (rx_bd_num_strat[6:0], rx_bd_num_end[6:0]);
3899
  check_rx_bd
3900
    (rx_bd_num_end[6:0], rx_bd_status);
3901
  clear_rx_bd
3902
    (rx_bd_num_strat[6:0], rx_bd_num_end[6:0]);
3903
 
3904
  TASKS for set and check TX packets:
3905
  -----------------------------------
3906
  set_tx_packet
3907
    (txpnt[31:0], len[15:0], eth_start_data[7:0]);
3908
  check_tx_packet
3909
    (txpnt_wb[31:0], txpnt_phy[31:0], len[15:0], failure[31:0]);
3910
 
3911
  TASKS for set and check RX packets:
3912
  -----------------------------------
3913
  set_rx_packet
3914
    (rxpnt[31:0], len[15:0], plus_nibble, d_addr[47:0], s_addr[47:0], type_len[15:0], start_data[7:0]);
3915
  check_rx_packet
3916
    (rxpnt_phy[31:0], rxpnt_wb[31:0], len[15:0], plus_nibble, successful_nibble, failure[31:0]);
3917
 
3918
  TASKS for append and check CRC to/of TX packet:
3919
  -----------------------------------------------
3920
  append_tx_crc
3921
    (txpnt_wb[31:0], len[15:0], negated_crc);
3922
  check_tx_crc
3923
    (txpnt_phy[31:0], len[15:0], negated_crc, failure[31:0]);
3924
 
3925
  TASK for append CRC to RX packet (CRC is checked together with check_rx_packet):
3926
  --------------------------------------------------------------------------------
3927
  append_rx_crc
3928
    (rxpnt_phy[31:0], len[15:0], plus_nibble, negated_crc);
3929
  */
3930
 
3931
 
3932
if ((start_task <= 0) && (end_task >= 0))
3933
begin
3934
  // TEST NO TRANSMIT WHEN ALL BUFFERS ARE RX ( 10Mbps )
3935
  test_name   = "TEST NO TRANSMIT WHEN ALL BUFFERS ARE RX ( 10Mbps )";
3936
  `TIME; $display("  TEST NO TRANSMIT WHEN ALL BUFFERS ARE RX ( 10Mbps )");
3937
 
3938
  // unmask interrupts
3939
  wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXF | `ETH_INT_RXE | `ETH_INT_BUSY |
3940
                           `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3941
  // set all buffer descriptors to RX - must be set before TX enable
3942
  wbm_write(`ETH_TX_BD_NUM, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3943
  // enable TX, set full-duplex mode, padding and CRC appending
3944
  wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
3945
            4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3946
 
3947
  // write to phy's control register for 10Mbps
3948
  #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
3949
  #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
3950
  speed = 10;
3951
 
3952
  i = 0;
3953
  while (i < 128)
3954
  begin
3955
    for (i1 = 0; i1 <= i; i1 = i1 + 1)
3956
    begin
3957
      set_tx_packet((`MEMORY_BASE + (i1 * 200)), 100, 0);
3958
      set_tx_bd(i1, i1, 100, 1'b1, 1'b1, 1'b1, (`MEMORY_BASE + (i1 * 200)));
3959 116 mohor
    end
3960 169 mohor
    set_tx_bd_wrap(i);
3961
    fork
3962
      begin
3963
        set_tx_bd_ready(0, i);
3964
        repeat(20) @(negedge mtx_clk);
3965
        #1 disable check_tx_en10;
3966
      end
3967
      begin: check_tx_en10
3968
        wait (MTxEn === 1'b1);
3969
        test_fail("Tramsmit should not start at all");
3970
        fail = fail + 1;
3971
        `TIME; $display("*E Transmit of %d packets should not start at all - active MTxEn", i);
3972
      end
3973
    join
3974
    for (i2 = 0; i2 < 20; i2 = i2 + 1)
3975
    begin
3976
      check_tx_bd(0, tmp);
3977
      #1;
3978
      if (tmp[15] === 1'b0)
3979
      begin
3980
        test_fail("Tramsmit should not start at all");
3981
        fail = fail + 1;
3982
        `TIME; $display("*E Transmit of %d packets should not start at all - ready is 0", i);
3983
      end
3984
      if (tmp[8:0] !== 0)
3985
      begin
3986
        test_fail("Tramsmit should not be finished since it should not start at all");
3987
        fail = fail + 1;
3988
        `TIME; $display("*E Transmit of should not be finished since it should not start at all");
3989
      end
3990
      @(posedge wb_clk);
3991 116 mohor
    end
3992 169 mohor
    wbm_read(`ETH_INT, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3993
    if (tmp[6:0] !== 0)
3994
    begin
3995
      test_fail("Tramsmit should not get INT since it should not start at all");
3996
      fail = fail + 1;
3997
      `TIME; $display("*E Transmit of should not get INT since it should not start at all");
3998
    end
3999
    clear_tx_bd(0, i);
4000
    if ((i < 5) || (i > 124))
4001
      i = i + 1;
4002 116 mohor
    else
4003 169 mohor
      i = i + 120;
4004
  end
4005
  // disable TX
4006
  wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
4007
            4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4008
  if(fail == 0)
4009
    test_ok;
4010
  else
4011
    fail = 0;
4012
end
4013 116 mohor
 
4014
 
4015 169 mohor
if ((start_task <= 1) && (end_task >= 1))
4016
begin
4017
  // TEST NO TRANSMIT WHEN ALL BUFFERS ARE RX ( 100Mbps )
4018
  test_name   = "TEST NO TRANSMIT WHEN ALL BUFFERS ARE RX ( 100Mbps )";
4019
  `TIME; $display("  TEST NO TRANSMIT WHEN ALL BUFFERS ARE RX ( 100Mbps )");
4020
 
4021
  // unmask interrupts
4022
  wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXF | `ETH_INT_RXE | `ETH_INT_BUSY |
4023
                           `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4024
  // set all buffer descriptors to RX - must be set before TX enable
4025
  wbm_write(`ETH_TX_BD_NUM, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4026
  // enable TX, set full-duplex mode, padding and CRC appending
4027
  wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
4028
            4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4029
 
4030
  // write to phy's control register for 100Mbps
4031
  #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
4032
  #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
4033
  speed = 100;
4034
 
4035
  i = 0;
4036
  while (i < 128)
4037
  begin
4038
    for (i1 = 0; i1 <= i; i1 = i1 + 1)
4039
    begin
4040
      set_tx_packet((`MEMORY_BASE + (i1 * 200)), 100, 0);
4041
      set_tx_bd(i1, i1, 100, 1'b1, 1'b1, 1'b1, (`MEMORY_BASE + (i1 * 200)));
4042 116 mohor
    end
4043 169 mohor
    set_tx_bd_wrap(i);
4044
    fork
4045
      begin
4046
        set_tx_bd_ready(0, i);
4047
        repeat(20) @(negedge mtx_clk);
4048
        #1 disable check_tx_en100;
4049
      end
4050
      begin: check_tx_en100
4051
        wait (MTxEn === 1'b1);
4052
        test_fail("Tramsmit should not start at all");
4053
        fail = fail + 1;
4054
        `TIME; $display("*E Transmit of %d packets should not start at all - active MTxEn", i);
4055
      end
4056
    join
4057
    for (i2 = 0; i2 < 20; i2 = i2 + 1)
4058
    begin
4059
      check_tx_bd(0, tmp);
4060
      #1;
4061
      if (tmp[15] === 1'b0)
4062
      begin
4063
        test_fail("Tramsmit should not start at all");
4064
        fail = fail + 1;
4065
        `TIME; $display("*E Transmit of %d packets should not start at all - ready is 0", i);
4066
      end
4067
      if (tmp[8:0] !== 0)
4068
      begin
4069
        test_fail("Tramsmit should not be finished since it should not start at all");
4070
        fail = fail + 1;
4071
        `TIME; $display("*E Transmit of should not be finished since it should not start at all");
4072
      end
4073
      @(posedge wb_clk);
4074
    end
4075
    wbm_read(`ETH_INT, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4076
    if (tmp[6:0] !== 0)
4077
    begin
4078
      test_fail("Tramsmit should not get INT since it should not start at all");
4079
      fail = fail + 1;
4080
      `TIME; $display("*E Transmit of should not get INT since it should not start at all");
4081
    end
4082
    clear_tx_bd(0, i);
4083
    if ((i < 5) || (i > 124))
4084
      i = i + 1;
4085
    else
4086
      i = i + 120;
4087
  end
4088
  // disable TX
4089
  wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
4090
            4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4091
  if(fail == 0)
4092
    test_ok;
4093
  else
4094
    fail = 0;
4095
end
4096
 
4097
 
4098
if ((start_task <= 2) && (end_task >= 2))
4099
begin
4100
  // TEST TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT ONE TX BD ( 10Mbps )
4101
  test_name = "TEST TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT ONE TX BD ( 10Mbps )";
4102
  `TIME; $display("  TEST TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT ONE TX BD ( 10Mbps )");
4103
 
4104
  max_tmp = 0;
4105
  min_tmp = 0;
4106
  // unmask interrupts
4107
  wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXF | `ETH_INT_RXE | `ETH_INT_BUSY |
4108
                           `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4109
  // set one TX buffer descriptor - must be set before TX enable
4110
  wbm_write(`ETH_TX_BD_NUM, 32'h1, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4111
  // enable TX, set full-duplex mode, padding and CRC appending
4112
  wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
4113
            4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4114
  // prepare two packets of MAXFL length
4115
  wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4116
  max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
4117
  min_tmp = tmp[31:16];
4118
  st_data = 8'h5A;
4119
  set_tx_packet(`MEMORY_BASE, (max_tmp - 4), st_data); // length without CRC
4120
  st_data = 8'h10;
4121
  set_tx_packet((`MEMORY_BASE + max_tmp), (max_tmp - 4), st_data); // length without CRC
4122
  // check WB INT signal
4123
  if (wb_int !== 1'b0)
4124
  begin
4125
    test_fail("WB INT signal should not be set");
4126
    fail = fail + 1;
4127
  end
4128
 
4129
  // write to phy's control register for 10Mbps
4130
  #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
4131
  #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
4132
  speed = 10;
4133
 
4134
  for (i_length = (min_tmp - 4); i_length <= (max_tmp - 4); i_length = i_length + 1)
4135
  begin
4136
    // choose generating carrier sense and collision
4137
    case (i_length[1:0])
4138
    2'h0:
4139
    begin
4140
 
4141
    end
4142
    2'h1:
4143
    begin
4144
 
4145
    end
4146
    2'h2:
4147
    begin
4148
 
4149
    end
4150
    default: // 2'h3:
4151
    begin
4152
 
4153
    end
4154
    endcase
4155
    // choose WB memory destination address regarding the speed
4156
    if (i_length[0] == 0)
4157
      set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
4158
    else
4159
      set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
4160
    eth_phy.set_tx_mem_addr(max_tmp);
4161
    // set wrap bit
4162
    set_tx_bd_wrap(0);
4163
    set_tx_bd_ready(0, 0);
4164
    #1 check_tx_bd(0, data);
4165
    if (i_length < min_tmp) // just first four
4166
    begin
4167
      while (data[15] === 1)
4168
      begin
4169
        #1 check_tx_bd(0, data);
4170
        @(posedge wb_clk);
4171
      end
4172
    end
4173
    else if (i_length > (max_tmp - 8)) // just last four
4174
    begin
4175
      tmp = 0;
4176
      wait (MTxEn === 1'b1); // start transmit
4177
      while (tmp < (i_length - 20))
4178
      begin
4179
        #1 tmp = tmp + 1;
4180
        @(posedge wb_clk);
4181
      end
4182
      #1 check_tx_bd(0, data);
4183
      while (data[15] === 1)
4184
      begin
4185
        #1 check_tx_bd(0, data);
4186
        @(posedge wb_clk);
4187
      end
4188
    end
4189
    else
4190
    begin
4191
      wait (MTxEn === 1'b1); // start transmit
4192
      wait (MTxEn === 1'b0); // end transmit
4193
      repeat (2) @(posedge mtx_clk);
4194
      repeat (3) @(posedge wb_clk);
4195
    end
4196
    // check length of a PACKET
4197
    if (eth_phy.tx_len != (i_length + 4))
4198
    begin
4199
      test_fail("Wrong length of the packet out from MAC");
4200
      fail = fail + 1;
4201
    end
4202
    // check transmitted TX packet data
4203
    if (i_length[0] == 0)
4204
    begin
4205
      check_tx_packet(`MEMORY_BASE, max_tmp, i_length, tmp);
4206
    end
4207
    else
4208
    begin
4209
      check_tx_packet((`MEMORY_BASE + max_tmp), max_tmp, i_length, tmp);
4210
    end
4211
    if (tmp > 0)
4212
    begin
4213
      test_fail("Wrong data of the transmitted packet");
4214
      fail = fail + 1;
4215
    end
4216
    // check WB INT signal
4217
    if (wb_int !== 1'b1)
4218
    begin
4219
      test_fail("WB INT signal should not be set");
4220
      fail = fail + 1;
4221
    end
4222
    // check transmited TX packet CRC
4223
    check_tx_crc(max_tmp, i_length, 1'b0, tmp); // length without CRC
4224
    if (tmp > 0)
4225
    begin
4226
      test_fail("Wrong CRC of the transmitted packet");
4227
      fail = fail + 1;
4228
    end
4229
    // check TX buffer descriptor of a packet
4230
    check_tx_bd(0, data);
4231 116 mohor
 
4232 169 mohor
 
4233
    // clear TX buffer descriptor
4234
    clear_tx_bd(0, 0);
4235
    // check interrupts
4236
    wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4237
    if ((data & `ETH_INT_TXB) !== 1'b1)
4238
    begin
4239
      `TIME;
4240
      test_fail("Interrupt Transmit Buffer was not set");
4241
      fail = fail + 1;
4242
    end
4243
    if ((data & (~`ETH_INT_TXB)) !== 0)
4244
    begin
4245
      `TIME;
4246
      test_fail("Other interrupts (except Transmit Buffer) were set");
4247
      fail = fail + 1;
4248
    end
4249
    // clear interrupts
4250
    wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4251
    // check WB INT signal
4252
    if (wb_int !== 1'b0)
4253
    begin
4254
      test_fail("WB INT signal should not be set");
4255
      fail = fail + 1;
4256
    end
4257
 
4258
  end
4259
  // disable TX
4260
  wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
4261
            4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4262
  if(fail == 0)
4263
    test_ok;
4264
  else
4265
    fail = 0;
4266
end
4267
 
4268
 
4269
/*
4270
          wbm_write(`ETH_MODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4271
          wbm_read(`ETH_MODER, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4272 116 mohor
 
4273 169 mohor
          wbm_write(32'hd0000000, `ETH_MODER_RXEN  | `ETH_MODER_TXEN | `ETH_MODER_PRO | `ETH_MODER_CRCEN |
4274
                    `ETH_MODER_PAD, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4275
          wbm_read(32'hd0000000, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4276
 
4277
 
4278
 
4279 116 mohor
 
4280 169 mohor
          set_tx_bd(3);
4281
          set_rx_bd(6);
4282
 
4283
          set_tx_packet(16'h34, 8'h1);
4284
          set_tx_packet(16'h34, 8'h11);
4285
          send_tx_packet;
4286
          set_tx_packet(16'h34, 8'h21);
4287
          set_tx_packet(16'h34, 8'h31);
4288
          send_tx_packet;
4289 116 mohor
 
4290
 
4291 169 mohor
          eth_phy.GetDataOnMRxD(100, `BROADCAST_XFR); // LengthRx bytes is comming on MRxD[3:0] signals
4292
          repeat (100) @(posedge mrx_clk);   // Waiting for TxEthMac to finish transmit
4293
 
4294
          eth_phy.GetDataOnMRxD(70, `BROADCAST_XFR); // LengthRx bytes is comming on MRxD[3:0] signals
4295
          repeat (10000) @(posedge wb_clk);   // Waiting for TxEthMac to finish transmit
4296
 
4297
          eth_phy.GetDataOnMRxD(70, `MULTICAST_XFR); // LengthRx bytes is comming on MRxD[3:0] signals
4298
          repeat (10000) @(posedge wb_clk);   // Waiting for TxEthMac to finish transmit
4299
*/
4300
 
4301
 
4302
end
4303
endtask // test_mac_full_duplex_transmit
4304
 
4305
 
4306
//////////////////////////////////////////////////////////////
4307
// WB Behavioral Models Basic tasks
4308
//////////////////////////////////////////////////////////////
4309
 
4310
task wbm_write;
4311
  input  [31:0] address_i;
4312
  input  [((`MAX_BLK_SIZE * 32) - 1):0] data_i;
4313
  input  [3:0]  sel_i;
4314
  input  [31:0] size_i;
4315
  input  [3:0]  init_waits_i;
4316
  input  [3:0]  subseq_waits_i;
4317
 
4318
  reg `WRITE_STIM_TYPE write_data;
4319
  reg `WB_TRANSFER_FLAGS flags;
4320
  reg `WRITE_RETURN_TYPE write_status;
4321
  integer i;
4322
begin
4323
  write_status = 0;
4324
 
4325
  flags                    = 0;
4326
  flags`WB_TRANSFER_SIZE   = size_i;
4327
  flags`INIT_WAITS         = init_waits_i;
4328
  flags`SUBSEQ_WAITS       = subseq_waits_i;
4329
 
4330
  write_data               = 0;
4331
  write_data`WRITE_DATA    = data_i[31:0];
4332
  write_data`WRITE_ADDRESS = address_i;
4333
  write_data`WRITE_SEL     = sel_i;
4334
 
4335
  for (i = 0; i < size_i; i = i + 1)
4336
  begin
4337
    wb_master.blk_write_data[i] = write_data;
4338
    data_i                      = data_i >> 32;
4339
    write_data`WRITE_DATA       = data_i[31:0];
4340
    write_data`WRITE_ADDRESS    = write_data`WRITE_ADDRESS + 4;
4341 116 mohor
  end
4342
 
4343 169 mohor
  wb_master.wb_block_write(flags, write_status);
4344 116 mohor
 
4345 169 mohor
  if (write_status`CYC_ACTUAL_TRANSFER !== size_i)
4346
  begin
4347
    `TIME;
4348
    $display("*E WISHBONE Master was unable to complete the requested write operation to MAC!");
4349
  end
4350
end
4351
endtask // wbm_write
4352 116 mohor
 
4353 169 mohor
task wbm_read;
4354
  input  [31:0] address_i;
4355
  output [((`MAX_BLK_SIZE * 32) - 1):0] data_o;
4356
  input  [3:0]  sel_i;
4357
  input  [31:0] size_i;
4358
  input  [3:0]  init_waits_i;
4359
  input  [3:0]  subseq_waits_i;
4360
 
4361
  reg `READ_RETURN_TYPE read_data;
4362
  reg `WB_TRANSFER_FLAGS flags;
4363
  reg `READ_RETURN_TYPE read_status;
4364
  integer i;
4365
begin
4366
  read_status = 0;
4367
  data_o      = 0;
4368
 
4369
  flags                  = 0;
4370
  flags`WB_TRANSFER_SIZE = size_i;
4371
  flags`INIT_WAITS       = init_waits_i;
4372
  flags`SUBSEQ_WAITS     = subseq_waits_i;
4373
 
4374
  read_data              = 0;
4375
  read_data`READ_ADDRESS = address_i;
4376
  read_data`READ_SEL     = sel_i;
4377
 
4378
  for (i = 0; i < size_i; i = i + 1)
4379 116 mohor
  begin
4380 169 mohor
    wb_master.blk_read_data_in[i] = read_data;
4381
    read_data`READ_ADDRESS        = read_data`READ_ADDRESS + 4;
4382
  end
4383
 
4384
  wb_master.wb_block_read(flags, read_status);
4385
 
4386
  if (read_status`CYC_ACTUAL_TRANSFER !== size_i)
4387
  begin
4388
    `TIME;
4389
    $display("*E WISHBONE Master was unable to complete the requested read operation from MAC!");
4390
  end
4391
 
4392
  for (i = 0; i < size_i; i = i + 1)
4393
  begin
4394
    data_o       = data_o << 32;
4395
    read_data    = wb_master.blk_read_data_out[(size_i - 1) - i]; // [31 - i];
4396
    data_o[31:0] = read_data`READ_DATA;
4397
  end
4398
end
4399
endtask // wbm_read
4400
 
4401
 
4402
//////////////////////////////////////////////////////////////
4403
// Ethernet Basic tasks
4404
//////////////////////////////////////////////////////////////
4405
 
4406
task hard_reset; //  MAC registers
4407
begin
4408
  // reset MAC registers
4409
  @(posedge wb_clk);
4410
  #2 wb_rst = 1'b1;
4411
  repeat(2) @(posedge wb_clk);
4412
  #2 wb_rst = 1'b0;
4413
end
4414
endtask // hard_reset
4415
 
4416
task reset_mac; //  MAC module
4417
  reg [31:0] tmp;
4418
  reg [31:0] tmp_no_rst;
4419
begin
4420
  // read MODER register first
4421
  wbm_read(`ETH_MODER, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4422
  // set reset bit - write back to MODER register with RESET bit
4423
  wbm_write(`ETH_MODER, (`ETH_MODER_RST | tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4424
  // clear reset bit - write back to MODER register without RESET bit
4425
  tmp_no_rst = `ETH_MODER_RST;
4426
  tmp_no_rst = ~tmp_no_rst;
4427
  wbm_write(`ETH_MODER, (tmp_no_rst & tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4428
end
4429
endtask // reset_mac
4430
 
4431
task set_tx_bd;
4432
  input  [6:0]  tx_bd_num_start;
4433
  input  [6:0]  tx_bd_num_end;
4434
  input  [15:0] len;
4435
  input         irq;
4436
  input         pad;
4437
  input         crc;
4438
  input  [31:0] txpnt;
4439
 
4440
  integer       i;
4441
  integer       bd_status_addr, bd_ptr_addr;
4442
//  integer       buf_addr;
4443
begin
4444
  for(i = tx_bd_num_start; i <= tx_bd_num_end; i = i + 1)
4445
  begin
4446
//    buf_addr = `TX_BUF_BASE + i * 32'h600;
4447
    bd_status_addr = `TX_BD_BASE + i * 8;
4448
    bd_ptr_addr = bd_status_addr + 4;
4449
    // initialize BD - status
4450
//    wbm_write(bd_status_addr, 32'h00005800, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // IRQ + PAD + CRC
4451
    wbm_write(bd_status_addr, {len, 1'b0, irq, 1'b0, pad, crc, 11'h0},
4452
              4'hF, 1, wbm_init_waits, wbm_subseq_waits); // IRQ + PAD + CRC
4453
    // initialize BD - pointer
4454
//    wbm_write(bd_ptr_addr, buf_addr, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Initializing BD-pointer
4455
    wbm_write(bd_ptr_addr, txpnt, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Initializing BD-pointer
4456
  end
4457
end
4458
endtask // set_tx_bd
4459
 
4460
task set_tx_bd_wrap;
4461
  input  [6:0]  tx_bd_num_end;
4462
  integer       bd_status_addr, tmp;
4463
begin
4464
  bd_status_addr = `TX_BD_BASE + tx_bd_num_end * 8;
4465
  wbm_read(bd_status_addr, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4466
  // set wrap bit to this BD - this BD should be last-one
4467
  wbm_write(bd_status_addr, (`ETH_TX_BD_WRAP | tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4468
end
4469
endtask // set_tx_bd_wrap
4470
 
4471
task set_tx_bd_ready;
4472
  input  [6:0]  tx_nd_num_strat;
4473
  input  [6:0]  tx_bd_num_end;
4474
  integer       i;
4475
  integer       bd_status_addr, tmp;
4476
begin
4477
  for(i = tx_nd_num_strat; i <= tx_bd_num_end; i = i + 1)
4478
  begin
4479
    bd_status_addr = `TX_BD_BASE + i * 8;
4480
    wbm_read(bd_status_addr, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4481
    // set empty bit to this BD - this BD should be ready
4482
    wbm_write(bd_status_addr, (`ETH_TX_BD_READY | tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4483
  end
4484
end
4485
endtask // set_tx_bd_ready
4486
 
4487
task check_tx_bd;
4488
  input  [6:0]  tx_bd_num_end;
4489
  output [31:0] tx_bd_status;
4490
  integer       bd_status_addr, tmp;
4491
begin
4492
  bd_status_addr = `TX_BD_BASE + tx_bd_num_end * 8;
4493
  wbm_read(bd_status_addr, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4494
  #1 tx_bd_status = tmp;
4495
  #1;
4496
end
4497
endtask // check_tx_bd
4498
 
4499
task clear_tx_bd;
4500
  input  [6:0]  tx_nd_num_strat;
4501
  input  [6:0]  tx_bd_num_end;
4502
  integer       i;
4503
  integer       bd_status_addr, bd_ptr_addr;
4504
begin
4505
  for(i = tx_nd_num_strat; i <= tx_bd_num_end; i = i + 1)
4506
  begin
4507
    bd_status_addr = `TX_BD_BASE + i * 8;
4508
    bd_ptr_addr = bd_status_addr + 4;
4509
    // clear BD - status
4510
    wbm_write(bd_status_addr, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4511
    // clear BD - pointer
4512
    wbm_write(bd_ptr_addr, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4513
  end
4514
end
4515
endtask // clear_tx_bd
4516
 
4517
task set_rx_bd;
4518
  input  [6:0]  rx_bd_num_strat;
4519
  input  [6:0]  rx_bd_num_end;
4520
  input         irq;
4521
  input  [31:0] rxpnt;
4522
//  input  [6:0]  rxbd_num;
4523
  integer       i;
4524
  integer       bd_status_addr, bd_ptr_addr;
4525
//  integer       buf_addr;
4526
begin
4527
  for(i = rx_bd_num_strat; i <= rx_bd_num_end; i = i + 1)
4528
  begin
4529
//    buf_addr = `RX_BUF_BASE + i * 32'h600;
4530
    bd_status_addr = `RX_BD_BASE + i * 8;
4531 116 mohor
    bd_ptr_addr = bd_status_addr + 4;
4532
 
4533 169 mohor
    // initialize BD - status
4534
//    wbm_write(bd_status_addr, 32'h0000c000, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // IRQ + PAD + CRC
4535
    wbm_write(bd_status_addr, {17'h0, irq, 14'h0},
4536
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4537
    // initialize BD - pointer
4538
//    wbm_write(bd_ptr_addr, buf_addr, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Initializing BD-pointer
4539
    wbm_write(bd_ptr_addr, rxpnt, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Initializing BD-pointer
4540
  end
4541
end
4542
endtask // set_rx_bd
4543 116 mohor
 
4544 169 mohor
task set_rx_bd_wrap;
4545
  input  [6:0]  rx_bd_num_end;
4546
  integer       bd_status_addr, tmp;
4547
begin
4548
  bd_status_addr = `RX_BD_BASE + rx_bd_num_end * 8;
4549
  wbm_read(bd_status_addr, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4550
  // set wrap bit to this BD - this BD should be last-one
4551
  wbm_write(bd_status_addr, (`ETH_RX_BD_WRAP | tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4552
end
4553
endtask // set_rx_bd_wrap
4554 116 mohor
 
4555 169 mohor
task set_rx_bd_empty;
4556
  input  [6:0]  rx_bd_num_strat;
4557
  input  [6:0]  rx_bd_num_end;
4558
  integer       i;
4559
  integer       bd_status_addr, tmp;
4560
begin
4561
  for(i = rx_bd_num_strat; i <= rx_bd_num_end; i = i + 1)
4562
  begin
4563
    bd_status_addr = `RX_BD_BASE + i * 8;
4564
    wbm_read(bd_status_addr, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4565
    // set empty bit to this BD - this BD should be ready
4566
    wbm_write(bd_status_addr, (`ETH_RX_BD_EMPTY | tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4567 116 mohor
  end
4568 169 mohor
end
4569
endtask // set_rx_bd_empty
4570 116 mohor
 
4571 169 mohor
task check_rx_bd;
4572
  input  [6:0]  rx_bd_num_end;
4573
  output [31:0] rx_bd_status;
4574
  integer       bd_status_addr, tmp;
4575
begin
4576
  bd_status_addr = `RX_BD_BASE + rx_bd_num_end * 8;
4577
  wbm_read(bd_status_addr, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4578
  #1 rx_bd_status = tmp;
4579
  #1;
4580
end
4581
endtask // check_rx_bd
4582 116 mohor
 
4583 169 mohor
task clear_rx_bd;
4584
  input  [6:0]  rx_bd_num_strat;
4585
  input  [6:0]  rx_bd_num_end;
4586
  integer       i;
4587
  integer       bd_status_addr, bd_ptr_addr;
4588
begin
4589
  for(i = rx_bd_num_strat; i <= rx_bd_num_end; i = i + 1)
4590
  begin
4591
    bd_status_addr = `RX_BD_BASE + i * 8;
4592
    bd_ptr_addr = bd_status_addr + 4;
4593
    // clear BD - status
4594
    wbm_write(bd_status_addr, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4595
    // clear BD - pointer
4596
    wbm_write(bd_ptr_addr, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4597
  end
4598
end
4599
endtask // clear_rx_bd
4600 116 mohor
 
4601 169 mohor
task set_tx_packet;
4602
  input  [31:0] txpnt;
4603
  input  [15:0] len;
4604
  input  [7:0]  eth_start_data;
4605
  integer       i, sd;
4606
  integer       buffer;
4607
  reg           delta_t;
4608
begin
4609
  buffer = txpnt;
4610
  sd = eth_start_data;
4611
  delta_t = 0;
4612 116 mohor
 
4613 169 mohor
  // First write might not be word allign.
4614
  if(buffer[1:0] == 1)
4615
  begin
4616
    wb_slave.wr_mem(buffer - 1, {8'h0, sd[7:0], sd[7:0] + 3'h1, sd[7:0] + 3'h2}, 4'h7);
4617
    sd = sd + 3;
4618
    i = 3;
4619
  end
4620
  else if(buffer[1:0] == 2)
4621
  begin
4622
    wb_slave.wr_mem(buffer - 2, {16'h0, sd[7:0], sd[7:0] + 3'h1}, 4'h3);
4623
    sd = sd + 2;
4624
    i = 2;
4625
  end
4626
  else if(buffer[1:0] == 3)
4627
  begin
4628
    wb_slave.wr_mem(buffer - 3, {24'h0, sd[7:0]}, 4'h1);
4629
    sd = sd + 1;
4630
    i = 1;
4631
  end
4632
  else
4633
    i = 0;
4634
  delta_t = !delta_t;
4635 116 mohor
 
4636 169 mohor
  for(i = i; i < (len - 4); i = i + 4) // Last 0-3 bytes are not written
4637
  begin
4638
    wb_slave.wr_mem(buffer + i, {sd[7:0], sd[7:0] + 3'h1, sd[7:0] + 3'h2, sd[7:0] + 3'h3}, 4'hF);
4639
    sd = sd + 4;
4640
  end
4641
  delta_t = !delta_t;
4642
 
4643
  // Last word
4644
  if((len - i) == 3)
4645 116 mohor
  begin
4646 169 mohor
    wb_slave.wr_mem(buffer + i, {sd[7:0], sd[7:0] + 3'h1, sd[7:0] + 3'h2, 8'h0}, 4'hE);
4647
  end
4648
  else if((len - i) == 2)
4649
  begin
4650
    wb_slave.wr_mem(buffer + i, {sd[7:0], sd[7:0] + 3'h1, 16'h0}, 4'hC);
4651
  end
4652
  else if((len - i) == 1)
4653
  begin
4654
    wb_slave.wr_mem(buffer + i, {sd[7:0], 24'h0}, 4'h8);
4655
  end
4656
  else if((len - i) == 4)
4657
  begin
4658
    wb_slave.wr_mem(buffer + i, {sd[7:0], sd[7:0] + 3'h1, sd[7:0] + 3'h2, sd[7:0] + 3'h3}, 4'hF);
4659
  end
4660
  else
4661
    $display("(%0t)(%m) ERROR", $time);
4662
  delta_t = !delta_t;
4663
end
4664
endtask // set_tx_packet
4665
 
4666
task check_tx_packet;
4667
  input  [31:0] txpnt_wb;  // source
4668
  input  [31:0] txpnt_phy; // destination
4669
  input  [15:0] len;
4670
  output [31:0] failure;
4671
  integer       i, data_wb, data_phy;
4672
  reg    [31:0] addr_wb, addr_phy;
4673
  reg    [31:0] failure;
4674
  reg           delta_t;
4675
begin
4676
  addr_wb = txpnt_wb;
4677
  addr_phy = txpnt_phy;
4678
  delta_t = 0;
4679
  failure = 0;
4680
 
4681
  // First write might not be word allign.
4682
  if(addr_wb[1:0] == 1)
4683
  begin
4684
    wb_slave.rd_mem(addr_wb - 1, data_wb, 4'h7);
4685
    data_phy[31:24] = 0;
4686
    data_phy[23:16] = eth_phy.tx_mem[addr_phy[21:0]];
4687
    data_phy[15: 8] = eth_phy.tx_mem[addr_phy[21:0] + 1];
4688
    data_phy[ 7: 0] = eth_phy.tx_mem[addr_phy[21:0] + 2];
4689
    i = 3;
4690
    if (data_phy[23:0] !== data_wb[23:0])
4691
    begin
4692
      `TIME;
4693
      $display("*E Wrong 1. word (3 bytes) of TX packet!");
4694
      failure = 1;
4695
    end
4696
  end
4697
  else if (addr_wb[1:0] == 2)
4698
  begin
4699
    wb_slave.rd_mem(addr_wb - 2, data_wb, 4'h3);
4700
    data_phy[31:16] = 0;
4701
    data_phy[15: 8] = eth_phy.tx_mem[addr_phy[21:0]];
4702
    data_phy[ 7: 0] = eth_phy.tx_mem[addr_phy[21:0] + 1];
4703
    i = 2;
4704
    if (data_phy[15:0] !== data_wb[15:0])
4705
    begin
4706
      `TIME;
4707
      $display("*E Wrong 1. word (2 bytes) of TX packet!");
4708
      failure = 1;
4709
    end
4710
  end
4711
  else if (addr_wb[1:0] == 3)
4712
  begin
4713
    wb_slave.rd_mem(addr_wb - 3, data_wb, 4'h1);
4714
    data_phy[31: 8] = 0;
4715
    data_phy[ 7: 0] = eth_phy.tx_mem[addr_phy[21:0]];
4716
    i = 1;
4717
    if (data_phy[7:0] !== data_wb[7:0])
4718
    begin
4719
      `TIME;
4720
      $display("*E Wrong 1. word (1 byte) of TX packet!");
4721
      failure = 1;
4722
    end
4723
  end
4724
  else
4725
    i = 0;
4726
  delta_t = !delta_t;
4727
 
4728
  for(i = i; i < (len - 4); i = i + 4) // Last 0-3 bytes are not checked
4729
  begin
4730
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hF);
4731
    data_phy[31:24] = eth_phy.tx_mem[addr_phy[21:0] + i];
4732
    data_phy[23:16] = eth_phy.tx_mem[addr_phy[21:0] + i + 1];
4733
    data_phy[15: 8] = eth_phy.tx_mem[addr_phy[21:0] + i + 2];
4734
    data_phy[ 7: 0] = eth_phy.tx_mem[addr_phy[21:0] + i + 3];
4735
    if (data_phy[31:0] !== data_wb[31:0])
4736
    begin
4737
      `TIME;
4738
      $display("*E Wrong %d. word (4 bytes) of TX packet!", ((i/4)+1));
4739
      failure = failure + 1;
4740
    end
4741
  end
4742
  delta_t = !delta_t;
4743
 
4744
  // Last word
4745
  if((len - i) == 3)
4746
  begin
4747
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hE);
4748
    data_phy[31:24] = eth_phy.tx_mem[addr_phy[21:0] + i];
4749
    data_phy[23:16] = eth_phy.tx_mem[addr_phy[21:0] + i + 1];
4750
    data_phy[15: 8] = eth_phy.tx_mem[addr_phy[21:0] + i + 2];
4751
    data_phy[ 7: 0] = 0;
4752
    if (data_phy[31:8] !== data_wb[31:8])
4753
    begin
4754
      `TIME;
4755
      $display("*E Wrong %d. word (3 bytes) of TX packet!", ((i/4)+1));
4756
      failure = failure + 1;
4757
    end
4758
  end
4759
  else if((len - i) == 2)
4760
  begin
4761
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hC);
4762
    data_phy[31:24] = eth_phy.tx_mem[addr_phy[21:0] + i];
4763
    data_phy[23:16] = eth_phy.tx_mem[addr_phy[21:0] + i + 1];
4764
    data_phy[15: 8] = 0;
4765
    data_phy[ 7: 0] = 0;
4766
    if (data_phy[31:16] !== data_wb[31:16])
4767
    begin
4768
      `TIME;
4769
      $display("*E Wrong %d. word (2 bytes) of TX packet!", ((i/4)+1));
4770
      failure = failure + 1;
4771
    end
4772
  end
4773
  else if((len - i) == 1)
4774
  begin
4775
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'h8);
4776
    data_phy[31:24] = eth_phy.tx_mem[addr_phy[21:0] + i];
4777
    data_phy[23:16] = 0;
4778
    data_phy[15: 8] = 0;
4779
    data_phy[ 7: 0] = 0;
4780
    if (data_phy[31:24] !== data_wb[31:24])
4781
    begin
4782
      `TIME;
4783
      $display("*E Wrong %d. word (1 byte) of TX packet!", ((i/4)+1));
4784
      failure = failure + 1;
4785
    end
4786
  end
4787
  else if((len - i) == 4)
4788
  begin
4789
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hF);
4790
    data_phy[31:24] = eth_phy.tx_mem[addr_phy[21:0] + i];
4791
    data_phy[23:16] = eth_phy.tx_mem[addr_phy[21:0] + i + 1];
4792
    data_phy[15: 8] = eth_phy.tx_mem[addr_phy[21:0] + i + 2];
4793
    data_phy[ 7: 0] = eth_phy.tx_mem[addr_phy[21:0] + i + 3];
4794
    if (data_phy[31:0] !== data_wb[31:0])
4795
    begin
4796
      `TIME;
4797
      $display("*E Wrong %d. word (4 bytes) of TX packet!", ((i/4)+1));
4798
      failure = failure + 1;
4799
    end
4800
  end
4801
  else
4802
    $display("(%0t)(%m) ERROR", $time);
4803
  delta_t = !delta_t;
4804
end
4805
endtask // check_tx_packet
4806
 
4807
task set_rx_packet;
4808
  input  [31:0] rxpnt;
4809
  input  [15:0] len;
4810
  input         plus_dribble_nibble; // if length is longer for one nibble
4811
  input  [47:0] eth_dest_addr;
4812
  input  [47:0] eth_source_addr;
4813
  input  [15:0] eth_type_len;
4814
  input  [7:0]  eth_start_data;
4815
  integer       i, sd;
4816
  reg    [47:0] dest_addr;
4817
  reg    [47:0] source_addr;
4818
  reg    [15:0] type_len;
4819
  reg    [21:0] buffer;
4820
  reg           delta_t;
4821
begin
4822
  buffer = rxpnt[21:0];
4823
  dest_addr = eth_dest_addr;
4824
  source_addr = eth_source_addr;
4825
  type_len = eth_type_len;
4826
  sd = eth_start_data;
4827
  delta_t = 0;
4828
  for(i = 0; i < len; i = i + 1)
4829
  begin
4830
    if (i < 6)
4831
    begin
4832
      eth_phy.rx_mem[buffer] = dest_addr[47:40];
4833
      dest_addr = dest_addr << 8;
4834
    end
4835
    else if (i < 12)
4836
    begin
4837
      eth_phy.rx_mem[buffer] = source_addr[47:40];
4838
      source_addr = source_addr << 8;
4839
    end
4840
    else if (i < 14)
4841
    begin
4842
      eth_phy.rx_mem[buffer] = type_len[15:8];
4843
      type_len = type_len << 8;
4844
    end
4845
    else
4846
    begin
4847
      eth_phy.rx_mem[buffer] = sd[7:0];
4848
      sd = sd + 1;
4849
    end
4850
    buffer = buffer + 1;
4851
  end
4852
  delta_t = !delta_t;
4853
  if (plus_dribble_nibble)
4854
    eth_phy.rx_mem[buffer] = {4'h0, 4'hD /*sd[3:0]*/};
4855
  delta_t = !delta_t;
4856
end
4857
endtask // set_rx_packet
4858
 
4859
task check_rx_packet;
4860
  input  [31:0] rxpnt_phy; // source
4861
  input  [31:0] rxpnt_wb;  // destination
4862
  input  [15:0] len;
4863
  input         plus_dribble_nibble; // if length is longer for one nibble
4864
  input         successful_dribble_nibble; // if additional nibble is stored into memory
4865
  output [31:0] failure;
4866
  integer       i, data_wb, data_phy;
4867
  reg    [31:0] addr_wb, addr_phy;
4868
  reg    [31:0] failure;
4869
  reg    [21:0] buffer;
4870
  reg           delta_t;
4871
begin
4872
  addr_phy = rxpnt_phy;
4873
  addr_wb = rxpnt_wb;
4874
  delta_t = 0;
4875
  failure = 0;
4876
 
4877
  // First write might not be word allign.
4878
  if(addr_wb[1:0] == 1)
4879
  begin
4880
    wb_slave.rd_mem(addr_wb - 1, data_wb, 4'h7);
4881
    data_phy[31:24] = 0;
4882
    data_phy[23:16] = eth_phy.rx_mem[addr_phy[21:0]];
4883
    data_phy[15: 8] = eth_phy.rx_mem[addr_phy[21:0] + 1];
4884
    data_phy[ 7: 0] = eth_phy.rx_mem[addr_phy[21:0] + 2];
4885
    i = 3;
4886
    if (data_phy[23:0] !== data_wb[23:0])
4887
    begin
4888
      `TIME;
4889
      $display("*E Wrong 1. word (3 bytes) of TX packet!");
4890
      failure = 1;
4891
    end
4892
  end
4893
  else if (addr_wb[1:0] == 2)
4894
  begin
4895
    wb_slave.rd_mem(addr_wb - 2, data_wb, 4'h3);
4896
    data_phy[31:16] = 0;
4897
    data_phy[15: 8] = eth_phy.rx_mem[addr_phy[21:0]];
4898
    data_phy[ 7: 0] = eth_phy.rx_mem[addr_phy[21:0] + 1];
4899
    i = 2;
4900
    if (data_phy[15:0] !== data_wb[15:0])
4901
    begin
4902
      `TIME;
4903
      $display("*E Wrong 1. word (2 bytes) of TX packet!");
4904
      failure = 1;
4905
    end
4906
  end
4907
  else if (addr_wb[1:0] == 3)
4908
  begin
4909
    wb_slave.rd_mem(addr_wb - 3, data_wb, 4'h1);
4910
    data_phy[31: 8] = 0;
4911
    data_phy[ 7: 0] = eth_phy.rx_mem[addr_phy[21:0]];
4912
    i = 1;
4913
    if (data_phy[7:0] !== data_wb[7:0])
4914
    begin
4915
      `TIME;
4916
      $display("*E Wrong 1. word (1 byte) of TX packet!");
4917
      failure = 1;
4918
    end
4919
  end
4920
  else
4921
    i = 0;
4922
  delta_t = !delta_t;
4923
 
4924
  for(i = i; i < (len - 4); i = i + 4) // Last 0-3 bytes are not checked
4925
  begin
4926
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hF);
4927
    data_phy[31:24] = eth_phy.rx_mem[addr_phy[21:0] + i];
4928
    data_phy[23:16] = eth_phy.rx_mem[addr_phy[21:0] + i + 1];
4929
    data_phy[15: 8] = eth_phy.rx_mem[addr_phy[21:0] + i + 2];
4930
    data_phy[ 7: 0] = eth_phy.rx_mem[addr_phy[21:0] + i + 3];
4931
    if (data_phy[31:0] !== data_wb[31:0])
4932
    begin
4933
      `TIME;
4934
      $display("*E Wrong %d. word (4 bytes) of TX packet!", ((i/4)+1));
4935
      failure = failure + 1;
4936
    end
4937
  end
4938
  delta_t = !delta_t;
4939
 
4940
  // Last word
4941
  if((len - i) == 3)
4942
  begin
4943
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hF);
4944
    data_phy[31:24] = eth_phy.rx_mem[addr_phy[21:0] + i];
4945
    data_phy[23:16] = eth_phy.rx_mem[addr_phy[21:0] + i + 1];
4946
    data_phy[15: 8] = eth_phy.rx_mem[addr_phy[21:0] + i + 2];
4947
    if (plus_dribble_nibble)
4948
      data_phy[ 7: 0] = eth_phy.rx_mem[addr_phy[21:0] + i + 3];
4949
    else
4950
      data_phy[ 7: 0] = 0;
4951
    if (data_phy[31:8] !== data_wb[31:8])
4952
    begin
4953
      `TIME;
4954
      $display("*E Wrong %d. word (3 bytes) of TX packet!", ((i/4)+1));
4955
      failure = failure + 1;
4956
    end
4957
    if (plus_dribble_nibble && successful_dribble_nibble)
4958
    begin
4959
      if (data_phy[3:0] !== data_wb[3:0])
4960 116 mohor
      begin
4961 169 mohor
        `TIME;
4962
        $display("*E Wrong dribble nibble in %d. word (3 bytes) of TX packet!", ((i/4)+1));
4963
        failure = failure + 1;
4964 116 mohor
      end
4965 169 mohor
    end
4966
    else if (plus_dribble_nibble && !successful_dribble_nibble)
4967
    begin
4968
      if (data_phy[3:0] === data_wb[3:0])
4969 116 mohor
      begin
4970 169 mohor
        `TIME;
4971
        $display("*E Wrong dribble nibble in %d. word (3 bytes) of TX packet!", ((i/4)+1));
4972
        failure = failure + 1;
4973 116 mohor
      end
4974 169 mohor
    end
4975
  end
4976
  else if((len - i) == 2)
4977
  begin
4978
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hE);
4979
    data_phy[31:24] = eth_phy.rx_mem[addr_phy[21:0] + i];
4980
    data_phy[23:16] = eth_phy.rx_mem[addr_phy[21:0] + i + 1];
4981
    if (plus_dribble_nibble)
4982
      data_phy[15: 8] = eth_phy.rx_mem[addr_phy[21:0] + i + 2];
4983
    else
4984
      data_phy[15: 8] = 0;
4985
    data_phy[ 7: 0] = 0;
4986
    if (data_phy[31:16] !== data_wb[31:16])
4987
    begin
4988
      `TIME;
4989
      $display("*E Wrong %d. word (2 bytes) of TX packet!", ((i/4)+1));
4990
      failure = failure + 1;
4991
    end
4992
    if (plus_dribble_nibble && successful_dribble_nibble)
4993
    begin
4994
      if (data_phy[11:8] !== data_wb[11:8])
4995
      begin
4996
        `TIME;
4997
        $display("*E Wrong dribble nibble in %d. word (2 bytes) of TX packet!", ((i/4)+1));
4998
        failure = failure + 1;
4999
      end
5000
    end
5001
    else if (plus_dribble_nibble && !successful_dribble_nibble)
5002
    begin
5003
      if (data_phy[11:8] === data_wb[11:8])
5004
      begin
5005
        `TIME;
5006
        $display("*E Wrong dribble nibble in %d. word (2 bytes) of TX packet!", ((i/4)+1));
5007
        failure = failure + 1;
5008
      end
5009
    end
5010
  end
5011
  else if((len - i) == 1)
5012
  begin
5013
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hC);
5014
    data_phy[31:24] = eth_phy.rx_mem[addr_phy[21:0] + i];
5015
    if (plus_dribble_nibble)
5016
      data_phy[23:16] = eth_phy.rx_mem[addr_phy[21:0] + i + 1];
5017
    else
5018
      data_phy[23:16] = 0;
5019
    data_phy[15: 8] = 0;
5020
    data_phy[ 7: 0] = 0;
5021
    if (data_phy[31:24] !== data_wb[31:24])
5022
    begin
5023
      `TIME;
5024
      $display("*E Wrong %d. word (1 byte) of TX packet!", ((i/4)+1));
5025
      failure = failure + 1;
5026
    end
5027
    if (plus_dribble_nibble && successful_dribble_nibble)
5028
    begin
5029
      if (data_phy[19:16] !== data_wb[19:16])
5030
      begin
5031
        `TIME;
5032
        $display("*E Wrong dribble nibble in %d. word (1 byte) of TX packet!", ((i/4)+1));
5033
        failure = failure + 1;
5034
      end
5035
    end
5036
    else if (plus_dribble_nibble && !successful_dribble_nibble)
5037
    begin
5038
      if (data_phy[19:16] === data_wb[19:16])
5039
      begin
5040
        `TIME;
5041
        $display("*E Wrong dribble nibble in %d. word (1 byte) of TX packet!", ((i/4)+1));
5042
        failure = failure + 1;
5043
      end
5044
    end
5045
  end
5046
  else if((len - i) == 4)
5047
  begin
5048
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hF);
5049
    data_phy[31:24] = eth_phy.rx_mem[addr_phy[21:0] + i];
5050
    data_phy[23:16] = eth_phy.rx_mem[addr_phy[21:0] + i + 1];
5051
    data_phy[15: 8] = eth_phy.rx_mem[addr_phy[21:0] + i + 2];
5052
    data_phy[ 7: 0] = eth_phy.rx_mem[addr_phy[21:0] + i + 3];
5053
    if (data_phy[31:0] !== data_wb[31:0])
5054
    begin
5055
      `TIME;
5056
      $display("*E Wrong %d. word (4 bytes) of TX packet!", ((i/4)+1));
5057
      failure = failure + 1;
5058
    end
5059
    if (plus_dribble_nibble)
5060
    begin
5061
      wb_slave.rd_mem(addr_wb + i + 4, data_wb, 4'h8);
5062
      data_phy[31:24] = eth_phy.rx_mem[addr_phy[21:0] + i + 4];
5063
      if (successful_dribble_nibble)
5064
      begin
5065
        if (data_phy[27:24] !== data_wb[27:24])
5066
        begin
5067
          `TIME;
5068
          $display("*E Wrong dribble nibble in %d. word (0 bytes) of TX packet!", ((i/4)+2));
5069
          failure = failure + 1;
5070
        end
5071
      end
5072
      else
5073
      begin
5074
        if (data_phy[27:24] === data_wb[27:24])
5075
        begin
5076
          `TIME;
5077
          $display("*E Wrong dribble nibble in %d. word (0 bytes) of TX packet!", ((i/4)+2));
5078
          failure = failure + 1;
5079
        end
5080
      end
5081
    end
5082
  end
5083
  else
5084
    $display("(%0t)(%m) ERROR", $time);
5085
  delta_t = !delta_t;
5086
end
5087
endtask // check_rx_packet
5088 116 mohor
 
5089 169 mohor
//////////////////////////////////////////////////////////////
5090
// Ethernet CRC Basic tasks
5091
//////////////////////////////////////////////////////////////
5092
 
5093
task append_tx_crc;
5094
  input  [31:0] txpnt_wb;  // source
5095
  input  [15:0] len; // length in bytes without CRC
5096
  input         negated_crc; // if appended CRC is correct or not
5097
  reg    [31:0] crc;
5098
  reg    [31:0] addr_wb;
5099
  reg           delta_t;
5100
begin
5101
  addr_wb = txpnt_wb + len;
5102
  delta_t = 0;
5103
  // calculate CRC from prepared packet
5104
  paralel_crc_mac(txpnt_wb, {16'h0, len}, 1'b0, crc);
5105
  if (negated_crc)
5106
    crc = ~crc;
5107
  delta_t = !delta_t;
5108
 
5109
  // Write might not be word allign.
5110
  if (addr_wb[1:0] == 1)
5111
  begin
5112
    wb_slave.wr_mem(addr_wb - 1, {8'h0, crc[7:0], crc[15:8], crc[23:16]}, 4'h7);
5113
    wb_slave.wr_mem(addr_wb + 3, {crc[31:24], 24'h0}, 4'h8);
5114 116 mohor
  end
5115 169 mohor
  else if (addr_wb[1:0] == 2)
5116
  begin
5117
    wb_slave.wr_mem(addr_wb - 2, {16'h0, crc[7:0], crc[15:8]}, 4'h3);
5118
    wb_slave.wr_mem(addr_wb + 2, {crc[23:16], crc[31:24], 16'h0}, 4'hC);
5119
  end
5120
  else if (addr_wb[1:0] == 3)
5121
  begin
5122
    wb_slave.wr_mem(addr_wb - 3, {24'h0, crc[7:0]}, 4'h1);
5123
    wb_slave.wr_mem(addr_wb + 1, {crc[15:8], crc[23:16], crc[31:24], 8'h0}, 4'hE);
5124
  end
5125
  else
5126
  begin
5127
    wb_slave.wr_mem(addr_wb, {crc[7:0], crc[15:8], crc[23:16], crc[31:24]}, 4'hF);
5128
  end
5129
  delta_t = !delta_t;
5130
end
5131
endtask // append_tx_crc
5132 116 mohor
 
5133 169 mohor
task check_tx_crc; // used to check crc added to TX packets by MAC
5134
  input  [31:0] txpnt_phy; // destination
5135
  input  [15:0] len; // length in bytes without CRC
5136
  input         negated_crc; // if appended CRC is correct or not
5137
  output [31:0] failure;
5138
  reg    [31:0] failure;
5139
  reg    [31:0] crc_calc;
5140
  reg    [31:0] crc;
5141
  reg    [31:0] addr_phy;
5142
  reg           delta_t;
5143
begin
5144
  addr_phy = txpnt_phy;
5145
  failure = 0;
5146
  // calculate CRC from sent packet
5147
//  serial_crc_phy_tx(addr_phy, {16'h0, len}, 1'b0, crc_calc);
5148
//#10;
5149
  paralel_crc_phy_tx(addr_phy, {16'h0, len}, 1'b0, crc_calc);
5150 116 mohor
 
5151 169 mohor
  addr_phy = addr_phy + len;
5152
  // Read CRC - BIG endian
5153
  crc[31:24] = eth_phy.tx_mem[addr_phy[21:0]];
5154
  crc[23:16] = eth_phy.tx_mem[addr_phy[21:0] + 1];
5155
  crc[15: 8] = eth_phy.tx_mem[addr_phy[21:0] + 2];
5156
  crc[ 7: 0] = eth_phy.tx_mem[addr_phy[21:0] + 3];
5157
 
5158
  delta_t = !delta_t;
5159
  if (negated_crc)
5160
  begin
5161
    if ((~crc_calc) !== crc)
5162
    begin
5163
      `TIME;
5164
      $display("*E Negated CRC was not successfuly transmitted!");
5165
      failure = failure + 1;
5166
    end
5167
  end
5168
  else
5169
  begin
5170
    if (crc_calc !== crc)
5171
    begin
5172
      `TIME;
5173
      $display("*E Transmitted CRC was not correct!");
5174
      failure = failure + 1;
5175
    end
5176
  end
5177
  delta_t = !delta_t;
5178
end
5179
endtask // check_tx_crc
5180
 
5181
task append_rx_crc;
5182
  input  [31:0] rxpnt_phy; // source
5183
  input  [15:0] len; // length in bytes without CRC
5184
  input         plus_dribble_nibble; // if length is longer for one nibble
5185
  input         negated_crc; // if appended CRC is correct or not
5186
  reg    [31:0] crc;
5187
  reg    [7:0]  tmp;
5188
  reg    [31:0] addr_phy;
5189
  reg           delta_t;
5190
begin
5191
  addr_phy = rxpnt_phy + len;
5192
  delta_t = 0;
5193
  // calculate CRC from prepared packet
5194
  paralel_crc_phy_rx(rxpnt_phy, {16'h0, len}, plus_dribble_nibble, crc);
5195
  if (negated_crc)
5196
    crc = ~crc;
5197
  delta_t = !delta_t;
5198
 
5199
  if (plus_dribble_nibble)
5200
  begin
5201
    tmp = eth_phy.rx_mem[addr_phy];
5202
    eth_phy.rx_mem[addr_phy]     = {crc[3:0], tmp[3:0]};
5203
    eth_phy.rx_mem[addr_phy + 1] = {crc[11:8], crc[7:4]};
5204
    eth_phy.rx_mem[addr_phy + 2] = {crc[19:16], crc[15:12]};
5205
    eth_phy.rx_mem[addr_phy + 3] = {crc[27:24], crc[23:20]};
5206
    eth_phy.rx_mem[addr_phy + 4] = {4'h0, crc[31:28]};
5207
  end
5208
  else
5209
  begin
5210
    eth_phy.rx_mem[addr_phy]     = crc[7:0];
5211
    eth_phy.rx_mem[addr_phy + 1] = crc[15:8];
5212
    eth_phy.rx_mem[addr_phy + 2] = crc[23:16];
5213
    eth_phy.rx_mem[addr_phy + 3] = crc[31:24];
5214
  end
5215
end
5216
endtask // append_rx_crc
5217
 
5218
// paralel CRC checking for PHY TX
5219
task paralel_crc_phy_tx;
5220
  input  [31:0] start_addr; // start address
5221
  input  [31:0] len; // length of frame in Bytes without CRC length
5222
  input         plus_dribble_nibble; // if length is longer for one nibble
5223
  output [31:0] crc_out;
5224
  reg    [21:0] addr_cnt; // only 22 address lines
5225
  integer       word_cnt;
5226
  integer       nibble_cnt;
5227
  reg    [31:0] load_reg;
5228
  reg           delta_t;
5229
  reg    [31:0] crc_next;
5230
  reg    [31:0] crc;
5231
  reg           crc_error;
5232
  reg     [3:0] data_in;
5233
  integer       i;
5234
begin
5235
  #1 addr_cnt = start_addr[21:0];
5236
  word_cnt = 24; // 27; // start of the frame - nibble granularity (MSbit first)
5237
  crc = 32'hFFFF_FFFF; // INITIAL value
5238
  delta_t = 0;
5239
  // length must include 4 bytes of ZEROs, to generate CRC
5240
  // get number of nibbles from Byte length (2^1 = 2)
5241
  if (plus_dribble_nibble)
5242
    nibble_cnt = ((len + 4) << 1) + 1'b1; // one nibble longer
5243
  else
5244
    nibble_cnt = ((len + 4) << 1);
5245
  // because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3]
5246
  load_reg[31:24] = eth_phy.tx_mem[addr_cnt];
5247
  addr_cnt = addr_cnt + 1;
5248
  load_reg[23:16] = eth_phy.tx_mem[addr_cnt];
5249
  addr_cnt = addr_cnt + 1;
5250
  load_reg[15: 8] = eth_phy.tx_mem[addr_cnt];
5251
  addr_cnt = addr_cnt + 1;
5252
  load_reg[ 7: 0] = eth_phy.tx_mem[addr_cnt];
5253
  addr_cnt = addr_cnt + 1;
5254
  while (nibble_cnt > 0)
5255
  begin
5256
    // wait for delta time
5257
    delta_t = !delta_t;
5258
    // shift data in
5259
 
5260
    if(nibble_cnt <= 8) // for additional 8 nibbles shift ZEROs in!
5261
      data_in[3:0] = 4'h0;
5262
    else
5263
 
5264
      data_in[3:0] = {load_reg[word_cnt], load_reg[word_cnt+1], load_reg[word_cnt+2], load_reg[word_cnt+3]};
5265
    crc_next[0]  = (data_in[0] ^ crc[28]);
5266
    crc_next[1]  = (data_in[1] ^ data_in[0] ^ crc[28]    ^ crc[29]);
5267
    crc_next[2]  = (data_in[2] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[30]);
5268
    crc_next[3]  = (data_in[3] ^ data_in[2] ^ data_in[1] ^ crc[29]  ^ crc[30] ^ crc[31]);
5269
    crc_next[4]  = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[0];
5270
    crc_next[5]  = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[1];
5271
    crc_next[6]  = (data_in[2] ^ data_in[1] ^ crc[29]    ^ crc[30]) ^ crc[ 2];
5272
    crc_next[7]  = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[3];
5273
    crc_next[8]  = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[4];
5274
    crc_next[9]  = (data_in[2] ^ data_in[1] ^ crc[29]    ^ crc[30]) ^ crc[5];
5275
    crc_next[10] = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[6];
5276
    crc_next[11] = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[7];
5277
    crc_next[12] = (data_in[2] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[30]) ^ crc[8];
5278
    crc_next[13] = (data_in[3] ^ data_in[2] ^ data_in[1] ^ crc[29]  ^ crc[30] ^ crc[31]) ^ crc[9];
5279
    crc_next[14] = (data_in[3] ^ data_in[2] ^ crc[30]    ^ crc[31]) ^ crc[10];
5280
    crc_next[15] = (data_in[3] ^ crc[31])   ^ crc[11];
5281
    crc_next[16] = (data_in[0] ^ crc[28])   ^ crc[12];
5282
    crc_next[17] = (data_in[1] ^ crc[29])   ^ crc[13];
5283
    crc_next[18] = (data_in[2] ^ crc[30])   ^ crc[14];
5284
    crc_next[19] = (data_in[3] ^ crc[31])   ^ crc[15];
5285
    crc_next[20] =  crc[16];
5286
    crc_next[21] =  crc[17];
5287
    crc_next[22] = (data_in[0] ^ crc[28])   ^ crc[18];
5288
    crc_next[23] = (data_in[1] ^ data_in[0] ^ crc[29]    ^ crc[28]) ^ crc[19];
5289
    crc_next[24] = (data_in[2] ^ data_in[1] ^ crc[30]    ^ crc[29]) ^ crc[20];
5290
    crc_next[25] = (data_in[3] ^ data_in[2] ^ crc[31]    ^ crc[30]) ^ crc[21];
5291
    crc_next[26] = (data_in[3] ^ data_in[0] ^ crc[31]    ^ crc[28]) ^ crc[22];
5292
    crc_next[27] = (data_in[1] ^ crc[29])   ^ crc[23];
5293
    crc_next[28] = (data_in[2] ^ crc[30])   ^ crc[24];
5294
    crc_next[29] = (data_in[3] ^ crc[31])   ^ crc[25];
5295
    crc_next[30] =  crc[26];
5296
    crc_next[31] =  crc[27];
5297
 
5298
    crc = crc_next;
5299
    crc_error = crc[31:0] != 32'hc704dd7b;  // CRC not equal to magic number
5300
    case (nibble_cnt)
5301
    9: crc_out = {!crc[24], !crc[25], !crc[26], !crc[27], !crc[28], !crc[29], !crc[30], !crc[31],
5302
                  !crc[16], !crc[17], !crc[18], !crc[19], !crc[20], !crc[21], !crc[22], !crc[23],
5303
                  !crc[ 8], !crc[ 9], !crc[10], !crc[11], !crc[12], !crc[13], !crc[14], !crc[15],
5304
                  !crc[ 0], !crc[ 1], !crc[ 2], !crc[ 3], !crc[ 4], !crc[ 5], !crc[ 6], !crc[ 7]};
5305
    default: crc_out = crc_out;
5306
    endcase
5307
    // wait for delta time
5308
    delta_t = !delta_t;
5309
    // increment address and load new data
5310
    if ((word_cnt+3) == 7)//4)
5311
    begin
5312
      // because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3]
5313
      load_reg[31:24] = eth_phy.tx_mem[addr_cnt];
5314
      addr_cnt = addr_cnt + 1;
5315
      load_reg[23:16] = eth_phy.tx_mem[addr_cnt];
5316
      addr_cnt = addr_cnt + 1;
5317
      load_reg[15: 8] = eth_phy.tx_mem[addr_cnt];
5318
      addr_cnt = addr_cnt + 1;
5319
      load_reg[ 7: 0] = eth_phy.tx_mem[addr_cnt];
5320
      addr_cnt = addr_cnt + 1;
5321
    end
5322
    // set new load bit position
5323
    if((word_cnt+3) == 31)
5324
      word_cnt = 16;
5325
    else if ((word_cnt+3) == 23)
5326
      word_cnt = 8;
5327
    else if ((word_cnt+3) == 15)
5328
      word_cnt = 0;
5329
    else if ((word_cnt+3) == 7)
5330
      word_cnt = 24;
5331
    else
5332
      word_cnt = word_cnt + 4;// - 4;
5333
    // decrement nibble counter
5334
    nibble_cnt = nibble_cnt - 1;
5335
    // wait for delta time
5336
    delta_t = !delta_t;
5337
  end // while
5338
  #1;
5339
end
5340
endtask // paralel_crc_phy_tx
5341
 
5342
// paralel CRC calculating for PHY RX
5343
task paralel_crc_phy_rx;
5344
  input  [31:0] start_addr; // start address
5345
  input  [31:0] len; // length of frame in Bytes without CRC length
5346
  input         plus_dribble_nibble; // if length is longer for one nibble
5347
  output [31:0] crc;
5348
  reg    [21:0] addr_cnt; // only 22 address lines
5349
  integer       word_cnt;
5350
  integer       bit_cnt;
5351
  reg    [31:0] load_reg;
5352
  reg    [31:0] crc_shift_reg;
5353
  reg    [31:0] crc_store_reg;
5354
  reg           delta_t;
5355
begin
5356
  #1 addr_cnt = start_addr[21:0];
5357
  word_cnt = 24; // start of the frame
5358
  crc_shift_reg = 0;
5359
  delta_t = 0;
5360
  // length must include 4 bytes of ZEROs, to generate CRC
5361
  // get number of bits from Byte length (2^3 = 8)
5362
  if (plus_dribble_nibble)
5363
    bit_cnt = ((len + 4) << 3) + 3'h4; // one nibble longer
5364
  else
5365
    bit_cnt = ((len + 4) << 3);
5366
  load_reg[31:24] = eth_phy.rx_mem[addr_cnt];
5367
  addr_cnt = addr_cnt + 1;
5368
  load_reg[23:16] = eth_phy.rx_mem[addr_cnt];
5369
  addr_cnt = addr_cnt + 1;
5370
  load_reg[15:8]  = eth_phy.rx_mem[addr_cnt];
5371
  addr_cnt = addr_cnt + 1;
5372
  load_reg[7:0]   = eth_phy.rx_mem[addr_cnt];
5373
 
5374
  while (bit_cnt > 0)
5375
  begin
5376
    // wait for delta time
5377
    delta_t = !delta_t;
5378
    // store previous data
5379
    crc_store_reg = crc_shift_reg;
5380
    // shift data in
5381
    if(bit_cnt <= 32) // for additional 32 bits shift ZEROs in!
5382
     crc_shift_reg[0] = 1'b0               ^ crc_store_reg[31];
5383
    else
5384
     crc_shift_reg[0] = load_reg[word_cnt] ^ crc_store_reg[31];
5385
    crc_shift_reg[1]  = crc_store_reg[0]   ^ crc_store_reg[31];
5386
    crc_shift_reg[2]  = crc_store_reg[1]   ^ crc_store_reg[31];
5387
    crc_shift_reg[3]  = crc_store_reg[2];
5388
    crc_shift_reg[4]  = crc_store_reg[3]   ^ crc_store_reg[31];
5389
    crc_shift_reg[5]  = crc_store_reg[4]   ^ crc_store_reg[31];
5390
    crc_shift_reg[6]  = crc_store_reg[5];
5391
    crc_shift_reg[7]  = crc_store_reg[6]   ^ crc_store_reg[31];
5392
    crc_shift_reg[8]  = crc_store_reg[7]   ^ crc_store_reg[31];
5393
    crc_shift_reg[9]  = crc_store_reg[8];
5394
    crc_shift_reg[10] = crc_store_reg[9]   ^ crc_store_reg[31];
5395
    crc_shift_reg[11] = crc_store_reg[10]  ^ crc_store_reg[31];
5396
    crc_shift_reg[12] = crc_store_reg[11]  ^ crc_store_reg[31];
5397
    crc_shift_reg[13] = crc_store_reg[12];
5398
    crc_shift_reg[14] = crc_store_reg[13];
5399
    crc_shift_reg[15] = crc_store_reg[14];
5400
    crc_shift_reg[16] = crc_store_reg[15]  ^ crc_store_reg[31];
5401
    crc_shift_reg[17] = crc_store_reg[16];
5402
    crc_shift_reg[18] = crc_store_reg[17];
5403
    crc_shift_reg[19] = crc_store_reg[18];
5404
    crc_shift_reg[20] = crc_store_reg[19];
5405
    crc_shift_reg[21] = crc_store_reg[20];
5406
    crc_shift_reg[22] = crc_store_reg[21]  ^ crc_store_reg[31];
5407
    crc_shift_reg[23] = crc_store_reg[22]  ^ crc_store_reg[31];
5408
    crc_shift_reg[24] = crc_store_reg[23];
5409
    crc_shift_reg[25] = crc_store_reg[24];
5410
    crc_shift_reg[26] = crc_store_reg[25]  ^ crc_store_reg[31];
5411
    crc_shift_reg[27] = crc_store_reg[26];
5412
    crc_shift_reg[28] = crc_store_reg[27];
5413
    crc_shift_reg[29] = crc_store_reg[28];
5414
    crc_shift_reg[30] = crc_store_reg[29];
5415
    crc_shift_reg[31] = crc_store_reg[30];
5416
    // wait for delta time
5417
    delta_t = !delta_t;
5418
    // increment address and load new data
5419
    if (word_cnt == 7)
5420
    begin
5421
      addr_cnt = addr_cnt + 1;
5422
      load_reg[31:24] = eth_phy.rx_mem[addr_cnt];
5423
      addr_cnt = addr_cnt + 1;
5424
      load_reg[23:16] = eth_phy.rx_mem[addr_cnt];
5425
      addr_cnt = addr_cnt + 1;
5426
      load_reg[15:8]  = eth_phy.rx_mem[addr_cnt];
5427
      addr_cnt = addr_cnt + 1;
5428
      load_reg[7:0]   = eth_phy.rx_mem[addr_cnt];
5429
    end
5430
    // set new load bit position
5431
    if(word_cnt == 31)
5432
      word_cnt = 16;
5433
    else if (word_cnt == 23)
5434
      word_cnt = 8;
5435
    else if (word_cnt == 15)
5436
      word_cnt = 0;
5437
    else if (word_cnt == 7)
5438
      word_cnt = 24;
5439
    else
5440
      word_cnt = word_cnt + 1;
5441
    // decrement bit counter
5442
    bit_cnt = bit_cnt - 1;
5443
    // wait for delta time
5444
    delta_t = !delta_t;
5445
  end // while
5446
 
5447
  // put CRC out
5448
  crc = crc_shift_reg;
5449
  #1;
5450
end
5451
endtask // paralel_crc_phy_rx
5452
 
5453
// paralel CRC checking for MAC
5454
task paralel_crc_mac;
5455
  input  [31:0] start_addr; // start address
5456
  input  [31:0] len; // length of frame in Bytes without CRC length
5457
  input         plus_dribble_nibble; // if length is longer for one nibble
5458
  output [31:0] crc;
5459
  reg    [19:0] addr_cnt; // only 20 address lines
5460
  integer       word_cnt;
5461
  integer       bit_cnt;
5462
  reg    [31:0] load_reg;
5463
  reg    [31:0] crc_shift_reg;
5464
  reg    [31:0] crc_store_reg;
5465
  reg           delta_t;
5466
begin
5467
  #1 addr_cnt = start_addr[19:0];
5468
  // set starting point depending with which byte frame starts (e.g. if addr_cnt[1:0] == 0, then
5469
  //   MSB of the packet must be written to the LSB of Big ENDIAN Word [31:24])
5470
  if (addr_cnt[1:0] == 2'h1)
5471
    word_cnt = 16; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
5472
  else if (addr_cnt[1:0] == 2'h2)
5473
    word_cnt = 8; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
5474
  else if (addr_cnt[1:0] == 2'h3)
5475
    word_cnt = 0; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
5476
  else
5477
    word_cnt = 24; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
5478
 
5479
  crc_shift_reg = 0;
5480
  delta_t = 0;
5481
  // length must include 4 bytes of ZEROs, to generate CRC
5482
  // get number of bits from Byte length (2^3 = 8)
5483
  if (plus_dribble_nibble)
5484
    bit_cnt = ((len + 4) << 3) + 3'h4; // one nibble longer
5485
  else
5486
    bit_cnt = ((len + 4) << 3);
5487
  load_reg = wb_slave.wb_memory[{12'h0, addr_cnt}];
5488
 
5489
  while (bit_cnt > 0)
5490
  begin
5491
    // wait for delta time
5492
    delta_t = !delta_t;
5493
    // store previous data
5494
    crc_store_reg = crc_shift_reg;
5495
    // shift data in
5496
    if(bit_cnt <= 32) // for additional 32 bits shift ZEROs in!
5497
     crc_shift_reg[0] = 1'b0               ^ crc_store_reg[31];
5498
    else
5499
     crc_shift_reg[0] = load_reg[word_cnt] ^ crc_store_reg[31];
5500
    crc_shift_reg[1]  = crc_store_reg[0]   ^ crc_store_reg[31];
5501
    crc_shift_reg[2]  = crc_store_reg[1]   ^ crc_store_reg[31];
5502
    crc_shift_reg[3]  = crc_store_reg[2];
5503
    crc_shift_reg[4]  = crc_store_reg[3]   ^ crc_store_reg[31];
5504
    crc_shift_reg[5]  = crc_store_reg[4]   ^ crc_store_reg[31];
5505
    crc_shift_reg[6]  = crc_store_reg[5];
5506
    crc_shift_reg[7]  = crc_store_reg[6]   ^ crc_store_reg[31];
5507
    crc_shift_reg[8]  = crc_store_reg[7]   ^ crc_store_reg[31];
5508
    crc_shift_reg[9]  = crc_store_reg[8];
5509
    crc_shift_reg[10] = crc_store_reg[9]   ^ crc_store_reg[31];
5510
    crc_shift_reg[11] = crc_store_reg[10]  ^ crc_store_reg[31];
5511
    crc_shift_reg[12] = crc_store_reg[11]  ^ crc_store_reg[31];
5512
    crc_shift_reg[13] = crc_store_reg[12];
5513
    crc_shift_reg[14] = crc_store_reg[13];
5514
    crc_shift_reg[15] = crc_store_reg[14];
5515
    crc_shift_reg[16] = crc_store_reg[15]  ^ crc_store_reg[31];
5516
    crc_shift_reg[17] = crc_store_reg[16];
5517
    crc_shift_reg[18] = crc_store_reg[17];
5518
    crc_shift_reg[19] = crc_store_reg[18];
5519
    crc_shift_reg[20] = crc_store_reg[19];
5520
    crc_shift_reg[21] = crc_store_reg[20];
5521
    crc_shift_reg[22] = crc_store_reg[21]  ^ crc_store_reg[31];
5522
    crc_shift_reg[23] = crc_store_reg[22]  ^ crc_store_reg[31];
5523
    crc_shift_reg[24] = crc_store_reg[23];
5524
    crc_shift_reg[25] = crc_store_reg[24];
5525
    crc_shift_reg[26] = crc_store_reg[25]  ^ crc_store_reg[31];
5526
    crc_shift_reg[27] = crc_store_reg[26];
5527
    crc_shift_reg[28] = crc_store_reg[27];
5528
    crc_shift_reg[29] = crc_store_reg[28];
5529
    crc_shift_reg[30] = crc_store_reg[29];
5530
    crc_shift_reg[31] = crc_store_reg[30];
5531
    // wait for delta time
5532
    delta_t = !delta_t;
5533
    // increment address and load new data for Big ENDIAN Bytes (Litle ENDIAN bits)
5534
    if (word_cnt == 7)
5535
    begin
5536
      addr_cnt = addr_cnt + 4;
5537
      load_reg = wb_slave.wb_memory[{12'h0, addr_cnt}];
5538
    end
5539
    // set new load bit position for Big ENDIAN Bytes (Litle ENDIAN bits)
5540
    if(word_cnt == 31)
5541
      word_cnt = 16;
5542
    else if (word_cnt == 23)
5543
      word_cnt = 8;
5544
    else if (word_cnt == 15)
5545
      word_cnt = 0;
5546
    else if (word_cnt == 7)
5547
      word_cnt = 24;
5548
    else
5549
      word_cnt = word_cnt + 1;
5550
    // decrement bit counter
5551
    bit_cnt = bit_cnt - 1;
5552
    // wait for delta time
5553
    delta_t = !delta_t;
5554
  end // while
5555
 
5556
  // put CRC out
5557
  crc = crc_shift_reg;
5558
  #1;
5559
end
5560
endtask // paralel_crc_mac
5561
 
5562
// serial CRC checking for PHY TX
5563
task serial_crc_phy_tx;
5564
  input  [31:0] start_addr; // start address
5565
  input  [31:0] len; // length of frame in Bytes without CRC length
5566
  input         plus_dribble_nibble; // if length is longer for one nibble
5567
  output [31:0] crc;
5568
  reg    [21:0] addr_cnt; // only 22 address lines
5569
  integer       word_cnt;
5570
  integer       bit_cnt;
5571
  reg    [31:0] load_reg;
5572
  reg    [31:0] crc_shift_reg;
5573
  reg    [31:0] crc_store_reg;
5574
  reg           delta_t;
5575
begin
5576
  #1 addr_cnt = start_addr[21:0];
5577
  word_cnt = 24; // 27; // start of the frame - nibble granularity (MSbit first)
5578
  crc_store_reg = 32'hFFFF_FFFF; // INITIAL value
5579
  delta_t = 0;
5580
  // length must include 4 bytes of ZEROs, to generate CRC
5581
  // get number of bits from Byte length (2^3 = 8)
5582
  if (plus_dribble_nibble)
5583
    bit_cnt = ((len + 4) << 3) + 3'h4; // one nibble longer
5584
  else
5585
    bit_cnt = ((len + 4) << 3);
5586
  // because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3]
5587
  load_reg[31:24] = eth_phy.tx_mem[addr_cnt];
5588
  addr_cnt = addr_cnt + 1;
5589
  load_reg[23:16] = eth_phy.tx_mem[addr_cnt];
5590
  addr_cnt = addr_cnt + 1;
5591
  load_reg[15: 8] = eth_phy.tx_mem[addr_cnt];
5592
  addr_cnt = addr_cnt + 1;
5593
  load_reg[ 7: 0] = eth_phy.tx_mem[addr_cnt];
5594
  addr_cnt = addr_cnt + 1;
5595
#1;
5596
  while (bit_cnt > 0)
5597
  begin
5598
    // wait for delta time
5599
    delta_t = !delta_t;
5600
#1;
5601
    // shift data in
5602
 
5603
    if(bit_cnt <= 32) // for additional 32 bits shift ZEROs in!
5604
     crc_shift_reg[0] = 1'b0               ^ crc_store_reg[31];
5605
    else
5606
 
5607
     crc_shift_reg[0] = load_reg[word_cnt] ^ crc_store_reg[31];
5608
    crc_shift_reg[1]  = crc_store_reg[0]   ^ crc_store_reg[31];
5609
    crc_shift_reg[2]  = crc_store_reg[1]   ^ crc_store_reg[31];
5610
    crc_shift_reg[3]  = crc_store_reg[2];
5611
    crc_shift_reg[4]  = crc_store_reg[3]   ^ crc_store_reg[31];
5612
    crc_shift_reg[5]  = crc_store_reg[4]   ^ crc_store_reg[31];
5613
    crc_shift_reg[6]  = crc_store_reg[5];
5614
    crc_shift_reg[7]  = crc_store_reg[6]   ^ crc_store_reg[31];
5615
    crc_shift_reg[8]  = crc_store_reg[7]   ^ crc_store_reg[31];
5616
    crc_shift_reg[9]  = crc_store_reg[8];
5617
    crc_shift_reg[10] = crc_store_reg[9]   ^ crc_store_reg[31];
5618
    crc_shift_reg[11] = crc_store_reg[10]  ^ crc_store_reg[31];
5619
    crc_shift_reg[12] = crc_store_reg[11]  ^ crc_store_reg[31];
5620
    crc_shift_reg[13] = crc_store_reg[12];
5621
    crc_shift_reg[14] = crc_store_reg[13];
5622
    crc_shift_reg[15] = crc_store_reg[14];
5623
    crc_shift_reg[16] = crc_store_reg[15]  ^ crc_store_reg[31];
5624
    crc_shift_reg[17] = crc_store_reg[16];
5625
    crc_shift_reg[18] = crc_store_reg[17];
5626
    crc_shift_reg[19] = crc_store_reg[18];
5627
    crc_shift_reg[20] = crc_store_reg[19];
5628
    crc_shift_reg[21] = crc_store_reg[20];
5629
    crc_shift_reg[22] = crc_store_reg[21]  ^ crc_store_reg[31];
5630
    crc_shift_reg[23] = crc_store_reg[22]  ^ crc_store_reg[31];
5631
    crc_shift_reg[24] = crc_store_reg[23];
5632
    crc_shift_reg[25] = crc_store_reg[24];
5633
    crc_shift_reg[26] = crc_store_reg[25]  ^ crc_store_reg[31];
5634
    crc_shift_reg[27] = crc_store_reg[26];
5635
    crc_shift_reg[28] = crc_store_reg[27];
5636
    crc_shift_reg[29] = crc_store_reg[28];
5637
    crc_shift_reg[30] = crc_store_reg[29];
5638
    crc_shift_reg[31] = crc_store_reg[30];
5639
    // wait for delta time
5640
    delta_t = !delta_t;
5641
 
5642
    // store previous data
5643
    crc_store_reg = crc_shift_reg;
5644
 
5645
    // put CRC out
5646
    case (bit_cnt)
5647
    33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 1:
5648
    begin
5649
      crc = crc_store_reg;
5650
      crc = {!crc[24], !crc[25], !crc[26], !crc[27], !crc[28], !crc[29], !crc[30], !crc[31],
5651
             !crc[16], !crc[17], !crc[18], !crc[19], !crc[20], !crc[21], !crc[22], !crc[23],
5652
             !crc[ 8], !crc[ 9], !crc[10], !crc[11], !crc[12], !crc[13], !crc[14], !crc[15],
5653
             !crc[ 0], !crc[ 1], !crc[ 2], !crc[ 3], !crc[ 4], !crc[ 5], !crc[ 6], !crc[ 7]};
5654
    end
5655
    default: crc = crc;
5656
    endcase
5657
 
5658
    // increment address and load new data
5659
#1;
5660
    if (word_cnt == 7)//4)
5661
    begin
5662
      // because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3]
5663
      load_reg[31:24] = eth_phy.tx_mem[addr_cnt];
5664
//      load_reg[31:24] = {load_reg[28], load_reg[29], load_reg[30], load_reg[31], 
5665
//                         load_reg[24], load_reg[25], load_reg[26], load_reg[27]};
5666
      addr_cnt = addr_cnt + 1;
5667
      load_reg[23:16] = eth_phy.tx_mem[addr_cnt];
5668
//      load_reg[23:16] = {load_reg[20], load_reg[21], load_reg[22], load_reg[23], 
5669
//                         load_reg[16], load_reg[17], load_reg[18], load_reg[19]};
5670
      addr_cnt = addr_cnt + 1;
5671
      load_reg[15: 8] = eth_phy.tx_mem[addr_cnt];
5672
//      load_reg[15: 8] = {load_reg[12], load_reg[13], load_reg[14], load_reg[15], 
5673
//                         load_reg[ 8], load_reg[ 9], load_reg[10], load_reg[11]};
5674
      addr_cnt = addr_cnt + 1;
5675
      load_reg[ 7: 0] = eth_phy.tx_mem[addr_cnt];
5676
//      load_reg[ 7: 0] = {load_reg[ 4], load_reg[ 5], load_reg[ 6], load_reg[ 7], 
5677
//                         load_reg[ 0], load_reg[ 1], load_reg[ 2], load_reg[ 3]};
5678
      addr_cnt = addr_cnt + 1;
5679
    end
5680
#1;
5681
    // set new load bit position
5682
    if(word_cnt == 31)
5683
      word_cnt = 16;
5684
    else if (word_cnt == 23)
5685
      word_cnt = 8;
5686
    else if (word_cnt == 15)
5687
      word_cnt = 0;
5688
    else if (word_cnt == 7)
5689
      word_cnt = 24;
5690
 
5691
//   if(word_cnt == 24)
5692
//     word_cnt = 31;
5693
//   else if (word_cnt == 28)
5694
//     word_cnt = 19;
5695
//   else if (word_cnt == 16)
5696
//     word_cnt = 23;
5697
//   else if (word_cnt == 20)
5698
//     word_cnt = 11;
5699
//   else if(word_cnt == 8)
5700
//     word_cnt = 15;
5701
//   else if (word_cnt == 12)
5702
//     word_cnt = 3;
5703
//   else if (word_cnt == 0)
5704
//     word_cnt = 7;
5705
//   else if (word_cnt == 4)
5706
//     word_cnt = 27;
5707
    else
5708
      word_cnt = word_cnt + 1;// - 1;
5709
#1;
5710
    // decrement bit counter
5711
    bit_cnt = bit_cnt - 1;
5712
#1;
5713
    // wait for delta time
5714
    delta_t = !delta_t;
5715
  end // while
5716
 
5717
  #1;
5718
end
5719
endtask // serial_crc_phy_tx
5720
 
5721
// serial CRC calculating for PHY RX
5722
task serial_crc_phy_rx;
5723
  input  [31:0] start_addr; // start address
5724
  input  [31:0] len; // length of frame in Bytes without CRC length
5725
  input         plus_dribble_nibble; // if length is longer for one nibble
5726
  output [31:0] crc;
5727
  reg    [21:0] addr_cnt; // only 22 address lines
5728
  integer       word_cnt;
5729
  integer       bit_cnt;
5730
  reg    [31:0] load_reg;
5731
  reg    [31:0] crc_shift_reg;
5732
  reg    [31:0] crc_store_reg;
5733
  reg           delta_t;
5734
begin
5735
  #1 addr_cnt = start_addr[21:0];
5736
  word_cnt = 24; // start of the frame
5737
  crc_shift_reg = 0;
5738
  delta_t = 0;
5739
  // length must include 4 bytes of ZEROs, to generate CRC
5740
  // get number of bits from Byte length (2^3 = 8)
5741
  if (plus_dribble_nibble)
5742
    bit_cnt = ((len + 4) << 3) + 3'h4; // one nibble longer
5743
  else
5744
    bit_cnt = ((len + 4) << 3);
5745
  load_reg[31:24] = eth_phy.rx_mem[addr_cnt];
5746
  addr_cnt = addr_cnt + 1;
5747
  load_reg[23:16] = eth_phy.rx_mem[addr_cnt];
5748
  addr_cnt = addr_cnt + 1;
5749
  load_reg[15:8]  = eth_phy.rx_mem[addr_cnt];
5750
  addr_cnt = addr_cnt + 1;
5751
  load_reg[7:0]   = eth_phy.rx_mem[addr_cnt];
5752
 
5753
  while (bit_cnt > 0)
5754
  begin
5755
    // wait for delta time
5756
    delta_t = !delta_t;
5757
    // store previous data
5758
    crc_store_reg = crc_shift_reg;
5759
    // shift data in
5760
    if(bit_cnt <= 32) // for additional 32 bits shift ZEROs in!
5761
     crc_shift_reg[0] = 1'b0               ^ crc_store_reg[31];
5762
    else
5763
     crc_shift_reg[0] = load_reg[word_cnt] ^ crc_store_reg[31];
5764
    crc_shift_reg[1]  = crc_store_reg[0]   ^ crc_store_reg[31];
5765
    crc_shift_reg[2]  = crc_store_reg[1]   ^ crc_store_reg[31];
5766
    crc_shift_reg[3]  = crc_store_reg[2];
5767
    crc_shift_reg[4]  = crc_store_reg[3]   ^ crc_store_reg[31];
5768
    crc_shift_reg[5]  = crc_store_reg[4]   ^ crc_store_reg[31];
5769
    crc_shift_reg[6]  = crc_store_reg[5];
5770
    crc_shift_reg[7]  = crc_store_reg[6]   ^ crc_store_reg[31];
5771
    crc_shift_reg[8]  = crc_store_reg[7]   ^ crc_store_reg[31];
5772
    crc_shift_reg[9]  = crc_store_reg[8];
5773
    crc_shift_reg[10] = crc_store_reg[9]   ^ crc_store_reg[31];
5774
    crc_shift_reg[11] = crc_store_reg[10]  ^ crc_store_reg[31];
5775
    crc_shift_reg[12] = crc_store_reg[11]  ^ crc_store_reg[31];
5776
    crc_shift_reg[13] = crc_store_reg[12];
5777
    crc_shift_reg[14] = crc_store_reg[13];
5778
    crc_shift_reg[15] = crc_store_reg[14];
5779
    crc_shift_reg[16] = crc_store_reg[15]  ^ crc_store_reg[31];
5780
    crc_shift_reg[17] = crc_store_reg[16];
5781
    crc_shift_reg[18] = crc_store_reg[17];
5782
    crc_shift_reg[19] = crc_store_reg[18];
5783
    crc_shift_reg[20] = crc_store_reg[19];
5784
    crc_shift_reg[21] = crc_store_reg[20];
5785
    crc_shift_reg[22] = crc_store_reg[21]  ^ crc_store_reg[31];
5786
    crc_shift_reg[23] = crc_store_reg[22]  ^ crc_store_reg[31];
5787
    crc_shift_reg[24] = crc_store_reg[23];
5788
    crc_shift_reg[25] = crc_store_reg[24];
5789
    crc_shift_reg[26] = crc_store_reg[25]  ^ crc_store_reg[31];
5790
    crc_shift_reg[27] = crc_store_reg[26];
5791
    crc_shift_reg[28] = crc_store_reg[27];
5792
    crc_shift_reg[29] = crc_store_reg[28];
5793
    crc_shift_reg[30] = crc_store_reg[29];
5794
    crc_shift_reg[31] = crc_store_reg[30];
5795
    // wait for delta time
5796
    delta_t = !delta_t;
5797
    // increment address and load new data
5798
    if (word_cnt == 7)
5799
    begin
5800
      addr_cnt = addr_cnt + 1;
5801
      load_reg[31:24] = eth_phy.rx_mem[addr_cnt];
5802
      addr_cnt = addr_cnt + 1;
5803
      load_reg[23:16] = eth_phy.rx_mem[addr_cnt];
5804
      addr_cnt = addr_cnt + 1;
5805
      load_reg[15:8]  = eth_phy.rx_mem[addr_cnt];
5806
      addr_cnt = addr_cnt + 1;
5807
      load_reg[7:0]   = eth_phy.rx_mem[addr_cnt];
5808
    end
5809
    // set new load bit position
5810
    if(word_cnt == 31)
5811
      word_cnt = 16;
5812
    else if (word_cnt == 23)
5813
      word_cnt = 8;
5814
    else if (word_cnt == 15)
5815
      word_cnt = 0;
5816
    else if (word_cnt == 7)
5817
      word_cnt = 24;
5818
    else
5819
      word_cnt = word_cnt + 1;
5820
    // decrement bit counter
5821
    bit_cnt = bit_cnt - 1;
5822
    // wait for delta time
5823
    delta_t = !delta_t;
5824
  end // while
5825
 
5826
  // put CRC out
5827
  crc = crc_shift_reg;
5828
  #1;
5829
end
5830
endtask // serial_crc_phy_rx
5831
 
5832
// serial CRC checking for MAC
5833
task serial_crc_mac;
5834
  input  [31:0] start_addr; // start address
5835
  input  [31:0] len; // length of frame in Bytes without CRC length
5836
  input         plus_dribble_nibble; // if length is longer for one nibble
5837
  output [31:0] crc;
5838
  reg    [19:0] addr_cnt; // only 20 address lines
5839
  integer       word_cnt;
5840
  integer       bit_cnt;
5841
  reg    [31:0] load_reg;
5842
  reg    [31:0] crc_shift_reg;
5843
  reg    [31:0] crc_store_reg;
5844
  reg           delta_t;
5845
begin
5846
  #1 addr_cnt = start_addr[19:0];
5847
  // set starting point depending with which byte frame starts (e.g. if addr_cnt[1:0] == 0, then
5848
  //   MSB of the packet must be written to the LSB of Big ENDIAN Word [31:24])
5849
  if (addr_cnt[1:0] == 2'h1)
5850
    word_cnt = 16; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
5851
  else if (addr_cnt[1:0] == 2'h2)
5852
    word_cnt = 8; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
5853
  else if (addr_cnt[1:0] == 2'h3)
5854
    word_cnt = 0; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
5855
  else
5856
    word_cnt = 24; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
5857
 
5858
  crc_shift_reg = 0;
5859
  delta_t = 0;
5860
  // length must include 4 bytes of ZEROs, to generate CRC
5861
  // get number of bits from Byte length (2^3 = 8)
5862
  if (plus_dribble_nibble)
5863
    bit_cnt = ((len + 4) << 3) + 3'h4; // one nibble longer
5864
  else
5865
    bit_cnt = ((len + 4) << 3);
5866
  load_reg = wb_slave.wb_memory[{12'h0, addr_cnt}];
5867
 
5868
  while (bit_cnt > 0)
5869
  begin
5870
    // wait for delta time
5871
    delta_t = !delta_t;
5872
    // store previous data
5873
    crc_store_reg = crc_shift_reg;
5874
    // shift data in
5875
    if(bit_cnt <= 32) // for additional 32 bits shift ZEROs in!
5876
     crc_shift_reg[0] = 1'b0               ^ crc_store_reg[31];
5877
    else
5878
     crc_shift_reg[0] = load_reg[word_cnt] ^ crc_store_reg[31];
5879
    crc_shift_reg[1]  = crc_store_reg[0]   ^ crc_store_reg[31];
5880
    crc_shift_reg[2]  = crc_store_reg[1]   ^ crc_store_reg[31];
5881
    crc_shift_reg[3]  = crc_store_reg[2];
5882
    crc_shift_reg[4]  = crc_store_reg[3]   ^ crc_store_reg[31];
5883
    crc_shift_reg[5]  = crc_store_reg[4]   ^ crc_store_reg[31];
5884
    crc_shift_reg[6]  = crc_store_reg[5];
5885
    crc_shift_reg[7]  = crc_store_reg[6]   ^ crc_store_reg[31];
5886
    crc_shift_reg[8]  = crc_store_reg[7]   ^ crc_store_reg[31];
5887
    crc_shift_reg[9]  = crc_store_reg[8];
5888
    crc_shift_reg[10] = crc_store_reg[9]   ^ crc_store_reg[31];
5889
    crc_shift_reg[11] = crc_store_reg[10]  ^ crc_store_reg[31];
5890
    crc_shift_reg[12] = crc_store_reg[11]  ^ crc_store_reg[31];
5891
    crc_shift_reg[13] = crc_store_reg[12];
5892
    crc_shift_reg[14] = crc_store_reg[13];
5893
    crc_shift_reg[15] = crc_store_reg[14];
5894
    crc_shift_reg[16] = crc_store_reg[15]  ^ crc_store_reg[31];
5895
    crc_shift_reg[17] = crc_store_reg[16];
5896
    crc_shift_reg[18] = crc_store_reg[17];
5897
    crc_shift_reg[19] = crc_store_reg[18];
5898
    crc_shift_reg[20] = crc_store_reg[19];
5899
    crc_shift_reg[21] = crc_store_reg[20];
5900
    crc_shift_reg[22] = crc_store_reg[21]  ^ crc_store_reg[31];
5901
    crc_shift_reg[23] = crc_store_reg[22]  ^ crc_store_reg[31];
5902
    crc_shift_reg[24] = crc_store_reg[23];
5903
    crc_shift_reg[25] = crc_store_reg[24];
5904
    crc_shift_reg[26] = crc_store_reg[25]  ^ crc_store_reg[31];
5905
    crc_shift_reg[27] = crc_store_reg[26];
5906
    crc_shift_reg[28] = crc_store_reg[27];
5907
    crc_shift_reg[29] = crc_store_reg[28];
5908
    crc_shift_reg[30] = crc_store_reg[29];
5909
    crc_shift_reg[31] = crc_store_reg[30];
5910
    // wait for delta time
5911
    delta_t = !delta_t;
5912
    // increment address and load new data for Big ENDIAN Bytes (Litle ENDIAN bits)
5913
    if (word_cnt == 7)
5914
    begin
5915
      addr_cnt = addr_cnt + 4;
5916
      load_reg = wb_slave.wb_memory[{12'h0, addr_cnt}];
5917
    end
5918
    // set new load bit position for Big ENDIAN Bytes (Litle ENDIAN bits)
5919
    if(word_cnt == 31)
5920
      word_cnt = 16;
5921
    else if (word_cnt == 23)
5922
      word_cnt = 8;
5923
    else if (word_cnt == 15)
5924
      word_cnt = 0;
5925
    else if (word_cnt == 7)
5926
      word_cnt = 24;
5927
    else
5928
      word_cnt = word_cnt + 1;
5929
    // decrement bit counter
5930
    bit_cnt = bit_cnt - 1;
5931
    // wait for delta time
5932
    delta_t = !delta_t;
5933
  end // while
5934
 
5935
  // put CRC out
5936
  crc = crc_shift_reg;
5937
  #1;
5938
end
5939
endtask // serial_crc_mac
5940
 
5941
//////////////////////////////////////////////////////////////
5942
// MIIM Basic tasks
5943
//////////////////////////////////////////////////////////////
5944
 
5945
task reset_mii; //  MII module
5946
  reg [31:0] tmp;
5947
  reg [31:0] tmp_no_rst;
5948
begin
5949
  // read MII mode register first
5950
  wbm_read(`ETH_MIIMODER, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5951
  // set reset bit - write back to MII mode register with RESET bit
5952
  wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_RST | tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5953
  // clear reset bit - write back to MII mode register without RESET bit
5954
  tmp_no_rst = `ETH_MIIMODER_RST;
5955
  tmp_no_rst = ~tmp_no_rst;
5956
  wbm_write(`ETH_MIIMODER, (tmp_no_rst & tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5957
end
5958
endtask // reset_mii
5959
 
5960
task mii_set_clk_div; // set clock divider for MII clock
5961
  input [7:0]  clk_div;
5962
begin
5963
  // MII mode register
5964
  wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_CLKDIV & clk_div), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5965
end
5966
endtask // mii_set_clk_div
5967
 
5968
 
5969
task check_mii_busy; // MII - check if BUSY
5970
  reg [31:0] tmp;
5971
begin
5972
  @(posedge wb_clk);
5973
  // MII read status register
5974
  wbm_read(`ETH_MIISTATUS, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5975
  while(tmp[`ETH_MIISTATUS_BUSY] !== 1'b0) //`ETH_MIISTATUS_BUSY
5976
  begin
5977
    @(posedge wb_clk);
5978
    wbm_read(`ETH_MIISTATUS, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5979
  end
5980
end
5981
endtask // check_mii_busy
5982
 
5983
 
5984
task check_mii_scan_valid; // MII - check if SCAN data are valid
5985
  reg [31:0] tmp;
5986
begin
5987
  @(posedge wb_clk);
5988
  // MII read status register
5989
  wbm_read(`ETH_MIISTATUS, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5990
  while(tmp[`ETH_MIISTATUS_NVALID] !== 1'b0) //`ETH_MIISTATUS_NVALID
5991
  begin
5992
    @(posedge wb_clk);
5993
    wbm_read(`ETH_MIISTATUS, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5994
  end
5995
end
5996
endtask // check_mii_scan_valid
5997
 
5998
 
5999
task mii_write_req; // requests write to MII
6000
  input [4:0]  phy_addr;
6001
  input [4:0]  reg_addr;
6002
  input [15:0] data_in;
6003
begin
6004
  // MII address, PHY address = 1, command register address = 0
6005
  wbm_write(`ETH_MIIADDRESS, (`ETH_MIIADDRESS_FIAD & phy_addr) | (`ETH_MIIADDRESS_RGAD & (reg_addr << 8)),
6006
            4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6007
  // MII TX data
6008
  wbm_write(`ETH_MIITX_DATA, {16'h0000, data_in}, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6009
  // MII command
6010
  wbm_write(`ETH_MIICOMMAND, `ETH_MIICOMMAND_WCTRLDATA, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6011
  @(posedge wb_clk);
6012
end
6013
endtask // mii_write_req
6014
 
6015
 
6016
task mii_read_req; // requests read from MII
6017
  input [4:0]  phy_addr;
6018
  input [4:0]  reg_addr;
6019
begin
6020
  // MII address, PHY address = 1, command register address = 0
6021
  wbm_write(`ETH_MIIADDRESS, (`ETH_MIIADDRESS_FIAD & phy_addr) | (`ETH_MIIADDRESS_RGAD & (reg_addr << 8)),
6022
            4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6023
  // MII command
6024
  wbm_write(`ETH_MIICOMMAND, `ETH_MIICOMMAND_RSTAT, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6025
  @(posedge wb_clk);
6026
end
6027
endtask // mii_read_req
6028
 
6029
 
6030
task mii_scan_req; // requests scan from MII
6031
  input [4:0]  phy_addr;
6032
  input [4:0]  reg_addr;
6033
begin
6034
  // MII address, PHY address = 1, command register address = 0
6035
  wbm_write(`ETH_MIIADDRESS, (`ETH_MIIADDRESS_FIAD & phy_addr) | (`ETH_MIIADDRESS_RGAD & (reg_addr << 8)),
6036
            4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6037
  // MII command
6038
  wbm_write(`ETH_MIICOMMAND, `ETH_MIICOMMAND_SCANSTAT, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6039
  @(posedge wb_clk);
6040
end
6041
endtask // mii_scan_req
6042
 
6043
 
6044
task mii_scan_finish; // finish scan from MII
6045
begin
6046
  // MII command
6047
  wbm_write(`ETH_MIICOMMAND, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6048
  @(posedge wb_clk);
6049
end
6050
endtask // mii_scan_finish
6051
 
6052
//////////////////////////////////////////////////////////////
6053
// Log files and memory tasks
6054
//////////////////////////////////////////////////////////////
6055
 
6056
task clear_memories;
6057
  reg    [22:0]  adr_i;
6058
  reg            delta_t;
6059
begin
6060
  delta_t = 0;
6061
  for (adr_i = 0; adr_i < 4194304; adr_i = adr_i + 1)
6062
  begin
6063
    eth_phy.rx_mem[adr_i[21:0]] = 0;
6064
    eth_phy.tx_mem[adr_i[21:0]] = 0;
6065
    wb_slave.wb_memory[adr_i[21:2]] = 0;
6066
    delta_t = !delta_t;
6067
  end
6068
end
6069
endtask // clear_memories
6070
 
6071
task test_note;
6072
  input [799:0] test_note ;
6073
  reg   [799:0] display_note ;
6074
begin
6075
  display_note = test_note;
6076
  while ( display_note[799:792] == 0 )
6077
    display_note = display_note << 8 ;
6078
  $fdisplay( tb_log_file, " " ) ;
6079
  $fdisplay( tb_log_file, "NOTE: %s", display_note ) ;
6080
  $fdisplay( tb_log_file, " " ) ;
6081
end
6082
endtask // test_note
6083
 
6084
task test_heading;
6085
  input [799:0] test_heading ;
6086
  reg   [799:0] display_test ;
6087
begin
6088
  display_test = test_heading;
6089
  while ( display_test[799:792] == 0 )
6090
    display_test = display_test << 8 ;
6091
  $fdisplay( tb_log_file, "  ***************************************************************************************" ) ;
6092
  $fdisplay( tb_log_file, "  ***************************************************************************************" ) ;
6093
  $fdisplay( tb_log_file, "  Heading: %s", display_test ) ;
6094
  $fdisplay( tb_log_file, "  ***************************************************************************************" ) ;
6095
  $fdisplay( tb_log_file, "  ***************************************************************************************" ) ;
6096
  $fdisplay( tb_log_file, " " ) ;
6097
end
6098
endtask // test_heading
6099
 
6100
 
6101
task test_fail ;
6102
  input [7999:0] failure_reason ;
6103
//  reg   [8007:0] display_failure ;
6104
  reg   [7999:0] display_failure ;
6105
  reg   [799:0] display_test ;
6106
begin
6107
  tests_failed = tests_failed + 1 ;
6108
 
6109
  display_failure = failure_reason; // {failure_reason, "!"} ;
6110
  while ( display_failure[7999:7992] == 0 )
6111
    display_failure = display_failure << 8 ;
6112
 
6113
  display_test = test_name ;
6114
  while ( display_test[799:792] == 0 )
6115
    display_test = display_test << 8 ;
6116
 
6117
  $fdisplay( tb_log_file, "    *************************************************************************************" ) ;
6118
  $fdisplay( tb_log_file, "    At time: %t ", $time ) ;
6119
  $fdisplay( tb_log_file, "    Test: %s", display_test ) ;
6120
  $fdisplay( tb_log_file, "    *FAILED* because") ;
6121
  $fdisplay( tb_log_file, "    %s", display_failure ) ;
6122
  $fdisplay( tb_log_file, "    *************************************************************************************" ) ;
6123
  $fdisplay( tb_log_file, " " ) ;
6124
 
6125
 `ifdef STOP_ON_FAILURE
6126
    #20 $stop ;
6127
 `endif
6128
end
6129
endtask // test_fail
6130
 
6131
 
6132
task test_ok ;
6133
  reg [799:0] display_test ;
6134
begin
6135
  tests_successfull = tests_successfull + 1 ;
6136
 
6137
  display_test = test_name ;
6138
  while ( display_test[799:792] == 0 )
6139
    display_test = display_test << 8 ;
6140
 
6141
  $fdisplay( tb_log_file, "    *************************************************************************************" ) ;
6142
  $fdisplay( tb_log_file, "    At time: %t ", $time ) ;
6143
  $fdisplay( tb_log_file, "    Test: %s", display_test ) ;
6144
  $fdisplay( tb_log_file, "    reported *SUCCESSFULL*! ") ;
6145
  $fdisplay( tb_log_file, "    *************************************************************************************" ) ;
6146
  $fdisplay( tb_log_file, " " ) ;
6147
end
6148
endtask // test_ok
6149
 
6150
 
6151
task test_summary;
6152
begin
6153
  $fdisplay(tb_log_file, "**************************** Ethernet MAC test summary **********************************") ;
6154
  $fdisplay(tb_log_file, "Tests performed:   %d", tests_successfull + tests_failed) ;
6155
  $fdisplay(tb_log_file, "Failed tests   :   %d", tests_failed) ;
6156
  $fdisplay(tb_log_file, "Successfull tests: %d", tests_successfull) ;
6157
  $fdisplay(tb_log_file, "**************************** Ethernet MAC test summary **********************************") ;
6158
  $fclose(tb_log_file) ;
6159
end
6160
endtask // test_summary
6161
 
6162
 
6163 116 mohor
endmodule

powered by: WebSVN 2.1.0

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