Skip to content

Commit

Permalink
Merge pull request #30 from enjoy-digital/new_driver
Browse files Browse the repository at this point in the history
New driver
  • Loading branch information
enjoy-digital authored Jun 2, 2020
2 parents b0e8383 + 2703b8a commit 5533144
Show file tree
Hide file tree
Showing 16 changed files with 2,666 additions and 921 deletions.
73 changes: 43 additions & 30 deletions examples/kc705.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

from litex.boards.platforms import kc705
from litex.build.generic_platform import tools
from litex.build.xilinx import VivadoProgrammer

from litex.soc.cores.clock import S7MMCM
from litex.soc.interconnect.csr import *
Expand Down Expand Up @@ -48,7 +47,6 @@ def __init__(self, platform, sys_clk_freq):
# LitePCIeSoC --------------------------------------------------------------------------------------

class LitePCIeSoC(SoCMini):
mem_map = {"csr": 0x00000000}
def __init__(self, platform, nlanes=1):
sys_clk_freq = int(125e6)

Expand All @@ -64,65 +62,80 @@ def __init__(self, platform, nlanes=1):
self.submodules.crg = _CRG(platform, sys_clk_freq)
self.add_csr("crg")

# PCIe PHY ---------------------------------------------------------------------------------
self.submodules.pcie_phy = S7PCIEPHY(platform, platform.request("pcie_x" + str(nlanes)))
# PCIe -------------------------------------------------------------------------------------
# PHY
self.submodules.pcie_phy = S7PCIEPHY(platform, platform.request("pcie_x4"),
data_width = 128,
bar0_size = 0x20000)
self.pcie_phy.add_timing_constraints(platform)
platform.add_false_path_constraints(self.crg.cd_sys.clk, self.pcie_phy.cd_pcie.clk)
self.add_csr("pcie_phy")

# PCIe Endpoint ----------------------------------------------------------------------------
self.submodules.pcie_endpoint = LitePCIeEndpoint(self.pcie_phy, endianness="big")
# Endpoint
self.submodules.pcie_endpoint = LitePCIeEndpoint(self.pcie_phy,
endianness="big",
max_pending_requests=8
)

# PCIe Wishbone bridge ---------------------------------------------------------------------
self.submodules.pcie_bridge = LitePCIeWishboneBridge(self.pcie_endpoint)
# Wishbone bridge
self.submodules.pcie_bridge = LitePCIeWishboneBridge(self.pcie_endpoint,
base_address = self.mem_map["csr"])
self.add_wb_master(self.pcie_bridge.wishbone)

# PCIe DMA ---------------------------------------------------------------------------------
self.submodules.pcie_dma = LitePCIeDMA(self.pcie_phy, self.pcie_endpoint, with_loopback=True)
self.add_csr("pcie_dma")
# DMA0
self.submodules.pcie_dma0 = LitePCIeDMA(self.pcie_phy, self.pcie_endpoint,
with_buffering = True, buffering_depth=1024,
with_loopback = True)
self.add_csr("pcie_dma0")

# PCIe MSI ---------------------------------------------------------------------------------
# DMA1
self.submodules.pcie_dma1 = LitePCIeDMA(self.pcie_phy, self.pcie_endpoint,
with_buffering = True, buffering_depth=1024,
with_loopback = True)
self.add_csr("pcie_dma1")

self.add_constant("DMA_CHANNELS", 2)

# MSI
self.submodules.pcie_msi = LitePCIeMSI()
self.add_csr("pcie_msi")
self.comb += self.pcie_msi.source.connect(self.pcie_phy.msi)
self.interrupts = {
"PCIE_DMA_WRITER": self.pcie_dma.writer.irq,
"PCIE_DMA_READER": self.pcie_dma.reader.irq
"PCIE_DMA0_WRITER": self.pcie_dma0.writer.irq,
"PCIE_DMA0_READER": self.pcie_dma0.reader.irq,
"PCIE_DMA1_WRITER": self.pcie_dma1.writer.irq,
"PCIE_DMA1_READER": self.pcie_dma1.reader.irq,
}
for i, (k, v) in enumerate(sorted(self.interrupts.items())):
self.comb += self.pcie_msi.irqs[i].eq(v)
self.add_constant(k + "_INTERRUPT", i)

