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

Subversion Repositories ethmac

[/] [ethmac/] [trunk/] [bench/] [verilog/] [tb_ethernet.v] - Diff between revs 158 and 169

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 158 Rev 169
Line 4... Line 4...
////                                                              ////
////                                                              ////
////  This file is part of the Ethernet IP core project           ////
////  This file is part of the Ethernet IP core project           ////
////  http://www.opencores.org/projects/ethmac/                   ////
////  http://www.opencores.org/projects/ethmac/                   ////
////                                                              ////
////                                                              ////
////  Author(s):                                                  ////
////  Author(s):                                                  ////
////      - Igor Mohor (igorM@opencores.org)                      ////
////      - Tadej Markovic, tadej@opencores.org                   ////
////                                                              ////
////                                                              ////
////  All additional information is avaliable in the Readme.txt   ////
////  All additional information is available in the Readme.txt   ////
////  file.                                                       ////
////  file.                                                       ////
////                                                              ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
////                                                              ////
////                                                              ////
//// Copyright (C) 2001, 2002 Authors                             ////
//// Copyright (C) 2001, 2002 Authors                             ////
Line 39... Line 39...
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//
//
// CVS Revision History
// CVS Revision History
//
//
// $Log: not supported by cvs2svn $
// $Log: not supported by cvs2svn $
// Revision 1.4  2002/09/06 11:03:24  mohor
 
// Valid testbench.
 
//
 
// Revision 1.3  2002/07/23 16:34:31  mohor
 
// gsr added for use when ETH_XILINX_RAMB4 define is set.
 
//
 
// Revision 1.2  2002/07/19 14:02:47  mohor
// Revision 1.2  2002/07/19 14:02:47  mohor
// Clock mrx_clk set to 2.5 MHz.
// Clock mrx_clk set to 2.5 MHz.
//
//
// Revision 1.1  2002/07/19 13:57:53  mohor
// Revision 1.1  2002/07/19 13:57:53  mohor
// Testing environment also includes traffic cop, memory interface and host
// Testing environment also includes traffic cop, memory interface and host
Line 58... Line 52...
//
//
//
//
//
//
 
 
 
 
 
`define TIME $display("  Time: %0t", $time)
 
 
 
`include "eth_phy_defines.v"
 
`include "wb_model_defines.v"
`include "tb_eth_defines.v"
`include "tb_eth_defines.v"
`include "eth_defines.v"
`include "eth_defines.v"
`include "timescale.v"
`include "timescale.v"
 
 
module tb_ethernet();
module tb_ethernet();
 
 
 
 
parameter Tp = 1;
reg           wb_clk;
 
reg           wb_rst;
 
wire          wb_int;
reg           wb_clk_o;
 
reg           wb_rst_o;
 
 
 
reg           mtx_clk;
wire          mtx_clk;  // This goes to PHY
reg           mrx_clk;
wire          mrx_clk;  // This goes to PHY
 
 
wire   [3:0]  MTxD;
wire   [3:0]  MTxD;
wire          MTxEn;
wire          MTxEn;
wire          MTxErr;
wire          MTxErr;
 
 
reg    [3:0]  MRxD;     // This goes to PHY
wire   [3:0]  MRxD;     // This goes to PHY
reg           MRxDV;    // This goes to PHY
wire          MRxDV;    // This goes to PHY
reg           MRxErr;   // This goes to PHY
wire          MRxErr;   // This goes to PHY
reg           MColl;    // This goes to PHY
wire          MColl;    // This goes to PHY
reg           MCrs;     // This goes to PHY
wire          MCrs;     // This goes to PHY
 
 
wire          Mdi_I;
wire          Mdi_I;
wire          Mdo_O;
wire          Mdo_O;
wire          Mdo_OE;
wire          Mdo_OE;
 
tri           Mdio_IO;
wire          Mdc_O;
wire          Mdc_O;
 
 
integer tx_log;
 
integer rx_log;
 
 
 
reg StartTB;
 
 
 
`ifdef ETH_XILINX_RAMB4
 
  reg gsr;
 
`endif
 
 
 
 
 
integer packet_ready_cnt, send_packet_cnt;
parameter Tp = 1;
 
 
 
 
// Ethernet Slave Interface signals
// Ethernet Slave Interface signals
 
wire [31:0] eth_sl_wb_adr;
wire [31:0] eth_sl_wb_adr_i, eth_sl_wb_dat_o, eth_sl_wb_dat_i;
wire [31:0] eth_sl_wb_adr_i, eth_sl_wb_dat_o, eth_sl_wb_dat_i;
wire  [3:0] eth_sl_wb_sel_i;
wire  [3:0] eth_sl_wb_sel_i;
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;
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;
 
 
// Memory Slave Interface signals
 
wire [31:0] mem_sl_wb_adr_i, mem_sl_wb_dat_o, mem_sl_wb_dat_i;
 
wire  [3:0] mem_sl_wb_sel_i;
 
wire        mem_sl_wb_we_i, mem_sl_wb_cyc_i, mem_sl_wb_stb_i, mem_sl_wb_ack_o, mem_sl_wb_err_o;
 
 
 
// Ethernet Master Interface signals
// Ethernet Master Interface signals
wire [31:0] eth_ma_wb_adr_o, eth_ma_wb_dat_i, eth_ma_wb_dat_o;
wire [31:0] eth_ma_wb_adr_o, eth_ma_wb_dat_i, eth_ma_wb_dat_o;
wire  [3:0] eth_ma_wb_sel_o;
wire  [3:0] eth_ma_wb_sel_o;
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;
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;
 
 
// Host Master Interface signals
 
wire [31:0] host_ma_wb_adr_o, host_ma_wb_dat_i, host_ma_wb_dat_o;
 
wire  [3:0] host_ma_wb_sel_o;
 
wire        host_ma_wb_we_o, host_ma_wb_cyc_o, host_ma_wb_stb_o, host_ma_wb_ack_i, host_ma_wb_err_i;
 
 
 
 
 
 
 
eth_cop i_eth_cop
 
(
 
  // WISHBONE common
 
  .wb_clk_i(wb_clk_o), .wb_rst_i(wb_rst_o),
 
 
 
  // WISHBONE MASTER 1  Ethernet Master Interface is connected here
 
  .m1_wb_adr_i(eth_ma_wb_adr_o),  .m1_wb_sel_i(eth_ma_wb_sel_o),  .m1_wb_we_i (eth_ma_wb_we_o),
 
  .m1_wb_dat_o(eth_ma_wb_dat_i),  .m1_wb_dat_i(eth_ma_wb_dat_o),  .m1_wb_cyc_i(eth_ma_wb_cyc_o),
 
  .m1_wb_stb_i(eth_ma_wb_stb_o),  .m1_wb_ack_o(eth_ma_wb_ack_i),  .m1_wb_err_o(eth_ma_wb_err_i),
 
 
 
  // WISHBONE MASTER 2  Host Interface is connected here
 
  .m2_wb_adr_i(host_ma_wb_adr_o), .m2_wb_sel_i(host_ma_wb_sel_o), .m2_wb_we_i (host_ma_wb_we_o),
 
  .m2_wb_dat_o(host_ma_wb_dat_i), .m2_wb_dat_i(host_ma_wb_dat_o), .m2_wb_cyc_i(host_ma_wb_cyc_o),
 
  .m2_wb_stb_i(host_ma_wb_stb_o), .m2_wb_ack_o(host_ma_wb_ack_i), .m2_wb_err_o(host_ma_wb_err_i),
 
 
 
  // WISHBONE slave 1   Ethernet Slave Interface is connected here
 
        .s1_wb_adr_o(eth_sl_wb_adr_i),  .s1_wb_sel_o(eth_sl_wb_sel_i),  .s1_wb_we_o (eth_sl_wb_we_i),
 
        .s1_wb_cyc_o(eth_sl_wb_cyc_i),  .s1_wb_stb_o(eth_sl_wb_stb_i),  .s1_wb_ack_i(eth_sl_wb_ack_o),
 
        .s1_wb_err_i(eth_sl_wb_err_o),  .s1_wb_dat_i(eth_sl_wb_dat_o),  .s1_wb_dat_o(eth_sl_wb_dat_i),
 
 
 
  // WISHBONE slave 2   Memory Interface is connected here
 
        .s2_wb_adr_o(mem_sl_wb_adr_i),  .s2_wb_sel_o(mem_sl_wb_sel_i),  .s2_wb_we_o (mem_sl_wb_we_i),
 
        .s2_wb_cyc_o(mem_sl_wb_cyc_i),  .s2_wb_stb_o(mem_sl_wb_stb_i),  .s2_wb_ack_i(mem_sl_wb_ack_o),
 
        .s2_wb_err_i(mem_sl_wb_err_o),  .s2_wb_dat_i(mem_sl_wb_dat_o),  .s2_wb_dat_o(mem_sl_wb_dat_i)
 
);
 
 
 
 
 
 
 
 
 
// Connecting Ethernet top module
// Connecting Ethernet top module
eth_top ethtop
eth_top eth_top
(
(
  // WISHBONE common
  // WISHBONE common
  .wb_clk_i(wb_clk_o),              .wb_rst_i(wb_rst_o),
  .wb_clk_i(wb_clk),              .wb_rst_i(wb_rst),
 
 
  // WISHBONE slave
  // WISHBONE slave
        .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),
        .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),
        .wb_cyc_i(eth_sl_wb_cyc_i),       .wb_stb_i(eth_sl_wb_stb_i),   .wb_ack_o(eth_sl_wb_ack_o),
        .wb_cyc_i(eth_sl_wb_cyc_i),       .wb_stb_i(eth_sl_wb_stb_i),   .wb_ack_o(eth_sl_wb_ack_o),
        .wb_err_o(eth_sl_wb_err_o),       .wb_dat_i(eth_sl_wb_dat_i),   .wb_dat_o(eth_sl_wb_dat_o),
        .wb_err_o(eth_sl_wb_err_o),       .wb_dat_i(eth_sl_wb_dat_i),   .wb_dat_o(eth_sl_wb_dat_o),
Line 180... Line 130...
  .mcoll_pad_i(MColl),    .mcrs_pad_i(MCrs),
  .mcoll_pad_i(MColl),    .mcrs_pad_i(MCrs),
 
 
  // MIIM
  // MIIM
  .mdc_pad_o(Mdc_O), .md_pad_i(Mdi_I), .md_pad_o(Mdo_O), .md_padoe_o(Mdo_OE),
  .mdc_pad_o(Mdc_O), .md_pad_i(Mdi_I), .md_pad_o(Mdo_O), .md_padoe_o(Mdo_OE),
 
 
  .int_o()
  .int_o(wb_int)
);
);
 
 
 
 
 
 
// Connecting Memory Interface Module
// Connecting Ethernet PHY Module
eth_memory i_eth_memory
assign Mdio_IO = Mdo_OE ? Mdo_O : 1'bz ;
 
assign Mdi_I   = Mdio_IO;
 
integer phy_log_file_desc;
 
 
 
eth_phy eth_phy
(
(
  // WISHBONE common
  // WISHBONE reset
        .wb_clk_i(wb_clk_o),         .wb_rst_i(wb_rst_o),
  .m_rst_n_i(!wb_rst),
 
 
 
  // MAC TX
 
  .mtx_clk_o(mtx_clk),    .mtxd_i(MTxD),    .mtxen_i(MTxEn),    .mtxerr_i(MTxErr),
 
 
 
  // MAC RX
 
  .mrx_clk_o(mrx_clk),    .mrxd_o(MRxD),    .mrxdv_o(MRxDV),    .mrxerr_o(MRxErr),
 
  .mcoll_o(MColl),        .mcrs_o(MCrs),
 
 
  // WISHBONE slave:   Memory Interface is connected here
  // MIIM
        .wb_adr_i(mem_sl_wb_adr_i),  .wb_sel_i(mem_sl_wb_sel_i),  .wb_we_i (mem_sl_wb_we_i),
  .mdc_i(Mdc_O),          .md_io(Mdio_IO),
        .wb_cyc_i(mem_sl_wb_cyc_i),  .wb_stb_i(mem_sl_wb_stb_i),  .wb_ack_o(mem_sl_wb_ack_o),
 
        .wb_err_o(mem_sl_wb_err_o),  .wb_dat_o(mem_sl_wb_dat_o),  .wb_dat_i(mem_sl_wb_dat_i)
  // SYSTEM
 
  .phy_log(phy_log_file_desc)
);
);
 
 
 
 
// Connecting Host Interface
 
eth_host eth_host
// Connecting WB Master as Host Interface
 
integer host_log_file_desc;
 
 
 
WB_MASTER_BEHAVIORAL wb_master
(
(
  // WISHBONE common
    .CLK_I(wb_clk),
  .wb_clk_i(wb_clk_o),         .wb_rst_i(wb_rst_o),
    .RST_I(wb_rst),
 
    .TAG_I({`WB_TAG_WIDTH{1'b0}}),
 
    .TAG_O(),
 
    .ACK_I(eth_sl_wb_ack_o),
 
    .ADR_O(eth_sl_wb_adr), // only eth_sl_wb_adr_i[11:2] used
 
    .CYC_O(eth_sl_wb_cyc_i),
 
    .DAT_I(eth_sl_wb_dat_o),
 
    .DAT_O(eth_sl_wb_dat_i),
 
    .ERR_I(eth_sl_wb_err_o),
 
    .RTY_I(1'b0),  // inactive (1'b0)
 
    .SEL_O(eth_sl_wb_sel_i),
 
    .STB_O(eth_sl_wb_stb_i),
 
    .WE_O (eth_sl_wb_we_i),
 
    .CAB_O()       // NOT USED for now!
 
);
 
 
  // WISHBONE master
assign eth_sl_wb_adr_i = {20'h0, eth_sl_wb_adr[11:2], 2'h0};
  .wb_adr_o(host_ma_wb_adr_o), .wb_sel_o(host_ma_wb_sel_o), .wb_we_o (host_ma_wb_we_o),
 
  .wb_dat_i(host_ma_wb_dat_i), .wb_dat_o(host_ma_wb_dat_o), .wb_cyc_o(host_ma_wb_cyc_o),
 
  .wb_stb_o(host_ma_wb_stb_o), .wb_ack_i(host_ma_wb_ack_i), .wb_err_i(host_ma_wb_err_i)
 
 
// Connecting WB Slave as Memory Interface Module
 
integer memory_log_file_desc;
 
 
 
WB_SLAVE_BEHAVIORAL wb_slave
 
(
 
    .CLK_I(wb_clk),
 
    .RST_I(wb_rst),
 
    .ACK_O(eth_ma_wb_ack_i),
 
    .ADR_I(eth_ma_wb_adr_o),
 
    .CYC_I(eth_ma_wb_cyc_o),
 
    .DAT_O(eth_ma_wb_dat_i),
 
    .DAT_I(eth_ma_wb_dat_o),
 
    .ERR_O(eth_ma_wb_err_i),
 
    .RTY_O(),      // NOT USED for now!
 
    .SEL_I(eth_ma_wb_sel_o),
 
    .STB_I(eth_ma_wb_stb_o),
 
    .WE_I (eth_ma_wb_we_o),
 
    .CAB_I(1'b0)   // inactive (1'b0)
);
);
 
 
 
 
 
 
 
// Connecting WISHBONE Bus Monitors to ethernet master and slave interfaces
 
integer wb_s_mon_log_file_desc ;
 
integer wb_m_mon_log_file_desc ;
 
 
 
WB_BUS_MON wb_eth_slave_bus_mon
 
(
 
  // WISHBONE common
 
  .CLK_I(wb_clk),
 
  .RST_I(wb_rst),
 
 
// Reset pulse
  // WISHBONE slave
initial
  .ACK_I(eth_sl_wb_ack_o),
begin
  .ADDR_O({20'h0, eth_sl_wb_adr_i[11:2], 2'b0}),
  MCrs=0;                                     // This should come from PHY
  .CYC_O(eth_sl_wb_cyc_i),
  MColl=0;                                    // This should come from PHY
  .DAT_I(eth_sl_wb_dat_o),
  MRxD=0;                                     // This should come from PHY
  .DAT_O(eth_sl_wb_dat_i),
  MRxDV=0;                                    // This should come from PHY
  .ERR_I(eth_sl_wb_err_o),
  MRxErr=0;                                   // This should come from PHY
  .RTY_I(1'b0),
  packet_ready_cnt = 0;
  .SEL_O(eth_sl_wb_sel_i),
  send_packet_cnt = 0;
  .STB_O(eth_sl_wb_stb_i),
  tx_log = $fopen("ethernet_tx.log");
  .WE_O (eth_sl_wb_we_i),
  rx_log = $fopen("ethernet_rx.log");
  .TAG_I({`WB_TAG_WIDTH{1'b0}}),
  wb_rst_o =  1'b1;
  .TAG_O(),
`ifdef ETH_XILINX_RAMB4
  .CAB_O(1'b0),
  gsr           =  1'b0;
  .log_file_desc (wb_s_mon_log_file_desc)
  #100 gsr      =  1'b1;
);
  #100 gsr      =  1'b0;
 
`endif
WB_BUS_MON wb_eth_master_bus_mon
  #100 wb_rst_o =  1'b0;
(
  #100 StartTB  =  1'b1;
  // WISHBONE common
end
  .CLK_I(wb_clk),
 
  .RST_I(wb_rst),
 
 
 
  // WISHBONE master
 
  .ACK_I(eth_ma_wb_ack_i),
 
  .ADDR_O(eth_ma_wb_adr_o),
 
  .CYC_O(eth_ma_wb_cyc_o),
 
  .DAT_I(eth_ma_wb_dat_i),
 
  .DAT_O(eth_ma_wb_dat_o),
 
  .ERR_I(eth_ma_wb_err_i),
 
  .RTY_I(1'b0),
 
  .SEL_O(eth_ma_wb_sel_o),
 
  .STB_O(eth_ma_wb_stb_o),
 
  .WE_O (eth_ma_wb_we_o),
 
  .TAG_I({`WB_TAG_WIDTH{1'b0}}),
 
  .TAG_O(),
 
  .CAB_O(1'b0),
 
  .log_file_desc(wb_m_mon_log_file_desc)
 
);
 
 
`ifdef ETH_XILINX_RAMB4
 
  assign glbl.GSR = gsr;
 
`endif
 
 
 
 
 
 
reg         StartTB;
 
integer     tb_log_file;
 
 
// Generating wb_clk_o clock
 
initial
initial
begin
begin
  wb_clk_o=0;
  tb_log_file = $fopen("../log/eth_tb.log");
//  forever #2.5 wb_clk_o = ~wb_clk_o;  // 2*2.5 ns -> 200.0 MHz    
  if (tb_log_file < 2)
//  forever #5 wb_clk_o = ~wb_clk_o;  // 2*5 ns -> 100.0 MHz    
  begin
//  forever #10 wb_clk_o = ~wb_clk_o;  // 2*10 ns -> 50.0 MHz    
    $display("*E Could not open/create testbench log file in ../log/ directory!");
//  forever #12.5 wb_clk_o = ~wb_clk_o;  // 2*12.5 ns -> 40 MHz    
    $finish;
//  forever #15 wb_clk_o = ~wb_clk_o;  // 2*10 ns -> 33.3 MHz    
 
  forever #20 wb_clk_o = ~wb_clk_o;  // 2*20 ns -> 25 MHz    
 
//  forever #25 wb_clk_o = ~wb_clk_o;  // 2*25 ns -> 20.0 MHz
 
//  forever #31.25 wb_clk_o = ~wb_clk_o;  // 2*31.25 ns -> 16.0 MHz    
 
//  forever #50 wb_clk_o = ~wb_clk_o;  // 2*50 ns -> 10.0 MHz
 
//  forever #55 wb_clk_o = ~wb_clk_o;  // 2*55 ns ->  9.1 MHz    
 
end
end
 
  $fdisplay(tb_log_file, "========================== ETHERNET IP Core Testbench results ===========================");
 
  $fdisplay(tb_log_file, " ");
 
 
// Generating mtx_clk clock
  phy_log_file_desc = $fopen("../log/eth_tb_phy.log");
initial
  if (phy_log_file_desc < 2)
begin
begin
  mtx_clk=0;
    $fdisplay(tb_log_file, "*E Could not open/create eth_tb_phy.log file in ../log/ directory!");
  #3 forever #20 mtx_clk = ~mtx_clk;   // 2*20 ns -> 25 MHz
    $finish;
//  #3 forever #200 mtx_clk = ~mtx_clk;   // 2*200 ns -> 2.5 MHz
 
end
end
 
  $fdisplay(phy_log_file_desc, "================ PHY Module  Testbench access log ================");
 
  $fdisplay(phy_log_file_desc, " ");
 
 
// Generating mrx_clk clock
  memory_log_file_desc = $fopen("../log/eth_tb_memory.log");
initial
  if (memory_log_file_desc < 2)
begin
begin
  mrx_clk=0;
    $fdisplay(tb_log_file, "*E Could not open/create eth_tb_memory.log file in ../log/ directory!");
  #16 forever #20 mrx_clk = ~mrx_clk;   // 2*20 ns -> 25 MHz
    $finish;
//  #16 forever #200 mrx_clk = ~mrx_clk;   // 2*200 ns -> 2.5 MHz
 
end
end
 
  $fdisplay(memory_log_file_desc, "=============== MEMORY Module Testbench access log ===============");
 
  $fdisplay(memory_log_file_desc, " ");
 
 
reg [31:0] tmp;
  host_log_file_desc = $fopen("../log/eth_tb_host.log");
initial
  if (host_log_file_desc < 2)
begin
begin
  wait(StartTB);  // Start of testbench
    $fdisplay(tb_log_file, "*E Could not open/create eth_tb_host.log file in ../log/ directory!");
 
    $finish;
 
  end
  eth_host.wb_write(`ETH_MODER, 4'hf, 32'h0); // Reset OFF
  $fdisplay(host_log_file_desc, "================ HOST Module Testbench access log ================");
  eth_host.wb_read(`ETH_MODER, 4'hf, tmp);
  $fdisplay(host_log_file_desc, " ");
  eth_host.wb_write(`ETH_MAC_ADDR1, 4'hf, 32'h0002); // Set ETH_MAC_ADDR1 register
 
  eth_host.wb_write(`ETH_MAC_ADDR0, 4'hf, 32'h03040506); // Set ETH_MAC_ADDR0 register
 
 
 
  initialize_txbd(3);
 
  initialize_rxbd(2);
 
 
 
//  eth_host.wb_write(`ETH_MODER, 4'hf, `ETH_MODER_RXEN  | `ETH_MODER_TXEN | `ETH_MODER_PRO | 
 
//                                      `ETH_MODER_CRCEN | `ETH_MODER_PAD); // Set MODER register
 
//  eth_host.wb_write(`ETH_MODER, 4'hf, `ETH_MODER_RXEN  | `ETH_MODER_TXEN | 
 
//                                      `ETH_MODER_CRCEN | `ETH_MODER_PAD); // Set MODER register
 
  eth_host.wb_write(`ETH_MODER, 4'hf, `ETH_MODER_RXEN  | `ETH_MODER_TXEN | `ETH_MODER_BRO |
 
                                      `ETH_MODER_CRCEN | `ETH_MODER_PAD); // Set MODER register
 
//  eth_host.wb_write(`ETH_MODER, 4'hf, `ETH_MODER_RXEN  | `ETH_MODER_TXEN | `ETH_MODER_PRO | 
 
//                                      `ETH_MODER_CRCEN | `ETH_MODER_PAD | `ETH_MODER_LOOPBCK); // Set MODER register
 
//  eth_host.wb_write(`ETH_MODER, 4'hf, `ETH_MODER_RXEN  | `ETH_MODER_TXEN | `ETH_MODER_PRO | 
 
//                                      `ETH_MODER_CRCEN | `ETH_MODER_PAD | `ETH_MODER_LOOPBCK | 
 
//                                      `ETH_MODER_FULLD); // Set MODER register
 
  eth_host.wb_read(`ETH_MODER, 4'hf, tmp);
 
 
 
  set_packet(16'h64, 8'h1);
 
  set_packet(16'h34, 8'h11);
 
  send_packet;
 
  set_packet(16'h34, 8'h21);
 
  set_packet(16'h34, 8'h31);
 
/*
 
  eth_host.wb_write(`ETH_CTRLMODER, 4'hf, 32'h4);   // Enable Tx Flow control
 
  eth_host.wb_write(`ETH_CTRLMODER, 4'hf, 32'h5);   // Enable Tx Flow control
 
  eth_host.wb_write(`ETH_TX_CTRL, 4'hf, 32'h10013); // Send Control frame with PAUSE_TV=0x0013
 
*/
 
  send_packet;
 
 
 
 
 
  GetDataOnMRxD(100, `UNICAST_XFR); // LengthRx bytes is comming on MRxD[3:0] signals
  wb_s_mon_log_file_desc = $fopen("../log/eth_tb_wb_s_mon.log");
 
  if (wb_s_mon_log_file_desc < 2)
 
  begin
 
    $fdisplay(tb_log_file, "*E Could not open/create eth_tb_wb_s_mon.log file in ../log/ directory!");
 
    $finish;
 
  end
 
  $fdisplay(wb_s_mon_log_file_desc, "============== WISHBONE Slave Bus Monitor error log ==============");
 
  $fdisplay(wb_s_mon_log_file_desc, " ");
 
  $fdisplay(wb_s_mon_log_file_desc, "   Only ERRONEOUS conditions are logged !");
 
  $fdisplay(wb_s_mon_log_file_desc, " ");
 
 
  repeat (1000) @(posedge wb_clk_o);   // Waiting for TxEthMac to finish transmit
  wb_m_mon_log_file_desc = $fopen("../log/eth_tb_wb_m_mon.log");
 
  if (wb_m_mon_log_file_desc < 2)
 
  begin
 
    $fdisplay(tb_log_file, "*E Could not open/create eth_tb_wb_m_mon.log file in ../log/ directory!");
 
    $finish;
 
  end
 
  $fdisplay(wb_m_mon_log_file_desc, "============= WISHBONE Master Bus Monitor  error log =============");
 
  $fdisplay(wb_m_mon_log_file_desc, " ");
 
  $fdisplay(wb_m_mon_log_file_desc, "   Only ERRONEOUS conditions are logged !");
 
  $fdisplay(wb_m_mon_log_file_desc, " ");
 
 
  GetDataOnMRxD(500, `BROADCAST_XFR); // LengthRx bytes is comming on MRxD[3:0] signals
  // Clear memories
 
  clear_memories;
 
 
  repeat (1000) @(posedge mrx_clk);   // Waiting for TxEthMac to finish transmit
  // Reset pulse
 
  wb_rst =  1'b1;
 
  #423 wb_rst =  1'b0;
 
  #423 StartTB  =  1'b1;
 
end
 
 
 
 
  GetDataOnMRxD(1200, `BROADCAST_XFR); // LengthRx bytes is comming on MRxD[3:0] signals
 
 
 
 
// Generating wb_clk clock
 
initial
 
begin
 
  wb_clk=0;
 
//  forever #2.5 wb_clk = ~wb_clk;  // 2*2.5 ns -> 200.0 MHz    
 
//  forever #5 wb_clk = ~wb_clk;  // 2*5 ns -> 100.0 MHz    
 
//  forever #10 wb_clk = ~wb_clk;  // 2*10 ns -> 50.0 MHz    
 
//  forever #12.5 wb_clk = ~wb_clk;  // 2*12.5 ns -> 40 MHz    
 
//  forever #15 wb_clk = ~wb_clk;  // 2*10 ns -> 33.3 MHz    
 
  forever #20 wb_clk = ~wb_clk;  // 2*20 ns -> 25 MHz    
 
//  forever #25 wb_clk = ~wb_clk;  // 2*25 ns -> 20.0 MHz
 
//  forever #31.25 wb_clk = ~wb_clk;  // 2*31.25 ns -> 16.0 MHz    
 
//  forever #50 wb_clk = ~wb_clk;  // 2*50 ns -> 10.0 MHz
 
//  forever #55 wb_clk = ~wb_clk;  // 2*55 ns ->  9.1 MHz    
 
end
 
 
  GetDataOnMRxD(1000, `UNICAST_XFR); // LengthRx bytes is comming on MRxD[3:0] signals
 
 
 
  repeat (10000) @(posedge wb_clk_o);   // Waiting for TxEthMac to finish transmit
 
 
 
  // Reading and printing interrupts
integer      tests_successfull;
  eth_host.wb_read(`ETH_INT, 4'hf, tmp);
integer      tests_failed;
  $display("Print irq = 0x%0x", tmp);
reg [799:0]  test_name; // used for tb_log_file
 
 
 
reg   [3:0]  wbm_init_waits; // initial wait cycles between CYC_O and STB_O of WB Master
 
reg   [3:0]  wbm_subseq_waits; // subsequent wait cycles between STB_Os of WB Master
 
reg   [2:0]  wbs_waits; // wait cycles befor WB Slave responds
 
reg   [7:0]  wbs_retries; // if RTY response, then this is the number of retries before ACK
 
 
  //Clearing all interrupts
initial
  eth_host.wb_write(`ETH_INT, 4'hf, 32'h60);
begin
 
  wait(StartTB);  // Start of testbench
 
 
  // Reading and printing interrupts
  // Initial global values
  eth_host.wb_read(`ETH_INT, 4'hf, tmp);
  tests_successfull = 0;
  $display("Print irq = 0x%0x", tmp);
  tests_failed = 0;
 
 
 
  wbm_init_waits = 4'h1;
 
  wbm_subseq_waits = 4'h3;
 
  wbs_waits = 4'h1;
 
  wbs_retries = 8'h2;
 
  wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries);
 
 
 
 
 
  //  Call tests
 
  //  ----------
 
    test_access_to_mac_reg(0, 3);          // 0 - 3
 
    test_mii(0, 17);                        // 0 - 17
 
  test_note("PHY generates ideal Carrier sense and Collision signals for following tests");
 
  eth_phy.carrier_sense_real_delay(0);
 
    test_mac_full_duplex_transmit(0, 3);   // 0 - (3)
 
 
 
  test_note("PHY generates 'real' Carrier sense and Collision signals for following tests");
 
  eth_phy.carrier_sense_real_delay(1);
 
 
 
 
 
  // Finish test's logs
 
  test_summary;
 
  $display("\n\n END of SIMULATION");
 
  $fclose(tb_log_file | phy_log_file_desc | memory_log_file_desc | host_log_file_desc);
 
  $fclose(wb_s_mon_log_file_desc | wb_m_mon_log_file_desc);
 
 
  $display("\n\n End of simulation");
 
  $stop;
  $stop;
 
 
 
 
 
 
end
end
 
 
 
 
 
 
task initialize_txbd;
//////////////////////////////////////////////////////////////
  input [6:0] txbd_num;
// Test tasks
 
//////////////////////////////////////////////////////////////
 
 
 
task test_access_to_mac_reg;
 
  input  [31:0]  start_task;
 
  input  [31:0]  end_task;
 
  integer        bit_start_1;
 
  integer        bit_end_1;
 
  integer        bit_start_2;
 
  integer        bit_end_2;
 
  integer        num_of_reg;
 
  integer        i_addr;
 
  integer        i_data;
 
  integer        i_length;
 
  integer        tmp_data;
 
  reg    [31:0]  tx_bd_num;
 
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_data;
 
  reg    [((`MAX_BLK_SIZE * 32) - 1):0] burst_tmp_data;
  integer i;
  integer i;
  integer bd_status_addr, buf_addr, bd_ptr_addr;
  integer        i1;
 
  integer        i2;
 
  integer        i3;
 
  integer        fail;
 
  reg    [31:0]  addr;
 
  reg    [31:0]  data;
 
  reg    [31:0]  data_max;
 
begin
 
// ACCESS TO MAC REGISTERS TEST
 
test_heading("ACCESS TO MAC REGISTERS TEST");
 
$display(" ");
 
$display("ACCESS TO MAC REGISTERS TEST");
 
fail = 0;
 
 
 
  /* Register space
 
     --------------
 
  `define ETH_MODER      `ETH_BASE + 32'h00      Mode Register
 
  `define ETH_INT        `ETH_BASE + 32'h04      Interrupt Source Register
 
  `define ETH_INT_MASK   `ETH_BASE + 32'h08      Interrupt Mask Register
 
  `define ETH_IPGT       `ETH_BASE + 32'h0C      Back to Bak Inter Packet Gap Register
 
  `define ETH_IPGR1      `ETH_BASE + 32'h10      Non Back to Back Inter Packet Gap Register 1
 
  `define ETH_IPGR2      `ETH_BASE + 32'h14      Non Back to Back Inter Packet Gap Register 2
 
  `define ETH_PACKETLEN  `ETH_BASE + 32'h18      Packet Length Register (min. and max.)
 
  `define ETH_COLLCONF   `ETH_BASE + 32'h1C      Collision and Retry Configuration Register
 
  `define ETH_TX_BD_NUM  `ETH_BASE + 32'h20      Transmit Buffer Descriptor Number Register
 
  `define ETH_CTRLMODER  `ETH_BASE + 32'h24      Control Module Mode Register
 
  `define ETH_MIIMODER   `ETH_BASE + 32'h28      MII Mode Register
 
  `define ETH_MIICOMMAND `ETH_BASE + 32'h2C      MII Command Register
 
  `define ETH_MIIADDRESS `ETH_BASE + 32'h30      MII Address Register
 
  `define ETH_MIITX_DATA `ETH_BASE + 32'h34      MII Transmit Data Register
 
  `define ETH_MIIRX_DATA `ETH_BASE + 32'h38      MII Receive Data Register
 
  `define ETH_MIISTATUS  `ETH_BASE + 32'h3C      MII Status Register
 
  `define ETH_MAC_ADDR0  `ETH_BASE + 32'h40      MAC Individual Address Register 0
 
  `define ETH_MAC_ADDR1  `ETH_BASE + 32'h44      MAC Individual Address Register 1
 
  `define ETH_HASH_ADDR0 `ETH_BASE + 32'h48      Hash Register 0
 
  `define ETH_HASH_ADDR1 `ETH_BASE + 32'h4C      Hash Register 1
 
  */
 
 
  for(i=0; i<txbd_num; i=i+1) begin
 
    buf_addr = `TX_BUF_BASE + i * 32'h600;
 
    bd_status_addr = `TX_BD_BASE + i * 8;
 
    bd_ptr_addr = bd_status_addr + 4;
 
 
 
    // Initializing BD - status
if ((start_task <= 0) && (end_task >= 0))
    if(i==txbd_num-1)
begin
      eth_host.wb_write(bd_status_addr, 4'hf, 32'h00007800);    // last BD: + WRAP
  // TEST 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )
    else
  test_name   = "TEST 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )";
      eth_host.wb_write(bd_status_addr, 4'hf, 32'h00005800);    // IRQ + PAD + CRC
  `TIME; $display("  TEST 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )");
 
 
    eth_host.wb_write(bd_ptr_addr, 4'hf, buf_addr);             // Initializing BD - pointer
  data = 0;
 
  for (i = 0; i <= 4; i = i + 1) // for initial wait cycles on WB bus
 
  begin
 
      wbm_init_waits = i;
 
      wbm_subseq_waits = {$random} % 5; // it is not important for single accesses
 
      for (i_addr = 0; i_addr <= 32'h4C; i_addr = i_addr + 4) // register address
 
      begin
 
        addr = `ETH_BASE + i_addr;
 
        // set ranges of R/W bits
 
        case (addr)
 
        `ETH_MODER:
 
          begin
 
            bit_start_1 = 0;
 
            bit_end_1   = 16;
 
            bit_start_2 = 32; // not used
 
            bit_end_2   = 32; // not used
 
          end
 
        `ETH_INT: // READONLY - tested within INT test
 
          begin
 
            bit_start_1 = 32; // not used
 
            bit_end_1   = 32; // not used
 
            bit_start_2 = 32; // not used
 
            bit_end_2   = 32; // not used
 
          end
 
        `ETH_INT_MASK:
 
          begin
 
            bit_start_1 = 0;
 
            bit_end_1   = 6;
 
            bit_start_2 = 32; // not used
 
            bit_end_2   = 32; // not used
 
          end
 
        `ETH_IPGT:
 
          begin
 
            bit_start_1 = 0;
 
            bit_end_1   = 6;
 
            bit_start_2 = 32; // not used
 
            bit_end_2   = 32; // not used
 
          end
 
        `ETH_IPGR1:
 
          begin
 
            bit_start_1 = 0;
 
            bit_end_1   = 6;
 
            bit_start_2 = 32; // not used
 
            bit_end_2   = 32; // not used
 
          end
 
        `ETH_IPGR2:
 
          begin
 
            bit_start_1 = 0;
 
            bit_end_1   = 6;
 
            bit_start_2 = 32; // not used
 
            bit_end_2   = 32; // not used
 
          end
 
        `ETH_PACKETLEN:
 
          begin
 
            bit_start_1 = 0;
 
            bit_end_1   = 31;
 
            bit_start_2 = 32; // not used
 
            bit_end_2   = 32; // not used
 
          end
 
        `ETH_COLLCONF:
 
          begin
 
            bit_start_1 = 0;
 
            bit_end_1   = 5;
 
            bit_start_2 = 16;
 
            bit_end_2   = 19;
 
          end
 
        `ETH_TX_BD_NUM:
 
          begin
 
            bit_start_1 = 0;
 
            bit_end_1   = 7;
 
            bit_start_2 = 32; // not used
 
            bit_end_2   = 32; // not used
 
          end
 
        `ETH_CTRLMODER:
 
          begin
 
            bit_start_1 = 0;
 
            bit_end_1   = 2;
 
            bit_start_2 = 32; // not used
 
            bit_end_2   = 32; // not used
 
          end
 
        `ETH_MIIMODER:
 
          begin
 
            bit_start_1 = 0;
 
            bit_end_1   = 9;
 
            bit_start_2 = 32; // not used
 
            bit_end_2   = 32; // not used
 
          end
 
        `ETH_MIICOMMAND: // "WRITEONLY" - tested within MIIM test - 3 LSBits are not written here!!!
 
          begin
 
            bit_start_1 = 32; // not used
 
            bit_end_1   = 32; // not used
 
            bit_start_2 = 32; // not used
 
            bit_end_2   = 32; // not used
 
          end
 
        `ETH_MIIADDRESS:
 
          begin
 
            bit_start_1 = 0;
 
            bit_end_1   = 4;
 
            bit_start_2 = 8;
 
            bit_end_2   = 12;
 
          end
 
        `ETH_MIITX_DATA:
 
          begin
 
            bit_start_1 = 0;
 
            bit_end_1   = 15;
 
            bit_start_2 = 32; // not used
 
            bit_end_2   = 32; // not used
 
          end
 
        `ETH_MIIRX_DATA: // READONLY - tested within MIIM test
 
          begin
 
            bit_start_1 = 32; // not used
 
            bit_end_1   = 32; // not used
 
            bit_start_2 = 32; // not used
 
            bit_end_2   = 32; // not used
 
          end
 
        `ETH_MIISTATUS: // READONLY - tested within MIIM test
 
          begin
 
            bit_start_1 = 32; // not used
 
            bit_end_1   = 32; // not used
 
            bit_start_2 = 32; // not used
 
            bit_end_2   = 32; // not used
 
          end
 
        `ETH_MAC_ADDR0:
 
          begin
 
            bit_start_1 = 0;
 
            bit_end_1   = 31;
 
            bit_start_2 = 32; // not used
 
            bit_end_2   = 32; // not used
 
          end
 
        `ETH_MAC_ADDR1:
 
          begin
 
            bit_start_1 = 0;
 
            bit_end_1   = 15;
 
            bit_start_2 = 32; // not used
 
            bit_end_2   = 32; // not used
 
          end
 
        `ETH_HASH_ADDR0:
 
          begin
 
            bit_start_1 = 0;
 
            bit_end_1   = 31;
 
            bit_start_2 = 32; // not used
 
            bit_end_2   = 32; // not used
 
          end
 
        default: // `ETH_HASH_ADDR1:
 
          begin
 
            bit_start_1 = 0;
 
            bit_end_1   = 31;
 
            bit_start_2 = 32; // not used
 
            bit_end_2   = 32; // not used
 
          end
 
        endcase
 
        for (i_data = 0; i_data <= 31; i_data = i_data + 1) // the position of walking one
 
        begin
 
          data = 1'b1 << i_data;
 
          if ( (addr == `ETH_MIICOMMAND) && (i_data <= 2) ) // DO NOT WRITE to 3 LSBits of MIICOMMAND !!!
 
          begin
  end
  end
endtask // initialize_txbd
 
 
 
 
 
task initialize_rxbd;
 
  input [6:0] rxbd_num;
 
 
 
  integer i;
 
  integer bd_status_addr, buf_addr, bd_ptr_addr;
 
 
 
  for(i=0; i<rxbd_num; i=i+1) begin
 
    buf_addr = `RX_BUF_BASE + i * 32'h600;
 
    bd_status_addr = `RX_BD_BASE + i * 8;
 
    bd_ptr_addr = bd_status_addr + 4;
 
 
 
    // Initializing BD - status
 
    if(i==rxbd_num-1)
 
      eth_host.wb_write(bd_status_addr, 4'hf, 32'h0000e000);    // last BD: + WRAP
 
    else
    else
      eth_host.wb_write(bd_status_addr, 4'hf, 32'h0000c000);    // IRQ + PAD + CRC
          begin
 
            wbm_write(addr, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
    eth_host.wb_write(bd_ptr_addr, 4'hf, buf_addr);             // Initializing BD - pointer
            wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
            if ( ((i_data >= bit_start_1) && (i_data <= bit_end_1)) ||
 
                 ((i_data >= bit_start_2) && (i_data <= bit_end_2)) ) // data should be equal to tmp_data
 
            begin
 
              if (tmp_data !== data)
 
              begin
 
                fail = fail + 1;
 
                test_fail("RW bit of the MAC register was not written or not read");
 
                `TIME;
 
                $display("wbm_init_waits %d, addr %h, data %h, tmp_data %h",
 
                          wbm_init_waits, addr, data, tmp_data);
  end
  end
endtask // initialize_rxbd
            end
 
            else // data should not be equal to tmp_data
 
 
task set_packet;
 
  input  [15:0] len;
 
  input   [7:0] start_data;
 
 
 
  integer i, sd;
 
  integer bd_status_addr, bd_ptr_addr, buffer, bd;
 
 
 
  begin
  begin
    sd = start_data;
              if (tmp_data === data)
    bd_status_addr = `TX_BD_BASE + packet_ready_cnt * 8;
              begin
    bd_ptr_addr = bd_status_addr + 4;
                fail = fail + 1;
 
                test_fail("NON RW bit of the MAC register was written, but it shouldn't be");
    // Reading BD + buffer pointer
                `TIME;
    eth_host.wb_read(bd_status_addr, 4'hf, bd);
                $display("wbm_init_waits %d, addr %h, data %h, tmp_data %h",
    eth_host.wb_read(bd_ptr_addr, 4'hf, buffer);
                          wbm_init_waits, addr, data, tmp_data);
 
 
    while(bd & `ETH_TX_BD_READY) begin  // Buffer is ready. Don't touch !!!
 
      repeat(100) @(posedge wb_clk_o);
 
      i=i+1;
 
      eth_host.wb_read(bd_status_addr, 4'hf, bd);
 
      if(i>1000)  begin
 
        $display("(%0t)(%m)Waiting for TxBD ready to clear timeout", $time);
 
        $stop;
 
      end
      end
    end
    end
 
 
    // First write might not be word allign.
 
    if(buffer[1:0]==1)  begin
 
      eth_host.wb_write(buffer-1, 4'h7, {8'h0, sd[7:0], sd[7:0]+3'h1, sd[7:0]+3'h2});
 
      sd=sd+3;
 
      i=3;
 
    end
    end
    else if(buffer[1:0]==2)  begin
 
      eth_host.wb_write(buffer-2, 4'h3, {16'h0, sd[7:0], sd[7:0]+3'h1});
 
      sd=sd+2;
 
      i=2;
 
    end
    end
    else if(buffer[1:0]==3)  begin
 
      eth_host.wb_write(buffer-3, 4'h1, {24'h0, sd[7:0]});
 
      sd=sd+1;
 
      i=1;
 
    end
    end
 
  end
 
  if(fail == 0)
 
    test_ok;
    else
    else
      i=0;
    fail = 0;    // Errors were reported previously
 
end
 
 
 
 
    for(i=i; i<len-4; i=i+4) begin   // Last 0-3 bytes are not written
if ((start_task <= 4) && (end_task >= 4)) // not used, since burst access to reg. is not supported
      eth_host.wb_write(buffer+i, 4'hf, {sd[7:0], sd[7:0]+3'h1, sd[7:0]+3'h2, sd[7:0]+3'h3});
begin
      sd=sd+4;
/*  // TEST 'WALKING ONE' WITH BURST CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )
 
  test_name   = "TEST 'WALKING ONE' WITH BURST CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )";
 
  `TIME; $display("  TEST 'WALKING ONE' WITH BURST CYCLES ACROSS MAC REGISTERS ( VARIOUS BUS DELAYS )");
 
 
 
  data = 0;
 
  burst_data = 0;
 
  burst_tmp_data = 0;
 
  i_length = 10; // two bursts for length 20
 
  for (i = 0; i <= 4; i = i + 1) // for initial wait cycles on WB bus
 
  begin
 
    for (i1 = 0; i1 <= 4; i1 = i1 + 1) // for initial wait cycles on WB bus
 
    begin
 
      wbm_init_waits = i;
 
      wbm_subseq_waits = i1;
 
      #1;
 
      for (i_data = 0; i_data <= 31; i_data = i_data + 1) // the position of walking one
 
      begin
 
        data = 1'b1 << i_data;
 
        #1;
 
        for (i2 = 32'h4C; i2 >= 0; i2 = i2 - 4)
 
        begin
 
          burst_data = burst_data << 32;
 
          // DO NOT WRITE to 3 LSBits of MIICOMMAND !!!
 
          if ( ((`ETH_BASE + i2) == `ETH_MIICOMMAND) && (i_data <= 2) )
 
          begin
 
            #1 burst_data[31:0] = 0;
 
          end
 
          else
 
          begin
 
            #1 burst_data[31:0] = data;
 
          end
 
        end
 
        #1;
 
        // 2 burst writes
 
        addr = `ETH_BASE; // address of a first burst
 
        wbm_write(addr, burst_data[(32 * 10 - 1):0], 4'hF, i_length, wbm_init_waits, wbm_subseq_waits);
 
        burst_tmp_data = burst_data >> (32 * i_length);
 
        addr = addr + 32'h28; // address of a second burst
 
        wbm_write(addr, burst_tmp_data[(32 * 10 - 1):0], 4'hF, i_length, wbm_init_waits, wbm_subseq_waits);
 
        #1;
 
        // 2 burst reads
 
        addr = `ETH_BASE; // address of a first burst
 
        wbm_read(addr, burst_tmp_data[(32 * 10 - 1):0], 4'hF, i_length,
 
                 wbm_init_waits, wbm_subseq_waits); // first burst
 
        burst_tmp_data = burst_tmp_data << (32 * i_length);
 
        addr = addr + 32'h28; // address of a second burst
 
        wbm_read(addr, burst_tmp_data[(32 * 10 - 1):0], 4'hF, i_length,
 
                 wbm_init_waits, wbm_subseq_waits); // second burst
 
        #1;
 
        for (i2 = 0; i2 <= 32'h4C; i2 = i2 + 4)
 
        begin
 
          // set ranges of R/W bits
 
          case (`ETH_BASE + i2)
 
          `ETH_MODER:
 
            begin
 
              bit_start_1 = 0;
 
              bit_end_1   = 16;
 
              bit_start_2 = 32; // not used
 
              bit_end_2   = 32; // not used
 
            end
 
          `ETH_INT: // READONLY - tested within INT test
 
            begin
 
              bit_start_1 = 32; // not used
 
              bit_end_1   = 32; // not used
 
              bit_start_2 = 32; // not used
 
              bit_end_2   = 32; // not used
 
            end
 
          `ETH_INT_MASK:
 
            begin
 
              bit_start_1 = 0;
 
              bit_end_1   = 6;
 
              bit_start_2 = 32; // not used
 
              bit_end_2   = 32; // not used
 
            end
 
          `ETH_IPGT:
 
            begin
 
              bit_start_1 = 0;
 
              bit_end_1   = 6;
 
              bit_start_2 = 32; // not used
 
              bit_end_2   = 32; // not used
 
            end
 
          `ETH_IPGR1:
 
            begin
 
              bit_start_1 = 0;
 
              bit_end_1   = 6;
 
              bit_start_2 = 32; // not used
 
              bit_end_2   = 32; // not used
 
            end
 
          `ETH_IPGR2:
 
            begin
 
              bit_start_1 = 0;
 
              bit_end_1   = 6;
 
              bit_start_2 = 32; // not used
 
              bit_end_2   = 32; // not used
 
            end
 
          `ETH_PACKETLEN:
 
            begin
 
              bit_start_1 = 0;
 
              bit_end_1   = 31;
 
              bit_start_2 = 32; // not used
 
              bit_end_2   = 32; // not used
 
            end
 
          `ETH_COLLCONF:
 
            begin
 
              bit_start_1 = 0;
 
              bit_end_1   = 5;
 
              bit_start_2 = 16;
 
              bit_end_2   = 19;
 
            end
 
          `ETH_TX_BD_NUM:
 
            begin
 
              bit_start_1 = 0;
 
              bit_end_1   = 7;
 
              bit_start_2 = 32; // not used
 
              bit_end_2   = 32; // not used
 
            end
 
          `ETH_CTRLMODER:
 
            begin
 
              bit_start_1 = 0;
 
              bit_end_1   = 2;
 
              bit_start_2 = 32; // not used
 
              bit_end_2   = 32; // not used
 
            end
 
          `ETH_MIIMODER:
 
            begin
 
              bit_start_1 = 0;
 
              bit_end_1   = 9;
 
              bit_start_2 = 32; // not used
 
              bit_end_2   = 32; // not used
 
            end
 
          `ETH_MIICOMMAND: // "WRITEONLY" - tested within MIIM test - 3 LSBits are not written here!!!
 
            begin
 
              bit_start_1 = 32; // not used
 
              bit_end_1   = 32; // not used
 
              bit_start_2 = 32; // not used
 
              bit_end_2   = 32; // not used
 
            end
 
          `ETH_MIIADDRESS:
 
            begin
 
              bit_start_1 = 0;
 
              bit_end_1   = 4;
 
              bit_start_2 = 8;
 
              bit_end_2   = 12;
 
            end
 
          `ETH_MIITX_DATA:
 
            begin
 
              bit_start_1 = 0;
 
              bit_end_1   = 15;
 
              bit_start_2 = 32; // not used
 
              bit_end_2   = 32; // not used
 
            end
 
          `ETH_MIIRX_DATA: // READONLY - tested within MIIM test
 
            begin
 
              bit_start_1 = 32; // not used
 
              bit_end_1   = 32; // not used
 
              bit_start_2 = 32; // not used
 
              bit_end_2   = 32; // not used
 
            end
 
          `ETH_MIISTATUS: // READONLY - tested within MIIM test
 
            begin
 
              bit_start_1 = 32; // not used
 
              bit_end_1   = 32; // not used
 
              bit_start_2 = 32; // not used
 
              bit_end_2   = 32; // not used
 
            end
 
          `ETH_MAC_ADDR0:
 
            begin
 
              bit_start_1 = 0;
 
              bit_end_1   = 31;
 
              bit_start_2 = 32; // not used
 
              bit_end_2   = 32; // not used
 
            end
 
          `ETH_MAC_ADDR1:
 
            begin
 
              bit_start_1 = 0;
 
              bit_end_1   = 15;
 
              bit_start_2 = 32; // not used
 
              bit_end_2   = 32; // not used
 
            end
 
          `ETH_HASH_ADDR0:
 
            begin
 
              bit_start_1 = 0;
 
              bit_end_1   = 31;
 
              bit_start_2 = 32; // not used
 
              bit_end_2   = 32; // not used
 
            end
 
          default: // `ETH_HASH_ADDR1:
 
            begin
 
              bit_start_1 = 0;
 
              bit_end_1   = 31;
 
              bit_start_2 = 32; // not used
 
              bit_end_2   = 32; // not used
 
            end
 
          endcase
 
          #1;
 
          // 3 LSBits of MIICOMMAND are NOT written !!!
 
          if ( ((`ETH_BASE + i2) == `ETH_MIICOMMAND) && (i_data <= 2) )
 
          begin
 
            if (burst_tmp_data[31:0] !== burst_data[31:0])
 
            begin
 
              fail = fail + 1;
 
              test_fail("NON WR bit of the MAC MIICOMMAND register was wrong written or read");
 
              `TIME;
 
              $display("wbm_init_waits %d, wbm_subseq_waits %d, addr %h, data %h, tmp_data %h",
 
                        wbm_init_waits, wbm_subseq_waits, i2, burst_data[31:0], burst_tmp_data[31:0]);
 
            end
 
          end
 
          else
 
          begin
 
            if ( ((i_data >= bit_start_1) && (i_data <= bit_end_1)) ||
 
                 ((i_data >= bit_start_2) && (i_data <= bit_end_2)) ) // data should be equal to tmp_data
 
            begin
 
              if (burst_tmp_data[31:0] !== burst_data[31:0])
 
              begin
 
                fail = fail + 1;
 
                test_fail("RW bit of the MAC register was not written or not read");
 
                `TIME;
 
                $display("wbm_init_waits %d, wbm_subseq_waits %d, addr %h, data %h, tmp_data %h",
 
                          wbm_init_waits, wbm_subseq_waits, i2, burst_data[31:0], burst_tmp_data[31:0]);
 
              end
 
            end
 
            else // data should not be equal to tmp_data
 
            begin
 
              if (burst_tmp_data[31:0] === burst_data[31:0])
 
              begin
 
                fail = fail + 1;
 
                test_fail("NON RW bit of the MAC register was written, but it shouldn't be");
 
                `TIME;
 
                $display("wbm_init_waits %d, wbm_subseq_waits %d, addr %h, data %h, tmp_data %h",
 
                          wbm_init_waits, wbm_subseq_waits, i2, burst_data[31:0], burst_tmp_data[31:0]);
 
              end
 
            end
 
          end
 
          burst_tmp_data = burst_tmp_data >> 32;
 
          burst_data = burst_data >> 32;
 
        end
 
      end
 
    end
 
  end
 
  if(fail == 0)
 
    test_ok;
 
  else
 
    fail = 0;*/
    end
    end
 
 
 
 
    // Last word
if ((start_task <= 1) && (end_task >= 1))
    if(len-i==3)
begin
      eth_host.wb_write(buffer+i, 4'he, {sd[7:0], sd[7:0]+3'h1, sd[7:0]+3'h2, 8'h0});
  // TEST 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC BUFFER DESC. ( VARIOUS BUS DELAYS )
    else if(len-i==2)
  test_name   = "TEST 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC BUFFER DESC. ( VARIOUS BUS DELAYS )";
      eth_host.wb_write(buffer+i, 4'hc, {sd[7:0], sd[7:0]+3'h1, 16'h0});
  `TIME; $display("  TEST 'WALKING ONE' WITH SINGLE CYCLES ACROSS MAC BUFFER DESC. ( VARIOUS BUS DELAYS )");
    else if(len-i==1)
 
      eth_host.wb_write(buffer+i, 4'h8, {sd[7:0], 24'h0});
  data = 0;
    else if(len-i==4)
  // set TX and RX buffer descriptors
      eth_host.wb_write(buffer+i, 4'hf, {sd[7:0], sd[7:0]+3'h1, sd[7:0]+3'h2, sd[7:0]+3'h3});
  tx_bd_num = 32'h40;
    else
  wbm_write(`ETH_TX_BD_NUM, tx_bd_num, 4'hF, 1, 0, 0);
      $display("(%0t)(%m) ERROR", $time);
  for (i = 0; i <= 4; i = i + 1) // for initial wait cycles on WB bus
 
  begin
 
    wbm_init_waits = i;
 
    wbm_subseq_waits = {$random} % 5; // it is not important for single accesses
 
    for (i_addr = 32'h400; i_addr <= 32'h7FC; i_addr = i_addr + 4) // buffer descriptor address
 
    begin
 
      addr = `ETH_BASE + i_addr;
 
      if (i_addr < (32'h400 + (tx_bd_num << 3))) // TX buffer descriptors
 
      begin
 
        // set ranges of R/W bits
 
        case (addr[3])
 
        1'b0: // buffer control bits
 
          begin
 
            bit_start_1 = 0;
 
            bit_end_1   = 31; // 8;
 
            bit_start_2 = 11;
 
            bit_end_2   = 31;
 
          end
 
        default: // 1'b1: // buffer pointer
 
          begin
 
            bit_start_1 = 0;
 
            bit_end_1   = 31;
 
            bit_start_2 = 32; // not used
 
            bit_end_2   = 32; // not used
 
          end
 
        endcase
 
      end
 
      else // RX buffer descriptors
 
      begin
 
        // set ranges of R/W bits
 
        case (addr[3])
 
        1'b0: // buffer control bits
 
          begin
 
            bit_start_1 = 0;
 
            bit_end_1   = 31; // 7;
 
            bit_start_2 = 13;
 
            bit_end_2   = 31;
 
          end
 
        default: // 1'b1: // buffer pointer
 
          begin
 
            bit_start_1 = 0;
 
            bit_end_1   = 31;
 
            bit_start_2 = 32; // not used
 
            bit_end_2   = 32; // not used
 
          end
 
        endcase
 
      end
 
 
    // Checking WRAP bit
      for (i_data = 0; i_data <= 31; i_data = i_data + 1) // the position of walking one
    if(bd & `ETH_TX_BD_WRAP)
      begin
      packet_ready_cnt = 0;
        data = 1'b1 << i_data;
 
        if ( (addr[3] == 0) && (i_data == 15) ) // DO NOT WRITE to this bit !!!
 
        begin
 
        end
    else
    else
      packet_ready_cnt = packet_ready_cnt+1;
        begin
 
          wbm_write(addr, data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
    // Writing len to bd
          wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
    bd = bd | (len<<16);
          if ( ((i_data >= bit_start_1) && (i_data <= bit_end_1)) ||
    eth_host.wb_write(bd_status_addr, 4'hf, bd);
               ((i_data >= bit_start_2) && (i_data <= bit_end_2)) ) // data should be equal to tmp_data
 
          begin
 
            if (tmp_data !== data)
 
            begin
 
              fail = fail + 1;
 
              test_fail("RW bit of the MAC buffer descriptors was not written or not read");
 
              `TIME;
 
              $display("wbm_init_waits %d, addr %h, data %h, tmp_data %h",
 
                        wbm_init_waits, addr, data, tmp_data);
  end
  end
endtask // set_packet
          end
 
          else // data should not be equal to tmp_data
 
 
task send_packet;
 
 
 
  integer bd_status_addr, bd_ptr_addr, buffer, bd;
 
 
 
  begin
  begin
    bd_status_addr = `TX_BD_BASE + send_packet_cnt * 8;
            if (tmp_data === data)
    bd_ptr_addr = bd_status_addr + 4;
            begin
 
              fail = fail + 1;
    // Reading BD + buffer pointer
              test_fail("NON RW bit of the MAC buffer descriptors was written, but it shouldn't be");
    eth_host.wb_read(bd_status_addr, 4'hf, bd);
              `TIME;
    eth_host.wb_read(bd_ptr_addr, 4'hf, buffer);
              $display("wbm_init_waits %d, addr %h, data %h, tmp_data %h",
 
                        wbm_init_waits, addr, data, tmp_data);
    if(bd & `ETH_TX_BD_WRAP)
            end
      send_packet_cnt=0;
          end
 
        end
 
      end
 
    end
 
    case (i)
 
    0:       $display("    buffer descriptors tested with 0 bus delay");
 
    1:       $display("    buffer descriptors tested with 1 bus delay cycle");
 
    2:       $display("    buffer descriptors tested with 2 bus delay cycles");
 
    3:       $display("    buffer descriptors tested with 3 bus delay cycles");
 
    default: $display("    buffer descriptors tested with 4 bus delay cycles");
 
    endcase
 
  end
 
  if(fail == 0)
 
    test_ok;
    else
    else
      send_packet_cnt=send_packet_cnt+1;
    fail = 0;
 
 
    // Setting ETH_TX_BD_READY bit
 
    bd = bd | `ETH_TX_BD_READY;
 
    eth_host.wb_write(bd_status_addr, 4'hf, bd);
 
  end
  end
 
 
 
  /* Register      RESET values    MAX. values
 
     -----------------------------------------
 
   ETH_MODER       32'h0000_A800   32'h0000_A800   Mode Register
 
   ETH_INT         32'h0000_0000   32'h0000_0000   Interrupt Source Register
 
   ETH_INT_MASK    32'h0000_0000   32'h0000_0000   Interrupt Mask Register
 
   ETH_IPGT        32'h0000_0012   32'h0000_0012   Back to Bak Inter Packet Gap Register
 
   ETH_IPGR1       32'h0000_000C   32'h0000_000C   Non Back to Back Inter Packet Gap Register 1
 
   ETH_IPGR2       32'h0000_0012   32'h0000_0012   Non Back to Back Inter Packet Gap Register 2
 
   ETH_PACKETLEN   32'h0040_0600   32'h0040_0600   Packet Length Register (min. and max.)
 
   ETH_COLLCONF    32'h000F_003F   32'h000F_003F   Collision and Retry Configuration Register
 
   ETH_TX_BD_NUM   32'h0000_0040   32'h0000_0080   Transmit Buffer Descriptor Number Register
 
   ETH_CTRLMODER   32'h0000_0000   32'h0000_0000   Control Module Mode Register
 
   ETH_MIIMODER    32'h0000_0064   32'h0000_0064   MII Mode Register
 
   ETH_MIICOMMAND  32'h0000_0000   32'h0000_0000   MII Command Register
 
   ETH_MIIADDRESS  32'h0000_0000   32'h0000_0000   MII Address Register
 
   ETH_MIITX_DATA  32'h0000_0000   32'h0000_0000   MII Transmit Data Register
 
   ETH_MIIRX_DATA  32'h0000_0000   32'h0000_0000   MII Receive Data Register
 
   ETH_MIISTATUS   32'h0000_0000   32'h0000_0000   MII Status Register
 
   ETH_MAC_ADDR0   32'h0000_0000   32'h0000_0000   MAC Individual Address Register 0
 
   ETH_MAC_ADDR1   32'h0000_0000   32'h0000_0000   MAC Individual Address Register 1
 
   ETH_HASH_ADDR0  32'h0000_0000   32'h0000_0000   Hash Register 0
 
   ETH_HASH_ADDR1  32'h0000_0000   32'h0000_0000   Hash Register 1
 
  */
 
 
endtask // send_packet
 
 
 
 
 
task GetDataOnMRxD;
 
  input [15:0] Len;
 
  input [31:0] TransferType;
 
  integer tt;
 
 
 
 
if ((start_task <= 2) && (end_task >= 2))
  begin
  begin
    @ (posedge mrx_clk);
  // TEST MAX REG. VALUES AND REG. VALUES AFTER WRITING INVERSE RESET VALUES AND HARD RESET OF THE MAC
    #1MRxDV=1'b1;
  test_name   =
 
  "TEST MAX REG. VALUES AND REG. VALUES AFTER WRITING INVERSE RESET VALUES AND HARD RESET OF THE MAC";
    for(tt=0; tt<15; tt=tt+1)
  `TIME; $display(
 
  "  TEST MAX REG. VALUES AND REG. VALUES AFTER WRITING INVERSE RESET VALUES AND HARD RESET OF THE MAC");
 
 
 
  // reset MAC registers
 
  hard_reset;
 
  for (i = 0; i <= 4; i = i + 1) // 0, 2 - WRITE; 1, 3, 4 - READ
      begin
      begin
        MRxD=4'h5;              // preamble
    for (i_addr = 0; i_addr <= 32'h4C; i_addr = i_addr + 4) // register address
        @ (posedge mrx_clk);
    begin
        #1;
      addr = `ETH_BASE + i_addr;
 
      // set ranges of R/W bits
 
      case (addr)
 
      `ETH_MODER:
 
      begin
 
        data = 32'h0000_A800;
 
        data_max = 32'h0001_FFFF;
      end
      end
 
      `ETH_INT: // READONLY - tested within INT test
    MRxD=4'hd;                // SFD
 
 
 
    for(tt=1; tt<(Len+1); tt=tt+1)
 
      begin
      begin
        @ (posedge mrx_clk);
        data = 32'h0000_0000;
        #1;
        data_max = 32'h0000_0000;
            if(TransferType == `UNICAST_XFR && tt == 1)
 
                MRxD= 4'h0;   // Unicast transfer
 
              else if(TransferType == `BROADCAST_XFR && tt < 7)
 
                MRxD = 4'hf;
 
              else
 
          MRxD=tt[3:0]; // Multicast transfer
 
 
 
        @ (posedge mrx_clk);
 
              #1;
 
              if(TransferType == `BROADCAST_XFR && tt < 7)
 
                MRxD = 4'hf;
 
              else
 
          MRxD=tt[7:4];
 
      end
      end
 
      `ETH_INT_MASK:
    @ (posedge mrx_clk);
      begin
    #1;
        data = 32'h0000_0000;
    MRxDV=1'b0;
        data_max = 32'h0000_007F;
 
      end
 
      `ETH_IPGT:
 
      begin
 
        data = 32'h0000_0012;
 
        data_max = 32'h0000_007F;
 
      end
 
      `ETH_IPGR1:
 
      begin
 
        data = 32'h0000_000C;
 
        data_max = 32'h0000_007F;
 
      end
 
      `ETH_IPGR2:
 
      begin
 
        data = 32'h0000_0012;
 
        data_max = 32'h0000_007F;
 
      end
 
      `ETH_PACKETLEN:
 
      begin
 
        data = 32'h0040_0600;
 
        data_max = 32'hFFFF_FFFF;
 
      end
 
      `ETH_COLLCONF:
 
      begin
 
        data = 32'h000F_003F;
 
        data_max = 32'h000F_003F;
 
      end
 
      `ETH_TX_BD_NUM:
 
      begin
 
        data = 32'h0000_0040;
 
        data_max = 32'h0000_0080;
 
      end
 
      `ETH_CTRLMODER:
 
      begin
 
        data = 32'h0000_0000;
 
        data_max = 32'h0000_0007;
 
      end
 
      `ETH_MIIMODER:
 
      begin
 
        data = 32'h0000_0064;
 
        data_max = 32'h0000_03FF;
 
      end
 
      `ETH_MIICOMMAND: // "WRITEONLY" - tested within MIIM test - 3 LSBits are not written here!!!
 
      begin
 
        data = 32'h0000_0000;
 
        data_max = 32'h0000_0007;
 
      end
 
      `ETH_MIIADDRESS:
 
      begin
 
        data = 32'h0000_0000;
 
        data_max = 32'h0000_1F1F;
 
      end
 
      `ETH_MIITX_DATA:
 
      begin
 
        data = 32'h0000_0000;
 
        data_max = 32'h0000_FFFF;
 
      end
 
      `ETH_MIIRX_DATA: // READONLY - tested within MIIM test
 
      begin
 
        data = 32'h0000_0000;
 
        data_max = 32'h0000_0000;
 
      end
 
      `ETH_MIISTATUS: // READONLY - tested within MIIM test
 
      begin
 
        data = 32'h0000_0000;
 
        data_max = 32'h0000_0000;
 
      end
 
      `ETH_MAC_ADDR0:
 
      begin
 
        data = 32'h0000_0000;
 
        data_max = 32'hFFFF_FFFF;
 
      end
 
      `ETH_MAC_ADDR1:
 
      begin
 
        data = 32'h0000_0000;
 
        data_max = 32'h0000_FFFF;
 
      end
 
      `ETH_HASH_ADDR0:
 
      begin
 
        data = 32'h0000_0000;
 
        data_max = 32'hFFFF_FFFF;
 
      end
 
      default: // `ETH_HASH_ADDR1:
 
      begin
 
        data = 32'h0000_0000;
 
        data_max = 32'hFFFF_FFFF;
 
      end
 
      endcase
 
 
 
      wbm_init_waits = {$random} % 3;
 
      wbm_subseq_waits = {$random} % 5; // it is not important for single accesses
 
      if (i == 0)
 
        wbm_write(addr, ~data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
      else if (i == 2)
 
        wbm_write(addr, 32'hFFFFFFFF, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
      else if ((i == 1) || (i == 4))
 
      begin
 
        wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
        if (tmp_data !== data)
 
        begin
 
          fail = fail + 1;
 
          test_fail("RESET value of the MAC register is not correct");
 
          `TIME;
 
          $display("  addr %h, data %h, tmp_data %h", addr, data, tmp_data);
 
        end
 
      end
 
      else // check maximum values
 
      begin
 
        wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
        if (addr == `ETH_TX_BD_NUM) // previous data should remain in this register
 
        begin
 
          if (tmp_data !== data)
 
          begin
 
            fail = fail + 1;
 
            test_fail("Previous value of the TX_BD_NUM register did not remain");
 
            `TIME;
 
            $display("  addr %h, data_max %h, tmp_data %h", addr, data_max, tmp_data);
 
          end
 
          // try maximum (80)
 
          wbm_write(addr, data_max, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
          wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
          if (tmp_data !== data_max)
 
          begin
 
            fail = fail + 1;
 
            test_fail("MAX value of the TX_BD_NUM register is not correct");
 
            `TIME;
 
            $display("  addr %h, data_max %h, tmp_data %h", addr, data_max, tmp_data);
 
          end
 
          // try one less than maximum (80)
 
          wbm_write(addr, (data_max - 1), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
          wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
          if (tmp_data !== (data_max - 1))
 
          begin
 
            fail = fail + 1;
 
            test_fail("ONE less than MAX value of the TX_BD_NUM register is not correct");
 
            `TIME;
 
            $display("  addr %h, data_max %h, tmp_data %h", addr, data_max, tmp_data);
 
          end
 
          // try one more than maximum (80)
 
          wbm_write(addr, (data_max + 1), 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
          wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
          if (tmp_data !== (data_max - 1)) // previous data should remain in this register
 
          begin
 
            fail = fail + 1;
 
            test_fail("Previous value of the TX_BD_NUM register did not remain");
 
            `TIME;
 
            $display("  addr %h, data_max %h, tmp_data %h", addr, data_max, tmp_data);
 
          end
 
        end
 
        else
 
        begin
 
          if (tmp_data !== data_max)
 
          begin
 
            fail = fail + 1;
 
            test_fail("MAX value of the MAC register is not correct");
 
            `TIME;
 
            $display("  addr %h, data_max %h, tmp_data %h", addr, data_max, tmp_data);
 
          end
 
        end
 
      end
 
    end
 
    // reset MAC registers
 
    if ((i == 0) || (i == 3))
 
    begin
 
      hard_reset;
 
    end
 
  end
 
  if(fail == 0)
 
    test_ok;
 
  else
 
    fail = 0;
 
end
 
 
 
 
 
if ((start_task <= 3) && (end_task >= 3))
 
begin
 
  // TEST BUFFER DESC. RAM PRESERVING VALUES AFTER HARD RESET OF THE MAC AND RESETING THE LOGIC
 
  test_name   = "TEST BUFFER DESC. RAM PRESERVING VALUES AFTER HARD RESET OF THE MAC AND RESETING THE LOGIC";
 
  `TIME;
 
  $display("  TEST BUFFER DESC. RAM PRESERVING VALUES AFTER HARD RESET OF THE MAC AND RESETING THE LOGIC");
 
 
 
  // reset MAC registers
 
  hard_reset;
 
  // reset LOGIC with soft reset
 
  reset_mac;
 
  reset_mii;
 
  for (i = 0; i <= 3; i = i + 1) // 0, 2 - WRITE; 1, 3 - READ
 
  begin
 
    for (i_addr = 32'h400; i_addr <= 32'h7FC; i_addr = i_addr + 4) // buffer descriptor address
 
    begin
 
      addr = `ETH_BASE + i_addr;
 
 
 
      wbm_init_waits = {$random} % 3;
 
      wbm_subseq_waits = {$random} % 5; // it is not important for single accesses
 
      if (i == 0)
 
      begin
 
        data = 32'hFFFFFFFF;
 
        wbm_write(addr, 32'hFFFFFFFF, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
      end
 
      else if (i == 2)
 
      begin
 
        data = 32'h00000000;
 
        wbm_write(addr, 32'h00000000, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
      end
 
      else
 
      begin
 
        wbm_read(addr, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
        if (tmp_data !== data)
 
        begin
 
          fail = fail + 1;
 
          test_fail("PRESERVED value of the MAC buffer descriptors is not correct");
 
          `TIME;
 
          $display("  addr %h, data %h, tmp_data %h", addr, data, tmp_data);
 
        end
 
      end
 
    end
 
    if ((i == 0) || (i == 2))
 
    begin
 
      // reset MAC registers
 
      hard_reset;
 
      // reset LOGIC with soft reset
 
      reset_mac;
 
      reset_mii;
 
    end
 
  end
 
  if(fail == 0)
 
    test_ok;
 
  else
 
    fail = 0;
 
end
 
 
 
 
 
end
 
endtask // test_access_to_mac_reg
 
 
 
 
 
task test_mii;
 
  input  [31:0]  start_task;
 
  input  [31:0]  end_task;
 
  integer        i;
 
  integer        i1;
 
  integer        i2;
 
  integer        i3;
 
  integer        cnt;
 
  integer        fail;
 
  reg     [8:0]  clk_div; // only 8 bits are valid!
 
  reg     [4:0]  phy_addr;
 
  reg     [4:0]  reg_addr;
 
  reg     [15:0] phy_data;
 
  reg     [15:0] tmp_data;
 
begin
 
// MIIM MODULE TEST
 
test_heading("MIIM MODULE TEST");
 
$display(" ");
 
$display("MIIM MODULE TEST");
 
fail = 0;
 
 
 
// reset MIIM LOGIC with soft reset
 
reset_mii;
 
 
 
 
 
if ((start_task <= 0) && (end_task >= 0))
 
begin
 
  // TEST CLOCK DIVIDER OF MII MANAGEMENT MODULE WITH ALL POSSIBLE FREQUENCES
 
  test_name   = "TEST CLOCK DIVIDER OF MII MANAGEMENT MODULE WITH ALL POSSIBLE FREQUENCES";
 
  `TIME; $display("  TEST CLOCK DIVIDER OF MII MANAGEMENT MODULE WITH ALL POSSIBLE FREQUENCES");
 
 
 
  wait(Mdc_O); // wait for MII clock to be 1
 
  for(clk_div = 0; clk_div <= 255; clk_div = clk_div + 1)
 
  begin
 
    i1 = 0;
 
    i2 = 0;
 
    #Tp mii_set_clk_div(clk_div[7:0]);
 
    @(posedge Mdc_O);
 
    #Tp;
 
    fork
 
      begin
 
        @(posedge Mdc_O);
 
        #Tp;
 
        disable count_i1;
 
        disable count_i2;
 
      end
 
      begin: count_i1
 
        forever
 
        begin
 
          @(posedge wb_clk);
 
          i1 = i1 + 1;
 
          #Tp;
 
        end
 
      end
 
      begin: count_i2
 
        forever
 
        begin
 
          @(negedge wb_clk);
 
          i2 = i2 + 1;
 
          #Tp;
 
        end
 
      end
 
    join
 
    if((clk_div[7:0] == 0) || (clk_div[7:0] == 1) || (clk_div[7:0] == 2) || (clk_div[7:0] == 3))
 
    begin
 
      if((i1 == i2) && (i1 == 2))
 
      begin
 
      end
 
      else
 
      begin
 
        fail = fail + 1;
 
        test_fail("Clock divider of MII module did'nt divide frequency corectly (it should divid with 2)");
 
      end
 
    end
 
    else
 
    begin
 
      if((i1 == i2) && (i1 == {clk_div[7:1], 1'b0}))
 
      begin
 
      end
 
      else
 
      begin
 
        fail = fail + 1;
 
        test_fail("Clock divider of MII module did'nt divide frequency corectly");
 
      end
 
    end
 
  end
 
  if(fail == 0)
 
    test_ok;
 
  else
 
    fail = 0;
 
end
 
 
 
 
 
if ((start_task <= 1) && (end_task >= 1))
 
begin
 
  // TEST VARIOUS READINGS FROM 'REAL' PHY REGISTERS
 
  test_name   = "TEST VARIOUS READINGS FROM 'REAL' PHY REGISTERS";
 
  `TIME; $display("  TEST VARIOUS READINGS FROM 'REAL' PHY REGISTERS");
 
 
 
  // set the fastest possible MII
 
  clk_div = 0;
 
  mii_set_clk_div(clk_div[7:0]);
 
  // set address
 
  reg_addr = 5'h1F;
 
  phy_addr = 5'h1;
 
  while(reg_addr >= 5'h4)
 
  begin
 
    // read request
 
    #Tp mii_read_req(phy_addr, reg_addr);
 
    check_mii_busy; // wait for read to finish
 
    // read data
 
    #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
    if (phy_data !== 16'hDEAD)
 
    begin
 
      test_fail("Wrong data was read from PHY from 'not used' address space");
 
      fail = fail + 1;
 
    end
 
    if (reg_addr == 5'h4) // go out of for loop
 
      reg_addr = 5'h3;
 
    else
 
      reg_addr = reg_addr - 5'h9;
 
  end
 
 
 
  // set address
 
  reg_addr = 5'h3;
 
  // read request
 
  #Tp mii_read_req(phy_addr, reg_addr);
 
  check_mii_busy; // wait for read to finish
 
  // read data
 
  #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
  if (phy_data !== {`PHY_ID2, `MAN_MODEL_NUM, `MAN_REVISION_NUM})
 
  begin
 
    test_fail("Wrong data was read from PHY from ID register 2");
 
    fail = fail + 1;
 
  end
 
  if(fail == 0)
 
    test_ok;
 
  else
 
    fail = 0;
 
end
 
 
 
 
 
if ((start_task <= 2) && (end_task >= 2))
 
begin
 
  // TEST VARIOUS WRITINGS TO 'REAL' PHY REGISTERS ( CONTROL AND NON WRITABLE REGISTERS )
 
  test_name   = "TEST VARIOUS WRITINGS TO 'REAL' PHY REGISTERS ( CONTROL AND NON WRITABLE REGISTERS )";
 
  `TIME; $display("  TEST VARIOUS WRITINGS TO 'REAL' PHY REGISTERS ( CONTROL AND NON WRITABLE REGISTERS )");
 
 
 
  // negate data and try to write into unwritable register
 
  tmp_data = ~phy_data;
 
  // write request
 
  #Tp mii_write_req(phy_addr, reg_addr, tmp_data);
 
  check_mii_busy; // wait for write to finish
 
  // read request
 
  #Tp mii_read_req(phy_addr, reg_addr);
 
  check_mii_busy; // wait for read to finish
 
  // read data
 
  #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
  if (tmp_data !== phy_data)
 
  begin
 
    test_fail("Data was written into unwritable PHY register - ID register 2");
 
    fail = fail + 1;
 
  end
 
 
 
  // set address
 
  reg_addr = 5'h0; // control register
 
  // read request
 
  #Tp mii_read_req(phy_addr, reg_addr);
 
  check_mii_busy; // wait for read to finish
 
  // read data
 
  #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
  // write request
 
  phy_data = 16'h7DFF; // bit 15 (RESET bit) and bit 9 are self clearing bits
 
  #Tp mii_write_req(phy_addr, reg_addr, phy_data);
 
  check_mii_busy; // wait for write to finish
 
  // read request
 
  #Tp mii_read_req(phy_addr, reg_addr);
 
  check_mii_busy; // wait for read to finish
 
  // read data
 
  #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
  if (phy_data !== 16'h7DFF)
 
  begin
 
    test_fail("Data was not correctly written into OR read from writable PHY register - control register");
 
    fail = fail + 1;
 
  end
 
  // write request
 
  #Tp mii_write_req(phy_addr, reg_addr, tmp_data);
 
  check_mii_busy; // wait for write to finish
 
  // read request
 
  #Tp mii_read_req(phy_addr, reg_addr);
 
  check_mii_busy; // wait for read to finish
 
  // read data
 
  #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
  if (phy_data !== tmp_data)
 
  begin
 
    test_fail("Data was not correctly written into OR read from writable PHY register - control register");
 
    fail = fail + 1;
 
  end
 
  if(fail == 0)
 
    test_ok;
 
  else
 
    fail = 0;
 
end
 
 
 
 
 
if ((start_task <= 3) && (end_task >= 3))
 
begin
 
  // TEST RESET PHY THROUGH MII MANAGEMENT MODULE
 
  test_name   = "TEST RESET PHY THROUGH MII MANAGEMENT MODULE";
 
  `TIME; $display("  TEST RESET PHY THROUGH MII MANAGEMENT MODULE");
 
 
 
  // set address
 
  reg_addr = 5'h0; // control register
 
  // write request
 
  phy_data = 16'h7DFF; // bit 15 (RESET bit) and bit 9 are self clearing bits
 
  #Tp mii_write_req(phy_addr, reg_addr, phy_data);
 
  check_mii_busy; // wait for write to finish
 
  // read request
 
  #Tp mii_read_req(phy_addr, reg_addr);
 
  check_mii_busy; // wait for read to finish
 
  // read data
 
  #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
  if (phy_data !== tmp_data)
 
  begin
 
    test_fail("Data was not correctly written into OR read from writable PHY register - control register");
 
    fail = fail + 1;
 
  end
 
  // set reset bit - selfclearing bit in PHY
 
  phy_data = phy_data | 16'h8000;
 
  // write request
 
  #Tp mii_write_req(phy_addr, reg_addr, phy_data);
 
  check_mii_busy; // wait for write to finish
 
  // read request
 
  #Tp mii_read_req(phy_addr, reg_addr);
 
  check_mii_busy; // wait for read to finish
 
  // read data
 
  #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
  // check self clearing of reset bit
 
  if (tmp_data[15] !== 1'b0)
 
  begin
 
    test_fail("Reset bit should be self cleared - control register");
 
    fail = fail + 1;
 
  end
 
  // check reset value of control register
 
  if (tmp_data !== {2'h0, (`LED_CFG1 || `LED_CFG2), `LED_CFG1, 3'h0, `LED_CFG3, 8'h0})
 
  begin
 
    test_fail("PHY was not reset correctly AND/OR reset bit not self cleared");
 
    fail = fail + 1;
 
  end
 
  if(fail == 0)
 
    test_ok;
 
  else
 
    fail = 0;
 
end
 
 
 
 
 
if ((start_task <= 4) && (end_task >= 4))
 
begin
 
  // TEST 'WALKING ONE' ACROSS PHY ADDRESS ( WITH AND WITHOUT PREAMBLE )
 
  test_name   = "TEST 'WALKING ONE' ACROSS PHY ADDRESS ( WITH AND WITHOUT PREAMBLE )";
 
  `TIME; $display("  TEST 'WALKING ONE' ACROSS PHY ADDRESS ( WITH AND WITHOUT PREAMBLE )");
 
 
 
  // set PHY to test mode
 
  #Tp eth_phy.test_regs(1); // set test registers (wholy writable registers) and respond to all PHY addresses
 
  for (i = 0; i <= 1; i = i + 1)
 
  begin
 
    #Tp eth_phy.preamble_suppresed(i);
 
    #Tp eth_phy.clear_test_regs;
 
    // MII mode register
 
    wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}), 4'hF, 1, wbm_init_waits,
 
              wbm_subseq_waits);
 
    // walk one across phy address
 
    for (phy_addr = 5'h1; phy_addr > 5'h0; phy_addr = phy_addr << 1)
 
    begin
 
      reg_addr = $random;
 
      tmp_data = $random;
 
      // write request
 
      #Tp mii_write_req(phy_addr, reg_addr, tmp_data);
 
      check_mii_busy; // wait for write to finish
 
      // read request
 
      #Tp mii_read_req(phy_addr, reg_addr);
 
      check_mii_busy; // wait for read to finish
 
      // read data
 
      #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
      #Tp;
 
      if (phy_data !== tmp_data)
 
      begin
 
        if (i)
 
          test_fail("Data was not correctly written into OR read from test registers (without preamble)");
 
        else
 
          test_fail("Data was not correctly written into OR read from test registers (with preamble)");
 
        fail = fail + 1;
 
      end
 
      @(posedge wb_clk);
 
      #Tp;
 
    end
 
  end
 
  // set PHY to normal mode
 
  #Tp eth_phy.test_regs(0);
 
  #Tp eth_phy.preamble_suppresed(0);
 
  // MII mode register
 
  wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
  if(fail == 0)
 
    test_ok;
 
  else
 
    fail = 0;
 
end
 
 
 
 
 
if ((start_task <= 5) && (end_task >= 5))
 
begin
 
  // TEST 'WALKING ONE' ACROSS PHY'S REGISTER ADDRESS ( WITH AND WITHOUT PREAMBLE )
 
  test_name   = "TEST 'WALKING ONE' ACROSS PHY'S REGISTER ADDRESS ( WITH AND WITHOUT PREAMBLE )";
 
  `TIME; $display("  TEST 'WALKING ONE' ACROSS PHY'S REGISTER ADDRESS ( WITH AND WITHOUT PREAMBLE )");
 
 
 
  // set PHY to test mode
 
  #Tp eth_phy.test_regs(1); // set test registers (wholy writable registers) and respond to all PHY addresses
 
  for (i = 0; i <= 1; i = i + 1)
 
  begin
 
    #Tp eth_phy.preamble_suppresed(i);
 
    #Tp eth_phy.clear_test_regs;
 
    // MII mode register
 
    wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}), 4'hF, 1, wbm_init_waits,
 
              wbm_subseq_waits);
 
    // walk one across reg address
 
    for (reg_addr = 5'h1; reg_addr > 5'h0; reg_addr = reg_addr << 1)
 
    begin
 
      phy_addr = $random;
 
      tmp_data = $random;
 
      // write request
 
      #Tp mii_write_req(phy_addr, reg_addr, tmp_data);
 
      check_mii_busy; // wait for write to finish
 
      // read request
 
      #Tp mii_read_req(phy_addr, reg_addr);
 
      check_mii_busy; // wait for read to finish
 
      // read data
 
      #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
      #Tp;
 
      if (phy_data !== tmp_data)
 
      begin
 
        if (i)
 
          test_fail("Data was not correctly written into OR read from test registers (without preamble)");
 
        else
 
          test_fail("Data was not correctly written into OR read from test registers (with preamble)");
 
        fail = fail + 1;
 
      end
 
      @(posedge wb_clk);
 
      #Tp;
 
    end
 
  end
 
  // set PHY to normal mode
 
  #Tp eth_phy.test_regs(0);
 
  #Tp eth_phy.preamble_suppresed(0);
 
  // MII mode register
 
  wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
  if(fail == 0)
 
    test_ok;
 
  else
 
    fail = 0;
 
end
 
 
 
 
 
if ((start_task <= 6) && (end_task >= 6))
 
begin
 
  // TEST 'WALKING ONE' ACROSS PHY'S DATA ( WITH AND WITHOUT PREAMBLE )
 
  test_name   = "TEST 'WALKING ONE' ACROSS PHY'S DATA ( WITH AND WITHOUT PREAMBLE )";
 
  `TIME; $display("  TEST 'WALKING ONE' ACROSS PHY'S DATA ( WITH AND WITHOUT PREAMBLE )");
 
 
 
  // set PHY to test mode
 
  #Tp eth_phy.test_regs(1); // set test registers (wholy writable registers) and respond to all PHY addresses
 
  for (i = 0; i <= 1; i = i + 1)
 
  begin
 
    #Tp eth_phy.preamble_suppresed(i);
 
    #Tp eth_phy.clear_test_regs;
 
    // MII mode register
 
    wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}), 4'hF, 1, wbm_init_waits,
 
              wbm_subseq_waits);
 
    // walk one across data
 
    for (tmp_data = 16'h1; tmp_data > 16'h0; tmp_data = tmp_data << 1)
 
    begin
 
      phy_addr = $random;
 
      reg_addr = $random;
 
      // write request
 
      #Tp mii_write_req(phy_addr, reg_addr, tmp_data);
 
      check_mii_busy; // wait for write to finish
 
      // read request
 
      #Tp mii_read_req(phy_addr, reg_addr);
 
      check_mii_busy; // wait for read to finish
 
      // read data
 
      #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
      #Tp;
 
      if (phy_data !== tmp_data)
 
      begin
 
        if (i)
 
          test_fail("Data was not correctly written into OR read from test registers (without preamble)");
 
        else
 
          test_fail("Data was not correctly written into OR read from test registers (with preamble)");
 
        fail = fail + 1;
 
      end
 
      @(posedge wb_clk);
 
      #Tp;
 
    end
 
  end
 
  // set PHY to normal mode
 
  #Tp eth_phy.test_regs(0);
 
  #Tp eth_phy.preamble_suppresed(0);
 
  // MII mode register
 
  wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
  if(fail == 0)
 
    test_ok;
 
  else
 
    fail = 0;
 
end
 
 
 
 
 
if ((start_task <= 7) && (end_task >= 7))
 
begin
 
  // TEST READING FROM PHY WITH WRONG PHY ADDRESS ( HOST READING HIGH 'Z' DATA )
 
  test_name   = "TEST READING FROM PHY WITH WRONG PHY ADDRESS ( HOST READING HIGH 'Z' DATA )";
 
  `TIME; $display("  TEST READING FROM PHY WITH WRONG PHY ADDRESS ( HOST READING HIGH 'Z' DATA )");
 
 
 
  phy_addr = 5'h2; // wrong PHY address
 
  // read request
 
  #Tp mii_read_req(phy_addr, reg_addr);
 
  check_mii_busy; // wait for read to finish
 
  // read data
 
  $display("  => Two errors will be displayed from WB Bus Monitor, because correct HIGH Z data was read");
 
  #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
  if (tmp_data !== 16'hzzzz)
 
  begin
 
    test_fail("Data was read from PHY register with wrong PHY address - control register");
 
    fail = fail + 1;
 
  end
 
  if(fail == 0)
 
    test_ok;
 
  else
 
    fail = 0;
 
end
 
 
 
 
 
if ((start_task <= 8) && (end_task >= 8))
 
begin
 
  // TEST WRITING TO PHY WITH WRONG PHY ADDRESS AND READING FROM CORRECT ONE
 
  test_name   = "TEST WRITING TO PHY WITH WRONG PHY ADDRESS AND READING FROM CORRECT ONE";
 
  `TIME; $display("  TEST WRITING TO PHY WITH WRONG PHY ADDRESS AND READING FROM CORRECT ONE");
 
 
 
  // set address
 
  reg_addr = 5'h0; // control register
 
  phy_addr = 5'h2; // wrong PHY address
 
  // write request
 
  phy_data = 16'h7DFF; // bit 15 (RESET bit) and bit 9 are self clearing bits
 
  #Tp mii_write_req(phy_addr, reg_addr, phy_data);
 
  check_mii_busy; // wait for write to finish
 
 
 
  phy_addr = 5'h1; // correct PHY address
 
  // read request
 
  #Tp mii_read_req(phy_addr, reg_addr);
 
  check_mii_busy; // wait for read to finish
 
  // read data
 
  #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
  if (phy_data === tmp_data)
 
  begin
 
    test_fail("Data was written into PHY register with wrong PHY address - control register");
 
    fail = fail + 1;
 
  end
 
  if(fail == 0)
 
    test_ok;
 
  else
 
    fail = 0;
 
end
 
 
 
 
 
if ((start_task <= 9) && (end_task >= 9))
 
begin
 
  // TEST SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER READ REQUEST ( WITH AND WITHOUT PREAMBLE )
 
  test_name = "TEST SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER READ REQUEST ( WITH AND WITHOUT PREAMBLE )";
 
  `TIME;
 
  $display("  TEST SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER READ REQUEST ( WITH AND WITHOUT PREAMBLE )");
 
 
 
  for (i2 = 0; i2 <= 1; i2 = i2 + 1) // choose preamble or not
 
  begin
 
    #Tp eth_phy.preamble_suppresed(i2);
 
    // MII mode register
 
    wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i2, 8'h0}), 4'hF, 1, wbm_init_waits,
 
             wbm_subseq_waits);
 
    i = 0;
 
    cnt = 0;
 
    while (i < 80) // delay for sliding of writing a STOP SCAN command
 
    begin
 
      for (i3 = 0; i3 <= 1; i3 = i3 + 1) // choose read or write after read will be finished
 
      begin
 
        // set address
 
        reg_addr = 5'h0; // control register
 
        phy_addr = 5'h1; // correct PHY address
 
        cnt = 0;
 
        // read request
 
        #Tp mii_read_req(phy_addr, reg_addr);
 
        fork
 
          begin
 
            repeat(i) @(posedge Mdc_O);
 
            // write command 0x0 into MII command register
 
            // MII command written while read in progress
 
            wbm_write(`ETH_MIICOMMAND, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
            @(posedge wb_clk);
 
            #Tp check_mii_busy; // wait for read to finish
 
          end
 
          begin
 
            // wait for serial bus to become active
 
            wait(Mdio_IO !== 1'bz);
 
            // count transfer length
 
            while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
 
            begin
 
              @(posedge Mdc_O);
 
              #Tp cnt = cnt + 1;
 
            end
 
          end
 
        join
 
        // check transfer length
 
        if (i2) // without preamble
 
        begin
 
          if (cnt != 33) // at this value Mdio_IO is HIGH Z
 
          begin
 
            test_fail("Read request did not proceed correctly, while SCAN STOP command was written");
 
            fail = fail + 1;
 
          end
 
        end
 
        else // with preamble
 
        begin
 
          if (cnt != 65) // at this value Mdio_IO is HIGH Z
 
          begin
 
            test_fail("Read request did not proceed correctly, while SCAN STOP command was written");
 
            fail = fail + 1;
 
          end
 
        end
 
        // check the BUSY signal to see if the bus is still IDLE
 
        for (i1 = 0; i1 < 8; i1 = i1 + 1)
 
          check_mii_busy; // wait for bus to become idle
 
 
 
        // try normal write or read after read was finished
 
        #Tp phy_data = {8'h7D, (i[7:0] + 1)};
 
        #Tp cnt = 0;
 
        if (i3 == 0) // write after read
 
        begin
 
          // write request
 
          #Tp mii_write_req(phy_addr, reg_addr, phy_data);
 
          // wait for serial bus to become active
 
          wait(Mdio_IO !== 1'bz);
 
          // count transfer length
 
          while(Mdio_IO !== 1'bz)
 
          begin
 
            @(posedge Mdc_O);
 
            #Tp cnt = cnt + 1;
 
          end
 
          @(posedge Mdc_O);
 
          // read request
 
          #Tp mii_read_req(phy_addr, reg_addr);
 
          check_mii_busy; // wait for read to finish
 
          // read and check data
 
          #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
          if (phy_data !== tmp_data)
 
          begin
 
            test_fail("Data was not correctly written into OR read from PHY register - control register");
 
            fail = fail + 1;
 
          end
 
        end
 
        else // read after read
 
        begin
 
          // read request
 
          #Tp mii_read_req(phy_addr, reg_addr);
 
          // wait for serial bus to become active
 
          wait(Mdio_IO !== 1'bz);
 
          // count transfer length
 
          while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
 
          begin
 
            @(posedge Mdc_O);
 
            #Tp cnt = cnt + 1;
 
          end
 
          @(posedge Mdc_O);
 
          check_mii_busy; // wait for read to finish
 
          // read and check data
 
          #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
          if (phy_data !== tmp_data)
 
          begin
 
            test_fail("Data was not correctly written into OR read from PHY register - control register");
 
            fail = fail + 1;
 
          end
 
        end
 
        // check if transfer was a proper length
 
        if (i2) // without preamble
 
        begin
 
          if (cnt != 33) // at this value Mdio_IO is HIGH Z
 
          begin
 
            test_fail("New request did not proceed correctly, after read request");
 
            fail = fail + 1;
 
          end
 
        end
 
        else // with preamble
 
        begin
 
          if (cnt != 65) // at this value Mdio_IO is HIGH Z
 
          begin
 
            test_fail("New request did not proceed correctly, after read request");
 
            fail = fail + 1;
 
          end
 
        end
 
      end
 
      #Tp;
 
      // set delay of writing the command
 
      if (i2) // without preamble
 
      begin
 
        case(i)
 
          0, 1:               i = i + 1;
 
          18, 19, 20, 21, 22,
 
          23, 24, 25, 26, 27,
 
          28, 29, 30, 31, 32,
 
          33, 34, 35:         i = i + 1;
 
          36:                 i = 80;
 
          default:            i = 18;
 
        endcase
 
      end
 
      else // with preamble
 
      begin
 
        case(i)
 
          0, 1:               i = i + 1;
 
          50, 51, 52, 53, 54,
 
          55, 56, 57, 58, 59,
 
          60, 61, 62, 63, 64,
 
          65, 66, 67:         i = i + 1;
 
          68:                 i = 80;
 
          default:            i = 50;
 
        endcase
 
      end
 
      @(posedge wb_clk);
 
    end
 
  end
 
  // set PHY to normal mode
 
  #Tp eth_phy.preamble_suppresed(0);
 
  // MII mode register
 
  wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
  if(fail == 0)
 
    test_ok;
 
  else
 
    fail = 0;
 
end
 
 
 
 
 
if ((start_task <= 10) && (end_task >= 10))
 
begin
 
  // TEST SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER WRITE REQUEST ( WITH AND WITHOUT PREAMBLE )
 
  test_name = "TEST SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER WRITE REQUEST ( WITH AND WITHOUT PREAMBLE )";
 
  `TIME;
 
  $display("  TEST SLIDING STOP SCAN COMMAND IMMEDIATELY AFTER WRITE REQUEST ( WITH AND WITHOUT PREAMBLE )");
 
 
 
  for (i2 = 0; i2 <= 1; i2 = i2 + 1) // choose preamble or not
 
  begin
 
    #Tp eth_phy.preamble_suppresed(i2);
 
    // MII mode register
 
    wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i2, 8'h0}), 4'hF, 1, wbm_init_waits,
 
              wbm_subseq_waits);
 
    i = 0;
 
    cnt = 0;
 
    while (i < 80) // delay for sliding of writing a STOP SCAN command
 
    begin
 
      for (i3 = 0; i3 <= 1; i3 = i3 + 1) // choose read or write after write will be finished
 
      begin
 
        // set address
 
        reg_addr = 5'h0; // control register
 
        phy_addr = 5'h1; // correct PHY address
 
        cnt = 0;
 
        // write request
 
        phy_data = {8'h75, (i[7:0] + 1)};
 
        #Tp mii_write_req(phy_addr, reg_addr, phy_data);
 
        fork
 
          begin
 
            repeat(i) @(posedge Mdc_O);
 
            // write command 0x0 into MII command register
 
            // MII command written while read in progress
 
            wbm_write(`ETH_MIICOMMAND, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
            @(posedge wb_clk);
 
            #Tp check_mii_busy; // wait for write to finish
 
          end
 
          begin
 
            // wait for serial bus to become active
 
            wait(Mdio_IO !== 1'bz);
 
            // count transfer length
 
            while(Mdio_IO !== 1'bz)
 
            begin
 
              @(posedge Mdc_O);
 
              #Tp cnt = cnt + 1;
 
            end
 
          end
 
        join
 
        // check transfer length
 
        if (i2) // without preamble
 
        begin
 
          if (cnt != 33) // at this value Mdio_IO is HIGH Z
 
          begin
 
            test_fail("Write request did not proceed correctly, while SCAN STOP command was written");
 
            fail = fail + 1;
 
          end
 
        end
 
        else // with preamble
 
        begin
 
          if (cnt != 65) // at this value Mdio_IO is HIGH Z
 
          begin
 
            test_fail("Write request did not proceed correctly, while SCAN STOP command was written");
 
            fail = fail + 1;
 
          end
 
        end
 
        // check the BUSY signal to see if the bus is still IDLE
 
        for (i1 = 0; i1 < 8; i1 = i1 + 1)
 
          check_mii_busy; // wait for bus to become idle
 
 
 
        // try normal write or read after write was finished
 
        #Tp cnt = 0;
 
        if (i3 == 0) // write after write
 
        begin
 
          phy_data = {8'h7A, (i[7:0] + 1)};
 
          // write request
 
          #Tp mii_write_req(phy_addr, reg_addr, phy_data);
 
          // wait for serial bus to become active
 
          wait(Mdio_IO !== 1'bz);
 
          // count transfer length
 
          while(Mdio_IO !== 1'bz)
 
          begin
 
            @(posedge Mdc_O);
 
            #Tp cnt = cnt + 1;
 
          end
 
          @(posedge Mdc_O);
 
          // read request
 
          #Tp mii_read_req(phy_addr, reg_addr);
 
          check_mii_busy; // wait for read to finish
 
          // read and check data
 
          #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data , 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
          if (phy_data !== tmp_data)
 
          begin
 
            test_fail("Data was not correctly written into OR read from PHY register - control register");
 
            fail = fail + 1;
 
          end
 
        end
 
        else // read after write
 
        begin
 
          // read request
 
          #Tp mii_read_req(phy_addr, reg_addr);
 
          // wait for serial bus to become active
 
          wait(Mdio_IO !== 1'bz);
 
          // count transfer length
 
          while( (Mdio_IO !== 1'bz) || ((cnt == 47) && (i2 == 0)) || ((cnt == 15) && (i2 == 1)) )
 
          begin
 
            @(posedge Mdc_O);
 
            #Tp cnt = cnt + 1;
 
          end
 
          @(posedge Mdc_O);
 
          check_mii_busy; // wait for read to finish
 
          // read and check data
 
          #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data , 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
          if (phy_data !== tmp_data)
 
          begin
 
            test_fail("Data was not correctly written into OR read from PHY register - control register");
 
            fail = fail + 1;
 
          end
 
        end
 
        // check if transfer was a proper length
 
        if (i2) // without preamble
 
        begin
 
          if (cnt != 33) // at this value Mdio_IO is HIGH Z
 
          begin
 
            test_fail("New request did not proceed correctly, after write request");
 
            fail = fail + 1;
 
          end
 
        end
 
        else // with preamble
 
        begin
 
          if (cnt != 65) // at this value Mdio_IO is HIGH Z
 
          begin
 
            test_fail("New request did not proceed correctly, after write request");
 
            fail = fail + 1;
 
          end
 
        end
 
      end
 
      #Tp;
 
      // set delay of writing the command
 
      if (i2) // without preamble
 
      begin
 
        case(i)
 
          0, 1:               i = i + 1;
 
          18, 19, 20, 21, 22,
 
          23, 24, 25, 26, 27,
 
          28, 29, 30, 31, 32,
 
          33, 34, 35:         i = i + 1;
 
          36:                 i = 80;
 
          default:            i = 18;
 
        endcase
 
      end
 
      else // with preamble
 
      begin
 
        case(i)
 
          0, 1:               i = i + 1;
 
          50, 51, 52, 53, 54,
 
          55, 56, 57, 58, 59,
 
          60, 61, 62, 63, 64,
 
          65, 66, 67:         i = i + 1;
 
          68:                 i = 80;
 
          default:            i = 50;
 
        endcase
 
      end
 
      @(posedge wb_clk);
 
    end
 
  end
 
  // set PHY to normal mode
 
  #Tp eth_phy.preamble_suppresed(0);
 
  // MII mode register
 
  wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
  if(fail == 0)
 
    test_ok;
 
  else
 
    fail = 0;
 
end
 
 
 
 
 
if ((start_task <= 11) && (end_task >= 11))
 
begin
 
  // TEST BUSY AND NVALID STATUS DURATIONS DURING WRITE ( WITH AND WITHOUT PREAMBLE )
 
  test_name   = "TEST BUSY AND NVALID STATUS DURATIONS DURING WRITE ( WITH AND WITHOUT PREAMBLE )";
 
  `TIME; $display("  TEST BUSY AND NVALID STATUS DURATIONS DURING WRITE ( WITH AND WITHOUT PREAMBLE )");
 
 
 
  reset_mii; // reset MII
 
  // set link up, if it wasn't due to previous tests, since there weren't PHY registers
 
  #Tp eth_phy.link_up_down(1);
 
  // set the MII
 
  clk_div = 64;
 
  mii_set_clk_div(clk_div[7:0]);
 
  // set address
 
  reg_addr = 5'h1; // status register
 
  phy_addr = 5'h1; // correct PHY address
 
 
 
  for (i = 0; i <= 1; i = i + 1)
 
  begin
 
    #Tp eth_phy.preamble_suppresed(i);
 
    // MII mode register
 
    wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}) | (`ETH_MIIMODER_CLKDIV & clk_div),
 
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
    @(posedge Mdc_O);
 
    // write request
 
    #Tp mii_write_req(phy_addr, reg_addr, 16'h5A5A);
 
    // read data from MII status register - Busy and Nvalid bits
 
    #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
 
 
    // check MII IO signal and Busy and Nvalid bits
 
    if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
 
    begin
 
      test_fail("Testbench error - read was to late, Mdio_IO is not HIGH Z - set higher clock divider");
 
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
 
      begin
 
        test_fail("Busy signal was not set while MII IO signal is not HIGH Z anymore - 1. read");
 
        fail = fail + 1;
 
      end
 
      if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
 
      begin
 
        test_fail("Nvalid signal was set during write");
 
        fail = fail + 1;
 
      end
 
    end
 
    else // Busy bit should already be set to '1', due to reads from MII status register
 
    begin
 
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
 
      begin
 
        test_fail("Busy signal should be set after write, due to reads from MII status register");
 
        fail = fail + 1;
 
      end
 
      if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
 
      begin
 
        test_fail("Nvalid signal was set during write");
 
        fail = fail + 1;
 
      end
 
    end
 
 
 
    // wait for serial bus to become active
 
    wait(Mdio_IO !== 1'bz);
 
    // count transfer bits
 
    if (i)
 
    begin
 
      repeat(32) @(posedge Mdc_O);
 
    end
 
    else
 
    begin
 
      repeat(64) @(posedge Mdc_O);
 
    end
 
    // read data from MII status register - Busy and Nvalid bits
 
    #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
 
 
    // check MII IO signal and Busy and Nvalid bits
 
    if (Mdio_IO === 1'bz) // Mdio_IO should not be HIGH Z here - testbench selfcheck
 
    begin
 
      test_fail("Testbench error - read was to late, Mdio_IO is HIGH Z - set higher clock divider");
 
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
 
      begin
 
        test_fail("Busy signal should be set while MII IO signal is not active anymore");
 
        fail = fail + 1;
 
      end
 
      if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
 
      begin
 
        test_fail("Nvalid signal was set during write");
 
        fail = fail + 1;
 
      end
 
    end
 
    else // Busy bit should still be set to '1'
 
    begin
 
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
 
      begin
 
        test_fail("Busy signal should be set while MII IO signal not HIGH Z");
 
        fail = fail + 1;
 
      end
 
      if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
 
      begin
 
        test_fail("Nvalid signal was set during write");
 
        fail = fail + 1;
 
      end
 
    end
 
 
 
    // wait for next negative clock edge
 
    @(negedge Mdc_O);
 
    // read data from MII status register - Busy and Nvalid bits
 
    #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
 
 
    // check MII IO signal and Busy and Nvalid bits
 
    if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
 
    begin
 
      test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider");
 
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
 
      begin
 
        test_fail("Busy signal was not set while MII IO signal is not HIGH Z");
 
        fail = fail + 1;
 
      end
 
      if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
 
      begin
 
        test_fail("Nvalid signal was set during write");
 
        fail = fail + 1;
 
      end
 
    end
 
    else // Busy bit should still be set to '1'
 
    begin
 
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
 
      begin
 
        test_fail("Busy signal should be set after MII IO signal become HIGH Z");
 
        fail = fail + 1;
 
      end
 
      if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
 
      begin
 
        test_fail("Nvalid signal was set during write");
 
        fail = fail + 1;
 
      end
 
    end
 
 
 
    // wait for Busy to become inactive
 
    i1 = 0;
 
    while (i1 <= 2)
 
    begin
 
      // wait for next positive clock edge
 
      @(posedge Mdc_O);
 
      // read data from MII status register - Busy and Nvalid bits
 
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
 
 
      // check MII IO signal and Busy and Nvalid bits
 
      if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
 
      begin
 
        test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider");
 
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
 
        begin
 
          test_fail("Busy signal was not set while MII IO signal is not HIGH Z");
 
          fail = fail + 1;
 
        end
 
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
 
        begin
 
          test_fail("Nvalid signal was set during write");
 
          fail = fail + 1;
 
        end
 
      end
 
      else // wait for Busy bit to be set to '0'
 
      begin
 
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
 
        begin
 
          i1 = 3; // end of Busy checking
 
        end
 
        else
 
        begin
 
          if (i1 == 2)
 
          begin
 
            test_fail("Busy signal should be cleared after 2 periods after MII IO signal become HIGH Z");
 
            fail = fail + 1;
 
          end
 
          #Tp i1 = i1 + 1;
 
        end
 
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
 
        begin
 
          test_fail("Nvalid signal was set after write");
 
          fail = fail + 1;
 
        end
 
      end
 
    end
 
  end
 
  // set PHY to normal mode
 
  #Tp eth_phy.preamble_suppresed(0);
 
  // MII mode register
 
  wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
  if(fail == 0)
 
    test_ok;
 
  else
 
    fail = 0;
 
end
 
 
 
 
 
if ((start_task <= 12) && (end_task >= 12))
 
begin
 
  // TEST BUSY AND NVALID STATUS DURATIONS DURING READ ( WITH AND WITHOUT PREAMBLE )
 
  test_name   = "TEST BUSY AND NVALID STATUS DURATIONS DURING READ ( WITH AND WITHOUT PREAMBLE )";
 
  `TIME; $display("  TEST BUSY AND NVALID STATUS DURATIONS DURING READ ( WITH AND WITHOUT PREAMBLE )");
 
 
 
  reset_mii; // reset MII
 
  // set link up, if it wasn't due to previous tests, since there weren't PHY registers
 
  #Tp eth_phy.link_up_down(1);
 
  // set the MII
 
  clk_div = 64;
 
  mii_set_clk_div(clk_div[7:0]);
 
  // set address
 
  reg_addr = 5'h1; // status register
 
  phy_addr = 5'h1; // correct PHY address
 
 
 
  for (i = 0; i <= 1; i = i + 1)
 
  begin
 
    #Tp eth_phy.preamble_suppresed(i);
 
    // MII mode register
 
    wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}) | (`ETH_MIIMODER_CLKDIV & clk_div),
 
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
    @(posedge Mdc_O);
 
    // read request
 
    #Tp mii_read_req(phy_addr, reg_addr);
 
    // read data from MII status register - Busy and Nvalid bits
 
    #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
 
 
    // check MII IO signal and Busy and Nvalid bits
 
    if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
 
    begin
 
      test_fail("Testbench error - read was to late, Mdio_IO is not HIGH Z - set higher clock divider");
 
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
 
      begin
 
        test_fail("Busy signal was not set while MII IO signal is not HIGH Z anymore - 1. read");
 
        fail = fail + 1;
 
      end
 
      if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
 
      begin
 
        test_fail("Nvalid signal was set during read");
 
        fail = fail + 1;
 
      end
 
    end
 
    else // Busy bit should already be set to '1', due to reads from MII status register
 
    begin
 
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
 
      begin
 
        test_fail("Busy signal should be set after read, due to reads from MII status register");
 
        fail = fail + 1;
 
      end
 
      if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
 
      begin
 
        test_fail("Nvalid signal was set during read");
 
        fail = fail + 1;
 
      end
 
    end
 
 
 
    // wait for serial bus to become active
 
    wait(Mdio_IO !== 1'bz);
 
    // count transfer bits
 
    if (i)
 
    begin
 
      repeat(31) @(posedge Mdc_O);
 
    end
 
    else
 
    begin
 
      repeat(63) @(posedge Mdc_O);
 
    end
 
    // wait for next negative clock edge
 
    @(negedge Mdc_O);
 
    // read data from MII status register - Busy and Nvalid bits
 
    #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
 
 
    // check MII IO signal and Busy and Nvalid bits
 
    if (Mdio_IO === 1'bz) // Mdio_IO should not be HIGH Z here - testbench selfcheck
 
    begin
 
      test_fail("Testbench error - read was to late, Mdio_IO is HIGH Z - set higher clock divider");
 
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
 
      begin
 
        test_fail("Busy signal should be set while MII IO signal is not active anymore");
 
        fail = fail + 1;
 
      end
 
      if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
 
      begin
 
        test_fail("Nvalid signal was set during read");
 
        fail = fail + 1;
 
      end
 
    end
 
    else // Busy bit should still be set to '1'
 
    begin
 
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
 
      begin
 
        test_fail("Busy signal should be set while MII IO signal not HIGH Z");
 
        fail = fail + 1;
 
      end
 
      if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
 
      begin
 
        test_fail("Nvalid signal was set during read");
 
        fail = fail + 1;
 
      end
 
    end
 
 
 
    // wait for next positive clock edge
 
    @(posedge Mdc_O);
 
    // read data from MII status register - Busy and Nvalid bits
 
    #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
 
 
    // check MII IO signal and Busy and Nvalid bits
 
    if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
 
    begin
 
      test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider");
 
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
 
      begin
 
        test_fail("Busy signal was not set while MII IO signal is not HIGH Z");
 
        fail = fail + 1;
 
      end
 
      if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
 
      begin
 
        test_fail("Nvalid signal was set during read");
 
        fail = fail + 1;
 
      end
 
    end
 
    else // Busy bit should still be set to '1'
 
    begin
 
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
 
      begin
 
        test_fail("Busy signal should be set after MII IO signal become HIGH Z");
 
        fail = fail + 1;
 
      end
 
      if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
 
      begin
 
        test_fail("Nvalid signal was set during read");
 
        fail = fail + 1;
 
      end
 
    end
 
 
 
    // wait for Busy to become inactive
 
    i1 = 0;
 
    while (i1 <= 2)
 
    begin
 
      // wait for next positive clock edge
 
      @(posedge Mdc_O);
 
      // read data from MII status register - Busy and Nvalid bits
 
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
 
 
      // check MII IO signal and Busy and Nvalid bits
 
      if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
 
      begin
 
        test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider");
 
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
 
        begin
 
          test_fail("Busy signal was not set while MII IO signal is not HIGH Z");
 
          fail = fail + 1;
 
        end
 
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
 
        begin
 
          test_fail("Nvalid signal was set during read");
 
          fail = fail + 1;
 
        end
 
      end
 
      else // wait for Busy bit to be set to '0'
 
      begin
 
        if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
 
        begin
 
          i1 = 3; // end of Busy checking
 
        end
 
        else
 
        begin
 
          if (i1 == 2)
 
          begin
 
            test_fail("Busy signal should be cleared after 2 periods after MII IO signal become HIGH Z");
 
            fail = fail + 1;
 
          end
 
          #Tp i1 = i1 + 1;
 
        end
 
        if (phy_data[`ETH_MIISTATUS_NVALID] !== 1'b0)
 
        begin
 
          test_fail("Nvalid signal was set after read");
 
          fail = fail + 1;
 
        end
 
      end
 
    end
 
  end
 
  // set PHY to normal mode
 
  #Tp eth_phy.preamble_suppresed(0);
 
  // MII mode register
 
  wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
  if(fail == 0)
 
    test_ok;
 
  else
 
    fail = 0;
 
end
 
 
 
 
 
if ((start_task <= 13) && (end_task >= 13))
 
begin
 
  // TEST BUSY AND NVALID STATUS DURATIONS DURING SCAN ( WITH AND WITHOUT PREAMBLE )
 
  test_name   = "TEST BUSY AND NVALID STATUS DURATIONS DURING SCAN ( WITH AND WITHOUT PREAMBLE )";
 
  `TIME; $display("  TEST BUSY AND NVALID STATUS DURATIONS DURING SCAN ( WITH AND WITHOUT PREAMBLE )");
 
 
 
  reset_mii; // reset MII
 
  // set link up, if it wasn't due to previous tests, since there weren't PHY registers
 
  #Tp eth_phy.link_up_down(1);
 
  // set the MII
 
  clk_div = 64;
 
  mii_set_clk_div(clk_div[7:0]);
 
  // set address
 
  reg_addr = 5'h1; // status register
 
  phy_addr = 5'h1; // correct PHY address
 
 
 
  for (i = 0; i <= 1; i = i + 1)
 
  begin
 
    #Tp eth_phy.preamble_suppresed(i);
 
    // MII mode register
 
    wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}) | (`ETH_MIIMODER_CLKDIV & clk_div),
 
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
    @(posedge Mdc_O);
 
    // scan request
 
    #Tp mii_scan_req(phy_addr, reg_addr);
 
    // read data from MII status register - Busy and Nvalid bits
 
    #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
 
 
    // check MII IO signal and Busy and Nvalid bits
 
    if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
 
    begin
 
      test_fail("Testbench error - read was to late, Mdio_IO is not HIGH Z - set higher clock divider");
 
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
 
      begin
 
        test_fail("Busy signal was not set while MII IO signal is not HIGH Z anymore - 1. read");
 
        fail = fail + 1;
 
      end
 
      if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
 
      begin
 
        test_fail("Nvalid signal was not set while MII IO signal is not HIGH Z anymore - 1. read");
 
        fail = fail + 1;
 
      end
 
    end
 
    else // Busy bit should already be set to '1', due to reads from MII status register
 
    begin
 
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
 
      begin
 
        test_fail("Busy signal should be set after scan, due to reads from MII status register");
 
        fail = fail + 1;
 
      end
 
      if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
 
      begin
 
        test_fail("Nvalid signal should be set after scan, due to reads from MII status register");
 
        fail = fail + 1;
 
      end
 
    end
 
 
 
    // wait for serial bus to become active
 
    wait(Mdio_IO !== 1'bz);
 
    // count transfer bits
 
    if (i)
 
    begin
 
      repeat(21) @(posedge Mdc_O);
 
    end
 
    else
 
    begin
 
      repeat(53) @(posedge Mdc_O);
 
    end
 
    // stop scan
 
    #Tp mii_scan_finish; // finish scan operation
 
 
 
    // wait for next positive clock edge
 
    repeat(10) @(posedge Mdc_O);
 
    // read data from MII status register - Busy and Nvalid bits
 
    #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
 
 
    // check MII IO signal and Busy and Nvalid bits
 
    if (Mdio_IO === 1'bz) // Mdio_IO should not be HIGH Z here - testbench selfcheck
 
    begin
 
      test_fail("Testbench error - read was to late, Mdio_IO is HIGH Z - set higher clock divider");
 
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
 
      begin
 
        test_fail("Busy signal should be set while MII IO signal is not active anymore");
 
        fail = fail + 1;
 
      end
 
      // Nvalid signal can be cleared here - it is still Testbench error
 
    end
 
    else // Busy bit should still be set to '1', Nvalid bit should still be set to '1'
 
    begin
 
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
 
      begin
 
        test_fail("Busy signal should be set while MII IO signal not HIGH Z");
 
        fail = fail + 1;
 
      end
 
      if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
 
      begin
 
        test_fail("Nvalid signal should be set while MII IO signal not HIGH Z");
 
        fail = fail + 1;
 
      end
 
    end
 
 
 
    // wait for next negative clock edge
 
    @(negedge Mdc_O);
 
    // read data from MII status register - Busy and Nvalid bits
 
    #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
 
 
    // check MII IO signal and Busy and Nvalid bits
 
    if (Mdio_IO === 1'bz) // Mdio_IO should not be HIGH Z here - testbench selfcheck
 
    begin
 
      test_fail("Testbench error - read was to late, Mdio_IO is HIGH Z - set higher clock divider");
 
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
 
      begin
 
        test_fail("Busy signal should be set while MII IO signal is not active anymore");
 
        fail = fail + 1;
 
      end
 
      // Nvalid signal can be cleared here - it is still Testbench error
 
    end
 
    else // Busy bit should still be set to '1', Nvalid bit should still be set to '1'
 
    begin
 
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
 
      begin
 
        test_fail("Busy signal should be set while MII IO signal not HIGH Z");
 
        fail = fail + 1;
 
      end
 
      if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
 
      begin
 
        test_fail("Nvalid signal should be set while MII IO signal not HIGH Z");
 
        fail = fail + 1;
 
      end
 
    end
 
 
 
    // wait for next negative clock edge
 
    @(posedge Mdc_O);
 
    // read data from MII status register - Busy and Nvalid bits
 
    #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
 
 
    // check MII IO signal and Busy and Nvalid bits
 
    if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
 
    begin
 
      test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider");
 
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
 
      begin
 
        test_fail("Busy signal was not set while MII IO signal is not HIGH Z");
 
        fail = fail + 1;
 
      end
 
      if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
 
      begin
 
        test_fail("Nvalid signal was not set while MII IO signal is not HIGH Z");
 
        fail = fail + 1;
 
      end
 
    end
 
    else // Busy bit should still be set to '1', Nvalid bit can be set to '0'
 
    begin
 
      if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
 
      begin
 
        test_fail("Busy signal should be set after MII IO signal become HIGH Z");
 
        fail = fail + 1;
 
      end
 
      if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
 
      begin
 
        i2 = 1; // check finished
 
      end
 
      else
 
      begin
 
        i2 = 0; // check must continue
 
      end
 
    end
 
 
 
    // wait for Busy to become inactive
 
    i1 = 0;
 
    while ((i1 <= 2) || (i2 == 0))
 
    begin
 
      // wait for next positive clock edge
 
      @(posedge Mdc_O);
 
      // read data from MII status register - Busy and Nvalid bits
 
      #Tp wbm_read(`ETH_MIISTATUS, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
 
 
      // check MII IO signal and Busy and Nvalid bits
 
      if (Mdio_IO !== 1'bz) // Mdio_IO should be HIGH Z here - testbench selfcheck
 
      begin
 
        test_fail("Testbench error - read was to early, Mdio_IO is not HIGH Z - set higher clock divider");
 
        if (i1 <= 2)
 
        begin
 
          if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
 
          begin
 
            test_fail("Busy signal was not set while MII IO signal is not HIGH Z");
 
            fail = fail + 1;
 
          end
 
        end
 
        if (i2 == 0)
 
        begin
 
          if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
 
          begin
 
            test_fail("Nvalid signal was not set while MII IO signal is not HIGH Z");
 
            fail = fail + 1;
 
          end
 
        end
 
      end
 
      else // wait for Busy bit to be set to '0'
 
      begin
 
        if (i1 <= 2)
 
        begin
 
          if (phy_data[`ETH_MIISTATUS_BUSY] === 1'b0)
 
          begin
 
            i1 = 3; // end of Busy checking
 
          end
 
          else
 
          begin
 
            if (i1 == 2)
 
            begin
 
              test_fail("Busy signal should be cleared after 2 periods after MII IO signal become HIGH Z");
 
              fail = fail + 1;
 
            end
 
            #Tp i1 = i1 + 1;
 
          end
 
        end
 
        if (i2 == 0)
 
        begin
 
          if (phy_data[`ETH_MIISTATUS_NVALID] === 1'b0)
 
          begin
 
            i2 = 1;
 
          end
 
          else
 
          begin
 
            test_fail("Nvalid signal should be cleared after MII IO signal become HIGH Z");
 
            fail = fail + 1;
 
          end
 
        end
 
      end
 
    end
 
  end
 
  // set PHY to normal mode
 
  #Tp eth_phy.preamble_suppresed(0);
 
  // MII mode register
 
  wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
  if(fail == 0)
 
    test_ok;
 
  else
 
    fail = 0;
 
end
 
 
 
 
 
if ((start_task <= 14) && (end_task >= 14))
 
begin
 
  // TEST SCAN STATUS FROM PHY WITH DETECTING LINK-FAIL BIT ( WITH AND WITHOUT PREAMBLE )
 
  test_name   = "TEST SCAN STATUS FROM PHY WITH DETECTING LINK-FAIL BIT ( WITH AND WITHOUT PREAMBLE )";
 
  `TIME; $display("  TEST SCAN STATUS FROM PHY WITH DETECTING LINK-FAIL BIT ( WITH AND WITHOUT PREAMBLE )");
 
 
 
  reset_mii; // reset MII
 
  // set link up, if it wasn't due to previous tests, since there weren't PHY registers
 
  #Tp eth_phy.link_up_down(1);
 
  // set MII speed
 
  clk_div = 6;
 
  mii_set_clk_div(clk_div[7:0]);
 
  // set address
 
  reg_addr = 5'h1; // status register
 
  phy_addr = 5'h1; // correct PHY address
 
 
 
  // read request
 
  #Tp mii_read_req(phy_addr, reg_addr);
 
  check_mii_busy; // wait for read to finish
 
  // read data from PHY status register - remember LINK-UP status
 
  #Tp wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
 
 
  for (i = 0; i <= 1; i = i + 1)
 
  begin
 
    #Tp eth_phy.preamble_suppresed(i);
 
    // MII mode register
 
    wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}) | (`ETH_MIIMODER_CLKDIV & clk_div),
 
              4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
    if (i)
 
    begin
 
      // change saved data when preamble is suppressed
 
      #Tp tmp_data = tmp_data | 16'h0040; // put bit 6 to ONE
 
    end
 
 
 
    // scan request
 
    #Tp mii_scan_req(phy_addr, reg_addr);
 
    check_mii_scan_valid; // wait for scan to make first data valid
 
 
 
    fork
 
    begin
 
      repeat(2) @(posedge Mdc_O);
 
      // read data from PHY status register
 
      #Tp wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
 
      if (phy_data !== tmp_data)
 
      begin
 
        test_fail("Data was not correctly scaned from status register");
 
        fail = fail + 1;