2011-12-22 18:35:53 -05:00
|
|
|
from migen.fhdl.structure import *
|
2012-01-08 07:56:11 -05:00
|
|
|
from migen.fhdl.structure import _Operator
|
2011-12-22 18:35:53 -05:00
|
|
|
from migen.flow.actor import *
|
2012-06-25 05:34:58 -04:00
|
|
|
from migen.flow.network import *
|
2012-01-06 08:32:00 -05:00
|
|
|
from migen.corelogic.record import *
|
2011-12-22 18:35:53 -05:00
|
|
|
from migen.corelogic import divider
|
|
|
|
|
2012-06-07 08:44:43 -04:00
|
|
|
class _SimpleBinary(CombinatorialActor):
|
2012-06-15 11:52:19 -04:00
|
|
|
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
|
2012-06-08 16:48:47 -04:00
|
|
|
super().__init__(
|
2012-02-14 07:12:43 -05:00
|
|
|
("operands", Sink, [("a", bv_op), ("b", bv_op)]),
|
|
|
|
("result", Source, [("r", bv_r)]))
|
2012-01-06 08:32:00 -05:00
|
|
|
|
2011-12-22 18:35:53 -05:00
|
|
|
def get_process_fragment(self):
|
2012-01-08 07:56:11 -05:00
|
|
|
return Fragment([
|
2012-01-15 09:09:44 -05:00
|
|
|
self.token("result").r.eq(_Operator(self.op,
|
|
|
|
[self.token("operands").a, self.token("operands").b]))
|
2012-01-08 07:56:11 -05:00
|
|
|
])
|
|
|
|
|
|
|
|
class Add(_SimpleBinary):
|
2012-06-15 11:52:19 -04:00
|
|
|
op = "+"
|
|
|
|
def get_result_bv(bv):
|
|
|
|
return BV(bv.width+1, bv.signed)
|
2012-01-08 07:56:11 -05:00
|
|
|
|
|
|
|
class Sub(_SimpleBinary):
|
2012-06-15 11:52:19 -04:00
|
|
|
op = "-"
|
|
|
|
def get_result_bv(bv):
|
|
|
|
return BV(bv.width+1, bv.signed)
|
2012-01-08 07:56:11 -05:00
|
|
|
|
|
|
|
class Mul(_SimpleBinary):
|
2012-06-15 11:52:19 -04:00
|
|
|
op = "*"
|
|
|
|
def get_result_bv(bv):
|
|
|
|
return BV(2*bv.width, bv.signed)
|
2012-01-08 07:56:11 -05:00
|
|
|
|
|
|
|
class And(_SimpleBinary):
|
2012-06-15 11:52:19 -04:00
|
|
|
op = "&"
|
|
|
|
def get_result_bv(bv):
|
|
|
|
return bv
|
2012-01-08 07:56:11 -05:00
|
|
|
|
|
|
|
class Xor(_SimpleBinary):
|
2012-06-15 11:52:19 -04:00
|
|
|
op = "^"
|
|
|
|
def get_result_bv(bv):
|
|
|
|
return bv
|
2012-01-08 07:56:11 -05:00
|
|
|
|
|
|
|
class Or(_SimpleBinary):
|
2012-06-15 11:52:19 -04:00
|
|
|
op = "|"
|
|
|
|
def get_result_bv(bv):
|
|
|
|
return bv
|
2012-01-08 07:56:11 -05:00
|
|
|
|
|
|
|
class LT(_SimpleBinary):
|
2012-06-15 11:52:19 -04:00
|
|
|
op = "<"
|
|
|
|
def get_result_bv(bv):
|
|
|
|
return BV(1)
|
2012-01-08 07:56:11 -05:00
|
|
|
|
|
|
|
class LE(_SimpleBinary):
|
2012-06-15 11:52:19 -04:00
|
|
|
op = "<="
|
|
|
|
def get_result_bv(bv):
|
|
|
|
return BV(1)
|
2012-01-08 07:56:11 -05:00
|
|
|
|
|
|
|
class EQ(_SimpleBinary):
|
2012-06-15 11:52:19 -04:00
|
|
|
op = "=="
|
|
|
|
def get_result_bv(bv):
|
|
|
|
return BV(1)
|
2012-01-08 07:56:11 -05:00
|
|
|
|
|
|
|
class NE(_SimpleBinary):
|
2012-06-15 11:52:19 -04:00
|
|
|
op = "!="
|
|
|
|
def get_result_bv(bv):
|
|
|
|
return BV(1)
|
2011-12-22 18:35:53 -05:00
|
|
|
|
2012-06-07 08:44:43 -04:00
|
|
|
class DivMod(SequentialActor):
|
2011-12-22 18:35:53 -05:00
|
|
|
def __init__(self, width):
|
2012-01-20 17:07:32 -05:00
|
|
|
self.div = divider.Divider(width)
|
2012-06-08 12:06:12 -04:00
|
|
|
super().__init__(width,
|
2012-01-15 09:09:44 -05:00
|
|
|
("operands", Sink, [("dividend", self.div.dividend_i), ("divisor", self.div.divisor_i)]),
|
|
|
|
("result", Source, [("quotient", self.div.quotient_o), ("remainder", self.div.remainder_o)]))
|
2012-01-06 08:32:00 -05:00
|
|
|
|
2011-12-22 18:35:53 -05:00
|
|
|
def get_process_fragment(self):
|
|
|
|
return self.div.get_fragment() + Fragment([self.div.start_i.eq(self.trigger)])
|
2012-06-25 05:34:58 -04:00
|
|
|
|
|
|
|
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)
|