Skip to content

Commit c29f22a

Browse files
committed
Special cares of fixed-point in AddN and Madd.
1 parent 1865310 commit c29f22a

File tree

1 file changed

+126
-103
lines changed

1 file changed

+126
-103
lines changed

veriloggen/stream/stypes.py

Lines changed: 126 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1625,12 +1625,107 @@ def _implement(self, m, seq, svalid=None, senable=None):
16251625
m.Instance(inst, self.name('lut'), ports=ports)
16261626

16271627

1628-
class TimesPlus(_SpecialOperator):
1628+
class _Delay(_UnaryOperator):
1629+
1630+
def __init__(self, right):
1631+
_UnaryOperator.__init__(self, right)
1632+
# parent value for delayed_value and previous_value
1633+
self.parent_value = None
1634+
1635+
def _set_parent_value(self, value):
1636+
self.parent_value = value
1637+
1638+
def _get_parent_value(self):
1639+
return self.parent_value
1640+
1641+
def eval(self):
1642+
return self
1643+
1644+
def _implement(self, m, seq, svalid=None, senable=None):
1645+
if self.latency != 1:
1646+
raise ValueError("Latency mismatch '%d' vs '%s'" %
1647+
(self.latency, 1))
1648+
1649+
width = self.bit_length()
1650+
signed = self.get_signed()
1651+
rdata = self.right.sig_data
1652+
1653+
data = m.Reg(self.name('data'), width, initval=0, signed=signed)
1654+
self.sig_data = data
1655+
1656+
seq(data(rdata), cond=senable)
1657+
1658+
1659+
class _Prev(_UnaryOperator):
1660+
latency = 0
1661+
1662+
def __init__(self, right):
1663+
_UnaryOperator.__init__(self, right)
1664+
# parent value for delayed_value and previous_value
1665+
self.parent_value = None
1666+
1667+
def _set_parent_value(self, value):
1668+
self.parent_value = value
1669+
1670+
def _get_parent_value(self):
1671+
return self.parent_value
1672+
1673+
def eval(self):
1674+
return self
1675+
1676+
def _implement(self, m, seq, svalid=None, senable=None):
1677+
if self.latency != 0:
1678+
raise ValueError("Latency mismatch '%d' vs '%s'" %
1679+
(self.latency, 0))
1680+
1681+
width = self.bit_length()
1682+
signed = self.get_signed()
1683+
rdata = self.right.sig_data
1684+
1685+
data = m.Reg(self.name('data'), width, initval=0, signed=signed)
1686+
self.sig_data = data
1687+
1688+
seq(data(rdata), cond=senable)
1689+
1690+
1691+
class _PlusN(_SpecialOperator):
1692+
latency = 1
1693+
1694+
def __init__(self, *vars):
1695+
_SpecialOperator.__init__(self, *vars)
1696+
1697+
for arg in self.args:
1698+
if arg.point != 0:
1699+
raise ValueError('Fixed point is not supported.')
1700+
1701+
def func(*args):
1702+
ret = args[0]
1703+
for arg in args[1:]:
1704+
ret += arg
1705+
return ret
1706+
1707+
self.op = func
1708+
1709+
def eval(self):
1710+
vars = [var.eval() for var in self.vars]
1711+
for var in vars:
1712+
if not isinstance(var, int):
1713+
return PlusN(*vars)
1714+
ret = 0
1715+
for var in vars:
1716+
ret += var
1717+
return ret
1718+
1719+
1720+
class _MulAdd(_SpecialOperator):
16291721
latency = 6 + 1
16301722

16311723
def __init__(self, a, b, c):
16321724
_SpecialOperator.__init__(self, a, b, c)
16331725

1726+
if self.a.point + self.b.point != self.c.point:
1727+
raise ValueError('Unsupported fixed point combination')
1728+
16341729
@property
16351730
def a(self):
16361731
return self.args[0]
@@ -1686,9 +1781,6 @@ def _implement(self, m, seq, svalid=None, senable=None):
16861781
bdata = self.b.sig_data
16871782
cdata = self.c.sig_data
16881783

1689-
if apoint + bpoint != cpoint:
1690-
raise ValueError('apoint + bpoint == cpoint')
1691-
16921784
odata = m.Wire(self.name('madd_odata'),
16931785
max(awidth + bwidth, cwidth), signed=signed)
16941786
odata_reg = m.Reg(self.name('madd_odata_reg'),
@@ -1729,131 +1821,62 @@ def eval(self):
17291821

17301822

17311823
def MulAdd(a, b, c):
1732-
return TimesPlus(a, b, c)
1824+
a_point = a.point if isinstance(a, _Numeric) else 0
1825+
b_point = b.point if isinstance(b, _Numeric) else 0
1826+
c_point = c.point if isinstance(c, _Numeric) else 0
1827+
if a_point + b_point != c_point:
1828+
return Plus(Times(a, b), c)
1829+
1830+
return _MulAdd(a, b, c)
17331831

17341832

17351833
def Madd(a, b, c):
1736-
return TimesPlus(a, b, c)
1834+
return MulAdd(a, b, c)
17371835

17381836

1739-
class PlusN(_SpecialOperator):
1740-
latency = 1
1837+
def op_tree(op, initval=0, latency=None, *args):
1838+
if len(args) == 1:
1839+
return args[0]
1840+
if len(args) == 0:
1841+
return initval
1842+
half_len = len(args) // 2
1843+
ret = op(op_tree(op, initval, latency, *args[:half_len]),
1844+
op_tree(op, initval, latency, *args[half_len:]))
1845+
if latency is not None:
1846+
ret.latency = latency
1847+
return ret
17411848

1742-
def __init__(self, *vars):
1743-
_SpecialOperator.__init__(self, *vars)
17441849

1745-
def func(*args):
1746-
ret = args[0]
1747-
for arg in args[1:]:
1748-
ret += arg
1850+
def PlusN(*args):
1851+
for arg in args:
1852+
if isinstance(arg, _Numeric) and arg.point != 0:
1853+
ret = op_tree(Plus, 0, 0, *args)
1854+
ret.latency = 1
17491855
return ret
17501856

1751-
self.op = func
1752-
1753-
def eval(self):
1754-
vars = [var.eval() for var in self.vars]
1755-
for var in vars:
1756-
if not isinstance(var, int):
1757-
return PlusN(*vars)
1758-
ret = 0
1759-
for var in vars:
1760-
ret += var
1761-
return ret
1762-
1857+
return _PlusN(*args)
17631858

1764-
def AddN(*vars):
1765-
return PlusN(*vars)
17661859

1767-
1768-
class _Delay(_UnaryOperator):
1769-
1770-
def __init__(self, right):
1771-
_UnaryOperator.__init__(self, right)
1772-
# parent value for delayed_value and previous_value
1773-
self.parent_value = None
1774-
1775-
def _set_parent_value(self, value):
1776-
self.parent_value = value
1777-
1778-
def _get_parent_value(self):
1779-
return self.parent_value
1780-
1781-
def eval(self):
1782-
return self
1783-
1784-
def _implement(self, m, seq, svalid=None, senable=None):
1785-
if self.latency != 1:
1786-
raise ValueError("Latency mismatch '%d' vs '%s'" %
1787-
(self.latency, 1))
1788-
1789-
width = self.bit_length()
1790-
signed = self.get_signed()
1791-
rdata = self.right.sig_data
1792-
1793-
data = m.Reg(self.name('data'), width, initval=0, signed=signed)
1794-
self.sig_data = data
1795-
1796-
seq(data(rdata), cond=senable)
1797-
1798-
1799-
class _Prev(_UnaryOperator):
1800-
latency = 0
1801-
1802-
def __init__(self, right):
1803-
_UnaryOperator.__init__(self, right)
1804-
# parent value for delayed_value and previous_value
1805-
self.parent_value = None
1806-
1807-
def _set_parent_value(self, value):
1808-
self.parent_value = value
1809-
1810-
def _get_parent_value(self):
1811-
return self.parent_value
1812-
1813-
def eval(self):
1814-
return self
1815-
1816-
def _implement(self, m, seq, svalid=None, senable=None):
1817-
if self.latency != 0:
1818-
raise ValueError("Latency mismatch '%d' vs '%s'" %
1819-
(self.latency, 0))
1820-
1821-
width = self.bit_length()
1822-
signed = self.get_signed()
1823-
rdata = self.right.sig_data
1824-
1825-
data = m.Reg(self.name('data'), width, initval=0, signed=signed)
1826-
self.sig_data = data
1827-
1828-
seq(data(rdata), cond=senable)
1829-
1830-
1831-
def op_tree(op, initval=0, *args):
1832-
if len(args) == 1:
1833-
return args[0]
1834-
if len(args) == 0:
1835-
return initval
1836-
half_len = len(args) // 2
1837-
return op(op_tree(op, initval, *args[:half_len]),
1838-
op_tree(op, initval, *args[half_len:]))
1860+
def AddN(*args):
1861+
return PlusN(*args)
18391862

18401863

18411864
def AddTree(*args):
1842-
return op_tree(Plus, 0, *args)
1865+
return op_tree(Plus, 0, None, *args)
18431866

18441867

18451868
def Max(*args):
18461869
if len(args) == 1:
18471870
return args[0]
18481871
initval = args[0]
1849-
return op_tree(lambda x, y: Mux(x > y, x, y), initval, *args)
1872+
return op_tree(lambda x, y: Mux(x > y, x, y), initval, None, *args)
18501873

18511874

18521875
def Min(*args):
18531876
if len(args) == 1:
18541877
return args[0]
18551878
initval = args[0]
1856-
return op_tree(lambda x, y: Mux(x < y, x, y), initval, *args)
1879+
return op_tree(lambda x, y: Mux(x < y, x, y), initval, None, *args)
18571880

18581881

18591882
def Average(*args):

0 commit comments

Comments
 (0)