origen 0.0.1 → 0.0.2

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.
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