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

Subversion Repositories ethmac

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

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

powered by: WebSVN 2.1.0

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