trashernet-soc/fpga/hdl/design/top.vhd

277 lines
7.1 KiB
VHDL

-- -------------------------------------------------------------------------- --
-- TRASHERNET SoC - A Trashy Ethernet SoC for FPGAs --
-- -------------------------------------------------------------------------- --
-- TODO
-- -------------------------------------------------------------------------- --
-- Author : Markus Koch <markus@notsyncing.net>
-- 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;