From 47e15b9feb1cdb2a7e00a19b5ca7cd21981b033b Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Sun, 14 Mar 2010 18:51:18 +0000 Subject: [PATCH] Initial version Committed on the Free edition of March Hare Software CVSNT Server. Upgrade to CVS Suite for more features and support: http://march-hare.com/cvsnt/ git-svn-id: http://moon:8086/svn/vhdl/trunk@794 cc03376c-175c-47c8-b038-4cd826a8556b --- lib/emac/emac_jb.vhd | 208 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 lib/emac/emac_jb.vhd diff --git a/lib/emac/emac_jb.vhd b/lib/emac/emac_jb.vhd new file mode 100644 index 0000000..b689075 --- /dev/null +++ b/lib/emac/emac_jb.vhd @@ -0,0 +1,208 @@ +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;