2011-12-04 10:44:38 -05:00
|
|
|
import math
|
2011-12-18 15:26:51 -05:00
|
|
|
import inspect
|
|
|
|
import re
|
2011-12-04 10:44:38 -05:00
|
|
|
|
2012-03-06 12:33:44 -05:00
|
|
|
from migen.fhdl import tracer
|
2012-01-16 12:09:52 -05:00
|
|
|
|
2012-03-14 07:19:42 -04:00
|
|
|
def log2_int(n):
|
|
|
|
l = 1
|
|
|
|
r = 0
|
|
|
|
while l < n:
|
|
|
|
l *= 2
|
|
|
|
r += 1
|
|
|
|
if l == n:
|
|
|
|
return r
|
|
|
|
else:
|
|
|
|
raise ValueError("Not a power of 2")
|
|
|
|
|
2011-12-16 10:02:55 -05:00
|
|
|
def bits_for(n):
|
2011-12-09 07:11:34 -05:00
|
|
|
if isinstance(n, Constant):
|
2012-07-13 12:32:54 -04:00
|
|
|
return len(n)
|
2011-12-04 10:44:38 -05:00
|
|
|
else:
|
2012-03-08 14:49:24 -05:00
|
|
|
if n < 0:
|
|
|
|
return bits_for(-n) + 1
|
|
|
|
elif n == 0:
|
2011-12-09 07:11:34 -05:00
|
|
|
return 1
|
|
|
|
else:
|
|
|
|
return int(math.ceil(math.log(n+1, 2)))
|
2011-12-04 10:44:38 -05:00
|
|
|
|
|
|
|
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):
|
2011-12-04 10:44:38 -05:00
|
|
|
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
|
2011-12-04 10:44:38 -05:00
|
|
|
|
|
|
|
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
|
|
|
|
2011-12-04 10:44:38 -05:00
|
|
|
def __add__(self, other):
|
2011-12-16 15:30:14 -05:00
|
|
|
return _Operator("+", [self, other])
|
2011-12-04 10:44:38 -05:00
|
|
|
def __radd__(self, other):
|
2011-12-16 15:30:14 -05:00
|
|
|
return _Operator("+", [other, self])
|
2011-12-04 10:44:38 -05:00
|
|
|
def __sub__(self, other):
|
2011-12-16 15:30:14 -05:00
|
|
|
return _Operator("-", [self, other])
|
2011-12-04 10:44:38 -05:00
|
|
|
def __rsub__(self, other):
|
2011-12-16 15:30:14 -05:00
|
|
|
return _Operator("-", [other, self])
|
2011-12-04 10:44:38 -05:00
|
|
|
def __mul__(self, other):
|
2011-12-16 15:30:14 -05:00
|
|
|
return _Operator("*", [self, other])
|
2011-12-04 10:44:38 -05:00
|
|
|
def __rmul__(self, other):
|
2011-12-16 15:30:14 -05:00
|
|
|
return _Operator("*", [other, self])
|
2011-12-04 10:44:38 -05:00
|
|
|
def __lshift__(self, other):
|
2011-12-16 15:30:14 -05:00
|
|
|
return _Operator("<<", [self, other])
|
2011-12-04 10:44:38 -05:00
|
|
|
def __rlshift__(self, other):
|
2011-12-16 15:30:14 -05:00
|
|
|
return _Operator("<<", [other, self])
|
2011-12-04 10:44:38 -05:00
|
|
|
def __rshift__(self, other):
|
2011-12-16 15:30:14 -05:00
|
|
|
return _Operator(">>", [self, other])
|
2011-12-04 10:44:38 -05:00
|
|
|
def __rrshift__(self, other):
|
2011-12-16 15:30:14 -05:00
|
|
|
return _Operator(">>", [other, self])
|
2011-12-04 10:44:38 -05:00
|
|
|
def __and__(self, other):
|
2011-12-16 15:30:14 -05:00
|
|
|
return _Operator("&", [self, other])
|
2011-12-04 10:44:38 -05:00
|
|
|
def __rand__(self, other):
|
2011-12-16 15:30:14 -05:00
|
|
|
return _Operator("&", [other, self])
|
2011-12-04 10:44:38 -05:00
|
|
|
def __xor__(self, other):
|
2011-12-16 15:30:14 -05:00
|
|
|
return _Operator("^", [self, other])
|
2011-12-04 10:44:38 -05:00
|
|
|
def __rxor__(self, other):
|
2011-12-16 15:30:14 -05:00
|
|
|
return _Operator("^", [other, self])
|
2011-12-04 10:44:38 -05:00
|
|
|
def __or__(self, other):
|
2011-12-16 15:30:14 -05:00
|
|
|
return _Operator("|", [self, other])
|
2011-12-04 10:44:38 -05:00
|
|
|
def __ror__(self, other):
|
2011-12-16 15:30:14 -05:00
|
|
|
return _Operator("|", [other, self])
|
2011-12-04 10:44:38 -05:00
|
|
|
|
|
|
|
def __lt__(self, other):
|
2011-12-16 15:30:14 -05:00
|
|
|
return _Operator("<", [self, other])
|
2011-12-04 10:44:38 -05:00
|
|
|
def __le__(self, other):
|
2011-12-16 15:30:14 -05:00
|
|
|
return _Operator("<=", [self, other])
|
2011-12-04 10:44:38 -05:00
|
|
|
def __eq__(self, other):
|
2011-12-16 15:30:14 -05:00
|
|
|
return _Operator("==", [self, other])
|
2011-12-04 10:44:38 -05:00
|
|
|
def __ne__(self, other):
|
2011-12-16 15:30:14 -05:00
|
|
|
return _Operator("!=", [self, other])
|
2011-12-04 10:44:38 -05:00
|
|
|
def __gt__(self, other):
|
2011-12-16 15:30:14 -05:00
|
|
|
return _Operator(">", [self, other])
|
2011-12-04 10:44:38 -05:00
|
|
|
def __ge__(self, other):
|
2011-12-16 15:30:14 -05:00
|
|
|
return _Operator(">=", [self, other])
|
2011-12-04 10:44:38 -05:00
|
|
|
|
|
|
|
|
|
|
|
def __getitem__(self, key):
|
|
|
|
if isinstance(key, int):
|
2011-12-21 16:57:07 -05:00
|
|
|
return _Slice(self, key, key+1)
|
2011-12-04 10:44:38 -05:00
|
|
|
elif isinstance(key, slice):
|
|
|
|
start = key.start or 0
|
2012-07-13 12:32:54 -04:00
|
|
|
stop = key.stop or len(self)
|
|
|
|
if stop > len(self):
|
|
|
|
stop = len(self)
|
2011-12-04 10:44:38 -05:00
|
|
|
if key.step != None:
|
|
|
|
raise KeyError
|
2011-12-21 16:57:07 -05:00
|
|
|
return _Slice(self, start, stop)
|
2011-12-04 10:44:38 -05:00
|
|
|
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-04 10:44:38 -05:00
|
|
|
|
2011-12-16 15:30:14 -05:00
|
|
|
class _Operator(Value):
|
2011-12-04 10:44:38 -05:00
|
|
|
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):
|
2011-12-04 10:44:38 -05:00
|
|
|
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
|
|
|
|
|
2011-12-04 10:44:38 -05:00
|
|
|
class Constant(Value):
|
|
|
|
def __init__(self, n, bv=None):
|
2012-03-08 14:49:24 -05:00
|
|
|
self.bv = bv or BV(bits_for(n), n < 0)
|
2011-12-04 10:44:38 -05:00
|
|
|
self.n = n
|
2011-12-09 07:11:34 -05:00
|
|
|
|
2012-07-13 12:16:50 -04:00
|
|
|
def __len__(self):
|
|
|
|
return self.bv.width
|
|
|
|
|
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
|
2011-12-04 10:44:38 -05:00
|
|
|
|
2012-02-05 13:32:11 -05:00
|
|
|
def binc(x, signed=False):
|
|
|
|
return Constant(int(x, 2), BV(len(x), signed))
|
|
|
|
|
2011-12-04 10:44:38 -05:00
|
|
|
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))
|
2011-12-04 10:44:38 -05:00
|
|
|
self.bv = bv
|
|
|
|
self.variable = variable
|
|
|
|
self.reset = Constant(reset, bv)
|
2012-01-16 12:09:52 -05:00
|
|
|
self.name_override = name_override
|
2012-03-06 12:33:44 -05:00
|
|
|
self.backtrace = tracer.trace_back(name)
|
2012-04-08 12:06:22 -04:00
|
|
|
|
|
|
|
def __len__(self):
|
|
|
|
return self.bv.width
|
2011-12-04 10:44:38 -05:00
|
|
|
|
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") + ">"
|
2011-12-04 10:44:38 -05:00
|
|
|
|
|
|
|
# statements
|
|
|
|
|
2011-12-21 16:57:07 -05:00
|
|
|
class _Assign:
|
2011-12-04 10:44:38 -05:00
|
|
|
def __init__(self, l, r):
|
|
|
|
self.l = l
|
|
|
|
self.r = _cst(r)
|
|
|
|
|
2011-12-16 15:30:14 -05:00
|
|
|
class If:
|
|
|
|
def __init__(self, cond, *t):
|
|
|
|
self.cond = cond
|
2012-07-13 11:07:56 -04:00
|
|
|
self.t = list(t)
|
|
|
|
self.f = []
|
2011-12-16 15:30:14 -05:00
|
|
|
|
|
|
|
def Else(self, *f):
|
2012-07-13 11:07:56 -04:00
|
|
|
_insert_else(self, list(f))
|
2011-12-16 15:30:14 -05:00
|
|
|
return self
|
|
|
|
|
|
|
|
def Elif(self, cond, *t):
|
2012-07-13 11:07:56 -04:00
|
|
|
_insert_else(self, [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
|
2012-07-13 11:07:56 -04:00
|
|
|
while o.f:
|
|
|
|
assert(len(o.f) == 1)
|
|
|
|
assert(isinstance(o.f[0], If))
|
|
|
|
o = o.f[0]
|
2011-12-17 14:31:42 -05:00
|
|
|
o.f = clause
|
|
|
|
|
2011-12-16 15:30:14 -05:00
|
|
|
class Default:
|
|
|
|
pass
|
2011-12-04 10:44:38 -05:00
|
|
|
|
|
|
|
class Case:
|
2011-12-16 15:30:14 -05:00
|
|
|
def __init__(self, test, *cases):
|
2011-12-04 10:44:38 -05:00
|
|
|
self.test = test
|
2012-07-13 11:07:56 -04:00
|
|
|
self.cases = [(c[0], list(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
|
2012-07-13 11:07:56 -04:00
|
|
|
self.default = list(c[1:])
|
2011-12-16 15:30:14 -05:00
|
|
|
if self.default is None:
|
2012-07-13 11:07:56 -04:00
|
|
|
self.default = []
|
2011-12-04 10:44:38 -05:00
|
|
|
|
2012-07-09 09:16:38 -04:00
|
|
|
# arrays
|
|
|
|
|
|
|
|
class _ArrayProxy(Value):
|
|
|
|
def __init__(self, choices, key):
|
|
|
|
self.choices = choices
|
|
|
|
self.key = key
|
|
|
|
|
|
|
|
def __getattr__(self, attr):
|
|
|
|
return _ArrayProxy([getattr(choice, attr) for choice in self.choices],
|
|
|
|
self.key)
|
|
|
|
|
|
|
|
def __getitem__(self, key):
|
|
|
|
return _ArrayProxy([choice.__getitem__(key) for choice in self.choices],
|
|
|
|
self.key)
|
|
|
|
|
|
|
|
class Array(list):
|
|
|
|
def __getitem__(self, key):
|
|
|
|
if isinstance(key, Value):
|
|
|
|
return _ArrayProxy(self, key)
|
|
|
|
else:
|
|
|
|
return super().__getitem__(key)
|
|
|
|
|
|
|
|
# extras
|
2011-12-04 10:44:38 -05:00
|
|
|
|
2011-12-08 10:35:32 -05:00
|
|
|
class Instance:
|
2012-02-16 12:34:32 -05:00
|
|
|
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):
|
2012-01-28 05:39:28 -05:00
|
|
|
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))
|
2012-02-16 12:34:32 -05:00
|
|
|
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
|
|
|
|
|
2012-07-09 09:16:38 -04:00
|
|
|
#
|
|
|
|
|
2011-12-04 10:44:38 -05:00
|
|
|
class Fragment:
|
2012-04-02 13:21:43 -04:00
|
|
|
def __init__(self, comb=None, sync=None, instances=None, memories=None, sim=None):
|
2011-12-11 14:17:29 -05:00
|
|
|
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 = []
|
2012-03-06 07:58:22 -05:00
|
|
|
if sim is None: sim = []
|
2012-07-13 11:07:56 -04:00
|
|
|
self.comb = comb
|
|
|
|
self.sync = sync
|
2011-12-08 10:35:32 -05:00
|
|
|
self.instances = instances
|
2012-01-27 10:53:34 -05:00
|
|
|
self.memories = memories
|
2012-03-06 07:58:22 -05:00
|
|
|
self.sim = sim
|
2011-12-04 10:44:38 -05:00
|
|
|
|
2011-12-05 11:43:56 -05:00
|
|
|
def __add__(self, other):
|
2012-07-13 11:07:56 -04:00
|
|
|
return Fragment(self.comb + other.comb,
|
|
|
|
self.sync + other.sync,
|
2011-12-10 14:25:24 -05:00
|
|
|
self.instances + other.instances,
|
2012-01-27 10:53:34 -05:00
|
|
|
self.memories + other.memories,
|
2012-03-06 07:58:22 -05:00
|
|
|
self.sim + other.sim)
|
|
|
|
|
2012-03-06 13:29:39 -05:00
|
|
|
def call_sim(self, simulator):
|
2012-03-06 07:58:22 -05:00
|
|
|
for s in self.sim:
|
2012-03-06 13:43:59 -05:00
|
|
|
if simulator.cycle_counter >= 0 or (hasattr(s, "initialize") and s.initialize):
|
|
|
|
s(simulator)
|