LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; use std.textio.all; -- Imports the standard textio package. ENTITY emac_jb IS 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 : out STD_LOGIC; mii_crs : in STD_LOGIC; mii_col : in STD_LOGIC ); END emac_jb; ARCHITECTURE behavior OF emac_jb IS -- Signals for EMAC connections signal tx_fifo_din : unsigned(7 downto 0); signal tx_fifo_dout : unsigned(7 downto 0); signal tx_fifo_we : std_logic; signal tx_fifo_re : std_logic; signal tx_fifo_empty : std_logic; signal rx_fifo_din : unsigned(7 downto 0); signal rx_fifo_dout : unsigned(7 downto 0); signal rx_fifo_we : std_logic; signal rx_fifo_re : std_logic; signal rx_fifo_empty : std_logic; signal rx_busy : std_logic; signal tx_busy : 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 tx_trig : std_logic; signal rx_trig : std_logic; signal tx_err : std_logic; signal tx_size : unsigned(15 downto 0); signal rx_size : unsigned(15 downto 0); signal tx_counter : unsigned(15 downto 0); signal rx_counter : unsigned(15 downto 0); begin SRDY_O <= CYC_I; INT_O <= irq_rx or irq_tx; mii_gtx_clk <= '0'; mii_tx_er <= tx_err; ------------------------------------------------------------------ registers_write: process(CLK_I) begin if rising_edge(CLK_I) then tx_fifo_we <= '0'; tx_trig <= '0'; rx_trig <= '0'; if RST_I = '1' then rx_int_en <= '0'; tx_int_en <= '0'; tx_err <= '0'; elsif (STB_I and CYC_I and WE_I) = '1' then case ADDR_I(5 downto 2) is when "0000" => tx_err <= DAT_I(31); tx_int_en <= DAT_I(5); rx_int_en <= DAT_I(4); tx_trig <= DAT_I(1); rx_trig <= DAT_I(0); when "0001" => rx_size <= DAT_I(15 downto 0); tx_size <= DAT_I(31 downto 16); when "0010" => tx_fifo_we <= '1'; tx_fifo_din <= DAT_I(7 downto 0); when others => null; end case; end if; end if; end process; registers_read: process(CLK_I) begin if rising_edge(CLK_I) then rx_fifo_re <= '0'; ACK_O <= '0'; if (STB_I and CYC_I) = '1' then ACK_O <= not WE_I; DAT_O <= (others => '0'); case ADDR_I(5 downto 2) is when "0000" => DAT_O(31) <= tx_err; DAT_O(30) <= mii_rx_er; DAT_O(29) <= mii_col; DAT_O(28) <= mii_crs; DAT_O(5) <= tx_int_en; DAT_O(4) <= rx_int_en; DAT_O(1) <= tx_busy; DAT_O(0) <= rx_busy; when "0001" => DAT_O(15 downto 0) <= rx_size; DAT_O(31 downto 16) <= tx_size; when "0010" => rx_fifo_re <= not WE_I; DAT_O(7 downto 0) <= rx_fifo_dout; when others => null; end case; end if; end if; end process; -- Instantiate synchronous FIFO inst_tx_fifo: entity work.fifo_async GENERIC MAP ( addr_width => 12, data_width => 8, do_last_read_update => true ) PORT MAP ( rst => RST_I, clk_w => CLK_I, clk_r => mii_tx_clk, we => tx_fifo_we, re => tx_fifo_re, fifo_full => open, fifo_empty => tx_fifo_empty, fifo_afull => open, fifo_aempty => open, data_w => tx_fifo_din, data_r => tx_fifo_dout ); tx_data_out: process(mii_tx_clk) begin if rising_edge(mii_tx_clk) then mii_tx <= tx_fifo_dout; tx_fifo_re <= tx_busy; mii_tx_en <= not tx_fifo_empty and tx_fifo_re; end if; end process; tx_busy_logic: process(CLK_I) begin if rising_edge(CLK_I) then if RST_I = '1' then tx_busy <= '0'; elsif tx_trig = '1' then tx_busy <= '1'; elsif tx_fifo_empty = '1' then tx_busy <= '0'; end if; end if; end process; rx_busy_logic: process(CLK_I) begin if rising_edge(CLK_I) then if RST_I = '1' then rx_busy <= '1'; end if; end if; end process; irq_register: process(CLK_I) begin if rising_edge(CLK_I) then irq_tx <= tx_int_en; irq_rx <= rx_int_en; end if; end process; end behavior;