HDLRuby 2.0.8

Sign up to get free protection for your applications and to get access to all the features.
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