Module: Xilinx::Provision::Impact
- Defined in:
- lib/xilinx/provision/impact.rb
Overview
Runs the impact tool.
Class Method Summary collapse
-
.download_url ⇒ Object
The URL printed when no ISE installation is found.
-
.identify_chain(options = {}) ⇒ Object
Scans the JTAG chain and returns the devices on it.
-
.parse_identify(output) ⇒ Object
Extracts a JTAG chain from an impact identify command.
-
.path ⇒ Object
Path to the impact binary.
-
.path! ⇒ Object
Path to the impact binary.
-
.program_fpga(bitfile, options = {}) ⇒ Object
Programs an FPGA chip on a JTAG chain.
-
.run(options = {}) ⇒ Object
Runs the impact tool and returns the status.
Class Method Details
.download_url ⇒ Object
The URL printed when no ISE installation is found.
150 151 152 |
# File 'lib/xilinx/provision/impact.rb', line 150 def self.download_url 'http://www.xilinx.com/support/download/index.htm' end |
.identify_chain(options = {}) ⇒ Object
Scans the JTAG chain and returns the devices on it.
The options argument accepts the following keys:
:cable_port:: set to :auto by default
Returns the command’s output.
42 43 44 45 46 |
# File 'lib/xilinx/provision/impact.rb', line 42 def self.identify_chain( = {}) batch = ['identify', 'cleanCableLock', 'closeCable'] = {:mode => :bscan, :cable_port => :auto, :batch => batch} parse_identify run() end |
.parse_identify(output) ⇒ Object
Extracts a JTAG chain from an impact identify command.
Args:
output:: the impact command output, obtained from Impact#run
Returns an array of hashes with the following keys:
name:: the device name, e.g. "Xilinx xc5vlx110t"
version:: number reported by impact
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/xilinx/provision/impact.rb', line 56 def self.parse_identify(output) lines = output.split("\n").each(&:strip!) lines.each_with_index do |line, index| if /ident.*chain/i =~ line lines = lines[index..-1] break end end device_id_regexp = /'(\d+)':.*manufacturer.* id.*=([^,]+),.*version.*(\d+)/i devices = [] device = {} lines.each do |line| if match = device_id_regexp.match(line) device[:index] = match[1].to_i device[:name] = match[2].strip device[:version] = match[3].to_i end if /^\-+$/ =~ line && !device.empty? devices << device device = {} end end devices end |
.path ⇒ Object
Path to the impact binary.
125 126 127 |
# File 'lib/xilinx/provision/impact.rb', line 125 def self.path @path ||= path! end |
.path! ⇒ Object
Path to the impact binary.
This method does not cache its result and is really slow.
135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/xilinx/provision/impact.rb', line 135 def self.path! paths = Dir['/opt/**/impact'] paths = Dir['/usr/**/impact'] if paths.empty? # 1 is a Fixnum which is a pointer, so its size shows 32/64-bit if 1.size == 8 paths = paths.select { |path| path.index '64' } else paths = paths.reject { |path| path.index '64' } end paths.sort.last end |
.program_fpga(bitfile, options = {}) ⇒ Object
Programs an FPGA chip on a JTAG chain.
The options argument accepts the following keys:
:cable_port:: set to :auto by default
Returns a false value for success, or a string containing error output if something goes wrong.
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/xilinx/provision/impact.rb', line 18 def self.program_fpga(bitfile, = {}) = { :mode => :bscan }.merge [:cable_port] ||= :auto devices = identify_chain() bitfile = File. bitfile batch = [ 'identify', "assignFile -position #{devices.length} -file #{bitfile}", "program -position #{devices.length}", 'cleanCableLock', 'closeCable' ] .merge! :batch => batch output = run $CHILD_STATUS.to_i == 0 ? nil : output end |
.run(options = {}) ⇒ Object
Runs the impact tool and returns the status.
The options argument accepts the following keys:
:batch:: array of commands to be written to a batch file and executed
:mode:: device configuration mode (try :bscan for JTAG boundary scan)
:cable_port:: (try :auto)
Returns the command’s output.
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/xilinx/provision/impact.rb', line 90 def self.run( = {}) unless command_line = "LD_PRELOAD=#{Xilinx::Provision::CableDriver.path} " + path raise "Xilinx ISE not found\nPlease download from #{download_url}" end batch = [:batch] && [:batch].dup if [:cable_port] command_line << " -port #{[:cable_port]}" batch.unshift "setCable -port #{[:cable_port]}" if batch end if [:mode] command_line << " -mode #{[:mode]}" batch.unshift "setMode -#{[:mode]}" if batch end batch.push 'quit' if batch && batch.last != 'quit' output = nil Dir.mktmpdir do |temp_dir| Dir.chdir temp_dir do if [:batch] File.open('impact_batch', 'wb') do |f| f.write batch.map { |line| line + "\n" }.join end command_line << ' -batch impact_batch' end command_line << ' 2>&1' output = Kernel.`(command_line) end end output end |