litex/migen/fhdl/structure.py

275 lines
6.3 KiB
Python
Raw Normal View History

import math
import inspect
import re
2012-01-16 12:09:52 -05:00
from migen.fhdl import namer
2011-12-16 10:02:55 -05:00
def bits_for(n):
2011-12-09 07:11:34 -05:00
if isinstance(n, Constant):
return n.bv.width
else:
2011-12-09 07:11:34 -05:00
if n == 0:
return 1
else:
return int(math.ceil(math.log(n+1, 2)))
class BV:
def __init__(self, width=1, signed=False):
self.width = width
self.signed = signed
2011-12-09 07:11:34 -05:00
def __repr__(self):
r = str(self.width) + "'"
if self.signed:
r += "s"
r += "d"
return r
2012-01-06 17:00:23 -05:00
def __eq__(self, other):
return self.width == other.width and self.signed == other.signed
class Value:
2011-12-08 15:15:44 -05:00
def __invert__(self):
2011-12-16 15:30:14 -05:00
return _Operator("~", [self])
2011-12-08 15:15:44 -05:00
def __add__(self, other):
2011-12-16 15:30:14 -05:00
return _Operator("+", [self, other])
def __radd__(self, other):
2011-12-16 15:30:14 -05:00
return _Operator("+", [other, self])
def __sub__(self, other):
2011-12-16 15:30:14 -05:00
return _Operator("-", [self, other])
def __rsub__(self, other):
2011-12-16 15:30:14 -05:00
return _Operator("-", [other, self])
def __mul__(self, other):
2011-12-16 15:30:14 -05:00
return _Operator("*", [self, other])
def __rmul__(self, other):
2011-12-16 15:30:14 -05:00
return _Operator("*", [other, self])
def __lshift__(self, other):
2011-12-16 15:30:14 -05:00
return _Operator("<<", [self, other])
def __rlshift__(self, other):
2011-12-16 15:30:14 -05:00
return _Operator("<<", [other, self])
def __rshift__(self, other):
2011-12-16 15:30:14 -05:00
return _Operator(">>", [self, other])
def __rrshift__(self, other):
2011-12-16 15:30:14 -05:00
return _Operator(">>", [other, self])
def __and__(self, other):
2011-12-16 15:30:14 -05:00
return _Operator("&", [self, other])
def __rand__(self, other):
2011-12-16 15:30:14 -05:00
return _Operator("&", [other, self])
def __xor__(self, other):
2011-12-16 15:30:14 -05:00
return _Operator("^", [self, other])
def __rxor__(self, other):
2011-12-16 15:30:14 -05:00
return _Operator("^", [other, self])
def __or__(self, other):
2011-12-16 15:30:14 -05:00
return _Operator("|", [self, other])
def __ror__(self, other):
2011-12-16 15:30:14 -05:00
return _Operator("|", [other, self])
def __lt__(self, other):
2011-12-16 15:30:14 -05:00
return _Operator("<", [self, other])
def __le__(self, other):
2011-12-16 15:30:14 -05:00
return _Operator("<=", [self, other])
def __eq__(self, other):
2011-12-16 15:30:14 -05:00
return _Operator("==", [self, other])
def __ne__(self, other):
2011-12-16 15:30:14 -05:00
return _Operator("!=", [self, other])
def __gt__(self, other):
2011-12-16 15:30:14 -05:00
return _Operator(">", [self, other])
def __ge__(self, other):
2011-12-16 15:30:14 -05:00
return _Operator(">=", [self, other])
def __getitem__(self, key):
if isinstance(key, int):
2011-12-21 16:57:07 -05:00
return _Slice(self, key, key+1)
elif isinstance(key, slice):
start = key.start or 0
stop = key.stop or self.bv.width
2011-12-07 16:21:30 -05:00
if stop > self.bv.width:
stop = self.bv.width
if key.step != None:
raise KeyError
2011-12-21 16:57:07 -05:00
return _Slice(self, start, stop)
else:
raise KeyError
2011-12-16 15:30:14 -05:00
def eq(self, r):
2011-12-21 16:57:07 -05:00
return _Assign(self, r)
2011-12-16 15:30:14 -05:00
class _Operator(Value):
def __init__(self, op, operands):
self.op = op
self.operands = list(map(_cst, operands))
2011-12-21 16:57:07 -05:00
class _Slice(Value):
def __init__(self, value, start, stop):
self.value = value
self.start = start
self.stop = stop
class Cat(Value):
def __init__(self, *args):
self.l = list(map(_cst, args))
2011-12-09 07:11:34 -05:00
class Replicate(Value):
def __init__(self, v, n):
2011-12-22 18:35:13 -05:00
self.v = _cst(v)
2011-12-09 07:11:34 -05:00
self.n = n
class Constant(Value):
def __init__(self, n, bv=None):
2011-12-16 10:02:55 -05:00
self.bv = bv or BV(bits_for(n))
self.n = n
2011-12-09 07:11:34 -05:00
def __repr__(self):
return str(self.bv) + str(self.n)
2012-01-07 06:29:47 -05:00
def __eq__(self, other):
return self.bv == other.bv and self.n == other.n
def binc(x, signed=False):
return Constant(int(x, 2), BV(len(x), signed))
def _cst(x):
if isinstance(x, int):
return Constant(x)
else:
return x
class Signal(Value):
2012-01-16 12:09:52 -05:00
def __init__(self, bv=BV(), name=None, variable=False, reset=0, name_override=None):
2012-02-17 17:50:54 -05:00
assert(isinstance(bv, BV))
self.bv = bv
self.variable = variable
self.reset = Constant(reset, bv)
2012-01-16 12:09:52 -05:00
self.name_override = name_override
self.backtrace = namer.trace_back(name)
2011-12-04 16:26:32 -05:00
def __hash__(self):
return id(self)
2012-01-06 05:20:33 -05:00
def __repr__(self):
2012-01-16 12:42:55 -05:00
return "<Signal " + (self.backtrace[-1][1] or "anonymous") + ">"
# statements
2011-12-21 16:57:07 -05:00
class _Assign:
def __init__(self, l, r):
self.l = l
self.r = _cst(r)
2011-12-21 16:57:07 -05:00
class _StatementList:
def __init__(self, l=None):
if l is None: l = []
self.l = l
2011-12-16 15:30:14 -05:00
class If:
def __init__(self, cond, *t):
self.cond = cond
2011-12-21 16:57:07 -05:00
self.t = _StatementList(t)
self.f = _StatementList()
2011-12-16 15:30:14 -05:00
def Else(self, *f):
2011-12-21 16:57:07 -05:00
_insert_else(self, _StatementList(f))
2011-12-16 15:30:14 -05:00
return self
def Elif(self, cond, *t):
2011-12-21 16:57:07 -05:00
_insert_else(self, _StatementList([If(cond, *t)]))
2011-12-16 15:30:14 -05:00
return self
2011-12-17 14:31:42 -05:00
def _insert_else(obj, clause):
o = obj
while o.f.l:
assert(len(o.f.l) == 1)
assert(isinstance(o.f.l[0], If))
o = o.f.l[0]
o.f = clause
def _sl(x):
if isinstance(x, list):
2011-12-21 16:57:07 -05:00
return _StatementList(x)
else:
return x
2011-12-16 15:30:14 -05:00
class Default:
pass
class Case:
2011-12-16 15:30:14 -05:00
def __init__(self, test, *cases):
self.test = test
2011-12-21 16:57:07 -05:00
self.cases = [(c[0], _StatementList(c[1:])) for c in cases if not isinstance(c[0], Default)]
2011-12-16 15:30:14 -05:00
self.default = None
for c in cases:
if isinstance(c[0], Default):
if self.default is not None:
raise ValueError
2011-12-21 16:57:07 -05:00
self.default = _StatementList(c[1:])
2011-12-16 15:30:14 -05:00
if self.default is None:
2011-12-21 16:57:07 -05:00
self.default = _StatementList()
#
2011-12-08 10:35:32 -05:00
class Instance:
def __init__(self, of, outs=[], ins=[], inouts=[], parameters=[], clkport="", rstport="", name=""):
2011-12-08 10:35:32 -05:00
self.of = of
if name:
2012-01-20 16:36:17 -05:00
self.name_override = name
2011-12-08 10:35:32 -05:00
else:
2012-01-20 16:36:17 -05:00
self.name_override = of
2011-12-08 12:56:14 -05:00
def process_io(x):
if isinstance(x[1], Signal):
return x # override
elif isinstance(x[1], BV):
return (x[0], Signal(x[1], x[0]))
2011-12-08 12:56:14 -05:00
else:
raise TypeError
self.outs = dict(map(process_io, outs))
self.ins = dict(map(process_io, ins))
self.inouts = dict(map(process_io, inouts))
2011-12-08 10:35:32 -05:00
self.parameters = parameters
self.clkport = clkport
self.rstport = rstport
def __hash__(self):
return id(self)
2012-01-27 14:22:17 -05:00
(READ_FIRST, WRITE_FIRST, NO_CHANGE) = range(3)
2012-01-27 10:53:34 -05:00
class MemoryPort:
2012-01-27 14:22:17 -05:00
def __init__(self, adr, dat_r, we=None, dat_w=None,
2012-01-27 15:35:58 -05:00
async_read=False, re=None, we_granularity=0, mode=WRITE_FIRST):
2012-01-27 10:53:34 -05:00
self.adr = adr
self.dat_r = dat_r
self.we = we
self.dat_w = dat_w
self.async_read = async_read
self.re = re
self.we_granularity = we_granularity
2012-01-27 14:22:17 -05:00
self.mode = mode
2012-01-27 10:53:34 -05:00
class Memory:
def __init__(self, width, depth, *ports, init=None):
self.width = width
self.depth = depth
self.ports = ports
self.init = init
class Fragment:
2012-01-27 10:53:34 -05:00
def __init__(self, comb=None, sync=None, instances=None, memories=None, pads=set()):
if comb is None: comb = []
if sync is None: sync = []
if instances is None: instances = []
2012-01-27 10:53:34 -05:00
if memories is None: memories = []
self.comb = _sl(comb)
self.sync = _sl(sync)
2011-12-08 10:35:32 -05:00
self.instances = instances
2012-01-27 10:53:34 -05:00
self.memories = memories
2011-12-10 14:25:24 -05:00
self.pads = pads
2011-12-05 11:43:56 -05:00
def __add__(self, other):
2011-12-10 14:25:24 -05:00
return Fragment(self.comb.l + other.comb.l,
self.sync.l + other.sync.l,
self.instances + other.instances,
2012-01-27 10:53:34 -05:00
self.memories + other.memories,
2011-12-10 14:25:24 -05:00
self.pads | other.pads)