fpga: Continue work on full HW support
This commit is contained in:
parent
c7caf2189b
commit
dd7cf08b6f
@ -1,5 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
# -------------------------------------------------------------------------- --
|
||||
# TRASHERNET SoC - A Trashy Ethernet SoC for FPGAs --
|
||||
# -------------------------------------------------------------------------- --
|
||||
# TODO
|
||||
# -------------------------------------------------------------------------- --
|
||||
# Author : Markus Koch <markus@notsyncing.net>
|
||||
# Contributors : None
|
||||
# License : Mozilla Public License (MPL) Version 2
|
||||
# -------------------------------------------------------------------------- --
|
||||
|
||||
if [ "$1" == "flash" ]; then
|
||||
openFPGALoader --unprotect-flash -f -c ft2232 -b ice40_generic build/bitstream.bin
|
||||
exit 0
|
||||
fi
|
||||
|
||||
mkdir -p build
|
||||
cd build
|
||||
|
||||
@ -8,7 +23,7 @@ set -e
|
||||
../run.py --compile
|
||||
|
||||
BASEDIR=".."
|
||||
DEVICE=--u4k # --up5k, --u4k
|
||||
DEVICE=--up5k # --up5k, --u4k
|
||||
PACKAGE=sg48
|
||||
|
||||
# Collect pre-analyzed VHDL sources
|
||||
@ -22,7 +37,7 @@ VLOGS="$VLOGS $SERV/servant/servant_ram.v $SERV/servant/servant_timer.v"
|
||||
# Synthesize and PnR
|
||||
# -device <hx | lp | u>
|
||||
yosys -m ghdl -p "read_verilog $VLOGS; ghdl --std=08 $GHDLINCDIRS design.top; synth_ice40 -abc9 -device u -top top -json netlist.json"
|
||||
nextpnr-ice40 $DEVICE --package $PACKAGE --freq 12 --asc netlist.asc --report report.json --detailed-timing-report --json netlist.json --pcf ../constraints.pcf
|
||||
nextpnr-ice40 $DEVICE --package $PACKAGE --asc netlist.asc --report report.json --detailed-timing-report --json netlist.json --pcf ../constraints.pcf
|
||||
|
||||
# Generate bitstream
|
||||
icepack netlist.asc bitstream.bin
|
||||
|
@ -23,9 +23,9 @@ set_io pmod[7] 31
|
||||
|
||||
set_io uart_rx 37
|
||||
set_io uart_tx 36
|
||||
set_io clk_12m 35
|
||||
set_io clk_50m 35
|
||||
|
||||
set_io eth_rx_n 38
|
||||
#set_io eth_rx_n 38
|
||||
set_io eth_rx_p 42
|
||||
|
||||
set_io eth_tx_n[0] 46
|
||||
@ -42,3 +42,6 @@ set_io eth_led_green 40
|
||||
set_io eth_led_orange 41
|
||||
|
||||
set_io led_user 34
|
||||
|
||||
set_frequency clk 24
|
||||
set_frequency clk_phy 50
|
||||
|
@ -73,11 +73,11 @@ begin
|
||||
|
||||
top_inst : entity design.top
|
||||
port map(
|
||||
clk_12m => clk,
|
||||
clk_50m => clk,
|
||||
uart_tx => uart_txd,
|
||||
uart_rx => uart_rxd,
|
||||
eth_rx_p => rx_p,
|
||||
eth_rx_n => rx_n,
|
||||
--eth_rx_n => rx_n,
|
||||
eth_tx_p => tx_p,
|
||||
eth_tx_n => tx_n,
|
||||
psram_ce_n => psram_ce_n,
|
||||
|
@ -11,15 +11,60 @@
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
|
||||
library generics;
|
||||
use generics.ice40_components.all;
|
||||
|
||||
entity pll0 is
|
||||
generic(
|
||||
F_CLK : in integer;
|
||||
F_CLK_PHY : in integer
|
||||
);
|
||||
port(
|
||||
CLKI : in std_logic;
|
||||
CLKOP : out std_logic;
|
||||
LOCK : out std_logic);
|
||||
clk_in : in std_logic;
|
||||
clk_out : out std_logic;
|
||||
clk_out_phy : out std_logic;
|
||||
locked : out std_logic
|
||||
);
|
||||
end pll0;
|
||||
|
||||
architecture Structure of pll0 is
|
||||
signal clk_int_osc : std_logic;
|
||||
begin
|
||||
CLKOP <= CLKI;
|
||||
LOCK <= '1';
|
||||
SB_HFOSC_inst : component SB_HFOSC
|
||||
generic map(
|
||||
CLKHF_DIV => "0b01" -- 24 MHz
|
||||
)
|
||||
port map(
|
||||
CLKHFPU => '1',
|
||||
CLKHFEN => '1',
|
||||
CLKHF => clk_int_osc
|
||||
);
|
||||
|
||||
-- SB_PLL40_PAD_inst : component SB_PLL40_PAD
|
||||
-- generic map(
|
||||
-- FEEDBACK_PATH => "SIMPLE",
|
||||
-- DIVR => "0000",
|
||||
-- DIVF => "1000010",
|
||||
-- DIVQ => "100",
|
||||
-- FILTER_RANGE => "001"
|
||||
-- )
|
||||
-- port map(
|
||||
-- RESETB => '1',
|
||||
-- BYPASS => '0',
|
||||
-- PACKAGEPIN => clk_in,
|
||||
-- PLLOUTCORE => clk_out_phy
|
||||
-- );
|
||||
|
||||
clk_out_phy <= clk_in;
|
||||
|
||||
-- Not clean, but it works...
|
||||
ckdiv2 : process(clk_out_phy) is
|
||||
begin
|
||||
if rising_edge(clk_out_phy) then
|
||||
clk_out <= not clk_out;
|
||||
end if;
|
||||
end process ckdiv2;
|
||||
|
||||
assert F_CLK = 25000000 report "clk: PLL generates clock different from specified." severity failure;
|
||||
assert F_CLK_PHY = 50000000 report "clk_phy: PLL generates clock different from specified." severity failure;
|
||||
end Structure;
|
||||
|
@ -15,19 +15,17 @@ use ieee.numeric_std.all;
|
||||
library generics;
|
||||
use generics.all;
|
||||
use generics.wishbone_pkg.all;
|
||||
|
||||
library trashernet;
|
||||
use trashernet.all;
|
||||
use generics.ice40_components.all;
|
||||
|
||||
entity top is
|
||||
generic(
|
||||
-- System configuration
|
||||
F_CLK : integer := 12000000;
|
||||
F_CLK_PHY : integer := 48000000;
|
||||
UART_BAUD : integer := 9600
|
||||
F_CLK : integer := 25000000;
|
||||
F_CLK_PHY : integer := 50000000;
|
||||
UART_BAUD : integer := 19200
|
||||
);
|
||||
port(
|
||||
clk_12m : in std_logic; -- System clock
|
||||
clk_50m : in std_logic; -- System clock
|
||||
|
||||
-- UART
|
||||
uart_tx : out std_logic; -- UART TX
|
||||
@ -35,44 +33,41 @@ entity top is
|
||||
|
||||
-- Trashernet
|
||||
eth_rx_p : in std_logic; -- Ethernet RX+
|
||||
eth_rx_n : 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;
|
||||
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);
|
||||
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);
|
||||
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 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;
|
||||
@ -120,8 +115,26 @@ architecture rtl of top is
|
||||
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);
|
||||
@ -135,21 +148,31 @@ begin
|
||||
pll_locked <= '1';
|
||||
|
||||
else generate
|
||||
pll_inst : pll0
|
||||
pll_inst : entity work.pll0
|
||||
generic map(
|
||||
F_CLK => F_CLK,
|
||||
F_CLK_PHY => F_CLK_PHY
|
||||
)
|
||||
port map(
|
||||
CLKI => clk_12m,
|
||||
CLKOP => clk,
|
||||
LOCK => pll_locked
|
||||
clk_in => clk_50m,
|
||||
clk_out => clk,
|
||||
clk_out_phy => clk_phy,
|
||||
locked => pll_locked
|
||||
);
|
||||
end generate clockgen;
|
||||
|
||||
por : process(clk) is
|
||||
variable reset_done : std_logic := '0';
|
||||
variable reset_cnt : integer range 0 to 255 := 0;
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
rst <= not reset_done;
|
||||
clr <= not reset_done;
|
||||
reset_done := '1';
|
||||
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;
|
||||
|
||||
@ -166,7 +189,7 @@ begin
|
||||
|
||||
servant_rom_vhdl_inst : entity work.servant_ram_vhdl
|
||||
generic map(
|
||||
memfile => "../../sw/bootrom/bootrom.vhex",
|
||||
memfile => "../sw/bootrom/bootrom.vhex",
|
||||
read_only => true,
|
||||
adr_width => 9
|
||||
)
|
||||
@ -200,7 +223,7 @@ begin
|
||||
uart_wb_inst : entity work.uart_wb
|
||||
generic map(
|
||||
F_CLK => F_CLK,
|
||||
BAUD_RATE => 9600
|
||||
BAUD_RATE => UART_BAUD
|
||||
)
|
||||
port map(
|
||||
clk => clk,
|
||||
@ -218,11 +241,11 @@ begin
|
||||
)
|
||||
port map(
|
||||
clk => clk,
|
||||
phy_clk => clk,
|
||||
phy_clk => clk_phy,
|
||||
rst => rst,
|
||||
wb_o => wb_eth_o,
|
||||
wb_i => wb_eth_i,
|
||||
rx_p => eth_rx_p,
|
||||
rx_p => eth_rx_p_i,
|
||||
tx_p => eth_tx_p_i,
|
||||
tx_n => eth_tx_n_i
|
||||
);
|
||||
@ -241,7 +264,13 @@ begin
|
||||
mask => wishbone_masks
|
||||
);
|
||||
|
||||
eth_led_green <= '0';
|
||||
eth_led_orange <= '1';
|
||||
led_user <= '1';
|
||||
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;
|
||||
|
@ -16,6 +16,7 @@ library trashernet;
|
||||
use trashernet.trashernet_pkg.all;
|
||||
|
||||
library generics;
|
||||
use generics.all;
|
||||
use generics.wishbone_pkg.all;
|
||||
|
||||
entity trashernet_phy_wb is
|
||||
@ -45,9 +46,15 @@ architecture RTL of trashernet_phy_wb is
|
||||
signal phy_out : phy_out_t; -- PHY application IF (out)
|
||||
signal phy_in : phy_in_t; -- PHY application IF (in)
|
||||
|
||||
signal wb_adr : unsigned(2 downto 0);
|
||||
signal wb_adr : unsigned(2 downto 2);
|
||||
|
||||
signal status_register : std_logic_vector(31 downto 0);
|
||||
|
||||
signal rx_fifo_read : std_logic;
|
||||
signal rx_fifo_full : std_logic;
|
||||
signal rx_fifo_empty : std_logic;
|
||||
signal rx_fifo_data : std_logic_vector(7 downto 0);
|
||||
signal rx_fifo_usage : integer range 0 to 2047;
|
||||
begin
|
||||
trashernet_phy_inst : entity trashernet.trashernet_phy_cdc
|
||||
generic map(
|
||||
@ -65,22 +72,53 @@ begin
|
||||
tx_n => tx_n
|
||||
);
|
||||
|
||||
rx_fifo_inst : entity generics.fifo_block
|
||||
generic map(
|
||||
SIZE => 2047
|
||||
)
|
||||
port map(
|
||||
clk => clk,
|
||||
rst_a => '0',
|
||||
clr => rst,
|
||||
data_in => phy_out.rx_data,
|
||||
write => phy_out.rx_data_valid,
|
||||
commit => not phy_out.rx_active,
|
||||
abort => '0',
|
||||
full => rx_fifo_full,
|
||||
data_out => rx_fifo_data,
|
||||
data_first => open,
|
||||
empty => rx_fifo_empty,
|
||||
read => rx_fifo_read,
|
||||
usage => rx_fifo_usage
|
||||
);
|
||||
|
||||
wb_adr <= unsigned(wb_i.adr(wb_adr'range));
|
||||
wbif : process(clk, rst) is
|
||||
variable bytes_rxd : unsigned(15 downto 0);
|
||||
begin
|
||||
if rst then
|
||||
wb_o.ack <= '0';
|
||||
wb_o.ack <= '0';
|
||||
rx_fifo_read <= '0';
|
||||
bytes_rxd := (others => '0');
|
||||
|
||||
elsif rising_edge(clk) then
|
||||
wb_o.ack <= '0';
|
||||
wb_o.ack <= '0';
|
||||
rx_fifo_read <= '0';
|
||||
|
||||
if (phy_out.rx_data_valid = '1') then
|
||||
bytes_rxd := bytes_rxd + 1;
|
||||
end if;
|
||||
if (wb_i.cyc and wb_i.stb) then
|
||||
wb_o.ack <= '1';
|
||||
if wb_adr = 0 then
|
||||
wb_o.dat <= status_register;
|
||||
else
|
||||
wb_o.dat <= (others => '0');
|
||||
wb_o.dat(7 downto 0) <= phy_out.rx_data; -- TODO: data
|
||||
wb_o.dat <= (others => '0');
|
||||
|
||||
if wb_o.ack = '0' then
|
||||
rx_fifo_read <= '1';
|
||||
end if;
|
||||
wb_o.dat(7 downto 0) <= rx_fifo_data;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
@ -93,5 +131,5 @@ begin
|
||||
phy_in.tx_data_en <= '0';
|
||||
phy_in.tx_data <= (others => '0');
|
||||
|
||||
status_register <= (x"0000000" & "000" & phy_out.carrier_detect);
|
||||
status_register <= (x"0000" & x"000" & "000" & phy_out.carrier_detect);
|
||||
end architecture RTL;
|
||||
|
@ -39,7 +39,7 @@ entity fifo_block is
|
||||
read : in std_logic; -- Acknowledge that `data_out` was read. The word is removed and next one shifted from FIFO when `read and not empty`.
|
||||
|
||||
-- FIFO meta
|
||||
usage : out integer -- Usage counter
|
||||
usage : out integer range 0 to SIZE -- Usage counter
|
||||
);
|
||||
end fifo_block;
|
||||
|
||||
@ -68,6 +68,7 @@ begin
|
||||
read_pointer_last <= SIZE - 1;
|
||||
write_pointer_committed <= 0;
|
||||
current_is_first <= '1';
|
||||
usage <= 0;
|
||||
|
||||
elsif rising_edge(clk) then
|
||||
succesful_read := read and not empty;
|
||||
@ -109,6 +110,7 @@ begin
|
||||
if clr then
|
||||
read_pointer <= 0;
|
||||
write_pointer <= 0;
|
||||
read_pointer_last <= SIZE - 1;
|
||||
write_pointer_committed <= 0;
|
||||
current_is_first <= '1';
|
||||
usage <= 0;
|
||||
|
88
fpga/hdl/generics/ice40_components.vhd
Normal file
88
fpga/hdl/generics/ice40_components.vhd
Normal file
@ -0,0 +1,88 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
package ice40_components is
|
||||
component SB_PLL40_PAD
|
||||
generic(
|
||||
FEEDBACK_PATH : string;
|
||||
DIVR : std_logic_vector(3 downto 0);
|
||||
DIVF : std_logic_vector(6 downto 0);
|
||||
DIVQ : std_logic_vector(2 downto 0);
|
||||
FILTER_RANGE : std_logic_vector(2 downto 0)
|
||||
);
|
||||
port(
|
||||
RESETB : in std_logic;
|
||||
BYPASS : in std_logic;
|
||||
PACKAGEPIN : in std_logic;
|
||||
PLLOUTCORE : out std_logic
|
||||
);
|
||||
end component SB_PLL40_PAD;
|
||||
|
||||
component SB_PLL40_CORE
|
||||
generic(
|
||||
FEEDBACK_PATH : string := "SIMPLE";
|
||||
-- DELAY_ADJUSTMENT_MODE_FEEDBACK : string := "FIXED";
|
||||
-- DELAY_ADJUSTMENT_MODE_RELATIVE : string := "FIXED";
|
||||
-- PLLOUT_SELECT : string := "GENCLK";
|
||||
-- SHIFTREG_DIV_MODE : std_logic;
|
||||
-- FDA_FEEDBACK : std_logic_vector(3 downto 0) := "1111";
|
||||
-- FDA_RELATIVE : std_logic_vector(3 downto 0) := "1111";
|
||||
DIVR : std_logic_vector(3 downto 0);
|
||||
DIVF : std_logic_vector(6 downto 0);
|
||||
DIVQ : std_logic_vector(2 downto 0);
|
||||
FILTER_RANGE : std_logic_vector(2 downto 0)
|
||||
-- ENABLE_ICEGATE : std_logic := '0';
|
||||
-- TEST_MODE : std_logic := '0'
|
||||
);
|
||||
port(
|
||||
REFERENCECLK : in std_logic;
|
||||
-- PLLOUTCORE : out std_logic;
|
||||
PLLOUTGLOBAL : out std_logic;
|
||||
-- EXTFEEDBACK : in std_logic;
|
||||
-- DYNAMICDELAY : in std_logic_vector(7 downto 0);
|
||||
LOCK : out std_logic;
|
||||
BYPASS : in std_logic;
|
||||
RESETB : in std_logic
|
||||
-- LATCHINPUTVALUE : in std_logic;
|
||||
-- SDO : out std_logic;
|
||||
-- SDI : in std_logic;
|
||||
-- SCLK : in std_logic
|
||||
);
|
||||
end component SB_PLL40_CORE;
|
||||
|
||||
component SB_HFOSC
|
||||
generic(
|
||||
CLKHF_DIV : string
|
||||
);
|
||||
port(
|
||||
CLKHFPU : in std_logic;
|
||||
CLKHFEN : in std_logic;
|
||||
CLKHF : out std_logic
|
||||
);
|
||||
end component SB_HFOSC;
|
||||
|
||||
COMPONENT SB_IO IS
|
||||
GENERIC(
|
||||
PIN_TYPE : std_logic_vector(5 downto 0) := "000000";
|
||||
IO_STANDARD : string := "SB_LVDS_INPUT"
|
||||
);
|
||||
PORT(
|
||||
PACKAGE_PIN : in std_logic;
|
||||
LATCH_INPUT_VALUE : in std_logic;
|
||||
CLOCK_ENABLE : in std_logic;
|
||||
INPUT_CLK : in std_logic;
|
||||
OUTPUT_CLK : in std_logic;
|
||||
OUTPUT_ENABLE : in std_logic;
|
||||
D_OUT_0 : in std_logic;
|
||||
D_OUT_1 : in std_logic;
|
||||
D_IN_0 : out std_logic;
|
||||
D_IN_1 : out std_logic
|
||||
);
|
||||
END COMPONENT SB_IO;
|
||||
|
||||
component SB_GB
|
||||
port(
|
||||
USER_SIGNAL_TO_GLOBAL_BUFFER : in std_logic;
|
||||
GLOBAL_BUFFER_OUTPUT : out std_logic);
|
||||
end component;
|
||||
end package ice40_components;
|
@ -1 +1 @@
|
||||
Subproject commit da7e329939d12e853acbd7636701350babf5e3f4
|
||||
Subproject commit 21a0d0e69aeacf9747bfac0262e0d7ca30a691d9
|
Loading…
Reference in New Issue
Block a user