HDLRuby 2.10.5 → 2.11.0

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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/HDLRuby.gemspec +1 -0
  3. data/README.md +8 -4
  4. data/Rakefile +8 -0
  5. data/{lib/HDLRuby/sim/Makefile → ext/hruby_sim/Makefile_csim} +0 -0
  6. data/ext/hruby_sim/extconf.rb +13 -0
  7. data/ext/hruby_sim/hruby_rcsim_build.c +1188 -0
  8. data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim.h +255 -16
  9. data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_calc.c +310 -181
  10. data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_core.c +34 -17
  11. data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_list.c +0 -0
  12. data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_stack_calc.c +4 -1
  13. data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_stack_calc.c.sav +0 -0
  14. data/ext/hruby_sim/hruby_sim_tree_calc.c +375 -0
  15. data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_vcd.c +5 -5
  16. data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_vizualize.c +2 -2
  17. data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_value_pool.c +4 -1
  18. data/lib/HDLRuby/hdr_samples/bstr_bench.rb +2 -0
  19. data/lib/HDLRuby/hdr_samples/case_bench.rb +2 -2
  20. data/lib/HDLRuby/hdr_samples/counter_bench.rb +0 -1
  21. data/lib/HDLRuby/hdr_samples/counter_dff_bench.rb +46 -0
  22. data/lib/HDLRuby/hdr_samples/dff_bench.rb +1 -1
  23. data/lib/HDLRuby/hdr_samples/print_bench.rb +62 -0
  24. data/lib/HDLRuby/hdr_samples/rom.rb +5 -3
  25. data/lib/HDLRuby/hdr_samples/simple_counter_bench.rb +43 -0
  26. data/lib/HDLRuby/hdrcc.rb +54 -8
  27. data/lib/HDLRuby/hruby_bstr.rb +1175 -917
  28. data/lib/HDLRuby/hruby_high.rb +200 -90
  29. data/lib/HDLRuby/hruby_high_fullname.rb +82 -0
  30. data/lib/HDLRuby/hruby_low.rb +41 -23
  31. data/lib/HDLRuby/hruby_low2c.rb +7 -0
  32. data/lib/HDLRuby/hruby_rcsim.rb +978 -0
  33. data/lib/HDLRuby/hruby_rsim.rb +1134 -0
  34. data/lib/HDLRuby/hruby_rsim_vcd.rb +322 -0
  35. data/lib/HDLRuby/hruby_values.rb +362 -18
  36. data/lib/HDLRuby/hruby_verilog.rb +21 -3
  37. data/lib/HDLRuby/version.rb +1 -1
  38. metadata +24 -13
@@ -6,112 +6,141 @@ module HDLRuby
6
6
  ########################################################################
7
7
 
8
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
9
+ # # Converts a value to a valid bit if possible.
10
+ # def make_bit(value)
11
+ # value = value.to_s.downcase
12
+ # # Removed because assume value is always right.
13
+ # # unless ["0","1","x","z"].include?(value)
14
+ # # raise "Invalid value for a bit: #{value}"
15
+ # # end
16
+ # return value
17
+ # end
18
+
19
+ # # Converts a value to a valid bit string of +width+ bits.
20
+ # def make_bits(value,width)
21
+ # if value.is_a?(Numeric) then
22
+ # value = value.to_s(2)
23
+ # else
24
+ # value = value.to_s.downcase
25
+ # end
26
+ # # puts "first value=#{value} width=#{width}"
27
+ # if value.size > width then
28
+ # value = value[-width..-1]
29
+ # elsif value.size < width then
30
+ # value = value[0] * (width-value.size) + value
31
+ # end
32
+ # return value
33
+ # end
17
34
 
18
35
 
19
36
  ##
20
37
  # Describes a bit string.
21
38
  #
22
39
  # NOTE:
23
- # * a bit string is immutable.
24
40
  # * bit strings are always signed.
25
- # * the upper bit of a bit string is the sign.
41
+ # * the representation is 2 complements.
26
42
  class BitString
27
43
 
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
- # puts "str=#{str}"
36
- # Maybe str is an numeric.
37
- if str.is_a?(Numeric) then
38
- # Yes, convert it to a binary string.
39
- num = str
40
- str = num.to_s(2)
41
- # And fix the sign.
42
- if str[0] == "-" then
43
- # str = str[1..-1]
44
- str = (2**str.size+num).to_s(2)
45
- puts "str=#{str}"
46
- sign = "-"
44
+ # Creates a new bit string from +val+.
45
+ # NOTE:* +val+ can be a Numeric or a String.
46
+ # * when +opt+ is :raw, val is considered to be the raw content.
47
+ def initialize(val, opt = false)
48
+ # puts "val=#{val} val.class=#{val.class} opt=#{opt}"
49
+ if opt == :raw then
50
+ @content = [*val]
51
+ elsif val.is_a?(Numeric) then
52
+ # Content is a numeric.
53
+ @content = []
54
+ if val > 0 then
55
+ while val > 0 do
56
+ @content << (val & 1)
57
+ val /= 2
58
+ end
59
+ @content << 0
47
60
  else
48
- sign = "+"
61
+ while val < -1 do
62
+ @content << (val & 1)
63
+ val /= 2
64
+ end
65
+ @content << 1
49
66
  end
50
- # puts "str=#{str} sign=#{sign}"
51
- end
52
- # Process the sign
53
- sign = sign.to_s unless sign.is_a?(Integer)
54
- case sign
55
- when 0, "0","+" then @str = "0"
56
- when 1, "1","-" then @str = "1"
57
- when 2, "z","Z" then @str = "z"
58
- when 3, "x","X" then @str = "x"
59
- when nil, "" then @str = "" # The sign is in str
60
67
  else
61
- raise "Invalid bit string sign: #{sign}"
62
- end
63
- # Check and set the value of the bit string.
64
- if str.respond_to?(:to_a) then
65
- # Str is a bit list: convert it to a string.
66
- str = str.to_a.map do |e|
67
- case e
68
- when 0 then "0"
69
- when 1 then "1"
70
- when 2 then "z"
71
- when 3 then "x"
68
+ # Content is not a numeric nor a BitString.
69
+ @content = []
70
+ # Ensure it is a string.
71
+ val = val.to_s.downcase
72
+ val.each_byte.reverse_each do |c|
73
+ case c
74
+ when 48 # "0"
75
+ @content << 0
76
+ when 49 # "1"
77
+ @content << 1
78
+ when 120 # "x"
79
+ @content << 3
80
+ when 122 # "z"
81
+ @content << 2
72
82
  else
73
- e
83
+ raise "Invalid bit: #{b.chr}"
74
84
  end
75
- end.reverse.join
85
+ end
76
86
  end
77
- @str += str.to_s.downcase
78
- # puts "@str=#{@str}"
79
- unless @str.match(/^[0-1zx]+$/) then
80
- raise "Invalid value for creating a bit string: #{str}"
87
+ end
88
+
89
+ # Clone the bit string.
90
+ def clone
91
+ return BitString.new(@content,:raw)
92
+ end
93
+
94
+ # Reverse the content of the bit string assuming a bit width
95
+ # of +width+.
96
+ def reverse!(width)
97
+ # Ensure content is large enough.
98
+ if @content.size < width then
99
+ @content.concat(content[-1]*(width-@content.size))
100
+ else
101
+ @content.trunc!(width)
81
102
  end
103
+ @content.reverse!
82
104
  end
83
105
 
84
- # Gets the bitwidth.
85
- def width
86
- return @str.size
106
+
107
+ # Give access to the raw content.
108
+ # NOTE: the content is not copied, so there is a risk of side effect.
109
+ def raw_content
110
+ return @content
87
111
  end
88
- alias_method :size, :width
89
112
 
90
113
  # Tells if the bit string is strictly.
91
114
  #
92
115
  # NOTE: return false if the sign is undefined of if it is unknown
93
116
  # if the result is zero or not.
94
117
  def positive?
95
- return (@str[0] == "0" and self.nonzero?)
118
+ return (@content[-1] == 0)
119
+ end
120
+
121
+ # Force the BitSting to be positive by appending a 0 is required.
122
+ def positive!
123
+ @content << 0 if @content[-1] != 0
124
+ return self
96
125
  end
97
126
 
98
127
  # Tells if the bit string is strictly negative.
99
128
  #
100
129
  # NOTE: return false if the sign is undefined
101
130
  def negative?
102
- return @str[0] == "1"
131
+ return (@content[-1] == 1)
103
132
  end
104
133
 
105
134
  # Tells if the bit string is zero.
106
135
  #
107
136
  # NOTE: return false if the bit string is undefined.
108
137
  def zero?
109
- return ! @str.each_char.any? {|b| b != "0" }
138
+ return ! @content.any? {|b| b != 0 }
110
139
  end
111
140
 
112
141
  # Tells if the bit string is not zero.
113
142
  def nonzero?
114
- return @str.each_char.any? {|b| b == "1" }
143
+ return @content.any? {|b| b == 1 }
115
144
  end
116
145
 
117
146
  # Tells if the bit string could be zero.
@@ -121,80 +150,190 @@ module HDLRuby
121
150
 
122
151
  # Converts to a string (sign bit is comprised).
123
152
  def to_s
124
- return @str.clone
153
+ return @content.reverse_each.map { |b| B2S_T[b] }.join
125
154
  end
126
155
  alias_method :str, :to_s
127
156
 
128
- # Gets a bit by +index+.
157
+ # Gets a bit by +index+. If +index+ is a range it is a range access.
129
158
  #
130
- # NOTE: If the index is larger than the bit string width, returns the
131
- # bit sign.
159
+ # NOTE: * Assumes index is a numeric or a range of numerics.
160
+ # * Access is compatible with Ruby array access and not with
161
+ # hardware access, e.g., 0..4 is not reversed.
162
+ # This is compatible with sub access of Numeric.
163
+ # * If the index is larger than the bit string width, returns the
164
+ # bit sign.
132
165
  def [](index)
133
- # Handle the negative index case.
134
- if index < 0 then
135
- return self[self.width+index]
166
+ if index.is_a?(Range) then
167
+ # Process the left index.
168
+ left = index.first
169
+ left = left.to_i
170
+ # Adjust left to @content size.
171
+ left += @content.size if left < 0
172
+ left = left >= @content.size ? @content.size-1 : left
173
+ # Process the right index.
174
+ right = index.last
175
+ right = right.to_i
176
+ # Adjust right to @content size.
177
+ right += @content.size if right < 0
178
+ right = right >= @content.size ? @content.size-1 : right
179
+ # Do the access.
180
+ if right >= left then
181
+ # puts "left=#{left} right=#{right}"
182
+ # Get the corresponding bits as a BitString
183
+ return BitString.new(@content[left..right],:raw)
184
+ else
185
+ # Get the corresponding bits as a BitString
186
+ return BitString.new(@content[right..left].reverse,:raw)
187
+ end
188
+ else
189
+ # Process the index.
190
+ index = index.to_i
191
+ # Handle the negative index case.
192
+ if index < 0 then
193
+ return self[self.width+index]
194
+ end
195
+ # Process the index.
196
+ index = index >= @content.size ? @content.size-1 : index
197
+ b = @content[index]
198
+ if b < 2 then
199
+ # b is specified return it as an Numeric.
200
+ return b
201
+ else
202
+ # b is not specified, create a new BitString.
203
+ return BitString.new(b,:raw)
204
+ end
136
205
  end
