Add liteeth support to Nexys Video

Signed-off-by: Anton Blanchard <anton@linux.ibm.com>
pull/310/head
Anton Blanchard 3 years ago committed by Anton Blanchard
parent cf6df4f17f
commit 458dfe01a6

@ -4,7 +4,7 @@

set_property -dict {PACKAGE_PIN R4 IOSTANDARD LVCMOS33} [get_ports ext_clk]

set_property -dict {PACKAGE_PIN G4 IOSTANDARD LVCMOS15} [get_ports ext_rst]
set_property -dict {PACKAGE_PIN G4 IOSTANDARD LVCMOS15} [get_ports ext_rst_n]

set_property -dict {PACKAGE_PIN AA19 IOSTANDARD LVCMOS33} [get_ports uart_main_tx]
set_property -dict {PACKAGE_PIN V18 IOSTANDARD LVCMOS33} [get_ports uart_main_rx]
@ -22,8 +22,14 @@ set_property -dict {PACKAGE_PIN V18 IOSTANDARD LVCMOS33} [get_ports uart_main_rx
# LEDs
################################################################################

set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 } [get_ports { led0 }];
set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { led1 }];
set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS25 } [get_ports { led0 }];
set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS25 } [get_ports { led1 }];
set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS25 } [get_ports { led2 }];
set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS25 } [get_ports { led3 }];
set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS25 } [get_ports { led4 }];
set_property -dict { PACKAGE_PIN W16 IOSTANDARD LVCMOS25 } [get_ports { led5 }];
set_property -dict { PACKAGE_PIN W15 IOSTANDARD LVCMOS25 } [get_ports { led6 }];
set_property -dict { PACKAGE_PIN Y13 IOSTANDARD LVCMOS25 } [get_ports { led7 }];

################################################################################
# SPI Flash
@ -35,6 +41,75 @@ set_property -dict { PACKAGE_PIN R22 IOSTANDARD LVCMOS33 } [get_ports { spi_flas
set_property -dict { PACKAGE_PIN P21 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_wp_n }];
set_property -dict { PACKAGE_PIN R21 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_hold_n }];

################################################################################
# Ethernet (generated by LiteX)
################################################################################

# eth_clocks:0.tx
set_property LOC AA14 [get_ports {eth_clocks_tx}]
set_property IOSTANDARD LVCMOS25 [get_ports {eth_clocks_tx}]

# eth_clocks:0.rx
set_property LOC V13 [get_ports {eth_clocks_rx}]
set_property IOSTANDARD LVCMOS25 [get_ports {eth_clocks_rx}]

# eth:0.rst_n
set_property LOC U7 [get_ports {eth_rst_n}]
set_property IOSTANDARD LVCMOS25 [get_ports {eth_rst_n}]
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rst_n}]

# eth:0.int_n
set_property LOC Y14 [get_ports {eth_int_n}]
set_property IOSTANDARD LVCMOS25 [get_ports {eth_int_n}]

# eth:0.mdio
set_property LOC Y16 [get_ports {eth_mdio}]
set_property IOSTANDARD LVCMOS25 [get_ports {eth_mdio}]

# eth:0.mdc
set_property LOC AA16 [get_ports {eth_mdc}]
set_property IOSTANDARD LVCMOS25 [get_ports {eth_mdc}]

# eth:0.rx_ctl
set_property LOC W10 [get_ports {eth_rx_ctl}]
set_property IOSTANDARD LVCMOS25 [get_ports {eth_rx_ctl}]

# eth:0.rx_data
set_property LOC AB16 [get_ports {eth_rx_data[0]}]
set_property IOSTANDARD LVCMOS25 [get_ports {eth_rx_data[0]}]

# eth:0.rx_data
set_property LOC AA15 [get_ports {eth_rx_data[1]}]
set_property IOSTANDARD LVCMOS25 [get_ports {eth_rx_data[1]}]

# eth:0.rx_data
set_property LOC AB15 [get_ports {eth_rx_data[2]}]
set_property IOSTANDARD LVCMOS25 [get_ports {eth_rx_data[2]}]

# eth:0.rx_data
set_property LOC AB11 [get_ports {eth_rx_data[3]}]
set_property IOSTANDARD LVCMOS25 [get_ports {eth_rx_data[3]}]

# eth:0.tx_ctl
set_property LOC V10 [get_ports {eth_tx_ctl}]
set_property IOSTANDARD LVCMOS25 [get_ports {eth_tx_ctl}]

# eth:0.tx_data
set_property LOC Y12 [get_ports {eth_tx_data[0]}]
set_property IOSTANDARD LVCMOS25 [get_ports {eth_tx_data[0]}]

