248 lines
6.4 KiB
VHDL
248 lines
6.4 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;
|
||
|
|
||
|
library trashernet;
|
||
|
use trashernet.all;
|
||
|
|
||
|
entity top is
|
||
|
generic(
|
||
|
-- System configuration
|
||
|
F_CLK : integer := 12000000;
|
||
|
F_CLK_PHY : integer := 48000000;
|
||
|
UART_BAUD : integer := 9600
|
||
|
);
|
||
|
port(
|
||
|
clk_12m : 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
|
||
|
component pll0
|
||
|
port(
|
||
|
CLKI : in std_logic;
|
||
|
CLKOP : out std_logic;
|
||
|
LOCK : out std_logic
|
||
|
);
|
||
|
end component pll0;
|
||
|
|
||
|
-- System
|
||
|
signal pll_locked : std_logic;
|
||
|
signal clk : 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;
|
||
|
|
||
|
-- 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
|
||
|
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 : pll0
|
||
|
port map(
|
||
|
CLKI => clk_12m,
|
||
|
CLKOP => clk,
|
||
|
LOCK => pll_locked
|
||
|
);
|
||
|
end generate clockgen;
|
||
|
|
||
|
por : process(clk) is
|
||
|
variable reset_done : std_logic := '0';
|
||
|
begin
|
||
|
if rising_edge(clk) then
|
||
|
rst <= not reset_done;
|
||
|
clr <= not reset_done;
|
||
|
reset_done := '1';
|
||
|
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 => 9600
|
||
|
)
|
||
|
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,
|
||
|
rst => rst,
|
||
|
wb_o => wb_eth_o,
|
||
|
wb_i => wb_eth_i,
|
||
|
rx_p => eth_rx_p,
|
||
|
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 <= '0';
|
||
|
eth_led_orange <= '1';
|
||
|
led_user <= '1';
|
||
|
end architecture rtl;
|