137
- # Process the index.
138
- index = index > @str.size ? @str.size : index
139
- # Get the corresponding bit.
140
- return @str[-index-1]
141
206
  end
142
207
 
143
208
  # Sets the bit at +index+ to +value+.
144
209
  #
145
- # NOTE: when index is larger than the bit width, the bit string is
146
- # sign extended accordingly.
210
+ # NOTE: * Assumes index is a numeric or a range of numerics.
211
+ # * Access is compatible with Ruby array access and not with
212
+ # hardware access, e.g., 0..4 is not reversed.
213
+ # This is compatible with sub access of Numeric.
214
+ # * when index is larger than the bit width, the bit string is
215
+ # X extended accordingly.
147
216
  def []=(index,value)
148
- # Handle the negative index case.
149
- if index < 0 then
150
- return self[self.width+index] = value
151
- end
152
- # Duplicate the bit string content to ensure immutability.
153
- str = @str.clone
154
- # Process the index.
155
- if index >= str.size then
156
- # Overflow, sign extend the bit string.
157
- str += str[-1] * (index-str.size+1)
217
+ # Change inside the bit string, it is not know any longer if it
218
+ # is specified or not
219
+ @specified = nil
220
+ # Process according to the kind of index.
221
+ if index.is_a?(Range) then
222
+ # Process the left index.
223
+ left = index.first
224
+ left = left.to_i
225
+ # Adjust left and @content size.
226
+ left += @content.size if left < 0
227
+ if left >= @content.size then
228
+ # Overflow, sign extend the content.
229
+ sign = @content[-1]
230
+ @content.concat([sign] * (left-@content.size+1))
231
+ end
232
+ # Process the right index.
233
+ right = index.last
234
+ right = right.to_i
235
+ # Adjust right and @content size.
236
+ right += @content.size if right < 0
237
+ if right >= @content.size then
238
+ # Overflow, sign extend the bit string.
239
+ sign = @content[-1]
240
+ @content.concat([sign] * (right-@content.size+1))
241
+ end
242
+ if right >= left then
243
+ # puts "left=#{left} right=#{right} value=#{value} (#{value.class})"
244
+ # Sets the value to a copy of the bit string.
245
+ @content[left..right] = value.is_a?(BitString) ?
246
+ value.raw_content[0..right-left] :
247
+ (right-left+1).times.map do |i|
248
+ value[i]
249
+ end
250
+ else
251
+ # Sets the value to a copy of the bit string.
252
+ @content[right..left] = value.is_a?(BitString) ?
253
+ value.raw_content[left-right..0] :
254
+ (left-right).down_to(0).map do |i|
255
+ value[i]
256
+ end
257
+ end
258
+ # puts "now @content=#{@content}"
259
+ else
260
+ # Process the index.
261
+ index = index.to_i
262
+ # Handle the negative index case.
263
+ if index < 0 then
264
+ return self[@content.size+index] = value
265
+ end
266
+ # Process the index.
267
+ if index >= @content.size then
268
+ # Overflow, sign extend the bit string.
269
+ sign = @content[-1]
270
+ @content.concat([sign] * (index-@content.size+1))
271
+ end
272
+ # Sets the value to the bit string.
273
+ @content[index] = value[0]
158
274
  end
159
- # Checks and convert the value
160
- value = make_bit(value)
161
- # Sets the value to a copy of the bit string.
162
- str[-index-1] = value
163
- # Return the result as a new bit string.
164
- return BitString.new(str)
275
+ return value
165
276
  end
166
277
 
167
278
  # Truncs to +width+.
168
279
  #
169
280
  # NOTE:
170
281
  # * trunc remove the end of the bit string.
171
- # * if the width is already smaller than +width+, do nothing.
172
- # * do not preserve the sign, but keep the last bit as sign bit.
173
- def trunc(width)
174
- return self if width >= @str.size-1
175
- return BitString.new(@str[(@str.size-width-1)..-1])
176
- end
177
-
178
- # Trims to +width+.
179
- #
180
- # NOTE:
181
- # * trim remove the begining of the bit string.
182
- # * if the width is already smaller than +width+, do nothing.
183
- # * do not preserve the sign, but keep the last bit as sign bit.
184
- def trim(width)
185
- return self if width >= @str.size-1
186
- return BitString.new(@str[0..width])
187
- end
188
-
189
- # Extend to +width+.
190
- #
191
- # NOTE:
192
- # * if the width is already larger than +width+, do nothing.
193
- # * preserves the sign.
194
- def extend(width)
195
- return self if width <= @str.size - 1
196
- return BitString.new(@str[0] * (width-@str.size+1) + @str)
197
- end
282
+ # * if the width is already smaller or equal than +width+, do nothing.
283
+ def trunc!(width)
284
+ return self if width >= @content.size
285
+ @content.pop(width-@content.size)
286
+ end
287
+
288
+ # # Trims to +width+.
289
+ # #
290
+ # # NOTE:
291
+ # # * trim remove the begining of the bit string.
292
+ # # * if the width is already smaller than +width+, do nothing.
293
+ # # * do not preserve the sign, but keep the last bit as sign bit.
294
+ # def trim(width)
295
+ # return self if width >= @str.size-1
296
+ # return BitString.new(@str[0..width])
297
+ # end
298
+
299
+ # # Sign extend to +width+.
300
+ # #
301
+ # # NOTE:
302
+ # # * if the width is already larger than +width+, do nothing.
303
+ # # * preserves the sign.
304
+ # # def extend(width)
305
+ # def sext(width)
306
+ # return self if width <= @str.size - 1
307
+ # return BitString.new(@str[0] * (width-@str.size) + @str)
308
+ # end
309
+
310
+ # # Zero extend to +width+.
311
+ # #
312
+ # # NOTE:
313
+ # # * if the width is already larger than +width+, do nothing.
314
+ # # * preserves the sign.
315
+ # def zext(width)
316
+ # return self if width <= @str.size - 1
317
+ # return BitString.new("0" * (width-@str.size) + @str)
318
+ # end
319
+
320
+ # # X extend to +width+.
321
+ # #
322
+ # # NOTE:
323
+ # # * if the width is already larger than +width+, do nothing.
324
+ # # * preserves the sign.
325
+ # def xext(width)
326
+ # return self if width <= @str.size - 1
327
+ # return BitString.new("x" * (width-@str.size) + @str)
328
+ # end
329
+
330
+ # # Concat with +value+ using +w0+ for current bit width and +w1+ for
331
+ # # value bit width.
332
+ # def concat(value,w0,w1)
333
+ # res = self[w0-1..0]
334
+ # res[w0+w1-1..w0] = value
335
+ # return res
336
+ # end
198
337
 
199
338
  # Iterates over the bits.
200
339
  #
@@ -205,7 +344,7 @@ module HDLRuby
205
344
  # No ruby block? Return an enumerator.
206
345
  return to_enum(:each) unless ruby_block
207
346
  # A block? Apply it on each bit.
208
- @str.each_char.reverse_each(&ruby_block)
347
+ @content.each(&ruby_block)
209
348
  end
210
349
 
211
350
  # Reverse iterates over the bits.
@@ -217,42 +356,58 @@ module HDLRuby
217
356
  # No ruby block? Return an enumerator.
218
357
  return to_enum(:reverse_each) unless ruby_block
219
358
  # A block? Apply it on each bit.
220
- @str.each_char(&ruby_block)
221
- end
222
-
223
- # Gets the sign of the bit string.
224
- def sign
225
- return @str[0]
226
- end
227
-
228
- # Tell if the sign is specified.
229
- def sign?
230
- return (@str[0] == "0" or @str[0] == "1")
231
- end
359
+ @content.reverse_each(&ruby_block)
360
+ end
361
+
362
+ # # Gets the sign of the bit string.
363
+ # def sign
364
+ # return @str[0]
365
+ # end
366
+
367
+ # # Tell if the sign is specified.
368
+ # def sign?
369
+ # return (@str[0] == "0" or @str[0] == "1")
370
+ # end
371
+
372
+ # # Convert the bit string to a Ruby Numeric.
373
+ # #
374
+ # # NOTE: the result will be wrong is the bit string is unspecified.
375
+ # def to_numeric
376
+ # res = 0
377
+ # # Process the bits.
378
+ # @str[1..-1].each_char { |b| res = res << 1 | b.to_i }
379
+ # # Process the sign.
380
+ # res = res - (2**(@str.size-1)) if @str[0] == "1"
381
+ # # Return the result.
382
+ # return res
383
+ # end
232
384
 
233
385
  # Convert the bit string to a Ruby Numeric.
234
386
  #
235
387
  # NOTE: the result will be wrong is the bit string is unspecified.
236
- def to_numeric
388
+ # def to_numeric
389
+ def to_i
390
+ # Compute the 2-complement's value.
237
391
  res = 0
238
- # Process the bits.
239
- @str[1..-1].each_char { |b| res = res << 1 | b.to_i }
240
- # Process the sign.
241
- res = res - (2**(@str.size-1)) if @str[0] == "1"
242
- # Return the result.
392
+ @content.reverse_each { |b| res = res * 2 | b }
393
+ # Fix the sign.
394
+ res = -((1 << @content.size) - res) if @content[-1] == 1
243
395
  return res
244
396
  end
245
397
 
246
398
  # Tell if the bit string is fully specified
247
399
  def specified?
248
- return ! @str.match(/[xz]/)
400
+ @specified = ! @content.any? {|b| b > 1 } if @specified == nil
401
+ return @specified
249
402
  end
250
403
 
251
- # Coerces.
252
- def coerce(other)
253
- return [BitString.new(other),self]
254
- end
404
+ # # Coerces.
405
+ # def coerce(other)
406
+ # return [BitString.new(other),self]
407
+ # end
255
408
 
409
+ # String conversion table.
410
+ B2S_T = [ "0", "1", "z", "x" ]
256
411
 
257
412
  # A few common bit strings.
258
413
 
@@ -271,819 +426,922 @@ module HDLRuby
271
426
  # The arithmetic and logic operations.
272
427
 
273
428
  # Not truth table
274
- NOT_T = { "0" => "1", "1" => "0", "z" => "x", "x" => "x" }
429
+ # NOT_T = { "0" => "1", "1" => "0", "z" => "x", "x" => "x" }
430
+ NOT_T = [ 1, 0, 3, 3 ]
275
431
 
276
432
  # And truth table: 0, 1, 2=z, 3=x
277
- AND_T = { "0" => {"0"=>"0", "1"=>"0", "z"=>"0", "x"=>"0"}, # 0 line
278
- "1" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"}, # 1 line
279
- "z" => {"0"=>"0", "1"=>"x", "z"=>"x", "x"=>"x"}, # z line
280
- "x" => {"0"=>"0", "1"=>"x", "z"=>"x", "x"=>"x"} } # x line
433
+ # AND_T = { "0" => {"0"=>"0", "1"=>"0", "z"=>"0", "x"=>"0"}, # 0 line
434
+ # "1" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"}, # 1 line
435
+ # "z" => {"0"=>"0", "1"=>"x", "z"=>"x", "x"=>"x"}, # z line
436
+ # "x" => {"0"=>"0", "1"=>"x", "z"=>"x", "x"=>"x"} } # x line
437
+ AND_T = [ [ 0, 0, 0, 0 ], # 0 line
438
+ [ 0, 1, 3, 3 ], # 1 line
439
+ [ 0, 3, 3, 3 ], # z line
440
+ [ 0, 3, 3, 3 ] ] # x line
281
441
 
282
442
  # Or truth table: 0, 1, 2=z, 3=x
283
- OR_T = { "0" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"}, # 0 line
284
- "1" => {"0"=>"1", "1"=>"1", "z"=>"1", "x"=>"1"}, # 1 line
285
- "z" => {"0"=>"x", "1"=>"1", "z"=>"x", "x"=>"x"}, # z line
286
- "x" => {"0"=>"x", "1"=>"1", "z"=>"x", "x"=>"x"} } # x line
443
+ # OR_T = { "0" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"}, # 0 line
444
+ # "1" => {"0"=>"1", "1"=>"1", "z"=>"1", "x"=>"1"}, # 1 line
445
+ # "z" => {"0"=>"x", "1"=>"1", "z"=>"x", "x"=>"x"}, # z line
446
+ # "x" => {"0"=>"x", "1"=>"1", "z"=>"x", "x"=>"x"} } # x line
447
+ OR_T = [ [ 0, 1, 3, 3 ], # 0 line
448
+ [ 1, 1, 1, 1 ], # 1 line
449
+ [ 3, 1, 3, 3 ], # z line
450
+ [ 3, 1, 3, 3 ] ] # x line
287
451
 
288
452
  # Xor truth table: 0, 1, 2=z, 3=x
289
- XOR_T = { "0" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"}, # 0 line
290
- "1" => {"0"=>"1", "1"=>"0", "z"=>"x", "x"=>"x"}, # 1 line
291
- "z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"}, # z line
292
- "x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} } # x line
293
-
294
- # Double xor truth table: 0, 1, 2=z, 3=x
295
- XOR3_T={ "0" => {
296
- "0" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"},
297
- "1" => {"0"=>"1", "1"=>"0", "z"=>"x", "x"=>"x"},
298
- "z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
299
- "x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} }, # 0 line
300
- "1" => {
301
- "0" => {"0"=>"1", "1"=>"0", "z"=>"x", "x"=>"x"},
302
- "1" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"},
303
- "z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
304
- "x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} }, # 1 line
305
- "z" => {
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"} }, # z line
310
- "x" => {
311
- "0" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
312
- "1" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
313
- "z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
314
- "x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} } }# x line
315
-
316
- # Majority truth table: 0, 1, 2=z, 3=x
317
- MAJ_T= { "0" => {
318
- "0" => {"0"=>"0", "1"=>"0", "z"=>"0", "x"=>"0"},
319
- "1" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"},
320
- "z" => {"0"=>"0", "1"=>"x", "z"=>"x", "x"=>"x"},
321
- "x" => {"0"=>"0", "1"=>"x", "z"=>"x", "x"=>"x"} }, # "0" line
322
- "1" => {
323
- "0" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"},
324
- "1" => {"0"=>"1", "1"=>"1", "z"=>"1", "x"=>"1"},
325
- "z" => {"0"=>"x", "1"=>"1", "z"=>"x", "x"=>"x"},
326
- "x" => {"0"=>"x", "1"=>"1", "z"=>"x", "x"=>"x"} }, # "1" line
327
- "z" => {
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"} }, # z line
332
- "x" => {
333
- "0" => {"0"=>"0", "1"=>"x", "z"=>"x", "x"=>"x"},
334
- "1" => {"0"=>"x", "1"=>"1", "z"=>"x", "x"=>"x"},
335
- "z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
336
- "x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} } }# x line
337
-
338
- # Lower than truth table: 0, 1, 2=z, 3=x
339
- LT_T = { "0" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"}, # 0 line
340
- "1" => {"0"=>"0", "1"=>"0", "z"=>"x", "x"=>"x"}, # 1 line
341
- "z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"}, # z line
342
- "x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} } # x line
343
-
344
- # Greater than truth table: 0, 1, 2=z, 3=x
345
- GT_T = { "0" => {"0"=>"0", "1"=>"0", "z"=>"x", "x"=>"x"}, # 0 line
346
- "1" => {"0"=>"1", "1"=>"0", "z"=>"x", "x"=>"x"}, # 1 line
347
- "z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"}, # z line
348
- "x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} } # x line
349
-
350
- # Table of bitwise operations
351
- BITWISE = { :+ => :bitwise_add0,
352
- :- => :bitwise_sub0,
353
- :-@ => :bitwise_neg0,
354
- :+@ => :bitwise_pos,
355
- :* => :bitwise_mul0,
356
- :/ => :bitwise_div0,
357
- :% => :bitwise_mod0,
358
- :** => :bitwise_pow0,
359
- :& => :bitwise_and,
360
- :| => :bitwise_or,
361
- :^ => :bitwise_xor,
362
- :~ => :bitwise_not,
363
- :<< => :bitwise_shl,
364
- :>> => :bitwise_shr,
365
- :== => :bitwise_eq0,
366
- :< => :bitwise_lt0,
367
- :> => :bitwise_gt0,
368
- :<= => :bitwise_le0,
369
- :>= => :bitwise_ge0,
370
- :<=>=> :bitwise_cp0
371
- }
372
-
373
-
374
-
375
- # Binary operations
376
-
377
- [:+, :-, :*, :/, :%, :**, :&, :|, :^,
378
- :<<, :>>,
379
- :==, :<, :>, :<=, :>=, :<=>].each do |op|
380
- # Select the bitwise operation.
381
- bitwise = BITWISE[op]
382
- # Define the operation method.
383
- define_method(op) do |value|
384
- # Check the value.
385
- unless value.is_a?(Numeric) then
386
- value = value.to_numeric if value.specified?
387
- end
388
- # Can the computation be performed with Ruby numeric values?
389
- if self.specified? and value.is_a?(Numeric) then
390
- # Yes, do it.
391
- if (op == :/ or op == :%) and value == 0 then
392
- # Division by 0.
393
- return UNKNOWN.extend(self.size)
453
+ # XOR_T = { "0" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"}, # 0 line
454
+ # "1" => {"0"=>"1", "1"=>"0", "z"=>"x", "x"=>"x"}, # 1 line
455
+ # "z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"}, # z line
456
+ # "x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} } # x line
457
+ XOR_T = [ [ 0, 1, 3, 3 ], # 0 line
458
+ [ 1, 0, 3, 3 ], # 1 line
459
+ [ 3, 3, 3, 3 ], # z line
460
+ [ 3, 3, 3, 3 ] ] # x line
461
+
462
+ LOGIC_T = [ AND_T, OR_T, XOR_T ]
463
+
464
+ # # Double xor truth table: 0, 1, 2=z, 3=x
465
+ # XOR3_T={ "0" => {
466
+ # "0" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"},
467
+ # "1" => {"0"=>"1", "1"=>"0", "z"=>"x", "x"=>"x"},
468
+ # "z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
469
+ # "x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} }, # 0 line
470
+ # "1" => {
471
+ # "0" => {"0"=>"1", "1"=>"0", "z"=>"x", "x"=>"x"},
472
+ # "1" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"},
473
+ # "z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
474
+ # "x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} }, # 1 line
475
+ # "z" => {
476
+ # "0" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
477
+ # "1" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
478
+ # "z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
479
+ # "x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} }, # z line
480
+ # "x" => {
481
+ # "0" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
482
+ # "1" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
483
+ # "z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
484
+ # "x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} } }# x line
485
+
486
+ # # Majority truth table: 0, 1, 2=z, 3=x
487
+ # MAJ_T= { "0" => {
488
+ # "0" => {"0"=>"0", "1"=>"0", "z"=>"0", "x"=>"0"},
489
+ # "1" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"},
490
+ # "z" => {"0"=>"0", "1"=>"x", "z"=>"x", "x"=>"x"},
491
+ # "x" => {"0"=>"0", "1"=>"x", "z"=>"x", "x"=>"x"} }, # "0" line
492
+ # "1" => {
493
+ # "0" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"},
494
+ # "1" => {"0"=>"1", "1"=>"1", "z"=>"1", "x"=>"1"},
495
+ # "z" => {"0"=>"x", "1"=>"1", "z"=>"x", "x"=>"x"},
496
+ # "x" => {"0"=>"x", "1"=>"1", "z"=>"x", "x"=>"x"} }, # "1" line
497
+ # "z" => {
498
+ # "0" => {"0"=>"0", "1"=>"x", "z"=>"x", "x"=>"x"},
499
+ # "1" => {"0"=>"x", "1"=>"1", "z"=>"x", "x"=>"x"},
500
+ # "z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
501
+ # "x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} }, # z line
502
+ # "x" => {
503
+ # "0" => {"0"=>"0", "1"=>"x", "z"=>"x", "x"=>"x"},
504
+ # "1" => {"0"=>"x", "1"=>"1", "z"=>"x", "x"=>"x"},
505
+ # "z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
506
+ # "x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} } }# x line
507
+
508
+ # # Lower than truth table: 0, 1, 2=z, 3=x
509
+ # LT_T = { "0" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"}, # 0 line
510
+ # "1" => {"0"=>"0", "1"=>"0", "z"=>"x", "x"=>"x"}, # 1 line
511
+ # "z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"}, # z line
512
+ # "x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} } # x line
513
+
514
+ # # Greater than truth table: 0, 1, 2=z, 3=x
515
+ # GT_T = { "0" => {"0"=>"0", "1"=>"0", "z"=>"x", "x"=>"x"}, # 0 line
516
+ # "1" => {"0"=>"1", "1"=>"0", "z"=>"x", "x"=>"x"}, # 1 line
517
+ # "z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"}, # z line
518
+ # "x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} } # x line
519
+
520
+ # The logic binary operators.
521
+ [:&, :|, :^].each_with_index do |op,logic_num|
522
+ tbl = LOGIC_T[logic_num]
523
+ define_method(op) do |val|
524
+ # puts "op=#{op} @content = #{@content} val=#{val} val.class=#{val.class}"
525
+ if val.is_a?(BitString) then
526
+ if self.specified? && val.specified? then
527
+ return self.to_i.send(op,val.to_i)
394
528
  end
395
- res = self.to_numeric.send(op,value)
396
- # Maybe the result was a boolean, change it to an integer
397
- res = res ? 1 : 0 unless res.is_a?(Numeric)
398
- return res
529
+ elsif val.is_a?(Numeric) && self.specified? then
530
+ return self.to_i.send(op,val)
399
531
  else
400
- # # No, is it a multiplication, division, modulo, or pow?
401
- # # If it is the case, only specific values can be computed
402
- # # otherwise the result is unspecified.
403
- # case op
404
- # when :* then
405
- # svalue = self.specified? ? self.to_numeric : self
406
- # return BitString.multiplication(svalue,value)
407
- # when :/ then
408
- # svalue = self.specified? ? self.to_numeric : self
409
- # return BitString.division(svalue,value)
410
- # when :% then
411
- # svalue = self.specified? ? self.to_numeric : self
412
- # return BitString.modulo(svalue,value)
413
- # when :** then
414
- # svalue = self.specified? ? self.to_numeric : self
415
- # return BitString.pow(svalue,value)
416
- # end
417
- # No, do it bitwise.
418
- # Ensure value is a bit string.
419
- s1 = value.is_a?(BitString) ? value : BitString.new(value)
420
- s0 = self
421
- # # Convert to list of bits.
422
- # value = value.to_list
423
- # slist = self.to_list
424
- # # Adjust the sizes.
425
- # if value.size < slist.size then
426
- # value += [value[-1]] * (slist.size - value.size)
427
- # elsif value.size > slist.size then
428
- # slist += [slist[-1]] * (value.size - slist.size)
429
- # end
430
- # # Perform the bitwise computation on the lists of bits
431
- # res = BitString.send(bitwise,slist,value)
432
- # return BitString.new(res[0..-2],res[-1])
433
-
434
- # Adjust the widths
435
- if s0.width < s1.width then
436
- s0 = s0.extend(s1.width)
437
- elsif s1.width < s0.width then
438
- s1 = s1.extend(s0.width)
439
- end
440
- # Perform the bitwise computation.
441
- return BitString.send(bitwise,s0,s1)
532
+ val = BitString.new(val)
442
533
  end
443
- end
444
- end
445
-
446
- # Unary operations
447
-
448
- [:+@, :-@, :~].each do |op|
449
- # Select the bitwise operation.
450
- bitwise = BITWISE[op]
451
- # Define the operation method.
452
- define_method(op) do
453
- # Can the computation be performed with Ruby numeric values?
454
- if self.specified? then
455
- # Yes, do it.
456
- return self.to_numeric.send(op)
457
- else
458
- # No, do it bitwise.
459
- # Perform the bitwise computiation on the lists of bits
460
- # res = BitString.send(bitwise,self.to_list)
461
- # return BitString.new(res[0..-2],res[-1])
462
- return BitString.send(bitwise,self)
534
+ vcontent = val.raw_content
535
+ width = vcontent.size > @content.size ? vcontent.size : @content.size
536
+ res_content = width.times.map do |i|
537
+ # Get the bits to compute with
538
+ b0 = @content[i]
539
+ b0 = @content[-1] unless b0
540
+ # Compute
541
+ b1 = vcontent[i]
542
+ b1 = vcontent[-1] unless b1
543
+ tbl[b0][b1]
463
544
  end
545
+ return BitString.new(res_content,:raw)
464
546
  end
465
547
  end
466
548
 
467
-
468
- # Bitwise operations: assume same bit width.
469
-
470
- # Bitwise addition without processing of the x and z states.
471
- def self.bitwise_add0(s0,s1)
472
- return BitString.new("x"*(s0.width+1))
473
- end
474
-
475
- # Bitwise addition
476
- def self.bitwise_add(s0,s1)
477
- res = "" # The result list of bits
478
- c = "0" # The current carry
479
- s0.each.zip(s1.each) do |b0,b1|
480
- res << XOR3_T[b0][b1][c]
481
- c = MAJ_T[b0][b1][c]
482
- end
483
- # Compute the sign extension (the sign bit of s0 and s1 is used
484
- # again)
485
- res << XOR3_T[s0.sign][s1.sign][c]
486
- return BitString.new(res.reverse)
487
- end
488
-
489
- # Bitwise subtraction without processing of the x and z states.
490
- def self.bitwise_sub0(s0,s1)
491
- return BitString.new("x"*(s0.width+1))
492
- end
493
-
494
- # Bitwise subtraction
495
- def self.bitwise_sub(s0,s1)
496
- # # Negate s1.
497
- # s1 = BitString.bitwise_neg(s1).trunc(s0.width)
498
- # # puts "s1.width = #{s1.width} s0.width = #{s0.width}"
499
- # # Add it to s0: but no need to add a bit since neg already added
500
- # # one.
501
- # return BitString.bitwise_add(s0,s1)
502
- # Perform the computation is a way to limit the propagation of
503
- # unspecified bits.
504
- # Is s1 specified?
505
- if s1.specified? then
506
- # Yes, perform -s1+s0
507
- return (-s1 + s0)
508
- else
509
- # No, perform s0+1+NOT(s1).
510
- # puts "s0=#{s0} s0+1=#{s0+1} not s1=#{bitwise_not(s1)}"
511
- return (s0 + 1 + bitwise_not(s1)).trunc(s0.width+1)
512
- end
513
- end
514
-
515
- # Bitwise positive sign: does nothing.
516
- def self.bitwise_pos(s)
517
- return s
518
- end
519
-
520
- # Bitwise negation without processing of the x and z states.
521
- def self.bitwise_neg0(s)
522
- return BitString.new("x"*(s.width+1))
523
- end
524
-
525
- # Bitwise negation
526
- def self.bitwise_neg(s)
527
- # -s = ~s + 1
528
- # # Not s.
529
- # s = BitString.bitwise_not(s)
530
- # # Add 1.
531
- # return BitString.bitwise_add(s,ONE.extend(s.width))
532
- return ~s + 1
533
- end
534
-
535
- # Bitwise and
536
- def self.bitwise_and(s0,s1)
537
- res = s0.each.zip(s1.each).map { |b0,b1| AND_T[b0][b1] }.join
538
- # puts "s0=#{s0}, s1=#{s1}, res=#{res}"
539
- return BitString.new(res.reverse)
540
- end
541
-
542
- # Bitwise or
543
- def self.bitwise_or(s0,s1)
544
- res = s0.each.zip(s1.each). map { |b0,b1| OR_T[b0][b1] }.join
545
- return BitString.new(res.reverse)
546
- end
547
-
548
- # Bitwise xor
549
- def self.bitwise_xor(s0,s1)
550
- res = s0.each.zip(s1.each). map { |b0,b1| XOR_T[b0][b1] }.join
551
- return BitString.new(res.reverse)
552
- end
553
-
554
- # Bitwise not
555
- def self.bitwise_not(s)
556
- return BitString.new(s.each.map { |b| NOT_T[b] }.join.reverse)
557
- end
558
-
559
- # Bitwise shift left.
560
- def self.bitwise_shl(s0,s1)
561
- # puts "s0=#{s0} s1=#{s1}"
562
- return BitString.new("x" * s0.width) unless s1.specified?
563
- s1 = s1.to_numeric
564
- if s1 >= 0 then
565
- return BitString.new(s0.str + "0" * s1)
566
- elsif -s1 > s0.width then
567
- return ZERO
568
- else
569
- return s0.trim(s0.width+s1)
570
- end
571
- end
572
-
573
- # Bitwise shift right.
574
- def self.bitwise_shr(s0,s1)
575
- # puts "s0=#{s0} s1=#{s1}"
576
- return BitString.new("x" * s0.width) unless s1.specified?
577
- s1 = s1.to_numeric
578
- if s1 <= 0 then
579
- return BitString.new(s0.str + "0" * -s1)
580
- elsif s1 > s0.width then
581
- return ZERO
582
- else
583
- return s0.trim(s0.width-s1)
584
- end
585
- end
586
-
587
-
588
- # Bitwise eq without processing of the x and z states.
589
- def self.bitwise_eq0(s0,s1)
590
- return UNKNOWN
591
- end
592
-
593
- # Bitwise eq.
594
- def self.bitwise_eq(s0,s1)
595
- return UNKNOWN unless (s0.specified? and s1.specified?)
596
- return s0.str == s1.str ? TRUE : FALSE
597
- end
598
-
599
-
600
- # Bitwise lt without processing of the x and z states.
601
- def self.bitwise_lt0(s0,s1)
602
- return UNKNOWN
603
- end
604
-
605
- # Bitwise lt.
606
- def self.bitwise_lt(s0,s1)
607
- # # Handle the zero cases.
608
- # if s0.zero? then
609
- # return TRUE if s1.positive?
610
- # return FALSE if s1.negative? or s1.zero?
611
- # return UNKNOWN
612
- # elsif s1.zero? then
613
- # return TRUE if s0.negative?
614
- # return FALSE if s0.positive? or s0.zero?
615
- # return UNKNOWN
616
- # end
617
- # # Handle the unspecified sign cases.
618
- # unless s0.sign? then
619
- # # Check both sign cases.
620
- # lt_pos = self.bitwise_lt(s0[-1] = "1",s1)
621
- # lt_neg = self.bitwise_lt(s0[-1] = "0",s1)
622
- # # At least one of the results is unspecified.
623
- # return UNKNOWN unless (lt_pos.specified? and lt_neg.specified?)
624
- # # Both results are specified and identical.
625
- # return lt_pos if lt_pos == lt_neg
626
- # # Results are different.
627
- # return UNKNOWN
628
- # end
629
- # unless s1.sign? then
630
- # # Check both sign cases.
631
- # lt_pos = self.bitwise_lt(s0,s1[-1] = "1")
632
- # lt_neg = self.bitwise_lt(s0,s1[-1] = "0")
633
- # # At least one of the results is unspecified.
634
- # return UNKNOWN unless (lt_pos.specified? and lt_neg.specified?)
635
- # # Both results are specified and identical.
636
- # return lt_pos if lt_pos == lt_neg
637
- # # Results are different.
638
- # return UNKNOWN
639
- # end
640
- # # Signs are specificied.
641
- # # Depending on the signs
642
- # if s0.positive? then
643
- # if s1.positive? then
644
- # # s0 and s1 are positive, need to compare each bit.
645
- # s0.reverse_each.zip(s1.reverse_each) do |b0,b1|
646
- # # puts "b0=#{b0} b1=#{b1}, LT_T[b0][b1]=#{LT_T[b0][b1]}"
647
- # case LT_T[b0][b1]
648
- # when "x" then return UNKNOWN
649
- # when "1" then return TRUE
650
- # when "0" then
651
- # return FALSE if GT_T[b0][b1] == "1"
652
- # end
653
- # end
654
- # elsif s1.negative? then
655
- # # s0 is positive and s1 is negative.
656
- # return FALSE
657
- # else
658
- # # The sign of s1 is undefined, comparison is undefined too.
659
- # return UNKNOWN
660
- # end
661
- # elsif s0.negative? then
662
- # if s1.positive? then
663
- # # s0 is negative and s1 is positive
664
- # return TRUE
665
- # elsif s1.negative? then
666
- # # s0 and s1 are negative, need to compare each bit.
667
- # s0.reverse_each.zip(s1.reverse_each) do |b0,b1|
668
- # case GT_T[b0][b1]
669
- # when "x" then return UNKNOWN
670
- # when "1" then return FALSE
671
- # when "0" then
672
- # return TRUE if LT_T[b0][b1] == "1"
673
- # end
674
- # end
675
- # end
676
- # else
677
- # # The sign of s0 is undefined, comparison is undefined too.
678
- # return UNKNOWN
679
- # end
680
-
681
- # Check the sign of the subtraction between s0 and s1.
682
- case (s0-s1).sign
683
- when "0" then return FALSE
684
- when "1" then return TRUE
685
- else
686
- return UNKNOWN
687
- end
688
- end
689
-
690
-
691
- # Bitwise gt without processing of the x and z states.
692
- def self.bitwise_gt0(s0,s1)
693
- return UNKNOWN
694
- end
695
-
696
- # Bitwise gt.
697
- def self.bitwise_gt(s0,s1)
698
- return self.bitwise_lt(s1,s0)
699
- end
700
-
701
-
702
- # Bitwise le without processing of the x and z states.
703
- def self.bitwise_le0(s0,s1)
704
- return UNKNOWN
705
- end
706
-
707
- # Bitwise le.
708
- def self.bitwise_le(s0,s1)
709
- gt = self.bitwise_gt(s0,s1)
710
- if gt.eql?(TRUE) then
711
- return FALSE
712
- elsif gt.eql?(FALSE) then
713
- return TRUE
549
+ # The unary logic operator.
550
+ define_method(:~) do
551
+ if self.specified? then
552
+ return ~self.to_i
714
553
  else
715
- return UNKNOWN
554
+ return BitString.new(@content.map {|b| NOT_T[b]},:raw)
716
555
  end
717
556
  end
718
557
 
719
-
720
- # Bitwise ge without processing of the x and z states.
721
- def self.bitwise_ge0(s0,s1)
722
- return UNKNOWN
723
- end
724
-
725
- # Bitwise ge.
726
- def self.bitwise_ge(s0,s1)
727
- lt = self.bitwise_lt(s0,s1)
728
- if lt.eql?(TRUE) then
729
- return FALSE
730
- elsif lt.eql?(FALSE) then
731
- return TRUE
732
- else
733
- return UNKNOWN
558
+ # The shift operators.
559
+ define_method(:<<) do |val|
560
+ if val.is_a?(BitString) then
561
+ return UNKNOWN.clone unless val.specified?
734
562
  end
563
+ return BitString.new(([0]*val.to_i) + @content,:raw)
735
564
  end
736
-
737
-
738
- # Bitwise cp without processing of the x and z states.
739
- def self.bitwise_cp0(s0,s1)
740
- return UNKNOWN
741
- end
742
-
743
- # Bitwise cp.
744
- def self.bitwise_cp(s0,s1)
745
- # Compare the signs.
746
- if s0.sign == "0" and s1.sign == "1" then
747
- return ONE
748
- elsif s0.sign == 0 and s1.sign == "1" then
749
- return MINUS_ONE
565
+ define_method(:>>) do |val|
566
+ if val.is_a?(BitString) then
567
+ return UNKNOWN unless val.specified?
750
568
  end
751
- # Compare the other bits.
752
- sub = self.bitwise_sub(s0,s1)
753
- if sub.negative? then
754
- return MINUS_ONE
755
- elsif sub.zero? then
756
- return ZERO
757
- elsif sub.positive? then
758
- return ONE
759
- else
760
- return UNKNOWN
569
+ val = val.to_i
570
+ val = @content.size if val > @content.size
571
+ res_content = @content[val..-1]
572
+ res_content << @content[-1] if res_content.empty?
573
+ return BitString.new(res_content,:raw)
574
+ end
575
+
576
+ # The arithmetic binary operators.
577
+ [:+, :-, :*, :**].each_with_index do |op|
578
+ define_method(op) do |val|
579
+ return UNKNOWN.clone unless self.specified?
580
+ return UNKNOWN.clone if val.is_a?(BitString) && !val.specified?
581
+ return self.to_i.send(op,val.to_i)
761
582
  end
762
583
  end
763
584
 
764
- # Bitwise mul without processing of the x and z states.
765
- def self.bitwise_mul0(s0,s1)
766
- return BitString.new("x"*(s0.width+s1.width))
767
- end
768
-
769
- # Bitwise mul.
770
- def self.bitwise_mul(s0,s1)
771
- # Initialize the result to ZERO of combined s0 and s1 widths
772
- res = ZERO.extend(s0.width + s1.width)
773
- # The zero cases.
774
- if s0.zero? or s1.zero? then
775
- return res
776
- end
777
- # Convert s1 and res to lists of bits which support computation
778
- # between unknown bits of same values.
779
- s1 = s1.extend(res.width).to_list
780
- res = res.to_list
781
- # The other cases: perform a multiplication with shifts and adds.
782
- s0.each.lazy.take(s0.width).each do |b|
783
- case b
784
- when "1" then self.list_add!(res,s1)
785
- when "x","z" then self.list_add!(res,self.list_and_unknown(s1))
786
- end
787
- # puts "res=#{res} s1=#{s1}"
788
- self.list_shl_1!(s1)
789
- end
790
- # Add the sign row.
791
- case s0.sign
792
- when "1" then self.list_sub!(res,s1)
793
- when "x","z" then self.list_sub!(res,list_and_unknown(s1))
585
+ # The dividing binary operators.
586
+ [:/, :%].each_with_index do |op|
587
+ define_method(op) do |val|
588
+ return UNKNOWN.clone unless self.specified?
589
+ return UNKNOWN.clone if val.is_a?(BitString) && !val.specified?
590
+ val = val.to_i
591
+ return UNKNOWN.clone if val == 0
592
+ return self.to_i.send(op,val)
794
593
  end
795
- # Return the result.
796
- return self.list_to_bstr(res)
797
594
  end
798
595
 
799
- # Bitwise div without processing of the x and z states.
800
- def self.bitwise_div0(s0,s1)
801
- return BitString.new("x"*(s0.width))
596
+ # The arithmetic unary operator.
597
+ define_method(:+@) do
598
+ return self.clone
802
599
  end
803
-
804
- # Bitwise div.
805
- def self.bitwise_div(s0,s1)
806
- width = s0.width
807
- # The zero cases.
808
- if s0.zero? then
809
- return res
810
- elsif s1.maybe_zero? then
811
- return UNKNOWN.extend(width)
812
- end
813
- # Handle the sign: the division is only performed on positive
814
- # numbers.
815
- # NOTE: we are sure that s0 and s1 are not zero since these
816
- # cases have been handled before.
817
- sign = nil
818
- if s0.sign == "0" then
819
- if s1.sign == "0" then
820
- sign = "0"
821
- elsif s1.sign == "1" then
822
- sign = "1"
823
- s1 = -s1
824
- else
825
- # Unknown sign, unkown result.
826
- return UNKNOWN.extend(width)
827
- end
828
- elsif s0.sign == "1" then
829
- s0 = -s0
830
- if s1.sign == "0" then
831
- sign = "1"
832
- elsif s1.sign == "1" then
833
- sign = "0"
834
- s1 = -s1
835
- else
836
- # Unknwown sign, unknown result.
837
- return UNKNOWN.extend(width)
838
- end
600
+ define_method(:-@) do
601
+ if self.specified? then
602
+ return -self.to_i
839
603
  else
840
- # Unknown sign, unknown result.
841
- return UNKNOWN.extend(width)
604
+ return UNKNOWN.clone
842
605
  end
843
- # Convert s0 and s1 to list of bits of widths of s0 and s1 -1
844
- # (the largest possible value).
845
- # s0 will serve as current remainder.
846
- s0 = BitString.new(s0) if s0.is_a?(Numeric)
847
- s1 = BitString.new(s1) if s1.is_a?(Numeric)
848
- s0 = s0.extend(s0.width+s1.width-1)
849
- s1 = s1.extend(s0.width)
850
- s0 = s0.to_list
851
- s1 = s1.to_list
852
- puts "first s1=#{s1}"
853
- # Adujst s1 to the end of s0 and the corresponding 0s in front of q
854
- msb = s0.reverse.index {|b| b != 0}
855
- steps = s0.size-msb
856
- self.list_shl!(s1,steps-1)
857
- q = [ 0 ] * (width-steps)
858
- # Apply the non-restoring division algorithm.
859
- sub = true
860
- puts "steps= #{steps} s0=#{s0} s1=#{s1} q=#{q}"
861
- (steps).times do |i|
862
- if sub then
863
- self.list_sub!(s0,s1)
864
- else
865
- self.list_add!(s0,s1)
866
- end
867
- puts "s0=#{s0}"
868
- # Is the result positive?
869
- if s0[-1] == 0 then
870
- # Yes, the next step is a subtraction and the current
871
- # result bit is one.
872
- sub = true
873
- q.unshift(1)
874
- elsif s0[-1] == 1 then
875
- # No, it is negative the next step is an addition and the
876
- # current result bit is zero.
877
- sub = false
878
- q.unshift(0)
879
- else
880
- # Unknown sign, the remaining of q is unknown.
881
- (steps-i).times { q.unshift(self.new_unknown) }
882
- # Still, can add the positive sign bit.
883
- q.push(0)
884
- break
885
- end
886
- self.list_shr_1!(s1)
887
- end
888
- # Generate the resulting bit string.
889
- puts "q=#{q}"
890
- q = self.list_to_bstr(q)
891
- puts "q=#{q}"
892
- # Set the sign.
893
- if sign == "1" then
894
- q = (-q).trunc(width)
895
- elsif q.zero? then
896
- q = 0
897
- else
898
- q = q.extend(width)
899
- end
900
- # Return the result.
901
- return q
902
606
  end
903
607
 
904
-
905
- # Bitwise mod without processing of the x and z states.
906
- def self.bitwise_mod0(s0,s1)
907
- return BitString.new("x"*(s1.width))
908
- end
909
-
910
- # Bitwise mod.
911
- def self.bitwise_div(s0,s1)
912
- raise "bitwise_div is not implemented yet."
913
- end
914
-
915
-
916
- # Computation with list of bits:
917
- # "0" -> 0, "1" -> 1, and then 2, 3, 4, ...
918
- # Allows more precise computations (e.g., mul, div).
919
-
920
- # The counter of unknown bits.
921
- @@unknown = 1
922
-
923
- # Creates a new uniq unknown bit.
924
- def self.new_unknown
925
- @@unknown += 1
926
- return @@unknown
927
- end
928
-
929
- # Converts to a list of bits where unknown or high z bits are
930
- # differentiate from each other.
931
- #
932
- # NOTE:
933
- # * the sign bit is also added to the list.
934
- # * the distinction between z and x is lost.
935
- def to_list
936
- return @str.each_char.reverse_each.map.with_index do |b,i|
937
- case b
938
- when "0" then 0
939
- when "1" then 1
940
- when "z","x" then BitString.new_unknown
941
- else
942
- raise "Internal error: invalid bit in bitstring: #{b}"
943
- end
608
+ # The comparison operators.
609
+ [:==, :!=, :<, :>, :<=, :>=].each_with_index do |op|
610
+ define_method(op) do |val|
611
+ return UNKNOWN.clone unless self.specified?
612
+ return UNKNOWN.clone if val.is_a?(BitString) && !val.specified?
613
+ return self.to_i.send(op,val.to_i) ? 1 : 0
944
614
  end
945
615
  end
946
616
 
947
- # Converts list of bits +l+ to a bit string.
948
- def self.list_to_bstr(l)
949
- str = l.reverse_each.map { |b| b > 1 ? "x" : b }.join
950
- return BitString.new(str)
951
- end
952
617
 
953
- # Compute the and between +l+ and an unknown value.
954
- def self.list_and_unknown(l)
955
- return l.map do |b|
956
- b == 0 ? 0 : BitString.new_unknown
957
- end
958
- end
959
618
 
960
- # Compute the not of +l+
961
- def self.list_not(l)
962
- return l.map do |b|
963
- case b
964
- when 0 then 1
965
- when 1 then 0
966
- else
967
- BitString.new_unknown
968
- end
969
- end
970
- end
971
619
 
972
- # Adds +l1+ to +l0+.
620
+ # # Table of bitwise operations
621
+ # BITWISE = { :+ => :bitwise_add0,
622
+ # :- => :bitwise_sub0,
623
+ # :-@ => :bitwise_neg0,
624
+ # :+@ => :bitwise_pos,
625
+ # :* => :bitwise_mul0,
626
+ # :/ => :bitwise_div0,
627
+ # :% => :bitwise_mod0,
628
+ # :** => :bitwise_pow0,
629
+ # :& => :bitwise_and,
630
+ # :| => :bitwise_or,
631
+ # :^ => :bitwise_xor,
632
+ # :~ => :bitwise_not,
633
+ # :<< => :bitwise_shl,
634
+ # :>> => :bitwise_shr,
635
+ # :== => :bitwise_eq0,
636
+ # :!= => :bitwise_neq0,
637
+ # :< => :bitwise_lt0,
638
+ # :> => :bitwise_gt0,
639
+ # :<= => :bitwise_le0,
640
+ # :>= => :bitwise_ge0,
641
+ # :<=>=> :bitwise_cp0
642
+ # }
643
+
644
+
645
+
646
+ # # Binary operations
647
+
648
+ # [:+, :-, :*, :/, :%, :**, :&, :|, :^,
649
+ # :<<, :>>,
650
+ # :==, :!=, :<, :>, :<=, :>=, :<=>].each do |op|
651
+ # # Select the bitwise operation.
652
+ # bitwise = BITWISE[op]
653
+ # # Define the operation method.
654
+ # define_method(op) do |value, sign0 = false, sign1 = false|
655
+ # # puts "op=#{op}, value=#{value}"
656
+ # # Check the value.
657
+ # unless value.is_a?(Numeric) || !value.specified? then
658
+ # value = sign1 ? value.to_numeric_signed : value.to_numeric
659
+ # end
660
+ # # Can the computation be performed with Ruby numeric values?
661
+ # if self.specified? and value.is_a?(Numeric) then
662
+ # # Yes, do it.
663
+ # if (op == :/ or op == :%) and value == 0 then
664
+ # # Division by 0.
665
+ # return UNKNOWN.sext(self.size)
666
+ # end
667
+ # res = sign0 ? self.to_numeric_signed.send(op,value) :
668
+ # self.to_numeric.send(op,value)
669
+ # # Maybe the result was a boolean, change it to an integer
670
+ # res = res ? 1 : 0 unless res.is_a?(Numeric)
671
+ # return res
672
+ # else
673
+ # # No, do it bitwise.
674
+ # # Ensure value is a bit string.
675
+ # s1 = value.is_a?(BitString) ? value : BitString.new(value)
676
+ # s0 = self
677
+ # # Adjust the widths
678
+ # if s0.width < s1.width then
679
+ # s0 = s0.xext(s1.width)
680
+ # elsif s1.width < s0.width then
681
+ # s1 = s1.xext(s0.width)
682
+ # end
683
+ # # Perform the bitwise computation.
684
+ # return BitString.send(bitwise,s0,s1)
685
+ # end
686
+ # end
687
+ # end
688
+
689
+ # # Unary operations
973
690
  #
974
- # NOTE:
975
- # * l0 is contains the result.
976
- # * The result has the same size as +l0+ (no sign extension).
977
- # * Assumes +l0+ and +l1+ have the same size.
978
- def self.list_add!(l0,l1)
979
- # puts "add l0=#{l0} l1=#{l1}"
980
- c = 0 # Current carry.
981
- l0.each_with_index do |b0,i|
982
- b1 = l1[i]
983
- # puts "i=#{i} b0=#{b0} b1=#{b1} c=#{c}"
984
- if b0 == b1 then
985
- # The sum is c.
986
- l0[i] = c
987
- # The carry is b0.
988
- c = b0
989
- elsif b0 == c then
990
- # The sum is b1.
991
- l0[i] = b1
992
- # The carry is b0.
993
- c = b0
994
- elsif b1 == c then
995
- # The sum is b0.
996
- l0[i] = b0
997
- # The carry is b1.
998
- c = b1
999
- else
1000
- l0[i] = self.new_unknown
1001
- c = self.new_unknown
1002
- end
1003
- end
1004
- return l0
1005
- end
1006
-
1007
- # Adds 1 to +l0+.
691
+ # [:+@, :-@, :~].each do |op|
692
+ # # Select the bitwise operation.
693
+ # bitwise = BITWISE[op]
694
+ # # Define the operation method.
695
+ # define_method(op) do
696
+ # # Can the computation be performed with Ruby numeric values?
697
+ # if self.specified? then
698
+ # # Yes, do it.
699
+ # return self.to_numeric.send(op)
700
+ # else
701
+ # # No, do it bitwise.
702
+ # # Perform the bitwise computiation on the lists of bits
703
+ # # res = BitString.send(bitwise,self.to_list)
704
+ # # return BitString.new(res[0..-2],res[-1])
705
+ # return BitString.send(bitwise,self)
706
+ # end
707
+ # end
708
+ # end
709
+
710
+
711
+
712
+ # # Bitwise operations: assume same bit width.
1008
713
  #
1009
- # NOTE:
1010
- # * l0 is contains the result.
1011
- # * The result has the same size as +l0+ (no sign extension).
1012
- def self.list_add_1!(l0)
1013
- c = 1 # Current carry.
1014
- l0.each_with_index do |b0,i|
1015
- if c == 0 then
1016
- # The sum is b0.
1017
- l0[i] = b0
1018
- # The carry is unchanged.
1019
- elsif b0 == 0 then
1020
- # The sum is c.
1021
- l0[i] = c
1022
- # The carry is 0.
1023
- c = 0
1024
- elsif b0 == c then
1025
- # The sum is 0.
1026
- l0[i] = 0
1027
- # The carry is b0.
1028
- c = b0
1029
- else
1030
- # Both sum and carry are unknown
1031
- l0[i] = BitString.new_unknown
1032
- c = BitString.new_unknown
1033
- end
1034
- end
1035
- return l0
1036
- end
1037
-
1038
- # Subtracts +l1+ from +l0+.
714
+ # # Bitwise addition without processing of the x and z states.
715
+ # def self.bitwise_add0(s0,s1)
716
+ # return BitString.new("x"*(s0.width+1))
717
+ # end
1039
718
  #
1040
- # NOTE:
1041
- # * l0 is contains the result.
1042
- # * The result has the same size as +l0+ (no sign extension).
1043
- # * Assumes +l0+ and +l1+ have the same size.
1044
- def self.list_sub!(l0,l1)
1045
- # Adds 1 to l0.
1046
- BitString.list_add_1!(l0)
1047
- # Adds ~l1 to l0.
1048
- # puts "l0=#{l0} l1=#{l1} ~l1=#{self.list_not(l1)}}"
1049
- self.list_add!(l0,self.list_not(l1))
1050
- # puts "l0=#{l0}"
1051
- # puts "now l0=#{l0}"
1052
- return l0
1053
- end
1054
-
1055
- # Left shifts +l+ once.
1056
- #
1057
- # NOTE:
1058
- # * l contains the result.
1059
- # * The result has the same size as +l+ (no sign extension).
1060
- def self.list_shl_1!(l)
1061
- l.pop
1062
- l.unshift(0)
1063
- return l
1064
- end
1065
-
1066
- # Right shifts +l+ once.
1067
- #
1068
- # NOTE:
1069
- # * l contains the result.
1070
- # * The result has the same size as +l+ (no sign extension).
1071
- def self.list_shr_1!(l)
1072
- l.shift
1073
- l.push(0)
1074
- return l
1075
- end
1076
-
719
+ # # Bitwise addition
720
+ # def self.bitwise_add(s0,s1)
721
+ # res = "" # The result list of bits
722
+ # c = "0" # The current carry
723
+ # s0.each.zip(s1.each) do |b0,b1|
724
+ # res << XOR3_T[b0][b1][c]
725
+ # c = MAJ_T[b0][b1][c]
726
+ # end
727
+ # # Compute the sign extension (the sign bit of s0 and s1 is used
728
+ # # again)
729
+ # res << XOR3_T[s0.sign][s1.sign][c]
730
+ # return BitString.new(res.reverse)
731
+ # end
732
+
733
+ # # Bitwise subtraction without processing of the x and z states.
734
+ # def self.bitwise_sub0(s0,s1)
735
+ # return BitString.new("x"*(s0.width+1))
736
+ # end
737
+
738
+ # # Bitwise subtraction
739
+ # def self.bitwise_sub(s0,s1)
740
+ # # # Negate s1.
741
+ # # s1 = BitString.bitwise_neg(s1).trunc(s0.width)
742
+ # # # puts "s1.width = #{s1.width} s0.width = #{s0.width}"
743
+ # # # Add it to s0: but no need to add a bit since neg already added
744
+ # # # one.
745
+ # # return BitString.bitwise_add(s0,s1)
746
+ # # Perform the computation is a way to limit the propagation of
747
+ # # unspecified bits.
748
+ # # Is s1 specified?
749
+ # if s1.specified? then
750
+ # # Yes, perform -s1+s0
751
+ # return (-s1 + s0)
752
+ # else
753
+ # # No, perform s0+1+NOT(s1).
754
+ # # puts "s0=#{s0} s0+1=#{s0+1} not s1=#{bitwise_not(s1)}"
755
+ # return (s0 + 1 + bitwise_not(s1)).trunc(s0.width+1)
756
+ # end
757
+ # end
758
+
759
+ # # Bitwise positive sign: does nothing.
760
+ # def self.bitwise_pos(s)
761
+ # return s
762
+ # end
763
+
764
+ # # Bitwise negation without processing of the x and z states.
765
+ # def self.bitwise_neg0(s)
766
+ # return BitString.new("x"*(s.width+1))
767
+ # end
768
+
769
+ # # Bitwise negation
770
+ # def self.bitwise_neg(s)
771
+ # # -s = ~s + 1
772
+ # # # Not s.
773
+ # # s = BitString.bitwise_not(s)
774
+ # # # Add 1.
775
+ # # return BitString.bitwise_add(s,ONE.extend(s.width))
776
+ # return ~s + 1
777
+ # end
778
+
779
+ # # Bitwise and
780
+ # def self.bitwise_and(s0,s1)
781
+ # # puts "bitwise_and with s0=#{s0} and s1=#{s1}"
782
+ # res = s0.each.zip(s1.each).map { |b0,b1| AND_T[b0][b1] }.join
783
+ # # puts "s0=#{s0}, s1=#{s1}, res=#{res.reverse}"
784
+ # return BitString.new(res.reverse)
785
+ # end
786
+
787
+ # # Bitwise or
788
+ # def self.bitwise_or(s0,s1)
789
+ # res = s0.each.zip(s1.each).map { |b0,b1| OR_T[b0][b1] }.join
790
+ # return BitString.new(res.reverse)
791
+ # end
792
+
793
+ # # Bitwise xor
794
+ # def self.bitwise_xor(s0,s1)
795
+ # res = s0.each.zip(s1.each). map { |b0,b1| XOR_T[b0][b1] }.join
796
+ # return BitString.new(res.reverse)
797
+ # end
798
+
799
+ # # Bitwise not
800
+ # def self.bitwise_not(s)
801
+ # # puts "bitwise_not with s=#{s}"
802
+ # return BitString.new(s.each.map { |b| NOT_T[b] }.join.reverse)
803
+ # end
804
+
805
+ # # Bitwise shift left.
806
+ # def self.bitwise_shl(s0,s1)
807
+ # # puts "s0=#{s0} s1=#{s1}"
808
+ # return BitString.new("x" * s0.width) unless s1.specified?
809
+ # s1 = s1.to_numeric
810
+ # if s1 >= 0 then
811
+ # return BitString.new(s0.str + "0" * s1)
812
+ # elsif -s1 > s0.width then
813
+ # return ZERO
814
+ # else
815
+ # return s0.trim(s0.width+s1)
816
+ # end
817
+ # end
818
+
819
+ # # Bitwise shift right.
820
+ # def self.bitwise_shr(s0,s1)
821
+ # # puts "s0=#{s0} s1=#{s1}"
822
+ # return BitString.new("x" * s0.width) unless s1.specified?
823
+ # s1 = s1.to_numeric
824
+ # if s1 <= 0 then
825
+ # return BitString.new(s0.str + "0" * -s1)
826
+ # elsif s1 > s0.width then
827
+ # return ZERO
828
+ # else
829
+ # return s0.trim(s0.width-s1)
830
+ # end
831
+ # end
832
+
833
+
834
+ # # Bitwise eq without processing of the x and z states.
835
+ # def self.bitwise_eq0(s0,s1)
836
+ # return UNKNOWN
837
+ # end
838
+
839
+ # # Bitwise eq without processing of the x and z states.
840
+ # def self.bitwise_neq0(s0,s1)
841
+ # return UNKNOWN
842
+ # end
843
+
844
+ # # Bitwise eq.
845
+ # def self.bitwise_eq(s0,s1)
846
+ # return UNKNOWN unless (s0.specified? and s1.specified?)
847
+ # return s0.str == s1.str ? TRUE : FALSE
848
+ # end
849
+
850
+ # # Bitwise neq.
851
+ # def self.bitwise_neq(s0,s1)
852
+ # return UNKNOWN unless (s0.specified? and s1.specified?)
853
+ # return s0.str == s1.str ? FALSE : TRUE
854
+ # end
855
+
856
+
857
+ # # Bitwise lt without processing of the x and z states.
858
+ # def self.bitwise_lt0(s0,s1)
859
+ # return UNKNOWN
860
+ # end
861
+
862
+ # # Bitwise lt.
863
+ # def self.bitwise_lt(s0,s1)
864
+ # # # Handle the zero cases.
865
+ # # if s0.zero? then
866
+ # # return TRUE if s1.positive?
867
+ # # return FALSE if s1.negative? or s1.zero?
868
+ # # return UNKNOWN
869
+ # # elsif s1.zero? then
870
+ # # return TRUE if s0.negative?
871
+ # # return FALSE if s0.positive? or s0.zero?
872
+ # # return UNKNOWN
873
+ # # end
874
+ # # # Handle the unspecified sign cases.
875
+ # # unless s0.sign? then
876
+ # # # Check both sign cases.
877
+ # # lt_pos = self.bitwise_lt(s0[-1] = "1",s1)
878
+ # # lt_neg = self.bitwise_lt(s0[-1] = "0",s1)
879
+ # # # At least one of the results is unspecified.
880
+ # # return UNKNOWN unless (lt_pos.specified? and lt_neg.specified?)
881
+ # # # Both results are specified and identical.
882
+ # # return lt_pos if lt_pos == lt_neg
883
+ # # # Results are different.
884
+ # # return UNKNOWN
885
+ # # end
886
+ # # unless s1.sign? then
887
+ # # # Check both sign cases.
888
+ # # lt_pos = self.bitwise_lt(s0,s1[-1] = "1")
889
+ # # lt_neg = self.bitwise_lt(s0,s1[-1] = "0")
890
+ # # # At least one of the results is unspecified.
891
+ # # return UNKNOWN unless (lt_pos.specified? and lt_neg.specified?)
892
+ # # # Both results are specified and identical.
893
+ # # return lt_pos if lt_pos == lt_neg
894
+ # # # Results are different.
895
+ # # return UNKNOWN
896
+ # # end
897
+ # # # Signs are specificied.
898
+ # # # Depending on the signs
899
+ # # if s0.positive? then
900
+ # # if s1.positive? then
901
+ # # # s0 and s1 are positive, need to compare each bit.
902
+ # # s0.reverse_each.zip(s1.reverse_each) do |b0,b1|
903
+ # # # puts "b0=#{b0} b1=#{b1}, LT_T[b0][b1]=#{LT_T[b0][b1]}"
904
+ # # case LT_T[b0][b1]
905
+ # # when "x" then return UNKNOWN
906
+ # # when "1" then return TRUE
907
+ # # when "0" then
908
+ # # return FALSE if GT_T[b0][b1] == "1"
909
+ # # end
910
+ # # end
911
+ # # elsif s1.negative? then
912
+ # # # s0 is positive and s1 is negative.
913
+ # # return FALSE
914
+ # # else
915
+ # # # The sign of s1 is undefined, comparison is undefined too.
916
+ # # return UNKNOWN
917
+ # # end
918
+ # # elsif s0.negative? then
919
+ # # if s1.positive? then
920
+ # # # s0 is negative and s1 is positive
921
+ # # return TRUE
922
+ # # elsif s1.negative? then
923
+ # # # s0 and s1 are negative, need to compare each bit.
924
+ # # s0.reverse_each.zip(s1.reverse_each) do |b0,b1|
925
+ # # case GT_T[b0][b1]
926
+ # # when "x" then return UNKNOWN
927
+ # # when "1" then return FALSE
928
+ # # when "0" then
929
+ # # return TRUE if LT_T[b0][b1] == "1"
930
+ # # end
931
+ # # end
932
+ # # end
933
+ # # else
934
+ # # # The sign of s0 is undefined, comparison is undefined too.
935
+ # # return UNKNOWN
936
+ # # end
937
+
938
+ # # Check the sign of the subtraction between s0 and s1.
939
+ # case (s0-s1).sign
940
+ # when "0" then return FALSE
941
+ # when "1" then return TRUE
942
+ # else
943
+ # return UNKNOWN
944
+ # end
945
+ # end
946
+
947
+
948
+ # # Bitwise gt without processing of the x and z states.
949
+ # def self.bitwise_gt0(s0,s1)
950
+ # return UNKNOWN
951
+ # end
952
+
953
+ # # Bitwise gt.
954
+ # def self.bitwise_gt(s0,s1)
955
+ # return self.bitwise_lt(s1,s0)
956
+ # end
957
+
958
+
959
+ # # Bitwise le without processing of the x and z states.
960
+ # def self.bitwise_le0(s0,s1)
961
+ # return UNKNOWN
962
+ # end
963
+
964
+ # # Bitwise le.
965
+ # def self.bitwise_le(s0,s1)
966
+ # gt = self.bitwise_gt(s0,s1)
967
+ # if gt.eql?(TRUE) then
968
+ # return FALSE
969
+ # elsif gt.eql?(FALSE) then
970
+ # return TRUE
971
+ # else
972
+ # return UNKNOWN
973
+ # end
974
+ # end
975
+
976
+
977
+ # # Bitwise ge without processing of the x and z states.
978
+ # def self.bitwise_ge0(s0,s1)
979
+ # return UNKNOWN
980
+ # end
981
+
982
+ # # Bitwise ge.
983
+ # def self.bitwise_ge(s0,s1)
984
+ # lt = self.bitwise_lt(s0,s1)
985
+ # if lt.eql?(TRUE) then
986
+ # return FALSE
987
+ # elsif lt.eql?(FALSE) then
988
+ # return TRUE
989
+ # else
990
+ # return UNKNOWN
991
+ # end
992
+ # end
993
+
994
+
995
+ # # Bitwise cp without processing of the x and z states.
996
+ # def self.bitwise_cp0(s0,s1)
997
+ # return UNKNOWN
998
+ # end
999
+
1000
+ # # Bitwise cp.
1001
+ # def self.bitwise_cp(s0,s1)
1002
+ # # Compare the signs.
1003
+ # if s0.sign == "0" and s1.sign == "1" then
1004
+ # return ONE
1005
+ # elsif s0.sign == 0 and s1.sign == "1" then
1006
+ # return MINUS_ONE
1007
+ # end
1008
+ # # Compare the other bits.
1009
+ # sub = self.bitwise_sub(s0,s1)
1010
+ # if sub.negative? then
1011
+ # return MINUS_ONE
1012
+ # elsif sub.zero? then
1013
+ # return ZERO
1014
+ # elsif sub.positive? then
1015
+ # return ONE
1016
+ # else
1017
+ # return UNKNOWN
1018
+ # end
1019
+ # end
1020
+
1021
+
1022
+ # # Bitwise mul without processing of the x and z states.
1023
+ # def self.bitwise_mul0(s0,s1)
1024
+ # return BitString.new("x"*(s0.width+s1.width))
1025
+ # end
1026
+
1027
+ # # # Bitwise mul.
1028
+ # # def self.bitwise_mul(s0,s1)
1029
+ # # # Initialize the result to ZERO of combined s0 and s1 widths
1030
+ # # res = ZERO.extend(s0.width + s1.width)
1031
+ # # # The zero cases.
1032
+ # # if s0.zero? or s1.zero? then
1033
+ # # return res
1034
+ # # end
1035
+ # # # Convert s1 and res to lists of bits which support computation
1036
+ # # # between unknown bits of same values.
1037
+ # # s1 = s1.extend(res.width).to_list
1038
+ # # res = res.to_list
1039
+ # # # The other cases: perform a multiplication with shifts and adds.
1040
+ # # s0.each.lazy.take(s0.width).each do |b|
1041
+ # # case b
1042
+ # # when "1" then self.list_add!(res,s1)
1043
+ # # when "x","z" then self.list_add!(res,self.list_and_unknown(s1))
1044
+ # # end
1045
+ # # # puts "res=#{res} s1=#{s1}"
1046
+ # # self.list_shl_1!(s1)
1047
+ # # end
1048
+ # # # Add the sign row.
1049
+ # # case s0.sign
1050
+ # # when "1" then self.list_sub!(res,s1)
1051
+ # # when "x","z" then self.list_sub!(res,list_and_unknown(s1))
1052
+ # # end
1053
+ # # # Return the result.
1054
+ # # return self.list_to_bstr(res)
1055
+ # # end
1056
+
1057
+ # # Bitwise div without processing of the x and z states.
1058
+ # def self.bitwise_div0(s0,s1)
1059
+ # return BitString.new("x"*(s0.width))
1060
+ # end
1061
+
1062
+ # # # Bitwise div.
1063
+ # # def self.bitwise_div(s0,s1)
1064
+ # # width = s0.width
1065
+ # # # The zero cases.
1066
+ # # if s0.zero? then
1067
+ # # return res
1068
+ # # elsif s1.maybe_zero? then
1069
+ # # return UNKNOWN.extend(width)
1070
+ # # end
1071
+ # # # Handle the sign: the division is only performed on positive
1072
+ # # # numbers.
1073
+ # # # NOTE: we are sure that s0 and s1 are not zero since these
1074
+ # # # cases have been handled before.
1075
+ # # sign = nil
1076
+ # # if s0.sign == "0" then
1077
+ # # if s1.sign == "0" then
1078
+ # # sign = "0"
1079
+ # # elsif s1.sign == "1" then
1080
+ # # sign = "1"
1081
+ # # s1 = -s1
1082
+ # # else
1083
+ # # # Unknown sign, unkown result.
1084
+ # # return UNKNOWN.extend(width)
1085
+ # # end
1086
+ # # elsif s0.sign == "1" then
1087
+ # # s0 = -s0
1088
+ # # if s1.sign == "0" then
1089
+ # # sign = "1"
1090
+ # # elsif s1.sign == "1" then
1091
+ # # sign = "0"
1092
+ # # s1 = -s1
1093
+ # # else
1094
+ # # # Unknwown sign, unknown result.
1095
+ # # return UNKNOWN.extend(width)
1096
+ # # end
1097
+ # # else
1098
+ # # # Unknown sign, unknown result.
1099
+ # # return UNKNOWN.extend(width)
1100
+ # # end
1101
+ # # # Convert s0 and s1 to list of bits of widths of s0 and s1 -1
1102
+ # # # (the largest possible value).
1103
+ # # # s0 will serve as current remainder.
1104
+ # # s0 = BitString.new(s0) if s0.is_a?(Numeric)
1105
+ # # s1 = BitString.new(s1) if s1.is_a?(Numeric)
1106
+ # # s0 = s0.extend(s0.width+s1.width-1)
1107
+ # # s1 = s1.extend(s0.width)
1108
+ # # s0 = s0.to_list
1109
+ # # s1 = s1.to_list
1110
+ # # puts "first s1=#{s1}"
1111
+ # # # Adujst s1 to the end of s0 and the corresponding 0s in front of q
1112
+ # # msb = s0.reverse.index {|b| b != 0}
1113
+ # # steps = s0.size-msb
1114
+ # # self.list_shl!(s1,steps-1)
1115
+ # # q = [ 0 ] * (width-steps)
1116
+ # # # Apply the non-restoring division algorithm.
1117
+ # # sub = true
1118
+ # # puts "steps= #{steps} s0=#{s0} s1=#{s1} q=#{q}"
1119
+ # # (steps).times do |i|
1120
+ # # if sub then
1121
+ # # self.list_sub!(s0,s1)
1122
+ # # else
1123
+ # # self.list_add!(s0,s1)
1124
+ # # end
1125
+ # # puts "s0=#{s0}"
1126
+ # # # Is the result positive?
1127
+ # # if s0[-1] == 0 then
1128
+ # # # Yes, the next step is a subtraction and the current
1129
+ # # # result bit is one.
1130
+ # # sub = true
1131
+ # # q.unshift(1)
1132
+ # # elsif s0[-1] == 1 then
1133
+ # # # No, it is negative the next step is an addition and the
1134
+ # # # current result bit is zero.
1135
+ # # sub = false
1136
+ # # q.unshift(0)
1137
+ # # else
1138
+ # # # Unknown sign, the remaining of q is unknown.
1139
+ # # (steps-i).times { q.unshift(self.new_unknown) }
1140
+ # # # Still, can add the positive sign bit.
1141
+ # # q.push(0)
1142
+ # # break
1143
+ # # end
1144
+ # # self.list_shr_1!(s1)
1145
+ # # end
1146
+ # # # Generate the resulting bit string.
1147
+ # # puts "q=#{q}"
1148
+ # # q = self.list_to_bstr(q)
1149
+ # # puts "q=#{q}"
1150
+ # # # Set the sign.
1151
+ # # if sign == "1" then
1152
+ # # q = (-q).trunc(width)
1153
+ # # elsif q.zero? then
1154
+ # # q = 0
1155
+ # # else
1156
+ # # q = q.extend(width)
1157
+ # # end
1158
+ # # # Return the result.
1159
+ # # return q
1160
+ # # end
1161
+
1162
+
1163
+ # # Bitwise mod without processing of the x and z states.
1164
+ # def self.bitwise_mod0(s0,s1)
1165
+ # return BitString.new("x"*(s1.width))
1166
+ # end
1167
+
1168
+ # # # Bitwise mod.
1169
+ # # def self.bitwise_mod(s0,s1)
1170
+ # # raise "bitwise_mod is not implemented yet."
1171
+ # # end
1172
+
1077
1173
 
1078
- # Left shifts +l+ +x+ times.
1079
- #
1080
- # NOTE:
1081
- # * l contains the result.
1082
- # * The result has the same size as +l+ (no sign extension).
1083
- def self.list_shl!(l,x)
1084
- l.pop(x)
1085
- l.unshift(*([0]*x))
1086
- end
1174
+ # # Computation with list of bits:
1175
+ # # "0" -> 0, "1" -> 1, and then 2, 3, 4, ...
1176
+ # # Allows more precise computations (e.g., mul, div).
1177
+ #
1178
+ # # The counter of unknown bits.
1179
+ # @@unknown = 1
1180
+
1181
+ # # Creates a new uniq unknown bit.
1182
+ # def self.new_unknown
1183
+ # @@unknown += 1
1184
+ # return @@unknown
1185
+ # end
1186
+
1187
+ # # Converts to a list of bits where unknown or high z bits are
1188
+ # # differentiate from each other.
1189
+ # #
1190
+ # # NOTE:
1191
+ # # * the sign bit is also added to the list.
1192
+ # # * the distinction between z and x is lost.
1193
+ # def to_list
1194
+ # return @str.each_char.reverse_each.map.with_index do |b,i|
1195
+ # case b
1196
+ # when "0" then 0
1197
+ # when "1" then 1
1198
+ # when "z","x" then BitString.new_unknown
1199
+ # else
1200
+ # raise "Internal error: invalid bit in bitstring: #{b}"
1201
+ # end
1202
+ # end
1203
+ # end
1204
+
1205
+ # # Converts list of bits +l+ to a bit string.
1206
+ # def self.list_to_bstr(l)
1207
+ # str = l.reverse_each.map { |b| b > 1 ? "x" : b }.join
1208
+ # return BitString.new(str)
1209
+ # end
1210
+
1211
+ # # Compute the and between +l+ and an unknown value.
1212
+ # def self.list_and_unknown(l)
1213
+ # return l.map do |b|
1214
+ # b == 0 ? 0 : BitString.new_unknown
1215
+ # end
1216
+ # end
1217
+
1218
+ # # Compute the not of +l+
1219
+ # def self.list_not(l)
1220
+ # return l.map do |b|
1221
+ # case b
1222
+ # when 0 then 1
1223
+ # when 1 then 0
1224
+ # else
1225
+ # BitString.new_unknown
1226
+ # end
1227
+ # end
1228
+ # end
1229
+
1230
+ # # Adds +l1+ to +l0+.
1231
+ # #
1232
+ # # NOTE:
1233
+ # # * l0 is contains the result.
1234
+ # # * The result has the same size as +l0+ (no sign extension).
1235
+ # # * Assumes +l0+ and +l1+ have the same size.
1236
+ # def self.list_add!(l0,l1)
1237
+ # # puts "add l0=#{l0} l1=#{l1}"
1238
+ # c = 0 # Current carry.
1239
+ # l0.each_with_index do |b0,i|
1240
+ # b1 = l1[i]
1241
+ # # puts "i=#{i} b0=#{b0} b1=#{b1} c=#{c}"
1242
+ # if b0 == b1 then
1243
+ # # The sum is c.
1244
+ # l0[i] = c
1245
+ # # The carry is b0.
1246
+ # c = b0
1247
+ # elsif b0 == c then
1248
+ # # The sum is b1.
1249
+ # l0[i] = b1
1250
+ # # The carry is b0.
1251
+ # c = b0
1252
+ # elsif b1 == c then
1253
+ # # The sum is b0.
1254
+ # l0[i] = b0
1255
+ # # The carry is b1.
1256
+ # c = b1
1257
+ # else
1258
+ # l0[i] = self.new_unknown
1259
+ # c = self.new_unknown
1260
+ # end
1261
+ # end
1262
+ # return l0
1263
+ # end
1264
+
1265
+ # # Adds 1 to +l0+.
1266
+ # #
1267
+ # # NOTE:
1268
+ # # * l0 is contains the result.
1269
+ # # * The result has the same size as +l0+ (no sign extension).
1270
+ # def self.list_add_1!(l0)
1271
+ # c = 1 # Current carry.
1272
+ # l0.each_with_index do |b0,i|
1273
+ # if c == 0 then
1274
+ # # The sum is b0.
1275
+ # l0[i] = b0
1276
+ # # The carry is unchanged.
1277
+ # elsif b0 == 0 then
1278
+ # # The sum is c.
1279
+ # l0[i] = c
1280
+ # # The carry is 0.
1281
+ # c = 0
1282
+ # elsif b0 == c then
1283
+ # # The sum is 0.
1284
+ # l0[i] = 0
1285
+ # # The carry is b0.
1286
+ # c = b0
1287
+ # else
1288
+ # # Both sum and carry are unknown
1289
+ # l0[i] = BitString.new_unknown
1290
+ # c = BitString.new_unknown
1291
+ # end
1292
+ # end
1293
+ # return l0
1294
+ # end
1295
+
1296
+ # # Subtracts +l1+ from +l0+.
1297
+ # #
1298
+ # # NOTE:
1299
+ # # * l0 is contains the result.
1300
+ # # * The result has the same size as +l0+ (no sign extension).
1301
+ # # * Assumes +l0+ and +l1+ have the same size.
1302
+ # def self.list_sub!(l0,l1)
1303
+ # # Adds 1 to l0.
1304
+ # BitString.list_add_1!(l0)
1305
+ # # Adds ~l1 to l0.
1306
+ # # puts "l0=#{l0} l1=#{l1} ~l1=#{self.list_not(l1)}}"
1307
+ # self.list_add!(l0,self.list_not(l1))
1308
+ # # puts "l0=#{l0}"
1309
+ # # puts "now l0=#{l0}"
1310
+ # return l0
1311
+ # end
1312
+
1313
+ # # Left shifts +l+ once.
1314
+ # #
1315
+ # # NOTE:
1316
+ # # * l contains the result.
1317
+ # # * The result has the same size as +l+ (no sign extension).
1318
+ # def self.list_shl_1!(l)
1319
+ # l.pop
1320
+ # l.unshift(0)
1321
+ # return l
1322
+ # end
1323
+
1324
+ # # Right shifts +l+ once.
1325
+ # #
1326
+ # # NOTE:
1327
+ # # * l contains the result.
1328
+ # # * The result has the same size as +l+ (no sign extension).
1329
+ # def self.list_shr_1!(l)
1330
+ # l.shift
1331
+ # l.push(0)
1332
+ # return l
1333
+ # end
1334
+
1335
+
1336
+ # # Left shifts +l+ +x+ times.
1337
+ # #
1338
+ # # NOTE:
1339
+ # # * l contains the result.
1340
+ # # * The result has the same size as +l+ (no sign extension).
1341
+ # def self.list_shl!(l,x)
1342
+ # l.pop(x)
1343
+ # l.unshift(*([0]*x))
1344
+ # end
1087
1345
 
1088
1346
  end
1089
1347