# eth:0.tx_data
set_property LOC W12 [get_ports {eth_tx_data[1]}]
set_property IOSTANDARD LVCMOS25 [get_ports {eth_tx_data[1]}]

# eth:0.tx_data
set_property LOC W11 [get_ports {eth_tx_data[2]}]
set_property IOSTANDARD LVCMOS25 [get_ports {eth_tx_data[2]}]

# eth:0.tx_data
set_property LOC Y11 [get_ports {eth_tx_data[3]}]
set_property IOSTANDARD LVCMOS25 [get_ports {eth_tx_data[3]}]

################################################################################
# DRAM (generated by LiteX)
################################################################################
@ -315,10 +390,16 @@ set_property CONFIG_MODE SPIx4 [current_design]

create_clock -name sys_clk_pin -period 10.00 [get_ports { ext_clk }];

create_clock -name eth_clocks_rx -period 8.0 [get_ports { eth_clocks_rx }]

set_clock_groups -asynchronous -group [get_clocks sys_clk_pin -include_generated_clocks] -group [get_clocks eth_clocks_rx -include_generated_clocks]

################################################################################
# False path constraints (from LiteX as they relate to LiteDRAM)
# False path constraints (from LiteX as they relate to LiteDRAM and LiteEth)
################################################################################

set_false_path -quiet -through [get_nets -hierarchical -filter {mr_ff == TRUE}]

set_false_path -quiet -to [get_pins -filter {REF_PIN_NAME == PRE} -of_objects [get_cells -hierarchical -filter {ars_ff1 == TRUE || ars_ff2 == TRUE}]]

set_max_delay 2 -quiet -from [get_pins -filter {REF_PIN_NAME == C} -of_objects [get_cells -hierarchical -filter {ars_ff1 == TRUE}]] -to [get_pins -filter {REF_PIN_NAME == D} -of_objects [get_cells -hierarchical -filter {ars_ff2 == TRUE}]]

@ -23,19 +23,26 @@ entity toplevel is
SPI_FLASH_DEF_CKDV : natural := 1;
SPI_FLASH_DEF_QUAD : boolean := true;
LOG_LENGTH : natural := 2048;
UART_IS_16550 : boolean := true
UART_IS_16550 : boolean := true;
USE_LITEETH : boolean := false
);
port(
ext_clk : in std_ulogic;
ext_rst : in std_ulogic;
ext_rst_n : in std_ulogic;

-- UART0 signals:
uart_main_tx : out std_ulogic;
uart_main_rx : in std_ulogic;

-- LEDs
led0 : out std_logic;
led1 : out std_logic;
-- LEDs
led0 : out std_ulogic;
led1 : out std_ulogic;
led2 : out std_ulogic;
led3 : out std_ulogic;
led4 : out std_ulogic;
led5 : out std_ulogic;
led6 : out std_ulogic;
led7 : out std_ulogic;

-- SPI
spi_flash_cs_n : out std_ulogic;
@ -44,6 +51,18 @@ entity toplevel is
spi_flash_wp_n : inout std_ulogic;
spi_flash_hold_n : inout std_ulogic;

-- Ethernet
eth_clocks_tx : out std_ulogic;
eth_clocks_rx : in std_ulogic;
eth_rst_n : out std_ulogic;
eth_int_n : in std_ulogic;
eth_mdio : inout std_ulogic;
eth_mdc : out std_ulogic;
eth_rx_ctl : in std_ulogic;
eth_rx_data : in std_ulogic_vector(3 downto 0);
eth_tx_ctl : out std_ulogic;
eth_tx_data : out std_ulogic_vector(3 downto 0);

-- DRAM wires
ddram_a : out std_logic_vector(14 downto 0);
ddram_ba : out std_logic_vector(2 downto 0);
@ -69,18 +88,26 @@ architecture behaviour of toplevel is
signal pll_rst : std_ulogic;

-- Internal clock signals:
signal system_clk : std_ulogic;
signal system_clk : std_ulogic;
signal system_clk_locked : std_ulogic;

-- External IOs from the SoC
signal wb_ext_io_in : wb_io_master_out;
signal wb_ext_io_out : wb_io_slave_out;
signal wb_ext_is_dram_csr : std_ulogic;
signal wb_ext_is_dram_init : std_ulogic;
signal wb_ext_is_eth : std_ulogic;

-- DRAM main data wishbone connection
signal wb_dram_in : wishbone_master_out;
signal wb_dram_out : wishbone_slave_out;

-- DRAM control wishbone connection
signal wb_ext_io_in : wb_io_master_out;
signal wb_ext_io_out : wb_io_slave_out;
signal wb_ext_is_dram_csr : std_ulogic;
signal wb_ext_is_dram_init : std_ulogic;
signal wb_dram_ctrl_out : wb_io_slave_out := wb_io_slave_out_init;

-- LiteEth connection
signal ext_irq_eth : std_ulogic;
signal wb_eth_out : wb_io_slave_out := wb_io_slave_out_init;

-- Control/status
signal core_alt_reset : std_ulogic;
@ -134,7 +161,8 @@ begin
SPI_FLASH_DEF_CKDV => SPI_FLASH_DEF_CKDV,
SPI_FLASH_DEF_QUAD => SPI_FLASH_DEF_QUAD,
LOG_LENGTH => LOG_LENGTH,
UART0_IS_16550 => UART_IS_16550
UART0_IS_16550 => UART_IS_16550,
HAS_LITEETH => USE_LITEETH
)
port map (
-- System signals
@ -152,6 +180,9 @@ begin
spi_flash_sdat_oe => spi_sdat_oe,
spi_flash_sdat_i => spi_sdat_i,

-- External interrupts
ext_irq_eth => ext_irq_eth,

-- DRAM wishbone
wb_dram_in => wb_dram_in,
wb_dram_out => wb_dram_out,
@ -159,6 +190,7 @@ begin
wb_ext_io_out => wb_ext_io_out,
wb_ext_is_dram_csr => wb_ext_is_dram_csr,
wb_ext_is_dram_init => wb_ext_is_dram_init,
wb_ext_is_eth => wb_ext_is_eth,
alt_reset => core_alt_reset
);

@ -198,8 +230,8 @@ begin
port map(
ext_clk => ext_clk,
pll_clk => system_clk,
pll_locked_in => system_clk_locked,
ext_rst_in => ext_rst,
pll_locked_in => system_clk_locked,
ext_rst_in => ext_rst_n,
pll_rst_out => pll_rst,
rst_out => soc_rst
);
@ -218,6 +250,7 @@ begin

led0 <= '1';
led1 <= not soc_rst;
led2 <= '0';
core_alt_reset <= '0';

-- Vivado barfs on those differential signals if left
@ -252,12 +285,22 @@ begin
port map(
ext_clk => ext_clk,
pll_clk => system_clk,
pll_locked_in => '1',
ext_rst_in => ext_rst,
pll_locked_in => '1',
ext_rst_in => ext_rst_n,
pll_rst_out => pll_rst,
rst_out => open
rst_out => open
);

-- Generate SoC reset
soc_rst_gen: process(system_clk)
begin
if ext_rst_n = '0' then
soc_rst <= '1';
elsif rising_edge(system_clk) then
soc_rst <= dram_sys_rst or not system_clk_locked;
end if;
end process;

dram: entity work.litedram_wrapper
generic map(
DRAM_ABITS => 25,
@ -271,14 +314,14 @@ begin
clk_in => ext_clk,
rst => pll_rst,
system_clk => system_clk,
system_reset => soc_rst,
system_reset => dram_sys_rst,
core_alt_reset => core_alt_reset,
pll_locked => system_clk_locked,

wb_in => wb_dram_in,
wb_out => wb_dram_out,
wb_ctrl_in => wb_ext_io_in,
wb_ctrl_out => wb_ext_io_out,
wb_ctrl_out => wb_dram_ctrl_out,
wb_ctrl_is_csr => wb_ext_is_dram_csr,
wb_ctrl_is_init => wb_ext_is_dram_init,

@ -302,8 +345,96 @@ begin
ddram_reset_n => ddram_reset_n
);

led0 <= dram_init_done and not dram_init_error;
led0 <= not dram_init_done;
led1 <= dram_init_error; -- Make it blink ?
led2 <= dram_init_done and not dram_init_error;

end generate;

has_liteeth : if USE_LITEETH generate

component liteeth_core port (
sys_clock : in std_ulogic;
sys_reset : in std_ulogic;
rgmii_eth_clocks_tx : out std_ulogic;
rgmii_eth_clocks_rx : in std_ulogic;
rgmii_eth_rst_n : out std_ulogic;
rgmii_eth_int_n : in std_ulogic;
rgmii_eth_mdio : inout std_ulogic;
rgmii_eth_mdc : out std_ulogic;
rgmii_eth_rx_ctl : in std_ulogic;
rgmii_eth_rx_data : in std_ulogic_vector(3 downto 0);
rgmii_eth_tx_ctl : out std_ulogic;
rgmii_eth_tx_data : out std_ulogic_vector(3 downto 0);
wishbone_adr : in std_ulogic_vector(29 downto 0);
wishbone_dat_w : in std_ulogic_vector(31 downto 0);
wishbone_dat_r : out std_ulogic_vector(31 downto 0);
wishbone_sel : in std_ulogic_vector(3 downto 0);
wishbone_cyc : in std_ulogic;
wishbone_stb : in std_ulogic;
wishbone_ack : out std_ulogic;
wishbone_we : in std_ulogic;
wishbone_cti : in std_ulogic_vector(2 downto 0);
wishbone_bte : in std_ulogic_vector(1 downto 0);
wishbone_err : out std_ulogic;
interrupt : out std_ulogic
);
end component;

