我正在使用MyHDL软件包进行硬件模拟,但我想在其周围放置一个GUI,以便用户可以交互式地更改信号并查看其他信号的更新。
问题是,MyHDL使用模拟器如下
wxPython显然使用了一个事件循环。因此,我显然不能在没有将另一个打起来的情况下运行这两个。
我的第一个(哑)方法如下
def Hack():
@instance
def inst():
yield delay(1)
self._app.MainLoop()
return inst
MyHack = Hack()
self._instances.append(MyHack)
self._simulator = Simulation(*self._instances)
self._simulator.run()
这很有效,但是inst()生成器只运行一次,因此Simulation实际上什么也没做。
然后我意识到这是一种需要多线程的情况。我尝试了以下方法:
self._simulator = Simulation(*self._instances)
p = Process(target=StartSim, args=(self._simulator,))
p.start()
#self._simulator.run()
self._app.MainLoop()
p.join()
def StartSim(sim):
sim.run()
但当然我最初没有想到线程安全。此外,我在模拟器中拥有的所有生成器函数都无法传递给线程。
我想我可以花一些时间真正开发一个先前创建的实体线程工作者类,并且可以通过某种消息传递获得所需的生成器函数。但是,在我看来,如果我能为 wxPython 循环的每一步定义某种称为“yield delay(1)”的生成器,那将会更容易。在课堂上有这样的事情:
def OnIdle(self):
yield delay(10)
然后继续使用我原来的方法。问题是,我需要代码是这样的:
def Hack():
@instance
def inst():
self._app.InitMainLoop()
while(self._app.InMainLoop())
yield delay(1)
self._app.DoMainLoopBody()
return inst
那么,在那个冗长的解释之后,是否有一个很好的方法来做到这一点?我可以定义自己的MainLoop或以某种方式更改它吗?或者有没有人曾经使用过MyHDL和线程?
答案 0 :(得分:3)
没关系,我使用app.ExitLoop()
“解决”了它我意识到我可以在app.MainLoop()周围包装自己的循环,每当我得到模拟器关心的事件时,处理程序调用app.ExitLoop(),将控制权交还给模拟器,然后启动主再次循环播放wx。
它并不完美,它绝对是一种黑客攻击,但它正在发挥作用