HDLRuby 2.0.8

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 (224) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.travis.yml +5 -0
  4. data/.yardopts +1 -0
  5. data/Gemfile +4 -0
  6. data/HDLRuby.gemspec +36 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +2774 -0
  9. data/README.pdf +0 -0
  10. data/Rakefile +10 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +8 -0
  13. data/exe/hdrcc +3 -0
  14. data/lib/HDLRuby/alcc.rb +137 -0
  15. data/lib/HDLRuby/backend/hruby_allocator.rb +69 -0
  16. data/lib/HDLRuby/backend/hruby_c_allocator.rb +76 -0
  17. data/lib/HDLRuby/hdr_samples/adder.rb +7 -0
  18. data/lib/HDLRuby/hdr_samples/adder_assign_error.rb +11 -0
  19. data/lib/HDLRuby/hdr_samples/adder_bench.rb +27 -0
  20. data/lib/HDLRuby/hdr_samples/adder_gen.rb +7 -0
  21. data/lib/HDLRuby/hdr_samples/adder_nodef_error.rb +7 -0
  22. data/lib/HDLRuby/hdr_samples/addsub.rb +19 -0
  23. data/lib/HDLRuby/hdr_samples/addsubz.rb +22 -0
  24. data/lib/HDLRuby/hdr_samples/alu.rb +47 -0
  25. data/lib/HDLRuby/hdr_samples/calculator.rb +48 -0
  26. data/lib/HDLRuby/hdr_samples/counter_bench.rb +83 -0
  27. data/lib/HDLRuby/hdr_samples/dff.rb +9 -0
  28. data/lib/HDLRuby/hdr_samples/dff_bench.rb +66 -0
  29. data/lib/HDLRuby/hdr_samples/dff_counter.rb +20 -0
  30. data/lib/HDLRuby/hdr_samples/include.rb +14 -0
  31. data/lib/HDLRuby/hdr_samples/instance_open.rb +23 -0
  32. data/lib/HDLRuby/hdr_samples/mei8.rb +256 -0
  33. data/lib/HDLRuby/hdr_samples/mei8_bench.rb +309 -0
  34. data/lib/HDLRuby/hdr_samples/multer_gen.rb +8 -0
  35. data/lib/HDLRuby/hdr_samples/multer_seq.rb +29 -0
  36. data/lib/HDLRuby/hdr_samples/neural/a.rb +9 -0
  37. data/lib/HDLRuby/hdr_samples/neural/a_sub.rb +5 -0
  38. data/lib/HDLRuby/hdr_samples/neural/bw.rb +23 -0
  39. data/lib/HDLRuby/hdr_samples/neural/counter.rb +16 -0
  40. data/lib/HDLRuby/hdr_samples/neural/dadz.rb +9 -0
  41. data/lib/HDLRuby/hdr_samples/neural/dadz_sub.rb +4 -0
  42. data/lib/HDLRuby/hdr_samples/neural/forward.rb +153 -0
  43. data/lib/HDLRuby/hdr_samples/neural/forward_sub.rb +62 -0
  44. data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand.rb +41 -0
  45. data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand_typedef.rb +47 -0
  46. data/lib/HDLRuby/hdr_samples/neural/mem.rb +30 -0
  47. data/lib/HDLRuby/hdr_samples/neural/random.rb +23 -0
  48. data/lib/HDLRuby/hdr_samples/neural/selector.rb +29 -0
  49. data/lib/HDLRuby/hdr_samples/neural/sigmoid.rb +20 -0
  50. data/lib/HDLRuby/hdr_samples/neural/z.rb +33 -0
  51. data/lib/HDLRuby/hdr_samples/prog.obj +256 -0
  52. data/lib/HDLRuby/hdr_samples/ram.rb +18 -0
  53. data/lib/HDLRuby/hdr_samples/register_with_code_bench.rb +98 -0
  54. data/lib/HDLRuby/hdr_samples/rom.rb +10 -0
  55. data/lib/HDLRuby/hdr_samples/struct.rb +14 -0
  56. data/lib/HDLRuby/hdr_samples/sumprod.rb +29 -0
  57. data/lib/HDLRuby/hdr_samples/sw_encrypt_bench.rb +103 -0
  58. data/lib/HDLRuby/hdr_samples/sw_encrypt_cpu_bench.rb +261 -0
  59. data/lib/HDLRuby/hdr_samples/sw_encrypt_cpusim_bench.rb +302 -0
  60. data/lib/HDLRuby/hdr_samples/system_open.rb +11 -0
  61. data/lib/HDLRuby/hdr_samples/tuple.rb +16 -0
  62. data/lib/HDLRuby/hdr_samples/with_channel.rb +118 -0
  63. data/lib/HDLRuby/hdr_samples/with_class.rb +199 -0
  64. data/lib/HDLRuby/hdr_samples/with_decoder.rb +17 -0
  65. data/lib/HDLRuby/hdr_samples/with_fsm.rb +34 -0
  66. data/lib/HDLRuby/hdr_samples/with_reconf.rb +103 -0
  67. data/lib/HDLRuby/hdrcc.rb +623 -0
  68. data/lib/HDLRuby/high_samples/_adder_fault.rb +23 -0
  69. data/lib/HDLRuby/high_samples/_generic_transmission2.rb +146 -0
  70. data/lib/HDLRuby/high_samples/adder.rb +21 -0
  71. data/lib/HDLRuby/high_samples/adder_common_errors.rb +25 -0
  72. data/lib/HDLRuby/high_samples/addsub.rb +33 -0
  73. data/lib/HDLRuby/high_samples/addsubz.rb +37 -0
  74. data/lib/HDLRuby/high_samples/after.rb +28 -0
  75. data/lib/HDLRuby/high_samples/all_signals.rb +29 -0
  76. data/lib/HDLRuby/high_samples/alu.rb +61 -0
  77. data/lib/HDLRuby/high_samples/anonymous.rb +41 -0
  78. data/lib/HDLRuby/high_samples/before.rb +28 -0
  79. data/lib/HDLRuby/high_samples/blockblock.rb +26 -0
  80. data/lib/HDLRuby/high_samples/bugs/dadz.rb +22 -0
  81. data/lib/HDLRuby/high_samples/bugs/misample_instan.rb +20 -0
  82. data/lib/HDLRuby/high_samples/bugs/misample_updown.rb +22 -0
  83. data/lib/HDLRuby/high_samples/bugs/sample_add.rb +16 -0
  84. data/lib/HDLRuby/high_samples/bugs/sample_barrel.rb +13 -0
  85. data/lib/HDLRuby/high_samples/bugs/sample_daice.rb +57 -0
  86. data/lib/HDLRuby/high_samples/bugs/sample_kumiawase.rb +52 -0
  87. data/lib/HDLRuby/high_samples/bugs/sample_multi.rb +18 -0
  88. data/lib/HDLRuby/high_samples/bugs/sample_sub.rb +14 -0
  89. data/lib/HDLRuby/high_samples/bugs/z2.rb +32 -0
  90. data/lib/HDLRuby/high_samples/case.rb +32 -0
  91. data/lib/HDLRuby/high_samples/case2.rb +30 -0
  92. data/lib/HDLRuby/high_samples/change.rb +23 -0
  93. data/lib/HDLRuby/high_samples/clocks.rb +35 -0
  94. data/lib/HDLRuby/high_samples/comparer.rb +21 -0
  95. data/lib/HDLRuby/high_samples/conditionals.rb +29 -0
  96. data/lib/HDLRuby/high_samples/dff.rb +23 -0
  97. data/lib/HDLRuby/high_samples/each.rb +28 -0
  98. data/lib/HDLRuby/high_samples/exporter.rb +42 -0
  99. data/lib/HDLRuby/high_samples/functions.rb +60 -0
  100. data/lib/HDLRuby/high_samples/if_seq.rb +26 -0
  101. data/lib/HDLRuby/high_samples/inherit_as_dff.rb +32 -0
  102. data/lib/HDLRuby/high_samples/inherit_dff.rb +36 -0
  103. data/lib/HDLRuby/high_samples/instance.rb +37 -0
  104. data/lib/HDLRuby/high_samples/memory.rb +64 -0
  105. data/lib/HDLRuby/high_samples/multi_file.rb +27 -0
  106. data/lib/HDLRuby/high_samples/overload.rb +32 -0
  107. data/lib/HDLRuby/high_samples/paper_after.rb +49 -0
  108. data/lib/HDLRuby/high_samples/ram.rb +27 -0
  109. data/lib/HDLRuby/high_samples/registers.rb +139 -0
  110. data/lib/HDLRuby/high_samples/rom.rb +23 -0
  111. data/lib/HDLRuby/high_samples/scopeblockname.rb +37 -0
  112. data/lib/HDLRuby/high_samples/scopescope.rb +26 -0
  113. data/lib/HDLRuby/high_samples/shift.rb +31 -0
  114. data/lib/HDLRuby/high_samples/shift2.rb +40 -0
  115. data/lib/HDLRuby/high_samples/simple_instance.rb +31 -0
  116. data/lib/HDLRuby/high_samples/test_all.sh +10 -0
  117. data/lib/HDLRuby/high_samples/typedef.rb +24 -0
  118. data/lib/HDLRuby/high_samples/values.rb +70 -0
  119. data/lib/HDLRuby/high_samples/vector.rb +22 -0
  120. data/lib/HDLRuby/high_samples/with_decoder.rb +30 -0
  121. data/lib/HDLRuby/high_samples/with_fsm.rb +46 -0
  122. data/lib/HDLRuby/high_samples/with_pipe.rb +43 -0
  123. data/lib/HDLRuby/high_samples/with_seq.rb +25 -0
  124. data/lib/HDLRuby/hruby_bstr.rb +1085 -0
  125. data/lib/HDLRuby/hruby_check.rb +317 -0
  126. data/lib/HDLRuby/hruby_db.rb +432 -0
  127. data/lib/HDLRuby/hruby_error.rb +44 -0
  128. data/lib/HDLRuby/hruby_high.rb +4103 -0
  129. data/lib/HDLRuby/hruby_low.rb +4735 -0
  130. data/lib/HDLRuby/hruby_low2c.rb +1986 -0
  131. data/lib/HDLRuby/hruby_low2high.rb +738 -0
  132. data/lib/HDLRuby/hruby_low2seq.rb +248 -0
  133. data/lib/HDLRuby/hruby_low2sym.rb +126 -0
  134. data/lib/HDLRuby/hruby_low2vhd.rb +1437 -0
  135. data/lib/HDLRuby/hruby_low_bool2select.rb +295 -0
  136. data/lib/HDLRuby/hruby_low_cleanup.rb +193 -0
  137. data/lib/HDLRuby/hruby_low_fix_types.rb +437 -0
  138. data/lib/HDLRuby/hruby_low_mutable.rb +1803 -0
  139. data/lib/HDLRuby/hruby_low_resolve.rb +165 -0
  140. data/lib/HDLRuby/hruby_low_skeleton.rb +129 -0
  141. data/lib/HDLRuby/hruby_low_with_bool.rb +141 -0
  142. data/lib/HDLRuby/hruby_low_with_port.rb +167 -0
  143. data/lib/HDLRuby/hruby_low_with_var.rb +302 -0
  144. data/lib/HDLRuby/hruby_low_without_bit2vector.rb +88 -0
  145. data/lib/HDLRuby/hruby_low_without_concat.rb +162 -0
  146. data/lib/HDLRuby/hruby_low_without_connection.rb +113 -0
  147. data/lib/HDLRuby/hruby_low_without_namespace.rb +718 -0
  148. data/lib/HDLRuby/hruby_low_without_outread.rb +107 -0
  149. data/lib/HDLRuby/hruby_low_without_select.rb +206 -0
  150. data/lib/HDLRuby/hruby_serializer.rb +398 -0
  151. data/lib/HDLRuby/hruby_tools.rb +37 -0
  152. data/lib/HDLRuby/hruby_types.rb +239 -0
  153. data/lib/HDLRuby/hruby_values.rb +64 -0
  154. data/lib/HDLRuby/hruby_verilog.rb +1888 -0
  155. data/lib/HDLRuby/hruby_verilog_name.rb +52 -0
  156. data/lib/HDLRuby/low_samples/adder.yaml +97 -0
  157. data/lib/HDLRuby/low_samples/after.yaml +228 -0
  158. data/lib/HDLRuby/low_samples/before.yaml +223 -0
  159. data/lib/HDLRuby/low_samples/blockblock.yaml +48 -0
  160. data/lib/HDLRuby/low_samples/bugs/sample_add.yaml +97 -0
  161. data/lib/HDLRuby/low_samples/bugs/sample_daice.yaml +444 -0
  162. data/lib/HDLRuby/low_samples/bugs/sample_kumiawase.yaml +332 -0
  163. data/lib/HDLRuby/low_samples/bugs/sample_sub.yaml +97 -0
  164. data/lib/HDLRuby/low_samples/bugs/seqpar.yaml +184 -0
  165. data/lib/HDLRuby/low_samples/case.yaml +327 -0
  166. data/lib/HDLRuby/low_samples/change.yaml +135 -0
  167. data/lib/HDLRuby/low_samples/clocks.yaml +674 -0
  168. data/lib/HDLRuby/low_samples/cloner.rb +22 -0
  169. data/lib/HDLRuby/low_samples/comparer.yaml +85 -0
  170. data/lib/HDLRuby/low_samples/conditionals.yaml +133 -0
  171. data/lib/HDLRuby/low_samples/dff.yaml +107 -0
  172. data/lib/HDLRuby/low_samples/each.yaml +1328 -0
  173. data/lib/HDLRuby/low_samples/exporter.yaml +226 -0
  174. data/lib/HDLRuby/low_samples/functions.yaml +298 -0
  175. data/lib/HDLRuby/low_samples/generic_transmission.yaml +597 -0
  176. data/lib/HDLRuby/low_samples/inherit_as_dff.yaml +125 -0
  177. data/lib/HDLRuby/low_samples/inherit_dff.yaml +107 -0
  178. data/lib/HDLRuby/low_samples/load_yaml.rb +11 -0
  179. data/lib/HDLRuby/low_samples/memory.yaml +678 -0
  180. data/lib/HDLRuby/low_samples/namespace_extractor.rb +23 -0
  181. data/lib/HDLRuby/low_samples/overload.yaml +226 -0
  182. data/lib/HDLRuby/low_samples/paper_after.yaml +431 -0
  183. data/lib/HDLRuby/low_samples/port_maker.rb +14 -0
  184. data/lib/HDLRuby/low_samples/ram.yaml +207 -0
  185. data/lib/HDLRuby/low_samples/registers.yaml +228 -0
  186. data/lib/HDLRuby/low_samples/rom.yaml +2950 -0
  187. data/lib/HDLRuby/low_samples/shift.yaml +230 -0
  188. data/lib/HDLRuby/low_samples/shift2.yaml +2095 -0
  189. data/lib/HDLRuby/low_samples/simple_instance.yaml +102 -0
  190. data/lib/HDLRuby/low_samples/test_all.sh +43 -0
  191. data/lib/HDLRuby/low_samples/typedef.yaml +115 -0
  192. data/lib/HDLRuby/low_samples/values.yaml +577 -0
  193. data/lib/HDLRuby/low_samples/variable_maker.rb +14 -0
  194. data/lib/HDLRuby/low_samples/vector.yaml +56 -0
  195. data/lib/HDLRuby/low_samples/with_seq.yaml +188 -0
  196. data/lib/HDLRuby/low_samples/yaml2hdr.rb +10 -0
  197. data/lib/HDLRuby/low_samples/yaml2vhd.rb +19 -0
  198. data/lib/HDLRuby/sim/Makefile +19 -0
  199. data/lib/HDLRuby/sim/hruby_sim.h +590 -0
  200. data/lib/HDLRuby/sim/hruby_sim_calc.c +2362 -0
  201. data/lib/HDLRuby/sim/hruby_sim_core.c +589 -0
  202. data/lib/HDLRuby/sim/hruby_sim_list.c +93 -0
  203. data/lib/HDLRuby/sim/hruby_sim_vizualize.c +91 -0
  204. data/lib/HDLRuby/sim/hruby_value_pool.c +64 -0
  205. data/lib/HDLRuby/std/channel.rb +354 -0
  206. data/lib/HDLRuby/std/clocks.rb +165 -0
  207. data/lib/HDLRuby/std/counters.rb +82 -0
  208. data/lib/HDLRuby/std/decoder.rb +214 -0
  209. data/lib/HDLRuby/std/fsm.rb +516 -0
  210. data/lib/HDLRuby/std/pipeline.rb +220 -0
  211. data/lib/HDLRuby/std/reconf.rb +309 -0
  212. data/lib/HDLRuby/test_hruby_bstr.rb +2259 -0
  213. data/lib/HDLRuby/test_hruby_high.rb +594 -0
  214. data/lib/HDLRuby/test_hruby_high_low.rb +99 -0
  215. data/lib/HDLRuby/test_hruby_low.rb +934 -0
  216. data/lib/HDLRuby/v_samples/adder.v +10 -0
  217. data/lib/HDLRuby/v_samples/dff.v +12 -0
  218. data/lib/HDLRuby/v_samples/ram.v +20 -0
  219. data/lib/HDLRuby/v_samples/rom.v +270 -0
  220. data/lib/HDLRuby/version.rb +3 -0
  221. data/lib/HDLRuby.rb +11 -0
  222. data/makedoc +1 -0
  223. data/metadata.yaml +4 -0
  224. metadata +299 -0
