New Lattice iCE40 FPGA development platform // Resolve #480

This commit is contained in:
Ivan Kravets
2016-04-26 11:43:46 +03:00
parent f3e8cd9707
commit b51d95aba5
8 changed files with 336 additions and 1 deletions
+149
View File
@@ -0,0 +1,149 @@
"""
Build script for lattice ice40 FPGAs
latticeice40-builder.py
"""
import os
from os.path import join
from SCons.Script import (COMMAND_LINE_TARGETS, AlwaysBuild, Builder, Default,
DefaultEnvironment, Environment, Exit, GetOption,
Glob)
env = DefaultEnvironment()
env.Replace(PROGNAME="hardware")
env.Append(SIMULNAME="simulation")
# -- Get the local folder in which the icestorm tools should be installed
piopackages_dir = env.subst('$PIOPACKAGES_DIR')
bin_dir = join(piopackages_dir, 'toolchain-icestorm', 'bin')
# -- Add this path to the PATH env variable. First the building tools will be
# -- searched in the local PATH. If they are not founde, the global ones will
# -- be executed (if installed)
env.PrependENVPath('PATH', bin_dir)
# -- Target name for synthesis
TARGET = join(env['BUILD_DIR'], env['PROGNAME'])
# -- Target name for simulation
# TARGET_SIM = join(env['PROJECT_DIR'], env['SIMULNAME'])
# -- Get a list of all the verilog files in the src folfer, in ASCII, with
# -- the full path. All these files are used for the simulation
v_nodes = Glob(join(env['PROJECTSRC_DIR'], '*.v'))
src_sim = ["{}".format(f) for f in v_nodes]
# --------- Get the Testbench file (there should be only 1)
# -- Create a list with all the files finished in _tb.v. It should contain
# -- the test bench
list_tb = [f for f in src_sim if f[-5:].upper() == "_TB.V"]
if len(list_tb) > 1:
print "---> WARNING: More than one testbenches used"
# -- Error checking
try:
testbench = list_tb[0]
# -- there is no testbench
except IndexError:
testbench = None
if 'sim' in COMMAND_LINE_TARGETS:
if testbench is None:
print "ERROR!!! NO testbench found for simulation"
Exit(1)
# -- Simulation name
testbench_file = os.path.split(testbench)[-1]
SIMULNAME, ext = os.path.splitext(testbench_file)
else:
SIMULNAME = ''
TARGET_SIM = join(env.subst('$BUILD_DIR'), SIMULNAME)
# -------- Get the synthesis files. They are ALL the files except the
# -------- testbench
src_synth = [f for f in src_sim if f not in list_tb]
# -- For debugging
print "Testbench: {}".format(testbench)
# -- Get the PCF file
src_dir = env.subst('$PROJECTSRC_DIR')
PCFs = join(src_dir, '*.pcf')
PCF_list = Glob(PCFs)
try:
PCF = PCF_list[0]
except IndexError:
print "\n--------> ERROR: no .pcf file found <----------\n"
Exit(2)
# -- Debug
print "----> PCF Found: {}".format(PCF)
# -- Builder 1 (.v --> .blif)
synth = Builder(action='yosys -p \"synth_ice40 -blif {}.blif\" \
$SOURCES'.format(TARGET),
suffix='.blif',
src_suffix='.v')
# -- Builder 2 (.blif --> .asc)
pnr = Builder(action='arachne-pnr -d 1k -o $TARGET -p {} \
$SOURCE'.format(PCF),
suffix='.asc',
src_suffix='.blif')
# -- Builder 3 (.asc --> .bin)
bitstream = Builder(action='icepack $SOURCE $TARGET',
suffix='.bin',
src_suffix='.asc')
# -- Builder 4 (.asc --> .rpt)
time_rpt = Builder(action='icetime -mtr $TARGET $SOURCE',
suffix='.rpt',
src_suffix='.asc')
env.Append(BUILDERS={'Synth': synth, 'PnR': pnr, 'Bin': bitstream,
'Time': time_rpt})
blif = env.Synth(TARGET, [src_synth])
asc = env.PnR(TARGET, [blif, PCF])
binf = env.Bin(TARGET, asc)
upload = env.Alias('upload', binf, 'iceprog ' + ' $SOURCE')
AlwaysBuild(upload)
# -- Target for calculating the time (.rpt)
# rpt = env.Time(asc)
t = env.Alias('time', env.Time('time.rpt', asc))
# -------------------- Simulation ------------------
# -- Constructor para generar simulacion: icarus Verilog
iverilog = Builder(action='iverilog -o $TARGET $SOURCES ',
suffix='.out',
src_suffix='.v')
vcd = Builder(action=' $SOURCE',
suffix='.vcd', src_suffix='.out')
simenv = Environment(BUILDERS={'IVerilog': iverilog, 'VCD': vcd},
ENV=os.environ)
out = simenv.IVerilog(TARGET_SIM, src_sim)
vcd_file = simenv.VCD(SIMULNAME, out)
waves = simenv.Alias('sim', vcd_file, 'gtkwave ' +
join(env['PROJECT_DIR'], "{} ".format(vcd_file[0])) +
join(env['PROJECTSRC_DIR'], SIMULNAME) +
'.gtkw')
AlwaysBuild(waves)
Default([binf])
# -- These is for cleaning the files generated using the alias targets
if GetOption('clean'):
env.Default([t])
simenv.Default([out, vcd_file])