Skip to content
Snippets Groups Projects
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})"