ruby-adept 0.0.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|