HDLRuby 2.10.5 → 2.11.0

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