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

Subversion Repositories ethmac

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

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

powered by: WebSVN 2.1.0

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