rtio-nmigen/artiq/gateware/rtio/rtlink.py

98 lines
2.6 KiB
Python
Raw Normal View History

2020-09-25 12:49:14 +08:00
from nmigen import *
class OInterface:
def __init__(self, data_width, address_width=0,
fine_ts_width=0, enable_replace=True,
delay=0):
self.stb = Signal()
self.busy = Signal()
assert 0 <= data_width <= 512
assert 0 <= address_width <= 8
assert 0 <= fine_ts_width <= 4
if data_width:
self.data = Signal(data_width, reset_less=True)
if address_width:
self.address = Signal(address_width, reset_less=True)
if fine_ts_width:
self.fine_ts = Signal(fine_ts_width, reset_less=True)
self.enable_replace = enable_replace
if delay < 0:
raise ValueError("only positive delays allowed", delay)
self.delay = delay
@classmethod
def like(cls, other):
return cls(get_data_width(other),
get_address_width(other),
get_fine_ts_width(other),
other.enable_replace,
other.delay)
class IInterface:
def __init__(self, data_width,
timestamped=True, fine_ts_width=0, delay=0):
self.stb = Signal()
assert 0 <= data_width <= 32
assert 0 <= fine_ts_width <= 4
if data_width:
self.data = Signal(data_width, reset_less=True)
if fine_ts_width:
self.fine_ts = Signal(fine_ts_width, reset_less=True)
assert(not fine_ts_width or timestamped)
self.timestamped = timestamped
if delay < 0:
raise ValueError("only positive delays")
self.delay = delay
@classmethod
def like(cls, other):
return cls(get_data_width(other),
other.timestamped,
get_fine_ts_width(other),
other.delay)
class Interface:
def __init__(self, o, i=None):
self.o = o
self.i = i
@classmethod
def like(cls, other):
if other.i is None:
return cls(OInterface.like(other.o))
else:
return cls(OInterface.like(other.o),
IInterface.like(other.i))
def _get_or_zero(interface, attr):
if interface is None:
return 0
assert isinstance(interface, (OInterface, IInterface))
if hasattr(interface, attr):
return len(getattr(interface, attr))
else:
return 0
def get_data_width(interface):
return _get_or_zero(interface, "data")
def get_address_width(interface):
return _get_or_zero(interface, "address")
def get_fine_ts_width(interface):
return _get_or_zero(interface, "fine_ts")