mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
mibuild: add initial Lattice Diamond support (with ECP3 Versa board platform skeleton)
This commit is contained in:
parent
beeaefccea
commit
f7bfa13144
4 changed files with 178 additions and 0 deletions
0
mibuild/lattice/__init__.py
Normal file
0
mibuild/lattice/__init__.py
Normal file
93
mibuild/lattice/diamond.py
Normal file
93
mibuild/lattice/diamond.py
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
# This file is Copyright (c) 2015 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||||
|
# License: BSD
|
||||||
|
|
||||||
|
import os, subprocess, shutil
|
||||||
|
|
||||||
|
from migen.fhdl.structure import _Fragment
|
||||||
|
from mibuild.generic_platform import *
|
||||||
|
from mibuild import tools
|
||||||
|
|
||||||
|
def _format_constraint(c):
|
||||||
|
if isinstance(c, Pins):
|
||||||
|
return ("LOCATE COMP ", " SITE " + "\"" + c.identifiers[0] + "\"")
|
||||||
|
elif isinstance(c, IOStandard):
|
||||||
|
return ("IOBUF PORT ", " IO_TYPE=" + c.name)
|
||||||
|
elif isinstance(c, Misc):
|
||||||
|
return c.misc
|
||||||
|
|
||||||
|
def _format_lpf(signame, pin, others, resname):
|
||||||
|
fmt_c = [_format_constraint(c) for c in ([Pins(pin)] + others)]
|
||||||
|
r = ""
|
||||||
|
for pre, suf in fmt_c:
|
||||||
|
r += pre + "\""+ signame +"\"" + suf + ";\n"
|
||||||
|
return r
|
||||||
|
|
||||||
|
def _build_lpf(named_sc, named_pc):
|
||||||
|
r = "BLOCK RESETPATHS;\n"
|
||||||
|
r += "BLOCK ASYNCPATHS;\n"
|
||||||
|
for sig, pins, others, resname in named_sc:
|
||||||
|
if len(pins) > 1:
|
||||||
|
for i, p in enumerate(pins):
|
||||||
|
r += _format_lpf(sig + "[" + str(i) + "]", p, others, resname)
|
||||||
|
else:
|
||||||
|
r += _format_lpf(sig, pins[0], others, resname)
|
||||||
|
if named_pc:
|
||||||
|
r += "\n" + "\n\n".join(named_pc)
|
||||||
|
return r
|
||||||
|
|
||||||
|
def _build_files(device, sources, vincpaths, build_name):
|
||||||
|
tcl = []
|
||||||
|
tcl.append("prj_project new -name \"%s\" -impl \"implementation\" -dev %s -synthesis \"synplify\"" %(build_name, device))
|
||||||
|
for filename, language in sources:
|
||||||
|
tcl.append("prj_src add \"" + filename.replace("\\", "/") + "\"")
|
||||||
|
tcl.append("prj_run Synthesis -impl implementation -forceOne")
|
||||||
|
tcl.append("prj_run Translate -impl implementation")
|
||||||
|
tcl.append("prj_run Map -impl implementation")
|
||||||
|
tcl.append("prj_run PAR -impl implementation")
|
||||||
|
tcl.append("prj_run Export -impl implementation -task Bitgen")
|
||||||
|
tools.write_to_file(build_name + ".tcl", "\n".join(tcl))
|
||||||
|
|
||||||
|
def _run_diamond(build_name, source, ver=None):
|
||||||
|
if sys.platform == "win32" or sys.platform == "cygwin":
|
||||||
|
build_script_contents = "REM Autogenerated by mibuild\n"
|
||||||
|
build_script_contents = "pnmainc " + build_name + ".tcl\n"
|
||||||
|
build_script_file = "build_" + build_name + ".bat"
|
||||||
|
tools.write_to_file(build_script_file, build_script_contents)
|
||||||
|
r = subprocess.call([build_script_file])
|
||||||
|
shutil.copy(os.path.join("implementation", build_name + "_implementation.bit"), build_name + ".bit")
|
||||||
|
else:
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
if r != 0:
|
||||||
|
raise OSError("Subprocess failed")
|
||||||
|
|
||||||
|
class LatticeDiamondPlatform(GenericPlatform):
|
||||||
|
bitstream_ext = ".bit"
|
||||||
|
def build(self, fragment, build_dir="build", build_name="top",
|
||||||
|
diamond_path="/opt/Diamond", run=True):
|
||||||
|
tools.mkdir_noerror(build_dir)
|
||||||
|
os.chdir(build_dir)
|
||||||
|
|
||||||
|
if not isinstance(fragment, _Fragment):
|
||||||
|
fragment = fragment.get_fragment()
|
||||||
|
self.finalize(fragment)
|
||||||
|
|
||||||
|
v_src, vns = self.get_verilog(fragment)
|
||||||
|
named_sc, named_pc = self.resolve_signals(vns)
|
||||||
|
v_file = build_name + ".v"
|
||||||
|
tools.write_to_file(v_file, v_src)
|
||||||
|
sources = self.sources + [(v_file, "verilog")]
|
||||||
|
_build_files(self.device, sources, self.verilog_include_paths, build_name)
|
||||||
|
|
||||||
|
tools.write_to_file(build_name + ".lpf", _build_lpf(named_sc, named_pc))
|
||||||
|
|
||||||
|
if run:
|
||||||
|
_run_diamond(build_name, diamond_path)
|
||||||
|
|
||||||
|
os.chdir("..")
|
||||||
|
|
||||||
|
return vns
|
||||||
|
|
||||||
|
def add_period_constraint(self, clk, period):
|
||||||
|
# TODO: handle differential clk
|
||||||
|
self.add_platform_command("""FREQUENCY PORT "{clk}" {freq} MHz;""".format(freq=str(float(1/period)*1000), clk="{clk}"), clk=clk)
|
51
mibuild/lattice/programmer.py
Normal file
51
mibuild/lattice/programmer.py
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
import os, subprocess
|
||||||
|
|
||||||
|
from mibuild.generic_programmer import GenericProgrammer
|
||||||
|
from mibuild import tools
|
||||||
|
|
||||||
|
# XXX Lattice programmer need an .xcf file, will need clean up and support for more parameters
|
||||||
|
_xcf_template = """
|
||||||
|
<?xml version='1.0' encoding='utf-8' ?>
|
||||||
|
<!DOCTYPE ispXCF SYSTEM "IspXCF.dtd" >
|
||||||
|
<ispXCF version="3.4.1">
|
||||||
|
<Comment></Comment>
|
||||||
|
<Chain>
|
||||||
|
<Comm>JTAG</Comm>
|
||||||
|
<Device>
|
||||||
|
<SelectedProg value="TRUE"/>
|
||||||
|
<Pos>1</Pos>
|
||||||
|
<Vendor>Lattice</Vendor>
|
||||||
|
<Family>LatticeECP3</Family>
|
||||||
|
<Name>LFE3-35EA</Name>
|
||||||
|
<File>{bitstream_file}</File>
|
||||||
|
<Operation>Fast Program</Operation>
|
||||||
|
</Device>
|
||||||
|
</Chain>
|
||||||
|
<ProjectOptions>
|
||||||
|
<Program>SEQUENTIAL</Program>
|
||||||
|
<Process>ENTIRED CHAIN</Process>
|
||||||
|
<OperationOverride>No Override</OperationOverride>
|
||||||
|
<StartTAP>TLR</StartTAP>
|
||||||
|
<EndTAP>TLR</EndTAP>
|
||||||
|
<VerifyUsercode value="FALSE"/>
|
||||||
|
</ProjectOptions>
|
||||||
|
<CableOptions>
|
||||||
|
<CableName>USB2</CableName>
|
||||||
|
<PortAdd>FTUSB-0</PortAdd>
|
||||||
|
<USBID>Dual RS232-HS A Location 0000 Serial A</USBID>
|
||||||
|
<JTAGPinSetting>
|
||||||
|
TRST ABSENT;
|
||||||
|
ISPEN ABSENT;
|
||||||
|
</JTAGPinSetting>
|
||||||
|
</CableOptions>
|
||||||
|
</ispXCF>
|
||||||
|
"""
|
||||||
|
|
||||||
|
class LatticeProgrammer(GenericProgrammer):
|
||||||
|
needs_bitreverse = False
|
||||||
|
|
||||||
|
def load_bitstream(self, bitstream_file):
|
||||||
|
xcf_file = bitstream_file.replace(".bit", ".xcf")
|
||||||
|
xcf_content = _xcf_template.format(bitstream_file=bitstream_file)
|
||||||
|
tools.write_to_file(xcf_file, xcf_content)
|
||||||
|
subprocess.call(["pgrcmd", "-infile", xcf_file])
|
34
mibuild/platforms/versa.py
Normal file
34
mibuild/platforms/versa.py
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
# This file is Copyright (c) 2013 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||||
|
# License: BSD
|
||||||
|
|
||||||
|
from mibuild.generic_platform import *
|
||||||
|
from mibuild.lattice.diamond import LatticeDiamondPlatform
|
||||||
|
from mibuild.lattice.programmer import LatticeProgrammer
|
||||||
|
|
||||||
|
_io = [
|
||||||
|
("clk100", 0, Pins("L5"), IOStandard("LVDS25")),
|
||||||
|
|
||||||
|
("user_led", 0, Pins("Y20"), IOStandard("LVCMOS33")),
|
||||||
|
("user_led", 1, Pins("AA21"), IOStandard("LVCMOS33")),
|
||||||
|
("user_led", 2, Pins("U18"), IOStandard("LVCMOS33")),
|
||||||
|
("user_led", 3, Pins("U19"), IOStandard("LVCMOS33")),
|
||||||
|
("user_led", 4, Pins("W19"), IOStandard("LVCMOS33")),
|
||||||
|
("user_led", 5, Pins("V19"), IOStandard("LVCMOS33")),
|
||||||
|
("user_led", 6, Pins("AB20"), IOStandard("LVCMOS33")),
|
||||||
|
("user_led", 7, Pins("AA20"), IOStandard("LVCMOS33")),
|
||||||
|
|
||||||
|
("serial", 0,
|
||||||
|
Subsignal("tx", Pins("B11"), IOStandard("LVCMOS33")), # X4 IO0
|
||||||
|
Subsignal("rx", Pins("B12"), IOStandard("LVCMOS33")), # X4 IO1
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
class Platform(LatticeDiamondPlatform):
|
||||||
|
default_clk_name = "clk100"
|
||||||
|
default_clk_period = 10
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
LatticeDiamondPlatform.__init__(self, "LFE3-35EA-6FN484C", _io)
|
||||||
|
|
||||||
|
def create_programmer(self):
|
||||||
|
return LatticeProgrammer()
|
Loading…
Reference in a new issue