View
@@ -0,0 +1,16 @@
#include <generated/csr.h>
#include <irq.h>
#include <uart.h>
extern void periodic_isr(void);
void isr(void);
void isr(void)
{
unsigned int irqs;
irqs = irq_pending() & irq_getmask();
if(irqs & (1 << UART_INTERRUPT))
uart_isr();
}
View
@@ -0,0 +1,58 @@
INCLUDE generated/output_format.ld
ENTRY(_start)
__DYNAMIC = 0;
INCLUDE generated/regions.ld
SECTIONS
{
.fbi :
{
. = . + 8; /* Firmware Base Image format (len/crc) data comes first. */
} > user_flash
.text :
{
_ftext = .;
*(.text .stub .text.* .gnu.linkonce.t.*)
_etext = .;
} > user_flash
.rodata :
{
. = ALIGN(4);
_frodata = .;
*(.rodata .rodata.* .gnu.linkonce.r.*)
*(.rodata1)
_erodata = .;
} > user_flash
.data :
{
. = ALIGN(4);
_fdata = .;
*(.data .data.* .gnu.linkonce.d.*)
*(.data1)
_gp = ALIGN(16);
*(.sdata .sdata.* .gnu.linkonce.s.*)
_edata = .;
} > sram
.bss :
{
. = ALIGN(4);
_fbss = .;
*(.dynsbss)
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
_end = .;
} > sram
}
PROVIDE(_fstack = ORIGIN(sram) + LENGTH(sram) - 4);
View
@@ -0,0 +1,128 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <irq.h>
#include <uart.h>
#include <console.h>
#include <generated/csr.h>
#include <generated/mem.h>
extern void boot_helper(unsigned int r1, unsigned int r2, unsigned int r3, unsigned int addr);
static void __attribute__((noreturn)) boot(unsigned int r1, unsigned int r2, unsigned int r3, unsigned int addr)
{
printf("Booting program at 0x%x.\n", addr);
uart_sync();
irq_setmask(0);
irq_setie(0);
flush_cpu_icache();
boot_helper(r1, r2, r3, addr);
while(1);
}
static char *readstr(void)
{
char c[2];
static char s[64];
static int ptr = 0;
if(readchar_nonblock()) {
c[0] = readchar();
c[1] = 0;
switch(c[0]) {
case 0x7f:
case 0x08:
if(ptr > 0) {
ptr--;
putsnonl("\x08 \x08");
}
break;
case 0x07:
break;
case '\r':
case '\n':
s[ptr] = 0x00;
putsnonl("\n");
ptr = 0;
return s;
default:
if(ptr >= (sizeof(s) - 1))
break;
putsnonl(c);
s[ptr] = c[0];
ptr++;
break;
}
}
return NULL;
}
static char *get_token(char **str)
{
char *c, *d;
c = (char *)strchr(*str, ' ');
if(c == NULL) {
d = *str;
*str = *str+strlen(*str);
return d;
}
*c = 0;
d = *str;
*str = c+1;
return d;
}
static void help(void)
{
puts("reboot - reboot CPU");
puts("help - this command");
}
static void reboot(void)
{
boot(0, 0, 0, CONFIG_CPU_RESET_ADDR);
}
static void ci_prompt(void)
{
printf("STUB>");
}
static void ci_service(void)
{
char *str;
char *token;
str = readstr();
if(str == NULL) return;
token = get_token(&str);
if(strcmp(token, "help") == 0) {
puts("Available commands:");
help();
}
else if(strcmp(token, "reboot") == 0) reboot();
ci_prompt();
}
int main(void)
{
irq_setmask(0);
irq_setie(1);
uart_init();
puts("Stub firmware booting...\n");
puts("\nLiteX-Buildenv Stub Firmware, built "__DATE__" "__TIME__"\n");
puts("Type \"help\" for help\n");
ci_prompt();
while(1) {
ci_service();
}
return 0;
}
View
10 make.py
@@ -136,7 +136,15 @@ def main():
builder = Builder(soc, **buildargs)
if not args.no_compile_firmware or args.override_firmware:
builder.add_software_package("uip", "{}/firmware/uip".format(os.getcwd()))
builder.add_software_package("firmware", "{}/firmware".format(os.getcwd()))
# FIXME: All platforms which current run their user programs from
# SPI flash lack the block RAM resources to run the default
# firmware. Check whether to use the stub or default firmware
# should be refined (perhaps soc attribute?).
if "main_ram" in (m[0] for m in soc.get_memory_regions()):
builder.add_software_package("firmware", "{}/firmware".format(os.getcwd()))
else:
builder.add_software_package("stub", "{}/firmware/stub".format(os.getcwd()))
vns = builder.build(**dict(args.build_option))
else:
vns = platform.build(soc, build_dir=os.path.join(builddir, "gateware"))
View
@@ -0,0 +1,75 @@
from litex.build.generic_platform import *
from litex.build.lattice import LatticePlatform
from litex.build.lattice.programmer import TinyProgProgrammer
_io = [
("user_led", 0, Pins("B3"), IOStandard("LVCMOS33")),
("usb", 0,
Subsignal("d_p", Pins("B4")),
Subsignal("d_n", Pins("A4")),
Subsignal("pullup", Pins("A3")),
IOStandard("LVCMOS33")
),
("spiflash", 0,
Subsignal("cs_n", Pins("F7"), IOStandard("LVCMOS33")),
Subsignal("clk", Pins("G7"), IOStandard("LVCMOS33")),
Subsignal("mosi", Pins("G6"), IOStandard("LVCMOS33")),
Subsignal("miso", Pins("H7"), IOStandard("LVCMOS33")),
Subsignal("wp", Pins("H4"), IOStandard("LVCMOS33")),
Subsignal("hold", Pins("J8"), IOStandard("LVCMOS33"))
),
("spiflash4x", 0,
Subsignal("cs_n", Pins("F7"), IOStandard("LVCMOS33")),
Subsignal("clk", Pins("G7"), IOStandard("LVCMOS33")),
Subsignal("dq", Pins("G6 H7 H4 J8"), IOStandard("LVCMOS33"))
),
("clk16", 0, Pins("B2"), IOStandard("LVCMOS33"))
]
_connectors = [
# A2-H2, Pins 1-13
# H9-A6, Pins 14-24
# G1-J2, Pins 25-31
("GPIO", "A2 A1 B1 C2 C1 D2 D1 E2 E1 G2 H1 J1 H2 H9 D9 D8 C9 A9 B8 A8 B7 A7 B6 A6"),
("EXTRA", "G1 J3 J4 G9 J9 E8 J2")
]
# Default peripherals
serial = [
("serial", 0,
Subsignal("tx", Pins("GPIO:0")),
Subsignal("rx", Pins("GPIO:1")),
IOStandard("LVCMOS33")
)
]
class Platform(LatticePlatform):
name = "tinyfpga_bx"
default_clk_name = "clk16"
default_clk_period = 62.5
# TinyFPGA BX normally defines the user bitstream to begin at 0x28000
# and user data to begin at 0x50000; follow the convention here.
bootloader_size = 0x28000
gateware_size = 0x50000 - bootloader_size
# FIXME: Create a "spi flash module" object in the same way we have SDRAM
spiflash_model = "m25p16"
spiflash_read_dummy_bits = 8
spiflash_clock_div = 2
spiflash_total_size = int((8/8)*1024*1024) # 8Mbit
spiflash_page_size = 256
spiflash_sector_size = 0x10000
def __init__(self):
LatticePlatform.__init__(self, "ice40-lp8k-cm81", _io, _connectors,
toolchain="icestorm")
def create_programmer(self):
return TinyProgProgrammer()
View
@@ -53,129 +53,6 @@ if [ ! -d $BUILD_DIR ]; then
mkdir -p $BUILD_DIR
fi
# FIXME: Move this to a separate script!
# Cutback Xilinx ISE for CI
# --------
# Save the passphrase to a file so we don't echo it in the logs
if [ ! -z "$XILINX_PASSPHRASE" ]; then
XILINX_PASSPHRASE_FILE=$(tempfile -s .passphrase | mktemp --suffix=.passphrase)
trap "rm -f -- '$XILINX_PASSPHRASE_FILE'" EXIT
echo $XILINX_PASSPHRASE >> $XILINX_PASSPHRASE_FILE
# Need gpg to do the unencryption
export XILINX_DIR=$BUILD_DIR/Xilinx
export LIKELY_XILINX_LICENSE_DIR=$XILINX_DIR
if [ ! -d "$XILINX_DIR" -o ! -d "$XILINX_DIR/opt" ]; then
(
cd $BUILD_DIR
mkdir -p Xilinx
cd Xilinx
wget -q http://xilinx.timvideos.us/index.txt -O xilinx-details.txt
XILINX_TAR_INFO=$(cat xilinx-details.txt | grep tar.bz2.gpg | tail -n 1)
XILINX_TAR_FILE=$(echo $XILINX_TAR_INFO | sed -e's/[^ ]* //' -e's/.gpg$//')
XILINX_TAR_MD5=$(echo $XILINX_TAR_INFO | sed -e's/ .*//')
# This setup was taken from https://github.com/m-labs/artiq/blob/master/.travis/get-xilinx.sh
wget --no-verbose -c http://xilinx.timvideos.us/${XILINX_TAR_FILE}.gpg
cat $XILINX_PASSPHRASE_FILE | gpg --batch --passphrase-fd 0 ${XILINX_TAR_FILE}.gpg
tar -xjf $XILINX_TAR_FILE
# Remove the tar file to free up space.
rm ${XILINX_TAR_FILE}*
# FIXME: Hacks to try and make Vivado work.
mkdir -p $XILINX_DIR/opt/Xilinx/Vivado/2017.3/scripts/rt/data/svlog/sdbs
mkdir -p $XILINX_DIR/opt/Xilinx/Vivado/2017.3/tps/lnx64/jre
# Make ISE stop complaining about missing wbtc binary
mkdir -p $XILINX_DIR/opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64
ln -s /bin/true $XILINX_DIR/opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/wbtc
# Relocate ISE from /opt to $XILINX_DIR
for i in $(grep -l -Rsn "/opt/Xilinx" $XILINX_DIR/opt)
do
sed -i -e "s!/opt/Xilinx!$XILINX_DIR/opt/Xilinx!g" $i
done
wget --no-verbose http://xilinx.timvideos.us/Xilinx.lic.gpg
cat $XILINX_PASSPHRASE_FILE | gpg --batch --passphrase-fd 0 Xilinx.lic.gpg
#git clone https://github.com/mithro/impersonate_macaddress
#cd impersonate_macaddress
#make
)
fi
rm $XILINX_PASSPHRASE_FILE
trap - EXIT
fi
if [ -z "$LIKELY_XILINX_LICENSE_DIR" ]; then
LIKELY_XILINX_LICENSE_DIR="$HOME/.Xilinx"
fi
XILINX_SETTINGS_ISE='/opt/Xilinx/*/ISE_DS/settings64.sh'
XILINX_SETTINGS_VIVADO='/opt/Xilinx/Vivado/*/settings64.sh'
if [ -z "$XILINX_DIR" ]; then
LOCAL_XILINX_DIR=$BUILD_DIR/Xilinx
if [ -d "$LOCAL_XILINX_DIR/opt/Xilinx/" ]; then
# Reserved MAC address from documentation block, see
# http://www.iana.org/assignments/ethernet-numbers/ethernet-numbers.xhtml
export LIKELY_XILINX_LICENSE_DIR=$LOCAL_XILINX_DIR
export MACADDR=90:10:00:00:00:01
#export LD_PRELOAD=$XILINX_DIR/impersonate_macaddress/impersonate_macaddress.so
#ls -l $LD_PRELOAD
export XILINX_DIR=$LOCAL_XILINX_DIR
export XILINX_LOCAL_USER_DATA=no
fi
fi
if [ -z "$LIKELY_XILINX_LICENSE_DIR" ]; then
LIKELY_XILINX_LICENSE_DIR="$HOME/.Xilinx"
fi
shopt -s nullglob
XILINX_SETTINGS_ISE=($XILINX_DIR/$XILINX_SETTINGS_ISE)
XILINX_SETTINGS_VIVADO=($XILINX_DIR/$XILINX_SETTINGS_VIVADO)
shopt -u nullglob
echo " Xilinx directory is: $XILINX_DIR/opt/Xilinx/"
if [ ${#XILINX_SETTINGS_ISE[@]} -gt 0 ]; then
echo -n " - Xilinx ISE toolchain found!"
if [ ${#XILINX_SETTINGS_ISE[@]} -gt 1 ]; then
echo -n " (${#XILINX_SETTINGS_ISE[@]} versions)"
fi
echo ""
export HAVE_XILINX_ISE=1
else
export HAVE_XILINX_ISE=0
fi
if [ ${#XILINX_SETTINGS_VIVADO[@]} -gt 0 ]; then
echo -n " - Xilinx Vivado toolchain found!"
if [ ${#XILINX_SETTINGS_VIVADO[@]} -gt 1 ]; then
echo -n " (${#XILINX_SETTINGS_VIVADO[@]} versions)"
fi
echo ""
export HAVE_XILINX_VIVADO=1
else
export HAVE_XILINX_VIVADO=0
fi
if [ $HAVE_XILINX_ISE -eq 1 -o $HAVE_XILINX_VIVADO -eq 1 ]; then
export HAVE_XILINX_TOOLCHAIN=1
else
export HAVE_XILINX_TOOLCHAIN=0
fi
if [ $HAVE_XILINX_TOOLCHAIN -eq 1 ]; then
export MISOC_EXTRA_CMDLINE="-Ob toolchain_path $XILINX_DIR/opt/Xilinx/"
fi
# Detect a likely lack of license early, but just warn if it's missing
# just in case they've set it up elsewhere.
if [ ! -e $LIKELY_XILINX_LICENSE_DIR/Xilinx.lic ]; then
echo "(WARNING) Please ensure you have installed Xilinx and have a license."
echo "(WARNING) Copy your Xilinx license to Xilinx.lic in $LIKELY_XILINX_LICENSE_DIR to suppress this warning."
else
echo " Xilinx license in: $LIKELY_XILINX_LICENSE_DIR"
export XILINXD_LICENSE_FILE=$LIKELY_XILINX_LICENSE_DIR
fi
function check_exists {
TOOL=$1
if which $TOOL >/dev/null; then
@@ -285,9 +162,115 @@ conda install -y $CONDA_FLAGS python=3.6
fix_conda
check_version python 3.6
# FPGA toolchain
################################################
echo ""
echo "Installing binaries into environment"
echo "---------------------------------"
echo "Installing FPGA toolchain"
echo "---------------------------------------"
PLATFORM_TOOLCHAIN=$(grep 'class Platform' $TOP_DIR/platforms/$PLATFORM.py | sed -e's/class Platform(//' -e's/Platform)://')
echo ""
echo "Platform Toolchain: $PLATFORM_TOOLCHAIN"
case $PLATFORM_TOOLCHAIN in
Xilinx)
$TOP_DIR/.travis/download-xilinx.sh
if [ -z "$LIKELY_XILINX_LICENSE_DIR" ]; then
LIKELY_XILINX_LICENSE_DIR="$HOME/.Xilinx"
fi
XILINX_SETTINGS_ISE='/opt/Xilinx/*/ISE_DS/settings64.sh'
XILINX_SETTINGS_VIVADO='/opt/Xilinx/Vivado/*/settings64.sh'
if [ -z "$XILINX_DIR" ]; then
LOCAL_XILINX_DIR=$BUILD_DIR/Xilinx
if [ -d "$LOCAL_XILINX_DIR/opt/Xilinx/" ]; then
# Reserved MAC address from documentation block, see
# http://www.iana.org/assignments/ethernet-numbers/ethernet-numbers.xhtml
export LIKELY_XILINX_LICENSE_DIR=$LOCAL_XILINX_DIR
export MACADDR=90:10:00:00:00:01
#export LD_PRELOAD=$XILINX_DIR/impersonate_macaddress/impersonate_macaddress.so
#ls -l $LD_PRELOAD
export XILINX_DIR=$LOCAL_XILINX_DIR
export XILINX_LOCAL_USER_DATA=no
fi
fi
if [ -z "$LIKELY_XILINX_LICENSE_DIR" ]; then
LIKELY_XILINX_LICENSE_DIR="$HOME/.Xilinx"
fi
# Find Xilinx toolchain versions...
shopt -s nullglob
XILINX_SETTINGS_ISE=($XILINX_DIR/$XILINX_SETTINGS_ISE)
XILINX_SETTINGS_VIVADO=($XILINX_DIR/$XILINX_SETTINGS_VIVADO)
shopt -u nullglob
# Tell user what we found...
echo " Xilinx directory is: $XILINX_DIR/opt/Xilinx/"
if [ ${#XILINX_SETTINGS_ISE[@]} -gt 0 ]; then
echo -n " - Xilinx ISE toolchain found!"
if [ ${#XILINX_SETTINGS_ISE[@]} -gt 1 ]; then
echo -n " (${#XILINX_SETTINGS_ISE[@]} versions)"
fi
echo ""
export HAVE_XILINX_ISE=1
else
export HAVE_XILINX_ISE=0
fi
if [ ${#XILINX_SETTINGS_VIVADO[@]} -gt 0 ]; then
echo -n " - Xilinx Vivado toolchain found!"
if [ ${#XILINX_SETTINGS_VIVADO[@]} -gt 1 ]; then
echo -n " (${#XILINX_SETTINGS_VIVADO[@]} versions)"
fi
echo ""
export HAVE_XILINX_VIVADO=1
else
export HAVE_XILINX_VIVADO=0
fi
if [ $HAVE_XILINX_ISE -eq 1 -o $HAVE_XILINX_VIVADO -eq 1 ]; then
export HAVE_XILINX_TOOLCHAIN=1
export HAVE_FPGA_TOOLCHAIN=1
else
export HAVE_XILINX_TOOLCHAIN=0
export HAVE_FPGA_TOOLCHAIN=0
fi
if [ $HAVE_XILINX_TOOLCHAIN -eq 1 ]; then
export MISOC_EXTRA_CMDLINE="-Ob toolchain_path $XILINX_DIR/opt/Xilinx/"
fi
# Detect a likely lack of license early, but just warn if it's missing
# just in case they've set it up elsewhere.
if [ ! -e $LIKELY_XILINX_LICENSE_DIR/Xilinx.lic ]; then
echo "(WARNING) Please ensure you have installed Xilinx and have a license."
echo "(WARNING) Copy your Xilinx license to Xilinx.lic in $LIKELY_XILINX_LICENSE_DIR to suppress this warning."
else
echo " Xilinx license in: $LIKELY_XILINX_LICENSE_DIR"
export XILINXD_LICENSE_FILE=$LIKELY_XILINX_LICENSE_DIR
fi
;;
Lattice)
export HAVE_FPGA_TOOLCHAIN=1
# yosys
echo
echo "Installing yosys (FOSS Synthesis tool)"
conda install -y $CONDA_FLAGS yosys
check_exists yosys
# nextpnr
echo
echo "Installing nextpnr (FOSS Place and Route tool)"
conda install -y $CONDA_FLAGS nextpnr
check_exists nextpnr-ice40
;;
*)
;;
esac
# FPGA Programming tools
################################################
echo ""
echo "Installing programming tools in environment"
echo "-----------------------------------------"
# fxload
if [ "$PLATFORM" = "opsis" -o "$PLATFORM" = "atlys" ]; then
@@ -310,19 +293,30 @@ if [ "$PLATFORM" == "mimasv2" ]; then
check_exists MimasV2Config.py
fi
# Map to the C compiler
if [ "$CPU" = "lm32" -o "$CPU" = "or1k" ]; then
CPU_ARCH=$CPU
elif [ "$CPU" = "vexriscv" -o "$CPU" = "picorv32" ]; then
CPU_ARCH=riscv32-unknown
fi
# flterm
echo
echo "Installing flterm (serial terminal tool)"
conda install -y $CONDA_FLAGS flterm
check_exists flterm
# openocd for programming via Cypress FX2
echo
echo "Installing openocd (jtag tool for programming and debug)"
conda install -y $CONDA_FLAGS openocd=$OPENOCD_VERSION
check_version openocd $OPENOCD_VERSION
# C compiler toolchain
################################################
echo ""
echo "Installing C compiler toolchain"
echo "---------------------------------------"
if [ "$CPU" = "lm32" -o "$CPU" = "or1k" ]; then
CPU_ARCH=$CPU
elif [ "$CPU" = "vexriscv" -o "$CPU" = "picorv32" ]; then
CPU_ARCH=riscv32-unknown
fi
# binutils for the target
echo
echo "Installing binutils for ${CPU_ARCH} (assembler, linker, and other tools)"
@@ -341,12 +335,9 @@ check_version ${CPU_ARCH}-elf-gcc $GCC_VERSION
#conda install -y $CONDA_FLAGS gdb-${CPU_ARCH}-elf=$GDB_VERSION
#check_version ${CPU_ARCH}-elf-gdb $GDB_VERSION
# openocd for programming via Cypress FX2
echo
echo "Installing openocd (jtag tool for programming and debug)"
conda install -y $CONDA_FLAGS openocd=$OPENOCD_VERSION
check_version openocd $OPENOCD_VERSION
# Python modules
################################################
echo ""
echo "Installing Python modules into environment"
echo "---------------------------------------"
View
@@ -77,73 +77,6 @@ if [ ! -d $BUILD_DIR ]; then
return 1
fi
XILINX_SETTINGS_ISE='/opt/Xilinx/*/ISE_DS/settings64.sh'
XILINX_SETTINGS_VIVADO='/opt/Xilinx/Vivado/*/settings64.sh'
if [ -z "$XILINX_DIR" ]; then
LOCAL_XILINX_DIR=$BUILD_DIR/Xilinx
if [ -d "$LOCAL_XILINX_DIR/opt/Xilinx/" ]; then
# Reserved MAC address from documentation block, see
# http://www.iana.org/assignments/ethernet-numbers/ethernet-numbers.xhtml
export LIKELY_XILINX_LICENSE_DIR=$LOCAL_XILINX_DIR
export MACADDR=90:10:00:00:00:01
#export LD_PRELOAD=$XILINX_DIR/impersonate_macaddress/impersonate_macaddress.so
#ls -l $LD_PRELOAD
export XILINX_DIR=$LOCAL_XILINX_DIR
export XILINX_LOCAL_USER_DATA=no
fi
fi
if [ -z "$LIKELY_XILINX_LICENSE_DIR" ]; then
LIKELY_XILINX_LICENSE_DIR="$HOME/.Xilinx"
fi
# Find Xilinx toolchain versions...
shopt -s nullglob
XILINX_SETTINGS_ISE=($XILINX_DIR/$XILINX_SETTINGS_ISE)
XILINX_SETTINGS_VIVADO=($XILINX_DIR/$XILINX_SETTINGS_VIVADO)
shopt -u nullglob
# Tell user what we found...
echo " Xilinx directory is: $XILINX_DIR/opt/Xilinx/"
if [ ${#XILINX_SETTINGS_ISE[@]} -gt 0 ]; then
echo -n " - Xilinx ISE toolchain found!"
if [ ${#XILINX_SETTINGS_ISE[@]} -gt 1 ]; then
echo -n " (${#XILINX_SETTINGS_ISE[@]} versions)"
fi
echo ""
export HAVE_XILINX_ISE=1
else
export HAVE_XILINX_ISE=0
fi
if [ ${#XILINX_SETTINGS_VIVADO[@]} -gt 0 ]; then
echo -n " - Xilinx Vivado toolchain found!"
if [ ${#XILINX_SETTINGS_VIVADO[@]} -gt 1 ]; then
echo -n " (${#XILINX_SETTINGS_VIVADO[@]} versions)"
fi
echo ""
export HAVE_XILINX_VIVADO=1
else
export HAVE_XILINX_VIVADO=0
fi
if [ $HAVE_XILINX_ISE -eq 1 -o $HAVE_XILINX_VIVADO -eq 1 ]; then
export HAVE_XILINX_TOOLCHAIN=1
else
export HAVE_XILINX_TOOLCHAIN=0
fi
if [ $HAVE_XILINX_TOOLCHAIN -eq 1 ]; then
export MISOC_EXTRA_CMDLINE="-Ob toolchain_path $XILINX_DIR/opt/Xilinx/"
fi
# Detect a likely lack of license early, but just warn if it's missing
# just in case they've set it up elsewhere.
if [ ! -e $LIKELY_XILINX_LICENSE_DIR/Xilinx.lic ]; then
echo "(WARNING) Please ensure you have installed Xilinx and have a license."
echo "(WARNING) Copy your Xilinx license to Xilinx.lic in $LIKELY_XILINX_LICENSE_DIR to suppress this warning."
else
echo " Xilinx license in: $LIKELY_XILINX_LICENSE_DIR"
export XILINXD_LICENSE_FILE=$LIKELY_XILINX_LICENSE_DIR
fi
function check_exists {
TOOL=$1
if which $TOOL >/dev/null; then
@@ -211,17 +144,120 @@ eval $(cd $TOP_DIR; export HDMI2USB_ENV=1; make env || return 1) || return 1
) || return 1
# Check the Python version
check_version python 3.6 || return 1
# FPGA toolchain
################################################
echo ""
echo "Checking binaries in environment"
echo "---------------------------------"
echo "Checking FPGA toolchain"
echo "---------------------------------------"
PLATFORM_TOOLCHAIN=$(grep 'class Platform' $TOP_DIR/platforms/$PLATFORM.py | sed -e's/class Platform(//' -e's/Platform)://')
echo ""
echo "Platform Toolchain: $PLATFORM_TOOLCHAIN"
case $PLATFORM_TOOLCHAIN in
Xilinx)
if [ -z "$LIKELY_XILINX_LICENSE_DIR" ]; then
LIKELY_XILINX_LICENSE_DIR="$HOME/.Xilinx"
fi
XILINX_SETTINGS_ISE='/opt/Xilinx/*/ISE_DS/settings64.sh'
XILINX_SETTINGS_VIVADO='/opt/Xilinx/Vivado/*/settings64.sh'
if [ -z "$XILINX_DIR" ]; then
LOCAL_XILINX_DIR=$BUILD_DIR/Xilinx
if [ -d "$LOCAL_XILINX_DIR/opt/Xilinx/" ]; then
# Reserved MAC address from documentation block, see
# http://www.iana.org/assignments/ethernet-numbers/ethernet-numbers.xhtml
export LIKELY_XILINX_LICENSE_DIR=$LOCAL_XILINX_DIR
export MACADDR=90:10:00:00:00:01
#export LD_PRELOAD=$XILINX_DIR/impersonate_macaddress/impersonate_macaddress.so
#ls -l $LD_PRELOAD
export XILINX_DIR=$LOCAL_XILINX_DIR
export XILINX_LOCAL_USER_DATA=no
fi
fi
if [ -z "$LIKELY_XILINX_LICENSE_DIR" ]; then
LIKELY_XILINX_LICENSE_DIR="$HOME/.Xilinx"
fi
# Find Xilinx toolchain versions...
shopt -s nullglob
XILINX_SETTINGS_ISE=($XILINX_DIR/$XILINX_SETTINGS_ISE)
XILINX_SETTINGS_VIVADO=($XILINX_DIR/$XILINX_SETTINGS_VIVADO)
shopt -u nullglob
# Tell user what we found...
echo " Xilinx directory is: $XILINX_DIR/opt/Xilinx/"
if [ ${#XILINX_SETTINGS_ISE[@]} -gt 0 ]; then
echo -n " - Xilinx ISE toolchain found!"
if [ ${#XILINX_SETTINGS_ISE[@]} -gt 1 ]; then
echo -n " (${#XILINX_SETTINGS_ISE[@]} versions)"
fi
echo ""
export HAVE_XILINX_ISE=1
else
export HAVE_XILINX_ISE=0
fi
if [ ${#XILINX_SETTINGS_VIVADO[@]} -gt 0 ]; then
echo -n " - Xilinx Vivado toolchain found!"
if [ ${#XILINX_SETTINGS_VIVADO[@]} -gt 1 ]; then
echo -n " (${#XILINX_SETTINGS_VIVADO[@]} versions)"
fi
echo ""
export HAVE_XILINX_VIVADO=1
else
export HAVE_XILINX_VIVADO=0
fi
if [ $HAVE_XILINX_ISE -eq 1 -o $HAVE_XILINX_VIVADO -eq 1 ]; then
export HAVE_XILINX_TOOLCHAIN=1
export HAVE_FPGA_TOOLCHAIN=1
else
export HAVE_XILINX_TOOLCHAIN=0
export HAVE_FPGA_TOOLCHAIN=0
fi
if [ $HAVE_XILINX_TOOLCHAIN -eq 1 ]; then
export MISOC_EXTRA_CMDLINE="-Ob toolchain_path $XILINX_DIR/opt/Xilinx/"
fi
# Detect a likely lack of license early, but just warn if it's missing
# just in case they've set it up elsewhere.
if [ ! -e $LIKELY_XILINX_LICENSE_DIR/Xilinx.lic ]; then
echo "(WARNING) Please ensure you have installed Xilinx and have a license."
echo "(WARNING) Copy your Xilinx license to Xilinx.lic in $LIKELY_XILINX_LICENSE_DIR to suppress this warning."
else
echo " Xilinx license in: $LIKELY_XILINX_LICENSE_DIR"
export XILINXD_LICENSE_FILE=$LIKELY_XILINX_LICENSE_DIR
fi
;;
Lattice)
export HAVE_FPGA_TOOLCHAIN=1
# yosys
check_exists yosys || return 1
# nextpnr
check_exists nextpnr-ice40 || return 1
;;
*)
;;
esac
# FPGA Programming tools
################################################
echo ""
echo "Checking programming tools in environment"
echo "-----------------------------------------"
# fxload
if [ "$PLATFORM" = "opsis" -o "$PLATFORM" = "atlys" ]; then
@@ -244,19 +280,30 @@ if [ "$PLATFORM" = "mimasv2" ]; then
check_exists MimasV2Config.py || return 1
fi
# Map to the C compiler
if [ "$CPU" = "lm32" -o "$CPU" = "or1k" ]; then
CPU_ARCH=$CPU
elif [ "$CPU" = "vexriscv" -o "$CPU" = "picorv32" ]; then
CPU_ARCH=riscv32-unknown
fi
# flterm
check_exists flterm || return 1
# openocd for programming via Cypress FX2
check_version openocd $OPENOCD_VERSION || return 1
# C compiler toolchain
################################################
echo ""
echo "Checking C compiler toolchain"
echo "---------------------------------------"
if [ "$CPU" = "lm32" -o "$CPU" = "or1k" ]; then
CPU_ARCH=$CPU
elif [ "$CPU" = "vexriscv" -o "$CPU" = "picorv32" ]; then
CPU_ARCH=riscv32-unknown
fi
# binutils for the target
@@ -275,12 +322,9 @@ check_version ${CPU_ARCH}-elf-gcc $GCC_VERSION || return 1
#
#check_version ${CPU_ARCH}-elf-gdb $GDB_VERSION
# openocd for programming via Cypress FX2
check_version openocd $OPENOCD_VERSION || return 1
# Python modules
################################################
echo ""
echo "Checking Python modules in environment"
echo "---------------------------------------"
View
@@ -0,0 +1,70 @@
# tinyfpga_bx targets
ifneq ($(PLATFORM),tinyfpga_bx)
$(error "Platform should be tinyfpga_bx when using this file!?")
endif
# Settings
DEFAULT_TARGET = base
TARGET ?= $(DEFAULT_TARGET)
BAUD ?= 115200
# Image
image-flash-$(PLATFORM):
tinyprog --program-image $(IMAGE_FILE)
# Gateware
gateware-load-$(PLATFORM):
@echo "TinyFPGA BX doesn't support loading, use the flash target instead."
@echo "make gateware-flash"
@echo $(GATEWARE_FILEBASE)
@echo $(GATEWARE_BIOS_FILE)
@echo $(IMAGE_FILE)
@echo $(BIOS_FILE)
@false
# As with Mimasv2, if the user asks to flash the gateware only, the BIOS must
# be sent as well (because the BIOS is too big to fit into the bitstream).
GATEWARE_BIOS_FILE = $(TARGET_BUILD_DIR)/image-gateware+bios+none.bin
gateware-flash-$(PLATFORM): $(GATEWARE_BIOS_FILE)
tinyprog --program-image $(GATEWARE_BIOS_FILE)
# To avoid duplicating the mkimage.py call here, if the user has not
# already built a image-gateware+bios+none.bin, we call make recursively
# to build one here, with the FIRMWARE=none override.
#
ifneq ($(GATEWARE_BIOS_FILE),$(IMAGE_FILE))
$(GATEWARE_BIOS_FILE): $(GATEWARE_FILEBASE).bin $(BIOS_FILE) mkimage.py
FIRMWARE=none make image
endif
# Firmware
firmware-load-$(PLATFORM):
@echo "Unsupported."
@false
firmware-flash-$(PLATFORM):
@echo "TinyFPGA BX doesn't support just flashing firmware, use image target instead."
@echo "make image-flash"
@false
firmware-connect-$(PLATFORM):
flterm --port=$(COMM_PORT) --speed=$(BAUD)
firmware-clear-$(PLATFORM):
@echo "FIXME: Unsupported?."
@false
# Bios
bios-flash-$(PLATFORM):
@echo "Unsupported."
@false
# Extra commands
help-$(PLATFORM):
@true
reset-$(PLATFORM):
@echo "Unsupported."
@false
View
@@ -0,0 +1,123 @@
import sys
import struct
import os.path
import argparse
from migen import *
from migen.genlib.resetsync import AsyncResetSynchronizer
from litex.build.generic_platform import Pins, Subsignal, IOStandard
from litex.soc.integration.soc_core import *
from litex.soc.integration.builder import *
from gateware import info
from gateware import spi_flash
from targets.utils import csr_map_update
This conversation was marked as resolved by mithro

This comment has been minimized.

@mithro

mithro Sep 11, 2018

Member

This seems duplicate with the platform/tinyfpga_bx.py file?

@mithro

mithro Sep 11, 2018

Member

This seems duplicate with the platform/tinyfpga_bx.py file?

This comment has been minimized.

@cr1901

cr1901 Sep 12, 2018

Contributor

I don't see csr_map_update imported anywhere in platform/tinyfpga_bx/py?

@cr1901

cr1901 Sep 12, 2018

Contributor

I don't see csr_map_update imported anywhere in platform/tinyfpga_bx/py?

This comment has been minimized.

@mithro

mithro Sep 13, 2018

Member

I think this comment was actually attached to code you removed. Closing.

@mithro

mithro Sep 13, 2018

Member

I think this comment was actually attached to code you removed. Closing.

serial = [
("serial", 0,
Subsignal("tx", Pins("GPIO:2")),
Subsignal("rx", Pins("GPIO:1")),
IOStandard("LVCMOS33")
)
]
reset = [
("rst", 0, Pins("GPIO:6"), IOStandard("LVCMOS33")),
]
class _CRG(Module):
def __init__(self, platform):
clk16 = platform.request("clk16")
rst = platform.request("rst")
self.clock_domains.cd_sys = ClockDomain()
self.reset = Signal()
# FIXME: Use PLL, increase system clock to 32 MHz, pending nextpnr
# fixes.
self.comb += self.cd_sys.clk.eq(clk16)
# POR reset logic- POR generated from sys clk, POR logic feeds sys clk
# reset.
self.clock_domains.cd_por = ClockDomain()
reset_delay = Signal(12, reset=4095)
self.comb += [
self.cd_por.clk.eq(self.cd_sys.clk),
self.cd_sys.rst.eq(reset_delay != 0)
]
self.sync.por += \
If(reset_delay != 0,
reset_delay.eq(reset_delay - 1)
)
self.specials += AsyncResetSynchronizer(self.cd_por, rst | self.reset)
class BaseSoC(SoCCore):
csr_peripherals = (
"spiflash",
"info",
)
csr_map_update(SoCCore.csr_map, csr_peripherals)
mem_map = {
"spiflash": 0x20000000, # (default shadow @0xa0000000)
}
mem_map.update(SoCCore.mem_map)
def __init__(self, platform, **kwargs):
if 'integrated_rom_size' not in kwargs:
kwargs['integrated_rom_size']=0
if 'integrated_sram_size' not in kwargs:
kwargs['integrated_sram_size']=0x2800
# FIXME: Force either lite or minimal variants of CPUs; full is too big.
platform.add_extension(serial)
platform.add_extension(reset)
clk_freq = int(16e6)
# Extra 0x28000 is due to bootloader bitstream.
This conversation was marked as resolved by mithro

This comment has been minimized.

@mithro

mithro Sep 11, 2018

Member

BOOTLOADER_SIZE would probably be a good define to put on the platform object...

Magic numbers bad, m'kay? :-P

@mithro

mithro Sep 11, 2018

Member

BOOTLOADER_SIZE would probably be a good define to put on the platform object...

Magic numbers bad, m'kay? :-P

kwargs['cpu_reset_address']=self.mem_map["spiflash"]+platform.gateware_size+platform.bootloader_size
SoCCore.__init__(self, platform, clk_freq, **kwargs)
self.submodules.crg = _CRG(platform)
self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/clk_freq)
# SPI flash peripheral
self.submodules.spiflash = spi_flash.SpiFlashSingle(
platform.request("spiflash"),
dummy=platform.spiflash_read_dummy_bits,
div=platform.spiflash_clock_div)
self.add_constant("SPIFLASH_PAGE_SIZE", platform.spiflash_page_size)
self.add_constant("SPIFLASH_SECTOR_SIZE", platform.spiflash_sector_size)
self.register_mem("spiflash", self.mem_map["spiflash"],
self.spiflash.bus, size=platform.spiflash_total_size)
bios_size = 0x8000
self.add_constant("ROM_DISABLE", 1)
self.add_memory_region("rom", kwargs['cpu_reset_address'], bios_size)
self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size+platform.bootloader_size
# We don't have a DRAM, so use the remaining SPI flash for user
# program.
self.add_memory_region("user_flash",
self.flash_boot_address,
# Leave a grace area- possible one-by-off bug in add_memory_region?
# Possible fix: addr < origin + length - 1
platform.spiflash_total_size - (self.flash_boot_address - self.mem_map["spiflash"]) - 0x100)
# Disable USB activity until we switch to a USB UART.
self.comb += [platform.request("usb").pullup.eq(0)]
# Arachne-pnr is unsupported- it has trouble routing this design
# on this particular board reliably. That said, annotate the build
# template anyway just in case.
# Disable final deep-sleep power down so firmware words are loaded
# onto softcore's address bus.
platform.toolchain.build_template[3] = "icepack -s {build_name}.txt {build_name}.bin"
platform.toolchain.nextpnr_build_template[2] = "icepack -s {build_name}.txt {build_name}.bin"
SoC = BaseSoC