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

📄 eth_mdio.vhd

📁 The GRLIB IP Library is an integrated set of reusable IP cores, designed for system-on-chip (SOC) de
💻 VHD
字号:
--------------------------------------------------------------------------------- Entity:	eth_mdio-- File:        eth_mdio.vhd-- Author:      Marko Isomaki-- Description: Ethernet Media Access Controller MDIO module-------------------------------------------------------------------------------library ieee;library grlib;library gaisler; use ieee.std_logic_1164.all;use grlib.stdlib.all;use gaisler.ethernet_mac.all;entity eth_mdio is  generic(    nsync        : integer range 1 to 2   := 2;     scaler       : integer range 0 to 255 := 25);  port(    rst    : in  std_ulogic;    clk    : in  std_ulogic;    emdioi : in  eth_mdio_in_type;    emdioo : out eth_mdio_out_type  );end entity;architecture rtl of eth_mdio is  constant divisor : std_logic_vector(7 downto 0) :=    conv_std_logic_vector(scaler, 8);      type main_state_type is (idle, preamble, startst, op, op2, phyadr, regadr,                           ta, ta2, ta3, data);  type reg_type is record    main_state  : main_state_type;    mdioo       : std_ulogic;    mdioen      : std_ulogic;    cnt         : std_logic_vector(4 downto 0);    data        : std_logic_vector(15 downto 0);    error       : std_ulogic;    done        : std_ulogic;    start       : std_logic_vector(nsync downto 0);  end record;  type clk_reg_type is record    cnt         : std_logic_vector(7 downto 0);    clk         : std_ulogic;   end record;  signal r, rin         : reg_type;  signal clk_r, clk_rin : clk_reg_type;begin  --clk divider process  comb : process(rst, clk_r) is  variable v : clk_reg_type;  begin    v := clk_r;    if clk_r.cnt = "00000000" then      v.cnt := divisor;      v.clk := not clk_r.clk;    else      v.cnt := clk_r.cnt - 1;    end if;    emdioo.mdc <= clk_r.clk;    clk_rin <= v;   end process;   regs : process(clk) is  begin    if rising_edge(clk) then clk_r <= clk_rin; end if;   end process;  --mdio clk domain  mdio_comb : process(rst, r, emdioi) is  variable v : reg_type;  variable index : integer range 0 to 31;  variable start : std_ulogic;  begin    --synchronization    v.start(0) := emdioi.mdiostart;    if nsync = 2 then      v.start(1) := r.start(0);    end if;    start := r.start(nsync) xor r.start(nsync-1);        v := r;    index := conv_integer(r.cnt);    case r.main_state is    when idle =>      v.error := '0';       if start = '1' then        v.mdioen := '0'; v.mdioo := '1'; v.cnt := (others => '0');        v.main_state := preamble; v.start(nsync) := r.start(nsync-1);      end if;     when preamble =>      v.cnt := r.cnt + 1; v.main_state := startst;       if r.cnt = "11111" then v.mdioo := '0'; end if;     when startst =>      v.mdioo := '1'; v.main_state := op; v.cnt := (others => '0');    when op =>      v.main_state := op2;          if emdioi.read = '1' then v.mdioo := '1';      else v.mdioo := '0'; end if;    when op2 =>      v.mdioo := not r.mdioo; v.main_state := phyadr; v.cnt := (others => '0');    when phyadr =>      case index is      when 0 => v.mdioo := emdioi.phyadr(4);      when 1 => v.mdioo := emdioi.phyadr(3);      when 2 => v.mdioo := emdioi.phyadr(2);      when 3 => v.mdioo := emdioi.phyadr(1);      when 4 => v.mdioo := emdioi.phyadr(0);                v.main_state := regadr; v.cnt := (others => '0');      when others => null;      end case;    when regadr =>      case index is      when 0 => v.mdioo := emdioi.regadr(4);      when 1 => v.mdioo := emdioi.regadr(3);      when 2 => v.mdioo := emdioi.regadr(2);      when 3 => v.mdioo := emdioi.regadr(1);      when 4 => v.mdioo := emdioi.regadr(0);                v.main_state := ta; v.cnt := (others => '0');      when others => null;      end case;    when ta =>      v.main_state := ta2;      if emdioi.read = '1' then v.mdioen := '1';      else v.mdioo := '1'; end if;    when ta2 =>      v.cnt := "01111"; v.main_state := ta3;       if emdioi.write = '1' then v.mdioo := '0'; v.main_state := data; end if;    when ta3 =>      v.main_state := data; if emdioi.mdioi /= '0' then v.error := '1'; end if;    when data =>      v.cnt := r.cnt - 1;      if emdioi.read = '1' then        v.data(index) := emdioi.mdioi;       else        v.mdioo := emdioi.data(index);      end if;      if r.cnt = "00000" then        v.mdioen := '0'; v.main_state := idle; v.done := not r.done;      end if;     when others => null;    end case;    if rst = '0' then      v.main_state := idle; v.mdioen := '1'; v.done := '0';      v.start := (others => '0');    end if;    emdioo.error  <= r.error;     emdioo.data   <= r.data;     emdioo.mdioen <= r.mdioen;     emdioo.mdioo  <= r.mdioo;     emdioo.done   <= r.done;    rin <= v;   end process;  mdio_regs : process(clk_r.clk) is  begin    if rising_edge(clk_r.clk) then r <= rin; end if;  end process;end architecture; 

⌨️ 快捷键说明

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