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

Subversion Repositories ethmac

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

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 209 tadejm
// Revision 1.15  2002/09/20 14:29:12  tadej
46
// Full duplex tests modified and testbench bug repaired.
47
//
48 194 tadej
// Revision 1.14  2002/09/18 17:56:38  tadej
49
// Some additional reports added
50
//
51 192 tadej
// Revision 1.13  2002/09/16 17:53:49  tadej
52
// Full duplex test improved.
53
//
54 182 tadej
// Revision 1.12  2002/09/16 15:10:42  mohor
55
// MIIM test look better.
56
//
57 181 mohor
// Revision 1.11  2002/09/13 19:18:04  mohor
58
// Bench outputs data to display every 128 bytes.
59
//
60 180 mohor
// Revision 1.10  2002/09/13 18:44:29  mohor
61
// Beautiful tests merget together
62
//
63 179 mohor
// Revision 1.9  2002/09/13 18:41:45  mohor
64
// Rearanged testcases
65
//
66 178 mohor
// Revision 1.8  2002/09/13 14:50:15  mohor
67
// Bug in MIIM fixed.
68
//
69 177 mohor
// Revision 1.7  2002/09/13 12:29:14  mohor
70
// Headers changed.
71
//
72 170 mohor
// Revision 1.6  2002/09/13 11:57:20  mohor
73
// New testbench. Thanks to Tadej M - "The Spammer".
74
//
75 121 mohor
// Revision 1.2  2002/07/19 14:02:47  mohor
76
// Clock mrx_clk set to 2.5 MHz.
77
//
78 117 mohor
// Revision 1.1  2002/07/19 13:57:53  mohor
79
// Testing environment also includes traffic cop, memory interface and host
80
// interface.
81 116 mohor
//
82
//
83
//
84
//
85 117 mohor
//
86 116 mohor
 
87
 
88 169 mohor
`include "eth_phy_defines.v"
89
`include "wb_model_defines.v"
90 116 mohor
`include "tb_eth_defines.v"
91
`include "eth_defines.v"
92
`include "timescale.v"
93
 
94
module tb_ethernet();
95
 
96
 
97 169 mohor
reg           wb_clk;
98
reg           wb_rst;
99
wire          wb_int;
100 116 mohor
 
101 169 mohor
wire          mtx_clk;  // This goes to PHY
102
wire          mrx_clk;  // This goes to PHY
103 116 mohor
 
104
wire   [3:0]  MTxD;
105
wire          MTxEn;
106
wire          MTxErr;
107
 
108 169 mohor
wire   [3:0]  MRxD;     // This goes to PHY
109
wire          MRxDV;    // This goes to PHY
110
wire          MRxErr;   // This goes to PHY
111
wire          MColl;    // This goes to PHY
112
wire          MCrs;     // This goes to PHY
113 116 mohor
 
114
wire          Mdi_I;
115
wire          Mdo_O;
116
wire          Mdo_OE;
117 169 mohor
tri           Mdio_IO;
118 116 mohor
wire          Mdc_O;
119
 
120
 
121 169 mohor
parameter Tp = 1;
122 116 mohor
 
123 121 mohor
 
124 116 mohor
// Ethernet Slave Interface signals
125 169 mohor
wire [31:0] eth_sl_wb_adr;
126 116 mohor
wire [31:0] eth_sl_wb_adr_i, eth_sl_wb_dat_o, eth_sl_wb_dat_i;
127
wire  [3:0] eth_sl_wb_sel_i;
128
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;
129
 
130
// Ethernet Master Interface signals
131
wire [31:0] eth_ma_wb_adr_o, eth_ma_wb_dat_i, eth_ma_wb_dat_o;
132
wire  [3:0] eth_ma_wb_sel_o;
133
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;
134
 
135
 
136
 
137
 
138
// Connecting Ethernet top module
139 169 mohor
eth_top eth_top
140 116 mohor
(
141
  // WISHBONE common
142 169 mohor
  .wb_clk_i(wb_clk),              .wb_rst_i(wb_rst),
143 116 mohor
 
144
  // WISHBONE slave
145 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),
146
  .wb_cyc_i(eth_sl_wb_cyc_i),       .wb_stb_i(eth_sl_wb_stb_i),   .wb_ack_o(eth_sl_wb_ack_o),
147
  .wb_err_o(eth_sl_wb_err_o),       .wb_dat_i(eth_sl_wb_dat_i),   .wb_dat_o(eth_sl_wb_dat_o),
148 116 mohor
 
149
  // WISHBONE master
150
  .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),
151
  .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),
152
  .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),
153
 
154
  //TX
155
  .mtx_clk_pad_i(mtx_clk), .mtxd_pad_o(MTxD), .mtxen_pad_o(MTxEn), .mtxerr_pad_o(MTxErr),
156
 
157
  //RX
158
  .mrx_clk_pad_i(mrx_clk), .mrxd_pad_i(MRxD), .mrxdv_pad_i(MRxDV), .mrxerr_pad_i(MRxErr),
159
  .mcoll_pad_i(MColl),    .mcrs_pad_i(MCrs),
160
 
161
  // MIIM
162
  .mdc_pad_o(Mdc_O), .md_pad_i(Mdi_I), .md_pad_o(Mdo_O), .md_padoe_o(Mdo_OE),
163
 
164 169 mohor
  .int_o(wb_int)
165 116 mohor
);
166
 
167
 
168
 
169 169 mohor
// Connecting Ethernet PHY Module
170
assign Mdio_IO = Mdo_OE ? Mdo_O : 1'bz ;
171
assign Mdi_I   = Mdio_IO;
172
integer phy_log_file_desc;
173
 
174
eth_phy eth_phy
175 116 mohor
(
176 169 mohor
  // WISHBONE reset
177
  .m_rst_n_i(!wb_rst),
178 116 mohor
 
179 169 mohor
  // MAC TX
180
  .mtx_clk_o(mtx_clk),    .mtxd_i(MTxD),    .mtxen_i(MTxEn),    .mtxerr_i(MTxErr),
181
 
182
  // MAC RX
183
  .mrx_clk_o(mrx_clk),    .mrxd_o(MRxD),    .mrxdv_o(MRxDV),    .mrxerr_o(MRxErr),
184
  .mcoll_o(MColl),        .mcrs_o(MCrs),
185
 
186
  // MIIM
187
  .mdc_i(Mdc_O),          .md_io(Mdio_IO),
188
 
189
  // SYSTEM
190
  .phy_log(phy_log_file_desc)
191 116 mohor
);
192
 
193
 
194 169 mohor
 
195
// Connecting WB Master as Host Interface
196
integer host_log_file_desc;
197
 
198
WB_MASTER_BEHAVIORAL wb_master
199 116 mohor
(
200 169 mohor
    .CLK_I(wb_clk),
201
    .RST_I(wb_rst),
202
    .TAG_I({`WB_TAG_WIDTH{1'b0}}),
203
    .TAG_O(),
204
    .ACK_I(eth_sl_wb_ack_o),
205
    .ADR_O(eth_sl_wb_adr), // only eth_sl_wb_adr_i[11:2] used
206
    .CYC_O(eth_sl_wb_cyc_i),
207
    .DAT_I(eth_sl_wb_dat_o),
208
    .DAT_O(eth_sl_wb_dat_i),
209
    .ERR_I(eth_sl_wb_err_o),
210
    .RTY_I(1'b0),  // inactive (1'b0)
211
    .SEL_O(eth_sl_wb_sel_i),
212
    .STB_O(eth_sl_wb_stb_i),
213
    .WE_O (eth_sl_wb_we_i),
214
    .CAB_O()       // NOT USED for now!
215
);
216
 
217
assign eth_sl_wb_adr_i = {20'h0, eth_sl_wb_adr[11:2], 2'h0};
218
 
219
 
220
 
221
// Connecting WB Slave as Memory Interface Module
222
integer memory_log_file_desc;
223
 
224
WB_SLAVE_BEHAVIORAL wb_slave
225
(
226
    .CLK_I(wb_clk),
227
    .RST_I(wb_rst),
228
    .ACK_O(eth_ma_wb_ack_i),
229
    .ADR_I(eth_ma_wb_adr_o),
230
    .CYC_I(eth_ma_wb_cyc_o),
231
    .DAT_O(eth_ma_wb_dat_i),
232
    .DAT_I(eth_ma_wb_dat_o),
233
    .ERR_O(eth_ma_wb_err_i),
234
    .RTY_O(),      // NOT USED for now!
235
    .SEL_I(eth_ma_wb_sel_o),
236
    .STB_I(eth_ma_wb_stb_o),
237
    .WE_I (eth_ma_wb_we_o),
238
    .CAB_I(1'b0)   // inactive (1'b0)
239
);
240
 
241
 
242
 
243
// Connecting WISHBONE Bus Monitors to ethernet master and slave interfaces
244
integer wb_s_mon_log_file_desc ;
245
integer wb_m_mon_log_file_desc ;
246
 
247
WB_BUS_MON wb_eth_slave_bus_mon
248
(
249 116 mohor
  // WISHBONE common
250 169 mohor
  .CLK_I(wb_clk),
251
  .RST_I(wb_rst),
252 116 mohor
 
253 169 mohor
  // WISHBONE slave
254
  .ACK_I(eth_sl_wb_ack_o),
255
  .ADDR_O({20'h0, eth_sl_wb_adr_i[11:2], 2'b0}),
256
  .CYC_O(eth_sl_wb_cyc_i),
257
  .DAT_I(eth_sl_wb_dat_o),
258
  .DAT_O(eth_sl_wb_dat_i),
259
  .ERR_I(eth_sl_wb_err_o),
260
  .RTY_I(1'b0),
261
  .SEL_O(eth_sl_wb_sel_i),
262
  .STB_O(eth_sl_wb_stb_i),
263
  .WE_O (eth_sl_wb_we_i),
264
  .TAG_I({`WB_TAG_WIDTH{1'b0}}),
265
  .TAG_O(),
266
  .CAB_O(1'b0),
267
  .log_file_desc (wb_s_mon_log_file_desc)
268
);
269
 
270
WB_BUS_MON wb_eth_master_bus_mon
271
(
272
  // WISHBONE common
273
  .CLK_I(wb_clk),
274
  .RST_I(wb_rst),
275
 
276 116 mohor
  // WISHBONE master
277 169 mohor
  .ACK_I(eth_ma_wb_ack_i),
278
  .ADDR_O(eth_ma_wb_adr_o),
279
  .CYC_O(eth_ma_wb_cyc_o),
280
  .DAT_I(eth_ma_wb_dat_i),
281
  .DAT_O(eth_ma_wb_dat_o),
282
  .ERR_I(eth_ma_wb_err_i),
283
  .RTY_I(1'b0),
284
  .SEL_O(eth_ma_wb_sel_o),
285
  .STB_O(eth_ma_wb_stb_o),
286
  .WE_O (eth_ma_wb_we_o),
287
  .TAG_I({`WB_TAG_WIDTH{1'b0}}),
288
  .TAG_O(),
289
  .CAB_O(1'b0),
290
  .log_file_desc(wb_m_mon_log_file_desc)
291 116 mohor
);
292
 
293
 
294
 
295 169 mohor
reg         StartTB;
296
integer     tb_log_file;
297 116 mohor
 
298 169 mohor
initial
299
begin
300
  tb_log_file = $fopen("../log/eth_tb.log");
301
  if (tb_log_file < 2)
302
  begin
303
    $display("*E Could not open/create testbench log file in ../log/ directory!");
304
    $finish;
305
  end
306
  $fdisplay(tb_log_file, "========================== ETHERNET IP Core Testbench results ===========================");
307
  $fdisplay(tb_log_file, " ");
308 116 mohor
 
309 169 mohor
  phy_log_file_desc = $fopen("../log/eth_tb_phy.log");
310
  if (phy_log_file_desc < 2)
311
  begin
312
    $fdisplay(tb_log_file, "*E Could not open/create eth_tb_phy.log file in ../log/ directory!");
313
    $finish;
314
  end
315
  $fdisplay(phy_log_file_desc, "================ PHY Module  Testbench access log ================");
316
  $fdisplay(phy_log_file_desc, " ");
317
 
318
  memory_log_file_desc = $fopen("../log/eth_tb_memory.log");
319
  if (memory_log_file_desc < 2)
320
  begin
321
    $fdisplay(tb_log_file, "*E Could not open/create eth_tb_memory.log file in ../log/ directory!");
322
    $finish;
323
  end
324
  $fdisplay(memory_log_file_desc, "=============== MEMORY Module Testbench access log ===============");
325
  $fdisplay(memory_log_file_desc, " ");
326
 
327
  host_log_file_desc = $fopen("../log/eth_tb_host.log");
328
  if (host_log_file_desc < 2)
329
  begin
330
    $fdisplay(tb_log_file, "*E Could not open/create eth_tb_host.log file in ../log/ directory!");
331
    $finish;
332
  end
333
  $fdisplay(host_log_file_desc, "================ HOST Module Testbench access log ================");
334
  $fdisplay(host_log_file_desc, " ");
335
 
336
  wb_s_mon_log_file_desc = $fopen("../log/eth_tb_wb_s_mon.log");
337
  if (wb_s_mon_log_file_desc < 2)
338
  begin
339
    $fdisplay(tb_log_file, "*E Could not open/create eth_tb_wb_s_mon.log file in ../log/ directory!");
340
    $finish;
341
  end
342
  $fdisplay(wb_s_mon_log_file_desc, "============== WISHBONE Slave Bus Monitor error log ==============");
343
  $fdisplay(wb_s_mon_log_file_desc, " ");
344
  $fdisplay(wb_s_mon_log_file_desc, "   Only ERRONEOUS conditions are logged !");
345
  $fdisplay(wb_s_mon_log_file_desc, " ");
346
 
347
  wb_m_mon_log_file_desc = $fopen("../log/eth_tb_wb_m_mon.log");
348
  if (wb_m_mon_log_file_desc < 2)
349
  begin
350
    $fdisplay(tb_log_file, "*E Could not open/create eth_tb_wb_m_mon.log file in ../log/ directory!");
351
    $finish;
352
  end
353
  $fdisplay(wb_m_mon_log_file_desc, "============= WISHBONE Master Bus Monitor  error log =============");
354
  $fdisplay(wb_m_mon_log_file_desc, " ");
355
  $fdisplay(wb_m_mon_log_file_desc, "   Only ERRONEOUS conditions are logged !");
356
  $fdisplay(wb_m_mon_log_file_desc, " ");
357
 
358
  // Clear memories
359
  clear_memories;
360
 
361
  // Reset pulse
362
  wb_rst =  1'b1;
363
  #423 wb_rst =  1'b0;
364
  #423 StartTB  =  1'b1;
365
end
366
 
367
 
368
 
369
// Generating wb_clk clock
370 116 mohor
initial
371
begin
372 169 mohor
  wb_clk=0;
373
//  forever #2.5 wb_clk = ~wb_clk;  // 2*2.5 ns -> 200.0 MHz    
374 209 tadejm
  forever #5 wb_clk = ~wb_clk;  // 2*5 ns -> 100.0 MHz    
375 169 mohor
//  forever #10 wb_clk = ~wb_clk;  // 2*10 ns -> 50.0 MHz    
376
//  forever #12.5 wb_clk = ~wb_clk;  // 2*12.5 ns -> 40 MHz    
377
//  forever #15 wb_clk = ~wb_clk;  // 2*10 ns -> 33.3 MHz    
378 209 tadejm
//  forever #20 wb_clk = ~wb_clk;  // 2*20 ns -> 25 MHz    
379 169 mohor
//  forever #25 wb_clk = ~wb_clk;  // 2*25 ns -> 20.0 MHz
380
//  forever #31.25 wb_clk = ~wb_clk;  // 2*31.25 ns -> 16.0 MHz    
381
//  forever #50 wb_clk = ~wb_clk;  // 2*50 ns -> 10.0 MHz
382
//  forever #55 wb_clk = ~wb_clk;  // 2*55 ns ->  9.1 MHz    
383 116 mohor
end
384
 
385
 
386
 
387 169 mohor
integer      tests_successfull;
388
integer      tests_failed;
389
reg [799:0]  test_name; // used for tb_log_file
390 121 mohor
 
391 169 mohor
reg   [3:0]  wbm_init_waits; // initial wait cycles between CYC_O and STB_O of WB Master
392
reg   [3:0]  wbm_subseq_waits; // subsequent wait cycles between STB_Os of WB Master
393
reg   [2:0]  wbs_waits; // wait cycles befor WB Slave responds
394
reg   [7:0]  wbs_retries; // if RTY response, then this is the number of retries before ACK
395
 
396 116 mohor
initial
397
begin
398 169 mohor
  wait(StartTB);  // Start of testbench
399
 
400
  // Initial global values
401
  tests_successfull = 0;
402
  tests_failed = 0;
403
 
404
  wbm_init_waits = 4'h1;
405
  wbm_subseq_waits = 4'h3;
406
  wbs_waits = 4'h1;
407
  wbs_retries = 8'h2;
408
  wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
409
 
410
 
411
  //  Call tests
412
  //  ----------
413 194 tadej
//    test_access_to_mac_reg(0, 3);           // 0 - 3
414
//    test_mii(0, 17);                        // 0 - 17
415 169 mohor
  test_note("PHY generates ideal Carrier sense and Collision signals for following tests");
416
  eth_phy.carrier_sense_real_delay(0);
417 209 tadejm
    test_mac_full_duplex_transmit(0, 21);    // 0 - (21)
418
    test_mac_full_duplex_receive(0, 5);
419
//    test_mac_full_duplex_flow(0, 0);
420 169 mohor
 
421
  test_note("PHY generates 'real' Carrier sense and Collision signals for following tests");
422
  eth_phy.carrier_sense_real_delay(1);
423
 
424
 
425
  // Finish test's logs
426
  test_summary;
427
  $display("\n\n END of SIMULATION");
428
  $fclose(tb_log_file | phy_log_file_desc | memory_log_file_desc | host_log_file_desc);
429
  $fclose(wb_s_mon_log_file_desc | wb_m_mon_log_file_desc);
430
 
431
  $stop;
432 116 mohor
end
433 169 mohor
 
434 116 mohor
 
435 169 mohor
 
436
//////////////////////////////////////////////////////////////
437
// Test tasks
438
//////////////////////////////////////////////////////////////
439
 
440
task test_access_to_mac_reg;
441
  input  [31:0]  start_task;
442
  input  [31:0]  end_task;
443
  integer        bit_start_1;
444
  integer        bit_end_1;
445
  integer        bit_start_2;
446
  integer        bit_end_2;
447
  integer        num_of_reg;
448
  integer        i_addr;
449
  integer        i_data;
450
  integer        i_length;
451
  integer        tmp_data;
452
  reg    [31:0]  tx_bd_num;
453
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_data;
454
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_tmp_data;
455
  integer        i;
456
  integer        i1;
457
  integer        i2;
458
  integer        i3;
459
  integer        fail;
460 178 mohor
  integer        test_num;
461 169 mohor
  reg    [31:0]  addr;
462
  reg    [31:0]  data;
463
  reg    [31:0]  data_max;
464 116 mohor
begin
465 169 mohor
// ACCESS TO MAC REGISTERS TEST
466
test_heading("ACCESS TO MAC REGISTERS TEST");
467
$display(" ");
468
$display("ACCESS TO MAC REGISTERS TEST");
469
fail = 0;
470
 
471 192 tadej
// reset MAC registers
472
hard_reset;
473
// reset MAC and MII LOGIC with soft reset
474
reset_mac;
475
reset_mii;
476 169 mohor
 
477 192 tadej
 
478 178 mohor
//////////////////////////////////////////////////////////////////////
479
////                                                              ////
480
////  test_access_to_mac_reg:                                     ////
481
////                                                              ////
482
////  0: Walking 1 with single cycles across MAC regs.            ////
483
////  1: Walking 1 with single cycles across MAC buffer descript. ////
484
////  2: Test max reg. values and reg. values after writing       ////
485
////     inverse reset values and hard reset of the MAC           ////
486
////  3: Test buffer desc. RAM preserving values after hard reset ////
487
////     of the MAC and resetting the logic                       ////
488
////                                                              ////
489
//////////////////////////////////////////////////////////////////////
490 194 tadej
for (test_num = start_task; test_num <= end_task; test_num = test_num + 1)
491 169 mohor
begin
492
 
493 178 mohor
  ////////////////////////////////////////////////////////////////////
494
  ////                                                            ////
495
  ////  Walking 1 with single cycles across MAC regs.             ////
496
  ////                                                            ////
497
  ////////////////////////////////////////////////////////////////////
498
  if (test_num == 0) // Walking 1 with single cycles across MAC regs.
499 194 tadej
  begin
500
    // TEST 0: 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )
501
    test_name   = "TEST 0: 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )";
502
    `TIME; $display("  TEST 0: 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )");
503 178 mohor
 
504 194 tadej
    data = 0;
505
    for (i = 0; i <= 4; i = i + 1) // for initial wait cycles on WB bus
506
      begin
507
        wbm_init_waits = i;
508
        wbm_subseq_waits = {$random} % 5; // it is not important for single accesses
509
        for (i_addr = 0; i_addr <= 32'h4C; i_addr = i_addr + 4) // register address
510
          begin
511
            addr = `ETH_BASE + i_addr;
512
            // set ranges of R/W bits
513
            case (addr)
514
              `ETH_MODER:
515
                begin
516
                  bit_start_1 = 0;
517
                  bit_end_1   = 16;
518
                  bit_start_2 = 32; // not used
519
                  bit_end_2   = 32; // not used
520
                end
521
              `ETH_INT: // READONLY - tested within INT test
522
                begin
523
                  bit_start_1 = 32; // not used
524
                  bit_end_1   = 32; // not used
525
                  bit_start_2 = 32; // not used
526
                  bit_end_2   = 32; // not used
527
                end
528
              `ETH_INT_MASK:
529
                begin
530
                  bit_start_1 = 0;
531
                  bit_end_1   = 6;
532
                  bit_start_2 = 32; // not used
533
                  bit_end_2   = 32; // not used
534
                end
535
              `ETH_IPGT:
536
                begin
537
                  bit_start_1 = 0;
538
                  bit_end_1   = 6;
539
                  bit_start_2 = 32; // not used
540
                  bit_end_2   = 32; // not used
541
                end
542
              `ETH_IPGR1:
543
                begin
544
                  bit_start_1 = 0;
545
                  bit_end_1   = 6;
546
                  bit_start_2 = 32; // not used
547
                  bit_end_2   = 32; // not used
548
                end
549
              `ETH_IPGR2:
550
                begin
551
                  bit_start_1 = 0;
552
                  bit_end_1   = 6;
553
                  bit_start_2 = 32; // not used
554
                  bit_end_2   = 32; // not used
555
                end
556
              `ETH_PACKETLEN:
557
                begin
558
                  bit_start_1 = 0;
559
                  bit_end_1   = 31;
560
                  bit_start_2 = 32; // not used
561
                  bit_end_2   = 32; // not used
562
                end
563
              `ETH_COLLCONF:
564
                begin
565
                  bit_start_1 = 0;
566
                  bit_end_1   = 5;
567
                  bit_start_2 = 16;
568
                  bit_end_2   = 19;
569
                end
570
              `ETH_TX_BD_NUM:
571
                begin
572
                  bit_start_1 = 0;
573
                  bit_end_1   = 7;
574
                  bit_start_2 = 32; // not used
575
                  bit_end_2   = 32; // not used
576
                end
577
              `ETH_CTRLMODER:
578
                begin
579
                  bit_start_1 = 0;
580
                  bit_end_1   = 2;
581
                  bit_start_2 = 32; // not used
582
                  bit_end_2   = 32; // not used
583
                end
584
              `ETH_MIIMODER:
585
                begin
586
                  bit_start_1 = 0;
587
                  bit_end_1   = 9;
588
                  bit_start_2 = 32; // not used
589
                  bit_end_2   = 32; // not used
590
                end
591
              `ETH_MIICOMMAND: // "WRITEONLY" - tested within MIIM test - 3 LSBits are not written here!!!
592
                begin
593
                  bit_start_1 = 32; // not used
594
                  bit_end_1   = 32; // not used
595
                  bit_start_2 = 32; // not used
596
                  bit_end_2   = 32; // not used
597
                end
598
              `ETH_MIIADDRESS:
599
                begin
600
                  bit_start_1 = 0;
601
                  bit_end_1   = 4;
602
                  bit_start_2 = 8;
603
                  bit_end_2   = 12;
604
                end
605
              `ETH_MIITX_DATA:
606
                begin
607
                  bit_start_1 = 0;
608
                  bit_end_1   = 15;
609
                  bit_start_2 = 32; // not used
610
                  bit_end_2   = 32; // not used
611
                end
612
              `ETH_MIIRX_DATA: // READONLY - tested within MIIM test
613
                begin
614
                  bit_start_1 = 32; // not used
615
                  bit_end_1   = 32; // not used
616
                  bit_start_2 = 32; // not used
617
                  bit_end_2   = 32; // not used
618
                end
619
              `ETH_MIISTATUS: // READONLY - tested within MIIM test
620
                begin
621
                  bit_start_1 = 32; // not used
622
                  bit_end_1   = 32; // not used
623
                  bit_start_2 = 32; // not used
624
                  bit_end_2   = 32; // not used
625
                end
626
              `ETH_MAC_ADDR0:
627
                begin
628
                  bit_start_1 = 0;
629
                  bit_end_1   = 31;
630
                  bit_start_2 = 32; // not used
631
                  bit_end_2   = 32; // not used
632 178 mohor
                  end
633 194 tadej
              `ETH_MAC_ADDR1:
634
                begin
635
                  bit_start_1 = 0;
636
                  bit_end_1   = 15;
637
                  bit_start_2 = 32; // not used
638
                  bit_end_2   = 32; // not used
639
                end
640
              `ETH_HASH_ADDR0:
641
                begin
642
                  bit_start_1 = 0;
643
                  bit_end_1   = 31;
644
                  bit_start_2 = 32; // not used
645
                  bit_end_2   = 32; // not used
646
                end
647
              default: // `ETH_HASH_ADDR1:
648
                begin
649
                  bit_start_1 = 0;
650
                  bit_end_1   = 31;
651
                  bit_start_2 = 32; // not used
652
                  bit_end_2   = 32; // not used
653
                end
654
            endcase
655
 
656
            for (i_data = 0; i_data <= 31; i_data = i_data + 1) // the position of walking one
657
              begin
658
                data = 1'b1 << i_data;
659
                if ( (addr == `ETH_MIICOMMAND) && (i_data <= 2) ) // DO NOT WRITE to 3 LSBits of MIICOMMAND !!!
660
                  ;
661
                else
662 178 mohor
                  begin
663 194 tadej
                    wbm_write(addr, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
664
                    wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
665
                    if ( ((i_data >= bit_start_1) && (i_data <= bit_end_1)) ||
666
                         ((i_data >= bit_start_2) && (i_data <= bit_end_2)) ) // data should be equal to tmp_data
667
                      begin
668
                        if (tmp_data !== data)
669 178 mohor
                        begin
670 194 tadej
                          fail = fail + 1;
671
                          test_fail("RW bit of the MAC register was not written or not read");
672
                          `TIME;
673
                          $display("wbm_init_waits %d, addr %h, data %h, tmp_data %h",
674
                                    wbm_init_waits, addr, data, tmp_data);
675
                        end
676
                      end
677
                    else // data should not be equal to tmp_data
678
                      begin
679
                        if (tmp_data === data)
680 178 mohor
                          begin
681
                            fail = fail + 1;
682 194 tadej
                            test_fail("NON RW bit of the MAC register was written, but it shouldn't be");
683 178 mohor
                            `TIME;
684 194 tadej
                            $display("wbm_init_waits %d, addr %h, data %h, tmp_data %h",
685 178 mohor
                                      wbm_init_waits, addr, data, tmp_data);
686
                          end
687 194 tadej
                      end
688
                  end
689
              end
690
          end
691
      end
692 209 tadejm
    // INTERMEDIATE DISPLAYS (The only one)
693
    $display("    ->buffer descriptors tested with 0, 1, 2, 3 and 4 bus delay cycles");
694 194 tadej
    if(fail == 0)
695
      test_ok;
696
    else
697
      fail = 0;    // Errors were reported previously
698
  end
699 178 mohor
 
700
 
701
  ////////////////////////////////////////////////////////////////////
702
  ////                                                            ////
703
  ////  Walking 1 with single cycles across MAC buffer descript.  ////
704
  ////                                                            ////
705
  ////////////////////////////////////////////////////////////////////
706
  if (test_num == 1) // Start Walking 1 with single cycles across MAC buffer descript.
707 169 mohor
  begin
708 194 tadej
    // TEST 1: 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC BUFFER DESC. ( VARIOUS BUS DELAYS )
709
    test_name   = "TEST 1: 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC BUFFER DESC. ( VARIOUS BUS DELAYS )";
710
    `TIME; $display("  TEST 1: 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC BUFFER DESC. ( VARIOUS BUS DELAYS )");
711 178 mohor
 
712
    data = 0;
713
    // set TX and RX buffer descriptors
714
    tx_bd_num = 32'h40;
715
    wbm_write(`ETH_TX_BD_NUM, tx_bd_num, 4'hF, 1, 0, 0);
716
    for (i = 0; i <= 4; i = i + 1) // for initial wait cycles on WB bus
717
    begin
718 169 mohor
      wbm_init_waits = i;
719
      wbm_subseq_waits = {$random} % 5; // it is not important for single accesses
720 178 mohor
      for (i_addr = 32'h400; i_addr <= 32'h7FC; i_addr = i_addr + 4) // buffer descriptor address
721 169 mohor
      begin
722
        addr = `ETH_BASE + i_addr;
723 178 mohor
        if (i_addr < (32'h400 + (tx_bd_num << 3))) // TX buffer descriptors
724
        begin
725
          // set ranges of R/W bits
726
          case (addr[3])
727
            1'b0: // buffer control bits
728
            begin
729
              bit_start_1 = 0;
730
              bit_end_1   = 31; // 8;
731
              bit_start_2 = 11;
732
              bit_end_2   = 31;
733
            end
734
            default: // 1'b1: // buffer pointer
735
            begin
736
              bit_start_1 = 0;
737
              bit_end_1   = 31;
738
              bit_start_2 = 32; // not used
739
              bit_end_2   = 32; // not used
740
            end
741
          endcase
742
        end
743
        else // RX buffer descriptors
744
        begin
745
          // set ranges of R/W bits
746
          case (addr[3])
747
            1'b0: // buffer control bits
748
            begin
749
              bit_start_1 = 0;
750
              bit_end_1   = 31; // 7;
751
              bit_start_2 = 13;
752
              bit_end_2   = 31;
753
            end
754
            default: // 1'b1: // buffer pointer
755
            begin
756
              bit_start_1 = 0;
757
              bit_end_1   = 31;
758
              bit_start_2 = 32; // not used
759
              bit_end_2   = 32; // not used
760
            end
761
          endcase
762
        end
763
 
764 169 mohor
        for (i_data = 0; i_data <= 31; i_data = i_data + 1) // the position of walking one
765
        begin
766
          data = 1'b1 << i_data;
767 178 mohor
          if ( (addr[3] == 0) && (i_data == 15) ) // DO NOT WRITE to this bit !!!
768
            ;
769 169 mohor
          else
770
          begin
771
            wbm_write(addr, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
772
            wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
773
            if ( ((i_data >= bit_start_1) && (i_data <= bit_end_1)) ||
774
                 ((i_data >= bit_start_2) && (i_data <= bit_end_2)) ) // data should be equal to tmp_data
775
            begin
776
              if (tmp_data !== data)
777
              begin
778
                fail = fail + 1;
779 178 mohor
                test_fail("RW bit of the MAC buffer descriptors was not written or not read");
780 169 mohor
                `TIME;
781
                $display("wbm_init_waits %d, addr %h, data %h, tmp_data %h",
782
                          wbm_init_waits, addr, data, tmp_data);
783
              end
784
            end
785
            else // data should not be equal to tmp_data
786
            begin
787
              if (tmp_data === data)
788
              begin
789
                fail = fail + 1;
790 178 mohor
                test_fail("NON RW bit of the MAC buffer descriptors was written, but it shouldn't be");
791 169 mohor
                `TIME;
792
                $display("wbm_init_waits %d, addr %h, data %h, tmp_data %h",
793
                          wbm_init_waits, addr, data, tmp_data);
794
              end
795
            end
796
          end
797
        end
798
      end
799 178 mohor
      // INTERMEDIATE DISPLAYS
800
      case (i)
801 209 tadejm
        0:       $display("    ->buffer descriptors tested with 0 bus delay");
802
        1:       $display("    ->buffer descriptors tested with 1 bus delay cycle");
803
        2:       $display("    ->buffer descriptors tested with 2 bus delay cycles");
804
        3:       $display("    ->buffer descriptors tested with 3 bus delay cycles");
805
        default: $display("    ->buffer descriptors tested with 4 bus delay cycles");
806 178 mohor
      endcase
807
    end
808
    if(fail == 0)
809
      test_ok;
810
    else
811
      fail = 0;
812 169 mohor
  end
813 178 mohor
 
814
 
815
  ////////////////////////////////////////////////////////////////////
816
  ////                                                            ////
817
  ////  Test max reg. values and reg. values after writing        ////
818
  ////  inverse reset values and hard reset of the MAC            ////
819
  ////                                                            ////
820
  ////////////////////////////////////////////////////////////////////
821
  if (test_num == 2) // Start this task
822 169 mohor
  begin
823 194 tadej
    // TEST 2: MAX REG. VALUES AND REG. VALUES AFTER WRITING INVERSE RESET VALUES AND HARD RESET OF THE MAC
824 178 mohor
    test_name   =
825 194 tadej
      "TEST 2: MAX REG. VALUES AND REG. VALUES AFTER WRITING INVERSE RESET VALUES AND HARD RESET OF THE MAC";
826 178 mohor
    `TIME; $display(
827 194 tadej
      "  TEST 2: MAX REG. VALUES AND REG. VALUES AFTER WRITING INVERSE RESET VALUES AND HARD RESET OF THE MAC");
828 178 mohor
 
829
    // reset MAC registers
830
    hard_reset;
831
    for (i = 0; i <= 4; i = i + 1) // 0, 2 - WRITE; 1, 3, 4 - READ
832 169 mohor
    begin
833 178 mohor
      for (i_addr = 0; i_addr <= 32'h4C; i_addr = i_addr + 4) // register address
834 169 mohor
      begin
835 178 mohor
        addr = `ETH_BASE + i_addr;
836
        // set ranges of R/W bits
837
        case (addr)
838
          `ETH_MODER:
839 169 mohor
          begin
840 178 mohor
            data = 32'h0000_A800;
841
            data_max = 32'h0001_FFFF;
842 169 mohor
          end
843 178 mohor
          `ETH_INT: // READONLY - tested within INT test
844 169 mohor
          begin
845 178 mohor
            data = 32'h0000_0000;
846
            data_max = 32'h0000_0000;
847 169 mohor
          end
848
          `ETH_INT_MASK:
849 178 mohor
          begin
850
            data = 32'h0000_0000;
851
            data_max = 32'h0000_007F;
852
          end
853 169 mohor
          `ETH_IPGT:
854 178 mohor
          begin
855
            data = 32'h0000_0012;
856
            data_max = 32'h0000_007F;
857
          end
858 169 mohor
          `ETH_IPGR1:
859 178 mohor
          begin
860
            data = 32'h0000_000C;
861
            data_max = 32'h0000_007F;
862
          end
863 169 mohor
          `ETH_IPGR2:
864 178 mohor
          begin
865
            data = 32'h0000_0012;
866
            data_max = 32'h0000_007F;
867
          end
868 169 mohor
          `ETH_PACKETLEN:
869 178 mohor
          begin
870
            data = 32'h0040_0600;
871
            data_max = 32'hFFFF_FFFF;
872
          end
873 169 mohor
          `ETH_COLLCONF:
874 178 mohor
          begin
875
            data = 32'h000F_003F;
876
            data_max = 32'h000F_003F;
877
          end
878 169 mohor
          `ETH_TX_BD_NUM:
879 178 mohor
          begin
880
            data = 32'h0000_0040;
881
            data_max = 32'h0000_0080;
882
          end
883 169 mohor
          `ETH_CTRLMODER:
884 178 mohor
          begin
885
            data = 32'h0000_0000;
886
            data_max = 32'h0000_0007;
887
          end
888 169 mohor
          `ETH_MIIMODER:
889 178 mohor
          begin
890
            data = 32'h0000_0064;
891
            data_max = 32'h0000_03FF;
892
          end
893 169 mohor
          `ETH_MIICOMMAND: // "WRITEONLY" - tested within MIIM test - 3 LSBits are not written here!!!
894 178 mohor
          begin
895
            data = 32'h0000_0000;
896
            data_max = 32'h0000_0007;
897
          end
898 169 mohor
          `ETH_MIIADDRESS:
899 178 mohor
          begin
900
            data = 32'h0000_0000;
901
            data_max = 32'h0000_1F1F;
902
          end
903 169 mohor
          `ETH_MIITX_DATA:
904 178 mohor
          begin
905
            data = 32'h0000_0000;
906
            data_max = 32'h0000_FFFF;
907
          end
908 169 mohor
          `ETH_MIIRX_DATA: // READONLY - tested within MIIM test
909
          begin
910 178 mohor
            data = 32'h0000_0000;
911
            data_max = 32'h0000_0000;
912 169 mohor
          end
913 178 mohor
          `ETH_MIISTATUS: // READONLY - tested within MIIM test
914 169 mohor
          begin
915 178 mohor
            data = 32'h0000_0000;
916
            data_max = 32'h0000_0000;
917 169 mohor
          end
918 178 mohor
          `ETH_MAC_ADDR0:
919 169 mohor
          begin
920 178 mohor
            data = 32'h0000_0000;
921
            data_max = 32'hFFFF_FFFF;
922 169 mohor
          end
923 178 mohor
          `ETH_MAC_ADDR1:
924 169 mohor
          begin
925 178 mohor
            data = 32'h0000_0000;
926
            data_max = 32'h0000_FFFF;
927 169 mohor
          end
928 178 mohor
          `ETH_HASH_ADDR0:
929 169 mohor
          begin
930 178 mohor
            data = 32'h0000_0000;
931
            data_max = 32'hFFFF_FFFF;
932 169 mohor
          end
933 178 mohor
          default: // `ETH_HASH_ADDR1:
934 169 mohor
          begin
935 178 mohor
            data = 32'h0000_0000;
936
            data_max = 32'hFFFF_FFFF;
937 169 mohor
          end
938
        endcase
939 178 mohor
 
940
        wbm_init_waits = {$random} % 3;
941
        wbm_subseq_waits = {$random} % 5; // it is not important for single accesses
942
        if (i == 0)
943
          wbm_write(addr, ~data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
944
        else if (i == 2)
945
          wbm_write(addr, 32'hFFFFFFFF, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
946
        else if ((i == 1) || (i == 4))
947 169 mohor
        begin
948 178 mohor
          wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
949
          if (tmp_data !== data)
950
          begin
951
            fail = fail + 1;
952
            test_fail("RESET value of the MAC register is not correct");
953
            `TIME;
954
            $display("  addr %h, data %h, tmp_data %h", addr, data, tmp_data);
955
          end
956 169 mohor
        end
957 178 mohor
        else // check maximum values
958 169 mohor
        begin
959
          wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
960 178 mohor
          if (addr == `ETH_TX_BD_NUM) // previous data should remain in this register
961 169 mohor
          begin
962
            if (tmp_data !== data)
963
            begin
964
              fail = fail + 1;
965 178 mohor
              test_fail("Previous value of the TX_BD_NUM register did not remain");
966 169 mohor
              `TIME;
967 178 mohor
              $display("  addr %h, data_max %h, tmp_data %h", addr, data_max, tmp_data);
968 169 mohor
            end
969 178 mohor
            // try maximum (80)
970
            wbm_write(addr, data_max, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
971
            wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
972
            if (tmp_data !== data_max)
973
            begin
974
              fail = fail + 1;
975
              test_fail("MAX value of the TX_BD_NUM register is not correct");
976
              `TIME;
977
              $display("  addr %h, data_max %h, tmp_data %h", addr, data_max, tmp_data);
978
            end
979
            // try one less than maximum (80)
980
            wbm_write(addr, (data_max - 1), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
981
            wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
982
            if (tmp_data !== (data_max - 1))
983
            begin
984
              fail = fail + 1;
985
              test_fail("ONE less than MAX value of the TX_BD_NUM register is not correct");
986
              `TIME;
987
              $display("  addr %h, data_max %h, tmp_data %h", addr, data_max, tmp_data);
988
            end
989
            // try one more than maximum (80)
990
            wbm_write(addr, (data_max + 1), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
991
            wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
992
            if (tmp_data !== (data_max - 1)) // previous data should remain in this register
993
            begin
994
              fail = fail + 1;
995
              test_fail("Previous value of the TX_BD_NUM register did not remain");
996
              `TIME;
997
              $display("  addr %h, data_max %h, tmp_data %h", addr, data_max, tmp_data);
998
            end
999 169 mohor
          end
1000 178 mohor
          else
1001 169 mohor
          begin
1002 178 mohor
            if (tmp_data !== data_max)
1003 169 mohor
            begin
1004
              fail = fail + 1;
1005 178 mohor
              test_fail("MAX value of the MAC register is not correct");
1006 169 mohor
              `TIME;
1007 178 mohor
              $display("  addr %h, data_max %h, tmp_data %h", addr, data_max, tmp_data);
1008 169 mohor
            end
1009
          end
1010
        end
1011
      end
1012 178 mohor
      // reset MAC registers
1013
      if ((i == 0) || (i == 3))
1014
        hard_reset;
1015 169 mohor
    end
1016 178 mohor
    if(fail == 0)
1017
      test_ok;
1018
    else
1019
      fail = 0;
1020 169 mohor
  end
1021 116 mohor
 
1022 156 mohor
 
1023 181 mohor
  ////////////////////////////////////////////////////////////////////
1024
  ////                                                            ////
1025
  ////  Test buffer desc. ram preserving values after hard reset  ////
1026
  ////  of the mac and reseting the logic                         ////
1027
  ////                                                            ////
1028
  ////////////////////////////////////////////////////////////////////
1029 178 mohor
  if (test_num == 3) // Start this task
1030 169 mohor
  begin
1031 194 tadej
    // TEST 3: BUFFER DESC. RAM PRESERVING VALUES AFTER HARD RESET OF THE MAC AND RESETING THE LOGIC
1032
    test_name   = "TEST 3: BUFFER DESC. RAM PRESERVING VALUES AFTER HARD RESET OF THE MAC AND RESETING THE LOGIC";
1033 178 mohor
    `TIME;
1034 194 tadej
    $display("  TEST 3: BUFFER DESC. RAM PRESERVING VALUES AFTER HARD RESET OF THE MAC AND RESETING THE LOGIC");
1035 178 mohor
 
1036
    // reset MAC registers
1037
    hard_reset;
1038
    // reset LOGIC with soft reset
1039
    reset_mac;
1040
    reset_mii;
1041
    for (i = 0; i <= 3; i = i + 1) // 0, 2 - WRITE; 1, 3 - READ
1042 169 mohor
    begin
1043 178 mohor
      for (i_addr = 32'h400; i_addr <= 32'h7FC; i_addr = i_addr + 4) // buffer descriptor address
1044 169 mohor
      begin
1045 178 mohor
        addr = `ETH_BASE + i_addr;
1046
 
1047
        wbm_init_waits = {$random} % 3;
1048
        wbm_subseq_waits = {$random} % 5; // it is not important for single accesses
1049
        if (i == 0)
1050 169 mohor
        begin
1051 178 mohor
          data = 32'hFFFFFFFF;
1052
          wbm_write(addr, 32'hFFFFFFFF, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1053 169 mohor
        end
1054 178 mohor
        else if (i == 2)
1055 169 mohor
        begin
1056 178 mohor
          data = 32'h00000000;
1057
          wbm_write(addr, 32'h00000000, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1058 169 mohor
        end
1059
        else
1060
        begin
1061 178 mohor
          wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1062
          if (tmp_data !== data)
1063 169 mohor
          begin
1064
            fail = fail + 1;
1065 178 mohor
            test_fail("PRESERVED value of the MAC buffer descriptors is not correct");
1066 169 mohor
            `TIME;
1067 178 mohor
            $display("  addr %h, data %h, tmp_data %h", addr, data, tmp_data);
1068 169 mohor
          end
1069
        end
1070
      end
1071 178 mohor
      if ((i == 0) || (i == 2))
1072
      begin
1073
        // reset MAC registers
1074
        hard_reset;
1075
        // reset LOGIC with soft reset
1076
        reset_mac;
1077
        reset_mii;
1078
      end
1079 169 mohor
    end
1080 178 mohor
    if(fail == 0)
1081
      test_ok;
1082
    else
1083
    fail = 0;
1084 169 mohor
  end
1085 116 mohor
 
1086
 
1087 178 mohor
  if (test_num == 4) // Start this task
1088 169 mohor
  begin
1089 194 tadej
        /*  // TEST 4: 'WALKING ONE' WITH BURST CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )
1090
          test_name   = "TEST 4: 'WALKING ONE' WITH BURST CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )";
1091
          `TIME; $display("  TEST 4: 'WALKING ONE' WITH BURST CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )");
1092 178 mohor
 
1093
          data = 0;
1094
          burst_data = 0;
1095
          burst_tmp_data = 0;
1096
          i_length = 10; // two bursts for length 20
1097
          for (i = 0; i <= 4; i = i + 1) // for initial wait cycles on WB bus
1098
          begin
1099
            for (i1 = 0; i1 <= 4; i1 = i1 + 1) // for initial wait cycles on WB bus
1100
            begin
1101
              wbm_init_waits = i;
1102
              wbm_subseq_waits = i1;
1103
              #1;
1104
              for (i_data = 0; i_data <= 31; i_data = i_data + 1) // the position of walking one
1105
              begin
1106
                data = 1'b1 << i_data;
1107
                #1;
1108
                for (i2 = 32'h4C; i2 >= 0; i2 = i2 - 4)
1109
                begin
1110
                  burst_data = burst_data << 32;
1111
                  // DO NOT WRITE to 3 LSBits of MIICOMMAND !!!
1112
                  if ( ((`ETH_BASE + i2) == `ETH_MIICOMMAND) && (i_data <= 2) )
1113
                  begin
1114
                    #1 burst_data[31:0] = 0;
1115
                  end
1116
                  else
1117
                  begin
1118
                    #1 burst_data[31:0] = data;
1119
                  end
1120
                end
1121
                #1;
1122
                // 2 burst writes
1123
                addr = `ETH_BASE; // address of a first burst
1124
                wbm_write(addr, burst_data[(32 * 10 - 1):0], 4'hF, i_length, wbm_init_waits, wbm_subseq_waits);
1125
                burst_tmp_data = burst_data >> (32 * i_length);
1126
                addr = addr + 32'h28; // address of a second burst
1127
                wbm_write(addr, burst_tmp_data[(32 * 10 - 1):0], 4'hF, i_length, wbm_init_waits, wbm_subseq_waits);
1128
                #1;
1129
                // 2 burst reads
1130
                addr = `ETH_BASE; // address of a first burst
1131
                wbm_read(addr, burst_tmp_data[(32 * 10 - 1):0], 4'hF, i_length,
1132
                         wbm_init_waits, wbm_subseq_waits); // first burst
1133
                burst_tmp_data = burst_tmp_data << (32 * i_length);
1134
                addr = addr + 32'h28; // address of a second burst
1135
                wbm_read(addr, burst_tmp_data[(32 * 10 - 1):0], 4'hF, i_length,
1136
                         wbm_init_waits, wbm_subseq_waits); // second burst
1137
                #1;
1138
                for (i2 = 0; i2 <= 32'h4C; i2 = i2 + 4)
1139
                begin
1140
                  // set ranges of R/W bits
1141
                  case (`ETH_BASE + i2)
1142
                  `ETH_MODER:
1143
                    begin
1144
                      bit_start_1 = 0;
1145
                      bit_end_1   = 16;
1146
                      bit_start_2 = 32; // not used
1147
                      bit_end_2   = 32; // not used
1148
                    end
1149
                  `ETH_INT: // READONLY - tested within INT test
1150
                    begin
1151
                      bit_start_1 = 32; // not used
1152
                      bit_end_1   = 32; // not used
1153
                      bit_start_2 = 32; // not used
1154
                      bit_end_2   = 32; // not used
1155
                    end
1156
                  `ETH_INT_MASK:
1157
                    begin
1158
                      bit_start_1 = 0;
1159
                      bit_end_1   = 6;
1160
                      bit_start_2 = 32; // not used
1161
                      bit_end_2   = 32; // not used
1162
                    end
1163
                  `ETH_IPGT:
1164
                    begin
1165
                      bit_start_1 = 0;
1166
                      bit_end_1   = 6;
1167
                      bit_start_2 = 32; // not used
1168
                      bit_end_2   = 32; // not used
1169
                    end
1170
                  `ETH_IPGR1:
1171
                    begin
1172
                      bit_start_1 = 0;
1173
                      bit_end_1   = 6;
1174
                      bit_start_2 = 32; // not used
1175
                      bit_end_2   = 32; // not used
1176
                    end
1177
                  `ETH_IPGR2:
1178
                    begin
1179
                      bit_start_1 = 0;
1180
                      bit_end_1   = 6;
1181
                      bit_start_2 = 32; // not used
1182
                      bit_end_2   = 32; // not used
1183
                    end
1184
                  `ETH_PACKETLEN:
1185
                    begin
1186
                      bit_start_1 = 0;
1187
                      bit_end_1   = 31;
1188
                      bit_start_2 = 32; // not used
1189
                      bit_end_2   = 32; // not used
1190
                    end
1191
                  `ETH_COLLCONF:
1192
                    begin
1193
                      bit_start_1 = 0;
1194
                      bit_end_1   = 5;
1195
                      bit_start_2 = 16;
1196
                      bit_end_2   = 19;
1197
                    end
1198
                  `ETH_TX_BD_NUM:
1199
                    begin
1200
                      bit_start_1 = 0;
1201
                      bit_end_1   = 7;
1202
                      bit_start_2 = 32; // not used
1203
                      bit_end_2   = 32; // not used
1204
                    end
1205
                  `ETH_CTRLMODER:
1206
                    begin
1207
                      bit_start_1 = 0;
1208
                      bit_end_1   = 2;
1209
                      bit_start_2 = 32; // not used
1210
                      bit_end_2   = 32; // not used
1211
                    end
1212
                  `ETH_MIIMODER:
1213
                    begin
1214
                      bit_start_1 = 0;
1215
                      bit_end_1   = 9;
1216
                      bit_start_2 = 32; // not used
1217
                      bit_end_2   = 32; // not used
1218
                    end
1219
                  `ETH_MIICOMMAND: // "WRITEONLY" - tested within MIIM test - 3 LSBits are not written here!!!
1220
                    begin
1221
                      bit_start_1 = 32; // not used
1222
                      bit_end_1   = 32; // not used
1223
                      bit_start_2 = 32; // not used
1224
                      bit_end_2   = 32; // not used
1225
                    end
1226
                  `ETH_MIIADDRESS:
1227
                    begin
1228
                      bit_start_1 = 0;
1229
                      bit_end_1   = 4;
1230
                      bit_start_2 = 8;
1231
                      bit_end_2   = 12;
1232
                    end
1233
                  `ETH_MIITX_DATA:
1234
                    begin
1235
                      bit_start_1 = 0;
1236
                      bit_end_1   = 15;
1237
                      bit_start_2 = 32; // not used
1238
                      bit_end_2   = 32; // not used
1239
                    end
1240
                  `ETH_MIIRX_DATA: // READONLY - tested within MIIM test
1241
                    begin
1242
                      bit_start_1 = 32; // not used
1243
                      bit_end_1   = 32; // not used
1244
                      bit_start_2 = 32; // not used
1245
                      bit_end_2   = 32; // not used
1246
                    end
1247
                  `ETH_MIISTATUS: // READONLY - tested within MIIM test
1248
                    begin
1249
                      bit_start_1 = 32; // not used
1250
                      bit_end_1   = 32; // not used
1251
                      bit_start_2 = 32; // not used
1252
                      bit_end_2   = 32; // not used
1253
                    end
1254
                  `ETH_MAC_ADDR0:
1255
                    begin
1256
                      bit_start_1 = 0;
1257
                      bit_end_1   = 31;
1258
                      bit_start_2 = 32; // not used
1259
                      bit_end_2   = 32; // not used
1260
                    end
1261
                  `ETH_MAC_ADDR1:
1262
                    begin
1263
                      bit_start_1 = 0;
1264
                      bit_end_1   = 15;
1265
                      bit_start_2 = 32; // not used
1266
                      bit_end_2   = 32; // not used
1267
                    end
1268
                  `ETH_HASH_ADDR0:
1269
                    begin
1270
                      bit_start_1 = 0;
1271
                      bit_end_1   = 31;
1272
                      bit_start_2 = 32; // not used
1273
                      bit_end_2   = 32; // not used
1274
                    end
1275
                  default: // `ETH_HASH_ADDR1:
1276
                    begin
1277
                      bit_start_1 = 0;
1278
                      bit_end_1   = 31;
1279
                      bit_start_2 = 32; // not used
1280
                      bit_end_2   = 32; // not used
1281
                    end
1282
                  endcase
1283
                  #1;
1284
                  // 3 LSBits of MIICOMMAND are NOT written !!!
1285
                  if ( ((`ETH_BASE + i2) == `ETH_MIICOMMAND) && (i_data <= 2) )
1286
                  begin
1287
                    if (burst_tmp_data[31:0] !== burst_data[31:0])
1288
                    begin
1289
                      fail = fail + 1;
1290
                      test_fail("NON WR bit of the MAC MIICOMMAND register was wrong written or read");
1291
                      `TIME;
1292
                      $display("wbm_init_waits %d, wbm_subseq_waits %d, addr %h, data %h, tmp_data %h",
1293
                                wbm_init_waits, wbm_subseq_waits, i2, burst_data[31:0], burst_tmp_data[31:0]);
1294
                    end
1295
                  end
1296
                  else
1297
                  begin
1298
                    if ( ((i_data >= bit_start_1) && (i_data <= bit_end_1)) ||
1299
                         ((i_data >= bit_start_2) && (i_data <= bit_end_2)) ) // data should be equal to tmp_data
1300
                    begin
1301
                      if (burst_tmp_data[31:0] !== burst_data[31:0])
1302
                      begin
1303
                        fail = fail + 1;
1304
                        test_fail("RW bit of the MAC register was not written or not read");
1305
                        `TIME;
1306
                        $display("wbm_init_waits %d, wbm_subseq_waits %d, addr %h, data %h, tmp_data %h",
1307
                                  wbm_init_waits, wbm_subseq_waits, i2, burst_data[31:0], burst_tmp_data[31:0]);
1308
                      end
1309
                    end
1310
                    else // data should not be equal to tmp_data
1311
                    begin
1312
                      if (burst_tmp_data[31:0] === burst_data[31:0])
1313
                      begin
1314
                        fail = fail + 1;
1315
                        test_fail("NON RW bit of the MAC register was written, but it shouldn't be");
1316
                        `TIME;
1317
                        $display("wbm_init_waits %d, wbm_subseq_waits %d, addr %h, data %h, tmp_data %h",
1318
                                  wbm_init_waits, wbm_subseq_waits, i2, burst_data[31:0], burst_tmp_data[31:0]);
1319
                      end
1320
                    end
1321
                  end
1322
                  burst_tmp_data = burst_tmp_data >> 32;
1323
                  burst_data = burst_data >> 32;
1324
                end
1325
              end
1326
            end
1327
          end
1328
          if(fail == 0)
1329
            test_ok;
1330
          else
1331
            fail = 0;*/
1332
  end
1333 116 mohor
 
1334 169 mohor
end
1335 156 mohor
 
1336 169 mohor
end
1337
endtask // test_access_to_mac_reg
1338 156 mohor
 
1339
 
1340 169 mohor
task test_mii;
1341
  input  [31:0]  start_task;
1342
  input  [31:0]  end_task;
1343
  integer        i;
1344
  integer        i1;
1345
  integer        i2;
1346
  integer        i3;
1347
  integer        cnt;
1348
  integer        fail;
1349 181 mohor
  integer        test_num;
1350 169 mohor
  reg     [8:0]  clk_div; // only 8 bits are valid!
1351
  reg     [4:0]  phy_addr;
1352
  reg     [4:0]  reg_addr;
1353
  reg     [15:0] phy_data;
1354
  reg     [15:0] tmp_data;
1355
begin
1356
// MIIM MODULE TEST
1357
test_heading("MIIM MODULE TEST");
1358
$display(" ");
1359
$display("MIIM MODULE TEST");
1360
fail = 0;
1361 156 mohor
 
1362 192 tadej
// reset MAC registers
1363
hard_reset;
1364
// reset MAC and MII LOGIC with soft reset
1365
reset_mac;
1366 169 mohor
reset_mii;
1367 116 mohor
 
1368 194 tadej
 
1369 181 mohor
//////////////////////////////////////////////////////////////////////
1370
////                                                              ////
1371
////  test_mii:                                                   ////
1372
////                                                              ////
1373
////  0:  Test clock divider of mii management module with all    ////
1374
////      possible frequences.                                    ////
1375
////  1:  Test various readings from 'real' phy registers.        ////
1376
////  2:  Test various writings to 'real' phy registers (control  ////
1377
////      and non writable registers)                             ////
1378
////  3:  Test reset phy through mii management module            ////
1379
////  4:  Test 'walking one' across phy address (with and without ////
1380
////      preamble)                                               ////
1381
////  5:  Test 'walking one' across phy's register address (with  ////
1382
////      and without preamble)                                   ////
1383
////  6:  Test 'walking one' across phy's data (with and without  ////
1384
////      preamble)                                               ////
1385
////  7:  Test reading from phy with wrong phy address (host      ////
1386
////      reading high 'z' data)                                  ////
1387
////  8:  Test writing to phy with wrong phy address and reading  ////
1388
////      from correct one                                        ////
1389
////  9:  Test sliding stop scan command immediately after read   ////
1390
////      request (with and without preamble)                     ////
1391
//// 10:  Test sliding stop scan command immediately after write  ////
1392
////      request (with and without preamble)                     ////
1393
//// 11:  Test busy and nvalid status durations during write      ////
1394
////      (with and without preamble)                             ////
1395
//// 12:  Test busy and nvalid status durations during write      ////
1396
////      (with and without preamble)                             ////
1397
//// 13:  Test busy and nvalid status durations during scan (with ////
1398
////      and without preamble)                                   ////
1399
//// 14:  Test scan status from phy with detecting link-fail bit  ////
1400
////      (with and without preamble)                             ////
1401
//// 15:  Test scan status from phy with sliding link-fail bit    ////
1402
////      (with and without preamble)                             ////
1403
//// 16:  Test sliding stop scan command immediately after scan   ////
1404
////      request (with and without preamble)                     ////
1405
//// 17:  Test sliding stop scan command after 2. scan (with and  ////
1406
////      without preamble)                                       ////
1407
////                                                              ////
1408
//////////////////////////////////////////////////////////////////////
1409 194 tadej
for (test_num = start_task; test_num <= end_task; test_num = test_num + 1)
1410 169 mohor
begin
1411 194 tadej
 
1412 181 mohor
  ////////////////////////////////////////////////////////////////////
1413
  ////                                                            ////
1414
  ////  Test clock divider of mii management module with all      ////
1415
  ////  possible frequences.                                      ////
1416
  ////                                                            ////
1417
  ////////////////////////////////////////////////////////////////////
1418
  if (test_num == 0) // Test clock divider of mii management module with all possible frequences.
1419 169 mohor
  begin
1420 194 tadej
    // TEST 0: CLOCK DIVIDER OF MII MANAGEMENT MODULE WITH ALL POSSIBLE FREQUENCES
1421
    test_name   = "TEST 0: CLOCK DIVIDER OF MII MANAGEMENT MODULE WITH ALL POSSIBLE FREQUENCES";
1422
    `TIME; $display("  TEST 0: CLOCK DIVIDER OF MII MANAGEMENT MODULE WITH ALL POSSIBLE FREQUENCES");
1423 181 mohor
 
1424
    wait(Mdc_O); // wait for MII clock to be 1
1425
    for(clk_div = 0; clk_div <= 255; clk_div = clk_div + 1)
1426
    begin
1427
      i1 = 0;
1428
      i2 = 0;
1429
      #Tp mii_set_clk_div(clk_div[7:0]);
1430
      @(posedge Mdc_O);
1431
      #Tp;
1432
      fork
1433 169 mohor
        begin
1434 181 mohor
          @(posedge Mdc_O);
1435 169 mohor
          #Tp;
1436 181 mohor
          disable count_i1;
1437
          disable count_i2;
1438 169 mohor
        end
1439 181 mohor
        begin: count_i1
1440
          forever
1441
          begin
1442
            @(posedge wb_clk);
1443
            i1 = i1 + 1;
1444
            #Tp;
1445
          end
1446
        end
1447
        begin: count_i2
1448
          forever
1449
          begin
1450
            @(negedge wb_clk);
1451
            i2 = i2 + 1;
1452
            #Tp;
1453
          end
1454
        end
1455
      join
1456
      if((clk_div[7:0] == 0) || (clk_div[7:0] == 1) || (clk_div[7:0] == 2) || (clk_div[7:0] == 3))
1457
      begin
1458
        if((i1 == i2) && (i1 == 2))
1459 169 mohor
        begin
1460
        end
1461 181 mohor
        else
1462
        begin
1463
          fail = fail + 1;
1464 209 tadejm
          test_fail("Clock divider of MII module did'nt divide frequency corectly (it should divide by 2)");
1465 181 mohor
        end
1466 169 mohor
      end
1467
      else
1468
      begin
1469 181 mohor
        if((i1 == i2) && (i1 == {clk_div[7:1], 1'b0}))
1470
        begin
1471
        end
1472
        else
1473
        begin
1474
          fail = fail + 1;
1475
          test_fail("Clock divider of MII module did'nt divide frequency corectly");
1476
        end
1477 169 mohor
      end
1478
    end
1479 181 mohor
    if(fail == 0)
1480
      test_ok;
1481 169 mohor
    else
1482 181 mohor
      fail = 0;
1483
  end
1484
 
1485
 
1486
  ////////////////////////////////////////////////////////////////////
1487
  ////                                                            ////
1488
  ////  Test various readings from 'real' phy registers.          ////
1489
  ////                                                            ////
1490
  ////////////////////////////////////////////////////////////////////
1491
  if (test_num == 1) // Test various readings from 'real' phy registers.
1492
  begin
1493 194 tadej
    // TEST 1: VARIOUS READINGS FROM 'REAL' PHY REGISTERS
1494
    test_name   = "TEST 1: VARIOUS READINGS FROM 'REAL' PHY REGISTERS";
1495
    `TIME; $display("  TEST 1: VARIOUS READINGS FROM 'REAL' PHY REGISTERS");
1496 181 mohor
 
1497
    // set the fastest possible MII
1498
    clk_div = 0;
1499
    mii_set_clk_div(clk_div[7:0]);
1500
    // set address
1501
    reg_addr = 5'h1F;
1502
    phy_addr = 5'h1;
1503
    while(reg_addr >= 5'h4)
1504 169 mohor
    begin
1505 181 mohor
      // read request
1506
      #Tp mii_read_req(phy_addr, reg_addr);
1507
      check_mii_busy; // wait for read to finish
1508
      // read data
1509
      #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1510
      if (phy_data !== 16'hDEAD)
1511 169 mohor
      begin
1512 181 mohor
        test_fail("Wrong data was read from PHY from 'not used' address space");
1513
        fail = fail + 1;
1514 169 mohor
      end
1515 181 mohor
      if (reg_addr == 5'h4) // go out of for loop
1516
        reg_addr = 5'h3;
1517 169 mohor
      else
1518 181 mohor
        reg_addr = reg_addr - 5'h9;
1519 169 mohor
    end
1520 181 mohor
 
1521
    // set address
1522
    reg_addr = 5'h3;
1523
    // read request
1524
    #Tp mii_read_req(phy_addr, reg_addr);
1525
    check_mii_busy; // wait for read to finish
1526
    // read data
1527
    #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1528
    if (phy_data !== {`PHY_ID2, `MAN_MODEL_NUM, `MAN_REVISION_NUM})
1529
    begin
1530
      test_fail("Wrong data was read from PHY from ID register 2");
1531
      fail = fail + 1;
1532
    end
1533
    if(fail == 0)
1534
      test_ok;
1535
    else
1536
      fail = 0;
1537 169 mohor
  end
1538 116 mohor
 
1539
 
1540 181 mohor
  ////////////////////////////////////////////////////////////////////
1541
  ////                                                            ////
1542
  ////  Test various writings to 'real' phy registers (control    ////
1543
  ////  and non writable registers)                               ////
1544
  ////                                                            ////
1545
  ////////////////////////////////////////////////////////////////////
1546
  if (test_num == 2) // 
1547 169 mohor
  begin
1548 194 tadej
    // TEST 2: VARIOUS WRITINGS TO 'REAL' PHY REGISTERS ( CONTROL AND NON WRITABLE REGISTERS )
1549
    test_name   = "TEST 2: VARIOUS WRITINGS TO 'REAL' PHY REGISTERS ( CONTROL AND NON WRITABLE REGISTERS )";
1550
    `TIME; $display("  TEST 2: VARIOUS WRITINGS TO 'REAL' PHY REGISTERS ( CONTROL AND NON WRITABLE REGISTERS )");
1551 181 mohor
 
1552
    // negate data and try to write into unwritable register
1553
    tmp_data = ~phy_data;
1554
    // write request
1555
    #Tp mii_write_req(phy_addr, reg_addr, tmp_data);
1556
    check_mii_busy; // wait for write to finish
1557 169 mohor
    // read request
1558
    #Tp mii_read_req(phy_addr, reg_addr);
1559
    check_mii_busy; // wait for read to finish
1560
    // read data
1561 181 mohor
    #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1562
    if (tmp_data !== phy_data)
1563
    begin
1564
      test_fail("Data was written into unwritable PHY register - ID register 2");
1565
      fail = fail + 1;
1566
    end
1567
 
1568
    // set address
1569
    reg_addr = 5'h0; // control register
1570
    // read request
1571
    #Tp mii_read_req(phy_addr, reg_addr);
1572
    check_mii_busy; // wait for read to finish
1573
    // read data
1574
    #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1575
    // write request
1576
    phy_data = 16'h7DFF; // bit 15 (RESET bit) and bit 9 are self clearing bits
1577
    #Tp mii_write_req(phy_addr, reg_addr, phy_data);
1578
    check_mii_busy; // wait for write to finish
1579
    // read request
1580
    #Tp mii_read_req(phy_addr, reg_addr);
1581
    check_mii_busy; // wait for read to finish
1582
    // read data
1583 169 mohor
    #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1584 181 mohor
    if (phy_data !== 16'h7DFF)
1585 169 mohor
    begin
1586 181 mohor
      test_fail("Data was not correctly written into OR read from writable PHY register - control register");
1587 169 mohor
      fail = fail + 1;
1588
    end
1589 181 mohor
    // write request
1590
    #Tp mii_write_req(phy_addr, reg_addr, tmp_data);
1591
    check_mii_busy; // wait for write to finish
1592
    // read request
1593
    #Tp mii_read_req(phy_addr, reg_addr);
1594
    check_mii_busy; // wait for read to finish
1595
    // read data
1596
    #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1597
    if (phy_data !== tmp_data)
1598
    begin
1599
      test_fail("Data was not correctly written into OR read from writable PHY register - control register");
1600
      fail = fail + 1;
1601
    end
1602
    if(fail == 0)
1603
      test_ok;
1604 116 mohor
    else
1605 181 mohor
      fail = 0;
1606 169 mohor
  end
1607 116 mohor
 
1608
 
1609 181 mohor
  ////////////////////////////////////////////////////////////////////
1610
  ////                                                            ////
1611
  ////  Test reset phy through mii management module              ////
1612
  ////                                                            ////
1613
  ////////////////////////////////////////////////////////////////////
1614
  if (test_num == 3) // 
1615 169 mohor
  begin
1616 194 tadej
    // TEST 3: RESET PHY THROUGH MII MANAGEMENT MODULE
1617
    test_name   = "TEST 3: RESET PHY THROUGH MII MANAGEMENT MODULE";
1618
    `TIME; $display("  TEST 3: RESET PHY THROUGH MII MANAGEMENT MODULE");
1619 181 mohor
 
1620
    // set address
1621
    reg_addr = 5'h0; // control register
1622
    // write request
1623
    phy_data = 16'h7DFF; // bit 15 (RESET bit) and bit 9 are self clearing bits
1624
    #Tp mii_write_req(phy_addr, reg_addr, phy_data);
1625
    check_mii_busy; // wait for write to finish
1626
    // read request
1627
    #Tp mii_read_req(phy_addr, reg_addr);
1628
    check_mii_busy; // wait for read to finish
1629
    // read data
1630
    #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1631
    if (phy_data !== tmp_data)
1632
    begin
1633
      test_fail("Data was not correctly written into OR read from writable PHY register - control register");
1634
      fail = fail + 1;
1635
    end
1636
    // set reset bit - selfclearing bit in PHY
1637
    phy_data = phy_data | 16'h8000;
1638
    // write request
1639
    #Tp mii_write_req(phy_addr, reg_addr, phy_data);
1640
    check_mii_busy; // wait for write to finish
1641
    // read request
1642
    #Tp mii_read_req(phy_addr, reg_addr);
1643
    check_mii_busy; // wait for read to finish
1644
    // read data
1645
    #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1646
    // check self clearing of reset bit
1647
    if (tmp_data[15] !== 1'b0)
1648
    begin
1649
      test_fail("Reset bit should be self cleared - control register");
1650
      fail = fail + 1;
1651
    end
1652
    // check reset value of control register
1653
    if (tmp_data !== {2'h0, (`LED_CFG1 || `LED_CFG2), `LED_CFG1, 3'h0, `LED_CFG3, 8'h0})
1654
    begin
1655
      test_fail("PHY was not reset correctly AND/OR reset bit not self cleared");
1656
      fail = fail + 1;
1657
    end
1658
    if(fail == 0)
1659
      test_ok;
1660
    else
1661
      fail = 0;
1662 169 mohor
  end
1663
 
1664
 
1665 181 mohor
  ////////////////////////////////////////////////////////////////////
1666
  ////                                                            ////
1667
  ////  Test 'walking one' across phy address (with and without   ////
1668
  ////  preamble)                                                 ////
1669
  ////                                                            ////
1670
  ////////////////////////////////////////////////////////////////////
1671
  if (test_num == 4) // 
1672 169 mohor
  begin
1673 194 tadej
    // TEST 4: 'WALKING ONE' ACROSS PHY ADDRESS ( WITH AND WITHOUT PREAMBLE )
1674
    test_name   = "TEST 4: 'WALKING ONE' ACROSS PHY ADDRESS ( WITH AND WITHOUT PREAMBLE )";
1675
    `TIME; $display("  TEST 4: 'WALKING ONE' ACROSS PHY ADDRESS ( WITH AND WITHOUT PREAMBLE )");
1676 181 mohor
 
1677
    // set PHY to test mode
1678
    #Tp eth_phy.test_regs(1); // set test registers (wholy writable registers) and respond to all PHY addresses
1679
    for (i = 0; i <= 1; i = i + 1)
1680 169 mohor
    begin
1681 181 mohor
      #Tp eth_phy.preamble_suppresed(i);
1682
      #Tp eth_phy.clear_test_regs;
1683
      // MII mode register
1684
      wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}), 4'hF, 1, wbm_init_waits,
1685
                wbm_subseq_waits);
1686
      // walk one across phy address
1687
      for (phy_addr = 5'h1; phy_addr > 5'h0; phy_addr = phy_addr << 1)
1688 169 mohor
      begin
1689 181 mohor
        reg_addr = $random;
1690
        tmp_data = $random;
1691
        // write request
1692
        #Tp mii_write_req(phy_addr, reg_addr, tmp_data);
1693
        check_mii_busy; // wait for write to finish
1694
        // read request
1695
        #Tp mii_read_req(phy_addr, reg_addr);
1696
        check_mii_busy; // wait for read to finish
1697
        // read data
1698
        #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1699
        #Tp;
1700
        if (phy_data !== tmp_data)
1701
        begin
1702
          if (i)
1703
            test_fail("Data was not correctly written into OR read from test registers (without preamble)");
1704
          else
1705
            test_fail("Data was not correctly written into OR read from test registers (with preamble)");
1706
          fail = fail + 1;
1707
        end
1708
        @(posedge wb_clk);
1709
        #Tp;
1710 169 mohor
      end
1711
    end
1712 181 mohor
    // set PHY to normal mode
1713
    #Tp eth_phy.test_regs(0);
1714
    #Tp eth_phy.preamble_suppresed(0);
1715
    // MII mode register
1716
    wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1717
    if(fail == 0)
1718
      test_ok;
1719
    else
1720
      fail = 0;
1721 169 mohor
  end
1722
 
1723
 
1724 181 mohor
  ////////////////////////////////////////////////////////////////////
1725
  ////                                                            ////
1726
  ////  Test 'walking one' across phy's register address (with    ////
1727
  ////  and without preamble)                                     ////
1728
  ////                                                            ////
1729
  ////////////////////////////////////////////////////////////////////
1730
  if (test_num == 5) // 
1731 169 mohor
  begin
1732 194 tadej
    // TEST 5: 'WALKING ONE' ACROSS PHY'S REGISTER ADDRESS ( WITH AND WITHOUT PREAMBLE )
1733
    test_name   = "TEST 5: 'WALKING ONE' ACROSS PHY'S REGISTER ADDRESS ( WITH AND WITHOUT PREAMBLE )";
1734
    `TIME; $display("  TEST 5: 'WALKING ONE' ACROSS PHY'S REGISTER ADDRESS ( WITH AND WITHOUT PREAMBLE )");
1735 181 mohor
 
1736
    // set PHY to test mode
1737
    #Tp eth_phy.test_regs(1); // set test registers (wholy writable registers) and respond to all PHY addresses
1738
    for (i = 0; i <= 1; i = i + 1)
1739 169 mohor
    begin
1740 181 mohor
      #Tp eth_phy.preamble_suppresed(i);
1741
      #Tp eth_phy.clear_test_regs;
1742
      // MII mode register
1743
      wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}), 4'hF, 1, wbm_init_waits,
1744
                wbm_subseq_waits);
1745
      // walk one across reg address
1746
      for (reg_addr = 5'h1; reg_addr > 5'h0; reg_addr = reg_addr << 1)
1747 169 mohor
      begin
1748 181 mohor
        phy_addr = $random;
1749
        tmp_data = $random;
1750
        // write request
1751
        #Tp mii_write_req(phy_addr, reg_addr, tmp_data);
1752
        check_mii_busy; // wait for write to finish
1753
        // read request
1754
        #Tp mii_read_req(phy_addr, reg_addr);
1755
        check_mii_busy; // wait for read to finish
1756
        // read data
1757
        #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1758
        #Tp;
1759
        if (phy_data !== tmp_data)
1760
        begin
1761
          if (i)
1762
            test_fail("Data was not correctly written into OR read from test registers (without preamble)");
1763
          else
1764
            test_fail("Data was not correctly written into OR read from test registers (with preamble)");
1765
          fail = fail + 1;
1766
        end
1767
        @(posedge wb_clk);
1768
        #Tp;
1769 169 mohor
      end
1770
    end
1771 181 mohor
    // set PHY to normal mode
1772
    #Tp eth_phy.test_regs(0);
1773
    #Tp eth_phy.preamble_suppresed(0);
1774
    // MII mode register
1775
    wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1776
    if(fail == 0)
1777
      test_ok;
1778
    else
1779
      fail = 0;
1780 169 mohor
  end
1781
 
1782
 
1783 181 mohor
  ////////////////////////////////////////////////////////////////////
1784
  ////                                                            ////
1785
  ////  Test 'walking one' across phy's data (with and without    ////
1786
  ////  preamble)                                                 ////
1787
  ////                                                            ////
1788
  ////////////////////////////////////////////////////////////////////
1789
  if (test_num == 6) // 
1790 169 mohor
  begin
1791 194 tadej
    // TEST 6: 'WALKING ONE' ACROSS PHY'S DATA ( WITH AND WITHOUT PREAMBLE )
1792
    test_name   = "TEST 6: 'WALKING ONE' ACROSS PHY'S DATA ( WITH AND WITHOUT PREAMBLE )";
1793
    `TIME; $display("  TEST 6: 'WALKING ONE' ACROSS PHY'S DATA ( WITH AND WITHOUT PREAMBLE )");
1794 181 mohor
 
1795
    // set PHY to test mode
1796
    #Tp eth_phy.test_regs(1); // set test registers (wholy writable registers) and respond to all PHY addresses
1797
    for (i = 0; i <= 1; i = i + 1)
1798 169 mohor
    begin
1799 181 mohor
      #Tp eth_phy.preamble_suppresed(i);
1800
      #Tp eth_phy.clear_test_regs;
1801
      // MII mode register
1802
      wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}), 4'hF, 1, wbm_init_waits,
1803
                wbm_subseq_waits);
1804
      // walk one across data
1805
      for (tmp_data = 16'h1; tmp_data > 16'h0; tmp_data = tmp_data << 1)
1806 169 mohor
      begin
1807 181 mohor
        phy_addr = $random;
1808
        reg_addr = $random;
1809
        // write request
1810
        #Tp mii_write_req(phy_addr, reg_addr, tmp_data);
1811
        check_mii_busy; // wait for write to finish
1812
        // read request
1813
        #Tp mii_read_req(phy_addr, reg_addr);
1814
        check_mii_busy; // wait for read to finish
1815
        // read data
1816
        #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1817
        #Tp;
1818
        if (phy_data !== tmp_data)
1819
        begin
1820
          if (i)
1821
            test_fail("Data was not correctly written into OR read from test registers (without preamble)");
1822
          else
1823
            test_fail("Data was not correctly written into OR read from test registers (with preamble)");
1824
          fail = fail + 1;
1825
        end
1826
        @(posedge wb_clk);
1827
        #Tp;
1828 169 mohor
      end
1829
    end
1830 181 mohor
    // set PHY to normal mode
1831
    #Tp eth_phy.test_regs(0);
1832
    #Tp eth_phy.preamble_suppresed(0);
1833
    // MII mode register
1834
    wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1835
    if(fail == 0)
1836
      test_ok;
1837
    else
1838
      fail = 0;
1839 169 mohor
  end
1840
 
1841
 
1842 181 mohor
  ////////////////////////////////////////////////////////////////////
1843
  ////                                                            ////
1844
  ////  Test reading from phy with wrong phy address (host        ////
1845
  ////  reading high 'z' data)                                    ////
1846
  ////                                                            ////
1847
  ////////////////////////////////////////////////////////////////////
1848
  if (test_num == 7) // 
1849 169 mohor
  begin
1850 194 tadej
    // TEST 7: READING FROM PHY WITH WRONG PHY ADDRESS ( HOST READING HIGH 'Z' DATA )
1851
    test_name   = "TEST 7: READING FROM PHY WITH WRONG PHY ADDRESS ( HOST READING HIGH 'Z' DATA )";
1852
    `TIME; $display("  TEST 7: READING FROM PHY WITH WRONG PHY ADDRESS ( HOST READING HIGH 'Z' DATA )");
1853 181 mohor
 
1854
    phy_addr = 5'h2; // wrong PHY address
1855
    // read request
1856
    #Tp mii_read_req(phy_addr, reg_addr);
1857
    check_mii_busy; // wait for read to finish
1858
    // read data
1859
    $display("  => Two errors will be displayed from WB Bus Monitor, because correct HIGH Z data was read");
1860
    #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1861
    if (tmp_data !== 16'hzzzz)
1862
    begin
1863
      test_fail("Data was read from PHY register with wrong PHY address - control register");
1864
      fail = fail + 1;
1865
    end
1866
    if(fail == 0)
1867
      test_ok;
1868
    else
1869
      fail = 0;
1870 169 mohor
  end
1871
 
1872
 
1873 181 mohor
  ////////////////////////////////////////////////////////////////////
1874
  ////                                                            ////
1875
  ////  Test writing to phy with wrong phy address and reading    ////
1876
  ////  from correct one                                          ////
1877
  ////                                                            ////
1878
  ////////////////////////////////////////////////////////////////////
1879
  if (test_num == 8) // 
1880 169 mohor
  begin
1881 194 tadej
    // TEST 8: WRITING TO PHY WITH WRONG PHY ADDRESS AND READING FROM CORRECT ONE
1882
    test_name   = "TEST 8: WRITING TO PHY WITH WRONG PHY ADDRESS AND READING FROM CORRECT ONE";
1883
    `TIME; $display("  TEST 8: WRITING TO PHY WITH WRONG PHY ADDRESS AND READING FROM CORRECT ONE");
1884 181 mohor
 
1885
    // set address
1886
    reg_addr = 5'h0; // control register
1887
    phy_addr = 5'h2; // wrong PHY address
1888
    // write request
1889
    phy_data = 16'h7DFF; // bit 15 (RESET bit) and bit 9 are self clearing bits
1890
    #Tp mii_write_req(phy_addr, reg_addr, phy_data);
1891
    check_mii_busy; // wait for write to finish
1892
 
1893
    phy_addr = 5'h1; // correct PHY address
1894
    // read request
1895
    #Tp mii_read_req(phy_addr, reg_addr);
1896
    check_mii_busy; // wait for read to finish
1897
    // read data
1898
    #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1899
    if (phy_data === tmp_data)
1900
    begin
1901
      test_fail("Data was written into PHY register with wrong PHY address - control register");
1902
      fail = fail + 1;
1903
    end
1904
    if(fail == 0)
1905
      test_ok;
1906
    else
1907
      fail = 0;
1908 169 mohor
  end
1909
 
1910
 
1911 181 mohor
  ////////////////////////////////////////////////////////////////////
1912
  ////                                                            ////
1913
  ////  Test sliding stop scan command immediately after read     ////
1914
  ////  request (with and without preamble)                       ////
1915
  ////                                                            ////
1916
  ////////////////////////////////////////////////////////////////////
1917
  if (test_num == 9) // 
1918 169 mohor
  begin
1919 194 tadej
    // TEST 9: SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER READ REQUEST ( WITH AND WITHOUT PREAMBLE )
1920
    test_name = "TEST 9: SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER READ REQUEST ( WITH AND WITHOUT PREAMBLE )";
1921 181 mohor
    `TIME;
1922 194 tadej
    $display("  TEST 9: SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER READ REQUEST ( WITH AND WITHOUT PREAMBLE )");
1923 181 mohor
 
1924
    for (i2 = 0; i2 <= 1; i2 = i2 + 1) // choose preamble or not
1925 169 mohor
    begin
1926 181 mohor
      #Tp eth_phy.preamble_suppresed(i2);
1927
      // MII mode register
1928
      wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i2, 8'h0}), 4'hF, 1, wbm_init_waits,
1929
               wbm_subseq_waits);
1930
      i = 0;
1931
      cnt = 0;
1932
      while (i < 80) // delay for sliding of writing a STOP SCAN command
1933 169 mohor
      begin
1934 181 mohor
        for (i3 = 0; i3 <= 1; i3 = i3 + 1) // choose read or write after read will be finished
1935
        begin
1936
          // set address
1937
          reg_addr = 5'h0; // control register
1938
          phy_addr = 5'h1; // correct PHY address
1939
          cnt = 0;
1940
          // read request
1941
          #Tp mii_read_req(phy_addr, reg_addr);
1942
          fork
1943
            begin
1944
              repeat(i) @(posedge Mdc_O);
1945
              // write command 0x0 into MII command register
1946
              // MII command written while read in progress
1947
              wbm_write(`ETH_MIICOMMAND, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1948
              @(posedge wb_clk);
1949
              #Tp check_mii_busy; // wait for read to finish
1950
            end
1951
            begin
1952
              // wait for serial bus to become active
1953
              wait(Mdio_IO !== 1'bz);
1954
              // count transfer length
1955
              while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
1956
              begin
1957
                @(posedge Mdc_O);
1958
                #Tp cnt = cnt + 1;
1959
              end
1960
            end
1961
          join
1962
          // check transfer length
1963
          if (i2) // without preamble
1964 169 mohor
          begin
1965 181 mohor
            if (cnt != 33) // at this value Mdio_IO is HIGH Z
1966
            begin
1967
              test_fail("Read request did not proceed correctly, while SCAN STOP command was written");
1968
              fail = fail + 1;
1969
            end
1970 169 mohor
          end
1971 181 mohor
          else // with preamble
1972 169 mohor
          begin
1973 181 mohor
            if (cnt != 65) // at this value Mdio_IO is HIGH Z
1974
            begin
1975
              test_fail("Read request did not proceed correctly, while SCAN STOP command was written");
1976
              fail = fail + 1;
1977
            end
1978
          end
1979
          // check the BUSY signal to see if the bus is still IDLE
1980
          for (i1 = 0; i1 < 8; i1 = i1 + 1)
1981
            check_mii_busy; // wait for bus to become idle
1982
 
1983
          // try normal write or read after read was finished
1984
          #Tp phy_data = {8'h7D, (i[7:0] + 1)};
1985
          #Tp cnt = 0;
1986
          if (i3 == 0) // write after read
1987
          begin
1988
            // write request
1989
            #Tp mii_write_req(phy_addr, reg_addr, phy_data);
1990 169 mohor
            // wait for serial bus to become active
1991
            wait(Mdio_IO !== 1'bz);
1992
            // count transfer length
1993 181 mohor
            while(Mdio_IO !== 1'bz)
1994 169 mohor
            begin
1995
              @(posedge Mdc_O);
1996
              #Tp cnt = cnt + 1;
1997
            end
1998 181 mohor
            @(posedge Mdc_O);
1999
            // read request
2000
            #Tp mii_read_req(phy_addr, reg_addr);
2001
            check_mii_busy; // wait for read to finish
2002
            // read and check data
2003
            #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2004
            if (phy_data !== tmp_data)
2005
            begin
2006
              test_fail("Data was not correctly written into OR read from PHY register - control register");
2007
              fail = fail + 1;
2008
            end
2009 169 mohor
          end
2010 181 mohor
          else // read after read
2011 169 mohor
          begin
2012 181 mohor
            // read request
2013
            #Tp mii_read_req(phy_addr, reg_addr);
2014
            // wait for serial bus to become active
2015
            wait(Mdio_IO !== 1'bz);
2016
            // count transfer length
2017
            while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
2018
            begin
2019
              @(posedge Mdc_O);
2020
              #Tp cnt = cnt + 1;
2021
            end
2022 169 mohor
            @(posedge Mdc_O);
2023 181 mohor
            check_mii_busy; // wait for read to finish
2024
            // read and check data
2025
            #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2026
            if (phy_data !== tmp_data)
2027
            begin
2028
              test_fail("Data was not correctly written into OR read from PHY register - control register");
2029
              fail = fail + 1;
2030
            end
2031 169 mohor
          end
2032 181 mohor
          // check if transfer was a proper length
2033
          if (i2) // without preamble
2034 169 mohor
          begin
2035 181 mohor
            if (cnt != 33) // at this value Mdio_IO is HIGH Z
2036
            begin
2037
              test_fail("New request did not proceed correctly, after read request");
2038
              fail = fail + 1;
2039
            end
2040 169 mohor
          end
2041 181 mohor
          else // with preamble
2042 169 mohor
          begin
2043 181 mohor
            if (cnt != 65) // at this value Mdio_IO is HIGH Z
2044
            begin
2045
              test_fail("New request did not proceed correctly, after read request");
2046
              fail = fail + 1;
2047
            end
2048 169 mohor
          end
2049
        end
2050 181 mohor
        #Tp;
2051
        // set delay of writing the command
2052 169 mohor
        if (i2) // without preamble
2053
        begin
2054 181 mohor
          case(i)
2055
            0, 1:               i = i + 1;
2056
            18, 19, 20, 21, 22,
2057
            23, 24, 25, 26, 27,
2058
            28, 29, 30, 31, 32,
2059
            33, 34, 35:         i = i + 1;
2060
            36:                 i = 80;
2061
            default:            i = 18;
2062
          endcase
2063 169 mohor
        end
2064
        else // with preamble
2065
        begin
2066 181 mohor
          case(i)
2067
            0, 1:               i = i + 1;
2068
            50, 51, 52, 53, 54,
2069
            55, 56, 57, 58, 59,
2070
            60, 61, 62, 63, 64,
2071
            65, 66, 67:         i = i + 1;
2072
            68:                 i = 80;
2073
            default:            i = 50;
2074
          endcase
2075 169 mohor
        end
2076 181 mohor
        @(posedge wb_clk);
2077 169 mohor
      end
2078
    end
2079 181 mohor
    // set PHY to normal mode
2080
    #Tp eth_phy.preamble_suppresed(0);
2081
    // MII mode register
2082
    wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2083
    if(fail == 0)
2084
      test_ok;
2085
    else
2086
      fail = 0;
2087 169 mohor
  end
2088
 
2089
 
2090 181 mohor
  ////////////////////////////////////////////////////////////////////
2091
  ////                                                            ////
2092
  ////  Test sliding stop scan command immediately after write    ////
2093
  ////  request (with and without preamble)                       ////
2094
  ////                                                            ////
2095
  ////////////////////////////////////////////////////////////////////
2096
  if (test_num == 10) // 
2097 169 mohor
  begin
2098 194 tadej
    // TEST 10: SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER WRITE REQUEST ( WITH AND WITHOUT PREAMBLE )
2099
    test_name = "TEST 10: SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER WRITE REQUEST ( WITH AND WITHOUT PREAMBLE )";
2100 181 mohor
    `TIME;
2101 194 tadej
    $display("  TEST 10: SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER WRITE REQUEST ( WITH AND WITHOUT PREAMBLE )");
2102 181 mohor
 
2103
    for (i2 = 0; i2 <= 1; i2 = i2 + 1) // choose preamble or not
2104 169 mohor
    begin
2105 181 mohor
      #Tp eth_phy.preamble_suppresed(i2);
2106
      // MII mode register
2107
      wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i2, 8'h0}), 4'hF, 1, wbm_init_waits,
2108
                wbm_subseq_waits);
2109
      i = 0;
2110
      cnt = 0;
2111
      while (i < 80) // delay for sliding of writing a STOP SCAN command
2112 169 mohor
      begin
2113 181 mohor
        for (i3 = 0; i3 <= 1; i3 = i3 + 1) // choose read or write after write will be finished
2114
        begin
2115
          // set address
2116
          reg_addr = 5'h0; // control register
2117
          phy_addr = 5'h1; // correct PHY address
2118
          cnt = 0;
2119
          // write request
2120
          phy_data = {8'h75, (i[7:0] + 1)};
2121
          #Tp mii_write_req(phy_addr, reg_addr, phy_data);
2122
          fork
2123
            begin
2124
              repeat(i) @(posedge Mdc_O);
2125
              // write command 0x0 into MII command register
2126
              // MII command written while read in progress
2127
              wbm_write(`ETH_MIICOMMAND, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2128
              @(posedge wb_clk);
2129
              #Tp check_mii_busy; // wait for write to finish
2130
            end
2131
            begin
2132
              // wait for serial bus to become active
2133
              wait(Mdio_IO !== 1'bz);
2134
              // count transfer length
2135
              while(Mdio_IO !== 1'bz)
2136
              begin
2137
                @(posedge Mdc_O);
2138
                #Tp cnt = cnt + 1;
2139
              end
2140
            end
2141
          join
2142
          // check transfer length
2143
          if (i2) // without preamble
2144 169 mohor
          begin
2145 181 mohor
            if (cnt != 33) // at this value Mdio_IO is HIGH Z
2146
            begin
2147
              test_fail("Write request did not proceed correctly, while SCAN STOP command was written");
2148
              fail = fail + 1;
2149
            end
2150 169 mohor
          end
2151 181 mohor
          else // with preamble
2152 169 mohor
          begin
2153 181 mohor
            if (cnt != 65) // at this value Mdio_IO is HIGH Z
2154
            begin
2155
              test_fail("Write request did not proceed correctly, while SCAN STOP command was written");
2156
              fail = fail + 1;
2157
            end
2158
          end
2159
          // check the BUSY signal to see if the bus is still IDLE
2160
          for (i1 = 0; i1 < 8; i1 = i1 + 1)
2161
            check_mii_busy; // wait for bus to become idle
2162
 
2163
          // try normal write or read after write was finished
2164
          #Tp cnt = 0;
2165
          if (i3 == 0) // write after write
2166
          begin
2167
            phy_data = {8'h7A, (i[7:0] + 1)};
2168
            // write request
2169
            #Tp mii_write_req(phy_addr, reg_addr, phy_data);
2170 169 mohor
            // wait for serial bus to become active
2171
            wait(Mdio_IO !== 1'bz);
2172
            // count transfer length
2173
            while(Mdio_IO !== 1'bz)
2174
            begin
2175
              @(posedge Mdc_O);
2176
              #Tp cnt = cnt + 1;
2177
            end
2178 181 mohor
            @(posedge Mdc_O);
2179
            // read request
2180
            #Tp mii_read_req(phy_addr, reg_addr);
2181
            check_mii_busy; // wait for read to finish
2182
            // read and check data
2183
            #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data , 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2184
            if (phy_data !== tmp_data)
2185
            begin
2186
              test_fail("Data was not correctly written into OR read from PHY register - control register");
2187
              fail = fail + 1;
2188
            end
2189 169 mohor
          end
2190 181 mohor
          else // read after write
2191 169 mohor
          begin
2192 181 mohor
            // read request
2193
            #Tp mii_read_req(phy_addr, reg_addr);
2194
            // wait for serial bus to become active
2195
            wait(Mdio_IO !== 1'bz);
2196
            // count transfer length
2197
            while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
2198
            begin
2199
              @(posedge Mdc_O);
2200
              #Tp cnt = cnt + 1;
2201
            end
2202 169 mohor
            @(posedge Mdc_O);
2203 181 mohor
            check_mii_busy; // wait for read to finish
2204
            // read and check data
2205
            #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data , 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2206
            if (phy_data !== tmp_data)
2207
            begin
2208
              test_fail("Data was not correctly written into OR read from PHY register - control register");
2209
              fail = fail + 1;
2210
            end
2211 169 mohor
          end
2212 181 mohor
          // check if transfer was a proper length
2213
          if (i2) // without preamble
2214 169 mohor
          begin
2215 181 mohor
            if (cnt != 33) // at this value Mdio_IO is HIGH Z
2216
            begin
2217
              test_fail("New request did not proceed correctly, after write request");
2218
              fail = fail + 1;
2219
            end
2220 169 mohor
          end
2221 181 mohor
          else // with preamble
2222 169 mohor
          begin
2223 181 mohor
            if (cnt != 65) // at this value Mdio_IO is HIGH Z
2224
            begin
2225
              test_fail("New request did not proceed correctly, after write request");
2226
              fail = fail + 1;
2227
            end
2228 169 mohor
          end
2229
        end
2230 181 mohor
        #Tp;
2231
        // set delay of writing the command
2232 169 mohor
        if (i2) // without preamble
2233
        begin
2234 181 mohor
          case(i)
2235
            0, 1:               i = i + 1;
2236
            18, 19, 20, 21, 22,
2237
            23, 24, 25, 26, 27,
2238
            28, 29, 30, 31, 32,
2239
            33, 34, 35:         i = i + 1;
2240
            36:                 i = 80;
2241
            default:            i = 18;
2242
          endcase
2243 169 mohor
        end
2244
        else // with preamble
2245
        begin
2246 181 mohor
          case(i)
2247
            0, 1:               i = i + 1;
2248
            50, 51, 52, 53, 54,
2249
            55, 56, 57, 58, 59,
2250
            60, 61, 62, 63, 64,
2251
            65, 66, 67:         i = i + 1;
2252
            68:                 i = 80;
2253
            default:            i = 50;
2254
          endcase
2255 169 mohor
        end
2256 181 mohor
        @(posedge wb_clk);
2257 169 mohor
      end
2258
    end
2259 181 mohor
    // set PHY to normal mode
2260
    #Tp eth_phy.preamble_suppresed(0);
2261
    // MII mode register
2262
    wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2263
    if(fail == 0)
2264
      test_ok;
2265
    else
2266
      fail = 0;
2267 169 mohor
  end
2268
 
2269
 
2270 181 mohor
  ////////////////////////////////////////////////////////////////////
2271
  ////                                                            ////
2272
  ////  Test busy and nvalid status durations during write (with  ////
2273
  ////  and without preamble)                                     ////
2274
  ////                                                            ////
2275
  ////////////////////////////////////////////////////////////////////
2276
  if (test_num == 11) // 
2277 169 mohor
  begin
2278 194 tadej
    // TEST 11: BUSY AND NVALID STATUS DURATIONS DURING WRITE ( WITH AND WITHOUT PREAMBLE )
2279
    test_name   = "TEST 11: BUSY AND NVALID STATUS DURATIONS DURING WRITE ( WITH AND WITHOUT PREAMBLE )";
2280
    `TIME; $display("  TEST 11: BUSY AND NVALID STATUS DURATIONS DURING WRITE ( WITH AND WITHOUT PREAMBLE )");
2281 181 mohor
 
2282
    reset_mii; // reset MII
2283
    // set link up, if it wasn't due to previous tests, since there weren't PHY registers
2284
    #Tp eth_phy.link_up_down(1);
2285
    // set the MII
2286
    clk_div = 64;
2287
    mii_set_clk_div(clk_div[7:0]);
2288
    // set address
2289
    reg_addr = 5'h1; // status register
2290
    phy_addr = 5'h1; // correct PHY address
2291
 
2292
    for (i = 0; i <= 1; i = i + 1)
2293 169 mohor
    begin
2294 181 mohor
      #Tp eth_phy.preamble_suppresed(i);
2295
      // MII mode register
2296
      wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}) | (`ETH_MIIMODER_CLKDIV & clk_div),
2297
                4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2298
      @(posedge Mdc_O);
2299
      // write request
2300
      #Tp mii_write_req(phy_addr, reg_addr, 16'h5A5A);
2301
      // read data from MII status register - Busy and Nvalid bits
2302
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2303
 
2304
      // check MII IO signal and Busy and Nvalid bits
2305
      if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
2306 169 mohor
      begin
2307 181 mohor
        test_fail("Testbench error - read was to late, Mdio_IO is not HIGH Z - set higher clock divider");
2308
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2309
        begin
2310
          test_fail("Busy signal was not set while MII IO signal is not HIGH Z anymore - 1. read");
2311
          fail = fail + 1;
2312
        end
2313
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2314
        begin
2315
          test_fail("Nvalid signal was set during write");
2316
          fail = fail + 1;
2317
        end
2318 169 mohor
      end
2319 181 mohor
      else // Busy bit should already be set to '1', due to reads from MII status register
2320 169 mohor
      begin
2321 181 mohor
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2322
        begin
2323
          test_fail("Busy signal should be set after write, due to reads from MII status register");
2324
          fail = fail + 1;
2325
        end
2326
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2327
        begin
2328
          test_fail("Nvalid signal was set during write");
2329
          fail = fail + 1;
2330
        end
2331 169 mohor
      end
2332 181 mohor
 
2333
      // wait for serial bus to become active
2334
      wait(Mdio_IO !== 1'bz);
2335
      // count transfer bits
2336
      if (i)
2337 169 mohor
      begin
2338 181 mohor
        repeat(32) @(posedge Mdc_O);
2339 169 mohor
      end
2340 181 mohor
      else
2341 169 mohor
      begin
2342 181 mohor
        repeat(64) @(posedge Mdc_O);
2343 169 mohor
      end
2344 181 mohor
      // read data from MII status register - Busy and Nvalid bits
2345
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2346
 
2347
      // check MII IO signal and Busy and Nvalid bits
2348
      if (Mdio_IO === 1'bz) // Mdio_IO should not be HIGH Z here - testbench selfcheck
2349 169 mohor
      begin
2350 181 mohor
        test_fail("Testbench error - read was to late, Mdio_IO is HIGH Z - set higher clock divider");
2351
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2352
        begin
2353
          test_fail("Busy signal should be set while MII IO signal is not active anymore");
2354
          fail = fail + 1;
2355
        end
2356
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2357
        begin
2358
          test_fail("Nvalid signal was set during write");
2359
          fail = fail + 1;
2360
        end
2361 169 mohor
      end
2362 181 mohor
      else // Busy bit should still be set to '1'
2363 169 mohor
      begin
2364 181 mohor
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2365
        begin
2366
          test_fail("Busy signal should be set while MII IO signal not HIGH Z");
2367
          fail = fail + 1;
2368
        end
2369
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2370
        begin
2371
          test_fail("Nvalid signal was set during write");
2372
          fail = fail + 1;
2373
        end
2374 169 mohor
      end
2375 181 mohor
 
2376
      // wait for next negative clock edge
2377
      @(negedge Mdc_O);
2378 169 mohor
      // read data from MII status register - Busy and Nvalid bits
2379
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2380 181 mohor
 
2381 169 mohor
      // check MII IO signal and Busy and Nvalid bits
2382
      if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
2383
      begin
2384
        test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider");
2385
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2386
        begin
2387
          test_fail("Busy signal was not set while MII IO signal is not HIGH Z");
2388
          fail = fail + 1;
2389
        end
2390
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2391
        begin
2392
          test_fail("Nvalid signal was set during write");
2393
          fail = fail + 1;
2394
        end
2395
      end
2396 181 mohor
      else // Busy bit should still be set to '1'
2397 169 mohor
      begin
2398
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2399
        begin
2400 181 mohor
          test_fail("Busy signal should be set after MII IO signal become HIGH Z");
2401
          fail = fail + 1;
2402 169 mohor
        end
2403 181 mohor
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2404 169 mohor
        begin
2405 181 mohor
          test_fail("Nvalid signal was set during write");
2406
          fail = fail + 1;
2407
        end
2408
      end
2409
 
2410
      // wait for Busy to become inactive
2411
      i1 = 0;
2412
      while (i1 <= 2)
2413
      begin
2414
        // wait for next positive clock edge
2415
        @(posedge Mdc_O);
2416
        // read data from MII status register - Busy and Nvalid bits
2417
        #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2418
 
2419
        // check MII IO signal and Busy and Nvalid bits
2420
        if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
2421
        begin
2422
          test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider");
2423
          if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2424 169 mohor
          begin
2425 181 mohor
            test_fail("Busy signal was not set while MII IO signal is not HIGH Z");
2426 169 mohor
            fail = fail + 1;
2427
          end
2428 181 mohor
          if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2429
          begin
2430
            test_fail("Nvalid signal was set during write");
2431
            fail = fail + 1;
2432
          end
2433 169 mohor
        end
2434 181 mohor
        else // wait for Busy bit to be set to '0'
2435 169 mohor
        begin
2436 181 mohor
          if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2437
          begin
2438
            i1 = 3; // end of Busy checking
2439
          end
2440
          else
2441
          begin
2442
            if (i1 == 2)
2443
            begin
2444
              test_fail("Busy signal should be cleared after 2 periods after MII IO signal become HIGH Z");
2445
              fail = fail + 1;
2446
            end
2447
            #Tp i1 = i1 + 1;
2448
          end
2449
          if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2450
          begin
2451
            test_fail("Nvalid signal was set after write");
2452
            fail = fail + 1;
2453
          end
2454 169 mohor
        end
2455
      end
2456
    end
2457 181 mohor
    // set PHY to normal mode
2458
    #Tp eth_phy.preamble_suppresed(0);
2459
    // MII mode register
2460
    wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2461
    if(fail == 0)
2462
      test_ok;
2463
    else
2464
      fail = 0;
2465 116 mohor
  end
2466
 
2467
 
2468 181 mohor
  ////////////////////////////////////////////////////////////////////
2469
  ////                                                            ////
2470
  ////  Test busy and nvalid status durations during write (with  ////
2471
  ////  and without preamble)                                     ////
2472
  ////                                                            ////
2473
  ////////////////////////////////////////////////////////////////////
2474
  if (test_num == 12) // 
2475 169 mohor
  begin
2476 194 tadej
    // TEST 12: BUSY AND NVALID STATUS DURATIONS DURING READ ( WITH AND WITHOUT PREAMBLE )
2477
    test_name   = "TEST 12: BUSY AND NVALID STATUS DURATIONS DURING READ ( WITH AND WITHOUT PREAMBLE )";
2478
    `TIME; $display("  TEST 12: BUSY AND NVALID STATUS DURATIONS DURING READ ( WITH AND WITHOUT PREAMBLE )");
2479 181 mohor
 
2480
    reset_mii; // reset MII
2481
    // set link up, if it wasn't due to previous tests, since there weren't PHY registers
2482
    #Tp eth_phy.link_up_down(1);
2483
    // set the MII
2484
    clk_div = 64;
2485
    mii_set_clk_div(clk_div[7:0]);
2486
    // set address
2487
    reg_addr = 5'h1; // status register
2488
    phy_addr = 5'h1; // correct PHY address
2489
 
2490
    for (i = 0; i <= 1; i = i + 1)
2491 169 mohor
    begin
2492 181 mohor
      #Tp eth_phy.preamble_suppresed(i);
2493
      // MII mode register
2494
      wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}) | (`ETH_MIIMODER_CLKDIV & clk_div),
2495
                4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2496 169 mohor
      @(posedge Mdc_O);
2497 181 mohor
      // read request
2498
      #Tp mii_read_req(phy_addr, reg_addr);
2499 169 mohor
      // read data from MII status register - Busy and Nvalid bits
2500
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2501 181 mohor
 
2502 169 mohor
      // check MII IO signal and Busy and Nvalid bits
2503
      if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
2504
      begin
2505 181 mohor
        test_fail("Testbench error - read was to late, Mdio_IO is not HIGH Z - set higher clock divider");
2506 169 mohor
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2507
        begin
2508 181 mohor
          test_fail("Busy signal was not set while MII IO signal is not HIGH Z anymore - 1. read");
2509 169 mohor
          fail = fail + 1;
2510
        end
2511
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2512
        begin
2513
          test_fail("Nvalid signal was set during read");
2514
          fail = fail + 1;
2515
        end
2516
      end
2517 181 mohor
      else // Busy bit should already be set to '1', due to reads from MII status register
2518 169 mohor
      begin
2519
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2520
        begin
2521 181 mohor
          test_fail("Busy signal should be set after read, due to reads from MII status register");
2522
          fail = fail + 1;
2523 169 mohor
        end
2524
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2525
        begin
2526 181 mohor
          test_fail("Nvalid signal was set during read");
2527 169 mohor
          fail = fail + 1;
2528
        end
2529
      end
2530 181 mohor
 
2531
      // wait for serial bus to become active
2532
      wait(Mdio_IO !== 1'bz);
2533
      // count transfer bits
2534
      if (i)
2535 169 mohor
      begin
2536 181 mohor
        repeat(31) @(posedge Mdc_O);
2537 169 mohor
      end
2538 181 mohor
      else
2539 169 mohor
      begin
2540 181 mohor
        repeat(63) @(posedge Mdc_O);
2541 169 mohor
      end
2542 181 mohor
      // wait for next negative clock edge
2543
      @(negedge Mdc_O);
2544
      // read data from MII status register - Busy and Nvalid bits
2545
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2546
 
2547
      // check MII IO signal and Busy and Nvalid bits
2548
      if (Mdio_IO === 1'bz) // Mdio_IO should not be HIGH Z here - testbench selfcheck
2549 169 mohor
      begin
2550 181 mohor
        test_fail("Testbench error - read was to late, Mdio_IO is HIGH Z - set higher clock divider");
2551
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2552
        begin
2553
          test_fail("Busy signal should be set while MII IO signal is not active anymore");
2554
          fail = fail + 1;
2555
        end
2556
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2557
        begin
2558
          test_fail("Nvalid signal was set during read");
2559
          fail = fail + 1;
2560
        end
2561 169 mohor
      end
2562 181 mohor
      else // Busy bit should still be set to '1'
2563 169 mohor
      begin
2564 181 mohor
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2565
        begin
2566
          test_fail("Busy signal should be set while MII IO signal not HIGH Z");
2567
          fail = fail + 1;
2568
        end
2569
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2570
        begin
2571
          test_fail("Nvalid signal was set during read");
2572
          fail = fail + 1;
2573
        end
2574 169 mohor
      end
2575 181 mohor
 
2576 169 mohor
      // wait for next positive clock edge
2577
      @(posedge Mdc_O);
2578
      // read data from MII status register - Busy and Nvalid bits
2579
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2580 181 mohor
 
2581 169 mohor
      // check MII IO signal and Busy and Nvalid bits
2582
      if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
2583
      begin
2584
        test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider");
2585 181 mohor
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2586 169 mohor
        begin
2587 181 mohor
          test_fail("Busy signal was not set while MII IO signal is not HIGH Z");
2588
          fail = fail + 1;
2589
        end
2590
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2591
        begin
2592
          test_fail("Nvalid signal was set during read");
2593
          fail = fail + 1;
2594
        end
2595
      end
2596
      else // Busy bit should still be set to '1'
2597
      begin
2598
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2599
        begin
2600
          test_fail("Busy signal should be set after MII IO signal become HIGH Z");
2601
          fail = fail + 1;
2602
        end
2603
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2604
        begin
2605
          test_fail("Nvalid signal was set during read");
2606
          fail = fail + 1;
2607
        end
2608
      end
2609
 
2610
      // wait for Busy to become inactive
2611
      i1 = 0;
2612
      while (i1 <= 2)
2613
      begin
2614
        // wait for next positive clock edge
2615
        @(posedge Mdc_O);
2616
        // read data from MII status register - Busy and Nvalid bits
2617
        #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2618
 
2619
        // check MII IO signal and Busy and Nvalid bits
2620
        if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
2621
        begin
2622
          test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider");
2623 169 mohor
          if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2624
          begin
2625
            test_fail("Busy signal was not set while MII IO signal is not HIGH Z");
2626
            fail = fail + 1;
2627
          end
2628 181 mohor
          if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2629 169 mohor
          begin
2630 181 mohor
            test_fail("Nvalid signal was set during read");
2631 169 mohor
            fail = fail + 1;
2632
          end
2633
        end
2634 181 mohor
        else // wait for Busy bit to be set to '0'
2635 169 mohor
        begin
2636
          if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2637
          begin
2638
            i1 = 3; // end of Busy checking
2639
          end
2640
          else
2641
          begin
2642
            if (i1 == 2)
2643
            begin
2644
              test_fail("Busy signal should be cleared after 2 periods after MII IO signal become HIGH Z");
2645
              fail = fail + 1;
2646
            end
2647
            #Tp i1 = i1 + 1;
2648
          end
2649 181 mohor
          if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2650 169 mohor
          begin
2651 181 mohor
            test_fail("Nvalid signal was set after read");
2652 169 mohor
            fail = fail + 1;
2653
          end
2654
        end
2655
      end
2656
    end
2657 181 mohor
    // set PHY to normal mode
2658
    #Tp eth_phy.preamble_suppresed(0);
2659
    // MII mode register
2660
    wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2661
    if(fail == 0)
2662
      test_ok;
2663
    else
2664
      fail = 0;
2665 169 mohor
  end
2666
 
2667
 
2668 181 mohor
  ////////////////////////////////////////////////////////////////////
2669
  ////                                                            ////
2670
  ////  Test busy and nvalid status durations during scan (with   ////
2671
  ////  and without preamble)                                     ////
2672
  ////                                                            ////
2673
  ////////////////////////////////////////////////////////////////////
2674
  if (test_num == 13) // 
2675 169 mohor
  begin
2676 194 tadej
    // TEST 13: BUSY AND NVALID STATUS DURATIONS DURING SCAN ( WITH AND WITHOUT PREAMBLE )
2677
    test_name   = "TEST 13: BUSY AND NVALID STATUS DURATIONS DURING SCAN ( WITH AND WITHOUT PREAMBLE )";
2678
    `TIME; $display("  TEST 13: BUSY AND NVALID STATUS DURATIONS DURING SCAN ( WITH AND WITHOUT PREAMBLE )");
2679 181 mohor
 
2680
    reset_mii; // reset MII
2681
    // set link up, if it wasn't due to previous tests, since there weren't PHY registers
2682
    #Tp eth_phy.link_up_down(1);
2683
    // set the MII
2684
    clk_div = 64;
2685
    mii_set_clk_div(clk_div[7:0]);
2686
    // set address
2687
    reg_addr = 5'h1; // status register
2688
    phy_addr = 5'h1; // correct PHY address
2689
 
2690
    for (i = 0; i <= 1; i = i + 1)
2691 169 mohor
    begin
2692 181 mohor
      #Tp eth_phy.preamble_suppresed(i);
2693
      // MII mode register
2694
      wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}) | (`ETH_MIIMODER_CLKDIV & clk_div),
2695
                4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2696
      @(posedge Mdc_O);
2697
      // scan request
2698
      #Tp mii_scan_req(phy_addr, reg_addr);
2699
      // read data from MII status register - Busy and Nvalid bits
2700
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2701
 
2702
      // check MII IO signal and Busy and Nvalid bits
2703
      if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
2704 169 mohor
      begin
2705 181 mohor
        test_fail("Testbench error - read was to late, Mdio_IO is not HIGH Z - set higher clock divider");
2706
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2707
        begin
2708
          test_fail("Busy signal was not set while MII IO signal is not HIGH Z anymore - 1. read");
2709
          fail = fail + 1;
2710
        end
2711
        if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
2712
        begin
2713
          test_fail("Nvalid signal was not set while MII IO signal is not HIGH Z anymore - 1. read");
2714
          fail = fail + 1;
2715
        end
2716 169 mohor
      end
2717 181 mohor
      else // Busy bit should already be set to '1', due to reads from MII status register
2718 169 mohor
      begin
2719 181 mohor
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2720
        begin
2721
          test_fail("Busy signal should be set after scan, due to reads from MII status register");
2722
          fail = fail + 1;
2723
        end
2724
        if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
2725
        begin
2726
          test_fail("Nvalid signal should be set after scan, due to reads from MII status register");
2727
          fail = fail + 1;
2728
        end
2729 169 mohor
      end
2730 181 mohor
 
2731
      // wait for serial bus to become active
2732 169 mohor
      wait(Mdio_IO !== 1'bz);
2733 181 mohor
      // count transfer bits
2734
      if (i)
2735 169 mohor
      begin
2736 181 mohor
        repeat(21) @(posedge Mdc_O);
2737 169 mohor
      end
2738 181 mohor
      else
2739 169 mohor
      begin
2740 181 mohor
        repeat(53) @(posedge Mdc_O);
2741 169 mohor
      end
2742 181 mohor
      // stop scan
2743
      #Tp mii_scan_finish; // finish scan operation
2744
 
2745
      // wait for next positive clock edge
2746
      repeat(10) @(posedge Mdc_O);
2747
      // read data from MII status register - Busy and Nvalid bits
2748
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2749
 
2750
      // check MII IO signal and Busy and Nvalid bits
2751
      if (Mdio_IO === 1'bz) // Mdio_IO should not be HIGH Z here - testbench selfcheck
2752 169 mohor
      begin
2753 181 mohor
        test_fail("Testbench error - read was to late, Mdio_IO is HIGH Z - set higher clock divider");
2754
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2755 169 mohor
        begin
2756 181 mohor
          test_fail("Busy signal should be set while MII IO signal is not active anymore");
2757 169 mohor
          fail = fail + 1;
2758
        end
2759 181 mohor
        // Nvalid signal can be cleared here - it is still Testbench error
2760 169 mohor
      end
2761 181 mohor
      else // Busy bit should still be set to '1', Nvalid bit should still be set to '1'
2762 169 mohor
      begin
2763 181 mohor
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2764 169 mohor
        begin
2765 181 mohor
          test_fail("Busy signal should be set while MII IO signal not HIGH Z");
2766 169 mohor
          fail = fail + 1;
2767
        end
2768 181 mohor
        if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
2769 169 mohor
        begin
2770 181 mohor
          test_fail("Nvalid signal should be set while MII IO signal not HIGH Z");
2771 169 mohor
          fail = fail + 1;
2772
        end
2773 181 mohor
      end
2774
 
2775
      // wait for next negative clock edge
2776
      @(negedge Mdc_O);
2777
      // read data from MII status register - Busy and Nvalid bits
2778
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2779
 
2780
      // check MII IO signal and Busy and Nvalid bits
2781
      if (Mdio_IO === 1'bz) // Mdio_IO should not be HIGH Z here - testbench selfcheck
2782
      begin
2783
        test_fail("Testbench error - read was to late, Mdio_IO is HIGH Z - set higher clock divider");
2784
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2785 169 mohor
        begin
2786 181 mohor
          test_fail("Busy signal should be set while MII IO signal is not active anymore");
2787
          fail = fail + 1;
2788 169 mohor
        end
2789 181 mohor
        // Nvalid signal can be cleared here - it is still Testbench error
2790 169 mohor
      end
2791 181 mohor
      else // Busy bit should still be set to '1', Nvalid bit should still be set to '1'
2792 169 mohor
      begin
2793 181 mohor
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2794 169 mohor
        begin
2795 181 mohor
          test_fail("Busy signal should be set while MII IO signal not HIGH Z");
2796
          fail = fail + 1;
2797 169 mohor
        end
2798 181 mohor
        if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
2799 169 mohor
        begin
2800 181 mohor
          test_fail("Nvalid signal should be set while MII IO signal not HIGH Z");
2801
          fail = fail + 1;
2802 169 mohor
        end
2803
      end
2804 181 mohor
 
2805
      // wait for next negative clock edge
2806
      @(posedge Mdc_O);
2807
      // read data from MII status register - Busy and Nvalid bits
2808 169 mohor
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2809 181 mohor
 
2810
      // check MII IO signal and Busy and Nvalid bits
2811
      if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
2812 169 mohor
      begin
2813 181 mohor
        test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider");
2814
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2815 169 mohor
        begin
2816 181 mohor
          test_fail("Busy signal was not set while MII IO signal is not HIGH Z");
2817 169 mohor
          fail = fail + 1;
2818
        end
2819 181 mohor
        if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
2820 169 mohor
        begin
2821 181 mohor
          test_fail("Nvalid signal was not set while MII IO signal is not HIGH Z");
2822 169 mohor
          fail = fail + 1;
2823
        end
2824
      end
2825 181 mohor
      else // Busy bit should still be set to '1', Nvalid bit can be set to '0'
2826 169 mohor
      begin
2827 181 mohor
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2828 169 mohor
        begin
2829 181 mohor
          test_fail("Busy signal should be set after MII IO signal become HIGH Z");
2830
          fail = fail + 1;
2831 169 mohor
        end
2832 181 mohor
        if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
2833 169 mohor
        begin
2834 181 mohor
          i2 = 1; // check finished
2835 169 mohor
        end
2836 181 mohor
        else
2837 169 mohor
        begin
2838 181 mohor
          i2 = 0; // check must continue
2839 169 mohor
        end
2840
      end
2841 181 mohor
 
2842
      // wait for Busy to become inactive
2843
      i1 = 0;
2844
      while ((i1 <= 2) || (i2 == 0))
2845
      begin
2846
        // wait for next positive clock edge
2847
        @(posedge Mdc_O);
2848
        // read data from MII status register - Busy and Nvalid bits
2849
        #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2850
 
2851
        // check MII IO signal and Busy and Nvalid bits
2852
        if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
2853 169 mohor
        begin
2854 181 mohor
          test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider");
2855
          if (i1 <= 2)
2856 169 mohor
          begin
2857 181 mohor
            if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2858 169 mohor
            begin
2859 181 mohor
              test_fail("Busy signal was not set while MII IO signal is not HIGH Z");
2860 169 mohor
              fail = fail + 1;
2861
            end
2862
          end
2863 181 mohor
          if (i2 == 0)
2864 169 mohor
          begin
2865 181 mohor
            if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
2866 169 mohor
            begin
2867 181 mohor
              test_fail("Nvalid signal was not set while MII IO signal is not HIGH Z");
2868 169 mohor
              fail = fail + 1;
2869
            end
2870
          end
2871
        end
2872 181 mohor
        else // wait for Busy bit to be set to '0'
2873 169 mohor
        begin
2874 181 mohor
          if (i1 <= 2)
2875 169 mohor
          begin
2876 181 mohor
            if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2877 169 mohor
            begin
2878 181 mohor
              i1 = 3; // end of Busy checking
2879 169 mohor
            end
2880 181 mohor
            else
2881 169 mohor
            begin
2882 181 mohor
              if (i1 == 2)
2883 169 mohor
              begin
2884 181 mohor
                test_fail("Busy signal should be cleared after 2 periods after MII IO signal become HIGH Z");
2885 169 mohor
                fail = fail + 1;
2886
              end
2887 181 mohor
              #Tp i1 = i1 + 1;
2888 169 mohor
            end
2889 181 mohor
          end
2890
          if (i2 == 0)
2891
          begin
2892
            if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
2893 169 mohor
            begin
2894 181 mohor
              i2 = 1;
2895 169 mohor
            end
2896 181 mohor
            else
2897
            begin
2898
              test_fail("Nvalid signal should be cleared after MII IO signal become HIGH Z");
2899
              fail = fail + 1;
2900
            end
2901 169 mohor
          end
2902
        end
2903 181 mohor
      end
2904
    end
2905
    // set PHY to normal mode
2906
    #Tp eth_phy.preamble_suppresed(0);
2907
    // MII mode register
2908
    wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2909
    if(fail == 0)
2910
      test_ok;
2911
    else
2912
      fail = 0;
2913
  end
2914
 
2915
 
2916
  ////////////////////////////////////////////////////////////////////
2917
  ////                                                            ////
2918
  ////  Test scan status from phy with detecting link-fail bit    ////
2919
  ////  (with and without preamble)                               ////
2920
  ////                                                            ////
2921
  ////////////////////////////////////////////////////////////////////
2922
  if (test_num == 14) // 
2923
  begin
2924 194 tadej
    // TEST 14: SCAN STATUS FROM PHY WITH DETECTING LINK-FAIL BIT ( WITH AND WITHOUT PREAMBLE )
2925
    test_name   = "TEST 14: SCAN STATUS FROM PHY WITH DETECTING LINK-FAIL BIT ( WITH AND WITHOUT PREAMBLE )";
2926
    `TIME; $display("  TEST 14: SCAN STATUS FROM PHY WITH DETECTING LINK-FAIL BIT ( WITH AND WITHOUT PREAMBLE )");
2927 181 mohor
 
2928
    reset_mii; // reset MII
2929
    // set link up, if it wasn't due to previous tests, since there weren't PHY registers
2930
    #Tp eth_phy.link_up_down(1);
2931
    // set MII speed
2932
    clk_div = 6;
2933
    mii_set_clk_div(clk_div[7:0]);
2934
    // set address
2935
    reg_addr = 5'h1; // status register
2936
    phy_addr = 5'h1; // correct PHY address
2937
 
2938
    // read request
2939
    #Tp mii_read_req(phy_addr, reg_addr);
2940
    check_mii_busy; // wait for read to finish
2941
    // read data from PHY status register - remember LINK-UP status
2942
    #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2943
 
2944
    for (i = 0; i <= 1; i = i + 1)
2945
    begin
2946
      #Tp eth_phy.preamble_suppresed(i);
2947
      // MII mode register
2948
      wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}) | (`ETH_MIIMODER_CLKDIV & clk_div),
2949
                4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2950
      if (i)
2951
      begin
2952
        // change saved data when preamble is suppressed
2953
        #Tp tmp_data = tmp_data | 16'h0040; // put bit 6 to ONE
2954
      end
2955
 
2956
      // scan request
2957
      #Tp mii_scan_req(phy_addr, reg_addr);
2958
      check_mii_scan_valid; // wait for scan to make first data valid
2959
 
2960 169 mohor
      fork
2961 181 mohor
      begin
2962 169 mohor
        repeat(2) @(posedge Mdc_O);
2963
        // read data from PHY status register
2964
        #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2965 181 mohor
        if (phy_data !== tmp_data)
2966 169 mohor
        begin
2967 181 mohor
          test_fail("Data was not correctly scaned from status register");
2968 169 mohor
          fail = fail + 1;
2969
        end
2970
        // read data from MII status register
2971
        #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2972 181 mohor
        if (phy_data[0] !== 1'b0)
2973 169 mohor
        begin
2974 181 mohor
          test_fail("Link FAIL bit was set in the MII status register");
2975 169 mohor
          fail = fail + 1;
2976
        end
2977
      end
2978
      begin
2979 181 mohor
      // Completely check second scan
2980 169 mohor
        #Tp cnt = 0;
2981
        // wait for serial bus to become active - second scan
2982
        wait(Mdio_IO !== 1'bz);
2983
        // count transfer length
2984 181 mohor
        while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i == 0)) || ((cnt == 15) && (i == 1)) )
2985 169 mohor
        begin
2986
          @(posedge Mdc_O);
2987
          #Tp cnt = cnt + 1;
2988
        end
2989
        // check transfer length
2990 181 mohor
        if (i) // without preamble
2991 169 mohor
        begin
2992
          if (cnt != 33) // at this value Mdio_IO is HIGH Z
2993
          begin
2994 181 mohor
            test_fail("Second scan request did not proceed correctly");
2995 169 mohor
            fail = fail + 1;
2996
          end
2997
        end
2998
        else // with preamble
2999
        begin
3000
          if (cnt != 65) // at this value Mdio_IO is HIGH Z
3001
          begin
3002 181 mohor
            test_fail("Second scan request did not proceed correctly");
3003 169 mohor
            fail = fail + 1;
3004
          end
3005
        end
3006
      end
3007
      join
3008 181 mohor
      // check third to fifth scans
3009
      for (i3 = 0; i3 <= 2; i3 = i3 + 1)
3010
      begin
3011
        fork
3012 169 mohor
        begin
3013
          repeat(2) @(posedge Mdc_O);
3014
          // read data from PHY status register
3015
          #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3016 181 mohor
          if (phy_data !== tmp_data)
3017 169 mohor
          begin
3018 181 mohor
            test_fail("Data was not correctly scaned from status register");
3019
            fail = fail + 1;
3020 169 mohor
          end
3021
          // read data from MII status register
3022
          #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3023 181 mohor
          if (phy_data[0] !== 1'b0)
3024 169 mohor
          begin
3025 181 mohor
            test_fail("Link FAIL bit was set in the MII status register");
3026
            fail = fail + 1;
3027 169 mohor
          end
3028 181 mohor
          if (i3 == 2) // after fourth scan read
3029 169 mohor
          begin
3030 181 mohor
            @(posedge Mdc_O);
3031
            // change saved data
3032
            #Tp tmp_data = tmp_data & 16'hFFFB; // put bit 3 to ZERO
3033
            // set link down
3034
            #Tp eth_phy.link_up_down(0);
3035 169 mohor
          end
3036
        end
3037
        begin
3038 181 mohor
        // Completely check scans
3039
          #Tp cnt = 0;
3040
          // wait for serial bus to become active - second scan
3041
          wait(Mdio_IO !== 1'bz);
3042
          // count transfer length
3043
          while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i == 0)) || ((cnt == 15) && (i == 1)) )
3044 169 mohor
          begin
3045 181 mohor
            @(posedge Mdc_O);
3046
            #Tp cnt = cnt + 1;
3047
          end
3048
          // check transfer length
3049
          if (i) // without preamble
3050
          begin
3051
            if (cnt != 33) // at this value Mdio_IO is HIGH Z
3052 169 mohor
            begin
3053 181 mohor
              test_fail("Fifth scan request did not proceed correctly");
3054
              fail = fail + 1;
3055 169 mohor
            end
3056 181 mohor
          end
3057
          else // with preamble
3058
          begin
3059
            if (cnt != 65) // at this value Mdio_IO is HIGH Z
3060 169 mohor
            begin
3061 181 mohor
              test_fail("Fifth scan request did not proceed correctly");
3062
              fail = fail + 1;
3063 169 mohor
            end
3064
          end
3065
        end
3066 181 mohor
        join
3067
      end
3068
 
3069
      fork
3070
      begin
3071
        repeat(2) @(posedge Mdc_O);
3072
        // read data from PHY status register
3073
        #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3074
        if (phy_data !== tmp_data)
3075
        begin
3076
          test_fail("Data was not correctly scaned from status register");
3077
          fail = fail + 1;
3078
        end
3079
        // read data from MII status register
3080
        #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3081
        if (phy_data[0] === 1'b0)
3082
        begin
3083
          test_fail("Link FAIL bit was not set in the MII status register");
3084
          fail = fail + 1;
3085
        end
3086
        // wait to see if data stayed latched
3087
        repeat(4) @(posedge Mdc_O);
3088
        // read data from PHY status register
3089
        #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3090
        if (phy_data !== tmp_data)
3091
        begin
3092
          test_fail("Data was not latched correctly in status register");
3093
          fail = fail + 1;
3094
        end
3095
        // read data from MII status register
3096
        #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3097
        if (phy_data[0] === 1'b0)
3098
        begin
3099
          test_fail("Link FAIL bit was not set in the MII status register");
3100
          fail = fail + 1;
3101
        end
3102
        // change saved data
3103
        #Tp tmp_data = tmp_data | 16'h0004; // put bit 2 to ONE
3104
        // set link up
3105
        #Tp eth_phy.link_up_down(1);
3106
      end
3107
      begin
3108
      // Wait for sixth scan
3109
        // wait for serial bus to become active - sixth scan
3110
        wait(Mdio_IO !== 1'bz);
3111
        // wait for serial bus to become inactive - turn-around cycle in sixth scan
3112
        wait(Mdio_IO === 1'bz);
3113
        // wait for serial bus to become active - end of turn-around cycle in sixth scan
3114
        wait(Mdio_IO !== 1'bz);
3115
        // wait for serial bus to become inactive - end of sixth scan
3116
        wait(Mdio_IO === 1'bz);
3117
      end
3118 169 mohor
      join
3119 181 mohor
 
3120
      @(posedge Mdc_O);
3121 169 mohor
      // read data from PHY status register
3122
      #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3123
      if (phy_data !== tmp_data)
3124
      begin
3125 181 mohor
        test_fail("Data was not correctly scaned from status register");
3126 169 mohor
        fail = fail + 1;
3127
      end
3128
      // read data from MII status register
3129
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3130
      if (phy_data[0] !== 1'b0)
3131
      begin
3132
        test_fail("Link FAIL bit was set in the MII status register");
3133
        fail = fail + 1;
3134
      end
3135 181 mohor
      // wait to see if data stayed latched
3136
      repeat(4) @(posedge Mdc_O);
3137
      // read data from PHY status register
3138
      #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3139
      if (phy_data !== tmp_data)
3140 169 mohor
      begin
3141 181 mohor
        test_fail("Data was not correctly scaned from status register");
3142
        fail = fail + 1;
3143 169 mohor
      end
3144 181 mohor
      // read data from MII status register
3145
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3146
      if (phy_data[0] !== 1'b0)
3147 169 mohor
      begin
3148 181 mohor
        test_fail("Link FAIL bit was set in the MII status register");
3149
        fail = fail + 1;
3150 169 mohor
      end
3151 181 mohor
 
3152
      // STOP SCAN
3153
      #Tp mii_scan_finish; // finish scan operation
3154
      #Tp check_mii_busy; // wait for scan to finish
3155 169 mohor
    end
3156 181 mohor
    // set PHY to normal mode
3157
    #Tp eth_phy.preamble_suppresed(0);
3158
    // MII mode register
3159
    wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3160
    if(fail == 0)
3161
      test_ok;
3162
    else
3163
      fail = 0;
3164 169 mohor
  end
3165
 
3166
 
3167 181 mohor
  ////////////////////////////////////////////////////////////////////
3168
  ////                                                            ////
3169
  ////  Test scan status from phy with sliding link-fail bit      ////
3170
  ////  (with and without preamble)                               ////
3171
  ////                                                            ////
3172
  ////////////////////////////////////////////////////////////////////
3173
  if (test_num == 15) // 
3174 169 mohor
  begin
3175 194 tadej
    // TEST 15: SCAN STATUS FROM PHY WITH SLIDING LINK-FAIL BIT ( WITH AND WITHOUT PREAMBLE )
3176
    test_name   = "TEST 15: SCAN STATUS FROM PHY WITH SLIDING LINK-FAIL BIT ( WITH AND WITHOUT PREAMBLE )";
3177
    `TIME; $display("  TEST 15: SCAN STATUS FROM PHY WITH SLIDING LINK-FAIL BIT ( WITH AND WITHOUT PREAMBLE )");
3178 181 mohor
 
3179
    // set address
3180
    reg_addr = 5'h1; // status register
3181
    phy_addr = 5'h1; // correct PHY address
3182
 
3183
    // read request
3184
    #Tp mii_read_req(phy_addr, reg_addr);
3185
    check_mii_busy; // wait for read to finish
3186
    // read data from PHY status register - remember LINK-UP status
3187
    #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3188
 
3189
    for (i2 = 0; i2 <= 1; i2 = i2 + 1) // choose preamble or not
3190 169 mohor
    begin
3191 181 mohor
      #Tp eth_phy.preamble_suppresed(i2);
3192
      // MII mode register
3193
      #Tp wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i2, 8'h0}), 4'hF, 1, wbm_init_waits,
3194
                    wbm_subseq_waits);
3195
      if (i2)
3196 169 mohor
      begin
3197 181 mohor
        // change saved data when preamble is suppressed
3198
        #Tp tmp_data = tmp_data | 16'h0040; // put bit 6 to ONE
3199
      end
3200
 
3201
      i = 0;
3202
      while (i < 80) // delay for sliding of LinkFail bit
3203
      begin
3204
        // first there are two scans
3205
        #Tp cnt = 0;
3206 169 mohor
        // scan request
3207
        #Tp mii_scan_req(phy_addr, reg_addr);
3208 181 mohor
        #Tp check_mii_scan_valid; // wait for scan to make first data valid
3209
 
3210
        // check second scan
3211 169 mohor
        fork
3212 181 mohor
        begin
3213
          repeat(4) @(posedge Mdc_O);
3214
          // read data from PHY status register
3215
          #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3216
          if (phy_data !== tmp_data)
3217 169 mohor
          begin
3218 181 mohor
            test_fail("Second data was not correctly scaned from status register");
3219
            fail = fail + 1;
3220 169 mohor
          end
3221 181 mohor
          // read data from MII status register
3222
          #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3223
          if (phy_data[0] !== 1'b0)
3224
          begin
3225
            test_fail("Link FAIL bit was set in the MII status register");
3226
            fail = fail + 1;
3227
          end
3228
        end
3229
        begin
3230
        // Completely check scan
3231
          #Tp cnt = 0;
3232
          // wait for serial bus to become active - second scan
3233
          wait(Mdio_IO !== 1'bz);
3234
          // count transfer length
3235
          while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3236
          begin
3237
            @(posedge Mdc_O);
3238
            #Tp cnt = cnt + 1;
3239
          end
3240
          // check transfer length
3241
          if (i2) // without preamble
3242
          begin
3243
            if (cnt != 33) // at this value Mdio_IO is HIGH Z
3244 169 mohor
            begin
3245 181 mohor
              test_fail("Second scan request did not proceed correctly");
3246
              fail = fail + 1;
3247 169 mohor
            end
3248 181 mohor
          end
3249
          else // with preamble
3250
          begin
3251
            if (cnt != 65) // at this value Mdio_IO is HIGH Z
3252
            begin
3253
              test_fail("Second scan request did not proceed correctly");
3254
              fail = fail + 1;
3255
            end
3256
          end
3257
        end
3258
        join
3259
        // reset counter 
3260
        #Tp cnt = 0;
3261
        // SLIDING LINK DOWN and CHECK
3262
        fork
3263
          begin
3264
          // set link down
3265
            repeat(i) @(posedge Mdc_O);
3266
            // set link down
3267
            #Tp eth_phy.link_up_down(0);
3268
          end
3269
          begin
3270
          // check data in MII registers after each scan in this fork statement
3271 169 mohor
            if (i2) // without preamble
3272 181 mohor
              wait (cnt == 32);
3273
            else // with preamble
3274
              wait (cnt == 64);
3275
            repeat(3) @(posedge Mdc_O);
3276
            // read data from PHY status register
3277
            #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3278
            if ( ((i < 49) && !i2) || ((i < 17) && i2) )
3279 169 mohor
            begin
3280 181 mohor
              if (phy_data !== (tmp_data & 16'hFFFB)) // bit 3 is ZERO
3281 169 mohor
              begin
3282 181 mohor
                test_fail("Third data was not correctly scaned from status register");
3283 169 mohor
                fail = fail + 1;
3284
              end
3285
            end
3286 181 mohor
            else
3287 169 mohor
            begin
3288 181 mohor
              if (phy_data !== tmp_data)
3289 169 mohor
              begin
3290 181 mohor
                test_fail("Third data was not correctly scaned from status register");
3291 169 mohor
                fail = fail + 1;
3292
              end
3293
            end
3294 181 mohor
            // read data from MII status register
3295
            #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3296
            if ( ((i < 49) && !i2) || ((i < 17) && i2) )
3297 169 mohor
            begin
3298 181 mohor
              if (phy_data[0] === 1'b0)
3299
              begin
3300
                test_fail("Link FAIL bit was not set in the MII status register");
3301
                fail = fail + 1;
3302
              end
3303 169 mohor
            end
3304 181 mohor
            else
3305 169 mohor
            begin
3306 181 mohor
              if (phy_data[0] !== 1'b0)
3307 169 mohor
              begin
3308 181 mohor
                test_fail("Link FAIL bit was set in the MII status register");
3309 169 mohor
                fail = fail + 1;
3310
              end
3311
            end
3312 181 mohor
          end
3313
          begin
3314
          // check length
3315
            for (i3 = 0; i3 <= 1; i3 = i3 + 1) // two scans
3316 169 mohor
            begin
3317 181 mohor
              #Tp cnt = 0;
3318
              // wait for serial bus to become active if there is more than one scan
3319
              wait(Mdio_IO !== 1'bz);
3320
              // count transfer length
3321
              while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3322 169 mohor
              begin
3323 181 mohor
                @(posedge Mdc_O);
3324
                #Tp cnt = cnt + 1;
3325 169 mohor
              end
3326 181 mohor
              // check transfer length
3327
              if (i2) // without preamble
3328
              begin
3329
                if (cnt != 33) // at this value Mdio_IO is HIGH Z
3330
                begin
3331
                  test_fail("3. or 4. scan request did not proceed correctly, while SCAN STOP was written");
3332
                  fail = fail + 1;
3333
                end
3334
              end
3335
              else // with preamble
3336
              begin
3337
                if (cnt != 65) // at this value Mdio_IO is HIGH Z
3338
                begin
3339
                  test_fail("3. or 4. scan request did not proceed correctly, while SCAN STOP was written");
3340
                  fail = fail + 1;
3341
                end
3342
              end
3343 169 mohor
            end
3344
          end
3345
        join
3346 181 mohor
        // reset counter
3347
        #Tp cnt = 0;
3348
        // check fifth scan and data from fourth scan
3349
        fork
3350 169 mohor
        begin
3351 181 mohor
          repeat(2) @(posedge Mdc_O);
3352
          // read data from PHY status register
3353
          #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3354
          if (phy_data !== (tmp_data & 16'hFFFB)) // bit 3 is ZERO
3355 169 mohor
          begin
3356 181 mohor
            test_fail("4. data was not correctly scaned from status register");
3357
            fail = fail + 1;
3358 169 mohor
          end
3359 181 mohor
          // read data from MII status register
3360
          #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3361
          if (phy_data[0] === 1'b0)
3362 169 mohor
          begin
3363 181 mohor
            test_fail("Link FAIL bit was not set in the MII status register");
3364 169 mohor
            fail = fail + 1;
3365
          end
3366
        end
3367
        begin
3368 181 mohor
        // Completely check intermediate scan
3369
          #Tp cnt = 0;
3370
          // wait for serial bus to become active - second scan
3371 169 mohor
          wait(Mdio_IO !== 1'bz);
3372
          // count transfer length
3373
          while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3374
          begin
3375
            @(posedge Mdc_O);
3376
            #Tp cnt = cnt + 1;
3377
          end
3378 181 mohor
          // check transfer length
3379
          if (i2) // without preamble
3380 169 mohor
          begin
3381 181 mohor
            if (cnt != 33) // at this value Mdio_IO is HIGH Z
3382
            begin
3383
              test_fail("Fifth scan request did not proceed correctly");
3384
              fail = fail + 1;
3385
            end
3386 169 mohor
          end
3387 181 mohor
          else // with preamble
3388
          begin
3389
            if (cnt != 65) // at this value Mdio_IO is HIGH Z
3390
            begin
3391
              test_fail("Fifth scan request did not proceed correctly");
3392
              fail = fail + 1;
3393
            end
3394
          end
3395 169 mohor
        end
3396 181 mohor
        join
3397
        // reset counter 
3398
        #Tp cnt = 0;
3399
        // SLIDING LINK UP and CHECK
3400
        fork
3401 169 mohor
          begin
3402 181 mohor
          // set link up
3403
            repeat(i) @(posedge Mdc_O);
3404
            // set link up
3405
            #Tp eth_phy.link_up_down(1);
3406 169 mohor
          end
3407 181 mohor
          begin
3408
          // check data in MII registers after each scan in this fork statement
3409
            repeat(2) @(posedge Mdc_O);
3410
            if (i2) // without preamble
3411
              wait (cnt == 32);
3412
            else // with preamble
3413
              wait (cnt == 64);
3414
            repeat(3) @(posedge Mdc_O);
3415
            // read data from PHY status register
3416
            #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3417
            if ( ((i < 49) && !i2) || ((i < 17) && i2) )
3418
            begin
3419
              if (phy_data !== tmp_data)
3420
              begin
3421
                test_fail("6. data was not correctly scaned from status register");
3422
                fail = fail + 1;
3423
              end
3424
            end
3425
            else
3426
            begin
3427
              if (phy_data !== (tmp_data & 16'hFFFB)) // bit 3 is ZERO
3428
              begin
3429
                test_fail("6. data was not correctly scaned from status register");
3430
                fail = fail + 1;
3431
              end
3432
            end
3433
            // read data from MII status register
3434
            #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3435
            if ( ((i < 49) && !i2) || ((i < 17) && i2) )
3436
            begin
3437
              if (phy_data[0] !== 1'b0)
3438
              begin
3439
                test_fail("Link FAIL bit was set in the MII status register");
3440
                fail = fail + 1;
3441
              end
3442
            end
3443
            else
3444
            begin
3445
              if (phy_data[0] === 1'b0)
3446
              begin
3447
                test_fail("Link FAIL bit was not set in the MII status register");
3448
                fail = fail + 1;
3449
              end
3450
            end
3451
          end
3452
          begin
3453
          // check length
3454
            for (i3 = 0; i3 <= 1; i3 = i3 + 1) // two scans
3455
            begin
3456
              #Tp cnt = 0;
3457
              // wait for serial bus to become active if there is more than one scan
3458
              wait(Mdio_IO !== 1'bz);
3459
              // count transfer length
3460
              while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3461
              begin
3462
                @(posedge Mdc_O);
3463
                #Tp cnt = cnt + 1;
3464
              end
3465
              // check transfer length
3466
              if (i2) // without preamble
3467
              begin
3468
                if (cnt != 33) // at this value Mdio_IO is HIGH Z
3469
                begin
3470
                  test_fail("Scan request did not proceed correctly, while SCAN STOP was written");
3471
                  fail = fail + 1;
3472
                end
3473
              end
3474
              else // with preamble
3475
              begin
3476
                if (cnt != 65) // at this value Mdio_IO is HIGH Z
3477
                begin
3478
                  test_fail("Scan request did not proceed correctly, while SCAN STOP was written");
3479
                  fail = fail + 1;
3480
                end
3481
              end
3482
            end
3483
          end
3484
        join
3485
        // check last scan 
3486
        repeat(4) @(posedge Mdc_O);
3487
        // read data from PHY status register
3488
        #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3489
        if (phy_data !== tmp_data)
3490
        begin
3491
          test_fail("7. data was not correctly scaned from status register");
3492
          fail = fail + 1;
3493 169 mohor
        end
3494 181 mohor
        // read data from MII status register
3495
        #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3496
        if (phy_data[0] !== 1'b0)
3497
        begin
3498
          test_fail("Link FAIL bit was set in the MII status register");
3499
          fail = fail + 1;
3500
        end
3501
 
3502
        #Tp mii_scan_finish; // finish scan operation
3503
        #Tp check_mii_busy; // wait for scan to finish
3504
        #Tp;
3505
        // set delay of writing the command
3506
        if (i2) // without preamble
3507
        begin
3508
          case(i)
3509
            0,  1,  2,  3,  4:  i = i + 1;
3510
            13, 14, 15, 16, 17,
3511
            18, 19, 20, 21, 22,
3512
            23, 24, 25, 26, 27,
3513
            28, 29, 30, 31, 32,
3514
            33, 34, 35:         i = i + 1;
3515
            36:                 i = 80;
3516
            default:            i = 13;
3517
          endcase
3518
        end
3519 169 mohor
        else // with preamble
3520
        begin
3521 181 mohor
          case(i)
3522
            0,  1,  2,  3,  4:  i = i + 1;
3523
            45, 46, 47, 48, 49,
3524
            50, 51, 52, 53, 54,
3525
            55, 56, 57, 58, 59,
3526
            60, 61, 62, 63, 64,
3527
            65, 66, 67:         i = i + 1;
3528
            68:                 i = 80;
3529
            default:            i = 45;
3530
          endcase
3531 169 mohor
        end
3532 181 mohor
        @(posedge wb_clk);
3533
        #Tp;
3534 169 mohor
      end
3535
    end
3536 181 mohor
    // set PHY to normal mode
3537
    #Tp eth_phy.preamble_suppresed(0);
3538
    // MII mode register
3539
    wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3540
    if(fail == 0)
3541
      test_ok;
3542
    else
3543
      fail = 0;
3544 169 mohor
  end
3545
 
3546
 
3547 181 mohor
  ////////////////////////////////////////////////////////////////////
3548
  ////                                                            ////
3549
  ////  Test sliding stop scan command immediately after scan     ////
3550
  ////  request (with and without preamble)                       ////
3551
  ////                                                            ////
3552
  ////////////////////////////////////////////////////////////////////
3553
  if (test_num == 16) // 
3554 116 mohor
  begin
3555 194 tadej
    // TEST 16: SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER SCAN REQUEST ( WITH AND WITHOUT PREAMBLE )
3556
    test_name = "TEST 16: SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER SCAN REQUEST ( WITH AND WITHOUT PREAMBLE )";
3557 181 mohor
    `TIME;
3558 194 tadej
    $display("  TEST 16: SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER SCAN REQUEST ( WITH AND WITHOUT PREAMBLE )");
3559 181 mohor
 
3560
    for (i2 = 0; i2 <= 1; i2 = i2 + 1) // choose preamble or not
3561 169 mohor
    begin
3562 181 mohor
      #Tp eth_phy.preamble_suppresed(i2);
3563
      // MII mode register
3564
      wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i2, 8'h0}), 4'hF, 1, wbm_init_waits,
3565
                wbm_subseq_waits);
3566
      i = 0;
3567
      cnt = 0;
3568
      while (i < 80) // delay for sliding of writing a STOP SCAN command
3569 169 mohor
      begin
3570 181 mohor
        for (i3 = 0; i3 <= 1; i3 = i3 + 1) // choose read or write after scan will be finished
3571 169 mohor
        begin
3572 181 mohor
          // set address
3573
          reg_addr = 5'h0; // control register
3574
          phy_addr = 5'h1; // correct PHY address
3575
          cnt = 0;
3576
          // scan request
3577
          #Tp mii_scan_req(phy_addr, reg_addr);
3578
          fork
3579
            begin
3580
              repeat(i) @(posedge Mdc_O);
3581
              // write command 0x0 into MII command register
3582
              // MII command written while scan in progress
3583
              wbm_write(`ETH_MIICOMMAND, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3584
              @(posedge wb_clk);
3585
              #Tp check_mii_busy; // wait for scan to finish
3586
              @(posedge wb_clk);
3587
              disable check;
3588
            end
3589
            begin: check
3590
              // wait for serial bus to become active
3591
              wait(Mdio_IO !== 1'bz);
3592
              // count transfer length
3593
              while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3594
              begin
3595
                @(posedge Mdc_O);
3596
                #Tp cnt = cnt + 1;
3597
              end
3598
              // check transfer length
3599
              if (i2) // without preamble
3600
              begin
3601
                if (cnt != 33) // at this value Mdio_IO is HIGH Z
3602
                begin
3603
                  test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3604
                  fail = fail + 1;
3605
                end
3606
              end
3607
              else // with preamble
3608
              begin
3609
                if (cnt != 65) // at this value Mdio_IO is HIGH Z
3610
                begin
3611
                  test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3612
                  fail = fail + 1;
3613
                end
3614
              end
3615
              cnt = 0;
3616
              // wait for serial bus to become active if there is more than one scan
3617
              wait(Mdio_IO !== 1'bz);
3618
              // count transfer length
3619
              while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3620
              begin
3621
                @(posedge Mdc_O);
3622
                #Tp cnt = cnt + 1;
3623
              end
3624
              // check transfer length
3625
              if (i2) // without preamble
3626
              begin
3627
                if (cnt != 33) // at this value Mdio_IO is HIGH Z
3628
                begin
3629
                  test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3630
                  fail = fail + 1;
3631
                end
3632
              end
3633
              else // with preamble
3634
              begin
3635
                if (cnt != 65) // at this value Mdio_IO is HIGH Z
3636
                begin
3637
                  test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3638
                  fail = fail + 1;
3639
                end
3640
              end
3641
            end
3642
          join
3643
          // check the BUSY signal to see if the bus is still IDLE
3644
          for (i1 = 0; i1 < 8; i1 = i1 + 1)
3645
            check_mii_busy; // wait for bus to become idle
3646
 
3647
          // try normal write or read after scan was finished
3648
          phy_data = {8'h7D, (i[7:0] + 1)};
3649
          cnt = 0;
3650
          if (i3 == 0) // write after scan
3651 169 mohor
          begin
3652 181 mohor
            // write request
3653
            #Tp mii_write_req(phy_addr, reg_addr, phy_data);
3654
            // wait for serial bus to become active
3655
            wait(Mdio_IO !== 1'bz);
3656
            // count transfer length
3657
            while(Mdio_IO !== 1'bz)
3658
            begin
3659
              @(posedge Mdc_O);
3660
              #Tp cnt = cnt + 1;
3661
            end
3662 169 mohor
            @(posedge Mdc_O);
3663 181 mohor
            // read request
3664
            #Tp mii_read_req(phy_addr, reg_addr);
3665
            check_mii_busy; // wait for read to finish
3666
            // read and check data
3667
            #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3668
            if (phy_data !== tmp_data)
3669 169 mohor
            begin
3670 181 mohor
              test_fail("Data was not correctly written into OR read from PHY register - control register");
3671 169 mohor
              fail = fail + 1;
3672
            end
3673
          end
3674 181 mohor
          else // read after scan
3675 169 mohor
          begin
3676 181 mohor
            // read request
3677
            #Tp mii_read_req(phy_addr, reg_addr);
3678
            // wait for serial bus to become active
3679
            wait(Mdio_IO !== 1'bz);
3680
            // count transfer length
3681
            while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3682 169 mohor
            begin
3683 181 mohor
              @(posedge Mdc_O);
3684
              #Tp cnt = cnt + 1;
3685
            end
3686
            @(posedge Mdc_O);
3687
            check_mii_busy; // wait for read to finish
3688
            // read and check data
3689
            #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3690
            if (phy_data !== tmp_data)
3691
            begin
3692
              test_fail("Data was not correctly written into OR read from PHY register - control register");
3693 169 mohor
              fail = fail + 1;
3694
            end
3695
          end
3696 181 mohor
          // check if transfer was a proper length
3697 169 mohor
          if (i2) // without preamble
3698
          begin
3699
            if (cnt != 33) // at this value Mdio_IO is HIGH Z
3700
            begin
3701 181 mohor
              test_fail("New request did not proceed correctly, after scan request");
3702 169 mohor
              fail = fail + 1;
3703
            end
3704
          end
3705
          else // with preamble
3706
          begin
3707
            if (cnt != 65) // at this value Mdio_IO is HIGH Z
3708
            begin
3709 181 mohor
              test_fail("New request did not proceed correctly, after scan request");
3710 169 mohor
              fail = fail + 1;
3711
            end
3712
          end
3713
        end
3714 181 mohor
        #Tp;
3715
        // set delay of writing the command
3716
        if (i2) // without preamble
3717
        begin
3718
          case(i)
3719
            0, 1:               i = i + 1;
3720
            18, 19, 20, 21, 22,
3721
            23, 24, 25, 26, 27,
3722
            28, 29, 30, 31, 32,
3723
            33, 34, 35:         i = i + 1;
3724
            36:                 i = 80;
3725
            default:            i = 18;
3726
          endcase
3727
        end
3728
        else // with preamble
3729
        begin
3730
          case(i)
3731
            0, 1:               i = i + 1;
3732
            50, 51, 52, 53, 54,
3733
            55, 56, 57, 58, 59,
3734
            60, 61, 62, 63, 64,
3735
            65, 66, 67:         i = i + 1;
3736
            68:                 i = 80;
3737
            default:            i = 50;
3738
          endcase
3739
        end
3740
        @(posedge wb_clk);
3741
      end
3742
    end
3743
    // set PHY to normal mode
3744
    #Tp eth_phy.preamble_suppresed(0);
3745
    // MII mode register
3746
    wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3747
    if(fail == 0)
3748
      test_ok;
3749
    else
3750
      fail = 0;
3751
  end
3752 169 mohor
 
3753 181 mohor
 
3754
  ////////////////////////////////////////////////////////////////////
3755
  ////                                                            ////
3756
  ////  Test sliding stop scan command after 2. scan (with and    ////
3757
  ////  without preamble)                                         ////
3758
  ////                                                            ////
3759
  ////////////////////////////////////////////////////////////////////
3760
  if (test_num == 17) // 
3761
  begin
3762 194 tadej
    // TEST 17: SLIDING STOP SCAN COMMAND AFTER 2. SCAN ( WITH AND WITHOUT PREAMBLE )
3763
    test_name = "TEST 17: SLIDING STOP SCAN COMMAND AFTER 2. SCAN ( WITH AND WITHOUT PREAMBLE )";
3764
    `TIME; $display("  TEST 17: SLIDING STOP SCAN COMMAND AFTER 2. SCAN ( WITH AND WITHOUT PREAMBLE )");
3765 181 mohor
 
3766
    for (i2 = 0; i2 <= 1; i2 = i2 + 1) // choose preamble or not
3767
    begin
3768
      #Tp eth_phy.preamble_suppresed(i2);
3769
      // MII mode register
3770
      wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i2, 8'h0}), 4'hF, 1, wbm_init_waits,
3771
                wbm_subseq_waits);
3772
 
3773
      i = 0;
3774
      cnt = 0;
3775
      while (i < 80) // delay for sliding of writing a STOP SCAN command
3776
      begin
3777
        for (i3 = 0; i3 <= 1; i3 = i3 + 1) // choose read or write after scan will be finished
3778
        begin
3779
          // first there are two scans
3780
          // set address
3781
          reg_addr = 5'h0; // control register
3782
          phy_addr = 5'h1; // correct PHY address
3783
          cnt = 0;
3784
          // scan request
3785
          #Tp mii_scan_req(phy_addr, reg_addr);
3786
          // wait and check first 2 scans
3787 169 mohor
          begin
3788
            // wait for serial bus to become active
3789
            wait(Mdio_IO !== 1'bz);
3790
            // count transfer length
3791
            while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3792
            begin
3793
              @(posedge Mdc_O);
3794
              #Tp cnt = cnt + 1;
3795
            end
3796
            // check transfer length
3797
            if (i2) // without preamble
3798
            begin
3799
              if (cnt != 33) // at this value Mdio_IO is HIGH Z
3800
              begin
3801
                test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3802
                fail = fail + 1;
3803
              end
3804
            end
3805
            else // with preamble
3806
            begin
3807
              if (cnt != 65) // at this value Mdio_IO is HIGH Z
3808
              begin
3809
                test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3810
                fail = fail + 1;
3811
              end
3812
            end
3813
            cnt = 0;
3814
            // wait for serial bus to become active if there is more than one scan
3815
            wait(Mdio_IO !== 1'bz);
3816
            // count transfer length
3817
            while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3818
            begin
3819
              @(posedge Mdc_O);
3820
              #Tp cnt = cnt + 1;
3821
            end
3822
            // check transfer length
3823
            if (i2) // without preamble
3824
            begin
3825
              if (cnt != 33) // at this value Mdio_IO is HIGH Z
3826
              begin
3827
                test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3828
                fail = fail + 1;
3829
              end
3830
            end
3831
            else // with preamble
3832
            begin
3833
              if (cnt != 65) // at this value Mdio_IO is HIGH Z
3834
              begin
3835
                test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3836
                fail = fail + 1;
3837
              end
3838
            end
3839
          end
3840
 
3841 181 mohor
          // reset counter 
3842
          cnt = 0;
3843
          fork
3844
            begin
3845
              repeat(i) @(posedge Mdc_O);
3846
              // write command 0x0 into MII command register
3847
              // MII command written while scan in progress
3848
              wbm_write(`ETH_MIICOMMAND, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3849
              @(posedge wb_clk);
3850
              #Tp check_mii_busy; // wait for scan to finish
3851
              @(posedge wb_clk);
3852
              disable check_3;
3853
            end
3854
            begin: check_3
3855
              // wait for serial bus to become active
3856
              wait(Mdio_IO !== 1'bz);
3857
              // count transfer length
3858
              while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3859
              begin
3860
                @(posedge Mdc_O);
3861
                #Tp cnt = cnt + 1;
3862
              end
3863
              // check transfer length
3864
              if (i2) // without preamble
3865
              begin
3866
                if (cnt != 33) // at this value Mdio_IO is HIGH Z
3867
                begin
3868
                  test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3869
                  fail = fail + 1;
3870
                end
3871
              end
3872
              else // with preamble
3873
              begin
3874
                if (cnt != 65) // at this value Mdio_IO is HIGH Z
3875
                begin
3876
                  test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3877
                  fail = fail + 1;
3878
                end
3879
              end
3880
              cnt = 0;
3881
              // wait for serial bus to become active if there is more than one scan
3882
              wait(Mdio_IO !== 1'bz);
3883
              // count transfer length
3884
              while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3885
              begin
3886
                @(posedge Mdc_O);
3887
                #Tp cnt = cnt + 1;
3888
              end
3889
              // check transfer length
3890
              if (i2) // without preamble
3891
              begin
3892
                if (cnt != 33) // at this value Mdio_IO is HIGH Z
3893
                begin
3894
                  test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3895
                  fail = fail + 1;
3896
                end
3897
              end
3898
              else // with preamble
3899
              begin
3900
                if (cnt != 65) // at this value Mdio_IO is HIGH Z
3901
                begin
3902
                  test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3903
                  fail = fail + 1;
3904
                end
3905
              end
3906
            end
3907
          join
3908
          // check the BUSY signal to see if the bus is still IDLE
3909
          for (i1 = 0; i1 < 8; i1 = i1 + 1)
3910
            check_mii_busy; // wait for bus to become idle
3911
 
3912
          // try normal write or read after scan was finished
3913
          phy_data = {8'h7D, (i[7:0] + 1)};
3914
          cnt = 0;
3915
          if (i3 == 0) // write after scan
3916 169 mohor
          begin
3917 181 mohor
            // write request
3918
            #Tp mii_write_req(phy_addr, reg_addr, phy_data);
3919
            // wait for serial bus to become active
3920
            wait(Mdio_IO !== 1'bz);
3921
            // count transfer length
3922
            while(Mdio_IO !== 1'bz)
3923
            begin
3924
              @(posedge Mdc_O);
3925
              #Tp cnt = cnt + 1;
3926
            end
3927 169 mohor
            @(posedge Mdc_O);
3928 181 mohor
            // read request
3929
            #Tp mii_read_req(phy_addr, reg_addr);
3930
            check_mii_busy; // wait for read to finish
3931
            // read and check data
3932
            #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3933
            if (phy_data !== tmp_data)
3934
            begin
3935
              test_fail("Data was not correctly written into OR read from PHY register - control register");
3936
              fail = fail + 1;
3937
            end
3938 169 mohor
          end
3939 181 mohor
          else // read after scan
3940 169 mohor
          begin
3941 181 mohor
            // read request
3942
            #Tp mii_read_req(phy_addr, reg_addr);
3943
            // wait for serial bus to become active
3944
            wait(Mdio_IO !== 1'bz);
3945
            // count transfer length
3946
            while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3947
            begin
3948
              @(posedge Mdc_O);
3949
              #Tp cnt = cnt + 1;
3950
            end
3951
            @(posedge Mdc_O);
3952
            check_mii_busy; // wait for read to finish
3953
            // read and check data
3954
            #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3955
            if (phy_data !== tmp_data)
3956
            begin
3957
              test_fail("Data was not correctly written into OR read from PHY register - control register");
3958
              fail = fail + 1;
3959
            end
3960 169 mohor
          end
3961 181 mohor
          // check if transfer was a proper length
3962
          if (i2) // without preamble
3963 169 mohor
          begin
3964 181 mohor
            if (cnt != 33) // at this value Mdio_IO is HIGH Z
3965
            begin
3966
              test_fail("New request did not proceed correctly, after scan request");
3967
              fail = fail + 1;
3968
            end
3969 169 mohor
          end
3970 181 mohor
          else // with preamble
3971 169 mohor
          begin
3972 181 mohor
            if (cnt != 65) // at this value Mdio_IO is HIGH Z
3973
            begin
3974
              test_fail("New request did not proceed correctly, after scan request");
3975
              fail = fail + 1;
3976
            end
3977 169 mohor
          end
3978
        end
3979 181 mohor
        #Tp;
3980
        // set delay of writing the command
3981 169 mohor
        if (i2) // without preamble
3982
        begin
3983 181 mohor
          case(i)
3984
            0, 1:               i = i + 1;
3985
            18, 19, 20, 21, 22,
3986
            23, 24, 25, 26, 27,
3987
            28, 29, 30, 31, 32,
3988
            33, 34, 35:         i = i + 1;
3989
            36:                 i = 80;
3990
            default:            i = 18;
3991
          endcase
3992 169 mohor
        end
3993
        else // with preamble
3994
        begin
3995 181 mohor
          case(i)
3996
            0, 1:               i = i + 1;
3997
            50, 51, 52, 53, 54,
3998
            55, 56, 57, 58, 59,
3999
            60, 61, 62, 63, 64,
4000
            65, 66, 67:         i = i + 1;
4001
            68:                 i = 80;
4002
            default:            i = 50;
4003
          endcase
4004 169 mohor
        end
4005 181 mohor
        @(posedge wb_clk);
4006 116 mohor
      end
4007
    end
4008 181 mohor
    // set PHY to normal mode
4009
    #Tp eth_phy.preamble_suppresed(0);
4010
    // MII mode register
4011
    wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4012
    if(fail == 0)
4013
      test_ok;
4014
    else
4015
      fail = 0;
4016 169 mohor
  end
4017 116 mohor
 
4018 181 mohor
end   //  for (test_num=start_task; test_num <= end_task; test_num=test_num+1)
4019
 
4020 169 mohor
end
4021
endtask // test_mii
4022
 
4023
 
4024
task test_mac_full_duplex_transmit;
4025
  input  [31:0]  start_task;
4026
  input  [31:0]  end_task;
4027
  integer        bit_start_1;
4028
  integer        bit_end_1;
4029
  integer        bit_start_2;
4030
  integer        bit_end_2;
4031
  integer        num_of_reg;
4032 209 tadejm
  integer        num_of_frames;
4033
  integer        num_of_bd;
4034 169 mohor
  integer        i_addr;
4035
  integer        i_data;
4036
  integer        i_length;
4037 209 tadejm
  integer        tmp_len;
4038
  integer        tmp_bd;
4039
  integer        tmp_bd_num;
4040 169 mohor
  integer        tmp_data;
4041 209 tadejm
  integer        tmp_ipgt;
4042 194 tadej
  integer        test_num;
4043 169 mohor
  reg    [31:0]  tx_bd_num;
4044
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_data;
4045
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_tmp_data;
4046
  integer        i;
4047
  integer        i1;
4048
  integer        i2;
4049
  integer        i3;
4050
  integer        fail;
4051
  integer        speed;
4052 209 tadejm
  reg            frame_started;
4053
  reg            frame_ended;
4054
  reg            wait_for_frame;
4055 169 mohor
  reg    [31:0]  addr;
4056
  reg    [31:0]  data;
4057
  reg    [31:0]  tmp;
4058
  reg    [ 7:0]  st_data;
4059
  reg    [15:0]  max_tmp;
4060
  reg    [15:0]  min_tmp;
4061
begin
4062
// MAC FULL DUPLEX TRANSMIT TEST
4063
test_heading("MAC FULL DUPLEX TRANSMIT TEST");
4064
$display(" ");
4065
$display("MAC FULL DUPLEX TRANSMIT TEST");
4066
fail = 0;
4067
 
4068
// reset MAC registers
4069
hard_reset;
4070
// reset MAC and MII LOGIC with soft reset
4071
reset_mac;
4072
reset_mii;
4073
// set wb slave response
4074
wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
4075
 
4076
  /*
4077
  TASKS for set and control TX buffer descriptors (also send packet - set_tx_bd_ready):
4078
  -------------------------------------------------------------------------------------
4079
  set_tx_bd
4080
    (tx_bd_num_start[6:0], tx_bd_num_end[6:0], len[15:0], irq, pad, crc, txpnt[31:0]);
4081
  set_tx_bd_wrap
4082
    (tx_bd_num_end[6:0]);
4083
  set_tx_bd_ready
4084
    (tx_bd_num_start[6:0], tx_bd_num_end[6:0]);
4085
  check_tx_bd
4086
    (tx_bd_num_start[6:0], tx_bd_status[31:0]);
4087
  clear_tx_bd
4088
    (tx_bd_num_start[6:0], tx_bd_num_end[6:0]);
4089
 
4090
  TASKS for set and control RX buffer descriptors:
4091
  ------------------------------------------------
4092
  set_rx_bd
4093
    (rx_bd_num_strat[6:0], rx_bd_num_end[6:0], irq, rxpnt[31:0]);
4094
  set_rx_bd_wrap
4095
    (rx_bd_num_end[6:0]);
4096
  set_rx_bd_empty
4097
    (rx_bd_num_strat[6:0], rx_bd_num_end[6:0]);
4098
  check_rx_bd
4099
    (rx_bd_num_end[6:0], rx_bd_status);
4100
  clear_rx_bd
4101
    (rx_bd_num_strat[6:0], rx_bd_num_end[6:0]);
4102
 
4103
  TASKS for set and check TX packets:
4104
  -----------------------------------
4105
  set_tx_packet
4106
    (txpnt[31:0], len[15:0], eth_start_data[7:0]);
4107
  check_tx_packet
4108
    (txpnt_wb[31:0], txpnt_phy[31:0], len[15:0], failure[31:0]);
4109
 
4110
  TASKS for set and check RX packets:
4111
  -----------------------------------
4112
  set_rx_packet
4113
    (rxpnt[31:0], len[15:0], plus_nibble, d_addr[47:0], s_addr[47:0], type_len[15:0], start_data[7:0]);
4114
  check_rx_packet
4115
    (rxpnt_phy[31:0], rxpnt_wb[31:0], len[15:0], plus_nibble, successful_nibble, failure[31:0]);
4116
 
4117
  TASKS for append and check CRC to/of TX packet:
4118
  -----------------------------------------------
4119
  append_tx_crc
4120
    (txpnt_wb[31:0], len[15:0], negated_crc);
4121
  check_tx_crc
4122
    (txpnt_phy[31:0], len[15:0], negated_crc, failure[31:0]);
4123
 
4124
  TASK for append CRC to RX packet (CRC is checked together with check_rx_packet):
4125
  --------------------------------------------------------------------------------
4126
  append_rx_crc
4127
    (rxpnt_phy[31:0], len[15:0], plus_nibble, negated_crc);
4128
  */
4129
 
4130 194 tadej
//////////////////////////////////////////////////////////////////////
4131
////                                                              ////
4132
////  test_mac_full_duplex_transmit:                              ////
4133
////                                                              ////
4134
////  0: Test no transmit when all buffers are RX ( 10Mbps ).     ////
4135
////  1: Test no transmit when all buffers are RX ( 100Mbps ).    ////
4136
////  2: Test transmit packets form MINFL to MAXFL sizes at       ////
4137
////     one TX buffer decriptor ( 10Mbps ).                      ////
4138
////  3: Test transmit packets form MINFL to MAXFL sizes at       ////
4139
////     one TX buffer decriptor ( 100Mbps ).                     ////
4140
////                                                              ////
4141
//////////////////////////////////////////////////////////////////////
4142
for (test_num = start_task; test_num <= end_task; test_num = test_num + 1)
4143 169 mohor
begin
4144
 
4145 194 tadej
  ////////////////////////////////////////////////////////////////////
4146
  ////                                                            ////
4147
  ////  Test no transmit when all buffers are RX ( 10Mbps ).      ////
4148
  ////                                                            ////
4149
  ////////////////////////////////////////////////////////////////////
4150
  if (test_num == 0) // Test no transmit when all buffers are RX ( 10Mbps ).
4151 169 mohor
  begin
4152 194 tadej
    // TEST 0: NO TRANSMIT WHEN ALL BUFFERS ARE RX ( 10Mbps )
4153
    test_name   = "TEST 0: NO TRANSMIT WHEN ALL BUFFERS ARE RX ( 10Mbps )";
4154
    `TIME; $display("  TEST 0: NO TRANSMIT WHEN ALL BUFFERS ARE RX ( 10Mbps )");
4155
 
4156
    // unmask interrupts
4157 209 tadejm
    wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
4158 194 tadej
                             `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4159
    // set all buffer descriptors to RX - must be set before TX enable
4160
    wbm_write(`ETH_TX_BD_NUM, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4161
    // enable TX, set full-duplex mode, padding and CRC appending
4162
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
4163
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4164
 
4165
    // write to phy's control register for 10Mbps
4166
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
4167
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
4168
    speed = 10;
4169
 
4170
    i = 0;
4171
    while (i < 128)
4172 169 mohor
    begin
4173 194 tadej
      for (i1 = 0; i1 <= i; i1 = i1 + 1)
4174 169 mohor
      begin
4175 194 tadej
        set_tx_packet((`MEMORY_BASE + (i1 * 200)), 100, 0);
4176
        set_tx_bd(i1, i1, 100, 1'b1, 1'b1, 1'b1, (`MEMORY_BASE + (i1 * 200)));
4177 169 mohor
      end
4178 194 tadej
      set_tx_bd_wrap(i);
4179
      fork
4180
        begin
4181
          set_tx_bd_ready(0, i);
4182
          repeat(20) @(negedge mtx_clk);
4183
          #1 disable check_tx_en10;
4184
        end
4185
        begin: check_tx_en10
4186
          wait (MTxEn === 1'b1);
4187
          test_fail("Tramsmit should not start at all");
4188
          fail = fail + 1;
4189
          `TIME; $display("*E Transmit of %d packets should not start at all - active MTxEn", i);
4190
        end
4191
      join
4192
      for (i2 = 0; i2 < 20; i2 = i2 + 1)
4193 169 mohor
      begin
4194 194 tadej
        check_tx_bd(0, tmp);
4195
        #1;
4196
        if (tmp[15] === 1'b0)
4197
        begin
4198
          test_fail("Tramsmit should not start at all");
4199
          fail = fail + 1;
4200
          `TIME; $display("*E Transmit of %d packets should not start at all - ready is 0", i);
4201
        end
4202
        if (tmp[8:0] !== 0)
4203
        begin
4204
          test_fail("Tramsmit should not be finished since it should not start at all");
4205
          fail = fail + 1;
4206
          `TIME; $display("*E Transmit of should not be finished since it should not start at all");
4207
        end
4208
        @(posedge wb_clk);
4209 169 mohor
      end
4210 194 tadej
      wbm_read(`ETH_INT, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4211
      if (tmp[6:0] !== 0)
4212 169 mohor
      begin
4213 194 tadej
        test_fail("Tramsmit should not get INT since it should not start at all");
4214 169 mohor
        fail = fail + 1;
4215 194 tadej
        `TIME; $display("*E Transmit of should not get INT since it should not start at all");
4216 169 mohor
      end
4217 194 tadej
      clear_tx_bd(0, i);
4218
      if ((i < 5) || (i > 124))
4219
        i = i + 1;
4220
      else
4221
        i = i + 120;
4222 116 mohor
    end
4223 194 tadej
    // disable TX
4224
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
4225
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4226
    if(fail == 0)
4227
      test_ok;
4228 116 mohor
    else
4229 194 tadej
      fail = 0;
4230 169 mohor
  end
4231 116 mohor
 
4232
 
4233 194 tadej
  ////////////////////////////////////////////////////////////////////
4234
  ////                                                            ////
4235
  ////  Test no transmit when all buffers are RX ( 100Mbps ).     ////
4236
  ////                                                            ////
4237
  ////////////////////////////////////////////////////////////////////
4238
  if (test_num == 1) // Test no transmit when all buffers are RX ( 100Mbps ).
4239 169 mohor
  begin
4240 194 tadej
    // TEST 1: NO TRANSMIT WHEN ALL BUFFERS ARE RX ( 100Mbps )
4241
    test_name   = "TEST 1: NO TRANSMIT WHEN ALL BUFFERS ARE RX ( 100Mbps )";
4242
    `TIME; $display("  TEST 1: NO TRANSMIT WHEN ALL BUFFERS ARE RX ( 100Mbps )");
4243
 
4244
    // unmask interrupts
4245 209 tadejm
    wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
4246 194 tadej
                             `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4247
    // set all buffer descriptors to RX - must be set before TX enable
4248
    wbm_write(`ETH_TX_BD_NUM, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4249
    // enable TX, set full-duplex mode, padding and CRC appending
4250
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
4251
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4252
 
4253
    // write to phy's control register for 100Mbps
4254
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
4255
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
4256
    speed = 100;
4257
 
4258
    i = 0;
4259
    while (i < 128)
4260 169 mohor
    begin
4261 194 tadej
      for (i1 = 0; i1 <= i; i1 = i1 + 1)
4262 169 mohor
      begin
4263 194 tadej
        set_tx_packet((`MEMORY_BASE + (i1 * 200)), 100, 0);
4264
        set_tx_bd(i1, i1, 100, 1'b1, 1'b1, 1'b1, (`MEMORY_BASE + (i1 * 200)));
4265 169 mohor
      end
4266 194 tadej
      set_tx_bd_wrap(i);
4267
      fork
4268
        begin
4269
          set_tx_bd_ready(0, i);
4270
          repeat(20) @(negedge mtx_clk);
4271
          #1 disable check_tx_en100;
4272
        end
4273
        begin: check_tx_en100
4274
          wait (MTxEn === 1'b1);
4275
          test_fail("Tramsmit should not start at all");
4276
          fail = fail + 1;
4277
          `TIME; $display("*E Transmit of %d packets should not start at all - active MTxEn", i);
4278
        end
4279
      join
4280
      for (i2 = 0; i2 < 20; i2 = i2 + 1)
4281 169 mohor
      begin
4282 194 tadej
        check_tx_bd(0, tmp);
4283
        #1;
4284
        if (tmp[15] === 1'b0)
4285
        begin
4286
          test_fail("Tramsmit should not start at all");
4287
          fail = fail + 1;
4288
          `TIME; $display("*E Transmit of %d packets should not start at all - ready is 0", i);
4289
        end
4290
        if (tmp[8:0] !== 0)
4291
        begin
4292
          test_fail("Tramsmit should not be finished since it should not start at all");
4293
          fail = fail + 1;
4294
          `TIME; $display("*E Transmit of should not be finished since it should not start at all");
4295
        end
4296
        @(posedge wb_clk);
4297 169 mohor
      end
4298 194 tadej
      wbm_read(`ETH_INT, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4299
      if (tmp[6:0] !== 0)
4300 169 mohor
      begin
4301 194 tadej
        test_fail("Tramsmit should not get INT since it should not start at all");
4302 169 mohor
        fail = fail + 1;
4303 194 tadej
        `TIME; $display("*E Transmit of should not get INT since it should not start at all");
4304 169 mohor
      end
4305 194 tadej
      clear_tx_bd(0, i);
4306
      if ((i < 5) || (i > 124))
4307
        i = i + 1;
4308
      else
4309
        i = i + 120;
4310 169 mohor
    end
4311 194 tadej
    // disable TX
4312
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
4313
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4314
    if(fail == 0)
4315
      test_ok;
4316 169 mohor
    else
4317 194 tadej
      fail = 0;
4318 169 mohor
  end
4319
 
4320
 
4321 194 tadej
  ////////////////////////////////////////////////////////////////////
4322
  ////                                                            ////
4323
  ////  Test transmit packets form MINFL to MAXFL sizes at        ////
4324
  ////  one TX buffer decriptor ( 10Mbps ).                       ////
4325
  ////                                                            ////
4326
  ////////////////////////////////////////////////////////////////////
4327 209 tadejm
  if (test_num == 2) // without and with padding
4328 169 mohor
  begin
4329 194 tadej
    // TEST 2: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT ONE TX BD ( 10Mbps )
4330
    test_name = "TEST 2: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT ONE TX BD ( 10Mbps )";
4331
    `TIME; $display("  TEST 2: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT ONE TX BD ( 10Mbps )");
4332
 
4333
    max_tmp = 0;
4334
    min_tmp = 0;
4335
    // set one TX buffer descriptor - must be set before TX enable
4336
    wbm_write(`ETH_TX_BD_NUM, 32'h1, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4337 209 tadejm
    // enable TX, set full-duplex mode, NO padding and CRC appending
4338
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
4339 194 tadej
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4340
    // prepare two packets of MAXFL length
4341
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4342
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
4343
    min_tmp = tmp[31:16];
4344 209 tadejm
    st_data = 8'h01;
4345
    set_tx_packet(`MEMORY_BASE, (max_tmp), st_data); // length without CRC
4346 194 tadej
    st_data = 8'h10;
4347 209 tadejm
    set_tx_packet((`MEMORY_BASE + max_tmp), (max_tmp), st_data); // length without CRC
4348 194 tadej
    // check WB INT signal
4349
    if (wb_int !== 1'b0)
4350 169 mohor
    begin
4351 194 tadej
      test_fail("WB INT signal should not be set");
4352
      fail = fail + 1;
4353 169 mohor
    end
4354 194 tadej
 
4355
    // write to phy's control register for 10Mbps
4356
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
4357
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
4358
    speed = 10;
4359
 
4360
    i_length = (min_tmp - 4);
4361
    while (i_length <= (max_tmp - 4))
4362 169 mohor
    begin
4363 194 tadej
      // choose generating carrier sense and collision for first and last 64 lengths of frames
4364
      case (i_length[1:0])
4365
      2'h0: // Interrupt is generated
4366 169 mohor
      begin
4367 194 tadej
        // enable interrupt generation
4368 209 tadejm
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, (`MEMORY_BASE + i_length[1:0]));
4369 194 tadej
        // unmask interrupts
4370 209 tadejm
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
4371 194 tadej
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4372
        // not detect carrier sense in FD and no collision
4373
        eth_phy.carrier_sense_tx_fd_detect(0);
4374
        eth_phy.collision(0);
4375 169 mohor
      end
4376 194 tadej
      2'h1: // Interrupt is not generated
4377 169 mohor
      begin
4378 194 tadej
        // enable interrupt generation
4379 209 tadejm
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
4380 194 tadej
        // mask interrupts
4381
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4382
        // detect carrier sense in FD and no collision
4383
        eth_phy.carrier_sense_tx_fd_detect(1);
4384
        eth_phy.collision(0);
4385 169 mohor
      end
4386 194 tadej
      2'h2: // Interrupt is not generated
4387
      begin
4388
        // disable interrupt generation
4389 209 tadejm
        set_tx_bd(0, 0, i_length, 1'b0, 1'b1, 1'b1, (`MEMORY_BASE + i_length[1:0]));
4390 194 tadej
        // unmask interrupts
4391 209 tadejm
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
4392 194 tadej
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4393
        // not detect carrier sense in FD and set collision
4394
        eth_phy.carrier_sense_tx_fd_detect(0);
4395
        eth_phy.collision(1);
4396
      end
4397
      default: // 2'h3: // Interrupt is not generated
4398
      begin
4399
        // disable interrupt generation
4400 209 tadejm
        set_tx_bd(0, 0, i_length, 1'b0, 1'b1, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
4401 194 tadej
        // mask interrupts
4402
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4403
        // detect carrier sense in FD and set collision
4404
        eth_phy.carrier_sense_tx_fd_detect(1);
4405
        eth_phy.collision(1);
4406
      end
4407
      endcase
4408
      eth_phy.set_tx_mem_addr(max_tmp);
4409
      // set wrap bit
4410
      set_tx_bd_wrap(0);
4411
      set_tx_bd_ready(0, 0);
4412 169 mohor
      #1 check_tx_bd(0, data);
4413 194 tadej
      if (i_length < min_tmp) // just first four
4414 169 mohor
      begin
4415 194 tadej
        while (data[15] === 1)
4416
        begin
4417
          #1 check_tx_bd(0, data);
4418
          @(posedge wb_clk);
4419
        end
4420 209 tadejm
        repeat (1) @(posedge wb_clk);
4421 169 mohor
      end
4422 194 tadej
      else if (i_length > (max_tmp - 8)) // just last four
4423 192 tadej
      begin
4424 194 tadej
        tmp = 0;
4425
        wait (MTxEn === 1'b1); // start transmit
4426
        while (tmp < (i_length - 20))
4427
        begin
4428
          #1 tmp = tmp + 1;
4429
          @(posedge wb_clk);
4430
        end
4431
        #1 check_tx_bd(0, data);
4432
        while (data[15] === 1)
4433
        begin
4434
          #1 check_tx_bd(0, data);
4435
          @(posedge wb_clk);
4436
        end
4437 209 tadejm
        repeat (1) @(posedge wb_clk);
4438 192 tadej
      end
4439
      else
4440
      begin
4441 194 tadej
        wait (MTxEn === 1'b1); // start transmit
4442
        #1 check_tx_bd(0, data);
4443
        if (data[15] !== 1)
4444
        begin
4445
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
4446
          fail = fail + 1;
4447
        end
4448
        wait (MTxEn === 1'b0); // end transmit
4449
        while (data[15] === 1)
4450
        begin
4451
          #1 check_tx_bd(0, data);
4452
          @(posedge wb_clk);
4453
        end
4454
        repeat (1) @(posedge wb_clk);
4455 192 tadej
      end
4456 194 tadej
      // check length of a PACKET
4457
      if (eth_phy.tx_len != (i_length + 4))
4458 192 tadej
      begin
4459 194 tadej
        test_fail("Wrong length of the packet out from MAC");
4460 192 tadej
        fail = fail + 1;
4461
      end
4462 194 tadej
      // checking in the following if statement is performed only for first and last 64 lengths
4463
      if ( ((i_length + 4) <= (min_tmp + 64)) || ((i_length + 4) > (max_tmp - 64)) )
4464 192 tadej
      begin
4465 194 tadej
        // check transmitted TX packet data
4466
        if (i_length[0] == 0)
4467
        begin
4468 209 tadejm
          check_tx_packet((`MEMORY_BASE + i_length[1:0]), max_tmp, i_length, tmp);
4469 194 tadej
        end
4470
        else
4471
        begin
4472 209 tadejm
          check_tx_packet(((`MEMORY_BASE + i_length[1:0]) + max_tmp), max_tmp, i_length, tmp);
4473 194 tadej
        end
4474
        if (tmp > 0)
4475
        begin
4476
          test_fail("Wrong data of the transmitted packet");
4477
          fail = fail + 1;
4478
        end
4479
        // check transmited TX packet CRC
4480
        check_tx_crc(max_tmp, i_length, 1'b0, tmp); // length without CRC
4481
        if (tmp > 0)
4482
        begin
4483
          test_fail("Wrong CRC of the transmitted packet");
4484
          fail = fail + 1;
4485
        end
4486 192 tadej
      end
4487 194 tadej
      // check WB INT signal
4488
      if (i_length[1:0] == 2'h0)
4489 192 tadej
      begin
4490 194 tadej
        if (wb_int !== 1'b1)
4491
        begin
4492
          `TIME; $display("*E WB INT signal should be set");
4493
          test_fail("WB INT signal should be set");
4494
          fail = fail + 1;
4495
        end
4496 192 tadej
      end
4497 194 tadej
      else
4498 192 tadej
      begin
4499 194 tadej
        if (wb_int !== 1'b0)
4500
        begin
4501
          `TIME; $display("*E WB INT signal should not be set");
4502
          test_fail("WB INT signal should not be set");
4503
          fail = fail + 1;
4504
        end
4505 192 tadej
      end
4506 194 tadej
      // check TX buffer descriptor of a packet
4507
      check_tx_bd(0, data);
4508
      if (i_length[1] == 1'b0) // interrupt enabled
4509 192 tadej
      begin
4510 194 tadej
        if (data[15:0] !== 16'h7800)
4511
        begin
4512
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
4513
          test_fail("TX buffer descriptor status is not correct");
4514
          fail = fail + 1;
4515
        end
4516 192 tadej
      end
4517 194 tadej
      else // interrupt not enabled
4518 192 tadej
      begin
4519 194 tadej
        if (data[15:0] !== 16'h3800)
4520
        begin
4521
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
4522
          test_fail("TX buffer descriptor status is not correct");
4523
          fail = fail + 1;
4524
        end
4525 192 tadej
      end
4526 194 tadej
      // clear TX buffer descriptor
4527
      clear_tx_bd(0, 0);
4528
      // check interrupts
4529
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4530
      if ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1))
4531 192 tadej
      begin
4532 194 tadej
        if ((data & `ETH_INT_TXB) !== 1'b1)
4533
        begin
4534
          `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
4535
          test_fail("Interrupt Transmit Buffer was not set");
4536
          fail = fail + 1;
4537
        end
4538
        if ((data & (~`ETH_INT_TXB)) !== 0)
4539
        begin
4540
          `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
4541
          test_fail("Other interrupts (except Transmit Buffer) were set");
4542
          fail = fail + 1;
4543
        end
4544 192 tadej
      end
4545 194 tadej
      else
4546 192 tadej
      begin
4547 194 tadej
        if (data !== 0)
4548
        begin
4549
          `TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]);
4550
          test_fail("Any of interrupts (except Transmit Buffer) was set");
4551
          fail = fail + 1;
4552
        end
4553 192 tadej
      end
4554 194 tadej
      // clear interrupts
4555
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4556
      // check WB INT signal
4557
      if (wb_int !== 1'b0)
4558 192 tadej
      begin
4559 194 tadej
        test_fail("WB INT signal should not be set");
4560 192 tadej
        fail = fail + 1;
4561
      end
4562 194 tadej
      // INTERMEDIATE DISPLAYS
4563
      if ((i_length + 4) == (min_tmp + 64))
4564 209 tadejm
      begin
4565 194 tadej
        // starting length is min_tmp, ending length is (min_tmp + 64)
4566 209 tadejm
        $display("    pads appending to packets is NOT selected");
4567
        $display("    ->packets with lengths from %0d (MINFL) to %0d are checked (length increasing by 1 byte)",
4568 194 tadej
                 min_tmp, (min_tmp + 64));
4569 209 tadejm
        // set padding, remain the rest
4570
        wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
4571
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4572
      end
4573 194 tadej
      else if ((i_length + 4) == (max_tmp - 16))
4574 209 tadejm
      begin
4575 194 tadej
        // starting length is for +128 longer than previous ending length, while ending length is tmp_data
4576 209 tadejm
        $display("    pads appending to packets is selected");
4577
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 128 bytes)",
4578 194 tadej
                 (min_tmp + 64 + 128), tmp_data);
4579 209 tadejm
        // reset padding, remain the rest
4580
        wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
4581
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4582
      end
4583 194 tadej
      else if ((i_length + 4) == max_tmp)
4584 209 tadejm
      begin
4585
        $display("    pads appending to packets is NOT selected");
4586
        $display("    ->packets with lengths from %0d to %0d (MAXFL) are checked (length increasing by 1 byte)",
4587 194 tadej
                 (max_tmp - (4 + 16)), max_tmp);
4588 209 tadejm
      end
4589 194 tadej
      // set length (loop variable)
4590
      if ((i_length + 4) < (min_tmp + 64))
4591
        i_length = i_length + 1;
4592
      else if ( ((i_length + 4) >= (min_tmp + 64)) && ((i_length + 4) <= (max_tmp - 256)) )
4593
      begin
4594
        i_length = i_length + 128;
4595
        tmp_data = i_length + 4; // last tmp_data is ending length
4596
      end
4597
      else if ( ((i_length + 4) > (max_tmp - 256)) && ((i_length + 4) < (max_tmp - 16)) )
4598
        i_length = max_tmp - (4 + 16);
4599
      else if ((i_length + 4) >= (max_tmp - 16))
4600
        i_length = i_length + 1;
4601
      else
4602
      begin
4603
        $display("*E TESTBENCH ERROR - WRONG PARAMETERS IN TESTBENCH");
4604
        #10 $stop;
4605
      end
4606 192 tadej
    end
4607 194 tadej
    // disable TX
4608
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
4609
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4610
    if(fail == 0)
4611
      test_ok;
4612
    else
4613
      fail = 0;
4614
  end
4615
 
4616
 
4617
  ////////////////////////////////////////////////////////////////////
4618
  ////                                                            ////
4619
  ////  Test transmit packets form MINFL to MAXFL sizes at        ////
4620
  ////  one TX buffer decriptor ( 100Mbps ).                      ////
4621
  ////                                                            ////
4622
  ////////////////////////////////////////////////////////////////////
4623 209 tadejm
  if (test_num == 3) // with and without padding
4624 194 tadej
  begin
4625
    // TEST 3: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT ONE TX BD ( 100Mbps )
4626
    test_name = "TEST 3: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT ONE TX BD ( 100Mbps )";
4627
    `TIME; $display("  TEST 3: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT ONE TX BD ( 100Mbps )");
4628
 
4629
    max_tmp = 0;
4630
    min_tmp = 0;
4631
    // set one TX buffer descriptor - must be set before TX enable
4632
    wbm_write(`ETH_TX_BD_NUM, 32'h1, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4633 209 tadejm
    // enable TX, set full-duplex mode, NO padding and CRC appending
4634
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
4635 194 tadej
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4636
    // prepare two packets of MAXFL length
4637
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4638
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
4639
    min_tmp = tmp[31:16];
4640
    st_data = 8'h5A;
4641 209 tadejm
    set_tx_packet(`MEMORY_BASE, (max_tmp), st_data); // length without CRC
4642 194 tadej
    st_data = 8'h10;
4643 209 tadejm
    set_tx_packet((`MEMORY_BASE + max_tmp), (max_tmp), st_data); // length without CRC
4644 169 mohor
    // check WB INT signal
4645 192 tadej
    if (wb_int !== 1'b0)
4646 169 mohor
    begin
4647
      test_fail("WB INT signal should not be set");
4648
      fail = fail + 1;
4649
    end
4650 194 tadej
 
4651
    // write to phy's control register for 100Mbps
4652
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
4653
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
4654
    speed = 100;
4655 192 tadej
 
4656 194 tadej
    i_length = (min_tmp - 4);
4657
    while (i_length <= (max_tmp - 4))
4658 192 tadej
    begin
4659 194 tadej
      // choose generating carrier sense and collision
4660
      case (i_length[1:0])
4661
      2'h0: // Interrupt is generated
4662 192 tadej
      begin
4663 194 tadej
        // enable interrupt generation
4664 209 tadejm
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, (`MEMORY_BASE + i_length[1:0]));
4665 194 tadej
        // unmask interrupts
4666 209 tadejm
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
4667 194 tadej
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4668
        // not detect carrier sense in FD and no collision
4669
        eth_phy.carrier_sense_tx_fd_detect(0);
4670
        eth_phy.collision(0);
4671 192 tadej
      end
4672 194 tadej
      2'h1: // Interrupt is not generated
4673 192 tadej
      begin
4674 194 tadej
        // enable interrupt generation
4675 209 tadejm
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
4676 194 tadej
        // mask interrupts
4677
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4678
        // detect carrier sense in FD and no collision
4679
        eth_phy.carrier_sense_tx_fd_detect(1);
4680
        eth_phy.collision(0);
4681 192 tadej
      end
4682 194 tadej
      2'h2: // Interrupt is not generated
4683
      begin
4684
        // disable interrupt generation
4685 209 tadejm
        set_tx_bd(0, 0, i_length, 1'b0, 1'b1, 1'b1, (`MEMORY_BASE + i_length[1:0]));
4686 194 tadej
        // unmask interrupts
4687 209 tadejm
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
4688 194 tadej
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4689
        // not detect carrier sense in FD and set collision
4690
        eth_phy.carrier_sense_tx_fd_detect(0);
4691
        eth_phy.collision(1);
4692
      end
4693
      default: // 2'h3: // Interrupt is not generated
4694
      begin
4695
        // disable interrupt generation
4696 209 tadejm
        set_tx_bd(0, 0, i_length, 1'b0, 1'b1, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
4697 194 tadej
        // mask interrupts
4698
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4699
        // detect carrier sense in FD and set collision
4700
        eth_phy.carrier_sense_tx_fd_detect(1);
4701
        eth_phy.collision(1);
4702
      end
4703
      endcase
4704
      eth_phy.set_tx_mem_addr(max_tmp);
4705
      // set wrap bit
4706
      set_tx_bd_wrap(0);
4707
      set_tx_bd_ready(0, 0);
4708 192 tadej
      #1 check_tx_bd(0, data);
4709 194 tadej
      if (i_length < min_tmp) // just first four
4710 192 tadej
      begin
4711 194 tadej
        while (data[15] === 1)
4712
        begin
4713
          #1 check_tx_bd(0, data);
4714
          @(posedge wb_clk);
4715
        end
4716 209 tadejm
        repeat (1) @(posedge wb_clk);
4717 194 tadej
      end
4718
      else if (i_length > (max_tmp - 8)) // just last four
4719
      begin
4720
        tmp = 0;
4721
        wait (MTxEn === 1'b1); // start transmit
4722
        while (tmp < (i_length - 20))
4723
        begin
4724
          #1 tmp = tmp + 1;
4725
          @(posedge wb_clk);
4726
        end
4727 192 tadej
        #1 check_tx_bd(0, data);
4728 194 tadej
        while (data[15] === 1)
4729
        begin
4730
          #1 check_tx_bd(0, data);
4731
          @(posedge wb_clk);
4732
        end
4733 209 tadejm
        repeat (1) @(posedge wb_clk);
4734 192 tadej
      end
4735 194 tadej
      else
4736
      begin
4737
        wait (MTxEn === 1'b1); // start transmit
4738
        #1 check_tx_bd(0, data);
4739
        if (data[15] !== 1)
4740
        begin
4741
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
4742
          fail = fail + 1;
4743
        end
4744
        wait (MTxEn === 1'b0); // end transmit
4745
        while (data[15] === 1)
4746
        begin
4747
          #1 check_tx_bd(0, data);
4748
          @(posedge wb_clk);
4749
        end
4750
        repeat (1) @(posedge wb_clk);
4751
      end
4752
      // check length of a PACKET
4753
      if (eth_phy.tx_len != (i_length + 4))
4754
      begin
4755
        test_fail("Wrong length of the packet out from MAC");
4756
        fail = fail + 1;
4757
      end
4758 192 tadej
      // check transmitted TX packet data
4759
      if (i_length[0] == 0)
4760
      begin
4761 209 tadejm
        check_tx_packet((`MEMORY_BASE + i_length[1:0]), max_tmp, i_length, tmp);
4762 192 tadej
      end
4763
      else
4764
      begin
4765 209 tadejm
        check_tx_packet(((`MEMORY_BASE + i_length[1:0]) + max_tmp), max_tmp, i_length, tmp);
4766 192 tadej
      end
4767
      if (tmp > 0)
4768
      begin
4769
        test_fail("Wrong data of the transmitted packet");
4770
        fail = fail + 1;
4771
      end
4772
      // check transmited TX packet CRC
4773
      check_tx_crc(max_tmp, i_length, 1'b0, tmp); // length without CRC
4774
      if (tmp > 0)
4775
      begin
4776
        test_fail("Wrong CRC of the transmitted packet");
4777
        fail = fail + 1;
4778
      end
4779 194 tadej
      // check WB INT signal
4780
      if (i_length[1:0] == 2'h0)
4781 192 tadej
      begin
4782 194 tadej
        if (wb_int !== 1'b1)
4783
        begin
4784
          `TIME; $display("*E WB INT signal should be set");
4785
          test_fail("WB INT signal should be set");
4786
          fail = fail + 1;
4787
        end
4788 192 tadej
      end
4789 194 tadej
      else
4790 192 tadej
      begin
4791 194 tadej
        if (wb_int !== 1'b0)
4792
        begin
4793
          `TIME; $display("*E WB INT signal should not be set");
4794
          test_fail("WB INT signal should not be set");
4795
          fail = fail + 1;
4796
        end
4797 192 tadej
      end
4798 194 tadej
      // check TX buffer descriptor of a packet
4799
      check_tx_bd(0, data);
4800
      if (i_length[1] == 1'b0) // interrupt enabled
4801 192 tadej
      begin
4802 194 tadej
        if (data[15:0] !== 16'h7800)
4803
        begin
4804
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
4805
          test_fail("TX buffer descriptor status is not correct");
4806
          fail = fail + 1;
4807
        end
4808 192 tadej
      end
4809 194 tadej
      else // interrupt not enabled
4810 192 tadej
      begin
4811 194 tadej
        if (data[15:0] !== 16'h3800)
4812
        begin
4813
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
4814
          test_fail("TX buffer descriptor status is not correct");
4815
          fail = fail + 1;
4816
        end
4817 192 tadej
      end
4818 194 tadej
      // clear TX buffer descriptor
4819
      clear_tx_bd(0, 0);
4820
      // check interrupts
4821
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4822
      if ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1))
4823 192 tadej
      begin
4824 194 tadej
        if ((data & `ETH_INT_TXB) !== 1'b1)
4825
        begin
4826
          `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
4827
          test_fail("Interrupt Transmit Buffer was not set");
4828
          fail = fail + 1;
4829
        end
4830
        if ((data & (~`ETH_INT_TXB)) !== 0)
4831
        begin
4832
          `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
4833
          test_fail("Other interrupts (except Transmit Buffer) were set");
4834
          fail = fail + 1;
4835
        end
4836 192 tadej
      end
4837 194 tadej
      else
4838 192 tadej
      begin
4839 194 tadej
        if (data !== 0)
4840
        begin
4841
          `TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h", data);
4842
          test_fail("Any of interrupts (except Transmit Buffer) was set");
4843
          fail = fail + 1;
4844
        end
4845 192 tadej
      end
4846 194 tadej
      // clear interrupts
4847
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4848
      // check WB INT signal
4849
      if (wb_int !== 1'b0)
4850 192 tadej
      begin
4851 194 tadej
        test_fail("WB INT signal should not be set");
4852 192 tadej
        fail = fail + 1;
4853
      end
4854 194 tadej
      // INTERMEDIATE DISPLAYS
4855
      if ((i_length + 4) == (min_tmp + 64))
4856 209 tadejm
      begin
4857 194 tadej
        // starting length is min_tmp, ending length is (min_tmp + 64)
4858 209 tadejm
        $display("    pads appending to packets is NOT selected");
4859
        $display("    ->packets with lengths from %0d (MINFL) to %0d are checked (length increasing by 1 byte)",
4860 194 tadej
                 min_tmp, (min_tmp + 64));
4861 209 tadejm
        // set padding, remain the rest
4862
        wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
4863
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4864
      end
4865 194 tadej
      else if ((i_length + 4) == (max_tmp - 16))
4866 209 tadejm
      begin
4867 194 tadej
        // starting length is for +128 longer than previous ending length, while ending length is tmp_data
4868 209 tadejm
        $display("    pads appending to packets is selected");
4869
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 128 bytes)",
4870 194 tadej
                 (min_tmp + 64 + 128), tmp_data);
4871 209 tadejm
        // reset padding, remain the rest
4872
        wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
4873
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4874
      end
4875 194 tadej
      else if ((i_length + 4) == max_tmp)
4876 209 tadejm
      begin
4877
        $display("    pads appending to packets is NOT selected");
4878
        $display("    ->packets with lengths from %0d to %0d (MAXFL) are checked (length increasing by 1 byte)",
4879 194 tadej
                 (max_tmp - (4 + 16)), max_tmp);
4880 209 tadejm
      end
4881 194 tadej
      // set length (loop variable)
4882
      if ((i_length + 4) < (min_tmp + 64))
4883
        i_length = i_length + 1;
4884
      else if ( ((i_length + 4) >= (min_tmp + 64)) && ((i_length + 4) <= (max_tmp - 256)) )
4885
      begin
4886
        i_length = i_length + 128;
4887
        tmp_data = i_length + 4; // last tmp_data is ending length
4888
      end
4889
      else if ( ((i_length + 4) > (max_tmp - 256)) && ((i_length + 4) < (max_tmp - 16)) )
4890
        i_length = max_tmp - (4 + 16);
4891
      else if ((i_length + 4) >= (max_tmp - 16))
4892
        i_length = i_length + 1;
4893 192 tadej
      else
4894 194 tadej
      begin
4895
        $display("*E TESTBENCH ERROR - WRONG PARAMETERS IN TESTBENCH");
4896
        #10 $stop;
4897
      end
4898 179 mohor
    end
4899 194 tadej
    // disable TX
4900
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
4901
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4902
    if(fail == 0)
4903
      test_ok;
4904
    else
4905
      fail = 0;
4906 169 mohor
  end
4907
 
4908
 
4909 209 tadejm
  ////////////////////////////////////////////////////////////////////
4910
  ////                                                            ////
4911
  ////  Test transmit packets form MINFL to MAXFL sizes at        ////
4912
  ////  maximum TX buffer decriptors ( 10Mbps ).                  ////
4913
  ////                                                            ////
4914
  ////////////////////////////////////////////////////////////////////
4915
  if (test_num == 4) // without and with padding
4916
  begin
4917
    // TEST 4: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT MAX TX BDs ( 10Mbps )
4918
    test_name = "TEST 4: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT MAX TX BDs ( 10Mbps )";
4919
    `TIME; $display("  TEST 4: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT MAX TX BDs ( 10Mbps )");
4920
 
4921
    // reset MAC registers
4922
    hard_reset;
4923
    // reset MAC and MII LOGIC with soft reset
4924
    reset_mac;
4925
    reset_mii;
4926
    // set wb slave response
4927
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
4928 192 tadej
 
4929 209 tadejm
    max_tmp = 0;
4930
    min_tmp = 0;
4931
    num_of_frames = 0;
4932
    num_of_bd = 0;
4933
    // set maximum TX buffer descriptors (128) - must be set before TX enable
4934
    wbm_write(`ETH_TX_BD_NUM, 32'h80, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4935
    // enable TX, set full-duplex mode, NO padding and CRC appending
4936
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
4937
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4938
    // prepare two packets of MAXFL length
4939
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4940
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
4941
    min_tmp = tmp[31:16];
4942
    st_data = 8'hA3;
4943
    set_tx_packet(`MEMORY_BASE, (max_tmp), st_data); // length without CRC
4944
    st_data = 8'h81;
4945
    set_tx_packet((`MEMORY_BASE + max_tmp), (max_tmp), st_data); // length without CRC
4946
    // check WB INT signal
4947
    if (wb_int !== 1'b0)
4948
    begin
4949
      test_fail("WB INT signal should not be set");
4950
      fail = fail + 1;
4951
    end
4952
 
4953
    // write to phy's control register for 10Mbps
4954
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
4955
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
4956
    speed = 10;
4957
 
4958
    i_length = (min_tmp - 4);
4959
    while (i_length <= (max_tmp - 4))
4960
    begin
4961
      // choose generating carrier sense and collision
4962
      case (i_length[1:0])
4963
      2'h0: // Interrupt is generated
4964
      begin
4965
        // Reset_tx_bd nable interrupt generation
4966
        // unmask interrupts
4967
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
4968
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4969
        // not detect carrier sense in FD and no collision
4970
        eth_phy.carrier_sense_tx_fd_detect(0);
4971
        eth_phy.collision(0);
4972
      end
4973
      2'h1: // Interrupt is not generated
4974
      begin
4975
        // set_tx_bd enable interrupt generation
4976
        // mask interrupts
4977
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4978
        // detect carrier sense in FD and no collision
4979
        eth_phy.carrier_sense_tx_fd_detect(1);
4980
        eth_phy.collision(0);
4981
      end
4982
      2'h2: // Interrupt is not generated
4983
      begin
4984
        // set_tx_bd disable the interrupt generation
4985
        // unmask interrupts
4986
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
4987
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4988
        // not detect carrier sense in FD and set collision
4989
        eth_phy.carrier_sense_tx_fd_detect(0);
4990
        eth_phy.collision(1);
4991
      end
4992
      default: // 2'h3: // Interrupt is not generated
4993
      begin
4994
        // set_tx_bd disable the interrupt generation
4995
        // mask interrupts
4996
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4997
        // detect carrier sense in FD and set collision
4998
        eth_phy.carrier_sense_tx_fd_detect(1);
4999
        eth_phy.collision(1);
5000
      end
5001
      endcase
5002
      // first destination address on ethernet PHY
5003
      if (i_length[0] == 0)
5004
        eth_phy.set_tx_mem_addr(0);
5005
      else
5006
        eth_phy.set_tx_mem_addr(max_tmp);
5007
      // first 8 frames are transmitted with TX BD 0 (wrap bit on TX BD 0)
5008
      // number of all frames is 154 (146 without first 8)
5009
      if (num_of_frames < 8)
5010
      begin
5011
        case (i_length[1:0])
5012
        2'h0: // Interrupt is generated
5013
        begin
5014
          // enable interrupt generation
5015
          set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, (`MEMORY_BASE + i_length[1:0]));
5016
          // interrupts are unmasked
5017
        end
5018
        2'h1: // Interrupt is not generated
5019
        begin
5020
          // enable interrupt generation
5021
          set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
5022
          // interrupts are masked
5023
        end
5024
        2'h2: // Interrupt is not generated
5025
        begin
5026
          // disable interrupt generation
5027
          set_tx_bd(0, 0, i_length, 1'b0, 1'b1, 1'b1, (`MEMORY_BASE + i_length[1:0]));
5028
          // interrupts are unmasked
5029
        end
5030
        default: // 2'h3: // Interrupt is not generated
5031
        begin
5032
          // disable interrupt generation
5033
          set_tx_bd(0, 0, i_length, 1'b0, 1'b1, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
5034
          // interrupts are masked
5035
        end
5036
        endcase
5037
        // set wrap bit
5038
        set_tx_bd_wrap(0);
5039
      end
5040
      // after first 8 number of frames, 128 frames form TX BD 0 to 127 will be transmitted
5041
      else if ((num_of_frames - 8) == 0)
5042
      begin
5043
        tmp_len = i_length; // length of frame
5044
        tmp_bd_num = 0; // TX BD number
5045
        while (tmp_bd_num < 128) // (tmp_len <= (max_tmp - 4)) - this is the last frame
5046
        begin
5047
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
5048
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
5049
          if (tmp_len[0] == 0)
5050
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + tmp_len[1:0]));
5051
          else
5052
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, ((`MEMORY_BASE + tmp_len[1:0]) + max_tmp));
5053
          // set length (loop variable) - THE SAME AS AT THE END OF THIS TASK !!!
5054
          if ((tmp_len + 4) < (min_tmp + 128))
5055
            tmp_len = tmp_len + 1;
5056
          else if ( ((tmp_len + 4) == (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
5057
            tmp_len = 256;
5058
          else if ( ((tmp_len + 4) > (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
5059
            tmp_len = tmp_len + 128;
5060
          else if ( ((tmp_len + 4) > (max_tmp - 256)) && ((tmp_len + 4) < (max_tmp - 16)) )
5061
            tmp_len = max_tmp - (4 + 16);
5062
          else if ((tmp_len + 4) >= (max_tmp - 16))
5063
            tmp_len = tmp_len + 1;
5064
          // set TX BD number
5065
          tmp_bd_num = tmp_bd_num + 1;
5066
        end
5067
        // set wrap bit
5068
        set_tx_bd_wrap(127);
5069
      end
5070
      // after 128 + first 8 number of frames, 19 frames form TX BD 0 to 18 will be transmitted
5071
      else if ((num_of_frames - 8) == 20) // 128
5072
      begin
5073
        tmp_len = tmp_len; // length of frame remaines from previous settings
5074
        tmp_bd_num = 0; // TX BD number
5075
        while (tmp_bd_num < 19) // (tmp_len <= (max_tmp - 4)) - this is the last frame
5076
        begin
5077
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
5078
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
5079
          if (tmp_len[0] == 0)
5080
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + tmp_len[1:0]));
5081
          else
5082
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, ((`MEMORY_BASE + tmp_len[1:0]) + max_tmp));
5083
          // set length (loop variable) - THE SAME AS AT THE END OF THIS TASK !!!
5084
          if ((tmp_len + 4) < (min_tmp + 128))
5085
            tmp_len = tmp_len + 1;
5086
          else if ( ((tmp_len + 4) == (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
5087
            tmp_len = 256;
5088
          else if ( ((tmp_len + 4) > (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
5089
            tmp_len = tmp_len + 128;
5090
          else if ( ((tmp_len + 4) > (max_tmp - 256)) && ((tmp_len + 4) < (max_tmp - 16)) )
5091
            tmp_len = max_tmp - (4 + 16);
5092
          else if ((tmp_len + 4) >= (max_tmp - 16))
5093
            tmp_len = tmp_len + 1;
5094
          // set TX BD number
5095
          tmp_bd_num = tmp_bd_num + 1;
5096
        end
5097
      end
5098
      // set ready bit
5099
      if (num_of_frames < 8)
5100
        set_tx_bd_ready(0, 0);
5101
      else if ((num_of_frames - 8) < 128)
5102
        set_tx_bd_ready((num_of_frames - 8), (num_of_frames - 8));
5103
      else if ((num_of_frames - 136) < 19)
5104
        set_tx_bd_ready((num_of_frames - 136), (num_of_frames - 136));
5105
      // CHECK END OF TRANSMITION
5106
      #1 check_tx_bd(num_of_bd, data);
5107
      if (i_length < min_tmp) // just first four
5108
      begin
5109
        while (data[15] === 1)
5110
        begin
5111
          #1 check_tx_bd(num_of_bd, data);
5112
          @(posedge wb_clk);
5113
        end
5114
        repeat (1) @(posedge wb_clk);
5115
      end
5116
      else if (i_length > (max_tmp - 8)) // just last four
5117
      begin
5118
        tmp = 0;
5119
        wait (MTxEn === 1'b1); // start transmit
5120
        while (tmp < (i_length - 20))
5121
        begin
5122
          #1 tmp = tmp + 1;
5123
          @(posedge wb_clk);
5124
        end
5125
        #1 check_tx_bd(num_of_bd, data);
5126
        while (data[15] === 1)
5127
        begin
5128
          #1 check_tx_bd(num_of_bd, data);
5129
          @(posedge wb_clk);
5130
        end
5131
        repeat (1) @(posedge wb_clk);
5132
      end
5133
      else
5134
      begin
5135
        wait (MTxEn === 1'b1); // start transmit
5136
        #1 check_tx_bd(num_of_bd, data);
5137
        if (data[15] !== 1)
5138
        begin
5139
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
5140
          fail = fail + 1;
5141
        end
5142
        wait (MTxEn === 1'b0); // end transmit
5143
        while (data[15] === 1)
5144
        begin
5145
          #1 check_tx_bd(num_of_bd, data);
5146
          @(posedge wb_clk);
5147
        end
5148
        repeat (1) @(posedge wb_clk);
5149
      end
5150
      // check length of a PACKET
5151
      if (eth_phy.tx_len != (i_length + 4))
5152
      begin
5153
        test_fail("Wrong length of the packet out from MAC");
5154
        fail = fail + 1;
5155
      end
5156
        // check transmitted TX packet data
5157
        if (i_length[0] == 0)
5158
        begin
5159
          check_tx_packet((`MEMORY_BASE + i_length[1:0]), 0, i_length, tmp);
5160
        end
5161
        else
5162
        begin
5163
          check_tx_packet(((`MEMORY_BASE + i_length[1:0]) + max_tmp), max_tmp, i_length, tmp);
5164
        end
5165
        if (tmp > 0)
5166
        begin
5167
          test_fail("Wrong data of the transmitted packet");
5168
          fail = fail + 1;
5169
        end
5170
        // check transmited TX packet CRC
5171
        if (i_length[0] == 0)
5172
          check_tx_crc(0, i_length, 1'b0, tmp); // length without CRC
5173
        else
5174
          check_tx_crc(max_tmp, i_length, 1'b0, tmp); // length without CRC
5175
        if (tmp > 0)
5176
        begin
5177
          test_fail("Wrong CRC of the transmitted packet");
5178
          fail = fail + 1;
5179
        end
5180
      // check WB INT signal
5181
      if (i_length[1:0] == 2'h0)
5182
      begin
5183
        if (wb_int !== 1'b1)
5184
        begin
5185
          `TIME; $display("*E WB INT signal should be set");
5186
          test_fail("WB INT signal should be set");
5187
          fail = fail + 1;
5188
        end
5189
      end
5190
      else
5191
      begin
5192
        if (wb_int !== 1'b0)
5193
        begin
5194
          `TIME; $display("*E WB INT signal should not be set");
5195
          test_fail("WB INT signal should not be set");
5196
          fail = fail + 1;
5197
        end
5198
      end
5199
      // check TX buffer descriptor of a packet
5200
      check_tx_bd(num_of_bd, data);
5201
      if (i_length[1] == 1'b0) // interrupt enabled
5202
      begin
5203
        if ( ((data[15:0] !== 16'h7800) && ((num_of_frames < 8) || ((num_of_frames - 8) == 127))) || // wrap bit
5204
             ((data[15:0] !== 16'h5800) && (num_of_frames >= 8) && ((num_of_frames - 8) != 127)) ) // without wrap bit
5205
        begin
5206
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
5207
          test_fail("TX buffer descriptor status is not correct");
5208
          fail = fail + 1;
5209
        end
5210
      end
5211
      else // interrupt not enabled
5212
      begin
5213
        if ( ((data[15:0] !== 16'h3800)  && ((num_of_frames < 8) || ((num_of_frames - 8) == 127))) || // wrap bit
5214
             ((data[15:0] !== 16'h1800) && (num_of_frames >= 8) && ((num_of_frames - 8) != 127)) ) // without wrap bit
5215
        begin
5216
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
5217
          test_fail("TX buffer descriptor status is not correct");
5218
          fail = fail + 1;
5219
        end
5220
      end
5221
      // clear first half of 8 frames from TX buffer descriptor 0
5222
      if (num_of_frames < 4)
5223
        clear_tx_bd(num_of_bd, num_of_bd);
5224
      // clear BD with wrap bit
5225
      if (num_of_frames == 140)
5226
        clear_tx_bd(127, 127);
5227
      // check interrupts
5228
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5229
      if ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1))
5230
      begin
5231
        if ((data & `ETH_INT_TXB) !== 1'b1)
5232
        begin
5233
          `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
5234
          test_fail("Interrupt Transmit Buffer was not set");
5235
          fail = fail + 1;
5236
        end
5237
        if ((data & (~`ETH_INT_TXB)) !== 0)
5238
        begin
5239
          `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
5240
          test_fail("Other interrupts (except Transmit Buffer) were set");
5241
          fail = fail + 1;
5242
        end
5243
      end
5244
      else
5245
      begin
5246
        if (data !== 0)
5247
        begin
5248
          `TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]);
5249
          test_fail("Any of interrupts (except Transmit Buffer) was set");
5250
          fail = fail + 1;
5251
        end
5252
      end
5253
      // clear interrupts
5254
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5255
      // check WB INT signal
5256
      if (wb_int !== 1'b0)
5257
      begin
5258
        test_fail("WB INT signal should not be set");
5259
        fail = fail + 1;
5260
      end
5261
      // INTERMEDIATE DISPLAYS
5262
      if ((i_length + 4) == (min_tmp + 7))
5263
      begin
5264
        // starting length is min_tmp, ending length is (min_tmp + 128)
5265
        $display("    pads appending to packets is NOT selected");
5266
        $display("    using only TX BD 0 out of 128 BDs assigned to TX (wrap at first BD - TX BD 0)");
5267
        $display("    ->packets with lengths from %0d (MINFL) to %0d are checked (length increasing by 1 byte)",
5268
                 min_tmp, (min_tmp + 7));
5269
        $display("    ->all packets were send from TX BD 0");
5270
        // set padding, remain the rest
5271
        wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
5272
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5273
      end
5274
      else if ((i_length + 4) == (min_tmp + 128))
5275
      begin
5276
        // starting length is min_tmp, ending length is (min_tmp + 128)
5277
        $display("    pads appending to packets is NOT selected");
5278
        $display("    using all 128 BDs assigned to TX (wrap at 128th BD - TX BD 127)");
5279
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
5280
                 (min_tmp + 8), (min_tmp + 128));
5281
        $display("    ->packets were send from TX BD %0d to TX BD %0d respectively",
5282
                 1'b0, num_of_bd);
5283
        tmp_bd = num_of_bd + 1;
5284
        // set padding, remain the rest
5285
        wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
5286
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5287
      end
5288
      else if ((i_length + 4) == (max_tmp - 16))
5289
      begin
5290
        // starting length is for +128 longer than previous ending length, while ending length is tmp_data
5291
        $display("    pads appending to packets is selected");
5292
        $display("    using all 128 BDs assigned to TX (wrap at 128th BD - TX BD 127)");
5293
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 128 bytes)",
5294
                 (min_tmp + 64 + 128), tmp_data);
5295
        if (tmp_bd > num_of_bd)
5296
          $display("    ->packets were send from TX BD %0d to TX BD 127 and from TX BD 0 to TX BD %0d respectively",
5297
                   tmp_bd, num_of_bd);
5298
        else
5299
          $display("    ->packets were send from TX BD %0d to TX BD %0d respectively",
5300
                   tmp_bd, num_of_bd);
5301
        tmp_bd = num_of_bd + 1;
5302
        // reset padding, remain the rest
5303
        wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
5304
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5305
      end
5306
      else if ((i_length + 4) == max_tmp)
5307
      begin
5308
        $display("    pads appending to packets is NOT selected");
5309
        $display("    using all 128 BDs assigned to TX (wrap at 128th BD - TX BD 127)");
5310
        $display("    ->packets with lengths from %0d to %0d (MAXFL) are checked (length increasing by 1 byte)",
5311
                 (max_tmp - (4 + 16)), max_tmp);
5312
        if (tmp_bd > num_of_bd)
5313
          $display("    ->packets were send from TX BD %0d to TX BD 127 and from TX BD 0 to TX BD %0d respectively",
5314
                   tmp_bd, num_of_bd);
5315
        else
5316
          $display("    ->packets were send from TX BD %0d to TX BD %0d respectively",
5317
                   tmp_bd, num_of_bd);
5318
      end
5319
      // set length (loop variable)
5320
      if ((i_length + 4) < (min_tmp + 128))
5321
        i_length = i_length + 1;
5322
      else if ( ((i_length + 4) == (min_tmp + 128)) && ((i_length + 4) <= (max_tmp - 256)) )
5323
        i_length = 256;
5324
      else if ( ((i_length + 4) > (min_tmp + 128)) && ((i_length + 4) <= (max_tmp - 256)) )
5325
      begin
5326
        i_length = i_length + 128;
5327
        tmp_data = i_length + 4; // last tmp_data is ending length
5328
      end
5329
      else if ( ((i_length + 4) > (max_tmp - 256)) && ((i_length + 4) < (max_tmp - 16)) )
5330
        i_length = max_tmp - (4 + 16);
5331
      else if ((i_length + 4) >= (max_tmp - 16))
5332
        i_length = i_length + 1;
5333
      else
5334
      begin
5335
        $display("*E TESTBENCH ERROR - WRONG PARAMETERS IN TESTBENCH");
5336
        #10 $stop;
5337
      end
5338
      // the number of frame transmitted
5339
      num_of_frames = num_of_frames + 1;
5340
      if ((num_of_frames <= 8) || ((num_of_frames - 8) == 128))
5341
        num_of_bd = 0;
5342
      else
5343
        num_of_bd = num_of_bd + 1;
5344
    end
5345
    // disable TX
5346
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
5347
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5348
    @(posedge wb_clk);
5349
    if(fail == 0)
5350
      test_ok;
5351
    else
5352
      fail = 0;
5353
  end
5354
 
5355
 
5356
  ////////////////////////////////////////////////////////////////////
5357
  ////                                                            ////
5358
  ////  Test transmit packets form MINFL to MAXFL sizes at        ////
5359
  ////  maximum TX buffer decriptors ( 100Mbps ).                 ////
5360
  ////                                                            ////
5361
  ////////////////////////////////////////////////////////////////////
5362
  if (test_num == 5) // with and without padding
5363
  begin
5364
    // TEST 5: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT MAX TX BDs ( 100Mbps )
5365
    test_name = "TEST 5: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT MAX TX BDs ( 100Mbps )";
5366
    `TIME; $display("  TEST 5: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT MAX TX BDs ( 100Mbps )");
5367
 
5368
    // reset MAC registers
5369
    hard_reset;
5370
    // reset MAC and MII LOGIC with soft reset
5371
    reset_mac;
5372
    reset_mii;
5373
    // set wb slave response
5374
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
5375
 
5376
    max_tmp = 0;
5377
    min_tmp = 0;
5378
    num_of_frames = 0;
5379
    num_of_bd = 0;
5380
    // set maximum TX buffer descriptors (128) - must be set before TX enable
5381
    wbm_write(`ETH_TX_BD_NUM, 32'h80, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5382
    // enable TX, set full-duplex mode, NO padding and CRC appending
5383
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
5384
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5385
    // prepare two packets of MAXFL length
5386
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5387
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
5388
    min_tmp = tmp[31:16];
5389
    st_data = 8'hA5;
5390
    set_tx_packet(`MEMORY_BASE, (max_tmp), st_data); // length without CRC
5391
    st_data = 8'h71;
5392
    set_tx_packet((`MEMORY_BASE + max_tmp), (max_tmp), st_data); // length without CRC
5393
    // check WB INT signal
5394
    if (wb_int !== 1'b0)
5395
    begin
5396
      test_fail("WB INT signal should not be set");
5397
      fail = fail + 1;
5398
    end
5399
 
5400
    // write to phy's control register for 100Mbps
5401
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
5402
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
5403
    speed = 100;
5404
 
5405
    i_length = (min_tmp - 4);
5406
    while (i_length <= (max_tmp - 4))
5407
    begin
5408
      // choose generating carrier sense and collision
5409
      case (i_length[1:0])
5410
      2'h0: // Interrupt is generated
5411
      begin
5412
        // Reset_tx_bd nable interrupt generation
5413
        // unmask interrupts
5414
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
5415
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5416
        // not detect carrier sense in FD and no collision
5417
        eth_phy.carrier_sense_tx_fd_detect(0);
5418
        eth_phy.collision(0);
5419
      end
5420
      2'h1: // Interrupt is not generated
5421
      begin
5422
        // set_tx_bd enable interrupt generation
5423
        // mask interrupts
5424
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5425
        // detect carrier sense in FD and no collision
5426
        eth_phy.carrier_sense_tx_fd_detect(1);
5427
        eth_phy.collision(0);
5428
      end
5429
      2'h2: // Interrupt is not generated
5430
      begin
5431
        // set_tx_bd disable the interrupt generation
5432
        // unmask interrupts
5433
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
5434
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5435
        // not detect carrier sense in FD and set collision
5436
        eth_phy.carrier_sense_tx_fd_detect(0);
5437
        eth_phy.collision(1);
5438
      end
5439
      default: // 2'h3: // Interrupt is not generated
5440
      begin
5441
        // set_tx_bd disable the interrupt generation
5442
        // mask interrupts
5443
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5444
        // detect carrier sense in FD and set collision
5445
        eth_phy.carrier_sense_tx_fd_detect(1);
5446
        eth_phy.collision(1);
5447
      end
5448
      endcase
5449
      // first destination address on ethernet PHY
5450
      if (i_length[0] == 0)
5451
        eth_phy.set_tx_mem_addr(0);
5452
      else
5453
        eth_phy.set_tx_mem_addr(max_tmp);
5454
      // first 8 frames are transmitted with TX BD 0 (wrap bit on TX BD 0)
5455
      // number of all frames is 154 (146 without first 8)
5456
      if (num_of_frames < 8)
5457
      begin
5458
        case (i_length[1:0])
5459
        2'h0: // Interrupt is generated
5460
        begin
5461
          // enable interrupt generation
5462
          set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, (`MEMORY_BASE + i_length[1:0]));
5463
          // interrupts are unmasked
5464
        end
5465
        2'h1: // Interrupt is not generated
5466
        begin
5467
          // enable interrupt generation
5468
          set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
5469
          // interrupts are masked
5470
        end
5471
        2'h2: // Interrupt is not generated
5472
        begin
5473
          // disable interrupt generation
5474
          set_tx_bd(0, 0, i_length, 1'b0, 1'b1, 1'b1, (`MEMORY_BASE + i_length[1:0]));
5475
          // interrupts are unmasked
5476
        end
5477
        default: // 2'h3: // Interrupt is not generated
5478
        begin
5479
          // disable interrupt generation
5480
          set_tx_bd(0, 0, i_length, 1'b0, 1'b1, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
5481
          // interrupts are masked
5482
        end
5483
        endcase
5484
        // set wrap bit
5485
        set_tx_bd_wrap(0);
5486
      end
5487
      // after first 8 number of frames, 128 frames form TX BD 0 to 127 will be transmitted
5488
      else if ((num_of_frames - 8) == 0)
5489
      begin
5490
        tmp_len = i_length; // length of frame
5491
        tmp_bd_num = 0; // TX BD number
5492
        while (tmp_bd_num < 128) // (tmp_len <= (max_tmp - 4)) - this is the last frame
5493
        begin
5494
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
5495
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
5496
          if (tmp_len[0] == 0)
5497
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + tmp_len[1:0]));
5498
          else
5499
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, ((`MEMORY_BASE + tmp_len[1:0]) + max_tmp));
5500
          // set length (loop variable) - THE SAME AS AT THE END OF THIS TASK !!!
5501
          if ((tmp_len + 4) < (min_tmp + 128))
5502
            tmp_len = tmp_len + 1;
5503
          else if ( ((tmp_len + 4) == (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
5504
            tmp_len = 256;
5505
          else if ( ((tmp_len + 4) > (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
5506
            tmp_len = tmp_len + 128;
5507
          else if ( ((tmp_len + 4) > (max_tmp - 256)) && ((tmp_len + 4) < (max_tmp - 16)) )
5508
            tmp_len = max_tmp - (4 + 16);
5509
          else if ((tmp_len + 4) >= (max_tmp - 16))
5510
            tmp_len = tmp_len + 1;
5511
          // set TX BD number
5512
          tmp_bd_num = tmp_bd_num + 1;
5513
        end
5514
        // set wrap bit
5515
        set_tx_bd_wrap(127);
5516
      end
5517
      // after 128 + first 8 number of frames, 19 frames form TX BD 0 to 18 will be transmitted
5518
      else if ((num_of_frames - 8) == 20) // 128
5519
      begin
5520
        tmp_len = tmp_len; // length of frame remaines from previous settings
5521
        tmp_bd_num = 0; // TX BD number
5522
        while (tmp_bd_num < 19) // (tmp_len <= (max_tmp - 4)) - this is the last frame
5523
        begin
5524
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
5525
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
5526
          if (tmp_len[0] == 0)
5527
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + tmp_len[1:0]));
5528
          else
5529
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, ((`MEMORY_BASE + tmp_len[1:0]) + max_tmp));
5530
          // set length (loop variable) - THE SAME AS AT THE END OF THIS TASK !!!
5531
          if ((tmp_len + 4) < (min_tmp + 128))
5532
            tmp_len = tmp_len + 1;
5533
          else if ( ((tmp_len + 4) == (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
5534
            tmp_len = 256;
5535
          else if ( ((tmp_len + 4) > (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
5536
            tmp_len = tmp_len + 128;
5537
          else if ( ((tmp_len + 4) > (max_tmp - 256)) && ((tmp_len + 4) < (max_tmp - 16)) )
5538
            tmp_len = max_tmp - (4 + 16);
5539
          else if ((tmp_len + 4) >= (max_tmp - 16))
5540
            tmp_len = tmp_len + 1;
5541
          // set TX BD number
5542
          tmp_bd_num = tmp_bd_num + 1;
5543
        end
5544
      end
5545
      // set ready bit
5546
      if (num_of_frames < 8)
5547
        set_tx_bd_ready(0, 0);
5548
      else if ((num_of_frames - 8) < 128)
5549
        set_tx_bd_ready((num_of_frames - 8), (num_of_frames - 8));
5550
      else if ((num_of_frames - 136) < 19)
5551
        set_tx_bd_ready((num_of_frames - 136), (num_of_frames - 136));
5552
      // CHECK END OF TRANSMITION
5553
      #1 check_tx_bd(num_of_bd, data);
5554
      if (i_length < min_tmp) // just first four
5555
      begin
5556
        while (data[15] === 1)
5557
        begin
5558
          #1 check_tx_bd(num_of_bd, data);
5559
          @(posedge wb_clk);
5560
        end
5561
        repeat (1) @(posedge wb_clk);
5562
      end
5563
      else if (i_length > (max_tmp - 8)) // just last four
5564
      begin
5565
        tmp = 0;
5566
        wait (MTxEn === 1'b1); // start transmit
5567
        while (tmp < (i_length - 20))
5568
        begin
5569
          #1 tmp = tmp + 1;
5570
          @(posedge wb_clk);
5571
        end
5572
        #1 check_tx_bd(num_of_bd, data);
5573
        while (data[15] === 1)
5574
        begin
5575
          #1 check_tx_bd(num_of_bd, data);
5576
          @(posedge wb_clk);
5577
        end
5578
        repeat (1) @(posedge wb_clk);
5579
      end
5580
      else
5581
      begin
5582
        wait (MTxEn === 1'b1); // start transmit
5583
        #1 check_tx_bd(num_of_bd, data);
5584
        if (data[15] !== 1)
5585
        begin
5586
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
5587
          fail = fail + 1;
5588
        end
5589
        wait (MTxEn === 1'b0); // end transmit
5590
        while (data[15] === 1)
5591
        begin
5592
          #1 check_tx_bd(num_of_bd, data);
5593
          @(posedge wb_clk);
5594
        end
5595
        repeat (1) @(posedge wb_clk);
5596
      end
5597
      // check length of a PACKET
5598
      if (eth_phy.tx_len != (i_length + 4))
5599
      begin
5600
        test_fail("Wrong length of the packet out from MAC");
5601
        fail = fail + 1;
5602
      end
5603
      // checking in the following if statement is performed only for first and last 64 lengths
5604
        // check transmitted TX packet data
5605
        if (i_length[0] == 0)
5606
        begin
5607
          check_tx_packet((`MEMORY_BASE + i_length[1:0]), 0, i_length, tmp);
5608
        end
5609
        else
5610
        begin
5611
          check_tx_packet(((`MEMORY_BASE + i_length[1:0]) + max_tmp), max_tmp, i_length, tmp);
5612
        end
5613
        if (tmp > 0)
5614
        begin
5615
          test_fail("Wrong data of the transmitted packet");
5616
          fail = fail + 1;
5617
        end
5618
        // check transmited TX packet CRC
5619
        if (i_length[0] == 0)
5620
          check_tx_crc(0, i_length, 1'b0, tmp); // length without CRC
5621
        else
5622
          check_tx_crc(max_tmp, i_length, 1'b0, tmp); // length without CRC
5623
        if (tmp > 0)
5624
        begin
5625
          test_fail("Wrong CRC of the transmitted packet");
5626
          fail = fail + 1;
5627
        end
5628
      // check WB INT signal
5629
      if (i_length[1:0] == 2'h0)
5630
      begin
5631
        if (wb_int !== 1'b1)
5632
        begin
5633
          `TIME; $display("*E WB INT signal should be set");
5634
          test_fail("WB INT signal should be set");
5635
          fail = fail + 1;
5636
        end
5637
      end
5638
      else
5639
      begin
5640
        if (wb_int !== 1'b0)
5641
        begin
5642
          `TIME; $display("*E WB INT signal should not be set");
5643
          test_fail("WB INT signal should not be set");
5644
          fail = fail + 1;
5645
        end
5646
      end
5647
      // check TX buffer descriptor of a packet
5648
      check_tx_bd(num_of_bd, data);
5649
      if (i_length[1] == 1'b0) // interrupt enabled
5650
      begin
5651
        if ( ((data[15:0] !== 16'h7800) && ((num_of_frames < 8) || ((num_of_frames - 8) == 127))) || // wrap bit
5652
             ((data[15:0] !== 16'h5800) && (num_of_frames >= 8) && ((num_of_frames - 8) != 127)) ) // without wrap bit
5653
        begin
5654
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
5655
          test_fail("TX buffer descriptor status is not correct");
5656
          fail = fail + 1;
5657
        end
5658
      end
5659
      else // interrupt not enabled
5660
      begin
5661
        if ( ((data[15:0] !== 16'h3800)  && ((num_of_frames < 8) || ((num_of_frames - 8) == 127))) || // wrap bit
5662
             ((data[15:0] !== 16'h1800) && (num_of_frames >= 8) && ((num_of_frames - 8) != 127)) ) // without wrap bit
5663
        begin
5664
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
5665
          test_fail("TX buffer descriptor status is not correct");
5666
          fail = fail + 1;
5667
        end
5668
      end
5669
      // clear first half of 8 frames from TX buffer descriptor 0
5670
      if (num_of_frames < 4)
5671
        clear_tx_bd(num_of_bd, num_of_bd);
5672
      // clear BD with wrap bit
5673
      if (num_of_frames == 140)
5674
        clear_tx_bd(127, 127);
5675
      // check interrupts
5676
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5677
      if ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1))
5678
      begin
5679
        if ((data & `ETH_INT_TXB) !== 1'b1)
5680
        begin
5681
          `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
5682
          test_fail("Interrupt Transmit Buffer was not set");
5683
          fail = fail + 1;
5684
        end
5685
        if ((data & (~`ETH_INT_TXB)) !== 0)
5686
        begin
5687
          `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
5688
          test_fail("Other interrupts (except Transmit Buffer) were set");
5689
          fail = fail + 1;
5690
        end
5691
      end
5692
      else
5693
      begin
5694
        if (data !== 0)
5695
        begin
5696
          `TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]);
5697
          test_fail("Any of interrupts (except Transmit Buffer) was set");
5698
          fail = fail + 1;
5699
        end
5700
      end
5701
      // clear interrupts
5702
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5703
      // check WB INT signal
5704
      if (wb_int !== 1'b0)
5705
      begin
5706
        test_fail("WB INT signal should not be set");
5707
        fail = fail + 1;
5708
      end
5709
      // INTERMEDIATE DISPLAYS
5710
      if ((i_length + 4) == (min_tmp + 7))
5711
      begin
5712
        // starting length is min_tmp, ending length is (min_tmp + 128)
5713
        $display("    pads appending to packets is NOT selected");
5714
        $display("    using only TX BD 0 out of 128 BDs assigned to TX (wrap at first BD - TX BD 0)");
5715
        $display("    ->packets with lengths from %0d (MINFL) to %0d are checked (length increasing by 1 byte)",
5716
                 min_tmp, (min_tmp + 7));
5717
        $display("    ->all packets were send from TX BD 0");
5718
        // set padding, remain the rest
5719
        wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
5720
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5721
      end
5722
      else if ((i_length + 4) == (min_tmp + 128))
5723
      begin
5724
        // starting length is min_tmp, ending length is (min_tmp + 128)
5725
        $display("    pads appending to packets is NOT selected");
5726
        $display("    using all 128 BDs assigned to TX (wrap at 128th BD - TX BD 127)");
5727
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
5728
                 (min_tmp + 8), (min_tmp + 128));
5729
        $display("    ->packets were send from TX BD %0d to TX BD %0d respectively",
5730
                 1'b0, num_of_bd);
5731
        tmp_bd = num_of_bd + 1;
5732
        // set padding, remain the rest
5733
        wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
5734
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5735
      end
5736
      else if ((i_length + 4) == (max_tmp - 16))
5737
      begin
5738
        // starting length is for +128 longer than previous ending length, while ending length is tmp_data
5739
        $display("    pads appending to packets is selected");
5740
        $display("    using all 128 BDs assigned to TX (wrap at 128th BD - TX BD 127)");
5741
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 128 bytes)",
5742
                 (min_tmp + 64 + 128), tmp_data);
5743
        if (tmp_bd > num_of_bd)
5744
          $display("    ->packets were send from TX BD %0d to TX BD 127 and from TX BD 0 to TX BD %0d respectively",
5745
                   tmp_bd, num_of_bd);
5746
        else
5747
          $display("    ->packets were send from TX BD %0d to TX BD %0d respectively",
5748
                   tmp_bd, num_of_bd);
5749
        tmp_bd = num_of_bd + 1;
5750
        // reset padding, remain the rest
5751
        wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
5752
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5753
      end
5754
      else if ((i_length + 4) == max_tmp)
5755
      begin
5756
        $display("    pads appending to packets is NOT selected");
5757
        $display("    using all 128 BDs assigned to TX (wrap at 128th BD - TX BD 127)");
5758
        $display("    ->packets with lengths from %0d to %0d (MAXFL) are checked (length increasing by 1 byte)",
5759
                 (max_tmp - (4 + 16)), max_tmp);
5760
        if (tmp_bd > num_of_bd)
5761
          $display("    ->packets were send from TX BD %0d to TX BD 127 and from TX BD 0 to TX BD %0d respectively",
5762
                   tmp_bd, num_of_bd);
5763
        else
5764
          $display("    ->packets were send from TX BD %0d to TX BD %0d respectively",
5765
                   tmp_bd, num_of_bd);
5766
      end
5767
      // set length (loop variable)
5768
      if ((i_length + 4) < (min_tmp + 128))
5769
        i_length = i_length + 1;
5770
      else if ( ((i_length + 4) == (min_tmp + 128)) && ((i_length + 4) <= (max_tmp - 256)) )
5771
        i_length = 256;
5772
      else if ( ((i_length + 4) > (min_tmp + 128)) && ((i_length + 4) <= (max_tmp - 256)) )
5773
      begin
5774
        i_length = i_length + 128;
5775
        tmp_data = i_length + 4; // last tmp_data is ending length
5776
      end
5777
      else if ( ((i_length + 4) > (max_tmp - 256)) && ((i_length + 4) < (max_tmp - 16)) )
5778
        i_length = max_tmp - (4 + 16);
5779
      else if ((i_length + 4) >= (max_tmp - 16))
5780
        i_length = i_length + 1;
5781
      else
5782
      begin
5783
        $display("*E TESTBENCH ERROR - WRONG PARAMETERS IN TESTBENCH");
5784
        #10 $stop;
5785
      end
5786
      // the number of frame transmitted
5787
      num_of_frames = num_of_frames + 1;
5788
      if ((num_of_frames <= 8) || ((num_of_frames - 8) == 128))
5789
        num_of_bd = 0;
5790
      else
5791
        num_of_bd = num_of_bd + 1;
5792
    end
5793
    // disable TX
5794
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
5795
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5796
    @(posedge wb_clk);
5797
    if(fail == 0)
5798
      test_ok;
5799
    else
5800
      fail = 0;
5801
  end
5802
 
5803
 
5804
  ////////////////////////////////////////////////////////////////////
5805
  ////                                                            ////
5806
  ////  Test transmit packets form 0 to (MINFL - 1) sizes at      ////
5807
  ////  8 TX buffer decriptors ( 10Mbps ).                        ////
5808
  ////                                                            ////
5809
  ////////////////////////////////////////////////////////////////////
5810
  if (test_num == 6) // 
5811
  begin
5812
    // TEST 6: TRANSMIT PACKETS FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 10Mbps )
5813
    test_name = "TEST 6: TRANSMIT PACKETS FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 10Mbps )";
5814
    `TIME; $display("  TEST 6: TRANSMIT PACKETS FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 10Mbps )");
5815
 
5816
    // reset MAC registers
5817
    hard_reset;
5818
    // reset MAC and MII LOGIC with soft reset
5819
    reset_mac;
5820
    reset_mii;
5821
    // set wb slave response
5822
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
5823
 
5824
    max_tmp = 0;
5825
    min_tmp = 0;
5826
    // set 8 TX buffer descriptors - must be set before TX enable
5827
    wbm_write(`ETH_TX_BD_NUM, 32'h8, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5828
    // enable TX, set full-duplex mode, padding and CRC appending
5829
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_PAD | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
5830
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5831
    // prepare two packets of MAXFL length
5832
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5833
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
5834
    min_tmp = tmp[31:16];
5835
    st_data = 8'h12;
5836
    set_tx_packet(`MEMORY_BASE, (max_tmp - 4), st_data); // length without CRC
5837
    st_data = 8'h34;
5838
    set_tx_packet((`MEMORY_BASE + max_tmp), (max_tmp - 4), st_data); // length without CRC
5839
    // check WB INT signal
5840
    if (wb_int !== 1'b0)
5841
    begin
5842
      test_fail("WB INT signal should not be set");
5843
      fail = fail + 1;
5844
    end
5845
 
5846
    // write to phy's control register for 10Mbps
5847
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
5848
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
5849
    speed = 10;
5850
 
5851
    frame_started = 0;
5852
    num_of_frames = 0;
5853
    num_of_bd = 0;
5854
    i_length = 0; // 0;
5855
    while (i_length < 70) // (min_tmp - 4))
5856
    begin
5857
      #1;
5858
      // choose generating carrier sense and collision
5859
      case (i_length[1:0])
5860
      2'h0: // Interrupt is generated
5861
      begin
5862
        // Reset_tx_bd nable interrupt generation
5863
        // unmask interrupts
5864
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
5865
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5866
        // not detect carrier sense in FD and no collision
5867
        eth_phy.carrier_sense_tx_fd_detect(0);
5868
        eth_phy.collision(0);
5869
      end
5870
      2'h1: // Interrupt is not generated
5871
      begin
5872
        // set_tx_bd enable interrupt generation
5873
        // mask interrupts
5874
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5875
        // detect carrier sense in FD and no collision
5876
        eth_phy.carrier_sense_tx_fd_detect(1);
5877
        eth_phy.collision(0);
5878
      end
5879
      2'h2: // Interrupt is not generated
5880
      begin
5881
        // set_tx_bd disable the interrupt generation
5882
        // unmask interrupts
5883
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
5884
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5885
        // not detect carrier sense in FD and set collision
5886
        eth_phy.carrier_sense_tx_fd_detect(0);
5887
        eth_phy.collision(1);
5888
      end
5889
      default: // 2'h3: // Interrupt is not generated
5890
      begin
5891
        // set_tx_bd disable the interrupt generation
5892
        // mask interrupts
5893
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5894
        // detect carrier sense in FD and set collision
5895
        eth_phy.carrier_sense_tx_fd_detect(1);
5896
        eth_phy.collision(1);
5897
      end
5898
      endcase
5899
      #1;
5900
      // first destination address on ethernet PHY
5901
      eth_phy.set_tx_mem_addr(num_of_frames * 16);
5902
      // SET packets and wrap bit
5903
      // num_of_frames <= 9 => wrap set to TX BD 0
5904
      if (num_of_frames <= 9)
5905
      begin
5906
        tmp_len = i_length; // length of frame
5907
        tmp_bd_num = 0; // TX BD number
5908
        // if i_length[1] == 0 then enable interrupt generation otherwise disable it
5909
        // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
5910
        if (tmp_len[0] == 0)
5911
          set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
5912
        else
5913
          set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
5914
        // set wrap bit
5915
        set_tx_bd_wrap(0);
5916
      end
5917
      // 10 <= num_of_frames < 18 => wrap set to TX BD 3
5918
      else if ((num_of_frames == 10) || (num_of_frames == 14))
5919
      begin
5920
        tmp_len = i_length; // length of frame
5921
        tmp_bd_num = 0; // TX BD number
5922
        while (tmp_bd_num < 4) //
5923
        begin
5924
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
5925
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
5926
          if (tmp_len[0] == 0)
5927
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
5928
          else
5929
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
5930
          tmp_len = tmp_len + 1;
5931
          // set TX BD number
5932
          tmp_bd_num = tmp_bd_num + 1;
5933
        end
5934
        // set wrap bit
5935
        set_tx_bd_wrap(3);
5936
      end
5937
      // 18 <= num_of_frames < 28 => wrap set to TX BD 4
5938
      else if ((num_of_frames == 18) || (num_of_frames == 23))
5939
      begin
5940
        tmp_len = i_length; // length of frame
5941
        tmp_bd_num = 0; // TX BD number
5942
        while (tmp_bd_num < 5) //
5943
        begin
5944
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
5945
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
5946
          if (tmp_len[0] == 0)
5947
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
5948
          else
5949
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
5950
          tmp_len = tmp_len + 1;
5951
          // set TX BD number
5952
          tmp_bd_num = tmp_bd_num + 1;
5953
        end
5954
        // set wrap bit
5955
        set_tx_bd_wrap(4);
5956
      end
5957
      // 28 <= num_of_frames < 40 => wrap set to TX BD 5
5958
      else if ((num_of_frames == 28) || (num_of_frames == 34))
5959
      begin
5960
        tmp_len = i_length; // length of frame
5961
        tmp_bd_num = 0; // TX BD number
5962
        while (tmp_bd_num < 6) //
5963
        begin
5964
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
5965
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
5966
          if (tmp_len[0] == 0)
5967
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
5968
          else
5969
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
5970
          tmp_len = tmp_len + 1;
5971
          // set TX BD number
5972
          tmp_bd_num = tmp_bd_num + 1;
5973
        end
5974
        // set wrap bit
5975
        set_tx_bd_wrap(5);
5976
      end
5977
      // 40 <= num_of_frames < 54 => wrap set to TX BD 6
5978
      else if ((num_of_frames == 40) || (num_of_frames == 47))
5979
      begin
5980
        tmp_len = i_length; // length of frame
5981
        tmp_bd_num = 0; // TX BD number
5982
        while (tmp_bd_num < 7) //
5983
        begin
5984
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
5985
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
5986
          if (tmp_len[0] == 0)
5987
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
5988
          else
5989
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
5990
          tmp_len = tmp_len + 1;
5991
          // set TX BD number
5992
          tmp_bd_num = tmp_bd_num + 1;
5993
        end
5994
        // set wrap bit
5995
        set_tx_bd_wrap(6);
5996
      end
5997
      // 54 <= num_of_frames < 70 => wrap set to TX BD 7
5998
      else if ((num_of_frames == 54) || (num_of_frames == 62))
5999
      begin
6000
        tmp_len = i_length; // length of frame
6001
        tmp_bd_num = 0; // TX BD number
6002
        while (tmp_bd_num < 8) //
6003
        begin
6004
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
6005
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
6006
          if (tmp_len[0] == 0)
6007
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
6008
          else
6009
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
6010
          tmp_len = tmp_len + 1;
6011
          // set TX BD number
6012
          tmp_bd_num = tmp_bd_num + 1;
6013
        end
6014
        // set wrap bit
6015
        set_tx_bd_wrap(7);
6016
      end
6017
      #1;
6018
      // SET ready bit
6019
      if (num_of_frames < 10)
6020
        set_tx_bd_ready(0, 0);
6021
      else if (num_of_frames < 14)
6022
        set_tx_bd_ready((num_of_frames - 10), (num_of_frames - 10));
6023
      else if (num_of_frames < 18)
6024
        set_tx_bd_ready((num_of_frames - 14), (num_of_frames - 14));
6025
      else if (num_of_frames < 23)
6026
        set_tx_bd_ready((num_of_frames - 18), (num_of_frames - 18));
6027
      else if (num_of_frames < 28)
6028
        set_tx_bd_ready((num_of_frames - 23), (num_of_frames - 23));
6029
      else if (num_of_frames < 34)
6030
        set_tx_bd_ready((num_of_frames - 28), (num_of_frames - 28));
6031
      else if (num_of_frames < 40)
6032
        set_tx_bd_ready((num_of_frames - 34), (num_of_frames - 34));
6033
      else if (num_of_frames < 47)
6034
        set_tx_bd_ready((num_of_frames - 40), (num_of_frames - 40));
6035
      else if (num_of_frames < 54)
6036
        set_tx_bd_ready((num_of_frames - 47), (num_of_frames - 47));
6037
      else if (num_of_frames < 62)
6038
        set_tx_bd_ready((num_of_frames - 54), (num_of_frames - 54));
6039
      else if (num_of_frames < 70)
6040
        set_tx_bd_ready((num_of_frames - 62), (num_of_frames - 62));
6041
      // CHECK END OF TRANSMITION
6042
      frame_started = 0;
6043
      if (num_of_frames >= 5)
6044
        #1 check_tx_bd(num_of_bd, data);
6045
      fork
6046
      begin: fr_st
6047
        wait (MTxEn === 1'b1); // start transmit
6048
        frame_started = 1;
6049
      end
6050
      begin
6051
        repeat (30) @(posedge mtx_clk);
6052
        if (num_of_frames < 5)
6053
        begin
6054
          if (frame_started == 1)
6055
          begin
6056
            `TIME; $display("*E Frame should NOT start!");
6057
          end
6058
          disable fr_st;
6059
        end
6060
        else
6061
        begin
6062
          if (frame_started == 0)
6063
          begin
6064
            `TIME; $display("*W Frame should start!");
6065
            disable fr_st;
6066
          end
6067
        end
6068
      end
6069
      join
6070
      // check packets larger than 4 bytes
6071
      if (num_of_frames >= 5)
6072
      begin
6073
        wait (MTxEn === 1'b0); // end transmit
6074
        while (data[15] === 1)
6075
        begin
6076
          #1 check_tx_bd(num_of_bd, data);
6077
          @(posedge wb_clk);
6078
        end
6079
        repeat (1) @(posedge wb_clk);
6080
        // check length of a PACKET
6081
        if (i_length <= (min_tmp - 4))
6082
        begin
6083
          if (eth_phy.tx_len != min_tmp)
6084
          begin
6085
            test_fail("Wrong length of the packet out from MAC");
6086
            fail = fail + 1;
6087
          end
6088
        end
6089
        else
6090
        begin
6091
          if (eth_phy.tx_len != (i_length + 4))
6092
          begin
6093
            test_fail("Wrong length of the packet out from MAC");
6094
            fail = fail + 1;
6095
          end
6096
        end
6097
        // check transmitted TX packet data
6098
        if (i_length[0] == 0)
6099
        begin
6100
          #1 check_tx_packet(`MEMORY_BASE, (num_of_frames * 16), i_length, tmp);
6101
        end
6102
        else
6103
        begin
6104
          #1 check_tx_packet((`MEMORY_BASE + max_tmp), (num_of_frames * 16), i_length, tmp);
6105
        end
6106
        if (tmp > 0)
6107
        begin
6108
          test_fail("Wrong data of the transmitted packet");
6109
          fail = fail + 1;
6110
        end
6111
        // check transmited TX packet CRC
6112
        if (num_of_frames < (min_tmp - 4))
6113
          #1 check_tx_crc((num_of_frames * 16), (min_tmp - 4), 1'b0, tmp); // length without CRC
6114
        else
6115
          #1 check_tx_crc((num_of_frames * 16), i_length, 1'b0, tmp); // length without CRC
6116
        if (tmp > 0)
6117
        begin
6118
          test_fail("Wrong CRC of the transmitted packet");
6119
          fail = fail + 1;
6120
        end
6121
      end
6122
      // check WB INT signal
6123
      if ((i_length[1:0] == 2'h0) && (num_of_frames >= 5))
6124
      begin
6125
        if (wb_int !== 1'b1)
6126
        begin
6127
          `TIME; $display("*E WB INT signal should be set");
6128
          test_fail("WB INT signal should be set");
6129
          fail = fail + 1;
6130
        end
6131
      end
6132
      else
6133
      begin
6134
        if (wb_int !== 1'b0)
6135
        begin
6136
          `TIME; $display("*E WB INT signal should not be set");
6137
          test_fail("WB INT signal should not be set");
6138
          fail = fail + 1;
6139
        end
6140
      end
6141
      // check TX buffer descriptor of a packet
6142
      check_tx_bd(num_of_bd, data);
6143
      if (num_of_frames >= 5)
6144
      begin
6145
        if (i_length[1] == 1'b0) // interrupt enabled
6146
        begin
6147
          if ( (data[15:0] !== 16'h7800) && // wrap bit
6148
               (data[15:0] !== 16'h5800) ) // without wrap bit
6149
          begin
6150
            `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
6151
            test_fail("TX buffer descriptor status is not correct");
6152
            fail = fail + 1;
6153
          end
6154
        end
6155
        else // interrupt not enabled
6156
        begin
6157
          if ( (data[15:0] !== 16'h3800) && // wrap bit
6158
               (data[15:0] !== 16'h1800) ) // without wrap bit
6159
          begin
6160
            `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
6161
            test_fail("TX buffer descriptor status is not correct");
6162
            fail = fail + 1;
6163
          end
6164
        end
6165
      end
6166
      else
6167
      begin
6168
        if (data[15] !== 1'b1)
6169
        begin
6170
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
6171
          test_fail("TX buffer descriptor status is not correct");
6172
          fail = fail + 1;
6173
        end
6174
      end
6175
      // clear TX BD with wrap bit
6176
      if (num_of_frames == 63)
6177
        clear_tx_bd(16, 16);
6178
      // check interrupts
6179
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6180
      if ( ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1)) && (num_of_frames >= 5) )
6181
      begin
6182
        if ((data & `ETH_INT_TXB) !== 1'b1)
6183
        begin
6184
          `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
6185
          test_fail("Interrupt Transmit Buffer was not set");
6186
          fail = fail + 1;
6187
        end
6188
        if ((data & (~`ETH_INT_TXB)) !== 0)
6189
        begin
6190
          `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
6191
          test_fail("Other interrupts (except Transmit Buffer) were set");
6192
          fail = fail + 1;
6193
        end
6194
      end
6195
      else
6196
      begin
6197
        if (data !== 0)
6198
        begin
6199
          `TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]);
6200
          test_fail("Any of interrupts (except Transmit Buffer) was set");
6201
          fail = fail + 1;
6202
        end
6203
      end
6204
      // clear interrupts
6205
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6206
      // check WB INT signal
6207
      if (wb_int !== 1'b0)
6208
      begin
6209
        test_fail("WB INT signal should not be set");
6210
        fail = fail + 1;
6211
      end
6212
      // INTERMEDIATE DISPLAYS
6213
      if (i_length == 3)
6214
      begin
6215
        $display("    pads appending to packets is selected");
6216
        $display("    using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)");
6217
        $display("    ->packets with lengths from %0d to %0d are not transmitted (length increasing by 1 byte)",
6218
                 0, 3);
6219
      end
6220
      else if (i_length == 9)
6221
      begin
6222
        $display("    using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)");
6223
        $display("    ->packet with length 4 is not transmitted (length increasing by 1 byte)");
6224
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
6225
                 5, 9);
6226
      end
6227
      else if (i_length == 17)
6228
      begin
6229
        $display("    using 4 BDs out of 8 BDs assigned to TX (wrap at 4th BD - TX BD 3)");
6230
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
6231
                 10, 17);
6232
      end
6233
      else if (i_length == 27)
6234
      begin
6235
        $display("    using 5 BDs out of 8 BDs assigned to TX (wrap at 5th BD - TX BD 4)");
6236
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
6237
                 18, 27);
6238
      end
6239
      else if (i_length == 40)
6240
      begin
6241
        $display("    using 6 BDs out of 8 BDs assigned to TX (wrap at 6th BD - TX BD 5)");
6242
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
6243
                 28, 40);
6244
      end
6245
      else if (i_length == 54)
6246
      begin
6247
        $display("    using 7 BDs out of 8 BDs assigned to TX (wrap at 7th BD - TX BD 6)");
6248
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
6249
                 41, 54);
6250
      end
6251
      else if (i_length == 69)
6252
      begin
6253
        $display("    using 8 BDs out of 8 BDs assigned to TX (wrap at 8th BD - TX BD 7)");
6254
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
6255
                 55, 69);
6256
      end
6257
      // set length (loop variable)
6258
      i_length = i_length + 1;
6259
      // the number of frame transmitted
6260
      num_of_frames = num_of_frames + 1;
6261
      if (/*(num_of_frames == 2) || (num_of_frames == 4) || (num_of_frames == 7) ||*/ (num_of_frames <= 10) ||
6262
          (num_of_frames == 14) || (num_of_frames == 18) || (num_of_frames == 23) || (num_of_frames == 28) ||
6263
          (num_of_frames == 34) || (num_of_frames == 40) || (num_of_frames == 47) ||
6264
          (num_of_frames == 54) || (num_of_frames == 62))
6265
        num_of_bd = 0;
6266
      else
6267
        num_of_bd = num_of_bd + 1;
6268
    end
6269
    // disable TX
6270
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
6271
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6272
    @(posedge wb_clk);
6273
    if(fail == 0)
6274
      test_ok;
6275
    else
6276
      fail = 0;
6277
  end
6278
 
6279
 
6280
  ////////////////////////////////////////////////////////////////////
6281
  ////                                                            ////
6282
  ////  Test transmit packets form 0 to (MINFL - 1) sizes at      ////
6283
  ////  8 TX buffer decriptors ( 100Mbps ).                       ////
6284
  ////                                                            ////
6285
  ////////////////////////////////////////////////////////////////////
6286
  if (test_num == 7) // 
6287
  begin
6288
    // TEST 7: TRANSMIT PACKETS FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 100Mbps )
6289
    test_name = "TEST 7: TRANSMIT PACKETS FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 100Mbps )";
6290
    `TIME; $display("  TEST 7: TRANSMIT PACKETS FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 100Mbps )");
6291
 
6292
    // reset MAC registers
6293
    hard_reset;
6294
    // reset MAC and MII LOGIC with soft reset
6295
    reset_mac;
6296
    reset_mii;
6297
    // set wb slave response
6298
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
6299
 
6300
    max_tmp = 0;
6301
    min_tmp = 0;
6302
    // set 8 TX buffer descriptors - must be set before TX enable
6303
    wbm_write(`ETH_TX_BD_NUM, 32'h8, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6304
    // enable TX, set full-duplex mode, padding and CRC appending
6305
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_PAD | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
6306
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6307
    // prepare two packets of MAXFL length
6308
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6309
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
6310
    min_tmp = tmp[31:16];
6311
    st_data = 8'h12;
6312
    set_tx_packet(`MEMORY_BASE, (max_tmp - 4), st_data); // length without CRC
6313
    st_data = 8'h34;
6314
    set_tx_packet((`MEMORY_BASE + max_tmp), (max_tmp - 4), st_data); // length without CRC
6315
    // check WB INT signal
6316
    if (wb_int !== 1'b0)
6317
    begin
6318
      test_fail("WB INT signal should not be set");
6319
      fail = fail + 1;
6320
    end
6321
 
6322
    // write to phy's control register for 100Mbps
6323
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
6324
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
6325
    speed = 100;
6326
 
6327
    frame_started = 0;
6328
    num_of_frames = 0;
6329
    num_of_bd = 0;
6330
    i_length = 0; // 0;
6331
    while (i_length < 70) // (min_tmp - 4))
6332
    begin
6333
      #1;
6334
      // choose generating carrier sense and collision
6335
      case (i_length[1:0])
6336
      2'h0: // Interrupt is generated
6337
      begin
6338
        // Reset_tx_bd nable interrupt generation
6339
        // unmask interrupts
6340
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
6341
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6342
        // not detect carrier sense in FD and no collision
6343
        eth_phy.carrier_sense_tx_fd_detect(0);
6344
        eth_phy.collision(0);
6345
      end
6346
      2'h1: // Interrupt is not generated
6347
      begin
6348
        // set_tx_bd enable interrupt generation
6349
        // mask interrupts
6350
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6351
        // detect carrier sense in FD and no collision
6352
        eth_phy.carrier_sense_tx_fd_detect(1);
6353
        eth_phy.collision(0);
6354
      end
6355
      2'h2: // Interrupt is not generated
6356
      begin
6357
        // set_tx_bd disable the interrupt generation
6358
        // unmask interrupts
6359
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
6360
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6361
        // not detect carrier sense in FD and set collision
6362
        eth_phy.carrier_sense_tx_fd_detect(0);
6363
        eth_phy.collision(1);
6364
      end
6365
      default: // 2'h3: // Interrupt is not generated
6366
      begin
6367
        // set_tx_bd disable the interrupt generation
6368
        // mask interrupts
6369
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6370
        // detect carrier sense in FD and set collision
6371
        eth_phy.carrier_sense_tx_fd_detect(1);
6372
        eth_phy.collision(1);
6373
      end
6374
      endcase
6375
      #1;
6376
      // first destination address on ethernet PHY
6377
      eth_phy.set_tx_mem_addr(num_of_frames * 16);
6378
      // SET packets and wrap bit
6379
      // num_of_frames <= 9 => wrap set to TX BD 0
6380
      if (num_of_frames <= 9)
6381
      begin
6382
        tmp_len = i_length; // length of frame
6383
        tmp_bd_num = 0; // TX BD number
6384
        // if i_length[1] == 0 then enable interrupt generation otherwise disable it
6385
        // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
6386
        if (tmp_len[0] == 0)
6387
          set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
6388
        else
6389
          set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
6390
        // set wrap bit
6391
        set_tx_bd_wrap(0);
6392
      end
6393
      // 10 <= num_of_frames < 18 => wrap set to TX BD 3
6394
      else if ((num_of_frames == 10) || (num_of_frames == 14))
6395
      begin
6396
        tmp_len = i_length; // length of frame
6397
        tmp_bd_num = 0; // TX BD number
6398
        while (tmp_bd_num < 4) //
6399
        begin
6400
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
6401
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
6402
          if (tmp_len[0] == 0)
6403
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
6404
          else
6405
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
6406
          tmp_len = tmp_len + 1;
6407
          // set TX BD number
6408
          tmp_bd_num = tmp_bd_num + 1;
6409
        end
6410
        // set wrap bit
6411
        set_tx_bd_wrap(3);
6412
      end
6413
      // 18 <= num_of_frames < 28 => wrap set to TX BD 4
6414
      else if ((num_of_frames == 18) || (num_of_frames == 23))
6415
      begin
6416
        tmp_len = i_length; // length of frame
6417
        tmp_bd_num = 0; // TX BD number
6418
        while (tmp_bd_num < 5) //
6419
        begin
6420
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
6421
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
6422
          if (tmp_len[0] == 0)
6423
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
6424
          else
6425
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
6426
          tmp_len = tmp_len + 1;
6427
          // set TX BD number
6428
          tmp_bd_num = tmp_bd_num + 1;
6429
        end
6430
        // set wrap bit
6431
        set_tx_bd_wrap(4);
6432
      end
6433
      // 28 <= num_of_frames < 40 => wrap set to TX BD 5
6434
      else if ((num_of_frames == 28) || (num_of_frames == 34))
6435
      begin
6436
        tmp_len = i_length; // length of frame
6437
        tmp_bd_num = 0; // TX BD number
6438
        while (tmp_bd_num < 6) //
6439
        begin
6440
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
6441
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
6442
          if (tmp_len[0] == 0)
6443
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
6444
          else
6445
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
6446
          tmp_len = tmp_len + 1;
6447
          // set TX BD number
6448
          tmp_bd_num = tmp_bd_num + 1;
6449
        end
6450
        // set wrap bit
6451
        set_tx_bd_wrap(5);
6452
      end
6453
      // 40 <= num_of_frames < 54 => wrap set to TX BD 6
6454
      else if ((num_of_frames == 40) || (num_of_frames == 47))
6455
      begin
6456
        tmp_len = i_length; // length of frame
6457
        tmp_bd_num = 0; // TX BD number
6458
        while (tmp_bd_num < 7) //
6459
        begin
6460
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
6461
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
6462
          if (tmp_len[0] == 0)
6463
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
6464
          else
6465
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
6466
          tmp_len = tmp_len + 1;
6467
          // set TX BD number
6468
          tmp_bd_num = tmp_bd_num + 1;
6469
        end
6470
        // set wrap bit
6471
        set_tx_bd_wrap(6);
6472
      end
6473
      // 54 <= num_of_frames < 70 => wrap set to TX BD 7
6474
      else if ((num_of_frames == 54) || (num_of_frames == 62))
6475
      begin
6476
        tmp_len = i_length; // length of frame
6477
        tmp_bd_num = 0; // TX BD number
6478
        while (tmp_bd_num < 8) //
6479
        begin
6480
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
6481
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
6482
          if (tmp_len[0] == 0)
6483
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
6484
          else
6485
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
6486
          tmp_len = tmp_len + 1;
6487
          // set TX BD number
6488
          tmp_bd_num = tmp_bd_num + 1;
6489
        end
6490
        // set wrap bit
6491
        set_tx_bd_wrap(7);
6492
      end
6493
      #1;
6494
      // SET ready bit
6495
      if (num_of_frames < 10)
6496
        set_tx_bd_ready(0, 0);
6497
      else if (num_of_frames < 14)
6498
        set_tx_bd_ready((num_of_frames - 10), (num_of_frames - 10));
6499
      else if (num_of_frames < 18)
6500
        set_tx_bd_ready((num_of_frames - 14), (num_of_frames - 14));
6501
      else if (num_of_frames < 23)
6502
        set_tx_bd_ready((num_of_frames - 18), (num_of_frames - 18));
6503
      else if (num_of_frames < 28)
6504
        set_tx_bd_ready((num_of_frames - 23), (num_of_frames - 23));
6505
      else if (num_of_frames < 34)
6506
        set_tx_bd_ready((num_of_frames - 28), (num_of_frames - 28));
6507
      else if (num_of_frames < 40)
6508
        set_tx_bd_ready((num_of_frames - 34), (num_of_frames - 34));
6509
      else if (num_of_frames < 47)
6510
        set_tx_bd_ready((num_of_frames - 40), (num_of_frames - 40));
6511
      else if (num_of_frames < 54)
6512
        set_tx_bd_ready((num_of_frames - 47), (num_of_frames - 47));
6513
      else if (num_of_frames < 62)
6514
        set_tx_bd_ready((num_of_frames - 54), (num_of_frames - 54));
6515
      else if (num_of_frames < 70)
6516
        set_tx_bd_ready((num_of_frames - 62), (num_of_frames - 62));
6517
      // CHECK END OF TRANSMITION
6518
      frame_started = 0;
6519
      if (num_of_frames >= 5)
6520
        #1 check_tx_bd(num_of_bd, data);
6521
      fork
6522
      begin: fr_st1
6523
        wait (MTxEn === 1'b1); // start transmit
6524
        frame_started = 1;
6525
      end
6526
      begin
6527
        repeat (30) @(posedge mtx_clk);
6528
        if (num_of_frames < 5)
6529
        begin
6530
          if (frame_started == 1)
6531
          begin
6532
            `TIME; $display("*E Frame should NOT start!");
6533
          end
6534
          disable fr_st1;
6535
        end
6536
        else
6537
        begin
6538
          if (frame_started == 0)
6539
          begin
6540
            `TIME; $display("*W Frame should start!");
6541
            disable fr_st1;
6542
          end
6543
        end
6544
      end
6545
      join
6546
      // check packets larger than 4 bytes
6547
      if (num_of_frames >= 5)
6548
      begin
6549
        wait (MTxEn === 1'b0); // end transmit
6550
        while (data[15] === 1)
6551
        begin
6552
          #1 check_tx_bd(num_of_bd, data);
6553
          @(posedge wb_clk);
6554
        end
6555
        repeat (1) @(posedge wb_clk);
6556
        // check length of a PACKET
6557
        if (i_length <= (min_tmp - 4))
6558
        begin
6559
          if (eth_phy.tx_len != min_tmp)
6560
          begin
6561
            test_fail("Wrong length of the packet out from MAC");
6562
            fail = fail + 1;
6563
          end
6564
        end
6565
        else
6566
        begin
6567
          if (eth_phy.tx_len != (i_length + 4))
6568
          begin
6569
            test_fail("Wrong length of the packet out from MAC");
6570
            fail = fail + 1;
6571
          end
6572
        end
6573
        // check transmitted TX packet data
6574
        if (i_length[0] == 0)
6575
        begin
6576
          #1 check_tx_packet(`MEMORY_BASE, (num_of_frames * 16), i_length, tmp);
6577
        end
6578
        else
6579
        begin
6580
          #1 check_tx_packet((`MEMORY_BASE + max_tmp), (num_of_frames * 16), i_length, tmp);
6581
        end
6582
        if (tmp > 0)
6583
        begin
6584
          test_fail("Wrong data of the transmitted packet");
6585
          fail = fail + 1;
6586
        end
6587
        // check transmited TX packet CRC
6588
        if (num_of_frames < (min_tmp - 4))
6589
          #1 check_tx_crc((num_of_frames * 16), (min_tmp - 4), 1'b0, tmp); // length without CRC
6590
        else
6591
          #1 check_tx_crc((num_of_frames * 16), i_length, 1'b0, tmp); // length without CRC
6592
        if (tmp > 0)
6593
        begin
6594
          test_fail("Wrong CRC of the transmitted packet");
6595
          fail = fail + 1;
6596
        end
6597
      end
6598
      // check WB INT signal
6599
      if ((i_length[1:0] == 2'h0) && (num_of_frames >= 5))
6600
      begin
6601
        if (wb_int !== 1'b1)
6602
        begin
6603
          `TIME; $display("*E WB INT signal should be set");
6604
          test_fail("WB INT signal should be set");
6605
          fail = fail + 1;
6606
        end
6607
      end
6608
      else
6609
      begin
6610
        if (wb_int !== 1'b0)
6611
        begin
6612
          `TIME; $display("*E WB INT signal should not be set");
6613
          test_fail("WB INT signal should not be set");
6614
          fail = fail + 1;
6615
        end
6616
      end
6617
      // check TX buffer descriptor of a packet
6618
      check_tx_bd(num_of_bd, data);
6619
      if (num_of_frames >= 5)
6620
      begin
6621
        if (i_length[1] == 1'b0) // interrupt enabled
6622
        begin
6623
          if ( (data[15:0] !== 16'h7800) && // wrap bit
6624
               (data[15:0] !== 16'h5800) ) // without wrap bit
6625
          begin
6626
            `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
6627
            test_fail("TX buffer descriptor status is not correct");
6628
            fail = fail + 1;
6629
          end
6630
        end
6631
        else // interrupt not enabled
6632
        begin
6633
          if ( (data[15:0] !== 16'h3800) && // wrap bit
6634
               (data[15:0] !== 16'h1800) ) // without wrap bit
6635
          begin
6636
            `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
6637
            test_fail("TX buffer descriptor status is not correct");
6638
            fail = fail + 1;
6639
          end
6640
        end
6641
      end
6642
      else
6643
      begin
6644
        if (data[15] !== 1'b1)
6645
        begin
6646
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
6647
          test_fail("TX buffer descriptor status is not correct");
6648
          fail = fail + 1;
6649
        end
6650
      end
6651
      // clear TX BD with wrap bit
6652
      if (num_of_frames == 63)
6653
        clear_tx_bd(16, 16);
6654
      // check interrupts
6655
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6656
      if ( ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1)) && (num_of_frames >= 5) )
6657
      begin
6658
        if ((data & `ETH_INT_TXB) !== 1'b1)
6659
        begin
6660
          `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
6661
          test_fail("Interrupt Transmit Buffer was not set");
6662
          fail = fail + 1;
6663
        end
6664
        if ((data & (~`ETH_INT_TXB)) !== 0)
6665
        begin
6666
          `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
6667
          test_fail("Other interrupts (except Transmit Buffer) were set");
6668
          fail = fail + 1;
6669
        end
6670
      end
6671
      else
6672
      begin
6673
        if (data !== 0)
6674
        begin
6675
          `TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]);
6676
          test_fail("Any of interrupts (except Transmit Buffer) was set");
6677
          fail = fail + 1;
6678
        end
6679
      end
6680
      // clear interrupts
6681
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6682
      // check WB INT signal
6683
      if (wb_int !== 1'b0)
6684
      begin
6685
        test_fail("WB INT signal should not be set");
6686
        fail = fail + 1;
6687
      end
6688
      // INTERMEDIATE DISPLAYS
6689
      if (i_length == 3)
6690
      begin
6691
        $display("    pads appending to packets is selected");
6692
        $display("    using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)");
6693
        $display("    ->packets with lengths from %0d to %0d are not transmitted (length increasing by 1 byte)",
6694
                 0, 3);
6695
      end
6696
      else if (i_length == 9)
6697
      begin
6698
        $display("    using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)");
6699
        $display("    ->packet with length 4 is not transmitted (length increasing by 1 byte)");
6700
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
6701
                 5, 9);
6702
      end
6703
      else if (i_length == 17)
6704
      begin
6705
        $display("    using 4 BDs out of 8 BDs assigned to TX (wrap at 4th BD - TX BD 3)");
6706
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
6707
                 10, 17);
6708
      end
6709
      else if (i_length == 27)
6710
      begin
6711
        $display("    using 5 BDs out of 8 BDs assigned to TX (wrap at 5th BD - TX BD 4)");
6712
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
6713
                 18, 27);
6714
      end
6715
      else if (i_length == 40)
6716
      begin
6717
        $display("    using 6 BDs out of 8 BDs assigned to TX (wrap at 6th BD - TX BD 5)");
6718
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
6719
                 28, 40);
6720
      end
6721
      else if (i_length == 54)
6722
      begin
6723
        $display("    using 7 BDs out of 8 BDs assigned to TX (wrap at 7th BD - TX BD 6)");
6724
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
6725
                 41, 54);
6726
      end
6727
      else if (i_length == 69)
6728
      begin
6729
        $display("    using 8 BDs out of 8 BDs assigned to TX (wrap at 8th BD - TX BD 7)");
6730
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
6731
                 55, 69);
6732
      end
6733
      // set length (loop variable)
6734
      i_length = i_length + 1;
6735
      // the number of frame transmitted
6736
      num_of_frames = num_of_frames + 1;
6737
      if (/*(num_of_frames == 2) || (num_of_frames == 4) || (num_of_frames == 7) ||*/ (num_of_frames <= 10) ||
6738
          (num_of_frames == 14) || (num_of_frames == 18) || (num_of_frames == 23) || (num_of_frames == 28) ||
6739
          (num_of_frames == 34) || (num_of_frames == 40) || (num_of_frames == 47) ||
6740
          (num_of_frames == 54) || (num_of_frames == 62))
6741
        num_of_bd = 0;
6742
      else
6743
        num_of_bd = num_of_bd + 1;
6744
    end
6745
    // disable TX
6746
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
6747
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6748
    @(posedge wb_clk);
6749
    if(fail == 0)
6750
      test_ok;
6751
    else
6752
      fail = 0;
6753
  end
6754
 
6755
 
6756
  ////////////////////////////////////////////////////////////////////
6757
  ////                                                            ////
6758
  ////  Test no transmit packets (no pads) form 0 to (MINFL - 1)  ////
6759
  ////  sizes at 8 TX buffer decriptors ( 10Mbps ).               ////
6760
  ////                                                            ////
6761
  ////////////////////////////////////////////////////////////////////
6762
  if (test_num == 8) // 
6763
  begin
6764
    // TEST 8: NO TRANSMIT PACKETS (NO PADs) FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 10Mbps )
6765
    test_name = "TEST 8: NO TRANSMIT PACKETS (NO PADs) FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 10Mbps )";
6766
    `TIME; $display("  TEST 8: NO TRANSMIT PACKETS (NO PADs) FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 10Mbps )");
6767
 
6768
    // reset MAC registers
6769
    hard_reset;
6770
    // reset MAC and MII LOGIC with soft reset
6771
    reset_mac;
6772
    reset_mii;
6773
    // set wb slave response
6774
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
6775
 
6776
    max_tmp = 0;
6777
    min_tmp = 0;
6778
    // set 8 TX buffer descriptors - must be set before TX enable
6779
    wbm_write(`ETH_TX_BD_NUM, 32'h8, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6780
    // enable TX, set full-duplex mode, padding and CRC appending
6781
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_PAD | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
6782
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6783
    // prepare two packets of MAXFL length
6784
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6785
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
6786
    min_tmp = tmp[31:16];
6787
    st_data = 8'h12;
6788
    set_tx_packet(`MEMORY_BASE, (max_tmp - 4), st_data); // length without CRC
6789
    st_data = 8'h34;
6790
    set_tx_packet((`MEMORY_BASE + max_tmp), (max_tmp - 4), st_data); // length without CRC
6791
    // check WB INT signal
6792
    if (wb_int !== 1'b0)
6793
    begin
6794
      test_fail("WB INT signal should not be set");
6795
      fail = fail + 1;
6796
    end
6797
 
6798
    // write to phy's control register for 10Mbps
6799
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
6800
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
6801
    speed = 10;
6802
 
6803
    frame_started = 0;
6804
    num_of_frames = 0;
6805
    num_of_bd = 0;
6806
    i_length = 0; // 0;
6807
    while (i_length < 70) // (min_tmp - 4))
6808
    begin
6809
      #1;
6810
      // choose generating carrier sense and collision
6811
      case (i_length[1:0])
6812
      2'h0: // Interrupt is generated
6813
      begin
6814
        // Reset_tx_bd nable interrupt generation
6815
        // unmask interrupts
6816
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
6817
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6818
        // not detect carrier sense in FD and no collision
6819
        eth_phy.carrier_sense_tx_fd_detect(0);
6820
        eth_phy.collision(0);
6821
      end
6822
      2'h1: // Interrupt is not generated
6823
      begin
6824
        // set_tx_bd enable interrupt generation
6825
        // mask interrupts
6826
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6827
        // detect carrier sense in FD and no collision
6828
        eth_phy.carrier_sense_tx_fd_detect(1);
6829
        eth_phy.collision(0);
6830
      end
6831
      2'h2: // Interrupt is not generated
6832
      begin
6833
        // set_tx_bd disable the interrupt generation
6834
        // unmask interrupts
6835
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
6836
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6837
        // not detect carrier sense in FD and set collision
6838
        eth_phy.carrier_sense_tx_fd_detect(0);
6839
        eth_phy.collision(1);
6840
      end
6841
      default: // 2'h3: // Interrupt is not generated
6842
      begin
6843
        // set_tx_bd disable the interrupt generation
6844
        // mask interrupts
6845
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6846
        // detect carrier sense in FD and set collision
6847
        eth_phy.carrier_sense_tx_fd_detect(1);
6848
        eth_phy.collision(1);
6849
      end
6850
      endcase
6851
      #1;
6852
      // first destination address on ethernet PHY
6853
      eth_phy.set_tx_mem_addr(num_of_frames * 16);
6854
      // SET packets and wrap bit
6855
      // num_of_frames <= 9 => wrap set to TX BD 0
6856
      if (num_of_frames <= 9)
6857
      begin
6858
        tmp_len = i_length; // length of frame
6859
        tmp_bd_num = 0; // TX BD number
6860
        // if i_length[1] == 0 then enable interrupt generation otherwise disable it
6861
        // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
6862
        if (tmp_len[0] == 0)
6863
          set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
6864
        else
6865
          set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
6866
        // set wrap bit
6867
        set_tx_bd_wrap(0);
6868
      end
6869
      // 10 <= num_of_frames < 18 => wrap set to TX BD 3
6870
      else if ((num_of_frames == 10) || (num_of_frames == 14))
6871
      begin
6872
        tmp_len = i_length; // length of frame
6873
        tmp_bd_num = 0; // TX BD number
6874
        while (tmp_bd_num < 4) //
6875
        begin
6876
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
6877
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
6878
          if (tmp_len[0] == 0)
6879
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
6880
          else
6881
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
6882
          tmp_len = tmp_len + 1;
6883
          // set TX BD number
6884
          tmp_bd_num = tmp_bd_num + 1;
6885
        end
6886
        // set wrap bit
6887
        set_tx_bd_wrap(3);
6888
      end
6889
      // 18 <= num_of_frames < 28 => wrap set to TX BD 4
6890
      else if ((num_of_frames == 18) || (num_of_frames == 23))
6891
      begin
6892
        tmp_len = i_length; // length of frame
6893
        tmp_bd_num = 0; // TX BD number
6894
        while (tmp_bd_num < 5) //
6895
        begin
6896
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
6897
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
6898
          if (tmp_len[0] == 0)
6899
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
6900
          else
6901
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
6902
          tmp_len = tmp_len + 1;
6903
          // set TX BD number
6904
          tmp_bd_num = tmp_bd_num + 1;
6905
        end
6906
        // set wrap bit
6907
        set_tx_bd_wrap(4);
6908
      end
6909
      // 28 <= num_of_frames < 40 => wrap set to TX BD 5
6910
      else if ((num_of_frames == 28) || (num_of_frames == 34))
6911
      begin
6912
        tmp_len = i_length; // length of frame
6913
        tmp_bd_num = 0; // TX BD number
6914
        while (tmp_bd_num < 6) //
6915
        begin
6916
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
6917
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
6918
          if (tmp_len[0] == 0)
6919
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
6920
          else
6921
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
6922
          tmp_len = tmp_len + 1;
6923
          // set TX BD number
6924
          tmp_bd_num = tmp_bd_num + 1;
6925
        end
6926
        // set wrap bit
6927
        set_tx_bd_wrap(5);
6928
      end
6929
      // 40 <= num_of_frames < 54 => wrap set to TX BD 6
6930
      else if ((num_of_frames == 40) || (num_of_frames == 47))
6931
      begin
6932
        tmp_len = i_length; // length of frame
6933
        tmp_bd_num = 0; // TX BD number
6934
        while (tmp_bd_num < 7) //
6935
        begin
6936
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
6937
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
6938
          if (tmp_len[0] == 0)
6939
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
6940
          else
6941
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
6942
          tmp_len = tmp_len + 1;
6943
          // set TX BD number
6944
          tmp_bd_num = tmp_bd_num + 1;
6945
        end
6946
        // set wrap bit
6947
        set_tx_bd_wrap(6);
6948
      end
6949
      // 54 <= num_of_frames < 70 => wrap set to TX BD 7
6950
      else if ((num_of_frames == 54) || (num_of_frames == 62))
6951
      begin
6952
        tmp_len = i_length; // length of frame
6953
        tmp_bd_num = 0; // TX BD number
6954
        while (tmp_bd_num < 8) //
6955
        begin
6956
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
6957
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
6958
          if (tmp_len[0] == 0)
6959
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
6960
          else
6961
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
6962
          tmp_len = tmp_len + 1;
6963
          // set TX BD number
6964
          tmp_bd_num = tmp_bd_num + 1;
6965
        end
6966
        // set wrap bit
6967
        set_tx_bd_wrap(7);
6968
      end
6969
      #1;
6970
      // SET ready bit
6971
      if (num_of_frames < 10)
6972
        set_tx_bd_ready(0, 0);
6973
      else if (num_of_frames < 14)
6974
        set_tx_bd_ready((num_of_frames - 10), (num_of_frames - 10));
6975
      else if (num_of_frames < 18)
6976
        set_tx_bd_ready((num_of_frames - 14), (num_of_frames - 14));
6977
      else if (num_of_frames < 23)
6978
        set_tx_bd_ready((num_of_frames - 18), (num_of_frames - 18));
6979
      else if (num_of_frames < 28)
6980
        set_tx_bd_ready((num_of_frames - 23), (num_of_frames - 23));
6981
      else if (num_of_frames < 34)
6982
        set_tx_bd_ready((num_of_frames - 28), (num_of_frames - 28));
6983
      else if (num_of_frames < 40)
6984
        set_tx_bd_ready((num_of_frames - 34), (num_of_frames - 34));
6985
      else if (num_of_frames < 47)
6986
        set_tx_bd_ready((num_of_frames - 40), (num_of_frames - 40));
6987
      else if (num_of_frames < 54)
6988
        set_tx_bd_ready((num_of_frames - 47), (num_of_frames - 47));
6989
      else if (num_of_frames < 62)
6990
        set_tx_bd_ready((num_of_frames - 54), (num_of_frames - 54));
6991
      else if (num_of_frames < 70)
6992
        set_tx_bd_ready((num_of_frames - 62), (num_of_frames - 62));
6993
      // CHECK END OF TRANSMITION
6994
      frame_started = 0;
6995
      if (num_of_frames >= 5)
6996
        #1 check_tx_bd(num_of_bd, data);
6997
      fork
6998
      begin: fr_st2
6999
        wait (MTxEn === 1'b1); // start transmit
7000
        frame_started = 1;
7001
      end
7002
      begin
7003
        repeat (30) @(posedge mtx_clk);
7004
        if (num_of_frames < 5)
7005
        begin
7006
          if (frame_started == 1)
7007
          begin
7008
            `TIME; $display("*E Frame should NOT start!");
7009
          end
7010
          disable fr_st2;
7011
        end
7012
        else
7013
        begin
7014
          if (frame_started == 0)
7015
          begin
7016
            `TIME; $display("*W Frame should start!");
7017
            disable fr_st2;
7018
          end
7019
        end
7020
      end
7021
      join
7022
      // check packets larger than 4 bytes
7023
      if (num_of_frames >= 5)
7024
      begin
7025
        wait (MTxEn === 1'b0); // end transmit
7026
        while (data[15] === 1)
7027
        begin
7028
          #1 check_tx_bd(num_of_bd, data);
7029
          @(posedge wb_clk);
7030
        end
7031
        repeat (1) @(posedge wb_clk);
7032
        // check length of a PACKET
7033
        if (eth_phy.tx_len != (i_length + 4))
7034
        begin
7035
          `TIME; $display("*E Wrong length of the packet out from MAC");
7036
          test_fail("Wrong length of the packet out from MAC");
7037
          fail = fail + 1;
7038
        end
7039
        // check transmitted TX packet data
7040
        if (i_length[0] == 0)
7041
        begin
7042
          #1 check_tx_packet(`MEMORY_BASE, (num_of_frames * 16), i_length, tmp);
7043
        end
7044
        else
7045
        begin
7046
          #1 check_tx_packet((`MEMORY_BASE + max_tmp), (num_of_frames * 16), i_length, tmp);
7047
        end
7048
        if (tmp > 0)
7049
        begin
7050
          test_fail("Wrong data of the transmitted packet");
7051
          fail = fail + 1;
7052
        end
7053
        // check transmited TX packet CRC
7054
        #1 check_tx_crc((num_of_frames * 16), (eth_phy.tx_len - 4), 1'b0, tmp); // length without CRC
7055
        if (tmp > 0)
7056
        begin
7057
          test_fail("Wrong CRC of the transmitted packet");
7058
          fail = fail + 1;
7059
        end
7060
      end
7061
      // check WB INT signal
7062
      if ((i_length[1:0] == 2'h0) && (num_of_frames >= 5))
7063
      begin
7064
        if (wb_int !== 1'b1)
7065
        begin
7066
          `TIME; $display("*E WB INT signal should be set");
7067
          test_fail("WB INT signal should be set");
7068
          fail = fail + 1;
7069
        end
7070
      end
7071
      else
7072
      begin
7073
        if (wb_int !== 1'b0)
7074
        begin
7075
          `TIME; $display("*E WB INT signal should not be set");
7076
          test_fail("WB INT signal should not be set");
7077
          fail = fail + 1;
7078
        end
7079
      end
7080
      // check TX buffer descriptor of a packet
7081
      check_tx_bd(num_of_bd, data);
7082
      if (num_of_frames >= 5)
7083
      begin
7084
        if (i_length[1] == 1'b0) // interrupt enabled
7085
        begin
7086
          if ( (data[15:0] !== 16'h7800) && // wrap bit
7087
               (data[15:0] !== 16'h5800) ) // without wrap bit
7088
          begin
7089
            `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
7090
            test_fail("TX buffer descriptor status is not correct");
7091
            fail = fail + 1;
7092
          end
7093
        end
7094
        else // interrupt not enabled
7095
        begin
7096
          if ( (data[15:0] !== 16'h3800) && // wrap bit
7097
               (data[15:0] !== 16'h1800) ) // without wrap bit
7098
          begin
7099
            `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
7100
            test_fail("TX buffer descriptor status is not correct");
7101
            fail = fail + 1;
7102
          end
7103
        end
7104
      end
7105
      else
7106
      begin
7107
        if (data[15] !== 1'b1)
7108
        begin
7109
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
7110
          test_fail("TX buffer descriptor status is not correct");
7111
          fail = fail + 1;
7112
        end
7113
      end
7114
      // clear TX BD with wrap bit
7115
      if (num_of_frames == 63)
7116
        clear_tx_bd(16, 16);
7117
      // check interrupts
7118
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7119
      if ( ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1)) && (num_of_frames >= 5) )
7120
      begin
7121
        if ((data & `ETH_INT_TXB) !== 1'b1)
7122
        begin
7123
          `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
7124
          test_fail("Interrupt Transmit Buffer was not set");
7125
          fail = fail + 1;
7126
        end
7127
        if ((data & (~`ETH_INT_TXB)) !== 0)
7128
        begin
7129
          `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
7130
          test_fail("Other interrupts (except Transmit Buffer) were set");
7131
          fail = fail + 1;
7132
        end
7133
      end
7134
      else
7135
      begin
7136
        if (data !== 0)
7137
        begin
7138
          `TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]);
7139
          test_fail("Any of interrupts (except Transmit Buffer) was set");
7140
          fail = fail + 1;
7141
        end
7142
      end
7143
      // clear interrupts
7144
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7145
      // check WB INT signal
7146
      if (wb_int !== 1'b0)
7147
      begin
7148
        test_fail("WB INT signal should not be set");
7149
        fail = fail + 1;
7150
      end
7151
      // INTERMEDIATE DISPLAYS
7152
      if (i_length == 3)
7153
      begin
7154
        $display("    pads appending to packets is selected");
7155
        $display("    using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)");
7156
        $display("    ->packets with lengths from %0d to %0d are not transmitted (length increasing by 1 byte)",
7157
                 0, 3);
7158
      end
7159
      else if (i_length == 9)
7160
      begin
7161
        $display("    using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)");
7162
        $display("    ->packet with length 4 is not transmitted (length increasing by 1 byte)");
7163
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
7164
                 5, 9);
7165
      end
7166
      else if (i_length == 17)
7167
      begin
7168
        $display("    using 4 BDs out of 8 BDs assigned to TX (wrap at 4th BD - TX BD 3)");
7169
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
7170
                 10, 17);
7171
      end
7172
      else if (i_length == 27)
7173
      begin
7174
        $display("    using 5 BDs out of 8 BDs assigned to TX (wrap at 5th BD - TX BD 4)");
7175
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
7176
                 18, 27);
7177
      end
7178
      else if (i_length == 40)
7179
      begin
7180
        $display("    using 6 BDs out of 8 BDs assigned to TX (wrap at 6th BD - TX BD 5)");
7181
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
7182
                 28, 40);
7183
      end
7184
      else if (i_length == 54)
7185
      begin
7186
        $display("    using 7 BDs out of 8 BDs assigned to TX (wrap at 7th BD - TX BD 6)");
7187
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
7188
                 41, 54);
7189
      end
7190
      else if (i_length == 69)
7191
      begin
7192
        $display("    using 8 BDs out of 8 BDs assigned to TX (wrap at 8th BD - TX BD 7)");
7193
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
7194
                 55, 69);
7195
      end
7196
      // set length (loop variable)
7197
      i_length = i_length + 1;
7198
      // the number of frame transmitted
7199
      num_of_frames = num_of_frames + 1;
7200
      if (/*(num_of_frames == 2) || (num_of_frames == 4) || (num_of_frames == 7) ||*/ (num_of_frames <= 10) ||
7201
          (num_of_frames == 14) || (num_of_frames == 18) || (num_of_frames == 23) || (num_of_frames == 28) ||
7202
          (num_of_frames == 34) || (num_of_frames == 40) || (num_of_frames == 47) ||
7203
          (num_of_frames == 54) || (num_of_frames == 62))
7204
        num_of_bd = 0;
7205
      else
7206
        num_of_bd = num_of_bd + 1;
7207
    end
7208
    // disable TX
7209
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
7210
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7211
    @(posedge wb_clk);
7212
    if(fail == 0)
7213
      test_ok;
7214
    else
7215
      fail = 0;
7216
  end
7217
 
7218
 
7219
  ////////////////////////////////////////////////////////////////////
7220
  ////                                                            ////
7221
  ////  Test no transmit packets (no pads) form 0 to (MINFL - 1)  ////
7222
  ////  sizes at 8 TX buffer decriptors ( 100Mbps ).              ////
7223
  ////                                                            ////
7224
  ////////////////////////////////////////////////////////////////////
7225
  if (test_num == 9) // 
7226
  begin
7227
    // TEST 9: NO TRANSMIT PACKETS (NO PADs) FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 100Mbps )
7228
    test_name = "TEST 9: NO TRANSMIT PACKETS (NO PADs) FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 100Mbps )";
7229
    `TIME; $display("  TEST 9: NO TRANSMIT PACKETS (NO PADs) FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 100Mbps )");
7230
 
7231
    // reset MAC registers
7232
    hard_reset;
7233
    // reset MAC and MII LOGIC with soft reset
7234
    reset_mac;
7235
    reset_mii;
7236
    // set wb slave response
7237
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
7238
 
7239
    max_tmp = 0;
7240
    min_tmp = 0;
7241
    // set 8 TX buffer descriptors - must be set before TX enable
7242
    wbm_write(`ETH_TX_BD_NUM, 32'h8, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7243
    // enable TX, set full-duplex mode, padding and CRC appending
7244
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_PAD | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
7245
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7246
    // prepare two packets of MAXFL length
7247
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7248
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
7249
    min_tmp = tmp[31:16];
7250
    st_data = 8'h12;
7251
    set_tx_packet(`MEMORY_BASE, (max_tmp - 4), st_data); // length without CRC
7252
    st_data = 8'h34;
7253
    set_tx_packet((`MEMORY_BASE + max_tmp), (max_tmp - 4), st_data); // length without CRC
7254
    // check WB INT signal
7255
    if (wb_int !== 1'b0)
7256
    begin
7257
      test_fail("WB INT signal should not be set");
7258
      fail = fail + 1;
7259
    end
7260
 
7261
    // write to phy's control register for 100Mbps
7262
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
7263
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
7264
    speed = 100;
7265
 
7266
    frame_started = 0;
7267
    num_of_frames = 0;
7268
    num_of_bd = 0;
7269
    i_length = 0; // 0;
7270
    while (i_length < 70) // (min_tmp - 4))
7271
    begin
7272
      #1;
7273
      // choose generating carrier sense and collision
7274
      case (i_length[1:0])
7275
      2'h0: // Interrupt is generated
7276
      begin
7277
        // Reset_tx_bd nable interrupt generation
7278
        // unmask interrupts
7279
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
7280
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7281
        // not detect carrier sense in FD and no collision
7282
        eth_phy.carrier_sense_tx_fd_detect(0);
7283
        eth_phy.collision(0);
7284
      end
7285
      2'h1: // Interrupt is not generated
7286
      begin
7287
        // set_tx_bd enable interrupt generation
7288
        // mask interrupts
7289
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7290
        // detect carrier sense in FD and no collision
7291
        eth_phy.carrier_sense_tx_fd_detect(1);
7292
        eth_phy.collision(0);
7293
      end
7294
      2'h2: // Interrupt is not generated
7295
      begin
7296
        // set_tx_bd disable the interrupt generation
7297
        // unmask interrupts
7298
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
7299
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7300
        // not detect carrier sense in FD and set collision
7301
        eth_phy.carrier_sense_tx_fd_detect(0);
7302
        eth_phy.collision(1);
7303
      end
7304
      default: // 2'h3: // Interrupt is not generated
7305
      begin
7306
        // set_tx_bd disable the interrupt generation
7307
        // mask interrupts
7308
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7309
        // detect carrier sense in FD and set collision
7310
        eth_phy.carrier_sense_tx_fd_detect(1);
7311
        eth_phy.collision(1);
7312
      end
7313
      endcase
7314
      #1;
7315
      // first destination address on ethernet PHY
7316
      eth_phy.set_tx_mem_addr(num_of_frames * 16);
7317
      // SET packets and wrap bit
7318
      // num_of_frames <= 9 => wrap set to TX BD 0
7319
      if (num_of_frames <= 9)
7320
      begin
7321
        tmp_len = i_length; // length of frame
7322
        tmp_bd_num = 0; // TX BD number
7323
        // if i_length[1] == 0 then enable interrupt generation otherwise disable it
7324
        // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
7325
        if (tmp_len[0] == 0)
7326
          set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
7327
        else
7328
          set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
7329
        // set wrap bit
7330
        set_tx_bd_wrap(0);
7331
      end
7332
      // 10 <= num_of_frames < 18 => wrap set to TX BD 3
7333
      else if ((num_of_frames == 10) || (num_of_frames == 14))
7334
      begin
7335
        tmp_len = i_length; // length of frame
7336
        tmp_bd_num = 0; // TX BD number
7337
        while (tmp_bd_num < 4) //
7338
        begin
7339
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
7340
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
7341
          if (tmp_len[0] == 0)
7342
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
7343
          else
7344
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
7345
          tmp_len = tmp_len + 1;
7346
          // set TX BD number
7347
          tmp_bd_num = tmp_bd_num + 1;
7348
        end
7349
        // set wrap bit
7350
        set_tx_bd_wrap(3);
7351
      end
7352
      // 18 <= num_of_frames < 28 => wrap set to TX BD 4
7353
      else if ((num_of_frames == 18) || (num_of_frames == 23))
7354
      begin
7355
        tmp_len = i_length; // length of frame
7356
        tmp_bd_num = 0; // TX BD number
7357
        while (tmp_bd_num < 5) //
7358
        begin
7359
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
7360
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
7361
          if (tmp_len[0] == 0)
7362
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
7363
          else
7364
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
7365
          tmp_len = tmp_len + 1;
7366
          // set TX BD number
7367
          tmp_bd_num = tmp_bd_num + 1;
7368
        end
7369
        // set wrap bit
7370
        set_tx_bd_wrap(4);
7371
      end
7372
      // 28 <= num_of_frames < 40 => wrap set to TX BD 5
7373
      else if ((num_of_frames == 28) || (num_of_frames == 34))
7374
      begin
7375
        tmp_len = i_length; // length of frame
7376
        tmp_bd_num = 0; // TX BD number
7377
        while (tmp_bd_num < 6) //
7378
        begin
7379
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
7380
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
7381
          if (tmp_len[0] == 0)
7382
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
7383
          else
7384
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
7385
          tmp_len = tmp_len + 1;
7386
          // set TX BD number
7387
          tmp_bd_num = tmp_bd_num + 1;
7388
        end
7389
        // set wrap bit
7390
        set_tx_bd_wrap(5);
7391
      end
7392
      // 40 <= num_of_frames < 54 => wrap set to TX BD 6
7393
      else if ((num_of_frames == 40) || (num_of_frames == 47))
7394
      begin
7395
        tmp_len = i_length; // length of frame
7396
        tmp_bd_num = 0; // TX BD number
7397
        while (tmp_bd_num < 7) //
7398
        begin
7399
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
7400
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
7401
          if (tmp_len[0] == 0)
7402
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
7403
          else
7404
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
7405
          tmp_len = tmp_len + 1;
7406
          // set TX BD number
7407
          tmp_bd_num = tmp_bd_num + 1;
7408
        end
7409
        // set wrap bit
7410
        set_tx_bd_wrap(6);
7411
      end
7412
      // 54 <= num_of_frames < 70 => wrap set to TX BD 7
7413
      else if ((num_of_frames == 54) || (num_of_frames == 62))
7414
      begin
7415
        tmp_len = i_length; // length of frame
7416
        tmp_bd_num = 0; // TX BD number
7417
        while (tmp_bd_num < 8) //
7418
        begin
7419
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
7420
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
7421
          if (tmp_len[0] == 0)
7422
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
7423
          else
7424
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
7425
          tmp_len = tmp_len + 1;
7426
          // set TX BD number
7427
          tmp_bd_num = tmp_bd_num + 1;
7428
        end
7429
        // set wrap bit
7430
        set_tx_bd_wrap(7);
7431
      end
7432
      #1;
7433
      // SET ready bit
7434
      if (num_of_frames < 10)
7435
        set_tx_bd_ready(0, 0);
7436
      else if (num_of_frames < 14)
7437
        set_tx_bd_ready((num_of_frames - 10), (num_of_frames - 10));
7438
      else if (num_of_frames < 18)
7439
        set_tx_bd_ready((num_of_frames - 14), (num_of_frames - 14));
7440
      else if (num_of_frames < 23)
7441
        set_tx_bd_ready((num_of_frames - 18), (num_of_frames - 18));
7442
      else if (num_of_frames < 28)
7443
        set_tx_bd_ready((num_of_frames - 23), (num_of_frames - 23));
7444
      else if (num_of_frames < 34)
7445
        set_tx_bd_ready((num_of_frames - 28), (num_of_frames - 28));
7446
      else if (num_of_frames < 40)
7447
        set_tx_bd_ready((num_of_frames - 34), (num_of_frames - 34));
7448
      else if (num_of_frames < 47)
7449
        set_tx_bd_ready((num_of_frames - 40), (num_of_frames - 40));
7450
      else if (num_of_frames < 54)
7451
        set_tx_bd_ready((num_of_frames - 47), (num_of_frames - 47));
7452
      else if (num_of_frames < 62)
7453
        set_tx_bd_ready((num_of_frames - 54), (num_of_frames - 54));
7454
      else if (num_of_frames < 70)
7455
        set_tx_bd_ready((num_of_frames - 62), (num_of_frames - 62));
7456
      // CHECK END OF TRANSMITION
7457
      frame_started = 0;
7458
      if (num_of_frames >= 5)
7459
        #1 check_tx_bd(num_of_bd, data);
7460
      fork
7461
      begin: fr_st3
7462
        wait (MTxEn === 1'b1); // start transmit
7463
        frame_started = 1;
7464
      end
7465
      begin
7466
        repeat (30) @(posedge mtx_clk);
7467
        if (num_of_frames < 5)
7468
        begin
7469
          if (frame_started == 1)
7470
          begin
7471
            `TIME; $display("*E Frame should NOT start!");
7472
          end
7473
          disable fr_st3;
7474
        end
7475
        else
7476
        begin
7477
          if (frame_started == 0)
7478
          begin
7479
            `TIME; $display("*W Frame should start!");
7480
            disable fr_st3;
7481
          end
7482
        end
7483
      end
7484
      join
7485
      // check packets larger than 4 bytes
7486
      if (num_of_frames >= 5)
7487
      begin
7488
        wait (MTxEn === 1'b0); // end transmit
7489
        while (data[15] === 1)
7490
        begin
7491
          #1 check_tx_bd(num_of_bd, data);
7492
          @(posedge wb_clk);
7493
        end
7494
        repeat (1) @(posedge wb_clk);
7495
        // check length of a PACKET
7496
        if (eth_phy.tx_len != (i_length + 4))
7497
        begin
7498
          `TIME; $display("*E Wrong length of the packet out from MAC");
7499
          test_fail("Wrong length of the packet out from MAC");
7500
          fail = fail + 1;
7501
        end
7502
        // check transmitted TX packet data
7503
        if (i_length[0] == 0)
7504
        begin
7505
          #1 check_tx_packet(`MEMORY_BASE, (num_of_frames * 16), i_length, tmp);
7506
        end
7507
        else
7508
        begin
7509
          #1 check_tx_packet((`MEMORY_BASE + max_tmp), (num_of_frames * 16), i_length, tmp);
7510
        end
7511
        if (tmp > 0)
7512
        begin
7513
          test_fail("Wrong data of the transmitted packet");
7514
          fail = fail + 1;
7515
        end
7516
        // check transmited TX packet CRC
7517
        #1 check_tx_crc((num_of_frames * 16), (eth_phy.tx_len - 4), 1'b0, tmp); // length without CRC
7518
        if (tmp > 0)
7519
        begin
7520
          test_fail("Wrong CRC of the transmitted packet");
7521
          fail = fail + 1;
7522
        end
7523
      end
7524
      // check WB INT signal
7525
      if ((i_length[1:0] == 2'h0) && (num_of_frames >= 5))
7526
      begin
7527
        if (wb_int !== 1'b1)
7528
        begin
7529
          `TIME; $display("*E WB INT signal should be set");
7530
          test_fail("WB INT signal should be set");
7531
          fail = fail + 1;
7532
        end
7533
      end
7534
      else
7535
      begin
7536
        if (wb_int !== 1'b0)
7537
        begin
7538
          `TIME; $display("*E WB INT signal should not be set");
7539
          test_fail("WB INT signal should not be set");
7540
          fail = fail + 1;
7541
        end
7542
      end
7543
      // check TX buffer descriptor of a packet
7544
      check_tx_bd(num_of_bd, data);
7545
      if (num_of_frames >= 5)
7546
      begin
7547
        if (i_length[1] == 1'b0) // interrupt enabled
7548
        begin
7549
          if ( (data[15:0] !== 16'h7800) && // wrap bit
7550
               (data[15:0] !== 16'h5800) ) // without wrap bit
7551
          begin
7552
            `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
7553
            test_fail("TX buffer descriptor status is not correct");
7554
            fail = fail + 1;
7555
          end
7556
        end
7557
        else // interrupt not enabled
7558
        begin
7559
          if ( (data[15:0] !== 16'h3800) && // wrap bit
7560
               (data[15:0] !== 16'h1800) ) // without wrap bit
7561
          begin
7562
            `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
7563
            test_fail("TX buffer descriptor status is not correct");
7564
            fail = fail + 1;
7565
          end
7566
        end
7567
      end
7568
      else
7569
      begin
7570
        if (data[15] !== 1'b1)
7571
        begin
7572
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
7573
          test_fail("TX buffer descriptor status is not correct");
7574
          fail = fail + 1;
7575
        end
7576
      end
7577
      // clear TX BD with wrap bit
7578
      if (num_of_frames == 63)
7579
        clear_tx_bd(16, 16);
7580
      // check interrupts
7581
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7582
      if ( ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1)) && (num_of_frames >= 5) )
7583
      begin
7584
        if ((data & `ETH_INT_TXB) !== 1'b1)
7585
        begin
7586
          `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
7587
          test_fail("Interrupt Transmit Buffer was not set");
7588
          fail = fail + 1;
7589
        end
7590
        if ((data & (~`ETH_INT_TXB)) !== 0)
7591
        begin
7592
          `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
7593
          test_fail("Other interrupts (except Transmit Buffer) were set");
7594
          fail = fail + 1;
7595
        end
7596
      end
7597
      else
7598
      begin
7599
        if (data !== 0)
7600
        begin
7601
          `TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]);
7602
          test_fail("Any of interrupts (except Transmit Buffer) was set");
7603
          fail = fail + 1;
7604
        end
7605
      end
7606
      // clear interrupts
7607
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7608
      // check WB INT signal
7609
      if (wb_int !== 1'b0)
7610
      begin
7611
        test_fail("WB INT signal should not be set");
7612
        fail = fail + 1;
7613
      end
7614
      // INTERMEDIATE DISPLAYS
7615
      if (i_length == 3)
7616
      begin
7617
        $display("    pads appending to packets is selected");
7618
        $display("    using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)");
7619
        $display("    ->packets with lengths from %0d to %0d are not transmitted (length increasing by 1 byte)",
7620
                 0, 3);
7621
      end
7622
      else if (i_length == 9)
7623
      begin
7624
        $display("    using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)");
7625
        $display("    ->packet with length 4 is not transmitted (length increasing by 1 byte)");
7626
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
7627
                 5, 9);
7628
      end
7629
      else if (i_length == 17)
7630
      begin
7631
        $display("    using 4 BDs out of 8 BDs assigned to TX (wrap at 4th BD - TX BD 3)");
7632
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
7633
                 10, 17);
7634
      end
7635
      else if (i_length == 27)
7636
      begin
7637
        $display("    using 5 BDs out of 8 BDs assigned to TX (wrap at 5th BD - TX BD 4)");
7638
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
7639
                 18, 27);
7640
      end
7641
      else if (i_length == 40)
7642
      begin
7643
        $display("    using 6 BDs out of 8 BDs assigned to TX (wrap at 6th BD - TX BD 5)");
7644
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
7645
                 28, 40);
7646
      end
7647
      else if (i_length == 54)
7648
      begin
7649
        $display("    using 7 BDs out of 8 BDs assigned to TX (wrap at 7th BD - TX BD 6)");
7650
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
7651
                 41, 54);
7652
      end
7653
      else if (i_length == 69)
7654
      begin
7655
        $display("    using 8 BDs out of 8 BDs assigned to TX (wrap at 8th BD - TX BD 7)");
7656
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
7657
                 55, 69);
7658
      end
7659
      // set length (loop variable)
7660
      i_length = i_length + 1;
7661
      // the number of frame transmitted
7662
      num_of_frames = num_of_frames + 1;
7663
      if (/*(num_of_frames == 2) || (num_of_frames == 4) || (num_of_frames == 7) ||*/ (num_of_frames <= 10) ||
7664
          (num_of_frames == 14) || (num_of_frames == 18) || (num_of_frames == 23) || (num_of_frames == 28) ||
7665
          (num_of_frames == 34) || (num_of_frames == 40) || (num_of_frames == 47) ||
7666
          (num_of_frames == 54) || (num_of_frames == 62))
7667
        num_of_bd = 0;
7668
      else
7669
        num_of_bd = num_of_bd + 1;
7670
    end
7671
    // disable TX
7672
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
7673
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7674
    @(posedge wb_clk);
7675
    if(fail == 0)
7676
      test_ok;
7677
    else
7678
      fail = 0;
7679
  end
7680
 
7681
 
7682
  ////////////////////////////////////////////////////////////////////
7683
  ////                                                            ////
7684
  ////  Test transmit packets across MAXFL value at               ////
7685
  ////  13 TX buffer decriptors ( 10Mbps ).                       ////
7686
  ////                                                            ////
7687
  ////////////////////////////////////////////////////////////////////
7688
  if (test_num == 10) // without and with padding
7689
  begin
7690
    // TEST 10: TRANSMIT PACKETS ACROSS MAXFL VALUE AT 13 TX BDs ( 10Mbps )
7691
    test_name = "TEST 10: TRANSMIT PACKETS ACROSS MAXFL VALUE AT 13 TX BDs ( 10Mbps )";
7692
    `TIME; $display("  TEST 10: TRANSMIT PACKETS ACROSS MAXFL VALUE AT 13 TX BDs ( 10Mbps )");
7693
 
7694
    // reset MAC registers
7695
    hard_reset;
7696
    // reset MAC and MII LOGIC with soft reset
7697
    reset_mac;
7698
    reset_mii;
7699
    // set wb slave response
7700
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
7701
 
7702
    max_tmp = 0;
7703
    min_tmp = 0;
7704
    num_of_frames = 0;
7705
    num_of_bd = 0;
7706
    // set 13 TX buffer descriptors - must be set before TX enable
7707
    wbm_write(`ETH_TX_BD_NUM, 32'hD, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7708
    // enable TX, set full-duplex mode, NO padding and CRC appending
7709
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
7710
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7711
    // prepare a packet of MAXFL + 10 length
7712
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7713
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
7714
    min_tmp = tmp[31:16];
7715
    st_data = 8'hA3;
7716
    set_tx_packet(`MEMORY_BASE, (max_tmp + 10), st_data); // length without CRC
7717
    // check WB INT signal
7718
    if (wb_int !== 1'b0)
7719
    begin
7720
      test_fail("WB INT signal should not be set");
7721
      fail = fail + 1;
7722
    end
7723
 
7724
    // write to phy's control register for 10Mbps
7725
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
7726
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
7727
    speed = 10;
7728
 
7729
    i_length = (max_tmp - 5);
7730
    while (i_length <= (max_tmp - 3)) // (max_tmp - 4) is the limit
7731
    begin
7732
$display("   i_length = %0d", i_length);
7733
      // choose generating carrier sense and collision
7734
//      case (i_length[1:0])
7735
//      2'h0: // Interrupt is generated
7736
//      begin
7737
        // Reset_tx_bd nable interrupt generation
7738
        // unmask interrupts
7739
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
7740
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7741
        // not detect carrier sense in FD and no collision
7742
        eth_phy.carrier_sense_tx_fd_detect(0);
7743
        eth_phy.collision(0);
7744
//      end
7745
//      2'h1: // Interrupt is not generated
7746
//      begin
7747
        // set_tx_bd enable interrupt generation
7748
        // mask interrupts
7749
//        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7750
        // detect carrier sense in FD and no collision
7751
//        eth_phy.carrier_sense_tx_fd_detect(1);
7752
//        eth_phy.collision(0);
7753
//      end
7754
//      2'h2: // Interrupt is not generated
7755
//      begin
7756
        // set_tx_bd disable the interrupt generation
7757
        // unmask interrupts
7758
//        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
7759
//                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7760
        // not detect carrier sense in FD and set collision
7761
//        eth_phy.carrier_sense_tx_fd_detect(0);
7762
//        eth_phy.collision(1);
7763
//      end
7764
//      default: // 2'h3: // Interrupt is not generated
7765
//      begin
7766
        // set_tx_bd disable the interrupt generation
7767
        // mask interrupts
7768
//        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7769
        // detect carrier sense in FD and set collision
7770
//        eth_phy.carrier_sense_tx_fd_detect(1);
7771
//        eth_phy.collision(1);
7772
//      end
7773
//      endcase
7774
      // first destination address on ethernet PHY
7775
      eth_phy.set_tx_mem_addr(0);
7776
      // 
7777
if (num_of_bd == 0)
7778
begin
7779
set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
7780
set_tx_bd(1, 1, i_length+1, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
7781
set_tx_bd(2, 2, i_length+2, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
7782
set_tx_bd_wrap(2);
7783
set_tx_bd_ready(0, 0);
7784
end
7785
else if (num_of_bd == 1)
7786
set_tx_bd_ready(1, 1);
7787
else if (num_of_bd == 2)
7788
set_tx_bd_ready(2, 2);
7789
 
7790
 
7791
//        tmp_len = i_length; // length of frame
7792
//        tmp_bd_num = 0; // TX BD number
7793
//        while (tmp_bd_num < 8) // 
7794
//        begin
7795
//          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
7796
//          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
7797
//          if (tmp_len[0] == 0)
7798
//            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
7799
//          else
7800
//            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + 2*max_tmp));
7801
//          // set length (loop variable) - THE SAME AS AT THE END OF THIS TASK !!!
7802
//          tmp_len = tmp_len + 1;
7803
//          // set TX BD number
7804
//          tmp_bd_num = tmp_bd_num + 1;
7805
//        end
7806
//        // set wrap bit
7807
//        set_tx_bd_wrap(7);
7808
//      // set ready bit
7809
//      set_tx_bd_ready((i_length - (max_tmp - 8)), (i_length - (max_tmp - 8)));
7810
      // CHECK END OF TRANSMITION
7811
check_tx_bd(num_of_bd, data);
7812
//      #1 check_tx_bd((i_length - (max_tmp - 8)), data);
7813
        wait (MTxEn === 1'b1); // start transmit
7814
check_tx_bd(num_of_bd, data);
7815
//        #1 check_tx_bd((i_length - (max_tmp - 8)), data);
7816
        if (data[15] !== 1)
7817
        begin
7818
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
7819
          fail = fail + 1;
7820
        end
7821
        wait (MTxEn === 1'b0); // end transmit
7822
        while (data[15] === 1)
7823
        begin
7824
check_tx_bd(num_of_bd, data);
7825
//          #1 check_tx_bd((i_length - (max_tmp - 8)), data);
7826
          @(posedge wb_clk);
7827
        end
7828
        repeat (1) @(posedge wb_clk);
7829
      // check length of a PACKET
7830
$display("   eth_phy length = %0d", eth_phy.tx_len);
7831
tmp_len = eth_phy.tx_len;
7832
#1;
7833
if (tmp_len != (i_length + 4))
7834
//      if (eth_phy.tx_len != (i_length + 4))
7835
      begin
7836
        test_fail("Wrong length of the packet out from MAC");
7837
        fail = fail + 1;
7838
      end
7839
      // checking in the following if statement is performed only for first and last 64 lengths
7840
//      if ( ((i_length + 4) <= (min_tmp + 64)) || ((i_length + 4) > (max_tmp - 64)) )
7841
//      begin
7842
        // check transmitted TX packet data
7843
//        if (i_length[0] == 0)
7844
//        begin
7845
          check_tx_packet(`MEMORY_BASE, 0, i_length, tmp);
7846
//        end
7847
//        else
7848
//        begin
7849
//          check_tx_packet((`MEMORY_BASE + 2*max_tmp), 0, i_length, tmp);
7850
//        end
7851
        if (tmp > 0)
7852
        begin
7853
          test_fail("Wrong data of the transmitted packet");
7854
          fail = fail + 1;
7855
        end
7856
        // check transmited TX packet CRC
7857
//        if (i_length[0] == 0)
7858
          check_tx_crc(0, i_length, 1'b0, tmp); // length without CRC
7859
//        else
7860
//          check_tx_crc(0, i_length, 1'b0, tmp); // length without CRC
7861
        if (tmp > 0)
7862
        begin
7863
          test_fail("Wrong CRC of the transmitted packet");
7864
          fail = fail + 1;
7865
        end
7866
//      end
7867
      // check WB INT signal
7868
//      if (i_length[1:0] == 2'h0)
7869
//      begin
7870
        if (wb_int !== 1'b1)
7871
        begin
7872
          `TIME; $display("*E WB INT signal should be set");
7873
          test_fail("WB INT signal should be set");
7874
          fail = fail + 1;
7875
        end
7876
//      end
7877
//      else
7878
//      begin
7879
//        if (wb_int !== 1'b0)
7880
//        begin
7881
//          `TIME; $display("*E WB INT signal should not be set");
7882
//          test_fail("WB INT signal should not be set");
7883
//          fail = fail + 1;
7884
//        end
7885
//      end
7886
//      // check TX buffer descriptor of a packet
7887
//      check_tx_bd((i_length - (max_tmp - 8)), data);
7888
check_tx_bd(num_of_bd, data);
7889
if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 2)) || // wrap bit
7890
     ((data[15:0] !== 16'h5800) && (num_of_bd < 2)) )   // without wrap bit
7891
//      if (i_length[1] == 1'b0) // interrupt enabled
7892
//      begin
7893
//        if ( ((data[15:0] !== 16'h7800) && ((num_of_frames < 8) || ((num_of_frames - 8) == 127))) || // wrap bit
7894
//             ((data[15:0] !== 16'h5800) && (num_of_frames >= 8) && ((num_of_frames - 8) != 127)) ) // without wrap bit
7895
        begin
7896
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
7897
          test_fail("TX buffer descriptor status is not correct");
7898
          fail = fail + 1;
7899
        end
7900
//      end
7901
//      else // interrupt not enabled
7902
//      begin
7903
//        if ( ((data[15:0] !== 16'h3800)  && ((num_of_frames < 8) || ((num_of_frames - 8) == 127))) || // wrap bit
7904
//             ((data[15:0] !== 16'h1800) && (num_of_frames >= 8) && ((num_of_frames - 8) != 127)) ) // without wrap bit
7905
//        begin
7906
//          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
7907
//          test_fail("TX buffer descriptor status is not correct");
7908
//          fail = fail + 1;
7909
//        end
7910
//      end
7911
//      // clear first half of 8 frames from TX buffer descriptor 0
7912
//      if (num_of_frames < 4)
7913
//        clear_tx_bd((i_length - (max_tmp - 8)), (i_length - (max_tmp - 8)));
7914
      // check interrupts
7915
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7916
//      if ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1))
7917
//      begin
7918
        if ((data & `ETH_INT_TXB) !== 1'b1)
7919
        begin
7920
          `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
7921
          test_fail("Interrupt Transmit Buffer was not set");
7922
          fail = fail + 1;
7923
        end
7924
        if ((data & (~`ETH_INT_TXB)) !== 0)
7925
        begin
7926
          `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
7927
          test_fail("Other interrupts (except Transmit Buffer) were set");
7928
          fail = fail + 1;
7929
        end
7930
//      end
7931
//      else
7932
//      begin
7933
//        if (data !== 0)
7934
//        begin
7935
//          `TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]);
7936
//          test_fail("Any of interrupts (except Transmit Buffer) was set");
7937
//          fail = fail + 1;
7938
//        end
7939
//      end
7940
      // clear interrupts
7941
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7942
      // check WB INT signal
7943
      if (wb_int !== 1'b0)
7944
      begin
7945
        test_fail("WB INT signal should not be set");
7946
        fail = fail + 1;
7947
      end
7948
      // INTERMEDIATE DISPLAYS
7949
if (num_of_bd == 0)
7950
  $display("    ->packet with length %0d sent", (i_length + 4));
7951
else if (num_of_bd == 1)
7952
  $display("    ->packet with length %0d sent", (i_length + 4));
7953
else if (num_of_bd == 2)
7954
  $display("    ->packet with length %0d sent", (i_length + 4));
7955
      // set length (loop variable)
7956
      i_length = i_length + 1;
7957
      // the number of frame transmitted
7958
      num_of_frames = num_of_frames + 1;
7959
      num_of_bd = num_of_bd + 1;
7960
      @(posedge wb_clk);
7961
    end
7962
    // disable TX
7963
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
7964
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7965
    @(posedge wb_clk);
7966
    if(fail == 0)
7967
      test_ok;
7968
    else
7969
      fail = 0;
7970
  end
7971
 
7972
 
7973
  ////////////////////////////////////////////////////////////////////
7974
  ////                                                            ////
7975
  ////  Test transmit packets across MAXFL value at               ////
7976
  ////  13 TX buffer decriptors ( 100Mbps ).                      ////
7977
  ////                                                            ////
7978
  ////////////////////////////////////////////////////////////////////
7979
  if (test_num == 11) // without and with padding
7980
  begin
7981
    // TEST 11: TRANSMIT PACKETS ACROSS MAXFL VALUE AT 13 TX BDs ( 100Mbps )
7982
    test_name = "TEST 11: TRANSMIT PACKETS ACROSS MAXFL VALUE AT 13 TX BDs ( 100Mbps )";
7983
    `TIME; $display("  TEST 11: TRANSMIT PACKETS ACROSS MAXFL VALUE AT 13 TX BDs ( 100Mbps )");
7984
 
7985
    // reset MAC registers
7986
    hard_reset;
7987
    // reset MAC and MII LOGIC with soft reset
7988
    reset_mac;
7989
    reset_mii;
7990
    // set wb slave response
7991
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
7992
 
7993
    max_tmp = 0;
7994
    min_tmp = 0;
7995
    num_of_frames = 0;
7996
    num_of_bd = 0;
7997
    // set 13 TX buffer descriptors - must be set before TX enable
7998
    wbm_write(`ETH_TX_BD_NUM, 32'hD, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7999
    // enable TX, set full-duplex mode, NO padding and CRC appending
8000
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
8001
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8002
    // prepare a packet of MAXFL + 10 length
8003
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8004
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
8005
    min_tmp = tmp[31:16];
8006
    st_data = 8'hA3;
8007
    set_tx_packet(`MEMORY_BASE, (max_tmp + 10), st_data); // length without CRC
8008
    // check WB INT signal
8009
    if (wb_int !== 1'b0)
8010
    begin
8011
      test_fail("WB INT signal should not be set");
8012
      fail = fail + 1;
8013
    end
8014
 
8015
    // write to phy's control register for 100Mbps
8016
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
8017
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
8018
    speed = 100;
8019
 
8020
    i_length = (max_tmp - 5);
8021
    while (i_length <= (max_tmp - 3)) // (max_tmp - 4) is the limit
8022
    begin
8023
      $display("   i_length = %0d", i_length);
8024
      // Reset_tx_bd nable interrupt generation
8025
      // unmask interrupts
8026
      wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
8027
                               `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8028
      // not detect carrier sense in FD and no collision
8029
      eth_phy.carrier_sense_tx_fd_detect(0);
8030
      eth_phy.collision(0);
8031
      // first destination address on ethernet PHY
8032
      eth_phy.set_tx_mem_addr(0);
8033
      // prepare BDs
8034
      if (num_of_bd == 0)
8035
      begin
8036
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8037
        set_tx_bd(1, 1, i_length+1, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8038
        set_tx_bd(2, 2, i_length+2, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8039
        set_tx_bd_wrap(2);
8040
        set_tx_bd_ready(0, 0);
8041
      end
8042
      else if (num_of_bd == 1)
8043
        set_tx_bd_ready(1, 1);
8044
      else if (num_of_bd == 2)
8045
        set_tx_bd_ready(2, 2);
8046
      // CHECK END OF TRANSMITION
8047
      check_tx_bd(num_of_bd, data);
8048
        wait (MTxEn === 1'b1); // start transmit
8049
      check_tx_bd(num_of_bd, data);
8050
        if (data[15] !== 1)
8051
        begin
8052
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
8053
          fail = fail + 1;
8054
        end
8055
        wait (MTxEn === 1'b0); // end transmit
8056
        while (data[15] === 1)
8057
        begin
8058
      check_tx_bd(num_of_bd, data);
8059
          @(posedge wb_clk);
8060
        end
8061
        repeat (1) @(posedge wb_clk);
8062
      // check length of a PACKET
8063
      $display("   eth_phy length = %0d", eth_phy.tx_len);
8064
      tmp_len = eth_phy.tx_len;
8065
      #1;
8066
      if (tmp_len != (i_length + 4))
8067
      begin
8068
        test_fail("Wrong length of the packet out from MAC");
8069
        fail = fail + 1;
8070
      end
8071
      // checking packet
8072
      check_tx_packet(`MEMORY_BASE, 0, i_length, tmp);
8073
      if (tmp > 0)
8074
      begin
8075
        test_fail("Wrong data of the transmitted packet");
8076
        fail = fail + 1;
8077
      end
8078
      // check transmited TX packet CRC
8079
      check_tx_crc(0, i_length, 1'b0, tmp); // length without CRC
8080
      if (tmp > 0)
8081
      begin
8082
        test_fail("Wrong CRC of the transmitted packet");
8083
        fail = fail + 1;
8084
      end
8085
      // check WB INT signal
8086
      if (wb_int !== 1'b1)
8087
      begin
8088
        `TIME; $display("*E WB INT signal should be set");
8089
        test_fail("WB INT signal should be set");
8090
        fail = fail + 1;
8091
      end
8092
      // check TX buffer descriptor of a packet
8093
      check_tx_bd(num_of_bd, data);
8094
      if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 2)) || // wrap bit
8095
           ((data[15:0] !== 16'h5800) && (num_of_bd < 2)) )   // without wrap bit
8096
      begin
8097
        `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
8098
        test_fail("TX buffer descriptor status is not correct");
8099
        fail = fail + 1;
8100
      end
8101
      // check interrupts
8102
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8103
      if ((data & `ETH_INT_TXB) !== 1'b1)
8104
      begin
8105
        `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
8106
        test_fail("Interrupt Transmit Buffer was not set");
8107
        fail = fail + 1;
8108
      end
8109
      if ((data & (~`ETH_INT_TXB)) !== 0)
8110
      begin
8111
        `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
8112
        test_fail("Other interrupts (except Transmit Buffer) were set");
8113
        fail = fail + 1;
8114
      end
8115
      // clear interrupts
8116
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8117
      // check WB INT signal
8118
      if (wb_int !== 1'b0)
8119
      begin
8120
        test_fail("WB INT signal should not be set");
8121
        fail = fail + 1;
8122
      end
8123
      // INTERMEDIATE DISPLAYS
8124
      if (num_of_bd == 0)
8125
        $display("    ->packet with length %0d sent", (i_length + 4));
8126
      else if (num_of_bd == 1)
8127
        $display("    ->packet with length %0d sent", (i_length + 4));
8128
      else if (num_of_bd == 2)
8129
        $display("    ->packet with length %0d sent", (i_length + 4));
8130
      // set length (loop variable)
8131
      i_length = i_length + 1;
8132
      // the number of frame transmitted
8133
      num_of_frames = num_of_frames + 1;
8134
      num_of_bd = num_of_bd + 1;
8135
      @(posedge wb_clk);
8136
    end
8137
    // disable TX
8138
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
8139
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8140
    @(posedge wb_clk);
8141
    if(fail == 0)
8142
      test_ok;
8143
    else
8144
      fail = 0;
8145
  end
8146
 
8147
 
8148
  ////////////////////////////////////////////////////////////////////
8149
  ////                                                            ////
8150
  ////  Test transmit packets across changed MAXFL value at       ////
8151
  ////  47 TX buffer decriptors ( 10Mbps ).                       ////
8152
  ////                                                            ////
8153
  ////////////////////////////////////////////////////////////////////
8154
  if (test_num == 12) // without and with padding
8155
  begin
8156
    // TEST 12: TRANSMIT PACKETS ACROSS CHANGED MAXFL VALUE AT 13 TX BDs ( 10Mbps )
8157
    test_name = "TEST 12: TRANSMIT PACKETS ACROSS CHANGED MAXFL VALUE AT 13 TX BDs ( 10Mbps )";
8158
    `TIME; $display("  TEST 12: TRANSMIT PACKETS ACROSS CHANGED MAXFL VALUE AT 13 TX BDs ( 10Mbps )");
8159
 
8160
    // reset MAC registers
8161
    hard_reset;
8162
    // reset MAC and MII LOGIC with soft reset
8163
    reset_mac;
8164
    reset_mii;
8165
    // set wb slave response
8166
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
8167
 
8168
    max_tmp = 0;
8169
    min_tmp = 0;
8170
    num_of_frames = 0;
8171
    num_of_bd = 0;
8172
    // set 47 TX buffer descriptors - must be set before TX enable
8173
    wbm_write(`ETH_TX_BD_NUM, 32'h2F, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8174
    // prepare a packet of MAXFL + 10 length
8175
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8176
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
8177
    min_tmp = tmp[31:16];
8178
    // change MAXFL value
8179
    max_tmp = min_tmp + 53;
8180
    wbm_write(`ETH_PACKETLEN, {min_tmp, max_tmp}, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8181
    st_data = 8'h62;
8182
    set_tx_packet(`MEMORY_BASE, max_tmp, st_data); // length with CRC
8183
    append_tx_crc(`MEMORY_BASE, (max_tmp - 5), 1'b0); // for first packet
8184
    // enable TX, set full-duplex mode, NO padding and NO CRC appending
8185
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD,
8186
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8187
    // check WB INT signal
8188
    if (wb_int !== 1'b0)
8189
    begin
8190
      test_fail("WB INT signal should not be set");
8191
      fail = fail + 1;
8192
    end
8193
 
8194
    // write to phy's control register for 10Mbps
8195
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
8196
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
8197
    speed = 10;
8198
 
8199
    i_length = (max_tmp - 5); // (max_tmp - 1); // not (max_tmp - 5) because NO automatic CRC appending
8200
    while (i_length <= (max_tmp - 3)) // (max_tmp + 1)) // (max_tmp) is the limit
8201
    begin
8202
      $display("   i_length = %0d", i_length);
8203
      // prepare packet's CRC
8204
      if (num_of_bd == 1)
8205
        append_tx_crc(`MEMORY_BASE, (max_tmp - 4), 1'b0); // for second and third packets
8206
      // Reset_tx_bd nable interrupt generation
8207
      // unmask interrupts
8208
      wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
8209
                               `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8210
      // not detect carrier sense in FD and no collision
8211
      eth_phy.carrier_sense_tx_fd_detect(0);
8212
      eth_phy.collision(0);
8213
      // first destination address on ethernet PHY
8214
      eth_phy.set_tx_mem_addr(0);
8215
      // prepare BDs
8216
      if (num_of_bd == 0)
8217
      begin
8218
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8219
        set_tx_bd(1, 1, i_length+1, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8220
        set_tx_bd(2, 2, i_length+2, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8221
        set_tx_bd_wrap(2);
8222
        set_tx_bd_ready(0, 0);
8223
      end
8224
      else if (num_of_bd == 1)
8225
        set_tx_bd_ready(1, 1);
8226
      else if (num_of_bd == 2)
8227
        set_tx_bd_ready(2, 2);
8228
      // CHECK END OF TRANSMITION
8229
      check_tx_bd(num_of_bd, data);
8230
        wait (MTxEn === 1'b1); // start transmit
8231
      check_tx_bd(num_of_bd, data);
8232
        if (data[15] !== 1)
8233
        begin
8234
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
8235
          fail = fail + 1;
8236
        end
8237
        wait (MTxEn === 1'b0); // end transmit
8238
        while (data[15] === 1)
8239
        begin
8240
      check_tx_bd(num_of_bd, data);
8241
          @(posedge wb_clk);
8242
        end
8243
        repeat (1) @(posedge wb_clk);
8244
      // check length of a PACKET
8245
      $display("   eth_phy length = %0d", eth_phy.tx_len);
8246
      tmp_len = eth_phy.tx_len;
8247
      #1;
8248
      if (tmp_len != (i_length + 4))
8249
      begin
8250
        test_fail("Wrong length of the packet out from MAC");
8251
        fail = fail + 1;
8252
      end
8253
      // checking packet
8254
      check_tx_packet(`MEMORY_BASE, 0, i_length, tmp);
8255
      if (tmp > 0)
8256
      begin
8257
        test_fail("Wrong data of the transmitted packet");
8258
        fail = fail + 1;
8259
      end
8260
      // check transmited TX packet CRC
8261
      check_tx_crc(0, i_length, 1'b0, tmp); // length without CRC
8262
      if (tmp > 0)
8263
      begin
8264
        test_fail("Wrong CRC of the transmitted packet");
8265
        fail = fail + 1;
8266
      end
8267
      // check WB INT signal
8268
      if (wb_int !== 1'b1)
8269
      begin
8270
        `TIME; $display("*E WB INT signal should be set");
8271
        test_fail("WB INT signal should be set");
8272
        fail = fail + 1;
8273
      end
8274
      // check TX buffer descriptor of a packet
8275
      check_tx_bd(num_of_bd, data);
8276
      if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 2)) || // wrap bit
8277
           ((data[15:0] !== 16'h5800) && (num_of_bd < 2)) )   // without wrap bit
8278
      begin
8279
        `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
8280
        test_fail("TX buffer descriptor status is not correct");
8281
        fail = fail + 1;
8282
      end
8283
      // check interrupts
8284
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8285
      if ((data & `ETH_INT_TXB) !== 1'b1)
8286
      begin
8287
        `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
8288
        test_fail("Interrupt Transmit Buffer was not set");
8289
        fail = fail + 1;
8290
      end
8291
      if ((data & (~`ETH_INT_TXB)) !== 0)
8292
      begin
8293
        `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
8294
        test_fail("Other interrupts (except Transmit Buffer) were set");
8295
        fail = fail + 1;
8296
      end
8297
      // clear interrupts
8298
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8299
      // check WB INT signal
8300
      if (wb_int !== 1'b0)
8301
      begin
8302
        test_fail("WB INT signal should not be set");
8303
        fail = fail + 1;
8304
      end
8305
      // INTERMEDIATE DISPLAYS
8306
      if (num_of_bd == 0)
8307
        $display("    ->packet with length %0d sent", (i_length + 4));
8308
      else if (num_of_bd == 1)
8309
        $display("    ->packet with length %0d sent", (i_length + 4));
8310
      else if (num_of_bd == 2)
8311
        $display("    ->packet with length %0d sent", (i_length + 4));
8312
      // set length (loop variable)
8313
      i_length = i_length + 1;
8314
      // the number of frame transmitted
8315
      num_of_frames = num_of_frames + 1;
8316
      num_of_bd = num_of_bd + 1;
8317
      @(posedge wb_clk);
8318
    end
8319
    // disable TX
8320
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
8321
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8322
    @(posedge wb_clk);
8323
    if(fail == 0)
8324
      test_ok;
8325
    else
8326
      fail = 0;
8327
  end
8328
 
8329
 
8330
  ////////////////////////////////////////////////////////////////////
8331
  ////                                                            ////
8332
  ////  Test transmit packets across changed MAXFL value at       ////
8333
  ////  47 TX buffer decriptors ( 100Mbps ).                      ////
8334
  ////                                                            ////
8335
  ////////////////////////////////////////////////////////////////////
8336
  if (test_num == 13) // without and with padding
8337
  begin
8338
    // TEST 13: TRANSMIT PACKETS ACROSS CHANGED MAXFL VALUE AT 13 TX BDs ( 100Mbps )
8339
    test_name = "TEST 13: TRANSMIT PACKETS ACROSS CHANGED MAXFL VALUE AT 13 TX BDs ( 100Mbps )";
8340
    `TIME; $display("  TEST 13: TRANSMIT PACKETS ACROSS CHANGED MAXFL VALUE AT 13 TX BDs ( 100Mbps )");
8341
 
8342
    // reset MAC registers
8343
    hard_reset;
8344
    // reset MAC and MII LOGIC with soft reset
8345
    reset_mac;
8346
    reset_mii;
8347
    // set wb slave response
8348
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
8349
 
8350
    max_tmp = 0;
8351
    min_tmp = 0;
8352
    num_of_frames = 0;
8353
    num_of_bd = 0;
8354
    // set 47 TX buffer descriptors - must be set before TX enable
8355
    wbm_write(`ETH_TX_BD_NUM, 32'h2F, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8356
    // prepare a packet of MAXFL + 10 length
8357
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8358
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
8359
    min_tmp = tmp[31:16];
8360
    // change MAXFL value
8361
    max_tmp = min_tmp + 53;
8362
    wbm_write(`ETH_PACKETLEN, {min_tmp, max_tmp}, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8363
    st_data = 8'h62;
8364
    set_tx_packet(`MEMORY_BASE, max_tmp, st_data); // length with CRC
8365
    append_tx_crc(`MEMORY_BASE, (max_tmp - 5), 1'b0); // for first packet
8366
    // enable TX, set full-duplex mode, NO padding and NO CRC appending
8367
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD,
8368
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8369
    // check WB INT signal
8370
    if (wb_int !== 1'b0)
8371
    begin
8372
      test_fail("WB INT signal should not be set");
8373
      fail = fail + 1;
8374
    end
8375
 
8376
    // write to phy's control register for 100Mbps
8377
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
8378
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
8379
    speed = 100;
8380
 
8381
    i_length = (max_tmp - 5); // (max_tmp - 1); // not (max_tmp - 5) because NO automatic CRC appending
8382
    while (i_length <= (max_tmp - 3)) // (max_tmp + 1)) // (max_tmp) is the limit
8383
    begin
8384
      $display("   i_length = %0d", i_length);
8385
      // prepare packet's CRC
8386
      if (num_of_bd == 1)
8387
        append_tx_crc(`MEMORY_BASE, (max_tmp - 4), 1'b0); // for second and third packets
8388
      // Reset_tx_bd nable interrupt generation
8389
      // unmask interrupts
8390
      wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
8391
                               `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8392
      // not detect carrier sense in FD and no collision
8393
      eth_phy.carrier_sense_tx_fd_detect(0);
8394
      eth_phy.collision(0);
8395
      // first destination address on ethernet PHY
8396
      eth_phy.set_tx_mem_addr(0);
8397
      // prepare BDs
8398
      if (num_of_bd == 0)
8399
      begin
8400
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8401
        set_tx_bd(1, 1, i_length+1, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8402
        set_tx_bd(2, 2, i_length+2, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8403
        set_tx_bd_wrap(2);
8404
        set_tx_bd_ready(0, 0);
8405
      end
8406
      else if (num_of_bd == 1)
8407
        set_tx_bd_ready(1, 1);
8408
      else if (num_of_bd == 2)
8409
        set_tx_bd_ready(2, 2);
8410
      // CHECK END OF TRANSMITION
8411
      check_tx_bd(num_of_bd, data);
8412
        wait (MTxEn === 1'b1); // start transmit
8413
      check_tx_bd(num_of_bd, data);
8414
        if (data[15] !== 1)
8415
        begin
8416
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
8417
          fail = fail + 1;
8418
        end
8419
        wait (MTxEn === 1'b0); // end transmit
8420
        while (data[15] === 1)
8421
        begin
8422
      check_tx_bd(num_of_bd, data);
8423
          @(posedge wb_clk);
8424
        end
8425
        repeat (1) @(posedge wb_clk);
8426
      // check length of a PACKET
8427
      $display("   eth_phy length = %0d", eth_phy.tx_len);
8428
      tmp_len = eth_phy.tx_len;
8429
      #1;
8430
      if (tmp_len != (i_length + 4))
8431
      begin
8432
        test_fail("Wrong length of the packet out from MAC");
8433
        fail = fail + 1;
8434
      end
8435
      // checking packet
8436
      check_tx_packet(`MEMORY_BASE, 0, i_length, tmp);
8437
      if (tmp > 0)
8438
      begin
8439
        test_fail("Wrong data of the transmitted packet");
8440
        fail = fail + 1;
8441
      end
8442
      // check transmited TX packet CRC
8443
      check_tx_crc(0, i_length, 1'b0, tmp); // length without CRC
8444
      if (tmp > 0)
8445
      begin
8446
        test_fail("Wrong CRC of the transmitted packet");
8447
        fail = fail + 1;
8448
      end
8449
      // check WB INT signal
8450
      if (wb_int !== 1'b1)
8451
      begin
8452
        `TIME; $display("*E WB INT signal should be set");
8453
        test_fail("WB INT signal should be set");
8454
        fail = fail + 1;
8455
      end
8456
      // check TX buffer descriptor of a packet
8457
      check_tx_bd(num_of_bd, data);
8458
      if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 2)) || // wrap bit
8459
           ((data[15:0] !== 16'h5800) && (num_of_bd < 2)) )   // without wrap bit
8460
      begin
8461
        `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
8462
        test_fail("TX buffer descriptor status is not correct");
8463
        fail = fail + 1;
8464
      end
8465
      // check interrupts
8466
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8467
      if ((data & `ETH_INT_TXB) !== 1'b1)
8468
      begin
8469
        `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
8470
        test_fail("Interrupt Transmit Buffer was not set");
8471
        fail = fail + 1;
8472
      end
8473
      if ((data & (~`ETH_INT_TXB)) !== 0)
8474
      begin
8475
        `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
8476
        test_fail("Other interrupts (except Transmit Buffer) were set");
8477
        fail = fail + 1;
8478
      end
8479
      // clear interrupts
8480
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8481
      // check WB INT signal
8482
      if (wb_int !== 1'b0)
8483
      begin
8484
        test_fail("WB INT signal should not be set");
8485
        fail = fail + 1;
8486
      end
8487
      // INTERMEDIATE DISPLAYS
8488
      if (num_of_bd == 0)
8489
        $display("    ->packet with length %0d sent", (i_length + 4));
8490
      else if (num_of_bd == 1)
8491
        $display("    ->packet with length %0d sent", (i_length + 4));
8492
      else if (num_of_bd == 2)
8493
        $display("    ->packet with length %0d sent", (i_length + 4));
8494
      // set length (loop variable)
8495
      i_length = i_length + 1;
8496
      // the number of frame transmitted
8497
      num_of_frames = num_of_frames + 1;
8498
      num_of_bd = num_of_bd + 1;
8499
      @(posedge wb_clk);
8500
    end
8501
    // disable TX
8502
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
8503
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8504
    @(posedge wb_clk);
8505
    if(fail == 0)
8506
      test_ok;
8507
    else
8508
      fail = 0;
8509
  end
8510
 
8511
 
8512
  ////////////////////////////////////////////////////////////////////
8513
  ////                                                            ////
8514
  ////  Test transmit packets across changed MINFL value at       ////
8515
  ////  7 TX buffer decriptors ( 10Mbps ).                        ////
8516
  ////                                                            ////
8517
  ////////////////////////////////////////////////////////////////////
8518
  if (test_num == 14) // without and with padding
8519
  begin
8520
    // TEST 14: TRANSMIT PACKETS ACROSS CHANGED MINFL VALUE AT 7 TX BDs ( 10Mbps )
8521
    test_name = "TEST 14: TRANSMIT PACKETS ACROSS CHANGED MINFL VALUE AT 7 TX BDs ( 10Mbps )";
8522
    `TIME; $display("  TEST 14: TRANSMIT PACKETS ACROSS CHANGED MINFL VALUE AT 7 TX BDs ( 10Mbps )");
8523
 
8524
    // reset MAC registers
8525
    hard_reset;
8526
    // reset MAC and MII LOGIC with soft reset
8527
    reset_mac;
8528
    reset_mii;
8529
    // set wb slave response
8530
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
8531
 
8532
    max_tmp = 0;
8533
    min_tmp = 0;
8534
    num_of_frames = 0;
8535
    num_of_bd = 0;
8536
    // set 7 TX buffer descriptors - must be set before TX enable
8537
    wbm_write(`ETH_TX_BD_NUM, 32'h7, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8538
    // prepare a packet of MAXFL + 10 length
8539
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8540
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
8541
    min_tmp = tmp[31:16];
8542
    // change MINFL value
8543
    min_tmp = max_tmp - 177;
8544
    wbm_write(`ETH_PACKETLEN, {min_tmp, max_tmp}, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8545
    st_data = 8'h62;
8546
    set_tx_packet(`MEMORY_BASE, min_tmp, st_data); // length without CRC
8547
    // enable TX, set full-duplex mode, padding and CRC appending
8548
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_PAD | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
8549
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8550
    // check WB INT signal
8551
    if (wb_int !== 1'b0)
8552
    begin
8553
      test_fail("WB INT signal should not be set");
8554
      fail = fail + 1;
8555
    end
8556
 
8557
    // write to phy's control register for 10Mbps
8558
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
8559
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
8560
    speed = 10;
8561
 
8562
    i_length = (min_tmp - 5);
8563
    while (i_length <= (min_tmp - 3)) // (min_tmp - 4) is the limit
8564
    begin
8565
      $display("   i_length = %0d", i_length);
8566
      // Reset_tx_bd nable interrupt generation
8567
      // unmask interrupts
8568
      wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
8569
                               `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8570
      // not detect carrier sense in FD and no collision
8571
      eth_phy.carrier_sense_tx_fd_detect(0);
8572
      eth_phy.collision(0);
8573
      // first destination address on ethernet PHY
8574
      eth_phy.set_tx_mem_addr(0);
8575
      // prepare BDs
8576
      if (num_of_bd == 0)
8577
      begin
8578
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8579
        set_tx_bd(1, 1, i_length+1, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8580
        set_tx_bd(2, 2, i_length+2, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8581
        set_tx_bd_wrap(2);
8582
        set_tx_bd_ready(0, 0);
8583
      end
8584
      else if (num_of_bd == 1)
8585
        set_tx_bd_ready(1, 1);
8586
      else if (num_of_bd == 2)
8587
        set_tx_bd_ready(2, 2);
8588
      // CHECK END OF TRANSMITION
8589
      check_tx_bd(num_of_bd, data);
8590
        wait (MTxEn === 1'b1); // start transmit
8591
      check_tx_bd(num_of_bd, data);
8592
        if (data[15] !== 1)
8593
        begin
8594
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
8595
          fail = fail + 1;
8596
        end
8597
        wait (MTxEn === 1'b0); // end transmit
8598
        while (data[15] === 1)
8599
        begin
8600
      check_tx_bd(num_of_bd, data);
8601
          @(posedge wb_clk);
8602
        end
8603
        repeat (1) @(posedge wb_clk);
8604
      // check length of a PACKET
8605
      $display("   eth_phy length = %0d", eth_phy.tx_len);
8606
      tmp_len = eth_phy.tx_len;
8607
      #1;
8608
      if (tmp_len != (i_length + 4))
8609
      begin
8610
        test_fail("Wrong length of the packet out from MAC");
8611
        fail = fail + 1;
8612
      end
8613
      // checking packet
8614
      check_tx_packet(`MEMORY_BASE, 0, i_length, tmp);
8615
      if (tmp > 0)
8616
      begin
8617
        test_fail("Wrong data of the transmitted packet");
8618
        fail = fail + 1;
8619
      end
8620
      // check transmited TX packet CRC
8621
      check_tx_crc(0, i_length, 1'b0, tmp); // length without CRC
8622
      if (tmp > 0)
8623
      begin
8624
        test_fail("Wrong CRC of the transmitted packet");
8625
        fail = fail + 1;
8626
      end
8627
      // check WB INT signal
8628
      if (wb_int !== 1'b1)
8629
      begin
8630
        `TIME; $display("*E WB INT signal should be set");
8631
        test_fail("WB INT signal should be set");
8632
        fail = fail + 1;
8633
      end
8634
      // check TX buffer descriptor of a packet
8635
      check_tx_bd(num_of_bd, data);
8636
      if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 2)) || // wrap bit
8637
           ((data[15:0] !== 16'h5800) && (num_of_bd < 2)) )   // without wrap bit
8638
      begin
8639
        `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
8640
        test_fail("TX buffer descriptor status is not correct");
8641
        fail = fail + 1;
8642
      end
8643
      // check interrupts
8644
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8645
      if ((data & `ETH_INT_TXB) !== 1'b1)
8646
      begin
8647
        `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
8648
        test_fail("Interrupt Transmit Buffer was not set");
8649
        fail = fail + 1;
8650
      end
8651
      if ((data & (~`ETH_INT_TXB)) !== 0)
8652
      begin
8653
        `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
8654
        test_fail("Other interrupts (except Transmit Buffer) were set");
8655
        fail = fail + 1;
8656
      end
8657
      // clear interrupts
8658
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8659
      // check WB INT signal
8660
      if (wb_int !== 1'b0)
8661
      begin
8662
        test_fail("WB INT signal should not be set");
8663
        fail = fail + 1;
8664
      end
8665
      // INTERMEDIATE DISPLAYS
8666
      if (num_of_bd == 0)
8667
        $display("    ->packet with length %0d sent", (i_length + 4));
8668
      else if (num_of_bd == 1)
8669
        $display("    ->packet with length %0d sent", (i_length + 4));
8670
      else if (num_of_bd == 2)
8671
        $display("    ->packet with length %0d sent", (i_length + 4));
8672
      // set length (loop variable)
8673
      i_length = i_length + 1;
8674
      // the number of frame transmitted
8675
      num_of_frames = num_of_frames + 1;
8676
      num_of_bd = num_of_bd + 1;
8677
      @(posedge wb_clk);
8678
    end
8679
    // disable TX
8680
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
8681
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8682
    @(posedge wb_clk);
8683
    if(fail == 0)
8684
      test_ok;
8685
    else
8686
      fail = 0;
8687
  end
8688
 
8689
 
8690
  ////////////////////////////////////////////////////////////////////
8691
  ////                                                            ////
8692
  ////  Test transmit packets across changed MINFL value at       ////
8693
  ////  7 TX buffer decriptors ( 100Mbps ).                       ////
8694
  ////                                                            ////
8695
  ////////////////////////////////////////////////////////////////////
8696
  if (test_num == 15) // without and with padding
8697
  begin
8698
    // TEST 15: TRANSMIT PACKETS ACROSS CHANGED MINFL VALUE AT 7 TX BDs ( 100Mbps )
8699
    test_name = "TEST 15: TRANSMIT PACKETS ACROSS CHANGED MINFL VALUE AT 7 TX BDs ( 100Mbps )";
8700
    `TIME; $display("  TEST 15: TRANSMIT PACKETS ACROSS CHANGED MINFL VALUE AT 7 TX BDs ( 100Mbps )");
8701
 
8702
    // reset MAC registers
8703
    hard_reset;
8704
    // reset MAC and MII LOGIC with soft reset
8705
    reset_mac;
8706
    reset_mii;
8707
    // set wb slave response
8708
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
8709
 
8710
    max_tmp = 0;
8711
    min_tmp = 0;
8712
    num_of_frames = 0;
8713
    num_of_bd = 0;
8714
    // set 7 TX buffer descriptors - must be set before TX enable
8715
    wbm_write(`ETH_TX_BD_NUM, 32'h7, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8716
    // prepare a packet of MAXFL + 10 length
8717
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8718
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
8719
    min_tmp = tmp[31:16];
8720
    // change MINFL value
8721
    min_tmp = max_tmp - 177;
8722
    wbm_write(`ETH_PACKETLEN, {min_tmp, max_tmp}, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8723
    st_data = 8'h62;
8724
    set_tx_packet(`MEMORY_BASE, min_tmp, st_data); // length without CRC
8725
    // enable TX, set full-duplex mode, padding and CRC appending
8726
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_PAD | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
8727
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8728
    // check WB INT signal
8729
    if (wb_int !== 1'b0)
8730
    begin
8731
      test_fail("WB INT signal should not be set");
8732
      fail = fail + 1;
8733
    end
8734
 
8735
    // write to phy's control register for 100Mbps
8736
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
8737
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
8738
    speed = 100;
8739
 
8740
    i_length = (min_tmp - 5);
8741
    while (i_length <= (min_tmp - 3)) // (min_tmp - 4) is the limit
8742
    begin
8743
      $display("   i_length = %0d", i_length);
8744
      // Reset_tx_bd nable interrupt generation
8745
      // unmask interrupts
8746
      wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
8747
                               `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8748
      // not detect carrier sense in FD and no collision
8749
      eth_phy.carrier_sense_tx_fd_detect(0);
8750
      eth_phy.collision(0);
8751
      // first destination address on ethernet PHY
8752
      eth_phy.set_tx_mem_addr(0);
8753
      // prepare BDs
8754
      if (num_of_bd == 0)
8755
      begin
8756
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8757
        set_tx_bd(1, 1, i_length+1, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8758
        set_tx_bd(2, 2, i_length+2, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8759
        set_tx_bd_wrap(2);
8760
        set_tx_bd_ready(0, 0);
8761
      end
8762
      else if (num_of_bd == 1)
8763
        set_tx_bd_ready(1, 1);
8764
      else if (num_of_bd == 2)
8765
        set_tx_bd_ready(2, 2);
8766
      // CHECK END OF TRANSMITION
8767
      check_tx_bd(num_of_bd, data);
8768
        wait (MTxEn === 1'b1); // start transmit
8769
      check_tx_bd(num_of_bd, data);
8770
        if (data[15] !== 1)
8771
        begin
8772
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
8773
          fail = fail + 1;
8774
        end
8775
        wait (MTxEn === 1'b0); // end transmit
8776
        while (data[15] === 1)
8777
        begin
8778
      check_tx_bd(num_of_bd, data);
8779
          @(posedge wb_clk);
8780
        end
8781
        repeat (1) @(posedge wb_clk);
8782
      // check length of a PACKET
8783
      $display("   eth_phy length = %0d", eth_phy.tx_len);
8784
      tmp_len = eth_phy.tx_len;
8785
      #1;
8786
      if (tmp_len != (i_length + 4))
8787
      begin
8788
        test_fail("Wrong length of the packet out from MAC");
8789
        fail = fail + 1;
8790
      end
8791
      // checking packet
8792
      check_tx_packet(`MEMORY_BASE, 0, i_length, tmp);
8793
      if (tmp > 0)
8794
      begin
8795
        test_fail("Wrong data of the transmitted packet");
8796
        fail = fail + 1;
8797
      end
8798
      // check transmited TX packet CRC
8799
      check_tx_crc(0, i_length, 1'b0, tmp); // length without CRC
8800
      if (tmp > 0)
8801
      begin
8802
        test_fail("Wrong CRC of the transmitted packet");
8803
        fail = fail + 1;
8804
      end
8805
      // check WB INT signal
8806
      if (wb_int !== 1'b1)
8807
      begin
8808
        `TIME; $display("*E WB INT signal should be set");
8809
        test_fail("WB INT signal should be set");
8810
        fail = fail + 1;
8811
      end
8812
      // check TX buffer descriptor of a packet
8813
      check_tx_bd(num_of_bd, data);
8814
      if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 2)) || // wrap bit
8815
           ((data[15:0] !== 16'h5800) && (num_of_bd < 2)) )   // without wrap bit
8816
      begin
8817
        `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
8818
        test_fail("TX buffer descriptor status is not correct");
8819
        fail = fail + 1;
8820
      end
8821
      // check interrupts
8822
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8823
      if ((data & `ETH_INT_TXB) !== 1'b1)
8824
      begin
8825
        `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
8826
        test_fail("Interrupt Transmit Buffer was not set");
8827
        fail = fail + 1;
8828
      end
8829
      if ((data & (~`ETH_INT_TXB)) !== 0)
8830
      begin
8831
        `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
8832
        test_fail("Other interrupts (except Transmit Buffer) were set");
8833
        fail = fail + 1;
8834
      end
8835
      // clear interrupts
8836
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8837
      // check WB INT signal
8838
      if (wb_int !== 1'b0)
8839
      begin
8840
        test_fail("WB INT signal should not be set");
8841
        fail = fail + 1;
8842
      end
8843
      // INTERMEDIATE DISPLAYS
8844
      if (num_of_bd == 0)
8845
        $display("    ->packet with length %0d sent", (i_length + 4));
8846
      else if (num_of_bd == 1)
8847
        $display("    ->packet with length %0d sent", (i_length + 4));
8848
      else if (num_of_bd == 2)
8849
        $display("    ->packet with length %0d sent", (i_length + 4));
8850
      // set length (loop variable)
8851
      i_length = i_length + 1;
8852
      // the number of frame transmitted
8853
      num_of_frames = num_of_frames + 1;
8854
      num_of_bd = num_of_bd + 1;
8855
      @(posedge wb_clk);
8856
    end
8857
    // disable TX
8858
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
8859
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8860
    @(posedge wb_clk);
8861
    if(fail == 0)
8862
      test_ok;
8863
    else
8864
      fail = 0;
8865
  end
8866
 
8867
 
8868
  ////////////////////////////////////////////////////////////////////
8869
  ////                                                            ////
8870
  ////  Test transmit packets across MAXFL with HUGEN at          ////
8871
  ////  19 TX buffer decriptors ( 10Mbps ).                       ////
8872
  ////                                                            ////
8873
  ////////////////////////////////////////////////////////////////////
8874
  if (test_num == 16) // without and with padding
8875
  begin
8876
    // TEST 16: TRANSMIT PACKETS ACROSS MAXFL WITH HUGEN AT 19 TX BDs ( 10Mbps )
8877
    test_name = "TEST 16: TRANSMIT PACKETS ACROSS MAXFL WITH HUGEN AT 19 TX BDs ( 10Mbps )";
8878
    `TIME; $display("  TEST 16: TRANSMIT PACKETS ACROSS MAXFL WITH HUGEN AT 19 TX BDs ( 10Mbps )");
8879
 
8880
    // reset MAC registers
8881
    hard_reset;
8882
    // reset MAC and MII LOGIC with soft reset
8883
    reset_mac;
8884
    reset_mii;
8885
    // set wb slave response
8886
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
8887
 
8888
    max_tmp = 0;
8889
    min_tmp = 0;
8890
    num_of_frames = 0;
8891
    num_of_bd = 0;
8892
    // set 19 TX buffer descriptors - must be set before TX enable
8893
    wbm_write(`ETH_TX_BD_NUM, 32'h13, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8894
    // prepare a packet of 64k - 1 length (16'hFFFF)
8895
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8896
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
8897
    min_tmp = tmp[31:16];
8898
    st_data = 8'h8D;
8899
    set_tx_packet(`MEMORY_BASE, 16'hFFFF, st_data); // length with CRC
8900
    // enable TX, set full-duplex mode, NO padding, CRC appending and huge enabled
8901
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN | `ETH_MODER_HUGEN,
8902
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8903
    // check WB INT signal
8904
    if (wb_int !== 1'b0)
8905
    begin
8906
      test_fail("WB INT signal should not be set");
8907
      fail = fail + 1;
8908
    end
8909
 
8910
    // write to phy's control register for 10Mbps
8911
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
8912
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
8913
    speed = 10;
8914
 
8915
    i_length = (max_tmp - 5); // (max_tmp - 4) is the MAXFL limit
8916
    while (i_length <= (16'hFFFF - 4)) // (16'hFFFF - 4) is the limit
8917
    begin
8918
      $display("   i_length = %0d", i_length);
8919
      // Reset_tx_bd nable interrupt generation
8920
      // unmask interrupts
8921
      wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
8922
                               `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8923
      // not detect carrier sense in FD and no collision
8924
      eth_phy.carrier_sense_tx_fd_detect(0);
8925
      eth_phy.collision(0);
8926
      // first destination address on ethernet PHY
8927
      eth_phy.set_tx_mem_addr(0);
8928
      // prepare BDs
8929
      if (num_of_bd == 0)
8930
      begin
8931
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8932
        set_tx_bd(1, 1, i_length+1, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8933
        set_tx_bd(2, 2, i_length+2, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8934
        set_tx_bd(3, 3, (16'hFFFF - 5), 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8935
        set_tx_bd(4, 4, (16'hFFFF - 4), 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8936
        set_tx_bd_wrap(4);
8937
        set_tx_bd_ready(0, 0);
8938
      end
8939
      else if (num_of_bd == 1)
8940
        set_tx_bd_ready(1, 1);
8941
      else if (num_of_bd == 2)
8942
        set_tx_bd_ready(2, 2);
8943
      else if (num_of_bd == 3)
8944
        set_tx_bd_ready(3, 3);
8945
      else if (num_of_bd == 4)
8946
        set_tx_bd_ready(4, 4);
8947
      // CHECK END OF TRANSMITION
8948
      check_tx_bd(num_of_bd, data);
8949
        wait (MTxEn === 1'b1); // start transmit
8950
      check_tx_bd(num_of_bd, data);
8951
        if (data[15] !== 1)
8952
        begin
8953
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
8954
          fail = fail + 1;
8955
        end
8956
        wait (MTxEn === 1'b0); // end transmit
8957
        while (data[15] === 1)
8958
        begin
8959
      check_tx_bd(num_of_bd, data);
8960
          @(posedge wb_clk);
8961
        end
8962
        repeat (1) @(posedge wb_clk);
8963
      // check length of a PACKET
8964
      $display("   eth_phy length = %0d", eth_phy.tx_len);
8965
      tmp_len = eth_phy.tx_len;
8966
      #1;
8967
      if (tmp_len != (i_length + 4))
8968
      begin
8969
        test_fail("Wrong length of the packet out from MAC");
8970
        fail = fail + 1;
8971
      end
8972
      // checking packet
8973
      check_tx_packet(`MEMORY_BASE, 0, i_length, tmp);
8974
      if (tmp > 0)
8975
      begin
8976
        test_fail("Wrong data of the transmitted packet");
8977
        fail = fail + 1;
8978
      end
8979
      // check transmited TX packet CRC
8980
      check_tx_crc(0, i_length, 1'b0, tmp); // length without CRC
8981
      if (tmp > 0)
8982
      begin
8983
        test_fail("Wrong CRC of the transmitted packet");
8984
        fail = fail + 1;
8985
      end
8986
      // check WB INT signal
8987
      if (wb_int !== 1'b1)
8988
      begin
8989
        `TIME; $display("*E WB INT signal should be set");
8990
        test_fail("WB INT signal should be set");
8991
        fail = fail + 1;
8992
      end
8993
      // check TX buffer descriptor of a packet
8994
      check_tx_bd(num_of_bd, data);
8995
      if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 4)) || // wrap bit
8996
           ((data[15:0] !== 16'h5800) && (num_of_bd < 4)) )   // without wrap bit
8997
      begin
8998
        `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
8999
        test_fail("TX buffer descriptor status is not correct");
9000
        fail = fail + 1;
9001
      end
9002
      // check interrupts
9003
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9004
      if ((data & `ETH_INT_TXB) !== 1'b1)
9005
      begin
9006
        `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
9007
        test_fail("Interrupt Transmit Buffer was not set");
9008
        fail = fail + 1;
9009
      end
9010
      if ((data & (~`ETH_INT_TXB)) !== 0)
9011
      begin
9012
        `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
9013
        test_fail("Other interrupts (except Transmit Buffer) were set");
9014
        fail = fail + 1;
9015
      end
9016
      // clear interrupts
9017
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9018
      // check WB INT signal
9019
      if (wb_int !== 1'b0)
9020
      begin
9021
        test_fail("WB INT signal should not be set");
9022
        fail = fail + 1;
9023
      end
9024
      // INTERMEDIATE DISPLAYS
9025
      $display("    ->packet with length %0d sent", (i_length + 4));
9026
      // set length (loop variable)
9027
      if ((num_of_bd < 2) || (num_of_bd >= 3))
9028
        i_length = i_length + 1;
9029
      else if (num_of_bd == 2)
9030
        i_length = (16'hFFFF - 5);
9031
      // the number of frame transmitted
9032
      num_of_frames = num_of_frames + 1;
9033
      num_of_bd = num_of_bd + 1;
9034
      @(posedge wb_clk);
9035
    end
9036
    // disable TX
9037
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
9038
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9039
    @(posedge wb_clk);
9040
    if(fail == 0)
9041
      test_ok;
9042
    else
9043
      fail = 0;
9044
  end
9045
 
9046
 
9047
  ////////////////////////////////////////////////////////////////////
9048
  ////                                                            ////
9049
  ////  Test transmit packets across MAXFL with HUGEN at          ////
9050
  ////  19 TX buffer decriptors ( 100Mbps ).                      ////
9051
  ////                                                            ////
9052
  ////////////////////////////////////////////////////////////////////
9053
  if (test_num == 17) // without and with padding
9054
  begin
9055
    // TEST 17: TRANSMIT PACKETS ACROSS MAXFL WITH HUGEN AT 19 TX BDs ( 100Mbps )
9056
    test_name = "TEST 17: TRANSMIT PACKETS ACROSS MAXFL WITH HUGEN AT 19 TX BDs ( 100Mbps )";
9057
    `TIME; $display("  TEST 17: TRANSMIT PACKETS ACROSS MAXFL WITH HUGEN AT 19 TX BDs ( 100Mbps )");
9058
 
9059
    // reset MAC registers
9060
    hard_reset;
9061
    // reset MAC and MII LOGIC with soft reset
9062
    reset_mac;
9063
    reset_mii;
9064
    // set wb slave response
9065
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
9066
 
9067
    max_tmp = 0;
9068
    min_tmp = 0;
9069
    num_of_frames = 0;
9070
    num_of_bd = 0;
9071
    // set 19 TX buffer descriptors - must be set before TX enable
9072
    wbm_write(`ETH_TX_BD_NUM, 32'h13, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9073
    // prepare a packet of 64k - 1 length (16'hFFFF)
9074
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9075
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
9076
    min_tmp = tmp[31:16];
9077
    st_data = 8'h8D;
9078
    set_tx_packet(`MEMORY_BASE, 16'hFFFF, st_data); // length with CRC
9079
    // enable TX, set full-duplex mode, NO padding, CRC appending and huge enabled
9080
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN | `ETH_MODER_HUGEN,
9081
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9082
    // check WB INT signal
9083
    if (wb_int !== 1'b0)
9084
    begin
9085
      test_fail("WB INT signal should not be set");
9086
      fail = fail + 1;
9087
    end
9088
 
9089
    // write to phy's control register for 100Mbps
9090
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
9091
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
9092
    speed = 100;
9093
 
9094
    i_length = (max_tmp - 5); // (max_tmp - 4) is the MAXFL limit
9095
    while (i_length <= (16'hFFFF - 4)) // (16'hFFFF - 4) is the limit
9096
    begin
9097
      $display("   i_length = %0d", i_length);
9098
      // Reset_tx_bd nable interrupt generation
9099
      // unmask interrupts
9100
      wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
9101
                               `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9102
      // not detect carrier sense in FD and no collision
9103
      eth_phy.carrier_sense_tx_fd_detect(0);
9104
      eth_phy.collision(0);
9105
      // first destination address on ethernet PHY
9106
      eth_phy.set_tx_mem_addr(0);
9107
      // prepare BDs
9108
      if (num_of_bd == 0)
9109
      begin
9110
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
9111
        set_tx_bd(1, 1, i_length+1, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
9112
        set_tx_bd(2, 2, i_length+2, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
9113
        set_tx_bd(3, 3, (16'hFFFF - 5), 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
9114
        set_tx_bd(4, 4, (16'hFFFF - 4), 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
9115
        set_tx_bd_wrap(4);
9116
        set_tx_bd_ready(0, 0);
9117
      end
9118
      else if (num_of_bd == 1)
9119
        set_tx_bd_ready(1, 1);
9120
      else if (num_of_bd == 2)
9121
        set_tx_bd_ready(2, 2);
9122
      else if (num_of_bd == 3)
9123
        set_tx_bd_ready(3, 3);
9124
      else if (num_of_bd == 4)
9125
        set_tx_bd_ready(4, 4);
9126
      // CHECK END OF TRANSMITION
9127
      check_tx_bd(num_of_bd, data);
9128
        wait (MTxEn === 1'b1); // start transmit
9129
      check_tx_bd(num_of_bd, data);
9130
        if (data[15] !== 1)
9131
        begin
9132
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
9133
          fail = fail + 1;
9134
        end
9135
        wait (MTxEn === 1'b0); // end transmit
9136
        while (data[15] === 1)
9137
        begin
9138
      check_tx_bd(num_of_bd, data);
9139
          @(posedge wb_clk);
9140
        end
9141
        repeat (1) @(posedge wb_clk);
9142
      // check length of a PACKET
9143
      $display("   eth_phy length = %0d", eth_phy.tx_len);
9144
      tmp_len = eth_phy.tx_len;
9145
      #1;
9146
      if (tmp_len != (i_length + 4))
9147
      begin
9148
        test_fail("Wrong length of the packet out from MAC");
9149
        fail = fail + 1;
9150
      end
9151
      // checking packet
9152
      check_tx_packet(`MEMORY_BASE, 0, i_length, tmp);
9153
      if (tmp > 0)
9154
      begin
9155
        test_fail("Wrong data of the transmitted packet");
9156
        fail = fail + 1;
9157
      end
9158
      // check transmited TX packet CRC
9159
      check_tx_crc(0, i_length, 1'b0, tmp); // length without CRC
9160
      if (tmp > 0)
9161
      begin
9162
        test_fail("Wrong CRC of the transmitted packet");
9163
        fail = fail + 1;
9164
      end
9165
      // check WB INT signal
9166
      if (wb_int !== 1'b1)
9167
      begin
9168
        `TIME; $display("*E WB INT signal should be set");
9169
        test_fail("WB INT signal should be set");
9170
        fail = fail + 1;
9171
      end
9172
      // check TX buffer descriptor of a packet
9173
      check_tx_bd(num_of_bd, data);
9174
      if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 4)) || // wrap bit
9175
           ((data[15:0] !== 16'h5800) && (num_of_bd < 4)) )   // without wrap bit
9176
      begin
9177
        `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
9178
        test_fail("TX buffer descriptor status is not correct");
9179
        fail = fail + 1;
9180
      end
9181
      // check interrupts
9182
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9183
      if ((data & `ETH_INT_TXB) !== 1'b1)
9184
      begin
9185
        `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
9186
        test_fail("Interrupt Transmit Buffer was not set");
9187
        fail = fail + 1;
9188
      end
9189
      if ((data & (~`ETH_INT_TXB)) !== 0)
9190
      begin
9191
        `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
9192
        test_fail("Other interrupts (except Transmit Buffer) were set");
9193
        fail = fail + 1;
9194
      end
9195
      // clear interrupts
9196
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9197
      // check WB INT signal
9198
      if (wb_int !== 1'b0)
9199
      begin
9200
        test_fail("WB INT signal should not be set");
9201
        fail = fail + 1;
9202
      end
9203
      // INTERMEDIATE DISPLAYS
9204
      $display("    ->packet with length %0d sent", (i_length + 4));
9205
      // set length (loop variable)
9206
      if ((num_of_bd < 2) || (num_of_bd >= 3))
9207
        i_length = i_length + 1;
9208
      else if (num_of_bd == 2)
9209
        i_length = (16'hFFFF - 5);
9210
      // the number of frame transmitted
9211
      num_of_frames = num_of_frames + 1;
9212
      num_of_bd = num_of_bd + 1;
9213
      @(posedge wb_clk);
9214
    end
9215
    // disable TX
9216
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
9217
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9218
    @(posedge wb_clk);
9219
    if(fail == 0)
9220
      test_ok;
9221
    else
9222
      fail = 0;
9223
  end
9224
 
9225
 
9226
  ////////////////////////////////////////////////////////////////////
9227
  ////                                                            ////
9228
  ////  Test IPG during Back-to-Back transmit at                  ////
9229
  ////  88 TX buffer decriptors ( 10Mbps ).                       ////
9230
  ////                                                            ////
9231
  ////////////////////////////////////////////////////////////////////
9232
  if (test_num == 18) // without and with padding
9233
  begin
9234
    // TEST 18: IPG DURING BACK-TO-BACK TRANSMIT AT 88 TX BDs ( 10Mbps )
9235
    test_name = "TEST 18: IPG DURING BACK-TO-BACK TRANSMIT AT 88 TX BDs ( 10Mbps )";
9236
    `TIME; $display("  TEST 18: IPG DURING BACK-TO-BACK TRANSMIT AT 88 TX BDs ( 10Mbps )");
9237
 
9238
    // reset MAC registers
9239
    hard_reset;
9240
    // reset MAC and MII LOGIC with soft reset
9241
    reset_mac;
9242
    reset_mii;
9243
    // set wb slave response
9244
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
9245
 
9246
    max_tmp = 0;
9247
    min_tmp = 0;
9248
    num_of_frames = 0;
9249
    num_of_bd = 0;
9250
    tmp_ipgt = 0;
9251
    // set 88 TX buffer descriptors - must be set before TX enable
9252
    wbm_write(`ETH_TX_BD_NUM, 32'h58, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9253
    // enable TX, set full-duplex mode, NO padding and CRC appending
9254
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
9255
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9256
    // prepare two packets of MAXFL length
9257
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9258
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
9259
    min_tmp = tmp[31:16];
9260
    st_data = 8'h29;
9261
    set_tx_packet(`MEMORY_BASE, (max_tmp - 4), st_data); // length without CRC
9262
    // check WB INT signal
9263
    if (wb_int !== 1'b0)
9264
    begin
9265
      test_fail("WB INT signal should not be set");
9266
      fail = fail + 1;
9267
    end
9268
 
9269
    // write to phy's control register for 10Mbps
9270
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
9271
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
9272
    speed = 10;
9273
 
9274
    i_length = (min_tmp - 4);
9275
    while (i_length < (max_tmp - 4))
9276
    begin
9277
      // disable TX, set full-duplex mode, NO padding and CRC appending
9278
      wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
9279
                4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9280
      // set IPGT register
9281
      wbm_write(`ETH_IPGT, tmp_ipgt, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9282
      // enable TX, set full-duplex mode, NO padding and CRC appending
9283
      wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
9284
                4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9285
      // Reset_tx_bd enable interrupt generation
9286
      // unmask interrupts
9287
      wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
9288
                               `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9289
      // not detect carrier sense in FD and no collision
9290
      eth_phy.carrier_sense_tx_fd_detect(0);
9291
      eth_phy.collision(0);
9292
      // first destination address on ethernet PHY
9293
      eth_phy.set_tx_mem_addr(0);
9294
      // prepare BDs
9295
      if (num_of_bd == 0)
9296
      begin
9297
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
9298
        set_tx_bd(1, 1, i_length+1, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
9299
        set_tx_bd_wrap(1);
9300
        set_tx_bd_ready(0, 0);
9301
        set_tx_bd_ready(1, 1);
9302
      end
9303
      // CHECK END OF TWO TRANSMITIONs
9304
      // wait for first transmit to end
9305
      check_tx_bd(num_of_bd, data);
9306
      wait (MTxEn === 1'b1); // start transmit
9307
      if (data[15] !== 1)
9308
      begin
9309
        test_fail("Wrong buffer descriptor's ready bit read out from MAC");
9310
        fail = fail + 1;
9311
      end
9312
      wait (MTxEn === 1'b0); // end transmit
9313
      num_of_frames = num_of_frames + 1;
9314
      num_of_bd = num_of_bd + 1;
9315
      #Tp;
9316
      // destination address on ethernet PHY
9317
      eth_phy.set_tx_mem_addr(0);
9318
      i1 = 0;
9319
      i2 = 0;
9320
      // count IPG clock periods
9321
      fork
9322
        begin
9323
          wait (MTxEn === 1'b1); // start second transmit
9324
          #Tp;
9325
          disable count_rising;
9326
          disable count_falling;
9327
        end
9328
        begin: count_rising
9329
          forever
9330
          begin
9331
            @(posedge mtx_clk);
9332
            i1 = i1 + 1;
9333
            #Tp;
9334
          end
9335
        end
9336
        begin: count_falling
9337
          forever
9338
          begin
9339
            @(negedge mtx_clk);
9340
            i2 = i2 + 1;
9341
            #Tp;
9342
          end
9343
        end
9344
      join
9345
      // check IPG length - INTERMEDIATE DISPLAYS
9346
      if((i1 == i2) && (i1 >= (tmp_ipgt + 3)))
9347
      begin
9348
        $display("    ->IPG with %0d mtx_clk periods (min %0d) between packets with lengths %0d and %0d checked",
9349
                  i1, (tmp_ipgt + 3), (i_length + 4), (i_length + 4 + 1));
9350
      end
9351
      else
9352
      begin
9353
        `TIME; $display("*E IPG is not correct: (%0d + %0d) / 2, requested: %d", i1, i2, (tmp_ipgt + 3));
9354
        fail = fail + 1;
9355
        test_fail("IPG is not correct");
9356
      end
9357
      // wait for second transmit to end
9358
      wait (MTxEn === 1'b0); // end second transmit
9359
      while (data[15] === 1)
9360
      begin
9361
        check_tx_bd(num_of_bd, data);
9362
        @(posedge wb_clk);
9363
      end
9364
      repeat (1) @(posedge wb_clk);
9365
      // check length of a second PACKET
9366
      tmp_len = eth_phy.tx_len;
9367
      #1;
9368
      if (tmp_len != (i_length + 4 + 1))
9369
      begin
9370
        test_fail("Wrong length of second packet out from MAC");
9371
        fail = fail + 1;
9372
      end
9373
      // checking second packet
9374
      check_tx_packet(`MEMORY_BASE, 0, (i_length + 1), tmp);
9375
      if (tmp > 0)
9376
      begin
9377
        test_fail("Wrong data of second transmitted packet");
9378
        fail = fail + 1;
9379
      end
9380
      // check second transmited TX packet CRC
9381
      check_tx_crc(0, (i_length + 1), 1'b0, tmp); // length without CRC
9382
      if (tmp > 0)
9383
      begin
9384
        test_fail("Wrong CRC of second transmitted packet");
9385
        fail = fail + 1;
9386
      end
9387
      // check WB INT signal
9388
      if (wb_int !== 1'b1)
9389
      begin
9390
        `TIME; $display("*E WB INT signal should be set");
9391
        test_fail("WB INT signal should be set");
9392
        fail = fail + 1;
9393
      end
9394
      // check TX buffer descriptor of a packet
9395
      check_tx_bd(num_of_bd, data);
9396
      if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 1)) || // wrap bit
9397
           ((data[15:0] !== 16'h5800) && (num_of_bd < 1)) )   // without wrap bit
9398
      begin
9399
        `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
9400
        test_fail("TX buffer descriptor status is not correct");
9401
        fail = fail + 1;
9402
      end
9403
      // check interrupts
9404
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9405
      if ((data & `ETH_INT_TXB) !== 1'b1)
9406
      begin
9407
        `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
9408
        test_fail("Interrupt Transmit Buffer was not set");
9409
        fail = fail + 1;
9410
      end
9411
      if ((data & (~`ETH_INT_TXB)) !== 0)
9412
      begin
9413
        `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
9414
        test_fail("Other interrupts (except Transmit Buffer) were set");
9415
        fail = fail + 1;
9416
      end
9417
      // clear interrupts
9418
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9419
      // check WB INT signal
9420
      if (wb_int !== 1'b0)
9421
      begin
9422
        test_fail("WB INT signal should not be set");
9423
        fail = fail + 1;
9424
      end
9425
      // set length (LOOP variable)
9426
      if ((tmp_ipgt + 3) < 130) // tmp_ipgt < 124
9427
        i_length = i_length + 2;
9428
      else
9429
        i_length = (max_tmp - 4);
9430
      // set IPGT
9431
      if ((tmp_ipgt + 3) < 10)
9432
        tmp_ipgt = tmp_ipgt + 1;
9433
      else if ((tmp_ipgt + 3) < 24)
9434
        tmp_ipgt = tmp_ipgt + 7;
9435
      else if ((tmp_ipgt + 3) == 24)
9436
        tmp_ipgt = 38 - 3;
9437
      else if ((tmp_ipgt + 3) == 38)
9438
        tmp_ipgt = 72 - 3;
9439
      else if ((tmp_ipgt + 3) == 72)
9440
        tmp_ipgt = 130 - 3; // 124 - 3
9441
      // the number of frame transmitted
9442
      num_of_frames = num_of_frames + 1;
9443
      num_of_bd = 0;
9444
      @(posedge wb_clk);
9445
    end
9446
    // disable TX
9447
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
9448
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9449
    @(posedge wb_clk);
9450
    if(fail == 0)
9451
      test_ok;
9452
    else
9453
      fail = 0;
9454
  end
9455
 
9456
 
9457
  ////////////////////////////////////////////////////////////////////
9458
  ////                                                            ////
9459
  ////  Test IPG during Back-to-Back transmit at                  ////
9460
  ////  88 TX buffer decriptors ( 100Mbps ).                      ////
9461
  ////                                                            ////
9462
  ////////////////////////////////////////////////////////////////////
9463
  if (test_num == 19) // without and with padding
9464
  begin
9465
    // TEST 19: IPG DURING BACK-TO-BACK TRANSMIT AT 88 TX BDs ( 100Mbps )
9466
    test_name = "TEST 19: IPG DURING BACK-TO-BACK TRANSMIT AT 88 TX BDs ( 100Mbps )";
9467
    `TIME; $display("  TEST 19: IPG DURING BACK-TO-BACK TRANSMIT AT 88 TX BDs ( 100Mbps )");
9468
 
9469
    // reset MAC registers
9470
    hard_reset;
9471
    // reset MAC and MII LOGIC with soft reset
9472
    reset_mac;
9473
    reset_mii;
9474
    // set wb slave response
9475
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
9476
 
9477
    max_tmp = 0;
9478
    min_tmp = 0;
9479
    num_of_frames = 0;
9480
    num_of_bd = 0;
9481
    tmp_ipgt = 0;
9482
    // set 88 TX buffer descriptors - must be set before TX enable
9483
    wbm_write(`ETH_TX_BD_NUM, 32'h58, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9484
    // enable TX, set full-duplex mode, NO padding and CRC appending
9485
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
9486
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9487
    // prepare two packets of MAXFL length
9488
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9489
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
9490
    min_tmp = tmp[31:16];
9491
    st_data = 8'h29;
9492
    set_tx_packet(`MEMORY_BASE, (max_tmp - 4), st_data); // length without CRC
9493
    // check WB INT signal
9494
    if (wb_int !== 1'b0)
9495
    begin
9496
      test_fail("WB INT signal should not be set");
9497
      fail = fail + 1;
9498
    end
9499
 
9500
    // write to phy's control register for 100Mbps
9501
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
9502
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
9503
    speed = 100;
9504
 
9505
    i_length = (min_tmp - 4);
9506
    while (i_length < (max_tmp - 4))
9507
    begin
9508
      // disable TX, set full-duplex mode, NO padding and CRC appending
9509
      wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
9510
                4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9511
      // set IPGT register
9512
      wbm_write(`ETH_IPGT, tmp_ipgt, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9513
      // enable TX, set full-duplex mode, NO padding and CRC appending
9514
      wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
9515
                4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9516
      // Reset_tx_bd enable interrupt generation
9517
      // unmask interrupts
9518
      wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
9519
                               `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9520
      // not detect carrier sense in FD and no collision
9521
      eth_phy.carrier_sense_tx_fd_detect(0);
9522
      eth_phy.collision(0);
9523
      // first destination address on ethernet PHY
9524
      eth_phy.set_tx_mem_addr(0);
9525
      // prepare BDs
9526
      if (num_of_bd == 0)
9527
      begin
9528
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
9529
        set_tx_bd(1, 1, i_length+1, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
9530
        set_tx_bd_wrap(1);
9531
        set_tx_bd_ready(0, 0);
9532
        set_tx_bd_ready(1, 1);
9533
      end
9534
      // CHECK END OF TWO TRANSMITIONs
9535
      // wait for first transmit to end
9536
      check_tx_bd(num_of_bd, data);
9537
      wait (MTxEn === 1'b1); // start transmit
9538
      if (data[15] !== 1)
9539
      begin
9540
        test_fail("Wrong buffer descriptor's ready bit read out from MAC");
9541
        fail = fail + 1;
9542
      end
9543
      wait (MTxEn === 1'b0); // end transmit
9544
      num_of_frames = num_of_frames + 1;
9545
      num_of_bd = num_of_bd + 1;
9546
      #Tp;
9547
      // destination address on ethernet PHY
9548
      eth_phy.set_tx_mem_addr(0);
9549
      i1 = 0;
9550
      i2 = 0;
9551
      // count IPG clock periods
9552
      fork
9553
        begin
9554
          wait (MTxEn === 1'b1); // start second transmit
9555
          #Tp;
9556
          disable count_rising1;
9557
          disable count_falling1;
9558
        end
9559
        begin: count_rising1
9560
          forever
9561
          begin
9562
            @(posedge mtx_clk);
9563
            i1 = i1 + 1;
9564
            #Tp;
9565
          end
9566
        end
9567
        begin: count_falling1
9568
          forever
9569
          begin
9570
            @(negedge mtx_clk);
9571
            i2 = i2 + 1;
9572
            #Tp;
9573
          end
9574
        end
9575
      join
9576
      // check IPG length - INTERMEDIATE DISPLAYS
9577
      if((i1 == i2) && (i1 >= (tmp_ipgt + 3)))
9578
      begin
9579
        $display("    ->IPG with %0d mtx_clk periods (min %0d) between packets with lengths %0d and %0d checked",
9580
                  i1, (tmp_ipgt + 3), (i_length + 4), (i_length + 4 + 1));
9581
      end
9582
      else
9583
      begin
9584
        `TIME; $display("*E IPG is not correct: (%0d + %0d) / 2, requested: %d", i1, i2, (tmp_ipgt + 3));
9585
        fail = fail + 1;
9586
        test_fail("IPG is not correct");
9587
      end
9588
      // wait for second transmit to end
9589
      wait (MTxEn === 1'b0); // end second transmit
9590
      while (data[15] === 1)
9591
      begin
9592
        check_tx_bd(num_of_bd, data);
9593
        @(posedge wb_clk);
9594
      end
9595
      repeat (1) @(posedge wb_clk);
9596
      // check length of a second PACKET
9597
      tmp_len = eth_phy.tx_len;
9598
      #1;
9599
      if (tmp_len != (i_length + 4 + 1))
9600
      begin
9601
        test_fail("Wrong length of second packet out from MAC");
9602
        fail = fail + 1;
9603
      end
9604
      // checking second packet
9605
      check_tx_packet(`MEMORY_BASE, 0, (i_length + 1), tmp);
9606
      if (tmp > 0)
9607
      begin
9608
        test_fail("Wrong data of second transmitted packet");
9609
        fail = fail + 1;
9610
      end
9611
      // check second transmited TX packet CRC
9612
      check_tx_crc(0, (i_length + 1), 1'b0, tmp); // length without CRC
9613
      if (tmp > 0)
9614
      begin
9615
        test_fail("Wrong CRC of second transmitted packet");
9616
        fail = fail + 1;
9617
      end
9618
      // check WB INT signal
9619
      if (wb_int !== 1'b1)
9620
      begin
9621
        `TIME; $display("*E WB INT signal should be set");
9622
        test_fail("WB INT signal should be set");
9623
        fail = fail + 1;
9624
      end
9625
      // check TX buffer descriptor of a packet
9626
      check_tx_bd(num_of_bd, data);
9627
      if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 1)) || // wrap bit
9628
           ((data[15:0] !== 16'h5800) && (num_of_bd < 1)) )   // without wrap bit
9629
      begin
9630
        `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
9631
        test_fail("TX buffer descriptor status is not correct");
9632
        fail = fail + 1;
9633
      end
9634
      // check interrupts
9635
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9636
      if ((data & `ETH_INT_TXB) !== 1'b1)
9637
      begin
9638
        `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
9639
        test_fail("Interrupt Transmit Buffer was not set");
9640
        fail = fail + 1;
9641
      end
9642
      if ((data & (~`ETH_INT_TXB)) !== 0)
9643
      begin
9644
        `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
9645
        test_fail("Other interrupts (except Transmit Buffer) were set");
9646
        fail = fail + 1;
9647
      end
9648
      // clear interrupts
9649
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9650
      // check WB INT signal
9651
      if (wb_int !== 1'b0)
9652
      begin
9653
        test_fail("WB INT signal should not be set");
9654
        fail = fail + 1;
9655
      end
9656
      // set length (LOOP variable)
9657
      if ((tmp_ipgt + 3) < 130) // tmp_ipgt < 124
9658
        i_length = i_length + 2;
9659
      else
9660
        i_length = (max_tmp - 4);
9661
      // set IPGT
9662
      if ((tmp_ipgt + 3) < 10)
9663
        tmp_ipgt = tmp_ipgt + 1;
9664
      else if ((tmp_ipgt + 3) < 24)
9665
        tmp_ipgt = tmp_ipgt + 7;
9666
      else if ((tmp_ipgt + 3) == 24)
9667
        tmp_ipgt = 38 - 3;
9668
      else if ((tmp_ipgt + 3) == 38)
9669
        tmp_ipgt = 72 - 3;
9670
      else if ((tmp_ipgt + 3) == 72)
9671
        tmp_ipgt = 130 - 3; // 124 - 3
9672
      // the number of frame transmitted
9673
      num_of_frames = num_of_frames + 1;
9674
      num_of_bd = 0;
9675
      @(posedge wb_clk);
9676
    end
9677
    // disable TX
9678
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
9679
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9680
    @(posedge wb_clk);
9681
    if(fail == 0)
9682
      test_ok;
9683
    else
9684
      fail = 0;
9685
  end
9686
 
9687
 
9688
  ////////////////////////////////////////////////////////////////////
9689
  ////                                                            ////
9690
  ////  Test transmit packets after TX under-run on each packet's ////
9691
  ////  byte at 2 TX buffer decriptors ( 10Mbps ).                ////
9692
  ////                                                            ////
9693
  ////////////////////////////////////////////////////////////////////
9694
  if (test_num == 20) // without padding
9695
  begin
9696
    // TEST 20: TRANSMIT PACKETS AFTER TX UNDER-RUN ON EACH PACKET's BYTE AT 2 TX BDs ( 10Mbps )
9697
    test_name = "TEST 20: TRANSMIT PACKETS AFTER TX UNDER-RUN ON EACH PACKET's BYTE AT 2 TX BDs ( 10Mbps )";
9698
    `TIME;
9699
    $display("  TEST 20: TRANSMIT PACKETS AFTER TX UNDER-RUN ON EACH PACKET's BYTE AT 2 TX BDs ( 10Mbps )");
9700
 
9701
    // reset MAC registers
9702
    hard_reset;
9703
    // reset MAC and MII LOGIC with soft reset
9704
    reset_mac;
9705
    reset_mii;
9706
    // set wb slave response
9707
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
9708
 
9709
    max_tmp = 0;
9710
    min_tmp = 0;
9711
    // set 2 TX buffer descriptors - must be set before TX enable
9712
    wbm_write(`ETH_TX_BD_NUM, 32'h2, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9713
    // enable TX, set full-duplex mode, NO padding and CRC appending
9714
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN |/* `ETH_MODER_PAD |*/ `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
9715
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9716
    // prepare a packet of MAXFL length
9717
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9718
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
9719
    min_tmp = tmp[31:16];
9720
    st_data = 8'h99;
9721
    set_tx_packet(`MEMORY_BASE, (max_tmp - 4), st_data); // length without CRC
9722
    // read IPG value
9723
    wbm_read(`ETH_IPGT, tmp_ipgt, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9724
    // check WB INT signal
9725
    if (wb_int !== 1'b0)
9726
    begin
9727
      test_fail("WB INT signal should not be set");
9728
      fail = fail + 1;
9729
    end
9730
 
9731
    // write to phy's control register for 10Mbps
9732
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
9733
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
9734
    speed = 10;
9735
 
9736
    num_of_frames = 0; // (0..3) => start under-run on first word
9737
    num_of_bd = 0;
9738
    i_data = 3; // (3) => one BYTE read in first word - FIRST byte
9739
    i_length = (min_tmp + 4);
9740
    while (i_length < (max_tmp - 4))
9741
    begin
9742
      // Reset_tx_bd enable interrupt generation
9743
      // unmask interrupts
9744
      wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
9745
                               `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9746
      // not detect carrier sense in FD and no collision
9747
      eth_phy.carrier_sense_tx_fd_detect(0);
9748
      eth_phy.collision(0);
9749
      // first destination address on ethernet PHY
9750
      eth_phy.set_tx_mem_addr(0);
9751
      // prepare BDs
9752
      if (num_of_bd == 0)
9753
      begin
9754
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, (`MEMORY_BASE + i_data[1:0]));
9755
        set_tx_bd(1, 1, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
9756
        set_tx_bd_wrap(1);
9757
        // set wb slave response: ACK (response), wbs_waits[2:0] (waits before response), 
9758
        //                       wbs_retries[7:0] (RTYs before ACK if RTY response selected)
9759
        #1 wb_slave.cycle_response(`ACK_RESPONSE, 3'h2, 8'h0);
9760
        set_tx_bd_ready(1, 1);
9761
        set_tx_bd_ready(0, 0);
9762
      end
9763
      // frame under-run checking
9764
      frame_started = 0;
9765
      frame_ended = 0;
9766
      wait_for_frame = 0;
9767
      fork
9768
        begin
9769
          // for every 4 frames bytes 1, 2, 3 and 4 respectively are read in first word => 1 ACK
9770
          // in other words 4 bytes are read, since length is MINFL => num_of_frames[31:2] ACKs
9771
          repeat ((num_of_frames[31:2] + 1'b1)) @(posedge eth_ma_wb_ack_i);
9772
          @(negedge eth_ma_wb_ack_i); // wait for last ACK to finish
9773
          // set wb slave response: ACK (response), wbs_waits[2:0] (waits before response), 
9774
          //                       wbs_retries[7:0] (RTYs before ACK if RTY response selected)
9775
          #1 wb_slave.cycle_response(`NO_RESPONSE, 3'h7, 8'hFF);
9776
          // wait for synchronization and some additional clocks
9777
          wait_for_frame = 1;
9778
          // wait for frame
9779
          wait ((wait_for_frame == 0) || (frame_started == 1))
9780
          if ((wait_for_frame == 0) && (frame_started == 0)) // frame didn't start
9781
          begin
9782
            disable check_fr;
9783
          end
9784
          else if ((wait_for_frame == 1) && (frame_started == 1)) // frame started
9785
          begin
9786
            disable wait_fr;
9787
            wait (frame_ended == 1);
9788
          end
9789
          repeat (2) @(posedge wb_clk);
9790
          // set wb slave response: ACK (response), wbs_waits[2:0] (waits before response), 
9791
          //                       wbs_retries[7:0] (RTYs before ACK if RTY response selected)
9792
          wb_slave.cycle_response(`ACK_RESPONSE, 3'h2, 8'h0);
9793
        end
9794
        begin: wait_fr
9795
          wait (wait_for_frame == 1)
9796
          begin
9797
            // wait for synchronization and some additional clocks
9798
            repeat (3) @(posedge wb_clk);
9799
            repeat (2 * tmp_ipgt) @(posedge mtx_clk);
9800
            repeat (2) @(posedge wb_clk);
9801
            repeat (2) @(posedge mtx_clk);
9802
            wait_for_frame = 0;
9803
          end
9804
        end
9805
        begin: check_fr
9806
          // wait for frame to start
9807
          @(posedge MTxEn);
9808
          frame_started = 1;
9809
$display("  Under-run (on %0d. byte) frame started", (num_of_frames + 1));
9810
          // wait for frame to end due to under-run
9811
          @(negedge MTxEn);
9812
          frame_ended = 1;
9813
$display("  Under-run frame ended");
9814
        end
9815
      join
9816
      // wait for first transmit to end, if under-run didn't happen
9817
      if (frame_ended == 0)
9818
      begin
9819
        // WAIT FOR FIRST TRANSMIT
9820
        check_tx_bd(num_of_bd, data);
9821
        wait (MTxEn === 1'b1); // start first transmit
9822
        if (data[15] !== 1)
9823
        begin
9824
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
9825
          fail = fail + 1;
9826
        end
9827
        wait (MTxEn === 1'b0); // end first transmit
9828
        while (data[15] === 1)
9829
        begin
9830
          check_tx_bd(num_of_bd, data);
9831
          @(posedge wb_clk);
9832
        end
9833
        repeat (1) @(posedge wb_clk);
9834
        // CHECK FIRST FRAME
9835
        // check length of a first PACKET
9836
        tmp_len = eth_phy.tx_len;
9837
        #1;
9838
        if (tmp_len != (i_length + 4))
9839
        begin
9840
          test_fail("Wrong length of second packet out from MAC");
9841
          fail = fail + 1;
9842
        end
9843
        // checking first packet
9844
        check_tx_packet((`MEMORY_BASE + i_data[1:0]), 0, (i_length), tmp);
9845
        if (tmp > 0)
9846
        begin
9847
          test_fail("Wrong data of second transmitted packet");
9848
          fail = fail + 1;
9849
        end
9850
        // check first transmited TX packet CRC
9851
        check_tx_crc(0, (i_length), 1'b0, tmp); // length without CRC
9852
        if (tmp > 0)
9853
        begin
9854
          test_fail("Wrong CRC of second transmitted packet");
9855
          fail = fail + 1;
9856
        end
9857
        // check WB INT signal
9858
        if (wb_int !== 1'b1)
9859
        begin
9860
          `TIME; $display("*E WB INT signal should be set");
9861
          test_fail("WB INT signal should be set");
9862
          fail = fail + 1;
9863
        end
9864
        // check TX buffer descriptor of a packet
9865
        check_tx_bd(num_of_bd, data);
9866
        if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 1)) || // wrap bit
9867
             ((data[15:0] !== 16'h5800) && (num_of_bd < 1)) )   // without wrap bit
9868
        begin
9869
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
9870
          test_fail("TX buffer descriptor status is not correct");
9871
          fail = fail + 1;
9872
        end
9873
        // check interrupts
9874
        wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9875
        if ((data & `ETH_INT_TXB) !== 1'b1)
9876
        begin
9877
          `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
9878
          test_fail("Interrupt Transmit Buffer was not set");
9879
          fail = fail + 1;
9880
        end
9881
        if ((data & (~`ETH_INT_TXB)) !== 0)
9882
        begin
9883
          `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
9884
          test_fail("Other interrupts (except Transmit Buffer) were set");
9885
          fail = fail + 1;
9886
        end
9887
        // clear interrupts
9888
        wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9889
        // check WB INT signal
9890
        if (wb_int !== 1'b0)
9891
        begin
9892
          test_fail("WB INT signal should not be set");
9893
          fail = fail + 1;
9894
        end
9895
      end
9896
      num_of_bd = num_of_bd + 1;
9897
      // destination address on ethernet PHY
9898
      eth_phy.set_tx_mem_addr(0);
9899
      // WAIT FOR FIRST TRANSMIT
9900
      check_tx_bd(num_of_bd, data);
9901
      wait (MTxEn === 1'b1); // start first transmit
9902
      if (data[15] !== 1)
9903
      begin
9904
        test_fail("Wrong buffer descriptor's ready bit read out from MAC");
9905
        fail = fail + 1;
9906
      end
9907
      wait (MTxEn === 1'b0); // end first transmit
9908
      while (data[15] === 1)
9909
      begin
9910
        check_tx_bd(num_of_bd, data);
9911
        @(posedge wb_clk);
9912
      end
9913
      repeat (1) @(posedge wb_clk);
9914
      // CHECK SECOND FRAME
9915
      // check length of a second PACKET
9916
      tmp_len = eth_phy.tx_len;
9917
      #1;
9918
      if (tmp_len != (i_length + 4))
9919
      begin
9920
        test_fail("Wrong length of second packet out from MAC");
9921
        fail = fail + 1;
9922
      end
9923
      // checking second packet
9924
      check_tx_packet(`MEMORY_BASE, 0, (i_length), tmp);
9925
      if (tmp > 0)
9926
      begin
9927
        test_fail("Wrong data of second transmitted packet");
9928
        fail = fail + 1;
9929
      end
9930
      // check second transmited TX packet CRC
9931
      check_tx_crc(0, (i_length), 1'b0, tmp); // length without CRC
9932
      if (tmp > 0)
9933
      begin
9934
        test_fail("Wrong CRC of second transmitted packet");
9935
        fail = fail + 1;
9936
      end
9937
      // check WB INT signal
9938
      if (wb_int !== 1'b1)
9939
      begin
9940
        `TIME; $display("*E WB INT signal should be set");
9941
        test_fail("WB INT signal should be set");
9942
        fail = fail + 1;
9943
      end
9944
      // check TX buffer descriptor of a packet
9945
      check_tx_bd(num_of_bd, data);
9946
      if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 1)) || // wrap bit
9947
           ((data[15:0] !== 16'h5800) && (num_of_bd < 1)) )   // without wrap bit
9948
      begin
9949
        `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
9950
        test_fail("TX buffer descriptor status is not correct");
9951
        fail = fail + 1;
9952
      end
9953
      // check interrupts
9954
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9955
      if ((data & `ETH_INT_TXB) !== 1'b1)
9956
      begin
9957
        `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
9958
        test_fail("Interrupt Transmit Buffer was not set");
9959
        fail = fail + 1;
9960
      end
9961
      if ((data & (~`ETH_INT_TXB)) !== 0)
9962
      begin
9963
        `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
9964
        test_fail("Other interrupts (except Transmit Buffer) were set");
9965
        fail = fail + 1;
9966
      end
9967
      // clear interrupts
9968
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9969
      // check WB INT signal
9970
      if (wb_int !== 1'b0)
9971
      begin
9972
        test_fail("WB INT signal should not be set");
9973
        fail = fail + 1;
9974
      end
9975
      // set initial value
9976
      i_data = i_data - 1;
9977
      // the number of frame transmitted
9978
      num_of_frames = num_of_frames + 1;
9979
      num_of_bd = 0;
9980
      // set length (LOOP variable)
9981
      if (num_of_frames == i_length + 4) // 64 => this vas last Byte (1st .. 64th) when i_length = min_tmp - 4
9982
        i_length = (max_tmp - 4);
9983
      @(posedge wb_clk);
9984
    end
9985
    // disable TX
9986
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
9987
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9988
    @(posedge wb_clk);
9989
    if(fail == 0)
9990
      test_ok;
9991
    else
9992
      fail = 0;
9993
  end
9994
 
9995
 
9996
  ////////////////////////////////////////////////////////////////////
9997
  ////                                                            ////
9998
  ////  Test transmit packets after TX under-run on each packet's ////
9999
  ////  byte at 2 TX buffer decriptors ( 100Mbps ).               ////
10000
  ////                                                            ////
10001
  ////////////////////////////////////////////////////////////////////
10002
  if (test_num == 21) // without padding
10003
  begin
10004
    // TEST 21: TRANSMIT PACKETS AFTER TX UNDER-RUN ON EACH PACKET's BYTE AT 2 TX BDs ( 100Mbps )
10005
    test_name = "TEST 21: TRANSMIT PACKETS AFTER TX UNDER-RUN ON EACH PACKET's BYTE AT 2 TX BDs ( 100Mbps )";
10006
    `TIME;
10007
    $display("  TEST 21: TRANSMIT PACKETS AFTER TX UNDER-RUN ON EACH PACKET's BYTE AT 2 TX BDs ( 100Mbps )");
10008
 
10009
    // reset MAC registers
10010
    hard_reset;
10011
    // reset MAC and MII LOGIC with soft reset
10012
    reset_mac;
10013
    reset_mii;
10014
    // set wb slave response
10015
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
10016
 
10017
    max_tmp = 0;
10018
    min_tmp = 0;
10019
    // set 2 TX buffer descriptors - must be set before TX enable
10020
    wbm_write(`ETH_TX_BD_NUM, 32'h2, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10021
    // enable TX, set full-duplex mode, NO padding and CRC appending
10022
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN |/* `ETH_MODER_PAD |*/ `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
10023
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10024
    // prepare a packet of MAXFL length
10025
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10026
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
10027
    min_tmp = tmp[31:16];
10028
    st_data = 8'h99;
10029
    set_tx_packet(`MEMORY_BASE, (max_tmp - 4), st_data); // length without CRC
10030
    // read IPG value
10031
    wbm_read(`ETH_IPGT, tmp_ipgt, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10032
    // check WB INT signal
10033
    if (wb_int !== 1'b0)
10034
    begin
10035
      test_fail("WB INT signal should not be set");
10036
      fail = fail + 1;
10037
    end
10038
 
10039
    // write to phy's control register for 100Mbps
10040
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
10041
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
10042
    speed = 100;
10043
 
10044
    num_of_frames = 0; // (0..3) => start under-run on first word
10045
    num_of_bd = 0;
10046
    i_data = 3; // (3) => one BYTE read in first word - FIRST byte
10047
    i_length = (min_tmp + 4);
10048
    while (i_length < (max_tmp - 4))
10049
    begin
10050
      // Reset_tx_bd enable interrupt generation
10051
      // unmask interrupts
10052
      wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
10053
                               `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10054
      // not detect carrier sense in FD and no collision
10055
      eth_phy.carrier_sense_tx_fd_detect(0);
10056
      eth_phy.collision(0);
10057
      // first destination address on ethernet PHY
10058
      eth_phy.set_tx_mem_addr(0);
10059
      // prepare BDs
10060
      if (num_of_bd == 0)
10061
      begin
10062
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, (`MEMORY_BASE + i_data[1:0]));
10063
        set_tx_bd(1, 1, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
10064
        set_tx_bd_wrap(1);
10065
        // set wb slave response: ACK (response), wbs_waits[2:0] (waits before response), 
10066
        //                       wbs_retries[7:0] (RTYs before ACK if RTY response selected)
10067
        #1 wb_slave.cycle_response(`ACK_RESPONSE, 3'h2, 8'h0);
10068
        set_tx_bd_ready(1, 1);
10069
        set_tx_bd_ready(0, 0);
10070
      end
10071
      // frame under-run checking
10072
      frame_started = 0;
10073
      frame_ended = 0;
10074
      wait_for_frame = 0;
10075
      fork
10076
        begin
10077
          // for every 4 frames bytes 1, 2, 3 and 4 respectively are read in first word => 1 ACK
10078
          // in other words 4 bytes are read, since length is MINFL => num_of_frames[31:2] ACKs
10079
          repeat ((num_of_frames[31:2] + 1'b1)) @(posedge eth_ma_wb_ack_i);
10080
          @(negedge eth_ma_wb_ack_i); // wait for last ACK to finish
10081
          // set wb slave response: ACK (response), wbs_waits[2:0] (waits before response), 
10082
          //                       wbs_retries[7:0] (RTYs before ACK if RTY response selected)
10083
          #1 wb_slave.cycle_response(`NO_RESPONSE, 3'h7, 8'hFF);
10084
          // wait for synchronization and some additional clocks
10085
          wait_for_frame = 1;
10086
          // wait for frame
10087
          wait ((wait_for_frame == 0) || (frame_started == 1))
10088
          if ((wait_for_frame == 0) && (frame_started == 0)) // frame didn't start
10089
          begin
10090
            disable check_fr1;
10091
          end
10092
          else if ((wait_for_frame == 1) && (frame_started == 1)) // frame started
10093
          begin
10094
            disable wait_fr1;
10095
            wait (frame_ended == 1);
10096
          end
10097
          repeat (2) @(posedge wb_clk);
10098
          // set wb slave response: ACK (response), wbs_waits[2:0] (waits before response), 
10099
          //                       wbs_retries[7:0] (RTYs before ACK if RTY response selected)
10100
          wb_slave.cycle_response(`ACK_RESPONSE, 3'h2, 8'h0);
10101
        end
10102
        begin: wait_fr1
10103
          wait (wait_for_frame == 1)
10104
          begin
10105
            // wait for synchronization and some additional clocks
10106
            repeat (3) @(posedge wb_clk);
10107
            repeat (2 * tmp_ipgt) @(posedge mtx_clk);
10108
            repeat (2) @(posedge wb_clk);
10109
            repeat (2) @(posedge mtx_clk);
10110
            wait_for_frame = 0;
10111
          end
10112
        end
10113
        begin: check_fr1
10114
          // wait for frame to start
10115
          @(posedge MTxEn);
10116
          frame_started = 1;
10117
$display("  Under-run (on %0d. byte) frame started", (num_of_frames + 1));
10118
          // wait for frame to end due to under-run
10119
          @(negedge MTxEn);
10120
          frame_ended = 1;
10121
$display("  Under-run frame ended");
10122
        end
10123
      join
10124
      // wait for first transmit to end, if under-run didn't happen
10125
      if (frame_ended == 0)
10126
      begin
10127
        // WAIT FOR FIRST TRANSMIT
10128
        check_tx_bd(num_of_bd, data);
10129
        wait (MTxEn === 1'b1); // start first transmit
10130
        if (data[15] !== 1)
10131
        begin
10132
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
10133
          fail = fail + 1;
10134
        end
10135
        wait (MTxEn === 1'b0); // end first transmit
10136
        while (data[15] === 1)
10137
        begin
10138
          check_tx_bd(num_of_bd, data);
10139
          @(posedge wb_clk);
10140
        end
10141
        repeat (1) @(posedge wb_clk);
10142
        // CHECK FIRST FRAME
10143
        // check length of a first PACKET
10144
        tmp_len = eth_phy.tx_len;
10145
        #1;
10146
        if (tmp_len != (i_length + 4))
10147
        begin
10148
          test_fail("Wrong length of second packet out from MAC");
10149
          fail = fail + 1;
10150
        end
10151
        // checking first packet
10152
        check_tx_packet((`MEMORY_BASE + i_data[1:0]), 0, (i_length), tmp);
10153
        if (tmp > 0)
10154
        begin
10155
          test_fail("Wrong data of second transmitted packet");
10156
          fail = fail + 1;
10157
        end
10158
        // check first transmited TX packet CRC
10159
        check_tx_crc(0, (i_length), 1'b0, tmp); // length without CRC
10160
        if (tmp > 0)
10161
        begin
10162
          test_fail("Wrong CRC of second transmitted packet");
10163
          fail = fail + 1;
10164
        end
10165
        // check WB INT signal
10166
        if (wb_int !== 1'b1)
10167
        begin
10168
          `TIME; $display("*E WB INT signal should be set");
10169
          test_fail("WB INT signal should be set");
10170
          fail = fail + 1;
10171
        end
10172
        // check TX buffer descriptor of a packet
10173
        check_tx_bd(num_of_bd, data);
10174
        if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 1)) || // wrap bit
10175
             ((data[15:0] !== 16'h5800) && (num_of_bd < 1)) )   // without wrap bit
10176
        begin
10177
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
10178
          test_fail("TX buffer descriptor status is not correct");
10179
          fail = fail + 1;
10180
        end
10181
        // check interrupts
10182
        wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10183
        if ((data & `ETH_INT_TXB) !== 1'b1)
10184
        begin
10185
          `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
10186
          test_fail("Interrupt Transmit Buffer was not set");
10187
          fail = fail + 1;
10188
        end
10189
        if ((data & (~`ETH_INT_TXB)) !== 0)
10190
        begin
10191
          `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
10192
          test_fail("Other interrupts (except Transmit Buffer) were set");
10193
          fail = fail + 1;
10194
        end
10195
        // clear interrupts
10196
        wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10197
        // check WB INT signal
10198
        if (wb_int !== 1'b0)
10199
        begin
10200
          test_fail("WB INT signal should not be set");
10201
          fail = fail + 1;
10202
        end
10203
      end
10204
      num_of_bd = num_of_bd + 1;
10205
      // destination address on ethernet PHY
10206
      eth_phy.set_tx_mem_addr(0);
10207
      // WAIT FOR FIRST TRANSMIT
10208
      check_tx_bd(num_of_bd, data);
10209
      wait (MTxEn === 1'b1); // start first transmit
10210
      if (data[15] !== 1)
10211
      begin
10212
        test_fail("Wrong buffer descriptor's ready bit read out from MAC");
10213
        fail = fail + 1;
10214
      end
10215
      wait (MTxEn === 1'b0); // end first transmit
10216
      while (data[15] === 1)
10217
      begin
10218
        check_tx_bd(num_of_bd, data);
10219
        @(posedge wb_clk);
10220
      end
10221
      repeat (1) @(posedge wb_clk);
10222
      // CHECK SECOND FRAME
10223
      // check length of a second PACKET
10224
      tmp_len = eth_phy.tx_len;
10225
      #1;
10226
      if (tmp_len != (i_length + 4))
10227
      begin
10228
        test_fail("Wrong length of second packet out from MAC");
10229
        fail = fail + 1;
10230
      end
10231
      // checking second packet
10232
      check_tx_packet(`MEMORY_BASE, 0, (i_length), tmp);
10233
      if (tmp > 0)
10234
      begin
10235
        test_fail("Wrong data of second transmitted packet");
10236
        fail = fail + 1;
10237
      end
10238
      // check second transmited TX packet CRC
10239
      check_tx_crc(0, (i_length), 1'b0, tmp); // length without CRC
10240
      if (tmp > 0)
10241
      begin
10242
        test_fail("Wrong CRC of second transmitted packet");
10243
        fail = fail + 1;
10244
      end
10245
      // check WB INT signal
10246
      if (wb_int !== 1'b1)
10247
      begin
10248
        `TIME; $display("*E WB INT signal should be set");
10249
        test_fail("WB INT signal should be set");
10250
        fail = fail + 1;
10251
      end
10252
      // check TX buffer descriptor of a packet
10253
      check_tx_bd(num_of_bd, data);
10254
      if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 1)) || // wrap bit
10255
           ((data[15:0] !== 16'h5800) && (num_of_bd < 1)) )   // without wrap bit
10256
      begin
10257
        `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
10258
        test_fail("TX buffer descriptor status is not correct");
10259
        fail = fail + 1;
10260
      end
10261
      // check interrupts
10262
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10263
      if ((data & `ETH_INT_TXB) !== 1'b1)
10264
      begin
10265
        `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
10266
        test_fail("Interrupt Transmit Buffer was not set");
10267
        fail = fail + 1;
10268
      end
10269
      if ((data & (~`ETH_INT_TXB)) !== 0)
10270
      begin
10271
        `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
10272
        test_fail("Other interrupts (except Transmit Buffer) were set");
10273
        fail = fail + 1;
10274
      end
10275
      // clear interrupts
10276
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10277
      // check WB INT signal
10278
      if (wb_int !== 1'b0)
10279
      begin
10280
        test_fail("WB INT signal should not be set");
10281
        fail = fail + 1;
10282
      end
10283
      // set initial value
10284
      i_data = i_data - 1;
10285
      // the number of frame transmitted
10286
      num_of_frames = num_of_frames + 1;
10287
      num_of_bd = 0;
10288
      // set length (LOOP variable)
10289
      if (num_of_frames == i_length + 4) // 64 => this vas last Byte (1st .. 64th) when i_length = min_tmp - 4
10290
        i_length = (max_tmp - 4);
10291
      @(posedge wb_clk);
10292
    end
10293
    // disable TX
10294
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
10295
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10296
    @(posedge wb_clk);
10297
    if(fail == 0)
10298
      test_ok;
10299
    else
10300
      fail = 0;
10301
  end
10302
 
10303 169 mohor
/*
10304
          wbm_write(`ETH_MODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10305
          wbm_read(`ETH_MODER, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10306 116 mohor
 
10307 169 mohor
          wbm_write(32'hd0000000, `ETH_MODER_RXEN  | `ETH_MODER_TXEN | `ETH_MODER_PRO | `ETH_MODER_CRCEN |
10308
                    `ETH_MODER_PAD, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10309
          wbm_read(32'hd0000000, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10310
 
10311
 
10312
 
10313 116 mohor
 
10314 169 mohor
          set_tx_bd(3);
10315
          set_rx_bd(6);
10316
 
10317
          set_tx_packet(16'h34, 8'h1);
10318
          set_tx_packet(16'h34, 8'h11);
10319
          send_tx_packet;
10320
          set_tx_packet(16'h34, 8'h21);
10321
          set_tx_packet(16'h34, 8'h31);
10322
          send_tx_packet;
10323 116 mohor
 
10324
 
10325 169 mohor
          eth_phy.GetDataOnMRxD(100, `BROADCAST_XFR); // LengthRx bytes is comming on MRxD[3:0] signals
10326
          repeat (100) @(posedge mrx_clk);   // Waiting for TxEthMac to finish transmit
10327
 
10328
          eth_phy.GetDataOnMRxD(70, `BROADCAST_XFR); // LengthRx bytes is comming on MRxD[3:0] signals
10329
          repeat (10000) @(posedge wb_clk);   // Waiting for TxEthMac to finish transmit
10330
 
10331
          eth_phy.GetDataOnMRxD(70, `MULTICAST_XFR); // LengthRx bytes is comming on MRxD[3:0] signals
10332
          repeat (10000) @(posedge wb_clk);   // Waiting for TxEthMac to finish transmit
10333
*/
10334
 
10335 194 tadej
end   //  for (test_num=start_task; test_num <= end_task; test_num=test_num+1)
10336 169 mohor
 
10337
end
10338
endtask // test_mac_full_duplex_transmit
10339
 
10340
 
10341 209 tadejm
task test_mac_full_duplex_receive;
10342
  input  [31:0]  start_task;
10343
  input  [31:0]  end_task;
10344
  integer        bit_start_1;
10345
  integer        bit_end_1;
10346
  integer        bit_start_2;
10347
  integer        bit_end_2;
10348
  integer        num_of_reg;
10349
  integer        num_of_frames;
10350
  integer        num_of_bd;
10351
  integer        i_addr;
10352
  integer        i_data;
10353
  integer        i_length;
10354
  integer        tmp_len;
10355
  integer        tmp_bd;
10356
  integer        tmp_bd_num;
10357
  integer        tmp_data;
10358
  integer        tmp_ipgt;
10359
  integer        test_num;
10360
  reg    [31:0]  tx_bd_num;
10361
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_data;
10362
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_tmp_data;
10363
  integer        i;
10364
  integer        i1;
10365
  integer        i2;
10366
  integer        i3;
10367
  integer        fail;
10368
  integer        speed;
10369
  reg            frame_started;
10370
  reg            frame_ended;
10371
  reg            wait_for_frame;
10372
  reg    [31:0]  addr;
10373
  reg    [31:0]  data;
10374
  reg    [31:0]  tmp;
10375
  reg    [ 7:0]  st_data;
10376
  reg    [15:0]  max_tmp;
10377
  reg    [15:0]  min_tmp;
10378
begin
10379
// MAC FULL DUPLEX RECEIVE TEST
10380
test_heading("MAC FULL DUPLEX RECEIVE TEST");
10381
$display(" ");
10382
$display("MAC FULL DUPLEX RECEIVE TEST");
10383
fail = 0;
10384
 
10385
// reset MAC registers
10386
hard_reset;
10387
// reset MAC and MII LOGIC with soft reset
10388
reset_mac;
10389
reset_mii;
10390
// set wb slave response
10391
wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
10392
 
10393
  /*
10394
  TASKS for set and control TX buffer descriptors (also send packet - set_tx_bd_ready):
10395
  -------------------------------------------------------------------------------------
10396
  set_tx_bd
10397
    (tx_bd_num_start[6:0], tx_bd_num_end[6:0], len[15:0], irq, pad, crc, txpnt[31:0]);
10398
  set_tx_bd_wrap
10399
    (tx_bd_num_end[6:0]);
10400
  set_tx_bd_ready
10401
    (tx_bd_num_start[6:0], tx_bd_num_end[6:0]);
10402
  check_tx_bd
10403
    (tx_bd_num_start[6:0], tx_bd_status[31:0]);
10404
  clear_tx_bd
10405
    (tx_bd_num_start[6:0], tx_bd_num_end[6:0]);
10406
 
10407
  TASKS for set and control RX buffer descriptors:
10408
  ------------------------------------------------
10409
  set_rx_bd
10410
    (rx_bd_num_strat[6:0], rx_bd_num_end[6:0], irq, rxpnt[31:0]);
10411
  set_rx_bd_wrap
10412
    (rx_bd_num_end[6:0]);
10413
  set_rx_bd_empty
10414
    (rx_bd_num_strat[6:0], rx_bd_num_end[6:0]);
10415
  check_rx_bd
10416
    (rx_bd_num_end[6:0], rx_bd_status);
10417
  clear_rx_bd
10418
    (rx_bd_num_strat[6:0], rx_bd_num_end[6:0]);
10419
 
10420
  TASKS for set and check TX packets:
10421
  -----------------------------------
10422
  set_tx_packet
10423
    (txpnt[31:0], len[15:0], eth_start_data[7:0]);
10424
  check_tx_packet
10425
    (txpnt_wb[31:0], txpnt_phy[31:0], len[15:0], failure[31:0]);
10426
 
10427
  TASKS for set and check RX packets:
10428
  -----------------------------------
10429
  set_rx_packet
10430
    (rxpnt[31:0], len[15:0], plus_nibble, d_addr[47:0], s_addr[47:0], type_len[15:0], start_data[7:0]);
10431
  check_rx_packet
10432
    (rxpnt_phy[31:0], rxpnt_wb[31:0], len[15:0], plus_nibble, successful_nibble, failure[31:0]);
10433
 
10434
  TASKS for append and check CRC to/of TX packet:
10435
  -----------------------------------------------
10436
  append_tx_crc
10437
    (txpnt_wb[31:0], len[15:0], negated_crc);
10438
  check_tx_crc
10439
    (txpnt_phy[31:0], len[15:0], negated_crc, failure[31:0]);
10440
 
10441
  TASK for append CRC to RX packet (CRC is checked together with check_rx_packet):
10442
  --------------------------------------------------------------------------------
10443
  append_rx_crc
10444
    (rxpnt_phy[31:0], len[15:0], plus_nibble, negated_crc);
10445
  */
10446
 
10447
//////////////////////////////////////////////////////////////////////
10448
////                                                              ////
10449
////  test_mac_full_duplex_receive:                               ////
10450
////                                                              ////
10451
////  0: Test no receive when all buffers are TX ( 10Mbps ).      ////
10452
////  1: Test no receive when all buffers are TX ( 100Mbps ).     ////
10453
////  2: Test receive packets form MINFL to MAXFL sizes at        ////
10454
////     one RX buffer decriptor ( 10Mbps ).                      ////
10455
////  3: Test receive packets form MINFL to MAXFL sizes at        ////
10456
////     one RX buffer decriptor ( 100Mbps ).                     ////
10457
////                                                              ////
10458
//////////////////////////////////////////////////////////////////////
10459
for (test_num = start_task; test_num <= end_task; test_num = test_num + 1)
10460
begin
10461
 
10462
  ////////////////////////////////////////////////////////////////////
10463
  ////                                                            ////
10464
  ////  Test no receive when all buffers are TX ( 10Mbps ).       ////
10465
  ////                                                            ////
10466
  ////////////////////////////////////////////////////////////////////
10467
  if (test_num == 0) // Test no receive when all buffers are TX ( 10Mbps ).
10468
  begin
10469
    // TEST 0: NO RECEIVE WHEN ALL BUFFERS ARE TX ( 10Mbps )
10470
    test_name   = "TEST 0: NO RECEIVE WHEN ALL BUFFERS ARE TX ( 10Mbps )";
10471
    `TIME; $display("  TEST 0: NO RECEIVE WHEN ALL BUFFERS ARE TX ( 10Mbps )");
10472
 
10473
    // unmask interrupts
10474
    wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
10475
                             `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10476
    // set all buffer descriptors to TX - must be set before RX enable
10477
    wbm_write(`ETH_TX_BD_NUM, 32'h80, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10478
    // enable RX, set full-duplex mode, padding and CRC appending
10479
    wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_IFG |
10480
              `ETH_MODER_PRO | `ETH_MODER_BRO,
10481
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10482
 
10483
    // write to phy's control register for 10Mbps
10484
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
10485
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
10486
    speed = 10;
10487
 
10488
    i = 0;
10489
    while (i < 128)
10490
    begin
10491
      for (i1 = 0; i1 <= i; i1 = i1 + 1)
10492
      begin
10493
        set_rx_packet((i1 * 50), 10, 1'b0, 48'h1234_5678_8765, 48'h0011_2233_4455, 16'h0101, 8'h0);
10494
        append_rx_crc((i1 * 50), 10, 1'b0, 1'b0);
10495
        set_rx_bd(i1, i1, 1'b1, (`MEMORY_BASE + (i1 * 50)));
10496
      end
10497
      set_rx_bd_wrap(i);
10498
      set_rx_bd_empty(0, i);
10499
      for (i1 = 0; i1 <= i; i1 = i1 + 1)
10500
      begin
10501
        #1 eth_phy.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, 8'hD5, (i1 * 50), 14, 1'b0);
10502
        repeat(10) @(posedge mrx_clk);
10503
      end
10504
      @(posedge mrx_clk);
10505
      for (i2 = 0; i2 < 20; i2 = i2 + 1)
10506
      begin
10507
        check_rx_bd(0, tmp);
10508
        #1;
10509
        if (tmp[15] === 1'b0)
10510
        begin
10511
          test_fail("Receive should not start at all");
10512
          fail = fail + 1;
10513
          `TIME; $display("*E Receive of %d packets should not start at all - empty is 0", i);
10514
        end
10515
        if (tmp[7:0] !== 0)
10516
        begin
10517
          test_fail("Receive should not be finished since it should not start at all");
10518
          fail = fail + 1;
10519
          `TIME; $display("*E Receive of should not be finished since it should not start at all");
10520
        end
10521
        @(posedge wb_clk);
10522
      end
10523
      wbm_read(`ETH_INT, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10524
      if (tmp[6:0] !== 0)
10525
      begin
10526
        test_fail("Receive should not get INT since it should not start at all");
10527
        fail = fail + 1;
10528
        `TIME; $display("*E Receive of should not get INT since it should not start at all");
10529
      end
10530
      clear_rx_bd(0, i);
10531
      if ((i < 5) || (i > 124))
10532
        i = i + 1;
10533
      else
10534
        i = i + 120;
10535
    end
10536
    // disable RX
10537
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_IFG |
10538
              `ETH_MODER_PRO | `ETH_MODER_BRO,
10539
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10540
    if(fail == 0)
10541
      test_ok;
10542
    else
10543
      fail = 0;
10544
  end
10545
 
10546
 
10547
  ////////////////////////////////////////////////////////////////////
10548
  ////                                                            ////
10549
  ////  Test no receive when all buffers are TX ( 100Mbps ).      ////
10550
  ////                                                            ////
10551
  ////////////////////////////////////////////////////////////////////
10552
  if (test_num == 1) // Test no receive when all buffers are TX ( 100Mbps ).
10553
  begin
10554
    // TEST 1: NO RECEIVE WHEN ALL BUFFERS ARE TX ( 100Mbps )
10555
    test_name   = "TEST 1: NO RECEIVE WHEN ALL BUFFERS ARE TX ( 100Mbps )";
10556
    `TIME; $display("  TEST 1: NO RECEIVE WHEN ALL BUFFERS ARE TX ( 100Mbps )");
10557
 
10558
    // unmask interrupts
10559
    wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
10560
                             `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10561
    // set all buffer descriptors to TX - must be set before RX enable
10562
    wbm_write(`ETH_TX_BD_NUM, 32'h80, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10563
    // enable RX, set full-duplex mode, padding and CRC appending
10564
    wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_IFG |
10565
              `ETH_MODER_PRO | `ETH_MODER_BRO,
10566
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10567
 
10568
    // write to phy's control register for 100Mbps
10569
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
10570
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
10571
    speed = 100;
10572
 
10573
    i = 0;
10574
    while (i < 128)
10575
    begin
10576
      for (i1 = 0; i1 <= i; i1 = i1 + 1)
10577
      begin
10578
        set_rx_packet((i1 * 50), 10, 1'b0, 48'h1234_5678_8765, 48'h0011_2233_4455, 16'h0101, 8'h0);
10579
        append_rx_crc((i1 * 50), 10, 1'b0, 1'b0);
10580
        set_rx_bd(i1, i1, 1'b1, (`MEMORY_BASE + (i1 * 50)));
10581
      end
10582
      set_rx_bd_wrap(i);
10583
      set_rx_bd_empty(0, i);
10584
      for (i1 = 0; i1 <= i; i1 = i1 + 1)
10585
      begin
10586
        #1 eth_phy.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, 8'hD5, (i1 * 50), 14, 1'b0);
10587
        repeat(10) @(posedge mrx_clk);
10588
      end
10589
      @(posedge mrx_clk);
10590
      for (i2 = 0; i2 < 20; i2 = i2 + 1)
10591
      begin
10592
        check_rx_bd(0, tmp);
10593
        #1;
10594
        if (tmp[15] === 1'b0)
10595
        begin
10596
          test_fail("Receive should not start at all");
10597
          fail = fail + 1;
10598
          `TIME; $display("*E Receive of %d packets should not start at all - empty is 0", i);
10599
        end
10600
        if (tmp[7:0] !== 0)
10601
        begin
10602
          test_fail("Receive should not be finished since it should not start at all");
10603
          fail = fail + 1;
10604
          `TIME; $display("*E Receive of should not be finished since it should not start at all");
10605
        end
10606
        @(posedge wb_clk);
10607
      end
10608
      wbm_read(`ETH_INT, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10609
      if (tmp[6:0] !== 0)
10610
      begin
10611
        test_fail("Receive should not get INT since it should not start at all");
10612
        fail = fail + 1;
10613
        `TIME; $display("*E Receive of should not get INT since it should not start at all");
10614
      end
10615
      clear_rx_bd(0, i);
10616
      if ((i < 5) || (i > 124))
10617
        i = i + 1;
10618
      else
10619
        i = i + 120;
10620
    end
10621
    // disable RX
10622
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_IFG |
10623
              `ETH_MODER_PRO | `ETH_MODER_BRO,
10624
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10625
    if(fail == 0)
10626
      test_ok;
10627
    else
10628
      fail = 0;
10629
  end
10630
 
10631
 
10632
  ////////////////////////////////////////////////////////////////////
10633
  ////                                                            ////
10634
  ////  Test receive packets form MINFL to MAXFL sizes at         ////
10635
  ////  one RX buffer decriptor ( 10Mbps ).                       ////
10636
  ////                                                            ////
10637
  ////////////////////////////////////////////////////////////////////
10638
  if (test_num == 2) // Test no receive when all buffers are TX ( 10Mbps ).
10639
  begin
10640
    // TEST 2: RECEIVE PACKETS FROM MINFL TO MAXFL SIZES AT ONE RX BD ( 10Mbps )
10641
    test_name   = "TEST 2: RECEIVE PACKETS FROM MINFL TO MAXFL SIZES AT ONE RX BD ( 10Mbps )";
10642
    `TIME; $display("  TEST 2: RECEIVE PACKETS FROM MINFL TO MAXFL SIZES AT ONE RX BD ( 10Mbps )");
10643
 
10644
    // unmask interrupts
10645
    wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
10646
                             `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10647
    // set 1 RX buffer descriptor (8'h80 - 1) - must be set before RX enable
10648
    wbm_write(`ETH_TX_BD_NUM, 32'h7F, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10649
    // enable RX, set full-duplex mode, NO receive small, NO correct IFG
10650
    wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
10651
              `ETH_MODER_PRO | `ETH_MODER_BRO,
10652
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10653
    // prepare two packets of MAXFL length
10654
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10655
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
10656
    min_tmp = tmp[31:16];
10657
    st_data = 8'h0F;
10658
    set_rx_packet(0, (max_tmp - 4), 1'b0, 48'h0102_0304_0506, 48'h0708_090A_0B0C, 16'h0D0E, st_data); // length without CRC
10659
    st_data = 8'h1A;
10660
    set_rx_packet((max_tmp), (max_tmp - 4), 1'b0, 48'h1234_5678_8765, 48'hA1B2_C3D4_E5F6, 16'hE77E, st_data);
10661
    // check WB INT signal
10662
    if (wb_int !== 1'b0)
10663
    begin
10664
      test_fail("WB INT signal should not be set");
10665
      fail = fail + 1;
10666
    end
10667
 
10668
    // write to phy's control register for 10Mbps
10669
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
10670
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
10671
    speed = 10;
10672
 
10673
    i_length = (min_tmp - 4);
10674
    while (i_length <= (max_tmp - 4))
10675
    begin
10676
      // choose generating carrier sense and collision for first and last 64 lengths of frames
10677
      case (i_length[1:0])
10678
      2'h0: // Interrupt is generated
10679
      begin
10680
        // enable interrupt generation
10681
        set_rx_bd(127, 127, 1'b1, (`MEMORY_BASE + i_length[1:0]));
10682
        // unmask interrupts
10683
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
10684
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10685
        // not detect carrier sense in FD and no collision
10686
        eth_phy.no_carrier_sense_rx_fd_detect(0);
10687
        eth_phy.collision(0);
10688
      end
10689
      2'h1: // Interrupt is not generated
10690
      begin
10691
        // enable interrupt generation
10692
        set_rx_bd(127, 127, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
10693
        // mask interrupts
10694
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10695
        // detect carrier sense in FD and no collision
10696
        eth_phy.no_carrier_sense_rx_fd_detect(1);
10697
        eth_phy.collision(0);
10698
      end
10699
      2'h2: // Interrupt is not generated
10700
      begin
10701
        // disable interrupt generation
10702
        set_rx_bd(127, 127, 1'b0, (`MEMORY_BASE + i_length[1:0]));
10703
        // unmask interrupts
10704
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
10705
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10706
        // not detect carrier sense in FD and set collision
10707
        eth_phy.no_carrier_sense_rx_fd_detect(0);
10708
        eth_phy.collision(1);
10709
      end
10710
      default: // 2'h3: // Interrupt is not generated
10711
      begin
10712
        // disable interrupt generation
10713
        set_rx_bd(127, 127, 1'b0, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
10714
        // mask interrupts
10715
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10716
        // detect carrier sense in FD and set collision
10717
        eth_phy.no_carrier_sense_rx_fd_detect(1);
10718
        eth_phy.collision(1);
10719
      end
10720
      endcase
10721
      if (i_length[0] == 1'b0)
10722
        append_rx_crc (0, i_length, 1'b0, 1'b0);
10723
      else
10724
        append_rx_crc (max_tmp, i_length, 1'b0, 1'b0);
10725
      // set wrap bit
10726
      set_rx_bd_wrap(127);
10727
      set_rx_bd_empty(127, 127);
10728
      fork
10729
        begin
10730
          if (i_length[0] == 1'b0)
10731
            #1 eth_phy.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, 8'hD5, 0, (i_length + 4), 1'b0);
10732
          else
10733
            #1 eth_phy.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, 8'hD5, max_tmp, (i_length + 4), 1'b0);
10734
          repeat(10) @(posedge mrx_clk);
10735
        end
10736
        begin
10737
          #1 check_rx_bd(127, data);
10738
          if (i_length < min_tmp) // just first four
10739
          begin
10740
            while (data[15] === 1)
10741
            begin
10742
              #1 check_rx_bd(127, data);
10743
              @(posedge wb_clk);
10744
            end
10745
            repeat (1) @(posedge wb_clk);
10746
          end
10747
          else
10748
          begin
10749
            wait (MRxDV === 1'b1); // start transmit
10750
            #1 check_rx_bd(127, data);
10751
            if (data[15] !== 1)
10752
            begin
10753
              test_fail("Wrong buffer descriptor's ready bit read out from MAC");
10754
              fail = fail + 1;
10755
            end
10756
            wait (MRxDV === 1'b0); // end transmit
10757
            while (data[15] === 1)
10758
            begin
10759
              #1 check_rx_bd(127, data);
10760
              @(posedge wb_clk);
10761
            end
10762
            repeat (1) @(posedge wb_clk);
10763
          end
10764
        end
10765
      join
10766
      // check length of a PACKET
10767
      if (data[31:16] != (i_length + 4))
10768
      begin
10769
        `TIME; $display("*E Wrong length of the packet out from PHY (%0d instead of %0d)",
10770
                        data[31:16], (i_length + 4));
10771
        test_fail("Wrong length of the packet out from PHY");
10772
        fail = fail + 1;
10773
      end
10774
      // checking in the following if statement is performed only for first and last 64 lengths
10775
      // check received RX packet data and CRC
10776
      if (i_length[0] == 1'b0)
10777
      begin
10778
        check_rx_packet(0, (`MEMORY_BASE + i_length[1:0]), (i_length + 4), 1'b0, 1'b0, tmp);
10779
      end
10780
      else
10781
      begin
10782
        check_rx_packet(max_tmp, ((`MEMORY_BASE + i_length[1:0]) + max_tmp), (i_length + 4), 1'b0, 1'b0, tmp);
10783
      end
10784
      if (tmp > 0)
10785
      begin
10786
        `TIME; $display("*E Wrong data of the received packet");
10787
        test_fail("Wrong data of the received packet");
10788
        fail = fail + 1;
10789
      end
10790
      // check WB INT signal
10791
      if (i_length[1:0] == 2'h0)
10792
      begin
10793
        if (wb_int !== 1'b1)
10794
        begin
10795
          `TIME; $display("*E WB INT signal should be set");
10796
          test_fail("WB INT signal should be set");
10797
          fail = fail + 1;
10798
        end
10799
      end
10800
      else
10801
      begin
10802
        if (wb_int !== 1'b0)
10803
        begin
10804
          `TIME; $display("*E WB INT signal should not be set");
10805
          test_fail("WB INT signal should not be set");
10806
          fail = fail + 1;
10807
        end
10808
      end
10809
      // check RX buffer descriptor of a packet
10810
      check_rx_bd(127, data);
10811
      if (i_length[1] == 1'b0) // interrupt enabled no_carrier_sense_rx_fd_detect
10812
      begin
10813
        if ( ((data[15:0] !== 16'h6000) && (i_length[0] == 1'b0)) ||
10814
             ((data[15:0] !== 16'h6000) && (i_length[0] == 1'b1)) )
10815
        begin
10816
          `TIME; $display("*E RX buffer descriptor status is not correct: %0h", data[15:0]);
10817
          test_fail("RX buffer descriptor status is not correct");
10818
          fail = fail + 1;
10819
        end
10820
      end
10821
      else // interrupt not enabled
10822
      begin
10823
        if ( ((data[15:0] !== 16'h2000) && (i_length[0] == 1'b0)) ||
10824
             ((data[15:0] !== 16'h2000) && (i_length[0] == 1'b1)) )
10825
        begin
10826
          `TIME; $display("*E RX buffer descriptor status is not correct: %0h", data[15:0]);
10827
          test_fail("RX buffer descriptor status is not correct");
10828
          fail = fail + 1;
10829
        end
10830
      end
10831
      // clear RX buffer descriptor for first 4 frames
10832
      if (i_length < min_tmp)
10833
        clear_rx_bd(127, 127);
10834
      // check interrupts
10835
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10836
      if ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1))
10837
      begin
10838
        if ((data & `ETH_INT_RXB) !== `ETH_INT_RXB)
10839
        begin
10840
          `TIME; $display("*E Interrupt Receive Buffer was not set, interrupt reg: %0h", data);
10841
          test_fail("Interrupt Receive Buffer was not set");
10842
          fail = fail + 1;
10843
        end
10844
        if ((data & (~`ETH_INT_RXB)) !== 0)
10845
        begin
10846
          `TIME; $display("*E Other interrupts (except Receive Buffer) were set, interrupt reg: %0h", data);
10847
          test_fail("Other interrupts (except Receive Buffer) were set");
10848
          fail = fail + 1;
10849
        end
10850
      end
10851
      else
10852
      begin
10853
        if (data !== 0)
10854
        begin
10855
          `TIME; $display("*E Any of interrupts (except Receive Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]);
10856
          test_fail("Any of interrupts (except Receive Buffer) was set");
10857
          fail = fail + 1;
10858
        end
10859
      end
10860
      // clear interrupts
10861
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10862
      // check WB INT signal
10863
      if (wb_int !== 1'b0)
10864
      begin
10865
        test_fail("WB INT signal should not be set");
10866
        fail = fail + 1;
10867
      end
10868
      // INTERMEDIATE DISPLAYS
10869
      if ((i_length + 4) == (min_tmp + 64))
10870
      begin
10871
        // starting length is min_tmp, ending length is (min_tmp + 64)
10872
        $display("    receive small packets is NOT selected");
10873
        $display("    ->packets with lengths from %0d (MINFL) to %0d are checked (length increasing by 1 byte)",
10874
                 min_tmp, (min_tmp + 64));
10875
        // set receive small, remain the rest
10876
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_IFG |
10877
                  `ETH_MODER_PRO | `ETH_MODER_BRO,
10878
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10879
      end
10880
      else if ((i_length + 4) == (max_tmp - 16))
10881
      begin
10882
        // starting length is for +128 longer than previous ending length, while ending length is tmp_data
10883
        $display("    receive small packets is selected");
10884
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 128 bytes)",
10885
                 (min_tmp + 64 + 128), tmp_data);
10886
        // reset receive small, remain the rest
10887
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
10888
                  `ETH_MODER_PRO | `ETH_MODER_BRO,
10889
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10890
      end
10891
      else if ((i_length + 4) == max_tmp)
10892
      begin
10893
        $display("    receive small packets is NOT selected");
10894
        $display("    ->packets with lengths from %0d to %0d (MAXFL) are checked (length increasing by 1 byte)",
10895
                 (max_tmp - (4 + 16)), max_tmp);
10896
      end
10897
      // set length (loop variable)
10898
      if ((i_length + 4) < (min_tmp + 64))
10899
        i_length = i_length + 1;
10900
      else if ( ((i_length + 4) >= (min_tmp + 64)) && ((i_length + 4) <= (max_tmp - 256)) )
10901
      begin
10902
        i_length = i_length + 128;
10903
        tmp_data = i_length + 4; // last tmp_data is ending length
10904
      end
10905
      else if ( ((i_length + 4) > (max_tmp - 256)) && ((i_length + 4) < (max_tmp - 16)) )
10906
        i_length = max_tmp - (4 + 16);
10907
      else if ((i_length + 4) >= (max_tmp - 16))
10908
        i_length = i_length + 1;
10909
      else
10910
      begin
10911
        $display("*E TESTBENCH ERROR - WRONG PARAMETERS IN TESTBENCH");
10912
        #10 $stop;
10913
      end
10914
    end
10915
    // disable RX
10916
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_IFG |
10917
              `ETH_MODER_PRO | `ETH_MODER_BRO,
10918
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10919
    if(fail == 0)
10920
      test_ok;
10921
    else
10922
      fail = 0;
10923
  end
10924
 
10925
 
10926
  ////////////////////////////////////////////////////////////////////
10927
  ////                                                            ////
10928
  ////  Test receive packets form MINFL to MAXFL sizes at         ////
10929
  ////  one RX buffer decriptor ( 100Mbps ).                      ////
10930
  ////                                                            ////
10931
  ////////////////////////////////////////////////////////////////////
10932
  if (test_num == 3) // Test no receive when all buffers are TX ( 100Mbps ).
10933
  begin
10934
    // TEST 3: RECEIVE PACKETS FROM MINFL TO MAXFL SIZES AT ONE RX BD ( 100Mbps )
10935
    test_name   = "TEST 3: RECEIVE PACKETS FROM MINFL TO MAXFL SIZES AT ONE RX BD ( 100Mbps )";
10936
    `TIME; $display("  TEST 3: RECEIVE PACKETS FROM MINFL TO MAXFL SIZES AT ONE RX BD ( 100Mbps )");
10937
 
10938
    // unmask interrupts
10939
    wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
10940
                             `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10941
    // set 1 RX buffer descriptor (8'h80 - 1) - must be set before RX enable
10942
    wbm_write(`ETH_TX_BD_NUM, 32'h7F, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10943
    // enable RX, set full-duplex mode, NO receive small, NO correct IFG
10944
    wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
10945
              `ETH_MODER_PRO | `ETH_MODER_BRO,
10946
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10947
    // prepare two packets of MAXFL length
10948
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10949
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
10950
    min_tmp = tmp[31:16];
10951
    st_data = 8'h0F;
10952
    set_rx_packet(0, (max_tmp - 4), 1'b0, 48'h0102_0304_0506, 48'h0708_090A_0B0C, 16'h0D0E, st_data); // length without CRC
10953
    st_data = 8'h1A;
10954
    set_rx_packet((max_tmp), (max_tmp - 4), 1'b0, 48'h1234_5678_8765, 48'hA1B2_C3D4_E5F6, 16'hE77E, st_data);
10955
    // check WB INT signal
10956
    if (wb_int !== 1'b0)
10957
    begin
10958
      test_fail("WB INT signal should not be set");
10959
      fail = fail + 1;
10960
    end
10961
 
10962
    // write to phy's control register for 100Mbps
10963
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
10964
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
10965
    speed = 100;
10966
 
10967
    i_length = (min_tmp - 4);
10968
    while (i_length <= (max_tmp - 4))
10969
    begin
10970
      // choose generating carrier sense and collision for first and last 64 lengths of frames
10971
      case (i_length[1:0])
10972
      2'h0: // Interrupt is generated
10973
      begin
10974
        // enable interrupt generation
10975
        set_rx_bd(127, 127, 1'b1, (`MEMORY_BASE + i_length[1:0]));
10976
        // unmask interrupts
10977
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
10978
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10979
        // not detect carrier sense in FD and no collision
10980
        eth_phy.no_carrier_sense_rx_fd_detect(0);
10981
        eth_phy.collision(0);
10982
      end
10983
      2'h1: // Interrupt is not generated
10984
      begin
10985
        // enable interrupt generation
10986
        set_rx_bd(127, 127, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
10987
        // mask interrupts
10988
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10989
        // detect carrier sense in FD and no collision
10990
        eth_phy.no_carrier_sense_rx_fd_detect(1);
10991
        eth_phy.collision(0);
10992
      end
10993
      2'h2: // Interrupt is not generated
10994
      begin
10995
        // disable interrupt generation
10996
        set_rx_bd(127, 127, 1'b0, (`MEMORY_BASE + i_length[1:0]));
10997
        // unmask interrupts
10998
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
10999
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11000
        // not detect carrier sense in FD and set collision
11001
        eth_phy.no_carrier_sense_rx_fd_detect(0);
11002
        eth_phy.collision(1);
11003
      end
11004
      default: // 2'h3: // Interrupt is not generated
11005
      begin
11006
        // disable interrupt generation
11007
        set_rx_bd(127, 127, 1'b0, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
11008
        // mask interrupts
11009
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11010
        // detect carrier sense in FD and set collision
11011
        eth_phy.no_carrier_sense_rx_fd_detect(1);
11012
        eth_phy.collision(1);
11013
      end
11014
      endcase
11015
      if (i_length[0] == 1'b0)
11016
        append_rx_crc (0, i_length, 1'b0, 1'b0);
11017
      else
11018
        append_rx_crc (max_tmp, i_length, 1'b0, 1'b0);
11019
      // set wrap bit
11020
      set_rx_bd_wrap(127);
11021
      set_rx_bd_empty(127, 127);
11022
      fork
11023
        begin
11024
          if (i_length[0] == 1'b0)
11025
            #1 eth_phy.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, 8'hD5, 0, (i_length + 4), 1'b0);
11026
          else
11027
            #1 eth_phy.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, 8'hD5, max_tmp, (i_length + 4), 1'b0);
11028
          repeat(10) @(posedge mrx_clk);
11029
        end
11030
        begin
11031
          #1 check_rx_bd(127, data);
11032
          if (i_length < min_tmp) // just first four
11033
          begin
11034
            while (data[15] === 1)
11035
            begin
11036
              #1 check_rx_bd(127, data);
11037
              @(posedge wb_clk);
11038
            end
11039
            repeat (1) @(posedge wb_clk);
11040
          end
11041
          else
11042
          begin
11043
            wait (MRxDV === 1'b1); // start transmit
11044
            #1 check_rx_bd(127, data);
11045
            if (data[15] !== 1)
11046
            begin
11047
              test_fail("Wrong buffer descriptor's ready bit read out from MAC");
11048
              fail = fail + 1;
11049
            end
11050
            wait (MRxDV === 1'b0); // end transmit
11051
            while (data[15] === 1)
11052
            begin
11053
              #1 check_rx_bd(127, data);
11054
              @(posedge wb_clk);
11055
            end
11056
            repeat (1) @(posedge wb_clk);
11057
          end
11058
        end
11059
      join
11060
      // check length of a PACKET
11061
      if (data[31:16] != (i_length + 4))
11062
      begin
11063
        `TIME; $display("*E Wrong length of the packet out from PHY (%0d instead of %0d)",
11064
                        data[31:16], (i_length + 4));
11065
        test_fail("Wrong length of the packet out from PHY");
11066
        fail = fail + 1;
11067
      end
11068
      // checking in the following if statement is performed only for first and last 64 lengths
11069
      // check received RX packet data and CRC
11070
      if (i_length[0] == 1'b0)
11071
      begin
11072
        check_rx_packet(0, (`MEMORY_BASE + i_length[1:0]), (i_length + 4), 1'b0, 1'b0, tmp);
11073
      end
11074
      else
11075
      begin
11076
        check_rx_packet(max_tmp, ((`MEMORY_BASE + i_length[1:0]) + max_tmp), (i_length + 4), 1'b0, 1'b0, tmp);
11077
      end
11078
      if (tmp > 0)
11079
      begin
11080
        `TIME; $display("*E Wrong data of the received packet");
11081
        test_fail("Wrong data of the received packet");
11082
        fail = fail + 1;
11083
      end
11084
      // check WB INT signal
11085
      if (i_length[1:0] == 2'h0)
11086
      begin
11087
        if (wb_int !== 1'b1)
11088
        begin
11089
          `TIME; $display("*E WB INT signal should be set");
11090
          test_fail("WB INT signal should be set");
11091
          fail = fail + 1;
11092
        end
11093
      end
11094
      else
11095
      begin
11096
        if (wb_int !== 1'b0)
11097
        begin
11098
          `TIME; $display("*E WB INT signal should not be set");
11099
          test_fail("WB INT signal should not be set");
11100
          fail = fail + 1;
11101
        end
11102
      end
11103
      // check RX buffer descriptor of a packet
11104
      check_rx_bd(127, data);
11105
      if (i_length[1] == 1'b0) // interrupt enabled 
11106
      begin
11107
        if ( ((data[15:0] !== 16'h6000) && (i_length[0] == 1'b0)) ||
11108
             ((data[15:0] !== 16'h6000) && (i_length[0] == 1'b1)) )
11109
        begin
11110
          `TIME; $display("*E RX buffer descriptor status is not correct: %0h", data[15:0]);
11111
          test_fail("RX buffer descriptor status is not correct");
11112
          fail = fail + 1;
11113
        end
11114
      end
11115
      else // interrupt not enabled
11116
      begin
11117
        if ( ((data[15:0] !== 16'h2000) && (i_length[0] == 1'b0)) ||
11118
             ((data[15:0] !== 16'h2000) && (i_length[0] == 1'b1)) )
11119
        begin
11120
          `TIME; $display("*E RX buffer descriptor status is not correct: %0h", data[15:0]);
11121
          test_fail("RX buffer descriptor status is not correct");
11122
          fail = fail + 1;
11123
        end
11124
      end
11125
      // clear RX buffer descriptor for first 4 frames
11126
      if (i_length < min_tmp)
11127
        clear_rx_bd(127, 127);
11128
      // check interrupts
11129
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11130
      if ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1))
11131
      begin
11132
        if ((data & `ETH_INT_RXB) !== `ETH_INT_RXB)
11133
        begin
11134
          `TIME; $display("*E Interrupt Receive Buffer was not set, interrupt reg: %0h", data);
11135
          test_fail("Interrupt Receive Buffer was not set");
11136
          fail = fail + 1;
11137
        end
11138
        if ((data & (~`ETH_INT_RXB)) !== 0)
11139
        begin
11140
          `TIME; $display("*E Other interrupts (except Receive Buffer) were set, interrupt reg: %0h", data);
11141
          test_fail("Other interrupts (except Receive Buffer) were set");
11142
          fail = fail + 1;
11143
        end
11144
      end
11145
      else
11146
      begin
11147
        if (data !== 0)
11148
        begin
11149
          `TIME; $display("*E Any of interrupts (except Receive Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]);
11150
          test_fail("Any of interrupts (except Receive Buffer) was set");
11151
          fail = fail + 1;
11152
        end
11153
      end
11154
      // clear interrupts
11155
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11156
      // check WB INT signal
11157
      if (wb_int !== 1'b0)
11158
      begin
11159
        test_fail("WB INT signal should not be set");
11160
        fail = fail + 1;
11161
      end
11162
      // INTERMEDIATE DISPLAYS
11163
      if ((i_length + 4) == (min_tmp + 64))
11164
      begin
11165
        // starting length is min_tmp, ending length is (min_tmp + 64)
11166
        $display("    receive small packets is NOT selected");
11167
        $display("    ->packets with lengths from %0d (MINFL) to %0d are checked (length increasing by 1 byte)",
11168
                 min_tmp, (min_tmp + 64));
11169
        // set receive small, remain the rest
11170
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_IFG |
11171
                  `ETH_MODER_PRO | `ETH_MODER_BRO,
11172
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11173
      end
11174
      else if ((i_length + 4) == (max_tmp - 16))
11175
      begin
11176
        // starting length is for +128 longer than previous ending length, while ending length is tmp_data
11177
        $display("    receive small packets is selected");
11178
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 128 bytes)",
11179
                 (min_tmp + 64 + 128), tmp_data);
11180
        // reset receive small, remain the rest
11181
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
11182
                  `ETH_MODER_PRO | `ETH_MODER_BRO,
11183
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11184
      end
11185
      else if ((i_length + 4) == max_tmp)
11186
      begin
11187
        $display("    receive small packets is NOT selected");
11188
        $display("    ->packets with lengths from %0d to %0d (MAXFL) are checked (length increasing by 1 byte)",
11189
                 (max_tmp - (4 + 16)), max_tmp);
11190
      end
11191
      // set length (loop variable)
11192
      if ((i_length + 4) < (min_tmp + 64))
11193
        i_length = i_length + 1;
11194
      else if ( ((i_length + 4) >= (min_tmp + 64)) && ((i_length + 4) <= (max_tmp - 256)) )
11195
      begin
11196
        i_length = i_length + 128;
11197
        tmp_data = i_length + 4; // last tmp_data is ending length
11198
      end
11199
      else if ( ((i_length + 4) > (max_tmp - 256)) && ((i_length + 4) < (max_tmp - 16)) )
11200
        i_length = max_tmp - (4 + 16);
11201
      else if ((i_length + 4) >= (max_tmp - 16))
11202
        i_length = i_length + 1;
11203
      else
11204
      begin
11205
        $display("*E TESTBENCH ERROR - WRONG PARAMETERS IN TESTBENCH");
11206
        #10 $stop;
11207
      end
11208
    end
11209
    // disable RX
11210
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_IFG |
11211
              `ETH_MODER_PRO | `ETH_MODER_BRO,
11212
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11213
    if(fail == 0)
11214
      test_ok;
11215
    else
11216
      fail = 0;
11217
  end
11218
 
11219
 
11220
  ////////////////////////////////////////////////////////////////////
11221
  ////                                                            ////
11222
  ////  Test receive packets form MINFL to MAXFL sizes at         ////
11223
  ////  maximum RX buffer decriptors ( 10Mbps ).                  ////
11224
  ////                                                            ////
11225
  ////////////////////////////////////////////////////////////////////
11226
  if (test_num == 4) // 
11227
  begin
11228
    // TEST 4: RECEIVE PACKETS FROM MINFL TO MAXFL SIZES AT MAX RX BDs ( 10Mbps )
11229
    test_name = "TEST 4: RECEIVE PACKETS FROM MINFL TO MAXFL SIZES AT MAX RX BDs ( 10Mbps )";
11230
    `TIME; $display("  TEST 4: RECEIVE PACKETS FROM MINFL TO MAXFL SIZES AT MAX RX BDs ( 10Mbps )");
11231
 
11232
    // reset MAC registers
11233
    hard_reset;
11234
    // reset MAC and MII LOGIC with soft reset
11235
    reset_mac;
11236
    reset_mii;
11237
    // set wb slave response
11238
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
11239
 
11240
    max_tmp = 0;
11241
    min_tmp = 0;
11242
    num_of_frames = 0;
11243
    num_of_bd = 0;
11244
    // set maximum RX buffer descriptors (128) - must be set before RX enable
11245
    wbm_write(`ETH_TX_BD_NUM, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11246
    // enable RX, set full-duplex mode, NO receive small, NO correct IFG
11247
    wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
11248
              `ETH_MODER_PRO | `ETH_MODER_BRO,
11249
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11250
    // prepare two packets of MAXFL length
11251
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11252
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
11253
    min_tmp = tmp[31:16];
11254
    st_data = 8'hAC;
11255
    set_rx_packet(0, (max_tmp - 4), 1'b0, 48'h0102_0304_0506, 48'h0708_090A_0B0C, 16'h0D0E, st_data); // length without CRC
11256
    st_data = 8'h35;
11257
    set_rx_packet((max_tmp), (max_tmp - 4), 1'b0, 48'h1234_5678_8765, 48'hA1B2_C3D4_E5F6, 16'hE77E, st_data);
11258
    // check WB INT signal
11259
    if (wb_int !== 1'b0)
11260
    begin
11261
      test_fail("WB INT signal should not be set");
11262
      fail = fail + 1;
11263
    end
11264
 
11265
    // write to phy's control register for 10Mbps
11266
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
11267
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
11268
    speed = 10;
11269
 
11270
    i_length = (min_tmp - 4);
11271
    while (i_length <= (max_tmp - 4))
11272
    begin
11273
      // append CRC to packet
11274
      if (i_length[0] == 1'b0)
11275
        append_rx_crc (0, i_length, 1'b0, 1'b0);
11276
      else
11277
        append_rx_crc (max_tmp, i_length, 1'b0, 1'b0);
11278
      // choose generating carrier sense and collision
11279
      case (i_length[1:0])
11280
      2'h0: // Interrupt is generated
11281
      begin
11282
        // Reset_tx_bd nable interrupt generation
11283
        // unmask interrupts
11284
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
11285
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11286
        // not detect carrier sense in FD and no collision
11287
        eth_phy.no_carrier_sense_rx_fd_detect(0);
11288
        eth_phy.collision(0);
11289
      end
11290
      2'h1: // Interrupt is not generated
11291
      begin
11292
        // set_tx_bd enable interrupt generation
11293
        // mask interrupts
11294
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11295
        // detect carrier sense in FD and no collision
11296
        eth_phy.no_carrier_sense_rx_fd_detect(1);
11297
        eth_phy.collision(0);
11298
      end
11299
      2'h2: // Interrupt is not generated
11300
      begin
11301
        // set_tx_bd disable the interrupt generation
11302
        // unmask interrupts
11303
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
11304
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11305
        // not detect carrier sense in FD and set collision
11306
        eth_phy.no_carrier_sense_rx_fd_detect(0);
11307
        eth_phy.collision(1);
11308
      end
11309
      default: // 2'h3: // Interrupt is not generated
11310
      begin
11311
        // set_tx_bd disable the interrupt generation
11312
        // mask interrupts
11313
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11314
        // detect carrier sense in FD and set collision
11315
        eth_phy.no_carrier_sense_rx_fd_detect(1);
11316
        eth_phy.collision(1);
11317
      end
11318
      endcase
11319
      // first 8 frames are received with RX BD 0 (wrap bit on RX BD 0)
11320
      // number of all frames is 154 (146 without first 8)
11321
      if (num_of_frames < 8)
11322
      begin
11323
        case (i_length[1:0])
11324
        2'h0: // Interrupt is generated
11325
        begin
11326
          // enable interrupt generation
11327
          set_rx_bd(0, 0, 1'b1, (`MEMORY_BASE + i_length[1:0]));
11328
          // interrupts are unmasked
11329
        end
11330
        2'h1: // Interrupt is not generated
11331
        begin
11332
          // enable interrupt generation
11333
          set_rx_bd(0, 0, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
11334
          // interrupts are masked
11335
        end
11336
        2'h2: // Interrupt is not generated
11337
        begin
11338
          // disable interrupt generation
11339
          set_rx_bd(0, 0, 1'b0, (`MEMORY_BASE + i_length[1:0]));
11340
          // interrupts are unmasked
11341
        end
11342
        default: // 2'h3: // Interrupt is not generated
11343
        begin
11344
          // disable interrupt generation
11345
          set_rx_bd(0, 0, 1'b0, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
11346
          // interrupts are masked
11347
        end
11348
        endcase
11349
        // set wrap bit
11350
        set_rx_bd_wrap(0);
11351
      end
11352
      // after first 8 number of frames, 128 frames form RX BD 0 to 127 will be received
11353
      else if ((num_of_frames - 8) == 0)
11354
      begin
11355
        tmp_len = i_length; // length of frame
11356
        tmp_bd_num = 0; // RX BD number
11357
        while (tmp_bd_num < 128) // (tmp_len <= (max_tmp - 4)) - this is the last frame
11358
        begin
11359
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
11360
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
11361
          if (tmp_len[0] == 0)
11362
            set_rx_bd(tmp_bd_num, tmp_bd_num, !tmp_len[1], (`MEMORY_BASE + tmp_len[1:0]));
11363
          else
11364
            set_rx_bd(tmp_bd_num, tmp_bd_num, !tmp_len[1], ((`MEMORY_BASE + tmp_len[1:0]) + max_tmp));
11365
          // set length (loop variable) - THE SAME AS AT THE END OF THIS TASK !!!
11366
          if ((tmp_len + 4) < (min_tmp + 128))
11367
            tmp_len = tmp_len + 1;
11368
          else if ( ((tmp_len + 4) == (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
11369
            tmp_len = 256;
11370
          else if ( ((tmp_len + 4) > (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
11371
            tmp_len = tmp_len + 128;
11372
          else if ( ((tmp_len + 4) > (max_tmp - 256)) && ((tmp_len + 4) < (max_tmp - 16)) )
11373
            tmp_len = max_tmp - (4 + 16);
11374
          else if ((tmp_len + 4) >= (max_tmp - 16))
11375
            tmp_len = tmp_len + 1;
11376
          // set RX BD number
11377
          tmp_bd_num = tmp_bd_num + 1;
11378
        end
11379
        // set wrap bit
11380
        set_rx_bd_wrap(127);
11381
      end
11382
      // after 128 + first 8 number of frames, 19 frames form RX BD 0 to 18 will be received
11383
      else if ((num_of_frames - 8) == 20) // 128
11384
      begin
11385
        tmp_len = tmp_len; // length of frame remaines from previous settings
11386
        tmp_bd_num = 0; // TX BD number
11387
        while (tmp_bd_num < 19) // (tmp_len <= (max_tmp - 4)) - this is the last frame
11388
        begin
11389
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
11390
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
11391
          if (tmp_len[0] == 0)
11392
            set_rx_bd(tmp_bd_num, tmp_bd_num, !tmp_len[1], (`MEMORY_BASE + tmp_len[1:0]));
11393
          else
11394
            set_rx_bd(tmp_bd_num, tmp_bd_num, !tmp_len[1], ((`MEMORY_BASE + tmp_len[1:0]) + max_tmp));
11395
          // set length (loop variable) - THE SAME AS AT THE END OF THIS TASK !!!
11396
          if ((tmp_len + 4) < (min_tmp + 128))
11397
            tmp_len = tmp_len + 1;
11398
          else if ( ((tmp_len + 4) == (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
11399
            tmp_len = 256;
11400
          else if ( ((tmp_len + 4) > (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
11401
            tmp_len = tmp_len + 128;
11402
          else if ( ((tmp_len + 4) > (max_tmp - 256)) && ((tmp_len + 4) < (max_tmp - 16)) )
11403
            tmp_len = max_tmp - (4 + 16);
11404
          else if ((tmp_len + 4) >= (max_tmp - 16))
11405
            tmp_len = tmp_len + 1;
11406
          // set TX BD number
11407
          tmp_bd_num = tmp_bd_num + 1;
11408
        end
11409
      end
11410
      // set empty bit
11411
      if (num_of_frames < 8)
11412
        set_rx_bd_empty(0, 0);
11413
      else if ((num_of_frames - 8) < 128)
11414
        set_rx_bd_empty((num_of_frames - 8), (num_of_frames - 8));
11415
      else if ((num_of_frames - 136) < 19)
11416
        set_rx_bd_empty((num_of_frames - 136), (num_of_frames - 136));
11417
      // CHECK END OF RECEIVE
11418
      fork
11419
        begin
11420
          if (i_length[0] == 1'b0)
11421
            #1 eth_phy.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, 8'hD5, 0, (i_length + 4), 1'b0);
11422
          else
11423
            #1 eth_phy.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, 8'hD5, max_tmp, (i_length + 4), 1'b0);
11424
          repeat(10) @(posedge mrx_clk);
11425
        end
11426
        begin
11427
          #1 check_rx_bd(num_of_bd, data);
11428
          if (i_length < min_tmp) // just first four
11429
          begin
11430
            while (data[15] === 1)
11431
            begin
11432
              #1 check_rx_bd(num_of_bd, data);
11433
              @(posedge wb_clk);
11434
            end
11435
            repeat (1) @(posedge wb_clk);
11436
          end
11437
          else
11438
          begin
11439
            wait (MRxDV === 1'b1); // start transmit
11440
            #1 check_rx_bd(num_of_bd, data);
11441
            if (data[15] !== 1)
11442
            begin
11443
              test_fail("Wrong buffer descriptor's ready bit read out from MAC");
11444
              fail = fail + 1;
11445
            end
11446
            wait (MRxDV === 1'b0); // end transmit
11447
            while (data[15] === 1)
11448
            begin
11449
              #1 check_rx_bd(num_of_bd, data);
11450
              @(posedge wb_clk);
11451
            end
11452
            repeat (1) @(posedge wb_clk);
11453
          end
11454
        end
11455
      join
11456
      // check length of a PACKET
11457
      if (data[31:16] != (i_length + 4))
11458
      begin
11459
        `TIME; $display("*E Wrong length of the packet out from PHY (%0d instead of %0d)",
11460
                        data[31:16], (i_length + 4));
11461
        test_fail("Wrong length of the packet out from PHY");
11462
        fail = fail + 1;
11463
      end
11464
      // checking in the following if statement is performed only for first and last 64 lengths
11465
      // check received RX packet data and CRC
11466
      if (i_length[0] == 1'b0)
11467
      begin
11468
        check_rx_packet(0, (`MEMORY_BASE + i_length[1:0]), (i_length + 4), 1'b0, 1'b0, tmp);
11469
      end
11470
      else
11471
      begin
11472
        check_rx_packet(max_tmp, ((`MEMORY_BASE + i_length[1:0]) + max_tmp), (i_length + 4), 1'b0, 1'b0, tmp);
11473
      end
11474
      if (tmp > 0)
11475
      begin
11476
        `TIME; $display("*E Wrong data of the received packet");
11477
        test_fail("Wrong data of the received packet");
11478
        fail = fail + 1;
11479
      end
11480
      // check WB INT signal
11481
      if (i_length[1:0] == 2'h0)
11482
      begin
11483
        if (wb_int !== 1'b1)
11484
        begin
11485
          `TIME; $display("*E WB INT signal should be set");
11486
          test_fail("WB INT signal should be set");
11487
          fail = fail + 1;
11488
        end
11489
      end
11490
      else
11491
      begin
11492
        if (wb_int !== 1'b0)
11493
        begin
11494
          `TIME; $display("*E WB INT signal should not be set");
11495
          test_fail("WB INT signal should not be set");
11496
          fail = fail + 1;
11497
        end
11498
      end
11499
      // check RX buffer descriptor of a packet
11500
      check_rx_bd(num_of_bd, data);
11501
      if (i_length[1] == 1'b0) // interrupt enabled
11502
      begin
11503
        if ( ((data[15:0] !== 16'h6000) && ((num_of_frames < 8) || ((num_of_frames - 8) == 127))) || // wrap bit
11504
             ((data[15:0] !== 16'h4000) && (num_of_frames >= 8) && ((num_of_frames - 8) != 127)) ) // without wrap bit
11505
        begin
11506
          `TIME; $display("*E RX buffer descriptor status is not correct: %0h", data[15:0]);
11507
          test_fail("RX buffer descriptor status is not correct");
11508
          fail = fail + 1;
11509
        end
11510
      end
11511
      else // interrupt not enabled
11512
      begin
11513
        if ( ((data[15:0] !== 16'h2000)  && ((num_of_frames < 8) || ((num_of_frames - 8) == 127))) || // wrap bit
11514
             ((data[15:0] !== 16'h0000) && (num_of_frames >= 8) && ((num_of_frames - 8) != 127)) ) // without wrap bit
11515
        begin
11516
          `TIME; $display("*E RX buffer descriptor status is not correct: %0h", data[15:0]);
11517
          test_fail("RX buffer descriptor status is not correct");
11518
          fail = fail + 1;
11519
        end
11520
      end
11521
      // clear first half of 8 frames from RX buffer descriptor 0
11522
      if (num_of_frames < 4)
11523
        clear_rx_bd(num_of_bd, num_of_bd);
11524
      // clear BD with wrap bit
11525
      if (num_of_frames == 140)
11526
        clear_rx_bd(127, 127);
11527
      // check interrupts
11528
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11529
      if ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1))
11530
      begin
11531
        if ((data & `ETH_INT_RXB) !== `ETH_INT_RXB)
11532
        begin
11533
          `TIME; $display("*E Interrupt Receive Buffer was not set, interrupt reg: %0h", data);
11534
          test_fail("Interrupt Receive Buffer was not set");
11535
          fail = fail + 1;
11536
        end
11537
        if ((data & (~`ETH_INT_RXB)) !== 0)
11538
        begin
11539
          `TIME; $display("*E Other interrupts (except Receive Buffer) were set, interrupt reg: %0h", data);
11540
          test_fail("Other interrupts (except Receive Buffer) were set");
11541
          fail = fail + 1;
11542
        end
11543
      end
11544
      else
11545
      begin
11546
        if (data !== 0)
11547
        begin
11548
          `TIME; $display("*E Any of interrupts (except Receive Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]);
11549
          test_fail("Any of interrupts (except Receive Buffer) was set");
11550
          fail = fail + 1;
11551
        end
11552
      end
11553
      // clear interrupts
11554
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11555
      // check WB INT signal
11556
      if (wb_int !== 1'b0)
11557
      begin
11558
        test_fail("WB INT signal should not be set");
11559
        fail = fail + 1;
11560
      end
11561
      // INTERMEDIATE DISPLAYS
11562
      if ((i_length + 4) == (min_tmp + 7))
11563
      begin
11564
        // starting length is min_tmp, ending length is (min_tmp + 128)
11565
        $display("    receive small packets is NOT selected");
11566
        $display("    using only RX BD 0 out of 128 BDs assigned to RX (wrap at first BD - RX BD 0)");
11567
        $display("    ->packets with lengths from %0d (MINFL) to %0d are checked (length increasing by 1 byte)",
11568
                 min_tmp, (min_tmp + 7));
11569
        $display("    ->all packets were received on RX BD 0");
11570
        // reset receive small, remain the rest
11571
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
11572
                  `ETH_MODER_PRO | `ETH_MODER_BRO,
11573
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11574
      end
11575
      else if ((i_length + 4) == (min_tmp + 128))
11576
      begin
11577
        // starting length is min_tmp, ending length is (min_tmp + 128)
11578
        $display("    receive small packets is NOT selected");
11579
        $display("    using all 128 BDs assigned to RX (wrap at 128th BD - RX BD 127)");
11580
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
11581
                 (min_tmp + 8), (min_tmp + 128));
11582
        $display("    ->packets were received on RX BD %0d to RX BD %0d respectively",
11583
                 1'b0, num_of_bd);
11584
        tmp_bd = num_of_bd + 1;
11585
        // set receive small, remain the rest
11586
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_IFG |
11587
                  `ETH_MODER_PRO | `ETH_MODER_BRO,
11588
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11589
      end
11590
      else if ((i_length + 4) == (max_tmp - 16))
11591
      begin
11592
        // starting length is for +128 longer than previous ending length, while ending length is tmp_data
11593
        $display("    receive small packets is selected");
11594
        $display("    using all 128 BDs assigned to RX (wrap at 128th BD - RX BD 127)");
11595
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 128 bytes)",
11596
                 (min_tmp + 64 + 128), tmp_data);
11597
        if (tmp_bd > num_of_bd)
11598
          $display("    ->packets were received from RX BD %0d to RX BD 127 and from RX BD 0 to RX BD %0d respectively",
11599
                   tmp_bd, num_of_bd);
11600
        else
11601
          $display("    ->packets were received from RX BD %0d to RX BD %0d respectively",
11602
                   tmp_bd, num_of_bd);
11603
        tmp_bd = num_of_bd + 1;
11604
        // reset receive small, remain the rest
11605
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
11606
                  `ETH_MODER_PRO | `ETH_MODER_BRO,
11607
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11608
      end
11609
      else if ((i_length + 4) == max_tmp)
11610
      begin
11611
        $display("    receive small packets is NOT selected");
11612
        $display("    using all 128 BDs assigned to RX (wrap at 128th BD - RX BD 127)");
11613
        $display("    ->packets with lengths from %0d to %0d (MAXFL) are checked (length increasing by 1 byte)",
11614
                 (max_tmp - (4 + 16)), max_tmp);
11615
        if (tmp_bd > num_of_bd)
11616
          $display("    ->packets were received from RX BD %0d to RX BD 127 and from RX BD 0 to RX BD %0d respectively",
11617
                   tmp_bd, num_of_bd);
11618
        else
11619
          $display("    ->packets were received from RX BD %0d to RX BD %0d respectively",
11620
                   tmp_bd, num_of_bd);
11621
      end
11622
      // set length (loop variable)
11623
      if ((i_length + 4) < (min_tmp + 128))
11624
        i_length = i_length + 1;
11625
      else if ( ((i_length + 4) == (min_tmp + 128)) && ((i_length + 4) <= (max_tmp - 256)) )
11626
        i_length = 256;
11627
      else if ( ((i_length + 4) > (min_tmp + 128)) && ((i_length + 4) <= (max_tmp - 256)) )
11628
      begin
11629
        i_length = i_length + 128;
11630
        tmp_data = i_length + 4; // last tmp_data is ending length
11631
      end
11632
      else if ( ((i_length + 4) > (max_tmp - 256)) && ((i_length + 4) < (max_tmp - 16)) )
11633
        i_length = max_tmp - (4 + 16);
11634
      else if ((i_length + 4) >= (max_tmp - 16))
11635
        i_length = i_length + 1;
11636
      else
11637
      begin
11638
        $display("*E TESTBENCH ERROR - WRONG PARAMETERS IN TESTBENCH");
11639
        #10 $stop;
11640
      end
11641
      // the number of frame transmitted
11642
      num_of_frames = num_of_frames + 1;
11643
      if ((num_of_frames <= 8) || ((num_of_frames - 8) == 128))
11644
        num_of_bd = 0;
11645
      else
11646
        num_of_bd = num_of_bd + 1;
11647
    end
11648
    // disable RX
11649
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_IFG |
11650
              `ETH_MODER_PRO | `ETH_MODER_BRO,
11651
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11652
    @(posedge wb_clk);
11653
    if(fail == 0)
11654
      test_ok;
11655
    else
11656
      fail = 0;
11657
  end
11658
 
11659
 
11660
  ////////////////////////////////////////////////////////////////////
11661
  ////                                                            ////
11662
  ////  Test receive packets form MINFL to MAXFL sizes at         ////
11663
  ////  maximum RX buffer decriptors ( 100Mbps ).                 ////
11664
  ////                                                            ////
11665
  ////////////////////////////////////////////////////////////////////
11666
  if (test_num == 5) // 
11667
  begin
11668
    // TEST 5: RECEIVE PACKETS FROM MINFL TO MAXFL SIZES AT MAX RX BDs ( 100Mbps )
11669
    test_name = "TEST 5: RECEIVE PACKETS FROM MINFL TO MAXFL SIZES AT MAX RX BDs ( 100Mbps )";
11670
    `TIME; $display("  TEST 5: RECEIVE PACKETS FROM MINFL TO MAXFL SIZES AT MAX RX BDs ( 100Mbps )");
11671
 
11672
    // reset MAC registers
11673
    hard_reset;
11674
    // reset MAC and MII LOGIC with soft reset
11675
    reset_mac;
11676
    reset_mii;
11677
    // set wb slave response
11678
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
11679
 
11680
    max_tmp = 0;
11681
    min_tmp = 0;
11682
    num_of_frames = 0;
11683
    num_of_bd = 0;
11684
    // set maximum RX buffer descriptors (128) - must be set before RX enable
11685
    wbm_write(`ETH_TX_BD_NUM, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11686
    // enable RX, set full-duplex mode, NO receive small, NO correct IFG
11687
    wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
11688
              `ETH_MODER_PRO | `ETH_MODER_BRO,
11689
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11690
    // prepare two packets of MAXFL length
11691
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11692
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
11693
    min_tmp = tmp[31:16];
11694
    st_data = 8'hAC;
11695
    set_rx_packet(0, (max_tmp - 4), 1'b0, 48'h0102_0304_0506, 48'h0708_090A_0B0C, 16'h0D0E, st_data); // length without CRC
11696
    st_data = 8'h35;
11697
    set_rx_packet((max_tmp), (max_tmp - 4), 1'b0, 48'h1234_5678_8765, 48'hA1B2_C3D4_E5F6, 16'hE77E, st_data);
11698
    // check WB INT signal
11699
    if (wb_int !== 1'b0)
11700
    begin
11701
      test_fail("WB INT signal should not be set");
11702
      fail = fail + 1;
11703
    end
11704
 
11705
    // write to phy's control register for 100Mbps
11706
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
11707
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
11708
    speed = 100;
11709
 
11710
    i_length = (min_tmp - 4);
11711
    while (i_length <= (max_tmp - 4))
11712
    begin
11713
      // append CRC to packet
11714
      if (i_length[0] == 1'b0)
11715
        append_rx_crc (0, i_length, 1'b0, 1'b0);
11716
      else
11717
        append_rx_crc (max_tmp, i_length, 1'b0, 1'b0);
11718
      // choose generating carrier sense and collision
11719
      case (i_length[1:0])
11720
      2'h0: // Interrupt is generated
11721
      begin
11722
        // Reset_tx_bd nable interrupt generation
11723
        // unmask interrupts
11724
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
11725
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11726
        // not detect carrier sense in FD and no collision
11727
        eth_phy.no_carrier_sense_rx_fd_detect(0);
11728
        eth_phy.collision(0);
11729
      end
11730
      2'h1: // Interrupt is not generated
11731
      begin
11732
        // set_tx_bd enable interrupt generation
11733
        // mask interrupts
11734
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11735
        // detect carrier sense in FD and no collision
11736
        eth_phy.no_carrier_sense_rx_fd_detect(1);
11737
        eth_phy.collision(0);
11738
      end
11739
      2'h2: // Interrupt is not generated
11740
      begin
11741
        // set_tx_bd disable the interrupt generation
11742
        // unmask interrupts
11743
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
11744
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11745
        // not detect carrier sense in FD and set collision
11746
        eth_phy.no_carrier_sense_rx_fd_detect(0);
11747
        eth_phy.collision(1);
11748
      end
11749
      default: // 2'h3: // Interrupt is not generated
11750
      begin
11751
        // set_tx_bd disable the interrupt generation
11752
        // mask interrupts
11753
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11754
        // detect carrier sense in FD and set collision
11755
        eth_phy.no_carrier_sense_rx_fd_detect(1);
11756
        eth_phy.collision(1);
11757
      end
11758
      endcase
11759
      // first 8 frames are received with RX BD 0 (wrap bit on RX BD 0)
11760
      // number of all frames is 154 (146 without first 8)
11761
      if (num_of_frames < 8)
11762
      begin
11763
        case (i_length[1:0])
11764
        2'h0: // Interrupt is generated
11765
        begin
11766
          // enable interrupt generation
11767
          set_rx_bd(0, 0, 1'b1, (`MEMORY_BASE + i_length[1:0]));
11768
          // interrupts are unmasked
11769
        end
11770
        2'h1: // Interrupt is not generated
11771
        begin
11772
          // enable interrupt generation
11773
          set_rx_bd(0, 0, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
11774
          // interrupts are masked
11775
        end
11776
        2'h2: // Interrupt is not generated
11777
        begin
11778
          // disable interrupt generation
11779
          set_rx_bd(0, 0, 1'b0, (`MEMORY_BASE + i_length[1:0]));
11780
          // interrupts are unmasked
11781
        end
11782
        default: // 2'h3: // Interrupt is not generated
11783
        begin
11784
          // disable interrupt generation
11785
          set_rx_bd(0, 0, 1'b0, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
11786
          // interrupts are masked
11787
        end
11788
        endcase
11789
        // set wrap bit
11790
        set_rx_bd_wrap(0);
11791
      end
11792
      // after first 8 number of frames, 128 frames form RX BD 0 to 127 will be received
11793
      else if ((num_of_frames - 8) == 0)
11794
      begin
11795
        tmp_len = i_length; // length of frame
11796
        tmp_bd_num = 0; // RX BD number
11797
        while (tmp_bd_num < 128) // (tmp_len <= (max_tmp - 4)) - this is the last frame
11798
        begin
11799
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
11800
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
11801
          if (tmp_len[0] == 0)
11802
            set_rx_bd(tmp_bd_num, tmp_bd_num, !tmp_len[1], (`MEMORY_BASE + tmp_len[1:0]));
11803
          else
11804
            set_rx_bd(tmp_bd_num, tmp_bd_num, !tmp_len[1], ((`MEMORY_BASE + tmp_len[1:0]) + max_tmp));
11805
          // set length (loop variable) - THE SAME AS AT THE END OF THIS TASK !!!
11806
          if ((tmp_len + 4) < (min_tmp + 128))
11807
            tmp_len = tmp_len + 1;
11808
          else if ( ((tmp_len + 4) == (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
11809
            tmp_len = 256;
11810
          else if ( ((tmp_len + 4) > (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
11811
            tmp_len = tmp_len + 128;
11812
          else if ( ((tmp_len + 4) > (max_tmp - 256)) && ((tmp_len + 4) < (max_tmp - 16)) )
11813
            tmp_len = max_tmp - (4 + 16);
11814
          else if ((tmp_len + 4) >= (max_tmp - 16))
11815
            tmp_len = tmp_len + 1;
11816
          // set RX BD number
11817
          tmp_bd_num = tmp_bd_num + 1;
11818
        end
11819
        // set wrap bit
11820
        set_rx_bd_wrap(127);
11821
      end
11822
      // after 128 + first 8 number of frames, 19 frames form RX BD 0 to 18 will be received
11823
      else if ((num_of_frames - 8) == 20) // 128
11824
      begin
11825
        tmp_len = tmp_len; // length of frame remaines from previous settings
11826
        tmp_bd_num = 0; // TX BD number
11827
        while (tmp_bd_num < 19) // (tmp_len <= (max_tmp - 4)) - this is the last frame
11828
        begin
11829
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
11830
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
11831
          if (tmp_len[0] == 0)
11832
            set_rx_bd(tmp_bd_num, tmp_bd_num, !tmp_len[1], (`MEMORY_BASE + tmp_len[1:0]));
11833
          else
11834
            set_rx_bd(tmp_bd_num, tmp_bd_num, !tmp_len[1], ((`MEMORY_BASE + tmp_len[1:0]) + max_tmp));
11835
          // set length (loop variable) - THE SAME AS AT THE END OF THIS TASK !!!
11836
          if ((tmp_len + 4) < (min_tmp + 128))
11837
            tmp_len = tmp_len + 1;
11838
          else if ( ((tmp_len + 4) == (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
11839
            tmp_len = 256;
11840
          else if ( ((tmp_len + 4) > (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
11841
            tmp_len = tmp_len + 128;
11842
          else if ( ((tmp_len + 4) > (max_tmp - 256)) && ((tmp_len + 4) < (max_tmp - 16)) )
11843
            tmp_len = max_tmp - (4 + 16);
11844
          else if ((tmp_len + 4) >= (max_tmp - 16))
11845
            tmp_len = tmp_len + 1;
11846
          // set TX BD number
11847
          tmp_bd_num = tmp_bd_num + 1;
11848
        end
11849
      end
11850
      // set empty bit
11851
      if (num_of_frames < 8)
11852
        set_rx_bd_empty(0, 0);
11853
      else if ((num_of_frames - 8) < 128)
11854
        set_rx_bd_empty((num_of_frames - 8), (num_of_frames - 8));
11855
      else if ((num_of_frames - 136) < 19)
11856
        set_rx_bd_empty((num_of_frames - 136), (num_of_frames - 136));
11857
      // CHECK END OF RECEIVE
11858
      fork
11859
        begin
11860
          if (i_length[0] == 1'b0)
11861
            #1 eth_phy.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, 8'hD5, 0, (i_length + 4), 1'b0);
11862
          else
11863
            #1 eth_phy.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, 8'hD5, max_tmp, (i_length + 4), 1'b0);
11864
          repeat(10) @(posedge mrx_clk);
11865
        end
11866
        begin
11867
          #1 check_rx_bd(num_of_bd, data);
11868
          if (i_length < min_tmp) // just first four
11869
          begin
11870
            while (data[15] === 1)
11871
            begin
11872
              #1 check_rx_bd(num_of_bd, data);
11873
              @(posedge wb_clk);
11874
            end
11875
            repeat (1) @(posedge wb_clk);
11876
          end
11877
          else
11878
          begin
11879
            wait (MRxDV === 1'b1); // start transmit
11880
            #1 check_rx_bd(num_of_bd, data);
11881
            if (data[15] !== 1)
11882
            begin
11883
              test_fail("Wrong buffer descriptor's ready bit read out from MAC");
11884
              fail = fail + 1;
11885
            end
11886
            wait (MRxDV === 1'b0); // end transmit
11887
            while (data[15] === 1)
11888
            begin
11889
              #1 check_rx_bd(num_of_bd, data);
11890
              @(posedge wb_clk);
11891
            end
11892
            repeat (1) @(posedge wb_clk);
11893
          end
11894
        end
11895
      join
11896
      // check length of a PACKET
11897
      if (data[31:16] != (i_length + 4))
11898
      begin
11899
        `TIME; $display("*E Wrong length of the packet out from PHY (%0d instead of %0d)",
11900
                        data[31:16], (i_length + 4));
11901
        test_fail("Wrong length of the packet out from PHY");
11902
        fail = fail + 1;
11903
      end
11904
      // checking in the following if statement is performed only for first and last 64 lengths
11905
      // check received RX packet data and CRC
11906
      if (i_length[0] == 1'b0)
11907
      begin
11908
        check_rx_packet(0, (`MEMORY_BASE + i_length[1:0]), (i_length + 4), 1'b0, 1'b0, tmp);
11909
      end
11910
      else
11911
      begin
11912
        check_rx_packet(max_tmp, ((`MEMORY_BASE + i_length[1:0]) + max_tmp), (i_length + 4), 1'b0, 1'b0, tmp);
11913
      end
11914
      if (tmp > 0)
11915
      begin
11916
        `TIME; $display("*E Wrong data of the received packet");
11917
        test_fail("Wrong data of the received packet");
11918
        fail = fail + 1;
11919
      end
11920
      // check WB INT signal
11921
      if (i_length[1:0] == 2'h0)
11922
      begin
11923
        if (wb_int !== 1'b1)
11924
        begin
11925
          `TIME; $display("*E WB INT signal should be set");
11926
          test_fail("WB INT signal should be set");
11927
          fail = fail + 1;
11928
        end
11929
      end
11930
      else
11931
      begin
11932
        if (wb_int !== 1'b0)
11933
        begin
11934
          `TIME; $display("*E WB INT signal should not be set");
11935
          test_fail("WB INT signal should not be set");
11936
          fail = fail + 1;
11937
        end
11938
      end
11939
      // check RX buffer descriptor of a packet
11940
      check_rx_bd(num_of_bd, data);
11941
      if (i_length[1] == 1'b0) // interrupt enabled
11942
      begin
11943
        if ( ((data[15:0] !== 16'h6000) && ((num_of_frames < 8) || ((num_of_frames - 8) == 127))) || // wrap bit
11944
             ((data[15:0] !== 16'h4000) && (num_of_frames >= 8) && ((num_of_frames - 8) != 127)) ) // without wrap bit
11945
        begin
11946
          `TIME; $display("*E RX buffer descriptor status is not correct: %0h", data[15:0]);
11947
          test_fail("RX buffer descriptor status is not correct");
11948
          fail = fail + 1;
11949
        end
11950
      end
11951
      else // interrupt not enabled
11952
      begin
11953
        if ( ((data[15:0] !== 16'h2000)  && ((num_of_frames < 8) || ((num_of_frames - 8) == 127))) || // wrap bit
11954
             ((data[15:0] !== 16'h0000) && (num_of_frames >= 8) && ((num_of_frames - 8) != 127)) ) // without wrap bit
11955
        begin
11956
          `TIME; $display("*E RX buffer descriptor status is not correct: %0h", data[15:0]);
11957
          test_fail("RX buffer descriptor status is not correct");
11958
          fail = fail + 1;
11959
        end
11960
      end
11961
      // clear first half of 8 frames from RX buffer descriptor 0
11962
      if (num_of_frames < 4)
11963
        clear_rx_bd(num_of_bd, num_of_bd);
11964
      // clear BD with wrap bit
11965
      if (num_of_frames == 140)
11966
        clear_rx_bd(127, 127);
11967
      // check interrupts
11968
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11969
      if ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1))
11970
      begin
11971
        if ((data & `ETH_INT_RXB) !== `ETH_INT_RXB)
11972
        begin
11973
          `TIME; $display("*E Interrupt Receive Buffer was not set, interrupt reg: %0h", data);
11974
          test_fail("Interrupt Receive Buffer was not set");
11975
          fail = fail + 1;
11976
        end
11977
        if ((data & (~`ETH_INT_RXB)) !== 0)
11978
        begin
11979
          `TIME; $display("*E Other interrupts (except Receive Buffer) were set, interrupt reg: %0h", data);
11980
          test_fail("Other interrupts (except Receive Buffer) were set");
11981
          fail = fail + 1;
11982
        end
11983
      end
11984
      else
11985
      begin
11986
        if (data !== 0)
11987
        begin
11988
          `TIME; $display("*E Any of interrupts (except Receive Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]);
11989
          test_fail("Any of interrupts (except Receive Buffer) was set");
11990
          fail = fail + 1;
11991
        end
11992
      end
11993
      // clear interrupts
11994
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11995
      // check WB INT signal
11996
      if (wb_int !== 1'b0)
11997
      begin
11998
        test_fail("WB INT signal should not be set");
11999
        fail = fail + 1;
12000
      end
12001
      // INTERMEDIATE DISPLAYS
12002
      if ((i_length + 4) == (min_tmp + 7))
12003
      begin
12004
        // starting length is min_tmp, ending length is (min_tmp + 128)
12005
        $display("    receive small packets is NOT selected");
12006
        $display("    using only RX BD 0 out of 128 BDs assigned to RX (wrap at first BD - RX BD 0)");
12007
        $display("    ->packets with lengths from %0d (MINFL) to %0d are checked (length increasing by 1 byte)",
12008
                 min_tmp, (min_tmp + 7));
12009
        $display("    ->all packets were received on RX BD 0");
12010
        // reset receive small, remain the rest
12011
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
12012
                  `ETH_MODER_PRO | `ETH_MODER_BRO,
12013
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12014
      end
12015
      else if ((i_length + 4) == (min_tmp + 128))
12016
      begin
12017
        // starting length is min_tmp, ending length is (min_tmp + 128)
12018
        $display("    receive small packets is NOT selected");
12019
        $display("    using all 128 BDs assigned to RX (wrap at 128th BD - RX BD 127)");
12020
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
12021
                 (min_tmp + 8), (min_tmp + 128));
12022
        $display("    ->packets were received on RX BD %0d to RX BD %0d respectively",
12023
                 1'b0, num_of_bd);
12024
        tmp_bd = num_of_bd + 1;
12025
        // set receive small, remain the rest
12026
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_IFG |
12027
                  `ETH_MODER_PRO | `ETH_MODER_BRO,
12028
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12029
      end
12030
      else if ((i_length + 4) == (max_tmp - 16))
12031
      begin
12032
        // starting length is for +128 longer than previous ending length, while ending length is tmp_data
12033
        $display("    receive small packets is selected");
12034
        $display("    using all 128 BDs assigned to RX (wrap at 128th BD - RX BD 127)");
12035
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 128 bytes)",
12036
                 (min_tmp + 64 + 128), tmp_data);
12037
        if (tmp_bd > num_of_bd)
12038
          $display("    ->packets were received from RX BD %0d to RX BD 127 and from RX BD 0 to RX BD %0d respectively",
12039
                   tmp_bd, num_of_bd);
12040
        else
12041
          $display("    ->packets were received from RX BD %0d to RX BD %0d respectively",
12042
                   tmp_bd, num_of_bd);
12043
        tmp_bd = num_of_bd + 1;
12044
        // reset receive small, remain the rest
12045
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
12046
                  `ETH_MODER_PRO | `ETH_MODER_BRO,
12047
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12048
      end
12049
      else if ((i_length + 4) == max_tmp)
12050
      begin
12051
        $display("    receive small packets is NOT selected");
12052
        $display("    using all 128 BDs assigned to RX (wrap at 128th BD - RX BD 127)");
12053
        $display("    ->packets with lengths from %0d to %0d (MAXFL) are checked (length increasing by 1 byte)",
12054
                 (max_tmp - (4 + 16)), max_tmp);
12055
        if (tmp_bd > num_of_bd)
12056
          $display("    ->packets were received from RX BD %0d to RX BD 127 and from RX BD 0 to RX BD %0d respectively",
12057
                   tmp_bd, num_of_bd);
12058
        else
12059
          $display("    ->packets were received from RX BD %0d to RX BD %0d respectively",
12060
                   tmp_bd, num_of_bd);
12061
      end
12062
      // set length (loop variable)
12063
      if ((i_length + 4) < (min_tmp + 128))
12064
        i_length = i_length + 1;
12065
      else if ( ((i_length + 4) == (min_tmp + 128)) && ((i_length + 4) <= (max_tmp - 256)) )
12066
        i_length = 256;
12067
      else if ( ((i_length + 4) > (min_tmp + 128)) && ((i_length + 4) <= (max_tmp - 256)) )
12068
      begin
12069
        i_length = i_length + 128;
12070
        tmp_data = i_length + 4; // last tmp_data is ending length
12071
      end
12072
      else if ( ((i_length + 4) > (max_tmp - 256)) && ((i_length + 4) < (max_tmp - 16)) )
12073
        i_length = max_tmp - (4 + 16);
12074
      else if ((i_length + 4) >= (max_tmp - 16))
12075
        i_length = i_length + 1;
12076
      else
12077
      begin
12078
        $display("*E TESTBENCH ERROR - WRONG PARAMETERS IN TESTBENCH");
12079
        #10 $stop;
12080
      end
12081
      // the number of frame transmitted
12082
      num_of_frames = num_of_frames + 1;
12083
      if ((num_of_frames <= 8) || ((num_of_frames - 8) == 128))
12084
        num_of_bd = 0;
12085
      else
12086
        num_of_bd = num_of_bd + 1;
12087
    end
12088
    // disable RX
12089
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_IFG |
12090
              `ETH_MODER_PRO | `ETH_MODER_BRO,
12091
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12092
    @(posedge wb_clk);
12093
    if(fail == 0)
12094
      test_ok;
12095
    else
12096
      fail = 0;
12097
  end
12098
 
12099
 
12100
  ////////////////////////////////////////////////////////////////////
12101
  ////                                                            ////
12102
  ////  Test receive packets form 0 to (MINFL - 1) sizes at       ////
12103
  ////  8 RX buffer decriptors ( 10Mbps ).                        ////
12104
  ////                                                            ////
12105
  ////////////////////////////////////////////////////////////////////
12106
  if (test_num == 6) // 
12107
  begin
12108
    // TEST 6: TRANSMIT PACKETS FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 10Mbps )
12109
    test_name = "TEST 6: TRANSMIT PACKETS FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 10Mbps )";
12110
    `TIME; $display("  TEST 6: TRANSMIT PACKETS FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 10Mbps )");
12111
 
12112
    // reset MAC registers
12113
    hard_reset;
12114
    // reset MAC and MII LOGIC with soft reset
12115
    reset_mac;
12116
    reset_mii;
12117
    // set wb slave response
12118
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
12119
 
12120
    max_tmp = 0;
12121
    min_tmp = 0;
12122
    // set 8 RX buffer descriptors (120 - 127) - must be set before RX enable
12123
    wbm_write(`ETH_TX_BD_NUM, 32'h78, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12124
    // enable RX, set full-duplex mode, receive small, NO correct IFG
12125
    wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_IFG |
12126
              `ETH_MODER_PRO | `ETH_MODER_BRO,
12127
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12128
    // prepare two packets of MAXFL length
12129
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12130
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
12131
    min_tmp = tmp[31:16];
12132
    st_data = 8'hAC;
12133
    set_rx_packet(0, (max_tmp - 4), 1'b0, 48'h0102_0304_0506, 48'h0708_090A_0B0C, 16'h0D0E, st_data); // length without CRC
12134
    st_data = 8'h35;
12135
    set_rx_packet((max_tmp), (max_tmp - 4), 1'b0, 48'h1234_5678_8765, 48'hA1B2_C3D4_E5F6, 16'hE77E, st_data);
12136
    // check WB INT signal
12137
    if (wb_int !== 1'b0)
12138
    begin
12139
      test_fail("WB INT signal should not be set");
12140
      fail = fail + 1;
12141
    end
12142
 
12143
    // write to phy's control register for 10Mbps
12144
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
12145
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
12146
    speed = 10;
12147
 
12148
    frame_started = 0;
12149
    num_of_frames = 0;
12150
    num_of_bd = 0;
12151
    i_length = 0; // 0;
12152
    while (i_length < 70) // (min_tmp - 4))
12153
    begin
12154
      #1;
12155
      // choose generating carrier sense and collision
12156
      case (i_length[1:0])
12157
      2'h0: // Interrupt is generated
12158
      begin
12159
        // Reset_tx_bd nable interrupt generation
12160
        // unmask interrupts
12161
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
12162
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12163
        // not detect carrier sense in FD and no collision
12164
        eth_phy.carrier_sense_tx_fd_detect(0);
12165
        eth_phy.collision(0);
12166
      end
12167
      2'h1: // Interrupt is not generated
12168
      begin
12169
        // set_tx_bd enable interrupt generation
12170
        // mask interrupts
12171
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12172
        // detect carrier sense in FD and no collision
12173
        eth_phy.carrier_sense_tx_fd_detect(1);
12174
        eth_phy.collision(0);
12175
      end
12176
      2'h2: // Interrupt is not generated
12177
      begin
12178
        // set_tx_bd disable the interrupt generation
12179
        // unmask interrupts
12180
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
12181
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12182
        // not detect carrier sense in FD and set collision
12183
        eth_phy.carrier_sense_tx_fd_detect(0);
12184
        eth_phy.collision(1);
12185
      end
12186
      default: // 2'h3: // Interrupt is not generated
12187
      begin
12188
        // set_tx_bd disable the interrupt generation
12189
        // mask interrupts
12190
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12191
        // detect carrier sense in FD and set collision
12192
        eth_phy.carrier_sense_tx_fd_detect(1);
12193
        eth_phy.collision(1);
12194
      end
12195
      endcase
12196
      #1;
12197
      // first destination address on ethernet PHY
12198
      eth_phy.set_tx_mem_addr(num_of_frames * 16);
12199
      // SET packets and wrap bit
12200
      // num_of_frames <= 9 => wrap set to TX BD 0
12201
      if (num_of_frames <= 9)
12202
      begin
12203
        tmp_len = i_length; // length of frame
12204
        tmp_bd_num = 0; // TX BD number
12205
        // if i_length[1] == 0 then enable interrupt generation otherwise disable it
12206
        // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
12207
        if (tmp_len[0] == 0)
12208
          set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
12209
        else
12210
          set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
12211
        // set wrap bit
12212
        set_tx_bd_wrap(0);
12213
      end
12214
      // 10 <= num_of_frames < 18 => wrap set to TX BD 3
12215
      else if ((num_of_frames == 10) || (num_of_frames == 14))
12216
      begin
12217
        tmp_len = i_length; // length of frame
12218
        tmp_bd_num = 0; // TX BD number
12219
        while (tmp_bd_num < 4) //
12220
        begin
12221
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
12222
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
12223
          if (tmp_len[0] == 0)
12224
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
12225
          else
12226
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
12227
          tmp_len = tmp_len + 1;
12228
          // set TX BD number
12229
          tmp_bd_num = tmp_bd_num + 1;
12230
        end
12231
        // set wrap bit
12232
        set_tx_bd_wrap(3);
12233
      end
12234
      // 18 <= num_of_frames < 28 => wrap set to TX BD 4
12235
      else if ((num_of_frames == 18) || (num_of_frames == 23))
12236
      begin
12237
        tmp_len = i_length; // length of frame
12238
        tmp_bd_num = 0; // TX BD number
12239
        while (tmp_bd_num < 5) //
12240
        begin
12241
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
12242
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
12243
          if (tmp_len[0] == 0)
12244
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
12245
          else
12246
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
12247
          tmp_len = tmp_len + 1;
12248
          // set TX BD number
12249
          tmp_bd_num = tmp_bd_num + 1;
12250
        end
12251
        // set wrap bit
12252
        set_tx_bd_wrap(4);
12253
      end
12254
      // 28 <= num_of_frames < 40 => wrap set to TX BD 5
12255
      else if ((num_of_frames == 28) || (num_of_frames == 34))
12256
      begin
12257
        tmp_len = i_length; // length of frame
12258
        tmp_bd_num = 0; // TX BD number
12259
        while (tmp_bd_num < 6) //
12260
        begin
12261
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
12262
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
12263
          if (tmp_len[0] == 0)
12264
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
12265
          else
12266
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
12267
          tmp_len = tmp_len + 1;
12268
          // set TX BD number
12269
          tmp_bd_num = tmp_bd_num + 1;
12270
        end
12271
        // set wrap bit
12272
        set_tx_bd_wrap(5);
12273
      end
12274
      // 40 <= num_of_frames < 54 => wrap set to TX BD 6
12275
      else if ((num_of_frames == 40) || (num_of_frames == 47))
12276
      begin
12277
        tmp_len = i_length; // length of frame
12278
        tmp_bd_num = 0; // TX BD number
12279
        while (tmp_bd_num < 7) //
12280
        begin
12281
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
12282
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
12283
          if (tmp_len[0] == 0)
12284
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
12285
          else
12286
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
12287
          tmp_len = tmp_len + 1;
12288
          // set TX BD number
12289
          tmp_bd_num = tmp_bd_num + 1;
12290
        end
12291
        // set wrap bit
12292
        set_tx_bd_wrap(6);
12293
      end
12294
      // 54 <= num_of_frames < 70 => wrap set to TX BD 7
12295
      else if ((num_of_frames == 54) || (num_of_frames == 62))
12296
      begin
12297
        tmp_len = i_length; // length of frame
12298
        tmp_bd_num = 0; // TX BD number
12299
        while (tmp_bd_num < 8) //
12300
        begin
12301
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
12302
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
12303
          if (tmp_len[0] == 0)
12304
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
12305
          else
12306
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
12307
          tmp_len = tmp_len + 1;
12308
          // set TX BD number
12309
          tmp_bd_num = tmp_bd_num + 1;
12310
        end
12311
        // set wrap bit
12312
        set_tx_bd_wrap(7);
12313
      end
12314
      #1;
12315
      // SET ready bit
12316
      if (num_of_frames < 10)
12317
        set_tx_bd_ready(0, 0);
12318
      else if (num_of_frames < 14)
12319
        set_tx_bd_ready((num_of_frames - 10), (num_of_frames - 10));
12320
      else if (num_of_frames < 18)
12321
        set_tx_bd_ready((num_of_frames - 14), (num_of_frames - 14));
12322
      else if (num_of_frames < 23)
12323
        set_tx_bd_ready((num_of_frames - 18), (num_of_frames - 18));
12324
      else if (num_of_frames < 28)
12325
        set_tx_bd_ready((num_of_frames - 23), (num_of_frames - 23));
12326
      else if (num_of_frames < 34)
12327
        set_tx_bd_ready((num_of_frames - 28), (num_of_frames - 28));
12328
      else if (num_of_frames < 40)
12329
        set_tx_bd_ready((num_of_frames - 34), (num_of_frames - 34));
12330
      else if (num_of_frames < 47)
12331
        set_tx_bd_ready((num_of_frames - 40), (num_of_frames - 40));
12332
      else if (num_of_frames < 54)
12333
        set_tx_bd_ready((num_of_frames - 47), (num_of_frames - 47));
12334
      else if (num_of_frames < 62)
12335
        set_tx_bd_ready((num_of_frames - 54), (num_of_frames - 54));
12336
      else if (num_of_frames < 70)
12337
        set_tx_bd_ready((num_of_frames - 62), (num_of_frames - 62));
12338
      // CHECK END OF TRANSMITION
12339
      frame_started = 0;
12340
      if (num_of_frames >= 5)
12341
        #1 check_tx_bd(num_of_bd, data);
12342
      fork
12343
      begin: fr_st
12344
        wait (MTxEn === 1'b1); // start transmit
12345
        frame_started = 1;
12346
      end
12347
      begin
12348
        repeat (30) @(posedge mtx_clk);
12349
        if (num_of_frames < 5)
12350
        begin
12351
          if (frame_started == 1)
12352
          begin
12353
            `TIME; $display("*E Frame should NOT start!");
12354
          end
12355
          disable fr_st;
12356
        end
12357
        else
12358
        begin
12359
          if (frame_started == 0)
12360
          begin
12361
            `TIME; $display("*W Frame should start!");
12362
            disable fr_st;
12363
          end
12364
        end
12365
      end
12366
      join
12367
      // check packets larger than 4 bytes
12368
      if (num_of_frames >= 5)
12369
      begin
12370
        wait (MTxEn === 1'b0); // end transmit
12371
        while (data[15] === 1)
12372
        begin
12373
          #1 check_tx_bd(num_of_bd, data);
12374
          @(posedge wb_clk);
12375
        end
12376
        repeat (1) @(posedge wb_clk);
12377
        // check length of a PACKET
12378
        if (i_length <= (min_tmp - 4))
12379
        begin
12380
          if (eth_phy.tx_len != min_tmp)
12381
          begin
12382
            test_fail("Wrong length of the packet out from MAC");
12383
            fail = fail + 1;
12384
          end
12385
        end
12386
        else
12387
        begin
12388
          if (eth_phy.tx_len != (i_length + 4))
12389
          begin
12390
            test_fail("Wrong length of the packet out from MAC");
12391
            fail = fail + 1;
12392
          end
12393
        end
12394
        // check transmitted TX packet data
12395
        if (i_length[0] == 0)
12396
        begin
12397
          #1 check_tx_packet(`MEMORY_BASE, (num_of_frames * 16), i_length, tmp);
12398
        end
12399
        else
12400
        begin
12401
          #1 check_tx_packet((`MEMORY_BASE + max_tmp), (num_of_frames * 16), i_length, tmp);
12402
        end
12403
        if (tmp > 0)
12404
        begin
12405
          test_fail("Wrong data of the transmitted packet");
12406
          fail = fail + 1;
12407
        end
12408
        // check transmited TX packet CRC
12409
        if (num_of_frames < (min_tmp - 4))
12410
          #1 check_tx_crc((num_of_frames * 16), (min_tmp - 4), 1'b0, tmp); // length without CRC
12411
        else
12412
          #1 check_tx_crc((num_of_frames * 16), i_length, 1'b0, tmp); // length without CRC
12413
        if (tmp > 0)
12414
        begin
12415
          test_fail("Wrong CRC of the transmitted packet");
12416
          fail = fail + 1;
12417
        end
12418
      end
12419
      // check WB INT signal
12420
      if ((i_length[1:0] == 2'h0) && (num_of_frames >= 5))
12421
      begin
12422
        if (wb_int !== 1'b1)
12423
        begin
12424
          `TIME; $display("*E WB INT signal should be set");
12425
          test_fail("WB INT signal should be set");
12426
          fail = fail + 1;
12427
        end
12428
      end
12429
      else
12430
      begin
12431
        if (wb_int !== 1'b0)
12432
        begin
12433
          `TIME; $display("*E WB INT signal should not be set");
12434
          test_fail("WB INT signal should not be set");
12435
          fail = fail + 1;
12436
        end
12437
      end
12438
      // check TX buffer descriptor of a packet
12439
      check_tx_bd(num_of_bd, data);
12440
      if (num_of_frames >= 5)
12441
      begin
12442
        if (i_length[1] == 1'b0) // interrupt enabled
12443
        begin
12444
          if ( (data[15:0] !== 16'h7800) && // wrap bit
12445
               (data[15:0] !== 16'h5800) ) // without wrap bit
12446
          begin
12447
            `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
12448
            test_fail("TX buffer descriptor status is not correct");
12449
            fail = fail + 1;
12450
          end
12451
        end
12452
        else // interrupt not enabled
12453
        begin
12454
          if ( (data[15:0] !== 16'h3800) && // wrap bit
12455
               (data[15:0] !== 16'h1800) ) // without wrap bit
12456
          begin
12457
            `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
12458
            test_fail("TX buffer descriptor status is not correct");
12459
            fail = fail + 1;
12460
          end
12461
        end
12462
      end
12463
      else
12464
      begin
12465
        if (data[15] !== 1'b1)
12466
        begin
12467
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
12468
          test_fail("TX buffer descriptor status is not correct");
12469
          fail = fail + 1;
12470
        end
12471
      end
12472
      // clear TX BD with wrap bit
12473
      if (num_of_frames == 63)
12474
        clear_tx_bd(16, 16);
12475
      // check interrupts
12476
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12477
      if ( ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1)) && (num_of_frames >= 5) )
12478
      begin
12479
        if ((data & `ETH_INT_TXB) !== 1'b1)
12480
        begin
12481
          `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
12482
          test_fail("Interrupt Transmit Buffer was not set");
12483
          fail = fail + 1;
12484
        end
12485
        if ((data & (~`ETH_INT_TXB)) !== 0)
12486
        begin
12487
          `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
12488
          test_fail("Other interrupts (except Transmit Buffer) were set");
12489
          fail = fail + 1;
12490
        end
12491
      end
12492
      else
12493
      begin
12494
        if (data !== 0)
12495
        begin
12496
          `TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]);
12497
          test_fail("Any of interrupts (except Transmit Buffer) was set");
12498
          fail = fail + 1;
12499
        end
12500
      end
12501
      // clear interrupts
12502
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12503
      // check WB INT signal
12504
      if (wb_int !== 1'b0)
12505
      begin
12506
        test_fail("WB INT signal should not be set");
12507
        fail = fail + 1;
12508
      end
12509
      // INTERMEDIATE DISPLAYS
12510
      if (i_length == 3)
12511
      begin
12512
        $display("    pads appending to packets is selected");
12513
        $display("    using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)");
12514
        $display("    ->packets with lengths from %0d to %0d are not transmitted (length increasing by 1 byte)",
12515
                 0, 3);
12516
      end
12517
      else if (i_length == 9)
12518
      begin
12519
        $display("    using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)");
12520
        $display("    ->packet with length 4 is not transmitted (length increasing by 1 byte)");
12521
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
12522
                 5, 9);
12523
      end
12524
      else if (i_length == 17)
12525
      begin
12526
        $display("    using 4 BDs out of 8 BDs assigned to TX (wrap at 4th BD - TX BD 3)");
12527
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
12528
                 10, 17);
12529
      end
12530
      else if (i_length == 27)
12531
      begin
12532
        $display("    using 5 BDs out of 8 BDs assigned to TX (wrap at 5th BD - TX BD 4)");
12533
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
12534
                 18, 27);
12535
      end
12536
      else if (i_length == 40)
12537
      begin
12538
        $display("    using 6 BDs out of 8 BDs assigned to TX (wrap at 6th BD - TX BD 5)");
12539
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
12540
                 28, 40);
12541
      end
12542
      else if (i_length == 54)
12543
      begin
12544
        $display("    using 7 BDs out of 8 BDs assigned to TX (wrap at 7th BD - TX BD 6)");
12545
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
12546
                 41, 54);
12547
      end
12548
      else if (i_length == 69)
12549
      begin
12550
        $display("    using 8 BDs out of 8 BDs assigned to TX (wrap at 8th BD - TX BD 7)");
12551
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
12552
                 55, 69);
12553
      end
12554
      // set length (loop variable)
12555
      i_length = i_length + 1;
12556
      // the number of frame transmitted
12557
      num_of_frames = num_of_frames + 1;
12558
      if (/*(num_of_frames == 2) || (num_of_frames == 4) || (num_of_frames == 7) ||*/ (num_of_frames <= 10) ||
12559
          (num_of_frames == 14) || (num_of_frames == 18) || (num_of_frames == 23) || (num_of_frames == 28) ||
12560
          (num_of_frames == 34) || (num_of_frames == 40) || (num_of_frames == 47) ||
12561
          (num_of_frames == 54) || (num_of_frames == 62))
12562
        num_of_bd = 0;
12563
      else
12564
        num_of_bd = num_of_bd + 1;
12565
    end
12566
    // disable TX
12567
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
12568
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12569
    @(posedge wb_clk);
12570
    if(fail == 0)
12571
      test_ok;
12572
    else
12573
      fail = 0;
12574
  end
12575
 
12576
 
12577
 
12578
end   //  for (test_num=start_task; test_num <= end_task; test_num=test_num+1)
12579
 
12580
end
12581
endtask // test_mac_full_duplex_receive
12582
 
12583
 
12584
task test_mac_full_duplex_flow;
12585
  input  [31:0]  start_task;
12586
  input  [31:0]  end_task;
12587
  integer        bit_start_1;
12588
  integer        bit_end_1;
12589
  integer        bit_start_2;
12590
  integer        bit_end_2;
12591
  integer        num_of_reg;
12592
  integer        num_of_frames;
12593
  integer        num_of_bd;
12594
  integer        i_addr;
12595
  integer        i_data;
12596
  integer        i_length;
12597
  integer        tmp_len;
12598
  integer        tmp_bd;
12599
  integer        tmp_bd_num;
12600
  integer        tmp_data;
12601
  integer        tmp_ipgt;
12602
  integer        test_num;
12603
  reg    [31:0]  tx_bd_num;
12604
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_data;
12605
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_tmp_data;
12606
  integer        i;
12607
  integer        i1;
12608
  integer        i2;
12609
  integer        i3;
12610
  integer        fail;
12611
  integer        speed;
12612
  reg            frame_started;
12613
  reg            frame_ended;
12614
  reg            wait_for_frame;
12615
  reg    [31:0]  addr;
12616
  reg    [31:0]  data;
12617
  reg    [31:0]  tmp;
12618
  reg    [ 7:0]  st_data;
12619
  reg    [15:0]  max_tmp;
12620
  reg    [15:0]  min_tmp;
12621
begin
12622
// MAC FULL DUPLEX FLOW TEST
12623
test_heading("MAC FULL DUPLEX FLOW TEST");
12624
$display(" ");
12625
$display("MAC FULL DUPLEX FLOW TEST");
12626
fail = 0;
12627
 
12628
// reset MAC registers
12629
hard_reset;
12630
// reset MAC and MII LOGIC with soft reset
12631
reset_mac;
12632
reset_mii;
12633
// set wb slave response
12634
wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
12635
 
12636
  /*
12637
  TASKS for set and control TX buffer descriptors (also send packet - set_tx_bd_ready):
12638
  -------------------------------------------------------------------------------------
12639
  set_tx_bd
12640
    (tx_bd_num_start[6:0], tx_bd_num_end[6:0], len[15:0], irq, pad, crc, txpnt[31:0]);
12641
  set_tx_bd_wrap
12642
    (tx_bd_num_end[6:0]);
12643
  set_tx_bd_ready
12644
    (tx_bd_num_start[6:0], tx_bd_num_end[6:0]);
12645
  check_tx_bd
12646
    (tx_bd_num_start[6:0], tx_bd_status[31:0]);
12647
  clear_tx_bd
12648
    (tx_bd_num_start[6:0], tx_bd_num_end[6:0]);
12649
 
12650
  TASKS for set and control RX buffer descriptors:
12651
  ------------------------------------------------
12652
  set_rx_bd
12653
    (rx_bd_num_strat[6:0], rx_bd_num_end[6:0], irq, rxpnt[31:0]);
12654
  set_rx_bd_wrap
12655
    (rx_bd_num_end[6:0]);
12656
  set_rx_bd_empty
12657
    (rx_bd_num_strat[6:0], rx_bd_num_end[6:0]);
12658
  check_rx_bd
12659
    (rx_bd_num_end[6:0], rx_bd_status);
12660
  clear_rx_bd
12661
    (rx_bd_num_strat[6:0], rx_bd_num_end[6:0]);
12662
 
12663
  TASKS for set and check TX packets:
12664
  -----------------------------------
12665
  set_tx_packet
12666
    (txpnt[31:0], len[15:0], eth_start_data[7:0]);
12667
  check_tx_packet
12668
    (txpnt_wb[31:0], txpnt_phy[31:0], len[15:0], failure[31:0]);
12669
 
12670
  TASKS for set and check RX packets:
12671
  -----------------------------------
12672
  set_rx_packet
12673
    (rxpnt[31:0], len[15:0], plus_nibble, d_addr[47:0], s_addr[47:0], type_len[15:0], start_data[7:0]);
12674
  check_rx_packet
12675
    (rxpnt_phy[31:0], rxpnt_wb[31:0], len[15:0], plus_nibble, successful_nibble, failure[31:0]);
12676
 
12677
  TASKS for append and check CRC to/of TX packet:
12678
  -----------------------------------------------
12679
  append_tx_crc
12680
    (txpnt_wb[31:0], len[15:0], negated_crc);
12681
  check_tx_crc
12682
    (txpnt_phy[31:0], len[15:0], negated_crc, failure[31:0]);
12683
 
12684
  TASK for append CRC to RX packet (CRC is checked together with check_rx_packet):
12685
  --------------------------------------------------------------------------------
12686
  append_rx_crc
12687
    (rxpnt_phy[31:0], len[15:0], plus_nibble, negated_crc);
12688
  */
12689
 
12690
//////////////////////////////////////////////////////////////////////
12691
////                                                              ////
12692
////  test_mac_full_duplex_flow:                                  ////
12693
////                                                              ////
12694
////  0: Test                                                     ////
12695
////                                                              ////
12696
//////////////////////////////////////////////////////////////////////
12697
for (test_num = start_task; test_num <= end_task; test_num = test_num + 1)
12698
begin
12699
 
12700
  ////////////////////////////////////////////////////////////////////
12701
  ////                                                            ////
12702
  ////  Test                                                      ////
12703
  ////                                                            ////
12704
  ////////////////////////////////////////////////////////////////////
12705
  if (test_num == 0) // Test 
12706
  begin
12707
    // TEST 0: 
12708
    test_name   = "TEST 0: ";
12709
    `TIME; $display("  TEST 0: ");
12710
 
12711
 
12712
  end
12713
 
12714
 
12715
 
12716
end   //  for (test_num=start_task; test_num <= end_task; test_num=test_num+1)
12717
 
12718
end
12719
endtask // test_mac_full_duplex_flow
12720
 
12721
 
12722 169 mohor
//////////////////////////////////////////////////////////////
12723
// WB Behavioral Models Basic tasks
12724
//////////////////////////////////////////////////////////////
12725
 
12726
task wbm_write;
12727
  input  [31:0] address_i;
12728
  input  [((`MAX_BLK_SIZE * 32) - 1):0] data_i;
12729
  input  [3:0]  sel_i;
12730
  input  [31:0] size_i;
12731
  input  [3:0]  init_waits_i;
12732
  input  [3:0]  subseq_waits_i;
12733
 
12734
  reg `WRITE_STIM_TYPE write_data;
12735
  reg `WB_TRANSFER_FLAGS flags;
12736
  reg `WRITE_RETURN_TYPE write_status;
12737
  integer i;
12738
begin
12739
  write_status = 0;
12740
 
12741
  flags                    = 0;
12742
  flags`WB_TRANSFER_SIZE   = size_i;
12743
  flags`INIT_WAITS         = init_waits_i;
12744
  flags`SUBSEQ_WAITS       = subseq_waits_i;
12745
 
12746
  write_data               = 0;
12747
  write_data`WRITE_DATA    = data_i[31:0];
12748
  write_data`WRITE_ADDRESS = address_i;
12749
  write_data`WRITE_SEL     = sel_i;
12750
 
12751
  for (i = 0; i < size_i; i = i + 1)
12752
  begin
12753
    wb_master.blk_write_data[i] = write_data;
12754
    data_i                      = data_i >> 32;
12755
    write_data`WRITE_DATA       = data_i[31:0];
12756
    write_data`WRITE_ADDRESS    = write_data`WRITE_ADDRESS + 4;
12757 116 mohor
  end
12758
 
12759 169 mohor
  wb_master.wb_block_write(flags, write_status);
12760 116 mohor
 
12761 169 mohor
  if (write_status`CYC_ACTUAL_TRANSFER !== size_i)
12762
  begin
12763
    `TIME;
12764
    $display("*E WISHBONE Master was unable to complete the requested write operation to MAC!");
12765
  end
12766
end
12767
endtask // wbm_write
12768 116 mohor
 
12769 169 mohor
task wbm_read;
12770
  input  [31:0] address_i;
12771
  output [((`MAX_BLK_SIZE * 32) - 1):0] data_o;
12772
  input  [3:0]  sel_i;
12773
  input  [31:0] size_i;
12774
  input  [3:0]  init_waits_i;
12775
  input  [3:0]  subseq_waits_i;
12776
 
12777
  reg `READ_RETURN_TYPE read_data;
12778
  reg `WB_TRANSFER_FLAGS flags;
12779
  reg `READ_RETURN_TYPE read_status;
12780
  integer i;
12781
begin
12782
  read_status = 0;
12783
  data_o      = 0;
12784
 
12785
  flags                  = 0;
12786
  flags`WB_TRANSFER_SIZE = size_i;
12787
  flags`INIT_WAITS       = init_waits_i;
12788
  flags`SUBSEQ_WAITS     = subseq_waits_i;
12789
 
12790
  read_data              = 0;
12791
  read_data`READ_ADDRESS = address_i;
12792
  read_data`READ_SEL     = sel_i;
12793
 
12794
  for (i = 0; i < size_i; i = i + 1)
12795 116 mohor
  begin
12796 169 mohor
    wb_master.blk_read_data_in[i] = read_data;
12797
    read_data`READ_ADDRESS        = read_data`READ_ADDRESS + 4;
12798
  end
12799
 
12800
  wb_master.wb_block_read(flags, read_status);
12801
 
12802
  if (read_status`CYC_ACTUAL_TRANSFER !== size_i)
12803
  begin
12804
    `TIME;
12805
    $display("*E WISHBONE Master was unable to complete the requested read operation from MAC!");
12806
  end
12807
 
12808
  for (i = 0; i < size_i; i = i + 1)
12809
  begin
12810
    data_o       = data_o << 32;
12811
    read_data    = wb_master.blk_read_data_out[(size_i - 1) - i]; // [31 - i];
12812
    data_o[31:0] = read_data`READ_DATA;
12813
  end
12814
end
12815
endtask // wbm_read
12816
 
12817
 
12818
//////////////////////////////////////////////////////////////
12819
// Ethernet Basic tasks
12820
//////////////////////////////////////////////////////////////
12821
 
12822
task hard_reset; //  MAC registers
12823
begin
12824
  // reset MAC registers
12825
  @(posedge wb_clk);
12826
  #2 wb_rst = 1'b1;
12827
  repeat(2) @(posedge wb_clk);
12828
  #2 wb_rst = 1'b0;
12829
end
12830
endtask // hard_reset
12831
 
12832
task reset_mac; //  MAC module
12833
  reg [31:0] tmp;
12834
  reg [31:0] tmp_no_rst;
12835
begin
12836
  // read MODER register first
12837
  wbm_read(`ETH_MODER, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12838
  // set reset bit - write back to MODER register with RESET bit
12839
  wbm_write(`ETH_MODER, (`ETH_MODER_RST | tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12840
  // clear reset bit - write back to MODER register without RESET bit
12841
  tmp_no_rst = `ETH_MODER_RST;
12842
  tmp_no_rst = ~tmp_no_rst;
12843
  wbm_write(`ETH_MODER, (tmp_no_rst & tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12844
end
12845
endtask // reset_mac
12846
 
12847
task set_tx_bd;
12848
  input  [6:0]  tx_bd_num_start;
12849
  input  [6:0]  tx_bd_num_end;
12850
  input  [15:0] len;
12851
  input         irq;
12852
  input         pad;
12853
  input         crc;
12854
  input  [31:0] txpnt;
12855
 
12856
  integer       i;
12857
  integer       bd_status_addr, bd_ptr_addr;
12858
//  integer       buf_addr;
12859
begin
12860
  for(i = tx_bd_num_start; i <= tx_bd_num_end; i = i + 1)
12861
  begin
12862
//    buf_addr = `TX_BUF_BASE + i * 32'h600;
12863
    bd_status_addr = `TX_BD_BASE + i * 8;
12864
    bd_ptr_addr = bd_status_addr + 4;
12865
    // initialize BD - status
12866
//    wbm_write(bd_status_addr, 32'h00005800, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // IRQ + PAD + CRC
12867
    wbm_write(bd_status_addr, {len, 1'b0, irq, 1'b0, pad, crc, 11'h0},
12868
              4'hF, 1, wbm_init_waits, wbm_subseq_waits); // IRQ + PAD + CRC
12869
    // initialize BD - pointer
12870
//    wbm_write(bd_ptr_addr, buf_addr, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Initializing BD-pointer
12871
    wbm_write(bd_ptr_addr, txpnt, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Initializing BD-pointer
12872
  end
12873
end
12874
endtask // set_tx_bd
12875
 
12876
task set_tx_bd_wrap;
12877
  input  [6:0]  tx_bd_num_end;
12878
  integer       bd_status_addr, tmp;
12879
begin
12880
  bd_status_addr = `TX_BD_BASE + tx_bd_num_end * 8;
12881
  wbm_read(bd_status_addr, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12882
  // set wrap bit to this BD - this BD should be last-one
12883
  wbm_write(bd_status_addr, (`ETH_TX_BD_WRAP | tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12884
end
12885
endtask // set_tx_bd_wrap
12886
 
12887
task set_tx_bd_ready;
12888
  input  [6:0]  tx_nd_num_strat;
12889
  input  [6:0]  tx_bd_num_end;
12890
  integer       i;
12891
  integer       bd_status_addr, tmp;
12892
begin
12893
  for(i = tx_nd_num_strat; i <= tx_bd_num_end; i = i + 1)
12894
  begin
12895
    bd_status_addr = `TX_BD_BASE + i * 8;
12896
    wbm_read(bd_status_addr, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12897
    // set empty bit to this BD - this BD should be ready
12898
    wbm_write(bd_status_addr, (`ETH_TX_BD_READY | tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12899
  end
12900
end
12901
endtask // set_tx_bd_ready
12902
 
12903
task check_tx_bd;
12904
  input  [6:0]  tx_bd_num_end;
12905
  output [31:0] tx_bd_status;
12906
  integer       bd_status_addr, tmp;
12907
begin
12908
  bd_status_addr = `TX_BD_BASE + tx_bd_num_end * 8;
12909
  wbm_read(bd_status_addr, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12910
  #1 tx_bd_status = tmp;
12911
  #1;
12912
end
12913
endtask // check_tx_bd
12914
 
12915
task clear_tx_bd;
12916
  input  [6:0]  tx_nd_num_strat;
12917
  input  [6:0]  tx_bd_num_end;
12918
  integer       i;
12919
  integer       bd_status_addr, bd_ptr_addr;
12920
begin
12921
  for(i = tx_nd_num_strat; i <= tx_bd_num_end; i = i + 1)
12922
  begin
12923
    bd_status_addr = `TX_BD_BASE + i * 8;
12924
    bd_ptr_addr = bd_status_addr + 4;
12925
    // clear BD - status
12926
    wbm_write(bd_status_addr, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12927
    // clear BD - pointer
12928
    wbm_write(bd_ptr_addr, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12929
  end
12930
end
12931
endtask // clear_tx_bd
12932
 
12933
task set_rx_bd;
12934
  input  [6:0]  rx_bd_num_strat;
12935
  input  [6:0]  rx_bd_num_end;
12936
  input         irq;
12937
  input  [31:0] rxpnt;
12938
//  input  [6:0]  rxbd_num;
12939
  integer       i;
12940
  integer       bd_status_addr, bd_ptr_addr;
12941
//  integer       buf_addr;
12942
begin
12943
  for(i = rx_bd_num_strat; i <= rx_bd_num_end; i = i + 1)
12944
  begin
12945
//    buf_addr = `RX_BUF_BASE + i * 32'h600;
12946 209 tadejm
//    bd_status_addr = `RX_BD_BASE + i * 8;
12947
//    bd_ptr_addr = bd_status_addr + 4; 
12948
    bd_status_addr = `TX_BD_BASE + i * 8;
12949
    bd_ptr_addr = bd_status_addr + 4;
12950 116 mohor
 
12951 169 mohor
    // initialize BD - status
12952
//    wbm_write(bd_status_addr, 32'h0000c000, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // IRQ + PAD + CRC
12953
    wbm_write(bd_status_addr, {17'h0, irq, 14'h0},
12954
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12955
    // initialize BD - pointer
12956
//    wbm_write(bd_ptr_addr, buf_addr, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Initializing BD-pointer
12957
    wbm_write(bd_ptr_addr, rxpnt, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Initializing BD-pointer
12958
  end
12959
end
12960
endtask // set_rx_bd
12961 116 mohor
 
12962 169 mohor
task set_rx_bd_wrap;
12963
  input  [6:0]  rx_bd_num_end;
12964
  integer       bd_status_addr, tmp;
12965
begin
12966 209 tadejm
//  bd_status_addr = `RX_BD_BASE + rx_bd_num_end * 8;
12967
  bd_status_addr = `TX_BD_BASE + rx_bd_num_end * 8;
12968 169 mohor
  wbm_read(bd_status_addr, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12969
  // set wrap bit to this BD - this BD should be last-one
12970
  wbm_write(bd_status_addr, (`ETH_RX_BD_WRAP | tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12971
end
12972
endtask // set_rx_bd_wrap
12973 116 mohor
 
12974 169 mohor
task set_rx_bd_empty;
12975
  input  [6:0]  rx_bd_num_strat;
12976
  input  [6:0]  rx_bd_num_end;
12977
  integer       i;
12978
  integer       bd_status_addr, tmp;
12979
begin
12980
  for(i = rx_bd_num_strat; i <= rx_bd_num_end; i = i + 1)
12981
  begin
12982 209 tadejm
//    bd_status_addr = `RX_BD_BASE + i * 8;
12983
    bd_status_addr = `TX_BD_BASE + i * 8;
12984 169 mohor
    wbm_read(bd_status_addr, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12985
    // set empty bit to this BD - this BD should be ready
12986
    wbm_write(bd_status_addr, (`ETH_RX_BD_EMPTY | tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12987 116 mohor
  end
12988 169 mohor
end
12989
endtask // set_rx_bd_empty
12990 116 mohor
 
12991 169 mohor
task check_rx_bd;
12992
  input  [6:0]  rx_bd_num_end;
12993
  output [31:0] rx_bd_status;
12994
  integer       bd_status_addr, tmp;
12995
begin
12996 209 tadejm
//  bd_status_addr = `RX_BD_BASE + rx_bd_num_end * 8;
12997
  bd_status_addr = `TX_BD_BASE + rx_bd_num_end * 8;
12998 169 mohor
  wbm_read(bd_status_addr, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12999
  #1 rx_bd_status = tmp;
13000
  #1;
13001
end
13002
endtask // check_rx_bd
13003 116 mohor
 
13004 169 mohor
task clear_rx_bd;
13005
  input  [6:0]  rx_bd_num_strat;
13006
  input  [6:0]  rx_bd_num_end;
13007
  integer       i;
13008
  integer       bd_status_addr, bd_ptr_addr;
13009
begin
13010
  for(i = rx_bd_num_strat; i <= rx_bd_num_end; i = i + 1)
13011
  begin
13012 209 tadejm
//    bd_status_addr = `RX_BD_BASE + i * 8;
13013
    bd_status_addr = `TX_BD_BASE + i * 8;
13014 169 mohor
    bd_ptr_addr = bd_status_addr + 4;
13015
    // clear BD - status
13016
    wbm_write(bd_status_addr, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
13017
    // clear BD - pointer
13018
    wbm_write(bd_ptr_addr, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
13019
  end
13020
end
13021
endtask // clear_rx_bd
13022 116 mohor
 
13023 169 mohor
task set_tx_packet;
13024
  input  [31:0] txpnt;
13025
  input  [15:0] len;
13026
  input  [7:0]  eth_start_data;
13027
  integer       i, sd;
13028
  integer       buffer;
13029
  reg           delta_t;
13030
begin
13031
  buffer = txpnt;
13032
  sd = eth_start_data;
13033
  delta_t = 0;
13034 116 mohor
 
13035 169 mohor
  // First write might not be word allign.
13036
  if(buffer[1:0] == 1)
13037
  begin
13038
    wb_slave.wr_mem(buffer - 1, {8'h0, sd[7:0], sd[7:0] + 3'h1, sd[7:0] + 3'h2}, 4'h7);
13039
    sd = sd + 3;
13040
    i = 3;
13041
  end
13042
  else if(buffer[1:0] == 2)
13043
  begin
13044
    wb_slave.wr_mem(buffer - 2, {16'h0, sd[7:0], sd[7:0] + 3'h1}, 4'h3);
13045
    sd = sd + 2;
13046
    i = 2;
13047
  end
13048
  else if(buffer[1:0] == 3)
13049
  begin
13050
    wb_slave.wr_mem(buffer - 3, {24'h0, sd[7:0]}, 4'h1);
13051
    sd = sd + 1;
13052
    i = 1;
13053
  end
13054
  else
13055
    i = 0;
13056
  delta_t = !delta_t;
13057 116 mohor
 
13058 169 mohor
  for(i = i; i < (len - 4); i = i + 4) // Last 0-3 bytes are not written
13059
  begin
13060
    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);
13061
    sd = sd + 4;
13062
  end
13063
  delta_t = !delta_t;
13064
 
13065
  // Last word
13066
  if((len - i) == 3)
13067 116 mohor
  begin
13068 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);
13069
  end
13070
  else if((len - i) == 2)
13071
  begin
13072
    wb_slave.wr_mem(buffer + i, {sd[7:0], sd[7:0] + 3'h1, 16'h0}, 4'hC);
13073
  end
13074
  else if((len - i) == 1)
13075
  begin
13076
    wb_slave.wr_mem(buffer + i, {sd[7:0], 24'h0}, 4'h8);
13077
  end
13078
  else if((len - i) == 4)
13079
  begin
13080
    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);
13081
  end
13082
  else
13083
    $display("(%0t)(%m) ERROR", $time);
13084
  delta_t = !delta_t;
13085
end
13086
endtask // set_tx_packet
13087
 
13088
task check_tx_packet;
13089
  input  [31:0] txpnt_wb;  // source
13090
  input  [31:0] txpnt_phy; // destination
13091
  input  [15:0] len;
13092
  output [31:0] failure;
13093
  integer       i, data_wb, data_phy;
13094
  reg    [31:0] addr_wb, addr_phy;
13095
  reg    [31:0] failure;
13096
  reg           delta_t;
13097
begin
13098
  addr_wb = txpnt_wb;
13099
  addr_phy = txpnt_phy;
13100
  delta_t = 0;
13101
  failure = 0;
13102 209 tadejm
  #1;
13103 169 mohor
  // First write might not be word allign.
13104
  if(addr_wb[1:0] == 1)
13105
  begin
13106
    wb_slave.rd_mem(addr_wb - 1, data_wb, 4'h7);
13107
    data_phy[31:24] = 0;
13108
    data_phy[23:16] = eth_phy.tx_mem[addr_phy[21:0]];
13109
    data_phy[15: 8] = eth_phy.tx_mem[addr_phy[21:0] + 1];
13110
    data_phy[ 7: 0] = eth_phy.tx_mem[addr_phy[21:0] + 2];
13111
    i = 3;
13112
    if (data_phy[23:0] !== data_wb[23:0])
13113
    begin
13114
      `TIME;
13115 209 tadejm
      $display("*E Wrong 1. word (3 bytes) of TX packet! phy: %0h, wb: %0h", data_phy[23:0], data_wb[23:0]);
13116
      $display("     address phy: %0h, address wb: %0h", addr_phy, addr_wb);
13117 169 mohor
      failure = 1;
13118
    end
13119
  end
13120
  else if (addr_wb[1:0] == 2)
13121
  begin
13122
    wb_slave.rd_mem(addr_wb - 2, data_wb, 4'h3);
13123
    data_phy[31:16] = 0;
13124
    data_phy[15: 8] = eth_phy.tx_mem[addr_phy[21:0]];
13125
    data_phy[ 7: 0] = eth_phy.tx_mem[addr_phy[21:0] + 1];
13126
    i = 2;
13127
    if (data_phy[15:0] !== data_wb[15:0])
13128
    begin
13129
      `TIME;
13130 209 tadejm
      $display("*E Wrong 1. word (2 bytes) of TX packet! phy: %0h, wb: %0h", data_phy[15:0], data_wb[15:0]);
13131
      $display("     address phy: %0h, address wb: %0h", addr_phy, addr_wb);
13132 169 mohor
      failure = 1;
13133
    end
13134
  end
13135
  else if (addr_wb[1:0] == 3)
13136
  begin
13137
    wb_slave.rd_mem(addr_wb - 3, data_wb, 4'h1);
13138
    data_phy[31: 8] = 0;
13139
    data_phy[ 7: 0] = eth_phy.tx_mem[addr_phy[21:0]];
13140
    i = 1;
13141
    if (data_phy[7:0] !== data_wb[7:0])
13142
    begin
13143
      `TIME;
13144 209 tadejm
      $display("*E Wrong 1. word (1 byte) of TX packet! phy: %0h, wb: %0h", data_phy[7:0], data_wb[7:0]);
13145
      $display("     address phy: %0h, address wb: %0h", addr_phy, addr_wb);
13146 169 mohor
      failure = 1;
13147
    end
13148
  end
13149
  else
13150
    i = 0;
13151
  delta_t = !delta_t;
13152 209 tadejm
  #1;
13153 169 mohor
  for(i = i; i < (len - 4); i = i + 4) // Last 0-3 bytes are not checked
13154
  begin
13155
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hF);
13156
    data_phy[31:24] = eth_phy.tx_mem[addr_phy[21:0] + i];
13157
    data_phy[23:16] = eth_phy.tx_mem[addr_phy[21:0] + i + 1];
13158
    data_phy[15: 8] = eth_phy.tx_mem[addr_phy[21:0] + i + 2];
13159
    data_phy[ 7: 0] = eth_phy.tx_mem[addr_phy[21:0] + i + 3];
13160
    if (data_phy[31:0] !== data_wb[31:0])
13161
    begin
13162
      `TIME;
13163 209 tadejm
      $display("*E Wrong %d. word (4 bytes) of TX packet! phy: %0h, wb: %0h", ((i/4)+1), data_phy[31:0], data_wb[31:0]);
13164
      $display("     address phy: %0h, address wb: %0h", addr_phy, addr_wb);
13165 169 mohor
      failure = failure + 1;
13166
    end
13167
  end
13168
  delta_t = !delta_t;
13169 209 tadejm
  #1;
13170 169 mohor
  // Last word
13171
  if((len - i) == 3)
13172
  begin
13173
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hE);
13174
    data_phy[31:24] = eth_phy.tx_mem[addr_phy[21:0] + i];
13175
    data_phy[23:16] = eth_phy.tx_mem[addr_phy[21:0] + i + 1];
13176
    data_phy[15: 8] = eth_phy.tx_mem[addr_phy[21:0] + i + 2];
13177
    data_phy[ 7: 0] = 0;
13178
    if (data_phy[31:8] !== data_wb[31:8])
13179
    begin
13180
      `TIME;
13181 209 tadejm
      $display("*E Wrong %d. word (3 bytes) of TX packet! phy: %0h, wb: %0h", ((i/4)+1), data_phy[31:8], data_wb[31:8]);
13182
      $display("     address phy: %0h, address wb: %0h", addr_phy, addr_wb);
13183 169 mohor
      failure = failure + 1;
13184
    end
13185
  end
13186
  else if((len - i) == 2)
13187
  begin
13188
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hC);
13189
    data_phy[31:24] = eth_phy.tx_mem[addr_phy[21:0] + i];
13190
    data_phy[23:16] = eth_phy.tx_mem[addr_phy[21:0] + i + 1];
13191
    data_phy[15: 8] = 0;
13192
    data_phy[ 7: 0] = 0;
13193
    if (data_phy[31:16] !== data_wb[31:16])
13194
    begin
13195
      `TIME;
13196 209 tadejm
      $display("*E Wrong %d. word (2 bytes) of TX packet! phy: %0h, wb: %0h", ((i/4)+1), data_phy[31:16], data_wb[31:16]);
13197
      $display("     address phy: %0h, address wb: %0h", addr_phy, addr_wb);
13198 169 mohor
      failure = failure + 1;
13199
    end
13200
  end
13201
  else if((len - i) == 1)
13202
  begin
13203
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'h8);
13204
    data_phy[31:24] = eth_phy.tx_mem[addr_phy[21:0] + i];
13205
    data_phy[23:16] = 0;
13206
    data_phy[15: 8] = 0;
13207
    data_phy[ 7: 0] = 0;
13208
    if (data_phy[31:24] !== data_wb[31:24])
13209
    begin
13210
      `TIME;
13211 209 tadejm
      $display("*E Wrong %d. word (1 byte) of TX packet! phy: %0h, wb: %0h", ((i/4)+1), data_phy[31:24], data_wb[31:24]);
13212
      $display("     address phy: %0h, address wb: %0h", addr_phy, addr_wb);
13213 169 mohor
      failure = failure + 1;
13214
    end
13215
  end
13216
  else if((len - i) == 4)
13217
  begin
13218
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hF);
13219
    data_phy[31:24] = eth_phy.tx_mem[addr_phy[21:0] + i];
13220
    data_phy[23:16] = eth_phy.tx_mem[addr_phy[21:0] + i + 1];
13221
    data_phy[15: 8] = eth_phy.tx_mem[addr_phy[21:0] + i + 2];
13222
    data_phy[ 7: 0] = eth_phy.tx_mem[addr_phy[21:0] + i + 3];
13223
    if (data_phy[31:0] !== data_wb[31:0])
13224
    begin
13225
      `TIME;
13226 209 tadejm
      $display("*E Wrong %d. word (4 bytes) of TX packet! phy: %0h, wb: %0h", ((i/4)+1), data_phy[31:0], data_wb[31:0]);
13227
      $display("     address phy: %0h, address wb: %0h", addr_phy, addr_wb);
13228 169 mohor
      failure = failure + 1;
13229
    end
13230
  end
13231
  else
13232
    $display("(%0t)(%m) ERROR", $time);
13233
  delta_t = !delta_t;
13234
end
13235
endtask // check_tx_packet
13236
 
13237
task set_rx_packet;
13238
  input  [31:0] rxpnt;
13239
  input  [15:0] len;
13240
  input         plus_dribble_nibble; // if length is longer for one nibble
13241
  input  [47:0] eth_dest_addr;
13242
  input  [47:0] eth_source_addr;
13243
  input  [15:0] eth_type_len;
13244
  input  [7:0]  eth_start_data;
13245
  integer       i, sd;
13246
  reg    [47:0] dest_addr;
13247
  reg    [47:0] source_addr;
13248
  reg    [15:0] type_len;
13249
  reg    [21:0] buffer;
13250
  reg           delta_t;
13251
begin
13252
  buffer = rxpnt[21:0];
13253
  dest_addr = eth_dest_addr;
13254
  source_addr = eth_source_addr;
13255
  type_len = eth_type_len;
13256
  sd = eth_start_data;
13257
  delta_t = 0;
13258
  for(i = 0; i < len; i = i + 1)
13259
  begin
13260
    if (i < 6)
13261
    begin
13262
      eth_phy.rx_mem[buffer] = dest_addr[47:40];
13263
      dest_addr = dest_addr << 8;
13264
    end
13265
    else if (i < 12)
13266
    begin
13267
      eth_phy.rx_mem[buffer] = source_addr[47:40];
13268
      source_addr = source_addr << 8;
13269
    end
13270
    else if (i < 14)
13271
    begin
13272
      eth_phy.rx_mem[buffer] = type_len[15:8];
13273
      type_len = type_len << 8;
13274
    end
13275
    else
13276
    begin
13277
      eth_phy.rx_mem[buffer] = sd[7:0];
13278
      sd = sd + 1;
13279
    end
13280
    buffer = buffer + 1;
13281
  end
13282
  delta_t = !delta_t;
13283
  if (plus_dribble_nibble)
13284
    eth_phy.rx_mem[buffer] = {4'h0, 4'hD /*sd[3:0]*/};
13285
  delta_t = !delta_t;
13286
end
13287
endtask // set_rx_packet
13288
 
13289
task check_rx_packet;
13290
  input  [31:0] rxpnt_phy; // source
13291
  input  [31:0] rxpnt_wb;  // destination
13292
  input  [15:0] len;
13293
  input         plus_dribble_nibble; // if length is longer for one nibble
13294
  input         successful_dribble_nibble; // if additional nibble is stored into memory
13295
  output [31:0] failure;
13296
  integer       i, data_wb, data_phy;
13297
  reg    [31:0] addr_wb, addr_phy;
13298
  reg    [31:0] failure;
13299
  reg    [21:0] buffer;
13300
  reg           delta_t;
13301
begin
13302
  addr_phy = rxpnt_phy;
13303
  addr_wb = rxpnt_wb;
13304
  delta_t = 0;
13305
  failure = 0;
13306
 
13307
  // First write might not be word allign.
13308
  if(addr_wb[1:0] == 1)
13309
  begin
13310
    wb_slave.rd_mem(addr_wb - 1, data_wb, 4'h7);
13311
    data_phy[31:24] = 0;
13312
    data_phy[23:16] = eth_phy.rx_mem[addr_phy[21:0]];
13313
    data_phy[15: 8] = eth_phy.rx_mem[addr_phy[21:0] + 1];
13314
    data_phy[ 7: 0] = eth_phy.rx_mem[addr_phy[21:0] + 2];
13315
    i = 3;
13316
    if (data_phy[23:0] !== data_wb[23:0])
13317
    begin
13318
      `TIME;
13319
      $display("*E Wrong 1. word (3 bytes) of TX packet!");
13320
      failure = 1;
13321
    end
13322
  end
13323
  else if (addr_wb[1:0] == 2)
13324
  begin
13325
    wb_slave.rd_mem(addr_wb - 2, data_wb, 4'h3);
13326
    data_phy[31:16] = 0;
13327
    data_phy[15: 8] = eth_phy.rx_mem[addr_phy[21:0]];
13328
    data_phy[ 7: 0] = eth_phy.rx_mem[addr_phy[21:0] + 1];
13329
    i = 2;
13330
    if (data_phy[15:0] !== data_wb[15:0])
13331
    begin
13332
      `TIME;
13333
      $display("*E Wrong 1. word (2 bytes) of TX packet!");
13334
      failure = 1;
13335
    end
13336
  end
13337
  else if (addr_wb[1:0] == 3)
13338
  begin
13339
    wb_slave.rd_mem(addr_wb - 3, data_wb, 4'h1);
13340
    data_phy[31: 8] = 0;
13341
    data_phy[ 7: 0] = eth_phy.rx_mem[addr_phy[21:0]];
13342
    i = 1;
13343
    if (data_phy[7:0] !== data_wb[7:0])
13344
    begin
13345
      `TIME;
13346
      $display("*E Wrong 1. word (1 byte) of TX packet!");
13347
      failure = 1;
13348
    end
13349
  end
13350
  else
13351
    i = 0;
13352
  delta_t = !delta_t;
13353
 
13354
  for(i = i; i < (len - 4); i = i + 4) // Last 0-3 bytes are not checked
13355
  begin
13356
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hF);
13357
    data_phy[31:24] = eth_phy.rx_mem[addr_phy[21:0] + i];
13358
    data_phy[23:16] = eth_phy.rx_mem[addr_phy[21:0] + i + 1];
13359
    data_phy[15: 8] = eth_phy.rx_mem[addr_phy[21:0] + i + 2];
13360
    data_phy[ 7: 0] = eth_phy.rx_mem[addr_phy[21:0] + i + 3];
13361
    if (data_phy[31:0] !== data_wb[31:0])
13362
    begin
13363
      `TIME;
13364
      $display("*E Wrong %d. word (4 bytes) of TX packet!", ((i/4)+1));
13365
      failure = failure + 1;
13366
    end
13367
  end
13368
  delta_t = !delta_t;
13369
 
13370
  // Last word
13371
  if((len - i) == 3)
13372
  begin
13373
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hF);
13374
    data_phy[31:24] = eth_phy.rx_mem[addr_phy[21:0] + i];
13375
    data_phy[23:16] = eth_phy.rx_mem[addr_phy[21:0] + i + 1];
13376
    data_phy[15: 8] = eth_phy.rx_mem[addr_phy[21:0] + i + 2];
13377
    if (plus_dribble_nibble)
13378
      data_phy[ 7: 0] = eth_phy.rx_mem[addr_phy[21:0] + i + 3];
13379
    else
13380
      data_phy[ 7: 0] = 0;
13381
    if (data_phy[31:8] !== data_wb[31:8])
13382
    begin
13383
      `TIME;
13384
      $display("*E Wrong %d. word (3 bytes) of TX packet!", ((i/4)+1));
13385
      failure = failure + 1;
13386
    end
13387
    if (plus_dribble_nibble && successful_dribble_nibble)
13388
    begin
13389
      if (data_phy[3:0] !== data_wb[3:0])
13390 116 mohor
      begin
13391 169 mohor
        `TIME;
13392
        $display("*E Wrong dribble nibble in %d. word (3 bytes) of TX packet!", ((i/4)+1));
13393
        failure = failure + 1;
13394 116 mohor
      end
13395 169 mohor
    end
13396
    else if (plus_dribble_nibble && !successful_dribble_nibble)
13397
    begin
13398
      if (data_phy[3:0] === data_wb[3:0])
13399 116 mohor
      begin
13400 169 mohor
        `TIME;
13401
        $display("*E Wrong dribble nibble in %d. word (3 bytes) of TX packet!", ((i/4)+1));
13402
        failure = failure + 1;
13403 116 mohor
      end
13404 169 mohor
    end
13405
  end
13406
  else if((len - i) == 2)
13407
  begin
13408
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hE);
13409
    data_phy[31:24] = eth_phy.rx_mem[addr_phy[21:0] + i];
13410
    data_phy[23:16] = eth_phy.rx_mem[addr_phy[21:0] + i + 1];
13411
    if (plus_dribble_nibble)
13412
      data_phy[15: 8] = eth_phy.rx_mem[addr_phy[21:0] + i + 2];
13413
    else
13414
      data_phy[15: 8] = 0;
13415
    data_phy[ 7: 0] = 0;
13416
    if (data_phy[31:16] !== data_wb[31:16])
13417
    begin
13418
      `TIME;
13419
      $display("*E Wrong %d. word (2 bytes) of TX packet!", ((i/4)+1));
13420
      failure = failure + 1;
13421
    end
13422
    if (plus_dribble_nibble && successful_dribble_nibble)
13423
    begin
13424
      if (data_phy[11:8] !== data_wb[11:8])
13425
      begin
13426
        `TIME;
13427
        $display("*E Wrong dribble nibble in %d. word (2 bytes) of TX packet!", ((i/4)+1));
13428
        failure = failure + 1;
13429
      end
13430
    end
13431
    else if (plus_dribble_nibble && !successful_dribble_nibble)
13432
    begin
13433
      if (data_phy[11:8] === data_wb[11:8])
13434
      begin
13435
        `TIME;
13436
        $display("*E Wrong dribble nibble in %d. word (2 bytes) of TX packet!", ((i/4)+1));
13437
        failure = failure + 1;
13438
      end
13439
    end
13440
  end
13441
  else if((len - i) == 1)
13442
  begin
13443
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hC);
13444
    data_phy[31:24] = eth_phy.rx_mem[addr_phy[21:0] + i];
13445
    if (plus_dribble_nibble)
13446
      data_phy[23:16] = eth_phy.rx_mem[addr_phy[21:0] + i + 1];
13447
    else
13448
      data_phy[23:16] = 0;
13449
    data_phy[15: 8] = 0;
13450
    data_phy[ 7: 0] = 0;
13451
    if (data_phy[31:24] !== data_wb[31:24])
13452
    begin
13453
      `TIME;
13454
      $display("*E Wrong %d. word (1 byte) of TX packet!", ((i/4)+1));
13455
      failure = failure + 1;
13456
    end
13457
    if (plus_dribble_nibble && successful_dribble_nibble)
13458
    begin
13459
      if (data_phy[19:16] !== data_wb[19:16])
13460
      begin
13461
        `TIME;
13462
        $display("*E Wrong dribble nibble in %d. word (1 byte) of TX packet!", ((i/4)+1));
13463
        failure = failure + 1;
13464
      end
13465
    end
13466
    else if (plus_dribble_nibble && !successful_dribble_nibble)
13467
    begin
13468
      if (data_phy[19:16] === data_wb[19:16])
13469
      begin
13470
        `TIME;
13471
        $display("*E Wrong dribble nibble in %d. word (1 byte) of TX packet!", ((i/4)+1));
13472
        failure = failure + 1;
13473
      end
13474
    end
13475
  end
13476
  else if((len - i) == 4)
13477
  begin
13478
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hF);
13479
    data_phy[31:24] = eth_phy.rx_mem[addr_phy[21:0] + i];
13480
    data_phy[23:16] = eth_phy.rx_mem[addr_phy[21:0] + i + 1];
13481
    data_phy[15: 8] = eth_phy.rx_mem[addr_phy[21:0] + i + 2];
13482
    data_phy[ 7: 0] = eth_phy.rx_mem[addr_phy[21:0] + i + 3];
13483
    if (data_phy[31:0] !== data_wb[31:0])
13484
    begin
13485
      `TIME;
13486
      $display("*E Wrong %d. word (4 bytes) of TX packet!", ((i/4)+1));
13487
      failure = failure + 1;
13488
    end
13489
    if (plus_dribble_nibble)
13490
    begin
13491
      wb_slave.rd_mem(addr_wb + i + 4, data_wb, 4'h8);
13492
      data_phy[31:24] = eth_phy.rx_mem[addr_phy[21:0] + i + 4];
13493
      if (successful_dribble_nibble)
13494
      begin
13495
        if (data_phy[27:24] !== data_wb[27:24])
13496
        begin
13497
          `TIME;
13498
          $display("*E Wrong dribble nibble in %d. word (0 bytes) of TX packet!", ((i/4)+2));
13499
          failure = failure + 1;
13500
        end
13501
      end
13502
      else
13503
      begin
13504
        if (data_phy[27:24] === data_wb[27:24])
13505
        begin
13506
          `TIME;
13507
          $display("*E Wrong dribble nibble in %d. word (0 bytes) of TX packet!", ((i/4)+2));
13508
          failure = failure + 1;
13509
        end
13510
      end
13511
    end
13512
  end
13513
  else
13514
    $display("(%0t)(%m) ERROR", $time);
13515
  delta_t = !delta_t;
13516
end
13517
endtask // check_rx_packet
13518 116 mohor
 
13519 169 mohor
//////////////////////////////////////////////////////////////
13520
// Ethernet CRC Basic tasks
13521
//////////////////////////////////////////////////////////////
13522
 
13523
task append_tx_crc;
13524
  input  [31:0] txpnt_wb;  // source
13525
  input  [15:0] len; // length in bytes without CRC
13526
  input         negated_crc; // if appended CRC is correct or not
13527
  reg    [31:0] crc;
13528
  reg    [31:0] addr_wb;
13529
  reg           delta_t;
13530
begin
13531
  addr_wb = txpnt_wb + len;
13532
  delta_t = 0;
13533
  // calculate CRC from prepared packet
13534
  paralel_crc_mac(txpnt_wb, {16'h0, len}, 1'b0, crc);
13535
  if (negated_crc)
13536
    crc = ~crc;
13537
  delta_t = !delta_t;
13538
 
13539
  // Write might not be word allign.
13540
  if (addr_wb[1:0] == 1)
13541
  begin
13542
    wb_slave.wr_mem(addr_wb - 1, {8'h0, crc[7:0], crc[15:8], crc[23:16]}, 4'h7);
13543
    wb_slave.wr_mem(addr_wb + 3, {crc[31:24], 24'h0}, 4'h8);
13544 116 mohor
  end
13545 169 mohor
  else if (addr_wb[1:0] == 2)
13546
  begin
13547
    wb_slave.wr_mem(addr_wb - 2, {16'h0, crc[7:0], crc[15:8]}, 4'h3);
13548
    wb_slave.wr_mem(addr_wb + 2, {crc[23:16], crc[31:24], 16'h0}, 4'hC);
13549
  end
13550
  else if (addr_wb[1:0] == 3)
13551
  begin
13552
    wb_slave.wr_mem(addr_wb - 3, {24'h0, crc[7:0]}, 4'h1);
13553
    wb_slave.wr_mem(addr_wb + 1, {crc[15:8], crc[23:16], crc[31:24], 8'h0}, 4'hE);
13554
  end
13555
  else
13556
  begin
13557
    wb_slave.wr_mem(addr_wb, {crc[7:0], crc[15:8], crc[23:16], crc[31:24]}, 4'hF);
13558
  end
13559
  delta_t = !delta_t;
13560
end
13561
endtask // append_tx_crc
13562 116 mohor
 
13563 169 mohor
task check_tx_crc; // used to check crc added to TX packets by MAC
13564
  input  [31:0] txpnt_phy; // destination
13565
  input  [15:0] len; // length in bytes without CRC
13566
  input         negated_crc; // if appended CRC is correct or not
13567
  output [31:0] failure;
13568
  reg    [31:0] failure;
13569
  reg    [31:0] crc_calc;
13570
  reg    [31:0] crc;
13571
  reg    [31:0] addr_phy;
13572
  reg           delta_t;
13573
begin
13574
  addr_phy = txpnt_phy;
13575
  failure = 0;
13576
  // calculate CRC from sent packet
13577
//  serial_crc_phy_tx(addr_phy, {16'h0, len}, 1'b0, crc_calc);
13578
//#10;
13579
  paralel_crc_phy_tx(addr_phy, {16'h0, len}, 1'b0, crc_calc);
13580 209 tadejm
  #1;
13581 169 mohor
  addr_phy = addr_phy + len;
13582
  // Read CRC - BIG endian
13583
  crc[31:24] = eth_phy.tx_mem[addr_phy[21:0]];
13584
  crc[23:16] = eth_phy.tx_mem[addr_phy[21:0] + 1];
13585
  crc[15: 8] = eth_phy.tx_mem[addr_phy[21:0] + 2];
13586
  crc[ 7: 0] = eth_phy.tx_mem[addr_phy[21:0] + 3];
13587
 
13588
  delta_t = !delta_t;
13589
  if (negated_crc)
13590
  begin
13591
    if ((~crc_calc) !== crc)
13592
    begin
13593
      `TIME;
13594
      $display("*E Negated CRC was not successfuly transmitted!");
13595
      failure = failure + 1;
13596
    end
13597
  end
13598
  else
13599
  begin
13600
    if (crc_calc !== crc)
13601
    begin
13602
      `TIME;
13603 209 tadejm
      $display("*E Transmitted CRC was not correct; crc_calc: %0h, crc_mem: %0h", crc_calc, crc);
13604 169 mohor
      failure = failure + 1;
13605
    end
13606
  end
13607
  delta_t = !delta_t;
13608
end
13609
endtask // check_tx_crc
13610
 
13611
task append_rx_crc;
13612
  input  [31:0] rxpnt_phy; // source
13613
  input  [15:0] len; // length in bytes without CRC
13614
  input         plus_dribble_nibble; // if length is longer for one nibble
13615
  input         negated_crc; // if appended CRC is correct or not
13616
  reg    [31:0] crc;
13617
  reg    [7:0]  tmp;
13618
  reg    [31:0] addr_phy;
13619
  reg           delta_t;
13620
begin
13621
  addr_phy = rxpnt_phy + len;
13622
  delta_t = 0;
13623
  // calculate CRC from prepared packet
13624
  paralel_crc_phy_rx(rxpnt_phy, {16'h0, len}, plus_dribble_nibble, crc);
13625
  if (negated_crc)
13626
    crc = ~crc;
13627
  delta_t = !delta_t;
13628
 
13629
  if (plus_dribble_nibble)
13630
  begin
13631
    tmp = eth_phy.rx_mem[addr_phy];
13632 209 tadejm
    eth_phy.rx_mem[addr_phy]     = {crc[27:24], tmp[3:0]};
13633
    eth_phy.rx_mem[addr_phy + 1] = {crc[19:16], crc[31:28]};
13634
    eth_phy.rx_mem[addr_phy + 2] = {crc[11:8], crc[23:20]};
13635
    eth_phy.rx_mem[addr_phy + 3] = {crc[3:0], crc[15:12]};
13636
    eth_phy.rx_mem[addr_phy + 4] = {4'h0, crc[7:4]};
13637 169 mohor
  end
13638
  else
13639
  begin
13640 209 tadejm
    eth_phy.rx_mem[addr_phy]     = crc[31:24];
13641
    eth_phy.rx_mem[addr_phy + 1] = crc[23:16];
13642
    eth_phy.rx_mem[addr_phy + 2] = crc[15:8];
13643
    eth_phy.rx_mem[addr_phy + 3] = crc[7:0];
13644 169 mohor
  end
13645
end
13646
endtask // append_rx_crc
13647
 
13648
// paralel CRC checking for PHY TX
13649
task paralel_crc_phy_tx;
13650
  input  [31:0] start_addr; // start address
13651
  input  [31:0] len; // length of frame in Bytes without CRC length
13652
  input         plus_dribble_nibble; // if length is longer for one nibble
13653
  output [31:0] crc_out;
13654
  reg    [21:0] addr_cnt; // only 22 address lines
13655
  integer       word_cnt;
13656
  integer       nibble_cnt;
13657
  reg    [31:0] load_reg;
13658
  reg           delta_t;
13659
  reg    [31:0] crc_next;
13660
  reg    [31:0] crc;
13661
  reg           crc_error;
13662
  reg     [3:0] data_in;
13663
  integer       i;
13664
begin
13665
  #1 addr_cnt = start_addr[21:0];
13666
  word_cnt = 24; // 27; // start of the frame - nibble granularity (MSbit first)
13667
  crc = 32'hFFFF_FFFF; // INITIAL value
13668
  delta_t = 0;
13669
  // length must include 4 bytes of ZEROs, to generate CRC
13670
  // get number of nibbles from Byte length (2^1 = 2)
13671
  if (plus_dribble_nibble)
13672
    nibble_cnt = ((len + 4) << 1) + 1'b1; // one nibble longer
13673
  else
13674
    nibble_cnt = ((len + 4) << 1);
13675
  // because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3]
13676
  load_reg[31:24] = eth_phy.tx_mem[addr_cnt];
13677
  addr_cnt = addr_cnt + 1;
13678
  load_reg[23:16] = eth_phy.tx_mem[addr_cnt];
13679
  addr_cnt = addr_cnt + 1;
13680
  load_reg[15: 8] = eth_phy.tx_mem[addr_cnt];
13681
  addr_cnt = addr_cnt + 1;
13682
  load_reg[ 7: 0] = eth_phy.tx_mem[addr_cnt];
13683
  addr_cnt = addr_cnt + 1;
13684
  while (nibble_cnt > 0)
13685
  begin
13686
    // wait for delta time
13687
    delta_t = !delta_t;
13688
    // shift data in
13689
 
13690
    if(nibble_cnt <= 8) // for additional 8 nibbles shift ZEROs in!
13691
      data_in[3:0] = 4'h0;
13692
    else
13693
 
13694
      data_in[3:0] = {load_reg[word_cnt], load_reg[word_cnt+1], load_reg[word_cnt+2], load_reg[word_cnt+3]};
13695
    crc_next[0]  = (data_in[0] ^ crc[28]);
13696
    crc_next[1]  = (data_in[1] ^ data_in[0] ^ crc[28]    ^ crc[29]);
13697
    crc_next[2]  = (data_in[2] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[30]);
13698
    crc_next[3]  = (data_in[3] ^ data_in[2] ^ data_in[1] ^ crc[29]  ^ crc[30] ^ crc[31]);
13699
    crc_next[4]  = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[0];
13700
    crc_next[5]  = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[1];
13701
    crc_next[6]  = (data_in[2] ^ data_in[1] ^ crc[29]    ^ crc[30]) ^ crc[ 2];
13702
    crc_next[7]  = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[3];
13703
    crc_next[8]  = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[4];
13704
    crc_next[9]  = (data_in[2] ^ data_in[1] ^ crc[29]    ^ crc[30]) ^ crc[5];
13705
    crc_next[10] = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[6];
13706
    crc_next[11] = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[7];
13707
    crc_next[12] = (data_in[2] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[30]) ^ crc[8];
13708
    crc_next[13] = (data_in[3] ^ data_in[2] ^ data_in[1] ^ crc[29]  ^ crc[30] ^ crc[31]) ^ crc[9];
13709
    crc_next[14] = (data_in[3] ^ data_in[2] ^ crc[30]    ^ crc[31]) ^ crc[10];
13710
    crc_next[15] = (data_in[3] ^ crc[31])   ^ crc[11];
13711
    crc_next[16] = (data_in[0] ^ crc[28])   ^ crc[12];
13712
    crc_next[17] = (data_in[1] ^ crc[29])   ^ crc[13];
13713
    crc_next[18] = (data_in[2] ^ crc[30])   ^ crc[14];
13714
    crc_next[19] = (data_in[3] ^ crc[31])   ^ crc[15];
13715
    crc_next[20] =  crc[16];
13716
    crc_next[21] =  crc[17];
13717
    crc_next[22] = (data_in[0] ^ crc[28])   ^ crc[18];
13718
    crc_next[23] = (data_in[1] ^ data_in[0] ^ crc[29]    ^ crc[28]) ^ crc[19];
13719
    crc_next[24] = (data_in[2] ^ data_in[1] ^ crc[30]    ^ crc[29]) ^ crc[20];
13720
    crc_next[25] = (data_in[3] ^ data_in[2] ^ crc[31]    ^ crc[30]) ^ crc[21];
13721
    crc_next[26] = (data_in[3] ^ data_in[0] ^ crc[31]    ^ crc[28]) ^ crc[22];
13722
    crc_next[27] = (data_in[1] ^ crc[29])   ^ crc[23];
13723
    crc_next[28] = (data_in[2] ^ crc[30])   ^ crc[24];
13724
    crc_next[29] = (data_in[3] ^ crc[31])   ^ crc[25];
13725
    crc_next[30] =  crc[26];
13726
    crc_next[31] =  crc[27];
13727
 
13728
    crc = crc_next;
13729
    crc_error = crc[31:0] != 32'hc704dd7b;  // CRC not equal to magic number
13730
    case (nibble_cnt)
13731
    9: crc_out = {!crc[24], !crc[25], !crc[26], !crc[27], !crc[28], !crc[29], !crc[30], !crc[31],
13732
                  !crc[16], !crc[17], !crc[18], !crc[19], !crc[20], !crc[21], !crc[22], !crc[23],
13733
                  !crc[ 8], !crc[ 9], !crc[10], !crc[11], !crc[12], !crc[13], !crc[14], !crc[15],
13734
                  !crc[ 0], !crc[ 1], !crc[ 2], !crc[ 3], !crc[ 4], !crc[ 5], !crc[ 6], !crc[ 7]};
13735
    default: crc_out = crc_out;
13736
    endcase
13737
    // wait for delta time
13738
    delta_t = !delta_t;
13739
    // increment address and load new data
13740
    if ((word_cnt+3) == 7)//4)
13741
    begin
13742
      // because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3]
13743
      load_reg[31:24] = eth_phy.tx_mem[addr_cnt];
13744
      addr_cnt = addr_cnt + 1;
13745
      load_reg[23:16] = eth_phy.tx_mem[addr_cnt];
13746
      addr_cnt = addr_cnt + 1;
13747
      load_reg[15: 8] = eth_phy.tx_mem[addr_cnt];
13748
      addr_cnt = addr_cnt + 1;
13749
      load_reg[ 7: 0] = eth_phy.tx_mem[addr_cnt];
13750
      addr_cnt = addr_cnt + 1;
13751
    end
13752
    // set new load bit position
13753
    if((word_cnt+3) == 31)
13754
      word_cnt = 16;
13755
    else if ((word_cnt+3) == 23)
13756
      word_cnt = 8;
13757
    else if ((word_cnt+3) == 15)
13758
      word_cnt = 0;
13759
    else if ((word_cnt+3) == 7)
13760
      word_cnt = 24;
13761
    else
13762
      word_cnt = word_cnt + 4;// - 4;
13763
    // decrement nibble counter
13764
    nibble_cnt = nibble_cnt - 1;
13765
    // wait for delta time
13766
    delta_t = !delta_t;
13767
  end // while
13768
  #1;
13769
end
13770
endtask // paralel_crc_phy_tx
13771
 
13772
// paralel CRC calculating for PHY RX
13773
task paralel_crc_phy_rx;
13774
  input  [31:0] start_addr; // start address
13775
  input  [31:0] len; // length of frame in Bytes without CRC length
13776
  input         plus_dribble_nibble; // if length is longer for one nibble
13777 209 tadejm
  output [31:0] crc_out;
13778 169 mohor
  reg    [21:0] addr_cnt; // only 22 address lines
13779
  integer       word_cnt;
13780 209 tadejm
  integer       nibble_cnt;
13781 169 mohor
  reg    [31:0] load_reg;
13782
  reg           delta_t;
13783 209 tadejm
  reg    [31:0] crc_next;
13784
  reg    [31:0] crc;
13785
  reg           crc_error;
13786
  reg     [3:0] data_in;
13787
  integer       i;
13788 169 mohor
begin
13789
  #1 addr_cnt = start_addr[21:0];
13790 209 tadejm
  word_cnt = 24; // 27; // start of the frame - nibble granularity (MSbit first)
13791
  crc = 32'hFFFF_FFFF; // INITIAL value
13792 169 mohor
  delta_t = 0;
13793
  // length must include 4 bytes of ZEROs, to generate CRC
13794 209 tadejm
  // get number of nibbles from Byte length (2^1 = 2)
13795 169 mohor
  if (plus_dribble_nibble)
13796 209 tadejm
    nibble_cnt = ((len + 4) << 1) + 1'b1; // one nibble longer
13797 169 mohor
  else
13798 209 tadejm
    nibble_cnt = ((len + 4) << 1);
13799
  // because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3]
13800 169 mohor
  load_reg[31:24] = eth_phy.rx_mem[addr_cnt];
13801
  addr_cnt = addr_cnt + 1;
13802
  load_reg[23:16] = eth_phy.rx_mem[addr_cnt];
13803
  addr_cnt = addr_cnt + 1;
13804 209 tadejm
  load_reg[15: 8] = eth_phy.rx_mem[addr_cnt];
13805 169 mohor
  addr_cnt = addr_cnt + 1;
13806 209 tadejm
  load_reg[ 7: 0] = eth_phy.rx_mem[addr_cnt];
13807
  addr_cnt = addr_cnt + 1;
13808
  while (nibble_cnt > 0)
13809 169 mohor
  begin
13810
    // wait for delta time
13811
    delta_t = !delta_t;
13812
    // shift data in
13813 209 tadejm
 
13814
    if(nibble_cnt <= 8) // for additional 8 nibbles shift ZEROs in!
13815
      data_in[3:0] = 4'h0;
13816 169 mohor
    else
13817 209 tadejm
 
13818
      data_in[3:0] = {load_reg[word_cnt], load_reg[word_cnt+1], load_reg[word_cnt+2], load_reg[word_cnt+3]};
13819
    crc_next[0]  = (data_in[0] ^ crc[28]);
13820
    crc_next[1]  = (data_in[1] ^ data_in[0] ^ crc[28]    ^ crc[29]);
13821
    crc_next[2]  = (data_in[2] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[30]);
13822
    crc_next[3]  = (data_in[3] ^ data_in[2] ^ data_in[1] ^ crc[29]  ^ crc[30] ^ crc[31]);
13823
    crc_next[4]  = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[0];
13824
    crc_next[5]  = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[1];
13825
    crc_next[6]  = (data_in[2] ^ data_in[1] ^ crc[29]    ^ crc[30]) ^ crc[ 2];
13826
    crc_next[7]  = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[3];
13827
    crc_next[8]  = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[4];
13828
    crc_next[9]  = (data_in[2] ^ data_in[1] ^ crc[29]    ^ crc[30]) ^ crc[5];
13829
    crc_next[10] = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[6];
13830
    crc_next[11] = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[7];
13831
    crc_next[12] = (data_in[2] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[30]) ^ crc[8];
13832
    crc_next[13] = (data_in[3] ^ data_in[2] ^ data_in[1] ^ crc[29]  ^ crc[30] ^ crc[31]) ^ crc[9];
13833
    crc_next[14] = (data_in[3] ^ data_in[2] ^ crc[30]    ^ crc[31]) ^ crc[10];
13834
    crc_next[15] = (data_in[3] ^ crc[31])   ^ crc[11];
13835
    crc_next[16] = (data_in[0] ^ crc[28])   ^ crc[12];
13836
    crc_next[17] = (data_in[1] ^ crc[29])   ^ crc[13];
13837
    crc_next[18] = (data_in[2] ^ crc[30])   ^ crc[14];
13838
    crc_next[19] = (data_in[3] ^ crc[31])   ^ crc[15];
13839
    crc_next[20] =  crc[16];
13840
    crc_next[21] =  crc[17];
13841
    crc_next[22] = (data_in[0] ^ crc[28])   ^ crc[18];
13842
    crc_next[23] = (data_in[1] ^ data_in[0] ^ crc[29]    ^ crc[28]) ^ crc[19];
13843
    crc_next[24] = (data_in[2] ^ data_in[1] ^ crc[30]    ^ crc[29]) ^ crc[20];
13844
    crc_next[25] = (data_in[3] ^ data_in[2] ^ crc[31]    ^ crc[30]) ^ crc[21];
13845
    crc_next[26] = (data_in[3] ^ data_in[0] ^ crc[31]    ^ crc[28]) ^ crc[22];
13846
    crc_next[27] = (data_in[1] ^ crc[29])   ^ crc[23];
13847
    crc_next[28] = (data_in[2] ^ crc[30])   ^ crc[24];
13848
    crc_next[29] = (data_in[3] ^ crc[31])   ^ crc[25];
13849
    crc_next[30] =  crc[26];
13850
    crc_next[31] =  crc[27];
13851
 
13852
    crc = crc_next;
13853
    crc_error = crc[31:0] != 32'hc704dd7b;  // CRC not equal to magic number
13854
    case (nibble_cnt)
13855
    9: crc_out = {!crc[24], !crc[25], !crc[26], !crc[27], !crc[28], !crc[29], !crc[30], !crc[31],
13856
                  !crc[16], !crc[17], !crc[18], !crc[19], !crc[20], !crc[21], !crc[22], !crc[23],
13857
                  !crc[ 8], !crc[ 9], !crc[10], !crc[11], !crc[12], !crc[13], !crc[14], !crc[15],
13858
                  !crc[ 0], !crc[ 1], !crc[ 2], !crc[ 3], !crc[ 4], !crc[ 5], !crc[ 6], !crc[ 7]};
13859
    default: crc_out = crc_out;
13860
    endcase
13861 169 mohor
    // wait for delta time
13862
    delta_t = !delta_t;
13863
    // increment address and load new data
13864 209 tadejm
    if ((word_cnt+3) == 7)//4)
13865 169 mohor
    begin
13866 209 tadejm
      // because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3]
13867 169 mohor
      load_reg[31:24] = eth_phy.rx_mem[addr_cnt];
13868
      addr_cnt = addr_cnt + 1;
13869
      load_reg[23:16] = eth_phy.rx_mem[addr_cnt];
13870
      addr_cnt = addr_cnt + 1;
13871 209 tadejm
      load_reg[15: 8] = eth_phy.rx_mem[addr_cnt];
13872 169 mohor
      addr_cnt = addr_cnt + 1;
13873 209 tadejm
      load_reg[ 7: 0] = eth_phy.rx_mem[addr_cnt];
13874
      addr_cnt = addr_cnt + 1;
13875 169 mohor
    end
13876
    // set new load bit position
13877 209 tadejm
    if((word_cnt+3) == 31)
13878 169 mohor
      word_cnt = 16;
13879 209 tadejm
    else if ((word_cnt+3) == 23)
13880 169 mohor
      word_cnt = 8;
13881 209 tadejm
    else if ((word_cnt+3) == 15)
13882 169 mohor
      word_cnt = 0;
13883 209 tadejm
    else if ((word_cnt+3) == 7)
13884 169 mohor
      word_cnt = 24;
13885
    else
13886 209 tadejm
      word_cnt = word_cnt + 4;// - 4;
13887
    // decrement nibble counter
13888
    nibble_cnt = nibble_cnt - 1;
13889 169 mohor
    // wait for delta time
13890
    delta_t = !delta_t;
13891
  end // while
13892
  #1;
13893
end
13894
endtask // paralel_crc_phy_rx
13895
 
13896
// paralel CRC checking for MAC
13897
task paralel_crc_mac;
13898
  input  [31:0] start_addr; // start address
13899
  input  [31:0] len; // length of frame in Bytes without CRC length
13900
  input         plus_dribble_nibble; // if length is longer for one nibble
13901 209 tadejm
  output [31:0] crc_out;
13902
 
13903
  reg    [21:0] addr_cnt; // only 22 address lines
13904 169 mohor
  integer       word_cnt;
13905 209 tadejm
  integer       nibble_cnt;
13906 169 mohor
  reg    [31:0] load_reg;
13907
  reg           delta_t;
13908 209 tadejm
  reg    [31:0] crc_next;
13909
  reg    [31:0] crc;
13910
  reg           crc_error;
13911
  reg     [3:0] data_in;
13912
  integer       i;
13913 169 mohor
begin
13914
  #1 addr_cnt = start_addr[19:0];
13915
  // set starting point depending with which byte frame starts (e.g. if addr_cnt[1:0] == 0, then
13916
  //   MSB of the packet must be written to the LSB of Big ENDIAN Word [31:24])
13917
  if (addr_cnt[1:0] == 2'h1)
13918
    word_cnt = 16; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
13919
  else if (addr_cnt[1:0] == 2'h2)
13920
    word_cnt = 8; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
13921
  else if (addr_cnt[1:0] == 2'h3)
13922
    word_cnt = 0; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
13923
  else
13924
    word_cnt = 24; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
13925 209 tadejm
  crc = 32'hFFFF_FFFF; // INITIAL value
13926 169 mohor
  delta_t = 0;
13927
  // length must include 4 bytes of ZEROs, to generate CRC
13928 209 tadejm
  // get number of nibbles from Byte length (2^1 = 2)
13929 169 mohor
  if (plus_dribble_nibble)
13930 209 tadejm
    nibble_cnt = ((len + 4) << 1) + 1'b1; // one nibble longer
13931 169 mohor
  else
13932 209 tadejm
    nibble_cnt = ((len + 4) << 1);
13933 169 mohor
  load_reg = wb_slave.wb_memory[{12'h0, addr_cnt}];
13934 209 tadejm
  addr_cnt = addr_cnt + 4;
13935
  while (nibble_cnt > 0)
13936 169 mohor
  begin
13937
    // wait for delta time
13938
    delta_t = !delta_t;
13939
    // shift data in
13940 209 tadejm
 
13941
    if(nibble_cnt <= 8) // for additional 8 nibbles shift ZEROs in!
13942
      data_in[3:0] = 4'h0;
13943 169 mohor
    else
13944 209 tadejm
 
13945
      data_in[3:0] = {load_reg[word_cnt], load_reg[word_cnt+1], load_reg[word_cnt+2], load_reg[word_cnt+3]};
13946
    crc_next[0]  = (data_in[0] ^ crc[28]);
13947
    crc_next[1]  = (data_in[1] ^ data_in[0] ^ crc[28]    ^ crc[29]);
13948
    crc_next[2]  = (data_in[2] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[30]);
13949
    crc_next[3]  = (data_in[3] ^ data_in[2] ^ data_in[1] ^ crc[29]  ^ crc[30] ^ crc[31]);
13950
    crc_next[4]  = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[0];
13951
    crc_next[5]  = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[1];
13952
    crc_next[6]  = (data_in[2] ^ data_in[1] ^ crc[29]    ^ crc[30]) ^ crc[ 2];
13953
    crc_next[7]  = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[3];
13954
    crc_next[8]  = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[4];
13955
    crc_next[9]  = (data_in[2] ^ data_in[1] ^ crc[29]    ^ crc[30]) ^ crc[5];
13956
    crc_next[10] = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[6];
13957
    crc_next[11] = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[7];
13958
    crc_next[12] = (data_in[2] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[30]) ^ crc[8];
13959
    crc_next[13] = (data_in[3] ^ data_in[2] ^ data_in[1] ^ crc[29]  ^ crc[30] ^ crc[31]) ^ crc[9];
13960
    crc_next[14] = (data_in[3] ^ data_in[2] ^ crc[30]    ^ crc[31]) ^ crc[10];
13961
    crc_next[15] = (data_in[3] ^ crc[31])   ^ crc[11];
13962
    crc_next[16] = (data_in[0] ^ crc[28])   ^ crc[12];
13963
    crc_next[17] = (data_in[1] ^ crc[29])   ^ crc[13];
13964
    crc_next[18] = (data_in[2] ^ crc[30])   ^ crc[14];
13965
    crc_next[19] = (data_in[3] ^ crc[31])   ^ crc[15];
13966
    crc_next[20] =  crc[16];
13967
    crc_next[21] =  crc[17];
13968
    crc_next[22] = (data_in[0] ^ crc[28])   ^ crc[18];
13969
    crc_next[23] = (data_in[1] ^ data_in[0] ^ crc[29]    ^ crc[28]) ^ crc[19];
13970
    crc_next[24] = (data_in[2] ^ data_in[1] ^ crc[30]    ^ crc[29]) ^ crc[20];
13971
    crc_next[25] = (data_in[3] ^ data_in[2] ^ crc[31]    ^ crc[30]) ^ crc[21];
13972
    crc_next[26] = (data_in[3] ^ data_in[0] ^ crc[31]    ^ crc[28]) ^ crc[22];
13973
    crc_next[27] = (data_in[1] ^ crc[29])   ^ crc[23];
13974
    crc_next[28] = (data_in[2] ^ crc[30])   ^ crc[24];
13975
    crc_next[29] = (data_in[3] ^ crc[31])   ^ crc[25];
13976
    crc_next[30] =  crc[26];
13977
    crc_next[31] =  crc[27];
13978
 
13979
    crc = crc_next;
13980
    crc_error = crc[31:0] != 32'hc704dd7b;  // CRC not equal to magic number
13981
    case (nibble_cnt)
13982
    9: crc_out = {!crc[24], !crc[25], !crc[26], !crc[27], !crc[28], !crc[29], !crc[30], !crc[31],
13983
                  !crc[16], !crc[17], !crc[18], !crc[19], !crc[20], !crc[21], !crc[22], !crc[23],
13984
                  !crc[ 8], !crc[ 9], !crc[10], !crc[11], !crc[12], !crc[13], !crc[14], !crc[15],
13985
                  !crc[ 0], !crc[ 1], !crc[ 2], !crc[ 3], !crc[ 4], !crc[ 5], !crc[ 6], !crc[ 7]};
13986
    default: crc_out = crc_out;
13987
    endcase
13988 169 mohor
    // wait for delta time
13989
    delta_t = !delta_t;
13990 209 tadejm
    // increment address and load new data
13991
    if ((word_cnt+3) == 7)//4)
13992 169 mohor
    begin
13993 209 tadejm
      // because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3]
13994
      load_reg = wb_slave.wb_memory[{12'h0, addr_cnt}];
13995 169 mohor
      addr_cnt = addr_cnt + 4;
13996
    end
13997 209 tadejm
    // set new load bit position
13998
    if((word_cnt+3) == 31)
13999 169 mohor
      word_cnt = 16;
14000 209 tadejm
    else if ((word_cnt+3) == 23)
14001 169 mohor
      word_cnt = 8;
14002 209 tadejm
    else if ((word_cnt+3) == 15)
14003 169 mohor
      word_cnt = 0;
14004 209 tadejm
    else if ((word_cnt+3) == 7)
14005 169 mohor
      word_cnt = 24;
14006
    else
14007 209 tadejm
      word_cnt = word_cnt + 4;// - 4;
14008
    // decrement nibble counter
14009
    nibble_cnt = nibble_cnt - 1;
14010 169 mohor
    // wait for delta time
14011
    delta_t = !delta_t;
14012
  end // while
14013
  #1;
14014
end
14015
endtask // paralel_crc_mac
14016
 
14017
// serial CRC checking for PHY TX
14018
task serial_crc_phy_tx;
14019
  input  [31:0] start_addr; // start address
14020
  input  [31:0] len; // length of frame in Bytes without CRC length
14021
  input         plus_dribble_nibble; // if length is longer for one nibble
14022
  output [31:0] crc;
14023
  reg    [21:0] addr_cnt; // only 22 address lines
14024
  integer       word_cnt;
14025
  integer       bit_cnt;
14026
  reg    [31:0] load_reg;
14027
  reg    [31:0] crc_shift_reg;
14028
  reg    [31:0] crc_store_reg;
14029
  reg           delta_t;
14030
begin
14031
  #1 addr_cnt = start_addr[21:0];
14032
  word_cnt = 24; // 27; // start of the frame - nibble granularity (MSbit first)
14033
  crc_store_reg = 32'hFFFF_FFFF; // INITIAL value
14034
  delta_t = 0;
14035
  // length must include 4 bytes of ZEROs, to generate CRC
14036
  // get number of bits from Byte length (2^3 = 8)
14037
  if (plus_dribble_nibble)
14038
    bit_cnt = ((len + 4) << 3) + 3'h4; // one nibble longer
14039
  else
14040
    bit_cnt = ((len + 4) << 3);
14041
  // because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3]
14042
  load_reg[31:24] = eth_phy.tx_mem[addr_cnt];
14043
  addr_cnt = addr_cnt + 1;
14044
  load_reg[23:16] = eth_phy.tx_mem[addr_cnt];
14045
  addr_cnt = addr_cnt + 1;
14046
  load_reg[15: 8] = eth_phy.tx_mem[addr_cnt];
14047
  addr_cnt = addr_cnt + 1;
14048
  load_reg[ 7: 0] = eth_phy.tx_mem[addr_cnt];
14049
  addr_cnt = addr_cnt + 1;
14050
#1;
14051
  while (bit_cnt > 0)
14052
  begin
14053
    // wait for delta time
14054
    delta_t = !delta_t;
14055
#1;
14056
    // shift data in
14057
 
14058
    if(bit_cnt <= 32) // for additional 32 bits shift ZEROs in!
14059
     crc_shift_reg[0] = 1'b0               ^ crc_store_reg[31];
14060
    else
14061
 
14062
     crc_shift_reg[0] = load_reg[word_cnt] ^ crc_store_reg[31];
14063
    crc_shift_reg[1]  = crc_store_reg[0]   ^ crc_store_reg[31];
14064
    crc_shift_reg[2]  = crc_store_reg[1]   ^ crc_store_reg[31];
14065
    crc_shift_reg[3]  = crc_store_reg[2];
14066
    crc_shift_reg[4]  = crc_store_reg[3]   ^ crc_store_reg[31];
14067
    crc_shift_reg[5]  = crc_store_reg[4]   ^ crc_store_reg[31];
14068
    crc_shift_reg[6]  = crc_store_reg[5];
14069
    crc_shift_reg[7]  = crc_store_reg[6]   ^ crc_store_reg[31];
14070
    crc_shift_reg[8]  = crc_store_reg[7]   ^ crc_store_reg[31];
14071
    crc_shift_reg[9]  = crc_store_reg[8];
14072
    crc_shift_reg[10] = crc_store_reg[9]   ^ crc_store_reg[31];
14073
    crc_shift_reg[11] = crc_store_reg[10]  ^ crc_store_reg[31];
14074
    crc_shift_reg[12] = crc_store_reg[11]  ^ crc_store_reg[31];
14075
    crc_shift_reg[13] = crc_store_reg[12];
14076
    crc_shift_reg[14] = crc_store_reg[13];
14077
    crc_shift_reg[15] = crc_store_reg[14];
14078
    crc_shift_reg[16] = crc_store_reg[15]  ^ crc_store_reg[31];
14079
    crc_shift_reg[17] = crc_store_reg[16];
14080
    crc_shift_reg[18] = crc_store_reg[17];
14081
    crc_shift_reg[19] = crc_store_reg[18];
14082
    crc_shift_reg[20] = crc_store_reg[19];
14083
    crc_shift_reg[21] = crc_store_reg[20];
14084
    crc_shift_reg[22] = crc_store_reg[21]  ^ crc_store_reg[31];
14085
    crc_shift_reg[23] = crc_store_reg[22]  ^ crc_store_reg[31];
14086
    crc_shift_reg[24] = crc_store_reg[23];
14087
    crc_shift_reg[25] = crc_store_reg[24];
14088
    crc_shift_reg[26] = crc_store_reg[25]  ^ crc_store_reg[31];
14089
    crc_shift_reg[27] = crc_store_reg[26];
14090
    crc_shift_reg[28] = crc_store_reg[27];
14091
    crc_shift_reg[29] = crc_store_reg[28];
14092
    crc_shift_reg[30] = crc_store_reg[29];
14093
    crc_shift_reg[31] = crc_store_reg[30];
14094
    // wait for delta time
14095
    delta_t = !delta_t;
14096
 
14097
    // store previous data
14098
    crc_store_reg = crc_shift_reg;
14099
 
14100
    // put CRC out
14101
    case (bit_cnt)
14102
    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:
14103
    begin
14104
      crc = crc_store_reg;
14105
      crc = {!crc[24], !crc[25], !crc[26], !crc[27], !crc[28], !crc[29], !crc[30], !crc[31],
14106
             !crc[16], !crc[17], !crc[18], !crc[19], !crc[20], !crc[21], !crc[22], !crc[23],
14107
             !crc[ 8], !crc[ 9], !crc[10], !crc[11], !crc[12], !crc[13], !crc[14], !crc[15],
14108
             !crc[ 0], !crc[ 1], !crc[ 2], !crc[ 3], !crc[ 4], !crc[ 5], !crc[ 6], !crc[ 7]};
14109
    end
14110
    default: crc = crc;
14111
    endcase
14112
 
14113
    // increment address and load new data
14114
#1;
14115
    if (word_cnt == 7)//4)
14116
    begin
14117
      // because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3]
14118
      load_reg[31:24] = eth_phy.tx_mem[addr_cnt];
14119
//      load_reg[31:24] = {load_reg[28], load_reg[29], load_reg[30], load_reg[31], 
14120
//                         load_reg[24], load_reg[25], load_reg[26], load_reg[27]};
14121
      addr_cnt = addr_cnt + 1;
14122
      load_reg[23:16] = eth_phy.tx_mem[addr_cnt];
14123
//      load_reg[23:16] = {load_reg[20], load_reg[21], load_reg[22], load_reg[23], 
14124
//                         load_reg[16], load_reg[17], load_reg[18], load_reg[19]};
14125
      addr_cnt = addr_cnt + 1;
14126
      load_reg[15: 8] = eth_phy.tx_mem[addr_cnt];
14127
//      load_reg[15: 8] = {load_reg[12], load_reg[13], load_reg[14], load_reg[15], 
14128
//                         load_reg[ 8], load_reg[ 9], load_reg[10], load_reg[11]};
14129
      addr_cnt = addr_cnt + 1;
14130
      load_reg[ 7: 0] = eth_phy.tx_mem[addr_cnt];
14131
//      load_reg[ 7: 0] = {load_reg[ 4], load_reg[ 5], load_reg[ 6], load_reg[ 7], 
14132
//                         load_reg[ 0], load_reg[ 1], load_reg[ 2], load_reg[ 3]};
14133
      addr_cnt = addr_cnt + 1;
14134
    end
14135
#1;
14136
    // set new load bit position
14137
    if(word_cnt == 31)
14138
      word_cnt = 16;
14139
    else if (word_cnt == 23)
14140
      word_cnt = 8;
14141
    else if (word_cnt == 15)
14142
      word_cnt = 0;
14143
    else if (word_cnt == 7)
14144
      word_cnt = 24;
14145
 
14146
//   if(word_cnt == 24)
14147
//     word_cnt = 31;
14148
//   else if (word_cnt == 28)
14149
//     word_cnt = 19;
14150
//   else if (word_cnt == 16)
14151
//     word_cnt = 23;
14152
//   else if (word_cnt == 20)
14153
//     word_cnt = 11;
14154
//   else if(word_cnt == 8)
14155
//     word_cnt = 15;
14156
//   else if (word_cnt == 12)
14157
//     word_cnt = 3;
14158
//   else if (word_cnt == 0)
14159
//     word_cnt = 7;
14160
//   else if (word_cnt == 4)
14161
//     word_cnt = 27;
14162
    else
14163
      word_cnt = word_cnt + 1;// - 1;
14164
#1;
14165
    // decrement bit counter
14166
    bit_cnt = bit_cnt - 1;
14167
#1;
14168
    // wait for delta time
14169
    delta_t = !delta_t;
14170
  end // while
14171
 
14172
  #1;
14173
end
14174
endtask // serial_crc_phy_tx
14175
 
14176
// serial CRC calculating for PHY RX
14177
task serial_crc_phy_rx;
14178
  input  [31:0] start_addr; // start address
14179
  input  [31:0] len; // length of frame in Bytes without CRC length
14180
  input         plus_dribble_nibble; // if length is longer for one nibble
14181
  output [31:0] crc;
14182
  reg    [21:0] addr_cnt; // only 22 address lines
14183
  integer       word_cnt;
14184
  integer       bit_cnt;
14185
  reg    [31:0] load_reg;
14186
  reg    [31:0] crc_shift_reg;
14187
  reg    [31:0] crc_store_reg;
14188
  reg           delta_t;
14189
begin
14190
  #1 addr_cnt = start_addr[21:0];
14191
  word_cnt = 24; // start of the frame
14192
  crc_shift_reg = 0;
14193
  delta_t = 0;
14194
  // length must include 4 bytes of ZEROs, to generate CRC
14195
  // get number of bits from Byte length (2^3 = 8)
14196
  if (plus_dribble_nibble)
14197
    bit_cnt = ((len + 4) << 3) + 3'h4; // one nibble longer
14198
  else
14199
    bit_cnt = ((len + 4) << 3);
14200
  load_reg[31:24] = eth_phy.rx_mem[addr_cnt];
14201
  addr_cnt = addr_cnt + 1;
14202
  load_reg[23:16] = eth_phy.rx_mem[addr_cnt];
14203
  addr_cnt = addr_cnt + 1;
14204
  load_reg[15:8]  = eth_phy.rx_mem[addr_cnt];
14205
  addr_cnt = addr_cnt + 1;
14206
  load_reg[7:0]   = eth_phy.rx_mem[addr_cnt];
14207
 
14208
  while (bit_cnt > 0)
14209
  begin
14210
    // wait for delta time
14211
    delta_t = !delta_t;
14212
    // store previous data
14213
    crc_store_reg = crc_shift_reg;
14214
    // shift data in
14215
    if(bit_cnt <= 32) // for additional 32 bits shift ZEROs in!
14216
     crc_shift_reg[0] = 1'b0               ^ crc_store_reg[31];
14217
    else
14218
     crc_shift_reg[0] = load_reg[word_cnt] ^ crc_store_reg[31];
14219
    crc_shift_reg[1]  = crc_store_reg[0]   ^ crc_store_reg[31];
14220
    crc_shift_reg[2]  = crc_store_reg[1]   ^ crc_store_reg[31];
14221
    crc_shift_reg[3]  = crc_store_reg[2];
14222
    crc_shift_reg[4]  = crc_store_reg[3]   ^ crc_store_reg[31];
14223
    crc_shift_reg[5]  = crc_store_reg[4]   ^ crc_store_reg[31];
14224
    crc_shift_reg[6]  = crc_store_reg[5];
14225
    crc_shift_reg[7]  = crc_store_reg[6]   ^ crc_store_reg[31];
14226
    crc_shift_reg[8]  = crc_store_reg[7]   ^ crc_store_reg[31];
14227
    crc_shift_reg[9]  = crc_store_reg[8];
14228
    crc_shift_reg[10] = crc_store_reg[9]   ^ crc_store_reg[31];
14229
    crc_shift_reg[11] = crc_store_reg[10]  ^ crc_store_reg[31];
14230
    crc_shift_reg[12] = crc_store_reg[11]  ^ crc_store_reg[31];
14231
    crc_shift_reg[13] = crc_store_reg[12];
14232
    crc_shift_reg[14] = crc_store_reg[13];
14233
    crc_shift_reg[15] = crc_store_reg[14];
14234
    crc_shift_reg[16] = crc_store_reg[15]  ^ crc_store_reg[31];
14235
    crc_shift_reg[17] = crc_store_reg[16];
14236
    crc_shift_reg[18] = crc_store_reg[17];
14237
    crc_shift_reg[19] = crc_store_reg[18];
14238
    crc_shift_reg[20] = crc_store_reg[19];
14239
    crc_shift_reg[21] = crc_store_reg[20];
14240
    crc_shift_reg[22] = crc_store_reg[21]  ^ crc_store_reg[31];
14241
    crc_shift_reg[23] = crc_store_reg[22]  ^ crc_store_reg[31];
14242
    crc_shift_reg[24] = crc_store_reg[23];
14243
    crc_shift_reg[25] = crc_store_reg[24];
14244
    crc_shift_reg[26] = crc_store_reg[25]  ^ crc_store_reg[31];
14245
    crc_shift_reg[27] = crc_store_reg[26];
14246
    crc_shift_reg[28] = crc_store_reg[27];
14247
    crc_shift_reg[29] = crc_store_reg[28];
14248
    crc_shift_reg[30] = crc_store_reg[29];
14249
    crc_shift_reg[31] = crc_store_reg[30];
14250
    // wait for delta time
14251
    delta_t = !delta_t;
14252
    // increment address and load new data
14253
    if (word_cnt == 7)
14254
    begin
14255
      addr_cnt = addr_cnt + 1;
14256
      load_reg[31:24] = eth_phy.rx_mem[addr_cnt];
14257
      addr_cnt = addr_cnt + 1;
14258
      load_reg[23:16] = eth_phy.rx_mem[addr_cnt];
14259
      addr_cnt = addr_cnt + 1;
14260
      load_reg[15:8]  = eth_phy.rx_mem[addr_cnt];
14261
      addr_cnt = addr_cnt + 1;
14262
      load_reg[7:0]   = eth_phy.rx_mem[addr_cnt];
14263
    end
14264
    // set new load bit position
14265
    if(word_cnt == 31)
14266
      word_cnt = 16;
14267
    else if (word_cnt == 23)
14268
      word_cnt = 8;
14269
    else if (word_cnt == 15)
14270
      word_cnt = 0;
14271
    else if (word_cnt == 7)
14272
      word_cnt = 24;
14273
    else
14274
      word_cnt = word_cnt + 1;
14275
    // decrement bit counter
14276
    bit_cnt = bit_cnt - 1;
14277
    // wait for delta time
14278
    delta_t = !delta_t;
14279
  end // while
14280
 
14281
  // put CRC out
14282
  crc = crc_shift_reg;
14283
  #1;
14284
end
14285
endtask // serial_crc_phy_rx
14286
 
14287
// serial CRC checking for MAC
14288
task serial_crc_mac;
14289
  input  [31:0] start_addr; // start address
14290
  input  [31:0] len; // length of frame in Bytes without CRC length
14291
  input         plus_dribble_nibble; // if length is longer for one nibble
14292
  output [31:0] crc;
14293
  reg    [19:0] addr_cnt; // only 20 address lines
14294
  integer       word_cnt;
14295
  integer       bit_cnt;
14296
  reg    [31:0] load_reg;
14297
  reg    [31:0] crc_shift_reg;
14298
  reg    [31:0] crc_store_reg;
14299
  reg           delta_t;
14300
begin
14301
  #1 addr_cnt = start_addr[19:0];
14302
  // set starting point depending with which byte frame starts (e.g. if addr_cnt[1:0] == 0, then
14303
  //   MSB of the packet must be written to the LSB of Big ENDIAN Word [31:24])
14304
  if (addr_cnt[1:0] == 2'h1)
14305
    word_cnt = 16; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
14306
  else if (addr_cnt[1:0] == 2'h2)
14307
    word_cnt = 8; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
14308
  else if (addr_cnt[1:0] == 2'h3)
14309
    word_cnt = 0; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
14310
  else
14311
    word_cnt = 24; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
14312
 
14313
  crc_shift_reg = 0;
14314
  delta_t = 0;
14315
  // length must include 4 bytes of ZEROs, to generate CRC
14316
  // get number of bits from Byte length (2^3 = 8)
14317
  if (plus_dribble_nibble)
14318
    bit_cnt = ((len + 4) << 3) + 3'h4; // one nibble longer
14319
  else
14320
    bit_cnt = ((len + 4) << 3);
14321
  load_reg = wb_slave.wb_memory[{12'h0, addr_cnt}];
14322
 
14323
  while (bit_cnt > 0)
14324
  begin
14325
    // wait for delta time
14326
    delta_t = !delta_t;
14327
    // store previous data
14328
    crc_store_reg = crc_shift_reg;
14329
    // shift data in
14330
    if(bit_cnt <= 32) // for additional 32 bits shift ZEROs in!
14331
     crc_shift_reg[0] = 1'b0               ^ crc_store_reg[31];
14332
    else
14333
     crc_shift_reg[0] = load_reg[word_cnt] ^ crc_store_reg[31];
14334
    crc_shift_reg[1]  = crc_store_reg[0]   ^ crc_store_reg[31];
14335
    crc_shift_reg[2]  = crc_store_reg[1]   ^ crc_store_reg[31];
14336
    crc_shift_reg[3]  = crc_store_reg[2];
14337
    crc_shift_reg[4]  = crc_store_reg[3]   ^ crc_store_reg[31];
14338
    crc_shift_reg[5]  = crc_store_reg[4]   ^ crc_store_reg[31];
14339
    crc_shift_reg[6]  = crc_store_reg[5];
14340
    crc_shift_reg[7]  = crc_store_reg[6]   ^ crc_store_reg[31];
14341
    crc_shift_reg[8]  = crc_store_reg[7]   ^ crc_store_reg[31];
14342
    crc_shift_reg[9]  = crc_store_reg[8];
14343
    crc_shift_reg[10] = crc_store_reg[9]   ^ crc_store_reg[31];
14344
    crc_shift_reg[11] = crc_store_reg[10]  ^ crc_store_reg[31];
14345
    crc_shift_reg[12] = crc_store_reg[11]  ^ crc_store_reg[31];
14346
    crc_shift_reg[13] = crc_store_reg[12];
14347
    crc_shift_reg[14] = crc_store_reg[13];
14348
    crc_shift_reg[15] = crc_store_reg[14];
14349
    crc_shift_reg[16] = crc_store_reg[15]  ^ crc_store_reg[31];
14350
    crc_shift_reg[17] = crc_store_reg[16];
14351
    crc_shift_reg[18] = crc_store_reg[17];
14352
    crc_shift_reg[19] = crc_store_reg[18];
14353
    crc_shift_reg[20] = crc_store_reg[19];
14354
    crc_shift_reg[21] = crc_store_reg[20];
14355
    crc_shift_reg[22] = crc_store_reg[21]  ^ crc_store_reg[31];
14356
    crc_shift_reg[23] = crc_store_reg[22]  ^ crc_store_reg[31];
14357
    crc_shift_reg[24] = crc_store_reg[23];
14358
    crc_shift_reg[25] = crc_store_reg[24];
14359
    crc_shift_reg[26] = crc_store_reg[25]  ^ crc_store_reg[31];
14360
    crc_shift_reg[27] = crc_store_reg[26];
14361
    crc_shift_reg[28] = crc_store_reg[27];
14362
    crc_shift_reg[29] = crc_store_reg[28];
14363
    crc_shift_reg[30] = crc_store_reg[29];
14364
    crc_shift_reg[31] = crc_store_reg[30];
14365
    // wait for delta time
14366
    delta_t = !delta_t;
14367
    // increment address and load new data for Big ENDIAN Bytes (Litle ENDIAN bits)
14368
    if (word_cnt == 7)
14369
    begin
14370
      addr_cnt = addr_cnt + 4;
14371
      load_reg = wb_slave.wb_memory[{12'h0, addr_cnt}];
14372
    end
14373
    // set new load bit position for Big ENDIAN Bytes (Litle ENDIAN bits)
14374
    if(word_cnt == 31)
14375
      word_cnt = 16;
14376
    else if (word_cnt == 23)
14377
      word_cnt = 8;
14378
    else if (word_cnt == 15)
14379
      word_cnt = 0;
14380
    else if (word_cnt == 7)
14381
      word_cnt = 24;
14382
    else
14383
      word_cnt = word_cnt + 1;
14384
    // decrement bit counter
14385
    bit_cnt = bit_cnt - 1;
14386
    // wait for delta time
14387
    delta_t = !delta_t;
14388
  end // while
14389
 
14390
  // put CRC out
14391
  crc = crc_shift_reg;
14392
  #1;
14393
end
14394
endtask // serial_crc_mac
14395
 
14396
//////////////////////////////////////////////////////////////
14397
// MIIM Basic tasks
14398
//////////////////////////////////////////////////////////////
14399
 
14400
task reset_mii; //  MII module
14401
  reg [31:0] tmp;
14402
  reg [31:0] tmp_no_rst;
14403
begin
14404
  // read MII mode register first
14405
  wbm_read(`ETH_MIIMODER, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14406
  // set reset bit - write back to MII mode register with RESET bit
14407
  wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_RST | tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14408
  // clear reset bit - write back to MII mode register without RESET bit
14409
  tmp_no_rst = `ETH_MIIMODER_RST;
14410
  tmp_no_rst = ~tmp_no_rst;
14411
  wbm_write(`ETH_MIIMODER, (tmp_no_rst & tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14412
end
14413
endtask // reset_mii
14414
 
14415
task mii_set_clk_div; // set clock divider for MII clock
14416
  input [7:0]  clk_div;
14417
begin
14418
  // MII mode register
14419
  wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_CLKDIV & clk_div), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14420
end
14421
endtask // mii_set_clk_div
14422
 
14423
 
14424
task check_mii_busy; // MII - check if BUSY
14425
  reg [31:0] tmp;
14426
begin
14427
  @(posedge wb_clk);
14428
  // MII read status register
14429
  wbm_read(`ETH_MIISTATUS, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14430
  while(tmp[`ETH_MIISTATUS_BUSY] !== 1'b0) //`ETH_MIISTATUS_BUSY
14431
  begin
14432
    @(posedge wb_clk);
14433
    wbm_read(`ETH_MIISTATUS, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14434
  end
14435
end
14436
endtask // check_mii_busy
14437
 
14438
 
14439
task check_mii_scan_valid; // MII - check if SCAN data are valid
14440
  reg [31:0] tmp;
14441
begin
14442
  @(posedge wb_clk);
14443
  // MII read status register
14444
  wbm_read(`ETH_MIISTATUS, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14445
  while(tmp[`ETH_MIISTATUS_NVALID] !== 1'b0) //`ETH_MIISTATUS_NVALID
14446
  begin
14447
    @(posedge wb_clk);
14448
    wbm_read(`ETH_MIISTATUS, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14449
  end
14450
end
14451
endtask // check_mii_scan_valid
14452
 
14453
 
14454
task mii_write_req; // requests write to MII
14455
  input [4:0]  phy_addr;
14456
  input [4:0]  reg_addr;
14457
  input [15:0] data_in;
14458
begin
14459
  // MII address, PHY address = 1, command register address = 0
14460
  wbm_write(`ETH_MIIADDRESS, (`ETH_MIIADDRESS_FIAD & phy_addr) | (`ETH_MIIADDRESS_RGAD & (reg_addr << 8)),
14461
            4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14462
  // MII TX data
14463
  wbm_write(`ETH_MIITX_DATA, {16'h0000, data_in}, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14464
  // MII command
14465
  wbm_write(`ETH_MIICOMMAND, `ETH_MIICOMMAND_WCTRLDATA, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14466
  @(posedge wb_clk);
14467
end
14468
endtask // mii_write_req
14469
 
14470
 
14471
task mii_read_req; // requests read from MII
14472
  input [4:0]  phy_addr;
14473
  input [4:0]  reg_addr;
14474
begin
14475
  // MII address, PHY address = 1, command register address = 0
14476
  wbm_write(`ETH_MIIADDRESS, (`ETH_MIIADDRESS_FIAD & phy_addr) | (`ETH_MIIADDRESS_RGAD & (reg_addr << 8)),
14477
            4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14478
  // MII command
14479
  wbm_write(`ETH_MIICOMMAND, `ETH_MIICOMMAND_RSTAT, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14480
  @(posedge wb_clk);
14481
end
14482
endtask // mii_read_req
14483
 
14484
 
14485
task mii_scan_req; // requests scan from MII
14486
  input [4:0]  phy_addr;
14487
  input [4:0]  reg_addr;
14488
begin
14489
  // MII address, PHY address = 1, command register address = 0
14490
  wbm_write(`ETH_MIIADDRESS, (`ETH_MIIADDRESS_FIAD & phy_addr) | (`ETH_MIIADDRESS_RGAD & (reg_addr << 8)),
14491
            4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14492
  // MII command
14493
  wbm_write(`ETH_MIICOMMAND, `ETH_MIICOMMAND_SCANSTAT, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14494
  @(posedge wb_clk);
14495
end
14496
endtask // mii_scan_req
14497
 
14498
 
14499
task mii_scan_finish; // finish scan from MII
14500
begin
14501
  // MII command
14502
  wbm_write(`ETH_MIICOMMAND, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14503
  @(posedge wb_clk);
14504
end
14505
endtask // mii_scan_finish
14506
 
14507
//////////////////////////////////////////////////////////////
14508
// Log files and memory tasks
14509
//////////////////////////////////////////////////////////////
14510
 
14511
task clear_memories;
14512
  reg    [22:0]  adr_i;
14513
  reg            delta_t;
14514
begin
14515
  delta_t = 0;
14516
  for (adr_i = 0; adr_i < 4194304; adr_i = adr_i + 1)
14517
  begin
14518
    eth_phy.rx_mem[adr_i[21:0]] = 0;
14519
    eth_phy.tx_mem[adr_i[21:0]] = 0;
14520
    wb_slave.wb_memory[adr_i[21:2]] = 0;
14521
    delta_t = !delta_t;
14522
  end
14523
end
14524
endtask // clear_memories
14525
 
14526
task test_note;
14527
  input [799:0] test_note ;
14528
  reg   [799:0] display_note ;
14529
begin
14530
  display_note = test_note;
14531
  while ( display_note[799:792] == 0 )
14532
    display_note = display_note << 8 ;
14533
  $fdisplay( tb_log_file, " " ) ;
14534
  $fdisplay( tb_log_file, "NOTE: %s", display_note ) ;
14535
  $fdisplay( tb_log_file, " " ) ;
14536
end
14537
endtask // test_note
14538
 
14539
task test_heading;
14540
  input [799:0] test_heading ;
14541
  reg   [799:0] display_test ;
14542
begin
14543
  display_test = test_heading;
14544
  while ( display_test[799:792] == 0 )
14545
    display_test = display_test << 8 ;
14546
  $fdisplay( tb_log_file, "  ***************************************************************************************" ) ;
14547
  $fdisplay( tb_log_file, "  ***************************************************************************************" ) ;
14548
  $fdisplay( tb_log_file, "  Heading: %s", display_test ) ;
14549
  $fdisplay( tb_log_file, "  ***************************************************************************************" ) ;
14550
  $fdisplay( tb_log_file, "  ***************************************************************************************" ) ;
14551
  $fdisplay( tb_log_file, " " ) ;
14552
end
14553
endtask // test_heading
14554
 
14555
 
14556
task test_fail ;
14557
  input [7999:0] failure_reason ;
14558
//  reg   [8007:0] display_failure ;
14559
  reg   [7999:0] display_failure ;
14560
  reg   [799:0] display_test ;
14561
begin
14562
  tests_failed = tests_failed + 1 ;
14563
 
14564
  display_failure = failure_reason; // {failure_reason, "!"} ;
14565
  while ( display_failure[7999:7992] == 0 )
14566
    display_failure = display_failure << 8 ;
14567
 
14568
  display_test = test_name ;
14569
  while ( display_test[799:792] == 0 )
14570
    display_test = display_test << 8 ;
14571
 
14572
  $fdisplay( tb_log_file, "    *************************************************************************************" ) ;
14573
  $fdisplay( tb_log_file, "    At time: %t ", $time ) ;
14574
  $fdisplay( tb_log_file, "    Test: %s", display_test ) ;
14575
  $fdisplay( tb_log_file, "    *FAILED* because") ;
14576
  $fdisplay( tb_log_file, "    %s", display_failure ) ;
14577
  $fdisplay( tb_log_file, "    *************************************************************************************" ) ;
14578
  $fdisplay( tb_log_file, " " ) ;
14579
 
14580
 `ifdef STOP_ON_FAILURE
14581
    #20 $stop ;
14582
 `endif
14583
end
14584
endtask // test_fail
14585
 
14586
 
14587
task test_ok ;
14588
  reg [799:0] display_test ;
14589
begin
14590
  tests_successfull = tests_successfull + 1 ;
14591
 
14592
  display_test = test_name ;
14593
  while ( display_test[799:792] == 0 )
14594
    display_test = display_test << 8 ;
14595
 
14596
  $fdisplay( tb_log_file, "    *************************************************************************************" ) ;
14597
  $fdisplay( tb_log_file, "    At time: %t ", $time ) ;
14598
  $fdisplay( tb_log_file, "    Test: %s", display_test ) ;
14599
  $fdisplay( tb_log_file, "    reported *SUCCESSFULL*! ") ;
14600
  $fdisplay( tb_log_file, "    *************************************************************************************" ) ;
14601
  $fdisplay( tb_log_file, " " ) ;
14602
end
14603
endtask // test_ok
14604
 
14605
 
14606
task test_summary;
14607
begin
14608
  $fdisplay(tb_log_file, "**************************** Ethernet MAC test summary **********************************") ;
14609
  $fdisplay(tb_log_file, "Tests performed:   %d", tests_successfull + tests_failed) ;
14610
  $fdisplay(tb_log_file, "Failed tests   :   %d", tests_failed) ;
14611
  $fdisplay(tb_log_file, "Successfull tests: %d", tests_successfull) ;
14612
  $fdisplay(tb_log_file, "**************************** Ethernet MAC test summary **********************************") ;
14613
  $fclose(tb_log_file) ;
14614
end
14615
endtask // test_summary
14616
 
14617
 
14618 116 mohor
endmodule

powered by: WebSVN 2.1.0

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