HDLRuby 2.10.5 → 2.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +1 -1
- 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/hdrcc.rb +54 -8
- data/lib/HDLRuby/hruby_bstr.rb +1175 -917
- data/lib/HDLRuby/hruby_high.rb +200 -90
- data/lib/HDLRuby/hruby_high_fullname.rb +82 -0
- data/lib/HDLRuby/hruby_low.rb +41 -23
- data/lib/HDLRuby/hruby_low2c.rb +7 -0
- 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/version.rb +1 -1
- metadata +24 -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
|
|