From f7c1cc23a5fdcad6e59d47c79598c947736e5c76 Mon Sep 17 00:00:00 2001 From: Donald Sebastian Leung Date: Fri, 25 Sep 2020 12:49:14 +0800 Subject: [PATCH] Implement artiq.gateware.rtio.rtlink --- README.md | 2 +- artiq/gateware/rtio/rtlink.py | 97 +++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e156f6b..4680700 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Formally verified implementation of the ARTIQ RTIO core in nMigen - - [ ] `artiq.gateware.rtio.core` - - [ ] `misoc.interconnect.csr` - - [ ] `artiq.gateware.rtio.cri` -- - [ ] `artiq.gateware.rtio.rtlink` +- - [x] `artiq.gateware.rtio.rtlink` - - [ ] `artiq.gateware.rtio.channel` - - [ ] `artiq.gateware.rtio.sed.core` - - [ ] `artiq.gateware.rtio.sed.layouts` diff --git a/artiq/gateware/rtio/rtlink.py b/artiq/gateware/rtio/rtlink.py index e69de29..585e22c 100644 --- a/artiq/gateware/rtio/rtlink.py +++ b/artiq/gateware/rtio/rtlink.py @@ -0,0 +1,97 @@ +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")