Initial import, FHDL basic structure, divider example
This commit is contained in:
commit
499b95a519
|
@ -0,0 +1,2 @@
|
|||
__pycache__
|
||||
*.pyc
|
|
@ -0,0 +1,207 @@
|
|||
import math
|
||||
|
||||
def BitsFor(n):
|
||||
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
|
||||
|
||||
def __str__(self):
|
||||
r = str(self.width) + "'"
|
||||
if self.signed:
|
||||
r += "s"
|
||||
r += "d"
|
||||
return r
|
||||
|
||||
class Value:
|
||||
def __init__(self, bv):
|
||||
self.bv = bv
|
||||
|
||||
def __add__(self, other):
|
||||
return Operator("+", [self, other])
|
||||
def __radd__(self, other):
|
||||
return Operator("+", [other, self])
|
||||
def __sub__(self, other):
|
||||
return Operator("-", [self, other])
|
||||
def __rsub__(self, other):
|
||||
return Operator("-", [other, self])
|
||||
def __mul__(self, other):
|
||||
return Operator("*", [self, other])
|
||||
def __rmul__(self, other):
|
||||
return Operator("*", [other, self])
|
||||
def __lshift__(self, other):
|
||||
return Operator("<<", [self, other])
|
||||
def __rlshift__(self, other):
|
||||
return Operator("<<", [other, self])
|
||||
def __rshift__(self, other):
|
||||
return Operator(">>", [self, other])
|
||||
def __rrshift__(self, other):
|
||||
return Operator(">>", [other, self])
|
||||
def __and__(self, other):
|
||||
return Operator("&", [self, other])
|
||||
def __rand__(self, other):
|
||||
return Operator("&", [other, self])
|
||||
def __xor__(self, other):
|
||||
return Operator("^", [self, other])
|
||||
def __rxor__(self, other):
|
||||
return Operator("^", [other, self])
|
||||
def __or__(self, other):
|
||||
return Operator("|", [self, other])
|
||||
def __ror__(self, other):
|
||||
return Operator("|", [other, self])
|
||||
|
||||
def __lt__(self, other):
|
||||
return Operator("<", [self, other])
|
||||
def __le__(self, other):
|
||||
return Operator("<=", [self, other])
|
||||
def __eq__(self, other):
|
||||
return Operator("==", [self, other])
|
||||
def __ne__(self, other):
|
||||
return Operator("!=", [self, other])
|
||||
def __gt__(self, other):
|
||||
return Operator(">", [self, other])
|
||||
def __ge__(self, other):
|
||||
return Operator(">=", [self, other])
|
||||
|
||||
|
||||
def __getitem__(self, key):
|
||||
if isinstance(key, int):
|
||||
return Slice(self, key, key+1)
|
||||
elif isinstance(key, slice):
|
||||
start = key.start or 0
|
||||
stop = key.stop or self.bv.width
|
||||
if key.step != None:
|
||||
raise KeyError
|
||||
return Slice(self, start, stop)
|
||||
else:
|
||||
raise KeyError
|
||||
|
||||
class Operator(Value):
|
||||
def __init__(self, op, operands):
|
||||
self.op = op
|
||||
self.operands = list(map(_cst, operands))
|
||||
|
||||
def __str__(self):
|
||||
arity = len(self.operands)
|
||||
if arity == 1:
|
||||
r = self.op + str(self.operands[0])
|
||||
elif arity == 2:
|
||||
r = str(self.operands[0]) + " " + self.op + " " + str(self.operands[1])
|
||||
else:
|
||||
r = self.op + "(" + ", ".join(map(str, self.operands)) + ")"
|
||||
return "(" + r + ")"
|
||||
|
||||
class Slice(Value):
|
||||
def __init__(self, value, start, stop):
|
||||
self.value = value
|
||||
self.start = start
|
||||
self.stop = stop
|
||||
|
||||
def __str__(self):
|
||||
if self.start + 1 == self.stop:
|
||||
sr = "[" + str(self.start) + "]"
|
||||
else:
|
||||
sr = "[" + str(self.start) + ":" + str(self.stop) + "]"
|
||||
return str(self.value) + sr
|
||||
|
||||
class Cat(Value):
|
||||
def __init__(self, *args):
|
||||
self.l = list(map(_cst, args))
|
||||
|
||||
def __str__(self):
|
||||
return "{" + ", ".join(map(str, self.l)) + "}"
|
||||
|
||||
class Constant(Value):
|
||||
def __init__(self, n, bv=None):
|
||||
if bv == None:
|
||||
Value.__init__(self, BV(BitsFor(n)))
|
||||
else:
|
||||
Value.__init__(self, bv)
|
||||
self.n = n
|
||||
|
||||
def __str__(self):
|
||||
if self.n >= 0:
|
||||
return str(self.bv) + str(self.n)
|
||||
else:
|
||||
return "-" + str(self.bv) + str(-self.n)
|
||||
|
||||
def _cst(x):
|
||||
if isinstance(x, int):
|
||||
return Constant(x)
|
||||
else:
|
||||
return x
|
||||
|
||||
class Signal(Value):
|
||||
def __init__(self, bv=BV(), name="anonymous", variable=False, reset=0):
|
||||
Value.__init__(self, bv)
|
||||
self.bv = bv
|
||||
self.variable = variable
|
||||
self.name = name
|
||||
self.reset = Constant(reset, bv)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def Declare(parent, name, bv=BV(), variable=False, reset=0):
|
||||
setattr(parent, name, Signal(bv, parent.__class__.__name__+"_"+name, variable, reset))
|
||||
|
||||
# statements
|
||||
|
||||
class Assign:
|
||||
def __init__(self, l, r):
|
||||
self.l = l
|
||||
self.r = _cst(r)
|
||||
|
||||
def __str__(self):
|
||||
return str(self.l) + " = " + str(self.r)
|
||||
|
||||
class StatementList:
|
||||
def __init__(self, l=[]):
|
||||
self.l = l
|
||||
|
||||
def __str__(self):
|
||||
return "\n".join(map(str, self.l))
|
||||
|
||||
def _sl(x):
|
||||
if isinstance(x, list):
|
||||
return StatementList(x)
|
||||
else:
|
||||
return x
|
||||
|
||||
def _indent(s):
|
||||
if s:
|
||||
return "\t" + s.replace("\n", "\n\t")
|
||||
else:
|
||||
return ""
|
||||
|
||||
class If:
|
||||
def __init__(self, cond, t, f=StatementList()):
|
||||
self.cond = cond
|
||||
self.t = _sl(t)
|
||||
self.f = _sl(f)
|
||||
|
||||
def __str__(self):
|
||||
r = "if " + str(self.cond) + ":\n" + _indent(str(self.t))
|
||||
if self.f.l:
|
||||
r += "\nelse:\n" + _indent(str(self.f))
|
||||
return r
|
||||
|
||||
class Case:
|
||||
def __init__(self, test, cases=[]):
|
||||
self.test = test
|
||||
self.cases = cases
|
||||
|
||||
#
|
||||
|
||||
class Fragment:
|
||||
def __init__(self, comb=StatementList(), sync=StatementList()):
|
||||
self.comb = _sl(comb)
|
||||
self.sync = _sl(sync)
|
||||
|
||||
def __str__(self):
|
||||
return "Comb:\n" + _indent(str(self.comb)) + "\nSync:\n" + _indent(str(self.sync))
|
|
@ -0,0 +1,48 @@
|
|||
from migen.fhdl import structure as f
|
||||
from functools import partial
|
||||
|
||||
class Divider:
|
||||
def __init__(self, w):
|
||||
self.w = w
|
||||
|
||||
d = partial(f.Declare, self)
|
||||
|
||||
d("start_i")
|
||||
d("dividend_i", f.BV(w))
|
||||
d("divisor_i", f.BV(w))
|
||||
d("ready_o")
|
||||
d("quotient_o", f.BV(w))
|
||||
d("remainder_o", f.BV(w))
|
||||
|
||||
d("_qr", f.BV(2*w))
|
||||
d("_counter", f.BV(f.BitsFor(w)))
|
||||
d("_divisor_r", f.BV(w))
|
||||
d("_diff", f.BV(w+1))
|
||||
|
||||
def GetFragment(self):
|
||||
a = f.Assign
|
||||
comb = [
|
||||
a(self.quotient_o, self._qr[:self.w]),
|
||||
a(self.remainder_o, self._qr[self.w:]),
|
||||
a(self.ready_o, self._counter == f.Constant(0, self._counter.bv)),
|
||||
a(self._diff, self.remainder_o - self._divisor_r)
|
||||
]
|
||||
sync = [
|
||||
f.If(self.start_i == 1, [
|
||||
a(self._counter, self.w),
|
||||
a(self._qr, self.dividend_i),
|
||||
a(self._divisor_r, self.divisor_i)
|
||||
], [
|
||||
f.If(self.ready_o == 0, [
|
||||
f.If(self._diff[self.w] == 1,
|
||||
[a(self._qr, f.Cat(0, self._qr[:2*self.w-1]))],
|
||||
[a(self._qr, f.Cat(1, self._qr[:self.w-1], self._diff[:self.w]))]),
|
||||
a(self._counter, self._counter - f.Constant(1, self._counter.bv)),
|
||||
])
|
||||
])
|
||||
]
|
||||
return f.Fragment(comb, sync)
|
||||
|
||||
d = Divider(32)
|
||||
f = d.GetFragment()
|
||||
print(f)
|
Loading…
Reference in New Issue