fpga: Implement functional Ethernet controller
This commit is contained in:
parent
79b1153df7
commit
e81166a82c
@ -38,8 +38,8 @@ set_io eth_tx_p[1] 2
|
|||||||
set_io eth_tx_p[2] 4
|
set_io eth_tx_p[2] 4
|
||||||
set_io eth_tx_p[3] 3
|
set_io eth_tx_p[3] 3
|
||||||
|
|
||||||
set_io eth_led_green 40
|
set_io eth_led_green_n 40
|
||||||
set_io eth_led_orange 41
|
set_io eth_led_orange_n 41
|
||||||
|
|
||||||
set_io led_user 34
|
set_io led_user 34
|
||||||
|
|
||||||
|
@ -25,35 +25,35 @@ entity top is
|
|||||||
UART_BAUD : integer := 19200
|
UART_BAUD : integer := 19200
|
||||||
);
|
);
|
||||||
port(
|
port(
|
||||||
clk_50m : in std_logic; -- System clock
|
clk_50m : in std_logic; -- System clock
|
||||||
|
|
||||||
-- UART
|
-- UART
|
||||||
uart_tx : out std_logic; -- UART TX
|
uart_tx : out std_logic; -- UART TX
|
||||||
uart_rx : in std_logic; -- UART RX
|
uart_rx : in std_logic; -- UART RX
|
||||||
|
|
||||||
-- Trashernet
|
-- Trashernet
|
||||||
eth_rx_p : in std_logic; -- Ethernet RX+
|
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_p : out std_logic_vector(3 downto 0); -- Ethernet TX+
|
||||||
eth_tx_n : out std_logic_vector(3 downto 0); -- Ethernet TX-
|
eth_tx_n : out std_logic_vector(3 downto 0); -- Ethernet TX-
|
||||||
|
|
||||||
-- LEDs
|
-- LEDs
|
||||||
eth_led_green : out std_logic;
|
eth_led_green_n : out std_logic;
|
||||||
eth_led_orange : out std_logic;
|
eth_led_orange_n : out std_logic;
|
||||||
led_user : out std_logic; --
|
led_user : out std_logic; --
|
||||||
|
|
||||||
-- PSRAM IF
|
-- PSRAM IF
|
||||||
psram_ce_n : out std_logic;
|
psram_ce_n : out std_logic;
|
||||||
psram_sclk : 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
|
-- Config Flash
|
||||||
flash_ce_n : out std_logic;
|
flash_ce_n : out std_logic;
|
||||||
flash_sclk : 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
|
||||||
pmod : inout std_logic_vector(7 downto 0)
|
pmod : inout std_logic_vector(7 downto 0)
|
||||||
);
|
);
|
||||||
end entity top;
|
end entity top;
|
||||||
|
|
||||||
@ -69,6 +69,9 @@ architecture rtl of top is
|
|||||||
signal eth_tx_n_i : std_logic;
|
signal eth_tx_n_i : std_logic;
|
||||||
signal eth_rx_p_i : std_logic;
|
signal eth_rx_p_i : std_logic;
|
||||||
|
|
||||||
|
signal eth_led_green : std_logic;
|
||||||
|
signal eth_led_orange : std_logic;
|
||||||
|
|
||||||
-- System Timer
|
-- System Timer
|
||||||
signal irq_timer : std_logic;
|
signal irq_timer : std_logic;
|
||||||
|
|
||||||
@ -247,7 +250,9 @@ begin
|
|||||||
wb_i => wb_eth_i,
|
wb_i => wb_eth_i,
|
||||||
rx_p => eth_rx_p_i,
|
rx_p => eth_rx_p_i,
|
||||||
tx_p => eth_tx_p_i,
|
tx_p => eth_tx_p_i,
|
||||||
tx_n => eth_tx_n_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_p <= (others => eth_tx_p_i);
|
||||||
eth_tx_n <= (others => eth_tx_n_i);
|
eth_tx_n <= (others => eth_tx_n_i);
|
||||||
@ -264,9 +269,9 @@ begin
|
|||||||
mask => wishbone_masks
|
mask => wishbone_masks
|
||||||
);
|
);
|
||||||
|
|
||||||
eth_led_green <= uart_tx;
|
eth_led_green_n <= not eth_led_green;
|
||||||
eth_led_orange <= uart_rx;
|
eth_led_orange_n <= not eth_led_orange;
|
||||||
led_user <= not psram_ce_n;
|
led_user <= not uart_tx or not uart_rx;
|
||||||
|
|
||||||
flash_ce_n <= 'Z';
|
flash_ce_n <= 'Z';
|
||||||
flash_sclk <= 'Z';
|
flash_sclk <= 'Z';
|
||||||
|
@ -37,7 +37,10 @@ entity trashernet_phy_wb is
|
|||||||
-- Ethernet physical signals
|
-- Ethernet physical signals
|
||||||
rx_p : in std_logic;
|
rx_p : in std_logic;
|
||||||
tx_p : out std_logic;
|
tx_p : out std_logic;
|
||||||
tx_n : out std_logic
|
tx_n : out std_logic;
|
||||||
|
-- LEDs
|
||||||
|
led_tx : out std_logic;
|
||||||
|
led_rx : out std_logic
|
||||||
);
|
);
|
||||||
end entity trashernet_phy_wb;
|
end entity trashernet_phy_wb;
|
||||||
|
|
||||||
@ -46,6 +49,9 @@ architecture RTL of trashernet_phy_wb is
|
|||||||
signal phy_out : phy_out_t; -- PHY application IF (out)
|
signal phy_out : phy_out_t; -- PHY application IF (out)
|
||||||
signal phy_in : phy_in_t; -- PHY application IF (in)
|
signal phy_in : phy_in_t; -- PHY application IF (in)
|
||||||
|
|
||||||
|
signal mac_out : raw_mac_out_t; -- MAC application IF (out)
|
||||||
|
signal mac_in : raw_mac_in_t; -- MAC application IF (in)
|
||||||
|
|
||||||
signal wb_adr : unsigned(2 downto 2);
|
signal wb_adr : unsigned(2 downto 2);
|
||||||
|
|
||||||
signal status_register : std_logic_vector(31 downto 0);
|
signal status_register : std_logic_vector(31 downto 0);
|
||||||
@ -57,6 +63,11 @@ architecture RTL of trashernet_phy_wb is
|
|||||||
signal tx_fifo_commit : std_logic;
|
signal tx_fifo_commit : std_logic;
|
||||||
signal tx_fifo_empty : std_logic;
|
signal tx_fifo_empty : std_logic;
|
||||||
signal tx_fifo_data : std_logic_vector(7 downto 0);
|
signal tx_fifo_data : std_logic_vector(7 downto 0);
|
||||||
|
|
||||||
|
signal rx_fifo_empty : std_logic;
|
||||||
|
signal rx_bitcount : std_logic_vector(10 downto 0);
|
||||||
|
signal rx_fifo_block_count : std_logic_vector(rx_bitcount'range);
|
||||||
|
signal rx_block_next : std_logic;
|
||||||
begin
|
begin
|
||||||
trashernet_phy_inst : entity trashernet.trashernet_phy_cdc
|
trashernet_phy_inst : entity trashernet.trashernet_phy_cdc
|
||||||
generic map(
|
generic map(
|
||||||
@ -74,6 +85,16 @@ begin
|
|||||||
tx_n => tx_n
|
tx_n => tx_n
|
||||||
);
|
);
|
||||||
|
|
||||||
|
trashernet_raw_mac_inst : entity trashernet.trashernet_raw_mac
|
||||||
|
port map(
|
||||||
|
clk => clk,
|
||||||
|
rst => rst,
|
||||||
|
phy_out => phy_out,
|
||||||
|
phy_in => phy_in,
|
||||||
|
mac_out => mac_out,
|
||||||
|
mac_in => mac_in
|
||||||
|
);
|
||||||
|
|
||||||
rx_fifo_inst : entity generics.fifo_block
|
rx_fifo_inst : entity generics.fifo_block
|
||||||
generic map(
|
generic map(
|
||||||
SIZE => 2047
|
SIZE => 2047
|
||||||
@ -82,18 +103,48 @@ begin
|
|||||||
clk => clk,
|
clk => clk,
|
||||||
rst_a => '0',
|
rst_a => '0',
|
||||||
clr => rst,
|
clr => rst,
|
||||||
data_in => phy_out.rx_data,
|
data_in => mac_out.rx_mac_data,
|
||||||
write => phy_out.rx_data_valid,
|
write => mac_out.rx_mac_valid,
|
||||||
commit => not phy_out.rx_active,
|
commit => mac_out.rx_mac_crc_ok,
|
||||||
abort => '0',
|
abort => mac_out.rx_mac_crc_error,
|
||||||
full => open,
|
full => open,
|
||||||
data_out => rx_fifo_data,
|
data_out => rx_fifo_data,
|
||||||
data_first => open,
|
data_first => open,
|
||||||
empty => open,
|
empty => rx_fifo_empty,
|
||||||
read => rx_fifo_read,
|
read => rx_fifo_read,
|
||||||
usage => open
|
usage => open
|
||||||
);
|
);
|
||||||
|
|
||||||
|
fifo_inst : entity generics.fifo
|
||||||
|
generic map(
|
||||||
|
SIZE => 31
|
||||||
|
)
|
||||||
|
port map(
|
||||||
|
clk => clk,
|
||||||
|
rst_a => '0',
|
||||||
|
clr => rst,
|
||||||
|
data_in => rx_bitcount,
|
||||||
|
write => mac_out.rx_mac_crc_ok,
|
||||||
|
full => open,
|
||||||
|
data_out => rx_fifo_block_count,
|
||||||
|
empty => open,
|
||||||
|
read => rx_block_next,
|
||||||
|
usage => open
|
||||||
|
);
|
||||||
|
|
||||||
|
rxcount : process(rst, clk) is
|
||||||
|
begin
|
||||||
|
if rst then
|
||||||
|
rx_bitcount <= (others => '0');
|
||||||
|
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
if mac_out.rx_mac_crc_error or mac_out.rx_mac_crc_ok then
|
||||||
|
rx_bitcount <= (others => '0');
|
||||||
|
elsif mac_out.rx_mac_valid then
|
||||||
|
rx_bitcount <= std_logic_vector(unsigned(rx_bitcount) + 1);
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process rxcount;
|
||||||
tx_fifo_inst : entity generics.fifo_block
|
tx_fifo_inst : entity generics.fifo_block
|
||||||
generic map(
|
generic map(
|
||||||
SIZE => 2047
|
SIZE => 2047
|
||||||
@ -110,7 +161,7 @@ begin
|
|||||||
data_out => tx_fifo_data,
|
data_out => tx_fifo_data,
|
||||||
data_first => open,
|
data_first => open,
|
||||||
empty => tx_fifo_empty,
|
empty => tx_fifo_empty,
|
||||||
read => phy_out.tx_data_ack,
|
read => mac_out.tx_mac_data_ack,
|
||||||
usage => open
|
usage => open
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -122,12 +173,14 @@ begin
|
|||||||
rx_fifo_read <= '0';
|
rx_fifo_read <= '0';
|
||||||
tx_fifo_write <= '0';
|
tx_fifo_write <= '0';
|
||||||
tx_fifo_commit <= '0';
|
tx_fifo_commit <= '0';
|
||||||
|
rx_block_next <= '0';
|
||||||
|
|
||||||
elsif rising_edge(clk) then
|
elsif rising_edge(clk) then
|
||||||
wb_o.ack <= '0';
|
wb_o.ack <= '0';
|
||||||
rx_fifo_read <= '0';
|
rx_fifo_read <= '0';
|
||||||
tx_fifo_write <= '0';
|
tx_fifo_write <= '0';
|
||||||
tx_fifo_commit <= '0';
|
tx_fifo_commit <= '0';
|
||||||
|
rx_block_next <= '0';
|
||||||
|
|
||||||
if (wb_i.cyc and wb_i.stb) then
|
if (wb_i.cyc and wb_i.stb) then
|
||||||
wb_o.ack <= '1';
|
wb_o.ack <= '1';
|
||||||
@ -136,7 +189,8 @@ begin
|
|||||||
wb_o.dat <= status_register;
|
wb_o.dat <= status_register;
|
||||||
if wb_o.ack = '0' then
|
if wb_o.ack = '0' then
|
||||||
if wb_i.we = '1' then
|
if wb_i.we = '1' then
|
||||||
tx_fifo_commit <= '1';
|
tx_fifo_commit <= wb_i.dat(2);
|
||||||
|
rx_block_next <= wb_i.dat(1);
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
else
|
else
|
||||||
@ -159,8 +213,43 @@ begin
|
|||||||
wb_o.rty <= '1';
|
wb_o.rty <= '1';
|
||||||
wb_o.stall <= '0';
|
wb_o.stall <= '0';
|
||||||
|
|
||||||
phy_in.tx_data_en <= not tx_fifo_empty; -- FIXME: this does not care about inter-packet gaps indicated by `data_first`
|
mac_in.tx_mac_data_en <= not tx_fifo_empty; -- FIXME: this does not care about inter-packet gaps indicated by `data_first`
|
||||||
phy_in.tx_data <= tx_fifo_data;
|
mac_in.tx_mac_data <= tx_fifo_data;
|
||||||
|
|
||||||
status_register <= (x"0000" & x"000" & "000" & phy_out.carrier_detect);
|
status_register <= ("0" & x"0" & rx_fifo_block_count & -- 31..16
|
||||||
|
x"000" & "0" & (not tx_fifo_empty) & (not rx_fifo_empty) & phy_out.carrier_detect);
|
||||||
|
|
||||||
|
ledstretch : process(clk) is
|
||||||
|
constant CMAX : integer := integer(0.2 / (1.0 / real(F_CLK)));
|
||||||
|
variable cnt : integer range 0 to CMAX;
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if cnt = 0 then
|
||||||
|
led_rx <= phy_out.carrier_detect;
|
||||||
|
if phy_out.rx_active then
|
||||||
|
cnt := CMAX;
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
led_rx <= '0';
|
||||||
|
cnt := cnt - 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process ledstretch;
|
||||||
|
|
||||||
|
ledstretch2 : process(clk) is
|
||||||
|
constant CMAX : integer := integer(0.2 / (1.0 / real(F_CLK)));
|
||||||
|
variable cnt : integer range 0 to CMAX;
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if cnt = 0 then
|
||||||
|
led_tx <= '0';
|
||||||
|
if phy_out.tx_active then
|
||||||
|
cnt := CMAX;
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
led_tx <= '1';
|
||||||
|
cnt := cnt - 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process ledstretch2;
|
||||||
end architecture RTL;
|
end architecture RTL;
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 21a0d0e69aeacf9747bfac0262e0d7ca30a691d9
|
Subproject commit 206332f3d1c1f5b704bad09b1380a8aed8b736aa
|
Loading…
Reference in New Issue
Block a user