def generate_software_headers(self):
csr_header = get_csr_header(self.csr_regions, self.constants, with_access_functions=False)
tools.write_to_file(os.path.join("build", "csr.h"), csr_header)
tools.write_to_file("csr.h", csr_header)
soc_header = get_soc_header(self.constants, with_access_functions=False)
tools.write_to_file(os.path.join("build", "soc.h"), soc_header)
tools.write_to_file("soc.h", soc_header)
mem_header = get_mem_header(self.mem_regions)
tools.write_to_file(os.path.join("build", "mem.h"), mem_header)

# Load ---------------------------------------------------------------------------------------------

def load():
prog = VivadoProgrammer()
prog.load_bitstream("build/gateware/kc705.bit")
tools.write_to_file("mem.h", mem_header)

# Build --------------------------------------------------------------------------------------------

def main():
parser = argparse.ArgumentParser()
parser.add_argument("--build", action="store_true", help="build bitstream")
parser.add_argument("--load", action="store_true", help="load bitstream (to SRAM)")
parser = argparse.ArgumentParser(description="LitePCIe SoC on KC705")
parser.add_argument("--build", action="store_true", help="Build bitstream")
parser.add_argument("--load", action="store_true", help="Load bitstream (to SRAM)")
parser.add_argument("--nlanes",default=1, help="Number of Gen2 PCIe lanes (1, 4 or 8)")
args = parser.parse_args()

platform = kc705.Platform()
soc = LitePCIeSoC(platform, nlanes=int(args.nlanes))
builder = Builder(soc, output_dir="build", csr_csv="csr.csv")
builder.build(build_name="kc705", run=args.build)
soc = LitePCIeSoC(platform, nlanes=int(args.nlanes))
builder = Builder(soc, csr_csv="csr.csv")
builder.build(run=args.build)
soc.generate_software_headers()

if args.load:
load()
prog = soc.platform.create_programmer()
prog.load_bitstream(os.path.join(builder.gateware_dir, soc.build_name + ".bit"))

if __name__ == "__main__":
main()
76 changes: 46 additions & 30 deletions examples/kcu105.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

from litex.boards.platforms import kcu105
from litex.build.generic_platform import tools
from litex.build.xilinx import VivadoProgrammer

from litex.soc.cores.clock import USPLL
from litex.soc.interconnect.csr import *
Expand Down Expand Up @@ -48,7 +47,6 @@ def __init__(self, platform, sys_clk_freq):
# LitePCIeSoC --------------------------------------------------------------------------------------

class LitePCIeSoC(SoCMini):
mem_map = {"csr": 0x00000000}
def __init__(self, platform, nlanes=4):
sys_clk_freq = int(125e6)

Expand All @@ -64,64 +62,82 @@ def __init__(self, platform, nlanes=4):
self.submodules.crg = _CRG(platform, sys_clk_freq)
self.add_csr("crg")

# PCIe PHY ---------------------------------------------------------------------------------
self.submodules.pcie_phy = USPCIEPHY(platform, platform.request("pcie_x" + str(nlanes)))

# PCIe -------------------------------------------------------------------------------------
# PHY
self.submodules.pcie_phy = USPCIEPHY(platform, platform.request("pcie_x" + str(nlanes)),
data_width = 128,
bar0_size = 0x20000
)
#self.pcie_phy.add_timing_constraints(platform) # FIXME
#platform.add_false_path_constraints(self.crg.cd_sys.clk, self.pcie_phy.cd_pcie.clk)
self.add_csr("pcie_phy")

# PCIe Endpoint ----------------------------------------------------------------------------
self.submodules.pcie_endpoint = LitePCIeEndpoint(self.pcie_phy, endianness="little")
# Endpoint
self.submodules.pcie_endpoint = LitePCIeEndpoint(self.pcie_phy,
endianness="little",
max_pending_requests=8
)

# PCIe Wishbone bridge ---------------------------------------------------------------------
self.submodules.pcie_bridge = LitePCIeWishboneBridge(self.pcie_endpoint)
# Wishbone bridge
self.submodules.pcie_bridge = LitePCIeWishboneBridge(self.pcie_endpoint,
base_address = self.mem_map["csr"])
self.add_wb_master(self.pcie_bridge.wishbone)

# PCIe DMA ---------------------------------------------------------------------------------
self.submodules.pcie_dma = LitePCIeDMA(self.pcie_phy, self.pcie_endpoint, with_loopback=True)
self.add_csr("pcie_dma")
# DMA0
self.submodules.pcie_dma0 = LitePCIeDMA(self.pcie_phy, self.pcie_endpoint,
with_buffering = True, buffering_depth=1024,
with_loopback = True)
self.add_csr("pcie_dma0")

# DMA1
self.submodules.pcie_dma1 = LitePCIeDMA(self.pcie_phy, self.pcie_endpoint,
with_buffering = True, buffering_depth=1024,
with_loopback = True)
self.add_csr("pcie_dma1")

self.add_constant("DMA_CHANNELS", 2)

# PCIe MSI ---------------------------------------------------------------------------------
# MSI
self.submodules.pcie_msi = LitePCIeMSI()
self.add_csr("pcie_msi")
self.comb += self.pcie_msi.source.connect(self.pcie_phy.msi)
self.interrupts = {
"PCIE_DMA_WRITER": self.pcie_dma.writer.irq,
"PCIE_DMA_READER": self.pcie_dma.reader.irq
"PCIE_DMA0_WRITER": self.pcie_dma0.writer.irq,
"PCIE_DMA0_READER": self.pcie_dma0.reader.irq,
"PCIE_DMA1_WRITER": self.pcie_dma1.writer.irq,
"PCIE_DMA1_READER": self.pcie_dma1.reader.irq,
}
for i, (k, v) in enumerate(sorted(self.interrupts.items())):
self.comb += self.pcie_msi.irqs[i].eq(v)
self.add_constant(k + "_INTERRUPT", i)

def generate_software_headers(self):
csr_header = get_csr_header(self.csr_regions, self.constants, with_access_functions=False)
tools.write_to_file(os.path.join("build", "csr.h"), csr_header)
tools.write_to_file("csr.h", csr_header)
soc_header = get_soc_header(self.constants, with_access_functions=False)
tools.write_to_file(os.path.join("build", "soc.h"), soc_header)
tools.write_to_file("soc.h", soc_header)
mem_header = get_mem_header(self.mem_regions)
tools.write_to_file(os.path.join("build", "mem.h"), mem_header)

# Load ---------------------------------------------------------------------------------------------

def load():
prog = VivadoProgrammer()
prog.load_bitstream("build/gateware/kcu105.bit")
tools.write_to_file("mem.h", mem_header)

# Build --------------------------------------------------------------------------------------------

def main():
parser = argparse.ArgumentParser()
parser.add_argument("--build", action="store_true", help="build bitstream")
parser.add_argument("--load", action="store_true", help="load bitstream (to SRAM)")
parser = argparse.ArgumentParser(description="LitePCIe SoC on KCU105")
parser.add_argument("--build", action="store_true", help="Build bitstream")
parser.add_argument("--load", action="store_true", help="Load bitstream (to SRAM)")
parser.add_argument("--nlanes",default=1, help="Number of Gen2 PCIe lanes (1, 4 or 8)")
args = parser.parse_args()

platform = kcu105.Platform()
soc = LitePCIeSoC(platform, nlanes=int(args.nlanes))
builder = Builder(soc, output_dir="build", csr_csv="csr.csv")
builder.build(build_name="kcu105", run=args.build)
soc = LitePCIeSoC(platform, nlanes=int(args.nlanes))
builder = Builder(soc, csr_csv="csr.csv")
builder.build(run=args.build)
soc.generate_software_headers()

if args.load:
load()
prog = soc.platform.create_programmer()
prog.load_bitstream(os.path.join(builder.gateware_dir, soc.build_name + ".bit"))

if __name__ == "__main__":
main()
6 changes: 3 additions & 3 deletions litepcie/software/kernel/Makefile
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# Makefile for kernel module

KERNEL_VERSION:=$(shell uname -r)
KERNEL_PATH:=/lib/modules/$(KERNEL_VERSION)/build

obj-m = litepcie.o
litepcie-objs = main.o


all: litepcie.ko

litepcie.ko: main.c
make -C $(KERNEL_PATH) M=$(PWD) modules
make -C $(KERNEL_PATH) M=$(shell pwd) modules

clean:
make -C $(KERNEL_PATH) M=$(PWD) clean
make -C $(KERNEL_PATH) M=$(shell pwd) clean
rm -f *~
56 changes: 44 additions & 12 deletions litepcie/software/kernel/config.h
Original file line number Diff line number Diff line change
@@ -1,18 +1,50 @@
// This file is Copyright (c) 2015-2019 Florent Kermarrec <[email protected]>
// License: BSD

#ifndef __HW_CONFIG_H
#define __HW_CONFIG_H
#include "csr.h"
#include "soc.h"
#include "mem.h"

