diff --git a/.clang-format b/.clang-format deleted file mode 100644 index 7548f76b9b80cc6c1725505ab0492be1d7e3317a..0000000000000000000000000000000000000000 --- a/.clang-format +++ /dev/null @@ -1,151 +0,0 @@ -AccessModifierOffset: -4 - -AlignAfterOpenBracket: DontAlign -AlignConsecutiveAssignments: false -AlignConsecutiveDeclarations: false -AlignConsecutiveMacros: true -AlignEscapedNewlines: DontAlign -AlignOperands: false -AlignTrailingComments: true - -AllowAllArgumentsOnNextLine: true -AllowAllConstructorInitializersOnNextLine: true -AllowAllParametersOfDeclarationOnNextLine: false -AllowShortBlocksOnASingleLine: Empty -AllowShortCaseLabelsOnASingleLine: true -AllowShortFunctionsOnASingleLine: Empty -AllowShortIfStatementsOnASingleLine: Never -AllowShortLambdasOnASingleLine: Inline -AllowShortLoopsOnASingleLine: false - -AlwaysBreakAfterReturnType: None -AlwaysBreakBeforeMultilineStrings: true -AlwaysBreakTemplateDeclarations: Yes - -BinPackArguments: false -BinPackParameters: true - -BreakBeforeBraces: Custom -BraceWrapping: - AfterCaseLabel: false - AfterClass: false - AfterControlStatement: false - AfterEnum: false - AfterFunction: false - AfterNamespace: false - AfterObjCDeclaration: false - AfterStruct: false - AfterUnion: false - AfterExternBlock: false - BeforeCatch: false - BeforeElse: false - IndentBraces: false - SplitEmptyFunction: false - SplitEmptyRecord: false - SplitEmptyNamespace: true - -BreakBeforeBinaryOperators: None -BreakBeforeTernaryOperators: false -BreakConstructorInitializers: BeforeComma -BreakInheritanceList: BeforeComma -BreakStringLiterals: true - -ColumnLimit: 140 - -CommentPragmas: '' - -CompactNamespaces: false - -ConstructorInitializerAllOnOneLineOrOnePerLine: true -ConstructorInitializerIndentWidth: 4 - -ContinuationIndentWidth: 4 - -Cpp11BracedListStyle: true - -DerivePointerAlignment: false - -DisableFormat: false - -FixNamespaceComments: true - -ForEachMacros: - - Q_FOREACH - - BOOST_FOREACH - - FOREACH - - FOR_EACH - -IncludeBlocks: Regroup -IncludeCategories: - - Regex: '^<' - Priority: 2 - - Regex: '.*' - Priority: 1 -IncludeIsMainRegex: '(_test)?$' - -IndentCaseLabels: true -IndentGotoLabels: false -IndentPPDirectives: None -IndentWidth: 4 -IndentWrappedFunctionNames: false - -KeepEmptyLinesAtTheStartOfBlocks: false - -Language: Cpp - -MacroBlockBegin: '' -MacroBlockEnd: '' - -MaxEmptyLinesToKeep: 1 - -NamespaceIndentation: None -NamespaceMacros: - - NAMESPACE - -PenaltyBreakAssignment: 100 -PenaltyBreakBeforeFirstCallParameter: 10 -PenaltyBreakComment: 10 -PenaltyBreakFirstLessLess: 100 -PenaltyBreakString: 10 -PenaltyBreakTemplateDeclaration: 10000 -PenaltyExcessCharacter: 999999 -PenaltyReturnTypeOnItsOwnLine: 10000 - -PointerAlignment: Left - -ReflowComments: false - -SortIncludes: true -SortUsingDeclarations: true - -SpaceAfterCStyleCast: false -SpaceAfterLogicalNot: false -SpaceAfterTemplateKeyword: true -SpaceBeforeAssignmentOperators: true -SpaceBeforeCpp11BracedList: false -SpaceBeforeCtorInitializerColon: true -SpaceBeforeInheritanceColon: true -SpaceBeforeParens: ControlStatements -SpaceBeforeRangeBasedForLoopColon: true -SpaceInEmptyBlock: false -SpaceInEmptyParentheses: false -SpacesBeforeTrailingComments: 1 -SpacesInAngles: false -SpacesInCStyleCastParentheses: false -SpacesInContainerLiterals: false -SpacesInParentheses: false -SpacesInSquareBrackets: false - -Standard: Cpp11 - -StatementMacros: - - Q_UNUSED - -TabWidth: 4 - -TypenameMacros: - - STACK_OF - - LIST - - LIST_ENTRY - -UseTab: ForContinuationAndIndentation \ No newline at end of file diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 0bdf5476787722ba2007a85c8c73255d56178262..0000000000000000000000000000000000000000 --- a/.gitignore +++ /dev/null @@ -1,33 +0,0 @@ -.vs/ -.vscode/ -build*/ -bin*/ -logs/ -dist/ -CMakeLists.txt.user* -*.autosave -*.creator -*.creator.user* -\#*\# -/.emacs.desktop -/.emacs.desktop.lock -*.elc -auto-save-list -tramp -.\#* -*~ -.fuse_hudden* -.directory -.Trash-* -.nfs* -Thumbs.db -Thumbs.db:encryptable -ehthumbs.db -ehthumbs_vista.db -$RECYCLE.BIN/ -*.stackdump -[Dd]esktop.ini -*.egg-info -__pycache__/ -env/ -venv/ \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3b2095bbac834a11ff4b8d3d5a13ad0f9903a090..6c51653c1a03a663601c9d49afbcd898f7fc86b9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,16 +1,10 @@ -image: python:3.6 - stages: - - test - -before_script: - - apt-get update --yes - - apt-get install --yes build-essential cmake libfmt-dev pybind11-dev - - pip3 install pytest pytest-cov - - pip3 install . - - pip3 show b_asic + - build -run tests: - stage: test +PythonBuild: + stage: build + artifacts: + untracked: true script: - - pytest test \ No newline at end of file + - apt-get update && apt-get install python3 -y + - bash build.sh \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 3471fb4f473b069f9a4f77efec5d7aeb0fc84a79..0000000000000000000000000000000000000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,79 +0,0 @@ -cmake_minimum_required(VERSION 3.8) - -project( - "B-ASIC" - VERSION 0.0.1 - DESCRIPTION "Better ASIC Toolbox for python3" - LANGUAGES C CXX -) - -find_package(fmt 5.2.1 REQUIRED) -find_package(pybind11 CONFIG REQUIRED) - -set(LIBRARY_NAME "b_asic") -set(TARGET_NAME "_${LIBRARY_NAME}") - -if(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY) - include(GNUInstallDirs) - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_INSTALL_LIBDIR}") -endif() -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") -set(CMAKE_PDB_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") -set(CMAKE_PDB_OUTPUT_DIRECTORY_DEBUG "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") -set(CMAKE_PDB_OUTPUT_DIRECTORY_RELEASE "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") - -pybind11_add_module( - "${TARGET_NAME}" - "${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp" -) - -target_include_directories( - "${TARGET_NAME}" - PRIVATE - "${CMAKE_CURRENT_SOURCE_DIR}/src" -) - -target_compile_features( - "${TARGET_NAME}" - PRIVATE - cxx_std_17 -) -target_compile_options( - "${TARGET_NAME}" - PRIVATE - $<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>>: - -W -Wall -Wextra -Werror -Wno-psabi - $<$<CONFIG:Debug>:-g> - $<$<NOT:$<CONFIG:Debug>>:-O3> - > - $<$<CXX_COMPILER_ID:MSVC>: - /W3 /WX /permissive- /utf-8 - $<$<CONFIG:Debug>:/Od> - $<$<NOT:$<CONFIG:Debug>>:/Ot> - > -) - -target_link_libraries( - "${TARGET_NAME}" - PRIVATE - fmt::fmt -) - -add_custom_target( - remove_old_python_dir ALL - COMMAND ${CMAKE_COMMAND} -E remove_directory "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${LIBRARY_NAME}" - COMMENT "Removing old python directory ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${LIBRARY_NAME}" -) -add_custom_target( - copy_python_dir ALL - COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_LIST_DIR}/${LIBRARY_NAME}" "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${LIBRARY_NAME}" - COMMENT "Copying python files to ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${LIBRARY_NAME}" - DEPENDS "${TARGET_NAME}" remove_old_python_dir -) \ No newline at end of file diff --git a/LICENSE b/LICENSE index 669ce41e6f7c3cc001e8f9bb88a86c0dfaf755d9..17010bd5c1e2eb344384a5fa1f4fa6bfc4b72e63 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 TDDD96 PUM4 +Copyright (c) 2020 TDDD96 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index ce996f6c4ffcc6a70d095c24ed296ec3b69e5f43..0000000000000000000000000000000000000000 --- a/MANIFEST.in +++ /dev/null @@ -1,4 +0,0 @@ -include README.md -include LICENSE -include CMakeLists.txt -recursive-include src *.cpp *.h diff --git a/README.md b/README.md index fd98f919202588942a3e8d394b0b461ef63cfe54..20c8c4a23579933ca86a74fade71c015da9a79cf 100644 --- a/README.md +++ b/README.md @@ -1,119 +1,3 @@ -<img src="logo.png" width="278" height="100"> - -# B-ASIC - Better ASIC Toolbox -B-ASIC is an ASIC toolbox for Python 3 that simplifies circuit design and optimization. - -## Development -How to build and debug the library during development. - -### Prerequisites -The following packages are required in order to build the library: -* cmake 3.8+ - * gcc 7+/clang 7+/msvc 16+ - * fmtlib 5.2.1+ - * pybind11 2.3.0+ -* python 3.6+ - * setuptools - * wheel - * pybind11 - * numpy - * pyside2/pyqt5 - -### Using CMake directly -How to build using CMake. - -#### Configuring -In `B-ASIC`: -``` -mkdir build -cd build -cmake .. -``` - -#### Building (Debug) -In `B-ASIC/build`: -``` -cmake --build . -``` -The output gets written to `B-ASIC/build/lib`. - -#### Building (Release) -In `B-ASIC/build`: -``` -cmake --build . --config Release -``` -The output gets written to `B-ASIC/build/lib`. - -### Using setuptools to create a package -How to create a package using setuptools that can be installed using pip. - -#### Setup (Binary distribution) -In `B-ASIC`: -``` -python3 setup.py bdist_wheel -``` -The output gets written to `B-ASIC/dist/b_asic-<version>-<python_tag>-<abi_tag>-<platform_tag>.whl`. - -#### Setup (Source distribution) -In `B-ASIC`: -``` -python3 setup.py sdist -``` -The output gets written to `B-ASIC/dist/b-asic-<version>.tar.gz`. - -#### Installation (Binary distribution) -In `B-ASIC/dist`: -``` -pip install b_asic-<version>-<python_tag>-<abi_tag>-<platform_tag>.whl -``` - -#### Installation (Source distribution) -In `B-ASIC/dist`: -``` -pip install b-asic-<version>.tar.gz -``` - -### Running tests -How to run the tests using pytest in a virtual environment. - -#### Linux/OS X -In `B-ASIC`: -``` -python3 -m venv env -source env/bin/activate -pip install . -pytest -``` - -#### Windows -In `B-ASIC` (as admin): -``` -python3 -m venv env -.\env\Scripts\activate.bat -pip install . -pytest -``` - -#### Test with coverage -``` -pytest --cov=b_asic --cov-report html test -``` - -## Usage -How to build and use the library as a user. - -### Installation -``` -pip install b_asic -``` - -### Importing -``` -python3 ->>> import b_asic as asic ->>> help(asic) -``` - -## License -B-ASIC is distributed under the MIT license. -See the included LICENSE file for more information. +<img src="https://files.slack.com/files-pri/TSHPRJY83-FTTRW9MQ8/b-asic-logo-opaque.png" width="318" height="100"> +<br> +<h3>B-ASIC is an ASIC toolbox for Python 3 that simplifies circuit design and optimization.<h3> \ No newline at end of file diff --git a/b_asic/__init__.py b/b_asic/__init__.py deleted file mode 100644 index 7e40ad52cdc51da3e1d91964ad55cfc90e12a34a..0000000000000000000000000000000000000000 --- a/b_asic/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -""" -Better ASIC Toolbox. -TODO: More info. -""" -from b_asic.core_operations import * -from b_asic.graph_component import * -from b_asic.graph_id import * -from b_asic.operation import * -from b_asic.precedence_chart import * -from b_asic.port import * -from b_asic.schema import * -from b_asic.signal_flow_graph import * -from b_asic.signal import * -from b_asic.simulation import * diff --git a/b_asic/core_operations.py b/b_asic/core_operations.py deleted file mode 100644 index 8902b169c07e600a843e526d44452fb9386ff7a9..0000000000000000000000000000000000000000 --- a/b_asic/core_operations.py +++ /dev/null @@ -1,337 +0,0 @@ -"""@package docstring -B-ASIC Core Operations Module. -TODO: More info. -""" - -from numbers import Number -from typing import Any -from numpy import conjugate, sqrt, abs as np_abs -from b_asic.port import InputPort, OutputPort -from b_asic.graph_id import GraphIDType -from b_asic.operation import AbstractOperation -from b_asic.graph_component import Name, TypeName - - -class Input(AbstractOperation): - """Input operation. - TODO: More info. - """ - - # TODO: Implement all functions. - - @property - def type_name(self) -> TypeName: - return "in" - - -class Constant(AbstractOperation): - """Constant value operation. - TODO: More info. - """ - - def __init__(self, value: Number = 0, name: Name = ""): - super().__init__(name) - - self._output_ports = [OutputPort(0, self)] - self._parameters["value"] = value - - def evaluate(self): - return self.param("value") - - @property - def type_name(self) -> TypeName: - return "c" - - -class Addition(AbstractOperation): - """Binary addition operation. - TODO: More info. - """ - - def __init__(self, source1: OutputPort = None, source2: OutputPort = None, name: Name = ""): - super().__init__(name) - - self._input_ports = [InputPort(0, self), InputPort(1, self)] - self._output_ports = [OutputPort(0, self)] - - if source1 is not None: - self._input_ports[0].connect(source1) - if source2 is not None: - self._input_ports[1].connect(source2) - - def evaluate(self, a, b): - return a + b - - @property - def type_name(self) -> TypeName: - return "add" - - -class Subtraction(AbstractOperation): - """Binary subtraction operation. - TODO: More info. - """ - - def __init__(self, source1: OutputPort = None, source2: OutputPort = None, name: Name = ""): - super().__init__(name) - self._input_ports = [InputPort(0, self), InputPort(1, self)] - self._output_ports = [OutputPort(0, self)] - - if source1 is not None: - self._input_ports[0].connect(source1) - if source2 is not None: - self._input_ports[1].connect(source2) - - def evaluate(self, a, b): - return a - b - - @property - def type_name(self) -> TypeName: - return "sub" - - -class Multiplication(AbstractOperation): - """Binary multiplication operation. - TODO: More info. - """ - - def __init__(self, source1: OutputPort = None, source2: OutputPort = None, name: Name = ""): - super().__init__(name) - self._input_ports = [InputPort(0, self), InputPort(1, self)] - self._output_ports = [OutputPort(0, self)] - - if source1 is not None: - self._input_ports[0].connect(source1) - if source2 is not None: - self._input_ports[1].connect(source2) - - def evaluate(self, a, b): - return a * b - - @property - def type_name(self) -> TypeName: - return "mul" - - -class Division(AbstractOperation): - """Binary division operation. - TODO: More info. - """ - - def __init__(self, source1: OutputPort = None, source2: OutputPort = None, name: Name = ""): - super().__init__(name) - self._input_ports = [InputPort(0, self), InputPort(1, self)] - self._output_ports = [OutputPort(0, self)] - - if source1 is not None: - self._input_ports[0].connect(source1) - if source2 is not None: - self._input_ports[1].connect(source2) - - def evaluate(self, a, b): - return a / b - - @property - def type_name(self) -> TypeName: - return "div" - - -class SquareRoot(AbstractOperation): - """Unary square root operation. - TODO: More info. - """ - - def __init__(self, source1: OutputPort = None, name: Name = ""): - super().__init__(name) - self._input_ports = [InputPort(0, self)] - self._output_ports = [OutputPort(0, self)] - - if source1 is not None: - self._input_ports[0].connect(source1) - - def evaluate(self, a): - return sqrt((complex)(a)) - - @property - def type_name(self) -> TypeName: - return "sqrt" - - -class ComplexConjugate(AbstractOperation): - """Unary complex conjugate operation. - TODO: More info. - """ - - def __init__(self, source1: OutputPort = None, name: Name = ""): - super().__init__(name) - self._input_ports = [InputPort(0, self)] - self._output_ports = [OutputPort(0, self)] - - if source1 is not None: - self._input_ports[0].connect(source1) - - def evaluate(self, a): - return conjugate(a) - - @property - def type_name(self) -> TypeName: - return "conj" - - -class Max(AbstractOperation): - """Binary max operation. - TODO: More info. - """ - - def __init__(self, source1: OutputPort = None, source2: OutputPort = None, name: Name = ""): - super().__init__(name) - self._input_ports = [InputPort(0, self), InputPort(1, self)] - self._output_ports = [OutputPort(0, self)] - - if source1 is not None: - self._input_ports[0].connect(source1) - if source2 is not None: - self._input_ports[1].connect(source2) - - def evaluate(self, a, b): - assert not isinstance(a, complex) and not isinstance(b, complex), \ - ("core_operations.Max does not support complex numbers.") - return a if a > b else b - - @property - def type_name(self) -> TypeName: - return "max" - - -class Min(AbstractOperation): - """Binary min operation. - TODO: More info. - """ - - def __init__(self, source1: OutputPort = None, source2: OutputPort = None, name: Name = ""): - super().__init__(name) - self._input_ports = [InputPort(0, self), InputPort(1, self)] - self._output_ports = [OutputPort(0, self)] - - if source1 is not None: - self._input_ports[0].connect(source1) - if source2 is not None: - self._input_ports[1].connect(source2) - - def evaluate(self, a, b): - assert not isinstance(a, complex) and not isinstance(b, complex), \ - ("core_operations.Min does not support complex numbers.") - return a if a < b else b - - @property - def type_name(self) -> TypeName: - return "min" - - -class Absolute(AbstractOperation): - """Unary absolute value operation. - TODO: More info. - """ - - def __init__(self, source1: OutputPort = None, name: Name = ""): - super().__init__(name) - self._input_ports = [InputPort(0, self)] - self._output_ports = [OutputPort(0, self)] - - if source1 is not None: - self._input_ports[0].connect(source1) - - def evaluate(self, a): - return np_abs(a) - - @property - def type_name(self) -> TypeName: - return "abs" - - -class ConstantMultiplication(AbstractOperation): - """Unary constant multiplication operation. - TODO: More info. - """ - - def __init__(self, coefficient: Number, source1: OutputPort = None, name: Name = ""): - super().__init__(name) - self._input_ports = [InputPort(0, self)] - self._output_ports = [OutputPort(0, self)] - self._parameters["coefficient"] = coefficient - - if source1 is not None: - self._input_ports[0].connect(source1) - - def evaluate(self, a): - return a * self.param("coefficient") - - @property - def type_name(self) -> TypeName: - return "cmul" - - -class ConstantAddition(AbstractOperation): - """Unary constant addition operation. - TODO: More info. - """ - - def __init__(self, coefficient: Number, source1: OutputPort = None, name: Name = ""): - super().__init__(name) - self._input_ports = [InputPort(0, self)] - self._output_ports = [OutputPort(0, self)] - self._parameters["coefficient"] = coefficient - - if source1 is not None: - self._input_ports[0].connect(source1) - - def evaluate(self, a): - return a + self.param("coefficient") - - @property - def type_name(self) -> TypeName: - return "cadd" - - -class ConstantSubtraction(AbstractOperation): - """Unary constant subtraction operation. - TODO: More info. - """ - - def __init__(self, coefficient: Number, source1: OutputPort = None, name: Name = ""): - super().__init__(name) - self._input_ports = [InputPort(0, self)] - self._output_ports = [OutputPort(0, self)] - self._parameters["coefficient"] = coefficient - - if source1 is not None: - self._input_ports[0].connect(source1) - - def evaluate(self, a): - return a - self.param("coefficient") - - @property - def type_name(self) -> TypeName: - return "csub" - - -class ConstantDivision(AbstractOperation): - """Unary constant division operation. - TODO: More info. - """ - - def __init__(self, coefficient: Number, source1: OutputPort = None, name: Name = ""): - super().__init__(name) - self._input_ports = [InputPort(0, self)] - self._output_ports = [OutputPort(0, self)] - self._parameters["coefficient"] = coefficient - - if source1 is not None: - self._input_ports[0].connect(source1) - - def evaluate(self, a): - return a / self.param("coefficient") - - @property - def type_name(self) -> TypeName: - return "cdiv" diff --git a/b_asic/graph_component.py b/b_asic/graph_component.py deleted file mode 100644 index 1987d4491e12089fec401eedc14fb91a7274252e..0000000000000000000000000000000000000000 --- a/b_asic/graph_component.py +++ /dev/null @@ -1,54 +0,0 @@ -"""@package docstring -B-ASIC Operation Module. -TODO: More info. -""" - -from abc import ABC, abstractmethod -from typing import NewType - -Name = NewType("Name", str) -TypeName = NewType("TypeName", str) - - -class GraphComponent(ABC): - """Graph component interface. - TODO: More info. - """ - - @property - @abstractmethod - def type_name(self) -> TypeName: - """Return the type name of the graph component""" - raise NotImplementedError - - @property - @abstractmethod - def name(self) -> Name: - """Return the name of the graph component.""" - raise NotImplementedError - - @name.setter - @abstractmethod - def name(self, name: Name) -> None: - """Set the name of the graph component to the entered name.""" - raise NotImplementedError - - -class AbstractGraphComponent(GraphComponent): - """Abstract Graph Component class which is a component of a signal flow graph. - - TODO: More info. - """ - - _name: Name - - def __init__(self, name: Name = ""): - self._name = name - - @property - def name(self) -> Name: - return self._name - - @name.setter - def name(self, name: Name) -> None: - self._name = name diff --git a/b_asic/graph_id.py b/b_asic/graph_id.py deleted file mode 100644 index 8da6a9d4af6a1bee25125904527a2fd3a374ab90..0000000000000000000000000000000000000000 --- a/b_asic/graph_id.py +++ /dev/null @@ -1,26 +0,0 @@ -"""@package docstring -B-ASIC Graph ID module for handling IDs of different objects in a graph. -TODO: More info -""" - -from collections import defaultdict -from typing import NewType, DefaultDict - -GraphID = NewType("GraphID", str) -GraphIDType = NewType("GraphIDType", str) -GraphIDNumber = NewType("GraphIDNumber", int) - - -class GraphIDGenerator: - """A class that generates Graph IDs for objects.""" - - _next_id_number: DefaultDict[GraphIDType, GraphIDNumber] - - def __init__(self): - self._next_id_number = defaultdict(lambda: 1) # Initalises every key element to 1 - - def get_next_id(self, graph_id_type: GraphIDType) -> GraphID: - """Return the next graph id for a certain graph id type.""" - graph_id = graph_id_type + str(self._next_id_number[graph_id_type]) - self._next_id_number[graph_id_type] += 1 # Increase the current id number - return graph_id diff --git a/b_asic/operation.py b/b_asic/operation.py deleted file mode 100644 index 5578e3c48edcf15594d6d1cd71e71a17521eca25..0000000000000000000000000000000000000000 --- a/b_asic/operation.py +++ /dev/null @@ -1,268 +0,0 @@ -"""@package docstring -B-ASIC Operation Module. -TODO: More info. -""" - -from abc import abstractmethod -from numbers import Number -from typing import List, Dict, Optional, Any, Set, TYPE_CHECKING -from collections import deque - -from b_asic.graph_component import GraphComponent, AbstractGraphComponent, Name -from b_asic.simulation import SimulationState, OperationState -from b_asic.signal import Signal - -if TYPE_CHECKING: - from b_asic.port import InputPort, OutputPort - - -class Operation(GraphComponent): - """Operation interface. - TODO: More info. - """ - - @abstractmethod - def inputs(self) -> "List[InputPort]": - """Get a list of all input ports.""" - raise NotImplementedError - - @abstractmethod - def outputs(self) -> "List[OutputPort]": - """Get a list of all output ports.""" - raise NotImplementedError - - @abstractmethod - def input_count(self) -> int: - """Get the number of input ports.""" - raise NotImplementedError - - @abstractmethod - def output_count(self) -> int: - """Get the number of output ports.""" - raise NotImplementedError - - @abstractmethod - def input(self, i: int) -> "InputPort": - """Get the input port at index i.""" - raise NotImplementedError - - @abstractmethod - def output(self, i: int) -> "OutputPort": - """Get the output port at index i.""" - raise NotImplementedError - - @abstractmethod - def params(self) -> Dict[str, Optional[Any]]: - """Get a dictionary of all parameter values.""" - raise NotImplementedError - - @abstractmethod - def param(self, name: str) -> Optional[Any]: - """Get the value of a parameter. - Returns None if the parameter is not defined. - """ - raise NotImplementedError - - @abstractmethod - def set_param(self, name: str, value: Any) -> None: - """Set the value of a parameter. - The parameter must be defined. - """ - raise NotImplementedError - - @abstractmethod - def evaluate_outputs(self, state: "SimulationState") -> List[Number]: - """Simulate the circuit until its iteration count matches that of the simulation state, - then return the resulting output vector. - """ - raise NotImplementedError - - @abstractmethod - def split(self) -> "List[Operation]": - """Split the operation into multiple operations. - If splitting is not possible, this may return a list containing only the operation itself. - """ - raise NotImplementedError - - @property - @abstractmethod - def neighbors(self) -> "List[Operation]": - """Return all operations that are connected by signals to this operation. - If no neighbors are found, this returns an empty list. - """ - raise NotImplementedError - - -class AbstractOperation(Operation, AbstractGraphComponent): - """Generic abstract operation class which most implementations will derive from. - TODO: More info. - """ - - _input_ports: List["InputPort"] - _output_ports: List["OutputPort"] - _parameters: Dict[str, Optional[Any]] - - def __init__(self, name: Name = ""): - super().__init__(name) - self._input_ports = [] - self._output_ports = [] - self._parameters = {} - - @abstractmethod - def evaluate(self, *inputs) -> Any: # pylint: disable=arguments-differ - """Evaluate the operation and generate a list of output values given a - list of input values. - """ - raise NotImplementedError - - def inputs(self) -> List["InputPort"]: - return self._input_ports.copy() - - def outputs(self) -> List["OutputPort"]: - return self._output_ports.copy() - - def input_count(self) -> int: - return len(self._input_ports) - - def output_count(self) -> int: - return len(self._output_ports) - - def input(self, i: int) -> "InputPort": - return self._input_ports[i] - - def output(self, i: int) -> "OutputPort": - return self._output_ports[i] - - def params(self) -> Dict[str, Optional[Any]]: - return self._parameters.copy() - - def param(self, name: str) -> Optional[Any]: - return self._parameters.get(name) - - def set_param(self, name: str, value: Any) -> None: - assert name in self._parameters # TODO: Error message. - self._parameters[name] = value - - def evaluate_outputs(self, state: SimulationState) -> List[Number]: - # TODO: Check implementation. - input_count: int = self.input_count() - output_count: int = self.output_count() - assert input_count == len(self._input_ports) # TODO: Error message. - assert output_count == len(self._output_ports) # TODO: Error message. - - self_state: OperationState = state.operation_states[self] - - while self_state.iteration < state.iteration: - input_values: List[Number] = [0] * input_count - for i in range(input_count): - source: Signal = self._input_ports[i].signal - input_values[i] = source.operation.evaluate_outputs(state)[ - source.port_index] - - self_state.output_values = self.evaluate(input_values) - # TODO: Error message. - assert len(self_state.output_values) == output_count - self_state.iteration += 1 - for i in range(output_count): - for signal in self._output_ports[i].signals(): - destination: Signal = signal.destination - destination.evaluate_outputs(state) - - return self_state.output_values - - def split(self) -> List[Operation]: - # TODO: Check implementation. - results = self.evaluate(self._input_ports) - if all(isinstance(e, Operation) for e in results): - return results - return [self] - - @property - def neighbors(self) -> List[Operation]: - neighbors: List[Operation] = [] - for port in self._input_ports: - for signal in port.signals: - neighbors.append(signal.source.operation) - - for port in self._output_ports: - for signal in port.signals: - neighbors.append(signal.destination.operation) - - return neighbors - - def traverse(self) -> Operation: - """Traverse the operation tree and return a generator with start point in the operation.""" - return self._breadth_first_search() - - def _breadth_first_search(self) -> Operation: - """Use breadth first search to traverse the operation tree.""" - visited: Set[Operation] = {self} - queue = deque([self]) - while queue: - operation = queue.popleft() - yield operation - for n_operation in operation.neighbors: - if n_operation not in visited: - visited.add(n_operation) - queue.append(n_operation) - - def __add__(self, other): - """Overloads the addition operator to make it return a new Addition operation - object that is connected to the self and other objects. If other is a number then - returns a ConstantAddition operation object instead. - """ - # Import here to avoid circular imports. - from b_asic.core_operations import Addition, ConstantAddition - - if isinstance(other, Operation): - return Addition(self.output(0), other.output(0)) - elif isinstance(other, Number): - return ConstantAddition(other, self.output(0)) - else: - raise TypeError("Other type is not an Operation or a Number.") - - def __sub__(self, other): - """Overloads the subtraction operator to make it return a new Subtraction operation - object that is connected to the self and other objects. If other is a number then - returns a ConstantSubtraction operation object instead. - """ - # Import here to avoid circular imports. - from b_asic.core_operations import Subtraction, ConstantSubtraction - - if isinstance(other, Operation): - return Subtraction(self.output(0), other.output(0)) - elif isinstance(other, Number): - return ConstantSubtraction(other, self.output(0)) - else: - raise TypeError("Other type is not an Operation or a Number.") - - def __mul__(self, other): - """Overloads the multiplication operator to make it return a new Multiplication operation - object that is connected to the self and other objects. If other is a number then - returns a ConstantMultiplication operation object instead. - """ - # Import here to avoid circular imports. - from b_asic.core_operations import Multiplication, ConstantMultiplication - - if isinstance(other, Operation): - return Multiplication(self.output(0), other.output(0)) - elif isinstance(other, Number): - return ConstantMultiplication(other, self.output(0)) - else: - raise TypeError("Other type is not an Operation or a Number.") - - def __truediv__(self, other): - """Overloads the division operator to make it return a new Division operation - object that is connected to the self and other objects. If other is a number then - returns a ConstantDivision operation object instead. - """ - # Import here to avoid circular imports. - from b_asic.core_operations import Division, ConstantDivision - - if isinstance(other, Operation): - return Division(self.output(0), other.output(0)) - elif isinstance(other, Number): - return ConstantDivision(other, self.output(0)) - else: - raise TypeError("Other type is not an Operation or a Number.") - diff --git a/b_asic/port.py b/b_asic/port.py deleted file mode 100644 index c22053df1928cf2f6ea32c4880816d551b85836a..0000000000000000000000000000000000000000 --- a/b_asic/port.py +++ /dev/null @@ -1,223 +0,0 @@ -"""@package docstring -B-ASIC Port Module. -TODO: More info. -""" - -from abc import ABC, abstractmethod -from typing import NewType, Optional, List - -from b_asic.operation import Operation -from b_asic.signal import Signal - -PortIndex = NewType("PortIndex", int) - -class Port(ABC): - """Port Interface. - - TODO: More documentaiton? - """ - - @property - @abstractmethod - def operation(self) -> Operation: - """Return the connected operation.""" - raise NotImplementedError - - @property - @abstractmethod - def index(self) -> PortIndex: - """Return the unique PortIndex.""" - raise NotImplementedError - - @property - @abstractmethod - def signals(self) -> List[Signal]: - """Return a list of all connected signals.""" - raise NotImplementedError - - @abstractmethod - def signal(self, i: int = 0) -> Signal: - """Return the connected signal at index i. - - Keyword argumens: - i: integer index of the signal requsted. - """ - raise NotImplementedError - - @property - @abstractmethod - def connected_ports(self) -> List["Port"]: - """Return a list of all connected Ports.""" - raise NotImplementedError - - @abstractmethod - def signal_count(self) -> int: - """Return the number of connected signals.""" - raise NotImplementedError - - @abstractmethod - def connect(self, port: "Port") -> Signal: - """Create and return a signal that is connected to this port and the entered - port and connect this port to the signal and the entered port to the signal.""" - raise NotImplementedError - - @abstractmethod - def add_signal(self, signal: Signal) -> None: - """Connect this port to the entered signal. If the entered signal isn't connected to - this port then connect the entered signal to the port aswell.""" - raise NotImplementedError - - @abstractmethod - def disconnect(self, port: "Port") -> None: - """Disconnect the entered port from the port by removing it from the ports signal. - If the entered port is still connected to this ports signal then disconnect the entered - port from the signal aswell.""" - raise NotImplementedError - - @abstractmethod - def remove_signal(self, signal: Signal) -> None: - """Remove the signal that was entered from the Ports signals. - If the entered signal still is connected to this port then disconnect the - entered signal from the port aswell. - - Keyword arguments: - - signal: Signal to remove. - """ - raise NotImplementedError - - @abstractmethod - def clear(self) -> None: - """Removes all connected signals from the Port.""" - raise NotImplementedError - - -class AbstractPort(Port): - """Abstract port class. - - Handles functionality for port id and saves the connection to the parent operation. - """ - - _index: int - _operation: Operation - - def __init__(self, index: int, operation: Operation): - self._index = index - self._operation = operation - - @property - def operation(self) -> Operation: - return self._operation - - @property - def index(self) -> PortIndex: - return self._index - - -class InputPort(AbstractPort): - """Input port. - TODO: More info. - """ - - _source_signal: Optional[Signal] - - def __init__(self, port_id: PortIndex, operation: Operation): - super().__init__(port_id, operation) - self._source_signal = None - - @property - def signals(self) -> List[Signal]: - return [] if self._source_signal is None else [self._source_signal] - - def signal(self, i: int = 0) -> Signal: - assert 0 <= i < self.signal_count(), "Signal index out of bound." - assert self._source_signal is not None, "No Signal connect to InputPort." - return self._source_signal - - @property - def connected_ports(self) -> List[Port]: - return [] if self._source_signal is None or self._source_signal.source is None \ - else [self._source_signal.source] - - def signal_count(self) -> int: - return 0 if self._source_signal is None else 1 - - def connect(self, port: "OutputPort") -> Signal: - assert self._source_signal is None, "Connecting new port to already connected input port." - return Signal(port, self) # self._source_signal is set by the signal constructor - - def add_signal(self, signal: Signal) -> None: - assert self._source_signal is None, "Connecting new port to already connected input port." - self._source_signal: Signal = signal - if self is not signal.destination: - # Connect this inputport as destination for this signal if it isn't already. - signal.set_destination(self) - - def disconnect(self, port: "OutputPort") -> None: - assert self._source_signal.source is port, "The entered port is not connected to this port." - self._source_signal.remove_source() - - def remove_signal(self, signal: Signal) -> None: - old_signal: Signal = self._source_signal - self._source_signal = None - if self is old_signal.destination: - # Disconnect the dest of the signal if this inputport currently is the dest - old_signal.remove_destination() - - def clear(self) -> None: - self.remove_signal(self._source_signal) - -class OutputPort(AbstractPort): - """Output port. - TODO: More info. - """ - - _destination_signals: List[Signal] - - def __init__(self, port_id: PortIndex, operation: Operation): - super().__init__(port_id, operation) - self._destination_signals = [] - - @property - def signals(self) -> List[Signal]: - return self._destination_signals.copy() - - def signal(self, i: int = 0) -> Signal: - assert 0 <= i < self.signal_count(), "Signal index out of bounds." - return self._destination_signals[i] - - @property - def connected_ports(self) -> List[Port]: - return [signal.destination for signal in self._destination_signals \ - if signal.destination is not None] - - def signal_count(self) -> int: - return len(self._destination_signals) - - def connect(self, port: InputPort) -> Signal: - return Signal(self, port) # Signal is added to self._destination_signals in signal constructor - - def add_signal(self, signal: Signal) -> None: - assert signal not in self.signals, \ - "Attempting to connect to Signal already connected." - self._destination_signals.append(signal) - if self is not signal.source: - # Connect this outputport to the signal if it isn't already - signal.set_source(self) - - def disconnect(self, port: InputPort) -> None: - assert port in self.connected_ports, "Attempting to disconnect port that isn't connected." - for sig in self._destination_signals: - if sig.destination is port: - sig.remove_destination() - break - - def remove_signal(self, signal: Signal) -> None: - i: int = self._destination_signals.index(signal) - old_signal: Signal = self._destination_signals[i] - del self._destination_signals[i] - if self is old_signal.source: - old_signal.remove_source() - - def clear(self) -> None: - for signal in self._destination_signals: - self.remove_signal(signal) diff --git a/b_asic/precedence_chart.py b/b_asic/precedence_chart.py deleted file mode 100644 index be55a123e0ab4330057c0bb62581e45195f5e5ba..0000000000000000000000000000000000000000 --- a/b_asic/precedence_chart.py +++ /dev/null @@ -1,21 +0,0 @@ -"""@package docstring -B-ASIC Precedence Chart Module. -TODO: More info. -""" - -from b_asic.signal_flow_graph import SFG - - -class PrecedenceChart: - """Precedence chart constructed from a signal flow graph. - TODO: More info. - """ - - sfg: SFG - # TODO: More members. - - def __init__(self, sfg: SFG): - self.sfg = sfg - # TODO: Implement. - - # TODO: More stuff. diff --git a/b_asic/schema.py b/b_asic/schema.py deleted file mode 100644 index e5068cdc080c5c5004c44c885ac48f52ba44c1f3..0000000000000000000000000000000000000000 --- a/b_asic/schema.py +++ /dev/null @@ -1,21 +0,0 @@ -"""@package docstring -B-ASIC Schema Module. -TODO: More info. -""" - -from b_asic.precedence_chart import PrecedenceChart - - -class Schema: - """Schema constructed from a precedence chart. - TODO: More info. - """ - - pc: PrecedenceChart - # TODO: More members. - - def __init__(self, pc: PrecedenceChart): - self.pc = pc - # TODO: Implement. - - # TODO: More stuff. diff --git a/b_asic/signal.py b/b_asic/signal.py deleted file mode 100644 index 64c259486abd78e3b18ea824b58bfabe271f50d8..0000000000000000000000000000000000000000 --- a/b_asic/signal.py +++ /dev/null @@ -1,96 +0,0 @@ -"""@package docstring -B-ASIC Signal Module. -""" -from typing import Optional, TYPE_CHECKING - -from b_asic.graph_component import AbstractGraphComponent, TypeName, Name - -if TYPE_CHECKING: - from b_asic.port import InputPort, OutputPort - - -class Signal(AbstractGraphComponent): - """A connection between two ports.""" - - _source: "OutputPort" - _destination: "InputPort" - - def __init__(self, source: Optional["OutputPort"] = None, \ - destination: Optional["InputPort"] = None, name: Name = ""): - - super().__init__(name) - - self._source = source - self._destination = destination - - if source is not None: - self.set_source(source) - - if destination is not None: - self.set_destination(destination) - - @property - def source(self) -> "OutputPort": - """Return the source OutputPort of the signal.""" - return self._source - - @property - def destination(self) -> "InputPort": - """Return the destination "InputPort" of the signal.""" - return self._destination - - def set_source(self, src: "OutputPort") -> None: - """Disconnect the previous source OutputPort of the signal and - connect to the entered source OutputPort. Also connect the entered - source port to the signal if it hasn't already been connected. - - Keyword arguments: - - src: OutputPort to connect as source to the signal. - """ - self.remove_source() - self._source = src - if self not in src.signals: - # If the new source isn't connected to this signal then connect it. - src.add_signal(self) - - def set_destination(self, dest: "InputPort") -> None: - """Disconnect the previous destination InputPort of the signal and - connect to the entered destination InputPort. Also connect the entered - destination port to the signal if it hasn't already been connected. - - Keywords argments: - - dest: InputPort to connect as destination to the signal. - """ - self.remove_destination() - self._destination = dest - if self not in dest.signals: - # If the new destination isn't connected to tis signal then connect it. - dest.add_signal(self) - - @property - def type_name(self) -> TypeName: - return "s" - - def remove_source(self) -> None: - """Disconnect the source OutputPort of the signal. If the source port - still is connected to this signal then also disconnect the source port.""" - if self._source is not None: - old_source: "OutputPort" = self._source - self._source = None - if self in old_source.signals: - # If the old destination port still is connected to this signal, then disconnect it. - old_source.remove_signal(self) - - def remove_destination(self) -> None: - """Disconnect the destination InputPort of the signal.""" - if self._destination is not None: - old_destination: "InputPort" = self._destination - self._destination = None - if self in old_destination.signals: - # If the old destination port still is connected to this signal, then disconnect it. - old_destination.remove_signal(self) - - def is_connected(self) -> bool: - """Returns true if the signal is connected to both a source and a destination, - else false.""" - return self._source is not None and self._destination is not None diff --git a/b_asic/signal_flow_graph.py b/b_asic/signal_flow_graph.py deleted file mode 100644 index 9c08aecc40ff77b8fe90051b6ea165c0f1703b9b..0000000000000000000000000000000000000000 --- a/b_asic/signal_flow_graph.py +++ /dev/null @@ -1,91 +0,0 @@ -"""@package docstring -B-ASIC Signal Flow Graph Module. -TODO: More info. -""" - -from typing import List, Dict, Optional, DefaultDict -from collections import defaultdict - -from b_asic.operation import Operation -from b_asic.operation import AbstractOperation -from b_asic.signal import Signal -from b_asic.graph_id import GraphIDGenerator, GraphID -from b_asic.graph_component import GraphComponent, Name, TypeName - - -class SFG(AbstractOperation): - """Signal flow graph. - TODO: More info. - """ - - _graph_components_by_id: Dict[GraphID, GraphComponent] - _graph_components_by_name: DefaultDict[Name, List[GraphComponent]] - _graph_id_generator: GraphIDGenerator - - def __init__(self, input_signals: List[Signal] = None, output_signals: List[Signal] = None, \ - ops: List[Operation] = None, **kwds): - super().__init__(**kwds) - if input_signals is None: - input_signals = [] - if output_signals is None: - output_signals = [] - if ops is None: - ops = [] - - self._graph_components_by_id = dict() # Maps Graph ID to objects - self._graph_components_by_name = defaultdict(list) # Maps Name to objects - self._graph_id_generator = GraphIDGenerator() - - for operation in ops: - self._add_graph_component(operation) - - for input_signal in input_signals: - self._add_graph_component(input_signal) - - # TODO: Construct SFG based on what inputs that were given - # TODO: Traverse the graph between the inputs/outputs and add to self._operations. - # TODO: Connect ports with signals with appropriate IDs. - - def evaluate(self, *inputs) -> list: - return [] # TODO: Implement - - def _add_graph_component(self, graph_component: GraphComponent) -> GraphID: - """Add the entered graph component to the SFG's dictionary of graph objects and - return a generated GraphID for it. - - Keyword arguments: - graph_component: Graph component to add to the graph. - """ - # Add to name dict - self._graph_components_by_name[graph_component.name].append(graph_component) - - # Add to ID dict - graph_id: GraphID = self._graph_id_generator.get_next_id(graph_component.type_name) - self._graph_components_by_id[graph_id] = graph_component - return graph_id - - def find_by_id(self, graph_id: GraphID) -> Optional[GraphComponent]: - """Find a graph object based on the entered Graph ID and return it. If no graph - object with the entered ID was found then return None. - - Keyword arguments: - graph_id: Graph ID of the wanted object. - """ - if graph_id in self._graph_components_by_id: - return self._graph_components_by_id[graph_id] - - return None - - def find_by_name(self, name: Name) -> List[GraphComponent]: - """Find all graph objects that have the entered name and return them - in a list. If no graph object with the entered name was found then return an - empty list. - - Keyword arguments: - name: Name of the wanted object. - """ - return self._graph_components_by_name[name] - - @property - def type_name(self) -> TypeName: - return "sfg" diff --git a/b_asic/simulation.py b/b_asic/simulation.py deleted file mode 100644 index 50adaa522b6d685b428354a9f84689330b7fd40f..0000000000000000000000000000000000000000 --- a/b_asic/simulation.py +++ /dev/null @@ -1,35 +0,0 @@ -"""@package docstring -B-ASIC Simulation Module. -TODO: More info. -""" - -from numbers import Number -from typing import List - - -class OperationState: - """Simulation state of an operation. - TODO: More info. - """ - - output_values: List[Number] - iteration: int - - def __init__(self): - self.output_values = [] - self.iteration = 0 - - -class SimulationState: - """Simulation state. - TODO: More info. - """ - - # operation_states: Dict[OperationId, OperationState] - iteration: int - - def __init__(self): - self.operation_states = {} - self.iteration = 0 - - # TODO: More stuff. diff --git a/build.sh b/build.sh new file mode 100644 index 0000000000000000000000000000000000000000..1015ced245f71f0f85cad0da8ae562acb0d7a550 --- /dev/null +++ b/build.sh @@ -0,0 +1,5 @@ +#! bin/sh +for n in `find . -name "*.py"` +do + python3 $n +done \ No newline at end of file diff --git a/logo.png b/logo.png deleted file mode 100644 index b1bd78fe7eb8a737ac8153576078d61492c2e9a3..0000000000000000000000000000000000000000 Binary files a/logo.png and /dev/null differ diff --git a/setup.py b/setup.py deleted file mode 100644 index 43d55d40a95212196facb973ebc97a1bdc5e7f42..0000000000000000000000000000000000000000 --- a/setup.py +++ /dev/null @@ -1,80 +0,0 @@ -import os -import sys -import shutil -import subprocess -import setuptools -from setuptools import Extension -from setuptools.command.build_ext import build_ext - -CMAKE_EXE = os.environ.get('CMAKE_EXE', shutil.which('cmake')) - -class CMakeExtension(Extension): - def __init__(self, name, sourcedir = ""): - super().__init__(name, sources=[]) - self.sourcedir = os.path.abspath(sourcedir) - -class CMakeBuild(build_ext): - def build_extension(self, ext): - if not isinstance(ext, CMakeExtension): - return super().build_extension(ext) - - if not CMAKE_EXE: - raise RuntimeError(f"Cannot build extension {ext.name}: CMake executable not found! Set the CMAKE_EXE environment variable or update your path.") - - cmake_build_type = "Debug" if self.debug else "Release" - cmake_output_dir = os.path.abspath(os.path.dirname(self.get_ext_fullpath(ext.name))) - cmake_configure_argv = [ - CMAKE_EXE, ext.sourcedir, - "-DCMAKE_BUILD_TYPE=" + cmake_build_type, - "-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=" + cmake_output_dir, - "-DPYTHON_EXECUTABLE=" + sys.executable, - ] - cmake_build_argv = [ - CMAKE_EXE, "--build", ".", - "--config", cmake_build_type - ] - - if not os.path.exists(self.build_temp): - os.makedirs(self.build_temp) - - env = os.environ.copy() - - print(f"=== Configuring {ext.name} ===") - print(f"Temp dir: {self.build_temp}") - print(f"Output dir: {cmake_output_dir}") - subprocess.check_call(cmake_configure_argv, cwd=self.build_temp, env=env) - - print(f"=== Building {ext.name} ===") - print(f"Temp dir: {self.build_temp}") - print(f"Output dir: {cmake_output_dir}") - print(f"Build type: {cmake_build_type}") - subprocess.check_call(cmake_build_argv, cwd=self.build_temp, env=env) - - print() - -setuptools.setup( - name = "b-asic", - version = "0.0.1", - author = "Adam Jakobsson, Angus Lothian, Arvid Westerlund, Felix Goding, Ivar Härnqvist, Jacob Wahlman, Kevin Scott, Rasmus Karlsson", - author_email = "adaja901@student.liu.se, anglo547@student.liu.se, arvwe160@student.liu.se, felgo673@student.liu.se, ivaha717@student.liu.se, jacwa448@student.liu.se, kevsc634@student.liu.se, raska119@student.liu.se", - description = "Better ASIC Toolbox", - long_description = open("README.md", "r").read(), - long_description_content_type = "text/markdown", - url = "https://gitlab.liu.se/PUM_TDDD96/B-ASIC", - license = "MIT", - classifiers = [ - "Programming Language :: Python :: 3", - "License :: OSI Approved :: MIT License", - "Operating System :: OS Independent", - ], - python_requires = ">=3.6", - install_requires = [ - "pybind11>=2.3.0", - "numpy", - "install_qt_binding" - ], - packages = ["b_asic"], - ext_modules = [CMakeExtension("b_asic")], - cmdclass = {"build_ext": CMakeBuild}, - zip_safe = False -) \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp deleted file mode 100644 index 75a77ef58b86cd29238205a078cec780a6ba9a36..0000000000000000000000000000000000000000 --- a/src/main.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include <pybind11/pybind11.h> - -namespace py = pybind11; - -namespace asic { - -int add(int a, int b) { - return a + b; -} - -int sub(int a, int b) { - return a - b; -} - -} // namespace asic - -PYBIND11_MODULE(_b_asic, m) { - m.doc() = "Better ASIC Toolbox Extension Module."; - m.def("add", &asic::add, "A function which adds two numbers.", py::arg("a"), py::arg("b")); - m.def("sub", &asic::sub, "A function which subtracts two numbers.", py::arg("a"), py::arg("b")); -} \ No newline at end of file diff --git a/test/__init__.py b/test/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/test/conftest.py b/test/conftest.py deleted file mode 100644 index 64f39843c53a4369781a269fd7fc30ad9aa1d255..0000000000000000000000000000000000000000 --- a/test/conftest.py +++ /dev/null @@ -1,4 +0,0 @@ -from test.fixtures.signal import signal, signals -from test.fixtures.operation_tree import * -from test.fixtures.port import * -import pytest diff --git a/test/fixtures/operation_tree.py b/test/fixtures/operation_tree.py deleted file mode 100644 index df3fcac35cc495d14bed06ccdfc2a3ebed25616e..0000000000000000000000000000000000000000 --- a/test/fixtures/operation_tree.py +++ /dev/null @@ -1,58 +0,0 @@ -from b_asic.core_operations import Addition, Constant -from b_asic.signal import Signal - -import pytest - -@pytest.fixture -def operation(): - return Constant(2) - -def create_operation(_type, dest_oper, index, **kwargs): - oper = _type(**kwargs) - oper_signal = Signal() - oper._output_ports[0].add_signal(oper_signal) - - dest_oper._input_ports[index].add_signal(oper_signal) - return oper - -@pytest.fixture -def operation_tree(): - """Return a addition operation connected with 2 constants. - ---C---+ - ---A - ---C---+ - """ - add_oper = Addition() - create_operation(Constant, add_oper, 0, value=2) - create_operation(Constant, add_oper, 1, value=3) - return add_oper - -@pytest.fixture -def large_operation_tree(): - """Return a constant operation connected with a large operation tree with 3 other constants and 3 additions. - ---C---+ - ---A---+ - ---C---+ | - +---A - ---C---+ | - ---A---+ - ---C---+ - """ - add_oper = Addition() - add_oper_2 = Addition() - - const_oper = create_operation(Constant, add_oper, 0, value=2) - create_operation(Constant, add_oper, 1, value=3) - - create_operation(Constant, add_oper_2, 0, value=4) - create_operation(Constant, add_oper_2, 1, value=5) - - add_oper_3 = Addition() - add_oper_signal = Signal(add_oper.output(0), add_oper_3.output(0)) - add_oper._output_ports[0].add_signal(add_oper_signal) - add_oper_3._input_ports[0].add_signal(add_oper_signal) - - add_oper_2_signal = Signal(add_oper_2.output(0), add_oper_3.output(0)) - add_oper_2._output_ports[0].add_signal(add_oper_2_signal) - add_oper_3._input_ports[1].add_signal(add_oper_2_signal) - return const_oper diff --git a/test/fixtures/port.py b/test/fixtures/port.py deleted file mode 100644 index 4019b3a2016aa418daeca771f9a2d8bcc4ca6652..0000000000000000000000000000000000000000 --- a/test/fixtures/port.py +++ /dev/null @@ -1,10 +0,0 @@ -import pytest -from b_asic.port import InputPort, OutputPort - -@pytest.fixture -def input_port(): - return InputPort(0, None) - -@pytest.fixture -def output_port(): - return OutputPort(0, None) diff --git a/test/fixtures/signal.py b/test/fixtures/signal.py deleted file mode 100644 index 7b13c9789f94c33338d08b48373391398bd9f71d..0000000000000000000000000000000000000000 --- a/test/fixtures/signal.py +++ /dev/null @@ -1,12 +0,0 @@ -import pytest -from b_asic import Signal - -@pytest.fixture -def signal(): - """Return a signal with no connections.""" - return Signal() - -@pytest.fixture -def signals(): - """Return 3 signals with no connections.""" - return [Signal() for _ in range(0,3)] diff --git a/test/operation/test_abstract_operation.py b/test/operation/test_abstract_operation.py deleted file mode 100644 index 626a2dc3e5e26fb76d9266dcdd31940681df5c6e..0000000000000000000000000000000000000000 --- a/test/operation/test_abstract_operation.py +++ /dev/null @@ -1,77 +0,0 @@ -""" -B-ASIC test suite for the AbstractOperation class. -""" - -from b_asic.core_operations import Addition, ConstantAddition, Subtraction, ConstantSubtraction, \ - Multiplication, ConstantMultiplication, Division, ConstantDivision - -import pytest - - -def test_addition_overload(): - """Tests addition overloading for both operation and number argument.""" - add1 = Addition(None, None, "add1") - add2 = Addition(None, None, "add2") - - add3 = add1 + add2 - - assert isinstance(add3, Addition) - assert add3.input(0).signals == add1.output(0).signals - assert add3.input(1).signals == add2.output(0).signals - - add4 = add3 + 5 - - assert isinstance(add4, ConstantAddition) - assert add4.input(0).signals == add3.output(0).signals - - -def test_subtraction_overload(): - """Tests subtraction overloading for both operation and number argument.""" - add1 = Addition(None, None, "add1") - add2 = Addition(None, None, "add2") - - sub1 = add1 - add2 - - assert isinstance(sub1, Subtraction) - assert sub1.input(0).signals == add1.output(0).signals - assert sub1.input(1).signals == add2.output(0).signals - - sub2 = sub1 - 5 - - assert isinstance(sub2, ConstantSubtraction) - assert sub2.input(0).signals == sub1.output(0).signals - - -def test_multiplication_overload(): - """Tests multiplication overloading for both operation and number argument.""" - add1 = Addition(None, None, "add1") - add2 = Addition(None, None, "add2") - - mul1 = add1 * add2 - - assert isinstance(mul1, Multiplication) - assert mul1.input(0).signals == add1.output(0).signals - assert mul1.input(1).signals == add2.output(0).signals - - mul2 = mul1 * 5 - - assert isinstance(mul2, ConstantMultiplication) - assert mul2.input(0).signals == mul1.output(0).signals - - -def test_division_overload(): - """Tests division overloading for both operation and number argument.""" - add1 = Addition(None, None, "add1") - add2 = Addition(None, None, "add2") - - div1 = add1 / add2 - - assert isinstance(div1, Division) - assert div1.input(0).signals == add1.output(0).signals - assert div1.input(1).signals == add2.output(0).signals - - div2 = div1 / 5 - - assert isinstance(div2, ConstantDivision) - assert div2.input(0).signals == div1.output(0).signals - diff --git a/test/test_core_operations.py b/test/test_core_operations.py deleted file mode 100644 index b176b2a6506cc5a1297813f6ddcb6d3589492838..0000000000000000000000000000000000000000 --- a/test/test_core_operations.py +++ /dev/null @@ -1,227 +0,0 @@ -""" -B-ASIC test suite for the core operations. -""" - -from b_asic.core_operations import Constant, Addition, Subtraction, Multiplication, Division, SquareRoot, ComplexConjugate, Max, Min, Absolute, ConstantMultiplication, ConstantAddition, ConstantSubtraction, ConstantDivision - -# Constant tests. -def test_constant(): - constant_operation = Constant(3) - assert constant_operation.evaluate() == 3 - -def test_constant_negative(): - constant_operation = Constant(-3) - assert constant_operation.evaluate() == -3 - -def test_constant_complex(): - constant_operation = Constant(3+4j) - assert constant_operation.evaluate() == 3+4j - -# Addition tests. -def test_addition(): - test_operation = Addition() - constant_operation = Constant(3) - constant_operation_2 = Constant(5) - assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == 8 - -def test_addition_negative(): - test_operation = Addition() - constant_operation = Constant(-3) - constant_operation_2 = Constant(-5) - assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == -8 - -def test_addition_complex(): - test_operation = Addition() - constant_operation = Constant((3+5j)) - constant_operation_2 = Constant((4+6j)) - assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == (7+11j) - -# Subtraction tests. -def test_subtraction(): - test_operation = Subtraction() - constant_operation = Constant(5) - constant_operation_2 = Constant(3) - assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == 2 - -def test_subtraction_negative(): - test_operation = Subtraction() - constant_operation = Constant(-5) - constant_operation_2 = Constant(-3) - assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == -2 - -def test_subtraction_complex(): - test_operation = Subtraction() - constant_operation = Constant((3+5j)) - constant_operation_2 = Constant((4+6j)) - assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == (-1-1j) - -# Multiplication tests. -def test_multiplication(): - test_operation = Multiplication() - constant_operation = Constant(5) - constant_operation_2 = Constant(3) - assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == 15 - -def test_multiplication_negative(): - test_operation = Multiplication() - constant_operation = Constant(-5) - constant_operation_2 = Constant(-3) - assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == 15 - -def test_multiplication_complex(): - test_operation = Multiplication() - constant_operation = Constant((3+5j)) - constant_operation_2 = Constant((4+6j)) - assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == (-18+38j) - -# Division tests. -def test_division(): - test_operation = Division() - constant_operation = Constant(30) - constant_operation_2 = Constant(5) - assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == 6 - -def test_division_negative(): - test_operation = Division() - constant_operation = Constant(-30) - constant_operation_2 = Constant(-5) - assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == 6 - -def test_division_complex(): - test_operation = Division() - constant_operation = Constant((60+40j)) - constant_operation_2 = Constant((10+20j)) - assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == (2.8-1.6j) - -# SquareRoot tests. -def test_squareroot(): - test_operation = SquareRoot() - constant_operation = Constant(36) - assert test_operation.evaluate(constant_operation.evaluate()) == 6 - -def test_squareroot_negative(): - test_operation = SquareRoot() - constant_operation = Constant(-36) - assert test_operation.evaluate(constant_operation.evaluate()) == 6j - -def test_squareroot_complex(): - test_operation = SquareRoot() - constant_operation = Constant((48+64j)) - assert test_operation.evaluate(constant_operation.evaluate()) == (8+4j) - -# ComplexConjugate tests. -def test_complexconjugate(): - test_operation = ComplexConjugate() - constant_operation = Constant(3+4j) - assert test_operation.evaluate(constant_operation.evaluate()) == (3-4j) - -def test_test_complexconjugate_negative(): - test_operation = ComplexConjugate() - constant_operation = Constant(-3-4j) - assert test_operation.evaluate(constant_operation.evaluate()) == (-3+4j) - -# Max tests. -def test_max(): - test_operation = Max() - constant_operation = Constant(30) - constant_operation_2 = Constant(5) - assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == 30 - -def test_max_negative(): - test_operation = Max() - constant_operation = Constant(-30) - constant_operation_2 = Constant(-5) - assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == -5 - -# Min tests. -def test_min(): - test_operation = Min() - constant_operation = Constant(30) - constant_operation_2 = Constant(5) - assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == 5 - -def test_min_negative(): - test_operation = Min() - constant_operation = Constant(-30) - constant_operation_2 = Constant(-5) - assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == -30 - -# Absolute tests. -def test_absolute(): - test_operation = Absolute() - constant_operation = Constant(30) - assert test_operation.evaluate(constant_operation.evaluate()) == 30 - -def test_absolute_negative(): - test_operation = Absolute() - constant_operation = Constant(-5) - assert test_operation.evaluate(constant_operation.evaluate()) == 5 - -def test_absolute_complex(): - test_operation = Absolute() - constant_operation = Constant((3+4j)) - assert test_operation.evaluate(constant_operation.evaluate()) == 5.0 - -# ConstantMultiplication tests. -def test_constantmultiplication(): - test_operation = ConstantMultiplication(5) - constant_operation = Constant(20) - assert test_operation.evaluate(constant_operation.evaluate()) == 100 - -def test_constantmultiplication_negative(): - test_operation = ConstantMultiplication(5) - constant_operation = Constant(-5) - assert test_operation.evaluate(constant_operation.evaluate()) == -25 - -def test_constantmultiplication_complex(): - test_operation = ConstantMultiplication(3+2j) - constant_operation = Constant((3+4j)) - assert test_operation.evaluate(constant_operation.evaluate()) == (1+18j) - -# ConstantAddition tests. -def test_constantaddition(): - test_operation = ConstantAddition(5) - constant_operation = Constant(20) - assert test_operation.evaluate(constant_operation.evaluate()) == 25 - -def test_constantaddition_negative(): - test_operation = ConstantAddition(4) - constant_operation = Constant(-5) - assert test_operation.evaluate(constant_operation.evaluate()) == -1 - -def test_constantaddition_complex(): - test_operation = ConstantAddition(3+2j) - constant_operation = Constant((3+4j)) - assert test_operation.evaluate(constant_operation.evaluate()) == (6+6j) - -# ConstantSubtraction tests. -def test_constantsubtraction(): - test_operation = ConstantSubtraction(5) - constant_operation = Constant(20) - assert test_operation.evaluate(constant_operation.evaluate()) == 15 - -def test_constantsubtraction_negative(): - test_operation = ConstantSubtraction(4) - constant_operation = Constant(-5) - assert test_operation.evaluate(constant_operation.evaluate()) == -9 - -def test_constantsubtraction_complex(): - test_operation = ConstantSubtraction(4+6j) - constant_operation = Constant((3+4j)) - assert test_operation.evaluate(constant_operation.evaluate()) == (-1-2j) - -# ConstantDivision tests. -def test_constantdivision(): - test_operation = ConstantDivision(5) - constant_operation = Constant(20) - assert test_operation.evaluate(constant_operation.evaluate()) == 4 - -def test_constantdivision_negative(): - test_operation = ConstantDivision(4) - constant_operation = Constant(-20) - assert test_operation.evaluate(constant_operation.evaluate()) == -5 - -def test_constantdivision_complex(): - test_operation = ConstantDivision(2+2j) - constant_operation = Constant((10+10j)) - assert test_operation.evaluate(constant_operation.evaluate()) == (5+0j) diff --git a/test/test_graph_id_generator.py b/test/test_graph_id_generator.py deleted file mode 100644 index b14597eabe6c15695c5c452f69f3deeab56e36d5..0000000000000000000000000000000000000000 --- a/test/test_graph_id_generator.py +++ /dev/null @@ -1,28 +0,0 @@ -""" -B-ASIC test suite for graph id generator. -""" - -from b_asic.graph_id import GraphIDGenerator, GraphID -import pytest - -@pytest.fixture -def graph_id_generator(): - return GraphIDGenerator() - -class TestGetNextId: - def test_empty_string_generator(self, graph_id_generator): - """Test the graph id generator for an empty string type.""" - assert graph_id_generator.get_next_id("") == "1" - assert graph_id_generator.get_next_id("") == "2" - - def test_normal_string_generator(self, graph_id_generator): - """"Test the graph id generator for a normal string type.""" - assert graph_id_generator.get_next_id("add") == "add1" - assert graph_id_generator.get_next_id("add") == "add2" - - def test_different_strings_generator(self, graph_id_generator): - """Test the graph id generator for different strings.""" - assert graph_id_generator.get_next_id("sub") == "sub1" - assert graph_id_generator.get_next_id("mul") == "mul1" - assert graph_id_generator.get_next_id("sub") == "sub2" - assert graph_id_generator.get_next_id("mul") == "mul2" diff --git a/test/test_inputport.py b/test/test_inputport.py deleted file mode 100644 index a43240693ac632b48461023536ff46b0ea379c5c..0000000000000000000000000000000000000000 --- a/test/test_inputport.py +++ /dev/null @@ -1,95 +0,0 @@ -""" -B-ASIC test suite for Inputport -""" - -import pytest - -from b_asic import InputPort, OutputPort -from b_asic import Signal - -@pytest.fixture -def inp_port(): - return InputPort(0, None) - -@pytest.fixture -def out_port(): - return OutputPort(0, None) - -@pytest.fixture -def out_port2(): - return OutputPort(1, None) - -@pytest.fixture -def dangling_sig(): - return Signal() - -@pytest.fixture -def s_w_source(): - out_port = OutputPort(0, None) - return Signal(source=out_port) - -@pytest.fixture -def sig_with_dest(): - inp_port = InputPort(0, None) - return Signal(destination=out_port) - -@pytest.fixture -def connected_sig(): - out_port = OutputPort(0, None) - inp_port = InputPort(0, None) - return Signal(source=out_port, destination=inp_port) - -def test_connect_then_disconnect(inp_port, out_port): - """Test connect unused port to port.""" - s1 = inp_port.connect(out_port) - - assert inp_port.connected_ports == [out_port] - assert out_port.connected_ports == [inp_port] - assert inp_port.signals == [s1] - assert out_port.signals == [s1] - assert s1.source is out_port - assert s1.destination is inp_port - - inp_port.remove_signal(s1) - - assert inp_port.connected_ports == [] - assert out_port.connected_ports == [] - assert inp_port.signals == [] - assert out_port.signals == [s1] - assert s1.source is out_port - assert s1.destination is None - -def test_connect_used_port_to_new_port(inp_port, out_port, out_port2): - """Does connecting multiple ports to an inputport throw error?""" - inp_port.connect(out_port) - with pytest.raises(AssertionError): - inp_port.connect(out_port2) - -def test_add_signal_then_disconnect(inp_port, s_w_source): - """Can signal be connected then disconnected properly?""" - inp_port.add_signal(s_w_source) - - assert inp_port.connected_ports == [s_w_source.source] - assert s_w_source.source.connected_ports == [inp_port] - assert inp_port.signals == [s_w_source] - assert s_w_source.source.signals == [s_w_source] - assert s_w_source.destination is inp_port - - inp_port.remove_signal(s_w_source) - - assert inp_port.connected_ports == [] - assert s_w_source.source.connected_ports == [] - assert inp_port.signals == [] - assert s_w_source.source.signals == [s_w_source] - assert s_w_source.destination is None - -def test_connect_then_disconnect(inp_port, out_port): - """Can port be connected and then disconnected properly?""" - inp_port.connect(out_port) - - inp_port.disconnect(out_port) - - print("outport signals:", out_port.signals, "count:", out_port.signal_count()) - assert inp_port.signal_count() == 1 - assert len(inp_port.connected_ports) == 0 - assert out_port.signal_count() == 0 diff --git a/test/test_operation.py b/test/test_operation.py deleted file mode 100644 index 6c37e30bddd0b55ea69ae5b95a341c1ddeb56847..0000000000000000000000000000000000000000 --- a/test/test_operation.py +++ /dev/null @@ -1,31 +0,0 @@ -from b_asic.core_operations import Constant, Addition -from b_asic.signal import Signal -from b_asic.port import InputPort, OutputPort - -import pytest - -class TestTraverse: - def test_traverse_single_tree(self, operation): - """Traverse a tree consisting of one operation.""" - constant = Constant(None) - assert list(constant.traverse()) == [constant] - - def test_traverse_tree(self, operation_tree): - """Traverse a basic addition tree with two constants.""" - assert len(list(operation_tree.traverse())) == 3 - - def test_traverse_large_tree(self, large_operation_tree): - """Traverse a larger tree.""" - assert len(list(large_operation_tree.traverse())) == 7 - - def test_traverse_type(self, large_operation_tree): - traverse = list(large_operation_tree.traverse()) - assert len(list(filter(lambda type_: isinstance(type_, Addition), traverse))) == 3 - assert len(list(filter(lambda type_: isinstance(type_, Constant), traverse))) == 4 - - def test_traverse_loop(self, operation_tree): - add_oper_signal = Signal() - operation_tree._output_ports[0].add_signal(add_oper_signal) - operation_tree._input_ports[0].remove_signal(add_oper_signal) - operation_tree._input_ports[0].add_signal(add_oper_signal) - assert len(list(operation_tree.traverse())) == 2 diff --git a/test/test_outputport.py b/test/test_outputport.py deleted file mode 100644 index deed7a1e06836600254e3903b8b45a3d05f17cbe..0000000000000000000000000000000000000000 --- a/test/test_outputport.py +++ /dev/null @@ -1,80 +0,0 @@ -""" -B-ASIC test suite for OutputPort. -""" -from b_asic import OutputPort, InputPort, Signal -import pytest - -@pytest.fixture -def output_port(): - return OutputPort(0, None) - -@pytest.fixture -def input_port(): - return InputPort(0, None) - -@pytest.fixture -def list_of_input_ports(): - return [InputPort(_, None) for _ in range(0,3)] - -class TestConnect: - def test_multiple_ports(self, output_port, list_of_input_ports): - """Can multiple ports connect to an output port?""" - for port in list_of_input_ports: - output_port.connect(port) - - assert output_port.signal_count() == len(list_of_input_ports) - - def test_same_port(self, output_port, list_of_input_ports): - """Check error handing.""" - output_port.connect(list_of_input_ports[0]) - with pytest.raises(AssertionError): - output_port.connect(list_of_input_ports[0]) - - assert output_port.signal_count() == 2 - -class TestAddSignal: - def test_dangling(self, output_port): - s = Signal() - output_port.add_signal(s) - - assert output_port.signal_count() == 1 - - def test_with_destination(self, output_port, input_port): - s = Signal(destination=input_port) - output_port.add_signal(s) - - assert output_port.connected_ports == [s.destination] - -class TestDisconnect: - def test_multiple_ports(self, output_port, list_of_input_ports): - """Can multiple ports disconnect from OutputPort?""" - for port in list_of_input_ports: - output_port.connect(port) - - for port in list_of_input_ports: - output_port.disconnect(port) - - assert output_port.signal_count() == 3 - assert output_port.connected_ports == [] - -class TestRemoveSignal: - def test_one_signal(self, output_port, input_port): - s = output_port.connect(input_port) - output_port.remove_signal(s) - - assert output_port.signal_count() == 0 - assert output_port.signals == [] - assert output_port.connected_ports == [] - - def test_multiple_signals(self, output_port, list_of_input_ports): - """Can multiple signals disconnect from OutputPort?""" - sigs = [] - - for port in list_of_input_ports: - sigs.append(output_port.connect(port)) - - for sig in sigs: - output_port.remove_signal(sig) - - assert output_port.signal_count() == 0 - assert output_port.signals == [] diff --git a/test/test_signal.py b/test/test_signal.py deleted file mode 100644 index ab07eb778ddb693bfc9cfabf6aeb7804038312d5..0000000000000000000000000000000000000000 --- a/test/test_signal.py +++ /dev/null @@ -1,62 +0,0 @@ -""" -B-ASIC test suit for the signal module which consists of the Signal class. -""" - -from b_asic.port import InputPort, OutputPort -from b_asic.signal import Signal - -import pytest - -def test_signal_creation_and_disconnction_and_connection_changing(): - in_port = InputPort(0, None) - out_port = OutputPort(1, None) - s = Signal(out_port, in_port) - - assert in_port.signals == [s] - assert out_port.signals == [s] - assert s.source is out_port - assert s.destination is in_port - - in_port1 = InputPort(0, None) - s.set_destination(in_port1) - - assert in_port.signals == [] - assert in_port1.signals == [s] - assert out_port.signals == [s] - assert s.source is out_port - assert s.destination is in_port1 - - s.remove_source() - - assert out_port.signals == [] - assert in_port1.signals == [s] - assert s.source is None - assert s.destination is in_port1 - - s.remove_destination() - - assert out_port.signals == [] - assert in_port1.signals == [] - assert s.source is None - assert s.destination is None - - out_port1 = OutputPort(0, None) - s.set_source(out_port1) - - assert out_port1.signals == [s] - assert s.source is out_port1 - assert s.destination is None - - s.set_source(out_port) - - assert out_port.signals == [s] - assert out_port1.signals == [] - assert s.source is out_port - assert s.destination is None - - s.set_destination(in_port) - - assert out_port.signals == [s] - assert in_port.signals == [s] - assert s.source is out_port - assert s.destination is in_port