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

Subversion Repositories ethmac

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

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

powered by: WebSVN 2.1.0

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