# Path: basil/utils/sim/Protocol.py
# class WriteRequest(ProtocolBase):
#     def __init__(self, address, data):
#         self.address = address
#         self.data = data
# 
#     def __str__(self):
#         return "WriteRequest: 0x%04x <- %s" % (self.address, self.data)
# 
# class ReadRequest(ProtocolBase):
#     def __init__(self, address, size):
#         self.address = address
#         self.size = size
# 
#     def __str__(self):
#         return "ReadRequest: 0x%04x (size %d)" % (self.address, self.size)
# 
# class ReadResponse(ProtocolBase):
#     def __init__(self, data):
#         self.data = data
# 
#     def __str__(self):
#         return "ReadResponse: %s" % str(self.data)
# 
# class PickleInterface(ProtocolBase):
#     def __init__(self, sock):
#         self.sock = sock
# 
#     def send(self, obj):
#         """Prepend a 4-byte length to the string"""
#         assert isinstance(obj, ProtocolBase)
#         string = pickle.dumps(obj)
#         length = len(string)
#         self.sock.sendall(struct.pack("<I", length) + string)
# 
#     def recv(self, blocking=True):
#         """Receive the next object from the socket"""
#         length = struct.unpack("<I", self.sock.recv(4))[0]
#         return self._get_next_obj(length)
# 
#     def try_recv(self):
#         """Return None immediately if nothing is waiting"""
#         try:
#             lenstr = self.sock.recv(4, socket.MSG_DONTWAIT)
#         except socket.error:
#             return None
#         if len(lenstr) < 4:
#             raise EOFError("Socket closed")
#         length = struct.unpack("<I", lenstr)[0]
#         return self._get_next_obj(length)
# 
#     def _get_next_obj(self, length):
#         """Assumes we've already read the object length"""
#         data = b""
#         while len(data) < length:
#             data += self.sock.recv(length - len(data))
# 
#         return pickle.loads(data)


import logging
import os
import socket
import yaml
import cocotb
from cocotb.triggers import Timer
from cocotb.clock import Clock
from basil.utils.sim.Protocol import WriteRequest, ReadRequest, ReadResponse, PickleInterface
        for mod in sim_modules_yml:
            mod_import = import_driver(mod)
            kargs = dict(sim_modules_yml[mod])
            sim_modules.append(mod_import(dut, **kargs))
            dut._log.info("Using simulation modules : %s  arguments: %s" % (mod, kargs))

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    try:
        s.bind((host, int(port)))
        s.listen(1)
    except Exception:
        s.close()
        s = None
        raise

    # Kick off a clock generator
    if bus_clock:
        cocotb.fork(Clock(bus.clock, bus_clk_freq).start())

    # start sim_modules
    for mod in sim_modules:
        cocotb.fork(mod.run())

    await bus.init()

    while True:
        dut._log.info("Waiting for incoming connection on %s:%d" % (host, int(port)))
        clientsocket, socket_address = s.accept()
        dut._log.info("New connection from %s:%d" % (socket_address[0], socket_address[1]))

# Path: basil/utils/sim/Protocol.py
# class WriteRequest(ProtocolBase):
#     def __init__(self, address, data):
#         self.address = address
#         self.data = data
# 
#     def __str__(self):
#         return "WriteRequest: 0x%04x <- %s" % (self.address, self.data)
# 
# class ReadRequest(ProtocolBase):
#     def __init__(self, address, size):
#         self.address = address
#         self.size = size
# 
#     def __str__(self):
#         return "ReadRequest: 0x%04x (size %d)" % (self.address, self.size)
# 
# class ReadResponse(ProtocolBase):
#     def __init__(self, data):
#         self.data = data
# 
#     def __str__(self):
#         return "ReadResponse: %s" % str(self.data)
# 
# class PickleInterface(ProtocolBase):
#     def __init__(self, sock):
#         self.sock = sock
# 
#     def send(self, obj):
#         """Prepend a 4-byte length to the string"""
#         assert isinstance(obj, ProtocolBase)
#         string = pickle.dumps(obj)
#         length = len(string)
#         self.sock.sendall(struct.pack("<I", length) + string)
# 
#     def recv(self, blocking=True):
#         """Receive the next object from the socket"""
#         length = struct.unpack("<I", self.sock.recv(4))[0]
#         return self._get_next_obj(length)
# 
#     def try_recv(self):
#         """Return None immediately if nothing is waiting"""
#         try:
#             lenstr = self.sock.recv(4, socket.MSG_DONTWAIT)
#         except socket.error:
#             return None
#         if len(lenstr) < 4:
#             raise EOFError("Socket closed")
#         length = struct.unpack("<I", lenstr)[0]
#         return self._get_next_obj(length)
# 
#     def _get_next_obj(self, length):
#         """Assumes we've already read the object length"""
#         data = b""
#         while len(data) < length:
#             data += self.sock.recv(length - len(data))
# 
#         return pickle.loads(data)


# Path: basil/utils/sim/Test.py
import logging
import os
import socket
import yaml
import cocotb
from cocotb.triggers import Timer
from cocotb.clock import Clock
from basil.utils.sim.Protocol import WriteRequest, ReadRequest, ReadResponse, PickleInterface

        for mod in sim_modules_yml:
            mod_import = import_driver(mod)
            kargs = dict(sim_modules_yml[mod])
            sim_modules.append(mod_import(dut, **kargs))
            dut._log.info("Using simulation modules : %s  arguments: %s" % (mod, kargs))

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    try:
        s.bind((host, int(port)))
        s.listen(1)
    except Exception:
        s.close()
        s = None
        raise

    # Kick off a clock generator
    if bus_clock:
        cocotb.fork(Clock(bus.clock, bus_clk_freq).start())

    # start sim_modules
    for mod in sim_modules:
        cocotb.fork(mod.run())

    await bus.init()

    while True:
        dut._log.info("Waiting for incoming connection on %s:%d" % (host, int(port)))
        clientsocket, socket_address = s.accept()
        dut._log.info("New connection from %s:%d" % (socket_address[0], socket_address[1]))

        iface = PickleInterface(clientsocket)