1 # This file is Copyright (c) 2014-2015 Sebastien Bourdeauducq <sb@m-labs.hk>
2 # This file is Copyright (c) 2014-2019 Florent Kermarrec <florent@enjoy-digital.fr>
3 # This file is Copyright (c) 2015 Robert Jordens <jordens@gmail.com>
11 from litex
.build
.generic_programmer
import GenericProgrammer
12 from litex
.build
.xilinx
import common
14 # UrJTAG -------------------------------------------------------------------------------------------
16 def _run_urjtag(cmds
):
17 with subprocess
.Popen("jtag", stdin
=subprocess
.PIPE
) as process
:
18 process
.stdin
.write(cmds
.encode("ASCII"))
22 class UrJTAG(GenericProgrammer
):
23 needs_bitreverse
= True
25 def __init__(self
, cable
, flash_proxy_basename
=None):
26 GenericProgrammer
.__init
__(self
, flash_proxy_basename
)
29 def load_bitstream(self
, bitstream_file
):
30 cmds
= """cable {cable}
34 """.format(bitstream
=bitstream_file
, cable
=self
.cable
)
37 def flash(self
, address
, data_file
):
38 flash_proxy
= self
.find_flash_proxy()
39 cmds
= """cable {cable}
41 pld load "{flash_proxy}"
42 initbus fjmem opcode=000010
46 flashmem "{address}" "{data_file}" noverify
47 """.format(flash_proxy
=flash_proxy
, address
=address
, data_file
=data_file
,
51 # XC3SProg -----------------------------------------------------------------------------------------
53 class XC3SProg(GenericProgrammer
):
54 needs_bitreverse
= False
56 def __init__(self
, cable
, flash_proxy_basename
=None, position
=0):
57 GenericProgrammer
.__init
__(self
, flash_proxy_basename
)
59 self
.position
= position
61 def load_bitstream(self
, bitstream_file
):
62 subprocess
.call(["xc3sprog", "-v", "-c", self
.cable
, "-p", str(self
.position
), bitstream_file
])
64 def flash(self
, address
, data_file
):
65 flash_proxy
= self
.find_flash_proxy()
66 subprocess
.call(["xc3sprog", "-v", "-c", self
.cable
, "-p", str(self
.position
),
67 "-I"+flash_proxy
, "{}:w:0x{:x}:BIN".format(data_file
, address
)])
69 # FpgaProg -----------------------------------------------------------------------------------------
71 class FpgaProg(GenericProgrammer
):
72 needs_bitreverse
= False
74 def __init__(self
, flash_proxy_basename
=None):
75 GenericProgrammer
.__init
__(self
, flash_proxy_basename
)
77 def load_bitstream(self
, bitstream_file
):
78 subprocess
.call(["fpgaprog", "-v", "-f", bitstream_file
])
80 def flash(self
, address
, data_file
):
82 raise ValueError("fpga prog needs a main bitstream at address 0")
83 flash_proxy
= self
.find_flash_proxy()
84 subprocess
.call(["fpgaprog", "-v", "-sa", "-r", "-b", flash_proxy
,
87 # iMPACT -------------------------------------------------------------------------------------------
89 def _run_impact(cmds
):
90 with subprocess
.Popen("impact -batch", stdin
=subprocess
.PIPE
, shell
=True) as process
:
91 process
.stdin
.write(cmds
.encode("ASCII"))
93 return process
.returncode
96 def _create_xsvf(bitstream_file
, xsvf_file
):
97 assert os
.path
.exists(bitstream_file
), bitstream_file
98 assert not os
.path
.exists(xsvf_file
), xsvf_file
99 assert 0 == _run_impact("""
100 setPreference -pref KeepSVF:True
102 setCable -port xsvf -file {xsvf}
103 addDevice -p 1 -file {bitstream}
106 """.format(bitstream
=bitstream_file
, xsvf
=xsvf_file
))
109 class iMPACT(GenericProgrammer
):
110 needs_bitreverse
= False
112 def load_bitstream(self
, bitstream_file
):
113 cmds
= """setMode -bs
115 addDevice -p 1 -file {bitstream}
118 """.format(bitstream
=bitstream_file
)
121 # Vivado -------------------------------------------------------------------------------------------
123 def _run_vivado(path
, ver
, cmds
):
124 vivado_cmd
= "vivado -mode tcl"
125 with subprocess
.Popen(vivado_cmd
, stdin
=subprocess
.PIPE
, shell
=True) as process
:
126 process
.stdin
.write(cmds
.encode("ASCII"))
127 process
.communicate()
130 class VivadoProgrammer(GenericProgrammer
):
131 needs_bitreverse
= False
132 def __init__(self
, vivado_path
="/opt/Xilinx/Vivado", vivado_ver
=None,
133 flash_part
="n25q256-3.3v-spi-x1_x2_x4"):
134 GenericProgrammer
.__init
__(self
)
135 self
.vivado_path
= vivado_path
136 self
.vivado_ver
= vivado_ver
137 self
.flash_part
= flash_part
139 def load_bitstream(self
, bitstream_file
, target
="", device
=0):
142 open_hw_target {target}
144 set_property PROBES.FILE {{}} [lindex [get_hw_devices] {{{device}}}]
145 set_property PROGRAM.FILE {{{bitstream}}} [lindex [get_hw_devices] {{{device}}}]
147 program_hw_devices [lindex [get_hw_devices] {{{device}}}]
148 refresh_hw_device [lindex [get_hw_devices] {{{device}}}]
151 """.format(target
=target
, bitstream
=bitstream_file
, device
=device
)
152 _run_vivado(self
.vivado_path
, self
.vivado_ver
, cmds
)
154 # XXX works to flash bitstream, adapt it to flash bios
155 def flash(self
, address
, data_file
, device
=0):
159 create_hw_cfgmem -hw_device [lindex [get_hw_devices] {{{device}}}] -mem_dev [lindex [get_cfgmem_parts {{{flash_part}}}] 0]
161 set_property PROGRAM.BLANK_CHECK 0 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] {{{device}}} ]]
162 set_property PROGRAM.ERASE 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] {{{device}}} ]]
163 set_property PROGRAM.CFG_PROGRAM 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] {{{device}}} ]]
164 set_property PROGRAM.VERIFY 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] {{{device}}} ]]
165 refresh_hw_device [lindex [get_hw_devices] {{{device}}}]
167 set_property PROGRAM.ADDRESS_RANGE {{use_file}} [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] {{{device}}} ]]
168 set_property PROGRAM.FILES [list "{data}" ] [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] {{{device}}}]]
169 set_property PROGRAM.UNUSED_PIN_TERMINATION {{pull-none}} [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] {{{device}}} ]]
170 set_property PROGRAM.BLANK_CHECK 0 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] {{{device}}} ]]
171 set_property PROGRAM.ERASE 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] {{{device}}} ]]
172 set_property PROGRAM.CFG_PROGRAM 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] {{{device}}} ]]
173 set_property PROGRAM.VERIFY 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] {{{device}}} ]]
176 if {{![string equal [get_property PROGRAM.HW_CFGMEM_TYPE [lindex [get_hw_devices] {{{device}}}]] [get_property MEM_TYPE [get_property CFGMEM_PART [get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] {{{device}}} ]]]]] }} {{ create_hw_bitstream -hw_device [lindex [get_hw_devices] {{{device}}}] [get_property PROGRAM.HW_CFGMEM_BITFILE [ lindex [get_hw_devices] {{{device}}}]]; program_hw_devices [lindex [get_hw_devices] {{{device}}}]; }};
177 program_hw_cfgmem -hw_cfgmem [get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] {{{device}}} ]]
181 """.format(data
=data_file
, flash_part
=self
.flash_part
, device
=device
)
182 _run_vivado(self
.vivado_path
, self
.vivado_ver
, cmds
)
184 # Adept --------------------------------------------------------------------------------------------
186 class Adept(GenericProgrammer
):
187 """Using the Adept tool with an onboard Digilent "USB JTAG" cable.
189 You need to install Adept Utilities V2 from
190 http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,66,828&Prod=ADEPT2
193 needs_bitreverse
= False
195 def __init__(self
, board
, index
, flash_proxy_basename
=None):
196 GenericProgrammer
.__init
__(self
, flash_proxy_basename
)
200 def load_bitstream(self
, bitstream_file
):
204 "prog", "-d", self
.board
,
205 "-i", str(self
.index
),
206 "-f", bitstream_file
,
209 def flash(self
, address
, data_file
):
210 raise ValueError("Flashing unsupported with DigilentAdept tools")