LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; ENTITY e_io_eth_rxif IS PORT ( rst: IN std_logic; clk: IN std_logic; o_data: OUT std_logic_vector(7 DOWNTO 0); o_data_en: OUT std_logic; o_done: OUT std_logic; o_err: OUT std_logic; pin_i_rx_clk: IN std_logic; pin_i_rxd: IN std_logic_vector(4 DOWNTO 0); pin_i_rx_dv: IN std_logic; pin_i_crs: IN std_logic; pin_i_col: IN std_logic ); END ENTITY e_io_eth_rxif; ARCHITECTURE a_io_eth_rxif OF e_io_eth_rxif IS TYPE t_in_state IS (in_idle, in_nibble, in_data, in_pre_done, in_done, in_pre_err, in_err, in_post_err); SIGNAL r_in_state: t_in_state := in_idle; SIGNAL r_in_data: std_logic_vector(7 DOWNTO 0) := X"00"; SIGNAL s_fifo_wr_rdy: std_logic; SIGNAL s_fifo_wr_data: std_logic_vector(9 DOWNTO 0); SIGNAL s_fifo_wr_en: std_logic; SIGNAL s_fifo_rd_rdy: std_logic; SIGNAL s_fifo_rd_data: std_logic_vector(9 DOWNTO 0); 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_in: PROCESS(rst, pin_i_rx_clk) BEGIN IF rst = '1' THEN r_in_state <= in_idle; r_in_data <= X"00"; ELSIF rising_edge(pin_i_rx_clk) THEN CASE r_in_state IS WHEN in_idle => IF pin_i_col = '1' THEN r_in_state <= in_pre_err; ELSIF pin_i_crs = '1' AND pin_i_rx_dv = '1' THEN IF pin_i_rxd(4) = '1' THEN -- rxd(4) is rx_err r_in_state <= in_pre_err; ELSE r_in_state <= in_nibble; r_in_data(3 DOWNTO 0) <= pin_i_rxd(3 DOWNTO 0); END IF; END IF; WHEN in_nibble => IF pin_i_col = '1' THEN r_in_state <= in_err; ELSIF pin_i_crs = '0' OR pin_i_rx_dv = '0' THEN r_in_state <= in_err; ELSIF pin_i_rxd(4) = '1' THEN -- rxd(4) is rx_err r_in_state <= in_err; ELSE r_in_state <= in_data; r_in_data(7 DOWNTO 4) <= pin_i_rxd(3 DOWNTO 0); END IF; WHEN in_data => IF pin_i_col = '1' THEN r_in_state <= in_pre_err; ELSIF pin_i_crs = '0' OR pin_i_rx_dv = '0' THEN r_in_state <= in_pre_done; ELSIF pin_i_rxd(4) = '1' THEN -- rxd(4) is rx_err r_in_state <= in_pre_err; ELSE r_in_state <= in_nibble; r_in_data(3 DOWNTO 0) <= pin_i_rxd(3 DOWNTO 0); END IF; WHEN in_pre_done => IF pin_i_col = '1' THEN r_in_state <= in_err; ELSIF pin_i_crs = '1' AND pin_i_rx_dv = '1' THEN r_in_state <= in_err; ELSE r_in_state <= in_done; END IF; WHEN in_done => IF pin_i_col = '1' THEN r_in_state <= in_pre_err; ELSIF pin_i_crs = '1' AND pin_i_rx_dv = '1' THEN r_in_state <= in_err; ELSE r_in_state <= in_idle; END IF; WHEN in_pre_err => r_in_state <= in_err; WHEN in_err => r_in_state <= in_post_err; WHEN in_post_err => IF pin_i_col = '0' AND (pin_i_crs = '0' OR pin_i_rx_dv = '0') THEN r_in_state <= in_idle; END IF; WHEN OTHERS => NULL; END CASE; END IF; END PROCESS p_in; p_wr_fifo: PROCESS(r_in_state, r_in_data, s_fifo_wr_rdy) BEGIN s_fifo_wr_data <= (OTHERS => '0'); s_fifo_wr_en <= '0'; IF s_fifo_wr_rdy = '1' THEN CASE r_in_state IS WHEN in_data => s_fifo_wr_data(7 DOWNTO 0) <= r_in_data; s_fifo_wr_en <= '1'; WHEN in_done => s_fifo_wr_data(8) <= '1'; s_fifo_wr_en <= '1'; WHEN in_err => s_fifo_wr_data(9) <= '1'; s_fifo_wr_en <= '1'; WHEN OTHERS => NULL; END CASE; END IF; END PROCESS p_wr_fifo; fifo: e_block_fifo_dc GENERIC MAP ( addr_width => 2, data_width => 10 ) PORT MAP ( rst => rst, wr_clk => pin_i_rx_clk, o_wr_rdy => s_fifo_wr_rdy, i_wr_data => s_fifo_wr_data, i_wr_en => s_fifo_wr_en, rd_clk => clk, o_rd_rdy => s_fifo_rd_rdy, o_rd_data => s_fifo_rd_data, i_rd_en => s_fifo_rd_rdy ); o_data <= s_fifo_rd_data(7 DOWNTO 0); o_data_en <= s_fifo_rd_rdy; o_done <= s_fifo_rd_data(8); o_err <= s_fifo_rd_data(9); END ARCHITECTURE a_io_eth_rxif;