/
ala.py
143 lines (121 loc) · 3.62 KB
/
ala.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
from migen.fhdl.structure import *
from migen.fhdl.structure import _Operator
from migen.flow.actor import *
from migen.flow.network import *
from migen.corelogic.record import *
from migen.corelogic import divider
class _SimpleBinary(CombinatorialActor):
def __init__(self, bv_op, bv_r=None):
self.bv_op = bv_op
if bv_r is None:
bv_r = self.__class__.get_result_bv(bv_op)
self.bv_r = bv_r
super().__init__(
("operands", Sink, [("a", bv_op), ("b", bv_op)]),
("result", Source, [("r", bv_r)]))
def get_process_fragment(self):
return Fragment([
self.token("result").r.eq(_Operator(self.op,
[self.token("operands").a, self.token("operands").b]))
])
class Add(_SimpleBinary):
op = "+"
def get_result_bv(bv):
return BV(bv.width+1, bv.signed)
class Sub(_SimpleBinary):
op = "-"
def get_result_bv(bv):
return BV(bv.width+1, bv.signed)
class Mul(_SimpleBinary):
op = "*"
def get_result_bv(bv):
return BV(2*bv.width, bv.signed)
class And(_SimpleBinary):
op = "&"
def get_result_bv(bv):
return bv
class Xor(_SimpleBinary):
op = "^"
def get_result_bv(bv):
return bv
class Or(_SimpleBinary):
op = "|"
def get_result_bv(bv):
return bv
class LT(_SimpleBinary):
op = "<"
def get_result_bv(bv):
return BV(1)
class LE(_SimpleBinary):
op = "<="
def get_result_bv(bv):
return BV(1)
class EQ(_SimpleBinary):
op = "=="
def get_result_bv(bv):
return BV(1)
class NE(_SimpleBinary):
op = "!="
def get_result_bv(bv):
return BV(1)
class DivMod(SequentialActor):
def __init__(self, width):
self.div = divider.Divider(width)
super().__init__(width,
("operands", Sink, [("dividend", self.div.dividend_i), ("divisor", self.div.divisor_i)]),
("result", Source, [("quotient", self.div.quotient_o), ("remainder", self.div.remainder_o)]))
def get_process_fragment(self):
return self.div.get_fragment() + Fragment([self.div.start_i.eq(self.trigger)])
def _create(a, b, actor_class):
assert id(a.dfg) == id(b.dfg)
dfg = a.dfg
bva = a.get_dict()["bv_r"]
bvb = b.get_dict()["bv_r"]
bv_op = BV(max(bva.width, bvb.width), bva.signed and bvb.signed)
bv_r = actor_class.get_result_bv(bv_op)
new_actor = ComposableNode(dfg, actor_class, {"bv_op": bv_op, "bv_r": bv_r})
dfg.add_connection(a, new_actor, "result", "operands", sink_subr=["a"])
dfg.add_connection(b, new_actor, "result", "operands", sink_subr=["b"])
return new_actor
class ComposableNode(ActorNode):
def __init__(self, dfg, actor_class, parameters=dict()):
self.dfg = dfg
super().__init__(actor_class, parameters)
def __hash__(self):
return id(self)
def __add__(self, other):
return _create(self, other, Add)
def __radd__(self, other):
return _create(other, self, Add)
def __sub__(self, other):
return _create(self, other, Sub)
def __rsub__(self, other):
return _create(other, self, Sub)
def __mul__(self, other):
return _create(self, other, Mul)
def __rmul__(self, other):
return _create(other, self, Mul)
def __and__(self, other):
return _create(self, other, And)
def __rand__(self, other):
return _create(other, self, And)
def __xor__(self, other):
return _create(self, other, Xor)
def __rxor__(self, other):
return _create(other, self, Xor)
def __or__(self, other):
return _create(self, other, Or)
def __ror__(self, other):
return _create(other, self, Or)
def __lt__(self, other):
return _create(self, other, LT)
def __le__(self, other):
return _create(self, other, LE)
def __eq__(self, other):
return _create(self, other, EQ)
def __ne__(self, other):
return _create(self, other, NE)
def __gt__(self, other):
return _create(other, self, LT)
def __ge__(self, other):
return _create(other, self, LE)