ruby-adept 0.0.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +5 -5
- data/Rakefile +16 -7
- data/bin/bprog +175 -12
- data/cores/avr8/avr_250k.bit +0 -0
- data/cores/avr8/avr_250k.bmm +56 -0
- data/cores/avr8/core.yaml +11 -0
- data/firmware/epp_stream/epp_stream.xise +5 -5
- data/lib/adept.rb +1 -0
- data/lib/adept/core.rb +148 -0
- data/lib/adept/error.rb +2 -0
- data/lib/adept/jtag/device.rb +2 -0
- data/lib/adept/version.rb +1 -1
- data/{adept.gemspec → ruby-adept.gemspec} +8 -8
- data/spec/lib/adept/core_spec.rb +58 -0
- metadata +57 -35
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -1,16 +1,25 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
|
3
|
-
task :default =>
|
3
|
+
task :default => :test_all
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
sh "rspec -Ilib --tag=~online"
|
5
|
+
task :test_all do
|
6
|
+
sh "rspec -Ilib"
|
8
7
|
end
|
9
8
|
|
10
|
-
|
11
|
-
|
9
|
+
desc 'Builds the ruby-adept gem.'
|
10
|
+
task :build do
|
11
|
+
sh "gem build ruby-adept.gemspec"
|
12
12
|
end
|
13
13
|
|
14
|
-
|
14
|
+
desc 'Builds and installs the ruby-adept gem.'
|
15
|
+
task :install => :build do
|
16
|
+
sh "gem install pkg/ruby-adept-#{Adept::VERSION}.gem"
|
17
|
+
end
|
15
18
|
|
19
|
+
desc 'Tags the current version, pushes it GitHub, and pushes the gem.'
|
20
|
+
task :release => :build do
|
21
|
+
sh "git tag v#{Adept::VERSION}"
|
22
|
+
sh "git push origin master"
|
23
|
+
sh "git push origin v#{Adept::VERSION}"
|
24
|
+
sh "git push pkg.ruby-adept-#{Adept::VERSION}.gem"
|
16
25
|
end
|
data/bin/bprog
CHANGED
@@ -37,10 +37,14 @@ end
|
|
37
37
|
#
|
38
38
|
# Get the currently connected device.
|
39
39
|
#
|
40
|
-
def get_target_connection(
|
40
|
+
def get_target_connection(fail_silently = false)
|
41
41
|
|
42
42
|
#Ensure that we have a plugged-in board.
|
43
|
-
|
43
|
+
if Device::connected_devices.empty?
|
44
|
+
fatal_error "It doesn't look like there's a Digilent board plugged in, on or off." unless fail_silently
|
45
|
+
exit
|
46
|
+
end
|
47
|
+
|
44
48
|
|
45
49
|
#By default, use the first connected device.
|
46
50
|
device = Device::open_first_connected_device
|
@@ -50,7 +54,12 @@ def get_target_connection(opts={})
|
|
50
54
|
fatal_error "This device isn't supported." unless device.supported_connections.include?(JTAG::Connection)
|
51
55
|
|
52
56
|
jtag = JTAG::Connection.new(device)
|
53
|
-
|
57
|
+
|
58
|
+
#Ensure that we found a supporte FPGA.
|
59
|
+
if jtag.connected_devices.empty?
|
60
|
+
fatal_error "The power switch is off on your connected board! Turn it on, and try again." unless fail_silently
|
61
|
+
exit
|
62
|
+
end
|
54
63
|
|
55
64
|
jtag
|
56
65
|
|
@@ -59,16 +68,21 @@ end
|
|
59
68
|
#
|
60
69
|
# Get the target file.
|
61
70
|
#
|
62
|
-
def get_target_file(
|
71
|
+
def get_target_file(do_not_guess=false, allow_none = false)
|
63
72
|
|
64
73
|
#If a file was provided on the command line, use it.
|
65
74
|
file = ARGV.shift if ARGV
|
66
75
|
|
67
76
|
#Attempt to determine the target file automagically.
|
68
|
-
unless file
|
77
|
+
unless file or do_not_guess
|
69
78
|
|
70
79
|
#Attempt to determine the file.
|
71
|
-
|
80
|
+
begin
|
81
|
+
file = ISE::ProjectNavigator::most_recent_project.bit_file
|
82
|
+
rescue
|
83
|
+
file = nil
|
84
|
+
end
|
85
|
+
|
72
86
|
fatal_error "You didn't specify a file to program, and I couldn't figure out a likely candidate.\n Perhaps you still need to generate a programming file?" unless file
|
73
87
|
|
74
88
|
#And warn the user of the file we chose.
|
@@ -77,27 +91,176 @@ def get_target_file(opts={})
|
|
77
91
|
|
78
92
|
end
|
79
93
|
|
80
|
-
|
94
|
+
#If the provided file does not exist...
|
95
|
+
unless file && File::exists?(file)
|
96
|
+
|
97
|
+
#... and this is allowed, return nil.
|
98
|
+
if allow_none
|
99
|
+
return nil
|
100
|
+
|
101
|
+
#Otherwise, throw a fatal error.
|
102
|
+
end
|
103
|
+
fatal_error "The file you asked me to program doesn't seem to exist."
|
104
|
+
else
|
105
|
+
|
106
|
+
end
|
107
|
+
|
81
108
|
|
82
109
|
#Return the ascertained file.
|
83
110
|
file
|
84
111
|
|
85
112
|
end
|
86
113
|
|
87
|
-
|
114
|
+
#
|
115
|
+
# Returns the part name of the first connected FPGA,
|
116
|
+
# or nil if no FPGAs are connected.
|
117
|
+
#
|
118
|
+
def connected_fpga_part_name(jtag)
|
119
|
+
|
120
|
+
#Find the first connected FPGA.
|
121
|
+
fpga = jtag.connected_devices.find { |device| device.is_a? JTAG::Devices::FPGA }
|
122
|
+
|
123
|
+
#If we found an FPGA, return its part name. Otherwise, return nil.
|
124
|
+
return fpga ? fpga.part_name : nil
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
#
|
129
|
+
# Configures the first connected FPGA with the provided bitstream.
|
130
|
+
#
|
131
|
+
def configure_fpga(jtag, bitstream)
|
88
132
|
|
89
133
|
#Find the first connected FPGA.
|
90
134
|
fpga = jtag.connected_devices.find { |device| device.is_a? JTAG::Devices::FPGA }
|
91
135
|
fatal_error "This board doesn't feature a supported FPGA!" unless fpga
|
92
136
|
|
93
|
-
#
|
94
|
-
|
137
|
+
#If we've been provided with a string, assume it is a filename,
|
138
|
+
#and open the relevant bitfile.
|
139
|
+
if bitstream.is_a?(String)
|
140
|
+
bitstream = Adept::DataFormats::Bitstream.from_file(bitfile_path)
|
141
|
+
end
|
142
|
+
|
143
|
+
#Use the bitfile to program the device.
|
95
144
|
fpga.configure(bitstream)
|
96
145
|
|
97
146
|
end
|
98
147
|
|
99
|
-
|
100
|
-
|
148
|
+
#
|
149
|
+
# Displays a list of available cores.
|
150
|
+
#
|
151
|
+
def list_available_cores(compatible_with=nil, display_help=true)
|
152
|
+
|
153
|
+
#Print a short header...
|
154
|
+
puts((compatible_with ? ' Connected board supports the following' : ' Available ').bold + " cores:\n\n".bold)
|
155
|
+
|
156
|
+
#... and a list of available cores.
|
157
|
+
cores = Core.available_cores(compatible_with)
|
158
|
+
cores.each { |core| puts " #{core.shortname}:\t#{core.name}\t(#{core.targets.keys.join(", ")})" }
|
159
|
+
|
160
|
+
puts " No cores supported." if cores.empty?
|
161
|
+
|
162
|
+
#If the display_help option was set, display a short help blurb.
|
163
|
+
if display_help
|
164
|
+
puts "\n Short-names (to the left) can be used as parameters to the"
|
165
|
+
puts " --core command line flag."
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
169
|
+
|
170
|
+
#
|
171
|
+
# Merge the provided file into the specified core, and return the resultant
|
172
|
+
# bitstream.
|
173
|
+
#
|
174
|
+
def merge_file_and_core(core_name, file, target=nil)
|
175
|
+
|
176
|
+
#... try to find a core with the given name.
|
177
|
+
core = Core.from_shortname(core_name)
|
178
|
+
|
179
|
+
#If we couldn't find a core with the given name, print an error message.
|
180
|
+
unless core
|
181
|
+
fatal_error "Couldn't find a core with the name #{core_name.underline}.\n" +
|
182
|
+
"You can list all available cores with the --list-cores command line option. "
|
183
|
+
end
|
184
|
+
|
185
|
+
if file
|
186
|
+
puts "Merging".bold + " #{File.basename(file)} into the #{core.shortname} core..."
|
187
|
+
end
|
188
|
+
|
189
|
+
#Create a bitstream from the given core.
|
190
|
+
file = core.to_bitstream(target, file)
|
191
|
+
|
192
|
+
#Notify the user that programming is about to begin.
|
193
|
+
puts "Programming".bold + " the attached board with the #{core.shortname} core..."
|
194
|
+
|
195
|
+
file
|
196
|
+
|
197
|
+
end
|
198
|
+
|
199
|
+
def read_bitstream(file)
|
200
|
+
begin
|
201
|
+
Adept::DataFormats::Bitstream.from_file(file)
|
202
|
+
rescue IOError
|
203
|
+
fatal_error "You specified a file to program that wasn't a bitfile!\n" +
|
204
|
+
"(If you wanted to program this file to a processor core, use the --core <processor> option.)"
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
#Parse the command-line flags.
|
209
|
+
options = Trollop::options do
|
210
|
+
version "bprog #{Adept::VERSION} (c) 2013 Binghamton University"
|
211
|
+
|
212
|
+
banner <<-BANNER
|
213
|
+
bprog #{Adept::VERSION} (c) 2013 Binghamton University
|
214
|
+
Author: Kyle Temkin, ktemkin@binghamton.edu
|
215
|
+
|
216
|
+
bprog ("board programmer") is a command-line programmer for Digilent devices
|
217
|
+
intended to simplify the process of programming Digilent devices.
|
218
|
+
|
219
|
+
usage: [options] <filename>
|
220
|
+
|
221
|
+
BANNER
|
222
|
+
|
223
|
+
opt :core, "Specifies a soft-core to use. If a compiled program is provided, it will be merged into the specified core.", :type => String
|
224
|
+
opt :'list-cores', "Display a list of all available processor cores."
|
225
|
+
|
226
|
+
end
|
227
|
+
|
228
|
+
# If the list-cores option is set, list the available cores, and quit.
|
229
|
+
list_available_cores if options[:'list-cores']
|
230
|
+
|
231
|
+
# If we're using the core option, make the file argument optional,
|
232
|
+
# and do not attempt to guess it. (Options[:core] will be nil unless
|
233
|
+
# a core name is provided, and true-like otherwise.)
|
234
|
+
allow_none = do_not_guess = options[:core]
|
235
|
+
|
236
|
+
# Create a JTAG connection to the Adept board.
|
237
|
+
connection = get_target_connection(options[:'list-cores'])
|
238
|
+
|
239
|
+
# Get the name of the connected FPGA, if applicable.
|
240
|
+
part_name = connected_fpga_part_name(connection)
|
241
|
+
|
242
|
+
#If the list_available_cores flag is set, list the compatible cores,
|
243
|
+
#
|
244
|
+
#and quit.
|
245
|
+
if options[:'list-cores']
|
246
|
+
puts
|
247
|
+
puts
|
248
|
+
list_available_cores(part_name, false)
|
249
|
+
exit
|
250
|
+
end
|
251
|
+
|
252
|
+
# Get the target file, if applicable.
|
253
|
+
file = get_target_file(do_not_guess, allow_none)
|
254
|
+
|
255
|
+
# If the core option was specified, attempt to merge it with the provided
|
256
|
+
# filename. (If no filename was provided, the core's bitstream will be returned.)
|
257
|
+
if options[:core]
|
258
|
+
file = merge_file_and_core(options[:core], file, part_name)
|
259
|
+
|
260
|
+
# Otherwise, read the file as a bitstream directly.
|
261
|
+
else
|
262
|
+
file = read_bitstream(file)
|
263
|
+
end
|
101
264
|
|
102
265
|
begin
|
103
266
|
configure_fpga(connection, file)
|
Binary file
|
@@ -0,0 +1,56 @@
|
|
1
|
+
// BMM LOC annotation file.
|
2
|
+
//
|
3
|
+
// Release 13.4 - P.15xf, build 2.8 Mar 16, 2012
|
4
|
+
// Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved.
|
5
|
+
|
6
|
+
|
7
|
+
///////////////////////////////////////////////////////////////////////////////
|
8
|
+
//
|
9
|
+
// Processor 'avrmap', ID 0, memory map.
|
10
|
+
//
|
11
|
+
///////////////////////////////////////////////////////////////////////////////
|
12
|
+
|
13
|
+
ADDRESS_MAP avrmap PPC405 0
|
14
|
+
|
15
|
+
///////////////////////////////////////////////////////////////////////////////
|
16
|
+
//
|
17
|
+
// Processor 'avrmap' address space 'rom_code' 0x00000000:0x00003FFF (16 KBytes).
|
18
|
+
//
|
19
|
+
///////////////////////////////////////////////////////////////////////////////
|
20
|
+
|
21
|
+
ADDRESS_SPACE rom_code RAMB16 [0x00000000:0x00003FFF]
|
22
|
+
BUS_BLOCK
|
23
|
+
PM_Inst/RAM_Word0 RAMB16 [15:0] [0:1023] PLACED = X1Y2;
|
24
|
+
END_BUS_BLOCK;
|
25
|
+
|
26
|
+
BUS_BLOCK
|
27
|
+
PM_Inst/RAM_Word1 RAMB16 [15:0] [1024:2047] PLACED = X0Y1;
|
28
|
+
END_BUS_BLOCK;
|
29
|
+
|
30
|
+
BUS_BLOCK
|
31
|
+
PM_Inst/RAM_Word2 RAMB16 [15:0] [2048:3071] PLACED = X0Y2;
|
32
|
+
END_BUS_BLOCK;
|
33
|
+
|
34
|
+
BUS_BLOCK
|
35
|
+
PM_Inst/RAM_Word3 RAMB16 [15:0] [3072:4095] PLACED = X1Y0;
|
36
|
+
END_BUS_BLOCK;
|
37
|
+
|
38
|
+
BUS_BLOCK
|
39
|
+
PM_Inst/RAM_Word4 RAMB16 [15:0] [4096:5119] PLACED = X1Y5;
|
40
|
+
END_BUS_BLOCK;
|
41
|
+
|
42
|
+
BUS_BLOCK
|
43
|
+
PM_Inst/RAM_Word5 RAMB16 [15:0] [5120:6143] PLACED = X1Y3;
|
44
|
+
END_BUS_BLOCK;
|
45
|
+
|
46
|
+
BUS_BLOCK
|
47
|
+
PM_Inst/RAM_Word6 RAMB16 [15:0] [6144:7167] PLACED = X1Y4;
|
48
|
+
END_BUS_BLOCK;
|
49
|
+
|
50
|
+
BUS_BLOCK
|
51
|
+
PM_Inst/RAM_Word7 RAMB16 [15:0] [7168:8191] PLACED = X1Y1;
|
52
|
+
END_BUS_BLOCK;
|
53
|
+
END_ADDRESS_SPACE;
|
54
|
+
|
55
|
+
END_ADDRESS_MAP;
|
56
|
+
|
@@ -26,7 +26,7 @@
|
|
26
26
|
<association xil_pn:name="PostTranslateSimulation" xil_pn:seqID="5"/>
|
27
27
|
</file>
|
28
28
|
<file xil_pn:name="epp_controller.vhd" xil_pn:type="FILE_VHDL">
|
29
|
-
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="
|
29
|
+
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="0"/>
|
30
30
|
<association xil_pn:name="Implementation" xil_pn:seqID="1"/>
|
31
31
|
</file>
|
32
32
|
<file xil_pn:name="Basys2_100_250General.ucf" xil_pn:type="FILE_UCF">
|
@@ -181,7 +181,7 @@
|
|
181
181
|
<property xil_pn:name="Optimization Strategy (Cover Mode)" xil_pn:value="Area" xil_pn:valueState="default"/>
|
182
182
|
<property xil_pn:name="Optimize Instantiated Primitives" xil_pn:value="false" xil_pn:valueState="default"/>
|
183
183
|
<property xil_pn:name="Other Bitgen Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
|
184
|
-
<property xil_pn:name="Other Compiler Options" xil_pn:value="" xil_pn:valueState="default"/>
|
184
|
+
<property xil_pn:name="Other Compiler Options" xil_pn:value="-mt off -v 1" xil_pn:valueState="non-default"/>
|
185
185
|
<property xil_pn:name="Other Compiler Options Map" xil_pn:value="" xil_pn:valueState="default"/>
|
186
186
|
<property xil_pn:name="Other Compiler Options Par" xil_pn:value="" xil_pn:valueState="default"/>
|
187
187
|
<property xil_pn:name="Other Compiler Options Translate" xil_pn:value="" xil_pn:valueState="default"/>
|
@@ -256,8 +256,8 @@
|
|
256
256
|
<property xil_pn:name="Run for Specified Time Translate" xil_pn:value="true" xil_pn:valueState="default"/>
|
257
257
|
<property xil_pn:name="Safe Implementation" xil_pn:value="No" xil_pn:valueState="default"/>
|
258
258
|
<property xil_pn:name="Security" xil_pn:value="Enable Readback and Reconfiguration" xil_pn:valueState="default"/>
|
259
|
-
<property xil_pn:name="Selected Module Instance Name" xil_pn:value="/
|
260
|
-
<property xil_pn:name="Selected Simulation Root Source Node Behavioral" xil_pn:value="work.
|
259
|
+
<property xil_pn:name="Selected Module Instance Name" xil_pn:value="/fifo_testbench" xil_pn:valueState="non-default"/>
|
260
|
+
<property xil_pn:name="Selected Simulation Root Source Node Behavioral" xil_pn:value="work.fifo_testbench" xil_pn:valueState="non-default"/>
|
261
261
|
<property xil_pn:name="Selected Simulation Root Source Node Post-Map" xil_pn:value="" xil_pn:valueState="default"/>
|
262
262
|
<property xil_pn:name="Selected Simulation Root Source Node Post-Route" xil_pn:value="" xil_pn:valueState="default"/>
|
263
263
|
<property xil_pn:name="Selected Simulation Root Source Node Post-Translate" xil_pn:value="" xil_pn:valueState="default"/>
|
@@ -273,7 +273,7 @@
|
|
273
273
|
<property xil_pn:name="Slice Packing" xil_pn:value="true" xil_pn:valueState="default"/>
|
274
274
|
<property xil_pn:name="Slice Utilization Ratio" xil_pn:value="100" xil_pn:valueState="default"/>
|
275
275
|
<property xil_pn:name="Specify 'define Macro Name and Value" xil_pn:value="" xil_pn:valueState="default"/>
|
276
|
-
<property xil_pn:name="Specify Top Level Instance Names Behavioral" xil_pn:value="work.
|
276
|
+
<property xil_pn:name="Specify Top Level Instance Names Behavioral" xil_pn:value="work.fifo_testbench" xil_pn:valueState="default"/>
|
277
277
|
<property xil_pn:name="Specify Top Level Instance Names Post-Map" xil_pn:value="Default" xil_pn:valueState="default"/>
|
278
278
|
<property xil_pn:name="Specify Top Level Instance Names Post-Route" xil_pn:value="Default" xil_pn:valueState="default"/>
|
279
279
|
<property xil_pn:name="Specify Top Level Instance Names Post-Translate" xil_pn:value="Default" xil_pn:valueState="default"/>
|
data/lib/adept.rb
CHANGED
data/lib/adept/core.rb
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
require 'adept'
|
2
|
+
require 'yaml'
|
3
|
+
require 'tempfile'
|
4
|
+
|
5
|
+
module Adept
|
6
|
+
|
7
|
+
|
8
|
+
#
|
9
|
+
# Class which represents a data-2-mem configurable IP core.
|
10
|
+
#
|
11
|
+
class Core
|
12
|
+
|
13
|
+
attr_reader :name
|
14
|
+
attr_reader :targets
|
15
|
+
attr_reader :shortname
|
16
|
+
|
17
|
+
#
|
18
|
+
# Returns a list of all available cores, optionally filtered by a device ID string.
|
19
|
+
#
|
20
|
+
def self.available_cores(device=nil)
|
21
|
+
|
22
|
+
#Determine the path at which the ruby-adept gem is stored.
|
23
|
+
gem_path = File.expand_path('../..', File.dirname(__FILE__))
|
24
|
+
|
25
|
+
#Get a list of all available core definition files.
|
26
|
+
core_definitions = Dir["#{gem_path}/cores/**/core.yaml"]
|
27
|
+
|
28
|
+
#Convert each definition to a YAML core.
|
29
|
+
definitions = core_definitions.map { |file| from_definition_file(file) }
|
30
|
+
|
31
|
+
#If we were passed a device shortname to filter by, ensure we
|
32
|
+
#only return cores that support that target.
|
33
|
+
unless device.nil?
|
34
|
+
definitions = definitions.select { |core| core.targets.include?(device) }
|
35
|
+
end
|
36
|
+
|
37
|
+
definitions
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
# Returns the core with the given shortname, or nil if no
|
43
|
+
# such core exists.
|
44
|
+
#
|
45
|
+
def self.from_shortname(shortname)
|
46
|
+
available_cores.find { |core| core.shortname == shortname }
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
# Creates a new Core object from a YAML definition file.
|
51
|
+
#
|
52
|
+
# file: The full path to a YAML core definition file.
|
53
|
+
#
|
54
|
+
def self.from_definition_file(file)
|
55
|
+
|
56
|
+
#Get the path of the directory that holds the core's files.
|
57
|
+
base_path = File.dirname(file)
|
58
|
+
|
59
|
+
#Parse the YAML definition file.
|
60
|
+
raw_definition = YAML.load_file(file)
|
61
|
+
|
62
|
+
#Return a new core object.
|
63
|
+
new(raw_definition["name"], raw_definition["shortname"], base_path, raw_definition["targets"])
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
# Initializes a new instance of a Core object.
|
69
|
+
#
|
70
|
+
def initialize(name, shortname, base_path, targets)
|
71
|
+
@name = name
|
72
|
+
@shortname = shortname
|
73
|
+
@base_path = base_path
|
74
|
+
@targets = targets
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# Returns a bitstream which can be use to load the given core onto the target
|
79
|
+
# device. If a program is provided, it will be loaded into the resultant bitstream.
|
80
|
+
#
|
81
|
+
# target: The Device ID string of the board to be programmed.
|
82
|
+
#
|
83
|
+
def to_bitstream(target=@targets.keys.first, program=nil)
|
84
|
+
|
85
|
+
#Ensure the target is a string.
|
86
|
+
target = target.to_s
|
87
|
+
|
88
|
+
#Get the path to the bitfile and memory map which will be used to generate the new bitfile.
|
89
|
+
memory_map = "#@base_path/#{@targets[target]['memory_map']}"
|
90
|
+
bit_file = "#@base_path/#{@targets[target]['bit_file']}"
|
91
|
+
|
92
|
+
#If no program was provided, return the bitfile unmodified.
|
93
|
+
return Adept::DataFormats::Bitstream.from_file(bit_file) unless program
|
94
|
+
|
95
|
+
#Generate the new raw bitfile...
|
96
|
+
hex = with_temporary_files { |dest, _| system("avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock #{program} #{dest}") }
|
97
|
+
mem = with_temporary_files(hex, '.mem', '.hex') { |dest, source| system("srec_cat #{source} -Intel -Byte_Swap 2 -Data_Only -Line_Length 100000000 -o #{dest} -vmem 8") }
|
98
|
+
bit = with_temporary_files(mem, '.bit', '.mem') { |dest, source| system("data2mem -bm #{memory_map} -bt #{bit_file} -bd #{source} -o b #{dest}") }
|
99
|
+
|
100
|
+
#... wrap it in a Bitstream object, and return it.
|
101
|
+
Adept::DataFormats::Bitstream.from_string(bit)
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
#
|
106
|
+
# Print a debugging represntation of the core.
|
107
|
+
#
|
108
|
+
def inspect
|
109
|
+
"<IP Core 0x#{object_id.to_s(16)}: #@name>"
|
110
|
+
end
|
111
|
+
|
112
|
+
private
|
113
|
+
|
114
|
+
#
|
115
|
+
# Executes a given block with an "anonymous" temporary file.
|
116
|
+
# The temporary file is deleted at the end of the block, and its contents
|
117
|
+
# are returned.
|
118
|
+
#
|
119
|
+
def with_temporary_files(file_contents='', dest_extension = '', source_extension = '', message=nil)
|
120
|
+
|
121
|
+
#File mode for all of the created temporary files.
|
122
|
+
#Create the files, and allow read/write, but do not lock for exclusive access.
|
123
|
+
file_mode = File::CREAT | File::RDWR
|
124
|
+
|
125
|
+
#Create a new file which contains the provided file content.
|
126
|
+
#Used to pass arbitrary data into an external tool.
|
127
|
+
Tempfile.open(['core_prev', source_extension], :mode => file_mode) do |source_file|
|
128
|
+
|
129
|
+
#Fill the source file with the provided file contents...
|
130
|
+
source_file.write(file_contents)
|
131
|
+
source_file.flush
|
132
|
+
|
133
|
+
#Create a new file which will store the resultant file content.
|
134
|
+
Tempfile.open(['core_next', dest_extension], :mode => file_mode) do |destination_file|
|
135
|
+
|
136
|
+
#Yield the file's paths the provided block.
|
137
|
+
raise CommandFailedError, message unless yield [destination_file.path, source_file.path]
|
138
|
+
|
139
|
+
#And return the content of the destination file.
|
140
|
+
return File::read(destination_file)
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
end
|
data/lib/adept/error.rb
CHANGED
data/lib/adept/jtag/device.rb
CHANGED
data/lib/adept/version.rb
CHANGED
@@ -15,16 +15,16 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.summary = "Framework for working with Digilent Adept devices."
|
16
16
|
gem.homepage = "http://www.github.com/ktemkin/ruby-adept"
|
17
17
|
|
18
|
-
gem.add_runtime_dependency 'bindata'
|
18
|
+
gem.add_runtime_dependency 'bindata', '~>1.4.5'
|
19
|
+
gem.add_runtime_dependency 'ffi', '~>1.3.1'
|
20
|
+
gem.add_runtime_dependency 'require_all', '~>1.2.1'
|
21
|
+
gem.add_runtime_dependency 'smart_colored', '~>1.1.1'
|
22
|
+
gem.add_runtime_dependency 'trollop', '~>2.0'
|
23
|
+
gem.add_runtime_dependency 'ruby-elf', '~>1.0.8'
|
19
24
|
gem.add_runtime_dependency 'ruby-ise'
|
20
|
-
gem.add_runtime_dependency 'trollop'
|
21
|
-
gem.add_runtime_dependency 'smart_colored'
|
22
|
-
gem.add_runtime_dependency 'ffi'
|
23
|
-
gem.add_runtime_dependency 'require_all'
|
24
|
-
|
25
|
-
gem.add_development_dependency 'rspec'
|
26
|
-
gem.add_development_dependency 'fakefs'
|
27
25
|
|
26
|
+
gem.add_development_dependency 'rspec', '~>2.12.0'
|
27
|
+
gem.add_development_dependency 'fakefs', '~>0.4.2'
|
28
28
|
|
29
29
|
gem.files = `git ls-files`.split($/)
|
30
30
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
@@ -0,0 +1,58 @@
|
|
1
|
+
|
2
|
+
require 'adept'
|
3
|
+
|
4
|
+
#
|
5
|
+
# Specification for the Adept Device interface.
|
6
|
+
# These tests assume _only_ one connected Basys2 board!
|
7
|
+
#
|
8
|
+
describe Adept::Core do
|
9
|
+
|
10
|
+
let(:avr8) { 'ATMega103-compatible AVR' }
|
11
|
+
|
12
|
+
#
|
13
|
+
# Matcher which returns true if the given list contains the AVR-8.
|
14
|
+
#
|
15
|
+
RSpec::Matchers.define :include_a_core_named do |expected|
|
16
|
+
match do |given|
|
17
|
+
given.find { |core| core.name == expected }
|
18
|
+
end
|
19
|
+
|
20
|
+
failure_message_for_should { |given| "expected #{actual.inspect} to contain a core named '#{expected}'" }
|
21
|
+
failure_message_for_should_not { |given| "expected #{actual.inspect} to not contain a core named '#{expected}'" }
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
describe "class methods" do
|
26
|
+
|
27
|
+
describe "#available_cores" do
|
28
|
+
subject { Adept::Core }
|
29
|
+
|
30
|
+
it "should return an array of known cores" do
|
31
|
+
|
32
|
+
#Get a list of all available cores...
|
33
|
+
cores = subject.available_cores
|
34
|
+
|
35
|
+
#... and validate their types.
|
36
|
+
cores.should be_an Array
|
37
|
+
cores.all? { |x| x.should be_a Adept::Core}
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
context "when provided with a device name" do
|
42
|
+
it "should return only the cores that correspond to that device name" do
|
43
|
+
subject.available_cores('invalidDevice').should_not include_a_core_named avr8
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "when a device name is not provided" do
|
48
|
+
it "should return all known cores as core objects" do
|
49
|
+
subject.available_cores('3s250ecp132').should include_a_core_named avr8
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-adept
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,90 +9,106 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-03-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bindata
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
|
-
- -
|
19
|
+
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
21
|
+
version: 1.4.5
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
26
26
|
requirements:
|
27
|
-
- -
|
27
|
+
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: 1.4.5
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
|
-
name:
|
31
|
+
name: ffi
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
none: false
|
34
34
|
requirements:
|
35
|
-
- -
|
35
|
+
- - ~>
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version:
|
37
|
+
version: 1.3.1
|
38
38
|
type: :runtime
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
42
|
requirements:
|
43
|
-
- -
|
43
|
+
- - ~>
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version:
|
45
|
+
version: 1.3.1
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
|
-
name:
|
47
|
+
name: require_all
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
49
49
|
none: false
|
50
50
|
requirements:
|
51
|
-
- -
|
51
|
+
- - ~>
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version:
|
53
|
+
version: 1.2.1
|
54
54
|
type: :runtime
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
none: false
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 1.2.1
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
63
|
name: smart_colored
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
65
65
|
none: false
|
66
66
|
requirements:
|
67
|
-
- -
|
67
|
+
- - ~>
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version:
|
69
|
+
version: 1.1.1
|
70
70
|
type: :runtime
|
71
71
|
prerelease: false
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
73
73
|
none: false
|
74
74
|
requirements:
|
75
|
-
- -
|
75
|
+
- - ~>
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
version:
|
77
|
+
version: 1.1.1
|
78
78
|
- !ruby/object:Gem::Dependency
|
79
|
-
name:
|
79
|
+
name: trollop
|
80
80
|
requirement: !ruby/object:Gem::Requirement
|
81
81
|
none: false
|
82
82
|
requirements:
|
83
|
-
- -
|
83
|
+
- - ~>
|
84
84
|
- !ruby/object:Gem::Version
|
85
|
-
version: '0'
|
85
|
+
version: '2.0'
|
86
86
|
type: :runtime
|
87
87
|
prerelease: false
|
88
88
|
version_requirements: !ruby/object:Gem::Requirement
|
89
89
|
none: false
|
90
90
|
requirements:
|
91
|
-
- -
|
91
|
+
- - ~>
|
92
92
|
- !ruby/object:Gem::Version
|
93
|
-
version: '0'
|
93
|
+
version: '2.0'
|
94
94
|
- !ruby/object:Gem::Dependency
|
95
|
-
name:
|
95
|
+
name: ruby-elf
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 1.0.8
|
102
|
+
type: :runtime
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 1.0.8
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: ruby-ise
|
96
112
|
requirement: !ruby/object:Gem::Requirement
|
97
113
|
none: false
|
98
114
|
requirements:
|
@@ -112,33 +128,33 @@ dependencies:
|
|
112
128
|
requirement: !ruby/object:Gem::Requirement
|
113
129
|
none: false
|
114
130
|
requirements:
|
115
|
-
- -
|
131
|
+
- - ~>
|
116
132
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
133
|
+
version: 2.12.0
|
118
134
|
type: :development
|
119
135
|
prerelease: false
|
120
136
|
version_requirements: !ruby/object:Gem::Requirement
|
121
137
|
none: false
|
122
138
|
requirements:
|
123
|
-
- -
|
139
|
+
- - ~>
|
124
140
|
- !ruby/object:Gem::Version
|
125
|
-
version:
|
141
|
+
version: 2.12.0
|
126
142
|
- !ruby/object:Gem::Dependency
|
127
143
|
name: fakefs
|
128
144
|
requirement: !ruby/object:Gem::Requirement
|
129
145
|
none: false
|
130
146
|
requirements:
|
131
|
-
- -
|
147
|
+
- - ~>
|
132
148
|
- !ruby/object:Gem::Version
|
133
|
-
version:
|
149
|
+
version: 0.4.2
|
134
150
|
type: :development
|
135
151
|
prerelease: false
|
136
152
|
version_requirements: !ruby/object:Gem::Requirement
|
137
153
|
none: false
|
138
154
|
requirements:
|
139
|
-
- -
|
155
|
+
- - ~>
|
140
156
|
- !ruby/object:Gem::Version
|
141
|
-
version:
|
157
|
+
version: 0.4.2
|
142
158
|
description: ! "Ruby library for working with Digilent devices via the Adept SDK.\n
|
143
159
|
\ Provides both low-level wrappers for the Adept SDK elements and high-level\n
|
144
160
|
\ interfaces, including simple programming and configuration routines."
|
@@ -155,9 +171,11 @@ files:
|
|
155
171
|
- LICENSE.txt
|
156
172
|
- README.md
|
157
173
|
- Rakefile
|
158
|
-
- adept.gemspec
|
159
174
|
- autotest/discover.rb
|
160
175
|
- bin/bprog
|
176
|
+
- cores/avr8/avr_250k.bit
|
177
|
+
- cores/avr8/avr_250k.bmm
|
178
|
+
- cores/avr8/core.yaml
|
161
179
|
- firmware/.gitignore
|
162
180
|
- firmware/epp_stream/Basys2_100_250General.ucf
|
163
181
|
- firmware/epp_stream/epp_controller.vhd
|
@@ -168,6 +186,7 @@ files:
|
|
168
186
|
- lib/adept/boards.rb
|
169
187
|
- lib/adept/boards/basys2.rb
|
170
188
|
- lib/adept/connection_provider.rb
|
189
|
+
- lib/adept/core.rb
|
171
190
|
- lib/adept/data_formats.rb
|
172
191
|
- lib/adept/data_formats/bitstream.rb
|
173
192
|
- lib/adept/data_formats/data_factories.rb
|
@@ -193,7 +212,9 @@ files:
|
|
193
212
|
- lib/adept/low_level/jtag.rb
|
194
213
|
- lib/adept/low_level/library.rb
|
195
214
|
- lib/adept/version.rb
|
215
|
+
- ruby-adept.gemspec
|
196
216
|
- spec/firmware/epp_loopback.bit
|
217
|
+
- spec/lib/adept/core_spec.rb
|
197
218
|
- spec/lib/adept/data_formats/bitstream_spec.rb
|
198
219
|
- spec/lib/adept/data_formats/data_factories_spec.rb
|
199
220
|
- spec/lib/adept/device_spec.rb
|
@@ -229,6 +250,7 @@ specification_version: 3
|
|
229
250
|
summary: Framework for working with Digilent Adept devices.
|
230
251
|
test_files:
|
231
252
|
- spec/firmware/epp_loopback.bit
|
253
|
+
- spec/lib/adept/core_spec.rb
|
232
254
|
- spec/lib/adept/data_formats/bitstream_spec.rb
|
233
255
|
- spec/lib/adept/data_formats/data_factories_spec.rb
|
234
256
|
- spec/lib/adept/device_spec.rb
|