signal wb_eth_cyc : std_ulogic;
signal wb_eth_adr : std_ulogic_vector(29 downto 0);

begin
liteeth : liteeth_core
port map(
sys_clock => system_clk,
sys_reset => soc_rst,
rgmii_eth_clocks_tx => eth_clocks_tx,
rgmii_eth_clocks_rx => eth_clocks_rx,
rgmii_eth_rst_n => eth_rst_n,
rgmii_eth_int_n => eth_int_n,
rgmii_eth_mdio => eth_mdio,
rgmii_eth_mdc => eth_mdc,
rgmii_eth_rx_ctl => eth_rx_ctl,
rgmii_eth_rx_data => eth_rx_data,
rgmii_eth_tx_ctl => eth_tx_ctl,
rgmii_eth_tx_data => eth_tx_data,
wishbone_adr => wb_eth_adr,
wishbone_dat_w => wb_ext_io_in.dat,
wishbone_dat_r => wb_eth_out.dat,
wishbone_sel => wb_ext_io_in.sel,
wishbone_cyc => wb_eth_cyc,
wishbone_stb => wb_ext_io_in.stb,
wishbone_ack => wb_eth_out.ack,
wishbone_we => wb_ext_io_in.we,
wishbone_cti => "000",
wishbone_bte => "00",
wishbone_err => open,
interrupt => ext_irq_eth
);

-- Gate cyc with "chip select" from soc
wb_eth_cyc <= wb_ext_io_in.cyc and wb_ext_is_eth;

-- Remove top address bits as liteeth decoder doesn't know about them
wb_eth_adr <= x"000" & "000" & wb_ext_io_in.adr(16 downto 2);

-- LiteETH isn't pipelined
wb_eth_out.stall <= not wb_eth_out.ack;

end generate;

no_liteeth : if not USE_LITEETH generate
ext_irq_eth <= '0';
end generate;

-- Mux WB response on the IO bus
wb_ext_io_out <= wb_eth_out when wb_ext_is_eth = '1' else
wb_dram_ctrl_out;

led4 <= system_clk_locked;
led5 <= '1';
led6 <= not soc_rst;
led7 <= '0';

end architecture behaviour;

@ -1,6 +1,6 @@
#!/bin/bash

TARGETS=arty
TARGETS="arty nexys-video"

ME=$(realpath $0)
echo ME=$ME

@ -0,0 +1,15 @@
# This file is Copyright (c) 2020 Florent Kermarrec <florent@enjoy-digital.fr>
# License: BSD

# PHY ----------------------------------------------------------------------
phy: LiteEthS7PHYRGMII
vendor: xilinx
# Core ---------------------------------------------------------------------
clk_freq: 125e6
core: wishbone
endianness: little

soc:
mem_map:
ethmac: 0x00010000
csr_data_width: 32

@ -12,4 +12,4 @@ generators:
based on the board type.

Parameters:
board: The board type (arty)
board: The board type (arty, nexys-video)

@ -228,11 +228,12 @@ targets:

nexys_video:
default_tool: vivado
filesets: [core, nexys_video, soc, fpga, debug_xilinx, litedram, uart16550, xilinx_specific]
filesets: [core, nexys_video, soc, fpga, debug_xilinx, litedram, liteeth, uart16550, xilinx_specific]
parameters:
- memory_size
- ram_init_file
- use_litedram=true
- use_liteeth=true
- disable_flatten_core
- no_bram
- spi_flash_offset=10485760
@ -240,7 +241,7 @@ targets:
- uart_is_16550
- has_fpu
- has_btc
generate: [litedram_nexys_video]
generate: [litedram_nexys_video, liteeth_nexys_video]
tools:
vivado: {part : xc7a200tsbg484-1}
toplevel : toplevel
@ -370,6 +371,10 @@ generate:
generator: litedram_gen
parameters: {board : nexys-video}

liteeth_nexys_video:
generator: liteeth_gen
parameters: {board : nexys-video}

litedram_acorn_cle_215:
generator: litedram_gen
parameters: {board : acorn-cle-215}

Loading…
Cancel
Save