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

Subversion Repositories mips_enhanced

[/] [mips_enhanced/] [trunk/] [grlib-gpl-1.0.19-b3188/] [lib/] [gaisler/] [sim/] [phy.vhd] - Rev 2

Compare with Previous | Blame | View Log

------------------------------------------------------------------------------
--  This file is a part of the GRLIB VHDL IP LIBRARY
--  Copyright (C) 2003, Gaisler Research
--
--  This program is free software; you can redistribute it and/or modify
--  it under the terms of the GNU General Public License as published by
--  the Free Software Foundation; either version 2 of the License, or
--  (at your option) any later version.
--
--  This program is distributed in the hope that it will be useful,
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--  GNU General Public License for more details.
--
--  You should have received a copy of the GNU General Public License
--  along with this program; if not, write to the Free Software
--  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
----------------------------------------------------------------------------
-- Entity:   	phy
-- File:	phy.vhd
-- Description:	Simulation model of an Ethernet PHY
-- Author:      Marko Isomaki
------------------------------------------------------------------------------
 
-- pragma translate_off
 
library ieee;
library grlib;
 
use ieee.std_logic_1164.all;
use grlib.stdlib.all;
 
entity phy is
  generic(
    address       : integer range 0 to 31 := 0;
    extended_regs : integer range 0 to 1  := 1;
    aneg          : integer range 0 to 1  := 1;
    base100_t4    : integer range 0 to 1  := 0;
    base100_x_fd  : integer range 0 to 1  := 1;
    base100_x_hd  : integer range 0 to 1  := 1;
    fd_10         : integer range 0 to 1  := 1;
    hd_10         : integer range 0 to 1  := 1;
    base100_t2_fd : integer range 0 to 1  := 1;
    base100_t2_hd : integer range 0 to 1  := 1;
    base1000_x_fd : integer range 0 to 1  := 0;
    base1000_x_hd : integer range 0 to 1  := 0;
    base1000_t_fd : integer range 0 to 1  := 1;
    base1000_t_hd : integer range 0 to 1  := 1
    );
  port(
    rstn     : in std_logic;
    mdio     : inout std_logic;
    tx_clk   : out std_logic;
    rx_clk   : out std_logic;
    rxd      : out std_logic_vector(7 downto 0);   
    rx_dv    : out std_logic; 
    rx_er    : out std_logic; 
    rx_col   : out std_logic;
    rx_crs   : out std_logic;
    txd      : in std_logic_vector(7 downto 0);   
    tx_en    : in std_logic; 
    tx_er    : in std_logic; 
    mdc      : in std_logic;
    gtx_clk  : in std_logic
  );
end;
 
architecture behavioral of phy is
  type mdio_state_type is (idle, start_of_frame, start_of_frame2, op, phyad, regad,
    ta, rdata, wdata);
 
  type ctrl_reg_type is record
    reset       : std_ulogic;
    loopback    : std_ulogic;
    speedsel    : std_logic_vector(1 downto 0);
    anegen      : std_ulogic;
    powerdown   : std_ulogic;
    isolate     : std_ulogic;
    restartaneg : std_ulogic;
    duplexmode  : std_ulogic;
    coltest     : std_ulogic;
  end record;
 
  type status_reg_type is record
    base100_t4    : std_ulogic;
    base100_x_fd  : std_ulogic;
    base100_x_hd  : std_ulogic;
    fd_10         : std_ulogic;
    hd_10         : std_ulogic;
    base100_t2_fd : std_ulogic;
    base100_t2_hd : std_ulogic;
    extstat       : std_ulogic;
    mfpreamblesup : std_ulogic;
    anegcmpt      : std_ulogic;
    remfault      : std_ulogic;
    anegability   : std_ulogic;
    linkstat      : std_ulogic;
    jabdetect     : std_ulogic;
    extcap        : std_ulogic;
  end record;
 
  type aneg_ab_type is record
    next_page     : std_ulogic;
    remote_fault  : std_ulogic;
    tech_ability  : std_logic_vector(7 downto 0);
    selector      : std_logic_vector(4 downto 0);
  end record;
 
  type aneg_exp_type is record
    par_detct_flt : std_ulogic;
    lp_np_able    : std_ulogic;
    np_able       : std_ulogic;
    page_rx       : std_ulogic;
    lp_aneg_able  : std_ulogic;
  end record;
 
  type aneg_nextpage_type is record
    next_page     : std_ulogic;
    message_page  : std_ulogic;
    ack2          : std_ulogic;
    toggle        : std_ulogic;
    message       : std_logic_vector(10 downto 0);
  end record;
 
  type mst_slv_ctrl_type is record
    tmode         : std_logic_vector(2 downto 0);
    manualcfgen   : std_ulogic;
    cfgval        : std_ulogic;
    porttype      : std_ulogic;
    base1000_t_fd : std_ulogic;
    base1000_t_hd : std_ulogic;
  end record;
 
  type mst_slv_status_type is record
    cfgfault        : std_ulogic;
    cfgres          : std_ulogic;
    locrxstate      : std_ulogic;
    remrxstate      : std_ulogic;
    lpbase1000_t_fd : std_ulogic;
    lpbase1000_t_hd : std_ulogic;
    idlerrcnt       : std_logic_vector(7 downto 0);
  end record;
 
  type extended_status_reg_type is record
    base1000_x_fd : std_ulogic;
    base1000_x_hd : std_ulogic;
    base1000_t_fd : std_ulogic;
    base1000_t_hd : std_ulogic;
  end record;
 
  type reg_type is record
    state         : mdio_state_type;
    cnt           : integer;
    op            : std_logic_vector(1 downto 0);
    phyad         : std_logic_vector(4 downto 0);
    regad         : std_logic_vector(4 downto 0);
    wr            : std_ulogic;
    regtmp        : std_logic_vector(15 downto 0);
    -- MII management registers
    ctrl          : ctrl_reg_type;
    status        : status_reg_type;
    anegadv       : aneg_ab_type;
    aneglp        : aneg_ab_type;
    anegexp       : aneg_exp_type;
    anegnptx      : aneg_nextpage_type;
    anegnplp      : aneg_nextpage_type;
    mstslvctrl    : mst_slv_ctrl_type;
    mstslvstat    : mst_slv_status_type;
    extstatus     : extended_status_reg_type;
    rstcnt        : integer;
    anegcnt       : integer;
  end record;
 
  signal r, rin   : reg_type;
  signal int_clk  : std_ulogic := '0';
  signal clkslow  : std_ulogic := '0';
  signal rcnt     : integer;
  signal anegact  : std_ulogic;
begin
  --mdio signal pull-up
  int_clk <= not int_clk after 8 ns when r.ctrl.speedsel = "01" else
             not int_clk after 40 ns when r.ctrl.speedsel = "10" else
             not int_clk after 400 ns when r.ctrl.speedsel = "00";
 
  clkslow <= not clkslow after 40 ns when r.ctrl.speedsel = "10" else
             not clkslow after 400 ns;
 
