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 194

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

powered by: WebSVN 2.1.0

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