HDLRuby 2.10.3 → 2.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/HDLRuby.gemspec +1 -0
- data/README.md +8 -4
- data/Rakefile +8 -0
- data/{lib/HDLRuby/sim/Makefile → ext/hruby_sim/Makefile_csim} +0 -0
- data/ext/hruby_sim/extconf.rb +13 -0
- data/ext/hruby_sim/hruby_rcsim_build.c +1188 -0
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim.h +255 -16
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_calc.c +310 -181
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_core.c +34 -17
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_list.c +0 -0
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_stack_calc.c +4 -1
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_stack_calc.c.sav +0 -0
- data/ext/hruby_sim/hruby_sim_tree_calc.c +375 -0
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_vcd.c +5 -5
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_vizualize.c +2 -2
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_value_pool.c +4 -1
- data/lib/HDLRuby/hdr_samples/bstr_bench.rb +2 -0
- data/lib/HDLRuby/hdr_samples/case_bench.rb +2 -2
- data/lib/HDLRuby/hdr_samples/counter_bench.rb +0 -1
- data/lib/HDLRuby/hdr_samples/counter_dff_bench.rb +46 -0
- data/lib/HDLRuby/hdr_samples/dff_bench.rb +4 -1
- data/lib/HDLRuby/hdr_samples/dff_override.rb +76 -0
- data/lib/HDLRuby/hdr_samples/print_bench.rb +62 -0
- data/lib/HDLRuby/hdr_samples/rom.rb +5 -3
- data/lib/HDLRuby/hdr_samples/simple_counter_bench.rb +43 -0
- data/lib/HDLRuby/hdr_samples/with_values.rb +14 -0
- data/lib/HDLRuby/hdrcc.rb +84 -21
- data/lib/HDLRuby/hruby_bstr.rb +1175 -917
- data/lib/HDLRuby/hruby_high.rb +267 -97
- data/lib/HDLRuby/hruby_high_fullname.rb +82 -0
- data/lib/HDLRuby/hruby_low.rb +110 -71
- data/lib/HDLRuby/hruby_low2c.rb +7 -0
- data/lib/HDLRuby/hruby_low_mutable.rb +1 -1
- data/lib/HDLRuby/hruby_low_without_namespace.rb +2 -1
- data/lib/HDLRuby/hruby_rcsim.rb +978 -0
- data/lib/HDLRuby/hruby_rsim.rb +1134 -0
- data/lib/HDLRuby/hruby_rsim_vcd.rb +322 -0
- data/lib/HDLRuby/hruby_values.rb +362 -18
- data/lib/HDLRuby/hruby_verilog.rb +21 -3
- data/lib/HDLRuby/std/handshakes.rb +1 -1
- data/lib/HDLRuby/version.rb +1 -1
- metadata +25 -13
data/lib/HDLRuby/hruby_bstr.rb
CHANGED
@@ -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
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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
|
41
|
+
# * the representation is 2 complements.
|
26
42
|
class BitString
|
27
43
|
|
28
|
-
# Creates a new bit string from +
|
29
|
-
#
|
30
|
-
#
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
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
|
-
|
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
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
when
|
70
|
-
|
71
|
-
when
|
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
|
-
|
83
|
+
raise "Invalid bit: #{b.chr}"
|
74
84
|
end
|
75
|
-
end
|
85
|
+
end
|
76
86
|
end
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
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
|
-
|
85
|
-
|
86
|
-
|
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 (@
|
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 @
|
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 ! @
|
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 @
|
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 @
|
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:
|
131
|
-
#
|
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
|
-
|
134
|
-
|
135
|
-
|
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:
|
146
|
-
#
|
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
|
-
#
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
#
|
157
|
-
|
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
|
-
|
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
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
#
|
179
|
-
#
|
180
|
-
#
|
181
|
-
# *
|
182
|
-
# *
|
183
|
-
#
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
#
|
190
|
-
#
|
191
|
-
#
|
192
|
-
# *
|
193
|
-
#
|
194
|
-
def
|
195
|
-
|
196
|
-
|
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
|
-
@
|
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
|
-
@
|
221
|
-
end
|
222
|
-
|
223
|
-
# Gets the sign of the bit string.
|
224
|
-
def sign
|
225
|
-
|
226
|
-
end
|
227
|
-
|
228
|
-
# Tell if the sign is specified.
|
229
|
-
def sign?
|
230
|
-
|
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
|
-
|
239
|
-
|
240
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
279
|
-
|
280
|
-
|
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
|
-
|
285
|
-
|
286
|
-
|
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
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
#
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
#
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
#
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
#
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
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
|
-
|
396
|
-
|
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
|
-
|
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
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
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
|
-
|
469
|
-
|
470
|
-
|
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
|
554
|
+
return BitString.new(@content.map {|b| NOT_T[b]},:raw)
|
716
555
|
end
|
717
556
|
end
|
718
557
|
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
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
|
-
|
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
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
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
|
-
#
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
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
|
-
#
|
800
|
-
|
801
|
-
return
|
596
|
+
# The arithmetic unary operator.
|
597
|
+
define_method(:+@) do
|
598
|
+
return self.clone
|
802
599
|
end
|
803
|
-
|
804
|
-
|
805
|
-
|
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
|
-
|
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
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
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
|
-
#
|
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
|
-
#
|
975
|
-
#
|
976
|
-
#
|
977
|
-
#
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
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
|
-
#
|
1010
|
-
#
|
1011
|
-
# *
|
1012
|
-
|
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
|
-
#
|
1041
|
-
#
|
1042
|
-
#
|
1043
|
-
#
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
#
|
1056
|
-
#
|
1057
|
-
#
|
1058
|
-
|
1059
|
-
#
|
1060
|
-
def self.
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
#
|
1067
|
-
#
|
1068
|
-
#
|
1069
|
-
#
|
1070
|
-
#
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
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
|
-
#
|
1079
|
-
#
|
1080
|
-
#
|
1081
|
-
#
|
1082
|
-
#
|
1083
|
-
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
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
|
|