uio: add simulation I/O object
This commit is contained in:
parent
7add4c6f3c
commit
be68ecfc72
|
@ -7,3 +7,63 @@ class UnifiedIOObject(Actor):
|
|||
if dataflow is not None:
|
||||
super().__init__(*dataflow)
|
||||
self.buses = buses
|
||||
|
||||
(_WAIT_COMPLETE, _WAIT_POLL) = range(2)
|
||||
|
||||
class UnifiedIOSimulation(UnifiedIOObject):
|
||||
def __init__(self, generator, dataflow=None, buses={}):
|
||||
self.generator = generator
|
||||
super().__init__(dataflow, buses)
|
||||
|
||||
self.callers = []
|
||||
self.busname_to_caller_id = {}
|
||||
if dataflow is not None:
|
||||
self.callers.append(TokenExchanger(self.demux_g(0), self))
|
||||
for k, v in self.buses.items():
|
||||
caller_id = len(self.callers)
|
||||
self.busname_to_caller_id[k] = caller_id
|
||||
g = self.demux_g(caller_id)
|
||||
if isinstance(v, wishbone.Interface):
|
||||
caller = wishbone.Initiator(g, v)
|
||||
else:
|
||||
raise NotImplementedError
|
||||
self.callers.append(caller)
|
||||
|
||||
self.dispatch_state = _WAIT_COMPLETE
|
||||
self.dispatch_caller = 0
|
||||
self.pending_transaction = None
|
||||
|
||||
def identify_transaction(self, t):
|
||||
if isinstance(t, Token):
|
||||
return 0
|
||||
elif isinstance(t, TRead) or isinstance(t, TWrite):
|
||||
if t.busname is None:
|
||||
if len(self.busname_to_caller_id) != 1:
|
||||
raise TypeError
|
||||
else:
|
||||
return list(self.busname_to_caller_id.values())[0]
|
||||
else:
|
||||
return self.busname_to_caller_id[t.busname]
|
||||
else:
|
||||
raise TypeError
|
||||
|
||||
def dispatch_g(self, caller_id):
|
||||
while True:
|
||||
if self.dispatch_state == _WAIT_COMPLETE and self.dispatch_caller == caller_id:
|
||||
transaction = next(self.generator)
|
||||
tr_cid = self.identify_transaction(transaction)
|
||||
self.dispatch_caller = tr_cid
|
||||
if tr_cid == caller_id:
|
||||
yield transaction
|
||||
else:
|
||||
self.pending_transaction = transaction
|
||||
self.dispatch_state = _WAIT_POLL
|
||||
yield None
|
||||
elif self.dispatch_state == _WAIT_POLL and self.dispatch_caller == caller_id:
|
||||
self.dispatch_state = _WAIT_COMPLETE
|
||||
yield self.pending_transaction
|
||||
else:
|
||||
yield None
|
||||
|
||||
def get_fragment(self):
|
||||
return sum([c.get_fragment() for c in self.callers], Fragment())
|
||||
|
|
Loading…
Reference in New Issue