origen_memory_image 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d364a5cedbccf382fae2a6bf7732604387fbdaf1
4
+ data.tar.gz: 87baaf7587ea2ee10562844104638ccc1bc46252
5
+ SHA512:
6
+ metadata.gz: d6873cb75247b6fbc0924706c982f6b0d7edf980b8137d791e48c7a3344336254f85b5e352a6ced1170c9b3a112614cc47a0375d6d9dcfdf0e3496cba3a7d218
7
+ data.tar.gz: c4afd730adea6589dce1bb53cf243283c39a66b6257681db1888c4e84274abdd3704453b74de010b647ba97b9acec4ef31d12d26041e9b1f10c952f606bbc1c8
@@ -0,0 +1,87 @@
1
+ class OrigenMemoryImageApplication < Origen::Application
2
+
3
+ # To share resources with the apps that import this plugin uncomment the following attribute:
4
+ #config.shared = {
5
+ # Add the dir/file of patterns that needs to be shared
6
+ # patterns: "pattern/shared",
7
+ # Add the file which includes all commands that needs the be shared with the app that imports
8
+ # this plugin in :command_launcher attribute
9
+ # command_launcher: "config/shared_commands.rb",
10
+ # Shared templates go in the :templates attribute
11
+ # templates: "templates/shared_templates",
12
+ # Shared programs go in the :programs attributes
13
+ # programs: "programs/shared"
14
+ #}
15
+
16
+ # This information is used in headers and email templates, set it specific
17
+ # to your application
18
+ config.name = "Origen Memory Image"
19
+ config.initials = "OrigenMemoryImage"
20
+ config.rc_url = "git@github.com:Origen-SDK/origen_memory_image.git"
21
+ config.release_externally = true
22
+
23
+ config.web_directory = "git@github.com:Origen-SDK/Origen-SDK.github.io.git/memory_image"
24
+ config.web_domain = "http://origen-sdk.org/memory_image"
25
+
26
+ # When false Origen will be less strict about checking for some common coding errors,
27
+ # it is recommended that you leave this to true for better feedback and easier debug.
28
+ # This will be the default setting in Origen v3.
29
+ config.strict_errors = true
30
+
31
+ # See: http://origen.freescale.net/origen/latest/guides/utilities/lint/
32
+ config.lint_test = {
33
+ # Require the lint tests to pass before allowing a release to proceed
34
+ run_on_tag: true,
35
+ # Auto correct violations where possible whenever 'origen lint' is run
36
+ auto_correct: true,
37
+ # Limit the testing for large legacy applications
38
+ #level: :easy,
39
+ # Run on these directories/files by default
40
+ #files: ["lib", "config/application.rb"],
41
+ }
42
+
43
+ config.semantically_version = true
44
+
45
+ # By default all generated output will end up in ./output.
46
+ # Here you can specify an alternative directory entirely, or make it dynamic such that
47
+ # the output ends up in a setup specific directory.
48
+ #config.output_directory do
49
+ # "#{Origen.root}/output/#{$dut.class}"
50
+ #end
51
+
52
+ # Similary for the reference files, generally you want to setup the reference directory
53
+ # structure to mirror that of your output directory structure.
54
+ #config.reference_directory do
55
+ # "#{Origen.root}/.ref/#{$dut.class}"
56
+ #end
57
+
58
+ # Run the tests before deploying to generate test coverage numbers
59
+ def before_deploy_site
60
+ Dir.chdir Origen.root do
61
+ #system "origen examples -c"
62
+ system "origen specs -c"
63
+ dir = "#{Origen.root}/web/output/coverage"
64
+ FileUtils.remove_dir(dir, true) if File.exists?(dir)
65
+ system "mv #{Origen.root}/coverage #{dir}"
66
+ end
67
+ end
68
+
69
+ # This will automatically deploy your documentation after every tag
70
+ def after_release_email(tag, note, type, selector, options)
71
+ command = "origen web compile --remote --api"
72
+ Dir.chdir Origen.root do
73
+ system command
74
+ end
75
+ end
76
+
77
+ # Ensure that all tests pass before allowing a release to continue
78
+ def validate_release
79
+ if !system("origen specs") #|| !system("origen examples")
80
+ puts "Sorry but you can't release with failing tests, please fix them and try again."
81
+ exit 1
82
+ else
83
+ puts "All tests passing, proceeding with release process!"
84
+ end
85
+ end
86
+
87
+ end
@@ -0,0 +1,107 @@
1
+ # This file should be used to extend the origen command line tool with tasks
2
+ # specific to your application.
3
+ # The comments below should help to get started and you can also refer to
4
+ # lib/origen/commands.rb in your Origen core workspace for more examples and
5
+ # inspiration.
6
+ #
7
+ # Also see the official docs on adding commands:
8
+ # http://origen.freescale.net/origen/latest/guides/custom/commands/
9
+
10
+ # Map any command aliases here, for example to allow origen -x to refer to a
11
+ # command called execute you would add a reference as shown below:
12
+ aliases ={
13
+ # "-x" => "execute",
14
+ }
15
+
16
+ # The requested command is passed in here as @command, this checks it against
17
+ # the above alias table and should not be removed.
18
+ @command = aliases[@command] || @command
19
+
20
+ # Smome helper methods to enable test coverage, these will eventually be
21
+ # added to Origen Core, but they need to be here for now
22
+ def path_to_coverage_report
23
+ require 'pathname'
24
+ Pathname.new("#{Origen.root}/coverage/index.html").relative_path_from(Pathname.pwd)
25
+ end
26
+
27
+ def enable_coverage(name, merge=true)
28
+ if ARGV.delete("-c") || ARGV.delete("--coverage")
29
+ require 'simplecov'
30
+ SimpleCov.start do
31
+ command_name name
32
+ add_filter "DO_NOT_HAND_MODIFY" # Exclude all imports
33
+
34
+ at_exit do
35
+ SimpleCov.result.format!
36
+ puts ""
37
+ puts "To view coverage report:"
38
+ puts " firefox #{path_to_coverage_report} &"
39
+ puts ""
40
+ end
41
+ end
42
+ yield
43
+ else
44
+ yield
45
+ end
46
+ end
47
+
48
+ # Now branch to the specific task code
49
+ case @command
50
+
51
+ # Run the unit tests
52
+ when "specs"
53
+ enable_coverage("specs") do
54
+ ARGV.unshift "spec"
55
+ require "rspec"
56
+ # For some unidentified reason Rspec does not autorun on this version
57
+ if RSpec::Core::Version::STRING && RSpec::Core::Version::STRING == "2.11.1"
58
+ RSpec::Core::Runner.run ARGV
59
+ else
60
+ require "rspec/autorun"
61
+ end
62
+ end
63
+ exit 0 # This will never be hit on a fail, RSpec will automatically exit 1
64
+
65
+ # Run the example-based (diff) tests
66
+ #when "examples"
67
+ # Origen.load_application
68
+ # status = 0
69
+ # enable_coverage("examples") do
70
+ #
71
+ # # Compiler tests
72
+ # ARGV = %w(templates/example.txt.erb -t debug -r approved)
73
+ # load "origen/commands/compile.rb"
74
+ # # Pattern generator tests
75
+ # #ARGV = %w(some_pattern -t debug -r approved)
76
+ # #load "#{Origen.top}/lib/origen/commands/generate.rb"
77
+ #
78
+ # if Origen.app.stats.changed_files == 0 &&
79
+ # Origen.app.stats.new_files == 0 &&
80
+ # Origen.app.stats.changed_patterns == 0 &&
81
+ # Origen.app.stats.new_patterns == 0
82
+ #
83
+ # Origen.app.stats.report_pass
84
+ # else
85
+ # Origen.app.stats.report_fail
86
+ # status = 1
87
+ # end
88
+ # puts ""
89
+ # end
90
+ # exit status # Exit with a 1 on the event of a failure per std unix result codes
91
+
92
+ # Always leave an else clause to allow control to fall back through to the
93
+ # Origen command handler.
94
+ # You probably want to also add the command details to the help shown via
95
+ # origen -h, you can do this be assigning the required text to @application_commands
96
+ # before handing control back to Origen. Un-comment the example below to get started.
97
+ else
98
+ @application_commands = <<-EOT
99
+ specs Run the specs (tests), -c will enable coverage
100
+ EOT
101
+ # examples Run the examples (tests), -c will enable coverage
102
+
103
+ # Uncomment the following and update the path with the file
104
+ # that handles the commands that are shared from this plugin
105
+ #require "#{Origen.app_root}/config/shared_commands"
106
+
107
+ end
@@ -0,0 +1,12 @@
1
+ # This file is similar to environment.rb and will be loaded
2
+ # automatically at the start of each invocation of Origen.
3
+ #
4
+ # However the major difference is that it will not be loaded
5
+ # if the application is imported by a 3rd party app - in that
6
+ # case only environment.rb is loaded.
7
+ #
8
+ # Therefore this file should be used to load anything you need
9
+ # to setup a development environment for this app, normally
10
+ # this would be used to load some dummy classes to instantiate
11
+ # your objects so that they can be tested and/or interacted with
12
+ # in the console.
@@ -0,0 +1,40 @@
1
+ # This file will be required by Origen before your target is loaded, you
2
+ # can use this to require all of your files, which is the easiest way
3
+ # to get started. As your experience grows you may wish to require only the
4
+ # minimum files required to allow the target to be initialized and let
5
+ # each class require its own dependencies.
6
+ #
7
+ # It is recommended that you keep all of your application logic in lib/
8
+ # The lib directory has already been added to the search path and so any files
9
+ # in there can be referenced from here with a relative path.
10
+ #
11
+ # Note that pattern files do not need to be referenced from here and these
12
+ # will be located automatically by origen.
13
+ #
14
+ # Examples
15
+ # --------
16
+ # This says load the file "lib/pioneer.rb" the first time anyone makes a
17
+ # reference to the class name 'Pioneer'.
18
+ #autoload :Pioneer, "pioneer"
19
+ #
20
+ # This is generally preferable to using require which will load the file
21
+ # regardless of whether it is needed by the current target or not:
22
+ #require "pioneer"
23
+ #
24
+ # Sometimes you have to use require however:-
25
+ # 1. When defining a test program interface:
26
+ #require "interfaces/j750"
27
+ # 2. If you want to extend a class defined by an imported plugin, in
28
+ # this case your must use required and supply a full path (to distinguish
29
+ # it from the one in the parent application):
30
+ #require "#{Origen.root}/c90_top_level/p2"
31
+
32
+ # Plugins should not use a wildcard import of the lib directory to help
33
+ # prevent long start up times, only require what is necessary to boot and
34
+ # use autoload for everything else.
35
+ module OrigenMemoryImage
36
+ autoload :Base, "origen_memory_image/base"
37
+ autoload :SRecord, "origen_memory_image/s_record"
38
+ autoload :Hex, "origen_memory_image/hex"
39
+ end
40
+ require "origen_memory_image"
data/config/users.rb ADDED
@@ -0,0 +1,18 @@
1
+ # This file defines the users associated with your project, it is basically the
2
+ # mailing list for release notes.
3
+ #
4
+ # You can split your users into "admin" and "user" groups, the main difference
5
+ # between the two is that admin users will get all tag emails, users will get
6
+ # emails on external/official releases only.
7
+ #
8
+ # Users are also prohibited from running the "origen tag" task, but this is
9
+ # really just to prevent a casual user from executing it inadvertently and is
10
+ # not intended to be a serious security gate.
11
+ module Origen
12
+ module Users
13
+ def users
14
+ @users ||= [
15
+ ]
16
+ end
17
+ end
18
+ end
data/config/version.rb ADDED
@@ -0,0 +1,8 @@
1
+ module OrigenMemoryImage
2
+ MAJOR = 0
3
+ MINOR = 5
4
+ BUGFIX = 0
5
+ DEV = nil
6
+
7
+ VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
8
+ end
@@ -0,0 +1,71 @@
1
+ module OrigenMemoryImage
2
+ class Base
3
+ attr_reader :file, :source
4
+
5
+ def initialize(file, options = {})
6
+ if options[:source] == String
7
+ @source = file
8
+ else
9
+ @file = file
10
+ end
11
+ end
12
+
13
+ # Returns the code execution start address as an int
14
+ def start_address
15
+ fail "#{self.class} has not implemented the start_address method!"
16
+ end
17
+
18
+ # Returns the s-record as an array of addresses and data
19
+ #
20
+ # @param [hash] options, allows the selection of endianness swapping - ie the output will have the endianness changed
21
+ #
22
+ # The output is a 2D array, with each element being an array with element zero being the
23
+ # address of the data and element one being one word of data
24
+ # like this [[ADDR0, DATA0], [ADDR1, DATA1], [ADDR2, DATA2]...]
25
+ #
26
+ # The block header data and end of block value are not interpreted in any way and
27
+ # the checksum bits are disregarded
28
+ def to_a(options = {})
29
+ options = {
30
+ flip_endianness: false,
31
+ data_width_in_bytes: 4
32
+ }.merge(options)
33
+ data = extract_addr_data(options)
34
+ if options[:flip_endianness] || options[:endianness_change]
35
+ data.map do |v|
36
+ [v[0], flip_endianness(v[1], 4)]
37
+ end
38
+ else
39
+ data
40
+ end
41
+ end
42
+ alias_method :to_array, :to_a
43
+
44
+ # Reverse the endianness of the given data value, the width of it in bytes must
45
+ # be supplied as the second argument
46
+ #
47
+ # @example
48
+ # flip_endianness(0x12345678, 4) # => 0x78563412
49
+ def flip_endianness(data, width_in_bytes)
50
+ v = 0
51
+ width_in_bytes.times do |i|
52
+ # data[7:0] => data[15:8]
53
+ start = 8 * i
54
+ v += data[(start + 7)..start] << ((width_in_bytes - i - 1) * 8)
55
+ end
56
+ v
57
+ end
58
+
59
+ def file_name
60
+ file || 'From source string'
61
+ end
62
+
63
+ def lines
64
+ if file
65
+ File.readlines(file)
66
+ else
67
+ source.split("\n")
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,56 @@
1
+ module OrigenMemoryImage
2
+ class Hex < Base
3
+ def self.match?(snippet)
4
+ snippet.any? do |line|
5
+ # Match a line like:
6
+ # @180000F0
7
+ line =~ /^@[0-9a-fA-F]+\s?$/
8
+ end
9
+ end
10
+
11
+ # The first in the file will be taken as the start address
12
+ def start_address
13
+ @start_address ||= begin
14
+ lines.each do |line|
15
+ if line =~ /^@([0-9a-fA-F]+)\s?$/
16
+ return Regexp.last_match[1].to_i(16)
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ # Returns an array containing all address/data from the given s-record
25
+ # No address manipulation is performed, that is left to the caller to apply
26
+ # any scrambling as required by the target system
27
+ def extract_addr_data(options = {})
28
+ options = {
29
+ data_width_in_bytes: 4
30
+ }.merge(options)
31
+
32
+ result = []
33
+ lines.each do |line|
34
+ # Only if the line is an s-record with data...
35
+ if line =~ /^@([0-9a-fA-F]+)\s?$/
36
+ @address = Regexp.last_match[1].to_i(16)
37
+ elsif line =~ /^[0-9A-F]/
38
+ unless @address
39
+ fail "Hex data found before an @address line in #{file_name}"
40
+ end
41
+ data = line.strip.gsub(/\s/, '')
42
+ data_matcher = '\w\w' * options[:data_width_in_bytes]
43
+ data.scan(/#{data_matcher}/).each do |data_packet|
44
+ result << [@address, data_packet.to_i(16)]
45
+ @address += options[:data_width_in_bytes]
46
+ end
47
+ # If a partial word is left over
48
+ if (remainder = data.length % (2 * options[:data_width_in_bytes])) > 0
49
+ result << [@address, data[data.length - remainder..data.length].to_i(16)]
50
+ end
51
+ end
52
+ end
53
+ result
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,212 @@
1
+ module OrigenMemoryImage
2
+ # An S-record file consists of a sequence of specially formatted ASCII character strings. An S-record will
3
+ # be less than or equal to 78 bytes in length.
4
+ # The order of S-records within a file is of no significance and no particular order may be assumed.
5
+ #
6
+ # The general format of an S-record follows:
7
+ #
8
+ # +-------------------//------------------//-----------------------+
9
+ # | type | count | address | data | checksum |
10
+ # +-------------------//------------------//-----------------------+
11
+ #
12
+ # type
13
+ # : A char[2] field. These characters describe the type of record (S0, S1, S2, S3, S5, S7, S8, or S9).
14
+ #
15
+ # count
16
+ # : A char[2] field. These characters when paired and interpreted as a hexadecimal value, display
17
+ # the count of remaining character pairs in the record.
18
+ #
19
+ # address
20
+ # : A char[4,6, or 8] field. These characters grouped and interpreted as a hexadecimal value,
21
+ # display the address at which the data field is to be loaded into memory. The length of the field depends
22
+ # on the number of bytes necessary to hold the address. A 2-byte address uses 4 characters, a 3-byte
23
+ # address uses 6 characters, and a 4-byte address uses 8 characters.
24
+ #
25
+ # data
26
+ # : A char [0-64] field. These characters when paired and interpreted as hexadecimal values represent
27
+ # the memory loadable data or descriptive information.
28
+ #
29
+ # checksum
30
+ # : A char[2] field. These characters when paired and interpreted as a hexadecimal value display
31
+ # the least significant byte of the ones complement of the sum of the byte values represented by the pairs
32
+ # of characters making up the count, the address, and the data fields.
33
+ #
34
+ # Each record is terminated with a line feed. If any additional or different record terminator(s) or delay
35
+ # characters are needed during transmission to the target system it is the responsibility of the
36
+ # transmitting program to provide them.
37
+ #
38
+ # #### S0 Record
39
+ #
40
+ # The type of record is 'S0' (0x5330). The address field is unused and will be filled with zeros
41
+ # (0x0000). The header information within the data field is divided into the following subfields.
42
+ #
43
+ # * mname is char[20] and is the module name.
44
+ # * ver is char[2] and is the version number.
45
+ # * rev is char[2] and is the revision number.
46
+ # * description is char[0-36] and is a text comment.
47
+ #
48
+ # Each of the subfields is composed of ASCII bytes whose associated characters, when paired, represent one
49
+ # byte hexadecimal values in the case of the version and revision numbers, or represent the hexadecimal
50
+ # values of the ASCII characters comprising the module name and description.
51
+ #
52
+ # #### S1 Record
53
+ #
54
+ # The type of record field is 'S1' (0x5331). The address field is intrepreted as a 2-byte
55
+ # address. The data field is composed of memory loadable data.
56
+ #
57
+ # #### S2 Record
58
+ #
59
+ # The type of record field is 'S2' (0x5332). The address field is intrepreted as a 3-byte
60
+ # address. The data field is composed of memory loadable data.
61
+ #
62
+ # #### S3 Record
63
+ #
64
+ # The type of record field is 'S3' (0x5333). The address field is intrepreted as a 4-byte
65
+ # address. The data field is composed of memory loadable data.
66
+ #
67
+ # #### S5 Record
68
+ #
69
+ # The type of record field is 'S5' (0x5335). The address field is intrepreted as a 2-byte value
70
+ # and contains the count of S1, S2, and S3 records previously transmitted. There is no data field.
71
+ #
72
+ # #### S7 Record
73
+ #
74
+ # The type of record field is 'S7' (0x5337). The address field contains the starting execution
75
+ # address and is intrepreted as 4-byte address. There is no data field.
76
+ #
77
+ # #### S8 Record
78
+ #
79
+ # The type of record field is 'S8' (0x5338). The address field contains the starting execution
80
+ # address and is intrepreted as 3-byte address. There is no data field.
81
+ #
82
+ # #### S9 Record
83
+ #
84
+ # The type of record field is 'S9' (0x5339). The address field contains the starting execution
85
+ # address and is intrepreted as 2-byte address. There is no data field.
86
+ #
87
+ # ### Example
88
+ #
89
+ # Shown below is a typical S-record format file.
90
+ #
91
+ # S00600004844521B
92
+ # S1130000285F245F2212226A000424290008237C2A
93
+ # S11300100002000800082629001853812341001813
94
+ # S113002041E900084E42234300182342000824A952
95
+ # S107003000144ED492
96
+ # S5030004F8
97
+ # S9030000FC
98
+ #
99
+ # The file consists of one S0 record, four S1 records, one S5 record and an S9 record.
100
+ #
101
+ # The S0 record is comprised as follows:
102
+ #
103
+ # * S0 S-record type S0, indicating it is a header record.
104
+ # * 06 Hexadecimal 06 (decimal 6), indicating that six character pairs (or ASCII bytes) follow.
105
+ # * 00 00 Four character 2-byte address field, zeroes in this example.
106
+ # * 48 44 52 ASCII H, D, and R - "HDR".
107
+ # * 1B The checksum.
108
+ #
109
+ # The first S1 record is comprised as follows:
110
+ #
111
+ # * S1 S-record type S1, indicating it is a data record to be loaded at a 2-byte address.
112
+ # * 13 Hexadecimal 13 (decimal 19), indicating that nineteen character pairs, representing a 2 byte address,
113
+ # * 16 bytes of binary data, and a 1 byte checksum, follow.
114
+ # * 00 00 Four character 2-byte address field; hexidecimal address 0x0000, where the data which follows is to
115
+ # be loaded.
116
+ # * 28 5F 24 5F 22 12 22 6A 00 04 24 29 00 08 23 7C Sixteen character pairs representing the actual binary
117
+ # data.
118
+ # * 2A The checksum.
119
+ # * The second and third S1 records each contain 0x13 (19) character pairs and are ended with checksums of 13
120
+ # and 52, respectively. The fourth S1 record contains 07 character pairs and has a checksum of 92.
121
+ #
122
+ # The S5 record is comprised as follows:
123
+ #
124
+ # * S5 S-record type S5, indicating it is a count record indicating the number of S1 records
125
+ # * 03 Hexadecimal 03 (decimal 3), indicating that three character pairs follow.
126
+ # * 00 04 Hexadecimal 0004 (decimal 4), indicating that there are four data records previous to this record.
127
+ # * F8 The checksum.
128
+ #
129
+ # The S9 record is comprised as follows:
130
+ #
131
+ # * S9 S-record type S9, indicating it is a termination record.
132
+ # * 03 Hexadecimal 03 (decimal 3), indicating that three character pairs follow.
133
+ # * 00 00 The address field, hexadecimal 0 (decimal 0) indicating the starting execution address.
134
+ # * FC The checksum.
135
+ #
136
+ # ### Additional Notes
137
+ #
138
+ # There isn't any evidence that Motorola ever has made use of the header information within the data field
139
+ # of the S0 record, as described above. This must have been used by some third party vendors.
140
+ # This is the only place that a 78-byte limit on total record length or 64-byte limit on data length is
141
+ # documented. These values shouldn't be trusted for the general case.
142
+ #
143
+ # The count field can have values in the range of 0x3 (2 bytes of address + 1 byte checksum = 3, a not
144
+ # very useful record) to 0xff; this is the count of remaining character pairs, including checksum.
145
+ # If you write code to convert S-Records, you should always assume that a record can be as long as 514
146
+ # (decimal) characters in length (255 * 2 = 510, plus 4 characters for the type and count fields), plus
147
+ # any terminating character(s).
148
+ #
149
+ # That is, in establishing an input buffer in C, you would declare it to be
150
+ # an array of 515 chars, thus leaving room for the terminating null character.
151
+ class SRecord < Base
152
+ def self.match?(snippet)
153
+ snippet.all? do |line|
154
+ line.empty? || line =~ /^S[01235789]/
155
+ end
156
+ end
157
+
158
+ def start_address
159
+ @start_address ||= begin
160
+ lines.each do |line|
161
+ if line =~ /^S([789])(.*)/
162
+ type = Regexp.last_match[1]
163
+ case type
164
+ when '7'
165
+ return line.slice(4, 8).to_i(16)
166
+ when '8'
167
+ return line.slice(4, 6).to_i(16)
168
+ when '9'
169
+ return line.slice(4, 4).to_i(16)
170
+ end
171
+ end
172
+ end
173
+ end
174
+ end
175
+
176
+ private
177
+
178
+ # Returns an array containing all address/data from the given s-record
179
+ # No address manipulation is performed, that is left to the caller to apply
180
+ # any scrambling as required by the target system
181
+ def extract_addr_data(options = {})
182
+ options = {
183
+ data_width_in_bytes: 4
184
+ }.merge(options)
185
+
186
+ result = []
187
+ lines.each do |line|
188
+ # Only if the line is an s-record with data...
189
+ if line =~ /^S([1-3])/
190
+ type = Regexp.last_match[1].to_i(16) # S-record type, 1-3
191
+ # Set the matcher to capture x number of bytes dependent on the s-rec type
192
+ addr_matcher = '\w\w' * (1 + type)
193
+ line.strip =~ /^S\d\w\w(#{addr_matcher})(\w*)\w\w$/ # $1 = address, $2 = data
194
+ addr = Regexp.last_match[1].to_i(16)
195
+ @start_address ||= addr
196
+ @start_address = addr if addr < @start_address
197
+ data = Regexp.last_match[2]
198
+ data_matcher = '\w\w' * options[:data_width_in_bytes]
199
+ data.scan(/#{data_matcher}/).each do |data_packet|
200
+ result << [addr, data_packet.to_i(16)]
201
+ addr += options[:data_width_in_bytes]
202
+ end
203
+ # If a partial word is left over
204
+ if (remainder = data.length % (2 * options[:data_width_in_bytes])) > 0
205
+ result << [addr, data[data.length - remainder..data.length].to_i(16)]
206
+ end
207
+ end
208
+ end
209
+ result
210
+ end
211
+ end
212
+ end
@@ -0,0 +1,30 @@
1
+ require 'origen'
2
+ require_relative '../config/application.rb'
3
+ require_relative '../config/environment.rb'
4
+
5
+ module OrigenMemoryImage
6
+ def self.new(file, options = {})
7
+ unless options[:source] == String
8
+ file = Origen.file_handler.clean_path_to(file)
9
+ end
10
+ find_type(file, options).new(file, options)
11
+ end
12
+
13
+ # Returns the class of the image manager for the given file
14
+ def self.find_type(file, options = {})
15
+ # Read first 10 lines
16
+ if options[:source] == String
17
+ snippet = file.split("\n")
18
+ else
19
+ snippet = File.foreach(file.to_s).first(1)
20
+ end
21
+ case
22
+ when options[:type] == :srecord || SRecord.match?(snippet)
23
+ SRecord
24
+ when options[:type] == :hex || Hex.match?(snippet)
25
+ Hex
26
+ else
27
+ fail "Unknown format for image file: #{file}"
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,147 @@
1
+ % render "layouts/basic.html" do
2
+
3
+ %# HTML tags can be embedded in mark down files if you want to do specific custom
4
+ %# formatting like this, but in most cases that is not required.
5
+ <h1><%= Origen.config.name %> <span style="font-size: 14px">(<%= Origen.app.version %>)</span></h1>
6
+
7
+ ### Purpose
8
+
9
+ This plugin provides a common API for easily reading memory image files in any format
10
+ so that their contained data can then be used in Origen:
11
+
12
+ ~~~ruby
13
+ # Read in an s-record
14
+ srec = OrigenMemoryImage.new("srecs/test_atd.abs.S19")
15
+
16
+ # Write it to the DUT, or otherwise work with it, however you like
17
+ srec.to_a.each do |addr, data|
18
+ $dut.write_memory data, address: addr
19
+ end
20
+ ~~~
21
+
22
+ ### How To Import
23
+
24
+ ##### To use in an application:
25
+
26
+ Add the following to your application's <code>Gemfile</code>:
27
+
28
+ ~~~ruby
29
+ gem 'origen_memory_image', '<%= Origen.app.version %>'
30
+ ~~~
31
+
32
+ ##### To use in a plugin:
33
+
34
+ Add the following to your plugin's gemspec:
35
+
36
+ ~~~ruby
37
+ spec.add_runtime_dependency 'origen_memory_image', '~> <%= Origen.app.version.major %>', '>= <%= Origen.app.version %>'
38
+ ~~~
39
+
40
+ and require the gem in your code:
41
+
42
+ ~~~ruby
43
+ require 'origen_memory_image'
44
+ ~~~
45
+
46
+
47
+ ### How To Use
48
+
49
+ Create a memory map object that points to a specific source file, note that
50
+ you do not need to supply the format.
51
+ Also note that the format is detected by looking at the file content and the naming
52
+ and extension of the file has no relevance (so it can be called anything).
53
+
54
+ The path to the file can be absolute or relative to <code>Origen.root</code>:
55
+
56
+ ~~~ruby
57
+ my_srec = OrigenMemoryImage.new("source_files/test_atd.abs.S19")
58
+ my_hex = OrigenMemoryImage.new("source_files/math.hex")
59
+ ~~~
60
+
61
+ Memory images can also be created directly from a string:
62
+
63
+ ~~~ruby
64
+ str = <<-END
65
+ @2D100E00
66
+ 0D 15 0F 13 0E 14 10 12
67
+ 00 00 04 17 04 03 05 06
68
+ END
69
+
70
+ my_hex = OrigenMemoryImage.new(str, source: String)
71
+ ~~~
72
+
73
+ Every memory image object then supports a common API.
74
+
75
+ The <code>start_address</code> method returns the start (execution start) address:
76
+
77
+ ~~~ruby
78
+ my_srec.start_address # => 0x3000_F000
79
+ ~~~
80
+
81
+ The <code>to_a</code> method returns the file content as an array of address/data pairs,
82
+ this method supports options to set the data width and to flip the data endianness:
83
+
84
+ ~~~ruby
85
+ my_srec.to_a # => [[0x3000_F000, 0x11223344], [0x3000_F004, 0x55667788], ...]
86
+
87
+ my_srec.to_a(flip_endianness: true) # => [[0x3000_F000, 0x44332211], [0x3000_F004, 0x88776655], ...]
88
+
89
+ my_srec.to_a(data_width_in_bytes: 2) # => [[0x3000_F000, 0x1122], [0x3000_F002, 0x3344], [0x3000_F004, 0x5566], ...]
90
+ ~~~
91
+
92
+ Such an array can be iterated on like this to separate the address and data:
93
+
94
+ ~~~ruby
95
+ my_srec.to_a.each do |address, data|
96
+ # Process as required
97
+ end
98
+ ~~~
99
+
100
+ ### Currently Supported Formats
101
+
102
+ #### S-Records
103
+
104
+ Any valid S-record:
105
+
106
+ ~~~text
107
+ S017000068656C6C6F5F776F726C645F6576622E73726563D6
108
+ S3153F00002018F09FE518F09FE518F09FE518F09FE55B
109
+ S3153F00003018F09FE500F020E314F09FE514F09FE5EC
110
+ S3113F000270F406003F102100407800003FDC
111
+ S3153F0005B05FF0FF301B4908605FF0FF301A49086063
112
+ S3093F0006F0704700000A
113
+ S7053F000410A7
114
+ ~~~
115
+
116
+ #### Hex Files
117
+
118
+ The data lines can be grouped into any size:
119
+
120
+ ~~~text
121
+ @18000000
122
+ 1E E0 02 1C 22 40 1B E0 02 1C 22 43 18 E0 02 1C
123
+ 5A 78 0A 43 03 E0 03 4B F7 21 5A 78 0A 40 00 20
124
+ 22 E0 84 42 22 D3 1F E0 84 42 1F D9 1C E0 84 42
125
+ @180000E0
126
+ 002B20D1 03E0012A 01D1002B 1BD00223
127
+ 2340022A 02D1002B 15D103E0 032A01D1
128
+ @180001F0
129
+ 780000187C0000188200001888000018
130
+ ~~~
131
+
132
+ ### How To Setup a Development Environment
133
+
134
+ [Clone the repository from Github](https://github.com/Origen-SDK/origen_memory_image).
135
+
136
+ Follow the instructions here if you want to make a 3rd party app
137
+ workspace use your development copy of the <%= Origen.app.config.initials %> plugin:
138
+ [Setting up a Plugin Development Environment](http://origen-sdk.org/origen/latest/guides/plugins)
139
+
140
+ This plugin also contains a test suite, makes sure this passes before committing
141
+ any changes!
142
+
143
+ ~~~text
144
+ origen specs
145
+ ~~~
146
+
147
+ % end
@@ -0,0 +1,16 @@
1
+ ---
2
+ title: <%= options[:title] || Origen.config.name %>
3
+ analytics: UA-64455560-1
4
+ ---
5
+ <%= render "templates/web/partials/navbar.html", tab: options[:tab] %>
6
+
7
+ <div class="row">
8
+ %# The markdown attribute is important if you are going to include content written
9
+ %# in markdown, without this is will be included verbatim
10
+ <div class="span12" markdown="1">
11
+ <%= yield %>
12
+
13
+ <%= disqus_comments %>
14
+
15
+ </div>
16
+ </div>
@@ -0,0 +1,22 @@
1
+ <nav class="navbar navbar-inverse navbar-fixed-top">
2
+ <div class="container">
3
+ <div class="navbar-header">
4
+ <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
5
+ <span class="sr-only">Toggle navigation</span>
6
+ <span class="icon-bar"></span>
7
+ <span class="icon-bar"></span>
8
+ <span class="icon-bar"></span>
9
+ </button>
10
+ <a class="navbar-brand" href="<%= path "/" %>">Home</a>
11
+ </div>
12
+ <div id="navbar" class="collapse navbar-collapse">
13
+ <ul class="nav navbar-nav">
14
+ <li class="<%= options[:tab] == :api ? 'active' : '' %>"><a href="<%= path "/api/" %>">API</a></li>
15
+ <li class="<%= options[:tab] == :coverage ? 'active' : '' %>"><a href="<%= path "/coverage" %>">Coverage</a></li>
16
+ <li class="<%= options[:tab] == :release ? 'active' : '' %>"><a href="<%= path "/release_notes" %>">Release Notes</a></li>
17
+ <li><a href="https://github.com/Origen-SDK/origen_memory_image">Github</a></li>
18
+ </ul>
19
+ <%= import "origen/web/logo.html" %>
20
+ </div><!--/.nav-collapse -->
21
+ </div>
22
+ </nav>
@@ -0,0 +1,5 @@
1
+ % render "layouts/basic.html", tab: :release do
2
+
3
+ <%= render "#{Origen.root}/doc/history" %>
4
+
5
+ % end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: origen_memory_image
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ platform: ruby
6
+ authors:
7
+ - Stephen McGinty
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-08-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: origen
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.2.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.2.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: origen_doc_helpers
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.2.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 0.2.0
41
+ description:
42
+ email:
43
+ - stephen.f.mcginty@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - config/application.rb
49
+ - config/commands.rb
50
+ - config/development.rb
51
+ - config/environment.rb
52
+ - config/users.rb
53
+ - config/version.rb
54
+ - lib/origen_memory_image.rb
55
+ - lib/origen_memory_image/base.rb
56
+ - lib/origen_memory_image/hex.rb
57
+ - lib/origen_memory_image/s_record.rb
58
+ - templates/web/index.md.erb
59
+ - templates/web/layouts/_basic.html.erb
60
+ - templates/web/partials/_navbar.html.erb
61
+ - templates/web/release_notes.md.erb
62
+ homepage: http://origen-sdk.org/memory_image
63
+ licenses: []
64
+ metadata: {}
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: 1.9.3
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: 1.8.11
79
+ requirements: []
80
+ rubyforge_project:
81
+ rubygems_version: 2.2.2
82
+ signing_key:
83
+ specification_version: 4
84
+ summary: Provides a standard API for consuming memory image files in any format e.g.
85
+ s-record, hex
86
+ test_files: []
87
+ has_rdoc: