Skip to content

Instantly share code, notes, and snippets.

@sielicki
Created April 5, 2020 19:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sielicki/29e3b424979e02de2c248cde8e5b9dc7 to your computer and use it in GitHub Desktop.
Save sielicki/29e3b424979e02de2c248cde8e5b9dc7 to your computer and use it in GitHub Desktop.
import typing as t
### Data Types
# Little Endian LSB MSB
row_in = t.Tuple[bool, bool, bool, bool]
# Also little endian
mat_in = t.Tuple[
row_in,
row_in,
row_in,
row_in,
row_in,
row_in,
row_in,
row_in,
row_in,
row_in,
row_in,
row_in,
row_in,
row_in,
row_in,
row_in,
]
# Little Endian LSB MSB
row_out = t.Tuple[bool, bool, bool, bool, bool, bool, bool, bool]
# Also little endian
mat_out = t.Tuple[
row_out,
row_out,
row_out,
row_out,
row_out,
row_out,
row_out,
row_out,
row_out,
row_out,
row_out,
row_out,
row_out,
row_out,
row_out,
row_out,
]
### Helper Functions
def number_to_row_in(val: int) -> row_in:
assert 0 <= val and val < 2 ** 4
return (
bool(val & (1 << 0)),
bool(val & (1 << 1)),
bool(val & (1 << 2)),
bool(val & (1 << 3)),
)
def number_to_row_out(val: int) -> row_out:
assert 0 <= val and val < 2 ** 8
return (
bool(val & (1 << 0)),
bool(val & (1 << 1)),
bool(val & (1 << 2)),
bool(val & (1 << 3)),
bool(val & (1 << 4)),
bool(val & (1 << 5)),
bool(val & (1 << 6)),
bool(val & (1 << 7)),
)
def number_to_row(val: int) -> t.Union[row_in, row_out]:
assert val >= 0
return number_to_row_in(val) if val < 16 else number_to_row_out(val)
def row_to_number(row: t.Union[row_in, row_out]) -> int:
return sum(
[2 ** idx if row[idx] else 0 for idx in range(0, len(row))]
)
def row_to_hex(row: t.Union[row_in, row_out]) -> str:
prefix = "0" if len(row) == 8 else ""
return prefix + str(hex(row_to_number(row)))[2:]
def m_to_hex(mat: t.Union[mat_in, mat_out]) -> str:
s = ""
for row in reversed(mat):
s += row_to_hex(row)
return s
def numbers_to_mat_in(vals: t.List[int]) -> mat_in:
""" Given an len 16 list of ints, produce a 16x4 tuple representation """
assert len(vals) == 16
return (
number_to_row_in(vals[15]),
number_to_row_in(vals[14]),
number_to_row_in(vals[13]),
number_to_row_in(vals[12]),
number_to_row_in(vals[11]),
number_to_row_in(vals[10]),
number_to_row_in(vals[9]),
number_to_row_in(vals[8]),
number_to_row_in(vals[7]),
number_to_row_in(vals[6]),
number_to_row_in(vals[5]),
number_to_row_in(vals[4]),
number_to_row_in(vals[3]),
number_to_row_in(vals[2]),
number_to_row_in(vals[1]),
number_to_row_in(vals[0]),
)
def convert_one_row(i: row_in) -> row_out:
""" Zero pad a 4-bit tuple representation to an 8-bit tuple representation """
# i is already a "row", so the MSB is the lower index.
return (False, False, False, False, i[3], i[2], i[1], i[0])
### The Thing We're Trying To Do, note the indicies!
def convert_mats(m_in: mat_in) -> mat_out:
""" Given a 16x4 tuple representation, produce a 16x8 tuple with zero-extension """
return (
convert_one_row(m_in[14]),
convert_one_row(m_in[12]),
convert_one_row(m_in[10]),
convert_one_row(m_in[8]),
convert_one_row(m_in[6]),
convert_one_row(m_in[4]),
convert_one_row(m_in[2]),
convert_one_row(m_in[0]),
convert_one_row(m_in[15]),
convert_one_row(m_in[13]),
convert_one_row(m_in[11]),
convert_one_row(m_in[9]),
convert_one_row(m_in[7]),
convert_one_row(m_in[5]),
convert_one_row(m_in[3]),
convert_one_row(m_in[1]),
)
### An example
my_input = numbers_to_mat_in(list(range(0x0, 0x10)))
print(m_to_hex(my_input))
print(m_to_hex(convert_mats(my_input)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment