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

Subversion Repositories mac_layer_switch

[/] [mac_layer_switch/] [trunk/] [bench/] [verilog/] [tb_ethernet.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ranm11
 
2
 
3
//   Created by Igor Mohor 
4
//   Changed by Ran Minerbi
5
//
6
//`include "switch.v"
7
`include "eth_phy_defines.v"
8
`include "wb_model_defines.v"
9
`include "tb_eth_defines.v"
10
`include "ethmac_defines.v"
11
`include "timescale.v"
12
 
13
 
14
module tb_instantiations( );
15
 
16
     wire [3:0] Rx1, Rx2,Rx3, Rx4,Rx5, Rx6;
17
     wire [3:0] Tx1 ,Tx2,Tx3 ,Tx4,Tx5 ,Tx6;      //B2B
18
     wire  Tx_En1 , Tx_En2,Tx_En3 , Tx_En4 ,Tx_En5 , Tx_En6 , Rx_Valid1, Rx_Valid2,Rx_Valid3, Rx_Valid4,Rx_Valid5, Rx_Valid6;
19
    // assign Rx2 = Tx1;
20
     //assign Rx1 = Tx2;
21
     assign Rx_Valid2 = Tx_En1;
22
     assign Rx_Valid1 = Tx_En2;
23
     assign Rx_Valid4 = Tx_En3;
24
     assign Rx_Valid3 = Tx_En4;
25
     assign Rx_Valid6 = Tx_En5;
26
     assign Rx_Valid5 = Tx_En6;
27
 
28
             reg [63:0] MAC1,MAC2,MAC3,MAC4,MAC5,MAC6;
29
     initial begin
30
          MAC1 =  64'h0000_AA203040_5060;
31
          MAC2 =  64'h0000_FFCCBB44_0011;
32
          MAC3 =  64'h0000_DDFFBB55_0022;
33
          MAC4 =  64'h0000_CCBBAA99_0099;
34
          MAC5 =  64'h0000_66EECC00_1133;
35
          MAC6 =  64'h0000_1100AAFF_00AA;
36
         end
37
    tb_ethernet nic1(Tx1,Rx1 , 2'h2 ,Tx_En1,Rx_Valid1, MAC1, MAC2 );   // mode=1 --nic 1 transmit test 23  --> nic2 rcv ethmac output
38
    tb_ethernet nic2(Tx2,Rx2 , 2'h2 ,Tx_En2,Rx_Valid2 ,MAC2, MAC1 );    //mode =0 -- nic 2 transmit test ::rcv  15     -->  nic1 rcv eth_phy output
39
    tb_ethernet nic3(Tx3,Rx3 , 2'h2 ,Tx_En3,Rx_Valid3, MAC3, MAC4 );   // mode=1 --nic 1 transmit test 23  --> nic2 rcv ethmac output
40
    tb_ethernet nic4(Tx4,Rx4 , 2'h2 ,Tx_En4,Rx_Valid4 ,MAC4, MAC3 );    //mode =0 -- nic 2 transmit test ::rcv  15     -->  nic1 rcv eth_phy output
41
 
42
    switch SX(Tx1,Tx2,Tx3,Tx4,Tx5,Tx6,Rx2,Rx1,Rx4,Rx3,Rx6,Rx5);
43
      // tb_ethernet nic3(1'h0);
44
 /* $display("#########  tb_instantiations occurance ###################################");
45
  $display("===========================================================================");
46
    */
47
 
48
endmodule
49
 
50
 
51
module tb_ethernet(Tx , Rx , mode ,Tx_en , Rx_valid ,MAC ,DMAC);     //Tx , Rx , mode(transmit = 1 / rcv = 0) , mac    , 
52
 
53
 input [1:0] mode;
54
input  [3:0] Rx;
55
input [63:0] MAC ,DMAC;
56
output [3:0] Tx;
57
output  Tx_en;
58
input   Rx_valid;
59
 
60
reg           wb_clk;
61
reg           wb_rst;
62
wire          wb_int;
63
 
64
wire          mtx_clk;  // This goes to PHY
65
wire          mrx_clk;  // This goes to PHY
66
 
67
wire   [3:0]  MTxD;
68
wire          MTxEn;
69
wire          MTxErr;
70
 
71
wire   [3:0]  MRxD;     // This goes to PHY
72
wire   [3:0]  MRxD_to_ethmac;
73
wire   [3:0]  MRxD_to_Tx;
74
wire          MRxDV_to_ethmac;
75
wire          MRxDV;    // This goes to PHY
76
wire          MRxErr;   // This goes to PHY
77
wire          MColl;    // This goes to PHY
78
wire          MCrs;     // This goes to PHY
79
 
80
wire          Mdi_I;
81
wire          Mdo_O;
82
wire          Mdo_OE;
83
tri           Mdio_IO;
84
wire          Mdc_O;
85
 
86
assign  Tx =mode? MTxD:MRxD;
87
assign  MRxD_to_ethmac = Rx;
88
assign  MRxD_to_Tx = MRxD;
89
assign  Tx_en = mode? MTxEn:MRxDV;
90
assign  MRxDV_to_ethmac = Rx_valid;
91
//assign  MRxD_to_Tx = Rx;
92
 
93
 
94
parameter Tp = 1;
95
 
96
 
97
// Ethernet Slave Interface signals
98
wire [31:0] eth_sl_wb_adr;
99
wire [31:0] eth_sl_wb_adr_i, eth_sl_wb_dat_o, eth_sl_wb_dat_i;
100
wire  [3:0] eth_sl_wb_sel_i;
101
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;
102
 
103
// Ethernet Master Interface signals
104
wire [31:0] eth_ma_wb_adr_o, eth_ma_wb_dat_i, eth_ma_wb_dat_o;
105
wire  [3:0] eth_ma_wb_sel_o;
106
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;
107
 
108
wire  [2:0] eth_ma_wb_cti_o;
109
wire  [1:0] eth_ma_wb_bte_o;
110
 
111
 
112
 
113
 
114
// Connecting Ethernet top module
115
ethmac eth_top
116
(
117
  // WISHBONE common
118
  .wb_clk_i(wb_clk),              .wb_rst_i(wb_rst),
119
 
120
  // WISHBONE slave
121
  .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),
122
  .wb_cyc_i(eth_sl_wb_cyc_i),       .wb_stb_i(eth_sl_wb_stb_i),   .wb_ack_o(eth_sl_wb_ack_o),
123
  .wb_err_o(eth_sl_wb_err_o),       .wb_dat_i(eth_sl_wb_dat_i),   .wb_dat_o(eth_sl_wb_dat_o),
124
 
125
  // WISHBONE master
126
  .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),
127
  .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),
128
  .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),
129
 
130
`ifdef ETH_WISHBONE_B3
131
  .m_wb_cti_o(eth_ma_wb_cti_o),     .m_wb_bte_o(eth_ma_wb_bte_o),
132
`endif
133
 
134
  //TX
135
  .mtx_clk_pad_i(mtx_clk), .mtxd_pad_o(MTxD), .mtxen_pad_o(MTxEn), .mtxerr_pad_o(MTxErr),
136
 
137
  //RX
138
  .mrx_clk_pad_i(mrx_clk), .mrxd_pad_i(MRxD_to_ethmac), .mrxdv_pad_i(MRxDV_to_ethmac), .mrxerr_pad_i(MRxErr),
139
  .mcoll_pad_i(MColl),    .mcrs_pad_i(MCrs),
140
 
141
  // MIIM
142
  .mdc_pad_o(Mdc_O), .md_pad_i(Mdi_I), .md_pad_o(Mdo_O), .md_padoe_o(Mdo_OE),
143
 
144
  .int_o(wb_int)
145
 
146
  // Bist
147
`ifdef ETH_BIST
148
  ,
149
  .mbist_si_i       (1'b0),
150
  .mbist_so_o       (),
151
  .mbist_ctrl_i       (3'b001) // {enable, clock, reset}
152
`endif
153
);
154
 
155
 
156
 
157
// Connecting Ethernet PHY Module
158
assign Mdio_IO = Mdo_OE ? Mdo_O : 1'bz ;
159
assign Mdi_I   = Mdio_IO;
160
integer phy_log_file_desc;
161
 
162
eth_phy eth_phy
163
(
164
  // WISHBONE reset
165
  .m_rst_n_i(!wb_rst),
166
 
167
  // MAC TX
168
  .mtx_clk_o(mtx_clk),    .mtxd_i(MTxD),    .mtxen_i(MTxEn),    .mtxerr_i(MTxErr),
169
 
170
  // MAC RX
171
  .mrx_clk_o(mrx_clk),    .mrxd_o(MRxD),    .mrxdv_o(MRxDV),    .mrxerr_o(MRxErr),
172
  .mcoll_o(MColl),        .mcrs_o(MCrs),
173
 
174
  // MIIM
175
  .mdc_i(Mdc_O),          .md_io(Mdio_IO),
176
 
177
  // SYSTEM
178
  .phy_log(phy_log_file_desc)
179
);
180
 
181
 
182
 
183
// Connecting WB Master as Host Interface
184
integer host_log_file_desc;
185
 
186
WB_MASTER_BEHAVIORAL wb_master
187
(
188
    .CLK_I(wb_clk),
189
    .RST_I(wb_rst),
190
    .TAG_I({`WB_TAG_WIDTH{1'b0}}),
191
    .TAG_O(),
192
    .ACK_I(eth_sl_wb_ack_o),
193
    .ADR_O(eth_sl_wb_adr), // only eth_sl_wb_adr_i[11:2] used
194
    .CYC_O(eth_sl_wb_cyc_i),
195
    .DAT_I(eth_sl_wb_dat_o),
196
    .DAT_O(eth_sl_wb_dat_i),
197
    .ERR_I(eth_sl_wb_err_o),
198
    .RTY_I(1'b0),  // inactive (1'b0)
199
    .SEL_O(eth_sl_wb_sel_i),
200
    .STB_O(eth_sl_wb_stb_i),
201
    .WE_O (eth_sl_wb_we_i),
202
    .CAB_O()       // NOT USED for now!
203
);
204
 
205
assign eth_sl_wb_adr_i = {20'h0, eth_sl_wb_adr[11:2], 2'h0};
206
 
207
 
208
 
209
// Connecting WB Slave as Memory Interface Module
210
integer memory_log_file_desc;
211
 
212
WB_SLAVE_BEHAVIORAL wb_slave
213
(
214
    .CLK_I(wb_clk),
215
    .RST_I(wb_rst),
216
    .ACK_O(eth_ma_wb_ack_i),
217
    .ADR_I(eth_ma_wb_adr_o),
218
    .CYC_I(eth_ma_wb_cyc_o),
219
    .DAT_O(eth_ma_wb_dat_i),
220
    .DAT_I(eth_ma_wb_dat_o),
221
    .ERR_O(eth_ma_wb_err_i),
222
    .RTY_O(),      // NOT USED for now!
223
    .SEL_I(eth_ma_wb_sel_o),
224
    .STB_I(eth_ma_wb_stb_o),
225
    .WE_I (eth_ma_wb_we_o),
226
    .CAB_I(1'b0)
227
);
228
 
229
 
230
 
231
// Connecting WISHBONE Bus Monitors to ethernet master and slave interfaces
232
integer wb_s_mon_log_file_desc ;
233
integer wb_m_mon_log_file_desc ;
234
 
235
WB_BUS_MON wb_eth_slave_bus_mon
236
(
237
  // WISHBONE common
238
  .CLK_I(wb_clk),
239
  .RST_I(wb_rst),
240
 
241
  // WISHBONE slave
242
  .ACK_I(eth_sl_wb_ack_o),
243
  .ADDR_O({20'h0, eth_sl_wb_adr_i[11:2], 2'b0}),
244
  .CYC_O(eth_sl_wb_cyc_i),
245
  .DAT_I(eth_sl_wb_dat_o),
246
  .DAT_O(eth_sl_wb_dat_i),
247
  .ERR_I(eth_sl_wb_err_o),
248
  .RTY_I(1'b0),
249
  .SEL_O(eth_sl_wb_sel_i),
250
  .STB_O(eth_sl_wb_stb_i),
251
  .WE_O (eth_sl_wb_we_i),
252
  .TAG_I({`WB_TAG_WIDTH{1'b0}}),
253
`ifdef ETH_WISHBONE_B3
254
  .TAG_O({eth_ma_wb_cti_o, eth_ma_wb_bte_o}),
255
`else
256
  .TAG_O(5'h0),
257
`endif
258
  .CAB_O(1'b0),
259
`ifdef ETH_WISHBONE_B3
260
  .check_CTI          (1'b1),
261
`else
262
  .check_CTI          (1'b0),
263
`endif
264
  .log_file_desc (wb_s_mon_log_file_desc)
265
);
266
 
267
WB_BUS_MON wb_eth_master_bus_mon
268
(
269
  // WISHBONE common
270
  .CLK_I(wb_clk),
271
  .RST_I(wb_rst),
272
 
273
  // WISHBONE master
274
  .ACK_I(eth_ma_wb_ack_i),
275
  .ADDR_O(eth_ma_wb_adr_o),
276
  .CYC_O(eth_ma_wb_cyc_o),
277
  .DAT_I(eth_ma_wb_dat_i),
278
  .DAT_O(eth_ma_wb_dat_o),
279
  .ERR_I(eth_ma_wb_err_i),
280
  .RTY_I(1'b0),
281
  .SEL_O(eth_ma_wb_sel_o),
282
  .STB_O(eth_ma_wb_stb_o),
283
  .WE_O (eth_ma_wb_we_o),
284
  .TAG_I({`WB_TAG_WIDTH{1'b0}}),
285
  .TAG_O(5'h0),
286
  .CAB_O(1'b0),
287
  .check_CTI(1'b0), // NO need
288
  .log_file_desc(wb_m_mon_log_file_desc)
289
);
290
 
291
 
292
 
293
reg         StartTB;
294
integer     tb_log_file;
295
 
296
initial
297
begin
298
  tb_log_file = $fopen("../log/eth_tb.log");
299
  if (tb_log_file < 2)
300
  begin
301
    $display("*E Could not open/create testbench log file in ../log/ directory!");
302
    $finish;
303
  end
304
  $fdisplay(tb_log_file, "========================== ETHERNET IP Core Testbench results ===========================");
305
  $fdisplay(tb_log_file, " ");
306
 
307
  phy_log_file_desc = $fopen("../log/eth_tb_phy.log");
308
  if (phy_log_file_desc < 2)
309
  begin
310
    $fdisplay(tb_log_file, "*E Could not open/create eth_tb_phy.log file in ../log/ directory!");
311
    $finish;
312
  end
313
  $fdisplay(phy_log_file_desc, "================ PHY Module  Testbench access log ================");
314
  $fdisplay(phy_log_file_desc, " ");
315
 
316
  memory_log_file_desc = $fopen("../log/eth_tb_memory.log");
317
  if (memory_log_file_desc < 2)
318
  begin
319
    $fdisplay(tb_log_file, "*E Could not open/create eth_tb_memory.log file in ../log/ directory!");
320
    $finish;
321
  end
322
  $fdisplay(memory_log_file_desc, "=============== MEMORY Module Testbench access log ===============");
323
  $fdisplay(memory_log_file_desc, " ");
324
 
325
  host_log_file_desc = $fopen("../log/eth_tb_host.log");
326
  if (host_log_file_desc < 2)
327
  begin
328
    $fdisplay(tb_log_file, "*E Could not open/create eth_tb_host.log file in ../log/ directory!");
329
    $finish;
330
  end
331
  $fdisplay(host_log_file_desc, "================ HOST Module Testbench access log ================");
332
  $fdisplay(host_log_file_desc, " ");
333
 
334
  wb_s_mon_log_file_desc = $fopen("../log/eth_tb_wb_s_mon.log");
335
  if (wb_s_mon_log_file_desc < 2)
336
  begin
337
    $fdisplay(tb_log_file, "*E Could not open/create eth_tb_wb_s_mon.log file in ../log/ directory!");
338
    $finish;
339
  end
340
  $fdisplay(wb_s_mon_log_file_desc, "============== WISHBONE Slave Bus Monitor error log ==============");
341
  $fdisplay(wb_s_mon_log_file_desc, " ");
342
  $fdisplay(wb_s_mon_log_file_desc, "   Only ERRONEOUS conditions are logged !");
343
  $fdisplay(wb_s_mon_log_file_desc, " ");
344
 
345
  wb_m_mon_log_file_desc = $fopen("../log/eth_tb_wb_m_mon.log");
346
  if (wb_m_mon_log_file_desc < 2)
347
  begin
348
    $fdisplay(tb_log_file, "*E Could not open/create eth_tb_wb_m_mon.log file in ../log/ directory!");
349
    $finish;
350
  end
351
  $fdisplay(wb_m_mon_log_file_desc, "============= WISHBONE Master Bus Monitor  error log =============");
352
  $fdisplay(wb_m_mon_log_file_desc, " ");
353
  $fdisplay(wb_m_mon_log_file_desc, "   Only ERRONEOUS conditions are logged !");
354
  $fdisplay(wb_m_mon_log_file_desc, " ");
355
 
356
`ifdef VCD
357
   $dumpfile("../build/sim/ethmac.vcd");
358
   $dumpvars(0);
359
`endif
360
  // Reset pulse
361
  wb_rst =  1'b1;
362
  #423 wb_rst =  1'b0;
363
 
364
  // Clear memories
365
  clear_memories;
366
  clear_buffer_descriptors;
367
 
368
  #423 StartTB  =  1'b1;
369
end
370
 
371
 
372
 
373
// Generating wb_clk clock
374
initial
375
begin
376
  wb_clk=0;
377
//  forever #2.5 wb_clk = ~wb_clk;  // 2*2.5 ns -> 200.0 MHz    
378
//  forever #5 wb_clk = ~wb_clk;  // 2*5 ns -> 100.0 MHz    
379
//  forever #10 wb_clk = ~wb_clk;  // 2*10 ns -> 50.0 MHz    
380
//  forever #12.5 wb_clk = ~wb_clk;  // 2*12.5 ns -> 40 MHz    
381
  forever #15 wb_clk = ~wb_clk;  // 2*10 ns -> 33.3 MHz    
382
//  forever #20 wb_clk = ~wb_clk;  // 2*20 ns -> 25 MHz    
383
//  forever #25 wb_clk = ~wb_clk;  // 2*25 ns -> 20.0 MHz
384
//  forever #31.25 wb_clk = ~wb_clk;  // 2*31.25 ns -> 16.0 MHz    
385
//  forever #50 wb_clk = ~wb_clk;  // 2*50 ns -> 10.0 MHz
386
//  forever #55 wb_clk = ~wb_clk;  // 2*55 ns ->  9.1 MHz    
387
end
388
 
389
 
390
 
391
integer      tests_successfull;
392
integer      tests_failed;
393
reg [799:0]  test_name; // used for tb_log_file
394
 
395
reg   [3:0]  wbm_init_waits; // initial wait cycles between CYC_O and STB_O of WB Master
396
reg   [3:0]  wbm_subseq_waits; // subsequent wait cycles between STB_Os of WB Master
397
reg   [3:0]  wbs_waits; // wait cycles befor WB Slave responds
398
reg   [7:0]  wbs_retries; // if RTY response, then this is the number of retries before ACK
399
 
400
reg          wbm_working; // tasks wbm_write and wbm_read set signal when working and reset it when stop working
401
 
402
 
403
initial
404
begin
405
  wait(StartTB);  // Start of testbench
406
 
407
  // Initial global values
408
  tests_successfull = 0;
409
  tests_failed = 0;
410
 
411
  wbm_working = 0;
412
 
413
  wbm_init_waits = 4'h1;
414
  wbm_subseq_waits = 4'h3;
415
  wbs_waits = 4'h1;
416
  wbs_retries = 8'h2;
417
  wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
418
 
419
  // set DIFFERENT mrx_clk to mtx_clk!
420
//  eth_phy.set_mrx_equal_mtx = 1'b0;
421
 
422
  //  Call tests
423
  //  ----------
424
  //  test_access_to_mac_reg(0, 4);           // 0 - 4
425
  //  test_mii(0, 17);                        // 0 - 17
426
  $display("");
427
  $display("===========================================================================");
428
  $display("PHY generates ideal Carrier sense and Collision signals for following tests");
429
  $display("===========================================================================");
430
  test_note("PHY generates ideal Carrier sense and Collision signals for following tests");
431
  eth_phy.carrier_sense_real_delay(0);
432
   if (mode == 1)   //transmit
433
     test_mac_full_duplex_transmit(23, 23);    // 0 - 23
434
   if (mode ==0)
435
     test_mac_full_duplex_receive(15, 15);     // 0 - 15
436
    if (mode ==2)
437
    test_mac_full_duplex_flow_control(5, MAC ,DMAC); // 0 - 5
438
 
439
    // Tests not working, yet.
440
    // test_mac_half_duplex_flow(0, 5);  // 0, 1, 2, 3, 4, 5 These tests need to be fixed !!!
441
 
442
    $display("");
443
    $display("===========================================================================");
444
    $display("PHY generates 'real delayed' Carrier sense and Collision signals for following tests");
445
    $display("===========================================================================");
446
    test_note("PHY generates 'real delayed' Carrier sense and Collision signals for following tests");
447
  //  eth_phy.carrier_sense_real_delay(1);
448
  //  test_mac_full_duplex_transmit(0, 23);    // 0 - 23
449
  //  test_mac_full_duplex_receive(0, 15);     // 0 - 15
450
//    test_mac_full_duplex_flow_control(0, 5); // 0 - 5
451
    //test_mac_half_duplex_flow(0, 5);
452
 
453
 
454
  // Finish test's logs
455
  test_summary;
456
  $display("\n\n END of SIMULATION");
457
  $fclose(tb_log_file | phy_log_file_desc | memory_log_file_desc | host_log_file_desc);
458
  $fclose(wb_s_mon_log_file_desc | wb_m_mon_log_file_desc);
459
 
460
  $stop;
461
end
462
 
463
 
464
 
465
//////////////////////////////////////////////////////////////
466
// Test tasks
467
//////////////////////////////////////////////////////////////
468
 
469
 
470
task test_mac_full_duplex_transmit;
471
  input  [31:0]  start_task;
472
  input  [31:0]  end_task;
473
  integer        bit_start_1;
474
  integer        bit_end_1;
475
  integer        bit_start_2;
476
  integer        bit_end_2;
477
  integer        num_of_reg;
478
  integer        num_of_frames;
479
  integer        num_of_bd;
480
  integer        i_addr;
481
  integer        i_data;
482
  integer        i_length;
483
  integer        tmp_len;
484
  integer        tmp_bd;
485
  integer        tmp_bd_num;
486
  integer        tmp_data;
487
  integer        tmp_ipgt;
488
  integer        test_num;
489
  reg    [31:0]  tx_bd_num;
490
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_data;
491
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_tmp_data;
492
  integer        i;
493
  integer        i1;
494
  integer        i2;
495
  integer        i3;
496
  integer        fail;
497
  integer        speed;
498
  reg            no_underrun;
499
  reg            frame_started;
500
  reg            frame_ended;
501
  reg            wait_for_frame;
502
  reg    [31:0]  addr;
503
  reg    [31:0]  data;
504
  reg    [31:0]  tmp;
505
  reg    [ 7:0]  st_data;
506
  reg    [15:0]  max_tmp;
507
  reg    [15:0]  min_tmp;
508
 
509
begin
510
// MAC FULL DUPLEX TRANSMIT TEST
511
test_heading("MAC FULL DUPLEX TRANSMIT TEST");
512
$display(" ");
513
$display("MAC FULL DUPLEX TRANSMIT TEST");
514
fail = 0;
515
 
516
// reset MAC registers
517
hard_reset;
518
// set wb slave response
519
wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
520
 
521
 
522
//////////////////////////////////////////////////////////////////////
523
////                                                              ////
524
////  test_mac_full_duplex_transmit:                              ////
525
////                                                              ////
526
////  0: Test no transmit when all buffers are RX ( 10Mbps ).     ////
527
////  1: Test no transmit when all buffers are RX ( 100Mbps ).    ////
528
////  2: Test transmit packets from MINFL to MAXFL sizes at       ////
529
////     one TX buffer decriptor ( 10Mbps ).                      ////
530
////  3: Test transmit packets from MINFL to MAXFL sizes at       ////
531
////     one TX buffer decriptor ( 100Mbps ).                     ////
532
////                                                              ////
533
//////////////////////////////////////////////////////////////////////
534
for (test_num = start_task; test_num <= end_task; test_num = test_num + 1)
535
begin
536
 
537
   ////////////////////////////////////////////////////////////////////
538
  ////                                                            ////
539
  ////  Test transmit packets (DELAYED CRC) from MINFL to MAXFL   ////
540
  ////  sizes at one TX buffer decriptor ( 100Mbps ).             ////
541
  ////                                                            ////
542
  ////////////////////////////////////////////////////////////////////
543
  if (test_num == 23) //
544
  begin
545
    // TEST 23: TRANSMIT PACKETS (DELAYED CRC) FROM MINFL TO MAXFL SIZES AT ONE TX BD ( 100Mbps )
546
    test_name = "TEST 23: TRANSMIT PACKETS (DELAYED CRC) FROM MINFL TO MAXFL SIZES AT ONE TX BD ( 100Mbps )";
547
    `TIME; $display("  TEST 23: TRANSMIT PACKETS (DELAYED CRC) FROM MINFL TO MAXFL SIZES AT ONE TX BD ( 100Mbps )");
548
 
549
 // set 1 RX buffer descriptor (8'h80 - 1) - must be set before RX enable
550
    wait (wbm_working == 0);
551
    wbm_write(`ETH_TX_BD_NUM, 32'h7F, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
552
    // unmask interrupts
553
    wait (wbm_working == 0);
554
    wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
555
                             `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
556
    // set 1 TX and 1 RX buffer descriptor (8'h01) - must be set before RX enable
557
    wbm_write(`ETH_TX_BD_NUM, 32'h01, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
558
    // enable RX, set full-duplex mode, NO receive small, NO correct IFG
559
    wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
560
              `ETH_MODER_PRO | `ETH_MODER_BRO | `ETH_MODER_CRCEN | `ETH_MODER_DLYCRCEN,
561
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
562
 
563
    // check WB INT signal
564
    if (wb_int !== 1'b0)
565
    begin
566
      test_fail("WB INT signal should not be set");
567
      fail = fail + 1;
568
    end
569
//set Rx descriptor
570
 
571
    max_tmp = 0;
572
    min_tmp = 0;
573
    // set one TX buffer descriptor - must be set before TX enable
574
        wait (wbm_working == 0);
575
     wbm_write(`ETH_MAC_ADDR1, 32'h0000_AA02, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Byte /, /, 0, 1 of Dest. addr.
576
     wait (wbm_working == 0);
577
     wbm_write(`ETH_MAC_ADDR0, 32'h0304_0506, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Byte 2, 3, 4. 5 of Dest. addr.
578
     wait (wbm_working == 0);
579
     wbm_write(`ETH_IPv4_L1_ADR, 32'h45020265, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Byte 2, 3, 4. 5 of Dest. addr.
580
    // prepare two packets of MAXFL length
581
    wait (wbm_working == 0);
582
    wbm_read(`ETH_PACKETLEN, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
583
    max_tmp = tmp[15:0]; // 18 bytes consists of 6B dest addr, 6B source addr, 2B type/len, 4B CRC
584
    min_tmp = tmp[31:16];
585
    st_data = 8'h5A;
586
    set_tx_packet(`MEMORY_BASE, (max_tmp), st_data); // length without CRC
587
    st_data = 8'h10;
588
    set_tx_packet((`MEMORY_BASE + max_tmp), (max_tmp), st_data); // length without CRC
589
    // check WB INT signal
590
    if (wb_int !== 1'b0)
591
    begin
592
      test_fail("WB INT signal should not be set");
593
      fail = fail + 1;
594
    end
595
 
596
    // write to phy's control register for 100Mbps
597
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
598
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
599
    speed = 100;
600
 
601
    i_length = (min_tmp - 4);
602
    while (i_length <= (max_tmp - 4))
603
    begin
604
      // choose generating carrier sense and collision
605
      case (i_length[1:0])
606
      2'h0: // Interrupt is generated
607
      begin
608
        // enable interrupt generation
609
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, (`MEMORY_BASE + i_length[1:0])); //tx_bd_num_start ,tx_bd_num_end ,len,irq,pad,crc,txpnt
610
        // unmask interrupts
611
        wait (wbm_working == 0);
612
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
613
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
614
        // not detect carrier sense in FD and no collision
615
        eth_phy.carrier_sense_tx_fd_detect(0);
616
        eth_phy.collision(0);
617
      end
618
      2'h1: // Interrupt is not generated
619
      begin
620
        // enable interrupt generation
621
        set_tx_bd(0, 0, i_length, 1'b1, 1'b1, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
622
        // mask interrupts
623
        wait (wbm_working == 0);
624
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
625
        // detect carrier sense in FD and no collision
626
        eth_phy.carrier_sense_tx_fd_detect(1);
627
        eth_phy.collision(0);
628
      end
629
      2'h2: // Interrupt is not generated
630
      begin
631
        // disable interrupt generation
632
        set_tx_bd(0, 0, i_length, 1'b0, 1'b1, 1'b1, (`MEMORY_BASE + i_length[1:0]));
633
        // unmask interrupts
634
        wait (wbm_working == 0);
635
        wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
636
                                 `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
637
        // not detect carrier sense in FD and set collision
638
        eth_phy.carrier_sense_tx_fd_detect(0);
639
        eth_phy.collision(1);
640
      end
641
      default: // 2'h3: // Interrupt is not generated
642
      begin
643
        // disable interrupt generation
644
        set_tx_bd(0, 0, i_length, 1'b0, 1'b1, 1'b1, ((`MEMORY_BASE + i_length[1:0]) + max_tmp));
645
        // mask interrupts
646
        wait (wbm_working == 0);
647
        wbm_write(`ETH_INT_MASK, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
648
        // detect carrier sense in FD and set collision
649
        eth_phy.carrier_sense_tx_fd_detect(1);
650
        eth_phy.collision(1);
651
      end
652
      endcase
653
      eth_phy.set_tx_mem_addr(max_tmp);
654
      // set wrap bit
655
      set_tx_bd_wrap(0);
656
      set_tx_bd_ready(0, 0);
657
      #1 check_tx_bd(0, data);
658
      if (i_length < min_tmp) // just first four
659
      begin
660
        while (data[15] === 1)
661
        begin
662
          #1 check_tx_bd(0, data);
663
          @(posedge wb_clk);
664
        end
665
        repeat (1) @(posedge wb_clk);
666
      end
667
      else if (i_length > (max_tmp - 8)) // just last four
668
      begin
669
        tmp = 0;
670
        wait (MTxEn === 1'b1); // start transmit
671
        while (tmp < (i_length - 20))
672
        begin
673
          #1 tmp = tmp + 1;
674
          @(posedge wb_clk);
675
        end
676
        #1 check_tx_bd(0, data);
677
        while (data[15] === 1)
678
        begin
679
          #1 check_tx_bd(0, data);
680
          @(posedge wb_clk);
681
        end
682
        repeat (1) @(posedge wb_clk);
683
      end
684
      else
685
      begin
686
        wait (MTxEn === 1'b1); // start transmit
687
        #1 check_tx_bd(0, data);
688
        if (data[15] !== 1)
689
        begin
690
          test_fail("Wrong buffer descriptor's ready bit read out from MAC");
691
          fail = fail + 1;
692
        end
693
        wait (MTxEn === 1'b0); // end transmit
694
        while (data[15] === 1)
695
        begin
696
          #1 check_tx_bd(0, data);
697
          @(posedge wb_clk);
698
        end
699
        repeat (1) @(posedge wb_clk);
700
      end
701
      // check length of a PACKET
702
           // check transmitted TX packet data
703
      if (i_length[0] == 0)
704
      begin
705
        check_tx_packet((`MEMORY_BASE + i_length[1:0]), max_tmp, i_length, tmp);
706
      end
707
      else
708
      begin
709
        check_tx_packet(((`MEMORY_BASE + i_length[1:0]) + max_tmp), max_tmp, i_length, tmp);
710
      end
711
      if (tmp > 0)
712
      begin
713
        test_fail("Wrong data of the transmitted packet");
714
        fail = fail + 1;
715
      end
716
      // check transmited TX packet CRC
717
      check_tx_crc_delayed(max_tmp, i_length, 1'b0, tmp); // length without CRC
718
      if (tmp > 0)
719
      begin
720
        test_fail("Wrong CRC of the transmitted packet");
721
        fail = fail + 1;
722
      end
723
      // check WB INT signal
724
      if (i_length[1:0] == 2'h0)
725
      begin
726
        if (wb_int !== 1'b1)
727
        begin
728
          `TIME; $display("*E WB INT signal should be set");
729
          test_fail("WB INT signal should be set");
730
          fail = fail + 1;
731
        end
732
      end
733
      else
734
      begin
735
        if (wb_int !== 1'b0)
736
        begin
737
          `TIME; $display("*E tx WB INT signal should not be set");
738
          test_fail("WB INT tx signal should not be set");
739
          fail = fail + 1;
740
        end
741
      end
742
      // check TX buffer descriptor of a packet
743
      check_tx_bd(0, data);
744
      if (i_length[1] == 1'b0) // interrupt enabled
745
      begin
746
        if (data[15:0] !== 16'h7800)
747
        begin
748
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
749
          test_fail("TX buffer descriptor status is not correct");
750
          fail = fail + 1;
751
        end
752
      end
753
      else // interrupt not enabled
754
      begin
755
        if (data[15:0] !== 16'h3800)
756
        begin
757
          `TIME; $display("*E TX buffer descriptor status is not correct: %0h", data[15:0]);
758
          test_fail("TX buffer descriptor status is not correct");
759
          fail = fail + 1;
760
        end
761
      end
762
      // clear TX buffer descriptor
763
      clear_tx_bd(0, 0);
764
      // check interrupts
765
      wait (wbm_working == 0);
766
      wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
767
      if ((i_length[1:0] == 2'h0) || (i_length[1:0] == 2'h1))
768
      begin
769
        if ((data & `ETH_INT_TXB) !== 1'b1)
770
        begin
771
          `TIME; $display("*E Interrupt Transmit Buffer was not set, interrupt reg: %0h", data);
772
          test_fail("Interrupt Transmit Buffer was not set");
773
          fail = fail + 1;
774
        end
775
        if ((data & (~`ETH_INT_TXB)) !== 0)
776
        begin
777
          `TIME; $display("*E Other interrupts (except Transmit Buffer) were set, interrupt reg: %0h", data);
778
          test_fail("Other interrupts (except Transmit Buffer) were set");
779
          fail = fail + 1;
780
        end
781
      end
782
      else
783
      begin
784
        if (data !== 0)
785
        begin
786
          `TIME; $display("*E Any of interrupts (except Transmit Buffer) was set, interrupt reg: %0h", data);
787
          test_fail("Any of interrupts (except Transmit Buffer) was set");
788
          fail = fail + 1;
789
        end
790
      end
791
      // clear interrupts
792
      wait (wbm_working == 0);
793
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
794
      // check WB INT signal
795
      if (wb_int !== 1'b0)
796
      begin
797
        test_fail("WB INT signal should not be set");
798
        fail = fail + 1;
799
      end
800
      // INTERMEDIATE DISPLAYS
801
      if ((i_length + 4) == (min_tmp + 64))
802
      begin
803
        // starting length is min_tmp, ending length is (min_tmp + 64)
804
        $display("    pads appending to packets is NOT selected");
805
        $display("    ->packets with lengths from %0d (MINFL) to %0d are checked (length increasing by 60 byte)",
806
                 min_tmp, (min_tmp + 64));
807
        // set padding, remain the rest
808
        wait (wbm_working == 0);
809
        wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN | `ETH_MODER_DLYCRCEN,
810
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
811
      end
812
      else if ((i_length + 4) == (max_tmp - 16))
813
      begin
814
        // starting length is for +128 longer than previous ending length, while ending length is tmp_data
815
        $display("    pads appending to packets is selected");
816
        $display("    ->packets with lengths from %0d to %0d are checked (length increasing by 500 bytes)",
817
                 (min_tmp + 64 + 128), tmp_data);
818
        // reset padding, remain the rest
819
        wait (wbm_working == 0);
820
        wbm_write(`ETH_MODER, `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_CRCEN | `ETH_MODER_DLYCRCEN,
821
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
822
      end
823
      else if ((i_length + 4) == max_tmp)
824
      begin
825
        $display("    pads appending to packets is NOT selected");
826
        $display("    ->packets with lengths from %0d to %0d (MAXFL) are checked (length increasing by 60 byte)",
827
                 (max_tmp - (4 + 16)), max_tmp);
828
      end
829
      // set length (loop variable)
830
      if ((i_length + 4) < (min_tmp + 64))
831
        i_length = i_length + 60;
832
      else if ( ((i_length + 4) >= (min_tmp + 64)) && ((i_length + 4) <= (max_tmp - 256)) )
833
      begin
834
        i_length = i_length + 500;
835
        tmp_data = i_length + 4; // last tmp_data is ending length
836
      end
837
      else if ( ((i_length + 4) > (max_tmp - 256)) && ((i_length + 4) < (max_tmp - 16)) )
838
        i_length = max_tmp - (4 + 16);
839
      else if ((i_length + 4) >= (max_tmp - 16))
840
        i_length = i_length + 60;
841
      else
842
      begin
843
        $display("*E TESTBENCH ERROR - WRONG PARAMETERS IN TESTBENCH");
844
        #10 $stop;
845
      end
846
    end
847
    // disable TX
848
    wait (wbm_working == 0);
849
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_PAD | `ETH_MODER_CRCEN | `ETH_MODER_DLYCRCEN,
850
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
851
    if(fail == 0)
852
      test_ok;
853
    else
854
      fail = 0;
855
  end
856
 
857
 
858
 
859
end   //  for (test_num=start_task; test_num <= end_task; test_num=test_num+1)
860
 
861
end
862
endtask // test_mac_full_duplex_transmit
863
 
864
 
865
task test_mac_full_duplex_receive;
866
  input  [31:0]  start_task;
867
  input  [31:0]  end_task;
868
  integer        bit_start_1;
869
  integer        bit_end_1;
870
  integer        bit_start_2;
871
  integer        bit_end_2;
872
  integer        num_of_reg;
873
  integer        num_of_frames;
874
  integer        num_of_bd;
875
  integer        i_addr;
876
  integer        i_data;
877
  integer        i_length;
878
  integer        tmp_len;
879
  integer        tmp_bd;
880
  integer        tmp_bd_num;
881
  integer        tmp_data;
882
  integer        tmp_ipgt;
883
  integer        test_num;
884
  reg    [31:0]  tx_bd_num;
885
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_data;
886
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_tmp_data;
887
  integer        i;
888
  integer        i1;
889
  integer        i2;
890
  integer        i3;
891
  integer        fail;
892
  integer        speed;
893
  reg            frame_started;
894
  reg            frame_ended;
895
  reg            wait_for_frame;
896
  reg            check_frame;
897
  reg            stop_checking_frame;
898
  reg            first_fr_received;
899
  reg    [31:0]  addr;
900
  reg    [31:0]  data;
901
  reg    [31:0]  tmp;
902
  reg    [ 7:0]  st_data;
903
  reg    [15:0]  max_tmp;
904
  reg    [15:0]  min_tmp;
905
begin
906
// MAC FULL DUPLEX RECEIVE TEST
907
test_heading("MAC FULL DUPLEX RECEIVE TEST");
908
$display(" ");
909
$display("MAC FULL DUPLEX RECEIVE TEST");
910
fail = 0;
911
 
912
// reset MAC registers
913
hard_reset;
914
// set wb slave response
915
wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
916
 
917
 for (test_num = start_task; test_num <= end_task; test_num = test_num + 1)
918
begin
919
 
920
  ////////////////////////////////////////////////////////////////////
921
  ////                                                            ////
922
  ////  Test no receive when all buffers are TX ( 10Mbps ).       ////
923
  ////                                                            ////
924
  ////////////////////////////////////////////////////////////////////
925
    ////////////////////////////////////////////////////////////////////
926
  ////                                                            ////
927
  ////  Test receive packets (delayed CRC) at one RX BD and       ////
928
  ////  check addresses ( 100Mbps ).                              ////
929
  ////                                                            ////
930
  ////////////////////////////////////////////////////////////////////
931
  if (test_num == 15) //
932
  begin
933
    // TEST 15: RECEIVE PACKETS (DELAYED CRC) AT ONE RX BD AND CHECK ADDRESSES ( 100Mbps )
934
    test_name   = "TEST 15: RECEIVE PACKETS (DELAYED CRC) AT ONE RX BD AND CHECK ADDRESSES ( 100Mbps )";
935
    `TIME; $display("  TEST 15: RECEIVE PACKETS (DELAYED CRC) AT ONE RX BD AND CHECK ADDRESSES ( 100Mbps )");
936
 
937
    // set 1 RX buffer descriptor (8'h80 - 1) - must be set before RX enable
938
    wait (wbm_working == 0);
939
    wbm_write(`ETH_TX_BD_NUM, 32'h7F, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
940
    // unmask interrupts
941
    wait (wbm_working == 0);
942
    wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
943
                             `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
944
    // check WB INT signal
945
    if (wb_int !== 1'b0)
946
    begin
947
      test_fail("WB INT signal should not be set");
948
      fail = fail + 1;
949
    end
950
 
951
    // write to phy's control register for 100Mbps
952
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
953
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
954
    speed = 100;
955
 
956
    num_of_frames = 0;
957
    i_length = 64;
958
    while (num_of_frames < 1)
959
    begin
960
      // not detect carrier sense in FD and no collision
961
      eth_phy.no_carrier_sense_rx_fd_detect(0);
962
      eth_phy.collision(0);
963
      case (num_of_frames)
964
      0: // unicast + PRO
965
      begin
966
        // enable interrupt generation
967
        set_rx_bd(127, 127, 1'b1, `MEMORY_BASE);
968
        // disable RX, set full-duplex mode, NO receive small, NO correct IFG
969
        wait (wbm_working == 0);
970
        wbm_write(`ETH_MODER, 32'h0,
971
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
972
        // enable RX, set full-duplex mode, NO receive small, NO correct IFG
973
        wait (wbm_working == 0);
974
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
975
                  `ETH_MODER_PRO | `ETH_MODER_BRO | `ETH_MODER_DLYCRCEN,
976
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
977
        // set Destination address - Byte 0 sent first
978
        wait (wbm_working == 0);
979
        wbm_write(`ETH_MAC_ADDR1, 32'h0000_FFCC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Byte /, /, 0, 1 of Dest. addr.
980
        wait (wbm_working == 0);
981
        wbm_write(`ETH_MAC_ADDR0, 32'hBB44_0011, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Byte 2, 3, 4. 5 of Dest. addr.
982
        // prepare packet
983
     //  st_data = 8'h0F;
984
     //   set_rx_packet_delayed_L3(0, i_length, 1'b1, 1'b0, 32'hDEAD_BEEF, 48'hAA02_0304_0506, 48'h0708_090A_0B0C, 16'h0D0E, st_data); // length without CRC
985
      //  append_rx_crc_delayed(0, i_length, 1'b0, 1'b0);
986
        $display("    Unicast packet (delayed CRC) is going to be received with PRO bit (wrap at 1st BD)");
987
      end
988
      1: // unicast + delayed CRC
989
      begin
990
        // enable interrupt generation
991
        set_rx_bd(127, 127, 1'b1, `MEMORY_BASE);
992
        // disable RX, set full-duplex mode, NO receive small, NO correct IFG
993
        wait (wbm_working == 0);
994
        wbm_write(`ETH_MODER, 32'h0,
995
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
996
        // enable RX, set full-duplex mode, NO receive small, NO correct IFG, set delayed CRC
997
        wait (wbm_working == 0);
998
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
999
                                   `ETH_MODER_BRO | `ETH_MODER_DLYCRCEN,
1000
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1001
        // set Destination address - Byte 0 sent first
1002
        wait (wbm_working == 0);
1003
        wbm_write(`ETH_MAC_ADDR1, 32'h0000_FFCC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Byte /, /, 0, 1 of Dest. addr.
1004
        wait (wbm_working == 0);
1005
        wbm_write(`ETH_MAC_ADDR0, 32'hBB44_0011, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Byte 2, 3, 4. 5 of Dest. addr.
1006
        // prepare packet
1007
      //  st_data = 8'h12;
1008
      //  set_rx_packet_delayed(0, i_length, 1'b1, 1'b0, 32'hDEAD_BEEF, 48'hAA02_0304_0506, 48'h0708_090A_0B0C, 16'h0D0E, st_data); // length without CRC
1009
     //   append_rx_crc_delayed(0, i_length, 1'b0, 1'b0);
1010
        $display("    Unicast packet (delayed CRC) is going to be received without PRO bit (wrap at 1st BD)");
1011
      end
1012
      2: // wrong unicast + PRO
1013
      begin
1014
        // enable interrupt generation
1015
        set_rx_bd(127, 127, 1'b1, `MEMORY_BASE);
1016
        // disable RX, set full-duplex mode, NO receive small, NO correct IFG
1017
        wait (wbm_working == 0);
1018
        wbm_write(`ETH_MODER, 32'h0,
1019
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1020
        // enable RX, set full-duplex mode, NO receive small, NO correct IFG
1021
        wait (wbm_working == 0);
1022
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
1023
                  `ETH_MODER_PRO | `ETH_MODER_BRO | `ETH_MODER_DLYCRCEN,
1024
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1025
        // set Destination address - Byte 0 sent first
1026
        wait (wbm_working == 0);
1027
        wbm_write(`ETH_MAC_ADDR1, 32'h0000_FFCC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Byte /, /, 0, 1 of Dest. addr.
1028
        wait (wbm_working == 0);
1029
        wbm_write(`ETH_MAC_ADDR0, 32'hBB44_0011, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Byte 2, 3, 4. 5 of Dest. addr.
1030
        // prepare packet
1031
       st_data = 8'h31;
1032
       set_rx_packet_delayed(0, i_length, 1'b1, 1'b0, 32'hDEAD_BEEF, 48'hAA02_0304_0507, 48'h0708_090A_0B0C, 16'h0D0E, st_data); // length without CRC
1033
       append_rx_crc_delayed(0, i_length, 1'b0, 1'b0);
1034
        $display("    non Unicast packet (delayed CRC) is going to be received with PRO bit (wrap at 1st BD)");
1035
      end
1036
      3: // wrong unicast
1037
      begin
1038
        // enable interrupt generation
1039
        set_rx_bd(127, 127, 1'b1, `MEMORY_BASE);
1040
        // disable RX, set full-duplex mode, NO receive small, NO correct IFG
1041
        wait (wbm_working == 0);
1042
        wbm_write(`ETH_MODER, 32'h0,
1043
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1044
        // enable RX, set full-duplex mode, NO receive small, NO correct IFG
1045
        wait (wbm_working == 0);
1046
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
1047
                                   `ETH_MODER_BRO | `ETH_MODER_DLYCRCEN,
1048
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1049
        // set Destination address - Byte 0 sent first
1050
        wait (wbm_working == 0);
1051
        wbm_write(`ETH_MAC_ADDR1, 32'h0000_FFCC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Byte /, /, 0, 1 of Dest. addr.
1052
        wait (wbm_working == 0);
1053
        wbm_write(`ETH_MAC_ADDR0, 32'hBB44_0011, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Byte 2, 3, 4. 5 of Dest. addr.
1054
        // prepare packet
1055
       st_data = 8'h0F;
1056
        set_rx_packet_delayed(0, i_length, 1'b1, 1'b0, 32'hDEAD_BEEF, 48'hAA02_0304_0507, 48'h0708_090A_0B0C, 16'h0D0E, st_data); // length without CRC
1057
        append_rx_crc_delayed(0, i_length, 1'b0, 1'b0);
1058
        $display("    non Unicast packet (delayed CRC) is NOT going to be received without PRO bit (wrap at 1st BD)");
1059
      end
1060
      4: // broadcast + PRO + ~BRO
1061
      begin
1062
        // enable interrupt generation
1063
        set_rx_bd(127, 127, 1'b1, `MEMORY_BASE);
1064
        // disable RX, set full-duplex mode, NO receive small, NO correct IFG
1065
        wait (wbm_working == 0);
1066
        wbm_write(`ETH_MODER, 32'h0,
1067
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1068
        // enable RX, set full-duplex mode, NO receive small, NO correct IFG
1069
        wait (wbm_working == 0);
1070
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
1071
                  `ETH_MODER_PRO | `ETH_MODER_DLYCRCEN,
1072
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1073
        // set Destination address - Byte 0 sent first
1074
        wait (wbm_working == 0);
1075
        wbm_write(`ETH_MAC_ADDR1, 32'h0000_FFCC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Byte /, /, 0, 1 of Dest. addr.
1076
        wait (wbm_working == 0);
1077
        wbm_write(`ETH_MAC_ADDR0, 32'hBB44_0011, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Byte 2, 3, 4. 5 of Dest. addr.
1078
        // prepare packet
1079
         st_data = 8'h84;
1080
         set_rx_packet_delayed(0, i_length, 1'b1, 1'b0, 32'hDEAD_BEEF, 48'hFFFF_FFFF_FFFF, 48'h0708_090A_0B0C, 16'hA56A, st_data); // length without CRC
1081
         append_rx_crc_delayed(0, i_length, 1'b0, 1'b0);
1082
        $display("    Broadcast packet (delayed CRC) is going to be received with PRO & without Reject_BRO bit (wrap at 1st BD)");
1083
      end
1084
      5: // broadcast       + ~BRO
1085
      begin
1086
        // enable interrupt generation
1087
        set_rx_bd(127, 127, 1'b1, `MEMORY_BASE);
1088
        // disable RX, set full-duplex mode, NO receive small, NO correct IFG
1089
        wait (wbm_working == 0);
1090
        wbm_write(`ETH_MODER, 32'h0,
1091
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1092
        // enable RX, set full-duplex mode, NO receive small, NO correct IFG
1093
        wait (wbm_working == 0);
1094
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG | `ETH_MODER_DLYCRCEN,
1095
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1096
        // set Destination address - Byte 0 sent first
1097
        wait (wbm_working == 0);
1098
        wbm_write(`ETH_MAC_ADDR1, 32'h0000_FFCC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Byte /, /, 0, 1 of Dest. addr.
1099
        wait (wbm_working == 0);
1100
        wbm_write(`ETH_MAC_ADDR0, 32'hBB44_0011, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Byte 2, 3, 4. 5 of Dest. addr.
1101
        // prepare packet
1102
         st_data = 8'h48;
1103
         set_rx_packet_delayed(0, i_length, 1'b1, 1'b0, 32'hDEAD_BEEF, 48'hFFFF_FFFF_FFFF, 48'h0708_090A_0B0C, 16'hA56A, st_data); // length without CRC
1104
         append_rx_crc_delayed(0, i_length, 1'b0, 1'b0);
1105
        $display("    Broadcast packet (delayed CRC) is going to be received without Reject_BRO bit (wrap at 1st BD)");
1106
      end
1107
      6: // broadcast + PRO + BRO
1108
      begin
1109
        // enable interrupt generation
1110
        set_rx_bd(127, 127, 1'b1, `MEMORY_BASE);
1111
        // disable RX, set full-duplex mode, NO receive small, NO correct IFG
1112
        wait (wbm_working == 0);
1113
        wbm_write(`ETH_MODER, 32'h0,
1114
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1115
        // enable RX, set full-duplex mode, NO receive small, NO correct IFG
1116
        wait (wbm_working == 0);
1117
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
1118
                  `ETH_MODER_PRO | `ETH_MODER_BRO | `ETH_MODER_DLYCRCEN,
1119
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1120
        // set Destination address - Byte 0 sent first
1121
        wait (wbm_working == 0);
1122
        wbm_write(`ETH_MAC_ADDR1, 32'h0000_FFCC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Byte /, /, 0, 1 of Dest. addr.
1123
        wait (wbm_working == 0);
1124
        wbm_write(`ETH_MAC_ADDR0, 32'hBB44_0011, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Byte 2, 3, 4. 5 of Dest. addr.
1125
        // prepare packet
1126
        st_data = 8'h30;
1127
        set_rx_packet_delayed(0, i_length, 1'b1, 1'b0, 32'hDEAD_BEEF, 48'hFFFF_FFFF_FFFF, 48'h0708_090A_0B0C, 16'hA56A, st_data); // length without CRC
1128
        append_rx_crc_delayed(0, i_length, 1'b0, 1'b0);
1129
        $display("    Broadcast packet (delayed CRC) is going to be received with PRO & with Reject_BRO bit (wrap at 1st BD)");
1130
      end
1131
      7: // broadcast       + BRO
1132
      begin
1133
        // enable interrupt generation
1134
        set_rx_bd(127, 127, 1'b1, `MEMORY_BASE);
1135
        // disable RX, set full-duplex mode, NO receive small, NO correct IFG
1136
        wait (wbm_working == 0);
1137
        wbm_write(`ETH_MODER, 32'h0,
1138
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1139
        // enable RX, set full-duplex mode, NO receive small, NO correct IFG
1140
        wait (wbm_working == 0);
1141
        wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
1142
                                   `ETH_MODER_BRO | `ETH_MODER_DLYCRCEN,
1143
                  4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1144
        // set Destination address - Byte 0 sent first
1145
        wait (wbm_working == 0);
1146
        wbm_write(`ETH_MAC_ADDR1, 32'h0000_FFCC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Byte /, /, 0, 1 of Dest. addr.
1147
        wait (wbm_working == 0);
1148
        wbm_write(`ETH_MAC_ADDR0, 32'hBB44_0011, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Byte 2, 3, 4. 5 of Dest. addr.
1149
        // prepare packet
1150
      st_data = 8'h04;
1151
      set_rx_packet_delayed(0, i_length, 1'b1, 1'b0, 32'hDEAD_BEEF, 48'hFFFF_FFFF_FFFF, 48'h0708_090A_0B0C, 16'hA56A, st_data); // length without CRC
1152
      append_rx_crc_delayed(0, i_length, 1'b0, 1'b0);
1153
        $display("    Broadcast packet (delayed CRC) is NOT going to be received with Reject_BRO bit (wrap at 1st BD)");
1154
      end
1155
      default:
1156
      begin
1157
      end
1158
      endcase
1159
      // set wrap bit
1160
      set_rx_bd_wrap(127);
1161
      set_rx_bd_empty(127, 127);
1162
      fork
1163
        begin
1164
         // #1 eth_phy.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, 8'hD5, 0, (i_length + 4), 1'b0);
1165
          repeat(10) @(posedge mrx_clk);
1166
        end
1167
        begin: wait_for_rece1
1168
          wait (MRxDV === 1'b1); // start transmit
1169
          #1 check_rx_bd(127, data);
1170
          if (data[15] !== 1)
1171
          begin
1172
            test_fail("Wrong buffer descriptor's ready bit read out from MAC");
1173
            fail = fail + 1;
1174
          end
1175
          wait (MRxDV === 1'b0); // end transmit
1176
          while (data[15] === 1)
1177
          begin
1178
            #1 check_rx_bd(127, data);
1179
            @(posedge wb_clk);
1180
          end
1181
          disable check_wait_for_rece1;
1182
          $display("    ->packet received");
1183
          repeat (1) @(posedge wb_clk);
1184
        end
1185
        begin: check_wait_for_rece1
1186
          wait (MRxDV === 1'b1); // start transmit
1187
          wait (MRxDV === 1'b0); // end transmit
1188
          repeat(10) @(posedge mrx_clk);
1189
          repeat(50) @(posedge wb_clk);
1190
          wait (wbm_working == 0);
1191
          disable wait_for_rece1;
1192
          $display("    ->packet NOT received");
1193
        end
1194
      join
1195
      // PACKET checking
1196
      wait (wbm_working == 0);
1197
      check_rx_bd(127, data);
1198
      case (num_of_frames)
1199
      0, 1, 4, 5:
1200
      begin
1201
        // check WB INT signal
1202
        if (wb_int !== 1'b1)
1203
        begin
1204
          `TIME; $display("*E WB INT signal should be set");
1205
          test_fail("WB INT signal should be set");
1206
          fail = fail + 1;
1207
        end
1208
        // check RX buffer descriptor of a packet
1209
        if (data[15:0] !== 16'h6000)
1210
        begin
1211
          `TIME; $display("*E RX buffer descriptor status is not correct: %0h", data[15:0]);
1212
          test_fail("RX buffer descriptor status is not correct");
1213
          fail = fail + 1;
1214
        end
1215
        // check length of a PACKET
1216
        if (data[31:16] != (i_length + 4))
1217
        begin
1218
          `TIME; $display("*E Wrong length of the packet out from PHY (%0d instead of %0d)",
1219
                          data[31:16], (i_length + 4));
1220
          test_fail("Wrong length of the packet out from PHY");
1221
          fail = fail + 1;
1222
        end
1223
        // check received RX packet data and CRC
1224
        check_rx_packet(0, `MEMORY_BASE, (i_length + 4), 1'b0, 1'b0, tmp);
1225
        if (tmp > 0)
1226
        begin
1227
          `TIME; $display("*E Wrong data of the received packet");
1228
          test_fail("Wrong data of the received packet");
1229
          fail = fail + 1;
1230
        end
1231
        // check interrupts
1232
        wait (wbm_working == 0);
1233
        wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1234
        if ((data & `ETH_INT_RXB) !== `ETH_INT_RXB)
1235
        begin
1236
          `TIME; $display("*E Interrupt Receive Buffer was not set, interrupt reg: %0h", data);
1237
          test_fail("Interrupt Receive Buffer was not set");
1238
          fail = fail + 1;
1239
        end
1240
        if ((data & (~`ETH_INT_RXB)) !== 0)
1241
        begin
1242
          `TIME; $display("*E Other interrupts (except Receive Buffer) were set, interrupt reg: %0h", data);
1243
          test_fail("Other interrupts (except Receive Buffer) were set");
1244
          fail = fail + 1;
1245
        end
1246
      end
1247
      2, 6:
1248
      begin
1249
        // check WB INT signal
1250
        if (wb_int !== 1'b1)
1251
        begin
1252
          `TIME; $display("*E WB INT signal should be set");
1253
          test_fail("WB INT signal should be set");
1254
          fail = fail + 1;
1255
        end
1256
        // check RX buffer descriptor of a packet
1257
        if (data[15:0] !== 16'h6080)
1258
        begin
1259
          `TIME; $display("*E RX buffer descriptor status is not correct: %0h", data[15:0]);
1260
          test_fail("RX buffer descriptor status is not correct");
1261
          fail = fail + 1;
1262
        end
1263
        // check length of a PACKET
1264
        if (data[31:16] != (i_length + 4))
1265
        begin
1266
          `TIME; $display("*E Wrong length of the packet out from PHY (%0d instead of %0d)",
1267
                          data[31:16], (i_length + 4));
1268
          test_fail("Wrong length of the packet out from PHY");
1269
          fail = fail + 1;
1270
        end
1271
        // check received RX packet data and CRC
1272
        check_rx_packet(0, `MEMORY_BASE, (i_length + 4), 1'b0, 1'b0, tmp);
1273
        if (tmp > 0)
1274
        begin
1275
          `TIME; $display("*E Wrong data of the received packet");
1276
          test_fail("Wrong data of the received packet");
1277
          fail = fail + 1;
1278
        end
1279
        // check interrupts
1280
        wait (wbm_working == 0);
1281
        wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1282
        if ((data & `ETH_INT_RXB) !== `ETH_INT_RXB)
1283
        begin
1284
          `TIME; $display("*E Interrupt Receive Buffer was not set, interrupt reg: %0h", data);
1285
          test_fail("Interrupt Receive Buffer was not set");
1286
          fail = fail + 1;
1287
        end
1288
        if ((data & (~`ETH_INT_RXB)) !== 0)
1289
        begin
1290
          `TIME; $display("*E Other interrupts (except Receive Buffer) were set, interrupt reg: %0h", data);
1291
          test_fail("Other interrupts (except Receive Buffer) were set");
1292
          fail = fail + 1;
1293
        end
1294
      end
1295
      3, 7:
1296
      begin
1297
        // check WB INT signal
1298
        if (wb_int !== 1'b0)
1299
        begin
1300
          `TIME; $display("*E WB INT signal should not be set");
1301
          test_fail("WB INT signal should not be set");
1302
          fail = fail + 1;
1303
        end
1304
        // check RX buffer descriptor of a packet
1305
        if (data[15:0] !== 16'hE000)
1306
        begin
1307
          `TIME; $display("*E RX buffer descriptor status is not correct: %0h", data[15:0]);
1308
          test_fail("RX buffer descriptor status is not correct");
1309
          fail = fail + 1;
1310
        end
1311
        // check interrupts
1312
        wait (wbm_working == 0);
1313
        wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1314
        if (data !== 0)
1315
        begin
1316
          `TIME; $display("*E Any of interrupts was set, interrupt reg: %0h, len: %0h", data, i_length[1:0]);
1317
          test_fail("Any of interrupts (except Receive Buffer) was set");
1318
          fail = fail + 1;
1319
        end
1320
      end
1321
      default:
1322
      begin
1323
      end
1324
      endcase
1325
      // clear RX buffer descriptor
1326
      clear_rx_bd(127, 127);
1327
      // clear interrupts
1328
      wait (wbm_working == 0);
1329
      wbm_write(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1330
      // check WB INT signal
1331
      if (wb_int !== 1'b0)
1332
      begin
1333
        test_fail("WB INT signal should not be set");
1334
        fail = fail + 1;
1335
      end
1336
      num_of_frames = num_of_frames + 1;
1337
    end
1338
    // disable RX
1339
    wait (wbm_working == 0);
1340
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_IFG |
1341
              `ETH_MODER_PRO | `ETH_MODER_BRO,
1342
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1343
    if(fail == 0)
1344
      test_ok;
1345
    else
1346
      fail = 0;
1347
  end
1348
 
1349
 
1350
end   //  for (test_num=start_task; test_num <= end_task; test_num=test_num+1)
1351
 
1352
end
1353
endtask // test_mac_full_duplex_receive
1354
 
1355
 
1356
 
1357
 
1358
task test_mac_full_duplex_flow_control;
1359
  input  [31:0]  start_task;
1360
  input  [63:0]  MAC ,DMAC;
1361
  integer        bit_start_1;
1362
  integer        bit_end_1;
1363
  integer        bit_start_2;
1364
  integer        bit_end_2;
1365
  integer        num_of_reg;
1366
  integer        num_of_frames;
1367
  integer        num_of_rx_frames;
1368
  integer        num_of_bd;
1369
  integer        i_addr;
1370
  integer        i_data;
1371
  integer        i_length;
1372
  integer        tmp_len;
1373
  integer        tmp_bd;
1374
  integer        tmp_bd_num;
1375
  integer        tmp_data;
1376
  integer        tmp_ipgt;
1377
  integer        test_num;
1378
  integer        rx_len;
1379
  integer        tx_len;
1380
  reg    [31:0]  tx_bd_num;
1381
  reg    [31:0]  rx_bd_num;
1382
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_data;
1383
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_tmp_data;
1384
  integer        i;
1385
  integer        i1;
1386
  integer        i2;
1387
  integer        i3;
1388
  integer        fail;
1389
  integer        speed;
1390
  integer        mac_hi_addr;
1391
  integer        mac_lo_addr;
1392
  reg            frame_started;
1393
  reg            frame_ended;
1394
  reg            wait_for_frame;
1395
  reg    [31:0]  addr;
1396
  reg    [31:0]  data;
1397
  reg    [31:0]  tmp;
1398
  reg    [ 7:0]  st_data;
1399
  reg    [15:0]  max_tmp;
1400
  reg    [15:0]  min_tmp;
1401
  reg            PassAll;
1402
  reg            RxFlow;
1403
  reg            enable_irq_in_rxbd;
1404
  reg    [15:0]  pause_value;
1405
 
1406
begin
1407
// MAC FULL DUPLEX FLOW CONTROL TEST
1408
test_heading("MAC FULL DUPLEX FLOW CONTROL TEST");
1409
$display(" ");
1410
$display("MAC FULL DUPLEX FLOW CONTROL TEST");
1411
fail = 0;
1412
 
1413
// reset MAC registers
1414
hard_reset;
1415
// set wb slave response
1416
wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
1417
 
1418
 
1419
for (test_num = start_task; test_num <= start_task; test_num = test_num + 1)
1420
begin
1421
 
1422
  ////////////////////////////////////////////////////////////////////
1423
  ////                                                            ////
1424
  ////  Random receive and transmit frames at one TX and          ////
1425
  ////  one RX buffer decriptor ( 100Mbps ).                      ////
1426
  ////                                                            ////
1427
  ////////////////////////////////////////////////////////////////////
1428
  if (test_num == 5) // 
1429
  begin
1430
    // TEST 5: RANDOM RECEIVE AND TRANSMIT FRAMES AT ONE TX AND ONE RX BD ( 100Mbps )
1431
    test_name   = "TEST 5: RANDOM RECEIVE AND TRANSMIT FRAMES AT ONE TX AND ONE RX BD ( 100Mbps )";
1432
    `TIME; $display("  TEST 5: RANDOM RECEIVE AND TRANSMIT FRAMES AT ONE TX AND ONE RX BD ( 100Mbps )");
1433
 
1434
    // unmask interrupts
1435
    wbm_write(`ETH_INT_MASK, `ETH_INT_TXB | `ETH_INT_TXE | `ETH_INT_RXB | `ETH_INT_RXE | `ETH_INT_BUSY |
1436
                             `ETH_INT_TXC | `ETH_INT_RXC, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1437
    // set 1 TX and 1 RX buffer descriptor (8'h01) - must be set before RX enable
1438
    wbm_write(`ETH_TX_BD_NUM, 32'h01, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1439
    // enable RX, set full-duplex mode, NO receive small, NO correct IFG
1440
    wbm_write(`ETH_MODER, `ETH_MODER_RXEN | `ETH_MODER_TXEN | `ETH_MODER_FULLD | `ETH_MODER_IFG |
1441
              `ETH_MODER_PRO | `ETH_MODER_BRO,
1442
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1443
    // enable flow control
1444
 
1445
    wbm_write(`ETH_CTRLMODER, `ETH_CTRLMODER_PASSALL | `ETH_CTRLMODER_RXFLOW | `ETH_CTRLMODER_TXFLOW,
1446
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1447
 
1448
         wait (wbm_working == 0);
1449
        wbm_write(`ETH_MAC_ADDR1, MAC[63:32], 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Byte /, /, 0, 1 of Dest. addr.
1450
        wait (wbm_working == 0);
1451
        wbm_write(`ETH_MAC_ADDR0, MAC[31:0], 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Byte 2, 3, 4. 5 of Dest. addr.
1452
 
1453
        wait (wbm_working == 0);
1454
        wbm_write(`ETH_DMAC_ADDR1, DMAC[63:32], 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Byte /, /, 0, 1 of Dest. addr.
1455
        wait (wbm_working == 0);
1456
        wbm_write(`ETH_DMAC_ADDR0, DMAC[31:0], 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Byte 2, 3, 4. 5 of Dest. addr.
1457
 
1458
 
1459
    // prepare one RX and one TX packet of 100 bytes long
1460
    rx_len = 100; // length of frame without CRC
1461
    st_data = 8'h1A;
1462
    set_rx_packet(200, rx_len, 1'b0, 48'h1234_5678_8765, 48'hA1B2_C3D4_E5F6, 16'hE77E, st_data);
1463
    append_rx_crc (200, rx_len, 1'b0, 1'b0); // CRC for data packet
1464
    tx_len = 73; // length of frame without CRC
1465
    st_data = 8'h01;
1466
    set_tx_packet(`MEMORY_BASE + 64, tx_len, st_data); // length without CRC
1467
    // set TX and RX Buffer Descriptors 
1468
    tx_bd_num = 0; // tx BDs go from 0 to 0
1469
    rx_bd_num = 1; // rx BDs go from 1 to 1
1470
    // check WB INT signal
1471
    if (wb_int !== 1'b0)
1472
    begin
1473
      test_fail("WB INT signal should not be set");
1474
      fail = fail + 1;
1475
    end
1476
 
1477
    // set EQUAL mrx_clk to mtx_clk!
1478
//    eth_phy.set_mrx_equal_mtx = 1'b1;
1479
 
1480
    // write to phy's control register for 100Mbps
1481
    #Tp eth_phy.control_bit14_10 = 5'b01000; // bit 13 set - speed 100
1482
    #Tp eth_phy.control_bit8_0   = 9'h1_00;  // bit 6 reset - (10/100), bit 8 set - FD
1483
    speed = 100;
1484
 
1485
    // TXB and RXB interrupts masked
1486
    wbm_write(`ETH_INT_MASK, `ETH_INT_TXE | `ETH_INT_RXE | `ETH_INT_BUSY | `ETH_INT_TXC | `ETH_INT_RXC,
1487
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1488
 
1489
    tmp_len = 0;
1490
    num_of_frames = 0;
1491
    num_of_rx_frames = 0;
1492
//    num_of_iter = 0;
1493
    // TX frame loop & RX frame loop work independently
1494
 
1495
 
1496
    fork
1497
      // TX frame loop
1498
      while (num_of_frames < 8)
1499
      begin
1500
        eth_phy.set_tx_mem_addr(64 + num_of_frames);
1501
        // set tx bd
1502
          // wait for WB master if it is working
1503
          @(posedge wb_clk);
1504
          while (wbm_working)
1505
          begin
1506
            @(posedge wb_clk);
1507
          end
1508
        set_tx_bd(0, 0, tx_len, 1'b1, 1'b1, 1'b1, (`MEMORY_BASE + 64));
1509
        set_tx_bd_wrap(0);
1510
        set_tx_bd_ready(0, 0);
1511
        check_tx_bd(0, data);
1512
        // check frame
1513
        i = 0;
1514
        while((i < 100) && (MTxEn === 1'b0)) // wait for start of TX frame!
1515
        begin
1516
          @(posedge mtx_clk);
1517
          i = i + 1;
1518
        end
1519
        if (MTxEn != 1'b1)
1520
        begin
1521
          `TIME; $display("*E Tx Frame %0d: MAC TX didn't start transmitting the packet ,MTxEn %d", num_of_frames,MTxEn);
1522
          test_fail("MAC TX didn't start transmitting the packet");
1523
          fail = fail + 1;
1524
          #10000 $stop;
1525
        end
1526
 
1527
        repeat (30) @(posedge mtx_clk); // waiting some time so PHY clears the tx_len
1528
 
1529
        wait ((MTxEn === 1'b0) /*|| (eth_phy.tx_len > (tx_len + 4))*/) // wait for end of TX frame
1530
        if (MTxEn != 1'b0)
1531
        begin
1532
          `TIME; $display("*E Tx Frame %0d: MAC TX didn't stop transmitting the packet,MTxEn %d", num_of_frames,MTxEn);
1533
          test_fail("MAC TX didn't stop transmitting the packet");
1534
          fail = fail + 1;
1535
          #10000 $stop;
1536
        end
1537
        tmp_len = eth_phy.tx_len;
1538
          // wait for WB master if it is working
1539
          @(posedge wb_clk);
1540
          while (wbm_working)
1541
          begin
1542
            @(posedge wb_clk);
1543
          end
1544
        check_tx_bd(0, data);
1545
        while (data[15] === 1)
1546
        begin
1547
            // wait for WB master if it is working
1548
            @(posedge wb_clk);
1549
            while (wbm_working)
1550
            begin
1551
              @(posedge wb_clk);
1552
            end
1553
          check_tx_bd(0, data);
1554
        end
1555
        repeat (1) @(posedge wb_clk);
1556
        // check length of a PACKET
1557
  /*      if (tmp_len != (tx_len + 4))
1558
        begin
1559
          `TIME; $display("*E Tx Frame %0d: Wrong length of the packet out from MAC (%0d instead of %0d)", num_of_frames,
1560
                          tmp_len, (tx_len + 4));
1561
          test_fail("Wrong length of the packet out from MAC");
1562
          fail = fail + 1;
1563
        end    */
1564
        // check transmitted TX packet data
1565
        check_tx_packet((`MEMORY_BASE + 64), (64 + num_of_frames), (tx_len), tmp);
1566
        if (tmp > 0)
1567
        begin
1568
          `TIME; $display("*E Tx Frame %0d: Wrong data of the transmitted packet", num_of_frames);
1569
          test_fail("Wrong data of the transmitted packet");
1570
          fail = fail + 1;
1571
        end
1572
        // check transmited TX packet CRC
1573
        check_tx_crc((64 + num_of_frames), (tx_len), 1'b0, tmp); // length without CRC
1574
        if (tmp > 0)
1575
        begin
1576
          `TIME; $display("*E Tx Frame %0d: Wrong CRC of the transmitted packet", num_of_frames);
1577
          test_fail("Wrong CRC of the transmitted packet");
1578
          fail = fail + 1;
1579
        end
1580
        // check WB INT signal
1581
        if (wb_int !== 1'b0)
1582
        begin
1583
          `TIME; $display("*E Tx Frame %0d: WB INT signal should not be set", num_of_frames);
1584
          test_fail("WB INT signal should not be set");
1585
          fail = fail + 1;
1586
        end
1587
        // check TX buffer descriptor of a packet
1588
          // wait for WB master if it is working
1589
          @(posedge wb_clk);
1590
          while (wbm_working)
1591
          begin
1592
            @(posedge wb_clk);
1593
          end
1594
        check_tx_bd(0, data);
1595
        if (data[15:0] !== 16'h7800)
1596
        begin
1597
          `TIME; $display("*E Tx Frame %0d: TX buffer descriptor status is not correct: %0h", num_of_frames, data[15:0]);
1598
          test_fail("TX buffer descriptor status is not correct");
1599
          fail = fail + 1;
1600
        end
1601
        // check interrupts
1602
          // wait for WB master if it is working
1603
          @(posedge wb_clk);
1604
          while (wbm_working)
1605
          begin
1606
            @(posedge wb_clk);
1607
          end
1608
        wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1609
        if ((data & `ETH_INT_TXB) !== `ETH_INT_TXB)
1610
        begin
1611
          `TIME; $display("*E Tx Frame %0d: Interrupt Transmit Buffer was not set, interrupt reg: %0h", num_of_frames, data);
1612
          test_fail("Interrupt Transmit Buffer was not set");
1613
          fail = fail + 1;
1614
        end
1615
        if ((data & (~(`ETH_INT_TXB | `ETH_INT_RXB))) !== 0) // RXB might occur at the same time - not error
1616
        begin
1617
          `TIME; $display("*E Tx Frame %0d: Other interrupts (except Tx and Rx Buffer) were set, interrupt reg: %0h",
1618
                          num_of_frames, data);
1619
          test_fail("Other interrupts (except Transmit Buffer) were set");
1620
          fail = fail + 1;
1621
        end
1622
        // clear interrupts (except RXB)
1623
          // wait for WB master if it is working
1624
          @(posedge wb_clk);
1625
          while (wbm_working)
1626
          begin
1627
            @(posedge wb_clk);
1628
          end
1629
        wbm_write(`ETH_INT, (data & (~`ETH_INT_RXB)), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1630
        // check WB INT signal
1631
        if (wb_int !== 1'b0)
1632
        begin
1633
          `TIME; $display("*E Tx Frame %0d: WB INT signal should not be set", num_of_frames);
1634
          test_fail("WB INT signal should not be set");
1635
          fail = fail + 1;
1636
        end
1637
        // Displays
1638
        if (num_of_frames[2:0] == 3'b111)
1639
        begin
1640
          $display("   ->8 frames transmitted");
1641
        end
1642
        // set length (loop variable)
1643
        num_of_frames = num_of_frames + 1;
1644
      end // TX frame loop
1645
      // RX frame loop
1646
      while (num_of_rx_frames < 400)
1647
      begin
1648
        // set rx bd
1649
          // wait for WB master if it is working
1650
          @(posedge wb_clk);
1651
          #1;
1652
          while (wbm_working)
1653
          begin
1654
            @(posedge wb_clk);
1655
            #1;
1656
          end
1657
        set_rx_bd(1, 1, 1'b1, (`MEMORY_BASE + 200 + num_of_rx_frames));
1658
        set_rx_bd_wrap(1);
1659
        set_rx_bd_empty(1, 1);
1660
        // check frame
1661
        fork
1662
          begin
1663
            #1 eth_phy.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, 8'hD5, 200, (rx_len + 4), 1'b0);
1664
            repeat(10) @(posedge mrx_clk);
1665
          end
1666
          begin
1667
            wait (MRxDV === 1'b1); // start receive
1668
              // wait for WB master if it is working
1669
              @(posedge wb_clk);
1670
              #1;
1671
              while (wbm_working)
1672
              begin
1673
                @(posedge wb_clk);
1674
                #1;
1675
              end
1676
            check_rx_bd(1, data);
1677
            if (data[15] !== 1)
1678
            begin
1679
              `TIME; $display("*E Rx Frame %0d: Wrong buffer descriptor's ready bit read out from MAC", num_of_rx_frames);
1680
              test_fail("Wrong buffer descriptor's ready bit read out from MAC");
1681
              fail = fail + 1;
1682
            end
1683
            wait (MRxDV === 1'b0); // end receive
1684
 
1685
            while (data[15] === 1)
1686
            begin
1687
                // wait for WB master if it is working
1688
                @(posedge wb_clk);
1689
                #1;
1690
                while (wbm_working)
1691
                begin
1692
                  @(posedge wb_clk);
1693
                  #1;
1694
                end
1695
              check_rx_bd(1, data);
1696
            end
1697
            repeat (1) @(posedge wb_clk);
1698
          end
1699
        join
1700
        // check length of a PACKET
1701
 
1702
        // Additional read because simulator was not working OK.
1703
        // wait for WB master if it is working
1704
        @(posedge wb_clk);
1705
        #1;
1706
        while (wbm_working)
1707
        begin
1708
          @(posedge wb_clk);
1709
          #1;
1710
        end
1711
        check_rx_bd(1, data);
1712
 
1713
        if (data[31:16] != (rx_len + 4))
1714
        begin
1715
          `TIME; $display("*E Rx Frame %0d: Wrong length of the packet written to MAC's register (%0d instead of %0d)",
1716
                          num_of_rx_frames, data[31:16], (rx_len + 4));
1717
          test_fail("Wrong length of the packet out from PHY");
1718
          fail = fail + 1;
1719
        end
1720
        // check received RX packet data and CRC
1721
        check_rx_packet(200, (`MEMORY_BASE + 200 + num_of_rx_frames), (rx_len + 4), 1'b0, 1'b0, tmp);
1722
        if (tmp > 0)
1723
        begin
1724
          `TIME; $display("*E Rx Frame %0d: Wrong data of the received packet", num_of_rx_frames);
1725
          test_fail("Wrong data of the received packet");
1726
          fail = fail + 1;
1727
        end
1728
        // check WB INT signal
1729
        if (wb_int !== 1'b0)
1730
        begin
1731
 
1732
           `TIME; $display("*E Rx Frame %0d: WB INT signal should not be set", num_of_rx_frames);
1733
          test_fail("WB INT signal should not be set");
1734
          fail = fail + 1;
1735
        end
1736
        // check RX buffer descriptor of a packet
1737
          // wait for WB master if it is working
1738
          @(posedge wb_clk);
1739
          #1;
1740
          while (wbm_working)
1741
          begin
1742
            @(posedge wb_clk);
1743
            #1;
1744
          end
1745
        check_rx_bd(1, data);
1746
        if (data[15:0] !== 16'h6080)
1747
        begin
1748
          `TIME; $display("*E Rx Frame %0d: RX buffer descriptor status is not correct: %0h", num_of_rx_frames, data[15:0]);
1749
          test_fail("RX buffer descriptor status is not correct");
1750
          fail = fail + 1;
1751
        end
1752
        // check interrupts
1753
          // wait for WB master if it is working
1754
          @(posedge wb_clk);
1755
          #1;
1756
          while (wbm_working)
1757
          begin
1758
            @(posedge wb_clk);
1759
            #1;
1760
          end
1761
        wbm_read(`ETH_INT, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1762
 
1763
        if ((data & `ETH_INT_RXB) !== `ETH_INT_RXB)
1764
        begin
1765
          `TIME; $display("*E Rx Frame %0d: Interrupt Receive Buffer was not set, interrupt reg: %0h",
1766
                          num_of_rx_frames, data);
1767
          test_fail("Interrupt Receive Buffer was not set");
1768
          fail = fail + 1;
1769
        end
1770
        if ((data & (~(`ETH_INT_RXB | `ETH_INT_TXB))) !== 0) // TXB might occur at the same time - not error
1771
        begin
1772
          `TIME; $display("*E Rx Frame %0d: Other interrupts (except Rx and Tx Buffer) were set, interrupt reg: %0h",
1773
                          num_of_rx_frames, data);
1774
          test_fail("Other interrupts (except Receive Buffer) were set");
1775
          fail = fail + 1;
1776
        end
1777
        // clear interrupts (except TXB)
1778
          // wait for WB master if it is working
1779
          @(posedge wb_clk);
1780
          #1;
1781
          while (wbm_working)
1782
          begin
1783
            @(posedge wb_clk);
1784
            #1;
1785
          end
1786
        wbm_write(`ETH_INT, (data & (~`ETH_INT_TXB)), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1787
        // check WB INT signal
1788
        if (wb_int !== 1'b0)
1789
        begin
1790
          `TIME; $display("*E Rx Frame %0d: WB INT signal should not be set", num_of_rx_frames);
1791
          test_fail("WB INT signal should not be set");
1792
          fail = fail + 1;
1793
        end
1794
        // Displays
1795
        if (num_of_rx_frames[2:0] == 3'b111)
1796
        begin
1797
          $display("   ->8 frames received");
1798
        end
1799
        // set length (loop variable)
1800
        num_of_rx_frames = num_of_rx_frames + 1;
1801
      end // RX frame loop
1802
    join
1803
    // disable TX & RX
1804
    wbm_write(`ETH_MODER, `ETH_MODER_FULLD | `ETH_MODER_RECSMALL | `ETH_MODER_PAD | `ETH_MODER_CRCEN |
1805
              `ETH_MODER_IFG | `ETH_MODER_PRO | `ETH_MODER_BRO,
1806
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1807
    // set DIFFERENT mrx_clk to mtx_clk!
1808
//    eth_phy.set_mrx_equal_mtx = 1'b0;
1809
    if(fail == 0)
1810
      test_ok;
1811
    else
1812
      fail = 0;
1813
  end
1814
 
1815
end   //  for (test_num=start_task; test_num <= end_task; test_num=test_num+1)
1816
 
1817
end
1818
endtask // test_mac_full_duplex_flow_control
1819
 
1820
 
1821
 
1822
//////////////////////////////////////////////////////////////
1823
// WB Behavioral Models Basic tasks
1824
//////////////////////////////////////////////////////////////
1825
 
1826
task wbm_write;
1827
  input  [31:0] address_i;
1828
  input  [((`MAX_BLK_SIZE * 32) - 1):0] data_i;
1829
  input  [3:0]  sel_i;
1830
  input  [31:0] size_i;
1831
  input  [3:0]  init_waits_i;
1832
  input  [3:0]  subseq_waits_i;
1833
 
1834
  reg `WRITE_STIM_TYPE write_data;
1835
  reg `WB_TRANSFER_FLAGS flags;
1836
  reg `WRITE_RETURN_TYPE write_status;
1837
  integer i;
1838
begin
1839
  wbm_working = 1;
1840
 
1841
  write_status = 0;
1842
 
1843
  flags                    = 0;
1844
  flags`WB_TRANSFER_SIZE   = size_i;
1845
  flags`INIT_WAITS         = init_waits_i;
1846
  flags`SUBSEQ_WAITS       = subseq_waits_i;
1847
 
1848
  write_data               = 0;
1849
  write_data`WRITE_DATA    = data_i[31:0];
1850
  write_data`WRITE_ADDRESS = address_i;
1851
  write_data`WRITE_SEL     = sel_i;
1852
 
1853
  for (i = 0; i < size_i; i = i + 1)
1854
  begin
1855
    wb_master.blk_write_data[i] = write_data;
1856
    data_i                      = data_i >> 32;
1857
    write_data`WRITE_DATA       = data_i[31:0];
1858
    write_data`WRITE_ADDRESS    = write_data`WRITE_ADDRESS + 4;
1859
  end
1860
 
1861
  wb_master.wb_block_write(flags, write_status);
1862
 
1863
  if (write_status`CYC_ACTUAL_TRANSFER !== size_i)
1864
  begin
1865
    `TIME;
1866
    $display("*E WISHBONE Master was unable to complete the requested write operation to MAC!");
1867
  end
1868
 
1869
  @(posedge wb_clk);
1870
  #3;
1871
  wbm_working = 0;
1872
  #1;
1873
end
1874
endtask // wbm_write
1875
 
1876
task wbm_read;
1877
  input  [31:0] address_i;
1878
  output [((`MAX_BLK_SIZE * 32) - 1):0] data_o;
1879
  input  [3:0]  sel_i;
1880
  input  [31:0] size_i;
1881
  input  [3:0]  init_waits_i;
1882
  input  [3:0]  subseq_waits_i;
1883
 
1884
  reg `READ_RETURN_TYPE read_data;
1885
  reg `WB_TRANSFER_FLAGS flags;
1886
  reg `READ_RETURN_TYPE read_status;
1887
  integer i;
1888
begin
1889
  wbm_working = 1;
1890
 
1891
  read_status = 0;
1892
  data_o      = 0;
1893
 
1894
  flags                  = 0;
1895
  flags`WB_TRANSFER_SIZE = size_i;
1896
  flags`INIT_WAITS       = init_waits_i;
1897
  flags`SUBSEQ_WAITS     = subseq_waits_i;
1898
 
1899
  read_data              = 0;
1900
  read_data`READ_ADDRESS = address_i;
1901
  read_data`READ_SEL     = sel_i;
1902
 
1903
  for (i = 0; i < size_i; i = i + 1)
1904
  begin
1905
    wb_master.blk_read_data_in[i] = read_data;
1906
    read_data`READ_ADDRESS        = read_data`READ_ADDRESS + 4;
1907
  end
1908
 
1909
  wb_master.wb_block_read(flags, read_status);
1910
 
1911
  if (read_status`CYC_ACTUAL_TRANSFER !== size_i)
1912
  begin
1913
    `TIME;
1914
    $display("*E WISHBONE Master was unable to complete the requested read operation from MAC!");
1915
  end
1916
 
1917
  for (i = 0; i < size_i; i = i + 1)
1918
  begin
1919
    data_o       = data_o << 32;
1920
    read_data    = wb_master.blk_read_data_out[(size_i - 1) - i]; // [31 - i];
1921
    data_o[31:0] = read_data`READ_DATA;
1922
  end
1923
 
1924
  @(posedge wb_clk);
1925
  #3;
1926
  wbm_working = 0;
1927
  #1;
1928
end
1929
endtask // wbm_read
1930
 
1931
 
1932
//////////////////////////////////////////////////////////////
1933
// Ethernet Basic tasks
1934
//////////////////////////////////////////////////////////////
1935
 
1936
task hard_reset; //  MAC registers
1937
begin
1938
  // reset MAC registers
1939
  @(posedge wb_clk);
1940
  #2 wb_rst = 1'b1;
1941
  repeat(2) @(posedge wb_clk);
1942
  #2 wb_rst = 1'b0;
1943
end
1944
endtask // hard_reset
1945
 
1946
task set_tx_bd;
1947
  input  [6:0]  tx_bd_num_start;
1948
  input  [6:0]  tx_bd_num_end;
1949
  input  [15:0] len;
1950
  input         irq;
1951
  input         pad;
1952
  input         crc;
1953
  input  [31:0] txpnt;
1954
 
1955
  integer       i;
1956
  integer       bd_status_addr, bd_ptr_addr;
1957
//  integer       buf_addr;
1958
begin
1959
  for(i = tx_bd_num_start; i <= tx_bd_num_end; i = i + 1)
1960
  begin
1961
//    buf_addr = `TX_BUF_BASE + i * 32'h600;
1962
    bd_status_addr = `TX_BD_BASE + i * 8;
1963
    bd_ptr_addr = bd_status_addr + 4;
1964
    // initialize BD - status
1965
    wait (wbm_working == 0);
1966
    wbm_write(bd_status_addr, {len, 1'b0, irq, 1'b0, pad, crc, 11'h0},
1967
              4'hF, 1, wbm_init_waits, wbm_subseq_waits); // IRQ + PAD + CRC
1968
    // initialize BD - pointer
1969
    wait (wbm_working == 0);
1970
    wbm_write(bd_ptr_addr, txpnt, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Initializing BD-pointer
1971
  end
1972
end
1973
endtask // set_tx_bd
1974
 
1975
task set_tx_bd_wrap;
1976
  input  [6:0]  tx_bd_num_end;
1977
  integer       bd_status_addr, tmp;
1978
begin
1979
  bd_status_addr = `TX_BD_BASE + tx_bd_num_end * 8;
1980
  wait (wbm_working == 0);
1981
  wbm_read(bd_status_addr, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1982
  // set wrap bit to this BD - this BD should be last-one
1983
  wait (wbm_working == 0);
1984
  wbm_write(bd_status_addr, (`ETH_TX_BD_WRAP | tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1985
end
1986
endtask // set_tx_bd_wrap
1987
 
1988
task set_tx_bd_ready;
1989
  input  [6:0]  tx_nd_num_strat;
1990
  input  [6:0]  tx_bd_num_end;
1991
  integer       i;
1992
  integer       bd_status_addr, tmp;
1993
begin
1994
  for(i = tx_nd_num_strat; i <= tx_bd_num_end; i = i + 1)
1995
  begin
1996
    bd_status_addr = `TX_BD_BASE + i * 8;
1997
    wait (wbm_working == 0);
1998
    wbm_read(bd_status_addr, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
1999
    // set empty bit to this BD - this BD should be ready
2000
    wait (wbm_working == 0);
2001
    wbm_write(bd_status_addr, (`ETH_TX_BD_READY | tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2002
  end
2003
end
2004
endtask // set_tx_bd_ready
2005
 
2006
task check_tx_bd;
2007
  input  [6:0]  tx_bd_num_end;
2008
  output [31:0] tx_bd_status;
2009
  integer       bd_status_addr, tmp;
2010
begin
2011
  bd_status_addr = `TX_BD_BASE + tx_bd_num_end * 8;
2012
  wait (wbm_working == 0);
2013
  wbm_read(bd_status_addr, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2014
  tx_bd_status = tmp;
2015
end
2016
endtask // check_tx_bd
2017
 
2018
task clear_tx_bd;
2019
  input  [6:0]  tx_nd_num_strat;
2020
  input  [6:0]  tx_bd_num_end;
2021
  integer       i;
2022
  integer       bd_status_addr, bd_ptr_addr;
2023
begin
2024
  for(i = tx_nd_num_strat; i <= tx_bd_num_end; i = i + 1)
2025
  begin
2026
    bd_status_addr = `TX_BD_BASE + i * 8;
2027
    bd_ptr_addr = bd_status_addr + 4;
2028
    // clear BD - status
2029
    wait (wbm_working == 0);
2030
    wbm_write(bd_status_addr, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2031
    // clear BD - pointer
2032
    wait (wbm_working == 0);
2033
    wbm_write(bd_ptr_addr, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2034
  end
2035
end
2036
endtask // clear_tx_bd
2037
 
2038
task set_rx_bd;
2039
  input  [6:0]  rx_bd_num_strat;
2040
  input  [6:0]  rx_bd_num_end;
2041
  input         irq;
2042
  input  [31:0] rxpnt;
2043
//  input  [6:0]  rxbd_num;
2044
  integer       i;
2045
  integer       bd_status_addr, bd_ptr_addr;
2046
//  integer       buf_addr;
2047
begin
2048
  for(i = rx_bd_num_strat; i <= rx_bd_num_end; i = i + 1)
2049
  begin
2050
//    buf_addr = `RX_BUF_BASE + i * 32'h600;
2051
//    bd_status_addr = `RX_BD_BASE + i * 8;
2052
//    bd_ptr_addr = bd_status_addr + 4; 
2053
    bd_status_addr = `TX_BD_BASE + i * 8;
2054
    bd_ptr_addr = bd_status_addr + 4;
2055
 
2056
    // initialize BD - status
2057
    wait (wbm_working == 0);
2058
//    wbm_write(bd_status_addr, 32'h0000c000, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // IRQ + PAD + CRC
2059
    wbm_write(bd_status_addr, {17'h0, irq, 14'h0},
2060
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2061
    // initialize BD - pointer
2062
    wait (wbm_working == 0);
2063
//    wbm_write(bd_ptr_addr, buf_addr, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Initializing BD-pointer
2064
    wbm_write(bd_ptr_addr, rxpnt, 4'hF, 1, wbm_init_waits, wbm_subseq_waits); // Initializing BD-pointer
2065
  end
2066
end
2067
endtask // set_rx_bd
2068
 
2069
task set_rx_bd_wrap;
2070
  input  [6:0]  rx_bd_num_end;
2071
  integer       bd_status_addr, tmp;
2072
begin
2073
//  bd_status_addr = `RX_BD_BASE + rx_bd_num_end * 8;
2074
  bd_status_addr = `TX_BD_BASE + rx_bd_num_end * 8;
2075
  wait (wbm_working == 0);
2076
  wbm_read(bd_status_addr, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2077
  // set wrap bit to this BD - this BD should be last-one
2078
  wait (wbm_working == 0);
2079
  wbm_write(bd_status_addr, (`ETH_RX_BD_WRAP | tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2080
end
2081
endtask // set_rx_bd_wrap
2082
 
2083
task set_rx_bd_empty;
2084
  input  [6:0]  rx_bd_num_strat;
2085
  input  [6:0]  rx_bd_num_end;
2086
  integer       i;
2087
  integer       bd_status_addr, tmp;
2088
begin
2089
  for(i = rx_bd_num_strat; i <= rx_bd_num_end; i = i + 1)
2090
  begin
2091
//    bd_status_addr = `RX_BD_BASE + i * 8;
2092
    bd_status_addr = `TX_BD_BASE + i * 8;
2093
    wait (wbm_working == 0);
2094
    wbm_read(bd_status_addr, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2095
    // set empty bit to this BD - this BD should be ready
2096
    wait (wbm_working == 0);
2097
    wbm_write(bd_status_addr, (`ETH_RX_BD_EMPTY | tmp), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2098
  end
2099
end
2100
endtask // set_rx_bd_empty
2101
 
2102
task check_rx_bd;
2103
  input  [6:0]  rx_bd_num_end;
2104
  output [31:0] rx_bd_status;
2105
  integer       bd_status_addr, tmp;
2106
begin
2107
//  bd_status_addr = `RX_BD_BASE + rx_bd_num_end * 8;
2108
  bd_status_addr = `TX_BD_BASE + rx_bd_num_end * 8;
2109
  wait (wbm_working == 0);
2110
  wbm_read(bd_status_addr, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2111
  rx_bd_status = tmp;
2112
end
2113
endtask // check_rx_bd
2114
 
2115
task clear_rx_bd;
2116
  input  [6:0]  rx_bd_num_strat;
2117
  input  [6:0]  rx_bd_num_end;
2118
  integer       i;
2119
  integer       bd_status_addr, bd_ptr_addr;
2120
begin
2121
  for(i = rx_bd_num_strat; i <= rx_bd_num_end; i = i + 1)
2122
  begin
2123
//    bd_status_addr = `RX_BD_BASE + i * 8;
2124
    bd_status_addr = `TX_BD_BASE + i * 8;
2125
    bd_ptr_addr = bd_status_addr + 4;
2126
    // clear BD - status
2127
    wait (wbm_working == 0);
2128
    wbm_write(bd_status_addr, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2129
    // clear BD - pointer
2130
    wait (wbm_working == 0);
2131
    wbm_write(bd_ptr_addr, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
2132
  end
2133
end
2134
endtask // clear_rx_bd
2135
 
2136
task set_tx_packet;
2137
  input  [31:0] txpnt;
2138
  input  [15:0] len;
2139
  input  [7:0]  eth_start_data;
2140
  integer       i, sd;
2141
  integer       buffer;
2142
  reg           delta_t;
2143
begin
2144
  buffer = txpnt;
2145
  sd = eth_start_data;
2146
  delta_t = 0;
2147
 
2148
  // First write might not be word allign.
2149
  if(buffer[1:0] == 1)
2150
  begin
2151
    wb_slave.wr_mem(buffer - 1, {8'h0, sd[7:0], sd[7:0] + 3'h1, sd[7:0] + 3'h2}, 4'h7);
2152
    sd = sd + 3;
2153
    i = 3;
2154
  end
2155
  else if(buffer[1:0] == 2)
2156
  begin
2157
    wb_slave.wr_mem(buffer - 2, {16'h0, sd[7:0], sd[7:0] + 3'h1}, 4'h3);
2158
    sd = sd + 2;
2159
    i = 2;
2160
  end
2161
  else if(buffer[1:0] == 3)
2162
  begin
2163
    wb_slave.wr_mem(buffer - 3, {24'h0, sd[7:0]}, 4'h1);
2164
    sd = sd + 1;
2165
    i = 1;
2166
  end
2167
  else
2168
    i = 0;
2169
  delta_t = !delta_t;
2170
 
2171
  for(i = i; i < (len - 4); i = i + 4) // Last 0-3 bytes are not written
2172
  begin
2173
    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);
2174
    sd = sd + 4;
2175
  end
2176
  delta_t = !delta_t;
2177
 
2178
  // Last word
2179
  if((len - i) == 3)
2180
  begin
2181
    wb_slave.wr_mem(buffer + i, {sd[7:0], sd[7:0] + 3'h1, sd[7:0] + 3'h2, 8'h0}, 4'hE);
2182
  end
2183
  else if((len - i) == 2)
2184
  begin
2185
    wb_slave.wr_mem(buffer + i, {sd[7:0], sd[7:0] + 3'h1, 16'h0}, 4'hC);
2186
  end
2187
  else if((len - i) == 1)
2188
  begin
2189
    wb_slave.wr_mem(buffer + i, {sd[7:0], 24'h0}, 4'h8);
2190
  end
2191
  else if((len - i) == 4)
2192
  begin
2193
    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);
2194
  end
2195
  else
2196
    $display("(%0t)(%m) ERROR", $time);
2197
  delta_t = !delta_t;
2198
end
2199
endtask // set_tx_packet
2200
 
2201
task check_tx_packet;
2202
  input  [31:0] txpnt_wb;  // source
2203
  input  [31:0] txpnt_phy; // destination
2204
  input  [15:0] len;
2205
  output [31:0] failure;
2206
  integer       i, data_wb, data_phy;
2207
  reg    [31:0] addr_wb, addr_phy;
2208
  reg    [31:0] failure;
2209
  reg           delta_t;
2210
begin
2211
  addr_wb = txpnt_wb;
2212
  addr_phy = txpnt_phy;
2213
  delta_t = 0;
2214
  failure = 0;
2215
  #1;
2216
  // First write might not be word allign.
2217
  if(addr_wb[1:0] == 1)
2218
  begin
2219
    wb_slave.rd_mem(addr_wb - 1, data_wb, 4'h7);
2220
    data_phy[31:24] = 0;
2221
    data_phy[23:16] = eth_phy.tx_mem[addr_phy[21:0]];
2222
    data_phy[15: 8] = eth_phy.tx_mem[addr_phy[21:0] + 1];
2223
    data_phy[ 7: 0] = eth_phy.tx_mem[addr_phy[21:0] + 2];
2224
    i = 3;
2225
    if (data_phy[23:0] !== data_wb[23:0])
2226
    begin
2227
      //`TIME;
2228
      //$display("*E Wrong 1. word (3 bytes) of TX packet! phy: %0h, wb: %0h", data_phy[23:0], data_wb[23:0]);
2229
      //$display("     address phy: %0h, address wb: %0h", addr_phy, addr_wb);
2230
      failure = 1;
2231
    end
2232
  end
2233
  else if (addr_wb[1:0] == 2)
2234
  begin
2235
    wb_slave.rd_mem(addr_wb - 2, data_wb, 4'h3);
2236
    data_phy[31:16] = 0;
2237
    data_phy[15: 8] = eth_phy.tx_mem[addr_phy[21:0]];
2238
    data_phy[ 7: 0] = eth_phy.tx_mem[addr_phy[21:0] + 1];
2239
    i = 2;
2240
    if (data_phy[15:0] !== data_wb[15:0])
2241
    begin
2242
      //`TIME;
2243
      //$display("*E Wrong 1. word (2 bytes) of TX packet! phy: %0h, wb: %0h", data_phy[15:0], data_wb[15:0]);
2244
      //$display("     address phy: %0h, address wb: %0h", addr_phy, addr_wb);
2245
      failure = 1;
2246
    end
2247
  end
2248
  else if (addr_wb[1:0] == 3)
2249
  begin
2250
    wb_slave.rd_mem(addr_wb - 3, data_wb, 4'h1);
2251
    data_phy[31: 8] = 0;
2252
    data_phy[ 7: 0] = eth_phy.tx_mem[addr_phy[21:0]];
2253
    i = 1;
2254
    if (data_phy[7:0] !== data_wb[7:0])
2255
    begin
2256
      //`TIME;
2257
      //$display("*E Wrong 1. word (1 byte) of TX packet! phy: %0h, wb: %0h", data_phy[7:0], data_wb[7:0]);
2258
      //$display("     address phy: %0h, address wb: %0h", addr_phy, addr_wb);
2259
      failure = 1;
2260
    end
2261
  end
2262
  else
2263
    i = 0;
2264
  delta_t = !delta_t;
2265
  #1;
2266
  for(i = i; i < (len - 4); i = i + 4) // Last 0-3 bytes are not checked
2267
  begin
2268
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hF);
2269
    data_phy[31:24] = eth_phy.tx_mem[addr_phy[21:0] + i];
2270
    data_phy[23:16] = eth_phy.tx_mem[addr_phy[21:0] + i + 1];
2271
    data_phy[15: 8] = eth_phy.tx_mem[addr_phy[21:0] + i + 2];
2272
    data_phy[ 7: 0] = eth_phy.tx_mem[addr_phy[21:0] + i + 3];
2273
 
2274
    if (data_phy[31:0] !== data_wb[31:0])
2275
    begin
2276
      //`TIME;
2277
      //$display("*E Wrong %d. word (4 bytes) of TX packet! phy: %0h, wb: %0h", ((i/4)+1), data_phy[31:0], data_wb[31:0]);
2278
      //$display("     address phy: %0h, address wb: %0h", addr_phy, addr_wb);
2279
      failure = failure + 1;
2280
    end
2281
  end
2282
  delta_t = !delta_t;
2283
  #1;
2284
  // Last word
2285
  if((len - i) == 3)
2286
  begin
2287
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hE);
2288
    data_phy[31:24] = eth_phy.tx_mem[addr_phy[21:0] + i];
2289
    data_phy[23:16] = eth_phy.tx_mem[addr_phy[21:0] + i + 1];
2290
    data_phy[15: 8] = eth_phy.tx_mem[addr_phy[21:0] + i + 2];
2291
    data_phy[ 7: 0] = 0;
2292
    if (data_phy[31:8] !== data_wb[31:8])
2293
    begin
2294
      //`TIME;
2295
      //$display("*E Wrong %d. word (3 bytes) of TX packet! phy: %0h, wb: %0h", ((i/4)+1), data_phy[31:8], data_wb[31:8]);
2296
      //$display("     address phy: %0h, address wb: %0h", addr_phy, addr_wb);
2297
      failure = failure + 1;
2298
    end
2299
  end
2300
  else if((len - i) == 2)
2301
  begin
2302
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hC);
2303
    data_phy[31:24] = eth_phy.tx_mem[addr_phy[21:0] + i];
2304
    data_phy[23:16] = eth_phy.tx_mem[addr_phy[21:0] + i + 1];
2305
    data_phy[15: 8] = 0;
2306
    data_phy[ 7: 0] = 0;
2307
    if (data_phy[31:16] !== data_wb[31:16])
2308
    begin
2309
      //`TIME;
2310
      //$display("*E Wrong %d. word (2 bytes) of TX packet! phy: %0h, wb: %0h", ((i/4)+1), data_phy[31:16], data_wb[31:16]);
2311
      //$display("     address phy: %0h, address wb: %0h", addr_phy, addr_wb);
2312
      failure = failure + 1;
2313
    end
2314
  end
2315
  else if((len - i) == 1)
2316
  begin
2317
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'h8);
2318
    data_phy[31:24] = eth_phy.tx_mem[addr_phy[21:0] + i];
2319
    data_phy[23:16] = 0;
2320
    data_phy[15: 8] = 0;
2321
    data_phy[ 7: 0] = 0;
2322
    if (data_phy[31:24] !== data_wb[31:24])
2323
    begin
2324
      //`TIME;
2325
      //$display("*E Wrong %d. word (1 byte) of TX packet! phy: %0h, wb: %0h", ((i/4)+1), data_phy[31:24], data_wb[31:24]);
2326
      //$display("     address phy: %0h, address wb: %0h", addr_phy, addr_wb);
2327
      failure = failure + 1;
2328
    end
2329
  end
2330
  else if((len - i) == 4)
2331
  begin
2332
    wb_slave.rd_mem(addr_wb + i, data_wb, 4'hF);
2333
    data_phy[31:24] = eth_phy.tx_mem[addr_phy[21:0] + i];
2334
    data_phy[23:16] = eth_phy.tx_mem[addr_phy[21:0] + i + 1];
2335
    data_phy[15: 8] = eth_phy.tx_mem[addr_phy[21:0] + i + 2];
2336
    data_phy[ 7: 0] = eth_phy.tx_mem[addr_phy[21:0] + i + 3];
2337
    if (data_phy[31:0] !== data_wb[31:0])
2338
    begin
2339
      //`TIME;
2340
      //$display("*E Wrong %d. word (4 bytes) of TX packet! phy: %0h, wb: %0h", ((i/4)+1), data_phy[31:0], data_wb[31:0]);
2341
      //$display("     address phy: %0h, address wb: %0h", addr_phy, addr_wb);
2342
      failure = failure + 1;
2343
    end
2344
  end
2345
  else
2346
    $display("(%0t)(%m) ERROR", $time);
2347
  delta_t = !delta_t;
2348
end
2349
endtask // check_tx_packet
2350
 
2351
task set_rx_packet;
2352
  input  [31:0] rxpnt;
2353
  input  [15:0] len;
2354
  input         plus_dribble_nibble; // if length is longer for one nibble
2355
  input  [47:0] eth_dest_addr;
2356
  input  [47:0] eth_source_addr;
2357
  input  [15:0] eth_type_len;
2358
  input  [7:0]  eth_start_data;
2359
  integer       i, sd;
2360
  reg    [47:0] dest_addr;
2361
  reg    [47:0] source_addr;
2362
  reg    [15:0] type_len;
2363
  reg    [21:0] buffer;
2364
  reg           delta_t;
2365
begin
2366
  buffer = rxpnt[21:0];
2367
  dest_addr = eth_dest_addr;
2368
  source_addr = eth_source_addr;
2369
  type_len = eth_type_len;
2370
  sd = eth_start_data;
2371
  delta_t = 0;
2372
  for(i = 0; i < len; i = i + 1)
2373
  begin
2374
    if (i < 6)
2375
    begin
2376
      eth_phy.rx_mem[buffer] = dest_addr[47:40];
2377
      dest_addr = dest_addr << 8;
2378
    end
2379
    else if (i < 12)
2380
    begin
2381
      eth_phy.rx_mem[buffer] = source_addr[47:40];
2382
      source_addr = source_addr << 8;
2383
    end
2384
    else if (i < 14)
2385
    begin
2386
      eth_phy.rx_mem[buffer] = type_len[15:8];
2387
      type_len = type_len << 8;
2388
    end
2389
    else
2390
    begin
2391
      eth_phy.rx_mem[buffer] = sd[7:0];
2392
      sd = sd + 1;
2393
    end
2394
    buffer = buffer + 1;
2395
  end
2396
  delta_t = !delta_t;
2397
  if (plus_dribble_nibble)
2398
    eth_phy.rx_mem[buffer] = {4'h0, 4'hD /*sd[3:0]*/};
2399
  delta_t = !delta_t;
2400
end
2401
endtask // set_rx_packet
2402
 
2403
task set_rx_packet_delayed;
2404
  input  [31:0] rxpnt;
2405
  input  [15:0] len;
2406
  input         delayed_crc;
2407
  input         plus_dribble_nibble; // if length is longer for one nibble
2408
  input  [31:0] eth_data_preamble;
2409
  input  [47:0] eth_dest_addr;
2410
  input  [47:0] eth_source_addr;
2411
  input  [15:0] eth_type_len;
2412
  input  [7:0]  eth_start_data;
2413
  integer       i, sd, start;
2414
  reg    [16:0] tmp_len;
2415
  reg    [47:0] dest_addr;
2416
  reg    [47:0] source_addr;
2417
  reg    [15:0] type_len;
2418
  reg    [21:0] buffer;
2419
  reg           delta_t;
2420
begin
2421
  buffer = rxpnt[21:0];
2422
  dest_addr = eth_dest_addr;
2423
  source_addr = eth_source_addr;
2424
  type_len = eth_type_len;
2425
  sd = eth_start_data;
2426
  delta_t = 0;
2427
 
2428
  if (delayed_crc)
2429
    begin
2430
      tmp_len = len;
2431
      start = 0;
2432
    end
2433
  else
2434
    begin
2435
      tmp_len = len+4;
2436
      start = 4;
2437
    end
2438
 
2439
  for(i = start; i < tmp_len; i = i + 1)
2440
  begin
2441
    if (i < 4)
2442
    begin
2443
      eth_phy.rx_mem[buffer] = eth_data_preamble[31:24];
2444
      eth_data_preamble = eth_data_preamble << 8;
2445
    end
2446
    else if (i < 10)
2447
    begin
2448
      eth_phy.rx_mem[buffer] = dest_addr[47:40];
2449
      dest_addr = dest_addr << 8;
2450
    end
2451
    else if (i < 16)
2452
    begin
2453
      eth_phy.rx_mem[buffer] = source_addr[47:40];
2454
      source_addr = source_addr << 8;
2455
    end
2456
    else if (i < 18)
2457
    begin
2458
      eth_phy.rx_mem[buffer] = type_len[15:8];
2459
      type_len = type_len << 8;
2460
    end
2461
    else
2462
    begin
2463
      eth_phy.rx_mem[buffer] = sd[7:0];
2464
      sd = sd + 1;
2465
    end
2466
    buffer = buffer + 1;
2467
  end
2468
  delta_t = !delta_t;
2469
  if (plus_dribble_nibble)
2470
    eth_phy.rx_mem[buffer] = {4'h0, 4'hD /*sd[3:0]*/};
2471
  delta_t = !delta_t;
2472
end
2473
endtask // set_rx_packet_delayed
2474
 
2475
task set_rx_control_packet;
2476
  input  [31:0] rxpnt;
2477
  input  [15:0] PauseTV;
2478
  integer       i;
2479
  reg    [47:0] dest_addr;
2480
  reg    [47:0] source_addr;
2481
  reg    [15:0] type_len;
2482
  reg    [21:0] buffer;
2483
  reg           delta_t;
2484
  reg    [15:0] PTV;
2485
  reg    [15:0] opcode;
2486
begin
2487
  buffer = rxpnt[21:0];
2488
  dest_addr = 48'h0180_c200_0001;
2489
  source_addr = 48'h0708_090A_0B0C;
2490
  type_len = 16'h8808;
2491
  opcode = 16'h0001;
2492
  PTV = PauseTV;
2493
  delta_t = 0;
2494
  for(i = 0; i < 60; i = i + 1)
2495
  begin
2496
    if (i < 6)
2497
    begin
2498
      eth_phy.rx_mem[buffer] = dest_addr[47:40];
2499
      dest_addr = dest_addr << 8;
2500
    end
2501
    else if (i < 12)
2502
    begin
2503
      eth_phy.rx_mem[buffer] = source_addr[47:40];
2504
      source_addr = source_addr << 8;
2505
    end
2506
    else if (i < 14)
2507
    begin
2508
      eth_phy.rx_mem[buffer] = type_len[15:8];
2509
      type_len = type_len << 8;
2510
    end
2511
    else if (i < 16)
2512
    begin
2513
      eth_phy.rx_mem[buffer] = opcode[15:8];
2514
      opcode = opcode << 8;
2515
    end
2516
    else if (i < 18)
2517
    begin
2518
      eth_phy.rx_mem[buffer] = PTV[15:8];
2519
      PTV = PTV << 8;
2520
    end
2521
    else
2522
    begin
2523
      eth_phy.rx_mem[buffer] = 0;
2524
    end
2525
    buffer = buffer + 1;
2526
  end
2527
  delta_t = !delta_t;
2528
  append_rx_crc (rxpnt, 60, 1'b0, 1'b0); // CRC for control packet
2529
end
2530
endtask // set_rx_control_packet
2531
 
2532
task set_rx_addr_type;
2533
  input  [31:0] rxpnt;
2534
  input  [47:0] eth_dest_addr;
2535
  input  [47:0] eth_source_addr;
2536
  input  [15:0] eth_type_len;
2537
  integer       i;
2538
  reg    [47:0] dest_addr;
2539
  reg    [47:0] source_addr;
2540
  reg    [15:0] type_len;
2541
  reg    [21:0] buffer;
2542
  reg           delta_t;
2543
begin
2544
  buffer = rxpnt[21:0];
2545
  dest_addr = eth_dest_addr;
2546
  source_addr = eth_source_addr;
2547
  type_len = eth_type_len;
2548
  delta_t = 0;
2549
  for(i = 0; i < 14; i = i + 1)
2550
  begin
2551
    if (i < 6)
2552
    begin
2553
      eth_phy.rx_mem[buffer] = dest_addr[47:40];
2554
      dest_addr = dest_addr << 8;
2555
    end
2556
    else if (i < 12)
2557
    begin
2558
      eth_phy.rx_mem[buffer] = source_addr[47:40];
2559
      source_addr = source_addr << 8;
2560
    end
2561
    else // if (i < 14)
2562
    begin
2563
      eth_phy.rx_mem[buffer] = type_len[15:8];
2564
      type_len = type_len << 8;
2565
    end
2566
    buffer = buffer + 1;
2567
  end
2568
  delta_t = !delta_t;
2569
end
2570
endtask // set_rx_addr_type
2571
 
2572
task check_rx_packet;
2573
  input  [31:0] rxpnt_phy; // source
2574
  input  [31:0] rxpnt_wb;  // destination
2575
  input  [15:0] len;
2576
  input         plus_dribble_nibble; // if length is longer for one nibble
2577
  input         successful_dribble_nibble; // if additional nibble is stored into memory
2578
  output [31:0] failure;
2579
  integer       i, data_wb, data_phy;
2580
  reg    [31:0] addr_wb, addr_phy;
2581
  reg    [31:0] failure;
2582
  reg    [21:0] buffer;
2583
  reg           delta_t;
2584
begin
2585
  addr_phy = rxpnt_phy;
2586
  addr_wb = rxpnt_wb;
2587
  delta_t = 0;
2588
  failure = 0;
2589
 
2590
  // First write might not be word allign.
2591
  if(addr_wb[1:0] == 1)
2592
  begin
2593
    wb_slave.rd_mem(addr_wb[21:0] - 1, data_wb, 4'h7);
2594
    data_phy[31:24] = 0;
2595
    data_phy[23:16] = eth_phy.rx_mem[addr_phy[21:0]];
2596
    data_phy[15: 8] = eth_phy.rx_mem[addr_phy[21:0] + 1];
2597
    data_phy[ 7: 0] = eth_phy.rx_mem[addr_phy[21:0] + 2];
2598
    i = 3;
2599
    if (data_phy[23:0] !== data_wb[23:0])
2600
    begin
2601
      //`TIME;
2602
      //$display("   addr_phy = %h, addr_wb = %h", rxpnt_phy, rxpnt_wb);
2603
      //$display("*E Wrong 1. word (3 bytes) of RX packet! phy = %h, wb = %h", data_phy[23:0], data_wb[23:0]);
2604
      failure = 1;
2605
    end
2606
  end
2607
  else if (addr_wb[1:0] == 2)
2608
  begin
2609
    wb_slave.rd_mem(addr_wb[21:0] - 2, data_wb, 4'h3);
2610
    data_phy[31:16] = 0;
2611
    data_phy[15: 8] = eth_phy.rx_mem[addr_phy[21:0]];
2612
    data_phy[ 7: 0] = eth_phy.rx_mem[addr_phy[21:0] + 1];
2613
    i = 2;
2614
    if (data_phy[15:0] !== data_wb[15:0])
2615
    begin
2616
      //`TIME;
2617
      //$display("   addr_phy = %h, addr_wb = %h", rxpnt_phy, rxpnt_wb);
2618
      //$display("*E Wrong 1. word (2 bytes) of RX packet! phy = %h, wb = %h", data_phy[15:0], data_wb[15:0]);
2619
      failure = 1;
2620
    end
2621
  end
2622
  else if (addr_wb[1:0] == 3)
2623
  begin
2624
    wb_slave.rd_mem(addr_wb[21:0] - 3, data_wb, 4'h1);
2625
    data_phy[31: 8] = 0;
2626
    data_phy[ 7: 0] = eth_phy.rx_mem[addr_phy[21:0]];
2627
    i = 1;
2628
    if (data_phy[7:0] !== data_wb[7:0])
2629
    begin
2630
      //`TIME;
2631
      //$display("   addr_phy = %h, addr_wb = %h", rxpnt_phy, rxpnt_wb);
2632
      //$display("*E Wrong 1. word (1 byte) of RX packet! phy = %h, wb = %h", data_phy[7:0], data_wb[7:0]);
2633
      failure = 1;
2634
    end
2635
  end
2636
  else
2637
    i = 0;
2638
  delta_t = !delta_t;
2639
 
2640
  for(i = i; i < (len - 4); i = i + 4) // Last 0-3 bytes are not checked
2641
  begin
2642
    wb_slave.rd_mem(addr_wb[21:0] + i, data_wb, 4'hF);
2643
    data_phy[31:24] = eth_phy.rx_mem[addr_phy[21:0] + i];
2644
    data_phy[23:16] = eth_phy.rx_mem[addr_phy[21:0] + i + 1];
2645
    data_phy[15: 8] = eth_phy.rx_mem[addr_phy[21:0] + i + 2];
2646
    data_phy[ 7: 0] = eth_phy.rx_mem[addr_phy[21:0] + i + 3];
2647
    if (data_phy[31:0] !== data_wb[31:0])
2648
    begin
2649
      //`TIME;
2650
      //if (i == 0)
2651
      //  $display("   addr_phy = %h, addr_wb = %h", rxpnt_phy, rxpnt_wb);
2652
      //$display("*E Wrong %0d. word (4 bytes) of RX packet! phy = %h, wb = %h", ((i/4)+1), data_phy[31:0], data_wb[31:0]);
2653
      failure = failure + 1;
2654
    end
2655
  end
2656
  delta_t = !delta_t;
2657
 
2658
  // Last word
2659
  if((len - i) == 3)
2660
  begin
2661
    wb_slave.rd_mem(addr_wb[21:0] + i, data_wb, 4'hF);
2662
    data_phy[31:24] = eth_phy.rx_mem[addr_phy[21:0] + i];
2663
    data_phy[23:16] = eth_phy.rx_mem[addr_phy[21:0] + i + 1];
2664
    data_phy[15: 8] = eth_phy.rx_mem[addr_phy[21:0] + i + 2];
2665
    if (plus_dribble_nibble)
2666
      data_phy[ 7: 0] = eth_phy.rx_mem[addr_phy[21:0] + i + 3];
2667
    else
2668
      data_phy[ 7: 0] = 0;
2669
    if (data_phy[31:8] !== data_wb[31:8])
2670
    begin
2671
      //`TIME;
2672
      //$display("*E Wrong %0d. word (3 bytes) of RX packet! phy = %h, wb = %h", ((i/4)+1), data_phy[31:8], data_wb[31:8]);
2673
      failure = failure + 1;
2674
    end
2675
    if (plus_dribble_nibble && successful_dribble_nibble)
2676
    begin
2677
      if (data_phy[3:0] !== data_wb[3:0])
2678
      begin
2679
        //`TIME;
2680
        //$display("*E Wrong dribble nibble in %0d. word (3 bytes) of RX packet!", ((i/4)+1));
2681
        failure = failure + 1;
2682
      end
2683
    end
2684
    else if (plus_dribble_nibble && !successful_dribble_nibble)
2685
    begin
2686
      if (data_phy[3:0] === data_wb[3:0])
2687
      begin
2688
        //`TIME;
2689
        //$display("*E Wrong dribble nibble in %0d. word (3 bytes) of RX packet!", ((i/4)+1));
2690
        failure = failure + 1;
2691
      end
2692
    end
2693
  end
2694
  else if((len - i) == 2)
2695
  begin
2696
    wb_slave.rd_mem(addr_wb[21:0] + i, data_wb, 4'hE);
2697
    data_phy[31:24] = eth_phy.rx_mem[addr_phy[21:0] + i];
2698
    data_phy[23:16] = eth_phy.rx_mem[addr_phy[21:0] + i + 1];
2699
    if (plus_dribble_nibble)
2700
      data_phy[15: 8] = eth_phy.rx_mem[addr_phy[21:0] + i + 2];
2701
    else
2702
      data_phy[15: 8] = 0;
2703
    data_phy[ 7: 0] = 0;
2704
    if (data_phy[31:16] !== data_wb[31:16])
2705
    begin
2706
      //`TIME;
2707
      //$display("*E Wrong %0d. word (2 bytes) of RX packet! phy = %h, wb = %h", ((i/4)+1), data_phy[31:16], data_wb[31:16]);
2708
      failure = failure + 1;
2709
    end
2710
    if (plus_dribble_nibble && successful_dribble_nibble)
2711
    begin
2712
      if (data_phy[11:8] !== data_wb[11:8])
2713
      begin
2714
        //`TIME;
2715
        //$display("*E Wrong dribble nibble in %0d. word (2 bytes) of RX packet!", ((i/4)+1));
2716
        failure = failure + 1;
2717
      end
2718
    end
2719
    else if (plus_dribble_nibble && !successful_dribble_nibble)
2720
    begin
2721
      if (data_phy[11:8] === data_wb[11:8])
2722
      begin
2723
        //`TIME;
2724
        //$display("*E Wrong dribble nibble in %0d. word (2 bytes) of RX packet!", ((i/4)+1));
2725
        failure = failure + 1;
2726
      end
2727
    end
2728
  end
2729
  else if((len - i) == 1)
2730
  begin
2731
    wb_slave.rd_mem(addr_wb[21:0] + i, data_wb, 4'hC);
2732
    data_phy[31:24] = eth_phy.rx_mem[addr_phy[21:0] + i];
2733
    if (plus_dribble_nibble)
2734
      data_phy[23:16] = eth_phy.rx_mem[addr_phy[21:0] + i + 1];
2735
    else
2736
      data_phy[23:16] = 0;
2737
    data_phy[15: 8] = 0;
2738
    data_phy[ 7: 0] = 0;
2739
    if (data_phy[31:24] !== data_wb[31:24])
2740
    begin
2741
      //`TIME;
2742
      //$display("*E Wrong %0d. word (1 byte) of RX packet! phy = %h, wb = %h", ((i/4)+1), data_phy[31:24], data_wb[31:24]);
2743
      failure = failure + 1;
2744
    end
2745
    if (plus_dribble_nibble && successful_dribble_nibble)
2746
    begin
2747
      if (data_phy[19:16] !== data_wb[19:16])
2748
      begin
2749
        //`TIME;
2750
        //$display("*E Wrong dribble nibble in %0d. word (1 byte) of RX packet!", ((i/4)+1));
2751
        failure = failure + 1;
2752
      end
2753
    end
2754
    else if (plus_dribble_nibble && !successful_dribble_nibble)
2755
    begin
2756
      if (data_phy[19:16] === data_wb[19:16])
2757
      begin
2758
        //`TIME;
2759
        //$display("*E Wrong dribble nibble in %0d. word (1 byte) of RX packet!", ((i/4)+1));
2760
        failure = failure + 1;
2761
      end
2762
    end
2763
  end
2764
  else if((len - i) == 4)
2765
  begin
2766
    wb_slave.rd_mem(addr_wb[21:0] + i, data_wb, 4'hF);
2767
    data_phy[31:24] = eth_phy.rx_mem[addr_phy[21:0] + i];
2768
    data_phy[23:16] = eth_phy.rx_mem[addr_phy[21:0] + i + 1];
2769
    data_phy[15: 8] = eth_phy.rx_mem[addr_phy[21:0] + i + 2];
2770
    data_phy[ 7: 0] = eth_phy.rx_mem[addr_phy[21:0] + i + 3];
2771
    if (data_phy[31:0] !== data_wb[31:0])
2772
    begin
2773
      //`TIME;
2774
      //$display("*E Wrong %0d. word (4 bytes) of RX packet! phy = %h, wb = %h", ((i/4)+1), data_phy[31:0], data_wb[31:0]);
2775
      failure = failure + 1;
2776
    end
2777
    if (plus_dribble_nibble)
2778
    begin
2779
      wb_slave.rd_mem(addr_wb[21:0] + i + 4, data_wb, 4'h8);
2780
      data_phy[31:24] = eth_phy.rx_mem[addr_phy[21:0] + i + 4];
2781
      if (successful_dribble_nibble)
2782
      begin
2783
        if (data_phy[27:24] !== data_wb[27:24])
2784
        begin
2785
          //`TIME;
2786
          //$display("*E Wrong dribble nibble in %0d. word (0 bytes) of RX packet!", ((i/4)+2));
2787
          failure = failure + 1;
2788
        end
2789
      end
2790
      else
2791
      begin
2792
        if (data_phy[27:24] === data_wb[27:24])
2793
        begin
2794
          //`TIME;
2795
          //$display("*E Wrong dribble nibble in %0d. word (0 bytes) of RX packet!", ((i/4)+2));
2796
          failure = failure + 1;
2797
        end
2798
      end
2799
    end
2800
  end
2801
  else
2802
    $display("(%0t)(%m) ERROR", $time);
2803
  delta_t = !delta_t;
2804
end
2805
endtask // check_rx_packet
2806
 
2807
//////////////////////////////////////////////////////////////
2808
// Ethernet CRC Basic tasks
2809
//////////////////////////////////////////////////////////////
2810
 
2811
task append_tx_crc;
2812
  input  [31:0] txpnt_wb;  // source
2813
  input  [15:0] len; // length in bytes without CRC
2814
  input         negated_crc; // if appended CRC is correct or not
2815
  reg    [31:0] crc;
2816
  reg    [31:0] addr_wb;
2817
  reg           delta_t;
2818
begin
2819
  addr_wb = txpnt_wb + {16'h0, len};
2820
  delta_t = 0;
2821
  // calculate CRC from prepared packet
2822
  paralel_crc_mac(txpnt_wb, {16'h0, len}, 1'b0, crc);
2823
  if (negated_crc)
2824
    crc = ~crc;
2825
  delta_t = !delta_t;
2826
 
2827
  // Write might not be word allign.
2828
  if (addr_wb[1:0] == 1)
2829
  begin
2830
    wb_slave.wr_mem(addr_wb - 1, {8'h0, crc[7:0], crc[15:8], crc[23:16]}, 4'h7);
2831
    wb_slave.wr_mem(addr_wb + 3, {crc[31:24], 24'h0}, 4'h8);
2832
  end
2833
  else if (addr_wb[1:0] == 2)
2834
  begin
2835
    wb_slave.wr_mem(addr_wb - 2, {16'h0, crc[7:0], crc[15:8]}, 4'h3);
2836
    wb_slave.wr_mem(addr_wb + 2, {crc[23:16], crc[31:24], 16'h0}, 4'hC);
2837
  end
2838
  else if (addr_wb[1:0] == 3)
2839
  begin
2840
    wb_slave.wr_mem(addr_wb - 3, {24'h0, crc[7:0]}, 4'h1);
2841
    wb_slave.wr_mem(addr_wb + 1, {crc[15:8], crc[23:16], crc[31:24], 8'h0}, 4'hE);
2842
  end
2843
  else
2844
  begin
2845
//    wb_slave.wr_mem(addr_wb, {crc[7:0], crc[15:8], crc[23:16], crc[31:24]}, 4'hF);
2846
    wb_slave.wr_mem(addr_wb, crc[31:0], 4'hF);
2847
  end
2848
  delta_t = !delta_t;
2849
end
2850
endtask // append_tx_crc
2851
 
2852
task check_tx_crc; // used to check crc added to TX packets by MAC
2853
  input  [31:0] txpnt_phy; // destination
2854
  input  [15:0] len; // length in bytes without CRC
2855
  input         negated_crc; // if appended CRC is correct or not
2856
  output [31:0] failure;
2857
  reg    [31:0] failure;
2858
  reg    [31:0] crc_calc;
2859
  reg    [31:0] crc;
2860
  reg    [31:0] addr_phy;
2861
  reg           delta_t;
2862
begin
2863
  addr_phy = txpnt_phy;
2864
  failure = 0;
2865
  // calculate CRC from sent packet
2866
//  serial_crc_phy_tx(addr_phy, {16'h0, len}, 1'b0, crc_calc);
2867
//#10;
2868
  paralel_crc_phy_tx(addr_phy, {16'h0, len}, 1'b0, crc_calc);
2869
  #1;
2870
  addr_phy = addr_phy + len;
2871
  // Read CRC - BIG endian
2872
  crc[31:24] = eth_phy.tx_mem[addr_phy[21:0]];
2873
  crc[23:16] = eth_phy.tx_mem[addr_phy[21:0] + 1];
2874
  crc[15: 8] = eth_phy.tx_mem[addr_phy[21:0] + 2];
2875
  crc[ 7: 0] = eth_phy.tx_mem[addr_phy[21:0] + 3];
2876
 
2877
  delta_t = !delta_t;
2878
  if (negated_crc)
2879
  begin
2880
    if ((~crc_calc) !== crc)
2881
    begin
2882
      `TIME;
2883
      $display("*E Negated CRC was not successfuly transmitted!");
2884
      failure = failure + 1;
2885
    end
2886
  end
2887
  else
2888
  begin
2889
    if (crc_calc !== crc)
2890
    begin
2891
      `TIME;
2892
      $display("*E Transmitted CRC was not correct; crc_calc: %0h, crc_mem: %0h", crc_calc, crc);
2893
      failure = failure + 1;
2894
    end
2895
  end
2896
  delta_t = !delta_t;
2897
end
2898
endtask // check_tx_crc
2899
 
2900
task check_tx_crc_delayed; // used to check crc added to TX packets by MAC
2901
  input  [31:0] txpnt_phy; // destination
2902
  input  [15:0] len; // length in bytes without CRC
2903
  input         negated_crc; // if appended CRC is correct or not
2904
  output [31:0] failure;
2905
  reg    [31:0] failure;
2906
  reg    [31:0] crc_calc;
2907
  reg    [31:0] crc;
2908
  reg    [31:0] addr_phy;
2909
  reg           delta_t;
2910
begin
2911
  addr_phy = txpnt_phy;
2912
  failure = 0;
2913
  // calculate CRC from sent packet
2914
//  serial_crc_phy_tx(addr_phy, {16'h0, len}, 1'b0, crc_calc);
2915
//#10;
2916
  paralel_crc_phy_tx(addr_phy+4, {16'h0, len}-4, 1'b0, crc_calc);
2917
  #1;
2918
  addr_phy = addr_phy + len;
2919
  // Read CRC - BIG endian
2920
  crc[31:24] = eth_phy.tx_mem[addr_phy[21:0]];
2921
  crc[23:16] = eth_phy.tx_mem[addr_phy[21:0] + 1];
2922
  crc[15: 8] = eth_phy.tx_mem[addr_phy[21:0] + 2];
2923
  crc[ 7: 0] = eth_phy.tx_mem[addr_phy[21:0] + 3];
2924
 
2925
  delta_t = !delta_t;
2926
  if (negated_crc)
2927
  begin
2928
    if ((~crc_calc) !== crc)
2929
    begin
2930
      `TIME;
2931
      $display("*E Negated CRC was not successfuly transmitted!");
2932
      failure = failure + 1;
2933
    end
2934
  end
2935
  else
2936
  begin
2937
    if (crc_calc !== crc)
2938
    begin
2939
      `TIME;
2940
      $display("*E Transmitted CRC was not correct; crc_calc: %0h, crc_mem: %0h", crc_calc, crc);
2941
      failure = failure + 1;
2942
    end
2943
  end
2944
  delta_t = !delta_t;
2945
end
2946
endtask // check_tx_crc_delayed
2947
 
2948
task set_rx_packet_delayed_L3;
2949
  input  [31:0] rxpnt;
2950
  input  [15:0] len;
2951
  input         delayed_crc;
2952
  input         plus_dribble_nibble; // if length is longer for one nibble
2953
  input  [31:0] eth_data_preamble;
2954
  input  [47:0] eth_dest_addr;
2955
  input  [47:0] eth_source_addr;
2956
  input  [15:0] eth_type_len;
2957
  input  [7:0]  eth_start_data;
2958
  integer       i, sd, start ;
2959
  reg    [16:0] tmp_len;
2960
  reg    [47:0] dest_addr;
2961
  reg    [47:0] source_addr;
2962
  reg    [3:0]  vlan;
2963
  reg    [3:0]  prio;
2964
  reg    [15:0] ethertype;
2965
  reg    [3:0]  ipv4_version;
2966
  reg    [3:0]  ipv4_HLEN;
2967
  reg    [15:0] type_len;
2968
  reg    [21:0] buffer;
2969
  reg           delta_t;
2970
  reg    [15:0] tot_len;
2971
  reg    [7:0] ttl;
2972
  reg    [7:0] protocol;
2973
  reg    [15:0] Header_CheckSum;
2974
  reg    [31:0] Source_IP;
2975
  reg    [31:0] Dest_IP;
2976
  reg    [31:0] identification;
2977
begin
2978
  buffer = rxpnt[21:0];
2979
  dest_addr = eth_dest_addr;
2980
  source_addr = eth_source_addr;
2981
  type_len = eth_type_len;
2982
  sd = eth_start_data;
2983
  tot_len = 16'h21c; // len + 20;
2984
  delta_t = 0;
2985
  vlan=4'h1;
2986
  prio = 4'h0;
2987
  ethertype = 16'h800;
2988
  ipv4_version = 4'h4;
2989
  ipv4_HLEN = 4'h5;
2990
  ttl = 8'hff;
2991
  identification = 32'h3;
2992
  protocol = 8'h11;
2993
  Header_CheckSum = 16'heda8;
2994
  Source_IP = 32'he8f9d0bf;
2995
  Dest_IP = 32'hc1a850c1;
2996
  if (delayed_crc)
2997
    begin
2998
      tmp_len = len;
2999
      start = 0;
3000
    end
3001
  else
3002
    begin
3003
      tmp_len = len+4;
3004
      start = 4;
3005
    end
3006
 
3007
  for(i = start; i < tmp_len; i = i + 1)
3008
  begin
3009
    if (i < 4)
3010
    begin
3011
      eth_phy.rx_mem[buffer] = eth_data_preamble[31:24];
3012
      eth_data_preamble = eth_data_preamble << 8;
3013
    end
3014
    else if (i < 10)
3015
    begin
3016
      eth_phy.rx_mem[buffer] = dest_addr[47:40];
3017
      dest_addr = dest_addr << 8;
3018
    end
3019
    else if (i < 16)
3020
    begin
3021
      eth_phy.rx_mem[buffer] = source_addr[47:40];
3022
      source_addr = source_addr << 8;
3023
    end
3024
    else if (i < 18)
3025
    begin
3026
      eth_phy.rx_mem[buffer] = type_len[15:8];
3027
      type_len = type_len << 8;
3028
    end
3029
    else if (i < 19)
3030
    begin
3031
      eth_phy.rx_mem[buffer] = {prio,vlan};          // 0x01
3032
    end
3033
    else if (i < 21)
3034
      begin
3035
          eth_phy.rx_mem[buffer] = ethertype[15:8] ;   //  0x800
3036
          ethertype = ethertype << 8;
3037
      end
3038
    else if (i < 22)
3039
      begin
3040
          eth_phy.rx_mem[buffer] = {ipv4_version,ipv4_HLEN};  // Version = 4 (ipv4) +HLEN = 5
3041
      end
3042
     else if (i < 23)
3043
         begin
3044
            eth_phy.rx_mem[buffer] = 8'h2; //TOS
3045
         end
3046
         else if (i < 25)
3047
         begin
3048
           eth_phy.rx_mem[buffer] = tot_len[15:8];     // ipv4+payload    length
3049
            tot_len = tot_len << 8;
3050
         end
3051
          else if (i < 29)
3052
         begin
3053
           eth_phy.rx_mem[buffer] = identification[31:24];        //identification+flag+fragment
3054
           identification = identification << 8;
3055
         end
3056
          else if (i < 30)
3057
         begin
3058
           eth_phy.rx_mem[buffer] = ttl[7:0];
3059
         end
3060
         else if (i < 31)
3061
         begin
3062
           eth_phy.rx_mem[buffer] = protocol[7:0];        //11 - udp
3063
         end
3064
          else if (i < 33)
3065
         begin
3066
           eth_phy.rx_mem[buffer] = Header_CheckSum[15:8];
3067
           Header_CheckSum = Header_CheckSum << 8;
3068
         end
3069
          else if (i < 37)
3070
         begin
3071
           eth_phy.rx_mem[buffer] = Source_IP[31:24];
3072
           Source_IP = Source_IP << 8;
3073
         end
3074
         else if (i < 41)
3075
         begin
3076
           eth_phy.rx_mem[buffer] = Dest_IP[31:24];
3077
           Dest_IP = Dest_IP << 8;
3078
         end
3079
 
3080
    else
3081
    begin
3082
      eth_phy.rx_mem[buffer] = sd[7:0];
3083
      sd = sd + 1;
3084
    end
3085
    buffer = buffer + 1;
3086
  end
3087
  delta_t = !delta_t;
3088
  if (plus_dribble_nibble)
3089
    eth_phy.rx_mem[buffer] = {4'h0, 4'hD /*sd[3:0]*/};
3090
  delta_t = !delta_t;
3091
end
3092
endtask // set_rx_packet_delayed_L3
3093
 
3094
 
3095
task append_rx_crc;
3096
  input  [31:0] rxpnt_phy; // source
3097
  input  [15:0] len; // length in bytes without CRC
3098
  input         plus_dribble_nibble; // if length is longer for one nibble
3099
  input         negated_crc; // if appended CRC is correct or not
3100
  reg    [31:0] crc;
3101
  reg    [7:0]  tmp;
3102
  reg    [31:0] addr_phy;
3103
  reg           delta_t;
3104
begin
3105
  addr_phy = rxpnt_phy + len;
3106
  delta_t = 0;
3107
  // calculate CRC from prepared packet
3108
  paralel_crc_phy_rx(rxpnt_phy, {16'h0, len}, plus_dribble_nibble, crc);
3109
  if (negated_crc)
3110
    crc = ~crc;
3111
  delta_t = !delta_t;
3112
 
3113
  if (plus_dribble_nibble)
3114
  begin
3115
    tmp = eth_phy.rx_mem[addr_phy];
3116
    eth_phy.rx_mem[addr_phy]     = {crc[27:24], tmp[3:0]};
3117
    eth_phy.rx_mem[addr_phy + 1] = {crc[19:16], crc[31:28]};
3118
    eth_phy.rx_mem[addr_phy + 2] = {crc[11:8], crc[23:20]};
3119
    eth_phy.rx_mem[addr_phy + 3] = {crc[3:0], crc[15:12]};
3120
    eth_phy.rx_mem[addr_phy + 4] = {4'h0, crc[7:4]};
3121
  end
3122
  else
3123
  begin
3124
    eth_phy.rx_mem[addr_phy]     = crc[31:24];
3125
    eth_phy.rx_mem[addr_phy + 1] = crc[23:16];
3126
    eth_phy.rx_mem[addr_phy + 2] = crc[15:8];
3127
    eth_phy.rx_mem[addr_phy + 3] = crc[7:0];
3128
  end
3129
end
3130
endtask // append_rx_crc
3131
 
3132
task append_rx_crc_delayed;
3133
  input  [31:0] rxpnt_phy; // source
3134
  input  [15:0] len; // length in bytes without CRC
3135
  input         plus_dribble_nibble; // if length is longer for one nibble
3136
  input         negated_crc; // if appended CRC is correct or not
3137
  reg    [31:0] crc;
3138
  reg    [7:0]  tmp;
3139
  reg    [31:0] addr_phy;
3140
  reg           delta_t;
3141
begin
3142
  addr_phy = rxpnt_phy + len;
3143
  delta_t = 0;
3144
  // calculate CRC from prepared packet
3145
  paralel_crc_phy_rx(rxpnt_phy+4, {16'h0, len}-4, plus_dribble_nibble, crc);
3146
  if (negated_crc)
3147
    crc = ~crc;
3148
  delta_t = !delta_t;
3149
 
3150
  if (plus_dribble_nibble)
3151
  begin
3152
    tmp = eth_phy.rx_mem[addr_phy];
3153
    eth_phy.rx_mem[addr_phy]     = {crc[27:24], tmp[3:0]};
3154
    eth_phy.rx_mem[addr_phy + 1] = {crc[19:16], crc[31:28]};
3155
    eth_phy.rx_mem[addr_phy + 2] = {crc[11:8], crc[23:20]};
3156
    eth_phy.rx_mem[addr_phy + 3] = {crc[3:0], crc[15:12]};
3157
    eth_phy.rx_mem[addr_phy + 4] = {4'h0, crc[7:4]};
3158
  end
3159
  else
3160
  begin
3161
    eth_phy.rx_mem[addr_phy]     = crc[31:24];
3162
    eth_phy.rx_mem[addr_phy + 1] = crc[23:16];
3163
    eth_phy.rx_mem[addr_phy + 2] = crc[15:8];
3164
    eth_phy.rx_mem[addr_phy + 3] = crc[7:0];
3165
  end
3166
end
3167
endtask // append_rx_crc_delayed
3168
 
3169
// paralel CRC checking for PHY TX
3170
task paralel_crc_phy_tx;
3171
  input  [31:0] start_addr; // start address
3172
  input  [31:0] len; // length of frame in Bytes without CRC length
3173
  input         plus_dribble_nibble; // if length is longer for one nibble
3174
  output [31:0] crc_out;
3175
  reg    [21:0] addr_cnt; // only 22 address lines
3176
  integer       word_cnt;
3177
  integer       nibble_cnt;
3178
  reg    [31:0] load_reg;
3179
  reg           delta_t;
3180
  reg    [31:0] crc_next;
3181
  reg    [31:0] crc;
3182
  reg           crc_error;
3183
  reg     [3:0] data_in;
3184
  integer       i;
3185
begin
3186
  #1 addr_cnt = start_addr[21:0];
3187
  word_cnt = 24; // 27; // start of the frame - nibble granularity (MSbit first)
3188
  crc = 32'hFFFF_FFFF; // INITIAL value
3189
  delta_t = 0;
3190
  // length must include 4 bytes of ZEROs, to generate CRC
3191
  // get number of nibbles from Byte length (2^1 = 2)
3192
  if (plus_dribble_nibble)
3193
    nibble_cnt = ((len + 4) << 1) + 1'b1; // one nibble longer
3194
  else
3195
    nibble_cnt = ((len + 4) << 1);
3196
  // because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3]
3197
  load_reg[31:24] = eth_phy.tx_mem[addr_cnt];
3198
  addr_cnt = addr_cnt + 1;
3199
  load_reg[23:16] = eth_phy.tx_mem[addr_cnt];
3200
  addr_cnt = addr_cnt + 1;
3201
  load_reg[15: 8] = eth_phy.tx_mem[addr_cnt];
3202
  addr_cnt = addr_cnt + 1;
3203
  load_reg[ 7: 0] = eth_phy.tx_mem[addr_cnt];
3204
  addr_cnt = addr_cnt + 1;
3205
  while (nibble_cnt > 0)
3206
  begin
3207
    // wait for delta time
3208
    delta_t = !delta_t;
3209
    // shift data in
3210
 
3211
    if(nibble_cnt <= 8) // for additional 8 nibbles shift ZEROs in!
3212
      data_in[3:0] = 4'h0;
3213
    else
3214
 
3215
      data_in[3:0] = {load_reg[word_cnt], load_reg[word_cnt+1], load_reg[word_cnt+2], load_reg[word_cnt+3]};
3216
    crc_next[0]  = (data_in[0] ^ crc[28]);
3217
    crc_next[1]  = (data_in[1] ^ data_in[0] ^ crc[28]    ^ crc[29]);
3218
    crc_next[2]  = (data_in[2] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[30]);
3219
    crc_next[3]  = (data_in[3] ^ data_in[2] ^ data_in[1] ^ crc[29]  ^ crc[30] ^ crc[31]);
3220
    crc_next[4]  = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[0];
3221
    crc_next[5]  = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[1];
3222
    crc_next[6]  = (data_in[2] ^ data_in[1] ^ crc[29]    ^ crc[30]) ^ crc[ 2];
3223
    crc_next[7]  = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[3];
3224
    crc_next[8]  = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[4];
3225
    crc_next[9]  = (data_in[2] ^ data_in[1] ^ crc[29]    ^ crc[30]) ^ crc[5];
3226
    crc_next[10] = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[6];
3227
    crc_next[11] = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[7];
3228
    crc_next[12] = (data_in[2] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[30]) ^ crc[8];
3229
    crc_next[13] = (data_in[3] ^ data_in[2] ^ data_in[1] ^ crc[29]  ^ crc[30] ^ crc[31]) ^ crc[9];
3230
    crc_next[14] = (data_in[3] ^ data_in[2] ^ crc[30]    ^ crc[31]) ^ crc[10];
3231
    crc_next[15] = (data_in[3] ^ crc[31])   ^ crc[11];
3232
    crc_next[16] = (data_in[0] ^ crc[28])   ^ crc[12];
3233
    crc_next[17] = (data_in[1] ^ crc[29])   ^ crc[13];
3234
    crc_next[18] = (data_in[2] ^ crc[30])   ^ crc[14];
3235
    crc_next[19] = (data_in[3] ^ crc[31])   ^ crc[15];
3236
    crc_next[20] =  crc[16];
3237
    crc_next[21] =  crc[17];
3238
    crc_next[22] = (data_in[0] ^ crc[28])   ^ crc[18];
3239
    crc_next[23] = (data_in[1] ^ data_in[0] ^ crc[29]    ^ crc[28]) ^ crc[19];
3240
    crc_next[24] = (data_in[2] ^ data_in[1] ^ crc[30]    ^ crc[29]) ^ crc[20];
3241
    crc_next[25] = (data_in[3] ^ data_in[2] ^ crc[31]    ^ crc[30]) ^ crc[21];
3242
    crc_next[26] = (data_in[3] ^ data_in[0] ^ crc[31]    ^ crc[28]) ^ crc[22];
3243
    crc_next[27] = (data_in[1] ^ crc[29])   ^ crc[23];
3244
    crc_next[28] = (data_in[2] ^ crc[30])   ^ crc[24];
3245
    crc_next[29] = (data_in[3] ^ crc[31])   ^ crc[25];
3246
    crc_next[30] =  crc[26];
3247
    crc_next[31] =  crc[27];
3248
 
3249
    crc = crc_next;
3250
    crc_error = crc[31:0] != 32'hc704dd7b;  // CRC not equal to magic number
3251
    case (nibble_cnt)
3252
    9: crc_out = {!crc[24], !crc[25], !crc[26], !crc[27], !crc[28], !crc[29], !crc[30], !crc[31],
3253
                  !crc[16], !crc[17], !crc[18], !crc[19], !crc[20], !crc[21], !crc[22], !crc[23],
3254
                  !crc[ 8], !crc[ 9], !crc[10], !crc[11], !crc[12], !crc[13], !crc[14], !crc[15],
3255
                  !crc[ 0], !crc[ 1], !crc[ 2], !crc[ 3], !crc[ 4], !crc[ 5], !crc[ 6], !crc[ 7]};
3256
    default: crc_out = crc_out;
3257
    endcase
3258
    // wait for delta time
3259
    delta_t = !delta_t;
3260
    // increment address and load new data
3261
    if ((word_cnt+3) == 7)//4)
3262
    begin
3263
      // because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3]
3264
      load_reg[31:24] = eth_phy.tx_mem[addr_cnt];
3265
      addr_cnt = addr_cnt + 1;
3266
      load_reg[23:16] = eth_phy.tx_mem[addr_cnt];
3267
      addr_cnt = addr_cnt + 1;
3268
      load_reg[15: 8] = eth_phy.tx_mem[addr_cnt];
3269
      addr_cnt = addr_cnt + 1;
3270
      load_reg[ 7: 0] = eth_phy.tx_mem[addr_cnt];
3271
      addr_cnt = addr_cnt + 1;
3272
    end
3273
    // set new load bit position
3274
    if((word_cnt+3) == 31)
3275
      word_cnt = 16;
3276
    else if ((word_cnt+3) == 23)
3277
      word_cnt = 8;
3278
    else if ((word_cnt+3) == 15)
3279
      word_cnt = 0;
3280
    else if ((word_cnt+3) == 7)
3281
      word_cnt = 24;
3282
    else
3283
      word_cnt = word_cnt + 4;// - 4;
3284
    // decrement nibble counter
3285
    nibble_cnt = nibble_cnt - 1;
3286
    // wait for delta time
3287
    delta_t = !delta_t;
3288
  end // while
3289
  #1;
3290
end
3291
endtask // paralel_crc_phy_tx
3292
 
3293
// paralel CRC calculating for PHY RX
3294
task paralel_crc_phy_rx;
3295
  input  [31:0] start_addr; // start address
3296
  input  [31:0] len; // length of frame in Bytes without CRC length
3297
  input         plus_dribble_nibble; // if length is longer for one nibble
3298
  output [31:0] crc_out;
3299
  reg    [21:0] addr_cnt; // only 22 address lines
3300
  integer       word_cnt;
3301
  integer       nibble_cnt;
3302
  reg    [31:0] load_reg;
3303
  reg           delta_t;
3304
  reg    [31:0] crc_next;
3305
  reg    [31:0] crc;
3306
  reg           crc_error;
3307
  reg     [3:0] data_in;
3308
  integer       i;
3309
begin
3310
  #1 addr_cnt = start_addr[21:0];
3311
  word_cnt = 24; // 27; // start of the frame - nibble granularity (MSbit first)
3312
  crc = 32'hFFFF_FFFF; // INITIAL value
3313
  delta_t = 0;
3314
  // length must include 4 bytes of ZEROs, to generate CRC
3315
  // get number of nibbles from Byte length (2^1 = 2)
3316
  if (plus_dribble_nibble)
3317
    nibble_cnt = ((len + 4) << 1) + 1'b1; // one nibble longer
3318
  else
3319
    nibble_cnt = ((len + 4) << 1);
3320
  // because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3]
3321
  load_reg[31:24] = eth_phy.rx_mem[addr_cnt];
3322
  addr_cnt = addr_cnt + 1;
3323
  load_reg[23:16] = eth_phy.rx_mem[addr_cnt];
3324
  addr_cnt = addr_cnt + 1;
3325
  load_reg[15: 8] = eth_phy.rx_mem[addr_cnt];
3326
  addr_cnt = addr_cnt + 1;
3327
  load_reg[ 7: 0] = eth_phy.rx_mem[addr_cnt];
3328
  addr_cnt = addr_cnt + 1;
3329
  while (nibble_cnt > 0)
3330
  begin
3331
    // wait for delta time
3332
    delta_t = !delta_t;
3333
    // shift data in
3334
 
3335
    if(nibble_cnt <= 8) // for additional 8 nibbles shift ZEROs in!
3336
      data_in[3:0] = 4'h0;
3337
    else
3338
 
3339
      data_in[3:0] = {load_reg[word_cnt], load_reg[word_cnt+1], load_reg[word_cnt+2], load_reg[word_cnt+3]};
3340
    crc_next[0]  = (data_in[0] ^ crc[28]);
3341
    crc_next[1]  = (data_in[1] ^ data_in[0] ^ crc[28]    ^ crc[29]);
3342
    crc_next[2]  = (data_in[2] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[30]);
3343
    crc_next[3]  = (data_in[3] ^ data_in[2] ^ data_in[1] ^ crc[29]  ^ crc[30] ^ crc[31]);
3344
    crc_next[4]  = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[0];
3345
    crc_next[5]  = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[1];
3346
    crc_next[6]  = (data_in[2] ^ data_in[1] ^ crc[29]    ^ crc[30]) ^ crc[ 2];
3347
    crc_next[7]  = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[3];
3348
    crc_next[8]  = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[4];
3349
    crc_next[9]  = (data_in[2] ^ data_in[1] ^ crc[29]    ^ crc[30]) ^ crc[5];
3350
    crc_next[10] = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[6];
3351
    crc_next[11] = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[7];
3352
    crc_next[12] = (data_in[2] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[30]) ^ crc[8];
3353
    crc_next[13] = (data_in[3] ^ data_in[2] ^ data_in[1] ^ crc[29]  ^ crc[30] ^ crc[31]) ^ crc[9];
3354
    crc_next[14] = (data_in[3] ^ data_in[2] ^ crc[30]    ^ crc[31]) ^ crc[10];
3355
    crc_next[15] = (data_in[3] ^ crc[31])   ^ crc[11];
3356
    crc_next[16] = (data_in[0] ^ crc[28])   ^ crc[12];
3357
    crc_next[17] = (data_in[1] ^ crc[29])   ^ crc[13];
3358
    crc_next[18] = (data_in[2] ^ crc[30])   ^ crc[14];
3359
    crc_next[19] = (data_in[3] ^ crc[31])   ^ crc[15];
3360
    crc_next[20] =  crc[16];
3361
    crc_next[21] =  crc[17];
3362
    crc_next[22] = (data_in[0] ^ crc[28])   ^ crc[18];
3363
    crc_next[23] = (data_in[1] ^ data_in[0] ^ crc[29]    ^ crc[28]) ^ crc[19];
3364
    crc_next[24] = (data_in[2] ^ data_in[1] ^ crc[30]    ^ crc[29]) ^ crc[20];
3365
    crc_next[25] = (data_in[3] ^ data_in[2] ^ crc[31]    ^ crc[30]) ^ crc[21];
3366
    crc_next[26] = (data_in[3] ^ data_in[0] ^ crc[31]    ^ crc[28]) ^ crc[22];
3367
    crc_next[27] = (data_in[1] ^ crc[29])   ^ crc[23];
3368
    crc_next[28] = (data_in[2] ^ crc[30])   ^ crc[24];
3369
    crc_next[29] = (data_in[3] ^ crc[31])   ^ crc[25];
3370
    crc_next[30] =  crc[26];
3371
    crc_next[31] =  crc[27];
3372
 
3373
    crc = crc_next;
3374
    crc_error = crc[31:0] != 32'hc704dd7b;  // CRC not equal to magic number
3375
    case (nibble_cnt)
3376
    9: crc_out = {!crc[24], !crc[25], !crc[26], !crc[27], !crc[28], !crc[29], !crc[30], !crc[31],
3377
                  !crc[16], !crc[17], !crc[18], !crc[19], !crc[20], !crc[21], !crc[22], !crc[23],
3378
                  !crc[ 8], !crc[ 9], !crc[10], !crc[11], !crc[12], !crc[13], !crc[14], !crc[15],
3379
                  !crc[ 0], !crc[ 1], !crc[ 2], !crc[ 3], !crc[ 4], !crc[ 5], !crc[ 6], !crc[ 7]};
3380
    default: crc_out = crc_out;
3381
    endcase
3382
    // wait for delta time
3383
    delta_t = !delta_t;
3384
    // increment address and load new data
3385
    if ((word_cnt+3) == 7)//4)
3386
    begin
3387
      // because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3]
3388
      load_reg[31:24] = eth_phy.rx_mem[addr_cnt];
3389
      addr_cnt = addr_cnt + 1;
3390
      load_reg[23:16] = eth_phy.rx_mem[addr_cnt];
3391
      addr_cnt = addr_cnt + 1;
3392
      load_reg[15: 8] = eth_phy.rx_mem[addr_cnt];
3393
      addr_cnt = addr_cnt + 1;
3394
      load_reg[ 7: 0] = eth_phy.rx_mem[addr_cnt];
3395
      addr_cnt = addr_cnt + 1;
3396
    end
3397
    // set new load bit position
3398
    if((word_cnt+3) == 31)
3399
      word_cnt = 16;
3400
    else if ((word_cnt+3) == 23)
3401
      word_cnt = 8;
3402
    else if ((word_cnt+3) == 15)
3403
      word_cnt = 0;
3404
    else if ((word_cnt+3) == 7)
3405
      word_cnt = 24;
3406
    else
3407
      word_cnt = word_cnt + 4;// - 4;
3408
    // decrement nibble counter
3409
    nibble_cnt = nibble_cnt - 1;
3410
    // wait for delta time
3411
    delta_t = !delta_t;
3412
  end // while
3413
  #1;
3414
end
3415
endtask // paralel_crc_phy_rx
3416
 
3417
// paralel CRC checking for MAC
3418
task paralel_crc_mac;
3419
  input  [31:0] start_addr; // start address
3420
  input  [31:0] len; // length of frame in Bytes without CRC length
3421
  input         plus_dribble_nibble; // if length is longer for one nibble
3422
  output [31:0] crc_out;
3423
 
3424
  reg    [21:0] addr_cnt; // only 22 address lines
3425
  integer       word_cnt;
3426
  integer       nibble_cnt;
3427
  reg    [31:0] load_reg;
3428
  reg           delta_t;
3429
  reg    [31:0] crc_next;
3430
  reg    [31:0] crc;
3431
  reg           crc_error;
3432
  reg     [3:0] data_in;
3433
  integer       i;
3434
begin
3435
  #1 addr_cnt = start_addr[19:0];
3436
  // set starting point depending with which byte frame starts (e.g. if addr_cnt[1:0] == 0, then
3437
  //   MSB of the packet must be written to the LSB of Big ENDIAN Word [31:24])
3438
  if (addr_cnt[1:0] == 2'h1)
3439
    word_cnt = 16; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
3440
  else if (addr_cnt[1:0] == 2'h2)
3441
    word_cnt = 8; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
3442
  else if (addr_cnt[1:0] == 2'h3)
3443
    word_cnt = 0; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
3444
  else
3445
    word_cnt = 24; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
3446
  crc = 32'hFFFF_FFFF; // INITIAL value
3447
  delta_t = 0;
3448
  // length must include 4 bytes of ZEROs, to generate CRC
3449
  // get number of nibbles from Byte length (2^1 = 2)
3450
  if (plus_dribble_nibble)
3451
    nibble_cnt = ((len + 4) << 1) + 1'b1; // one nibble longer
3452
  else
3453
    nibble_cnt = ((len + 4) << 1);
3454
  load_reg = wb_slave.wb_memory[{12'h0, addr_cnt[21:2]}];
3455
  addr_cnt = addr_cnt + 4;
3456
  while (nibble_cnt > 0)
3457
  begin
3458
    // wait for delta time
3459
    delta_t = !delta_t;
3460
    // shift data in
3461
 
3462
    if(nibble_cnt <= 8) // for additional 8 nibbles shift ZEROs in!
3463
      data_in[3:0] = 4'h0;
3464
    else
3465
 
3466
      data_in[3:0] = {load_reg[word_cnt], load_reg[word_cnt+1], load_reg[word_cnt+2], load_reg[word_cnt+3]};
3467
    crc_next[0]  = (data_in[0] ^ crc[28]);
3468
    crc_next[1]  = (data_in[1] ^ data_in[0] ^ crc[28]    ^ crc[29]);
3469
    crc_next[2]  = (data_in[2] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[30]);
3470
    crc_next[3]  = (data_in[3] ^ data_in[2] ^ data_in[1] ^ crc[29]  ^ crc[30] ^ crc[31]);
3471
    crc_next[4]  = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[0];
3472
    crc_next[5]  = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[1];
3473
    crc_next[6]  = (data_in[2] ^ data_in[1] ^ crc[29]    ^ crc[30]) ^ crc[ 2];
3474
    crc_next[7]  = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[3];
3475
    crc_next[8]  = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[4];
3476
    crc_next[9]  = (data_in[2] ^ data_in[1] ^ crc[29]    ^ crc[30]) ^ crc[5];
3477
    crc_next[10] = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28]  ^ crc[30] ^ crc[31]) ^ crc[6];
3478
    crc_next[11] = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[31]) ^ crc[7];
3479
    crc_next[12] = (data_in[2] ^ data_in[1] ^ data_in[0] ^ crc[28]  ^ crc[29] ^ crc[30]) ^ crc[8];
3480
    crc_next[13] = (data_in[3] ^ data_in[2] ^ data_in[1] ^ crc[29]  ^ crc[30] ^ crc[31]) ^ crc[9];
3481
    crc_next[14] = (data_in[3] ^ data_in[2] ^ crc[30]    ^ crc[31]) ^ crc[10];
3482
    crc_next[15] = (data_in[3] ^ crc[31])   ^ crc[11];
3483
    crc_next[16] = (data_in[0] ^ crc[28])   ^ crc[12];
3484
    crc_next[17] = (data_in[1] ^ crc[29])   ^ crc[13];
3485
    crc_next[18] = (data_in[2] ^ crc[30])   ^ crc[14];
3486
    crc_next[19] = (data_in[3] ^ crc[31])   ^ crc[15];
3487
    crc_next[20] =  crc[16];
3488
    crc_next[21] =  crc[17];
3489
    crc_next[22] = (data_in[0] ^ crc[28])   ^ crc[18];
3490
    crc_next[23] = (data_in[1] ^ data_in[0] ^ crc[29]    ^ crc[28]) ^ crc[19];
3491
    crc_next[24] = (data_in[2] ^ data_in[1] ^ crc[30]    ^ crc[29]) ^ crc[20];
3492
    crc_next[25] = (data_in[3] ^ data_in[2] ^ crc[31]    ^ crc[30]) ^ crc[21];
3493
    crc_next[26] = (data_in[3] ^ data_in[0] ^ crc[31]    ^ crc[28]) ^ crc[22];
3494
    crc_next[27] = (data_in[1] ^ crc[29])   ^ crc[23];
3495
    crc_next[28] = (data_in[2] ^ crc[30])   ^ crc[24];
3496
    crc_next[29] = (data_in[3] ^ crc[31])   ^ crc[25];
3497
    crc_next[30] =  crc[26];
3498
    crc_next[31] =  crc[27];
3499
 
3500
    crc = crc_next;
3501
    crc_error = crc[31:0] != 32'hc704dd7b;  // CRC not equal to magic number
3502
    case (nibble_cnt)
3503
    9: crc_out = {!crc[24], !crc[25], !crc[26], !crc[27], !crc[28], !crc[29], !crc[30], !crc[31],
3504
                  !crc[16], !crc[17], !crc[18], !crc[19], !crc[20], !crc[21], !crc[22], !crc[23],
3505
                  !crc[ 8], !crc[ 9], !crc[10], !crc[11], !crc[12], !crc[13], !crc[14], !crc[15],
3506
                  !crc[ 0], !crc[ 1], !crc[ 2], !crc[ 3], !crc[ 4], !crc[ 5], !crc[ 6], !crc[ 7]};
3507
    default: crc_out = crc_out;
3508
    endcase
3509
    // wait for delta time
3510
    delta_t = !delta_t;
3511
    // increment address and load new data
3512
    if ((word_cnt+3) == 7)//4)
3513
    begin
3514
      // because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3]
3515
      load_reg = wb_slave.wb_memory[{12'h0, addr_cnt[21:2]}];
3516
      addr_cnt = addr_cnt + 4;
3517
    end
3518
    // set new load bit position
3519
    if((word_cnt+3) == 31)
3520
      word_cnt = 16;
3521
    else if ((word_cnt+3) == 23)
3522
      word_cnt = 8;
3523
    else if ((word_cnt+3) == 15)
3524
      word_cnt = 0;
3525
    else if ((word_cnt+3) == 7)
3526
      word_cnt = 24;
3527
    else
3528
      word_cnt = word_cnt + 4;// - 4;
3529
    // decrement nibble counter
3530
    nibble_cnt = nibble_cnt - 1;
3531
    // wait for delta time
3532
    delta_t = !delta_t;
3533
  end // while
3534
  #1;
3535
end
3536
endtask // paralel_crc_mac
3537
 
3538
// serial CRC checking for PHY TX
3539
task serial_crc_phy_tx;
3540
  input  [31:0] start_addr; // start address
3541
  input  [31:0] len; // length of frame in Bytes without CRC length
3542
  input         plus_dribble_nibble; // if length is longer for one nibble
3543
  output [31:0] crc;
3544
  reg    [21:0] addr_cnt; // only 22 address lines
3545
  integer       word_cnt;
3546
  integer       bit_cnt;
3547
  reg    [31:0] load_reg;
3548
  reg    [31:0] crc_shift_reg;
3549
  reg    [31:0] crc_store_reg;
3550
  reg           delta_t;
3551
begin
3552
  #1 addr_cnt = start_addr[21:0];
3553
  word_cnt = 24; // 27; // start of the frame - nibble granularity (MSbit first)
3554
  crc_store_reg = 32'hFFFF_FFFF; // INITIAL value
3555
  delta_t = 0;
3556
  // length must include 4 bytes of ZEROs, to generate CRC
3557
  // get number of bits from Byte length (2^3 = 8)
3558
  if (plus_dribble_nibble)
3559
    bit_cnt = ((len + 4) << 3) + 3'h4; // one nibble longer
3560
  else
3561
    bit_cnt = ((len + 4) << 3);
3562
  // because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3]
3563
  load_reg[31:24] = eth_phy.tx_mem[addr_cnt];
3564
  addr_cnt = addr_cnt + 1;
3565
  load_reg[23:16] = eth_phy.tx_mem[addr_cnt];
3566
  addr_cnt = addr_cnt + 1;
3567
  load_reg[15: 8] = eth_phy.tx_mem[addr_cnt];
3568
  addr_cnt = addr_cnt + 1;
3569
  load_reg[ 7: 0] = eth_phy.tx_mem[addr_cnt];
3570
  addr_cnt = addr_cnt + 1;
3571
#1;
3572
  while (bit_cnt > 0)
3573
  begin
3574
    // wait for delta time
3575
    delta_t = !delta_t;
3576
#1;
3577
    // shift data in
3578
 
3579
    if(bit_cnt <= 32) // for additional 32 bits shift ZEROs in!
3580
     crc_shift_reg[0] = 1'b0               ^ crc_store_reg[31];
3581
    else
3582
 
3583
     crc_shift_reg[0] = load_reg[word_cnt] ^ crc_store_reg[31];
3584
    crc_shift_reg[1]  = crc_store_reg[0]   ^ crc_store_reg[31];
3585
    crc_shift_reg[2]  = crc_store_reg[1]   ^ crc_store_reg[31];
3586
    crc_shift_reg[3]  = crc_store_reg[2];
3587
    crc_shift_reg[4]  = crc_store_reg[3]   ^ crc_store_reg[31];
3588
    crc_shift_reg[5]  = crc_store_reg[4]   ^ crc_store_reg[31];
3589
    crc_shift_reg[6]  = crc_store_reg[5];
3590
    crc_shift_reg[7]  = crc_store_reg[6]   ^ crc_store_reg[31];
3591
    crc_shift_reg[8]  = crc_store_reg[7]   ^ crc_store_reg[31];
3592
    crc_shift_reg[9]  = crc_store_reg[8];
3593
    crc_shift_reg[10] = crc_store_reg[9]   ^ crc_store_reg[31];
3594
    crc_shift_reg[11] = crc_store_reg[10]  ^ crc_store_reg[31];
3595
    crc_shift_reg[12] = crc_store_reg[11]  ^ crc_store_reg[31];
3596
    crc_shift_reg[13] = crc_store_reg[12];
3597
    crc_shift_reg[14] = crc_store_reg[13];
3598
    crc_shift_reg[15] = crc_store_reg[14];
3599
    crc_shift_reg[16] = crc_store_reg[15]  ^ crc_store_reg[31];
3600
    crc_shift_reg[17] = crc_store_reg[16];
3601
    crc_shift_reg[18] = crc_store_reg[17];
3602
    crc_shift_reg[19] = crc_store_reg[18];
3603
    crc_shift_reg[20] = crc_store_reg[19];
3604
    crc_shift_reg[21] = crc_store_reg[20];
3605
    crc_shift_reg[22] = crc_store_reg[21]  ^ crc_store_reg[31];
3606
    crc_shift_reg[23] = crc_store_reg[22]  ^ crc_store_reg[31];
3607
    crc_shift_reg[24] = crc_store_reg[23];
3608
    crc_shift_reg[25] = crc_store_reg[24];
3609
    crc_shift_reg[26] = crc_store_reg[25]  ^ crc_store_reg[31];
3610
    crc_shift_reg[27] = crc_store_reg[26];
3611
    crc_shift_reg[28] = crc_store_reg[27];
3612
    crc_shift_reg[29] = crc_store_reg[28];
3613
    crc_shift_reg[30] = crc_store_reg[29];
3614
    crc_shift_reg[31] = crc_store_reg[30];
3615
    // wait for delta time
3616
    delta_t = !delta_t;
3617
 
3618
    // store previous data
3619
    crc_store_reg = crc_shift_reg;
3620
 
3621
    // put CRC out
3622
    case (bit_cnt)
3623
    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:
3624
    begin
3625
      crc = crc_store_reg;
3626
      crc = {!crc[24], !crc[25], !crc[26], !crc[27], !crc[28], !crc[29], !crc[30], !crc[31],
3627
             !crc[16], !crc[17], !crc[18], !crc[19], !crc[20], !crc[21], !crc[22], !crc[23],
3628
             !crc[ 8], !crc[ 9], !crc[10], !crc[11], !crc[12], !crc[13], !crc[14], !crc[15],
3629
             !crc[ 0], !crc[ 1], !crc[ 2], !crc[ 3], !crc[ 4], !crc[ 5], !crc[ 6], !crc[ 7]};
3630
    end
3631
    default: crc = crc;
3632
    endcase
3633
 
3634
    // increment address and load new data
3635
#1;
3636
    if (word_cnt == 7)//4)
3637
    begin
3638
      // because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3]
3639
      load_reg[31:24] = eth_phy.tx_mem[addr_cnt];
3640
//      load_reg[31:24] = {load_reg[28], load_reg[29], load_reg[30], load_reg[31], 
3641
//                         load_reg[24], load_reg[25], load_reg[26], load_reg[27]};
3642
      addr_cnt = addr_cnt + 1;
3643
      load_reg[23:16] = eth_phy.tx_mem[addr_cnt];
3644
//      load_reg[23:16] = {load_reg[20], load_reg[21], load_reg[22], load_reg[23], 
3645
//                         load_reg[16], load_reg[17], load_reg[18], load_reg[19]};
3646
      addr_cnt = addr_cnt + 1;
3647
      load_reg[15: 8] = eth_phy.tx_mem[addr_cnt];
3648
//      load_reg[15: 8] = {load_reg[12], load_reg[13], load_reg[14], load_reg[15], 
3649
//                         load_reg[ 8], load_reg[ 9], load_reg[10], load_reg[11]};
3650
      addr_cnt = addr_cnt + 1;
3651
      load_reg[ 7: 0] = eth_phy.tx_mem[addr_cnt];
3652
//      load_reg[ 7: 0] = {load_reg[ 4], load_reg[ 5], load_reg[ 6], load_reg[ 7], 
3653
//                         load_reg[ 0], load_reg[ 1], load_reg[ 2], load_reg[ 3]};
3654
      addr_cnt = addr_cnt + 1;
3655
    end
3656
#1;
3657
    // set new load bit position
3658
    if(word_cnt == 31)
3659
      word_cnt = 16;
3660
    else if (word_cnt == 23)
3661
      word_cnt = 8;
3662
    else if (word_cnt == 15)
3663
      word_cnt = 0;
3664
    else if (word_cnt == 7)
3665
      word_cnt = 24;
3666
 
3667
//   if(word_cnt == 24)
3668
//     word_cnt = 31;
3669
//   else if (word_cnt == 28)
3670
//     word_cnt = 19;
3671
//   else if (word_cnt == 16)
3672
//     word_cnt = 23;
3673
//   else if (word_cnt == 20)
3674
//     word_cnt = 11;
3675
//   else if(word_cnt == 8)
3676
//     word_cnt = 15;
3677
//   else if (word_cnt == 12)
3678
//     word_cnt = 3;
3679
//   else if (word_cnt == 0)
3680
//     word_cnt = 7;
3681
//   else if (word_cnt == 4)
3682
//     word_cnt = 27;
3683
    else
3684
      word_cnt = word_cnt + 1;// - 1;
3685
#1;
3686
    // decrement bit counter
3687
    bit_cnt = bit_cnt - 1;
3688
#1;
3689
    // wait for delta time
3690
    delta_t = !delta_t;
3691
  end // while
3692
 
3693
  #1;
3694
end
3695
endtask // serial_crc_phy_tx
3696
 
3697
// serial CRC calculating for PHY RX
3698
task serial_crc_phy_rx;
3699
  input  [31:0] start_addr; // start address
3700
  input  [31:0] len; // length of frame in Bytes without CRC length
3701
  input         plus_dribble_nibble; // if length is longer for one nibble
3702
  output [31:0] crc;
3703
  reg    [21:0] addr_cnt; // only 22 address lines
3704
  integer       word_cnt;
3705
  integer       bit_cnt;
3706
  reg    [31:0] load_reg;
3707
  reg    [31:0] crc_shift_reg;
3708
  reg    [31:0] crc_store_reg;
3709
  reg           delta_t;
3710
begin
3711
  #1 addr_cnt = start_addr[21:0];
3712
  word_cnt = 24; // start of the frame
3713
  crc_shift_reg = 0;
3714
  delta_t = 0;
3715
  // length must include 4 bytes of ZEROs, to generate CRC
3716
  // get number of bits from Byte length (2^3 = 8)
3717
  if (plus_dribble_nibble)
3718
    bit_cnt = ((len + 4) << 3) + 3'h4; // one nibble longer
3719
  else
3720
    bit_cnt = ((len + 4) << 3);
3721
  load_reg[31:24] = eth_phy.rx_mem[addr_cnt];
3722
  addr_cnt = addr_cnt + 1;
3723
  load_reg[23:16] = eth_phy.rx_mem[addr_cnt];
3724
  addr_cnt = addr_cnt + 1;
3725
  load_reg[15:8]  = eth_phy.rx_mem[addr_cnt];
3726
  addr_cnt = addr_cnt + 1;
3727
  load_reg[7:0]   = eth_phy.rx_mem[addr_cnt];
3728
 
3729
  while (bit_cnt > 0)
3730
  begin
3731
    // wait for delta time
3732
    delta_t = !delta_t;
3733
    // store previous data
3734
    crc_store_reg = crc_shift_reg;
3735
    // shift data in
3736
    if(bit_cnt <= 32) // for additional 32 bits shift ZEROs in!
3737
     crc_shift_reg[0] = 1'b0               ^ crc_store_reg[31];
3738
    else
3739
     crc_shift_reg[0] = load_reg[word_cnt] ^ crc_store_reg[31];
3740
    crc_shift_reg[1]  = crc_store_reg[0]   ^ crc_store_reg[31];
3741
    crc_shift_reg[2]  = crc_store_reg[1]   ^ crc_store_reg[31];
3742
    crc_shift_reg[3]  = crc_store_reg[2];
3743
    crc_shift_reg[4]  = crc_store_reg[3]   ^ crc_store_reg[31];
3744
    crc_shift_reg[5]  = crc_store_reg[4]   ^ crc_store_reg[31];
3745
    crc_shift_reg[6]  = crc_store_reg[5];
3746
    crc_shift_reg[7]  = crc_store_reg[6]   ^ crc_store_reg[31];
3747
    crc_shift_reg[8]  = crc_store_reg[7]   ^ crc_store_reg[31];
3748
    crc_shift_reg[9]  = crc_store_reg[8];
3749
    crc_shift_reg[10] = crc_store_reg[9]   ^ crc_store_reg[31];
3750
    crc_shift_reg[11] = crc_store_reg[10]  ^ crc_store_reg[31];
3751
    crc_shift_reg[12] = crc_store_reg[11]  ^ crc_store_reg[31];
3752
    crc_shift_reg[13] = crc_store_reg[12];
3753
    crc_shift_reg[14] = crc_store_reg[13];
3754
    crc_shift_reg[15] = crc_store_reg[14];
3755
    crc_shift_reg[16] = crc_store_reg[15]  ^ crc_store_reg[31];
3756
    crc_shift_reg[17] = crc_store_reg[16];
3757
    crc_shift_reg[18] = crc_store_reg[17];
3758
    crc_shift_reg[19] = crc_store_reg[18];
3759
    crc_shift_reg[20] = crc_store_reg[19];
3760
    crc_shift_reg[21] = crc_store_reg[20];
3761
    crc_shift_reg[22] = crc_store_reg[21]  ^ crc_store_reg[31];
3762
    crc_shift_reg[23] = crc_store_reg[22]  ^ crc_store_reg[31];
3763
    crc_shift_reg[24] = crc_store_reg[23];
3764
    crc_shift_reg[25] = crc_store_reg[24];
3765
    crc_shift_reg[26] = crc_store_reg[25]  ^ crc_store_reg[31];
3766
    crc_shift_reg[27] = crc_store_reg[26];
3767
    crc_shift_reg[28] = crc_store_reg[27];
3768
    crc_shift_reg[29] = crc_store_reg[28];
3769
    crc_shift_reg[30] = crc_store_reg[29];
3770
    crc_shift_reg[31] = crc_store_reg[30];
3771
    // wait for delta time
3772
    delta_t = !delta_t;
3773
    // increment address and load new data
3774
    if (word_cnt == 7)
3775
    begin
3776
      addr_cnt = addr_cnt + 1;
3777
      load_reg[31:24] = eth_phy.rx_mem[addr_cnt];
3778
      addr_cnt = addr_cnt + 1;
3779
      load_reg[23:16] = eth_phy.rx_mem[addr_cnt];
3780
      addr_cnt = addr_cnt + 1;
3781
      load_reg[15:8]  = eth_phy.rx_mem[addr_cnt];
3782
      addr_cnt = addr_cnt + 1;
3783
      load_reg[7:0]   = eth_phy.rx_mem[addr_cnt];
3784
    end
3785
    // set new load bit position
3786
    if(word_cnt == 31)
3787
      word_cnt = 16;
3788
    else if (word_cnt == 23)
3789
      word_cnt = 8;
3790
    else if (word_cnt == 15)
3791
      word_cnt = 0;
3792
    else if (word_cnt == 7)
3793
      word_cnt = 24;
3794
    else
3795
      word_cnt = word_cnt + 1;
3796
    // decrement bit counter
3797
    bit_cnt = bit_cnt - 1;
3798
    // wait for delta time
3799
    delta_t = !delta_t;
3800
  end // while
3801
 
3802
  // put CRC out
3803
  crc = crc_shift_reg;
3804
  #1;
3805
end
3806
endtask // serial_crc_phy_rx
3807
 
3808
// serial CRC checking for MAC
3809
task serial_crc_mac;
3810
  input  [31:0] start_addr; // start address
3811
  input  [31:0] len; // length of frame in Bytes without CRC length
3812
  input         plus_dribble_nibble; // if length is longer for one nibble
3813
  output [31:0] crc;
3814
  reg    [19:0] addr_cnt; // only 20 address lines
3815
  integer       word_cnt;
3816
  integer       bit_cnt;
3817
  reg    [31:0] load_reg;
3818
  reg    [31:0] crc_shift_reg;
3819
  reg    [31:0] crc_store_reg;
3820
  reg           delta_t;
3821
begin
3822
  #1 addr_cnt = start_addr[19:0];
3823
  // set starting point depending with which byte frame starts (e.g. if addr_cnt[1:0] == 0, then
3824
  //   MSB of the packet must be written to the LSB of Big ENDIAN Word [31:24])
3825
  if (addr_cnt[1:0] == 2'h1)
3826
    word_cnt = 16; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
3827
  else if (addr_cnt[1:0] == 2'h2)
3828
    word_cnt = 8; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
3829
  else if (addr_cnt[1:0] == 2'h3)
3830
    word_cnt = 0; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
3831
  else
3832
    word_cnt = 24; // start of the frame for Big ENDIAN Bytes (Litle ENDIAN bits)
3833
 
3834
  crc_shift_reg = 0;
3835
  delta_t = 0;
3836
  // length must include 4 bytes of ZEROs, to generate CRC
3837
  // get number of bits from Byte length (2^3 = 8)
3838
  if (plus_dribble_nibble)
3839
    bit_cnt = ((len + 4) << 3) + 3'h4; // one nibble longer
3840
  else
3841
    bit_cnt = ((len + 4) << 3);
3842
  load_reg = wb_slave.wb_memory[{12'h0, addr_cnt}];
3843
 
3844
  while (bit_cnt > 0)
3845
  begin
3846
    // wait for delta time
3847
    delta_t = !delta_t;
3848
    // store previous data
3849
    crc_store_reg = crc_shift_reg;
3850
    // shift data in
3851
    if(bit_cnt <= 32) // for additional 32 bits shift ZEROs in!
3852
     crc_shift_reg[0] = 1'b0               ^ crc_store_reg[31];
3853
    else
3854
     crc_shift_reg[0] = load_reg[word_cnt] ^ crc_store_reg[31];
3855
    crc_shift_reg[1]  = crc_store_reg[0]   ^ crc_store_reg[31];
3856
    crc_shift_reg[2]  = crc_store_reg[1]   ^ crc_store_reg[31];
3857
    crc_shift_reg[3]  = crc_store_reg[2];
3858
    crc_shift_reg[4]  = crc_store_reg[3]   ^ crc_store_reg[31];
3859
    crc_shift_reg[5]  = crc_store_reg[4]   ^ crc_store_reg[31];
3860
    crc_shift_reg[6]  = crc_store_reg[5];
3861
    crc_shift_reg[7]  = crc_store_reg[6]   ^ crc_store_reg[31];
3862
    crc_shift_reg[8]  = crc_store_reg[7]   ^ crc_store_reg[31];
3863
    crc_shift_reg[9]  = crc_store_reg[8];
3864
    crc_shift_reg[10] = crc_store_reg[9]   ^ crc_store_reg[31];
3865
    crc_shift_reg[11] = crc_store_reg[10]  ^ crc_store_reg[31];
3866
    crc_shift_reg[12] = crc_store_reg[11]  ^ crc_store_reg[31];
3867
    crc_shift_reg[13] = crc_store_reg[12];
3868
    crc_shift_reg[14] = crc_store_reg[13];
3869
    crc_shift_reg[15] = crc_store_reg[14];
3870
    crc_shift_reg[16] = crc_store_reg[15]  ^ crc_store_reg[31];
3871
    crc_shift_reg[17] = crc_store_reg[16];
3872
    crc_shift_reg[18] = crc_store_reg[17];
3873
    crc_shift_reg[19] = crc_store_reg[18];
3874
    crc_shift_reg[20] = crc_store_reg[19];
3875
    crc_shift_reg[21] = crc_store_reg[20];
3876
    crc_shift_reg[22] = crc_store_reg[21]  ^ crc_store_reg[31];
3877
    crc_shift_reg[23] = crc_store_reg[22]  ^ crc_store_reg[31];
3878
    crc_shift_reg[24] = crc_store_reg[23];
3879
    crc_shift_reg[25] = crc_store_reg[24];
3880
    crc_shift_reg[26] = crc_store_reg[25]  ^ crc_store_reg[31];
3881
    crc_shift_reg[27] = crc_store_reg[26];
3882
    crc_shift_reg[28] = crc_store_reg[27];
3883
    crc_shift_reg[29] = crc_store_reg[28];
3884
    crc_shift_reg[30] = crc_store_reg[29];
3885
    crc_shift_reg[31] = crc_store_reg[30];
3886
    // wait for delta time
3887
    delta_t = !delta_t;
3888
    // increment address and load new data for Big ENDIAN Bytes (Litle ENDIAN bits)
3889
    if (word_cnt == 7)
3890
    begin
3891
      addr_cnt = addr_cnt + 4;
3892
      load_reg = wb_slave.wb_memory[{12'h0, addr_cnt}];
3893
    end
3894
    // set new load bit position for Big ENDIAN Bytes (Litle ENDIAN bits)
3895
    if(word_cnt == 31)
3896
      word_cnt = 16;
3897
    else if (word_cnt == 23)
3898
      word_cnt = 8;
3899
    else if (word_cnt == 15)
3900
      word_cnt = 0;
3901
    else if (word_cnt == 7)
3902
      word_cnt = 24;
3903
    else
3904
      word_cnt = word_cnt + 1;
3905
    // decrement bit counter
3906
    bit_cnt = bit_cnt - 1;
3907
    // wait for delta time
3908
    delta_t = !delta_t;
3909
  end // while
3910
 
3911
  // put CRC out
3912
  crc = crc_shift_reg;
3913
  #1;
3914
end
3915
endtask // serial_crc_mac
3916
 
3917
//////////////////////////////////////////////////////////////
3918
// MIIM Basic tasks
3919
//////////////////////////////////////////////////////////////
3920
 
3921
task mii_set_clk_div; // set clock divider for MII clock
3922
  input [7:0]  clk_div;
3923
begin
3924
  // MII mode register
3925
  wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_CLKDIV & clk_div), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3926
end
3927
endtask // mii_set_clk_div
3928
 
3929
 
3930
task check_mii_busy; // MII - check if BUSY
3931
  reg [31:0] tmp;
3932
begin
3933
  @(posedge wb_clk);
3934
  // MII read status register
3935
  wbm_read(`ETH_MIISTATUS, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3936
  while(tmp[`ETH_MIISTATUS_BUSY] !== 1'b0) //`ETH_MIISTATUS_BUSY
3937
  begin
3938
    @(posedge wb_clk);
3939
    wbm_read(`ETH_MIISTATUS, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3940
  end
3941
end
3942
endtask // check_mii_busy
3943
 
3944
 
3945
task check_mii_scan_valid; // MII - check if SCAN data are valid
3946
  reg [31:0] tmp;
3947
begin
3948
  @(posedge wb_clk);
3949
  // MII read status register
3950
  wbm_read(`ETH_MIISTATUS, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3951
  while(tmp[`ETH_MIISTATUS_NVALID] !== 1'b0) //`ETH_MIISTATUS_NVALID
3952
  begin
3953
    @(posedge wb_clk);
3954
    wbm_read(`ETH_MIISTATUS, tmp, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3955
  end
3956
end
3957
endtask // check_mii_scan_valid
3958
 
3959
 
3960
task mii_write_req; // requests write to MII
3961
  input [4:0]  phy_addr;
3962
  input [4:0]  reg_addr;
3963
  input [15:0] data_in;
3964
begin
3965
  // MII address, PHY address = 1, command register address = 0
3966
  wbm_write(`ETH_MIIADDRESS, (`ETH_MIIADDRESS_FIAD & phy_addr) | (`ETH_MIIADDRESS_RGAD & (reg_addr << 8)),
3967
            4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3968
  // MII TX data
3969
  wbm_write(`ETH_MIITX_DATA, {16'h0000, data_in}, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3970
  // MII command
3971
  wbm_write(`ETH_MIICOMMAND, `ETH_MIICOMMAND_WCTRLDATA, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3972
  @(posedge wb_clk);
3973
end
3974
endtask // mii_write_req
3975
 
3976
 
3977
task mii_read_req; // requests read from MII
3978
  input [4:0]  phy_addr;
3979
  input [4:0]  reg_addr;
3980
begin
3981
  // MII address, PHY address = 1, command register address = 0
3982
  wbm_write(`ETH_MIIADDRESS, (`ETH_MIIADDRESS_FIAD & phy_addr) | (`ETH_MIIADDRESS_RGAD & (reg_addr << 8)),
3983
            4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3984
  // MII command
3985
  wbm_write(`ETH_MIICOMMAND, `ETH_MIICOMMAND_RSTAT, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3986
  @(posedge wb_clk);
3987
end
3988
endtask // mii_read_req
3989
 
3990
 
3991
task mii_scan_req; // requests scan from MII
3992
  input [4:0]  phy_addr;
3993
  input [4:0]  reg_addr;
3994
begin
3995
  // MII address, PHY address = 1, command register address = 0
3996
  wbm_write(`ETH_MIIADDRESS, (`ETH_MIIADDRESS_FIAD & phy_addr) | (`ETH_MIIADDRESS_RGAD & (reg_addr << 8)),
3997
            4'hF, 1, wbm_init_waits, wbm_subseq_waits);
3998
  // MII command
3999
  wbm_write(`ETH_MIICOMMAND, `ETH_MIICOMMAND_SCANSTAT, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4000
  @(posedge wb_clk);
4001
end
4002
endtask // mii_scan_req
4003
 
4004
 
4005
task mii_scan_finish; // finish scan from MII
4006
begin
4007
  // MII command
4008
  wbm_write(`ETH_MIICOMMAND, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
4009
  @(posedge wb_clk);
4010
end
4011
endtask // mii_scan_finish
4012
 
4013
//////////////////////////////////////////////////////////////
4014
// Log files and memory tasks
4015
//////////////////////////////////////////////////////////////
4016
 
4017
task clear_memories;
4018
  reg    [22:0]  adr_i;
4019
  reg            delta_t;
4020
begin
4021
  for (adr_i = 0; adr_i < 4194304; adr_i = adr_i + 1)
4022
  begin
4023
    eth_phy.rx_mem[adr_i[21:0]] = 0;
4024
    eth_phy.tx_mem[adr_i[21:0]] = 0;
4025
    wb_slave.wb_memory[adr_i[21:2]] = 0;
4026
  end
4027
end
4028
endtask // clear_memories
4029
 
4030
task clear_buffer_descriptors;
4031
  reg    [8:0]  adr_i;
4032
  reg            delta_t;
4033
begin
4034
  delta_t = 0;
4035
  for (adr_i = 0; adr_i < 256; adr_i = adr_i + 1)
4036
  begin
4037
    wbm_write((`TX_BD_BASE + {adr_i[7:0], 2'b0}), 32'h0, 4'hF, 1, 4'h1, 4'h1);
4038
    delta_t = !delta_t;
4039
  end
4040
end
4041
endtask // clear_buffer_descriptors
4042
 
4043
task test_note;
4044
  input [799:0] test_note ;
4045
  reg   [799:0] display_note ;
4046
begin
4047
  display_note = test_note;
4048
  while ( display_note[799:792] == 0 )
4049
    display_note = display_note << 8 ;
4050
  $fdisplay( tb_log_file, " " ) ;
4051
  $fdisplay( tb_log_file, "NOTE: %s", display_note ) ;
4052
  $fdisplay( tb_log_file, " " ) ;
4053
end
4054
endtask // test_note
4055
 
4056
task test_heading;
4057
  input [799:0] test_heading ;
4058
  reg   [799:0] display_test ;
4059
begin
4060
  display_test = test_heading;
4061
  while ( display_test[799:792] == 0 )
4062
    display_test = display_test << 8 ;
4063
  $fdisplay( tb_log_file, "  ***************************************************************************************" ) ;
4064
  $fdisplay( tb_log_file, "  ***************************************************************************************" ) ;
4065
  $fdisplay( tb_log_file, "  Heading: %s", display_test ) ;
4066
  $fdisplay( tb_log_file, "  ***************************************************************************************" ) ;
4067
  $fdisplay( tb_log_file, "  ***************************************************************************************" ) ;
4068
  $fdisplay( tb_log_file, " " ) ;
4069
end
4070
endtask // test_heading
4071
 
4072
 
4073
task test_fail ;
4074
  input [7999:0] failure_reason ;
4075
//  reg   [8007:0] display_failure ;
4076
  reg   [7999:0] display_failure ;
4077
  reg   [799:0] display_test ;
4078
begin
4079
  tests_failed = tests_failed + 1 ;
4080
 
4081
  display_failure = failure_reason; // {failure_reason, "!"} ;
4082
  while ( display_failure[7999:7992] == 0 )
4083
    display_failure = display_failure << 8 ;
4084
 
4085
  display_test = test_name ;
4086
  while ( display_test[799:792] == 0 )
4087
    display_test = display_test << 8 ;
4088
 
4089
  $fdisplay( tb_log_file, "    *************************************************************************************" ) ;
4090
  $fdisplay( tb_log_file, "    At time: %t ", $time ) ;
4091
  $fdisplay( tb_log_file, "    Test: %s", display_test ) ;
4092
  $fdisplay( tb_log_file, "    *FAILED* because") ;
4093
  $fdisplay( tb_log_file, "    %s", display_failure ) ;
4094
  $fdisplay( tb_log_file, "    *************************************************************************************" ) ;
4095
  $fdisplay( tb_log_file, " " ) ;
4096
 
4097
 `ifdef STOP_ON_FAILURE
4098
    #20 $stop ;
4099
 `endif
4100
end
4101
endtask // test_fail
4102
 
4103
 
4104
task test_fail_num ;
4105
  input [7999:0] failure_reason ;
4106
  input [31:0]   number ;
4107
//  reg   [8007:0] display_failure ;
4108
  reg   [7999:0] display_failure ;
4109
  reg   [799:0] display_test ;
4110
begin
4111
  tests_failed = tests_failed + 1 ;
4112
 
4113
  display_failure = failure_reason; // {failure_reason, "!"} ;
4114
  while ( display_failure[7999:7992] == 0 )
4115
    display_failure = display_failure << 8 ;
4116
 
4117
  display_test = test_name ;
4118
  while ( display_test[799:792] == 0 )
4119
    display_test = display_test << 8 ;
4120
 
4121
  $fdisplay( tb_log_file, "    *************************************************************************************" ) ;
4122
  $fdisplay( tb_log_file, "    At time: %t ", $time ) ;
4123
  $fdisplay( tb_log_file, "    Test: %s", display_test ) ;
4124
  $fdisplay( tb_log_file, "    *FAILED* because") ;
4125
  $fdisplay( tb_log_file, "    %s; %d", display_failure, number ) ;
4126
  $fdisplay( tb_log_file, "    *************************************************************************************" ) ;
4127
  $fdisplay( tb_log_file, " " ) ;
4128
 
4129
 `ifdef STOP_ON_FAILURE
4130
    #20 $stop ;
4131
 `endif
4132
end
4133
endtask // test_fail_num
4134
 
4135
 
4136
task test_ok ;
4137
  reg [799:0] display_test ;
4138
begin
4139
  tests_successfull = tests_successfull + 1 ;
4140
 
4141
  display_test = test_name ;
4142
  while ( display_test[799:792] == 0 )
4143
    display_test = display_test << 8 ;
4144
 
4145
  $fdisplay( tb_log_file, "    *************************************************************************************" ) ;
4146
  $fdisplay( tb_log_file, "    At time: %t ", $time ) ;
4147
  $fdisplay( tb_log_file, "    Test: %s", display_test ) ;
4148
  $fdisplay( tb_log_file, "    reported *SUCCESSFULL*! ") ;
4149
  $fdisplay( tb_log_file, "    *************************************************************************************" ) ;
4150
  $fdisplay( tb_log_file, " " ) ;
4151
end
4152
endtask // test_ok
4153
 
4154
 
4155
task test_summary;
4156
begin
4157
  $fdisplay(tb_log_file, "**************************** Ethernet MAC test summary **********************************") ;
4158
  $fdisplay(tb_log_file, "Tests performed:   %d", tests_successfull + tests_failed) ;
4159
  $fdisplay(tb_log_file, "Failed tests   :   %d", tests_failed) ;
4160
  $fdisplay(tb_log_file, "Successfull tests: %d", tests_successfull) ;
4161
  $fdisplay(tb_log_file, "**************************** Ethernet MAC test summary **********************************") ;
4162
  $fclose(tb_log_file) ;
4163
end
4164
endtask // test_summary
4165
 
4166
endmodule

powered by: WebSVN 2.1.0

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