import logging from ScEpTIC.emulator.memory.virtual_global_symbol_table import VirtualGlobalSymbolTable from ScEpTIC.emulator.memory.virtual_heap import VirtualHeap from ScEpTIC.emulator.memory.virtual_stack import VirtualStack class VirtualRAM: """ RAM base object. It may contain stack, heap and global symbol table. """ def __init__(self, config): logging.debug('Creating {} memory.'.format(self.ram_type)) self.max_size = config['max_size'] if config['stack']: self.stack = VirtualStack(config['stack_base_address'], config['stack_prefix'], config['stack_mmu']) else: self.stack = None if config['heap']: self.heap = VirtualHeap(config['heap_base_address'], config['heap_prefix'], config['heap_mmu']) else: self.heap = None if config['gst']: self.gst = VirtualGlobalSymbolTable(config['gst_base_address'], config['gst_prefix'], config['gst_mmu']) else: self.gst = None @property def ram_type(self): """ Returns the name of the RAM. """ return self.__class__.__name__ def reset(self): """ Performs the CPU reset operation """ logging.info('Resetting {}'.format(self.ram_type)) if self.stack is not None: self.stack.reset() if self.heap is not None: self.heap.reset() if self.gst is not None: self.gst.reset() def check_memory_size(self): """ Checks memory size """ if self.max_size == 0: return gst_size = 0 stack_size = 0 heap_size = 0 if self.gst is not None: gst_size = self.gst.get_used_size() if self.stack is not None: stack_size = self.stack.get_used_size() if self.heap is not None: heap_size = self.heap.get_used_size() size = gst_size + stack_size + heap_size if size > self.max_size: message = f"Maximum memory size of {self.max_size} bytes exceeded: {size} bytes used.\n" message += f" GST: {gst_size} bytes; Stack: {stack_size} bytes; Heap: {heap_size} bytes" raise Exception(message) class VolatileRAM(VirtualRAM): """ Static RAM. """ pass class NonVolatileRAM(VirtualRAM): """ Non-volatile Memory. """ def reset(self): """ NVM is persistent w.r.t. CPU reset """ return def force_reset(self): """ Forces reset of NVM """ super().reset()