6

I am currently learning MyHDL for my summer project. I have a problem grasping the functioning of yield statement in it. Though its true that the MyHDL is based upon python, it uses its yield statement in a specialized way. the link for the same is : http://www.myhdl.org/doc/current/manual/reference.html#myhdl.always

it states: MyHDL generators are standard Python generators with specialized yield statements. In hardware description languages, the equivalent statements are called sensitivity lists. The general format of yield statements in in MyHDL generators is: yield clause [, clause ...] When a generator executes a yield statement, its execution is suspended at that point. At the same time, each clause is a trigger object which defines the condition upon which the generator should be resumed. However, per invocation of a yield statement, the generator resumes exactly once, regardless of the number of clauses. This happens on the first trigger that occurs.

I am not able to comprehend it. Could someone please explain it in simple words? or perhaps redirect me to another source?

I'll be grateful if you could help. Thanks!

Regards

Adwaitvedant
  • 253
  • 3
  • 10

3 Answers3

3

First and foremost: remember that the MyHDL implementation is strictly pure Python. In that sense there is no "difference" between a yield statement in MyHDL and in Python.

MyHDL really is a way to use Python as a HDL. Partially, this is done by implementing some hardware design specific objects in a pure Python package called myhdl. For example, there is a myhdl.Simulation object that runs generators in a way suited for hardware simulation.

The other part is simply interpreting certain Python features in a hardware specific way. For example, a hardware module is modeled as a Python function that returns generators. Another example is that the "yield" statement is interpreted as a "wait" functionality.

Jan Decaluwe
  • 2,405
  • 19
  • 18
2

MyHDL is using the yield statement to communicate a list of conditions which, when one of them is True, will resume execution of the generator. For example, a generator might yield condition clock.posedge when the clock transitions from low to high (0 to 1) -- when the clock makes this transition, the generator will be resumed.

To simulate (roughly) how this works, here is a Python generator which is resumed when one of its conditions (argument is evenly divisible by 3 or 7) are met:

def process():
    j = 0
    while True:
        yield (lambda x: x % 3 == 0, lambda x: x % 7 == 0)
        j += 1
        print 'process j=', j

gen = process()
conds = next(gen)

for i in range(1, 11):
    print 'i=', i
    if any(cond(i) for cond in conds):
        conds = next(gen)

Output:

i= 1
i= 2
i= 3
process j= 1
i= 4
i= 5
i= 6
process j= 2
i= 7
process j= 3
i= 8
i= 9
process j= 4
i= 10

Update - A bit more detail on some of the syntax I used:

I tend to use the [next(gen, [default])] function as it is a bit more flexible than calling gen.next(). For example, if you pass the default arg, when the generator is exhausted it will return default rather than raising StopIteration.

The var conds points to a tuple containing the conditions. In this case above it points to a tuple containing the 2 lambda anonymous functions returned by process.

The syntax:

if any(cond(i) for cond in conds):
    conds = next(gen)

Calls the any built-in function, passing it a generator expression which loops over conds and evaluates if cond(i) is True. It is shorthand for writing:

for cond in conds:
    if cond(i):
        conds = next(gen)
        break
samplebias
  • 37,113
  • 6
  • 107
  • 103
  • @samplebias : Thanks a lot gor you reply...however could you please explain the following in you code: 1)conds=next(gen) means conds=gen.next()..right? 2)could you explain what does "for cond in conds" mean...conds is not a list as far as I can interpret. So how are we iterating over it? Thanks a lot! – Adwaitvedant May 19 '11 at 08:33
  • @samplebias: Thanks for your reply!..ignore my last post...i went through your example and understood it properly!..however I still dont get the answer...in python we have to explicitly call next(conds) when we want to invoke the function again...in myhdl thats not the case....it automatically triggers itself when the object in the yield statement "fires back"(this is what they have said in their documentation)... how is this implemented? – Adwaitvedant May 19 '11 at 15:51
  • @Adwait I believe they are using the Python code to generate HDL which behaves differently. Compare some [MyHDL Python source](http://www.myhdl.org/doku.php/cookbook:sinecomp#design) with the corresponding [generated Verilog code](http://www.myhdl.org/doku.php/cookbook:sinecomp#automatic_conversion_to_verilog). Notice how the `yield clock.posedge` creates the `always(..)` directive. – samplebias May 19 '11 at 16:10
  • @Adwait In MyHDL, there is a Simulation object that controls all MyHDL generators. In particular, the Simulation calls the .next() methods in a way appropriate for hardware simulation. Remember, it is all pure Python. In a sense, MyHDL is just a way to interprete certain pure Python constructs in a hardware oriented way. For example, when you see "yield" in a MyHDL generator, think "wait". – Jan Decaluwe May 19 '11 at 18:58
  • @samplebias The goal of MyHDL conversion is that the generated Verilog/VHDL code behaves identically to the MyHDL code on the MyHDL simulator. – Jan Decaluwe May 19 '11 at 19:03
  • @Jan Yes, in my example I tried to sketch how the simulator evaluates the yielded conditions in deciding when to resume a generator. @Adwait The "fires back" just means "the simulator resumes the generator when a condition evaluates `True`". – samplebias May 19 '11 at 19:09
  • @samplebias @Jan : Thanks a lot for your reply! Exactly what I was looking for! Could you please tell me where can I find the python implementation of myhdl constructs such as simulation etc. On their site, for Simulation object they have just given the description but not the implementation..thanks! – Adwaitvedant May 20 '11 at 04:24
  • Follow the Download link on myhdl.org. – Jan Decaluwe May 20 '11 at 07:19
2

The yield statement is used to create the generators. In turn these generators can be used with the Simulation(...) object within MyHDL or with the converter functions. In other words, The generators are used in MyHDL by passing all the generators that describe hardware behavior to the simulator. The Simulation.run() function will use the "next()".

In the RTL modeling section of the MyHDL manual, http://www.myhdl.org/doc/current/manual/modeling.html#example, are some good examples how to create the MyHDL generators and use these in a simulation.

  • Thanks a lot for your reply! Exactly what I was looking for! Could you please tell me where can I find the python implementation of myhdl constructs such as simulation etc. On their site, for Simulation object they have just given the description but not the implementation..thanks! – Adwaitvedant May 20 '11 at 04:24
  • 1
    @Adwaitvedant : The latest release of MyHDL is available [here](http://sourceforge.net/projects/myhdl/files/myhdl/). Instructions to access the development repository are available [here](http://www.myhdl.org/doku.php/dev:repo). In _Simulation.py, roughly line 129, shows that a "wait" queue is used and generators that are ready to run (on the wait queue), their next function is called. – Christopher Felton May 20 '11 at 13:30