cross_origen 0.5.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.
- checksums.yaml +7 -0
- data/config/application.rb +78 -0
- data/config/commands.rb +47 -0
- data/config/development.rb +17 -0
- data/config/environment.rb +35 -0
- data/config/users.rb +18 -0
- data/config/version.rb +8 -0
- data/lib/cross_origen/design_sync.rb +54 -0
- data/lib/cross_origen/headers.rb +21 -0
- data/lib/cross_origen/ip_xact.rb +243 -0
- data/lib/cross_origen/origen_format.rb +541 -0
- data/lib/cross_origen/ralf.rb +15 -0
- data/lib/cross_origen/test/dut.rb +51 -0
- data/lib/cross_origen/xml_doc.rb +252 -0
- data/lib/cross_origen.rb +108 -0
- data/templates/headers/default.h.erb +18 -0
- data/templates/ralf/_register.ralf.erb +21 -0
- data/templates/ralf/default.ralf.erb +37 -0
- data/templates/test/default.ralf.erb +1 -0
- data/templates/test/headers_default.h.erb +1 -0
- data/templates/test/ip_xact.xml.erb +1 -0
- data/templates/web/_history.md +547 -0
- data/templates/web/example.md.erb +73 -0
- data/templates/web/examples/ip_xact_export.md.erb +25 -0
- data/templates/web/examples/origen_export.md.erb +96 -0
- data/templates/web/examples/ralf_export.md.erb +18 -0
- data/templates/web/examples.md.erb +13 -0
- data/templates/web/index.md.erb +104 -0
- data/templates/web/layouts/_basic.html.erb +13 -0
- data/templates/web/layouts/_doc.html.erb +61 -0
- data/templates/web/partials/_navbar.html.erb +23 -0
- data/templates/web/release_notes.md.erb +5 -0
- metadata +117 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 20fb4952ec7d0da9dcad3673c0442cbc1b79afc3
|
4
|
+
data.tar.gz: 8b55d120f0783322f057ba2db4fc638d063f1443
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 513b242817d94cd5b7f7614ca14087150e9e5cbcad31995e9eea344493d35bf525a6b9d52a268702b0d3ec73b44f31338d0d755e80b30fbcfec1d6a4183fe038
|
7
|
+
data.tar.gz: 9b767385a47a1f14319b4c22e4feb4c575f4aef07f615a70f376f12998623921642eff97e9b8dc9940b4248a7074b78923c81ebf76fc64dde058bc5c3cd1cc7e
|
@@ -0,0 +1,78 @@
|
|
1
|
+
class CrossOrigenApplication < Origen::Application
|
2
|
+
|
3
|
+
# See http://origen.freescale.net/origen/latest/api/Origen/Application/Configuration.html
|
4
|
+
# for a full list of the configuration options available
|
5
|
+
|
6
|
+
config.lint_test = {
|
7
|
+
# Require the lint tests to pass before allowing a release to proceed
|
8
|
+
:run_on_tag => true,
|
9
|
+
# Auto correct violations where possible whenever 'origen lint' is run
|
10
|
+
:auto_correct => true,
|
11
|
+
# Limit the testing for large legacy applications
|
12
|
+
#:level => :easy,
|
13
|
+
# Run on these directories/files by default
|
14
|
+
#:files => ["lib", "config/application.rb"],
|
15
|
+
}
|
16
|
+
|
17
|
+
# Prevent these from showing up in 'origen rc unman'
|
18
|
+
config.unmanaged_dirs = %w()
|
19
|
+
config.unmanaged_files = %w()
|
20
|
+
|
21
|
+
# This information is used in headers and email templates, set it specific
|
22
|
+
# to your application
|
23
|
+
config.name = "Cross Origen"
|
24
|
+
config.initials = "CrossOrigen"
|
25
|
+
config.rc_url = "git@github.com:Origen-SDK/cross_origen.git"
|
26
|
+
config.release_externally = true
|
27
|
+
|
28
|
+
config.web_directory = "git@github.com:Origen-SDK/Origen-SDK.github.io.git/cross_origen"
|
29
|
+
config.web_domain = "http://origen-sdk.org/cross_origen"
|
30
|
+
|
31
|
+
# When false Origen will be less strict about checking for some common coding errors,
|
32
|
+
# it is recommended that you leave this to true for better feedback and easier debug.
|
33
|
+
# This will be the default setting in Origen v3.
|
34
|
+
config.strict_errors = true
|
35
|
+
|
36
|
+
config.semantically_version = true
|
37
|
+
|
38
|
+
# By default all generated output will end up in ./output.
|
39
|
+
# Here you can specify an alternative directory entirely, or make it dynamic such that
|
40
|
+
# the output ends up in a setup specific directory.
|
41
|
+
#config.output_directory do
|
42
|
+
# "#{Origen.root}/output/#{$dut.class}"
|
43
|
+
#end
|
44
|
+
|
45
|
+
# Similary for the reference files, generally you want to setup the reference directory
|
46
|
+
# structure to mirror that of your output directory structure.
|
47
|
+
#config.reference_directory do
|
48
|
+
# "#{Origen.root}/.ref/#{$dut.class}"
|
49
|
+
#end
|
50
|
+
|
51
|
+
# Ensure that all tests pass before allowing a release to continue
|
52
|
+
def validate_release
|
53
|
+
if !system("origen test")
|
54
|
+
puts "Sorry but you can't release with failing tests, please fix them and try again."
|
55
|
+
exit 1
|
56
|
+
else
|
57
|
+
puts "All tests passing, proceeding with the release process!"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Run the tests before deploying to generate test coverage numbers
|
62
|
+
def before_deploy_site
|
63
|
+
Dir.chdir Origen.root do
|
64
|
+
system "origen test -c"
|
65
|
+
dir = "#{Origen.root}/web/output/coverage"
|
66
|
+
FileUtils.remove_dir(dir, true) if File.exists?(dir)
|
67
|
+
system "mv #{Origen.root}/coverage #{dir}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# This will automatically deploy your documentation after every tag
|
72
|
+
def after_release_email(tag, note, type, selector, options)
|
73
|
+
command = "origen web compile --remote --api"
|
74
|
+
Dir.chdir Origen.root do
|
75
|
+
system command
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/config/commands.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# This file should be used to extend origen with application specific tasks
|
2
|
+
|
3
|
+
aliases ={
|
4
|
+
|
5
|
+
}
|
6
|
+
|
7
|
+
@command = aliases[@command] || @command
|
8
|
+
|
9
|
+
case @command
|
10
|
+
|
11
|
+
when "specs"
|
12
|
+
require "rspec"
|
13
|
+
exit RSpec::Core::Runner.run(['spec'])
|
14
|
+
|
15
|
+
when "examples", "test"
|
16
|
+
status = 0
|
17
|
+
|
18
|
+
ARGV = %w(templates/test -t debug -r approved)
|
19
|
+
load "origen/commands/compile.rb"
|
20
|
+
|
21
|
+
if Origen.app.stats.changed_files == 0 &&
|
22
|
+
Origen.app.stats.new_files == 0 &&
|
23
|
+
Origen.app.stats.changed_patterns == 0 &&
|
24
|
+
Origen.app.stats.new_patterns == 0
|
25
|
+
|
26
|
+
Origen.app.stats.report_pass
|
27
|
+
else
|
28
|
+
Origen.app.stats.report_fail
|
29
|
+
status = 1
|
30
|
+
end
|
31
|
+
puts
|
32
|
+
if @command == "test"
|
33
|
+
Origen.app.unload_target!
|
34
|
+
require "rspec"
|
35
|
+
result = RSpec::Core::Runner.run(['spec'])
|
36
|
+
status = status == 1 ? 1 : result
|
37
|
+
end
|
38
|
+
exit status
|
39
|
+
|
40
|
+
else
|
41
|
+
@application_commands = <<-EOT
|
42
|
+
specs Run the specs (unit tests), -c will enable coverage
|
43
|
+
examples Run the examples (acceptance tests), -c will enable coverage
|
44
|
+
test Run both specs and examples, -c will enable coverage
|
45
|
+
EOT
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,17 @@
|
|
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.
|
13
|
+
module CrossOrigen
|
14
|
+
module Test
|
15
|
+
autoload :DUT, "cross_origen/test/dut"
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,35 @@
|
|
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
|
+
# This says load the file "lib/pioneer.rb" the first time anyone makes a
|
15
|
+
# reference to the class name 'Pioneer'.
|
16
|
+
#autoload :Pioneer, "pioneer"
|
17
|
+
# This is generally preferable to using require which will load the file
|
18
|
+
# regardless of whether it is needed by the current target or not:
|
19
|
+
#require "pioneer"
|
20
|
+
# Sometimes you have to use require however:-
|
21
|
+
# 1. When defining a test program interface:
|
22
|
+
#require "interfaces/j750"
|
23
|
+
# 2. If you want to extend a class defined by an imported application, in
|
24
|
+
# this case your must use required and supply a full path (to distinguish
|
25
|
+
# it from the one in the parent application):
|
26
|
+
#require "#{Origen.root}/c90_top_level/p2"
|
27
|
+
module CrossOrigen
|
28
|
+
autoload :XMLDoc, "cross_origen/xml_doc"
|
29
|
+
autoload :Headers, "cross_origen/headers"
|
30
|
+
autoload :Ralf, "cross_origen/ralf"
|
31
|
+
autoload :IpXact, "cross_origen/ip_xact"
|
32
|
+
autoload :DesignSync, "cross_origen/design_sync"
|
33
|
+
autoload :OrigenFormat, "cross_origen/origen_format"
|
34
|
+
end
|
35
|
+
require "cross_origen"
|
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,54 @@
|
|
1
|
+
module CrossOrigen
|
2
|
+
# Driver for talking to DesignSync
|
3
|
+
class DesignSync
|
4
|
+
require 'digest/sha1'
|
5
|
+
|
6
|
+
# Returns the object that included the CrossOrigen module
|
7
|
+
attr_reader :owner
|
8
|
+
|
9
|
+
def initialize(owner)
|
10
|
+
@owner = owner
|
11
|
+
end
|
12
|
+
|
13
|
+
def driver
|
14
|
+
@driver ||= Origen::Utility::DesignSync.new
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns a full path to the Design Sync import (cache) directory
|
18
|
+
def import_dir
|
19
|
+
return @import_dir if @import_dir
|
20
|
+
@import_dir = "#{Origen.app.workspace_manager.imports_directory}/design_sync"
|
21
|
+
FileUtils.mkdir_p(@import_dir) unless File.exist?(@import_dir)
|
22
|
+
@import_dir
|
23
|
+
end
|
24
|
+
|
25
|
+
# This will be called if the user has supplied a :vault in the rs_import options. The corresponding
|
26
|
+
# version of the file will be returned from the cache if it already exists locally, otherwise it
|
27
|
+
# will be imported.
|
28
|
+
#
|
29
|
+
# This method returns a full path to the local cache copy of the file.
|
30
|
+
def fetch(options = {})
|
31
|
+
unless options[:version]
|
32
|
+
puts 'You must supply a :version number (or tag) when importing data from Design Sync'
|
33
|
+
exit 1
|
34
|
+
end
|
35
|
+
v = options[:vault]
|
36
|
+
f = v.split('/').last
|
37
|
+
vault = v.sub(/\/#{f}$/, '')
|
38
|
+
# Consider that similarly named files could exist in different vaults, so attach
|
39
|
+
# a representation of the vault to the filename
|
40
|
+
vault_hash = Digest::SHA1.hexdigest(vault)
|
41
|
+
dir = "#{import_dir}/#{vault_hash}-#{f}"
|
42
|
+
file = "#{dir}/#{options[:version]}"
|
43
|
+
if f =~ /.*\.(.*)/
|
44
|
+
file += ".#{Regexp.last_match[1]}"
|
45
|
+
end
|
46
|
+
if !File.exist?(file) || options[:force]
|
47
|
+
FileUtils.mkdir_p(dir) unless File.exist?(dir)
|
48
|
+
driver.import(f, vault, options[:version], dir)
|
49
|
+
FileUtils.mv("#{dir}/#{f}", file)
|
50
|
+
end
|
51
|
+
file
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module CrossOrigen
|
2
|
+
class Headers
|
3
|
+
# Returns the object that included the CrossOrigen module
|
4
|
+
attr_reader :owner
|
5
|
+
|
6
|
+
def initialize(owner)
|
7
|
+
@owner = owner
|
8
|
+
end
|
9
|
+
|
10
|
+
# Returns a string representing the owner as a C header
|
11
|
+
def owner_to_header(_options = {})
|
12
|
+
Origen.compile("#{path_to_templates}/headers/default.h.erb", scope: owner)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def path_to_templates
|
18
|
+
"#{File.expand_path(File.dirname(__FILE__))}/../../templates"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,243 @@
|
|
1
|
+
module CrossOrigen
|
2
|
+
class IpXact < XMLDoc
|
3
|
+
AddressSpace = Struct.new(:name, :range, :width)
|
4
|
+
|
5
|
+
MemoryMaps = Struct.new(:name, :address_blocks)
|
6
|
+
|
7
|
+
AddressBlock = Struct.new(:name, :base_address, :range, :width)
|
8
|
+
|
9
|
+
# Import/reader that currently only supports creating registers and bit fields
|
10
|
+
def import(file, options = {}) # rubocop:disable CyclomaticComplexity
|
11
|
+
require 'kramdown'
|
12
|
+
|
13
|
+
address_spaces = {}
|
14
|
+
|
15
|
+
doc(file, options) do |doc|
|
16
|
+
doc.xpath('//spirit:addressSpaces/spirit:addressSpace').each do |addr_space|
|
17
|
+
name = fetch addr_space.at_xpath('spirit:name'), downcase: true, to_sym: true, get_text: true
|
18
|
+
range = fetch addr_space.at_xpath('spirit:range'), get_text: true, to_dec: true
|
19
|
+
width = fetch addr_space.at_xpath('spirit:width'), get_text: true, to_i: true
|
20
|
+
address_spaces[name] = AddressSpace.new(name, range, width)
|
21
|
+
end
|
22
|
+
doc.xpath('//spirit:memoryMaps/spirit:memoryMap').each do |mem_map|
|
23
|
+
mem_map_name = fetch mem_map.at_xpath('spirit:name'), downcase: true, to_sym: true, get_text: true
|
24
|
+
owner.sub_block mem_map_name
|
25
|
+
mem_map_obj = owner.send(mem_map_name)
|
26
|
+
mem_map.xpath('spirit:addressBlock').each do |addr_block|
|
27
|
+
name = fetch addr_block.at_xpath('spirit:name'), downcase: true, to_sym: true, get_text: true
|
28
|
+
base_address = fetch addr_block.at_xpath('spirit:baseAddress'), get_text: true, to_dec: true
|
29
|
+
range = fetch addr_block.at_xpath('spirit:range'), get_text: true, to_dec: true
|
30
|
+
width = fetch addr_block.at_xpath('spirit:width'), get_text: true, to_i: true
|
31
|
+
mem_map_obj.sub_block name, base_address: base_address, range: range, lau: width
|
32
|
+
addr_block_obj = mem_map_obj.send(name)
|
33
|
+
addr_block.xpath('spirit:register').each do |register|
|
34
|
+
name = fetch register.at_xpath('spirit:name'), downcase: true, to_sym: true, get_text: true
|
35
|
+
size = fetch register.at_xpath('spirit:size'), get_text: true, to_i: true
|
36
|
+
addr_offset = fetch register.at_xpath('spirit:addressOffset'), get_text: true, to_dec: true
|
37
|
+
access = fetch register.at_xpath('spirit:access'), get_text: true
|
38
|
+
reset_value = fetch register.at_xpath('spirit:reset/spirit:value'), get_text: true, to_dec: true
|
39
|
+
reset_mask = fetch register.at_xpath('spirit:reset/spirit:mask'), get_text: true, to_dec: true
|
40
|
+
if [reset_value, reset_mask].include? nil
|
41
|
+
# Set default values for some register attributes
|
42
|
+
reset_value, reset_mask = 0, 0
|
43
|
+
else
|
44
|
+
# Do a logical bitwise AND with the reset value and mask
|
45
|
+
reset_value = reset_value & reset_mask
|
46
|
+
end
|
47
|
+
addr_block_obj.reg name, addr_offset, size: size, access: access do |reg|
|
48
|
+
register.xpath('spirit:field').each do |field|
|
49
|
+
name = fetch field.at_xpath('spirit:name'), downcase: true, to_sym: true, get_text: true
|
50
|
+
bit_offset = fetch field.at_xpath('spirit:bitOffset'), get_text: true, to_i: true
|
51
|
+
bit_width = fetch field.at_xpath('spirit:bitWidth'), get_text: true, to_i: true
|
52
|
+
access = fetch field.at_xpath('spirit:access'), get_text: true
|
53
|
+
if access =~ /\S+\-\S+/
|
54
|
+
access = access[/^(\S)/, 1] + access[/\-(\S)\S+$/, 1]
|
55
|
+
access = access.downcase.to_sym
|
56
|
+
else
|
57
|
+
# default to read-write if access is not specified
|
58
|
+
access = :rw
|
59
|
+
end
|
60
|
+
range = nil
|
61
|
+
if bit_width == 1
|
62
|
+
range = bit_offset
|
63
|
+
else
|
64
|
+
range = (bit_offset + bit_width - 1)..bit_offset
|
65
|
+
end
|
66
|
+
reg.bit range, name, reset: reset_value[range], access: access
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Returns a string representing the owner object in IP-XACT XML
|
76
|
+
def owner_to_xml(options = {})
|
77
|
+
require 'builder'
|
78
|
+
|
79
|
+
options = {
|
80
|
+
include_bit_field_values: true
|
81
|
+
}.merge(options)
|
82
|
+
|
83
|
+
@format = options[:format]
|
84
|
+
|
85
|
+
xml = Builder::XmlMarkup.new(indent: 2, margin: 0)
|
86
|
+
|
87
|
+
xml.instruct!
|
88
|
+
|
89
|
+
schemas = [
|
90
|
+
'http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.4',
|
91
|
+
'http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.4/index.xsd'
|
92
|
+
]
|
93
|
+
if uvm?
|
94
|
+
schemas << '$IREG_GEN/XMLSchema/SPIRIT/VendorExtensions.xsd'
|
95
|
+
end
|
96
|
+
|
97
|
+
headers = {
|
98
|
+
'xmlns:spirit' => 'http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.4',
|
99
|
+
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
100
|
+
'xsi:schemaLocation' => schemas.join(' ')
|
101
|
+
}
|
102
|
+
if uvm?
|
103
|
+
headers['xmlns:vendorExtensions'] = '$IREG_GEN/XMLSchema/SPIRIT'
|
104
|
+
end
|
105
|
+
|
106
|
+
xml.tag!('spirit:component', headers) do
|
107
|
+
xml.spirit :vendor, options[:vendor] || 'Freescale'
|
108
|
+
xml.spirit :library, options[:library] || 'Freescale'
|
109
|
+
# I guess this should really be the register owner's owner's name?
|
110
|
+
xml.spirit :name, try(:ip_name, :pdm_part_name) || owner.class.to_s.split('::').last
|
111
|
+
xml.spirit :version, try(:ip_version, :pdm_version, :pdm_cm_version, :version, :revision)
|
112
|
+
xml.spirit :memoryMaps do
|
113
|
+
memory_maps.each do |map_name, _map|
|
114
|
+
xml.spirit :memoryMap do
|
115
|
+
xml.spirit :name, map_name
|
116
|
+
address_blocks do |domain_name, _domain, sub_block|
|
117
|
+
xml.spirit :addressBlock do
|
118
|
+
xml.spirit :name, address_block_name(domain_name, sub_block)
|
119
|
+
xml.spirit :baseAddress, sub_block.base_address.to_hex
|
120
|
+
xml.spirit :range, range(sub_block)
|
121
|
+
xml.spirit :width, width(sub_block)
|
122
|
+
sub_block.regs.each do |name, reg|
|
123
|
+
# Required for now to ensure that the current value is the reset value
|
124
|
+
reg.reset
|
125
|
+
xml.spirit :register do
|
126
|
+
xml.spirit :name, name
|
127
|
+
xml.spirit :description, try(reg, :name_full, :full_name)
|
128
|
+
xml.spirit :addressOffset, reg.offset.to_hex
|
129
|
+
xml.spirit :size, reg.size
|
130
|
+
if reg.bits.any?(&:writable?)
|
131
|
+
xml.spirit :access, 'read-write'
|
132
|
+
else
|
133
|
+
xml.spirit :access, 'read-only'
|
134
|
+
end
|
135
|
+
xml.spirit :reset do
|
136
|
+
xml.spirit :value, reg.data.to_hex
|
137
|
+
xml.spirit :mask, mask(reg).to_hex
|
138
|
+
end
|
139
|
+
reg.named_bits do |name, bits|
|
140
|
+
xml.spirit :field do
|
141
|
+
xml.spirit :name, name
|
142
|
+
xml.spirit :description, try(bits, :brief_description, :name_full, :full_name)
|
143
|
+
xml.spirit :bitOffset, bits.position
|
144
|
+
xml.spirit :bitWidth, bits.size
|
145
|
+
xml.spirit :access, bits.access
|
146
|
+
if options[:include_bit_field_values]
|
147
|
+
if bits.bit_value_descriptions[0]
|
148
|
+
bits.bit_value_descriptions.each do |val, desc|
|
149
|
+
xml.spirit :values do
|
150
|
+
xml.spirit :value, val.to_hex
|
151
|
+
xml.spirit :name, "val_#{val.to_hex}"
|
152
|
+
xml.spirit :description, desc
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
if uvm?
|
158
|
+
xml.spirit :vendorExtensions do
|
159
|
+
xml.vendorExtensions :hdl_path, bits.path(relative_to: sub_block)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
if uvm?
|
167
|
+
xml.spirit :vendorExtensions do
|
168
|
+
xml.vendorExtensions :hdl_path, sub_block.path(relative_to: owner)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
private
|
180
|
+
|
181
|
+
def mask(reg)
|
182
|
+
m = 0
|
183
|
+
reg.size.times do |i|
|
184
|
+
unless reg[i].reset_val == :undefined
|
185
|
+
m |= (1 << i)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
m
|
189
|
+
end
|
190
|
+
|
191
|
+
def uvm?
|
192
|
+
@format == :uvm
|
193
|
+
end
|
194
|
+
|
195
|
+
def memory_maps
|
196
|
+
{ owner.name => {} }
|
197
|
+
end
|
198
|
+
|
199
|
+
def sub_blocks(domain_name)
|
200
|
+
owner.all_sub_blocks.select do |sub_block|
|
201
|
+
sub_block.owns_registers? &&
|
202
|
+
(sub_block.domains[domain_name] || domain_name == :default)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def address_blocks
|
207
|
+
domains = owner.register_domains
|
208
|
+
domains = { default: {} } if domains.empty?
|
209
|
+
domains.each do |domain_name, domain|
|
210
|
+
sub_blocks(domain_name).each do |sub_block|
|
211
|
+
yield domain_name, domain, sub_block
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def address_block_name(domain_name, sub_block)
|
217
|
+
if domain_name == :default
|
218
|
+
sub_block.name.to_s
|
219
|
+
else
|
220
|
+
"#{domain_name}_#{sub_block.name}"
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
def width(sub_block)
|
225
|
+
sub_block.try(:width) || 32
|
226
|
+
end
|
227
|
+
|
228
|
+
def range(sub_block)
|
229
|
+
range = sub_block.try(:range) || begin
|
230
|
+
# This is to work around an Origen bug where max_address_reg_size is not updated in the case of
|
231
|
+
# only one register being present
|
232
|
+
# TODO: Fix in Origen
|
233
|
+
max_address_reg_size = sub_block.max_address_reg_size || sub_block.regs.first[1].size
|
234
|
+
(sub_block.max_reg_address + (max_address_reg_size / 8))
|
235
|
+
end
|
236
|
+
width_in_bytes = width(sub_block) / 8
|
237
|
+
if range % width_in_bytes != 0
|
238
|
+
range += (width_in_bytes - (range % width_in_bytes))
|
239
|
+
end
|
240
|
+
range
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|