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

Subversion Repositories ethmac

[/] [ethmac/] [tags/] [rel_11/] [bench/] [verilog/] [tb_ethernet.v] - Blame information for rev 181

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

powered by: WebSVN 2.1.0

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