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

Subversion Repositories ethmac

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

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

powered by: WebSVN 2.1.0

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