origen 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (336) hide show
  1. checksums.yaml +4 -4
  2. data/bin/ctags +0 -0
  3. data/bin/origen +165 -1
  4. data/bin/rgen +2 -0
  5. data/config/application.rb +141 -0
  6. data/config/commands.rb +72 -0
  7. data/config/development.rb +7 -0
  8. data/config/environment.rb +0 -0
  9. data/config/rgen.policy +7 -0
  10. data/config/rubocop/easy.yml +620 -0
  11. data/config/rubocop/easy_disabled.yml +271 -0
  12. data/config/rubocop/easy_enabled.yml +731 -0
  13. data/config/rubocop/strict.yml +620 -0
  14. data/config/rubocop/strict_disabled.yml +247 -0
  15. data/config/rubocop/strict_enabled.yml +755 -0
  16. data/config/users.rb +20 -0
  17. data/config/version.rb +1 -1
  18. data/helpers/url.rb +68 -0
  19. data/lib/c99/doc_interface.rb +56 -0
  20. data/lib/c99/j750_interface.rb +85 -0
  21. data/lib/c99/nvm.rb +89 -0
  22. data/lib/c99/target/mock2.rb +1 -0
  23. data/lib/c99/target/subdir/mock3.rb +1 -0
  24. data/lib/option_parser/optparse.rb +12 -0
  25. data/lib/origen/acronyms.rb +60 -0
  26. data/lib/origen/application/command_dispatcher.rb +12 -0
  27. data/lib/origen/application/configuration.rb +206 -0
  28. data/lib/origen/application/configuration_manager.rb +78 -0
  29. data/lib/origen/application/deployer.rb +367 -0
  30. data/lib/origen/application/environment.rb +186 -0
  31. data/lib/origen/application/lsf.rb +145 -0
  32. data/lib/origen/application/lsf_manager.rb +657 -0
  33. data/lib/origen/application/plugins_manager.rb +280 -0
  34. data/lib/origen/application/release.rb +359 -0
  35. data/lib/origen/application/runner.rb +246 -0
  36. data/lib/origen/application/statistics.rb +191 -0
  37. data/lib/origen/application/target.rb +374 -0
  38. data/lib/origen/application/version_tracker.rb +59 -0
  39. data/lib/origen/application/workspace_manager.rb +151 -0
  40. data/lib/origen/application.rb +746 -0
  41. data/lib/origen/bugs/bug.rb +36 -0
  42. data/lib/origen/bugs.rb +45 -0
  43. data/lib/origen/callbacks.rb +35 -0
  44. data/lib/origen/chip_mode.rb +118 -0
  45. data/lib/origen/chip_package.rb +461 -0
  46. data/lib/origen/client.rb +87 -0
  47. data/lib/origen/code_generators/actions.rb +258 -0
  48. data/lib/origen/code_generators/base.rb +57 -0
  49. data/lib/origen/code_generators/bundler.rb +17 -0
  50. data/lib/origen/code_generators/gem_setup.rb +49 -0
  51. data/lib/origen/code_generators/rake.rb +13 -0
  52. data/lib/origen/code_generators/rspec.rb +12 -0
  53. data/lib/origen/code_generators/semver.rb +39 -0
  54. data/lib/origen/code_generators/timever.rb +37 -0
  55. data/lib/origen/code_generators.rb +111 -0
  56. data/lib/origen/commands/add.rb +12 -0
  57. data/lib/origen/commands/compile.rb +62 -0
  58. data/lib/origen/commands/ctags.rb +9 -0
  59. data/lib/origen/commands/dispatch.rb +22 -0
  60. data/lib/origen/commands/environment.rb +11 -0
  61. data/lib/origen/commands/fetch.rb +63 -0
  62. data/lib/origen/commands/generate.rb +130 -0
  63. data/lib/origen/commands/interactive.rb +73 -0
  64. data/lib/origen/commands/lint.rb +82 -0
  65. data/lib/origen/commands/lsf.rb +93 -0
  66. data/lib/origen/commands/merge.rb +55 -0
  67. data/lib/origen/commands/modifications.rb +12 -0
  68. data/lib/origen/commands/new.rb +113 -0
  69. data/lib/origen/commands/plugin.rb +105 -0
  70. data/lib/origen/commands/program.rb +70 -0
  71. data/lib/origen/commands/rc.rb +442 -0
  72. data/lib/origen/commands/save.rb +56 -0
  73. data/lib/origen/commands/target.rb +27 -0
  74. data/lib/origen/commands/time.rb +127 -0
  75. data/lib/origen/commands/version.rb +17 -0
  76. data/lib/origen/commands/web.rb +221 -0
  77. data/lib/origen/commands.rb +272 -0
  78. data/lib/origen/commands_global.rb +76 -0
  79. data/lib/origen/controller.rb +94 -0
  80. data/lib/origen/core_ext/array.rb +23 -0
  81. data/lib/origen/core_ext/bignum.rb +36 -0
  82. data/lib/origen/core_ext/enumerable.rb +76 -0
  83. data/lib/origen/core_ext/fixnum.rb +46 -0
  84. data/lib/origen/core_ext/hash.rb +52 -0
  85. data/lib/origen/core_ext/module.rb +14 -0
  86. data/lib/origen/core_ext/numeric.rb +126 -0
  87. data/lib/origen/core_ext/object.rb +13 -0
  88. data/lib/origen/core_ext/range.rb +7 -0
  89. data/lib/origen/core_ext/string.rb +124 -0
  90. data/lib/origen/core_ext.rb +10 -0
  91. data/lib/origen/database/key_value_store.rb +111 -0
  92. data/lib/origen/database/key_value_stores.rb +108 -0
  93. data/lib/origen/database.rb +6 -0
  94. data/lib/origen/encodings.rb +102 -0
  95. data/lib/origen/features/feature.rb +22 -0
  96. data/lib/origen/features.rb +104 -0
  97. data/lib/origen/file_handler.rb +429 -0
  98. data/lib/origen/generator/comparator.rb +56 -0
  99. data/lib/origen/generator/compiler.rb +277 -0
  100. data/lib/origen/generator/flow.rb +49 -0
  101. data/lib/origen/generator/job.rb +131 -0
  102. data/lib/origen/generator/pattern.rb +356 -0
  103. data/lib/origen/generator/pattern_finder.rb +155 -0
  104. data/lib/origen/generator/pattern_iterator.rb +55 -0
  105. data/lib/origen/generator/renderer.rb +113 -0
  106. data/lib/origen/generator/resources.rb +40 -0
  107. data/lib/origen/generator/stage.rb +89 -0
  108. data/lib/origen/generator.rb +85 -0
  109. data/lib/origen/global_methods.rb +205 -0
  110. data/lib/origen/import_manager.rb +596 -0
  111. data/lib/origen/location/base.rb +116 -0
  112. data/lib/origen/location/map.rb +83 -0
  113. data/lib/origen/location.rb +6 -0
  114. data/lib/origen/log.rb +217 -0
  115. data/lib/origen/logger_methods.rb +56 -0
  116. data/lib/origen/mode.rb +61 -0
  117. data/lib/origen/model.rb +267 -0
  118. data/lib/origen/model_initializer.rb +45 -0
  119. data/lib/origen/nvm/block_array.rb +72 -0
  120. data/lib/origen/nvm.rb +6 -0
  121. data/lib/origen/parameters/live.rb +22 -0
  122. data/lib/origen/parameters/missing.rb +28 -0
  123. data/lib/origen/parameters/set.rb +144 -0
  124. data/lib/origen/parameters.rb +107 -0
  125. data/lib/origen/pdm.rb +218 -0
  126. data/lib/origen/pins/function_proxy.rb +36 -0
  127. data/lib/origen/pins/ground_pin.rb +6 -0
  128. data/lib/origen/pins/pin.rb +860 -0
  129. data/lib/origen/pins/pin_bank.rb +349 -0
  130. data/lib/origen/pins/pin_clock.rb +124 -0
  131. data/lib/origen/pins/pin_collection.rb +492 -0
  132. data/lib/origen/pins/pin_common.rb +206 -0
  133. data/lib/origen/pins/port.rb +268 -0
  134. data/lib/origen/pins/power_pin.rb +30 -0
  135. data/lib/origen/pins.rb +696 -0
  136. data/lib/origen/registers/bit.rb +562 -0
  137. data/lib/origen/registers/bit_collection.rb +787 -0
  138. data/lib/origen/registers/container.rb +288 -0
  139. data/lib/origen/registers/domain.rb +16 -0
  140. data/lib/origen/registers/reg.rb +1406 -0
  141. data/lib/origen/registers/reg_collection.rb +24 -0
  142. data/lib/origen/registers.rb +652 -0
  143. data/lib/origen/regression_manager.rb +251 -0
  144. data/lib/origen/remote_manager.rb +340 -0
  145. data/lib/origen/revision_control/base.rb +257 -0
  146. data/lib/origen/revision_control/design_sync.rb +276 -0
  147. data/lib/origen/revision_control/git.rb +243 -0
  148. data/lib/origen/revision_control/subversion.rb +6 -0
  149. data/lib/origen/revision_control.rb +44 -0
  150. data/lib/origen/ruby_version_check.rb +131 -0
  151. data/lib/origen/site_config.rb +61 -0
  152. data/lib/origen/specs/checkers.rb +103 -0
  153. data/lib/origen/specs/creation_info.rb +17 -0
  154. data/lib/origen/specs/doc_resource.rb +91 -0
  155. data/lib/origen/specs/exhibit.rb +17 -0
  156. data/lib/origen/specs/mode_select.rb +16 -0
  157. data/lib/origen/specs/note.rb +17 -0
  158. data/lib/origen/specs/override.rb +21 -0
  159. data/lib/origen/specs/power_supply.rb +13 -0
  160. data/lib/origen/specs/spec.rb +226 -0
  161. data/lib/origen/specs/version_history.rb +14 -0
  162. data/lib/origen/specs.rb +552 -0
  163. data/lib/origen/sub_blocks.rb +298 -0
  164. data/lib/origen/tester/api.rb +277 -0
  165. data/lib/origen/tester/bdm/bdm.rb +25 -0
  166. data/lib/origen/tester/command_based_tester.rb +46 -0
  167. data/lib/origen/tester/doc/doc.rb +226 -0
  168. data/lib/origen/tester/doc/generator/flow.rb +71 -0
  169. data/lib/origen/tester/doc/generator/flow_line.rb +203 -0
  170. data/lib/origen/tester/doc/generator/test.rb +68 -0
  171. data/lib/origen/tester/doc/generator/test_group.rb +66 -0
  172. data/lib/origen/tester/doc/generator/tests.rb +47 -0
  173. data/lib/origen/tester/doc/generator.rb +126 -0
  174. data/lib/origen/tester/doc/model.rb +162 -0
  175. data/lib/origen/tester/generator/flow_control_api.rb +606 -0
  176. data/lib/origen/tester/generator/identity_map.rb +25 -0
  177. data/lib/origen/tester/generator/placeholder.rb +13 -0
  178. data/lib/origen/tester/generator/test_numberer.rb +25 -0
  179. data/lib/origen/tester/generator.rb +271 -0
  180. data/lib/origen/tester/interface.rb +154 -0
  181. data/lib/origen/tester/j750/files.rb +45 -0
  182. data/lib/origen/tester/j750/generator/flow.rb +123 -0
  183. data/lib/origen/tester/j750/generator/flow_line.rb +288 -0
  184. data/lib/origen/tester/j750/generator/patgroup.rb +111 -0
  185. data/lib/origen/tester/j750/generator/patgroups.rb +41 -0
  186. data/lib/origen/tester/j750/generator/patset.rb +111 -0
  187. data/lib/origen/tester/j750/generator/patsets.rb +41 -0
  188. data/lib/origen/tester/j750/generator/templates/flow.txt.erb +9 -0
  189. data/lib/origen/tester/j750/generator/templates/instances.txt.erb +16 -0
  190. data/lib/origen/tester/j750/generator/templates/patgroups.txt.erb +8 -0
  191. data/lib/origen/tester/j750/generator/templates/patsets.txt.erb +10 -0
  192. data/lib/origen/tester/j750/generator/test_instance.rb +846 -0
  193. data/lib/origen/tester/j750/generator/test_instance_group.rb +60 -0
  194. data/lib/origen/tester/j750/generator/test_instances.rb +182 -0
  195. data/lib/origen/tester/j750/generator.rb +203 -0
  196. data/lib/origen/tester/j750/j750.rb +845 -0
  197. data/lib/origen/tester/j750/j750_hpt.rb +35 -0
  198. data/lib/origen/tester/j750/parser/ac_spec.rb +11 -0
  199. data/lib/origen/tester/j750/parser/ac_specs.rb +0 -0
  200. data/lib/origen/tester/j750/parser/dc_spec.rb +36 -0
  201. data/lib/origen/tester/j750/parser/dc_specs.rb +50 -0
  202. data/lib/origen/tester/j750/parser/descriptions.rb +340 -0
  203. data/lib/origen/tester/j750/parser/flow.rb +111 -0
  204. data/lib/origen/tester/j750/parser/flow_line.rb +207 -0
  205. data/lib/origen/tester/j750/parser/flows.rb +23 -0
  206. data/lib/origen/tester/j750/parser/pattern_set.rb +94 -0
  207. data/lib/origen/tester/j750/parser/pattern_sets.rb +33 -0
  208. data/lib/origen/tester/j750/parser/test_instance.rb +322 -0
  209. data/lib/origen/tester/j750/parser/test_instances.rb +26 -0
  210. data/lib/origen/tester/j750/parser/timeset.rb +15 -0
  211. data/lib/origen/tester/j750/parser/timesets.rb +0 -0
  212. data/lib/origen/tester/j750/parser.rb +104 -0
  213. data/lib/origen/tester/jlink/jlink.rb +33 -0
  214. data/lib/origen/tester/parser/description_lookup.rb +64 -0
  215. data/lib/origen/tester/parser/searchable_array.rb +32 -0
  216. data/lib/origen/tester/parser/searchable_hash.rb +32 -0
  217. data/lib/origen/tester/parser.rb +24 -0
  218. data/lib/origen/tester/time.rb +338 -0
  219. data/lib/origen/tester/timing.rb +253 -0
  220. data/lib/origen/tester/ultraflex/files.rb +45 -0
  221. data/lib/origen/tester/ultraflex/generator/flow.rb +119 -0
  222. data/lib/origen/tester/ultraflex/generator/flow_line.rb +269 -0
  223. data/lib/origen/tester/ultraflex/generator/patgroup.rb +111 -0
  224. data/lib/origen/tester/ultraflex/generator/patgroups.rb +41 -0
  225. data/lib/origen/tester/ultraflex/generator/patset.rb +111 -0
  226. data/lib/origen/tester/ultraflex/generator/patsets.rb +41 -0
  227. data/lib/origen/tester/ultraflex/generator/templates/flow.txt.erb +9 -0
  228. data/lib/origen/tester/ultraflex/generator/templates/instances.txt.erb +16 -0
  229. data/lib/origen/tester/ultraflex/generator/templates/patgroups.txt.erb +8 -0
  230. data/lib/origen/tester/ultraflex/generator/templates/patsets.txt.erb +10 -0
  231. data/lib/origen/tester/ultraflex/generator/test_instance.rb +622 -0
  232. data/lib/origen/tester/ultraflex/generator/test_instance_group.rb +60 -0
  233. data/lib/origen/tester/ultraflex/generator/test_instances.rb +174 -0
  234. data/lib/origen/tester/ultraflex/generator.rb +200 -0
  235. data/lib/origen/tester/ultraflex/parser/ac_spec.rb +11 -0
  236. data/lib/origen/tester/ultraflex/parser/ac_specs.rb +0 -0
  237. data/lib/origen/tester/ultraflex/parser/dc_spec.rb +36 -0
  238. data/lib/origen/tester/ultraflex/parser/dc_specs.rb +50 -0
  239. data/lib/origen/tester/ultraflex/parser/descriptions.rb +342 -0
  240. data/lib/origen/tester/ultraflex/parser/flow.rb +111 -0
  241. data/lib/origen/tester/ultraflex/parser/flow_line.rb +207 -0
  242. data/lib/origen/tester/ultraflex/parser/flows.rb +23 -0
  243. data/lib/origen/tester/ultraflex/parser/pattern_set.rb +94 -0
  244. data/lib/origen/tester/ultraflex/parser/pattern_sets.rb +33 -0
  245. data/lib/origen/tester/ultraflex/parser/test_instance.rb +262 -0
  246. data/lib/origen/tester/ultraflex/parser/test_instances.rb +26 -0
  247. data/lib/origen/tester/ultraflex/parser/timeset.rb +15 -0
  248. data/lib/origen/tester/ultraflex/parser/timesets.rb +0 -0
  249. data/lib/origen/tester/ultraflex/parser.rb +104 -0
  250. data/lib/origen/tester/ultraflex/ultraflex.rb +759 -0
  251. data/lib/origen/tester/v93k/generator/flow.rb +63 -0
  252. data/lib/origen/tester/v93k/generator/flow_node/print.rb +10 -0
  253. data/lib/origen/tester/v93k/generator/flow_node.rb +17 -0
  254. data/lib/origen/tester/v93k/generator/pattern.rb +16 -0
  255. data/lib/origen/tester/v93k/generator/pattern_master.rb +54 -0
  256. data/lib/origen/tester/v93k/generator/templates/_test_method.txt.erb +6 -0
  257. data/lib/origen/tester/v93k/generator/templates/_test_suite.txt.erb +11 -0
  258. data/lib/origen/tester/v93k/generator/templates/template.flow.erb +121 -0
  259. data/lib/origen/tester/v93k/generator/templates/template.pmfl.erb +9 -0
  260. data/lib/origen/tester/v93k/generator/test_function.rb +103 -0
  261. data/lib/origen/tester/v93k/generator/test_functions.rb +79 -0
  262. data/lib/origen/tester/v93k/generator/test_method.rb +46 -0
  263. data/lib/origen/tester/v93k/generator/test_methods.rb +75 -0
  264. data/lib/origen/tester/v93k/generator/test_suite.rb +54 -0
  265. data/lib/origen/tester/v93k/generator/test_suites.rb +65 -0
  266. data/lib/origen/tester/v93k/generator.rb +80 -0
  267. data/lib/origen/tester/v93k/v93k.rb +420 -0
  268. data/lib/origen/tester/vector.rb +86 -0
  269. data/lib/origen/tester/vector_generator.rb +633 -0
  270. data/lib/origen/tester/vector_pipeline.rb +150 -0
  271. data/lib/origen/tester.rb +56 -0
  272. data/lib/origen/top_level.rb +134 -0
  273. data/lib/origen/users/ldap.rb +65 -0
  274. data/lib/origen/users/user.rb +149 -0
  275. data/lib/origen/users.rb +30 -0
  276. data/lib/origen/utility/block_args.rb +93 -0
  277. data/lib/origen/utility/csv_data.rb +110 -0
  278. data/lib/origen/utility/design_sync.rb +494 -0
  279. data/lib/origen/utility/diff.rb +158 -0
  280. data/lib/origen/utility/input_capture.rb +121 -0
  281. data/lib/origen/utility/mailer.rb +143 -0
  282. data/lib/origen/utility/s_record.rb +205 -0
  283. data/lib/origen/utility/time_and_date.rb +30 -0
  284. data/lib/origen/utility.rb +12 -0
  285. data/lib/origen/version_checker.rb +117 -0
  286. data/lib/origen/version_string.rb +356 -0
  287. data/lib/origen.rb +648 -0
  288. data/lib/tasks/gem.rake +27 -22
  289. data/origen_site_config.yml +36 -0
  290. data/source_setup +17 -0
  291. data/spec/format/rgen_formatter.rb +14 -0
  292. data/templates/api_doc/README.txt.erb +24 -0
  293. data/templates/code_generators/gemfile_app.rb +4 -0
  294. data/templates/code_generators/gemfile_plugin.rb +6 -0
  295. data/templates/code_generators/gemspec.rb +33 -0
  296. data/templates/code_generators/rakefile.rb +10 -0
  297. data/templates/code_generators/spec_helper.rb +49 -0
  298. data/templates/code_generators/version.rb +8 -0
  299. data/templates/code_generators/version_time.rb +3 -0
  300. data/templates/git/gitignore.erb +33 -0
  301. data/templates/j750/_vt_flow.txt.erb +8 -0
  302. data/templates/j750/_vt_instances.txt.erb +4 -0
  303. data/templates/j750/program_sheet.txt.erb +9 -0
  304. data/templates/nanoc/Rules +74 -0
  305. data/templates/nanoc/config.yaml +77 -0
  306. data/templates/nanoc/content/favicon.ico +0 -0
  307. data/templates/nanoc/layouts/bootstrap.html.erb +63 -0
  308. data/templates/nanoc/layouts/bootstrap3.html.erb +71 -0
  309. data/templates/nanoc/layouts/freescale.html.erb +79 -0
  310. data/templates/nanoc/lib/bootstrap_filter.rb +49 -0
  311. data/templates/nanoc/lib/codeblocks_filter.rb +41 -0
  312. data/templates/nanoc/lib/default.rb +2 -0
  313. data/templates/nanoc/lib/gzip_filter.rb +16 -0
  314. data/templates/nanoc/lib/haml_code_filter.rb +41 -0
  315. data/templates/nanoc/lib/helpers.rb +1 -0
  316. data/templates/nanoc/lib/search_filter.rb +62 -0
  317. data/templates/nanoc_dynamic/content/search.js.erb +92 -0
  318. data/templates/shared/web/_logo.html +10 -0
  319. data/templates/test/_inline_sub.txt.erb +2 -0
  320. data/templates/test/environment.txt.erb +1 -0
  321. data/templates/test/inline.txt.erb +11 -0
  322. data/templates/test/inspections.txt.erb +19 -0
  323. data/templates/test/set1/_sub1.txt.erb +12 -0
  324. data/templates/test/set1/_sub4.txt.erb +1 -0
  325. data/templates/test/set1/_sub5.txt.erb +1 -0
  326. data/templates/test/set1/main.txt.erb +53 -0
  327. data/templates/test/set1/sub_dir/_sub2.txt.erb +20 -0
  328. data/templates/test/set1/sub_dir/_sub3.txt.erb +12 -0
  329. data/templates/test/set1/sub_dir/main2.txt.erb +4 -0
  330. data/templates/test/set2/template_with_no_erb_1.txt +9 -0
  331. data/templates/test/set2/template_with_no_erb_2.txt +9 -0
  332. data/templates/test/set3/_layout.html.erb +4 -0
  333. data/templates/test/set3/content.html.erb +6 -0
  334. data/templates/time/filter.rb.erb +15 -0
  335. data/templates/time/rules.rb.erb +45 -0
  336. metadata +639 -5
@@ -0,0 +1,1406 @@
1
+ module Origen
2
+ module Registers
3
+ # The register class can be used to represent not only h/ware resgisters,
4
+ # but really any entity which has an address and data component, such as a specific RAM location.<br>
5
+ # Any registers instantiated through Origen::Registers#add_reg are instances of this class.
6
+ #
7
+ # All methods in BitCollection can also be called on a Reg object.
8
+ class Reg
9
+ include Origen::SubBlocks::Path
10
+ include Origen::SubBlocks::Domains
11
+
12
+ # These attributes can be defined on a register at definition time and will get applied
13
+ # to all of its contained bits unless a specific bit has its own definition of the same
14
+ # attribute
15
+ REG_LEVEL_ATTRIBUTES = {
16
+ feature: {},
17
+ reset: { aliases: [:res] },
18
+ memory: {},
19
+ path: { aliases: [:hdl_path] },
20
+ abs_path: { aliases: [:absolute_path] },
21
+ access: {}
22
+ }
23
+
24
+ # Returns the object that own the register.
25
+ # ==== Example
26
+ # $soc.reg(:blah).owner # Returns the $soc object
27
+ attr_reader :owner
28
+ alias_method :parent, :owner
29
+ # The base address of the register, this will be set dynamically
30
+ # by Origen based on the parent's base address
31
+ attr_accessor :base_address
32
+ attr_writer :address # :nodoc:
33
+ # Returns an integer representing the number of bits in the register
34
+ attr_reader :size
35
+ # The register name
36
+ attr_accessor :name
37
+ # Any feature associated with the register
38
+ attr_accessor :feature
39
+
40
+ attr_accessor :grows_backwards # :nodoc:
41
+ attr_accessor :lookup # :nodoc:
42
+ # Returns a full path to the file in which the register was defined
43
+ attr_reader :define_file
44
+ # Returns any application-specific meta-data attatched to the given register
45
+ attr_accessor :meta
46
+ alias_method :meta_data, :meta
47
+ alias_method :metadata, :meta
48
+ # If the given register's reset data is backed by memory, the memory address can
49
+ # be recorded in this attribute
50
+ attr_accessor :memory
51
+
52
+ # Normally shouldn't be called directly, instantiate through add_reg
53
+ # Upon initialization bits are stored as follows:
54
+ # @bits -
55
+ # An array of bit objects in position order, @bits[5] corresponds
56
+ # to the bit as position r
57
+ # @lookup -
58
+ # A Hash lookup table for quickly accessing bit objects by name
59
+ # @lookup = { :bit_or_bus_name => {:pos => 3, :bits => 4} }
60
+ def initialize(owner, address, size, name, options = {}) # :nodoc:
61
+ @owner = owner
62
+ @address = address
63
+ @size = size
64
+ @bits = []
65
+ @lookup = {}
66
+ @name = name
67
+ @init_as_writable = options.delete(:init_as_writable)
68
+ @define_file = options.delete(:define_file)
69
+ REG_LEVEL_ATTRIBUTES.each do |attribute, _meta|
70
+ instance_variable_set("@#{attribute}", options.delete(attribute))
71
+ end
72
+ @description_from_api = {}
73
+ description = options.delete(:description)
74
+ if description
75
+ @description_from_api[:_reg] = description.split(/\r?\n/)
76
+ end
77
+ @meta = default_reg_metadata.merge(options.delete(:meta) || {})
78
+
79
+ # Initialize with unwritable bits that read back as zero, can override this
80
+ # to make all writable by default by setting the :init_writable option to true
81
+ @size.times do |n|
82
+ @bits << Bit.new(self, n, writable: @init_as_writable, undefined: true)
83
+ end
84
+
85
+ add_bits_from_options(options)
86
+ end
87
+
88
+ def freeze
89
+ bits.each(&:freeze)
90
+ # Call any methods which cache results to generate the instance variables
91
+ # before they are frozen
92
+ address
93
+ super
94
+ end
95
+
96
+ def bind(bitname, live_parameter)
97
+ unless live_parameter.respond_to?(:is_a_live_parameter?) && live_parameter.is_a_live_parameter?
98
+ fail 'Only live updating parameters should be bound, make sure you have not missed .live in the path to the parameter!'
99
+ end
100
+ @parameter_bound_bits ||= {}
101
+ @parameter_bound_bits[bitname] = live_parameter
102
+ end
103
+
104
+ def has_parameter_bound_bits?
105
+ @parameter_bound_bits && !@parameter_bound_bits.empty?
106
+ end
107
+
108
+ def update_bound_bits
109
+ @updating_bound_bits = true
110
+ @parameter_bound_bits.each do |name, val|
111
+ bits(name).write(val)
112
+ end
113
+ @updating_bound_bits = false
114
+ end
115
+
116
+ def updating_bound_bits?
117
+ @updating_bound_bits
118
+ end
119
+
120
+ def inspect
121
+ bit_width = 13
122
+ desc = ["\n0x%X - :#{name}" % address]
123
+ desc << ' ' + ('=' * (bit_width + 1) * 8)
124
+
125
+ # "<#{self.class}: #{self.name}>"
126
+ (size / 8).times do |byte_index|
127
+ # Need to add support for little endian regs here?
128
+ byte_number = (size / 8) - byte_index
129
+ max_bit = size - (byte_index * 8) - 1
130
+ min_bit = max_bit - 8 + 1
131
+
132
+ line = ' '
133
+ # BIT INDEX ROW
134
+ 8.times do |i|
135
+ line << '|' + "#{size - i - 1 - (byte_index * 8)}".center(bit_width)
136
+ end
137
+ line += '|'
138
+ desc << line
139
+
140
+ # BIT NAME ROW
141
+ line = ' '
142
+ named_bits include_spacers: true do |name, bit, bitcounter|
143
+ if _bit_in_range?(bit, max_bit, min_bit)
144
+ if bit.size > 1
145
+
146
+ if name
147
+ if bitcounter.nil?
148
+ bit_name = "#{name}[#{_max_bit_in_range(bit, max_bit, min_bit)}:#{_min_bit_in_range(bit, max_bit, min_bit)}]"
149
+ bit_span = _num_bits_in_range(bit, max_bit, min_bit)
150
+
151
+ else
152
+ upper = _max_bit_in_range(bit, max_bit, min_bit) + bitcounter - bit.size
153
+ lower = _min_bit_in_range(bit, max_bit, min_bit) + bitcounter - bit.size
154
+ bit_name = "#{name}[#{upper}:#{lower}]"
155
+ bit_span = upper - lower + 1
156
+ end
157
+ width = bit_width * bit_span
158
+ line << '|' + ":#{bit_name[0..width - 2]}".center(width + bit_span - 1)
159
+
160
+ else
161
+ bit.shift_out_left do |bit|
162
+ if _index_in_range?(bit.position, max_bit, min_bit)
163
+ line << '|' + ''.center(bit_width)
164
+ end
165
+ end
166
+ end
167
+
168
+ else
169
+ bit_name = "#{name}"
170
+ line << '|' + ":#{bit_name[0..bit_width - 2]}".center(bit_width)
171
+ end
172
+ end
173
+ end
174
+ line += '|'
175
+ desc << line
176
+
177
+ ## BIT ACCESS ROW
178
+ # line = "Access "
179
+ # self.named_bits :include_spacers => true do |name, bit|
180
+ # if _bit_in_range?(bit, max_bit, min_bit)
181
+ # if bit.size > 1
182
+ # if name
183
+ # access = _bit_rw(bit)
184
+ # bit_span = _num_bits_in_range(bit, max_bit, min_bit)
185
+ # width = bit_width * bit_span
186
+ # line << "|" + access.center(width + bit_span - 1)
187
+ # else
188
+ # bit.shift_out_left do |bit|
189
+ # if _index_in_range?(bit.position, max_bit, min_bit)
190
+ # line << "|" + "".center(bit_width)
191
+ # end
192
+ # end
193
+ # end
194
+ # else
195
+ # access = _bit_rw(bit)
196
+ # line << "|" + access.center(bit_width)
197
+ # end
198
+ # end
199
+ # end
200
+ # line += "|"
201
+ # desc << line
202
+
203
+ ## BIT RESET ROW
204
+ # line = "Reset "
205
+ # self.named_bits :include_spacers => true do |name, bit|
206
+ # if _bit_in_range?(bit, max_bit, min_bit)
207
+ # if bit.size > 1
208
+ # if name
209
+ # value = "0x%X" % bit.reset_val[_max_bit_in_range(bit, max_bit, min_bit).._min_bit_in_range(bit, max_bit, min_bit)]
210
+ # bit_span = _num_bits_in_range(bit, max_bit, min_bit)
211
+ # width = bit_width * bit_span
212
+ # line << "|" + value.center(width + bit_span - 1)
213
+ # else
214
+ # bit.shift_out_left do |bit|
215
+ # if _index_in_range?(bit.position, max_bit, min_bit)
216
+ # line << "|" + "".center(bit_width)
217
+ # end
218
+ # end
219
+ # end
220
+ # else
221
+ # line << "|" + "#{bit.reset_val}".center(bit_width)
222
+ # end
223
+ # end
224
+ # end
225
+ # line += "|"
226
+ # desc << line
227
+
228
+ # BIT STATE ROW
229
+ line = ' '
230
+ named_bits include_spacers: true do |name, bit, _bitcounter|
231
+ if _bit_in_range?(bit, max_bit, min_bit)
232
+ if bit.size > 1
233
+ if name
234
+ if bit.has_known_value?
235
+ value = '0x%X' % bit.val[_max_bit_in_range(bit, max_bit, min_bit).._min_bit_in_range(bit, max_bit, min_bit)]
236
+ else
237
+ if bit.reset_val == :undefined
238
+ value = 'X'
239
+ else
240
+ value = 'M'
241
+ end
242
+ end
243
+ value += _state_desc(bit)
244
+ bit_span = _num_bits_in_range(bit, max_bit, min_bit)
245
+ width = bit_width * bit_span
246
+ line << '|' + value.center(width + bit_span - 1)
247
+ else
248
+ bit.shift_out_left do |bit|
249
+ if _index_in_range?(bit.position, max_bit, min_bit)
250
+ line << '|' + ''.center(bit_width)
251
+ end
252
+ end
253
+ end
254
+ else
255
+ if bit.has_known_value?
256
+ val = bit.val
257
+ else
258
+ if bit.reset_val == :undefined
259
+ val = 'X'
260
+ else
261
+ val = 'M'
262
+ end
263
+ end
264
+ value = "#{val}" + _state_desc(bit)
265
+ line << '|' + value.center(bit_width)
266
+ end
267
+ end
268
+ end
269
+ line += '|'
270
+ desc << line
271
+
272
+ desc << ' ' + ('-' * (bit_width + 1) * 8)
273
+ end
274
+ desc.join("\n")
275
+ end
276
+
277
+ # Returns a hash containing all register descriptions that have been parsed so far.
278
+ #
279
+ # @api private
280
+ def description_lookup
281
+ @@description_lookup ||= {}
282
+ end
283
+
284
+ # Returns any application specific metadata that has been inherited by the
285
+ # given register.
286
+ # This does not account for any overridding that may have been applied to
287
+ # this register specifically however, use the meta method to get that.
288
+ def default_reg_metadata
289
+ Origen::Registers.default_reg_metadata.merge(
290
+ Origen::Registers.reg_metadata[owner.class] || {})
291
+ end
292
+
293
+ def bit_value_descriptions(bitname, options = {})
294
+ options = {
295
+ format: :binary
296
+ }.merge(options)
297
+ base = case options[:format]
298
+ when :bin, :binary
299
+ 2
300
+ when :hex, :hexadecimal
301
+ 16
302
+ when :dec, :decimal
303
+ 10
304
+ else
305
+ fail "Unknown integer format: #{options[:format]}"
306
+ end
307
+ desc = {}
308
+ description(bitname).each do |line|
309
+ if line =~ /^\s*(\d+)\s+\|\s+(.+)/
310
+ desc[Regexp.last_match[1].to_i(base)] = Regexp.last_match[2]
311
+ end
312
+ end
313
+ desc
314
+ end
315
+
316
+ # Returns the full name of the register when this has been specified in the register
317
+ # description like this:
318
+ #
319
+ # # ** This is the Register Full Name **
320
+ # # This register blah blah
321
+ #
322
+ # This method will also be called by bit collections to look up the name when
323
+ # defined in a similar manner in the bit description.
324
+ #
325
+ # If no name has been specified this will return nil.
326
+ def full_name(bitname = :_reg, _options = {})
327
+ bitname, options = :_reg, bitname if bitname.is_a?(Hash)
328
+ desc = description(bitname).first
329
+ # Capture something like this:
330
+ # ** This is the full name ** - This bit blah blah
331
+ if desc && desc =~ /\s*\*\*\s*([^\*.]*)\s*\*\*/
332
+ Regexp.last_match[1].strip
333
+ end
334
+ end
335
+
336
+ # Escapes brackets and parenthesis. Helper for description method.
337
+ def escape_special_char(str)
338
+ str.gsub('[', '\[').gsub(']', '\]').gsub('(', '\(').gsub(')', '\)') if str
339
+ end
340
+
341
+ # Returns the description of this register if any, if none then an empty array
342
+ # will be returned
343
+ #
344
+ # **Note** Adding a description field will override any comment-driven documentation
345
+ # of a register (ie markdown style comments)
346
+ def description(bitname = :_reg, options = {})
347
+ bitname, options = :_reg, bitname if bitname.is_a?(Hash)
348
+ options = {
349
+ include_name: true,
350
+ include_bit_values: true
351
+ }.merge(options)
352
+ if @description_from_api[bitname]
353
+ desc = @description_from_api[bitname]
354
+ else
355
+ parse_descriptions unless description_lookup[define_file]
356
+ begin
357
+ desc = description_lookup[define_file][name][bitname] || []
358
+ rescue
359
+ desc = []
360
+ end
361
+ end
362
+ desc = desc.reject do |line|
363
+ if bitname != :_reg
364
+ unless options[:include_bit_values]
365
+ !!(line =~ /^\s*(\d+)\s+\|\s+(.+)/)
366
+ end
367
+ else
368
+ false
369
+ end
370
+ end
371
+ if desc.first
372
+ unless options[:include_name]
373
+ desc[0] = desc.first.sub(/\s*\*\*\s*#{escape_special_char(full_name(bitname))}\s*\*\*\s*-?\s*/, '')
374
+ end
375
+ end
376
+ desc.shift if desc.first && desc.first.strip.empty?
377
+ desc.pop if desc.last && desc.last.strip.empty?
378
+ desc
379
+ end
380
+ alias_method :descriptions, :description
381
+
382
+ # @api private
383
+ def parse_descriptions
384
+ desc = []
385
+ File.readlines(define_file).each do |line|
386
+ if line =~ /^\s*#(.*)/
387
+ desc << Regexp.last_match[1].strip
388
+ elsif line =~ /^\s*(add_reg|reg)\(?\s*:(\w+)\s*,.*do/
389
+ @current_reg_name = Regexp.last_match[2].to_sym
390
+ description_lookup[define_file] ||= {}
391
+ description_lookup[define_file][@current_reg_name] ||= {}
392
+ description_lookup[define_file][@current_reg_name][:_reg] = desc.dup
393
+ desc = []
394
+ # http://www.rubular.com/r/7FidbC1JRA
395
+ elsif @current_reg_name && line =~ /^\s*(add_bit|bit|reg\.bit)s?\(?\s*\d+\.?\.?\d*\s*,\s*:(\w+)/
396
+ description_lookup[define_file][@current_reg_name][Regexp.last_match[2].to_sym] = desc.dup
397
+ desc = []
398
+ else
399
+ desc = []
400
+ end
401
+ end
402
+ end
403
+
404
+ def contains_bits?
405
+ true
406
+ end
407
+
408
+ # @api private
409
+ def add_bits_from_options(options = {}) # :nodoc:
410
+ # edit Traynor
411
+ # options is now an array for split bit groups or a hash if single bit/range bits
412
+ # Now add the requested bits to the register, removing the unwritable bits as required
413
+ options.each do |bit_id, bit_params|
414
+ if bit_params.is_a? Hash
415
+ description = bit_params.delete(:description)
416
+ if description
417
+ @description_from_api[bit_id] = description.split(/\r?\n/)
418
+ end
419
+ bind(bit_id, bit_params.delete(:bind)) if bit_params[:bind]
420
+ position = bit_params[:pos] || 0
421
+ num_bits = bit_params[:bits] || 1
422
+ if @reset
423
+ if @reset.is_a?(Symbol)
424
+ bit_params[:res] = @reset
425
+ else
426
+ bit_params[:res] = @reset[(num_bits + position - 1), position]
427
+ end
428
+ end
429
+ bit_params[:access] = @access if bit_params[:access].nil?
430
+ bit_params[:res] = bit_params[:data] if bit_params[:data]
431
+ bit_params[:res] = bit_params[:reset] if bit_params[:reset]
432
+ if num_bits == 1
433
+ add_bit(bit_id, position, bit_params) # and add the new one
434
+ else
435
+ add_bus(bit_id, position, num_bits, bit_params)
436
+ end
437
+ elsif bit_params.is_a? Array
438
+
439
+ description = bit_params.map { |h| h.delete(:description) }.compact.join("\n")
440
+ unless description.empty?
441
+ @description_from_api[bit_id] = description.split(/\r?\n/)
442
+ end
443
+ add_bus_scramble(bit_id, bit_params)
444
+ end
445
+ end
446
+ self
447
+ end
448
+
449
+ # This method is called whenever reg.clone is called to make a copy of a given register.
450
+ # Ruby will correctly copy all instance variables but it will not drill down to copy nested
451
+ # attributes, like the bits contained in @bits.
452
+ # This function will therefore correctly clone all bits contained in the register also.
453
+ def initialize_copy(orig) # :nodoc:
454
+ @bits = []
455
+ orig.bits.each do |bit|
456
+ @bits << bit.clone
457
+ end
458
+ @lookup = orig.lookup.clone
459
+ self
460
+ end
461
+
462
+ # Returns a dummy register object that can be used on the fly, this can sometimes
463
+ # be useful to configure an intricate read operation.
464
+ # ==== Example
465
+ # # Read bit 5 of RAM address 0xFFFF1280
466
+ # dummy = Reg.dummy # Create a dummy reg to configure the read operation
467
+ # dummy.address = 0xFFFF1280 # Set the address
468
+ # dummy.bit(5).read!(1) # Read bit 5 expecting a 1
469
+ def self.dummy(size = 16)
470
+ Reg.new(self, 0, size, :dummy, init_as_writable: true)
471
+ end
472
+
473
+ # Returns each named bit collection contained in the register,
474
+ def named_bits(options = {})
475
+ options = {
476
+ include_spacers: false
477
+ }.merge(options)
478
+
479
+ # test if @lookup has any values stored as an array
480
+ # if so it means there is a split group of bits
481
+ # process that differently to a single bit or continuous range of bits
482
+ # which are typically stored in a hash
483
+
484
+ split_bits = false
485
+ @lookup.each { |_k, v| split_bits = true if v.is_a? Array }
486
+
487
+ if split_bits == false
488
+ current_pos = size
489
+ # Sort by position descending
490
+ @lookup.sort_by { |_name, details| -details[:pos] }.each do |name, details|
491
+ pos = details[:bits] + details[:pos]
492
+ if options[:include_spacers] && (pos != current_pos)
493
+ collection = BitCollection.dummy(self, nil, size: current_pos - pos, pos: pos)
494
+ yield nil, collection
495
+ end
496
+ collection = BitCollection.new(self, name)
497
+ details[:bits].times do |i|
498
+ collection << @bits[details[:pos] + i]
499
+ end
500
+ yield name, collection
501
+ current_pos = details[:pos]
502
+ end
503
+ if options[:include_spacers] && current_pos != 0
504
+ collection = BitCollection.dummy(self, nil, size: current_pos, pos: 0)
505
+ yield nil, collection
506
+ end
507
+ elsif split_bits == true # if there are split bits, need to convert all regsiter bit values to array elements to allow sorting
508
+
509
+ # if the register has bits split up across it, then store the bits in order of decreasing reg position
510
+ # but first, stuff all the bits in a simple array, as single bits, or ranges of bits
511
+
512
+ @lookup_splits = []
513
+ @lookup.each do |k, v|
514
+ tempbit = {}
515
+ bitcounter = {}
516
+ if v.is_a? Hash
517
+ # then this is already a single bit or a continuous range so just stuff it into the array
518
+ tempbit[k] = v
519
+ @lookup_splits << tempbit.clone
520
+ elsif v.is_a? Array
521
+ # if the bitgroup is split, then decompose into single bits and continuous ranges
522
+ v.each_with_index do |bitdetail, _i|
523
+ if bitcounter.key?(k)
524
+ bitcounter[k] = bitcounter[k] + bitdetail[:bits]
525
+ else
526
+ bitcounter[k] = bitdetail[:bits]
527
+ end
528
+ tempbit[k] = bitdetail
529
+ @lookup_splits << tempbit.clone
530
+ end
531
+ end
532
+ if v.is_a? Array
533
+ @lookup_splits.each_with_index do |_e, q|
534
+ groupname = @lookup_splits[q].to_a[0][0]
535
+ if groupname == k
536
+ @lookup_splits[q][groupname][:bitgrouppos] = bitcounter[groupname] if groupname == k
537
+ bitcounter[groupname] = bitcounter[groupname] - @lookup_splits[q][groupname][:bits]
538
+ end
539
+ end
540
+ end
541
+ end
542
+ # Now sort the array in descending order
543
+ # Does adding the bitgrouppos need to happen after the sort ?
544
+ @lookup_splits = @lookup_splits.sort do |a, b|
545
+ b.to_a[0][1][:pos] <=> a.to_a[0][1][:pos]
546
+ end
547
+
548
+ current_pos = size
549
+ countbits = {} # if countbits.method == nil
550
+
551
+ @master = {}
552
+ bitgroup = {}
553
+ bitinfo = {}
554
+ info = {}
555
+
556
+ @lookup_splits.each_with_index do |hash, _i|
557
+ name = hash.to_a[0][0]
558
+ details = hash.to_a[0][1]
559
+ bitcounter = hash.to_a[0][1][:bitgrouppos]
560
+ pos = details[:bits] + details[:pos]
561
+ if options[:include_spacers] && (pos != current_pos)
562
+ collection = BitCollection.dummy(self, nil, size: current_pos - pos, pos: pos)
563
+ yield nil, collection, bitcounter
564
+ end
565
+ collection = BitCollection.new(self, name)
566
+ details[:bits].times do |i|
567
+ collection << @bits[details[:pos] + i]
568
+ end
569
+ yield name, collection, bitcounter
570
+ current_pos = details[:pos]
571
+ end
572
+ if options[:include_spacers] && current_pos != 0
573
+ collection = BitCollection.dummy(self, nil, size: current_pos, pos: 0)
574
+ yield nil, collection, bitcounter
575
+ end
576
+ end
577
+ end
578
+
579
+ # Returns each named bit collection contained in self
580
+ def reverse_named_bits(_options = {})
581
+ bits = []
582
+ named_bits { |name, bit| bits << [name, bit] }
583
+ bits.each do |bit|
584
+ yield bit[0], bit[1]
585
+ end
586
+ end
587
+
588
+ # Returns an array of occupied bit positions
589
+ # ==== Example
590
+ # reg :fstat, @base + 0x0000, :size => 8 do
591
+ # bit 7, :ccif
592
+ # bit 6, :rdcolerr
593
+ # bit 5, :accerr
594
+ # bit 4, :pviol
595
+ # bit 0, :mgstat0
596
+ # end
597
+ # regs(:fstat).used_bits
598
+ # => [0, 4, 5, 6, 7]
599
+ #
600
+ # ==== Example
601
+ # reg :aguahb2, @base + 0x2A, :size => 8 do
602
+ # bit 5..2, :m0b_hbstrb, :reset => 0x0
603
+ # bit 1..0, :m0b_htrans, :reset => 0x2
604
+ # end
605
+ # regs(:aguahb2).used_bits
606
+ # => [0, 1, 2, 3, 4, 5]
607
+ def used_bits(_options = {})
608
+ used_bits = []
609
+ named_bits do |_name, bit|
610
+ used_bits << bit.position if bit.size == 1
611
+ if bit.size > 1
612
+ used_bits << ((bit.position)..(bit.position + bit.size - 1)).to_a
613
+ end
614
+ end
615
+ used_bits.flatten!
616
+ used_bits.sort!
617
+ used_bits
618
+ end
619
+
620
+ # Returns true if any named_bits exist, false if used_bits is an empty array
621
+ def used_bits?(_options = {})
622
+ used_bits.size > 0
623
+ end
624
+
625
+ # Returns an array of unoccupied bit positions
626
+ # ==== Example
627
+ # reg :fstat, @base + 0x0000, :size => 8 do
628
+ # bit 7, :ccif
629
+ # bit 6, :rdcolerr
630
+ # bit 5, :accerr
631
+ # bit 4, :pviol
632
+ # bit 0, :mgstat0
633
+ # end
634
+ # regs(:fstat).empty_bits
635
+ # => [1, 2, 3]
636
+ #
637
+ # ==== Example
638
+ # reg :aguahb2, @base + 0x2A, :size => 8 do
639
+ # bit 5..2, :m0b_hbstrb, :reset => 0x0
640
+ # bit 1..0, :m0b_htrans, :reset => 0x2
641
+ # end
642
+ # regs(:aguahb2).empty_bits
643
+ # => [6, 7]
644
+ def empty_bits(_options = {})
645
+ array_span = (0..(size - 1)).to_a
646
+ empty_bits = array_span - used_bits
647
+ empty_bits
648
+ end
649
+
650
+ # Returns true if any named_bits exist, false if used_bits is an empty array
651
+ def empty_bits?(_options = {})
652
+ empty_bits.size > 0
653
+ end
654
+
655
+ # Proxies requests from bit collections to the register owner
656
+ def request(operation, options = {}) # :nodoc:
657
+ if operation == :read_register
658
+ object = reader
659
+ owner.read_register_missing!(self) unless object
660
+ else
661
+ object = writer
662
+ owner.write_register_missing!(self) unless object
663
+ end
664
+ object.send(operation, self, options)
665
+ self
666
+ end
667
+
668
+ # Returns the object that will be responsible for writing the given register
669
+ def writer
670
+ @writer ||= lookup_operation_handler(:write_register)
671
+ end
672
+
673
+ # Returns the object that will be responsible for reading the given register
674
+ def reader
675
+ @reader ||= lookup_operation_handler(:read_register)
676
+ end
677
+
678
+ # @api private
679
+ def lookup_operation_handler(operation)
680
+ # Could have made the controller be the owner when assigned above, but may have run
681
+ # into problems with the reg meta data stuff
682
+ reg_owner = owner.respond_to?(:controller) && owner.controller ? owner.controller : owner
683
+ if reg_owner.respond_to?(operation)
684
+ reg_owner
685
+ elsif reg_owner.respond_to?(:owner) && reg_owner.owner.respond_to?(operation)
686
+ reg_owner.owner
687
+ elsif Origen.top_level && Origen.top_level.respond_to?(operation)
688
+ Origen.top_level
689
+ end
690
+ end
691
+
692
+ # Returns the relative address of the given register, equivalent to calling
693
+ # reg.address(:relative => true)
694
+ def offset
695
+ address(relative: true)
696
+ end
697
+
698
+ # Returns the register address added to its current base_address value (if any).
699
+ #
700
+ # @param [Hash] options
701
+ # @option options [Boolean] :relative (false) Return the address without adding the base address (if present)
702
+ def address(options = {})
703
+ options = {
704
+ relative: false
705
+ }.merge(options)
706
+ address = @address
707
+ domain_option = options[:domains] || options[:domain]
708
+ @domain_option ||= domain_option unless frozen?
709
+ # Blow the cache when the domain option changes
710
+ @base_address_applied = nil unless @domain_option == domain_option
711
+ unless @base_address_applied
712
+ # Give highest priority to the original API which allowed the object
713
+ # doing register read/write to define a base_address method
714
+ if (writer && writer.methods.include?(:base_address) && writer.method(:base_address).arity != 0) ||
715
+ (reader && reader.methods.include?(:base_address) && reader.method(:base_address).arity != 0)
716
+ # This currently assumes that the base address is always the same
717
+ # for reading and writing
718
+ if writer && writer.respond_to?(:base_address) && writer.method(:base_address).arity != 0
719
+ self.base_address = writer.base_address(self)
720
+ elsif reader && reader.respond_to?(:base_address) && reader.method(:base_address).arity != 0
721
+ self.base_address = reader.base_address(self)
722
+ end
723
+ else
724
+ o = owner.is_a?(Container) ? owner.owner : owner
725
+ d = domain_option || domains
726
+ if o && o.reg_base_address(domain: d)
727
+ self.base_address = o.reg_base_address(domain: d)
728
+ end
729
+ end
730
+ @base_address_applied = true
731
+ end
732
+ unless options[:relative]
733
+ address += base_address if base_address
734
+ end
735
+ if options[:address_type]
736
+ Origen.deprecate 'Specifying the address_type of a register address will be removed from Origen 3'
737
+ case options[:address_type]
738
+ when :byte
739
+ address = address * 2
740
+ when :word
741
+ address = address
742
+ when :longword
743
+ address = address / 2
744
+ else
745
+ fail 'Unknown address type requested!'
746
+ end
747
+ end
748
+ address
749
+ end
750
+ alias_method :addr, :address
751
+
752
+ # Returns true if the register owner matches the given name. A match will be detected
753
+ # if the class names of the register's owner contains the given name.
754
+ #
755
+ # Alternatively if the register owner implements a method called reg_owner_alias
756
+ # then the value that this returns instead will also be considered when checking if the given
757
+ # name matches. This method can return an array of names if multiple aliases are required.
758
+ #
759
+ # Aliases can be useful for de-coupling the commonly used name, e.g. "NVM" from the actual
760
+ # class name.
761
+ #
762
+ # @example
763
+ # class C90NVM
764
+ # include Origen::Registers
765
+ #
766
+ # def initialize
767
+ # add_reg :clkdiv, 0x3, 16, :div => {:bits => 8}
768
+ # end
769
+ #
770
+ # end
771
+ #
772
+ # reg = C90NVM.new.reg(:clkdiv)
773
+ # reg.owned_by?(:ram) # => false
774
+ # reg.owned_by?(:nvm) # => true
775
+ # reg.owned_by?(:c90nvm) # => true
776
+ # reg.owned_by?(:c40nvm) # => false
777
+ # reg.owned_by?(:flash) # => false
778
+ #
779
+ # @example Using an alias
780
+ # class C90NVM
781
+ # include Origen::Registers
782
+ #
783
+ # def initialize
784
+ # add_reg :clkdiv, 0x3, 16, :div => {:bits => 8}
785
+ # end
786
+ #
787
+ # def reg_owner_alias
788
+ # "flash"
789
+ # end
790
+ #
791
+ # end
792
+ #
793
+ # reg = C90NVM.new.reg(:clkdiv)
794
+ # reg.owned_by?(:ram) # => false
795
+ # reg.owned_by?(:nvm) # => true
796
+ # reg.owned_by?(:c90nvm) # => true
797
+ # reg.owned_by?(:c40nvm) # => false
798
+ # reg.owned_by?(:flash) # => true
799
+ def owned_by?(name)
800
+ !!(owner.class.to_s =~ /#{name}/i) || begin
801
+ if owner.respond_to?(:reg_owner_alias)
802
+ [owner.reg_owner_alias].flatten.any? do |al|
803
+ al.to_s =~ /#{name}/i
804
+ end
805
+ else
806
+ false
807
+ end
808
+ end
809
+ end
810
+
811
+ # Returns true if the register contains a bit(s) matching the given name
812
+ # ==== Example
813
+ # add_reg :control, 0x55, :status => {:pos => 1}
814
+ #
815
+ # reg(:control).has_bit?(:result) # => false
816
+ # reg(:control).has_bit?(:status) # => true
817
+ def has_bit?(name)
818
+ @lookup.include?(name)
819
+ end
820
+ alias_method :has_bits?, :has_bit?
821
+ alias_method :has_bit, :has_bit?
822
+ alias_method :has_bits, :has_bit?
823
+
824
+ # Add a bit to the register, should only be called internally
825
+ def add_bit(id, position, options = {}) # :nodoc:
826
+ options = { data: @bits[position].data, # If undefined preserve any data/reset value that has
827
+ res: @bits[position].data, # already been applied at reg level
828
+ }.merge(options)
829
+
830
+ @lookup[id] = { pos: position, bits: 1, feature: options[:feature] }
831
+ @bits.delete_at(position) # Remove the initial bit from this position
832
+
833
+ @bits.insert(position, Bit.new(self, position, options))
834
+ self
835
+ end
836
+
837
+ # Add a bus to the register, should only be called internally
838
+ def add_bus(id, position, size, options = {}) # :nodoc:
839
+ default_data = 0
840
+ size.times do |n|
841
+ default_data |= @bits[position + n].data << n
842
+ end
843
+ options = { data: default_data, # If undefined preserve any data/reset value that has
844
+ res: default_data, # already been applied at reg level
845
+ }.merge(options)
846
+
847
+ @lookup[id] = { pos: position, bits: size }
848
+ size.times do |n|
849
+ bit_options = options.dup
850
+ bit_options[:data] = options[:data][n]
851
+ if options[:res].is_a?(Symbol)
852
+ bit_options[:res] = options[:res]
853
+ else
854
+ bit_options[:res] = options[:res][n]
855
+ end
856
+ @bits.delete_at(position + n)
857
+ @bits.insert(position + n, Bit.new(self, position + n, bit_options))
858
+ end
859
+ self
860
+ end
861
+
862
+ def add_bus_scramble(id, array_of_hashes = [])
863
+ array_of_hashes.each do |options|
864
+ bind(id, options.delete(:bind)) if options[:bind]
865
+ position = options[:pos] || 0
866
+ num_bits = options[:bits] || 1
867
+ size = options[:bits]
868
+ options[:data] = options[:data] if options[:data]
869
+ options[:res] = options[:reset] if options[:reset]
870
+ default_data = 0
871
+ size.times do |n|
872
+ default_data |= @bits[position + n].data << n
873
+ end
874
+ options = { data: default_data, # If undefined preserve any data/reset value that has
875
+ res: default_data, # already been applied at reg level
876
+ }.merge(options)
877
+
878
+ @lookup[id] = [] if @lookup[id].nil?
879
+ @lookup[id] = @lookup[id].push(pos: position, bits: size)
880
+ size.times do |n|
881
+ bit_options = options.dup
882
+ bit_options[:data] = options[:data][n]
883
+ bit_options[:res] = options[:res][n]
884
+ @bits.delete_at(position + n)
885
+ @bits.insert(position + n, Bit.new(self, position + n, bit_options))
886
+ end
887
+ self
888
+ end
889
+ end
890
+
891
+ # Delete the bits in the collection from the register
892
+ def delete_bit(collection)
893
+ [collection.name].flatten.each do |name|
894
+ @lookup.delete(name)
895
+ end
896
+ collection.each do |bit|
897
+ @bits.delete_at(bit.position) # Remove the bit
898
+ @bits.insert(bit.position, Bit.new(self, bit.position, writable: @init_as_writable))
899
+ end
900
+ self
901
+ end
902
+ alias_method :delete_bits, :delete_bit
903
+
904
+ # @api private
905
+ def expand_range(range)
906
+ if range.first > range.last
907
+ range = Range.new(range.last, range.first)
908
+ end
909
+ range.each do |i|
910
+ yield i
911
+ end
912
+ end
913
+
914
+ # Returns the bit object(s) responding to the given name, wrapped in a BitCollection.
915
+ # This method also accepts multiple name possibilities, if neither bit exists in
916
+ # the register it will raise an error, otherwise it will return the first match.
917
+ # If no args passed in, it will return a BitCollection containing all bits.
918
+ # If a number is passed in then the bits from those positions are returned.
919
+ # ==== Example
920
+ # add_reg :control, 0x55, :status => {:pos => 1, :bits => 2},
921
+ # :fail => {:pos => 0}
922
+ #
923
+ # reg(:control).bit(:fail) # => Returns a BitCollection containing the fail bit
924
+ # reg(:control).bits(:status) # => Returns a BifCollection containing the status bits
925
+ # reg(:control).bit(:bist_fail, :fail) # => Returns a BitCollection containing the fail bit
926
+ # reg(:control).bit(0) # => Returns a BitCollection containing the fail bit
927
+ # reg(:control).bit(1) # => Returns a BitCollection containing status bit
928
+ # reg(:control).bit(1,2) # => Returns a BitCollection containing both status bits
929
+ def bit(*args)
930
+ # return get_bits_with_constraint(nil,:default) if args.size == 0
931
+ constraint = extract_feature_params(args)
932
+ if constraint.nil?
933
+ constraint = :default
934
+ end
935
+ collection = BitCollection.new(self, :unknown)
936
+ if args.size == 0
937
+ collection.add_name(name)
938
+ @bits.each do |bit|
939
+ collection << get_bits_with_constraint(bit.position, constraint)
940
+ end
941
+ else
942
+ args.flatten!
943
+ args.sort!
944
+ args.each do |arg_item|
945
+ if arg_item.is_a?(Fixnum)
946
+ b = get_bits_with_constraint(arg_item, constraint)
947
+ collection << b if b
948
+ elsif arg_item.is_a?(Range)
949
+ expand_range(arg_item) do |bit_number|
950
+ collection << get_bits_with_constraint(bit_number, constraint)
951
+ end
952
+ else
953
+ # Reaches here if bit name is specified
954
+
955
+ if @lookup.include?(arg_item)
956
+ split_bits = false
957
+ @lookup.each { |_k, v| split_bits = true if v.is_a? Array }
958
+ coll = get_lookup_feature_bits(arg_item, constraint, split_bits)
959
+ if coll
960
+ coll.each do |b|
961
+ collection.add_name(arg_item)
962
+ collection << b
963
+ end
964
+ end
965
+ end
966
+ end
967
+ end
968
+ end
969
+ if collection.size == 0
970
+ # Originally Origen returned nil when asking for a bit via an index which does not
971
+ # exist, e.g. reg[1000] => nil
972
+ # The args numeric clause here is to maintain that behavior
973
+ if Origen.config.strict_errors && !args.all? { |arg| arg.is_a?(Numeric) }
974
+ puts "Register #{@name} does not have a bits(s) named :#{args.join(', :')} or it might not be enabled."
975
+ puts 'This could also be a typo, these are the valid bit names:'
976
+ puts @lookup.keys
977
+ fail 'Missing bits error!'
978
+ end
979
+ nil
980
+ else
981
+ collection
982
+ end
983
+ end
984
+ alias_method :bits, :bit
985
+ alias_method :[], :bit
986
+
987
+ def get_bits_with_constraint(number, params)
988
+ return nil unless @bits[number]
989
+ if (params == :default || !params) && @bits[number].enabled?
990
+ @bits[number]
991
+ elsif params == :none && !@bits[number].has_feature_constraint?
992
+ @bits[number]
993
+ elsif params == :all
994
+ @bits[number]
995
+ elsif params.class == Array
996
+ params.each do |param|
997
+ unless @bits[number].enabled_by_feature?(param)
998
+ return nil
999
+ end
1000
+ @bits[number]
1001
+ end
1002
+ elsif @bits[number].enabled_by_feature?(params)
1003
+ @bits[number]
1004
+ else
1005
+ return Bit.new(self, number, writable: false)
1006
+ end
1007
+ end
1008
+
1009
+ def get_lookup_feature_bits(bit_name, params, split_group_reg)
1010
+ ##
1011
+ if split_group_reg == false # if this register has single bits and continuous ranges
1012
+
1013
+ if @lookup.include?(bit_name)
1014
+ collection = BitCollection.new(self, bit_name)
1015
+ (@lookup[bit_name][:bits]).times do |i|
1016
+ collection << @bits[@lookup[bit_name][:pos] + i]
1017
+ end
1018
+ if !params || params == :default
1019
+ if collection.enabled?
1020
+ return collection
1021
+ end
1022
+ elsif params == :none
1023
+ unless collection.has_feature_constraint?
1024
+ return collection
1025
+ end
1026
+ elsif params == :all
1027
+ return collection
1028
+ elsif params.class == Array
1029
+ if params.all? { |param| collection.enabled_by_feature?(param) }
1030
+ return collection
1031
+ end
1032
+ else
1033
+ if collection.enabled_by_feature?(params)
1034
+ return collection
1035
+ end
1036
+ end
1037
+ return BitCollection.dummy(self, bit_name, size: collection.size, pos: @lookup[bit_name][:pos])
1038
+ else
1039
+ return []
1040
+ end
1041
+
1042
+ elsif split_group_reg == true # if this registers has split bits in its range
1043
+ if @lookup.is_a?(Hash) # && @lookup.include?(bit_name)
1044
+ collection = false
1045
+ @lookup.each do |k, v| # k is the bitname, v is the hash of bit data
1046
+ if k == bit_name
1047
+ collection ||= BitCollection.new(self, k)
1048
+ if v.is_a?(Array)
1049
+ v.reverse_each do |pb| # loop each piece of bit group data
1050
+ (pb[:bits]).times do |i|
1051
+ collection << @bits[pb[:pos] + i]
1052
+ end
1053
+ end
1054
+ else
1055
+ (v[:bits]).times do |i|
1056
+ collection << @bits[v[:pos] + i]
1057
+ end
1058
+ end
1059
+ end
1060
+ end
1061
+ if !params || params == :default
1062
+ if collection.enabled?
1063
+ return collection
1064
+ end
1065
+ elsif params == :none
1066
+ unless collection.has_feature_constraint?
1067
+ return collection
1068
+ end
1069
+ elsif params == :all
1070
+ return collection
1071
+ elsif params.class == Array
1072
+ if params.all? { |param| collection.enabled_by_feature?(param) }
1073
+ return collection
1074
+ end
1075
+ else
1076
+ if collection.enabled_by_feature?(params)
1077
+ return collection
1078
+ end
1079
+ end
1080
+ if @lookup.is_a?(Hash) && @lookup[bit_name].is_a?(Array)
1081
+ return BitCollection.dummy(self, bit_name, size: collection.size, pos: @lookup[bit_name][0][:pos])
1082
+ else
1083
+ return BitCollection.dummy(self, bit_name, size: collection.size, pos: @lookup[bit_name[:pos]])
1084
+ end
1085
+ else
1086
+ return []
1087
+ end
1088
+ end
1089
+ end
1090
+
1091
+ def extract_feature_params(args)
1092
+ index = args.find_index { |arg| arg.class == Hash }
1093
+ if index
1094
+ params = args.delete_at(index)
1095
+ else
1096
+ params = nil
1097
+ end
1098
+
1099
+ if params
1100
+ return params[:enabled_features] || params[:enabled_feature]
1101
+ else
1102
+ return nil
1103
+ end
1104
+ end
1105
+
1106
+ # All other Reg methods are delegated to BitCollection
1107
+ def method_missing(method, *args, &block) # :nodoc:
1108
+ if method.to_sym == :to_ary || method.to_sym == :to_hash
1109
+ nil
1110
+ elsif meta_data_method?(method)
1111
+ extract_meta_data(method, *args)
1112
+ else
1113
+ if BitCollection.instance_methods.include?(method)
1114
+ BitCollection.new(self, name, @bits).send(method, *args, &block)
1115
+ elsif has_bits?(method)
1116
+ bits(method)
1117
+ else
1118
+ super
1119
+ end
1120
+ end
1121
+ end
1122
+
1123
+ # Recognize that Reg responds to all BitCollection methods methods based on
1124
+ # application-specific meta data properties
1125
+ def respond_to?(sym) # :nodoc:
1126
+ sym = sym.to_sym
1127
+ meta_data_method?(sym) || has_bits?(sym) || super(sym) || BitCollection.instance_methods.include?(sym)
1128
+ end
1129
+
1130
+ # Copy overlays from one reg object to another
1131
+ # ==== Example
1132
+ # reg(:data_copy).has_overlay? # => false
1133
+ # reg(:data).overlay("data_val")
1134
+ # reg(:data_copy).copy_overlays_from(reg(:data))
1135
+ # reg(:data_copy).has_overlay? # => true
1136
+ def copy_overlays_from(reg, options = {})
1137
+ size.times do |i|
1138
+ source_bit = reg.bit[i]
1139
+ if source_bit.has_overlay?
1140
+ ov = source_bit.overlay_str
1141
+ # If an id has been supplied make sure any trailing ID in the source is
1142
+ # changed to supplied identifier
1143
+ ov.gsub!(/_\d$/, "_#{options[:update_id]}") if options[:update_id]
1144
+ @bits[i].overlay(ov)
1145
+ end
1146
+ end
1147
+ self
1148
+ end
1149
+
1150
+ # Copies data from one reg object to another
1151
+ # ==== Example
1152
+ # reg(:data_copy).data # => 0
1153
+ # reg(:data).write(0x1234)
1154
+ # reg(:data_copy).copy_data_from(reg(:data))
1155
+ # reg(:data_copy).data # => 0x1234
1156
+ def copy_data_from(reg)
1157
+ size.times do |i|
1158
+ @bits[i].write(reg.bit[i].data)
1159
+ end
1160
+ self
1161
+ end
1162
+
1163
+ # Copies data and overlays from one reg object to another, it does not copy
1164
+ # read or store flags
1165
+ def copy(reg)
1166
+ size.times do |i|
1167
+ source_bit = reg.bit[i]
1168
+ @bits[i].overlay(source_bit.overlay_str) if source_bit.has_overlay?
1169
+ @bits[i].write(source_bit.data)
1170
+ end
1171
+ self
1172
+ end
1173
+
1174
+ # Returns the BITWISE AND of reg with another reg or a number, the state of
1175
+ # both registers remains unchanged
1176
+ # ==== Example
1177
+ # reg(:data).write(0x5555)
1178
+ # reg(:data2).write(0xFFFF)
1179
+ # reg(:data) & 0xFF00 # => 0x5500
1180
+ # reg(:data) & reg(:data2) # => 0x5555
1181
+ def &(val)
1182
+ data & Reg.clean_value(val)
1183
+ end
1184
+
1185
+ # Returns the BITWISE OR of reg with another reg or a number, the state of
1186
+ # both registers remains unchanged
1187
+ def |(val)
1188
+ data | Reg.clean_value(val)
1189
+ end
1190
+
1191
+ # Returns the SUM of reg with another reg or a number, the state of
1192
+ # both registers remains unchanged
1193
+ def +(val)
1194
+ data + Reg.clean_value(val)
1195
+ end
1196
+
1197
+ # Returns the SUBTRACTION of reg with another reg or a number, the state of
1198
+ # both registers remains unchanged
1199
+ def -(val)
1200
+ data - Reg.clean_value(val)
1201
+ end
1202
+
1203
+ # Returns the DIVISION of reg with another reg or a number, the state of
1204
+ # both registers remains unchanged
1205
+ def /(val)
1206
+ data / Reg.clean_value(val)
1207
+ end
1208
+
1209
+ # Returns the PRODUCT of reg with another reg or a number, the state of
1210
+ # both registers remains unchanged
1211
+ def *(val)
1212
+ data * Reg.clean_value(val)
1213
+ end
1214
+
1215
+ # Cleans an input value, in some cases it could be a register object, or an explicit value.
1216
+ # This will return an explicit value in either case.
1217
+ def self.clean_value(value) # :nodoc:
1218
+ value = value.val if value.respond_to?('val') # Pull out the data value if a reg object has been passed in
1219
+ value
1220
+ end
1221
+
1222
+ # @api private
1223
+ def meta_data_method?(method)
1224
+ attr_name = method.to_s.gsub(/\??=?/, '').to_sym
1225
+ if default_reg_metadata.key?(attr_name)
1226
+ if method.to_s =~ /\?/
1227
+ [true, false].include?(default_reg_metadata[attr_name])
1228
+ else
1229
+ true
1230
+ end
1231
+ else
1232
+ false
1233
+ end
1234
+ end
1235
+
1236
+ def extract_meta_data(method, *args)
1237
+ method = method.to_s.sub('?', '')
1238
+ if method =~ /=/
1239
+ instance_variable_set("@#{method.sub('=', '')}", args.first)
1240
+ else
1241
+ instance_variable_get("@#{method}") || meta[method.to_sym]
1242
+ end
1243
+ end
1244
+
1245
+ # Returns true if the register is constrained by the given/any feature
1246
+ def enabled_by_feature?(name = nil)
1247
+ if !name
1248
+ !!feature
1249
+ else
1250
+ if feature.class == Array
1251
+ feature.each do |f|
1252
+ if f == name
1253
+ return true
1254
+ end
1255
+ end
1256
+ return false
1257
+ else
1258
+ return feature == name
1259
+ end
1260
+ end
1261
+ end
1262
+ alias_method :has_feature_constraint?, :enabled_by_feature?
1263
+
1264
+ # Query the owner heirarchy to see if this register is enabled
1265
+ def enabled?
1266
+ if feature
1267
+ value = false
1268
+ current_owner = self
1269
+ if feature.class == Array
1270
+ feature.each do |f|
1271
+ current_owner = self
1272
+ loop do
1273
+ if current_owner.respond_to?(:owner)
1274
+ current_owner = current_owner.owner
1275
+ if current_owner.respond_to?(:has_feature?)
1276
+ if current_owner.has_feature?(f)
1277
+ value = true
1278
+ break
1279
+ end
1280
+ end
1281
+ else # if current owner does not have a owner
1282
+ value = false
1283
+ break
1284
+ end
1285
+ end # loop end
1286
+ unless value
1287
+ if Origen.top_level && \
1288
+ Origen.top_level.respond_to?(:has_feature?) && \
1289
+ Origen.top_level.has_feature?(f)
1290
+ value = true
1291
+ unless value
1292
+ break
1293
+ end
1294
+ end
1295
+ end
1296
+ unless value
1297
+ break # break if feature not found and return false
1298
+ end
1299
+ end # iterated through all features in array
1300
+ return value
1301
+ else # if feature.class != Array
1302
+ loop do
1303
+ if current_owner.respond_to?(:owner)
1304
+ current_owner = current_owner.owner
1305
+ if current_owner.respond_to?(:has_feature?)
1306
+ if current_owner.has_feature?(feature)
1307
+ value = true
1308
+ break
1309
+ end
1310
+ end
1311
+ else # if current owner does not have a owner
1312
+ value = false
1313
+ break
1314
+ end
1315
+ end # loop end
1316
+ unless value
1317
+ if Origen.top_level && \
1318
+ Origen.top_level.respond_to?(:has_feature?) && \
1319
+ Origen.top_level.has_feature?(feature)
1320
+ value = true
1321
+ end
1322
+ end
1323
+ return value
1324
+ end
1325
+ else
1326
+ return true
1327
+ end
1328
+ end
1329
+
1330
+ # Returns true if any of the bits within this register has feature
1331
+ # associated with it.
1332
+ def has_bits_enabled_by_feature?(name = nil)
1333
+ if !name
1334
+ bits.any?(&:has_feature_constraint?)
1335
+ else
1336
+ bits.any? { |bit| bit.enabled_by_feature?(name) }
1337
+ end
1338
+ end
1339
+
1340
+ private
1341
+
1342
+ def _state_desc(bits)
1343
+ state = []
1344
+ unless bits.readable? && bits.writable?
1345
+ if bits.readable?
1346
+ state << 'RO'
1347
+ else
1348
+ state << 'WO'
1349
+ end
1350
+ end
1351
+ state << 'Rd' if bits.is_to_be_read?
1352
+ state << 'Str' if bits.is_to_be_stored?
1353
+ state << 'Ov' if bits.has_overlay?
1354
+ if state.empty?
1355
+ ''
1356
+ else
1357
+ "(#{state.join('|')})"
1358
+ end
1359
+ end
1360
+
1361
+ def _max_bit_in_range(bits, max, _min)
1362
+ upper = bits.position + bits.size - 1
1363
+ [upper, max].min - bits.position
1364
+ end
1365
+
1366
+ def _min_bit_in_range(bits, _max, min)
1367
+ lower = bits.position
1368
+ [lower, min].max - bits.position
1369
+ end
1370
+
1371
+ # Returns true if some portion of the given bits falls
1372
+ # within the given range
1373
+ def _bit_in_range?(bits, max, min)
1374
+ upper = bits.position + bits.size - 1
1375
+ lower = bits.position
1376
+ !((lower > max) || (upper < min))
1377
+ end
1378
+
1379
+ # Returns the number of bits from the given bits that
1380
+ # fall within the given range
1381
+ def _num_bits_in_range(bits, max, min)
1382
+ upper = bits.position + bits.size - 1
1383
+ lower = bits.position
1384
+ [upper, max].min - [lower, min].max + 1
1385
+ end
1386
+
1387
+ # Returns true if the given number is is the
1388
+ # given range
1389
+ def _index_in_range?(i, max, min)
1390
+ !((i > max) || (i < min))
1391
+ end
1392
+
1393
+ def _bit_rw(bits)
1394
+ if bits.readable? && bits.writable?
1395
+ 'RW'
1396
+ elsif bits.readable?
1397
+ 'RO'
1398
+ elsif bits.writable?
1399
+ 'WO'
1400
+ else
1401
+ 'X'
1402
+ end
1403
+ end
1404
+ end
1405
+ end
1406
+ end