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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [bench/] [verilog/] [eth_phy.v] - Diff between revs 408 and 415

Only display areas with differences | Details | Blame | View Log

Rev 408 Rev 415
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
////                                                              ////
////                                                              ////
////  File name: eth_phy.v                                        ////
////  File name: eth_phy.v                                        ////
////                                                              ////
////                                                              ////
////  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):                                                  ////
////      - Tadej Markovic, tadej@opencores.org                   ////
////      - Tadej Markovic, tadej@opencores.org                   ////
////                                                              ////
////                                                              ////
////  All additional information is available in the README.txt   ////
////  All additional information is available in the README.txt   ////
////  file.                                                       ////
////  file.                                                       ////
////                                                              ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
////                                                              ////
////                                                              ////
//// Copyright (C) 2002  Authors                                  ////
//// Copyright (C) 2002  Authors                                  ////
////                                                              ////
////                                                              ////
//// This source file may be used and distributed without         ////
//// This source file may be used and distributed without         ////
//// restriction provided that this copyright statement is not    ////
//// restriction provided that this copyright statement is not    ////
//// removed from the file and that any derivative work contains  ////
//// removed from the file and that any derivative work contains  ////
//// the original copyright notice and the associated disclaimer. ////
//// the original copyright notice and the associated disclaimer. ////
////                                                              ////
////                                                              ////
//// This source file is free software; you can redistribute it   ////
//// This source file is free software; you can redistribute it   ////
//// and/or modify it under the terms of the GNU Lesser General   ////
//// and/or modify it under the terms of the GNU Lesser General   ////
//// Public License as published by the Free Software Foundation; ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any   ////
//// either version 2.1 of the License, or (at your option) any   ////
//// later version.                                               ////
//// later version.                                               ////
////                                                              ////
////                                                              ////
//// This source is distributed in the hope that it will be       ////
//// This source is distributed in the hope that it will be       ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
//// PURPOSE.  See the GNU Lesser General Public License for more ////
//// PURPOSE.  See the GNU Lesser General Public License for more ////
//// details.                                                     ////
//// details.                                                     ////
////                                                              ////
////                                                              ////
//// You should have received a copy of the GNU Lesser General    ////
//// You should have received a copy of the GNU Lesser General    ////
//// Public License along with this source; if not, download it   ////
//// Public License along with this source; if not, download it   ////
//// from http://www.opencores.org/lgpl.shtml                     ////
//// from http://www.opencores.org/lgpl.shtml                     ////
////                                                              ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//
//
// CVS Revision History
// CVS Revision History
//
//
// $Log: not supported by cvs2svn $
// $Log: not supported by cvs2svn $
// Revision 1.7  2002/10/18 13:58:22  tadejm
// Revision 1.7  2002/10/18 13:58:22  tadejm
// Some code changed due to bug fixes.
// Some code changed due to bug fixes.
//
//
// Revision 1.6  2002/10/09 13:16:51  tadejm
// Revision 1.6  2002/10/09 13:16:51  tadejm
// Just back-up; not completed testbench and some testcases are not
// Just back-up; not completed testbench and some testcases are not
// wotking properly yet.
// wotking properly yet.
//
//
// Revision 1.5  2002/09/18 17:55:08  tadej
// Revision 1.5  2002/09/18 17:55:08  tadej
// Bug repaired in eth_phy device
// Bug repaired in eth_phy device
//
//
// Revision 1.3  2002/09/13 14:50:15  mohor
// Revision 1.3  2002/09/13 14:50:15  mohor
// Bug in MIIM fixed.
// Bug in MIIM fixed.
//
//
// Revision 1.2  2002/09/13 12:29:14  mohor
// Revision 1.2  2002/09/13 12:29:14  mohor
// Headers changed.
// Headers changed.
//
//
// Revision 1.1  2002/09/13 11:57:20  mohor
// Revision 1.1  2002/09/13 11:57:20  mohor
// New testbench. Thanks to Tadej M - "The Spammer".
// New testbench. Thanks to Tadej M - "The Spammer".
//
//
//
//
//
//
 
 
`include "timescale.v"
`include "timescale.v"
`include "eth_phy_defines.v"
`include "eth_phy_defines.v"
 
 
// ORPSoCv2 testbench include
// ORPSoCv2 testbench include
// Will enable verbose if eth test
// Will enable verbose if eth test
`ifdef TEST_DEFINE_FILE
`ifdef TEST_DEFINE_FILE
 `include "test_define.v"
 `include "test_define.v"
`endif
`endif
 
 
 
 
`define MULTICAST_XFR          0
`define MULTICAST_XFR          0
`define UNICAST_XFR            1
`define UNICAST_XFR            1
`define BROADCAST_XFR          2
`define BROADCAST_XFR          2
`define UNICAST_WRONG_XFR      3
`define UNICAST_WRONG_XFR      3
 
 
 
 
`define ETH_PHY_VERBOSE 1
`define ETH_PHY_VERBOSE 1
 
 
module eth_phy // This PHY model simulate simplified Intel LXT971A PHY
module eth_phy // This PHY model simulate simplified Intel LXT971A PHY
  (
  (
   // COMMON
   // COMMON
   m_rst_n_i,
   m_rst_n_i,
 
 
   // MAC TX
   // MAC TX
   mtx_clk_o,
   mtx_clk_o,
   mtxd_i,
   mtxd_i,
   mtxen_i,
   mtxen_i,
   mtxerr_i,
   mtxerr_i,
 
 
   // MAC RX
   // MAC RX
   mrx_clk_o,
   mrx_clk_o,
   mrxd_o,
   mrxd_o,
   mrxdv_o,
   mrxdv_o,
   mrxerr_o,
   mrxerr_o,
 
 
   // SMII signals
   // SMII signals
   smii_clk_i,
   smii_clk_i,
   smii_sync_i,
   smii_sync_i,
   smii_rx_o,
   smii_rx_o,
 
 
   mcoll_o,
   mcoll_o,
   mcrs_o,
   mcrs_o,
 
 
   // MIIM
   // MIIM
   mdc_i,
   mdc_i,
   md_io,
   md_io,
   speed_o,
   speed_o,
   link_o,
   link_o,
   duplex_o
   duplex_o
   );
   );
 
 
   //////////////////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////////////////
         //
         //
   // Input/output signals
   // Input/output signals
   //
   //
   //////////////////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////////////////
 
 
   // MAC miscellaneous signals
   // MAC miscellaneous signals
   input           m_rst_n_i;
   input           m_rst_n_i;
   // MAC TX signals
   // MAC TX signals
   output          mtx_clk_o;
   output          mtx_clk_o;
   input [3:0]      mtxd_i;
   input [3:0]      mtxd_i;
   input           mtxen_i;
   input           mtxen_i;
   input           mtxerr_i;
   input           mtxerr_i;
   // MAC RX signals
   // MAC RX signals
   output          mrx_clk_o;
   output          mrx_clk_o;
   output [3:0]    mrxd_o;
   output [3:0]    mrxd_o;
   output          mrxdv_o;
   output          mrxdv_o;
   output          mrxerr_o;
   output          mrxerr_o;
   // SMII RX signals
   // SMII RX signals
   input           smii_clk_i;
   input           smii_clk_i;
   input           smii_sync_i;
   input           smii_sync_i;
   output          smii_rx_o;
   output          smii_rx_o;
 
 
   // MAC common signals
   // MAC common signals
   output          mcoll_o;
   output          mcoll_o;
   output          mcrs_o;
   output          mcrs_o;
   // MAC management signals
   // MAC management signals
   input           mdc_i;
   input           mdc_i;
   inout           md_io;
   inout           md_io;
   // Sideband signals for SMII -- jb
   // Sideband signals for SMII -- jb
   output          link_o;
   output          link_o;
   output          speed_o;
   output          speed_o;
   output          duplex_o;
   output          duplex_o;
 
 
 
 
   //////////////////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////////////////
   //
   //
   // PHY management (MIIM) REGISTER definitions
   // PHY management (MIIM) REGISTER definitions
   //
   //
   //////////////////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////////////////
   //
   //
   //   Supported registers:
   //   Supported registers:
   //
   //
   // Addr | Register Name
   // Addr | Register Name
   //--------------------------------------------------------------------
   //--------------------------------------------------------------------
   //   0  | Control reg.     |
   //   0  | Control reg.     |
   //   1  | Status reg. #1   |--> normal operation
   //   1  | Status reg. #1   |--> normal operation
   //   2  | PHY ID reg. 1    |
   //   2  | PHY ID reg. 1    |
   //   3  | PHY ID reg. 2    |
   //   3  | PHY ID reg. 2    |
   //----------------------
   //----------------------
   // Addr | Data MEMORY      |-->  for testing
   // Addr | Data MEMORY      |-->  for testing
   //
   //
   //--------------------------------------------------------------------
   //--------------------------------------------------------------------
   //
   //
   // Control register
   // Control register
   reg             control_bit15; // self clearing bit
   reg             control_bit15; // self clearing bit
   reg [14:10]     control_bit14_10 = 5'b01000; // Init to 100MBPs (speed set)
   reg [14:10]     control_bit14_10 = 5'b01000; // Init to 100MBPs (speed set)
   reg             control_bit9; // self clearing bit
   reg             control_bit9; // self clearing bit
   reg [8:0]        control_bit8_0;
   reg [8:0]        control_bit8_0;
   // Status register
   // Status register
   wire [15:9]     status_bit15_9 = `SUPPORTED_SPEED_AND_PORT;
   wire [15:9]     status_bit15_9 = `SUPPORTED_SPEED_AND_PORT;
   wire            status_bit8    = `EXTENDED_STATUS;
   wire            status_bit8    = `EXTENDED_STATUS;
   wire            status_bit7    = 1'b0; // reserved
   wire            status_bit7    = 1'b0; // reserved
   reg [6:0]        status_bit6_0;
   reg [6:0]        status_bit6_0;
   // PHY ID register 1
   // PHY ID register 1
   wire [15:0]      phy_id1        = `PHY_ID1;
   wire [15:0]      phy_id1        = `PHY_ID1;
   // PHY ID register 2
   // PHY ID register 2
   wire [15:0]      phy_id2        = {`PHY_ID2, `MAN_MODEL_NUM, `MAN_REVISION_NUM};
   wire [15:0]      phy_id2        = {`PHY_ID2, `MAN_MODEL_NUM, `MAN_REVISION_NUM};
   //--------------------------------------------------------------------
   //--------------------------------------------------------------------
   //
   //
   // Data MEMORY
   // Data MEMORY
   reg [15:0]       data_mem [0:31]; // 32 locations of 16-bit data width
   reg [15:0]       data_mem [0:31]; // 32 locations of 16-bit data width
   //
   //
   //////////////////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////////////////
 
 
 
 
   //////////////////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////////////////
   //
   //
   // PHY clocks - RX & TX
   // PHY clocks - RX & TX
   //
   //
   //////////////////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////////////////
 
 
   reg             mtx_clk_o;
   reg             mtx_clk_o;
   reg             mrx_clk_o;
   reg             mrx_clk_o;
 
 
   // random generator for a RX period when link is down
   // random generator for a RX period when link is down
   real            rx_link_down_halfperiod;
   real            rx_link_down_halfperiod;
 
 
   always@(status_bit6_0[2])
   always@(status_bit6_0[2])
     begin
     begin
        if (!status_bit6_0[2]) // Link is down
        if (!status_bit6_0[2]) // Link is down
          begin
          begin
             #1 rx_link_down_halfperiod = ({$random} % 243) + 13;
             #1 rx_link_down_halfperiod = ({$random} % 243) + 13;
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
             #1 $display( "(%0t)(%m)MAC RX clock is %f MHz while ethernet link is down!",
             #1 $display( "(%0t)(%m)MAC RX clock is %f MHz while ethernet link is down!",
                          $time, (1000/(rx_link_down_halfperiod*2)) );
                          $time, (1000/(rx_link_down_halfperiod*2)) );
`endif
`endif
          end
          end
     end
     end
 
 
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
   always@(status_bit6_0[2])
   always@(status_bit6_0[2])
     begin
     begin
        if (!status_bit6_0[2]) // Link is down
        if (!status_bit6_0[2]) // Link is down
          #1 $display( "(%0t)(%m)Ethernet link is down!", $time);
          #1 $display( "(%0t)(%m)Ethernet link is down!", $time);
        else
        else
          #1 $display( "(%0t)(%m)Ethernet link is up!", $time);
          #1 $display( "(%0t)(%m)Ethernet link is up!", $time);
     end
     end
`endif
`endif
 
 
   // speed selection signal eth_speed: 1'b1 - 100 Mbps, 1'b0 - 10 Mbps
   // speed selection signal eth_speed: 1'b1 - 100 Mbps, 1'b0 - 10 Mbps
   wire      eth_speed;
   wire      eth_speed;
 
 
   assign eth_speed = ( (control_bit14_10[13]) && !((`LED_CFG1) && (`LED_CFG2)) );
   assign eth_speed = ( (control_bit14_10[13]) && !((`LED_CFG1) && (`LED_CFG2)) );
 
 
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
   always@(eth_speed)
   always@(eth_speed)
     begin
     begin
        if (eth_speed)
        if (eth_speed)
          #1 $display( "(%0t)(%m)PHY configured to 100 Mbps!", $time);
          #1 $display( "(%0t)(%m)PHY configured to 100 Mbps!", $time);
        else
        else
          #1 $display( "(%0t)(%m)PHY configured tp 10 Mbps!", $time);
          #1 $display( "(%0t)(%m)PHY configured tp 10 Mbps!", $time);
     end
     end
`endif
`endif
 
 
   // different clock calculation between RX and TX, so that there is alsways a litle difference
   // different clock calculation between RX and TX, so that there is alsways a litle difference
   /*initial
   /*initial
    begin
    begin
    set_mrx_equal_mtx = 1; // default
    set_mrx_equal_mtx = 1; // default
end*/
end*/
 
 
   always
   always
     begin
     begin
        mtx_clk_o = 0;
        mtx_clk_o = 0;
        #7;
        #7;
        forever
        forever
          begin
          begin
             if (eth_speed) // 100 Mbps - 25 MHz, 40 ns
             if (eth_speed) // 100 Mbps - 25 MHz, 40 ns
               begin
               begin
                  #20 mtx_clk_o = ~mtx_clk_o;
                  #20 mtx_clk_o = ~mtx_clk_o;
               end
               end
             else // 10 Mbps - 2.5 MHz, 400 ns
             else // 10 Mbps - 2.5 MHz, 400 ns
               begin
               begin
                  #200 mtx_clk_o = ~mtx_clk_o;
                  #200 mtx_clk_o = ~mtx_clk_o;
               end
               end
          end
          end
     end
     end
 
 
   always
   always
     begin
     begin
        // EQUAL mrx_clk to mtx_clk
        // EQUAL mrx_clk to mtx_clk
        mrx_clk_o = 0;
        mrx_clk_o = 0;
        #7;
        #7;
        forever
        forever
          begin
          begin
             if (eth_speed) // 100 Mbps - 25 MHz, 40 ns
             if (eth_speed) // 100 Mbps - 25 MHz, 40 ns
               begin
               begin
                  #20 mrx_clk_o = ~mrx_clk_o;
                  #20 mrx_clk_o = ~mrx_clk_o;
               end
               end
             else // 10 Mbps - 2.5 MHz, 400 ns
             else // 10 Mbps - 2.5 MHz, 400 ns
               begin
               begin
                  #200 mrx_clk_o = ~mrx_clk_o;
                  #200 mrx_clk_o = ~mrx_clk_o;
               end
               end
          end
          end
        // DIFFERENT mrx_clk than mtx_clk
        // DIFFERENT mrx_clk than mtx_clk
        /*  mrx_clk_diff_than_mtx = 1;
        /*  mrx_clk_diff_than_mtx = 1;
         #3;
         #3;
         forever
         forever
         begin
         begin
         if (status_bit6_0[2]) // Link is UP
         if (status_bit6_0[2]) // Link is UP
         begin
         begin
         if (eth_speed) // 100 Mbps - 25 MHz, 40 ns
         if (eth_speed) // 100 Mbps - 25 MHz, 40 ns
         begin
         begin
         //#(((1/0.025001)/2))
         //#(((1/0.025001)/2))
         #19.99 mrx_clk_diff_than_mtx = ~mrx_clk_diff_than_mtx; // period is calculated from frequency in GHz
         #19.99 mrx_clk_diff_than_mtx = ~mrx_clk_diff_than_mtx; // period is calculated from frequency in GHz
      end
      end
         else // 10 Mbps - 2.5 MHz, 400 ns
         else // 10 Mbps - 2.5 MHz, 400 ns
         begin
         begin
         //#(((1/0.0024999)/2))
         //#(((1/0.0024999)/2))
         #200.01 mrx_clk_diff_than_mtx = ~mrx_clk_diff_than_mtx; // period is calculated from frequency in GHz
         #200.01 mrx_clk_diff_than_mtx = ~mrx_clk_diff_than_mtx; // period is calculated from frequency in GHz
      end
      end
    end
    end
         else // Link is down
         else // Link is down
         begin
         begin
         #(rx_link_down_halfperiod) mrx_clk_diff_than_mtx = ~mrx_clk_diff_than_mtx; // random frequency between 2 MHz and 40 MHz
         #(rx_link_down_halfperiod) mrx_clk_diff_than_mtx = ~mrx_clk_diff_than_mtx; // random frequency between 2 MHz and 40 MHz
    end
    end
  end*/
  end*/
        //  // set output mrx_clk
        //  // set output mrx_clk
        //  if (set_mrx_equal_mtx)
        //  if (set_mrx_equal_mtx)
        //    mrx_clk_o = mrx_clk_equal_to_mtx;
        //    mrx_clk_o = mrx_clk_equal_to_mtx;
        //  else
        //  else
        //    mrx_clk_o = mrx_clk_diff_than_mtx;
        //    mrx_clk_o = mrx_clk_diff_than_mtx;
     end
     end
 
 
   // set output mrx_clk
   // set output mrx_clk
   //assign mrx_clk_o = set_mrx_equal_mtx ? mrx_clk_equal_to_mtx : mrx_clk_diff_than_mtx ;
   //assign mrx_clk_o = set_mrx_equal_mtx ? mrx_clk_equal_to_mtx : mrx_clk_diff_than_mtx ;
 
 
   //////////////////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////////////////
   //
   //
   // PHY management (MIIM) interface
   // PHY management (MIIM) interface
   //
   //
   //////////////////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////////////////
   reg             respond_to_all_phy_addr; // PHY will respond to all phy addresses
   reg             respond_to_all_phy_addr; // PHY will respond to all phy addresses
   reg             no_preamble; // PHY responds to frames without preamble
   reg             no_preamble; // PHY responds to frames without preamble
 
 
   integer         md_transfer_cnt; // counter countes the value of whole data transfer
   integer         md_transfer_cnt; // counter countes the value of whole data transfer
   reg             md_transfer_cnt_reset; // for reseting the counter
   reg             md_transfer_cnt_reset; // for reseting the counter
   reg             md_io_reg; // registered input
   reg             md_io_reg; // registered input
   reg             md_io_output; // registered output
   reg             md_io_output; // registered output
   reg             md_io_rd_wr;  // op-code latched (read or write)
   reg             md_io_rd_wr;  // op-code latched (read or write)
   reg             md_io_enable; // output enable
   reg             md_io_enable; // output enable
   reg [4:0]        phy_address; // address of PHY device
   reg [4:0]        phy_address; // address of PHY device
   reg [4:0]        reg_address; // address of a register
   reg [4:0]        reg_address; // address of a register
   reg             md_get_phy_address; // for shifting PHY address in
   reg             md_get_phy_address; // for shifting PHY address in
   reg             md_get_reg_address; // for shifting register address in
   reg             md_get_reg_address; // for shifting register address in
   reg [15:0]       reg_data_in; // data to be written in a register
   reg [15:0]       reg_data_in; // data to be written in a register
   reg             md_get_reg_data_in; // for shifting data in
   reg             md_get_reg_data_in; // for shifting data in
   reg             md_put_reg_data_in; // for storing data into a selected register
   reg             md_put_reg_data_in; // for storing data into a selected register
   reg [15:0]       reg_data_out; // data to be read from a register
   reg [15:0]       reg_data_out; // data to be read from a register
   reg             md_put_reg_data_out; // for registering data from a selected register
   reg             md_put_reg_data_out; // for registering data from a selected register
 
 
   wire [15:0]      register_bus_in; // data bus to a selected register
   wire [15:0]      register_bus_in; // data bus to a selected register
   reg [15:0]       register_bus_out; // data bus from a selected register
   reg [15:0]       register_bus_out; // data bus from a selected register
 
 
   initial
   initial
     begin
     begin
        md_io_enable = 1'b0;
        md_io_enable = 1'b0;
        respond_to_all_phy_addr = 1'b0;
        respond_to_all_phy_addr = 1'b0;
        no_preamble = 1'b0;
        no_preamble = 1'b0;
     end
     end
 
 
   // tristate output
   // tristate output
   assign #1 md_io = (m_rst_n_i && md_io_enable) ? md_io_output : 1'bz ;
   assign #1 md_io = (m_rst_n_i && md_io_enable) ? md_io_output : 1'bz ;
 
 
   // registering input
   // registering input
   always@(posedge mdc_i or negedge m_rst_n_i)
   always@(posedge mdc_i or negedge m_rst_n_i)
     begin
     begin
        if (!m_rst_n_i)
        if (!m_rst_n_i)
          md_io_reg <= #1 0;
          md_io_reg <= #1 0;
        else
        else
          md_io_reg <= #1 md_io;
          md_io_reg <= #1 md_io;
     end
     end
 
 
   // getting (shifting) PHY address, Register address and Data in
   // getting (shifting) PHY address, Register address and Data in
   // putting Data out and shifting
   // putting Data out and shifting
   always@(posedge mdc_i or negedge m_rst_n_i)
   always@(posedge mdc_i or negedge m_rst_n_i)
     begin
     begin
        if (!m_rst_n_i)
        if (!m_rst_n_i)
          begin
          begin
             phy_address <= 0;
             phy_address <= 0;
             reg_address <= 0;
             reg_address <= 0;
             reg_data_in <= 0;
             reg_data_in <= 0;
             reg_data_out <= 0;
             reg_data_out <= 0;
             md_io_output <= 0;
             md_io_output <= 0;
          end
          end
        else
        else
          begin
          begin
             if (md_get_phy_address)
             if (md_get_phy_address)
               begin
               begin
                  phy_address[4:1] <= phy_address[3:0]; // correct address is `ETH_PHY_ADDR
                  phy_address[4:1] <= phy_address[3:0]; // correct address is `ETH_PHY_ADDR
                  phy_address[0]   <= md_io;
                  phy_address[0]   <= md_io;
               end
               end
             if (md_get_reg_address)
             if (md_get_reg_address)
               begin
               begin
                  reg_address[4:1] <= reg_address[3:0];
                  reg_address[4:1] <= reg_address[3:0];
                  reg_address[0]   <= md_io;
                  reg_address[0]   <= md_io;
               end
               end
             if (md_get_reg_data_in)
             if (md_get_reg_data_in)
               begin
               begin
                  reg_data_in[15:1] <= reg_data_in[14:0];
                  reg_data_in[15:1] <= reg_data_in[14:0];
                  reg_data_in[0]    <= md_io;
                  reg_data_in[0]    <= md_io;
               end
               end
             if (md_put_reg_data_out)
             if (md_put_reg_data_out)
               begin
               begin
                  reg_data_out <= register_bus_out;
                  reg_data_out <= register_bus_out;
               end
               end
             if (md_io_enable)
             if (md_io_enable)
               begin
               begin
                  md_io_output       <= reg_data_out[15];
                  md_io_output       <= reg_data_out[15];
                  reg_data_out[15:1] <= reg_data_out[14:0];
                  reg_data_out[15:1] <= reg_data_out[14:0];
                  reg_data_out[0]    <= 1'b0;
                  reg_data_out[0]    <= 1'b0;
               end
               end
          end
          end
     end
     end
 
 
   assign #1 register_bus_in = reg_data_in; // md_put_reg_data_in - allows writing to a selected register
   assign #1 register_bus_in = reg_data_in; // md_put_reg_data_in - allows writing to a selected register
 
 
   // counter for transfer to and from MIIM
   // counter for transfer to and from MIIM
   always@(posedge mdc_i or negedge m_rst_n_i)
   always@(posedge mdc_i or negedge m_rst_n_i)
     begin
     begin
        if (!m_rst_n_i)
        if (!m_rst_n_i)
          begin
          begin
             if (no_preamble)
             if (no_preamble)
               md_transfer_cnt <= 33;
               md_transfer_cnt <= 33;
             else
             else
               md_transfer_cnt <= 1;
               md_transfer_cnt <= 1;
          end
          end
        else
        else
          begin
          begin
             if (md_transfer_cnt_reset)
             if (md_transfer_cnt_reset)
               begin
               begin
                  if (no_preamble)
                  if (no_preamble)
                    md_transfer_cnt <= 33;
                    md_transfer_cnt <= 33;
                  else
                  else
                    md_transfer_cnt <= 1;
                    md_transfer_cnt <= 1;
               end
               end
             else if (md_transfer_cnt < 64)
             else if (md_transfer_cnt < 64)
               begin
               begin
                  md_transfer_cnt <= md_transfer_cnt + 1'b1;
                  md_transfer_cnt <= md_transfer_cnt + 1'b1;
               end
               end
             else
             else
               begin
               begin
                  if (no_preamble)
                  if (no_preamble)
                    md_transfer_cnt <= 33;
                    md_transfer_cnt <= 33;
                  else
                  else
                    md_transfer_cnt <= 1;
                    md_transfer_cnt <= 1;
               end
               end
          end
          end
     end
     end
 
 
   // MIIM transfer control
   // MIIM transfer control
   always@(m_rst_n_i or md_transfer_cnt or md_io_reg or md_io_rd_wr or
   always@(m_rst_n_i or md_transfer_cnt or md_io_reg or md_io_rd_wr or
           phy_address or respond_to_all_phy_addr or no_preamble)
           phy_address or respond_to_all_phy_addr or no_preamble)
     begin
     begin
        #1;
        #1;
        while ((m_rst_n_i) && (md_transfer_cnt <= 64))
        while ((m_rst_n_i) && (md_transfer_cnt <= 64))
          begin
          begin
             // reset the signal - put registered data in the register (when write)
             // reset the signal - put registered data in the register (when write)
             // check preamble
             // check preamble
             if (md_transfer_cnt < 33)
             if (md_transfer_cnt < 33)
               begin
               begin
                  #4 md_put_reg_data_in = 1'b0;
                  #4 md_put_reg_data_in = 1'b0;
                  if (md_io_reg !== 1'b1)
                  if (md_io_reg !== 1'b1)
                    begin
                    begin
                       #1 md_transfer_cnt_reset = 1'b1;
                       #1 md_transfer_cnt_reset = 1'b1;
                    end
                    end
                  else
                  else
                    begin
                    begin
                       #1 md_transfer_cnt_reset = 1'b0;
                       #1 md_transfer_cnt_reset = 1'b0;
                    end
                    end
               end
               end
 
 
             // check start bits
             // check start bits
             else if (md_transfer_cnt == 33)
             else if (md_transfer_cnt == 33)
               begin
               begin
                  if (no_preamble)
                  if (no_preamble)
                    begin
                    begin
                       #4 md_put_reg_data_in = 1'b0;
                       #4 md_put_reg_data_in = 1'b0;
                       if (md_io_reg === 1'b0)
                       if (md_io_reg === 1'b0)
                         begin
                         begin
                            #1 md_transfer_cnt_reset = 1'b0;
                            #1 md_transfer_cnt_reset = 1'b0;
                         end
                         end
                       else
                       else
                         begin
                         begin
                            #1 md_transfer_cnt_reset = 1'b1;
                            #1 md_transfer_cnt_reset = 1'b1;
                            //if ((md_io_reg !== 1'bz) && (md_io_reg !== 1'b1))
                            //if ((md_io_reg !== 1'bz) && (md_io_reg !== 1'b1))
                            if (md_io_reg !== 1'bz)
                            if (md_io_reg !== 1'bz)
                              begin
                              begin
                                 // ERROR - start !
                                 // ERROR - start !
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
                                 $display( "*E (%0t)(%m)MIIM - wrong first start bit (without preamble)", $time);
                                 $display( "*E (%0t)(%m)MIIM - wrong first start bit (without preamble)", $time);
`endif
`endif
                                 #10 $stop;
                                 #10 $stop;
                              end
                              end
                         end
                         end
                    end
                    end
                  else // with preamble
                  else // with preamble
                    begin
                    begin
                       #4 ;
                       #4 ;
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
                       $display( "(%0t)(%m)MIIM - 32-bit preamble received", $time);
                       $display( "(%0t)(%m)MIIM - 32-bit preamble received", $time);
`endif
`endif
                       // check start bit only if md_transfer_cnt_reset is inactive, because if
                       // check start bit only if md_transfer_cnt_reset is inactive, because if
                       // preamble suppression was changed start bit should not be checked
                       // preamble suppression was changed start bit should not be checked
                       if ((md_io_reg !== 1'b0) && (md_transfer_cnt_reset == 1'b0))
                       if ((md_io_reg !== 1'b0) && (md_transfer_cnt_reset == 1'b0))
                         begin
                         begin
                            // ERROR - start !
                            // ERROR - start !
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
                            $display( "*E (%0t)(%m)MIIM - wrong first start bit", $time);
                            $display( "*E (%0t)(%m)MIIM - wrong first start bit", $time);
`endif
`endif
                            #10 $stop;
                            #10 $stop;
                         end
                         end
                    end
                    end
               end
               end
 
 
             else if (md_transfer_cnt == 34)
             else if (md_transfer_cnt == 34)
               begin
               begin
                  #4;
                  #4;
                  if (md_io_reg !== 1'b1)
                  if (md_io_reg !== 1'b1)
                    begin
                    begin
                       // ERROR - start !
                       // ERROR - start !
                       #1;
                       #1;
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
                       if (no_preamble)
                       if (no_preamble)
                         $display( "*E (%0t)(%m)MIIM - wrong second start bit (without preamble)", $time);
                         $display( "*E (%0t)(%m)MIIM - wrong second start bit (without preamble)", $time);
                       else
                       else
                         $display( "*E (%0t)(%m)MIIM - wrong second start bit", $time);
                         $display( "*E (%0t)(%m)MIIM - wrong second start bit", $time);
`endif
`endif
                       #10 $stop;
                       #10 $stop;
                    end
                    end
                  else
                  else
                    begin
                    begin
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
                       if (no_preamble)
                       if (no_preamble)
                         #1 $display( "(%0t)(%m)MIIM - 2 start bits received (without preamble)", $time);
                         #1 $display( "(%0t)(%m)MIIM - 2 start bits received (without preamble)", $time);
                       else
                       else
                         #1 $display( "(%0t)(%m)MIIM - 2 start bits received", $time);
                         #1 $display( "(%0t)(%m)MIIM - 2 start bits received", $time);
`endif
`endif
                    end
                    end
               end
               end
 
 
             // register the op-code (rd / wr)
             // register the op-code (rd / wr)
             else if (md_transfer_cnt == 35)
             else if (md_transfer_cnt == 35)
               begin
               begin
                  #4;
                  #4;
                  if (md_io_reg === 1'b1)
                  if (md_io_reg === 1'b1)
                    begin
                    begin
                       #1 md_io_rd_wr = 1'b1;
                       #1 md_io_rd_wr = 1'b1;
                    end
                    end
                  else
                  else
                    begin
                    begin
                       #1 md_io_rd_wr = 1'b0;
                       #1 md_io_rd_wr = 1'b0;
                    end
                    end
               end
               end
 
 
             else if (md_transfer_cnt == 36)
             else if (md_transfer_cnt == 36)
               begin
               begin
                  #4;
                  #4;
                  if ((md_io_reg === 1'b0) && (md_io_rd_wr == 1'b1))
                  if ((md_io_reg === 1'b0) && (md_io_rd_wr == 1'b1))
                    begin
                    begin
                       #1 md_io_rd_wr = 1'b1; // reading from PHY registers
                       #1 md_io_rd_wr = 1'b1; // reading from PHY registers
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
                       $display( "(%0t)(%m)MIIM - op-code for READING from registers", $time);
                       $display( "(%0t)(%m)MIIM - op-code for READING from registers", $time);
`endif
`endif
                    end
                    end
                  else if ((md_io_reg === 1'b1) && (md_io_rd_wr == 1'b0))
                  else if ((md_io_reg === 1'b1) && (md_io_rd_wr == 1'b0))
                    begin
                    begin
                       #1 md_io_rd_wr = 1'b0; // writing to PHY registers
                       #1 md_io_rd_wr = 1'b0; // writing to PHY registers
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
                       $display( "(%0t)(%m)MIIM - op-code for WRITING to registers", $time);
                       $display( "(%0t)(%m)MIIM - op-code for WRITING to registers", $time);
`endif
`endif
                    end
                    end
                  else
                  else
                    begin
                    begin
                       // ERROR - wrong opcode !
                       // ERROR - wrong opcode !
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
                       #1 $display( "*E (%0t)(%m)MIIM - wrong OP-CODE", $time);
                       #1 $display( "*E (%0t)(%m)MIIM - wrong OP-CODE", $time);
`endif
`endif
                       #10 $stop;
                       #10 $stop;
                    end
                    end
                  // set the signal - get PHY address
                  // set the signal - get PHY address
                  begin
                  begin
                     #1 md_get_phy_address = 1'b1;
                     #1 md_get_phy_address = 1'b1;
                  end
                  end
               end
               end
 
 
             // reset the signal - get PHY address
             // reset the signal - get PHY address
             else if (md_transfer_cnt == 41)
             else if (md_transfer_cnt == 41)
               begin
               begin
                  #4 md_get_phy_address = 1'b0;
                  #4 md_get_phy_address = 1'b0;
                  // set the signal - get register address
                  // set the signal - get register address
                  #1 md_get_reg_address = 1'b1;
                  #1 md_get_reg_address = 1'b1;
               end
               end
 
 
             // reset the signal - get register address
             // reset the signal - get register address
             // set the signal - put register data to output register
             // set the signal - put register data to output register
             else if (md_transfer_cnt == 46)
             else if (md_transfer_cnt == 46)
               begin
               begin
                  #4 md_get_reg_address = 1'b0;
                  #4 md_get_reg_address = 1'b0;
                  #1 md_put_reg_data_out = 1'b1;
                  #1 md_put_reg_data_out = 1'b1;
               end
               end
 
 
             // reset the signal - put register data to output register
             // reset the signal - put register data to output register
             // set the signal - enable md_io as output when read
             // set the signal - enable md_io as output when read
             else if (md_transfer_cnt == 47)
             else if (md_transfer_cnt == 47)
               begin
               begin
                  #4 md_put_reg_data_out = 1'b0;
                  #4 md_put_reg_data_out = 1'b0;
                  if (md_io_rd_wr) //read
                  if (md_io_rd_wr) //read
                    begin
                    begin
                       if (md_io_reg !== 1'bz)
                       if (md_io_reg !== 1'bz)
                         begin
                         begin
                            // ERROR - turn around !
                            // ERROR - turn around !
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
                            #1 $display( "*E (%0t)(%m)MIIM - wrong turn-around cycle before reading data out", $time);
                            #1 $display( "*E (%0t)(%m)MIIM - wrong turn-around cycle before reading data out", $time);
`endif
`endif
                            #10 $stop;
                            #10 $stop;
                         end
                         end
                       if ((phy_address === `ETH_PHY_ADDR) || respond_to_all_phy_addr) // check the PHY address
                       if ((phy_address === `ETH_PHY_ADDR) || respond_to_all_phy_addr) // check the PHY address
                         begin
                         begin
                            #1 md_io_enable = 1'b1;
                            #1 md_io_enable = 1'b1;
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
                            $display( "(%0t)(%m)MIIM - received correct PHY ADDRESS: %x", $time, phy_address);
                            $display( "(%0t)(%m)MIIM - received correct PHY ADDRESS: %x", $time, phy_address);
`endif
`endif
                         end
                         end
                       else
                       else
                         begin
                         begin
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
                            #1 $display( "*W (%0t)(%m)MIIM - received different PHY ADDRESS: %x", $time, phy_address);
                            #1 $display( "*W (%0t)(%m)MIIM - received different PHY ADDRESS: %x", $time, phy_address);
`endif
`endif
                         end
                         end
                    end
                    end
                  else // write
                  else // write
                    begin
                    begin
                       #1 md_io_enable = 1'b0;
                       #1 md_io_enable = 1'b0;
                       // check turn around cycle when write on clock 47
                       // check turn around cycle when write on clock 47
                       if (md_io_reg !== 1'b1)
                       if (md_io_reg !== 1'b1)
                         begin
                         begin
                            // ERROR - turn around !
                            // ERROR - turn around !
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
                            #1 $display( "*E (%0t)(%m)MIIM - wrong 1. turn-around cycle before writing data in",
                            #1 $display( "*E (%0t)(%m)MIIM - wrong 1. turn-around cycle before writing data in",
                                         $time);
                                         $time);
`endif
`endif
                            #10 $stop;
                            #10 $stop;
                         end
                         end
                    end
                    end
               end
               end
 
 
             // set the signal - get register data in when write
             // set the signal - get register data in when write
             else if (md_transfer_cnt == 48)
             else if (md_transfer_cnt == 48)
               begin
               begin
                  #4;
                  #4;
                  if (!md_io_rd_wr) // write
                  if (!md_io_rd_wr) // write
                    begin
                    begin
                       #1 md_get_reg_data_in = 1'b1;
                       #1 md_get_reg_data_in = 1'b1;
                       // check turn around cycle when write on clock 48
                       // check turn around cycle when write on clock 48
                       if (md_io_reg !== 1'b0)
                       if (md_io_reg !== 1'b0)
                         begin
                         begin
                            // ERROR - turn around !
                            // ERROR - turn around !
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
                            #1 $display( "*E (%0t)(%m)MIIM - wrong 2. turn-around cycle before writing data in",
                            #1 $display( "*E (%0t)(%m)MIIM - wrong 2. turn-around cycle before writing data in",
                                         $time);
                                         $time);
`endif
`endif
                            #10 $stop;
                            #10 $stop;
                         end
                         end
                    end
                    end
                  else // read
                  else // read
                    begin
                    begin
                       #1 md_get_reg_data_in = 1'b0;
                       #1 md_get_reg_data_in = 1'b0;
                    end
                    end
               end
               end
 
 
             // reset the signal - enable md_io as output when read
             // reset the signal - enable md_io as output when read
             // reset the signal - get register data in when write
             // reset the signal - get register data in when write
             // set the signal - put registered data in the register when write
             // set the signal - put registered data in the register when write
             else if (md_transfer_cnt == 64)
             else if (md_transfer_cnt == 64)
               begin
               begin
                  #1 md_io_enable = 1'b0;
                  #1 md_io_enable = 1'b0;
                  #4 md_get_reg_data_in = 1'b0;
                  #4 md_get_reg_data_in = 1'b0;
                  if (!md_io_rd_wr) // write
                  if (!md_io_rd_wr) // write
                    begin
                    begin
                       if ((phy_address === `ETH_PHY_ADDR) || respond_to_all_phy_addr) // check the PHY address
                       if ((phy_address === `ETH_PHY_ADDR) || respond_to_all_phy_addr) // check the PHY address
                         begin
                         begin
                            #1 md_put_reg_data_in = 1'b1;
                            #1 md_put_reg_data_in = 1'b1;
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
                            $display( "(%0t)(%m)MIIM - received correct PHY ADDRESS: %x", $time, phy_address);
                            $display( "(%0t)(%m)MIIM - received correct PHY ADDRESS: %x", $time, phy_address);
                            $display( "(%0t)(%m)MIIM - WRITING to register %x COMPLETED!", $time, reg_address);
                            $display( "(%0t)(%m)MIIM - WRITING to register %x COMPLETED!", $time, reg_address);
`endif
`endif
                         end
                         end
                       else
                       else
                         begin
                         begin
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
                            #1 $display( "*W (%0t)(%m)MIIM - received different PHY ADDRESS: %x", $time, phy_address);
                            #1 $display( "*W (%0t)(%m)MIIM - received different PHY ADDRESS: %x", $time, phy_address);
                            $display( "*W (%0t)(%m)MIIM - NO WRITING to register %x !", $time, reg_address);
                            $display( "*W (%0t)(%m)MIIM - NO WRITING to register %x !", $time, reg_address);
`endif
`endif
                         end
                         end
                    end
                    end
                  else // read
                  else // read
                    begin
                    begin
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
                       if ((phy_address === `ETH_PHY_ADDR) || respond_to_all_phy_addr) // check the PHY address
                       if ((phy_address === `ETH_PHY_ADDR) || respond_to_all_phy_addr) // check the PHY address
                         #1 $display( "(%0t)(%m)MIIM - READING from register %x COMPLETED!",
                         #1 $display( "(%0t)(%m)MIIM - READING from register %x COMPLETED!",
                                      $time, reg_address);
                                      $time, reg_address);
                       else
                       else
                         #1 $display( "*W (%0t)(%m)MIIM - NO READING from register %x !", $time, reg_address);
                         #1 $display( "*W (%0t)(%m)MIIM - NO READING from register %x !", $time, reg_address);
`endif
`endif
                    end
                    end
               end
               end
 
 
             // wait for one clock period
             // wait for one clock period
             @(posedge mdc_i)
             @(posedge mdc_i)
               #1;
               #1;
          end
          end
     end
     end
 
 
   //====================================================================
   //====================================================================
   //
   //
   // PHY management (MIIM) REGISTERS
   // PHY management (MIIM) REGISTERS
   //
   //
   //====================================================================
   //====================================================================
   //
   //
   //   Supported registers (normal operation):
   //   Supported registers (normal operation):
   //
   //
   // Addr | Register Name 
   // Addr | Register Name 
   //--------------------------------------------------------------------
   //--------------------------------------------------------------------
   //   0  | Control reg.  
   //   0  | Control reg.  
   //   1  | Status reg. #1 
   //   1  | Status reg. #1 
   //   2  | PHY ID reg. 1 
   //   2  | PHY ID reg. 1 
   //   3  | PHY ID reg. 2 
   //   3  | PHY ID reg. 2 
   //----------------------
   //----------------------
   // Addr | Data MEMORY      |-->  for testing
   // Addr | Data MEMORY      |-->  for testing
   //
   //
   //--------------------------------------------------------------------
   //--------------------------------------------------------------------
   //
   //
   // Control register
   // Control register
   //  reg            control_bit15; // self clearing bit
   //  reg            control_bit15; // self clearing bit
   //  reg    [14:10] control_bit14_10;
   //  reg    [14:10] control_bit14_10;
   //  reg            control_bit9; // self clearing bit
   //  reg            control_bit9; // self clearing bit
   //  reg    [8:0]   control_bit8_0;
   //  reg    [8:0]   control_bit8_0;
   // Status register
   // Status register
   //  wire   [15:9]  status_bit15_9 = `SUPPORTED_SPEED_AND_PORT;
   //  wire   [15:9]  status_bit15_9 = `SUPPORTED_SPEED_AND_PORT;
   //  wire           status_bit8    = `EXTENDED_STATUS;
   //  wire           status_bit8    = `EXTENDED_STATUS;
   //  wire           status_bit7    = 1'b0; // reserved
   //  wire           status_bit7    = 1'b0; // reserved
   //  reg    [6:0]   status_bit6_0  = `DEFAULT_STATUS;
   //  reg    [6:0]   status_bit6_0  = `DEFAULT_STATUS;
   // PHY ID register 1
   // PHY ID register 1
   //  wire   [15:0]  phy_id1        = `PHY_ID1;
   //  wire   [15:0]  phy_id1        = `PHY_ID1;
   // PHY ID register 2
   // PHY ID register 2
   //  wire   [15:0]  phy_id2        = {`PHY_ID2, `MAN_MODEL_NUM, `MAN_REVISION_NUM};
   //  wire   [15:0]  phy_id2        = {`PHY_ID2, `MAN_MODEL_NUM, `MAN_REVISION_NUM};
   //--------------------------------------------------------------------
   //--------------------------------------------------------------------
   //
   //
   // Data MEMORY
   // Data MEMORY
   //  reg    [15:0]  data_mem [0:31]; // 32 locations of 16-bit data width
   //  reg    [15:0]  data_mem [0:31]; // 32 locations of 16-bit data width
   //
   //
   //====================================================================
   //====================================================================
 
 
   //////////////////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////////////////
   //
   //
   // PHY management (MIIM) REGISTER control
   // PHY management (MIIM) REGISTER control
   //
   //
   //////////////////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////////////////
 
 
   // wholy writable registers for walking ONE's on data, phy and reg. addresses
   // wholy writable registers for walking ONE's on data, phy and reg. addresses
   reg     registers_addr_data_test_operation;
   reg     registers_addr_data_test_operation;
 
 
   // Non writable status registers
   // Non writable status registers
   initial // always
   initial // always
     begin
     begin
        #1 status_bit6_0[6] = no_preamble;
        #1 status_bit6_0[6] = no_preamble;
        status_bit6_0[5] = 1'b0;
        status_bit6_0[5] = 1'b0;
        status_bit6_0[3] = 1'b1;
        status_bit6_0[3] = 1'b1;
        status_bit6_0[0] = 1'b1;
        status_bit6_0[0] = 1'b1;
     end
     end
   always@(posedge mrx_clk_o)
   always@(posedge mrx_clk_o)
     begin
     begin
        status_bit6_0[4] <= #1 1'b0;
        status_bit6_0[4] <= #1 1'b0;
        status_bit6_0[1] <= #1 1'b0;
        status_bit6_0[1] <= #1 1'b0;
     end
     end
   initial
   initial
     begin
     begin
        status_bit6_0[2] = 1'b1;
        status_bit6_0[2] = 1'b1;
        registers_addr_data_test_operation = 0;
        registers_addr_data_test_operation = 0;
     end
     end
 
 
   // Reading from a selected registers
   // Reading from a selected registers
   always@(reg_address or registers_addr_data_test_operation or md_put_reg_data_out or
   always@(reg_address or registers_addr_data_test_operation or md_put_reg_data_out or
           control_bit15 or control_bit14_10 or control_bit9 or control_bit8_0 or
           control_bit15 or control_bit14_10 or control_bit9 or control_bit8_0 or
           status_bit15_9 or status_bit8 or status_bit7 or status_bit6_0 or
           status_bit15_9 or status_bit8 or status_bit7 or status_bit6_0 or
           phy_id1 or phy_id2)
           phy_id1 or phy_id2)
     begin
     begin
        if (registers_addr_data_test_operation) // test operation
        if (registers_addr_data_test_operation) // test operation
          begin
          begin
             if (md_put_reg_data_out) // read enable
             if (md_put_reg_data_out) // read enable
               begin
               begin
                  register_bus_out = #1 data_mem[reg_address];
                  register_bus_out = #1 data_mem[reg_address];
               end
               end
          end
          end
        else // normal operation
        else // normal operation
          begin
          begin
             if (md_put_reg_data_out) // read enable
             if (md_put_reg_data_out) // read enable
               begin
               begin
                  case (reg_address)
                  case (reg_address)
                    5'h0:    register_bus_out = #1 {control_bit15, control_bit14_10, control_bit9, control_bit8_0};
                    5'h0:    register_bus_out = #1 {control_bit15, control_bit14_10, control_bit9, control_bit8_0};
                    5'h1:    register_bus_out = #1 {status_bit15_9, status_bit8, status_bit7, status_bit6_0};
                    5'h1:    register_bus_out = #1 {status_bit15_9, status_bit8, status_bit7, status_bit6_0};
                    5'h2:    register_bus_out = #1 phy_id1;
                    5'h2:    register_bus_out = #1 phy_id1;
                    5'h3:    register_bus_out = #1 phy_id2;
                    5'h3:    register_bus_out = #1 phy_id2;
                    default: register_bus_out = #1 16'hDEAD;
                    default: register_bus_out = #1 16'hDEAD;
                  endcase
                  endcase
               end
               end
          end
          end
     end
     end
 
 
   // Self clear control signals
   // Self clear control signals
   reg    self_clear_d0;
   reg    self_clear_d0;
   reg    self_clear_d1;
   reg    self_clear_d1;
   reg    self_clear_d2;
   reg    self_clear_d2;
   reg    self_clear_d3;
   reg    self_clear_d3;
   // Self clearing control
   // Self clearing control
   always@(posedge mdc_i or negedge m_rst_n_i)
   always@(posedge mdc_i or negedge m_rst_n_i)
     begin
     begin
        if (!m_rst_n_i)
        if (!m_rst_n_i)
          begin
          begin
             self_clear_d0    <= #1 0;
             self_clear_d0    <= #1 0;
             self_clear_d1    <= #1 0;
             self_clear_d1    <= #1 0;
             self_clear_d2    <= #1 0;
             self_clear_d2    <= #1 0;
             self_clear_d3    <= #1 0;
             self_clear_d3    <= #1 0;
          end
          end
        else
        else
          begin
          begin
             self_clear_d0    <= #1 md_put_reg_data_in;
             self_clear_d0    <= #1 md_put_reg_data_in;
             self_clear_d1    <= #1 self_clear_d0;
             self_clear_d1    <= #1 self_clear_d0;
             self_clear_d2    <= #1 self_clear_d1;
             self_clear_d2    <= #1 self_clear_d1;
             self_clear_d3    <= #1 self_clear_d2;
             self_clear_d3    <= #1 self_clear_d2;
          end
          end
     end
     end
 
 
   // Writing to a selected register
   // Writing to a selected register
   always@(posedge mdc_i or negedge m_rst_n_i)
   always@(posedge mdc_i or negedge m_rst_n_i)
     begin
     begin
        if ((!m_rst_n_i) || (control_bit15))
        if ((!m_rst_n_i) || (control_bit15))
          begin
          begin
             if (!registers_addr_data_test_operation) // normal operation
             if (!registers_addr_data_test_operation) // normal operation
               begin
               begin
                  control_bit15    <= #1 0;
                  control_bit15    <= #1 0;
                  control_bit14_10 <= #1 {1'b0, (`LED_CFG1 || `LED_CFG2), `LED_CFG1, 2'b0};
                  control_bit14_10 <= #1 {1'b0, (`LED_CFG1 || `LED_CFG2), `LED_CFG1, 2'b0};
                  control_bit9     <= #1 0;
                  control_bit9     <= #1 0;
                  control_bit8_0   <= #1 {`LED_CFG3, 8'b0};
                  control_bit8_0   <= #1 {`LED_CFG3, 8'b0};
               end
               end
          end
          end
        else
        else
          begin
          begin
             if (registers_addr_data_test_operation) // test operation
             if (registers_addr_data_test_operation) // test operation
               begin
               begin
                  if (md_put_reg_data_in)
                  if (md_put_reg_data_in)
                    begin
                    begin
                       data_mem[reg_address] <= #1 register_bus_in[15:0];
                       data_mem[reg_address] <= #1 register_bus_in[15:0];
                    end
                    end
               end
               end
             else // normal operation
             else // normal operation
               begin
               begin
                  // bits that are normaly written
                  // bits that are normaly written
                  if (md_put_reg_data_in)
                  if (md_put_reg_data_in)
                    begin
                    begin
                       case (reg_address)
                       case (reg_address)
                         5'h0:
                         5'h0:
                           begin
                           begin
                              control_bit14_10 <= #1 register_bus_in[14:10];
                              control_bit14_10 <= #1 register_bus_in[14:10];
                              control_bit8_0   <= #1 register_bus_in[8:0];
                              control_bit8_0   <= #1 register_bus_in[8:0];
                           end
                           end
                         default:
                         default:
                           begin
                           begin
                           end
                           end
                       endcase
                       endcase
                    end
                    end
                  // self cleared bits written
                  // self cleared bits written
                  if ((md_put_reg_data_in) && (reg_address == 5'h0))
                  if ((md_put_reg_data_in) && (reg_address == 5'h0))
                    begin
                    begin
                       control_bit15 <= #1 register_bus_in[15];
                       control_bit15 <= #1 register_bus_in[15];
                       control_bit9  <= #1 register_bus_in[9];
                       control_bit9  <= #1 register_bus_in[9];
                    end
                    end
                  else if (self_clear_d3) // self cleared bits cleared
                  else if (self_clear_d3) // self cleared bits cleared
                    begin
                    begin
                       control_bit15 <= #1 1'b0;
                       control_bit15 <= #1 1'b0;
                       control_bit9  <= #1 1'b0;
                       control_bit9  <= #1 1'b0;
                    end
                    end
               end
               end
          end
          end
     end
     end
 
 
   //////////////////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////////////////
         //
         //
   // PHY <-> MAC control (RX and TX clocks are at the begining)
   // PHY <-> MAC control (RX and TX clocks are at the begining)
   //
   //
   //////////////////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////////////////
 
 
   // CARRIER SENSE & COLLISION
   // CARRIER SENSE & COLLISION
 
 
   // MAC common signals
   // MAC common signals
   reg             mcoll_o;
   reg             mcoll_o;
   reg             mcrs_o;
   reg             mcrs_o;
   // Internal signals controling Carrier sense & Collision
   // Internal signals controling Carrier sense & Collision
   // MAC common signals generated when appropriate transfer
   // MAC common signals generated when appropriate transfer
   reg             mcrs_rx;
   reg             mcrs_rx;
   reg             mcrs_tx;
   reg             mcrs_tx;
   // delayed mtxen_i signal for generating delayed tx carrier sense
   // delayed mtxen_i signal for generating delayed tx carrier sense
   reg             mtxen_d1;
   reg             mtxen_d1;
   reg             mtxen_d2;
   reg             mtxen_d2;
   reg             mtxen_d3;
   reg             mtxen_d3;
   reg             mtxen_d4;
   reg             mtxen_d4;
   reg             mtxen_d5;
   reg             mtxen_d5;
   reg             mtxen_d6;
   reg             mtxen_d6;
   // collision signal set or rest within task for controling collision
   // collision signal set or rest within task for controling collision
   reg             task_mcoll;
   reg             task_mcoll;
   // carrier sense signal set or rest within task for controling carrier sense
   // carrier sense signal set or rest within task for controling carrier sense
   reg             task_mcrs;
   reg             task_mcrs;
   reg             task_mcrs_lost;
   reg             task_mcrs_lost;
   // do not generate collision in half duplex - not normal operation
   // do not generate collision in half duplex - not normal operation
   reg             no_collision_in_half_duplex;
   reg             no_collision_in_half_duplex;
   // generate collision in full-duplex mode also - not normal operation
   // generate collision in full-duplex mode also - not normal operation
   reg             collision_in_full_duplex;
   reg             collision_in_full_duplex;
   // do not generate carrier sense in half duplex mode - not normal operation
   // do not generate carrier sense in half duplex mode - not normal operation
   reg             no_carrier_sense_in_tx_half_duplex;
   reg             no_carrier_sense_in_tx_half_duplex;
   reg             no_carrier_sense_in_rx_half_duplex;
   reg             no_carrier_sense_in_rx_half_duplex;
   // generate carrier sense during TX in full-duplex mode also - not normal operation
   // generate carrier sense during TX in full-duplex mode also - not normal operation
   reg             carrier_sense_in_tx_full_duplex;
   reg             carrier_sense_in_tx_full_duplex;
   // do not generate carrier sense during RX in full-duplex mode - not normal operation
   // do not generate carrier sense during RX in full-duplex mode - not normal operation
   reg             no_carrier_sense_in_rx_full_duplex;
   reg             no_carrier_sense_in_rx_full_duplex;
   // on RX: delay after carrier sense signal; on TX: carrier sense delayed (delay is one clock period)
   // on RX: delay after carrier sense signal; on TX: carrier sense delayed (delay is one clock period)
   reg             real_carrier_sense;
   reg             real_carrier_sense;
 
 
   initial
   initial
     begin
     begin
        mcrs_rx = 0;
        mcrs_rx = 0;
        mcrs_tx = 0;
        mcrs_tx = 0;
        task_mcoll = 0;
        task_mcoll = 0;
        task_mcrs = 0;
        task_mcrs = 0;
        task_mcrs_lost = 0;
        task_mcrs_lost = 0;
        no_collision_in_half_duplex = 0;
        no_collision_in_half_duplex = 0;
        collision_in_full_duplex = 0;
        collision_in_full_duplex = 0;
        no_carrier_sense_in_tx_half_duplex = 0;
        no_carrier_sense_in_tx_half_duplex = 0;
        no_carrier_sense_in_rx_half_duplex = 0;
        no_carrier_sense_in_rx_half_duplex = 0;
        carrier_sense_in_tx_full_duplex = 0;
        carrier_sense_in_tx_full_duplex = 0;
        no_carrier_sense_in_rx_full_duplex = 0;
        no_carrier_sense_in_rx_full_duplex = 0;
        real_carrier_sense = 0;
        real_carrier_sense = 0;
     end
     end
 
 
   // Collision
   // Collision
   always@(m_rst_n_i or control_bit8_0 or collision_in_full_duplex or
   always@(m_rst_n_i or control_bit8_0 or collision_in_full_duplex or
           mcrs_rx or mcrs_tx or task_mcoll or no_collision_in_half_duplex
           mcrs_rx or mcrs_tx or task_mcoll or no_collision_in_half_duplex
           )
           )
     begin
     begin
        if (!m_rst_n_i)
        if (!m_rst_n_i)
          mcoll_o = 0;
          mcoll_o = 0;
        else
        else
          begin
          begin
             if (control_bit8_0[8]) // full duplex
             if (control_bit8_0[8]) // full duplex
               begin
               begin
                  if (collision_in_full_duplex) // collision is usually not asserted in full duplex
                  if (collision_in_full_duplex) // collision is usually not asserted in full duplex
                    begin
                    begin
                       mcoll_o = ((mcrs_rx && mcrs_tx) || task_mcoll);
                       mcoll_o = ((mcrs_rx && mcrs_tx) || task_mcoll);
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
                       if (mcrs_rx && mcrs_tx)
                       if (mcrs_rx && mcrs_tx)
                         $display( "(%0t)(%m) Collision set in FullDuplex!", $time);
                         $display( "(%0t)(%m) Collision set in FullDuplex!", $time);
                       if (task_mcoll)
                       if (task_mcoll)
                         $display( "(%0t)(%m) Collision set in FullDuplex from TASK!", $time);
                         $display( "(%0t)(%m) Collision set in FullDuplex from TASK!", $time);
`endif
`endif
                    end
                    end
                  else
                  else
                    begin
                    begin
                       mcoll_o = task_mcoll;
                       mcoll_o = task_mcoll;
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
                       if (task_mcoll)
                       if (task_mcoll)
                         $display( "(%0t)(%m) Collision set in FullDuplex from TASK!", $time);
                         $display( "(%0t)(%m) Collision set in FullDuplex from TASK!", $time);
`endif
`endif
                    end
                    end
               end
               end
             else // half duplex
             else // half duplex
               begin
               begin
                  mcoll_o = ((mcrs_rx && mcrs_tx && !no_collision_in_half_duplex) ||
                  mcoll_o = ((mcrs_rx && mcrs_tx && !no_collision_in_half_duplex) ||
                             task_mcoll);
                             task_mcoll);
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
                  if (mcrs_rx && mcrs_tx)
                  if (mcrs_rx && mcrs_tx)
                    $display( "(%0t)(%m) Collision set in HalfDuplex!", $time);
                    $display( "(%0t)(%m) Collision set in HalfDuplex!", $time);
                  if (task_mcoll)
                  if (task_mcoll)
                    $display( "(%0t)(%m) Collision set in HalfDuplex from TASK!", $time);
                    $display( "(%0t)(%m) Collision set in HalfDuplex from TASK!", $time);
`endif
`endif
               end
               end
          end
          end
     end
     end
 
 
   // Carrier sense
   // Carrier sense
   always@(m_rst_n_i or control_bit8_0 or carrier_sense_in_tx_full_duplex or
   always@(m_rst_n_i or control_bit8_0 or carrier_sense_in_tx_full_duplex or
           no_carrier_sense_in_rx_full_duplex or
           no_carrier_sense_in_rx_full_duplex or
           no_carrier_sense_in_tx_half_duplex or
           no_carrier_sense_in_tx_half_duplex or
           no_carrier_sense_in_rx_half_duplex or
           no_carrier_sense_in_rx_half_duplex or
           mcrs_rx or mcrs_tx or task_mcrs or task_mcrs_lost
           mcrs_rx or mcrs_tx or task_mcrs or task_mcrs_lost
           )
           )
     begin
     begin
        if (!m_rst_n_i)
        if (!m_rst_n_i)
          mcrs_o = 0;
          mcrs_o = 0;
        else
        else
          begin
          begin
             if (control_bit8_0[8]) // full duplex
             if (control_bit8_0[8]) // full duplex
               begin
               begin
                  if (carrier_sense_in_tx_full_duplex) // carrier sense is usually not asserted during TX in full duplex
                  if (carrier_sense_in_tx_full_duplex) // carrier sense is usually not asserted during TX in full duplex
                    mcrs_o = ((mcrs_rx && !no_carrier_sense_in_rx_full_duplex) ||
                    mcrs_o = ((mcrs_rx && !no_carrier_sense_in_rx_full_duplex) ||
                              mcrs_tx || task_mcrs) && !task_mcrs_lost;
                              mcrs_tx || task_mcrs) && !task_mcrs_lost;
                  else
                  else
                    mcrs_o = ((mcrs_rx && !no_carrier_sense_in_rx_full_duplex) ||
                    mcrs_o = ((mcrs_rx && !no_carrier_sense_in_rx_full_duplex) ||
                              task_mcrs) && !task_mcrs_lost;
                              task_mcrs) && !task_mcrs_lost;
               end
               end
             else // half duplex
             else // half duplex
               begin
               begin
                  mcrs_o = ((mcrs_rx && !no_carrier_sense_in_rx_half_duplex) ||
                  mcrs_o = ((mcrs_rx && !no_carrier_sense_in_rx_half_duplex) ||
                            (mcrs_tx && !no_carrier_sense_in_tx_half_duplex) ||
                            (mcrs_tx && !no_carrier_sense_in_tx_half_duplex) ||
                            task_mcrs) && !task_mcrs_lost;
                            task_mcrs) && !task_mcrs_lost;
               end
               end
          end
          end
     end
     end
 
 
   // MAC TX CONTROL (RECEIVING AT PHY)
   // MAC TX CONTROL (RECEIVING AT PHY)
 
 
   // storage memory for TX data received from MAC
   // storage memory for TX data received from MAC
   reg     [7:0]  tx_mem [0:4194303]; // 4194304 locations (22 address lines) of 8-bit data width
   reg     [7:0]  tx_mem [0:4194303]; // 4194304 locations (22 address lines) of 8-bit data width
   reg [31:0]      tx_mem_addr_in; // address for storing to TX memory
   reg [31:0]      tx_mem_addr_in; // address for storing to TX memory
   reg [7:0]       tx_mem_data_in; // data for storing to TX memory
   reg [7:0]       tx_mem_data_in; // data for storing to TX memory
   reg [31:0]      tx_cnt; // counts nibbles
   reg [31:0]      tx_cnt; // counts nibbles
 
 
   // control data of a TX packet for upper layer of testbench
   // control data of a TX packet for upper layer of testbench
   reg            tx_preamble_ok;
   reg            tx_preamble_ok;
   reg            tx_sfd_ok;
   reg            tx_sfd_ok;
   // if there is a drible nibble, then tx packet is not byte aligned!
   // if there is a drible nibble, then tx packet is not byte aligned!
   reg            tx_byte_aligned_ok;
   reg            tx_byte_aligned_ok;
   // complete length of TX packet (Bytes) received (without preamble and SFD)
   // complete length of TX packet (Bytes) received (without preamble and SFD)
   reg [31:0]      tx_len;
   reg [31:0]      tx_len;
   // complete length of TX packet (Bytes) received (without preamble and SFD) untill MTxErr signal was set first
   // complete length of TX packet (Bytes) received (without preamble and SFD) untill MTxErr signal was set first
   reg [31:0]      tx_len_err;
   reg [31:0]      tx_len_err;
 
 
   // TX control
   // TX control
   always@(posedge mtx_clk_o)
   always@(posedge mtx_clk_o)
     begin
     begin
        // storing data and basic checking of frame
        // storing data and basic checking of frame
        if (!m_rst_n_i)
        if (!m_rst_n_i)
          begin
          begin
             tx_cnt <= 0;
             tx_cnt <= 0;
             tx_preamble_ok <= 0;
             tx_preamble_ok <= 0;
             tx_sfd_ok <= 0;
             tx_sfd_ok <= 0;
             tx_len <= 0;
             tx_len <= 0;
             tx_len_err <= 0;
             tx_len_err <= 0;
          end
          end
        else
        else
          begin
          begin
             if (!mtxen_i)
             if (!mtxen_i)
               begin
               begin
                  tx_cnt <= 0;
                  tx_cnt <= 0;
               end
               end
             else
             else
               begin
               begin
                  // tx nibble counter
                  // tx nibble counter
                  tx_cnt <= tx_cnt + 1;
                  tx_cnt <= tx_cnt + 1;
                  // set initial values and check first preamble nibble
                  // set initial values and check first preamble nibble
                  if (tx_cnt == 0)
                  if (tx_cnt == 0)
                    begin
                    begin
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
                       $display( "(%0t)(%m) TX frame started with tx_en set!", $time);
                       $display( "(%0t)(%m) TX frame started with tx_en set!", $time);
`endif
`endif
                       if (mtxd_i == 4'h5)
                       if (mtxd_i == 4'h5)
                         tx_preamble_ok <= 1;
                         tx_preamble_ok <= 1;
                       else
                       else
                         tx_preamble_ok <= 0;
                         tx_preamble_ok <= 0;
                       tx_sfd_ok <= 0;
                       tx_sfd_ok <= 0;
                       tx_byte_aligned_ok <= 0;
                       tx_byte_aligned_ok <= 0;
                       tx_len <= 0;
                       tx_len <= 0;
                       tx_len_err <= 0;
                       tx_len_err <= 0;
                       tx_mem_addr_in <= 0; // RESET this here each packet! 
                       tx_mem_addr_in <= 0; // RESET this here each packet! 
                    end
                    end
 
 
                  // check preamble
                  // check preamble
                  if ((tx_cnt > 0) && (tx_cnt <= 13))
                  if ((tx_cnt > 0) && (tx_cnt <= 13))
                    begin
                    begin
                       if ((tx_preamble_ok != 1) || (mtxd_i != 4'h5))
                       if ((tx_preamble_ok != 1) || (mtxd_i != 4'h5))
                         tx_preamble_ok <= 0;
                         tx_preamble_ok <= 0;
                    end
                    end
                  // check SFD
                  // check SFD
                  if (tx_cnt == 14)
                  if (tx_cnt == 14)
                    begin
                    begin
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
                       if (tx_preamble_ok == 1)
                       if (tx_preamble_ok == 1)
                         $display( "(%0t)(%m) TX frame preamble OK!", $time);
                         $display( "(%0t)(%m) TX frame preamble OK!", $time);
                       else
                       else
                         $display( "*E (%0t)(%m) TX frame preamble NOT OK!", $time);
                         $display( "*E (%0t)(%m) TX frame preamble NOT OK!", $time);
`endif
`endif
                       if (mtxd_i == 4'h5)
                       if (mtxd_i == 4'h5)
                         tx_sfd_ok <= 1;
                         tx_sfd_ok <= 1;
                       else
                       else
                         tx_sfd_ok <= 0;
                         tx_sfd_ok <= 0;
                    end
                    end
                  if (tx_cnt == 15)
                  if (tx_cnt == 15)
                    begin
                    begin
                       if ((tx_sfd_ok != 1) || (mtxd_i != 4'hD))
                       if ((tx_sfd_ok != 1) || (mtxd_i != 4'hD))
                         tx_sfd_ok <= 0;
                         tx_sfd_ok <= 0;
                    end
                    end
 
 
                  // control for storing addresses, type/length, data and FCS to TX memory
                  // control for storing addresses, type/length, data and FCS to TX memory
                  if (tx_cnt > 15)
                  if (tx_cnt > 15)
                    begin
                    begin
                       if (tx_cnt == 16)
                       if (tx_cnt == 16)
                         begin
                         begin
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
                            if (tx_sfd_ok == 1)
                            if (tx_sfd_ok == 1)
                              $display( "(%0t)(%m) TX frame SFD OK!", $time);
                              $display( "(%0t)(%m) TX frame SFD OK!", $time);
                            else
                            else
                              $display( "*E (%0t)(%m) TX frame SFD NOT OK!", $time);
                              $display( "*E (%0t)(%m) TX frame SFD NOT OK!", $time);
`endif
`endif
                         end
                         end
 
 
                       if (tx_cnt[0] == 0)
                       if (tx_cnt[0] == 0)
                         begin
                         begin
                            tx_mem_data_in[3:0] <= mtxd_i; // storing LSB nibble
                            tx_mem_data_in[3:0] <= mtxd_i; // storing LSB nibble
                            tx_byte_aligned_ok <= 0; // if transfer will stop after this, then there was drible nibble
                            tx_byte_aligned_ok <= 0; // if transfer will stop after this, then there was drible nibble
                         end
                         end
                       else
                       else
                         begin
                         begin
                            tx_mem[tx_mem_addr_in[21:0]] <= {mtxd_i, tx_mem_data_in[3:0]}; // storing data into tx memory
                            tx_mem[tx_mem_addr_in[21:0]] <= {mtxd_i, tx_mem_data_in[3:0]}; // storing data into tx memory
                            tx_len <= tx_len + 1; // enlarge byte length counter
                            tx_len <= tx_len + 1; // enlarge byte length counter
                            tx_byte_aligned_ok <= 1; // if transfer will stop after this, then transfer is byte alligned
                            tx_byte_aligned_ok <= 1; // if transfer will stop after this, then transfer is byte alligned
                            tx_mem_addr_in <= tx_mem_addr_in + 1'b1;
                            tx_mem_addr_in <= tx_mem_addr_in + 1'b1;
                         end
                         end
 
 
                       if (mtxerr_i)
                       if (mtxerr_i)
                         tx_len_err <= tx_len;
                         tx_len_err <= tx_len;
                    end
                    end
               end
               end
          end
          end
 
 
        // generating CARRIER SENSE for TX with or without delay
        // generating CARRIER SENSE for TX with or without delay
        if (!m_rst_n_i)
        if (!m_rst_n_i)
          begin
          begin
             mcrs_tx  <= 0;
             mcrs_tx  <= 0;
             mtxen_d1 <= 0;
             mtxen_d1 <= 0;
             mtxen_d2 <= 0;
             mtxen_d2 <= 0;
             mtxen_d3 <= 0;
             mtxen_d3 <= 0;
             mtxen_d4 <= 0;
             mtxen_d4 <= 0;
             mtxen_d5 <= 0;
             mtxen_d5 <= 0;
             mtxen_d6 <= 0;
             mtxen_d6 <= 0;
          end
          end
        else
        else
          begin
          begin
             mtxen_d1 <= mtxen_i;
             mtxen_d1 <= mtxen_i;
             mtxen_d2 <= mtxen_d1;
             mtxen_d2 <= mtxen_d1;
             mtxen_d3 <= mtxen_d2;
             mtxen_d3 <= mtxen_d2;
             mtxen_d4 <= mtxen_d3;
             mtxen_d4 <= mtxen_d3;
             mtxen_d5 <= mtxen_d4;
             mtxen_d5 <= mtxen_d4;
             mtxen_d6 <= mtxen_d5;
             mtxen_d6 <= mtxen_d5;
             if (real_carrier_sense)
             if (real_carrier_sense)
               mcrs_tx  <= mtxen_d6;
               mcrs_tx  <= mtxen_d6;
             else
             else
               mcrs_tx  <= mtxen_i;
               mcrs_tx  <= mtxen_i;
          end
          end
     end
     end
 
 
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
   reg             frame_started;
   reg             frame_started;
 
 
   initial
   initial
     begin
     begin
        frame_started = 0;
        frame_started = 0;
     end
     end
   always@(posedge mtxen_i)
   always@(posedge mtxen_i)
     begin
     begin
        frame_started <= 1;
        frame_started <= 1;
     end
     end
   always@(negedge mtxen_i)
   always@(negedge mtxen_i)
     begin
     begin
        if (frame_started)
        if (frame_started)
          begin
          begin
             $display( "(%0t)(%m) TX frame ended with tx_en reset!", $time);
             $display( "(%0t)(%m) TX frame ended with tx_en reset!", $time);
             frame_started <= 0;
             frame_started <= 0;
          end
          end
     end
     end
 
 
   always@(posedge mrxerr_o)
   always@(posedge mrxerr_o)
     begin
     begin
        $display( "(%0t)(%m) RX frame ERROR signal was set!", $time);
        $display( "(%0t)(%m) RX frame ERROR signal was set!", $time);
     end
     end
`endif
`endif
 
 
   //////////////////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////////////////
   // 
   // 
   // Tasks for PHY <-> MAC transactions
   // Tasks for PHY <-> MAC transactions
   // 
   // 
   //////////////////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////////////////
 
 
   initial
   initial
     begin
     begin
        tx_mem_addr_in = 0;
        tx_mem_addr_in = 0;
     end
     end
 
 
   // setting the address of tx_mem, to set the starting point of tx packet
   // setting the address of tx_mem, to set the starting point of tx packet
   task set_tx_mem_addr;
   task set_tx_mem_addr;
      input [31:0] tx_mem_address;
      input [31:0] tx_mem_address;
      begin
      begin
         #1 tx_mem_addr_in = tx_mem_address;
         #1 tx_mem_addr_in = tx_mem_address;
      end
      end
   endtask // set_tx_mem_addr
   endtask // set_tx_mem_addr
 
 
   // storage memory for RX data to be transmited to MAC
   // storage memory for RX data to be transmited to MAC
   //reg     [7:0]  rx_mem [0:4194303]; // 4194304 locations (22 address lines) of 8-bit data width
   //reg     [7:0]  rx_mem [0:4194303]; // 4194304 locations (22 address lines) of 8-bit data width
   reg     [7:0]  rx_mem [0:2000]; // Legal ethernet packet is 1512, so add a bit more for extras
   reg     [7:0]  rx_mem [0:2000]; // Legal ethernet packet is 1512, so add a bit more for extras
 
 
   // MAC RX signals
   // MAC RX signals
   reg [3:0]       mrxd_o;
   reg [3:0]       mrxd_o;
   reg            mrxdv_o;
   reg            mrxdv_o;
   reg            mrxerr_o;
   reg            mrxerr_o;
 
 
   // SMII signals
   // SMII signals
   reg            smii_rx_go;
   reg            smii_rx_go;
   reg [31:0]      smii_rx_dat_addr;
   reg [31:0]      smii_rx_dat_addr;
   reg [10:1]     smii_rx_frame;
   reg [10:1]     smii_rx_frame;
   reg [10:1]     smii_sync_state;
   reg [10:1]     smii_sync_state;
   reg [31:0]      smii_rx_len;
   reg [31:0]      smii_rx_len;
 
 
`define DEFAULT_SMII_RX_FRAME {3'b101,1'b0,1'b1,1'b1,eth_speed,1'b0,1'b0,1'b0}
`define DEFAULT_SMII_RX_FRAME {3'b101,1'b0,1'b1,1'b1,eth_speed,1'b0,1'b0,1'b0}
 
 
 
 
   initial
   initial
     begin
     begin
        mrxd_o = 0;
        mrxd_o = 0;
        mrxdv_o = 0;
        mrxdv_o = 0;
        mrxerr_o = 0;
        mrxerr_o = 0;
        mcrs_rx = 0;
        mcrs_rx = 0;
        smii_rx_go = 0;
        smii_rx_go = 0;
        #100
        #100
        // For now hardcoded to 100Mbps
        // For now hardcoded to 100Mbps
        smii_rx_frame = `DEFAULT_SMII_RX_FRAME;
        smii_rx_frame = `DEFAULT_SMII_RX_FRAME;
     end
     end
 
 
 
 
   always @(posedge smii_clk_i or negedge m_rst_n_i)
   always @(posedge smii_clk_i or negedge m_rst_n_i)
        if (!m_rst_n_i)
        if (!m_rst_n_i)
       smii_sync_state <= 10'b00000_00000;
       smii_sync_state <= 10'b00000_00000;
     else if (smii_sync_i)
     else if (smii_sync_i)
       smii_sync_state <= 10'b00000_00010;
       smii_sync_state <= 10'b00000_00010;
     else
     else
       smii_sync_state <= {smii_sync_state[9:1], smii_sync_state[10]};
       smii_sync_state <= {smii_sync_state[9:1], smii_sync_state[10]};
 
 
   assign #2 smii_rx_o = |(smii_rx_frame & smii_sync_state);
   assign #2 smii_rx_o = |(smii_rx_frame & smii_sync_state);
 
 
   integer smii_frame_counter;
   integer smii_frame_counter;
 
 
   // Update the SMII frame we'll put out next
   // Update the SMII frame we'll put out next
   task smii_rx_new_frame;
   task smii_rx_new_frame;
      input [10:1] frame;
      input [10:1] frame;
      begin
      begin
         while (~smii_sync_state[10]) // Wait for state before sync to output data
         while (~smii_sync_state[10]) // Wait for state before sync to output data
           @(posedge smii_clk_i);
           @(posedge smii_clk_i);
         #2;
         #2;
 
 
         // Set the frame out
         // Set the frame out
         smii_rx_frame = frame;
         smii_rx_frame = frame;
 
 
         if (eth_speed == 0)
         if (eth_speed == 0)
           begin
           begin
              // is 10Mbps mode, so repeat the frame 10 times
              // is 10Mbps mode, so repeat the frame 10 times
              smii_frame_counter = 0;
              smii_frame_counter = 0;
              while (smii_frame_counter < 10)
              while (smii_frame_counter < 10)
                begin
                begin
                   @(posedge smii_sync_state[10]);
                   @(posedge smii_sync_state[10]);
                   smii_frame_counter  = smii_frame_counter + 1;
                   smii_frame_counter  = smii_frame_counter + 1;
                end
                end
           end
           end
      end
      end
   endtask // smii_rx_new_frame
   endtask // smii_rx_new_frame
 
 
   always @(eth_speed)
   always @(eth_speed)
     // Update frame
     // Update frame
     smii_rx_new_frame(`DEFAULT_SMII_RX_FRAME);
     smii_rx_new_frame(`DEFAULT_SMII_RX_FRAME);
 
 
   integer smii_rx_cnt;
   integer smii_rx_cnt;
 
 
   // SMII RX functions
   // SMII RX functions
   always @(posedge smii_rx_go)
   always @(posedge smii_rx_go)
     begin
     begin
        // SFD
        // SFD
        smii_rx_new_frame({8'h55,2'b10});
        smii_rx_new_frame({8'h55,2'b10});
        smii_rx_new_frame({8'h55,2'b10});
        smii_rx_new_frame({8'h55,2'b10});
        smii_rx_new_frame({8'h55,2'b10});
        smii_rx_new_frame({8'h55,2'b10});
        smii_rx_new_frame({8'h55,2'b10});
        smii_rx_new_frame({8'h55,2'b10});
        smii_rx_new_frame({8'h55,2'b10});
        smii_rx_new_frame({8'h55,2'b10});
        smii_rx_new_frame({8'h55,2'b10});
        smii_rx_new_frame({8'h55,2'b10});
        smii_rx_new_frame({8'h55,2'b10});
        smii_rx_new_frame({8'h55,2'b10});
        smii_rx_new_frame({8'hd5,2'b10});
        smii_rx_new_frame({8'hd5,2'b10});
 
 
        // send packet's addresses, type/length, data and FCS
        // send packet's addresses, type/length, data and FCS
         for (smii_rx_cnt = 0; smii_rx_cnt < smii_rx_len; smii_rx_cnt = smii_rx_cnt + 1)
         for (smii_rx_cnt = 0; smii_rx_cnt < smii_rx_len; smii_rx_cnt = smii_rx_cnt + 1)
           begin
           begin
              smii_rx_new_frame({rx_mem[smii_rx_dat_addr[21:0]],2'b10});
              smii_rx_new_frame({rx_mem[smii_rx_dat_addr[21:0]],2'b10});
              smii_rx_dat_addr = smii_rx_dat_addr + 1;
              smii_rx_dat_addr = smii_rx_dat_addr + 1;
           end
           end
        // Set frame back to original
        // Set frame back to original
        smii_rx_new_frame(`DEFAULT_SMII_RX_FRAME);
        smii_rx_new_frame(`DEFAULT_SMII_RX_FRAME);
 
 
        smii_rx_go = 0;
        smii_rx_go = 0;
 
 
     end
     end
 
 
 
 
   task send_rx_packet;
   task send_rx_packet;
      input  [(8*8)-1:0] preamble_data; // preamble data to be sent - 
      input  [(8*8)-1:0] preamble_data; // preamble data to be sent - 
                                        // correct is 64'h0055_5555_5555_5555
                                        // correct is 64'h0055_5555_5555_5555
      input [3:0]         preamble_len; // length of preamble in bytes - 
      input [3:0]         preamble_len; // length of preamble in bytes - 
                                       // max is 4'h8, correct is 4'h7 
                                       // max is 4'h8, correct is 4'h7 
      input [7:0]         sfd_data; // SFD data to be sent - correct is 8'hD5
      input [7:0]         sfd_data; // SFD data to be sent - correct is 8'hD5
      input [31:0]        start_addr; // start address
      input [31:0]        start_addr; // start address
      input [31:0]        len; // length of frame in Bytes (without preamble
      input [31:0]        len; // length of frame in Bytes (without preamble
                              // and SFD)
                              // and SFD)
      input              plus_drible_nibble; // if length is longer for one 
      input              plus_drible_nibble; // if length is longer for one 
                                             // nibble
                                             // nibble
      input              assert_rx_err; // Set rxerr during transmit
      input              assert_rx_err; // Set rxerr during transmit
      begin
      begin
         smii_rx_dat_addr = start_addr;
         smii_rx_dat_addr = start_addr;
         smii_rx_len = len;
         smii_rx_len = len;
         smii_rx_go = 1;
         smii_rx_go = 1;
 
 
         send_mii_rx_packet(preamble_data, preamble_len, sfd_data, start_addr, len, plus_drible_nibble,
         send_mii_rx_packet(preamble_data, preamble_len, sfd_data, start_addr,
                            assert_rx_err);
                            len, plus_drible_nibble, assert_rx_err);
 
`ifdef SMII0
         while(smii_rx_go)
         while(smii_rx_go)
           @(posedge smii_clk_i);
           @(posedge smii_clk_i);
 
`endif
 
 
      end
      end
   endtask // send_rx_packet
   endtask // send_rx_packet
 
 
   task send_mii_rx_packet;
   task send_mii_rx_packet;
      input  [(8*8)-1:0] preamble_data; // preamble data to be sent - 
      input  [(8*8)-1:0] preamble_data; // preamble data to be sent - 
                                        // correct is 64'h0055_5555_5555_5555
                                        // correct is 64'h0055_5555_5555_5555
      input [3:0]         preamble_len; // length of preamble in bytes - 
      input [3:0]         preamble_len; // length of preamble in bytes - 
                                       // max is 4'h8, correct is 4'h7 
                                       // max is 4'h8, correct is 4'h7 
      input [7:0]         sfd_data; // SFD data to be sent - correct is 8'hD5
      input [7:0]         sfd_data; // SFD data to be sent - correct is 8'hD5
      input [31:0]        start_addr; // start address
      input [31:0]        start_addr; // start address
      input [31:0]        len; // length of frame in Bytes (without preamble
      input [31:0]        len; // length of frame in Bytes (without preamble
                              // and SFD)
                              // and SFD)
      input              plus_drible_nibble; // if length is longer for one 
      input              plus_drible_nibble; // if length is longer for one 
                                             // nibble
                                             // nibble
      input              assert_rx_err; // Set rxerr during transmit
      input              assert_rx_err; // Set rxerr during transmit
 
 
      integer            rx_cnt;
      integer            rx_cnt;
      reg [31:0]          rx_mem_addr_in; // address for reading from RX memory
      reg [31:0]          rx_mem_addr_in; // address for reading from RX memory
      reg [7:0]   rx_mem_data_out; // data for reading from RX memory
      reg [7:0]   rx_mem_data_out; // data for reading from RX memory
      begin
      begin
         @(posedge mrx_clk_o);
         @(posedge mrx_clk_o);
         // generating CARRIER SENSE for TX with or without delay
         // generating CARRIER SENSE for TX with or without delay
         if (real_carrier_sense)
         if (real_carrier_sense)
           #1 mcrs_rx = 1;
           #1 mcrs_rx = 1;
         else
         else
           #1 mcrs_rx = 0;
           #1 mcrs_rx = 0;
         @(posedge mrx_clk_o);
         @(posedge mrx_clk_o);
         #1 mcrs_rx = 1;
         #1 mcrs_rx = 1;
         #1 mrxdv_o = 1;
         #1 mrxdv_o = 1;
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
         $display( "(%0t)(%m) RX frame started with rx_dv set!", $time);
         $display( "(%0t)(%m) RX frame started with rx_dv set!", $time);
`endif
`endif
         // set initial rx memory address
         // set initial rx memory address
         rx_mem_addr_in = start_addr;
         rx_mem_addr_in = start_addr;
 
 
         // send preamble
         // send preamble
         for (rx_cnt = 0; (rx_cnt < (preamble_len << 1)) && (rx_cnt < 16); rx_cnt = rx_cnt + 1)
         for (rx_cnt = 0; (rx_cnt < (preamble_len << 1)) && (rx_cnt < 16);
 
              rx_cnt = rx_cnt + 1)
           begin
           begin
              #1 mrxd_o = preamble_data[3:0];
              #1 mrxd_o = preamble_data[3:0];
              #1 preamble_data = preamble_data >> 4;
              #1 preamble_data = preamble_data >> 4;
              @(posedge mrx_clk_o);
              @(posedge mrx_clk_o);
           end
           end
 
 
         // send SFD
         // send SFD
         for (rx_cnt = 0; rx_cnt < 2; rx_cnt = rx_cnt + 1)
         for (rx_cnt = 0; rx_cnt < 2; rx_cnt = rx_cnt + 1)
           begin
           begin
              #1 mrxd_o = sfd_data[3:0];
              #1 mrxd_o = sfd_data[3:0];
              #1 sfd_data = sfd_data >> 4;
              #1 sfd_data = sfd_data >> 4;
              @(posedge mrx_clk_o);
              @(posedge mrx_clk_o);
           end
           end
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
         $display( "(%0t)(%m) RX frame preamble and SFD sent!", $time);
         $display( "(%0t)(%m) RX frame preamble and SFD sent!", $time);
`endif
`endif
         // send packet's addresses, type/length, data and FCS
         // send packet's addresses, type/length, data and FCS
         for (rx_cnt = 0; rx_cnt < len; rx_cnt = rx_cnt + 1)
         for (rx_cnt = 0; rx_cnt < len; rx_cnt = rx_cnt + 1)
           begin
           begin
              #1;
              #1;
              rx_mem_data_out = rx_mem[rx_mem_addr_in[21:0]];
              rx_mem_data_out = rx_mem[rx_mem_addr_in[21:0]];
              mrxd_o = rx_mem_data_out[3:0];
              mrxd_o = rx_mem_data_out[3:0];
              @(posedge mrx_clk_o);
              @(posedge mrx_clk_o);
              #1;
              #1;
 
 
              // Assert error if told to .... TODO: make this occur at random time
              // Assert error if told to .... TODO: make this occur at random 
              // jb
              //                                    time - JPB
 
 
              if (rx_cnt > 18) rx_err(assert_rx_err);
              if (rx_cnt > 18) rx_err(assert_rx_err);
 
 
              mrxd_o = rx_mem_data_out[7:4];
              mrxd_o = rx_mem_data_out[7:4];
              rx_mem_addr_in = rx_mem_addr_in + 1;
              rx_mem_addr_in = rx_mem_addr_in + 1;
              @(posedge mrx_clk_o);
              @(posedge mrx_clk_o);
              #1;
              #1;
           end
           end
         if (plus_drible_nibble)
         if (plus_drible_nibble)
           begin
           begin
              rx_mem_data_out = rx_mem[rx_mem_addr_in[21:0]];
              rx_mem_data_out = rx_mem[rx_mem_addr_in[21:0]];
              mrxd_o = rx_mem_data_out[3:0];
              mrxd_o = rx_mem_data_out[3:0];
              @(posedge mrx_clk_o);
              @(posedge mrx_clk_o);
           end
           end
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
         $display( "(%0t)(%m) RX frame addresses, type/length, data and FCS sent!", $time);
         $display( "(%0t)(%m) RX frame addresses, type/length, data and FCS sent!", $time);
`endif
`endif
         #1 mcrs_rx = 0;
         #1 mcrs_rx = 0;
         #1 mrxdv_o = 0;
         #1 mrxdv_o = 0;
         @(posedge mrx_clk_o);
         @(posedge mrx_clk_o);
`ifdef ETH_PHY_VERBOSE
`ifdef ETH_PHY_VERBOSE
         $display( "(%0t)(%m) RX frame ended with rx_dv reset!", $time);
         $display( "(%0t)(%m) RX frame ended with rx_dv reset!", $time);
`endif
`endif
      end
      end
   endtask // send_rx_packet
   endtask // send_rx_packet
 
 
 
 
 
 
   task GetDataOnMRxD;
   task GetDataOnMRxD;
      input [15:0] Len;
      input [15:0] Len;
      input [31:0] TransferType;
      input [31:0] TransferType;
      integer      tt;
      integer      tt;
 
 
      begin
      begin
         @ (posedge mrx_clk_o);
         @ (posedge mrx_clk_o);
         #1 mrxdv_o=1'b1;
         #1 mrxdv_o=1'b1;
 
 
         for(tt=0; tt<15; tt=tt+1)
         for(tt=0; tt<15; tt=tt+1)
           begin
           begin
              mrxd_o=4'h5;              // preamble
              mrxd_o=4'h5;              // preamble
              @ (posedge mrx_clk_o);
              @ (posedge mrx_clk_o);
              #1;
              #1;
           end
           end
 
 
         mrxd_o=4'hd;                // SFD
         mrxd_o=4'hd;                // SFD
 
 
         for(tt=1; tt<(Len+1); tt=tt+1)
         for(tt=1; tt<(Len+1); tt=tt+1)
           begin
           begin
              @ (posedge mrx_clk_o);
              @ (posedge mrx_clk_o);
              #1;
              #1;
              if(TransferType == `UNICAST_XFR && tt == 1)
              if(TransferType == `UNICAST_XFR && tt == 1)
                mrxd_o = 4'h0;   // Unicast transfer
                mrxd_o = 4'h0;   // Unicast transfer
              else if(TransferType == `BROADCAST_XFR && tt < 7)
              else if(TransferType == `BROADCAST_XFR && tt < 7)
                mrxd_o = 4'hf;
                mrxd_o = 4'hf;
              else
              else
                mrxd_o = tt[3:0]; // Multicast transfer
                mrxd_o = tt[3:0]; // Multicast transfer
 
 
              @ (posedge mrx_clk_o);
              @ (posedge mrx_clk_o);
              #1;
              #1;
 
 
              if(TransferType == `BROADCAST_XFR && tt == 6)
              if(TransferType == `BROADCAST_XFR && tt == 6)
                mrxd_o = 4'he;
                mrxd_o = 4'he;
              else
              else
 
 
                if(TransferType == `BROADCAST_XFR && tt < 7)
                if(TransferType == `BROADCAST_XFR && tt < 7)
                  mrxd_o = 4'hf;
                  mrxd_o = 4'hf;
                else
                else
                  mrxd_o = tt[7:4];
                  mrxd_o = tt[7:4];
           end
           end
 
 
         @ (posedge mrx_clk_o);
         @ (posedge mrx_clk_o);
         #1;
         #1;
         mrxdv_o = 1'b0;
         mrxdv_o = 1'b0;
      end
      end
   endtask // GetDataOnMRxD
   endtask // GetDataOnMRxD
 
 
 
 
   //////////////////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////////////////
   //
   //
   // Tastks for controling PHY statuses and rx error
   // Tastks for controling PHY statuses and rx error
   //
   //
   //////////////////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////////////////
 
 
   // Link control tasks
   // Link control tasks
   task link_up_down;
   task link_up_down;
      input   test_op;
      input   test_op;
      begin
      begin
         #1 status_bit6_0[2] = test_op; // 1 - link up; 0 - link down
         #1 status_bit6_0[2] = test_op; // 1 - link up; 0 - link down
      end
      end
   endtask
   endtask
 
 
   // RX error
   // RX error
   task rx_err;
   task rx_err;
      input   test_op;
      input   test_op;
      begin
      begin
         #1 mrxerr_o = test_op; // 1 - RX error set; 0 - RX error reset
         #1 mrxerr_o = test_op; // 1 - RX error set; 0 - RX error reset
      end
      end
   endtask
   endtask
 
 
   //////////////////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////////////////
   //
   //
   // Tastks for controling PHY carrier sense and collision
   // Tastks for controling PHY carrier sense and collision
   //
   //
   //////////////////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////////////////
 
 
   // Collision
   // Collision
   task collision;
   task collision;
      input   test_op;
      input   test_op;
      begin
      begin
         #1 task_mcoll = test_op;
         #1 task_mcoll = test_op;
      end
      end
   endtask
   endtask
 
 
   // Carrier sense
   // Carrier sense
   task carrier_sense;
   task carrier_sense;
      input   test_op;
      input   test_op;
      begin
      begin
         #1 task_mcrs = test_op;
         #1 task_mcrs = test_op;
      end
      end
   endtask
   endtask
 
 
   // Carrier sense lost - higher priority than Carrier sense task
   // Carrier sense lost - higher priority than Carrier sense task
   task carrier_sense_lost;
   task carrier_sense_lost;
      input   test_op;
      input   test_op;
      begin
      begin
         #1 task_mcrs_lost = test_op;
         #1 task_mcrs_lost = test_op;
      end
      end
   endtask
   endtask
 
 
   // No collision detection in half duplex
   // No collision detection in half duplex
   task no_collision_hd_detect;
   task no_collision_hd_detect;
      input   test_op;
      input   test_op;
      begin
      begin
         #1 no_collision_in_half_duplex = test_op;
         #1 no_collision_in_half_duplex = test_op;
      end
      end
   endtask
   endtask
 
 
   // Collision detection in full duplex also
   // Collision detection in full duplex also
   task collision_fd_detect;
   task collision_fd_detect;
      input   test_op;
      input   test_op;
      begin
      begin
         #1 collision_in_full_duplex = test_op;
         #1 collision_in_full_duplex = test_op;
      end
      end
   endtask
   endtask
 
 
   // No carrier sense detection at TX in half duplex
   // No carrier sense detection at TX in half duplex
   task no_carrier_sense_tx_hd_detect;
   task no_carrier_sense_tx_hd_detect;
      input   test_op;
      input   test_op;
      begin
      begin
         #1 no_carrier_sense_in_tx_half_duplex = test_op;
         #1 no_carrier_sense_in_tx_half_duplex = test_op;
      end
      end
   endtask
   endtask
 
 
   // No carrier sense detection at RX in half duplex
   // No carrier sense detection at RX in half duplex
   task no_carrier_sense_rx_hd_detect;
   task no_carrier_sense_rx_hd_detect;
      input   test_op;
      input   test_op;
      begin
      begin
         #1 no_carrier_sense_in_rx_half_duplex = test_op;
         #1 no_carrier_sense_in_rx_half_duplex = test_op;
      end
      end
   endtask
   endtask
 
 
   // Carrier sense detection at TX in full duplex also
   // Carrier sense detection at TX in full duplex also
   task carrier_sense_tx_fd_detect;
   task carrier_sense_tx_fd_detect;
      input   test_op;
      input   test_op;
      begin
      begin
         #1 carrier_sense_in_tx_full_duplex = test_op;
         #1 carrier_sense_in_tx_full_duplex = test_op;
      end
      end
   endtask
   endtask
 
 
   // No carrier sense detection at RX in full duplex
   // No carrier sense detection at RX in full duplex
   task no_carrier_sense_rx_fd_detect;
   task no_carrier_sense_rx_fd_detect;
      input   test_op;
      input   test_op;
      begin
      begin
         #1 no_carrier_sense_in_rx_full_duplex = test_op;
         #1 no_carrier_sense_in_rx_full_duplex = test_op;
      end
      end
   endtask
   endtask
 
 
   // Set real delay on carrier sense signal (and therefor collision signal)
   // Set real delay on carrier sense signal (and therefor collision signal)
   task carrier_sense_real_delay;
   task carrier_sense_real_delay;
      input   test_op;
      input   test_op;
      begin
      begin
         #1 real_carrier_sense = test_op;
         #1 real_carrier_sense = test_op;
      end
      end
   endtask
   endtask
 
 
   //////////////////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////////////////
   //
   //
   // Tastks for controling PHY management test operation
   // Tastks for controling PHY management test operation
   //
   //
   //////////////////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////////////////
 
 
   // Set registers to test operation and respond to all phy addresses
   // Set registers to test operation and respond to all phy addresses
   task test_regs;
   task test_regs;
      input   test_op;
      input   test_op;
      begin
      begin
         #1 registers_addr_data_test_operation = test_op;
         #1 registers_addr_data_test_operation = test_op;
         respond_to_all_phy_addr = test_op;
         respond_to_all_phy_addr = test_op;
      end
      end
   endtask
   endtask
 
 
   // Clears data memory for testing the MII
   // Clears data memory for testing the MII
   task clear_test_regs;
   task clear_test_regs;
      integer i;
      integer i;
      begin
      begin
         for (i = 0; i < 32; i = i + 1)
         for (i = 0; i < 32; i = i + 1)
           begin
           begin
              #1 data_mem[i] = 16'h0;
              #1 data_mem[i] = 16'h0;
           end
           end
      end
      end
   endtask
   endtask
 
 
   // Accept frames with preamble suppresed
   // Accept frames with preamble suppresed
   task preamble_suppresed;
   task preamble_suppresed;
      input   test_op;
      input   test_op;
      begin
      begin
         #1 no_preamble = test_op;
         #1 no_preamble = test_op;
         md_transfer_cnt_reset = 1'b1;
         md_transfer_cnt_reset = 1'b1;
         @(posedge mdc_i);
         @(posedge mdc_i);
         #1 md_transfer_cnt_reset = 1'b0;
         #1 md_transfer_cnt_reset = 1'b0;
      end
      end
   endtask
   endtask
 
 
 
 
 
 
   // Sideband signals for external SMII converter --jb
   // Sideband signals for external SMII converter --jb
   assign link_o = status_bit6_0[2];
   assign link_o = status_bit6_0[2];
 
 
   assign speed_o = eth_speed;
   assign speed_o = eth_speed;
 
 
   assign duplex_o = control_bit8_0[8];
   assign duplex_o = control_bit8_0[8];
 
 
 
 
 
 
 
 
endmodule
endmodule
 
 
 
 

powered by: WebSVN 2.1.0

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