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
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
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
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
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
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
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
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
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
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
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
}
// @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 },
{
public final static Timeline TIMELINE = new Timeline(11);
+ public static void main(String[] args)
+ {
+ }
}
\ No newline at end of file
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;
/**
}
@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();
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;
}
@Override
- public List<WireArray> getAllInputs()
+ public List<WireEnd> getAllInputs()
{
- return List.of(in);
+ return Collections.unmodifiableList(Arrays.asList(in));
}
@Override
- public List<WireArray> getAllOutputs()
+ public List<WireEnd> getAllOutputs()
{
- return List.of();
+ return Collections.unmodifiableList(new ArrayList<WireEnd>());
}
}
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()
}
@Override
- public List<WireArray> getAllInputs()
+ public List<WireEnd> getAllInputs()
{
- return List.of();
+ return Collections.unmodifiableList(Arrays.asList());
}
@Override
- public List<WireArray> getAllOutputs()
+ public List<WireEnd> getAllOutputs()
{
- return List.of(outI.owner);
+ return Collections.unmodifiableList(Arrays.asList(out));
}
}
import java.util.List;
-import era.mi.logic.wires.WireArray;
+import era.mi.logic.wires.Wire.WireEnd;
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<WireArray> getAllInputs();
+ public List<WireEnd> getAllInputs();
/**
* Returns immutable list of all outputs to the {@link Component}. Intended for visualization in the UI.
*/
- public List<WireArray> getAllOutputs();
+ public List<WireEnd> getAllOutputs();
}
+++ /dev/null
-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<WireArray> getAllInputs()
- {
- return List.of(a, b);
- }
-
- @Override
- public List<WireArray> getAllOutputs()
- {
- return List.of(a, b);
- }
-}
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);
}
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<WireArray> getAllInputs()
+ public List<WireEnd> getAllInputs()
{
- return List.of(in, select);
+ return Collections.unmodifiableList(Arrays.asList(in, select));
}
@Override
- public List<WireArray> getAllOutputs()
+ public List<WireEnd> getAllOutputs()
{
- return List.of(outputs);
+ return Collections.unmodifiableList(Arrays.asList(outputs));
}
}
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.
*/
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()
if (this.isOn == isOn)
return;
this.isOn = isOn;
- outputI.feedSignals(getValue());
+ output.feedSignals(getValue());
}
public boolean isOn()
}
@Override
- public List<WireArray> getAllInputs()
+ public List<WireEnd> getAllInputs()
{
return List.of();
}
@Override
- public List<WireArray> getAllOutputs()
+ public List<WireEnd> getAllOutputs()
{
return List.of(output);
}
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<WireArray> getAllInputs()
+ public List<WireEnd> getAllInputs()
{
- return List.of(inputs);
+ return Collections.unmodifiableList(Arrays.asList(inputs));
}
@Override
- public List<WireArray> getAllOutputs()
+ public List<WireEnd> getAllOutputs()
{
- return List.of(outI.owner);
+ return Collections.unmodifiableList(Arrays.asList(out));
}
}
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
*/
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);
}
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;
}
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<WireArray> getAllInputs()
+ public List<WireEnd> getAllInputs()
{
- ArrayList<WireArray> wires = new ArrayList<WireArray>(Arrays.asList(inputs));
+ ArrayList<WireEnd> wires = new ArrayList<WireEnd>(Arrays.asList(inputs));
wires.add(select);
return Collections.unmodifiableList(wires);
}
@Override
- public List<WireArray> getAllOutputs()
+ public List<WireEnd> getAllOutputs()
{
- return List.of(outI.owner);
+ return Collections.unmodifiableList(Arrays.asList(out));
}
}
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().");
}
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();
}
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<WireArray> getAllInputs()
+ public List<WireEnd> getAllInputs()
{
- return List.of(in, enable);
+ return Collections.unmodifiableList(Arrays.asList(in, enable));
}
@Override
- public List<WireArray> getAllOutputs()
+ public List<WireEnd> getAllOutputs()
{
- return List.of(outI.owner);
+ return Collections.unmodifiableList(Arrays.asList(out));
}
}
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);
}
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<WireArray> getAllInputs()
+ public List<WireEnd> getAllInputs()
{
- return List.of(in);
+ return Collections.unmodifiableList(Arrays.asList(in));
}
@Override
- public List<WireArray> getAllOutputs()
+ public List<WireEnd> 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
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<WireArray> getAllInputs()
+ public List<WireEnd> getAllInputs()
{
- return List.of(in);
+ return Collections.unmodifiableList(Arrays.asList(in));
}
@Override
- public List<WireArray> getAllOutputs()
+ public List<WireEnd> getAllOutputs()
{
- return List.of(out);
+ return Collections.unmodifiableList(Arrays.asList(out));
}
}
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);
}
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.
*/
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);
}
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;
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
{
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();
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();
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();
@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();
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);
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);
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();
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();
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);
{
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();
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();
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);
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);
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);
--- /dev/null
+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);
+ }
+}
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
{
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<ManualSwitch, Rectangle> switchMap = new HashMap<>();
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));
g.setColor(Color.BLACK);
}
- private static void setTo(Graphics g, WireArray wa)
+ private static void setTo(Graphics g, Wire wa)
{
switch (wa.getValue())
{
g.setColor(Color.BLACK);
break;
case U:
- g.setColor(Color.MAGENTA);
+ g.setColor(Color.BLUE);
break;
default:
throw new IllegalArgumentException();
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)
{
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);
}
{
if (!hasNext())
return -1;
- return events.peek().timing;
+ else
+ return events.peek().timing;
}
public void reset()
private class InnerEvent
{
- final long timing;
+ private final long timing;
private final TimelineEventHandler function;
private final TimelineEvent event;
return timing;
}
- @Override
public String toString()
{
return "timestamp: " + timing;
--- /dev/null
+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<WireArrayObserver> observers = new ArrayList<WireArrayObserver>();
+ public final int length;
+ private List<WireEnd> inputs = new ArrayList<WireEnd>();
+
+ 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<WireEnd> 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 <code>true</code> if all bits are either <code>Bit.ONE</code> or <code>Bit.ZERO</code> (they do not all have to have the same
+ * value), not <code>Bit.X</code> or <code>Bit.Z</code>. <code>false</code> 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 <code>true</code> if all bits are either <code>Bit.ONE</code> or <code>Bit.ZERO</code> (they do not all have to have the same
+ * value), not <code>Bit.X</code> or <code>Bit.Z</code>. <code>false</code> 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
+++ /dev/null
-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<WireArrayObserver> observers = new ArrayList<WireArrayObserver>();
- public final int length;
- List<WireArrayEnd> inputs = new ArrayList<WireArrayEnd>();
-
- 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<WireArrayEnd> 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 <code>true</code> if all bits are either <code>Bit.ONE</code> or <code>Bit.ZERO</code> (they do not all have to have the same
- * value), not <code>Bit.X</code> or <code>Bit.Z</code>. <code>false</code> 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
public interface WireArrayObserver
{
- public void update(WireArray initiator, Bit[] oldValues);
+ public void update(Wire initiator, Bit[] oldValues);
}