-- -------------------------------------------------------------------------- -- -- TRASHERNET SoC - A Trashy Ethernet SoC for FPGAs -- -- -------------------------------------------------------------------------- -- -- TODO -- -------------------------------------------------------------------------- -- -- Author : Markus Koch -- Contributors : None -- License : Mozilla Public License (MPL) Version 2 -- -------------------------------------------------------------------------- -- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; library generics; use generics.all; use generics.wishbone_pkg.all; use generics.ice40_components.all; entity top is generic( -- System configuration F_CLK : integer := 25000000; F_CLK_PHY : integer := 50000000; UART_BAUD : integer := 19200 ); port( clk_50m : in std_logic; -- System clock -- UART uart_tx : out std_logic; -- UART TX uart_rx : in std_logic; -- UART RX -- Trashernet eth_rx_p : in std_logic; -- Ethernet RX+ --eth_rx_n : in std_logic; -- Ethernet RX- eth_tx_p : out std_logic_vector(3 downto 0); -- Ethernet TX+ eth_tx_n : out std_logic_vector(3 downto 0); -- Ethernet TX- -- LEDs eth_led_green : out std_logic; eth_led_orange : out std_logic; led_user : out std_logic; -- -- PSRAM IF psram_ce_n : out std_logic; psram_sclk : out std_logic; psram_sio : inout std_logic_vector(3 downto 0); -- -- Config Flash flash_ce_n : out std_logic; flash_sclk : out std_logic; flash_sio : inout std_logic_vector(3 downto 0); -- -- PMOD pmod : inout std_logic_vector(7 downto 0) ); end entity top; architecture rtl of top is -- System signal pll_locked : std_logic; signal clk : std_logic; signal clk_phy : std_logic; signal rst : std_logic := '1'; -- Asynchronous assert, synchronous release reset signal clr : std_logic := '1'; -- Fully synchronous reset signal eth_tx_p_i : std_logic; signal eth_tx_n_i : std_logic; signal eth_rx_p_i : std_logic; -- System Timer signal irq_timer : std_logic; -- Wishbone interconnect (master) signal wb_masters_o : wishbone_slave_in_vector(1 downto 0); signal wb_masters_i : wishbone_slave_out_vector(wb_masters_o'range); alias wbi_o is wb_masters_o(0); alias wbi_i is wb_masters_i(0); alias wbd_o is wb_masters_o(1); alias wbd_i is wb_masters_i(1); -- Wishbone interconnect (slave) signal wb_slaves_o : wishbone_master_in_vector(4 downto 0); signal wb_slaves_i : wishbone_master_out_vector(wb_slaves_o'range); alias wb_rom_o is wb_slaves_o(0); alias wb_rom_i is wb_slaves_i(0); alias wb_ram_o is wb_slaves_o(1); alias wb_ram_i is wb_slaves_i(1); alias wb_timer_o is wb_slaves_o(2); alias wb_timer_i is wb_slaves_i(2); alias wb_uart_o is wb_slaves_o(3); alias wb_uart_i is wb_slaves_i(3); alias wb_eth_o is wb_slaves_o(4); alias wb_eth_i is wb_slaves_i(4); -- Slave address map constant wishbone_addresses : wishbone_address_vector := ( 0 => x"00000000", -- Boot ROM 1 => x"40000000", -- RAM 2 => x"80000000", -- Timer 3 => x"81000000", -- UART 4 => x"82000000" -- Eth ); constant wishbone_masks : wishbone_address_vector := ( 0 => x"FF000000", -- Boot ROM: 256b 1 => x"FF000000", -- RAM: Max 16M 2 => x"FF000000", -- Timer 3 => x"FF000000", -- UART 4 => x"FF000000" -- Eth ); constant IN_SIMULATION : boolean := false -- -- pragma translate_off or true -- -- pragma translate_on ; begin SB_IO_inst : component SB_IO generic map( PIN_TYPE => "000000", IO_STANDARD => "SB_LVDS_INPUT" ) port map( PACKAGE_PIN => eth_rx_p, LATCH_INPUT_VALUE => '1', CLOCK_ENABLE => '1', INPUT_CLK => clk_phy, OUTPUT_CLK => clk_phy, OUTPUT_ENABLE => '0', D_OUT_0 => '0', D_OUT_1 => '0', D_IN_0 => eth_rx_p_i, D_IN_1 => open ); clockgen : if IN_SIMULATION generate clock_driver : process constant period : time := 1 sec / real(F_CLK); begin clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2; end process clock_driver; pll_locked <= '1'; else generate pll_inst : entity work.pll0 generic map( F_CLK => F_CLK, F_CLK_PHY => F_CLK_PHY ) port map( clk_in => clk_50m, clk_out => clk, clk_out_phy => clk_phy, locked => pll_locked ); end generate clockgen; por : process(clk) is variable reset_cnt : integer range 0 to 255 := 0; begin if rising_edge(clk) then if reset_cnt = 255 then rst <= '0'; clr <= '0'; else reset_cnt := reset_cnt + 1; rst <= '1'; clr <= '1'; end if; end if; end process por; serv_top_vhdl_inst : entity work.serv_top_vhdl port map( clk => clk, clr => clr, wbi_o => wbi_o, wbi_i => wbi_i, wbd_o => wbd_o, wbd_i => wbd_i, irq_timer => irq_timer ); servant_rom_vhdl_inst : entity work.servant_ram_vhdl generic map( memfile => "../sw/bootrom/bootrom.vhex", read_only => true, adr_width => 9 ) port map( clk => clk, clr => clr, wb_o => wb_rom_o, wb_i => wb_rom_i ); aps6404l_wb_inst : entity work.aps6404l_wb port map( clk => clk, rst => rst, wb_o => wb_ram_o, wb_i => wb_ram_i, psram_ce_n => psram_ce_n, psram_sclk => psram_sclk, psram_sio => psram_sio ); servant_timer_vhdl_inst : entity work.servant_timer_vhdl port map( clk => clk, clr => clr, wb_o => wb_timer_o, wb_i => wb_timer_i, irq => irq_timer ); uart_wb_inst : entity work.uart_wb generic map( F_CLK => F_CLK, BAUD_RATE => UART_BAUD ) port map( clk => clk, rst => rst, wb_o => wb_uart_o, wb_i => wb_uart_i, serial_out => uart_tx, serial_in => uart_rx ); trashernet_phy_wb_inst : entity work.trashernet_phy_wb generic map( F_CLK => F_CLK, F_CLK_PHY => F_CLK_PHY ) port map( clk => clk, phy_clk => clk_phy, rst => rst, wb_o => wb_eth_o, wb_i => wb_eth_i, rx_p => eth_rx_p_i, tx_p => eth_tx_p_i, tx_n => eth_tx_n_i ); eth_tx_p <= (others => eth_tx_p_i); eth_tx_n <= (others => eth_tx_n_i); wishbone_crossbar_inst : entity generics.wishbone_arbiter port map( clk => clk, rst => rst, masters_o => wb_masters_o, masters_i => wb_masters_i, slaves_o => wb_slaves_o, slaves_i => wb_slaves_i, address => wishbone_addresses, mask => wishbone_masks ); eth_led_green <= uart_tx; eth_led_orange <= uart_rx; led_user <= not psram_ce_n; flash_ce_n <= 'Z'; flash_sclk <= 'Z'; flash_sio <= (others => 'Z'); pmod <= (others => 'Z'); end architecture rtl;