Code owners
Assign users and groups as approvers for specific file changes. Learn more.
module.py 4.27 KiB
from __future__ import annotations
from simudator.core.signal import Signal
class Module:
"""
This class specifies the basic functionality of all module types.
The modules are processor componenets in the processor,
such as ALU, busses, registers and more.
"""
def __init__(self, signals: dict[str, Signal], name: str = "") -> None:
self.name = name
self.signals = signals
for key, signal in self.signals.items():
if key[0:2] == "in":
signal.add_destination(self)
def update_register(self) -> None:
"""
Simulates module behaviour for saving input into the internal state
during a clock tick. Exact behaviour is specifid in each module type.
"""
raise NotImplemented
def output_register(self) -> None:
"""
Simulates module behaviour for giving data to output signals
during a clock tick. Exact behaviour is specifid in each module type.
"""
raise NotImplemented
def update_logic(self) -> None:
"""
Simulates behaviour for sending output using the internal state
during a clock tick. Exact behaviour is specifid in each module type.
"""
raise NotImplemented
def get_state(self) -> dict:
"""
Returns a dict of the module states.
"""
state_dict = dict()
state_dict["name"] = self.name
return state_dict
def get_gui_state(self) -> dict:
"""
Returns a dict of the module states that should be displayed in a GUI.
"""
state_dict = dict()
state_dict["name"] = self.name
return state_dict
def set_state(self, state: dict) -> None:
"""
Sets the modules state to one given in dict. Dict format will be
diffrent for each type of module so use get_state to get correct format.
"""
self.name = state["name"]
def get_output_signals(self) -> list[Signal]:
"""
Returns the modules output signals. Assumes all output signals are
stored with a key beginning in 'out' in the signals dictionary.
"""
return [signal for key, signal in self.signals.items() if key[0:3] == "out"]
def get_input_signals(self) -> list[Signal]:
"""
Returns the modules input signals. Assumes all input signals are stored
with a key beginning in 'in' in the signals dictionary.
"""
return [signal for key, signal in self.signals.items() if key[0:2] == "in"]
def reset(self) -> None:
"""
Resets the module to its default state.
"""
raise NotImplemented
def load_from_str(self, state_string):
"""
Sets the modules state according to a string.
Each module class will parse and set its own state.
"""
raise NotImplemented
def get_longest_line_len(self, ignore_keys=None) -> int:
"""
Helper function for pretty_print that returns the length of
the longest line to print for a module.
"""
if ignore_keys == None:
ignore_keys = []
longest_line_len = 0
state = self.get_state()
for key in state:
if key not in ignore_keys:
line = key + ": " + str(state[key])
if len(line) > longest_line_len:
longest_line_len = len(line)
return longest_line_len
def print_module(self) -> None:
"""
Prints the module directly to terminal
"""
print(self.name)
def _helper_save_state_to_file(self, file_path: str, content: str) -> bool:
"""
Tries to save the content to a given file.
Returns true on success and false otherwise.
"""
try:
with open(file_path, "a") as file:
file.write(content)
file.close()
except OSError:
return False
return True
def save_state_to_file(self, file_path: str) -> bool:
"""
Tries to save the module state to a given file.
Returns true on success and false otherwise.
"""
raise NotImplemented
def __str__(self) -> str:
return self.name
def __repr__(self) -> str:
return f"Module({self.name!r})"