1 from migen
.fhdl
import structure
as f
4 __all__
= ["log2_int", "bits_for", "flen", "fiter"]
7 def log2_int(n
, need_pow2
=True):
13 if need_pow2
and l
!= n
:
14 raise ValueError("Not a power of 2")
18 def bits_for(n
, require_sign_bit
=False):
20 r
= log2_int(n
+ 1, False)
22 require_sign_bit
= True
23 r
= log2_int(-n
, False)
29 def value_bits_sign(v
):
30 if isinstance(v
, (f
.Constant
, f
.Signal
)):
31 return v
.nbits
, v
.signed
32 elif isinstance(v
, (f
.ClockSignal
, f
.ResetSignal
)):
34 elif isinstance(v
, f
._Operator
):
35 obs
= list(map(value_bits_sign
, v
.operands
))
36 if v
.op
== "+" or v
.op
== "-":
37 if not obs
[0][1] and not obs
[1][1]:
38 # both operands unsigned
39 return max(obs
[0][0], obs
[1][0]) + 1, False
40 elif obs
[0][1] and obs
[1][1]:
41 # both operands signed
42 return max(obs
[0][0], obs
[1][0]) + 1, True
43 elif not obs
[0][1] and obs
[1][1]:
44 # first operand unsigned (add sign bit), second operand signed
45 return max(obs
[0][0] + 1, obs
[1][0]) + 1, True
47 # first signed, second operand unsigned (add sign bit)
48 return max(obs
[0][0], obs
[1][0] + 1) + 1, True
50 if not obs
[0][1] and not obs
[1][1]:
51 # both operands unsigned
52 return obs
[0][0] + obs
[1][0], False
53 elif obs
[0][1] and obs
[1][1]:
54 # both operands signed
55 return obs
[0][0] + obs
[1][0] - 1, True
57 # one operand signed, the other unsigned (add sign bit)
58 return obs
[0][0] + obs
[1][0] + 1 - 1, True
61 extra
= 2**(obs
[1][0] - 1) - 1
63 extra
= 2**obs
[1][0] - 1
64 return obs
[0][0] + extra
, obs
[0][1]
67 extra
= 2**(obs
[1][0] - 1)
70 return obs
[0][0] + extra
, obs
[0][1]
71 elif v
.op
== "&" or v
.op
== "^" or v
.op
== "|":
72 if not obs
[0][1] and not obs
[1][1]:
73 # both operands unsigned
74 return max(obs
[0][0], obs
[1][0]), False
75 elif obs
[0][1] and obs
[1][1]:
76 # both operands signed
77 return max(obs
[0][0], obs
[1][0]), True
78 elif not obs
[0][1] and obs
[1][1]:
79 # first operand unsigned (add sign bit), second operand signed
80 return max(obs
[0][0] + 1, obs
[1][0]), True
82 # first signed, second operand unsigned (add sign bit)
83 return max(obs
[0][0], obs
[1][0] + 1), True
84 elif v
.op
== "<" or v
.op
== "<=" or v
.op
== "==" or v
.op
== "!=" \
85 or v
.op
== ">" or v
.op
== ">=":
91 elif isinstance(v
, f
._Slice
):
92 return v
.stop
- v
.start
, value_bits_sign(v
.value
)[1]
93 elif isinstance(v
, f
.Cat
):
94 return sum(value_bits_sign(sv
)[0] for sv
in v
.l
), False
95 elif isinstance(v
, f
.Replicate
):
96 return (value_bits_sign(v
.v
)[0])*v
.n
, False
97 elif isinstance(v
, f
._ArrayProxy
):
98 bsc
= list(map(value_bits_sign
, v
.choices
))
99 return max(bs
[0] for bs
in bsc
), any(bs
[1] for bs
in bsc
)
101 raise TypeError("Can not calculate bit length of {} {}".format(
106 """Bit length of an expression
110 v : int, bool or Value
115 Number of bits required to store `v` or available in `v`
119 >>> flen(f.Signal(8))
124 return value_bits_sign(v
)[0]
132 v : int, bool or Value
137 Iterator over the bits in `v`
141 >>> list(fiter(f.Signal(2))) #doctest: +ELLIPSIS
142 [<migen.fhdl.structure._Slice object at 0x...>, <migen.fhdl.structure._Slice object at 0x...>]
146 if isinstance(v
, (bool, int)):
147 return ((v
>> i
) & 1 for i
in range(bits_for(v
)))
148 elif isinstance(v
, f
.Value
):
149 return (v
[i
] for i
in range(flen(v
)))
151 raise TypeError("Can not bit-iterate {} {}".format(type(v
), v
))