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 170

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

powered by: WebSVN 2.1.0

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