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,787 @@
1
+ module Origen
2
+ module Registers
3
+ # This is a regular Ruby array that is used to store collections of Bit objects, it has additional
4
+ # methods added to allow interaction with the contained bits.
5
+ # All Ruby array methods are also available - http://www.ruby-doc.org/core/classes/Array.html
6
+ #
7
+ # A BitCollection is returned whenever a subset of bits is requested from a register. Also whenever
8
+ # any of these methods are called on a register object a BitCollection is created on the fly that
9
+ # contains all bits in the register. This means that when interacting with a Register, a single Bit,
10
+ # or a group of Bit objects, the same API can be used as described below.
11
+ class BitCollection < Array
12
+ include Origen::SubBlocks::Path
13
+
14
+ DONT_CARE_CHAR = 'X'
15
+ OVERLAY_CHAR = 'V'
16
+ STORE_CHAR = 'S'
17
+
18
+ attr_accessor :name
19
+
20
+ def initialize(reg, name, data = []) # :nodoc:
21
+ if reg.respond_to?(:has_bits_enabled_by_feature?) && reg.has_parameter_bound_bits?
22
+ reg.update_bound_bits unless reg.updating_bound_bits?
23
+ end
24
+ @reg = reg
25
+ @name = name
26
+ [data].flatten.each { |item| self << item }
27
+ end
28
+
29
+ def bind(live_parameter)
30
+ parent.bind(name, live_parameter)
31
+ end
32
+
33
+ def [](*indexes)
34
+ return self if indexes.empty?
35
+ b = BitCollection.new(parent, name)
36
+ expand_and_order(*indexes).each do |i|
37
+ b << fetch(i)
38
+ end
39
+ # When 1 bit requested just return that bit, this is consistent with the original
40
+ # behaviour before sub collections were added
41
+ if b.size == 1
42
+ b.first
43
+ else
44
+ b
45
+ end
46
+ end
47
+ alias_method :bits, :[]
48
+ alias_method :bit, :[]
49
+
50
+ def parent
51
+ @reg
52
+ end
53
+
54
+ def path_var
55
+ if first.path_var
56
+ if first.path_var =~ /^\./
57
+ base = parent.path(relative_to: parent.parent)
58
+ "#{base}#{first.path_var}"
59
+ else
60
+ first.path_var
61
+ end
62
+ else
63
+ base = parent.path(relative_to: parent.parent)
64
+ if size == 1
65
+ "#{base}[#{position}]"
66
+ else
67
+ "#{base}[#{position + size - 1}:#{position}]"
68
+ end
69
+ end
70
+ end
71
+
72
+ def abs_path
73
+ first.abs_path
74
+ end
75
+
76
+ Bit::ACCESS_CODES.each do |code, _meta|
77
+ define_method "#{code}?" do
78
+ all? { |b| b.undefined? || b.send("#{code}?") }
79
+ end
80
+ end
81
+
82
+ # Copies all data and flags from one bit collection (or reg) object to another
83
+ #
84
+ # This method will accept a dumb value as the argument, in which case it is essentially a write,
85
+ # however it will also clear all flags.
86
+ def copy_all(reg)
87
+ if reg.respond_to?(:contains_bits?) && reg.contains_bits?
88
+ unless reg.size == size
89
+ puts 'Bit collection copy must be performed on collections of the same size.'
90
+ puts 'You can fix this by calling copy on a subset of the bits you require, e.g.'
91
+ puts ' larger_bit_collection[3..0].copy_all(smaller_bit_collection)'
92
+ puts
93
+ fail 'Mismatched size for bit collection copy'
94
+ end
95
+ size.times do |i|
96
+ source_bit = reg.bit[i]
97
+ if source_bit
98
+ self[i].overlay(source_bit.overlay_str) if source_bit.has_overlay?
99
+ self[i].write(source_bit.data)
100
+
101
+ self[i].read if source_bit.is_to_be_read?
102
+ self[i].store if source_bit.is_to_be_stored?
103
+ end
104
+ end
105
+ else
106
+ write(reg)
107
+ clear_flags
108
+ end
109
+ self
110
+ end
111
+
112
+ # Returns the access attribute of the first contained bit, in most normal use cases
113
+ # the application will naturally guarantee that when this is called all of the bits
114
+ # in the collection have the same access value.
115
+ #
116
+ # If you are worried about hitting the case where some bits have different values then
117
+ # use access!, but this will be a bit less efficient
118
+ def access(value = nil)
119
+ if value.nil?
120
+ first.access
121
+ else # set access
122
+ each { |b| b.set_access(value) }
123
+ self
124
+ end
125
+ end
126
+
127
+ # Like access but will raise an error if not all bits in the collection have the same
128
+ # access value
129
+ def access!
130
+ val = access
131
+ if any? { |b| b.access != val }
132
+ fail 'Not all bits the collection have the same access value!'
133
+ end
134
+ val
135
+ end
136
+
137
+ # Returns the description of the given bit(s) if any, if none then an empty array
138
+ # will be returned
139
+ #
140
+ # **Note** Adding a description field will override any comment-driven documentation
141
+ # of a bit collection (ie markdown style comments)
142
+ def description(bitname = nil, options = {})
143
+ bitname, options = nil, bitname if bitname.is_a?(Hash)
144
+ if name == :unknown
145
+ []
146
+ else
147
+ @reg.description(name, options)
148
+ end
149
+ end
150
+
151
+ def full_name(bitname = nil, options = {})
152
+ bitname, options = nil, bitname if bitname.is_a?(Hash)
153
+ unless name == :unknown
154
+ @reg.full_name(name, options)
155
+ end
156
+ end
157
+
158
+ def bit_value_descriptions(_bitname = nil)
159
+ if name == :unknown
160
+ []
161
+ else
162
+ @reg.bit_value_descriptions(name)
163
+ end
164
+ end
165
+
166
+ # Returns a dummy bit collection that is populated with un-writable bits that will
167
+ # read back as 0. This can be useful for padding out spaces in registers with something that
168
+ # responds like conventional bits.
169
+ def self.dummy(reg, name = nil, options = {})
170
+ name, options = nil, name if name.is_a?(Hash)
171
+ options = {
172
+ size: 8,
173
+ pos: 0
174
+ }.merge(options)
175
+ collection = new(reg, name)
176
+ pos = options[:pos]
177
+ options[:size].times do
178
+ bit = Bit.new(reg, pos, writable: false, feature: :dummy_feature)
179
+ collection << bit
180
+ pos += 1
181
+ end
182
+ collection
183
+ end
184
+
185
+ def contains_bits?
186
+ true
187
+ end
188
+
189
+ def inspect
190
+ "<#{self.class}:#{object_id}>"
191
+ end
192
+
193
+ # Returns the LSB position of the collection
194
+ def position
195
+ first.position
196
+ end
197
+
198
+ # Returns the data value held by the collection
199
+ # ==== Example
200
+ # reg(:control).write(0x55)
201
+ # reg(:control).data # => 0x55, assuming the reg has the required bits to store that
202
+ def data
203
+ data = 0
204
+ each_with_index { |bit, i| data |= bit.data << i }
205
+ data
206
+ end
207
+ alias_method :val, :data
208
+ alias_method :value, :data
209
+
210
+ # Returns the inverse of the data value held by the collection
211
+ def data_b
212
+ # (& operation takes care of Bignum formatting issues)
213
+ ~data & ((1 << size) - 1)
214
+ end
215
+
216
+ # Supports reg.bit[0] and bitcollection.bit[0]
217
+ def bit
218
+ self
219
+ end
220
+
221
+ # Set the data value of the collection within the patgen, but not on silicon - i.e. calling
222
+ # write will not trigger a pattern write event.
223
+ def write(value, options = {})
224
+ # If an array is written it means a data value and an overlay have been supplied
225
+ # in one go...
226
+ if value.is_a?(Array) && !value.is_a?(BitCollection)
227
+ overlay(value[1])
228
+ value = value[0]
229
+ end
230
+ value = value.data if value.respond_to?('data')
231
+ each_with_index { |bit, i| bit.write(value[i], options) }
232
+ self
233
+ end
234
+ alias_method :data=, :write
235
+ alias_method :value=, :write
236
+ alias_method :val=, :write
237
+
238
+ # Will tag all bits for read and if a data value is supplied it
239
+ # will update the expected data for when the read is performed.
240
+ def read(value = nil, options = {}) # :nodoc:
241
+ # First properly assign the args if value is absent...
242
+ if value.is_a?(Hash)
243
+ options = value
244
+ value = nil
245
+ end
246
+ if value
247
+ value = Reg.clean_value(value)
248
+ write(value)
249
+ end
250
+ if options[:mask]
251
+ each_with_index { |bit, i| bit.read if options[:mask][i] == 1 }
252
+ each_with_index { |bit, i| bit.clear_read_flag if options[:mask][i] == 0 }
253
+ else
254
+ each(&:read)
255
+ end
256
+ self
257
+ end
258
+
259
+ # Returns a value representing the bit collection / register where a bit value of
260
+ # 1 means the bit is enabled for the given operation.
261
+ def enable_mask(operation)
262
+ str = ''
263
+ shift_out_left do |bit|
264
+ if operation == :store && bit.is_to_be_stored? ||
265
+ operation == :read && bit.is_to_be_read? ||
266
+ operation == :overlay && bit.has_overlay?
267
+ str += '1'
268
+ else
269
+ str += '0'
270
+ end
271
+ end
272
+ str.to_i(2)
273
+ end
274
+
275
+ # Attaches the supplied overlay string to all bits
276
+ # ==== Example
277
+ # reg(:data).overlay("data_val")
278
+ def overlay(value)
279
+ each { |bit| bit.overlay(value) }
280
+ self
281
+ end
282
+
283
+ # Resets all bits, this clears all flags and assigns the data value
284
+ # back to the reset state
285
+ def reset
286
+ each(&:reset)
287
+ self
288
+ end
289
+
290
+ # Shifts out a stream of bit objects corresponding to the size of the BitCollection. i.e. calling
291
+ # this on a 16-bit register this will pass back 16 bit objects.
292
+ # If there are holes in the given register then a dummy bit object will be returned that
293
+ # is not writable and which will always read as 0.
294
+ # ==== Example
295
+ # reg(:data).shift_out_left do |bit|
296
+ # bist_shift(bit)
297
+ # end
298
+ def shift_out_left
299
+ reverse_each { |bit| yield bit }
300
+ end
301
+
302
+ # Same as Reg#shift_out_left but starts from the MSB
303
+ def shift_out_right
304
+ each { |bit| yield bit }
305
+ end
306
+
307
+ # Returns true if any bits have the read flag set - see Bit#is_to_be_read?
308
+ # for more details.
309
+ def is_to_be_read?
310
+ any?(&:is_to_be_read?)
311
+ end
312
+
313
+ # Returns true if any bits have the store flag set - see Bit#is_to_be_stored?
314
+ # for more details.
315
+ def is_to_be_stored?
316
+ any?(&:is_to_be_stored?)
317
+ end
318
+
319
+ # Returns true if any bits have the update_required flag set - see Bit#update_required?
320
+ # for more details.
321
+ def update_required?
322
+ any?(&:update_required?)
323
+ end
324
+
325
+ # Calls the clear_flags method on all bits, see Bit#clear_flags for more details
326
+ def clear_flags
327
+ each(&:clear_flags)
328
+ self
329
+ end
330
+
331
+ # Returns the value you would need to write to the register to put the given
332
+ # value in these bits
333
+ def setting(value)
334
+ result = 0
335
+ each_with_index do |bit, i|
336
+ result |= bit.setting(value[i])
337
+ end
338
+ result
339
+ end
340
+
341
+ # Returns true if any bits within are tagged for overlay, supply a specific name
342
+ # to require a specific overlay only
343
+ # ==== Example
344
+ # myreg.overlay("data")
345
+ # myreg.has_overlay? # => true
346
+ # myreg.has_overlay?("address") # => false
347
+ # myreg.has_overlay?("data") # => true
348
+ def has_overlay?(name = nil)
349
+ any? { |bit| bit.has_overlay?(name) }
350
+ end
351
+
352
+ # Cycles through all bits and returns the last overlay value found, it is assumed therefore
353
+ # that all bits have the same overlay value when calling this method
354
+ # ==== Example
355
+ # myreg.overlay("data")
356
+ #
357
+ # myreg.overlay_str # => "data"
358
+ def overlay_str
359
+ result = ''
360
+ each do |bit|
361
+ result = bit.overlay_str if bit.has_overlay?
362
+ end
363
+ result.to_s
364
+ end
365
+
366
+ # Write the bit value on silicon<br>
367
+ # This method will update the data value of the bits and then call $top.write_register
368
+ # passing the owngin register as the first argument.<br>
369
+ # This method is expected to handle writing the current state of the register to silicon.
370
+ def write!(value = nil, options = {})
371
+ value, options = nil, value if value.is_a?(Hash)
372
+ write(value, options) if value
373
+ @reg.request(:write_register, options)
374
+ self
375
+ end
376
+
377
+ # Similar to write! this method will perform the standard read method and then make
378
+ # a call to $top.read_register(self) with the expectation that this method will
379
+ # implement a read event in the pattern.
380
+ # ==== Example
381
+ # reg(:data).read! # Read register :data, expecting whatever value it currently holds
382
+ # reg(:data).read!(0x5555) # Read register :data, expecting 0x5555
383
+ def read!(value = nil, options = {})
384
+ value, options = nil, value if value.is_a?(Hash)
385
+ read(value, options)
386
+ # launch a read reg
387
+ @reg.request(:read_register, options)
388
+ self
389
+ end
390
+
391
+ # Normally whenever a register is processed by the $top.read_register method
392
+ # it will call Reg#clear_flags to acknowledge that the read has been performed,
393
+ # which clears the read and store flags for the given bits. Normally however you
394
+ # want overlays to stick around such that whenever a given bit is written/read its
395
+ # data is always picked from an overlay.<br>
396
+ # Call this passing in false for a given register to cause the overlay data to also
397
+ # be cleared by Reg#clear_flags.
398
+ # ==== Example
399
+ # reg(:data).overlay("data_val")
400
+ # reg(:data).has_overlay? # => true
401
+ # reg(:data).clear_flags
402
+ # reg(:data).has_overlay? # => true
403
+ # reg(:data).sticky_overlay(false)
404
+ # reg(:data).clear_flags
405
+ # reg(:data).has_overlay? # => false
406
+ def sticky_overlay(set = true)
407
+ each { |bit| bit.sticky_overlay = set }
408
+ self
409
+ end
410
+ alias_method :sticky_overlays, :sticky_overlay
411
+
412
+ # Similar to sticky_overlay this method affects how the store flags are treated by
413
+ # Reg#clear_flags.<br>
414
+ # The default is that store flags will get cleared by Reg#clear_flags, passing true
415
+ # into this method will override this and prevent them from clearing.
416
+ # ==== Example
417
+ # reg(:data).sticky_store(true)
418
+ # reg(:data).store
419
+ # reg(:data).clear_flags # Does not clear the request to store
420
+ def sticky_store(set = true)
421
+ each { |bit| bit.sticky_store = set }
422
+ self
423
+ end
424
+
425
+ # Marks all bits to be stored
426
+ def store
427
+ each(&:store)
428
+ self
429
+ end
430
+
431
+ # Marks all bits to be stored and then calls read!
432
+ def store!
433
+ store
434
+ read!
435
+ self
436
+ end
437
+
438
+ # Sets the store flag on all bits that already have the overlay flag set
439
+ # and then calls $top.read_register passing self as the first argument
440
+ def store_overlay_bits!(options = {})
441
+ store_overlay_bits(options)
442
+ @reg.request(:read_register, options) # Bypass the normal read method since we don't want to
443
+ # tag the other bits for read
444
+ self
445
+ end
446
+
447
+ # Sets the store flag on all bits that already have the overlay flag set
448
+ def store_overlay_bits(options = {})
449
+ options = { exclude: [], # Pass in an array of any overlays that are to be excluded from store
450
+ }.merge(options)
451
+ each do |bit|
452
+ bit.store if bit.has_overlay? && !options[:exclude].include?(bit.overlay_str)
453
+ end
454
+ self
455
+ end
456
+
457
+ # Will yield all unique overlay strings attached to the bits within the collection.
458
+ # It will also return the number of bits for the overlay (the length) and the current
459
+ # data value held in those bits.
460
+ # ==== Example
461
+ # reg(:control).unique_overlays do |str, length, data|
462
+ # do_something(str, length, data)
463
+ # end
464
+ def unique_overlays
465
+ current_overlay = false
466
+ length = 0
467
+ data = 0
468
+ shift_out_right do |bit|
469
+ # Init the current overlay when the first one is encountered
470
+ current_overlay = bit.overlay_str if bit.has_overlay? && !current_overlay
471
+
472
+ if bit.has_overlay?
473
+ if bit.overlay_str != current_overlay
474
+ yield current_overlay, length, data if current_overlay
475
+ length = 0
476
+ data = 0
477
+ end
478
+
479
+ data = data | (bit.data << length)
480
+ length += 1
481
+ else
482
+ yield current_overlay, length, data if current_overlay
483
+ length = 0
484
+ data = 0
485
+ current_overlay = false
486
+ end
487
+ end
488
+ yield current_overlay, length, data if current_overlay
489
+ end
490
+
491
+ # Append a value, for example a block identifier, to all overlays
492
+ # ==== Example
493
+ # reg(:data).overlay("data_val")
494
+ # reg(:data).append_overlays("_0")
495
+ # reg(:data).overlay_str # => "data_val_0"
496
+ def append_overlays(value)
497
+ each do |bit|
498
+ bit.overlay(bit.overlay_str + value) if bit.has_overlay?
499
+ end
500
+ self
501
+ end
502
+
503
+ # Delete the contained bits from the parent Register
504
+ def delete
505
+ @reg.delete_bits(self)
506
+ self
507
+ end
508
+
509
+ def add_name(name) # :nodoc:
510
+ if @name == :unknown
511
+ @name = name
512
+ elsif ![name].flatten.include?(name)
513
+ @name = [@name, name].flatten
514
+ end
515
+ self
516
+ end
517
+
518
+ def owner
519
+ first.owner
520
+ end
521
+
522
+ # All other methods send to bit 0
523
+ def method_missing(method, *args, &block) # :nodoc:
524
+ if first.respond_to?(method)
525
+ if size > 1
526
+ if [:meta, :meta_data, :metadata].include?(method.to_sym) ||
527
+ first.meta_data_method?(method)
528
+ first.send(method, *args, &block)
529
+ else
530
+ fail "Error, calling #{method} on a multi-bit collection is not implemented!"
531
+ end
532
+ else
533
+ first.send(method, *args, &block)
534
+ end
535
+ else
536
+ fail "BitCollection does not have a method named #{method}!"
537
+ end
538
+ end
539
+
540
+ # Recognize that BitCollection responds to some Bit methods via method_missing
541
+ def respond_to?(sym) # :nodoc:
542
+ first.respond_to?(sym) || super(sym)
543
+ end
544
+
545
+ # Returns true if the values of all bits in the collection are known. The value will be
546
+ # unknown in cases where the reset value is undefined or determined by a memory location
547
+ # and where the register has not been written or read to a specific value yet.
548
+ def has_known_value?
549
+ all?(&:has_known_value?)
550
+ end
551
+
552
+ # Returns the reset value of the collection, note that this does not reset the register and the
553
+ # current data is maintained.
554
+ #
555
+ # ==== Example
556
+ # reg(:control).write(0x55)
557
+ # reg(:control).data # => 0x55
558
+ # reg(:control).reset_data # => 0x11, assuming the reg was declared with a reset value of 0x11
559
+ # reg(:control).data # => 0x55
560
+ def reset_data(value = nil)
561
+ # This method was originally setup to set the reset value by passing an argument
562
+ if value
563
+ each_with_index { |bit, i| bit.reset_val = value[i] }
564
+ self
565
+ else
566
+ data = 0
567
+ each_with_index do |bit, i|
568
+ return bit.reset_data if bit.reset_data.is_a?(Symbol)
569
+ data |= bit.reset_data << i
570
+ end
571
+ data
572
+ end
573
+ end
574
+ alias_method :reset_val, :reset_data
575
+ alias_method :reset_value, :reset_data
576
+ alias_method :reset_data=, :reset_data
577
+ alias_method :reset_val=, :reset_data
578
+ alias_method :reset_value=, :reset_data
579
+
580
+ # Modify writable for bits in collection
581
+ def writable(value)
582
+ each_with_index { |bit, i| bit.writable = (value[i] == 0b1); bit.set_access_from_rw }
583
+ self
584
+ end
585
+
586
+ # Modify readable for bits in collection
587
+ def readable(value)
588
+ each_with_index { |bit, i| bit.readable = (value[i] == 0b1); bit.set_access_from_rw }
589
+ self
590
+ end
591
+
592
+ def feature
593
+ feature = []
594
+ feature << fetch(0).feature
595
+ each { |bit| feature << bit.feature if bit.has_feature_constraint? }
596
+ feature = feature.flatten.uniq unless feature.empty?
597
+ feature.delete(nil) if feature.include?(nil)
598
+ if !feature.empty?
599
+ if feature.size == 1
600
+ return feature[0]
601
+ else
602
+ return feature.uniq
603
+ end
604
+ else
605
+ if Origen.config.strict_errors
606
+ fail 'No feature found'
607
+ end
608
+ return nil
609
+ end
610
+ end
611
+ alias_method :features, :feature
612
+
613
+ # Return true if there is any feature associated with these bits
614
+ def has_feature_constraint?(name = nil)
615
+ if !name
616
+ any?(&:has_feature_constraint?)
617
+ else
618
+ any? { |bit| bit.enabled_by_feature?(name) }
619
+ end
620
+ end
621
+ alias_method :enabled_by_feature?, :has_feature_constraint?
622
+
623
+ def enabled?
624
+ all?(&:enabled?)
625
+ end
626
+
627
+ # Returns true if any bits in the collection are writable
628
+ def is_writable?
629
+ any?(&:writable?)
630
+ end
631
+ alias_method :writable?, :is_writable?
632
+
633
+ # Returns true if any bits in the collection are readable
634
+ def is_readable?
635
+ any?(&:readable?)
636
+ end
637
+ alias_method :readable?, :is_readable?
638
+
639
+ # Modify clr_only for bits in collection
640
+ def clr_only(value)
641
+ each_with_index { |bit, i| bit.clr_only = (value[i] == 0b1) }
642
+ self
643
+ end
644
+
645
+ # Modify set_only for bits in collection
646
+ def set_only(value)
647
+ each_with_index { |bit, i| bit.set_only = (value[i] == 0b1) }
648
+ self
649
+ end
650
+
651
+ # Return nvm_dep value held by collection
652
+ def nvm_dep
653
+ nvm_dep = 0
654
+ each_with_index { |bit, i| nvm_dep |= bit.nvm_dep << i }
655
+ nvm_dep
656
+ end
657
+
658
+ # Clear any w1c set bits back to 0
659
+ def clear_w1c
660
+ each(&:clear_w1c)
661
+ self
662
+ end
663
+
664
+ # Clear any start set bits back to 0
665
+ def clear_start
666
+ each(&:clear_start)
667
+ self
668
+ end
669
+
670
+ # Provides a string summary of the bit collection / register state that would be
671
+ # applied to given operation (write or read).
672
+ # This is mainly intended to be useful when generating pattern comments describing
673
+ # an upcoming register transaction.
674
+ #
675
+ # This highlights not only bit values bit the status of any flags or overlays that
676
+ # are currently set.
677
+ #
678
+ # The data is presented in hex nibble format with individual nibbles are expanded to
679
+ # binary format whenever all 4 bits do not have the same status - e.g. if only one
680
+ # of the four is marked for read.
681
+ #
682
+ # The following symbols are used to represent bit state:
683
+ #
684
+ # X - Bit is don't care (not marked for read)
685
+ # V - Bit has been tagged with an overlay
686
+ # S - Bit is marked for store
687
+ #
688
+ # @example
689
+ #
690
+ # myreg.status_str(:write) # => "0000"
691
+ # myreg.status_str(:read) # => "XXXX"
692
+ # myreg[7..4].read(5)
693
+ # myreg.status_str(:read) # => "XX5X"
694
+ # myreg[14].read(0)
695
+ # myreg.status_str(:read) # => "(x0xx)X5X"
696
+ def status_str(operation, options = {})
697
+ options = {
698
+ mark_overlays: true
699
+ }.merge(options)
700
+ str = ''
701
+ if operation == :read
702
+ shift_out_left do |bit|
703
+ if bit.is_to_be_stored?
704
+ str += STORE_CHAR
705
+ elsif bit.is_to_be_read?
706
+ if bit.has_overlay? && options[:mark_overlays]
707
+ str += OVERLAY_CHAR
708
+ else
709
+ str += bit.data.to_s
710
+ end
711
+ else
712
+ str += DONT_CARE_CHAR
713
+ end
714
+ end
715
+ elsif operation == :write
716
+ shift_out_left do |bit|
717
+ if bit.has_overlay? && options[:mark_overlays]
718
+ str += OVERLAY_CHAR
719
+ else
720
+ str += bit.data.to_s
721
+ end
722
+ end
723
+ else
724
+ fail "Unknown operation (#{operation}), must be :read or :write"
725
+ end
726
+ make_hex_like(str, size / 4)
727
+ end
728
+
729
+ private
730
+
731
+ # Converts a binary-like representation of a data value into a hex-like version.
732
+ # e.g. input => 010S0011SSSS0110 (where S, X or V represent store, don't care or overlay)
733
+ # output => (010s)3S6 (i.e. nibbles that are not all of the same type are expanded)
734
+ def make_hex_like(regval, size_in_nibbles)
735
+ outstr = ''
736
+ regex = '^'
737
+ size_in_nibbles.times { regex += '(....)' }
738
+ regex += '$'
739
+ Regexp.new(regex) =~ regval
740
+
741
+ nibbles = []
742
+ size_in_nibbles.times do |n| # now grouped by nibble
743
+ nibbles << Regexp.last_match[n + 1]
744
+ end
745
+
746
+ nibbles.each_with_index do |nibble, i|
747
+ # If contains any special chars...
748
+ if nibble =~ /[#{DONT_CARE_CHAR}#{STORE_CHAR}#{OVERLAY_CHAR}]/
749
+ # If all the same...
750
+ if nibble[0] == nibble[1] && nibble[1] == nibble[2] && nibble[2] == nibble[3]
751
+ outstr += nibble[0, 1] # .to_s
752
+ # Otherwise present this nibble in 'binary' format
753
+ else
754
+ outstr += "(#{nibble.downcase})"
755
+ end
756
+ # Otherwise if all 1s and 0s...
757
+ else
758
+ outstr += '%1X' % nibble.to_i(2)
759
+ end
760
+ end
761
+ outstr
762
+ end
763
+
764
+ # Cleans up indexed references to pins, e.g. makes these equal:
765
+ #
766
+ # bits(:data)[0,1,2,3]
767
+ # bits(:data)[3,2,1,0]
768
+ # bits(:data)[0..3]
769
+ # bits(:data)[3..0]
770
+ def expand_and_order(*indexes)
771
+ ixs = []
772
+ indexes.flatten.each do |index|
773
+ if index.is_a?(Range)
774
+ if index.first > index.last
775
+ ixs << (index.last..index.first).to_a
776
+ else
777
+ ixs << index.to_a
778
+ end
779
+ else
780
+ ixs << index
781
+ end
782
+ end
783
+ ixs.flatten.sort
784
+ end
785
+ end
786
+ end
787
+ end