📄 eth_mdio.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 + -