@@ -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
17311823def 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
17351833def 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
18411864def AddTree (* args ):
1842- return op_tree (Plus , 0 , * args )
1865+ return op_tree (Plus , 0 , None , * args )
18431866
18441867
18451868def 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
18521875def 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
18591882def Average (* args ):
0 commit comments