Я использую пакет 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 и многопоточностью?