Re: [myhdl-list] difficulty using itertools with MyHDL
Brought to you by:
jandecaluwe
From: Jan D. <ja...@ja...> - 2006-10-24 19:50:30
|
Jan Decaluwe wrote: > However, I'm really not sure that the interaction of this > with the MyHDL scheduler works meaningfully. Normally the > scheduler should decide when a MyHDL generator is run, and > this seems to inferere with that. I'll have to experiment > with itertools. Ok, I'll start with the conclusion. itertools shouldn't be used to manipulate MyHDL generators. The results are meaningless. The reason is the following. When using the MyHDL simulator, there is an implicit contract about (MyHDL) generator usage: don't run them yourself (by calling their 'next') method, but let the Simulator do that. Of course this is Python and I don't see how this could be enforced. But the results are basically meaningless. When using itertools in the way discussed, that's exactly what happens under the hood - itertool object methods such as 'next' run the underlying generators themselves. No need for despair though. The MyHDL scheduler, combined with coding techniques, should be able to support the required behavior correctly, and probably in an easier way. Here's an example. Consider this generator: def gen(msg, d=1, n=3): for i in range(n): yield delay(d) print " %s: %s" % (now(), msg) yield delay(1) It prints out a message a number of times after a delay. Now let's a play a game of ping-pong using itertools. We set up the sequence as follows: seq = itertools.izip(gen("ping", 1), gen("pong", 1)) and simulate this generator: def test(seq): while seq: yield seq.next() The result is: 1: ping 1: pong 2: ping 2: pong 3: ping 3: pong Seems OK. But now let's try this: seq = itertools.izip(gen("ping", 1), gen("pong", 4)) We give a much larger delay to "pong", and we would expect a number of pings first. But we get: 1: ping 1: pong 2: ping 2: pong 3: ping 3: pong No difference. Clearly not OK. The reason is that both generators are incorrectly forced to run both as soon as the fastest one triggers. Not good. What to do? Well, one thing we can do is use the MyHDL simulator's ability to schedule generators dynamically. If we simply simulate: def test2(): yield gen("ping", 1), gen("pong", 1) we get: 1: pong 1: ping 2: pong 2: ping 3: pong 3: ping as before. But when we now do: def test2(): yield gen("ping", 1), gen("pong", 4) we get: 1: ping 2: ping 3: ping 4: pong 8: pong 12: pong as expected. There's more to it, but this is probably enough food for thought for one post. More info can be found in the manual under "bus-functional procedures". Jan -- Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com Losbergenlaan 16, B-3010 Leuven, Belgium From Python to silicon: http://myhdl.jandecaluwe.com |