Search code examples
pythonpython-2.7myhdl

yield statement in myhdl


I have the following code in my myhdl environment:

def rst(self):
   rst.next=rst.active
   self.wait_clks(5)

def wait_clks(self, cycles):
   for _ in range(cycles):
      yield self.clk.posedge

the above code doesn't work but when I replace it with the following it works:

def rst(self):
   rst.next=rst.active
   for _ in range(5):
      yield self.clk.posedge

I am confused over this, if anyone can explain why the yield in the function definition doesn't work?


Solution

  • When you simply call a generator function (one that has yield statement in its body) , you get a generator object, it does not even start going through the function at that point, it only starts that when you start iterating over the returned generator object (or call next() on it). Example -

    >>> def gen1():
    ...     print("Starting")
    ...     for i in range(10):
    ...             yield i
    ...
    >>> g = gen1()
    >>> g
    <generator object gen1 at 0x00273E68>
    

    As you can see above, it did not start going through the function, it just returned the generator object. To go through the function you need to iterate over g or call next() on it. Example -

    >>> g.next()
    Starting
    0
    >>> for i in g:
    ...     print i
    ... 
    1
    2
    .
    .
    

    In your first case as well something similar is happenning, you are just calling the generator function, which returns the generator object, and then discarding the result. Most probably, from wherever rst() is called , it is expecting a generator object in return. In which case your second method is the best.

    But if you really really want to make it in a separate function (and I do not see any need to make it in a separate method) , you can directly return the result of self.wait_clks(5) back from rst(self) . Example -

    def rst(self):
       rst.next=reset.active
       return self.wait_clks(5)
    

    Example to show that this works -

    >>> def f():
    ...     return gen1()
    ... 
    >>> for i in f():
    ...     print(i)
    ... 
    Starting
    0
    1
    2
    .
    .