From 0fffe741a1f1da87645e2833d06bc0851e6ff28e Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Fri, 18 Jun 2010 11:53:45 +0200 Subject: Add TSE MAC and hook it up (code taken from SInet) --- dionysos_top.vhd | 318 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 315 insertions(+), 3 deletions(-) (limited to 'dionysos_top.vhd') diff --git a/dionysos_top.vhd b/dionysos_top.vhd index 208b967..66e0392 100644 --- a/dionysos_top.vhd +++ b/dionysos_top.vhd @@ -24,6 +24,10 @@ library ieee; use ieee.numeric_std.all; library ines_misc; use ines_misc.reset_sync_pkg.all; + use ines_misc.bibuf_async_pkg.all; +library ines_ethernet; + use ines_ethernet.rmii_in_out_pkg.all; + use ines_ethernet.mdio_interface_pkg.all; --! \brief Top file for design on Dionysos board entity dionysos_top is @@ -103,8 +107,91 @@ entity dionysos_top is flash_reset_n_o : out std_logic; --! FLASH Reset flash_oe_n_o : out std_logic; --! FLASH Output Enable flash_ce_n_o : out std_logic; --! FLASH Chip Enable - fash_acc_o : out std_logic --! + fash_acc_o : out std_logic; --! --@} + + --!@name 100BaseTX Phy0 & Phy1 50 MHz Clock output + --@{ + --! \anchor phy11_grp + et_phy_clk_50mhz_o : out std_logic; --! PHY clock for all RMII ethernet phys + et_phy1_tx_clk_1_i : in std_logic; --! PHY clock in MII mode (not used in RMII mode) + et_phy1_rx_clk_1_i : in std_logic; --! PHY clock in MII mode (not used in RMII mode) + et_phy2_rx_clk_2_i : in std_logic; --! PHY2 clock in MII mode (not used in RMII mode) + et_phy2_tx_clk_2_i : in std_logic; --! PHY2 clock in MII mode (not used in RMII mode) + et_phy2_rx_clk_1_i : in std_logic; --! PHY2 clock in MII mode (not used in RMII mode) + et_phy2_tx_clk_1_i : in std_logic; --! PHY2 clock in MII mode (not used in RMII mode) + et_phy1_rx_clk_2_i : in std_logic; --! PHY2 clock in MII mode (not used in RMII mode) + et_phy1_tx_clk_2_i : in std_logic; --! PHY2 clock in MII mode (not used in RMII mode) + --@} + + --!@name 100BaseTX Phy1 Port 1 + --@{ + --! \anchor phy11_grp + et_phy1_rxd_1_i : in std_logic_vector(3 downto 0); --! Dual eth phy1: phy1 receive data + et_phy1_rx_dv_1_i : in std_logic; --! Dual eth phy1: phy1 rx data valid + et_phy1_crs_1_i : in std_logic; --! Dual eth phy1: phy1 carrier sense + et_phy1_col_1_i : in std_logic; --! Dual eth phy1: phy1 collision detect + et_phy1_txd_1_o : out std_logic_vector(3 downto 0); --! Dual eth phy1: phy1 transmit data + et_phy1_tx_en_1_o : out std_logic; --! Dual eth phy1: phy1 tx enable + et_phy1_int_1_i : in std_logic; --! Dual eth phy1: phy1 interrupt/power down (not used) + et_phy1_rx_er_1_i : in std_logic; --! Dual eth phy1: phy1 error (not used) + --@} + + --!@name 100BaseTX Phy1 Port 2 + --@{ + --! \anchor phy12_grp + et_phy1_rxd_2_i : in std_logic_vector(3 downto 0); --! Dual eth phy1: phy2 receive data + et_phy1_rx_dv_2_i : in std_logic; --! Dual eth phy1: phy2 rx data valid + et_phy1_crs_2_i : in std_logic; --! Dual eth phy1: phy2 carrier sense + et_phy1_col_2_i : in std_logic; --! Dual eth phy1: phy2 collision detect + et_phy1_txd_2_o : out std_logic_vector(3 downto 0); --! Dual eth phy1: phy2 transmit data + et_phy1_tx_en_2_o : out std_logic; --! Dual eth phy1: phy2 tx enable + et_phy1_int_2_i : in std_logic; --! Dual eth phy1: phy2 interrupt/power down (not used) + et_phy1_rx_er_2_i : in std_logic; --! Dual eth phy1: phy2 error (not used) + --@} + + --!@name 100BaseTX Phy2 Port 1 + --@{ + --! \anchor phy11_grp + et_phy2_rxd_1_i : in std_logic_vector(3 downto 0); --! Dual eth phy1: phy1 receive data + et_phy2_rx_dv_1_i : in std_logic; --! Dual eth phy1: phy1 rx data valid + et_phy2_crs_1_i : in std_logic; --! Dual eth phy1: phy1 carrier sense + et_phy2_col_1_i : in std_logic; --! Dual eth phy1: phy1 collision detect + et_phy2_txd_1_o : out std_logic_vector(3 downto 0); --! Dual eth phy1: phy1 transmit data + et_phy2_tx_en_1_o : out std_logic; --! Dual eth phy1: phy1 tx enable + et_phy2_int_1_i : in std_logic; --! Dual eth phy1: phy1 interrupt/power down (not used) + et_phy2_rx_er_1_i : in std_logic; --! Dual eth phy1: phy1 error (not used) + --@} + + --!@name 100BaseTX Phy2 Port 2 + --@{ + --! \anchor phy12_grp + et_phy2_rxd_2_i : in std_logic_vector(3 downto 0); --! Dual eth phy1: phy2 receive data + et_phy2_rx_dv_2_i : in std_logic; --! Dual eth phy1: phy2 rx data valid + et_phy2_crs_2_i : in std_logic; --! Dual eth phy1: phy2 carrier sense + et_phy2_col_2_i : in std_logic; --! Dual eth phy1: phy2 collision detect + et_phy2_txd_2_o : out std_logic_vector(3 downto 0); --! Dual eth phy1: phy2 transmit data + et_phy2_tx_en_2_o : out std_logic; --! Dual eth phy1: phy2 tx enable + et_phy2_int_2_i : in std_logic; --! Dual eth phy1: phy2 interrupt/power down (not used) + et_phy2_rx_er_2_i : in std_logic; --! Dual eth phy1: phy2 error (not used) + --@} + + --!@name Phy 1 configuration (MDIO, reset) + --@{ + --! \anchor mdio_grp + et_phy1_mdc_o : out std_logic; --! Dual eth phy1, phy2 Management clock + et_phy1_mdio_io : inout std_logic; --! Dual eth phy1, phy2 data + rst_et_phy1_n_o : out std_logic; --! Ethernet phy reset + --@} + + --!@name Phy 2 configuration (MDIO, reset) + --@{ + --! \anchor mdio_grp + et_phy2_mdc_o : out std_logic; --! Dual eth phy1, phy2 Management clock + et_phy2_mdio_io : inout std_logic; --! Dual eth phy1, phy2 data + rst_et_phy2_n_o : out std_logic --! Ethernet phy reset + --@} + ); end dionysos_top; @@ -118,11 +205,13 @@ architecture rtl of dionysos_top is --! 25 MHz Clock signal pll_clk_25 : std_logic; --! 12.5 MHz Clock - signal pll_clk_12_5 : std_logic; + signal pll_clk_12_5 : std_logic; --! main design reset after reset circuit signal reset_n : std_logic; --! synchronous reset signal fpga_reset_n_ff : std_logic; + --! synchronous reset + signal fpga_reset_n_ff_100 : std_logic; --! Reset for the NIOS. Active in Ethernet Modus (no DSL) signal reset_nios_n : std_logic; @@ -137,9 +226,79 @@ architecture rtl of dionysos_top is signal dram_ba : std_logic_vector(1 downto 0); --@} + --! @name RX byte stream interface of ethernet phy 1 + --! (see \subpage bs_interface_stb) + --@{ + --! Ethernet phy 1 RMII receive data + signal et_phy1_rx_data_1 : std_logic_vector(7 downto 0); + signal et_phy1_rx_data_2 : std_logic_vector(7 downto 0); + --! Ethernet phy 1 RMII receive strobe + signal et_phy1_rx_stb_1 : std_logic; + signal et_phy1_rx_stb_2 : std_logic; + --! Ethernet phy 1 RMII receive data valid + signal et_phy1_rx_dv_1 : std_logic; + signal et_phy1_rx_dv_2 : std_logic; + --@} + + --! \page bs_interface_stb Bytestream Interface (Strobe) + --! \image html timingdiagramme_bytestream_interface_stb.png "bytestream interface with strobe signal" + + --! @name RX interface 2 of ethernet phy 2 + --@{ + --! Ethernet phy 2 port 2 RMII receive data + signal et_phy2_rx_data_2 : std_logic_vector(7 downto 0); + --! Ethernet phy 2 port 2 RMII receive strobe + signal et_phy2_rx_stb_2 : std_logic; + --! Ethernet phy 2 port 2 RMII receive data valid + signal et_phy2_rx_dv_2 : std_logic; + --@} + + --! @name TX interface 2 of ethernet phy 2 + --@{ + --! Ethernet phy 2 port 2 RMII transmit data + signal et_phy2_txd_2 : std_logic_vector(7 downto 0); + --! Ethernet phy 2 port 2 RMII transmit eanble + signal et_phy2_tx_en_2 : std_logic; + --! Ethernet phy 2 port 2 RMII transmit data acknowledge + signal et_phy2_tx_ack_2 : std_logic; + --@} + + --! link status of ethernet interfaces (from MDIO) \todo tidy mdio + signal et_phy1_link_status : std_logic_vector(3 downto 0); + --! synchronised on clock dip switch states signal sw_sync : std_logic_vector(switch_i'range); + --! @name MDIO signals (100BaseTX phy configuration interface) + --@{ + --! output enable for mdio data + signal et_phy1_mdio_oe : std_logic; + signal et_phy2_mdio_oe : std_logic; + --! mdio data input + signal et_phy1_mdio_in : std_logic; + signal et_phy2_mdio_in : std_logic; + --! mdio data output + signal et_phy1_mdio_out : std_logic; + signal et_phy2_mdio_out : std_logic; + --@} + + --! @name Signals between TSE mac (MII mode) and RMII bridge + --@{ + signal mii_txd_from_mac_0 : std_logic_vector(3 downto 0); + signal mii_rx_dv_to_mac_0 : std_logic; + signal mii_rxd_to_mac_0 : std_logic_vector(3 downto 0); + signal mii_tx_en_from_mac_0 : std_logic; + signal mii_txd_from_mac_1 : std_logic_vector(3 downto 0); + signal mii_rx_dv_to_mac_1 : std_logic; + signal mii_rxd_to_mac_1 : std_logic_vector(3 downto 0); + signal mii_tx_en_from_mac_1 : std_logic; + + signal mac_mdio_in : std_logic; + signal mac_mdio_out : std_logic; + signal mac_mdio_en : std_logic; + signal mac_mdio_en_n : std_logic; + --@} + begin --! @name Components --@{ @@ -156,6 +315,9 @@ architecture rtl of dionysos_top is c3 => dram_clk_o -- 50MHz clock output (-3ns) ); + -- generate ETH-PHY 50MHz clock + et_phy_clk_50mhz_o <= pll_clk_50; + --! synchronize reset reset_n_sync : reset_sync generic map( @@ -167,6 +329,8 @@ architecture rtl of dionysos_top is reset2_n_i => '1', reset_n_o => fpga_reset_n_ff ); + rst_et_phy1_n_o <= fpga_reset_n_ff; -- reset for de RMII-PHY 0 + rst_et_phy2_n_o <= fpga_reset_n_ff_100; -- reset for de RMII-PHY 1 --! Delay reset => Latch in Time from Power up for the RMII-Phy (min 167ms) reset_gen : reset_sync @@ -180,6 +344,18 @@ architecture rtl of dionysos_top is reset_n_o => reset_n -- reset for all other components ); + --! Delay reset for PHY Nr. 2 => so that the two phy's aren't exactly synchron + reset_gen_100 : reset_sync + generic map( + STAGES => 100 --2us + ) + port map( + clk_i => pll_clk_50, + reset1_n_i => fpga_reset_n_ff, + reset2_n_i => '1', + reset_n_o => fpga_reset_n_ff_100 -- reset 100 clocks delayed + ); + -- NIOSII CPU flash_reset_n_o <= '1'; fash_acc_o <= '0'; -- Hardware Write Protect input (accelerated program operations) @@ -229,7 +405,143 @@ architecture rtl of dionysos_top is data0_to_the_epcs_flash_controller_0 => config_data0_i, dclk_from_the_epcs_flash_controller_0 => config_dclk_o, sce_from_the_epcs_flash_controller_0 => config_ce_n_o, - sdo_from_the_epcs_flash_controller_0 => config_asd0_o + sdo_from_the_epcs_flash_controller_0 => config_asd0_o, + + -- TSE MAC + -- ena_10_from_the_triple_speed_ethernet_0 => ena_10_from_the_triple_speed_ethernet_0, + -- eth_mode_from_the_triple_speed_ethernet_0 => eth_mode_from_the_triple_speed_ethernet_0, + gm_rx_d_to_the_triple_speed_ethernet_0 => (others => '0'), + gm_rx_dv_to_the_triple_speed_ethernet_0 => '0', + gm_rx_err_to_the_triple_speed_ethernet_0 => '0', + -- gm_tx_d_from_the_triple_speed_ethernet_0 => gm_tx_d_from_the_triple_speed_ethernet_0, + -- gm_tx_en_from_the_triple_speed_ethernet_0 => gm_tx_en_from_the_triple_speed_ethernet_0, + -- gm_tx_err_from_the_triple_speed_ethernet_0 => gm_tx_err_from_the_triple_speed_ethernet_0, + m_rx_col_to_the_triple_speed_ethernet_0 => et_phy2_col_1_i, + m_rx_crs_to_the_triple_speed_ethernet_0 => '1', -- et_phy2_crs_1_i is not the same in rmii mode + m_rx_d_to_the_triple_speed_ethernet_0 => mii_rxd_to_mac_0, + m_rx_en_to_the_triple_speed_ethernet_0 => mii_rx_dv_to_mac_0, + m_rx_err_to_the_triple_speed_ethernet_0 => '0', + mdio_in_to_the_triple_speed_ethernet_0 => mac_mdio_in, + m_tx_d_from_the_triple_speed_ethernet_0 => mii_txd_from_mac_0, + m_tx_en_from_the_triple_speed_ethernet_0 => mii_tx_en_from_mac_0, + -- m_tx_err_from_the_triple_speed_ethernet_0 => m_tx_err_from_the_triple_speed_ethernet_0, + mdc_from_the_triple_speed_ethernet_0 => et_phy2_mdc_o, + mdio_oen_from_the_triple_speed_ethernet_0 => mac_mdio_en_n, + mdio_out_from_the_triple_speed_ethernet_0 => mac_mdio_out, + rx_clk_to_the_triple_speed_ethernet_0 => pll_clk_25, + set_1000_to_the_triple_speed_ethernet_0 => '0', -- tie to 0 if not used + set_10_to_the_triple_speed_ethernet_0 => '0', -- tie to 0 if not used + tx_clk_to_the_triple_speed_ethernet_0 => pll_clk_25 + ); + + --------------------------------------------------------------------- + -- ethernet MDIO for connection between TSE and PHY 2 + --------------------------------------------------------------------- + + --! MDIO bidirectional data buffer + mdio_phy_2_data_buf : bibuf_async + port map( + oe => mac_mdio_en, + io => et_phy2_mdio_io, + inp => mac_mdio_out, + outp => mac_mdio_in ); + mac_mdio_en <= not mac_mdio_en_n; + + ------------------------------------------------------------------------ + -- Converts the rmii interface to the mii interface + ------------------------------------------------------------------------ + + et_phy2_txd_1_o(3 downto 2) <= "00"; + + rmii_phy_to_mii_mac_0 : entity ines_ethernet.rmii_phy_to_mii_mac + port map( + reset_n_i => reset_n, + clk_25_i => pll_clk_25, + clk_50_i => pll_clk_50, + rmii_crs_i => et_phy2_crs_1_i, + + -- Transmit Path + mii_tx_en_i => mii_tx_en_from_mac_0, + mii_txd_i => mii_txd_from_mac_0, + rmii_tx_en_o => et_phy2_tx_en_1_o, + rmii_txd_o => et_phy2_txd_1_o(1 downto 0), + + -- Receive Path + rmii_rx_dv_i => et_phy2_rx_dv_1_i, + rmii_rxd_i => et_phy2_rxd_1_i(1 downto 0), + + mii_rx_dv_o => mii_rx_dv_to_mac_0, + mii_rxd_o => mii_rxd_to_mac_0 + ); + + et_phy2_txd_2_o(3 downto 2) <= "00"; + + rmii_phy_to_mii_mac_1 : entity ines_ethernet.rmii_phy_to_mii_mac + port map( + reset_n_i => reset_n, + clk_25_i => pll_clk_25, + clk_50_i => pll_clk_50, + rmii_crs_i => et_phy2_crs_2_i, + + -- Transmit Path + mii_tx_en_i => mii_tx_en_from_mac_1, + mii_txd_i => mii_txd_from_mac_1, + rmii_tx_en_o => et_phy2_tx_en_2_o, + rmii_txd_o => et_phy2_txd_2_o(1 downto 0), + + -- Receive Path + rmii_rx_dv_i => et_phy2_rx_dv_2_i, + rmii_rxd_i => et_phy2_rxd_2_i(1 downto 0), + + mii_rx_dv_o => mii_rx_dv_to_mac_1, + mii_rxd_o => mii_rxd_to_mac_1 + ); + + ------------------------------------------------------------------------ + -- MDIO Interface + ------------------------------------------------------------------------ + --! MDIO interface for ethernet phy configuration + mdio : entity ines_ethernet.mdio_interface + generic map( + C_SET_TO_MII => false, + CLK_DIVIDER => 10, -- divider for MDC + CHK_INTERVAL => 50e6, -- link check interval in clk_i cycles +-- CHK_INTERVAL => 500, -- for Testbench + NO_OF_PORTS => 2, -- number of ports to poll => max 4 + ADDR_PORT_1 => 0, + ADDR_PORT_2 => 1, + ADDR_PORT_3 => 2, + ADDR_PORT_4 => 3) + port map( + clk_i => pll_clk_50, + reset_n_i => reset_n, + -- manual access (could be connected to the CPU interface...) + phy_addr_i => (others => '0'), + phy_reg_i => (others => '0'), + phy_data_i => (others => '0'), + phy_data_o => open, + send_i => '0', + read_i => '0', + busy_n_o => open, + -- Status out + link_o => et_phy1_link_status, -- 1= link OK + reset_phy_i => (others => '0'), -- 1= reset phy + -- MDIO + mdio_i => et_phy1_mdio_in, + mdio_o => et_phy1_mdio_out, + mdio_oe_o => et_phy1_mdio_oe, + mdc_o => et_phy1_mdc_o + ); + + --! MDIO bidirectional data buffer + mdio_data_buf : bibuf_async + port map( + oe => et_phy1_mdio_oe, + io => et_phy1_mdio_io, + inp => et_phy1_mdio_out, + outp => et_phy1_mdio_in + ); + --@} end rtl; -- cgit v1.2.3-54-g00ecf