git-svn-id: http://moon:8086/svn/vhdl/trunk@1331 cc03376c-175c-47c8-b038-4cd826a8556b
307 lines
6.9 KiB
VHDL
307 lines
6.9 KiB
VHDL
LIBRARY IEEE;
|
|
USE IEEE.STD_LOGIC_1164.ALL;
|
|
USE IEEE.NUMERIC_STD.ALL;
|
|
use std.textio.all; -- Imports the standard textio package.
|
|
|
|
use work.emac_types.all;
|
|
use work.utils_pkg.all;
|
|
|
|
ENTITY emac_top_jb IS
|
|
Generic
|
|
(
|
|
f_sysclk : real := 100.0;
|
|
TX_RAM_SIZE : natural := 2048;
|
|
RX_RAM_SIZE : natural := 2048
|
|
);
|
|
Port
|
|
(
|
|
CLK_I : in STD_LOGIC;
|
|
RST_I : in STD_LOGIC;
|
|
INT_O : out STD_LOGIC;
|
|
CYC_I : in STD_LOGIC;
|
|
STB_I : in STD_LOGIC;
|
|
SEL_I : in unsigned(3 downto 0);
|
|
WE_I : in STD_LOGIC;
|
|
ACK_O : out STD_LOGIC;
|
|
SRDY_O : out STD_LOGIC;
|
|
MRDY_I : in STD_LOGIC;
|
|
ADDR_I : in unsigned(31 downto 0);
|
|
DAT_I : in unsigned(31 downto 0);
|
|
DAT_O : out unsigned(31 downto 0);
|
|
mii_rx_clk : in STD_LOGIC;
|
|
mii_rx_dv : in STD_LOGIC;
|
|
mii_rx_er : in STD_LOGIC;
|
|
mii_rx : in unsigned(7 downto 0);
|
|
mii_tx_clk : in STD_LOGIC;
|
|
mii_tx_en : out STD_LOGIC;
|
|
mii_tx_er : out STD_LOGIC;
|
|
mii_tx : out unsigned(7 downto 0);
|
|
mii_gtx_clk : in STD_LOGIC;
|
|
mii_crs : in STD_LOGIC;
|
|
mii_col : in STD_LOGIC
|
|
|
|
);
|
|
END emac_top_jb;
|
|
|
|
ARCHITECTURE behavior OF emac_top_jb IS
|
|
|
|
-- Signals for EMAC connections
|
|
signal tx_ctrl_in : tx_ctrl_in_t;
|
|
signal tx_ctrl_out : tx_ctrl_out_t;
|
|
signal tx_din : unsigned(31 downto 0);
|
|
signal tx_din_vld : std_logic;
|
|
|
|
signal rx_ctrl_in : rx_ctrl_in_t;
|
|
signal rx_ctrl_out : rx_ctrl_out_t;
|
|
|
|
signal rx_dout : unsigned(31 downto 0);
|
|
signal rx_dout_re : std_logic;
|
|
|
|
signal rx_int_en : std_logic;
|
|
signal tx_int_en : std_logic;
|
|
signal irq_rx : std_logic;
|
|
signal irq_tx : std_logic;
|
|
|
|
signal ready : std_logic;
|
|
|
|
signal read : std_logic;
|
|
signal write : std_logic;
|
|
signal data_read : std_logic;
|
|
signal data_write : std_logic;
|
|
signal reg_read : std_logic;
|
|
signal reg_write : std_logic;
|
|
|
|
signal reg_addr : unsigned(3 downto 0);
|
|
signal tx_clk : std_logic;
|
|
|
|
begin
|
|
|
|
SRDY_O <= CYC_I and ready;
|
|
read <= STB_I and CYC_I and not WE_I;
|
|
write <= STB_I and CYC_I and WE_I;
|
|
data_read <= read and ADDR_I(15);
|
|
data_write <= write and ADDR_I(15);
|
|
reg_read <= read and not ADDR_I(15);
|
|
reg_write <= write and not ADDR_I(15);
|
|
reg_addr <= ADDR_I(5 downto 2);
|
|
|
|
ready <= not tx_ctrl_in.pkt_alloc_en;
|
|
|
|
tx_din_vld <= data_write;
|
|
tx_din <= DAT_I;
|
|
|
|
rx_dout_re <= data_read;
|
|
|
|
tx_clk <= mii_gtx_clk when tx_ctrl_in.Gbps_en = '1' else mii_tx_clk;
|
|
|
|
------------------------------------------------------------------
|
|
registers_write:
|
|
process(CLK_I)
|
|
begin
|
|
if rising_edge(CLK_I) then
|
|
tx_ctrl_in.pkt_alloc_en <= '0';
|
|
tx_ctrl_in.pkt_commit_en <= '0';
|
|
tx_ctrl_in.reset <= '0';
|
|
rx_ctrl_in.pkt_free_en <= '0';
|
|
rx_ctrl_in.pkt_req_en <= '0';
|
|
rx_ctrl_in.reset <= '0';
|
|
if RST_I = '1' then
|
|
rx_int_en <= '0';
|
|
tx_int_en <= '0';
|
|
tx_ctrl_in.tx_size <= (others => '0');
|
|
rx_ctrl_in.mac_addr <= (X"03", X"02", X"01", X"00", X"07", X"06");
|
|
rx_ctrl_in.promiscious <= '0';
|
|
tx_ctrl_in.Gbps_en <= '0';
|
|
rx_ctrl_in.Gbps_en <= '0';
|
|
tx_ctrl_in.fcs_gen_en <= '0';
|
|
rx_ctrl_in.fcs_chk_en <= '0';
|
|
elsif reg_write = '1' then
|
|
|
|
-- 0x0000 .. 0x003C
|
|
case reg_addr is
|
|
|
|
-- 0x0000
|
|
when "0000" =>
|
|
rx_ctrl_in.reset <= DAT_I(31);
|
|
rx_ctrl_in.Gbps_en <= DAT_I(30);
|
|
rx_ctrl_in.fcs_chk_en <= DAT_I(29);
|
|
rx_ctrl_in.promiscious <= DAT_I(23);
|
|
rx_ctrl_in.pkt_req_en <= DAT_I(17);
|
|
rx_ctrl_in.pkt_free_en <= DAT_I(16);
|
|
rx_int_en <= DAT_I(4);
|
|
|
|
-- 0x0004
|
|
-- rx_size R/O
|
|
|
|
-- 0x0008
|
|
when "0010" =>
|
|
tx_ctrl_in.reset <= DAT_I(31);
|
|
tx_ctrl_in.Gbps_en <= DAT_I(30);
|
|
tx_ctrl_in.fcs_gen_en <= DAT_I(29);
|
|
tx_ctrl_in.pkt_alloc_en <= DAT_I(17);
|
|
tx_ctrl_in.pkt_commit_en <= DAT_I(16);
|
|
tx_int_en <= DAT_I(4);
|
|
|
|
-- 0x000C
|
|
when "0011" =>
|
|
tx_ctrl_in.tx_size <= DAT_I(15 downto 0);
|
|
|
|
-- 0x0010
|
|
-- Gap
|
|
|
|
-- 0x0014
|
|
-- Gap
|
|
|
|
-- 0x0018
|
|
when "0110" =>
|
|
rx_ctrl_in.mac_addr(0) <= DAT_I(31 downto 24);
|
|
rx_ctrl_in.mac_addr(1) <= DAT_I(23 downto 16);
|
|
rx_ctrl_in.mac_addr(2) <= DAT_I(15 downto 8);
|
|
rx_ctrl_in.mac_addr(3) <= DAT_I(7 downto 0);
|
|
|
|
-- 0x001C
|
|
when "0111" =>
|
|
rx_ctrl_in.mac_addr(4) <= DAT_I(31 downto 24);
|
|
rx_ctrl_in.mac_addr(5) <= DAT_I(23 downto 16);
|
|
|
|
-- 0x0020 .. 0x003C
|
|
-- Gap
|
|
when others => null;
|
|
|
|
end case;
|
|
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
registers_read:
|
|
process(CLK_I)
|
|
begin
|
|
if rising_edge(CLK_I) then
|
|
ACK_O <= data_read;
|
|
DAT_O <= rx_dout;
|
|
if reg_read = '1' then
|
|
|
|
-- 0x0000 .. 0x003C
|
|
case reg_addr is
|
|
|
|
-- 0x0000
|
|
when "0000" =>
|
|
ACK_O <= ready;
|
|
DAT_O <= (others => '0');
|
|
DAT_O(31) <= rx_ctrl_out.reset_busy;
|
|
DAT_O(30) <= rx_ctrl_in.Gbps_en;
|
|
DAT_O(29) <= rx_ctrl_in.fcs_chk_en;
|
|
DAT_O(23) <= rx_ctrl_in.promiscious;
|
|
DAT_O(19) <= rx_ctrl_out.pkt_bcast;
|
|
DAT_O(18) <= rx_ctrl_out.pkt_mac_match;
|
|
DAT_O(17) <= rx_ctrl_out.pkt_valid;
|
|
DAT_O(16) <= rx_ctrl_out.pkt_avail;
|
|
DAT_O(4) <= rx_int_en;
|
|
|
|
-- 0x0004
|
|
when "0001" =>
|
|
ACK_O <= '1';
|
|
DAT_O <= X"0000" & rx_ctrl_out.rx_size;
|
|
|
|
-- 0x0008
|
|
when "0010" =>
|
|
ACK_O <= ready;
|
|
DAT_O <= (others => '0');
|
|
DAT_O(31) <= tx_ctrl_out.reset_busy;
|
|
DAT_O(30) <= tx_ctrl_in.Gbps_en;
|
|
DAT_O(29) <= tx_ctrl_in.fcs_gen_en;
|
|
DAT_O(24) <= tx_ctrl_out.pkt_done;
|
|
DAT_O(17) <= tx_ctrl_out.pkt_alloc_req;
|
|
DAT_O(16) <= tx_ctrl_out.pkt_armed;
|
|
DAT_O(4) <= tx_int_en;
|
|
|
|
-- 0x000C
|
|
when "0011" =>
|
|
ACK_O <= '1';
|
|
DAT_O <= X"0000" & tx_ctrl_out.tx_size;
|
|
|
|
-- 0x0010
|
|
-- Gap
|
|
|
|
-- 0x0014
|
|
-- Gap
|
|
|
|
-- 0x0018
|
|
when "0110" =>
|
|
ACK_O <= '1';
|
|
DAT_O <= rx_ctrl_in.mac_addr(0) & rx_ctrl_in.mac_addr(1) & rx_ctrl_in.mac_addr(2) & rx_ctrl_in.mac_addr(3);
|
|
|
|
-- 0x001C
|
|
when "0111" =>
|
|
ACK_O <= '1';
|
|
DAT_O <= rx_ctrl_in.mac_addr(4) & rx_ctrl_in.mac_addr(5) & X"0000";
|
|
|
|
-- 0x0020 .. 0x003C
|
|
-- Gap
|
|
when others => null;
|
|
|
|
end case;
|
|
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
irq_register:
|
|
process(CLK_I)
|
|
begin
|
|
if rising_edge(CLK_I) then
|
|
INT_O <= irq_rx or irq_tx;
|
|
irq_tx <= tx_int_en and tx_ctrl_out.pkt_done;
|
|
irq_rx <= rx_int_en and rx_ctrl_out.pkt_avail;
|
|
end if;
|
|
end process;
|
|
|
|
inst_emac_rx : entity work.emac_rx
|
|
GENERIC MAP
|
|
(
|
|
f_sysclk => f_sysclk,
|
|
RAM_SIZE => RX_RAM_SIZE
|
|
)
|
|
PORT MAP
|
|
(
|
|
clk => CLK_I,
|
|
rst => RST_I,
|
|
dout_re => rx_dout_re,
|
|
dout => rx_dout,
|
|
ctrl_in => rx_ctrl_in,
|
|
ctrl_out => rx_ctrl_out,
|
|
mii_rx_clk => mii_rx_clk,
|
|
mii_rx_dv => mii_rx_dv,
|
|
mii_rx_er => mii_rx_er,
|
|
mii_rx => mii_rx,
|
|
mii_crs => mii_crs,
|
|
mii_col => mii_col
|
|
|
|
);
|
|
|
|
|
|
inst_emac_tx : entity work.emac_tx
|
|
GENERIC MAP
|
|
(
|
|
f_sysclk => f_sysclk,
|
|
RAM_SIZE => TX_RAM_SIZE
|
|
)
|
|
PORT MAP
|
|
(
|
|
clk => CLK_I,
|
|
rst => RST_I,
|
|
din_vld => tx_din_vld,
|
|
din => tx_din,
|
|
ctrl_in => tx_ctrl_in,
|
|
ctrl_out => tx_ctrl_out,
|
|
mii_tx_clk => tx_clk,
|
|
mii_tx_en => mii_tx_en,
|
|
mii_tx_er => mii_tx_er,
|
|
mii_tx => mii_tx
|
|
|
|
);
|
|
|
|
|
|
end behavior;
|