1
0
mirror of https://github.com/antonblanchard/microwatt.git synced 2026-03-10 12:28:45 +00:00

Merge pull request #212 from ozbenh/liteeth

liteeth: Hook up LiteX LiteEth ethernet controller
This commit is contained in:
Michael Neuling
2020-06-29 12:18:44 +10:00
committed by GitHub
15 changed files with 6161 additions and 2672 deletions

View File

@@ -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}]]

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

15
liteeth/liteeth.core Normal file
View 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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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');