Skip to content

Instantly share code, notes, and snippets.

@rizemon
Last active April 26, 2021 16:31
Show Gist options
  • Save rizemon/c1ca54b68295ecfa15500c2825e0c177 to your computer and use it in GitHub Desktop.
Save rizemon/c1ca54b68295ecfa15500c2825e0c177 to your computer and use it in GitHub Desktop.
from math import log2
from sys import argv
from rich.console import Console
from rich.table import Table
########## CHANGE THIS ###########
NWAY = 2 # 1/2/4
# Number of bytes
WORD = 4 # 4 bytes (Probably no need to change this)
MAIN_MEMORY = 2 ** 32 # 4GB (Probably no need to change this)
BLOCK = 8
CACHE = 2**8
##################################
def humanbytes(B):
'Return the given bytes as a human friendly KB, MB, GB, or TB string'
B = float(B)
KB = float(1024)
MB = float(KB ** 2) # 1,048,576
GB = float(KB ** 3) # 1,073,741,824
TB = float(KB ** 4) # 1,099,511,627,776
if B < KB:
return '{0} {1}'.format(B, 'Bytes')
elif KB <= B < MB:
return '{0:.2f} KB'.format(B/KB)
elif MB <= B < GB:
return '{0:.2f} MB'.format(B/MB)
elif GB <= B < TB:
return '{0:.2f} GB'.format(B/GB)
elif TB <= B:
return '{0:.2f} TB'.format(B/TB)
def print_cache():
CACHE_SIZE = CACHE // NWAY
ADDRESS_LENGTH = int(log2(MAIN_MEMORY)) # In bits
BLOCK_LENGTH = int(log2(BLOCK)) # In bits
BLOCKNUMBER_LENGTH = ADDRESS_LENGTH - BLOCK_LENGTH # In bits
CACHE_LENGTH = int(log2(CACHE_SIZE // BLOCK)) # In bits
CACHETAG_LENGTH = ADDRESS_LENGTH - CACHE_LENGTH - BLOCK_LENGTH # In bits
WORD_LENGTH = int(log2(WORD)) # In bits
WORDNUMBER_LENGTH = BLOCK_LENGTH - WORD_LENGTH # In bits
print(f"""Calculations for {NWAY}-Way Associative Cache
Main Memory: {humanbytes(MAIN_MEMORY)} / {MAIN_MEMORY} Bytes
Cache: {humanbytes(CACHE)} / {CACHE} Bytes
Block: {humanbytes(BLOCK)} / {BLOCK} Bytes
Word: {humanbytes(WORD)} / {WORD} Bytes
Number of bits for address: {ADDRESS_LENGTH} bits
Offset, N: {BLOCK_LENGTH} bits
Block Number: {ADDRESS_LENGTH} - {BLOCK_LENGTH} = {BLOCKNUMBER_LENGTH} bits
Number of Cache sets: {2**CACHE_LENGTH}
Cache Index, M: {CACHE_LENGTH} bits
Cache Tag: {ADDRESS_LENGTH} - {CACHE_LENGTH} - {BLOCK_LENGTH} = {CACHETAG_LENGTH} bits
""")
memorytable = Table(show_lines=True)
memorytable.add_column("Block Number ")
memorytable.add_column("Offset (N) ")
memorytable.add_row(f"{BLOCKNUMBER_LENGTH} bits", f"{BLOCK_LENGTH} bits")
cachetable = Table(show_lines=True)
cachetable.add_column("Tag")
cachetable.add_column("Index (M)")
cachetable.add_column("Word")
cachetable.add_column("Byte")
cachetable.add_row(f"{CACHETAG_LENGTH} bits", f"{CACHE_LENGTH} bits", f"{WORDNUMBER_LENGTH} bits", f"{BLOCK_LENGTH - WORDNUMBER_LENGTH} bits")
console = Console()
print("Memory")
console.print(memorytable)
print("Cache")
console.print(cachetable)
print()
headertable = Table(show_lines=True, show_edge=False)
headertable.add_column("Index")
for a in range(NWAY):
headertable.add_column(f"Block {a}" + 4 * " " + 9 * " " * 2 ** WORDNUMBER_LENGTH)
console.print(headertable)
bodytable = Table(show_lines=True, show_header=False)
entry = [" "]
for b in range(NWAY):
entry += ["Valid", "Tag", *[f"Word {i}" for i in range(2 ** WORDNUMBER_LENGTH)]]
bodytable.add_row(*entry)
console.print(bodytable)
def main():
print_cache()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment