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

Subversion Repositories ethmac

[/] [ethmac/] [tags/] [rel_14/] [bench/] [verilog/] [tb_ethernet.v] - Blame information for rev 169

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

powered by: WebSVN 2.1.0

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