mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-03-10 04:24:30 +00:00
Merge pull request #212 from ozbenh/liteeth
liteeth: Hook up LiteX LiteEth ethernet controller
This commit is contained in:
104
fpga/arty_a7.xdc
104
fpga/arty_a7.xdc
@@ -4,7 +4,7 @@
|
||||
|
||||
set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { ext_clk }];
|
||||
|
||||
set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { ext_rst }];
|
||||
set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { ext_rst_n }];
|
||||
|
||||
set_property -dict { PACKAGE_PIN D10 IOSTANDARD LVCMOS33 } [get_ports { uart_main_tx }];
|
||||
set_property -dict { PACKAGE_PIN A9 IOSTANDARD LVCMOS33 } [get_ports { uart_main_rx }];
|
||||
@@ -26,6 +26,15 @@ set_property -dict { PACKAGE_PIN E1 IOSTANDARD LVCMOS33 } [get_ports { led0_b }
|
||||
set_property -dict { PACKAGE_PIN F6 IOSTANDARD LVCMOS33 } [get_ports { led0_g }];
|
||||
set_property -dict { PACKAGE_PIN G6 IOSTANDARD LVCMOS33 } [get_ports { led0_r }];
|
||||
|
||||
################################################################################
|
||||
# Normal LEDs
|
||||
################################################################################
|
||||
|
||||
set_property -dict { PACKAGE_PIN H5 IOSTANDARD LVCMOS33 } [get_ports { led4 }];
|
||||
set_property -dict { PACKAGE_PIN J5 IOSTANDARD LVCMOS33 } [get_ports { led5 }];
|
||||
set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports { led6 }];
|
||||
set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports { led7 }];
|
||||
|
||||
################################################################################
|
||||
# SPI Flash
|
||||
################################################################################
|
||||
@@ -41,6 +50,85 @@ set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports { spi_flas
|
||||
set_property IOB true [get_cells -hierarchical -filter {NAME =~*/spi_rxtx/*sck_1*}]
|
||||
set_property IOB true [get_cells -hierarchical -filter {NAME =~*/spi_rxtx/input_delay_1.dat_i_l*}]
|
||||
|
||||
################################################################################
|
||||
# Ethernet (generated by LiteX)
|
||||
################################################################################
|
||||
|
||||
# eth_ref_clk:0
|
||||
set_property LOC G18 [get_ports {eth_ref_clk}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_ref_clk}]
|
||||
|
||||
# eth_clocks:0.tx
|
||||
set_property LOC H16 [get_ports {eth_clocks_tx}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_clocks_tx}]
|
||||
|
||||
# eth_clocks:0.rx
|
||||
set_property LOC F15 [get_ports {eth_clocks_rx}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_clocks_rx}]
|
||||
|
||||
# eth:0.rst_n
|
||||
set_property LOC C16 [get_ports {eth_rst_n}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rst_n}]
|
||||
|
||||
# eth:0.mdio
|
||||
set_property LOC K13 [get_ports {eth_mdio}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_mdio}]
|
||||
|
||||
# eth:0.mdc
|
||||
set_property LOC F16 [get_ports {eth_mdc}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_mdc}]
|
||||
|
||||
# eth:0.rx_dv
|
||||
set_property LOC G16 [get_ports {eth_rx_dv}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_dv}]
|
||||
|
||||
# eth:0.rx_er
|
||||
set_property LOC C17 [get_ports {eth_rx_er}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_er}]
|
||||
|
||||
# eth:0.rx_data
|
||||
set_property LOC D18 [get_ports {eth_rx_data[0]}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_data[0]}]
|
||||
|
||||
# eth:0.rx_data
|
||||
set_property LOC E17 [get_ports {eth_rx_data[1]}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_data[1]}]
|
||||
|
||||
# eth:0.rx_data
|
||||
set_property LOC E18 [get_ports {eth_rx_data[2]}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_data[2]}]
|
||||
|
||||
# eth:0.rx_data
|
||||
set_property LOC G17 [get_ports {eth_rx_data[3]}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_data[3]}]
|
||||
|
||||
# eth:0.tx_en
|
||||
set_property LOC H15 [get_ports {eth_tx_en}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_en}]
|
||||
|
||||
# eth:0.tx_data
|
||||
set_property LOC H14 [get_ports {eth_tx_data[0]}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_data[0]}]
|
||||
|
||||
# eth:0.tx_data
|
||||
set_property LOC J14 [get_ports {eth_tx_data[1]}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_data[1]}]
|
||||
|
||||
# eth:0.tx_data
|
||||
set_property LOC J13 [get_ports {eth_tx_data[2]}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_data[2]}]
|
||||
|
||||
# eth:0.tx_data
|
||||
set_property LOC H17 [get_ports {eth_tx_data[3]}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_data[3]}]
|
||||
|
||||
# eth:0.col
|
||||
set_property LOC D17 [get_ports {eth_col}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_col}]
|
||||
|
||||
# eth:0.crs
|
||||
set_property LOC G14 [get_ports {eth_crs}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_crs}]
|
||||
|
||||
################################################################################
|
||||
# DRAM (generated by LiteX)
|
||||
@@ -326,10 +414,22 @@ set_property CONFIG_MODE SPIx4 [current_design]
|
||||
|
||||
create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports { ext_clk }];
|
||||
|
||||
create_clock -name eth_rx_clk -period 40.0 [get_ports { eth_clocks_rx }]
|
||||
|
||||
create_clock -name eth_tx_clk -period 40.0 [get_ports { eth_clocks_tx }]
|
||||
|
||||
set_clock_groups -group [get_clocks -include_generated_clocks -of [get_nets system_clk]] -group [get_clocks -include_generated_clocks -of [get_nets eth_clocks_rx]] -asynchronous
|
||||
|
||||
set_clock_groups -group [get_clocks -include_generated_clocks -of [get_nets system_clk]] -group [get_clocks -include_generated_clocks -of [get_nets eth_clocks_tx]] -asynchronous
|
||||
|
||||
set_clock_groups -group [get_clocks -include_generated_clocks -of [get_nets eth_clocks_rx]] -group [get_clocks -include_generated_clocks -of [get_nets eth_clocks_tx]] -asynchronous
|
||||
|
||||
################################################################################
|
||||
# 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}]]
|
||||
|
||||
@@ -21,11 +21,12 @@ entity toplevel is
|
||||
SPI_FLASH_OFFSET : integer := 4194304;
|
||||
SPI_FLASH_DEF_CKDV : natural := 1;
|
||||
SPI_FLASH_DEF_QUAD : boolean := true;
|
||||
LOG_LENGTH : natural := 512
|
||||
LOG_LENGTH : natural := 512;
|
||||
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;
|
||||
@@ -35,6 +36,10 @@ entity toplevel is
|
||||
led0_b : out std_ulogic;
|
||||
led0_g : out std_ulogic;
|
||||
led0_r : 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 +49,21 @@ entity toplevel is
|
||||
spi_flash_wp_n : inout std_ulogic;
|
||||
spi_flash_hold_n : inout std_ulogic;
|
||||
|
||||
-- Ethernet
|
||||
eth_ref_clk : out std_ulogic;
|
||||
eth_clocks_tx : in std_ulogic;
|
||||
eth_clocks_rx : in std_ulogic;
|
||||
eth_rst_n : out std_ulogic;
|
||||
eth_mdio : inout std_ulogic;
|
||||
eth_mdc : out std_ulogic;
|
||||
eth_rx_dv : in std_ulogic;
|
||||
eth_rx_er : in std_ulogic;
|
||||
eth_rx_data : in std_ulogic_vector(3 downto 0);
|
||||
eth_tx_en : out std_ulogic;
|
||||
eth_tx_data : out std_ulogic_vector(3 downto 0);
|
||||
eth_col : in std_ulogic;
|
||||
eth_crs : in std_ulogic;
|
||||
|
||||
-- DRAM wires
|
||||
ddram_a : out std_ulogic_vector(13 downto 0);
|
||||
ddram_ba : out std_ulogic_vector(2 downto 0);
|
||||
@@ -70,20 +90,27 @@ 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;
|
||||
signal eth_clk_locked : 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
|
||||
-- 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_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;
|
||||
@@ -142,7 +169,8 @@ begin
|
||||
SPI_FLASH_OFFSET => SPI_FLASH_OFFSET,
|
||||
SPI_FLASH_DEF_CKDV => SPI_FLASH_DEF_CKDV,
|
||||
SPI_FLASH_DEF_QUAD => SPI_FLASH_DEF_QUAD,
|
||||
LOG_LENGTH => LOG_LENGTH
|
||||
LOG_LENGTH => LOG_LENGTH,
|
||||
USE_LITEETH => USE_LITEETH
|
||||
)
|
||||
port map (
|
||||
-- System signals
|
||||
@@ -160,6 +188,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,
|
||||
@@ -167,6 +198,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
|
||||
);
|
||||
|
||||
@@ -217,8 +249,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 and eth_clk_locked,
|
||||
ext_rst_in => ext_rst_n,
|
||||
pll_rst_out => pll_rst,
|
||||
rst_out => soc_rst
|
||||
);
|
||||
@@ -257,6 +289,7 @@ begin
|
||||
signal dram_init_done : std_ulogic;
|
||||
signal dram_init_error : std_ulogic;
|
||||
signal dram_sys_rst : std_ulogic;
|
||||
signal rst_gen_rst : std_ulogic;
|
||||
begin
|
||||
|
||||
-- Eventually dig out the frequency from the generator
|
||||
@@ -272,12 +305,22 @@ begin
|
||||
port map(
|
||||
ext_clk => ext_clk,
|
||||
pll_clk => system_clk,
|
||||
pll_locked_in => '1',
|
||||
ext_rst_in => ext_rst,
|
||||
pll_locked_in => eth_clk_locked,
|
||||
ext_rst_in => ext_rst_n,
|
||||
pll_rst_out => pll_rst,
|
||||
rst_out => open
|
||||
rst_out => rst_gen_rst
|
||||
);
|
||||
|
||||
-- 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 eth_clk_locked or not system_clk_locked;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
dram: entity work.litedram_wrapper
|
||||
generic map(
|
||||
DRAM_ABITS => 24,
|
||||
@@ -289,14 +332,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,
|
||||
|
||||
@@ -326,6 +369,141 @@ begin
|
||||
|
||||
end generate;
|
||||
|
||||
has_liteeth : if USE_LITEETH generate
|
||||
|
||||
component liteeth_core port (
|
||||
sys_clock : in std_ulogic;
|
||||
sys_reset : in std_ulogic;
|
||||
mii_eth_clocks_tx : in std_ulogic;
|
||||
mii_eth_clocks_rx : in std_ulogic;
|
||||
mii_eth_rst_n : out std_ulogic;
|
||||
mii_eth_mdio : in std_ulogic;
|
||||
mii_eth_mdc : out std_ulogic;
|
||||
mii_eth_rx_dv : in std_ulogic;
|
||||
mii_eth_rx_er : in std_ulogic;
|
||||
mii_eth_rx_data : in std_ulogic_vector(3 downto 0);
|
||||
mii_eth_tx_en : out std_ulogic;
|
||||
mii_eth_tx_data : out std_ulogic_vector(3 downto 0);
|
||||
mii_eth_col : in std_ulogic;
|
||||
mii_eth_crs : in std_ulogic;
|
||||
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);
|
||||
|
||||
-- Change this to use a PLL instead of a BUFR to generate the 25Mhz
|
||||
-- reference clock to the PHY.
|
||||
constant USE_PLL : boolean := false;
|
||||
begin
|
||||
eth_use_pll: if USE_PLL generate
|
||||
signal eth_clk_25 : std_ulogic;
|
||||
signal eth_clkfb : std_ulogic;
|
||||
begin
|
||||
pll_eth : PLLE2_BASE
|
||||
generic map (
|
||||
BANDWIDTH => "OPTIMIZED",
|
||||
CLKFBOUT_MULT => 16,
|
||||
CLKIN1_PERIOD => 10.0,
|
||||
CLKOUT0_DIVIDE => 64,
|
||||
DIVCLK_DIVIDE => 1,
|
||||
STARTUP_WAIT => "FALSE")
|
||||
port map (
|
||||
CLKOUT0 => eth_clk_25,
|
||||
CLKOUT1 => open,
|
||||
CLKOUT2 => open,
|
||||
CLKOUT3 => open,
|
||||
CLKOUT4 => open,
|
||||
CLKOUT5 => open,
|
||||
CLKFBOUT => eth_clkfb,
|
||||
LOCKED => eth_clk_locked,
|
||||
CLKIN1 => ext_clk,
|
||||
PWRDWN => '0',
|
||||
RST => pll_rst,
|
||||
CLKFBIN => eth_clkfb);
|
||||
|
||||
eth_clk_buf: BUFG
|
||||
port map (
|
||||
I => eth_clk_25,
|
||||
O => eth_ref_clk
|
||||
);
|
||||
end generate;
|
||||
|
||||
eth_use_bufr: if not USE_PLL generate
|
||||
eth_clk_div: BUFR
|
||||
generic map (
|
||||
BUFR_DIVIDE => "4"
|
||||
)
|
||||
port map (
|
||||
I => system_clk,
|
||||
O => eth_ref_clk,
|
||||
CE => '1',
|
||||
CLR => '0'
|
||||
);
|
||||
eth_clk_locked <= '1';
|
||||
end generate;
|
||||
|
||||
liteeth : liteeth_core
|
||||
port map(
|
||||
sys_clock => system_clk,
|
||||
sys_reset => soc_rst,
|
||||
mii_eth_clocks_tx => eth_clocks_tx,
|
||||
mii_eth_clocks_rx => eth_clocks_rx,
|
||||
mii_eth_rst_n => eth_rst_n,
|
||||
mii_eth_mdio => eth_mdio,
|
||||
mii_eth_mdc => eth_mdc,
|
||||
mii_eth_rx_dv => eth_rx_dv,
|
||||
mii_eth_rx_er => eth_rx_er,
|
||||
mii_eth_rx_data => eth_rx_data,
|
||||
mii_eth_tx_en => eth_tx_en,
|
||||
mii_eth_tx_data => eth_tx_data,
|
||||
mii_eth_col => eth_col,
|
||||
mii_eth_crs => eth_crs,
|
||||
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
|
||||
eth_clk_locked <= '1';
|
||||
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;
|
||||
|
||||
leds_pwm : process(system_clk)
|
||||
begin
|
||||
if rising_edge(system_clk) then
|
||||
@@ -342,4 +520,9 @@ begin
|
||||
end if;
|
||||
end process;
|
||||
|
||||
led4 <= system_clk_locked;
|
||||
led5 <= eth_clk_locked;
|
||||
led6 <= not soc_rst;
|
||||
led7 <= not spi_flash_cs_n;
|
||||
|
||||
end architecture behaviour;
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#define XICS_ICS_BASE 0xc0005000 /* Interrupt controller */
|
||||
#define SPI_FCTRL_BASE 0xc0006000 /* SPI flash controller registers */
|
||||
#define DRAM_CTRL_BASE 0xc8000000 /* LiteDRAM control registers */
|
||||
#define LETH_CSR_BASE 0xc8020000 /* LiteEth CSR registers */
|
||||
#define LETH_SRAM_BASE 0xc8030000 /* LiteEth MMIO space */
|
||||
#define SPI_FLASH_BASE 0xf0000000 /* SPI Flash memory map */
|
||||
#define DRAM_INIT_BASE 0xff000000 /* Internal DRAM init firmware */
|
||||
|
||||
@@ -22,6 +24,7 @@
|
||||
* Interrupt numbers
|
||||
*/
|
||||
#define IRQ_UART0 0
|
||||
#define IRQ_ETHERNET 1
|
||||
|
||||
/*
|
||||
* Register definitions for the syscon registers
|
||||
@@ -33,6 +36,7 @@
|
||||
#define SYS_REG_INFO_HAS_DRAM (1ull << 1)
|
||||
#define SYS_REG_INFO_HAS_BRAM (1ull << 2)
|
||||
#define SYS_REG_INFO_HAS_SPI_FLASH (1ull << 3)
|
||||
#define SYS_REG_INFO_HAS_LITEETH (1ull << 4)
|
||||
#define SYS_REG_BRAMINFO 0x10
|
||||
#define SYS_REG_BRAMINFO_SIZE_MASK 0xfffffffffffffull
|
||||
#define SYS_REG_DRAMINFO 0x18
|
||||
|
||||
@@ -260,6 +260,8 @@ uint64_t main(void)
|
||||
printf("BRAM ");
|
||||
if (ftr & SYS_REG_INFO_HAS_SPI_FLASH)
|
||||
printf("SPIFLASH ");
|
||||
if (ftr & SYS_REG_INFO_HAS_LITEETH)
|
||||
printf("ETHERNET ");
|
||||
printf("\n");
|
||||
if (ftr & SYS_REG_INFO_HAS_BRAM) {
|
||||
val = readq(SYSCON_BASE + SYS_REG_BRAMINFO) & SYS_REG_BRAMINFO_SIZE_MASK;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
27
liteeth/fusesoc-add-files.py
Normal file
27
liteeth/fusesoc-add-files.py
Normal file
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/python3
|
||||
from fusesoc.capi2.generator import Generator
|
||||
import os
|
||||
import sys
|
||||
import pathlib
|
||||
|
||||
class LiteEthGenerator(Generator):
|
||||
def run(self):
|
||||
board = self.config.get('board')
|
||||
|
||||
# Collect a bunch of directory path
|
||||
script_dir = os.path.dirname(sys.argv[0])
|
||||
gen_dir = os.path.join(script_dir, "generated", board)
|
||||
|
||||
print("Adding LiteEth for board... ", board)
|
||||
|
||||
# Add files to fusesoc
|
||||
files = []
|
||||
f = os.path.join(gen_dir, "liteeth_core.v")
|
||||
files.append({f : {'file_type' : 'verilogSource'}})
|
||||
|
||||
self.add_files(files)
|
||||
|
||||
g = LiteEthGenerator()
|
||||
g.run()
|
||||
g.write()
|
||||
|
||||
15
liteeth/gen-src/arty.yml
Normal file
15
liteeth/gen-src/arty.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
# This file is Copyright (c) 2020 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||
# License: BSD
|
||||
|
||||
# PHY ----------------------------------------------------------------------
|
||||
phy: LiteEthPHYMII
|
||||
vendor: xilinx
|
||||
# Core ---------------------------------------------------------------------
|
||||
clk_freq: 100e6
|
||||
core: wishbone
|
||||
endianness: little
|
||||
|
||||
soc:
|
||||
mem_map:
|
||||
ethmac: 0x00010000
|
||||
csr_data_width: 32
|
||||
30
liteeth/gen-src/generate.sh
Executable file
30
liteeth/gen-src/generate.sh
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
|
||||
TARGETS=arty
|
||||
|
||||
ME=$(realpath $0)
|
||||
echo ME=$ME
|
||||
MY_PATH=$(dirname $ME)
|
||||
echo MYPATH=$MY_PATH
|
||||
PARENT_PATH=$(realpath $MY_PATH/..)
|
||||
echo PARENT=$PARENT_PATH
|
||||
BUILD_PATH=$PARENT_PATH/build
|
||||
mkdir -p $BUILD_PATH
|
||||
GEN_PATH=$PARENT_PATH/generated
|
||||
mkdir -p $GEN_PATH
|
||||
|
||||
for i in $TARGETS
|
||||
do
|
||||
TARGET_BUILD_PATH=$BUILD_PATH/$i
|
||||
TARGET_GEN_PATH=$GEN_PATH/$i
|
||||
rm -rf $TARGET_BUILD_PATH
|
||||
rm -rf $TARGET_GEN_PATH
|
||||
mkdir -p $TARGET_BUILD_PATH
|
||||
mkdir -p $TARGET_GEN_PATH
|
||||
|
||||
echo "Generating $i in $TARGET_BUILD_PATH"
|
||||
liteeth_gen --output-dir=$TARGET_BUILD_PATH $MY_PATH/$i.yml
|
||||
|
||||
cp $TARGET_BUILD_PATH/gateware/liteeth_core.v $TARGET_GEN_PATH/
|
||||
done
|
||||
|
||||
3057
liteeth/generated/arty/liteeth_core.v
Normal file
3057
liteeth/generated/arty/liteeth_core.v
Normal file
File diff suppressed because it is too large
Load Diff
15
liteeth/liteeth.core
Normal file
15
liteeth/liteeth.core
Normal file
@@ -0,0 +1,15 @@
|
||||
CAPI=2:
|
||||
|
||||
name : :microwatt:liteeth:0
|
||||
|
||||
generators:
|
||||
liteeth_gen:
|
||||
interpreter: python3
|
||||
command: fusesoc-add-files.py
|
||||
description: Generate a liteeth ethernet controller
|
||||
usage: |
|
||||
liteeth_gen adds the pre-generated LiteX LiteEth memory controller
|
||||
based on the board type.
|
||||
|
||||
Parameters:
|
||||
board: The board type (arty)
|
||||
@@ -100,6 +100,9 @@ filesets:
|
||||
litedram:
|
||||
depend : [":microwatt:litedram"]
|
||||
|
||||
liteeth:
|
||||
depend : [":microwatt:liteeth"]
|
||||
|
||||
targets:
|
||||
nexys_a7:
|
||||
default_tool: vivado
|
||||
@@ -141,7 +144,7 @@ targets:
|
||||
- no_bram
|
||||
- spi_flash_offset=10485760
|
||||
- log_length=2048
|
||||
generate: [dram_nexys_video]
|
||||
generate: [litedram_nexys_video]
|
||||
tools:
|
||||
vivado: {part : xc7a200tsbg484-1}
|
||||
toplevel : toplevel
|
||||
@@ -163,16 +166,17 @@ targets:
|
||||
|
||||
arty_a7-35:
|
||||
default_tool: vivado
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, litedram, xilinx_specific]
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, litedram, liteeth, xilinx_specific]
|
||||
parameters :
|
||||
- memory_size
|
||||
- ram_init_file
|
||||
- use_litedram=true
|
||||
- use_liteeth=true
|
||||
- disable_flatten_core
|
||||
- no_bram
|
||||
- spi_flash_offset=3145728
|
||||
- log_length=512
|
||||
generate: [dram_arty]
|
||||
generate: [litedram_arty, liteeth_arty]
|
||||
tools:
|
||||
vivado: {part : xc7a35ticsg324-1L}
|
||||
toplevel : toplevel
|
||||
@@ -194,16 +198,17 @@ targets:
|
||||
|
||||
arty_a7-100:
|
||||
default_tool: vivado
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, litedram, xilinx_specific]
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, litedram, liteeth, xilinx_specific]
|
||||
parameters:
|
||||
- memory_size
|
||||
- ram_init_file
|
||||
- use_litedram=true
|
||||
- use_liteeth=true
|
||||
- disable_flatten_core
|
||||
- no_bram
|
||||
- spi_flash_offset=4194304
|
||||
- log_length=2048
|
||||
generate: [dram_arty]
|
||||
generate: [litedram_arty, liteeth_arty]
|
||||
tools:
|
||||
vivado: {part : xc7a100ticsg324-1L}
|
||||
toplevel : toplevel
|
||||
@@ -230,11 +235,15 @@ targets:
|
||||
toplevel: core
|
||||
|
||||
generate:
|
||||
dram_arty:
|
||||
litedram_arty:
|
||||
generator: litedram_gen
|
||||
parameters: {board : arty}
|
||||
|
||||
dram_nexys_video:
|
||||
liteeth_arty:
|
||||
generator: liteeth_gen
|
||||
parameters: {board : arty}
|
||||
|
||||
litedram_nexys_video:
|
||||
generator: litedram_gen
|
||||
parameters: {board : nexys-video}
|
||||
|
||||
@@ -279,6 +288,12 @@ parameters:
|
||||
paramtype : generic
|
||||
default : false
|
||||
|
||||
use_liteeth:
|
||||
datatype : bool
|
||||
description : Use liteEth
|
||||
paramtype : generic
|
||||
default : false
|
||||
|
||||
no_bram:
|
||||
datatype : bool
|
||||
description : No internal block RAM (only DRAM and init code carrying payload)
|
||||
|
||||
27
soc.vhdl
27
soc.vhdl
@@ -29,6 +29,12 @@ use work.wishbone_types.all;
|
||||
|
||||
-- External IO bus:
|
||||
-- 0xc8000000: LiteDRAM control (CSRs)
|
||||
-- 0xc8020000: LiteEth CSRs (*)
|
||||
-- 0xc8030000: LiteEth MMIO (*)
|
||||
|
||||
-- (*) LiteEth must be a single aligned 32KB block as the CSRs and MMIOs
|
||||
-- are actually decoded as a single wishbone which LiteEth will
|
||||
-- internally split based on bit 16.
|
||||
|
||||
-- (**) DRAM init code is currently special and goes to the external
|
||||
-- IO bus, this will be fixed when it's moved out of litedram and
|
||||
@@ -37,6 +43,7 @@ use work.wishbone_types.all;
|
||||
-- Interrupt numbers:
|
||||
--
|
||||
-- 0 : UART0
|
||||
-- 1 : Ethernet
|
||||
|
||||
entity soc is
|
||||
generic (
|
||||
@@ -53,7 +60,8 @@ entity soc is
|
||||
SPI_FLASH_OFFSET : integer := 0;
|
||||
SPI_FLASH_DEF_CKDV : natural := 2;
|
||||
SPI_FLASH_DEF_QUAD : boolean := false;
|
||||
LOG_LENGTH : natural := 512
|
||||
LOG_LENGTH : natural := 512;
|
||||
HAS_LITEETH : boolean := false
|
||||
);
|
||||
port(
|
||||
rst : in std_ulogic;
|
||||
@@ -68,6 +76,10 @@ entity soc is
|
||||
wb_ext_io_out : in wb_io_slave_out := wb_io_slave_out_init;
|
||||
wb_ext_is_dram_csr : out std_ulogic;
|
||||
wb_ext_is_dram_init : out std_ulogic;
|
||||
wb_ext_is_eth : out std_ulogic;
|
||||
|
||||
-- External interrupts
|
||||
ext_irq_eth : in std_ulogic := '0';
|
||||
|
||||
-- UART0 signals:
|
||||
uart0_txd : out std_ulogic;
|
||||
@@ -181,6 +193,7 @@ architecture behaviour of soc is
|
||||
SLAVE_IO_EXTERNAL,
|
||||
SLAVE_IO_NONE);
|
||||
signal slave_io_dbg : slave_io_type;
|
||||
|
||||
begin
|
||||
|
||||
resets: process(system_clk)
|
||||
@@ -298,6 +311,7 @@ begin
|
||||
wb_io_in.cyc <= wb_master_out.cyc;
|
||||
wb_master_in <= wb_io_out;
|
||||
end case;
|
||||
|
||||
end process slave_top_intercon;
|
||||
|
||||
-- IO wishbone slave 64->32 bits converter
|
||||
@@ -499,6 +513,7 @@ begin
|
||||
|
||||
wb_ext_is_dram_csr <= '0';
|
||||
wb_ext_is_dram_init <= '0';
|
||||
wb_ext_is_eth <= '0';
|
||||
|
||||
-- Default response, ack & return all 1's
|
||||
wb_sio_in.dat <= (others => '1');
|
||||
@@ -520,6 +535,12 @@ begin
|
||||
elsif wb_sio_out.adr(23 downto 16) = x"00" and HAS_DRAM then
|
||||
wb_ext_is_dram_csr <= '1';
|
||||
ext_valid := true;
|
||||
elsif wb_sio_out.adr(23 downto 16) = x"02" and HAS_LITEETH then
|
||||
wb_ext_is_eth <= '1';
|
||||
ext_valid := true;
|
||||
elsif wb_sio_out.adr(23 downto 16) = x"03" and HAS_LITEETH then
|
||||
wb_ext_is_eth <= '1';
|
||||
ext_valid := true;
|
||||
end if;
|
||||
if ext_valid then
|
||||
wb_ext_io_in.cyc <= wb_sio_out.cyc;
|
||||
@@ -564,7 +585,8 @@ begin
|
||||
DRAM_INIT_SIZE => DRAM_INIT_SIZE,
|
||||
CLK_FREQ => CLK_FREQ,
|
||||
HAS_SPI_FLASH => HAS_SPI_FLASH,
|
||||
SPI_FLASH_OFFSET => SPI_FLASH_OFFSET
|
||||
SPI_FLASH_OFFSET => SPI_FLASH_OFFSET,
|
||||
HAS_LITEETH => HAS_LITEETH
|
||||
)
|
||||
port map(
|
||||
clk => system_clk,
|
||||
@@ -657,6 +679,7 @@ begin
|
||||
begin
|
||||
int_level_in <= (others => '0');
|
||||
int_level_in(0) <= uart0_irq;
|
||||
int_level_in(1) <= ext_irq_eth;
|
||||
end process;
|
||||
|
||||
-- BRAM Memory slave
|
||||
|
||||
14
syscon.vhdl
14
syscon.vhdl
@@ -16,7 +16,8 @@ entity syscon is
|
||||
DRAM_SIZE : integer;
|
||||
DRAM_INIT_SIZE : integer;
|
||||
HAS_SPI_FLASH : boolean;
|
||||
SPI_FLASH_OFFSET : integer
|
||||
SPI_FLASH_OFFSET : integer;
|
||||
HAS_LITEETH : boolean
|
||||
);
|
||||
port (
|
||||
clk : in std_ulogic;
|
||||
@@ -56,6 +57,7 @@ architecture behaviour of syscon is
|
||||
constant SYS_REG_INFO_HAS_DRAM : integer := 1;
|
||||
constant SYS_REG_INFO_HAS_BRAM : integer := 2;
|
||||
constant SYS_REG_INFO_HAS_SPIF : integer := 3;
|
||||
constant SYS_REG_INFO_HAS_LETH : integer := 4;
|
||||
|
||||
-- BRAMINFO contains the BRAM size in the bottom 52 bits
|
||||
-- DRAMINFO contains the DRAM size if any in the bottom 52 bits
|
||||
@@ -89,6 +91,7 @@ architecture behaviour of syscon is
|
||||
signal info_has_bram : std_ulogic;
|
||||
signal info_has_uart : std_ulogic;
|
||||
signal info_has_spif : std_ulogic;
|
||||
signal info_has_leth : std_ulogic;
|
||||
signal info_clk : std_ulogic_vector(39 downto 0);
|
||||
signal info_fl_off : std_ulogic_vector(31 downto 0);
|
||||
|
||||
@@ -102,16 +105,19 @@ begin
|
||||
core_reset <= reg_ctrl(SYS_REG_CTRL_CORE_RESET);
|
||||
|
||||
-- Info register is hard wired
|
||||
info_has_uart <= '1' when HAS_UART else '0';
|
||||
info_has_dram <= '1' when HAS_DRAM else '0';
|
||||
info_has_uart <= '1' when HAS_UART else '0';
|
||||
info_has_dram <= '1' when HAS_DRAM else '0';
|
||||
info_has_bram <= '1' when BRAM_SIZE /= 0 else '0';
|
||||
info_has_spif <= '1' when HAS_SPI_FLASH else '0';
|
||||
info_has_spif <= '1' when HAS_SPI_FLASH else '0';
|
||||
info_has_leth <= '1' when HAS_LITEETH else '0';
|
||||
info_clk <= std_ulogic_vector(to_unsigned(CLK_FREQ, 40));
|
||||
reg_info <= (SYS_REG_INFO_HAS_UART => info_has_uart,
|
||||
SYS_REG_INFO_HAS_DRAM => info_has_dram,
|
||||
SYS_REG_INFO_HAS_BRAM => info_has_bram,
|
||||
SYS_REG_INFO_HAS_SPIF => info_has_spif,
|
||||
SYS_REG_INFO_HAS_LETH => info_has_leth,
|
||||
others => '0');
|
||||
|
||||
reg_braminfo <= x"000" & std_ulogic_vector(to_unsigned(BRAM_SIZE, 52));
|
||||
reg_draminfo <= x"000" & std_ulogic_vector(to_unsigned(DRAM_SIZE, 52)) when HAS_DRAM
|
||||
else (others => '0');
|
||||
|
||||
Reference in New Issue
Block a user