import migen in litex/gen
[litex.git] / migen / fhdl / bitcontainer.py
1 from migen.fhdl import structure as f
2
3
4 __all__ = ["log2_int", "bits_for", "value_bits_sign"]
5
6
7 def log2_int(n, need_pow2=True):
8 l = 1
9 r = 0
10 while l < n:
11 l *= 2
12 r += 1
13 if need_pow2 and l != n:
14 raise ValueError("Not a power of 2")
15 return r
16
17
18 def bits_for(n, require_sign_bit=False):
19 if n > 0:
20 r = log2_int(n + 1, False)
21 else:
22 require_sign_bit = True
23 r = log2_int(-n, False)
24 if require_sign_bit:
25 r += 1
26 return r
27
28
29 def value_bits_sign(v):
30 """Bit length and signedness of a value.
31
32 Parameters
33 ----------
34 v : Value
35
36 Returns
37 -------
38 int, bool
39 Number of bits required to store `v` or available in `v`, followed by
40 whether `v` has a sign bit (included in the bit count).
41
42 Examples
43 --------
44 >>> value_bits_sign(f.Signal(8))
45 8, False
46 >>> value_bits_sign(C(0xaa))
47 8, False
48 """
49 if isinstance(v, (f.Constant, f.Signal)):
50 return v.nbits, v.signed
51 elif isinstance(v, (f.ClockSignal, f.ResetSignal)):
52 return 1, False
53 elif isinstance(v, f._Operator):
54 obs = list(map(value_bits_sign, v.operands))
55 if v.op == "+" or v.op == "-":
56 if not obs[0][1] and not obs[1][1]:
57 # both operands unsigned
58 return max(obs[0][0], obs[1][0]) + 1, False
59 elif obs[0][1] and obs[1][1]:
60 # both operands signed
61 return max(obs[0][0], obs[1][0]) + 1, True
62 elif not obs[0][1] and obs[1][1]:
63 # first operand unsigned (add sign bit), second operand signed
64 return max(obs[0][0] + 1, obs[1][0]) + 1, True
65 else:
66 # first signed, second operand unsigned (add sign bit)
67 return max(obs[0][0], obs[1][0] + 1) + 1, True
68 elif v.op == "*":
69 if not obs[0][1] and not obs[1][1]:
70 # both operands unsigned
71 return obs[0][0] + obs[1][0], False
72 elif obs[0][1] and obs[1][1]:
73 # both operands signed
74 return obs[0][0] + obs[1][0] - 1, True
75 else:
76 # one operand signed, the other unsigned (add sign bit)
77 return obs[0][0] + obs[1][0] + 1 - 1, True
78 elif v.op == "<<<":
79 if obs[1][1]:
80 extra = 2**(obs[1][0] - 1) - 1
81 else:
82 extra = 2**obs[1][0] - 1
83 return obs[0][0] + extra, obs[0][1]
84 elif v.op == ">>>":
85 if obs[1][1]:
86 extra = 2**(obs[1][0] - 1)
87 else:
88 extra = 0
89 return obs[0][0] + extra, obs[0][1]
90 elif v.op == "&" or v.op == "^" or v.op == "|":
91 if not obs[0][1] and not obs[1][1]:
92 # both operands unsigned
93 return max(obs[0][0], obs[1][0]), False
94 elif obs[0][1] and obs[1][1]:
95 # both operands signed
96 return max(obs[0][0], obs[1][0]), True
97 elif not obs[0][1] and obs[1][1]:
98 # first operand unsigned (add sign bit), second operand signed
99 return max(obs[0][0] + 1, obs[1][0]), True
100 else:
101 # first signed, second operand unsigned (add sign bit)
102 return max(obs[0][0], obs[1][0] + 1), True
103 elif v.op == "<" or v.op == "<=" or v.op == "==" or v.op == "!=" \
104 or v.op == ">" or v.op == ">=":
105 return 1, False
106 elif v.op == "~":
107 return obs[0]
108 else:
109 raise TypeError
110 elif isinstance(v, f._Slice):
111 return v.stop - v.start, value_bits_sign(v.value)[1]
112 elif isinstance(v, f.Cat):
113 return sum(value_bits_sign(sv)[0] for sv in v.l), False
114 elif isinstance(v, f.Replicate):
115 return (value_bits_sign(v.v)[0])*v.n, False
116 elif isinstance(v, f._ArrayProxy):
117 bsc = list(map(value_bits_sign, v.choices))
118 return max(bs[0] for bs in bsc), any(bs[1] for bs in bsc)
119 else:
120 raise TypeError("Can not calculate bit length of {} {}".format(
121 type(v), v))