cross_origen 0.6.1 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/fix_my_workspace +92 -0
- data/config/application.rb +7 -0
- data/config/environment.rb +1 -0
- data/config/shared_commands.rb +18 -0
- data/config/version.rb +2 -2
- data/lib/cross_origen/cmsis_svd.rb +143 -0
- data/lib/cross_origen/commands/import.rb +32 -0
- data/lib/cross_origen/origen_format.rb +17 -4
- data/lib/cross_origen.rb +3 -2
- data/templates/web/examples/origen_export.md.erb +151 -96
- metadata +9 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7a8a97d56c4be0c17d49a9486ec425b34eab92fc
|
4
|
+
data.tar.gz: 19f08b7708edb0fd9b1b1da7bd2b7a0e59b98766
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: de17ae91904278a13727d3ae7d2e1d3f48e1e45a29177e31155a6281a0d3623b17eaf33e7aabb9d13f553f337a37a205d9c00a02c4c12e2bae378f26a0ce9025
|
7
|
+
data.tar.gz: e20b7196527a69f0bedacbe778843beb1dde1da11495405d820cb9a89d106c3f787f3e1e61d184106dc05e9bfbc54ee1aa293269a6a62a87d45307b359a30515
|
@@ -0,0 +1,92 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$VERBOSE = nil # Don't care about world writable dir warnings and the like
|
3
|
+
|
4
|
+
if $_fix_my_workspace_version_check
|
5
|
+
$_fix_my_workspace_version = '0.6.0'
|
6
|
+
else
|
7
|
+
require 'origen'
|
8
|
+
|
9
|
+
if !Origen.site_config.gem_manage_bundler
|
10
|
+
puts 'Sorry but you have opted to manage Bundler yourself via your Origen site config, and this means'
|
11
|
+
puts 'that I cannot make certain assumptions about how your workspace is configured.'
|
12
|
+
puts 'You will need to either resolve this problem yourself, or else change the value of'
|
13
|
+
puts 'gem_mange_bundler to true.'
|
14
|
+
puts 'See here for more details on how to do that: http://origen-sdk.org/origen/guides/starting/company/'
|
15
|
+
|
16
|
+
else
|
17
|
+
ENV['BUNDLE_GEMFILE'] = File.join(Origen.root, 'Gemfile')
|
18
|
+
ENV['BUNDLE_PATH'] = File.expand_path(Origen.site_config.gem_install_dir)
|
19
|
+
ENV['BUNDLE_BIN'] = File.join(Origen.root, 'lbin')
|
20
|
+
|
21
|
+
# Force copy system gems to local gems
|
22
|
+
if Origen.site_config.gem_use_from_system
|
23
|
+
local_gem_dir = "#{ENV['BUNDLE_PATH']}/ruby/#{Pathname.new(Gem.dir).basename}"
|
24
|
+
gem_dir = Pathname.new(Gem.dir)
|
25
|
+
|
26
|
+
Origen.site_config.gem_use_from_system.each do |gem, version|
|
27
|
+
begin
|
28
|
+
# This will raise an error if the system doesn't have this gem installed, that
|
29
|
+
# will be rescued below
|
30
|
+
spec = Gem::Specification.find_by_name(gem, version)
|
31
|
+
|
32
|
+
local_dir = File.join(local_gem_dir, Pathname.new(spec.gem_dir).relative_path_from(gem_dir))
|
33
|
+
FileUtils.mkdir_p local_dir
|
34
|
+
FileUtils.cp_r("#{spec.gem_dir}/.", local_dir)
|
35
|
+
|
36
|
+
local_file = Pathname.new(File.join(local_gem_dir, Pathname.new(spec.cache_file).relative_path_from(gem_dir)))
|
37
|
+
FileUtils.mkdir_p local_file.dirname
|
38
|
+
FileUtils.cp(spec.cache_file, local_file)
|
39
|
+
|
40
|
+
if spec.extension_dir && File.exist?(spec.extension_dir)
|
41
|
+
local_dir = File.join(local_gem_dir, Pathname.new(spec.extension_dir).relative_path_from(gem_dir))
|
42
|
+
FileUtils.mkdir_p local_dir
|
43
|
+
FileUtils.cp_r("#{spec.extension_dir}/.", local_dir)
|
44
|
+
end
|
45
|
+
|
46
|
+
local_file = Pathname.new(File.join(local_gem_dir, Pathname.new(spec.spec_file).relative_path_from(gem_dir)))
|
47
|
+
FileUtils.mkdir_p local_file.dirname
|
48
|
+
FileUtils.cp(spec.spec_file, local_file)
|
49
|
+
|
50
|
+
rescue Gem::LoadError
|
51
|
+
# This just means that one of the gems that should be copied from the system
|
52
|
+
# was not actually installed in the system, so nothing we can do about that here
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Delete lbin
|
58
|
+
FileUtils.rm_rf(ENV['BUNDLE_BIN']) if File.exist?(ENV['BUNDLE_BIN'])
|
59
|
+
|
60
|
+
# Run bundler with correct switches
|
61
|
+
cmd = "bundle install --gemfile #{ENV['BUNDLE_GEMFILE']} --binstubs #{ENV['BUNDLE_BIN']} --path #{ENV['BUNDLE_PATH']}"
|
62
|
+
`chmod o-w #{Origen.root}` # Stops some annoying world writable warnings during install
|
63
|
+
`chmod o-w #{Origen.root}/bin` if File.exist?("#{Origen.root}/bin")
|
64
|
+
`chmod o-w #{Origen.root}/.bin` if File.exist?("#{Origen.root}/.bin")
|
65
|
+
|
66
|
+
# Try again, this time updating the bundle
|
67
|
+
if system(cmd)
|
68
|
+
fixed = true
|
69
|
+
elsif system 'bundle update'
|
70
|
+
fixed = true
|
71
|
+
end
|
72
|
+
|
73
|
+
if File.exist?(ENV['BUNDLE_BIN'])
|
74
|
+
`chmod o-w #{ENV['BUNDLE_BIN']}`
|
75
|
+
|
76
|
+
# Make .bat versions of all executables, Bundler should really be doing this when running
|
77
|
+
# on windows
|
78
|
+
if Origen.os.windows?
|
79
|
+
Dir.glob("#{ENV['BUNDLE_BIN']}/*").each do |bin|
|
80
|
+
unless bin =~ /.bat$/
|
81
|
+
bat = "#{bin}.bat"
|
82
|
+
unless File.exist?(bat)
|
83
|
+
File.open(bat, 'w') { |f| f.write('@"ruby.exe" "%~dpn0" %*') }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
system 'origen -v' if fixed
|
91
|
+
end
|
92
|
+
end
|
data/config/application.rb
CHANGED
@@ -14,6 +14,13 @@ class CrossOrigenApplication < Origen::Application
|
|
14
14
|
#:files => ["lib", "config/application.rb"],
|
15
15
|
}
|
16
16
|
|
17
|
+
config.shared = {
|
18
|
+
# :patterns => "pattern/shared",
|
19
|
+
# :templates => "templates",
|
20
|
+
# :programs => "program",
|
21
|
+
:command_launcher => "config/shared_commands.rb"
|
22
|
+
}
|
23
|
+
|
17
24
|
# Prevent these from showing up in 'origen rc unman'
|
18
25
|
config.unmanaged_dirs = %w()
|
19
26
|
config.unmanaged_files = %w()
|
data/config/environment.rb
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
# The requested command is passed in here as @command
|
2
|
+
case @command
|
3
|
+
|
4
|
+
when "cr:import"
|
5
|
+
require "cross_origen/commands/import"
|
6
|
+
# Important to exit when a command has been fulfilled or else Origen core will try and execute it
|
7
|
+
exit 0
|
8
|
+
|
9
|
+
# Always leave an else clause to allow control to fall back through to the Origen command handler.
|
10
|
+
# You probably want to also add the command details to the help shown via 'origen -h',
|
11
|
+
# you can do this bb adding the required text to @plugin_commands before handing control back to
|
12
|
+
# Origen.
|
13
|
+
else
|
14
|
+
@plugin_commands << <<-EOT
|
15
|
+
cr:import Import peripheral and register data from 3rd party formats
|
16
|
+
EOT
|
17
|
+
|
18
|
+
end
|
data/config/version.rb
CHANGED
@@ -0,0 +1,143 @@
|
|
1
|
+
module CrossOrigen
|
2
|
+
class CMSISSVD < XMLDoc
|
3
|
+
def import(file, options = {}) # rubocop:disable CyclomaticComplexity
|
4
|
+
with_output_file(options) do |f|
|
5
|
+
doc(file, options) do |doc|
|
6
|
+
f.puts '# This file was automatically generated from a CMSIS-SVD input file'
|
7
|
+
f.puts '# Name: ' + (fetch(doc.xpath('device/name'), get_text: true) || '')
|
8
|
+
f.puts '# Version: ' + (fetch(doc.xpath('device/version'), get_text: true) || '')
|
9
|
+
f.puts "# Created at #{Time.now.strftime('%e %b %Y %H:%M%p')} by #{User.current.name}"
|
10
|
+
f.puts '# rubocop:disable all'
|
11
|
+
f.puts 'module ImportedCMSISSVD'
|
12
|
+
f.puts ' def initialize(*args)'
|
13
|
+
f.puts ' instantiate_imported_cmsis_svd_data'
|
14
|
+
f.puts ' end'
|
15
|
+
f.puts ''
|
16
|
+
f.puts ' def instantiate_imported_cmsis_svd_data'
|
17
|
+
|
18
|
+
# Create sub-blocks
|
19
|
+
indexes = {}
|
20
|
+
doc.xpath('device/peripherals/peripheral').each do |p|
|
21
|
+
name = fetch(p.xpath('groupName'), get_text: true)
|
22
|
+
name = name.to_s.downcase.symbolize
|
23
|
+
ba = extract(p, 'baseAddress', format: :integer, hex: true)
|
24
|
+
if j = peripheral_groups(doc)[name] > 1
|
25
|
+
indexes[name] ||= 0
|
26
|
+
f.puts " sub_block :#{name}#{indexes[name]}, base_address: #{ba.to_hex}"
|
27
|
+
indexes[name] += 1
|
28
|
+
else
|
29
|
+
f.puts " sub_block :#{name}, base_address: #{ba.to_hex}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
f.puts ''
|
33
|
+
|
34
|
+
# Add registers to each sub-block
|
35
|
+
indexes = {}
|
36
|
+
doc.xpath('device/peripherals/peripheral').each do |p|
|
37
|
+
sb = fetch(p.xpath('groupName'), get_text: true)
|
38
|
+
sb = sb.to_s.downcase.symbolize
|
39
|
+
if j = peripheral_groups(doc)[sb] > 1
|
40
|
+
indexes[sb] ||= 0
|
41
|
+
ix = indexes[sb]
|
42
|
+
indexes[sb] += 1
|
43
|
+
sb = "#{sb}#{ix}"
|
44
|
+
end
|
45
|
+
|
46
|
+
p.xpath('registers/register').each do |r|
|
47
|
+
name = extract(r, 'name')
|
48
|
+
di = extract(r, 'dim', format: :integer)
|
49
|
+
dim = !!di
|
50
|
+
if dim
|
51
|
+
dinc = extract(r, 'dimIncrement', format: :integer)
|
52
|
+
dvals = extract(r, 'dimIndex').split(',')
|
53
|
+
else
|
54
|
+
di = 1
|
55
|
+
end
|
56
|
+
offset = extract(r, 'addressOffset', format: :integer, hex: true)
|
57
|
+
size = extract(r, 'size', format: :integer)
|
58
|
+
reset = extract(r, 'resetValue', format: :integer, hex: true)
|
59
|
+
desc = (extract(r, 'description') || '').gsub("'", %q(\\\'))
|
60
|
+
|
61
|
+
di.times do |i|
|
62
|
+
if dim
|
63
|
+
n = name.sub('[%s]', dvals[i])
|
64
|
+
addr = offset + (i * dinc)
|
65
|
+
else
|
66
|
+
n = name
|
67
|
+
addr = offset
|
68
|
+
end
|
69
|
+
f.puts " #{sb}.add_reg :#{n.downcase.symbolize}, #{addr.to_hex}, size: #{size}#{reset ? ', reset: ' + reset.to_hex : ''}, description: '#{desc}' do |reg|"
|
70
|
+
r.xpath('fields/field').each do |b|
|
71
|
+
bn = extract(b, 'name')
|
72
|
+
unless bn == 'RESERVED'
|
73
|
+
bn = bn.to_s.downcase.symbolize
|
74
|
+
lsb = extract(b, 'lsb', format: :integer)
|
75
|
+
msb = extract(b, 'msb', format: :integer)
|
76
|
+
access = extract(b, 'access')
|
77
|
+
desc = (extract(r, 'description') || '').gsub("'", %q(\\\'))
|
78
|
+
case access
|
79
|
+
when 'read-only'
|
80
|
+
ac = :ro
|
81
|
+
else
|
82
|
+
ac = :rw
|
83
|
+
end
|
84
|
+
if lsb == msb
|
85
|
+
f.puts " reg.bit #{lsb}, :#{bn}, access: :#{ac}, description: '#{desc}'"
|
86
|
+
else
|
87
|
+
f.puts " reg.bit #{msb}..#{lsb}, :#{bn}, access: :#{ac}, description: '#{desc}'"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
f.puts ' end'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
f.puts ' end'
|
97
|
+
|
98
|
+
# Create accessor methods to return an array of peripherals in the case
|
99
|
+
# where there are many in a group
|
100
|
+
peripheral_groups(doc).each do |name, size|
|
101
|
+
name = name.to_s.downcase.symbolize
|
102
|
+
if size > 1
|
103
|
+
f.puts ''
|
104
|
+
f.puts " def #{name}"
|
105
|
+
f.print ' ['
|
106
|
+
size.times do |i|
|
107
|
+
if i == 0
|
108
|
+
f.print "#{name}0"
|
109
|
+
else
|
110
|
+
f.print ", #{name}#{i}"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
f.puts ']'
|
114
|
+
f.puts ' end'
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
f.puts 'end'
|
119
|
+
f.puts '# rubocop:enable all'
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def peripheral_groups(doc)
|
125
|
+
@peripheral_groups ||= begin
|
126
|
+
g = {}
|
127
|
+
doc.xpath('device/peripherals/peripheral').each do |p|
|
128
|
+
group = fetch(p.xpath('groupName'), get_text: true)
|
129
|
+
group = group.to_s.downcase.symbolize
|
130
|
+
g[group] ||= 0
|
131
|
+
g[group] += 1
|
132
|
+
end
|
133
|
+
g
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def with_output_file(options = {})
|
138
|
+
path = options[:output] || 'imported_cmsis_svd.rb'
|
139
|
+
File.open(path, 'w') { |f| yield f }
|
140
|
+
puts "Successfully imported to #{path}"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
options = {}
|
2
|
+
opt_parser = OptionParser.new do |opts|
|
3
|
+
opts.banner = <<-END
|
4
|
+
Usage: origen cr:import FILE [options]
|
5
|
+
|
6
|
+
Import the given file into Origen format.
|
7
|
+
This will output a Ruby module that can then be included in an Origen model
|
8
|
+
to add the contained registers, sub-blocks, etc.
|
9
|
+
|
10
|
+
END
|
11
|
+
opts.on('-o', '--output PATH', String, 'Override the default output file') { |t| options[:output] = t }
|
12
|
+
end
|
13
|
+
opt_parser.parse! ARGV
|
14
|
+
|
15
|
+
file = ARGV[0]
|
16
|
+
unless file
|
17
|
+
puts 'You must supply a file to import!'
|
18
|
+
exit
|
19
|
+
end
|
20
|
+
|
21
|
+
unless File.exist?(file)
|
22
|
+
puts 'That file does not exist!'
|
23
|
+
exit
|
24
|
+
end
|
25
|
+
|
26
|
+
snippet = IO.read(file, 2000) # Read first 2000 characters
|
27
|
+
case snippet
|
28
|
+
when /CMSIS-SVD.xsd/
|
29
|
+
CrossOrigen::CMSISSVD.new(nil).import(file, options)
|
30
|
+
else
|
31
|
+
puts 'Unknown file format!'
|
32
|
+
end
|
@@ -21,15 +21,18 @@ module CrossOrigen
|
|
21
21
|
incl: "\# This file is created by Origen via CrossOrigen::OrigenFormat#export, and is read-only"
|
22
22
|
}
|
23
23
|
|
24
|
-
attr_reader :obj, :top_level_class, :top_level_hierarchy, :output_dir, :top_level_path, :incl_path, :incl_dir, :file_content
|
24
|
+
attr_reader :obj, :top_level_class, :top_level_hierarchy, :output_dir, :top_level_path, :incl_path, :incl_dir, :file_content, :inst_level
|
25
25
|
|
26
26
|
def initialize(options = {})
|
27
27
|
options = {
|
28
|
-
obj:
|
29
|
-
path:
|
28
|
+
obj: $dut,
|
29
|
+
path: "#{Origen.root!}/output",
|
30
|
+
instantiate_level: :top
|
30
31
|
}.update(options)
|
31
32
|
@obj = options[:obj]
|
32
33
|
@output_dir = options[:path]
|
34
|
+
@inst_level = options[:instantiate_level]
|
35
|
+
fail "@instantiate_level must be either set to ':top' or ':sub_block'" unless [:top, :sub_block].include?(@inst_level)
|
33
36
|
@top_level_path = "#{output_dir}/top_level.rb"
|
34
37
|
@incl_path = "#{output_dir}/sub_blocks.rb"
|
35
38
|
@incl_dir = "#{output_dir}/import"
|
@@ -72,12 +75,22 @@ module CrossOrigen
|
|
72
75
|
bom_file.puts(FILE_COMMENTS[:incl])
|
73
76
|
bom_file.puts("require_relative 'sub_blocks'")
|
74
77
|
@top_level_hierarchy.each do |name, obj|
|
78
|
+
if @inst_level == :sub_block && @top_level_hierarchy.keys.last == name
|
79
|
+
obj = 'module'
|
80
|
+
name = 'SubBlocks'
|
81
|
+
end
|
75
82
|
bom_file.puts("#{indent}#{obj} #{name.split('::').last}")
|
76
83
|
indent += ' '
|
77
84
|
end
|
78
85
|
bom_file.puts("#{indent}include Origen::Model")
|
79
86
|
bom_file.puts('')
|
80
|
-
|
87
|
+
if @inst_level == :sub_block
|
88
|
+
bom_file.puts("#{indent}def instantiate_sub_blocks(options = {})")
|
89
|
+
elsif @inst_level == :top
|
90
|
+
bom_file.puts("#{indent}def initialize(options = {})")
|
91
|
+
else
|
92
|
+
fail '@instantiate_level not set to an acceptable value [:top, :sub_block]'
|
93
|
+
end
|
81
94
|
indent += ' '
|
82
95
|
# This method is recursive (indirectly) so file_content should find all BoM and include file strings
|
83
96
|
create_file_content(@obj, indent)
|
data/lib/cross_origen.rb
CHANGED
@@ -64,8 +64,9 @@ module CrossOrigen
|
|
64
64
|
# The Ruby files are created at options[:path] (app output directory by default)
|
65
65
|
def cr_to_origen(options = {})
|
66
66
|
options = {
|
67
|
-
obj:
|
68
|
-
path:
|
67
|
+
obj: $dut,
|
68
|
+
path: Origen.app.config.output_directory,
|
69
|
+
instantiate_level: :top
|
69
70
|
}.update(options)
|
70
71
|
# This method assumes and checks for $self to contain Origen::Model
|
71
72
|
error "ERROR: #{options[:obj].class} does not contain Origen::Model as required" unless options[:obj].class < Origen::Model
|
@@ -1,96 +1,151 @@
|
|
1
|
-
% render "layouts/basic.html", tab: :examples do
|
2
|
-
|
3
|
-
## Origen Export
|
4
|
-
|
5
|
-
This page shows how to create static read-only Ruby files from
|
6
|
-
models created by importing 3rd party data (e.g. IP-XACT). The Ruby files can then be
|
7
|
-
used for day-day running of your application and this will significantly improve
|
8
|
-
the boot up speed vs. re-importing the data every time.
|
9
|
-
|
10
|
-
The Ruby files can be periodically refreshed as new versions of the master
|
11
|
-
data are released.
|
12
|
-
|
13
|
-
The user only need provide the output path where they want the
|
14
|
-
Ruby files to be written.
|
15
|
-
|
16
|
-
### Implementation
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
#
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
1
|
+
% render "layouts/basic.html", tab: :examples do
|
2
|
+
|
3
|
+
## Origen Export
|
4
|
+
|
5
|
+
This page shows how to create static read-only Ruby files from
|
6
|
+
models created by importing 3rd party data (e.g. IP-XACT). The Ruby files can then be
|
7
|
+
used for day-day running of your application and this will significantly improve
|
8
|
+
the boot up speed vs. re-importing the data every time.
|
9
|
+
|
10
|
+
The Ruby files can be periodically refreshed as new versions of the master
|
11
|
+
data are released.
|
12
|
+
|
13
|
+
The user only need provide the output path where they want the
|
14
|
+
Ruby files to be written.
|
15
|
+
|
16
|
+
### Implementation
|
17
|
+
|
18
|
+
There are two methods for instantiating device models:
|
19
|
+
|
20
|
+
1. As a named Origen TopLevel class with a method #instantiate_sub_blocks to model the device
|
21
|
+
2. As a generic SubBlocks module to model the device
|
22
|
+
|
23
|
+
Option #1 is the default behavior and is handled in this manner:
|
24
|
+
|
25
|
+
~~~ruby
|
26
|
+
$dut.to_origen(path: "#{Origen.root}/output/exported")
|
27
|
+
~~~
|
28
|
+
|
29
|
+
### Output
|
30
|
+
|
31
|
+
At the output path the following files are created:
|
32
|
+
|
33
|
+
* top_level.rb: The top-level object, this is the one that should be instantiated
|
34
|
+
|
35
|
+
~~~ruby
|
36
|
+
# This file is created by Origen, CrossOrigen::OrigenFormat#export, and is read-only
|
37
|
+
require_relative 'sub_blocks'
|
38
|
+
module CrossOrigen
|
39
|
+
module Test
|
40
|
+
class DUT
|
41
|
+
include Origen::Model
|
42
|
+
|
43
|
+
def initialize(options = {})
|
44
|
+
sub_block :atx, base_address: 0xDEADBEEF, class_name: 'ATX'
|
45
|
+
sub_block # ...
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
~~~
|
51
|
+
|
52
|
+
* sub_blocks.rb: include file for the sub_block class files
|
53
|
+
|
54
|
+
~~~ruby
|
55
|
+
# This file is created by Origen, CrossOrigen::OrigenFormat#export, and is read-only
|
56
|
+
require_relative 'import/atx.rb'
|
57
|
+
require_relative # ...
|
58
|
+
~~~
|
59
|
+
|
60
|
+
* import/\<sub_block\>.rb: models the individual sub_block object
|
61
|
+
|
62
|
+
~~~ruby
|
63
|
+
# -*- encoding : utf-8 -*-
|
64
|
+
# This file is created by Origen, CrossOrigen::OrigenFormat#export, and is read-only.
|
65
|
+
# If you need to make changes, re-open the class
|
66
|
+
module CrossOrigen
|
67
|
+
module Test
|
68
|
+
class DUT
|
69
|
+
class ATX # rubocop:disable ClassLength
|
70
|
+
include Origen::Model
|
71
|
+
|
72
|
+
def initialize(options = {})
|
73
|
+
instantiate_registers(options)
|
74
|
+
end
|
75
|
+
|
76
|
+
# rubocop:disable LineLength
|
77
|
+
# rubocop:disable StringLiterals
|
78
|
+
def instantiate_registers(options = {}) # rubocop:disable MethodLength
|
79
|
+
# ** MGATE Clock Divider Register **
|
80
|
+
# The MCLKDIV register is used to divide down the frequency of the HBOSCCLK input. If the MCLKDIV
|
81
|
+
# register is set to value "N", then the output (beat) frequency of the clock divider is OSCCLK / (N+1). The
|
82
|
+
# resulting beats are, in turn, counted by the PTIMER module to control the duration of Flash high-voltage
|
83
|
+
# operations.
|
84
|
+
reg :mclkdiv, 0x0, size: 16 do |reg|
|
85
|
+
# **Oscillator (Hi)** - Firmware FMU clk source selection. (Note that in addition to this firmware-controlled bit, the
|
86
|
+
# FMU clock source is also dependent on test and power control discretes).
|
87
|
+
#
|
88
|
+
# 0 | FMU clock is the externally supplied bus clock ipg_clk
|
89
|
+
# 1 | FMU clock is the internal oscillator from the TFS hardblock
|
90
|
+
reg.bit 15, :osch, reset: 0b1, access: :rw
|
91
|
+
# ...
|
92
|
+
end
|
93
|
+
# ...
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
~~~
|
100
|
+
|
101
|
+
Why option #2? Some Origen applications may serve multiple products and want the ability to swap the current
|
102
|
+
TopLevel model using target instantitation.
|
103
|
+
|
104
|
+
~~~ruby
|
105
|
+
origen i -t my_product
|
106
|
+
~~~
|
107
|
+
|
108
|
+
Here is a generic example of how an application may use option #2 in
|
109
|
+
combination with the CrossOrigen import feature. By passing the 'instantiate_level: :sub_block' to the #to_origen
|
110
|
+
method, the device model is changed to a SubBlocks module implementation. Notice that the #to_origen method is called
|
111
|
+
inside the #on_load_target callback. This is necessary as the #to_origen method accesses Origen.app.output_directory,
|
112
|
+
which is not available until the target is instantiated.
|
113
|
+
|
114
|
+
~~~ruby
|
115
|
+
|
116
|
+
module MyOrigenApp
|
117
|
+
class Product
|
118
|
+
include Origen::TopLevel
|
119
|
+
include CrossOrigen
|
120
|
+
|
121
|
+
attr_accessor :curr_prod, :curr_prod_xml, :top_origen_path
|
122
|
+
|
123
|
+
def initialize(options = {})
|
124
|
+
options = {
|
125
|
+
curr_product: nil
|
126
|
+
}.update(options)
|
127
|
+
@curr_prod = options [:curr_product]
|
128
|
+
@curr_prod_xml = Pathname.new("#{Origen.root}/vendor/mycompany/products/#{curr_prod}/product_ipxact.xml")
|
129
|
+
@top_origen_path = Pathname.new("#{Origen.root}/vendor/mycompany/products/#{curr_prod}/top_level.rb")
|
130
|
+
# Import or instantiate registers
|
131
|
+
if @top_origen_path.exist?
|
132
|
+
Origen.log.info("Instantiating registers from Origen source for product #{curr_prod}...")
|
133
|
+
require @top_origen_path.to_s.chomp(".rb")
|
134
|
+
extend SubBlocks
|
135
|
+
instantiate_sub_blocks()
|
136
|
+
else
|
137
|
+
Origen.log.info("Importing IP-XACT registers for #{curr_prod}...")
|
138
|
+
cr_import(path: @curr_prod_xml)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def on_load_target
|
143
|
+
to_origen(path: @top_origen_path, instantiate_level: :sub_block)
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
~~~
|
150
|
+
|
151
|
+
% end
|
metadata
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cross_origen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen McGinty
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-06-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: origen
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0.2'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0.2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
@@ -38,20 +38,6 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '3.0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: origen_doc_helpers
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: 0.2.0
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: 0.2.0
|
55
41
|
description:
|
56
42
|
email:
|
57
43
|
- stephen.f.mcginty@gmail.com
|
@@ -59,13 +45,17 @@ executables: []
|
|
59
45
|
extensions: []
|
60
46
|
extra_rdoc_files: []
|
61
47
|
files:
|
48
|
+
- bin/fix_my_workspace
|
62
49
|
- config/application.rb
|
63
50
|
- config/commands.rb
|
64
51
|
- config/development.rb
|
65
52
|
- config/environment.rb
|
53
|
+
- config/shared_commands.rb
|
66
54
|
- config/users.rb
|
67
55
|
- config/version.rb
|
68
56
|
- lib/cross_origen.rb
|
57
|
+
- lib/cross_origen/cmsis_svd.rb
|
58
|
+
- lib/cross_origen/commands/import.rb
|
69
59
|
- lib/cross_origen/design_sync.rb
|
70
60
|
- lib/cross_origen/headers.rb
|
71
61
|
- lib/cross_origen/ip_xact.rb
|
@@ -109,9 +99,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
109
99
|
version: 1.8.11
|
110
100
|
requirements: []
|
111
101
|
rubyforge_project:
|
112
|
-
rubygems_version: 2.6.
|
102
|
+
rubygems_version: 2.6.7
|
113
103
|
signing_key:
|
114
104
|
specification_version: 4
|
115
105
|
summary: Translators for importing and exporting Origen data to/from 3rd party formats
|
116
106
|
test_files: []
|
117
|
-
has_rdoc:
|