myhdl-list Mailing List for MyHDL (Page 110)
Brought to you by:
jandecaluwe
You can subscribe to this list here.
2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(14) |
Nov
(4) |
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
(1) |
Feb
(10) |
Mar
(19) |
Apr
(14) |
May
(1) |
Jun
(4) |
Jul
(10) |
Aug
|
Sep
(2) |
Oct
(7) |
Nov
(17) |
Dec
(12) |
2005 |
Jan
(6) |
Feb
(10) |
Mar
(17) |
Apr
(10) |
May
(9) |
Jun
(5) |
Jul
(26) |
Aug
(34) |
Sep
(10) |
Oct
(38) |
Nov
(71) |
Dec
(74) |
2006 |
Jan
(20) |
Feb
(20) |
Mar
(7) |
Apr
(2) |
May
(13) |
Jun
|
Jul
|
Aug
(4) |
Sep
(37) |
Oct
(43) |
Nov
(30) |
Dec
(33) |
2007 |
Jan
(3) |
Feb
|
Mar
|
Apr
|
May
(30) |
Jun
(9) |
Jul
(1) |
Aug
|
Sep
(8) |
Oct
(13) |
Nov
|
Dec
(4) |
2008 |
Jan
(13) |
Feb
(46) |
Mar
(25) |
Apr
(7) |
May
(20) |
Jun
(73) |
Jul
(38) |
Aug
(47) |
Sep
(24) |
Oct
(18) |
Nov
(9) |
Dec
(36) |
2009 |
Jan
(31) |
Feb
(24) |
Mar
(73) |
Apr
(13) |
May
(47) |
Jun
(28) |
Jul
(36) |
Aug
(2) |
Sep
(5) |
Oct
(8) |
Nov
(16) |
Dec
(29) |
2010 |
Jan
(34) |
Feb
(18) |
Mar
(18) |
Apr
(5) |
May
|
Jun
(24) |
Jul
(53) |
Aug
(3) |
Sep
(18) |
Oct
(33) |
Nov
(19) |
Dec
(15) |
2011 |
Jan
(9) |
Feb
(4) |
Mar
(39) |
Apr
(213) |
May
(86) |
Jun
(46) |
Jul
(22) |
Aug
(11) |
Sep
(78) |
Oct
(59) |
Nov
(38) |
Dec
(24) |
2012 |
Jan
(9) |
Feb
(22) |
Mar
(89) |
Apr
(55) |
May
(222) |
Jun
(86) |
Jul
(57) |
Aug
(32) |
Sep
(49) |
Oct
(69) |
Nov
(12) |
Dec
(35) |
2013 |
Jan
(67) |
Feb
(39) |
Mar
(18) |
Apr
(42) |
May
(79) |
Jun
(1) |
Jul
(19) |
Aug
(18) |
Sep
(54) |
Oct
(79) |
Nov
(9) |
Dec
(26) |
2014 |
Jan
(30) |
Feb
(44) |
Mar
(26) |
Apr
(11) |
May
(39) |
Jun
(1) |
Jul
(89) |
Aug
(15) |
Sep
(7) |
Oct
(6) |
Nov
(20) |
Dec
(27) |
2015 |
Jan
(107) |
Feb
(106) |
Mar
(130) |
Apr
(90) |
May
(147) |
Jun
(28) |
Jul
(53) |
Aug
(16) |
Sep
(23) |
Oct
(7) |
Nov
|
Dec
(16) |
2016 |
Jan
(86) |
Feb
(41) |
Mar
(38) |
Apr
(31) |
May
(37) |
Jun
(11) |
Jul
(1) |
Aug
(1) |
Sep
(3) |
Oct
(1) |
Nov
(5) |
Dec
(3) |
2017 |
Jan
|
Feb
(4) |
Mar
(2) |
Apr
(2) |
May
|
Jun
(3) |
Jul
(2) |
Aug
(2) |
Sep
(1) |
Oct
(2) |
Nov
(1) |
Dec
(1) |
2018 |
Jan
(1) |
Feb
(1) |
Mar
(7) |
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2019 |
Jan
(1) |
Feb
|
Mar
(2) |
Apr
(1) |
May
(1) |
Jun
(2) |
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
(3) |
Dec
|
2020 |
Jan
(1) |
Feb
(2) |
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
(1) |
Aug
(1) |
Sep
(1) |
Oct
|
Nov
|
Dec
(3) |
2021 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
(2) |
Aug
|
Sep
|
Oct
|
Nov
(12) |
Dec
(11) |
2022 |
Jan
(7) |
Feb
(2) |
Mar
(1) |
Apr
|
May
|
Jun
(1) |
Jul
(3) |
Aug
(2) |
Sep
(1) |
Oct
|
Nov
|
Dec
(1) |
2023 |
Jan
|
Feb
(1) |
Mar
(1) |
Apr
(3) |
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
(1) |
2024 |
Jan
(1) |
Feb
(2) |
Mar
(4) |
Apr
(2) |
May
(2) |
Jun
(1) |
Jul
|
Aug
(1) |
Sep
(1) |
Oct
|
Nov
|
Dec
(2) |
2025 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Sébastien B. <seb...@mi...> - 2011-09-12 12:26:38
|
On 09/12/2011 06:39 AM, Christopher Felton wrote: >But your patch proposes an alternative method to create > constant drivers, correct? > > Your proposed changes would support something like: > > def testc(y): > @always_comb > def rtl(): > y.next = 5 > > return rtl Yes. |
From: Jan D. <ja...@ja...> - 2011-09-12 08:18:15
|
On 09/11/2011 11:06 PM, Sébastien Bourdeauducq wrote: > Hi, > > why isn't it possible to use __dict__ on signal objects? How to get > equivalent functionality? Signal and intbv have __slots__ defined. Whether that's a good idea or not, for either one, in the specific case of MyHDL, is a question that warrants thorough analysis and on which I don't have a clear-cut answer. -- Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com Python as a HDL: http://www.myhdl.org VHDL development, the modern way: http://www.sigasi.com World-class digital design: http://www.easics.com |
From: Christopher F. <chr...@gm...> - 2011-09-12 05:06:41
|
> > Yes, I agree! Using the numerical packages in Python is much easier. > To your point I can open a Python shell and do the following: > >> from numpy import * > >> X = random.rand(3,3) > >> matrix(X) * matrix(X[1,:]).transpose() > >> > matrix([[ 0.53398746], > [ 0.96773496], > [ 1.01327792]]) > > #... expand to myhdl ... > >> sX = Signal(matrix(X)) > >> sY = Signal(matrix(X[1,:].transpose()) > >> sX.next = sX * sY > #... > Doh, awhile ago I posted the above incorrect example. I had done something similar to the above in the past and forgot I added a small wrapper to work with numpy arrays. The above does not function out of the box, when the update function is called it will fail when trying to determine if the current != next for numpy arrays. Below is the wrapper I used. #------------------------------------------------------------------------------- # BlockSignal : #------------------------------------------------------------------------------- class BlockSignal(SignalType): __slots__ = ("parent",) + SignalType.__slots__ def __init__(self, val=None): # @todo check type, always should be an ndarray type! self.parent = None # Call the myhdl.Signal constructor SignalType.__init__(self, val) # For the DSP simulations / executions going to make a copy # of the numpy.ndarray. The update functions will just swap # buffers instead of copying (copy was actually done in the next # assign). self._next = copy(self._val) def _update(self): # @todo check no waiters (self._eventWaiters) should be # no waiters on these signals. Too expensive to check # the arrays for value changes. waiters = self._eventWaiters[:] # Swap the buffers (numpy.ndarray) so that the consumers have # the latest samples and the producers have a new buffer to # fill. tmp = self._val self._val = self._next self._next = self._val return [] def _update_type(self, val): self._val = val self._next = copy(self._val) Regards, Chris Felton |
From: Christopher F. <chr...@gm...> - 2011-09-12 04:45:42
|
On 9/11/11 4:06 PM, Sébastien Bourdeauducq wrote: > Hi, > > why isn't it possible to use __dict__ on signal objects? How to get > equivalent functionality? > > Thanks, > Sébastien > > >>> from myhdl import * > >>> > >>> s = Signal(intbv(0)[5:]) > >>> > >>> print s._max > 32 > >>> print s.__dict__["_max"] > Traceback (most recent call last): > File "<stdin>", line 1, in<module> > File "/home/lekernel/TE/myhdl/myhdl/_Signal.py", line 465, in __getattr__ > return getattr(self._val, attr) > AttributeError: 'intbv' object has no attribute '__dict__' > You can see from the error message, the __dict__ on a Signal, simply tries to pass the attribute *get* to whatever the Signal might be containing. It does work on an object that does have a __dict__ but the intbv doesn't have a __dict__. class foo(object): ....: def __init__(self): ....: pass ....: ....: In [78]: x = foo() In [79]: x.bar = 1 In [81]: xs = Signal(x) In [83]: xs.__dict__ Out[83]: {'bar': 1} Regards, Chris Felton |
From: Christopher F. <chr...@gm...> - 2011-09-12 04:40:17
|
On 9/10/11 9:05 AM, Sébastien Bourdeauducq wrote: > Hi, > > the patch below implements constant driver support. A constant driver > generator yields None. > > * Generic waiter object: block on None clauses > * New InfiniteWaiter object > * inferWaiter: create InfiniteWaiter when generator yields None > * always_comb decorator: yield None on empty sensitivity list > * conversion/analyze: return empty sensitivity list for generators that > yield None > * Verilog/VHDL conversion: wait forever on empty sensitivity list > <snip code patch> I haven't had time to review your code, so I don't have any specific feedback on the code but a couple general comments. Jan Decaluwe created a page outlining the process to contribute changes, http://www.myhdl.org/doku.php/dev:patches. Have a look at this page, it is very useful. You might want to create an hg bundle, in addition, to expedite any patches that might be accepted. If I recall, from the conversation it sounded like constant drivers are supported but not from a generator. Something like this works, currently: def testc(y): x = Signal(intbv(5)[8:]) @always_comb def rtl(): y.next = x return rtl The above will generate a constant driver (e.g. assign x = 5 in Verilog). But your patch proposes an alternative method to create constant drivers, correct? Your proposed changes would support something like: def testc(y): @always_comb def rtl(): y.next = 5 return rtl My question would be: Are there any error cases that might be missed now (that were previously caught)? Regards, Chris Felton |
From: Sébastien B. <seb...@mi...> - 2011-09-11 21:09:16
|
Hi, why isn't it possible to use __dict__ on signal objects? How to get equivalent functionality? Thanks, Sébastien >>> from myhdl import * >>> >>> s = Signal(intbv(0)[5:]) >>> >>> print s._max 32 >>> print s.__dict__["_max"] Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/lekernel/TE/myhdl/myhdl/_Signal.py", line 465, in __getattr__ return getattr(self._val, attr) AttributeError: 'intbv' object has no attribute '__dict__' |
From: Sébastien B. <seb...@mi...> - 2011-09-10 14:16:51
|
Sorry about the word-wrap damage, here is the patch again. diff -r e18493b5f0ad myhdl/_Waiter.py --- a/myhdl/_Waiter.py Fri May 20 21:07:24 2011 +0200 +++ b/myhdl/_Waiter.py Sat Sep 10 15:51:22 2011 +0200 @@ -107,7 +107,7 @@ elif isinstance(clause, join): waiters.append(_Waiter(clause._generator(), clone)) elif clause is None: - waiters.append(clone) + pass elif isinstance(clause, Exception): waiters.append(clone) if not exc: @@ -194,7 +194,17 @@ actives[id(wl)] = wl -_kind = enum("SIGNAL_TUPLE", "EDGE_TUPLE", "SIGNAL", "EDGE", "DELAY", "UNDEFINED") +class _InfiniteWaiter(_Waiter): + + __slots__ = ('generator') + + def __init__(self, generator): + self.generator = generator + + def next(self, waiters, actives, exc): + self.generator.next() + +_kind = enum("INFINITE", "SIGNAL_TUPLE", "EDGE_TUPLE", "SIGNAL", "EDGE", "DELAY", "UNDEFINED") def _inferWaiter(gen): @@ -207,6 +217,8 @@ # print ast.dump(root) v = _YieldVisitor(root) v.visit(root) + if v.kind == _kind.INFINITE: + return _InfiniteWaiter(gen) if v.kind == _kind.EDGE_TUPLE: return _EdgeTupleWaiter(gen) if v.kind == _kind.SIGNAL_TUPLE: @@ -265,7 +277,9 @@ def visit_Name(self, node): n = node.id node.kind = _kind.UNDEFINED - if n in self.root.symdict: + if n == "None": + node.kind = _kind.INFINITE + elif n in self.root.symdict: obj = self.root.symdict[n] if isinstance(obj, _Signal): node.kind = _kind.SIGNAL diff -r e18493b5f0ad myhdl/_always_comb.py --- a/myhdl/_always_comb.py Fri May 20 21:07:24 2011 +0200 +++ b/myhdl/_always_comb.py Sat Sep 10 15:51:22 2011 +0200 @@ -29,7 +29,7 @@ from myhdl._Signal import _Signal, _isListOfSigs from myhdl._util import _isGenFunc, _dedent from myhdl._cell_deref import _cell_deref -from myhdl._Waiter import _Waiter, _SignalWaiter, _SignalTupleWaiter +from myhdl._Waiter import _Waiter, _SignalWaiter, _SignalTupleWaiter, _InfiniteWaiter from myhdl._instance import _Instantiator class _error: @@ -39,7 +39,6 @@ _error.Scope = "always_comb argument should be a local function" _error.SignalAsInout = "signal (%s) used as inout in always_comb function argument" _error.EmbeddedFunction = "embedded functions in always_comb function argument not supported" -_error.EmptySensitivityList= "sensitivity list is empty" def always_comb(func): if not isinstance( func, FunctionType): @@ -200,8 +199,9 @@ self.senslist = tuple(senslist) self.gen = self.genfunc() if len(self.senslist) == 0: - raise AlwaysCombError(_error.EmptySensitivityList) - if len(self.senslist) == 1: + W = _InfiniteWaiter + self.senslist = None + elif len(self.senslist) == 1: W = _SignalWaiter else: W = _SignalTupleWaiter @@ -211,7 +211,7 @@ def genfunc(self): senslist = self.senslist - if len(senslist) == 1: + if (senslist != None) and (len(senslist) == 1): senslist = senslist[0] func = self.func while 1: diff -r e18493b5f0ad myhdl/conversion/_analyze.py --- a/myhdl/conversion/_analyze.py Fri May 20 21:07:24 2011 +0200 +++ b/myhdl/conversion/_analyze.py Sat Sep 10 15:51:22 2011 +0200 @@ -1042,6 +1042,8 @@ senslist = [n.obj] elif _isMem(n.obj): senslist = n.obj + elif n.obj is None: + pass else: self.raiseError(node, _error.UnsupportedYield) node.senslist = senslist diff -r e18493b5f0ad myhdl/conversion/_toVHDL.py --- a/myhdl/conversion/_toVHDL.py Fri May 20 21:07:24 2011 +0200 +++ b/myhdl/conversion/_toVHDL.py Sat Sep 10 15:51:22 2011 +0200 @@ -1354,17 +1354,18 @@ def visit_Yield(self, node): - self.write("wait ") + self.write("wait") yieldObj = self.getObj(node.value) - if isinstance(yieldObj, delay): - self.write("for ") - elif isinstance(yieldObj, _WaiterList): - self.write("until ") - else: - self.write("on ") - self.context = _context.YIELD - self.visit(node.value) - self.context = _context.UNKNOWN + if not yieldObj is None: + if isinstance(yieldObj, delay): + self.write(" for ") + elif isinstance(yieldObj, _WaiterList): + self.write(" until ") + else: + self.write(" on ") + self.context = _context.YIELD + self.visit(node.value) + self.context = _context.UNKNOWN self.write(";") diff -r e18493b5f0ad myhdl/conversion/_toVerilog.py --- a/myhdl/conversion/_toVerilog.py Fri May 20 21:07:24 2011 +0200 +++ b/myhdl/conversion/_toVerilog.py Sat Sep 10 15:51:22 2011 +0200 @@ -1176,7 +1176,6 @@ def visit_Yield(self, node): yieldObj = self.getObj(node.value) - assert node.senslist senslist = node.senslist if isinstance(yieldObj, delay): self.write("# ") @@ -1184,9 +1183,11 @@ self.visit(node.value) self.context = _context.UNKNOWN self.write(";") - else: + elif senslist: self.writeSensitivityList(senslist) self.write(";") + else: + self.write("wait(0);") |
From: Sébastien B. <seb...@mi...> - 2011-09-10 14:08:16
|
Hi, the patch below implements constant driver support. A constant driver generator yields None. * Generic waiter object: block on None clauses * New InfiniteWaiter object * inferWaiter: create InfiniteWaiter when generator yields None * always_comb decorator: yield None on empty sensitivity list * conversion/analyze: return empty sensitivity list for generators that yield None * Verilog/VHDL conversion: wait forever on empty sensitivity list Test code is here: https://github.com/sbourdeauducq/TokenEngine/blob/master/myhdl-limits/constantdriver.py Best regards, Sébastien Bourdeauducq --- diff -r e18493b5f0ad myhdl/_Waiter.py --- a/myhdl/_Waiter.py Fri May 20 21:07:24 2011 +0200 +++ b/myhdl/_Waiter.py Sat Sep 10 15:51:22 2011 +0200 @@ -107,7 +107,7 @@ elif isinstance(clause, join): waiters.append(_Waiter(clause._generator(), clone)) elif clause is None: - waiters.append(clone) + pass elif isinstance(clause, Exception): waiters.append(clone) if not exc: @@ -194,7 +194,17 @@ actives[id(wl)] = wl -_kind = enum("SIGNAL_TUPLE", "EDGE_TUPLE", "SIGNAL", "EDGE", "DELAY", "UNDEFINED") +class _InfiniteWaiter(_Waiter): + + __slots__ = ('generator') + + def __init__(self, generator): + self.generator = generator + + def next(self, waiters, actives, exc): + self.generator.next() + +_kind = enum("INFINITE", "SIGNAL_TUPLE", "EDGE_TUPLE", "SIGNAL", "EDGE", "DELAY", "UNDEFINED") def _inferWaiter(gen): @@ -207,6 +217,8 @@ # print ast.dump(root) v = _YieldVisitor(root) v.visit(root) + if v.kind == _kind.INFINITE: + return _InfiniteWaiter(gen) if v.kind == _kind.EDGE_TUPLE: return _EdgeTupleWaiter(gen) if v.kind == _kind.SIGNAL_TUPLE: @@ -265,7 +277,9 @@ def visit_Name(self, node): n = node.id node.kind = _kind.UNDEFINED - if n in self.root.symdict: + if n == "None": + node.kind = _kind.INFINITE + elif n in self.root.symdict: obj = self.root.symdict[n] if isinstance(obj, _Signal): node.kind = _kind.SIGNAL diff -r e18493b5f0ad myhdl/_always_comb.py --- a/myhdl/_always_comb.py Fri May 20 21:07:24 2011 +0200 +++ b/myhdl/_always_comb.py Sat Sep 10 15:51:22 2011 +0200 @@ -29,7 +29,7 @@ from myhdl._Signal import _Signal, _isListOfSigs from myhdl._util import _isGenFunc, _dedent from myhdl._cell_deref import _cell_deref -from myhdl._Waiter import _Waiter, _SignalWaiter, _SignalTupleWaiter +from myhdl._Waiter import _Waiter, _SignalWaiter, _SignalTupleWaiter, _InfiniteWaiter from myhdl._instance import _Instantiator class _error: @@ -39,7 +39,6 @@ _error.Scope = "always_comb argument should be a local function" _error.SignalAsInout = "signal (%s) used as inout in always_comb function argument" _error.EmbeddedFunction = "embedded functions in always_comb function argument not supported" -_error.EmptySensitivityList= "sensitivity list is empty" def always_comb(func): if not isinstance( func, FunctionType): @@ -200,8 +199,9 @@ self.senslist = tuple(senslist) self.gen = self.genfunc() if len(self.senslist) == 0: - raise AlwaysCombError(_error.EmptySensitivityList) - if len(self.senslist) == 1: + W = _InfiniteWaiter + self.senslist = None + elif len(self.senslist) == 1: W = _SignalWaiter else: W = _SignalTupleWaiter @@ -211,7 +211,7 @@ def genfunc(self): senslist = self.senslist - if len(senslist) == 1: + if (senslist != None) and (len(senslist) == 1): senslist = senslist[0] func = self.func while 1: diff -r e18493b5f0ad myhdl/conversion/_analyze.py --- a/myhdl/conversion/_analyze.py Fri May 20 21:07:24 2011 +0200 +++ b/myhdl/conversion/_analyze.py Sat Sep 10 15:51:22 2011 +0200 @@ -1042,6 +1042,8 @@ senslist = [n.obj] elif _isMem(n.obj): senslist = n.obj + elif n.obj is None: + pass else: self.raiseError(node, _error.UnsupportedYield) node.senslist = senslist diff -r e18493b5f0ad myhdl/conversion/_toVHDL.py --- a/myhdl/conversion/_toVHDL.py Fri May 20 21:07:24 2011 +0200 +++ b/myhdl/conversion/_toVHDL.py Sat Sep 10 15:51:22 2011 +0200 @@ -1354,17 +1354,18 @@ def visit_Yield(self, node): - self.write("wait ") + self.write("wait") yieldObj = self.getObj(node.value) - if isinstance(yieldObj, delay): - self.write("for ") - elif isinstance(yieldObj, _WaiterList): - self.write("until ") - else: - self.write("on ") - self.context = _context.YIELD - self.visit(node.value) - self.context = _context.UNKNOWN + if not yieldObj is None: + if isinstance(yieldObj, delay): + self.write(" for ") + elif isinstance(yieldObj, _WaiterList): + self.write(" until ") + else: + self.write(" on ") + self.context = _context.YIELD + self.visit(node.value) + self.context = _context.UNKNOWN self.write(";") diff -r e18493b5f0ad myhdl/conversion/_toVerilog.py --- a/myhdl/conversion/_toVerilog.py Fri May 20 21:07:24 2011 +0200 +++ b/myhdl/conversion/_toVerilog.py Sat Sep 10 15:51:22 2011 +0200 @@ -1176,7 +1176,6 @@ def visit_Yield(self, node): yieldObj = self.getObj(node.value) - assert node.senslist senslist = node.senslist if isinstance(yieldObj, delay): self.write("# ") @@ -1184,9 +1183,11 @@ self.visit(node.value) self.context = _context.UNKNOWN self.write(";") - else: + elif senslist: self.writeSensitivityList(senslist) self.write(";") + else: + self.write("wait(0);") |
From: Jan D. <ja...@ja...> - 2011-09-06 14:21:47
|
On 09/06/2011 03:39 PM, Sébastien Bourdeauducq wrote: > On 09/06/2011 03:39 PM, Jan Decaluwe wrote: >>> The signals are created by the __init__ method of the parent class. I >>> could of course add parameters to this __init__ method to define the >>> initial value of the signals, but it's quite messy and inelegant. >> >> No, just use overloading, it works for constructors also. > > Well, yes, but it's still inelegant. Not in my opinion. I would want to define a constant at construction time, not through a driver. (In the first case events at time 0 are avoided, in the second case not necessarily.) In my view, Verilog' assign for this purpose is a workaround for the fact that Verilog didn't have initialization syntax originally. (The reason why I don't use initialization in conversion is because I fear some tools won't support it.) >> I infer that some signals may have constant values that are >> different depending on the subclass. > > Yes. > > How about my proposition of yielding a special object "empty sensitivity > list/constant driver" in the generators? You can use 'yield None' today, but it's not supported by conversion. Classes are neither, so perhaps you don't mind. -- Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com Python as a HDL: http://www.myhdl.org VHDL development, the modern way: http://www.sigasi.com World-class digital design: http://www.easics.com |
From: Sébastien B. <seb...@mi...> - 2011-09-06 13:42:58
|
On 09/06/2011 03:39 PM, Jan Decaluwe wrote: >> The signals are created by the __init__ method of the parent class. I >> could of course add parameters to this __init__ method to define the >> initial value of the signals, but it's quite messy and inelegant. > > No, just use overloading, it works for constructors also. Well, yes, but it's still inelegant. > I infer that some signals may have constant values that are > different depending on the subclass. Yes. How about my proposition of yielding a special object "empty sensitivity list/constant driver" in the generators? |
From: Jan D. <ja...@ja...> - 2011-09-06 13:39:16
|
On 09/06/2011 02:27 PM, Sébastien Bourdeauducq wrote: > On 09/06/2011 02:26 PM, Jan Decaluwe wrote: >> On 09/05/2011 10:48 AM, Sébastien Bourdeauducq wrote: >>> On 09/05/2011 10:01 AM, Jan Decaluwe wrote: >>>> What would probably work is if such a method returns >>>> an empty list, explicitly indicating that it has no >>>> generators to contribute. >>> >>> Then how will MyHDL get the constant values to use, if all it gets from >>> the method is an empty list? >> >> From the initial value of the signals. > > And how do I set it? > > The signals are created by the __init__ method of the parent class. I > could of course add parameters to this __init__ method to define the > initial value of the signals, but it's quite messy and inelegant. No, just use overloading, it works for constructors also. I infer that some signals may have constant values that are different depending on the subclass. (I find that strange, because I would assume that the default initial value in a protocol is always the same. But I don't know your application of course.) In such a case, I would definitely want to set it right to the correct value at construction time. -- Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com Python as a HDL: http://www.myhdl.org VHDL development, the modern way: http://www.sigasi.com World-class digital design: http://www.easics.com |
From: Sébastien B. <seb...@mi...> - 2011-09-06 12:30:56
|
On 09/06/2011 02:26 PM, Jan Decaluwe wrote: > On 09/05/2011 10:48 AM, Sébastien Bourdeauducq wrote: >> On 09/05/2011 10:01 AM, Jan Decaluwe wrote: >>> What would probably work is if such a method returns >>> an empty list, explicitly indicating that it has no >>> generators to contribute. >> >> Then how will MyHDL get the constant values to use, if all it gets from >> the method is an empty list? > > From the initial value of the signals. And how do I set it? The signals are created by the __init__ method of the parent class. I could of course add parameters to this __init__ method to define the initial value of the signals, but it's quite messy and inelegant. |
From: Jan D. <ja...@ja...> - 2011-09-06 12:27:04
|
On 09/05/2011 10:48 AM, Sébastien Bourdeauducq wrote: > On 09/05/2011 10:01 AM, Jan Decaluwe wrote: >> What would probably work is if such a method returns >> an empty list, explicitly indicating that it has no >> generators to contribute. > > Then how will MyHDL get the constant values to use, if all it gets from > the method is an empty list? From the initial value of the signals. -- Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com Python as a HDL: http://www.myhdl.org VHDL development, the modern way: http://www.sigasi.com World-class digital design: http://www.easics.com |
From: Sébastien B. <seb...@mi...> - 2011-09-05 08:52:00
|
On 09/05/2011 10:01 AM, Jan Decaluwe wrote: > What would probably work is if such a method returns > an empty list, explicitly indicating that it has no > generators to contribute. Then how will MyHDL get the constant values to use, if all it gets from the method is an empty list? What about making the generator yield a special object, which would mean "empty sensitivity list/only driving constants"? Then the @always_comb decorator can automatically use that special object when it detects an empty sensitivity list, which makes the whole thing transparent from the normal user's point of view. |
From: Sébastien B. <seb...@mi...> - 2011-09-05 08:46:13
|
On 09/05/2011 12:49 AM, Jan Langer wrote: > Maybe you got a reset signal and can use that to set the initial > value. Then the synthesis will get rid of the register. No, the initial value is set upon configuration, independently of the user's reset signal. There are only two ways to set this initial value: 1) "initial" block in Verilog or assignment at signal declaration in VHDL 2) with a parameter when you instantiate the register primitive |
From: Jan D. <ja...@ja...> - 2011-09-05 08:02:14
|
On 09/04/2011 11:26 AM, Sébastien Bourdeauducq wrote: > On 09/03/2011 10:16 PM, Jan Decaluwe wrote: >> I don't see what's messy about it. > > Ok, then here is some more background: > > I have an abstract class FunctionalUnit which implements dataflow > processing units. This abstract class creates handshaking signals (ack, > strobe) common to all functional units which are used to control the > flow of data. > The method ImplementControl is overloaded by derived classes to > implement the actual handshaking logic, and returns instances. Now, when > some functional units need to drive handshaking signals constants, and > if it is not possible to build "constant drivers" instances, it becomes > messy. What would probably work is if such a method returns an empty list, explicitly indicating that it has no generators to contribute. -- Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com Python as a HDL: http://www.myhdl.org VHDL development, the modern way: http://www.sigasi.com World-class digital design: http://www.easics.com |
From: Jan L. <jan...@et...> - 2011-09-04 22:50:00
|
Am 05.09.2011 um 00:40 schrieb Sébastien Bourdeauducq: > On 09/04/2011 11:59 PM, Jan Langer wrote: >> So my idea was to put the clock edge into the sensitivity list and >> you >> get a clocked process that drives a constant, > > Ah, ok. :) > >> which in your case will get optimized away and behave as a normal >> constant. > > I'm afraid it won't. By default, FPGA registers are initialized at 0 > immediately after configuration. So if I want to drive a constant 1, I > will get instead a register that will drive 0 until the first clock > cycle, after which it drives 1. Maybe you got a reset signal and can use that to set the initial value. Then the synthesis will get rid of the register. -- Jan Langer Professorship Circuit and System Design Chemnitz University of Technology, Reichenhainer Str. 70, 09126 Chemnitz Phone: +49 37209 688001, Fax: +49 371 531-833158, Mobile: +49 162 9847325 http://www.tu-chemnitz.de/etit/sse |
From: Sébastien B. <seb...@mi...> - 2011-09-04 22:43:44
|
On 09/04/2011 11:59 PM, Jan Langer wrote: > So my idea was to put the clock edge into the sensitivity list and you > get a clocked process that drives a constant, Ah, ok. :) > which in your case will get optimized away and behave as a normal constant. I'm afraid it won't. By default, FPGA registers are initialized at 0 immediately after configuration. So if I want to drive a constant 1, I will get instead a register that will drive 0 until the first clock cycle, after which it drives 1. |
From: Jan L. <jan...@et...> - 2011-09-04 21:59:59
|
Am 04.09.2011 um 23:37 schrieb Sébastien Bourdeauducq: > On 09/04/2011 10:35 PM, Jan Langer wrote: >> Could you just use a clock everywhere? > > Huh? How is that related? > > There is indeed a clock everywhere - the whole generated circuit is > synchronous - but I still need (synchronous) strobe and acknowledgment > signals to control the flow of data. This practice is very common in > digital design, e.g. Wishbone and many other interconnect buses have > similar systems. As I understood, you need a always_comb block that just drives a constant. And since your sensitivity list is empty it does not work. So my idea was to put the clock edge into the sensitivity list and you get a clocked process that drives a constant, which in your case will get optimized away and behave as a normal constant. -- Jan Langer Professorship Circuit and System Design Chemnitz University of Technology, Reichenhainer Str. 70, 09126 Chemnitz Phone: +49 37209 688001, Fax: +49 371 531-833158, Mobile: +49 162 9847325 http://www.tu-chemnitz.de/etit/sse |
From: Sébastien B. <seb...@mi...> - 2011-09-04 21:40:59
|
On 09/04/2011 10:35 PM, Jan Langer wrote: > Could you just use a clock everywhere? Huh? How is that related? There is indeed a clock everywhere - the whole generated circuit is synchronous - but I still need (synchronous) strobe and acknowledgment signals to control the flow of data. This practice is very common in digital design, e.g. Wishbone and many other interconnect buses have similar systems. |
From: Jan L. <jan...@et...> - 2011-09-04 20:50:07
|
Am 02.09.2011 um 21:56 schrieb Christopher Felton: > On 9/2/2011 2:39 PM, Sébastien Bourdeauducq wrote: >> On 09/02/2011 09:20 PM, Christopher Felton wrote: >>> should limit the discussion to building >>> objects similar to VHDL record and SV struct >> >> Hmm, this would be of little help for the high level synthesizer I'm >> trying to develop :-) I tend to think I need dynamically built >> structures. >> > > Doh, but the first post (start of the conversation) was this simple > type? > > class Binary: > def __init__(self): > self.a = Signal(intbv()[32:]) > self.b = Signal(intbv()[32:]) > > In general, I don't think it would be a big issue. If something like > the SignalStruct was used dynamically. You could add signals as you > like. Then the converter would look at the final configuration and > still get a list of signals. > > But I kinda want to wrap my head around the declarative types first > (converter issues, etc) without closing the door on the dynamic. I > think I am struggling with a use case were dynamic is more useful than > the declarative. A dynamic approach on top of a declarative is easily possible. I think we should have a protocol of what the converter expects from a type to be convertible. Then we can define signal types that have dynamic behavior from a users point of view and provide the declarative interface to the converter. The basic data structure used in this interface will probably be the classic intbv. I remember the discussions on the fixed point type. With an approach like the one above, it should be possible to have a very clean fixed point class that shows the user a nice and clean interface where the correct result data type is inferred in expressions and through the declarative interface behind the scene the converter knows how to map the fixed point object to bit vectors. Jan -- Jan Langer Professorship Circuit and System Design Chemnitz University of Technology, Reichenhainer Str. 70, 09126 Chemnitz Phone: +49 37209 688001, Fax: +49 371 531-833158, Mobile: +49 162 9847325 http://www.tu-chemnitz.de/etit/sse |
From: Jan L. <jan...@et...> - 2011-09-04 20:35:43
|
Could you just use a clock everywhere? Am 04.09.2011 um 11:26 schrieb Sébastien Bourdeauducq: > On 09/03/2011 10:16 PM, Jan Decaluwe wrote: >> I don't see what's messy about it. > > Ok, then here is some more background: > > I have an abstract class FunctionalUnit which implements dataflow > processing units. This abstract class creates handshaking signals > (ack, > strobe) common to all functional units which are used to control the > flow of data. > The method ImplementControl is overloaded by derived classes to > implement the actual handshaking logic, and returns instances. Now, > when > some functional units need to drive handshaking signals constants, and > if it is not possible to build "constant drivers" instances, it > becomes > messy. -- Jan Langer Professorship Circuit and System Design Chemnitz University of Technology, Reichenhainer Str. 70, 09126 Chemnitz Phone: +49 37209 688001, Fax: +49 371 531-833158, Mobile: +49 162 9847325 http://www.tu-chemnitz.de/etit/sse |
From: Sébastien B. <seb...@mi...> - 2011-09-04 09:29:26
|
On 09/03/2011 10:16 PM, Jan Decaluwe wrote: > I don't see what's messy about it. Ok, then here is some more background: I have an abstract class FunctionalUnit which implements dataflow processing units. This abstract class creates handshaking signals (ack, strobe) common to all functional units which are used to control the flow of data. The method ImplementControl is overloaded by derived classes to implement the actual handshaking logic, and returns instances. Now, when some functional units need to drive handshaking signals constants, and if it is not possible to build "constant drivers" instances, it becomes messy. |
From: Jan D. <ja...@ja...> - 2011-09-03 20:16:45
|
On 09/03/2011 12:39 PM, Sébastien Bourdeauducq wrote: > Hi, > > I need to create instances that only drive their output to some constant > level, e.g. the equivalent of: > > module foo(output bar); > assign bar = 1'b1; > endmodule > > I have tried doing: > def ImplementControl(self): > @always_comb > def logic(): > self.control.ack_o.next[0] = 1 > return logic > > but MyHDL doesn't cope with the empty sensitivity list. > > Setting the value at signal creation (e.g. things like > self.control.ack_o = Signal(intbv(1))) is not an option because it would > become very messy with my object-oriented approach. Besides, I would > find it surprising that describing something as basic as a constant > driver is an intractable problem in MyHDL. > > Any solutions? A signal that you don't drive in your code gives you a warning and the expected assign. To me, that is exactly what "constant" means. I don't see what's messy about it. Of course, one could use such a signal in an always_comb and assign it to another signal. Such an approach would be meaningful for parametrization (a signal which is sometimes a constant, in other cases driven in code). Jan -- Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com Python as a HDL: http://www.myhdl.org VHDL development, the modern way: http://www.sigasi.com World-class digital design: http://www.easics.com |
From: Sébastien B. <seb...@mi...> - 2011-09-03 10:42:08
|
Hi, I need to create instances that only drive their output to some constant level, e.g. the equivalent of: module foo(output bar); assign bar = 1'b1; endmodule I have tried doing: def ImplementControl(self): @always_comb def logic(): self.control.ack_o.next[0] = 1 return logic but MyHDL doesn't cope with the empty sensitivity list. Setting the value at signal creation (e.g. things like self.control.ack_o = Signal(intbv(1))) is not an option because it would become very messy with my object-oriented approach. Besides, I would find it surprising that describing something as basic as a constant driver is an intractable problem in MyHDL. Any solutions? Thanks, Sébastien |