一起使用模拟(MyHDL)和wxPython

时间:2011-03-02 07:28:34

标签: python multithreading wxpython generator simulation

我正在使用MyHDL软件包进行硬件模拟,但我想在其周围放置一个GUI,以便用户可以交互式地更改信号并查看其他信号的更新。

问题是,MyHDL使用模拟器如下

  • 模拟器有几个发电机
  • 每个发生器可以监听信号变化,也可以调用产量延迟(x),以告诉模拟器等待再次调用x滴答。
  • 调用Simulator.run()以启动模拟循环
  • 运行循环完成

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和线程?

1 个答案:

答案 0 :(得分:3)

没关系,我使用app.ExitLoop()

“解决”了它

我意识到我可以在app.MainLoop()周围包装自己的循环,每当我得到模拟器关心的事件时,处理程序调用app.ExitLoop(),将控制权交还给模拟器,然后启动主再次循环播放wx。

它并不完美,它绝对是一种黑客攻击,但它正在发挥作用