Skip to content

Instantly share code, notes, and snippets.

@LightslicerGP
Last active January 30, 2025 02:55
Show Gist options
  • Save LightslicerGP/ed82e665f5328890ff215a49ecfd754d to your computer and use it in GitHub Desktop.
Save LightslicerGP/ed82e665f5328890ff215a49ecfd754d to your computer and use it in GitHub Desktop.
Alu made in Python
def intToBool(Number: int, bitlength: int = 8):
Number = bin(Number)[2:].zfill(bitlength)
numArr = []
if len(Number) > bitlength:
raise ValueError(
f"bit length allowed: {bitlength}, number bit count: {len(Number)} "
)
for i in range(bitlength):
if Number[i] == "0":
numArr.append(False)
elif Number[i] == "1":
numArr.append(True)
return numArr
debug = False
def alu(
A: int,
B: int,
invA: bool = False,
invB: bool = False,
enableOr: bool = False,
floodCarry: bool = False,
carryIn: bool = False,
bitlength: int = 8,
):
"""
returns: (result, carryOut)
"""
if A < 0:
A = bin(A)[3:].zfill(bitlength)
print(A) if debug else None
A = int("".join(["1" if bit == "0" else "0" for bit in A]), 2) + 1
if B < 0:
B = bin(B)[3:].zfill(bitlength)
print(B) if debug else None
B = int("".join(["1" if bit == "0" else "0" for bit in B]), 2) + 1
A = intToBool(A, bitlength)
B = intToBool(B, bitlength)
result = []
if invA:
A = [not i for i in A]
if invB:
B = [not i for i in B]
print(A) if debug else None
print(B) if debug else None
for i in range(bitlength - 1, -1, -1): # from lsb to msb, instead of msb to lsb
print("i:", i) if debug else None
print("carry in:", carryIn) if debug else None
print("A: ", A[i]) if debug else None
print("B: ", B[i]) if debug else None
# DeprecationWarning: Bitwise inversion '~' on bool is deprecated. (this means ill use "and not" instead of "& !")
# Shoutout to mr_nano for clearing things up for me, huge thanks to him
result.insert(0, carryIn ^ (A[i] | B[i] if enableOr else A[i] ^ B[i]))
if floodCarry:
carryIn = True
elif enableOr:
carryIn = False
else:
carryIn = (A[i] & B[i]) | (A[i] & carryIn) | (B[i] & carryIn)
print(A, B, carryIn) if debug else None
print(result) if debug else None
negativeFlag = result[0]
parityFlag = sum(result) % 2 == 0
overflowFlag = A[0] == B[0] and A[0] != result[0]
result = int("".join(["1" if i else "0" for i in result]), 2)
zeroFlag = result == 0
return {
"result": result,
"flags": {
"carry": carryIn,
"zero": zeroFlag,
"negative": negativeFlag,
"parity": parityFlag,
"overflow": overflowFlag,
},
}
def compute(mode: str, a: int, b: int):
mode.lower()
match mode:
case "add":
return alu(
a,
b,
invA=False,
invB=False,
enableOr=False,
floodCarry=False,
carryIn=False,
)
case "subtract":
return alu(
a,
b,
invA=False,
invB=True,
enableOr=False,
floodCarry=False,
carryIn=True,
)
case "or":
return alu(
a,
b,
invA=False,
invB=False,
enableOr=True,
floodCarry=False,
carryIn=False,
)
case "nor":
return alu(
a,
b,
invA=False,
invB=False,
enableOr=True,
floodCarry=True,
carryIn=True,
)
case "and":
return alu(
a,
b,
invA=True,
invB=True,
enableOr=True,
floodCarry=True,
carryIn=True,
)
case "nand":
return alu(
a,
b,
invA=True,
invB=True,
enableOr=True,
floodCarry=False,
carryIn=False,
)
case "xor":
return alu(
a,
b,
invA=False,
invB=True,
enableOr=False,
floodCarry=True,
carryIn=True,
)
case "xnor":
return alu(
a,
b,
invA=False,
invB=False,
enableOr=False,
floodCarry=True,
carryIn=True,
)
case _:
return alu(
a,
b,
invA=False,
invB=False,
enableOr=False,
floodCarry=False,
carryIn=False,
)
output = compute("xnor", 0b1100, 0b1010)
import json
print(json.dumps(output, indent=2))
print(f"result in binary: {bin(output["result"])[2:].zfill(8)}")

Alu Example and table

the results are when the inputs are as follows:

  • a is 0b00001100
  • b is 0b00001010
Mode Invert A Invert B Enable Or Flood Carry Carry in Result Carry out
Add false false false false false 0b00010110 false
Subtract false true false false true 0b00000010 true
Or false false true false false 0b00001110 false
Nor false false true true true 0b11110001 true
And true true true true true 0b00001000 true
Nand true true true false false 0b11110111 false
Xor false true false true true 0b00000110 true
Xnor false false false true true 0b11111001 true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment