Skip to content

Commit

Permalink
Added new RegBitsFields
Browse files Browse the repository at this point in the history
  • Loading branch information
prgeor committed Aug 8, 2023
1 parent c99d311 commit 8deaa31
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 0 deletions.
31 changes: 31 additions & 0 deletions sonic_platform_base/sonic_xcvr/fields/xcvr_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,38 @@ def encode(self, val, raw_state=None):
curr_state &= ~(1 << self.bitpos % 8)
return bytearray([curr_state])

class RegBitsField(XcvrField):
"""
Multi-bit register field. Must be defined under a parent RegField
Args:
bitpos: the bit position of this field relative to its parent's offset
"""
def __init__(self, name, bitpos, offset=None, **kwargs):
super(RegBitsField, self).__init__(name, offset, **kwargs)
self.size = self.size = kwargs.get("size", 1) #No of bits
assert (bitpos >= 0 and (bitpos+self.size-1 < 8), "bitpos must be within one byte")
self.bitpos = bitpos
self.bitmask = (((1 << self.size) - 1) << self.bitpos) & 0xff

def get_size(self):
return 1 # 1-Byte

def read_before_write(self):
return True

def decode(self, raw_data, **decoded_deps):
val = (raw_data[0] & self.bitmask) >> self.bitpos
return val

def encode(self, val, raw_value=None):
assert not self.ro and raw_value is not None
val = val & ((1 << self.size) - 1)
byte = raw_value[0]
byte &= ~self.bitmask
byte |= (val << self.bitpos)
return bytearray([byte])

class RegField(XcvrField):
"""
Field denoting one or more bytes, but logically interpreted as one unit (e.g. a 4-byte integer)
Expand Down
54 changes: 54 additions & 0 deletions tests/sonic_xcvr/test_xcvr_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
HexRegField,
NumberRegField,
RegBitField,
RegBitsField,
RegGroupField,
StringRegField,
)
Expand Down Expand Up @@ -51,6 +52,16 @@ def __init__(self, codes):
RegBitField("NumRegBit", bitpos=20, ro=False),
format="<I", size=4, ro=False
)
self.NUM_REG_2BITS = NumberRegField("MultiBitsReg1", 154,
RegBitsField("Bits0to1", bitpos=0, ro=False, size=2),
RegBitsField("Bits2to3", bitpos=2, ro=False, size=2),
RegBitsField("Bits4to5", bitpos=4, ro=False, size=2),
RegBitsField("Bits6to7", bitpos=6, ro=False, size=2)
)
self.NUM_REG_4BITS = NumberRegField("MultiBitsReg2", 162,
RegBitsField("Bits0to3", bitpos=0, ro=False, size=4),
RegBitsField("Bits4to7", bitpos=4, ro=False, size=4)
)
self.STRING_REG = StringRegField("StringReg", 12, size=15)
self.HEX_REG = HexRegField("HexReg", 30, size=3)
self.REG_GROUP = RegGroupField("RegGroup",
Expand Down Expand Up @@ -141,6 +152,49 @@ def test_get_fields(self):
"NestedField2": mem_map.get_field("NestedField2")
}

class TestRegBitsField(object):
def test_encode_decode(self):
field = mem_map.get_field("Bits0to1")
encoded_data = field.encode(0x3, bytearray(b'\xfc'))
assert encoded_data == bytearray(b'\xff')
decoded_data = field.decode(bytearray(b'\xf2'))
assert decoded_data == 0x2

field = mem_map.get_field("Bits2to3")
encoded_data = field.encode(0x0, bytearray(b'\xff'))
assert encoded_data == bytearray(b'\xf3')
decoded_data = field.decode(bytearray(b'\xf4'))
assert decoded_data == 0x1

field = mem_map.get_field("Bits4to5")
encoded_data = field.encode(0x2, bytearray(b'\xff'))
assert encoded_data == bytearray(b'\xef')
decoded_data = field.decode(bytearray(b'\xef'))
assert decoded_data == 0x2

field = mem_map.get_field("Bits6to7")
encoded_data = field.encode(0x2, bytearray(b'\xff'))
assert encoded_data == bytearray(b'\xbf')
decoded_data = field.decode(bytearray(b'\xbf'))
assert decoded_data == 0x2

field = mem_map.get_field("Bits6to7")
encoded_data = field.encode(0x1, bytearray(b'\xff'))
assert encoded_data == bytearray(b'\x7f')
decoded_data = field.decode(bytearray(b'\x7f'))
assert decoded_data == 0x1

field = mem_map.get_field("Bits0to3")
encoded_data = field.encode(0x3, bytearray(b'\xff'))
assert encoded_data == bytearray(b'\xf3')
decoded_data = field.decode(bytearray(b'\xf3'))
assert decoded_data == 3
field = mem_map.get_field("Bits4to7")
encoded_data = field.encode(0x3, bytearray(b'\xff'))
assert encoded_data == bytearray(b'\x3f')
decoded_data = field.decode(bytearray(b'\xf3'))
assert decoded_data == 0xf

class TestRegBitField(object):
def test_offset(self):
field = mem_map.get_field("BitField0")
Expand Down

0 comments on commit 8deaa31

Please sign in to comment.