HDLRuby 2.0.8
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 +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +5 -0
- data/.yardopts +1 -0
- data/Gemfile +4 -0
- data/HDLRuby.gemspec +36 -0
- data/LICENSE.txt +21 -0
- data/README.md +2774 -0
- data/README.pdf +0 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/hdrcc +3 -0
- data/lib/HDLRuby/alcc.rb +137 -0
- data/lib/HDLRuby/backend/hruby_allocator.rb +69 -0
- data/lib/HDLRuby/backend/hruby_c_allocator.rb +76 -0
- data/lib/HDLRuby/hdr_samples/adder.rb +7 -0
- data/lib/HDLRuby/hdr_samples/adder_assign_error.rb +11 -0
- data/lib/HDLRuby/hdr_samples/adder_bench.rb +27 -0
- data/lib/HDLRuby/hdr_samples/adder_gen.rb +7 -0
- data/lib/HDLRuby/hdr_samples/adder_nodef_error.rb +7 -0
- data/lib/HDLRuby/hdr_samples/addsub.rb +19 -0
- data/lib/HDLRuby/hdr_samples/addsubz.rb +22 -0
- data/lib/HDLRuby/hdr_samples/alu.rb +47 -0
- data/lib/HDLRuby/hdr_samples/calculator.rb +48 -0
- data/lib/HDLRuby/hdr_samples/counter_bench.rb +83 -0
- data/lib/HDLRuby/hdr_samples/dff.rb +9 -0
- data/lib/HDLRuby/hdr_samples/dff_bench.rb +66 -0
- data/lib/HDLRuby/hdr_samples/dff_counter.rb +20 -0
- data/lib/HDLRuby/hdr_samples/include.rb +14 -0
- data/lib/HDLRuby/hdr_samples/instance_open.rb +23 -0
- data/lib/HDLRuby/hdr_samples/mei8.rb +256 -0
- data/lib/HDLRuby/hdr_samples/mei8_bench.rb +309 -0
- data/lib/HDLRuby/hdr_samples/multer_gen.rb +8 -0
- data/lib/HDLRuby/hdr_samples/multer_seq.rb +29 -0
- data/lib/HDLRuby/hdr_samples/neural/a.rb +9 -0
- data/lib/HDLRuby/hdr_samples/neural/a_sub.rb +5 -0
- data/lib/HDLRuby/hdr_samples/neural/bw.rb +23 -0
- data/lib/HDLRuby/hdr_samples/neural/counter.rb +16 -0
- data/lib/HDLRuby/hdr_samples/neural/dadz.rb +9 -0
- data/lib/HDLRuby/hdr_samples/neural/dadz_sub.rb +4 -0
- data/lib/HDLRuby/hdr_samples/neural/forward.rb +153 -0
- data/lib/HDLRuby/hdr_samples/neural/forward_sub.rb +62 -0
- data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand.rb +41 -0
- data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand_typedef.rb +47 -0
- data/lib/HDLRuby/hdr_samples/neural/mem.rb +30 -0
- data/lib/HDLRuby/hdr_samples/neural/random.rb +23 -0
- data/lib/HDLRuby/hdr_samples/neural/selector.rb +29 -0
- data/lib/HDLRuby/hdr_samples/neural/sigmoid.rb +20 -0
- data/lib/HDLRuby/hdr_samples/neural/z.rb +33 -0
- data/lib/HDLRuby/hdr_samples/prog.obj +256 -0
- data/lib/HDLRuby/hdr_samples/ram.rb +18 -0
- data/lib/HDLRuby/hdr_samples/register_with_code_bench.rb +98 -0
- data/lib/HDLRuby/hdr_samples/rom.rb +10 -0
- data/lib/HDLRuby/hdr_samples/struct.rb +14 -0
- data/lib/HDLRuby/hdr_samples/sumprod.rb +29 -0
- data/lib/HDLRuby/hdr_samples/sw_encrypt_bench.rb +103 -0
- data/lib/HDLRuby/hdr_samples/sw_encrypt_cpu_bench.rb +261 -0
- data/lib/HDLRuby/hdr_samples/sw_encrypt_cpusim_bench.rb +302 -0
- data/lib/HDLRuby/hdr_samples/system_open.rb +11 -0
- data/lib/HDLRuby/hdr_samples/tuple.rb +16 -0
- data/lib/HDLRuby/hdr_samples/with_channel.rb +118 -0
- data/lib/HDLRuby/hdr_samples/with_class.rb +199 -0
- data/lib/HDLRuby/hdr_samples/with_decoder.rb +17 -0
- data/lib/HDLRuby/hdr_samples/with_fsm.rb +34 -0
- data/lib/HDLRuby/hdr_samples/with_reconf.rb +103 -0
- data/lib/HDLRuby/hdrcc.rb +623 -0
- data/lib/HDLRuby/high_samples/_adder_fault.rb +23 -0
- data/lib/HDLRuby/high_samples/_generic_transmission2.rb +146 -0
- data/lib/HDLRuby/high_samples/adder.rb +21 -0
- data/lib/HDLRuby/high_samples/adder_common_errors.rb +25 -0
- data/lib/HDLRuby/high_samples/addsub.rb +33 -0
- data/lib/HDLRuby/high_samples/addsubz.rb +37 -0
- data/lib/HDLRuby/high_samples/after.rb +28 -0
- data/lib/HDLRuby/high_samples/all_signals.rb +29 -0
- data/lib/HDLRuby/high_samples/alu.rb +61 -0
- data/lib/HDLRuby/high_samples/anonymous.rb +41 -0
- data/lib/HDLRuby/high_samples/before.rb +28 -0
- data/lib/HDLRuby/high_samples/blockblock.rb +26 -0
- data/lib/HDLRuby/high_samples/bugs/dadz.rb +22 -0
- data/lib/HDLRuby/high_samples/bugs/misample_instan.rb +20 -0
- data/lib/HDLRuby/high_samples/bugs/misample_updown.rb +22 -0
- data/lib/HDLRuby/high_samples/bugs/sample_add.rb +16 -0
- data/lib/HDLRuby/high_samples/bugs/sample_barrel.rb +13 -0
- data/lib/HDLRuby/high_samples/bugs/sample_daice.rb +57 -0
- data/lib/HDLRuby/high_samples/bugs/sample_kumiawase.rb +52 -0
- data/lib/HDLRuby/high_samples/bugs/sample_multi.rb +18 -0
- data/lib/HDLRuby/high_samples/bugs/sample_sub.rb +14 -0
- data/lib/HDLRuby/high_samples/bugs/z2.rb +32 -0
- data/lib/HDLRuby/high_samples/case.rb +32 -0
- data/lib/HDLRuby/high_samples/case2.rb +30 -0
- data/lib/HDLRuby/high_samples/change.rb +23 -0
- data/lib/HDLRuby/high_samples/clocks.rb +35 -0
- data/lib/HDLRuby/high_samples/comparer.rb +21 -0
- data/lib/HDLRuby/high_samples/conditionals.rb +29 -0
- data/lib/HDLRuby/high_samples/dff.rb +23 -0
- data/lib/HDLRuby/high_samples/each.rb +28 -0
- data/lib/HDLRuby/high_samples/exporter.rb +42 -0
- data/lib/HDLRuby/high_samples/functions.rb +60 -0
- data/lib/HDLRuby/high_samples/if_seq.rb +26 -0
- data/lib/HDLRuby/high_samples/inherit_as_dff.rb +32 -0
- data/lib/HDLRuby/high_samples/inherit_dff.rb +36 -0
- data/lib/HDLRuby/high_samples/instance.rb +37 -0
- data/lib/HDLRuby/high_samples/memory.rb +64 -0
- data/lib/HDLRuby/high_samples/multi_file.rb +27 -0
- data/lib/HDLRuby/high_samples/overload.rb +32 -0
- data/lib/HDLRuby/high_samples/paper_after.rb +49 -0
- data/lib/HDLRuby/high_samples/ram.rb +27 -0
- data/lib/HDLRuby/high_samples/registers.rb +139 -0
- data/lib/HDLRuby/high_samples/rom.rb +23 -0
- data/lib/HDLRuby/high_samples/scopeblockname.rb +37 -0
- data/lib/HDLRuby/high_samples/scopescope.rb +26 -0
- data/lib/HDLRuby/high_samples/shift.rb +31 -0
- data/lib/HDLRuby/high_samples/shift2.rb +40 -0
- data/lib/HDLRuby/high_samples/simple_instance.rb +31 -0
- data/lib/HDLRuby/high_samples/test_all.sh +10 -0
- data/lib/HDLRuby/high_samples/typedef.rb +24 -0
- data/lib/HDLRuby/high_samples/values.rb +70 -0
- data/lib/HDLRuby/high_samples/vector.rb +22 -0
- data/lib/HDLRuby/high_samples/with_decoder.rb +30 -0
- data/lib/HDLRuby/high_samples/with_fsm.rb +46 -0
- data/lib/HDLRuby/high_samples/with_pipe.rb +43 -0
- data/lib/HDLRuby/high_samples/with_seq.rb +25 -0
- data/lib/HDLRuby/hruby_bstr.rb +1085 -0
- data/lib/HDLRuby/hruby_check.rb +317 -0
- data/lib/HDLRuby/hruby_db.rb +432 -0
- data/lib/HDLRuby/hruby_error.rb +44 -0
- data/lib/HDLRuby/hruby_high.rb +4103 -0
- data/lib/HDLRuby/hruby_low.rb +4735 -0
- data/lib/HDLRuby/hruby_low2c.rb +1986 -0
- data/lib/HDLRuby/hruby_low2high.rb +738 -0
- data/lib/HDLRuby/hruby_low2seq.rb +248 -0
- data/lib/HDLRuby/hruby_low2sym.rb +126 -0
- data/lib/HDLRuby/hruby_low2vhd.rb +1437 -0
- data/lib/HDLRuby/hruby_low_bool2select.rb +295 -0
- data/lib/HDLRuby/hruby_low_cleanup.rb +193 -0
- data/lib/HDLRuby/hruby_low_fix_types.rb +437 -0
- data/lib/HDLRuby/hruby_low_mutable.rb +1803 -0
- data/lib/HDLRuby/hruby_low_resolve.rb +165 -0
- data/lib/HDLRuby/hruby_low_skeleton.rb +129 -0
- data/lib/HDLRuby/hruby_low_with_bool.rb +141 -0
- data/lib/HDLRuby/hruby_low_with_port.rb +167 -0
- data/lib/HDLRuby/hruby_low_with_var.rb +302 -0
- data/lib/HDLRuby/hruby_low_without_bit2vector.rb +88 -0
- data/lib/HDLRuby/hruby_low_without_concat.rb +162 -0
- data/lib/HDLRuby/hruby_low_without_connection.rb +113 -0
- data/lib/HDLRuby/hruby_low_without_namespace.rb +718 -0
- data/lib/HDLRuby/hruby_low_without_outread.rb +107 -0
- data/lib/HDLRuby/hruby_low_without_select.rb +206 -0
- data/lib/HDLRuby/hruby_serializer.rb +398 -0
- data/lib/HDLRuby/hruby_tools.rb +37 -0
- data/lib/HDLRuby/hruby_types.rb +239 -0
- data/lib/HDLRuby/hruby_values.rb +64 -0
- data/lib/HDLRuby/hruby_verilog.rb +1888 -0
- data/lib/HDLRuby/hruby_verilog_name.rb +52 -0
- data/lib/HDLRuby/low_samples/adder.yaml +97 -0
- data/lib/HDLRuby/low_samples/after.yaml +228 -0
- data/lib/HDLRuby/low_samples/before.yaml +223 -0
- data/lib/HDLRuby/low_samples/blockblock.yaml +48 -0
- data/lib/HDLRuby/low_samples/bugs/sample_add.yaml +97 -0
- data/lib/HDLRuby/low_samples/bugs/sample_daice.yaml +444 -0
- data/lib/HDLRuby/low_samples/bugs/sample_kumiawase.yaml +332 -0
- data/lib/HDLRuby/low_samples/bugs/sample_sub.yaml +97 -0
- data/lib/HDLRuby/low_samples/bugs/seqpar.yaml +184 -0
- data/lib/HDLRuby/low_samples/case.yaml +327 -0
- data/lib/HDLRuby/low_samples/change.yaml +135 -0
- data/lib/HDLRuby/low_samples/clocks.yaml +674 -0
- data/lib/HDLRuby/low_samples/cloner.rb +22 -0
- data/lib/HDLRuby/low_samples/comparer.yaml +85 -0
- data/lib/HDLRuby/low_samples/conditionals.yaml +133 -0
- data/lib/HDLRuby/low_samples/dff.yaml +107 -0
- data/lib/HDLRuby/low_samples/each.yaml +1328 -0
- data/lib/HDLRuby/low_samples/exporter.yaml +226 -0
- data/lib/HDLRuby/low_samples/functions.yaml +298 -0
- data/lib/HDLRuby/low_samples/generic_transmission.yaml +597 -0
- data/lib/HDLRuby/low_samples/inherit_as_dff.yaml +125 -0
- data/lib/HDLRuby/low_samples/inherit_dff.yaml +107 -0
- data/lib/HDLRuby/low_samples/load_yaml.rb +11 -0
- data/lib/HDLRuby/low_samples/memory.yaml +678 -0
- data/lib/HDLRuby/low_samples/namespace_extractor.rb +23 -0
- data/lib/HDLRuby/low_samples/overload.yaml +226 -0
- data/lib/HDLRuby/low_samples/paper_after.yaml +431 -0
- data/lib/HDLRuby/low_samples/port_maker.rb +14 -0
- data/lib/HDLRuby/low_samples/ram.yaml +207 -0
- data/lib/HDLRuby/low_samples/registers.yaml +228 -0
- data/lib/HDLRuby/low_samples/rom.yaml +2950 -0
- data/lib/HDLRuby/low_samples/shift.yaml +230 -0
- data/lib/HDLRuby/low_samples/shift2.yaml +2095 -0
- data/lib/HDLRuby/low_samples/simple_instance.yaml +102 -0
- data/lib/HDLRuby/low_samples/test_all.sh +43 -0
- data/lib/HDLRuby/low_samples/typedef.yaml +115 -0
- data/lib/HDLRuby/low_samples/values.yaml +577 -0
- data/lib/HDLRuby/low_samples/variable_maker.rb +14 -0
- data/lib/HDLRuby/low_samples/vector.yaml +56 -0
- data/lib/HDLRuby/low_samples/with_seq.yaml +188 -0
- data/lib/HDLRuby/low_samples/yaml2hdr.rb +10 -0
- data/lib/HDLRuby/low_samples/yaml2vhd.rb +19 -0
- data/lib/HDLRuby/sim/Makefile +19 -0
- data/lib/HDLRuby/sim/hruby_sim.h +590 -0
- data/lib/HDLRuby/sim/hruby_sim_calc.c +2362 -0
- data/lib/HDLRuby/sim/hruby_sim_core.c +589 -0
- data/lib/HDLRuby/sim/hruby_sim_list.c +93 -0
- data/lib/HDLRuby/sim/hruby_sim_vizualize.c +91 -0
- data/lib/HDLRuby/sim/hruby_value_pool.c +64 -0
- data/lib/HDLRuby/std/channel.rb +354 -0
- data/lib/HDLRuby/std/clocks.rb +165 -0
- data/lib/HDLRuby/std/counters.rb +82 -0
- data/lib/HDLRuby/std/decoder.rb +214 -0
- data/lib/HDLRuby/std/fsm.rb +516 -0
- data/lib/HDLRuby/std/pipeline.rb +220 -0
- data/lib/HDLRuby/std/reconf.rb +309 -0
- data/lib/HDLRuby/test_hruby_bstr.rb +2259 -0
- data/lib/HDLRuby/test_hruby_high.rb +594 -0
- data/lib/HDLRuby/test_hruby_high_low.rb +99 -0
- data/lib/HDLRuby/test_hruby_low.rb +934 -0
- data/lib/HDLRuby/v_samples/adder.v +10 -0
- data/lib/HDLRuby/v_samples/dff.v +12 -0
- data/lib/HDLRuby/v_samples/ram.v +20 -0
- data/lib/HDLRuby/v_samples/rom.v +270 -0
- data/lib/HDLRuby/version.rb +3 -0
- data/lib/HDLRuby.rb +11 -0
- data/makedoc +1 -0
- data/metadata.yaml +4 -0
- metadata +299 -0
|
@@ -0,0 +1,1085 @@
|
|
|
1
|
+
module HDLRuby
|
|
2
|
+
|
|
3
|
+
##
|
|
4
|
+
# Library for describing the bit string and their computations.
|
|
5
|
+
#
|
|
6
|
+
########################################################################
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# Converts a value to a valid bit if possible.
|
|
10
|
+
def make_bit(value)
|
|
11
|
+
value = value.to_s.downcase
|
|
12
|
+
unless ["0","1","x","z"].include?(value)
|
|
13
|
+
raise "Invalid value for a bit: #{value}"
|
|
14
|
+
end
|
|
15
|
+
return value
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
##
|
|
20
|
+
# Describes a bit string.
|
|
21
|
+
#
|
|
22
|
+
# NOTE:
|
|
23
|
+
# * a bit string is immutable.
|
|
24
|
+
# * bit strings are always signed.
|
|
25
|
+
# * the upper bit of a bit string is the sign.
|
|
26
|
+
class BitString
|
|
27
|
+
|
|
28
|
+
# Creates a new bit string from +str+ with +sign+.
|
|
29
|
+
#
|
|
30
|
+
# NOTE:
|
|
31
|
+
# * +sign+ can be "0", "1", "z" and "x", is positive when "0"
|
|
32
|
+
# and negative when "1".
|
|
33
|
+
# * when not present it is assumed to be within str.
|
|
34
|
+
def initialize(str,sign = nil)
|
|
35
|
+
# Maybe str is an numeric.
|
|
36
|
+
if str.is_a?(Numeric) then
|
|
37
|
+
# Yes, convert it to a binary string.
|
|
38
|
+
str = str.to_s(2)
|
|
39
|
+
# And fix the sign.
|
|
40
|
+
if str[0] == "-" then
|
|
41
|
+
str = str[1..-1]
|
|
42
|
+
sign = "-"
|
|
43
|
+
else
|
|
44
|
+
sign = "+"
|
|
45
|
+
end
|
|
46
|
+
# puts "str=#{str} sign=#{sign}"
|
|
47
|
+
end
|
|
48
|
+
# Process the sign
|
|
49
|
+
sign = sign.to_s unless sign.is_a?(Integer)
|
|
50
|
+
case sign
|
|
51
|
+
when 0, "0","+" then @str = "0"
|
|
52
|
+
when 1, "1","-" then @str = "1"
|
|
53
|
+
when 2, "z","Z" then @str = "z"
|
|
54
|
+
when 3, "x","X" then @str = "x"
|
|
55
|
+
when nil, "" then @str = "" # The sign is in str
|
|
56
|
+
else
|
|
57
|
+
raise "Invalid bit string sign: #{sign}"
|
|
58
|
+
end
|
|
59
|
+
# Check and set the value of the bit string.
|
|
60
|
+
if str.respond_to?(:to_a) then
|
|
61
|
+
# Str is a bit list: convert it to a string.
|
|
62
|
+
str = str.to_a.map do |e|
|
|
63
|
+
case e
|
|
64
|
+
when 0 then "0"
|
|
65
|
+
when 1 then "1"
|
|
66
|
+
when 2 then "z"
|
|
67
|
+
when 3 then "x"
|
|
68
|
+
else
|
|
69
|
+
e
|
|
70
|
+
end
|
|
71
|
+
end.reverse.join
|
|
72
|
+
end
|
|
73
|
+
@str += str.to_s.downcase
|
|
74
|
+
unless @str.match(/^[0-1zx]+$/) then
|
|
75
|
+
raise "Invalid value for creating a bit string: #{str}"
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Gets the bitwidth.
|
|
80
|
+
def width
|
|
81
|
+
return @str.size
|
|
82
|
+
end
|
|
83
|
+
alias_method :size, :width
|
|
84
|
+
|
|
85
|
+
# Tells if the bit string is strictly.
|
|
86
|
+
#
|
|
87
|
+
# NOTE: return false if the sign is undefined of if it is unknown
|
|
88
|
+
# if the result is zero or not.
|
|
89
|
+
def positive?
|
|
90
|
+
return (@str[0] == "0" and self.nonzero?)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Tells if the bit string is strictly negative.
|
|
94
|
+
#
|
|
95
|
+
# NOTE: return false if the sign is undefined
|
|
96
|
+
def negative?
|
|
97
|
+
return @str[0] == "1"
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Tells if the bit string is zero.
|
|
101
|
+
#
|
|
102
|
+
# NOTE: return false if the bit string is undefined.
|
|
103
|
+
def zero?
|
|
104
|
+
return ! @str.each_char.any? {|b| b != "0" }
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Tells if the bit string is not zero.
|
|
108
|
+
def nonzero?
|
|
109
|
+
return @str.each_char.any? {|b| b == "1" }
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Tells if the bit string could be zero.
|
|
113
|
+
def maybe_zero?
|
|
114
|
+
return ! self.nonzero?
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Converts to a string (sign bit is comprised).
|
|
118
|
+
def to_s
|
|
119
|
+
return @str.clone
|
|
120
|
+
end
|
|
121
|
+
alias_method :str, :to_s
|
|
122
|
+
|
|
123
|
+
# Gets a bit by +index+.
|
|
124
|
+
#
|
|
125
|
+
# NOTE: If the index is larger than the bit string width, returns the
|
|
126
|
+
# bit sign.
|
|
127
|
+
def [](index)
|
|
128
|
+
# Handle the negative index case.
|
|
129
|
+
if index < 0 then
|
|
130
|
+
return self[self.width+index]
|
|
131
|
+
end
|
|
132
|
+
# Process the index.
|
|
133
|
+
index = index > @str.size ? @str.size : index
|
|
134
|
+
# Get the corresponding bit.
|
|
135
|
+
return @str[-index-1]
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Sets the bit at +index+ to +value+.
|
|
139
|
+
#
|
|
140
|
+
# NOTE: when index is larger than the bit width, the bit string is
|
|
141
|
+
# sign extended accordingly.
|
|
142
|
+
def []=(index,value)
|
|
143
|
+
# Handle the negative index case.
|
|
144
|
+
if index < 0 then
|
|
145
|
+
return self[self.width+index] = value
|
|
146
|
+
end
|
|
147
|
+
# Duplicate the bit string content to ensure immutability.
|
|
148
|
+
str = @str.clone
|
|
149
|
+
# Process the index.
|
|
150
|
+
if index >= str.size then
|
|
151
|
+
# Overflow, sign extend the bit string.
|
|
152
|
+
str += str[-1] * (index-str.size+1)
|
|
153
|
+
end
|
|
154
|
+
# Checks and convert the value
|
|
155
|
+
value = make_bit(value)
|
|
156
|
+
# Sets the value to a copy of the bit string.
|
|
157
|
+
str[-index-1] = value
|
|
158
|
+
# Return the result as a new bit string.
|
|
159
|
+
return BitString.new(str)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Truncs to +width+.
|
|
163
|
+
#
|
|
164
|
+
# NOTE:
|
|
165
|
+
# * trunc remove the end of the bit string.
|
|
166
|
+
# * if the width is already smaller than +width+, do nothing.
|
|
167
|
+
# * do not preserve the sign, but keep the last bit as sign bit.
|
|
168
|
+
def trunc(width)
|
|
169
|
+
return self if width >= @str.size-1
|
|
170
|
+
return BitString.new(@str[(@str.size-width-1)..-1])
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# Trims to +width+.
|
|
174
|
+
#
|
|
175
|
+
# NOTE:
|
|
176
|
+
# * trim remove the begining of the bit string.
|
|
177
|
+
# * if the width is already smaller than +width+, do nothing.
|
|
178
|
+
# * do not preserve the sign, but keep the last bit as sign bit.
|
|
179
|
+
def trim(width)
|
|
180
|
+
return self if width >= @str.size-1
|
|
181
|
+
return BitString.new(@str[0..width])
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# Extend to +width+.
|
|
185
|
+
#
|
|
186
|
+
# NOTE:
|
|
187
|
+
# * if the width is already larger than +width+, do nothing.
|
|
188
|
+
# * preserves the sign.
|
|
189
|
+
def extend(width)
|
|
190
|
+
return self if width <= @str.size - 1
|
|
191
|
+
return BitString.new(@str[0] * (width-@str.size+1) + @str)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# Iterates over the bits.
|
|
195
|
+
#
|
|
196
|
+
# NOTE: the sign bit in comprised.
|
|
197
|
+
#
|
|
198
|
+
# Returns an enumerator if no ruby block is given.
|
|
199
|
+
def each(&ruby_block)
|
|
200
|
+
# No ruby block? Return an enumerator.
|
|
201
|
+
return to_enum(:each) unless ruby_block
|
|
202
|
+
# A block? Apply it on each bit.
|
|
203
|
+
@str.each_char.reverse_each(&ruby_block)
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# Reverse iterates over the bits.
|
|
207
|
+
#
|
|
208
|
+
# NOTE: the sign bit in comprised.
|
|
209
|
+
#
|
|
210
|
+
# Returns an enumerator if no ruby block is given.
|
|
211
|
+
def reverse_each(&ruby_block)
|
|
212
|
+
# No ruby block? Return an enumerator.
|
|
213
|
+
return to_enum(:reverse_each) unless ruby_block
|
|
214
|
+
# A block? Apply it on each bit.
|
|
215
|
+
@str.each_char(&ruby_block)
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# Gets the sign of the bit string.
|
|
219
|
+
def sign
|
|
220
|
+
return @str[0]
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# Tell if the sign is specified.
|
|
224
|
+
def sign?
|
|
225
|
+
return (@str[0] == "0" or @str[0] == "1")
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
# Convert the bit string to a Ruby Numeric.
|
|
229
|
+
#
|
|
230
|
+
# NOTE: the result will be wrong is the bit string is unspecified.
|
|
231
|
+
def to_numeric
|
|
232
|
+
res = 0
|
|
233
|
+
# Process the bits.
|
|
234
|
+
@str[1..-1].each_char { |b| res = res << 1 | b.to_i }
|
|
235
|
+
# Process the sign.
|
|
236
|
+
res = res - (2**(@str.size-1)) if @str[0] == "1"
|
|
237
|
+
# Return the result.
|
|
238
|
+
return res
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# Tell if the bit string is fully specified
|
|
242
|
+
def specified?
|
|
243
|
+
return ! @str.match(/[xz]/)
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
# Coerces.
|
|
247
|
+
def coerce(other)
|
|
248
|
+
return [BitString.new(other),self]
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
# A few common bit strings.
|
|
253
|
+
|
|
254
|
+
TRUE = BitString.new("01")
|
|
255
|
+
FALSE = BitString.new("00")
|
|
256
|
+
UNKNOWN = BitString.new("xx")
|
|
257
|
+
ZERO = BitString.new("00")
|
|
258
|
+
ONE = BitString.new("01")
|
|
259
|
+
TWO = BitString.new("010")
|
|
260
|
+
THREE = BitString.new("011")
|
|
261
|
+
MINUS_ONE = BitString.new("11")
|
|
262
|
+
MINUS_TWO = BitString.new("10")
|
|
263
|
+
MINUS_THREE = BitString.new("101")
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
# The arithmetic and logic operations.
|
|
267
|
+
|
|
268
|
+
# Not truth table
|
|
269
|
+
NOT_T = { "0" => "1", "1" => "0", "z" => "x", "x" => "x" }
|
|
270
|
+
|
|
271
|
+
# And truth table: 0, 1, 2=z, 3=x
|
|
272
|
+
AND_T = { "0" => {"0"=>"0", "1"=>"0", "z"=>"0", "x"=>"0"}, # 0 line
|
|
273
|
+
"1" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"}, # 1 line
|
|
274
|
+
"z" => {"0"=>"0", "1"=>"x", "z"=>"x", "x"=>"x"}, # z line
|
|
275
|
+
"x" => {"0"=>"0", "1"=>"x", "z"=>"x", "x"=>"x"} } # x line
|
|
276
|
+
|
|
277
|
+
# Or truth table: 0, 1, 2=z, 3=x
|
|
278
|
+
OR_T = { "0" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"}, # 0 line
|
|
279
|
+
"1" => {"0"=>"1", "1"=>"1", "z"=>"1", "x"=>"1"}, # 1 line
|
|
280
|
+
"z" => {"0"=>"x", "1"=>"1", "z"=>"x", "x"=>"x"}, # z line
|
|
281
|
+
"x" => {"0"=>"x", "1"=>"1", "z"=>"x", "x"=>"x"} } # x line
|
|
282
|
+
|
|
283
|
+
# Xor truth table: 0, 1, 2=z, 3=x
|
|
284
|
+
XOR_T = { "0" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"}, # 0 line
|
|
285
|
+
"1" => {"0"=>"1", "1"=>"0", "z"=>"x", "x"=>"x"}, # 1 line
|
|
286
|
+
"z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"}, # z line
|
|
287
|
+
"x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} } # x line
|
|
288
|
+
|
|
289
|
+
# Double xor truth table: 0, 1, 2=z, 3=x
|
|
290
|
+
XOR3_T={ "0" => {
|
|
291
|
+
"0" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"},
|
|
292
|
+
"1" => {"0"=>"1", "1"=>"0", "z"=>"x", "x"=>"x"},
|
|
293
|
+
"z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
|
|
294
|
+
"x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} }, # 0 line
|
|
295
|
+
"1" => {
|
|
296
|
+
"0" => {"0"=>"1", "1"=>"0", "z"=>"x", "x"=>"x"},
|
|
297
|
+
"1" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"},
|
|
298
|
+
"z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
|
|
299
|
+
"x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} }, # 1 line
|
|
300
|
+
"z" => {
|
|
301
|
+
"0" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
|
|
302
|
+
"1" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
|
|
303
|
+
"z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
|
|
304
|
+
"x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} }, # z line
|
|
305
|
+
"x" => {
|
|
306
|
+
"0" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
|
|
307
|
+
"1" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
|
|
308
|
+
"z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
|
|
309
|
+
"x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} } }# x line
|
|
310
|
+
|
|
311
|
+
# Majority truth table: 0, 1, 2=z, 3=x
|
|
312
|
+
MAJ_T= { "0" => {
|
|
313
|
+
"0" => {"0"=>"0", "1"=>"0", "z"=>"0", "x"=>"0"},
|
|
314
|
+
"1" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"},
|
|
315
|
+
"z" => {"0"=>"0", "1"=>"x", "z"=>"x", "x"=>"x"},
|
|
316
|
+
"x" => {"0"=>"0", "1"=>"x", "z"=>"x", "x"=>"x"} }, # "0" line
|
|
317
|
+
"1" => {
|
|
318
|
+
"0" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"},
|
|
319
|
+
"1" => {"0"=>"1", "1"=>"1", "z"=>"1", "x"=>"1"},
|
|
320
|
+
"z" => {"0"=>"x", "1"=>"1", "z"=>"x", "x"=>"x"},
|
|
321
|
+
"x" => {"0"=>"x", "1"=>"1", "z"=>"x", "x"=>"x"} }, # "1" line
|
|
322
|
+
"z" => {
|
|
323
|
+
"0" => {"0"=>"0", "1"=>"x", "z"=>"x", "x"=>"x"},
|
|
324
|
+
"1" => {"0"=>"x", "1"=>"1", "z"=>"x", "x"=>"x"},
|
|
325
|
+
"z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
|
|
326
|
+
"x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} }, # z line
|
|
327
|
+
"x" => {
|
|
328
|
+
"0" => {"0"=>"0", "1"=>"x", "z"=>"x", "x"=>"x"},
|
|
329
|
+
"1" => {"0"=>"x", "1"=>"1", "z"=>"x", "x"=>"x"},
|
|
330
|
+
"z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"},
|
|
331
|
+
"x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} } }# x line
|
|
332
|
+
|
|
333
|
+
# Lower than truth table: 0, 1, 2=z, 3=x
|
|
334
|
+
LT_T = { "0" => {"0"=>"0", "1"=>"1", "z"=>"x", "x"=>"x"}, # 0 line
|
|
335
|
+
"1" => {"0"=>"0", "1"=>"0", "z"=>"x", "x"=>"x"}, # 1 line
|
|
336
|
+
"z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"}, # z line
|
|
337
|
+
"x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} } # x line
|
|
338
|
+
|
|
339
|
+
# Greater than truth table: 0, 1, 2=z, 3=x
|
|
340
|
+
GT_T = { "0" => {"0"=>"0", "1"=>"0", "z"=>"x", "x"=>"x"}, # 0 line
|
|
341
|
+
"1" => {"0"=>"1", "1"=>"0", "z"=>"x", "x"=>"x"}, # 1 line
|
|
342
|
+
"z" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"}, # z line
|
|
343
|
+
"x" => {"0"=>"x", "1"=>"x", "z"=>"x", "x"=>"x"} } # x line
|
|
344
|
+
|
|
345
|
+
# Table of bitwise operations
|
|
346
|
+
BITWISE = { :+ => :bitwise_add0,
|
|
347
|
+
:- => :bitwise_sub0,
|
|
348
|
+
:-@ => :bitwise_neg0,
|
|
349
|
+
:+@ => :bitwise_pos,
|
|
350
|
+
:* => :bitwise_mul0,
|
|
351
|
+
:/ => :bitwise_div0,
|
|
352
|
+
:% => :bitwise_mod0,
|
|
353
|
+
:** => :bitwise_pow0,
|
|
354
|
+
:& => :bitwise_and,
|
|
355
|
+
:| => :bitwise_or,
|
|
356
|
+
:^ => :bitwise_xor,
|
|
357
|
+
:~ => :bitwise_not,
|
|
358
|
+
:<< => :bitwise_shl,
|
|
359
|
+
:>> => :bitwise_shr,
|
|
360
|
+
:== => :bitwise_eq0,
|
|
361
|
+
:< => :bitwise_lt0,
|
|
362
|
+
:> => :bitwise_gt0,
|
|
363
|
+
:<= => :bitwise_le0,
|
|
364
|
+
:>= => :bitwise_ge0,
|
|
365
|
+
:<=>=> :bitwise_cp0
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
# Binary operations
|
|
371
|
+
|
|
372
|
+
[:+, :-, :*, :/, :%, :**, :&, :|, :^,
|
|
373
|
+
:<<, :>>,
|
|
374
|
+
:==, :<, :>, :<=, :>=, :<=>].each do |op|
|
|
375
|
+
# Select the bitwise operation.
|
|
376
|
+
bitwise = BITWISE[op]
|
|
377
|
+
# Define the operation method.
|
|
378
|
+
define_method(op) do |value|
|
|
379
|
+
# Check the value.
|
|
380
|
+
unless value.is_a?(Numeric) then
|
|
381
|
+
value = value.to_numeric if value.specified?
|
|
382
|
+
end
|
|
383
|
+
# Can the computation be performed with Ruby numeric values?
|
|
384
|
+
if self.specified? and value.is_a?(Numeric) then
|
|
385
|
+
# Yes, do it.
|
|
386
|
+
if (op == :/ or op == :%) and value == 0 then
|
|
387
|
+
# Division by 0.
|
|
388
|
+
return UNKNOWN.extend(self.size)
|
|
389
|
+
end
|
|
390
|
+
res = self.to_numeric.send(op,value)
|
|
391
|
+
# Maybe the result was a boolean, change it to an integer
|
|
392
|
+
res = res ? 1 : 0 unless res.is_a?(Numeric)
|
|
393
|
+
return res
|
|
394
|
+
else
|
|
395
|
+
# # No, is it a multiplication, division, modulo, or pow?
|
|
396
|
+
# # If it is the case, only specific values can be computed
|
|
397
|
+
# # otherwise the result is unspecified.
|
|
398
|
+
# case op
|
|
399
|
+
# when :* then
|
|
400
|
+
# svalue = self.specified? ? self.to_numeric : self
|
|
401
|
+
# return BitString.multiplication(svalue,value)
|
|
402
|
+
# when :/ then
|
|
403
|
+
# svalue = self.specified? ? self.to_numeric : self
|
|
404
|
+
# return BitString.division(svalue,value)
|
|
405
|
+
# when :% then
|
|
406
|
+
# svalue = self.specified? ? self.to_numeric : self
|
|
407
|
+
# return BitString.modulo(svalue,value)
|
|
408
|
+
# when :** then
|
|
409
|
+
# svalue = self.specified? ? self.to_numeric : self
|
|
410
|
+
# return BitString.pow(svalue,value)
|
|
411
|
+
# end
|
|
412
|
+
# No, do it bitwise.
|
|
413
|
+
# Ensure value is a bit string.
|
|
414
|
+
s1 = value.is_a?(BitString) ? value : BitString.new(value)
|
|
415
|
+
s0 = self
|
|
416
|
+
# # Convert to list of bits.
|
|
417
|
+
# value = value.to_list
|
|
418
|
+
# slist = self.to_list
|
|
419
|
+
# # Adjust the sizes.
|
|
420
|
+
# if value.size < slist.size then
|
|
421
|
+
# value += [value[-1]] * (slist.size - value.size)
|
|
422
|
+
# elsif value.size > slist.size then
|
|
423
|
+
# slist += [slist[-1]] * (value.size - slist.size)
|
|
424
|
+
# end
|
|
425
|
+
# # Perform the bitwise computation on the lists of bits
|
|
426
|
+
# res = BitString.send(bitwise,slist,value)
|
|
427
|
+
# return BitString.new(res[0..-2],res[-1])
|
|
428
|
+
|
|
429
|
+
# Adjust the widths
|
|
430
|
+
if s0.width < s1.width then
|
|
431
|
+
s0 = s0.extend(s1.width)
|
|
432
|
+
elsif s1.width < s0.width then
|
|
433
|
+
s1 = s1.extend(s0.width)
|
|
434
|
+
end
|
|
435
|
+
# Perform the bitwise computation.
|
|
436
|
+
return BitString.send(bitwise,s0,s1)
|
|
437
|
+
end
|
|
438
|
+
end
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
# Unary operations
|
|
442
|
+
|
|
443
|
+
[:+@, :-@, :~].each do |op|
|
|
444
|
+
# Select the bitwise operation.
|
|
445
|
+
bitwise = BITWISE[op]
|
|
446
|
+
# Define the operation method.
|
|
447
|
+
define_method(op) do
|
|
448
|
+
# Can the computation be performed with Ruby numeric values?
|
|
449
|
+
if self.specified? then
|
|
450
|
+
# Yes, do it.
|
|
451
|
+
return self.to_numeric.send(op)
|
|
452
|
+
else
|
|
453
|
+
# No, do it bitwise.
|
|
454
|
+
# Perform the bitwise computiation on the lists of bits
|
|
455
|
+
# res = BitString.send(bitwise,self.to_list)
|
|
456
|
+
# return BitString.new(res[0..-2],res[-1])
|
|
457
|
+
return BitString.send(bitwise,self)
|
|
458
|
+
end
|
|
459
|
+
end
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
# Bitwise operations: assume same bit width.
|
|
464
|
+
|
|
465
|
+
# Bitwise addition without processing of the x and z states.
|
|
466
|
+
def self.bitwise_add0(s0,s1)
|
|
467
|
+
return BitString.new("x"*(s0.width+1))
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
# Bitwise addition
|
|
471
|
+
def self.bitwise_add(s0,s1)
|
|
472
|
+
res = "" # The result list of bits
|
|
473
|
+
c = "0" # The current carry
|
|
474
|
+
s0.each.zip(s1.each) do |b0,b1|
|
|
475
|
+
res << XOR3_T[b0][b1][c]
|
|
476
|
+
c = MAJ_T[b0][b1][c]
|
|
477
|
+
end
|
|
478
|
+
# Compute the sign extension (the sign bit of s0 and s1 is used
|
|
479
|
+
# again)
|
|
480
|
+
res << XOR3_T[s0.sign][s1.sign][c]
|
|
481
|
+
return BitString.new(res.reverse)
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
# Bitwise subtraction without processing of the x and z states.
|
|
485
|
+
def self.bitwise_sub0(s0,s1)
|
|
486
|
+
return BitString.new("x"*(s0.width+1))
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
# Bitwise subtraction
|
|
490
|
+
def self.bitwise_sub(s0,s1)
|
|
491
|
+
# # Negate s1.
|
|
492
|
+
# s1 = BitString.bitwise_neg(s1).trunc(s0.width)
|
|
493
|
+
# # puts "s1.width = #{s1.width} s0.width = #{s0.width}"
|
|
494
|
+
# # Add it to s0: but no need to add a bit since neg already added
|
|
495
|
+
# # one.
|
|
496
|
+
# return BitString.bitwise_add(s0,s1)
|
|
497
|
+
# Perform the computation is a way to limit the propagation of
|
|
498
|
+
# unspecified bits.
|
|
499
|
+
# Is s1 specified?
|
|
500
|
+
if s1.specified? then
|
|
501
|
+
# Yes, perform -s1+s0
|
|
502
|
+
return (-s1 + s0)
|
|
503
|
+
else
|
|
504
|
+
# No, perform s0+1+NOT(s1).
|
|
505
|
+
# puts "s0=#{s0} s0+1=#{s0+1} not s1=#{bitwise_not(s1)}"
|
|
506
|
+
return (s0 + 1 + bitwise_not(s1)).trunc(s0.width+1)
|
|
507
|
+
end
|
|
508
|
+
end
|
|
509
|
+
|
|
510
|
+
# Bitwise positive sign: does nothing.
|
|
511
|
+
def self.bitwise_pos(s)
|
|
512
|
+
return s
|
|
513
|
+
end
|
|
514
|
+
|
|
515
|
+
# Bitwise negation without processing of the x and z states.
|
|
516
|
+
def self.bitwise_neg0(s)
|
|
517
|
+
return BitString.new("x"*(s.width+1))
|
|
518
|
+
end
|
|
519
|
+
|
|
520
|
+
# Bitwise negation
|
|
521
|
+
def self.bitwise_neg(s)
|
|
522
|
+
# -s = ~s + 1
|
|
523
|
+
# # Not s.
|
|
524
|
+
# s = BitString.bitwise_not(s)
|
|
525
|
+
# # Add 1.
|
|
526
|
+
# return BitString.bitwise_add(s,ONE.extend(s.width))
|
|
527
|
+
return ~s + 1
|
|
528
|
+
end
|
|
529
|
+
|
|
530
|
+
# Bitwise and
|
|
531
|
+
def self.bitwise_and(s0,s1)
|
|
532
|
+
res = s0.each.zip(s1.each).map { |b0,b1| AND_T[b0][b1] }.join
|
|
533
|
+
# puts "s0=#{s0}, s1=#{s1}, res=#{res}"
|
|
534
|
+
return BitString.new(res.reverse)
|
|
535
|
+
end
|
|
536
|
+
|
|
537
|
+
# Bitwise or
|
|
538
|
+
def self.bitwise_or(s0,s1)
|
|
539
|
+
res = s0.each.zip(s1.each). map { |b0,b1| OR_T[b0][b1] }.join
|
|
540
|
+
return BitString.new(res.reverse)
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
# Bitwise xor
|
|
544
|
+
def self.bitwise_xor(s0,s1)
|
|
545
|
+
res = s0.each.zip(s1.each). map { |b0,b1| XOR_T[b0][b1] }.join
|
|
546
|
+
return BitString.new(res.reverse)
|
|
547
|
+
end
|
|
548
|
+
|
|
549
|
+
# Bitwise not
|
|
550
|
+
def self.bitwise_not(s)
|
|
551
|
+
return BitString.new(s.each.map { |b| NOT_T[b] }.join.reverse)
|
|
552
|
+
end
|
|
553
|
+
|
|
554
|
+
# Bitwise shift left.
|
|
555
|
+
def self.bitwise_shl(s0,s1)
|
|
556
|
+
# puts "s0=#{s0} s1=#{s1}"
|
|
557
|
+
return BitString.new("x" * s0.width) unless s1.specified?
|
|
558
|
+
s1 = s1.to_numeric
|
|
559
|
+
if s1 >= 0 then
|
|
560
|
+
return BitString.new(s0.str + "0" * s1)
|
|
561
|
+
elsif -s1 > s0.width then
|
|
562
|
+
return ZERO
|
|
563
|
+
else
|
|
564
|
+
return s0.trim(s0.width+s1)
|
|
565
|
+
end
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
# Bitwise shift right.
|
|
569
|
+
def self.bitwise_shr(s0,s1)
|
|
570
|
+
# puts "s0=#{s0} s1=#{s1}"
|
|
571
|
+
return BitString.new("x" * s0.width) unless s1.specified?
|
|
572
|
+
s1 = s1.to_numeric
|
|
573
|
+
if s1 <= 0 then
|
|
574
|
+
return BitString.new(s0.str + "0" * -s1)
|
|
575
|
+
elsif s1 > s0.width then
|
|
576
|
+
return ZERO
|
|
577
|
+
else
|
|
578
|
+
return s0.trim(s0.width-s1)
|
|
579
|
+
end
|
|
580
|
+
end
|
|
581
|
+
|
|
582
|
+
|
|
583
|
+
# Bitwise eq without processing of the x and z states.
|
|
584
|
+
def self.bitwise_eq0(s0,s1)
|
|
585
|
+
return UNKNOWN
|
|
586
|
+
end
|
|
587
|
+
|
|
588
|
+
# Bitwise eq.
|
|
589
|
+
def self.bitwise_eq(s0,s1)
|
|
590
|
+
return UNKNOWN unless (s0.specified? and s1.specified?)
|
|
591
|
+
return s0.str == s1.str ? TRUE : FALSE
|
|
592
|
+
end
|
|
593
|
+
|
|
594
|
+
|
|
595
|
+
# Bitwise lt without processing of the x and z states.
|
|
596
|
+
def self.bitwise_lt0(s0,s1)
|
|
597
|
+
return UNKNOWN
|
|
598
|
+
end
|
|
599
|
+
|
|
600
|
+
# Bitwise lt.
|
|
601
|
+
def self.bitwise_lt(s0,s1)
|
|
602
|
+
# # Handle the zero cases.
|
|
603
|
+
# if s0.zero? then
|
|
604
|
+
# return TRUE if s1.positive?
|
|
605
|
+
# return FALSE if s1.negative? or s1.zero?
|
|
606
|
+
# return UNKNOWN
|
|
607
|
+
# elsif s1.zero? then
|
|
608
|
+
# return TRUE if s0.negative?
|
|
609
|
+
# return FALSE if s0.positive? or s0.zero?
|
|
610
|
+
# return UNKNOWN
|
|
611
|
+
# end
|
|
612
|
+
# # Handle the unspecified sign cases.
|
|
613
|
+
# unless s0.sign? then
|
|
614
|
+
# # Check both sign cases.
|
|
615
|
+
# lt_pos = self.bitwise_lt(s0[-1] = "1",s1)
|
|
616
|
+
# lt_neg = self.bitwise_lt(s0[-1] = "0",s1)
|
|
617
|
+
# # At least one of the results is unspecified.
|
|
618
|
+
# return UNKNOWN unless (lt_pos.specified? and lt_neg.specified?)
|
|
619
|
+
# # Both results are specified and identical.
|
|
620
|
+
# return lt_pos if lt_pos == lt_neg
|
|
621
|
+
# # Results are different.
|
|
622
|
+
# return UNKNOWN
|
|
623
|
+
# end
|
|
624
|
+
# unless s1.sign? then
|
|
625
|
+
# # Check both sign cases.
|
|
626
|
+
# lt_pos = self.bitwise_lt(s0,s1[-1] = "1")
|
|
627
|
+
# lt_neg = self.bitwise_lt(s0,s1[-1] = "0")
|
|
628
|
+
# # At least one of the results is unspecified.
|
|
629
|
+
# return UNKNOWN unless (lt_pos.specified? and lt_neg.specified?)
|
|
630
|
+
# # Both results are specified and identical.
|
|
631
|
+
# return lt_pos if lt_pos == lt_neg
|
|
632
|
+
# # Results are different.
|
|
633
|
+
# return UNKNOWN
|
|
634
|
+
# end
|
|
635
|
+
# # Signs are specificied.
|
|
636
|
+
# # Depending on the signs
|
|
637
|
+
# if s0.positive? then
|
|
638
|
+
# if s1.positive? then
|
|
639
|
+
# # s0 and s1 are positive, need to compare each bit.
|
|
640
|
+
# s0.reverse_each.zip(s1.reverse_each) do |b0,b1|
|
|
641
|
+
# # puts "b0=#{b0} b1=#{b1}, LT_T[b0][b1]=#{LT_T[b0][b1]}"
|
|
642
|
+
# case LT_T[b0][b1]
|
|
643
|
+
# when "x" then return UNKNOWN
|
|
644
|
+
# when "1" then return TRUE
|
|
645
|
+
# when "0" then
|
|
646
|
+
# return FALSE if GT_T[b0][b1] == "1"
|
|
647
|
+
# end
|
|
648
|
+
# end
|
|
649
|
+
# elsif s1.negative? then
|
|
650
|
+
# # s0 is positive and s1 is negative.
|
|
651
|
+
# return FALSE
|
|
652
|
+
# else
|
|
653
|
+
# # The sign of s1 is undefined, comparison is undefined too.
|
|
654
|
+
# return UNKNOWN
|
|
655
|
+
# end
|
|
656
|
+
# elsif s0.negative? then
|
|
657
|
+
# if s1.positive? then
|
|
658
|
+
# # s0 is negative and s1 is positive
|
|
659
|
+
# return TRUE
|
|
660
|
+
# elsif s1.negative? then
|
|
661
|
+
# # s0 and s1 are negative, need to compare each bit.
|
|
662
|
+
# s0.reverse_each.zip(s1.reverse_each) do |b0,b1|
|
|
663
|
+
# case GT_T[b0][b1]
|
|
664
|
+
# when "x" then return UNKNOWN
|
|
665
|
+
# when "1" then return FALSE
|
|
666
|
+
# when "0" then
|
|
667
|
+
# return TRUE if LT_T[b0][b1] == "1"
|
|
668
|
+
# end
|
|
669
|
+
# end
|
|
670
|
+
# end
|
|
671
|
+
# else
|
|
672
|
+
# # The sign of s0 is undefined, comparison is undefined too.
|
|
673
|
+
# return UNKNOWN
|
|
674
|
+
# end
|
|
675
|
+
|
|
676
|
+
# Check the sign of the subtraction between s0 and s1.
|
|
677
|
+
case (s0-s1).sign
|
|
678
|
+
when "0" then return FALSE
|
|
679
|
+
when "1" then return TRUE
|
|
680
|
+
else
|
|
681
|
+
return UNKNOWN
|
|
682
|
+
end
|
|
683
|
+
end
|
|
684
|
+
|
|
685
|
+
|
|
686
|
+
# Bitwise gt without processing of the x and z states.
|
|
687
|
+
def self.bitwise_gt0(s0,s1)
|
|
688
|
+
return UNKNOWN
|
|
689
|
+
end
|
|
690
|
+
|
|
691
|
+
# Bitwise gt.
|
|
692
|
+
def self.bitwise_gt(s0,s1)
|
|
693
|
+
return self.bitwise_lt(s1,s0)
|
|
694
|
+
end
|
|
695
|
+
|
|
696
|
+
|
|
697
|
+
# Bitwise le without processing of the x and z states.
|
|
698
|
+
def self.bitwise_le0(s0,s1)
|
|
699
|
+
return UNKNOWN
|
|
700
|
+
end
|
|
701
|
+
|
|
702
|
+
# Bitwise le.
|
|
703
|
+
def self.bitwise_le(s0,s1)
|
|
704
|
+
gt = self.bitwise_gt(s0,s1)
|
|
705
|
+
if gt.eql?(TRUE) then
|
|
706
|
+
return FALSE
|
|
707
|
+
elsif gt.eql?(FALSE) then
|
|
708
|
+
return TRUE
|
|
709
|
+
else
|
|
710
|
+
return UNKNOWN
|
|
711
|
+
end
|
|
712
|
+
end
|
|
713
|
+
|
|
714
|
+
|
|
715
|
+
# Bitwise ge without processing of the x and z states.
|
|
716
|
+
def self.bitwise_ge0(s0,s1)
|
|
717
|
+
return UNKNOWN
|
|
718
|
+
end
|
|
719
|
+
|
|
720
|
+
# Bitwise ge.
|
|
721
|
+
def self.bitwise_ge(s0,s1)
|
|
722
|
+
lt = self.bitwise_lt(s0,s1)
|
|
723
|
+
if lt.eql?(TRUE) then
|
|
724
|
+
return FALSE
|
|
725
|
+
elsif lt.eql?(FALSE) then
|
|
726
|
+
return TRUE
|
|
727
|
+
else
|
|
728
|
+
return UNKNOWN
|
|
729
|
+
end
|
|
730
|
+
end
|
|
731
|
+
|
|
732
|
+
|
|
733
|
+
# Bitwise cp without processing of the x and z states.
|
|
734
|
+
def self.bitwise_cp0(s0,s1)
|
|
735
|
+
return UNKNOWN
|
|
736
|
+
end
|
|
737
|
+
|
|
738
|
+
# Bitwise cp.
|
|
739
|
+
def self.bitwise_cp(s0,s1)
|
|
740
|
+
# Compare the signs.
|
|
741
|
+
if s0.sign == "0" and s1.sign == "1" then
|
|
742
|
+
return ONE
|
|
743
|
+
elsif s0.sign == 0 and s1.sign == "1" then
|
|
744
|
+
return MINUS_ONE
|
|
745
|
+
end
|
|
746
|
+
# Compare the other bits.
|
|
747
|
+
sub = self.bitwise_sub(s0,s1)
|
|
748
|
+
if sub.negative? then
|
|
749
|
+
return MINUS_ONE
|
|
750
|
+
elsif sub.zero? then
|
|
751
|
+
return ZERO
|
|
752
|
+
elsif sub.positive? then
|
|
753
|
+
return ONE
|
|
754
|
+
else
|
|
755
|
+
return UNKNOWN
|
|
756
|
+
end
|
|
757
|
+
end
|
|
758
|
+
|
|
759
|
+
# Bitwise mul without processing of the x and z states.
|
|
760
|
+
def self.bitwise_mul0(s0,s1)
|
|
761
|
+
return BitString.new("x"*(s0.width+s1.width))
|
|
762
|
+
end
|
|
763
|
+
|
|
764
|
+
# Bitwise mul.
|
|
765
|
+
def self.bitwise_mul(s0,s1)
|
|
766
|
+
# Initialize the result to ZERO of combined s0 and s1 widths
|
|
767
|
+
res = ZERO.extend(s0.width + s1.width)
|
|
768
|
+
# The zero cases.
|
|
769
|
+
if s0.zero? or s1.zero? then
|
|
770
|
+
return res
|
|
771
|
+
end
|
|
772
|
+
# Convert s1 and res to lists of bits which support computation
|
|
773
|
+
# between unknown bits of same values.
|
|
774
|
+
s1 = s1.extend(res.width).to_list
|
|
775
|
+
res = res.to_list
|
|
776
|
+
# The other cases: perform a multiplication with shifts and adds.
|
|
777
|
+
s0.each.lazy.take(s0.width).each do |b|
|
|
778
|
+
case b
|
|
779
|
+
when "1" then self.list_add!(res,s1)
|
|
780
|
+
when "x","z" then self.list_add!(res,self.list_and_unknown(s1))
|
|
781
|
+
end
|
|
782
|
+
# puts "res=#{res} s1=#{s1}"
|
|
783
|
+
self.list_shl_1!(s1)
|
|
784
|
+
end
|
|
785
|
+
# Add the sign row.
|
|
786
|
+
case s0.sign
|
|
787
|
+
when "1" then self.list_sub!(res,s1)
|
|
788
|
+
when "x","z" then self.list_sub!(res,list_and_unknown(s1))
|
|
789
|
+
end
|
|
790
|
+
# Return the result.
|
|
791
|
+
return self.list_to_bstr(res)
|
|
792
|
+
end
|
|
793
|
+
|
|
794
|
+
# Bitwise div without processing of the x and z states.
|
|
795
|
+
def self.bitwise_div0(s0,s1)
|
|
796
|
+
return BitString.new("x"*(s0.width))
|
|
797
|
+
end
|
|
798
|
+
|
|
799
|
+
# Bitwise div.
|
|
800
|
+
def self.bitwise_div(s0,s1)
|
|
801
|
+
width = s0.width
|
|
802
|
+
# The zero cases.
|
|
803
|
+
if s0.zero? then
|
|
804
|
+
return res
|
|
805
|
+
elsif s1.maybe_zero? then
|
|
806
|
+
return UNKNOWN.extend(width)
|
|
807
|
+
end
|
|
808
|
+
# Handle the sign: the division is only performed on positive
|
|
809
|
+
# numbers.
|
|
810
|
+
# NOTE: we are sure that s0 and s1 are not zero since these
|
|
811
|
+
# cases have been handled before.
|
|
812
|
+
sign = nil
|
|
813
|
+
if s0.sign == "0" then
|
|
814
|
+
if s1.sign == "0" then
|
|
815
|
+
sign = "0"
|
|
816
|
+
elsif s1.sign == "1" then
|
|
817
|
+
sign = "1"
|
|
818
|
+
s1 = -s1
|
|
819
|
+
else
|
|
820
|
+
# Unknown sign, unkown result.
|
|
821
|
+
return UNKNOWN.extend(width)
|
|
822
|
+
end
|
|
823
|
+
elsif s0.sign == "1" then
|
|
824
|
+
s0 = -s0
|
|
825
|
+
if s1.sign == "0" then
|
|
826
|
+
sign = "1"
|
|
827
|
+
elsif s1.sign == "1" then
|
|
828
|
+
sign = "0"
|
|
829
|
+
s1 = -s1
|
|
830
|
+
else
|
|
831
|
+
# Unknwown sign, unknown result.
|
|
832
|
+
return UNKNOWN.extend(width)
|
|
833
|
+
end
|
|
834
|
+
else
|
|
835
|
+
# Unknown sign, unknown result.
|
|
836
|
+
return UNKNOWN.extend(width)
|
|
837
|
+
end
|
|
838
|
+
# Convert s0 and s1 to list of bits of widths of s0 and s1 -1
|
|
839
|
+
# (the largest possible value).
|
|
840
|
+
# s0 will serve as current remainder.
|
|
841
|
+
s0 = BitString.new(s0) if s0.is_a?(Numeric)
|
|
842
|
+
s1 = BitString.new(s1) if s1.is_a?(Numeric)
|
|
843
|
+
s0 = s0.extend(s0.width+s1.width-1)
|
|
844
|
+
s1 = s1.extend(s0.width)
|
|
845
|
+
s0 = s0.to_list
|
|
846
|
+
s1 = s1.to_list
|
|
847
|
+
puts "first s1=#{s1}"
|
|
848
|
+
# Adujst s1 to the end of s0 and the corresponding 0s in front of q
|
|
849
|
+
msb = s0.reverse.index {|b| b != 0}
|
|
850
|
+
steps = s0.size-msb
|
|
851
|
+
self.list_shl!(s1,steps-1)
|
|
852
|
+
q = [ 0 ] * (width-steps)
|
|
853
|
+
# Apply the non-restoring division algorithm.
|
|
854
|
+
sub = true
|
|
855
|
+
puts "steps= #{steps} s0=#{s0} s1=#{s1} q=#{q}"
|
|
856
|
+
(steps).times do |i|
|
|
857
|
+
if sub then
|
|
858
|
+
self.list_sub!(s0,s1)
|
|
859
|
+
else
|
|
860
|
+
self.list_add!(s0,s1)
|
|
861
|
+
end
|
|
862
|
+
puts "s0=#{s0}"
|
|
863
|
+
# Is the result positive?
|
|
864
|
+
if s0[-1] == 0 then
|
|
865
|
+
# Yes, the next step is a subtraction and the current
|
|
866
|
+
# result bit is one.
|
|
867
|
+
sub = true
|
|
868
|
+
q.unshift(1)
|
|
869
|
+
elsif s0[-1] == 1 then
|
|
870
|
+
# No, it is negative the next step is an addition and the
|
|
871
|
+
# current result bit is zero.
|
|
872
|
+
sub = false
|
|
873
|
+
q.unshift(0)
|
|
874
|
+
else
|
|
875
|
+
# Unknown sign, the remaining of q is unknown.
|
|
876
|
+
(steps-i).times { q.unshift(self.new_unknown) }
|
|
877
|
+
# Still, can add the positive sign bit.
|
|
878
|
+
q.push(0)
|
|
879
|
+
break
|
|
880
|
+
end
|
|
881
|
+
self.list_shr_1!(s1)
|
|
882
|
+
end
|
|
883
|
+
# Generate the resulting bit string.
|
|
884
|
+
puts "q=#{q}"
|
|
885
|
+
q = self.list_to_bstr(q)
|
|
886
|
+
puts "q=#{q}"
|
|
887
|
+
# Set the sign.
|
|
888
|
+
if sign == "1" then
|
|
889
|
+
q = (-q).trunc(width)
|
|
890
|
+
elsif q.zero? then
|
|
891
|
+
q = 0
|
|
892
|
+
else
|
|
893
|
+
q = q.extend(width)
|
|
894
|
+
end
|
|
895
|
+
# Return the result.
|
|
896
|
+
return q
|
|
897
|
+
end
|
|
898
|
+
|
|
899
|
+
|
|
900
|
+
# Bitwise mod without processing of the x and z states.
|
|
901
|
+
def self.bitwise_mod0(s0,s1)
|
|
902
|
+
return BitString.new("x"*(s1.width))
|
|
903
|
+
end
|
|
904
|
+
|
|
905
|
+
# Bitwise mod.
|
|
906
|
+
def self.bitwise_div(s0,s1)
|
|
907
|
+
raise "bitwise_div is not implemented yet."
|
|
908
|
+
end
|
|
909
|
+
|
|
910
|
+
|
|
911
|
+
# Computation with list of bits:
|
|
912
|
+
# "0" -> 0, "1" -> 1, and then 2, 3, 4, ...
|
|
913
|
+
# Allows more precise computations (e.g., mul, div).
|
|
914
|
+
|
|
915
|
+
# The counter of unknown bits.
|
|
916
|
+
@@unknown = 1
|
|
917
|
+
|
|
918
|
+
# Creates a new uniq unknown bit.
|
|
919
|
+
def self.new_unknown
|
|
920
|
+
@@unknown += 1
|
|
921
|
+
return @@unknown
|
|
922
|
+
end
|
|
923
|
+
|
|
924
|
+
# Converts to a list of bits where unknown or high z bits are
|
|
925
|
+
# differentiate from each other.
|
|
926
|
+
#
|
|
927
|
+
# NOTE:
|
|
928
|
+
# * the sign bit is also added to the list.
|
|
929
|
+
# * the distinction between z and x is lost.
|
|
930
|
+
def to_list
|
|
931
|
+
return @str.each_char.reverse_each.map.with_index do |b,i|
|
|
932
|
+
case b
|
|
933
|
+
when "0" then 0
|
|
934
|
+
when "1" then 1
|
|
935
|
+
when "z","x" then BitString.new_unknown
|
|
936
|
+
else
|
|
937
|
+
raise "Internal error: invalid bit in bitstring: #{b}"
|
|
938
|
+
end
|
|
939
|
+
end
|
|
940
|
+
end
|
|
941
|
+
|
|
942
|
+
# Converts list of bits +l+ to a bit string.
|
|
943
|
+
def self.list_to_bstr(l)
|
|
944
|
+
str = l.reverse_each.map { |b| b > 1 ? "x" : b }.join
|
|
945
|
+
return BitString.new(str)
|
|
946
|
+
end
|
|
947
|
+
|
|
948
|
+
# Compute the and between +l+ and an unknown value.
|
|
949
|
+
def self.list_and_unknown(l)
|
|
950
|
+
return l.map do |b|
|
|
951
|
+
b == 0 ? 0 : BitString.new_unknown
|
|
952
|
+
end
|
|
953
|
+
end
|
|
954
|
+
|
|
955
|
+
# Compute the not of +l+
|
|
956
|
+
def self.list_not(l)
|
|
957
|
+
return l.map do |b|
|
|
958
|
+
case b
|
|
959
|
+
when 0 then 1
|
|
960
|
+
when 1 then 0
|
|
961
|
+
else
|
|
962
|
+
BitString.new_unknown
|
|
963
|
+
end
|
|
964
|
+
end
|
|
965
|
+
end
|
|
966
|
+
|
|
967
|
+
# Adds +l1+ to +l0+.
|
|
968
|
+
#
|
|
969
|
+
# NOTE:
|
|
970
|
+
# * l0 is contains the result.
|
|
971
|
+
# * The result has the same size as +l0+ (no sign extension).
|
|
972
|
+
# * Assumes +l0+ and +l1+ have the same size.
|
|
973
|
+
def self.list_add!(l0,l1)
|
|
974
|
+
# puts "add l0=#{l0} l1=#{l1}"
|
|
975
|
+
c = 0 # Current carry.
|
|
976
|
+
l0.each_with_index do |b0,i|
|
|
977
|
+
b1 = l1[i]
|
|
978
|
+
# puts "i=#{i} b0=#{b0} b1=#{b1} c=#{c}"
|
|
979
|
+
if b0 == b1 then
|
|
980
|
+
# The sum is c.
|
|
981
|
+
l0[i] = c
|
|
982
|
+
# The carry is b0.
|
|
983
|
+
c = b0
|
|
984
|
+
elsif b0 == c then
|
|
985
|
+
# The sum is b1.
|
|
986
|
+
l0[i] = b1
|
|
987
|
+
# The carry is b0.
|
|
988
|
+
c = b0
|
|
989
|
+
elsif b1 == c then
|
|
990
|
+
# The sum is b0.
|
|
991
|
+
l0[i] = b0
|
|
992
|
+
# The carry is b1.
|
|
993
|
+
c = b1
|
|
994
|
+
else
|
|
995
|
+
l0[i] = self.new_unknown
|
|
996
|
+
c = self.new_unknown
|
|
997
|
+
end
|
|
998
|
+
end
|
|
999
|
+
return l0
|
|
1000
|
+
end
|
|
1001
|
+
|
|
1002
|
+
# Adds 1 to +l0+.
|
|
1003
|
+
#
|
|
1004
|
+
# NOTE:
|
|
1005
|
+
# * l0 is contains the result.
|
|
1006
|
+
# * The result has the same size as +l0+ (no sign extension).
|
|
1007
|
+
def self.list_add_1!(l0)
|
|
1008
|
+
c = 1 # Current carry.
|
|
1009
|
+
l0.each_with_index do |b0,i|
|
|
1010
|
+
if c == 0 then
|
|
1011
|
+
# The sum is b0.
|
|
1012
|
+
l0[i] = b0
|
|
1013
|
+
# The carry is unchanged.
|
|
1014
|
+
elsif b0 == 0 then
|
|
1015
|
+
# The sum is c.
|
|
1016
|
+
l0[i] = c
|
|
1017
|
+
# The carry is 0.
|
|
1018
|
+
c = 0
|
|
1019
|
+
elsif b0 == c then
|
|
1020
|
+
# The sum is 0.
|
|
1021
|
+
l0[i] = 0
|
|
1022
|
+
# The carry is b0.
|
|
1023
|
+
c = b0
|
|
1024
|
+
else
|
|
1025
|
+
# Both sum and carry are unknown
|
|
1026
|
+
l0[i] = BitString.new_unknown
|
|
1027
|
+
c = BitString.new_unknown
|
|
1028
|
+
end
|
|
1029
|
+
end
|
|
1030
|
+
return l0
|
|
1031
|
+
end
|
|
1032
|
+
|
|
1033
|
+
# Subtracts +l1+ from +l0+.
|
|
1034
|
+
#
|
|
1035
|
+
# NOTE:
|
|
1036
|
+
# * l0 is contains the result.
|
|
1037
|
+
# * The result has the same size as +l0+ (no sign extension).
|
|
1038
|
+
# * Assumes +l0+ and +l1+ have the same size.
|
|
1039
|
+
def self.list_sub!(l0,l1)
|
|
1040
|
+
# Adds 1 to l0.
|
|
1041
|
+
BitString.list_add_1!(l0)
|
|
1042
|
+
# Adds ~l1 to l0.
|
|
1043
|
+
# puts "l0=#{l0} l1=#{l1} ~l1=#{self.list_not(l1)}}"
|
|
1044
|
+
self.list_add!(l0,self.list_not(l1))
|
|
1045
|
+
# puts "l0=#{l0}"
|
|
1046
|
+
# puts "now l0=#{l0}"
|
|
1047
|
+
return l0
|
|
1048
|
+
end
|
|
1049
|
+
|
|
1050
|
+
# Left shifts +l+ once.
|
|
1051
|
+
#
|
|
1052
|
+
# NOTE:
|
|
1053
|
+
# * l contains the result.
|
|
1054
|
+
# * The result has the same size as +l+ (no sign extension).
|
|
1055
|
+
def self.list_shl_1!(l)
|
|
1056
|
+
l.pop
|
|
1057
|
+
l.unshift(0)
|
|
1058
|
+
return l
|
|
1059
|
+
end
|
|
1060
|
+
|
|
1061
|
+
# Right shifts +l+ once.
|
|
1062
|
+
#
|
|
1063
|
+
# NOTE:
|
|
1064
|
+
# * l contains the result.
|
|
1065
|
+
# * The result has the same size as +l+ (no sign extension).
|
|
1066
|
+
def self.list_shr_1!(l)
|
|
1067
|
+
l.shift
|
|
1068
|
+
l.push(0)
|
|
1069
|
+
return l
|
|
1070
|
+
end
|
|
1071
|
+
|
|
1072
|
+
|
|
1073
|
+
# Left shifts +l+ +x+ times.
|
|
1074
|
+
#
|
|
1075
|
+
# NOTE:
|
|
1076
|
+
# * l contains the result.
|
|
1077
|
+
# * The result has the same size as +l+ (no sign extension).
|
|
1078
|
+
def self.list_shl!(l,x)
|
|
1079
|
+
l.pop(x)
|
|
1080
|
+
l.unshift(*([0]*x))
|
|
1081
|
+
end
|
|
1082
|
+
|
|
1083
|
+
end
|
|
1084
|
+
|
|
1085
|
+
end
|