[Twisted-Python] verilog simulation calling out to twisted
Bryan Murdock
bmurdock at gmail.com
Thu Sep 21 12:31:00 MDT 2017
On Thu, Sep 21, 2017 at 4:07 AM, ex vito <ex.vitorino at gmail.com> wrote:
> On 2017-09-20, at 22:33, Bryan Murdock <bmurdock at gmail.com> wrote:
>
> Welcome to the club! :)
Thanks!
>> Now I have a crazy idea. I'd like that Python code that my Verilog
>> calls out to to use twisted. OK, actually I've already done that, my
>> Verilog calls out to my that TCP server that I wrote. I had to spawn
>> a thread and run the server in that thread so that the Verilog could
>> continue to do stuff in parallel with the server. It's working great.
>
> Can you clarify what "your Verilog" is? Python code running a Verilog simulation, maybe? Something else?
<snip/>
> I do not fully understand this: if "Verilog calls out to TCP server" means it establishes a TCP connection (does it?) what does "Verilog calls out to a TCP client" mean? Does it call a function/method with async Twisted code? How does it handle the fact that the result is async?
Sorry, I was worried that this would be too hard to explain and/or I
may be giving too many details and confusing the issue. Let me try
again. It's probably simplest to think of the whole simulation as a
TCP proxy. It looks like this:
some TCP client process <--> Python TCP Server <--> Verilog <-->
Python TCP Client <--> some TCP server
The Verilog, Python TCP server, and Python TCP client are all running
in the same process (some TCP client and some TCP server can be a web
browser and web server or whatever). The Verilog code starts up,
calls a python function to start the Python TCP Server as a thread,
calls another python function to start the Python TCP Client as a
thread, and then essentially just loops asking (polling) the Python
TCP Server if it has any data, if so, it calls a function to send that
data to the Python TCP Client. It does the same in reverse to flow
data from client to server.
I originally wrote the Python TCP Client and Server as low-level
socket code, handling only one connection at a time and not
automatically reconnecting if a connection was lost. All the
downsides of using multiple processes instead of threads that you
listed are exactly the reasons I used threads. Verilog has no support
for spawning subprocesses or doing interprocess communication. It
can't spawn threads either, to be fair though[1]. I have to do "real
programming" things like that by calling python functions. Threads
just seemed easier at the time because I can just use a Queue to get
data to/from the server and client threads from/to the Verilog. And
it all worked great.
Then, when I went to add support for multiple connections and
auto-reconnects I discovered twisted. I rewrote the Python TCP server
and client with twisted but now data doesn't flow. I assume that's
because the client and server are making thread-unsafe calls to the
reactor. Is that true?
(By the way, I can run the client and server standalone as separate
processes, without verilog involved, and they work fine that way. I
have also replaced the twisted Python TCP Client with my original
socket-based TCP client and everything works fine. It's just when I
try to use twisted for both client and server that it fails).
> In general you are able to run concurrent (not parallel) code for TCP clients and servers within the same thread - after all, that's the key idea behind async programming with Twisted, with the reactor driving concurrent handling of multiple connections and events.
Right, I think the solution is going to have to be: have verilog spawn
one thread that runs the Python TCP Server and Client. Or start them
both as subprocesses and figure out how to communicate with them, I
guess.
Bryan
1. Aside from it's "green threads" that it uses to model concurrent
digital logic
More information about the Twisted-Python
mailing list