282 lines
7.3 KiB
VHDL
282 lines
7.3 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_n : out std_logic;
|
|
eth_led_orange_n : 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;
|
|
|
|
signal eth_led_green : std_logic;
|
|
signal eth_led_orange : 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,
|
|
led_rx => eth_led_green,
|
|
led_tx => eth_led_orange
|
|
);
|
|
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_n <= not eth_led_green;
|
|
eth_led_orange_n <= not eth_led_orange;
|
|
led_user <= not uart_tx or not uart_rx;
|
|
|
|
flash_ce_n <= 'Z';
|
|
flash_sclk <= 'Z';
|
|
flash_sio <= (others => 'Z');
|
|
|
|
pmod <= (others => 'Z');
|
|
end architecture rtl;
|