diff options
Diffstat (limited to 'mpm/python/usrp_mpm/simulator/stream_ep_regs.py')
-rw-r--r-- | mpm/python/usrp_mpm/simulator/stream_ep_regs.py | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/mpm/python/usrp_mpm/simulator/stream_ep_regs.py b/mpm/python/usrp_mpm/simulator/stream_ep_regs.py new file mode 100644 index 000000000..defed345f --- /dev/null +++ b/mpm/python/usrp_mpm/simulator/stream_ep_regs.py @@ -0,0 +1,129 @@ +# +# Copyright 2020 Ettus Research, a National Instruments Brand +# +# SPDX-License-Identifier: GPL-3.0-or-later +# +"""This module holds the Emulated registers for a Stream Endpoint Node. +One of these objects is instantiated for each Stream Endpoint Node. +""" +from enum import IntEnum + +REG_EPID_SELF = 0x00 # RW +REG_RESET_AND_FLUSH = 0x04 # W +REG_OSTRM_CTRL_STATUS = 0x08 # RW +REG_OSTRM_DST_EPID = 0x0C # W +REG_OSTRM_FC_FREQ_BYTES_LO = 0x10 # W +REG_OSTRM_FC_FREQ_BYTES_HI = 0x14 # W +REG_OSTRM_FC_FREQ_PKTS = 0x18 # W +REG_OSTRM_FC_HEADROOM = 0x1C # W +REG_OSTRM_BUFF_CAP_BYTES_LO = 0x20 # R +REG_OSTRM_BUFF_CAP_BYTES_HI = 0x24 # R +REG_OSTRM_BUFF_CAP_PKTS = 0x28 # R +REG_OSTRM_SEQ_ERR_CNT = 0x2C # R +REG_OSTRM_DATA_ERR_CNT = 0x30 # R +REG_OSTRM_ROUTE_ERR_CNT = 0x34 # R +REG_ISTRM_CTRL_STATUS = 0x38 # RW + +RESET_AND_FLUSH_OSTRM = (1 << 0) +RESET_AND_FLUSH_ISTRM = (1 << 1) +RESET_AND_FLUSH_CTRL = (1 << 2) +RESET_AND_FLUSH_ALL = 0x7 + +STRM_STATUS_FC_ENABLED = 0x80000000 +STRM_STATUS_SETUP_ERR = 0x40000000 +STRM_STATUS_SETUP_PENDING = 0x20000000 + +class SwBuff(IntEnum): + """The size of the elements in a buffer""" + BUFF_U64 = 0 + BUFF_U32 = 1 + BUFF_U16 = 2 + BUFF_U8 = 3 + +class CtrlStatusWord: + """Represents a Control Status Word + + See mgmt_portal:BUILD_CTRL_STATUS_WORD() + """ + def __init__(self, cfg_start, xport_lossy, pyld_buff_fmt, mdata_buff_fmt, byte_swap): + self.cfg_start = cfg_start + self.xport_lossy = xport_lossy + self.pyld_buff_fmt = pyld_buff_fmt + self.mdata_buff_fmt = mdata_buff_fmt + self.byte_swap = byte_swap + + @classmethod + def parse(cls, val): + cfg_start = (val & 1) != 0 + xport_lossy = ((val >> 1) & 1) != 0 + pyld_buff_fmt = SwBuff((val >> 2) & 3) + mdata_buff_fmt = SwBuff((val >> 4) & 3) + byte_swap = ((val >> 6) & 1) != 0 + return cls(cfg_start, xport_lossy, pyld_buff_fmt, mdata_buff_fmt, byte_swap) + + def __str__(self): + return "CtrlStatusWord{{cfg_start: {}, xport_lossy: {}, " \ + "pyld_buff_fmt: {}, mdata_buff_fmt: {}, byte_swap: {}}}" \ + .format(self.cfg_start, self.xport_lossy, + self.pyld_buff_fmt, self.mdata_buff_fmt, self.byte_swap) + +class StreamEpRegs: + """Represents a set of registers associated with a stream endpoint + which can be accessed through management packets + + See mgmt_portal.cpp + """ + def __init__(self, get_epid, set_epid, set_dst_epid, update_status_out, + update_status_in, cap_pkts, cap_bytes): + self.get_epid = get_epid + self.set_epid = set_epid + self.set_dst_epid = set_dst_epid + self.log = None + self.out_ctrl_status = 0 + self.in_ctrl_status = 0 + self.update_status_out = update_status_out + self.update_status_in = update_status_in + self.cap_pkts = cap_pkts + self.cap_bytes = cap_bytes + + def read(self, addr): + if addr == REG_EPID_SELF: + return self.get_epid() + elif addr == REG_OSTRM_CTRL_STATUS: + return self.out_ctrl_status + elif addr == REG_ISTRM_CTRL_STATUS: + return self.in_ctrl_status + elif addr == REG_OSTRM_BUFF_CAP_BYTES_LO: + return self.cap_bytes & 0xFFFFFFFF + elif addr == REG_OSTRM_BUFF_CAP_BYTES_HI: + return (self.cap_bytes >> 32) & 0xFFFFFFFF + elif addr == REG_OSTRM_BUFF_CAP_PKTS: + return self.cap_pkts + else: + raise NotImplementedError("Unable to read addr 0x{:08X} from stream ep regs" + .format(addr)) + + def write(self, addr, val): + if addr == REG_EPID_SELF: + self.log.debug("Setting EPID to {}".format(val)) + self.set_epid(val) + elif addr == REG_OSTRM_CTRL_STATUS: + status = CtrlStatusWord.parse(val) + self.log.debug("Setting EPID Output Stream Ctrl Status: {}".format(status)) + new_status = self.update_status_out(status) + self.out_ctrl_status = new_status if new_status is not None else val + elif addr == REG_RESET_AND_FLUSH: + self.log.trace("Stream EP Regs Reset and Flush") + elif addr == REG_OSTRM_DST_EPID: + self.log.debug("Setting Dest EPID to {}".format(val)) + self.set_dst_epid(val) + elif REG_OSTRM_FC_FREQ_BYTES_LO <= addr <= REG_OSTRM_FC_HEADROOM: + pass # TODO: implement these Flow Control parameters + elif addr == REG_ISTRM_CTRL_STATUS: + status = CtrlStatusWord.parse(val) + self.log.debug("Setting EPID Input Stream Ctrl Status: {}".format(status)) + new_status = self.update_status_in(status) + self.in_ctrl_status = new_status if new_status is not None else val + else: + raise NotImplementedError("Unable to write addr 0x{:08X} from stream ep regs" + .format(addr)) |