📄 eth_arb.vhd
字号:
-------------------------------------------------------------------------------- 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: eth_arb-- File: eth_arb.vhd-- Author: Marko Isomaki-- Description: Arbiter for two Ethernet MAC:s using one PHY------------------------------------------------------------------------------ library ieee;library gaisler;use ieee.std_logic_1164.all;use gaisler.net.all;entity eth_arb is generic( fullduplex : integer := 0; mdiomaster : integer := 0); port( rst : in std_logic; clk : in std_logic; ethi : in eth_in_type; etho : out eth_out_type; methi : in eth_out_type; metho : out eth_in_type; dethi : in eth_out_type; detho : out eth_in_type );end;architecture rtl of eth_arb is type state_type is (reset,mainh,debugh,mt,dt,mainf,debugf);type buf_elem is record tx_en : std_logic; tx_er : std_logic; txd : std_logic_vector(3 downto 0);end record;type fifo_buf_type is array (0 to 25) of buf_elem; type reg_type is record ifgcounter : integer range 0 to 25; main_state : state_type; fifo_buf : fifo_buf_type;end record;signal r,rin : reg_type; begin comb:process(r,methi,dethi,ethi,rst) variable v : reg_type; variable mcol, dcol, tx_en, tx_er : std_logic; variable txd : std_logic_vector(3 downto 0); begin v := r; tx_en := methi.tx_en; tx_er := methi.tx_er; txd := methi.txd(3 downto 0); mcol := ethi.rx_col; dcol := dethi.tx_en; v.fifo_buf(1 to 25) := r.fifo_buf(0 to 24); case r.main_state is when reset => if fullduplex=1 then v.main_state := mainf; else v.main_state := mainh; end if; --half duplex part when mainh => if dethi.tx_en = '0' and methi.tx_en = '0' and ethi.rx_crs = '0' then v.main_state:=mt; end if; when mt => dcol := ethi.rx_col; if methi.tx_en = '1' then v.main_state := mainh; elsif dethi.tx_en = '1' then v.main_state := debugh; tx_en := dethi.tx_en; tx_er := dethi.tx_er; txd := dethi.txd(3 downto 0); end if; when dt => dcol := ethi.rx_col; tx_en := dethi.tx_en; tx_er := dethi.tx_er; txd := dethi.txd(3 downto 0); if dethi.tx_en = '1' then v.main_state := debugh; elsif methi.tx_en = '1' then v.main_state := mainh; tx_en := methi.tx_en; tx_er := methi.tx_er; txd := methi.txd(3 downto 0); end if; when debugh => tx_en := dethi.tx_en; tx_er := dethi.tx_er; txd := dethi.txd(3 downto 0); dcol := ethi.rx_col; mcol := methi.tx_en; if methi.tx_en = '0' and dethi.tx_en = '0' and ethi.rx_crs = '0' then v.main_state := dt; end if; --full duplex part when mainf => if methi.tx_en = '0' and dethi.tx_en = '1' then v.main_state := debugf; v.ifgcounter := 25; v.fifo_buf(0).tx_en := dethi.tx_en; v.fifo_buf(0).tx_er := dethi.tx_er; v.fifo_buf(0).txd := dethi.txd(3 downto 0); end if; v.fifo_buf(0).tx_en := methi.tx_en; v.fifo_buf(0).tx_er := methi.tx_er; v.fifo_buf(0).txd := methi.txd(3 downto 0); when debugf => if methi.tx_en = '1' then v.main_state := mainf; v.ifgcounter := 25; v.fifo_buf(0).tx_en := methi.tx_en; v.fifo_buf(0).tx_er := methi.tx_er; v.fifo_buf(0).txd := methi.txd(3 downto 0); end if; v.fifo_buf(0).tx_en := dethi.tx_en; v.fifo_buf(0).tx_er := dethi.tx_er; v.fifo_buf(0).txd := dethi.txd(3 downto 0); when others => null; end case; if fullduplex = 1 then if r.ifgcounter > 0 then tx_en := '0'; tx_er := '0'; txd := (others=>'0'); else tx_en := r.fifo_buf(25).tx_en; tx_er := r.fifo_buf(25).tx_er; txd := r.fifo_buf(25).txd; end if; end if; if r.ifgcounter > 0 then v.ifgcounter := r.ifgcounter-1; end if; etho.tx_en <= tx_en; etho.tx_er <= tx_er; etho.txd(3 downto 0) <= txd(3 downto 0); metho.rx_col <= mcol; detho.rx_col <= dcol; detho.rx_clk <= ethi.rx_clk; detho.tx_clk <= ethi.tx_clk; metho.rx_clk <= ethi.rx_clk; metho.tx_clk <= ethi.tx_clk; detho.rxd(3 downto 0) <= ethi.rxd(3 downto 0); detho.rx_dv <= ethi.rx_dv; detho.rx_er <= ethi.rx_er; metho.rxd(3 downto 0) <= ethi.rxd(3 downto 0); metho.rx_dv <= ethi.rx_dv; metho.rx_er <= ethi.rx_er; metho.rx_crs <= ethi.rx_crs; detho.rx_crs <= ethi.rx_crs; if mdiomaster = 1 then etho.mdc <= methi.mdc; etho.mdio_o <= methi.mdio_o; etho.mdio_oe <= methi.mdio_oe; detho.mdio_i <= dethi.mdio_o; metho.mdio_i <= ethi.mdio_i; etho.reset <= methi.reset; else etho.mdc <= dethi.mdc; etho.mdio_o <= dethi.mdio_o; etho.mdio_oe <= dethi.mdio_oe; metho.mdio_i <= methi.mdio_o; detho.mdio_i <= ethi.mdio_i; etho.reset <= dethi.reset; end if; if rst = '0' then v.ifgcounter := 0; v.main_state := reset; end if; rin <= v; end process; reg : process(clk) begin if rising_edge(clk) then r <= rin; end if; end process;end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -