2020-05-06 01:49:21 -04:00
#!/usr/bin/env python3
2020-08-23 09:00:17 -04:00
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2020 Florent Kermarrec <florent@enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause
2020-05-06 01:49:21 -04:00
2020-05-13 11:54:42 -04:00
# Build/Use ----------------------------------------------------------------------------------------
# Build/Load bitstream:
2021-04-29 05:56:52 -04:00
# ./sqrl_acorn.py --uart-name=crossover --with-pcie --build --driver --load (or --flash)
2020-05-13 11:54:42 -04:00
#
#.Build the kernel and load it:
2020-06-03 02:20:43 -04:00
# cd build/<platform>/driver/kernel
2020-05-13 11:54:42 -04:00
# make
# sudo ./init.sh
#
# Test userspace utilities:
2020-06-03 02:20:43 -04:00
# cd build/<platform>/driver/user
2020-05-13 11:54:42 -04:00
# make
# ./litepcie_util info
# ./litepcie_util scratch_test
# ./litepcie_util dma_test
# ./litepcie_util uart_test
2020-05-06 01:49:21 -04:00
import os
import argparse
import sys
from migen import *
2021-03-26 18:52:36 -04:00
from litex_boards . platforms import acorn
2020-05-06 01:49:21 -04:00
from litex . soc . interconnect . csr import *
from litex . soc . integration . soc_core import *
from litex . soc . integration . builder import *
from litex . soc . cores . clock import *
2020-05-08 16:16:13 -04:00
from litex . soc . cores . led import LedChaser
2020-05-06 01:49:21 -04:00
2020-05-09 10:39:17 -04:00
from litedram . modules import MT41K512M16
2020-05-06 01:49:21 -04:00
from litedram . phy import s7ddrphy
from litepcie . phy . s7pciephy import S7PCIEPHY
2020-06-03 02:20:43 -04:00
from litepcie . software import generate_litepcie_software
2020-05-06 01:49:21 -04:00
# CRG ----------------------------------------------------------------------------------------------
2020-06-30 11:28:13 -04:00
class CRG ( Module ) :
2020-05-06 01:49:21 -04:00
def __init__ ( self , platform , sys_clk_freq ) :
2020-11-04 05:09:30 -05:00
self . rst = Signal ( )
2020-05-06 01:49:21 -04:00
self . clock_domains . cd_sys = ClockDomain ( )
self . clock_domains . cd_sys4x = ClockDomain ( reset_less = True )
self . clock_domains . cd_sys4x_dqs = ClockDomain ( reset_less = True )
2020-10-13 06:10:29 -04:00
self . clock_domains . cd_idelay = ClockDomain ( )
2020-05-06 01:49:21 -04:00
# Clk/Rst
clk200 = platform . request ( " clk200 " )
# PLL
self . submodules . pll = pll = S7PLL ( )
2020-11-04 05:09:30 -05:00
self . comb + = pll . reset . eq ( self . rst )
2020-05-06 01:49:21 -04:00
pll . register_clkin ( clk200 , 200e6 )
pll . create_clkout ( self . cd_sys , sys_clk_freq )
pll . create_clkout ( self . cd_sys4x , 4 * sys_clk_freq )
pll . create_clkout ( self . cd_sys4x_dqs , 4 * sys_clk_freq , phase = 90 )
2020-10-13 06:10:29 -04:00
pll . create_clkout ( self . cd_idelay , 200e6 )
2021-01-07 02:00:40 -05:00
platform . add_false_path_constraints ( self . cd_sys . clk , pll . clkin ) # Ignore sys_clk to pll.clkin path created by SoC's rst.
2020-05-06 01:49:21 -04:00
2020-10-13 06:10:29 -04:00
self . submodules . idelayctrl = S7IDELAYCTRL ( self . cd_idelay )
2020-05-06 01:49:21 -04:00
2020-06-30 11:41:57 -04:00
# BaseSoC -----------------------------------------------------------------------------------------
2020-05-06 01:49:21 -04:00
2020-06-30 11:41:57 -04:00
class BaseSoC ( SoCCore ) :
2021-07-06 17:39:37 -04:00
def __init__ ( self , variant = " cle-215+ " , sys_clk_freq = int ( 100e6 ) , with_led_chaser = True ,
with_pcie = False , with_sata = False , * * kwargs ) :
2021-03-26 18:52:36 -04:00
platform = acorn . Platform ( variant = variant )
2020-05-06 01:49:21 -04:00
# SoCCore ----------------------------------------------------------------------------------
SoCCore . __init__ ( self , platform , sys_clk_freq ,
2021-03-26 18:52:36 -04:00
ident = " LiteX SoC on Acorn CLE-101/215(+) " ,
2020-05-06 01:49:21 -04:00
ident_version = True ,
* * kwargs )
# CRG --------------------------------------------------------------------------------------
self . submodules . crg = CRG ( platform , sys_clk_freq )
# DDR3 SDRAM -------------------------------------------------------------------------------
if not self . integrated_main_ram_size :
self . submodules . ddrphy = s7ddrphy . A7DDRPHY ( platform . request ( " ddram " ) ,
memtype = " DDR3 " ,
nphases = 4 ,
sys_clk_freq = sys_clk_freq ,
iodelay_clk_freq = 200e6 )
self . add_sdram ( " sdram " ,
2021-03-29 09:28:04 -04:00
phy = self . ddrphy ,
module = MT41K512M16 ( sys_clk_freq , " 1:4 " ) ,
l2_cache_size = kwargs . get ( " l2_size " , 8192 )
2020-05-06 01:49:21 -04:00
)
# PCIe -------------------------------------------------------------------------------------
2020-06-30 12:44:00 -04:00
if with_pcie :
self . submodules . pcie_phy = S7PCIEPHY ( platform , platform . request ( " pcie_x4 " ) ,
data_width = 128 ,
bar0_size = 0x20000 )
2020-11-12 10:39:42 -05:00
self . add_pcie ( phy = self . pcie_phy , ndmas = 1 )
2021-09-08 10:27:30 -04:00
# FIXME: Apply it to all targets (integrate it in LitePCIe?).
platform . add_period_constraint ( self . crg . cd_sys . clk , 1e9 / sys_clk_freq )
platform . toolchain . pre_placement_commands . add ( " set_clock_groups -group [get_clocks {sys_clk} ] -group [get_clocks userclk2] -asynchronous " , sys_clk = self . crg . cd_sys . clk )
platform . toolchain . pre_placement_commands . add ( " set_clock_groups -group [get_clocks {sys_clk} ] -group [get_clocks clk_125mhz] -asynchronous " , sys_clk = self . crg . cd_sys . clk )
platform . toolchain . pre_placement_commands . add ( " set_clock_groups -group [get_clocks {sys_clk} ] -group [get_clocks clk_250mhz] -asynchronous " , sys_clk = self . crg . cd_sys . clk )
platform . toolchain . pre_placement_commands . add ( " set_clock_groups -group [get_clocks clk_125mhz] -group [get_clocks clk_250mhz] -asynchronous " )
2021-04-21 11:00:40 -04:00
# ICAP (For FPGA reload over PCIe).
from litex . soc . cores . icap import ICAP
self . submodules . icap = ICAP ( )
self . icap . add_reload ( )
self . icap . add_timing_constraints ( platform , sys_clk_freq , self . crg . cd_sys . clk )
# Flash (For SPIFlash update over PCIe). FIXME: Should probably be updated to use SpiFlashSingle/SpiFlashDualQuad (so MMAPed and do the update with bit-banging)
from litex . soc . cores . gpio import GPIOOut
from litex . soc . cores . spi_flash import S7SPIFlash
self . submodules . flash_cs_n = GPIOOut ( platform . request ( " flash_cs_n " ) )
self . submodules . flash = S7SPIFlash ( platform . request ( " flash " ) , sys_clk_freq , 25e6 )
2020-11-18 13:14:18 -05:00
# SATA -------------------------------------------------------------------------------------
if with_sata :
from litex . build . generic_platform import Subsignal , Pins
from litesata . phy import LiteSATAPHY
# IOs
_sata_io = [
# PCIe 2 SATA Custom Adapter (With PCIe Riser / SATA cable mod).
( " pcie2sata " , 0 ,
Subsignal ( " tx_p " , Pins ( " B6 " ) ) ,
Subsignal ( " tx_n " , Pins ( " A6 " ) ) ,
Subsignal ( " rx_p " , Pins ( " B10 " ) ) ,
Subsignal ( " rx_n " , Pins ( " A10 " ) ) ,
) ,
]
platform . add_extension ( _sata_io )
# RefClk, Generate 150MHz from PLL.
self . clock_domains . cd_sata_refclk = ClockDomain ( )
self . crg . pll . create_clkout ( self . cd_sata_refclk , 150e6 )
sata_refclk = ClockSignal ( " sata_refclk " )
platform . add_platform_command ( " set_property SEVERITY {{ Warning}} [get_drc_checks REQP-49] " )
# PHY
self . submodules . sata_phy = LiteSATAPHY ( platform . device ,
refclk = sata_refclk ,
pads = platform . request ( " pcie2sata " ) ,
gen = " gen2 " ,
clk_freq = sys_clk_freq ,
data_width = 16 )
# Core
self . add_sata ( phy = self . sata_phy , mode = " read+write " )
2020-05-08 16:16:13 -04:00
# Leds -------------------------------------------------------------------------------------
2021-07-06 17:39:37 -04:00
if with_led_chaser :
self . submodules . leds = LedChaser (
pads = platform . request_all ( " user_led " ) ,
sys_clk_freq = sys_clk_freq )
2020-05-08 16:16:13 -04:00
2020-05-06 01:49:21 -04:00
# Build --------------------------------------------------------------------------------------------
def main ( ) :
2021-03-26 18:52:36 -04:00
parser = argparse . ArgumentParser ( description = " LiteX SoC on Acorn CLE-101/215(+) " )
2020-08-09 16:27:41 -04:00
parser . add_argument ( " --build " , action = " store_true " , help = " Build bitstream " )
parser . add_argument ( " --load " , action = " store_true " , help = " Load bitstream " )
parser . add_argument ( " --flash " , action = " store_true " , help = " Flash bitstream " )
2021-03-26 18:52:36 -04:00
parser . add_argument ( " --variant " , default = " cle-215+ " , help = " Board variant: cle-215+ (default), cle-215 or cle-101 " )
2020-11-12 12:07:28 -05:00
parser . add_argument ( " --sys-clk-freq " , default = 100e6 , help = " System clock frequency (default: 100MHz) " )
2021-01-29 20:08:38 -05:00
pcieopts = parser . add_mutually_exclusive_group ( )
pcieopts . add_argument ( " --with-pcie " , action = " store_true " , help = " Enable PCIe support " )
2020-11-12 10:39:42 -05:00
parser . add_argument ( " --driver " , action = " store_true " , help = " Generate PCIe driver " )
parser . add_argument ( " --with-spi-sdcard " , action = " store_true " , help = " Enable SPI-mode SDCard support (requires SDCard adapter on P2) " )
2021-01-29 20:08:38 -05:00
pcieopts . add_argument ( " --with-sata " , action = " store_true " , help = " Enable SATA support (over PCIe2SATA) " )
2020-05-06 01:49:21 -04:00
builder_args ( parser )
2021-03-24 10:01:23 -04:00
soc_core_args ( parser )
2020-05-06 01:49:21 -04:00
args = parser . parse_args ( )
2020-11-12 12:07:28 -05:00
soc = BaseSoC (
2021-03-26 18:52:36 -04:00
variant = args . variant ,
2020-11-12 12:07:28 -05:00
sys_clk_freq = int ( float ( args . sys_clk_freq ) ) ,
with_pcie = args . with_pcie ,
2020-11-18 13:14:18 -05:00
with_sata = args . with_sata ,
2021-03-24 10:01:23 -04:00
* * soc_core_argdict ( args )
2020-11-12 12:07:28 -05:00
)
2020-08-09 16:27:41 -04:00
if args . with_spi_sdcard :
soc . add_spi_sdcard ( )
2020-05-06 01:49:21 -04:00
builder = Builder ( soc , * * builder_argdict ( args ) )
2020-06-03 02:20:43 -04:00
builder . build ( run = args . build )
if args . driver :
generate_litepcie_software ( soc , os . path . join ( builder . output_dir , " driver " ) )
2020-05-06 01:49:21 -04:00
if args . load :
prog = soc . platform . create_programmer ( )
2020-05-21 03:12:29 -04:00
prog . load_bitstream ( os . path . join ( builder . gateware_dir , soc . build_name + " .bit " ) )
2020-05-06 01:49:21 -04:00
2020-05-06 06:27:07 -04:00
if args . flash :
prog = soc . platform . create_programmer ( )
2021-04-21 11:00:40 -04:00
prog . flash ( 0 , os . path . join ( builder . gateware_dir , soc . build_name + " .bin " ) )
2020-05-06 06:27:07 -04:00
2020-05-06 01:49:21 -04:00
if __name__ == " __main__ " :
main ( )