def counter_value(quad, channel, frame): """Returns object counter value. Format by HB, '0xXXYYZZZZ' where X is the lane, Y the object (0..5), Z the BX. """ lane = (quad * 4 + channel) & binutils.bitmask(8) obj = (frame % 6) & binutils.bitmask(8) bx = (frame // 6) & binutils.bitmask( 16) # 6 objects per bx in 240 Mz domain. return lane << 24 | obj << 16 | bx
def unpack_line(self, *args): """Unpacks a record line.""" if self.unpack_pos >= self.data.lines: IndexError( "unpack_line(): no more line to unpack: {self.unpack_pos}". format(**locals())) value = self.data.next() self.data_raw.append(value) for arg in args: item = RecordItem(arg, self.unpack_pos + self.pos) if hasattr(self, item.name) and item.index is None: raise AttributeError( "unpack_line(): attribute already exists: {arg}".format( **locals())) item.value = (value >> item.lsb) & bitmask(item.bitwidth) self.items.append(item) if item.index is None: setattr(self, item.name, item) else: setattr( self, item.name, ItemList( filter(lambda item_: item_.name == item.name, self.items))) # Sort by line number and descending LSB position. self.items.sort( key=lambda item: (item.line, item.index, -item.lsb)) self.unpack_pos += 1
def __init__(self, count, width, coding={}): self._count = count self._width = width self._coding = coding self._dwords = binutils.requires(width, UHAL_DATA_WIDTH) self._charcount = binutils.charcount(width) self._bitmask = binutils.bitmask(width)
def vetos(self, offset=0): """Return vetos as list. Offset rotates values by BX. Provided for convenience.""" values = self.merged()[:TDF.ORBIT_LENGTH] # Mask veto bits mask = bitmask(self.Inputs) # upper 8 bits values = [(value >> 8) & mask for value in values] return values[offset:] + values[:offset]
def finors(self, offset=0): """Return FinORs as list. Offset rotates values by BX. Provided for convenience.""" values = self.merged()[:TDF.ORBIT_LENGTH] # Mask FinOR bits mask = bitmask(self.Inputs) # lower 8 bits values = [(value >> 0) & mask for value in values] return values[offset:] + values[:offset]
def index(self, i): """Return value of record line with offset *i* (0..n). Raises an IndexError if *i* is out of bounds (*i* >= number of lines). """ if i < self.lines: return (self._data >> (i * RECORD_WIDTH)) & bitmask(RECORD_WIDTH) raise IndexError( "index(): record index out of range: {i}".format(**locals()))
def append(self, value): self._data |= (value & bitmask(RECORD_WIDTH)) << (self.lines * RECORD_WIDTH) self._lines += 1
def value(self, value): self._value = value & bitmask(self.bitwidth)
# Fetch raw memory to decode and cross-check... spymem = dump(target_device, 'payload.spymem') # Check for jitter samples = spymem.merged()[1:TDF.ORBIT_LENGTH] counter = Counter(samples) if len(counter) != 1: errors += 1 TDF_ERROR("DETECTED JITTER:") for key, count in counter.iteritems(): TDF_ERROR(" value=0x{:08x} count={} times".format(key, count)) # Fetch sample memory line # bits [xxxxxxxTxxVVVVVVxxFFFFFF] T=finor2tcds, V=veto, F=finor sample = spymem.merged()[args.offset] sample_finor = (sample >> (0 + index)) & bitmask(6) sample_veto = (sample >> (8 + index)) & bitmask(6) sample_finor2tcds = (sample >> 16) & bitmask(1) # Cross check (no other bit must be active) reference = (sample_finor2tcds << 16) | ( sample_veto << (8 + index)) | (sample_finor << (0 + index)) if sample != reference: errors += 1 TDF_ERROR( "CROSS-CHECK FAILED: sample={:08x} (reference={:08x})".format( sample, reference)) TDF_NOTICE( "source={}, target={}, cable={}, sample=0x{:08x}, finor={}, veto={}, finor2tcds={}" .format(device, target_device, cable, sample, sample_finor,
def setEnabled(self, enabled): """Enable or disable all algorithms of all BX.""" self.clear(bitmask(TDF.DATA_WIDTH) if enabled else 0x0)