Class: CrossOrigen::IpXact
Defined Under Namespace
Classes: AddressBlock, AddressSpace, MemoryMaps
Constant Summary
Constants inherited from XMLDoc
XMLDoc::HTML_SANITIZATION_CONFIG, XMLDoc::HTML_TRANSFORMER, XMLDoc::HTML_TRANSFORMS
Instance Attribute Summary
Attributes inherited from XMLDoc
#creation_info, #import_info, #owner
Instance Method Summary collapse
- #doc(path, options = {}) ⇒ Object
-
#import(file, options = {}) ⇒ Object
Import/reader that currently only supports creating registers and bit fields.
-
#owner_to_xml(options = {}) ⇒ Object
Returns a string representing the owner object in IP-XACT XML.
Methods inherited from XMLDoc
#extract, #fetch, #initialize, #pre_sanitize, #to_html, #to_markdown, #try
Constructor Details
This class inherits a constructor from CrossOrigen::XMLDoc
Instance Method Details
#doc(path, options = {}) ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/cross_origen/ip_xact.rb', line 99 def doc(path, = {}) # If a fragment of IP-XACT is given, then wrap it with a valid header and we will try our best if [:fragment] require 'nokogiri' content = %( <?xml version="1.0"?> <spirit:component xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.4" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="$REGMEM_HOME/builder/ipxact/schema/ipxact $REGMEM_HOME/builder/ipxact/schema/ipxact/index.xsd"> #{File.read(path)} </spirit:component> ) yield Nokogiri::XML(content) else super end end |
#import(file, options = {}) ⇒ Object
Import/reader that currently only supports creating registers and bit fields
10 11 12 13 14 15 16 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 97 |
# File 'lib/cross_origen/ip_xact.rb', line 10 def import(file, = {}) # rubocop:disable CyclomaticComplexity require 'kramdown' filename = Pathname.new(file).basename('.*').to_s unless [:refresh] || CrossOrigen.refresh? return if owner.import(filename, allow_missing: true) end model = CrossOrigen::Model.new address_spaces = {} doc(file, ) do |doc| doc.xpath('//spirit:addressSpaces/spirit:addressSpace').each do |addr_space| name = fetch addr_space.at_xpath('spirit:name'), downcase: true, to_sym: true, get_text: true range = fetch addr_space.at_xpath('spirit:range'), get_text: true, to_dec: true width = fetch addr_space.at_xpath('spirit:width'), get_text: true, to_i: true address_spaces[name] = AddressSpace.new(name, range, width) end open_memory_map(doc) do |mem_map| if mem_map mem_map_name = fetch mem_map.at_xpath('spirit:name'), downcase: true, to_sym: true, get_text: true if mem_map_name.to_s.empty? mem_map_obj = model else model.sub_block mem_map_name mem_map_obj = model.send(mem_map_name) end addr_blocks = mem_map.xpath('spirit:addressBlock') else mem_map_obj = model addr_blocks = doc.xpath('//spirit:addressBlock') end addr_blocks.each do |addr_block| name = fetch addr_block.at_xpath('spirit:name'), downcase: true, to_sym: true, get_text: true base_address = fetch addr_block.at_xpath('spirit:baseAddress'), get_text: true, to_dec: true range = fetch addr_block.at_xpath('spirit:range'), get_text: true, to_dec: true width = fetch addr_block.at_xpath('spirit:width'), get_text: true, to_i: true if name.to_s.empty? addr_block_obj = mem_map_obj else mem_map_obj.sub_block name, base_address: base_address, range: range, lau: width addr_block_obj = mem_map_obj.send(name) end addr_block.xpath('spirit:register').each do |register| name = fetch register.at_xpath('spirit:name'), downcase: true, to_sym: true, get_text: true size = fetch register.at_xpath('spirit:size'), get_text: true, to_i: true addr_offset = fetch register.at_xpath('spirit:addressOffset'), get_text: true, to_dec: true access = fetch register.at_xpath('spirit:access'), get_text: true reset_value = fetch register.at_xpath('spirit:reset/spirit:value'), get_text: true, to_dec: true reset_mask = fetch register.at_xpath('spirit:reset/spirit:mask'), get_text: true, to_dec: true if [reset_value, reset_mask].include? nil # Set default values for some register attributes reset_value, reset_mask = 0, 0 else # Do a logical bitwise AND with the reset value and mask reset_value = reset_value & reset_mask end addr_block_obj.reg name, addr_offset, size: size, access: access, description: reg_description(register) do |reg| register.xpath('spirit:field').each do |field| name = fetch field.at_xpath('spirit:name'), downcase: true, to_sym: true, get_text: true bit_offset = fetch field.at_xpath('spirit:bitOffset'), get_text: true, to_i: true bit_width = fetch field.at_xpath('spirit:bitWidth'), get_text: true, to_i: true access = fetch field.at_xpath('spirit:access'), get_text: true if access =~ /\S+\-\S+/ access = access[/^(\S)/, 1] + access[/\-(\S)\S+$/, 1] access = access.downcase.to_sym else # default to read-write if access is not specified access = :rw end range = nil if bit_width == 1 range = bit_offset else range = (bit_offset + bit_width - 1)..bit_offset end reg.bit range, name, reset: reset_value[range], access: access, description: bit_description(field) end end end end end end model.export(filename, include_timestamp: CrossOrigen.) owner.import(filename) end |
#owner_to_xml(options = {}) ⇒ Object
Returns a string representing the owner object in IP-XACT XML
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/cross_origen/ip_xact.rb', line 120 def owner_to_xml( = {}) require 'nokogiri' = { include_bit_field_values: true }.merge() @format = [:format] schemas = [ 'http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.4', 'http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.4/index.xsd' ] if uvm? schemas << '$IREG_GEN/XMLSchema/SPIRIT/VendorExtensions.xsd' end headers = { 'xmlns:spirit' => 'http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.4', 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xsi:schemaLocation' => schemas.join(' ') } if uvm? headers['xmlns:vendorExtensions'] = '$IREG_GEN/XMLSchema/SPIRIT' end builder = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml| spirit = xml['spirit'] spirit.component(headers) do spirit.vendor [:vendor] || 'Origen' spirit.library [:library] || 'Origen' # I guess this should really be the register owner's owner's name? spirit.name try(:ip_name) || owner.class.to_s.split('::').last spirit.version try(:ip_version, :version, :revision) spirit.memoryMaps do memory_maps.each do |map_name, _map| spirit.memoryMap do spirit.name map_name address_blocks do |domain_name, _domain, sub_block| spirit.addressBlock do if sub_block == owner spirit.name nil spirit.baseAddress 0.to_hex else spirit.name address_block_name(domain_name, sub_block) spirit.baseAddress sub_block.base_address.to_hex end spirit.range range(sub_block) spirit.width width(sub_block) sub_block.regs.each do |name, reg| # Required for now to ensure that the current value is the reset value reg.reset spirit.register do spirit.name name spirit.description try(reg, :name_full, :full_name) spirit.addressOffset reg.offset.to_hex spirit.size reg.size if reg.bits.any?(&:writable?) spirit.access 'read-write' else spirit.access 'read-only' end spirit.reset do spirit.value reg.data.to_hex spirit.mask mask(reg).to_hex end reg.named_bits do |name, bits| spirit.field do spirit.name name spirit.description try(bits, :brief_description, :name_full, :full_name) spirit.bitOffset bits.position spirit.bitWidth bits.size spirit.access bits.access if [:include_bit_field_values] if bits.bit_value_descriptions[0] bits.bit_value_descriptions.each do |val, desc| spirit.values do spirit.value val.to_hex spirit.name "val_#{val.to_hex}" spirit.description desc end end end end if uvm? spirit.vendorExtensions do xml['vendorExtensions'].hdl_path bits.path(relative_to: sub_block) end end end end end end if uvm? spirit.vendorExtensions do xml['vendorExtensions'].hdl_path sub_block.path(relative_to: owner) end end end end end end end end end builder.to_xml end |