⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tb_ethernet.v

📁 < FPGA数字电子系统设计与开发实例导航> 一书的代码
💻 V
📖 第 1 页 / 共 5 页
字号:
            i2 = i2 + 1;
            #Tp;
          end
        end
      join
      if((clk_div[7:0] == 0) || (clk_div[7:0] == 1) || (clk_div[7:0] == 2) || (clk_div[7:0] == 3))
      begin
        if((i1 == i2) && (i1 == 2))
        begin
        end
        else
        begin
          fail = fail + 1;
          test_fail("Clock divider of MII module did'nt divide frequency corectly (it should divide by 2)");
        end
      end
      else
      begin
        if((i1 == i2) && (i1 == {clk_div[7:1], 1'b0}))
        begin
        end
        else
        begin
          fail = fail + 1;
          test_fail("Clock divider of MII module did'nt divide frequency corectly");
        end
      end
    end
    if(fail == 0)
      test_ok;
    else
      fail = 0;
  end
  
  
  ////////////////////////////////////////////////////////////////////
  ////                                                            ////
  ////  Test various readings from 'real' phy registers.          ////
  ////                                                            ////
  ////////////////////////////////////////////////////////////////////
  if (test_num == 1) // Test various readings from 'real' phy registers.
  begin
    // TEST 1: VARIOUS READINGS FROM 'REAL' PHY REGISTERS
    test_name   = "TEST 1: VARIOUS READINGS FROM 'REAL' PHY REGISTERS";
    `TIME; $display("  TEST 1: VARIOUS READINGS FROM 'REAL' PHY REGISTERS");
  
    // set the fastest possible MII
    clk_div = 0;
    mii_set_clk_div(clk_div[7:0]);
    // set address
    reg_addr = 5'h1F;
    phy_addr = 5'h1;
    while(reg_addr >= 5'h4)
    begin
      // read request
      #Tp mii_read_req(phy_addr, reg_addr);
      check_mii_busy; // wait for read to finish
      // read data
      wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
      if (phy_data !== 16'hDEAD)
      begin
        test_fail("Wrong data was read from PHY from 'not used' address space");
        fail = fail + 1;
      end
      if (reg_addr == 5'h4) // go out of for loop
        reg_addr = 5'h3;
      else
        reg_addr = reg_addr - 5'h9;
    end
  
    // set address
    reg_addr = 5'h3;
    // read request
    #Tp mii_read_req(phy_addr, reg_addr);
    check_mii_busy; // wait for read to finish
    // read data
    wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
    if (phy_data !== {`PHY_ID2, `MAN_MODEL_NUM, `MAN_REVISION_NUM})
    begin
      test_fail("Wrong data was read from PHY from ID register 2");
      fail = fail + 1;
    end
    if(fail == 0)
      test_ok;
    else
      fail = 0;
  end


  ////////////////////////////////////////////////////////////////////
  ////                                                            ////
  ////  Test various writings to 'real' phy registers (control    ////
  ////  and non writable registers)                               ////
  ////                                                            ////
  ////////////////////////////////////////////////////////////////////
  if (test_num == 2) // 
  begin
    // TEST 2: VARIOUS WRITINGS TO 'REAL' PHY REGISTERS ( CONTROL AND NON WRITABLE REGISTERS )
    test_name   = "TEST 2: VARIOUS WRITINGS TO 'REAL' PHY REGISTERS ( CONTROL AND NON WRITABLE REGISTERS )";
    `TIME; $display("  TEST 2: VARIOUS WRITINGS TO 'REAL' PHY REGISTERS ( CONTROL AND NON WRITABLE REGISTERS )");
  
    // negate data and try to write into unwritable register
    tmp_data = ~phy_data;
    // write request
    #Tp mii_write_req(phy_addr, reg_addr, tmp_data);
    check_mii_busy; // wait for write to finish
    // read request
    #Tp mii_read_req(phy_addr, reg_addr);
    check_mii_busy; // wait for read to finish
    // read data
    wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
    if (tmp_data !== phy_data)
    begin
      test_fail("Data was written into unwritable PHY register - ID register 2");
      fail = fail + 1;
    end
  
    // set address
    reg_addr = 5'h0; // control register
    // read request
    #Tp mii_read_req(phy_addr, reg_addr);
    check_mii_busy; // wait for read to finish
    // read data
    wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
    // write request
    phy_data = 16'h7DFF; // bit 15 (RESET bit) and bit 9 are self clearing bits
    #Tp mii_write_req(phy_addr, reg_addr, phy_data);
    check_mii_busy; // wait for write to finish
    // read request
    #Tp mii_read_req(phy_addr, reg_addr);
    check_mii_busy; // wait for read to finish
    // read data
    wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
    if (phy_data !== 16'h7DFF)
    begin
      test_fail("Data was not correctly written into OR read from writable PHY register - control register");
      fail = fail + 1;
    end
    // write request
    #Tp mii_write_req(phy_addr, reg_addr, tmp_data);
    check_mii_busy; // wait for write to finish
    // read request
    #Tp mii_read_req(phy_addr, reg_addr);
    check_mii_busy; // wait for read to finish
    // read data
    wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
    if (phy_data !== tmp_data)
    begin
      test_fail("Data was not correctly written into OR read from writable PHY register - control register");
      fail = fail + 1;
    end
    if(fail == 0)
      test_ok;
    else
      fail = 0;
  end


  ////////////////////////////////////////////////////////////////////
  ////                                                            ////
  ////  Test reset phy through mii management module              ////
  ////                                                            ////
  ////////////////////////////////////////////////////////////////////
  if (test_num == 3) // 
  begin
    // TEST 3: RESET PHY THROUGH MII MANAGEMENT MODULE
    test_name   = "TEST 3: RESET PHY THROUGH MII MANAGEMENT MODULE";
    `TIME; $display("  TEST 3: RESET PHY THROUGH MII MANAGEMENT MODULE");
  
    // set address
    reg_addr = 5'h0; // control register
    // write request
    phy_data = 16'h7DFF; // bit 15 (RESET bit) and bit 9 are self clearing bits
    #Tp mii_write_req(phy_addr, reg_addr, phy_data);
    check_mii_busy; // wait for write to finish
    // read request
    #Tp mii_read_req(phy_addr, reg_addr);
    check_mii_busy; // wait for read to finish
    // read data
    wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
    if (phy_data !== tmp_data)
    begin
      test_fail("Data was not correctly written into OR read from writable PHY register - control register");
      fail = fail + 1;
    end
    // set reset bit - selfclearing bit in PHY
    phy_data = phy_data | 16'h8000;
    // write request
    #Tp mii_write_req(phy_addr, reg_addr, phy_data);
    check_mii_busy; // wait for write to finish
    // read request
    #Tp mii_read_req(phy_addr, reg_addr);
    check_mii_busy; // wait for read to finish
    // read data
    wbm_read(`ETH_MIIRX_DATA, tmp_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
    // check self clearing of reset bit
    if (tmp_data[15] !== 1'b0)
    begin
      test_fail("Reset bit should be self cleared - control register");
      fail = fail + 1;
    end
    // check reset value of control register
    if (tmp_data !== {2'h0, (`LED_CFG1 || `LED_CFG2), `LED_CFG1, 3'h0, `LED_CFG3, 8'h0})
    begin
      test_fail("PHY was not reset correctly AND/OR reset bit not self cleared");
      fail = fail + 1;
    end
    if(fail == 0)
      test_ok;
    else
      fail = 0;
  end


  ////////////////////////////////////////////////////////////////////
  ////                                                            ////
  ////  Test 'walking one' across phy address (with and without   ////
  ////  preamble)                                                 ////
  ////                                                            ////
  ////////////////////////////////////////////////////////////////////
  if (test_num == 4) // 
  begin
    // TEST 4: 'WALKING ONE' ACROSS PHY ADDRESS ( WITH AND WITHOUT PREAMBLE )
    test_name   = "TEST 4: 'WALKING ONE' ACROSS PHY ADDRESS ( WITH AND WITHOUT PREAMBLE )";
    `TIME; $display("  TEST 4: 'WALKING ONE' ACROSS PHY ADDRESS ( WITH AND WITHOUT PREAMBLE )");
  
    // set PHY to test mode
    #Tp eth_phy.test_regs(1); // set test registers (wholy writable registers) and respond to all PHY addresses
    for (i = 0; i <= 1; i = i + 1)
    begin
      #Tp eth_phy.preamble_suppresed(i); 
      #Tp eth_phy.clear_test_regs;
      // MII mode register
      wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}), 4'hF, 1, wbm_init_waits, 
                wbm_subseq_waits);
      // walk one across phy address
      for (phy_addr = 5'h1; phy_addr > 5'h0; phy_addr = phy_addr << 1)
      begin
        reg_addr = $random;
        tmp_data = $random;
        // write request
        #Tp mii_write_req(phy_addr, reg_addr, tmp_data);
        check_mii_busy; // wait for write to finish
        // read request
        #Tp mii_read_req(phy_addr, reg_addr);
        check_mii_busy; // wait for read to finish
        // read data
        wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
        #Tp;
        if (phy_data !== tmp_data)
        begin
          if (i)
            test_fail("Data was not correctly written into OR read from test registers (without preamble)");
          else
            test_fail("Data was not correctly written into OR read from test registers (with preamble)");
          fail = fail + 1;
        end
        @(posedge wb_clk);
        #Tp;
      end
    end
    // set PHY to normal mode
    #Tp eth_phy.test_regs(0);
    #Tp eth_phy.preamble_suppresed(0);
    // MII mode register
    wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
    if(fail == 0)
      test_ok;
    else
      fail = 0;
  end


  ////////////////////////////////////////////////////////////////////
  ////                                                            ////
  ////  Test 'walking one' across phy's register address (with    ////
  ////  and without preamble)                                     ////
  ////                                                            ////
  ////////////////////////////////////////////////////////////////////
  if (test_num == 5) // 
  begin
    // TEST 5: 'WALKING ONE' ACROSS PHY'S REGISTER ADDRESS ( WITH AND WITHOUT PREAMBLE )
    test_name   = "TEST 5: 'WALKING ONE' ACROSS PHY'S REGISTER ADDRESS ( WITH AND WITHOUT PREAMBLE )";
    `TIME; $display("  TEST 5: 'WALKING ONE' ACROSS PHY'S REGISTER ADDRESS ( WITH AND WITHOUT PREAMBLE )");
  
    // set PHY to test mode
    #Tp eth_phy.test_regs(1); // set test registers (wholy writable registers) and respond to all PHY addresses
    for (i = 0; i <= 1; i = i + 1)
    begin
      #Tp eth_phy.preamble_suppresed(i);
      #Tp eth_phy.clear_test_regs;
      // MII mode register
      wbm_write(`ETH_MIIMODER, (`ETH_MIIMODER_NOPRE & {23'h0, i, 8'h0}), 4'hF, 1, wbm_init_waits, 
                wbm_subseq_waits);
      // walk one across reg address
      for (reg_addr = 5'h1; reg_addr > 5'h0; reg_addr = reg_addr << 1)
      begin
        phy_addr = $random;
        tmp_data = $random;
        // write request
        #Tp mii_write_req(phy_addr, reg_addr, tmp_data);
        check_mii_busy; // wait for write to finish
        // read request
        #Tp mii_read_req(phy_addr, reg_addr);
        check_mii_busy; // wait for read to finish
        // read data
        wbm_read(`ETH_MIIRX_DATA, phy_data, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
        #Tp;
        if (phy_data !== tmp_data)
        begin
          if (i)
            test_fail("Data was not correctly written into OR read from test registers (without preamble)");
          else
            test_fail("Data was not correctly written into OR read from test registers (with preamble)");
          fail = fail + 1;
        end
        @(posedge wb_clk);
        #Tp;
      end
    end
    // set PHY to normal mode
    #Tp eth_phy.test_regs(0);
    #Tp eth_phy.preamble_suppresed(0);
    // MII mode register
    wbm_write(`ETH_MIIMODER, 32'h0, 4'hF, 1, wbm_init_waits, wbm_subseq_waits);
    if(fail == 0)
      test_ok;
    else
      fail = 0;
  end


  ////////////////////////////////////////////////////////////////////
  ////                                                            ////
  ////  Test 'walking one' across phy's data (with and without    ////
  ////  preamble)                                                 ////
  ////                                                            ////
  ////////////////////////////////////////////////////////////////////
  if (test_num == 6) // 
  begin
    // TEST 6: 'WALKING ONE' ACROSS PHY'S DATA ( WITH AND WITHOUT PREAMBLE )
    test_name   = "TEST 6: 'WALKING ONE' ACROSS PHY'S DATA ( WITH AND WITHOUT PREAMBLE )";
    `TIME; $display("  TEST 6: 'WALKING ONE' ACROSS PHY'S DATA ( WITH AND WITHOUT PREAMBLE )");
  
    // set PHY to test mode
    #Tp e

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -