mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-02-26 08:43:26 +00:00
arty_a7: Add litesdcard interface
This adds litesdcard.v generated from the litex/litesdcard project, along with logic in top-arty.vhdl to connect it into the system. There is now a DMA wishbone coming in to soc.vhdl which is narrower than the other wishbone masters (it has 32-bit data rather than 64-bit) so there is a widening/narrowing adapter between it and the main wishbone master arbiter. Also, litesdcard generates a non-pipelined wishbone for its DMA connection, which needs to be converted to a pipelined wishbone. We have a latch on both the incoming and outgoing sides of the wishbone in order to help make timing (at the cost of two extra cycles of latency). litesdcard generates an interrupt signal which is wired up to input 3 of the ICS (IRQ 19). Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
This commit is contained in:
@@ -72,6 +72,19 @@ set_property IOB true [get_cells -hierarchical -filter {NAME =~*/spi_rxtx/input_
|
||||
#set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVCMOS33 } [get_ports { pmod_ja_9 }];
|
||||
#set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { pmod_ja_10 }];
|
||||
|
||||
# connection to Digilent PmodSD on JA
|
||||
set_property -dict { PACKAGE_PIN G13 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[3] }];
|
||||
set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_cmd }];
|
||||
set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[0] }];
|
||||
set_property -dict { PACKAGE_PIN D12 IOSTANDARD LVCMOS33 SLEW FAST } [get_ports { sdcard_clk }];
|
||||
set_property -dict { PACKAGE_PIN D13 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[1] }];
|
||||
set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[2] }];
|
||||
set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVCMOS33 } [get_ports { sdcard_cd }];
|
||||
#set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { sdcard_wp }];
|
||||
|
||||
# Put registers into IOBs to improve timing
|
||||
set_property IOB true [get_cells -hierarchical -filter {NAME =~*.litesdcard/sdcard_*}]
|
||||
|
||||
################################################################################
|
||||
# PMOD header JB (high-speed, no protection resisters)
|
||||
################################################################################
|
||||
@@ -85,6 +98,16 @@ set_property IOB true [get_cells -hierarchical -filter {NAME =~*/spi_rxtx/input_
|
||||
#set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_9 }];
|
||||
#set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_10 }];
|
||||
|
||||
# connection to Digilent PmodSD on JB
|
||||
#set_property -dict { PACKAGE_PIN E15 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[3] }];
|
||||
#set_property -dict { PACKAGE_PIN E16 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_cmd }];
|
||||
#set_property -dict { PACKAGE_PIN D15 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[0] }];
|
||||
#set_property -dict { PACKAGE_PIN C15 IOSTANDARD LVCMOS33 SLEW FAST } [get_ports { sdcard_clk }];
|
||||
#set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[1] }];
|
||||
#set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[2] }];
|
||||
#set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { sdcard_cd }];
|
||||
#set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { sdcard_wp }];
|
||||
|
||||
################################################################################
|
||||
# PMOD header JC (high-speed, no protection resisters)
|
||||
################################################################################
|
||||
|
||||
@@ -26,7 +26,8 @@ entity toplevel is
|
||||
LOG_LENGTH : natural := 512;
|
||||
USE_LITEETH : boolean := false;
|
||||
UART_IS_16550 : boolean := false;
|
||||
HAS_UART1 : boolean := true
|
||||
HAS_UART1 : boolean := true;
|
||||
USE_LITESDCARD : boolean := false
|
||||
);
|
||||
port(
|
||||
ext_clk : in std_ulogic;
|
||||
@@ -74,6 +75,12 @@ entity toplevel is
|
||||
eth_col : in std_ulogic;
|
||||
eth_crs : in std_ulogic;
|
||||
|
||||
-- SD card
|
||||
sdcard_data : inout std_ulogic_vector(3 downto 0);
|
||||
sdcard_cmd : inout std_ulogic;
|
||||
sdcard_clk : out std_ulogic;
|
||||
sdcard_cd : in std_ulogic;
|
||||
|
||||
-- DRAM wires
|
||||
ddram_a : out std_ulogic_vector(13 downto 0);
|
||||
ddram_ba : out std_ulogic_vector(2 downto 0);
|
||||
@@ -110,6 +117,7 @@ architecture behaviour of toplevel is
|
||||
signal wb_ext_is_dram_csr : std_ulogic;
|
||||
signal wb_ext_is_dram_init : std_ulogic;
|
||||
signal wb_ext_is_eth : std_ulogic;
|
||||
signal wb_ext_is_sdcard : std_ulogic;
|
||||
|
||||
-- DRAM main data wishbone connection
|
||||
signal wb_dram_in : wishbone_master_out;
|
||||
@@ -122,6 +130,16 @@ architecture behaviour of toplevel is
|
||||
signal ext_irq_eth : std_ulogic;
|
||||
signal wb_eth_out : wb_io_slave_out := wb_io_slave_out_init;
|
||||
|
||||
-- LiteSDCard connection
|
||||
signal ext_irq_sdcard : std_ulogic := '0';
|
||||
signal wb_sdcard_out : wb_io_slave_out := wb_io_slave_out_init;
|
||||
signal wb_sddma_out : wb_io_master_out := wb_io_master_out_init;
|
||||
signal wb_sddma_in : wb_io_slave_out;
|
||||
signal wb_sddma_nr : wb_io_master_out;
|
||||
signal wb_sddma_ir : wb_io_slave_out;
|
||||
-- for conversion from non-pipelined wishbone to pipelined
|
||||
signal wb_sddma_stb_sent : std_ulogic;
|
||||
|
||||
-- Control/status
|
||||
signal core_alt_reset : std_ulogic;
|
||||
|
||||
@@ -184,7 +202,8 @@ begin
|
||||
LOG_LENGTH => LOG_LENGTH,
|
||||
HAS_LITEETH => USE_LITEETH,
|
||||
UART0_IS_16550 => UART_IS_16550,
|
||||
HAS_UART1 => HAS_UART1
|
||||
HAS_UART1 => HAS_UART1,
|
||||
HAS_SD_CARD => USE_LITESDCARD
|
||||
)
|
||||
port map (
|
||||
-- System signals
|
||||
@@ -208,15 +227,24 @@ begin
|
||||
|
||||
-- External interrupts
|
||||
ext_irq_eth => ext_irq_eth,
|
||||
ext_irq_sdcard => ext_irq_sdcard,
|
||||
|
||||
-- DRAM wishbone
|
||||
wb_dram_in => wb_dram_in,
|
||||
wb_dram_out => wb_dram_out,
|
||||
|
||||
-- IO wishbone
|
||||
wb_ext_io_in => wb_ext_io_in,
|
||||
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,
|
||||
wb_ext_is_sdcard => wb_ext_is_sdcard,
|
||||
|
||||
-- DMA wishbone
|
||||
wishbone_dma_in => wb_sddma_in,
|
||||
wishbone_dma_out => wb_sddma_out,
|
||||
|
||||
alt_reset => core_alt_reset
|
||||
);
|
||||
|
||||
@@ -523,8 +551,113 @@ begin
|
||||
ext_irq_eth <= '0';
|
||||
end generate;
|
||||
|
||||
-- SD card pmod
|
||||
has_sdcard : if USE_LITESDCARD generate
|
||||
component litesdcard_core port (
|
||||
clk : in std_ulogic;
|
||||
rst : in std_ulogic;
|
||||
-- wishbone for accessing control registers
|
||||
wb_ctrl_adr : in std_ulogic_vector(29 downto 0);
|
||||
wb_ctrl_dat_w : in std_ulogic_vector(31 downto 0);
|
||||
wb_ctrl_dat_r : out std_ulogic_vector(31 downto 0);
|
||||
wb_ctrl_sel : in std_ulogic_vector(3 downto 0);
|
||||
wb_ctrl_cyc : in std_ulogic;
|
||||
wb_ctrl_stb : in std_ulogic;
|
||||
wb_ctrl_ack : out std_ulogic;
|
||||
wb_ctrl_we : in std_ulogic;
|
||||
wb_ctrl_cti : in std_ulogic_vector(2 downto 0);
|
||||
wb_ctrl_bte : in std_ulogic_vector(1 downto 0);
|
||||
wb_ctrl_err : out std_ulogic;
|
||||
-- wishbone for SD card core to use for DMA
|
||||
wb_dma_adr : out std_ulogic_vector(29 downto 0);
|
||||
wb_dma_dat_w : out std_ulogic_vector(31 downto 0);
|
||||
wb_dma_dat_r : in std_ulogic_vector(31 downto 0);
|
||||
wb_dma_sel : out std_ulogic_vector(3 downto 0);
|
||||
wb_dma_cyc : out std_ulogic;
|
||||
wb_dma_stb : out std_ulogic;
|
||||
wb_dma_ack : in std_ulogic;
|
||||
wb_dma_we : out std_ulogic;
|
||||
wb_dma_cti : out std_ulogic_vector(2 downto 0);
|
||||
wb_dma_bte : out std_ulogic_vector(1 downto 0);
|
||||
wb_dma_err : in std_ulogic;
|
||||
-- connections to SD card
|
||||
sdcard_data : inout std_ulogic_vector(3 downto 0);
|
||||
sdcard_cmd : inout std_ulogic;
|
||||
sdcard_clk : out std_ulogic;
|
||||
sdcard_cd : in std_ulogic;
|
||||
irq : out std_ulogic
|
||||
);
|
||||
end component;
|
||||
|
||||
signal wb_sdcard_cyc : std_ulogic;
|
||||
signal wb_sdcard_adr : std_ulogic_vector(29 downto 0);
|
||||
|
||||
begin
|
||||
litesdcard : litesdcard_core
|
||||
port map (
|
||||
clk => system_clk,
|
||||
rst => soc_rst,
|
||||
wb_ctrl_adr => wb_sdcard_adr,
|
||||
wb_ctrl_dat_w => wb_ext_io_in.dat,
|
||||
wb_ctrl_dat_r => wb_sdcard_out.dat,
|
||||
wb_ctrl_sel => wb_ext_io_in.sel,
|
||||
wb_ctrl_cyc => wb_sdcard_cyc,
|
||||
wb_ctrl_stb => wb_ext_io_in.stb,
|
||||
wb_ctrl_ack => wb_sdcard_out.ack,
|
||||
wb_ctrl_we => wb_ext_io_in.we,
|
||||
wb_ctrl_cti => "000",
|
||||
wb_ctrl_bte => "00",
|
||||
wb_ctrl_err => open,
|
||||
wb_dma_adr => wb_sddma_nr.adr,
|
||||
wb_dma_dat_w => wb_sddma_nr.dat,
|
||||
wb_dma_dat_r => wb_sddma_ir.dat,
|
||||
wb_dma_sel => wb_sddma_nr.sel,
|
||||
wb_dma_cyc => wb_sddma_nr.cyc,
|
||||
wb_dma_stb => wb_sddma_nr.stb,
|
||||
wb_dma_ack => wb_sddma_ir.ack,
|
||||
wb_dma_we => wb_sddma_nr.we,
|
||||
wb_dma_cti => open,
|
||||
wb_dma_bte => open,
|
||||
wb_dma_err => '0',
|
||||
sdcard_data => sdcard_data,
|
||||
sdcard_cmd => sdcard_cmd,
|
||||
sdcard_clk => sdcard_clk,
|
||||
sdcard_cd => sdcard_cd,
|
||||
irq => ext_irq_sdcard
|
||||
);
|
||||
|
||||
-- Gate cyc with chip select from SoC
|
||||
wb_sdcard_cyc <= wb_ext_io_in.cyc and wb_ext_is_sdcard;
|
||||
|
||||
wb_sdcard_adr <= x"0000" & wb_ext_io_in.adr(15 downto 2);
|
||||
|
||||
wb_sdcard_out.stall <= not wb_sdcard_out.ack;
|
||||
|
||||
-- Convert non-pipelined DMA wishbone to pipelined by suppressing
|
||||
-- non-acknowledged strobes
|
||||
process(system_clk)
|
||||
begin
|
||||
if rising_edge(system_clk) then
|
||||
wb_sddma_out <= wb_sddma_nr;
|
||||
if wb_sddma_stb_sent = '1' or
|
||||
(wb_sddma_out.stb = '1' and wb_sddma_in.stall = '0') then
|
||||
wb_sddma_out.stb <= '0';
|
||||
end if;
|
||||
if wb_sddma_nr.cyc = '0' or wb_sddma_ir.ack = '1' then
|
||||
wb_sddma_stb_sent <= '0';
|
||||
elsif wb_sddma_in.stall = '0' then
|
||||
wb_sddma_stb_sent <= wb_sddma_nr.stb;
|
||||
end if;
|
||||
wb_sddma_ir <= wb_sddma_in;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
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;
|
||||
wb_ext_io_out <= wb_eth_out when wb_ext_is_eth = '1' else
|
||||
wb_sdcard_out when wb_ext_is_sdcard = '1' else
|
||||
wb_dram_ctrl_out;
|
||||
|
||||
leds_pwm : process(system_clk)
|
||||
begin
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#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 LSDC_CSR_BASE 0xc8040000 /* LiteSDCard MMIO space */
|
||||
#define SPI_FLASH_BASE 0xf0000000 /* SPI Flash memory map */
|
||||
#define DRAM_INIT_BASE 0xff000000 /* Internal DRAM init firmware */
|
||||
|
||||
@@ -40,6 +41,7 @@
|
||||
#define SYS_REG_INFO_HAS_LARGE_SYSCON (1ull << 5)
|
||||
#define SYS_REG_INFO_HAS_UART1 (1ull << 6)
|
||||
#define SYS_REG_INFO_HAS_ARTB (1ull << 7)
|
||||
#define SYS_REG_INFO_HAS_LITESDCARD (1ull << 8)
|
||||
#define SYS_REG_BRAMINFO 0x10
|
||||
#define SYS_REG_BRAMINFO_SIZE_MASK 0xfffffffffffffull
|
||||
#define SYS_REG_DRAMINFO 0x18
|
||||
|
||||
27
litesdcard/fusesoc-add-files.py
Normal file
27
litesdcard/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 LiteSDCardGenerator(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 LiteSDCard for board... ", board)
|
||||
|
||||
# Add files to fusesoc
|
||||
files = []
|
||||
f = os.path.join(gen_dir, "litesdcard_core.v")
|
||||
files.append({f : {'file_type' : 'verilogSource'}})
|
||||
|
||||
self.add_files(files)
|
||||
|
||||
g = LiteSDCardGenerator()
|
||||
g.run()
|
||||
g.write()
|
||||
|
||||
35
litesdcard/gen-src/generate.sh
Executable file
35
litesdcard/gen-src/generate.sh
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/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
|
||||
|
||||
# Note litesdcard/gen.py doesn't parse a YAML file, instead it takes
|
||||
# a --vendor=xxx parameter, where xxx = xilinx or lattice. If we
|
||||
# want to generate litesdcard for ecp5 we'll have to invent a way to
|
||||
# map arty to xilinx and ecp5 to lattice
|
||||
|
||||
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"
|
||||
(cd $TARGET_BUILD_PATH && litesdcard_gen)
|
||||
|
||||
cp $TARGET_BUILD_PATH/build/gateware/litesdcard_core.v $TARGET_GEN_PATH/
|
||||
done
|
||||
|
||||
4159
litesdcard/generated/arty/litesdcard_core.v
Normal file
4159
litesdcard/generated/arty/litesdcard_core.v
Normal file
File diff suppressed because it is too large
Load Diff
15
litesdcard/litesdcard.core
Normal file
15
litesdcard/litesdcard.core
Normal file
@@ -0,0 +1,15 @@
|
||||
CAPI=2:
|
||||
|
||||
name : :microwatt:litesdcard:0
|
||||
|
||||
generators:
|
||||
litesdcard_gen:
|
||||
interpreter: python3
|
||||
command: fusesoc-add-files.py
|
||||
description: Generate a litesdcard SD-card controller
|
||||
usage: |
|
||||
litesdcard_gen adds the pre-generated LiteX LiteSDCard SD-card controller
|
||||
based on the board type.
|
||||
|
||||
Parameters:
|
||||
board: The board type (arty)
|
||||
@@ -116,6 +116,9 @@ filesets:
|
||||
liteeth:
|
||||
depend : [":microwatt:liteeth"]
|
||||
|
||||
litesdcard:
|
||||
depend : [":microwatt:litesdcard"]
|
||||
|
||||
uart16550:
|
||||
depend : ["::uart16550"]
|
||||
|
||||
@@ -243,7 +246,7 @@ targets:
|
||||
|
||||
arty_a7-35-nodram:
|
||||
default_tool: vivado
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, uart16550, xilinx_specific]
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, uart16550, xilinx_specific, litesdcard]
|
||||
parameters :
|
||||
- memory_size
|
||||
- ram_init_file
|
||||
@@ -256,18 +259,20 @@ targets:
|
||||
- has_uart1
|
||||
- has_fpu=false
|
||||
- has_btc=false
|
||||
- use_litesdcard
|
||||
tools:
|
||||
vivado: {part : xc7a35ticsg324-1L}
|
||||
toplevel : toplevel
|
||||
|
||||
arty_a7-35:
|
||||
default_tool: vivado
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, litedram, liteeth, uart16550, xilinx_specific]
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, litedram, liteeth, uart16550, xilinx_specific, litesdcard]
|
||||
parameters :
|
||||
- memory_size
|
||||
- ram_init_file
|
||||
- use_litedram=true
|
||||
- use_liteeth=true
|
||||
- use_litesdcard
|
||||
- disable_flatten_core
|
||||
- no_bram
|
||||
- spi_flash_offset=3145728
|
||||
@@ -276,14 +281,14 @@ targets:
|
||||
- has_uart1
|
||||
- has_fpu=false
|
||||
- has_btc=false
|
||||
generate: [litedram_arty, liteeth_arty]
|
||||
generate: [litedram_arty, liteeth_arty, litesdcard_arty]
|
||||
tools:
|
||||
vivado: {part : xc7a35ticsg324-1L}
|
||||
toplevel : toplevel
|
||||
|
||||
arty_a7-100-nodram:
|
||||
default_tool: vivado
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, uart16550, xilinx_specific]
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, uart16550, xilinx_specific, litesdcard]
|
||||
parameters :
|
||||
- memory_size
|
||||
- ram_init_file
|
||||
@@ -296,18 +301,20 @@ targets:
|
||||
- has_uart1
|
||||
- has_fpu
|
||||
- has_btc
|
||||
- use_litesdcard
|
||||
tools:
|
||||
vivado: {part : xc7a100ticsg324-1L}
|
||||
toplevel : toplevel
|
||||
|
||||
arty_a7-100:
|
||||
default_tool: vivado
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, litedram, liteeth, uart16550, xilinx_specific]
|
||||
filesets: [core, arty_a7, soc, fpga, debug_xilinx, litedram, liteeth, uart16550, xilinx_specific, litesdcard]
|
||||
parameters:
|
||||
- memory_size
|
||||
- ram_init_file
|
||||
- use_litedram=true
|
||||
- use_liteeth=true
|
||||
- use_litesdcard
|
||||
- disable_flatten_core
|
||||
- no_bram
|
||||
- spi_flash_offset=4194304
|
||||
@@ -316,7 +323,7 @@ targets:
|
||||
- has_uart1
|
||||
- has_fpu
|
||||
- has_btc
|
||||
generate: [litedram_arty, liteeth_arty]
|
||||
generate: [litedram_arty, liteeth_arty, litesdcard_arty]
|
||||
tools:
|
||||
vivado: {part : xc7a100ticsg324-1L}
|
||||
toplevel : toplevel
|
||||
@@ -354,6 +361,10 @@ generate:
|
||||
generator: liteeth_gen
|
||||
parameters: {board : arty}
|
||||
|
||||
litesdcard_arty:
|
||||
generator: litesdcard_gen
|
||||
parameters: {board : arty}
|
||||
|
||||
litedram_nexys_video:
|
||||
generator: litedram_gen
|
||||
parameters: {board : nexys-video}
|
||||
@@ -425,6 +436,12 @@ parameters:
|
||||
paramtype : generic
|
||||
default : false
|
||||
|
||||
use_litesdcard:
|
||||
datatype : bool
|
||||
description : Use LiteSDCard
|
||||
paramtype : generic
|
||||
default : false
|
||||
|
||||
uart_is_16550:
|
||||
datatype : bool
|
||||
description : Use 16550-compatible UART from OpenCores
|
||||
|
||||
60
soc.vhdl
60
soc.vhdl
@@ -32,6 +32,7 @@ use work.wishbone_types.all;
|
||||
-- 0xc8000000: LiteDRAM control (CSRs)
|
||||
-- 0xc8020000: LiteEth CSRs (*)
|
||||
-- 0xc8030000: LiteEth MMIO (*)
|
||||
-- 0xc8040000: LiteSDCard CSRs
|
||||
|
||||
-- (*) LiteEth must be a single aligned 32KB block as the CSRs and MMIOs
|
||||
-- are actually decoded as a single wishbone which LiteEth will
|
||||
@@ -45,6 +46,8 @@ use work.wishbone_types.all;
|
||||
--
|
||||
-- 0 : UART0
|
||||
-- 1 : Ethernet
|
||||
-- 2 : UART1
|
||||
-- 3 : SD card
|
||||
|
||||
entity soc is
|
||||
generic (
|
||||
@@ -74,7 +77,8 @@ entity soc is
|
||||
DCACHE_NUM_LINES : natural := 64;
|
||||
DCACHE_NUM_WAYS : natural := 2;
|
||||
DCACHE_TLB_SET_SIZE : natural := 64;
|
||||
DCACHE_TLB_NUM_WAYS : natural := 2
|
||||
DCACHE_TLB_NUM_WAYS : natural := 2;
|
||||
HAS_SD_CARD : boolean := false
|
||||
);
|
||||
port(
|
||||
rst : in std_ulogic;
|
||||
@@ -90,9 +94,15 @@ entity soc is
|
||||
wb_ext_is_dram_csr : out std_ulogic;
|
||||
wb_ext_is_dram_init : out std_ulogic;
|
||||
wb_ext_is_eth : out std_ulogic;
|
||||
wb_ext_is_sdcard : out std_ulogic;
|
||||
|
||||
-- external DMA wishbone with 32-bit data/address
|
||||
wishbone_dma_in : out wb_io_slave_out := wb_io_slave_out_init;
|
||||
wishbone_dma_out : in wb_io_master_out := wb_io_master_out_init;
|
||||
|
||||
-- External interrupts
|
||||
ext_irq_eth : in std_ulogic := '0';
|
||||
ext_irq_sdcard : in std_ulogic := '0';
|
||||
|
||||
-- UART0 signals:
|
||||
uart0_txd : out std_ulogic;
|
||||
@@ -121,12 +131,12 @@ architecture behaviour of soc is
|
||||
signal wishbone_dcore_out : wishbone_master_out;
|
||||
signal wishbone_icore_in : wishbone_slave_out;
|
||||
signal wishbone_icore_out : wishbone_master_out;
|
||||
signal wishbone_debug_in : wishbone_slave_out;
|
||||
signal wishbone_debug_in : wishbone_slave_out;
|
||||
signal wishbone_debug_out : wishbone_master_out;
|
||||
|
||||
-- Arbiter array (ghdl doesnt' support assigning the array
|
||||
-- elements in the entity instantiation)
|
||||
constant NUM_WB_MASTERS : positive := 3;
|
||||
constant NUM_WB_MASTERS : positive := 4;
|
||||
signal wb_masters_out : wishbone_master_out_vector(0 to NUM_WB_MASTERS-1);
|
||||
signal wb_masters_in : wishbone_slave_out_vector(0 to NUM_WB_MASTERS-1);
|
||||
|
||||
@@ -219,6 +229,37 @@ architecture behaviour of soc is
|
||||
SLAVE_IO_NONE);
|
||||
signal slave_io_dbg : slave_io_type;
|
||||
|
||||
function wishbone_widen_data(wb : wb_io_master_out) return wishbone_master_out is
|
||||
variable wwb : wishbone_master_out;
|
||||
begin
|
||||
wwb.adr := wb.adr & "00"; -- XXX note wrong adr usage in wishbone_master_out
|
||||
wwb.dat := wb.dat & wb.dat;
|
||||
wwb.sel := x"00";
|
||||
if wwb.adr(2) = '0' then
|
||||
wwb.sel(3 downto 0) := wb.sel;
|
||||
else
|
||||
wwb.sel(7 downto 4) := wb.sel;
|
||||
end if;
|
||||
wwb.cyc := wb.cyc;
|
||||
wwb.stb := wb.stb;
|
||||
wwb.we := wb.we;
|
||||
return wwb;
|
||||
end;
|
||||
|
||||
function wishbone_narrow_data(wwbs : wishbone_slave_out; adr : std_ulogic_vector(29 downto 0))
|
||||
return wb_io_slave_out is
|
||||
variable wbs : wb_io_slave_out;
|
||||
begin
|
||||
wbs.ack := wwbs.ack;
|
||||
wbs.stall := wwbs.stall;
|
||||
if adr(0) = '0' then
|
||||
wbs.dat := wwbs.dat(31 downto 0);
|
||||
else
|
||||
wbs.dat := wwbs.dat(63 downto 32);
|
||||
end if;
|
||||
return wbs;
|
||||
end;
|
||||
|
||||
-- This is the component exported by the 16550 compatible
|
||||
-- UART from FuseSoC.
|
||||
--
|
||||
@@ -243,6 +284,7 @@ architecture behaviour of soc is
|
||||
dcd_pad_i : in std_ulogic
|
||||
);
|
||||
end component;
|
||||
|
||||
begin
|
||||
|
||||
resets: process(system_clk)
|
||||
@@ -298,10 +340,12 @@ begin
|
||||
-- Wishbone bus master arbiter & mux
|
||||
wb_masters_out <= (0 => wishbone_dcore_out,
|
||||
1 => wishbone_icore_out,
|
||||
2 => wishbone_debug_out);
|
||||
2 => wishbone_widen_data(wishbone_dma_out),
|
||||
3 => wishbone_debug_out);
|
||||
wishbone_dcore_in <= wb_masters_in(0);
|
||||
wishbone_icore_in <= wb_masters_in(1);
|
||||
wishbone_debug_in <= wb_masters_in(2);
|
||||
wishbone_dma_in <= wishbone_narrow_data(wb_masters_in(2), wishbone_dma_out.adr);
|
||||
wishbone_debug_in <= wb_masters_in(3);
|
||||
wishbone_arbiter_0: entity work.wishbone_arbiter
|
||||
generic map(
|
||||
NUM_MASTERS => NUM_WB_MASTERS
|
||||
@@ -589,6 +633,7 @@ begin
|
||||
wb_ext_is_dram_csr <= '0';
|
||||
wb_ext_is_dram_init <= '0';
|
||||
wb_ext_is_eth <= '0';
|
||||
wb_ext_is_sdcard <= '0';
|
||||
|
||||
-- Default response, ack & return all 1's
|
||||
wb_sio_in.dat <= (others => '1');
|
||||
@@ -616,6 +661,9 @@ begin
|
||||
elsif wb_sio_out.adr(23 downto 16) = x"03" and HAS_LITEETH then
|
||||
wb_ext_is_eth <= '1';
|
||||
ext_valid := true;
|
||||
elsif wb_sio_out.adr(23 downto 16) = x"04" and HAS_SD_CARD then
|
||||
wb_ext_is_sdcard <= '1';
|
||||
ext_valid := true;
|
||||
end if;
|
||||
if ext_valid then
|
||||
wb_ext_io_in.cyc <= wb_sio_out.cyc;
|
||||
@@ -665,6 +713,7 @@ begin
|
||||
HAS_SPI_FLASH => HAS_SPI_FLASH,
|
||||
SPI_FLASH_OFFSET => SPI_FLASH_OFFSET,
|
||||
HAS_LITEETH => HAS_LITEETH,
|
||||
HAS_SD_CARD => HAS_SD_CARD,
|
||||
UART0_IS_16550 => UART0_IS_16550,
|
||||
HAS_UART1 => HAS_UART1
|
||||
)
|
||||
@@ -848,6 +897,7 @@ begin
|
||||
int_level_in(0) <= uart0_irq;
|
||||
int_level_in(1) <= ext_irq_eth;
|
||||
int_level_in(2) <= uart1_irq;
|
||||
int_level_in(3) <= ext_irq_sdcard;
|
||||
end process;
|
||||
|
||||
-- BRAM Memory slave
|
||||
|
||||
19
syscon.vhdl
19
syscon.vhdl
@@ -18,6 +18,7 @@ entity syscon is
|
||||
HAS_SPI_FLASH : boolean;
|
||||
SPI_FLASH_OFFSET : integer;
|
||||
HAS_LITEETH : boolean;
|
||||
HAS_SD_CARD : boolean;
|
||||
UART0_IS_16550 : boolean;
|
||||
HAS_UART1 : boolean
|
||||
);
|
||||
@@ -65,6 +66,7 @@ architecture behaviour of syscon is
|
||||
constant SYS_REG_INFO_HAS_LSYS : integer := 5; -- Has 6-bit address syscon
|
||||
constant SYS_REG_INFO_HAS_URT1 : integer := 6; -- Has second UART
|
||||
constant SYS_REG_INFO_HAS_ARTB : integer := 7; -- Has architected TB frequency
|
||||
constant SYS_REG_INFO_HAS_SDCARD : integer := 8; -- Has LiteSDCard SD-card interface
|
||||
|
||||
-- BRAMINFO contains the BRAM size in the bottom 52 bits
|
||||
-- DRAMINFO contains the DRAM size if any in the bottom 52 bits
|
||||
@@ -107,6 +109,7 @@ architecture behaviour of syscon is
|
||||
signal info_has_uart : std_ulogic;
|
||||
signal info_has_spif : std_ulogic;
|
||||
signal info_has_leth : std_ulogic;
|
||||
signal info_has_lsdc : std_ulogic;
|
||||
signal info_has_urt1 : std_ulogic;
|
||||
signal info_clk : std_ulogic_vector(39 downto 0);
|
||||
signal info_fl_off : std_ulogic_vector(31 downto 0);
|
||||
@@ -128,15 +131,17 @@ begin
|
||||
info_has_bram <= '1' when BRAM_SIZE /= 0 else '0';
|
||||
info_has_spif <= '1' when HAS_SPI_FLASH else '0';
|
||||
info_has_leth <= '1' when HAS_LITEETH else '0';
|
||||
info_has_lsdc <= '1' when HAS_SD_CARD else '0';
|
||||
info_has_urt1 <= '1' when HAS_UART1 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,
|
||||
SYS_REG_INFO_HAS_LSYS => '1',
|
||||
SYS_REG_INFO_HAS_URT1 => info_has_urt1,
|
||||
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,
|
||||
SYS_REG_INFO_HAS_SDCARD => info_has_lsdc,
|
||||
SYS_REG_INFO_HAS_LSYS => '1',
|
||||
SYS_REG_INFO_HAS_URT1 => info_has_urt1,
|
||||
others => '0');
|
||||
|
||||
reg_braminfo <= x"000" & std_ulogic_vector(to_unsigned(BRAM_SIZE, 52));
|
||||
|
||||
@@ -44,6 +44,8 @@ package wishbone_types is
|
||||
stb : std_ulogic;
|
||||
we : std_ulogic;
|
||||
end record;
|
||||
constant wb_io_master_out_init : wb_io_master_out := (adr => (others => '0'), dat => (others => '0'),
|
||||
sel => "0000", cyc => '0', stb => '0', we => '0');
|
||||
|
||||
type wb_io_slave_out is record
|
||||
dat : std_ulogic_vector(31 downto 0);
|
||||
|
||||
Reference in New Issue
Block a user