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

Subversion Repositories ethmac

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

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 223 tadejm
// Revision 1.16  2002/10/09 13:16:51  tadejm
46
// Just back-up; not completed testbench and some testcases are not
47
// wotking properly yet.
48
//
49 209 tadejm
// Revision 1.15  2002/09/20 14:29:12  tadej
50
// Full duplex tests modified and testbench bug repaired.
51
//
52 194 tadej
// Revision 1.14  2002/09/18 17:56:38  tadej
53
// Some additional reports added
54
//
55 192 tadej
// Revision 1.13  2002/09/16 17:53:49  tadej
56
// Full duplex test improved.
57
//
58 182 tadej
// Revision 1.12  2002/09/16 15:10:42  mohor
59
// MIIM test look better.
60
//
61 181 mohor
// Revision 1.11  2002/09/13 19:18:04  mohor
62
// Bench outputs data to display every 128 bytes.
63
//
64 180 mohor
// Revision 1.10  2002/09/13 18:44:29  mohor
65
// Beautiful tests merget together
66
//
67 179 mohor
// Revision 1.9  2002/09/13 18:41:45  mohor
68
// Rearanged testcases
69
//
70 178 mohor
// Revision 1.8  2002/09/13 14:50:15  mohor
71
// Bug in MIIM fixed.
72
//
73 177 mohor
// Revision 1.7  2002/09/13 12:29:14  mohor
74
// Headers changed.
75
//
76 170 mohor
// Revision 1.6  2002/09/13 11:57:20  mohor
77
// New testbench. Thanks to Tadej M - "The Spammer".
78
//
79 121 mohor
// Revision 1.2  2002/07/19 14:02:47  mohor
80
// Clock mrx_clk set to 2.5 MHz.
81
//
82 117 mohor
// Revision 1.1  2002/07/19 13:57:53  mohor
83
// Testing environment also includes traffic cop, memory interface and host
84
// interface.
85 116 mohor
//
86
//
87
//
88
//
89 117 mohor
//
90 116 mohor
 
91
 
92 169 mohor
`include "eth_phy_defines.v"
93
`include "wb_model_defines.v"
94 116 mohor
`include "tb_eth_defines.v"
95
`include "eth_defines.v"
96
`include "timescale.v"
97
 
98
module tb_ethernet();
99
 
100
 
101 169 mohor
reg           wb_clk;
102
reg           wb_rst;
103
wire          wb_int;
104 116 mohor
 
105 169 mohor
wire          mtx_clk;  // This goes to PHY
106
wire          mrx_clk;  // This goes to PHY
107 116 mohor
 
108
wire   [3:0]  MTxD;
109
wire          MTxEn;
110
wire          MTxErr;
111
 
112 169 mohor
wire   [3:0]  MRxD;     // This goes to PHY
113
wire          MRxDV;    // This goes to PHY
114
wire          MRxErr;   // This goes to PHY
115
wire          MColl;    // This goes to PHY
116
wire          MCrs;     // This goes to PHY
117 116 mohor
 
118
wire          Mdi_I;
119
wire          Mdo_O;
120
wire          Mdo_OE;
121 169 mohor
tri           Mdio_IO;
122 116 mohor
wire          Mdc_O;
123
 
124
 
125 169 mohor
parameter Tp = 1;
126 116 mohor
 
127 121 mohor
 
128 116 mohor
// Ethernet Slave Interface signals
129 169 mohor
wire [31:0] eth_sl_wb_adr;
130 116 mohor
wire [31:0] eth_sl_wb_adr_i, eth_sl_wb_dat_o, eth_sl_wb_dat_i;
131
wire  [3:0] eth_sl_wb_sel_i;
132
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;
133
 
134
// Ethernet Master Interface signals
135
wire [31:0] eth_ma_wb_adr_o, eth_ma_wb_dat_i, eth_ma_wb_dat_o;
136
wire  [3:0] eth_ma_wb_sel_o;
137
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;
138
 
139
 
140
 
141
 
142
// Connecting Ethernet top module
143 169 mohor
eth_top eth_top
144 116 mohor
(
145
  // WISHBONE common
146 169 mohor
  .wb_clk_i(wb_clk),              .wb_rst_i(wb_rst),
147 116 mohor
 
148
  // WISHBONE slave
149 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),
150
  .wb_cyc_i(eth_sl_wb_cyc_i),       .wb_stb_i(eth_sl_wb_stb_i),   .wb_ack_o(eth_sl_wb_ack_o),
151
  .wb_err_o(eth_sl_wb_err_o),       .wb_dat_i(eth_sl_wb_dat_i),   .wb_dat_o(eth_sl_wb_dat_o),
152 116 mohor
 
153
  // WISHBONE master
154
  .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),
155
  .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),
156
  .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),
157
 
158
  //TX
159
  .mtx_clk_pad_i(mtx_clk), .mtxd_pad_o(MTxD), .mtxen_pad_o(MTxEn), .mtxerr_pad_o(MTxErr),
160
 
161
  //RX
162
  .mrx_clk_pad_i(mrx_clk), .mrxd_pad_i(MRxD), .mrxdv_pad_i(MRxDV), .mrxerr_pad_i(MRxErr),
163
  .mcoll_pad_i(MColl),    .mcrs_pad_i(MCrs),
164
 
165
  // MIIM
166
  .mdc_pad_o(Mdc_O), .md_pad_i(Mdi_I), .md_pad_o(Mdo_O), .md_padoe_o(Mdo_OE),
167
 
168 169 mohor
  .int_o(wb_int)
169 116 mohor
);
170
 
171
 
172
 
173 169 mohor
// Connecting Ethernet PHY Module
174
assign Mdio_IO = Mdo_OE ? Mdo_O : 1'bz ;
175
assign Mdi_I   = Mdio_IO;
176
integer phy_log_file_desc;
177
 
178
eth_phy eth_phy
179 116 mohor
(
180 169 mohor
  // WISHBONE reset
181
  .m_rst_n_i(!wb_rst),
182 116 mohor
 
183 169 mohor
  // MAC TX
184
  .mtx_clk_o(mtx_clk),    .mtxd_i(MTxD),    .mtxen_i(MTxEn),    .mtxerr_i(MTxErr),
185
 
186
  // MAC RX
187
  .mrx_clk_o(mrx_clk),    .mrxd_o(MRxD),    .mrxdv_o(MRxDV),    .mrxerr_o(MRxErr),
188
  .mcoll_o(MColl),        .mcrs_o(MCrs),
189
 
190
  // MIIM
191
  .mdc_i(Mdc_O),          .md_io(Mdio_IO),
192
 
193
  // SYSTEM
194
  .phy_log(phy_log_file_desc)
195 116 mohor
);
196
 
197
 
198 169 mohor
 
199
// Connecting WB Master as Host Interface
200
integer host_log_file_desc;
201
 
202
WB_MASTER_BEHAVIORAL wb_master
203 116 mohor
(
204 169 mohor
    .CLK_I(wb_clk),
205
    .RST_I(wb_rst),
206
    .TAG_I({`WB_TAG_WIDTH{1'b0}}),
207
    .TAG_O(),
208
    .ACK_I(eth_sl_wb_ack_o),
209
    .ADR_O(eth_sl_wb_adr), // only eth_sl_wb_adr_i[11:2] used
210
    .CYC_O(eth_sl_wb_cyc_i),
211
    .DAT_I(eth_sl_wb_dat_o),
212
    .DAT_O(eth_sl_wb_dat_i),
213
    .ERR_I(eth_sl_wb_err_o),
214
    .RTY_I(1'b0),  // inactive (1'b0)
215
    .SEL_O(eth_sl_wb_sel_i),
216
    .STB_O(eth_sl_wb_stb_i),
217
    .WE_O (eth_sl_wb_we_i),
218
    .CAB_O()       // NOT USED for now!
219
);
220
 
221
assign eth_sl_wb_adr_i = {20'h0, eth_sl_wb_adr[11:2], 2'h0};
222
 
223
 
224
 
225
// Connecting WB Slave as Memory Interface Module
226
integer memory_log_file_desc;
227
 
228
WB_SLAVE_BEHAVIORAL wb_slave
229
(
230
    .CLK_I(wb_clk),
231
    .RST_I(wb_rst),
232
    .ACK_O(eth_ma_wb_ack_i),
233
    .ADR_I(eth_ma_wb_adr_o),
234
    .CYC_I(eth_ma_wb_cyc_o),
235
    .DAT_O(eth_ma_wb_dat_i),
236
    .DAT_I(eth_ma_wb_dat_o),
237
    .ERR_O(eth_ma_wb_err_i),
238
    .RTY_O(),      // NOT USED for now!
239
    .SEL_I(eth_ma_wb_sel_o),
240
    .STB_I(eth_ma_wb_stb_o),
241
    .WE_I (eth_ma_wb_we_o),
242
    .CAB_I(1'b0)   // inactive (1'b0)
243
);
244
 
245
 
246
 
247
// Connecting WISHBONE Bus Monitors to ethernet master and slave interfaces
248
integer wb_s_mon_log_file_desc ;
249
integer wb_m_mon_log_file_desc ;
250
 
251
WB_BUS_MON wb_eth_slave_bus_mon
252
(
253 116 mohor
  // WISHBONE common
254 169 mohor
  .CLK_I(wb_clk),
255
  .RST_I(wb_rst),
256 116 mohor
 
257 169 mohor
  // WISHBONE slave
258
  .ACK_I(eth_sl_wb_ack_o),
259
  .ADDR_O({20'h0, eth_sl_wb_adr_i[11:2], 2'b0}),
260
  .CYC_O(eth_sl_wb_cyc_i),
261
  .DAT_I(eth_sl_wb_dat_o),
262
  .DAT_O(eth_sl_wb_dat_i),
263
  .ERR_I(eth_sl_wb_err_o),
264
  .RTY_I(1'b0),
265
  .SEL_O(eth_sl_wb_sel_i),
266
  .STB_O(eth_sl_wb_stb_i),
267
  .WE_O (eth_sl_wb_we_i),
268
  .TAG_I({`WB_TAG_WIDTH{1'b0}}),
269
  .TAG_O(),
270
  .CAB_O(1'b0),
271
  .log_file_desc (wb_s_mon_log_file_desc)
272
);
273
 
274
WB_BUS_MON wb_eth_master_bus_mon
275
(
276
  // WISHBONE common
277
  .CLK_I(wb_clk),
278
  .RST_I(wb_rst),
279
 
280 116 mohor
  // WISHBONE master
281 169 mohor
  .ACK_I(eth_ma_wb_ack_i),
282
  .ADDR_O(eth_ma_wb_adr_o),
283
  .CYC_O(eth_ma_wb_cyc_o),
284
  .DAT_I(eth_ma_wb_dat_i),
285
  .DAT_O(eth_ma_wb_dat_o),
286
  .ERR_I(eth_ma_wb_err_i),
287
  .RTY_I(1'b0),
288
  .SEL_O(eth_ma_wb_sel_o),
289
  .STB_O(eth_ma_wb_stb_o),
290
  .WE_O (eth_ma_wb_we_o),
291
  .TAG_I({`WB_TAG_WIDTH{1'b0}}),
292
  .TAG_O(),
293
  .CAB_O(1'b0),
294
  .log_file_desc(wb_m_mon_log_file_desc)
295 116 mohor
);
296
 
297
 
298
 
299 169 mohor
reg         StartTB;
300
integer     tb_log_file;
301 116 mohor
 
302 169 mohor
initial
303
begin
304
  tb_log_file = $fopen("../log/eth_tb.log");
305
  if (tb_log_file < 2)
306
  begin
307
    $display("*E Could not open/create testbench log file in ../log/ directory!");
308
    $finish;
309
  end
310
  $fdisplay(tb_log_file, "========================== ETHERNET IP Core Testbench results ===========================");
311
  $fdisplay(tb_log_file, " ");
312 116 mohor
 
313 169 mohor
  phy_log_file_desc = $fopen("../log/eth_tb_phy.log");
314
  if (phy_log_file_desc < 2)
315
  begin
316
    $fdisplay(tb_log_file, "*E Could not open/create eth_tb_phy.log file in ../log/ directory!");
317
    $finish;
318
  end
319
  $fdisplay(phy_log_file_desc, "================ PHY Module  Testbench access log ================");
320
  $fdisplay(phy_log_file_desc, " ");
321
 
322
  memory_log_file_desc = $fopen("../log/eth_tb_memory.log");
323
  if (memory_log_file_desc < 2)
324
  begin
325
    $fdisplay(tb_log_file, "*E Could not open/create eth_tb_memory.log file in ../log/ directory!");
326
    $finish;
327
  end
328
  $fdisplay(memory_log_file_desc, "=============== MEMORY Module Testbench access log ===============");
329
  $fdisplay(memory_log_file_desc, " ");
330
 
331
  host_log_file_desc = $fopen("../log/eth_tb_host.log");
332
  if (host_log_file_desc < 2)
333
  begin
334
    $fdisplay(tb_log_file, "*E Could not open/create eth_tb_host.log file in ../log/ directory!");
335
    $finish;
336
  end
337
  $fdisplay(host_log_file_desc, "================ HOST Module Testbench access log ================");
338
  $fdisplay(host_log_file_desc, " ");
339
 
340
  wb_s_mon_log_file_desc = $fopen("../log/eth_tb_wb_s_mon.log");
341
  if (wb_s_mon_log_file_desc < 2)
342
  begin
343
    $fdisplay(tb_log_file, "*E Could not open/create eth_tb_wb_s_mon.log file in ../log/ directory!");
344
    $finish;
345
  end
346
  $fdisplay(wb_s_mon_log_file_desc, "============== WISHBONE Slave Bus Monitor error log ==============");
347
  $fdisplay(wb_s_mon_log_file_desc, " ");
348
  $fdisplay(wb_s_mon_log_file_desc, "   Only ERRONEOUS conditions are logged !");
349
  $fdisplay(wb_s_mon_log_file_desc, " ");
350
 
351
  wb_m_mon_log_file_desc = $fopen("../log/eth_tb_wb_m_mon.log");
352
  if (wb_m_mon_log_file_desc < 2)
353
  begin
354
    $fdisplay(tb_log_file, "*E Could not open/create eth_tb_wb_m_mon.log file in ../log/ directory!");
355
    $finish;
356
  end
357
  $fdisplay(wb_m_mon_log_file_desc, "============= WISHBONE Master Bus Monitor  error log =============");
358
  $fdisplay(wb_m_mon_log_file_desc, " ");
359
  $fdisplay(wb_m_mon_log_file_desc, "   Only ERRONEOUS conditions are logged !");
360
  $fdisplay(wb_m_mon_log_file_desc, " ");
361
 
362
  // Clear memories
363
  clear_memories;
364
 
365
  // Reset pulse
366
  wb_rst =  1'b1;
367
  #423 wb_rst =  1'b0;
368
  #423 StartTB  =  1'b1;
369
end
370
 
371
 
372
 
373
// Generating wb_clk clock
374 116 mohor
initial
375
begin
376 169 mohor
  wb_clk=0;
377
//  forever #2.5 wb_clk = ~wb_clk;  // 2*2.5 ns -> 200.0 MHz    
378 209 tadejm
  forever #5 wb_clk = ~wb_clk;  // 2*5 ns -> 100.0 MHz    
379 169 mohor
//  forever #10 wb_clk = ~wb_clk;  // 2*10 ns -> 50.0 MHz    
380
//  forever #12.5 wb_clk = ~wb_clk;  // 2*12.5 ns -> 40 MHz    
381
//  forever #15 wb_clk = ~wb_clk;  // 2*10 ns -> 33.3 MHz    
382 209 tadejm
//  forever #20 wb_clk = ~wb_clk;  // 2*20 ns -> 25 MHz    
383 169 mohor
//  forever #25 wb_clk = ~wb_clk;  // 2*25 ns -> 20.0 MHz
384
//  forever #31.25 wb_clk = ~wb_clk;  // 2*31.25 ns -> 16.0 MHz    
385
//  forever #50 wb_clk = ~wb_clk;  // 2*50 ns -> 10.0 MHz
386
//  forever #55 wb_clk = ~wb_clk;  // 2*55 ns ->  9.1 MHz    
387 116 mohor
end
388
 
389
 
390
 
391 169 mohor
integer      tests_successfull;
392
integer      tests_failed;
393
reg [799:0]  test_name; // used for tb_log_file
394 121 mohor
 
395 169 mohor
reg   [3:0]  wbm_init_waits; // initial wait cycles between CYC_O and STB_O of WB Master
396
reg   [3:0]  wbm_subseq_waits; // subsequent wait cycles between STB_Os of WB Master
397
reg   [2:0]  wbs_waits; // wait cycles befor WB Slave responds
398
reg   [7:0]  wbs_retries; // if RTY response, then this is the number of retries before ACK
399
 
400 116 mohor
initial
401
begin
402 169 mohor
  wait(StartTB);  // Start of testbench
403
 
404
  // Initial global values
405
  tests_successfull = 0;
406
  tests_failed = 0;
407
 
408
  wbm_init_waits = 4'h1;
409
  wbm_subseq_waits = 4'h3;
410
  wbs_waits = 4'h1;
411
  wbs_retries = 8'h2;
412
  wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
413
 
414
 
415
  //  Call tests
416
  //  ----------
417 194 tadej
//    test_access_to_mac_reg(0, 3);           // 0 - 3
418
//    test_mii(0, 17);                        // 0 - 17
419 169 mohor
  test_note("PHY generates ideal Carrier sense and Collision signals for following tests");
420
  eth_phy.carrier_sense_real_delay(0);
421 223 tadejm
    test_mac_full_duplex_transmit(20, 20);    // 0 - (21)
422
//    test_mac_full_duplex_receive(0, 5);
423 209 tadejm
//    test_mac_full_duplex_flow(0, 0);
424 169 mohor
 
425
  test_note("PHY generates 'real' Carrier sense and Collision signals for following tests");
426
  eth_phy.carrier_sense_real_delay(1);
427
 
428
 
429
  // Finish test's logs
430
  test_summary;
431
  $display("\n\n END of SIMULATION");
432
  $fclose(tb_log_file | phy_log_file_desc | memory_log_file_desc | host_log_file_desc);
433
  $fclose(wb_s_mon_log_file_desc | wb_m_mon_log_file_desc);
434
 
435
  $stop;
436 116 mohor
end
437 169 mohor
 
438 116 mohor
 
439 169 mohor
 
440
//////////////////////////////////////////////////////////////
441
// Test tasks
442
//////////////////////////////////////////////////////////////
443
 
444
task test_access_to_mac_reg;
445
  input  [31:0]  start_task;
446
  input  [31:0]  end_task;
447
  integer        bit_start_1;
448
  integer        bit_end_1;
449
  integer        bit_start_2;
450
  integer        bit_end_2;
451
  integer        num_of_reg;
452
  integer        i_addr;
453
  integer        i_data;
454
  integer        i_length;
455
  integer        tmp_data;
456
  reg    [31:0]  tx_bd_num;
457
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_data;
458
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_tmp_data;
459
  integer        i;
460
  integer        i1;
461
  integer        i2;
462
  integer        i3;
463
  integer        fail;
464 178 mohor
  integer        test_num;
465 169 mohor
  reg    [31:0]  addr;
466
  reg    [31:0]  data;
467
  reg    [31:0]  data_max;
468 116 mohor
begin
469 169 mohor
// ACCESS TO MAC REGISTERS TEST
470
test_heading("ACCESS TO MAC REGISTERS TEST");
471
$display(" ");
472
$display("ACCESS TO MAC REGISTERS TEST");
473
fail = 0;
474
 
475 192 tadej
// reset MAC registers
476
hard_reset;
477
// reset MAC and MII LOGIC with soft reset
478
reset_mac;
479
reset_mii;
480 169 mohor
 
481 192 tadej
 
482 178 mohor
//////////////////////////////////////////////////////////////////////
483
////                                                              ////
484
////  test_access_to_mac_reg:                                     ////
485
////                                                              ////
486
////  0: Walking 1 with single cycles across MAC regs.            ////
487
////  1: Walking 1 with single cycles across MAC buffer descript. ////
488
////  2: Test max reg. values and reg. values after writing       ////
489
////     inverse reset values and hard reset of the MAC           ////
490
////  3: Test buffer desc. RAM preserving values after hard reset ////
491
////     of the MAC and resetting the logic                       ////
492
////                                                              ////
493
//////////////////////////////////////////////////////////////////////
494 194 tadej
for (test_num = start_task; test_num <= end_task; test_num = test_num + 1)
495 169 mohor
begin
496
 
497 178 mohor
  ////////////////////////////////////////////////////////////////////
498
  ////                                                            ////
499
  ////  Walking 1 with single cycles across MAC regs.             ////
500
  ////                                                            ////
501
  ////////////////////////////////////////////////////////////////////
502
  if (test_num == 0) // Walking 1 with single cycles across MAC regs.
503 194 tadej
  begin
504
    // TEST 0: 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )
505
    test_name   = "TEST 0: 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )";
506
    `TIME; $display("  TEST 0: 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )");
507 178 mohor
 
508 194 tadej
    data = 0;
509
    for (i = 0; i <= 4; i = i + 1) // for initial wait cycles on WB bus
510
      begin
511
        wbm_init_waits = i;
512
        wbm_subseq_waits = {$random} % 5; // it is not important for single accesses
513
        for (i_addr = 0; i_addr <= 32'h4C; i_addr = i_addr + 4) // register address
514
          begin
515
            addr = `ETH_BASE + i_addr;
516
            // set ranges of R/W bits
517
            case (addr)
518
              `ETH_MODER:
519
                begin
520
                  bit_start_1 = 0;
521
                  bit_end_1   = 16;
522
                  bit_start_2 = 32; // not used
523
                  bit_end_2   = 32; // not used
524
                end
525
              `ETH_INT: // READONLY - tested within INT test
526
                begin
527
                  bit_start_1 = 32; // not used
528
                  bit_end_1   = 32; // not used
529
                  bit_start_2 = 32; // not used
530
                  bit_end_2   = 32; // not used
531
                end
532
              `ETH_INT_MASK:
533
                begin
534
                  bit_start_1 = 0;
535
                  bit_end_1   = 6;
536
                  bit_start_2 = 32; // not used
537
                  bit_end_2   = 32; // not used
538
                end
539
              `ETH_IPGT:
540
                begin
541
                  bit_start_1 = 0;
542
                  bit_end_1   = 6;
543
                  bit_start_2 = 32; // not used
544
                  bit_end_2   = 32; // not used
545
                end
546
              `ETH_IPGR1:
547
                begin
548
                  bit_start_1 = 0;
549
                  bit_end_1   = 6;
550
                  bit_start_2 = 32; // not used
551
                  bit_end_2   = 32; // not used
552
                end
553
              `ETH_IPGR2:
554
                begin
555
                  bit_start_1 = 0;
556
                  bit_end_1   = 6;
557
                  bit_start_2 = 32; // not used
558
                  bit_end_2   = 32; // not used
559
                end
560
              `ETH_PACKETLEN:
561
                begin
562
                  bit_start_1 = 0;
563
                  bit_end_1   = 31;
564
                  bit_start_2 = 32; // not used
565
                  bit_end_2   = 32; // not used
566
                end
567
              `ETH_COLLCONF:
568
                begin
569
                  bit_start_1 = 0;
570
                  bit_end_1   = 5;
571
                  bit_start_2 = 16;
572
                  bit_end_2   = 19;
573
                end
574
              `ETH_TX_BD_NUM:
575
                begin
576
                  bit_start_1 = 0;
577
                  bit_end_1   = 7;
578
                  bit_start_2 = 32; // not used
579
                  bit_end_2   = 32; // not used
580
                end
581
              `ETH_CTRLMODER:
582
                begin
583
                  bit_start_1 = 0;
584
                  bit_end_1   = 2;
585
                  bit_start_2 = 32; // not used
586
                  bit_end_2   = 32; // not used
587
                end
588
              `ETH_MIIMODER:
589
                begin
590
                  bit_start_1 = 0;
591
                  bit_end_1   = 9;
592
                  bit_start_2 = 32; // not used
593
                  bit_end_2   = 32; // not used
594
                end
595
              `ETH_MIICOMMAND: // "WRITEONLY" - tested within MIIM test - 3 LSBits are not written here!!!
596
                begin
597
                  bit_start_1 = 32; // not used
598
                  bit_end_1   = 32; // not used
599
                  bit_start_2 = 32; // not used
600
                  bit_end_2   = 32; // not used
601
                end
602
              `ETH_MIIADDRESS:
603
                begin
604
                  bit_start_1 = 0;
605
                  bit_end_1   = 4;
606
                  bit_start_2 = 8;
607
                  bit_end_2   = 12;
608
                end
609
              `ETH_MIITX_DATA:
610
                begin
611
                  bit_start_1 = 0;
612
                  bit_end_1   = 15;
613
                  bit_start_2 = 32; // not used
614
                  bit_end_2   = 32; // not used
615
                end
616
              `ETH_MIIRX_DATA: // READONLY - tested within MIIM test
617
                begin
618
                  bit_start_1 = 32; // not used
619
                  bit_end_1   = 32; // not used
620
                  bit_start_2 = 32; // not used
621
                  bit_end_2   = 32; // not used
622
                end
623
              `ETH_MIISTATUS: // READONLY - tested within MIIM test
624
                begin
625
                  bit_start_1 = 32; // not used
626
                  bit_end_1   = 32; // not used
627
                  bit_start_2 = 32; // not used
628
                  bit_end_2   = 32; // not used
629
                end
630
              `ETH_MAC_ADDR0:
631
                begin
632
                  bit_start_1 = 0;
633
                  bit_end_1   = 31;
634
                  bit_start_2 = 32; // not used
635
                  bit_end_2   = 32; // not used
636 178 mohor
                  end
637 194 tadej
              `ETH_MAC_ADDR1:
638
                begin
639
                  bit_start_1 = 0;
640
                  bit_end_1   = 15;
641
                  bit_start_2 = 32; // not used
642
                  bit_end_2   = 32; // not used
643
                end
644
              `ETH_HASH_ADDR0:
645
                begin
646
                  bit_start_1 = 0;
647
                  bit_end_1   = 31;
648
                  bit_start_2 = 32; // not used
649
                  bit_end_2   = 32; // not used
650
                end
651
              default: // `ETH_HASH_ADDR1:
652
                begin
653
                  bit_start_1 = 0;
654
                  bit_end_1   = 31;
655
                  bit_start_2 = 32; // not used
656
                  bit_end_2   = 32; // not used
657
                end
658
            endcase
659
 
660
            for (i_data = 0; i_data <= 31; i_data = i_data + 1) // the position of walking one
661
              begin
662
                data = 1'b1 << i_data;
663
                if ( (addr == `ETH_MIICOMMAND) && (i_data <= 2) ) // DO NOT WRITE to 3 LSBits of MIICOMMAND !!!
664
                  ;
665
                else
666 178 mohor
                  begin
667 194 tadej
                    wbm_write(addr, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
668
                    wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
669
                    if ( ((i_data >= bit_start_1) && (i_data <= bit_end_1)) ||
670
                         ((i_data >= bit_start_2) && (i_data <= bit_end_2)) ) // data should be equal to tmp_data
671
                      begin
672
                        if (tmp_data !== data)
673 178 mohor
                        begin
674 194 tadej
                          fail = fail + 1;
675
                          test_fail("RW bit of the MAC register was not written or not read");
676
                          `TIME;
677
                          $display("wbm_init_waits %d, addr %h, data %h, tmp_data %h",
678
                                    wbm_init_waits, addr, data, tmp_data);
679
                        end
680
                      end
681
                    else // data should not be equal to tmp_data
682
                      begin
683
                        if (tmp_data === data)
684 178 mohor
                          begin
685
                            fail = fail + 1;
686 194 tadej
                            test_fail("NON RW bit of the MAC register was written, but it shouldn't be");
687 178 mohor
                            `TIME;
688 194 tadej
                            $display("wbm_init_waits %d, addr %h, data %h, tmp_data %h",
689 178 mohor
                                      wbm_init_waits, addr, data, tmp_data);
690
                          end
691 194 tadej
                      end
692
                  end
693
              end
694
          end
695
      end
696 209 tadejm
    // INTERMEDIATE DISPLAYS (The only one)
697
    $display("    ->buffer descriptors tested with 0, 1, 2, 3 and 4 bus delay cycles");
698 194 tadej
    if(fail == 0)
699
      test_ok;
700
    else
701
      fail = 0;    // Errors were reported previously
702
  end
703 178 mohor
 
704
 
705
  ////////////////////////////////////////////////////////////////////
706
  ////                                                            ////
707
  ////  Walking 1 with single cycles across MAC buffer descript.  ////
708
  ////                                                            ////
709
  ////////////////////////////////////////////////////////////////////
710
  if (test_num == 1) // Start Walking 1 with single cycles across MAC buffer descript.
711 169 mohor
  begin
712 194 tadej
    // TEST 1: 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC BUFFER DESC. ( VARIOUS BUS DELAYS )
713
    test_name   = "TEST 1: 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC BUFFER DESC. ( VARIOUS BUS DELAYS )";
714
    `TIME; $display("  TEST 1: 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC BUFFER DESC. ( VARIOUS BUS DELAYS )");
715 178 mohor
 
716
    data = 0;
717
    // set TX and RX buffer descriptors
718
    tx_bd_num = 32'h40;
719
    wbm_write(`ETH_TX_BD_NUM, tx_bd_num, 4'hF, 1, 0, 0);
720
    for (i = 0; i <= 4; i = i + 1) // for initial wait cycles on WB bus
721
    begin
722 169 mohor
      wbm_init_waits = i;
723
      wbm_subseq_waits = {$random} % 5; // it is not important for single accesses
724 178 mohor
      for (i_addr = 32'h400; i_addr <= 32'h7FC; i_addr = i_addr + 4) // buffer descriptor address
725 169 mohor
      begin
726
        addr = `ETH_BASE + i_addr;
727 178 mohor
        if (i_addr < (32'h400 + (tx_bd_num << 3))) // TX buffer descriptors
728
        begin
729
          // set ranges of R/W bits
730
          case (addr[3])
731
            1'b0: // buffer control bits
732
            begin
733
              bit_start_1 = 0;
734
              bit_end_1   = 31; // 8;
735
              bit_start_2 = 11;
736
              bit_end_2   = 31;
737
            end
738
            default: // 1'b1: // buffer pointer
739
            begin
740
              bit_start_1 = 0;
741
              bit_end_1   = 31;
742
              bit_start_2 = 32; // not used
743
              bit_end_2   = 32; // not used
744
            end
745
          endcase
746
        end
747
        else // RX buffer descriptors
748
        begin
749
          // set ranges of R/W bits
750
          case (addr[3])
751
            1'b0: // buffer control bits
752
            begin
753
              bit_start_1 = 0;
754
              bit_end_1   = 31; // 7;
755
              bit_start_2 = 13;
756
              bit_end_2   = 31;
757
            end
758
            default: // 1'b1: // buffer pointer
759
            begin
760
              bit_start_1 = 0;
761
              bit_end_1   = 31;
762
              bit_start_2 = 32; // not used
763
              bit_end_2   = 32; // not used
764
            end
765
          endcase
766
        end
767
 
768 169 mohor
        for (i_data = 0; i_data <= 31; i_data = i_data + 1) // the position of walking one
769
        begin
770
          data = 1'b1 << i_data;
771 178 mohor
          if ( (addr[3] == 0) && (i_data == 15) ) // DO NOT WRITE to this bit !!!
772
            ;
773 169 mohor
          else
774
          begin
775
            wbm_write(addr, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
776
            wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
777
            if ( ((i_data >= bit_start_1) && (i_data <= bit_end_1)) ||
778
                 ((i_data >= bit_start_2) && (i_data <= bit_end_2)) ) // data should be equal to tmp_data
779
            begin
780
              if (tmp_data !== data)
781
              begin
782
                fail = fail + 1;
783 178 mohor
                test_fail("RW bit of the MAC buffer descriptors was not written or not read");
784 169 mohor
                `TIME;
785
                $display("wbm_init_waits %d, addr %h, data %h, tmp_data %h",
786
                          wbm_init_waits, addr, data, tmp_data);
787
              end
788
            end
789
            else // data should not be equal to tmp_data
790
            begin
791
              if (tmp_data === data)
792
              begin
793
                fail = fail + 1;
794 178 mohor
                test_fail("NON RW bit of the MAC buffer descriptors was written, but it shouldn't be");
795 169 mohor
                `TIME;
796
                $display("wbm_init_waits %d, addr %h, data %h, tmp_data %h",
797
                          wbm_init_waits, addr, data, tmp_data);
798
              end
799
            end
800
          end
801
        end
802
      end
803 178 mohor
      // INTERMEDIATE DISPLAYS
804
      case (i)
805 209 tadejm
        0:       $display("    ->buffer descriptors tested with 0 bus delay");
806
        1:       $display("    ->buffer descriptors tested with 1 bus delay cycle");
807
        2:       $display("    ->buffer descriptors tested with 2 bus delay cycles");
808
        3:       $display("    ->buffer descriptors tested with 3 bus delay cycles");
809
        default: $display("    ->buffer descriptors tested with 4 bus delay cycles");
810 178 mohor
      endcase
811
    end
812
    if(fail == 0)
813
      test_ok;
814
    else
815
      fail = 0;
816 169 mohor
  end
817 178 mohor
 
818
 
819
  ////////////////////////////////////////////////////////////////////
820
  ////                                                            ////
821
  ////  Test max reg. values and reg. values after writing        ////
822
  ////  inverse reset values and hard reset of the MAC            ////
823
  ////                                                            ////
824
  ////////////////////////////////////////////////////////////////////
825
  if (test_num == 2) // Start this task
826 169 mohor
  begin
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
    test_name   =
829 194 tadej
      "TEST 2: MAX REG. VALUES AND REG. VALUES AFTER WRITING INVERSE RESET VALUES AND HARD RESET OF THE MAC";
830 178 mohor
    `TIME; $display(
831 194 tadej
      "  TEST 2: MAX REG. VALUES AND REG. VALUES AFTER WRITING INVERSE RESET VALUES AND HARD RESET OF THE MAC");
832 178 mohor
 
833
    // reset MAC registers
834
    hard_reset;
835
    for (i = 0; i <= 4; i = i + 1) // 0, 2 - WRITE; 1, 3, 4 - READ
836 169 mohor
    begin
837 178 mohor
      for (i_addr = 0; i_addr <= 32'h4C; i_addr = i_addr + 4) // register address
838 169 mohor
      begin
839 178 mohor
        addr = `ETH_BASE + i_addr;
840
        // set ranges of R/W bits
841
        case (addr)
842
          `ETH_MODER:
843 169 mohor
          begin
844 178 mohor
            data = 32'h0000_A800;
845
            data_max = 32'h0001_FFFF;
846 169 mohor
          end
847 178 mohor
          `ETH_INT: // READONLY - tested within INT test
848 169 mohor
          begin
849 178 mohor
            data = 32'h0000_0000;
850
            data_max = 32'h0000_0000;
851 169 mohor
          end
852
          `ETH_INT_MASK:
853 178 mohor
          begin
854
            data = 32'h0000_0000;
855
            data_max = 32'h0000_007F;
856
          end
857 169 mohor
          `ETH_IPGT:
858 178 mohor
          begin
859
            data = 32'h0000_0012;
860
            data_max = 32'h0000_007F;
861
          end
862 169 mohor
          `ETH_IPGR1:
863 178 mohor
          begin
864
            data = 32'h0000_000C;
865
            data_max = 32'h0000_007F;
866
          end
867 169 mohor
          `ETH_IPGR2:
868 178 mohor
          begin
869
            data = 32'h0000_0012;
870
            data_max = 32'h0000_007F;
871
          end
872 169 mohor
          `ETH_PACKETLEN:
873 178 mohor
          begin
874
            data = 32'h0040_0600;
875
            data_max = 32'hFFFF_FFFF;
876
          end
877 169 mohor
          `ETH_COLLCONF:
878 178 mohor
          begin
879
            data = 32'h000F_003F;
880
            data_max = 32'h000F_003F;
881
          end
882 169 mohor
          `ETH_TX_BD_NUM:
883 178 mohor
          begin
884
            data = 32'h0000_0040;
885
            data_max = 32'h0000_0080;
886
          end
887 169 mohor
          `ETH_CTRLMODER:
888 178 mohor
          begin
889
            data = 32'h0000_0000;
890
            data_max = 32'h0000_0007;
891
          end
892 169 mohor
          `ETH_MIIMODER:
893 178 mohor
          begin
894
            data = 32'h0000_0064;
895
            data_max = 32'h0000_03FF;
896
          end
897 169 mohor
          `ETH_MIICOMMAND: // "WRITEONLY" - tested within MIIM test - 3 LSBits are not written here!!!
898 178 mohor
          begin
899
            data = 32'h0000_0000;
900
            data_max = 32'h0000_0007;
901
          end
902 169 mohor
          `ETH_MIIADDRESS:
903 178 mohor
          begin
904
            data = 32'h0000_0000;
905
            data_max = 32'h0000_1F1F;
906
          end
907 169 mohor
          `ETH_MIITX_DATA:
908 178 mohor
          begin
909
            data = 32'h0000_0000;
910
            data_max = 32'h0000_FFFF;
911
          end
912 169 mohor
          `ETH_MIIRX_DATA: // READONLY - tested within MIIM test
913
          begin
914 178 mohor
            data = 32'h0000_0000;
915
            data_max = 32'h0000_0000;
916 169 mohor
          end
917 178 mohor
          `ETH_MIISTATUS: // READONLY - tested within MIIM test
918 169 mohor
          begin
919 178 mohor
            data = 32'h0000_0000;
920
            data_max = 32'h0000_0000;
921 169 mohor
          end
922 178 mohor
          `ETH_MAC_ADDR0:
923 169 mohor
          begin
924 178 mohor
            data = 32'h0000_0000;
925
            data_max = 32'hFFFF_FFFF;
926 169 mohor
          end
927 178 mohor
          `ETH_MAC_ADDR1:
928 169 mohor
          begin
929 178 mohor
            data = 32'h0000_0000;
930
            data_max = 32'h0000_FFFF;
931 169 mohor
          end
932 178 mohor
          `ETH_HASH_ADDR0:
933 169 mohor
          begin
934 178 mohor
            data = 32'h0000_0000;
935
            data_max = 32'hFFFF_FFFF;
936 169 mohor
          end
937 178 mohor
          default: // `ETH_HASH_ADDR1:
938 169 mohor
          begin
939 178 mohor
            data = 32'h0000_0000;
940
            data_max = 32'hFFFF_FFFF;
941 169 mohor
          end
942
        endcase
943 178 mohor
 
944
        wbm_init_waits = {$random} % 3;
945
        wbm_subseq_waits = {$random} % 5; // it is not important for single accesses
946
        if (i == 0)
947
          wbm_write(addr, ~data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
948
        else if (i == 2)
949
          wbm_write(addr, 32'hFFFFFFFF, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
950
        else if ((i == 1) || (i == 4))
951 169 mohor
        begin
952 178 mohor
          wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
953
          if (tmp_data !== data)
954
          begin
955
            fail = fail + 1;
956
            test_fail("RESET value of the MAC register is not correct");
957
            `TIME;
958
            $display("  addr %h, data %h, tmp_data %h", addr, data, tmp_data);
959
          end
960 169 mohor
        end
961 178 mohor
        else // check maximum values
962 169 mohor
        begin
963
          wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
964 178 mohor
          if (addr == `ETH_TX_BD_NUM) // previous data should remain in this register
965 169 mohor
          begin
966
            if (tmp_data !== data)
967
            begin
968
              fail = fail + 1;
969 178 mohor
              test_fail("Previous value of the TX_BD_NUM register did not remain");
970 169 mohor
              `TIME;
971 178 mohor
              $display("  addr %h, data_max %h, tmp_data %h", addr, data_max, tmp_data);
972 169 mohor
            end
973 178 mohor
            // try maximum (80)
974
            wbm_write(addr, data_max, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
975
            wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
976
            if (tmp_data !== data_max)
977
            begin
978
              fail = fail + 1;
979
              test_fail("MAX value of the TX_BD_NUM register is not correct");
980
              `TIME;
981
              $display("  addr %h, data_max %h, tmp_data %h", addr, data_max, tmp_data);
982
            end
983
            // try one less than maximum (80)
984
            wbm_write(addr, (data_max - 1), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
985
            wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
986
            if (tmp_data !== (data_max - 1))
987
            begin
988
              fail = fail + 1;
989
              test_fail("ONE less than MAX value of the TX_BD_NUM register is not correct");
990
              `TIME;
991
              $display("  addr %h, data_max %h, tmp_data %h", addr, data_max, tmp_data);
992
            end
993
            // try one more than maximum (80)
994
            wbm_write(addr, (data_max + 1), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
995
            wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
996
            if (tmp_data !== (data_max - 1)) // previous data should remain in this register
997
            begin
998
              fail = fail + 1;
999
              test_fail("Previous value of the TX_BD_NUM register did not remain");
1000
              `TIME;
1001
              $display("  addr %h, data_max %h, tmp_data %h", addr, data_max, tmp_data);
1002
            end
1003 169 mohor
          end
1004 178 mohor
          else
1005 169 mohor
          begin
1006 178 mohor
            if (tmp_data !== data_max)
1007 169 mohor
            begin
1008
              fail = fail + 1;
1009 178 mohor
              test_fail("MAX value of the MAC register is not correct");
1010 169 mohor
              `TIME;
1011 178 mohor
              $display("  addr %h, data_max %h, tmp_data %h", addr, data_max, tmp_data);
1012 169 mohor
            end
1013
          end
1014
        end
1015
      end
1016 178 mohor
      // reset MAC registers
1017
      if ((i == 0) || (i == 3))
1018
        hard_reset;
1019 169 mohor
    end
1020 178 mohor
    if(fail == 0)
1021
      test_ok;
1022
    else
1023
      fail = 0;
1024 169 mohor
  end
1025 116 mohor
 
1026 156 mohor
 
1027 181 mohor
  ////////////////////////////////////////////////////////////////////
1028
  ////                                                            ////
1029
  ////  Test buffer desc. ram preserving values after hard reset  ////
1030
  ////  of the mac and reseting the logic                         ////
1031
  ////                                                            ////
1032
  ////////////////////////////////////////////////////////////////////
1033 178 mohor
  if (test_num == 3) // Start this task
1034 169 mohor
  begin
1035 194 tadej
    // TEST 3: BUFFER DESC. RAM PRESERVING VALUES AFTER HARD RESET OF THE MAC AND RESETING THE LOGIC
1036
    test_name   = "TEST 3: BUFFER DESC. RAM PRESERVING VALUES AFTER HARD RESET OF THE MAC AND RESETING THE LOGIC";
1037 178 mohor
    `TIME;
1038 194 tadej
    $display("  TEST 3: BUFFER DESC. RAM PRESERVING VALUES AFTER HARD RESET OF THE MAC AND RESETING THE LOGIC");
1039 178 mohor
 
1040
    // reset MAC registers
1041
    hard_reset;
1042
    // reset LOGIC with soft reset
1043
    reset_mac;
1044
    reset_mii;
1045
    for (i = 0; i <= 3; i = i + 1) // 0, 2 - WRITE; 1, 3 - READ
1046 169 mohor
    begin
1047 178 mohor
      for (i_addr = 32'h400; i_addr <= 32'h7FC; i_addr = i_addr + 4) // buffer descriptor address
1048 169 mohor
      begin
1049 178 mohor
        addr = `ETH_BASE + i_addr;
1050
 
1051
        wbm_init_waits = {$random} % 3;
1052
        wbm_subseq_waits = {$random} % 5; // it is not important for single accesses
1053
        if (i == 0)
1054 169 mohor
        begin
1055 178 mohor
          data = 32'hFFFFFFFF;
1056
          wbm_write(addr, 32'hFFFFFFFF, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1057 169 mohor
        end
1058 178 mohor
        else if (i == 2)
1059 169 mohor
        begin
1060 178 mohor
          data = 32'h00000000;
1061
          wbm_write(addr, 32'h00000000, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1062 169 mohor
        end
1063
        else
1064
        begin
1065 178 mohor
          wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1066
          if (tmp_data !== data)
1067 169 mohor
          begin
1068
            fail = fail + 1;
1069 178 mohor
            test_fail("PRESERVED value of the MAC buffer descriptors is not correct");
1070 169 mohor
            `TIME;
1071 178 mohor
            $display("  addr %h, data %h, tmp_data %h", addr, data, tmp_data);
1072 169 mohor
          end
1073
        end
1074
      end
1075 178 mohor
      if ((i == 0) || (i == 2))
1076
      begin
1077
        // reset MAC registers
1078
        hard_reset;
1079
        // reset LOGIC with soft reset
1080
        reset_mac;
1081
        reset_mii;
1082
      end
1083 169 mohor
    end
1084 178 mohor
    if(fail == 0)
1085
      test_ok;
1086
    else
1087
    fail = 0;
1088 169 mohor
  end
1089 116 mohor
 
1090
 
1091 178 mohor
  if (test_num == 4) // Start this task
1092 169 mohor
  begin
1093 194 tadej
        /*  // TEST 4: 'WALKING ONE' WITH BURST CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )
1094
          test_name   = "TEST 4: 'WALKING ONE' WITH BURST CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )";
1095
          `TIME; $display("  TEST 4: 'WALKING ONE' WITH BURST CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )");
1096 178 mohor
 
1097
          data = 0;
1098
          burst_data = 0;
1099
          burst_tmp_data = 0;
1100
          i_length = 10; // two bursts for length 20
1101
          for (i = 0; i <= 4; i = i + 1) // for initial wait cycles on WB bus
1102
          begin
1103
            for (i1 = 0; i1 <= 4; i1 = i1 + 1) // for initial wait cycles on WB bus
1104
            begin
1105
              wbm_init_waits = i;
1106
              wbm_subseq_waits = i1;
1107
              #1;
1108
              for (i_data = 0; i_data <= 31; i_data = i_data + 1) // the position of walking one
1109
              begin
1110
                data = 1'b1 << i_data;
1111
                #1;
1112
                for (i2 = 32'h4C; i2 >= 0; i2 = i2 - 4)
1113
                begin
1114
                  burst_data = burst_data << 32;
1115
                  // DO NOT WRITE to 3 LSBits of MIICOMMAND !!!
1116
                  if ( ((`ETH_BASE + i2) == `ETH_MIICOMMAND) && (i_data <= 2) )
1117
                  begin
1118
                    #1 burst_data[31:0] = 0;
1119
                  end
1120
                  else
1121
                  begin
1122
                    #1 burst_data[31:0] = data;
1123
                  end
1124
                end
1125
                #1;
1126
                // 2 burst writes
1127
                addr = `ETH_BASE; // address of a first burst
1128
                wbm_write(addr, burst_data[(32 * 10 - 1):0], 4'hF, i_length, wbm_init_waits, wbm_subseq_waits);
1129
                burst_tmp_data = burst_data >> (32 * i_length);
1130
                addr = addr + 32'h28; // address of a second burst
1131
                wbm_write(addr, burst_tmp_data[(32 * 10 - 1):0], 4'hF, i_length, wbm_init_waits, wbm_subseq_waits);
1132
                #1;
1133
                // 2 burst reads
1134
                addr = `ETH_BASE; // address of a first burst
1135
                wbm_read(addr, burst_tmp_data[(32 * 10 - 1):0], 4'hF, i_length,
1136
                         wbm_init_waits, wbm_subseq_waits); // first burst
1137
                burst_tmp_data = burst_tmp_data << (32 * i_length);
1138
                addr = addr + 32'h28; // address of a second burst
1139
                wbm_read(addr, burst_tmp_data[(32 * 10 - 1):0], 4'hF, i_length,
1140
                         wbm_init_waits, wbm_subseq_waits); // second burst
1141
                #1;
1142
                for (i2 = 0; i2 <= 32'h4C; i2 = i2 + 4)
1143
                begin
1144
                  // set ranges of R/W bits
1145
                  case (`ETH_BASE + i2)
1146
                  `ETH_MODER:
1147
                    begin
1148
                      bit_start_1 = 0;
1149
                      bit_end_1   = 16;
1150
                      bit_start_2 = 32; // not used
1151
                      bit_end_2   = 32; // not used
1152
                    end
1153
                  `ETH_INT: // READONLY - tested within INT test
1154
                    begin
1155
                      bit_start_1 = 32; // not used
1156
                      bit_end_1   = 32; // not used
1157
                      bit_start_2 = 32; // not used
1158
                      bit_end_2   = 32; // not used
1159
                    end
1160
                  `ETH_INT_MASK:
1161
                    begin
1162
                      bit_start_1 = 0;
1163
                      bit_end_1   = 6;
1164
                      bit_start_2 = 32; // not used
1165
                      bit_end_2   = 32; // not used
1166
                    end
1167
                  `ETH_IPGT:
1168
                    begin
1169
                      bit_start_1 = 0;
1170
                      bit_end_1   = 6;
1171
                      bit_start_2 = 32; // not used
1172
                      bit_end_2   = 32; // not used
1173
                    end
1174
                  `ETH_IPGR1:
1175
                    begin
1176
                      bit_start_1 = 0;
1177
                      bit_end_1   = 6;
1178
                      bit_start_2 = 32; // not used
1179
                      bit_end_2   = 32; // not used
1180
                    end
1181
                  `ETH_IPGR2:
1182
                    begin
1183
                      bit_start_1 = 0;
1184
                      bit_end_1   = 6;
1185
                      bit_start_2 = 32; // not used
1186
                      bit_end_2   = 32; // not used
1187
                    end
1188
                  `ETH_PACKETLEN:
1189
                    begin
1190
                      bit_start_1 = 0;
1191
                      bit_end_1   = 31;
1192
                      bit_start_2 = 32; // not used
1193
                      bit_end_2   = 32; // not used
1194
                    end
1195
                  `ETH_COLLCONF:
1196
                    begin
1197
                      bit_start_1 = 0;
1198
                      bit_end_1   = 5;
1199
                      bit_start_2 = 16;
1200
                      bit_end_2   = 19;
1201
                    end
1202
                  `ETH_TX_BD_NUM:
1203
                    begin
1204
                      bit_start_1 = 0;
1205
                      bit_end_1   = 7;
1206
                      bit_start_2 = 32; // not used
1207
                      bit_end_2   = 32; // not used
1208
                    end
1209
                  `ETH_CTRLMODER:
1210
                    begin
1211
                      bit_start_1 = 0;
1212
                      bit_end_1   = 2;
1213
                      bit_start_2 = 32; // not used
1214
                      bit_end_2   = 32; // not used
1215
                    end
1216
                  `ETH_MIIMODER:
1217
                    begin
1218
                      bit_start_1 = 0;
1219
                      bit_end_1   = 9;
1220
                      bit_start_2 = 32; // not used
1221
                      bit_end_2   = 32; // not used
1222
                    end
1223
                  `ETH_MIICOMMAND: // "WRITEONLY" - tested within MIIM test - 3 LSBits are not written here!!!
1224
                    begin
1225
                      bit_start_1 = 32; // not used
1226
                      bit_end_1   = 32; // not used
1227
                      bit_start_2 = 32; // not used
1228
                      bit_end_2   = 32; // not used
1229
                    end
1230
                  `ETH_MIIADDRESS:
1231
                    begin
1232
                      bit_start_1 = 0;
1233
                      bit_end_1   = 4;
1234
                      bit_start_2 = 8;
1235
                      bit_end_2   = 12;
1236
                    end
1237
                  `ETH_MIITX_DATA:
1238
                    begin
1239
                      bit_start_1 = 0;
1240
                      bit_end_1   = 15;
1241
                      bit_start_2 = 32; // not used
1242
                      bit_end_2   = 32; // not used
1243
                    end
1244
                  `ETH_MIIRX_DATA: // READONLY - tested within MIIM test
1245
                    begin
1246
                      bit_start_1 = 32; // not used
1247
                      bit_end_1   = 32; // not used
1248
                      bit_start_2 = 32; // not used
1249
                      bit_end_2   = 32; // not used
1250
                    end
1251
                  `ETH_MIISTATUS: // READONLY - tested within MIIM test
1252
                    begin
1253
                      bit_start_1 = 32; // not used
1254
                      bit_end_1   = 32; // not used
1255
                      bit_start_2 = 32; // not used
1256
                      bit_end_2   = 32; // not used
1257
                    end
1258
                  `ETH_MAC_ADDR0:
1259
                    begin
1260
                      bit_start_1 = 0;
1261
                      bit_end_1   = 31;
1262
                      bit_start_2 = 32; // not used
1263
                      bit_end_2   = 32; // not used
1264
                    end
1265
                  `ETH_MAC_ADDR1:
1266
                    begin
1267
                      bit_start_1 = 0;
1268
                      bit_end_1   = 15;
1269
                      bit_start_2 = 32; // not used
1270
                      bit_end_2   = 32; // not used
1271
                    end
1272
                  `ETH_HASH_ADDR0:
1273
                    begin
1274
                      bit_start_1 = 0;
1275
                      bit_end_1   = 31;
1276
                      bit_start_2 = 32; // not used
1277
                      bit_end_2   = 32; // not used
1278
                    end
1279
                  default: // `ETH_HASH_ADDR1:
1280
                    begin
1281
                      bit_start_1 = 0;
1282
                      bit_end_1   = 31;
1283
                      bit_start_2 = 32; // not used
1284
                      bit_end_2   = 32; // not used
1285
                    end
1286
                  endcase
1287
                  #1;
1288
                  // 3 LSBits of MIICOMMAND are NOT written !!!
1289
                  if ( ((`ETH_BASE + i2) == `ETH_MIICOMMAND) && (i_data <= 2) )
1290
                  begin
1291
                    if (burst_tmp_data[31:0] !== burst_data[31:0])
1292
                    begin
1293
                      fail = fail + 1;
1294
                      test_fail("NON WR bit of the MAC MIICOMMAND register was wrong written or read");
1295
                      `TIME;
1296
                      $display("wbm_init_waits %d, wbm_subseq_waits %d, addr %h, data %h, tmp_data %h",
1297
                                wbm_init_waits, wbm_subseq_waits, i2, burst_data[31:0], burst_tmp_data[31:0]);
1298
                    end
1299
                  end
1300
                  else
1301
                  begin
1302
                    if ( ((i_data >= bit_start_1) && (i_data <= bit_end_1)) ||
1303
                         ((i_data >= bit_start_2) && (i_data <= bit_end_2)) ) // data should be equal to tmp_data
1304
                    begin
1305
                      if (burst_tmp_data[31:0] !== burst_data[31:0])
1306
                      begin
1307
                        fail = fail + 1;
1308
                        test_fail("RW bit of the MAC register was not written or not read");
1309
                        `TIME;
1310
                        $display("wbm_init_waits %d, wbm_subseq_waits %d, addr %h, data %h, tmp_data %h",
1311
                                  wbm_init_waits, wbm_subseq_waits, i2, burst_data[31:0], burst_tmp_data[31:0]);
1312
                      end
1313
                    end
1314
                    else // data should not be equal to tmp_data
1315
                    begin
1316
                      if (burst_tmp_data[31:0] === burst_data[31:0])
1317
                      begin
1318
                        fail = fail + 1;
1319
                        test_fail("NON RW bit of the MAC register was written, but it shouldn't be");
1320
                        `TIME;
1321
                        $display("wbm_init_waits %d, wbm_subseq_waits %d, addr %h, data %h, tmp_data %h",
1322
                                  wbm_init_waits, wbm_subseq_waits, i2, burst_data[31:0], burst_tmp_data[31:0]);
1323
                      end
1324
                    end
1325
                  end
1326
                  burst_tmp_data = burst_tmp_data >> 32;
1327
                  burst_data = burst_data >> 32;
1328
                end
1329
              end
1330
            end
1331
          end
1332
          if(fail == 0)
1333
            test_ok;
1334
          else
1335
            fail = 0;*/
1336
  end
1337 116 mohor
 
1338 169 mohor
end
1339 156 mohor
 
1340 169 mohor
end
1341
endtask // test_access_to_mac_reg
1342 156 mohor
 
1343
 
1344 169 mohor
task test_mii;
1345
  input  [31:0]  start_task;
1346
  input  [31:0]  end_task;
1347
  integer        i;
1348
  integer        i1;
1349
  integer        i2;
1350
  integer        i3;
1351
  integer        cnt;
1352
  integer        fail;
1353 181 mohor
  integer        test_num;
1354 169 mohor
  reg     [8:0]  clk_div; // only 8 bits are valid!
1355
  reg     [4:0]  phy_addr;
1356
  reg     [4:0]  reg_addr;
1357
  reg     [15:0] phy_data;
1358
  reg     [15:0] tmp_data;
1359
begin
1360
// MIIM MODULE TEST
1361
test_heading("MIIM MODULE TEST");
1362
$display(" ");
1363
$display("MIIM MODULE TEST");
1364
fail = 0;
1365 156 mohor
 
1366 192 tadej
// reset MAC registers
1367
hard_reset;
1368
// reset MAC and MII LOGIC with soft reset
1369
reset_mac;
1370 169 mohor
reset_mii;
1371 116 mohor
 
1372 194 tadej
 
1373 181 mohor
//////////////////////////////////////////////////////////////////////
1374
////                                                              ////
1375
////  test_mii:                                                   ////
1376
////                                                              ////
1377
////  0:  Test clock divider of mii management module with all    ////
1378
////      possible frequences.                                    ////
1379
////  1:  Test various readings from 'real' phy registers.        ////
1380
////  2:  Test various writings to 'real' phy registers (control  ////
1381
////      and non writable registers)                             ////
1382
////  3:  Test reset phy through mii management module            ////
1383
////  4:  Test 'walking one' across phy address (with and without ////
1384
////      preamble)                                               ////
1385
////  5:  Test 'walking one' across phy's register address (with  ////
1386
////      and without preamble)                                   ////
1387
////  6:  Test 'walking one' across phy's data (with and without  ////
1388
////      preamble)                                               ////
1389
////  7:  Test reading from phy with wrong phy address (host      ////
1390
////      reading high 'z' data)                                  ////
1391
////  8:  Test writing to phy with wrong phy address and reading  ////
1392
////      from correct one                                        ////
1393
////  9:  Test sliding stop scan command immediately after read   ////
1394
////      request (with and without preamble)                     ////
1395
//// 10:  Test sliding stop scan command immediately after write  ////
1396
////      request (with and without preamble)                     ////
1397
//// 11:  Test busy and nvalid status durations during write      ////
1398
////      (with and without preamble)                             ////
1399
//// 12:  Test busy and nvalid status durations during write      ////
1400
////      (with and without preamble)                             ////
1401
//// 13:  Test busy and nvalid status durations during scan (with ////
1402
////      and without preamble)                                   ////
1403
//// 14:  Test scan status from phy with detecting link-fail bit  ////
1404
////      (with and without preamble)                             ////
1405
//// 15:  Test scan status from phy with sliding link-fail bit    ////
1406
////      (with and without preamble)                             ////
1407
//// 16:  Test sliding stop scan command immediately after scan   ////
1408
////      request (with and without preamble)                     ////
1409
//// 17:  Test sliding stop scan command after 2. scan (with and  ////
1410
////      without preamble)                                       ////
1411
////                                                              ////
1412
//////////////////////////////////////////////////////////////////////
1413 194 tadej
for (test_num = start_task; test_num <= end_task; test_num = test_num + 1)
1414 169 mohor
begin
1415 194 tadej
 
1416 181 mohor
  ////////////////////////////////////////////////////////////////////
1417
  ////                                                            ////
1418
  ////  Test clock divider of mii management module with all      ////
1419
  ////  possible frequences.                                      ////
1420
  ////                                                            ////
1421
  ////////////////////////////////////////////////////////////////////
1422
  if (test_num == 0) // Test clock divider of mii management module with all possible frequences.
1423 169 mohor
  begin
1424 194 tadej
    // TEST 0: CLOCK DIVIDER OF MII MANAGEMENT MODULE WITH ALL POSSIBLE FREQUENCES
1425
    test_name   = "TEST 0: CLOCK DIVIDER OF MII MANAGEMENT MODULE WITH ALL POSSIBLE FREQUENCES";
1426
    `TIME; $display("  TEST 0: CLOCK DIVIDER OF MII MANAGEMENT MODULE WITH ALL POSSIBLE FREQUENCES");
1427 181 mohor
 
1428
    wait(Mdc_O); // wait for MII clock to be 1
1429
    for(clk_div = 0; clk_div <= 255; clk_div = clk_div + 1)
1430
    begin
1431
      i1 = 0;
1432
      i2 = 0;
1433
      #Tp mii_set_clk_div(clk_div[7:0]);
1434
      @(posedge Mdc_O);
1435
      #Tp;
1436
      fork
1437 169 mohor
        begin
1438 181 mohor
          @(posedge Mdc_O);
1439 169 mohor
          #Tp;
1440 181 mohor
          disable count_i1;
1441
          disable count_i2;
1442 169 mohor
        end
1443 181 mohor
        begin: count_i1
1444
          forever
1445
          begin
1446
            @(posedge wb_clk);
1447
            i1 = i1 + 1;
1448
            #Tp;
1449
          end
1450
        end
1451
        begin: count_i2
1452
          forever
1453
          begin
1454
            @(negedge wb_clk);
1455
            i2 = i2 + 1;
1456
            #Tp;
1457
          end
1458
        end
1459
      join
1460
      if((clk_div[7:0] == 0) || (clk_div[7:0] == 1) || (clk_div[7:0] == 2) || (clk_div[7:0] == 3))
1461
      begin
1462
        if((i1 == i2) && (i1 == 2))
1463 169 mohor
        begin
1464
        end
1465 181 mohor
        else
1466
        begin
1467
          fail = fail + 1;
1468 209 tadejm
          test_fail("Clock divider of MII module did'nt divide frequency corectly (it should divide by 2)");
1469 181 mohor
        end
1470 169 mohor
      end
1471
      else
1472
      begin
1473 181 mohor
        if((i1 == i2) && (i1 == {clk_div[7:1], 1'b0}))
1474
        begin
1475
        end
1476
        else
1477
        begin
1478
          fail = fail + 1;
1479
          test_fail("Clock divider of MII module did'nt divide frequency corectly");
1480
        end
1481 169 mohor
      end
1482
    end
1483 181 mohor
    if(fail == 0)
1484
      test_ok;
1485 169 mohor
    else
1486 181 mohor
      fail = 0;
1487
  end
1488
 
1489
 
1490
  ////////////////////////////////////////////////////////////////////
1491
  ////                                                            ////
1492
  ////  Test various readings from 'real' phy registers.          ////
1493
  ////                                                            ////
1494
  ////////////////////////////////////////////////////////////////////
1495
  if (test_num == 1) // Test various readings from 'real' phy registers.
1496
  begin
1497 194 tadej
    // TEST 1: VARIOUS READINGS FROM 'REAL' PHY REGISTERS
1498
    test_name   = "TEST 1: VARIOUS READINGS FROM 'REAL' PHY REGISTERS";
1499
    `TIME; $display("  TEST 1: VARIOUS READINGS FROM 'REAL' PHY REGISTERS");
1500 181 mohor
 
1501
    // set the fastest possible MII
1502
    clk_div = 0;
1503
    mii_set_clk_div(clk_div[7:0]);
1504
    // set address
1505
    reg_addr = 5'h1F;
1506
    phy_addr = 5'h1;
1507
    while(reg_addr >= 5'h4)
1508 169 mohor
    begin
1509 181 mohor
      // read request
1510
      #Tp mii_read_req(phy_addr, reg_addr);
1511
      check_mii_busy; // wait for read to finish
1512
      // read data
1513
      #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1514
      if (phy_data !== 16'hDEAD)
1515 169 mohor
      begin
1516 181 mohor
        test_fail("Wrong data was read from PHY from 'not used' address space");
1517
        fail = fail + 1;
1518 169 mohor
      end
1519 181 mohor
      if (reg_addr == 5'h4) // go out of for loop
1520
        reg_addr = 5'h3;
1521 169 mohor
      else
1522 181 mohor
        reg_addr = reg_addr - 5'h9;
1523 169 mohor
    end
1524 181 mohor
 
1525
    // set address
1526
    reg_addr = 5'h3;
1527
    // read request
1528
    #Tp mii_read_req(phy_addr, reg_addr);
1529
    check_mii_busy; // wait for read to finish
1530
    // read data
1531
    #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1532
    if (phy_data !== {`PHY_ID2, `MAN_MODEL_NUM, `MAN_REVISION_NUM})
1533
    begin
1534
      test_fail("Wrong data was read from PHY from ID register 2");
1535
      fail = fail + 1;
1536
    end
1537
    if(fail == 0)
1538
      test_ok;
1539
    else
1540
      fail = 0;
1541 169 mohor
  end
1542 116 mohor
 
1543
 
1544 181 mohor
  ////////////////////////////////////////////////////////////////////
1545
  ////                                                            ////
1546
  ////  Test various writings to 'real' phy registers (control    ////
1547
  ////  and non writable registers)                               ////
1548
  ////                                                            ////
1549
  ////////////////////////////////////////////////////////////////////
1550
  if (test_num == 2) // 
1551 169 mohor
  begin
1552 194 tadej
    // TEST 2: VARIOUS WRITINGS TO 'REAL' PHY REGISTERS ( CONTROL AND NON WRITABLE REGISTERS )
1553
    test_name   = "TEST 2: VARIOUS WRITINGS TO 'REAL' PHY REGISTERS ( CONTROL AND NON WRITABLE REGISTERS )";
1554
    `TIME; $display("  TEST 2: VARIOUS WRITINGS TO 'REAL' PHY REGISTERS ( CONTROL AND NON WRITABLE REGISTERS )");
1555 181 mohor
 
1556
    // negate data and try to write into unwritable register
1557
    tmp_data = ~phy_data;
1558
    // write request
1559
    #Tp mii_write_req(phy_addr, reg_addr, tmp_data);
1560
    check_mii_busy; // wait for write to finish
1561 169 mohor
    // read request
1562
    #Tp mii_read_req(phy_addr, reg_addr);
1563
    check_mii_busy; // wait for read to finish
1564
    // read data
1565 181 mohor
    #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1566
    if (tmp_data !== phy_data)
1567
    begin
1568
      test_fail("Data was written into unwritable PHY register - ID register 2");
1569
      fail = fail + 1;
1570
    end
1571
 
1572
    // set address
1573
    reg_addr = 5'h0; // control register
1574
    // read request
1575
    #Tp mii_read_req(phy_addr, reg_addr);
1576
    check_mii_busy; // wait for read to finish
1577
    // read data
1578
    #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1579
    // write request
1580
    phy_data = 16'h7DFF; // bit 15 (RESET bit) and bit 9 are self clearing bits
1581
    #Tp mii_write_req(phy_addr, reg_addr, phy_data);
1582
    check_mii_busy; // wait for write to finish
1583
    // read request
1584
    #Tp mii_read_req(phy_addr, reg_addr);
1585
    check_mii_busy; // wait for read to finish
1586
    // read data
1587 169 mohor
    #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1588 181 mohor
    if (phy_data !== 16'h7DFF)
1589 169 mohor
    begin
1590 181 mohor
      test_fail("Data was not correctly written into OR read from writable PHY register - control register");
1591 169 mohor
      fail = fail + 1;
1592
    end
1593 181 mohor
    // write request
1594
    #Tp mii_write_req(phy_addr, reg_addr, tmp_data);
1595
    check_mii_busy; // wait for write to finish
1596
    // read request
1597
    #Tp mii_read_req(phy_addr, reg_addr);
1598
    check_mii_busy; // wait for read to finish
1599
    // read data
1600
    #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1601
    if (phy_data !== tmp_data)
1602
    begin
1603
      test_fail("Data was not correctly written into OR read from writable PHY register - control register");
1604
      fail = fail + 1;
1605
    end
1606
    if(fail == 0)
1607
      test_ok;
1608 116 mohor
    else
1609 181 mohor
      fail = 0;
1610 169 mohor
  end
1611 116 mohor
 
1612
 
1613 181 mohor
  ////////////////////////////////////////////////////////////////////
1614
  ////                                                            ////
1615
  ////  Test reset phy through mii management module              ////
1616
  ////                                                            ////
1617
  ////////////////////////////////////////////////////////////////////
1618
  if (test_num == 3) // 
1619 169 mohor
  begin
1620 194 tadej
    // TEST 3: RESET PHY THROUGH MII MANAGEMENT MODULE
1621
    test_name   = "TEST 3: RESET PHY THROUGH MII MANAGEMENT MODULE";
1622
    `TIME; $display("  TEST 3: RESET PHY THROUGH MII MANAGEMENT MODULE");
1623 181 mohor
 
1624
    // set address
1625
    reg_addr = 5'h0; // control register
1626
    // write request
1627
    phy_data = 16'h7DFF; // bit 15 (RESET bit) and bit 9 are self clearing bits
1628
    #Tp mii_write_req(phy_addr, reg_addr, phy_data);
1629
    check_mii_busy; // wait for write to finish
1630
    // read request
1631
    #Tp mii_read_req(phy_addr, reg_addr);
1632
    check_mii_busy; // wait for read to finish
1633
    // read data
1634
    #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1635
    if (phy_data !== tmp_data)
1636
    begin
1637
      test_fail("Data was not correctly written into OR read from writable PHY register - control register");
1638
      fail = fail + 1;
1639
    end
1640
    // set reset bit - selfclearing bit in PHY
1641
    phy_data = phy_data | 16'h8000;
1642
    // write request
1643
    #Tp mii_write_req(phy_addr, reg_addr, phy_data);
1644
    check_mii_busy; // wait for write to finish
1645
    // read request
1646
    #Tp mii_read_req(phy_addr, reg_addr);
1647
    check_mii_busy; // wait for read to finish
1648
    // read data
1649
    #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1650
    // check self clearing of reset bit
1651
    if (tmp_data[15] !== 1'b0)
1652
    begin
1653
      test_fail("Reset bit should be self cleared - control register");
1654
      fail = fail + 1;
1655
    end
1656
    // check reset value of control register
1657
    if (tmp_data !== {2'h0, (`LED_CFG1 || `LED_CFG2), `LED_CFG1, 3'h0, `LED_CFG3, 8'h0})
1658
    begin
1659
      test_fail("PHY was not reset correctly AND/OR reset bit not self cleared");
1660
      fail = fail + 1;
1661
    end
1662
    if(fail == 0)
1663
      test_ok;
1664
    else
1665
      fail = 0;
1666 169 mohor
  end
1667
 
1668
 
1669 181 mohor
  ////////////////////////////////////////////////////////////////////
1670
  ////                                                            ////
1671
  ////  Test 'walking one' across phy address (with and without   ////
1672
  ////  preamble)                                                 ////
1673
  ////                                                            ////
1674
  ////////////////////////////////////////////////////////////////////
1675
  if (test_num == 4) // 
1676 169 mohor
  begin
1677 194 tadej
    // TEST 4: 'WALKING ONE' ACROSS PHY ADDRESS ( WITH AND WITHOUT PREAMBLE )
1678
    test_name   = "TEST 4: 'WALKING ONE' ACROSS PHY ADDRESS ( WITH AND WITHOUT PREAMBLE )";
1679
    `TIME; $display("  TEST 4: 'WALKING ONE' ACROSS PHY ADDRESS ( WITH AND WITHOUT PREAMBLE )");
1680 181 mohor
 
1681
    // set PHY to test mode
1682
    #Tp eth_phy.test_regs(1); // set test registers (wholy writable registers) and respond to all PHY addresses
1683
    for (i = 0; i <= 1; i = i + 1)
1684 169 mohor
    begin
1685 181 mohor
      #Tp eth_phy.preamble_suppresed(i);
1686
      #Tp eth_phy.clear_test_regs;
1687
      // MII mode register
1688
      wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}), 4'hF, 1, wbm_init_waits,
1689
                wbm_subseq_waits);
1690
      // walk one across phy address
1691
      for (phy_addr = 5'h1; phy_addr > 5'h0; phy_addr = phy_addr << 1)
1692 169 mohor
      begin
1693 181 mohor
        reg_addr = $random;
1694
        tmp_data = $random;
1695
        // write request
1696
        #Tp mii_write_req(phy_addr, reg_addr, tmp_data);
1697
        check_mii_busy; // wait for write to finish
1698
        // read request
1699
        #Tp mii_read_req(phy_addr, reg_addr);
1700
        check_mii_busy; // wait for read to finish
1701
        // read data
1702
        #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1703
        #Tp;
1704
        if (phy_data !== tmp_data)
1705
        begin
1706
          if (i)
1707
            test_fail("Data was not correctly written into OR read from test registers (without preamble)");
1708
          else
1709
            test_fail("Data was not correctly written into OR read from test registers (with preamble)");
1710
          fail = fail + 1;
1711
        end
1712
        @(posedge wb_clk);
1713
        #Tp;
1714 169 mohor
      end
1715
    end
1716 181 mohor
    // set PHY to normal mode
1717
    #Tp eth_phy.test_regs(0);
1718
    #Tp eth_phy.preamble_suppresed(0);
1719
    // MII mode register
1720
    wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1721
    if(fail == 0)
1722
      test_ok;
1723
    else
1724
      fail = 0;
1725 169 mohor
  end
1726
 
1727
 
1728 181 mohor
  ////////////////////////////////////////////////////////////////////
1729
  ////                                                            ////
1730
  ////  Test 'walking one' across phy's register address (with    ////
1731
  ////  and without preamble)                                     ////
1732
  ////                                                            ////
1733
  ////////////////////////////////////////////////////////////////////
1734
  if (test_num == 5) // 
1735 169 mohor
  begin
1736 194 tadej
    // TEST 5: 'WALKING ONE' ACROSS PHY'S REGISTER ADDRESS ( WITH AND WITHOUT PREAMBLE )
1737
    test_name   = "TEST 5: 'WALKING ONE' ACROSS PHY'S REGISTER ADDRESS ( WITH AND WITHOUT PREAMBLE )";
1738
    `TIME; $display("  TEST 5: 'WALKING ONE' ACROSS PHY'S REGISTER ADDRESS ( WITH AND WITHOUT PREAMBLE )");
1739 181 mohor
 
1740
    // set PHY to test mode
1741
    #Tp eth_phy.test_regs(1); // set test registers (wholy writable registers) and respond to all PHY addresses
1742
    for (i = 0; i <= 1; i = i + 1)
1743 169 mohor
    begin
1744 181 mohor
      #Tp eth_phy.preamble_suppresed(i);
1745
      #Tp eth_phy.clear_test_regs;
1746
      // MII mode register
1747
      wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}), 4'hF, 1, wbm_init_waits,
1748
                wbm_subseq_waits);
1749
      // walk one across reg address
1750
      for (reg_addr = 5'h1; reg_addr > 5'h0; reg_addr = reg_addr << 1)
1751 169 mohor
      begin
1752 181 mohor
        phy_addr = $random;
1753
        tmp_data = $random;
1754
        // write request
1755
        #Tp mii_write_req(phy_addr, reg_addr, tmp_data);
1756
        check_mii_busy; // wait for write to finish
1757
        // read request
1758
        #Tp mii_read_req(phy_addr, reg_addr);
1759
        check_mii_busy; // wait for read to finish
1760
        // read data
1761
        #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1762
        #Tp;
1763
        if (phy_data !== tmp_data)
1764
        begin
1765
          if (i)
1766
            test_fail("Data was not correctly written into OR read from test registers (without preamble)");
1767
          else
1768
            test_fail("Data was not correctly written into OR read from test registers (with preamble)");
1769
          fail = fail + 1;
1770
        end
1771
        @(posedge wb_clk);
1772
        #Tp;
1773 169 mohor
      end
1774
    end
1775 181 mohor
    // set PHY to normal mode
1776
    #Tp eth_phy.test_regs(0);
1777
    #Tp eth_phy.preamble_suppresed(0);
1778
    // MII mode register
1779
    wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1780
    if(fail == 0)
1781
      test_ok;
1782
    else
1783
      fail = 0;
1784 169 mohor
  end
1785
 
1786
 
1787 181 mohor
  ////////////////////////////////////////////////////////////////////
1788
  ////                                                            ////
1789
  ////  Test 'walking one' across phy's data (with and without    ////
1790
  ////  preamble)                                                 ////
1791
  ////                                                            ////
1792
  ////////////////////////////////////////////////////////////////////
1793
  if (test_num == 6) // 
1794 169 mohor
  begin
1795 194 tadej
    // TEST 6: 'WALKING ONE' ACROSS PHY'S DATA ( WITH AND WITHOUT PREAMBLE )
1796
    test_name   = "TEST 6: 'WALKING ONE' ACROSS PHY'S DATA ( WITH AND WITHOUT PREAMBLE )";
1797
    `TIME; $display("  TEST 6: 'WALKING ONE' ACROSS PHY'S DATA ( WITH AND WITHOUT PREAMBLE )");
1798 181 mohor
 
1799
    // set PHY to test mode
1800
    #Tp eth_phy.test_regs(1); // set test registers (wholy writable registers) and respond to all PHY addresses
1801
    for (i = 0; i <= 1; i = i + 1)
1802 169 mohor
    begin
1803 181 mohor
      #Tp eth_phy.preamble_suppresed(i);
1804
      #Tp eth_phy.clear_test_regs;
1805
      // MII mode register
1806
      wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}), 4'hF, 1, wbm_init_waits,
1807
                wbm_subseq_waits);
1808
      // walk one across data
1809
      for (tmp_data = 16'h1; tmp_data > 16'h0; tmp_data = tmp_data << 1)
1810 169 mohor
      begin
1811 181 mohor
        phy_addr = $random;
1812
        reg_addr = $random;
1813
        // write request
1814
        #Tp mii_write_req(phy_addr, reg_addr, tmp_data);
1815
        check_mii_busy; // wait for write to finish
1816
        // read request
1817
        #Tp mii_read_req(phy_addr, reg_addr);
1818
        check_mii_busy; // wait for read to finish
1819
        // read data
1820
        #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1821
        #Tp;
1822
        if (phy_data !== tmp_data)
1823
        begin
1824
          if (i)
1825
            test_fail("Data was not correctly written into OR read from test registers (without preamble)");
1826
          else
1827
            test_fail("Data was not correctly written into OR read from test registers (with preamble)");
1828
          fail = fail + 1;
1829
        end
1830
        @(posedge wb_clk);
1831
        #Tp;
1832 169 mohor
      end
1833
    end
1834 181 mohor
    // set PHY to normal mode
1835
    #Tp eth_phy.test_regs(0);
1836
    #Tp eth_phy.preamble_suppresed(0);
1837
    // MII mode register
1838
    wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1839
    if(fail == 0)
1840
      test_ok;
1841
    else
1842
      fail = 0;
1843 169 mohor
  end
1844
 
1845
 
1846 181 mohor
  ////////////////////////////////////////////////////////////////////
1847
  ////                                                            ////
1848
  ////  Test reading from phy with wrong phy address (host        ////
1849
  ////  reading high 'z' data)                                    ////
1850
  ////                                                            ////
1851
  ////////////////////////////////////////////////////////////////////
1852
  if (test_num == 7) // 
1853 169 mohor
  begin
1854 194 tadej
    // TEST 7: READING FROM PHY WITH WRONG PHY ADDRESS ( HOST READING HIGH 'Z' DATA )
1855
    test_name   = "TEST 7: READING FROM PHY WITH WRONG PHY ADDRESS ( HOST READING HIGH 'Z' DATA )";
1856
    `TIME; $display("  TEST 7: READING FROM PHY WITH WRONG PHY ADDRESS ( HOST READING HIGH 'Z' DATA )");
1857 181 mohor
 
1858
    phy_addr = 5'h2; // wrong PHY address
1859
    // read request
1860
    #Tp mii_read_req(phy_addr, reg_addr);
1861
    check_mii_busy; // wait for read to finish
1862
    // read data
1863
    $display("  => Two errors will be displayed from WB Bus Monitor, because correct HIGH Z data was read");
1864
    #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1865
    if (tmp_data !== 16'hzzzz)
1866
    begin
1867
      test_fail("Data was read from PHY register with wrong PHY address - control register");
1868
      fail = fail + 1;
1869
    end
1870
    if(fail == 0)
1871
      test_ok;
1872
    else
1873
      fail = 0;
1874 169 mohor
  end
1875
 
1876
 
1877 181 mohor
  ////////////////////////////////////////////////////////////////////
1878
  ////                                                            ////
1879
  ////  Test writing to phy with wrong phy address and reading    ////
1880
  ////  from correct one                                          ////
1881
  ////                                                            ////
1882
  ////////////////////////////////////////////////////////////////////
1883
  if (test_num == 8) // 
1884 169 mohor
  begin
1885 194 tadej
    // TEST 8: WRITING TO PHY WITH WRONG PHY ADDRESS AND READING FROM CORRECT ONE
1886
    test_name   = "TEST 8: WRITING TO PHY WITH WRONG PHY ADDRESS AND READING FROM CORRECT ONE";
1887
    `TIME; $display("  TEST 8: WRITING TO PHY WITH WRONG PHY ADDRESS AND READING FROM CORRECT ONE");
1888 181 mohor
 
1889
    // set address
1890
    reg_addr = 5'h0; // control register
1891
    phy_addr = 5'h2; // wrong PHY address
1892
    // write request
1893
    phy_data = 16'h7DFF; // bit 15 (RESET bit) and bit 9 are self clearing bits
1894
    #Tp mii_write_req(phy_addr, reg_addr, phy_data);
1895
    check_mii_busy; // wait for write to finish
1896
 
1897
    phy_addr = 5'h1; // correct PHY address
1898
    // read request
1899
    #Tp mii_read_req(phy_addr, reg_addr);
1900
    check_mii_busy; // wait for read to finish
1901
    // read data
1902
    #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1903
    if (phy_data === tmp_data)
1904
    begin
1905
      test_fail("Data was written into PHY register with wrong PHY address - control register");
1906
      fail = fail + 1;
1907
    end
1908
    if(fail == 0)
1909
      test_ok;
1910
    else
1911
      fail = 0;
1912 169 mohor
  end
1913
 
1914
 
1915 181 mohor
  ////////////////////////////////////////////////////////////////////
1916
  ////                                                            ////
1917
  ////  Test sliding stop scan command immediately after read     ////
1918
  ////  request (with and without preamble)                       ////
1919
  ////                                                            ////
1920
  ////////////////////////////////////////////////////////////////////
1921
  if (test_num == 9) // 
1922 169 mohor
  begin
1923 194 tadej
    // TEST 9: SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER READ REQUEST ( WITH AND WITHOUT PREAMBLE )
1924
    test_name = "TEST 9: SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER READ REQUEST ( WITH AND WITHOUT PREAMBLE )";
1925 181 mohor
    `TIME;
1926 194 tadej
    $display("  TEST 9: SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER READ REQUEST ( WITH AND WITHOUT PREAMBLE )");
1927 181 mohor
 
1928
    for (i2 = 0; i2 <= 1; i2 = i2 + 1) // choose preamble or not
1929 169 mohor
    begin
1930 181 mohor
      #Tp eth_phy.preamble_suppresed(i2);
1931
      // MII mode register
1932
      wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i2, 8'h0}), 4'hF, 1, wbm_init_waits,
1933
               wbm_subseq_waits);
1934
      i = 0;
1935
      cnt = 0;
1936
      while (i < 80) // delay for sliding of writing a STOP SCAN command
1937 169 mohor
      begin
1938 181 mohor
        for (i3 = 0; i3 <= 1; i3 = i3 + 1) // choose read or write after read will be finished
1939
        begin
1940
          // set address
1941
          reg_addr = 5'h0; // control register
1942
          phy_addr = 5'h1; // correct PHY address
1943
          cnt = 0;
1944
          // read request
1945
          #Tp mii_read_req(phy_addr, reg_addr);
1946
          fork
1947
            begin
1948
              repeat(i) @(posedge Mdc_O);
1949
              // write command 0x0 into MII command register
1950
              // MII command written while read in progress
1951
              wbm_write(`ETH_MIICOMMAND, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1952
              @(posedge wb_clk);
1953
              #Tp check_mii_busy; // wait for read to finish
1954
            end
1955
            begin
1956
              // wait for serial bus to become active
1957
              wait(Mdio_IO !== 1'bz);
1958
              // count transfer length
1959
              while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
1960
              begin
1961
                @(posedge Mdc_O);
1962
                #Tp cnt = cnt + 1;
1963
              end
1964
            end
1965
          join
1966
          // check transfer length
1967
          if (i2) // without preamble
1968 169 mohor
          begin
1969 181 mohor
            if (cnt != 33) // at this value Mdio_IO is HIGH Z
1970
            begin
1971
              test_fail("Read request did not proceed correctly, while SCAN STOP command was written");
1972
              fail = fail + 1;
1973
            end
1974 169 mohor
          end
1975 181 mohor
          else // with preamble
1976 169 mohor
          begin
1977 181 mohor
            if (cnt != 65) // at this value Mdio_IO is HIGH Z
1978
            begin
1979
              test_fail("Read request did not proceed correctly, while SCAN STOP command was written");
1980
              fail = fail + 1;
1981
            end
1982
          end
1983
          // check the BUSY signal to see if the bus is still IDLE
1984
          for (i1 = 0; i1 < 8; i1 = i1 + 1)
1985
            check_mii_busy; // wait for bus to become idle
1986
 
1987
          // try normal write or read after read was finished
1988
          #Tp phy_data = {8'h7D, (i[7:0] + 1)};
1989
          #Tp cnt = 0;
1990
          if (i3 == 0) // write after read
1991
          begin
1992
            // write request
1993
            #Tp mii_write_req(phy_addr, reg_addr, phy_data);
1994 169 mohor
            // wait for serial bus to become active
1995
            wait(Mdio_IO !== 1'bz);
1996
            // count transfer length
1997 181 mohor
            while(Mdio_IO !== 1'bz)
1998 169 mohor
            begin
1999
              @(posedge Mdc_O);
2000
              #Tp cnt = cnt + 1;
2001
            end
2002 181 mohor
            @(posedge Mdc_O);
2003
            // read request
2004
            #Tp mii_read_req(phy_addr, reg_addr);
2005
            check_mii_busy; // wait for read to finish
2006
            // read and check data
2007
            #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2008
            if (phy_data !== tmp_data)
2009
            begin
2010
              test_fail("Data was not correctly written into OR read from PHY register - control register");
2011
              fail = fail + 1;
2012
            end
2013 169 mohor
          end
2014 181 mohor
          else // read after read
2015 169 mohor
          begin
2016 181 mohor
            // read request
2017
            #Tp mii_read_req(phy_addr, reg_addr);
2018
            // wait for serial bus to become active
2019
            wait(Mdio_IO !== 1'bz);
2020
            // count transfer length
2021
            while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
2022
            begin
2023
              @(posedge Mdc_O);
2024
              #Tp cnt = cnt + 1;
2025
            end
2026 169 mohor
            @(posedge Mdc_O);
2027 181 mohor
            check_mii_busy; // wait for read to finish
2028
            // read and check data
2029
            #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2030
            if (phy_data !== tmp_data)
2031
            begin
2032
              test_fail("Data was not correctly written into OR read from PHY register - control register");
2033
              fail = fail + 1;
2034
            end
2035 169 mohor
          end
2036 181 mohor
          // check if transfer was a proper length
2037
          if (i2) // without preamble
2038 169 mohor
          begin
2039 181 mohor
            if (cnt != 33) // at this value Mdio_IO is HIGH Z
2040
            begin
2041
              test_fail("New request did not proceed correctly, after read request");
2042
              fail = fail + 1;
2043
            end
2044 169 mohor
          end
2045 181 mohor
          else // with preamble
2046 169 mohor
          begin
2047 181 mohor
            if (cnt != 65) // at this value Mdio_IO is HIGH Z
2048
            begin
2049
              test_fail("New request did not proceed correctly, after read request");
2050
              fail = fail + 1;
2051
            end
2052 169 mohor
          end
2053
        end
2054 181 mohor
        #Tp;
2055
        // set delay of writing the command
2056 169 mohor
        if (i2) // without preamble
2057
        begin
2058 181 mohor
          case(i)
2059
            0, 1:               i = i + 1;
2060
            18, 19, 20, 21, 22,
2061
            23, 24, 25, 26, 27,
2062
            28, 29, 30, 31, 32,
2063
            33, 34, 35:         i = i + 1;
2064
            36:                 i = 80;
2065
            default:            i = 18;
2066
          endcase
2067 169 mohor
        end
2068
        else // with preamble
2069
        begin
2070 181 mohor
          case(i)
2071
            0, 1:               i = i + 1;
2072
            50, 51, 52, 53, 54,
2073
            55, 56, 57, 58, 59,
2074
            60, 61, 62, 63, 64,
2075
            65, 66, 67:         i = i + 1;
2076
            68:                 i = 80;
2077
            default:            i = 50;
2078
          endcase
2079 169 mohor
        end
2080 181 mohor
        @(posedge wb_clk);
2081 169 mohor
      end
2082
    end
2083 181 mohor
    // set PHY to normal mode
2084
    #Tp eth_phy.preamble_suppresed(0);
2085
    // MII mode register
2086
    wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2087
    if(fail == 0)
2088
      test_ok;
2089
    else
2090
      fail = 0;
2091 169 mohor
  end
2092
 
2093
 
2094 181 mohor
  ////////////////////////////////////////////////////////////////////
2095
  ////                                                            ////
2096
  ////  Test sliding stop scan command immediately after write    ////
2097
  ////  request (with and without preamble)                       ////
2098
  ////                                                            ////
2099
  ////////////////////////////////////////////////////////////////////
2100
  if (test_num == 10) // 
2101 169 mohor
  begin
2102 194 tadej
    // TEST 10: SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER WRITE REQUEST ( WITH AND WITHOUT PREAMBLE )
2103
    test_name = "TEST 10: SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER WRITE REQUEST ( WITH AND WITHOUT PREAMBLE )";
2104 181 mohor
    `TIME;
2105 194 tadej
    $display("  TEST 10: SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER WRITE REQUEST ( WITH AND WITHOUT PREAMBLE )");
2106 181 mohor
 
2107
    for (i2 = 0; i2 <= 1; i2 = i2 + 1) // choose preamble or not
2108 169 mohor
    begin
2109 181 mohor
      #Tp eth_phy.preamble_suppresed(i2);
2110
      // MII mode register
2111
      wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i2, 8'h0}), 4'hF, 1, wbm_init_waits,
2112
                wbm_subseq_waits);
2113
      i = 0;
2114
      cnt = 0;
2115
      while (i < 80) // delay for sliding of writing a STOP SCAN command
2116 169 mohor
      begin
2117 181 mohor
        for (i3 = 0; i3 <= 1; i3 = i3 + 1) // choose read or write after write will be finished
2118
        begin
2119
          // set address
2120
          reg_addr = 5'h0; // control register
2121
          phy_addr = 5'h1; // correct PHY address
2122
          cnt = 0;
2123
          // write request
2124
          phy_data = {8'h75, (i[7:0] + 1)};
2125
          #Tp mii_write_req(phy_addr, reg_addr, phy_data);
2126
          fork
2127
            begin
2128
              repeat(i) @(posedge Mdc_O);
2129
              // write command 0x0 into MII command register
2130
              // MII command written while read in progress
2131
              wbm_write(`ETH_MIICOMMAND, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2132
              @(posedge wb_clk);
2133
              #Tp check_mii_busy; // wait for write to finish
2134
            end
2135
            begin
2136
              // wait for serial bus to become active
2137
              wait(Mdio_IO !== 1'bz);
2138
              // count transfer length
2139
              while(Mdio_IO !== 1'bz)
2140
              begin
2141
                @(posedge Mdc_O);
2142
                #Tp cnt = cnt + 1;
2143
              end
2144
            end
2145
          join
2146
          // check transfer length
2147
          if (i2) // without preamble
2148 169 mohor
          begin
2149 181 mohor
            if (cnt != 33) // at this value Mdio_IO is HIGH Z
2150
            begin
2151
              test_fail("Write request did not proceed correctly, while SCAN STOP command was written");
2152
              fail = fail + 1;
2153
            end
2154 169 mohor
          end
2155 181 mohor
          else // with preamble
2156 169 mohor
          begin
2157 181 mohor
            if (cnt != 65) // at this value Mdio_IO is HIGH Z
2158
            begin
2159
              test_fail("Write request did not proceed correctly, while SCAN STOP command was written");
2160
              fail = fail + 1;
2161
            end
2162
          end
2163
          // check the BUSY signal to see if the bus is still IDLE
2164
          for (i1 = 0; i1 < 8; i1 = i1 + 1)
2165
            check_mii_busy; // wait for bus to become idle
2166
 
2167
          // try normal write or read after write was finished
2168
          #Tp cnt = 0;
2169
          if (i3 == 0) // write after write
2170
          begin
2171
            phy_data = {8'h7A, (i[7:0] + 1)};
2172
            // write request
2173
            #Tp mii_write_req(phy_addr, reg_addr, phy_data);
2174 169 mohor
            // wait for serial bus to become active
2175
            wait(Mdio_IO !== 1'bz);
2176
            // count transfer length
2177
            while(Mdio_IO !== 1'bz)
2178
            begin
2179
              @(posedge Mdc_O);
2180
              #Tp cnt = cnt + 1;
2181
            end
2182 181 mohor
            @(posedge Mdc_O);
2183
            // read request
2184
            #Tp mii_read_req(phy_addr, reg_addr);
2185
            check_mii_busy; // wait for read to finish
2186
            // read and check data
2187
            #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data , 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2188
            if (phy_data !== tmp_data)
2189
            begin
2190
              test_fail("Data was not correctly written into OR read from PHY register - control register");
2191
              fail = fail + 1;
2192
            end
2193 169 mohor
          end
2194 181 mohor
          else // read after write
2195 169 mohor
          begin
2196 181 mohor
            // read request
2197
            #Tp mii_read_req(phy_addr, reg_addr);
2198
            // wait for serial bus to become active
2199
            wait(Mdio_IO !== 1'bz);
2200
            // count transfer length
2201
            while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
2202
            begin
2203
              @(posedge Mdc_O);
2204
              #Tp cnt = cnt + 1;
2205
            end
2206 169 mohor
            @(posedge Mdc_O);
2207 181 mohor
            check_mii_busy; // wait for read to finish
2208
            // read and check data
2209
            #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data , 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2210
            if (phy_data !== tmp_data)
2211
            begin
2212
              test_fail("Data was not correctly written into OR read from PHY register - control register");
2213
              fail = fail + 1;
2214
            end
2215 169 mohor
          end
2216 181 mohor
          // check if transfer was a proper length
2217
          if (i2) // without preamble
2218 169 mohor
          begin
2219 181 mohor
            if (cnt != 33) // at this value Mdio_IO is HIGH Z
2220
            begin
2221
              test_fail("New request did not proceed correctly, after write request");
2222
              fail = fail + 1;
2223
            end
2224 169 mohor
          end
2225 181 mohor
          else // with preamble
2226 169 mohor
          begin
2227 181 mohor
            if (cnt != 65) // at this value Mdio_IO is HIGH Z
2228
            begin
2229
              test_fail("New request did not proceed correctly, after write request");
2230
              fail = fail + 1;
2231
            end
2232 169 mohor
          end
2233
        end
2234 181 mohor
        #Tp;
2235
        // set delay of writing the command
2236 169 mohor
        if (i2) // without preamble
2237
        begin
2238 181 mohor
          case(i)
2239
            0, 1:               i = i + 1;
2240
            18, 19, 20, 21, 22,
2241
            23, 24, 25, 26, 27,
2242
            28, 29, 30, 31, 32,
2243
            33, 34, 35:         i = i + 1;
2244
            36:                 i = 80;
2245
            default:            i = 18;
2246
          endcase
2247 169 mohor
        end
2248
        else // with preamble
2249
        begin
2250 181 mohor
          case(i)
2251
            0, 1:               i = i + 1;
2252
            50, 51, 52, 53, 54,
2253
            55, 56, 57, 58, 59,
2254
            60, 61, 62, 63, 64,
2255
            65, 66, 67:         i = i + 1;
2256
            68:                 i = 80;
2257
            default:            i = 50;
2258
          endcase
2259 169 mohor
        end
2260 181 mohor
        @(posedge wb_clk);
2261 169 mohor
      end
2262
    end
2263 181 mohor
    // set PHY to normal mode
2264
    #Tp eth_phy.preamble_suppresed(0);
2265
    // MII mode register
2266
    wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2267
    if(fail == 0)
2268
      test_ok;
2269
    else
2270
      fail = 0;
2271 169 mohor
  end
2272
 
2273
 
2274 181 mohor
  ////////////////////////////////////////////////////////////////////
2275
  ////                                                            ////
2276
  ////  Test busy and nvalid status durations during write (with  ////
2277
  ////  and without preamble)                                     ////
2278
  ////                                                            ////
2279
  ////////////////////////////////////////////////////////////////////
2280
  if (test_num == 11) // 
2281 169 mohor
  begin
2282 194 tadej
    // TEST 11: BUSY AND NVALID STATUS DURATIONS DURING WRITE ( WITH AND WITHOUT PREAMBLE )
2283
    test_name   = "TEST 11: BUSY AND NVALID STATUS DURATIONS DURING WRITE ( WITH AND WITHOUT PREAMBLE )";
2284
    `TIME; $display("  TEST 11: BUSY AND NVALID STATUS DURATIONS DURING WRITE ( WITH AND WITHOUT PREAMBLE )");
2285 181 mohor
 
2286
    reset_mii; // reset MII
2287
    // set link up, if it wasn't due to previous tests, since there weren't PHY registers
2288
    #Tp eth_phy.link_up_down(1);
2289
    // set the MII
2290
    clk_div = 64;
2291
    mii_set_clk_div(clk_div[7:0]);
2292
    // set address
2293
    reg_addr = 5'h1; // status register
2294
    phy_addr = 5'h1; // correct PHY address
2295
 
2296
    for (i = 0; i <= 1; i = i + 1)
2297 169 mohor
    begin
2298 181 mohor
      #Tp eth_phy.preamble_suppresed(i);
2299
      // MII mode register
2300
      wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}) | (`ETH_MIIMODER_CLKDIV & clk_div),
2301
                4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2302
      @(posedge Mdc_O);
2303
      // write request
2304
      #Tp mii_write_req(phy_addr, reg_addr, 16'h5A5A);
2305
      // read data from MII status register - Busy and Nvalid bits
2306
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2307
 
2308
      // check MII IO signal and Busy and Nvalid bits
2309
      if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
2310 169 mohor
      begin
2311 181 mohor
        test_fail("Testbench error - read was to late, Mdio_IO is not HIGH Z - set higher clock divider");
2312
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2313
        begin
2314
          test_fail("Busy signal was not set while MII IO signal is not HIGH Z anymore - 1. read");
2315
          fail = fail + 1;
2316
        end
2317
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2318
        begin
2319
          test_fail("Nvalid signal was set during write");
2320
          fail = fail + 1;
2321
        end
2322 169 mohor
      end
2323 181 mohor
      else // Busy bit should already be set to '1', due to reads from MII status register
2324 169 mohor
      begin
2325 181 mohor
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2326
        begin
2327
          test_fail("Busy signal should be set after write, due to reads from MII status register");
2328
          fail = fail + 1;
2329
        end
2330
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2331
        begin
2332
          test_fail("Nvalid signal was set during write");
2333
          fail = fail + 1;
2334
        end
2335 169 mohor
      end
2336 181 mohor
 
2337
      // wait for serial bus to become active
2338
      wait(Mdio_IO !== 1'bz);
2339
      // count transfer bits
2340
      if (i)
2341 169 mohor
      begin
2342 181 mohor
        repeat(32) @(posedge Mdc_O);
2343 169 mohor
      end
2344 181 mohor
      else
2345 169 mohor
      begin
2346 181 mohor
        repeat(64) @(posedge Mdc_O);
2347 169 mohor
      end
2348 181 mohor
      // read data from MII status register - Busy and Nvalid bits
2349
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2350
 
2351
      // check MII IO signal and Busy and Nvalid bits
2352
      if (Mdio_IO === 1'bz) // Mdio_IO should not be HIGH Z here - testbench selfcheck
2353 169 mohor
      begin
2354 181 mohor
        test_fail("Testbench error - read was to late, Mdio_IO is HIGH Z - set higher clock divider");
2355
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2356
        begin
2357
          test_fail("Busy signal should be set while MII IO signal is not active anymore");
2358
          fail = fail + 1;
2359
        end
2360
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2361
        begin
2362
          test_fail("Nvalid signal was set during write");
2363
          fail = fail + 1;
2364
        end
2365 169 mohor
      end
2366 181 mohor
      else // Busy bit should still be set to '1'
2367 169 mohor
      begin
2368 181 mohor
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2369
        begin
2370
          test_fail("Busy signal should be set while MII IO signal not HIGH Z");
2371
          fail = fail + 1;
2372
        end
2373
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2374
        begin
2375
          test_fail("Nvalid signal was set during write");
2376
          fail = fail + 1;
2377
        end
2378 169 mohor
      end
2379 181 mohor
 
2380
      // wait for next negative clock edge
2381
      @(negedge Mdc_O);
2382 169 mohor
      // read data from MII status register - Busy and Nvalid bits
2383
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2384 181 mohor
 
2385 169 mohor
      // check MII IO signal and Busy and Nvalid bits
2386
      if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
2387
      begin
2388
        test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider");
2389
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2390
        begin
2391
          test_fail("Busy signal was not set while MII IO signal is not HIGH Z");
2392
          fail = fail + 1;
2393
        end
2394
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2395
        begin
2396
          test_fail("Nvalid signal was set during write");
2397
          fail = fail + 1;
2398
        end
2399
      end
2400 181 mohor
      else // Busy bit should still be set to '1'
2401 169 mohor
      begin
2402
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2403
        begin
2404 181 mohor
          test_fail("Busy signal should be set after MII IO signal become HIGH Z");
2405
          fail = fail + 1;
2406 169 mohor
        end
2407 181 mohor
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2408 169 mohor
        begin
2409 181 mohor
          test_fail("Nvalid signal was set during write");
2410
          fail = fail + 1;
2411
        end
2412
      end
2413
 
2414
      // wait for Busy to become inactive
2415
      i1 = 0;
2416
      while (i1 <= 2)
2417
      begin
2418
        // wait for next positive clock edge
2419
        @(posedge Mdc_O);
2420
        // read data from MII status register - Busy and Nvalid bits
2421
        #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2422
 
2423
        // check MII IO signal and Busy and Nvalid bits
2424
        if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
2425
        begin
2426
          test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider");
2427
          if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2428 169 mohor
          begin
2429 181 mohor
            test_fail("Busy signal was not set while MII IO signal is not HIGH Z");
2430 169 mohor
            fail = fail + 1;
2431
          end
2432 181 mohor
          if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2433
          begin
2434
            test_fail("Nvalid signal was set during write");
2435
            fail = fail + 1;
2436
          end
2437 169 mohor
        end
2438 181 mohor
        else // wait for Busy bit to be set to '0'
2439 169 mohor
        begin
2440 181 mohor
          if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2441
          begin
2442
            i1 = 3; // end of Busy checking
2443
          end
2444
          else
2445
          begin
2446
            if (i1 == 2)
2447
            begin
2448
              test_fail("Busy signal should be cleared after 2 periods after MII IO signal become HIGH Z");
2449
              fail = fail + 1;
2450
            end
2451
            #Tp i1 = i1 + 1;
2452
          end
2453
          if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2454
          begin
2455
            test_fail("Nvalid signal was set after write");
2456
            fail = fail + 1;
2457
          end
2458 169 mohor
        end
2459
      end
2460
    end
2461 181 mohor
    // set PHY to normal mode
2462
    #Tp eth_phy.preamble_suppresed(0);
2463
    // MII mode register
2464
    wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2465
    if(fail == 0)
2466
      test_ok;
2467
    else
2468
      fail = 0;
2469 116 mohor
  end
2470
 
2471
 
2472 181 mohor
  ////////////////////////////////////////////////////////////////////
2473
  ////                                                            ////
2474
  ////  Test busy and nvalid status durations during write (with  ////
2475
  ////  and without preamble)                                     ////
2476
  ////                                                            ////
2477
  ////////////////////////////////////////////////////////////////////
2478
  if (test_num == 12) // 
2479 169 mohor
  begin
2480 194 tadej
    // TEST 12: BUSY AND NVALID STATUS DURATIONS DURING READ ( WITH AND WITHOUT PREAMBLE )
2481
    test_name   = "TEST 12: BUSY AND NVALID STATUS DURATIONS DURING READ ( WITH AND WITHOUT PREAMBLE )";
2482
    `TIME; $display("  TEST 12: BUSY AND NVALID STATUS DURATIONS DURING READ ( WITH AND WITHOUT PREAMBLE )");
2483 181 mohor
 
2484
    reset_mii; // reset MII
2485
    // set link up, if it wasn't due to previous tests, since there weren't PHY registers
2486
    #Tp eth_phy.link_up_down(1);
2487
    // set the MII
2488
    clk_div = 64;
2489
    mii_set_clk_div(clk_div[7:0]);
2490
    // set address
2491
    reg_addr = 5'h1; // status register
2492
    phy_addr = 5'h1; // correct PHY address
2493
 
2494
    for (i = 0; i <= 1; i = i + 1)
2495 169 mohor
    begin
2496 181 mohor
      #Tp eth_phy.preamble_suppresed(i);
2497
      // MII mode register
2498
      wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}) | (`ETH_MIIMODER_CLKDIV & clk_div),
2499
                4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2500 169 mohor
      @(posedge Mdc_O);
2501 181 mohor
      // read request
2502
      #Tp mii_read_req(phy_addr, reg_addr);
2503 169 mohor
      // read data from MII status register - Busy and Nvalid bits
2504
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2505 181 mohor
 
2506 169 mohor
      // check MII IO signal and Busy and Nvalid bits
2507
      if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
2508
      begin
2509 181 mohor
        test_fail("Testbench error - read was to late, Mdio_IO is not HIGH Z - set higher clock divider");
2510 169 mohor
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2511
        begin
2512 181 mohor
          test_fail("Busy signal was not set while MII IO signal is not HIGH Z anymore - 1. read");
2513 169 mohor
          fail = fail + 1;
2514
        end
2515
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2516
        begin
2517
          test_fail("Nvalid signal was set during read");
2518
          fail = fail + 1;
2519
        end
2520
      end
2521 181 mohor
      else // Busy bit should already be set to '1', due to reads from MII status register
2522 169 mohor
      begin
2523
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2524
        begin
2525 181 mohor
          test_fail("Busy signal should be set after read, due to reads from MII status register");
2526
          fail = fail + 1;
2527 169 mohor
        end
2528
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2529
        begin
2530 181 mohor
          test_fail("Nvalid signal was set during read");
2531 169 mohor
          fail = fail + 1;
2532
        end
2533
      end
2534 181 mohor
 
2535
      // wait for serial bus to become active
2536
      wait(Mdio_IO !== 1'bz);
2537
      // count transfer bits
2538
      if (i)
2539 169 mohor
      begin
2540 181 mohor
        repeat(31) @(posedge Mdc_O);
2541 169 mohor
      end
2542 181 mohor
      else
2543 169 mohor
      begin
2544 181 mohor
        repeat(63) @(posedge Mdc_O);
2545 169 mohor
      end
2546 181 mohor
      // wait for next negative clock edge
2547
      @(negedge Mdc_O);
2548
      // read data from MII status register - Busy and Nvalid bits
2549
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2550
 
2551
      // check MII IO signal and Busy and Nvalid bits
2552
      if (Mdio_IO === 1'bz) // Mdio_IO should not be HIGH Z here - testbench selfcheck
2553 169 mohor
      begin
2554 181 mohor
        test_fail("Testbench error - read was to late, Mdio_IO is HIGH Z - set higher clock divider");
2555
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2556
        begin
2557
          test_fail("Busy signal should be set while MII IO signal is not active anymore");
2558
          fail = fail + 1;
2559
        end
2560
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2561
        begin
2562
          test_fail("Nvalid signal was set during read");
2563
          fail = fail + 1;
2564
        end
2565 169 mohor
      end
2566 181 mohor
      else // Busy bit should still be set to '1'
2567 169 mohor
      begin
2568 181 mohor
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2569
        begin
2570
          test_fail("Busy signal should be set while MII IO signal not HIGH Z");
2571
          fail = fail + 1;
2572
        end
2573
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2574
        begin
2575
          test_fail("Nvalid signal was set during read");
2576
          fail = fail + 1;
2577
        end
2578 169 mohor
      end
2579 181 mohor
 
2580 169 mohor
      // wait for next positive clock edge
2581
      @(posedge Mdc_O);
2582
      // read data from MII status register - Busy and Nvalid bits
2583
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2584 181 mohor
 
2585 169 mohor
      // check MII IO signal and Busy and Nvalid bits
2586
      if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
2587
      begin
2588
        test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider");
2589 181 mohor
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2590 169 mohor
        begin
2591 181 mohor
          test_fail("Busy signal was not set while MII IO signal is not HIGH Z");
2592
          fail = fail + 1;
2593
        end
2594
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2595
        begin
2596
          test_fail("Nvalid signal was set during read");
2597
          fail = fail + 1;
2598
        end
2599
      end
2600
      else // Busy bit should still be set to '1'
2601
      begin
2602
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2603
        begin
2604
          test_fail("Busy signal should be set after MII IO signal become HIGH Z");
2605
          fail = fail + 1;
2606
        end
2607
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2608
        begin
2609
          test_fail("Nvalid signal was set during read");
2610
          fail = fail + 1;
2611
        end
2612
      end
2613
 
2614
      // wait for Busy to become inactive
2615
      i1 = 0;
2616
      while (i1 <= 2)
2617
      begin
2618
        // wait for next positive clock edge
2619
        @(posedge Mdc_O);
2620
        // read data from MII status register - Busy and Nvalid bits
2621
        #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2622
 
2623
        // check MII IO signal and Busy and Nvalid bits
2624
        if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
2625
        begin
2626
          test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider");
2627 169 mohor
          if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2628
          begin
2629
            test_fail("Busy signal was not set while MII IO signal is not HIGH Z");
2630
            fail = fail + 1;
2631
          end
2632 181 mohor
          if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2633 169 mohor
          begin
2634 181 mohor
            test_fail("Nvalid signal was set during read");
2635 169 mohor
            fail = fail + 1;
2636
          end
2637
        end
2638 181 mohor
        else // wait for Busy bit to be set to '0'
2639 169 mohor
        begin
2640
          if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2641
          begin
2642
            i1 = 3; // end of Busy checking
2643
          end
2644
          else
2645
          begin
2646
            if (i1 == 2)
2647
            begin
2648
              test_fail("Busy signal should be cleared after 2 periods after MII IO signal become HIGH Z");
2649
              fail = fail + 1;
2650
            end
2651
            #Tp i1 = i1 + 1;
2652
          end
2653 181 mohor
          if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
2654 169 mohor
          begin
2655 181 mohor
            test_fail("Nvalid signal was set after read");
2656 169 mohor
            fail = fail + 1;
2657
          end
2658
        end
2659
      end
2660
    end
2661 181 mohor
    // set PHY to normal mode
2662
    #Tp eth_phy.preamble_suppresed(0);
2663
    // MII mode register
2664
    wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2665
    if(fail == 0)
2666
      test_ok;
2667
    else
2668
      fail = 0;
2669 169 mohor
  end
2670
 
2671
 
2672 181 mohor
  ////////////////////////////////////////////////////////////////////
2673
  ////                                                            ////
2674
  ////  Test busy and nvalid status durations during scan (with   ////
2675
  ////  and without preamble)                                     ////
2676
  ////                                                            ////
2677
  ////////////////////////////////////////////////////////////////////
2678
  if (test_num == 13) // 
2679 169 mohor
  begin
2680 194 tadej
    // TEST 13: BUSY AND NVALID STATUS DURATIONS DURING SCAN ( WITH AND WITHOUT PREAMBLE )
2681
    test_name   = "TEST 13: BUSY AND NVALID STATUS DURATIONS DURING SCAN ( WITH AND WITHOUT PREAMBLE )";
2682
    `TIME; $display("  TEST 13: BUSY AND NVALID STATUS DURATIONS DURING SCAN ( WITH AND WITHOUT PREAMBLE )");
2683 181 mohor
 
2684
    reset_mii; // reset MII
2685
    // set link up, if it wasn't due to previous tests, since there weren't PHY registers
2686
    #Tp eth_phy.link_up_down(1);
2687
    // set the MII
2688
    clk_div = 64;
2689
    mii_set_clk_div(clk_div[7:0]);
2690
    // set address
2691
    reg_addr = 5'h1; // status register
2692
    phy_addr = 5'h1; // correct PHY address
2693
 
2694
    for (i = 0; i <= 1; i = i + 1)
2695 169 mohor
    begin
2696 181 mohor
      #Tp eth_phy.preamble_suppresed(i);
2697
      // MII mode register
2698
      wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}) | (`ETH_MIIMODER_CLKDIV & clk_div),
2699
                4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2700
      @(posedge Mdc_O);
2701
      // scan request
2702
      #Tp mii_scan_req(phy_addr, reg_addr);
2703
      // read data from MII status register - Busy and Nvalid bits
2704
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2705
 
2706
      // check MII IO signal and Busy and Nvalid bits
2707
      if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
2708 169 mohor
      begin
2709 181 mohor
        test_fail("Testbench error - read was to late, Mdio_IO is not HIGH Z - set higher clock divider");
2710
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2711
        begin
2712
          test_fail("Busy signal was not set while MII IO signal is not HIGH Z anymore - 1. read");
2713
          fail = fail + 1;
2714
        end
2715
        if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
2716
        begin
2717
          test_fail("Nvalid signal was not set while MII IO signal is not HIGH Z anymore - 1. read");
2718
          fail = fail + 1;
2719
        end
2720 169 mohor
      end
2721 181 mohor
      else // Busy bit should already be set to '1', due to reads from MII status register
2722 169 mohor
      begin
2723 181 mohor
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2724
        begin
2725
          test_fail("Busy signal should be set after scan, due to reads from MII status register");
2726
          fail = fail + 1;
2727
        end
2728
        if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
2729
        begin
2730
          test_fail("Nvalid signal should be set after scan, due to reads from MII status register");
2731
          fail = fail + 1;
2732
        end
2733 169 mohor
      end
2734 181 mohor
 
2735
      // wait for serial bus to become active
2736 169 mohor
      wait(Mdio_IO !== 1'bz);
2737 181 mohor
      // count transfer bits
2738
      if (i)
2739 169 mohor
      begin
2740 181 mohor
        repeat(21) @(posedge Mdc_O);
2741 169 mohor
      end
2742 181 mohor
      else
2743 169 mohor
      begin
2744 181 mohor
        repeat(53) @(posedge Mdc_O);
2745 169 mohor
      end
2746 181 mohor
      // stop scan
2747
      #Tp mii_scan_finish; // finish scan operation
2748
 
2749
      // wait for next positive clock edge
2750
      repeat(10) @(posedge Mdc_O);
2751
      // read data from MII status register - Busy and Nvalid bits
2752
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2753
 
2754
      // check MII IO signal and Busy and Nvalid bits
2755
      if (Mdio_IO === 1'bz) // Mdio_IO should not be HIGH Z here - testbench selfcheck
2756 169 mohor
      begin
2757 181 mohor
        test_fail("Testbench error - read was to late, Mdio_IO is HIGH Z - set higher clock divider");
2758
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2759 169 mohor
        begin
2760 181 mohor
          test_fail("Busy signal should be set while MII IO signal is not active anymore");
2761 169 mohor
          fail = fail + 1;
2762
        end
2763 181 mohor
        // Nvalid signal can be cleared here - it is still Testbench error
2764 169 mohor
      end
2765 181 mohor
      else // Busy bit should still be set to '1', Nvalid bit should still be set to '1'
2766 169 mohor
      begin
2767 181 mohor
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2768 169 mohor
        begin
2769 181 mohor
          test_fail("Busy signal should be set while MII IO signal not HIGH Z");
2770 169 mohor
          fail = fail + 1;
2771
        end
2772 181 mohor
        if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
2773 169 mohor
        begin
2774 181 mohor
          test_fail("Nvalid signal should be set while MII IO signal not HIGH Z");
2775 169 mohor
          fail = fail + 1;
2776
        end
2777 181 mohor
      end
2778
 
2779
      // wait for next negative clock edge
2780
      @(negedge Mdc_O);
2781
      // read data from MII status register - Busy and Nvalid bits
2782
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2783
 
2784
      // check MII IO signal and Busy and Nvalid bits
2785
      if (Mdio_IO === 1'bz) // Mdio_IO should not be HIGH Z here - testbench selfcheck
2786
      begin
2787
        test_fail("Testbench error - read was to late, Mdio_IO is HIGH Z - set higher clock divider");
2788
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2789 169 mohor
        begin
2790 181 mohor
          test_fail("Busy signal should be set while MII IO signal is not active anymore");
2791
          fail = fail + 1;
2792 169 mohor
        end
2793 181 mohor
        // Nvalid signal can be cleared here - it is still Testbench error
2794 169 mohor
      end
2795 181 mohor
      else // Busy bit should still be set to '1', Nvalid bit should still be set to '1'
2796 169 mohor
      begin
2797 181 mohor
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2798 169 mohor
        begin
2799 181 mohor
          test_fail("Busy signal should be set while MII IO signal not HIGH Z");
2800
          fail = fail + 1;
2801 169 mohor
        end
2802 181 mohor
        if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
2803 169 mohor
        begin
2804 181 mohor
          test_fail("Nvalid signal should be set while MII IO signal not HIGH Z");
2805
          fail = fail + 1;
2806 169 mohor
        end
2807
      end
2808 181 mohor
 
2809
      // wait for next negative clock edge
2810
      @(posedge Mdc_O);
2811
      // read data from MII status register - Busy and Nvalid bits
2812 169 mohor
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2813 181 mohor
 
2814
      // check MII IO signal and Busy and Nvalid bits
2815
      if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
2816 169 mohor
      begin
2817 181 mohor
        test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider");
2818
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2819 169 mohor
        begin
2820 181 mohor
          test_fail("Busy signal was not set while MII IO signal is not HIGH Z");
2821 169 mohor
          fail = fail + 1;
2822
        end
2823 181 mohor
        if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
2824 169 mohor
        begin
2825 181 mohor
          test_fail("Nvalid signal was not set while MII IO signal is not HIGH Z");
2826 169 mohor
          fail = fail + 1;
2827
        end
2828
      end
2829 181 mohor
      else // Busy bit should still be set to '1', Nvalid bit can be set to '0'
2830 169 mohor
      begin
2831 181 mohor
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2832 169 mohor
        begin
2833 181 mohor
          test_fail("Busy signal should be set after MII IO signal become HIGH Z");
2834
          fail = fail + 1;
2835 169 mohor
        end
2836 181 mohor
        if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
2837 169 mohor
        begin
2838 181 mohor
          i2 = 1; // check finished
2839 169 mohor
        end
2840 181 mohor
        else
2841 169 mohor
        begin
2842 181 mohor
          i2 = 0; // check must continue
2843 169 mohor
        end
2844
      end
2845 181 mohor
 
2846
      // wait for Busy to become inactive
2847
      i1 = 0;
2848
      while ((i1 <= 2) || (i2 == 0))
2849
      begin
2850
        // wait for next positive clock edge
2851
        @(posedge Mdc_O);
2852
        // read data from MII status register - Busy and Nvalid bits
2853
        #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2854
 
2855
        // check MII IO signal and Busy and Nvalid bits
2856
        if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
2857 169 mohor
        begin
2858 181 mohor
          test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider");
2859
          if (i1 <= 2)
2860 169 mohor
          begin
2861 181 mohor
            if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2862 169 mohor
            begin
2863 181 mohor
              test_fail("Busy signal was not set while MII IO signal is not HIGH Z");
2864 169 mohor
              fail = fail + 1;
2865
            end
2866
          end
2867 181 mohor
          if (i2 == 0)
2868 169 mohor
          begin
2869 181 mohor
            if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
2870 169 mohor
            begin
2871 181 mohor
              test_fail("Nvalid signal was not set while MII IO signal is not HIGH Z");
2872 169 mohor
              fail = fail + 1;
2873
            end
2874
          end
2875
        end
2876 181 mohor
        else // wait for Busy bit to be set to '0'
2877 169 mohor
        begin
2878 181 mohor
          if (i1 <= 2)
2879 169 mohor
          begin
2880 181 mohor
            if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
2881 169 mohor
            begin
2882 181 mohor
              i1 = 3; // end of Busy checking
2883 169 mohor
            end
2884 181 mohor
            else
2885 169 mohor
            begin
2886 181 mohor
              if (i1 == 2)
2887 169 mohor
              begin
2888 181 mohor
                test_fail("Busy signal should be cleared after 2 periods after MII IO signal become HIGH Z");
2889 169 mohor
                fail = fail + 1;
2890
              end
2891 181 mohor
              #Tp i1 = i1 + 1;
2892 169 mohor
            end
2893 181 mohor
          end
2894
          if (i2 == 0)
2895
          begin
2896
            if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
2897 169 mohor
            begin
2898 181 mohor
              i2 = 1;
2899 169 mohor
            end
2900 181 mohor
            else
2901
            begin
2902
              test_fail("Nvalid signal should be cleared after MII IO signal become HIGH Z");
2903
              fail = fail + 1;
2904
            end
2905 169 mohor
          end
2906
        end
2907 181 mohor
      end
2908
    end
2909
    // set PHY to normal mode
2910
    #Tp eth_phy.preamble_suppresed(0);
2911
    // MII mode register
2912
    wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2913
    if(fail == 0)
2914
      test_ok;
2915
    else
2916
      fail = 0;
2917
  end
2918
 
2919
 
2920
  ////////////////////////////////////////////////////////////////////
2921
  ////                                                            ////
2922
  ////  Test scan status from phy with detecting link-fail bit    ////
2923
  ////  (with and without preamble)                               ////
2924
  ////                                                            ////
2925
  ////////////////////////////////////////////////////////////////////
2926
  if (test_num == 14) // 
2927
  begin
2928 194 tadej
    // TEST 14: SCAN STATUS FROM PHY WITH DETECTING LINK-FAIL BIT ( WITH AND WITHOUT PREAMBLE )
2929
    test_name   = "TEST 14: SCAN STATUS FROM PHY WITH DETECTING LINK-FAIL BIT ( WITH AND WITHOUT PREAMBLE )";
2930
    `TIME; $display("  TEST 14: SCAN STATUS FROM PHY WITH DETECTING LINK-FAIL BIT ( WITH AND WITHOUT PREAMBLE )");
2931 181 mohor
 
2932
    reset_mii; // reset MII
2933
    // set link up, if it wasn't due to previous tests, since there weren't PHY registers
2934
    #Tp eth_phy.link_up_down(1);
2935
    // set MII speed
2936
    clk_div = 6;
2937
    mii_set_clk_div(clk_div[7:0]);
2938
    // set address
2939
    reg_addr = 5'h1; // status register
2940
    phy_addr = 5'h1; // correct PHY address
2941
 
2942
    // read request
2943
    #Tp mii_read_req(phy_addr, reg_addr);
2944
    check_mii_busy; // wait for read to finish
2945
    // read data from PHY status register - remember LINK-UP status
2946
    #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2947
 
2948
    for (i = 0; i <= 1; i = i + 1)
2949
    begin
2950
      #Tp eth_phy.preamble_suppresed(i);
2951
      // MII mode register
2952
      wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}) | (`ETH_MIIMODER_CLKDIV & clk_div),
2953
                4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2954
      if (i)
2955
      begin
2956
        // change saved data when preamble is suppressed
2957
        #Tp tmp_data = tmp_data | 16'h0040; // put bit 6 to ONE
2958
      end
2959
 
2960
      // scan request
2961
      #Tp mii_scan_req(phy_addr, reg_addr);
2962
      check_mii_scan_valid; // wait for scan to make first data valid
2963
 
2964 169 mohor
      fork
2965 181 mohor
      begin
2966 169 mohor
        repeat(2) @(posedge Mdc_O);
2967
        // read data from PHY status register
2968
        #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2969 181 mohor
        if (phy_data !== tmp_data)
2970 169 mohor
        begin
2971 181 mohor
          test_fail("Data was not correctly scaned from status register");
2972 169 mohor
          fail = fail + 1;
2973
        end
2974
        // read data from MII status register
2975
        #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2976 181 mohor
        if (phy_data[0] !== 1'b0)
2977 169 mohor
        begin
2978 181 mohor
          test_fail("Link FAIL bit was set in the MII status register");
2979 169 mohor
          fail = fail + 1;
2980
        end
2981
      end
2982
      begin
2983 181 mohor
      // Completely check second scan
2984 169 mohor
        #Tp cnt = 0;
2985
        // wait for serial bus to become active - second scan
2986
        wait(Mdio_IO !== 1'bz);
2987
        // count transfer length
2988 181 mohor
        while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i == 0)) || ((cnt == 15) && (i == 1)) )
2989 169 mohor
        begin
2990
          @(posedge Mdc_O);
2991
          #Tp cnt = cnt + 1;
2992
        end
2993
        // check transfer length
2994 181 mohor
        if (i) // without preamble
2995 169 mohor
        begin
2996
          if (cnt != 33) // at this value Mdio_IO is HIGH Z
2997
          begin
2998 181 mohor
            test_fail("Second scan request did not proceed correctly");
2999 169 mohor
            fail = fail + 1;
3000
          end
3001
        end
3002
        else // with preamble
3003
        begin
3004
          if (cnt != 65) // at this value Mdio_IO is HIGH Z
3005
          begin
3006 181 mohor
            test_fail("Second scan request did not proceed correctly");
3007 169 mohor
            fail = fail + 1;
3008
          end
3009
        end
3010
      end
3011
      join
3012 181 mohor
      // check third to fifth scans
3013
      for (i3 = 0; i3 <= 2; i3 = i3 + 1)
3014
      begin
3015
        fork
3016 169 mohor
        begin
3017
          repeat(2) @(posedge Mdc_O);
3018
          // read data from PHY status register
3019
          #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3020 181 mohor
          if (phy_data !== tmp_data)
3021 169 mohor
          begin
3022 181 mohor
            test_fail("Data was not correctly scaned from status register");
3023
            fail = fail + 1;
3024 169 mohor
          end
3025
          // read data from MII status register
3026
          #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3027 181 mohor
          if (phy_data[0] !== 1'b0)
3028 169 mohor
          begin
3029 181 mohor
            test_fail("Link FAIL bit was set in the MII status register");
3030
            fail = fail + 1;
3031 169 mohor
          end
3032 181 mohor
          if (i3 == 2) // after fourth scan read
3033 169 mohor
          begin
3034 181 mohor
            @(posedge Mdc_O);
3035
            // change saved data
3036
            #Tp tmp_data = tmp_data & 16'hFFFB; // put bit 3 to ZERO
3037
            // set link down
3038
            #Tp eth_phy.link_up_down(0);
3039 169 mohor
          end
3040
        end
3041
        begin
3042 181 mohor
        // Completely check scans
3043
          #Tp cnt = 0;
3044
          // wait for serial bus to become active - second scan
3045
          wait(Mdio_IO !== 1'bz);
3046
          // count transfer length
3047
          while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i == 0)) || ((cnt == 15) && (i == 1)) )
3048 169 mohor
          begin
3049 181 mohor
            @(posedge Mdc_O);
3050
            #Tp cnt = cnt + 1;
3051
          end
3052
          // check transfer length
3053
          if (i) // without preamble
3054
          begin
3055
            if (cnt != 33) // at this value Mdio_IO is HIGH Z
3056 169 mohor
            begin
3057 181 mohor
              test_fail("Fifth scan request did not proceed correctly");
3058
              fail = fail + 1;
3059 169 mohor
            end
3060 181 mohor
          end
3061
          else // with preamble
3062
          begin
3063
            if (cnt != 65) // at this value Mdio_IO is HIGH Z
3064 169 mohor
            begin
3065 181 mohor
              test_fail("Fifth scan request did not proceed correctly");
3066
              fail = fail + 1;
3067 169 mohor
            end
3068
          end
3069
        end
3070 181 mohor
        join
3071
      end
3072
 
3073
      fork
3074
      begin
3075
        repeat(2) @(posedge Mdc_O);
3076
        // read data from PHY status register
3077
        #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3078
        if (phy_data !== tmp_data)
3079
        begin
3080
          test_fail("Data was not correctly scaned from status register");
3081
          fail = fail + 1;
3082
        end
3083
        // read data from MII status register
3084
        #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3085
        if (phy_data[0] === 1'b0)
3086
        begin
3087
          test_fail("Link FAIL bit was not set in the MII status register");
3088
          fail = fail + 1;
3089
        end
3090
        // wait to see if data stayed latched
3091
        repeat(4) @(posedge Mdc_O);
3092
        // read data from PHY status register
3093
        #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3094
        if (phy_data !== tmp_data)
3095
        begin
3096
          test_fail("Data was not latched correctly in status register");
3097
          fail = fail + 1;
3098
        end
3099
        // read data from MII status register
3100
        #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3101
        if (phy_data[0] === 1'b0)
3102
        begin
3103
          test_fail("Link FAIL bit was not set in the MII status register");
3104
          fail = fail + 1;
3105
        end
3106
        // change saved data
3107
        #Tp tmp_data = tmp_data | 16'h0004; // put bit 2 to ONE
3108
        // set link up
3109
        #Tp eth_phy.link_up_down(1);
3110
      end
3111
      begin
3112
      // Wait for sixth scan
3113
        // wait for serial bus to become active - sixth scan
3114
        wait(Mdio_IO !== 1'bz);
3115
        // wait for serial bus to become inactive - turn-around cycle in sixth scan
3116
        wait(Mdio_IO === 1'bz);
3117
        // wait for serial bus to become active - end of turn-around cycle in sixth scan
3118
        wait(Mdio_IO !== 1'bz);
3119
        // wait for serial bus to become inactive - end of sixth scan
3120
        wait(Mdio_IO === 1'bz);
3121
      end
3122 169 mohor
      join
3123 181 mohor
 
3124
      @(posedge Mdc_O);
3125 169 mohor
      // read data from PHY status register
3126
      #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3127
      if (phy_data !== tmp_data)
3128
      begin
3129 181 mohor
        test_fail("Data was not correctly scaned from status register");
3130 169 mohor
        fail = fail + 1;
3131
      end
3132
      // read data from MII status register
3133
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3134
      if (phy_data[0] !== 1'b0)
3135
      begin
3136
        test_fail("Link FAIL bit was set in the MII status register");
3137
        fail = fail + 1;
3138
      end
3139 181 mohor
      // wait to see if data stayed latched
3140
      repeat(4) @(posedge Mdc_O);
3141
      // read data from PHY status register
3142
      #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3143
      if (phy_data !== tmp_data)
3144 169 mohor
      begin
3145 181 mohor
        test_fail("Data was not correctly scaned from status register");
3146
        fail = fail + 1;
3147 169 mohor
      end
3148 181 mohor
      // read data from MII status register
3149
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3150
      if (phy_data[0] !== 1'b0)
3151 169 mohor
      begin
3152 181 mohor
        test_fail("Link FAIL bit was set in the MII status register");
3153
        fail = fail + 1;
3154 169 mohor
      end
3155 181 mohor
 
3156
      // STOP SCAN
3157
      #Tp mii_scan_finish; // finish scan operation
3158
      #Tp check_mii_busy; // wait for scan to finish
3159 169 mohor
    end
3160 181 mohor
    // set PHY to normal mode
3161
    #Tp eth_phy.preamble_suppresed(0);
3162
    // MII mode register
3163
    wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3164
    if(fail == 0)
3165
      test_ok;
3166
    else
3167
      fail = 0;
3168 169 mohor
  end
3169
 
3170
 
3171 181 mohor
  ////////////////////////////////////////////////////////////////////
3172
  ////                                                            ////
3173
  ////  Test scan status from phy with sliding link-fail bit      ////
3174
  ////  (with and without preamble)                               ////
3175
  ////                                                            ////
3176
  ////////////////////////////////////////////////////////////////////
3177
  if (test_num == 15) // 
3178 169 mohor
  begin
3179 194 tadej
    // TEST 15: SCAN STATUS FROM PHY WITH SLIDING LINK-FAIL BIT ( WITH AND WITHOUT PREAMBLE )
3180
    test_name   = "TEST 15: SCAN STATUS FROM PHY WITH SLIDING LINK-FAIL BIT ( WITH AND WITHOUT PREAMBLE )";
3181
    `TIME; $display("  TEST 15: SCAN STATUS FROM PHY WITH SLIDING LINK-FAIL BIT ( WITH AND WITHOUT PREAMBLE )");
3182 181 mohor
 
3183
    // set address
3184
    reg_addr = 5'h1; // status register
3185
    phy_addr = 5'h1; // correct PHY address
3186
 
3187
    // read request
3188
    #Tp mii_read_req(phy_addr, reg_addr);
3189
    check_mii_busy; // wait for read to finish
3190
    // read data from PHY status register - remember LINK-UP status
3191
    #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3192
 
3193
    for (i2 = 0; i2 <= 1; i2 = i2 + 1) // choose preamble or not
3194 169 mohor
    begin
3195 181 mohor
      #Tp eth_phy.preamble_suppresed(i2);
3196
      // MII mode register
3197
      #Tp wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i2, 8'h0}), 4'hF, 1, wbm_init_waits,
3198
                    wbm_subseq_waits);
3199
      if (i2)
3200 169 mohor
      begin
3201 181 mohor
        // change saved data when preamble is suppressed
3202
        #Tp tmp_data = tmp_data | 16'h0040; // put bit 6 to ONE
3203
      end
3204
 
3205
      i = 0;
3206
      while (i < 80) // delay for sliding of LinkFail bit
3207
      begin
3208
        // first there are two scans
3209
        #Tp cnt = 0;
3210 169 mohor
        // scan request
3211
        #Tp mii_scan_req(phy_addr, reg_addr);
3212 181 mohor
        #Tp check_mii_scan_valid; // wait for scan to make first data valid
3213
 
3214
        // check second scan
3215 169 mohor
        fork
3216 181 mohor
        begin
3217
          repeat(4) @(posedge Mdc_O);
3218
          // read data from PHY status register
3219
          #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3220
          if (phy_data !== tmp_data)
3221 169 mohor
          begin
3222 181 mohor
            test_fail("Second data was not correctly scaned from status register");
3223
            fail = fail + 1;
3224 169 mohor
          end
3225 181 mohor
          // read data from MII status register
3226
          #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3227
          if (phy_data[0] !== 1'b0)
3228
          begin
3229
            test_fail("Link FAIL bit was set in the MII status register");
3230
            fail = fail + 1;
3231
          end
3232
        end
3233
        begin
3234
        // Completely check scan
3235
          #Tp cnt = 0;
3236
          // wait for serial bus to become active - second scan
3237
          wait(Mdio_IO !== 1'bz);
3238
          // count transfer length
3239
          while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3240
          begin
3241
            @(posedge Mdc_O);
3242
            #Tp cnt = cnt + 1;
3243
          end
3244
          // check transfer length
3245
          if (i2) // without preamble
3246
          begin
3247
            if (cnt != 33) // at this value Mdio_IO is HIGH Z
3248 169 mohor
            begin
3249 181 mohor
              test_fail("Second scan request did not proceed correctly");
3250
              fail = fail + 1;
3251 169 mohor
            end
3252 181 mohor
          end
3253
          else // with preamble
3254
          begin
3255
            if (cnt != 65) // at this value Mdio_IO is HIGH Z
3256
            begin
3257
              test_fail("Second scan request did not proceed correctly");
3258
              fail = fail + 1;
3259
            end
3260
          end
3261
        end
3262
        join
3263
        // reset counter 
3264
        #Tp cnt = 0;
3265
        // SLIDING LINK DOWN and CHECK
3266
        fork
3267
          begin
3268
          // set link down
3269
            repeat(i) @(posedge Mdc_O);
3270
            // set link down
3271
            #Tp eth_phy.link_up_down(0);
3272
          end
3273
          begin
3274
          // check data in MII registers after each scan in this fork statement
3275 169 mohor
            if (i2) // without preamble
3276 181 mohor
              wait (cnt == 32);
3277
            else // with preamble
3278
              wait (cnt == 64);
3279
            repeat(3) @(posedge Mdc_O);
3280
            // read data from PHY status register
3281
            #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3282
            if ( ((i < 49) && !i2) || ((i < 17) && i2) )
3283 169 mohor
            begin
3284 181 mohor
              if (phy_data !== (tmp_data & 16'hFFFB)) // bit 3 is ZERO
3285 169 mohor
              begin
3286 181 mohor
                test_fail("Third data was not correctly scaned from status register");
3287 169 mohor
                fail = fail + 1;
3288
              end
3289
            end
3290 181 mohor
            else
3291 169 mohor
            begin
3292 181 mohor
              if (phy_data !== tmp_data)
3293 169 mohor
              begin
3294 181 mohor
                test_fail("Third data was not correctly scaned from status register");
3295 169 mohor
                fail = fail + 1;
3296
              end
3297
            end
3298 181 mohor
            // read data from MII status register
3299
            #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3300
            if ( ((i < 49) && !i2) || ((i < 17) && i2) )
3301 169 mohor
            begin
3302 181 mohor
              if (phy_data[0] === 1'b0)
3303
              begin
3304
                test_fail("Link FAIL bit was not set in the MII status register");
3305
                fail = fail + 1;
3306
              end
3307 169 mohor
            end
3308 181 mohor
            else
3309 169 mohor
            begin
3310 181 mohor
              if (phy_data[0] !== 1'b0)
3311 169 mohor
              begin
3312 181 mohor
                test_fail("Link FAIL bit was set in the MII status register");
3313 169 mohor
                fail = fail + 1;
3314
              end
3315
            end
3316 181 mohor
          end
3317
          begin
3318
          // check length
3319
            for (i3 = 0; i3 <= 1; i3 = i3 + 1) // two scans
3320 169 mohor
            begin
3321 181 mohor
              #Tp cnt = 0;
3322
              // wait for serial bus to become active if there is more than one scan
3323
              wait(Mdio_IO !== 1'bz);
3324
              // count transfer length
3325
              while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3326 169 mohor
              begin
3327 181 mohor
                @(posedge Mdc_O);
3328
                #Tp cnt = cnt + 1;
3329 169 mohor
              end
3330 181 mohor
              // check transfer length
3331
              if (i2) // without preamble
3332
              begin
3333
                if (cnt != 33) // at this value Mdio_IO is HIGH Z
3334
                begin
3335
                  test_fail("3. or 4. scan request did not proceed correctly, while SCAN STOP was written");
3336
                  fail = fail + 1;
3337
                end
3338
              end
3339
              else // with preamble
3340
              begin
3341
                if (cnt != 65) // at this value Mdio_IO is HIGH Z
3342
                begin
3343
                  test_fail("3. or 4. scan request did not proceed correctly, while SCAN STOP was written");
3344
                  fail = fail + 1;
3345
                end
3346
              end
3347 169 mohor
            end
3348
          end
3349
        join
3350 181 mohor
        // reset counter
3351
        #Tp cnt = 0;
3352
        // check fifth scan and data from fourth scan
3353
        fork
3354 169 mohor
        begin
3355 181 mohor
          repeat(2) @(posedge Mdc_O);
3356
          // read data from PHY status register
3357
          #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3358
          if (phy_data !== (tmp_data & 16'hFFFB)) // bit 3 is ZERO
3359 169 mohor
          begin
3360 181 mohor
            test_fail("4. data was not correctly scaned from status register");
3361
            fail = fail + 1;
3362 169 mohor
          end
3363 181 mohor
          // read data from MII status register
3364
          #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3365
          if (phy_data[0] === 1'b0)
3366 169 mohor
          begin
3367 181 mohor
            test_fail("Link FAIL bit was not set in the MII status register");
3368 169 mohor
            fail = fail + 1;
3369
          end
3370
        end
3371
        begin
3372 181 mohor
        // Completely check intermediate scan
3373
          #Tp cnt = 0;
3374
          // wait for serial bus to become active - second scan
3375 169 mohor
          wait(Mdio_IO !== 1'bz);
3376
          // count transfer length
3377
          while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3378
          begin
3379
            @(posedge Mdc_O);
3380
            #Tp cnt = cnt + 1;
3381
          end
3382 181 mohor
          // check transfer length
3383
          if (i2) // without preamble
3384 169 mohor
          begin
3385 181 mohor
            if (cnt != 33) // at this value Mdio_IO is HIGH Z
3386
            begin
3387
              test_fail("Fifth scan request did not proceed correctly");
3388
              fail = fail + 1;
3389
            end
3390 169 mohor
          end
3391 181 mohor
          else // with preamble
3392
          begin
3393
            if (cnt != 65) // at this value Mdio_IO is HIGH Z
3394
            begin
3395
              test_fail("Fifth scan request did not proceed correctly");
3396
              fail = fail + 1;
3397
            end
3398
          end
3399 169 mohor
        end
3400 181 mohor
        join
3401
        // reset counter 
3402
        #Tp cnt = 0;
3403
        // SLIDING LINK UP and CHECK
3404
        fork
3405 169 mohor
          begin
3406 181 mohor
          // set link up
3407
            repeat(i) @(posedge Mdc_O);
3408
            // set link up
3409
            #Tp eth_phy.link_up_down(1);
3410 169 mohor
          end
3411 181 mohor
          begin
3412
          // check data in MII registers after each scan in this fork statement
3413
            repeat(2) @(posedge Mdc_O);
3414
            if (i2) // without preamble
3415
              wait (cnt == 32);
3416
            else // with preamble
3417
              wait (cnt == 64);
3418
            repeat(3) @(posedge Mdc_O);
3419
            // read data from PHY status register
3420
            #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3421
            if ( ((i < 49) && !i2) || ((i < 17) && i2) )
3422
            begin
3423
              if (phy_data !== tmp_data)
3424
              begin
3425
                test_fail("6. data was not correctly scaned from status register");
3426
                fail = fail + 1;
3427
              end
3428
            end
3429
            else
3430
            begin
3431
              if (phy_data !== (tmp_data & 16'hFFFB)) // bit 3 is ZERO
3432
              begin
3433
                test_fail("6. data was not correctly scaned from status register");
3434
                fail = fail + 1;
3435
              end
3436
            end
3437
            // read data from MII status register
3438
            #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3439
            if ( ((i < 49) && !i2) || ((i < 17) && i2) )
3440
            begin
3441
              if (phy_data[0] !== 1'b0)
3442
              begin
3443
                test_fail("Link FAIL bit was set in the MII status register");
3444
                fail = fail + 1;
3445
              end
3446
            end
3447
            else
3448
            begin
3449
              if (phy_data[0] === 1'b0)
3450
              begin
3451
                test_fail("Link FAIL bit was not set in the MII status register");
3452
                fail = fail + 1;
3453
              end
3454
            end
3455
          end
3456
          begin
3457
          // check length
3458
            for (i3 = 0; i3 <= 1; i3 = i3 + 1) // two scans
3459
            begin
3460
              #Tp cnt = 0;
3461
              // wait for serial bus to become active if there is more than one scan
3462
              wait(Mdio_IO !== 1'bz);
3463
              // count transfer length
3464
              while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3465
              begin
3466
                @(posedge Mdc_O);
3467
                #Tp cnt = cnt + 1;
3468
              end
3469
              // check transfer length
3470
              if (i2) // without preamble
3471
              begin
3472
                if (cnt != 33) // at this value Mdio_IO is HIGH Z
3473
                begin
3474
                  test_fail("Scan request did not proceed correctly, while SCAN STOP was written");
3475
                  fail = fail + 1;
3476
                end
3477
              end
3478
              else // with preamble
3479
              begin
3480
                if (cnt != 65) // at this value Mdio_IO is HIGH Z
3481
                begin
3482
                  test_fail("Scan request did not proceed correctly, while SCAN STOP was written");
3483
                  fail = fail + 1;
3484
                end
3485
              end
3486
            end
3487
          end
3488
        join
3489
        // check last scan 
3490
        repeat(4) @(posedge Mdc_O);
3491
        // read data from PHY status register
3492
        #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3493
        if (phy_data !== tmp_data)
3494
        begin
3495
          test_fail("7. data was not correctly scaned from status register");
3496
          fail = fail + 1;
3497 169 mohor
        end
3498 181 mohor
        // read data from MII status register
3499
        #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3500
        if (phy_data[0] !== 1'b0)
3501
        begin
3502
          test_fail("Link FAIL bit was set in the MII status register");
3503
          fail = fail + 1;
3504
        end
3505
 
3506
        #Tp mii_scan_finish; // finish scan operation
3507
        #Tp check_mii_busy; // wait for scan to finish
3508
        #Tp;
3509
        // set delay of writing the command
3510
        if (i2) // without preamble
3511
        begin
3512
          case(i)
3513
            0,  1,  2,  3,  4:  i = i + 1;
3514
            13, 14, 15, 16, 17,
3515
            18, 19, 20, 21, 22,
3516
            23, 24, 25, 26, 27,
3517
            28, 29, 30, 31, 32,
3518
            33, 34, 35:         i = i + 1;
3519
            36:                 i = 80;
3520
            default:            i = 13;
3521
          endcase
3522
        end
3523 169 mohor
        else // with preamble
3524
        begin
3525 181 mohor
          case(i)
3526
            0,  1,  2,  3,  4:  i = i + 1;
3527
            45, 46, 47, 48, 49,
3528
            50, 51, 52, 53, 54,
3529
            55, 56, 57, 58, 59,
3530
            60, 61, 62, 63, 64,
3531
            65, 66, 67:         i = i + 1;
3532
            68:                 i = 80;
3533
            default:            i = 45;
3534
          endcase
3535 169 mohor
        end
3536 181 mohor
        @(posedge wb_clk);
3537
        #Tp;
3538 169 mohor
      end
3539
    end
3540 181 mohor
    // set PHY to normal mode
3541
    #Tp eth_phy.preamble_suppresed(0);
3542
    // MII mode register
3543
    wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3544
    if(fail == 0)
3545
      test_ok;
3546
    else
3547
      fail = 0;
3548 169 mohor
  end
3549
 
3550
 
3551 181 mohor
  ////////////////////////////////////////////////////////////////////
3552
  ////                                                            ////
3553
  ////  Test sliding stop scan command immediately after scan     ////
3554
  ////  request (with and without preamble)                       ////
3555
  ////                                                            ////
3556
  ////////////////////////////////////////////////////////////////////
3557
  if (test_num == 16) // 
3558 116 mohor
  begin
3559 194 tadej
    // TEST 16: SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER SCAN REQUEST ( WITH AND WITHOUT PREAMBLE )
3560
    test_name = "TEST 16: SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER SCAN REQUEST ( WITH AND WITHOUT PREAMBLE )";
3561 181 mohor
    `TIME;
3562 194 tadej
    $display("  TEST 16: SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER SCAN REQUEST ( WITH AND WITHOUT PREAMBLE )");
3563 181 mohor
 
3564
    for (i2 = 0; i2 <= 1; i2 = i2 + 1) // choose preamble or not
3565 169 mohor
    begin
3566 181 mohor
      #Tp eth_phy.preamble_suppresed(i2);
3567
      // MII mode register
3568
      wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i2, 8'h0}), 4'hF, 1, wbm_init_waits,
3569
                wbm_subseq_waits);
3570
      i = 0;
3571
      cnt = 0;
3572
      while (i < 80) // delay for sliding of writing a STOP SCAN command
3573 169 mohor
      begin
3574 181 mohor
        for (i3 = 0; i3 <= 1; i3 = i3 + 1) // choose read or write after scan will be finished
3575 169 mohor
        begin
3576 181 mohor
          // set address
3577
          reg_addr = 5'h0; // control register
3578
          phy_addr = 5'h1; // correct PHY address
3579
          cnt = 0;
3580
          // scan request
3581
          #Tp mii_scan_req(phy_addr, reg_addr);
3582
          fork
3583
            begin
3584
              repeat(i) @(posedge Mdc_O);
3585
              // write command 0x0 into MII command register
3586
              // MII command written while scan in progress
3587
              wbm_write(`ETH_MIICOMMAND, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3588
              @(posedge wb_clk);
3589
              #Tp check_mii_busy; // wait for scan to finish
3590
              @(posedge wb_clk);
3591
              disable check;
3592
            end
3593
            begin: check
3594
              // wait for serial bus to become active
3595
              wait(Mdio_IO !== 1'bz);
3596
              // count transfer length
3597
              while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3598
              begin
3599
                @(posedge Mdc_O);
3600
                #Tp cnt = cnt + 1;
3601
              end
3602
              // check transfer length
3603
              if (i2) // without preamble
3604
              begin
3605
                if (cnt != 33) // at this value Mdio_IO is HIGH Z
3606
                begin
3607
                  test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3608
                  fail = fail + 1;
3609
                end
3610
              end
3611
              else // with preamble
3612
              begin
3613
                if (cnt != 65) // at this value Mdio_IO is HIGH Z
3614
                begin
3615
                  test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3616
                  fail = fail + 1;
3617
                end
3618
              end
3619
              cnt = 0;
3620
              // wait for serial bus to become active if there is more than one scan
3621
              wait(Mdio_IO !== 1'bz);
3622
              // count transfer length
3623
              while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3624
              begin
3625
                @(posedge Mdc_O);
3626
                #Tp cnt = cnt + 1;
3627
              end
3628
              // check transfer length
3629
              if (i2) // without preamble
3630
              begin
3631
                if (cnt != 33) // at this value Mdio_IO is HIGH Z
3632
                begin
3633
                  test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3634
                  fail = fail + 1;
3635
                end
3636
              end
3637
              else // with preamble
3638
              begin
3639
                if (cnt != 65) // at this value Mdio_IO is HIGH Z
3640
                begin
3641
                  test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3642
                  fail = fail + 1;
3643
                end
3644
              end
3645
            end
3646
          join
3647
          // check the BUSY signal to see if the bus is still IDLE
3648
          for (i1 = 0; i1 < 8; i1 = i1 + 1)
3649
            check_mii_busy; // wait for bus to become idle
3650
 
3651
          // try normal write or read after scan was finished
3652
          phy_data = {8'h7D, (i[7:0] + 1)};
3653
          cnt = 0;
3654
          if (i3 == 0) // write after scan
3655 169 mohor
          begin
3656 181 mohor
            // write request
3657
            #Tp mii_write_req(phy_addr, reg_addr, phy_data);
3658
            // wait for serial bus to become active
3659
            wait(Mdio_IO !== 1'bz);
3660
            // count transfer length
3661
            while(Mdio_IO !== 1'bz)
3662
            begin
3663
              @(posedge Mdc_O);
3664
              #Tp cnt = cnt + 1;
3665
            end
3666 169 mohor
            @(posedge Mdc_O);
3667 181 mohor
            // read request
3668
            #Tp mii_read_req(phy_addr, reg_addr);
3669
            check_mii_busy; // wait for read to finish
3670
            // read and check data
3671
            #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3672
            if (phy_data !== tmp_data)
3673 169 mohor
            begin
3674 181 mohor
              test_fail("Data was not correctly written into OR read from PHY register - control register");
3675 169 mohor
              fail = fail + 1;
3676
            end
3677
          end
3678 181 mohor
          else // read after scan
3679 169 mohor
          begin
3680 181 mohor
            // read request
3681
            #Tp mii_read_req(phy_addr, reg_addr);
3682
            // wait for serial bus to become active
3683
            wait(Mdio_IO !== 1'bz);
3684
            // count transfer length
3685
            while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3686 169 mohor
            begin
3687 181 mohor
              @(posedge Mdc_O);
3688
              #Tp cnt = cnt + 1;
3689
            end
3690
            @(posedge Mdc_O);
3691
            check_mii_busy; // wait for read to finish
3692
            // read and check data
3693
            #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3694
            if (phy_data !== tmp_data)
3695
            begin
3696
              test_fail("Data was not correctly written into OR read from PHY register - control register");
3697 169 mohor
              fail = fail + 1;
3698
            end
3699
          end
3700 181 mohor
          // check if transfer was a proper length
3701 169 mohor
          if (i2) // without preamble
3702
          begin
3703
            if (cnt != 33) // at this value Mdio_IO is HIGH Z
3704
            begin
3705 181 mohor
              test_fail("New request did not proceed correctly, after scan request");
3706 169 mohor
              fail = fail + 1;
3707
            end
3708
          end
3709
          else // with preamble
3710
          begin
3711
            if (cnt != 65) // at this value Mdio_IO is HIGH Z
3712
            begin
3713 181 mohor
              test_fail("New request did not proceed correctly, after scan request");
3714 169 mohor
              fail = fail + 1;
3715
            end
3716
          end
3717
        end
3718 181 mohor
        #Tp;
3719
        // set delay of writing the command
3720
        if (i2) // without preamble
3721
        begin
3722
          case(i)
3723
            0, 1:               i = i + 1;
3724
            18, 19, 20, 21, 22,
3725
            23, 24, 25, 26, 27,
3726
            28, 29, 30, 31, 32,
3727
            33, 34, 35:         i = i + 1;
3728
            36:                 i = 80;
3729
            default:            i = 18;
3730
          endcase
3731
        end
3732
        else // with preamble
3733
        begin
3734
          case(i)
3735
            0, 1:               i = i + 1;
3736
            50, 51, 52, 53, 54,
3737
            55, 56, 57, 58, 59,
3738
            60, 61, 62, 63, 64,
3739
            65, 66, 67:         i = i + 1;
3740
            68:                 i = 80;
3741
            default:            i = 50;
3742
          endcase
3743
        end
3744
        @(posedge wb_clk);
3745
      end
3746
    end
3747
    // set PHY to normal mode
3748
    #Tp eth_phy.preamble_suppresed(0);
3749
    // MII mode register
3750
    wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3751
    if(fail == 0)
3752
      test_ok;
3753
    else
3754
      fail = 0;
3755
  end
3756 169 mohor
 
3757 181 mohor
 
3758
  ////////////////////////////////////////////////////////////////////
3759
  ////                                                            ////
3760
  ////  Test sliding stop scan command after 2. scan (with and    ////
3761
  ////  without preamble)                                         ////
3762
  ////                                                            ////
3763
  ////////////////////////////////////////////////////////////////////
3764
  if (test_num == 17) // 
3765
  begin
3766 194 tadej
    // TEST 17: SLIDING STOP SCAN COMMAND AFTER 2. SCAN ( WITH AND WITHOUT PREAMBLE )
3767
    test_name = "TEST 17: SLIDING STOP SCAN COMMAND AFTER 2. SCAN ( WITH AND WITHOUT PREAMBLE )";
3768
    `TIME; $display("  TEST 17: SLIDING STOP SCAN COMMAND AFTER 2. SCAN ( WITH AND WITHOUT PREAMBLE )");
3769 181 mohor
 
3770
    for (i2 = 0; i2 <= 1; i2 = i2 + 1) // choose preamble or not
3771
    begin
3772
      #Tp eth_phy.preamble_suppresed(i2);
3773
      // MII mode register
3774
      wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i2, 8'h0}), 4'hF, 1, wbm_init_waits,
3775
                wbm_subseq_waits);
3776
 
3777
      i = 0;
3778
      cnt = 0;
3779
      while (i < 80) // delay for sliding of writing a STOP SCAN command
3780
      begin
3781
        for (i3 = 0; i3 <= 1; i3 = i3 + 1) // choose read or write after scan will be finished
3782
        begin
3783
          // first there are two scans
3784
          // set address
3785
          reg_addr = 5'h0; // control register
3786
          phy_addr = 5'h1; // correct PHY address
3787
          cnt = 0;
3788
          // scan request
3789
          #Tp mii_scan_req(phy_addr, reg_addr);
3790
          // wait and check first 2 scans
3791 169 mohor
          begin
3792
            // wait for serial bus to become active
3793
            wait(Mdio_IO !== 1'bz);
3794
            // count transfer length
3795
            while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3796
            begin
3797
              @(posedge Mdc_O);
3798
              #Tp cnt = cnt + 1;
3799
            end
3800
            // check transfer length
3801
            if (i2) // without preamble
3802
            begin
3803
              if (cnt != 33) // at this value Mdio_IO is HIGH Z
3804
              begin
3805
                test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3806
                fail = fail + 1;
3807
              end
3808
            end
3809
            else // with preamble
3810
            begin
3811
              if (cnt != 65) // at this value Mdio_IO is HIGH Z
3812
              begin
3813
                test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3814
                fail = fail + 1;
3815
              end
3816
            end
3817
            cnt = 0;
3818
            // wait for serial bus to become active if there is more than one scan
3819
            wait(Mdio_IO !== 1'bz);
3820
            // count transfer length
3821
            while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3822
            begin
3823
              @(posedge Mdc_O);
3824
              #Tp cnt = cnt + 1;
3825
            end
3826
            // check transfer length
3827
            if (i2) // without preamble
3828
            begin
3829
              if (cnt != 33) // at this value Mdio_IO is HIGH Z
3830
              begin
3831
                test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3832
                fail = fail + 1;
3833
              end
3834
            end
3835
            else // with preamble
3836
            begin
3837
              if (cnt != 65) // at this value Mdio_IO is HIGH Z
3838
              begin
3839
                test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3840
                fail = fail + 1;
3841
              end
3842
            end
3843
          end
3844
 
3845 181 mohor
          // reset counter 
3846
          cnt = 0;
3847
          fork
3848
            begin
3849
              repeat(i) @(posedge Mdc_O);
3850
              // write command 0x0 into MII command register
3851
              // MII command written while scan in progress
3852
              wbm_write(`ETH_MIICOMMAND, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3853
              @(posedge wb_clk);
3854
              #Tp check_mii_busy; // wait for scan to finish
3855
              @(posedge wb_clk);
3856
              disable check_3;
3857
            end
3858
            begin: check_3
3859
              // wait for serial bus to become active
3860
              wait(Mdio_IO !== 1'bz);
3861
              // count transfer length
3862
              while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3863
              begin
3864
                @(posedge Mdc_O);
3865
                #Tp cnt = cnt + 1;
3866
              end
3867
              // check transfer length
3868
              if (i2) // without preamble
3869
              begin
3870
                if (cnt != 33) // at this value Mdio_IO is HIGH Z
3871
                begin
3872
                  test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3873
                  fail = fail + 1;
3874
                end
3875
              end
3876
              else // with preamble
3877
              begin
3878
                if (cnt != 65) // at this value Mdio_IO is HIGH Z
3879
                begin
3880
                  test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3881
                  fail = fail + 1;
3882
                end
3883
              end
3884
              cnt = 0;
3885
              // wait for serial bus to become active if there is more than one scan
3886
              wait(Mdio_IO !== 1'bz);
3887
              // count transfer length
3888
              while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3889
              begin
3890
                @(posedge Mdc_O);
3891
                #Tp cnt = cnt + 1;
3892
              end
3893
              // check transfer length
3894
              if (i2) // without preamble
3895
              begin
3896
                if (cnt != 33) // at this value Mdio_IO is HIGH Z
3897
                begin
3898
                  test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3899
                  fail = fail + 1;
3900
                end
3901
              end
3902
              else // with preamble
3903
              begin
3904
                if (cnt != 65) // at this value Mdio_IO is HIGH Z
3905
                begin
3906
                  test_fail("First scan request did not proceed correctly, while SCAN STOP was written");
3907
                  fail = fail + 1;
3908
                end
3909
              end
3910
            end
3911
          join
3912
          // check the BUSY signal to see if the bus is still IDLE
3913
          for (i1 = 0; i1 < 8; i1 = i1 + 1)
3914
            check_mii_busy; // wait for bus to become idle
3915
 
3916
          // try normal write or read after scan was finished
3917
          phy_data = {8'h7D, (i[7:0] + 1)};
3918
          cnt = 0;
3919
          if (i3 == 0) // write after scan
3920 169 mohor
          begin
3921 181 mohor
            // write request
3922
            #Tp mii_write_req(phy_addr, reg_addr, phy_data);
3923
            // wait for serial bus to become active
3924
            wait(Mdio_IO !== 1'bz);
3925
            // count transfer length
3926
            while(Mdio_IO !== 1'bz)
3927
            begin
3928
              @(posedge Mdc_O);
3929
              #Tp cnt = cnt + 1;
3930
            end
3931 169 mohor
            @(posedge Mdc_O);
3932 181 mohor
            // read request
3933
            #Tp mii_read_req(phy_addr, reg_addr);
3934
            check_mii_busy; // wait for read to finish
3935
            // read and check data
3936
            #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3937
            if (phy_data !== tmp_data)
3938
            begin
3939
              test_fail("Data was not correctly written into OR read from PHY register - control register");
3940
              fail = fail + 1;
3941
            end
3942 169 mohor
          end
3943 181 mohor
          else // read after scan
3944 169 mohor
          begin
3945 181 mohor
            // read request
3946
            #Tp mii_read_req(phy_addr, reg_addr);
3947
            // wait for serial bus to become active
3948
            wait(Mdio_IO !== 1'bz);
3949
            // count transfer length
3950
            while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
3951
            begin
3952
              @(posedge Mdc_O);
3953
              #Tp cnt = cnt + 1;
3954
            end
3955
            @(posedge Mdc_O);
3956
            check_mii_busy; // wait for read to finish
3957
            // read and check data
3958
            #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3959
            if (phy_data !== tmp_data)
3960
            begin
3961
              test_fail("Data was not correctly written into OR read from PHY register - control register");
3962
              fail = fail + 1;
3963
            end
3964 169 mohor
          end
3965 181 mohor
          // check if transfer was a proper length
3966
          if (i2) // without preamble
3967 169 mohor
          begin
3968 181 mohor
            if (cnt != 33) // at this value Mdio_IO is HIGH Z
3969
            begin
3970
              test_fail("New request did not proceed correctly, after scan request");
3971
              fail = fail + 1;
3972
            end
3973 169 mohor
          end
3974 181 mohor
          else // with preamble
3975 169 mohor
          begin
3976 181 mohor
            if (cnt != 65) // at this value Mdio_IO is HIGH Z
3977
            begin
3978
              test_fail("New request did not proceed correctly, after scan request");
3979
              fail = fail + 1;
3980
            end
3981 169 mohor
          end
3982
        end
3983 181 mohor
        #Tp;
3984
        // set delay of writing the command
3985 169 mohor
        if (i2) // without preamble
3986
        begin
3987 181 mohor
          case(i)
3988
            0, 1:               i = i + 1;
3989
            18, 19, 20, 21, 22,
3990
            23, 24, 25, 26, 27,
3991
            28, 29, 30, 31, 32,
3992
            33, 34, 35:         i = i + 1;
3993
            36:                 i = 80;
3994
            default:            i = 18;
3995
          endcase
3996 169 mohor
        end
3997
        else // with preamble
3998
        begin
3999 181 mohor
          case(i)
4000
            0, 1:               i = i + 1;
4001
            50, 51, 52, 53, 54,
4002
            55, 56, 57, 58, 59,
4003
            60, 61, 62, 63, 64,
4004
            65, 66, 67:         i = i + 1;
4005
            68:                 i = 80;
4006
            default:            i = 50;
4007
          endcase
4008 169 mohor
        end
4009 181 mohor
        @(posedge wb_clk);
4010 116 mohor
      end
4011
    end
4012 181 mohor
    // set PHY to normal mode
4013
    #Tp eth_phy.preamble_suppresed(0);
4014
    // MII mode register
4015
    wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4016
    if(fail == 0)
4017
      test_ok;
4018
    else
4019
      fail = 0;
4020 169 mohor
  end
4021 116 mohor
 
4022 181 mohor
end   //  for (test_num=start_task; test_num <= end_task; test_num=test_num+1)
4023
 
4024 169 mohor
end
4025
endtask // test_mii
4026
 
4027
 
4028
task test_mac_full_duplex_transmit;
4029
  input  [31:0]  start_task;
4030
  input  [31:0]  end_task;
4031
  integer        bit_start_1;
4032
  integer        bit_end_1;
4033
  integer        bit_start_2;
4034
  integer        bit_end_2;
4035
  integer        num_of_reg;
4036 209 tadejm
  integer        num_of_frames;
4037
  integer        num_of_bd;
4038 169 mohor
  integer        i_addr;
4039
  integer        i_data;
4040
  integer        i_length;
4041 209 tadejm
  integer        tmp_len;
4042
  integer        tmp_bd;
4043
  integer        tmp_bd_num;
4044 169 mohor
  integer        tmp_data;
4045 209 tadejm
  integer        tmp_ipgt;
4046 194 tadej
  integer        test_num;
4047 169 mohor
  reg    [31:0]  tx_bd_num;
4048
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_data;
4049
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_tmp_data;
4050
  integer        i;
4051
  integer        i1;
4052
  integer        i2;
4053
  integer        i3;
4054
  integer        fail;
4055
  integer        speed;
4056 209 tadejm
  reg            frame_started;
4057
  reg            frame_ended;
4058
  reg            wait_for_frame;
4059 169 mohor
  reg    [31:0]  addr;
4060
  reg    [31:0]  data;
4061
  reg    [31:0]  tmp;
4062
  reg    [ 7:0]  st_data;
4063
  reg    [15:0]  max_tmp;
4064
  reg    [15:0]  min_tmp;
4065
begin
4066
// MAC FULL DUPLEX TRANSMIT TEST
4067
test_heading("MAC FULL DUPLEX TRANSMIT TEST");
4068
$display(" ");
4069
$display("MAC FULL DUPLEX TRANSMIT TEST");
4070
fail = 0;
4071
 
4072
// reset MAC registers
4073
hard_reset;
4074
// reset MAC and MII LOGIC with soft reset
4075
reset_mac;
4076
reset_mii;
4077
// set wb slave response
4078
wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
4079
 
4080
  /*
4081
  TASKS for set and control TX buffer descriptors (also send packet - set_tx_bd_ready):
4082
  -------------------------------------------------------------------------------------
4083
  set_tx_bd
4084
    (tx_bd_num_start[6:0], tx_bd_num_end[6:0], len[15:0], irq, pad, crc, txpnt[31:0]);
4085
  set_tx_bd_wrap
4086
    (tx_bd_num_end[6:0]);
4087
  set_tx_bd_ready
4088
    (tx_bd_num_start[6:0], tx_bd_num_end[6:0]);
4089
  check_tx_bd
4090
    (tx_bd_num_start[6:0], tx_bd_status[31:0]);
4091
  clear_tx_bd
4092
    (tx_bd_num_start[6:0], tx_bd_num_end[6:0]);
4093
 
4094
  TASKS for set and control RX buffer descriptors:
4095
  ------------------------------------------------
4096
  set_rx_bd
4097
    (rx_bd_num_strat[6:0], rx_bd_num_end[6:0], irq, rxpnt[31:0]);
4098
  set_rx_bd_wrap
4099
    (rx_bd_num_end[6:0]);
4100
  set_rx_bd_empty
4101
    (rx_bd_num_strat[6:0], rx_bd_num_end[6:0]);
4102
  check_rx_bd
4103
    (rx_bd_num_end[6:0], rx_bd_status);
4104
  clear_rx_bd
4105
    (rx_bd_num_strat[6:0], rx_bd_num_end[6:0]);
4106
 
4107
  TASKS for set and check TX packets:
4108
  -----------------------------------
4109
  set_tx_packet
4110
    (txpnt[31:0], len[15:0], eth_start_data[7:0]);
4111
  check_tx_packet
4112
    (txpnt_wb[31:0], txpnt_phy[31:0], len[15:0], failure[31:0]);
4113
 
4114
  TASKS for set and check RX packets:
4115
  -----------------------------------
4116
  set_rx_packet
4117
    (rxpnt[31:0], len[15:0], plus_nibble, d_addr[47:0], s_addr[47:0], type_len[15:0], start_data[7:0]);
4118
  check_rx_packet
4119
    (rxpnt_phy[31:0], rxpnt_wb[31:0], len[15:0], plus_nibble, successful_nibble, failure[31:0]);
4120
 
4121
  TASKS for append and check CRC to/of TX packet:
4122
  -----------------------------------------------
4123
  append_tx_crc
4124
    (txpnt_wb[31:0], len[15:0], negated_crc);
4125
  check_tx_crc
4126
    (txpnt_phy[31:0], len[15:0], negated_crc, failure[31:0]);
4127
 
4128
  TASK for append CRC to RX packet (CRC is checked together with check_rx_packet):
4129
  --------------------------------------------------------------------------------
4130
  append_rx_crc
4131
    (rxpnt_phy[31:0], len[15:0], plus_nibble, negated_crc);
4132
  */
4133
 
4134 194 tadej
//////////////////////////////////////////////////////////////////////
4135
////                                                              ////
4136
////  test_mac_full_duplex_transmit:                              ////
4137
////                                                              ////
4138
////  0: Test no transmit when all buffers are RX ( 10Mbps ).     ////
4139
////  1: Test no transmit when all buffers are RX ( 100Mbps ).    ////
4140
////  2: Test transmit packets form MINFL to MAXFL sizes at       ////
4141
////     one TX buffer decriptor ( 10Mbps ).                      ////
4142
////  3: Test transmit packets form MINFL to MAXFL sizes at       ////
4143
////     one TX buffer decriptor ( 100Mbps ).                     ////
4144
////                                                              ////
4145
//////////////////////////////////////////////////////////////////////
4146
for (test_num = start_task; test_num <= end_task; test_num = test_num + 1)
4147 169 mohor
begin
4148
 
4149 194 tadej
  ////////////////////////////////////////////////////////////////////
4150
  ////                                                            ////
4151
  ////  Test no transmit when all buffers are RX ( 10Mbps ).      ////
4152
  ////                                                            ////
4153
  ////////////////////////////////////////////////////////////////////
4154
  if (test_num == 0) // Test no transmit when all buffers are RX ( 10Mbps ).
4155 169 mohor
  begin
4156 194 tadej
    // TEST 0: NO TRANSMIT WHEN ALL BUFFERS ARE RX ( 10Mbps )
4157
    test_name   = "TEST 0: NO TRANSMIT WHEN ALL BUFFERS ARE RX ( 10Mbps )";
4158
    `TIME; $display("  TEST 0: NO TRANSMIT WHEN ALL BUFFERS ARE RX ( 10Mbps )");
4159
 
4160
    // unmask interrupts
4161 209 tadejm
    wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
4162 194 tadej
                             `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4163
    // set all buffer descriptors to RX - must be set before TX enable
4164
    wbm_write(`ETH_TX_BD_NUM, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4165
    // enable TX, set full-duplex mode, padding and CRC appending
4166
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
4167
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4168
 
4169
    // write to phy's control register for 10Mbps
4170
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
4171
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
4172
    speed = 10;
4173
 
4174
    i = 0;
4175
    while (i < 128)
4176 169 mohor
    begin
4177 194 tadej
      for (i1 = 0; i1 <= i; i1 = i1 + 1)
4178 169 mohor
      begin
4179 194 tadej
        set_tx_packet((`MEMORY_BASE + (i1 * 200)), 100, 0);
4180
        set_tx_bd(i1, i1, 100, 1'b1, 1'b1, 1'b1, (`MEMORY_BASE + (i1 * 200)));
4181 169 mohor
      end
4182 194 tadej
      set_tx_bd_wrap(i);
4183
      fork
4184
        begin
4185
          set_tx_bd_ready(0, i);
4186
          repeat(20) @(negedge mtx_clk);
4187
          #1 disable check_tx_en10;
4188
        end
4189
        begin: check_tx_en10
4190
          wait (MTxEn === 1'b1);
4191
          test_fail("Tramsmit should not start at all");
4192
          fail = fail + 1;
4193
          `TIME; $display("*E Transmit of %d packets should not start at all - active MTxEn", i);
4194
        end
4195
      join
4196
      for (i2 = 0; i2 < 20; i2 = i2 + 1)
4197 169 mohor
      begin
4198 194 tadej
        check_tx_bd(0, tmp);
4199
        #1;
4200
        if (tmp[15] === 1'b0)
4201
        begin
4202
          test_fail("Tramsmit should not start at all");
4203
          fail = fail + 1;
4204
          `TIME; $display("*E Transmit of %d packets should not start at all - ready is 0", i);
4205
        end
4206
        if (tmp[8:0] !== 0)
4207
        begin
4208
          test_fail("Tramsmit should not be finished since it should not start at all");
4209
          fail = fail + 1;
4210
          `TIME; $display("*E Transmit of should not be finished since it should not start at all");
4211
        end
4212
        @(posedge wb_clk);
4213 169 mohor
      end
4214 194 tadej
      wbm_read(`ETH_INT, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4215
      if (tmp[6:0] !== 0)
4216 169 mohor
      begin
4217 194 tadej
        test_fail("Tramsmit should not get INT since it should not start at all");
4218 169 mohor
        fail = fail + 1;
4219 194 tadej
        `TIME; $display("*E Transmit of should not get INT since it should not start at all");
4220 169 mohor
      end
4221 194 tadej
      clear_tx_bd(0, i);
4222
      if ((i < 5) || (i > 124))
4223
        i = i + 1;
4224
      else
4225
        i = i + 120;
4226 116 mohor
    end
4227 194 tadej
    // disable TX
4228
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
4229
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4230
    if(fail == 0)
4231
      test_ok;
4232 116 mohor
    else
4233 194 tadej
      fail = 0;
4234 169 mohor
  end
4235 116 mohor
 
4236
 
4237 194 tadej
  ////////////////////////////////////////////////////////////////////
4238
  ////                                                            ////
4239
  ////  Test no transmit when all buffers are RX ( 100Mbps ).     ////
4240
  ////                                                            ////
4241
  ////////////////////////////////////////////////////////////////////
4242
  if (test_num == 1) // Test no transmit when all buffers are RX ( 100Mbps ).
4243 169 mohor
  begin
4244 194 tadej
    // TEST 1: NO TRANSMIT WHEN ALL BUFFERS ARE RX ( 100Mbps )
4245
    test_name   = "TEST 1: NO TRANSMIT WHEN ALL BUFFERS ARE RX ( 100Mbps )";
4246
    `TIME; $display("  TEST 1: NO TRANSMIT WHEN ALL BUFFERS ARE RX ( 100Mbps )");
4247
 
4248
    // unmask interrupts
4249 209 tadejm
    wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
4250 194 tadej
                             `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4251
    // set all buffer descriptors to RX - must be set before TX enable
4252
    wbm_write(`ETH_TX_BD_NUM, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4253
    // enable TX, set full-duplex mode, padding and CRC appending
4254
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
4255
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4256
 
4257
    // write to phy's control register for 100Mbps
4258
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
4259
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
4260
    speed = 100;
4261
 
4262
    i = 0;
4263
    while (i < 128)
4264 169 mohor
    begin
4265 194 tadej
      for (i1 = 0; i1 <= i; i1 = i1 + 1)
4266 169 mohor
      begin
4267 194 tadej
        set_tx_packet((`MEMORY_BASE + (i1 * 200)), 100, 0);
4268
        set_tx_bd(i1, i1, 100, 1'b1, 1'b1, 1'b1, (`MEMORY_BASE + (i1 * 200)));
4269 169 mohor
      end
4270 194 tadej
      set_tx_bd_wrap(i);
4271
      fork
4272
        begin
4273
          set_tx_bd_ready(0, i);
4274
          repeat(20) @(negedge mtx_clk);
4275
          #1 disable check_tx_en100;
4276
        end
4277
        begin: check_tx_en100
4278
          wait (MTxEn === 1'b1);
4279
          test_fail("Tramsmit should not start at all");
4280
          fail = fail + 1;
4281
          `TIME; $display("*E Transmit of %d packets should not start at all - active MTxEn", i);
4282
        end
4283
      join
4284
      for (i2 = 0; i2 < 20; i2 = i2 + 1)
4285 169 mohor
      begin
4286 194 tadej
        check_tx_bd(0, tmp);
4287
        #1;
4288
        if (tmp[15] === 1'b0)
4289
        begin
4290
          test_fail("Tramsmit should not start at all");
4291
          fail = fail + 1;
4292
          `TIME; $display("*E Transmit of %d packets should not start at all - ready is 0", i);
4293
        end
4294
        if (tmp[8:0] !== 0)
4295
        begin
4296
          test_fail("Tramsmit should not be finished since it should not start at all");
4297
          fail = fail + 1;
4298
          `TIME; $display("*E Transmit of should not be finished since it should not start at all");
4299
        end
4300
        @(posedge wb_clk);
4301 169 mohor
      end
4302 194 tadej
      wbm_read(`ETH_INT, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4303
      if (tmp[6:0] !== 0)
4304 169 mohor
      begin
4305 194 tadej
        test_fail("Tramsmit should not get INT since it should not start at all");
4306 169 mohor
        fail = fail + 1;
4307 194 tadej
        `TIME; $display("*E Transmit of should not get INT since it should not start at all");
4308 169 mohor
      end
4309 194 tadej
      clear_tx_bd(0, i);
4310
      if ((i < 5) || (i > 124))
4311
        i = i + 1;
4312
      else
4313
        i = i + 120;
4314 169 mohor
    end
4315 194 tadej
    // disable TX
4316
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
4317
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4318
    if(fail == 0)
4319
      test_ok;
4320 169 mohor
    else
4321 194 tadej
      fail = 0;
4322 169 mohor
  end
4323
 
4324
 
4325 194 tadej
  ////////////////////////////////////////////////////////////////////
4326
  ////                                                            ////
4327
  ////  Test transmit packets form MINFL to MAXFL sizes at        ////
4328
  ////  one TX buffer decriptor ( 10Mbps ).                       ////
4329
  ////                                                            ////
4330
  ////////////////////////////////////////////////////////////////////
4331 209 tadejm
  if (test_num == 2) // without and with padding
4332 169 mohor
  begin
4333 194 tadej
    // TEST 2: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT ONE TX BD ( 10Mbps )
4334
    test_name = "TEST 2: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT ONE TX BD ( 10Mbps )";
4335
    `TIME; $display("  TEST 2: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT ONE TX BD ( 10Mbps )");
4336
 
4337
    max_tmp = 0;
4338
    min_tmp = 0;
4339
    // set one TX buffer descriptor - must be set before TX enable
4340
    wbm_write(`ETH_TX_BD_NUM, 32'h1, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4341 209 tadejm
    // enable TX, set full-duplex mode, NO padding and CRC appending
4342
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
4343 194 tadej
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4344
    // prepare two packets of MAXFL length
4345
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4346
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
4347
    min_tmp = tmp[31:16];
4348 209 tadejm
    st_data = 8'h01;
4349
    set_tx_packet(`MEMORY_BASE, (max_tmp), st_data); // length without CRC
4350 194 tadej
    st_data = 8'h10;
4351 209 tadejm
    set_tx_packet((`MEMORY_BASE + max_tmp), (max_tmp), st_data); // length without CRC
4352 194 tadej
    // check WB INT signal
4353
    if (wb_int !== 1'b0)
4354 169 mohor
    begin
4355 194 tadej
      test_fail("WB INT signal should not be set");
4356
      fail = fail + 1;
4357 169 mohor
    end
4358 194 tadej
 
4359
    // write to phy's control register for 10Mbps
4360
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
4361
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
4362
    speed = 10;
4363
 
4364
    i_length = (min_tmp - 4);
4365
    while (i_length <= (max_tmp - 4))
4366 169 mohor
    begin
4367 194 tadej
      // choose generating carrier sense and collision for first and last 64 lengths of frames
4368
      case (i_length[1:0])
4369
      2'h0: // Interrupt is generated
4370 169 mohor
      begin
4371 194 tadej
        // enable interrupt generation
4372 209 tadejm
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, (`MEMORY_BASE + i_length[1:0]));
4373 194 tadej
        // unmask interrupts
4374 209 tadejm
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
4375 194 tadej
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4376
        // not detect carrier sense in FD and no collision
4377
        eth_phy.carrier_sense_tx_fd_detect(0);
4378
        eth_phy.collision(0);
4379 169 mohor
      end
4380 194 tadej
      2'h1: // Interrupt is not generated
4381 169 mohor
      begin
4382 194 tadej
        // enable interrupt generation
4383 209 tadejm
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
4384 194 tadej
        // mask interrupts
4385
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4386
        // detect carrier sense in FD and no collision
4387
        eth_phy.carrier_sense_tx_fd_detect(1);
4388
        eth_phy.collision(0);
4389 169 mohor
      end
4390 194 tadej
      2'h2: // Interrupt is not generated
4391
      begin
4392
        // disable interrupt generation
4393 209 tadejm
        set_tx_bd(0, 0, i_length, 1'b0, 1'b1, 1'b1, (`MEMORY_BASE + i_length[1:0]));
4394 194 tadej
        // unmask interrupts
4395 209 tadejm
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
4396 194 tadej
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4397
        // not detect carrier sense in FD and set collision
4398
        eth_phy.carrier_sense_tx_fd_detect(0);
4399
        eth_phy.collision(1);
4400
      end
4401
      default: // 2'h3: // Interrupt is not generated
4402
      begin
4403
        // disable interrupt generation
4404 209 tadejm
        set_tx_bd(0, 0, i_length, 1'b0, 1'b1, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
4405 194 tadej
        // mask interrupts
4406
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4407
        // detect carrier sense in FD and set collision
4408
        eth_phy.carrier_sense_tx_fd_detect(1);
4409
        eth_phy.collision(1);
4410
      end
4411
      endcase
4412
      eth_phy.set_tx_mem_addr(max_tmp);
4413
      // set wrap bit
4414
      set_tx_bd_wrap(0);
4415
      set_tx_bd_ready(0, 0);
4416 169 mohor
      #1 check_tx_bd(0, data);
4417 194 tadej
      if (i_length < min_tmp) // just first four
4418 169 mohor
      begin
4419 194 tadej
        while (data[15] === 1)
4420
        begin
4421
          #1 check_tx_bd(0, data);
4422
          @(posedge wb_clk);
4423
        end
4424 209 tadejm
        repeat (1) @(posedge wb_clk);
4425 169 mohor
      end
4426 194 tadej
      else if (i_length > (max_tmp - 8)) // just last four
4427 192 tadej
      begin
4428 194 tadej
        tmp = 0;
4429
        wait (MTxEn === 1'b1); // start transmit
4430
        while (tmp < (i_length - 20))
4431
        begin
4432
          #1 tmp = tmp + 1;
4433
          @(posedge wb_clk);
4434
        end
4435
        #1 check_tx_bd(0, data);
4436
        while (data[15] === 1)
4437
        begin
4438
          #1 check_tx_bd(0, data);
4439
          @(posedge wb_clk);
4440
        end
4441 209 tadejm
        repeat (1) @(posedge wb_clk);
4442 192 tadej
      end
4443
      else
4444
      begin
4445 194 tadej
        wait (MTxEn === 1'b1); // start transmit
4446
        #1 check_tx_bd(0, data);
4447
        if (data[15] !== 1)
4448
        begin
4449
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
4450
          fail = fail + 1;
4451
        end
4452
        wait (MTxEn === 1'b0); // end transmit
4453
        while (data[15] === 1)
4454
        begin
4455
          #1 check_tx_bd(0, data);
4456
          @(posedge wb_clk);
4457
        end
4458
        repeat (1) @(posedge wb_clk);
4459 192 tadej
      end
4460 194 tadej
      // check length of a PACKET
4461
      if (eth_phy.tx_len != (i_length + 4))
4462 192 tadej
      begin
4463 194 tadej
        test_fail("Wrong length of the packet out from MAC");
4464 192 tadej
        fail = fail + 1;
4465
      end
4466 194 tadej
      // checking in the following if statement is performed only for first and last 64 lengths
4467
      if ( ((i_length + 4) <= (min_tmp + 64)) || ((i_length + 4) > (max_tmp - 64)) )
4468 192 tadej
      begin
4469 194 tadej
        // check transmitted TX packet data
4470
        if (i_length[0] == 0)
4471
        begin
4472 209 tadejm
          check_tx_packet((`MEMORY_BASE + i_length[1:0]), max_tmp, i_length, tmp);
4473 194 tadej
        end
4474
        else
4475
        begin
4476 209 tadejm
          check_tx_packet(((`MEMORY_BASE + i_length[1:0]) + max_tmp), max_tmp, i_length, tmp);
4477 194 tadej
        end
4478
        if (tmp > 0)
4479
        begin
4480
          test_fail("Wrong data of the transmitted packet");
4481
          fail = fail + 1;
4482
        end
4483
        // check transmited TX packet CRC
4484
        check_tx_crc(max_tmp, i_length, 1'b0, tmp); // length without CRC
4485
        if (tmp > 0)
4486
        begin
4487
          test_fail("Wrong CRC of the transmitted packet");
4488
          fail = fail + 1;
4489
        end
4490 192 tadej
      end
4491 194 tadej
      // check WB INT signal
4492
      if (i_length[1:0] == 2'h0)
4493 192 tadej
      begin
4494 194 tadej
        if (wb_int !== 1'b1)
4495
        begin
4496
          `TIME; $display("*E WB INT signal should be set");
4497
          test_fail("WB INT signal should be set");
4498
          fail = fail + 1;
4499
        end
4500 192 tadej
      end
4501 194 tadej
      else
4502 192 tadej
      begin
4503 194 tadej
        if (wb_int !== 1'b0)
4504
        begin
4505
          `TIME; $display("*E WB INT signal should not be set");
4506
          test_fail("WB INT signal should not be set");
4507
          fail = fail + 1;
4508
        end
4509 192 tadej
      end
4510 194 tadej
      // check TX buffer descriptor of a packet
4511
      check_tx_bd(0, data);
4512
      if (i_length[1] == 1'b0) // interrupt enabled
4513 192 tadej
      begin
4514 194 tadej
        if (data[15:0] !== 16'h7800)
4515
        begin
4516
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
4517
          test_fail("TX buffer descriptor status is not correct");
4518
          fail = fail + 1;
4519
        end
4520 192 tadej
      end
4521 194 tadej
      else // interrupt not enabled
4522 192 tadej
      begin
4523 194 tadej
        if (data[15:0] !== 16'h3800)
4524
        begin
4525
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
4526
          test_fail("TX buffer descriptor status is not correct");
4527
          fail = fail + 1;
4528
        end
4529 192 tadej
      end
4530 194 tadej
      // clear TX buffer descriptor
4531
      clear_tx_bd(0, 0);
4532
      // check interrupts
4533
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4534
      if ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1))
4535 192 tadej
      begin
4536 194 tadej
        if ((data & `ETH_INT_TXB) !== 1'b1)
4537
        begin
4538
          `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
4539
          test_fail("Interrupt Transmit Buffer was not set");
4540
          fail = fail + 1;
4541
        end
4542
        if ((data & (~`ETH_INT_TXB)) !== 0)
4543
        begin
4544
          `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
4545
          test_fail("Other interrupts (except Transmit Buffer) were set");
4546
          fail = fail + 1;
4547
        end
4548 192 tadej
      end
4549 194 tadej
      else
4550 192 tadej
      begin
4551 194 tadej
        if (data !== 0)
4552
        begin
4553
          `TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]);
4554
          test_fail("Any of interrupts (except Transmit Buffer) was set");
4555
          fail = fail + 1;
4556
        end
4557 192 tadej
      end
4558 194 tadej
      // clear interrupts
4559
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4560
      // check WB INT signal
4561
      if (wb_int !== 1'b0)
4562 192 tadej
      begin
4563 194 tadej
        test_fail("WB INT signal should not be set");
4564 192 tadej
        fail = fail + 1;
4565
      end
4566 194 tadej
      // INTERMEDIATE DISPLAYS
4567
      if ((i_length + 4) == (min_tmp + 64))
4568 209 tadejm
      begin
4569 194 tadej
        // starting length is min_tmp, ending length is (min_tmp + 64)
4570 209 tadejm
        $display("    pads appending to packets is NOT selected");
4571
        $display("    ->packets with lengths from %0d (MINFL) to %0d are checked (length increasing by 1 byte)",
4572 194 tadej
                 min_tmp, (min_tmp + 64));
4573 209 tadejm
        // set padding, remain the rest
4574
        wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
4575
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4576
      end
4577 194 tadej
      else if ((i_length + 4) == (max_tmp - 16))
4578 209 tadejm
      begin
4579 194 tadej
        // starting length is for +128 longer than previous ending length, while ending length is tmp_data
4580 209 tadejm
        $display("    pads appending to packets is selected");
4581
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 128 bytes)",
4582 194 tadej
                 (min_tmp + 64 + 128), tmp_data);
4583 209 tadejm
        // reset padding, remain the rest
4584
        wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
4585
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4586
      end
4587 194 tadej
      else if ((i_length + 4) == max_tmp)
4588 209 tadejm
      begin
4589
        $display("    pads appending to packets is NOT selected");
4590
        $display("    ->packets with lengths from %0d to %0d (MAXFL) are checked (length increasing by 1 byte)",
4591 194 tadej
                 (max_tmp - (4 + 16)), max_tmp);
4592 209 tadejm
      end
4593 194 tadej
      // set length (loop variable)
4594
      if ((i_length + 4) < (min_tmp + 64))
4595
        i_length = i_length + 1;
4596
      else if ( ((i_length + 4) >= (min_tmp + 64)) && ((i_length + 4) <= (max_tmp - 256)) )
4597
      begin
4598
        i_length = i_length + 128;
4599
        tmp_data = i_length + 4; // last tmp_data is ending length
4600
      end
4601
      else if ( ((i_length + 4) > (max_tmp - 256)) && ((i_length + 4) < (max_tmp - 16)) )
4602
        i_length = max_tmp - (4 + 16);
4603
      else if ((i_length + 4) >= (max_tmp - 16))
4604
        i_length = i_length + 1;
4605
      else
4606
      begin
4607
        $display("*E TESTBENCH ERROR - WRONG PARAMETERS IN TESTBENCH");
4608
        #10 $stop;
4609
      end
4610 192 tadej
    end
4611 194 tadej
    // disable TX
4612
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
4613
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4614
    if(fail == 0)
4615
      test_ok;
4616
    else
4617
      fail = 0;
4618
  end
4619
 
4620
 
4621
  ////////////////////////////////////////////////////////////////////
4622
  ////                                                            ////
4623
  ////  Test transmit packets form MINFL to MAXFL sizes at        ////
4624
  ////  one TX buffer decriptor ( 100Mbps ).                      ////
4625
  ////                                                            ////
4626
  ////////////////////////////////////////////////////////////////////
4627 209 tadejm
  if (test_num == 3) // with and without padding
4628 194 tadej
  begin
4629
    // TEST 3: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT ONE TX BD ( 100Mbps )
4630
    test_name = "TEST 3: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT ONE TX BD ( 100Mbps )";
4631
    `TIME; $display("  TEST 3: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT ONE TX BD ( 100Mbps )");
4632
 
4633
    max_tmp = 0;
4634
    min_tmp = 0;
4635
    // set one TX buffer descriptor - must be set before TX enable
4636
    wbm_write(`ETH_TX_BD_NUM, 32'h1, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4637 209 tadejm
    // enable TX, set full-duplex mode, NO padding and CRC appending
4638
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
4639 194 tadej
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4640
    // prepare two packets of MAXFL length
4641
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4642
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
4643
    min_tmp = tmp[31:16];
4644
    st_data = 8'h5A;
4645 209 tadejm
    set_tx_packet(`MEMORY_BASE, (max_tmp), st_data); // length without CRC
4646 194 tadej
    st_data = 8'h10;
4647 209 tadejm
    set_tx_packet((`MEMORY_BASE + max_tmp), (max_tmp), st_data); // length without CRC
4648 169 mohor
    // check WB INT signal
4649 192 tadej
    if (wb_int !== 1'b0)
4650 169 mohor
    begin
4651
      test_fail("WB INT signal should not be set");
4652
      fail = fail + 1;
4653
    end
4654 194 tadej
 
4655
    // write to phy's control register for 100Mbps
4656
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
4657
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
4658
    speed = 100;
4659 192 tadej
 
4660 194 tadej
    i_length = (min_tmp - 4);
4661
    while (i_length <= (max_tmp - 4))
4662 192 tadej
    begin
4663 194 tadej
      // choose generating carrier sense and collision
4664
      case (i_length[1:0])
4665
      2'h0: // Interrupt is generated
4666 192 tadej
      begin
4667 194 tadej
        // enable interrupt generation
4668 209 tadejm
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, (`MEMORY_BASE + i_length[1:0]));
4669 194 tadej
        // unmask interrupts
4670 209 tadejm
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
4671 194 tadej
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4672
        // not detect carrier sense in FD and no collision
4673
        eth_phy.carrier_sense_tx_fd_detect(0);
4674
        eth_phy.collision(0);
4675 192 tadej
      end
4676 194 tadej
      2'h1: // Interrupt is not generated
4677 192 tadej
      begin
4678 194 tadej
        // enable interrupt generation
4679 209 tadejm
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
4680 194 tadej
        // mask interrupts
4681
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4682
        // detect carrier sense in FD and no collision
4683
        eth_phy.carrier_sense_tx_fd_detect(1);
4684
        eth_phy.collision(0);
4685 192 tadej
      end
4686 194 tadej
      2'h2: // Interrupt is not generated
4687
      begin
4688
        // disable interrupt generation
4689 209 tadejm
        set_tx_bd(0, 0, i_length, 1'b0, 1'b1, 1'b1, (`MEMORY_BASE + i_length[1:0]));
4690 194 tadej
        // unmask interrupts
4691 209 tadejm
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
4692 194 tadej
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4693
        // not detect carrier sense in FD and set collision
4694
        eth_phy.carrier_sense_tx_fd_detect(0);
4695
        eth_phy.collision(1);
4696
      end
4697
      default: // 2'h3: // Interrupt is not generated
4698
      begin
4699
        // disable interrupt generation
4700 209 tadejm
        set_tx_bd(0, 0, i_length, 1'b0, 1'b1, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
4701 194 tadej
        // mask interrupts
4702
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4703
        // detect carrier sense in FD and set collision
4704
        eth_phy.carrier_sense_tx_fd_detect(1);
4705
        eth_phy.collision(1);
4706
      end
4707
      endcase
4708
      eth_phy.set_tx_mem_addr(max_tmp);
4709
      // set wrap bit
4710
      set_tx_bd_wrap(0);
4711
      set_tx_bd_ready(0, 0);
4712 192 tadej
      #1 check_tx_bd(0, data);
4713 194 tadej
      if (i_length < min_tmp) // just first four
4714 192 tadej
      begin
4715 194 tadej
        while (data[15] === 1)
4716
        begin
4717
          #1 check_tx_bd(0, data);
4718
          @(posedge wb_clk);
4719
        end
4720 209 tadejm
        repeat (1) @(posedge wb_clk);
4721 194 tadej
      end
4722
      else if (i_length > (max_tmp - 8)) // just last four
4723
      begin
4724
        tmp = 0;
4725
        wait (MTxEn === 1'b1); // start transmit
4726
        while (tmp < (i_length - 20))
4727
        begin
4728
          #1 tmp = tmp + 1;
4729
          @(posedge wb_clk);
4730
        end
4731 192 tadej
        #1 check_tx_bd(0, data);
4732 194 tadej
        while (data[15] === 1)
4733
        begin
4734
          #1 check_tx_bd(0, data);
4735
          @(posedge wb_clk);
4736
        end
4737 209 tadejm
        repeat (1) @(posedge wb_clk);
4738 192 tadej
      end
4739 194 tadej
      else
4740
      begin
4741
        wait (MTxEn === 1'b1); // start transmit
4742
        #1 check_tx_bd(0, data);
4743
        if (data[15] !== 1)
4744
        begin
4745
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
4746
          fail = fail + 1;
4747
        end
4748
        wait (MTxEn === 1'b0); // end transmit
4749
        while (data[15] === 1)
4750
        begin
4751
          #1 check_tx_bd(0, data);
4752
          @(posedge wb_clk);
4753
        end
4754
        repeat (1) @(posedge wb_clk);
4755
      end
4756
      // check length of a PACKET
4757
      if (eth_phy.tx_len != (i_length + 4))
4758
      begin
4759
        test_fail("Wrong length of the packet out from MAC");
4760
        fail = fail + 1;
4761
      end
4762 192 tadej
      // check transmitted TX packet data
4763
      if (i_length[0] == 0)
4764
      begin
4765 209 tadejm
        check_tx_packet((`MEMORY_BASE + i_length[1:0]), max_tmp, i_length, tmp);
4766 192 tadej
      end
4767
      else
4768
      begin
4769 209 tadejm
        check_tx_packet(((`MEMORY_BASE + i_length[1:0]) + max_tmp), max_tmp, i_length, tmp);
4770 192 tadej
      end
4771
      if (tmp > 0)
4772
      begin
4773
        test_fail("Wrong data of the transmitted packet");
4774
        fail = fail + 1;
4775
      end
4776
      // check transmited TX packet CRC
4777
      check_tx_crc(max_tmp, i_length, 1'b0, tmp); // length without CRC
4778
      if (tmp > 0)
4779
      begin
4780
        test_fail("Wrong CRC of the transmitted packet");
4781
        fail = fail + 1;
4782
      end
4783 194 tadej
      // check WB INT signal
4784
      if (i_length[1:0] == 2'h0)
4785 192 tadej
      begin
4786 194 tadej
        if (wb_int !== 1'b1)
4787
        begin
4788
          `TIME; $display("*E WB INT signal should be set");
4789
          test_fail("WB INT signal should be set");
4790
          fail = fail + 1;
4791
        end
4792 192 tadej
      end
4793 194 tadej
      else
4794 192 tadej
      begin
4795 194 tadej
        if (wb_int !== 1'b0)
4796
        begin
4797
          `TIME; $display("*E WB INT signal should not be set");
4798
          test_fail("WB INT signal should not be set");
4799
          fail = fail + 1;
4800
        end
4801 192 tadej
      end
4802 194 tadej
      // check TX buffer descriptor of a packet
4803
      check_tx_bd(0, data);
4804
      if (i_length[1] == 1'b0) // interrupt enabled
4805 192 tadej
      begin
4806 194 tadej
        if (data[15:0] !== 16'h7800)
4807
        begin
4808
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
4809
          test_fail("TX buffer descriptor status is not correct");
4810
          fail = fail + 1;
4811
        end
4812 192 tadej
      end
4813 194 tadej
      else // interrupt not enabled
4814 192 tadej
      begin
4815 194 tadej
        if (data[15:0] !== 16'h3800)
4816
        begin
4817
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
4818
          test_fail("TX buffer descriptor status is not correct");
4819
          fail = fail + 1;
4820
        end
4821 192 tadej
      end
4822 194 tadej
      // clear TX buffer descriptor
4823
      clear_tx_bd(0, 0);
4824
      // check interrupts
4825
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4826
      if ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1))
4827 192 tadej
      begin
4828 194 tadej
        if ((data & `ETH_INT_TXB) !== 1'b1)
4829
        begin
4830
          `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
4831
          test_fail("Interrupt Transmit Buffer was not set");
4832
          fail = fail + 1;
4833
        end
4834
        if ((data & (~`ETH_INT_TXB)) !== 0)
4835
        begin
4836
          `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
4837
          test_fail("Other interrupts (except Transmit Buffer) were set");
4838
          fail = fail + 1;
4839
        end
4840 192 tadej
      end
4841 194 tadej
      else
4842 192 tadej
      begin
4843 194 tadej
        if (data !== 0)
4844
        begin
4845
          `TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h", data);
4846
          test_fail("Any of interrupts (except Transmit Buffer) was set");
4847
          fail = fail + 1;
4848
        end
4849 192 tadej
      end
4850 194 tadej
      // clear interrupts
4851
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4852
      // check WB INT signal
4853
      if (wb_int !== 1'b0)
4854 192 tadej
      begin
4855 194 tadej
        test_fail("WB INT signal should not be set");
4856 192 tadej
        fail = fail + 1;
4857
      end
4858 194 tadej
      // INTERMEDIATE DISPLAYS
4859
      if ((i_length + 4) == (min_tmp + 64))
4860 209 tadejm
      begin
4861 194 tadej
        // starting length is min_tmp, ending length is (min_tmp + 64)
4862 209 tadejm
        $display("    pads appending to packets is NOT selected");
4863
        $display("    ->packets with lengths from %0d (MINFL) to %0d are checked (length increasing by 1 byte)",
4864 194 tadej
                 min_tmp, (min_tmp + 64));
4865 209 tadejm
        // set padding, remain the rest
4866
        wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
4867
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4868
      end
4869 194 tadej
      else if ((i_length + 4) == (max_tmp - 16))
4870 209 tadejm
      begin
4871 194 tadej
        // starting length is for +128 longer than previous ending length, while ending length is tmp_data
4872 209 tadejm
        $display("    pads appending to packets is selected");
4873
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 128 bytes)",
4874 194 tadej
                 (min_tmp + 64 + 128), tmp_data);
4875 209 tadejm
        // reset padding, remain the rest
4876
        wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
4877
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4878
      end
4879 194 tadej
      else if ((i_length + 4) == max_tmp)
4880 209 tadejm
      begin
4881
        $display("    pads appending to packets is NOT selected");
4882
        $display("    ->packets with lengths from %0d to %0d (MAXFL) are checked (length increasing by 1 byte)",
4883 194 tadej
                 (max_tmp - (4 + 16)), max_tmp);
4884 209 tadejm
      end
4885 194 tadej
      // set length (loop variable)
4886
      if ((i_length + 4) < (min_tmp + 64))
4887
        i_length = i_length + 1;
4888
      else if ( ((i_length + 4) >= (min_tmp + 64)) && ((i_length + 4) <= (max_tmp - 256)) )
4889
      begin
4890
        i_length = i_length + 128;
4891
        tmp_data = i_length + 4; // last tmp_data is ending length
4892
      end
4893
      else if ( ((i_length + 4) > (max_tmp - 256)) && ((i_length + 4) < (max_tmp - 16)) )
4894
        i_length = max_tmp - (4 + 16);
4895
      else if ((i_length + 4) >= (max_tmp - 16))
4896
        i_length = i_length + 1;
4897 192 tadej
      else
4898 194 tadej
      begin
4899
        $display("*E TESTBENCH ERROR - WRONG PARAMETERS IN TESTBENCH");
4900
        #10 $stop;
4901
      end
4902 179 mohor
    end
4903 194 tadej
    // disable TX
4904
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
4905
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4906
    if(fail == 0)
4907
      test_ok;
4908
    else
4909
      fail = 0;
4910 169 mohor
  end
4911
 
4912
 
4913 209 tadejm
  ////////////////////////////////////////////////////////////////////
4914
  ////                                                            ////
4915
  ////  Test transmit packets form MINFL to MAXFL sizes at        ////
4916
  ////  maximum TX buffer decriptors ( 10Mbps ).                  ////
4917
  ////                                                            ////
4918
  ////////////////////////////////////////////////////////////////////
4919
  if (test_num == 4) // without and with padding
4920
  begin
4921
    // TEST 4: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT MAX TX BDs ( 10Mbps )
4922
    test_name = "TEST 4: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT MAX TX BDs ( 10Mbps )";
4923
    `TIME; $display("  TEST 4: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT MAX TX BDs ( 10Mbps )");
4924
 
4925
    // reset MAC registers
4926
    hard_reset;
4927
    // reset MAC and MII LOGIC with soft reset
4928
    reset_mac;
4929
    reset_mii;
4930
    // set wb slave response
4931
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
4932 192 tadej
 
4933 209 tadejm
    max_tmp = 0;
4934
    min_tmp = 0;
4935
    num_of_frames = 0;
4936
    num_of_bd = 0;
4937
    // set maximum TX buffer descriptors (128) - must be set before TX enable
4938
    wbm_write(`ETH_TX_BD_NUM, 32'h80, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4939
    // enable TX, set full-duplex mode, NO padding and CRC appending
4940
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
4941
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4942
    // prepare two packets of MAXFL length
4943
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4944
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
4945
    min_tmp = tmp[31:16];
4946
    st_data = 8'hA3;
4947
    set_tx_packet(`MEMORY_BASE, (max_tmp), st_data); // length without CRC
4948
    st_data = 8'h81;
4949
    set_tx_packet((`MEMORY_BASE + max_tmp), (max_tmp), st_data); // length without CRC
4950
    // check WB INT signal
4951
    if (wb_int !== 1'b0)
4952
    begin
4953
      test_fail("WB INT signal should not be set");
4954
      fail = fail + 1;
4955
    end
4956
 
4957
    // write to phy's control register for 10Mbps
4958
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
4959
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
4960
    speed = 10;
4961
 
4962
    i_length = (min_tmp - 4);
4963
    while (i_length <= (max_tmp - 4))
4964
    begin
4965
      // choose generating carrier sense and collision
4966
      case (i_length[1:0])
4967
      2'h0: // Interrupt is generated
4968
      begin
4969
        // Reset_tx_bd nable interrupt generation
4970
        // unmask interrupts
4971
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
4972
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4973
        // not detect carrier sense in FD and no collision
4974
        eth_phy.carrier_sense_tx_fd_detect(0);
4975
        eth_phy.collision(0);
4976
      end
4977
      2'h1: // Interrupt is not generated
4978
      begin
4979
        // set_tx_bd enable interrupt generation
4980
        // mask interrupts
4981
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4982
        // detect carrier sense in FD and no collision
4983
        eth_phy.carrier_sense_tx_fd_detect(1);
4984
        eth_phy.collision(0);
4985
      end
4986
      2'h2: // Interrupt is not generated
4987
      begin
4988
        // set_tx_bd disable the interrupt generation
4989
        // unmask interrupts
4990
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
4991
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4992
        // not detect carrier sense in FD and set collision
4993
        eth_phy.carrier_sense_tx_fd_detect(0);
4994
        eth_phy.collision(1);
4995
      end
4996
      default: // 2'h3: // Interrupt is not generated
4997
      begin
4998
        // set_tx_bd disable the interrupt generation
4999
        // mask interrupts
5000
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5001
        // detect carrier sense in FD and set collision
5002
        eth_phy.carrier_sense_tx_fd_detect(1);
5003
        eth_phy.collision(1);
5004
      end
5005
      endcase
5006
      // first destination address on ethernet PHY
5007
      if (i_length[0] == 0)
5008
        eth_phy.set_tx_mem_addr(0);
5009
      else
5010
        eth_phy.set_tx_mem_addr(max_tmp);
5011
      // first 8 frames are transmitted with TX BD 0 (wrap bit on TX BD 0)
5012
      // number of all frames is 154 (146 without first 8)
5013
      if (num_of_frames < 8)
5014
      begin
5015
        case (i_length[1:0])
5016
        2'h0: // Interrupt is generated
5017
        begin
5018
          // enable interrupt generation
5019
          set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, (`MEMORY_BASE + i_length[1:0]));
5020
          // interrupts are unmasked
5021
        end
5022
        2'h1: // Interrupt is not generated
5023
        begin
5024
          // enable interrupt generation
5025
          set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
5026
          // interrupts are masked
5027
        end
5028
        2'h2: // Interrupt is not generated
5029
        begin
5030
          // disable interrupt generation
5031
          set_tx_bd(0, 0, i_length, 1'b0, 1'b1, 1'b1, (`MEMORY_BASE + i_length[1:0]));
5032
          // interrupts are unmasked
5033
        end
5034
        default: // 2'h3: // Interrupt is not generated
5035
        begin
5036
          // disable interrupt generation
5037
          set_tx_bd(0, 0, i_length, 1'b0, 1'b1, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
5038
          // interrupts are masked
5039
        end
5040
        endcase
5041
        // set wrap bit
5042
        set_tx_bd_wrap(0);
5043
      end
5044
      // after first 8 number of frames, 128 frames form TX BD 0 to 127 will be transmitted
5045
      else if ((num_of_frames - 8) == 0)
5046
      begin
5047
        tmp_len = i_length; // length of frame
5048
        tmp_bd_num = 0; // TX BD number
5049
        while (tmp_bd_num < 128) // (tmp_len <= (max_tmp - 4)) - this is the last frame
5050
        begin
5051
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
5052
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
5053
          if (tmp_len[0] == 0)
5054
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + tmp_len[1:0]));
5055
          else
5056
            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));
5057
          // set length (loop variable) - THE SAME AS AT THE END OF THIS TASK !!!
5058
          if ((tmp_len + 4) < (min_tmp + 128))
5059
            tmp_len = tmp_len + 1;
5060
          else if ( ((tmp_len + 4) == (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
5061
            tmp_len = 256;
5062
          else if ( ((tmp_len + 4) > (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
5063
            tmp_len = tmp_len + 128;
5064
          else if ( ((tmp_len + 4) > (max_tmp - 256)) && ((tmp_len + 4) < (max_tmp - 16)) )
5065
            tmp_len = max_tmp - (4 + 16);
5066
          else if ((tmp_len + 4) >= (max_tmp - 16))
5067
            tmp_len = tmp_len + 1;
5068
          // set TX BD number
5069
          tmp_bd_num = tmp_bd_num + 1;
5070
        end
5071
        // set wrap bit
5072
        set_tx_bd_wrap(127);
5073
      end
5074
      // after 128 + first 8 number of frames, 19 frames form TX BD 0 to 18 will be transmitted
5075
      else if ((num_of_frames - 8) == 20) // 128
5076
      begin
5077
        tmp_len = tmp_len; // length of frame remaines from previous settings
5078
        tmp_bd_num = 0; // TX BD number
5079
        while (tmp_bd_num < 19) // (tmp_len <= (max_tmp - 4)) - this is the last frame
5080
        begin
5081
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
5082
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
5083
          if (tmp_len[0] == 0)
5084
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + tmp_len[1:0]));
5085
          else
5086
            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));
5087
          // set length (loop variable) - THE SAME AS AT THE END OF THIS TASK !!!
5088
          if ((tmp_len + 4) < (min_tmp + 128))
5089
            tmp_len = tmp_len + 1;
5090
          else if ( ((tmp_len + 4) == (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
5091
            tmp_len = 256;
5092
          else if ( ((tmp_len + 4) > (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
5093
            tmp_len = tmp_len + 128;
5094
          else if ( ((tmp_len + 4) > (max_tmp - 256)) && ((tmp_len + 4) < (max_tmp - 16)) )
5095
            tmp_len = max_tmp - (4 + 16);
5096
          else if ((tmp_len + 4) >= (max_tmp - 16))
5097
            tmp_len = tmp_len + 1;
5098
          // set TX BD number
5099
          tmp_bd_num = tmp_bd_num + 1;
5100
        end
5101
      end
5102
      // set ready bit
5103
      if (num_of_frames < 8)
5104
        set_tx_bd_ready(0, 0);
5105
      else if ((num_of_frames - 8) < 128)
5106
        set_tx_bd_ready((num_of_frames - 8), (num_of_frames - 8));
5107
      else if ((num_of_frames - 136) < 19)
5108
        set_tx_bd_ready((num_of_frames - 136), (num_of_frames - 136));
5109
      // CHECK END OF TRANSMITION
5110
      #1 check_tx_bd(num_of_bd, data);
5111
      if (i_length < min_tmp) // just first four
5112
      begin
5113
        while (data[15] === 1)
5114
        begin
5115
          #1 check_tx_bd(num_of_bd, data);
5116
          @(posedge wb_clk);
5117
        end
5118
        repeat (1) @(posedge wb_clk);
5119
      end
5120
      else if (i_length > (max_tmp - 8)) // just last four
5121
      begin
5122
        tmp = 0;
5123
        wait (MTxEn === 1'b1); // start transmit
5124
        while (tmp < (i_length - 20))
5125
        begin
5126
          #1 tmp = tmp + 1;
5127
          @(posedge wb_clk);
5128
        end
5129
        #1 check_tx_bd(num_of_bd, data);
5130
        while (data[15] === 1)
5131
        begin
5132
          #1 check_tx_bd(num_of_bd, data);
5133
          @(posedge wb_clk);
5134
        end
5135
        repeat (1) @(posedge wb_clk);
5136
      end
5137
      else
5138
      begin
5139
        wait (MTxEn === 1'b1); // start transmit
5140
        #1 check_tx_bd(num_of_bd, data);
5141
        if (data[15] !== 1)
5142
        begin
5143
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
5144
          fail = fail + 1;
5145
        end
5146
        wait (MTxEn === 1'b0); // end transmit
5147
        while (data[15] === 1)
5148
        begin
5149
          #1 check_tx_bd(num_of_bd, data);
5150
          @(posedge wb_clk);
5151
        end
5152
        repeat (1) @(posedge wb_clk);
5153
      end
5154
      // check length of a PACKET
5155
      if (eth_phy.tx_len != (i_length + 4))
5156
      begin
5157
        test_fail("Wrong length of the packet out from MAC");
5158
        fail = fail + 1;
5159
      end
5160
        // check transmitted TX packet data
5161
        if (i_length[0] == 0)
5162
        begin
5163
          check_tx_packet((`MEMORY_BASE + i_length[1:0]), 0, i_length, tmp);
5164
        end
5165
        else
5166
        begin
5167
          check_tx_packet(((`MEMORY_BASE + i_length[1:0]) + max_tmp), max_tmp, i_length, tmp);
5168
        end
5169
        if (tmp > 0)
5170
        begin
5171
          test_fail("Wrong data of the transmitted packet");
5172
          fail = fail + 1;
5173
        end
5174
        // check transmited TX packet CRC
5175
        if (i_length[0] == 0)
5176
          check_tx_crc(0, i_length, 1'b0, tmp); // length without CRC
5177
        else
5178
          check_tx_crc(max_tmp, i_length, 1'b0, tmp); // length without CRC
5179
        if (tmp > 0)
5180
        begin
5181
          test_fail("Wrong CRC of the transmitted packet");
5182
          fail = fail + 1;
5183
        end
5184
      // check WB INT signal
5185
      if (i_length[1:0] == 2'h0)
5186
      begin
5187
        if (wb_int !== 1'b1)
5188
        begin
5189
          `TIME; $display("*E WB INT signal should be set");
5190
          test_fail("WB INT signal should be set");
5191
          fail = fail + 1;
5192
        end
5193
      end
5194
      else
5195
      begin
5196
        if (wb_int !== 1'b0)
5197
        begin
5198
          `TIME; $display("*E WB INT signal should not be set");
5199
          test_fail("WB INT signal should not be set");
5200
          fail = fail + 1;
5201
        end
5202
      end
5203
      // check TX buffer descriptor of a packet
5204
      check_tx_bd(num_of_bd, data);
5205
      if (i_length[1] == 1'b0) // interrupt enabled
5206
      begin
5207
        if ( ((data[15:0] !== 16'h7800) && ((num_of_frames < 8) || ((num_of_frames - 8) == 127))) || // wrap bit
5208
             ((data[15:0] !== 16'h5800) && (num_of_frames >= 8) && ((num_of_frames - 8) != 127)) ) // without wrap bit
5209
        begin
5210
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
5211
          test_fail("TX buffer descriptor status is not correct");
5212
          fail = fail + 1;
5213
        end
5214
      end
5215
      else // interrupt not enabled
5216
      begin
5217
        if ( ((data[15:0] !== 16'h3800)  && ((num_of_frames < 8) || ((num_of_frames - 8) == 127))) || // wrap bit
5218
             ((data[15:0] !== 16'h1800) && (num_of_frames >= 8) && ((num_of_frames - 8) != 127)) ) // without wrap bit
5219
        begin
5220
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
5221
          test_fail("TX buffer descriptor status is not correct");
5222
          fail = fail + 1;
5223
        end
5224
      end
5225
      // clear first half of 8 frames from TX buffer descriptor 0
5226
      if (num_of_frames < 4)
5227
        clear_tx_bd(num_of_bd, num_of_bd);
5228
      // clear BD with wrap bit
5229
      if (num_of_frames == 140)
5230
        clear_tx_bd(127, 127);
5231
      // check interrupts
5232
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5233
      if ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1))
5234
      begin
5235
        if ((data & `ETH_INT_TXB) !== 1'b1)
5236
        begin
5237
          `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
5238
          test_fail("Interrupt Transmit Buffer was not set");
5239
          fail = fail + 1;
5240
        end
5241
        if ((data & (~`ETH_INT_TXB)) !== 0)
5242
        begin
5243
          `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
5244
          test_fail("Other interrupts (except Transmit Buffer) were set");
5245
          fail = fail + 1;
5246
        end
5247
      end
5248
      else
5249
      begin
5250
        if (data !== 0)
5251
        begin
5252
          `TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]);
5253
          test_fail("Any of interrupts (except Transmit Buffer) was set");
5254
          fail = fail + 1;
5255
        end
5256
      end
5257
      // clear interrupts
5258
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5259
      // check WB INT signal
5260
      if (wb_int !== 1'b0)
5261
      begin
5262
        test_fail("WB INT signal should not be set");
5263
        fail = fail + 1;
5264
      end
5265
      // INTERMEDIATE DISPLAYS
5266
      if ((i_length + 4) == (min_tmp + 7))
5267
      begin
5268
        // starting length is min_tmp, ending length is (min_tmp + 128)
5269
        $display("    pads appending to packets is NOT selected");
5270
        $display("    using only TX BD 0 out of 128 BDs assigned to TX (wrap at first BD - TX BD 0)");
5271
        $display("    ->packets with lengths from %0d (MINFL) to %0d are checked (length increasing by 1 byte)",
5272
                 min_tmp, (min_tmp + 7));
5273
        $display("    ->all packets were send from TX BD 0");
5274
        // set padding, remain the rest
5275
        wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
5276
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5277
      end
5278
      else if ((i_length + 4) == (min_tmp + 128))
5279
      begin
5280
        // starting length is min_tmp, ending length is (min_tmp + 128)
5281
        $display("    pads appending to packets is NOT selected");
5282
        $display("    using all 128 BDs assigned to TX (wrap at 128th BD - TX BD 127)");
5283
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
5284
                 (min_tmp + 8), (min_tmp + 128));
5285
        $display("    ->packets were send from TX BD %0d to TX BD %0d respectively",
5286
                 1'b0, num_of_bd);
5287
        tmp_bd = num_of_bd + 1;
5288
        // set padding, remain the rest
5289
        wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
5290
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5291
      end
5292
      else if ((i_length + 4) == (max_tmp - 16))
5293
      begin
5294
        // starting length is for +128 longer than previous ending length, while ending length is tmp_data
5295
        $display("    pads appending to packets is selected");
5296
        $display("    using all 128 BDs assigned to TX (wrap at 128th BD - TX BD 127)");
5297
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 128 bytes)",
5298
                 (min_tmp + 64 + 128), tmp_data);
5299
        if (tmp_bd > num_of_bd)
5300
          $display("    ->packets were send from TX BD %0d to TX BD 127 and from TX BD 0 to TX BD %0d respectively",
5301
                   tmp_bd, num_of_bd);
5302
        else
5303
          $display("    ->packets were send from TX BD %0d to TX BD %0d respectively",
5304
                   tmp_bd, num_of_bd);
5305
        tmp_bd = num_of_bd + 1;
5306
        // reset padding, remain the rest
5307
        wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
5308
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5309
      end
5310
      else if ((i_length + 4) == max_tmp)
5311
      begin
5312
        $display("    pads appending to packets is NOT selected");
5313
        $display("    using all 128 BDs assigned to TX (wrap at 128th BD - TX BD 127)");
5314
        $display("    ->packets with lengths from %0d to %0d (MAXFL) are checked (length increasing by 1 byte)",
5315
                 (max_tmp - (4 + 16)), max_tmp);
5316
        if (tmp_bd > num_of_bd)
5317
          $display("    ->packets were send from TX BD %0d to TX BD 127 and from TX BD 0 to TX BD %0d respectively",
5318
                   tmp_bd, num_of_bd);
5319
        else
5320
          $display("    ->packets were send from TX BD %0d to TX BD %0d respectively",
5321
                   tmp_bd, num_of_bd);
5322
      end
5323
      // set length (loop variable)
5324
      if ((i_length + 4) < (min_tmp + 128))
5325
        i_length = i_length + 1;
5326
      else if ( ((i_length + 4) == (min_tmp + 128)) && ((i_length + 4) <= (max_tmp - 256)) )
5327
        i_length = 256;
5328
      else if ( ((i_length + 4) > (min_tmp + 128)) && ((i_length + 4) <= (max_tmp - 256)) )
5329
      begin
5330
        i_length = i_length + 128;
5331
        tmp_data = i_length + 4; // last tmp_data is ending length
5332
      end
5333
      else if ( ((i_length + 4) > (max_tmp - 256)) && ((i_length + 4) < (max_tmp - 16)) )
5334
        i_length = max_tmp - (4 + 16);
5335
      else if ((i_length + 4) >= (max_tmp - 16))
5336
        i_length = i_length + 1;
5337
      else
5338
      begin
5339
        $display("*E TESTBENCH ERROR - WRONG PARAMETERS IN TESTBENCH");
5340
        #10 $stop;
5341
      end
5342
      // the number of frame transmitted
5343
      num_of_frames = num_of_frames + 1;
5344
      if ((num_of_frames <= 8) || ((num_of_frames - 8) == 128))
5345
        num_of_bd = 0;
5346
      else
5347
        num_of_bd = num_of_bd + 1;
5348
    end
5349
    // disable TX
5350
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
5351
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5352
    @(posedge wb_clk);
5353
    if(fail == 0)
5354
      test_ok;
5355
    else
5356
      fail = 0;
5357
  end
5358
 
5359
 
5360
  ////////////////////////////////////////////////////////////////////
5361
  ////                                                            ////
5362
  ////  Test transmit packets form MINFL to MAXFL sizes at        ////
5363
  ////  maximum TX buffer decriptors ( 100Mbps ).                 ////
5364
  ////                                                            ////
5365
  ////////////////////////////////////////////////////////////////////
5366
  if (test_num == 5) // with and without padding
5367
  begin
5368
    // TEST 5: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT MAX TX BDs ( 100Mbps )
5369
    test_name = "TEST 5: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT MAX TX BDs ( 100Mbps )";
5370
    `TIME; $display("  TEST 5: TRANSMIT PACKETS FROM MINFL TO MAXFL SIZES AT MAX TX BDs ( 100Mbps )");
5371
 
5372
    // reset MAC registers
5373
    hard_reset;
5374
    // reset MAC and MII LOGIC with soft reset
5375
    reset_mac;
5376
    reset_mii;
5377
    // set wb slave response
5378
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
5379
 
5380
    max_tmp = 0;
5381
    min_tmp = 0;
5382
    num_of_frames = 0;
5383
    num_of_bd = 0;
5384
    // set maximum TX buffer descriptors (128) - must be set before TX enable
5385
    wbm_write(`ETH_TX_BD_NUM, 32'h80, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5386
    // enable TX, set full-duplex mode, NO padding and CRC appending
5387
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
5388
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5389
    // prepare two packets of MAXFL length
5390
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5391
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
5392
    min_tmp = tmp[31:16];
5393
    st_data = 8'hA5;
5394
    set_tx_packet(`MEMORY_BASE, (max_tmp), st_data); // length without CRC
5395
    st_data = 8'h71;
5396
    set_tx_packet((`MEMORY_BASE + max_tmp), (max_tmp), st_data); // length without CRC
5397
    // check WB INT signal
5398
    if (wb_int !== 1'b0)
5399
    begin
5400
      test_fail("WB INT signal should not be set");
5401
      fail = fail + 1;
5402
    end
5403
 
5404
    // write to phy's control register for 100Mbps
5405
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
5406
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
5407
    speed = 100;
5408
 
5409
    i_length = (min_tmp - 4);
5410
    while (i_length <= (max_tmp - 4))
5411
    begin
5412
      // choose generating carrier sense and collision
5413
      case (i_length[1:0])
5414
      2'h0: // Interrupt is generated
5415
      begin
5416
        // Reset_tx_bd nable interrupt generation
5417
        // unmask interrupts
5418
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
5419
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5420
        // not detect carrier sense in FD and no collision
5421
        eth_phy.carrier_sense_tx_fd_detect(0);
5422
        eth_phy.collision(0);
5423
      end
5424
      2'h1: // Interrupt is not generated
5425
      begin
5426
        // set_tx_bd enable interrupt generation
5427
        // mask interrupts
5428
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5429
        // detect carrier sense in FD and no collision
5430
        eth_phy.carrier_sense_tx_fd_detect(1);
5431
        eth_phy.collision(0);
5432
      end
5433
      2'h2: // Interrupt is not generated
5434
      begin
5435
        // set_tx_bd disable the interrupt generation
5436
        // unmask interrupts
5437
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
5438
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5439
        // not detect carrier sense in FD and set collision
5440
        eth_phy.carrier_sense_tx_fd_detect(0);
5441
        eth_phy.collision(1);
5442
      end
5443
      default: // 2'h3: // Interrupt is not generated
5444
      begin
5445
        // set_tx_bd disable the interrupt generation
5446
        // mask interrupts
5447
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5448
        // detect carrier sense in FD and set collision
5449
        eth_phy.carrier_sense_tx_fd_detect(1);
5450
        eth_phy.collision(1);
5451
      end
5452
      endcase
5453
      // first destination address on ethernet PHY
5454
      if (i_length[0] == 0)
5455
        eth_phy.set_tx_mem_addr(0);
5456
      else
5457
        eth_phy.set_tx_mem_addr(max_tmp);
5458
      // first 8 frames are transmitted with TX BD 0 (wrap bit on TX BD 0)
5459
      // number of all frames is 154 (146 without first 8)
5460
      if (num_of_frames < 8)
5461
      begin
5462
        case (i_length[1:0])
5463
        2'h0: // Interrupt is generated
5464
        begin
5465
          // enable interrupt generation
5466
          set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, (`MEMORY_BASE + i_length[1:0]));
5467
          // interrupts are unmasked
5468
        end
5469
        2'h1: // Interrupt is not generated
5470
        begin
5471
          // enable interrupt generation
5472
          set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
5473
          // interrupts are masked
5474
        end
5475
        2'h2: // Interrupt is not generated
5476
        begin
5477
          // disable interrupt generation
5478
          set_tx_bd(0, 0, i_length, 1'b0, 1'b1, 1'b1, (`MEMORY_BASE + i_length[1:0]));
5479
          // interrupts are unmasked
5480
        end
5481
        default: // 2'h3: // Interrupt is not generated
5482
        begin
5483
          // disable interrupt generation
5484
          set_tx_bd(0, 0, i_length, 1'b0, 1'b1, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
5485
          // interrupts are masked
5486
        end
5487
        endcase
5488
        // set wrap bit
5489
        set_tx_bd_wrap(0);
5490
      end
5491
      // after first 8 number of frames, 128 frames form TX BD 0 to 127 will be transmitted
5492
      else if ((num_of_frames - 8) == 0)
5493
      begin
5494
        tmp_len = i_length; // length of frame
5495
        tmp_bd_num = 0; // TX BD number
5496
        while (tmp_bd_num < 128) // (tmp_len <= (max_tmp - 4)) - this is the last frame
5497
        begin
5498
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
5499
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
5500
          if (tmp_len[0] == 0)
5501
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + tmp_len[1:0]));
5502
          else
5503
            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));
5504
          // set length (loop variable) - THE SAME AS AT THE END OF THIS TASK !!!
5505
          if ((tmp_len + 4) < (min_tmp + 128))
5506
            tmp_len = tmp_len + 1;
5507
          else if ( ((tmp_len + 4) == (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
5508
            tmp_len = 256;
5509
          else if ( ((tmp_len + 4) > (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
5510
            tmp_len = tmp_len + 128;
5511
          else if ( ((tmp_len + 4) > (max_tmp - 256)) && ((tmp_len + 4) < (max_tmp - 16)) )
5512
            tmp_len = max_tmp - (4 + 16);
5513
          else if ((tmp_len + 4) >= (max_tmp - 16))
5514
            tmp_len = tmp_len + 1;
5515
          // set TX BD number
5516
          tmp_bd_num = tmp_bd_num + 1;
5517
        end
5518
        // set wrap bit
5519
        set_tx_bd_wrap(127);
5520
      end
5521
      // after 128 + first 8 number of frames, 19 frames form TX BD 0 to 18 will be transmitted
5522
      else if ((num_of_frames - 8) == 20) // 128
5523
      begin
5524
        tmp_len = tmp_len; // length of frame remaines from previous settings
5525
        tmp_bd_num = 0; // TX BD number
5526
        while (tmp_bd_num < 19) // (tmp_len <= (max_tmp - 4)) - this is the last frame
5527
        begin
5528
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
5529
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
5530
          if (tmp_len[0] == 0)
5531
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + tmp_len[1:0]));
5532
          else
5533
            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));
5534
          // set length (loop variable) - THE SAME AS AT THE END OF THIS TASK !!!
5535
          if ((tmp_len + 4) < (min_tmp + 128))
5536
            tmp_len = tmp_len + 1;
5537
          else if ( ((tmp_len + 4) == (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
5538
            tmp_len = 256;
5539
          else if ( ((tmp_len + 4) > (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
5540
            tmp_len = tmp_len + 128;
5541
          else if ( ((tmp_len + 4) > (max_tmp - 256)) && ((tmp_len + 4) < (max_tmp - 16)) )
5542
            tmp_len = max_tmp - (4 + 16);
5543
          else if ((tmp_len + 4) >= (max_tmp - 16))
5544
            tmp_len = tmp_len + 1;
5545
          // set TX BD number
5546
          tmp_bd_num = tmp_bd_num + 1;
5547
        end
5548
      end
5549
      // set ready bit
5550
      if (num_of_frames < 8)
5551
        set_tx_bd_ready(0, 0);
5552
      else if ((num_of_frames - 8) < 128)
5553
        set_tx_bd_ready((num_of_frames - 8), (num_of_frames - 8));
5554
      else if ((num_of_frames - 136) < 19)
5555
        set_tx_bd_ready((num_of_frames - 136), (num_of_frames - 136));
5556
      // CHECK END OF TRANSMITION
5557
      #1 check_tx_bd(num_of_bd, data);
5558
      if (i_length < min_tmp) // just first four
5559
      begin
5560
        while (data[15] === 1)
5561
        begin
5562
          #1 check_tx_bd(num_of_bd, data);
5563
          @(posedge wb_clk);
5564
        end
5565
        repeat (1) @(posedge wb_clk);
5566
      end
5567
      else if (i_length > (max_tmp - 8)) // just last four
5568
      begin
5569
        tmp = 0;
5570
        wait (MTxEn === 1'b1); // start transmit
5571
        while (tmp < (i_length - 20))
5572
        begin
5573
          #1 tmp = tmp + 1;
5574
          @(posedge wb_clk);
5575
        end
5576
        #1 check_tx_bd(num_of_bd, data);
5577
        while (data[15] === 1)
5578
        begin
5579
          #1 check_tx_bd(num_of_bd, data);
5580
          @(posedge wb_clk);
5581
        end
5582
        repeat (1) @(posedge wb_clk);
5583
      end
5584
      else
5585
      begin
5586
        wait (MTxEn === 1'b1); // start transmit
5587
        #1 check_tx_bd(num_of_bd, data);
5588
        if (data[15] !== 1)
5589
        begin
5590
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
5591
          fail = fail + 1;
5592
        end
5593
        wait (MTxEn === 1'b0); // end transmit
5594
        while (data[15] === 1)
5595
        begin
5596
          #1 check_tx_bd(num_of_bd, data);
5597
          @(posedge wb_clk);
5598
        end
5599
        repeat (1) @(posedge wb_clk);
5600
      end
5601
      // check length of a PACKET
5602
      if (eth_phy.tx_len != (i_length + 4))
5603
      begin
5604
        test_fail("Wrong length of the packet out from MAC");
5605
        fail = fail + 1;
5606
      end
5607
      // checking in the following if statement is performed only for first and last 64 lengths
5608
        // check transmitted TX packet data
5609
        if (i_length[0] == 0)
5610
        begin
5611
          check_tx_packet((`MEMORY_BASE + i_length[1:0]), 0, i_length, tmp);
5612
        end
5613
        else
5614
        begin
5615
          check_tx_packet(((`MEMORY_BASE + i_length[1:0]) + max_tmp), max_tmp, i_length, tmp);
5616
        end
5617
        if (tmp > 0)
5618
        begin
5619
          test_fail("Wrong data of the transmitted packet");
5620
          fail = fail + 1;
5621
        end
5622
        // check transmited TX packet CRC
5623
        if (i_length[0] == 0)
5624
          check_tx_crc(0, i_length, 1'b0, tmp); // length without CRC
5625
        else
5626
          check_tx_crc(max_tmp, i_length, 1'b0, tmp); // length without CRC
5627
        if (tmp > 0)
5628
        begin
5629
          test_fail("Wrong CRC of the transmitted packet");
5630
          fail = fail + 1;
5631
        end
5632
      // check WB INT signal
5633
      if (i_length[1:0] == 2'h0)
5634
      begin
5635
        if (wb_int !== 1'b1)
5636
        begin
5637
          `TIME; $display("*E WB INT signal should be set");
5638
          test_fail("WB INT signal should be set");
5639
          fail = fail + 1;
5640
        end
5641
      end
5642
      else
5643
      begin
5644
        if (wb_int !== 1'b0)
5645
        begin
5646
          `TIME; $display("*E WB INT signal should not be set");
5647
          test_fail("WB INT signal should not be set");
5648
          fail = fail + 1;
5649
        end
5650
      end
5651
      // check TX buffer descriptor of a packet
5652
      check_tx_bd(num_of_bd, data);
5653
      if (i_length[1] == 1'b0) // interrupt enabled
5654
      begin
5655
        if ( ((data[15:0] !== 16'h7800) && ((num_of_frames < 8) || ((num_of_frames - 8) == 127))) || // wrap bit
5656
             ((data[15:0] !== 16'h5800) && (num_of_frames >= 8) && ((num_of_frames - 8) != 127)) ) // without wrap bit
5657
        begin
5658
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
5659
          test_fail("TX buffer descriptor status is not correct");
5660
          fail = fail + 1;
5661
        end
5662
      end
5663
      else // interrupt not enabled
5664
      begin
5665
        if ( ((data[15:0] !== 16'h3800)  && ((num_of_frames < 8) || ((num_of_frames - 8) == 127))) || // wrap bit
5666
             ((data[15:0] !== 16'h1800) && (num_of_frames >= 8) && ((num_of_frames - 8) != 127)) ) // without wrap bit
5667
        begin
5668
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
5669
          test_fail("TX buffer descriptor status is not correct");
5670
          fail = fail + 1;
5671
        end
5672
      end
5673
      // clear first half of 8 frames from TX buffer descriptor 0
5674
      if (num_of_frames < 4)
5675
        clear_tx_bd(num_of_bd, num_of_bd);
5676
      // clear BD with wrap bit
5677
      if (num_of_frames == 140)
5678
        clear_tx_bd(127, 127);
5679
      // check interrupts
5680
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5681
      if ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1))
5682
      begin
5683
        if ((data & `ETH_INT_TXB) !== 1'b1)
5684
        begin
5685
          `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
5686
          test_fail("Interrupt Transmit Buffer was not set");
5687
          fail = fail + 1;
5688
        end
5689
        if ((data & (~`ETH_INT_TXB)) !== 0)
5690
        begin
5691
          `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
5692
          test_fail("Other interrupts (except Transmit Buffer) were set");
5693
          fail = fail + 1;
5694
        end
5695
      end
5696
      else
5697
      begin
5698
        if (data !== 0)
5699
        begin
5700
          `TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]);
5701
          test_fail("Any of interrupts (except Transmit Buffer) was set");
5702
          fail = fail + 1;
5703
        end
5704
      end
5705
      // clear interrupts
5706
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5707
      // check WB INT signal
5708
      if (wb_int !== 1'b0)
5709
      begin
5710
        test_fail("WB INT signal should not be set");
5711
        fail = fail + 1;
5712
      end
5713
      // INTERMEDIATE DISPLAYS
5714
      if ((i_length + 4) == (min_tmp + 7))
5715
      begin
5716
        // starting length is min_tmp, ending length is (min_tmp + 128)
5717
        $display("    pads appending to packets is NOT selected");
5718
        $display("    using only TX BD 0 out of 128 BDs assigned to TX (wrap at first BD - TX BD 0)");
5719
        $display("    ->packets with lengths from %0d (MINFL) to %0d are checked (length increasing by 1 byte)",
5720
                 min_tmp, (min_tmp + 7));
5721
        $display("    ->all packets were send from TX BD 0");
5722
        // set padding, remain the rest
5723
        wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
5724
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5725
      end
5726
      else if ((i_length + 4) == (min_tmp + 128))
5727
      begin
5728
        // starting length is min_tmp, ending length is (min_tmp + 128)
5729
        $display("    pads appending to packets is NOT selected");
5730
        $display("    using all 128 BDs assigned to TX (wrap at 128th BD - TX BD 127)");
5731
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
5732
                 (min_tmp + 8), (min_tmp + 128));
5733
        $display("    ->packets were send from TX BD %0d to TX BD %0d respectively",
5734
                 1'b0, num_of_bd);
5735
        tmp_bd = num_of_bd + 1;
5736
        // set padding, remain the rest
5737
        wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
5738
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5739
      end
5740
      else if ((i_length + 4) == (max_tmp - 16))
5741
      begin
5742
        // starting length is for +128 longer than previous ending length, while ending length is tmp_data
5743
        $display("    pads appending to packets is selected");
5744
        $display("    using all 128 BDs assigned to TX (wrap at 128th BD - TX BD 127)");
5745
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 128 bytes)",
5746
                 (min_tmp + 64 + 128), tmp_data);
5747
        if (tmp_bd > num_of_bd)
5748
          $display("    ->packets were send from TX BD %0d to TX BD 127 and from TX BD 0 to TX BD %0d respectively",
5749
                   tmp_bd, num_of_bd);
5750
        else
5751
          $display("    ->packets were send from TX BD %0d to TX BD %0d respectively",
5752
                   tmp_bd, num_of_bd);
5753
        tmp_bd = num_of_bd + 1;
5754
        // reset padding, remain the rest
5755
        wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
5756
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5757
      end
5758
      else if ((i_length + 4) == max_tmp)
5759
      begin
5760
        $display("    pads appending to packets is NOT selected");
5761
        $display("    using all 128 BDs assigned to TX (wrap at 128th BD - TX BD 127)");
5762
        $display("    ->packets with lengths from %0d to %0d (MAXFL) are checked (length increasing by 1 byte)",
5763
                 (max_tmp - (4 + 16)), max_tmp);
5764
        if (tmp_bd > num_of_bd)
5765
          $display("    ->packets were send from TX BD %0d to TX BD 127 and from TX BD 0 to TX BD %0d respectively",
5766
                   tmp_bd, num_of_bd);
5767
        else
5768
          $display("    ->packets were send from TX BD %0d to TX BD %0d respectively",
5769
                   tmp_bd, num_of_bd);
5770
      end
5771
      // set length (loop variable)
5772
      if ((i_length + 4) < (min_tmp + 128))
5773
        i_length = i_length + 1;
5774
      else if ( ((i_length + 4) == (min_tmp + 128)) && ((i_length + 4) <= (max_tmp - 256)) )
5775
        i_length = 256;
5776
      else if ( ((i_length + 4) > (min_tmp + 128)) && ((i_length + 4) <= (max_tmp - 256)) )
5777
      begin
5778
        i_length = i_length + 128;
5779
        tmp_data = i_length + 4; // last tmp_data is ending length
5780
      end
5781
      else if ( ((i_length + 4) > (max_tmp - 256)) && ((i_length + 4) < (max_tmp - 16)) )
5782
        i_length = max_tmp - (4 + 16);
5783
      else if ((i_length + 4) >= (max_tmp - 16))
5784
        i_length = i_length + 1;
5785
      else
5786
      begin
5787
        $display("*E TESTBENCH ERROR - WRONG PARAMETERS IN TESTBENCH");
5788
        #10 $stop;
5789
      end
5790
      // the number of frame transmitted
5791
      num_of_frames = num_of_frames + 1;
5792
      if ((num_of_frames <= 8) || ((num_of_frames - 8) == 128))
5793
        num_of_bd = 0;
5794
      else
5795
        num_of_bd = num_of_bd + 1;
5796
    end
5797
    // disable TX
5798
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
5799
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5800
    @(posedge wb_clk);
5801
    if(fail == 0)
5802
      test_ok;
5803
    else
5804
      fail = 0;
5805
  end
5806
 
5807
 
5808
  ////////////////////////////////////////////////////////////////////
5809
  ////                                                            ////
5810
  ////  Test transmit packets form 0 to (MINFL - 1) sizes at      ////
5811
  ////  8 TX buffer decriptors ( 10Mbps ).                        ////
5812
  ////                                                            ////
5813
  ////////////////////////////////////////////////////////////////////
5814
  if (test_num == 6) // 
5815
  begin
5816
    // TEST 6: TRANSMIT PACKETS FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 10Mbps )
5817
    test_name = "TEST 6: TRANSMIT PACKETS FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 10Mbps )";
5818
    `TIME; $display("  TEST 6: TRANSMIT PACKETS FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 10Mbps )");
5819
 
5820
    // reset MAC registers
5821
    hard_reset;
5822
    // reset MAC and MII LOGIC with soft reset
5823
    reset_mac;
5824
    reset_mii;
5825
    // set wb slave response
5826
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
5827
 
5828
    max_tmp = 0;
5829
    min_tmp = 0;
5830
    // set 8 TX buffer descriptors - must be set before TX enable
5831
    wbm_write(`ETH_TX_BD_NUM, 32'h8, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5832
    // enable TX, set full-duplex mode, padding and CRC appending
5833
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_PAD | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
5834
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5835
    // prepare two packets of MAXFL length
5836
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5837
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
5838
    min_tmp = tmp[31:16];
5839
    st_data = 8'h12;
5840
    set_tx_packet(`MEMORY_BASE, (max_tmp - 4), st_data); // length without CRC
5841
    st_data = 8'h34;
5842
    set_tx_packet((`MEMORY_BASE + max_tmp), (max_tmp - 4), st_data); // length without CRC
5843
    // check WB INT signal
5844
    if (wb_int !== 1'b0)
5845
    begin
5846
      test_fail("WB INT signal should not be set");
5847
      fail = fail + 1;
5848
    end
5849
 
5850
    // write to phy's control register for 10Mbps
5851
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
5852
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
5853
    speed = 10;
5854
 
5855
    frame_started = 0;
5856
    num_of_frames = 0;
5857
    num_of_bd = 0;
5858
    i_length = 0; // 0;
5859
    while (i_length < 70) // (min_tmp - 4))
5860
    begin
5861
      #1;
5862
      // choose generating carrier sense and collision
5863
      case (i_length[1:0])
5864
      2'h0: // Interrupt is generated
5865
      begin
5866
        // Reset_tx_bd nable interrupt generation
5867
        // unmask interrupts
5868
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
5869
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5870
        // not detect carrier sense in FD and no collision
5871
        eth_phy.carrier_sense_tx_fd_detect(0);
5872
        eth_phy.collision(0);
5873
      end
5874
      2'h1: // Interrupt is not generated
5875
      begin
5876
        // set_tx_bd enable interrupt generation
5877
        // mask interrupts
5878
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5879
        // detect carrier sense in FD and no collision
5880
        eth_phy.carrier_sense_tx_fd_detect(1);
5881
        eth_phy.collision(0);
5882
      end
5883
      2'h2: // Interrupt is not generated
5884
      begin
5885
        // set_tx_bd disable the interrupt generation
5886
        // unmask interrupts
5887
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
5888
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5889
        // not detect carrier sense in FD and set collision
5890
        eth_phy.carrier_sense_tx_fd_detect(0);
5891
        eth_phy.collision(1);
5892
      end
5893
      default: // 2'h3: // Interrupt is not generated
5894
      begin
5895
        // set_tx_bd disable the interrupt generation
5896
        // mask interrupts
5897
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
5898
        // detect carrier sense in FD and set collision
5899
        eth_phy.carrier_sense_tx_fd_detect(1);
5900
        eth_phy.collision(1);
5901
      end
5902
      endcase
5903
      #1;
5904
      // first destination address on ethernet PHY
5905
      eth_phy.set_tx_mem_addr(num_of_frames * 16);
5906
      // SET packets and wrap bit
5907
      // num_of_frames <= 9 => wrap set to TX BD 0
5908
      if (num_of_frames <= 9)
5909
      begin
5910
        tmp_len = i_length; // length of frame
5911
        tmp_bd_num = 0; // TX BD number
5912
        // if i_length[1] == 0 then enable interrupt generation otherwise disable it
5913
        // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
5914
        if (tmp_len[0] == 0)
5915
          set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
5916
        else
5917
          set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
5918
        // set wrap bit
5919
        set_tx_bd_wrap(0);
5920
      end
5921
      // 10 <= num_of_frames < 18 => wrap set to TX BD 3
5922
      else if ((num_of_frames == 10) || (num_of_frames == 14))
5923
      begin
5924
        tmp_len = i_length; // length of frame
5925
        tmp_bd_num = 0; // TX BD number
5926
        while (tmp_bd_num < 4) //
5927
        begin
5928
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
5929
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
5930
          if (tmp_len[0] == 0)
5931
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
5932
          else
5933
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
5934
          tmp_len = tmp_len + 1;
5935
          // set TX BD number
5936
          tmp_bd_num = tmp_bd_num + 1;
5937
        end
5938
        // set wrap bit
5939
        set_tx_bd_wrap(3);
5940
      end
5941
      // 18 <= num_of_frames < 28 => wrap set to TX BD 4
5942
      else if ((num_of_frames == 18) || (num_of_frames == 23))
5943
      begin
5944
        tmp_len = i_length; // length of frame
5945
        tmp_bd_num = 0; // TX BD number
5946
        while (tmp_bd_num < 5) //
5947
        begin
5948
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
5949
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
5950
          if (tmp_len[0] == 0)
5951
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
5952
          else
5953
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
5954
          tmp_len = tmp_len + 1;
5955
          // set TX BD number
5956
          tmp_bd_num = tmp_bd_num + 1;
5957
        end
5958
        // set wrap bit
5959
        set_tx_bd_wrap(4);
5960
      end
5961
      // 28 <= num_of_frames < 40 => wrap set to TX BD 5
5962
      else if ((num_of_frames == 28) || (num_of_frames == 34))
5963
      begin
5964
        tmp_len = i_length; // length of frame
5965
        tmp_bd_num = 0; // TX BD number
5966
        while (tmp_bd_num < 6) //
5967
        begin
5968
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
5969
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
5970
          if (tmp_len[0] == 0)
5971
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
5972
          else
5973
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
5974
          tmp_len = tmp_len + 1;
5975
          // set TX BD number
5976
          tmp_bd_num = tmp_bd_num + 1;
5977
        end
5978
        // set wrap bit
5979
        set_tx_bd_wrap(5);
5980
      end
5981
      // 40 <= num_of_frames < 54 => wrap set to TX BD 6
5982
      else if ((num_of_frames == 40) || (num_of_frames == 47))
5983
      begin
5984
        tmp_len = i_length; // length of frame
5985
        tmp_bd_num = 0; // TX BD number
5986
        while (tmp_bd_num < 7) //
5987
        begin
5988
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
5989
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
5990
          if (tmp_len[0] == 0)
5991
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
5992
          else
5993
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
5994
          tmp_len = tmp_len + 1;
5995
          // set TX BD number
5996
          tmp_bd_num = tmp_bd_num + 1;
5997
        end
5998
        // set wrap bit
5999
        set_tx_bd_wrap(6);
6000
      end
6001
      // 54 <= num_of_frames < 70 => wrap set to TX BD 7
6002
      else if ((num_of_frames == 54) || (num_of_frames == 62))
6003
      begin
6004
        tmp_len = i_length; // length of frame
6005
        tmp_bd_num = 0; // TX BD number
6006
        while (tmp_bd_num < 8) //
6007
        begin
6008
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
6009
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
6010
          if (tmp_len[0] == 0)
6011
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
6012
          else
6013
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
6014
          tmp_len = tmp_len + 1;
6015
          // set TX BD number
6016
          tmp_bd_num = tmp_bd_num + 1;
6017
        end
6018
        // set wrap bit
6019
        set_tx_bd_wrap(7);
6020
      end
6021
      #1;
6022
      // SET ready bit
6023
      if (num_of_frames < 10)
6024
        set_tx_bd_ready(0, 0);
6025
      else if (num_of_frames < 14)
6026
        set_tx_bd_ready((num_of_frames - 10), (num_of_frames - 10));
6027
      else if (num_of_frames < 18)
6028
        set_tx_bd_ready((num_of_frames - 14), (num_of_frames - 14));
6029
      else if (num_of_frames < 23)
6030
        set_tx_bd_ready((num_of_frames - 18), (num_of_frames - 18));
6031
      else if (num_of_frames < 28)
6032
        set_tx_bd_ready((num_of_frames - 23), (num_of_frames - 23));
6033
      else if (num_of_frames < 34)
6034
        set_tx_bd_ready((num_of_frames - 28), (num_of_frames - 28));
6035
      else if (num_of_frames < 40)
6036
        set_tx_bd_ready((num_of_frames - 34), (num_of_frames - 34));
6037
      else if (num_of_frames < 47)
6038
        set_tx_bd_ready((num_of_frames - 40), (num_of_frames - 40));
6039
      else if (num_of_frames < 54)
6040
        set_tx_bd_ready((num_of_frames - 47), (num_of_frames - 47));
6041
      else if (num_of_frames < 62)
6042
        set_tx_bd_ready((num_of_frames - 54), (num_of_frames - 54));
6043
      else if (num_of_frames < 70)
6044
        set_tx_bd_ready((num_of_frames - 62), (num_of_frames - 62));
6045
      // CHECK END OF TRANSMITION
6046
      frame_started = 0;
6047
      if (num_of_frames >= 5)
6048
        #1 check_tx_bd(num_of_bd, data);
6049
      fork
6050
      begin: fr_st
6051
        wait (MTxEn === 1'b1); // start transmit
6052
        frame_started = 1;
6053
      end
6054
      begin
6055
        repeat (30) @(posedge mtx_clk);
6056
        if (num_of_frames < 5)
6057
        begin
6058
          if (frame_started == 1)
6059
          begin
6060
            `TIME; $display("*E Frame should NOT start!");
6061
          end
6062
          disable fr_st;
6063
        end
6064
        else
6065
        begin
6066
          if (frame_started == 0)
6067
          begin
6068
            `TIME; $display("*W Frame should start!");
6069
            disable fr_st;
6070
          end
6071
        end
6072
      end
6073
      join
6074
      // check packets larger than 4 bytes
6075
      if (num_of_frames >= 5)
6076
      begin
6077
        wait (MTxEn === 1'b0); // end transmit
6078
        while (data[15] === 1)
6079
        begin
6080
          #1 check_tx_bd(num_of_bd, data);
6081
          @(posedge wb_clk);
6082
        end
6083
        repeat (1) @(posedge wb_clk);
6084
        // check length of a PACKET
6085
        if (i_length <= (min_tmp - 4))
6086
        begin
6087
          if (eth_phy.tx_len != min_tmp)
6088
          begin
6089
            test_fail("Wrong length of the packet out from MAC");
6090
            fail = fail + 1;
6091
          end
6092
        end
6093
        else
6094
        begin
6095
          if (eth_phy.tx_len != (i_length + 4))
6096
          begin
6097
            test_fail("Wrong length of the packet out from MAC");
6098
            fail = fail + 1;
6099
          end
6100
        end
6101
        // check transmitted TX packet data
6102
        if (i_length[0] == 0)
6103
        begin
6104
          #1 check_tx_packet(`MEMORY_BASE, (num_of_frames * 16), i_length, tmp);
6105
        end
6106
        else
6107
        begin
6108
          #1 check_tx_packet((`MEMORY_BASE + max_tmp), (num_of_frames * 16), i_length, tmp);
6109
        end
6110
        if (tmp > 0)
6111
        begin
6112
          test_fail("Wrong data of the transmitted packet");
6113
          fail = fail + 1;
6114
        end
6115
        // check transmited TX packet CRC
6116
        if (num_of_frames < (min_tmp - 4))
6117
          #1 check_tx_crc((num_of_frames * 16), (min_tmp - 4), 1'b0, tmp); // length without CRC
6118
        else
6119
          #1 check_tx_crc((num_of_frames * 16), i_length, 1'b0, tmp); // length without CRC
6120
        if (tmp > 0)
6121
        begin
6122
          test_fail("Wrong CRC of the transmitted packet");
6123
          fail = fail + 1;
6124
        end
6125
      end
6126
      // check WB INT signal
6127
      if ((i_length[1:0] == 2'h0) && (num_of_frames >= 5))
6128
      begin
6129
        if (wb_int !== 1'b1)
6130
        begin
6131
          `TIME; $display("*E WB INT signal should be set");
6132
          test_fail("WB INT signal should be set");
6133
          fail = fail + 1;
6134
        end
6135
      end
6136
      else
6137
      begin
6138
        if (wb_int !== 1'b0)
6139
        begin
6140
          `TIME; $display("*E WB INT signal should not be set");
6141
          test_fail("WB INT signal should not be set");
6142
          fail = fail + 1;
6143
        end
6144
      end
6145
      // check TX buffer descriptor of a packet
6146
      check_tx_bd(num_of_bd, data);
6147
      if (num_of_frames >= 5)
6148
      begin
6149
        if (i_length[1] == 1'b0) // interrupt enabled
6150
        begin
6151
          if ( (data[15:0] !== 16'h7800) && // wrap bit
6152
               (data[15:0] !== 16'h5800) ) // without wrap bit
6153
          begin
6154
            `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
6155
            test_fail("TX buffer descriptor status is not correct");
6156
            fail = fail + 1;
6157
          end
6158
        end
6159
        else // interrupt not enabled
6160
        begin
6161
          if ( (data[15:0] !== 16'h3800) && // wrap bit
6162
               (data[15:0] !== 16'h1800) ) // without wrap bit
6163
          begin
6164
            `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
6165
            test_fail("TX buffer descriptor status is not correct");
6166
            fail = fail + 1;
6167
          end
6168
        end
6169
      end
6170
      else
6171
      begin
6172
        if (data[15] !== 1'b1)
6173
        begin
6174
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
6175
          test_fail("TX buffer descriptor status is not correct");
6176
          fail = fail + 1;
6177
        end
6178
      end
6179
      // clear TX BD with wrap bit
6180
      if (num_of_frames == 63)
6181
        clear_tx_bd(16, 16);
6182
      // check interrupts
6183
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6184
      if ( ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1)) && (num_of_frames >= 5) )
6185
      begin
6186
        if ((data & `ETH_INT_TXB) !== 1'b1)
6187
        begin
6188
          `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
6189
          test_fail("Interrupt Transmit Buffer was not set");
6190
          fail = fail + 1;
6191
        end
6192
        if ((data & (~`ETH_INT_TXB)) !== 0)
6193
        begin
6194
          `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
6195
          test_fail("Other interrupts (except Transmit Buffer) were set");
6196
          fail = fail + 1;
6197
        end
6198
      end
6199
      else
6200
      begin
6201
        if (data !== 0)
6202
        begin
6203
          `TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]);
6204
          test_fail("Any of interrupts (except Transmit Buffer) was set");
6205
          fail = fail + 1;
6206
        end
6207
      end
6208
      // clear interrupts
6209
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6210
      // check WB INT signal
6211
      if (wb_int !== 1'b0)
6212
      begin
6213
        test_fail("WB INT signal should not be set");
6214
        fail = fail + 1;
6215
      end
6216
      // INTERMEDIATE DISPLAYS
6217
      if (i_length == 3)
6218
      begin
6219
        $display("    pads appending to packets is selected");
6220
        $display("    using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)");
6221
        $display("    ->packets with lengths from %0d to %0d are not transmitted (length increasing by 1 byte)",
6222
                 0, 3);
6223
      end
6224
      else if (i_length == 9)
6225
      begin
6226
        $display("    using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)");
6227
        $display("    ->packet with length 4 is not transmitted (length increasing by 1 byte)");
6228
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
6229
                 5, 9);
6230
      end
6231
      else if (i_length == 17)
6232
      begin
6233
        $display("    using 4 BDs out of 8 BDs assigned to TX (wrap at 4th BD - TX BD 3)");
6234
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
6235
                 10, 17);
6236
      end
6237
      else if (i_length == 27)
6238
      begin
6239
        $display("    using 5 BDs out of 8 BDs assigned to TX (wrap at 5th BD - TX BD 4)");
6240
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
6241
                 18, 27);
6242
      end
6243
      else if (i_length == 40)
6244
      begin
6245
        $display("    using 6 BDs out of 8 BDs assigned to TX (wrap at 6th BD - TX BD 5)");
6246
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
6247
                 28, 40);
6248
      end
6249
      else if (i_length == 54)
6250
      begin
6251
        $display("    using 7 BDs out of 8 BDs assigned to TX (wrap at 7th BD - TX BD 6)");
6252
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
6253
                 41, 54);
6254
      end
6255
      else if (i_length == 69)
6256
      begin
6257
        $display("    using 8 BDs out of 8 BDs assigned to TX (wrap at 8th BD - TX BD 7)");
6258
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
6259
                 55, 69);
6260
      end
6261
      // set length (loop variable)
6262
      i_length = i_length + 1;
6263
      // the number of frame transmitted
6264
      num_of_frames = num_of_frames + 1;
6265
      if (/*(num_of_frames == 2) || (num_of_frames == 4) || (num_of_frames == 7) ||*/ (num_of_frames <= 10) ||
6266
          (num_of_frames == 14) || (num_of_frames == 18) || (num_of_frames == 23) || (num_of_frames == 28) ||
6267
          (num_of_frames == 34) || (num_of_frames == 40) || (num_of_frames == 47) ||
6268
          (num_of_frames == 54) || (num_of_frames == 62))
6269
        num_of_bd = 0;
6270
      else
6271
        num_of_bd = num_of_bd + 1;
6272
    end
6273
    // disable TX
6274
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
6275
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6276
    @(posedge wb_clk);
6277
    if(fail == 0)
6278
      test_ok;
6279
    else
6280
      fail = 0;
6281
  end
6282
 
6283
 
6284
  ////////////////////////////////////////////////////////////////////
6285
  ////                                                            ////
6286
  ////  Test transmit packets form 0 to (MINFL - 1) sizes at      ////
6287
  ////  8 TX buffer decriptors ( 100Mbps ).                       ////
6288
  ////                                                            ////
6289
  ////////////////////////////////////////////////////////////////////
6290
  if (test_num == 7) // 
6291
  begin
6292
    // TEST 7: TRANSMIT PACKETS FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 100Mbps )
6293
    test_name = "TEST 7: TRANSMIT PACKETS FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 100Mbps )";
6294
    `TIME; $display("  TEST 7: TRANSMIT PACKETS FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 100Mbps )");
6295
 
6296
    // reset MAC registers
6297
    hard_reset;
6298
    // reset MAC and MII LOGIC with soft reset
6299
    reset_mac;
6300
    reset_mii;
6301
    // set wb slave response
6302
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
6303
 
6304
    max_tmp = 0;
6305
    min_tmp = 0;
6306
    // set 8 TX buffer descriptors - must be set before TX enable
6307
    wbm_write(`ETH_TX_BD_NUM, 32'h8, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6308
    // enable TX, set full-duplex mode, padding and CRC appending
6309
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_PAD | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
6310
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6311
    // prepare two packets of MAXFL length
6312
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6313
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
6314
    min_tmp = tmp[31:16];
6315
    st_data = 8'h12;
6316
    set_tx_packet(`MEMORY_BASE, (max_tmp - 4), st_data); // length without CRC
6317
    st_data = 8'h34;
6318
    set_tx_packet((`MEMORY_BASE + max_tmp), (max_tmp - 4), st_data); // length without CRC
6319
    // check WB INT signal
6320
    if (wb_int !== 1'b0)
6321
    begin
6322
      test_fail("WB INT signal should not be set");
6323
      fail = fail + 1;
6324
    end
6325
 
6326
    // write to phy's control register for 100Mbps
6327
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
6328
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
6329
    speed = 100;
6330
 
6331
    frame_started = 0;
6332
    num_of_frames = 0;
6333
    num_of_bd = 0;
6334
    i_length = 0; // 0;
6335
    while (i_length < 70) // (min_tmp - 4))
6336
    begin
6337
      #1;
6338
      // choose generating carrier sense and collision
6339
      case (i_length[1:0])
6340
      2'h0: // Interrupt is generated
6341
      begin
6342
        // Reset_tx_bd nable interrupt generation
6343
        // unmask interrupts
6344
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
6345
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6346
        // not detect carrier sense in FD and no collision
6347
        eth_phy.carrier_sense_tx_fd_detect(0);
6348
        eth_phy.collision(0);
6349
      end
6350
      2'h1: // Interrupt is not generated
6351
      begin
6352
        // set_tx_bd enable interrupt generation
6353
        // mask interrupts
6354
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6355
        // detect carrier sense in FD and no collision
6356
        eth_phy.carrier_sense_tx_fd_detect(1);
6357
        eth_phy.collision(0);
6358
      end
6359
      2'h2: // Interrupt is not generated
6360
      begin
6361
        // set_tx_bd disable the interrupt generation
6362
        // unmask interrupts
6363
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
6364
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6365
        // not detect carrier sense in FD and set collision
6366
        eth_phy.carrier_sense_tx_fd_detect(0);
6367
        eth_phy.collision(1);
6368
      end
6369
      default: // 2'h3: // Interrupt is not generated
6370
      begin
6371
        // set_tx_bd disable the interrupt generation
6372
        // mask interrupts
6373
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6374
        // detect carrier sense in FD and set collision
6375
        eth_phy.carrier_sense_tx_fd_detect(1);
6376
        eth_phy.collision(1);
6377
      end
6378
      endcase
6379
      #1;
6380
      // first destination address on ethernet PHY
6381
      eth_phy.set_tx_mem_addr(num_of_frames * 16);
6382
      // SET packets and wrap bit
6383
      // num_of_frames <= 9 => wrap set to TX BD 0
6384
      if (num_of_frames <= 9)
6385
      begin
6386
        tmp_len = i_length; // length of frame
6387
        tmp_bd_num = 0; // TX BD number
6388
        // if i_length[1] == 0 then enable interrupt generation otherwise disable it
6389
        // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
6390
        if (tmp_len[0] == 0)
6391
          set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
6392
        else
6393
          set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
6394
        // set wrap bit
6395
        set_tx_bd_wrap(0);
6396
      end
6397
      // 10 <= num_of_frames < 18 => wrap set to TX BD 3
6398
      else if ((num_of_frames == 10) || (num_of_frames == 14))
6399
      begin
6400
        tmp_len = i_length; // length of frame
6401
        tmp_bd_num = 0; // TX BD number
6402
        while (tmp_bd_num < 4) //
6403
        begin
6404
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
6405
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
6406
          if (tmp_len[0] == 0)
6407
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
6408
          else
6409
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
6410
          tmp_len = tmp_len + 1;
6411
          // set TX BD number
6412
          tmp_bd_num = tmp_bd_num + 1;
6413
        end
6414
        // set wrap bit
6415
        set_tx_bd_wrap(3);
6416
      end
6417
      // 18 <= num_of_frames < 28 => wrap set to TX BD 4
6418
      else if ((num_of_frames == 18) || (num_of_frames == 23))
6419
      begin
6420
        tmp_len = i_length; // length of frame
6421
        tmp_bd_num = 0; // TX BD number
6422
        while (tmp_bd_num < 5) //
6423
        begin
6424
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
6425
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
6426
          if (tmp_len[0] == 0)
6427
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
6428
          else
6429
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
6430
          tmp_len = tmp_len + 1;
6431
          // set TX BD number
6432
          tmp_bd_num = tmp_bd_num + 1;
6433
        end
6434
        // set wrap bit
6435
        set_tx_bd_wrap(4);
6436
      end
6437
      // 28 <= num_of_frames < 40 => wrap set to TX BD 5
6438
      else if ((num_of_frames == 28) || (num_of_frames == 34))
6439
      begin
6440
        tmp_len = i_length; // length of frame
6441
        tmp_bd_num = 0; // TX BD number
6442
        while (tmp_bd_num < 6) //
6443
        begin
6444
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
6445
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
6446
          if (tmp_len[0] == 0)
6447
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
6448
          else
6449
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
6450
          tmp_len = tmp_len + 1;
6451
          // set TX BD number
6452
          tmp_bd_num = tmp_bd_num + 1;
6453
        end
6454
        // set wrap bit
6455
        set_tx_bd_wrap(5);
6456
      end
6457
      // 40 <= num_of_frames < 54 => wrap set to TX BD 6
6458
      else if ((num_of_frames == 40) || (num_of_frames == 47))
6459
      begin
6460
        tmp_len = i_length; // length of frame
6461
        tmp_bd_num = 0; // TX BD number
6462
        while (tmp_bd_num < 7) //
6463
        begin
6464
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
6465
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
6466
          if (tmp_len[0] == 0)
6467
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
6468
          else
6469
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
6470
          tmp_len = tmp_len + 1;
6471
          // set TX BD number
6472
          tmp_bd_num = tmp_bd_num + 1;
6473
        end
6474
        // set wrap bit
6475
        set_tx_bd_wrap(6);
6476
      end
6477
      // 54 <= num_of_frames < 70 => wrap set to TX BD 7
6478
      else if ((num_of_frames == 54) || (num_of_frames == 62))
6479
      begin
6480
        tmp_len = i_length; // length of frame
6481
        tmp_bd_num = 0; // TX BD number
6482
        while (tmp_bd_num < 8) //
6483
        begin
6484
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
6485
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
6486
          if (tmp_len[0] == 0)
6487
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
6488
          else
6489
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
6490
          tmp_len = tmp_len + 1;
6491
          // set TX BD number
6492
          tmp_bd_num = tmp_bd_num + 1;
6493
        end
6494
        // set wrap bit
6495
        set_tx_bd_wrap(7);
6496
      end
6497
      #1;
6498
      // SET ready bit
6499
      if (num_of_frames < 10)
6500
        set_tx_bd_ready(0, 0);
6501
      else if (num_of_frames < 14)
6502
        set_tx_bd_ready((num_of_frames - 10), (num_of_frames - 10));
6503
      else if (num_of_frames < 18)
6504
        set_tx_bd_ready((num_of_frames - 14), (num_of_frames - 14));
6505
      else if (num_of_frames < 23)
6506
        set_tx_bd_ready((num_of_frames - 18), (num_of_frames - 18));
6507
      else if (num_of_frames < 28)
6508
        set_tx_bd_ready((num_of_frames - 23), (num_of_frames - 23));
6509
      else if (num_of_frames < 34)
6510
        set_tx_bd_ready((num_of_frames - 28), (num_of_frames - 28));
6511
      else if (num_of_frames < 40)
6512
        set_tx_bd_ready((num_of_frames - 34), (num_of_frames - 34));
6513
      else if (num_of_frames < 47)
6514
        set_tx_bd_ready((num_of_frames - 40), (num_of_frames - 40));
6515
      else if (num_of_frames < 54)
6516
        set_tx_bd_ready((num_of_frames - 47), (num_of_frames - 47));
6517
      else if (num_of_frames < 62)
6518
        set_tx_bd_ready((num_of_frames - 54), (num_of_frames - 54));
6519
      else if (num_of_frames < 70)
6520
        set_tx_bd_ready((num_of_frames - 62), (num_of_frames - 62));
6521
      // CHECK END OF TRANSMITION
6522
      frame_started = 0;
6523
      if (num_of_frames >= 5)
6524
        #1 check_tx_bd(num_of_bd, data);
6525
      fork
6526
      begin: fr_st1
6527
        wait (MTxEn === 1'b1); // start transmit
6528
        frame_started = 1;
6529
      end
6530
      begin
6531
        repeat (30) @(posedge mtx_clk);
6532
        if (num_of_frames < 5)
6533
        begin
6534
          if (frame_started == 1)
6535
          begin
6536
            `TIME; $display("*E Frame should NOT start!");
6537
          end
6538
          disable fr_st1;
6539
        end
6540
        else
6541
        begin
6542
          if (frame_started == 0)
6543
          begin
6544
            `TIME; $display("*W Frame should start!");
6545
            disable fr_st1;
6546
          end
6547
        end
6548
      end
6549
      join
6550
      // check packets larger than 4 bytes
6551
      if (num_of_frames >= 5)
6552
      begin
6553
        wait (MTxEn === 1'b0); // end transmit
6554
        while (data[15] === 1)
6555
        begin
6556
          #1 check_tx_bd(num_of_bd, data);
6557
          @(posedge wb_clk);
6558
        end
6559
        repeat (1) @(posedge wb_clk);
6560
        // check length of a PACKET
6561
        if (i_length <= (min_tmp - 4))
6562
        begin
6563
          if (eth_phy.tx_len != min_tmp)
6564
          begin
6565
            test_fail("Wrong length of the packet out from MAC");
6566
            fail = fail + 1;
6567
          end
6568
        end
6569
        else
6570
        begin
6571
          if (eth_phy.tx_len != (i_length + 4))
6572
          begin
6573
            test_fail("Wrong length of the packet out from MAC");
6574
            fail = fail + 1;
6575
          end
6576
        end
6577
        // check transmitted TX packet data
6578
        if (i_length[0] == 0)
6579
        begin
6580
          #1 check_tx_packet(`MEMORY_BASE, (num_of_frames * 16), i_length, tmp);
6581
        end
6582
        else
6583
        begin
6584
          #1 check_tx_packet((`MEMORY_BASE + max_tmp), (num_of_frames * 16), i_length, tmp);
6585
        end
6586
        if (tmp > 0)
6587
        begin
6588
          test_fail("Wrong data of the transmitted packet");
6589
          fail = fail + 1;
6590
        end
6591
        // check transmited TX packet CRC
6592
        if (num_of_frames < (min_tmp - 4))
6593
          #1 check_tx_crc((num_of_frames * 16), (min_tmp - 4), 1'b0, tmp); // length without CRC
6594
        else
6595
          #1 check_tx_crc((num_of_frames * 16), i_length, 1'b0, tmp); // length without CRC
6596
        if (tmp > 0)
6597
        begin
6598
          test_fail("Wrong CRC of the transmitted packet");
6599
          fail = fail + 1;
6600
        end
6601
      end
6602
      // check WB INT signal
6603
      if ((i_length[1:0] == 2'h0) && (num_of_frames >= 5))
6604
      begin
6605
        if (wb_int !== 1'b1)
6606
        begin
6607
          `TIME; $display("*E WB INT signal should be set");
6608
          test_fail("WB INT signal should be set");
6609
          fail = fail + 1;
6610
        end
6611
      end
6612
      else
6613
      begin
6614
        if (wb_int !== 1'b0)
6615
        begin
6616
          `TIME; $display("*E WB INT signal should not be set");
6617
          test_fail("WB INT signal should not be set");
6618
          fail = fail + 1;
6619
        end
6620
      end
6621
      // check TX buffer descriptor of a packet
6622
      check_tx_bd(num_of_bd, data);
6623
      if (num_of_frames >= 5)
6624
      begin
6625
        if (i_length[1] == 1'b0) // interrupt enabled
6626
        begin
6627
          if ( (data[15:0] !== 16'h7800) && // wrap bit
6628
               (data[15:0] !== 16'h5800) ) // without wrap bit
6629
          begin
6630
            `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
6631
            test_fail("TX buffer descriptor status is not correct");
6632
            fail = fail + 1;
6633
          end
6634
        end
6635
        else // interrupt not enabled
6636
        begin
6637
          if ( (data[15:0] !== 16'h3800) && // wrap bit
6638
               (data[15:0] !== 16'h1800) ) // without wrap bit
6639
          begin
6640
            `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
6641
            test_fail("TX buffer descriptor status is not correct");
6642
            fail = fail + 1;
6643
          end
6644
        end
6645
      end
6646
      else
6647
      begin
6648
        if (data[15] !== 1'b1)
6649
        begin
6650
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
6651
          test_fail("TX buffer descriptor status is not correct");
6652
          fail = fail + 1;
6653
        end
6654
      end
6655
      // clear TX BD with wrap bit
6656
      if (num_of_frames == 63)
6657
        clear_tx_bd(16, 16);
6658
      // check interrupts
6659
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6660
      if ( ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1)) && (num_of_frames >= 5) )
6661
      begin
6662
        if ((data & `ETH_INT_TXB) !== 1'b1)
6663
        begin
6664
          `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
6665
          test_fail("Interrupt Transmit Buffer was not set");
6666
          fail = fail + 1;
6667
        end
6668
        if ((data & (~`ETH_INT_TXB)) !== 0)
6669
        begin
6670
          `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
6671
          test_fail("Other interrupts (except Transmit Buffer) were set");
6672
          fail = fail + 1;
6673
        end
6674
      end
6675
      else
6676
      begin
6677
        if (data !== 0)
6678
        begin
6679
          `TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]);
6680
          test_fail("Any of interrupts (except Transmit Buffer) was set");
6681
          fail = fail + 1;
6682
        end
6683
      end
6684
      // clear interrupts
6685
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6686
      // check WB INT signal
6687
      if (wb_int !== 1'b0)
6688
      begin
6689
        test_fail("WB INT signal should not be set");
6690
        fail = fail + 1;
6691
      end
6692
      // INTERMEDIATE DISPLAYS
6693
      if (i_length == 3)
6694
      begin
6695
        $display("    pads appending to packets is selected");
6696
        $display("    using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)");
6697
        $display("    ->packets with lengths from %0d to %0d are not transmitted (length increasing by 1 byte)",
6698
                 0, 3);
6699
      end
6700
      else if (i_length == 9)
6701
      begin
6702
        $display("    using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)");
6703
        $display("    ->packet with length 4 is not transmitted (length increasing by 1 byte)");
6704
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
6705
                 5, 9);
6706
      end
6707
      else if (i_length == 17)
6708
      begin
6709
        $display("    using 4 BDs out of 8 BDs assigned to TX (wrap at 4th BD - TX BD 3)");
6710
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
6711
                 10, 17);
6712
      end
6713
      else if (i_length == 27)
6714
      begin
6715
        $display("    using 5 BDs out of 8 BDs assigned to TX (wrap at 5th BD - TX BD 4)");
6716
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
6717
                 18, 27);
6718
      end
6719
      else if (i_length == 40)
6720
      begin
6721
        $display("    using 6 BDs out of 8 BDs assigned to TX (wrap at 6th BD - TX BD 5)");
6722
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
6723
                 28, 40);
6724
      end
6725
      else if (i_length == 54)
6726
      begin
6727
        $display("    using 7 BDs out of 8 BDs assigned to TX (wrap at 7th BD - TX BD 6)");
6728
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
6729
                 41, 54);
6730
      end
6731
      else if (i_length == 69)
6732
      begin
6733
        $display("    using 8 BDs out of 8 BDs assigned to TX (wrap at 8th BD - TX BD 7)");
6734
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
6735
                 55, 69);
6736
      end
6737
      // set length (loop variable)
6738
      i_length = i_length + 1;
6739
      // the number of frame transmitted
6740
      num_of_frames = num_of_frames + 1;
6741
      if (/*(num_of_frames == 2) || (num_of_frames == 4) || (num_of_frames == 7) ||*/ (num_of_frames <= 10) ||
6742
          (num_of_frames == 14) || (num_of_frames == 18) || (num_of_frames == 23) || (num_of_frames == 28) ||
6743
          (num_of_frames == 34) || (num_of_frames == 40) || (num_of_frames == 47) ||
6744
          (num_of_frames == 54) || (num_of_frames == 62))
6745
        num_of_bd = 0;
6746
      else
6747
        num_of_bd = num_of_bd + 1;
6748
    end
6749
    // disable TX
6750
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
6751
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6752
    @(posedge wb_clk);
6753
    if(fail == 0)
6754
      test_ok;
6755
    else
6756
      fail = 0;
6757
  end
6758
 
6759
 
6760
  ////////////////////////////////////////////////////////////////////
6761
  ////                                                            ////
6762
  ////  Test no transmit packets (no pads) form 0 to (MINFL - 1)  ////
6763
  ////  sizes at 8 TX buffer decriptors ( 10Mbps ).               ////
6764
  ////                                                            ////
6765
  ////////////////////////////////////////////////////////////////////
6766
  if (test_num == 8) // 
6767
  begin
6768
    // TEST 8: NO TRANSMIT PACKETS (NO PADs) FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 10Mbps )
6769
    test_name = "TEST 8: NO TRANSMIT PACKETS (NO PADs) FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 10Mbps )";
6770
    `TIME; $display("  TEST 8: NO TRANSMIT PACKETS (NO PADs) FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 10Mbps )");
6771
 
6772
    // reset MAC registers
6773
    hard_reset;
6774
    // reset MAC and MII LOGIC with soft reset
6775
    reset_mac;
6776
    reset_mii;
6777
    // set wb slave response
6778
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
6779
 
6780
    max_tmp = 0;
6781
    min_tmp = 0;
6782
    // set 8 TX buffer descriptors - must be set before TX enable
6783
    wbm_write(`ETH_TX_BD_NUM, 32'h8, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6784
    // enable TX, set full-duplex mode, padding and CRC appending
6785
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_PAD | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
6786
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6787
    // prepare two packets of MAXFL length
6788
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6789
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
6790
    min_tmp = tmp[31:16];
6791
    st_data = 8'h12;
6792
    set_tx_packet(`MEMORY_BASE, (max_tmp - 4), st_data); // length without CRC
6793
    st_data = 8'h34;
6794
    set_tx_packet((`MEMORY_BASE + max_tmp), (max_tmp - 4), st_data); // length without CRC
6795
    // check WB INT signal
6796
    if (wb_int !== 1'b0)
6797
    begin
6798
      test_fail("WB INT signal should not be set");
6799
      fail = fail + 1;
6800
    end
6801
 
6802
    // write to phy's control register for 10Mbps
6803
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
6804
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
6805
    speed = 10;
6806
 
6807
    frame_started = 0;
6808
    num_of_frames = 0;
6809
    num_of_bd = 0;
6810
    i_length = 0; // 0;
6811
    while (i_length < 70) // (min_tmp - 4))
6812
    begin
6813
      #1;
6814
      // choose generating carrier sense and collision
6815
      case (i_length[1:0])
6816
      2'h0: // Interrupt is generated
6817
      begin
6818
        // Reset_tx_bd nable interrupt generation
6819
        // unmask interrupts
6820
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
6821
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6822
        // not detect carrier sense in FD and no collision
6823
        eth_phy.carrier_sense_tx_fd_detect(0);
6824
        eth_phy.collision(0);
6825
      end
6826
      2'h1: // Interrupt is not generated
6827
      begin
6828
        // set_tx_bd enable interrupt generation
6829
        // mask interrupts
6830
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6831
        // detect carrier sense in FD and no collision
6832
        eth_phy.carrier_sense_tx_fd_detect(1);
6833
        eth_phy.collision(0);
6834
      end
6835
      2'h2: // Interrupt is not generated
6836
      begin
6837
        // set_tx_bd disable the interrupt generation
6838
        // unmask interrupts
6839
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
6840
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6841
        // not detect carrier sense in FD and set collision
6842
        eth_phy.carrier_sense_tx_fd_detect(0);
6843
        eth_phy.collision(1);
6844
      end
6845
      default: // 2'h3: // Interrupt is not generated
6846
      begin
6847
        // set_tx_bd disable the interrupt generation
6848
        // mask interrupts
6849
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
6850
        // detect carrier sense in FD and set collision
6851
        eth_phy.carrier_sense_tx_fd_detect(1);
6852
        eth_phy.collision(1);
6853
      end
6854
      endcase
6855
      #1;
6856
      // first destination address on ethernet PHY
6857
      eth_phy.set_tx_mem_addr(num_of_frames * 16);
6858
      // SET packets and wrap bit
6859
      // num_of_frames <= 9 => wrap set to TX BD 0
6860
      if (num_of_frames <= 9)
6861
      begin
6862
        tmp_len = i_length; // length of frame
6863
        tmp_bd_num = 0; // TX BD number
6864
        // if i_length[1] == 0 then enable interrupt generation otherwise disable it
6865
        // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
6866
        if (tmp_len[0] == 0)
6867
          set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
6868
        else
6869
          set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
6870
        // set wrap bit
6871
        set_tx_bd_wrap(0);
6872
      end
6873
      // 10 <= num_of_frames < 18 => wrap set to TX BD 3
6874
      else if ((num_of_frames == 10) || (num_of_frames == 14))
6875
      begin
6876
        tmp_len = i_length; // length of frame
6877
        tmp_bd_num = 0; // TX BD number
6878
        while (tmp_bd_num < 4) //
6879
        begin
6880
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
6881
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
6882
          if (tmp_len[0] == 0)
6883
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
6884
          else
6885
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
6886
          tmp_len = tmp_len + 1;
6887
          // set TX BD number
6888
          tmp_bd_num = tmp_bd_num + 1;
6889
        end
6890
        // set wrap bit
6891
        set_tx_bd_wrap(3);
6892
      end
6893
      // 18 <= num_of_frames < 28 => wrap set to TX BD 4
6894
      else if ((num_of_frames == 18) || (num_of_frames == 23))
6895
      begin
6896
        tmp_len = i_length; // length of frame
6897
        tmp_bd_num = 0; // TX BD number
6898
        while (tmp_bd_num < 5) //
6899
        begin
6900
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
6901
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
6902
          if (tmp_len[0] == 0)
6903
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
6904
          else
6905
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
6906
          tmp_len = tmp_len + 1;
6907
          // set TX BD number
6908
          tmp_bd_num = tmp_bd_num + 1;
6909
        end
6910
        // set wrap bit
6911
        set_tx_bd_wrap(4);
6912
      end
6913
      // 28 <= num_of_frames < 40 => wrap set to TX BD 5
6914
      else if ((num_of_frames == 28) || (num_of_frames == 34))
6915
      begin
6916
        tmp_len = i_length; // length of frame
6917
        tmp_bd_num = 0; // TX BD number
6918
        while (tmp_bd_num < 6) //
6919
        begin
6920
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
6921
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
6922
          if (tmp_len[0] == 0)
6923
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
6924
          else
6925
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
6926
          tmp_len = tmp_len + 1;
6927
          // set TX BD number
6928
          tmp_bd_num = tmp_bd_num + 1;
6929
        end
6930
        // set wrap bit
6931
        set_tx_bd_wrap(5);
6932
      end
6933
      // 40 <= num_of_frames < 54 => wrap set to TX BD 6
6934
      else if ((num_of_frames == 40) || (num_of_frames == 47))
6935
      begin
6936
        tmp_len = i_length; // length of frame
6937
        tmp_bd_num = 0; // TX BD number
6938
        while (tmp_bd_num < 7) //
6939
        begin
6940
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
6941
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
6942
          if (tmp_len[0] == 0)
6943
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
6944
          else
6945
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
6946
          tmp_len = tmp_len + 1;
6947
          // set TX BD number
6948
          tmp_bd_num = tmp_bd_num + 1;
6949
        end
6950
        // set wrap bit
6951
        set_tx_bd_wrap(6);
6952
      end
6953
      // 54 <= num_of_frames < 70 => wrap set to TX BD 7
6954
      else if ((num_of_frames == 54) || (num_of_frames == 62))
6955
      begin
6956
        tmp_len = i_length; // length of frame
6957
        tmp_bd_num = 0; // TX BD number
6958
        while (tmp_bd_num < 8) //
6959
        begin
6960
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
6961
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
6962
          if (tmp_len[0] == 0)
6963
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
6964
          else
6965
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
6966
          tmp_len = tmp_len + 1;
6967
          // set TX BD number
6968
          tmp_bd_num = tmp_bd_num + 1;
6969
        end
6970
        // set wrap bit
6971
        set_tx_bd_wrap(7);
6972
      end
6973
      #1;
6974
      // SET ready bit
6975
      if (num_of_frames < 10)
6976
        set_tx_bd_ready(0, 0);
6977
      else if (num_of_frames < 14)
6978
        set_tx_bd_ready((num_of_frames - 10), (num_of_frames - 10));
6979
      else if (num_of_frames < 18)
6980
        set_tx_bd_ready((num_of_frames - 14), (num_of_frames - 14));
6981
      else if (num_of_frames < 23)
6982
        set_tx_bd_ready((num_of_frames - 18), (num_of_frames - 18));
6983
      else if (num_of_frames < 28)
6984
        set_tx_bd_ready((num_of_frames - 23), (num_of_frames - 23));
6985
      else if (num_of_frames < 34)
6986
        set_tx_bd_ready((num_of_frames - 28), (num_of_frames - 28));
6987
      else if (num_of_frames < 40)
6988
        set_tx_bd_ready((num_of_frames - 34), (num_of_frames - 34));
6989
      else if (num_of_frames < 47)
6990
        set_tx_bd_ready((num_of_frames - 40), (num_of_frames - 40));
6991
      else if (num_of_frames < 54)
6992
        set_tx_bd_ready((num_of_frames - 47), (num_of_frames - 47));
6993
      else if (num_of_frames < 62)
6994
        set_tx_bd_ready((num_of_frames - 54), (num_of_frames - 54));
6995
      else if (num_of_frames < 70)
6996
        set_tx_bd_ready((num_of_frames - 62), (num_of_frames - 62));
6997
      // CHECK END OF TRANSMITION
6998
      frame_started = 0;
6999
      if (num_of_frames >= 5)
7000
        #1 check_tx_bd(num_of_bd, data);
7001
      fork
7002
      begin: fr_st2
7003
        wait (MTxEn === 1'b1); // start transmit
7004
        frame_started = 1;
7005
      end
7006
      begin
7007
        repeat (30) @(posedge mtx_clk);
7008
        if (num_of_frames < 5)
7009
        begin
7010
          if (frame_started == 1)
7011
          begin
7012
            `TIME; $display("*E Frame should NOT start!");
7013
          end
7014
          disable fr_st2;
7015
        end
7016
        else
7017
        begin
7018
          if (frame_started == 0)
7019
          begin
7020
            `TIME; $display("*W Frame should start!");
7021
            disable fr_st2;
7022
          end
7023
        end
7024
      end
7025
      join
7026
      // check packets larger than 4 bytes
7027
      if (num_of_frames >= 5)
7028
      begin
7029
        wait (MTxEn === 1'b0); // end transmit
7030
        while (data[15] === 1)
7031
        begin
7032
          #1 check_tx_bd(num_of_bd, data);
7033
          @(posedge wb_clk);
7034
        end
7035
        repeat (1) @(posedge wb_clk);
7036
        // check length of a PACKET
7037
        if (eth_phy.tx_len != (i_length + 4))
7038
        begin
7039
          `TIME; $display("*E Wrong length of the packet out from MAC");
7040
          test_fail("Wrong length of the packet out from MAC");
7041
          fail = fail + 1;
7042
        end
7043
        // check transmitted TX packet data
7044
        if (i_length[0] == 0)
7045
        begin
7046
          #1 check_tx_packet(`MEMORY_BASE, (num_of_frames * 16), i_length, tmp);
7047
        end
7048
        else
7049
        begin
7050
          #1 check_tx_packet((`MEMORY_BASE + max_tmp), (num_of_frames * 16), i_length, tmp);
7051
        end
7052
        if (tmp > 0)
7053
        begin
7054
          test_fail("Wrong data of the transmitted packet");
7055
          fail = fail + 1;
7056
        end
7057
        // check transmited TX packet CRC
7058
        #1 check_tx_crc((num_of_frames * 16), (eth_phy.tx_len - 4), 1'b0, tmp); // length without CRC
7059
        if (tmp > 0)
7060
        begin
7061
          test_fail("Wrong CRC of the transmitted packet");
7062
          fail = fail + 1;
7063
        end
7064
      end
7065
      // check WB INT signal
7066
      if ((i_length[1:0] == 2'h0) && (num_of_frames >= 5))
7067
      begin
7068
        if (wb_int !== 1'b1)
7069
        begin
7070
          `TIME; $display("*E WB INT signal should be set");
7071
          test_fail("WB INT signal should be set");
7072
          fail = fail + 1;
7073
        end
7074
      end
7075
      else
7076
      begin
7077
        if (wb_int !== 1'b0)
7078
        begin
7079
          `TIME; $display("*E WB INT signal should not be set");
7080
          test_fail("WB INT signal should not be set");
7081
          fail = fail + 1;
7082
        end
7083
      end
7084
      // check TX buffer descriptor of a packet
7085
      check_tx_bd(num_of_bd, data);
7086
      if (num_of_frames >= 5)
7087
      begin
7088
        if (i_length[1] == 1'b0) // interrupt enabled
7089
        begin
7090
          if ( (data[15:0] !== 16'h7800) && // wrap bit
7091
               (data[15:0] !== 16'h5800) ) // without wrap bit
7092
          begin
7093
            `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
7094
            test_fail("TX buffer descriptor status is not correct");
7095
            fail = fail + 1;
7096
          end
7097
        end
7098
        else // interrupt not enabled
7099
        begin
7100
          if ( (data[15:0] !== 16'h3800) && // wrap bit
7101
               (data[15:0] !== 16'h1800) ) // without wrap bit
7102
          begin
7103
            `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
7104
            test_fail("TX buffer descriptor status is not correct");
7105
            fail = fail + 1;
7106
          end
7107
        end
7108
      end
7109
      else
7110
      begin
7111
        if (data[15] !== 1'b1)
7112
        begin
7113
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
7114
          test_fail("TX buffer descriptor status is not correct");
7115
          fail = fail + 1;
7116
        end
7117
      end
7118
      // clear TX BD with wrap bit
7119
      if (num_of_frames == 63)
7120
        clear_tx_bd(16, 16);
7121
      // check interrupts
7122
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7123
      if ( ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1)) && (num_of_frames >= 5) )
7124
      begin
7125
        if ((data & `ETH_INT_TXB) !== 1'b1)
7126
        begin
7127
          `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
7128
          test_fail("Interrupt Transmit Buffer was not set");
7129
          fail = fail + 1;
7130
        end
7131
        if ((data & (~`ETH_INT_TXB)) !== 0)
7132
        begin
7133
          `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
7134
          test_fail("Other interrupts (except Transmit Buffer) were set");
7135
          fail = fail + 1;
7136
        end
7137
      end
7138
      else
7139
      begin
7140
        if (data !== 0)
7141
        begin
7142
          `TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]);
7143
          test_fail("Any of interrupts (except Transmit Buffer) was set");
7144
          fail = fail + 1;
7145
        end
7146
      end
7147
      // clear interrupts
7148
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7149
      // check WB INT signal
7150
      if (wb_int !== 1'b0)
7151
      begin
7152
        test_fail("WB INT signal should not be set");
7153
        fail = fail + 1;
7154
      end
7155
      // INTERMEDIATE DISPLAYS
7156
      if (i_length == 3)
7157
      begin
7158
        $display("    pads appending to packets is selected");
7159
        $display("    using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)");
7160
        $display("    ->packets with lengths from %0d to %0d are not transmitted (length increasing by 1 byte)",
7161
                 0, 3);
7162
      end
7163
      else if (i_length == 9)
7164
      begin
7165
        $display("    using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)");
7166
        $display("    ->packet with length 4 is not transmitted (length increasing by 1 byte)");
7167
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
7168
                 5, 9);
7169
      end
7170
      else if (i_length == 17)
7171
      begin
7172
        $display("    using 4 BDs out of 8 BDs assigned to TX (wrap at 4th BD - TX BD 3)");
7173
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
7174
                 10, 17);
7175
      end
7176
      else if (i_length == 27)
7177
      begin
7178
        $display("    using 5 BDs out of 8 BDs assigned to TX (wrap at 5th BD - TX BD 4)");
7179
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
7180
                 18, 27);
7181
      end
7182
      else if (i_length == 40)
7183
      begin
7184
        $display("    using 6 BDs out of 8 BDs assigned to TX (wrap at 6th BD - TX BD 5)");
7185
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
7186
                 28, 40);
7187
      end
7188
      else if (i_length == 54)
7189
      begin
7190
        $display("    using 7 BDs out of 8 BDs assigned to TX (wrap at 7th BD - TX BD 6)");
7191
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
7192
                 41, 54);
7193
      end
7194
      else if (i_length == 69)
7195
      begin
7196
        $display("    using 8 BDs out of 8 BDs assigned to TX (wrap at 8th BD - TX BD 7)");
7197
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
7198
                 55, 69);
7199
      end
7200
      // set length (loop variable)
7201
      i_length = i_length + 1;
7202
      // the number of frame transmitted
7203
      num_of_frames = num_of_frames + 1;
7204
      if (/*(num_of_frames == 2) || (num_of_frames == 4) || (num_of_frames == 7) ||*/ (num_of_frames <= 10) ||
7205
          (num_of_frames == 14) || (num_of_frames == 18) || (num_of_frames == 23) || (num_of_frames == 28) ||
7206
          (num_of_frames == 34) || (num_of_frames == 40) || (num_of_frames == 47) ||
7207
          (num_of_frames == 54) || (num_of_frames == 62))
7208
        num_of_bd = 0;
7209
      else
7210
        num_of_bd = num_of_bd + 1;
7211
    end
7212
    // disable TX
7213
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
7214
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7215
    @(posedge wb_clk);
7216
    if(fail == 0)
7217
      test_ok;
7218
    else
7219
      fail = 0;
7220
  end
7221
 
7222
 
7223
  ////////////////////////////////////////////////////////////////////
7224
  ////                                                            ////
7225
  ////  Test no transmit packets (no pads) form 0 to (MINFL - 1)  ////
7226
  ////  sizes at 8 TX buffer decriptors ( 100Mbps ).              ////
7227
  ////                                                            ////
7228
  ////////////////////////////////////////////////////////////////////
7229
  if (test_num == 9) // 
7230
  begin
7231
    // TEST 9: NO TRANSMIT PACKETS (NO PADs) FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 100Mbps )
7232
    test_name = "TEST 9: NO TRANSMIT PACKETS (NO PADs) FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 100Mbps )";
7233
    `TIME; $display("  TEST 9: NO TRANSMIT PACKETS (NO PADs) FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 100Mbps )");
7234
 
7235
    // reset MAC registers
7236
    hard_reset;
7237
    // reset MAC and MII LOGIC with soft reset
7238
    reset_mac;
7239
    reset_mii;
7240
    // set wb slave response
7241
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
7242
 
7243
    max_tmp = 0;
7244
    min_tmp = 0;
7245
    // set 8 TX buffer descriptors - must be set before TX enable
7246
    wbm_write(`ETH_TX_BD_NUM, 32'h8, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7247
    // enable TX, set full-duplex mode, padding and CRC appending
7248
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_PAD | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
7249
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7250
    // prepare two packets of MAXFL length
7251
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7252
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
7253
    min_tmp = tmp[31:16];
7254
    st_data = 8'h12;
7255
    set_tx_packet(`MEMORY_BASE, (max_tmp - 4), st_data); // length without CRC
7256
    st_data = 8'h34;
7257
    set_tx_packet((`MEMORY_BASE + max_tmp), (max_tmp - 4), st_data); // length without CRC
7258
    // check WB INT signal
7259
    if (wb_int !== 1'b0)
7260
    begin
7261
      test_fail("WB INT signal should not be set");
7262
      fail = fail + 1;
7263
    end
7264
 
7265
    // write to phy's control register for 100Mbps
7266
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
7267
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
7268
    speed = 100;
7269
 
7270
    frame_started = 0;
7271
    num_of_frames = 0;
7272
    num_of_bd = 0;
7273
    i_length = 0; // 0;
7274
    while (i_length < 70) // (min_tmp - 4))
7275
    begin
7276
      #1;
7277
      // choose generating carrier sense and collision
7278
      case (i_length[1:0])
7279
      2'h0: // Interrupt is generated
7280
      begin
7281
        // Reset_tx_bd nable interrupt generation
7282
        // unmask interrupts
7283
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
7284
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7285
        // not detect carrier sense in FD and no collision
7286
        eth_phy.carrier_sense_tx_fd_detect(0);
7287
        eth_phy.collision(0);
7288
      end
7289
      2'h1: // Interrupt is not generated
7290
      begin
7291
        // set_tx_bd enable interrupt generation
7292
        // mask interrupts
7293
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7294
        // detect carrier sense in FD and no collision
7295
        eth_phy.carrier_sense_tx_fd_detect(1);
7296
        eth_phy.collision(0);
7297
      end
7298
      2'h2: // Interrupt is not generated
7299
      begin
7300
        // set_tx_bd disable the interrupt generation
7301
        // unmask interrupts
7302
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
7303
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7304
        // not detect carrier sense in FD and set collision
7305
        eth_phy.carrier_sense_tx_fd_detect(0);
7306
        eth_phy.collision(1);
7307
      end
7308
      default: // 2'h3: // Interrupt is not generated
7309
      begin
7310
        // set_tx_bd disable the interrupt generation
7311
        // mask interrupts
7312
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7313
        // detect carrier sense in FD and set collision
7314
        eth_phy.carrier_sense_tx_fd_detect(1);
7315
        eth_phy.collision(1);
7316
      end
7317
      endcase
7318
      #1;
7319
      // first destination address on ethernet PHY
7320
      eth_phy.set_tx_mem_addr(num_of_frames * 16);
7321
      // SET packets and wrap bit
7322
      // num_of_frames <= 9 => wrap set to TX BD 0
7323
      if (num_of_frames <= 9)
7324
      begin
7325
        tmp_len = i_length; // length of frame
7326
        tmp_bd_num = 0; // TX BD number
7327
        // if i_length[1] == 0 then enable interrupt generation otherwise disable it
7328
        // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
7329
        if (tmp_len[0] == 0)
7330
          set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
7331
        else
7332
          set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
7333
        // set wrap bit
7334
        set_tx_bd_wrap(0);
7335
      end
7336
      // 10 <= num_of_frames < 18 => wrap set to TX BD 3
7337
      else if ((num_of_frames == 10) || (num_of_frames == 14))
7338
      begin
7339
        tmp_len = i_length; // length of frame
7340
        tmp_bd_num = 0; // TX BD number
7341
        while (tmp_bd_num < 4) //
7342
        begin
7343
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
7344
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
7345
          if (tmp_len[0] == 0)
7346
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
7347
          else
7348
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
7349
          tmp_len = tmp_len + 1;
7350
          // set TX BD number
7351
          tmp_bd_num = tmp_bd_num + 1;
7352
        end
7353
        // set wrap bit
7354
        set_tx_bd_wrap(3);
7355
      end
7356
      // 18 <= num_of_frames < 28 => wrap set to TX BD 4
7357
      else if ((num_of_frames == 18) || (num_of_frames == 23))
7358
      begin
7359
        tmp_len = i_length; // length of frame
7360
        tmp_bd_num = 0; // TX BD number
7361
        while (tmp_bd_num < 5) //
7362
        begin
7363
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
7364
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
7365
          if (tmp_len[0] == 0)
7366
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
7367
          else
7368
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
7369
          tmp_len = tmp_len + 1;
7370
          // set TX BD number
7371
          tmp_bd_num = tmp_bd_num + 1;
7372
        end
7373
        // set wrap bit
7374
        set_tx_bd_wrap(4);
7375
      end
7376
      // 28 <= num_of_frames < 40 => wrap set to TX BD 5
7377
      else if ((num_of_frames == 28) || (num_of_frames == 34))
7378
      begin
7379
        tmp_len = i_length; // length of frame
7380
        tmp_bd_num = 0; // TX BD number
7381
        while (tmp_bd_num < 6) //
7382
        begin
7383
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
7384
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
7385
          if (tmp_len[0] == 0)
7386
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
7387
          else
7388
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
7389
          tmp_len = tmp_len + 1;
7390
          // set TX BD number
7391
          tmp_bd_num = tmp_bd_num + 1;
7392
        end
7393
        // set wrap bit
7394
        set_tx_bd_wrap(5);
7395
      end
7396
      // 40 <= num_of_frames < 54 => wrap set to TX BD 6
7397
      else if ((num_of_frames == 40) || (num_of_frames == 47))
7398
      begin
7399
        tmp_len = i_length; // length of frame
7400
        tmp_bd_num = 0; // TX BD number
7401
        while (tmp_bd_num < 7) //
7402
        begin
7403
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
7404
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
7405
          if (tmp_len[0] == 0)
7406
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
7407
          else
7408
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
7409
          tmp_len = tmp_len + 1;
7410
          // set TX BD number
7411
          tmp_bd_num = tmp_bd_num + 1;
7412
        end
7413
        // set wrap bit
7414
        set_tx_bd_wrap(6);
7415
      end
7416
      // 54 <= num_of_frames < 70 => wrap set to TX BD 7
7417
      else if ((num_of_frames == 54) || (num_of_frames == 62))
7418
      begin
7419
        tmp_len = i_length; // length of frame
7420
        tmp_bd_num = 0; // TX BD number
7421
        while (tmp_bd_num < 8) //
7422
        begin
7423
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
7424
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
7425
          if (tmp_len[0] == 0)
7426
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
7427
          else
7428
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
7429
          tmp_len = tmp_len + 1;
7430
          // set TX BD number
7431
          tmp_bd_num = tmp_bd_num + 1;
7432
        end
7433
        // set wrap bit
7434
        set_tx_bd_wrap(7);
7435
      end
7436
      #1;
7437
      // SET ready bit
7438
      if (num_of_frames < 10)
7439
        set_tx_bd_ready(0, 0);
7440
      else if (num_of_frames < 14)
7441
        set_tx_bd_ready((num_of_frames - 10), (num_of_frames - 10));
7442
      else if (num_of_frames < 18)
7443
        set_tx_bd_ready((num_of_frames - 14), (num_of_frames - 14));
7444
      else if (num_of_frames < 23)
7445
        set_tx_bd_ready((num_of_frames - 18), (num_of_frames - 18));
7446
      else if (num_of_frames < 28)
7447
        set_tx_bd_ready((num_of_frames - 23), (num_of_frames - 23));
7448
      else if (num_of_frames < 34)
7449
        set_tx_bd_ready((num_of_frames - 28), (num_of_frames - 28));
7450
      else if (num_of_frames < 40)
7451
        set_tx_bd_ready((num_of_frames - 34), (num_of_frames - 34));
7452
      else if (num_of_frames < 47)
7453
        set_tx_bd_ready((num_of_frames - 40), (num_of_frames - 40));
7454
      else if (num_of_frames < 54)
7455
        set_tx_bd_ready((num_of_frames - 47), (num_of_frames - 47));
7456
      else if (num_of_frames < 62)
7457
        set_tx_bd_ready((num_of_frames - 54), (num_of_frames - 54));
7458
      else if (num_of_frames < 70)
7459
        set_tx_bd_ready((num_of_frames - 62), (num_of_frames - 62));
7460
      // CHECK END OF TRANSMITION
7461
      frame_started = 0;
7462
      if (num_of_frames >= 5)
7463
        #1 check_tx_bd(num_of_bd, data);
7464
      fork
7465
      begin: fr_st3
7466
        wait (MTxEn === 1'b1); // start transmit
7467
        frame_started = 1;
7468
      end
7469
      begin
7470
        repeat (30) @(posedge mtx_clk);
7471
        if (num_of_frames < 5)
7472
        begin
7473
          if (frame_started == 1)
7474
          begin
7475
            `TIME; $display("*E Frame should NOT start!");
7476
          end
7477
          disable fr_st3;
7478
        end
7479
        else
7480
        begin
7481
          if (frame_started == 0)
7482
          begin
7483
            `TIME; $display("*W Frame should start!");
7484
            disable fr_st3;
7485
          end
7486
        end
7487
      end
7488
      join
7489
      // check packets larger than 4 bytes
7490
      if (num_of_frames >= 5)
7491
      begin
7492
        wait (MTxEn === 1'b0); // end transmit
7493
        while (data[15] === 1)
7494
        begin
7495
          #1 check_tx_bd(num_of_bd, data);
7496
          @(posedge wb_clk);
7497
        end
7498
        repeat (1) @(posedge wb_clk);
7499
        // check length of a PACKET
7500
        if (eth_phy.tx_len != (i_length + 4))
7501
        begin
7502
          `TIME; $display("*E Wrong length of the packet out from MAC");
7503
          test_fail("Wrong length of the packet out from MAC");
7504
          fail = fail + 1;
7505
        end
7506
        // check transmitted TX packet data
7507
        if (i_length[0] == 0)
7508
        begin
7509
          #1 check_tx_packet(`MEMORY_BASE, (num_of_frames * 16), i_length, tmp);
7510
        end
7511
        else
7512
        begin
7513
          #1 check_tx_packet((`MEMORY_BASE + max_tmp), (num_of_frames * 16), i_length, tmp);
7514
        end
7515
        if (tmp > 0)
7516
        begin
7517
          test_fail("Wrong data of the transmitted packet");
7518
          fail = fail + 1;
7519
        end
7520
        // check transmited TX packet CRC
7521
        #1 check_tx_crc((num_of_frames * 16), (eth_phy.tx_len - 4), 1'b0, tmp); // length without CRC
7522
        if (tmp > 0)
7523
        begin
7524
          test_fail("Wrong CRC of the transmitted packet");
7525
          fail = fail + 1;
7526
        end
7527
      end
7528
      // check WB INT signal
7529
      if ((i_length[1:0] == 2'h0) && (num_of_frames >= 5))
7530
      begin
7531
        if (wb_int !== 1'b1)
7532
        begin
7533
          `TIME; $display("*E WB INT signal should be set");
7534
          test_fail("WB INT signal should be set");
7535
          fail = fail + 1;
7536
        end
7537
      end
7538
      else
7539
      begin
7540
        if (wb_int !== 1'b0)
7541
        begin
7542
          `TIME; $display("*E WB INT signal should not be set");
7543
          test_fail("WB INT signal should not be set");
7544
          fail = fail + 1;
7545
        end
7546
      end
7547
      // check TX buffer descriptor of a packet
7548
      check_tx_bd(num_of_bd, data);
7549
      if (num_of_frames >= 5)
7550
      begin
7551
        if (i_length[1] == 1'b0) // interrupt enabled
7552
        begin
7553
          if ( (data[15:0] !== 16'h7800) && // wrap bit
7554
               (data[15:0] !== 16'h5800) ) // without wrap bit
7555
          begin
7556
            `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
7557
            test_fail("TX buffer descriptor status is not correct");
7558
            fail = fail + 1;
7559
          end
7560
        end
7561
        else // interrupt not enabled
7562
        begin
7563
          if ( (data[15:0] !== 16'h3800) && // wrap bit
7564
               (data[15:0] !== 16'h1800) ) // without wrap bit
7565
          begin
7566
            `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
7567
            test_fail("TX buffer descriptor status is not correct");
7568
            fail = fail + 1;
7569
          end
7570
        end
7571
      end
7572
      else
7573
      begin
7574
        if (data[15] !== 1'b1)
7575
        begin
7576
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
7577
          test_fail("TX buffer descriptor status is not correct");
7578
          fail = fail + 1;
7579
        end
7580
      end
7581
      // clear TX BD with wrap bit
7582
      if (num_of_frames == 63)
7583
        clear_tx_bd(16, 16);
7584
      // check interrupts
7585
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7586
      if ( ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1)) && (num_of_frames >= 5) )
7587
      begin
7588
        if ((data & `ETH_INT_TXB) !== 1'b1)
7589
        begin
7590
          `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
7591
          test_fail("Interrupt Transmit Buffer was not set");
7592
          fail = fail + 1;
7593
        end
7594
        if ((data & (~`ETH_INT_TXB)) !== 0)
7595
        begin
7596
          `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
7597
          test_fail("Other interrupts (except Transmit Buffer) were set");
7598
          fail = fail + 1;
7599
        end
7600
      end
7601
      else
7602
      begin
7603
        if (data !== 0)
7604
        begin
7605
          `TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]);
7606
          test_fail("Any of interrupts (except Transmit Buffer) was set");
7607
          fail = fail + 1;
7608
        end
7609
      end
7610
      // clear interrupts
7611
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7612
      // check WB INT signal
7613
      if (wb_int !== 1'b0)
7614
      begin
7615
        test_fail("WB INT signal should not be set");
7616
        fail = fail + 1;
7617
      end
7618
      // INTERMEDIATE DISPLAYS
7619
      if (i_length == 3)
7620
      begin
7621
        $display("    pads appending to packets is selected");
7622
        $display("    using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)");
7623
        $display("    ->packets with lengths from %0d to %0d are not transmitted (length increasing by 1 byte)",
7624
                 0, 3);
7625
      end
7626
      else if (i_length == 9)
7627
      begin
7628
        $display("    using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)");
7629
        $display("    ->packet with length 4 is not transmitted (length increasing by 1 byte)");
7630
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
7631
                 5, 9);
7632
      end
7633
      else if (i_length == 17)
7634
      begin
7635
        $display("    using 4 BDs out of 8 BDs assigned to TX (wrap at 4th BD - TX BD 3)");
7636
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
7637
                 10, 17);
7638
      end
7639
      else if (i_length == 27)
7640
      begin
7641
        $display("    using 5 BDs out of 8 BDs assigned to TX (wrap at 5th BD - TX BD 4)");
7642
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
7643
                 18, 27);
7644
      end
7645
      else if (i_length == 40)
7646
      begin
7647
        $display("    using 6 BDs out of 8 BDs assigned to TX (wrap at 6th BD - TX BD 5)");
7648
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
7649
                 28, 40);
7650
      end
7651
      else if (i_length == 54)
7652
      begin
7653
        $display("    using 7 BDs out of 8 BDs assigned to TX (wrap at 7th BD - TX BD 6)");
7654
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
7655
                 41, 54);
7656
      end
7657
      else if (i_length == 69)
7658
      begin
7659
        $display("    using 8 BDs out of 8 BDs assigned to TX (wrap at 8th BD - TX BD 7)");
7660
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
7661
                 55, 69);
7662
      end
7663
      // set length (loop variable)
7664
      i_length = i_length + 1;
7665
      // the number of frame transmitted
7666
      num_of_frames = num_of_frames + 1;
7667
      if (/*(num_of_frames == 2) || (num_of_frames == 4) || (num_of_frames == 7) ||*/ (num_of_frames <= 10) ||
7668
          (num_of_frames == 14) || (num_of_frames == 18) || (num_of_frames == 23) || (num_of_frames == 28) ||
7669
          (num_of_frames == 34) || (num_of_frames == 40) || (num_of_frames == 47) ||
7670
          (num_of_frames == 54) || (num_of_frames == 62))
7671
        num_of_bd = 0;
7672
      else
7673
        num_of_bd = num_of_bd + 1;
7674
    end
7675
    // disable TX
7676
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
7677
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7678
    @(posedge wb_clk);
7679
    if(fail == 0)
7680
      test_ok;
7681
    else
7682
      fail = 0;
7683
  end
7684
 
7685
 
7686
  ////////////////////////////////////////////////////////////////////
7687
  ////                                                            ////
7688
  ////  Test transmit packets across MAXFL value at               ////
7689
  ////  13 TX buffer decriptors ( 10Mbps ).                       ////
7690
  ////                                                            ////
7691
  ////////////////////////////////////////////////////////////////////
7692
  if (test_num == 10) // without and with padding
7693
  begin
7694
    // TEST 10: TRANSMIT PACKETS ACROSS MAXFL VALUE AT 13 TX BDs ( 10Mbps )
7695
    test_name = "TEST 10: TRANSMIT PACKETS ACROSS MAXFL VALUE AT 13 TX BDs ( 10Mbps )";
7696
    `TIME; $display("  TEST 10: TRANSMIT PACKETS ACROSS MAXFL VALUE AT 13 TX BDs ( 10Mbps )");
7697
 
7698
    // reset MAC registers
7699
    hard_reset;
7700
    // reset MAC and MII LOGIC with soft reset
7701
    reset_mac;
7702
    reset_mii;
7703
    // set wb slave response
7704
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
7705
 
7706
    max_tmp = 0;
7707
    min_tmp = 0;
7708
    num_of_frames = 0;
7709
    num_of_bd = 0;
7710
    // set 13 TX buffer descriptors - must be set before TX enable
7711
    wbm_write(`ETH_TX_BD_NUM, 32'hD, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7712
    // enable TX, set full-duplex mode, NO padding and CRC appending
7713
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
7714
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7715
    // prepare a packet of MAXFL + 10 length
7716
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7717
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
7718
    min_tmp = tmp[31:16];
7719
    st_data = 8'hA3;
7720
    set_tx_packet(`MEMORY_BASE, (max_tmp + 10), st_data); // length without CRC
7721
    // check WB INT signal
7722
    if (wb_int !== 1'b0)
7723
    begin
7724
      test_fail("WB INT signal should not be set");
7725
      fail = fail + 1;
7726
    end
7727
 
7728
    // write to phy's control register for 10Mbps
7729
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
7730
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
7731
    speed = 10;
7732
 
7733
    i_length = (max_tmp - 5);
7734
    while (i_length <= (max_tmp - 3)) // (max_tmp - 4) is the limit
7735
    begin
7736
$display("   i_length = %0d", i_length);
7737
      // choose generating carrier sense and collision
7738
//      case (i_length[1:0])
7739
//      2'h0: // Interrupt is generated
7740
//      begin
7741
        // Reset_tx_bd nable interrupt generation
7742
        // unmask interrupts
7743
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
7744
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7745
        // not detect carrier sense in FD and no collision
7746
        eth_phy.carrier_sense_tx_fd_detect(0);
7747
        eth_phy.collision(0);
7748
//      end
7749
//      2'h1: // Interrupt is not generated
7750
//      begin
7751
        // set_tx_bd enable interrupt generation
7752
        // mask interrupts
7753
//        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7754
        // detect carrier sense in FD and no collision
7755
//        eth_phy.carrier_sense_tx_fd_detect(1);
7756
//        eth_phy.collision(0);
7757
//      end
7758
//      2'h2: // Interrupt is not generated
7759
//      begin
7760
        // set_tx_bd disable the interrupt generation
7761
        // unmask interrupts
7762
//        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
7763
//                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7764
        // not detect carrier sense in FD and set collision
7765
//        eth_phy.carrier_sense_tx_fd_detect(0);
7766
//        eth_phy.collision(1);
7767
//      end
7768
//      default: // 2'h3: // Interrupt is not generated
7769
//      begin
7770
        // set_tx_bd disable the interrupt generation
7771
        // mask interrupts
7772
//        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7773
        // detect carrier sense in FD and set collision
7774
//        eth_phy.carrier_sense_tx_fd_detect(1);
7775
//        eth_phy.collision(1);
7776
//      end
7777
//      endcase
7778
      // first destination address on ethernet PHY
7779
      eth_phy.set_tx_mem_addr(0);
7780
      // 
7781
if (num_of_bd == 0)
7782
begin
7783
set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
7784
set_tx_bd(1, 1, i_length+1, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
7785
set_tx_bd(2, 2, i_length+2, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
7786
set_tx_bd_wrap(2);
7787
set_tx_bd_ready(0, 0);
7788
end
7789
else if (num_of_bd == 1)
7790
set_tx_bd_ready(1, 1);
7791
else if (num_of_bd == 2)
7792
set_tx_bd_ready(2, 2);
7793
 
7794
 
7795
//        tmp_len = i_length; // length of frame
7796
//        tmp_bd_num = 0; // TX BD number
7797
//        while (tmp_bd_num < 8) // 
7798
//        begin
7799
//          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
7800
//          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
7801
//          if (tmp_len[0] == 0)
7802
//            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
7803
//          else
7804
//            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + 2*max_tmp));
7805
//          // set length (loop variable) - THE SAME AS AT THE END OF THIS TASK !!!
7806
//          tmp_len = tmp_len + 1;
7807
//          // set TX BD number
7808
//          tmp_bd_num = tmp_bd_num + 1;
7809
//        end
7810
//        // set wrap bit
7811
//        set_tx_bd_wrap(7);
7812
//      // set ready bit
7813
//      set_tx_bd_ready((i_length - (max_tmp - 8)), (i_length - (max_tmp - 8)));
7814
      // CHECK END OF TRANSMITION
7815
check_tx_bd(num_of_bd, data);
7816
//      #1 check_tx_bd((i_length - (max_tmp - 8)), data);
7817
        wait (MTxEn === 1'b1); // start transmit
7818
check_tx_bd(num_of_bd, data);
7819
//        #1 check_tx_bd((i_length - (max_tmp - 8)), data);
7820
        if (data[15] !== 1)
7821
        begin
7822
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
7823
          fail = fail + 1;
7824
        end
7825
        wait (MTxEn === 1'b0); // end transmit
7826
        while (data[15] === 1)
7827
        begin
7828
check_tx_bd(num_of_bd, data);
7829
//          #1 check_tx_bd((i_length - (max_tmp - 8)), data);
7830
          @(posedge wb_clk);
7831
        end
7832
        repeat (1) @(posedge wb_clk);
7833
      // check length of a PACKET
7834
$display("   eth_phy length = %0d", eth_phy.tx_len);
7835
tmp_len = eth_phy.tx_len;
7836
#1;
7837
if (tmp_len != (i_length + 4))
7838
//      if (eth_phy.tx_len != (i_length + 4))
7839
      begin
7840
        test_fail("Wrong length of the packet out from MAC");
7841
        fail = fail + 1;
7842
      end
7843
      // checking in the following if statement is performed only for first and last 64 lengths
7844
//      if ( ((i_length + 4) <= (min_tmp + 64)) || ((i_length + 4) > (max_tmp - 64)) )
7845
//      begin
7846
        // check transmitted TX packet data
7847
//        if (i_length[0] == 0)
7848
//        begin
7849
          check_tx_packet(`MEMORY_BASE, 0, i_length, tmp);
7850
//        end
7851
//        else
7852
//        begin
7853
//          check_tx_packet((`MEMORY_BASE + 2*max_tmp), 0, i_length, tmp);
7854
//        end
7855
        if (tmp > 0)
7856
        begin
7857
          test_fail("Wrong data of the transmitted packet");
7858
          fail = fail + 1;
7859
        end
7860
        // check transmited TX packet CRC
7861
//        if (i_length[0] == 0)
7862
          check_tx_crc(0, i_length, 1'b0, tmp); // length without CRC
7863
//        else
7864
//          check_tx_crc(0, i_length, 1'b0, tmp); // length without CRC
7865
        if (tmp > 0)
7866
        begin
7867
          test_fail("Wrong CRC of the transmitted packet");
7868
          fail = fail + 1;
7869
        end
7870
//      end
7871
      // check WB INT signal
7872
//      if (i_length[1:0] == 2'h0)
7873
//      begin
7874
        if (wb_int !== 1'b1)
7875
        begin
7876
          `TIME; $display("*E WB INT signal should be set");
7877
          test_fail("WB INT signal should be set");
7878
          fail = fail + 1;
7879
        end
7880
//      end
7881
//      else
7882
//      begin
7883
//        if (wb_int !== 1'b0)
7884
//        begin
7885
//          `TIME; $display("*E WB INT signal should not be set");
7886
//          test_fail("WB INT signal should not be set");
7887
//          fail = fail + 1;
7888
//        end
7889
//      end
7890
//      // check TX buffer descriptor of a packet
7891
//      check_tx_bd((i_length - (max_tmp - 8)), data);
7892
check_tx_bd(num_of_bd, data);
7893
if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 2)) || // wrap bit
7894
     ((data[15:0] !== 16'h5800) && (num_of_bd < 2)) )   // without wrap bit
7895
//      if (i_length[1] == 1'b0) // interrupt enabled
7896
//      begin
7897
//        if ( ((data[15:0] !== 16'h7800) && ((num_of_frames < 8) || ((num_of_frames - 8) == 127))) || // wrap bit
7898
//             ((data[15:0] !== 16'h5800) && (num_of_frames >= 8) && ((num_of_frames - 8) != 127)) ) // without wrap bit
7899
        begin
7900
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
7901
          test_fail("TX buffer descriptor status is not correct");
7902
          fail = fail + 1;
7903
        end
7904
//      end
7905
//      else // interrupt not enabled
7906
//      begin
7907
//        if ( ((data[15:0] !== 16'h3800)  && ((num_of_frames < 8) || ((num_of_frames - 8) == 127))) || // wrap bit
7908
//             ((data[15:0] !== 16'h1800) && (num_of_frames >= 8) && ((num_of_frames - 8) != 127)) ) // without wrap bit
7909
//        begin
7910
//          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
7911
//          test_fail("TX buffer descriptor status is not correct");
7912
//          fail = fail + 1;
7913
//        end
7914
//      end
7915
//      // clear first half of 8 frames from TX buffer descriptor 0
7916
//      if (num_of_frames < 4)
7917
//        clear_tx_bd((i_length - (max_tmp - 8)), (i_length - (max_tmp - 8)));
7918
      // check interrupts
7919
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7920
//      if ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1))
7921
//      begin
7922
        if ((data & `ETH_INT_TXB) !== 1'b1)
7923
        begin
7924
          `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
7925
          test_fail("Interrupt Transmit Buffer was not set");
7926
          fail = fail + 1;
7927
        end
7928
        if ((data & (~`ETH_INT_TXB)) !== 0)
7929
        begin
7930
          `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
7931
          test_fail("Other interrupts (except Transmit Buffer) were set");
7932
          fail = fail + 1;
7933
        end
7934
//      end
7935
//      else
7936
//      begin
7937
//        if (data !== 0)
7938
//        begin
7939
//          `TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]);
7940
//          test_fail("Any of interrupts (except Transmit Buffer) was set");
7941
//          fail = fail + 1;
7942
//        end
7943
//      end
7944
      // clear interrupts
7945
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7946
      // check WB INT signal
7947
      if (wb_int !== 1'b0)
7948
      begin
7949
        test_fail("WB INT signal should not be set");
7950
        fail = fail + 1;
7951
      end
7952
      // INTERMEDIATE DISPLAYS
7953
if (num_of_bd == 0)
7954
  $display("    ->packet with length %0d sent", (i_length + 4));
7955
else if (num_of_bd == 1)
7956
  $display("    ->packet with length %0d sent", (i_length + 4));
7957
else if (num_of_bd == 2)
7958
  $display("    ->packet with length %0d sent", (i_length + 4));
7959
      // set length (loop variable)
7960
      i_length = i_length + 1;
7961
      // the number of frame transmitted
7962
      num_of_frames = num_of_frames + 1;
7963
      num_of_bd = num_of_bd + 1;
7964
      @(posedge wb_clk);
7965
    end
7966
    // disable TX
7967
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
7968
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
7969
    @(posedge wb_clk);
7970
    if(fail == 0)
7971
      test_ok;
7972
    else
7973
      fail = 0;
7974
  end
7975
 
7976
 
7977
  ////////////////////////////////////////////////////////////////////
7978
  ////                                                            ////
7979
  ////  Test transmit packets across MAXFL value at               ////
7980
  ////  13 TX buffer decriptors ( 100Mbps ).                      ////
7981
  ////                                                            ////
7982
  ////////////////////////////////////////////////////////////////////
7983
  if (test_num == 11) // without and with padding
7984
  begin
7985
    // TEST 11: TRANSMIT PACKETS ACROSS MAXFL VALUE AT 13 TX BDs ( 100Mbps )
7986
    test_name = "TEST 11: TRANSMIT PACKETS ACROSS MAXFL VALUE AT 13 TX BDs ( 100Mbps )";
7987
    `TIME; $display("  TEST 11: TRANSMIT PACKETS ACROSS MAXFL VALUE AT 13 TX BDs ( 100Mbps )");
7988
 
7989
    // reset MAC registers
7990
    hard_reset;
7991
    // reset MAC and MII LOGIC with soft reset
7992
    reset_mac;
7993
    reset_mii;
7994
    // set wb slave response
7995
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
7996
 
7997
    max_tmp = 0;
7998
    min_tmp = 0;
7999
    num_of_frames = 0;
8000
    num_of_bd = 0;
8001
    // set 13 TX buffer descriptors - must be set before TX enable
8002
    wbm_write(`ETH_TX_BD_NUM, 32'hD, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8003
    // enable TX, set full-duplex mode, NO padding and CRC appending
8004
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
8005
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8006
    // prepare a packet of MAXFL + 10 length
8007
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8008
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
8009
    min_tmp = tmp[31:16];
8010
    st_data = 8'hA3;
8011
    set_tx_packet(`MEMORY_BASE, (max_tmp + 10), st_data); // length without CRC
8012
    // check WB INT signal
8013
    if (wb_int !== 1'b0)
8014
    begin
8015
      test_fail("WB INT signal should not be set");
8016
      fail = fail + 1;
8017
    end
8018
 
8019
    // write to phy's control register for 100Mbps
8020
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
8021
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
8022
    speed = 100;
8023
 
8024
    i_length = (max_tmp - 5);
8025
    while (i_length <= (max_tmp - 3)) // (max_tmp - 4) is the limit
8026
    begin
8027
      $display("   i_length = %0d", i_length);
8028
      // Reset_tx_bd nable interrupt generation
8029
      // unmask interrupts
8030
      wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
8031
                               `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8032
      // not detect carrier sense in FD and no collision
8033
      eth_phy.carrier_sense_tx_fd_detect(0);
8034
      eth_phy.collision(0);
8035
      // first destination address on ethernet PHY
8036
      eth_phy.set_tx_mem_addr(0);
8037
      // prepare BDs
8038
      if (num_of_bd == 0)
8039
      begin
8040
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8041
        set_tx_bd(1, 1, i_length+1, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8042
        set_tx_bd(2, 2, i_length+2, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8043
        set_tx_bd_wrap(2);
8044
        set_tx_bd_ready(0, 0);
8045
      end
8046
      else if (num_of_bd == 1)
8047
        set_tx_bd_ready(1, 1);
8048
      else if (num_of_bd == 2)
8049
        set_tx_bd_ready(2, 2);
8050
      // CHECK END OF TRANSMITION
8051
      check_tx_bd(num_of_bd, data);
8052
        wait (MTxEn === 1'b1); // start transmit
8053
      check_tx_bd(num_of_bd, data);
8054
        if (data[15] !== 1)
8055
        begin
8056
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
8057
          fail = fail + 1;
8058
        end
8059
        wait (MTxEn === 1'b0); // end transmit
8060
        while (data[15] === 1)
8061
        begin
8062
      check_tx_bd(num_of_bd, data);
8063
          @(posedge wb_clk);
8064
        end
8065
        repeat (1) @(posedge wb_clk);
8066
      // check length of a PACKET
8067
      $display("   eth_phy length = %0d", eth_phy.tx_len);
8068
      tmp_len = eth_phy.tx_len;
8069
      #1;
8070
      if (tmp_len != (i_length + 4))
8071
      begin
8072
        test_fail("Wrong length of the packet out from MAC");
8073
        fail = fail + 1;
8074
      end
8075
      // checking packet
8076
      check_tx_packet(`MEMORY_BASE, 0, i_length, tmp);
8077
      if (tmp > 0)
8078
      begin
8079
        test_fail("Wrong data of the transmitted packet");
8080
        fail = fail + 1;
8081
      end
8082
      // check transmited TX packet CRC
8083
      check_tx_crc(0, i_length, 1'b0, tmp); // length without CRC
8084
      if (tmp > 0)
8085
      begin
8086
        test_fail("Wrong CRC of the transmitted packet");
8087
        fail = fail + 1;
8088
      end
8089
      // check WB INT signal
8090
      if (wb_int !== 1'b1)
8091
      begin
8092
        `TIME; $display("*E WB INT signal should be set");
8093
        test_fail("WB INT signal should be set");
8094
        fail = fail + 1;
8095
      end
8096
      // check TX buffer descriptor of a packet
8097
      check_tx_bd(num_of_bd, data);
8098
      if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 2)) || // wrap bit
8099
           ((data[15:0] !== 16'h5800) && (num_of_bd < 2)) )   // without wrap bit
8100
      begin
8101
        `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
8102
        test_fail("TX buffer descriptor status is not correct");
8103
        fail = fail + 1;
8104
      end
8105
      // check interrupts
8106
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8107
      if ((data & `ETH_INT_TXB) !== 1'b1)
8108
      begin
8109
        `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
8110
        test_fail("Interrupt Transmit Buffer was not set");
8111
        fail = fail + 1;
8112
      end
8113
      if ((data & (~`ETH_INT_TXB)) !== 0)
8114
      begin
8115
        `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
8116
        test_fail("Other interrupts (except Transmit Buffer) were set");
8117
        fail = fail + 1;
8118
      end
8119
      // clear interrupts
8120
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8121
      // check WB INT signal
8122
      if (wb_int !== 1'b0)
8123
      begin
8124
        test_fail("WB INT signal should not be set");
8125
        fail = fail + 1;
8126
      end
8127
      // INTERMEDIATE DISPLAYS
8128
      if (num_of_bd == 0)
8129
        $display("    ->packet with length %0d sent", (i_length + 4));
8130
      else if (num_of_bd == 1)
8131
        $display("    ->packet with length %0d sent", (i_length + 4));
8132
      else if (num_of_bd == 2)
8133
        $display("    ->packet with length %0d sent", (i_length + 4));
8134
      // set length (loop variable)
8135
      i_length = i_length + 1;
8136
      // the number of frame transmitted
8137
      num_of_frames = num_of_frames + 1;
8138
      num_of_bd = num_of_bd + 1;
8139
      @(posedge wb_clk);
8140
    end
8141
    // disable TX
8142
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
8143
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8144
    @(posedge wb_clk);
8145
    if(fail == 0)
8146
      test_ok;
8147
    else
8148
      fail = 0;
8149
  end
8150
 
8151
 
8152
  ////////////////////////////////////////////////////////////////////
8153
  ////                                                            ////
8154
  ////  Test transmit packets across changed MAXFL value at       ////
8155
  ////  47 TX buffer decriptors ( 10Mbps ).                       ////
8156
  ////                                                            ////
8157
  ////////////////////////////////////////////////////////////////////
8158
  if (test_num == 12) // without and with padding
8159
  begin
8160
    // TEST 12: TRANSMIT PACKETS ACROSS CHANGED MAXFL VALUE AT 13 TX BDs ( 10Mbps )
8161
    test_name = "TEST 12: TRANSMIT PACKETS ACROSS CHANGED MAXFL VALUE AT 13 TX BDs ( 10Mbps )";
8162
    `TIME; $display("  TEST 12: TRANSMIT PACKETS ACROSS CHANGED MAXFL VALUE AT 13 TX BDs ( 10Mbps )");
8163
 
8164
    // reset MAC registers
8165
    hard_reset;
8166
    // reset MAC and MII LOGIC with soft reset
8167
    reset_mac;
8168
    reset_mii;
8169
    // set wb slave response
8170
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
8171
 
8172
    max_tmp = 0;
8173
    min_tmp = 0;
8174
    num_of_frames = 0;
8175
    num_of_bd = 0;
8176
    // set 47 TX buffer descriptors - must be set before TX enable
8177
    wbm_write(`ETH_TX_BD_NUM, 32'h2F, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8178
    // prepare a packet of MAXFL + 10 length
8179
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8180
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
8181
    min_tmp = tmp[31:16];
8182
    // change MAXFL value
8183
    max_tmp = min_tmp + 53;
8184
    wbm_write(`ETH_PACKETLEN, {min_tmp, max_tmp}, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8185
    st_data = 8'h62;
8186
    set_tx_packet(`MEMORY_BASE, max_tmp, st_data); // length with CRC
8187
    append_tx_crc(`MEMORY_BASE, (max_tmp - 5), 1'b0); // for first packet
8188
    // enable TX, set full-duplex mode, NO padding and NO CRC appending
8189
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD,
8190
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8191
    // check WB INT signal
8192
    if (wb_int !== 1'b0)
8193
    begin
8194
      test_fail("WB INT signal should not be set");
8195
      fail = fail + 1;
8196
    end
8197
 
8198
    // write to phy's control register for 10Mbps
8199
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
8200
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
8201
    speed = 10;
8202
 
8203
    i_length = (max_tmp - 5); // (max_tmp - 1); // not (max_tmp - 5) because NO automatic CRC appending
8204
    while (i_length <= (max_tmp - 3)) // (max_tmp + 1)) // (max_tmp) is the limit
8205
    begin
8206
      $display("   i_length = %0d", i_length);
8207
      // prepare packet's CRC
8208
      if (num_of_bd == 1)
8209
        append_tx_crc(`MEMORY_BASE, (max_tmp - 4), 1'b0); // for second and third packets
8210
      // Reset_tx_bd nable interrupt generation
8211
      // unmask interrupts
8212
      wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
8213
                               `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8214
      // not detect carrier sense in FD and no collision
8215
      eth_phy.carrier_sense_tx_fd_detect(0);
8216
      eth_phy.collision(0);
8217
      // first destination address on ethernet PHY
8218
      eth_phy.set_tx_mem_addr(0);
8219
      // prepare BDs
8220
      if (num_of_bd == 0)
8221
      begin
8222
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8223
        set_tx_bd(1, 1, i_length+1, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8224
        set_tx_bd(2, 2, i_length+2, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8225
        set_tx_bd_wrap(2);
8226
        set_tx_bd_ready(0, 0);
8227
      end
8228
      else if (num_of_bd == 1)
8229
        set_tx_bd_ready(1, 1);
8230
      else if (num_of_bd == 2)
8231
        set_tx_bd_ready(2, 2);
8232
      // CHECK END OF TRANSMITION
8233
      check_tx_bd(num_of_bd, data);
8234
        wait (MTxEn === 1'b1); // start transmit
8235
      check_tx_bd(num_of_bd, data);
8236
        if (data[15] !== 1)
8237
        begin
8238
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
8239
          fail = fail + 1;
8240
        end
8241
        wait (MTxEn === 1'b0); // end transmit
8242
        while (data[15] === 1)
8243
        begin
8244
      check_tx_bd(num_of_bd, data);
8245
          @(posedge wb_clk);
8246
        end
8247
        repeat (1) @(posedge wb_clk);
8248
      // check length of a PACKET
8249
      $display("   eth_phy length = %0d", eth_phy.tx_len);
8250
      tmp_len = eth_phy.tx_len;
8251
      #1;
8252
      if (tmp_len != (i_length + 4))
8253
      begin
8254
        test_fail("Wrong length of the packet out from MAC");
8255
        fail = fail + 1;
8256
      end
8257
      // checking packet
8258
      check_tx_packet(`MEMORY_BASE, 0, i_length, tmp);
8259
      if (tmp > 0)
8260
      begin
8261
        test_fail("Wrong data of the transmitted packet");
8262
        fail = fail + 1;
8263
      end
8264
      // check transmited TX packet CRC
8265
      check_tx_crc(0, i_length, 1'b0, tmp); // length without CRC
8266
      if (tmp > 0)
8267
      begin
8268
        test_fail("Wrong CRC of the transmitted packet");
8269
        fail = fail + 1;
8270
      end
8271
      // check WB INT signal
8272
      if (wb_int !== 1'b1)
8273
      begin
8274
        `TIME; $display("*E WB INT signal should be set");
8275
        test_fail("WB INT signal should be set");
8276
        fail = fail + 1;
8277
      end
8278
      // check TX buffer descriptor of a packet
8279
      check_tx_bd(num_of_bd, data);
8280
      if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 2)) || // wrap bit
8281
           ((data[15:0] !== 16'h5800) && (num_of_bd < 2)) )   // without wrap bit
8282
      begin
8283
        `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
8284
        test_fail("TX buffer descriptor status is not correct");
8285
        fail = fail + 1;
8286
      end
8287
      // check interrupts
8288
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8289
      if ((data & `ETH_INT_TXB) !== 1'b1)
8290
      begin
8291
        `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
8292
        test_fail("Interrupt Transmit Buffer was not set");
8293
        fail = fail + 1;
8294
      end
8295
      if ((data & (~`ETH_INT_TXB)) !== 0)
8296
      begin
8297
        `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
8298
        test_fail("Other interrupts (except Transmit Buffer) were set");
8299
        fail = fail + 1;
8300
      end
8301
      // clear interrupts
8302
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8303
      // check WB INT signal
8304
      if (wb_int !== 1'b0)
8305
      begin
8306
        test_fail("WB INT signal should not be set");
8307
        fail = fail + 1;
8308
      end
8309
      // INTERMEDIATE DISPLAYS
8310
      if (num_of_bd == 0)
8311
        $display("    ->packet with length %0d sent", (i_length + 4));
8312
      else if (num_of_bd == 1)
8313
        $display("    ->packet with length %0d sent", (i_length + 4));
8314
      else if (num_of_bd == 2)
8315
        $display("    ->packet with length %0d sent", (i_length + 4));
8316
      // set length (loop variable)
8317
      i_length = i_length + 1;
8318
      // the number of frame transmitted
8319
      num_of_frames = num_of_frames + 1;
8320
      num_of_bd = num_of_bd + 1;
8321
      @(posedge wb_clk);
8322
    end
8323
    // disable TX
8324
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
8325
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8326
    @(posedge wb_clk);
8327
    if(fail == 0)
8328
      test_ok;
8329
    else
8330
      fail = 0;
8331
  end
8332
 
8333
 
8334
  ////////////////////////////////////////////////////////////////////
8335
  ////                                                            ////
8336
  ////  Test transmit packets across changed MAXFL value at       ////
8337
  ////  47 TX buffer decriptors ( 100Mbps ).                      ////
8338
  ////                                                            ////
8339
  ////////////////////////////////////////////////////////////////////
8340
  if (test_num == 13) // without and with padding
8341
  begin
8342
    // TEST 13: TRANSMIT PACKETS ACROSS CHANGED MAXFL VALUE AT 13 TX BDs ( 100Mbps )
8343
    test_name = "TEST 13: TRANSMIT PACKETS ACROSS CHANGED MAXFL VALUE AT 13 TX BDs ( 100Mbps )";
8344
    `TIME; $display("  TEST 13: TRANSMIT PACKETS ACROSS CHANGED MAXFL VALUE AT 13 TX BDs ( 100Mbps )");
8345
 
8346
    // reset MAC registers
8347
    hard_reset;
8348
    // reset MAC and MII LOGIC with soft reset
8349
    reset_mac;
8350
    reset_mii;
8351
    // set wb slave response
8352
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
8353
 
8354
    max_tmp = 0;
8355
    min_tmp = 0;
8356
    num_of_frames = 0;
8357
    num_of_bd = 0;
8358
    // set 47 TX buffer descriptors - must be set before TX enable
8359
    wbm_write(`ETH_TX_BD_NUM, 32'h2F, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8360
    // prepare a packet of MAXFL + 10 length
8361
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8362
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
8363
    min_tmp = tmp[31:16];
8364
    // change MAXFL value
8365
    max_tmp = min_tmp + 53;
8366
    wbm_write(`ETH_PACKETLEN, {min_tmp, max_tmp}, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8367
    st_data = 8'h62;
8368
    set_tx_packet(`MEMORY_BASE, max_tmp, st_data); // length with CRC
8369
    append_tx_crc(`MEMORY_BASE, (max_tmp - 5), 1'b0); // for first packet
8370
    // enable TX, set full-duplex mode, NO padding and NO CRC appending
8371
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD,
8372
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8373
    // check WB INT signal
8374
    if (wb_int !== 1'b0)
8375
    begin
8376
      test_fail("WB INT signal should not be set");
8377
      fail = fail + 1;
8378
    end
8379
 
8380
    // write to phy's control register for 100Mbps
8381
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
8382
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
8383
    speed = 100;
8384
 
8385
    i_length = (max_tmp - 5); // (max_tmp - 1); // not (max_tmp - 5) because NO automatic CRC appending
8386
    while (i_length <= (max_tmp - 3)) // (max_tmp + 1)) // (max_tmp) is the limit
8387
    begin
8388
      $display("   i_length = %0d", i_length);
8389
      // prepare packet's CRC
8390
      if (num_of_bd == 1)
8391
        append_tx_crc(`MEMORY_BASE, (max_tmp - 4), 1'b0); // for second and third packets
8392
      // Reset_tx_bd nable interrupt generation
8393
      // unmask interrupts
8394
      wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
8395
                               `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8396
      // not detect carrier sense in FD and no collision
8397
      eth_phy.carrier_sense_tx_fd_detect(0);
8398
      eth_phy.collision(0);
8399
      // first destination address on ethernet PHY
8400
      eth_phy.set_tx_mem_addr(0);
8401
      // prepare BDs
8402
      if (num_of_bd == 0)
8403
      begin
8404
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8405
        set_tx_bd(1, 1, i_length+1, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8406
        set_tx_bd(2, 2, i_length+2, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8407
        set_tx_bd_wrap(2);
8408
        set_tx_bd_ready(0, 0);
8409
      end
8410
      else if (num_of_bd == 1)
8411
        set_tx_bd_ready(1, 1);
8412
      else if (num_of_bd == 2)
8413
        set_tx_bd_ready(2, 2);
8414
      // CHECK END OF TRANSMITION
8415
      check_tx_bd(num_of_bd, data);
8416
        wait (MTxEn === 1'b1); // start transmit
8417
      check_tx_bd(num_of_bd, data);
8418
        if (data[15] !== 1)
8419
        begin
8420
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
8421
          fail = fail + 1;
8422
        end
8423
        wait (MTxEn === 1'b0); // end transmit
8424
        while (data[15] === 1)
8425
        begin
8426
      check_tx_bd(num_of_bd, data);
8427
          @(posedge wb_clk);
8428
        end
8429
        repeat (1) @(posedge wb_clk);
8430
      // check length of a PACKET
8431
      $display("   eth_phy length = %0d", eth_phy.tx_len);
8432
      tmp_len = eth_phy.tx_len;
8433
      #1;
8434
      if (tmp_len != (i_length + 4))
8435
      begin
8436
        test_fail("Wrong length of the packet out from MAC");
8437
        fail = fail + 1;
8438
      end
8439
      // checking packet
8440
      check_tx_packet(`MEMORY_BASE, 0, i_length, tmp);
8441
      if (tmp > 0)
8442
      begin
8443
        test_fail("Wrong data of the transmitted packet");
8444
        fail = fail + 1;
8445
      end
8446
      // check transmited TX packet CRC
8447
      check_tx_crc(0, i_length, 1'b0, tmp); // length without CRC
8448
      if (tmp > 0)
8449
      begin
8450
        test_fail("Wrong CRC of the transmitted packet");
8451
        fail = fail + 1;
8452
      end
8453
      // check WB INT signal
8454
      if (wb_int !== 1'b1)
8455
      begin
8456
        `TIME; $display("*E WB INT signal should be set");
8457
        test_fail("WB INT signal should be set");
8458
        fail = fail + 1;
8459
      end
8460
      // check TX buffer descriptor of a packet
8461
      check_tx_bd(num_of_bd, data);
8462
      if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 2)) || // wrap bit
8463
           ((data[15:0] !== 16'h5800) && (num_of_bd < 2)) )   // without wrap bit
8464
      begin
8465
        `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
8466
        test_fail("TX buffer descriptor status is not correct");
8467
        fail = fail + 1;
8468
      end
8469
      // check interrupts
8470
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8471
      if ((data & `ETH_INT_TXB) !== 1'b1)
8472
      begin
8473
        `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
8474
        test_fail("Interrupt Transmit Buffer was not set");
8475
        fail = fail + 1;
8476
      end
8477
      if ((data & (~`ETH_INT_TXB)) !== 0)
8478
      begin
8479
        `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
8480
        test_fail("Other interrupts (except Transmit Buffer) were set");
8481
        fail = fail + 1;
8482
      end
8483
      // clear interrupts
8484
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8485
      // check WB INT signal
8486
      if (wb_int !== 1'b0)
8487
      begin
8488
        test_fail("WB INT signal should not be set");
8489
        fail = fail + 1;
8490
      end
8491
      // INTERMEDIATE DISPLAYS
8492
      if (num_of_bd == 0)
8493
        $display("    ->packet with length %0d sent", (i_length + 4));
8494
      else if (num_of_bd == 1)
8495
        $display("    ->packet with length %0d sent", (i_length + 4));
8496
      else if (num_of_bd == 2)
8497
        $display("    ->packet with length %0d sent", (i_length + 4));
8498
      // set length (loop variable)
8499
      i_length = i_length + 1;
8500
      // the number of frame transmitted
8501
      num_of_frames = num_of_frames + 1;
8502
      num_of_bd = num_of_bd + 1;
8503
      @(posedge wb_clk);
8504
    end
8505
    // disable TX
8506
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
8507
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8508
    @(posedge wb_clk);
8509
    if(fail == 0)
8510
      test_ok;
8511
    else
8512
      fail = 0;
8513
  end
8514
 
8515
 
8516
  ////////////////////////////////////////////////////////////////////
8517
  ////                                                            ////
8518
  ////  Test transmit packets across changed MINFL value at       ////
8519
  ////  7 TX buffer decriptors ( 10Mbps ).                        ////
8520
  ////                                                            ////
8521
  ////////////////////////////////////////////////////////////////////
8522
  if (test_num == 14) // without and with padding
8523
  begin
8524
    // TEST 14: TRANSMIT PACKETS ACROSS CHANGED MINFL VALUE AT 7 TX BDs ( 10Mbps )
8525
    test_name = "TEST 14: TRANSMIT PACKETS ACROSS CHANGED MINFL VALUE AT 7 TX BDs ( 10Mbps )";
8526
    `TIME; $display("  TEST 14: TRANSMIT PACKETS ACROSS CHANGED MINFL VALUE AT 7 TX BDs ( 10Mbps )");
8527
 
8528
    // reset MAC registers
8529
    hard_reset;
8530
    // reset MAC and MII LOGIC with soft reset
8531
    reset_mac;
8532
    reset_mii;
8533
    // set wb slave response
8534
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
8535
 
8536
    max_tmp = 0;
8537
    min_tmp = 0;
8538
    num_of_frames = 0;
8539
    num_of_bd = 0;
8540
    // set 7 TX buffer descriptors - must be set before TX enable
8541
    wbm_write(`ETH_TX_BD_NUM, 32'h7, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8542
    // prepare a packet of MAXFL + 10 length
8543
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8544
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
8545
    min_tmp = tmp[31:16];
8546
    // change MINFL value
8547
    min_tmp = max_tmp - 177;
8548
    wbm_write(`ETH_PACKETLEN, {min_tmp, max_tmp}, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8549
    st_data = 8'h62;
8550
    set_tx_packet(`MEMORY_BASE, min_tmp, st_data); // length without CRC
8551
    // enable TX, set full-duplex mode, padding and CRC appending
8552
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_PAD | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
8553
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8554
    // check WB INT signal
8555
    if (wb_int !== 1'b0)
8556
    begin
8557
      test_fail("WB INT signal should not be set");
8558
      fail = fail + 1;
8559
    end
8560
 
8561
    // write to phy's control register for 10Mbps
8562
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
8563
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
8564
    speed = 10;
8565
 
8566
    i_length = (min_tmp - 5);
8567
    while (i_length <= (min_tmp - 3)) // (min_tmp - 4) is the limit
8568
    begin
8569
      $display("   i_length = %0d", i_length);
8570
      // Reset_tx_bd nable interrupt generation
8571
      // unmask interrupts
8572
      wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
8573
                               `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8574
      // not detect carrier sense in FD and no collision
8575
      eth_phy.carrier_sense_tx_fd_detect(0);
8576
      eth_phy.collision(0);
8577
      // first destination address on ethernet PHY
8578
      eth_phy.set_tx_mem_addr(0);
8579
      // prepare BDs
8580
      if (num_of_bd == 0)
8581
      begin
8582
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8583
        set_tx_bd(1, 1, i_length+1, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8584
        set_tx_bd(2, 2, i_length+2, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8585
        set_tx_bd_wrap(2);
8586
        set_tx_bd_ready(0, 0);
8587
      end
8588
      else if (num_of_bd == 1)
8589
        set_tx_bd_ready(1, 1);
8590
      else if (num_of_bd == 2)
8591
        set_tx_bd_ready(2, 2);
8592
      // CHECK END OF TRANSMITION
8593
      check_tx_bd(num_of_bd, data);
8594
        wait (MTxEn === 1'b1); // start transmit
8595
      check_tx_bd(num_of_bd, data);
8596
        if (data[15] !== 1)
8597
        begin
8598
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
8599
          fail = fail + 1;
8600
        end
8601
        wait (MTxEn === 1'b0); // end transmit
8602
        while (data[15] === 1)
8603
        begin
8604
      check_tx_bd(num_of_bd, data);
8605
          @(posedge wb_clk);
8606
        end
8607
        repeat (1) @(posedge wb_clk);
8608
      // check length of a PACKET
8609
      $display("   eth_phy length = %0d", eth_phy.tx_len);
8610
      tmp_len = eth_phy.tx_len;
8611
      #1;
8612
      if (tmp_len != (i_length + 4))
8613
      begin
8614
        test_fail("Wrong length of the packet out from MAC");
8615
        fail = fail + 1;
8616
      end
8617
      // checking packet
8618
      check_tx_packet(`MEMORY_BASE, 0, i_length, tmp);
8619
      if (tmp > 0)
8620
      begin
8621
        test_fail("Wrong data of the transmitted packet");
8622
        fail = fail + 1;
8623
      end
8624
      // check transmited TX packet CRC
8625
      check_tx_crc(0, i_length, 1'b0, tmp); // length without CRC
8626
      if (tmp > 0)
8627
      begin
8628
        test_fail("Wrong CRC of the transmitted packet");
8629
        fail = fail + 1;
8630
      end
8631
      // check WB INT signal
8632
      if (wb_int !== 1'b1)
8633
      begin
8634
        `TIME; $display("*E WB INT signal should be set");
8635
        test_fail("WB INT signal should be set");
8636
        fail = fail + 1;
8637
      end
8638
      // check TX buffer descriptor of a packet
8639
      check_tx_bd(num_of_bd, data);
8640
      if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 2)) || // wrap bit
8641
           ((data[15:0] !== 16'h5800) && (num_of_bd < 2)) )   // without wrap bit
8642
      begin
8643
        `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
8644
        test_fail("TX buffer descriptor status is not correct");
8645
        fail = fail + 1;
8646
      end
8647
      // check interrupts
8648
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8649
      if ((data & `ETH_INT_TXB) !== 1'b1)
8650
      begin
8651
        `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
8652
        test_fail("Interrupt Transmit Buffer was not set");
8653
        fail = fail + 1;
8654
      end
8655
      if ((data & (~`ETH_INT_TXB)) !== 0)
8656
      begin
8657
        `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
8658
        test_fail("Other interrupts (except Transmit Buffer) were set");
8659
        fail = fail + 1;
8660
      end
8661
      // clear interrupts
8662
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8663
      // check WB INT signal
8664
      if (wb_int !== 1'b0)
8665
      begin
8666
        test_fail("WB INT signal should not be set");
8667
        fail = fail + 1;
8668
      end
8669
      // INTERMEDIATE DISPLAYS
8670
      if (num_of_bd == 0)
8671
        $display("    ->packet with length %0d sent", (i_length + 4));
8672
      else if (num_of_bd == 1)
8673
        $display("    ->packet with length %0d sent", (i_length + 4));
8674
      else if (num_of_bd == 2)
8675
        $display("    ->packet with length %0d sent", (i_length + 4));
8676
      // set length (loop variable)
8677
      i_length = i_length + 1;
8678
      // the number of frame transmitted
8679
      num_of_frames = num_of_frames + 1;
8680
      num_of_bd = num_of_bd + 1;
8681
      @(posedge wb_clk);
8682
    end
8683
    // disable TX
8684
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
8685
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8686
    @(posedge wb_clk);
8687
    if(fail == 0)
8688
      test_ok;
8689
    else
8690
      fail = 0;
8691
  end
8692
 
8693
 
8694
  ////////////////////////////////////////////////////////////////////
8695
  ////                                                            ////
8696
  ////  Test transmit packets across changed MINFL value at       ////
8697
  ////  7 TX buffer decriptors ( 100Mbps ).                       ////
8698
  ////                                                            ////
8699
  ////////////////////////////////////////////////////////////////////
8700
  if (test_num == 15) // without and with padding
8701
  begin
8702
    // TEST 15: TRANSMIT PACKETS ACROSS CHANGED MINFL VALUE AT 7 TX BDs ( 100Mbps )
8703
    test_name = "TEST 15: TRANSMIT PACKETS ACROSS CHANGED MINFL VALUE AT 7 TX BDs ( 100Mbps )";
8704
    `TIME; $display("  TEST 15: TRANSMIT PACKETS ACROSS CHANGED MINFL VALUE AT 7 TX BDs ( 100Mbps )");
8705
 
8706
    // reset MAC registers
8707
    hard_reset;
8708
    // reset MAC and MII LOGIC with soft reset
8709
    reset_mac;
8710
    reset_mii;
8711
    // set wb slave response
8712
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
8713
 
8714
    max_tmp = 0;
8715
    min_tmp = 0;
8716
    num_of_frames = 0;
8717
    num_of_bd = 0;
8718
    // set 7 TX buffer descriptors - must be set before TX enable
8719
    wbm_write(`ETH_TX_BD_NUM, 32'h7, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8720
    // prepare a packet of MAXFL + 10 length
8721
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8722
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
8723
    min_tmp = tmp[31:16];
8724
    // change MINFL value
8725
    min_tmp = max_tmp - 177;
8726
    wbm_write(`ETH_PACKETLEN, {min_tmp, max_tmp}, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8727
    st_data = 8'h62;
8728
    set_tx_packet(`MEMORY_BASE, min_tmp, st_data); // length without CRC
8729
    // enable TX, set full-duplex mode, padding and CRC appending
8730
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_PAD | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
8731
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8732
    // check WB INT signal
8733
    if (wb_int !== 1'b0)
8734
    begin
8735
      test_fail("WB INT signal should not be set");
8736
      fail = fail + 1;
8737
    end
8738
 
8739
    // write to phy's control register for 100Mbps
8740
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
8741
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
8742
    speed = 100;
8743
 
8744
    i_length = (min_tmp - 5);
8745
    while (i_length <= (min_tmp - 3)) // (min_tmp - 4) is the limit
8746
    begin
8747
      $display("   i_length = %0d", i_length);
8748
      // Reset_tx_bd nable interrupt generation
8749
      // unmask interrupts
8750
      wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
8751
                               `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8752
      // not detect carrier sense in FD and no collision
8753
      eth_phy.carrier_sense_tx_fd_detect(0);
8754
      eth_phy.collision(0);
8755
      // first destination address on ethernet PHY
8756
      eth_phy.set_tx_mem_addr(0);
8757
      // prepare BDs
8758
      if (num_of_bd == 0)
8759
      begin
8760
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8761
        set_tx_bd(1, 1, i_length+1, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8762
        set_tx_bd(2, 2, i_length+2, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8763
        set_tx_bd_wrap(2);
8764
        set_tx_bd_ready(0, 0);
8765
      end
8766
      else if (num_of_bd == 1)
8767
        set_tx_bd_ready(1, 1);
8768
      else if (num_of_bd == 2)
8769
        set_tx_bd_ready(2, 2);
8770
      // CHECK END OF TRANSMITION
8771
      check_tx_bd(num_of_bd, data);
8772
        wait (MTxEn === 1'b1); // start transmit
8773
      check_tx_bd(num_of_bd, data);
8774
        if (data[15] !== 1)
8775
        begin
8776
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
8777
          fail = fail + 1;
8778
        end
8779
        wait (MTxEn === 1'b0); // end transmit
8780
        while (data[15] === 1)
8781
        begin
8782
      check_tx_bd(num_of_bd, data);
8783
          @(posedge wb_clk);
8784
        end
8785
        repeat (1) @(posedge wb_clk);
8786
      // check length of a PACKET
8787
      $display("   eth_phy length = %0d", eth_phy.tx_len);
8788
      tmp_len = eth_phy.tx_len;
8789
      #1;
8790
      if (tmp_len != (i_length + 4))
8791
      begin
8792
        test_fail("Wrong length of the packet out from MAC");
8793
        fail = fail + 1;
8794
      end
8795
      // checking packet
8796
      check_tx_packet(`MEMORY_BASE, 0, i_length, tmp);
8797
      if (tmp > 0)
8798
      begin
8799
        test_fail("Wrong data of the transmitted packet");
8800
        fail = fail + 1;
8801
      end
8802
      // check transmited TX packet CRC
8803
      check_tx_crc(0, i_length, 1'b0, tmp); // length without CRC
8804
      if (tmp > 0)
8805
      begin
8806
        test_fail("Wrong CRC of the transmitted packet");
8807
        fail = fail + 1;
8808
      end
8809
      // check WB INT signal
8810
      if (wb_int !== 1'b1)
8811
      begin
8812
        `TIME; $display("*E WB INT signal should be set");
8813
        test_fail("WB INT signal should be set");
8814
        fail = fail + 1;
8815
      end
8816
      // check TX buffer descriptor of a packet
8817
      check_tx_bd(num_of_bd, data);
8818
      if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 2)) || // wrap bit
8819
           ((data[15:0] !== 16'h5800) && (num_of_bd < 2)) )   // without wrap bit
8820
      begin
8821
        `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
8822
        test_fail("TX buffer descriptor status is not correct");
8823
        fail = fail + 1;
8824
      end
8825
      // check interrupts
8826
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8827
      if ((data & `ETH_INT_TXB) !== 1'b1)
8828
      begin
8829
        `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
8830
        test_fail("Interrupt Transmit Buffer was not set");
8831
        fail = fail + 1;
8832
      end
8833
      if ((data & (~`ETH_INT_TXB)) !== 0)
8834
      begin
8835
        `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
8836
        test_fail("Other interrupts (except Transmit Buffer) were set");
8837
        fail = fail + 1;
8838
      end
8839
      // clear interrupts
8840
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8841
      // check WB INT signal
8842
      if (wb_int !== 1'b0)
8843
      begin
8844
        test_fail("WB INT signal should not be set");
8845
        fail = fail + 1;
8846
      end
8847
      // INTERMEDIATE DISPLAYS
8848
      if (num_of_bd == 0)
8849
        $display("    ->packet with length %0d sent", (i_length + 4));
8850
      else if (num_of_bd == 1)
8851
        $display("    ->packet with length %0d sent", (i_length + 4));
8852
      else if (num_of_bd == 2)
8853
        $display("    ->packet with length %0d sent", (i_length + 4));
8854
      // set length (loop variable)
8855
      i_length = i_length + 1;
8856
      // the number of frame transmitted
8857
      num_of_frames = num_of_frames + 1;
8858
      num_of_bd = num_of_bd + 1;
8859
      @(posedge wb_clk);
8860
    end
8861
    // disable TX
8862
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
8863
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8864
    @(posedge wb_clk);
8865
    if(fail == 0)
8866
      test_ok;
8867
    else
8868
      fail = 0;
8869
  end
8870
 
8871
 
8872
  ////////////////////////////////////////////////////////////////////
8873
  ////                                                            ////
8874
  ////  Test transmit packets across MAXFL with HUGEN at          ////
8875
  ////  19 TX buffer decriptors ( 10Mbps ).                       ////
8876
  ////                                                            ////
8877
  ////////////////////////////////////////////////////////////////////
8878
  if (test_num == 16) // without and with padding
8879
  begin
8880
    // TEST 16: TRANSMIT PACKETS ACROSS MAXFL WITH HUGEN AT 19 TX BDs ( 10Mbps )
8881
    test_name = "TEST 16: TRANSMIT PACKETS ACROSS MAXFL WITH HUGEN AT 19 TX BDs ( 10Mbps )";
8882
    `TIME; $display("  TEST 16: TRANSMIT PACKETS ACROSS MAXFL WITH HUGEN AT 19 TX BDs ( 10Mbps )");
8883
 
8884
    // reset MAC registers
8885
    hard_reset;
8886
    // reset MAC and MII LOGIC with soft reset
8887
    reset_mac;
8888
    reset_mii;
8889
    // set wb slave response
8890
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
8891
 
8892
    max_tmp = 0;
8893
    min_tmp = 0;
8894
    num_of_frames = 0;
8895
    num_of_bd = 0;
8896
    // set 19 TX buffer descriptors - must be set before TX enable
8897
    wbm_write(`ETH_TX_BD_NUM, 32'h13, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8898
    // prepare a packet of 64k - 1 length (16'hFFFF)
8899
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8900
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
8901
    min_tmp = tmp[31:16];
8902
    st_data = 8'h8D;
8903
    set_tx_packet(`MEMORY_BASE, 16'hFFFF, st_data); // length with CRC
8904
    // enable TX, set full-duplex mode, NO padding, CRC appending and huge enabled
8905
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN | `ETH_MODER_HUGEN,
8906
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8907
    // check WB INT signal
8908
    if (wb_int !== 1'b0)
8909
    begin
8910
      test_fail("WB INT signal should not be set");
8911
      fail = fail + 1;
8912
    end
8913
 
8914
    // write to phy's control register for 10Mbps
8915
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
8916
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
8917
    speed = 10;
8918
 
8919
    i_length = (max_tmp - 5); // (max_tmp - 4) is the MAXFL limit
8920
    while (i_length <= (16'hFFFF - 4)) // (16'hFFFF - 4) is the limit
8921
    begin
8922
      $display("   i_length = %0d", i_length);
8923
      // Reset_tx_bd nable interrupt generation
8924
      // unmask interrupts
8925
      wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
8926
                               `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
8927
      // not detect carrier sense in FD and no collision
8928
      eth_phy.carrier_sense_tx_fd_detect(0);
8929
      eth_phy.collision(0);
8930
      // first destination address on ethernet PHY
8931
      eth_phy.set_tx_mem_addr(0);
8932
      // prepare BDs
8933
      if (num_of_bd == 0)
8934
      begin
8935
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8936
        set_tx_bd(1, 1, i_length+1, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8937
        set_tx_bd(2, 2, i_length+2, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8938
        set_tx_bd(3, 3, (16'hFFFF - 5), 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8939
        set_tx_bd(4, 4, (16'hFFFF - 4), 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
8940
        set_tx_bd_wrap(4);
8941
        set_tx_bd_ready(0, 0);
8942
      end
8943
      else if (num_of_bd == 1)
8944
        set_tx_bd_ready(1, 1);
8945
      else if (num_of_bd == 2)
8946
        set_tx_bd_ready(2, 2);
8947
      else if (num_of_bd == 3)
8948
        set_tx_bd_ready(3, 3);
8949
      else if (num_of_bd == 4)
8950
        set_tx_bd_ready(4, 4);
8951
      // CHECK END OF TRANSMITION
8952
      check_tx_bd(num_of_bd, data);
8953
        wait (MTxEn === 1'b1); // start transmit
8954
      check_tx_bd(num_of_bd, data);
8955
        if (data[15] !== 1)
8956
        begin
8957
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
8958
          fail = fail + 1;
8959
        end
8960
        wait (MTxEn === 1'b0); // end transmit
8961
        while (data[15] === 1)
8962
        begin
8963
      check_tx_bd(num_of_bd, data);
8964
          @(posedge wb_clk);
8965
        end
8966
        repeat (1) @(posedge wb_clk);
8967
      // check length of a PACKET
8968
      $display("   eth_phy length = %0d", eth_phy.tx_len);
8969
      tmp_len = eth_phy.tx_len;
8970
      #1;
8971
      if (tmp_len != (i_length + 4))
8972
      begin
8973
        test_fail("Wrong length of the packet out from MAC");
8974
        fail = fail + 1;
8975
      end
8976
      // checking packet
8977
      check_tx_packet(`MEMORY_BASE, 0, i_length, tmp);
8978
      if (tmp > 0)
8979
      begin
8980
        test_fail("Wrong data of the transmitted packet");
8981
        fail = fail + 1;
8982
      end
8983
      // check transmited TX packet CRC
8984
      check_tx_crc(0, i_length, 1'b0, tmp); // length without CRC
8985
      if (tmp > 0)
8986
      begin
8987
        test_fail("Wrong CRC of the transmitted packet");
8988
        fail = fail + 1;
8989
      end
8990
      // check WB INT signal
8991
      if (wb_int !== 1'b1)
8992
      begin
8993
        `TIME; $display("*E WB INT signal should be set");
8994
        test_fail("WB INT signal should be set");
8995
        fail = fail + 1;
8996
      end
8997
      // check TX buffer descriptor of a packet
8998
      check_tx_bd(num_of_bd, data);
8999
      if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 4)) || // wrap bit
9000
           ((data[15:0] !== 16'h5800) && (num_of_bd < 4)) )   // without wrap bit
9001
      begin
9002
        `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
9003
        test_fail("TX buffer descriptor status is not correct");
9004
        fail = fail + 1;
9005
      end
9006
      // check interrupts
9007
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9008
      if ((data & `ETH_INT_TXB) !== 1'b1)
9009
      begin
9010
        `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
9011
        test_fail("Interrupt Transmit Buffer was not set");
9012
        fail = fail + 1;
9013
      end
9014
      if ((data & (~`ETH_INT_TXB)) !== 0)
9015
      begin
9016
        `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
9017
        test_fail("Other interrupts (except Transmit Buffer) were set");
9018
        fail = fail + 1;
9019
      end
9020
      // clear interrupts
9021
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9022
      // check WB INT signal
9023
      if (wb_int !== 1'b0)
9024
      begin
9025
        test_fail("WB INT signal should not be set");
9026
        fail = fail + 1;
9027
      end
9028
      // INTERMEDIATE DISPLAYS
9029
      $display("    ->packet with length %0d sent", (i_length + 4));
9030
      // set length (loop variable)
9031
      if ((num_of_bd < 2) || (num_of_bd >= 3))
9032
        i_length = i_length + 1;
9033
      else if (num_of_bd == 2)
9034
        i_length = (16'hFFFF - 5);
9035
      // the number of frame transmitted
9036
      num_of_frames = num_of_frames + 1;
9037
      num_of_bd = num_of_bd + 1;
9038
      @(posedge wb_clk);
9039
    end
9040
    // disable TX
9041
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
9042
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9043
    @(posedge wb_clk);
9044
    if(fail == 0)
9045
      test_ok;
9046
    else
9047
      fail = 0;
9048
  end
9049
 
9050
 
9051
  ////////////////////////////////////////////////////////////////////
9052
  ////                                                            ////
9053
  ////  Test transmit packets across MAXFL with HUGEN at          ////
9054
  ////  19 TX buffer decriptors ( 100Mbps ).                      ////
9055
  ////                                                            ////
9056
  ////////////////////////////////////////////////////////////////////
9057
  if (test_num == 17) // without and with padding
9058
  begin
9059
    // TEST 17: TRANSMIT PACKETS ACROSS MAXFL WITH HUGEN AT 19 TX BDs ( 100Mbps )
9060
    test_name = "TEST 17: TRANSMIT PACKETS ACROSS MAXFL WITH HUGEN AT 19 TX BDs ( 100Mbps )";
9061
    `TIME; $display("  TEST 17: TRANSMIT PACKETS ACROSS MAXFL WITH HUGEN AT 19 TX BDs ( 100Mbps )");
9062
 
9063
    // reset MAC registers
9064
    hard_reset;
9065
    // reset MAC and MII LOGIC with soft reset
9066
    reset_mac;
9067
    reset_mii;
9068
    // set wb slave response
9069
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
9070
 
9071
    max_tmp = 0;
9072
    min_tmp = 0;
9073
    num_of_frames = 0;
9074
    num_of_bd = 0;
9075
    // set 19 TX buffer descriptors - must be set before TX enable
9076
    wbm_write(`ETH_TX_BD_NUM, 32'h13, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9077
    // prepare a packet of 64k - 1 length (16'hFFFF)
9078
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9079
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
9080
    min_tmp = tmp[31:16];
9081
    st_data = 8'h8D;
9082
    set_tx_packet(`MEMORY_BASE, 16'hFFFF, st_data); // length with CRC
9083
    // enable TX, set full-duplex mode, NO padding, CRC appending and huge enabled
9084
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN | `ETH_MODER_HUGEN,
9085
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9086
    // check WB INT signal
9087
    if (wb_int !== 1'b0)
9088
    begin
9089
      test_fail("WB INT signal should not be set");
9090
      fail = fail + 1;
9091
    end
9092
 
9093
    // write to phy's control register for 100Mbps
9094
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
9095
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
9096
    speed = 100;
9097
 
9098
    i_length = (max_tmp - 5); // (max_tmp - 4) is the MAXFL limit
9099
    while (i_length <= (16'hFFFF - 4)) // (16'hFFFF - 4) is the limit
9100
    begin
9101
      $display("   i_length = %0d", i_length);
9102
      // Reset_tx_bd nable interrupt generation
9103
      // unmask interrupts
9104
      wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
9105
                               `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9106
      // not detect carrier sense in FD and no collision
9107
      eth_phy.carrier_sense_tx_fd_detect(0);
9108
      eth_phy.collision(0);
9109
      // first destination address on ethernet PHY
9110
      eth_phy.set_tx_mem_addr(0);
9111
      // prepare BDs
9112
      if (num_of_bd == 0)
9113
      begin
9114
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
9115
        set_tx_bd(1, 1, i_length+1, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
9116
        set_tx_bd(2, 2, i_length+2, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
9117
        set_tx_bd(3, 3, (16'hFFFF - 5), 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
9118
        set_tx_bd(4, 4, (16'hFFFF - 4), 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
9119
        set_tx_bd_wrap(4);
9120
        set_tx_bd_ready(0, 0);
9121
      end
9122
      else if (num_of_bd == 1)
9123
        set_tx_bd_ready(1, 1);
9124
      else if (num_of_bd == 2)
9125
        set_tx_bd_ready(2, 2);
9126
      else if (num_of_bd == 3)
9127
        set_tx_bd_ready(3, 3);
9128
      else if (num_of_bd == 4)
9129
        set_tx_bd_ready(4, 4);
9130
      // CHECK END OF TRANSMITION
9131
      check_tx_bd(num_of_bd, data);
9132
        wait (MTxEn === 1'b1); // start transmit
9133
      check_tx_bd(num_of_bd, data);
9134
        if (data[15] !== 1)
9135
        begin
9136
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
9137
          fail = fail + 1;
9138
        end
9139
        wait (MTxEn === 1'b0); // end transmit
9140
        while (data[15] === 1)
9141
        begin
9142
      check_tx_bd(num_of_bd, data);
9143
          @(posedge wb_clk);
9144
        end
9145
        repeat (1) @(posedge wb_clk);
9146
      // check length of a PACKET
9147
      $display("   eth_phy length = %0d", eth_phy.tx_len);
9148
      tmp_len = eth_phy.tx_len;
9149
      #1;
9150
      if (tmp_len != (i_length + 4))
9151
      begin
9152
        test_fail("Wrong length of the packet out from MAC");
9153
        fail = fail + 1;
9154
      end
9155
      // checking packet
9156
      check_tx_packet(`MEMORY_BASE, 0, i_length, tmp);
9157
      if (tmp > 0)
9158
      begin
9159
        test_fail("Wrong data of the transmitted packet");
9160
        fail = fail + 1;
9161
      end
9162
      // check transmited TX packet CRC
9163
      check_tx_crc(0, i_length, 1'b0, tmp); // length without CRC
9164
      if (tmp > 0)
9165
      begin
9166
        test_fail("Wrong CRC of the transmitted packet");
9167
        fail = fail + 1;
9168
      end
9169
      // check WB INT signal
9170
      if (wb_int !== 1'b1)
9171
      begin
9172
        `TIME; $display("*E WB INT signal should be set");
9173
        test_fail("WB INT signal should be set");
9174
        fail = fail + 1;
9175
      end
9176
      // check TX buffer descriptor of a packet
9177
      check_tx_bd(num_of_bd, data);
9178
      if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 4)) || // wrap bit
9179
           ((data[15:0] !== 16'h5800) && (num_of_bd < 4)) )   // without wrap bit
9180
      begin
9181
        `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
9182
        test_fail("TX buffer descriptor status is not correct");
9183
        fail = fail + 1;
9184
      end
9185
      // check interrupts
9186
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9187
      if ((data & `ETH_INT_TXB) !== 1'b1)
9188
      begin
9189
        `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
9190
        test_fail("Interrupt Transmit Buffer was not set");
9191
        fail = fail + 1;
9192
      end
9193
      if ((data & (~`ETH_INT_TXB)) !== 0)
9194
      begin
9195
        `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
9196
        test_fail("Other interrupts (except Transmit Buffer) were set");
9197
        fail = fail + 1;
9198
      end
9199
      // clear interrupts
9200
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9201
      // check WB INT signal
9202
      if (wb_int !== 1'b0)
9203
      begin
9204
        test_fail("WB INT signal should not be set");
9205
        fail = fail + 1;
9206
      end
9207
      // INTERMEDIATE DISPLAYS
9208
      $display("    ->packet with length %0d sent", (i_length + 4));
9209
      // set length (loop variable)
9210
      if ((num_of_bd < 2) || (num_of_bd >= 3))
9211
        i_length = i_length + 1;
9212
      else if (num_of_bd == 2)
9213
        i_length = (16'hFFFF - 5);
9214
      // the number of frame transmitted
9215
      num_of_frames = num_of_frames + 1;
9216
      num_of_bd = num_of_bd + 1;
9217
      @(posedge wb_clk);
9218
    end
9219
    // disable TX
9220
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
9221
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9222
    @(posedge wb_clk);
9223
    if(fail == 0)
9224
      test_ok;
9225
    else
9226
      fail = 0;
9227
  end
9228
 
9229
 
9230
  ////////////////////////////////////////////////////////////////////
9231
  ////                                                            ////
9232
  ////  Test IPG during Back-to-Back transmit at                  ////
9233
  ////  88 TX buffer decriptors ( 10Mbps ).                       ////
9234
  ////                                                            ////
9235
  ////////////////////////////////////////////////////////////////////
9236
  if (test_num == 18) // without and with padding
9237
  begin
9238
    // TEST 18: IPG DURING BACK-TO-BACK TRANSMIT AT 88 TX BDs ( 10Mbps )
9239
    test_name = "TEST 18: IPG DURING BACK-TO-BACK TRANSMIT AT 88 TX BDs ( 10Mbps )";
9240
    `TIME; $display("  TEST 18: IPG DURING BACK-TO-BACK TRANSMIT AT 88 TX BDs ( 10Mbps )");
9241
 
9242
    // reset MAC registers
9243
    hard_reset;
9244
    // reset MAC and MII LOGIC with soft reset
9245
    reset_mac;
9246
    reset_mii;
9247
    // set wb slave response
9248
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
9249
 
9250
    max_tmp = 0;
9251
    min_tmp = 0;
9252
    num_of_frames = 0;
9253
    num_of_bd = 0;
9254
    tmp_ipgt = 0;
9255
    // set 88 TX buffer descriptors - must be set before TX enable
9256
    wbm_write(`ETH_TX_BD_NUM, 32'h58, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9257
    // enable TX, set full-duplex mode, NO padding and CRC appending
9258
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
9259
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9260
    // prepare two packets of MAXFL length
9261
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9262
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
9263
    min_tmp = tmp[31:16];
9264
    st_data = 8'h29;
9265
    set_tx_packet(`MEMORY_BASE, (max_tmp - 4), st_data); // length without CRC
9266
    // check WB INT signal
9267
    if (wb_int !== 1'b0)
9268
    begin
9269
      test_fail("WB INT signal should not be set");
9270
      fail = fail + 1;
9271
    end
9272
 
9273
    // write to phy's control register for 10Mbps
9274
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
9275
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
9276
    speed = 10;
9277
 
9278
    i_length = (min_tmp - 4);
9279
    while (i_length < (max_tmp - 4))
9280
    begin
9281
      // disable TX, set full-duplex mode, NO padding and CRC appending
9282
      wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
9283
                4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9284
      // set IPGT register
9285
      wbm_write(`ETH_IPGT, tmp_ipgt, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9286
      // enable TX, set full-duplex mode, NO padding and CRC appending
9287
      wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
9288
                4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9289
      // Reset_tx_bd enable interrupt generation
9290
      // unmask interrupts
9291
      wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
9292
                               `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9293
      // not detect carrier sense in FD and no collision
9294
      eth_phy.carrier_sense_tx_fd_detect(0);
9295
      eth_phy.collision(0);
9296
      // first destination address on ethernet PHY
9297
      eth_phy.set_tx_mem_addr(0);
9298
      // prepare BDs
9299
      if (num_of_bd == 0)
9300
      begin
9301
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
9302
        set_tx_bd(1, 1, i_length+1, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
9303
        set_tx_bd_wrap(1);
9304
        set_tx_bd_ready(0, 0);
9305
        set_tx_bd_ready(1, 1);
9306
      end
9307
      // CHECK END OF TWO TRANSMITIONs
9308
      // wait for first transmit to end
9309
      check_tx_bd(num_of_bd, data);
9310
      wait (MTxEn === 1'b1); // start transmit
9311
      if (data[15] !== 1)
9312
      begin
9313
        test_fail("Wrong buffer descriptor's ready bit read out from MAC");
9314
        fail = fail + 1;
9315
      end
9316
      wait (MTxEn === 1'b0); // end transmit
9317
      num_of_frames = num_of_frames + 1;
9318
      num_of_bd = num_of_bd + 1;
9319
      #Tp;
9320
      // destination address on ethernet PHY
9321
      eth_phy.set_tx_mem_addr(0);
9322
      i1 = 0;
9323
      i2 = 0;
9324
      // count IPG clock periods
9325
      fork
9326
        begin
9327
          wait (MTxEn === 1'b1); // start second transmit
9328
          #Tp;
9329
          disable count_rising;
9330
          disable count_falling;
9331
        end
9332
        begin: count_rising
9333
          forever
9334
          begin
9335
            @(posedge mtx_clk);
9336
            i1 = i1 + 1;
9337
            #Tp;
9338
          end
9339
        end
9340
        begin: count_falling
9341
          forever
9342
          begin
9343
            @(negedge mtx_clk);
9344
            i2 = i2 + 1;
9345
            #Tp;
9346
          end
9347
        end
9348
      join
9349
      // check IPG length - INTERMEDIATE DISPLAYS
9350
      if((i1 == i2) && (i1 >= (tmp_ipgt + 3)))
9351
      begin
9352
        $display("    ->IPG with %0d mtx_clk periods (min %0d) between packets with lengths %0d and %0d checked",
9353
                  i1, (tmp_ipgt + 3), (i_length + 4), (i_length + 4 + 1));
9354
      end
9355
      else
9356
      begin
9357
        `TIME; $display("*E IPG is not correct: (%0d + %0d) / 2, requested: %d", i1, i2, (tmp_ipgt + 3));
9358
        fail = fail + 1;
9359
        test_fail("IPG is not correct");
9360
      end
9361
      // wait for second transmit to end
9362
      wait (MTxEn === 1'b0); // end second transmit
9363
      while (data[15] === 1)
9364
      begin
9365
        check_tx_bd(num_of_bd, data);
9366
        @(posedge wb_clk);
9367
      end
9368
      repeat (1) @(posedge wb_clk);
9369
      // check length of a second PACKET
9370
      tmp_len = eth_phy.tx_len;
9371
      #1;
9372
      if (tmp_len != (i_length + 4 + 1))
9373
      begin
9374
        test_fail("Wrong length of second packet out from MAC");
9375
        fail = fail + 1;
9376
      end
9377
      // checking second packet
9378
      check_tx_packet(`MEMORY_BASE, 0, (i_length + 1), tmp);
9379
      if (tmp > 0)
9380
      begin
9381
        test_fail("Wrong data of second transmitted packet");
9382
        fail = fail + 1;
9383
      end
9384
      // check second transmited TX packet CRC
9385
      check_tx_crc(0, (i_length + 1), 1'b0, tmp); // length without CRC
9386
      if (tmp > 0)
9387
      begin
9388
        test_fail("Wrong CRC of second transmitted packet");
9389
        fail = fail + 1;
9390
      end
9391
      // check WB INT signal
9392
      if (wb_int !== 1'b1)
9393
      begin
9394
        `TIME; $display("*E WB INT signal should be set");
9395
        test_fail("WB INT signal should be set");
9396
        fail = fail + 1;
9397
      end
9398
      // check TX buffer descriptor of a packet
9399
      check_tx_bd(num_of_bd, data);
9400
      if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 1)) || // wrap bit
9401
           ((data[15:0] !== 16'h5800) && (num_of_bd < 1)) )   // without wrap bit
9402
      begin
9403
        `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
9404
        test_fail("TX buffer descriptor status is not correct");
9405
        fail = fail + 1;
9406
      end
9407
      // check interrupts
9408
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9409
      if ((data & `ETH_INT_TXB) !== 1'b1)
9410
      begin
9411
        `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
9412
        test_fail("Interrupt Transmit Buffer was not set");
9413
        fail = fail + 1;
9414
      end
9415
      if ((data & (~`ETH_INT_TXB)) !== 0)
9416
      begin
9417
        `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
9418
        test_fail("Other interrupts (except Transmit Buffer) were set");
9419
        fail = fail + 1;
9420
      end
9421
      // clear interrupts
9422
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9423
      // check WB INT signal
9424
      if (wb_int !== 1'b0)
9425
      begin
9426
        test_fail("WB INT signal should not be set");
9427
        fail = fail + 1;
9428
      end
9429
      // set length (LOOP variable)
9430
      if ((tmp_ipgt + 3) < 130) // tmp_ipgt < 124
9431
        i_length = i_length + 2;
9432
      else
9433
        i_length = (max_tmp - 4);
9434
      // set IPGT
9435
      if ((tmp_ipgt + 3) < 10)
9436
        tmp_ipgt = tmp_ipgt + 1;
9437
      else if ((tmp_ipgt + 3) < 24)
9438
        tmp_ipgt = tmp_ipgt + 7;
9439
      else if ((tmp_ipgt + 3) == 24)
9440
        tmp_ipgt = 38 - 3;
9441
      else if ((tmp_ipgt + 3) == 38)
9442
        tmp_ipgt = 72 - 3;
9443
      else if ((tmp_ipgt + 3) == 72)
9444
        tmp_ipgt = 130 - 3; // 124 - 3
9445
      // the number of frame transmitted
9446
      num_of_frames = num_of_frames + 1;
9447
      num_of_bd = 0;
9448
      @(posedge wb_clk);
9449
    end
9450
    // disable TX
9451
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
9452
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9453
    @(posedge wb_clk);
9454
    if(fail == 0)
9455
      test_ok;
9456
    else
9457
      fail = 0;
9458
  end
9459
 
9460
 
9461
  ////////////////////////////////////////////////////////////////////
9462
  ////                                                            ////
9463
  ////  Test IPG during Back-to-Back transmit at                  ////
9464
  ////  88 TX buffer decriptors ( 100Mbps ).                      ////
9465
  ////                                                            ////
9466
  ////////////////////////////////////////////////////////////////////
9467
  if (test_num == 19) // without and with padding
9468
  begin
9469
    // TEST 19: IPG DURING BACK-TO-BACK TRANSMIT AT 88 TX BDs ( 100Mbps )
9470
    test_name = "TEST 19: IPG DURING BACK-TO-BACK TRANSMIT AT 88 TX BDs ( 100Mbps )";
9471
    `TIME; $display("  TEST 19: IPG DURING BACK-TO-BACK TRANSMIT AT 88 TX BDs ( 100Mbps )");
9472
 
9473
    // reset MAC registers
9474
    hard_reset;
9475
    // reset MAC and MII LOGIC with soft reset
9476
    reset_mac;
9477
    reset_mii;
9478
    // set wb slave response
9479
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
9480
 
9481
    max_tmp = 0;
9482
    min_tmp = 0;
9483
    num_of_frames = 0;
9484
    num_of_bd = 0;
9485
    tmp_ipgt = 0;
9486
    // set 88 TX buffer descriptors - must be set before TX enable
9487
    wbm_write(`ETH_TX_BD_NUM, 32'h58, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9488
    // enable TX, set full-duplex mode, NO padding and CRC appending
9489
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
9490
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9491
    // prepare two packets of MAXFL length
9492
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9493
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
9494
    min_tmp = tmp[31:16];
9495
    st_data = 8'h29;
9496
    set_tx_packet(`MEMORY_BASE, (max_tmp - 4), st_data); // length without CRC
9497
    // check WB INT signal
9498
    if (wb_int !== 1'b0)
9499
    begin
9500
      test_fail("WB INT signal should not be set");
9501
      fail = fail + 1;
9502
    end
9503
 
9504
    // write to phy's control register for 100Mbps
9505
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
9506
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
9507
    speed = 100;
9508
 
9509
    i_length = (min_tmp - 4);
9510
    while (i_length < (max_tmp - 4))
9511
    begin
9512
      // disable TX, set full-duplex mode, NO padding and CRC appending
9513
      wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
9514
                4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9515
      // set IPGT register
9516
      wbm_write(`ETH_IPGT, tmp_ipgt, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9517
      // enable TX, set full-duplex mode, NO padding and CRC appending
9518
      wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
9519
                4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9520
      // Reset_tx_bd enable interrupt generation
9521
      // unmask interrupts
9522
      wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
9523
                               `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9524
      // not detect carrier sense in FD and no collision
9525
      eth_phy.carrier_sense_tx_fd_detect(0);
9526
      eth_phy.collision(0);
9527
      // first destination address on ethernet PHY
9528
      eth_phy.set_tx_mem_addr(0);
9529
      // prepare BDs
9530
      if (num_of_bd == 0)
9531
      begin
9532
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
9533
        set_tx_bd(1, 1, i_length+1, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
9534
        set_tx_bd_wrap(1);
9535
        set_tx_bd_ready(0, 0);
9536
        set_tx_bd_ready(1, 1);
9537
      end
9538
      // CHECK END OF TWO TRANSMITIONs
9539
      // wait for first transmit to end
9540
      check_tx_bd(num_of_bd, data);
9541
      wait (MTxEn === 1'b1); // start transmit
9542
      if (data[15] !== 1)
9543
      begin
9544
        test_fail("Wrong buffer descriptor's ready bit read out from MAC");
9545
        fail = fail + 1;
9546
      end
9547
      wait (MTxEn === 1'b0); // end transmit
9548
      num_of_frames = num_of_frames + 1;
9549
      num_of_bd = num_of_bd + 1;
9550
      #Tp;
9551
      // destination address on ethernet PHY
9552
      eth_phy.set_tx_mem_addr(0);
9553
      i1 = 0;
9554
      i2 = 0;
9555
      // count IPG clock periods
9556
      fork
9557
        begin
9558
          wait (MTxEn === 1'b1); // start second transmit
9559
          #Tp;
9560
          disable count_rising1;
9561
          disable count_falling1;
9562
        end
9563
        begin: count_rising1
9564
          forever
9565
          begin
9566
            @(posedge mtx_clk);
9567
            i1 = i1 + 1;
9568
            #Tp;
9569
          end
9570
        end
9571
        begin: count_falling1
9572
          forever
9573
          begin
9574
            @(negedge mtx_clk);
9575
            i2 = i2 + 1;
9576
            #Tp;
9577
          end
9578
        end
9579
      join
9580
      // check IPG length - INTERMEDIATE DISPLAYS
9581
      if((i1 == i2) && (i1 >= (tmp_ipgt + 3)))
9582
      begin
9583
        $display("    ->IPG with %0d mtx_clk periods (min %0d) between packets with lengths %0d and %0d checked",
9584
                  i1, (tmp_ipgt + 3), (i_length + 4), (i_length + 4 + 1));
9585
      end
9586
      else
9587
      begin
9588
        `TIME; $display("*E IPG is not correct: (%0d + %0d) / 2, requested: %d", i1, i2, (tmp_ipgt + 3));
9589
        fail = fail + 1;
9590
        test_fail("IPG is not correct");
9591
      end
9592
      // wait for second transmit to end
9593
      wait (MTxEn === 1'b0); // end second transmit
9594
      while (data[15] === 1)
9595
      begin
9596
        check_tx_bd(num_of_bd, data);
9597
        @(posedge wb_clk);
9598
      end
9599
      repeat (1) @(posedge wb_clk);
9600
      // check length of a second PACKET
9601
      tmp_len = eth_phy.tx_len;
9602
      #1;
9603
      if (tmp_len != (i_length + 4 + 1))
9604
      begin
9605
        test_fail("Wrong length of second packet out from MAC");
9606
        fail = fail + 1;
9607
      end
9608
      // checking second packet
9609
      check_tx_packet(`MEMORY_BASE, 0, (i_length + 1), tmp);
9610
      if (tmp > 0)
9611
      begin
9612
        test_fail("Wrong data of second transmitted packet");
9613
        fail = fail + 1;
9614
      end
9615
      // check second transmited TX packet CRC
9616
      check_tx_crc(0, (i_length + 1), 1'b0, tmp); // length without CRC
9617
      if (tmp > 0)
9618
      begin
9619
        test_fail("Wrong CRC of second transmitted packet");
9620
        fail = fail + 1;
9621
      end
9622
      // check WB INT signal
9623
      if (wb_int !== 1'b1)
9624
      begin
9625
        `TIME; $display("*E WB INT signal should be set");
9626
        test_fail("WB INT signal should be set");
9627
        fail = fail + 1;
9628
      end
9629
      // check TX buffer descriptor of a packet
9630
      check_tx_bd(num_of_bd, data);
9631
      if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 1)) || // wrap bit
9632
           ((data[15:0] !== 16'h5800) && (num_of_bd < 1)) )   // without wrap bit
9633
      begin
9634
        `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
9635
        test_fail("TX buffer descriptor status is not correct");
9636
        fail = fail + 1;
9637
      end
9638
      // check interrupts
9639
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9640
      if ((data & `ETH_INT_TXB) !== 1'b1)
9641
      begin
9642
        `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
9643
        test_fail("Interrupt Transmit Buffer was not set");
9644
        fail = fail + 1;
9645
      end
9646
      if ((data & (~`ETH_INT_TXB)) !== 0)
9647
      begin
9648
        `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
9649
        test_fail("Other interrupts (except Transmit Buffer) were set");
9650
        fail = fail + 1;
9651
      end
9652
      // clear interrupts
9653
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9654
      // check WB INT signal
9655
      if (wb_int !== 1'b0)
9656
      begin
9657
        test_fail("WB INT signal should not be set");
9658
        fail = fail + 1;
9659
      end
9660
      // set length (LOOP variable)
9661
      if ((tmp_ipgt + 3) < 130) // tmp_ipgt < 124
9662
        i_length = i_length + 2;
9663
      else
9664
        i_length = (max_tmp - 4);
9665
      // set IPGT
9666
      if ((tmp_ipgt + 3) < 10)
9667
        tmp_ipgt = tmp_ipgt + 1;
9668
      else if ((tmp_ipgt + 3) < 24)
9669
        tmp_ipgt = tmp_ipgt + 7;
9670
      else if ((tmp_ipgt + 3) == 24)
9671
        tmp_ipgt = 38 - 3;
9672
      else if ((tmp_ipgt + 3) == 38)
9673
        tmp_ipgt = 72 - 3;
9674
      else if ((tmp_ipgt + 3) == 72)
9675
        tmp_ipgt = 130 - 3; // 124 - 3
9676
      // the number of frame transmitted
9677
      num_of_frames = num_of_frames + 1;
9678
      num_of_bd = 0;
9679
      @(posedge wb_clk);
9680
    end
9681
    // disable TX
9682
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
9683
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9684
    @(posedge wb_clk);
9685
    if(fail == 0)
9686
      test_ok;
9687
    else
9688
      fail = 0;
9689
  end
9690
 
9691
 
9692
  ////////////////////////////////////////////////////////////////////
9693
  ////                                                            ////
9694
  ////  Test transmit packets after TX under-run on each packet's ////
9695
  ////  byte at 2 TX buffer decriptors ( 10Mbps ).                ////
9696
  ////                                                            ////
9697
  ////////////////////////////////////////////////////////////////////
9698
  if (test_num == 20) // without padding
9699
  begin
9700
    // TEST 20: TRANSMIT PACKETS AFTER TX UNDER-RUN ON EACH PACKET's BYTE AT 2 TX BDs ( 10Mbps )
9701
    test_name = "TEST 20: TRANSMIT PACKETS AFTER TX UNDER-RUN ON EACH PACKET's BYTE AT 2 TX BDs ( 10Mbps )";
9702
    `TIME;
9703
    $display("  TEST 20: TRANSMIT PACKETS AFTER TX UNDER-RUN ON EACH PACKET's BYTE AT 2 TX BDs ( 10Mbps )");
9704
 
9705
    // reset MAC registers
9706
    hard_reset;
9707
    // reset MAC and MII LOGIC with soft reset
9708
    reset_mac;
9709
    reset_mii;
9710
    // set wb slave response
9711
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
9712
 
9713
    max_tmp = 0;
9714
    min_tmp = 0;
9715
    // set 2 TX buffer descriptors - must be set before TX enable
9716
    wbm_write(`ETH_TX_BD_NUM, 32'h2, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9717
    // enable TX, set full-duplex mode, NO padding and CRC appending
9718
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN |/* `ETH_MODER_PAD |*/ `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
9719
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9720
    // prepare a packet of MAXFL length
9721
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9722
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
9723
    min_tmp = tmp[31:16];
9724
    st_data = 8'h99;
9725
    set_tx_packet(`MEMORY_BASE, (max_tmp - 4), st_data); // length without CRC
9726
    // read IPG value
9727
    wbm_read(`ETH_IPGT, tmp_ipgt, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9728
    // check WB INT signal
9729
    if (wb_int !== 1'b0)
9730
    begin
9731
      test_fail("WB INT signal should not be set");
9732
      fail = fail + 1;
9733
    end
9734
 
9735
    // write to phy's control register for 10Mbps
9736
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
9737
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
9738
    speed = 10;
9739
 
9740 223 tadejm
    num_of_frames = 40; // (0..3) => start under-run on first word
9741 209 tadejm
    num_of_bd = 0;
9742
    i_data = 3; // (3) => one BYTE read in first word - FIRST byte
9743
    i_length = (min_tmp + 4);
9744
    while (i_length < (max_tmp - 4))
9745
    begin
9746
      // Reset_tx_bd enable interrupt generation
9747
      // unmask interrupts
9748
      wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
9749
                               `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9750
      // not detect carrier sense in FD and no collision
9751
      eth_phy.carrier_sense_tx_fd_detect(0);
9752
      eth_phy.collision(0);
9753
      // first destination address on ethernet PHY
9754
      eth_phy.set_tx_mem_addr(0);
9755
      // prepare BDs
9756
      if (num_of_bd == 0)
9757
      begin
9758
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, (`MEMORY_BASE + i_data[1:0]));
9759
        set_tx_bd(1, 1, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
9760
        set_tx_bd_wrap(1);
9761
        // set wb slave response: ACK (response), wbs_waits[2:0] (waits before response), 
9762
        //                       wbs_retries[7:0] (RTYs before ACK if RTY response selected)
9763 223 tadejm
        #1 wb_slave.cycle_response(`ACK_RESPONSE, 3'h0, 8'h0);
9764 209 tadejm
        set_tx_bd_ready(1, 1);
9765
        set_tx_bd_ready(0, 0);
9766
      end
9767
      // frame under-run checking
9768
      frame_started = 0;
9769
      frame_ended = 0;
9770
      wait_for_frame = 0;
9771
      fork
9772
        begin
9773
          // for every 4 frames bytes 1, 2, 3 and 4 respectively are read in first word => 1 ACK
9774
          // in other words 4 bytes are read, since length is MINFL => num_of_frames[31:2] ACKs
9775
          repeat ((num_of_frames[31:2] + 1'b1)) @(posedge eth_ma_wb_ack_i);
9776
          @(negedge eth_ma_wb_ack_i); // wait for last ACK to finish
9777
          // set wb slave response: ACK (response), wbs_waits[2:0] (waits before response), 
9778
          //                       wbs_retries[7:0] (RTYs before ACK if RTY response selected)
9779 223 tadejm
          #1 wb_slave.cycle_response(`NO_RESPONSE, 3'h0, 8'hFF);
9780 209 tadejm
          // wait for synchronization and some additional clocks
9781
          wait_for_frame = 1;
9782
          // wait for frame
9783
          wait ((wait_for_frame == 0) || (frame_started == 1))
9784
          if ((wait_for_frame == 0) && (frame_started == 0)) // frame didn't start
9785
          begin
9786
            disable check_fr;
9787
          end
9788
          else if ((wait_for_frame == 1) && (frame_started == 1)) // frame started
9789
          begin
9790
            disable wait_fr;
9791
            wait (frame_ended == 1);
9792
          end
9793
          repeat (2) @(posedge wb_clk);
9794
          // set wb slave response: ACK (response), wbs_waits[2:0] (waits before response), 
9795
          //                       wbs_retries[7:0] (RTYs before ACK if RTY response selected)
9796 223 tadejm
          wb_slave.cycle_response(`ACK_RESPONSE, 3'h0, 8'h0);
9797 209 tadejm
        end
9798
        begin: wait_fr
9799
          wait (wait_for_frame == 1)
9800
          begin
9801
            // wait for synchronization and some additional clocks
9802
            repeat (3) @(posedge wb_clk);
9803
            repeat (2 * tmp_ipgt) @(posedge mtx_clk);
9804
            repeat (2) @(posedge wb_clk);
9805
            repeat (2) @(posedge mtx_clk);
9806
            wait_for_frame = 0;
9807
          end
9808
        end
9809
        begin: check_fr
9810
          // wait for frame to start
9811
          @(posedge MTxEn);
9812
          frame_started = 1;
9813 223 tadejm
`TIME; $display("  Under-run (on %0d. byte) frame started", (num_of_frames + 1));
9814 209 tadejm
          // wait for frame to end due to under-run
9815
          @(negedge MTxEn);
9816
          frame_ended = 1;
9817 223 tadejm
`TIME; $display("  Under-run frame ended");
9818 209 tadejm
        end
9819
      join
9820
      // wait for first transmit to end, if under-run didn't happen
9821
      if (frame_ended == 0)
9822
      begin
9823
        // WAIT FOR FIRST TRANSMIT
9824
        check_tx_bd(num_of_bd, data);
9825
        wait (MTxEn === 1'b1); // start first transmit
9826
        if (data[15] !== 1)
9827
        begin
9828
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
9829
          fail = fail + 1;
9830
        end
9831
        wait (MTxEn === 1'b0); // end first transmit
9832
        while (data[15] === 1)
9833
        begin
9834
          check_tx_bd(num_of_bd, data);
9835
          @(posedge wb_clk);
9836
        end
9837
        repeat (1) @(posedge wb_clk);
9838
        // CHECK FIRST FRAME
9839
        // check length of a first PACKET
9840
        tmp_len = eth_phy.tx_len;
9841
        #1;
9842
        if (tmp_len != (i_length + 4))
9843
        begin
9844 223 tadejm
          `TIME; $display("*E Wrong length of first packet out from MAC");
9845
          test_fail("Wrong length of first packet out from MAC");
9846 209 tadejm
          fail = fail + 1;
9847
        end
9848
        // checking first packet
9849
        check_tx_packet((`MEMORY_BASE + i_data[1:0]), 0, (i_length), tmp);
9850
        if (tmp > 0)
9851
        begin
9852 223 tadejm
          `TIME; $display("*E Wrong data of first transmitted packet");
9853
          test_fail("Wrong data of first transmitted packet");
9854 209 tadejm
          fail = fail + 1;
9855
        end
9856
        // check first transmited TX packet CRC
9857
        check_tx_crc(0, (i_length), 1'b0, tmp); // length without CRC
9858
        if (tmp > 0)
9859
        begin
9860 223 tadejm
          `TIME; $display("*E Wrong CRC of first transmitted packet");
9861
          test_fail("Wrong CRC of first transmitted packet");
9862 209 tadejm
          fail = fail + 1;
9863
        end
9864
        // check WB INT signal
9865
        if (wb_int !== 1'b1)
9866
        begin
9867
          `TIME; $display("*E WB INT signal should be set");
9868
          test_fail("WB INT signal should be set");
9869
          fail = fail + 1;
9870
        end
9871
        // check TX buffer descriptor of a packet
9872
        check_tx_bd(num_of_bd, data);
9873
        if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 1)) || // wrap bit
9874
             ((data[15:0] !== 16'h5800) && (num_of_bd < 1)) )   // without wrap bit
9875
        begin
9876
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
9877
          test_fail("TX buffer descriptor status is not correct");
9878
          fail = fail + 1;
9879
        end
9880
        // check interrupts
9881
        wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9882
        if ((data & `ETH_INT_TXB) !== 1'b1)
9883
        begin
9884
          `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
9885
          test_fail("Interrupt Transmit Buffer was not set");
9886
          fail = fail + 1;
9887
        end
9888
        if ((data & (~`ETH_INT_TXB)) !== 0)
9889
        begin
9890
          `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
9891
          test_fail("Other interrupts (except Transmit Buffer) were set");
9892
          fail = fail + 1;
9893
        end
9894
        // clear interrupts
9895
        wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9896
        // check WB INT signal
9897
        if (wb_int !== 1'b0)
9898
        begin
9899
          test_fail("WB INT signal should not be set");
9900
          fail = fail + 1;
9901
        end
9902
      end
9903 223 tadejm
      else
9904
      begin
9905
        // CHECK FIRST FRAME
9906
        // check length of a first PACKET
9907
        tmp_len = eth_phy.tx_len_err;
9908
        #1;
9909
        if (tmp_len != (num_of_frames + (4 - i_data)))
9910
        begin
9911
          `TIME; $display("*E Wrong length of first packet out from MAC");
9912
          test_fail("Wrong length of first packet out from MAC");
9913
          fail = fail + 1;
9914
        end
9915
        // checking first packet
9916
        check_tx_packet((`MEMORY_BASE + i_data[1:0]), 0, (num_of_frames), tmp);
9917
        if (tmp > 0)
9918
        begin
9919
          `TIME; $display("*E Wrong data of first transmitted packet");
9920
          test_fail("Wrong data of first transmitted packet");
9921
          fail = fail + 1;
9922
        end
9923
        // check WB INT signal
9924
        if (wb_int !== 1'b1)
9925
        begin
9926
          `TIME; $display("*E WB INT signal should be set");
9927
          test_fail("WB INT signal should be set");
9928
          fail = fail + 1;
9929
        end
9930
        // check TX buffer descriptor of a packet
9931
        check_tx_bd(num_of_bd, data);
9932
        if ( ((data[15:0] !== 16'h7900) && (num_of_bd == 1)) || // under-run, wrap bit
9933
             ((data[15:0] !== 16'h5900) && (num_of_bd < 1)) )   // under-run, without wrap bit
9934
        begin
9935
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
9936
          test_fail("TX buffer descriptor status is not correct");
9937
          fail = fail + 1;
9938
        end
9939
        // check interrupts
9940
        wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9941
        if ((data & `ETH_INT_TXE) !== 2'b10)
9942
        begin
9943
          `TIME; $display("*E Interrupt Transmit Error was not set, interrupt reg: %0h", data);
9944
          test_fail("Interrupt Transmit Buffer was not set");
9945
          fail = fail + 1;
9946
        end
9947
        if ((data & (~`ETH_INT_TXE)) !== 0)
9948
        begin
9949
          `TIME; $display("*E Other interrupts (except Transmit Error) were set, interrupt reg: %0h", data);
9950
          test_fail("Other interrupts (except Transmit Buffer) were set");
9951
          fail = fail + 1;
9952
        end
9953
        // clear interrupts
9954
        wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
9955
        // check WB INT signal
9956
        if (wb_int !== 1'b0)
9957
        begin
9958
          test_fail("WB INT signal should not be set");
9959
          fail = fail + 1;
9960
        end
9961
      end
9962 209 tadejm
      num_of_bd = num_of_bd + 1;
9963
      // destination address on ethernet PHY
9964
      eth_phy.set_tx_mem_addr(0);
9965 223 tadejm
      // WAIT FOR SECOND TRANSMIT
9966 209 tadejm
      check_tx_bd(num_of_bd, data);
9967
      wait (MTxEn === 1'b1); // start first transmit
9968
      if (data[15] !== 1)
9969
      begin
9970
        test_fail("Wrong buffer descriptor's ready bit read out from MAC");
9971
        fail = fail + 1;
9972
      end
9973
      wait (MTxEn === 1'b0); // end first transmit
9974
      while (data[15] === 1)
9975
      begin
9976
        check_tx_bd(num_of_bd, data);
9977
        @(posedge wb_clk);
9978
      end
9979
      repeat (1) @(posedge wb_clk);
9980
      // CHECK SECOND FRAME
9981
      // check length of a second PACKET
9982 223 tadejm
if (frame_ended == 1'b1)
9983
begin
9984
`TIME; $display("  Second frame after under-run ended");
9985
end
9986 209 tadejm
      tmp_len = eth_phy.tx_len;
9987
      #1;
9988
      if (tmp_len != (i_length + 4))
9989
      begin
9990 223 tadejm
        `TIME; $display("*E Wrong length of second packet out from MAC");
9991 209 tadejm
        test_fail("Wrong length of second packet out from MAC");
9992
        fail = fail + 1;
9993
      end
9994
      // checking second packet
9995
      check_tx_packet(`MEMORY_BASE, 0, (i_length), tmp);
9996
      if (tmp > 0)
9997
      begin
9998 223 tadejm
        `TIME; $display("*E Wrong data of second transmitted packet");
9999 209 tadejm
        test_fail("Wrong data of second transmitted packet");
10000
        fail = fail + 1;
10001
      end
10002
      // check second transmited TX packet CRC
10003
      check_tx_crc(0, (i_length), 1'b0, tmp); // length without CRC
10004
      if (tmp > 0)
10005
      begin
10006 223 tadejm
        `TIME; $display("*E Wrong CRC of second transmitted packet");
10007 209 tadejm
        test_fail("Wrong CRC of second transmitted packet");
10008
        fail = fail + 1;
10009
      end
10010
      // check WB INT signal
10011
      if (wb_int !== 1'b1)
10012
      begin
10013
        `TIME; $display("*E WB INT signal should be set");
10014
        test_fail("WB INT signal should be set");
10015
        fail = fail + 1;
10016
      end
10017
      // check TX buffer descriptor of a packet
10018
      check_tx_bd(num_of_bd, data);
10019
      if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 1)) || // wrap bit
10020
           ((data[15:0] !== 16'h5800) && (num_of_bd < 1)) )   // without wrap bit
10021
      begin
10022
        `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
10023
        test_fail("TX buffer descriptor status is not correct");
10024
        fail = fail + 1;
10025
      end
10026
      // check interrupts
10027
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10028
      if ((data & `ETH_INT_TXB) !== 1'b1)
10029
      begin
10030
        `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
10031
        test_fail("Interrupt Transmit Buffer was not set");
10032
        fail = fail + 1;
10033
      end
10034
      if ((data & (~`ETH_INT_TXB)) !== 0)
10035
      begin
10036
        `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
10037
        test_fail("Other interrupts (except Transmit Buffer) were set");
10038
        fail = fail + 1;
10039
      end
10040
      // clear interrupts
10041
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10042
      // check WB INT signal
10043
      if (wb_int !== 1'b0)
10044
      begin
10045
        test_fail("WB INT signal should not be set");
10046
        fail = fail + 1;
10047
      end
10048
      // set initial value
10049
      i_data = i_data - 1;
10050
      // the number of frame transmitted
10051
      num_of_frames = num_of_frames + 1;
10052
      num_of_bd = 0;
10053
      // set length (LOOP variable)
10054 223 tadejm
      if (num_of_frames == i_length + 4) // 64 => this was last Byte (1st .. 64th) when i_length = min_tmp - 4
10055 209 tadejm
        i_length = (max_tmp - 4);
10056
      @(posedge wb_clk);
10057
    end
10058
    // disable TX
10059
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
10060
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10061
    @(posedge wb_clk);
10062
    if(fail == 0)
10063
      test_ok;
10064
    else
10065
      fail = 0;
10066
  end
10067
 
10068
 
10069
  ////////////////////////////////////////////////////////////////////
10070
  ////                                                            ////
10071
  ////  Test transmit packets after TX under-run on each packet's ////
10072
  ////  byte at 2 TX buffer decriptors ( 100Mbps ).               ////
10073
  ////                                                            ////
10074
  ////////////////////////////////////////////////////////////////////
10075
  if (test_num == 21) // without padding
10076
  begin
10077
    // TEST 21: TRANSMIT PACKETS AFTER TX UNDER-RUN ON EACH PACKET's BYTE AT 2 TX BDs ( 100Mbps )
10078
    test_name = "TEST 21: TRANSMIT PACKETS AFTER TX UNDER-RUN ON EACH PACKET's BYTE AT 2 TX BDs ( 100Mbps )";
10079
    `TIME;
10080
    $display("  TEST 21: TRANSMIT PACKETS AFTER TX UNDER-RUN ON EACH PACKET's BYTE AT 2 TX BDs ( 100Mbps )");
10081
 
10082
    // reset MAC registers
10083
    hard_reset;
10084
    // reset MAC and MII LOGIC with soft reset
10085
    reset_mac;
10086
    reset_mii;
10087
    // set wb slave response
10088
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
10089
 
10090
    max_tmp = 0;
10091
    min_tmp = 0;
10092
    // set 2 TX buffer descriptors - must be set before TX enable
10093
    wbm_write(`ETH_TX_BD_NUM, 32'h2, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10094
    // enable TX, set full-duplex mode, NO padding and CRC appending
10095
    wbm_write(`ETH_MODER, `ETH_MODER_TXEN |/* `ETH_MODER_PAD |*/ `ETH_MODER_FULLD | `ETH_MODER_CRCEN,
10096
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10097
    // prepare a packet of MAXFL length
10098
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10099
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
10100
    min_tmp = tmp[31:16];
10101
    st_data = 8'h99;
10102
    set_tx_packet(`MEMORY_BASE, (max_tmp - 4), st_data); // length without CRC
10103
    // read IPG value
10104
    wbm_read(`ETH_IPGT, tmp_ipgt, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10105
    // check WB INT signal
10106
    if (wb_int !== 1'b0)
10107
    begin
10108
      test_fail("WB INT signal should not be set");
10109
      fail = fail + 1;
10110
    end
10111
 
10112
    // write to phy's control register for 100Mbps
10113
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
10114
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
10115
    speed = 100;
10116
 
10117
    num_of_frames = 0; // (0..3) => start under-run on first word
10118
    num_of_bd = 0;
10119
    i_data = 3; // (3) => one BYTE read in first word - FIRST byte
10120
    i_length = (min_tmp + 4);
10121
    while (i_length < (max_tmp - 4))
10122
    begin
10123
      // Reset_tx_bd enable interrupt generation
10124
      // unmask interrupts
10125
      wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
10126
                               `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10127
      // not detect carrier sense in FD and no collision
10128
      eth_phy.carrier_sense_tx_fd_detect(0);
10129
      eth_phy.collision(0);
10130
      // first destination address on ethernet PHY
10131
      eth_phy.set_tx_mem_addr(0);
10132
      // prepare BDs
10133
      if (num_of_bd == 0)
10134
      begin
10135
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, (`MEMORY_BASE + i_data[1:0]));
10136
        set_tx_bd(1, 1, i_length, 1'b1, 1'b1, 1'b1, `MEMORY_BASE);
10137
        set_tx_bd_wrap(1);
10138
        // set wb slave response: ACK (response), wbs_waits[2:0] (waits before response), 
10139
        //                       wbs_retries[7:0] (RTYs before ACK if RTY response selected)
10140
        #1 wb_slave.cycle_response(`ACK_RESPONSE, 3'h2, 8'h0);
10141
        set_tx_bd_ready(1, 1);
10142
        set_tx_bd_ready(0, 0);
10143
      end
10144
      // frame under-run checking
10145
      frame_started = 0;
10146
      frame_ended = 0;
10147
      wait_for_frame = 0;
10148
      fork
10149
        begin
10150
          // for every 4 frames bytes 1, 2, 3 and 4 respectively are read in first word => 1 ACK
10151
          // in other words 4 bytes are read, since length is MINFL => num_of_frames[31:2] ACKs
10152
          repeat ((num_of_frames[31:2] + 1'b1)) @(posedge eth_ma_wb_ack_i);
10153
          @(negedge eth_ma_wb_ack_i); // wait for last ACK to finish
10154
          // set wb slave response: ACK (response), wbs_waits[2:0] (waits before response), 
10155
          //                       wbs_retries[7:0] (RTYs before ACK if RTY response selected)
10156
          #1 wb_slave.cycle_response(`NO_RESPONSE, 3'h7, 8'hFF);
10157
          // wait for synchronization and some additional clocks
10158
          wait_for_frame = 1;
10159
          // wait for frame
10160
          wait ((wait_for_frame == 0) || (frame_started == 1))
10161
          if ((wait_for_frame == 0) && (frame_started == 0)) // frame didn't start
10162
          begin
10163
            disable check_fr1;
10164
          end
10165
          else if ((wait_for_frame == 1) && (frame_started == 1)) // frame started
10166
          begin
10167
            disable wait_fr1;
10168
            wait (frame_ended == 1);
10169
          end
10170
          repeat (2) @(posedge wb_clk);
10171
          // set wb slave response: ACK (response), wbs_waits[2:0] (waits before response), 
10172
          //                       wbs_retries[7:0] (RTYs before ACK if RTY response selected)
10173
          wb_slave.cycle_response(`ACK_RESPONSE, 3'h2, 8'h0);
10174
        end
10175
        begin: wait_fr1
10176
          wait (wait_for_frame == 1)
10177
          begin
10178
            // wait for synchronization and some additional clocks
10179
            repeat (3) @(posedge wb_clk);
10180
            repeat (2 * tmp_ipgt) @(posedge mtx_clk);
10181
            repeat (2) @(posedge wb_clk);
10182
            repeat (2) @(posedge mtx_clk);
10183
            wait_for_frame = 0;
10184
          end
10185
        end
10186
        begin: check_fr1
10187
          // wait for frame to start
10188
          @(posedge MTxEn);
10189
          frame_started = 1;
10190
$display("  Under-run (on %0d. byte) frame started", (num_of_frames + 1));
10191
          // wait for frame to end due to under-run
10192
          @(negedge MTxEn);
10193
          frame_ended = 1;
10194
$display("  Under-run frame ended");
10195
        end
10196
      join
10197
      // wait for first transmit to end, if under-run didn't happen
10198
      if (frame_ended == 0)
10199
      begin
10200
        // WAIT FOR FIRST TRANSMIT
10201
        check_tx_bd(num_of_bd, data);
10202
        wait (MTxEn === 1'b1); // start first transmit
10203
        if (data[15] !== 1)
10204
        begin
10205
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
10206
          fail = fail + 1;
10207
        end
10208
        wait (MTxEn === 1'b0); // end first transmit
10209
        while (data[15] === 1)
10210
        begin
10211
          check_tx_bd(num_of_bd, data);
10212
          @(posedge wb_clk);
10213
        end
10214
        repeat (1) @(posedge wb_clk);
10215
        // CHECK FIRST FRAME
10216
        // check length of a first PACKET
10217
        tmp_len = eth_phy.tx_len;
10218
        #1;
10219
        if (tmp_len != (i_length + 4))
10220
        begin
10221
          test_fail("Wrong length of second packet out from MAC");
10222
          fail = fail + 1;
10223
        end
10224
        // checking first packet
10225
        check_tx_packet((`MEMORY_BASE + i_data[1:0]), 0, (i_length), tmp);
10226
        if (tmp > 0)
10227
        begin
10228
          test_fail("Wrong data of second transmitted packet");
10229
          fail = fail + 1;
10230
        end
10231
        // check first transmited TX packet CRC
10232
        check_tx_crc(0, (i_length), 1'b0, tmp); // length without CRC
10233
        if (tmp > 0)
10234
        begin
10235
          test_fail("Wrong CRC of second transmitted packet");
10236
          fail = fail + 1;
10237
        end
10238
        // check WB INT signal
10239
        if (wb_int !== 1'b1)
10240
        begin
10241
          `TIME; $display("*E WB INT signal should be set");
10242
          test_fail("WB INT signal should be set");
10243
          fail = fail + 1;
10244
        end
10245
        // check TX buffer descriptor of a packet
10246
        check_tx_bd(num_of_bd, data);
10247
        if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 1)) || // wrap bit
10248
             ((data[15:0] !== 16'h5800) && (num_of_bd < 1)) )   // without wrap bit
10249
        begin
10250
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
10251
          test_fail("TX buffer descriptor status is not correct");
10252
          fail = fail + 1;
10253
        end
10254
        // check interrupts
10255
        wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10256
        if ((data & `ETH_INT_TXB) !== 1'b1)
10257
        begin
10258
          `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
10259
          test_fail("Interrupt Transmit Buffer was not set");
10260
          fail = fail + 1;
10261
        end
10262
        if ((data & (~`ETH_INT_TXB)) !== 0)
10263
        begin
10264
          `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
10265
          test_fail("Other interrupts (except Transmit Buffer) were set");
10266
          fail = fail + 1;
10267
        end
10268
        // clear interrupts
10269
        wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10270
        // check WB INT signal
10271
        if (wb_int !== 1'b0)
10272
        begin
10273
          test_fail("WB INT signal should not be set");
10274
          fail = fail + 1;
10275
        end
10276
      end
10277
      num_of_bd = num_of_bd + 1;
10278
      // destination address on ethernet PHY
10279
      eth_phy.set_tx_mem_addr(0);
10280
      // WAIT FOR FIRST TRANSMIT
10281
      check_tx_bd(num_of_bd, data);
10282
      wait (MTxEn === 1'b1); // start first transmit
10283
      if (data[15] !== 1)
10284
      begin
10285
        test_fail("Wrong buffer descriptor's ready bit read out from MAC");
10286
        fail = fail + 1;
10287
      end
10288
      wait (MTxEn === 1'b0); // end first transmit
10289
      while (data[15] === 1)
10290
      begin
10291
        check_tx_bd(num_of_bd, data);
10292
        @(posedge wb_clk);
10293
      end
10294
      repeat (1) @(posedge wb_clk);
10295
      // CHECK SECOND FRAME
10296
      // check length of a second PACKET
10297
      tmp_len = eth_phy.tx_len;
10298
      #1;
10299
      if (tmp_len != (i_length + 4))
10300
      begin
10301
        test_fail("Wrong length of second packet out from MAC");
10302
        fail = fail + 1;
10303
      end
10304
      // checking second packet
10305
      check_tx_packet(`MEMORY_BASE, 0, (i_length), tmp);
10306
      if (tmp > 0)
10307
      begin
10308
        test_fail("Wrong data of second transmitted packet");
10309
        fail = fail + 1;
10310
      end
10311
      // check second transmited TX packet CRC
10312
      check_tx_crc(0, (i_length), 1'b0, tmp); // length without CRC
10313
      if (tmp > 0)
10314
      begin
10315
        test_fail("Wrong CRC of second transmitted packet");
10316
        fail = fail + 1;
10317
      end
10318
      // check WB INT signal
10319
      if (wb_int !== 1'b1)
10320
      begin
10321
        `TIME; $display("*E WB INT signal should be set");
10322
        test_fail("WB INT signal should be set");
10323
        fail = fail + 1;
10324
      end
10325
      // check TX buffer descriptor of a packet
10326
      check_tx_bd(num_of_bd, data);
10327
      if ( ((data[15:0] !== 16'h7800) && (num_of_bd == 1)) || // wrap bit
10328
           ((data[15:0] !== 16'h5800) && (num_of_bd < 1)) )   // without wrap bit
10329
      begin
10330
        `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
10331
        test_fail("TX buffer descriptor status is not correct");
10332
        fail = fail + 1;
10333
      end
10334
      // check interrupts
10335
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10336
      if ((data & `ETH_INT_TXB) !== 1'b1)
10337
      begin
10338
        `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
10339
        test_fail("Interrupt Transmit Buffer was not set");
10340
        fail = fail + 1;
10341
      end
10342
      if ((data & (~`ETH_INT_TXB)) !== 0)
10343
      begin
10344
        `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
10345
        test_fail("Other interrupts (except Transmit Buffer) were set");
10346
        fail = fail + 1;
10347
      end
10348
      // clear interrupts
10349
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10350
      // check WB INT signal
10351
      if (wb_int !== 1'b0)
10352
      begin
10353
        test_fail("WB INT signal should not be set");
10354
        fail = fail + 1;
10355
      end
10356
      // set initial value
10357
      i_data = i_data - 1;
10358
      // the number of frame transmitted
10359
      num_of_frames = num_of_frames + 1;
10360
      num_of_bd = 0;
10361
      // set length (LOOP variable)
10362
      if (num_of_frames == i_length + 4) // 64 => this vas last Byte (1st .. 64th) when i_length = min_tmp - 4
10363
        i_length = (max_tmp - 4);
10364
      @(posedge wb_clk);
10365
    end
10366
    // disable TX
10367
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
10368
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10369
    @(posedge wb_clk);
10370
    if(fail == 0)
10371
      test_ok;
10372
    else
10373
      fail = 0;
10374
  end
10375
 
10376 169 mohor
/*
10377
          wbm_write(`ETH_MODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10378
          wbm_read(`ETH_MODER, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10379 116 mohor
 
10380 169 mohor
          wbm_write(32'hd0000000, `ETH_MODER_RXEN  | `ETH_MODER_TXEN | `ETH_MODER_PRO | `ETH_MODER_CRCEN |
10381
                    `ETH_MODER_PAD, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10382
          wbm_read(32'hd0000000, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10383
 
10384
 
10385
 
10386 116 mohor
 
10387 169 mohor
          set_tx_bd(3);
10388
          set_rx_bd(6);
10389
 
10390
          set_tx_packet(16'h34, 8'h1);
10391
          set_tx_packet(16'h34, 8'h11);
10392
          send_tx_packet;
10393
          set_tx_packet(16'h34, 8'h21);
10394
          set_tx_packet(16'h34, 8'h31);
10395
          send_tx_packet;
10396 116 mohor
 
10397
 
10398 169 mohor
          eth_phy.GetDataOnMRxD(100, `BROADCAST_XFR); // LengthRx bytes is comming on MRxD[3:0] signals
10399
          repeat (100) @(posedge mrx_clk);   // Waiting for TxEthMac to finish transmit
10400
 
10401
          eth_phy.GetDataOnMRxD(70, `BROADCAST_XFR); // LengthRx bytes is comming on MRxD[3:0] signals
10402
          repeat (10000) @(posedge wb_clk);   // Waiting for TxEthMac to finish transmit
10403
 
10404
          eth_phy.GetDataOnMRxD(70, `MULTICAST_XFR); // LengthRx bytes is comming on MRxD[3:0] signals
10405
          repeat (10000) @(posedge wb_clk);   // Waiting for TxEthMac to finish transmit
10406
*/
10407
 
10408 194 tadej
end   //  for (test_num=start_task; test_num <= end_task; test_num=test_num+1)
10409 169 mohor
 
10410
end
10411
endtask // test_mac_full_duplex_transmit
10412
 
10413
 
10414 209 tadejm
task test_mac_full_duplex_receive;
10415
  input  [31:0]  start_task;
10416
  input  [31:0]  end_task;
10417
  integer        bit_start_1;
10418
  integer        bit_end_1;
10419
  integer        bit_start_2;
10420
  integer        bit_end_2;
10421
  integer        num_of_reg;
10422
  integer        num_of_frames;
10423
  integer        num_of_bd;
10424
  integer        i_addr;
10425
  integer        i_data;
10426
  integer        i_length;
10427
  integer        tmp_len;
10428
  integer        tmp_bd;
10429
  integer        tmp_bd_num;
10430
  integer        tmp_data;
10431
  integer        tmp_ipgt;
10432
  integer        test_num;
10433
  reg    [31:0]  tx_bd_num;
10434
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_data;
10435
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_tmp_data;
10436
  integer        i;
10437
  integer        i1;
10438
  integer        i2;
10439
  integer        i3;
10440
  integer        fail;
10441
  integer        speed;
10442
  reg            frame_started;
10443
  reg            frame_ended;
10444
  reg            wait_for_frame;
10445
  reg    [31:0]  addr;
10446
  reg    [31:0]  data;
10447
  reg    [31:0]  tmp;
10448
  reg    [ 7:0]  st_data;
10449
  reg    [15:0]  max_tmp;
10450
  reg    [15:0]  min_tmp;
10451
begin
10452
// MAC FULL DUPLEX RECEIVE TEST
10453
test_heading("MAC FULL DUPLEX RECEIVE TEST");
10454
$display(" ");
10455
$display("MAC FULL DUPLEX RECEIVE TEST");
10456
fail = 0;
10457
 
10458
// reset MAC registers
10459
hard_reset;
10460
// reset MAC and MII LOGIC with soft reset
10461
reset_mac;
10462
reset_mii;
10463
// set wb slave response
10464
wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
10465
 
10466
  /*
10467
  TASKS for set and control TX buffer descriptors (also send packet - set_tx_bd_ready):
10468
  -------------------------------------------------------------------------------------
10469
  set_tx_bd
10470
    (tx_bd_num_start[6:0], tx_bd_num_end[6:0], len[15:0], irq, pad, crc, txpnt[31:0]);
10471
  set_tx_bd_wrap
10472
    (tx_bd_num_end[6:0]);
10473
  set_tx_bd_ready
10474
    (tx_bd_num_start[6:0], tx_bd_num_end[6:0]);
10475
  check_tx_bd
10476
    (tx_bd_num_start[6:0], tx_bd_status[31:0]);
10477
  clear_tx_bd
10478
    (tx_bd_num_start[6:0], tx_bd_num_end[6:0]);
10479
 
10480
  TASKS for set and control RX buffer descriptors:
10481
  ------------------------------------------------
10482
  set_rx_bd
10483
    (rx_bd_num_strat[6:0], rx_bd_num_end[6:0], irq, rxpnt[31:0]);
10484
  set_rx_bd_wrap
10485
    (rx_bd_num_end[6:0]);
10486
  set_rx_bd_empty
10487
    (rx_bd_num_strat[6:0], rx_bd_num_end[6:0]);
10488
  check_rx_bd
10489
    (rx_bd_num_end[6:0], rx_bd_status);
10490
  clear_rx_bd
10491
    (rx_bd_num_strat[6:0], rx_bd_num_end[6:0]);
10492
 
10493
  TASKS for set and check TX packets:
10494
  -----------------------------------
10495
  set_tx_packet
10496
    (txpnt[31:0], len[15:0], eth_start_data[7:0]);
10497
  check_tx_packet
10498
    (txpnt_wb[31:0], txpnt_phy[31:0], len[15:0], failure[31:0]);
10499
 
10500
  TASKS for set and check RX packets:
10501
  -----------------------------------
10502
  set_rx_packet
10503
    (rxpnt[31:0], len[15:0], plus_nibble, d_addr[47:0], s_addr[47:0], type_len[15:0], start_data[7:0]);
10504
  check_rx_packet
10505
    (rxpnt_phy[31:0], rxpnt_wb[31:0], len[15:0], plus_nibble, successful_nibble, failure[31:0]);
10506
 
10507
  TASKS for append and check CRC to/of TX packet:
10508
  -----------------------------------------------
10509
  append_tx_crc
10510
    (txpnt_wb[31:0], len[15:0], negated_crc);
10511
  check_tx_crc
10512
    (txpnt_phy[31:0], len[15:0], negated_crc, failure[31:0]);
10513
 
10514
  TASK for append CRC to RX packet (CRC is checked together with check_rx_packet):
10515
  --------------------------------------------------------------------------------
10516
  append_rx_crc
10517
    (rxpnt_phy[31:0], len[15:0], plus_nibble, negated_crc);
10518
  */
10519
 
10520
//////////////////////////////////////////////////////////////////////
10521
////                                                              ////
10522
////  test_mac_full_duplex_receive:                               ////
10523
////                                                              ////
10524
////  0: Test no receive when all buffers are TX ( 10Mbps ).      ////
10525
////  1: Test no receive when all buffers are TX ( 100Mbps ).     ////
10526
////  2: Test receive packets form MINFL to MAXFL sizes at        ////
10527
////     one RX buffer decriptor ( 10Mbps ).                      ////
10528
////  3: Test receive packets form MINFL to MAXFL sizes at        ////
10529
////     one RX buffer decriptor ( 100Mbps ).                     ////
10530
////                                                              ////
10531
//////////////////////////////////////////////////////////////////////
10532
for (test_num = start_task; test_num <= end_task; test_num = test_num + 1)
10533
begin
10534
 
10535
  ////////////////////////////////////////////////////////////////////
10536
  ////                                                            ////
10537
  ////  Test no receive when all buffers are TX ( 10Mbps ).       ////
10538
  ////                                                            ////
10539
  ////////////////////////////////////////////////////////////////////
10540
  if (test_num == 0) // Test no receive when all buffers are TX ( 10Mbps ).
10541
  begin
10542
    // TEST 0: NO RECEIVE WHEN ALL BUFFERS ARE TX ( 10Mbps )
10543
    test_name   = "TEST 0: NO RECEIVE WHEN ALL BUFFERS ARE TX ( 10Mbps )";
10544
    `TIME; $display("  TEST 0: NO RECEIVE WHEN ALL BUFFERS ARE TX ( 10Mbps )");
10545
 
10546
    // unmask interrupts
10547
    wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
10548
                             `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10549
    // set all buffer descriptors to TX - must be set before RX enable
10550
    wbm_write(`ETH_TX_BD_NUM, 32'h80, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10551 223 tadejm
    // enable RX, set full-duplex mode, receive small, NO correct IFG
10552 209 tadejm
    wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_IFG |
10553
              `ETH_MODER_PRO | `ETH_MODER_BRO,
10554
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10555
 
10556
    // write to phy's control register for 10Mbps
10557
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
10558
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
10559
    speed = 10;
10560
 
10561
    i = 0;
10562
    while (i < 128)
10563
    begin
10564
      for (i1 = 0; i1 <= i; i1 = i1 + 1)
10565
      begin
10566
        set_rx_packet((i1 * 50), 10, 1'b0, 48'h1234_5678_8765, 48'h0011_2233_4455, 16'h0101, 8'h0);
10567
        append_rx_crc((i1 * 50), 10, 1'b0, 1'b0);
10568
        set_rx_bd(i1, i1, 1'b1, (`MEMORY_BASE + (i1 * 50)));
10569
      end
10570
      set_rx_bd_wrap(i);
10571
      set_rx_bd_empty(0, i);
10572
      for (i1 = 0; i1 <= i; i1 = i1 + 1)
10573
      begin
10574
        #1 eth_phy.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, 8'hD5, (i1 * 50), 14, 1'b0);
10575
        repeat(10) @(posedge mrx_clk);
10576
      end
10577
      @(posedge mrx_clk);
10578
      for (i2 = 0; i2 < 20; i2 = i2 + 1)
10579
      begin
10580
        check_rx_bd(0, tmp);
10581
        #1;
10582
        if (tmp[15] === 1'b0)
10583
        begin
10584
          test_fail("Receive should not start at all");
10585
          fail = fail + 1;
10586
          `TIME; $display("*E Receive of %d packets should not start at all - empty is 0", i);
10587
        end
10588
        if (tmp[7:0] !== 0)
10589
        begin
10590
          test_fail("Receive should not be finished since it should not start at all");
10591
          fail = fail + 1;
10592
          `TIME; $display("*E Receive of should not be finished since it should not start at all");
10593
        end
10594
        @(posedge wb_clk);
10595
      end
10596
      wbm_read(`ETH_INT, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10597
      if (tmp[6:0] !== 0)
10598
      begin
10599
        test_fail("Receive should not get INT since it should not start at all");
10600
        fail = fail + 1;
10601
        `TIME; $display("*E Receive of should not get INT since it should not start at all");
10602
      end
10603
      clear_rx_bd(0, i);
10604
      if ((i < 5) || (i > 124))
10605
        i = i + 1;
10606
      else
10607
        i = i + 120;
10608
    end
10609
    // disable RX
10610
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_IFG |
10611
              `ETH_MODER_PRO | `ETH_MODER_BRO,
10612
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10613
    if(fail == 0)
10614
      test_ok;
10615
    else
10616
      fail = 0;
10617
  end
10618
 
10619
 
10620
  ////////////////////////////////////////////////////////////////////
10621
  ////                                                            ////
10622
  ////  Test no receive when all buffers are TX ( 100Mbps ).      ////
10623
  ////                                                            ////
10624
  ////////////////////////////////////////////////////////////////////
10625
  if (test_num == 1) // Test no receive when all buffers are TX ( 100Mbps ).
10626
  begin
10627
    // TEST 1: NO RECEIVE WHEN ALL BUFFERS ARE TX ( 100Mbps )
10628
    test_name   = "TEST 1: NO RECEIVE WHEN ALL BUFFERS ARE TX ( 100Mbps )";
10629
    `TIME; $display("  TEST 1: NO RECEIVE WHEN ALL BUFFERS ARE TX ( 100Mbps )");
10630
 
10631
    // unmask interrupts
10632
    wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
10633
                             `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10634
    // set all buffer descriptors to TX - must be set before RX enable
10635
    wbm_write(`ETH_TX_BD_NUM, 32'h80, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10636 223 tadejm
    // enable RX, set full-duplex mode, receive small, NO correct IFG
10637 209 tadejm
    wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_IFG |
10638
              `ETH_MODER_PRO | `ETH_MODER_BRO,
10639
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10640
 
10641
    // write to phy's control register for 100Mbps
10642
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
10643
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
10644
    speed = 100;
10645
 
10646
    i = 0;
10647
    while (i < 128)
10648
    begin
10649
      for (i1 = 0; i1 <= i; i1 = i1 + 1)
10650
      begin
10651
        set_rx_packet((i1 * 50), 10, 1'b0, 48'h1234_5678_8765, 48'h0011_2233_4455, 16'h0101, 8'h0);
10652
        append_rx_crc((i1 * 50), 10, 1'b0, 1'b0);
10653
        set_rx_bd(i1, i1, 1'b1, (`MEMORY_BASE + (i1 * 50)));
10654
      end
10655
      set_rx_bd_wrap(i);
10656
      set_rx_bd_empty(0, i);
10657
      for (i1 = 0; i1 <= i; i1 = i1 + 1)
10658
      begin
10659
        #1 eth_phy.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, 8'hD5, (i1 * 50), 14, 1'b0);
10660
        repeat(10) @(posedge mrx_clk);
10661
      end
10662
      @(posedge mrx_clk);
10663
      for (i2 = 0; i2 < 20; i2 = i2 + 1)
10664
      begin
10665
        check_rx_bd(0, tmp);
10666
        #1;
10667
        if (tmp[15] === 1'b0)
10668
        begin
10669
          test_fail("Receive should not start at all");
10670
          fail = fail + 1;
10671
          `TIME; $display("*E Receive of %d packets should not start at all - empty is 0", i);
10672
        end
10673
        if (tmp[7:0] !== 0)
10674
        begin
10675
          test_fail("Receive should not be finished since it should not start at all");
10676
          fail = fail + 1;
10677
          `TIME; $display("*E Receive of should not be finished since it should not start at all");
10678
        end
10679
        @(posedge wb_clk);
10680
      end
10681
      wbm_read(`ETH_INT, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10682
      if (tmp[6:0] !== 0)
10683
      begin
10684
        test_fail("Receive should not get INT since it should not start at all");
10685
        fail = fail + 1;
10686
        `TIME; $display("*E Receive of should not get INT since it should not start at all");
10687
      end
10688
      clear_rx_bd(0, i);
10689
      if ((i < 5) || (i > 124))
10690
        i = i + 1;
10691
      else
10692
        i = i + 120;
10693
    end
10694
    // disable RX
10695
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_IFG |
10696
              `ETH_MODER_PRO | `ETH_MODER_BRO,
10697
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10698
    if(fail == 0)
10699
      test_ok;
10700
    else
10701
      fail = 0;
10702
  end
10703
 
10704
 
10705
  ////////////////////////////////////////////////////////////////////
10706
  ////                                                            ////
10707
  ////  Test receive packets form MINFL to MAXFL sizes at         ////
10708
  ////  one RX buffer decriptor ( 10Mbps ).                       ////
10709
  ////                                                            ////
10710
  ////////////////////////////////////////////////////////////////////
10711
  if (test_num == 2) // Test no receive when all buffers are TX ( 10Mbps ).
10712
  begin
10713
    // TEST 2: RECEIVE PACKETS FROM MINFL TO MAXFL SIZES AT ONE RX BD ( 10Mbps )
10714
    test_name   = "TEST 2: RECEIVE PACKETS FROM MINFL TO MAXFL SIZES AT ONE RX BD ( 10Mbps )";
10715
    `TIME; $display("  TEST 2: RECEIVE PACKETS FROM MINFL TO MAXFL SIZES AT ONE RX BD ( 10Mbps )");
10716
 
10717
    // unmask interrupts
10718
    wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
10719
                             `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10720
    // set 1 RX buffer descriptor (8'h80 - 1) - must be set before RX enable
10721
    wbm_write(`ETH_TX_BD_NUM, 32'h7F, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10722
    // enable RX, set full-duplex mode, NO receive small, NO correct IFG
10723
    wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
10724
              `ETH_MODER_PRO | `ETH_MODER_BRO,
10725
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10726
    // prepare two packets of MAXFL length
10727
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10728
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
10729
    min_tmp = tmp[31:16];
10730
    st_data = 8'h0F;
10731
    set_rx_packet(0, (max_tmp - 4), 1'b0, 48'h0102_0304_0506, 48'h0708_090A_0B0C, 16'h0D0E, st_data); // length without CRC
10732
    st_data = 8'h1A;
10733
    set_rx_packet((max_tmp), (max_tmp - 4), 1'b0, 48'h1234_5678_8765, 48'hA1B2_C3D4_E5F6, 16'hE77E, st_data);
10734
    // check WB INT signal
10735
    if (wb_int !== 1'b0)
10736
    begin
10737
      test_fail("WB INT signal should not be set");
10738
      fail = fail + 1;
10739
    end
10740
 
10741
    // write to phy's control register for 10Mbps
10742
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
10743
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
10744
    speed = 10;
10745
 
10746
    i_length = (min_tmp - 4);
10747
    while (i_length <= (max_tmp - 4))
10748
    begin
10749
      // choose generating carrier sense and collision for first and last 64 lengths of frames
10750
      case (i_length[1:0])
10751
      2'h0: // Interrupt is generated
10752
      begin
10753
        // enable interrupt generation
10754
        set_rx_bd(127, 127, 1'b1, (`MEMORY_BASE + i_length[1:0]));
10755
        // unmask interrupts
10756
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
10757
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10758
        // not detect carrier sense in FD and no collision
10759
        eth_phy.no_carrier_sense_rx_fd_detect(0);
10760
        eth_phy.collision(0);
10761
      end
10762
      2'h1: // Interrupt is not generated
10763
      begin
10764
        // enable interrupt generation
10765
        set_rx_bd(127, 127, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
10766
        // mask interrupts
10767
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10768
        // detect carrier sense in FD and no collision
10769
        eth_phy.no_carrier_sense_rx_fd_detect(1);
10770
        eth_phy.collision(0);
10771
      end
10772
      2'h2: // Interrupt is not generated
10773
      begin
10774
        // disable interrupt generation
10775
        set_rx_bd(127, 127, 1'b0, (`MEMORY_BASE + i_length[1:0]));
10776
        // unmask interrupts
10777
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
10778
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10779
        // not detect carrier sense in FD and set collision
10780
        eth_phy.no_carrier_sense_rx_fd_detect(0);
10781
        eth_phy.collision(1);
10782
      end
10783
      default: // 2'h3: // Interrupt is not generated
10784
      begin
10785
        // disable interrupt generation
10786
        set_rx_bd(127, 127, 1'b0, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
10787
        // mask interrupts
10788
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10789
        // detect carrier sense in FD and set collision
10790
        eth_phy.no_carrier_sense_rx_fd_detect(1);
10791
        eth_phy.collision(1);
10792
      end
10793
      endcase
10794
      if (i_length[0] == 1'b0)
10795
        append_rx_crc (0, i_length, 1'b0, 1'b0);
10796
      else
10797
        append_rx_crc (max_tmp, i_length, 1'b0, 1'b0);
10798
      // set wrap bit
10799
      set_rx_bd_wrap(127);
10800
      set_rx_bd_empty(127, 127);
10801
      fork
10802
        begin
10803
          if (i_length[0] == 1'b0)
10804
            #1 eth_phy.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, 8'hD5, 0, (i_length + 4), 1'b0);
10805
          else
10806
            #1 eth_phy.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, 8'hD5, max_tmp, (i_length + 4), 1'b0);
10807
          repeat(10) @(posedge mrx_clk);
10808
        end
10809
        begin
10810
          #1 check_rx_bd(127, data);
10811
          if (i_length < min_tmp) // just first four
10812
          begin
10813
            while (data[15] === 1)
10814
            begin
10815
              #1 check_rx_bd(127, data);
10816
              @(posedge wb_clk);
10817
            end
10818
            repeat (1) @(posedge wb_clk);
10819
          end
10820
          else
10821
          begin
10822
            wait (MRxDV === 1'b1); // start transmit
10823
            #1 check_rx_bd(127, data);
10824
            if (data[15] !== 1)
10825
            begin
10826
              test_fail("Wrong buffer descriptor's ready bit read out from MAC");
10827
              fail = fail + 1;
10828
            end
10829
            wait (MRxDV === 1'b0); // end transmit
10830
            while (data[15] === 1)
10831
            begin
10832
              #1 check_rx_bd(127, data);
10833
              @(posedge wb_clk);
10834
            end
10835
            repeat (1) @(posedge wb_clk);
10836
          end
10837
        end
10838
      join
10839
      // check length of a PACKET
10840
      if (data[31:16] != (i_length + 4))
10841
      begin
10842
        `TIME; $display("*E Wrong length of the packet out from PHY (%0d instead of %0d)",
10843
                        data[31:16], (i_length + 4));
10844
        test_fail("Wrong length of the packet out from PHY");
10845
        fail = fail + 1;
10846
      end
10847
      // checking in the following if statement is performed only for first and last 64 lengths
10848
      // check received RX packet data and CRC
10849
      if (i_length[0] == 1'b0)
10850
      begin
10851
        check_rx_packet(0, (`MEMORY_BASE + i_length[1:0]), (i_length + 4), 1'b0, 1'b0, tmp);
10852
      end
10853
      else
10854
      begin
10855
        check_rx_packet(max_tmp, ((`MEMORY_BASE + i_length[1:0]) + max_tmp), (i_length + 4), 1'b0, 1'b0, tmp);
10856
      end
10857
      if (tmp > 0)
10858
      begin
10859
        `TIME; $display("*E Wrong data of the received packet");
10860
        test_fail("Wrong data of the received packet");
10861
        fail = fail + 1;
10862
      end
10863
      // check WB INT signal
10864
      if (i_length[1:0] == 2'h0)
10865
      begin
10866
        if (wb_int !== 1'b1)
10867
        begin
10868
          `TIME; $display("*E WB INT signal should be set");
10869
          test_fail("WB INT signal should be set");
10870
          fail = fail + 1;
10871
        end
10872
      end
10873
      else
10874
      begin
10875
        if (wb_int !== 1'b0)
10876
        begin
10877
          `TIME; $display("*E WB INT signal should not be set");
10878
          test_fail("WB INT signal should not be set");
10879
          fail = fail + 1;
10880
        end
10881
      end
10882
      // check RX buffer descriptor of a packet
10883
      check_rx_bd(127, data);
10884
      if (i_length[1] == 1'b0) // interrupt enabled no_carrier_sense_rx_fd_detect
10885
      begin
10886
        if ( ((data[15:0] !== 16'h6000) && (i_length[0] == 1'b0)) ||
10887
             ((data[15:0] !== 16'h6000) && (i_length[0] == 1'b1)) )
10888
        begin
10889
          `TIME; $display("*E RX buffer descriptor status is not correct: %0h", data[15:0]);
10890
          test_fail("RX buffer descriptor status is not correct");
10891
          fail = fail + 1;
10892
        end
10893
      end
10894
      else // interrupt not enabled
10895
      begin
10896
        if ( ((data[15:0] !== 16'h2000) && (i_length[0] == 1'b0)) ||
10897
             ((data[15:0] !== 16'h2000) && (i_length[0] == 1'b1)) )
10898
        begin
10899
          `TIME; $display("*E RX buffer descriptor status is not correct: %0h", data[15:0]);
10900
          test_fail("RX buffer descriptor status is not correct");
10901
          fail = fail + 1;
10902
        end
10903
      end
10904
      // clear RX buffer descriptor for first 4 frames
10905
      if (i_length < min_tmp)
10906
        clear_rx_bd(127, 127);
10907
      // check interrupts
10908
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10909
      if ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1))
10910
      begin
10911
        if ((data & `ETH_INT_RXB) !== `ETH_INT_RXB)
10912
        begin
10913
          `TIME; $display("*E Interrupt Receive Buffer was not set, interrupt reg: %0h", data);
10914
          test_fail("Interrupt Receive Buffer was not set");
10915
          fail = fail + 1;
10916
        end
10917
        if ((data & (~`ETH_INT_RXB)) !== 0)
10918
        begin
10919
          `TIME; $display("*E Other interrupts (except Receive Buffer) were set, interrupt reg: %0h", data);
10920
          test_fail("Other interrupts (except Receive Buffer) were set");
10921
          fail = fail + 1;
10922
        end
10923
      end
10924
      else
10925
      begin
10926
        if (data !== 0)
10927
        begin
10928
          `TIME; $display("*E Any of interrupts (except Receive Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]);
10929
          test_fail("Any of interrupts (except Receive Buffer) was set");
10930
          fail = fail + 1;
10931
        end
10932
      end
10933
      // clear interrupts
10934
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10935
      // check WB INT signal
10936
      if (wb_int !== 1'b0)
10937
      begin
10938
        test_fail("WB INT signal should not be set");
10939
        fail = fail + 1;
10940
      end
10941
      // INTERMEDIATE DISPLAYS
10942
      if ((i_length + 4) == (min_tmp + 64))
10943
      begin
10944
        // starting length is min_tmp, ending length is (min_tmp + 64)
10945
        $display("    receive small packets is NOT selected");
10946
        $display("    ->packets with lengths from %0d (MINFL) to %0d are checked (length increasing by 1 byte)",
10947
                 min_tmp, (min_tmp + 64));
10948
        // set receive small, remain the rest
10949
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_IFG |
10950
                  `ETH_MODER_PRO | `ETH_MODER_BRO,
10951
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10952
      end
10953
      else if ((i_length + 4) == (max_tmp - 16))
10954
      begin
10955
        // starting length is for +128 longer than previous ending length, while ending length is tmp_data
10956
        $display("    receive small packets is selected");
10957
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 128 bytes)",
10958
                 (min_tmp + 64 + 128), tmp_data);
10959
        // reset receive small, remain the rest
10960
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
10961
                  `ETH_MODER_PRO | `ETH_MODER_BRO,
10962
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10963
      end
10964
      else if ((i_length + 4) == max_tmp)
10965
      begin
10966
        $display("    receive small packets is NOT selected");
10967
        $display("    ->packets with lengths from %0d to %0d (MAXFL) are checked (length increasing by 1 byte)",
10968
                 (max_tmp - (4 + 16)), max_tmp);
10969
      end
10970
      // set length (loop variable)
10971
      if ((i_length + 4) < (min_tmp + 64))
10972
        i_length = i_length + 1;
10973
      else if ( ((i_length + 4) >= (min_tmp + 64)) && ((i_length + 4) <= (max_tmp - 256)) )
10974
      begin
10975
        i_length = i_length + 128;
10976
        tmp_data = i_length + 4; // last tmp_data is ending length
10977
      end
10978
      else if ( ((i_length + 4) > (max_tmp - 256)) && ((i_length + 4) < (max_tmp - 16)) )
10979
        i_length = max_tmp - (4 + 16);
10980
      else if ((i_length + 4) >= (max_tmp - 16))
10981
        i_length = i_length + 1;
10982
      else
10983
      begin
10984
        $display("*E TESTBENCH ERROR - WRONG PARAMETERS IN TESTBENCH");
10985
        #10 $stop;
10986
      end
10987
    end
10988
    // disable RX
10989
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_IFG |
10990
              `ETH_MODER_PRO | `ETH_MODER_BRO,
10991
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
10992
    if(fail == 0)
10993
      test_ok;
10994
    else
10995
      fail = 0;
10996
  end
10997
 
10998
 
10999
  ////////////////////////////////////////////////////////////////////
11000
  ////                                                            ////
11001
  ////  Test receive packets form MINFL to MAXFL sizes at         ////
11002
  ////  one RX buffer decriptor ( 100Mbps ).                      ////
11003
  ////                                                            ////
11004
  ////////////////////////////////////////////////////////////////////
11005
  if (test_num == 3) // Test no receive when all buffers are TX ( 100Mbps ).
11006
  begin
11007
    // TEST 3: RECEIVE PACKETS FROM MINFL TO MAXFL SIZES AT ONE RX BD ( 100Mbps )
11008
    test_name   = "TEST 3: RECEIVE PACKETS FROM MINFL TO MAXFL SIZES AT ONE RX BD ( 100Mbps )";
11009
    `TIME; $display("  TEST 3: RECEIVE PACKETS FROM MINFL TO MAXFL SIZES AT ONE RX BD ( 100Mbps )");
11010
 
11011
    // unmask interrupts
11012
    wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
11013
                             `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11014
    // set 1 RX buffer descriptor (8'h80 - 1) - must be set before RX enable
11015
    wbm_write(`ETH_TX_BD_NUM, 32'h7F, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11016
    // enable RX, set full-duplex mode, NO receive small, NO correct IFG
11017
    wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
11018
              `ETH_MODER_PRO | `ETH_MODER_BRO,
11019
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11020
    // prepare two packets of MAXFL length
11021
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11022
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
11023
    min_tmp = tmp[31:16];
11024
    st_data = 8'h0F;
11025
    set_rx_packet(0, (max_tmp - 4), 1'b0, 48'h0102_0304_0506, 48'h0708_090A_0B0C, 16'h0D0E, st_data); // length without CRC
11026
    st_data = 8'h1A;
11027
    set_rx_packet((max_tmp), (max_tmp - 4), 1'b0, 48'h1234_5678_8765, 48'hA1B2_C3D4_E5F6, 16'hE77E, st_data);
11028
    // check WB INT signal
11029
    if (wb_int !== 1'b0)
11030
    begin
11031
      test_fail("WB INT signal should not be set");
11032
      fail = fail + 1;
11033
    end
11034
 
11035
    // write to phy's control register for 100Mbps
11036
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
11037
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
11038
    speed = 100;
11039
 
11040
    i_length = (min_tmp - 4);
11041
    while (i_length <= (max_tmp - 4))
11042
    begin
11043
      // choose generating carrier sense and collision for first and last 64 lengths of frames
11044
      case (i_length[1:0])
11045
      2'h0: // Interrupt is generated
11046
      begin
11047
        // enable interrupt generation
11048
        set_rx_bd(127, 127, 1'b1, (`MEMORY_BASE + i_length[1:0]));
11049
        // unmask interrupts
11050
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
11051
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11052
        // not detect carrier sense in FD and no collision
11053
        eth_phy.no_carrier_sense_rx_fd_detect(0);
11054
        eth_phy.collision(0);
11055
      end
11056
      2'h1: // Interrupt is not generated
11057
      begin
11058
        // enable interrupt generation
11059
        set_rx_bd(127, 127, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
11060
        // mask interrupts
11061
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11062
        // detect carrier sense in FD and no collision
11063
        eth_phy.no_carrier_sense_rx_fd_detect(1);
11064
        eth_phy.collision(0);
11065
      end
11066
      2'h2: // Interrupt is not generated
11067
      begin
11068
        // disable interrupt generation
11069
        set_rx_bd(127, 127, 1'b0, (`MEMORY_BASE + i_length[1:0]));
11070
        // unmask interrupts
11071
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
11072
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11073
        // not detect carrier sense in FD and set collision
11074
        eth_phy.no_carrier_sense_rx_fd_detect(0);
11075
        eth_phy.collision(1);
11076
      end
11077
      default: // 2'h3: // Interrupt is not generated
11078
      begin
11079
        // disable interrupt generation
11080
        set_rx_bd(127, 127, 1'b0, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
11081
        // mask interrupts
11082
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11083
        // detect carrier sense in FD and set collision
11084
        eth_phy.no_carrier_sense_rx_fd_detect(1);
11085
        eth_phy.collision(1);
11086
      end
11087
      endcase
11088
      if (i_length[0] == 1'b0)
11089
        append_rx_crc (0, i_length, 1'b0, 1'b0);
11090
      else
11091
        append_rx_crc (max_tmp, i_length, 1'b0, 1'b0);
11092
      // set wrap bit
11093
      set_rx_bd_wrap(127);
11094
      set_rx_bd_empty(127, 127);
11095
      fork
11096
        begin
11097
          if (i_length[0] == 1'b0)
11098
            #1 eth_phy.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, 8'hD5, 0, (i_length + 4), 1'b0);
11099
          else
11100
            #1 eth_phy.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, 8'hD5, max_tmp, (i_length + 4), 1'b0);
11101
          repeat(10) @(posedge mrx_clk);
11102
        end
11103
        begin
11104
          #1 check_rx_bd(127, data);
11105
          if (i_length < min_tmp) // just first four
11106
          begin
11107
            while (data[15] === 1)
11108
            begin
11109
              #1 check_rx_bd(127, data);
11110
              @(posedge wb_clk);
11111
            end
11112
            repeat (1) @(posedge wb_clk);
11113
          end
11114
          else
11115
          begin
11116
            wait (MRxDV === 1'b1); // start transmit
11117
            #1 check_rx_bd(127, data);
11118
            if (data[15] !== 1)
11119
            begin
11120
              test_fail("Wrong buffer descriptor's ready bit read out from MAC");
11121
              fail = fail + 1;
11122
            end
11123
            wait (MRxDV === 1'b0); // end transmit
11124
            while (data[15] === 1)
11125
            begin
11126
              #1 check_rx_bd(127, data);
11127
              @(posedge wb_clk);
11128
            end
11129
            repeat (1) @(posedge wb_clk);
11130
          end
11131
        end
11132
      join
11133
      // check length of a PACKET
11134
      if (data[31:16] != (i_length + 4))
11135
      begin
11136
        `TIME; $display("*E Wrong length of the packet out from PHY (%0d instead of %0d)",
11137
                        data[31:16], (i_length + 4));
11138
        test_fail("Wrong length of the packet out from PHY");
11139
        fail = fail + 1;
11140
      end
11141
      // checking in the following if statement is performed only for first and last 64 lengths
11142
      // check received RX packet data and CRC
11143
      if (i_length[0] == 1'b0)
11144
      begin
11145
        check_rx_packet(0, (`MEMORY_BASE + i_length[1:0]), (i_length + 4), 1'b0, 1'b0, tmp);
11146
      end
11147
      else
11148
      begin
11149
        check_rx_packet(max_tmp, ((`MEMORY_BASE + i_length[1:0]) + max_tmp), (i_length + 4), 1'b0, 1'b0, tmp);
11150
      end
11151
      if (tmp > 0)
11152
      begin
11153
        `TIME; $display("*E Wrong data of the received packet");
11154
        test_fail("Wrong data of the received packet");
11155
        fail = fail + 1;
11156
      end
11157
      // check WB INT signal
11158
      if (i_length[1:0] == 2'h0)
11159
      begin
11160
        if (wb_int !== 1'b1)
11161
        begin
11162
          `TIME; $display("*E WB INT signal should be set");
11163
          test_fail("WB INT signal should be set");
11164
          fail = fail + 1;
11165
        end
11166
      end
11167
      else
11168
      begin
11169
        if (wb_int !== 1'b0)
11170
        begin
11171
          `TIME; $display("*E WB INT signal should not be set");
11172
          test_fail("WB INT signal should not be set");
11173
          fail = fail + 1;
11174
        end
11175
      end
11176
      // check RX buffer descriptor of a packet
11177
      check_rx_bd(127, data);
11178
      if (i_length[1] == 1'b0) // interrupt enabled 
11179
      begin
11180
        if ( ((data[15:0] !== 16'h6000) && (i_length[0] == 1'b0)) ||
11181
             ((data[15:0] !== 16'h6000) && (i_length[0] == 1'b1)) )
11182
        begin
11183
          `TIME; $display("*E RX buffer descriptor status is not correct: %0h", data[15:0]);
11184
          test_fail("RX buffer descriptor status is not correct");
11185
          fail = fail + 1;
11186
        end
11187
      end
11188
      else // interrupt not enabled
11189
      begin
11190
        if ( ((data[15:0] !== 16'h2000) && (i_length[0] == 1'b0)) ||
11191
             ((data[15:0] !== 16'h2000) && (i_length[0] == 1'b1)) )
11192
        begin
11193
          `TIME; $display("*E RX buffer descriptor status is not correct: %0h", data[15:0]);
11194
          test_fail("RX buffer descriptor status is not correct");
11195
          fail = fail + 1;
11196
        end
11197
      end
11198
      // clear RX buffer descriptor for first 4 frames
11199
      if (i_length < min_tmp)
11200
        clear_rx_bd(127, 127);
11201
      // check interrupts
11202
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11203
      if ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1))
11204
      begin
11205
        if ((data & `ETH_INT_RXB) !== `ETH_INT_RXB)
11206
        begin
11207
          `TIME; $display("*E Interrupt Receive Buffer was not set, interrupt reg: %0h", data);
11208
          test_fail("Interrupt Receive Buffer was not set");
11209
          fail = fail + 1;
11210
        end
11211
        if ((data & (~`ETH_INT_RXB)) !== 0)
11212
        begin
11213
          `TIME; $display("*E Other interrupts (except Receive Buffer) were set, interrupt reg: %0h", data);
11214
          test_fail("Other interrupts (except Receive Buffer) were set");
11215
          fail = fail + 1;
11216
        end
11217
      end
11218
      else
11219
      begin
11220
        if (data !== 0)
11221
        begin
11222
          `TIME; $display("*E Any of interrupts (except Receive Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]);
11223
          test_fail("Any of interrupts (except Receive Buffer) was set");
11224
          fail = fail + 1;
11225
        end
11226
      end
11227
      // clear interrupts
11228
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11229
      // check WB INT signal
11230
      if (wb_int !== 1'b0)
11231
      begin
11232
        test_fail("WB INT signal should not be set");
11233
        fail = fail + 1;
11234
      end
11235
      // INTERMEDIATE DISPLAYS
11236
      if ((i_length + 4) == (min_tmp + 64))
11237
      begin
11238
        // starting length is min_tmp, ending length is (min_tmp + 64)
11239
        $display("    receive small packets is NOT selected");
11240
        $display("    ->packets with lengths from %0d (MINFL) to %0d are checked (length increasing by 1 byte)",
11241
                 min_tmp, (min_tmp + 64));
11242
        // set receive small, remain the rest
11243
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_IFG |
11244
                  `ETH_MODER_PRO | `ETH_MODER_BRO,
11245
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11246
      end
11247
      else if ((i_length + 4) == (max_tmp - 16))
11248
      begin
11249
        // starting length is for +128 longer than previous ending length, while ending length is tmp_data
11250
        $display("    receive small packets is selected");
11251
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 128 bytes)",
11252
                 (min_tmp + 64 + 128), tmp_data);
11253
        // reset receive small, remain the rest
11254
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
11255
                  `ETH_MODER_PRO | `ETH_MODER_BRO,
11256
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11257
      end
11258
      else if ((i_length + 4) == max_tmp)
11259
      begin
11260
        $display("    receive small packets is NOT selected");
11261
        $display("    ->packets with lengths from %0d to %0d (MAXFL) are checked (length increasing by 1 byte)",
11262
                 (max_tmp - (4 + 16)), max_tmp);
11263
      end
11264
      // set length (loop variable)
11265
      if ((i_length + 4) < (min_tmp + 64))
11266
        i_length = i_length + 1;
11267
      else if ( ((i_length + 4) >= (min_tmp + 64)) && ((i_length + 4) <= (max_tmp - 256)) )
11268
      begin
11269
        i_length = i_length + 128;
11270
        tmp_data = i_length + 4; // last tmp_data is ending length
11271
      end
11272
      else if ( ((i_length + 4) > (max_tmp - 256)) && ((i_length + 4) < (max_tmp - 16)) )
11273
        i_length = max_tmp - (4 + 16);
11274
      else if ((i_length + 4) >= (max_tmp - 16))
11275
        i_length = i_length + 1;
11276
      else
11277
      begin
11278
        $display("*E TESTBENCH ERROR - WRONG PARAMETERS IN TESTBENCH");
11279
        #10 $stop;
11280
      end
11281
    end
11282
    // disable RX
11283
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_IFG |
11284
              `ETH_MODER_PRO | `ETH_MODER_BRO,
11285
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11286
    if(fail == 0)
11287
      test_ok;
11288
    else
11289
      fail = 0;
11290
  end
11291
 
11292
 
11293
  ////////////////////////////////////////////////////////////////////
11294
  ////                                                            ////
11295
  ////  Test receive packets form MINFL to MAXFL sizes at         ////
11296
  ////  maximum RX buffer decriptors ( 10Mbps ).                  ////
11297
  ////                                                            ////
11298
  ////////////////////////////////////////////////////////////////////
11299
  if (test_num == 4) // 
11300
  begin
11301
    // TEST 4: RECEIVE PACKETS FROM MINFL TO MAXFL SIZES AT MAX RX BDs ( 10Mbps )
11302
    test_name = "TEST 4: RECEIVE PACKETS FROM MINFL TO MAXFL SIZES AT MAX RX BDs ( 10Mbps )";
11303
    `TIME; $display("  TEST 4: RECEIVE PACKETS FROM MINFL TO MAXFL SIZES AT MAX RX BDs ( 10Mbps )");
11304
 
11305
    // reset MAC registers
11306
    hard_reset;
11307
    // reset MAC and MII LOGIC with soft reset
11308
    reset_mac;
11309
    reset_mii;
11310
    // set wb slave response
11311
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
11312
 
11313
    max_tmp = 0;
11314
    min_tmp = 0;
11315
    num_of_frames = 0;
11316
    num_of_bd = 0;
11317
    // set maximum RX buffer descriptors (128) - must be set before RX enable
11318
    wbm_write(`ETH_TX_BD_NUM, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11319
    // enable RX, set full-duplex mode, NO receive small, NO correct IFG
11320
    wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
11321
              `ETH_MODER_PRO | `ETH_MODER_BRO,
11322
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11323
    // prepare two packets of MAXFL length
11324
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11325
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
11326
    min_tmp = tmp[31:16];
11327
    st_data = 8'hAC;
11328
    set_rx_packet(0, (max_tmp - 4), 1'b0, 48'h0102_0304_0506, 48'h0708_090A_0B0C, 16'h0D0E, st_data); // length without CRC
11329
    st_data = 8'h35;
11330
    set_rx_packet((max_tmp), (max_tmp - 4), 1'b0, 48'h1234_5678_8765, 48'hA1B2_C3D4_E5F6, 16'hE77E, st_data);
11331
    // check WB INT signal
11332
    if (wb_int !== 1'b0)
11333
    begin
11334
      test_fail("WB INT signal should not be set");
11335
      fail = fail + 1;
11336
    end
11337
 
11338
    // write to phy's control register for 10Mbps
11339
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
11340
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
11341
    speed = 10;
11342
 
11343
    i_length = (min_tmp - 4);
11344
    while (i_length <= (max_tmp - 4))
11345
    begin
11346
      // append CRC to packet
11347
      if (i_length[0] == 1'b0)
11348
        append_rx_crc (0, i_length, 1'b0, 1'b0);
11349
      else
11350
        append_rx_crc (max_tmp, i_length, 1'b0, 1'b0);
11351
      // choose generating carrier sense and collision
11352
      case (i_length[1:0])
11353
      2'h0: // Interrupt is generated
11354
      begin
11355
        // Reset_tx_bd nable interrupt generation
11356
        // unmask interrupts
11357
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
11358
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11359
        // not detect carrier sense in FD and no collision
11360
        eth_phy.no_carrier_sense_rx_fd_detect(0);
11361
        eth_phy.collision(0);
11362
      end
11363
      2'h1: // Interrupt is not generated
11364
      begin
11365
        // set_tx_bd enable interrupt generation
11366
        // mask interrupts
11367
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11368
        // detect carrier sense in FD and no collision
11369
        eth_phy.no_carrier_sense_rx_fd_detect(1);
11370
        eth_phy.collision(0);
11371
      end
11372
      2'h2: // Interrupt is not generated
11373
      begin
11374
        // set_tx_bd disable the interrupt generation
11375
        // unmask interrupts
11376
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
11377
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11378
        // not detect carrier sense in FD and set collision
11379
        eth_phy.no_carrier_sense_rx_fd_detect(0);
11380
        eth_phy.collision(1);
11381
      end
11382
      default: // 2'h3: // Interrupt is not generated
11383
      begin
11384
        // set_tx_bd disable the interrupt generation
11385
        // mask interrupts
11386
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11387
        // detect carrier sense in FD and set collision
11388
        eth_phy.no_carrier_sense_rx_fd_detect(1);
11389
        eth_phy.collision(1);
11390
      end
11391
      endcase
11392
      // first 8 frames are received with RX BD 0 (wrap bit on RX BD 0)
11393
      // number of all frames is 154 (146 without first 8)
11394
      if (num_of_frames < 8)
11395
      begin
11396
        case (i_length[1:0])
11397
        2'h0: // Interrupt is generated
11398
        begin
11399
          // enable interrupt generation
11400
          set_rx_bd(0, 0, 1'b1, (`MEMORY_BASE + i_length[1:0]));
11401
          // interrupts are unmasked
11402
        end
11403
        2'h1: // Interrupt is not generated
11404
        begin
11405
          // enable interrupt generation
11406
          set_rx_bd(0, 0, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
11407
          // interrupts are masked
11408
        end
11409
        2'h2: // Interrupt is not generated
11410
        begin
11411
          // disable interrupt generation
11412
          set_rx_bd(0, 0, 1'b0, (`MEMORY_BASE + i_length[1:0]));
11413
          // interrupts are unmasked
11414
        end
11415
        default: // 2'h3: // Interrupt is not generated
11416
        begin
11417
          // disable interrupt generation
11418
          set_rx_bd(0, 0, 1'b0, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
11419
          // interrupts are masked
11420
        end
11421
        endcase
11422
        // set wrap bit
11423
        set_rx_bd_wrap(0);
11424
      end
11425
      // after first 8 number of frames, 128 frames form RX BD 0 to 127 will be received
11426
      else if ((num_of_frames - 8) == 0)
11427
      begin
11428
        tmp_len = i_length; // length of frame
11429
        tmp_bd_num = 0; // RX BD number
11430
        while (tmp_bd_num < 128) // (tmp_len <= (max_tmp - 4)) - this is the last frame
11431
        begin
11432
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
11433
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
11434
          if (tmp_len[0] == 0)
11435
            set_rx_bd(tmp_bd_num, tmp_bd_num, !tmp_len[1], (`MEMORY_BASE + tmp_len[1:0]));
11436
          else
11437
            set_rx_bd(tmp_bd_num, tmp_bd_num, !tmp_len[1], ((`MEMORY_BASE + tmp_len[1:0]) + max_tmp));
11438
          // set length (loop variable) - THE SAME AS AT THE END OF THIS TASK !!!
11439
          if ((tmp_len + 4) < (min_tmp + 128))
11440
            tmp_len = tmp_len + 1;
11441
          else if ( ((tmp_len + 4) == (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
11442
            tmp_len = 256;
11443
          else if ( ((tmp_len + 4) > (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
11444
            tmp_len = tmp_len + 128;
11445
          else if ( ((tmp_len + 4) > (max_tmp - 256)) && ((tmp_len + 4) < (max_tmp - 16)) )
11446
            tmp_len = max_tmp - (4 + 16);
11447
          else if ((tmp_len + 4) >= (max_tmp - 16))
11448
            tmp_len = tmp_len + 1;
11449
          // set RX BD number
11450
          tmp_bd_num = tmp_bd_num + 1;
11451
        end
11452
        // set wrap bit
11453
        set_rx_bd_wrap(127);
11454
      end
11455
      // after 128 + first 8 number of frames, 19 frames form RX BD 0 to 18 will be received
11456
      else if ((num_of_frames - 8) == 20) // 128
11457
      begin
11458
        tmp_len = tmp_len; // length of frame remaines from previous settings
11459
        tmp_bd_num = 0; // TX BD number
11460
        while (tmp_bd_num < 19) // (tmp_len <= (max_tmp - 4)) - this is the last frame
11461
        begin
11462
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
11463
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
11464
          if (tmp_len[0] == 0)
11465
            set_rx_bd(tmp_bd_num, tmp_bd_num, !tmp_len[1], (`MEMORY_BASE + tmp_len[1:0]));
11466
          else
11467
            set_rx_bd(tmp_bd_num, tmp_bd_num, !tmp_len[1], ((`MEMORY_BASE + tmp_len[1:0]) + max_tmp));
11468
          // set length (loop variable) - THE SAME AS AT THE END OF THIS TASK !!!
11469
          if ((tmp_len + 4) < (min_tmp + 128))
11470
            tmp_len = tmp_len + 1;
11471
          else if ( ((tmp_len + 4) == (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
11472
            tmp_len = 256;
11473
          else if ( ((tmp_len + 4) > (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
11474
            tmp_len = tmp_len + 128;
11475
          else if ( ((tmp_len + 4) > (max_tmp - 256)) && ((tmp_len + 4) < (max_tmp - 16)) )
11476
            tmp_len = max_tmp - (4 + 16);
11477
          else if ((tmp_len + 4) >= (max_tmp - 16))
11478
            tmp_len = tmp_len + 1;
11479
          // set TX BD number
11480
          tmp_bd_num = tmp_bd_num + 1;
11481
        end
11482
      end
11483
      // set empty bit
11484
      if (num_of_frames < 8)
11485
        set_rx_bd_empty(0, 0);
11486
      else if ((num_of_frames - 8) < 128)
11487
        set_rx_bd_empty((num_of_frames - 8), (num_of_frames - 8));
11488
      else if ((num_of_frames - 136) < 19)
11489
        set_rx_bd_empty((num_of_frames - 136), (num_of_frames - 136));
11490
      // CHECK END OF RECEIVE
11491
      fork
11492
        begin
11493
          if (i_length[0] == 1'b0)
11494
            #1 eth_phy.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, 8'hD5, 0, (i_length + 4), 1'b0);
11495
          else
11496
            #1 eth_phy.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, 8'hD5, max_tmp, (i_length + 4), 1'b0);
11497
          repeat(10) @(posedge mrx_clk);
11498
        end
11499
        begin
11500
          #1 check_rx_bd(num_of_bd, data);
11501
          if (i_length < min_tmp) // just first four
11502
          begin
11503
            while (data[15] === 1)
11504
            begin
11505
              #1 check_rx_bd(num_of_bd, data);
11506
              @(posedge wb_clk);
11507
            end
11508
            repeat (1) @(posedge wb_clk);
11509
          end
11510
          else
11511
          begin
11512
            wait (MRxDV === 1'b1); // start transmit
11513
            #1 check_rx_bd(num_of_bd, data);
11514
            if (data[15] !== 1)
11515
            begin
11516
              test_fail("Wrong buffer descriptor's ready bit read out from MAC");
11517
              fail = fail + 1;
11518
            end
11519
            wait (MRxDV === 1'b0); // end transmit
11520
            while (data[15] === 1)
11521
            begin
11522
              #1 check_rx_bd(num_of_bd, data);
11523
              @(posedge wb_clk);
11524
            end
11525
            repeat (1) @(posedge wb_clk);
11526
          end
11527
        end
11528
      join
11529
      // check length of a PACKET
11530
      if (data[31:16] != (i_length + 4))
11531
      begin
11532
        `TIME; $display("*E Wrong length of the packet out from PHY (%0d instead of %0d)",
11533
                        data[31:16], (i_length + 4));
11534
        test_fail("Wrong length of the packet out from PHY");
11535
        fail = fail + 1;
11536
      end
11537
      // checking in the following if statement is performed only for first and last 64 lengths
11538
      // check received RX packet data and CRC
11539
      if (i_length[0] == 1'b0)
11540
      begin
11541
        check_rx_packet(0, (`MEMORY_BASE + i_length[1:0]), (i_length + 4), 1'b0, 1'b0, tmp);
11542
      end
11543
      else
11544
      begin
11545
        check_rx_packet(max_tmp, ((`MEMORY_BASE + i_length[1:0]) + max_tmp), (i_length + 4), 1'b0, 1'b0, tmp);
11546
      end
11547
      if (tmp > 0)
11548
      begin
11549
        `TIME; $display("*E Wrong data of the received packet");
11550
        test_fail("Wrong data of the received packet");
11551
        fail = fail + 1;
11552
      end
11553
      // check WB INT signal
11554
      if (i_length[1:0] == 2'h0)
11555
      begin
11556
        if (wb_int !== 1'b1)
11557
        begin
11558
          `TIME; $display("*E WB INT signal should be set");
11559
          test_fail("WB INT signal should be set");
11560
          fail = fail + 1;
11561
        end
11562
      end
11563
      else
11564
      begin
11565
        if (wb_int !== 1'b0)
11566
        begin
11567
          `TIME; $display("*E WB INT signal should not be set");
11568
          test_fail("WB INT signal should not be set");
11569
          fail = fail + 1;
11570
        end
11571
      end
11572
      // check RX buffer descriptor of a packet
11573
      check_rx_bd(num_of_bd, data);
11574
      if (i_length[1] == 1'b0) // interrupt enabled
11575
      begin
11576
        if ( ((data[15:0] !== 16'h6000) && ((num_of_frames < 8) || ((num_of_frames - 8) == 127))) || // wrap bit
11577
             ((data[15:0] !== 16'h4000) && (num_of_frames >= 8) && ((num_of_frames - 8) != 127)) ) // without wrap bit
11578
        begin
11579
          `TIME; $display("*E RX buffer descriptor status is not correct: %0h", data[15:0]);
11580
          test_fail("RX buffer descriptor status is not correct");
11581
          fail = fail + 1;
11582
        end
11583
      end
11584
      else // interrupt not enabled
11585
      begin
11586
        if ( ((data[15:0] !== 16'h2000)  && ((num_of_frames < 8) || ((num_of_frames - 8) == 127))) || // wrap bit
11587
             ((data[15:0] !== 16'h0000) && (num_of_frames >= 8) && ((num_of_frames - 8) != 127)) ) // without wrap bit
11588
        begin
11589
          `TIME; $display("*E RX buffer descriptor status is not correct: %0h", data[15:0]);
11590
          test_fail("RX buffer descriptor status is not correct");
11591
          fail = fail + 1;
11592
        end
11593
      end
11594
      // clear first half of 8 frames from RX buffer descriptor 0
11595
      if (num_of_frames < 4)
11596
        clear_rx_bd(num_of_bd, num_of_bd);
11597
      // clear BD with wrap bit
11598
      if (num_of_frames == 140)
11599
        clear_rx_bd(127, 127);
11600
      // check interrupts
11601
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11602
      if ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1))
11603
      begin
11604
        if ((data & `ETH_INT_RXB) !== `ETH_INT_RXB)
11605
        begin
11606
          `TIME; $display("*E Interrupt Receive Buffer was not set, interrupt reg: %0h", data);
11607
          test_fail("Interrupt Receive Buffer was not set");
11608
          fail = fail + 1;
11609
        end
11610
        if ((data & (~`ETH_INT_RXB)) !== 0)
11611
        begin
11612
          `TIME; $display("*E Other interrupts (except Receive Buffer) were set, interrupt reg: %0h", data);
11613
          test_fail("Other interrupts (except Receive Buffer) were set");
11614
          fail = fail + 1;
11615
        end
11616
      end
11617
      else
11618
      begin
11619
        if (data !== 0)
11620
        begin
11621
          `TIME; $display("*E Any of interrupts (except Receive Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]);
11622
          test_fail("Any of interrupts (except Receive Buffer) was set");
11623
          fail = fail + 1;
11624
        end
11625
      end
11626
      // clear interrupts
11627
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11628
      // check WB INT signal
11629
      if (wb_int !== 1'b0)
11630
      begin
11631
        test_fail("WB INT signal should not be set");
11632
        fail = fail + 1;
11633
      end
11634
      // INTERMEDIATE DISPLAYS
11635
      if ((i_length + 4) == (min_tmp + 7))
11636
      begin
11637
        // starting length is min_tmp, ending length is (min_tmp + 128)
11638
        $display("    receive small packets is NOT selected");
11639
        $display("    using only RX BD 0 out of 128 BDs assigned to RX (wrap at first BD - RX BD 0)");
11640
        $display("    ->packets with lengths from %0d (MINFL) to %0d are checked (length increasing by 1 byte)",
11641
                 min_tmp, (min_tmp + 7));
11642
        $display("    ->all packets were received on RX BD 0");
11643
        // reset receive small, remain the rest
11644
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
11645
                  `ETH_MODER_PRO | `ETH_MODER_BRO,
11646
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11647
      end
11648
      else if ((i_length + 4) == (min_tmp + 128))
11649
      begin
11650
        // starting length is min_tmp, ending length is (min_tmp + 128)
11651
        $display("    receive small packets is NOT selected");
11652
        $display("    using all 128 BDs assigned to RX (wrap at 128th BD - RX BD 127)");
11653
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
11654
                 (min_tmp + 8), (min_tmp + 128));
11655
        $display("    ->packets were received on RX BD %0d to RX BD %0d respectively",
11656
                 1'b0, num_of_bd);
11657
        tmp_bd = num_of_bd + 1;
11658
        // set receive small, remain the rest
11659
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_IFG |
11660
                  `ETH_MODER_PRO | `ETH_MODER_BRO,
11661
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11662
      end
11663
      else if ((i_length + 4) == (max_tmp - 16))
11664
      begin
11665
        // starting length is for +128 longer than previous ending length, while ending length is tmp_data
11666
        $display("    receive small packets is selected");
11667
        $display("    using all 128 BDs assigned to RX (wrap at 128th BD - RX BD 127)");
11668
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 128 bytes)",
11669
                 (min_tmp + 64 + 128), tmp_data);
11670
        if (tmp_bd > num_of_bd)
11671
          $display("    ->packets were received from RX BD %0d to RX BD 127 and from RX BD 0 to RX BD %0d respectively",
11672
                   tmp_bd, num_of_bd);
11673
        else
11674
          $display("    ->packets were received from RX BD %0d to RX BD %0d respectively",
11675
                   tmp_bd, num_of_bd);
11676
        tmp_bd = num_of_bd + 1;
11677
        // reset receive small, remain the rest
11678
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
11679
                  `ETH_MODER_PRO | `ETH_MODER_BRO,
11680
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11681
      end
11682
      else if ((i_length + 4) == max_tmp)
11683
      begin
11684
        $display("    receive small packets is NOT selected");
11685
        $display("    using all 128 BDs assigned to RX (wrap at 128th BD - RX BD 127)");
11686
        $display("    ->packets with lengths from %0d to %0d (MAXFL) are checked (length increasing by 1 byte)",
11687
                 (max_tmp - (4 + 16)), max_tmp);
11688
        if (tmp_bd > num_of_bd)
11689
          $display("    ->packets were received from RX BD %0d to RX BD 127 and from RX BD 0 to RX BD %0d respectively",
11690
                   tmp_bd, num_of_bd);
11691
        else
11692
          $display("    ->packets were received from RX BD %0d to RX BD %0d respectively",
11693
                   tmp_bd, num_of_bd);
11694
      end
11695
      // set length (loop variable)
11696
      if ((i_length + 4) < (min_tmp + 128))
11697
        i_length = i_length + 1;
11698
      else if ( ((i_length + 4) == (min_tmp + 128)) && ((i_length + 4) <= (max_tmp - 256)) )
11699
        i_length = 256;
11700
      else if ( ((i_length + 4) > (min_tmp + 128)) && ((i_length + 4) <= (max_tmp - 256)) )
11701
      begin
11702
        i_length = i_length + 128;
11703
        tmp_data = i_length + 4; // last tmp_data is ending length
11704
      end
11705
      else if ( ((i_length + 4) > (max_tmp - 256)) && ((i_length + 4) < (max_tmp - 16)) )
11706
        i_length = max_tmp - (4 + 16);
11707
      else if ((i_length + 4) >= (max_tmp - 16))
11708
        i_length = i_length + 1;
11709
      else
11710
      begin
11711
        $display("*E TESTBENCH ERROR - WRONG PARAMETERS IN TESTBENCH");
11712
        #10 $stop;
11713
      end
11714
      // the number of frame transmitted
11715
      num_of_frames = num_of_frames + 1;
11716
      if ((num_of_frames <= 8) || ((num_of_frames - 8) == 128))
11717
        num_of_bd = 0;
11718
      else
11719
        num_of_bd = num_of_bd + 1;
11720
    end
11721
    // disable RX
11722
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_IFG |
11723
              `ETH_MODER_PRO | `ETH_MODER_BRO,
11724
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11725
    @(posedge wb_clk);
11726
    if(fail == 0)
11727
      test_ok;
11728
    else
11729
      fail = 0;
11730
  end
11731
 
11732
 
11733
  ////////////////////////////////////////////////////////////////////
11734
  ////                                                            ////
11735
  ////  Test receive packets form MINFL to MAXFL sizes at         ////
11736
  ////  maximum RX buffer decriptors ( 100Mbps ).                 ////
11737
  ////                                                            ////
11738
  ////////////////////////////////////////////////////////////////////
11739
  if (test_num == 5) // 
11740
  begin
11741
    // TEST 5: RECEIVE PACKETS FROM MINFL TO MAXFL SIZES AT MAX RX BDs ( 100Mbps )
11742
    test_name = "TEST 5: RECEIVE PACKETS FROM MINFL TO MAXFL SIZES AT MAX RX BDs ( 100Mbps )";
11743
    `TIME; $display("  TEST 5: RECEIVE PACKETS FROM MINFL TO MAXFL SIZES AT MAX RX BDs ( 100Mbps )");
11744
 
11745
    // reset MAC registers
11746
    hard_reset;
11747
    // reset MAC and MII LOGIC with soft reset
11748
    reset_mac;
11749
    reset_mii;
11750
    // set wb slave response
11751
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
11752
 
11753
    max_tmp = 0;
11754
    min_tmp = 0;
11755
    num_of_frames = 0;
11756
    num_of_bd = 0;
11757
    // set maximum RX buffer descriptors (128) - must be set before RX enable
11758
    wbm_write(`ETH_TX_BD_NUM, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11759
    // enable RX, set full-duplex mode, NO receive small, NO correct IFG
11760
    wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
11761
              `ETH_MODER_PRO | `ETH_MODER_BRO,
11762
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11763
    // prepare two packets of MAXFL length
11764
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11765
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
11766
    min_tmp = tmp[31:16];
11767
    st_data = 8'hAC;
11768
    set_rx_packet(0, (max_tmp - 4), 1'b0, 48'h0102_0304_0506, 48'h0708_090A_0B0C, 16'h0D0E, st_data); // length without CRC
11769
    st_data = 8'h35;
11770
    set_rx_packet((max_tmp), (max_tmp - 4), 1'b0, 48'h1234_5678_8765, 48'hA1B2_C3D4_E5F6, 16'hE77E, st_data);
11771
    // check WB INT signal
11772
    if (wb_int !== 1'b0)
11773
    begin
11774
      test_fail("WB INT signal should not be set");
11775
      fail = fail + 1;
11776
    end
11777
 
11778
    // write to phy's control register for 100Mbps
11779
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
11780
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
11781
    speed = 100;
11782
 
11783
    i_length = (min_tmp - 4);
11784
    while (i_length <= (max_tmp - 4))
11785
    begin
11786
      // append CRC to packet
11787
      if (i_length[0] == 1'b0)
11788
        append_rx_crc (0, i_length, 1'b0, 1'b0);
11789
      else
11790
        append_rx_crc (max_tmp, i_length, 1'b0, 1'b0);
11791
      // choose generating carrier sense and collision
11792
      case (i_length[1:0])
11793
      2'h0: // Interrupt is generated
11794
      begin
11795
        // Reset_tx_bd nable interrupt generation
11796
        // unmask interrupts
11797
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
11798
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11799
        // not detect carrier sense in FD and no collision
11800
        eth_phy.no_carrier_sense_rx_fd_detect(0);
11801
        eth_phy.collision(0);
11802
      end
11803
      2'h1: // Interrupt is not generated
11804
      begin
11805
        // set_tx_bd enable interrupt generation
11806
        // mask interrupts
11807
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11808
        // detect carrier sense in FD and no collision
11809
        eth_phy.no_carrier_sense_rx_fd_detect(1);
11810
        eth_phy.collision(0);
11811
      end
11812
      2'h2: // Interrupt is not generated
11813
      begin
11814
        // set_tx_bd disable the interrupt generation
11815
        // unmask interrupts
11816
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
11817
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11818
        // not detect carrier sense in FD and set collision
11819
        eth_phy.no_carrier_sense_rx_fd_detect(0);
11820
        eth_phy.collision(1);
11821
      end
11822
      default: // 2'h3: // Interrupt is not generated
11823
      begin
11824
        // set_tx_bd disable the interrupt generation
11825
        // mask interrupts
11826
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
11827
        // detect carrier sense in FD and set collision
11828
        eth_phy.no_carrier_sense_rx_fd_detect(1);
11829
        eth_phy.collision(1);
11830
      end
11831
      endcase
11832
      // first 8 frames are received with RX BD 0 (wrap bit on RX BD 0)
11833
      // number of all frames is 154 (146 without first 8)
11834
      if (num_of_frames < 8)
11835
      begin
11836
        case (i_length[1:0])
11837
        2'h0: // Interrupt is generated
11838
        begin
11839
          // enable interrupt generation
11840
          set_rx_bd(0, 0, 1'b1, (`MEMORY_BASE + i_length[1:0]));
11841
          // interrupts are unmasked
11842
        end
11843
        2'h1: // Interrupt is not generated
11844
        begin
11845
          // enable interrupt generation
11846
          set_rx_bd(0, 0, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
11847
          // interrupts are masked
11848
        end
11849
        2'h2: // Interrupt is not generated
11850
        begin
11851
          // disable interrupt generation
11852
          set_rx_bd(0, 0, 1'b0, (`MEMORY_BASE + i_length[1:0]));
11853
          // interrupts are unmasked
11854
        end
11855
        default: // 2'h3: // Interrupt is not generated
11856
        begin
11857
          // disable interrupt generation
11858
          set_rx_bd(0, 0, 1'b0, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
11859
          // interrupts are masked
11860
        end
11861
        endcase
11862
        // set wrap bit
11863
        set_rx_bd_wrap(0);
11864
      end
11865
      // after first 8 number of frames, 128 frames form RX BD 0 to 127 will be received
11866
      else if ((num_of_frames - 8) == 0)
11867
      begin
11868
        tmp_len = i_length; // length of frame
11869
        tmp_bd_num = 0; // RX BD number
11870
        while (tmp_bd_num < 128) // (tmp_len <= (max_tmp - 4)) - this is the last frame
11871
        begin
11872
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
11873
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
11874
          if (tmp_len[0] == 0)
11875
            set_rx_bd(tmp_bd_num, tmp_bd_num, !tmp_len[1], (`MEMORY_BASE + tmp_len[1:0]));
11876
          else
11877
            set_rx_bd(tmp_bd_num, tmp_bd_num, !tmp_len[1], ((`MEMORY_BASE + tmp_len[1:0]) + max_tmp));
11878
          // set length (loop variable) - THE SAME AS AT THE END OF THIS TASK !!!
11879
          if ((tmp_len + 4) < (min_tmp + 128))
11880
            tmp_len = tmp_len + 1;
11881
          else if ( ((tmp_len + 4) == (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
11882
            tmp_len = 256;
11883
          else if ( ((tmp_len + 4) > (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
11884
            tmp_len = tmp_len + 128;
11885
          else if ( ((tmp_len + 4) > (max_tmp - 256)) && ((tmp_len + 4) < (max_tmp - 16)) )
11886
            tmp_len = max_tmp - (4 + 16);
11887
          else if ((tmp_len + 4) >= (max_tmp - 16))
11888
            tmp_len = tmp_len + 1;
11889
          // set RX BD number
11890
          tmp_bd_num = tmp_bd_num + 1;
11891
        end
11892
        // set wrap bit
11893
        set_rx_bd_wrap(127);
11894
      end
11895
      // after 128 + first 8 number of frames, 19 frames form RX BD 0 to 18 will be received
11896
      else if ((num_of_frames - 8) == 20) // 128
11897
      begin
11898
        tmp_len = tmp_len; // length of frame remaines from previous settings
11899
        tmp_bd_num = 0; // TX BD number
11900
        while (tmp_bd_num < 19) // (tmp_len <= (max_tmp - 4)) - this is the last frame
11901
        begin
11902
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
11903
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
11904
          if (tmp_len[0] == 0)
11905
            set_rx_bd(tmp_bd_num, tmp_bd_num, !tmp_len[1], (`MEMORY_BASE + tmp_len[1:0]));
11906
          else
11907
            set_rx_bd(tmp_bd_num, tmp_bd_num, !tmp_len[1], ((`MEMORY_BASE + tmp_len[1:0]) + max_tmp));
11908
          // set length (loop variable) - THE SAME AS AT THE END OF THIS TASK !!!
11909
          if ((tmp_len + 4) < (min_tmp + 128))
11910
            tmp_len = tmp_len + 1;
11911
          else if ( ((tmp_len + 4) == (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
11912
            tmp_len = 256;
11913
          else if ( ((tmp_len + 4) > (min_tmp + 128)) && ((tmp_len + 4) <= (max_tmp - 256)) )
11914
            tmp_len = tmp_len + 128;
11915
          else if ( ((tmp_len + 4) > (max_tmp - 256)) && ((tmp_len + 4) < (max_tmp - 16)) )
11916
            tmp_len = max_tmp - (4 + 16);
11917
          else if ((tmp_len + 4) >= (max_tmp - 16))
11918
            tmp_len = tmp_len + 1;
11919
          // set TX BD number
11920
          tmp_bd_num = tmp_bd_num + 1;
11921
        end
11922
      end
11923
      // set empty bit
11924
      if (num_of_frames < 8)
11925
        set_rx_bd_empty(0, 0);
11926
      else if ((num_of_frames - 8) < 128)
11927
        set_rx_bd_empty((num_of_frames - 8), (num_of_frames - 8));
11928
      else if ((num_of_frames - 136) < 19)
11929
        set_rx_bd_empty((num_of_frames - 136), (num_of_frames - 136));
11930
      // CHECK END OF RECEIVE
11931
      fork
11932
        begin
11933
          if (i_length[0] == 1'b0)
11934
            #1 eth_phy.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, 8'hD5, 0, (i_length + 4), 1'b0);
11935
          else
11936
            #1 eth_phy.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, 8'hD5, max_tmp, (i_length + 4), 1'b0);
11937
          repeat(10) @(posedge mrx_clk);
11938
        end
11939
        begin
11940
          #1 check_rx_bd(num_of_bd, data);
11941
          if (i_length < min_tmp) // just first four
11942
          begin
11943
            while (data[15] === 1)
11944
            begin
11945
              #1 check_rx_bd(num_of_bd, data);
11946
              @(posedge wb_clk);
11947
            end
11948
            repeat (1) @(posedge wb_clk);
11949
          end
11950
          else
11951
          begin
11952
            wait (MRxDV === 1'b1); // start transmit
11953
            #1 check_rx_bd(num_of_bd, data);
11954
            if (data[15] !== 1)
11955
            begin
11956
              test_fail("Wrong buffer descriptor's ready bit read out from MAC");
11957
              fail = fail + 1;
11958
            end
11959
            wait (MRxDV === 1'b0); // end transmit
11960
            while (data[15] === 1)
11961
            begin
11962
              #1 check_rx_bd(num_of_bd, data);
11963
              @(posedge wb_clk);
11964
            end
11965
            repeat (1) @(posedge wb_clk);
11966
          end
11967
        end
11968
      join
11969
      // check length of a PACKET
11970
      if (data[31:16] != (i_length + 4))
11971
      begin
11972
        `TIME; $display("*E Wrong length of the packet out from PHY (%0d instead of %0d)",
11973
                        data[31:16], (i_length + 4));
11974
        test_fail("Wrong length of the packet out from PHY");
11975
        fail = fail + 1;
11976
      end
11977
      // checking in the following if statement is performed only for first and last 64 lengths
11978
      // check received RX packet data and CRC
11979
      if (i_length[0] == 1'b0)
11980
      begin
11981
        check_rx_packet(0, (`MEMORY_BASE + i_length[1:0]), (i_length + 4), 1'b0, 1'b0, tmp);
11982
      end
11983
      else
11984
      begin
11985
        check_rx_packet(max_tmp, ((`MEMORY_BASE + i_length[1:0]) + max_tmp), (i_length + 4), 1'b0, 1'b0, tmp);
11986
      end
11987
      if (tmp > 0)
11988
      begin
11989
        `TIME; $display("*E Wrong data of the received packet");
11990
        test_fail("Wrong data of the received packet");
11991
        fail = fail + 1;
11992
      end
11993
      // check WB INT signal
11994
      if (i_length[1:0] == 2'h0)
11995
      begin
11996
        if (wb_int !== 1'b1)
11997
        begin
11998
          `TIME; $display("*E WB INT signal should be set");
11999
          test_fail("WB INT signal should be set");
12000
          fail = fail + 1;
12001
        end
12002
      end
12003
      else
12004
      begin
12005
        if (wb_int !== 1'b0)
12006
        begin
12007
          `TIME; $display("*E WB INT signal should not be set");
12008
          test_fail("WB INT signal should not be set");
12009
          fail = fail + 1;
12010
        end
12011
      end
12012
      // check RX buffer descriptor of a packet
12013
      check_rx_bd(num_of_bd, data);
12014
      if (i_length[1] == 1'b0) // interrupt enabled
12015
      begin
12016
        if ( ((data[15:0] !== 16'h6000) && ((num_of_frames < 8) || ((num_of_frames - 8) == 127))) || // wrap bit
12017
             ((data[15:0] !== 16'h4000) && (num_of_frames >= 8) && ((num_of_frames - 8) != 127)) ) // without wrap bit
12018
        begin
12019
          `TIME; $display("*E RX buffer descriptor status is not correct: %0h", data[15:0]);
12020
          test_fail("RX buffer descriptor status is not correct");
12021
          fail = fail + 1;
12022
        end
12023
      end
12024
      else // interrupt not enabled
12025
      begin
12026
        if ( ((data[15:0] !== 16'h2000)  && ((num_of_frames < 8) || ((num_of_frames - 8) == 127))) || // wrap bit
12027
             ((data[15:0] !== 16'h0000) && (num_of_frames >= 8) && ((num_of_frames - 8) != 127)) ) // without wrap bit
12028
        begin
12029
          `TIME; $display("*E RX buffer descriptor status is not correct: %0h", data[15:0]);
12030
          test_fail("RX buffer descriptor status is not correct");
12031
          fail = fail + 1;
12032
        end
12033
      end
12034
      // clear first half of 8 frames from RX buffer descriptor 0
12035
      if (num_of_frames < 4)
12036
        clear_rx_bd(num_of_bd, num_of_bd);
12037
      // clear BD with wrap bit
12038
      if (num_of_frames == 140)
12039
        clear_rx_bd(127, 127);
12040
      // check interrupts
12041
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12042
      if ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1))
12043
      begin
12044
        if ((data & `ETH_INT_RXB) !== `ETH_INT_RXB)
12045
        begin
12046
          `TIME; $display("*E Interrupt Receive Buffer was not set, interrupt reg: %0h", data);
12047
          test_fail("Interrupt Receive Buffer was not set");
12048
          fail = fail + 1;
12049
        end
12050
        if ((data & (~`ETH_INT_RXB)) !== 0)
12051
        begin
12052
          `TIME; $display("*E Other interrupts (except Receive Buffer) were set, interrupt reg: %0h", data);
12053
          test_fail("Other interrupts (except Receive Buffer) were set");
12054
          fail = fail + 1;
12055
        end
12056
      end
12057
      else
12058
      begin
12059
        if (data !== 0)
12060
        begin
12061
          `TIME; $display("*E Any of interrupts (except Receive Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]);
12062
          test_fail("Any of interrupts (except Receive Buffer) was set");
12063
          fail = fail + 1;
12064
        end
12065
      end
12066
      // clear interrupts
12067
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12068
      // check WB INT signal
12069
      if (wb_int !== 1'b0)
12070
      begin
12071
        test_fail("WB INT signal should not be set");
12072
        fail = fail + 1;
12073
      end
12074
      // INTERMEDIATE DISPLAYS
12075
      if ((i_length + 4) == (min_tmp + 7))
12076
      begin
12077
        // starting length is min_tmp, ending length is (min_tmp + 128)
12078
        $display("    receive small packets is NOT selected");
12079
        $display("    using only RX BD 0 out of 128 BDs assigned to RX (wrap at first BD - RX BD 0)");
12080
        $display("    ->packets with lengths from %0d (MINFL) to %0d are checked (length increasing by 1 byte)",
12081
                 min_tmp, (min_tmp + 7));
12082
        $display("    ->all packets were received on RX BD 0");
12083
        // reset receive small, remain the rest
12084
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
12085
                  `ETH_MODER_PRO | `ETH_MODER_BRO,
12086
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12087
      end
12088
      else if ((i_length + 4) == (min_tmp + 128))
12089
      begin
12090
        // starting length is min_tmp, ending length is (min_tmp + 128)
12091
        $display("    receive small packets is NOT selected");
12092
        $display("    using all 128 BDs assigned to RX (wrap at 128th BD - RX BD 127)");
12093
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
12094
                 (min_tmp + 8), (min_tmp + 128));
12095
        $display("    ->packets were received on RX BD %0d to RX BD %0d respectively",
12096
                 1'b0, num_of_bd);
12097
        tmp_bd = num_of_bd + 1;
12098
        // set receive small, remain the rest
12099
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_IFG |
12100
                  `ETH_MODER_PRO | `ETH_MODER_BRO,
12101
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12102
      end
12103
      else if ((i_length + 4) == (max_tmp - 16))
12104
      begin
12105
        // starting length is for +128 longer than previous ending length, while ending length is tmp_data
12106
        $display("    receive small packets is selected");
12107
        $display("    using all 128 BDs assigned to RX (wrap at 128th BD - RX BD 127)");
12108
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 128 bytes)",
12109
                 (min_tmp + 64 + 128), tmp_data);
12110
        if (tmp_bd > num_of_bd)
12111
          $display("    ->packets were received from RX BD %0d to RX BD 127 and from RX BD 0 to RX BD %0d respectively",
12112
                   tmp_bd, num_of_bd);
12113
        else
12114
          $display("    ->packets were received from RX BD %0d to RX BD %0d respectively",
12115
                   tmp_bd, num_of_bd);
12116
        tmp_bd = num_of_bd + 1;
12117
        // reset receive small, remain the rest
12118
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
12119
                  `ETH_MODER_PRO | `ETH_MODER_BRO,
12120
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12121
      end
12122
      else if ((i_length + 4) == max_tmp)
12123
      begin
12124
        $display("    receive small packets is NOT selected");
12125
        $display("    using all 128 BDs assigned to RX (wrap at 128th BD - RX BD 127)");
12126
        $display("    ->packets with lengths from %0d to %0d (MAXFL) are checked (length increasing by 1 byte)",
12127
                 (max_tmp - (4 + 16)), max_tmp);
12128
        if (tmp_bd > num_of_bd)
12129
          $display("    ->packets were received from RX BD %0d to RX BD 127 and from RX BD 0 to RX BD %0d respectively",
12130
                   tmp_bd, num_of_bd);
12131
        else
12132
          $display("    ->packets were received from RX BD %0d to RX BD %0d respectively",
12133
                   tmp_bd, num_of_bd);
12134
      end
12135
      // set length (loop variable)
12136
      if ((i_length + 4) < (min_tmp + 128))
12137
        i_length = i_length + 1;
12138
      else if ( ((i_length + 4) == (min_tmp + 128)) && ((i_length + 4) <= (max_tmp - 256)) )
12139
        i_length = 256;
12140
      else if ( ((i_length + 4) > (min_tmp + 128)) && ((i_length + 4) <= (max_tmp - 256)) )
12141
      begin
12142
        i_length = i_length + 128;
12143
        tmp_data = i_length + 4; // last tmp_data is ending length
12144
      end
12145
      else if ( ((i_length + 4) > (max_tmp - 256)) && ((i_length + 4) < (max_tmp - 16)) )
12146
        i_length = max_tmp - (4 + 16);
12147
      else if ((i_length + 4) >= (max_tmp - 16))
12148
        i_length = i_length + 1;
12149
      else
12150
      begin
12151
        $display("*E TESTBENCH ERROR - WRONG PARAMETERS IN TESTBENCH");
12152
        #10 $stop;
12153
      end
12154
      // the number of frame transmitted
12155
      num_of_frames = num_of_frames + 1;
12156
      if ((num_of_frames <= 8) || ((num_of_frames - 8) == 128))
12157
        num_of_bd = 0;
12158
      else
12159
        num_of_bd = num_of_bd + 1;
12160
    end
12161
    // disable RX
12162
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_IFG |
12163
              `ETH_MODER_PRO | `ETH_MODER_BRO,
12164
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12165
    @(posedge wb_clk);
12166
    if(fail == 0)
12167
      test_ok;
12168
    else
12169
      fail = 0;
12170
  end
12171
 
12172
 
12173
  ////////////////////////////////////////////////////////////////////
12174
  ////                                                            ////
12175
  ////  Test receive packets form 0 to (MINFL - 1) sizes at       ////
12176
  ////  8 RX buffer decriptors ( 10Mbps ).                        ////
12177
  ////                                                            ////
12178
  ////////////////////////////////////////////////////////////////////
12179
  if (test_num == 6) // 
12180
  begin
12181
    // TEST 6: TRANSMIT PACKETS FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 10Mbps )
12182
    test_name = "TEST 6: TRANSMIT PACKETS FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 10Mbps )";
12183
    `TIME; $display("  TEST 6: TRANSMIT PACKETS FROM 0 TO (MINFL - 1) SIZES AT 8 TX BD ( 10Mbps )");
12184
 
12185
    // reset MAC registers
12186
    hard_reset;
12187
    // reset MAC and MII LOGIC with soft reset
12188
    reset_mac;
12189
    reset_mii;
12190
    // set wb slave response
12191
    wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
12192
 
12193
    max_tmp = 0;
12194
    min_tmp = 0;
12195
    // set 8 RX buffer descriptors (120 - 127) - must be set before RX enable
12196
    wbm_write(`ETH_TX_BD_NUM, 32'h78, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12197
    // enable RX, set full-duplex mode, receive small, NO correct IFG
12198
    wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_IFG |
12199
              `ETH_MODER_PRO | `ETH_MODER_BRO,
12200
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12201
    // prepare two packets of MAXFL length
12202
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12203
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
12204
    min_tmp = tmp[31:16];
12205
    st_data = 8'hAC;
12206
    set_rx_packet(0, (max_tmp - 4), 1'b0, 48'h0102_0304_0506, 48'h0708_090A_0B0C, 16'h0D0E, st_data); // length without CRC
12207
    st_data = 8'h35;
12208
    set_rx_packet((max_tmp), (max_tmp - 4), 1'b0, 48'h1234_5678_8765, 48'hA1B2_C3D4_E5F6, 16'hE77E, st_data);
12209
    // check WB INT signal
12210
    if (wb_int !== 1'b0)
12211
    begin
12212
      test_fail("WB INT signal should not be set");
12213
      fail = fail + 1;
12214
    end
12215
 
12216
    // write to phy's control register for 10Mbps
12217
    #Tp eth_phy.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10
12218
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset  - (10/100), bit 8 set - FD
12219
    speed = 10;
12220
 
12221
    frame_started = 0;
12222
    num_of_frames = 0;
12223
    num_of_bd = 0;
12224
    i_length = 0; // 0;
12225
    while (i_length < 70) // (min_tmp - 4))
12226
    begin
12227
      #1;
12228
      // choose generating carrier sense and collision
12229
      case (i_length[1:0])
12230
      2'h0: // Interrupt is generated
12231
      begin
12232
        // Reset_tx_bd nable interrupt generation
12233
        // unmask interrupts
12234
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
12235
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12236
        // not detect carrier sense in FD and no collision
12237
        eth_phy.carrier_sense_tx_fd_detect(0);
12238
        eth_phy.collision(0);
12239
      end
12240
      2'h1: // Interrupt is not generated
12241
      begin
12242
        // set_tx_bd enable interrupt generation
12243
        // mask interrupts
12244
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12245
        // detect carrier sense in FD and no collision
12246
        eth_phy.carrier_sense_tx_fd_detect(1);
12247
        eth_phy.collision(0);
12248
      end
12249
      2'h2: // Interrupt is not generated
12250
      begin
12251
        // set_tx_bd disable the interrupt generation
12252
        // unmask interrupts
12253
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
12254
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12255
        // not detect carrier sense in FD and set collision
12256
        eth_phy.carrier_sense_tx_fd_detect(0);
12257
        eth_phy.collision(1);
12258
      end
12259
      default: // 2'h3: // Interrupt is not generated
12260
      begin
12261
        // set_tx_bd disable the interrupt generation
12262
        // mask interrupts
12263
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12264
        // detect carrier sense in FD and set collision
12265
        eth_phy.carrier_sense_tx_fd_detect(1);
12266
        eth_phy.collision(1);
12267
      end
12268
      endcase
12269
      #1;
12270
      // first destination address on ethernet PHY
12271
      eth_phy.set_tx_mem_addr(num_of_frames * 16);
12272
      // SET packets and wrap bit
12273
      // num_of_frames <= 9 => wrap set to TX BD 0
12274
      if (num_of_frames <= 9)
12275
      begin
12276
        tmp_len = i_length; // length of frame
12277
        tmp_bd_num = 0; // TX BD number
12278
        // if i_length[1] == 0 then enable interrupt generation otherwise disable it
12279
        // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
12280
        if (tmp_len[0] == 0)
12281
          set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
12282
        else
12283
          set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
12284
        // set wrap bit
12285
        set_tx_bd_wrap(0);
12286
      end
12287
      // 10 <= num_of_frames < 18 => wrap set to TX BD 3
12288
      else if ((num_of_frames == 10) || (num_of_frames == 14))
12289
      begin
12290
        tmp_len = i_length; // length of frame
12291
        tmp_bd_num = 0; // TX BD number
12292
        while (tmp_bd_num < 4) //
12293
        begin
12294
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
12295
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
12296
          if (tmp_len[0] == 0)
12297
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
12298
          else
12299
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
12300
          tmp_len = tmp_len + 1;
12301
          // set TX BD number
12302
          tmp_bd_num = tmp_bd_num + 1;
12303
        end
12304
        // set wrap bit
12305
        set_tx_bd_wrap(3);
12306
      end
12307
      // 18 <= num_of_frames < 28 => wrap set to TX BD 4
12308
      else if ((num_of_frames == 18) || (num_of_frames == 23))
12309
      begin
12310
        tmp_len = i_length; // length of frame
12311
        tmp_bd_num = 0; // TX BD number
12312
        while (tmp_bd_num < 5) //
12313
        begin
12314
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
12315
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
12316
          if (tmp_len[0] == 0)
12317
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
12318
          else
12319
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
12320
          tmp_len = tmp_len + 1;
12321
          // set TX BD number
12322
          tmp_bd_num = tmp_bd_num + 1;
12323
        end
12324
        // set wrap bit
12325
        set_tx_bd_wrap(4);
12326
      end
12327
      // 28 <= num_of_frames < 40 => wrap set to TX BD 5
12328
      else if ((num_of_frames == 28) || (num_of_frames == 34))
12329
      begin
12330
        tmp_len = i_length; // length of frame
12331
        tmp_bd_num = 0; // TX BD number
12332
        while (tmp_bd_num < 6) //
12333
        begin
12334
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
12335
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
12336
          if (tmp_len[0] == 0)
12337
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
12338
          else
12339
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
12340
          tmp_len = tmp_len + 1;
12341
          // set TX BD number
12342
          tmp_bd_num = tmp_bd_num + 1;
12343
        end
12344
        // set wrap bit
12345
        set_tx_bd_wrap(5);
12346
      end
12347
      // 40 <= num_of_frames < 54 => wrap set to TX BD 6
12348
      else if ((num_of_frames == 40) || (num_of_frames == 47))
12349
      begin
12350
        tmp_len = i_length; // length of frame
12351
        tmp_bd_num = 0; // TX BD number
12352
        while (tmp_bd_num < 7) //
12353
        begin
12354
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
12355
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
12356
          if (tmp_len[0] == 0)
12357
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
12358
          else
12359
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
12360
          tmp_len = tmp_len + 1;
12361
          // set TX BD number
12362
          tmp_bd_num = tmp_bd_num + 1;
12363
        end
12364
        // set wrap bit
12365
        set_tx_bd_wrap(6);
12366
      end
12367
      // 54 <= num_of_frames < 70 => wrap set to TX BD 7
12368
      else if ((num_of_frames == 54) || (num_of_frames == 62))
12369
      begin
12370
        tmp_len = i_length; // length of frame
12371
        tmp_bd_num = 0; // TX BD number
12372
        while (tmp_bd_num < 8) //
12373
        begin
12374
          // if i_length[1] == 0 then enable interrupt generation otherwise disable it
12375
          // if i_length[0] == 0 then base address is `MEMORY_BASE otherwise it is `MEMORY_BASE + max_tmp
12376
          if (tmp_len[0] == 0)
12377
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, `MEMORY_BASE);
12378
          else
12379
            set_tx_bd(tmp_bd_num, tmp_bd_num, tmp_len, !tmp_len[1], 1'b1, 1'b1, (`MEMORY_BASE + max_tmp));
12380
          tmp_len = tmp_len + 1;
12381
          // set TX BD number
12382
          tmp_bd_num = tmp_bd_num + 1;
12383
        end
12384
        // set wrap bit
12385
        set_tx_bd_wrap(7);
12386
      end
12387
      #1;
12388
      // SET ready bit
12389
      if (num_of_frames < 10)
12390
        set_tx_bd_ready(0, 0);
12391
      else if (num_of_frames < 14)
12392
        set_tx_bd_ready((num_of_frames - 10), (num_of_frames - 10));
12393
      else if (num_of_frames < 18)
12394
        set_tx_bd_ready((num_of_frames - 14), (num_of_frames - 14));
12395
      else if (num_of_frames < 23)
12396
        set_tx_bd_ready((num_of_frames - 18), (num_of_frames - 18));
12397
      else if (num_of_frames < 28)
12398
        set_tx_bd_ready((num_of_frames - 23), (num_of_frames - 23));
12399
      else if (num_of_frames < 34)
12400
        set_tx_bd_ready((num_of_frames - 28), (num_of_frames - 28));
12401
      else if (num_of_frames < 40)
12402
        set_tx_bd_ready((num_of_frames - 34), (num_of_frames - 34));
12403
      else if (num_of_frames < 47)
12404
        set_tx_bd_ready((num_of_frames - 40), (num_of_frames - 40));
12405
      else if (num_of_frames < 54)
12406
        set_tx_bd_ready((num_of_frames - 47), (num_of_frames - 47));
12407
      else if (num_of_frames < 62)
12408
        set_tx_bd_ready((num_of_frames - 54), (num_of_frames - 54));
12409
      else if (num_of_frames < 70)
12410
        set_tx_bd_ready((num_of_frames - 62), (num_of_frames - 62));
12411
      // CHECK END OF TRANSMITION
12412
      frame_started = 0;
12413
      if (num_of_frames >= 5)
12414
        #1 check_tx_bd(num_of_bd, data);
12415
      fork
12416
      begin: fr_st
12417
        wait (MTxEn === 1'b1); // start transmit
12418
        frame_started = 1;
12419
      end
12420
      begin
12421
        repeat (30) @(posedge mtx_clk);
12422
        if (num_of_frames < 5)
12423
        begin
12424
          if (frame_started == 1)
12425
          begin
12426
            `TIME; $display("*E Frame should NOT start!");
12427
          end
12428
          disable fr_st;
12429
        end
12430
        else
12431
        begin
12432
          if (frame_started == 0)
12433
          begin
12434
            `TIME; $display("*W Frame should start!");
12435
            disable fr_st;
12436
          end
12437
        end
12438
      end
12439
      join
12440
      // check packets larger than 4 bytes
12441
      if (num_of_frames >= 5)
12442
      begin
12443
        wait (MTxEn === 1'b0); // end transmit
12444
        while (data[15] === 1)
12445
        begin
12446
          #1 check_tx_bd(num_of_bd, data);
12447
          @(posedge wb_clk);
12448
        end
12449
        repeat (1) @(posedge wb_clk);
12450
        // check length of a PACKET
12451
        if (i_length <= (min_tmp - 4))
12452
        begin
12453
          if (eth_phy.tx_len != min_tmp)
12454
          begin
12455
            test_fail("Wrong length of the packet out from MAC");
12456
            fail = fail + 1;
12457
          end
12458
        end
12459
        else
12460
        begin
12461
          if (eth_phy.tx_len != (i_length + 4))
12462
          begin
12463
            test_fail("Wrong length of the packet out from MAC");
12464
            fail = fail + 1;
12465
          end
12466
        end
12467
        // check transmitted TX packet data
12468
        if (i_length[0] == 0)
12469
        begin
12470
          #1 check_tx_packet(`MEMORY_BASE, (num_of_frames * 16), i_length, tmp);
12471
        end
12472
        else
12473
        begin
12474
          #1 check_tx_packet((`MEMORY_BASE + max_tmp), (num_of_frames * 16), i_length, tmp);
12475
        end
12476
        if (tmp > 0)
12477
        begin
12478
          test_fail("Wrong data of the transmitted packet");
12479
          fail = fail + 1;
12480
        end
12481
        // check transmited TX packet CRC
12482
        if (num_of_frames < (min_tmp - 4))
12483
          #1 check_tx_crc((num_of_frames * 16), (min_tmp - 4), 1'b0, tmp); // length without CRC
12484
        else
12485
          #1 check_tx_crc((num_of_frames * 16), i_length, 1'b0, tmp); // length without CRC
12486
        if (tmp > 0)
12487
        begin
12488
          test_fail("Wrong CRC of the transmitted packet");
12489
          fail = fail + 1;
12490
        end
12491
      end
12492
      // check WB INT signal
12493
      if ((i_length[1:0] == 2'h0) && (num_of_frames >= 5))
12494
      begin
12495
        if (wb_int !== 1'b1)
12496
        begin
12497
          `TIME; $display("*E WB INT signal should be set");
12498
          test_fail("WB INT signal should be set");
12499
          fail = fail + 1;
12500
        end
12501
      end
12502
      else
12503
      begin
12504
        if (wb_int !== 1'b0)
12505
        begin
12506
          `TIME; $display("*E WB INT signal should not be set");
12507
          test_fail("WB INT signal should not be set");
12508
          fail = fail + 1;
12509
        end
12510
      end
12511
      // check TX buffer descriptor of a packet
12512
      check_tx_bd(num_of_bd, data);
12513
      if (num_of_frames >= 5)
12514
      begin
12515
        if (i_length[1] == 1'b0) // interrupt enabled
12516
        begin
12517
          if ( (data[15:0] !== 16'h7800) && // wrap bit
12518
               (data[15:0] !== 16'h5800) ) // without wrap bit
12519
          begin
12520
            `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
12521
            test_fail("TX buffer descriptor status is not correct");
12522
            fail = fail + 1;
12523
          end
12524
        end
12525
        else // interrupt not enabled
12526
        begin
12527
          if ( (data[15:0] !== 16'h3800) && // wrap bit
12528
               (data[15:0] !== 16'h1800) ) // without wrap bit
12529
          begin
12530
            `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
12531
            test_fail("TX buffer descriptor status is not correct");
12532
            fail = fail + 1;
12533
          end
12534
        end
12535
      end
12536
      else
12537
      begin
12538
        if (data[15] !== 1'b1)
12539
        begin
12540
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
12541
          test_fail("TX buffer descriptor status is not correct");
12542
          fail = fail + 1;
12543
        end
12544
      end
12545
      // clear TX BD with wrap bit
12546
      if (num_of_frames == 63)
12547
        clear_tx_bd(16, 16);
12548
      // check interrupts
12549
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12550
      if ( ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1)) && (num_of_frames >= 5) )
12551
      begin
12552
        if ((data & `ETH_INT_TXB) !== 1'b1)
12553
        begin
12554
          `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
12555
          test_fail("Interrupt Transmit Buffer was not set");
12556
          fail = fail + 1;
12557
        end
12558
        if ((data & (~`ETH_INT_TXB)) !== 0)
12559
        begin
12560
          `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
12561
          test_fail("Other interrupts (except Transmit Buffer) were set");
12562
          fail = fail + 1;
12563
        end
12564
      end
12565
      else
12566
      begin
12567
        if (data !== 0)
12568
        begin
12569
          `TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]);
12570
          test_fail("Any of interrupts (except Transmit Buffer) was set");
12571
          fail = fail + 1;
12572
        end
12573
      end
12574
      // clear interrupts
12575
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12576
      // check WB INT signal
12577
      if (wb_int !== 1'b0)
12578
      begin
12579
        test_fail("WB INT signal should not be set");
12580
        fail = fail + 1;
12581
      end
12582
      // INTERMEDIATE DISPLAYS
12583
      if (i_length == 3)
12584
      begin
12585
        $display("    pads appending to packets is selected");
12586
        $display("    using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)");
12587
        $display("    ->packets with lengths from %0d to %0d are not transmitted (length increasing by 1 byte)",
12588
                 0, 3);
12589
      end
12590
      else if (i_length == 9)
12591
      begin
12592
        $display("    using 1 BD out of 8 BDs assigned to TX (wrap at 1st BD - TX BD 0)");
12593
        $display("    ->packet with length 4 is not transmitted (length increasing by 1 byte)");
12594
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
12595
                 5, 9);
12596
      end
12597
      else if (i_length == 17)
12598
      begin
12599
        $display("    using 4 BDs out of 8 BDs assigned to TX (wrap at 4th BD - TX BD 3)");
12600
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
12601
                 10, 17);
12602
      end
12603
      else if (i_length == 27)
12604
      begin
12605
        $display("    using 5 BDs out of 8 BDs assigned to TX (wrap at 5th BD - TX BD 4)");
12606
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
12607
                 18, 27);
12608
      end
12609
      else if (i_length == 40)
12610
      begin
12611
        $display("    using 6 BDs out of 8 BDs assigned to TX (wrap at 6th BD - TX BD 5)");
12612
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
12613
                 28, 40);
12614
      end
12615
      else if (i_length == 54)
12616
      begin
12617
        $display("    using 7 BDs out of 8 BDs assigned to TX (wrap at 7th BD - TX BD 6)");
12618
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
12619
                 41, 54);
12620
      end
12621
      else if (i_length == 69)
12622
      begin
12623
        $display("    using 8 BDs out of 8 BDs assigned to TX (wrap at 8th BD - TX BD 7)");
12624
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 1 byte)",
12625
                 55, 69);
12626
      end
12627
      // set length (loop variable)
12628
      i_length = i_length + 1;
12629
      // the number of frame transmitted
12630
      num_of_frames = num_of_frames + 1;
12631
      if (/*(num_of_frames == 2) || (num_of_frames == 4) || (num_of_frames == 7) ||*/ (num_of_frames <= 10) ||
12632
          (num_of_frames == 14) || (num_of_frames == 18) || (num_of_frames == 23) || (num_of_frames == 28) ||
12633
          (num_of_frames == 34) || (num_of_frames == 40) || (num_of_frames == 47) ||
12634
          (num_of_frames == 54) || (num_of_frames == 62))
12635
        num_of_bd = 0;
12636
      else
12637
        num_of_bd = num_of_bd + 1;
12638
    end
12639
    // disable TX
12640
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN,
12641
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12642
    @(posedge wb_clk);
12643
    if(fail == 0)
12644
      test_ok;
12645
    else
12646
      fail = 0;
12647
  end
12648
 
12649
 
12650
 
12651
end   //  for (test_num=start_task; test_num <= end_task; test_num=test_num+1)
12652
 
12653
end
12654
endtask // test_mac_full_duplex_receive
12655
 
12656
 
12657
task test_mac_full_duplex_flow;
12658
  input  [31:0]  start_task;
12659
  input  [31:0]  end_task;
12660
  integer        bit_start_1;
12661
  integer        bit_end_1;
12662
  integer        bit_start_2;
12663
  integer        bit_end_2;
12664
  integer        num_of_reg;
12665
  integer        num_of_frames;
12666
  integer        num_of_bd;
12667
  integer        i_addr;
12668
  integer        i_data;
12669
  integer        i_length;
12670
  integer        tmp_len;
12671
  integer        tmp_bd;
12672
  integer        tmp_bd_num;
12673
  integer        tmp_data;
12674
  integer        tmp_ipgt;
12675
  integer        test_num;
12676
  reg    [31:0]  tx_bd_num;
12677
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_data;
12678
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_tmp_data;
12679
  integer        i;
12680
  integer        i1;
12681
  integer        i2;
12682
  integer        i3;
12683
  integer        fail;
12684
  integer        speed;
12685
  reg            frame_started;
12686
  reg            frame_ended;
12687
  reg            wait_for_frame;
12688
  reg    [31:0]  addr;
12689
  reg    [31:0]  data;
12690
  reg    [31:0]  tmp;
12691
  reg    [ 7:0]  st_data;
12692
  reg    [15:0]  max_tmp;
12693
  reg    [15:0]  min_tmp;
12694
begin
12695
// MAC FULL DUPLEX FLOW TEST
12696
test_heading("MAC FULL DUPLEX FLOW TEST");
12697
$display(" ");
12698
$display("MAC FULL DUPLEX FLOW TEST");
12699
fail = 0;
12700
 
12701
// reset MAC registers
12702
hard_reset;
12703
// reset MAC and MII LOGIC with soft reset
12704
reset_mac;
12705
reset_mii;
12706
// set wb slave response
12707
wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
12708
 
12709
  /*
12710
  TASKS for set and control TX buffer descriptors (also send packet - set_tx_bd_ready):
12711
  -------------------------------------------------------------------------------------
12712
  set_tx_bd
12713
    (tx_bd_num_start[6:0], tx_bd_num_end[6:0], len[15:0], irq, pad, crc, txpnt[31:0]);
12714
  set_tx_bd_wrap
12715
    (tx_bd_num_end[6:0]);
12716
  set_tx_bd_ready
12717
    (tx_bd_num_start[6:0], tx_bd_num_end[6:0]);
12718
  check_tx_bd
12719
    (tx_bd_num_start[6:0], tx_bd_status[31:0]);
12720
  clear_tx_bd
12721
    (tx_bd_num_start[6:0], tx_bd_num_end[6:0]);
12722
 
12723
  TASKS for set and control RX buffer descriptors:
12724
  ------------------------------------------------
12725
  set_rx_bd
12726
    (rx_bd_num_strat[6:0], rx_bd_num_end[6:0], irq, rxpnt[31:0]);
12727
  set_rx_bd_wrap
12728
    (rx_bd_num_end[6:0]);
12729
  set_rx_bd_empty
12730
    (rx_bd_num_strat[6:0], rx_bd_num_end[6:0]);
12731
  check_rx_bd
12732
    (rx_bd_num_end[6:0], rx_bd_status);
12733
  clear_rx_bd
12734
    (rx_bd_num_strat[6:0], rx_bd_num_end[6:0]);
12735
 
12736
  TASKS for set and check TX packets:
12737
  -----------------------------------
12738
  set_tx_packet
12739
    (txpnt[31:0], len[15:0], eth_start_data[7:0]);
12740
  check_tx_packet
12741
    (txpnt_wb[31:0], txpnt_phy[31:0], len[15:0], failure[31:0]);
12742
 
12743
  TASKS for set and check RX packets:
12744
  -----------------------------------
12745
  set_rx_packet
12746
    (rxpnt[31:0], len[15:0], plus_nibble, d_addr[47:0], s_addr[47:0], type_len[15:0], start_data[7:0]);
12747
  check_rx_packet
12748
    (rxpnt_phy[31:0], rxpnt_wb[31:0], len[15:0], plus_nibble, successful_nibble, failure[31:0]);
12749
 
12750
  TASKS for append and check CRC to/of TX packet:
12751
  -----------------------------------------------
12752
  append_tx_crc
12753
    (txpnt_wb[31:0], len[15:0], negated_crc);
12754
  check_tx_crc
12755
    (txpnt_phy[31:0], len[15:0], negated_crc, failure[31:0]);
12756
 
12757
  TASK for append CRC to RX packet (CRC is checked together with check_rx_packet):
12758
  --------------------------------------------------------------------------------
12759
  append_rx_crc
12760
    (rxpnt_phy[31:0], len[15:0], plus_nibble, negated_crc);
12761
  */
12762
 
12763
//////////////////////////////////////////////////////////////////////
12764
////                                                              ////
12765
////  test_mac_full_duplex_flow:                                  ////
12766
////                                                              ////
12767
////  0: Test                                                     ////
12768
////                                                              ////
12769
//////////////////////////////////////////////////////////////////////
12770
for (test_num = start_task; test_num <= end_task; test_num = test_num + 1)
12771
begin
12772
 
12773
  ////////////////////////////////////////////////////////////////////
12774
  ////                                                            ////
12775
  ////  Test                                                      ////
12776
  ////                                                            ////
12777
  ////////////////////////////////////////////////////////////////////
12778
  if (test_num == 0) // Test 
12779
  begin
12780
    // TEST 0: 
12781
    test_name   = "TEST 0: ";
12782
    `TIME; $display("  TEST 0: ");
12783
 
12784
 
12785
  end
12786
 
12787
 
12788
 
12789
end   //  for (test_num=start_task; test_num <= end_task; test_num=test_num+1)
12790
 
12791
end
12792
endtask // test_mac_full_duplex_flow
12793
 
12794
 
12795 169 mohor
//////////////////////////////////////////////////////////////
12796
// WB Behavioral Models Basic tasks
12797
//////////////////////////////////////////////////////////////
12798
 
12799
task wbm_write;
12800
  input  [31:0] address_i;
12801
  input  [((`MAX_BLK_SIZE * 32) - 1):0] data_i;
12802
  input  [3:0]  sel_i;
12803
  input  [31:0] size_i;
12804
  input  [3:0]  init_waits_i;
12805
  input  [3:0]  subseq_waits_i;
12806
 
12807
  reg `WRITE_STIM_TYPE write_data;
12808
  reg `WB_TRANSFER_FLAGS flags;
12809
  reg `WRITE_RETURN_TYPE write_status;
12810
  integer i;
12811
begin
12812
  write_status = 0;
12813
 
12814
  flags                    = 0;
12815
  flags`WB_TRANSFER_SIZE   = size_i;
12816
  flags`INIT_WAITS         = init_waits_i;
12817
  flags`SUBSEQ_WAITS       = subseq_waits_i;
12818
 
12819
  write_data               = 0;
12820
  write_data`WRITE_DATA    = data_i[31:0];
12821
  write_data`WRITE_ADDRESS = address_i;
12822
  write_data`WRITE_SEL     = sel_i;
12823
 
12824
  for (i = 0; i < size_i; i = i + 1)
12825
  begin
12826
    wb_master.blk_write_data[i] = write_data;
12827
    data_i                      = data_i >> 32;
12828
    write_data`WRITE_DATA       = data_i[31:0];
12829
    write_data`WRITE_ADDRESS    = write_data`WRITE_ADDRESS + 4;
12830 116 mohor
  end
12831
 
12832 169 mohor
  wb_master.wb_block_write(flags, write_status);
12833 116 mohor
 
12834 169 mohor
  if (write_status`CYC_ACTUAL_TRANSFER !== size_i)
12835
  begin
12836
    `TIME;
12837
    $display("*E WISHBONE Master was unable to complete the requested write operation to MAC!");
12838
  end
12839
end
12840
endtask // wbm_write
12841 116 mohor
 
12842 169 mohor
task wbm_read;
12843
  input  [31:0] address_i;
12844
  output [((`MAX_BLK_SIZE * 32) - 1):0] data_o;
12845
  input  [3:0]  sel_i;
12846
  input  [31:0] size_i;
12847
  input  [3:0]  init_waits_i;
12848
  input  [3:0]  subseq_waits_i;
12849
 
12850
  reg `READ_RETURN_TYPE read_data;
12851
  reg `WB_TRANSFER_FLAGS flags;
12852
  reg `READ_RETURN_TYPE read_status;
12853
  integer i;
12854
begin
12855
  read_status = 0;
12856
  data_o      = 0;
12857
 
12858
  flags                  = 0;
12859
  flags`WB_TRANSFER_SIZE = size_i;
12860
  flags`INIT_WAITS       = init_waits_i;
12861
  flags`SUBSEQ_WAITS     = subseq_waits_i;
12862
 
12863
  read_data              = 0;
12864
  read_data`READ_ADDRESS = address_i;
12865
  read_data`READ_SEL     = sel_i;
12866
 
12867
  for (i = 0; i < size_i; i = i + 1)
12868 116 mohor
  begin
12869 169 mohor
    wb_master.blk_read_data_in[i] = read_data;
12870
    read_data`READ_ADDRESS        = read_data`READ_ADDRESS + 4;
12871
  end
12872
 
12873
  wb_master.wb_block_read(flags, read_status);
12874
 
12875
  if (read_status`CYC_ACTUAL_TRANSFER !== size_i)
12876
  begin
12877
    `TIME;
12878
    $display("*E WISHBONE Master was unable to complete the requested read operation from MAC!");
12879
  end
12880
 
12881
  for (i = 0; i < size_i; i = i + 1)
12882
  begin
12883
    data_o       = data_o << 32;
12884
    read_data    = wb_master.blk_read_data_out[(size_i - 1) - i]; // [31 - i];
12885
    data_o[31:0] = read_data`READ_DATA;
12886
  end
12887
end
12888
endtask // wbm_read
12889
 
12890
 
12891
//////////////////////////////////////////////////////////////
12892
// Ethernet Basic tasks
12893
//////////////////////////////////////////////////////////////
12894
 
12895
task hard_reset; //  MAC registers
12896
begin
12897
  // reset MAC registers
12898
  @(posedge wb_clk);
12899
  #2 wb_rst = 1'b1;
12900
  repeat(2) @(posedge wb_clk);
12901
  #2 wb_rst = 1'b0;
12902
end
12903
endtask // hard_reset
12904
 
12905
task reset_mac; //  MAC module
12906
  reg [31:0] tmp;
12907
  reg [31:0] tmp_no_rst;
12908
begin
12909
  // read MODER register first
12910
  wbm_read(`ETH_MODER, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12911
  // set reset bit - write back to MODER register with RESET bit
12912
  wbm_write(`ETH_MODER, (`ETH_MODER_RST | tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12913
  // clear reset bit - write back to MODER register without RESET bit
12914
  tmp_no_rst = `ETH_MODER_RST;
12915
  tmp_no_rst = ~tmp_no_rst;
12916
  wbm_write(`ETH_MODER, (tmp_no_rst & tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12917
end
12918
endtask // reset_mac
12919
 
12920
task set_tx_bd;
12921
  input  [6:0]  tx_bd_num_start;
12922
  input  [6:0]  tx_bd_num_end;
12923
  input  [15:0] len;
12924
  input         irq;
12925
  input         pad;
12926
  input         crc;
12927
  input  [31:0] txpnt;
12928
 
12929
  integer       i;
12930
  integer       bd_status_addr, bd_ptr_addr;
12931
//  integer       buf_addr;
12932
begin
12933
  for(i = tx_bd_num_start; i <= tx_bd_num_end; i = i + 1)
12934
  begin
12935
//    buf_addr = `TX_BUF_BASE + i * 32'h600;
12936
    bd_status_addr = `TX_BD_BASE + i * 8;
12937
    bd_ptr_addr = bd_status_addr + 4;
12938
    // initialize BD - status
12939
//    wbm_write(bd_status_addr, 32'h00005800, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // IRQ + PAD + CRC
12940
    wbm_write(bd_status_addr, {len, 1'b0, irq, 1'b0, pad, crc, 11'h0},
12941
              4'hF, 1, wbm_init_waits, wbm_subseq_waits); // IRQ + PAD + CRC
12942
    // initialize BD - pointer
12943
//    wbm_write(bd_ptr_addr, buf_addr, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Initializing BD-pointer
12944
    wbm_write(bd_ptr_addr, txpnt, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Initializing BD-pointer
12945
  end
12946
end
12947
endtask // set_tx_bd
12948
 
12949
task set_tx_bd_wrap;
12950
  input  [6:0]  tx_bd_num_end;
12951
  integer       bd_status_addr, tmp;
12952
begin
12953
  bd_status_addr = `TX_BD_BASE + tx_bd_num_end * 8;
12954
  wbm_read(bd_status_addr, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12955
  // set wrap bit to this BD - this BD should be last-one
12956
  wbm_write(bd_status_addr, (`ETH_TX_BD_WRAP | tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12957
end
12958
endtask // set_tx_bd_wrap
12959
 
12960
task set_tx_bd_ready;
12961
  input  [6:0]  tx_nd_num_strat;
12962
  input  [6:0]  tx_bd_num_end;
12963
  integer       i;
12964
  integer       bd_status_addr, tmp;
12965
begin
12966
  for(i = tx_nd_num_strat; i <= tx_bd_num_end; i = i + 1)
12967
  begin
12968
    bd_status_addr = `TX_BD_BASE + i * 8;
12969
    wbm_read(bd_status_addr, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12970
    // set empty bit to this BD - this BD should be ready
12971
    wbm_write(bd_status_addr, (`ETH_TX_BD_READY | tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12972
  end
12973
end
12974
endtask // set_tx_bd_ready
12975
 
12976
task check_tx_bd;
12977
  input  [6:0]  tx_bd_num_end;
12978
  output [31:0] tx_bd_status;
12979
  integer       bd_status_addr, tmp;
12980
begin
12981
  bd_status_addr = `TX_BD_BASE + tx_bd_num_end * 8;
12982
  wbm_read(bd_status_addr, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
12983
  #1 tx_bd_status = tmp;
12984
  #1;
12985
end
12986
endtask // check_tx_bd
12987
 
12988
task clear_tx_bd;
12989
  input  [6:0]  tx_nd_num_strat;
12990
  input  [6:0]  tx_bd_num_end;
12991
  integer       i;
12992
  integer       bd_status_addr, bd_ptr_addr;
12993
begin
12994
  for(i = tx_nd_num_strat; i <= tx_bd_num_end; i = i + 1)
12995
  begin
12996
    bd_status_addr = `TX_BD_BASE + i * 8;
12997
    bd_ptr_addr = bd_status_addr + 4;
12998
    // clear BD - status
12999
    wbm_write(bd_status_addr, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
13000
    // clear BD - pointer
13001
    wbm_write(bd_ptr_addr, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
13002
  end
13003
end
13004
endtask // clear_tx_bd
13005
 
13006
task set_rx_bd;
13007
  input  [6:0]  rx_bd_num_strat;
13008
  input  [6:0]  rx_bd_num_end;
13009
  input         irq;
13010
  input  [31:0] rxpnt;
13011
//  input  [6:0]  rxbd_num;
13012
  integer       i;
13013
  integer       bd_status_addr, bd_ptr_addr;
13014
//  integer       buf_addr;
13015
begin
13016
  for(i = rx_bd_num_strat; i <= rx_bd_num_end; i = i + 1)
13017
  begin
13018
//    buf_addr = `RX_BUF_BASE + i * 32'h600;
13019 209 tadejm
//    bd_status_addr = `RX_BD_BASE + i * 8;
13020
//    bd_ptr_addr = bd_status_addr + 4; 
13021
    bd_status_addr = `TX_BD_BASE + i * 8;
13022
    bd_ptr_addr = bd_status_addr + 4;
13023 116 mohor
 
13024 169 mohor
    // initialize BD - status
13025
//    wbm_write(bd_status_addr, 32'h0000c000, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // IRQ + PAD + CRC
13026
    wbm_write(bd_status_addr, {17'h0, irq, 14'h0},
13027
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
13028
    // initialize BD - pointer
13029
//    wbm_write(bd_ptr_addr, buf_addr, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Initializing BD-pointer
13030
    wbm_write(bd_ptr_addr, rxpnt, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Initializing BD-pointer
13031
  end
13032
end
13033
endtask // set_rx_bd
13034 116 mohor
 
13035 169 mohor
task set_rx_bd_wrap;
13036
  input  [6:0]  rx_bd_num_end;
13037
  integer       bd_status_addr, tmp;
13038
begin
13039 209 tadejm
//  bd_status_addr = `RX_BD_BASE + rx_bd_num_end * 8;
13040
  bd_status_addr = `TX_BD_BASE + rx_bd_num_end * 8;
13041 169 mohor
  wbm_read(bd_status_addr, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
13042
  // set wrap bit to this BD - this BD should be last-one
13043
  wbm_write(bd_status_addr, (`ETH_RX_BD_WRAP | tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
13044
end
13045
endtask // set_rx_bd_wrap
13046 116 mohor
 
13047 169 mohor
task set_rx_bd_empty;
13048
  input  [6:0]  rx_bd_num_strat;
13049
  input  [6:0]  rx_bd_num_end;
13050
  integer       i;
13051
  integer       bd_status_addr, tmp;
13052
begin
13053
  for(i = rx_bd_num_strat; i <= rx_bd_num_end; i = i + 1)
13054
  begin
13055 209 tadejm
//    bd_status_addr = `RX_BD_BASE + i * 8;
13056
    bd_status_addr = `TX_BD_BASE + i * 8;
13057 169 mohor
    wbm_read(bd_status_addr, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
13058
    // set empty bit to this BD - this BD should be ready
13059
    wbm_write(bd_status_addr, (`ETH_RX_BD_EMPTY | tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
13060 116 mohor
  end
13061 169 mohor
end
13062
endtask // set_rx_bd_empty
13063 116 mohor
 
13064 169 mohor
task check_rx_bd;
13065
  input  [6:0]  rx_bd_num_end;
13066
  output [31:0] rx_bd_status;
13067
  integer       bd_status_addr, tmp;
13068
begin
13069 209 tadejm
//  bd_status_addr = `RX_BD_BASE + rx_bd_num_end * 8;
13070
  bd_status_addr = `TX_BD_BASE + rx_bd_num_end * 8;
13071 169 mohor
  wbm_read(bd_status_addr, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
13072
  #1 rx_bd_status = tmp;
13073
  #1;
13074
end
13075
endtask // check_rx_bd
13076 116 mohor
 
13077 169 mohor
task clear_rx_bd;
13078
  input  [6:0]  rx_bd_num_strat;
13079
  input  [6:0]  rx_bd_num_end;
13080
  integer       i;
13081
  integer       bd_status_addr, bd_ptr_addr;
13082
begin
13083
  for(i = rx_bd_num_strat; i <= rx_bd_num_end; i = i + 1)
13084
  begin
13085 209 tadejm
//    bd_status_addr = `RX_BD_BASE + i * 8;
13086
    bd_status_addr = `TX_BD_BASE + i * 8;
13087 169 mohor
    bd_ptr_addr = bd_status_addr + 4;
13088
    // clear BD - status
13089
    wbm_write(bd_status_addr, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
13090
    // clear BD - pointer
13091
    wbm_write(bd_ptr_addr, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
13092
  end
13093
end
13094
endtask // clear_rx_bd
13095 116 mohor
 
13096 169 mohor
task set_tx_packet;
13097
  input  [31:0] txpnt;
13098
  input  [15:0] len;
13099
  input  [7:0]  eth_start_data;
13100
  integer       i, sd;
13101
  integer       buffer;
13102
  reg           delta_t;
13103
begin
13104
  buffer = txpnt;
13105
  sd = eth_start_data;
13106
  delta_t = 0;
13107 116 mohor
 
13108 169 mohor
  // First write might not be word allign.
13109
  if(buffer[1:0] == 1)
13110
  begin
13111
    wb_slave.wr_mem(buffer - 1, {8'h0, sd[7:0], sd[7:0] + 3'h1, sd[7:0] + 3'h2}, 4'h7);
13112
    sd = sd + 3;
13113
    i = 3;
13114
  end
13115
  else if(buffer[1:0] == 2)
13116
  begin
13117
    wb_slave.wr_mem(buffer - 2, {16'h0, sd[7:0], sd[7:0] + 3'h1}, 4'h3);
13118
    sd = sd + 2;
13119
    i = 2;
13120
  end
13121
  else if(buffer[1:0] == 3)
13122
  begin
13123
    wb_slave.wr_mem(buffer - 3, {24'h0, sd[7:0]}, 4'h1);
13124
    sd = sd + 1;
13125
    i = 1;
13126
  end
13127
  else
13128
    i = 0;
13129
  delta_t = !delta_t;
13130 116 mohor
 
13131 169 mohor
  for(i = i; i < (len - 4); i = i + 4) // Last 0-3 bytes are not written
13132
  begin
13133
    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);
13134
    sd = sd + 4;
13135
  end
13136
  delta_t = !delta_t;
13137
 
13138
  // Last word
13139
  if((len - i) == 3)
13140 116 mohor
  begin
13141 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);
13142
  end
13143
  else if((len - i) == 2)
13144
  begin
13145
    wb_slave.wr_mem(buffer + i, {sd[7:0], sd[7:0] + 3'h1, 16'h0}, 4'hC);
13146
  end
13147
  else if((len - i) == 1)
13148
  begin
13149
    wb_slave.wr_mem(buffer + i, {sd[7:0], 24'h0}, 4'h8);
13150
  end
13151
  else if((len - i) == 4)
13152
  begin
13153
    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);
13154
  end
13155
  else
13156
    $display("(%0t)(%m) ERROR", $time);
13157
  delta_t = !delta_t;
13158
end
13159
endtask // set_tx_packet
13160
 
13161
task check_tx_packet;
13162
  input  [31:0] txpnt_wb;  // source
13163
  input  [31:0] txpnt_phy; // destination
13164
  input  [15:0] len;
13165
  output [31:0] failure;
13166
  integer       i, data_wb, data_phy;
13167
  reg    [31:0] addr_wb, addr_phy;
13168
  reg    [31:0] failure;
13169
  reg           delta_t;
13170
begin
13171
  addr_wb = txpnt_wb;
13172
  addr_phy = txpnt_phy;
13173
  delta_t = 0;
13174
  failure = 0;
13175 209 tadejm
  #1;
13176 169 mohor
  // First write might not be word allign.
13177
  if(addr_wb[1:0] == 1)
13178
  begin
13179
    wb_slave.rd_mem(addr_wb - 1, data_wb, 4'h7);
13180
    data_phy[31:24] = 0;
13181
    data_phy[23:16] = eth_phy.tx_mem[addr_phy[21:0]];
13182
    data_phy[15: 8] = eth_phy.tx_mem[addr_phy[21:0] + 1];
13183
    data_phy[ 7: 0] = eth_phy.tx_mem[addr_phy[21:0] + 2];
13184
    i = 3;
13185
    if (data_phy[23:0] !== data_wb[23:0])
13186
    begin
13187
      `TIME;
13188 209 tadejm
      $display("*E Wrong 1. word (3 bytes) of TX packet! phy: %0h, wb: %0h", data_phy[23:0], data_wb[23:0]);
13189
      $display("     address phy: %0h, address wb: %0h", addr_phy, addr_wb);
13190 169 mohor
      failure = 1;
13191
    end
13192
  end
13193
  else if (addr_wb[1:0] == 2)
13194
  begin
13195
    wb_slave.rd_mem(addr_wb - 2, data_wb, 4'h3);
13196
    data_phy[31:16] = 0;
13197
    data_phy[15: 8] = eth_phy.tx_mem[addr_phy[21:0]];
13198
    data_phy[ 7: 0] = eth_phy.tx_mem[addr_phy[21:0] + 1];
13199
    i = 2;
13200
    if (data_phy[15:0] !== data_wb[15:0])
13201
    begin
13202
      `TIME;
13203 209 tadejm
      $display("*E Wrong 1. word (2 bytes) of TX packet! phy: %0h, wb: %0h", data_phy[15:0], data_wb[15:0]);
13204
      $display("     address phy: %0h, address wb: %0h", addr_phy, addr_wb);
13205 169 mohor
      failure = 1;
13206
    end
13207
  end
13208
  else if (addr_wb[1:0] == 3)
13209
  begin
13210
    wb_slave.rd_mem(addr_wb - 3, data_wb, 4'h1);
13211
    data_phy[31: 8] = 0;
13212
    data_phy[ 7: 0] = eth_phy.tx_mem[addr_phy[21:0]];
13213
    i = 1;
13214
    if (data_phy[7:0] !== data_wb[7:0])
13215
    begin
13216
      `TIME;
13217 209 tadejm
      $display("*E Wrong 1. word (1 byte) of TX packet! phy: %0h, wb: %0h", data_phy[7:0], data_wb[7:0]);
13218
      $display("     address phy: %0h, address wb: %0h", addr_phy, addr_wb);
13219 169 mohor
      failure = 1;
13220
    end
13221
  end
13222
  else
13223
    i = 0;
13224
  delta_t = !delta_t;
13225 209 tadejm
  #1;
13226 169 mohor
  for(i = i; i < (len - 4); i = i + 4) // Last 0-3 bytes are not checked
13227
  begin
13228
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hF);
13229
    data_phy[31:24] = eth_phy.tx_mem[addr_phy[21:0] + i];
13230
    data_phy[23:16] = eth_phy.tx_mem[addr_phy[21:0] + i + 1];
13231
    data_phy[15: 8] = eth_phy.tx_mem[addr_phy[21:0] + i + 2];
13232
    data_phy[ 7: 0] = eth_phy.tx_mem[addr_phy[21:0] + i + 3];
13233
    if (data_phy[31:0] !== data_wb[31:0])
13234
    begin
13235
      `TIME;
13236 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]);
13237
      $display("     address phy: %0h, address wb: %0h", addr_phy, addr_wb);
13238 169 mohor
      failure = failure + 1;
13239
    end
13240
  end
13241
  delta_t = !delta_t;
13242 209 tadejm
  #1;
13243 169 mohor
  // Last word
13244
  if((len - i) == 3)
13245
  begin
13246
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hE);
13247
    data_phy[31:24] = eth_phy.tx_mem[addr_phy[21:0] + i];
13248
    data_phy[23:16] = eth_phy.tx_mem[addr_phy[21:0] + i + 1];
13249
    data_phy[15: 8] = eth_phy.tx_mem[addr_phy[21:0] + i + 2];
13250
    data_phy[ 7: 0] = 0;
13251
    if (data_phy[31:8] !== data_wb[31:8])
13252
    begin
13253
      `TIME;
13254 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]);
13255
      $display("     address phy: %0h, address wb: %0h", addr_phy, addr_wb);
13256 169 mohor
      failure = failure + 1;
13257
    end
13258
  end
13259
  else if((len - i) == 2)
13260
  begin
13261
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hC);
13262
    data_phy[31:24] = eth_phy.tx_mem[addr_phy[21:0] + i];
13263
    data_phy[23:16] = eth_phy.tx_mem[addr_phy[21:0] + i + 1];
13264
    data_phy[15: 8] = 0;
13265
    data_phy[ 7: 0] = 0;
13266
    if (data_phy[31:16] !== data_wb[31:16])
13267
    begin
13268
      `TIME;
13269 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]);
13270
      $display("     address phy: %0h, address wb: %0h", addr_phy, addr_wb);
13271 169 mohor
      failure = failure + 1;
13272
    end
13273
  end
13274
  else if((len - i) == 1)
13275
  begin
13276
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'h8);
13277
    data_phy[31:24] = eth_phy.tx_mem[addr_phy[21:0] + i];
13278
    data_phy[23:16] = 0;
13279
    data_phy[15: 8] = 0;
13280
    data_phy[ 7: 0] = 0;
13281
    if (data_phy[31:24] !== data_wb[31:24])
13282
    begin
13283
      `TIME;
13284 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]);
13285
      $display("     address phy: %0h, address wb: %0h", addr_phy, addr_wb);
13286 169 mohor
      failure = failure + 1;
13287
    end
13288
  end
13289
  else if((len - i) == 4)
13290
  begin
13291
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hF);
13292
    data_phy[31:24] = eth_phy.tx_mem[addr_phy[21:0] + i];
13293
    data_phy[23:16] = eth_phy.tx_mem[addr_phy[21:0] + i + 1];
13294
    data_phy[15: 8] = eth_phy.tx_mem[addr_phy[21:0] + i + 2];
13295
    data_phy[ 7: 0] = eth_phy.tx_mem[addr_phy[21:0] + i + 3];
13296
    if (data_phy[31:0] !== data_wb[31:0])
13297
    begin
13298
      `TIME;
13299 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]);
13300
      $display("     address phy: %0h, address wb: %0h", addr_phy, addr_wb);
13301 169 mohor
      failure = failure + 1;
13302
    end
13303
  end
13304
  else
13305
    $display("(%0t)(%m) ERROR", $time);
13306
  delta_t = !delta_t;
13307
end
13308
endtask // check_tx_packet
13309
 
13310
task set_rx_packet;
13311
  input  [31:0] rxpnt;
13312
  input  [15:0] len;
13313
  input         plus_dribble_nibble; // if length is longer for one nibble
13314
  input  [47:0] eth_dest_addr;
13315
  input  [47:0] eth_source_addr;
13316
  input  [15:0] eth_type_len;
13317
  input  [7:0]  eth_start_data;
13318
  integer       i, sd;
13319
  reg    [47:0] dest_addr;
13320
  reg    [47:0] source_addr;
13321
  reg    [15:0] type_len;
13322
  reg    [21:0] buffer;
13323
  reg           delta_t;
13324
begin
13325
  buffer = rxpnt[21:0];
13326
  dest_addr = eth_dest_addr;
13327
  source_addr = eth_source_addr;
13328
  type_len = eth_type_len;
13329
  sd = eth_start_data;
13330
  delta_t = 0;
13331
  for(i = 0; i < len; i = i + 1)
13332
  begin
13333
    if (i < 6)
13334
    begin
13335
      eth_phy.rx_mem[buffer] = dest_addr[47:40];
13336
      dest_addr = dest_addr << 8;
13337
    end
13338
    else if (i < 12)
13339
    begin
13340
      eth_phy.rx_mem[buffer] = source_addr[47:40];
13341
      source_addr = source_addr << 8;
13342
    end
13343
    else if (i < 14)
13344
    begin
13345
      eth_phy.rx_mem[buffer] = type_len[15:8];
13346
      type_len = type_len << 8;
13347
    end
13348
    else
13349
    begin
13350
      eth_phy.rx_mem[buffer] = sd[7:0];
13351
      sd = sd + 1;
13352
    end
13353
    buffer = buffer + 1;
13354
  end
13355
  delta_t = !delta_t;
13356
  if (plus_dribble_nibble)
13357
    eth_phy.rx_mem[buffer] = {4'h0, 4'hD /*sd[3:0]*/};
13358
  delta_t = !delta_t;
13359
end
13360
endtask // set_rx_packet
13361
 
13362
task check_rx_packet;
13363
  input  [31:0] rxpnt_phy; // source
13364
  input  [31:0] rxpnt_wb;  // destination
13365
  input  [15:0] len;
13366
  input         plus_dribble_nibble; // if length is longer for one nibble
13367
  input         successful_dribble_nibble; // if additional nibble is stored into memory
13368
  output [31:0] failure;
13369
  integer       i, data_wb, data_phy;
13370
  reg    [31:0] addr_wb, addr_phy;
13371
  reg    [31:0] failure;
13372
  reg    [21:0] buffer;
13373
  reg           delta_t;
13374
begin
13375
  addr_phy = rxpnt_phy;
13376
  addr_wb = rxpnt_wb;
13377
  delta_t = 0;
13378
  failure = 0;
13379
 
13380
  // First write might not be word allign.
13381
  if(addr_wb[1:0] == 1)
13382
  begin
13383
    wb_slave.rd_mem(addr_wb - 1, data_wb, 4'h7);
13384
    data_phy[31:24] = 0;
13385
    data_phy[23:16] = eth_phy.rx_mem[addr_phy[21:0]];
13386
    data_phy[15: 8] = eth_phy.rx_mem[addr_phy[21:0] + 1];
13387
    data_phy[ 7: 0] = eth_phy.rx_mem[addr_phy[21:0] + 2];
13388
    i = 3;
13389
    if (data_phy[23:0] !== data_wb[23:0])
13390
    begin
13391
      `TIME;
13392
      $display("*E Wrong 1. word (3 bytes) of TX packet!");
13393
      failure = 1;
13394
    end
13395
  end
13396
  else if (addr_wb[1:0] == 2)
13397
  begin
13398
    wb_slave.rd_mem(addr_wb - 2, data_wb, 4'h3);
13399
    data_phy[31:16] = 0;
13400
    data_phy[15: 8] = eth_phy.rx_mem[addr_phy[21:0]];
13401
    data_phy[ 7: 0] = eth_phy.rx_mem[addr_phy[21:0] + 1];
13402
    i = 2;
13403
    if (data_phy[15:0] !== data_wb[15:0])
13404
    begin
13405
      `TIME;
13406
      $display("*E Wrong 1. word (2 bytes) of TX packet!");
13407
      failure = 1;
13408
    end
13409
  end
13410
  else if (addr_wb[1:0] == 3)
13411
  begin
13412
    wb_slave.rd_mem(addr_wb - 3, data_wb, 4'h1);
13413
    data_phy[31: 8] = 0;
13414
    data_phy[ 7: 0] = eth_phy.rx_mem[addr_phy[21:0]];
13415
    i = 1;
13416
    if (data_phy[7:0] !== data_wb[7:0])
13417
    begin
13418
      `TIME;
13419
      $display("*E Wrong 1. word (1 byte) of TX packet!");
13420
      failure = 1;
13421
    end
13422
  end
13423
  else
13424
    i = 0;
13425
  delta_t = !delta_t;
13426
 
13427
  for(i = i; i < (len - 4); i = i + 4) // Last 0-3 bytes are not checked
13428
  begin
13429
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hF);
13430
    data_phy[31:24] = eth_phy.rx_mem[addr_phy[21:0] + i];
13431
    data_phy[23:16] = eth_phy.rx_mem[addr_phy[21:0] + i + 1];
13432
    data_phy[15: 8] = eth_phy.rx_mem[addr_phy[21:0] + i + 2];
13433
    data_phy[ 7: 0] = eth_phy.rx_mem[addr_phy[21:0] + i + 3];
13434
    if (data_phy[31:0] !== data_wb[31:0])
13435
    begin
13436
      `TIME;
13437
      $display("*E Wrong %d. word (4 bytes) of TX packet!", ((i/4)+1));
13438
      failure = failure + 1;
13439
    end
13440
  end
13441
  delta_t = !delta_t;
13442
 
13443
  // Last word
13444
  if((len - i) == 3)
13445
  begin
13446
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hF);
13447
    data_phy[31:24] = eth_phy.rx_mem[addr_phy[21:0] + i];
13448
    data_phy[23:16] = eth_phy.rx_mem[addr_phy[21:0] + i + 1];
13449
    data_phy[15: 8] = eth_phy.rx_mem[addr_phy[21:0] + i + 2];
13450
    if (plus_dribble_nibble)
13451
      data_phy[ 7: 0] = eth_phy.rx_mem[addr_phy[21:0] + i + 3];
13452
    else
13453
      data_phy[ 7: 0] = 0;
13454
    if (data_phy[31:8] !== data_wb[31:8])
13455
    begin
13456
      `TIME;
13457
      $display("*E Wrong %d. word (3 bytes) of TX packet!", ((i/4)+1));
13458
      failure = failure + 1;
13459
    end
13460
    if (plus_dribble_nibble && successful_dribble_nibble)
13461
    begin
13462
      if (data_phy[3:0] !== data_wb[3:0])
13463 116 mohor
      begin
13464 169 mohor
        `TIME;
13465
        $display("*E Wrong dribble nibble in %d. word (3 bytes) of TX packet!", ((i/4)+1));
13466
        failure = failure + 1;
13467 116 mohor
      end
13468 169 mohor
    end
13469
    else if (plus_dribble_nibble && !successful_dribble_nibble)
13470
    begin
13471
      if (data_phy[3:0] === data_wb[3:0])
13472 116 mohor
      begin
13473 169 mohor
        `TIME;
13474
        $display("*E Wrong dribble nibble in %d. word (3 bytes) of TX packet!", ((i/4)+1));
13475
        failure = failure + 1;
13476 116 mohor
      end
13477 169 mohor
    end
13478
  end
13479
  else if((len - i) == 2)
13480
  begin
13481
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hE);
13482
    data_phy[31:24] = eth_phy.rx_mem[addr_phy[21:0] + i];
13483
    data_phy[23:16] = eth_phy.rx_mem[addr_phy[21:0] + i + 1];
13484
    if (plus_dribble_nibble)
13485
      data_phy[15: 8] = eth_phy.rx_mem[addr_phy[21:0] + i + 2];
13486
    else
13487
      data_phy[15: 8] = 0;
13488
    data_phy[ 7: 0] = 0;
13489
    if (data_phy[31:16] !== data_wb[31:16])
13490
    begin
13491
      `TIME;
13492
      $display("*E Wrong %d. word (2 bytes) of TX packet!", ((i/4)+1));
13493
      failure = failure + 1;
13494
    end
13495
    if (plus_dribble_nibble && successful_dribble_nibble)
13496
    begin
13497
      if (data_phy[11:8] !== data_wb[11:8])
13498
      begin
13499
        `TIME;
13500
        $display("*E Wrong dribble nibble in %d. word (2 bytes) of TX packet!", ((i/4)+1));
13501
        failure = failure + 1;
13502
      end
13503
    end
13504
    else if (plus_dribble_nibble && !successful_dribble_nibble)
13505
    begin
13506
      if (data_phy[11:8] === data_wb[11:8])
13507
      begin
13508
        `TIME;
13509
        $display("*E Wrong dribble nibble in %d. word (2 bytes) of TX packet!", ((i/4)+1));
13510
        failure = failure + 1;
13511
      end
13512
    end
13513
  end
13514
  else if((len - i) == 1)
13515
  begin
13516
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hC);
13517
    data_phy[31:24] = eth_phy.rx_mem[addr_phy[21:0] + i];
13518
    if (plus_dribble_nibble)
13519
      data_phy[23:16] = eth_phy.rx_mem[addr_phy[21:0] + i + 1];
13520
    else
13521
      data_phy[23:16] = 0;
13522
    data_phy[15: 8] = 0;
13523
    data_phy[ 7: 0] = 0;
13524
    if (data_phy[31:24] !== data_wb[31:24])
13525
    begin
13526
      `TIME;
13527
      $display("*E Wrong %d. word (1 byte) of TX packet!", ((i/4)+1));
13528
      failure = failure + 1;
13529
    end
13530
    if (plus_dribble_nibble && successful_dribble_nibble)
13531
    begin
13532
      if (data_phy[19:16] !== data_wb[19:16])
13533
      begin
13534
        `TIME;
13535
        $display("*E Wrong dribble nibble in %d. word (1 byte) of TX packet!", ((i/4)+1));
13536
        failure = failure + 1;
13537
      end
13538
    end
13539
    else if (plus_dribble_nibble && !successful_dribble_nibble)
13540
    begin
13541
      if (data_phy[19:16] === data_wb[19:16])
13542
      begin
13543
        `TIME;
13544
        $display("*E Wrong dribble nibble in %d. word (1 byte) of TX packet!", ((i/4)+1));
13545
        failure = failure + 1;
13546
      end
13547
    end
13548
  end
13549
  else if((len - i) == 4)
13550
  begin
13551
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hF);
13552
    data_phy[31:24] = eth_phy.rx_mem[addr_phy[21:0] + i];
13553
    data_phy[23:16] = eth_phy.rx_mem[addr_phy[21:0] + i + 1];
13554
    data_phy[15: 8] = eth_phy.rx_mem[addr_phy[21:0] + i + 2];
13555
    data_phy[ 7: 0] = eth_phy.rx_mem[addr_phy[21:0] + i + 3];
13556
    if (data_phy[31:0] !== data_wb[31:0])
13557
    begin
13558
      `TIME;
13559
      $display("*E Wrong %d. word (4 bytes) of TX packet!", ((i/4)+1));
13560
      failure = failure + 1;
13561
    end
13562
    if (plus_dribble_nibble)
13563
    begin
13564
      wb_slave.rd_mem(addr_wb + i + 4, data_wb, 4'h8);
13565
      data_phy[31:24] = eth_phy.rx_mem[addr_phy[21:0] + i + 4];
13566
      if (successful_dribble_nibble)
13567
      begin
13568
        if (data_phy[27:24] !== data_wb[27:24])
13569
        begin
13570
          `TIME;
13571
          $display("*E Wrong dribble nibble in %d. word (0 bytes) of TX packet!", ((i/4)+2));
13572
          failure = failure + 1;
13573
        end
13574
      end
13575
      else
13576
      begin
13577
        if (data_phy[27:24] === data_wb[27:24])
13578
        begin
13579
          `TIME;
13580
          $display("*E Wrong dribble nibble in %d. word (0 bytes) of TX packet!", ((i/4)+2));
13581
          failure = failure + 1;
13582
        end
13583
      end
13584
    end
13585
  end
13586
  else
13587
    $display("(%0t)(%m) ERROR", $time);
13588
  delta_t = !delta_t;
13589
end
13590
endtask // check_rx_packet
13591 116 mohor
 
13592 169 mohor
//////////////////////////////////////////////////////////////
13593
// Ethernet CRC Basic tasks
13594
//////////////////////////////////////////////////////////////
13595
 
13596
task append_tx_crc;
13597
  input  [31:0] txpnt_wb;  // source
13598
  input  [15:0] len; // length in bytes without CRC
13599
  input         negated_crc; // if appended CRC is correct or not
13600
  reg    [31:0] crc;
13601
  reg    [31:0] addr_wb;
13602
  reg           delta_t;
13603
begin
13604
  addr_wb = txpnt_wb + len;
13605
  delta_t = 0;
13606
  // calculate CRC from prepared packet
13607
  paralel_crc_mac(txpnt_wb, {16'h0, len}, 1'b0, crc);
13608
  if (negated_crc)
13609
    crc = ~crc;
13610
  delta_t = !delta_t;
13611
 
13612
  // Write might not be word allign.
13613
  if (addr_wb[1:0] == 1)
13614
  begin
13615
    wb_slave.wr_mem(addr_wb - 1, {8'h0, crc[7:0], crc[15:8], crc[23:16]}, 4'h7);
13616
    wb_slave.wr_mem(addr_wb + 3, {crc[31:24], 24'h0}, 4'h8);
13617 116 mohor
  end
13618 169 mohor
  else if (addr_wb[1:0] == 2)
13619
  begin
13620
    wb_slave.wr_mem(addr_wb - 2, {16'h0, crc[7:0], crc[15:8]}, 4'h3);
13621
    wb_slave.wr_mem(addr_wb + 2, {crc[23:16], crc[31:24], 16'h0}, 4'hC);
13622
  end
13623
  else if (addr_wb[1:0] == 3)
13624
  begin
13625
    wb_slave.wr_mem(addr_wb - 3, {24'h0, crc[7:0]}, 4'h1);
13626
    wb_slave.wr_mem(addr_wb + 1, {crc[15:8], crc[23:16], crc[31:24], 8'h0}, 4'hE);
13627
  end
13628
  else
13629
  begin
13630
    wb_slave.wr_mem(addr_wb, {crc[7:0], crc[15:8], crc[23:16], crc[31:24]}, 4'hF);
13631
  end
13632
  delta_t = !delta_t;
13633
end
13634
endtask // append_tx_crc
13635 116 mohor
 
13636 169 mohor
task check_tx_crc; // used to check crc added to TX packets by MAC
13637
  input  [31:0] txpnt_phy; // destination
13638
  input  [15:0] len; // length in bytes without CRC
13639
  input         negated_crc; // if appended CRC is correct or not
13640
  output [31:0] failure;
13641
  reg    [31:0] failure;
13642
  reg    [31:0] crc_calc;
13643
  reg    [31:0] crc;
13644
  reg    [31:0] addr_phy;
13645
  reg           delta_t;
13646
begin
13647
  addr_phy = txpnt_phy;
13648
  failure = 0;
13649
  // calculate CRC from sent packet
13650
//  serial_crc_phy_tx(addr_phy, {16'h0, len}, 1'b0, crc_calc);
13651
//#10;
13652
  paralel_crc_phy_tx(addr_phy, {16'h0, len}, 1'b0, crc_calc);
13653 209 tadejm
  #1;
13654 169 mohor
  addr_phy = addr_phy + len;
13655
  // Read CRC - BIG endian
13656
  crc[31:24] = eth_phy.tx_mem[addr_phy[21:0]];
13657
  crc[23:16] = eth_phy.tx_mem[addr_phy[21:0] + 1];
13658
  crc[15: 8] = eth_phy.tx_mem[addr_phy[21:0] + 2];
13659
  crc[ 7: 0] = eth_phy.tx_mem[addr_phy[21:0] + 3];
13660
 
13661
  delta_t = !delta_t;
13662
  if (negated_crc)
13663
  begin
13664
    if ((~crc_calc) !== crc)
13665
    begin
13666
      `TIME;
13667
      $display("*E Negated CRC was not successfuly transmitted!");
13668
      failure = failure + 1;
13669
    end
13670
  end
13671
  else
13672
  begin
13673
    if (crc_calc !== crc)
13674
    begin
13675
      `TIME;
13676 209 tadejm
      $display("*E Transmitted CRC was not correct; crc_calc: %0h, crc_mem: %0h", crc_calc, crc);
13677 169 mohor
      failure = failure + 1;
13678
    end
13679
  end
13680
  delta_t = !delta_t;
13681
end
13682
endtask // check_tx_crc
13683
 
13684
task append_rx_crc;
13685
  input  [31:0] rxpnt_phy; // source
13686
  input  [15:0] len; // length in bytes without CRC
13687
  input         plus_dribble_nibble; // if length is longer for one nibble
13688
  input         negated_crc; // if appended CRC is correct or not
13689
  reg    [31:0] crc;
13690
  reg    [7:0]  tmp;
13691
  reg    [31:0] addr_phy;
13692
  reg           delta_t;
13693
begin
13694
  addr_phy = rxpnt_phy + len;
13695
  delta_t = 0;
13696
  // calculate CRC from prepared packet
13697
  paralel_crc_phy_rx(rxpnt_phy, {16'h0, len}, plus_dribble_nibble, crc);
13698
  if (negated_crc)
13699
    crc = ~crc;
13700
  delta_t = !delta_t;
13701
 
13702
  if (plus_dribble_nibble)
13703
  begin
13704
    tmp = eth_phy.rx_mem[addr_phy];
13705 209 tadejm
    eth_phy.rx_mem[addr_phy]     = {crc[27:24], tmp[3:0]};
13706
    eth_phy.rx_mem[addr_phy + 1] = {crc[19:16], crc[31:28]};
13707
    eth_phy.rx_mem[addr_phy + 2] = {crc[11:8], crc[23:20]};
13708
    eth_phy.rx_mem[addr_phy + 3] = {crc[3:0], crc[15:12]};
13709
    eth_phy.rx_mem[addr_phy + 4] = {4'h0, crc[7:4]};
13710 169 mohor
  end
13711
  else
13712
  begin
13713 209 tadejm
    eth_phy.rx_mem[addr_phy]     = crc[31:24];
13714
    eth_phy.rx_mem[addr_phy + 1] = crc[23:16];
13715
    eth_phy.rx_mem[addr_phy + 2] = crc[15:8];
13716
    eth_phy.rx_mem[addr_phy + 3] = crc[7:0];
13717 169 mohor
  end
13718
end
13719
endtask // append_rx_crc
13720
 
13721
// paralel CRC checking for PHY TX
13722
task paralel_crc_phy_tx;
13723
  input  [31:0] start_addr; // start address
13724
  input  [31:0] len; // length of frame in Bytes without CRC length
13725
  input         plus_dribble_nibble; // if length is longer for one nibble
13726
  output [31:0] crc_out;
13727
  reg    [21:0] addr_cnt; // only 22 address lines
13728
  integer       word_cnt;
13729
  integer       nibble_cnt;
13730
  reg    [31:0] load_reg;
13731
  reg           delta_t;
13732
  reg    [31:0] crc_next;
13733
  reg    [31:0] crc;
13734
  reg           crc_error;
13735
  reg     [3:0] data_in;
13736
  integer       i;
13737
begin
13738
  #1 addr_cnt = start_addr[21:0];
13739
  word_cnt = 24; // 27; // start of the frame - nibble granularity (MSbit first)
13740
  crc = 32'hFFFF_FFFF; // INITIAL value
13741
  delta_t = 0;
13742
  // length must include 4 bytes of ZEROs, to generate CRC
13743
  // get number of nibbles from Byte length (2^1 = 2)
13744
  if (plus_dribble_nibble)
13745
    nibble_cnt = ((len + 4) << 1) + 1'b1; // one nibble longer
13746
  else
13747
    nibble_cnt = ((len + 4) << 1);
13748
  // because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3]
13749
  load_reg[31:24] = eth_phy.tx_mem[addr_cnt];
13750
  addr_cnt = addr_cnt + 1;
13751
  load_reg[23:16] = eth_phy.tx_mem[addr_cnt];
13752
  addr_cnt = addr_cnt + 1;
13753
  load_reg[15: 8] = eth_phy.tx_mem[addr_cnt];
13754
  addr_cnt = addr_cnt + 1;
13755
  load_reg[ 7: 0] = eth_phy.tx_mem[addr_cnt];
13756
  addr_cnt = addr_cnt + 1;
13757
  while (nibble_cnt > 0)
13758
  begin
13759
    // wait for delta time
13760
    delta_t = !delta_t;
13761
    // shift data in
13762
 
13763
    if(nibble_cnt <= 8) // for additional 8 nibbles shift ZEROs in!
13764
      data_in[3:0] = 4'h0;
13765
    else
13766
 
13767
      data_in[3:0] = {load_reg[word_cnt], load_reg[word_cnt+1], load_reg[word_cnt+2], load_reg[word_cnt+3]};
13768
    crc_next[0]  = (data_in[0] ^ crc[28]);
13769
    crc_next[1]  = (data_in[1] ^ data_in[0] ^ crc[28]    ^ crc[29]);
13770
    crc_next[2]  = (data_in[2] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[30]);
13771
    crc_next[3]  = (data_in[3] ^ data_in[2] ^ data_in[1] ^ crc[29]  ^ crc[30] ^ crc[31]);
13772
    crc_next[4]  = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[0];
13773
    crc_next[5]  = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[1];
13774
    crc_next[6]  = (data_in[2] ^ data_in[1] ^ crc[29]    ^ crc[30]) ^ crc[ 2];
13775
    crc_next[7]  = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[3];
13776
    crc_next[8]  = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[4];
13777
    crc_next[9]  = (data_in[2] ^ data_in[1] ^ crc[29]    ^ crc[30]) ^ crc[5];
13778
    crc_next[10] = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[6];
13779
    crc_next[11] = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[7];
13780
    crc_next[12] = (data_in[2] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[30]) ^ crc[8];
13781
    crc_next[13] = (data_in[3] ^ data_in[2] ^ data_in[1] ^ crc[29]  ^ crc[30] ^ crc[31]) ^ crc[9];
13782
    crc_next[14] = (data_in[3] ^ data_in[2] ^ crc[30]    ^ crc[31]) ^ crc[10];
13783
    crc_next[15] = (data_in[3] ^ crc[31])   ^ crc[11];
13784
    crc_next[16] = (data_in[0] ^ crc[28])   ^ crc[12];
13785
    crc_next[17] = (data_in[1] ^ crc[29])   ^ crc[13];
13786
    crc_next[18] = (data_in[2] ^ crc[30])   ^ crc[14];
13787
    crc_next[19] = (data_in[3] ^ crc[31])   ^ crc[15];
13788
    crc_next[20] =  crc[16];
13789
    crc_next[21] =  crc[17];
13790
    crc_next[22] = (data_in[0] ^ crc[28])   ^ crc[18];
13791
    crc_next[23] = (data_in[1] ^ data_in[0] ^ crc[29]    ^ crc[28]) ^ crc[19];
13792
    crc_next[24] = (data_in[2] ^ data_in[1] ^ crc[30]    ^ crc[29]) ^ crc[20];
13793
    crc_next[25] = (data_in[3] ^ data_in[2] ^ crc[31]    ^ crc[30]) ^ crc[21];
13794
    crc_next[26] = (data_in[3] ^ data_in[0] ^ crc[31]    ^ crc[28]) ^ crc[22];
13795
    crc_next[27] = (data_in[1] ^ crc[29])   ^ crc[23];
13796
    crc_next[28] = (data_in[2] ^ crc[30])   ^ crc[24];
13797
    crc_next[29] = (data_in[3] ^ crc[31])   ^ crc[25];
13798
    crc_next[30] =  crc[26];
13799
    crc_next[31] =  crc[27];
13800
 
13801
    crc = crc_next;
13802
    crc_error = crc[31:0] != 32'hc704dd7b;  // CRC not equal to magic number
13803
    case (nibble_cnt)
13804
    9: crc_out = {!crc[24], !crc[25], !crc[26], !crc[27], !crc[28], !crc[29], !crc[30], !crc[31],
13805
                  !crc[16], !crc[17], !crc[18], !crc[19], !crc[20], !crc[21], !crc[22], !crc[23],
13806
                  !crc[ 8], !crc[ 9], !crc[10], !crc[11], !crc[12], !crc[13], !crc[14], !crc[15],
13807
                  !crc[ 0], !crc[ 1], !crc[ 2], !crc[ 3], !crc[ 4], !crc[ 5], !crc[ 6], !crc[ 7]};
13808
    default: crc_out = crc_out;
13809
    endcase
13810
    // wait for delta time
13811
    delta_t = !delta_t;
13812
    // increment address and load new data
13813
    if ((word_cnt+3) == 7)//4)
13814
    begin
13815
      // because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3]
13816
      load_reg[31:24] = eth_phy.tx_mem[addr_cnt];
13817
      addr_cnt = addr_cnt + 1;
13818
      load_reg[23:16] = eth_phy.tx_mem[addr_cnt];
13819
      addr_cnt = addr_cnt + 1;
13820
      load_reg[15: 8] = eth_phy.tx_mem[addr_cnt];
13821
      addr_cnt = addr_cnt + 1;
13822
      load_reg[ 7: 0] = eth_phy.tx_mem[addr_cnt];
13823
      addr_cnt = addr_cnt + 1;
13824
    end
13825
    // set new load bit position
13826
    if((word_cnt+3) == 31)
13827
      word_cnt = 16;
13828
    else if ((word_cnt+3) == 23)
13829
      word_cnt = 8;
13830
    else if ((word_cnt+3) == 15)
13831
      word_cnt = 0;
13832
    else if ((word_cnt+3) == 7)
13833
      word_cnt = 24;
13834
    else
13835
      word_cnt = word_cnt + 4;// - 4;
13836
    // decrement nibble counter
13837
    nibble_cnt = nibble_cnt - 1;
13838
    // wait for delta time
13839
    delta_t = !delta_t;
13840
  end // while
13841
  #1;
13842
end
13843
endtask // paralel_crc_phy_tx
13844
 
13845
// paralel CRC calculating for PHY RX
13846
task paralel_crc_phy_rx;
13847
  input  [31:0] start_addr; // start address
13848
  input  [31:0] len; // length of frame in Bytes without CRC length
13849
  input         plus_dribble_nibble; // if length is longer for one nibble
13850 209 tadejm
  output [31:0] crc_out;
13851 169 mohor
  reg    [21:0] addr_cnt; // only 22 address lines
13852
  integer       word_cnt;
13853 209 tadejm
  integer       nibble_cnt;
13854 169 mohor
  reg    [31:0] load_reg;
13855
  reg           delta_t;
13856 209 tadejm
  reg    [31:0] crc_next;
13857
  reg    [31:0] crc;
13858
  reg           crc_error;
13859
  reg     [3:0] data_in;
13860
  integer       i;
13861 169 mohor
begin
13862
  #1 addr_cnt = start_addr[21:0];
13863 209 tadejm
  word_cnt = 24; // 27; // start of the frame - nibble granularity (MSbit first)
13864
  crc = 32'hFFFF_FFFF; // INITIAL value
13865 169 mohor
  delta_t = 0;
13866
  // length must include 4 bytes of ZEROs, to generate CRC
13867 209 tadejm
  // get number of nibbles from Byte length (2^1 = 2)
13868 169 mohor
  if (plus_dribble_nibble)
13869 209 tadejm
    nibble_cnt = ((len + 4) << 1) + 1'b1; // one nibble longer
13870 169 mohor
  else
13871 209 tadejm
    nibble_cnt = ((len + 4) << 1);
13872
  // because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3]
13873 169 mohor
  load_reg[31:24] = eth_phy.rx_mem[addr_cnt];
13874
  addr_cnt = addr_cnt + 1;
13875
  load_reg[23:16] = eth_phy.rx_mem[addr_cnt];
13876
  addr_cnt = addr_cnt + 1;
13877 209 tadejm
  load_reg[15: 8] = eth_phy.rx_mem[addr_cnt];
13878 169 mohor
  addr_cnt = addr_cnt + 1;
13879 209 tadejm
  load_reg[ 7: 0] = eth_phy.rx_mem[addr_cnt];
13880
  addr_cnt = addr_cnt + 1;
13881
  while (nibble_cnt > 0)
13882 169 mohor
  begin
13883
    // wait for delta time
13884
    delta_t = !delta_t;
13885
    // shift data in
13886 209 tadejm
 
13887
    if(nibble_cnt <= 8) // for additional 8 nibbles shift ZEROs in!
13888
      data_in[3:0] = 4'h0;
13889 169 mohor
    else
13890 209 tadejm
 
13891
      data_in[3:0] = {load_reg[word_cnt], load_reg[word_cnt+1], load_reg[word_cnt+2], load_reg[word_cnt+3]};
13892
    crc_next[0]  = (data_in[0] ^ crc[28]);
13893
    crc_next[1]  = (data_in[1] ^ data_in[0] ^ crc[28]    ^ crc[29]);
13894
    crc_next[2]  = (data_in[2] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[30]);
13895
    crc_next[3]  = (data_in[3] ^ data_in[2] ^ data_in[1] ^ crc[29]  ^ crc[30] ^ crc[31]);
13896
    crc_next[4]  = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[0];
13897
    crc_next[5]  = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[1];
13898
    crc_next[6]  = (data_in[2] ^ data_in[1] ^ crc[29]    ^ crc[30]) ^ crc[ 2];
13899
    crc_next[7]  = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[3];
13900
    crc_next[8]  = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[4];
13901
    crc_next[9]  = (data_in[2] ^ data_in[1] ^ crc[29]    ^ crc[30]) ^ crc[5];
13902
    crc_next[10] = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[6];
13903
    crc_next[11] = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[7];
13904
    crc_next[12] = (data_in[2] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[30]) ^ crc[8];
13905
    crc_next[13] = (data_in[3] ^ data_in[2] ^ data_in[1] ^ crc[29]  ^ crc[30] ^ crc[31]) ^ crc[9];
13906
    crc_next[14] = (data_in[3] ^ data_in[2] ^ crc[30]    ^ crc[31]) ^ crc[10];
13907
    crc_next[15] = (data_in[3] ^ crc[31])   ^ crc[11];
13908
    crc_next[16] = (data_in[0] ^ crc[28])   ^ crc[12];
13909
    crc_next[17] = (data_in[1] ^ crc[29])   ^ crc[13];
13910
    crc_next[18] = (data_in[2] ^ crc[30])   ^ crc[14];
13911
    crc_next[19] = (data_in[3] ^ crc[31])   ^ crc[15];
13912
    crc_next[20] =  crc[16];
13913
    crc_next[21] =  crc[17];
13914
    crc_next[22] = (data_in[0] ^ crc[28])   ^ crc[18];
13915
    crc_next[23] = (data_in[1] ^ data_in[0] ^ crc[29]    ^ crc[28]) ^ crc[19];
13916
    crc_next[24] = (data_in[2] ^ data_in[1] ^ crc[30]    ^ crc[29]) ^ crc[20];
13917
    crc_next[25] = (data_in[3] ^ data_in[2] ^ crc[31]    ^ crc[30]) ^ crc[21];
13918
    crc_next[26] = (data_in[3] ^ data_in[0] ^ crc[31]    ^ crc[28]) ^ crc[22];
13919
    crc_next[27] = (data_in[1] ^ crc[29])   ^ crc[23];
13920
    crc_next[28] = (data_in[2] ^ crc[30])   ^ crc[24];
13921
    crc_next[29] = (data_in[3] ^ crc[31])   ^ crc[25];
13922
    crc_next[30] =  crc[26];
13923
    crc_next[31] =  crc[27];
13924
 
13925
    crc = crc_next;
13926
    crc_error = crc[31:0] != 32'hc704dd7b;  // CRC not equal to magic number
13927
    case (nibble_cnt)
13928
    9: crc_out = {!crc[24], !crc[25], !crc[26], !crc[27], !crc[28], !crc[29], !crc[30], !crc[31],
13929
                  !crc[16], !crc[17], !crc[18], !crc[19], !crc[20], !crc[21], !crc[22], !crc[23],
13930
                  !crc[ 8], !crc[ 9], !crc[10], !crc[11], !crc[12], !crc[13], !crc[14], !crc[15],
13931
                  !crc[ 0], !crc[ 1], !crc[ 2], !crc[ 3], !crc[ 4], !crc[ 5], !crc[ 6], !crc[ 7]};
13932
    default: crc_out = crc_out;
13933
    endcase
13934 169 mohor
    // wait for delta time
13935
    delta_t = !delta_t;
13936
    // increment address and load new data
13937 209 tadejm
    if ((word_cnt+3) == 7)//4)
13938 169 mohor
    begin
13939 209 tadejm
      // because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3]
13940 169 mohor
      load_reg[31:24] = eth_phy.rx_mem[addr_cnt];
13941
      addr_cnt = addr_cnt + 1;
13942
      load_reg[23:16] = eth_phy.rx_mem[addr_cnt];
13943
      addr_cnt = addr_cnt + 1;
13944 209 tadejm
      load_reg[15: 8] = eth_phy.rx_mem[addr_cnt];
13945 169 mohor
      addr_cnt = addr_cnt + 1;
13946 209 tadejm
      load_reg[ 7: 0] = eth_phy.rx_mem[addr_cnt];
13947
      addr_cnt = addr_cnt + 1;
13948 169 mohor
    end
13949
    // set new load bit position
13950 209 tadejm
    if((word_cnt+3) == 31)
13951 169 mohor
      word_cnt = 16;
13952 209 tadejm
    else if ((word_cnt+3) == 23)
13953 169 mohor
      word_cnt = 8;
13954 209 tadejm
    else if ((word_cnt+3) == 15)
13955 169 mohor
      word_cnt = 0;
13956 209 tadejm
    else if ((word_cnt+3) == 7)
13957 169 mohor
      word_cnt = 24;
13958
    else
13959 209 tadejm
      word_cnt = word_cnt + 4;// - 4;
13960
    // decrement nibble counter
13961
    nibble_cnt = nibble_cnt - 1;
13962 169 mohor
    // wait for delta time
13963
    delta_t = !delta_t;
13964
  end // while
13965
  #1;
13966
end
13967
endtask // paralel_crc_phy_rx
13968
 
13969
// paralel CRC checking for MAC
13970
task paralel_crc_mac;
13971
  input  [31:0] start_addr; // start address
13972
  input  [31:0] len; // length of frame in Bytes without CRC length
13973
  input         plus_dribble_nibble; // if length is longer for one nibble
13974 209 tadejm
  output [31:0] crc_out;
13975
 
13976
  reg    [21:0] addr_cnt; // only 22 address lines
13977 169 mohor
  integer       word_cnt;
13978 209 tadejm
  integer       nibble_cnt;
13979 169 mohor
  reg    [31:0] load_reg;
13980
  reg           delta_t;
13981 209 tadejm
  reg    [31:0] crc_next;
13982
  reg    [31:0] crc;
13983
  reg           crc_error;
13984
  reg     [3:0] data_in;
13985
  integer       i;
13986 169 mohor
begin
13987
  #1 addr_cnt = start_addr[19:0];
13988
  // set starting point depending with which byte frame starts (e.g. if addr_cnt[1:0] == 0, then
13989
  //   MSB of the packet must be written to the LSB of Big ENDIAN Word [31:24])
13990
  if (addr_cnt[1:0] == 2'h1)
13991
    word_cnt = 16; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
13992
  else if (addr_cnt[1:0] == 2'h2)
13993
    word_cnt = 8; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
13994
  else if (addr_cnt[1:0] == 2'h3)
13995
    word_cnt = 0; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
13996
  else
13997
    word_cnt = 24; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
13998 209 tadejm
  crc = 32'hFFFF_FFFF; // INITIAL value
13999 169 mohor
  delta_t = 0;
14000
  // length must include 4 bytes of ZEROs, to generate CRC
14001 209 tadejm
  // get number of nibbles from Byte length (2^1 = 2)
14002 169 mohor
  if (plus_dribble_nibble)
14003 209 tadejm
    nibble_cnt = ((len + 4) << 1) + 1'b1; // one nibble longer
14004 169 mohor
  else
14005 209 tadejm
    nibble_cnt = ((len + 4) << 1);
14006 169 mohor
  load_reg = wb_slave.wb_memory[{12'h0, addr_cnt}];
14007 209 tadejm
  addr_cnt = addr_cnt + 4;
14008
  while (nibble_cnt > 0)
14009 169 mohor
  begin
14010
    // wait for delta time
14011
    delta_t = !delta_t;
14012
    // shift data in
14013 209 tadejm
 
14014
    if(nibble_cnt <= 8) // for additional 8 nibbles shift ZEROs in!
14015
      data_in[3:0] = 4'h0;
14016 169 mohor
    else
14017 209 tadejm
 
14018
      data_in[3:0] = {load_reg[word_cnt], load_reg[word_cnt+1], load_reg[word_cnt+2], load_reg[word_cnt+3]};
14019
    crc_next[0]  = (data_in[0] ^ crc[28]);
14020
    crc_next[1]  = (data_in[1] ^ data_in[0] ^ crc[28]    ^ crc[29]);
14021
    crc_next[2]  = (data_in[2] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[30]);
14022
    crc_next[3]  = (data_in[3] ^ data_in[2] ^ data_in[1] ^ crc[29]  ^ crc[30] ^ crc[31]);
14023
    crc_next[4]  = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[0];
14024
    crc_next[5]  = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[1];
14025
    crc_next[6]  = (data_in[2] ^ data_in[1] ^ crc[29]    ^ crc[30]) ^ crc[ 2];
14026
    crc_next[7]  = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[3];
14027
    crc_next[8]  = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[4];
14028
    crc_next[9]  = (data_in[2] ^ data_in[1] ^ crc[29]    ^ crc[30]) ^ crc[5];
14029
    crc_next[10] = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[6];
14030
    crc_next[11] = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[7];
14031
    crc_next[12] = (data_in[2] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[30]) ^ crc[8];
14032
    crc_next[13] = (data_in[3] ^ data_in[2] ^ data_in[1] ^ crc[29]  ^ crc[30] ^ crc[31]) ^ crc[9];
14033
    crc_next[14] = (data_in[3] ^ data_in[2] ^ crc[30]    ^ crc[31]) ^ crc[10];
14034
    crc_next[15] = (data_in[3] ^ crc[31])   ^ crc[11];
14035
    crc_next[16] = (data_in[0] ^ crc[28])   ^ crc[12];
14036
    crc_next[17] = (data_in[1] ^ crc[29])   ^ crc[13];
14037
    crc_next[18] = (data_in[2] ^ crc[30])   ^ crc[14];
14038
    crc_next[19] = (data_in[3] ^ crc[31])   ^ crc[15];
14039
    crc_next[20] =  crc[16];
14040
    crc_next[21] =  crc[17];
14041
    crc_next[22] = (data_in[0] ^ crc[28])   ^ crc[18];
14042
    crc_next[23] = (data_in[1] ^ data_in[0] ^ crc[29]    ^ crc[28]) ^ crc[19];
14043
    crc_next[24] = (data_in[2] ^ data_in[1] ^ crc[30]    ^ crc[29]) ^ crc[20];
14044
    crc_next[25] = (data_in[3] ^ data_in[2] ^ crc[31]    ^ crc[30]) ^ crc[21];
14045
    crc_next[26] = (data_in[3] ^ data_in[0] ^ crc[31]    ^ crc[28]) ^ crc[22];
14046
    crc_next[27] = (data_in[1] ^ crc[29])   ^ crc[23];
14047
    crc_next[28] = (data_in[2] ^ crc[30])   ^ crc[24];
14048
    crc_next[29] = (data_in[3] ^ crc[31])   ^ crc[25];
14049
    crc_next[30] =  crc[26];
14050
    crc_next[31] =  crc[27];
14051
 
14052
    crc = crc_next;
14053
    crc_error = crc[31:0] != 32'hc704dd7b;  // CRC not equal to magic number
14054
    case (nibble_cnt)
14055
    9: crc_out = {!crc[24], !crc[25], !crc[26], !crc[27], !crc[28], !crc[29], !crc[30], !crc[31],
14056
                  !crc[16], !crc[17], !crc[18], !crc[19], !crc[20], !crc[21], !crc[22], !crc[23],
14057
                  !crc[ 8], !crc[ 9], !crc[10], !crc[11], !crc[12], !crc[13], !crc[14], !crc[15],
14058
                  !crc[ 0], !crc[ 1], !crc[ 2], !crc[ 3], !crc[ 4], !crc[ 5], !crc[ 6], !crc[ 7]};
14059
    default: crc_out = crc_out;
14060
    endcase
14061 169 mohor
    // wait for delta time
14062
    delta_t = !delta_t;
14063 209 tadejm
    // increment address and load new data
14064
    if ((word_cnt+3) == 7)//4)
14065 169 mohor
    begin
14066 209 tadejm
      // because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3]
14067
      load_reg = wb_slave.wb_memory[{12'h0, addr_cnt}];
14068 169 mohor
      addr_cnt = addr_cnt + 4;
14069
    end
14070 209 tadejm
    // set new load bit position
14071
    if((word_cnt+3) == 31)
14072 169 mohor
      word_cnt = 16;
14073 209 tadejm
    else if ((word_cnt+3) == 23)
14074 169 mohor
      word_cnt = 8;
14075 209 tadejm
    else if ((word_cnt+3) == 15)
14076 169 mohor
      word_cnt = 0;
14077 209 tadejm
    else if ((word_cnt+3) == 7)
14078 169 mohor
      word_cnt = 24;
14079
    else
14080 209 tadejm
      word_cnt = word_cnt + 4;// - 4;
14081
    // decrement nibble counter
14082
    nibble_cnt = nibble_cnt - 1;
14083 169 mohor
    // wait for delta time
14084
    delta_t = !delta_t;
14085
  end // while
14086
  #1;
14087
end
14088
endtask // paralel_crc_mac
14089
 
14090
// serial CRC checking for PHY TX
14091
task serial_crc_phy_tx;
14092
  input  [31:0] start_addr; // start address
14093
  input  [31:0] len; // length of frame in Bytes without CRC length
14094
  input         plus_dribble_nibble; // if length is longer for one nibble
14095
  output [31:0] crc;
14096
  reg    [21:0] addr_cnt; // only 22 address lines
14097
  integer       word_cnt;
14098
  integer       bit_cnt;
14099
  reg    [31:0] load_reg;
14100
  reg    [31:0] crc_shift_reg;
14101
  reg    [31:0] crc_store_reg;
14102
  reg           delta_t;
14103
begin
14104
  #1 addr_cnt = start_addr[21:0];
14105
  word_cnt = 24; // 27; // start of the frame - nibble granularity (MSbit first)
14106
  crc_store_reg = 32'hFFFF_FFFF; // INITIAL value
14107
  delta_t = 0;
14108
  // length must include 4 bytes of ZEROs, to generate CRC
14109
  // get number of bits from Byte length (2^3 = 8)
14110
  if (plus_dribble_nibble)
14111
    bit_cnt = ((len + 4) << 3) + 3'h4; // one nibble longer
14112
  else
14113
    bit_cnt = ((len + 4) << 3);
14114
  // because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3]
14115
  load_reg[31:24] = eth_phy.tx_mem[addr_cnt];
14116
  addr_cnt = addr_cnt + 1;
14117
  load_reg[23:16] = eth_phy.tx_mem[addr_cnt];
14118
  addr_cnt = addr_cnt + 1;
14119
  load_reg[15: 8] = eth_phy.tx_mem[addr_cnt];
14120
  addr_cnt = addr_cnt + 1;
14121
  load_reg[ 7: 0] = eth_phy.tx_mem[addr_cnt];
14122
  addr_cnt = addr_cnt + 1;
14123
#1;
14124
  while (bit_cnt > 0)
14125
  begin
14126
    // wait for delta time
14127
    delta_t = !delta_t;
14128
#1;
14129
    // shift data in
14130
 
14131
    if(bit_cnt <= 32) // for additional 32 bits shift ZEROs in!
14132
     crc_shift_reg[0] = 1'b0               ^ crc_store_reg[31];
14133
    else
14134
 
14135
     crc_shift_reg[0] = load_reg[word_cnt] ^ crc_store_reg[31];
14136
    crc_shift_reg[1]  = crc_store_reg[0]   ^ crc_store_reg[31];
14137
    crc_shift_reg[2]  = crc_store_reg[1]   ^ crc_store_reg[31];
14138
    crc_shift_reg[3]  = crc_store_reg[2];
14139
    crc_shift_reg[4]  = crc_store_reg[3]   ^ crc_store_reg[31];
14140
    crc_shift_reg[5]  = crc_store_reg[4]   ^ crc_store_reg[31];
14141
    crc_shift_reg[6]  = crc_store_reg[5];
14142
    crc_shift_reg[7]  = crc_store_reg[6]   ^ crc_store_reg[31];
14143
    crc_shift_reg[8]  = crc_store_reg[7]   ^ crc_store_reg[31];
14144
    crc_shift_reg[9]  = crc_store_reg[8];
14145
    crc_shift_reg[10] = crc_store_reg[9]   ^ crc_store_reg[31];
14146
    crc_shift_reg[11] = crc_store_reg[10]  ^ crc_store_reg[31];
14147
    crc_shift_reg[12] = crc_store_reg[11]  ^ crc_store_reg[31];
14148
    crc_shift_reg[13] = crc_store_reg[12];
14149
    crc_shift_reg[14] = crc_store_reg[13];
14150
    crc_shift_reg[15] = crc_store_reg[14];
14151
    crc_shift_reg[16] = crc_store_reg[15]  ^ crc_store_reg[31];
14152
    crc_shift_reg[17] = crc_store_reg[16];
14153
    crc_shift_reg[18] = crc_store_reg[17];
14154
    crc_shift_reg[19] = crc_store_reg[18];
14155
    crc_shift_reg[20] = crc_store_reg[19];
14156
    crc_shift_reg[21] = crc_store_reg[20];
14157
    crc_shift_reg[22] = crc_store_reg[21]  ^ crc_store_reg[31];
14158
    crc_shift_reg[23] = crc_store_reg[22]  ^ crc_store_reg[31];
14159
    crc_shift_reg[24] = crc_store_reg[23];
14160
    crc_shift_reg[25] = crc_store_reg[24];
14161
    crc_shift_reg[26] = crc_store_reg[25]  ^ crc_store_reg[31];
14162
    crc_shift_reg[27] = crc_store_reg[26];
14163
    crc_shift_reg[28] = crc_store_reg[27];
14164
    crc_shift_reg[29] = crc_store_reg[28];
14165
    crc_shift_reg[30] = crc_store_reg[29];
14166
    crc_shift_reg[31] = crc_store_reg[30];
14167
    // wait for delta time
14168
    delta_t = !delta_t;
14169
 
14170
    // store previous data
14171
    crc_store_reg = crc_shift_reg;
14172
 
14173
    // put CRC out
14174
    case (bit_cnt)
14175
    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:
14176
    begin
14177
      crc = crc_store_reg;
14178
      crc = {!crc[24], !crc[25], !crc[26], !crc[27], !crc[28], !crc[29], !crc[30], !crc[31],
14179
             !crc[16], !crc[17], !crc[18], !crc[19], !crc[20], !crc[21], !crc[22], !crc[23],
14180
             !crc[ 8], !crc[ 9], !crc[10], !crc[11], !crc[12], !crc[13], !crc[14], !crc[15],
14181
             !crc[ 0], !crc[ 1], !crc[ 2], !crc[ 3], !crc[ 4], !crc[ 5], !crc[ 6], !crc[ 7]};
14182
    end
14183
    default: crc = crc;
14184
    endcase
14185
 
14186
    // increment address and load new data
14187
#1;
14188
    if (word_cnt == 7)//4)
14189
    begin
14190
      // because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3]
14191
      load_reg[31:24] = eth_phy.tx_mem[addr_cnt];
14192
//      load_reg[31:24] = {load_reg[28], load_reg[29], load_reg[30], load_reg[31], 
14193
//                         load_reg[24], load_reg[25], load_reg[26], load_reg[27]};
14194
      addr_cnt = addr_cnt + 1;
14195
      load_reg[23:16] = eth_phy.tx_mem[addr_cnt];
14196
//      load_reg[23:16] = {load_reg[20], load_reg[21], load_reg[22], load_reg[23], 
14197
//                         load_reg[16], load_reg[17], load_reg[18], load_reg[19]};
14198
      addr_cnt = addr_cnt + 1;
14199
      load_reg[15: 8] = eth_phy.tx_mem[addr_cnt];
14200
//      load_reg[15: 8] = {load_reg[12], load_reg[13], load_reg[14], load_reg[15], 
14201
//                         load_reg[ 8], load_reg[ 9], load_reg[10], load_reg[11]};
14202
      addr_cnt = addr_cnt + 1;
14203
      load_reg[ 7: 0] = eth_phy.tx_mem[addr_cnt];
14204
//      load_reg[ 7: 0] = {load_reg[ 4], load_reg[ 5], load_reg[ 6], load_reg[ 7], 
14205
//                         load_reg[ 0], load_reg[ 1], load_reg[ 2], load_reg[ 3]};
14206
      addr_cnt = addr_cnt + 1;
14207
    end
14208
#1;
14209
    // set new load bit position
14210
    if(word_cnt == 31)
14211
      word_cnt = 16;
14212
    else if (word_cnt == 23)
14213
      word_cnt = 8;
14214
    else if (word_cnt == 15)
14215
      word_cnt = 0;
14216
    else if (word_cnt == 7)
14217
      word_cnt = 24;
14218
 
14219
//   if(word_cnt == 24)
14220
//     word_cnt = 31;
14221
//   else if (word_cnt == 28)
14222
//     word_cnt = 19;
14223
//   else if (word_cnt == 16)
14224
//     word_cnt = 23;
14225
//   else if (word_cnt == 20)
14226
//     word_cnt = 11;
14227
//   else if(word_cnt == 8)
14228
//     word_cnt = 15;
14229
//   else if (word_cnt == 12)
14230
//     word_cnt = 3;
14231
//   else if (word_cnt == 0)
14232
//     word_cnt = 7;
14233
//   else if (word_cnt == 4)
14234
//     word_cnt = 27;
14235
    else
14236
      word_cnt = word_cnt + 1;// - 1;
14237
#1;
14238
    // decrement bit counter
14239
    bit_cnt = bit_cnt - 1;
14240
#1;
14241
    // wait for delta time
14242
    delta_t = !delta_t;
14243
  end // while
14244
 
14245
  #1;
14246
end
14247
endtask // serial_crc_phy_tx
14248
 
14249
// serial CRC calculating for PHY RX
14250
task serial_crc_phy_rx;
14251
  input  [31:0] start_addr; // start address
14252
  input  [31:0] len; // length of frame in Bytes without CRC length
14253
  input         plus_dribble_nibble; // if length is longer for one nibble
14254
  output [31:0] crc;
14255
  reg    [21:0] addr_cnt; // only 22 address lines
14256
  integer       word_cnt;
14257
  integer       bit_cnt;
14258
  reg    [31:0] load_reg;
14259
  reg    [31:0] crc_shift_reg;
14260
  reg    [31:0] crc_store_reg;
14261
  reg           delta_t;
14262
begin
14263
  #1 addr_cnt = start_addr[21:0];
14264
  word_cnt = 24; // start of the frame
14265
  crc_shift_reg = 0;
14266
  delta_t = 0;
14267
  // length must include 4 bytes of ZEROs, to generate CRC
14268
  // get number of bits from Byte length (2^3 = 8)
14269
  if (plus_dribble_nibble)
14270
    bit_cnt = ((len + 4) << 3) + 3'h4; // one nibble longer
14271
  else
14272
    bit_cnt = ((len + 4) << 3);
14273
  load_reg[31:24] = eth_phy.rx_mem[addr_cnt];
14274
  addr_cnt = addr_cnt + 1;
14275
  load_reg[23:16] = eth_phy.rx_mem[addr_cnt];
14276
  addr_cnt = addr_cnt + 1;
14277
  load_reg[15:8]  = eth_phy.rx_mem[addr_cnt];
14278
  addr_cnt = addr_cnt + 1;
14279
  load_reg[7:0]   = eth_phy.rx_mem[addr_cnt];
14280
 
14281
  while (bit_cnt > 0)
14282
  begin
14283
    // wait for delta time
14284
    delta_t = !delta_t;
14285
    // store previous data
14286
    crc_store_reg = crc_shift_reg;
14287
    // shift data in
14288
    if(bit_cnt <= 32) // for additional 32 bits shift ZEROs in!
14289
     crc_shift_reg[0] = 1'b0               ^ crc_store_reg[31];
14290
    else
14291
     crc_shift_reg[0] = load_reg[word_cnt] ^ crc_store_reg[31];
14292
    crc_shift_reg[1]  = crc_store_reg[0]   ^ crc_store_reg[31];
14293
    crc_shift_reg[2]  = crc_store_reg[1]   ^ crc_store_reg[31];
14294
    crc_shift_reg[3]  = crc_store_reg[2];
14295
    crc_shift_reg[4]  = crc_store_reg[3]   ^ crc_store_reg[31];
14296
    crc_shift_reg[5]  = crc_store_reg[4]   ^ crc_store_reg[31];
14297
    crc_shift_reg[6]  = crc_store_reg[5];
14298
    crc_shift_reg[7]  = crc_store_reg[6]   ^ crc_store_reg[31];
14299
    crc_shift_reg[8]  = crc_store_reg[7]   ^ crc_store_reg[31];
14300
    crc_shift_reg[9]  = crc_store_reg[8];
14301
    crc_shift_reg[10] = crc_store_reg[9]   ^ crc_store_reg[31];
14302
    crc_shift_reg[11] = crc_store_reg[10]  ^ crc_store_reg[31];
14303
    crc_shift_reg[12] = crc_store_reg[11]  ^ crc_store_reg[31];
14304
    crc_shift_reg[13] = crc_store_reg[12];
14305
    crc_shift_reg[14] = crc_store_reg[13];
14306
    crc_shift_reg[15] = crc_store_reg[14];
14307
    crc_shift_reg[16] = crc_store_reg[15]  ^ crc_store_reg[31];
14308
    crc_shift_reg[17] = crc_store_reg[16];
14309
    crc_shift_reg[18] = crc_store_reg[17];
14310
    crc_shift_reg[19] = crc_store_reg[18];
14311
    crc_shift_reg[20] = crc_store_reg[19];
14312
    crc_shift_reg[21] = crc_store_reg[20];
14313
    crc_shift_reg[22] = crc_store_reg[21]  ^ crc_store_reg[31];
14314
    crc_shift_reg[23] = crc_store_reg[22]  ^ crc_store_reg[31];
14315
    crc_shift_reg[24] = crc_store_reg[23];
14316
    crc_shift_reg[25] = crc_store_reg[24];
14317
    crc_shift_reg[26] = crc_store_reg[25]  ^ crc_store_reg[31];
14318
    crc_shift_reg[27] = crc_store_reg[26];
14319
    crc_shift_reg[28] = crc_store_reg[27];
14320
    crc_shift_reg[29] = crc_store_reg[28];
14321
    crc_shift_reg[30] = crc_store_reg[29];
14322
    crc_shift_reg[31] = crc_store_reg[30];
14323
    // wait for delta time
14324
    delta_t = !delta_t;
14325
    // increment address and load new data
14326
    if (word_cnt == 7)
14327
    begin
14328
      addr_cnt = addr_cnt + 1;
14329
      load_reg[31:24] = eth_phy.rx_mem[addr_cnt];
14330
      addr_cnt = addr_cnt + 1;
14331
      load_reg[23:16] = eth_phy.rx_mem[addr_cnt];
14332
      addr_cnt = addr_cnt + 1;
14333
      load_reg[15:8]  = eth_phy.rx_mem[addr_cnt];
14334
      addr_cnt = addr_cnt + 1;
14335
      load_reg[7:0]   = eth_phy.rx_mem[addr_cnt];
14336
    end
14337
    // set new load bit position
14338
    if(word_cnt == 31)
14339
      word_cnt = 16;
14340
    else if (word_cnt == 23)
14341
      word_cnt = 8;
14342
    else if (word_cnt == 15)
14343
      word_cnt = 0;
14344
    else if (word_cnt == 7)
14345
      word_cnt = 24;
14346
    else
14347
      word_cnt = word_cnt + 1;
14348
    // decrement bit counter
14349
    bit_cnt = bit_cnt - 1;
14350
    // wait for delta time
14351
    delta_t = !delta_t;
14352
  end // while
14353
 
14354
  // put CRC out
14355
  crc = crc_shift_reg;
14356
  #1;
14357
end
14358
endtask // serial_crc_phy_rx
14359
 
14360
// serial CRC checking for MAC
14361
task serial_crc_mac;
14362
  input  [31:0] start_addr; // start address
14363
  input  [31:0] len; // length of frame in Bytes without CRC length
14364
  input         plus_dribble_nibble; // if length is longer for one nibble
14365
  output [31:0] crc;
14366
  reg    [19:0] addr_cnt; // only 20 address lines
14367
  integer       word_cnt;
14368
  integer       bit_cnt;
14369
  reg    [31:0] load_reg;
14370
  reg    [31:0] crc_shift_reg;
14371
  reg    [31:0] crc_store_reg;
14372
  reg           delta_t;
14373
begin
14374
  #1 addr_cnt = start_addr[19:0];
14375
  // set starting point depending with which byte frame starts (e.g. if addr_cnt[1:0] == 0, then
14376
  //   MSB of the packet must be written to the LSB of Big ENDIAN Word [31:24])
14377
  if (addr_cnt[1:0] == 2'h1)
14378
    word_cnt = 16; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
14379
  else if (addr_cnt[1:0] == 2'h2)
14380
    word_cnt = 8; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
14381
  else if (addr_cnt[1:0] == 2'h3)
14382
    word_cnt = 0; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
14383
  else
14384
    word_cnt = 24; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
14385
 
14386
  crc_shift_reg = 0;
14387
  delta_t = 0;
14388
  // length must include 4 bytes of ZEROs, to generate CRC
14389
  // get number of bits from Byte length (2^3 = 8)
14390
  if (plus_dribble_nibble)
14391
    bit_cnt = ((len + 4) << 3) + 3'h4; // one nibble longer
14392
  else
14393
    bit_cnt = ((len + 4) << 3);
14394
  load_reg = wb_slave.wb_memory[{12'h0, addr_cnt}];
14395
 
14396
  while (bit_cnt > 0)
14397
  begin
14398
    // wait for delta time
14399
    delta_t = !delta_t;
14400
    // store previous data
14401
    crc_store_reg = crc_shift_reg;
14402
    // shift data in
14403
    if(bit_cnt <= 32) // for additional 32 bits shift ZEROs in!
14404
     crc_shift_reg[0] = 1'b0               ^ crc_store_reg[31];
14405
    else
14406
     crc_shift_reg[0] = load_reg[word_cnt] ^ crc_store_reg[31];
14407
    crc_shift_reg[1]  = crc_store_reg[0]   ^ crc_store_reg[31];
14408
    crc_shift_reg[2]  = crc_store_reg[1]   ^ crc_store_reg[31];
14409
    crc_shift_reg[3]  = crc_store_reg[2];
14410
    crc_shift_reg[4]  = crc_store_reg[3]   ^ crc_store_reg[31];
14411
    crc_shift_reg[5]  = crc_store_reg[4]   ^ crc_store_reg[31];
14412
    crc_shift_reg[6]  = crc_store_reg[5];
14413
    crc_shift_reg[7]  = crc_store_reg[6]   ^ crc_store_reg[31];
14414
    crc_shift_reg[8]  = crc_store_reg[7]   ^ crc_store_reg[31];
14415
    crc_shift_reg[9]  = crc_store_reg[8];
14416
    crc_shift_reg[10] = crc_store_reg[9]   ^ crc_store_reg[31];
14417
    crc_shift_reg[11] = crc_store_reg[10]  ^ crc_store_reg[31];
14418
    crc_shift_reg[12] = crc_store_reg[11]  ^ crc_store_reg[31];
14419
    crc_shift_reg[13] = crc_store_reg[12];
14420
    crc_shift_reg[14] = crc_store_reg[13];
14421
    crc_shift_reg[15] = crc_store_reg[14];
14422
    crc_shift_reg[16] = crc_store_reg[15]  ^ crc_store_reg[31];
14423
    crc_shift_reg[17] = crc_store_reg[16];
14424
    crc_shift_reg[18] = crc_store_reg[17];
14425
    crc_shift_reg[19] = crc_store_reg[18];
14426
    crc_shift_reg[20] = crc_store_reg[19];
14427
    crc_shift_reg[21] = crc_store_reg[20];
14428
    crc_shift_reg[22] = crc_store_reg[21]  ^ crc_store_reg[31];
14429
    crc_shift_reg[23] = crc_store_reg[22]  ^ crc_store_reg[31];
14430
    crc_shift_reg[24] = crc_store_reg[23];
14431
    crc_shift_reg[25] = crc_store_reg[24];
14432
    crc_shift_reg[26] = crc_store_reg[25]  ^ crc_store_reg[31];
14433
    crc_shift_reg[27] = crc_store_reg[26];
14434
    crc_shift_reg[28] = crc_store_reg[27];
14435
    crc_shift_reg[29] = crc_store_reg[28];
14436
    crc_shift_reg[30] = crc_store_reg[29];
14437
    crc_shift_reg[31] = crc_store_reg[30];
14438
    // wait for delta time
14439
    delta_t = !delta_t;
14440
    // increment address and load new data for Big ENDIAN Bytes (Litle ENDIAN bits)
14441
    if (word_cnt == 7)
14442
    begin
14443
      addr_cnt = addr_cnt + 4;
14444
      load_reg = wb_slave.wb_memory[{12'h0, addr_cnt}];
14445
    end
14446
    // set new load bit position for Big ENDIAN Bytes (Litle ENDIAN bits)
14447
    if(word_cnt == 31)
14448
      word_cnt = 16;
14449
    else if (word_cnt == 23)
14450
      word_cnt = 8;
14451
    else if (word_cnt == 15)
14452
      word_cnt = 0;
14453
    else if (word_cnt == 7)
14454
      word_cnt = 24;
14455
    else
14456
      word_cnt = word_cnt + 1;
14457
    // decrement bit counter
14458
    bit_cnt = bit_cnt - 1;
14459
    // wait for delta time
14460
    delta_t = !delta_t;
14461
  end // while
14462
 
14463
  // put CRC out
14464
  crc = crc_shift_reg;
14465
  #1;
14466
end
14467
endtask // serial_crc_mac
14468
 
14469
//////////////////////////////////////////////////////////////
14470
// MIIM Basic tasks
14471
//////////////////////////////////////////////////////////////
14472
 
14473
task reset_mii; //  MII module
14474
  reg [31:0] tmp;
14475
  reg [31:0] tmp_no_rst;
14476
begin
14477
  // read MII mode register first
14478
  wbm_read(`ETH_MIIMODER, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14479
  // set reset bit - write back to MII mode register with RESET bit
14480
  wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_RST | tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14481
  // clear reset bit - write back to MII mode register without RESET bit
14482
  tmp_no_rst = `ETH_MIIMODER_RST;
14483
  tmp_no_rst = ~tmp_no_rst;
14484
  wbm_write(`ETH_MIIMODER, (tmp_no_rst & tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14485
end
14486
endtask // reset_mii
14487
 
14488
task mii_set_clk_div; // set clock divider for MII clock
14489
  input [7:0]  clk_div;
14490
begin
14491
  // MII mode register
14492
  wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_CLKDIV & clk_div), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14493
end
14494
endtask // mii_set_clk_div
14495
 
14496
 
14497
task check_mii_busy; // MII - check if BUSY
14498
  reg [31:0] tmp;
14499
begin
14500
  @(posedge wb_clk);
14501
  // MII read status register
14502
  wbm_read(`ETH_MIISTATUS, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14503
  while(tmp[`ETH_MIISTATUS_BUSY] !== 1'b0) //`ETH_MIISTATUS_BUSY
14504
  begin
14505
    @(posedge wb_clk);
14506
    wbm_read(`ETH_MIISTATUS, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14507
  end
14508
end
14509
endtask // check_mii_busy
14510
 
14511
 
14512
task check_mii_scan_valid; // MII - check if SCAN data are valid
14513
  reg [31:0] tmp;
14514
begin
14515
  @(posedge wb_clk);
14516
  // MII read status register
14517
  wbm_read(`ETH_MIISTATUS, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14518
  while(tmp[`ETH_MIISTATUS_NVALID] !== 1'b0) //`ETH_MIISTATUS_NVALID
14519
  begin
14520
    @(posedge wb_clk);
14521
    wbm_read(`ETH_MIISTATUS, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14522
  end
14523
end
14524
endtask // check_mii_scan_valid
14525
 
14526
 
14527
task mii_write_req; // requests write to MII
14528
  input [4:0]  phy_addr;
14529
  input [4:0]  reg_addr;
14530
  input [15:0] data_in;
14531
begin
14532
  // MII address, PHY address = 1, command register address = 0
14533
  wbm_write(`ETH_MIIADDRESS, (`ETH_MIIADDRESS_FIAD & phy_addr) | (`ETH_MIIADDRESS_RGAD & (reg_addr << 8)),
14534
            4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14535
  // MII TX data
14536
  wbm_write(`ETH_MIITX_DATA, {16'h0000, data_in}, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14537
  // MII command
14538
  wbm_write(`ETH_MIICOMMAND, `ETH_MIICOMMAND_WCTRLDATA, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14539
  @(posedge wb_clk);
14540
end
14541
endtask // mii_write_req
14542
 
14543
 
14544
task mii_read_req; // requests read from MII
14545
  input [4:0]  phy_addr;
14546
  input [4:0]  reg_addr;
14547
begin
14548
  // MII address, PHY address = 1, command register address = 0
14549
  wbm_write(`ETH_MIIADDRESS, (`ETH_MIIADDRESS_FIAD & phy_addr) | (`ETH_MIIADDRESS_RGAD & (reg_addr << 8)),
14550
            4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14551
  // MII command
14552
  wbm_write(`ETH_MIICOMMAND, `ETH_MIICOMMAND_RSTAT, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14553
  @(posedge wb_clk);
14554
end
14555
endtask // mii_read_req
14556
 
14557
 
14558
task mii_scan_req; // requests scan from MII
14559
  input [4:0]  phy_addr;
14560
  input [4:0]  reg_addr;
14561
begin
14562
  // MII address, PHY address = 1, command register address = 0
14563
  wbm_write(`ETH_MIIADDRESS, (`ETH_MIIADDRESS_FIAD & phy_addr) | (`ETH_MIIADDRESS_RGAD & (reg_addr << 8)),
14564
            4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14565
  // MII command
14566
  wbm_write(`ETH_MIICOMMAND, `ETH_MIICOMMAND_SCANSTAT, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14567
  @(posedge wb_clk);
14568
end
14569
endtask // mii_scan_req
14570
 
14571
 
14572
task mii_scan_finish; // finish scan from MII
14573
begin
14574
  // MII command
14575
  wbm_write(`ETH_MIICOMMAND, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
14576
  @(posedge wb_clk);
14577
end
14578
endtask // mii_scan_finish
14579
 
14580
//////////////////////////////////////////////////////////////
14581
// Log files and memory tasks
14582
//////////////////////////////////////////////////////////////
14583
 
14584
task clear_memories;
14585
  reg    [22:0]  adr_i;
14586
  reg            delta_t;
14587
begin
14588
  delta_t = 0;
14589
  for (adr_i = 0; adr_i < 4194304; adr_i = adr_i + 1)
14590
  begin
14591
    eth_phy.rx_mem[adr_i[21:0]] = 0;
14592
    eth_phy.tx_mem[adr_i[21:0]] = 0;
14593
    wb_slave.wb_memory[adr_i[21:2]] = 0;
14594
    delta_t = !delta_t;
14595
  end
14596
end
14597
endtask // clear_memories
14598
 
14599
task test_note;
14600
  input [799:0] test_note ;
14601
  reg   [799:0] display_note ;
14602
begin
14603
  display_note = test_note;
14604
  while ( display_note[799:792] == 0 )
14605
    display_note = display_note << 8 ;
14606
  $fdisplay( tb_log_file, " " ) ;
14607
  $fdisplay( tb_log_file, "NOTE: %s", display_note ) ;
14608
  $fdisplay( tb_log_file, " " ) ;
14609
end
14610
endtask // test_note
14611
 
14612
task test_heading;
14613
  input [799:0] test_heading ;
14614
  reg   [799:0] display_test ;
14615
begin
14616
  display_test = test_heading;
14617
  while ( display_test[799:792] == 0 )
14618
    display_test = display_test << 8 ;
14619
  $fdisplay( tb_log_file, "  ***************************************************************************************" ) ;
14620
  $fdisplay( tb_log_file, "  ***************************************************************************************" ) ;
14621
  $fdisplay( tb_log_file, "  Heading: %s", display_test ) ;
14622
  $fdisplay( tb_log_file, "  ***************************************************************************************" ) ;
14623
  $fdisplay( tb_log_file, "  ***************************************************************************************" ) ;
14624
  $fdisplay( tb_log_file, " " ) ;
14625
end
14626
endtask // test_heading
14627
 
14628
 
14629
task test_fail ;
14630
  input [7999:0] failure_reason ;
14631
//  reg   [8007:0] display_failure ;
14632
  reg   [7999:0] display_failure ;
14633
  reg   [799:0] display_test ;
14634
begin
14635
  tests_failed = tests_failed + 1 ;
14636
 
14637
  display_failure = failure_reason; // {failure_reason, "!"} ;
14638
  while ( display_failure[7999:7992] == 0 )
14639
    display_failure = display_failure << 8 ;
14640
 
14641
  display_test = test_name ;
14642
  while ( display_test[799:792] == 0 )
14643
    display_test = display_test << 8 ;
14644
 
14645
  $fdisplay( tb_log_file, "    *************************************************************************************" ) ;
14646
  $fdisplay( tb_log_file, "    At time: %t ", $time ) ;
14647
  $fdisplay( tb_log_file, "    Test: %s", display_test ) ;
14648
  $fdisplay( tb_log_file, "    *FAILED* because") ;
14649
  $fdisplay( tb_log_file, "    %s", display_failure ) ;
14650
  $fdisplay( tb_log_file, "    *************************************************************************************" ) ;
14651
  $fdisplay( tb_log_file, " " ) ;
14652
 
14653
 `ifdef STOP_ON_FAILURE
14654
    #20 $stop ;
14655
 `endif
14656
end
14657
endtask // test_fail
14658
 
14659
 
14660
task test_ok ;
14661
  reg [799:0] display_test ;
14662
begin
14663
  tests_successfull = tests_successfull + 1 ;
14664
 
14665
  display_test = test_name ;
14666
  while ( display_test[799:792] == 0 )
14667
    display_test = display_test << 8 ;
14668
 
14669
  $fdisplay( tb_log_file, "    *************************************************************************************" ) ;
14670
  $fdisplay( tb_log_file, "    At time: %t ", $time ) ;
14671
  $fdisplay( tb_log_file, "    Test: %s", display_test ) ;
14672
  $fdisplay( tb_log_file, "    reported *SUCCESSFULL*! ") ;
14673
  $fdisplay( tb_log_file, "    *************************************************************************************" ) ;
14674
  $fdisplay( tb_log_file, " " ) ;
14675
end
14676
endtask // test_ok
14677
 
14678
 
14679
task test_summary;
14680
begin
14681
  $fdisplay(tb_log_file, "**************************** Ethernet MAC test summary **********************************") ;
14682
  $fdisplay(tb_log_file, "Tests performed:   %d", tests_successfull + tests_failed) ;
14683
  $fdisplay(tb_log_file, "Failed tests   :   %d", tests_failed) ;
14684
  $fdisplay(tb_log_file, "Successfull tests: %d", tests_successfull) ;
14685
  $fdisplay(tb_log_file, "**************************** Ethernet MAC test summary **********************************") ;
14686
  $fclose(tb_log_file) ;
14687
end
14688
endtask // test_summary
14689
 
14690
 
14691 116 mohor
endmodule

powered by: WebSVN 2.1.0

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