@@ -0,0 +1,1085 @@
1
+ module HDLRuby
2
+
3
+ ##
4
+ # Library for describing the bit string and their computations.
5
+ #
6
+ ########################################################################
7
+
8
+
9
+ # Converts a value to a valid bit if possible.
10
+ def make_bit(value)
11
+ value = value.to_s.downcase
12
+ unless ["0","1","x","z"].include?(value)
13
+ raise "Invalid value for a bit: #{value}"
14
+ end
15
+ return value
16
+ end
17
+
18
+
19
+ ##
20
+ # Describes a bit string.
21
+ #
22
+ # NOTE:
23
+ # * a bit string is immutable.
24
+ # * bit strings are always signed.
25
+ # * the upper bit of a bit string is the sign.
26
+ class BitString
27
+
28
+ # Creates a new bit string from +str+ with +sign+.
29
+ #
30
+ # NOTE:
31
+ # * +sign+ can be "0", "1", "z" and "x", is positive when "0"
32
+ # and negative when "1".
33
+ # * when not present it is assumed to be within str.
34
+ def initialize(str,sign = nil)
35
+ # Maybe str is an numeric.
36
+ if str.is_a?(Numeric) then
37
+ # Yes, convert it to a binary string.
38
+ str = str.to_s(2)
39
+ # And fix the sign.
40
+ if str[0] == "-" then
41
+ str = str[1..-1]
42
+ sign = "-"
43
+ else
44
+ sign = "+"
45
+ end
46
+ # puts "str=#{str} sign=#{sign}"
47
+ end
48
+ # Process the sign
49
+ sign = sign.to_s unless sign.is_a?(Integer)
50
+ case sign
51
+ when 0, "0","+" then @str = "0"
52
+ when 1, "1","-" then @str = "1"
53
+ when 2, "z","Z" then @str = "z"
54
+ when 3, "x","X" then @str = "x"
55
+ when nil, "" then @str = "" # The sign is in str
56
+ else
57
+ raise "Invalid bit string sign: #{sign}"
58
+ end
59
+ # Check and set the value of the bit string.
60
+ if str.respond_to?(:to_a) then
61
+ # Str is a bit list: convert it to a string.
62
+ str = str.to_a.map do |e|
63
+ case e
64
+ when 0 then "0"
65
+ when 1 then "1"
66
+ when 2 then "z"
67
+ when 3 then "x"
68
+ else
69
+ e
70
+ end
71
+ end.reverse.join
72
+ end
73
+ @str += str.to_s.downcase
74
+ unless @str.match(/^[0-1zx]+$/) then
75
+ raise "Invalid value for creating a bit string: #{str}"
76
+ end
77
+ end
78
+
79
+ # Gets the bitwidth.
80
+ def width
81
+ return @str.size
82
+ end
83
+ alias_method :size, :width
84
+
85
+ # Tells if the bit string is strictly.
86
+ #
87
+ # NOTE: return false if the sign is undefined of if it is unknown
88
+ # if the result is zero or not.
89
+ def positive?
90
+ return (@str[0] == "0" and self.nonzero?)
91
+ end
92
+
93
+ # Tells if the bit string is strictly negative.
94
+ #
95
+ # NOTE: return false if the sign is undefined
96
+ def negative?
97
+ return @str[0] == "1"
98
+ end
99
+
100
+ # Tells if the bit string is zero.
101
+ #
102
+ # NOTE: return false if the bit string is undefined.
103
+ def zero?
104
+ return ! @str.each_char.any? {|b| b != "0" }
105
+ end
106
+
107
+ # Tells if the bit string is not zero.
108
+ def nonzero?
109
+ return @str.each_char.any? {|b| b == "1" }
110
+ end
111
+
112
+ # Tells if the bit string could be zero.
113
+ def maybe_zero?
114
+ return ! self.nonzero?
115
+ end
116
+
117
+ # Converts to a string (sign bit is comprised).
118
+ def to_s
119
+ return @str.clone
120
+ end
121
+ alias_method :str, :to_s
122
+
123
+ # Gets a bit by +index+.
124
+ #
125
+ # NOTE: If the index is larger than the bit string width, returns the
126
+ # bit sign.
127
+ def [](index)
128
+ # Handle the negative index case.
129
+ if index < 0 then
130
+ return self[self.width+index]
131
+ end
132
+ # Process the index.
133
+ index = index > @str.size ? @str.size : index
134
+ # Get the corresponding bit.
135
+ return @str[-index-1]
136
+ end
137
+
138
+ # Sets the bit at +index+ to +value+.
139
+ #
140
+ # NOTE: when index is larger than the bit width, the bit string is
141
+ # sign extended accordingly.
142
+ def []=(index,value)
143
+ # Handle the negative index case.
144
+ if index < 0 then
145
+ return self[self.width+index] = value
146
+ end
147
+ # Duplicate the bit string content to ensure immutability.
148
+ str = @str.clone
149
+ # Process the index.
150
+ if index >= str.size then
151
+ # Overflow, sign extend the bit string.
152
+ str += str[-1] * (index-str.size+1)
153
+ end
154
+ # Checks and convert the value
155
+ value = make_bit(value)
156
+ # Sets the value to a copy of the bit string.
157
+ str[-index-1] = value
158
+ # Return the result as a new bit string.
159
+ return BitString.new(str)
160
+ end
161
+
162
+ # Truncs to +width+.
163
+ #
164
+ # NOTE:
165
+ # * trunc remove the end of the bit string.
166
+ # * if the width is already smaller than +width+, do nothing.
167
+ # * do not preserve the sign, but keep the last bit as sign bit.
168
+ def trunc(width)
169
+ return self if width >= @str.size-1
170
+ return BitString.new(@str[(@str.size-width-1)..-1])
171
+ end
172
+
173
+ # Trims to +width+.
174
+ #
175
+ # NOTE:
176
+ # * trim remove the begining of the bit string.
177
+ # * if the width is already smaller than +width+, do nothing.
178
+ # * do not preserve the sign, but keep the last bit as sign bit.
179
+ def trim(width)
180
+ return self if width >= @str.size-1
181
+ return BitString.new(@str[0..width])
182
+ end
183
+
184
+ # Extend to +width+.
185
+ #
186
+ # NOTE:
187
+ # * if the width is already larger than +width+, do nothing.
188
+ # * preserves the sign.
189
+ def extend(width)
190
+ return self if width <= @str.size - 1
191
+ return BitString.new(@str[0] * (width-@str.size+1) + @str)
192
+ end
193
+
194
+ # Iterates over the bits.
195
+ #
196
+ # NOTE: the sign bit in comprised.
197
+ #
198
+ # Returns an enumerator if no ruby block is given.
199
+ def each(&ruby_block)
200
+ # No ruby block? Return an enumerator.
201
+ return to_enum(:each) unless ruby_block
202
+ # A block? Apply it on each bit.
203
+ @str.each_char.reverse_each(&ruby_block)
204
+ end
205
+
206
+ # Reverse iterates over the bits.
207
+ #
208
+ # NOTE: the sign bit in comprised.
209
+ #
210
+ # Returns an enumerator if no ruby block is given.
211
+ def reverse_each(&ruby_block)
212
+ # No ruby block? Return an enumerator.
213
+ return to_enum(:reverse_each) unless ruby_block
214
+ # A block? Apply it on each bit.
215
+ @str.each_char(&ruby_block)
216
+ end
217
+
218
+ # Gets the sign of the bit string.
219
+ def sign
220
+ return @str[0]
221
+ end
222
+
223
+ # Tell if the sign is specified.
224
+ def sign?
225
+ return (@str[0] == "0" or @str[0] == "1")
226
+ end
227
+
228
+ # Convert the bit string to a Ruby Numeric.
229
+ #
230
+ # NOTE: the result will be wrong is the bit string is unspecified.
231
+ def to_numeric
232
+ res = 0
233
+ # Process the bits.
234
+ @str[1..-1].each_char { |b| res = res << 1 | b.to_i }
235
+ # Process the sign.
236
+ res = res - (2**(@str.size-1)) if @str[0] == "1"
237
+ # Return the result.
238
+ return res
239
+ end
240
+
241
+ # Tell if the bit string is fully specified
242
+ def specified?
243
+ return ! @str.match(/[xz]/)
244
+ end
245
+
246
+ # Coerces.
247
+ def coerce(other)
248
+ return [BitString.new(other),self]
249
+ end
250
+
251
+
252
+ # A few common bit strings.
253
+
254
+ TRUE = BitString.new("01")
255
+ FALSE = BitString.new("00")
256
+ UNKNOWN = BitString.new("xx")
257
+ ZERO = BitString.new("00")
258
+ ONE = BitString.new("01")
259
+ TWO = BitString.new("010")
260
+ THREE = BitString.new("011")
261
+ MINUS_ONE = BitString.new("11")
262
+ MINUS_TWO = BitString.new("10")
263
+ MINUS_THREE = BitString.new("101")
264
+
265
+
266
+ # The arithmetic and logic operations.
267
+
268
+ # Not truth table
269
+ NOT_T = { "0" => "1", "1" => "0", "z" => "x", "x" => "x" }
270
+
271
+ # And truth table: 0, 1, 2=z, 3=x
272
+ AND_T = { "0" => {"0"=>"0", "1"=>"0", "z"=>"0", "x"=>"0"}, # 0 line
273
+ "1" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"}, # 1 line
274
+ "z" => {"0"=>"0", "1"=>"x", "z"=>"x", "x"=>"x"}, # z line
275
+ "x" => {"0"=>"0", "1"=>"x", "z"=>"x", "x"=>"x"} } # x line
276
+
277
+ # Or truth table: 0, 1, 2=z, 3=x
278
+ OR_T = { "0" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"}, # 0 line
279
+ "1" => {"0"=>"1", "1"=>"1", "z"=>"1", "x"=>"1"}, # 1 line
280
+ "z" => {"0"=>"x", "1"=>"1", "z"=>"x", "x"=>"x"}, # z line
281
+ "x" => {"0"=>"x", "1"=>"1", "z"=>"x", "x"=>"x"} } # x line
282
+
283
+ # Xor truth table: 0, 1, 2=z, 3=x
284
+ XOR_T = { "0" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"}, # 0 line
285
+ "1" => {"0"=>"1", "1"=>"0", "z"=>"x", "x"=>"x"}, # 1 line
286
+ "z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"}, # z line
287
+ "x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} } # x line
288
+
289
+ # Double xor truth table: 0, 1, 2=z, 3=x
290
+ XOR3_T={ "0" => {
291
+ "0" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"},
292
+ "1" => {"0"=>"1", "1"=>"0", "z"=>"x", "x"=>"x"},
293
+ "z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
294
+ "x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} }, # 0 line
295
+ "1" => {
296
+ "0" => {"0"=>"1", "1"=>"0", "z"=>"x", "x"=>"x"},
297
+ "1" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"},
298
+ "z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
299
+ "x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} }, # 1 line
300
+ "z" => {
301
+ "0" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
302
+ "1" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
303
+ "z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
304
+ "x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} }, # z line
305
+ "x" => {
306
+ "0" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
307
+ "1" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
308
+ "z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
309
+ "x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} } }# x line
310
+
311
+ # Majority truth table: 0, 1, 2=z, 3=x
312
+ MAJ_T= { "0" => {
313
+ "0" => {"0"=>"0", "1"=>"0", "z"=>"0", "x"=>"0"},
314
+ "1" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"},
315
+ "z" => {"0"=>"0", "1"=>"x", "z"=>"x", "x"=>"x"},
316
+ "x" => {"0"=>"0", "1"=>"x", "z"=>"x", "x"=>"x"} }, # "0" line
317
+ "1" => {
318
+ "0" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"},
319
+ "1" => {"0"=>"1", "1"=>"1", "z"=>"1", "x"=>"1"},
320
+ "z" => {"0"=>"x", "1"=>"1", "z"=>"x", "x"=>"x"},
321
+ "x" => {"0"=>"x", "1"=>"1", "z"=>"x", "x"=>"x"} }, # "1" line
322
+ "z" => {
323
+ "0" => {"0"=>"0", "1"=>"x", "z"=>"x", "x"=>"x"},
324
+ "1" => {"0"=>"x", "1"=>"1", "z"=>"x", "x"=>"x"},
325
+ "z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
326
+ "x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} }, # z line
327
+ "x" => {
328
+ "0" => {"0"=>"0", "1"=>"x", "z"=>"x", "x"=>"x"},
329
+ "1" => {"0"=>"x", "1"=>"1", "z"=>"x", "x"=>"x"},
330
+ "z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
331
+ "x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} } }# x line
332
+
333
+ # Lower than truth table: 0, 1, 2=z, 3=x
334
+ LT_T = { "0" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"}, # 0 line
335
+ "1" => {"0"=>"0", "1"=>"0", "z"=>"x", "x"=>"x"}, # 1 line
336
+ "z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"}, # z line
337
+ "x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} } # x line
338
+
339
+ # Greater than truth table: 0, 1, 2=z, 3=x
340
+ GT_T = { "0" => {"0"=>"0", "1"=>"0", "z"=>"x", "x"=>"x"}, # 0 line
341
+ "1" => {"0"=>"1", "1"=>"0", "z"=>"x", "x"=>"x"}, # 1 line
342
+ "z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"}, # z line
343
+ "x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} } # x line
344
+
345
+ # Table of bitwise operations
346
+ BITWISE = { :+ => :bitwise_add0,
347
+ :- => :bitwise_sub0,
348
+ :-@ => :bitwise_neg0,
349
+ :+@ => :bitwise_pos,
350
+ :* => :bitwise_mul0,
351
+ :/ => :bitwise_div0,
352
+ :% => :bitwise_mod0,
353
+ :** => :bitwise_pow0,
354
+ :& => :bitwise_and,
355
+ :| => :bitwise_or,
356
+ :^ => :bitwise_xor,
357
+ :~ => :bitwise_not,
358
+ :<< => :bitwise_shl,
359
+ :>> => :bitwise_shr,
360
+ :== => :bitwise_eq0,
361
+ :< => :bitwise_lt0,
362
+ :> => :bitwise_gt0,
363
+ :<= => :bitwise_le0,
364
+ :>= => :bitwise_ge0,
365
+ :<=>=> :bitwise_cp0
366
+ }
367
+
368
+
369
+
370
+ # Binary operations
371
+
372
+ [:+, :-, :*, :/, :%, :**, :&, :|, :^,
373
+ :<<, :>>,
374
+ :==, :<, :>, :<=, :>=, :<=>].each do |op|
375
+ # Select the bitwise operation.
376
+ bitwise = BITWISE[op]
377
+ # Define the operation method.
378
+ define_method(op) do |value|
379
+ # Check the value.
380
+ unless value.is_a?(Numeric) then
381
+ value = value.to_numeric if value.specified?
382
+ end
383
+ # Can the computation be performed with Ruby numeric values?
384
+ if self.specified? and value.is_a?(Numeric) then
385
+ # Yes, do it.
386
+ if (op == :/ or op == :%) and value == 0 then
387
+ # Division by 0.
388
+ return UNKNOWN.extend(self.size)
389
+ end
390
+ res = self.to_numeric.send(op,value)
391
+ # Maybe the result was a boolean, change it to an integer
392
+ res = res ? 1 : 0 unless res.is_a?(Numeric)
393
+ return res
394
+ else
395
+ # # No, is it a multiplication, division, modulo, or pow?
396
+ # # If it is the case, only specific values can be computed
397
+ # # otherwise the result is unspecified.
398
+ # case op
399
+ # when :* then
400
+ # svalue = self.specified? ? self.to_numeric : self
401
+ # return BitString.multiplication(svalue,value)
402
+ # when :/ then
403
+ # svalue = self.specified? ? self.to_numeric : self
404
+ # return BitString.division(svalue,value)
405
+ # when :% then
406
+ # svalue = self.specified? ? self.to_numeric : self
407
+ # return BitString.modulo(svalue,value)
408
+ # when :** then
409
+ # svalue = self.specified? ? self.to_numeric : self
410
+ # return BitString.pow(svalue,value)
411
+ # end
412
+ # No, do it bitwise.
413
+ # Ensure value is a bit string.
414
+ s1 = value.is_a?(BitString) ? value : BitString.new(value)
415
+ s0 = self
416
+ # # Convert to list of bits.
417
+ # value = value.to_list
418
+ # slist = self.to_list
419
+ # # Adjust the sizes.
420
+ # if value.size < slist.size then
421
+ # value += [value[-1]] * (slist.size - value.size)
422
+ # elsif value.size > slist.size then
423
+ # slist += [slist[-1]] * (value.size - slist.size)
424
+ # end
425
+ # # Perform the bitwise computation on the lists of bits
426
+ # res = BitString.send(bitwise,slist,value)
427
+ # return BitString.new(res[0..-2],res[-1])
428
+
429
+ # Adjust the widths
430
+ if s0.width < s1.width then
431
+ s0 = s0.extend(s1.width)
432
+ elsif s1.width < s0.width then
433
+ s1 = s1.extend(s0.width)
434
+ end
435
+ # Perform the bitwise computation.
436
+ return BitString.send(bitwise,s0,s1)
437
+ end
438
+ end
439
+ end
440
+
441
+ # Unary operations
442
+
443
+ [:+@, :-@, :~].each do |op|
444
+ # Select the bitwise operation.
445
+ bitwise = BITWISE[op]
446
+ # Define the operation method.
447
+ define_method(op) do
448
+ # Can the computation be performed with Ruby numeric values?
449
+ if self.specified? then
450
+ # Yes, do it.
451
+ return self.to_numeric.send(op)
452
+ else
453
+ # No, do it bitwise.
454
+ # Perform the bitwise computiation on the lists of bits
455
+ # res = BitString.send(bitwise,self.to_list)
456
+ # return BitString.new(res[0..-2],res[-1])
457
+ return BitString.send(bitwise,self)
458
+ end
459
+ end
460
+ end
461
+
462
+
463
+ # Bitwise operations: assume same bit width.
464
+
465
+ # Bitwise addition without processing of the x and z states.
466
+ def self.bitwise_add0(s0,s1)
467
+ return BitString.new("x"*(s0.width+1))
468
+ end
469
+
470
+ # Bitwise addition
471
+ def self.bitwise_add(s0,s1)
472
+ res = "" # The result list of bits
473
+ c = "0" # The current carry
474
+ s0.each.zip(s1.each) do |b0,b1|
475
+ res << XOR3_T[b0][b1][c]
476
+ c = MAJ_T[b0][b1][c]
477
+ end
478
+ # Compute the sign extension (the sign bit of s0 and s1 is used
479
+ # again)
480
+ res << XOR3_T[s0.sign][s1.sign][c]
481
+ return BitString.new(res.reverse)
482
+ end
483
+
484
+ # Bitwise subtraction without processing of the x and z states.
485
+ def self.bitwise_sub0(s0,s1)
486
+ return BitString.new("x"*(s0.width+1))
487
+ end
488
+
489
+ # Bitwise subtraction
490
+ def self.bitwise_sub(s0,s1)
491
+ # # Negate s1.
492
+ # s1 = BitString.bitwise_neg(s1).trunc(s0.width)
493
+ # # puts "s1.width = #{s1.width} s0.width = #{s0.width}"
494
+ # # Add it to s0: but no need to add a bit since neg already added
495
+ # # one.
496
+ # return BitString.bitwise_add(s0,s1)
497
+ # Perform the computation is a way to limit the propagation of
498
+ # unspecified bits.
499
+ # Is s1 specified?
500
+ if s1.specified? then
501
+ # Yes, perform -s1+s0
502
+ return (-s1 + s0)
503
+ else
504
+ # No, perform s0+1+NOT(s1).
505
+ # puts "s0=#{s0} s0+1=#{s0+1} not s1=#{bitwise_not(s1)}"
506
+ return (s0 + 1 + bitwise_not(s1)).trunc(s0.width+1)
507
+ end
508
+ end
509
+
510
+ # Bitwise positive sign: does nothing.
511
+ def self.bitwise_pos(s)
512
+ return s
513
+ end
514
+
515
+ # Bitwise negation without processing of the x and z states.
516
+ def self.bitwise_neg0(s)
517
+ return BitString.new("x"*(s.width+1))
518
+ end
519
+
520
+ # Bitwise negation
521
+ def self.bitwise_neg(s)
522
+ # -s = ~s + 1
523
+ # # Not s.
524
+ # s = BitString.bitwise_not(s)
525
+ # # Add 1.
526
+ # return BitString.bitwise_add(s,ONE.extend(s.width))
527
+ return ~s + 1
528
+ end
529
+
530
+ # Bitwise and
531
+ def self.bitwise_and(s0,s1)
532
+ res = s0.each.zip(s1.each).map { |b0,b1| AND_T[b0][b1] }.join
533
+ # puts "s0=#{s0}, s1=#{s1}, res=#{res}"
534
+ return BitString.new(res.reverse)
535
+ end
536
+
537
+ # Bitwise or
538
+ def self.bitwise_or(s0,s1)
539
+ res = s0.each.zip(s1.each). map { |b0,b1| OR_T[b0][b1] }.join
540
+ return BitString.new(res.reverse)
541
+ end
542
+
543
+ # Bitwise xor
544
+ def self.bitwise_xor(s0,s1)
545
+ res = s0.each.zip(s1.each). map { |b0,b1| XOR_T[b0][b1] }.join
546
+ return BitString.new(res.reverse)
547
+ end
548
+
549
+ # Bitwise not
550
+ def self.bitwise_not(s)
551
+ return BitString.new(s.each.map { |b| NOT_T[b] }.join.reverse)
552
+ end
553
+
554
+ # Bitwise shift left.
555
+ def self.bitwise_shl(s0,s1)
556
+ # puts "s0=#{s0} s1=#{s1}"
557
+ return BitString.new("x" * s0.width) unless s1.specified?
558
+ s1 = s1.to_numeric
559
+ if s1 >= 0 then
560
+ return BitString.new(s0.str + "0" * s1)
561
+ elsif -s1 > s0.width then
562
+ return ZERO
563
+ else
564
+ return s0.trim(s0.width+s1)
565
+ end
566
+ end
567
+
568
+ # Bitwise shift right.
569
+ def self.bitwise_shr(s0,s1)
570
+ # puts "s0=#{s0} s1=#{s1}"
571
+ return BitString.new("x" * s0.width) unless s1.specified?
572
+ s1 = s1.to_numeric
573
+ if s1 <= 0 then
574
+ return BitString.new(s0.str + "0" * -s1)
575
+ elsif s1 > s0.width then
576
+ return ZERO
577
+ else
578
+ return s0.trim(s0.width-s1)
579
+ end
580
+ end
581
+
582
+
583
+ # Bitwise eq without processing of the x and z states.
584
+ def self.bitwise_eq0(s0,s1)
585
+ return UNKNOWN
586
+ end
587
+
588
+ # Bitwise eq.
589
+ def self.bitwise_eq(s0,s1)
590
+ return UNKNOWN unless (s0.specified? and s1.specified?)
591
+ return s0.str == s1.str ? TRUE : FALSE
592
+ end
593
+
594
+
595
+ # Bitwise lt without processing of the x and z states.
596
+ def self.bitwise_lt0(s0,s1)
597
+ return UNKNOWN
598
+ end
599
+
600
+ # Bitwise lt.
601
+ def self.bitwise_lt(s0,s1)
602
+ # # Handle the zero cases.
603
+ # if s0.zero? then
604
+ # return TRUE if s1.positive?
605
+ # return FALSE if s1.negative? or s1.zero?
606
+ # return UNKNOWN
607
+ # elsif s1.zero? then
608
+ # return TRUE if s0.negative?
609
+ # return FALSE if s0.positive? or s0.zero?
610
+ # return UNKNOWN
611
+ # end
612
+ # # Handle the unspecified sign cases.
613
+ # unless s0.sign? then
614
+ # # Check both sign cases.
615
+ # lt_pos = self.bitwise_lt(s0[-1] = "1",s1)
616
+ # lt_neg = self.bitwise_lt(s0[-1] = "0",s1)
617
+ # # At least one of the results is unspecified.
618
+ # return UNKNOWN unless (lt_pos.specified? and lt_neg.specified?)
619
+ # # Both results are specified and identical.
620
+ # return lt_pos if lt_pos == lt_neg
621
+ # # Results are different.
622
+ # return UNKNOWN
623
+ # end
624
+ # unless s1.sign? then
625
+ # # Check both sign cases.
626
+ # lt_pos = self.bitwise_lt(s0,s1[-1] = "1")
627
+ # lt_neg = self.bitwise_lt(s0,s1[-1] = "0")
628
+ # # At least one of the results is unspecified.
629
+ # return UNKNOWN unless (lt_pos.specified? and lt_neg.specified?)
630
+ # # Both results are specified and identical.
631
+ # return lt_pos if lt_pos == lt_neg
632
+ # # Results are different.
633
+ # return UNKNOWN
634
+ # end
635
+ # # Signs are specificied.
636
+ # # Depending on the signs
637
+ # if s0.positive? then
638
+ # if s1.positive? then
639
+ # # s0 and s1 are positive, need to compare each bit.
640
+ # s0.reverse_each.zip(s1.reverse_each) do |b0,b1|
641
+ # # puts "b0=#{b0} b1=#{b1}, LT_T[b0][b1]=#{LT_T[b0][b1]}"
642
+ # case LT_T[b0][b1]
643
+ # when "x" then return UNKNOWN
644
+ # when "1" then return TRUE
645
+ # when "0" then
646
+ # return FALSE if GT_T[b0][b1] == "1"
647
+ # end
648
+ # end
649
+ # elsif s1.negative? then
650
+ # # s0 is positive and s1 is negative.
651
+ # return FALSE
652
+ # else
653
+ # # The sign of s1 is undefined, comparison is undefined too.
654
+ # return UNKNOWN
655
+ # end
656
+ # elsif s0.negative? then
657
+ # if s1.positive? then
658
+ # # s0 is negative and s1 is positive
659
+ # return TRUE
660
+ # elsif s1.negative? then
661
+ # # s0 and s1 are negative, need to compare each bit.
662
+ # s0.reverse_each.zip(s1.reverse_each) do |b0,b1|
663
+ # case GT_T[b0][b1]
664
+ # when "x" then return UNKNOWN
665
+ # when "1" then return FALSE
666
+ # when "0" then
667
+ # return TRUE if LT_T[b0][b1] == "1"
668
+ # end
669
+ # end
670
+ # end
671
+ # else
672
+ # # The sign of s0 is undefined, comparison is undefined too.
673
+ # return UNKNOWN
674
+ # end
675
+
676
+ # Check the sign of the subtraction between s0 and s1.
677
+ case (s0-s1).sign
678
+ when "0" then return FALSE
679
+ when "1" then return TRUE
680
+ else
681
+ return UNKNOWN
682
+ end
683
+ end
684
+
685
+
686
+ # Bitwise gt without processing of the x and z states.
687
+ def self.bitwise_gt0(s0,s1)
688
+ return UNKNOWN
689
+ end
690
+
691
+ # Bitwise gt.
692
+ def self.bitwise_gt(s0,s1)
693
+ return self.bitwise_lt(s1,s0)
694
+ end
695
+
696
+
697
+ # Bitwise le without processing of the x and z states.
698
+ def self.bitwise_le0(s0,s1)
699
+ return UNKNOWN
700
+ end
701
+
702
+ # Bitwise le.
703
+ def self.bitwise_le(s0,s1)
704
+ gt = self.bitwise_gt(s0,s1)
705
+ if gt.eql?(TRUE) then
706
+ return FALSE
707
+ elsif gt.eql?(FALSE) then
708
+ return TRUE
709
+ else
710
+ return UNKNOWN
711
+ end
712
+ end
713
+
714
+
715
+ # Bitwise ge without processing of the x and z states.
716
+ def self.bitwise_ge0(s0,s1)
717
+ return UNKNOWN
718
+ end
719
+
720
+ # Bitwise ge.
721
+ def self.bitwise_ge(s0,s1)
722
+ lt = self.bitwise_lt(s0,s1)
723
+ if lt.eql?(TRUE) then
724
+ return FALSE
725
+ elsif lt.eql?(FALSE) then
726
+ return TRUE
727
+ else
728
+ return UNKNOWN
729
+ end
730
+ end
731
+
732
+
733
+ # Bitwise cp without processing of the x and z states.
734
+ def self.bitwise_cp0(s0,s1)
735
+ return UNKNOWN
736
+ end
737
+
738
+ # Bitwise cp.
739
+ def self.bitwise_cp(s0,s1)
740
+ # Compare the signs.
741
+ if s0.sign == "0" and s1.sign == "1" then
742
+ return ONE
743
+ elsif s0.sign == 0 and s1.sign == "1" then
744
+ return MINUS_ONE
745
+ end
746
+ # Compare the other bits.
747
+ sub = self.bitwise_sub(s0,s1)
748
+ if sub.negative? then
749
+ return MINUS_ONE
750
+ elsif sub.zero? then
751
+ return ZERO
752
+ elsif sub.positive? then
753
+ return ONE
754
+ else
755
+ return UNKNOWN
756
+ end
757
+ end
758
+
759
+ # Bitwise mul without processing of the x and z states.
760
+ def self.bitwise_mul0(s0,s1)
761
+ return BitString.new("x"*(s0.width+s1.width))
762
+ end
763
+
764
+ # Bitwise mul.
765
+ def self.bitwise_mul(s0,s1)
766
+ # Initialize the result to ZERO of combined s0 and s1 widths
767
+ res = ZERO.extend(s0.width + s1.width)
768
+ # The zero cases.
769
+ if s0.zero? or s1.zero? then
770
+ return res
771
+ end
772
+ # Convert s1 and res to lists of bits which support computation
773
+ # between unknown bits of same values.
774
+ s1 = s1.extend(res.width).to_list
775
+ res = res.to_list
776
+ # The other cases: perform a multiplication with shifts and adds.
777
+ s0.each.lazy.take(s0.width).each do |b|
778
+ case b
779
+ when "1" then self.list_add!(res,s1)
780
+ when "x","z" then self.list_add!(res,self.list_and_unknown(s1))
781
+ end
782
+ # puts "res=#{res} s1=#{s1}"
783
+ self.list_shl_1!(s1)
784
+ end
785
+ # Add the sign row.
786
+ case s0.sign
787
+ when "1" then self.list_sub!(res,s1)
788
+ when "x","z" then self.list_sub!(res,list_and_unknown(s1))
789
+ end
790
+ # Return the result.
791
+ return self.list_to_bstr(res)
792
+ end
793
+
794
+ # Bitwise div without processing of the x and z states.
795
+ def self.bitwise_div0(s0,s1)
796
+ return BitString.new("x"*(s0.width))
797
+ end
798
+
799
+ # Bitwise div.
800
+ def self.bitwise_div(s0,s1)
801
+ width = s0.width
802
+ # The zero cases.
803
+ if s0.zero? then
804
+ return res
805
+ elsif s1.maybe_zero? then
806
+ return UNKNOWN.extend(width)
807
+ end
808
+ # Handle the sign: the division is only performed on positive
809
+ # numbers.
810
+ # NOTE: we are sure that s0 and s1 are not zero since these
811
+ # cases have been handled before.
812
+ sign = nil
813
+ if s0.sign == "0" then
814
+ if s1.sign == "0" then
815
+ sign = "0"
816
+ elsif s1.sign == "1" then
817
+ sign = "1"
818
+ s1 = -s1
819
+ else
820
+ # Unknown sign, unkown result.
821
+ return UNKNOWN.extend(width)
822
+ end
823
+ elsif s0.sign == "1" then
824
+ s0 = -s0
825
+ if s1.sign == "0" then
826
+ sign = "1"
827
+ elsif s1.sign == "1" then
828
+ sign = "0"
829
+ s1 = -s1
830
+ else
831
+ # Unknwown sign, unknown result.
832
+ return UNKNOWN.extend(width)
833
+ end
834
+ else
835
+ # Unknown sign, unknown result.
836
+ return UNKNOWN.extend(width)
837
+ end
838
+ # Convert s0 and s1 to list of bits of widths of s0 and s1 -1
839
+ # (the largest possible value).
840
+ # s0 will serve as current remainder.
841
+ s0 = BitString.new(s0) if s0.is_a?(Numeric)
842
+ s1 = BitString.new(s1) if s1.is_a?(Numeric)
843
+ s0 = s0.extend(s0.width+s1.width-1)
844
+ s1 = s1.extend(s0.width)
845
+ s0 = s0.to_list
846
+ s1 = s1.to_list
847
+ puts "first s1=#{s1}"
848
+ # Adujst s1 to the end of s0 and the corresponding 0s in front of q
849
+ msb = s0.reverse.index {|b| b != 0}
850
+ steps = s0.size-msb
851
+ self.list_shl!(s1,steps-1)
852
+ q = [ 0 ] * (width-steps)
853
+ # Apply the non-restoring division algorithm.
854
+ sub = true
855
+ puts "steps= #{steps} s0=#{s0} s1=#{s1} q=#{q}"
856
+ (steps).times do |i|
857
+ if sub then
858
+ self.list_sub!(s0,s1)
859
+ else
860
+ self.list_add!(s0,s1)
861
+ end
862
+ puts "s0=#{s0}"
863
+ # Is the result positive?
864
+ if s0[-1] == 0 then
865
+ # Yes, the next step is a subtraction and the current
866
+ # result bit is one.
867
+ sub = true
868
+ q.unshift(1)
869
+ elsif s0[-1] == 1 then
870
+ # No, it is negative the next step is an addition and the
871
+ # current result bit is zero.
872
+ sub = false
873
+ q.unshift(0)
874
+ else
875
+ # Unknown sign, the remaining of q is unknown.
876
+ (steps-i).times { q.unshift(self.new_unknown) }
877
+ # Still, can add the positive sign bit.
878
+ q.push(0)
879
+ break
880
+ end
881
+ self.list_shr_1!(s1)
882
+ end
883
+ # Generate the resulting bit string.
884
+ puts "q=#{q}"
885
+ q = self.list_to_bstr(q)
886
+ puts "q=#{q}"
887
+ # Set the sign.
888
+ if sign == "1" then
889
+ q = (-q).trunc(width)
890
+ elsif q.zero? then
891
+ q = 0
892
+ else
893
+ q = q.extend(width)
894
+ end
895
+ # Return the result.
896
+ return q
897
+ end
898
+
899
+
900
+ # Bitwise mod without processing of the x and z states.
901
+ def self.bitwise_mod0(s0,s1)
902
+ return BitString.new("x"*(s1.width))
903
+ end
904
+
905
+ # Bitwise mod.
906
+ def self.bitwise_div(s0,s1)
907
+ raise "bitwise_div is not implemented yet."
908
+ end
909
+
910
+
911
+ # Computation with list of bits:
912
+ # "0" -> 0, "1" -> 1, and then 2, 3, 4, ...
913
+ # Allows more precise computations (e.g., mul, div).
914
+
915
+ # The counter of unknown bits.
916
+ @@unknown = 1
917
+
918
+ # Creates a new uniq unknown bit.
919
+ def self.new_unknown
920
+ @@unknown += 1
921
+ return @@unknown
922
+ end
923
+
924
+ # Converts to a list of bits where unknown or high z bits are
925
+ # differentiate from each other.
926
+ #
927
+ # NOTE:
928
+ # * the sign bit is also added to the list.
929
+ # * the distinction between z and x is lost.
930
+ def to_list
931
+ return @str.each_char.reverse_each.map.with_index do |b,i|
932
+ case b
933
+ when "0" then 0
934
+ when "1" then 1
935
+ when "z","x" then BitString.new_unknown
936
+ else
937
+ raise "Internal error: invalid bit in bitstring: #{b}"
938
+ end
939
+ end
940
+ end
941
+
942
+ # Converts list of bits +l+ to a bit string.
943
+ def self.list_to_bstr(l)
944
+ str = l.reverse_each.map { |b| b > 1 ? "x" : b }.join
945
+ return BitString.new(str)
946
+ end
947
+
948
+ # Compute the and between +l+ and an unknown value.
949
+ def self.list_and_unknown(l)
950
+ return l.map do |b|
951
+ b == 0 ? 0 : BitString.new_unknown
952
+ end
953
+ end
954
+
955
+ # Compute the not of +l+
956
+ def self.list_not(l)
957
+ return l.map do |b|
958
+ case b
959
+ when 0 then 1
960
+ when 1 then 0
961
+ else
962
+ BitString.new_unknown
963
+ end
964
+ end
965
+ end
966
+
967
+ # Adds +l1+ to +l0+.
968
+ #
969
+ # NOTE:
970
+ # * l0 is contains the result.
971
+ # * The result has the same size as +l0+ (no sign extension).
972
+ # * Assumes +l0+ and +l1+ have the same size.
973
+ def self.list_add!(l0,l1)
974
+ # puts "add l0=#{l0} l1=#{l1}"
975
+ c = 0 # Current carry.
976
+ l0.each_with_index do |b0,i|
977
+ b1 = l1[i]
978
+ # puts "i=#{i} b0=#{b0} b1=#{b1} c=#{c}"
979
+ if b0 == b1 then
980
+ # The sum is c.
981
+ l0[i] = c
982
+ # The carry is b0.
983
+ c = b0
984
+ elsif b0 == c then
985
+ # The sum is b1.
986
+ l0[i] = b1
987
+ # The carry is b0.
988
+ c = b0
989
+ elsif b1 == c then
990
+ # The sum is b0.
991
+ l0[i] = b0
992
+ # The carry is b1.
993
+ c = b1
994
+ else
995
+ l0[i] = self.new_unknown
996
+ c = self.new_unknown
997
+ end
998
+ end
999
+ return l0
1000
+ end
1001
+
1002
+ # Adds 1 to +l0+.
1003
+ #
1004
+ # NOTE:
1005
+ # * l0 is contains the result.
1006
+ # * The result has the same size as +l0+ (no sign extension).
1007
+ def self.list_add_1!(l0)
1008
+ c = 1 # Current carry.
1009
+ l0.each_with_index do |b0,i|
1010
+ if c == 0 then
1011
+ # The sum is b0.
1012
+ l0[i] = b0
1013
+ # The carry is unchanged.
1014
+ elsif b0 == 0 then
1015
+ # The sum is c.
1016
+ l0[i] = c
1017
+ # The carry is 0.
1018
+ c = 0
1019
+ elsif b0 == c then
1020
+ # The sum is 0.
1021
+ l0[i] = 0
1022
+ # The carry is b0.
1023
+ c = b0
1024
+ else
1025
+ # Both sum and carry are unknown
1026
+ l0[i] = BitString.new_unknown
1027
+ c = BitString.new_unknown
1028
+ end
1029
+ end
1030
+ return l0
1031
+ end
1032
+
1033
+ # Subtracts +l1+ from +l0+.
1034
+ #
1035
+ # NOTE:
1036
+ # * l0 is contains the result.
1037
+ # * The result has the same size as +l0+ (no sign extension).
1038
+ # * Assumes +l0+ and +l1+ have the same size.
1039
+ def self.list_sub!(l0,l1)
1040
+ # Adds 1 to l0.
1041
+ BitString.list_add_1!(l0)
1042
+ # Adds ~l1 to l0.
1043
+ # puts "l0=#{l0} l1=#{l1} ~l1=#{self.list_not(l1)}}"
1044
+ self.list_add!(l0,self.list_not(l1))
1045
+ # puts "l0=#{l0}"
1046
+ # puts "now l0=#{l0}"
1047
+ return l0
1048
+ end
1049
+
1050
+ # Left shifts +l+ once.
1051
+ #
1052
+ # NOTE:
1053
+ # * l contains the result.
1054
+ # * The result has the same size as +l+ (no sign extension).
1055
+ def self.list_shl_1!(l)
1056
+ l.pop
1057
+ l.unshift(0)
1058
+ return l
1059
+ end
1060
+
1061
+ # Right shifts +l+ once.
1062
+ #
1063
+ # NOTE:
1064
+ # * l contains the result.
1065
+ # * The result has the same size as +l+ (no sign extension).
1066
+ def self.list_shr_1!(l)
1067
+ l.shift
1068
+ l.push(0)
1069
+ return l
1070
+ end
1071
+
1072
+
1073
+ # Left shifts +l+ +x+ times.
1074
+ #
1075
+ # NOTE:
1076
+ # * l contains the result.
1077
+ # * The result has the same size as +l+ (no sign extension).
1078
+ def self.list_shl!(l,x)
1079
+ l.pop(x)
1080
+ l.unshift(*([0]*x))
1081
+ end
1082
+
1083
+ end
1084
+
1085
+ end