--   rstdelay : process
--   begin
--     loop
--       rstd <= '0';
--       while r.ctrl.reset /= '1' loop
--         wait on r.ctrl.reset;
--       end loop;
--       rstd <= '1';
--       while rstn = '0' loop
--         wait on rstn;
--       end loop;
--       wait on rstn for 3 us;
--       rstd <= '0';
--       wait on rstn until r.ctrl.reset = '0' for 5 us; 
--     end loop;
--   end process;
 
  anegproc : process is
  begin
    loop
      anegact <= '0';
      while rstn /= '1' loop
        wait on rstn;
      end loop;
      while rstn = '1' loop
        if r.ctrl.anegen = '0' then
          anegact <= '0';
          wait on rstn, r.ctrl.anegen, r.ctrl.restartaneg;
        else
          if r.ctrl.restartaneg = '1' then
            anegact <= '1';
            wait on rstn, r.ctrl.restartaneg, r.ctrl.anegen for 2 us;
            anegact <= '0';
            wait on rstn, r.ctrl.anegen until r.ctrl.restartaneg = '0';
            if (rstn and r.ctrl.anegen) = '1' then
              wait on rstn, r.ctrl.anegen, r.ctrl.restartaneg;
            end if;
          else
            anegact <= '0';
            wait on rstn, r.ctrl.restartaneg, r.ctrl.anegen;
          end if;
        end if;
      end loop;
    end loop;
  end process; 
 
  mdiocomb : process(rstn, r, anegact, mdio) is
    variable v : reg_type;
  begin
    v := r; 
    if anegact = '0' then
      v.ctrl.restartaneg := '0';
    end if;
    case r.state is
      when idle =>
        mdio <= 'Z';
        if to_X01(mdio) = '1' then
          v.cnt := v.cnt + 1;
          if v.cnt = 31 then
            v.state := start_of_frame; v.cnt := 0;
          end if;
        else
          v.cnt := 0;
        end if;
      when start_of_frame =>
        if to_X01(mdio) = '0' then
          v.state := start_of_frame2;
        elsif to_X01(mdio) /= '1' then
          v.state := idle;
        end if;
      when start_of_frame2 =>
        if to_X01(mdio) = '1' then
          v.state := op;
        else
          v.state := idle;
        end if;
      when op =>
        v.cnt := v.cnt + 1;
        v.op := r.op(0) & to_X01(mdio);
        if r.cnt = 1 then
          if (v.op = "01") or (v.op = "10") then 
            v.state := phyad; v.cnt := 0;
          else
            v.state := idle; v.cnt := 0;
          end if;
        end if;
      when phyad =>
        v.phyad := r.phyad(3 downto 0) & to_X01(mdio);
        v.cnt := v.cnt + 1;
        if r.cnt = 4 then
          v.state := regad; v.cnt := 0;
        end if;
      when regad =>
        v.regad := r.regad(3 downto 0) & to_X01(mdio);
        v.cnt := v.cnt + 1;
        if r.cnt = 4 then
          v.cnt := 0;
          if conv_integer(r.phyad) = address then
            v.state := ta; 
          else
            v.state := idle;
          end if;
        end if;
      when ta =>
        v.cnt := r.cnt + 1;
        if r.cnt = 0 then
          if (r.op = "01") and to_X01(mdio) /= '1' then
            v.cnt := 0; v.state := idle;
          end if;
        else
          if r.op = "10" then
            mdio <= '0'; v.cnt := 0; v.state := rdata;
            case r.regad is
              when "00000" => --ctrl (basic)
                v.regtmp := r.ctrl.reset & r.ctrl.loopback &
                  r.ctrl.speedsel(1) & r.ctrl.anegen & r.ctrl.powerdown &
                  r.ctrl.isolate & r.ctrl.restartaneg & r.ctrl.duplexmode &
                  r.ctrl.coltest & r.ctrl.speedsel(0) & "000000";
              when "00001" => --statuc (basic)
                v.regtmp := r.status.base100_t4 & r.status.base100_x_fd & 
                  r.status.base100_x_hd & r.status.fd_10 & r.status.hd_10 & 
                  r.status.base100_t2_fd & r.status.base100_t2_hd & 
                  r.status.extstat & '0' & r.status.mfpreamblesup & 
                  r.status.anegcmpt & r.status.remfault & r.status.anegability &
                  r.status.linkstat & r.status.jabdetect & r.status.extcap;
              when "00010" => --PHY ID (extended)
                if extended_regs = 1 then
                  v.regtmp := X"BBCD";
                else
                  v.cnt := 0; v.state := idle; 
                end if;
              when "00011" => --PHY ID (extended)
                if extended_regs = 1 then
                  v.regtmp := X"9C83";
                else
                  v.cnt := 0; v.state := idle; 
                end if;
              when "00100" => --Auto-neg adv. (extended)
                if extended_regs = 1 then
                  v.regtmp := r.anegadv.next_page & '0' & r.anegadv.remote_fault & 
                    r.anegadv.tech_ability & r.anegadv.selector;
                else
                  v.cnt := 0; v.state := idle; 
                end if;
              when "00101" => --Auto-neg link partner ability (extended)
                if extended_regs = 1 then
                  v.regtmp := r.aneglp.next_page & '0' & r.aneglp.remote_fault & 
                    r.aneglp.tech_ability & r.aneglp.selector;
                else
                  v.cnt := 0; v.state := idle; 
                end if;
              when "00110" => --Auto-neg expansion (extended)
                if extended_regs = 1 then
                  v.regtmp := "00000000000" & r.anegexp.par_detct_flt & 
                  r.anegexp.lp_np_able &  r.anegexp.np_able & r.anegexp.page_rx &
                  r.anegexp.lp_aneg_able;
                else
                  v.cnt := 0; v.state := idle; 
                end if;
              when "00111" => --Auto-neg next page (extended)
                if extended_regs = 1 then
                  v.regtmp := r.anegnptx.next_page & '0' & r.anegnptx.message_page &
                  r.anegnptx.ack2 & r.anegnptx.toggle & r.anegnptx.message;
                else
                  v.cnt := 0; v.state := idle; 
                end if;
              when "01000" => --Auto-neg link partner received next page (extended)
                if extended_regs = 1 then
                  v.regtmp := r.anegnplp.next_page & '0' & r.anegnplp.message_page &
                  r.anegnplp.ack2 & r.anegnplp.toggle & r.anegnplp.message;
                else
                  v.cnt := 0; v.state := idle; 
                end if;
              when "01001" => --Master-slave control (extended)
                if extended_regs = 1 then
                  v.regtmp := r.mstslvctrl.tmode & r.mstslvctrl.manualcfgen & 
                  r.mstslvctrl.cfgval & r.mstslvctrl.porttype &
                  r.mstslvctrl.base1000_t_fd &  r.mstslvctrl.base1000_t_hd &
                  "00000000";
                else
                  v.cnt := 0; v.state := idle;
                end if;
              when "01010" => --Master-slave status (extended)
                if extended_regs = 1 then
                  v.regtmp := r.mstslvstat.cfgfault & r.mstslvstat.cfgres &
                  r.mstslvstat.locrxstate & r.mstslvstat.remrxstate & 
                  r.mstslvstat.lpbase1000_t_fd & r.mstslvstat.lpbase1000_t_hd &
                  "00" & r.mstslvstat.idlerrcnt;
                else
                  v.cnt := 0; v.state := idle;
                end if;
              when "01111" =>
                if (base1000_x_fd = 1) or (base1000_x_hd = 1) or
                   (base1000_t_fd = 1) or (base1000_t_hd = 1) then
                  v.regtmp := r.extstatus.base1000_x_fd &
                              r.extstatus.base1000_x_hd &
                              r.extstatus.base1000_t_fd &
                              r.extstatus.base1000_t_hd & X"000";
                else
                  v.regtmp := (others => '0');
                end if;
              when others =>
                --PHY shall not drive MDIO when unimplemented registers
                --are accessed
                v.cnt := 0; v.state := idle;
                v.regtmp := (others => '0');
            end case;
            if r.ctrl.reset = '1' then
              if r.regad = "00000" then
                v.regtmp := X"8000";
              else
                v.regtmp := X"0000";
              end if;
            end if;
          else
            if to_X01(mdio) /= '0'then
              v.cnt := 0; v.state := idle; 
            else
              v.cnt := 0; v.state := wdata;
            end if; 
          end if;
        end if;
      when rdata =>
        v.cnt := r.cnt + 1;
        mdio <= r.regtmp(15-r.cnt);
        if r.cnt = 15 then
          v.state := idle; v.cnt := 0;
        end if;
      when wdata =>
        v.cnt := r.cnt + 1;
        v.regtmp := r.regtmp(14 downto 0) & to_X01(mdio);
        if r.cnt = 15 then
          v.state := idle; v.cnt := 0;
          if r.ctrl.reset = '0' then
            case r.regad is
              when "00000" =>
                v.ctrl.reset := v.regtmp(15);
                v.ctrl.loopback := v.regtmp(14);
                v.ctrl.speedsel(1) := v.regtmp(13);
                v.ctrl.anegen := v.regtmp(12);
                v.ctrl.powerdown := v.regtmp(11);
                v.ctrl.isolate := v.regtmp(10);
                v.ctrl.restartaneg := v.regtmp(9);
                v.ctrl.duplexmode := v.regtmp(8);
                v.ctrl.coltest := v.regtmp(7);
                v.ctrl.speedsel(0) := v.regtmp(6);
              when "00100" =>
                if extended_regs = 1 then
                  v.anegadv.remote_fault := r.regtmp(13);
                  v.anegadv.tech_ability := r.regtmp(12 downto 5);
                  v.anegadv.selector := r.regtmp(4 downto 0);
                end if;
              when "00111" =>
                if extended_regs = 1 then
                  v.anegnptx.next_page     := r.regtmp(15);
                  v.anegnptx.message_page  := r.regtmp(13);
                  v.anegnptx.ack2          := r.regtmp(12);
                  v.anegnptx.message       := r.regtmp(10 downto 0);
                end if;
              when "01001" =>
                if extended_regs = 1 then
                  v.mstslvctrl.tmode         := r.regtmp(15 downto 13);
                  v.mstslvctrl.manualcfgen   := r.regtmp(12);
                  v.mstslvctrl.cfgval        := r.regtmp(11);
                  v.mstslvctrl.porttype      := r.regtmp(10);
                  v.mstslvctrl.base1000_t_fd := r.regtmp(9);
                  v.mstslvctrl.base1000_t_hd := r.regtmp(8);
                end if;
              when others =>  --no writable bits for other regs
                null;
            end case;
          end if;
        end if;
      when others =>
        null;
    end case;
    if r.rstcnt > 19 then
      v.ctrl.reset := '0'; v.rstcnt := 0;
    else
      v.rstcnt := r.rstcnt + 1; 
    end if;
    if (v.ctrl.reset and not r.ctrl.reset) = '1' then
      v.rstcnt := 0; 
    end if;
    if r.ctrl.anegen = '1' then
      if r.anegcnt < 10 then
        v.anegcnt := r.anegcnt + 1;
      else
        v.status.anegcmpt := '1';
        if (base1000_x_fd = 1) or (base1000_x_hd = 1) or
           (r.mstslvctrl.base1000_t_fd = '1') or
           (r.mstslvctrl.base1000_t_hd = '1') then
          v.ctrl.speedsel(1 downto 0) := "01";
        elsif (r.anegadv.tech_ability(4) = '1') or
              (r.anegadv.tech_ability(3) = '1') or
              (r.anegadv.tech_ability(2) = '1') or
              (base100_t2_fd = 1) or (base100_t2_hd = 1) then
          v.ctrl.speedsel(1 downto 0) := "10";
        else
          v.ctrl.speedsel(1 downto 0) := "00";
        end if;
        if ((base1000_x_fd = 1) or (r.mstslvctrl.base1000_t_fd = '1')) or
           (((base100_t2_fd = 1) or (r.anegadv.tech_ability(3) = '1')) and
           (r.mstslvctrl.base1000_t_hd = '0') and (base1000_x_hd = 0)) or
           ((r.anegadv.tech_ability(1) = '1') and (base100_t2_hd = 0) and
           (r.anegadv.tech_ability(4) = '0') and
           (r.anegadv.tech_ability(2) = '0')) then
          v.ctrl.duplexmode := '1';
        else
          v.ctrl.duplexmode := '0';
        end if;
      end if;
    end if;
    if r.ctrl.restartaneg = '1' then
      v.anegcnt := 0;
      v.status.anegcmpt := '0';
      v.ctrl.restartaneg := '0';
    end if;
    rin <= v;
  end process;
 
  reg : process(rstn, mdc) is
  begin
    if rising_edge(mdc) then
      r <= rin;
    end if;
--     -- RESET DELAY
--     if rstd = '1' then
--       r.ctrl.reset <= '1';
--     else
--       r.ctrl.reset <= '0';
--     end if;
 
    -- RESET
    if (r.ctrl.reset or not rstn) = '1' then
      r.ctrl.loopback <= '0'; r.anegcnt <= 0;
      if (base1000_x_hd = 1) or (base1000_x_fd = 1) or (base1000_t_hd = 1) or
         (base1000_t_fd = 1) then
        r.ctrl.speedsel <= "01";
      elsif (base100_x_hd = 1) or (base100_t2_hd = 1) or (base100_x_fd = 1) or
            (base100_t2_fd = 1) or (base100_t4 = 1) then
        r.ctrl.speedsel <= "10";
      else
        r.ctrl.speedsel <= "00";
      end if;
 
      r.ctrl.anegen <= conv_std_logic(aneg = 1);
      r.ctrl.powerdown <= '0';
      r.ctrl.isolate <= '0';
      r.ctrl.restartaneg <= '0';
      if (base100_x_hd = 0) and (hd_10 = 0) and (base100_t2_hd = 0) and
         (base1000_x_hd = 0) and (base1000_t_hd = 0) then
        r.ctrl.duplexmode <= '1';
      else
        r.ctrl.duplexmode <= '0';
      end if;
      r.ctrl.coltest <= '0';
 
      r.status.base100_t4 <= conv_std_logic(base100_t4 = 1);
      r.status.base100_x_fd <= conv_std_logic(base100_x_fd = 1);
      r.status.base100_x_hd <= conv_std_logic(base100_x_hd = 1);  
      r.status.fd_10 <= conv_std_logic(fd_10 = 1);        
      r.status.hd_10 <= conv_std_logic(hd_10 = 1);        
      r.status.base100_t2_fd <= conv_std_logic(base100_t2_fd = 1);
      r.status.base100_t2_hd <= conv_std_logic(base100_t2_hd = 1);
      r.status.extstat <= conv_std_logic((base1000_x_fd = 1) or
                                         (base1000_x_hd = 1) or
                                         (base1000_t_fd = 1) or
                                         (base1000_t_hd = 1)); 
      r.status.mfpreamblesup <= '0';
      r.status.anegcmpt <= '0';      
      r.status.remfault <= '0';     
      r.status.anegability <= conv_std_logic(aneg = 1); 
      r.status.linkstat <= '0';     
      r.status.jabdetect <= '0';    
      r.status.extcap <= conv_std_logic(extended_regs = 1);
 
      r.anegadv.next_page <= '0';
      r.anegadv.remote_fault <= '0';
      r.anegadv.tech_ability <= "000" & conv_std_logic(base100_t4 = 1) &
        conv_std_logic(base100_x_fd = 1) & conv_std_logic(base100_x_hd = 1) &
        conv_std_logic(fd_10 = 1) & conv_std_logic(hd_10 = 1);
      r.anegadv.selector <= "00001";
 
      r.aneglp.next_page <= '0';
      r.aneglp.remote_fault <= '0';
      r.aneglp.tech_ability <= "000" & conv_std_logic(base100_t4 = 1) &
        conv_std_logic(base100_x_fd = 1) & conv_std_logic(base100_x_hd = 1) &
        conv_std_logic(fd_10 = 1) & conv_std_logic(hd_10 = 1);
      r.aneglp.selector <= "00001";
 
      r.anegexp.par_detct_flt <= '0';
      r.anegexp.lp_np_able    <= '0';
      r.anegexp.np_able       <= '0';
      r.anegexp.page_rx       <= '0';
      r.anegexp.lp_aneg_able  <= '0';
 
      r.anegnptx.next_page     <= '0';
      r.anegnptx.message_page  <= '1';
      r.anegnptx.ack2          <= '0';
      r.anegnptx.toggle        <= '0';
      r.anegnptx.message       <= "00000000001";
 
      r.anegnplp.next_page     <= '0';
      r.anegnplp.message_page  <= '1';
      r.anegnplp.ack2          <= '0';
      r.anegnplp.toggle        <= '0';
      r.anegnplp.message       <= "00000000001";
 
      r.mstslvctrl.tmode         <= (others => '0');
      r.mstslvctrl.manualcfgen   <= '0';
      r.mstslvctrl.cfgval        <= '0';
      r.mstslvctrl.porttype      <= '0';
      r.mstslvctrl.base1000_t_fd <= conv_std_logic(base1000_t_fd = 1);
      r.mstslvctrl.base1000_t_hd <= conv_std_logic(base1000_t_fd = 1);
 
      r.mstslvstat.cfgfault         <= '0';
      r.mstslvstat.cfgres           <= '1';
      r.mstslvstat.locrxstate       <= '1';
      r.mstslvstat.remrxstate       <= '1';
      r.mstslvstat.lpbase1000_t_fd  <= conv_std_logic(base1000_t_fd = 1);
      r.mstslvstat.lpbase1000_t_hd  <= conv_std_logic(base1000_t_fd = 1);
      r.mstslvstat.idlerrcnt        <= (others => '0');
 
      r.extstatus.base1000_x_fd <= conv_std_logic(base1000_x_fd = 1);
      r.extstatus.base1000_x_hd <= conv_std_logic(base1000_x_hd = 1);
      r.extstatus.base1000_t_fd <= conv_std_logic(base1000_t_fd = 1);
      r.extstatus.base1000_t_hd <= conv_std_logic(base1000_t_hd = 1);
 
    end if;
 
    if rstn = '0' then
      r.cnt <= 0; r.state <= idle; r.rstcnt <= 0;
      r.ctrl.reset <= '1'; 
    end if;
  end process;
 
 
  loopback_sel : process(r.ctrl.loopback, int_clk, gtx_clk, r.ctrl.speedsel, txd, tx_en) is
  begin
    if r.ctrl.loopback = '1' then
      rx_col <= '0'; rx_crs <= tx_en; rx_dv <= tx_en; rx_er <= tx_er;
      rxd <= txd;
      if r.ctrl.speedsel /= "01" then
        rx_clk <= int_clk; tx_clk <= int_clk;
      else
        rx_clk <= gtx_clk; tx_clk <= clkslow;
      end if;
    else
      rx_col <= '0'; rx_crs <= '0'; rx_dv <= '0';
      rxd <= (others => '0');
      if r.ctrl.speedsel /= "01" then
        rx_clk <= int_clk; tx_clk <= int_clk after 3 ns;
      else
        rx_clk <= gtx_clk; tx_clk <= clkslow;
      end if;
    end if;
  end process;
end;
-- pragma translate_on
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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