-- MIPS I system -- Copyright 2011-2012 Stefan Schuermans -- Copyleft GNU public license V2 or later -- http://www.gnu.org/copyleft/gpl.html LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; ENTITY e_io_eth_txif IS PORT ( rst: IN std_logic; clk: IN std_logic; i_data: IN std_logic_vector(7 DOWNTO 0); i_data_en: IN std_logic; o_data_ack: OUT std_logic; pin_i_tx_clk: IN std_logic; pin_o_txd: OUT std_logic_vector(3 DOWNTO 0); pin_o_tx_en: OUT std_logic ); END ENTITY e_io_eth_txif; ARCHITECTURE a_io_eth_txif OF e_io_eth_txif IS TYPE t_out_state IS (out_idle, out_data_l, out_data_h); SIGNAL r_out_state: t_out_state := out_idle; SIGNAL n_out_state: t_out_state; SIGNAL r_out_data: std_logic_vector(7 DOWNTO 0) := X"00"; SIGNAL n_out_data: std_logic_vector(7 DOWNTO 0); SIGNAL s_fifo_wr_rdy: std_logic; SIGNAL s_fifo_wr_data: std_logic_vector(7 DOWNTO 0); SIGNAL s_fifo_wr_en: std_logic; SIGNAL s_fifo_rd_rdy: std_logic; SIGNAL s_fifo_rd_data: std_logic_vector(7 DOWNTO 0); SIGNAL s_fifo_rd_en: std_logic; COMPONENT e_block_fifo_dc IS GENERIC ( addr_width: natural; data_width: natural ); PORT ( rst: IN std_logic; wr_clk: IN std_logic; o_wr_rdy: OUT std_logic; i_wr_data: IN std_logic_vector(data_width - 1 DOWNTO 0); i_wr_en: IN std_logic; rd_clk: IN std_logic; o_rd_rdy: OUT std_logic; o_rd_data: OUT std_logic_vector(data_width - 1 DOWNTO 0); i_rd_en: IN std_logic ); END COMPONENT e_block_fifo_dc; BEGIN p_out: PROCESS(rst, pin_i_tx_clk) BEGIN IF rst = '1' THEN pin_o_txd <= X"0"; pin_o_tx_en <= '0'; ELSIF falling_edge(pin_i_tx_clk) THEN CASE r_out_state IS WHEN out_idle => pin_o_txd <= X"0"; pin_o_tx_en <= '0'; WHEN out_data_l => pin_o_txd <= r_out_data(3 DOWNTO 0); pin_o_tx_en <= '1'; WHEN out_data_h => pin_o_txd <= r_out_data(7 DOWNTO 4); pin_o_tx_en <= '1'; WHEN OTHERS => NULL; END CASE; END IF; END PROCESS p_out; p_out_next: PROCESS(r_out_state, r_out_data, s_fifo_rd_rdy, s_fifo_rd_data) BEGIN n_out_state <= r_out_state; n_out_data <= r_out_data; s_fifo_rd_en <= '0'; CASE r_out_state IS WHEN out_idle | out_data_h => IF s_fifo_rd_rdy = '1' THEN n_out_state <= out_data_l; n_out_data <= s_fifo_rd_data; s_fifo_rd_en <= '1'; ELSE n_out_state <= out_idle; END IF; WHEN out_data_l => n_out_state <= out_data_h; WHEN OTHERS => NULL; END CASE; END PROCESS p_out_next; p_out_sync: PROCESS(rst, pin_i_tx_clk) BEGIN IF rst = '1' THEN r_out_state <= out_idle; r_out_data <= X"00"; ELSIF rising_edge(pin_i_tx_clk) THEN r_out_state <= n_out_state; r_out_data <= n_out_data; END IF; END PROCESS p_out_sync; fifo: e_block_fifo_dc GENERIC MAP ( addr_width => 4, data_width => 8 ) PORT MAP ( rst => rst, wr_clk => clk, o_wr_rdy => s_fifo_wr_rdy, i_wr_data => s_fifo_wr_data, i_wr_en => s_fifo_wr_en, rd_clk => pin_i_tx_clk, o_rd_rdy => s_fifo_rd_rdy, o_rd_data => s_fifo_rd_data, i_rd_en => s_fifo_rd_en ); s_fifo_wr_data <= i_data; s_fifo_wr_en <= s_fifo_wr_rdy AND i_data_en; o_data_ack <= s_fifo_wr_en; END ARCHITECTURE a_io_eth_txif;