diff options
author | Ekaitz Zarraga <ekaitz@elenq.tech> | 2021-07-23 20:49:14 +0200 |
---|---|---|
committer | Ekaitz Zarraga <ekaitz@elenq.tech> | 2021-07-23 20:49:14 +0200 |
commit | 681036ddc3891904f13c84197cd90e2472cb3e1c (patch) | |
tree | 080b9580c14274698d1848e7640cba0cc47a53a6 /pysc-v/memory.py | |
parent | 309d36182ef32a1bc5bff84f39e9e81db0ddb9a6 (diff) |
Diffstat (limited to 'pysc-v/memory.py')
-rw-r--r-- | pysc-v/memory.py | 112 |
1 files changed, 0 insertions, 112 deletions
diff --git a/pysc-v/memory.py b/pysc-v/memory.py deleted file mode 100644 index 84bf0bd..0000000 --- a/pysc-v/memory.py +++ /dev/null @@ -1,112 +0,0 @@ -from ctypes import c_uint8, c_uint16, c_uint32 - -class Addressable: - def __init__(self, start=0, end=0): - self.start = start - self.end = end - def addr_to_pos(self, addr): - if not (self.start <= addr < self.end): - raise KeyError("Address out of space") - return addr - self.start - -def merge_bytes (byte_iter): - val = 0 - for i,v in enumerate(byte_ouput): - val += v.value << 8 * i - return val -def split_bytes (val, byte_count): - return tuple( c_uint8(val >> 8 * i) for i in range(byte_count) ) - -class Memory32 (Addressable): - """ - This is a raw 32-bit word memory addressable at a byte level. - Internally it is defined as c_uint8 list. - Special functions are needed to access halfs (c_uint16) and words - (c_uint32). - """ - - def __init__(self, start=0, end=0, bigEndian=False): - super().__init__(start, end) - self.bigEndian = bigEndian - self.lastChange = None - # Pre-allocate or allocate or allocate per write? - self.data = [None] * (end - start) - - def get_byte(self, addr): - return self.data[ self.addr_to_pos(addr) ] - def set_byte(self, addr, val): - if not isinstance(val, c_uint8): - if val > 0xFF: - raise ValueError("Value is larger than a byte") - self.data[ self.addr_to_pos(addr) ] = val if isinstance(val, c_uint8) else c_uint8(val) - self.lastChange = range(addr, addr+1) - - - def get_half(self,addr): - byte_output = (get_byte(addr), get_byte(addr+1)) - if self.bigEndian: - byte_output = reversed(byte_output) - return c_uint16( merge_bytes(byte_output) ) - - def set_half(self, addr, val): - if not isinstance(val, c_uint16): - if val > 0xFFFF: - raise ValueError("Value is larger than a half") - bytes = split_bytes(val, 2) - if self.bigEndian: - bytes = reversed(bytes) - for i,v in enumerate(bytes): - self.set_byte(addr+i, v) - self.lastChange = range(addr,addr+2) - - def get_word(self, pos): - byte_output = tuple(get_byte(addr+i) for i in range(4)) - if self.bigEndian: - byte_output = reversed(byte_output) - return c_uint32( merge_bytes(byte_output) ) - - def set_word(self, addr, val): - if not isinstance(val, c_uint32): - if val > 0xFFFFFFFF: - raise ValueError("Value is larger than a word") - bytes = split_bytes(val, 4) - if self.bigEndian: - bytes = reversed(bytes) - for i,v in enumerate(bytes): - self.set_byte(addr+i, v) - self.lastChange = range(addr,addr+4) - - def __str__(self): - out = " " - out += "-" * 50 - out += "\n" - for i,d in enumerate(self.data): - if d is not None: - addr = i+self.start - out += "->" if addr in self.lastChange else " " - out += f"| {addr:#20x} | {d.value:#5} | {d.value:#04x} | {d.value:#010b} |" - out += "\n" - out += " " - out += "-" * 50 - out += "\n" - return out - - -class Memory32RO (Memory32): - def set_byte(self, addr, val): - raise NotImplementedError("Trying to write in a read-only memory") - def set_half(self, addr, val): - raise NotImplementedError("Trying to write in a read-only memory") - def set_word(self, addr, val): - raise NotImplementedError("Trying to write in a read-only memory") - -class CodeMemory32 (Memory32RO): - def __init__(self, start=0, end=0): - super().__init__(writable=False,start=start,end=end) - - -if __name__ == "__main__": - m = Memory32(start=100,end=200) - print(m.start, m.end) - m.set_byte(100, 246) - print(m) |