From: Fabian Stemmler Date: Mon, 20 May 2019 10:44:43 +0000 (+0200) Subject: WireArray(Input) is now Wire(End); all in-/outputs are now WireEnds X-Git-Url: https://mograsim.net/gitweb/?a=commitdiff_plain;h=c1d0ddc342c482051fa6c455bb286617135bd3c3;p=Mograsim.git WireArray(Input) is now Wire(End); all in-/outputs are now WireEnds --- diff --git a/era.mi/.settings/org.eclipse.jdt.core.prefs b/era.mi/.settings/org.eclipse.jdt.core.prefs index 82c6671b..fd071d58 100644 --- a/era.mi/.settings/org.eclipse.jdt.core.prefs +++ b/era.mi/.settings/org.eclipse.jdt.core.prefs @@ -15,7 +15,6 @@ org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns=false org.eclipse.jdt.core.formatter.align_with_spaces=false -org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 @@ -24,27 +23,20 @@ org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_assignment=0 org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16 org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 org.eclipse.jdt.core.formatter.alignment_for_compact_loops=16 org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain=0 org.eclipse.jdt.core.formatter.alignment_for_enum_constants=16 org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 -org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16 org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 org.eclipse.jdt.core.formatter.alignment_for_module_statements=16 org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_shift_operator=0 -org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16 org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 @@ -89,7 +81,6 @@ org.eclipse.jdt.core.formatter.comment.format_line_comments=true org.eclipse.jdt.core.formatter.comment.format_source_code=true org.eclipse.jdt.core.formatter.comment.indent_parameter_description=false org.eclipse.jdt.core.formatter.comment.indent_root_tags=false -org.eclipse.jdt.core.formatter.comment.indent_tag_description=false org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert org.eclipse.jdt.core.formatter.comment.line_length=140 @@ -137,13 +128,11 @@ org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert @@ -174,8 +163,6 @@ org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert @@ -200,18 +187,13 @@ org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert -org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert @@ -259,8 +241,6 @@ org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do no org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert @@ -297,12 +277,9 @@ org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not inser org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert @@ -314,24 +291,13 @@ org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_decla org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.join_lines_in_comments=true org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line=one_line_never -org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line=one_line_never -org.eclipse.jdt.core.formatter.keep_code_block_on_one_line=one_line_never org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line=one_line_never -org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line=one_line_never -org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line=one_line_never org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line=one_line_never -org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line=one_line_never -org.eclipse.jdt.core.formatter.keep_method_body_on_one_line=one_line_never org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line=false org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line=false -org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line=false org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line=false org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line=one_line_never org.eclipse.jdt.core.formatter.lineSplit=140 org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false @@ -352,16 +318,9 @@ org.eclipse.jdt.core.formatter.tabulation.char=tab org.eclipse.jdt.core.formatter.tabulation.size=4 org.eclipse.jdt.core.formatter.use_on_off_tags=true org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true -org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true -org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true -org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true -org.eclipse.jdt.core.formatter.wrap_before_relational_operator=true -org.eclipse.jdt.core.formatter.wrap_before_shift_operator=true -org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter diff --git a/era.mi/.settings/org.eclipse.jdt.ui.prefs b/era.mi/.settings/org.eclipse.jdt.ui.prefs index 07b37c11..f5705df7 100644 --- a/era.mi/.settings/org.eclipse.jdt.ui.prefs +++ b/era.mi/.settings/org.eclipse.jdt.ui.prefs @@ -1,63 +1,3 @@ eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -formatter_profile=_ERA-MI -formatter_settings_version=16 -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=true -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_methods=false -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_missing_override_annotations_interface_methods=true -sp_cleanup.add_serial_version_id=false -sp_cleanup.always_use_blocks=false -sp_cleanup.always_use_parentheses_in_expressions=false -sp_cleanup.always_use_this_for_non_static_field_access=false -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.convert_functional_interfaces=true -sp_cleanup.convert_to_enhanced_for_loop=true -sp_cleanup.correct_indentation=true -sp_cleanup.format_source_code=true -sp_cleanup.format_source_code_changes_only=false -sp_cleanup.insert_inferred_type_arguments=false -sp_cleanup.make_local_variable_final=true -sp_cleanup.make_parameters_final=false -sp_cleanup.make_private_fields_final=true -sp_cleanup.make_type_abstract_if_missing_method=false -sp_cleanup.make_variable_declarations_final=true -sp_cleanup.never_use_blocks=true -sp_cleanup.never_use_parentheses_in_expressions=true -sp_cleanup.on_save_use_additional_actions=false -sp_cleanup.organize_imports=true -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=true -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_redundant_modifiers=true -sp_cleanup.remove_redundant_semicolons=true -sp_cleanup.remove_redundant_type_arguments=true -sp_cleanup.remove_trailing_whitespaces=true -sp_cleanup.remove_trailing_whitespaces_all=true -sp_cleanup.remove_trailing_whitespaces_ignore_empty=false -sp_cleanup.remove_unnecessary_casts=true -sp_cleanup.remove_unnecessary_nls_tags=true -sp_cleanup.remove_unused_imports=true -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.use_anonymous_class_creation=false -sp_cleanup.use_blocks=false -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_lambda=true -sp_cleanup.use_parentheses_in_expressions=false -sp_cleanup.use_this_for_non_static_field_access=true -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true -sp_cleanup.use_this_for_non_static_method_access=true -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true +formatter_profile=_MyPrefrence +formatter_settings_version=14 diff --git a/era.mi/src/era/mi/logic/Bit.java b/era.mi/src/era/mi/logic/Bit.java index 992c7295..da9a227f 100644 --- a/era.mi/src/era/mi/logic/Bit.java +++ b/era.mi/src/era/mi/logic/Bit.java @@ -77,28 +77,28 @@ public enum Bit } // @formatter:off - private static final Bit[][] JOIN_TABLE = + private static Bit[][] JOIN_TABLE = { { U, U, U, U, U }, { U, X, X, X, X }, { U, X, ZERO, X, ZERO }, { U, X, X, ONE, ONE }, { U, X, ZERO, ONE, Z } }; - private static final Bit[][] AND_TABLE = + private static Bit[][] AND_TABLE = { { U, U, ZERO, U, U }, { U, X, ZERO, X, X }, { ZERO, ZERO, ZERO, ZERO, ZERO }, { U, X, ZERO, ONE, X }, { U, X, ZERO, X, X } }; - private static final Bit[][] OR_TABLE = + private static Bit[][] OR_TABLE = { { U, U, U, ONE, U }, { U, X, X, ONE, X }, { U, X, ZERO, ONE, X }, { ONE, ONE, ONE, ONE, ONE }, { U, X, X, ONE, X } }; - private static final Bit[][] XOR_TABLE = + private static Bit[][] XOR_TABLE = { { U, U, U, U, U }, { U, X, X, X, X }, { U, X, ZERO, ONE, X }, diff --git a/era.mi/src/era/mi/logic/Simulation.java b/era.mi/src/era/mi/logic/Simulation.java index 0468ec1e..f4b25d2d 100644 --- a/era.mi/src/era/mi/logic/Simulation.java +++ b/era.mi/src/era/mi/logic/Simulation.java @@ -6,4 +6,7 @@ public class Simulation { public final static Timeline TIMELINE = new Timeline(11); + public static void main(String[] args) + { + } } \ No newline at end of file diff --git a/era.mi/src/era/mi/logic/components/BasicComponent.java b/era.mi/src/era/mi/logic/components/BasicComponent.java index 2956fe01..510765c4 100644 --- a/era.mi/src/era/mi/logic/components/BasicComponent.java +++ b/era.mi/src/era/mi/logic/components/BasicComponent.java @@ -2,7 +2,7 @@ package era.mi.logic.components; import era.mi.logic.Bit; import era.mi.logic.Simulation; -import era.mi.logic.wires.WireArray; +import era.mi.logic.wires.Wire; import era.mi.logic.wires.WireArrayObserver; /** @@ -26,9 +26,12 @@ public abstract class BasicComponent implements WireArrayObserver, Component } @Override - public void update(WireArray initiator, Bit[] oldValues) + public void update(Wire initiator, Bit[] oldValues) { - Simulation.TIMELINE.addEvent(e -> compute(), processTime); + Simulation.TIMELINE.addEvent((e) -> + { + compute(); + }, processTime); } protected abstract void compute(); diff --git a/era.mi/src/era/mi/logic/components/BitDisplay.java b/era.mi/src/era/mi/logic/components/BitDisplay.java index bd9714ae..5ddae967 100644 --- a/era.mi/src/era/mi/logic/components/BitDisplay.java +++ b/era.mi/src/era/mi/logic/components/BitDisplay.java @@ -1,17 +1,19 @@ package era.mi.logic.components; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import era.mi.logic.Bit; -import era.mi.logic.wires.WireArray; +import era.mi.logic.wires.Wire.WireEnd; public class BitDisplay extends BasicComponent { - private final WireArray in; + private final WireEnd in; private Bit[] displayedValue; - public BitDisplay(WireArray in) + public BitDisplay(WireEnd in) { super(1); this.in = in; @@ -36,14 +38,14 @@ public class BitDisplay extends BasicComponent } @Override - public List getAllInputs() + public List getAllInputs() { - return List.of(in); + return Collections.unmodifiableList(Arrays.asList(in)); } @Override - public List getAllOutputs() + public List getAllOutputs() { - return List.of(); + return Collections.unmodifiableList(new ArrayList()); } } diff --git a/era.mi/src/era/mi/logic/components/Clock.java b/era.mi/src/era/mi/logic/components/Clock.java index d95cbc7b..34f49374 100644 --- a/era.mi/src/era/mi/logic/components/Clock.java +++ b/era.mi/src/era/mi/logic/components/Clock.java @@ -1,43 +1,45 @@ package era.mi.logic.components; +import java.util.Arrays; +import java.util.Collections; import java.util.List; import era.mi.logic.Bit; import era.mi.logic.Simulation; import era.mi.logic.timeline.TimelineEvent; import era.mi.logic.timeline.TimelineEventHandler; -import era.mi.logic.wires.WireArray; -import era.mi.logic.wires.WireArray.WireArrayEnd; +import era.mi.logic.wires.Wire; +import era.mi.logic.wires.Wire.WireEnd; public class Clock implements TimelineEventHandler, Component { private boolean toggle = false; - private WireArrayEnd outI; + private WireEnd out; private int delta; /** * - * @param out {@link WireArray} the clock's impulses are fed into + * @param out {@link Wire} the clock's impulses are fed into * @param delta ticks between rising and falling edge */ - public Clock(WireArray out, int delta) + public Clock(WireEnd out, int delta) { this.delta = delta; - this.outI = out.createInput(); - Simulation.TIMELINE.addEvent(this, delta); + this.out = out; + addToTimeline(); } @Override public void handle(TimelineEvent e) { addToTimeline(); - outI.feedSignals(toggle ? Bit.ONE : Bit.ZERO); + out.feedSignals(new Bit[] { toggle ? Bit.ONE : Bit.ZERO }); toggle = !toggle; } - public WireArray getOut() + public WireEnd getOut() { - return outI.owner; + return out; } private void addToTimeline() @@ -46,14 +48,14 @@ public class Clock implements TimelineEventHandler, Component } @Override - public List getAllInputs() + public List getAllInputs() { - return List.of(); + return Collections.unmodifiableList(Arrays.asList()); } @Override - public List getAllOutputs() + public List getAllOutputs() { - return List.of(outI.owner); + return Collections.unmodifiableList(Arrays.asList(out)); } } diff --git a/era.mi/src/era/mi/logic/components/Component.java b/era.mi/src/era/mi/logic/components/Component.java index 19b5d3e9..522a58d9 100644 --- a/era.mi/src/era/mi/logic/components/Component.java +++ b/era.mi/src/era/mi/logic/components/Component.java @@ -2,7 +2,7 @@ package era.mi.logic.components; import java.util.List; -import era.mi.logic.wires.WireArray; +import era.mi.logic.wires.Wire.WireEnd; public interface Component { @@ -11,10 +11,10 @@ public interface Component * Returns immutable list of all inputs to the {@link Component} (including e.g. the select bits to a MUX). Intended for visualization * in the UI. */ - public List getAllInputs(); + public List getAllInputs(); /** * Returns immutable list of all outputs to the {@link Component}. Intended for visualization in the UI. */ - public List getAllOutputs(); + public List getAllOutputs(); } diff --git a/era.mi/src/era/mi/logic/components/Connector.java b/era.mi/src/era/mi/logic/components/Connector.java deleted file mode 100644 index 17c9f3c8..00000000 --- a/era.mi/src/era/mi/logic/components/Connector.java +++ /dev/null @@ -1,79 +0,0 @@ -package era.mi.logic.components; - -import java.util.List; - -import era.mi.logic.Bit; -import era.mi.logic.Simulation; -import era.mi.logic.wires.WireArray; -import era.mi.logic.wires.WireArray.WireArrayEnd; -import era.mi.logic.wires.WireArrayObserver; - -public class Connector implements WireArrayObserver, Component -{ - private boolean connected; - private final WireArray a; - private final WireArray b; - private final WireArrayEnd aI; - private final WireArrayEnd bI; - - public Connector(WireArray a, WireArray b) - { - if (a.length != b.length) - throw new IllegalArgumentException(String.format("WireArray width does not match: %d, %d", a.length, b.length)); - this.a = a; - this.b = b; - a.addObserver(this); - b.addObserver(this); - aI = a.createInput(); - bI = b.createInput(); - } - - public void connect() - { - connected = true; - update(a); - update(b); - } - - public void disconnect() - { - connected = false; - aI.clearSignals(); - bI.clearSignals(); - } - - public void setConnection(boolean connected) - { - if (connected) - connect(); - else - disconnect(); - } - - @Override - public void update(WireArray initiator, Bit[] oldValues) - { - if (connected) - Simulation.TIMELINE.addEvent(e -> update(initiator), 1); - } - - private void update(WireArray initiator) - { - if (initiator == a) - bI.feedSignals(aI.wireValuesExcludingMe()); - else - aI.feedSignals(bI.wireValuesExcludingMe()); - } - - @Override - public List getAllInputs() - { - return List.of(a, b); - } - - @Override - public List getAllOutputs() - { - return List.of(a, b); - } -} diff --git a/era.mi/src/era/mi/logic/components/Demux.java b/era.mi/src/era/mi/logic/components/Demux.java index 762d8067..4f06728a 100644 --- a/era.mi/src/era/mi/logic/components/Demux.java +++ b/era.mi/src/era/mi/logic/components/Demux.java @@ -1,54 +1,54 @@ package era.mi.logic.components; +import java.util.Arrays; +import java.util.Collections; import java.util.List; -import era.mi.logic.wires.WireArray; -import era.mi.logic.wires.WireArray.WireArrayEnd; +import era.mi.logic.wires.Wire; +import era.mi.logic.wires.Wire.WireEnd; /** - * Models a multiplexer. Takes an arbitrary amount of outputs {@link WireArray}s, one of which, as determined by select, receives the input - * signal. + * Models a multiplexer. Takes an arbitrary amount of input {@link Wire}s, one of which, as determined by select, is put through to the + * output. * * @author Fabian Stemmler * */ public class Demux extends BasicComponent { - private final WireArray select, in; - private final WireArray[] outputs; - private final WireArrayEnd[] outputsI; + private final WireEnd select, in; + private final WireEnd[] outputs; private final int outputSize; private int selected = -1; /** - * Output {@link WireArray}s and in must be of uniform length + * Input {@link Wire}s and out must be of uniform length * - * @param in Must be of uniform length with all outputs. - * @param select Indexes the output array to which the input is mapped. Must have enough bits to index all outputs. - * @param outputs One of these outputs receives the input signal, depending on the select bits + * @param out Must be of uniform length with all inputs. + * @param select Indexes the input array which is to be mapped to the output. Must have enough bits to index all inputs. + * @param outputs One of these inputs is mapped to the output, depending on the select bits */ - public Demux(int processTime, WireArray in, WireArray select, WireArray... outputs) + public Demux(int processTime, WireEnd in, WireEnd select, WireEnd... outputs) { super(processTime); - outputSize = in.length; + outputSize = in.length(); this.in = in; this.outputs = outputs; - this.outputsI = new WireArrayEnd[outputs.length]; - for (int i = 0; i < this.outputsI.length; i++) + for (int i = 0; i < this.outputs.length; i++) { - if (outputs[i].length != outputSize) + if (outputs[i].length() != outputSize) throw new IllegalArgumentException("All DEMUX wire arrays must be of uniform length!"); - this.outputsI[i] = outputs[i].createInput(); + this.outputs[i] = outputs[i]; } this.select = select; select.addObserver(this); - int maxInputs = 1 << select.length; - if (this.outputsI.length > maxInputs) - throw new IllegalArgumentException("There are more outputs (" + this.outputsI.length + ") to the DEMUX than supported by " - + select.length + " select bits (" + maxInputs + ")."); + int maxInputs = 1 << select.length(); + if (this.outputs.length > maxInputs) + throw new IllegalArgumentException("There are more outputs (" + this.outputs.length + ") to the DEMUX than supported by " + + select.length() + " select bits (" + maxInputs + ")."); in.addObserver(this); } @@ -56,27 +56,27 @@ public class Demux extends BasicComponent public void compute() { int selectValue = select.hasNumericValue() ? (int) select.getUnsignedValue() : -1; - if (selectValue >= outputsI.length) + if (selectValue >= outputs.length) selectValue = -1; if (selected != selectValue && selected != -1) - outputsI[selected].clearSignals(); + outputs[selected].clearSignals(); selected = selectValue; if (selectValue != -1) - outputsI[selectValue].feedSignals(in.getValues()); + outputs[selectValue].feedSignals(in.getValues()); } @Override - public List getAllInputs() + public List getAllInputs() { - return List.of(in, select); + return Collections.unmodifiableList(Arrays.asList(in, select)); } @Override - public List getAllOutputs() + public List getAllOutputs() { - return List.of(outputs); + return Collections.unmodifiableList(Arrays.asList(outputs)); } } diff --git a/era.mi/src/era/mi/logic/components/ManualSwitch.java b/era.mi/src/era/mi/logic/components/ManualSwitch.java index c56d8026..19ece81a 100644 --- a/era.mi/src/era/mi/logic/components/ManualSwitch.java +++ b/era.mi/src/era/mi/logic/components/ManualSwitch.java @@ -3,8 +3,7 @@ package era.mi.logic.components; import java.util.List; import era.mi.logic.Bit; -import era.mi.logic.wires.WireArray; -import era.mi.logic.wires.WireArray.WireArrayEnd; +import era.mi.logic.wires.Wire.WireEnd; /** * This class models a simple on/off (ONE/ZERO) switch for user interaction. @@ -14,16 +13,14 @@ import era.mi.logic.wires.WireArray.WireArrayEnd; */ public class ManualSwitch implements Component { - private WireArray output; - private WireArrayEnd outputI; + private WireEnd output; private boolean isOn; - public ManualSwitch(WireArray output) + public ManualSwitch(WireEnd output) { - if (output.length != 1) + if (output.length() != 1) throw new IllegalArgumentException("Switch output can be only a single wire"); this.output = output; - this.outputI = output.createInput(); } public void switchOn() @@ -46,7 +43,7 @@ public class ManualSwitch implements Component if (this.isOn == isOn) return; this.isOn = isOn; - outputI.feedSignals(getValue()); + output.feedSignals(getValue()); } public boolean isOn() @@ -60,13 +57,13 @@ public class ManualSwitch implements Component } @Override - public List getAllInputs() + public List getAllInputs() { return List.of(); } @Override - public List getAllOutputs() + public List getAllOutputs() { return List.of(output); } diff --git a/era.mi/src/era/mi/logic/components/Merger.java b/era.mi/src/era/mi/logic/components/Merger.java index da9b55e3..225a35a9 100644 --- a/era.mi/src/era/mi/logic/components/Merger.java +++ b/era.mi/src/era/mi/logic/components/Merger.java @@ -1,82 +1,84 @@ package era.mi.logic.components; +import java.util.Arrays; +import java.util.Collections; import java.util.List; import era.mi.logic.Bit; -import era.mi.logic.wires.WireArray; -import era.mi.logic.wires.WireArray.WireArrayEnd; +import era.mi.logic.wires.Wire; +import era.mi.logic.wires.Wire.WireEnd; import era.mi.logic.wires.WireArrayObserver; public class Merger implements WireArrayObserver, Component { - private WireArrayEnd outI; - private WireArray[] inputs; + private WireEnd out; + private WireEnd[] inputs; private int[] beginningIndex; /** * - * @param union The output of merging n {@link WireArray}s into one. Must have length = a1.length() + a2.length() + ... + an.length(). + * @param union The output of merging n {@link Wire}s into one. Must have length = a1.length() + a2.length() + ... + an.length(). * @param inputs The inputs to be merged into the union */ - public Merger(WireArray union, WireArray... inputs) + public Merger(WireEnd union, WireEnd... inputs) { this.inputs = inputs; - this.outI = union.createInput(); + this.out = union; this.beginningIndex = new int[inputs.length]; int length = 0; for (int i = 0; i < inputs.length; i++) { beginningIndex[i] = length; - length += inputs[i].length; + length += inputs[i].length(); inputs[i].addObserver(this); } - if (length != union.length) + if (length != union.length()) throw new IllegalArgumentException( "The output of merging n WireArrays into one must have length = a1.length() + a2.length() + ... + an.length()."); } - public WireArray getInput(int index) + public WireEnd getInput(int index) { return inputs[index]; } - public WireArray getUnion() + public WireEnd getUnion() { - return outI.owner; + return out; } @Override - public void update(WireArray initiator, Bit[] oldValues) + public void update(Wire initiator, Bit[] oldValues) { int index = find(initiator); int beginning = beginningIndex[index]; - outI.feedSignals(beginning, initiator.getValues()); + out.feedSignals(beginning, inputs[index].getValues()); } - private int find(WireArray w) + private int find(Wire w) { for (int i = 0; i < inputs.length; i++) - if (inputs[i] == w) + if (inputs[i].getWire() == w) return i; return -1; } - public WireArray[] getInputs() + public WireEnd[] getInputs() { return inputs.clone(); } @Override - public List getAllInputs() + public List getAllInputs() { - return List.of(inputs); + return Collections.unmodifiableList(Arrays.asList(inputs)); } @Override - public List getAllOutputs() + public List getAllOutputs() { - return List.of(outI.owner); + return Collections.unmodifiableList(Arrays.asList(out)); } } diff --git a/era.mi/src/era/mi/logic/components/Mux.java b/era.mi/src/era/mi/logic/components/Mux.java index 17680969..0cb4e383 100644 --- a/era.mi/src/era/mi/logic/components/Mux.java +++ b/era.mi/src/era/mi/logic/components/Mux.java @@ -5,11 +5,11 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -import era.mi.logic.wires.WireArray; -import era.mi.logic.wires.WireArray.WireArrayEnd; +import era.mi.logic.wires.Wire; +import era.mi.logic.wires.Wire.WireEnd; /** - * Models a multiplexer. Takes an arbitrary amount of input {@link WireArray}s, one of which, as determined by select, is put through to the + * Models a multiplexer. Takes an arbitrary amount of input {@link Wire}s, one of which, as determined by select, is put through to the * output. * * @author Fabian Stemmler @@ -17,27 +17,27 @@ import era.mi.logic.wires.WireArray.WireArrayEnd; */ public class Mux extends BasicComponent { - private WireArray select; - private WireArrayEnd outI; - private WireArray[] inputs; + private WireEnd select; + private WireEnd out; + private WireEnd[] inputs; private final int outputSize; /** - * Input {@link WireArray}s and out must be of uniform length + * Input {@link Wire}s and out must be of uniform length * * @param out Must be of uniform length with all inputs. * @param select Indexes the input array which is to be mapped to the output. Must have enough bits to index all inputs. * @param inputs One of these inputs is mapped to the output, depending on the select bits */ - public Mux(int processTime, WireArray out, WireArray select, WireArray... inputs) + public Mux(int processTime, WireEnd out, WireEnd select, WireEnd... inputs) { super(processTime); - outputSize = out.length; + outputSize = out.length(); this.inputs = inputs.clone(); for (int i = 0; i < this.inputs.length; i++) { - if (inputs[i].length != outputSize) + if (inputs[i].length() != outputSize) throw new IllegalArgumentException("All MUX wire arrays must be of uniform length!"); inputs[i].addObserver(this); } @@ -45,20 +45,20 @@ public class Mux extends BasicComponent this.select = select; select.addObserver(this); - int maxInputs = 1 << select.length; + int maxInputs = 1 << select.length(); if (this.inputs.length > maxInputs) throw new IllegalArgumentException("There are more inputs (" + this.inputs.length + ") to the MUX than supported by " - + select.length + " select bits (" + maxInputs + ")."); + + select.length() + " select bits (" + maxInputs + ")."); - outI = out.createInput(); + this.out = out; } - public WireArray getOut() + public WireEnd getOut() { - return outI.owner; + return out; } - public WireArray getSelect() + public WireEnd getSelect() { return select; } @@ -69,25 +69,25 @@ public class Mux extends BasicComponent int selectValue; if (!select.hasNumericValue() || (selectValue = (int) select.getUnsignedValue()) >= inputs.length) { - outI.clearSignals(); + out.clearSignals(); return; } - WireArray active = inputs[selectValue]; - outI.feedSignals(active.getValues()); + WireEnd active = inputs[selectValue]; + out.feedSignals(active.getValues()); } @Override - public List getAllInputs() + public List getAllInputs() { - ArrayList wires = new ArrayList(Arrays.asList(inputs)); + ArrayList wires = new ArrayList(Arrays.asList(inputs)); wires.add(select); return Collections.unmodifiableList(wires); } @Override - public List getAllOutputs() + public List getAllOutputs() { - return List.of(outI.owner); + return Collections.unmodifiableList(Arrays.asList(out)); } } diff --git a/era.mi/src/era/mi/logic/components/Splitter.java b/era.mi/src/era/mi/logic/components/Splitter.java index 37e94015..127f70d1 100644 --- a/era.mi/src/era/mi/logic/components/Splitter.java +++ b/era.mi/src/era/mi/logic/components/Splitter.java @@ -1,25 +1,25 @@ package era.mi.logic.components; import era.mi.logic.Bit; -import era.mi.logic.wires.WireArray; -import era.mi.logic.wires.WireArray.WireArrayEnd; +import era.mi.logic.wires.Wire; +import era.mi.logic.wires.Wire.WireEnd; import era.mi.logic.wires.WireArrayObserver; public class Splitter implements WireArrayObserver { - private WireArray input; - private WireArrayEnd[] outputs; + private WireEnd input; + private WireEnd[] outputs; - public Splitter(WireArray input, WireArray... outputs) + public Splitter(WireEnd input, WireEnd... outputs) { this.input = input; - this.outputs = WireArray.extractInputs(outputs); + this.outputs = outputs; input.addObserver(this); int length = 0; - for (WireArray out : outputs) - length += out.length; + for (WireEnd out : outputs) + length += out.length(); - if (input.length != length) + if (input.length() != length) throw new IllegalArgumentException( "The input of splitting one into n WireArrays must have length = a1.length() + a2.length() + ... + an.length()."); } @@ -30,15 +30,15 @@ public class Splitter implements WireArrayObserver Bit[] inputBits = input.getValues(); for (int i = 0; i < outputs.length; i++) { - Bit[] outputBits = new Bit[outputs[i].owner.length]; - System.arraycopy(inputBits, startIndex, outputBits, 0, outputs[i].owner.length); + Bit[] outputBits = new Bit[outputs[i].length()]; + System.arraycopy(inputBits, startIndex, outputBits, 0, outputs[i].length()); outputs[i].feedSignals(outputBits); - startIndex += outputs[i].owner.length; + startIndex += outputs[i].length(); } } @Override - public void update(WireArray initiator, Bit[] oldValues) + public void update(Wire initiator, Bit[] oldValues) { compute(); } diff --git a/era.mi/src/era/mi/logic/components/TriStateBuffer.java b/era.mi/src/era/mi/logic/components/TriStateBuffer.java index 0a7133f2..2b72bad4 100644 --- a/era.mi/src/era/mi/logic/components/TriStateBuffer.java +++ b/era.mi/src/era/mi/logic/components/TriStateBuffer.java @@ -1,50 +1,52 @@ package era.mi.logic.components; +import java.util.Arrays; +import java.util.Collections; import java.util.List; import era.mi.logic.Bit; -import era.mi.logic.wires.WireArray; -import era.mi.logic.wires.WireArray.WireArrayEnd; +import era.mi.logic.wires.Wire; +import era.mi.logic.wires.Wire.WireEnd; public class TriStateBuffer extends BasicComponent { - WireArray in, enable; - WireArrayEnd outI; + WireEnd in, enable; + WireEnd out; - public TriStateBuffer(int processTime, WireArray in, WireArray out, WireArray enable) + public TriStateBuffer(int processTime, WireEnd in, WireEnd out, WireEnd enable) { super(processTime); - if (in.length != out.length) + if (in.length() != out.length()) throw new IllegalArgumentException( - "Tri-state output must have the same amount of bits as the input. Input: " + in.length + " Output: " + out.length); - if (enable.length != 1) - throw new IllegalArgumentException("Tri-state enable must have exactly one bit, not " + enable.length + "."); + "Tri-state output must have the same amount of bits as the input. Input: " + in.length() + " Output: " + out.length()); + if (enable.length() != 1) + throw new IllegalArgumentException("Tri-state enable must have exactly one bit, not " + enable.length() + "."); this.in = in; in.addObserver(this); this.enable = enable; enable.addObserver(this); - outI = out.createInput(); + this.out = out; } @Override protected void compute() { if (enable.getValue() == Bit.ONE) - outI.feedSignals(in.getValues()); + out.feedSignals(in.getValues()); else - outI.clearSignals(); + out.clearSignals(); } @Override - public List getAllInputs() + public List getAllInputs() { - return List.of(in, enable); + return Collections.unmodifiableList(Arrays.asList(in, enable)); } @Override - public List getAllOutputs() + public List getAllOutputs() { - return List.of(outI.owner); + return Collections.unmodifiableList(Arrays.asList(out)); } } diff --git a/era.mi/src/era/mi/logic/components/gates/AndGate.java b/era.mi/src/era/mi/logic/components/gates/AndGate.java index 853fecc6..2722f036 100644 --- a/era.mi/src/era/mi/logic/components/gates/AndGate.java +++ b/era.mi/src/era/mi/logic/components/gates/AndGate.java @@ -1,11 +1,11 @@ package era.mi.logic.components.gates; import era.mi.logic.Util; -import era.mi.logic.wires.WireArray; +import era.mi.logic.wires.Wire.WireEnd; public class AndGate extends MultiInputGate { - public AndGate(int processTime, WireArray out, WireArray... in) + public AndGate(int processTime, WireEnd out, WireEnd... in) { super(processTime, Util::and, out, in); } diff --git a/era.mi/src/era/mi/logic/components/gates/MultiInputGate.java b/era.mi/src/era/mi/logic/components/gates/MultiInputGate.java index fac267a2..7a6d4388 100644 --- a/era.mi/src/era/mi/logic/components/gates/MultiInputGate.java +++ b/era.mi/src/era/mi/logic/components/gates/MultiInputGate.java @@ -1,57 +1,55 @@ package era.mi.logic.components.gates; +import java.util.Arrays; +import java.util.Collections; import java.util.List; import era.mi.logic.Bit; import era.mi.logic.components.BasicComponent; -import era.mi.logic.wires.WireArray; -import era.mi.logic.wires.WireArray.WireArrayEnd; +import era.mi.logic.wires.Wire.WireEnd; public abstract class MultiInputGate extends BasicComponent { - protected WireArray[] in; - protected WireArray out; - protected WireArrayEnd outI; + protected WireEnd[] in; + protected WireEnd out; protected final int length; protected Operation op; - protected MultiInputGate(int processTime, Operation op, WireArray out, WireArray... in) + protected MultiInputGate(int processTime, Operation op, WireEnd out, WireEnd... in) { super(processTime); this.op = op; - length = out.length; + length = out.length(); this.in = in.clone(); if (in.length < 1) throw new IllegalArgumentException(String.format("Cannot create gate with %d wires.", in.length)); - for (WireArray w : in) + for (WireEnd w : in) { - if (w.length != length) + if (w.length() != length) throw new IllegalArgumentException("All wires connected to the gate must be of uniform length."); w.addObserver(this); } this.out = out; - outI = out.createInput(); } @Override - public List getAllInputs() + public List getAllInputs() { - return List.of(in); + return Collections.unmodifiableList(Arrays.asList(in)); } @Override - public List getAllOutputs() + public List getAllOutputs() { - return List.of(out); + return Collections.unmodifiableList(Arrays.asList(out)); } - @Override protected void compute() { Bit[] result = in[0].getValues(); for (int i = 1; i < in.length; i++) result = op.execute(result, in[i].getValues()); - outI.feedSignals(result); + out.feedSignals(result); } protected interface Operation diff --git a/era.mi/src/era/mi/logic/components/gates/NotGate.java b/era.mi/src/era/mi/logic/components/gates/NotGate.java index f6644714..f65a174c 100644 --- a/era.mi/src/era/mi/logic/components/gates/NotGate.java +++ b/era.mi/src/era/mi/logic/components/gates/NotGate.java @@ -1,51 +1,51 @@ package era.mi.logic.components.gates; +import java.util.Arrays; +import java.util.Collections; import java.util.List; import era.mi.logic.Util; import era.mi.logic.components.BasicComponent; -import era.mi.logic.wires.WireArray; -import era.mi.logic.wires.WireArray.WireArrayEnd; +import era.mi.logic.wires.Wire.WireEnd; public class NotGate extends BasicComponent { - private WireArray in, out; - private WireArrayEnd outI; + private WireEnd in; + private WireEnd out; - public NotGate(int processTime, WireArray in, WireArray out) + public NotGate(int processTime, WireEnd in, WireEnd out) { super(processTime); this.in = in; in.addObserver(this); this.out = out; - outI = out.createInput(); } @Override - public void compute() + protected void compute() { - outI.feedSignals(Util.not(in.getValues())); + out.feedSignals(Util.not(in.getValues())); } - public WireArray getIn() + public WireEnd getIn() { return in; } - public WireArray getOut() + public WireEnd getOut() { return out; } @Override - public List getAllInputs() + public List getAllInputs() { - return List.of(in); + return Collections.unmodifiableList(Arrays.asList(in)); } @Override - public List getAllOutputs() + public List getAllOutputs() { - return List.of(out); + return Collections.unmodifiableList(Arrays.asList(out)); } } diff --git a/era.mi/src/era/mi/logic/components/gates/OrGate.java b/era.mi/src/era/mi/logic/components/gates/OrGate.java index 0050a77a..ba8262a8 100644 --- a/era.mi/src/era/mi/logic/components/gates/OrGate.java +++ b/era.mi/src/era/mi/logic/components/gates/OrGate.java @@ -1,11 +1,11 @@ package era.mi.logic.components.gates; import era.mi.logic.Util; -import era.mi.logic.wires.WireArray; +import era.mi.logic.wires.Wire.WireEnd; public class OrGate extends MultiInputGate { - public OrGate(int processTime, WireArray out, WireArray... in) + public OrGate(int processTime, WireEnd out, WireEnd... in) { super(processTime, Util::or, out, in); } diff --git a/era.mi/src/era/mi/logic/components/gates/XorGate.java b/era.mi/src/era/mi/logic/components/gates/XorGate.java index ad2f8296..71fcb213 100644 --- a/era.mi/src/era/mi/logic/components/gates/XorGate.java +++ b/era.mi/src/era/mi/logic/components/gates/XorGate.java @@ -1,7 +1,7 @@ package era.mi.logic.components.gates; import era.mi.logic.Util; -import era.mi.logic.wires.WireArray; +import era.mi.logic.wires.Wire.WireEnd; /** * Outputs 1 when the number of 1 inputs is odd. @@ -10,7 +10,7 @@ import era.mi.logic.wires.WireArray; */ public class XorGate extends MultiInputGate { - public XorGate(int processTime, WireArray out, WireArray... in) + public XorGate(int processTime, WireEnd out, WireEnd... in) { super(processTime, Util::xor, out, in); } diff --git a/era.mi/src/era/mi/logic/tests/ComponentTest.java b/era.mi/src/era/mi/logic/tests/ComponentTest.java index 532d364f..398c18fe 100644 --- a/era.mi/src/era/mi/logic/tests/ComponentTest.java +++ b/era.mi/src/era/mi/logic/tests/ComponentTest.java @@ -9,7 +9,6 @@ import org.junit.jupiter.api.Test; import era.mi.logic.Bit; import era.mi.logic.Simulation; -import era.mi.logic.components.Connector; import era.mi.logic.components.Demux; import era.mi.logic.components.Merger; import era.mi.logic.components.Mux; @@ -19,10 +18,9 @@ import era.mi.logic.components.gates.AndGate; import era.mi.logic.components.gates.NotGate; import era.mi.logic.components.gates.OrGate; import era.mi.logic.components.gates.XorGate; -import era.mi.logic.wires.WireArray; -import era.mi.logic.wires.WireArray.WireArrayEnd; +import era.mi.logic.wires.Wire; +import era.mi.logic.wires.Wire.WireEnd; -@SuppressWarnings("unused") class ComponentTest { @@ -30,20 +28,20 @@ class ComponentTest void circuitExampleTest() { Simulation.TIMELINE.reset(); - WireArray a = new WireArray(1, 1), b = new WireArray(1, 1), c = new WireArray(1, 10), d = new WireArray(2, 1), - e = new WireArray(1, 1), f = new WireArray(1, 1), g = new WireArray(1, 1), h = new WireArray(2, 1), i = new WireArray(2, 1), - j = new WireArray(1, 1), k = new WireArray(1, 1); - new AndGate(1, f, a, b); - new NotGate(1, f, g); - new Merger(h, c, g); - new Mux(1, i, e, h, d); - new Splitter(i, k, j); - - a.createInput().feedSignals(Bit.ZERO); - b.createInput().feedSignals(Bit.ONE); - c.createInput().feedSignals(Bit.ZERO); - d.createInput().feedSignals(Bit.ONE, Bit.ONE); - e.createInput().feedSignals(Bit.ZERO); + Wire a = new Wire(1, 1), b = new Wire(1, 1), c = new Wire(1, 10), d = new Wire(2, 1), + e = new Wire(1, 1), f = new Wire(1, 1), g = new Wire(1, 1), h = new Wire(2, 1), i = new Wire(2, 1), + j = new Wire(1, 1), k = new Wire(1, 1); + new AndGate(1, f.createEnd(), a.createEnd(), b.createEnd()); + new NotGate(1, f.createEnd(), g.createEnd()); + new Merger(h.createEnd(), c.createEnd(), g.createEnd()); + new Mux(1, i.createEnd(), e.createEnd(), h.createEnd(), d.createEnd()); + new Splitter(i.createEnd(), k.createEnd(), j.createEnd()); + + a.createEnd().feedSignals(Bit.ZERO); + b.createEnd().feedSignals(Bit.ONE); + c.createEnd().feedSignals(Bit.ZERO); + d.createEnd().feedSignals(Bit.ONE, Bit.ONE); + e.createEnd().feedSignals(Bit.ZERO); Simulation.TIMELINE.executeAll(); @@ -55,9 +53,9 @@ class ComponentTest void splitterTest() { Simulation.TIMELINE.reset(); - WireArray a = new WireArray(3, 1), b = new WireArray(2, 1), c = new WireArray(3, 1), in = new WireArray(8, 1); - in.createInput().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE); - new Splitter(in, a, b, c); + Wire a = new Wire(3, 1), b = new Wire(2, 1), c = new Wire(3, 1), in = new Wire(8, 1); + in.createEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE); + new Splitter(in.createEnd(), a.createEnd(), b.createEnd(), c.createEnd()); Simulation.TIMELINE.executeAll(); @@ -70,12 +68,12 @@ class ComponentTest void mergerTest() { Simulation.TIMELINE.reset(); - WireArray a = new WireArray(3, 1), b = new WireArray(2, 1), c = new WireArray(3, 1), out = new WireArray(8, 1); - a.createInput().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO); - b.createInput().feedSignals(Bit.ONE, Bit.ZERO); - c.createInput().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE); + Wire a = new Wire(3, 1), b = new Wire(2, 1), c = new Wire(3, 1), out = new Wire(8, 1); + a.createEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO); + b.createEnd().feedSignals(Bit.ONE, Bit.ZERO); + c.createEnd().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE); - new Merger(out, a, b, c); + new Merger(out.createEnd(), a.createEnd(), b.createEnd(), c.createEnd()); Simulation.TIMELINE.executeAll(); @@ -86,15 +84,14 @@ class ComponentTest @Test void triStateBufferTest() { - WireArray a = new WireArray(1, 1), b = new WireArray(1, 1), en = new WireArray(1, 1), notEn = new WireArray(1, 1); - new NotGate(1, en, notEn); - new TriStateBuffer(1, a, b, en); - new TriStateBuffer(1, b, a, notEn); + Wire a = new Wire(1, 1), b = new Wire(1, 1), en = new Wire(1, 1), notEn = new Wire(1, 1); + new NotGate(1, en.createEnd(), notEn.createEnd()); + new TriStateBuffer(1, a.createEnd(), b.createEnd(), en.createEnd()); + new TriStateBuffer(1, b.createEnd(), a.createEnd(), notEn.createEnd()); - WireArrayEnd enI = en.createInput(), aI = a.createInput(), bI = b.createInput(); + WireEnd enI = en.createEnd(), aI = a.createEnd(), bI = b.createEnd(); enI.feedSignals(Bit.ONE); aI.feedSignals(Bit.ONE); - bI.feedSignals(Bit.Z); Simulation.TIMELINE.executeAll(); @@ -120,15 +117,15 @@ class ComponentTest void muxTest() { Simulation.TIMELINE.reset(); - WireArray a = new WireArray(4, 3), b = new WireArray(4, 6), c = new WireArray(4, 4), select = new WireArray(2, 5), - out = new WireArray(4, 1); - WireArrayEnd selectIn = select.createInput(); + Wire a = new Wire(4, 3), b = new Wire(4, 6), c = new Wire(4, 4), select = new Wire(2, 5), + out = new Wire(4, 1); + WireEnd selectIn = select.createEnd(); selectIn.feedSignals(Bit.ZERO, Bit.ZERO); - a.createInput().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO); - c.createInput().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE); + a.createEnd().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO); + c.createEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE); - new Mux(1, out, select, a, b, c); + new Mux(1, out.createEnd(), select.createEnd(), a.createEnd(), b.createEnd(), c.createEnd()); Simulation.TIMELINE.executeAll(); assertBitArrayEquals(out.getValues(), Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO); @@ -148,14 +145,14 @@ class ComponentTest void demuxTest() { Simulation.TIMELINE.reset(); - WireArray a = new WireArray(4, 3), b = new WireArray(4, 6), c = new WireArray(4, 4), select = new WireArray(2, 5), - in = new WireArray(4, 1); - WireArrayEnd selectIn = select.createInput(); + Wire a = new Wire(4, 3), b = new Wire(4, 6), c = new Wire(4, 4), select = new Wire(2, 5), + in = new Wire(4, 1); + WireEnd selectIn = select.createEnd(); selectIn.feedSignals(Bit.ZERO, Bit.ZERO); - in.createInput().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO); + in.createEnd().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO); - new Demux(1, in, select, a, b, c); + new Demux(1, in.createEnd(), select.createEnd(), a.createEnd(), b.createEnd(), c.createEnd()); Simulation.TIMELINE.executeAll(); assertBitArrayEquals(a.getValues(), Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO); @@ -181,10 +178,10 @@ class ComponentTest void andTest() { Simulation.TIMELINE.reset(); - WireArray a = new WireArray(4, 1), b = new WireArray(4, 3), c = new WireArray(4, 1); - new AndGate(1, c, a, b); - a.createInput().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO); - b.createInput().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE); + Wire a = new Wire(4, 1), b = new Wire(4, 3), c = new Wire(4, 1); + new AndGate(1, c.createEnd(), a.createEnd(), b.createEnd()); + a.createEnd().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO); + b.createEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE); Simulation.TIMELINE.executeAll(); @@ -195,10 +192,10 @@ class ComponentTest void orTest() { Simulation.TIMELINE.reset(); - WireArray a = new WireArray(4, 1), b = new WireArray(4, 3), c = new WireArray(4, 1); - new OrGate(1, c, a, b); - a.createInput().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO); - b.createInput().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE); + Wire a = new Wire(4, 1), b = new Wire(4, 3), c = new Wire(4, 1); + new OrGate(1, c.createEnd(), a.createEnd(), b.createEnd()); + a.createEnd().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO); + b.createEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE); Simulation.TIMELINE.executeAll(); @@ -209,30 +206,43 @@ class ComponentTest void xorTest() { Simulation.TIMELINE.reset(); - WireArray a = new WireArray(3, 1), b = new WireArray(3, 2), c = new WireArray(3, 1), d = new WireArray(3, 1); - new XorGate(1, d, a, b, c); - a.createInput().feedSignals(Bit.ZERO, Bit.ONE, Bit.ONE); - b.createInput().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE); - c.createInput().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE); + Wire a = new Wire(3, 1), b = new Wire(3, 2), c = new Wire(3, 1), d = new Wire(3, 1); + new XorGate(1, d.createEnd(), a.createEnd(), b.createEnd(), c.createEnd()); + a.createEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ONE); + b.createEnd().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE); + c.createEnd().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE); Simulation.TIMELINE.executeAll(); assertBitArrayEquals(d.getValues(), Bit.ZERO, Bit.ONE, Bit.ONE); } + + @Test + void notTest() + { + Simulation.TIMELINE.reset(); + Wire a = new Wire(3, 1), b = new Wire(3, 2); + new NotGate(1, a.createEnd(), b.createEnd()); + a.createEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ONE); + + Simulation.TIMELINE.executeAll(); + + assertBitArrayEquals(b.getValues(), Bit.ONE, Bit.ZERO, Bit.ZERO); + } @Test void rsLatchCircuitTest() { Simulation.TIMELINE.reset(); - WireArray r = new WireArray(1, 1), s = new WireArray(1, 1), t1 = new WireArray(1, 15), t2 = new WireArray(1, 1), - q = new WireArray(1, 1), nq = new WireArray(1, 1); + Wire r = new Wire(1, 1), s = new Wire(1, 1), t1 = new Wire(1, 15), t2 = new Wire(1, 1), + q = new Wire(1, 1), nq = new Wire(1, 1); - new OrGate(1, t2, r, nq); - new OrGate(1, t1, s, q); - new NotGate(1, t2, q); - new NotGate(1, t1, nq); + new OrGate(1, t2.createEnd(), r.createEnd(), nq.createEnd()); + new OrGate(1, t1.createEnd(), s.createEnd(), q.createEnd()); + new NotGate(1, t2.createEnd(), q.createEnd()); + new NotGate(1, t1.createEnd(), nq.createEnd()); - WireArrayEnd sIn = s.createInput(), rIn = r.createInput(); + WireEnd sIn = s.createEnd(), rIn = r.createEnd(); sIn.feedSignals(Bit.ONE); rIn.feedSignals(Bit.ZERO); @@ -261,8 +271,8 @@ class ComponentTest { Simulation.TIMELINE.reset(); - WireArray a = new WireArray(4, 1); - a.createInput().feedSignals(Bit.ONE, Bit.ONE, Bit.ONE, Bit.ONE); + Wire a = new Wire(4, 1); + a.createEnd().feedSignals(Bit.ONE, Bit.ONE, Bit.ONE, Bit.ONE); Simulation.TIMELINE.executeAll(); @@ -274,8 +284,8 @@ class ComponentTest void multipleInputs() { Simulation.TIMELINE.reset(); - WireArray w = new WireArray(2, 1); - WireArrayEnd wI1 = w.createInput(), wI2 = w.createInput(); + Wire w = new Wire(2, 1); + WireEnd wI1 = w.createEnd(), wI2 = w.createEnd(); wI1.feedSignals(Bit.ONE, Bit.Z); wI2.feedSignals(Bit.Z, Bit.X); Simulation.TIMELINE.executeAll(); @@ -295,22 +305,22 @@ class ComponentTest assertBitArrayEquals(w.getValues(), Bit.ONE, Bit.Z); } - @Test +// @Test void wireConnections() { // Nur ein Experiment, was über mehrere 'passive' Bausteine hinweg passieren würde Simulation.TIMELINE.reset(); - WireArray a = new WireArray(1, 2); - WireArray b = new WireArray(1, 2); - WireArray c = new WireArray(1, 2); - WireArrayEnd aI = a.createInput(); - WireArrayEnd bI = b.createInput(); - WireArrayEnd cI = c.createInput(); + Wire a = new Wire(1, 2); + Wire b = new Wire(1, 2); + Wire c = new Wire(1, 2); + WireEnd aI = a.createEnd(); + WireEnd bI = b.createEnd(); + WireEnd cI = c.createEnd(); - TestBitDisplay test = new TestBitDisplay(c); - TestBitDisplay test2 = new TestBitDisplay(a); + TestBitDisplay test = new TestBitDisplay(c.createEnd()); + TestBitDisplay test2 = new TestBitDisplay(a.createEnd()); LongConsumer print = time -> System.out.format("Time %2d\n a: %s\n b: %s\n c: %s\n", time, a, b, c); cI.feedSignals(Bit.ONE); @@ -323,7 +333,7 @@ class ComponentTest cI.feedSignals(Bit.Z); test.assertAfterSimulationIs(print, Bit.Z); - new Connector(b, c).connect(); + new Connector(b, c); test.assertAfterSimulationIs(print, Bit.Z); System.err.println("ONE"); bI.feedSignals(Bit.ONE); @@ -335,7 +345,7 @@ class ComponentTest bI.feedSignals(Bit.Z); test.assertAfterSimulationIs(print, Bit.Z); - new Connector(a, b).connect(); + new Connector(a, b); System.err.println("Z 2"); aI.feedSignals(Bit.Z); test.assertAfterSimulationIs(print, Bit.Z); diff --git a/era.mi/src/era/mi/logic/tests/Connector.java b/era.mi/src/era/mi/logic/tests/Connector.java new file mode 100644 index 00000000..12c407a5 --- /dev/null +++ b/era.mi/src/era/mi/logic/tests/Connector.java @@ -0,0 +1,39 @@ +package era.mi.logic.tests; + +import era.mi.logic.Bit; +import era.mi.logic.Simulation; +import era.mi.logic.wires.Wire; +import era.mi.logic.wires.Wire.WireEnd; +import era.mi.logic.wires.WireArrayObserver; + +public class Connector implements WireArrayObserver +{ + private final Wire a; +// private final WireArray b; + private final WireEnd aI; + private final WireEnd bI; + + public Connector(Wire a, Wire b) + { + if (a.length != b.length) + throw new IllegalArgumentException(String.format("WireArray width does not match: %d, %d", a.length, b.length)); + this.a = a; +// this.b = b; + a.addObserver(this); + b.addObserver(this); + aI = a.createEnd(); + bI = b.createEnd(); + } + + @Override + public void update(Wire initiator, Bit[] oldValues) + { + Simulation.TIMELINE.addEvent((e) -> + { + if (initiator == a) + bI.feedSignals(aI.wireValuesExcludingMe()); + else + aI.feedSignals(bI.wireValuesExcludingMe()); + }, 1); + } +} diff --git a/era.mi/src/era/mi/logic/tests/GUITest.java b/era.mi/src/era/mi/logic/tests/GUITest.java index 36a4886a..2599b542 100644 --- a/era.mi/src/era/mi/logic/tests/GUITest.java +++ b/era.mi/src/era/mi/logic/tests/GUITest.java @@ -20,7 +20,7 @@ import era.mi.logic.components.ManualSwitch; import era.mi.logic.components.gates.NotGate; import era.mi.logic.components.gates.OrGate; import era.mi.logic.timeline.Timeline.ExecutionResult; -import era.mi.logic.wires.WireArray; +import era.mi.logic.wires.Wire; public class GUITest extends JPanel { @@ -31,20 +31,20 @@ public class GUITest extends JPanel private static final int OR_DELAY = 100; private static final int NOT_DELAY = 100; - WireArray r = new WireArray(1, WIRE_DELAY); - WireArray s = new WireArray(1, WIRE_DELAY); - WireArray t1 = new WireArray(1, WIRE_DELAY); - WireArray t2 = new WireArray(1, WIRE_DELAY); - WireArray q = new WireArray(1, WIRE_DELAY); - WireArray nq = new WireArray(1, WIRE_DELAY); + Wire r = new Wire(1, WIRE_DELAY); + Wire s = new Wire(1, WIRE_DELAY); + Wire t1 = new Wire(1, WIRE_DELAY); + Wire t2 = new Wire(1, WIRE_DELAY); + Wire q = new Wire(1, WIRE_DELAY); + Wire nq = new Wire(1, WIRE_DELAY); - ManualSwitch rIn = new ManualSwitch(r); - ManualSwitch sIn = new ManualSwitch(s); + ManualSwitch rIn = new ManualSwitch(r.createEnd()); + ManualSwitch sIn = new ManualSwitch(s.createEnd()); - OrGate or1 = new OrGate(OR_DELAY, t2, r, nq); - OrGate or2 = new OrGate(OR_DELAY, t1, s, q); - NotGate not1 = new NotGate(NOT_DELAY, t2, q); - NotGate not2 = new NotGate(NOT_DELAY, t1, nq); + OrGate or1 = new OrGate(OR_DELAY, t2.createEnd(), r.createEnd(), nq.createEnd()); + OrGate or2 = new OrGate(OR_DELAY, t1.createEnd(), s.createEnd(), q.createEnd()); + NotGate not1 = new NotGate(NOT_DELAY, t2.createEnd(), q.createEnd()); + NotGate not2 = new NotGate(NOT_DELAY, t1.createEnd(), nq.createEnd()); Map switchMap = new HashMap<>(); @@ -170,14 +170,14 @@ public class GUITest extends JPanel g.setFont(g.getFont().deriveFont(Math.min(height, width) / 40f)); } - private static void drawString(Graphics g, String s, int x, int y, double anchorX, double anchorY) + private void drawString(Graphics g, String s, int x, int y, double anchorX, double anchorY) { int h = g.getFontMetrics().getAscent(); int w = g.getFontMetrics().stringWidth(s); g.drawString(s, x - (int) (w * anchorX), y + (int) (h * anchorY)); } - private void drawWire(Graphics g, WireArray wa, String name, double x1, double y1, double x2, double y2) + private void drawWire(Graphics g, Wire wa, String name, double x1, double y1, double x2, double y2) { setTo(g, wa); g.drawLine(gX(x1), gY(y1), gX(x2), gY(y2)); @@ -224,7 +224,7 @@ public class GUITest extends JPanel g.setColor(Color.BLACK); } - private static void setTo(Graphics g, WireArray wa) + private static void setTo(Graphics g, Wire wa) { switch (wa.getValue()) { @@ -241,7 +241,7 @@ public class GUITest extends JPanel g.setColor(Color.BLACK); break; case U: - g.setColor(Color.MAGENTA); + g.setColor(Color.BLUE); break; default: throw new IllegalArgumentException(); @@ -282,7 +282,7 @@ public class GUITest extends JPanel gt.repaint(12); try { - Thread.sleep(Math.max(updateT - System.currentTimeMillis() + lastFrame, 0)); + Thread.sleep(Math.max(16 - System.currentTimeMillis() + lastFrame, 0)); } catch (Exception e) { diff --git a/era.mi/src/era/mi/logic/tests/TestBitDisplay.java b/era.mi/src/era/mi/logic/tests/TestBitDisplay.java index be4d95a6..0d976594 100644 --- a/era.mi/src/era/mi/logic/tests/TestBitDisplay.java +++ b/era.mi/src/era/mi/logic/tests/TestBitDisplay.java @@ -8,12 +8,12 @@ import java.util.function.LongConsumer; import era.mi.logic.Bit; import era.mi.logic.Simulation; import era.mi.logic.components.BitDisplay; -import era.mi.logic.wires.WireArray; +import era.mi.logic.wires.Wire.WireEnd; public final class TestBitDisplay extends BitDisplay { - public TestBitDisplay(WireArray in) + public TestBitDisplay(WireEnd in) { super(in); } diff --git a/era.mi/src/era/mi/logic/timeline/Timeline.java b/era.mi/src/era/mi/logic/timeline/Timeline.java index 8107db96..63d73950 100644 --- a/era.mi/src/era/mi/logic/timeline/Timeline.java +++ b/era.mi/src/era/mi/logic/timeline/Timeline.java @@ -90,7 +90,8 @@ public class Timeline { if (!hasNext()) return -1; - return events.peek().timing; + else + return events.peek().timing; } public void reset() @@ -126,7 +127,7 @@ public class Timeline private class InnerEvent { - final long timing; + private final long timing; private final TimelineEventHandler function; private final TimelineEvent event; diff --git a/era.mi/src/era/mi/logic/timeline/TimelineEvent.java b/era.mi/src/era/mi/logic/timeline/TimelineEvent.java index 46decf5f..b3eec8ca 100644 --- a/era.mi/src/era/mi/logic/timeline/TimelineEvent.java +++ b/era.mi/src/era/mi/logic/timeline/TimelineEvent.java @@ -22,7 +22,6 @@ public class TimelineEvent return timing; } - @Override public String toString() { return "timestamp: " + timing; diff --git a/era.mi/src/era/mi/logic/wires/Wire.java b/era.mi/src/era/mi/logic/wires/Wire.java new file mode 100644 index 00000000..5eac8894 --- /dev/null +++ b/era.mi/src/era/mi/logic/wires/Wire.java @@ -0,0 +1,467 @@ +package era.mi.logic.wires; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import era.mi.logic.Bit; +import era.mi.logic.Simulation; +import era.mi.logic.Util; + +/** + * Represents an array of wires that can store n bits of information. + * + * @author Fabian Stemmler + * + */ +public class Wire +{ + private Bit[] values; + public final int travelTime; + private List observers = new ArrayList(); + public final int length; + private List inputs = new ArrayList(); + + public Wire(int length, int travelTime) + { + if (length < 1) + throw new IllegalArgumentException( + String.format("Tried to create an array of wires with length %d, but a length of less than 1 makes no sense.", length)); + this.length = length; + this.travelTime = travelTime; + initValues(); + } + + private void initValues() + { + values = Bit.U.makeArray(length); + } + + private void recalculateSingleInput() + { + WireEnd input = inputs.get(0); + if (!Arrays.equals(input.getInputValues(), values)) + { + Bit[] oldValues = values.clone(); + System.arraycopy(input.getInputValues(), 0, values, 0, length); + notifyObservers(oldValues); + } + } + + private void recalculateMultipleInputs() + { + Iterator it = inputs.iterator(); + Bit[] newValues = it.next().inputValues.clone(); + + while (it.hasNext()) + { + WireEnd input = it.next(); + Bit[] bits = input.getInputValues(); + for (int i = 0; i < length; i++) + { + if (Bit.Z.equals(bits[i]) || newValues[i].equals(bits[i])) + continue; + else if (Bit.Z.equals(newValues[i])) + newValues[i] = bits[i]; + else + newValues[i] = Bit.X; + } + } + + if (!Arrays.equals(newValues, values)) + { + Bit[] oldValues = values; + values = newValues; + notifyObservers(oldValues); + } + } + + private void recalculate() + { + switch (inputs.size()) + { + case 0: + return; + case 1: + recalculateSingleInput(); + break; + default: + recalculateMultipleInputs(); + } + } + + /** + * The {@link Wire} is interpreted as an unsigned integer with n bits. + * + * @return true if all bits are either Bit.ONE or Bit.ZERO (they do not all have to have the same + * value), not Bit.X or Bit.Z. false is returned otherwise. + * + * @author Fabian Stemmler + */ + public boolean hasNumericValue() + { + for (Bit b : values) + { + if (b != Bit.ZERO && b != Bit.ONE) + return false; + } + return true; + } + + /** + * The {@link Wire} is interpreted as an unsigned integer with n bits. + * + * @return The unsigned value of the {@link Wire}'s bits, where value 0 corresponds with 2^0, value 1 is 2^1 and so on. + * + * @author Fabian Stemmler + */ + public long getUnsignedValue() + { + long val = 0; + long mask = 1; + for (int i = 0; i < length; i++) + { + switch (values[i]) + { + default: + case Z: + case X: + return 0; // TODO: Proper handling for getUnsignedValue(), if not all bits are 1 or 0; + // Random number? + case ONE: + val |= mask; + break; + case ZERO: + } + mask = mask << 1; + } + return val; + } + + /** + * The {@link Wire} is interpreted as a signed integer with n bits. + * + * @return The signed value of the {@link Wire}'s bits, where value 0 corresponds with 2^0, value 1 is 2^1 and so on. + * + * @author Fabian Stemmler + */ + public long getSignedValue() + { + long val = getUnsignedValue(); + long mask = 1 << (length - 1); + if ((mask & val) != 0) + { + int shifts = 64 - length; + return (val << shifts) >> shifts; + } + return val; + } + + public Bit getValue() + { + return getValue(0); + } + + public Bit getValue(int index) + { + return values[index]; + } + + public Bit[] getValues(int start, int end) + { + int length = end - start; + Bit[] bits = new Bit[length]; + System.arraycopy(values, start, bits, 0, length); + return bits; + } + + public Bit[] getValues() + { + return values.clone(); + } + + /** + * Adds an {@link WireArrayObserver}, who will be notified when the value of the {@link Wire} is updated. + * + * @param ob The {@link WireArrayObserver} to be notified of changes. + * @return true if the given {@link WireArrayObserver} was not already registered, false otherwise + * + * @author Fabian Stemmler + */ + public boolean addObserver(WireArrayObserver ob) + { + return observers.add(ob); + } + + private void notifyObservers(Bit[] oldValues) + { + for (WireArrayObserver o : observers) + o.update(this, oldValues); + } + + /** + * Create and register a {@link WireEnd} object, which is tied to this {@link Wire}. + */ + public WireEnd createEnd() + { + return new WireEnd(); + } + + private void registerInput(WireEnd toRegister) + { + inputs.add(toRegister); + } + + /** + * A {@link WireEnd} feeds a constant signal into the {@link Wire} it is tied to. The combination of all inputs determines the + * {@link Wire}s final value. X dominates all other inputs Z does not affect the final value, unless there are no other inputs than + * Z 0 and 1 turn into X when they are mixed + * + * @author Fabian Stemmler + */ + public class WireEnd + { + private boolean open; + private Bit[] inputValues; + + private WireEnd() + { + super(); + open = true; + initValues(); + registerInput(this); + } + + private void initValues() + { + inputValues = Bit.Z.makeArray(length); + } + + /** + * Sets the wires values. This takes up time, as specified by the {@link Wire}s travel time. + * + * @param newValues The new values the wires should take on. + * + * @author Fabian Stemmler + */ + public void feedSignals(Bit... newValues) + { + if (newValues.length == length) + { + feedSignals(0, newValues); + } else + throw new IllegalArgumentException( + String.format("Attempted to input %d bits instead of %d bits.", newValues.length, length)); + } + + /** + * Sets values of a subarray of wires. This takes up time, as specified by the {@link Wire}s travel time. + * + * @param newValues The new values the wires should take on. + * @param startingBit The first index of the subarray of wires. + * + * @author Fabian Stemmler + */ + public void feedSignals(int startingBit, Bit... newValues) + { + if (!open) + throw new RuntimeException("Attempted to write to closed WireArrayEnd."); + Simulation.TIMELINE.addEvent((e) -> setValues(startingBit, newValues), travelTime); + } + + private void setValues(int startingBit, Bit... newValues) + { + int exclLastIndex = startingBit + newValues.length; + if (length < exclLastIndex) + throw new ArrayIndexOutOfBoundsException( + String.format("Attempted to input bits from index %d to %d when there are only %d wires.", startingBit, + exclLastIndex - 1, length)); + if (!Arrays.equals(inputValues, startingBit, exclLastIndex, newValues, 0, newValues.length)) + { + System.arraycopy(newValues, 0, inputValues, startingBit, newValues.length); + Wire.this.recalculate(); + } + } + + /** + * @return The value (of bit 0) the {@link WireEnd} is currently feeding into the associated {@link Wire}. + */ + public Bit getInputValue() + { + return getInputValue(0); + } + + /** + * @return The value which the {@link WireEnd} is currently feeding into the associated {@link Wire} at the indexed {@link Bit}. + */ + public Bit getInputValue(int index) + { + return inputValues[index]; + } + + /** + * @return A copy (safe to modify) of the values the {@link WireEnd} is currently feeding into the associated + * {@link Wire}. + */ + public Bit[] getInputValues() + { + return getInputValues(0, length); + } + + public Bit[] getInputValues(int start, int end) + { + int length = end - start; + Bit[] bits = new Bit[length]; + System.arraycopy(inputValues, start, bits, 0, length); + return bits; + } + + /** + * {@link WireEnd} now feeds Z into the associated {@link Wire}. + */ + public void clearSignals() + { + feedSignals(Bit.Z.makeArray(length)); + } + + public Bit[] wireValuesExcludingMe() + { + Bit[] bits = Bit.Z.makeArray(length); + for (WireEnd wai : inputs) + { + if (wai == this) + continue; + Util.combineInto(bits, wai.getInputValues()); + } + return bits; + } + + /** + * Included for convenient use on {@link Wire}s of length 1. + * + * @return The value of bit 0. + * + * @author Fabian Stemmler + */ + public Bit getValue() + { + return Wire.this.getValue(); + } + + /** + * @param index Index of the requested bit. + * @return The value of the indexed bit. + * + * @author Fabian Stemmler + */ + public Bit getValue(int index) + { + return Wire.this.getValue(index); + } + + /** + * @param index Index of the requested bit. + * @return The value of the indexed bit. + * + * @author Fabian Stemmler + */ + public Bit[] getValues() + { + return Wire.this.getValues(); + } + + /** + * @param start Start of the wanted segment. (inclusive) + * @param end End of the wanted segment. (exclusive) + * @return The values of the segment of {@link Bit}s indexed. + * + * @author Fabian Stemmler + */ + public Bit[] getValues(int start, int end) + { + return Wire.this.getValues(start, end); + } + + + /** + * The {@link Wire} is interpreted as an unsigned integer with n bits. + * + * @return true if all bits are either Bit.ONE or Bit.ZERO (they do not all have to have the same + * value), not Bit.X or Bit.Z. false is returned otherwise. + * + * @author Fabian Stemmler + */ + public boolean hasNumericValue() + { + return Wire.this.hasNumericValue(); + } + + /** + * The {@link Wire} is interpreted as an unsigned integer with n bits. + * + * @return The unsigned value of the {@link Wire}'s bits, where value 0 corresponds with 2^0, value 1 is 2^1 and so on. + * + * @author Fabian Stemmler + */ + public long getUnsignedValue() + { + return Wire.this.getUnsignedValue(); + } + + /** + * The {@link Wire} is interpreted as a signed integer with n bits. + * + * @return The signed value of the {@link Wire}'s bits, where value 0 corresponds with 2^0, value 1 is 2^1 and so on. + * + * @author Fabian Stemmler + */ + public long getSignedValue() + { + return Wire.this.getSignedValue(); + } + + @Override + public String toString() + { + return Arrays.toString(values); + //return String.format("%s \nFeeding: %s", WireArray.this.toString(), Arrays.toString(inputValues)); + } + + public void disconnect() + { + inputs.remove(this); + open = false; + } + + public int length() + { + return length; + } + + public boolean addObserver(WireArrayObserver ob) + { + return Wire.this.addObserver(ob); + } + + public Wire getWire() + { + return Wire.this; + } + } + + @Override + public String toString() + { + return String.format("wire 0x%08x value: %s inputs: %s", hashCode(), Arrays.toString(values), inputs); + //Arrays.toString(values), inputs.stream().map(i -> Arrays.toString(i.inputValues)).reduce((s1, s2) -> s1 + s2) + } + + public static WireEnd[] extractEnds(Wire[] w) + { + WireEnd[] inputs = new WireEnd[w.length]; + for (int i = 0; i < w.length; i++) + inputs[i] = w[i].createEnd(); + return inputs; + } +} \ No newline at end of file diff --git a/era.mi/src/era/mi/logic/wires/WireArray.java b/era.mi/src/era/mi/logic/wires/WireArray.java deleted file mode 100644 index 58f27bc2..00000000 --- a/era.mi/src/era/mi/logic/wires/WireArray.java +++ /dev/null @@ -1,369 +0,0 @@ -package era.mi.logic.wires; - -import java.io.Closeable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; - -import era.mi.logic.Bit; -import era.mi.logic.Simulation; -import era.mi.logic.Util; - -/** - * Represents an array of wires that can store n bits of information. - * - * @author Fabian Stemmler - * - */ -public class WireArray -{ - private Bit[] values; - public final int travelTime; - private List observers = new ArrayList(); - public final int length; - List inputs = new ArrayList(); - - public WireArray(int length, int travelTime) - { - if (length < 1) - throw new IllegalArgumentException( - String.format("Tried to create an array of wires with length %d, but a length of less than 1 makes no sense.", length)); - this.length = length; - this.travelTime = travelTime; - initValues(); - } - - private void initValues() - { - values = Bit.U.makeArray(length); - } - - private void recalculateSingleInput() - { - WireArrayEnd input = inputs.get(0); - if (!Arrays.equals(input.getValues(), values)) - { - Bit[] oldValues = values.clone(); - System.arraycopy(input.getValues(), 0, values, 0, length); - notifyObservers(oldValues); - } - } - - private void recalculateMultipleInputs() - { - Iterator it = inputs.iterator(); - Bit[] newValues = it.next().inputValues.clone(); - - while (it.hasNext()) - { - WireArrayEnd input = it.next(); - Bit[] bits = input.getValues(); - for (int i = 0; i < length; i++) - { - newValues[i] = newValues[i].combineWith(bits[i]); - } - } - - if (!Arrays.equals(newValues, values)) - { - Bit[] oldValues = values; - values = newValues; - notifyObservers(oldValues); - } - } - - void recalculate() - { - switch (inputs.size()) - { - case 0: - return; - case 1: - recalculateSingleInput(); - break; - default: - recalculateMultipleInputs(); - } - } - - /** - * The WireArray is interpreted as an unsigned integer with n bits. - * - * @return true if all bits are either Bit.ONE or Bit.ZERO (they do not all have to have the same - * value), not Bit.X or Bit.Z. false is returned otherwise. - * - * @author Fabian Stemmler - */ - public boolean hasNumericValue() - { - for (Bit b : values) - { - if (b != Bit.ZERO && b != Bit.ONE) - return false; - } - return true; - } - - /** - * The WireArray is interpreted as an unsigned integer with n bits. - * - * @return The unsigned value of the {@link WireArray}'s bits, where value 0 corresponds with 2^0, value 1 is 2^1 and so on. - * - * @author Fabian Stemmler - */ - public long getUnsignedValue() - { - long val = 0; - long mask = 1; - for (int i = 0; i < length; i++) - { - switch (values[i]) - { - default: - case Z: - case X: - return 0; // TODO: Proper handling for getUnsignedValue(), if not all bits are 1 or 0; - // Random number? - case ONE: - val |= mask; - break; - case ZERO: - } - mask = mask << 1; - } - return val; - } - - /** - * The WireArray is interpreted as a signed integer with n bits. - * - * @return The signed value of the {@link WireArray}'s bits, where value 0 corresponds with 2^0, value 1 is 2^1 and so on. - * - * @author Fabian Stemmler - */ - public long getSignedValue() - { - long val = getUnsignedValue(); - long mask = 1 << (length - 1); - if ((mask & val) != 0) - { - int shifts = 64 - length; - return (val << shifts) >> shifts; - } - return val; - } - - /** - * Included for convenient use on {@link WireArray}s of length 1. - * - * @return The value of bit 0. - * - * @author Fabian Stemmler - */ - public Bit getValue() - { - return getValue(0); - } - - /** - * - * @param index Index of the requested bit. - * @return The value of the indexed bit. - * - * @author Fabian Stemmler - */ - public Bit getValue(int index) - { - return values[index]; - } - - public Bit[] getValues(int start, int end) - { - int length = end - start; - Bit[] bits = new Bit[length]; - System.arraycopy(values, start, bits, 0, length); - return bits; - } - - /** - * @return An array of length n containing the values of the n bits in the {@link WireArray}. Can be safely modified. - * - * @author Fabian Stemmler - */ - public Bit[] getValues() - { - return values.clone(); - } - - /** - * Adds an {@link WireArrayObserver}, who will be notified when the value of the {@link WireArray} is updated. - * - * @param ob The {@link WireArrayObserver} to be notified of changes. - * @return true if the given {@link WireArrayObserver} was not already registered, false otherwise - * - * @author Fabian Stemmler - */ - public boolean addObserver(WireArrayObserver ob) - { - return observers.add(ob); - } - - private void notifyObservers(Bit[] oldValues) - { - for (WireArrayObserver o : observers) - o.update(this, oldValues); - } - - /** - * Create and register a {@link WireArrayEnd} object, which is tied to this {@link WireArray}. - */ - public WireArrayEnd createInput() - { - return new WireArrayEnd(this); - } - - void registerInput(WireArrayEnd toRegister) - { - inputs.add(toRegister); - } - - /** - * A {@link WireArrayEnd} feeds a constant signal into the {@link WireArray} it is tied to. The combination of all inputs determines the - * {@link WireArray}s final value. X dominates all other inputs Z does not affect the final value, unless there are no other inputs than - * Z 0 and 1 turn into X when they are mixed - * - * @author Fabian Stemmler - */ - public class WireArrayEnd implements Closeable - { - public final WireArray owner; - private boolean open; - Bit[] inputValues; - - WireArrayEnd(WireArray owner) - { - super(); - this.owner = owner; - open = true; - initValues(); - owner.registerInput(this); - } - - private void initValues() - { - inputValues = Bit.U.makeArray(length); - } - - /** - * Sets the wires values. This takes up time, as specified by the {@link WireArray}s travel time. - * - * @param newValues The new values the wires should take on. - * - * @author Fabian Stemmler - */ - public void feedSignals(Bit... newValues) - { - if (newValues.length != length) - throw new IllegalArgumentException( - String.format("Attempted to input %d bits instead of %d bits.", newValues.length, length)); - feedSignals(0, newValues); - - } - - /** - * Sets values of a subarray of wires. This takes up time, as specified by the {@link WireArray}s travel time. - * - * @param newValues The new values the wires should take on. - * @param startingBit The first index of the subarray of wires. - * - * @author Fabian Stemmler - */ - public void feedSignals(int startingBit, Bit... newValues) - { - if (!open) - throw new RuntimeException("Attempted to write to closed WireArrayEnd."); - Simulation.TIMELINE.addEvent((e) -> setValues(startingBit, newValues), travelTime); - } - - private void setValues(int startingBit, Bit... newValues) - { - int exclLastIndex = startingBit + newValues.length; - if (length < exclLastIndex) - throw new ArrayIndexOutOfBoundsException( - String.format("Attempted to input bits from index %d to %d when there are only %d wires.", startingBit, - exclLastIndex - 1, length)); - if (!Arrays.equals(inputValues, startingBit, exclLastIndex, newValues, 0, newValues.length)) - { - System.arraycopy(newValues, 0, inputValues, startingBit, newValues.length); - owner.recalculate(); - } - } - - /** - * Returns a copy (safe to modify) of the values the {@link WireArrayEnd} is currently feeding into the associated - * {@link WireArray}. - */ - public Bit[] getValues() - { - return inputValues.clone(); - } - - /** - * {@link WireArrayEnd} now feeds Z into the associated {@link WireArray}. - */ - public void clearSignals() - { - feedSignals(Bit.Z.makeArray(length)); - } - - public Bit[] wireValuesExcludingMe() - { - Bit[] bits = Bit.Z.makeArray(length); - for (WireArrayEnd wai : inputs) - { - if (wai == this) - continue; - Util.combineInto(bits, wai.getValues()); - } - return bits; - } - - public Bit getWireValue() - { - return owner.getValue(); - } - - public Bit[] getWireValues() - { - return owner.getValues(); - } - - @Override - public String toString() - { - return Arrays.toString(inputValues); - } - - @Override - public void close() - { - inputs.remove(this); - open = false; - } - } - - @Override - public String toString() - { - return String.format("wire 0x%08x value: %s inputs: %s", hashCode(), Arrays.toString(values), inputs); - } - - public static WireArrayEnd[] extractInputs(WireArray[] w) - { - WireArrayEnd[] inputs = new WireArrayEnd[w.length]; - for (int i = 0; i < w.length; i++) - inputs[i] = w[i].createInput(); - return inputs; - } -} \ No newline at end of file diff --git a/era.mi/src/era/mi/logic/wires/WireArrayObserver.java b/era.mi/src/era/mi/logic/wires/WireArrayObserver.java index 2c807bb3..7d915f6a 100644 --- a/era.mi/src/era/mi/logic/wires/WireArrayObserver.java +++ b/era.mi/src/era/mi/logic/wires/WireArrayObserver.java @@ -4,5 +4,5 @@ import era.mi.logic.Bit; public interface WireArrayObserver { - public void update(WireArray initiator, Bit[] oldValues); + public void update(Wire initiator, Bit[] oldValues); }