Merge branch 'master' of https://github.com/m-labs/migen
This commit is contained in:
commit
73ea404380
|
@ -26,7 +26,7 @@ install:
|
|||
- "verilator --version; true"
|
||||
# Build and install Migen conda package
|
||||
- "conda build conda/migen"
|
||||
- "conda install $HOME/miniconda/conda-bld/linux-64/migen-*.tar.bz2"
|
||||
- "conda install migen --use-local"
|
||||
|
||||
script:
|
||||
# Run tests
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
|
||||
import os
|
||||
|
||||
from mibuild.generic_programmer import GenericProgrammer
|
||||
from mibuild.xilinx.programmer import _create_xsvf
|
||||
|
||||
import fpgalink3
|
||||
fpgalink3.flInitialise(0)
|
||||
|
||||
|
||||
class FPGALink(GenericProgrammer):
|
||||
"""Using the fpgalink library from makestuff
|
||||
|
||||
You will need fpgalink library installed from
|
||||
https://github.com/makestuff/libfpgalink
|
||||
"""
|
||||
|
||||
needs_bitreverse = False
|
||||
|
||||
def __init__(self, initial_vidpid=None, pin_cfg="D0D2D3D4",
|
||||
fpgalink_vidpid="1D50:602B:0002", flash_proxy_basename=None):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
initial_vidpid : string
|
||||
The USB vendor and product id of the device before fpgalink
|
||||
firmware is loaded onto the device.
|
||||
|
||||
Format is vid:pid as 4 digit hex numbers.
|
||||
|
||||
pin_cfg : string
|
||||
FPGALink pin configuration string describing how the JTAG interface
|
||||
is hooked up to the programmer.
|
||||
|
||||
fpgalink_vidpid : string
|
||||
The USB vendor, product and device id of the device after the
|
||||
fpgalink firmware is loaded onto the device.
|
||||
|
||||
Format is vid:pid:did as 4 digit hex numbers.
|
||||
Defaults to 1D50:602B:0002 which is the makestuff FPGALink device.
|
||||
"""
|
||||
GenericProgrammer.__init__(self, flash_proxy_basename)
|
||||
self.initial_vidpid = initial_vidpid
|
||||
self.fpgalink_vidpid = fpgalink_vidpid
|
||||
self.pin_cfg = pin_cfg
|
||||
|
||||
def open_device(self):
|
||||
ivp = self.initial_vidpid
|
||||
vp = self.fpgalink_vidpid
|
||||
|
||||
print("Attempting to open connection to FPGALink device", vp, "...")
|
||||
try:
|
||||
handle = fpgalink3.flOpen(self.fpgalink_vidpid)
|
||||
except fpgalink3.FLException as ex:
|
||||
if not ivp:
|
||||
raise FLException(
|
||||
"Could not open FPGALink device at {0} and"
|
||||
" no initial VID:PID was supplied".format(vp))
|
||||
|
||||
print("Loading firmware into %s..." % ivp)
|
||||
fpgalink3.flLoadStandardFirmware(ivp, vp)
|
||||
|
||||
print("Awaiting renumeration...")
|
||||
if not fpgalink3.flAwaitDevice(vp, 600):
|
||||
raise fpgalink3.FLException(
|
||||
"FPGALink device did not renumerate properly"
|
||||
" as {0}".format(vp))
|
||||
|
||||
print("Attempting to open connection to FPGALink device", vp,
|
||||
"again...")
|
||||
handle = fpgalink3.flOpen(vp)
|
||||
|
||||
# Only Nero capable hardware support doing programming.
|
||||
assert fpgalink3.flIsNeroCapable(handle)
|
||||
return handle
|
||||
|
||||
def load_bitstream(self, bitstream_file):
|
||||
n = 27
|
||||
|
||||
xsvf_file = os.path.splitext(bitstream_file)[0]+'.xsvf'
|
||||
print("\nGenerating xsvf formatted bitstream")
|
||||
print("="*n)
|
||||
if os.path.exists(xsvf_file):
|
||||
os.unlink(xsvf_file)
|
||||
_create_xsvf(bitstream_file, xsvf_file)
|
||||
print("\n"+"="*n+"\n")
|
||||
|
||||
print("Programming %s to device." % xsvf_file)
|
||||
print("="*n)
|
||||
handle = self.open_device()
|
||||
fpgalink3.flProgram(handle, 'J:'+self.pin_cfg, progFile=xsvf_file)
|
||||
print("Programming successful!")
|
||||
print("="*n+"\n")
|
||||
fpgalink3.flClose(handle)
|
||||
|
||||
def flash(self, address, data_file):
|
||||
raise NotImplementedError("Not supported yet.")
|
|
@ -1,2 +1,2 @@
|
|||
from mibuild.xilinx.platform import XilinxPlatform
|
||||
from mibuild.xilinx.programmer import UrJTAG, XC3SProg, FpgaProg, VivadoProgrammer, iMPACT
|
||||
from mibuild.xilinx.programmer import UrJTAG, XC3SProg, FpgaProg, VivadoProgrammer, iMPACT, Adept
|
||||
|
|
|
@ -104,10 +104,10 @@ class XilinxDifferentialOutput:
|
|||
|
||||
class XilinxDDROutputImpl(Module):
|
||||
def __init__(self, i1, i2, o, clk):
|
||||
self.specials += Instance("ODDR",
|
||||
p_DDR_CLK_EDGE="SAME_EDGE",
|
||||
i_C=clk, i_CE=1, i_S=0, i_R=0,
|
||||
i_D1=i1, i_D2=i2, o_Q=o,
|
||||
self.specials += Instance("ODDR2",
|
||||
p_DDR_ALIGNMENT="NONE", p_INIT=0, p_SRTYPE="SYNC",
|
||||
i_C0=clk, i_C1=~clk, i_CE=1, i_S=0, i_R=0,
|
||||
i_D0=i1, i_D1=i2, o_Q=o,
|
||||
)
|
||||
|
||||
|
||||
|
@ -116,11 +116,32 @@ class XilinxDDROutput:
|
|||
def lower(dr):
|
||||
return XilinxDDROutputImpl(dr.i1, dr.i2, dr.o, dr.clk)
|
||||
|
||||
|
||||
xilinx_special_overrides = {
|
||||
NoRetiming: XilinxNoRetiming,
|
||||
MultiReg: XilinxMultiReg,
|
||||
AsyncResetSynchronizer: XilinxAsyncResetSynchronizer,
|
||||
DifferentialInput: XilinxDifferentialInput,
|
||||
DifferentialOutput: XilinxDifferentialOutput,
|
||||
DDROutput: XilinxDDROutput
|
||||
NoRetiming: XilinxNoRetiming,
|
||||
MultiReg: XilinxMultiReg,
|
||||
AsyncResetSynchronizer: XilinxAsyncResetSynchronizer,
|
||||
DifferentialInput: XilinxDifferentialInput,
|
||||
DifferentialOutput: XilinxDifferentialOutput,
|
||||
DDROutput: XilinxDDROutput
|
||||
}
|
||||
|
||||
|
||||
class XilinxDDROutputImplS7(Module):
|
||||
def __init__(self, i1, i2, o, clk):
|
||||
self.specials += Instance("ODDR",
|
||||
p_DDR_CLK_EDGE="SAME_EDGE",
|
||||
i_C=clk, i_CE=1, i_S=0, i_R=0,
|
||||
i_D1=i1, i_D2=i2, o_Q=o,
|
||||
)
|
||||
|
||||
|
||||
class XilinxDDROutputS7:
|
||||
@staticmethod
|
||||
def lower(dr):
|
||||
return XilinxDDROutputImplS7(dr.i1, dr.i2, dr.o, dr.clk)
|
||||
|
||||
|
||||
xilinx_s7_special_overrides = {
|
||||
DDROutput: XilinxDDROutputS7
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@ class XilinxPlatform(GenericPlatform):
|
|||
|
||||
def get_verilog(self, *args, special_overrides=dict(), **kwargs):
|
||||
so = dict(common.xilinx_special_overrides)
|
||||
if self.device[:3] == "xc7":
|
||||
so.update(dict(common.xilinx_s7_special_overrides))
|
||||
so.update(special_overrides)
|
||||
return GenericPlatform.get_verilog(self, *args, special_overrides=so, **kwargs)
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
|
@ -75,9 +76,23 @@ class FpgaProg(GenericProgrammer):
|
|||
|
||||
|
||||
def _run_impact(cmds):
|
||||
with subprocess.Popen("impact -batch", stdin=subprocess.PIPE) as process:
|
||||
with subprocess.Popen("impact -batch", stdin=subprocess.PIPE, shell=True) as process:
|
||||
process.stdin.write(cmds.encode("ASCII"))
|
||||
process.communicate()
|
||||
return process.returncode
|
||||
|
||||
|
||||
def _create_xsvf(bitstream_file, xsvf_file):
|
||||
assert os.path.exists(bitstream_file), bitstream_file
|
||||
assert not os.path.exists(xsvf_file), xsvf_file
|
||||
assert 0 == _run_impact("""
|
||||
setPreference -pref KeepSVF:True
|
||||
setMode -bs
|
||||
setCable -port xsvf -file {xsvf}
|
||||
addDevice -p 1 -file {bitstream}
|
||||
program -p 1
|
||||
quit
|
||||
""".format(bitstream=bitstream_file, xsvf=xsvf_file))
|
||||
|
||||
|
||||
class iMPACT(GenericProgrammer):
|
||||
|
@ -155,3 +170,30 @@ endgroup
|
|||
quit
|
||||
""".format(data=data_file)
|
||||
_run_vivado(self.vivado_path, self.vivado_ver, cmds)
|
||||
|
||||
|
||||
class Adept(GenericProgrammer):
|
||||
"""Using the Adept tool with an onboard Digilent "USB JTAG" cable.
|
||||
|
||||
You need to install Adept Utilities V2 from
|
||||
http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,66,828&Prod=ADEPT2
|
||||
"""
|
||||
|
||||
needs_bitreverse = False
|
||||
|
||||
def __init__(self, board, index, flash_proxy_basename=None):
|
||||
GenericProgrammer.__init__(self, flash_proxy_basename)
|
||||
self.board = board
|
||||
self.index = index
|
||||
|
||||
def load_bitstream(self, bitstream_file):
|
||||
subprocess.call([
|
||||
"djtgcfg",
|
||||
"--verbose",
|
||||
"prog", "-d", self.board,
|
||||
"-i", str(self.index),
|
||||
"-f", bitstream_file,
|
||||
])
|
||||
|
||||
def flash(self, address, data_file):
|
||||
raise ValueError("Flashing unsupported with DigilentAdept tools")
|
||||
|
|
Loading…
Reference in New Issue