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

Subversion Repositories ethmac

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

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

powered by: WebSVN 2.1.0

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