Использование Simulation (MyHDL) и wxPython вместе - PullRequest
2 голосов
/ 02 марта 2011

Я использую пакет MyHDL для аппаратного моделирования, но я хочу разместить графический интерфейс вокруг него, чтобы пользователи могли интерактивно изменять сигналы и видеть обновление других сигналов.

Проблема в том, что 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()

Но, конечно, я изначально не думал о безопасности потоков. Кроме того, все те функции генератора, которые есть в симуляторе, не могут быть переданы в поток.

Я думаю, что мог бы потратить некоторое время, действительно работая над рабочим классом с твердыми потоками, который был создан ранее и который КТО-ТО может получить функции генератора, необходимые посредством некоторой передачи сообщений. Однако мне кажется, что было бы намного проще, если бы я мог определить какой-то генератор, который будет вызывать «yield delay (1)» для каждого шага цикла wxPython . Примерно так в классе:

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 Ответ

3 голосов
/ 02 марта 2011

Неважно, я "решил" это с помощью app.ExitLoop ()

Я понял, что могу обернуть свой собственный цикл вокруг app.MainLoop (), и всякий раз, когда я получаю событие, о котором заботится симулятор, обработчик вызывает app.ExitLoop (), возвращая управление симулятору, а затем запускает главный снова цикл для wx.

Это не идеально, это определенно хак, но работает

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...