Python中yield语句和MyHDL之间的区别

6
我正在学习MyHDL,这是我的暑期项目。我在理解其中yield语句的作用方面有困难。尽管MyHDL基于Python,但它以一种专门的方式使用了yield语句。以下是相关链接: http://www.myhdl.org/doc/current/manual/reference.html#myhdl.always 该链接中提到: MyHDL生成器是标准的Python生成器,具有专门的yield语句。在硬件描述语言中,等效的语句称为敏感性列表。在MyHDL生成器中,yield语句的一般格式是: yield clause [, clause ...] 当生成器执行yield语句时,它的执行在此处被暂停。同时,每个条款都是一个触发器对象,它定义了生成器应该在其上恢复执行的条件。然而,对于yield语句的每次调用,生成器仅会恢复一次,无论clause数量如何。这发生在第一个触发器出现时。 我无法理解这段内容。请问是否有人能以简单的话来解释一下?或者将我转到另一个来源?
非常感谢您的帮助。
祝好!
3个回答

3
首先要记住的是,MyHDL实现严格遵循纯Python。在这个意义上,MyHDL中的yield语句与Python中的yield语句并无区别。
MyHDL真正做到了将Python用作硬件描述语言的一种方式。部分地,这是通过在一个名为myhdl的纯Python包中实现一些硬件设计特定对象来完成的。例如,有一个名为myhdl.Simulation的对象,可以以适合硬件仿真的方式运行生成器。
另一个部分就是简单地以硬件特定的方式解释某些Python功能。例如,将硬件模块建模为返回生成器的Python函数。另一个例子是将“yield”语句解释为“wait”功能。

2
我的HDL使用yield语句来传递条件列表,当其中一个条件为True时,将恢复生成器的执行。例如,生成器可能会在时钟从低电平到高电平(0到1)转换时产生时钟上升沿条件clock.posedge - 当时钟进行此转换时,生成器将被恢复。
为了模拟这个过程,这里有一个Python生成器,当其条件(参数可被3或7整除)之一得到满足时就会被恢复执行:
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)

输出:

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

更新 - 我使用的一些语法细节更详细的解释:

我倾向于使用 [next(gen, [default])] 函数,因为它比调用 gen.next() 更加灵活。例如,如果您传递了 default 参数,当生成器被耗尽时,它将返回 default 而不是 引发 StopIteration 异常。

变量 conds 指向一个包含条件的元组。在这个例子中,它指向包含由 process 返回的 2 个lambda 匿名函数元组

语法:

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

调用内置函数 any,并将其传递给一个生成器表达式,该表达式循环遍历conds并评估if cond(i) is True。 它是以下代码的简写形式:
for cond in conds:
    if cond(i):
        conds = next(gen)
        break

@samplebias:非常感谢您的回复...但是,您能否解释一下您代码中的以下内容:1)conds=next(gen) 意味着 conds=gen.next()..对吗?2)您能否解释一下“for cond in conds”是什么意思...就我所知,conds不是一个列表。那么我们如何遍历它呢?非常感谢! - Adwaitvedant
@samplebias:感谢您的回复!请忽略我的上一篇帖子。我仔细看了您的例子并正确地理解了它!然而,我仍然不明白答案...在Python中,我们必须显式调用next(conds)才能再次调用函数...但在myhdl中,情况并非如此....当yield语句中的对象“返回”时(这是文档中所说的),它会自动触发自身...这是如何实现的? - Adwaitvedant
@Jan 是的,在我的示例中,我试图勾勒出模拟器在决定何时恢复生成器时如何评估产生的条件。@Adwait “反弹回来”只是意味着“当条件评估为True时,模拟器会恢复生成器”。 - samplebias
@samplebias @Jan:非常感谢您的回复!正是我在寻找的!请问您能告诉我在哪里可以找到myhdl构造的Python实现,例如模拟等。在他们的网站上,对于Simulation对象,他们只给出了描述而没有实现...谢谢! - Adwaitvedant
请在myhdl.org上点击下载链接。 - Jan Decaluwe
显示剩余3条评论

2
yield语句用于创建生成器。这些生成器可以与MyHDL中的Simulation(...)对象或转换器函数一起使用。换句话说,通过将描述硬件行为的所有生成器传递给模拟器,在MyHDL中使用生成器。Simulation.run()函数将使用“next()”。
在MyHDL手册的RTL建模部分http://www.myhdl.org/doc/current/manual/modeling.html#example中,有一些很好的示例,说明如何创建MyHDL生成器并在模拟中使用它们。

非常感谢您的回复!正是我在寻找的!请问您能告诉我在哪里可以找到myhdl构造的Python实现,例如模拟等。在他们的网站上,对于Simulation对象,他们只给出了描述,但没有实现...谢谢! - Adwaitvedant
1
@Adwaitvedant:MyHDL的最新版本可以在这里获取。访问开发存储库的说明可以在这里找到。在_Simulation.py文件中,大约在第129行左右,显示使用了“等待”队列,并且准备运行的生成器(在等待队列上)会调用它们的下一个函数。 - Christopher Felton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接