#define MINIMAL_GATEWARE_REVISION "2020-05-19"

/* pcie */
#define PCIE_FPGA_VENDOR_ID 0x10ee
#define PCIE_FPGA_DEVICE_ID_X1 0x7021
#define PCIE_FPGA_DEVICE_ID_X2 0x7022
#define PCIE_FPGA_DEVICE_ID_X4 0x7024
#define PCIE_FPGA_DEVICE_ID_X8 0x7028

/* /!\ keep in sync with csr.h /!\ */

/* dma */
#define DMA_IRQ_DISABLE (1<<24)
#define DMA_LAST_DISABLE (1<<25)

/* pci */
#define PCI_FPGA_VENDOR_ID 0x10ee
#define PCI_FPGA_DEVICE_ID_X1 0x7021
#define PCI_FPGA_DEVICE_ID_X2 0x7022
#define PCI_FPGA_DEVICE_ID_X4 0x7024
#define PCI_FPGA_DEVICE_ID_X8 0x7028
#define PCI_FPGA_BAR0_SIZE 0xa000
#define DMA_CHANNEL_COUNT DMA_CHANNELS
#define DMA_BUFFER_PER_IRQ 32
#define DMA_BUFFER_COUNT 256
#define DMA_BUFFER_SIZE 8192
#define DMA_BUFFER_TOTAL_SIZE (DMA_BUFFER_COUNT*DMA_BUFFER_SIZE)
//#define DMA_BUFFER_ALIGNED

/* pcie_dma */
#define PCIE_DMA_BUFFER_COUNT 128
/* pcie dma */
#define PCIE_DMA_WRITER_ENABLE_OFFSET 0x0000
#define PCIE_DMA_WRITER_TABLE_VALUE_OFFSET 0x0004
#define PCIE_DMA_WRITER_TABLE_WE_OFFSET 0x000c
#define PCIE_DMA_WRITER_TABLE_LOOP_PROG_N_OFFSET 0x0010
#define PCIE_DMA_WRITER_TABLE_LOOP_STATUS_OFFSET 0x0014
#define PCIE_DMA_WRITER_TABLE_LEVEL_OFFSET 0x0018
#define PCIE_DMA_WRITER_TABLE_FLUSH_OFFSET 0x001c
#define PCIE_DMA_READER_ENABLE_OFFSET 0x0020
#define PCIE_DMA_READER_TABLE_VALUE_OFFSET 0x0024
#define PCIE_DMA_READER_TABLE_WE_OFFSET 0x002c
#define PCIE_DMA_READER_TABLE_LOOP_PROG_N_OFFSET 0x0030
#define PCIE_DMA_READER_TABLE_LOOP_STATUS_OFFSET 0x0034
#define PCIE_DMA_READER_TABLE_LEVEL_OFFSET 0x0038
#define PCIE_DMA_READER_TABLE_FLUSH_OFFSET 0x003c
#define PCIE_DMA_LOOPBACK_ENABLE_OFFSET 0x0040
#define PCIE_DMA_BUFFERING_READER_FIFO_DEPTH_ADDR 0x0044
#define PCIE_DMA_BUFFERING_READER_FIFO_LEVEL_ADDR 0x0048
#define PCIE_DMA_BUFFERING_WRITER_FIFO_DEPTH_ADDR 0x004c
#define PCIE_DMA_BUFFERING_WRITER_FIFO_LEVEL_ADDR 0x0050

#endif /* __HW_CONFIG_H */
14 changes: 7 additions & 7 deletions litepcie/software/kernel/flags.h
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// This file is Copyright (c) 2015-2019 Florent Kermarrec <[email protected]>
// License: BSD

#ifndef __HW_FLAGS_H
#define __HW_FLAGS_H

/* pcie_dma */
#define PCIE_DMA_LOOPBACK_ENABLE 0x1
/* spi */
#define SPI_CTRL_START 0x1
#define SPI_CTRL_LENGTH (1<<8)
#define SPI_STATUS_DONE 0x1

#define PCIE_DMA_TABLE_LOOP_INDEX 1 << 0
#define PCIE_DMA_TABLE_LOOP_COUNT 1 << 16
/* pcie */
#define DMA_TABLE_LOOP_INDEX (1 << 0)
#define DMA_TABLE_LOOP_COUNT (1 << 16)

#endif /* __HW_FLAGS_H */
Loading

0 comments on commit 5533144

Please sign in to comment.